定时器VHDL设计(特制材料)

定时器VHDL设计(特制材料)
定时器VHDL设计(特制材料)

定时器

1.实验任务

设计要求:整体清零;可以定时最高到99min;以秒速度递增至预定时间,以分速度递减至零。

总体框图如下图所示:

clr 用来整体复位清零;clk 提供了秒信号,频率为1HZ(在仿真中取10MHZ);clky 是用来扫描输出的,选用频率大于50HZ的方波(为便于观察结果,在仿真中取10MHZ);set 是用来置位的,低电平时有效,将以秒的速度,从零递增到所需定时的时间,为高电平时以分的速度递减,实现定时,直到零,定时结束;alm 输出高电平,可启动各种电路或发出警报。时间的变化都将在数码管上显示出来。

2.模块及模块功能

模块AAA见下图示。它是核心模块,用来实现定时器的逻辑功能,计数结果用十进制数输出。

LIBRARY ieee;

USE ieee.std_logic_1164.all;

USE ieee.std_logic_unsigned.all;

ENTITY aaa IS

PORT(clk, clr, set: in std_logic;

alm: out std_logic;

q1,q0: out std_logic_vector(3 downto 0));

END aaa;

ARCHITECTURE aaa_arc OF aaa IS

BEGIN

PROCESS (clk,clr)

variable cnt1,cnt0:std_logic_vector(3 downto 0);

variable cnt: integer range 0 to 59;

BEGIN

IF clr='0' THEN --整体复位

alm<='0';

cnt:=0;

cnt1:="0000";

cnt0:="0000";

ELSIF clk'EVENT AND clk='1' THEN --设计数初值

IF set='0' THEN

cnt:=0;

IF cnt0<"1001" THEN

cnt0:=cnt0+1;

ELSE

cnt0:="0000";

IF cnt1<"1001" THEN

cnt1:=cnt1+1;

ELSE

cnt1:="0000";

END IF;

END IF;

ELSE

IF cnt<59 THEN --60分频

cnt:=cnt+1;

ELSE

cnt:=0;

IF cnt0>"0000" THEN

cnt0:=cnt0-1;

IF cnt1="0000" AND cnt0="0000" THEN --判断计时是否结束

alm<='1';

END IF;

ELSE

cnt0:="1001";

IF cnt1>"0000" THEN

cnt1:=cnt1-1;

ELSE

cnt1:="1001";

END IF;

END IF;

END IF;

END IF;

END IF;

q0<=cnt0;

q1<=cnt1;

END PROCESS;

END aaa_arc;

模块CH如下图示。由于只用了两个数码管,所以片选信号直接接一个较快的时钟。此模块的功能是对应片选信号,送出要显示的数据。

LIBRARY ieee;

USE ieee.std_logic_1164.all;

ENTITY ch IS

PORT(sel:in std_logic;

a1,a0:in std_logic_vector(3 downto 0);

q:out std_logic_vector(3 downto 0));

END ch;

ARCHITECTURE ch_arc OF ch IS

BEGIN

PROCESS(sel,a0,a1)

BEGIN

IF sel='0' THEN

q<=a0;

ELSE

q<=a1;

END IF;

END PROCESS;

END ch_arc;

模块DISP如下图示。该模块为七段译码器。

LIBRARY ieee;

USE ieee.std_logic_1164.all;

ENTITY disp IS

PORT(a:in std_logic_vector(3 downto 0);

q:out std_logic_vector(6 downto 0)); END disp;

ARCHITECTURE disp_arc OF disp IS BEGIN

PROCESS(a)

BEGIN

CASE a IS

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";

WHEN others=>q<="0000000";

END CASE;

END PROCESS;

END disp_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)。在仿真中,这些数字将替代状态的名称出现在仿真波形中。

LIBRARY ieee;

USE ieee.std_logic_1164.all;

ENTITY vending_machine IS

PORT (clk, rst:IN STD_LOGIC;

nickel_in, dime_in, quarter_in: IN BOOLEAN;

candy_out, nickel_out, dime_out: OUT STD_LOGIC);

25

5

10 15 20 40

45

30

35

ni

ni

ni

ni qi qi

qi

qi

qi

no

do

di no+co

do+co

co

di

di

di

di ni

自动售货机控制器的顶层电路图和状态转移图

信号说明:ni=nickel_in, di=dime_in, qi=quarter_in, no=nickel_out, do=dime_out,

co=candy_out

END vending_machine;

ARCHITECTURE fsm OF vending_machine IS

TYPE state IS(st0,st5,st10,st15,st20,st25,st30,st35,st40,st45);

SIGNAL present_state,next_state: STA TE;

BEGIN

PROCESS(rst,clk)

BEGIN

IF(rst='1') THEN

present_state<=st0;

ELSIF (clk'EVENT AND clk='1') THEN

present_state<=next_state;

END IF;

END PROCESS;

PROCESS(present_state, nickel_in, dime_in, quarter_in)

BEGIN

CASE present_state IS

WHEN st0=>

candy_out<='0';

nickel_out<='0';

dime_out<='0';

IF(nickel_in) THEN next_state<=st5;

ELSIF(dime_in) THEN next_state<=st10;

ELSIF(quarter_in) THEN next_state<=st25;

ELSE next_state<=st0;

END IF;

WHEN st5=>

candy_out<='0';

nickel_out<='0';

dime_out<='0';

IF(nickel_in) THEN next_state<=st10;

ELSIF(dime_in) THEN next_state<=st15;

ELSIF(quarter_in) THEN next_state<= st30;

ELSE next_state<=st5;

END IF;

WHEN st10=>

candy_out<='0';

nickel_out<='0';

dime_out<='0';

IF(nickel_in) THEN next_state<=st15;

ELSIF(dime_in) THEN next_state<=st20;

ELSIF(quarter_in) THEN next_state<=st35;

ELSE next_state<=st10;

END IF;

WHEN st15=>

candy_out<='0';

nickel_out<='0';

dime_out<='0';

IF(nickel_in) THEN next_state<=st20;

ELSIF(dime_in) THEN next_state<=st25;

ELSIF(quarter_in) THEN next_state<=st40;

ELSE next_state<=st15;

END IF;

WHEN st20=>

candy_out<='0';

nickel_out<='0';

dime_out<='0';

IF(nickel_in) THEN next_state<=st25;

ELSIF(dime_in) THEN next_state<=st30;

ELSIF(quarter_in) THEN next_state<=st45;

ELSE next_state<=st20;

END IF;

WHEN st25=>

candy_out<='1';

nickel_out<='0';

dime_out<='0';

next_state<=st0;

WHEN st30=>

candy_out<='1';

nickel_out<='1';

dime_out<='0';

next_state<=st0;

WHEN st35=>

candy_out<='1';

nickel_out<='0';

dime_out<='1';

next_state<=st0;

WHEN st40=>

candy_out<='0';

nickel_out<='1';

dime_out<='0';

next_state<=st35;

WHEN st45=>

candy_out<='0';

相关主题
相关文档
最新文档