文档详情

《vhdl应用设计》PPT课件

大米
实名认证
店铺
PPT
1.41MB
约198页
文档ID:577029755
《vhdl应用设计》PPT课件_第1页
1/198

VHDL设计应用实例VHDL设计应用实例1 8位加法器的设计位加法器的设计2 8位乘法器的设计位乘法器的设计3 序列检测器的设计序列检测器的设计4 正负脉宽数控调制信号发生器的设计正负脉宽数控调制信号发生器的设计5 数字频率计的设计数字频率计的设计6 秒表的设计秒表的设计7 MCS–51单片机与单片机与FPGA/CPLD总线接口逻辑设计总线接口逻辑设计8 交通灯信号控制器的设计交通灯信号控制器的设计9 语音信箱控制系统的设计语音信箱控制系统的设计10 PID控制器的设计控制器的设计11 空调系统有限状态自动机的设计空调系统有限状态自动机的设计12 闹钟系统的设计闹钟系统的设计 VHDL设计应用实例1 8位加法器的设计位加法器的设计 1.设计思路.设计思路 加法器是数字系统中的基本逻辑器件,减法器和硬件乘法器都可由加法器来构成多位加法器的构成有两种方式:并行进位和串行进位方式并行进位加法器设有进位产生逻辑,运算速度较快;串行进位方式是将全加器级联构成多位加法器并行进位加法器通常比串行级联加法器占用更多的资源随着位数的增加,相同位数的并行加法器与串行加法器的资源占用差距也越来越大。

因此,在工程中使用加法器时,要在速度和容量之间寻找平衡点 VHDL设计应用实例 实践证明,4位二进制并行加法器和串行级联加法器占用几乎相同的资源这样,多位加法器由4位二进制并行加法器级联构成是较好的折中选择本设计中的8位二进制并行加法器即是由两个4位二进制并行加法器级联而成的,其电路原理图如图6.1所示 VHDL设计应用实例图6.1 8位加法器电路原理图 VHDL设计应用实例2..VHDL源程序源程序1) 4位二进制并行加法器的源程序ADDER4B.VHDLIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY ADDER4B IS --4位二进制并行加法器 PORT(CIN:IN STD_LOGIC; --低位进位 A: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --4位加数 B: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --4位被加数 S: OUT STD_LOGIC_VECTOR(3 DOWNTO 0); --4位和 CONT: OUT STD_LOGIC); --进位输出 VHDL设计应用实例END ADDER4B;ARCHITECTURE ART OF ADDER4B IS SIGNAL SINT:STD_LOGIC_VECTOR(4 DOWNTO 0); SIGNAL AA,BB: STD_LOGIC_VECTOR(4 DOWNTO 0); BEGIN AA<='0'& A; --将4位加数矢量扩为5位,为进位提供空间 BB<='0'& B; --将4位被加数矢量扩为5位,为进位提供空间 SINT<=AA+BB+CIN ; S<=SINT(3 DOWNTO 0); CONT<=SINT(4);END ART; VHDL设计应用实例2) 8位二进制加法器的源程序ADDER8B.VHDLIBRARY IEEE;USE IEEE_STD.LOGIC_1164.ALL;USE IEEE_STD.LOGIC_UNSIGNED.ALL:ENTITY ADDER8B IS --由4位二进制并行加法器级联而成的8位二进制加法器 PORT(CIN:IN STD_LOGIC; A:IN STD_LOGIC_VECTOR(7 DOWNTO 0); B:IN STD_LOGIC_VECTOR(7 DOWNTO 0); S:OUT STD_LOGIC_VECTOR(7 DOWNTO 0); COUT:OUT STD_LOGIC);END ADDER8B;ARCHICTURE ART OF ADDER8B IS VHDL设计应用实例 COMPONENET ADDER4B --对要调用的元件ADDER4B的界面端口进行定义 PORT(CIN:IN STD_LOGIC; A:IN STD_LOGIC_VECTOR(3 DOWNTO 0);B:IN STD_LOGIC_VECTOR(3 DOWNTO 0);S:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);CONT:OUT STD_LOGIC);END COMPONENT ;SIGNAL CARRY_OUT:STD_LOGIC; --4位加法器的进位标志BEGIN U1:ADDER4B --例化(安装)一个4位二进制加法器U1 VHDL设计应用实例 PORT MAP(CIN=>CIN,A=>A(3 DOWNTO 0),B=>B(3 DOWNTO0), S=>S(3 DOWNTO 0),COUT=>CARRY_OUT);U2:ADDER4B --例化(安装)一个4位二进制加法器U2 PORT MAP(CIN=>CARRY_OUT,A=>A(7 DOWNTO 4),B=>B(7 DOWNTO 4), S=>S (7 DOWNTO 4);CONT=>CONT);END ART; VHDL设计应用实例 3.硬件逻辑验证.硬件逻辑验证 选择实验电路结构图NO.1,由5.2的实验电路结构图NO.1和图6.1确定引脚的锁定。

如可取实验电路结构图的PIO3~PIO0接A[3..0],PIO7~PIO4接A[7..4], PIO11~PIO8接B[3..0],PIO15~PIO12接B[7..4],PIO49接CIN此加法器的被加数A和加数B分别由键2与键1、键4与键3输入,加法器的最低位进位CIN由键8输入,计算结果将分别通过PIO23~PIO20,PIO19~PIO16输出并显示于数码管6(高4位)和数码管5(低4位),溢出进位由PIO39输出,当有进位时,结果显示于发光管D8 VHDL设计应用实例2 8位乘法器的设计位乘法器的设计 1.设计思路.设计思路 纯组合逻辑构成的乘法器虽然工作速度比较快,但占用硬件资源多,难以实现宽位乘法器,而基于PLD器件外接ROM九九表的乘法器则无法构成单片系统,也不实用这里介绍由8位加法器构成的以时序逻辑方式设计的8位乘法器,此乘法器具有一定的实用价值其乘法原理是:乘法通过逐项位移相加原理来实现,从被乘数的最低位开始,若为1,则乘数左移后与上一次和相加;若为0,左移后以全零相加,直至被乘数的最高位从图6.2的逻辑图上可以清楚地看出此乘法器的工作原理。

VHDL设计应用实例图6.2 8×8位乘法器电路原理图 VHDL设计应用实例 图6.2中,ARICTL是乘法运算控制电路,它的START(可锁定于引脚I/O 49)信号的上跳沿与高电平有两个功能,即16位寄存器清零和被乘数A[7..0]向移位寄存器SREG8B加载;它的低电平则作为乘法使能信号乘法时钟信号从ARICTL的CLK输入当被乘数加载于8位右移寄存器SREG8B后,随着每一时钟节拍,最低位在前,由低位至高位逐位移出当为1时,与门ANDARITH打开,8位乘数B[7..0]在同一节拍进入8位加法器,与上一次锁存在16位锁存器REG16B中的高8位进行相加,其和在下一时钟节拍的上升沿被锁进此锁存器而当被乘数移出位为0时,与门全零输出如此往复,直至8个时钟脉冲后,由ARICTL的控制,乘法运算过程自动中止ARIEND输出高电平,以此可点亮一发光管,以示乘法结束此时REG16B的输出值即为最后乘积 VHDL设计应用实例 此乘法器的优点是节省芯片资源,它的核心元件只是一个8位加法器,其运算速度取决于输入的时钟频率若时钟频率为100 MHz,则每一运算周期仅需80 ns。

而若利用备用最高时钟,即12 MHz晶振的MCS-51单片机的乘法指令,进行8位乘法运算,仅单指令的运算周期就长达4 μs因此,可以利用此乘法器或相同原理构成的更高位乘法器完成一些数字信号处理方面的运算 VHDL设计应用实例2. VHDL源程序源程序1) 选通与门模块的源程序ANDARITH.VHDLIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;ENTITY ANDARITH IS --选通与门模块 PORT (ABIN:IN STD_LOGIC; --与门开关 DIN:IN STD_LOGIC_VECTOR (7 DOWNTO 0) --8位输入 DOUT:OUT STD_LOGIC_VECTOR (7 DOWNTO 0)); --8位输出END ANDARITH;ARCHITECTURE ART OF ANDARITH IS VHDL设计应用实例 BEGIN PROCESS (ABIN,DIN) BEGIN FOR I IN 0 TO 7 LOOP --循环,分别完成8位数据与一位 DOUT (I)<=DIN (I)AND ABIN; --控制位的与操作 END LOOP; END PROCESS;END ART; VHDL设计应用实例2) 16位锁存器的源程序REG16B.VHDLIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;ENTITY REG16B IS --16位锁存器 PORT (CLK:IN STD_LOGIC; --锁存信号 CLR:IN STD_LOGIC; --清零信号 D:IN STD_LOGIC_VECTOR (8 DOWNTO 0) --8位数据输入 Q:OUT STD_LOGIC_VECTOR(15 DOWNTO 0));--16位数据输出END REG16B;ARCHITECTURE ART OF REG16B IS SIGNAL R16S:STD_LOGIC_VECTOR(15 DOWNTO 0); --16位寄存器设置 VHDL设计应用实例BEGINPROCESS (CLK,CLR) BEGIN IF CLR = '1' THEN R16S<= "0000000000000000";--异步复位信号 ELSIF CLK'EVENT AND CLK = '1' THEN--时钟到来时,锁存输入值 R16S(6 DOWNTO 0)<=R16S(7 DOWNTO 1);--右移低8位 R16S(15 DOWNTO 7)<=D; --将输入锁到高能位 END IF; END PROCESS; Q<=R16S;END ART; VHDL设计应用实例3) 8位右移寄存器的源程序SREG8B.VHDLIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL; --8位右移寄存器ENTITY SREG8B IS PORT (CLK:IN STD_LOGIC; LOAD :IN STD _LOGIC; BIN:IN STD_LOGIC_VECTOR(7DOWNTO 0); QB:OUT STD_LOGIC );END SREG8B;ARCHITECTURE ART OF SREG8B IS SIGNAL REG8B:STD_LOGIC_VECTOR(7 DOWNTO 0); BEGIN PROCESS (CLK,LOAD) VHDL设计应用实例 BEGIN IF CLK'EVENT AND CLK= '1' THEN IF LOAD = '1' THEN REG8<=DIN; --装载新数据 ELSE REG8(6 DOWNTO0)<=REG8(7 DOWNTO 1);--数据右移 END IF; END IF; END PROCESS; QB<= REG8 (0); --输出最低位END ART; VHDL设计应用实例4) 乘法运算控制器的源程序ARICTL.VHD LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY ARICTL IS --乘法运算控制器 PORT ( CLK:IN STD_LOGIC; START:IN STD_LOGIC; CLKOUT:OUT STD_LOGIC; RSTALL:OUT STD_LOGIC; ARIEND:OUT STD_LOGIC );END ARICTL;ARCHITECTURE ART OF ARICTL IS SIGNAL CNT4B:STD_LOGIC_VECTOR(3 DOWNTO 0);BEGIN VHDL设计应用实例 RSTALL<=START; PROCESS (CLK,START) BEGIN IF START = '1' THEN CNT4B<= "0000"; --高电平清零计数器 ELSIF CLK'EVENT AND CLK = '1' THEN IF CNT4B<8 THEN--小于则计数,等于8表明乘法运算已经结束 CNT4B=CNT4B+1; END IF; END IF;END PROCESS;PROCESS (CLK,CNT4B,START)BEGIN VHDL设计应用实例 IF START = '0' THEN IF CNT4B<8 THEN --乘法运算正在进行 CLKOUT <=CLK; ARIEND<= '0'; ELSE CLKOUT <= '0'; ARIEND<= '1';--运算已经结束 END IF; ELSE CLKOUT <=CLK; ARIEND<= '0'; END IF; END PROCESS;END ART; VHDL设计应用实例5) 8位乘法器的源程序MULTI8X8.VHDLIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL; --8位乘法器顶层设计ENTITY MULTI8X8 IS PORT(CLK:IN STD_LOGIC; START:IN STD_LOGIC;--乘法启动信号,高电平复位与加载,低电平运算 A:IN STD_LOGIC_VECTOR(7 DOWNTO 0); --8位被乘数 B:IN STD_LOGIC_VECTOR(7 DOWNTO 0); --8位乘数 ARIEND:OUT STD_LOGIC; --乘法运算结束标志位 DOUT:OUT STD_LOGIC_VECTOR(15 DOWNTO 0));--16位乘积输出END MULTI8X8; VHDL设计应用实例ARCHITECTURE ART OF MULTI8X8 IS COMPONENT ARICTL --待调用的乘法控制器端口定义 PORT(CLK:IN STD_LOGIC;START:IN STD_LOGIC; CLKOUT:OUT STD_LOGIC;RSTALL:OUT STD_LOGIC; ARIEND:OUT STD_LOGIC);END COMPONENT;COMPONENT ANDARITH --待调用的控制与门端口定义 PORT(ABIN:IN STD_LOGIC; DIN:IN STD_LOGIC_VECTOR(7 DOWNTO 0); DOUT:OUT_STD_LOGIC_VECTOR( 7 DOWNTO 0) );END COMPONENT;COMPONENT ADDER8B --待调用的8位加法器端口定义  ... VHDL设计应用实例COMPONENT SREG8B --待调用的8位右移寄存器端口定义 ...COMPONENT REG16B --待调用的16右移寄存器端口定义 ...SIGNAL GNDINT:STD_LOGIC;SIGNAL INTCLK:STD_LOGIC;SIGNAL RSTALL:STD_LOGIC;SIGNAL QB:STD_LOGIC;SIGNAL ANDSD:STD_LOGIC_VECTOR(7 DOWNTO 0);SIGNAL DTBIN:STD_LOGIC_VECTOR(8 DOWNTO 0);SIGNAL DTBOUT:STD_LOGIC_VECTOR(15 DOWNTO 0);BEGIN VHDL设计应用实例DOUT<=DTBOUT;GNDINT<= '0';U1:ARICTL PORT MAP(CLK=>CLK, START=>START, CLKOUT=>INTCLK, RSTALL=>RSTALL, ARIEND=>ARIEND); U2:SREG8B PORT MAP(CLK=>INTCLK, LOAD=>RSTALL. DIN=>B, QB=>QB);U3:ANDARITH PORT MAP(ABIN=>QB,DIN=>A,DOUT=>ANDSD);U4:ADDER8B PORT MAP(CIN=>GNDINT,A=>DTBOUT(15 DOWNTO 8), B=>ANDSD, S=>DTBIN(7 DOWNTO 0),COUT =>DTBIN(8));U5:REG16B PORT MAP(CLK =>INTCLK,CLR=>RSTALL, D=>DTBIN, Q=>DTBOUT);END ART; VHDL设计应用实例 3. 硬件逻辑验证硬件逻辑验证 选择实验电路结构图NO.1,由5.2节的实验电路结构图NO.1和图6.2确定引脚的锁定。

