VHDL语言的数据类型及运算操作符.ppt
第三章VHDL语言的数据类型及运算操作符,3.1 VHDL语言的客体及其分类,在VHDL 语言中,可以赋予一个值的的对象就称为客体或对象,它接受不同数据类型的赋值。对象主要包括以下3种:信号(SIGNAL):对应物理意义上是实际电路连接线。说明全局量 变量(VARIABLE):相当于暂存寄存器,变量值不是最终的结果。说明局部量 常数(CONSTANT):如电源、地等,用来描述固定的值。说明全局量,常数(Constant),常量是指在设计实体中不会发生变化的值,它可以在很多部分进行说明,并且可以是任何数据类型。常量的定义和设置主要是为了使设计实体中的常数更容易阅读和修改。例如,将位矢的宽度定义为一个常量,只要修改这个常量就能很容易地改变宽度,从而改变硬件结构。在程序中,常量是一个恒定不变的值,一旦作了数据类型的赋值定义后,在程序中不能再改变,因而具有全局意义。,格式:CONSTANT 常数名:数据类型:表达式;例:CONSTANT VCC:REAL:=5.0;CONSTANT DALY:TIME:=100ns;CONSTANT BUS:BIT_VECTOR:=“1010”CONSTANT G1:BIT:1;数据类型和表达式表示的数据类型应该一致。表示是位信息,而“”表示的是位矢量信息。,常量定义语句所允许的设计单元有实体、结构体、程序包、块、进程和子程序。在程序包中定义的常量可以暂不设具体数值,它可以在程序包体中设定。常量的可视性,即常量的使用范围取决于它被定义的位置。在程序包中定义的常量具有最大全局化特征,可以用在调用此程序包的所有设计实体中;定义在设计实体中的常量,其有效范围为这个实体定义的所有的结构体;定义在设计实体的某一结构体中的常量,则只能用于此结构体;定义在结构体的某一单元的常量,如一个进程中,则这个常量只能用在这一进程中。,总结:,在运行中不变,若要改变必须要改变设计,也就是说改变常量说明,重新编译。常量必须在程序的实体、结构体或过程的说明区中,对其标识符类型常量值进行指定。定义在实体中的常量仅在实体中使用。以此类推。,变量(Variable),变量是局部变量,只能在进程、过程、函数中使用和定义。格式:VARIABLE 变量名:数据类型 约束条件:表达式;例:VARIABLE x,y:INTEGER VARIABLE x,y:INTEGER RANGE 0 TO 255:=10 在程序中,变量的赋值是立即生效的,不能产生附加延时。tmp1:=tmp2+tmp3 AFTER 10ns,变量作为局部量,其适用范围仅限于定义了变量的进程或子程序中。仿真过程中惟一的例外是共享变量。变量的值将随变量赋值语句的运算而改变。变量定义语句中的初始值可以是一个与变量具有相同数据类型的常数值,也可以是一个全局静态表达式,这个表达式的数据类型必须与所赋值变量一致。此初始值不是必需的,综合过程中综合器将略去所有的初始值。变量数值的改变是通过变量赋值来实现的,其赋值语句的语法格式如下:目标变量名:=表达式;,总结:,(1)变量值是直接的,在某一时刻,仅包含一个值。(2)赋值和初始化符号:(3)变量不能表示连线或存贮元件,3.1.3 信号(Signal),信号是描述硬件系统的基本数据对象,它类似于连接线。信号可以作为设计实体中并行语句模块间的信息交流通道。在VHDL中,信号及其相关的信号赋值语句、决断函数、延时语句等很好地描述了硬件系统的许多基本特征。如硬件系统运行的并行性;信号传输过程中的惯性延时特性;多驱动源的总线行为等。信号作为一种数值容器,不但可以容纳当前值,也可以保持历史值。这一属性与触发器的记忆功能有很好的对应关系。信号初始值的设置不是必需的,而且初始值仅在VHDL的行为仿真中有效。与变量相比,信号的硬件特征更为明显,它具有全局性特性。信号的说明通常在ARCHITECTURE、PACKAGE、ENTITY中进行的。,信号的定义格式如下:SIGNAL 信号名:数据类型 约束条件:=初始值;示例:SIGNAL S1:STD_LOGIG:=0;-定义了一个标准位的单值信号S1,初始值为低电平SIGNAL S2,S3:BIT;-定义了两个为BIT的信号S2和S3SIGNAL S4:STD_LOGIC_VECTOR(15 DOWNTO 0);-定义了一个标准位矢的位矢量(数组、总线)信号,共有16个信号元素,以下示例定义的信号数据类型是设计者自行定义的,这是VHDL所允许的:TYPE FOUR IS(X,0,I,Z);SIGNAL S1FOUR;SIGNAL S2FOUR:=X;SIGNAL S3FOUR:=L;,总结:,信号大多数均是在实体或结构体的说明区加以说明信号赋值语句“=”符号重要应用:信号可以在状态机中表示变量端口说明中的对象均为信号类型,信号与变量的区别,信号赋值至少有延时;而变量赋值没有延时。信号除当前值外有许多相关的信息;而变量只有当前值。进程对信号敏感而不对变量敏感。信号可以是多个进程的全局信号;而变量只在定义它们的顺序域可见(共享变量除外)。信号是硬件中连线的抽象描述,它们的功能是保存变化的数据和连接子元件,信号在元件的端口连接元件。变量在硬件中没有类似的对应关系,它们用于硬件特性的高层次建模所需要的计算中。信号赋值和变量赋值分别使用不同的赋值符号“=”和“:”;允许两者之间相互赋值,但要保证两者的类型相同。对于信号赋值来说,在信号赋值的执行和信号值的更新之间至少有延时,只有延迟之后才能得到新值,否则保持原值;而对于变量来说,赋值没有延迟,变量在赋值语句执行后立即得到新值。,例31:PROCESS(A,B,C,D)BEGIN D=A;X=B+D;D=C;Y=B;END PROCESS,结果:X=B+C;,例32:PROCESS(A,B,C)VARIABLE D:STD_LOGIC_VECTOR(3DOWNTO 0)BEGIN D:=A;X:=B+D;D:=C;Y:=B;END PROCESS,结果:X=B+A;,3.2 VHDL语言的数据类型,VHDL是一种强类型语言,要求设计实体中的每一个常数、信号、变量、函数以及设定的各种参量都必须具有确定的数据类型,并且只有数据类型相同的量才能互相传递和作用。VHDL作为强类型语言的好处是能使VHDL编译或综合工具很容易地找出设计中的各种常见错误。VHDL中的数据类型可以分成以下几大类:标准的数据类型、用户自定义的数据类型、用户自定义的子类型。,3.2.1 标准的数据类型,1:整数 2:实数 3:位 4:位矢量 5:布尔量 6:字符 7:时间 8:错误等级 9:自然数,正整数 10:字符串,1、整数(INTEGER),整数类型的数代表正整数、负整数和零。取值范围为-(231-1)(231-1),主要用于表示总线(如多位计数器的输出)的状态,不能直接按位来操作,也不能进行逻辑运算。整数常量的书写方式示例如下:2-十进制整数10E4-十进制整数16#D2#-十六进制整数2#11011010#-二进制整数,2、实数(REAL)数据类型,VHDL的实数类型类似于数学上的实数,或称浮点数。实数的取值范围为-1.0E+38+1.0E+38。通常情况下,实数类型仅能在VHDL仿真器中使用,VHDL综合器不支持实数,因为实数类型的实现相当复杂,目前在电路规模上难以承受。主要用于硬件方案的研究或实验。实数常量的书写方式举例 65971.333333-十进制浮点数8#43.6E+4#-八进制浮点数43.6E-4-十进制浮点数,3、位(BIT)数据类型,位数据类型也属于枚举型,取值只能是1或0。位数据类型的数据对象,如变量、信号等,可以参与逻辑运算,运算结果仍是位的数据类型。VHDL综合器用一个二进制位表示BIT。在程序包STANDARD中定义的源代码是:TYPE BIT IS(0,1);,4、位矢量(BIT_VECTOR)数据类型,是用双引号括起来的一组位数据,每位只有两种取值:0和1。在其前面可以加上数制标记,如X(十六进制)、B(二进制,默认)、O(八进制)等。常用于表示总线的状态。在程序包STANDARD中定义的源代码是:TYPE BIT _VETOR IS ARRAY(NATURA RANGE)OF BIT;“001100”X“00BB”,5、布尔(BOOLEAN)数据类型,Boolean(布尔量),又称逻辑量。有“真”、“假”两种状态,分别用TRUE和FALSE标记。用于关系运算和逻辑判断,常用来表示信号的状态或者总线上的情况,程序包STANDARD中定义布尔数据类型的源代码如下:TYPE BOOLEAN IS(FALSE,TRUE);一般这一类型的数据的初始值总为FALSE,6、字符(CHARACTER)数据类型,字符类型通常用单引号括起来的一个字母、数字或$、%等字符。如A。字符类型区分大小写,如B不同于b。字符类型已在STANDARD程序包中作了定义。CHARACTER(1)指出1的字符数据,7、字符串(STRING)数据类型,字符串数据类型是字符数据类型的一个非约束型数组,或称为字符串数组。字符串必须用双引号标明。区分大小写字母。常用于程序的提示和说明等。如:VARIABLE STRING_VARSTRING(1 TO 7);STRING_VAR“A B C D”;,8、时间(TIME)数据类型,VHDL中惟一的预定义物理类型是时间。完整的时间类型包括整数和物理量单位两部分,整数和单位之间至少留一个空格,如55 ms,20 ns。常用单位有fs(飞秒)、ns(纳秒)、s(微秒)、ms(毫秒)、s(秒)、min(分)等。常用于指定器件延时和标记仿真时刻。STANDARD 程序包中也定义了时间。定义如下:TYPE TIME IS RANGE-2147483647 TO 2147483647units fs;-飞秒,VHDL中的最小时间单位ps=1000 fs;-皮秒ns=1000 ps;-纳秒us=1000 ns;-微秒 ms=1000 us;-毫秒sec=1000 ms;-秒min=60 sec;-分hr=60 min;-时end untis;,9、错误等级(SEVERITY_LEVEL),在VHDL仿真器中,错误等级用来指示设计系统的工作状态,共有四种可能的状态值:NOTE(注意)、WARNING(警告)、ERROR(出错)、FAILURE(失败)。在仿真过程中,可输出这四种值来提示被仿真系统当前的工作情况。其定义如下:TYPE SEVERITY_LEVE IS(NOTE,WARNING,ERROR,FAILURE);,10、自然数(NATURAL)和正整数(POSITIVE)数据类型,自然数是整数的一个子类型,是非负的整数,即零和正整数;正整数也是整数的一个子类型,它包括整数中非零和非负的数值。INTEGER RANGE 100 DOWNTO 1;INTEGER RANGE 0 TO 9:=0;,3.3.2 用户定义的数据类型,除了可使用VHDL提供的标准数据类型之外,设计者还可以自己建立新的数据类型及子类型。新构造的数据类型及子类型通常在包集合中说明,以便重用和供多个设计共用。类型说明语句的一般形式是:TYPE 数据类型名 IS 数据类型定义OF 基本数据类型;或 TYPE 数据类型名 IS 数据类型定义;VHDL允许用户自行定义新的数据类型,它们可以有多种,如枚举类型(ENUMERA-TION TYPE)、整数类型(INTEGER TYPE)、数组类型(ARRAY TYPE)、记录类型(RECORD TYPE)、时间类型(TIME TYPE)、实数类型(REA TYPE)等。,1、枚举类型,通过列举某类变量所有可能的取值来加以定义。对这些取值,一般使用自然语言中有相应含义的单词或字符序列来代表,因而便于阅读和理解。VHDL中的枚举数据类型是用文字符号来表示一组实际的二进制数的类型(若直接用数值来定义,则必须使用单引号)。枚举类型的具体定义格式为 TYPE 数据类型名 IS(元素1,元素2,);例如,在程序包STD LOGIC 1164中对STD LOGIC的定义为TYPE STD LOGIC IS(U,X,0,1,Z,W,L,H,-);,2、整数类型和实数类型,整数和实数的数据类型在标准的程序包中已作了定义,但在实际应用中,特别在综合中,由于这两种非枚举型的数据类型的取值定义范围太大,综合器无法进行综合。整数或实数用户定义数据类型的格式为:TYPE 数据类型名 IS 数据类型定义 约束范围 实际应用中,VHDL仿真器通常将整数或实数类型作为有符号数处理,VHDL综合器对整数或实数的编码方法是:对用户已定义的数据类型和子类型中的负数,编码为二进制补码;对用户已定义的数据类型和子类型中的正数,编码为二进制原码。,3、数组类型,数组类型属复合类型,它是将一组具有相同数据类型的元素集合在一起,作为一个数据对象来处理的数据类型。数组可以是一维(每个元素只有一个下标)数组或多维数组(每个元素有多个下标)。VHDL仿真器支持多维数组,但VHDL综合器只支持一维数组。数组的元素可以是任何一种数据类型,用以定义数组元素的下标范围子句决定了数组中元素的个数以及元素的排序方向,即下标数是由低到高,或是由高到低。限定性数组定义语句格式如下:TYPE 数组名 IS ARRAY(数组范围)OF 数据类型;其中,数组名是新定义的限定性数组类型的名称,可以是任何标识符,其类型与数组元素相同;数组范围指出数组元素的定义数量和排序方式,以整数来表示其数组的下标。默认的下标类型是整型,但也可以使用其它数据类型,如枚举类型等,这时需在范围中标明下标的类型;数据类型即指数组各元素的数据类型。,TYPE STB IS ARRAY(7 DOWNTO 0)OF STD_LOGIC;这个数组类型的名称是STB,它有八个元素,它的下标排序是7,6,5,4,3,2,1,0,各元素的排序是STB(7),STB(6),STB(1),STB(0)。TYPE X IS(LOW,HIGH);TYPE DATA_BUS IS ARRAY(0 TO 7,X)OF BIT;首先定义X为两元素的枚举数据类型,然后将DATA_BUS定义为一个数组类型,其中每一元素的数据类型是BIT。非限制性数组的定义语句格式如下:TYPE 数组名 IS ARRAY(数组下标名 RANGE)OF 数据类型;TYPE BIT_VECTOR IS ARRAY(NATURA RANE)OF BIT;VARABLE VA:BIT_VECTOR(1 TO 6);-将数组取值范围定在16,4、记录类型,由已定义的、数据类型不同的对象元素构成的数组称为记录类型的对象。定义记录类型的语句格式如下:TYPE 记录类型名 IS RECORD 元素名:元素数据类型;元素名:元素数据类型;END RECORD 记录类型名;,【例】TYPE RECDATA IS RECORD-将RECDATA定义为三元素记录类型ELEMENT1 TIME;-将元素ELEMENT1定义为时间类型ELEMENT2 TIME;-将元素ELEMENT2定义为时间类型ELEMENT3 STD_LOGIC;-将元素ELEMENT3定义为标准位类型END RECORD RECDATA;,【例】利用记录类型定义的一个微处理器命令信息表 TYPE REGNAME IS(AX,BX,CX,DX);TYPE OPERATION IS RECORD OPSTRSTRING(1 TO 10);OPCODEBIT_VECTOR(3 DOWNTO 0);OP1,OP2,RES:REGNAME;END RECORD OPERATION;VARIABLE INSTR1,INSTR2:OPERATION;INSTR1:=(ADD AX,BX,0001,AX,BX,AX);INSTR2:=(ADD AX,BX,“0010,OTHERS=BX);VARIABLE INSTR3OPERATION;INSTR3.OPSTR:=MU AX,BX;INSTR3.OP1:=AX;,3.2.3 用户定义的子类型,设计者还可以对已定义的数据类型的取值范围加以限制,形成新的数据类型,称为用户定义的子类型。子类型定义的一般格式为 SUBTYPE 子类型名 IS 数据类型名 范围;例如,可定义一种适用于数码管的数据类型digit:SUBTYPE digit IS INTEGER RANGE 0 TO 9;除了定义新的数据类型之外,设计者还可以通过限制和约束已有的数据类型来达到同样的目的。例如,可以使用RANGE子句来将整型信号digit的取值限制在09之间:SIGNAL digit:INTEGER RANGE 0 TO 9;同样,可以限制STD LOGIC类型得到取值限制为X、0、1 或 Z的变量var1:VARIABLE var1 STD LOGIC RANGE X TO Z,3.2.4 数据类型的转换,为了实现正确的代入操作,必须将要代入的数据进行类型转换。变换函数通常由VHDL语言的包集合提供。见书P4243,3.2.5 数据类型的限定,数据类型的限定方式是在数据前加上“类型名”AYY=“11111111”;,3.2.6 IEEE标准”STD_LOGIC”,”STD_LOGIC_VECTOR”,1)标准逻辑位STD_LOGIC数据类型 数据类型STD_LOGIC的定义如下所示:TYPE STD_LOGIC IS(U,X,0,1,Z,W,L,H,-);各值的含义是:U-未初始化的,X-强未知的,0-强0,1-强1,Z-高阻态,W-弱未知的,L-弱0,H-弱1,-忽略。在程序中使用此数据类型前,需加入下面的语句:LIBRARY IEEE;STD_LOGIC是标准的BIT数据类型的扩展,共定义了九种值。,2)标准逻辑矢量(STD_LOGIC_VECTOR)数据类型STD_LOGIC_VECTOR类型定义如下:TYPE STD_LOGIC_VECTOR IS ARRAY(NATURA RANGE)OF STD_LOGIC;【例】TYPE T_DATA IS ARRAY(7 DOWNTO 0)OF STD_LOGIC;-自定义数组类型SIGNA DATABUS,MEMORY:T_DATA;-定义信号DATABUS,MEMORYCPUPROCESS IS-CPU工作进程开始VARIABLE REG1T_DATA;-定义寄存器变量REG1BEGIN DATABUS=REG1;-向8位数据总线赋值END PROCESS CPU;-CPU工作进程结束MEMPROCESS IS-RAM工作进程开始BEGIN DATABUS=MEMORY;END PROCESS MEM;,3.3 VHDL语言的运算操作符,VHDL语言中共有四类运算,即逻辑运算、关系运算、算术运算和并置运算。前三类操作符是完成逻辑和算术运算的最基本的操作符的单元。关系运算和算术运算的运算规则及运算符与常用的程序设计语言的几乎完全相同,主要的差别可能只有两个:。不等号是“/=”,乘方运算符是“*”,3.3.1 逻辑运算符,六种逻辑运算符 NOT取反 AND与 OR或 NAND与非 NOR或非 XOR异或。注意:运算符的左边和右边,以及代入的信号的数据类型必须是相同的。左右没有优先级差别a=b AND c AND d AND e;a=(b AND c)OR(d AND e);NOT优先级最高,3.3.2 算术运算符,10种算术运算符:加 减*乘/除MOD 求模REM 求余 正(一元运算)负(一元运算)*指数ABS 取绝对值,3.3.3 关系运算符,6种关系运算符:等于/=不等于 大于=大于等于进行关系运算时,左右两边操作数的数据类型必须相同,但是位长度不一定相同,对3位和4位的位矢量进行比较,SIGNAL a:STD_LOGIC_VECTOR(3 DOWNTO 0);SIGNAL a:STD_LOGIC_VECTOR(3 DOWNTO 0);,3.3.4 并置运算符,并置运算符“&”用于位的连接用于将多个位连接成位矢量。使用该运算符,可以将两个位变量连接成长度为2的位矢量。实际上,这种运算与程序设计语言中将字符连接成字符串的操作很相似。,a=a3,提醒,由于VHDL有非常严格的数据类型规定,因此在编写VHDL程序时,必须保证操作数的类型与运算符所要求的类型一致,否则就必须重新定义操作数的类型或者换成相应的运算符,各种操作符的使用说明,(1)严格遵循在基本操作符间操作数是同数据类型的规则;严格遵循操作数的数据类型必须与操作符所要求的数据类型完全一致的规则。(2)注意操作符之间的优先级别。当一个表达式中有两个以上的运算符时,可使用括号将这些运算分组。(3)VHDL共有七种基本逻辑操作符,对于数组型(如STD_LOGIC_VECTOR)数据对象的相互作用是按位进行的。(4)关系操作符的作用是将相同数据类型的数据对象进行数值比较(=、/=)或关系排序判断(、=),并将结果以布尔类型(BOOLEAN)的数据表示出来,即TRUE或FALSE两种。,