第 6章 VHDL设计应用实例第 6章 VHDL设计应用实例
6.1 8位加法器的设计
6.2 8位乘法器的设计
6.3 序列检测器的设计
6.4 正负脉宽数控调制信号发生器的设计
6.5 数字频率计的设计
6.6 秒表的设计
6.7 MCS–51单片机与 FPGA/CPLD总线接口逻辑设计
6.8 交通灯信号控制器的设计
6.9 语音信箱控制系统的设计
6.10 PID控制器的设计
6.11 空调系统有限状态自动机的设计
6.12 闹钟系统的设计第 6章 VHDL设计应用实例
6.1 8位加法器的设计
1.设计思路加法器是数字系统中的基本逻辑器件,减法器和硬件乘法器都可由加法器来构成。多位加法器的构成有两种方式:并行进位和串行进位方式。并行进位加法器设有进位产生逻辑,运算速度较快;串行进位方式是将全加器级联构成多位加法器。
并行进位加法器通常比串行级联加法器占用更多的资源。随着位数的增加,相同位数的并行加法器与串行加法器的资源占用差距也越来越大。因此,在工程中使用加法器时,要在速度和容量之间寻找平衡点。
第 6章 VHDL设计应用实例实践证明,4位二进制并行加法器和串行级联加法器占用几乎相同的资源。这样,多位加法器由 4位二进制并行加法器级联构成是较好的折中选择。本设计中的 8位二进制并行加法器即是由两个 4位二进制并行加法器级联而成的,其电路原理图如图 6.1所示。
第 6章 VHDL设计应用实例图 6.1 8位加法器电路原理图第 6章 VHDL设计应用实例
2,VHDL源程序
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); --进位输出第 6章 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;
第 6章 VHDL设计应用实例
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
第 6章 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
第 6章 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;
第 6章 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。
第 6章 VHDL设计应用实例
6.2 8位乘法器的设计
1.设计思路纯组合逻辑构成的乘法器虽然工作速度比较快,但占用硬件资源多,难以实现宽位乘法器,而基于 PLD器件外接 ROM九九表的乘法器则无法构成单片系统,也不实用。这里介绍由 8位加法器构成的以时序逻辑方式设计的 8位乘法器,此乘法器具有一定的实用价值。其乘法原理是:乘法通过逐项位移相加原理来实现,
从被乘数的最低位开始,若为 1,则乘数左移后与上一次和相加;
若为 0,左移后以全零相加,直至被乘数的最高位。从图 6.2的逻辑图上可以清楚地看出此乘法器的工作原理。
第 6章 VHDL设计应用实例图 6.2 8× 8位乘法器电路原理图
S 7 [ 7,,0 ]
S 6 [ 7,,0 ]
S 6 ( 8 )
A R I E N D
R E G 1 6 B
A D D E R 8 B
A R I C T L
S R E G 8 B
A N D A R I T H
O U T [ 1 5,,0 ]
B [ 7,,0 ]
A [ 7,,0 ]
S T A R T
C L K
Q [ 1 5,,0 ]
D [ 8,,0 ]
C L R
C L K
G N D
S 5 [ 7,,0 ]
S 6 [ 8,,0 ]
R S T A L L
C L K O U T
S 5 [ 7,,0 ]
S 7 [ 1 5,,8 ]
B [ 7,,0 ]
A [ 7,,0 ] C O U T
S [ 7,,0 ]
C I N
D O U T [ 7,,0 ]
D I N [ 7,,0 ]
A B I N
QB
D I N [ 7,,0 ]
L O A D
C L K
A R I E N DC L K
S T A R T
U1
U2
U3
U4
U5
S2
S3
S4
S 7 [ 1 5,,0 ]
S 7 [ 1 5,,8 ]
S1
第 6章 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的输出值即为最后乘积。
第 6章 VHDL设计应用实例此乘法器的优点是节省芯片资源,它的核心元件只是一个 8
位加法器,其运算速度取决于输入的时钟频率。若时钟频率为
100 MHz,则每一运算周期仅需 80 ns。而若利用备用最高时钟,
即 12 MHz晶振的 MCS-51单片机的乘法指令,进行 8位乘法运算,
仅单指令的运算周期就长达 4 μs。因此,可以利用此乘法器或相同原理构成的更高位乘法器完成一些数字信号处理方面的运算。
第 6章 VHDL设计应用实例
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
第 6章 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;
第 6章 VHDL设计应用实例
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位寄存器设置第 6章 VHDL设计应用实例
BEGIN
PROCESS (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;
第 6章 VHDL设计应用实例
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)
第 6章 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;
第 6章 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
第 6章 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
第 6章 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;
第 6章 VHDL设计应用实例
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;
第 6章 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位加法器端口定义
...
第 6章 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
第 6章 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;
第 6章 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)。
第 6章 VHDL设计应用实例进行硬件验证时方法如下:① 键 2和键 1分别输入乘数的高
4位和低 4位 (输入值显示于数码 2和数码 1);② 键 4和键 3分别输入被乘数的高 4位和低 4位 (输入值显示于数码 4和数码 3);③ 乘法操作时钟信号输入接 CLOCK0;④ 键 8输入高电平时,乘积锁存器清零,乘数和被乘数数值加载,低电平时开始作乘法,
8个脉冲后乘法结束,乘积显示于数码管 8~ 5,高位在左。
第 6章 VHDL设计应用实例
6.3 序列检测器的设计
1.设计思路序列检测器可用于检测一组或多组由二进制码组成的脉冲序列信号,这在数字通信领域有广泛的应用。当序列检测器连续收到一组串行二进制码后,如果这组码与检测器中预先设置的码相同,则输出 1,否则输出 0。由于这种检测的关键在于正确码的收到必须是连续的,这就要求检测器必须记住前一次的正确码及正确序列,直到在连续的检测中所收到的每一位码都与预置数的对应码相同。在检测过程中,任何一位不相等都将回到初始状态重新开始检测。如图 6.3所示,当一串待检测的串行数据进入检测器后,若此数在每一位的连续检测中都与预置的密码数相同,则输出,A”,否则仍然输出,B”。
第 6章 VHDL设计应用实例图 6.3 8位序列检测器逻辑图
C H K
A B [ 3,,0 ]
D [ 7,,0 ]
C L R
C L K
D I N
C L K
D I N
C L R
D [ 7,,0 ]
A B [ 3,,0 ]
第 6章 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
第 6章 VHDL设计应用实例
SIGNAL Q,INTEGER RANGE 0 TO 8;
BEGIN
PROCESS ( 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;
第 6章 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 ;
第 6章 VHDL设计应用实例
END PROCESS;
PROCESS(Q) --检测结果判断输出
BEGIN
IF Q= 8 THEN AB<= "1010"; --序列数检测正确,输出,A”
ELSE AB<= "1011"; --序列数检测错误,输出,B”
END IF ;
END PROCESS;
END ART;
第 6章 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)。
第 6章 VHDL设计应用实例进行硬件验证时方法如下:① 选择实验电路结构图 NO.8,
按实验板“系统复位”键;② 用键 2和键 1输入两位十六进制待测序列数;③ 利用键 4和键 3输入两位十六进制预置码;④ 按键 8,高电平初始化清零,低电平清零结束 (平时数码 6应显
,B”);⑤ 按键 6(CLK)8次,这时若串行输入的 8位二进制序列码与预置码相同,则数码 7应从原来的,B”变成,A”,表示序列检测正确,否则仍为,B”。
第 6章 VHDL设计应用实例
6.4 正负脉宽数控调制信号发生器的设计
1.设计思路图 6.4 是脉宽数控调制信号发生器逻辑图,此信号发生器是由两个完全相同的可自加载加法计数 LCNT8组成的,它的输出信号的高低电平脉宽可分别由两组 8位预置数进行控制。
第 6章 VHDL设计应用实例图 6.4 脉宽数控调制信号发生器逻辑图
I2
D
Q
C LR N
P R N
V C C
P S O U T
LC N T8
C A O
D [ 7,,0 ]
LD
C LK
B
A
C LK
LC N T8
C A O
D [ 7,,0 ]
LD
C LK
U1 U2
LD 1
C A O 1
LD 2
C A O 2
P S I N T
第 6章 VHDL设计应用实例如果将初始值可预置的加法计数器的溢出信号作为本计数器的初始预置加载信号 LD,则可构成计数初始值自加载方式的加法计数器,从而构成数控分频器。图 6.4中 D触发器的一个重要功能就是均匀输出信号的占空比,提高驱动能力,这对驱动,诸如扬声器或电动机十分重要。
第 6章 VHDL设计应用实例
2,VHDL源程序
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 )
第 6章 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;
第 6章 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
第 6章 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);
第 6章 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;
第 6章 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)。
第 6章 VHDL设计应用实例进行硬件验证时方法如下:通过键 2和键 1输入控制高电平信号脉宽的预置数 (显示于数码管 2和 1);由键 4和键 3输入控制低电平信号脉宽的预置数 (显示于数码管 4和 3);取待分频率
F=12 MHz,6 MHz或 3 MHz,通过短路帽输入 CLK9;频率输出可利用示波器观察波形随预置数的变化而变化的情况。在没有示波器时,,CLK”可接低频率信号,然后接通扬声器,通过声音音调的变化来了解输出频率的变化。
第 6章 VHDL设计应用实例
6.5 数字频率计的设计
1,设计思路图 6.5是 8位十进制数字频率计的电路逻辑图,它由一个测频控制信号发生器 TESTCTL,8个有时钟使能的十进制计数器
CNT10、一个 32位锁存器 REG32B组成。以下分别叙述频率计各逻辑模块的功能与设计方法。
第 6章 VHDL设计应用实例图 6.5 8位十进制数字频率计逻辑图
S D [ 3 1,,0 ]
R E G 3 2 B
T E S T C T L
G N D
F SI N
C L K
D O U T [ 3 1,,0 ]
S D [ 3 1,,2 8 ]
S D [ 2 7,,2 4 ]
S D [ 2 3,,2 0 ]
S D [ 1 9,,1 6 ]
S D [ 1 5,,1 2 ]
S D [ 1 1,,8 ]
S D [ 7,,4 ]
S D [ 3,,0 ]
D O U T [ 3 1,,0 ]
D IN [ 3 1,,0 ]
L O A D
C L K C Q [ 3,,0 ]
C A R R Y _ O U T
EN
A
C L R
C N T 1 0
C L K C Q [ 3,,0 ]
C A R R Y _ O U T
EN
A
C L R
C N T 1 0
C L K C Q [ 3,,0 ]
C A R R Y _ O U T
EN
A
C L R
C N T 1 0
C L K C Q [ 3,,0 ]
C A R R Y _ O U T
EN
A
C L R
C N T 1 0
C N T 1 0
C L K C Q [ 3,,0 ]
C A R R Y _ O U T
EN
A
C L R
C N T 1 0
C N T 1 0
C L K C Q [ 3,,0 ]
C A R R Y _ O U T
EN
A
C L R
C L K C Q [ 3,,0 ]
C A R R Y _ O U T
EN
A
C L R
C N T 1 0
C L K C Q [ 3,,0 ]
C A R R Y _ O U T
EN
A
C L R
L O A D
C L R _ C N T
T ST E N
R ST
C L K
U0
U9
U2
U1
U3
U4 U8
U7
U6
U5
SE
SC
SL
S1
S2
S3
S4
S5
S6
S7
S8
第 6章 VHDL设计应用实例
1) 测频控制信号发生器设计频率测量的基本原理是计算每秒钟内待测信号的脉冲个数。
这就要求 TESTCTL的计数使能信号 TSTEN能产生一个 1秒脉宽的周期信号,并对频率计的每一计数器 CNT10的 ENA使能端进行同步控制。当 TSTEN高电平时,允许计数;低电平时,停止计数,并保持其所计的数。在停止计数期间,首先需要一个锁存信号 LOAD的上跳沿将计数器在前 1秒钟的计数值锁存进 32位锁存器 REG32B中,并由外部的 7段译码器译出并稳定显示。锁存信号之后,必须有一清零信号 CLR_CNT对计数器进行清零,
为下 1秒钟的计数操作作准备。测频控制信号发生器的工作时序如图 6.6所示。为了产生这个时序图,需首先建立一个由 D触发器构成的二分频器,在每次时钟 CLK上沿到来时其值翻转。
第 6章 VHDL设计应用实例其中控制信号时钟 CLK的频率取 1 Hz,而信号 TSTEN的脉宽恰好为 1 s,可以用作闸门信号。此时,根据测频的时序要求,
可得出信号 LOAD和 CLR_CNT的逻辑描述。由图 6.6可见,在计数完成后,即计数使能信号 TSTEN在 1 s的高电平后,利用其反相值的上跳沿产生一个锁存信号 LOAD,0.5 s后,CLR_CNT
产生一个清零信号上跳沿。
高质量的测频控制信号发生器的设计十分重要,设计中要对其进行仔细的实时仿真 (TIMING SIMULATION),防止可能产生的毛刺。
第 6章 VHDL设计应用实例图 6.6 测频控制信号发生器工作时序
[ I ] R S T
[ I ] C L K
[ O ] T S T E N
[ O ] L O A D
[ O ] C L R _ C N T
第 6章 VHDL设计应用实例
2) 寄存器 REG32B设计设置锁存器的好处是,显示的数据稳定,不会由于周期性的清零信号而不断闪烁。若已有 32位 BCD码存在于此模块的输入口,在信号 LOAD的上升沿后即被锁存到寄存器 REG32B的内部,并由 REG32B的输出端输出,然后由实验板上的 7段译码器译成能在数码管上显示输出的相对应的数值。
第 6章 VHDL设计应用实例
3) 十进制计数器 CNT10的设计如图 6.5所示,此十进制计数器的特殊之处是,有一时钟使能输入端 ENA,用于锁定计数值。当高电平时计数允许,低电平时禁止计数。
第 6章 VHDL设计应用实例
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
第 6章 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;
第 6章 VHDL设计应用实例
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;
第 6章 VHDL设计应用实例
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
第 6章 VHDL设计应用实例
PROCESS ( CLK )
BEGIN
IF 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;
第 6章 VHDL设计应用实例
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);
第 6章 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);
第 6章 VHDL设计应用实例
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,
第 6章 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;
第 6章 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的频率。
第 6章 VHDL设计应用实例
6.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分。
第 6章 VHDL设计应用实例图 6.7 秒表电路逻辑图
D O U T [ 1 1,,8 ]
D O U T [ 7,,4 ]
E N A
CL R
CL K
CN T 1 0
CA RRY _ O U T
CQ [ 3,,0 ]
CL R
CL K
CL K N E W C L K
CL K G E
N
E N A
E N A
CL R
CL K
CN T 1 0
CA RRY _ O U T
CQ [ 3,,0 ]
E N A
CL R
CL K
CN T 1 0
D O U T [ 3,,0 ]
CA RRY _ O U T
CQ [ 3,,0 ]
E N A
CL R
CL K
CN T 6
D O U T [ 2 3,,2 0 ]
CA RRY _ O U T
CQ [ 3,,0 ]
E N A
CL R
CL K
CN T 1 0
D O U T [ 1 9,,1 6 ]
CA RRY _ O U T
CQ [ 3,,0 ]
E N A
CL R
CL K
CN T 6
D O U T [ 1 5,,1 2 ]
CA RRY _ O U T
CQ [ 3,,0 ]
D O U T [ 2 3,,0 ]U0
U1
S1
U2
S2
U3
S3
U6
U5
S5
S4
U4
S0
第 6章 VHDL设计应用实例
2,VHDL源程序
1) 3 MHz→100 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
第 6章 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;
第 6章 VHDL设计应用实例
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);
第 6章 VHDL设计应用实例
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 CLK'EVENT AND CLK='1' THEN
IF ENA='1' THEN
IF CQI=“0101” THEN CQI<=“0000”;
第 6章 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;
第 6章 VHDL设计应用实例
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);
第 6章 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;
第 6章 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);
第 6章 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;
第 6章 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个数码管上。
第 6章 VHDL设计应用实例
6.7 MCS-51单片机与 FPGA/CPLD总线接口逻辑设计单片机具有性能价格比高、功能灵活、易于人机对话和良好的数据处理能力等特点; PLD则具有高速、高可靠以及开发便捷规范等方面的优点,以此两类器件相结合的电路结构在许多高性能仪器仪表和电子产品中将被广泛应用。单片机与 CPLD
的接口方式一般有两种,即总线方式与独立方式。
单片机以总线方式与 FPGA/CPLD进行数据与控制信息通信有许多优点:
第 6章 VHDL设计应用实例
(1) 速度快。其通信工作时序是纯硬件行为,对于 MCS-51
单片机,只需一条单字节指令就能完成所需的读 /写时序,如:
MOV @DPTR,A; MOV A,@DPTR。
(2) 节省 PLD芯片的 I/O口线。如图 6.9,如果将图中的译码
DECODER设置足够的译码输出,以及安排足够的锁存器,就能仅通过 19根 I/O口线在 FPGA/CPLD与单片机之间进行各种类型的数据与控制信息交换。
(3) 相对于非总线方式,单片机的编程简捷,控制可靠。
第 6章 VHDL设计应用实例
(4) 在 FPGA/CPLD中通过逻辑切换,单片机易于与 SRAM
或 ROM接口。这种方式有许多实用之处,如利用类似于微处理器 DMA的工作方法,首先由 FPGA/CPLD与接口的高速 A/D
等器件进行高速数据采样,并将数据暂存于 SRAM中,采样结束后,通过切换,使单片机与 SRAM以总线方式进行数据通信,
以便发挥单片机强大的数据处理能力。
第 6章 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位地址锁存于地址锁存器。
第 6章 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的数据写入图中相关的锁存器。
第 6章 VHDL设计应用实例图 6.8 MCS-51单片机总线接口方式工作时序低 8 位数据地址低 8 位数据地址数据低 8 位指令地址指令数据地址指令地址
A7 ~ A0
外部 RA M 读/写 允许指令读允许
A 15 ~ A8 A 15 ~ A8
A7 ~ A0A7 ~ A0
P0
P2
W R/ R D
P S E N
A L E
地址锁存沿第 6章 VHDL设计应用实例图 6.9 CPLD/FPGA与 MCS-51单片机的总线接口通信逻辑图
F P G A / CP L D
I1
A L E
P2
RD
WR
80 31
8
8
D E CO D E R
W R_E N A BL E 1
W R_E N A BL E 2
RD _E N A BL E
L A T C H _ A D D RE S
W R_E N A BL E 2
L A T C H _ O U T 2
W R_E N A BL E 1
L A T C H _ O U T 1
D A T O U T
1
A D _C S
RE A D
Y
D A T O U T
2
D A T A IN
1
L A T C H 1
L A T C H T _ I N 1
8
8
8
8
8
8
8
P0
WR
R
D
P2
P0
A L E
第 6章 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; --读回信号锁存第 6章 VHDL设计应用实例
DATOUT1,OUT STD_LOGIC_VECTOR(7 DOWNTO 0); --锁存输出数据 1
DATOUT2,OUT STD_LOGIC_VECTOR(7 DOWNTO 0); --锁存输出数据 2
END 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
第 6章 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
第 6章 VHDL设计应用实例
BEGIN
IF WR_ENABLE1'EVENT AND WR_ENABLE1 = '1'
THEN LLATCH_OUT1<= P0; END IF;
END PROCESS;
PROCESS (P2,LATCH_ADDRES ) --WR写信号译码进程 2
BEGIN
IF ( LATCH_ADDRES= "11110011")AND(P2= "00011111" ) THEN
WR_ENABLE2<= WR; --写允许
ELSE WR_ ENABLE2<= '1'; END IF; --写禁止
END PROCESS;
PROCESS (WR_ENABLE2 ) --数据写入寄存器 2
BEGIN
第 6章 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中数据读入进程
BEGIN
IF ( 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进程第 6章 VHDL设计应用实例
BEGIN
IF LATCH1'EVENT AND LATCH1= '1'
THEN LATCH_IN1<=DATAIN1; END IF;
END PROCESS;
PROCESS(ALTCH_ADDRES) --A/D工作控制片选信号输出进程
BEGIN
IF ( 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;
第 6章 VHDL设计应用实例这是一个 CPLD与 8031单片机接口的 VHDL电路设计。
8031以总线方式工作,例如,由 8031将数据 5AH写入目标器件中的第一个寄存器 LATCH_OUT1的指令是:
MOV A,#5AH
MOV DPTR,#6FF5H
MOVX @DPTR,A
当 READY为高电平时,8031从目标器件中的寄存器
LATCH_IN1将数据读入的指令是:
MOV DPTR,#9F7EH
MOVX A,@DPTR
第 6章 VHDL设计应用实例
6.8 交通灯信号控制器的设计
1,设计思路设交通灯信号控制器用于主干道与支道公路的交叉路口,
要求是优先保证主干道的畅通。因此,平时处于“主干道绿灯,
支道红灯”状态,只有在支道有车辆要穿行主干道时,才将交通灯切向“主干道红灯,支道绿灯”,一旦支道无车辆通过路口,交通灯又回到“主干道绿灯,支道红灯”的状态。此外,
主干道和支道每次通行的时间不得短于 30 s,而在两个状态交换过程出现的“主黄,支红”和“主红,支黄”状态,持续时间都为 4 s。根据交通灯信号控制的要求,我们可把它分解为定时器和控制器两部分,其原理方框图如图 6.10所示。
第 6章 VHDL设计应用实例图 6.10 交通灯信号控制器原理方框图第 6章 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
第 6章 VHDL设计应用实例
CNT,PROCESS(CLK)
VARIABLE S,INTEGER RANGE 0 TO 29;
VARIABLE CLR,EN,BIT;
BEGIN
IF (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';
第 6章 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';
第 6章 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';
第 6章 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;
第 6章 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则按控制要求显示相应的信号。
第 6章 VHDL设计应用实例
6.9 语音信箱控制系统的设计
1.设计思路语音信箱控制系统用于控制对语音信箱的有关操作,允许用户发送信息、重阅信息、存储信息和擦除信息,状态转移图如图 6.11所示。
第 6章 VHDL设计应用实例图 6.11 语音信箱控制器的状态转移图
5
3
21
21
R E VI E W
收信阅览
R E P E A
T
重复
S A VE
存信
E R AS E
擦除
R E C O R D
开始录音
B E GI N
AD DR E S S
寻址
S E ND
发信
M AI N
语音信箱
R E C O R D
记录
M E S S AG E
记录语音
R E C O R D
M AI N _ S
T
R E VI E W _ S
T
R E P E AT _ S
T S A VE _ S T E R AS E _ S T M E S S AG E _ S T B I GI N _ R E C _ S T
R E C O R D _ S T
AD DR E S S _ S
T
S E ND _ S T
第 6章 VHDL设计应用实例正常起始状态是 MAIN_ST状态,从 MAIN_ST状态,用户选择究竟是收信息还是发信息。为了得到收阅菜单,用户在按键电话上按 1键;为了选发送信息菜单,用户在按键菜单上按 2
键。一旦用户选择了这些选项中的任何一种,下一级菜单允许用户选择执行进一步 (如存储与删除信息 )的功能。例如,如果用户先按键 1,选收阅菜单,那么再按键 2,将允许用户在收阅完时存储用户收阅过的信息。
第 6章 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;
第 6章 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
第 6章 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
第 6章 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;
第 6章 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
第 6章 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;
第 6章 VHDL设计应用实例
END IF;
END CASE;
END PROCESS;
PROCESS
BEGIN
WAIT UNTIL (CLK'EVENT AND CLK = '1');
CURRENT_STATE<=NEXT_STATE;
END PROCESS;
END ART;
第 6章 VHDL设计应用实例程序包 VM_PACK含有对状态值的类型说明和语音信箱控制系统允许用的键盘。必须指出的是,状态是用来表示某些事件的全过程,而事件的全过程又是由它所对应状态 (如 STATE1、
STATE2和 STATE3 等 )来说明,用状态描述将使模块的可读性更好。
为了实用,这个程序包实体标明了局部信号和键输入端口。
该实体只有一种输入 (即键输入 ),由按键电话的键盘示出可能的键字,实体除 KEY和 CLK之外,所有其他的端口都是输出端口,并且用这些端口控制语音信箱系统的工作。
第 6章 VHDL设计应用实例
6.10 PID控制器的设计
1.设计思路要求设计一个 PID控制器,对电机转速进行采样,与额定的转速进行比较,并通过微积分计算得到电机的控制电流,从而实现对电机转速的调整。通常,PID控制器用模拟电路实现,但数字电路的实现方案可以很方便地实现集成。
该 PID控制器包括一个完成算术和逻辑功能的 ALU以及一个存储状态变量和有关系数的存储器。其端口说明如图 6.12 所示。
第 6章 VHDL设计应用实例图 6.12 PID控制器示意图
R E S E T
H O S T I N T E R R U P T
F S I G N I N
I R E F K O U T
P O S I T I O N C H A N G E
P I D 控制器第 6章 VHDL设计应用实例其中,RESET 端口为复位端口,当 RESET为高电平时,
PID控制器复位; FSIGNIN为输入的偏差方向,转速超过额定转速时为‘ 1?,否则为‘ 0?; HOSTINTERRUPT为主机请求信号,
当此信号为‘ 1?时,PID开始计算,为‘ 0?时,则停止计算并输出结果。 POSITIONCHANGE为电机向 PID控制器发送的脉冲信号,每转过一周,POSITONCHANGE 出现一个脉冲;
IREFKOUT为最终输出的控制电流值。
主机向 PID控制器发调用请求 HOSTINTERRUPT之后,PID
控制器进行采样并开始计算,当 HOSTINTERRUPT信号停止时,
PID控制器停止采样计算,并将计算结果输出到主机。
第 6章 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线性相加得到控制电流值。然后,在下一个时钟周期将该控制电流值输出到主机。
第 6章 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
第 6章 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;
第 6章 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);
第 6章 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);
第 6章 VHDL设计应用实例
PROCESS
VARIABLE N,EK_1,IK,EK,KP,KI,KD,FREF,REAL;
VARIABLE FK,DEK,IREFK,TEMP,REAL;
VARIABLE DONE,BIT;
第 6章 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;
第 6章 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;
第 6章 VHDL设计应用实例
PROCEDURE WAITRESULT(X,OUT REAL; Y,OUT BIT) IS
BEGIN
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
第 6章 VHDL设计应用实例
BEGIN
X,= VAL_ROM(0);
END GETCONSTKP;
PROCEDURE GETCONSTKI(X,OUT REAL) IS
BEGIN
X,= VAL_ROM(1);
END GETCONSTKI;
PROCEDURE GETCONSTKD(X,OUT REAL) IS
BEGIN
X,= VAL_ROM(2);
END GETCONSTKD;
PROCEDURE GETFREF(X,OUT REAL) IS
BEGIN
X,= VAL_ROM(3);
第 6章 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;
第 6章 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;
第 6章 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;
第 6章 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;
第 6章 VHDL设计应用实例
6.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所示。
第 6章 VHDL设计应用实例图 6.13 空调有限状态自动机原理方框图空调有限状态自动机
H E A T
T E M P _ L O W
T E M P _ H I G H
C O O L
第 6章 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;
第 6章 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
第 6章 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;
第 6章 VHDL设计应用实例
6.12 闹钟系统的设计
6.12.1 闹钟系统的设计要求及设计思路要求设计一个带闹钟功能的 24小时计时器,计时器的外观如图 6.14所示。它包括以下几个组成部分:① 显示屏,由 4个七段数码管组成,用于显示当前时间 (时:分 )或设置的闹钟时间;②
数字键‘ 0?~‘ 9?,用于输入新的时间或新的闹钟时间;③
TIME(时间 )键,用于确定新的时间设置;④ ALARM(闹钟 )键,
用于确定新的闹钟时间设置,或显示已设置的闹钟时间;⑤ 扬声器,在当前时钟时间与闹钟时间相同时,发出蜂鸣声。
第 6章 VHDL设计应用实例图 6.14 计时器外观
0 1 2 3
654
7 8 9
A L A R M
T I M E
第 6章 VHDL设计应用实例该计时器设计要求完成如下功能:
(1) 计时功能:这是本计时器设计的基本功能,每隔一分钟计时一次,并在显示屏上显示当前时间。
(2) 闹钟功能:如果当前时间与设置的闹钟时间相同,则扬声器发出蜂鸣声。
(3) 设置新的计时器时间:用户用数字键‘ 0?~‘ 9?输入新的时间,然后按 "TIME"键确认。在输入过程中,输入数字在显示屏上从右到左依次显示。例如,用户要设置新的时间 12,34,
则按顺序输入,1”,,2”,,3”,,4”键,与之对应,显示屏上依次显示的信息为:,1”,,12”,,123”,,1234"。如果用户在输入任意几个数字后较长时间内,例如 5 s,没有按任何键,
则计时器恢复到正常的计时显示状态。
第 6章 VHDL设计应用实例
(4) 设置新的闹钟时间:用户用数字键,0”~“9”输入新的时间,然后按,ALARM”键确认。过程与 (3)类似。
(5) 显示所设置的闹钟时间:在正常计时显示状态下,用户直接按下,ALARM”键,则已设置的闹钟时间将显示在显示屏上。
根据上述的设计要求,整个系统大致包括如下几个组成部分:用于键盘输入的缓冲器;用于时钟计数的计数器;用于保存闹钟时间的寄存器;用于显示的七段数码显示电路以及控制以上各个部分协同工作的控制器。
第 6章 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”
键。
第 6章 VHDL设计应用实例图 6.15 控制器的外部端口
A L A R M _ C O N T R O L L E R
K E Y
A L A R M _ B U T T O N
T I M E _ B U T T O N
C L K
R E S E T
L O A D _ N E W _ A
L O A D _ N E W _ C
S H O W _ N E W _ T I M E
S H O W _ A
第 6章 VHDL设计应用实例
(5) 当 LOAD_NEW_A 为高电平时,控制 (闹钟时间寄存器 )
加载新的闹钟时间值。
(6) 当 LOAD_NEW_C为高电平时,控制 (时钟计数器 )设置新的时间值。
(7) 当 SHOW_NEW_TIME为高电平时,控制 (七段数码显示电路 )显示新的时间值,即用户通过数字键输入的时间;否则,
当 SHOW_NEW_TIME为低电平时,根据 SHOW_A信号的值控制显示当前时间或闹钟时间。此时,当 SHOW_A为高电平时,
控制显示闹钟时间,否则,显示当前时间。
第 6章 VHDL设计应用实例控制器的功能可以通过有限状态自动机 (FSM)的方式来实现。根据设计要求及端口设置,需要 5个状态来实现:
S0,表示电路初态即正常时钟计数状态,完成前面设计功能 (1) 的工作。
S1:接收键盘输入状态。在状态 S0时用户按下数字键后进入此状态。在此状态下,显示屏上显示的是用户键入的数字。
S2:设置新的闹钟时间。在状态 S1时用户按下 ALARM键后进入此状态。
S3:设置新的计时器时间。在状态 S1时用户按下 TIME键后进入此状态。
第 6章 VHDL设计应用实例
S4:显示闹钟时间。在状态 S0时用户直接按下 ALARM键后进入此状态。在此状态下,显示屏上显示的是所设置的闹钟时间。注意:在此状态下,用户按下 ALARM键后,显示屏上保持显示闹钟时间,经过一段时间以后,再返回状态 S0显示计时器时间。
第 6章 VHDL设计应用实例表 6.1 控制器状态转换及控制输出表当前状态 控制输入 ( 条件 ) 下一状态 控制输出 ( 动作 )
K E Y =?1? S1 S H O W _ N E W _ T IM E < =?1?
A L A R M _ B U T T O N =?1? S4 S H O W _ A < =?1? S0
否则 S0 --
K E Y =?1? S1 S H O W _ N E W _ T IM E < =?1?
A L A R M _ B U T T O N =?1? S2 L O A D _ N E W _ A < =?1?
T IM E _ B U T T O N =?1? S3 L O A D _ N E W _ C < =?1?
否
S1
S H O W _ N E W _ T IM E < =?1?,,超时,判断处理
S1
否则 ( 超时 )
是 S0 --
A L A R M _ B U T T O N =?1? S2 L O A D _ N E W _ A < =?1?
S2
否则 S0 --
T IM E _ B U T T O N =?1? S3 L O A D _ N E W _ C < =?1?
S3
否则 S0 --
A L A R M _ B U T T O N =?1? S4 S H O W _ A < =?1?
否 S4 S H O W _ A < =?1?,,超时,判断处理 S4
否则 ( 超时 )
是 S0 --
第 6章 VHDL设计应用实例表 6.1中没有显式说明的控制信号赋值,表示信号的值为零。例如在状态 S0,当信号 KEY =?1?时,SHOW_NEW_TIME
信号的赋值为‘ 1?,而其他信号 LOAD_NEW_A,
LOAD_NEW_C和 SHOW_A的值此时都赋为‘ 0?。另外,表中关于“超时”判断处理的处理细节见 VHDL源程序中的有关部分。
第 6章 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;
第 6章 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
第 6章 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;
第 6章 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';
第 6章 VHDL设计应用实例
CASE CURR_STATE IS
WHEN 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;
第 6章 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';
第 6章 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;
第 6章 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';
第 6章 VHDL设计应用实例
END IF;
ENABLE_COUNT_A <= '1';
END IF;
WHEN OTHERS =>
NULL;
END CASE;
END PROCESS;
第 6章 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;
第 6章 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;
第 6章 VHDL设计应用实例
6.12.3 闹钟系统的译码器的设计
1.设计思路本模块的功能是将每次按下闹钟系统的数字键盘后产生的一个数字所对应的 10位二进制数据信号转换为 1位十进制整数信号,以作为小时、分钟计数的 4个数字之一,如图 6.16所示。
其中 KEYPAD为输入端口,接收 10位二进制数据信号;
VALUE为输出端口,输出相应的 1位十进制整数信号。输入数据与输出数据的译码关系见表 6.2。
第 6章 VHDL设计应用实例图 6.16 电路系统示意图
K EY P A D
D EC O D ER
V A LU E
第 6章 VHDL设计应用实例表 6.2 输入、输出数据的译码关系输入 0000000001 0000000010 0000000100 0000001000 0000010000
输出 0 1 2 3 4
输入 0000100000 0001000000 0010000000 0100000000 1000000000
输出 5 6 7 8 9
第 6章 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 IS
BEGIN
第 6章 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;
第 6章 VHDL设计应用实例
6.12.4 闹钟系统的移位寄存器的设计
1.设计思路本模块的功能是在 CLK端口输入信号的上升沿同步下,将
KEY端口的输入信号移入 NEW_TIME 端口的输出信号最低位,
原有信息依次向左移,最高位信息丢失;而 RESET端口的输入信号对 NEW_TIME端口输出信号进行异步清零复位。电路系统示意图如图 6.17所示。
第 6章 VHDL设计应用实例图 6.17 移位寄存器电路示意图
K EY
C LK
K EY _ B U F F ER
N EW _ T I M ER ES E T
第 6章 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
第 6章 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;
第 6章 VHDL设计应用实例
6.12.5 闹钟系统的闹钟寄存器和时间计数器的设计
1.电路系统工作原理闹钟寄存器模块的功能是在时钟上升沿同步下,根据 LOAD
_NEW _A端口的输入信号控制 ALARM _TIME端口的输出,当控制信号有效 (高电平 )时,把 NEW _ALARM _TIME端口的输入信号值输出;而 RESET端口输入信号对 ALARM _TIME 端口的输出进行异步的清零复位。图 6.18是闹钟寄存器模块的示意图。
闹钟系统的闹钟时间由闹钟寄存器保存和传递,而当前时间由时间计数器保存、传递并按分钟累加推进。这两个组件的功能和设计描述比较相似,它们之间的区别主要在于自动累加功能的有无和控制信号的优先作用次序。
第 6章 VHDL设计应用实例图 6.18 闹钟寄存器示意图
LO A D _ N EW _ A
N EW _ A LA R M _ T I M E
C LK
R ES E T
A LA R M _ T I M E
A LA R M _ R EG
第 6章 VHDL设计应用实例时间计数器模块的功能是当 RESET端口输入信号为高电平时,对 CURRENT _TIME端口输出信号清零复位;当 LOAD
_NEW _C端口输入信号为高电平时,将
NEW_CURRENT_TIME端口的输入信号输出给
CURRENT_TIME端口。 RESET端口 D的控制优先于 LOAD
_NEW _C端口。当这两个控制信号都无效时,在时钟上升沿同步下,对 CURRENT _TIME端口输出信号累加 1,并根据小时、
分钟的规律处理进位。图 6.19是时间计数器模块的示意图。
第 6章 VHDL设计应用实例图 6.19 时间计数器模块的示意图
C L K
R E S E T
C U R R E N T _ T I M E
A L A R M _ C O U N T E R
L O A D _ N E W _ C
N E W _ C U R R E N T _ T I M E
第 6章 VHDL设计应用实例
2,VHDL源程序
--时间计数器的源程序 ALARM_COUNTER.VHD
LIBRARY 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);
第 6章 VHDL设计应用实例
END ALARM_COUNTER;
ARCHITECTURE ART OF ALARM_COUNTER IS
SIGNAL I_CURRENT_TIME,T_CLOCK_TIME;
BEGIN
PROCESS(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
第 6章 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;
第 6章 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;
第 6章 VHDL设计应用实例
END IF;
END PROCESS;
CURRENT_TIME <= I_CURRENT_TIME;
END ART;
--闹钟寄存器的源程序 ALARM_REG.VHD
LIBRARY 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;
第 6章 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;
第 6章 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;
第 6章 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为显示驱动器示意图。
第 6章 VHDL设计应用实例图 6.20 显示驱动器示意图
A LA R M _ T I M E
S H O W _ N E W _ TI M E
S O U N D _ A LA R M
D I S P LA Y _ D R I V E R
C U R R E N T _ TI M E
N EW _ T I M E
D I S P LA Y
S H O W _ A
第 6章 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);
第 6章 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;
第 6章 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!”
第 6章 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;
第 6章 VHDL设计应用实例
6.12.7 闹钟系统的分频器的设计
1.设计思路本模块的功能是将 CLK_IN端口输入的时钟信号分频后送给
CLK_OUT端口。当 RESET端口输入信号有效 (高电平 )时,
CLK_OUT端口输出信号清零。图 6.21为分频器示意图。
第 6章 VHDL设计应用实例图 6.21 分频器示意图
C LK _ I N
F Q _ D I V I D E R
C LK _ O U TR ES E T
第 6章 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
第 6章 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';
第 6章 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 CLK
END ART;
第 6章 VHDL设计应用实例
6.12.8 闹钟系统的整体组装
1.整体组装说明前边已经完成了计时器各个组成部分的设计,下面把这些组成部分组装起来,形成完整的总体设计。该计时器命名为
ALARM_CLOCK,其外部端口如图 6.22所示。
第 6章 VHDL设计应用实例图 6.22 计时器的外部端口
A L A R M _ B U T T O N
T I M E _ B U T T O N
S O U N D _ A L A R M
A L A R M _ C L O C K
K E Y _ D O W N
K E Y P A D
D I S P L A Y
C L K
R E S E T
第 6章 VHDL设计应用实例各个输入输出端口的作用如下:
(1) CLK为外部时钟信号,RESET为复位信号。
(2) KEYPAD是一个 10位信号,若其中某一位为高电平,
则表示用户按下了相应下标的数字键。例如,若 KEYPAD(5)
= '1',表示用户按下了数字键,5”。本设计不考虑用户同时按下多个数字键的情况,所以任意时刻 KEYPAD中只能有一位为‘ 1?。
(3) 当 KEYDOWN为高电平时 (KEYDOWN= '1'),表示用户按下某一数字键。
第 6章 VHDL设计应用实例
(4) 当 ALARM_BUTTON为高电平时,表示用户按下
ALARM键。
(5) 当 TIME_BUTTON为高电平时,表示用户按下 TIME键。
(6) DISPLAY实际上表示了 4个七段数码显示管,用于显示时间,如 12,20。
(7) SOUND_ALARM用于控制扬声器发声,当
SOUND_ALARM = '1' 时,扬声器发出蜂鸣,表示到了设定的闹钟时间。
设计的总体结构图如图 6.23所示。
第 6章 VHDL设计应用实例图 6.23 总体结构第 6章 VHDL设计应用实例下面再简要说明各组成部分的功能:
(1) 译码器 (DECODER) 可将 KEYPAD信号转换为 0~9的整型数,以直观地表示和处理用户输入的数字。
(2) 键盘缓冲器 (KEY_BUFFER)是一个移位寄存器,暂存用户键入的数字,并且实现用户键入数字在显示器上从右到左的依次显示。这里需要注意的是,由图 6.23可以看出,
KEY_BUFFER的时钟端连接的是外部 KEY_DOWN 信号。这表示用户每输入一个数字,KEY_BUFFER移位一次。
第 6章 VHDL设计应用实例
(3) 分频器 (FQ_DIVIDER)将较高速的外部时钟频率分频成每分钟一次的时钟频率,以便进行时钟计数。
(4) 计数器 (ALARM_COUNTER)实际上是一个异步复位、
异步置数的累加器,通常情况下进行时钟累加计数,必要时可置入新的时钟值,然后从该值开始新的计数。
(5) 寄存器 (ALARM_REG)用于保存用户设置的闹钟时间,
是一个异步复位寄存器。
第 6章 VHDL设计应用实例
(6) 显示器 (DISPLAY_DRIVER)根据需要显示当前时间、
用户设置的闹钟时间或用户通过键盘输入的新的时间,同时判断当前时间是否已到了闹钟时间,实际上是一个多路选择器加比较器。
(7) 控制器 (ALARM_CONTROLLER)是设计的核心部分,
按设计要求产生相应的控制逻辑,以控制其他各部分的工作。
第 6章 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;
第 6章 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 --待调用元件端口定义
...
第 6章 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;
第 6章 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);
第 6章 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;
第 6章 VHDL设计应用实例
6.12.9 闹钟系统的硬件验证若用 GW48型 EDA实验开发系统进行硬件验证,考虑到实验开发系统提供的输入信号按键的有限,可将输入数字按键
0~ 9改为一个按键,该按键的信号作为一个 8421码信号发生器的输入,由 8421码信号发生器输出数字 0~ 9。具体验证方案由读者自行完成。
6.1 8位加法器的设计
6.2 8位乘法器的设计
6.3 序列检测器的设计
6.4 正负脉宽数控调制信号发生器的设计
6.5 数字频率计的设计
6.6 秒表的设计
6.7 MCS–51单片机与 FPGA/CPLD总线接口逻辑设计
6.8 交通灯信号控制器的设计
6.9 语音信箱控制系统的设计
6.10 PID控制器的设计
6.11 空调系统有限状态自动机的设计
6.12 闹钟系统的设计第 6章 VHDL设计应用实例
6.1 8位加法器的设计
1.设计思路加法器是数字系统中的基本逻辑器件,减法器和硬件乘法器都可由加法器来构成。多位加法器的构成有两种方式:并行进位和串行进位方式。并行进位加法器设有进位产生逻辑,运算速度较快;串行进位方式是将全加器级联构成多位加法器。
并行进位加法器通常比串行级联加法器占用更多的资源。随着位数的增加,相同位数的并行加法器与串行加法器的资源占用差距也越来越大。因此,在工程中使用加法器时,要在速度和容量之间寻找平衡点。
第 6章 VHDL设计应用实例实践证明,4位二进制并行加法器和串行级联加法器占用几乎相同的资源。这样,多位加法器由 4位二进制并行加法器级联构成是较好的折中选择。本设计中的 8位二进制并行加法器即是由两个 4位二进制并行加法器级联而成的,其电路原理图如图 6.1所示。
第 6章 VHDL设计应用实例图 6.1 8位加法器电路原理图第 6章 VHDL设计应用实例
2,VHDL源程序
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); --进位输出第 6章 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;
第 6章 VHDL设计应用实例
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
第 6章 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
第 6章 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;
第 6章 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。
第 6章 VHDL设计应用实例
6.2 8位乘法器的设计
1.设计思路纯组合逻辑构成的乘法器虽然工作速度比较快,但占用硬件资源多,难以实现宽位乘法器,而基于 PLD器件外接 ROM九九表的乘法器则无法构成单片系统,也不实用。这里介绍由 8位加法器构成的以时序逻辑方式设计的 8位乘法器,此乘法器具有一定的实用价值。其乘法原理是:乘法通过逐项位移相加原理来实现,
从被乘数的最低位开始,若为 1,则乘数左移后与上一次和相加;
若为 0,左移后以全零相加,直至被乘数的最高位。从图 6.2的逻辑图上可以清楚地看出此乘法器的工作原理。
第 6章 VHDL设计应用实例图 6.2 8× 8位乘法器电路原理图
S 7 [ 7,,0 ]
S 6 [ 7,,0 ]
S 6 ( 8 )
A R I E N D
R E G 1 6 B
A D D E R 8 B
A R I C T L
S R E G 8 B
A N D A R I T H
O U T [ 1 5,,0 ]
B [ 7,,0 ]
A [ 7,,0 ]
S T A R T
C L K
Q [ 1 5,,0 ]
D [ 8,,0 ]
C L R
C L K
G N D
S 5 [ 7,,0 ]
S 6 [ 8,,0 ]
R S T A L L
C L K O U T
S 5 [ 7,,0 ]
S 7 [ 1 5,,8 ]
B [ 7,,0 ]
A [ 7,,0 ] C O U T
S [ 7,,0 ]
C I N
D O U T [ 7,,0 ]
D I N [ 7,,0 ]
A B I N
QB
D I N [ 7,,0 ]
L O A D
C L K
A R I E N DC L K
S T A R T
U1
U2
U3
U4
U5
S2
S3
S4
S 7 [ 1 5,,0 ]
S 7 [ 1 5,,8 ]
S1
第 6章 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的输出值即为最后乘积。
第 6章 VHDL设计应用实例此乘法器的优点是节省芯片资源,它的核心元件只是一个 8
位加法器,其运算速度取决于输入的时钟频率。若时钟频率为
100 MHz,则每一运算周期仅需 80 ns。而若利用备用最高时钟,
即 12 MHz晶振的 MCS-51单片机的乘法指令,进行 8位乘法运算,
仅单指令的运算周期就长达 4 μs。因此,可以利用此乘法器或相同原理构成的更高位乘法器完成一些数字信号处理方面的运算。
第 6章 VHDL设计应用实例
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
第 6章 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;
第 6章 VHDL设计应用实例
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位寄存器设置第 6章 VHDL设计应用实例
BEGIN
PROCESS (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;
第 6章 VHDL设计应用实例
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)
第 6章 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;
第 6章 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
第 6章 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
第 6章 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;
第 6章 VHDL设计应用实例
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;
第 6章 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位加法器端口定义
...
第 6章 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
第 6章 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;
第 6章 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)。
第 6章 VHDL设计应用实例进行硬件验证时方法如下:① 键 2和键 1分别输入乘数的高
4位和低 4位 (输入值显示于数码 2和数码 1);② 键 4和键 3分别输入被乘数的高 4位和低 4位 (输入值显示于数码 4和数码 3);③ 乘法操作时钟信号输入接 CLOCK0;④ 键 8输入高电平时,乘积锁存器清零,乘数和被乘数数值加载,低电平时开始作乘法,
8个脉冲后乘法结束,乘积显示于数码管 8~ 5,高位在左。
第 6章 VHDL设计应用实例
6.3 序列检测器的设计
1.设计思路序列检测器可用于检测一组或多组由二进制码组成的脉冲序列信号,这在数字通信领域有广泛的应用。当序列检测器连续收到一组串行二进制码后,如果这组码与检测器中预先设置的码相同,则输出 1,否则输出 0。由于这种检测的关键在于正确码的收到必须是连续的,这就要求检测器必须记住前一次的正确码及正确序列,直到在连续的检测中所收到的每一位码都与预置数的对应码相同。在检测过程中,任何一位不相等都将回到初始状态重新开始检测。如图 6.3所示,当一串待检测的串行数据进入检测器后,若此数在每一位的连续检测中都与预置的密码数相同,则输出,A”,否则仍然输出,B”。
第 6章 VHDL设计应用实例图 6.3 8位序列检测器逻辑图
C H K
A B [ 3,,0 ]
D [ 7,,0 ]
C L R
C L K
D I N
C L K
D I N
C L R
D [ 7,,0 ]
A B [ 3,,0 ]
第 6章 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
第 6章 VHDL设计应用实例
SIGNAL Q,INTEGER RANGE 0 TO 8;
BEGIN
PROCESS ( 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;
第 6章 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 ;
第 6章 VHDL设计应用实例
END PROCESS;
PROCESS(Q) --检测结果判断输出
BEGIN
IF Q= 8 THEN AB<= "1010"; --序列数检测正确,输出,A”
ELSE AB<= "1011"; --序列数检测错误,输出,B”
END IF ;
END PROCESS;
END ART;
第 6章 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)。
第 6章 VHDL设计应用实例进行硬件验证时方法如下:① 选择实验电路结构图 NO.8,
按实验板“系统复位”键;② 用键 2和键 1输入两位十六进制待测序列数;③ 利用键 4和键 3输入两位十六进制预置码;④ 按键 8,高电平初始化清零,低电平清零结束 (平时数码 6应显
,B”);⑤ 按键 6(CLK)8次,这时若串行输入的 8位二进制序列码与预置码相同,则数码 7应从原来的,B”变成,A”,表示序列检测正确,否则仍为,B”。
第 6章 VHDL设计应用实例
6.4 正负脉宽数控调制信号发生器的设计
1.设计思路图 6.4 是脉宽数控调制信号发生器逻辑图,此信号发生器是由两个完全相同的可自加载加法计数 LCNT8组成的,它的输出信号的高低电平脉宽可分别由两组 8位预置数进行控制。
第 6章 VHDL设计应用实例图 6.4 脉宽数控调制信号发生器逻辑图
I2
D
Q
C LR N
P R N
V C C
P S O U T
LC N T8
C A O
D [ 7,,0 ]
LD
C LK
B
A
C LK
LC N T8
C A O
D [ 7,,0 ]
LD
C LK
U1 U2
LD 1
C A O 1
LD 2
C A O 2
P S I N T
第 6章 VHDL设计应用实例如果将初始值可预置的加法计数器的溢出信号作为本计数器的初始预置加载信号 LD,则可构成计数初始值自加载方式的加法计数器,从而构成数控分频器。图 6.4中 D触发器的一个重要功能就是均匀输出信号的占空比,提高驱动能力,这对驱动,诸如扬声器或电动机十分重要。
第 6章 VHDL设计应用实例
2,VHDL源程序
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 )
第 6章 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;
第 6章 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
第 6章 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);
第 6章 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;
第 6章 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)。
第 6章 VHDL设计应用实例进行硬件验证时方法如下:通过键 2和键 1输入控制高电平信号脉宽的预置数 (显示于数码管 2和 1);由键 4和键 3输入控制低电平信号脉宽的预置数 (显示于数码管 4和 3);取待分频率
F=12 MHz,6 MHz或 3 MHz,通过短路帽输入 CLK9;频率输出可利用示波器观察波形随预置数的变化而变化的情况。在没有示波器时,,CLK”可接低频率信号,然后接通扬声器,通过声音音调的变化来了解输出频率的变化。
第 6章 VHDL设计应用实例
6.5 数字频率计的设计
1,设计思路图 6.5是 8位十进制数字频率计的电路逻辑图,它由一个测频控制信号发生器 TESTCTL,8个有时钟使能的十进制计数器
CNT10、一个 32位锁存器 REG32B组成。以下分别叙述频率计各逻辑模块的功能与设计方法。
第 6章 VHDL设计应用实例图 6.5 8位十进制数字频率计逻辑图
S D [ 3 1,,0 ]
R E G 3 2 B
T E S T C T L
G N D
F SI N
C L K
D O U T [ 3 1,,0 ]
S D [ 3 1,,2 8 ]
S D [ 2 7,,2 4 ]
S D [ 2 3,,2 0 ]
S D [ 1 9,,1 6 ]
S D [ 1 5,,1 2 ]
S D [ 1 1,,8 ]
S D [ 7,,4 ]
S D [ 3,,0 ]
D O U T [ 3 1,,0 ]
D IN [ 3 1,,0 ]
L O A D
C L K C Q [ 3,,0 ]
C A R R Y _ O U T
EN
A
C L R
C N T 1 0
C L K C Q [ 3,,0 ]
C A R R Y _ O U T
EN
A
C L R
C N T 1 0
C L K C Q [ 3,,0 ]
C A R R Y _ O U T
EN
A
C L R
C N T 1 0
C L K C Q [ 3,,0 ]
C A R R Y _ O U T
EN
A
C L R
C N T 1 0
C N T 1 0
C L K C Q [ 3,,0 ]
C A R R Y _ O U T
EN
A
C L R
C N T 1 0
C N T 1 0
C L K C Q [ 3,,0 ]
C A R R Y _ O U T
EN
A
C L R
C L K C Q [ 3,,0 ]
C A R R Y _ O U T
EN
A
C L R
C N T 1 0
C L K C Q [ 3,,0 ]
C A R R Y _ O U T
EN
A
C L R
L O A D
C L R _ C N T
T ST E N
R ST
C L K
U0
U9
U2
U1
U3
U4 U8
U7
U6
U5
SE
SC
SL
S1
S2
S3
S4
S5
S6
S7
S8
第 6章 VHDL设计应用实例
1) 测频控制信号发生器设计频率测量的基本原理是计算每秒钟内待测信号的脉冲个数。
这就要求 TESTCTL的计数使能信号 TSTEN能产生一个 1秒脉宽的周期信号,并对频率计的每一计数器 CNT10的 ENA使能端进行同步控制。当 TSTEN高电平时,允许计数;低电平时,停止计数,并保持其所计的数。在停止计数期间,首先需要一个锁存信号 LOAD的上跳沿将计数器在前 1秒钟的计数值锁存进 32位锁存器 REG32B中,并由外部的 7段译码器译出并稳定显示。锁存信号之后,必须有一清零信号 CLR_CNT对计数器进行清零,
为下 1秒钟的计数操作作准备。测频控制信号发生器的工作时序如图 6.6所示。为了产生这个时序图,需首先建立一个由 D触发器构成的二分频器,在每次时钟 CLK上沿到来时其值翻转。
第 6章 VHDL设计应用实例其中控制信号时钟 CLK的频率取 1 Hz,而信号 TSTEN的脉宽恰好为 1 s,可以用作闸门信号。此时,根据测频的时序要求,
可得出信号 LOAD和 CLR_CNT的逻辑描述。由图 6.6可见,在计数完成后,即计数使能信号 TSTEN在 1 s的高电平后,利用其反相值的上跳沿产生一个锁存信号 LOAD,0.5 s后,CLR_CNT
产生一个清零信号上跳沿。
高质量的测频控制信号发生器的设计十分重要,设计中要对其进行仔细的实时仿真 (TIMING SIMULATION),防止可能产生的毛刺。
第 6章 VHDL设计应用实例图 6.6 测频控制信号发生器工作时序
[ I ] R S T
[ I ] C L K
[ O ] T S T E N
[ O ] L O A D
[ O ] C L R _ C N T
第 6章 VHDL设计应用实例
2) 寄存器 REG32B设计设置锁存器的好处是,显示的数据稳定,不会由于周期性的清零信号而不断闪烁。若已有 32位 BCD码存在于此模块的输入口,在信号 LOAD的上升沿后即被锁存到寄存器 REG32B的内部,并由 REG32B的输出端输出,然后由实验板上的 7段译码器译成能在数码管上显示输出的相对应的数值。
第 6章 VHDL设计应用实例
3) 十进制计数器 CNT10的设计如图 6.5所示,此十进制计数器的特殊之处是,有一时钟使能输入端 ENA,用于锁定计数值。当高电平时计数允许,低电平时禁止计数。
第 6章 VHDL设计应用实例
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
第 6章 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;
第 6章 VHDL设计应用实例
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;
第 6章 VHDL设计应用实例
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
第 6章 VHDL设计应用实例
PROCESS ( CLK )
BEGIN
IF 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;
第 6章 VHDL设计应用实例
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);
第 6章 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);
第 6章 VHDL设计应用实例
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,
第 6章 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;
第 6章 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的频率。
第 6章 VHDL设计应用实例
6.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分。
第 6章 VHDL设计应用实例图 6.7 秒表电路逻辑图
D O U T [ 1 1,,8 ]
D O U T [ 7,,4 ]
E N A
CL R
CL K
CN T 1 0
CA RRY _ O U T
CQ [ 3,,0 ]
CL R
CL K
CL K N E W C L K
CL K G E
N
E N A
E N A
CL R
CL K
CN T 1 0
CA RRY _ O U T
CQ [ 3,,0 ]
E N A
CL R
CL K
CN T 1 0
D O U T [ 3,,0 ]
CA RRY _ O U T
CQ [ 3,,0 ]
E N A
CL R
CL K
CN T 6
D O U T [ 2 3,,2 0 ]
CA RRY _ O U T
CQ [ 3,,0 ]
E N A
CL R
CL K
CN T 1 0
D O U T [ 1 9,,1 6 ]
CA RRY _ O U T
CQ [ 3,,0 ]
E N A
CL R
CL K
CN T 6
D O U T [ 1 5,,1 2 ]
CA RRY _ O U T
CQ [ 3,,0 ]
D O U T [ 2 3,,0 ]U0
U1
S1
U2
S2
U3
S3
U6
U5
S5
S4
U4
S0
第 6章 VHDL设计应用实例
2,VHDL源程序
1) 3 MHz→100 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
第 6章 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;
第 6章 VHDL设计应用实例
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);
第 6章 VHDL设计应用实例
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 CLK'EVENT AND CLK='1' THEN
IF ENA='1' THEN
IF CQI=“0101” THEN CQI<=“0000”;
第 6章 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;
第 6章 VHDL设计应用实例
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);
第 6章 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;
第 6章 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);
第 6章 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;
第 6章 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个数码管上。
第 6章 VHDL设计应用实例
6.7 MCS-51单片机与 FPGA/CPLD总线接口逻辑设计单片机具有性能价格比高、功能灵活、易于人机对话和良好的数据处理能力等特点; PLD则具有高速、高可靠以及开发便捷规范等方面的优点,以此两类器件相结合的电路结构在许多高性能仪器仪表和电子产品中将被广泛应用。单片机与 CPLD
的接口方式一般有两种,即总线方式与独立方式。
单片机以总线方式与 FPGA/CPLD进行数据与控制信息通信有许多优点:
第 6章 VHDL设计应用实例
(1) 速度快。其通信工作时序是纯硬件行为,对于 MCS-51
单片机,只需一条单字节指令就能完成所需的读 /写时序,如:
MOV @DPTR,A; MOV A,@DPTR。
(2) 节省 PLD芯片的 I/O口线。如图 6.9,如果将图中的译码
DECODER设置足够的译码输出,以及安排足够的锁存器,就能仅通过 19根 I/O口线在 FPGA/CPLD与单片机之间进行各种类型的数据与控制信息交换。
(3) 相对于非总线方式,单片机的编程简捷,控制可靠。
第 6章 VHDL设计应用实例
(4) 在 FPGA/CPLD中通过逻辑切换,单片机易于与 SRAM
或 ROM接口。这种方式有许多实用之处,如利用类似于微处理器 DMA的工作方法,首先由 FPGA/CPLD与接口的高速 A/D
等器件进行高速数据采样,并将数据暂存于 SRAM中,采样结束后,通过切换,使单片机与 SRAM以总线方式进行数据通信,
以便发挥单片机强大的数据处理能力。
第 6章 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位地址锁存于地址锁存器。
第 6章 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的数据写入图中相关的锁存器。
第 6章 VHDL设计应用实例图 6.8 MCS-51单片机总线接口方式工作时序低 8 位数据地址低 8 位数据地址数据低 8 位指令地址指令数据地址指令地址
A7 ~ A0
外部 RA M 读/写 允许指令读允许
A 15 ~ A8 A 15 ~ A8
A7 ~ A0A7 ~ A0
P0
P2
W R/ R D
P S E N
A L E
地址锁存沿第 6章 VHDL设计应用实例图 6.9 CPLD/FPGA与 MCS-51单片机的总线接口通信逻辑图
F P G A / CP L D
I1
A L E
P2
RD
WR
80 31
8
8
D E CO D E R
W R_E N A BL E 1
W R_E N A BL E 2
RD _E N A BL E
L A T C H _ A D D RE S
W R_E N A BL E 2
L A T C H _ O U T 2
W R_E N A BL E 1
L A T C H _ O U T 1
D A T O U T
1
A D _C S
RE A D
Y
D A T O U T
2
D A T A IN
1
L A T C H 1
L A T C H T _ I N 1
8
8
8
8
8
8
8
P0
WR
R
D
P2
P0
A L E
第 6章 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; --读回信号锁存第 6章 VHDL设计应用实例
DATOUT1,OUT STD_LOGIC_VECTOR(7 DOWNTO 0); --锁存输出数据 1
DATOUT2,OUT STD_LOGIC_VECTOR(7 DOWNTO 0); --锁存输出数据 2
END 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
第 6章 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
第 6章 VHDL设计应用实例
BEGIN
IF WR_ENABLE1'EVENT AND WR_ENABLE1 = '1'
THEN LLATCH_OUT1<= P0; END IF;
END PROCESS;
PROCESS (P2,LATCH_ADDRES ) --WR写信号译码进程 2
BEGIN
IF ( LATCH_ADDRES= "11110011")AND(P2= "00011111" ) THEN
WR_ENABLE2<= WR; --写允许
ELSE WR_ ENABLE2<= '1'; END IF; --写禁止
END PROCESS;
PROCESS (WR_ENABLE2 ) --数据写入寄存器 2
BEGIN
第 6章 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中数据读入进程
BEGIN
IF ( 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进程第 6章 VHDL设计应用实例
BEGIN
IF LATCH1'EVENT AND LATCH1= '1'
THEN LATCH_IN1<=DATAIN1; END IF;
END PROCESS;
PROCESS(ALTCH_ADDRES) --A/D工作控制片选信号输出进程
BEGIN
IF ( 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;
第 6章 VHDL设计应用实例这是一个 CPLD与 8031单片机接口的 VHDL电路设计。
8031以总线方式工作,例如,由 8031将数据 5AH写入目标器件中的第一个寄存器 LATCH_OUT1的指令是:
MOV A,#5AH
MOV DPTR,#6FF5H
MOVX @DPTR,A
当 READY为高电平时,8031从目标器件中的寄存器
LATCH_IN1将数据读入的指令是:
MOV DPTR,#9F7EH
MOVX A,@DPTR
第 6章 VHDL设计应用实例
6.8 交通灯信号控制器的设计
1,设计思路设交通灯信号控制器用于主干道与支道公路的交叉路口,
要求是优先保证主干道的畅通。因此,平时处于“主干道绿灯,
支道红灯”状态,只有在支道有车辆要穿行主干道时,才将交通灯切向“主干道红灯,支道绿灯”,一旦支道无车辆通过路口,交通灯又回到“主干道绿灯,支道红灯”的状态。此外,
主干道和支道每次通行的时间不得短于 30 s,而在两个状态交换过程出现的“主黄,支红”和“主红,支黄”状态,持续时间都为 4 s。根据交通灯信号控制的要求,我们可把它分解为定时器和控制器两部分,其原理方框图如图 6.10所示。
第 6章 VHDL设计应用实例图 6.10 交通灯信号控制器原理方框图第 6章 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
第 6章 VHDL设计应用实例
CNT,PROCESS(CLK)
VARIABLE S,INTEGER RANGE 0 TO 29;
VARIABLE CLR,EN,BIT;
BEGIN
IF (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';
第 6章 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';
第 6章 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';
第 6章 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;
第 6章 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则按控制要求显示相应的信号。
第 6章 VHDL设计应用实例
6.9 语音信箱控制系统的设计
1.设计思路语音信箱控制系统用于控制对语音信箱的有关操作,允许用户发送信息、重阅信息、存储信息和擦除信息,状态转移图如图 6.11所示。
第 6章 VHDL设计应用实例图 6.11 语音信箱控制器的状态转移图
5
3
21
21
R E VI E W
收信阅览
R E P E A
T
重复
S A VE
存信
E R AS E
擦除
R E C O R D
开始录音
B E GI N
AD DR E S S
寻址
S E ND
发信
M AI N
语音信箱
R E C O R D
记录
M E S S AG E
记录语音
R E C O R D
M AI N _ S
T
R E VI E W _ S
T
R E P E AT _ S
T S A VE _ S T E R AS E _ S T M E S S AG E _ S T B I GI N _ R E C _ S T
R E C O R D _ S T
AD DR E S S _ S
T
S E ND _ S T
第 6章 VHDL设计应用实例正常起始状态是 MAIN_ST状态,从 MAIN_ST状态,用户选择究竟是收信息还是发信息。为了得到收阅菜单,用户在按键电话上按 1键;为了选发送信息菜单,用户在按键菜单上按 2
键。一旦用户选择了这些选项中的任何一种,下一级菜单允许用户选择执行进一步 (如存储与删除信息 )的功能。例如,如果用户先按键 1,选收阅菜单,那么再按键 2,将允许用户在收阅完时存储用户收阅过的信息。
第 6章 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;
第 6章 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
第 6章 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
第 6章 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;
第 6章 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
第 6章 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;
第 6章 VHDL设计应用实例
END IF;
END CASE;
END PROCESS;
PROCESS
BEGIN
WAIT UNTIL (CLK'EVENT AND CLK = '1');
CURRENT_STATE<=NEXT_STATE;
END PROCESS;
END ART;
第 6章 VHDL设计应用实例程序包 VM_PACK含有对状态值的类型说明和语音信箱控制系统允许用的键盘。必须指出的是,状态是用来表示某些事件的全过程,而事件的全过程又是由它所对应状态 (如 STATE1、
STATE2和 STATE3 等 )来说明,用状态描述将使模块的可读性更好。
为了实用,这个程序包实体标明了局部信号和键输入端口。
该实体只有一种输入 (即键输入 ),由按键电话的键盘示出可能的键字,实体除 KEY和 CLK之外,所有其他的端口都是输出端口,并且用这些端口控制语音信箱系统的工作。
第 6章 VHDL设计应用实例
6.10 PID控制器的设计
1.设计思路要求设计一个 PID控制器,对电机转速进行采样,与额定的转速进行比较,并通过微积分计算得到电机的控制电流,从而实现对电机转速的调整。通常,PID控制器用模拟电路实现,但数字电路的实现方案可以很方便地实现集成。
该 PID控制器包括一个完成算术和逻辑功能的 ALU以及一个存储状态变量和有关系数的存储器。其端口说明如图 6.12 所示。
第 6章 VHDL设计应用实例图 6.12 PID控制器示意图
R E S E T
H O S T I N T E R R U P T
F S I G N I N
I R E F K O U T
P O S I T I O N C H A N G E
P I D 控制器第 6章 VHDL设计应用实例其中,RESET 端口为复位端口,当 RESET为高电平时,
PID控制器复位; FSIGNIN为输入的偏差方向,转速超过额定转速时为‘ 1?,否则为‘ 0?; HOSTINTERRUPT为主机请求信号,
当此信号为‘ 1?时,PID开始计算,为‘ 0?时,则停止计算并输出结果。 POSITIONCHANGE为电机向 PID控制器发送的脉冲信号,每转过一周,POSITONCHANGE 出现一个脉冲;
IREFKOUT为最终输出的控制电流值。
主机向 PID控制器发调用请求 HOSTINTERRUPT之后,PID
控制器进行采样并开始计算,当 HOSTINTERRUPT信号停止时,
PID控制器停止采样计算,并将计算结果输出到主机。
第 6章 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线性相加得到控制电流值。然后,在下一个时钟周期将该控制电流值输出到主机。
第 6章 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
第 6章 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;
第 6章 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);
第 6章 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);
第 6章 VHDL设计应用实例
PROCESS
VARIABLE N,EK_1,IK,EK,KP,KI,KD,FREF,REAL;
VARIABLE FK,DEK,IREFK,TEMP,REAL;
VARIABLE DONE,BIT;
第 6章 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;
第 6章 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;
第 6章 VHDL设计应用实例
PROCEDURE WAITRESULT(X,OUT REAL; Y,OUT BIT) IS
BEGIN
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
第 6章 VHDL设计应用实例
BEGIN
X,= VAL_ROM(0);
END GETCONSTKP;
PROCEDURE GETCONSTKI(X,OUT REAL) IS
BEGIN
X,= VAL_ROM(1);
END GETCONSTKI;
PROCEDURE GETCONSTKD(X,OUT REAL) IS
BEGIN
X,= VAL_ROM(2);
END GETCONSTKD;
PROCEDURE GETFREF(X,OUT REAL) IS
BEGIN
X,= VAL_ROM(3);
第 6章 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;
第 6章 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;
第 6章 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;
第 6章 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;
第 6章 VHDL设计应用实例
6.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所示。
第 6章 VHDL设计应用实例图 6.13 空调有限状态自动机原理方框图空调有限状态自动机
H E A T
T E M P _ L O W
T E M P _ H I G H
C O O L
第 6章 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;
第 6章 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
第 6章 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;
第 6章 VHDL设计应用实例
6.12 闹钟系统的设计
6.12.1 闹钟系统的设计要求及设计思路要求设计一个带闹钟功能的 24小时计时器,计时器的外观如图 6.14所示。它包括以下几个组成部分:① 显示屏,由 4个七段数码管组成,用于显示当前时间 (时:分 )或设置的闹钟时间;②
数字键‘ 0?~‘ 9?,用于输入新的时间或新的闹钟时间;③
TIME(时间 )键,用于确定新的时间设置;④ ALARM(闹钟 )键,
用于确定新的闹钟时间设置,或显示已设置的闹钟时间;⑤ 扬声器,在当前时钟时间与闹钟时间相同时,发出蜂鸣声。
第 6章 VHDL设计应用实例图 6.14 计时器外观
0 1 2 3
654
7 8 9
A L A R M
T I M E
第 6章 VHDL设计应用实例该计时器设计要求完成如下功能:
(1) 计时功能:这是本计时器设计的基本功能,每隔一分钟计时一次,并在显示屏上显示当前时间。
(2) 闹钟功能:如果当前时间与设置的闹钟时间相同,则扬声器发出蜂鸣声。
(3) 设置新的计时器时间:用户用数字键‘ 0?~‘ 9?输入新的时间,然后按 "TIME"键确认。在输入过程中,输入数字在显示屏上从右到左依次显示。例如,用户要设置新的时间 12,34,
则按顺序输入,1”,,2”,,3”,,4”键,与之对应,显示屏上依次显示的信息为:,1”,,12”,,123”,,1234"。如果用户在输入任意几个数字后较长时间内,例如 5 s,没有按任何键,
则计时器恢复到正常的计时显示状态。
第 6章 VHDL设计应用实例
(4) 设置新的闹钟时间:用户用数字键,0”~“9”输入新的时间,然后按,ALARM”键确认。过程与 (3)类似。
(5) 显示所设置的闹钟时间:在正常计时显示状态下,用户直接按下,ALARM”键,则已设置的闹钟时间将显示在显示屏上。
根据上述的设计要求,整个系统大致包括如下几个组成部分:用于键盘输入的缓冲器;用于时钟计数的计数器;用于保存闹钟时间的寄存器;用于显示的七段数码显示电路以及控制以上各个部分协同工作的控制器。
第 6章 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”
键。
第 6章 VHDL设计应用实例图 6.15 控制器的外部端口
A L A R M _ C O N T R O L L E R
K E Y
A L A R M _ B U T T O N
T I M E _ B U T T O N
C L K
R E S E T
L O A D _ N E W _ A
L O A D _ N E W _ C
S H O W _ N E W _ T I M E
S H O W _ A
第 6章 VHDL设计应用实例
(5) 当 LOAD_NEW_A 为高电平时,控制 (闹钟时间寄存器 )
加载新的闹钟时间值。
(6) 当 LOAD_NEW_C为高电平时,控制 (时钟计数器 )设置新的时间值。
(7) 当 SHOW_NEW_TIME为高电平时,控制 (七段数码显示电路 )显示新的时间值,即用户通过数字键输入的时间;否则,
当 SHOW_NEW_TIME为低电平时,根据 SHOW_A信号的值控制显示当前时间或闹钟时间。此时,当 SHOW_A为高电平时,
控制显示闹钟时间,否则,显示当前时间。
第 6章 VHDL设计应用实例控制器的功能可以通过有限状态自动机 (FSM)的方式来实现。根据设计要求及端口设置,需要 5个状态来实现:
S0,表示电路初态即正常时钟计数状态,完成前面设计功能 (1) 的工作。
S1:接收键盘输入状态。在状态 S0时用户按下数字键后进入此状态。在此状态下,显示屏上显示的是用户键入的数字。
S2:设置新的闹钟时间。在状态 S1时用户按下 ALARM键后进入此状态。
S3:设置新的计时器时间。在状态 S1时用户按下 TIME键后进入此状态。
第 6章 VHDL设计应用实例
S4:显示闹钟时间。在状态 S0时用户直接按下 ALARM键后进入此状态。在此状态下,显示屏上显示的是所设置的闹钟时间。注意:在此状态下,用户按下 ALARM键后,显示屏上保持显示闹钟时间,经过一段时间以后,再返回状态 S0显示计时器时间。
第 6章 VHDL设计应用实例表 6.1 控制器状态转换及控制输出表当前状态 控制输入 ( 条件 ) 下一状态 控制输出 ( 动作 )
K E Y =?1? S1 S H O W _ N E W _ T IM E < =?1?
A L A R M _ B U T T O N =?1? S4 S H O W _ A < =?1? S0
否则 S0 --
K E Y =?1? S1 S H O W _ N E W _ T IM E < =?1?
A L A R M _ B U T T O N =?1? S2 L O A D _ N E W _ A < =?1?
T IM E _ B U T T O N =?1? S3 L O A D _ N E W _ C < =?1?
否
S1
S H O W _ N E W _ T IM E < =?1?,,超时,判断处理
S1
否则 ( 超时 )
是 S0 --
A L A R M _ B U T T O N =?1? S2 L O A D _ N E W _ A < =?1?
S2
否则 S0 --
T IM E _ B U T T O N =?1? S3 L O A D _ N E W _ C < =?1?
S3
否则 S0 --
A L A R M _ B U T T O N =?1? S4 S H O W _ A < =?1?
否 S4 S H O W _ A < =?1?,,超时,判断处理 S4
否则 ( 超时 )
是 S0 --
第 6章 VHDL设计应用实例表 6.1中没有显式说明的控制信号赋值,表示信号的值为零。例如在状态 S0,当信号 KEY =?1?时,SHOW_NEW_TIME
信号的赋值为‘ 1?,而其他信号 LOAD_NEW_A,
LOAD_NEW_C和 SHOW_A的值此时都赋为‘ 0?。另外,表中关于“超时”判断处理的处理细节见 VHDL源程序中的有关部分。
第 6章 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;
第 6章 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
第 6章 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;
第 6章 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';
第 6章 VHDL设计应用实例
CASE CURR_STATE IS
WHEN 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;
第 6章 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';
第 6章 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;
第 6章 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';
第 6章 VHDL设计应用实例
END IF;
ENABLE_COUNT_A <= '1';
END IF;
WHEN OTHERS =>
NULL;
END CASE;
END PROCESS;
第 6章 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;
第 6章 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;
第 6章 VHDL设计应用实例
6.12.3 闹钟系统的译码器的设计
1.设计思路本模块的功能是将每次按下闹钟系统的数字键盘后产生的一个数字所对应的 10位二进制数据信号转换为 1位十进制整数信号,以作为小时、分钟计数的 4个数字之一,如图 6.16所示。
其中 KEYPAD为输入端口,接收 10位二进制数据信号;
VALUE为输出端口,输出相应的 1位十进制整数信号。输入数据与输出数据的译码关系见表 6.2。
第 6章 VHDL设计应用实例图 6.16 电路系统示意图
K EY P A D
D EC O D ER
V A LU E
第 6章 VHDL设计应用实例表 6.2 输入、输出数据的译码关系输入 0000000001 0000000010 0000000100 0000001000 0000010000
输出 0 1 2 3 4
输入 0000100000 0001000000 0010000000 0100000000 1000000000
输出 5 6 7 8 9
第 6章 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 IS
BEGIN
第 6章 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;
第 6章 VHDL设计应用实例
6.12.4 闹钟系统的移位寄存器的设计
1.设计思路本模块的功能是在 CLK端口输入信号的上升沿同步下,将
KEY端口的输入信号移入 NEW_TIME 端口的输出信号最低位,
原有信息依次向左移,最高位信息丢失;而 RESET端口的输入信号对 NEW_TIME端口输出信号进行异步清零复位。电路系统示意图如图 6.17所示。
第 6章 VHDL设计应用实例图 6.17 移位寄存器电路示意图
K EY
C LK
K EY _ B U F F ER
N EW _ T I M ER ES E T
第 6章 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
第 6章 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;
第 6章 VHDL设计应用实例
6.12.5 闹钟系统的闹钟寄存器和时间计数器的设计
1.电路系统工作原理闹钟寄存器模块的功能是在时钟上升沿同步下,根据 LOAD
_NEW _A端口的输入信号控制 ALARM _TIME端口的输出,当控制信号有效 (高电平 )时,把 NEW _ALARM _TIME端口的输入信号值输出;而 RESET端口输入信号对 ALARM _TIME 端口的输出进行异步的清零复位。图 6.18是闹钟寄存器模块的示意图。
闹钟系统的闹钟时间由闹钟寄存器保存和传递,而当前时间由时间计数器保存、传递并按分钟累加推进。这两个组件的功能和设计描述比较相似,它们之间的区别主要在于自动累加功能的有无和控制信号的优先作用次序。
第 6章 VHDL设计应用实例图 6.18 闹钟寄存器示意图
LO A D _ N EW _ A
N EW _ A LA R M _ T I M E
C LK
R ES E T
A LA R M _ T I M E
A LA R M _ R EG
第 6章 VHDL设计应用实例时间计数器模块的功能是当 RESET端口输入信号为高电平时,对 CURRENT _TIME端口输出信号清零复位;当 LOAD
_NEW _C端口输入信号为高电平时,将
NEW_CURRENT_TIME端口的输入信号输出给
CURRENT_TIME端口。 RESET端口 D的控制优先于 LOAD
_NEW _C端口。当这两个控制信号都无效时,在时钟上升沿同步下,对 CURRENT _TIME端口输出信号累加 1,并根据小时、
分钟的规律处理进位。图 6.19是时间计数器模块的示意图。
第 6章 VHDL设计应用实例图 6.19 时间计数器模块的示意图
C L K
R E S E T
C U R R E N T _ T I M E
A L A R M _ C O U N T E R
L O A D _ N E W _ C
N E W _ C U R R E N T _ T I M E
第 6章 VHDL设计应用实例
2,VHDL源程序
--时间计数器的源程序 ALARM_COUNTER.VHD
LIBRARY 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);
第 6章 VHDL设计应用实例
END ALARM_COUNTER;
ARCHITECTURE ART OF ALARM_COUNTER IS
SIGNAL I_CURRENT_TIME,T_CLOCK_TIME;
BEGIN
PROCESS(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
第 6章 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;
第 6章 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;
第 6章 VHDL设计应用实例
END IF;
END PROCESS;
CURRENT_TIME <= I_CURRENT_TIME;
END ART;
--闹钟寄存器的源程序 ALARM_REG.VHD
LIBRARY 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;
第 6章 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;
第 6章 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;
第 6章 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为显示驱动器示意图。
第 6章 VHDL设计应用实例图 6.20 显示驱动器示意图
A LA R M _ T I M E
S H O W _ N E W _ TI M E
S O U N D _ A LA R M
D I S P LA Y _ D R I V E R
C U R R E N T _ TI M E
N EW _ T I M E
D I S P LA Y
S H O W _ A
第 6章 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);
第 6章 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;
第 6章 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!”
第 6章 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;
第 6章 VHDL设计应用实例
6.12.7 闹钟系统的分频器的设计
1.设计思路本模块的功能是将 CLK_IN端口输入的时钟信号分频后送给
CLK_OUT端口。当 RESET端口输入信号有效 (高电平 )时,
CLK_OUT端口输出信号清零。图 6.21为分频器示意图。
第 6章 VHDL设计应用实例图 6.21 分频器示意图
C LK _ I N
F Q _ D I V I D E R
C LK _ O U TR ES E T
第 6章 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
第 6章 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';
第 6章 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 CLK
END ART;
第 6章 VHDL设计应用实例
6.12.8 闹钟系统的整体组装
1.整体组装说明前边已经完成了计时器各个组成部分的设计,下面把这些组成部分组装起来,形成完整的总体设计。该计时器命名为
ALARM_CLOCK,其外部端口如图 6.22所示。
第 6章 VHDL设计应用实例图 6.22 计时器的外部端口
A L A R M _ B U T T O N
T I M E _ B U T T O N
S O U N D _ A L A R M
A L A R M _ C L O C K
K E Y _ D O W N
K E Y P A D
D I S P L A Y
C L K
R E S E T
第 6章 VHDL设计应用实例各个输入输出端口的作用如下:
(1) CLK为外部时钟信号,RESET为复位信号。
(2) KEYPAD是一个 10位信号,若其中某一位为高电平,
则表示用户按下了相应下标的数字键。例如,若 KEYPAD(5)
= '1',表示用户按下了数字键,5”。本设计不考虑用户同时按下多个数字键的情况,所以任意时刻 KEYPAD中只能有一位为‘ 1?。
(3) 当 KEYDOWN为高电平时 (KEYDOWN= '1'),表示用户按下某一数字键。
第 6章 VHDL设计应用实例
(4) 当 ALARM_BUTTON为高电平时,表示用户按下
ALARM键。
(5) 当 TIME_BUTTON为高电平时,表示用户按下 TIME键。
(6) DISPLAY实际上表示了 4个七段数码显示管,用于显示时间,如 12,20。
(7) SOUND_ALARM用于控制扬声器发声,当
SOUND_ALARM = '1' 时,扬声器发出蜂鸣,表示到了设定的闹钟时间。
设计的总体结构图如图 6.23所示。
第 6章 VHDL设计应用实例图 6.23 总体结构第 6章 VHDL设计应用实例下面再简要说明各组成部分的功能:
(1) 译码器 (DECODER) 可将 KEYPAD信号转换为 0~9的整型数,以直观地表示和处理用户输入的数字。
(2) 键盘缓冲器 (KEY_BUFFER)是一个移位寄存器,暂存用户键入的数字,并且实现用户键入数字在显示器上从右到左的依次显示。这里需要注意的是,由图 6.23可以看出,
KEY_BUFFER的时钟端连接的是外部 KEY_DOWN 信号。这表示用户每输入一个数字,KEY_BUFFER移位一次。
第 6章 VHDL设计应用实例
(3) 分频器 (FQ_DIVIDER)将较高速的外部时钟频率分频成每分钟一次的时钟频率,以便进行时钟计数。
(4) 计数器 (ALARM_COUNTER)实际上是一个异步复位、
异步置数的累加器,通常情况下进行时钟累加计数,必要时可置入新的时钟值,然后从该值开始新的计数。
(5) 寄存器 (ALARM_REG)用于保存用户设置的闹钟时间,
是一个异步复位寄存器。
第 6章 VHDL设计应用实例
(6) 显示器 (DISPLAY_DRIVER)根据需要显示当前时间、
用户设置的闹钟时间或用户通过键盘输入的新的时间,同时判断当前时间是否已到了闹钟时间,实际上是一个多路选择器加比较器。
(7) 控制器 (ALARM_CONTROLLER)是设计的核心部分,
按设计要求产生相应的控制逻辑,以控制其他各部分的工作。
第 6章 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;
第 6章 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 --待调用元件端口定义
...
第 6章 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;
第 6章 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);
第 6章 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;
第 6章 VHDL设计应用实例
6.12.9 闹钟系统的硬件验证若用 GW48型 EDA实验开发系统进行硬件验证,考虑到实验开发系统提供的输入信号按键的有限,可将输入数字按键
0~ 9改为一个按键,该按键的信号作为一个 8421码信号发生器的输入,由 8421码信号发生器输出数字 0~ 9。具体验证方案由读者自行完成。