数字系统设计(EDA)实验报告【出租车计价器】

一、问题描述

题目九:出租车计价器设计(平台实现)★★

完成简易出租车计价器设计,选做停车等待计价功能。

1、基本功能:

(1)起步8元/3km,此后2元/km;

(2)里程指示信号为每前进50米一个高电平脉冲,上升沿有效;显示行驶公里数,精确到0.1km。(模拟时速40km/h)

(3)前进里程开始之前显示价钱,精确到0.1元;

(4)用两个按键分别表示开始行程和结束行程。

2、选做功能:

(1)增加一个停车等待/恢复行程按钮,用2个数码管显示等待时间,精确到0.1分钟。

(2)等候费1元/min,计价精度为0.1元。

二、设计方案

        根据题设分析得到出租车的计费工作原理分成以下4个阶段:

(1)出租车起步开始计费,首先显示起步价(设计起步费为8.0元),当出租车在3km的行驶里程以内,只收起步价8.0元;

(2)出租车行驶超过3km后,按每公里2元计费(在8.0元基础上每行驶1km车费加2.0元),车费依次累加;

(3)出租车暂停行驶(如行驶中遇红灯或中途由于堵车等意外情况而停车),按停止时间进行计费,每1分钟计费1.0元;

(4)若行程终止,则车费清零,等待下一次计费的开始。

        对应主要可分为以下三大模块去实现:

(1)秒分频模块:

        脉冲生成模块保证整个系统的同步工作,对于电路板上提供的100Hz时钟脉冲信号进行分频处理,得到题目中需要用到的秒分频信号,便于后续计量数据模块对于信号的处理。

(2)计量控制模块:

        计量数据模块主要有三个部分组成,分别是计价部分、计时部分和计程部分,这三个部分是出租车计价器系统多功能实现的基础与保证。

        计价部分又可以分为两个内容,其一是在出租车正常行驶的过程中根据不同的收费标准分段将里程数折算为对应的价格费用,如本题中在起步3km以内固定收费8.0元,而超出3km起步里程后对后续的每公里里程折算为2元的价格费用;其二是在出租车暂停行驶的情况下,将等候时间折算为对应的价格费用,如本题中将每分钟折算为1.0元。

        与此同时,出租车需要实现开始行程、停车等待、恢复行程和结束行程四个动作,因此控制出租车的状态需要设计三个按键,用来选择出租车的启动、暂停和终止,对应按键按下时将对应的电平从低电平翻转为高电平,并将此信号送往控制模块产生相应的响应动作。

(3)译码显示模块:

        译码显示模块用于将出租车的实时里程数、价格费用和等待时间显示出来。

        ① 用2个数码管显示实时里程数;

        ② 用2个数码管显示等待时间;

        ③ 用4个数码管显示价格费用。

系统顶层框图如下:

三、系统实现

1、基本流程

(1)设计输入:运用VHDL硬件描述语言根据题目所要求实现的功能和自己设计的拓展部分进行电路设计(开发软件:Quartus Ⅱ 9.0);

(2)文件处理:对设计输入的文件进行编译检查、逻辑化简、改进优化等一系列步骤,最后生成对应的编程文件;

(3)仿真验证:对设计处理的编程文件进行仿真测试,以验证程序是否符合题目给出的要求和设计的功能是否可以实现;

(4)元器件编程:将对应的VHDL硬件描述语言的编程代码数据下载至具体的可编程元器件中;

(5)硬件测试:将编写好的系统程序载入到实验电路板上并按题目要求进行测试(硬件:EDA-I实验板,如下图)。

2、程序流程图

3、代码说明

(1)分频:根据题目要求首先设置秒计时,即先完成1s分频;再根据50米给出一个高脉冲,设置4.5s分频;对于精确到0.1元的计价,设计6s分频;对于精确到0.1km的里程,设计9s分频。

p1:process(rst, clk) 						-- 1s 分频
   begin 
	if rst = '0' then 
		if clk'event and clk = '1' then 
			if count_1 = 99 then 
				count_1 <= 0;
				clk1hz <= '1'; 
			else 
				count_1 <= count_1 + 1;
				clk1hz <= '0';  
			end if;
		end if; 
	end if; 
   end process; 
  
p2:process(rst, clk) 						-- 4.5s 分频
   begin 
	if rst = '0' then 
		if clk'event and clk = '1' then 
			if count_2 = 449 then 
				count_2 <= 0;
				clklhz_1 <= '1'; 
			else 
				count_2 <= count_2 + 1;
				clklhz_1 <= '0';  
			end if;
		end if; 
	end if; 
   end process; 

p3:process(rst, clk) 						-- 6s 分频
   begin 
	if rst = '0' then 
		if clk'event and clk = '1' then 
			if count = 599 then 
				count <= 0;
				clklhz_2 <= '1'; 
			else 
				count <= count + 1;
				clklhz_2 <= '0';  
			end if;
		end if; 
	end if; 
   end process; 

p4:process(rst, clk) -- 9s 分频
   begin 
	if rst = '0' then 
		if clk'event and clk = '1' then 
			if count_3 = 899 then 
				count_3 <= 0;
				clklhz_3 <= '1'; 
			else 
				count_3 <= count_3 + 1;
				clklhz_3 <= '0';  
			end if;
		end if; 
	end if; 
   end process; 

(2)段选与片选:对需要显示在数码管上的信号量设计译码方案,并根据实际情况分出的不同情况进行不同的段选与片选。

p9:process(clk2)
	begin
		if clk2'event and clk2 = '1' then
			case show is
				when "000" =>show <= "001";
							 pianxuan <= "11111110";
							 bt <= c0;
							 flag <= 0;
				when "001" =>show <= "010";
						 	 pianxuan <= "11111101";
							 bt <= c1;
							 flag <= 1;
				when "010" =>show <= "011";
							 pianxuan <= "11111011";
							 bt <= c2;
							 flag <= 0;
				when "011" =>show <= "100";
							 pianxuan <= "11110111";
							 bt <= c3;
							 flag <= 0;
				when "100" =>show <= "101";
							 pianxuan <= "11101111";
							 bt <= k0;
							 flag <= 0;
				when "101" =>show <= "110";
							 pianxuan <= "11011111";
							 bt <= k1;
							 flag <= 1;
				when "110" =>show <= "111";
							 pianxuan <= "10111111";
							 bt <= m0;
							 flag <= 0;
				when "111" =>show <= "000";
							 pianxuan <= "01111111";
							 bt <= m1;
							 flag <= 0;
			end case;
		end if;
	end process;
	
p10:process(bt, flag)
	begin
		if flag = 1 then
			case bt is
				when "0000" => duanxuan <= "11111110";	--0
				when "0001" => duanxuan <= "10110000";
				when "0010" => duanxuan <= "11101101";
				when "0011" => duanxuan <= "11111001";
				when "0100" => duanxuan <= "10110011";
				when "0101" => duanxuan <= "11011011";
				when "0110" => duanxuan <= "11011111";
				when "0111" => duanxuan <= "11110000";
				when "1000" => duanxuan <= "11111111";
				when "1001" => duanxuan <= "11111011";	--9
				when others => NULL;
			end case;
		elsif flag = 0 then
			case bt is
				when "0000" => duanxuan <= "01111110";	--0
				when "0001" => duanxuan <= "00110000";
				when "0010" => duanxuan <= "01101101";
				when "0011" => duanxuan <= "01111001";
				when "0100" => duanxuan <= "00110011";
				when "0101" => duanxuan <= "01011011";
				when "0110" => duanxuan <= "01011111";
				when "0111" => duanxuan <= "01110000";
				when "1000" => duanxuan <= "01111111";
				when "1001" => duanxuan <= "01111011";	--9
				when others => NULL;
			end case;         
		end if;
	end process;
end;

(3)里程计数:根据3km内和超出3km部分进行计价模式切换,并设计完成进位部分和重置部分。

p7:process(rst, start, mile_clk) 			--里程计数
   begin 
	if rst = '1' then 
		k0 <= "0000"; 
		k1 <= "0000"; 
		mode <= '0';
   elsif clklhz_3'event and clklhz_3 = '1' then
		if wait_signal = '0' and start = '1' then 
			if k1 & k0="00110000" then 		--超过3km
				mode <= '1'; 
			end if; 
			if k0 = "1001" then 
				k0 <= "0000"; 
				if k1 = "1001" then 
					k1 <= "0000"; 
				else 
					k1 <= k1 + '1'; 
				end if; 
			else 
				k0 <= k0 + '1'; 
			end if; 
		end if;
    end if; 
   end process; 

(4)等待时间计数:此处为了方便观察实验结果,我将显示分钟改为了显示秒钟,但仍按分钟对应的秒数进行进位(0-59s)。

