定时器VHDL设计.docx
《定时器VHDL设计.docx》由会员分享,可在线阅读,更多相关《定时器VHDL设计.docx(34页珍藏版)》请在冰豆网上搜索。
![定时器VHDL设计.docx](https://file1.bdocx.com/fileroot1/2023-6/17/a40dd280-1f9e-48ca-b554-dea42e1d93f3/a40dd280-1f9e-48ca-b554-dea42e1d93f31.gif)
定时器VHDL设计
定时器
1.实验任务
设计要求:
整体清零;可以定时最高到99min;以秒速度递增至预定时间,以分速度递减至零。
总体框图如下图所示:
clr用来整体复位清零;clk提供了秒信号,频率为1HZ(在仿真中取10MHZ);clky是用来扫描输出的,选用频率大于50HZ的方波(为便于观察结果,在仿真中取10MHZ);set是用来置位的,低电平时有效,将以秒的速度,从零递增到所需定时的时间,为高电平时以分的速度递减,实现定时,直到零,定时结束;alm输出高电平,可启动各种电路或发出警报。
时间的变化都将在数码管上显示出来。
2.模块及模块功能
模块AAA见下图示。
它是核心模块,用来实现定时器的逻辑功能,计数结果用十进制数输出。
LIBRARYieee;
USEieee.std_logic_1164.all;
USEieee.std_logic_unsigned.all;
ENTITYaaaIS
PORT(clk,clr,set:
instd_logic;
alm:
outstd_logic;
q1,q0:
outstd_logic_vector(3downto0));
ENDaaa;
ARCHITECTUREaaa_arcOFaaaIS
BEGIN
PROCESS(clk,clr)
variablet1,cnt0:
std_logic_vector(3downto0);
variablet:
integerrange0to59;
BEGIN
IFclr='0'THEN--整体复位
alm<='0';
t:
=0;
t1:
="0000";
t0:
="0000";
ELSIFclk'EVENTANDclk='1'THEN--设计数初值
IFset='0'THEN
t:
=0;
IFt0<"1001"THEN
t0:
=cnt0+1;
ELSE
t0:
="0000";
IFt1<"1001"THEN
t1:
=cnt1+1;
ELSE
t1:
="0000";
ENDIF;
ENDIF;
ELSE
IFt<59THEN--60分频
t:
=cnt+1;
ELSE
t:
=0;
IFt0>"0000"THEN
t0:
=cnt0-1;
IFt1="0000"ANDt0="0000"THEN--判断计时是否结束
alm<='1';
ENDIF;
ELSE
t0:
="1001";
IFt1>"0000"THEN
t1:
=cnt1-1;
ELSE
t1:
="1001";
ENDIF;
ENDIF;
ENDIF;
ENDIF;
ENDIF;
q0<=cnt0;
q1<=cnt1;
ENDPROCESS;
ENDaaa_arc;
模块CH如下图示。
由于只用了两个数码管,所以片选信号直接接一个较快的时钟。
此模块的功能是对应片选信号,送出要显示的数据。
LIBRARYieee;
USEieee.std_logic_1164.all;
ENTITYchIS
PORT(sel:
instd_logic;
a1,a0:
instd_logic_vector(3downto0);
q:
outstd_logic_vector(3downto0));
ENDch;
ARCHITECTUREch_arcOFchIS
BEGIN
PROCESS(sel,a0,a1)
BEGIN
IFsel='0'THEN
q<=a0;
ELSE
q<=a1;
ENDIF;
ENDPROCESS;
ENDch_arc;
模块DISP如下图示。
该模块为七段译码器。
LIBRARYieee;
USEieee.std_logic_1164.all;
ENTITYdispIS
PORT(a:
instd_logic_vector(3downto0);
q:
outstd_logic_vector(6downto0));
ENDdisp;
ARCHITECTUREdisp_arcOFdispIS
BEGIN
PROCESS(a)
BEGIN
CASEaIS
WHEN"0000"=>q<="0111111";
WHEN"0001"=>q<="0000110";
WHEN"0010"=>q<="1011011";
WHEN"0011"=>q<="1001111";
WHEN"0100"=>q<="1100110";
WHEN"0101"=>q<="1101101";
WHEN"0110"=>q<="1111101";
WHEN"0111"=>q<="0000111";
WHEN"1000"=>q<="1111111";
WHEN"1001"=>q<="1101111";
WHENothers=>q<="0000000";
ENDCASE;
ENDPROCESS;
ENDdisp_arc;
3.仿真结果分析
总体仿真结果如下:
由图可见,clr=’0’可实现整体复位功能。
set=’0’,输出以秒的速度从零递增。
本图中当递增到26后,set=’1’,输出经60分频后以分的速度递减,实现定时,直到零,定时结束。
定时结束后,clm=’1’,此时可启动各种电路或发出报警,定时结束。
clr=’0’,整体复位,clm=’0’。
该设计采用动态扫描电路,经过二选一模块将结果显示出来。
从上图可见,q交替输出两位结果。
sel=’1’时输出高位,sel=’0’时输出低位。
自动售货机控制器
一、设计一个自动售货机的控制电路。
该自动售货机销售价格为25美分的糖果,利用有限状态机进行电路设计。
控制器的输入输出如图所示:
输入信号是nickel_in(投入5美分),dime_in(投入10美分),quarter_in(投入25美分)。
另外两个必要的输入是clk(时钟)和rst(复位)。
控制器相应的有3个输出:
candy_out用于控制发放糖果,nickel_out用于控制找回5美分的零钱,dime_out用于控制找回10美分的零钱。
上图给出了有限状态机的状态转移图。
圆圈里的数代表顾客投进来的总钱数(接受5美分、10美分或25美分的硬币)。
状态0是空闲状态。
从它开始,如果投入5美分硬币,将跳转到状态5;如果投入10美分硬币,将跳转到状态10;如果投入25美分硬币,将跳转到状态25。
随着投币数量的增加,状态不断跳转,如果投入的币值达到25美分,就可以进入状态25,然后售货机会发放糖果,并跳转回状态0。
如果投入的币值超过了25美分,那么售货机要进入与找零钱相关的状态。
例如,当投入的币值达到40美分时,需要先退出5美分硬币(进入状态35),然后再退出10美分,发放糖果并进入状态0。
二、该设计的VHDL源码如下:
在代码中定义了枚举类型state,它包含10个状态,所以至少需要用4位对其进行编码(将产生4个寄存器)。
在默认状态下,编译器将按照它们的排列顺序对其进行编码,所以有st0=”0000”(十进制的0),st5=”0001”(十进制的1),…和st45=”1001”(十进制的9)。
在仿真中,这些数字将替代状态的名称出现在仿真波形中。
LIBRARYieee;
USEieee.std_logic_1164.all;
ENTITYvending_machineIS
PORT(clk,rst:
INSTD_LOGIC;
nickel_in,dime_in,quarter_in:
INBOOLEAN;
candy_out,nickel_out,dime_out:
OUTSTD_LOGIC);
ENDvending_machine;
ARCHITECTUREfsmOFvending_machineIS
TYPEstateIS(st0,st5,st10,st15,st20,st25,st30,st35,st40,st45);
SIGNALpresent_state,next_state:
STATE;
BEGIN
PROCESS(rst,clk)
BEGIN
IF(rst='1')THEN
present_state<=st0;
ELSIF(clk'EVENTANDclk='1')THEN
present_state<=next_state;
ENDIF;
ENDPROCESS;
PROCESS(present_state,nickel_in,dime_in,quarter_in)
BEGIN
CASEpresent_stateIS
WHENst0=>
candy_out<='0';
nickel_out<='0';
dime_out<='0';
IF(nickel_in)THENnext_state<=st5;
ELSIF(dime_in)THENnext_state<=st10;
ELSIF(quarter_in)THENnext_state<=st25;
ELSEnext_state<=st0;
ENDIF;
WHENst5=>
candy_out<='0';
nickel_out<='0';
dime_out<='0';
IF(nickel_in)THENnext_state<=st10;
ELSIF(dime_in)THENnext_state<=st15;
ELSIF(quarter_in)THENnext_state<=st30;
ELSEnext_state<=st5;
ENDIF;
WHENst10=>
candy_out<='0';
nickel_out<='0';
dime_out<='0';
IF(nickel_in)THENnext_state<=st15;
ELSIF(dime_in)THENnext_state<=st20;
ELSIF(quarter_in)THENnext_state<=st35;
ELSEnext_state<=st10;
ENDIF;
WHENst15=>
candy_out<='0';
nickel_out<='0';
dime_out<='0';
IF(nickel_in)THENnext_state<=st20;
ELSIF(dime_in)THENnext_state<=st25;
ELSIF(quarter_in)THENnext_state<=st40;
ELSEnext_state<=st15;
ENDIF;
WHENst20=>
candy_out<='0';
nickel_out<='0';
dime_out<='0';
IF(nickel_in)THENnext_state<=st25;
ELSIF(dime_in)THENnext_state<=st30;
ELSIF(quarter_in)THENnext_state<=st45;
ELSEnext_state<=st20;
ENDIF;
WHENst25=>
candy_out<='1';
nickel_out<='0';
dime_out<='0';
next_state<=st0;
WHENst30=>
candy_out<='1';
nickel_out<='1';
dime_out<='0';
next_state<=st0;
WHENst35=>
candy_out<='1';
nickel_out<='0';
dime_out<='1';
next_state<=st0;
WHENst40=>
candy_out<='0';
nickel_out<='1';
dime_out<='0';
next_state<=st35;
WHENst45=>
candy_out<='0';
nickel_out<='0';
dime_out<='1';
next_state<=st35;
ENDCASE;
ENDPROCESS;
ENDfsm;
三、仿真结果分析
仿真结果如下图示:
由上图可以看到:
第一个周期内,一共投入了3个5美分硬币和1个25美分硬币。
在第一个5美分硬币投进去后的第一个时钟上升沿出现时,有限状态机的状态从st0(十进制的0)转到了st5(十进制的1)。
在投入第二个5美分硬币后状态转到st10(十进制的2),投入第二个5美分硬币后状态转到st15(十进制的3),在25美分硬币投进去以后,状态变为st40(十进制的8)。
此后,售货机退还顾客一个5美分硬币(nickle_out=’1’),同时状态机进入st35(十进制的7),接着退还10美分硬币(dime_out=’1’)并发放糖果(candy_out=’1’),同时状态回到空闲状态(st0)。
其他输入组合的分析同上。
二、2.设计帧同步检测电路,输入位宽1位的二进制序列及时钟,输出高电平脉冲的检测结果。
对输入的二进制序列检测帧同步序列“01011”,即当输入的二进制序列中出现帧同步序列时,输出一个高电平脉冲。
(1).设计原理
用状态机,状态转换图如下图示:
状态转换图
各状态定义如下:
S0:
空闲状态或仅输入“1”;
S1:
输入一个“0”后的状态;
S2:
输入序列“01”后的状态;
S3:
输入序列“010”后的状态;
S4:
输入序列“0101”后的状态;
S5:
输入帧同步序列“01011”后的状态,此时输出一个高电平脉冲。
管脚图
管脚说明:
CLK—时钟信号;X—输入二进制序列;Y—输出变量。
(2).VHDL源程序:
LIBRARYieee;
USEieee.std_logic_1164.all;
USEieee.std_logic_arith.all;
USEieee.std_logic_unsigned.all;
ENTITYcheckIS
PORT(clk,x:
instd_logic;
y:
outstd_logic);
ENDcheck;
ARCHITECTUREcheck_arcOFcheckIS
typestateis(s0,s1,s2,s3,s4,s5);
signalpresent_state:
state;
signalnext_state:
state;
BEGIN
s:
PROCESS(clk)
BEGIN
IFclk'eventandclk='1'THEN
present_state<=next_state;
ENDIF;
ENDPROCESSs;
c:
PROCESS(x,present_state)
BEGIN
casepresent_stateis
whens0=>y<='0';
ifx='0'then
next_state<=s1;
else
next_state<=s0;
endif;
whens1=>y<='0';
ifx='1'then
next_state<=s2;
else
next_state<=s1;
endif;
whens2=>y<='0';
ifx='0'then
next_state<=s3;
else
next_state<=s0;
endif;
whens3=>y<='0';
ifx='1'then
next_state<=s4;
else
next_state<=s1;
endif;
whens4=>y<='0';
ifx='1'then
next_state<=s5;
else
next_state<=s3;
endif;
whens5=>y<='1';
ifx='1'then
next_state<=s0;
else
next_state<=s1;
endif;
whenothers=>null;
endcase;
ENDPROCESSc;
ENDcheck_arc;
(3).仿真结果及其分析
仿真结果如下图示:
仿真结果分析:
由以上截图可以看到,当输入的二进制序列x=“01011”,即检测到帧同步序列时,y输出一个高电平脉冲。
且由第三个图可见,当clk取
Hz时,输出有12.6ns/12.8ns的延时。
二、3.设计可以对两个运动员赛跑计时的秒表,要求如下:
(1)秒表的输入只有时钟(clk)和一个按键(key),假设key已经经过防抖动和脉冲宽度处理,每按一次key产生持续一个时钟周期的高电平脉冲,可以满足设计的需要,不需要对key再做任何处理。
(2)秒表输出用0-59的整数表示,不需要对十位和个位分别计数,不需要7段译码。
(3)键key的功能如下:
(A)按第一下key,开始计数,并输出计数值;
(B)第一个运动员到终点时按第二下key,秒表记住第一个运动员到终点的时间,但还在继续计数并输出计数值;
(C)第二个运动员到终点时按第三下key,停止计数,这时输出的计数值就是第二个运动员用的时间;
(D)然后按第四下key,秒表输出第一个运动员到终点的时间,即按第二下key时记住的计数值;
(E)按第五下key,秒表清0,开始新的周期。
(4)画出秒表的状态转移图,标明各个状态的转移条件和输出。
(5)用VHDL完成秒表的设计。
(1).设计原理:
该设计的状态转移图如下:
其中,S0:
空闲状态,输出为0;
S1:
第一个key按下后的状态,输出计数值;
S2:
第二个key按下后的状态,输出计数值,并记下第一个运动员到达终点的时间;
S3:
第三个key按下后的状态,输出第二个运动员所用时间;
S4:
第四个key按下后的状态,输出第一个运动员所用时间;
S5:
第五个key按下后的状态,输出清零。
(2).VHDL源程序如下:
LIBRARYieee;
USEieee.std_logic_1164.all;
USEieee.std_logic_arith.all;
USEieee.std_logic_unsigned.all;
ENTITYsecondIS
PORT(clk,key:
instd_logic;
count:
outintegerrange0to59);
ENDsecond;
ARCHITECTUREsecond_arcOFsecondIS
typestateis(s0,s1,s2,s3,s4,s5);
signalpresent_state:
state;
signalnext_state:
state;
BEGIN
h:
PROCESS(key)
BEGIN
IFkey='1'THEN
present_state<=next_state;
ENDIF;
ENDPROCESSh;
s:
PROCESS(present_state)
BEGIN
CASEpresent_stateIS
WHENs0=>next_state<=s1;
WHENs1=>next_state<=s2;
WHENs2=>next_state<=s3;
WHENs3=>next_state<=s4;
WHENs4=>next_state<=s5;
WHENs5=>next_state<=s1;
WHENothers=>null;
ENDCASE;
ENDPROCESSs;
c:
PROCESS(clk,present_state)
variablec1,c2:
integerrange0to59;
BEGIN
IFclk'eventandclk='1'THEN
casepresent_stateis
whens0=>c1:
=0;
c2:
=0;
count<=0;
whens1=>c1:
=c1+1;
c2:
=c2+1;
count<=c1;
whens2=>c2:
=c2+1;
count<=c2;
whens3=>count<=c2;
whens4=>count<=c1;
whens5=>c1:
=0;
c2:
=0;
count<=0;
whenothers=>null;
endcase;
ENDIF;
ENDPROCESSc;
ENDsecond_arc;
(3).仿真结果及其分析
仿真结果如下图示:
仿真结果分析:
仿真中clk时钟频率为
Hz,(实际应用中采用1Hz)。
由以上3副截图可以看出:
在第一个计数周期内,按第一下key(2us)后,clk上升沿到来时,系统开始计数,并同时输出计数值;
第一个运动员到终点(23us)时按第二下key,秒表记住第一个运动员到终点的时间(23us-2us=21us),但还在继续计数并输出计数值;
第二个运动员到终点(30us)时按第三下key,停止计数,这时输出的计数值(28)就是第二个运动员用的时间(30us-2us=28us);
然后按第四下key,秒表输出第一个运动员到终点的时间(21),即按第二下key时记住的计数值;
按第五下key,秒表清0,开始新的周期。
此外,由图可见,present_state的变化发生在key=“1”且时钟上升沿来临时。
其改变与状态转换图给出的一致。
二、自选题三层电梯控制器
1.实验任务
(1)每层电梯入口处设有上下请求开关,电梯内设有乘客到达层次的停站请求开关。
(2)设有电梯处所处位置指示装置及电梯运行模式(上升或下降)指示装置。
(3)电梯每秒升(降)一层楼(在仿真中取1
s)。
(4)电梯到达有停站请求的楼层后,经过1s(在仿真中取1
s)电梯门打开,开门指示灯亮,开门4s(在仿真中取2
s)后,电梯门关闭(开门指示灯灭),电梯继续运行,直至执行完最后一个请求信号后停在当前层。
(5)能记忆电梯内外的所有请求信号,并按照电梯运行规则次序响应,每个请求信号保留至执行后清除。
(6)电梯运行规则:
当电梯处于上升模式时,只响应比电梯所在位置高的上楼请求信号,由下而上逐个执行,直至最后一个上楼请求执行完毕,如更高层有下楼请求,则直接升到下楼请求的最高楼接客,然后便进入下降模式。
当电梯处于下降模式时,则与上升模