资源描述
VHDL设计应用实例,1 8位加法器的设计 2 8位乘法器的设计 3 序列检测器的设计 4 正负脉宽数控调制信号发生器的设计 5 数字频率计的设计 6 秒表的设计 7 MCS51单片机与FPGA/CPLD总线接口逻辑设计 8 交通灯信号控制器的设计 9 语音信箱控制系统的设计 10 PID控制器的设计 11 空调系统有限状态自动机的设计 12 闹钟系统的设计,1 8位加法器的设计,1设计思路 加法器是数字系统中的基本逻辑器件,减法器和硬件乘法器都可由加法器来构成。多位加法器的构成有两种方式:并行进位和串行进位方式。并行进位加法器设有进位产生逻辑,运算速度较快;串行进位方式是将全加器级联构成多位加法器。并行进位加法器通常比串行级联加法器占用更多的资源。随着位数的增加,相同位数的并行加法器与串行加法器的资源占用差距也越来越大。因此,在工程中使用加法器时,要在速度和容量之间寻找平衡点。,实践证明,4位二进制并行加法器和串行级联加法器占用几乎相同的资源。这样,多位加法器由4位二进制并行加法器级联构成是较好的折中选择。本设计中的8位二进制并行加法器即是由两个4位二进制并行加法器级联而成的,其电路原理图如图6.1所示。,图6.1 8位加法器电路原理图,2VHDL源程序 1) 4位二进制并行加法器的源程序ADDER4B.VHD LIBRARY 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); -进位输出,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;,2) 8位二进制加法器的源程序ADDER8B.VHD LIBRARY 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,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,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;,3硬件逻辑验证 选择实验电路结构图NO.1,由5.2的实验电路结构图NO.1和图6.1确定引脚的锁定。如可取实验电路结构图的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。,2 8位乘法器的设计,1设计思路 纯组合逻辑构成的乘法器虽然工作速度比较快,但占用硬件资源多,难以实现宽位乘法器,而基于PLD器件外接ROM九九表的乘法器则无法构成单片系统,也不实用。这里介绍由8位加法器构成的以时序逻辑方式设计的8位乘法器,此乘法器具有一定的实用价值。其乘法原理是:乘法通过逐项位移相加原理来实现,从被乘数的最低位开始,若为1,则乘数左移后与上一次和相加;若为0,左移后以全零相加,直至被乘数的最高位。从图6.2的逻辑图上可以清楚地看出此乘法器的工作原理。,图6.2 88位乘法器电路原理图,图6.2中,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的输出值即为最后乘积。,此乘法器的优点是节省芯片资源,它的核心元件只是一个8位加法器,其运算速度取决于输入的时钟频率。若时钟频率为100 MHz,则每一运算周期仅需80 ns。而若利用备用最高时钟,即12 MHz晶振的MCS-51单片机的乘法指令,进行8位乘法运算,仅单指令的运算周期就长达4 s。因此,可以利用此乘法器或相同原理构成的更高位乘法器完成一些数字信号处理方面的运算。,2. VHDL源程序 1) 选通与门模块的源程序ANDARITH.VHD LIBRARY 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,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;,2) 16位锁存器的源程序REG16B.VHD LIBRARY 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位寄存器设置,BEGIN PROCESS (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;,3) 8位右移寄存器的源程序SREG8B.VHD LIBRARY 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),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;,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,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) BEGIN,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;,5) 8位乘法器的源程序MULTI8X8.VHD LIBRARY 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;,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位加法器端口定义 ,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,DOUTCLK, 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;,3. 硬件逻辑验证 选择实验电路结构图NO.1,由5.2节的实验电路结构图NO.1和图6.2确定引脚的锁定。如乘法运算时钟CLK接CLOCK0,清零及启动运算信号START由键8 (PIO49)控制,乘数B7.0接PIO7PIO0(由键2,键1输入8位二进制数),被乘数A7.0接PIO15PIO8(由键4,键3输入8位二进制数),乘积输出DOUT15.0接PIO31PIO16,乘法运算结束信号ARIEND接PIO39(D8)。,进行硬件验证时方法如下: 键2和键1分别输入乘数的高4位和低4位(输入值显示于数码2和数码1); 键4和键3分别输入被乘数的高4位和低4位(输入值显示于数码4和数码3); 乘法操作时钟信号输入接CLOCK0; 键8输入高电平时,乘积锁存器清零,乘数和被乘数数值加载,低电平时开始作乘法,8个脉冲后乘法结束,乘积显示于数码管85,高位在左。,3 序列检测器的设计,1设计思路 序列检测器可用于检测一组或多组由二进制码组成的脉冲序列信号,这在数字通信领域有广泛的应用。当序列检测器连续收到一组串行二进制码后,如果这组码与检测器中预先设置的码相同,则输出1,否则输出0。由于这种检测的关键在于正确码的收到必须是连续的,这就要求检测器必须记住前一次的正确码及正确序列,直到在连续的检测中所收到的每一位码都与预置数的对应码相同。在检测过程中,任何一位不相等都将回到初始状态重新开始检测。如图6.3所示,当一串待检测的串行数据进入检测器后,若此数在每一位的连续检测中都与预置的密码数相同,则输出“A”,否则仍然输出“B”。,图6.3 8位序列检测器逻辑图,2VHDL源程序 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,SIGNAL Q :INTEGER RANGE 0 TO 8; BEGIN PROCESS ( CLK,CLR ) BEGIN IF CLR= 1 THEN Q IF DIN =D(7) THEN Q IF DIN =D(6) THEN Q IF DIN =D(5) THEN Q= 3 ;ELSE Q=0;END IF;,WHEN 3= IF DIN =D(4) THEN Q IF DIN =D(3) THEN Q IF DIN =D(2) THEN Q IF DIN =D(1) THEN Q IF DIN =D(0) THEN Q Q=0; END IF ;,END PROCESS; PROCESS(Q) -检测结果判断输出 BEGIN IF Q= 8 THEN AB= 1010; -序列数检测正确,输出“A” ELSE AB= 1011; -序列数检测错误,输出 “B” END IF ; END PROCESS; END ART;,3硬件逻辑验证 选择实验电路结构图NO.8,由5.2节的实验电路结构图NO.8和图6.3确定引脚的锁定。待检测串行序列数输入DIN接PIO10(左移,最高位在前),清零信号CLR接PIO8,工作时钟CLK接PIO9,预置位密码D7.0接PIO7PIO0,指示输出AB3.0接PIO39PIO36(显示于数码管6)。,进行硬件验证时方法如下: 选择实验电路结构图NO.8,按实验板“系统复位”键; 用键2和键1输入两位十六进制待测序列数; 利用键4和键3输入两位十六进制预置码; 按键8,高电平初始化清零,低电平清零结束(平时数码6应显“B”); 按键6(CLK)8次,这时若串行输入的8位二进制序列码与预置码相同,则数码7应从原来的“B”变成“A”,表示序列检测正确,否则仍为“B”。,4 正负脉宽数控调制信号发生器的设计,1设计思路 图6.4 是脉宽数控调制信号发生器逻辑图,此信号发生器是由两个完全相同的可自加载加法计数LCNT8组成的,它的输出信号的高低电平脉宽可分别由两组8位预置数进行控制。,图6.4 脉宽数控调制信号发生器逻辑图,如果将初始值可预置的加法计数器的溢出信号作为本计数器的初始预置加载信号LD,则可构成计数初始值自加载方式的加法计数器,从而构成数控分频器。图6.4中D触发器的一个重要功能就是均匀输出信号的占空比,提高驱动能力,这对驱动,诸如扬声器或电动机十分重要。,2VHDL源程序 1) 8位可自加载加法计数器的源程序LCNT8.VHD LIBRARY 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 ),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 CAO= 0; END IF; END PROCESS; END ART;,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,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);,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;,3. 硬件逻辑验证 选择实验电路结构图NO.1,由5.2节的实验电路结构图NO.1和图6.4确定引脚的锁定。输入时钟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)。,进行硬件验证时方法如下:通过键2和键1输入控制高电平信号脉宽的预置数(显示于数码管2和1);由键4和键3输入控制低电平信号脉宽的预置数(显示于数码管4和3);取待分频率F=12 MHz、6 MHz或3 MHz,通过短路帽输入CLK9;频率输出可利用示波器观察波形随预置数的变化而变化的情况。在没有示波器时,“CLK”可接低频率信号,然后接通扬声器,通过声音音调的变化来了解输出频率的变化。,5 数字频率计的设计,1. 设计思路 图6.5是8位十进制数字频率计的电路逻辑图,它由一个测频控制信号发生器TESTCTL、8个有时钟使能的十进制计数器CNT10、一个32位锁存器REG32B组成。以下分别叙述频率计各逻辑模块的功能与设计方法。,图6.5 8位十进制数字频率计逻辑图,1) 测频控制信号发生器设计 频率测量的基本原理是计算每秒钟内待测信号的脉冲个数。这就要求TESTCTL的计数使能信号TSTEN能产生一个1秒脉宽的周期信号,并对频率计的每一计数器CNT10的ENA使能端进行同步控制。当TSTEN高电平时,允许计数;低电平时,停止计数,并保持其所计的数。在停止计数期间,首先需要一个锁存信号LOAD的上跳沿将计数器在前1秒钟的计数值锁存进32位锁存器REG32B中,并由外部的7段译码器译出并稳定显示。锁存信号之后,必须有一清零信号CLR_CNT对计数器进行清零,为下1秒钟的计数操作作准备。测频控制信号发生器的工作时序如图6.6所示。为了产生这个时序图,需首先建立一个由D触发器构成的二分频器,在每次时钟CLK上沿到来时其值翻转。,其中控制信号时钟CLK的频率取1 Hz,而信号TSTEN的脉宽恰好为1 s,可以用作闸门信号。此时,根据测频的时序要求,可得出信号LOAD和CLR_CNT的逻辑描述。由图6.6可见,在计数完成后,即计数使能信号TSTEN在1 s的高电平后,利用其反相值的上跳沿产生一个锁存信号LOAD,0.5 s后,CLR_CNT产生一个清零信号上跳沿。 高质量的测频控制信号发生器的设计十分重要,设计中要对其进行仔细的实时仿真(TIMING SIMULATION),防止可能产生的毛刺。,图6.6 测频控制信号发生器工作时序,2) 寄存器REG32B设计 设置锁存器的好处是,显示的数据稳定,不会由于周期性的清零信号而不断闪烁。若已有32位BCD码存在于此模块的输入口,在信号LOAD的上升沿后即被锁存到寄存器REG32B的内部,并由REG32B的输出端输出,然后由实验板上的7段译码器译成能在数码管上显示输出的相对应的数值。,3) 十进制计数器CNT10的设计 如图6.5所示,此十进制计数器的特殊之处是,有一时钟使能输入端ENA,用于锁定计数值。当高电平时计数允许,低电平时禁止计数。,2. VHDL源程序 1) 有时钟使能的十进制计数器的源程序CNT10.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; -有时钟使能的十进制计数器 ENTITY CNT10 IS PORT (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,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;,2) 32位锁存器的源程序REG32B.VHD LIBRARY 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 BEGIN PROCESS ( LOAD, DIN ) BEGIN IF LOAD EVENT AND LOAD= 1 THEN DOUT=DIN; -锁存输入数据 END IF ; END PROCESS; END ART;,3) 测频控制信号发生器的源程序TESTCTL.VHD LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; -测频控制信号发生器 USE IEEE.STD_LOGIC_UNSIGNED.ALL 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; BEGIN,PROCESS ( CLK ) BEGIN IF 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; TSTEN=Div2CLK; END ART;,4) 数字频率计的源程序FREQ.VHD LIBRARY 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 IS 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 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);,BEGIN U0: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,,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;,3. 硬件逻辑验证 选择实验电路结构图NO.0,由5.2节的实验电路结构图NO.0和图6.5确定引脚的锁定,测频控制器时钟信号CLK(1 Hz)可接CLOCK1,待测频FSIN可接CLOCK0,8位数码显示输出DOUT31.0接PIO47PIO16。 进行硬件验证时方法如下:选择实验模式0,测频控制器时钟信号CLK与CLOCK1信号组中的1 Hz信号相接,待测频FSIN与CLOCK0信号组中的某个信号相接,数码管应显示来自CLOCK0的频率。,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位二进制计数输出的最小显示值分别为:DOUT3.01/100秒、DOUT7.41/10秒、DOUT11.81秒、DOUT15.1210秒、DOUT19.161分、DOUT23.2010分。,图6.7 秒表电路逻辑图,2. VHDL源程序 1) 3 MHz100 Hz分频器的源程序CLKGEN.VHD LIBRARY 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,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;,2) 六进制计数器的源程序CNT6.VHD(十进制计数器的源程序CNT10.VHD与此类似) LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY CNT6 IS PORT (CLK:IN STD_LOGIC; CLR:IN STD_LOGIC; ENA: IN STD_LOGIC; CQ:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);,CARRY_OUT: OUT STD_LOGIC ); END CNT6; ARCHITECTURE ART OF CNT6 IS SIGNAL CQI:STD_LOGIC_VECTOR(3 DOWNTO 0); BEGIN PROCESS(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”;,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;,3) 秒表的源程序TIMES.VHD LIBRARY 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);,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;,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);,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;,3. 硬件逻辑验证 选择实验电路结构图NO.0,由5.2节的实验电路结构图NO.0和图6.7确定引脚的锁定。时钟信号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个数码管上。,7 MCS-51单片机与FPGA/CPLD总线接口逻辑设计,单片机具有性能价格比高、功能灵活、易于人机对话和良好的数据处理能力等特点;PLD则具有高速、高可靠以及开发便捷规范等方面的优点,以此两类器件相结合的电路结构在许多高性能仪器仪表和电子产品中将被广泛应用。单片机与CPLD的接口方式一般有两种,即总线方式与独立方式。 单片机以总线方式与FPGA/CPLD进行数据与控制信息通信有许多优点:,(1) 速度快。其通信工作时序是纯硬件行为,对于MCS-51单片机,只需一条单字节指令就能完成所需的读/写时序,如:MOV DPTR,A;MOV A,DPTR。 (2) 节省PLD芯片的I/O口线。如图6.9,如果将图中的译码DECODER设置足够的译码输出,以及安排足够的锁存器,就能仅通过19根I/O口线在FPGA/CPLD与单片机之间进行各种类型的数据与控制信息交换。 (3) 相对于非总线方式,单片机的编程简捷,控制可靠。,(4) 在FPGA/CPLD中通过逻辑切换,单片机易于与SRAM或ROM接口。这种方式有许多实用之处,如利用类似于微处理器DMA的工作方法,首先由FPGA/CPLD与接口的高速A/D等器件进行高速数据采样,并将数据暂存于SRAM中,采样结束后,通过切换,使单片机与SRAM以总线方式进行数据通信,以便发挥单片机强大的数据处理能力。,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位地址锁存于地址锁存器。,若需从“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的数据写入图中相关的锁存器。,图6.8 MCS-51单片机总线接口方式工作时序,图6.9 CPLD/FPGA与MCS-51单片机的总线接口通信逻辑图,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; -读回信号锁存,DATOUT1:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);-锁存输出数据1 DATOU
展开阅读全文