p5:process(rst, clk1hz, start, wait_signal)  --等待时间计数
   begin   
	if rst = '1' then 							--乘客离开
		m0 <= "0000";
		m1 <= "0000"; 
	elsif start = '0' then 						--没开车
		wait_clk <= '0'; 
	elsif clklhz_2'event and clklhz_2 = '1' then 
		if wait_signal = '1' then 				--停车
			if sec = 9 then
				sec <= 0;
				if m0 = "1001" then 
					m0 <= "0000"; 
					if m1 = "0101" then
						m1 <= "0000"; 
					else 
						m1 <= m1 + '1'; 
					end if; 
				else 
					m0 <= m0 + '1'; 
				end if;
			else 
				wait_clk <= '0'; 
				sec <= sec + 1;
				if m0 = "1001" then 
					m0 <= "0000"; 
					if m1 = "0101" then
						m1 <= "0000"; 
					else 
						m1 <= m1 + '1'; 
					end if; 
				else 
					m0 <= m0 + '1'; 
				end if; 
			end if; 
		else 
			wait_clk <= '0'; 
		end if; 
	end if; 
   end process; 

(5)计费:根据不同的行程状态对应不同的时钟信号cost_clk,按50m上升沿时钟频率更新计算费用,并完成进位部分和重置。

p6:process(rst, clklhz_1, clklhz_2) --检测mile上升沿
   begin
	if wait_clk = '1' or rst = '1' then
		mile_clk <= '0';
	elsif rst = '0' and wait_clk = '0' then
	    mile_clk <= clklhz_1;
	end if; 
   end process; 
   cost_clk <= clklhz_2 when wait_signal = '1' else 
    		   mile_clk when mode = '1' else 
	     	   '0'; 

p8:process(rst, start, cost_clk) --计费
   begin 
	if rst = '1' then --计价结束
		c0 <= "0000";
		c1 <= "0000"; 
		c2 <= "0000";
		c3 <= "0000"; 
	elsif start = '1' and mode = '0' then --还在起步范围
		c0 <= "0000";
		c1 <= "1000"; --8.0元
		c2 <= "0000"; 
		c3 <= "0000"; 
	elsif cost_clk'event and cost_clk = '1' then --50m每个上升沿/中途停车等待
		if mode = '1' and start = '1' then 
			if c0 = "1001" then 
				c0 <= "0000"; 
				if c1 = "1001" then 
					c1 <= "0000"; 
					if c2 = "1001" then 
						c2 <= "0000";
						if c3 = "1001" then
							c3 <= "0000";
						else
							c3 <= c3 + '1';
						end if;
					else 
						c2 <= c2 + '1'; 
					end if; 
				else 
					c1 <= c1 + '1'; 
				end if; 
			else 
				c0 <= c0 + '1'; 
			end if; 
		end if;
	end if; 
   end process;

(6)消除抖动:通过延时计数的方法将不连续的输入脉冲信号调整为稳定的输出信号。

xiaodou:process(clk, start_in, wait_signal_in, rst_in)
	begin
		if clk'event and clk = '1' then
			if count < 1 then
				count <= count + 1;
			else
				count <= 0;
				if start_in = '1' then
					start <= '1';
				elsif wait_signal_in = '1' then
					wait_signal <= '1';
				elsif rst_in = '1' then
					rst <= '1';
				end if;
			end if;
		end if;
	end process;

4、完整代码

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.std_logic_unsigned.all; 
use ieee.std_logic_arith.all; 
entity taxi is 
port(
		clk:in std_logic;  --时钟信号
		start:inout std_logic;
		wait_signal:inout std_logic;
		rst:inout std_logic;
		numViewOutputSg:out std_logic_vector(7 downto 0);
		numViewOutputBt:out std_logic_vector(7 downto 0);
		clk2: in std_logic --高频时钟
	);
end; 

architecture bhv of taxi is 
	signal mile_clk,clk1hz,clklhz_1,clklhz_2,clklhz_3:std_logic; --clklhz:分频后的时钟信号
	signal count:integer range 0 to 599;
	signal count_1:integer range 0 to 99; 
	signal count_2:integer range 0 to 449;
	signal count_3:integer range 0 to 899;
	signal sec:integer range 0 to 59 :=0; --秒数
	signal c0,c1,c2,c3:std_logic_vector(3 downto 0); --费用(从低到高)
	signal k0,k1,m0,m1:std_logic_vector(3 downto 0); --k指公里 m指时间
	signal en0:std_logic :='0'; 
	signal wait_clk,cost_clk:std_logic; 
	signal temp:std_logic;
	signal show:std_logic_vector(2 downto 0):="000";
	signal bt:std_logic_vector(3 downto 0);
	signal flag:integer range 0 to 1;
	--signal rst:std_logic; --判断是否停车
	--signal start:std_logic; --使能信号
	--signal wait_signal:std_logic; --停车信号