如乘法运算时钟CLK接CLOCK0,清零及启动运算信号START由键8 (PIO49)控制,乘数B[7..0]接PIO7~PIO0(由键2,键1输入8位二进制数),被乘数A[7..0]接PIO15~PIO8(由键4,键3输入8位二进制数),乘积输出DOUT[15..0]接PIO31~PIO16,乘法运算结束信号ARIEND接PIO39(D8) VHDL设计应用实例 进行硬件验证时方法如下:① 键2和键1分别输入乘数的高4位和低4位(输入值显示于数码2和数码1);② 键4和键3分别输入被乘数的高4位和低4位(输入值显示于数码4和数码3);③ 乘法操作时钟信号输入接CLOCK0;④ 键8输入高电平时,乘积锁存器清零,乘数和被乘数数值加载,低电平时开始作乘法,8个脉冲后乘法结束,乘积显示于数码管8~5,高位在左 VHDL设计应用实例3 序列检测器的设计序列检测器的设计 1.设计思路.设计思路 序列检测器可用于检测一组或多组由二进制码组成的脉冲序列信号,这在数字通信领域有广泛的应用当序列检测器连续收到一组串行二进制码后,如果这组码与检测器中预先设置的码相同,则输出1,否则输出0。

由于这种检测的关键在于正确码的收到必须是连续的,这就要求检测器必须记住前一次的正确码及正确序列,直到在连续的检测中所收到的每一位码都与预置数的对应码相同在检测过程中,任何一位不相等都将回到初始状态重新开始检测如图6.3所示,当一串待检测的串行数据进入检测器后,若此数在每一位的连续检测中都与预置的密码数相同,则输出“A”,否则仍然输出“B” VHDL设计应用实例图6.3 8位序列检测器逻辑图 VHDL设计应用实例2..VHDL源程序源程序LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;ENTITY CHK IS PORT(DIN:IN STD_LOGIC; --串行输入数据位 CLK,CLR:IN STD_LOGIC; --工作时钟/复位信号 D:IN STD_LOGIC_VECTOR(7 DOWNTO 0);--8位待检测预置数 AB:OUT STD_LOGIC_VECTOR(3 DOWNTO 0));--检测结果输出END CHK;ARCHITECTURE ART OF CHK IS VHDL设计应用实例SIGNAL Q :INTEGER RANGE 0 TO 8;BEGINPROCESS ( CLK,CLR )BEGIN IF CLR= '1' THEN Q<=0; ELSIF CLK'EVENT AND CLK= '1' THEN --时钟到来时,判断并处理当前输入的位 CASE Q IS WHEN 0 => IF DIN =D(7) THEN Q<= 1 ;ELSE Q<=0;END IF; WHEN 1 => IF DIN =D(6) THEN Q<= 2 ;ELSE Q<=0;END IF; WHEN 2 => IF DIN =D(5) THEN Q<= 3 ;ELSE Q<=0;END IF; VHDL设计应用实例WHEN 3=> IF DIN =D(4) THEN Q<= 4 ;ELSE Q<=0;END IF;WHEN 4 => IF DIN =D(3) THEN Q<= 5 ;ELSE Q<=0;END IF;WHEN 5 => IF DIN =D(2) THEN Q<= 6 ;ELSE Q<=0;END IF;WHEN 6 => IF DIN =D(1) THEN Q<= 7 ;ELSE Q<=0;END IF;WHEN 7 => IF DIN =D(0) THEN Q<= 8 ;ELSE Q<=0;END IF;WHEN OTHERS => Q<=0;END IF ; VHDL设计应用实例END PROCESS;PROCESS(Q) --检测结果判断输出BEGIN IF Q= 8 THEN AB<= "1010"; --序列数检测正确,输出“A” ELSE AB<= "1011"; --序列数检测错误,输出 “B” END IF ; END PROCESS;END ART; VHDL设计应用实例 3.硬件逻辑验证.硬件逻辑验证 选择实验电路结构图NO.8,由5.2节的实验电路结构图NO.8和图6.3确定引脚的锁定。

待检测串行序列数输入DIN接PIO10(左移,最高位在前),清零信号CLR接PIO8,工作时钟CLK接PIO9,预置位密码D[7..0]接PIO7~PIO0,指示输出AB[3..0]接PIO39~PIO36(显示于数码管6) VHDL设计应用实例 进行硬件验证时方法如下:① 选择实验电路结构图NO.8,按实验板“系统复位”键;② 用键2和键1输入两位十六进制待测序列数;③ 利用键4和键3输入两位十六进制预置码;④ 按键8,高电平初始化清零,低电平清零结束(平时数码6应显“B”);⑤ 按键6(CLK)8次,这时若串行输入的8位二进制序列码与预置码相同,则数码7应从原来的“B”变成“A”,表示序列检测正确,否则仍为“B” VHDL设计应用实例4 正负脉宽数控调制信号发生器的设计正负脉宽数控调制信号发生器的设计 1.设计思路.设计思路 图6.4 是脉宽数控调制信号发生器逻辑图,此信号发生器是由两个完全相同的可自加载加法计数LCNT8组成的,它的输出信号的高低电平脉宽可分别由两组8位预置数进行控制 VHDL设计应用实例图6.4 脉宽数控调制信号发生器逻辑图 VHDL设计应用实例 如果将初始值可预置的加法计数器的溢出信号作为本计数器的初始预置加载信号LD,则可构成计数初始值自加载方式的加法计数器,从而构成数控分频器。

图6.4中D触发器的一个重要功能就是均匀输出信号的占空比,提高驱动能力,这对驱动,诸如扬声器或电动机十分重要 VHDL设计应用实例2..VHDL源程序源程序1) 8位可自加载加法计数器的源程序LCNT8.VHDLIBRARY IEEE;USE IEEE.STD_LOGIC_1164,.ALL;ENTITY LCNT8 IS --8位可自加载加法计数器 PORT(CLK,LD:IN STD_LOGIC; --工作时钟/预置值加载信号 D:IN INTEGER RANGE 0 TO 255;--8位分频预置数 CAO:OUT STD_LOGIC); --计数溢出输出END LCNT8;ARCHITECTURE ART OF LCNT8 IS SIGNAL COUNT:INTEGER RANGE 0 TO 255; --8位计数器设置 BEGIN PROCESS ( CLK ) VHDL设计应用实例BEGIN IF CLK'EVENT AND CLK= '1' THEN IF LD= '1' THEN COUNT<=D; --LD为高电平时加载预置数 ELSE COUNT<=COUNT+1; --否则继续计数 END IF; END IF;END PROCESS;PROCESS (COUNT)BEGIN IF COUNT=255 THEN CAO<= '1'; --计数满后,置于溢出位 ELSE CAO<= '0'; END IF; END PROCESS;END ART; VHDL设计应用实例2) 正负脉宽数控调制信号发生器的源程序PULSE.VHD LIBRARY IEEE; --正负脉宽数控调制信号发生器顶层文件USE IEEE.STD_LOGIC_1164.ALL;ENTITY PULSE IS PORT (CLK:IN STD_LOGIC; --计数时钟 A,B:IN STD_LOGIC_VECTOR(7 DOWNTO 0);--8位计数预置数 PSOUT:OUT STD_LOGIC); --计数溢出并分频输出END PULSE;ARCHITECTURE ART OF PULSE IS COMPONENT LCNT8 VHDL设计应用实例 PORT(CLK,LD:IN STD_LOGIC; D:IN STD_LOGIC_VECTOR(7 DOWNTO 0); CAO:OUT STD_LOGIC); END COMPONENT; SIGNAL CAO1,CAO2 :STD_LOGIC; SIGNAL LD1,LD2 :STD_LOGIC; SIGNAL PSINT:STD_LOGIC; BEGIN U1:LCNT8 PORT MAP(CLK=>CLK,LD=>LD1, D=>A,CAO=>CAO1); U2:LCNT8 PORT MAP(CLK=>CLK,LD=>LD2, D=>B,CAO=>CAO2); VHDL设计应用实例PROCESS(CAO1,CAO2)BEGIN IF CAO1= '1' THEN PSINT<= '0'; ELSIF CAO2 'EVENT AND CAO2= '1' THEN PSINT<='1'; END IF; END PROCESS; LD1<=NOT PSINT;LD2<=PSINT;PSOUT<=PSINT;END ART; VHDL设计应用实例 3. 硬件逻辑验证硬件逻辑验证 选择实验电路结构图NO.1,由5.2节的实验电路结构图NO.1和图6.4确定引脚的锁定。

