Professional Documents
Culture Documents
第1章 硬件描述语言VHDL
第1章 硬件描述语言VHDL
数字系统设计分为硬件设计和软件设计, 但是随着计算机技术、超大规模集成电路
(CPLD、FPGA)的发展和硬件描述语言(HDL, Hardware Description Language)的出现,
软、硬件设计之间的界限被打破,数字系统的硬件设计可以完全用软件来实现,只要掌握
了 HDL 语言就可以设计出各种各样的数字逻辑电路。
程是否能达到系统设计规格书的要求。
第二个层次是数据流描述,又称为寄存器描述或 RTL 方式描述,该描述比行为描述更
注重硬件的具体实现,通过该描述可以导出系统的逻辑表达式,为逻辑综合作准备,当然
进行逻辑综合和逻辑综合工具的能力有关,当然设计人员还必须了解逻辑综合工具的说明
和规定,
第三个层次为逻辑综合。该层次把 RTL 描述的程序转换成基本逻辑元件表示的文件,该
文件就象老的设计方法中的电原理图。
(2)采用大量的 ASIC 芯片
(3)早期仿真以 确定系统 的可行性
(4)使设计更容 易
只需写出系 统的 HDL 源程序 文件,其 它由计算 机去做
(5)全部设计文 件就是 HDL 源程序文件
1.4 .1 基本设计单 元
VHDL 的基本设计单元就是实体,无论数字电路复杂还是简单,都是由实体和构造体
组成。
(1) 实体说 明
实体说明有如下结构:
ENTITY 实体名 IS
[端口说明]
END 实体名;
(VHDL 语言中不分大小写字母)
2
太原理工大学 夏路易
其中:
端口说明是对设计实体中输入和输出借口进行描述,格式如下:
PORT(端口名(,端口名):方向 数据类型名;
:
:
端口名(,端口名):方向 数据类型名);
端口名是赋予每个系统引脚的名称,一般用几个英文字母组成。
端口方向是定义引脚是输入还是输出,见下表:
方向 说明
IN 输入到实体
OUT 从实体输出输出
INOUT 双向
BUFFER 输出(但可以反馈到实体内部)
LINKAGE 不指定方向
3
太原理工大学 夏路易
(2) 构造体
构造体是实体的一个重要部分,每一个实体都有一个或一个以上的构造体。
1) 一般说明
构造体格式如下:
ARCHITECTURE 构造体名 OF 实体名 IS
[定义语句] 内部信号,常数,数据类型,函数等的定义
BEGIN
[并行处理语句]
END 构造体名;
例:
ENTITY nax IS
PORT(a0,a1 : IN BIT;
Sel : IN BIT;
Sh : OUT BIT);
END nax;
ARCHITECTURE dataflow OF nax IS
BEGIN
sh<=(a0 AND sel) OR (NOT sel AND a1);
END dataflow;
构造体描述设计实体的具体行为,它包含两类语句:
并行语句 并行语句总是在进程语句(PROCESS)的外部,该语句的执行与书写顺
序无关,总是同时被执行
顺序语句 顺序语句总是在进程语句(PROCESS)的内部,从仿真的角度,该语句
是顺序执行的
一个构造体包含几个类型的子结构描述,这些描述是:
* BLOCK 描述(块描述)
* PROCESS 描述(进程描述)
* SUNPROGRAMS 描述(子程序描述)
2) BLOCK 语句描述
使用 BLOCK 语句描述的格式如下:
块标号:BLOCK
BEGIN
:
:
4
太原理工大学 夏路易
例: 二选一电路
ENTITY mux IS
PORT (d0,d1,sel: IN BIT;
q: OUT BIT);
END mux;
ARCHITECTURE connect OF mux IS
SIGNAL tmp1,tmp2,tmp3: BIT;
BEGIN
cale:
BLOCK
BEGIN
tmp1<=d0 AND sel;
tmp2<=d1 AND (NOT sel);
tmp3<=tmp1 OR tmp2;
q<=tmp3;
END BLOCK cale;
END connect;
在对程序进行仿真时,BLOCK 中的语句是并行执行的,与书写顺序无关,这一点和构
造体中直接写的语句是一样的。
3) 进程(PROCESS)描述
进程描述的格式如下:
[进程名]:PROCESS(信号 1,信号 2,。。。 )
BEGIN
:
:
END PROCESS 进程名;
* 一般用于组合电路进程模式:
__进程标记:
PROCESS (__信号名, __信号名, __信号名)
VARIABLE __变量名 : STD_LOGIC;
VARIABLE __变量名 : STD_LOGIC;
BEGIN
5
太原理工大学 夏路易
-- 指定信号
-- 指定变量
-- 过程调用
-- 如果语句
-- CASE 语句
-- 循环语句
END PROCESS __进程标记;
* 用于时序电路进程模式:
__进程标记:
PROCESS (__信号名, __信号名, __信号名)
VARIABLE __变量名 : STD_LOGIC;
VARIABLE __变量名 : STD_LOGIC;
BEGIN
WAIT UNTIL __时钟信号 = '1';
-- 指定信号
-- 指定变量
-- 过程调用
-- 如果语句
-- CASE 语句
-- 循环语句
END PROCESS __进程标记;
例:
ENTITY mux1 IS
PORT (d0,d1,sel: IN BIT;
q : OUT BIT);
END mux1;
ARCHITECTURE connect OF mux1 IS
BEGIN
cale:
PROCESS(d0,d1,sel)
VARIABLE tmp1,tmp2,tmp3 : BIT;--在进程中定义的变量
BEGIN
tmp1:=d0 AND sel; --输入端口向变量赋值
tmp2:=d1 AND (NOT sel);
tmp3:=tmp1 OR tmp2;
6
太原理工大学 夏路易
q<=tmp3;
END PROCESS cale;
END connect;
在 PROCESS 中的语句是顺序执行的,这一点和 BLOCK 中的语句是不一样的。
当 PROCESS 所带的信号量发生变化时,PROCESS 中的语句就会执行一遍。
4)子程序描述
子程序的概念和其它高级程序中子程序的概念相同,在 VHDL 中有两种类型:
过程(Procedure)
函数(Function)
1. 过程的格式:
PROCEDURE 过程名(参数 1,参数 2。。。。) IS
[定义变量语句]
BEGIN
[顺序处理语句]
END 过程名;
例:
PROCEDURE vector_to_int
(z : IN STD_LOGIC_VECTOR;
x_flag : OUT BOOLEAN;
q : IN INTEGER) IS
BEGIN
q:=0;
x_flag:=FALSE;
FOR i IN z RANGE LOOP
q:=q*2;
IF(z(i)=1) THEN
q:=q+1;
ELSEIF (z(i)/=10) THEN
x_flag:=TRUE;
END IF;
END LOOP;
END vector_to_int;
在过程中,语句是顺序执行的。
7
太原理工大学 夏路易
2.函数
函数的格式:
FUNCTION 函数名(参数 1,参数 2。。。。) RETURN 数据类型名 IS
[定义变量语句]
BEGIN
[顺序处理语句]
RETURN [返回变量名];
END 函数名;
在 VHDL 语言中函数的参数都是输入信号,
例:
FUNCTION min(x,y:INTEGER ) RETURN INTEGER IS
BEGIN
IF X<Y THEN
RETURN(x);
ELSE
RETURN(y);
END IF;
END min;
1.4.2 2 包、库和配 置
(1) 库
库是经编译后的数据的集合,它存放包定义、实体定义、构造定义和配置定义。
在设计单元内的语句可以使用库中的结果,所以,库的好处就是设计者可以共享已经
编译的设计结果,在 VHDL 中有很多库,但他们相互独立。
IEEE 库:在 IEEE 库中有一个 STD_LOGIC 的包,它是 IEEE 正式认可的包。
STD 库:STD 库是 VHDL 的标准库,在库中有名为 STANDARD 的包,还有 TEXTIO 包。若使用
STANDARD 包中的数据可以不按标准格式说明,但是若使用 TEXTIO 包,则需要按照如下格
式说明:
LIBRARY STD;
USE STD.TEXTIO.ALL
另外还有 ASIC 库、WORK 库和用户自定义库等。
库的使用:
在使用库之前,一定要进行库说明和包说明,库和包的说明总是放在设计单元的前面:
LIBRARY 库名;
8
太原理工大学 夏路易
(2) 包
通常在一个实体中对数据类型、常量等进行的说明只可以在一个实体中使用,为使这
些说明可以在其它实体中使用,VHDL 提供了程序包结构,包中罗列 VHDL 中用到的信号定
义、常数定义、数据类型、元件语句、函数定义和过程定义,它是一个可编译的设计单元,也
是库结构中的一个层次,使用包时可以用 USE 语句说明,例如:
USE IEEE.STD_LOGIC_1164.ALL
程序包分为包头和包体,包结构的格式如下:
1) 包头格式:
PACKAGE 包名 IS
[说明语句]
END 包名
包头中列出所有项的名称。
2) 包体格式:
PACKAGE BODY 包名 IS
[说明语句]
END 包名;
包体给出各项的具体细节。
例:包头
USE STD.STD.LOGIC.ALL
PACKAGE logic IS
TYPE three_level_logic IS (‘0’,’1’,’z’); //数据类型项目
CONSTANT unknown_value : three_level_logic :=’0’;//常数项目
FUNCTION invert (input: three_level_logic)//函数项目
RETURN three_level_logic;
END logic;
例:包体
9
太原理工大学 夏路易
(2) 配置
用于在多构造体中的实体中选择构造体,例如,在做 RS 触发器的实体中使用了两个构
造体,目的是研究各个构造体描述的 RS 触发器的行为性能如何,但是究竟在仿真中使用哪
一个构造体的问题就是配置问题。
配置语句格式:
CONFIGURATION 配置名 OF 实体名 IS
[说明语句]
END 配置名;
例:最简单的配置
10
太原理工大学 夏路易
ARCHITECTURE rsff2 OF rs IS
BEGIN
q<=NOT(qb AND set);
qb<=NOT(q AND reset);
END rsff2
两个构造体,可以用配置语句进行设置:
CONFIGRATION rscon OF rs IS //选择构造体 rsff1
FOR rsff1
END FOR;
END rscon;
常数:可以在数字电路中代表电源、地线等等
变量:可以代表某些数值
1.常数
常数的描述格式:
CONSTANT 常数名:数据类型:=表达式
例:
CONSTANT Vcc: REAL:=5.0;
CONSTANT DALY: TIME:=100ns;
CONSTANT FBUS: BIT_VECTOR:=”0101”;
2.变量
变量只能在进程、函数和过程中使用,一旦赋值立即生效。
变量的描述格式:
VARIABLE 变量名:数据类型 约束条件:=表达式
例:
VARIABLE x, y: INTEGER;
VARIABLE count: INTEGER RANGE 0 TO 255:=10;
3.信号
信号除了没有方向的概念以外几乎和端口概念一致。
信号的描述格式:
SIGNAL 信号名:数据类型 约束条件:=表达式
例:
SIGNAL sys_clk: BIT:=’0’;
SIGNAL ground: BIT:=’0’
在程序中,信号值输入信号时采用代入符”<=”,而不是赋值符“:=”,同时信号可以
附加延时。
信号传送语句:
s1<=s2 AFTER 10ns
信号是一个全局量,可以用来进行进程之间的通信
4.信号与变量的区别
信号赋值可以有延迟时间,变量赋值无时间延迟
信号除当前值外还有许多相关值,如历史信息等,变量只有当前值
进程对信号敏感,对变量不敏感
信号可以是多个进程的全局信号,但变量只在定义它之后的顺序域可见
信号可以看作硬件的一根连线,但变量无此对应关系
12
太原理工大学 夏路易
例:
INTEGER RANGE 100 DOWNTO 0
BIT_ VECTOR (3 DOWNTO 0)
REAL RANGE 2.0 TO 30.0
15
太原理工大学 夏路易
制
b<=TO_STDLOGICVECTOR(X”AF7”);十六进制变换
b<=TO_STDLOGICVECTOR(O”5177”); 八进制变换
b<=TO_STDLOGICVECTOR(B”1010_1111_0111”); 三位二进制变换
优先级别 类型 操作符 说明
17
太原理工大学 夏路易
(1) 逻辑运 算符
要求运算符左右的数据类型必须相同,
例:x<=(a AND b) OR (NOT c AND d);
x<=b AND a AND d AND e;
x<=b OR c OR d OR e;
x<=a XOR d XOR e;
a<=(x1 AND x2) OR (y1 AND y2);
(2) 算数运 算符
18
太原理工大学 夏路易
在使用乘法运算符时,应该特别慎重,因为它可以使逻辑门数大大增加。
(3) 关系运 算符
应该注意小于等于<=和代入运算符的不同(从上下文区别)
(4) 并置运 算符
并置运算符 ”&” 用于位连接,
例如: y(0)=b(0)&en
y(1)=b(1)&en
y(2)=b(2)&en
y(3)=b(3)&en
y(4)=a(0)
y(5)=a(1)
y(6)=a(2)
y(7)=a(3)
从上可以看出 a,b 是四位长度的矢量,而 y 的位长是 7 位,上述情况可以表示成:
tmp_b<=b AND (en&en&en&en);
y<= a&tmp_b;
若是位连接,可以简单写为:
tmp_b<=b AND (en,en,en,en);
(1)行为描述
描述数字系统的行为,主要用于仿真和系统工作原理的研究。下面介绍一些专用语句。
1) 代入语句
格式: 信号量<=敏感信号量表达式;
例如: z<=a NOR(b NAND c);
该例中有三个敏感量,无论哪一个发生变化都可以使 z 变化。
具有时间延迟的代入语句:
a<=b AFTER 10 ns
表示当 b 发生变化 10 ns 后 a 才变化。
19
太原理工大学 夏路易
例:与门电路
ENTITY and2 IS
PORT(a,b : IN BIT;
c : OUT BIT);
END and2;
ARCHITECTURE and2_behave OF and2 IS
BEGIN
c<=a AND b;
END and2_behave;
2)延时语句
VHDL 中有两种延时语句:惯性延时和传输延时。
*惯性延时
VHDL 中惯性延时是缺省的,因为逻辑硬件电路总是有时间延迟的,若延迟时间是
20ns,那末输入信号时间若小于 20ns,则输出信号将不跟随输入信号的变化。
有时为使延迟时间更逼真实际电路,就专门设置惯性时间:
b<=a AFTER 10 ns;
* 传输延时
传输延时常代表总线、连接线的延迟时间,该时间必须专门说明。该传输延时只对信号
起纯延时作用。
例: b<=TRANSPORT a AFTER 20 ns;
BEGIN
y<=input(0) WHEN sel=0 ELSE
input(1) WHEN sel=1 ELSE
input(2) WHEN sel=2 ELSE
input(3);
END app;
使用数据流描述方式应该注意的问题:
1.‘X’状态的传递问题
有时‘X’状态会逐级传递,造成系统的输出为不确定或者错误,所以要在设计中考虑
‘X’状态对输出的影响。
2. 一些限制
*禁止在一个进程中使用两个寄存器
*在 IF 语句描述寄存器时,禁止 ELSE 项
*在寄存器描述中,禁止将变量代入信号
*关连性强的信号应该放在一个进程中
例: WAIT FOR 20 ns
*多条件 WAIT 语句
例: WAIT ON nmi,interrupt UNTIL ((nmi=TRUE) OR (interrupt=TRUE)) FOR 5 us
该等待有三个条件:
第一,信号 nmi 和 interrupt 任何一个有一次刷新动作
第二, 信号 nmi 和 interrupt 任何一个为真
第三, 等待 5 us
只要一个以上的条件被满足,进程就被启动.
*超时等待
若在程序中所设置的等待条件永远不会满足,则进程就永远不能启动,为防止进入无限等待
情况,应做一些处理.
2. 断言语句(ASSERT)
格式: ASSERT 条件 [REPORT 输出信息][SEVERITY 级别]
执行到断言语句时,判断条件,若条件满足就继续执行,否则输出文字串和错误级别信息.
例: ASSERT (tiaojian=’1’)
REPORT “some thing wrong”
SEVERITY ERROR;
3. 信号代入语句
格式: 目的信号量<=信号量表达式
例: a<=b;
4. 变量赋值语句
格式: 目的变量:=表达式
例: c:=a+d
5. IF 语句
1) IF 的门闩控制
格式:IF 条件 THEN
顺序执行语句
END IF;
例:IF (a=’1’) THEN
c<=b;
END IF;
2) IF 语句的选择控制
格式一:IF 条件 THEN
顺序执行语句
ELSE
23
太原理工大学 夏路易
顺序执行语句
END IF;
格式二:IF 条件 THEN
顺序执行语句
ELSIF 条件 THEN
顺序执行语句
:
:
ELSIF 条件 THEN
顺序执行语句
ELSIF 条件 THEN
顺序执行语句
END IF;
6. CASE 语句
常用来描述总线、编码和译码的行为。
格式:
CASE 表达式 IS
WHEN 条件表达式=>顺序处理语句
END CASE;
其中 WHEN 的条件表达式可以有 4 种形式:
WHEN 值=>顺序处理语句
WHEN 值|值|值|…|值=>顺序处理语句
WHEN 值 TO 值=>顺序处理语句
WHEN OTHERS=>顺序处理语句
例:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY mux43 IS
PORT(a,b,i0,i1,i2,i3 :IN STD_LOGIC;
q : OUT STD_LOGIC);
END mux43;
BEGIN
nn: PROCESS(a,b,i0,i1,i2,i3)
BEGIN
sel<=0;
IF (a='1') THEN
sel<=sel+1;
END IF;
IF (b='1') THEN
sel<=sel+2;
END IF;
CASE sel IS
WHEN 0 =>q<=i0;
WHEN 1 =>q<=i1;
WHEN 2 =>q<=i2;
WHEN 3 =>q<=i3;
END CASE;
END PROCESS nn;
END mux4_behave;
7. LOOP 语句
格式一:
[标号]: FOR 循环变量 IN 离散范围 LOOP
顺序处理语句
END LOOP [标号];
例: ASUM: FORi IN 1 TO 9 LOOP
sum=1+sum;
END LOOP ASUM;
例:8位奇偶校验电路
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY pc IS
PORT(a : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
y : OUT STD_LOGIC);
END pc;
ARCHITECTURE behave OF pc IS
25
太原理工大学 夏路易
BEGIN
cbc: PROCESS(a)
VARIABLE tmp: STD_LOGIC;
BEGIN
tmp:='0';
FOR i IN 0 TO 7 LOOP
tmp:=tmp XOR a(i);
END LOOP;
y<=tmp;
END PROCESS cbc;
END behave;
格式二:
[标号]: WHILE 条件 LOOP
顺序处理语句
END LOOP [标号];
在该语句中,如果条件为真,则进行循环,否则结束循环.
例:
sum:=0
abcd: WHILE (I<10) LOOP
sum:=I+sum;
I:=I+1;
END LOOP abcd;
8. NEXT 语句
在 LOOP 语句中用 NEXT 语句跳出循环.
格式: NEXT [标号][WHEN 条件];
NEXT 语句用于控制内循环的结束.
例:
PROCESS (a,b)
CONSTANT max_limit: INTEGER:=255
BEGIN
FOR I IN 0 TO max_limit LOOP
IF (done(I)=TRUE) THEN
NEXT;
ELSE done(I):=TRUE;
26
太原理工大学 夏路易
END IF;
q(I)<=a(I) AND b(I);
END LOOP;
END PROCESS;
9. EXIT 语句
EXIT 语句用于结束 LOOP 循环状态.
格式: EXIT [标号] [WHEN 条件]
例:
PROCESS(a)
VARIABLE int_a :INTEGER;
BEGIN
int_a:=a
FOR I=0 IN 0 TO max_limit LOOP
IF (int_a<=0) THEN
EXIT;
ELSE
int_a:=int_a-1;
q(I)<=3.1416/REAL(a*I);
END IF
END LOOP;
y<=q;
END PROCESS;
例:四选一电路
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY mux44 IS
PORT(i0,i1,i2,i3,a,b:IN STD_LOGIC;
q : OUT STD_LOGIC);
END mux44;
ARCHITECTURE aa OF mux44 IS
SIGNAL sel: STD_LOGIC_VECTOR(1 DOWNTO 0);
BEGIN
sel<=b & a;
q<= i0 WHEN sel="00" ELSE
i1 WHEN sel="01" ELSE
28
太原理工大学 夏路易
4. 选择信号代入
格式: WITH 表达式样 SELECT
目的信号量<=表达式 1 WHEN 条件 1
表达式 2 WHEN 条件 2
:
表达式 n WHEN 条件 n;
该语句很象 CASE 语句.
例:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY mux45 IS
PORT(i0,i1,i2,i3,a,b :IN STD_LOGIC;
q : OUT STD_LOGIC);
END mux45;
ARCHITECTURE bb OF mux45 IS
SIGNAL sel: INTEGER range 0 to 3;
BEGIN
WITH sel SELECT
q<=i0 WHEN 0,
i1 WHEN 1,
i2 WHEN 2,
i3 WHEN 3;
sel<=0 WHEN a='0' AND b='0' ELSE
1 WHEN a='1' AND b='0' ELSE
2 WHEN a='0' AND b='1' ELSE
3 WHEN a='1' AND b='1' ;
END bb;
5. 并发过程调用语句
过程调用语句可以并发执行,但要注意如下问题:
并发过程调用是一个完整的语句,在它之前可以加标号
29
太原理工大学 夏路易
例 2: 2 输入或非门
30
太原理工大学 夏路易
LIBRARY ieee;
use ieee.std_logic_1164.all;
entity nor2 is
port(a,b: in std_logic;
y: out std_logic);
end nor2;
architecture nor_behave of nor2 is
begin
y<=a nor b;
end nor_behave;
例3 2 输入异或门电路
library ieee;
use ieee.std_logic_1164.all;
entity xor2 is
port(a,b: in std_logic;
y: out std_logic);
end xor2;
architecture xor_behave of xor2 is
begin
y<=a xor b;
end xor_behave;
例 4 3-8 译码器
LIBRARY ieee;
USE ieee.std_logic_1164.all;
entity decoder38 is
port(a,b,c,g1,g2a,g2b: in std_logic;
y: out std_logic_vector(7 downto 0));
end decoder38;
architecture behave38 OF decoder38 is
signal indata: std_logic_vector(2 downto 0);
begin
indata<=c&b&a;
process(indata,g1,g2a,g2b)
31
太原理工大学 夏路易
begin
if(g1='1' and g2a='0' and g2b='0') then
case indata is
when "000"=>y<="11111110";
when "001"=>y<="11111101";
when "010"=>y<="11111011";
when "011"=>y<="11110111";
when "100"=>y<="11101111";
when "101"=>y<="11011111";
when "110"=>y<="10111111";
when "111"=>y<="01111111";
when others=>y<="XXXXXXXX";
end case;
else
y<="11111111";
end if;
end process;
end behave38;
例 5 优先编码器
LIBRARY ieee;
USE ieee.std_logic_1164.all;
entity prior is
port( input: in std_logic_vector(7 downto 0);
y: out std_logic_vector(2 downto 0));
end prior;
architecture be_prior OF prior is
begin
process(input)
begin
if(input(0)='0') then
y<="111";
elsif (input(1)='0') then
y<="110";
elsif (input(2)='0') then
32
太原理工大学 夏路易
y<="101";
elsif (input(3)='0') then
y<="100";
elsif (input(4)='0') then
y<="011";
elsif (input(5)='0') then
y<="010";
elsif (input(6)='0') then
y<="001";
elsif (input(7)='0') then
y<="000";
end if;
end process;
end be_prior;
例7 四选一选择器
LIBRARY ieee;
USE ieee.std_logic_1164.all;
entity mux4 is
port( input: in std_logic_vector(3 downto 0);
a,b: in std_logic;
y: out std_logic);
end mux4;
architecture be_mux4 OF mux4 is
signal sel: std_logic_vector(1 downto 0);
begin
sel<=b&a;
process(input,sel)
begin
if(sel="00") then
y<=input(0);
elsif (sel="01") then
y<=input(1);
elsif (sel="10") then
y<=input(2);
33
太原理工大学 夏路易
else
y<=input(3);
end if;
end process;
end be_mux4;
例8 :加法器
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
ENTITY adder IS
PORT (op1, op2 : IN UNSIGNED(7 downto 0);
result : OUT INTEGER);
END adder;
ARCHITECTURE maxpld OF adder IS
BEGIN
result <= CONV_INTEGER(op1 + op2);
END maxpld;
例9 半加器
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY half IS
PORT (a, b : IN std_LOGIC;
s,co : OUT std_LOGIC);
END half;
ARCHITECTURE half1 OF half IS
signal c,d :std_logic;
BEGIN
c<=a or b;
d<=a nand b;
co<=not d;
s<=c and d;
end half1;
34
太原理工大学 夏路易
例 10 全加器,由半加器组成,以元件方式调用.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY half IS
PORT (a, b : IN std_LOGIC;
s,co : OUT std_LOGIC);
END half;
ARCHITECTURE half1 OF half IS
signal c,d:std_logic;
BEGIN
c<=a or b;
d<=a nand b;
co<=not d;
s<=c and d;
end half1;
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY full IS
PORT (a, b,cin : IN std_LOGIC;
s,co : OUT std_LOGIC);
END full;
ARCHITECTURE full1 OF full IS
component half
PORT (a, b : IN std_LOGIC;
s,co : OUT std_LOGIC);
end component;
signal u0_co,u0_s,u1_co:std_logic;
begin
u0:half port map(a,b,u0_s,u0_co);
u1:half port map(u0_s,cin,s,u1_co);
co<=u0_co or u1_co;
end full1;
例 10: 三态门
35
太原理工大学 夏路易
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY tri IS
PORT (din, en : IN std_LOGIC;
dout : OUT std_LOGIC);
END tri;
ARCHITECTURE tri1 OF tri IS
BEGIN
tri_gate: process(din,en)
begin
if (en='1') then
dout<=din;
else
dout<='Z';
end if;
end process;
end tri1;
例 11 三态单向总线
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY bufs IS
PORT (din : IN std_LOGIC_vector(7 downto 0);
dout : OUT std_LOGIC_vector(7 downto 0) bus;
en : IN std_LOGIC);
END bufs;
ARCHITECTURE bufs1 OF bufs IS
BEGIN
process(en,din)
begin
if (en='1') then
dout<=din;
else
dout<="ZZZZZZZZ";
end if;
36
太原理工大学 夏路易
end process;
end bufs1;
例 1:对于上升沿 D 触发器,其描述为:
process(clk,d)
begin
if(clk’event and clk=’1’) then
q<=d;
end if;
end process;
例 2:对于上升沿 D 触发器的另一描述为:
process
begin
wait until clk’event and clk=’1’;
q<=d;
end process;
2.复位信号
*同步复位
当复位信号有效且在给定的时钟边沿到来时,触发器才被复位.
例 1:
process (clock)
begin
if (clock_edge_condition) then
if (reset_condition) then
signal_out<=reset_value;
else
signal_out=signal_in;
:
其它语句
38
太原理工大学 夏路易
:
end if;
end if;
end process;
例 2:
process(clock)
if (clock’event and clock=’1’) then
if reset=’1’ then
count<=’0’;
else
count<=count+1;
end if;
end if;
end process;
此例中,敏感表中只有时钟信号,因为只有时钟到来时才能复位.
* 异步复位
只要复位信号有效,触发器就被复位,所以敏感表中除时钟信号外,还需要复位信号
例 1:
process(reset_signal,clock_signal)
begin
if (reset_signal) then
signal_out<=reset_value;
elsif (clock_event and clock_edge_condition) then
signal_out<=signal_in;
:
其它语句
:
end if;
end process;
例 2:
process(clock,reset)
begin
if reset=’1’ then
count<=’0’;
elsif clock’event and clock=’1’ then
39
太原理工大学 夏路易
count<=count+1;
end if;
end process;
3.触发器
1) D 锁存器
LIBRARY ieee;
use ieee.std_logic_1164.all;
entity dff1 is
port(clk,d: in std_logic;
q: out std_logic);
end dff1;
architecture dff1_behave of dff1 is
begin
process(clk)
begin
if (clk'event and clk='1') then
q<=d;
end if;
end process;
end dff1_behave;
2)异步复位 D 锁存器
LIBRARY ieee;
use ieee.std_logic_1164.all;
entity dff2 is
port(clk,d,reset: in std_logic;
q: out std_logic);
end dff2;
architecture dff2_behave of dff2 is
begin
process(clk,reset)
begin
if (reset='0') then
q<='0';
40
太原理工大学 夏路易
3) 异步复位/置位 D 锁存器
LIBRARY ieee;
use ieee.std_logic_1164.all;
entity dff3 is
port(clk,d,reset,set: in std_logic;
q: out std_logic);
end dff3;
architecture dff3_behave of dff3 is
begin
process(clk,reset,set)
begin
if (set='0') then
q<='1';
elsif (reset='0') then
q<='0';
elsif (clk'event and clk='1') then
q<=d;
end if;
end process;
end dff3_behave;
在该例中,置位优先级最高,复位次之,时钟最低.
4) 同步复位/置位 D 触发器
LIBRARY ieee;
use ieee.std_logic_1164.all;
entity dff4 is
port(clk,d,reset,set: in std_logic;
q: out std_logic);
end dff4;
41
太原理工大学 夏路易
5) 异步复/置位 D 触发器
LIBRARY ieee;
use ieee.std_logic_1164.all;
entity jk is
port(clk,j,k,reset,set: in std_logic;
q,qb: out std_logic);
end jk;
architecture jk_behave of jk is
signal q_s,qb_s: std_logic;
begin
process(clk,reset,set,j,k)
begin
if (set='0')and (reset='1') then
q_s<='1';
qb_s<='0';
elsif (set='1')and (reset='0') then
q_s<='0';
qb_s<='1';
elsif (clk'event and clk='1') then
42
太原理工大学 夏路易
6)寄存器例
ENTITY reginf IS
PORT
(
d, clk, clr, pre, load, data : IN BIT;
q1, q2, q3, q4, q5, q6, q7 : OUT BIT
);
END reginf;
--低电平时钟触发
43
太原理工大学 夏路易
PROCESS
BEGIN
WAIT UNTIL clk = '0';
q2 <= d;
END PROCESS;
--上升沿触发/同步清除
PROCESS (clk, clr)
BEGIN
IF clr = '1' THEN
q3 <= '0';
ELSIF clk'EVENT AND clk = '1' THEN
q3 <= d;
END IF;
END PROCESS;
--下降沿触发/同步清除
PROCESS (clk, clr)
BEGIN
IF clr = '0' THEN
q4 <= '0';
ELSIF clk'EVENT AND clk = '0' THEN
q4 <= d;
END IF;
END PROCESS;
--上升沿触发/同步预置”1”
PROCESS (clk, pre)
BEGIN
IF pre = '1' THEN
q5 <= '1';
ELSIF clk'EVENT AND clk = '1' THEN
q5 <= d;
END IF;
END PROCESS;
--上升沿触发/同步预置数据
44
太原理工大学 夏路易
--上升沿触发/同步置”1”和清除
PROCESS (clk, clr, pre)
BEGIN
IF clr = '1' THEN
q7 <= '0';
ELSIF pre = '1' THEN
q7 <= '1';
ELSIF clk'EVENT AND clk = '1' THEN
q7 <= d;
END IF;
END PROCESS;
END maxpld;
7) D 触发器组成的 8 位移位寄存器.
LIBRARY ieee;
use ieee.std_logic_1164.all;
entity shift8 is
port(a,clk: in std_logic;
b: out std_logic);
end shift8;
architecture shift_behave of shift8 is
signal df1,df2,df3,df4,df5,df6,df7: std_logic;
begin
process(clk)
begin
45
太原理工大学 夏路易
LIBRARY ieee;
use ieee.std_logic_1164.all;
entity ttl74166 is
port(reset,s1,fe,clk,se,a,b,c,d,e,f,g,h: in std_logic;
q: out std_logic);
end ttl74166;
architecture behave of ttl74166 is
signal tmpreg8: std_logic_vector(7 downto 0);
begin
process(clk,reset,s1,fe)
begin
if (reset='0') then --
tmpreg8<="00000000";
46
太原理工大学 夏路易
q<=tmpreg8(7);
elsif (clk'event) and (clk='1') then
if (fe='0') then
if (s1='0') then
tmpreg8(0)<=a;
tmpreg8(1)<=b;
tmpreg8(2)<=c;
tmpreg8(3)<=d;
tmpreg8(4)<=e;
tmpreg8(5)<=f;
tmpreg8(6)<=g;
tmpreg8(7)<=h;
elsif (s1='1') then
for i in tmpreg8'high downto tmpreg8'low+1 loop
tmpreg8(i)<=tmpreg8(i-1);
end loop;
tmpreg8(tmpreg8'low)<=se;
q<=tmpreg8(7);
end if;
end if;
end if;
end process;
end behave;
9) 十二进制同步计数器
引脚定义:
reset 复位
en 计数控制
clk 时钟
qa,qb,qc,qd 计数器输出
LIBRARY ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity count12 is
47
太原理工大学 夏路易
port(clk,reset,en: in std_logic;
qa,qb,qc,qd: out std_logic);
end count12;
10) 4 位二进制可逆计数器
管脚定义: reset 复位
clk 时钟
updn 加减计数控制
qa,qb,qc,qd 输出
LIBRARY ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
48
太原理工大学 夏路易
entity updown is
port(clk,reset,updn: in std_logic;
qa,qb,qc,qd: out std_logic);
end updown;
architecture behave of updown is
signal count_6: std_logic_vector(3 downto 0);
begin
qa<=count_6(0);
qb<=count_6(1);
qc<=count_6(2);
qd<=count_6(3);
process(clk,reset)
begin
if (reset='1') then
count_6<="000000";
elsif(clk'event and clk='1') then
if(updn='1') then
count_6<=count_6+'1';
else
count_6<=count_6-'1';
end if;
end if;
end process;
end behave;
11)可预置数的六十进制计数器
管脚定义:
clk 时钟
bcd1wr 个位预置数控制
bcd10wr 十位预置数控制
datain 预置数据
cin 进位输入(计数脉冲)
co 进位输出
bcd1p 个位数据输出
bcd10p 十位数据输出
49
太原理工大学 夏路易
LIBRARY ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity count60 is
port(clk,bcd1wr,bcd10wr,cin: in std_logic;
co: out std_logic;
datain: in std_logic_vector(3 downto 0);
bcd1p: out std_logic_vector(3 downto 0);
bcd10p: out std_logic_vector(2 downto 0));
end count60;
kk2: process(clk,bcd10wr)
begin
if (bcd10wr='1') then
50
太原理工大学 夏路易
kk3: process(bcd10n,bcd1n,cin)
begin
if(cin='1' and bcd1n="1001" and bcd10n="101") then
co<='1';
else
co<='0';
end if;
end process kk3;
end behave;
12) 各种计数器例
ENTITY counter IS
PORT
(
d : IN INTEGER RANGE 0 TO 255; --预置数据
clk : INBIT;--时钟信号
clear : INBIT;--计数器清零
ld : INBIT;--计数器预置数
enable : INBIT;--计数使能
up_down : INBIT;--计数器加减控制
qa : OUT INTEGER RANGE 0 TO 255;--输出端
qb : OUT INTEGER RANGE 0 TO 255; :
qc : OUT INTEGER RANGE 0 TO 255; :
51
太原理工大学 夏路易
END counter;
ARCHITECTURE a OF counter IS
BEGIN
-- 有使能端的计数器
PROCESS (clk)
VARIABLEcnt : INTEGER RANGE 0 TO 255;
BEGIN
IF (clk'EVENT AND clk = '1') THEN
IF enable = '1' THEN
cnt := cnt + 1;
END IF;
END IF;
qa <= cnt;
END PROCESS;
--同步预置数计数器
PROCESS (clk)
VARIABLEcnt : INTEGER RANGE 0 TO 255;
BEGIN
IF (clk'EVENT AND clk = '1') THEN
52
太原理工大学 夏路易
IF ld = '0' THEN
cnt := d;
ELSE
cnt := cnt + 1;
END IF;
END IF;
qb <= cnt;
END PROCESS;
--同步清除计数器
PROCESS (clk)
VARIABLEcnt : INTEGER RANGE 0 TO 255;
BEGIN
IF (clk'EVENT AND clk = '1') THEN
IF clear = '0' THEN
cnt := 0;
ELSE
cnt := cnt + 1;
END IF;
END IF;
qc <= cnt;
END PROCESS;
--加减计数器
PROCESS (clk)
VARIABLE cnt : INTEGER RANGE 0 TO 255;
VARIABLE direction : INTEGER;
BEGIN
IF (up_down = '1') THEN
direction := 1;
ELSE
direction := -1;
END IF;
--同步预置/计数控制计数器
PROCESS (clk)
VARIABLE cnt : INTEGER RANGE 0 TO 255;
BEGIN
IF (clk'EVENT AND clk = '1') THEN
IF ld = '0' THEN
cnt := d;
ELSE
IF enable = '1' THEN
cnt := cnt + 1;
END IF;
END IF;
END IF;
qe <= cnt;
END PROCESS;
--计数控制的加减计数器
PROCESS (clk)
VARIABLE cnt : INTEGER RANGE 0 TO 255;
VARIABLE direction : INTEGER;
BEGIN
IF (up_down = '1') THEN
direction := 1;
ELSE
direction := -1;
END IF;
END IF;
END IF;
qf <= cnt;
END PROCESS;
--同步清除/计数控制计数器
PROCESS (clk)
VARIABLE cnt : INTEGER RANGE 0 TO 255;
BEGIN
IF (clk'EVENT AND clk = '1') THEN
IF clear = '0' THEN
cnt := 0;
ELSE
IF enable = '1' THEN
cnt := cnt + 1;
END IF;
END IF;
END IF;
qg <= cnt;
END PROCESS;
--同步预置/清除计数器
PROCESS (clk)
VARIABLE cnt : INTEGER RANGE 0 TO 255;
BEGIN
IF (clk'EVENT AND clk = '1') THEN
IF clear = '0' THEN
cnt := 0;
ELSE
IF ld = '0' THEN
cnt := d;
ELSE
cnt := cnt + 1;
END IF;
END IF;
55
太原理工大学 夏路易
END IF;
qh <= cnt;
END PROCESS;
--同步预置/加减计数器
PROCESS (clk)
VARIABLE cnt : INTEGER RANGE 0 TO 255;
VARIABLE direction : INTEGER;
BEGIN
IF (up_down = '1') THEN
direction := 1;
ELSE
direction := -1;
END IF;
--同步预置/计数控制/加减计数器
PROCESS (clk)
VARIABLEcnt : INTEGER RANGE 0 TO 255;
VARIABLEdirection : INTEGER;
BEGIN
IF (up_down = '1') THEN
direction := 1;
ELSE
direction := -1;
END IF;
56
太原理工大学 夏路易
--同步清除/预置/计数控制计数器
PROCESS (clk)
VARIABLEcnt : INTEGER RANGE 0 TO 255;
BEGIN
IF (clk'EVENT AND clk = '1') THEN
IF clear = '0' THEN
cnt := 0;
ELSE
IF ld = '0' THEN
cnt := d;
ELSE
IF enable = '1' THEN
cnt := cnt + 1;
END IF;
END IF;
END IF;
END IF;
qk <= cnt;
END PROCESS;
--同步清除/加减计数器
PROCESS (clk)
57
太原理工大学 夏路易
--同步清除/计数控制/加减计数器
PROCESS (clk)
VARIABLEcnt : INTEGER RANGE 0 TO 255;
VARIABLEdirection : INTEGER;
BEGIN
IF (up_down = '1') THEN
direction := 1;
ELSE
direction := -1;
END IF;
13) 直接调用小规模数字电路例
LIBRARY altera;
USE altera.maxplus2.ALL;--使用 Altera 的元件库
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY compinst IS
PORT
(
data, clock, clearn, presetn : INSTD_LOGIC;
q_out : OUT STD_LOGIC;
59
太原理工大学 夏路易
a, b, c, gn : INSTD_LOGIC;
d : INSTD_LOGIC_VECTOR(7 DOWNTO 0);
y, wn : OUT STD_LOGIC
);
END compinst;
ARCHITECTURE a OF compinst IS
BEGIN
--D 触发器
dff1 : dff PORT MAP (d =>data, q => q_out, clk => clock, clrn => clearn,
prn => presetn);
--TTL74151
mux : a_74151b PORT MAP (c, b, a, d, gn, y, wn);
END a;
14) 选择信号
如果 sel 信号为”1”时,选择信号 input1,否则选择信号 input0.
ENTITY condsig IS
PORT
(
input0, input1, sel : IN BIT;
output : OUT BIT
);
END condsig;
ARCHITECTURE maxpld OF condsig IS
BEGIN
output <= input0 WHEN sel = '0' ELSE input1;
END maxpld;
15) 三信号分别控制输出数值
输入信号 high =1 输出 q=3
mid=1 输出 q=2
low=1 输出 q=1
ENTITY condsigm IS
60
太原理工大学 夏路易
PORT
(
high, mid, low : IN BIT;
q : OUT INTEGER
);
END condsigm;
BEGIN
PROCESS
BEGIN
WAIT UNTIL clock'EVENT and clock = '1';
present_state <= next_state;
END PROCESS;
END firstenumsmch;
16) 状态机例
ENTITY statmach IS
PORT(
clk : INBIT;
input : INBIT;
reset : INBIT;
output : OUT BIT);
END statmach;
ARCHITECTURE a OF statmach IS
TYPE STATE_TYPE IS (s0, s1);
SIGNAL state: STATE_TYPE;
BEGIN
PROCESS (clk)
BEGIN
63
太原理工大学 夏路易
64