begin 
--xiaodou:process(clk,start_in,wait_signal_in,rst_in)
--	begin
--		if clk'event and clk='1' then
--			if count<1 then
--				count<=count+1;
--			else
--				count<=0;
--				if start_in='1' then
--					start<='1';
--				elsif wait_signal_in='1' then
--					wait_signal<='1';
--				elsif rst_in='1' then
--					rst<='1';
--				end if;
--			end if;
--		end if;
--	end process;

U1:process(rst,clk) -- 1s 分频
   begin 
	if rst='0' then 
		if clk'event and clk='1' then 
			if count_1=99 then 
				count_1<=0;
				clk1hz<='1'; 
			else 
				count_1<=count_1+1;
				clk1hz<='0';  
			end if;
		end if; 
	end if; 
   end process; 
   
U0:process(rst,clk) -- 4.5s 分频
   begin 
	if rst='0' then 
		if clk'event and clk='1' then 
			if count_2=449 then 
				count_2<=0;
				clklhz_1<='1'; 
			else 
				count_2<=count_2+1;
				clklhz_1<='0';  
			end if;
		end if; 
	end if; 
   end process; 

U6:process(rst,clk) -- 6s
   begin 
	if rst='0' then 
		if clk'event and clk='1' then 
			if count=599 then 
				count<=0;
				clklhz_2<='1'; 
			else 
				count<=count+1;
				clklhz_2<='0';  
			end if;
		end if; 
	end if; 
   end process; 

U9:process(rst,clk) -- 9s
   begin 
	if rst='0' then 
		if clk'event and clk='1' then 
			if count_3=899 then 
				count_3<=0;
				clklhz_3<='1'; 
			else 
				count_3<=count_3+1;
				clklhz_3<='0';  
			end if;
		end if; 
	end if; 
   end process; 

U2:process(rst,clk1hz,start,wait_signal)  --等待时间计数
   begin   
	if rst='1' then --乘客离开
		m0<="0000";
		m1<="0000"; 
	elsif start='0' then --没开车
		wait_clk<='0'; 
	elsif clk1hz'event and clk1hz='1' then 
		if wait_signal='1' then --停车
			if sec=59 then
				sec<=0;
			elsif ((sec+1) mod 6)=0 then
				sec<=sec+1; 
				if m0="1001" then 
					m0<="0000"; 
					if m1="0101" then
						m1<="0000"; 
					else 
						m1<=m1+'1'; 
					end if; 
				else 
					m0<=m0+'1'; 
				end if;
			else 
				wait_clk<='0'; 
				sec<=sec+1;
				if m0="1001" then 
					m0<="0000"; 
					if m1="0101" then
						m1<="0000"; 
					else 
						m1<=m1+'1'; 
					end if; 
				else 
					m0<=m0+'1'; 
				end if; 
			end if; 
		else 
			wait_clk<='0'; 
		end if; 
	end if; 
   end process; 

U3:process( rst,clklhz_1,clklhz_2) --检测mile上升沿
   begin
	if wait_clk='1' or rst='1' then
		mile_clk<='0';
	elsif rst='0' and wait_clk='0' then
	    mile_clk<=clklhz_1;
	end if; 
   end process; 
   cost_clk<=clklhz_2 when wait_signal='1' else 
    		  mile_clk when en0='1' else 
	     	  '0'; 

U4:process(rst,start,mile_clk) --里程计数
   begin 
	if rst='1' then 
		k0<="0000"; 
		k1<="0000"; 
		en0<='0';
    elsif clklhz_3'event and clklhz_3='1' then
		if wait_signal='0' and start='1' then 
			if k1 & k0="00000011" then --超过3km
				en0<='1'; 
			end if; 
			if k0="1001" then 
				k0<="0000"; 
				if k1="1001" then 
					k1<="0000"; 
				else 
					k1<=k1+'1'; 
				end if; 
			else 
				k0<=k0+'1'; 
			end if; 
		end if;
    end if; 
   end process; 

U5:process( rst,start,cost_clk) --计费
   begin 
	if rst='1' then --计价结束
		c0<="0000";
		c1<="0000"; 
		c2<="0000";
		c3<="0000"; 
	elsif start='1' and en0='0' then --还在起步范围
		c0<="0000";
		c1<="1000"; --8.0元
		c2<="0000"; 
		c3<="0000"; 
	elsif cost_clk'event and cost_clk='1' then --50m每个上升沿/中途停车等待
		if en0='1' and start='1' then 
			if c0="1001" then 
				c0<="0000"; 
				if c1="1001" then 
					c1<="0000"; 
					if c2="1001" then 
						c2<="0000";
						if c3="1001" then
							c3<="0000";
						else
							c3<=c3+'1';
						end if;
					else 
						c2<=c2+'1'; 
					end if; 
				else 
					c1<=c1+'1'; 
				end if; 
			else 
				c0<=c0+'1'; 
			end if; 
		end if;
	end if; 
   end process;
   
p4:process(clk2)
	begin
		if clk2'event and clk2='1' then
			case show is
				when "000" =>show <= "001";
							 numViewOutputSg <= "11111110";
							 bt <= c0;
							 flag <= 0;
				when "001" =>show <= "010";
						 	 numViewOutputSg <= "11111101";
							 bt <= c1;
							 flag <= 1;
				when "010" =>show <= "011";
							 numViewOutputSg <= "11111011";
							 bt <= c2;
							 flag <= 0;
				when "011" =>show <= "100";
							 numViewOutputSg <= "11110111";
							 bt <= c3;
							 flag <= 0;
				when "100" =>show <= "101";
							 numViewOutputSg <= "11101111";
							 bt <= k0;
							 flag <= 0;
				when "101" =>show <= "110";
							 numViewOutputSg <= "11011111";
							 bt <= k1;
							 flag <= 1;
				when "110" =>show <= "111";
							 numViewOutputSg <= "10111111";
							 bt <= m0;
							 flag <= 0;
				when "111" =>show <= "000";
							 numViewOutputSg <= "01111111";
							 bt <= m1;
							 flag <= 0;
			end case;
		end if;
	end process p4;
	
p5:process(bt, flag)
	begin
		if flag = 1 then
			case bt is
				when "0000" => numViewOutputBt <= "11111110";--0
				when "0001" => numViewOutputBt <= "10110000";
				when "0010" => numViewOutputBt <= "11101101";
				when "0011" => numViewOutputBt <= "11111001";
				when "0100" => numViewOutputBt <= "10110011";
				when "0101" => numViewOutputBt <= "11011011";
				when "0110" => numViewOutputBt <= "11011111";
				when "0111" => numViewOutputBt <= "11110000";
				when "1000" => numViewOutputBt <= "11111111";
				when "1001" => numViewOutputBt <= "11111011";--9
				when others => NULL;
			end case;
		elsif flag = 0 then
			case bt is
				when "0000" => numViewOutputBt <= "01111110";--0
				when "0001" => numViewOutputBt <= "00110000";
				when "0010" => numViewOutputBt <= "01101101";
				when "0011" => numViewOutputBt <= "01111001";
				when "0100" => numViewOutputBt <= "00110011";
				when "0101" => numViewOutputBt <= "01011011";
				when "0110" => numViewOutputBt <= "01011111";
				when "0111" => numViewOutputBt <= "01110000";
				when "1000" => numViewOutputBt <= "01111111";
				when "1001" => numViewOutputBt <= "01111011";--9
				when others => NULL;
			end case;
		end if;
	end process p5;
end;

四、仿真

五、测试

1、初始状态(行程未开始)

2、行程开始,计价开始(3km内)

3、里程达到3km

4、里程超过3km(切换计价模式)

 5、停车等待,开始按时计价

 6、行程继续(切换计价模式)

 7、行程结束

 8、演示视频

EDA出租车计价系统演示视频(2x)

六、课程学习或实验过程中出现的问题

1、对端口模式的理解不透彻,导致在分析教材部分例题和其他代码的过程中出现问题,尤其以双向端口(INOUT)最难学习与掌握;

2、使用EDA实验板时,对于设置好的按钮在进行按键操作的过程中,信号稳定的前后出现了多个不稳定的脉冲现象,而正常情况下一次按键操作理论上应只产生一个边沿信号脉冲(如下图所示);

3、本题中需要实现对价格费用、里程和等待时间的显示,而在VHDL硬件描述语言的编程设计过程中,在Pin Planner(引脚规划器)的设置中各个数字都出现了4个引脚选择,而EDA实验板上只有8个数码管而不够使用;

4、 实验过程中设置引脚后发现没有解决小数点的问题,在应该精确到0.1的地方没有显示小数点;

七、对各种问题的解决过程、方法和结果

(注:序号对应第六部分中的问题)

1、对于之前看过的一道程序中的以下部分源码(其中,程序中DataB为双向端口INOUT):

......
DataB <= Din when CE = '1' and Rd = '0' else
Others => 'Z';
Dout <= DataB when CE = '1' and Rd = '1' else
Others => '1';
......

      通过查阅相关书籍及在CSDN等平台上查找相关的资料,了解到教材上仅仅只提到了端口的双向模式允许信号双向传输(即既可以进入实体,也可以离开实体),可代替IN、OUT和BUFFER。但在实际编程时还必须要注意的细节是,当双向端口DataB作为输出且空闲时,必须将其设为高阻态挂起,即在上述程序的部分代码中需要有“Others => 'Z'”这一条语句,否则实现后会导致端口死锁;而当双向端口DataB作为有效输入时,DataB输出必须处于高阻态,即在上述程序的部分代码中需要有“CE = '1' and Rd = '1'”这一条语句,否则同样也会出现问题。

2、通过对实验电路板的结构分析以及在其他相关课程(如计算机组成原理)的学习中,了解到本次实验中使用的实验电路板的按键为机械式开关结构,由于机械式开关的核心部件为弹性金属簧片,因而在开关切换的瞬间会在接触点出现来回弹跳的现象,因此虽然看上去只是进行了一次按键,结果却可能是在按键的信号稳定的前后出现了多个不规则的脉冲,如果将这样的脉冲信号直接送给微处理器进行扫描采集的话,将可能把按键稳定前后出现的脉冲信号当作按键信号,这就会导致人为的一次按键但是微处理器以为是执行多次按键的现象。因此为了确保按键识别的准确性,应当使得在按键信号产生抖动的情况之下禁止进入状态输入,为此就必须对按键进行消抖处理,消除出现抖动时的不稳定的、随机的电压信号。测试过程中发现机械式按键的抖动次数、抖动时间、抖动波形都是随机的,而不同类型的按键其最长抖动时间也有差别,进一步查阅相关资料可知抖动时间的长短和按键的机械特性有关,一般为5-10ms,但是有些按键的抖动时间可达到20 ms,甚至更长。所以在具体设计过程中要具体分析,根据实际情况来调整设计。

3、分析代码后发现,在设置端口数据时将端口宽度设置为4(如下):

        未对输出端口进行分组处理,因此会导致每个数字都按照四位二进制的形式有4个输出,因此可以将原先定义在结构体内的信号经译码后打包送到对应输出端口(一种可行的解决方案如下):

4、根据设置的信号量分析可知,应当在c1和k1处固定显示小数点,经过分析决定设置一个flag标记位,在片选模块中单独标记c1和k1两处(flag=1),其余部分不做标记(flag=0),最后在段选模块中根据flag的值进行输出,即flag=1时段选信号的第一位置“1”,即显示小数点,而flag=0时则相反。

八、总结

        通过本次数字系统设计实验设计,首先我学到了很多关于数字逻辑和数字系统的知识,基本理解了一些系统的设计理念以及设计方案的制定和流程。同时通过对VHDL硬件描述语言的学习,我深刻的感受到了软硬件相结合的强大,基于软件设计硬件的方法十分高效,同时代码相对于电路更具备可读性,能更好的理解系统设计原理和方法。本次我选择的出租车计价器设计难度中等偏上,在我完成实验设计的过程中遇到了很多问题,比如对VHDL硬件描述语言的基本语法掌握得不够熟练,亦或者是对数字逻辑的相关知识和一些基础的实验元件的认识不足,因此设计过程举步维艰,对信号量的设计也有很多的不合理之处,比如输出信号量cost、kilogram和minute,最早设计的时候采取的方案是单独设置输出信号量out static_logic_vector(3 downto 0),输出对应的二进制数,但没有考虑到数码管的译码部分,从而导致无法正确选择合适的引脚进行数码显示。之后我意识到这个问题后决定将其包装一下,对四位BCD码进行译码后,再送入后续改进设计的段选模块和片选模块进行输出,从而解决了这一问题。在完成实验之后我也尝试思考一些实验过程中的问题,尝试去改进一些方法策略,后来发现了按键抖动的问题之后设计了消除抖动的模块,为了进行更好的演示将等待时间计时的分钟显示改为秒钟显示……通过不断的思考,我也渐渐掌握了一定的设计能力,培养了创新思想。但仅仅是对VHDL硬件描述语言的掌握是远远不够完成实验的,管脚的连接、实验板的操作或是软件的安装使用都出现过问题,而只是学习书本上的知识也是不够的,书本上的知识往往偏向理论,实际实验涉及到的范围往往更广,因此也应该要不断学习,自觉拓展知识面,开拓视野,一步一步的完成每一件学习任务,这样才能更好的掌握EDA这门课程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/233013.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【工厂方法】设计模式项目实践