输入时钟CLK接CLOCK0(用于发声时,接频率65536 Hz);8位数控预置输入B[7..0]接PIO15~PIO8,由键4和键3控制输入,输入值分别显示于数码管4和数码管3;另8位数控预置输入A[7..0]接PIO7~PIO0,由键1和键2控制输入,输入值分别显示于数码管2和数码管1;输出PSOUT 接SPEAKER(对应1032E是第5引脚PIN5;对应EPF10K是第3引脚PIN3) VHDL设计应用实例 进行硬件验证时方法如下:通过键2和键1输入控制高电平信号脉宽的预置数(显示于数码管2和1);由键4和键3输入控制低电平信号脉宽的预置数(显示于数码管4和3);取待分频率F=12 MHz、6 MHz或3 MHz,通过短路帽输入CLK9;频率输出可利用示波器观察波形随预置数的变化而变化的情况在没有示波器时,“CLK”可接低频率信号,然后接通扬声器,通过声音音调的变化来了解输出频率的变化 VHDL设计应用实例5 数字频率计的设计数字频率计的设计 1. 设计思路设计思路 图6.5是8位十进制数字频率计的电路逻辑图,它由一个测频控制信号发生器TESTCTL、8个有时钟使能的十进制计数器CNT10、一个32位锁存器REG32B组成。

以下分别叙述频率计各逻辑模块的功能与设计方法 VHDL设计应用实例图6.5 8位十进制数字频率计逻辑图 VHDL设计应用实例 1) 测频控制信号发生器设计 频率测量的基本原理是计算每秒钟内待测信号的脉冲个数这就要求TESTCTL的计数使能信号TSTEN能产生一个1秒脉宽的周期信号,并对频率计的每一计数器CNT10的ENA使能端进行同步控制当TSTEN高电平时,允许计数;低电平时,停止计数,并保持其所计的数在停止计数期间,首先需要一个锁存信号LOAD的上跳沿将计数器在前1秒钟的计数值锁存进32位锁存器REG32B中,并由外部的7段译码器译出并稳定显示锁存信号之后,必须有一清零信号CLR_CNT对计数器进行清零,为下1秒钟的计数操作作准备测频控制信号发生器的工作时序如图6.6所示为了产生这个时序图,需首先建立一个由D触发器构成的二分频器,在每次时钟CLK上沿到来时其值翻转 VHDL设计应用实例 其中控制信号时钟CLK的频率取1 Hz,而信号TSTEN的脉宽恰好为1 s,可以用作闸门信号此时,根据测频的时序要求,可得出信号LOAD和CLR_CNT的逻辑描述。

由图6.6可见,在计数完成后,即计数使能信号TSTEN在1 s的高电平后,利用其反相值的上跳沿产生一个锁存信号LOAD,0.5 s后,CLR_CNT产生一个清零信号上跳沿 高质量的测频控制信号发生器的设计十分重要,设计中要对其进行仔细的实时仿真(TIMING SIMULATION),防止可能产生的毛刺 VHDL设计应用实例图6.6 测频控制信号发生器工作时序 VHDL设计应用实例 2) 寄存器REG32B设计 设置锁存器的好处是,显示的数据稳定,不会由于周期性的清零信号而不断闪烁若已有32位BCD码存在于此模块的输入口,在信号LOAD的上升沿后即被锁存到寄存器REG32B的内部,并由REG32B的输出端输出,然后由实验板上的7段译码器译成能在数码管上显示输出的相对应的数值 VHDL设计应用实例 3) 十进制计数器CNT10的设计 如图6.5所示,此十进制计数器的特殊之处是,有一时钟使能输入端ENA,用于锁定计数值当高电平时计数允许,低电平时禁止计数 VHDL设计应用实例2. VHDL源程序源程序1) 有时钟使能的十进制计数器的源程序CNT10.VHDLIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL; --有时钟使能的十进制计数器ENTITY CNT10 ISPORT (CLK:IN STD_LOGIC; --计数时钟信号 CLR:IN STD_LOGIC; --清零信号 END:IN STD_LOGIC; --计数使能信号 CQ:OUT INTEGER RANGE 0 TO 15;--4位计数结果输出 CARRY_OUT:OUT STD_LOGIC); --计数进位 END CNT10;ARCHITECTURE ART OF CNT10 IS VHDL设计应用实例SIGNAL CQI :INTEGER RANGE 0 TO 15;BEGIN PROCESS(CLK,CLR,ENA) BEGIN IF CLR= '1' THEN CQI<= 0; --计数器异步清零 ELSIF CLK'EVENT AND CLK= '1' THEN IF ENA= '1' THEN IF CQI<9 THEN CQI<=CQI+1; ELSE CQI<=0;END IF; --等于9,则计数器清零 END IF; END IF; END PROCESS; PROCESS (CQI) BEGIN IF CQI=9 THEN CARRY_OUT<= '1'; --进位输出 ELSE CARRY_OUT<= '0';END IF; END PROCESS; CQ<=CQI;END ART; VHDL设计应用实例2) 32位锁存器的源程序REG32B.VHDLIBRARY IEEE; --32位锁存器USE IEEE.STD_LOGIC_1164.ALL;ENTITY REG32B IS PORT(LOAD:IN STD_LOGIC; DIN:IN STD_LOGIC_VECTOR(31 DOWNTO 0); DOUT:OUT STD_LOGEC_VECTOR(31 DOWNTO 0));END REG32B;ARCHITECTURE ART OF REG32B IS BEGINPROCESS ( LOAD, DIN )BEGINIF LOAD 'EVENT AND LOAD= '1' THEN DOUT<=DIN; --锁存输入数据 END IF ; END PROCESS;END ART; VHDL设计应用实例3) 测频控制信号发生器的源程序TESTCTL.VHD LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL; --测频控制信号发生器USE IEEE.STD_LOGIC_UNSIGNED.ALLENTITY TESTCTL IS PORT (CLK:IN STD_LOGIC; --1 Hz测频控制时钟 TSTEN:OUT STD_LOGIC; --计数器时钟使能 CLR_CNT:OUT STD_LOGIC; --计数器清零 LOAD:OUT STD_LOGIC); --输出锁存信号END TESTCTL;ARCHITECTURE ART OF TESTCTL IS SIGNAL Dvi2CLK :STD_LOGIC; BEGIN VHDL设计应用实例PROCESS ( CLK )BEGINIF CLK'EVENT AND CLK= '1' THEN --1 Hz时钟二分频Div2CLK<=NOT Div2CLK;END IF ;END PROCESS;PROCESS ( CLK,Div2CLK )BEGIN IF CLK= '0' AND Div2CLK = '0' THEN --产生计数器清零信号 CLR_CNT<= '1'; ELSE CLR_CNT<= '0' ; END IF; END PROCESS; LOAD<=NOT Div2CLK; TSTEN<=Div2CLK;END ART; VHDL设计应用实例4) 数字频率计的源程序FREQ.VHDLIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;ENTITY FREQ IS PORT(FSIN:IN STD_LOGIC; CLK:IN STD_LOGIC; DOUT:OUT STD_LOGIC_VECTOR(31 DOWNTO 0));END FREQ;ARCHITECTURE ART OF FREQ ISCOMPONENT CNT10 --待调用的有时钟使能的十进制计数器端口定义 PORT(CLK,CLR,ENA:IN STD_LOGIC; CQ:OUT STD_LOGIC_VECTOR(3 DOWNTO 0); CARRY_OUT:OUT STD_LOGIC); VHDL设计应用实例END COMPONENT;COMPONENT REG32B --待调用的32位锁存器端口定义  ...COMPONENT TESTCTL --待调用的测频控制信号发生器端口定义 ... SIGNAL TSTEN:STD_LOGIC; SIGNAL CLR_CNT:STD_LOGIC; SIGNAL LOAD:STD_LOGIC; SIGNAL CARRY1:STD_LOGIC; SIGNAL CARRY2:STD_LOGIC; SIGNAL CARRY3:STD_LOGIC; SIGNAL CARRY4:STD_LOGIC; SIGNAL CARRY5:STD_LOGIC; SIGNAL CARRY6:STD_LOGIC; SIGNAL CARRY7:STD_LOGIC; SIGNAL CARRY8:STD_LOGIC; SIGNAL DIN:STD_LOGIC_VECTOR(31 DOWNTO 0); VHDL设计应用实例BEGINU0:TESTCTL PORT MAP(CLK=>CLK,TSTEN=>TSTEN, CLR_CNT=>CLR_CNT,LOAD=>LOAD);U1:CNT10 PORT MAP(CLK=>FSIN,CLR=>CLR_CNT,ENA=>TSTEN, CQ=>DIN (3 DOWNTO 0),CARRY_OUT=>CARRY1);U2:CNT10 PORT MAP(CLK=>CARRY1,CLR=>CLR_CNT,ENA=>TSTEN, CQ=>DIN (7 DOWNTO 4),CARRY_OUT=>CARRY2);U3:CNT10 PORT MAP(CLK=>CARRY2,CLR=>CLR_CNT,ENA=>TSTEN, CQ=>DIN (11 DOWNTO 8),CARRY_OUT=>CARRY3);U4:CNT10 PORT MAP(CLK=>CARRY3,CLR=>CLR_CNT,ENA=>TSTEN, CQ=>DIN (15 DOWNTO 12),CARRY_OUT=>CARRY4);U5:CNT10 PORT MAP(CLK=>CARRY4,CLR=>CLR_CNT,ENA=>TSTEN, VHDL设计应用实例 CQ=>DIN (19 DOWNTO 16),CARRY_OUT=>CARRY5);U6:CNT10 PORT MAP(CLK=>CARRY5,CLR=>CLR_CNT,ENA=>TSTEN, CQ=>DIN (23 DOWNTO 20),CARRY_OUT=>CARRY6);U7:CNT10 PORT MAP(CLK=>CARRY6,CLR=>CLR_CNT,ENA=>TSTEN, CQ=>DIN (27 DOWNTO 24),CARRY_OUT=>CARRY7);U8:CNT10 PORT MAP(CLK=>CARRY7,CLR=>CLR_CNT,ENA=>TSTEN, CQ=>DIN (31 DOWNTO 28),CARRY_OUT=>CARRY8);U9:REG32B PORT MAP(LOAD=>LOAD,DIN=>DIN(31 DOWNTO 0),DOUT=>DOUT);END ART; VHDL设计应用实例 3. 硬件逻辑验证硬件逻辑验证 选择实验电路结构图NO.0,由5.2节的实验电路结构图NO.0和图6.5确定引脚的锁定,测频控制器时钟信号CLK(1 Hz)可接CLOCK1,待测频FSIN可接CLOCK0,8位数码显示输出DOUT[31..0]接PIO47~PIO16。

进行硬件验证时方法如下:选择实验模式0,测频控制器时钟信号CLK与CLOCK1信号组中的1 Hz信号相接,待测频FSIN与CLOCK0信号组中的某个信号相接,数码管应显示来自CLOCK0的频率 VHDL设计应用实例6 秒秒 表表 的的 设设 计计 1.设计思路.设计思路 今需设计一个计时范围为0.01秒~1小时的秒表,首先需要获得一个比较精确的计时基准信号,这里是周期为1/100 s的计时脉冲其次,除了对每一计数器需设置清零信号输入外,还需在6个计数器设置时钟使能信号,即计时允许信号,以便作为秒表的计时起停控制开关因此秒表可由1个分频器、4个十进制计数器 (1/100秒、1/10秒、1秒、1分)以及2个六进制计数器(10秒、10分)组成,如图6.7所示6个计数器中的每一计数器的4位输出,通过外设的BCD译码器输出显示图6.7中6个4位二进制计数输出的最小显示值分别为:DOUT[3..0]1/100秒、DOUT[7..4]1/10秒、DOUT[11..8]1秒、DOUT[15..12]10秒、DOUT[19..16]1分、DOUT[23..20]10分。

VHDL设计应用实例图6.7 秒表电路逻辑图 VHDL设计应用实例2. VHDL源程序源程序1) 3 MHz→100 Hz分频器的源程序CLKGEN.VHDLIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;ENTITY CLKGEN IS PORT (CLK:IN STD_LOGIC; --3 MHz信号输入 NEWCLK:OUT STD_LOGIC ); --100 Hz计时时钟信号输出END CLKGEN;ARCHITECTURE ART OF CLKGEN IS SIGNAL CNTER:INTEGER RANGE 0 TO 10#29999#; --十进制计数预制数 BEGIN PROCESS(CLK) --分频计数器,由3 MHz时钟产生100 Hz信号 BEGIN VHDL设计应用实例 IF CLK'EVENT AND CLK='1' THEN IF CNTER=10#29999# THEN CNTER<=0;--3 MHz信号变为100 Hz,计数常数为30 000 ELSE CNTER<=CNTER+1; END IF; END IF;END PROCESS;PROCESS(CNTER) --计数溢出信号控制BEGIN IF CNTER=10#29999# THEN NEWCLK<='1'; ELSE NEWCLK<='0'; END IF; END PROCESS;END ART; VHDL设计应用实例 2) 六进制计数器的源程序CNT6.VHD(十进制计数器的源程序CNT10.VHD与此类似)LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY CNT6 ISPORT (CLK:IN STD_LOGIC; CLR:IN STD_LOGIC; ENA: IN STD_LOGIC; CQ:OUT STD_LOGIC_VECTOR(3 DOWNTO 0); VHDL设计应用实例 CARRY_OUT: OUT STD_LOGIC );END CNT6;ARCHITECTURE ART OF CNT6 ISSIGNAL CQI:STD_LOGIC_VECTOR(3 DOWNTO 0);BEGINPROCESS(CLK,CLR,ENA)BEGIN IF CLR='1' THEN CQI<="0000"; ELSIF CLK'EVENT AND CLK='1' THEN IF ENA='1' THEN IF CQI=“0101” THEN CQI<=“0000”; VHDL设计应用实例 ELSE CQI<=CQI+'1';END IF; END IF; END IF; END PROCESS; PROCESS(CQI) BEGIN IF CQI=“0000” THEN CARRY_OUT<='1'; ELSE CARRY_OUT<='0';END IF; END PROCESS; CQ<=CQI;END ART; VHDL设计应用实例3) 秒表的源程序TIMES.VHDLIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;ENTITY TIMES IS PORT(CLR:IN STD_LOGIC; CLK:IN STD_LOGIC; ENA:IN STD_LOGIC; DOUT:OUT STD_LOGIC_VECTOR(23 DOWNTO 0));END TIMES;ARCHITECTURE ART OF TIMES IS COMPONENT CLKGEN PORT(CLK:IN STD_LOGIC; NEWCLK:OUT STD_LOGIC); VHDL设计应用实例END COMPONENT;COMPONENT CNT10 PORT(CLK,CLR,ENA:IN STD_LOGIC; CQ:OUT STD_LOGIC_VECTOR(3 DOWNTO 0); CARRY_OUT:OUT STD_LOGIC);END COMPONENT;COMPONENT CNT6 PORT(CLK,CLR,ENA:IN STD_LOGIC; CQ:OUT STD_LOGIC_VECTOR(3 DOWNTO 0); CARRY_OUT:OUT STD_LOGIC);END COMPONENT; VHDL设计应用实例 SIGNAL NEWCLK:STD_LOGIC; SIGNAL CARRY1:STD_LOGIC; SIGNAL CARRY2:STD_LOGIC; SIGNAL CARRY3:STD_LOGIC; SIGNAL CARRY4:STD_LOGIC; SIGNAL CARRY5:STD_LOGIC; BEGIN U0:CLKGEN PORT MAP(CLK=>CLK,NEWCLK=>NEWCLK); U1:CNT10 PORT MAP(CLK=>NEWCLK,CLR=>CLR,ENA=>ENA, CQ=>DOUT(3 DOWNTO 0),CARRY_OUT=>CARRY1); VHDL设计应用实例 U2:CNT10 PORT MAP(CLK=>CARRY1,CLR=>CLR,ENA=>ENA, CQ=>DOUT(7 DOWNTO 4),CARRY_OUT=>CARRY2); U3:CNT10 PORT MAP(CLK=>CARRY2,CLR=>CLR,ENA=>ENA, CQ=>DOUT(11 DOWNTO 8),CARRY_OUT=>CARRY3); U4:CNT6 PORT MAP(CLK=>CARRY3,CLR=>CLR,ENA=>ENA, CQ=>DOUT(15 DOWNTO 12),CARRY_OUT=>CARRY4); U5:CNT10 PORT MAP(CLK=>CARRY4,CLR=>CLR,ENA=>ENA, CQ=>DOUT(19 DOWNTO 16),CARRY_OUT=>CARRY5); U6:CNT6 PORT MAP(CLK=>CARRY5,CLR=>CLR,ENA=>ENA, CQ=>DOUT(23 DOWNTO 20));END ART; VHDL设计应用实例 3. 硬件逻辑验证硬件逻辑验证 选择实验电路结构图NO.0,由5.2节的实验电路结构图NO.0和图6.7确定引脚的锁定。

时钟信号CLK可接CLOCK0,计数清零信号接键1,计数使能信号接键2,数码管1~6分别显示以1/100 s、1/10 s、1 s、10 s、1 min、10 min为计时基准的计数值 进行硬件验证时方法如下:选择实验模式0,时钟信号CLK与CLOCK0信号组中的3 MHz信号相接,键1和键2分别为计数清零信号和计数使能信号,计数开始后时间显示在6个数码管上 VHDL设计应用实例7 MCS-51单片机与单片机与FPGA/CPLD总线接口逻辑设计总线接口逻辑设计 单片机具有性能价格比高、功能灵活、易于人机对话和良好的数据处理能力等特点;PLD则具有高速、高可靠以及开发便捷规范等方面的优点,以此两类器件相结合的电路结构在许多高性能仪器仪表和电子产品中将被广泛应用单片机与CPLD的接口方式一般有两种,即总线方式与独立方式 单片机以总线方式与FPGA/CPLD进行数据与控制信息通信有许多优点: VHDL设计应用实例 (1) 速度快其通信工作时序是纯硬件行为,对于MCS-51单片机,只需一条单字节指令就能完成所需的读/写时序,如:MOV @DPTR,A;MOV A,@DPTR。

(2) 节省PLD芯片的I/O口线如图6.9,如果将图中的译码DECODER设置足够的译码输出,以及安排足够的锁存器,就能仅通过19根I/O口线在FPGA/CPLD与单片机之间进行各种类型的数据与控制信息交换 (3) 相对于非总线方式,单片机的编程简捷,控制可靠 VHDL设计应用实例 (4) 在FPGA/CPLD中通过逻辑切换,单片机易于与SRAM或ROM接口这种方式有许多实用之处,如利用类似于微处理器DMA的工作方法,首先由FPGA/CPLD与接口的高速A/D等器件进行高速数据采样,并将数据暂存于SRAM中,采样结束后,通过切换,使单片机与SRAM以总线方式进行数据通信,以便发挥单片机强大的数据处理能力 VHDL设计应用实例 1.设计思路.设计思路 对单片机与FPGA/CPLD以总线方式通信的逻辑设计, 应详细了解单片机的总线读写时序,根据时序图来设计逻辑结构图6.8 是MCS-51系列单片机的时序图,其时序电平变化速度与单片机工作时钟频率有关图中,ALE为地址锁存使能信号,可利用其下降沿将低8位地址锁存于FPGA/CPLD中的地址锁存器(LATCH_ADDRES)中。

当ALE将低8位地址通过P0锁存的同时,高8位地址已稳定建立于P2口,单片机利用读写指令允许信号PSEN的低电平,从外部ROM中将指令从P0口读入由时序图可见,其指令读入的时机是在PSEN的上跳沿之前接下来,由P2口和P0口分别输出高8位和低8位数据地址,并由ALE的下沿将P0口的低8位地址锁存于地址锁存器 VHDL设计应用实例 若需从“FPGA/CPLD”中读出数据,单片机则通过指令“MOV A,@DPTR”使RD信号为低电平,由P0口将图6.9中锁存器LATCH_IN1中的数据读入累加器A但若欲将累加器A的数据写进FPGA/CPLD,需通过指令“MOV @DPRT,A”和写允许信号WR这时,DPTR中的高8位和低8位数据作为高低8位地址分别向P2 和P0口输出,然后由WR的低电平,并结合译码,将A的数据写入图中相关的锁存器 VHDL设计应用实例图6.8 MCS-51单片机总线接口方式工作时序 VHDL设计应用实例图6.9 CPLD/FPGA与MCS-51单片机的总线接口通信逻辑图 VHDL设计应用实例2. VHDL源程序源程序LIBRARY IEEE; --MCS-51单片机读写电路USE IEEE.STD_LOGIC_1164.ALL;ENTITY MCS_51 IS PORT( --与8031接口的各端口定义: P0:INOUT STD_LOGIC_VECTOR(7 DOWNTO 0); --双向地址/数据口 P2:IN STD_LOGIC_VECTOR(7 DOWNTO 0); --高8位地址线 RD,WR:IN STD_LOGIC; --读、写允许 ALE:IN STD_LOGIC; -- 地址锁存 READY:IN STD_LOGIC; --待读入数据准备就绪标志位 AD_CS:OUT STD_LOGIC;--A/D器件片选信号 DATAIN1:IN STD_LOGIC_VECTOR(7 DOWNTO 0);--单片机待读回信号 LATCH1:IN STD_LOGIC; --读回信号锁存 VHDL设计应用实例 DATOUT1:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);--锁存输出数据1 DATOUT2:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);--锁存输出数据2END MCS-51;ARCHITECTURE ART OF MCS-51 IS SIGNAL LATCH_ADDRES:STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL LATCH_OUT1:STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL LATCH_OUT2:STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL LATCH_IN1:STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL WR_ENABLE1:STD_LOGIC; SIGNAL WR_ENABLE2:STD_LOGIC; BEGIN PROCESS ( ALE ) --低8位地址锁存进程 BEGIN VHDL设计应用实例IF ALE'EVENT AND ALE= '0' THEN LATCH_ADDRES<=P0; --ALE的下降沿将P0口的低8位地址 END IF; --锁入锁存器LATCH_ADDRES中 END PROCESS; PROCESS(P2,LATCH_ADDRES) --WR写信号译码进程1 BEGIN IF ( LATCH_ADDRES= "11110101") AND ( P2= "01101111" ) THEN WR_ENABLE1<=WR; --写允许 ELSE WR_ENABLE1<= '1'; END IF ;--写禁止 END PROCESS; PROCESS ( WR_ENABLE1 ) --数据写入寄存器1 VHDL设计应用实例BEGINIF WR_ENABLE1'EVENT AND WR_ENABLE1 = '1' THEN LLATCH_OUT1<= P0; END IF;END PROCESS;PROCESS (P2,LATCH_ADDRES ) --WR写信号译码进程2 BEGINIF ( LATCH_ADDRES= "11110011")AND(P2= "00011111" ) THEN WR_ENABLE2<= WR; --写允许ELSE WR_ ENABLE2<= '1';END IF; --写禁止END PROCESS;PROCESS (WR_ENABLE2 ) --数据写入寄存器2BEGIN VHDL设计应用实例IF WR_ENABLE2'EVENT AND WR_ENABLE2= '1' THEN LATCH_OUT2<=P0; END IF;END PROCESS;PROCESS(P2,LATCH_ADDRES,READY,RD) --8031对PLD中数据读入进程BEGINIF ( LATCH_ADDRES= "01111110" ) AND ( P2= "10011111" )AND ( READY= '1') AND ( RD= '0' ) THEN P0<=LATCH_IN1; --寄存器中的数据读入P0口ELSE P0<= "ZZZZZZZZ";END IF ; --禁止读数,P0口呈高阻态END PROCESS;PROCESS(LATCH1 ) --外部数据进入CPLD进程 VHDL设计应用实例BEGIN IF LATCH1'EVENT AND LATCH1= '1' THEN LATCH_IN1<=DATAIN1; END IF; END PROCESS; PROCESS(ALTCH_ADDRES) --A/D工作控制片选信号输出进程 BEGINIF ( LATCH_ADDRES= "00011110" ) THEN AD_CS<= '0'; --允许A/D工作 ELSE AD_CS<= '1'; END IF; -- 禁止A/D工作 END PROCESS; DATOUT1<=LATCH_OUT1; DATOUT2<=LATCH_OUT2;EDN ART; VHDL设计应用实例 这是一个CPLD与8031单片机接口的VHDL电路设计。

8031以总线方式工作,例如,由8031将数据5AH写入目标器件中的第一个寄存器LATCH_OUT1的指令是:MOV A,#5AHMOV DPTR,#6FF5HMOVX @DPTR,A 当READY为高电平时,8031从目标器件中的寄存器LATCH_IN1将数据读入的指令是:MOV DPTR,#9F7EHMOVX A,@DPTR VHDL设计应用实例8 交通灯信号控制器的设计交通灯信号控制器的设计 1.. 设计思路设计思路 设交通灯信号控制器用于主干道与支道公路的交叉路口,要求是优先保证主干道的畅通因此,平时处于“主干道绿灯,支道红灯”状态,只有在支道有车辆要穿行主干道时,才将交通灯切向“主干道红灯,支道绿灯”,一旦支道无车辆通过路口,交通灯又回到“主干道绿灯,支道红灯”的状态此外,主干道和支道每次通行的时间不得短于30 s,而在两个状态交换过程出现的“主黄,支红”和“主红,支黄”状态,持续时间都为4 s根据交通灯信号控制的要求,我们可把它分解为定时器和控制器两部分,其原理方框图如图6.10所示 VHDL设计应用实例图6.10 交通灯信号控制器原理方框图 VHDL设计应用实例2. VHDL源程序源程序LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;ENTITY JTDKZ IS PORT(CLK,SM,SB;IN BIT;--这里要求CLK为1 kHz MR,MY,MG,BR,BY,BG:OUT BIT);END JTDKZ;ARCHITECTURE ART OF JTDKZ IS TYPE STATE_TYPE IS (A,B,C,D); SIGNAL STATE:STATE_TYPE; BEGIN VHDL设计应用实例CNT:PROCESS(CLK)VARIABLE S:INTEGER RANGE 0 TO 29;VARIABLE CLR,EN:BIT;BEGINIF (CLK'EVENT AND CLK='1') THEN IF CLR = '0' THEN S:=0; ELSIF EN = '0' THEN S:=S; ELSE S:=S+1; END IF; CASE STATE IS WHEN A=>MR<='0';MY<='0';MG<='1'; BR<= '1';BY<= '0';BG<= '0'; VHDL设计应用实例 IF (SB AND SM)= '1' THEN IF S=29 THEN STATE<=B;CLR:='0';EN:='0'; ELSE STATE<=A;CLR:='1';EN: = '1'; END IF; ELSIF (SB AND (NOT SM)) = '1' THEN STATE<=B;CLR:='0';EN:='0'; ELSE STATE<=A;CLR:='1';EN:='1'; END IF; WHEN B =>MR<= '0';MY<= '1';MG<= '0'; BR<= '1';BY<= '0';BG<= '0'; VHDL设计应用实例 IF S=3 THEN STATE <=C;CLR:='0';EN:='0'; ELSE STATE<=B;CLR:='1';EN:='1'; ENDIF; WHEN C =>MR<= '1';MY<= '0';MG<= '0'; BR<= '0';BY<= '0';BG <= '1'; IF (SM AND SB) = ' 1' THEN IF S=29 THEN STATE<=D;CLR:='0';EN:='0'; ELSE STATE<=C;CLR:= '1';EN:='1'; ELSIF SB = '0' THEN STATE <=D;CLR:= '0';EN:='0'; VHDL设计应用实例 ELSE STATE<=C;CLR:='1';EN:='1'; END IF ; WHEN D=>MR<= '1';MY<='0';MG<='0'; BR<='0';BY<='1';BG<= '0'; IF S =3 THEN STATE<=A;CLR:='0';EN:='0'; ELSE STATE<=D;CLR:='1';EN:='1'; END IF ; END CASE; END IF; END PROCESS CNT;END ART; VHDL设计应用实例 3. 硬件逻辑验证硬件逻辑验证 选择实验电路结构图NO.1,由5.2节的实验电路结构图NO.1和图6.10确定引脚的锁定。

时钟脉冲CLK可接CLOCK0(1 Hz),主干道和支干道来车信号分别接键7和键8,主干道和支干道红、黄、绿灯驱动信号MR、MY、MG和BR、BY、BG分别接D1~D3和D8~D6 进行硬件验证时方法如下:选择实验模式1,时钟脉冲与CLOCK0信号组中的1 Hz信号相接,在键7和键8施加相应的信号,发光二极管D1~D3、D8~D6则按控制要求显示相应的信号 VHDL设计应用实例9 语音信箱控制系统的设计语音信箱控制系统的设计 1.设计思路.设计思路 语音信箱控制系统用于控制对语音信箱的有关操作,允许用户发送信息、重阅信息、存储信息和擦除信息,状态转移图如图6.11所示 VHDL设计应用实例图6.11 语音信箱控制器的状态转移图 VHDL设计应用实例 正常起始状态是MAIN_ST状态,从MAIN_ST状态,用户选择究竟是收信息还是发信息为了得到收阅菜单,用户在按键上按1键;为了选发送信息菜单,用户在按键菜单上按2键一旦用户选择了这些选项中的任何一种,下一级菜单允许用户选择执行进一步(如存储与删除信息)的功能例如,如果用户先按键1,选收阅菜单,那么再按键2,将允许用户在收阅完时存储用户收阅过的信息。

VHDL设计应用实例2. VHDL源程序源程序PACKAGE VM_PACK IS TYPE T_VM_STATE IS(MAIN_ST,REPEAT_ST,SAVE_ST,ERASE_ST,SEND_ST,ADDRESS_ST,RECORD_ST,BEGIN_REC_ST,MESSAGE_ST); TYPE T_KEY('1','2','3','4','5','6','7','8','9','*','#');END VM_PACK;LIBRARY IEEE;USE WORK.VM_PACK,ALL;USE IEEE.STD_LOGIC_1164.ALL;ENTITY CONTROL IS PORT(CLK,KEY:IN STD_LOGIC; VHDL设计应用实例 PLAY,RECORD,ERASE,SAVE,ADDRESS:OUT STD_LOGIC);END CONTROL;ARCHITECTURE ART OF CONTROL IS SIGNAL NEXT_STATE,CURRENT_STATE:T_VM_STATE; BEGIN PROCESS(CURRENT_STATE,KEY) BEGIN PLAY<= '0';SAVE <= '0';ERASE<= '0'; RECORD<= '0';ADDRESS<= '0'; CASE CURRENT_STATE IS WHEN MAIN_ST => --看信箱 IF ( KEY='1') THEN VHDL设计应用实例 NEXT_STATE<=REVIEW_ST; --转到重阅 ELSIF (KEY ='2') THEN NEXT_STATE<=SEND_ST ; 转到发送 ELSE NEXT_STATE<=MAIN_ST; END IF; WHEN REVIEW_ST=> --重阅 IF (KEY='1')THEN NEXT_STATE<=REPEAT_ST; ELSIF(KEY='2') THEN NEXT_STATE<=SAVE_ST; ELSIF( KEY = '3') THEN NEXT_STATE =ERASE_ST; ELSIF( KEY = '#') THEN VHDL设计应用实例 NEXT_STATE =MAIN_ST;ELSE NEXT_STATE<=REVIEW_ST;END IF;WHEN REPEAT_ST => --重复 PLAY<= '1'; NEXT_STATE<=REVIEW_ST;WHEN SAVE_ST => --存信息 SAVE<= '1'; NEXT_STATE<=REVIEW_ST;WHEN ERASE_ST => --擦掉 ERASE<= '1'; NEXT_STATE<=REVIEW_ST; VHDL设计应用实例WHEN SEND_ST => --发送 NEXT_STATE<=ADDRESS_ST;WHEN ADDRESS_ST => --寻址 ADDRESS<= '1'; IF (KEY='#')THEN NEXT_STATE<=RECORD_ST; ELSE NEXT_STATE, =ADDRESS_ST; END IF ;WHEN RECORD_ST=> --记录 IF (KEY='5') THEN NEXT_STATE<=BEGIN_REC_ST; ELSE VHDL设计应用实例 NEXT_STATE<=RECORD_ST; END IF;WHEN BEGIN_REC_ST => --开始录音 RECORD<= '1'; NEXT_STATE<=MESSAGE_ST;WHEN MESSAGE_ST=> --记录录音 RECORD<= '1'; IF (KEY='#')THEN NEXT_STATE<=SEND_ST; 发送到信箱 ELSE NEXT_STATE<=MESSAGE_ST; VHDL设计应用实例 END IF;END CASE;END PROCESS;PROCESSBEGINWAIT UNTIL (CLK'EVENT AND CLK = '1');CURRENT_STATE<=NEXT_STATE;END PROCESS;END ART; VHDL设计应用实例 程序包VM_PACK含有对状态值的类型说明和语音信箱控制系统允许用的键盘。

必须指出的是,状态是用来表示某些事件的全过程,而事件的全过程又是由它所对应状态(如STATE1、STATE2和STATE3 等)来说明,用状态描述将使模块的可读性更好 为了实用,这个程序包实体标明了局部信号和键输入端口该实体只有一种输入(即键输入),由按键的键盘示出可能的键字,实体除KEY和CLK之外,所有其他的端口都是输出端口,并且用这些端口控制语音信箱系统的工作 VHDL设计应用实例10 PID控制器的设计控制器的设计 1.设计思路.设计思路 要求设计一个PID控制器,对电机转速进行采样,与额定的转速进行比较,并通过微积分计算得到电机的控制电流,从而实现对电机转速的调整通常,PID控制器用模拟电路实现,但数字电路的实现方案可以很方便地实现集成 该PID控制器包括一个完成算术和逻辑功能的ALU以及一个存储状态变量和有关系数的存储器其端口说明如图6.12 所示 VHDL设计应用实例图6.12 PID控制器示意图 VHDL设计应用实例 其中,RESET 端口为复位端口,当RESET为高电平时,PID控制器复位;FSIGNIN为输入的偏差方向,转速超过额定转速时为‘1’,否则为‘0’;HOSTINTERRUPT为主机请求信号,当此信号为‘1’时,PID开始计算,为‘0’时,则停止计算并输出结果。

POSITIONCHANGE为电机向PID控制器发送的脉冲信号,每转过一周,POSITONCHANGE 出现一个脉冲;IREFKOUT为最终输出的控制电流值 主机向PID控制器发调用请求HOSTINTERRUPT之后,PID控制器进行采样并开始计算,当HOSTINTERRUPT信号停止时,PID控制器停止采样计算,并将计算结果输出到主机 VHDL设计应用实例PID控制器的电流计算公式为 Irefk=(Kp+Ek) + Ki×∫Ekdt + Kd×dEk/dt采用近似的离散方式表示为 Irefk=(Kp+Ek) + Ki ×∑ Ekdt + Kd ×dEk/dt PID控制器运行时,电机每转过一周,即POSITIONCHANGE信号发生一次变化时进行采样,得到电机转过一周所需要的时间,并将其作为积分的dt值,将该dt 值取倒数计算出转速然后与标准转速进行比较,得到转速偏差Ek,将该Ek与前一周得到的Ek-1相减得出d Ek 将每一周的Ek /dt值相加得到积分∫ Ek /dt的值当HOSTINTERRUPT信号出现下降沿时将积分与当前时刻的(Kp+ Ek)以及Kd×d Ek /dt线性相加得到控制电流值。

然后,在下一个时钟周期将该控制电流值输出到主机 VHDL设计应用实例4..VHDL源程序源程序LIBRARY WORK;USE WORK.SYNCHRO.ALL;USE WORK.OP_PKG.ALL;ENTITY PID IS PORT ( RESET:IN BIT;FSIGNIN:IN BIT;HOSTINTERRUPT:IN BIT;POSITIONCHANGE:IN BIT;IREFKOUT :OUT REAL );END PID;ARCHITECTURE ART OF PID IS COMPONENT FU_FPU VHDL设计应用实例PORT (CLOCK :IN BIT;RESET :N BIT;INPUT1 :IN REAL;INPUT2 :IN REAL;SEL :IN BIT;COM :IN INT3BIT;OUTPUT :OUT REAL;OUTDONE :OUT BIT);END COMPONENT; VHDL设计应用实例 SIGNAL SIG_IN1,SIG_IN2 :REAL; SIGNAL SIG_OUT : REAL; SIGNAL SIG_SEL,SIG_DONE :BIT; SIGNAL SIG_COM : INT3BIT; SIGNAL CLOCK : BIT;-- <= '1'; FOR ALL:FU_FPU USE ENTITY WORK.FIXEDPOINTUNIT(ART); VHDL设计应用实例 BEGIN INST_FU :FU_FPU PORT MAP(CLOCK => CLOCK, RESET => RESET, INPUT1 => SIG_IN1, INPUT2 => SIG_IN2, SEL => SIG_SEL, COM => SIG_COM, OUTPUT => SIG_OUT, OUTDONE => SIG_DONE); VHDL设计应用实例PROCESSVARIABLE N,EK_1,IK,EK,KP,KI,KD,FREF: REAL;VARIABLE FK,DEK,IREFK, TEMP: REAL;VARIABLE DONE : BIT; VHDL设计应用实例PROCEDURE MUL(A,B : IN REAL) IS BEGIN SIG_IN1 <= A; SIG_IN2 <= B; SIG_SEL <='1'; SIG_COM <= 2; WAIT UNTIL RISING_EDGE(CLOCK); SIG_SEL <='0'; RETURN;END MUL; VHDL设计应用实例PROCEDURE REP(A: IN REAL) IS BEGIN SIG_IN1 <= A; SIG_SEL <='1'; SIG_COM <= 1; WAIT UNTIL RISING_EDGE(CLOCK); SIG_SEL <='0'; RETURN;END REP; VHDL设计应用实例PROCEDURE WAITRESULT(X:OUT REAL; Y:OUT BIT) ISBEGIN X := SIG_OUT; Y := SIG_DONE; WAIT UNTIL RISING_EDGE(CLOCK); RETURN;END WAITRESULT;TYPE ROM IS ARRAY(0 TO 4) OF REAL;VARIABLE VAL_ROM : ROM := (2.0*2.0**(-20),2.0,3.0*2.0**(- 20),4.0*2.0**(20),2.0*2.0** (-20)); PROCEDURE GETCONSTKP(X :OUT REAL) IS VHDL设计应用实例BEGIN X := VAL_ROM(0);END GETCONSTKP;PROCEDURE GETCONSTKI(X :OUT REAL) ISBEGIN X := VAL_ROM(1);END GETCONSTKI;PROCEDURE GETCONSTKD(X : OUT REAL) ISBEGIN X := VAL_ROM(2);END GETCONSTKD;PROCEDURE GETFREF(X :OUT REAL) ISBEGIN X := VAL_ROM(3); VHDL设计应用实例END GETFREF;PROCEDURE GETN(X :OUT REAL) IS BEGIN X := VAL_ROM(4);END GETN;BEGIN GETCONSTKP(KP); GETCONSTKI(KI); GETCONSTKD(KD); GETFREF(FREF); IK :=0.0; EK := 0.0; IREFK := 0.0; VHDL设计应用实例 --WAIT FOR 50 NS; WAIT UNTIL (HOSTINTERRUPT ='0'); WHILE (HOSTINTERRUPT ='0') LOOP WAIT UNTIL(POSITIONCHANGE ='1'); GETN(N); REP(N); EK_1 := EK; --WAIT UNTIL(DONE ='1')WAITRESULT(FK,DONE);WHILE (DONE /='1') LOOP WAITRESULT(FK,DONE); END LOOP; IF(FSIGNIN ='0') THEN EK := FREF - FK; ELSE EK := FREF + FK; VHDL设计应用实例END IF;MUL(KP,EK);DEK := EK - EK_1;WAITRESULT(IREFK,DONE);WHILE(DONE /='1'') LOOP WAITRESULT(IREFK,DONE); END LOOP;MUL(DEK,FK);WAITRESULT(TEMP,DONE);WHILE(DONE /='1') LOOP WAITRESULT(TEMP,DONE); END LOOP;MUL(TEMP,KD);WAITRESULT(TEMP,DONE);WHILE(DONE /='1') LOOP WAITRESULT(TEMP,DONE); END LOOP; IREFK := IREFK + TEMP; VHDL设计应用实例MUL(EK,N); WAITRESULT(TEMP,DONE);WHILE(DONE /='1') LOOP WAITRESULT(TEMP,DONE); END LOOP;IK := IK + TEMP;MUL(IK,KI);WAITRESULT(TEMP,DONE);WHILE (DONE /='1') LOOP WAITRESULT(TEMP ,DONE); END LOOP;-- IREFKOUT <= IREFK + TEMP;IREFK := IREFK + TEMP; END LOOP; IREFKOUT <= IREFK; END PROCESS; CLOCK <= NOT CLOCK ;END ART; VHDL设计应用实例11 空调系统有限状态自动机的设计空调系统有限状态自动机的设计 1.设计思路.设计思路 设计一个空调系统的有限状态自动机,它的两个输入端TEMP_HIGH 和TEMP_LOW分别与传感器相连,用于检测室内温度。

如果室内温度正常,则TEMP_HIGH和TEMP_LOW均为‘0’如果室内温度过高,则TEMP_HIGH为‘1’,TEMP_LOW为‘0 ’如果室内温度过低,则TEMP_HIGH为‘0’, TEMP_LOW为‘1’根据TEMP_HIGH 和TEMP_LOW的值来判断当前的状态(太热TOO_HOT,太冷 TOO_COLD或适中JUST_RIGHT),并决定HEAT和COOL的输出值其原理方框图如图6.13所示 VHDL设计应用实例图6.13 空调有限状态自动机原理方框图 VHDL设计应用实例2..VHDL源程序源程序LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;ENTITY AIR_CONDITIONER IS PORT(CLK : IN STD_ULOGIC; TEMP_HIGH :IN STD_ULOGIC; TEMP_LOW : IN STD_ULOGIC; HEAT : OUT STD_ULOGIC; COOL : OUT STD_ULOGIC);END AIR_CONDITIONER; VHDL设计应用实例ARCHITECTURE ART OF AIR_CONDITIONER IS TYPE STATE_TYPE IS (JUST_RIGHT,TOO_COLD,TOO_HOT); ATTRIBUTE SEQUENTIAL_ENCODING : STRING; ATTRIBUTE SEQUENTIAL_ENCODING OF STATE_TYPE :TYPE IS “00 01 10”; SIGNAL STVAR: STATE_TYPE; ATTRIBUTE STATE_VECTOR : STRING; ATTRIBUTE STATE_VECTOR OF STYLE_B:ARCHITECTURE IS “STVAR”;BEGIN CONTROLLER1: PROCESS BEGIN WAIT UNTIL CLK='1'; --REVISED BY DLS VHDL设计应用实例 IF (TEMP_LOW='1') THEN STVAR<=TOO_COLD; ELSIF (TEMP_HIGH='1') THEN STVAR<=TOO_HOT; ELSE STVAR<=JUST_RIGHT; END IF; CASE STVAR IS WHEN JUST_RIGHT=>HEAT<='0';COOL<='0'; WHEN TOO_COLD=>HEAT<='1';COOL<='0'; WHEN TOO_HOT=>HEAT<='0';COOL<='1'; END CASE; END PROCESS CONTROLLER1;END ART; VHDL设计应用实例12 闹钟系统的设计闹钟系统的设计6.12.1 闹钟系统的设计要求及设计思路闹钟系统的设计要求及设计思路 要求设计一个带闹钟功能的24小时计时器,计时器的外观如图6.14所示。

它包括以下几个组成部分:① 显示屏,由4个七段数码管组成,用于显示当前时间(时:分)或设置的闹钟时间;② 数字键‘0’~‘9’,用于输入新的时间或新的闹钟时间;③ TIME(时间)键,用于确定新的时间设置;④ ALARM(闹钟)键,用于确定新的闹钟时间设置,或显示已设置的闹钟时间;⑤ 扬声器,在当前时钟时间与闹钟时间相同时,发出蜂鸣声 VHDL设计应用实例图6.14 计时器外观 VHDL设计应用实例 该计时器设计要求完成如下功能: (1) 计时功能:这是本计时器设计的基本功能,每隔一分钟计时一次,并在显示屏上显示当前时间 (2) 闹钟功能:如果当前时间与设置的闹钟时间相同,则扬声器发出蜂鸣声 (3) 设置新的计时器时间:用户用数字键‘0’~‘9’输入新的时间,然后按 "TIME"键确认在输入过程中,输入数字在显示屏上从右到左依次显示例如,用户要设置新的时间12:34,则按顺序输入“1”,“2”,“3”,“4”键,与之对应,显示屏上依次显示的信息为:“1”,“12”,“123”,“1234"如果用户在输入任意几个数字后较长时间内,例如5 s,没有按任何键,则计时器恢复到正常的计时显示状态。

VHDL设计应用实例 (4) 设置新的闹钟时间:用户用数字键“0”~“9”输入新的时间,然后按“ALARM”键确认过程与(3)类似 (5) 显示所设置的闹钟时间:在正常计时显示状态下,用户直接按下“ALARM”键,则已设置的闹钟时间将显示在显示屏上 根据上述的设计要求,整个系统大致包括如下几个组成部分:用于键盘输入的缓冲器;用于时钟计数的计数器;用于保存闹钟时间的寄存器;用于显示的七段数码显示电路以及控制以上各个部分协同工作的控制器 VHDL设计应用实例6.12.2 闹钟系统的控制器的设计闹钟系统的控制器的设计 1.设计思路.设计思路 控制器命名为ALARM_CONTROLLER,其外部端口如图6.15所示各端口的作用如下: (1) CLK为外部时钟信号,RESET为复位信号 (2) 当KEY为高电平(KEY= '1')时,表示用户按下数字键(“0”~“9”) (3) 当ALARM_BUTTON为高电平时,表示用户按下“ALARM”键 (4) 当TIME_BUTTON为高电平时,表示用户按下“TIME”键。

VHDL设计应用实例图6.15 控制器的外部端口 VHDL设计应用实例 (5) 当LOAD_NEW_A 为高电平时,控制(闹钟时间寄存器)加载新的闹钟时间值 (6) 当LOAD_NEW_C为高电平时,控制(时钟计数器)设置新的时间值 (7) 当SHOW_NEW_TIME为高电平时,控制(七段数码显示电路)显示新的时间值,即用户通过数字键输入的时间;否则,当SHOW_NEW_TIME为低电平时,根据SHOW_A信号的值控制显示当前时间或闹钟时间此时,当SHOW_A为高电平时,控制显示闹钟时间,否则,显示当前时间 VHDL设计应用实例 控制器的功能可以通过有限状态自动机(FSM)的方式来实现根据设计要求及端口设置,需要5个状态来实现: S0: 表示电路初态即正常时钟计数状态,完成前面设计功能 (1) 的工作 S1:接收键盘输入状态在状态S0时用户按下数字键后进入此状态在此状态下,显示屏上显示的是用户键入的数字 S2:设置新的闹钟时间在状态S1时用户按下ALARM键后进入此状态 S3:设置新的计时器时间。

在状态S1时用户按下TIME键后进入此状态 VHDL设计应用实例 S4:显示闹钟时间在状态S0时用户直接按下ALARM键后进入此状态在此状态下, 显示屏上显示的是所设置的闹钟时间注意:在此状态下,用户按下ALARM键后,显示屏上保持显示闹钟时间,经过一段时间以后,再返回状态S0显示计时器时间 VHDL设计应用实例表表6.1 控制器状态转换及控制输出表控制器状态转换及控制输出表 VHDL设计应用实例 表6.1中没有显式说明的控制信号赋值,表示信号的值为零例如在状态S0,当信号KEY =‘1’时,SHOW_NEW_TIME信号的赋值为‘1’,而其他信号LOAD_NEW_A,LOAD_NEW_C和SHOW_A的值此时都赋为‘0’另外,表中关于“超时”判断处理的处理细节见VHDL源程序中的有关部分 VHDL设计应用实例2..VHDL源程序源程序LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE WORK.P_ALARM.ALL;ENTITY ALARM_CONTROLLER IS PORT(KEY :IN STD_LOGIC; ALARM_BUTTON :IN STD_LOGIC; TIME_BUTTON :IN STD_LOGIC; CLK :IN STD_LOGIC; RESET :IN STD_LOGIC; LOAD_NEW_A :OUT STD_LOGIC; LOAD_NEW_C :OUT STD_LOGIC; SHOW_NEW_TIME :OUT STD_LOGIC; SHOW_A :OUT STD_LOGIC );END ALARM_CONTROLLER; VHDL设计应用实例ARCHITECTURE ART OF ALARM_CONTROLLER IS TYPE T_STATE IS (S0, S1, S2, S3,S4); CONSTANT KEY_TIMEOUT :T_SHORT := 500; CONSTANT SHOW_ALARM_TIMEOUT : T_SHORT := 500; SIGNAL CURR_STATE : T_STATE; SIGNAL NEXT_STATE : T_STATE; SIGNAL COUNTER_K : T_SHORT; SIGNAL ENABLE_COUNT_K : STD_LOGIC; SIGNAL COUNT_K_END : STD_LOGIC; SIGNAL COUNTER_A : T_SHORT; SIGNAL ENABLE_COUNT_A : STD_LOGIC; SIGNAL COUNT_A_END : STD_LOGIC; BEGIN VHDL设计应用实例PROCESS(CLK,RESET)BEGIN IF RESET ='1' THEN CURR_STATE <= S0; ELSIF RISING_EDGE(CLK) THEN CURR_STATE <= NEXT_STATE; END IF; END PROCESS; VHDL设计应用实例PROCESS(KEY,ALARM_BUTTON,TIME_BUTTON,CURR_STATE, COUNT_A_END,COUNT_K_END)BEGIN NEXT_STATE <= CURR_STATE; LOAD_NEW_A <= '0'; LOAD_NEW_C <= '0'; SHOW_A <= '0'; SHOW_NEW_TIME <= '0'; ENABLE_COUNT_K <= '0'; ENABLE_COUNT_A <= '0'; VHDL设计应用实例CASE CURR_STATE ISWHEN S0 => IF (KEY = '1') THEN NEXT_STATE <= S1; SHOW_NEW_TIME <= '1'; ELSIF (ALARM_BUTTON = '1') THEN NEXT_STATE <= S4; SHOW_A <= '1'; ELSE NEXT_STATE <= S0; END IF;WHEN S1 => IF (KEY = '1') THEN NEXT_STATE <= S1; VHDL设计应用实例 ELSIF (ALARM_BUTTON = '1') THEN NEXT_STATE <= S2; LOAD_NEW_A <= '1'; ELSIF (TIME_BUTTON = '1') THEN NEXT_STATE <= S3; LOAD_NEW_C <= '1'; ELSE IF (COUNT_K_END = '1') THEN NEXT_STATE <= S0; ELSE NEXT_STATE <= S1; END IF; ENABLE_COUNT_K <= '1'; END IF; SHOW_NEW_TIME <= '1'; VHDL设计应用实例WHEN S2 => IF (ALARM_BUTTON = '1') THEN NEXT_STATE <= S2; LOAD_NEW_A <= '1'; ELSE NEXT_STATE <= S0; END IF; WHEN S3 => IF (TIME_BUTTON = '1') THEN NEXT_STATE <= S3; LOAD_NEW_C <= '1'; ELSE NEXT_STATE <= S0; VHDL设计应用实例 END IF; WHEN S4 => IF (KEY = '1') THEN NEXT_STATE <= S1; ELSE NEXT_STATE <= S4; IF (COUNT_A_END = '1') THEN NEXT_STATE <= S0; ELSE NEXT_STATE <= S4; SHOW_A <= '1'; VHDL设计应用实例 END IF; ENABLE_COUNT_A <= '1'; END IF;WHEN OTHERS => NULL; END CASE;END PROCESS; VHDL设计应用实例COUNT_KEY : PROCESS(ENABLE_COUNT_K, CLK)BEGIN IF (ENABLE_COUNT_K = '0') THEN COUNTER_K <= 0; COUNT_K_END <= '0'; ELSIF (RISING_EDGE(CLK)) THEN IF (COUNTER_K >= KEY_TIMEOUT) THEN COUNT_K_END <= '1'; ELSE COUNTER_K <= COUNTER_K + 1; END IF; END IF;END PROCESS; VHDL设计应用实例COUNT_ALARM : PROCESS(ENABLE_COUNT_A, CLK)BEGIN IF (ENABLE_COUNT_A = '0') THEN COUNTER_A <= 0; COUNT_A_END <= '0'; ELSIF RISING_EDGE(CLK) THEN IF (COUNTER_A >= SHOW_ALARM_TIMEOUT) THEN COUNT_A_END <= '1'; ELSE COUNTER_A <= COUNTER_A + 1; END IF; END IF;END PROCESS;END ART; VHDL设计应用实例6.12.3 闹钟系统的译码器的设计闹钟系统的译码器的设计 1.设计思路.设计思路 本模块的功能是将每次按下闹钟系统的数字键盘后产生的一个数字所对应的10位二进制数据信号转换为1位十进制整数信号,以作为小时、分钟计数的4个数字之一,如图6.16所示。

其中KEYPAD为输入端口,接收10位二进制数据信号;VALUE为输出端口,输出相应的1位十进制整数信号输入数据与输出数据的译码关系见表6.2 VHDL设计应用实例图6.16 电路系统示意图 VHDL设计应用实例表表6.2 输入、输出数据的译码关系输入、输出数据的译码关系 VHDL设计应用实例2..VHDL源程序源程序LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE WORK.P_ALARM.ALL;ENTITY DECODER IS PORT(KEYPAD :IN STD_LOGIC_VECTOR(9 DOWNTO 0); VALUE :OUT T_DIGITAL);END DECODER;ARCHITECTURE ART OF DECODER ISBEGIN VHDL设计应用实例 WITH KEYPAD SELECT VALUE <= 0 WHEN “0000000001”, 1 WHEN “0000000010”, 2 WHEN “0000000100”, 3 WHEN “0000001000”, 4 WHEN “0000010000”, 5 WHEN “0000100000”, 6 WHEN “0001000000”, 7 WHEN “0010000000”, 8 WHEN “0100000000”, 9 WHEN “1000000000”, 0 WHEN OTHERS; END ART; VHDL设计应用实例6.12.4 闹钟系统的移位寄存器的设计闹钟系统的移位寄存器的设计 1.设计思路.设计思路 本模块的功能是在CLK端口输入信号的上升沿同步下,将KEY端口的输入信号移入NEW_TIME 端口的输出信号最低位,原有信息依次向左移,最高位信息丢失;而RESET端口的输入信号对NEW_TIME端口输出信号进行异步清零复位。

电路系统示意图如图6.17所示 VHDL设计应用实例图6.17 移位寄存器电路示意图 VHDL设计应用实例2..VHDL源程序源程序LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE WORK.P_ALARM.ALL;ENTITY KEY_BUFFER IS PORT(KEY :IN T_DIGITAL; CLK :IN STD_LOGIC; RESET :IN STD_LOGIC; NEW_TIME:OUT T_CLOCK_TIME);END KEY_BUFFER;ARCHITECTURE ART OF KEY_BUFFER IS SIGNAL N_T:T_CLOCK_TIME; BEGIN VHDL设计应用实例 SHIFT:PROCESS(RESET,CLK) BEGIN IF (RESET = '1') THEN N_T <= (0,0,0,0); ELSIF (CLK'EVENT AND CLK = '1' )THEN FOR I IN 3 DOWNTO 1 LOOP N_T(I) <= N_T(I-1); END LOOP; N_T(0) <= KEY; END IF; END PROCESS; NEW_TIME <= N_T;END ART; VHDL设计应用实例6.12.5 闹钟系统的闹钟寄存器和时间计数器的设计闹钟系统的闹钟寄存器和时间计数器的设计 1.电路系统工作原理.电路系统工作原理 闹钟寄存器模块的功能是在时钟上升沿同步下,根据LOAD _NEW _A端口的输入信号控制ALARM _TIME端口的输出,当控制信号有效(高电平)时,把NEW _ALARM _TIME端口的输入信号值输出;而RESET端口输入信号对ALARM _TIME 端口的输出进行异步的清零复位。

图6.18是闹钟寄存器模块的示意图 闹钟系统的闹钟时间由闹钟寄存器保存和传递,而当前时间由时间计数器保存、传递并按分钟累加推进这两个组件的功能和设计描述比较相似,它们之间的区别主要在于自动累加功能的有无和控制信号的优先作用次序 VHDL设计应用实例图6.18 闹钟寄存器示意图 VHDL设计应用实例 时间计数器模块的功能是当RESET端口输入信号为高电平时,对CURRENT _TIME端口输出信号清零复位;当LOAD _NEW _C端口输入信号为高电平时,将NEW_CURRENT_TIME端口的输入信号输出给CURRENT_TIME端口RESET端口D的控制优先于LOAD _NEW _C端口当这两个控制信号都无效时,在时钟上升沿同步下,对CURRENT _TIME端口输出信号累加1,并根据小时、分钟的规律处理进位图6.19是时间计数器模块的示意图 VHDL设计应用实例图6.19 时间计数器模块的示意图 VHDL设计应用实例2..VHDL源程序源程序--时间计数器的源程序ALARM_COUNTER.VHDLIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE WORK.P_ALARM.ALL;ENTITY ALARM_COUNTER IS PORT(NEW_CURRENT_TIME:IN T_CLOCK_TIME; LOAD_NEW_C :IN STD_LOGIC; CLK :IN STD_LOGIC; RESET :IN STD_LOGIC; CURRENT_TIME :OUT T_CLOCK_TIME); VHDL设计应用实例END ALARM_COUNTER;ARCHITECTURE ART OF ALARM_COUNTER IS SIGNAL I_CURRENT_TIME : T_CLOCK_TIME; BEGINPROCESS(CLK,RESET,LOAD_NEW_C) VARIABLE C_T:T_CLOCK_TIME; BEGIN IF RESET = '1' THEN I_CURRENT_TIME <= (0,0,0,0); ELSIF LOAD_NEW_C ='1' THEN I_CURRENT_TIME <= NEW_CURRENT_TIME; ELSIF RISING_EDGE(CLK) THEN VHDL设计应用实例 C_T := I_CURRENT_TIME; IF C_T(0) < 9 THEN C_T(0) := C_T(0) + 1; ELSE C_T(0) := 0; IF C_T(1) < 5 THEN C_T(1) := C_T(1) + 1; ELSE C_T(1) := 0; IF C_T(3) < 2 THEN IF C_T(2) < 9 THEN C_T(2) := C_T(2) + 1; ELSE C_T(2) := 0; VHDL设计应用实例 C_T(3) := C_T(3) + 1; END IF; ELSE IF C_T(2) < 3 THEN C_T(2) := C_T(2) + 1; ELSE C_T(2) := 0; C_T(3) := 0; END IF; END IF; END IF; END IF; I_CURRENT_TIME <= C_T; VHDL设计应用实例 END IF; END PROCESS; CURRENT_TIME <= I_CURRENT_TIME;END ART;--闹钟寄存器的源程序ALARM_REG.VHDLIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE WORK.P_ALARM.ALL;ENTITY ALARM_REG IS PORT(NEW_ALARM_TIME:IN T_CLOCK_TIME; LOAD_NEW_A :IN STD_LOGIC; CLK :IN STD_LOGIC; VHDL设计应用实例 RESET :IN STD_LOGIC; ALARM_TIME :OUT T_CLOCK_TIME);END ALARM_REG;ARCHITECTURE ART OF ALARM_REG IS BEGIN PROCESS(CLK,RESET) BEGIN IF RESET = '1' THEN ALARM_TIME <= (0,0,0,0); ELSE IF RISING_EDGE(CLK) THEN IF LOAD_NEW_A = '1' THEN ALARM_TIME <= NEW_ALARM_TIME; VHDL设计应用实例ELSIF LOAD_NEW_A /= '0' THEN ASSERT FALSE REPORT“UNCERTAIN LOAD_NEW_ALARM CONTROL!” SEVERITY WARNING; END IF; END IF; END IF; END PROCESS;END ART; VHDL设计应用实例6.12.6 闹钟系统的显示驱动器的设计闹钟系统的显示驱动器的设计 1.设计思路.设计思路 本模块的功能是:当SHOW_NEW_TIME端口输入信号有效(高电平)时,根据NEW_TIME端口输入信号(时间数据),产生相应的4个七段数码显示器的驱动数据,并在DISPLAY端口输出该信号。

当SHOW_NEW_TIME端口输入信号无效(低电平)时,判断SHOW_A端口的输入信号,为高电平时,根据ALARM_TIME端口的输入信号(时间数据)产生相应的4个七段数码显示器的驱动数据,并在DISPLAY端口输出该信号;为低电平时,根据CURRENT_TIME端口的输入信号,对DISPLAY端口进行驱动当ALARM_TIME 端口的输入信号值与CURRENT_TIME端口的输入信号值相同时,SOUND_ALARM端口的输出信号有效(高电平),反之无效图6.20为显示驱动器示意图 VHDL设计应用实例图6.20 显示驱动器示意图 VHDL设计应用实例2..VHDL源程序源程序LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE WORK.P_ALARM.ALL;ENTITY DISPLAY_DRIVER IS PORT(ALARM_TIME :IN T_CLOCK_TIME; CURRENT_TIME :IN T_CLOCK_TIME; NEW_TIME :IN T_CLOCK_TIME; SHOW_NEW_TIME:IN STD_LOGIC; SHOW_A :IN STD_LOGIC; SOUND_ALARM :OUT STD_LOGIC; DISPLAY:OUT T_DISPLAY); VHDL设计应用实例END DISPLAY_DRIVER;ARCHITECTURE ART OF DISPLAY_DRIVER IS SIGNAL DISPLAY_TIME:T_CLOCK_TIME; BEGIN CTRL:PROCESS(ALARM_TIME,CURRENT_TIME,NEW_TIME,SHOW_A,SHOW_NEW_TIME) BEGIN SOUND_LP: FOR I IN ALARM_TIME'RANGE LOOP IF NOT(ALARM_TIME(I) = CURRENT_TIME(I)) THEN SOUND_ALARM <= '0'; EXIT SOUND_LP; VHDL设计应用实例ELSE SOUND_ALARM <= '1'; END IF; END LOOP SOUND_LP; IF SHOW_NEW_TIME = '1' THEN DISPLAY_TIME <= NEW_TIME; ELSIF SHOW_A = '1' THEN DISPLAY_TIME <= ALARM_TIME; ELSIF SHOW_A = '0' THEN DISPLAY_TIME <= CURRENT_TIME; ELSE ASSERT FALSE REPORT “UNCERTAIN DISPLAY_DRIVER CONTROL!” VHDL设计应用实例SEVERITY WARNING; END IF; END PROCESS; DISP:PROCESS(DISPLAY_TIME) BEGIN FOR I IN DISPLAY_TIME'RANGE LOOP DISPLAY(I) <= SEVEN_SEG(DISPLAY_TIME(I)); END LOOP; END PROCESS; END ART; VHDL设计应用实例6.12.7 闹钟系统的分频器的设计闹钟系统的分频器的设计 1.设计思路 .设计思路  本模块的功能是将CLK_IN端口输入的时钟信号分频后送给CLK_OUT端口。

当RESET端口输入信号有效(高电平)时,CLK_OUT端口输出信号清零图6.21为分频器示意图 VHDL设计应用实例图6.21 分频器示意图 VHDL设计应用实例2..VHDL源程序源程序LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE WORK.P_ALARM.ALL;ENTITY FQ_DIVIDER IS PORT( CLK_IN :IN STD_LOGIC; RESET :IN STD_LOGIC; CLK_OUT :OUT STD_LOGIC );END FQ_DIVIDER;ARCHITECTURE ART OF FQ_DIVIDER IS VHDL设计应用实例 CONSTANT DIVIDE_PERIOD : T_SHORT := 6000; BEGIN DIVIDE_CLK: PROCESS(CLK_IN,RESET) VARIABLE CNT : T_SHORT; BEGIN IF (RESET = '1') THEN CNT := 0; CLK_OUT <= '0'; ELSIF RISING_EDGE(CLK_IN) THEN IF (CNT < (DIVIDE_PERIOD/2)) THEN CLK_OUT <= '1'; VHDL设计应用实例 CNT := CNT + 1; ELSIF (CNT < (DIVIDE_PERIOD-1)) THEN CLK_OUT <= '0'; CNT := CNT + 1; ELSE CNT := 0; END IF; END IF; END PROCESS; -- DIVIDE CLKEND ART; VHDL设计应用实例6.12.8 闹钟系统的整体组装闹钟系统的整体组装 1.整体组装说明.整体组装说明 前边已经完成了计时器各个组成部分的设计,下面把这些组成部分组装起来,形成完整的总体设计。

该计时器命名为ALARM_CLOCK,其外部端口如图6.22所示 VHDL设计应用实例图6.22 计时器的外部端口 VHDL设计应用实例 各个输入输出端口的作用如下: (1) CLK为外部时钟信号,RESET为复位信号 (2) KEYPAD是一个10位信号,若其中某一位为高电平,则表示用户按下了相应下标的数字键例如,若KEYPAD(5) = '1',表示用户按下了数字键“5”本设计不考虑用户同时按下多个数字键的情况,所以任意时刻KEYPAD中只能有一位为‘1’ (3) 当KEYDOWN为高电平时(KEYDOWN= '1'),表示用户按下某一数字键 VHDL设计应用实例 (4) 当ALARM_BUTTON为高电平时,表示用户按下ALARM键 (5) 当TIME_BUTTON为高电平时,表示用户按下TIME键 (6) DISPLAY实际上表示了4个七段数码显示管,用于显示时间,如12:20 (7) SOUND_ALARM用于控制扬声器发声,当SOUND_ALARM = '1' 时,扬声器发出蜂鸣,表示到了设定的闹钟时间。

设计的总体结构图如图6.23所示 VHDL设计应用实例图6.23 总体结构 VHDL设计应用实例 下面再简要说明各组成部分的功能: (1) 译码器(DECODER) 可将KEYPAD信号转换为0~9的整型数,以直观地表示和处理用户输入的数字 (2) 键盘缓冲器(KEY_BUFFER)是一个移位寄存器,暂存用户键入的数字,并且实现用户键入数字在显示器上从右到左的依次显示这里需要注意的是,由图6.23可以看出,KEY_BUFFER的时钟端连接的是外部KEY_DOWN 信号这表示用户每输入一个数字,KEY_BUFFER移位一次 VHDL设计应用实例 (3) 分频器(FQ_DIVIDER)将较高速的外部时钟频率分频成每分钟一次的时钟频率,以便进行时钟计数 (4) 计数器(ALARM_COUNTER)实际上是一个异步复位、异步置数的累加器,通常情况下进行时钟累加计数,必要时可置入新的时钟值,然后从该值开始新的计数 (5) 寄存器(ALARM_REG)用于保存用户设置的闹钟时间,是一个异步复位寄存器。

VHDL设计应用实例 (6) 显示器(DISPLAY_DRIVER)根据需要显示当前时间、用户设置的闹钟时间或用户通过键盘输入的新的时间,同时判断当前时间是否已到了闹钟时间,实际上是一个多路选择器加比较器 (7) 控制器(ALARM_CONTROLLER)是设计的核心部分,按设计要求产生相应的控制逻辑,以控制其他各部分的工作 VHDL设计应用实例2..VHDL源程序源程序LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE WORK.P_ALARM.ALL;ENTITY ALARM_CLOCK IS PORT(KEYPAD :IN STD_LOGIC_VECTOR(9 DOWNTO 0);KEY_DOWN :IN STD_LOGIC; ALARM_BUTTON:IN STD_LOGIC; TIME_BUTTON :IN STD_LOGIC; CLK :IN STD_LOGIC; RESET :IN STD_LOGIC; DISPLAY :OUT T_DISPLAY; SOUND_ALARM :OUT STD_LOGIC);END ALARM_CLOCK; VHDL设计应用实例ARCHITECTURE ART OF ALARM_CLOCK IS COMPONENT DECODER --待调用元件端口定义 PORT(KEYPAD:IN STD_LOGIC_VECTOR(9 DOWNTO 0); VALUE :OUT T_DIGITAL); END COMPONENT; COMPONENT KEY_BUFFER --待调用元件端口定义  ... COMPONENT ALARM_COUNTER --待调用元件端口定义 ... COMPONENT ALARM_REG --待调用元件端口定义 ... COMPONENT ALARM_CONTROLLER --待调用元件端口定义 ... VHDL设计应用实例 COMPONENT DISPLAY_DRIVER --待调用元件端口定义 ... COMPONENT FQ_DIVIDER --待调用元件端口定义   ... SIGNAL INNER_KEY : T_DIGITAL; SIGNAL INNER_TIME : T_CLOCK_TIME; SIGNAL INNER_TIME_C : T_CLOCK_TIME; SIGNAL INNER_TIME_A : T_CLOCK_TIME; SIGNAL INNER_L_C : STD_LOGIC; SIGNAL INNER_L_A : STD_LOGIC; SIGNAL INNER_S_A : STD_LOGIC; SIGNAL INNER_S_N : STD_LOGIC; SIGNAL INNER_SEC_CLK : STD_LOGIC; VHDL设计应用实例FOR ALL: DECODER USE ENTITY WORK.DECODER(ART);FOR ALL: KEY_BUFFER USE ENTITY WORK.KEY_BUFFER(ART);FOR ALL: ALARM_COUNTER USE ENTITY WORK.ALARM_COUNTER(ART);FOR ALL: ALARM_REG USE ENTITY WORK.ALARM_REG(ART);FOR ALL: ALARM_CONTROLLER USE ENTITY WORK.ALARM_CONTROLLER(ART);FOR ALL: DISPLAY_DRIVER USE ENTITY WORK.DISPLAY_DRIVER(ART);F OR ALL: FQ_DIVIDER USE ENTITY WORK.FQ_DIVIDER(ART); VHDL设计应用实例BEGIN U1: DECODER PORT MAP(KEYPAD,INNER_KEY); U2: KEY_BUFFER PORT MAP(INNER_KEY, KEY_DOWN, RESET, INNER_TIME); U3: ALARM_CONTROLLER PORT MAP(KEY_DOWN,ALARM_BUTTON,TIME_BUTTON,CLK,RESET, INNER_L_A,INNER_L_C, INNER_S_N, INNER_S_A ); U4: ALARM_COUNTER PORT MAP( INNER_TIME, INNER_L_C, INNER_SEC_CLK, RESET, INNER_TIME_C); U5: ALARM_REG PORT MAP(INNER_TIME,INNER_L_A,CLK,RESET,INNER_TIME_A); U6: DISPLAY_DRIVER PORT MAP( INNER_TIME_A,INNER_TIME_C,INNER_TIME, INNER_S_N, INNER_S_A, SOUND_ALARM,DISPLAY ); U7: FQ_DIVIDER PORT MAP(CLK,RESET,INNER_SEC_CLK);END ART; VHDL设计应用实例6.12.9 闹钟系统的硬件验证闹钟系统的硬件验证 若用GW48型EDA实验开发系统进行硬件验证,考虑到实验开发系统提供的输入信号按键的有限,可将输入数字按键0~9改为一个按键,该按键的信号作为一个8421码信号发生器的输入,由8421码信号发生器输出数字0~9。

具体验证方案由读者自行完成。

下载提示
相似文档
正为您匹配相似的精品文档
相关文档