资源预览内容
第1页 / 共198页
第2页 / 共198页
第3页 / 共198页
第4页 / 共198页
第5页 / 共198页
第6页 / 共198页
第7页 / 共198页
第8页 / 共198页
第9页 / 共198页
第10页 / 共198页
亲,该文档总共198页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
VHDL设计应用实例VHDL设计应用实例1 8位加法器的设计位加法器的设计2 8位乘法器的设计位乘法器的设计3 序列检测器的设计序列检测器的设计4 正负脉宽数控调制信号发生器的设计正负脉宽数控调制信号发生器的设计5 数字频率计的设计数字频率计的设计6 秒表的设计秒表的设计7 MCS51单片机与单片机与FPGA/CPLD总线接口逻辑设计总线接口逻辑设计8 交通灯信号控制器的设计交通灯信号控制器的设计9 语音信箱控制系统的设计语音信箱控制系统的设计10 PID控制器的设计控制器的设计11 空调系统有限状态自动机的设计空调系统有限状态自动机的设计12 闹钟系统的设计闹钟系统的设计 VHDL设计应用实例1 8位加法器的设计位加法器的设计 1设计思路设计思路 加法器是数字系统中的基本逻辑器件,减法器和硬件乘法器都可由加法器来构成。多位加法器的构成有两种方式:并行进位和串行进位方式。并行进位加法器设有进位产生逻辑,运算速度较快;串行进位方式是将全加器级联构成多位加法器。并行进位加法器通常比串行级联加法器占用更多的资源。随着位数的增加,相同位数的并行加法器与串行加法器的资源占用差距也越来越大。因此,在工程中使用加法器时,要在速度和容量之间寻找平衡点。VHDL设计应用实例 实践证明,4位二进制并行加法器和串行级联加法器占用几乎相同的资源。这样,多位加法器由4位二进制并行加法器级联构成是较好的折中选择。本设计中的8位二进制并行加法器即是由两个4位二进制并行加法器级联而成的,其电路原理图如图所示。VHDL设计应用实例图6.1 8位加法器电路原理图VHDL设计应用实例2VHDL源程序源程序1) 4位二进制并行加法器的源程序LIBRARY IEEE;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); CONTCIN,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硬件逻辑验证硬件逻辑验证 选择实验电路结构图,由的实验电路结构图和图确定引脚的锁定。如可取实验电路结构图的PIO3PIO0接A3.0,PIO7PIO4接A7.4, PIO11PIO8接B3.0,PIO15PIO12接B7.4,PIO49接CIN。此加法器的被加数A和加数B分别由键2与键1、键4与键3输入,加法器的最低位进位CIN由键8输入,计算结果将分别通过PIO23PIO20,PIO19PIO16输出并显示于数码管6(高4位)和数码管5(低4位),溢出进位由PIO39输出,当有进位时,结果显示于发光管D8。VHDL设计应用实例2 8位乘法器的设计位乘法器的设计 1设计思路设计思路 纯组合逻辑构成的乘法器虽然工作速度比较快,但占用硬件资源多,难以实现宽位乘法器,而基于PLD器件外接ROM九九表的乘法器则无法构成单片系统,也不实用。这里介绍由8位加法器构成的以时序逻辑方式设计的8位乘法器,此乘法器具有一定的实用价值。其乘法原理是:乘法通过逐项位移相加原理来实现,从被乘数的最低位开始,若为1,则乘数左移后与上一次和相加;若为0,左移后以全零相加,直至被乘数的最高位。从图的逻辑图上可以清楚地看出此乘法器的工作原理。VHDL设计应用实例图6.2 88位乘法器电路原理图VHDL设计应用实例 图中,ARICTL是乘法运算控制电路,它的START(可锁定于引脚I/O 49)信号的上跳沿与高电平有两个功能,即16位寄存器清零和被乘数A7.0向移位寄存器SREG8B加载;它的低电平则作为乘法使能信号。乘法时钟信号从ARICTL的CLK输入。当被乘数加载于8位右移寄存器SREG8B后,随着每一时钟节拍,最低位在前,由低位至高位逐位移出。当为1时,与门ANDARITH打开,8位乘数B7.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) 选通与门模块的源程序LIBRARY IEEE;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位锁存器的源程序LIBRARY IEEE;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 CLKEVENT 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位右移寄存器的源程序LIBRARY IEEE; -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 CLKEVENT 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;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);BEGINVHDL设计应用实例 RSTALL=START; PROCESS (CLK,START) BEGIN IF START = 1 THEN CNT4B= 0000; -高电平清零计数器 ELSIF CLKEVENT AND CLK = 1 THEN IF CNT4B8 THEN-小于则计数,等于8表明乘法运算已经结束 CNT4B=CNT4B+1; END IF; END IF;END PROCESS;PROCESS (CLK,CNT4B,START)BEGINVHDL设计应用实例 IF START = 0 THEN IF CNT4B8 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位乘法器的源程序LIBRARY IEEE; -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);BEGINVHDL设计应用实例DOUT=DTBOUT;GNDINTCLK, 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. 硬件逻辑验证硬件逻辑验证 选择实验电路结构图,由节的实验电路结构图和图确定引脚的锁定。如乘法运算时钟CLK接CLOCK0,清零及启动运算信号START由键8 (PIO49)控制,乘数B7.0接PIO7PIO0(由键2,键1输入8位二进制数),被乘数A7.0接PIO15PIO8(由键4,键3输入8位二进制数),乘积输出DOUT15.0接PIO31PIO16,乘法运算结束信号ARIEND接PIO39(D8)。VHDL设计应用实例 进行硬件验证时方法如下: 键2和键1分别输入乘数的高4位和低4位(输入值显示于数码2和数码1); 键4和键3分别输入被乘数的高4位和低4位(输入值显示于数码4和数码3); 乘法操作时钟信号输入接CLOCK0; 键8输入高电平时,乘积锁存器清零,乘数和被乘数数值加载,低电平时开始作乘法,8个脉冲后乘法结束,乘积显示于数码管85,高位在左。 VHDL设计应用实例3 序列检测器的设计序列检测器的设计 1设计思路设计思路 序列检测器可用于检测一组或多组由二进制码组成的脉冲序列信号,这在数字通信领域有广泛的应用。当序列检测器连续收到一组串行二进制码后,如果这组码与检测器中预先设置的码相同,则输出1,否则输出0。由于这种检测的关键在于正确码的收到必须是连续的,这就要求检测器必须记住前一次的正确码及正确序列,直到在连续的检测中所收到的每一位码都与预置数的对应码相同。在检测过程中,任何一位不相等都将回到初始状态重新开始检测。如图所示,当一串待检测的串行数据进入检测器后,若此数在每一位的连续检测中都与预置的密码数相同,则输出“A”,否则仍然输出“B”。 VHDL设计应用实例图6.3 8位序列检测器逻辑图VHDL设计应用实例2VHDL源程序源程序LIBRARY IEEE;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 IF DIN =D(7) THEN Q= 1 ;ELSE Q IF DIN =D(6) THEN Q= 2 ;ELSE Q IF DIN =D(5) THEN Q= 3 ;ELSE Q IF DIN =D(4) THEN Q= 4 ;ELSE Q IF DIN =D(3) THEN Q= 5 ;ELSE Q IF DIN =D(2) THEN Q= 6 ;ELSE Q IF DIN =D(1) THEN Q= 7 ;ELSE Q IF DIN =D(0) THEN Q= 8 ;ELSE Q 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硬件逻辑验证硬件逻辑验证 选择实验电路结构图,由节的实验电路结构图和图确定引脚的锁定。待检测串行序列数输入DIN接PIO10(左移,最高位在前),清零信号CLR接PIO8,工作时钟CLK接PIO9,预置位密码D7.0接PIO7PIO0,指示输出AB3.0接PIO39PIO36(显示于数码管6)。VHDL设计应用实例 进行硬件验证时方法如下: 选择实验电路结构图,按实验板“系统复位”键; 用键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,则可构成计数初始值自加载方式的加法计数器,从而构成数控分频器。图中D触发器的一个重要功能就是均匀输出信号的占空比,提高驱动能力,这对驱动,诸如扬声器或电动机十分重要。VHDL设计应用实例2VHDL源程序源程序1) 8位可自加载加法计数器的源程序LIBRARY IEEE;,.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 CLKEVENT 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 CAOCLK,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. 硬件逻辑验证硬件逻辑验证 选择实验电路结构图,由节的实验电路结构图和图确定引脚的锁定。输入时钟CLK接CLOCK0(用于发声时,接频率65536 Hz);8位数控预置输入B7.0接PIO15PIO8,由键4和键3控制输入,输入值分别显示于数码管4和数码管3;另8位数控预置输入A7.0接PIO7PIO0,由键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. 设计思路设计思路 图是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秒钟的计数操作作准备。测频控制信号发生器的工作时序如图所示。为了产生这个时序图,需首先建立一个由D触发器构成的二分频器,在每次时钟CLK上沿到来时其值翻转。VHDL设计应用实例 其中控制信号时钟CLK的频率取1 Hz,而信号TSTEN的脉宽恰好为1 s,可以用作闸门信号。此时,根据测频的时序要求,可得出信号LOAD和CLR_CNT的逻辑描述。由图可见,在计数完成后,即计数使能信号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的设计 如图所示,此十进制计数器的特殊之处是,有一时钟使能输入端ENA,用于锁定计数值。当高电平时计数允许,低电平时禁止计数。VHDL设计应用实例2. VHDL源程序源程序1) 有时钟使能的十进制计数器的源程序LIBRARY IEEE; -有时钟使能的十进制计数器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 CLKEVENT AND CLK= 1 THEN IF ENA= 1 THEN IF CQI9 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位锁存器的源程序LIBRARY IEEE; -32位锁存器;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; -测频控制信号发生器ENTITY 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; BEGINVHDL设计应用实例PROCESS ( CLK )BEGINIF CLKEVENT 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; TSTENCLK,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. 硬件逻辑验证硬件逻辑验证 选择实验电路结构图,由节的实验电路结构图和图确定引脚的锁定,测频控制器时钟信号CLK(1 Hz)可接CLOCK1,待测频FSIN可接CLOCK0,8位数码显示输出DOUT31.0接PIO47PIO16。 进行硬件验证时方法如下:选择实验模式0,测频控制器时钟信号CLK与CLOCK1信号组中的1 Hz信号相接,待测频FSIN与CLOCK0信号组中的某个信号相接,数码管应显示来自CLOCK0的频率。VHDL设计应用实例6 秒秒 表表 的的 设设 计计 1设计思路设计思路 今需设计一个计时范围为秒1小时的秒表,首先需要获得一个比较精确的计时基准信号,这里是周期为1/100 s的计时脉冲。其次,除了对每一计数器需设置清零信号输入外,还需在6个计数器设置时钟使能信号,即计时允许信号,以便作为秒表的计时起停控制开关。因此秒表可由1个分频器、4个十进制计数器 (1/100秒、1/10秒、1秒、1分)以及2个六进制计数器(10秒、10分)组成,如图所示。6个计数器中的每一计数器的4位输出,通过外设的BCD译码器输出显示。图中6个4位二进制计数输出的最小显示值分别为:DOUT3.01/100秒、DOUT7.41/10秒、DOUT11.81秒、DOUT15.1210秒、DOUT19.161分、DOUT23.2010分。VHDL设计应用实例图6.7 秒表电路逻辑图VHDL设计应用实例2. VHDL源程序源程序1) 3 MHz100 Hz分频器的源程序LIBRARY IEEE;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 CLKEVENT 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(十进制计数器的源程序与此类似)LIBRARY IEEE;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 CLKEVENT 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; CQCLK,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. 硬件逻辑验证硬件逻辑验证 选择实验电路结构图,由节的实验电路结构图和图确定引脚的锁定。时钟信号CLK可接CLOCK0,计数清零信号接键1,计数使能信号接键2,数码管16分别显示以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口线。如图,如果将图中的译码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口将图中锁存器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单片机读写电路;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位地址锁存进程 BEGINVHDL设计应用实例IF ALEEVENT 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 ) -数据写入寄存器1VHDL设计应用实例BEGINIF WR_ENABLE1EVENT 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 ) -数据写入寄存器2BEGINVHDL设计应用实例IF WR_ENABLE2EVENT 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 LATCH1EVENT 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; DATOUT2MR=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 STATEMR= 0;MY= 1;MG= 0; BR= 1;BY= 0;BG= 0;VHDL设计应用实例 IF S=3 THEN STATE =C;CLR:=0;EN:=0; ELSE STATEMR= 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 STATEMR= 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. 硬件逻辑验证硬件逻辑验证 选择实验电路结构图,由节的实验电路结构图和图确定引脚的锁定。时钟脉冲CLK可接CLOCK0(1 Hz),主干道和支干道来车信号分别接键7和键8,主干道和支干道红、黄、绿灯驱动信号MR、MY、MG和BR、BY、BG分别接D1D3和D8D6。 进行硬件验证时方法如下:选择实验模式1,时钟脉冲与CLOCK0信号组中的1 Hz信号相接,在键7和键8施加相应的信号,发光二极管D1D3、D8D6则按控制要求显示相应的信号。VHDL设计应用实例9 语音信箱控制系统的设计语音信箱控制系统的设计 1设计思路设计思路 语音信箱控制系统用于控制对语音信箱的有关操作,允许用户发送信息、重阅信息、存储信息和擦除信息,状态转移图如图所示。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;,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 -看信箱 IF ( KEY=1) THENVHDL设计应用实例 NEXT_STATE=REVIEW_ST; -转到重阅 ELSIF (KEY =2) THEN NEXT_STATE=SEND_ST ; 转到发送 ELSE NEXT_STATE -重阅 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 = #) THENVHDL设计应用实例 NEXT_STATE =MAIN_ST;ELSE NEXT_STATE -重复 PLAY= 1; NEXT_STATE -存信息 SAVE= 1; NEXT_STATE -擦掉 ERASE= 1; NEXT_STATE -发送 NEXT_STATE -寻址 ADDRESS= 1; IF (KEY=#)THEN NEXT_STATE -记录 IF (KEY=5) THEN NEXT_STATE=BEGIN_REC_ST; ELSEVHDL设计应用实例 NEXT_STATE -开始录音 RECORD= 1; NEXT_STATE -记录录音 RECORD= 1; IF (KEY=#)THEN NEXT_STATE=SEND_ST; 发送到信箱 ELSE NEXT_STATE=MESSAGE_ST;VHDL设计应用实例 END IF;END CASE;END PROCESS;PROCESSBEGINWAIT UNTIL (CLKEVENT 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) + KiEkdt + KddEk/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)以及Kdd Ek /dt线性相加得到控制电流值。然后,在下一个时钟周期将该控制电流值输出到主机。VHDL设计应用实例4VHDL源程序源程序LIBRARY WORK;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_FPUVHDL设计应用实例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;- 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) ISVHDL设计应用实例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的输出值。其原理方框图如图所示。VHDL设计应用实例图6.13 空调有限状态自动机原理方框图VHDL设计应用实例2VHDL源程序源程序LIBRARY IEEE;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 DLSVHDL设计应用实例 IF (TEMP_LOW=1) THEN STVAR=TOO_COLD; ELSIF (TEMP_HIGH=1) THEN STVAR=TOO_HOT; ELSE STVARHEAT=0;COOLHEAT=1;COOLHEAT=0;COOL=1; END CASE; END PROCESS CONTROLLER1;END ART;VHDL设计应用实例12 闹钟系统的设计闹钟系统的设计6.12.1 闹钟系统的设计要求及设计思路闹钟系统的设计要求及设计思路 要求设计一个带闹钟功能的24小时计时器,计时器的外观如图所示。它包括以下几个组成部分: 显示屏,由4个七段数码管组成,用于显示当前时间(时:分)或设置的闹钟时间; 数字键09,用于输入新的时间或新的闹钟时间; TIME(时间)键,用于确定新的时间设置; ALARM(闹钟)键,用于确定新的闹钟时间设置,或显示已设置的闹钟时间; 扬声器,在当前时钟时间与闹钟时间相同时,发出蜂鸣声。VHDL设计应用实例图6.14 计时器外观VHDL设计应用实例 该计时器设计要求完成如下功能: (1) 计时功能:这是本计时器设计的基本功能,每隔一分钟计时一次,并在显示屏上显示当前时间。 (2) 闹钟功能:如果当前时间与设置的闹钟时间相同,则扬声器发出蜂鸣声。 (3) 设置新的计时器时间:用户用数字键09输入新的时间,然后按 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,其外部端口如图所示。各端口的作用如下: (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设计应用实例 表中没有显式说明的控制信号赋值,表示信号的值为零。例如在状态S0,当信号KEY =1时,SHOW_NEW_TIME信号的赋值为1,而其他信号LOAD_NEW_A,LOAD_NEW_C和SHOW_A的值此时都赋为0。另外,表中关于“超时”判断处理的处理细节见VHDL源程序中的有关部分。VHDL设计应用实例2VHDL源程序源程序LIBRARY IEEE;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; BEGINVHDL设计应用实例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 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 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 IF (ALARM_BUTTON = 1) THEN NEXT_STATE = S2; LOAD_NEW_A = 1; ELSE NEXT_STATE IF (TIME_BUTTON = 1) THEN NEXT_STATE = S3; LOAD_NEW_C = 1; ELSE NEXT_STATE 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 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 = 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 = 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个数字之一,如图所示。其中KEYPAD为输入端口,接收10位二进制数据信号;VALUE为输出端口,输出相应的1位十进制整数信号。输入数据与输出数据的译码关系见表。VHDL设计应用实例图6.16 电路系统示意图 VHDL设计应用实例表表6.2 输入、输出数据的译码关系输入、输出数据的译码关系VHDL设计应用实例2VHDL源程序源程序LIBRARY IEEE;ENTITY DECODER IS PORT(KEYPAD :IN STD_LOGIC_VECTOR(9 DOWNTO 0); VALUE :OUT T_DIGITAL);END DECODER;ARCHITECTURE ART OF DECODER ISBEGINVHDL设计应用实例 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端口输出信号进行异步清零复位。电路系统示意图如图所示。VHDL设计应用实例图6.17 移位寄存器电路示意图VHDL设计应用实例2VHDL源程序源程序LIBRARY IEEE;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; BEGINVHDL设计应用实例 SHIFT:PROCESS(RESET,CLK) BEGIN IF (RESET = 1) THEN N_T = (0,0,0,0); ELSIF (CLKEVENT 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 端口的输出进行异步的清零复位。图是闹钟寄存器模块的示意图。 闹钟系统的闹钟时间由闹钟寄存器保存和传递,而当前时间由时间计数器保存、传递并按分钟累加推进。这两个组件的功能和设计描述比较相似,它们之间的区别主要在于自动累加功能的有无和控制信号的优先作用次序。VHDL设计应用实例图6.18 闹钟寄存器示意图VHDL设计应用实例 时间计数器模块的功能是当RESET端口输入信号为高电平时,对CURRENT _TIME端口输出信号清零复位;当LOAD _NEW _C端口输入信号为高电平时,将NEW_CURRENT_TIME端口的输入信号输出给CURRENT_TIME端口。RESET端口D的控制优先于LOAD _NEW _C端口。当这两个控制信号都无效时,在时钟上升沿同步下,对CURRENT _TIME端口输出信号累加1,并根据小时、分钟的规律处理进位。图是时间计数器模块的示意图。VHDL设计应用实例图6.19 时间计数器模块的示意图VHDL设计应用实例2VHDL源程序源程序-时间计数器的源程序LIBRARY IEEE;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) THENVHDL设计应用实例 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;-闹钟寄存器的源程序LIBRARY IEEE;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端口的输出信号有效(高电平),反之无效。图为显示驱动器示意图。VHDL设计应用实例图6.20 显示驱动器示意图VHDL设计应用实例2VHDL源程序源程序LIBRARY IEEE;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_TIMERANGE 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_TIMERANGE 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端口输出信号清零。图为分频器示意图。 VHDL设计应用实例图6.21 分频器示意图VHDL设计应用实例2VHDL源程序源程序LIBRARY IEEE;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 ISVHDL设计应用实例 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,其外部端口如图所示。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 时,扬声器发出蜂鸣,表示到了设定的闹钟时间。 设计的总体结构图如图所示。 VHDL设计应用实例图6.23 总体结构VHDL设计应用实例 下面再简要说明各组成部分的功能: (1) 译码器(DECODER) 可将KEYPAD信号转换为09的整型数,以直观地表示和处理用户输入的数字。 (2) 键盘缓冲器(KEY_BUFFER)是一个移位寄存器,暂存用户键入的数字,并且实现用户键入数字在显示器上从右到左的依次显示。这里需要注意的是,由图可以看出,KEY_BUFFER的时钟端连接的是外部KEY_DOWN 信号。这表示用户每输入一个数字,KEY_BUFFER移位一次。VHDL设计应用实例 (3) 分频器(FQ_DIVIDER)将较高速的外部时钟频率分频成每分钟一次的时钟频率,以便进行时钟计数。 (4) 计数器(ALARM_COUNTER)实际上是一个异步复位、异步置数的累加器,通常情况下进行时钟累加计数,必要时可置入新的时钟值,然后从该值开始新的计数。 (5) 寄存器(ALARM_REG)用于保存用户设置的闹钟时间,是一个异步复位寄存器。VHDL设计应用实例 (6) 显示器(DISPLAY_DRIVER)根据需要显示当前时间、用户设置的闹钟时间或用户通过键盘输入的新的时间,同时判断当前时间是否已到了闹钟时间,实际上是一个多路选择器加比较器。 (7) 控制器(ALARM_CONTROLLER)是设计的核心部分,按设计要求产生相应的控制逻辑,以控制其他各部分的工作。VHDL设计应用实例2VHDL源程序源程序LIBRARY IEEE;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实验开发系统进行硬件验证,考虑到实验开发系统提供的输入信号按键的有限,可将输入数字按键09改为一个按键,该按键的信号作为一个8421码信号发生器的输入,由8421码信号发生器输出数字09。具体验证方案由读者自行完成。
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号