前言 以采集数据处理逻辑为例&#xff0c;数据采集分为不同种类如&#xff1a;MQTT、MODBUS、HTTP等&#xff0c;不同的采集数据有不同的解析处理逻辑。但总体解析处理步骤是固定的。可以使用工厂方法设计模式简化代码&#xff0c;让代码变得更加优雅。 代码实践 抽象类 总体…

蒙特霍尔问题(选择三扇门后的车与羊)及其贝叶斯定理数学解释

1. 蒙特霍尔问题 有一个美国电视游戏节目叫做“Let’s Make a Deal”&#xff0c;游戏中参赛者将面对3扇关闭的门&#xff0c;其中一扇门背后有一辆汽车&#xff0c;另外两扇门后是山羊&#xff0c;参赛者如果能猜中哪一扇门后是汽车&#xff0c;就可以得到它。 通常&#xf…

工业4.0分类:数字化转型的多维度

引言 工业4.0代表着制造业的数字化革命&#xff0c;它将制造过程带入了数字时代。然而&#xff0c;工业4.0并不是一个单一的概念&#xff0c;而是一个多维度的范畴&#xff0c;包括不同的技术、应用领域、企业规模和实施方式。但在这一多维度的概念中&#xff0c;低代码技术正…

shell基本知识

Linux 系统中 shell 的基本知识 1 什么是 shell Shell 是一种命令行解释器&#xff0c;它为用户提供了一个向 Linux 内核发送请求以便运行程序的界面系统级程序。用户可以用 shell 来启动、挂起、停止甚至是编写一些程序。 2 Linux 启动过程 Linux 系统的启动过程可以概括为…

[强网拟态决赛 2023] Crypto

文章目录 Bad_rsaClasslcal Bad_rsa 题目描述&#xff1a; from Crypto.Util.number import *f open(flag.txt,rb) m bytes_to_long(f.readline().strip())p getPrime(512) q getPrime(512) e getPrime(8) n p*q phi (p-1)*(q-1) d inverse(e,phi) leak d & ((1…

L1-032:Left-pad

题目描述 根据新浪微博上的消息&#xff0c;有一位开发者不满NPM&#xff08;Node Package Manager&#xff09;的做法&#xff0c;收回了自己的开源代码&#xff0c;其中包括一个叫left-pad的模块&#xff0c;就是这个模块把javascript里面的React/Babel干瘫痪了。这是个什么样…

【11】Qt Designer

目录 VSCode添加外部工具 QtDesigner PyUIC PyRCC 加载UI文件模板代码 QMainWindow QWidget 常用知识点 1. 修改标题图标 2. 图片资源管理 3. 图片按钮 4. 加载对话框 5. 动态加载Widget 6. 修改主题 其他注意事项 事件被多次触发 PyQt5提供了一个可视化图形工…

【springboot设计源码】庆阳非物质文化遗产展示平台课题背景、目的、意义、研究方法

该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程等学习内容。 目录 一、项目介绍&#xff1a; 二、文档学习资料&#xff1a; 三、模块截图&#xff1a; 四、开发技术与运行环境&#xff1a; 五、代码展示&#xff1a; 六、数据库表截图&#xff1…

正在快速兴起的云数据架构

云数据架构的日益流行表明了一个主题&#xff1a;在未来几年&#xff0c;越来越多的企业将把他们的数据中心业务完全迁移到云平台上&#xff0c;因为内部部署数据中心设施具有一些固有的优势。数字时代的企业生存已经成为向云迁移的代名词。 云数据架构的日益流行表明了一个主…

