七人表决器的VHDL程序设计.doc
一、题目 用VHDL设计七人表决器二、分析讨论: 七人表决器这一功能用C语言、汇编语言或VHDL编程然后下载到单片机上实现,不过用VHDL编程不仅技术含量高而且能让我们更熟练的掌握使用quartus软件的步骤和方法。所以我们使用VHDL完成。七人表决器就是当投票的人中,同意个数过半(即大于等于4)时,认为通过;否则,不通过。 在编程中我们使用一个七位二进制输入变量表示投票人;一个七位二进制输出变量表示一个七段数码管显示同意的票数;一个一位的输出变量表示最终的投票结果。此结果能够在quartus软件中通过时序仿真。 在硬件上我们用七个拨动开关来表示七个投票人,拨动开关为1时表示同意,为0表示不同意;同意的票数和表决的时间分别通过一个七段数码管显示出来;最终的表决结果用一个LED表示。 三、设计方案 31实现原理 首先,编写一个十进制的减法计数器,其输入为clk, clr, en,输出为q3.0。外部的时钟信号的频率选择为1KHz,此频率太大无法显示投票的限制时间,所以要用一个分频器来增大计数时间。设计一个分频器的程序,将时钟信号经过分频器输入到计数器中,输入为clk, 输出为 new clk。当clk 有1000个上升沿是newclk产生一个脉冲,也就是计数器计数一次。其次,编辑七人表决器在主程序,其输入为clk, clr, en, input6.0, q3.0,输出为output,led6.0。此程序的是时钟脉冲clk也为1KHz;当q从9到4期间投票是有效的,在4到0期间是无效的,此时就显示之前同意的票数。记录的票数通过casa语句转换到8位七段数码管显示出来。投票的时间和记录的票数要通过两个数码管显示,所以要用一个三八译码器来完成。接着编辑一个三八译码器的程序,其输入为clk, led6.0, q3.0, 输出为 choice, data7.0。程序中当用一个中间变量来选择数码管,由于clk的扫描的频率很大,所以两个数码管看上去是同时显示。 32 实现条件 在quartus环境下编辑操作; 外部时钟信号; 控制引脚。3.3 算法的描述 首先,编写十进制的减法计数器,其输入为clk, clr, en,输出为q3.0,运行之后生成模块器件。这个子程序中主要用到的算法是if语句:if(clr='0')then count_4<="1001"elsif(clk'event and clk='1')thenif(en='1')thenif(count_4="0000")thencount_4<="1001"elsecount_4<=count_4-'1'end if;end if;end if; 其次,编辑七人表决器在主程序,其输入为cl, clr, en, input6.0, q3.0,输出为led6.0;生成模块器件。此程序中主要用到的算法有case语句和loop语句: for i in 6 downto 0 loop if (input(i)='1')then cnt:=cnt+1; else cnt:=cnt; end if; end loop;case cnt is when 0=>x:="1111110" when 1=>x:="0110000" when 2=>x:="1101101" when 3=>x:="1111001" when 4=>x:="0110011" when 5=>x:="1011011" when 6=>x:="1011111" when 7=>x:="1110000" when others=>x:="0000000"end case; 接着编辑三八译码器的程序,其输入为clk, led6.0, q3.0, 输出为 choice, data7.0, 生产模块器件。此程序中用到的算法主要有if语句和casa语句。 if clk'event and clk='1' THEN if count='1' then count<='0' else count<='1' end if;end if; case temp1 is when "0000"=>datain<="11111100" when "0001"=>datain<="01100000" when "0010"=>datain<="11011010" when "0011"=>datain<="11110010" when "0100"=>datain<="01100110" when "0101"=>datain<="10110110" when "0110"=>datain<="10111110" when "0111"=>datain<="11100000" when "1000"=>datain<="11111110" when "1001"=>datain<="11110110" when others=>datain<="00000000" end case; 最后,设计一个分频器的程序,将时钟信号经过分频器输入到计数器中,输入为clk, 输出为 new clk 。此程序主要用到的算法是if语句。 if clk'event and clk='1' then if cnter=999 then cnter<=0; else cnter<=cnter+1; end if; end if; 将生产的四个模块器件连接到一起形成的BLOCK文件如下图所示:四、仿真结果: 4.1、仿真条件: 软件仿真和硬件仿真:软件仿真是在quartus中建立一个vector waveform file文件,将工程block中的输入输出变量名称加载进去,设置输入变量值进行时序仿真。 硬件仿真是在quartus中将工程block的所有输入输出变量分配引脚,之后下载到硬件试验箱上,试验箱中所用到的模块是CycloneIIEP2C35F672C8 。 引脚分配图如下:4.2 仿真结果及必要说明 I、 软件仿真结果如下图所示:II、硬件仿真结果如下:4.3 仿真结果分析讨论1)软件分析 仿真是clk周期设置为1ms,clr和en都设置为高电平,input的周期设为10ms,clk在10个上升沿时当input【6.0】中1的个数大于3时output为1;小于3时为0。Clk有1000个上升沿时q3.0减1。Clk有一个上升沿时data交替显示q和led。2)硬件分析 D1显示表决结果通过与否;G0、G1分别显示同意的票数和投票时间范围;k1k7代表7个投票人,起始都置0。置1表示同意,置0表示反对。引脚分配完,下载到试验箱后clk的频率选择在1khz。开始仿真:G1显示从9减到0;当依次置k1、k2、k3、k4为1 ,G0从0加到4,D1显示亮。当G1减到4以后再拨动k1到k7,G0都不再变化,投票结束。 五、心得体会 VHDL 是由美国国防部为描述电子电路所开发的一种语言,其全称为(Very High Speed Integrated Circuit) Hardware Description Language。 与另外一门硬件描述语言 Verilog HDL 相比,VHDL 更善于描述高层的一些设计,包括系统级(算法、数据通路、控制)和行为级(寄存器传输级),而且 VHDL 具有设计重用、大型设计能力、可读性强、易于编译等优点逐渐受到硬件设计者的青睐。但是,VHDL 是一门语法相当严格的语言,易学性差,特别是对于刚开始接触 VHDL 的设计者而言,经常会因某些小细节处理不当导致综合无法通过。我在这个设计过程中就有很深刻的体会。在设计七人表决器的时候,首先是主程序的编程,编程中会出现VHDL语言的描述错误,经过反复的思考、修改才编写成功。然后,对课程设计任务书的每个要求进行编程设计,过程中用到了最基本的三八译码器和分频器,让我对这两个器件的程序也能熟练应用。最后就是仿真过程,通过请教和咨询老师和同学我顺利的完成了任务书中要求的所有功能。此次课程设计让我对quartus软件的使用有了更为深刻的掌握,学会了用VHDL设计一个七人表决器的整个设计过程,在这个设计过程中我的收获很大。在这次的设计过程中我明白了只要认真用心坚持去做一件据一点能够完美的做好。附件:七人表决器主程序library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity bjq2 isport (input:in std_logic_vector(6 downto 0); q:in std_logic_vector(3 downto 0); clk,clr,en:in std_logic; l:out std_logic_vector(6 downto 0); output:out std_logic);end bjq2;architecture art of bjq2 isbeginprocess(input,q,clr,en,clk)variable cnt:integer range 0 to 7;variable x:std_logic_vector(0 to 6);begincnt:=0;if(q="0100")then cnt:=cnt;else if(clr='0')then cnt:=0; elsif(en='1')then for i in 6 downto 0 loop if (input(i)='1')then cnt:=cnt+1; else cnt:=cnt; end if; end loop; end if;case cnt iswhen 0 to 3 =>output<='0'when 4 to 7 =>output<='1'end case;case cnt is when 0=>x:="1111110" when 1=>x:="0110000" when 2=>x:="1101101" when 3=>x:="1111001" when 4=>x:="0110011" when 5=>x:="1011011" when 6=>x:="1011111" when 7=>x:="1110000" when others=>x:="0000000" end case;l<=x;end if;end process;end art;十进制计数器library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity count10 isport (clk,clr,en:in std_logic; q:out std_logic_vector(3 downto 0);end count10;architecture rtl of count10 issignal count_4:std_logic_vector(3 downto 0);beginq(0)<=count_4(0);q(1)<=count_4(1);q(2)<=count_4(2);q(3)<=count_4(3);process(clk,clr)beginif(clr='0')then count_4<="1001"elsif(clk'event and clk='1')thenif(en='1')thenif(count_4="0000")thencount_4<="1001"elsecount_4<=count_4-'1'end if;end if;end if;end process;end rtl;译码器library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;ENTITY ymq1 ISPORT( clk: INSTD_LOGIC; p1 : INSTD_LOGIC_VECTOR(6 downto 0); p2 : IN STD_LOGIC_VECTOR(3 downto 0);choice: OUTSTD_LOGIC;data: OUTSTD_LOGIC_VECTOR(7 downto 0);END ymq1;ARCHITECTURE art OF ymq1 IS SIGNAL count : STD_LOGIC;-_VECTOR(2 downto 0);SIGNAL temp : STD_LOGIC_VECTOR(6 downto 0);signal temp1: STD_LOGIC_VECTOR(3 downto 0);SIGNAL choicein :STD_LOGIC;-_VECTOR(2 downto 0);SIGNAL datain : STD_LOGIC_VECTOR(7 downto 0);beginclk1_label:PROCESS (clk)BEGINif clk'event and clk='1' THEN if count='1' then count<='0' else count<='1' end if;end if;END PROCESS clk1_label;clk2_label:process(clk,p1,p2)BEGINif clk'event and clk='1' then choicein<=count; choice<=choicein; data<=datain; if(count='1')then temp1<=p2(3 downto 0); case temp1 is when "0000"=>datain<="11111100" when "0001"=>datain<="01100000" when "0010"=>datain<="11011010" when "0011"=>datain<="11110010" when "0100"=>datain<="01100110" when "0101"=>datain<="10110110" when "0110"=>datain<="10111110" when "0111"=>datain<="11100000" when "1000"=>datain<="11111110" when "1001"=>datain<="11110110" when others=>datain<="00000000" end case; elsetemp<=p1(6 downto 0); case temp is WHEN "1111110"=>datain<="11111100" WHEN "0110000"=>datain<="01100000" WHEN "1101101"=>datain<="11011010" WHEN "1111001"=>datain<="11110010" WHEN "0110011"=>datain<="01100110" WHEN "1011011"=>datain<="10110110" WHEN "1011111"=>datain<="10111110" WHEN "1110000"=>datain<="11100000" WHEN "1111111"=>datain<="11111110" WHEN "1111011"=>datain<="11110110" WHEN "1110111"=>datain<="11101110" WHEN "0011111"=>datain<="00111110" WHEN "1001110"=>datain<="10011100" WHEN "0111101"=>datain<="01111010" WHEN "1001111"=>datain<="10011110" WHEN OTHERS=>datain<="00000000" end case;end if; data<=datain;end if;end process;END art;分频器library ieee;use ieee.std_logic_1164.all;entity fpq is port(clk:in std_logic; newclk:out std_logic);end entity fpq;architecture art of fpq is signal cnter:integer range 0 to 999; begin process(clk)is begin if clk'event and clk='1' then if cnter=999 then cnter<=0; else cnter<=cnter+1; end if; end if; end process; process(cnter)is begin if cnter=999 then newclk<='1' else newclk<='0' end if; end process;end art;工程图: