5.3 VHDL语言要素

Download Report

Transcript 5.3 VHDL语言要素

5.3 VHDL语言要素
5.3.1 标识符Identifiers
标识符:取的各种名字。
如:实体、结构体、端口、信号、变量、常数、
子程序或参数的名字。
由英文字母“a”到“z”、“A”到“Z”、数字“0”
到“9”以及下划线“_”组成。
例:a%b_1、show-new-state等是非法标识符。
注意:
1、不区分大小写;
2、须以字母开头,如20040516错误:
3、下划线只能在中间,不能以它开头或结尾,
如DEcoder_和_ Decoder错
4、下划线不能连用,如De_ _ coder错;
5、不能用关键词,如IN错;
*6、取名最好有实际意义。
5.3.2 数据类型Data Types
VHDL作为一种强类型语言,任何一种数据对
象(信号、变量、常数、函数及设定的各种
参数)必须严格限定其类型和取值范围,相
同类型才能相互传递。
VHDL的数据类型有:
标准库定义的数据类型:
IEEE预定义标准逻辑位与矢量
用户自定义的数据类型
1、标准库定义的数据类型:
在标准库STANDARD库中定义,不需要用
USE显式调用。
1)、位类型BIT
取值范围是逻辑位‘1’和‘0’。
在VHDL中,逻辑位0和1的表达必须加单引号
BIT型可以参与逻辑运算或算术运算,其结果
仍是位的数据类型。
2)、位矢量(Bit_vector):
是基于BIT数据类型的数组,
必须注明宽度,即数组中的元素的个数和排列。
如:SIGNAL a:bit_vector(7 DOWNTO 0);
SIGNAL b:bit_vector(0 TO 7);
信号a、b的数据类型被定义为一个具有8位位宽的
矢量或总线端口信号,
a的最左位,即最高位是a(7),向右依次递减为a(6)、
a(5)…a(0)。
b的最左位,即最高位是b(0),向右依次递增为b(1)、
b(2)…b(7)。
赋值方式:
*整体操作,值加双引号: a<=”01010101”;
*对其中的一位操作: a(0)<=’0’;a(7)<=’1’;
*对其中的几位操作 :
a(7 downto 1)<=a(6 downto 0);
3)、布尔类(BOOLEAN)



取值是: true(真)和false(伪)
在VHDL中分别用‘1’和‘0’表达true和false。
布尔数据不是数值,只能用于逻辑操作或
条件判断。
4)、整数(Integer):



在VHDL中,整数可取值范围从-(231-1)到
(231-1)。
要用RANGE子句为所定义整数限定范围,
以便综合器决定该信号或变量的二进制的
位数,从而分配相应的硬件资源。
在实际应用中,VHDL仿真器通常将
INTEGER类型作为有符号数处理,而
VHDL综合器则将INTEGER作为无符号数
处理。
整数常量的书写方式:
 23 十进制数23
 -4 十进制整数-4
 2E3 十进制整数2*103=2000,E代表10的次
方
 16#A0# 十六进制数A0HEX=160,格式:
进制#数据#
 2#110100101# 二进制整数
注意:不加引号,如:1、0、25等;而逻辑位的数
据必须加引号,如‘1’、‘0’、“101”。
2、IEEE预定义标准逻辑位与矢量
在IEEE的程序包std_logic_1164中定义了两个
非常重要的数据类型:
std_logic、
std_logic_vector。
注意:在使用“std_logic”和“std_logic_vector”时,
在程序中必须声明库及程序包说明语句,即下列
两句在程序中必不可少。
LIBRARY ieee ;
USE ieee.std_logic_1164.ALL
1)std_logic:




工业标准的逻辑类型,简称标准逻辑位 。
9个取值:‘0’(强0)、‘1’(强1)、‘Z’(高
阻态)、‘X’(强未知的)、‘W’(弱未知的)、
‘L’(弱0)、‘H’(弱1)、‘-’(忽略)、
‘U’(未初始化)。
std_logic较完整地概括了数字系统中所有可能的
数据表现形式,其实际电路有更好的适应性。
其中只有前4种的取值具有实际物理意义,其他
的是为了与模拟环境相容才保留的。
2)std_logic_vector:

工业标准的逻辑类型std_logic的组合。象
BIT_VECTOR是BIT的组合一样。

使用标准逻辑位矢量必须注明宽度,即数
组中的元素的个数和排列。
由于std_logic不像BIT只有两种取值,在编程时应
当特别注意。如IF语句中是否会因未考虑std_logic
的所有可能取值情况而插入不希望的锁存器,
CASE语句中是否少了分枝等。
【例5-9】例5-2的四选一数据选择器的
CASE实现。
LIBRARY ieee; -- std_logic必须声明库及程序包
USE ieee.std_logic_1164.ALL;
ENTITY mux4 IS
PORT
(s: IN std_logic_vector(1 DOWNTO 0);
a0, a1, a2, a3: IN std_logic_vector(7 DOWNTO 0);
y: OUT std_logic_vector(7 DOWNTO 0));
END mux4;
ARCHITECTURE archmux OF mux4 IS
BEGIN
PROCESS(s , a0, a1, a2, a3 )
BEGIN
CASE s IS
WHEN “00”=> y<=a0;
2位std_logic,每位有9种
WHEN “01”=> y<=a1;
取值,2位有81种取值。
OTHERS用于剩余取值
WHEN “10”=> y<=a2;
的处理。
WHEN “11”=> y<=a3;
WHEN OTHERS =>NULL;
END CASE;
END PROCESS;
END archmux;
3、用户自定义的数据类型
除了上述一些标准的预定义数据类型外,如整数类
型、Boolean类型、标准逻辑位类型Std_logic等,
VHDL还允许用户自行定义新的数据类型。
由用户定义的数据类型可以有多种,如枚举类型
(Enumeration Types)、整数类型(interger Types)、数
组类型(Array Types)、记录类型(Record Types)、时
间类型(Time Types)、实数类型(Real Types)等。
1)枚举类型(Enumerated Types)
枚举类型定义语法如下:
TYPE 数据类型名 IS(枚举文字,枚举文
字…….);
如:TYPE color IS (red, green, yellow, blue);
用户自定义的数据类型名,可在信号、变量
定义时象STD_LOGIC一样使用。
例:枚举类型的定义及使用:
TYPE color IS (red, green, yellow, blue);
TYPE level IS (‘0’,’1’,’z’);
SIGNAL b: level;
采用枚举法,可增加编
…
程效率、提高程序的可
VARIABLE a:color;
读性、并便于VHDL综
…
合器综合。
a:=red;
b<=’1’;
采用枚举法,在编译时取数范围自动编码,如上例
中类型a的四个值red、green、 yellow、blue编译时
常编码为00、01、10、11。
2)数组类型
数组类型定义语法如下:
TYPE 数据类型名 IS ARRAY(索引范围) OF 类型名称
如:
TYPE a IS ARRAY (integer 0 TO 9) OF std_logic;
其中,索引范围为(0,1,2,…,9),每一个数
组元素的类型为std_logic。
*3)子类型定义语句SUBTYPE
格式:
SUBTYPE 子类型名 IS 基本数据类型 RANGE
约束范围;
 子类型SUBTYPE是基本数据类型的一个子集,
它满足基本数据类型的所有约束条件。子类型用
于简化信号说明。
 如:
SUBTYPE int10 IS INTEGER RANGE 0 TO 9;
SIGNAL a: int10;

*4)记录类型(Record Types)
记录类型定义语法如下:
TYPE 记录类型名 IS RECORD
元素名:数据类型名
元素名:数据类型名
…
END RECORD [记录类型名]

例:记录类型的定义
CONSTANT LEN: INTEGER:=100;
TYPE arraylogic IS ARRAY (99 DOWNTO 0)
OF std_logic_vector(7 DOWNTO 0);
TYPE table IS RECORD
a:integer RANGE 0 TO LEN;
b:arraylogic;
c:std_logic_vector(7 DWNTO 0);
END RECORD;
5.3.3 操作符(Operators)
VHDL为构造计算数值的表达式提供了许多预定义
操作符,可分为4种类型:
算术操作符
关系操作符
逻辑操作符
连接操作符
1、算术操作符(Arithmetic Operators)
+加
-减
*乘
/除
** 乘方
MOD 求模
REM 求余
ABS 求绝对值
SLL逻辑左移、SRL逻辑右移
SLA算术左移、SRA算术右移
ROL循环左移、ROR循环右移
2、关系操作符(Relation Operators):
关系操作符的作用是将相同数据类型的数据
对象进行数值比较,并将结果以BOOLEAN
类型的数据表示出来,即TRUE或FALSE两
种
=
等于
/= 不等于
>
大于
>= 大于等于
<
小于
<= 小于等于
3、逻辑操作符(Logic Operator)
共有7种基本逻辑操作符:
AND(与)、
OR(或)、
NAND(与非)、
NOR(或非),
XOR(异或)、
XNOR(同或)
NOT(取反)。
要求的操作数(操作对象)的数据类型有3种,即BIT、
BOOLEAN和STD_LOGIC。
注意:

操作数数据类型和长度一致。

两个以上的,需要使用括号将这些运算分
组。如果操作符相同,且是AND、OR、
XOR这三个算符中的一种,则不需使用括
号;
【例5-10】逻辑操作符使用注意事项:不加
括号的条件和数据类型、长度。
SIGNAL a,b,c:STD_LOGIC_VECTOR(3 DOWNTO
0);
SIGNAL d,e,f,g: STD_LOGIC_VECTOR (1
DOWNTO 0);
SIGNAL h,i,j,k: STD_LOGIC;
SIGNAL l,m,n,o,p:BOOLEAN;
l<=(m
XOR
n)
--i的数据类型是位STD_LOGIC,而l是
(o XOR
d<=e
h<=(i
h<=i
OR
NAND
l;
f OR
j)AND
g;
NAND
--操作数b与e的位矢长度不一致,
--b、c相与后向a赋值,a、b、c的
k; p);
-- NAND不属AND、
a<=b OR
AND
c;
e;
--两个操作符相同且为AND、
--操作符不同,
布尔量Boolean,表达错误.
表达错误
数据类型同属4位长的位矢量
OR、XOR,虽相同
OR、XOR中1个,不需括号
须加括号
也要括号。
【例5-11】例5-1的2选1多路数据选择器,
Y=AS+BS
ARCHITECTURE One OF mux2la IS
BEGIN
y <= (a AND (NOT s)) OR (b AND S) ;
END ARCHITECTURE One;
4、连接操作符(Concatenation Operator)


&--连接,将多个对象或矢量连接成维数更大的
矢量。
例:‘0’&‘1‘ 的结果为”01”。
o1<’0’&a(7 downto 1); -- a右移1位给o1
o2<=o1(6 downto 0) & ‘0’; -- o1左移1位给o2
o3<=o1 & o2; -- o1、o2合并
a<=‘1’&‘0’& d(1)&‘1’ ;--元素与元素并 置,
并置后的数组长度为4
IF a&d=“101011” THEN...--在IF条件句
中可以使用并置符
5.3.4数据对象(Data Objects)
VHDL常用的数据对象有:
信号
变量
常量
1、信号(SIGNAL)





当表达式太长或为便于理解,可设中间信号
SIGNAL用于声明内部信号,而非外部信号(外
部信号对应为IN,OUT,INOUT, BUFFER)
在其元件之间起互联作用,可以赋值给外部信号。
信号是全局变量
在实体说明、结构体描述和程序包说明中使用。
信号的定义格式如下:
SIGNAL信号名:数据类型[:=初始值];
如:SIGNAL count:std_logic_vector(3 DOWNTO
0) :=”0000”;
注意:建议在结构体中用赋值语句完成对信号赋初
值的任务,因为综合器往往会忽略信号声明时所
赋的初值。
信号赋值语句语法格式:
目标信号名<=表达式;
如:q<=count;
【例5-12】例5-1的2选1多路数据选择器,
Y=AS+BS
d
s
0
&
0
0
b
e
图5-6 例5-11综合后的门电路
ARCHITECTURE one OF mux21a IS
SIGNAl d,e : BIT;
BEGIN
d <= a AND (NOT s) ;
e <= b AND s ;
y <= d OR e ;
END ARCHITECTURE one ;
y
2.变量(VARIABLE)



变量只在给定的进程中用于声明局部值或用于子
程序中,
变量的赋值符号为“:=”。
和信号不同,信号是实际的,是外输入,或者是
内部的一个存储元件;而变量是虚的,仅仅是为
书写方便而引入的一个名称,它常用在实现某种
算法的赋值语句中。
变量定义格式如下:
VARIABLE 变量名:数据类型[:=初始值];
如:VARIABLE a: integer:=0;
变量赋值语句的语法格式;
目标变量名:=表达式;
如:a:=b+c;
3.常量(CONSTANT)

常量是全局量,在结构体描述、程序包说明、实
体说明、过程说明、函数调用说明和进程说明中
使用。

常量在设计描述中保持某一规定类型的特定值不
变。如利用它可设计不同模值的计数器,模值存
于一常量中,对不同的设计,改变模值仅需改变
此常量值即可。
常量定义格式如下:
CONSTANT 常数名:数据类型:=表达式;
如:CONSTANT mod :integer:=6;

【例5-13】一位BCD码的加法器。
信号、变量及常量的定义及使用方法。
思路:汇编语言十进制加法:加、比较、调整
ENTITY bcdadder IS
PORT ( op1 , op2 : IN integer RANGE 0 TO 9;
result : OUT integer RANGE 0 TO 31 );
END bcdadder;
ARCHITECTURE behave OF bcdadder IS
CONSTANT adjustnum : integer : = 6; --定义一整数型常量,值为6
SIGNAL binadd : integer RANGE 0 TO 18;
--定义一个信号,以保存和
BEGIN
--信号赋值
binadd<=op1+op2;
PROCESS(binadd)
VARIABLE tmp : integer : = 0; --定义一变量,并赋初值为0
BEGIN
IF binadd>9 THEN tmp : = adjustnum;
--变量赋值,立即起作用。
ELSE tmp : = 0;
END IF;
result<=binadd+tmp;
END PROCESS;
END behave;
4.信号和变量的比较

声明的形式不同:
信号为SIGNAL,变量为VARIABLE;

声明的位置不同:信号声明在子程序,进程等外
部,而变量声明在子程序,进程的内部。

赋值起作用时刻不同:在进程中,信号赋值在进
程结束时起作用,而变量赋值是立即起作用的。
赋值符不同:信号赋值为“<=”,变量赋值为“:=”。


作用的范围不同。信号作用于整个结构体,可用
于进程间传递信息,而变量只能在进程内部起作
用,达到实现某个算法的目的。

在VHDL设计中,可以使用信号和变量。考
虑到信号的行为更接近于硬件,需要到所
在进程结束时才会更新值,而变量值的改
变是立即进行的,因此有可能影响设计的
功能等因素,虽然使用变量可以增加仿真
的速度,但还是推荐在对硬件进行描述时
尽量采用信号。

注意:如果在一个进程中多次为一个信号赋值时,
只有最后一个值会起作用;而当为变量赋值时,
变量值的改变是立即发生的。即变量将保持着当
前值,直到被赋予新的值。

下面的例子分别进一步表明了使用信号和变量的
区别。
【例5-14】使用信号的情况
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY xor_sig IS
PORT (a , b , c : IN std_logic;
x , y : OUT STD_LOGIC );
END xor_sig;
ARCHITECTURE sig_arch OF xor_sig IS
SIGNAL d : std_logic;
BEGIN
sig : PROCESS(a , b , c)
BEGIN
--ignored !!
d<=a;
x<=c XOR d;
d<=b;
--overrides !!
y<=c XOR d;
A
END PROCESS;
B
END sig_arch;
C
图5-7 例5-13的电路实现
执行结果:x=c⊕b,y=c⊕b;
X
Y
【例5-15】使用变量的情况
ARCHITECTURE var_arch OF xor_var IS
BEGIN
PROCESS(a , b , c)
VARIABLE d : std_logic;
BEGIN
d : = a;
x<=c XOR d;
执行结果:x=c⊕a,y=c⊕b
d : = b;
A
X
y<=c XOR d;
C
Y
B
END PROCESS;
图5-8 例5-14的电路实现
END var_arch;
5.3.5 VHDL的属性

属性指的是关于实体、结构体、类型及信号的一
些特性。

有些属性对综合(设计)非常有用,如:数值类
属性、函数类以有范围类属性等等。
其引用的一般形式均为:对象’属性。

*1. 数值类属性
数值类属性返回数组、块或一般数据有关的值。
常用的有:
’left(左边界),
’right(右边界),
’low(下边界),
’high(上边界),
’length(数组长度)等。
例:
sdown: IN std_logic_vector(8 downto 0);
sup: out std_logic_vector(0 to 8);
这两个信号的各属性值如下:
sdown’left=8;sdown’right=0; sdown’low=0;
sdown’high=8; sdown’length=9;
sup’left=0; sup’right=8; sup’low=0;
sup’high=8; sup’length=9;
2、函数类属性
信号属性函数属于函数类属性,用来返回有关信
号行为功能的信息。
 函数:信号’event
返回值为布尔型。如果信号值有变化称发生事件,
返回值为TRUE ,否则为False。
 时钟边沿表示:
clk’event and clk=’1’
时钟clk的上升沿。
即时钟变化了,且其值为1(从0变1)。
clk’event and clk=’0’
时钟clk的下降沿。
即时钟变化了,且其值为0(从1变0)。

预定义的时钟边沿函数:
 rising_edge(clk)
时钟clk的上升沿
与clk’event and clk=’1’等效;
falling_edge(clk)
时钟clk的下降沿
与clk’event and clk=’0’ 等效。
 rising_edge()和falling_edge()是VHDL在IEEE
库中标准程序包STD_LOGIC_1164内的预
定义函数,这条语句只能用于标准逻辑位
数据类型STD_LOGIC的信号.
*3. 范围类属性




’RANGE 属性,其生成一个限制性数据对象的范
围。
如:SIGNAL data: std_logic_vector(15 DOWNTO
0);
则data’RANGE=15 DOWNTO 0。
注意:maxplusII不支持该属性。