sqlite3.44.2的编译

文章目录 sqlite3.44.2的编译概述笔记解决shell.c编译报错的方法整理 - 正常可用的编译脚本过程剩下的事情验证编译出的输出是否可以给工程正常使用?END sqlite3.44.2的编译 概述 想从源码编译一份Sqlite3.44.2出来. 编译sqlite3.44.2前置需要的TCL环境已经编译出来到了, 做…

排序:挖坑快排前后指针快排

目录 挖坑快排&#xff1a; 代码实现&#xff1a; 代码分析&#xff1a; 前后指针快排&#xff1a; ​编辑动画分析&#xff1a; 代码分析&#xff1a; 代码演示&#xff1a; 快排的优化&#xff1a;三数取一 挖坑快排&#xff1a; 挖坑法&#xff0c;顾名思义&am…

球上进攻^^

欢迎来到程序小院 球上进攻 玩法&#xff1a;点击鼠标走动躲避滚动的球球&#xff0c;球球碰到即为游戏结束&#xff0c;看看你能坚持多久&#xff0c;快去玩吧^^。开始游戏https://www.ormcc.com/play/gameStart/214 html <div id"game" class"game" …

Vue3组合式API详解

目录 一、setup详解 二、ref详解 三、computed详解 四、watch详解 &#xff08;1&#xff09;监听单个数据的变化 &#xff08;2&#xff09;监听多个数据的变化 &#xff08;3&#xff09;immediate &#xff08;4&#xff09;deep &#xff08;5&#xff09;精确监听…

排序:非递归的快排

目录 非递归的快排&#xff1a; 代码分析&#xff1a; 代码演示&#xff1a; 非递归的快排&#xff1a; 众所周知&#xff0c;递归变成非递归&#xff0c;而如果还想具有递归的功能&#xff0c;那么递归的那部分则需要变成循环来实现。 而再我们的排序中&#xff0c;我们可…

PHP入门软件Wampserver与vscode

PHP入门软件Wampserver与vscode Wampserver 一个集成的PHP环境&#xff0c;非常好用&#xff0c;上链接官网&#xff1a;https://www.wampserver.com/#download-wrapper 推荐华军https://www.onlinedown.net/soft/82112.htm 无脑下一步就行&#xff0c;会出现两个弹窗全点否。…

我在Vscode学OpenCV 图像处理二(滤除噪声干扰)

图像处理二 滤除噪声干扰三、噪声3.1图像噪声3.2 滤波3.2.1均值滤波&#xff08;1&#xff09;锚点&#xff08;2&#xff09;中心点&#xff08;下面第3小点会详细解释&#xff09;&#xff08;3&#xff09;核的大小奇偶数的区别&#xff08;1&#xff09;举例奇偶的例子&…

vue-seamless-scroll无缝滚动组件

首先找到他的官网vue-seamless-scroll 1.进行安装依赖 vue2 npm install vue-seamless-scroll --save vue3 npm install vue3-seamless-scroll --save 2.全局引入 vue2 import scroll from vue-seamless-scroll Vue.use(scroll) vue3 import vue3SeamlessScroll fro…

2023年【建筑电工(建筑特殊工种)】免费试题及建筑电工(建筑特殊工种)试题及解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年建筑电工(建筑特殊工种)免费试题为正在备考建筑电工(建筑特殊工种)操作证的学员准备的理论考试专题&#xff0c;每个月更新的建筑电工(建筑特殊工种)试题及解析祝您顺利通过建筑电工(建筑特殊工种)考试。 1、【…

不同品牌的手机如何投屏到苹果MacBook?例如小米、华为怎样投屏比较好?

习惯使用apple全家桶的人当然知道苹果手机或iPad可以直接用airplay投屏到MacBook。 但工作和生活的多个场合里&#xff0c;并不是所有人都喜欢用同一品牌的设备&#xff0c;如果同事或同学其他品牌的手机需要投屏到MacBook&#xff0c;有什么方法可以快捷实现&#xff1f; 首先…

第76讲:MySQL数据库中常用的命令行工具的基本使用

文章目录 1.mysql客户端命令工具2.mysqladmin管理数据库的客户端工具3.mysqlbinlog查看数据库中的二进制日志4.mysqlshow统计数据库中的信息5.mysqldump数据库备份工具6.mysqllimport还原备份的数据7.source命令还原SQL类型的备份文件 MySQL数据库提供了很多的命令行工具&#…