七人表决器的VHDL程序设计.docx
《七人表决器的VHDL程序设计.docx》由会员分享,可在线阅读,更多相关《七人表决器的VHDL程序设计.docx(13页珍藏版)》请在冰豆网上搜索。
![七人表决器的VHDL程序设计.docx](https://file1.bdocx.com/fileroot1/2023-1/11/3aa9b117-8b65-4a70-a140-27056341db8a/3aa9b117-8b65-4a70-a140-27056341db8a1.gif)
七人表决器的VHDL程序设计
一、题目用VHDL设计七人表决器
二、分析讨论:
七人表决器这一功能用C语言、汇编语言或VHDL编程然后下载到单片机上实现,不过用VHDL编程不仅技术含量高而且能让我们更熟练的掌握使用quartus软件的步骤和方法。
所以我们使用VHDL完成。
七人表决器就是当投票的人中,同意个数过半(即大于等于4)时,认为通过;否则,不通过。
在编程中我们使用一个七位二进制输入变量表示投票人;一个七位二进制输出变量表示一个七段数码管显示同意的票数;一个一位的输出变量表示最终的投票结果。
此结果能够在quartus软件中通过时序仿真。
在硬件上我们用七个拨动开关来表示七个投票人,拨动开关为‘1’时表示同意,为‘0’表示不同意;同意的票数和表决的时间分别通过一个七段数码管显示出来;最终的表决结果用一个LED表示。
三、设计方案
3.1实现原理
首先,编写一个十进制的减法计数器,其输入为clk,clr,en,输出为q[3..0]。
外部的时钟信号的频率选择为1KHz,此频率太大无法显示投票的限制时间,所以要用一个分频器来增大计数时间。
设计一个分频器的程序,将时钟信号经过分频器输入到计数器中,输入为clk,输出为newclk。
当clk有1000个上升沿是newclk产生一个脉冲,也就是计数器计数一次。
其次,编辑七人表决器在主程序,其输入为clk,clr,en,input[6..0],q[3..0],输出为output,led[6..0]。
此程序的是时钟脉冲clk也为1KHz;当q从9到4期间投票是有效的,在4到0期间是无效的,此时就显示之前同意的票数。
记录的票数通过casa语句转换到8位七段数码管显示出来。
投票的时间和记录的票数要通过两个数码管显示,所以要用一个三八译码器来完成。
接着编辑一个三八译码器的程序,其输入为clk,led[6..0],q[3..0],输出为choice,data[7..0]。
程序中当用一个中间变量来选择数码管,由于clk的扫描的频率很大,所以两个数码管看上去是同时显示。
3.2实现条件
在quartus环境下编辑操作;
外部时钟信号;
控制引脚。
3.3算法的描述
首先,编写十进制的减法计数器,其输入为clk,clr,en,输出为q[3..0],运行之后生成模块器件。
这个子程序中主要用到的算法是if语句:
if(clr='0')then
count_4<="1001";
elsif(clk'eventandclk='1')then
if(en='1')then
if(count_4="0000")then
count_4<="1001";
else
count_4<=count_4-'1';
endif;
endif;
endif;
其次,编辑七人表决器在主程序,其输入为cl,clr,en,input[6..0],q[3..0],输出为led[6..0];生成模块器件。
此程序中主要用到的算法有case语句和loop语句:
foriin6downto0loop
if(input(i)='1')then
cnt:
=cnt+1;
elsecnt:
=cnt;
endif;
endloop;
casecntis
when0=>x:
="1111110";
when1=>x:
="0110000";
when2=>x:
="1101101";
when3=>x:
="1111001";
when4=>x:
="0110011";
when5=>x:
="1011011";
when6=>x:
="1011111";
when7=>x:
="1110000";
whenothers=>x:
="0000000";
endcase;
接着编辑三八译码器的程序,其输入为clk,led[6..0],q[3..0],输出为choice,data[7..0],生产模块器件。
此程序中用到的算法主要有if语句和casa语句。
ifclk'eventandclk='1'THEN
ifcount='1'then
count<='0';
elsecount<='1';
endif;
endif;
casetemp1is
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";
whenothers=>datain<="00000000";
endcase;
最后,设计一个分频器的程序,将时钟信号经过分频器输入到计数器中,输入为clk,输出为newclk。
此程序主要用到的算法是if语句。
ifclk'eventandclk='1'then
ifcnter=999thencnter<=0;
elsecnter<=cnter+1;
endif;
endif;
将生产的四个模块器件连接到一起形成的BLOCK文件如下图所示:
四、仿真结果:
4.1、仿真条件:
软件仿真和硬件仿真:
软件仿真是在quartus中建立一个vectorwaveformfile文件,将工程block中的输入输出变量名称加载进去,设置输入变量值进行时序仿真。
硬件仿真是在quartus中将工程block的所有输入输出变量分配引脚,之后下载到硬件试验箱上,试验箱中所用到的模块是Cyclone
—EP2C35F672C8。
引脚分配图如下:
4.2仿真结果及必要说明
、软件仿真结果如下图所示:
、硬件仿真结果如下:
4.3仿真结果分析讨论
1)软件分析
仿真是clk周期设置为1ms,clr和en都设置为高电平,input的周期设为10ms,clk在10个上升沿时当input【6..0】中‘1’的个数大于3时output为‘1’;小于3时为‘0’。
Clk有1000个上升沿时q[3..0]减’1’。
Clk有一个上升沿时data交替显示q和led。
2)硬件分析
D1显示表决结果通过与否;G0、G1分别显示同意的票数和投票时间范围;k1—k7代表7个投票人,起始都置’0’。
置’1’表示同意,置’0’表示反对。
引脚分配完,下载到试验箱后clk的频率选择在1khz。
开始仿真:
G1显示从9减到0;当依次置k1、k2、k3、k4为’1’,G0从0加到4,D1显示亮。
当G1减到4以后再拨动k1到k7,G0都不再变化,投票结束。
五、心得体会
VHDL是由美国国防部为描述电子电路所开发的一种语言,其全称为(VeryHighSpeedIntegratedCircuit)HardwareDescriptionLanguage。
与另外一门硬件描述语言VerilogHDL相比,VHDL更善于描述高层的一些设计,包括系统级(算法、数据通路、控制)和行为级(寄存器传输级),而且VHDL具有设计重用、大型设计能力、可读性强、易于编译等优点逐渐受到硬件设计者的青睐。
但是,VHDL是一门语法相当严格的语言,易学性差,特别是对于刚开始接触VHDL的设计者而言,经常会因某些小细节处理不当导致综合无法通过。
我在这个设计过程中就有很深刻的体会。
在设计七人表决器的时候,首先是主程序的编程,编程中会出现VHDL语言的描述错误,经过反复的思考、修改才编写成功。
然后,对课程设计任务书的每个要求进行编程设计,过程中用到了最基本的三八译码器和分频器,让我对这两个器件的程序也能熟练应用。
最后就是仿真过程,通过请教和咨询老师和同学我顺利的完成了任务书中要求的所有功能。
此次课程设计让我对quartus软件的使用有了更为深刻的掌握,学会了用VHDL设计一个七人表决器的整个设计过程,在这个设计过程中我的收获很大。
在这次的设计过程中我明白了只要认真用心坚持去做一件据一点能够完美的做好。
附件:
七人表决器主程序
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitybjq2is
port(input:
instd_logic_vector(6downto0);
q:
instd_logic_vector(3downto0);
clk,clr,en:
instd_logic;
l:
outstd_logic_vector(6downto0);
output:
outstd_logic);
endbjq2;
architectureartofbjq2is
begin
process(input,q,clr,en,clk)
variablecnt:
integerrange0to7;
variablex:
std_logic_vector(0to6);
begin
cnt:
=0;
if(q="0100")then
cnt:
=cnt;
else
if(clr='0')then
cnt:
=0;
elsif(en='1')then
foriin6downto0loop
if(input(i)='1')then
cnt:
=cnt+1;
elsecnt:
=cnt;
endif;
endloop;
endif;
casecntis
when0to3=>output<='0';
when4to7=>output<='1';
endcase;
casecntis
when0=>x:
="1111110";
when1=>x:
="0110000";
when2=>x:
="1101101";
when3=>x:
="1111001";
when4=>x:
="0110011";
when5=>x:
="1011011";
when6=>x:
="1011111";
when7=>x:
="1110000";
whenothers=>x:
="0000000";
endcase;
l<=x;
endif;
endprocess;
endart;
十进制计数器
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entitycount10is
port(clk,clr,en:
instd_logic;
q:
outstd_logic_vector(3downto0));
endcount10;
architecturertlofcount10is
signalcount_4:
std_logic_vector(3downto0);
begin
q(0)<=count_4(0);
q
(1)<=count_4
(1);
q
(2)<=count_4
(2);
q(3)<=count_4(3);
process(clk,clr)
begin
if(clr='0')then
count_4<="1001";
elsif(clk'eventandclk='1')then
if(en='1')then
if(count_4="0000")then
count_4<="1001";
else
count_4<=count_4-'1';
endif;
endif;
endif;
endprocess;
endrtl;
译码器
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
ENTITYymq1IS
PORT(
clk:
INSTD_LOGIC;
p1:
INSTD_LOGIC_VECTOR(6downto0);
p2:
INSTD_LOGIC_VECTOR(3downto0);
choice:
OUTSTD_LOGIC;
data:
OUTSTD_LOGIC_VECTOR(7downto0));
ENDymq1;
ARCHITECTUREartOFymq1IS
SIGNALcount:
STD_LOGIC;--_VECTOR(2downto0);
SIGNALtemp:
STD_LOGIC_VECTOR(6downto0);
signaltemp1:
STD_LOGIC_VECTOR(3downto0);
SIGNALchoicein:
STD_LOGIC;--_VECTOR(2downto0);
SIGNALdatain:
STD_LOGIC_VECTOR(7downto0);
begin
clk1_label:
PROCESS(clk)
BEGIN
ifclk'eventandclk='1'THEN
ifcount='1'then
count<='0';
elsecount<='1';
endif;
endif;
ENDPROCESSclk1_label;
clk2_label:
process(clk,p1,p2)
BEGIN
ifclk'eventandclk='1'then
choicein<=count;
choice<=choicein;
data<=datain;
if(count='1')then
temp1<=p2(3downto0);
casetemp1is
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";
whenothers=>datain<="00000000";
endcase;
else
temp<=p1(6downto0);
casetempis
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";
WHENOTHERS=>datain<="00000000";
endcase;
endif;
data<=datain;
endif;
endprocess;
ENDart;
分频器
libraryieee;
useieee.std_logic_1164.all;
entityfpqis
port(clk:
instd_logic;
newclk:
outstd_logic);
endentityfpq;
architectureartoffpqis
signalcnter:
integerrange0to999;
begin
process(clk)is
begin
ifclk'eventandclk='1'then
ifcnter=999thencnter<=0;
elsecnter<=cnter+1;
endif;
endif;
endprocess;
process(cnter)is
begin
ifcnter=999thennewclk<='1';
elsenewclk<='0';
endif;
endprocess;
endart;
工程图: