return signal srl type variable xnor
rol shared subtype unaffected wait ror sla then units when
xor
select sll to until while severity sra
transport use with
3. VHDL中的界符
界符是作为VHDL语言中两个部分的分隔符用的。如每个完整的语句均以 “;” 结尾,用 双减号“-”开头的部分是注释内容,不参加程序编译。信号赋值符号是“<=”,变量赋值符号是 “:=” 等。 在VHDL中,常用的界符如表1-2-2所列 表1-2-2 VHDL中的界符
4. 注释符
在VHDL中,为了便于理解和阅读程序,常常加上注释,注释符用双减号 “.”表示。注
释语句以注释符打头,到行尾结束。注释可以加在语句结束符 “;”之后,也可以加在空行处。 1.2.2 VHDL的数据类型
在VHDL中,定义了三种数据对象,即信号、变量和常数,每一个数据对象都必须具
有确定的数据类型,只有相同的数据类型的两个数据对象才能进行运算和赋值,为此VHDL 定义了多种标准的数据类型,而且每一种数据类型都具有特定的物理意义。例如,BIT型、 STD_LOGIC型、INTEGER型和REAL型等数据类型。
VHDL的数据类型较多,根据数据用途分类可分为标量型、复合型、存取型和文件型。 标量型包括整数类型、实数类型、枚举类型和时间类型,其中位(BIT)型和标准逻辑位 (STD_LOGIC)型属于枚举类型。复合型主要包括数组(ARRAY)型和记录(RECORD) 型,存取类型和文件类型提供数据和文件的存取方式。这些数据类型又可以分为两大类:即
在VHDL程序包中预定义的数据类型和用户自定义的数据类型。预定义的数据类型是最基本的数据类型,这些数据类型都定义在标准程序包STANARD、STD_LOGIC_1164和其它标准的程序包中,这些程序包放在EDA软件中IEEE和STD目录中,供用户随时调用。在预定义的各种数据类型的基础上,用户可以根据实际需要自己定义数据类型和子类型,如标量型和数组型。使用用户定义的数据类型和子类型可以使设计程序的语句简练易于阅读,简化设计电路硬件结构。
值得注意的是,各种EDA工具不能完全支持VHDL的所有数据类型,只支持VHDL的子 集。
1. STANDARD程序包中预定义的数据类型 (1) 整数(INTEGER)数据类型
整数数据类型与数学中整数的定义是相同的,整数类型的数据代表正整数、负整数 和零。VHDL整数类型定义格式为:
TYPE INTEGER IS RANGE -2147483648 TO 2147483647 ; 实际上一个整数是由32位二进制码表示的带符号数的范围。 正整数(POSITIVE)和自然数(NATURAL)是整数的子类型,定义格式为: SUBTYPE POSITIVE IS INTEGER RANGE 0 TO INTEGER’HIGH ; SUBTYPE NATURE IS INTEGER RANGE 1 TO INTEGER’HIGH ;
其中INTEGER.HIGH是数值类属性,代表整数上限的数值,也即2147483647。所以正整
数表示的数值范围是0~2147483647,自然数表示的数值范围是1~2147483647。实际使用过程中为了节省硬件组件,常用RANGER?TO?限制整数的范围。例如: SIGNALA :INTEGER; --信号A是整数数据类型
VARIABLE B :INTEGER RANGE 0 TO 15; --变量B是整数数据类型,变化范围是0到15。 SIGNAL C :INTEGER RANGE 1 TO 7; --信号C是整数数据类型,变化范围是1到7。 (2) 实数(REAL)数据类型
VHDL实数数据类型与数学上的实数相似,VHDL的实数就是带小数点的数,分为正数 和小数。实数有两种书写形式即小数形式和科学计数形式,不能写成整数形式。例如 1.0,1.0E4,-5.2等实数是合法的。实数数据类型的定义格式为: TYPE REAL is range -1.7e38 to 1.7e38; 例如:SIGNAL A, B, C :REAL ; A<= 5.0; B <= 3.5E5; C <= -4.5;
小提示:
整数与实数均可以由下划线分割,便于阅读,如:45_133_134; 124_452_112.113_429; 此外不同进制的数可以由如下格式表达: 基数#数字文字#E指数 如:2#1111_1110# = 254; 16#E#E1 = 14*161 = 224; (3) 位(BIT)数据类型
位数据类型的位值用字符.0.和.1.表示,将值放在单引号中,表示二值逻辑的0和1。这里
的0和1与整数型的0和1不同,可以进行算术运算和逻辑运算,而整数类型只能进行算术运算。 位数据类型的定义格式为: TYPE BIT is ( '0', '1' ); 例如:
RESULT : OUT BIT; RESULT<= .1.;
将RESULT引脚设置为高电平。
(4) 位向量(BIT_VECTOR)数据类型
位向量是基于BIT数据类型的数组。VHDL位向量的定义格式为: TYPE BIT_VECTOR is array (NATURAL range <>) of BIT;
使用位向量必须注明位宽,即数组的个数和排列顺序,位向量的数据要用双引号括起来。 例如 “1010”,X “A8”。其中1010是四位二进制数,用X表示双引号里的数是十六进制数。 例如:
SIGNAL A :BIT_VECTOR (3 DOWNTO 0 ); A <= “1110” ;
表示A是四个BIT型元素组成的一维数组,数组元素的排列顺序是A3=1,A2=1,A1=1, A0=0。
(5) 布尔(BOOLEAN)数据类型
一个布尔量具有真(TRUE)和假(FALSE)两种状态。布尔量没有数值的含义,不能
用于数值运算,它的数值只能通过关系运算产生。例如,在IF语句中,A>B是关系运算,如果A=3,B=2,则A>B关系成立,结果是布尔量TRUE,否则结果为FALSE。 VHDL中,布尔数据类型的定义格式为: TYPE BOOLEAN IS (FALSE, TRUE); (6) 字符(CHARACTER)数据类型
在STANDARD程序包中预定义了128个ASCII码字符类型,字符类型用单引号括起来,如.A.,.b.,.1.等,与VHDL标识符不区分大小写不同,字符类型中的字符大小写是不同的,如.B.和.b.不同。 (7) 字符串(STRING)
在STANDARD程序包中,字符串的定义是:
TYPE STRING is array (POSITIVE range <>) of CHARACTER;
字符串数据类型是由字符型数据组成的数组,字符串必须用双引号括起来。 例如:
CONSTANT STR1 :STRING := “Hellow world”; 定义常数ST1是字符串,初值是“Hellow world ”。 小提示:
与C语言类似,字符类型用单引号括起来,而字符串必须用双引号括起来,别弄混了。 (8) 时间(TIME)数据类型
表示时间的数据类型,一个完整的时间类型包括整数表示的数值部分和时间单位两个部 分,数值和单位之间至少留一个空格,如1 ms,20 ns等。 STANDARD程序包中定义时间格式为:
TYPE TIME is range -9223372036854775808 to 9223372036854775807 UNITS fs; -- 飞秒
ps = 1000 fs; -- 皮秒 ns = 1000 ps; -- 纳秒 us = 1000 ns; -- 微秒 ms = 1000 us; -- 毫秒 sec = 1000 ms; -- 秒 min = 60 sec; -- 分 hr = 60min; -- 小时 END UNITS; 小提示:
实数,时间类型仅用于VHDL仿真,一般综合器不支持。 2. IEEE预定义的标准逻辑位和标准逻辑位向量 (1) 标准逻辑位(STD_LOGIC)数据类型
STD_LOGIC是位(BIT)数据类型的扩展,是STD_ULOGIC数据类型的子类型。它是一
个逻辑型的数据类型,其取值取代BIT数据类型的取值0和1两种数值,扩展定义了九种值,在IEEE STD1164程序包中,STD_ULOGIC和STD_LOGIC数据类型定义格式为: TYPE std_ulogic IS ( U', -- Uninitialized
'X', -- Forcing Unknown '0', -- Forcing 0 '1', -- Forcing 1
'Z', --High Impedance 'W', -- Weak Unknown 'L', --Weak 0 'H', --Weak 1 '-' -- Don't care );
FUNCTION resolved ( s : std_ulogic_vector ) RETURN std_ulogic; SUBTYPE std_logic IS resolved std_ulogic; 小提示:
STD_LOGIC中的数据类型必须要大写,不能使用小写字母代替,在实际的IC集成时, 一般只使用.0., .1., .Z., ._.四种数据类型,其余的.W., .L., .H.是不可综合的。
STD_LOGIC和STD_ULOGIC数据类型的区别在于STD_LOGIC数据类型是经过重新定 义的,可以用来描述多路驱动的三态总线,而STD_ULOGIC数据类型只能用于描述单路驱 动的三态总线。
(2) 标准逻辑位向量(STD_LOGIC_VECTOR)数据类型
STD_LOGIC_VECTOR是基于STD_LOGIC数据类型的标准逻辑一维数组,和
BIT_VECTOR数组一样,使用标准逻辑位向量必须注明位宽和排列顺序,数据要用双引号 括起来。 例如:
SIGNAL SA1 :STD_LOGIC_VECTOR (3 DOWNTO 0 ); SA1 <= “0110” ;
在IEEE_STD_1164程序包中,STD_LOGIC_VECTOR数据类型定义格式为: TYPE std_logic_vector IS ARRAY ( NATURAL RANGE <>) OF std_logic; 3. 其它预定义的数据类型
在STD_LOGIC_ARITH程序包中定义了无符号(UNSIGNED)和带符号(SIGNED)数 据类型,这两种数据类型主要用来进行算术运算。定义格式为: TYPE UNSIGNED is array (NATURAL range <>) of STD_LOGIC; TYPE SIGNED is array (NATURAL range <>) of STD_LOGIC; (1) 无符号(UNSIGNED)数据类型
无符号数据类型是由STD_LOGIC数据类型构成的一维数组,它表示一个自然数。在一 个结构体中,当一个数据除了执行算术运算之外,还要执行逻辑运算,就必须定义成 UNSIGNED,而不能是SIGNED或INTEGER类型。 例如: SIGNAL DAT1 :UNSIGNED(3 DOWNTO 0); DAT1 <= “1001”; 定义信号DAT1是四位二进制码表示的无符号数据,数值是9。 (2) 带符号(SIGNED)数据类型
带符号(SIGNED)数据类型表示一个带符号的整数,其最高位用来表示符号位,用补
码表示数值的大小。当一个数据的最高位是0时,这个数表示正整数,当一个数据的最高位 是1时,这个数表示负整数。 例如:
VARIABLE DB1, DB2 : SIGNED(3 DOWNTO 0); DB1 <= “0110” ; DB2 <= “ 1001” ;
定义变量DB1是6,变量DB2是-7。 4. 用户自定义的数据类型
在VHDL中,用户可以根据设计需要,自己定义数据的类型,称为用户自定义的数据类 型。利用用户自己定义数据类型可以使设计程序便于阅读。用户自定义的数据类型可以通过 两种途径来实现,一种方法是通过对预定义的数据类型作一些范围限定而形成的一种新的 数据类型。这种定义数据类型的方法有如下几种格式: TYPE 数据类型名称 IS 数据类型名RANGE 数据范围; 例如: TYPE DATA IS INTEGER RANGER 0 TO 9 ; 定义DATA是INTEGER数据类型的子集,数据范围是0~9。 SUBTYPE 数据类型名称 IS 数据类型名 RANGE 数据范围; 例如:
SUBTYPE DB IS STD_LOGIC_VECTOR(7 DOWNTO 0);
定义DB 是STD_LOGIC_VECTOR数据类型的子集,位宽8位。
另一种方法是在数据类型定义中直接列出新的数据类型的所有取值,称为枚举数据类 型。定义该种数据类型的格式为:
TYPE 数据类型名称 IS(取值1,取值2,?); 例如 :
TYPE BIT IS(.0.,.1.); TYPE STATE_M IS (STAT0, STAT1, STAT2, STAT3); 定义BIT数据类型,取值0和1。定义STATE_M是数据类型,表示状态变量STAT0,STAT1, STAT2,STAT3。在VHDL中,为了便于阅读程序,可以用符号名来代替具体的数值,前例 中STATE_M是状态变量,用符号STAT0, STAT1, STAT2, STAT3表示四种不同的状态取值是 00,01,10,11。
例如定义一个 “WEEK” 的数据类型用来表示一个星期的七天,定义格式为: TYPE WEEK IS (SUN, MON, TUE, WED, THU, FRI, SAT); 小提示:
使用枚举数据类型定义后,综合器会自动将字符类型从0开始进行二进制编码,编码的位 数由枚举元素个数决定。 5.数组(ARRAY)的定义
数组是将相同类型的单个数据元素集合在一起所形成的一个新的数据类型。它可以是一 维数组(一个下标)和多维数组(多个下标),下标的数据类型必须是整数。前面介绍的位 向量(BIT_VECTOR)和标准逻辑位向量(STD_LOGIC_VECTOR)数据类型都属于一维 数组类型。数组定义的格式为:
TYPE 数据类型名称 IS ARRAY 数组下标的范围 OF 数组元素的数 小提示:
VHDL多维数组定义,多维数组声明即将第一维的数组作为第二维数组的元素定义即可。 TYPE 1维数据类型名称 IS ARRAY 数组下标的范围 OF 数组元素的数据类型;
TYPE 2维数据类型名称 IS ARRAY 数组下标的范围 OF 上面所定义的1维数据类型; 根据数组元素下标的范围是否指定,把数组分为非限定性数组和限定性数组两种类型。 非限定性数组不具体指定数组元素下标的范围,而是用NATURAL RANGER <> 表示,当用到该数组时,再定义具体的下标范围。如前面介绍的位向量(BIT_VECTOR)和标准逻辑位向量(STD_LOGIC_VECTOR)数据类型等在程序包中预定义的数组属于非限定性数组。
例如,在IEEE程序包中定义STD_LOGIC_VECTOR数据类型的语句是 TYPE std_logic_vector IS ARRAY ( NATURAL RANGE <>) OF std_logic; 没有具体指出数组元素的下标范围,在程序中用信号说明语句指定。 例如: SIGNAL DAT : STD_LOGIC_VECTOR(3 DOWNTO 0);
限定性数组的下标的范围用整数指定,数组元素的下标可以是由低到高,如 0 TO 3, 也可以是由高到低,如7 DOWNTO 0,表示数组元素的个数和在数组中的排列方式。 例如:
TYPE D IS ARRAY(0 TO 3)OF STD_LOGIC; TYPE A IS ARRAY(4 DOWNTO 1)OF BIT;
定义数组D是一维数组,由四个STD_LOGIC型元素组成,数组元素的排列顺序是D(0), D(1),D(2),D(3)。A数组是由四个元素组成的BIT数据类型,数组元素的排列顺序是A(4), A(3),A(2),A(1)。 小提示:
对于数组数据类型,可以给一组数据多个值一起赋值: 如上例:
SIGNAL ARRAY1: D; BEGIN
ARRAY1<=(.1.,.0.,.0.,.1.); 6.数据类型的转换
在VHDL语言中,数据类型的定义是相当严格的,不同类型的数据是不能进行运算和赋
值的。为了实现不同类型的数据赋值,就要进行数据类型的变换。变换函数在VHDL语言程序包中定义。在程序包STD_LOGIC_1164、STD_LOGITH_ARITH和STD_LOGIC_ UNSIGNED中提供的数据类型变换函数如表1-2-3所列。
例如把INTEGER数据类型的信号转换为STD_LOGIC_VECTOR数据类型的方法是: 定义A, B为:
SIGNALA :INTEGER RANGER 0 TO 15;
SIGNALB : STD_LOGIC_VECTOR(3 DOWNTO 0);
需要调用STD_LOGIC_ARITH程序包中的函数CONV_STD_LOGIC_VECTOR
调用的格式是:B <= CONV_STD_LOGIC_VECTOR(A);
表1-2-3 数据类型变换函数
程序包名称
STD_LOGIC_1164
函数名称 TO_BIT
TO_BITVECTOR TO_STDULOGIC
TO_STDULOGICVECTER
功能 由STD_LOGIC转换为BIT
由STD_LOGIC_VECTOR转换为 BIT_VECTOR
由BIT转换为STD_LOGIC 由BIT_VECTOR转换为STD_LOGIC_VECTOR
由UNSIGNED, SIGNED 转换为INTEGER
由SIGNED, INTEGER转换为UNSIGNED
由INTEGER, UNSDGNED, SIGNED
转换为STD_LOGIC_VECTOR 由STD_LOGIC_VECTOT转换为INTEGER
STD_LOGIC_ARITH
CONV_INTEGER CONV_UNSIGNED
CONV_STD_LOGIC_VECTOR
STD_LOGIC_UNSIGNED CONV_INTEGER
1.2.3 VHDL的运算符
与高级语言一样,VHDL语言的表达式也是由运算符和操作数组成的。VHDL标准预
定义了四种运算符,即逻辑运算符、算术运算符、关系运算符、移位运算符和连接运算符, 并且定义了与运算符相应的操作数的数据类型。各种运算符之间是有优先级的,例如在所有 运算符中,逻辑运算符NOT的优先级别最高。表1-2-4列出了所有运算符的优先级顺序。
表1-2-4 VHDL运算符列表 运
算符类型 逻辑运算符 OR NAND NOR XOR NXOR
关系运算符 /= < > <= >=
移位运算符 SLA SRL SRA ROL ROR
符号运算符 -
连接运算符
运算符
功能
优先级
AND
=
SLL
+ & +
逻辑与 逻辑或 逻辑与非 逻辑或非 逻辑异或 逻辑异或非
等于
不等于 小于 大于
小于等于 大于等于
逻辑左移
算术左移 逻辑右移 算术右移
逻辑循环左移 逻辑循环右移
正
负
位合并
加
减 乘 除 求模 求余 乘方
求绝对值 逻辑非
最低
算术运算符 - * /
MOD REM ** ABS
逻辑非运算符
NOT 最高