1、第4章 VHDL的数据类型与运算操作符第4章 VHDL的数据类型与运算操作符4.1 VHDL的客体及其分类4.2 VHDL的数据类型4.3 VHDL的运算操作符习题与思考题第4章 VHDL的数据类型与运算操作符4.1 VHDL的客体及其分类在VHDL中,凡是可以赋予一个值的对象就称为客体(Object)。客体主要包括以下4种:信号(Signal)、变量(Variable)、常数(Constant)、文件(File)。在电子电路设计中,这4类客体通常都具有一定的物理含义。例如,信号对应地代表物理设计中的某一条硬件连接线,常数对应地代表数字电路中的电源和地等。当然,变量对应关系不太直接,通常只代表
2、暂存某些值的载体。4类客体的含义和说明场合如表4-1所示。第4章 VHDL的数据类型与运算操作符第4章 VHDL的数据类型与运算操作符4.1.1 常数常数(Constant)是一个固定的值。所谓常数说明,就是对某一常数名赋予一个固定的值。通常赋值在程序开始前进行,该值的数据类型则在说明语句中指明。常数说明的一般格式如下:CONSTANT 常数名:数据类型:=表达式;第4章 VHDL的数据类型与运算操作符例如:CONSTANT VCC:REAL:=5.0;CONSTANT DALY:TIME:=100ns;CONSTANT FBUS:BIT_VECTOR:=0101;第4章 VHDL的数据类型与
3、运算操作符常数一旦被赋值就不能再改变。上面VCC被赋值为5.0 V,那么在所有的VHDL程序中VCC的值就固定为5.0 V,它不像后面所提到的信号和变量那样,可以任意代入不同的数值。另外,常数所赋的值应和定义的数据类型一致。例如:CONSTANT VCC:REAL:=“0101”;这样的常数说明显然是错误的。第4章 VHDL的数据类型与运算操作符4.1.2 变量在93版中,变量(Variable)增添了一种可在全局引用的共享变量(Shared Variable),但初学者应慎用。因为,几个进程执行的时序不同会产生不同的结果。以后书中未作特殊说明的变量都是局部变量。第4章 VHDL的数据类型与运
4、算操作符1.共享变量前面已经提到信号和变量的重要区别是:信号可以是全局量,只要在构造体中已定义,那么在构造体内的所有地方都可以使用;变量是局部量,只能在进程、子程序内部定义和使用。如果要将结果带出外部,则必须将变量值赋给某一个信号量才行。但是,实际使用过程中有时希望进程或子程序中的结果以变量形式进行数据传递,因此,在93版中定义了共享变量。共享变量的说明格式如下:SHARED VARIABLE变量名:子类型名 :=初始值;第4章 VHDL的数据类型与运算操作符第4章 VHDL的数据类型与运算操作符p1进程在时钟上升沿将共享变量notclk置为“0”,而p2进程在时钟下降沿将notclk置为“1
5、”,从而使notclk和clk在任何时刻其值正好相反。共享变量除在进程和子程序的说明域中不能使用外,在其他任何地方都可以使用。但是,如前所述,初学者应慎用,因为几个并发进程执行的时序不同,会产生不同的结果。第4章 VHDL的数据类型与运算操作符2局部变量局部变量只能在进程语句、函数语句和过程语句结构中使用,它是一个局部量。在仿真过程中,它不像信号那样,到了规定的仿真时间才进行赋值,局部变量的赋值是立即生效的。局部变量说明语句的格式如下:VARIABLE 变量名:数据类型 约束条件:=表达式;第4章 VHDL的数据类型与运算操作符例如:VARIABLE x,y:INTEGER;VARIABLE
6、count:INTEGER RANGE 0 TO 255:=10;局部变量在赋值时不能产生附加延时。例如,tmp1、tmp2、tmp3都是局部变量,那么下式产生延时的方式是不合法的:tmp3:=tmp1+tmp2 AFTER 10 ns;第4章 VHDL的数据类型与运算操作符4.1.3 信号信号(Signal)是电子电路内部硬件连接的抽象。它除了没有数据流动方向说明以外,其他性质几乎和前面所述的“端口”概念一致。信号通常在构造体、包集合和实体中说明。信号说明的语句的格式如下:SIGNAL 信号名:数据类型 约束条件:=表达式;第4章 VHDL的数据类型与运算操作符例如:SIGNAL sys_c
7、lk:BIT:=0;SIGNAL ground:BIT:=0;在程序中,信号值的代入采用“=”代入符,而不是像变量赋值时用“:=”符,而且信号代入时可以附加延时。例如,s1和s2都是信号,且s2的值经10ns延时以后才被代入s1。此时信号传送语句可写为s1=s2 AFTER 10ns;第4章 VHDL的数据类型与运算操作符信号是一个全局量,它可以用来进行进程之间的通信。一般来说,在VHDL中对信号赋值是按仿真时间来进行的。信号值的改变也需按仿真时间的计划表行事。在93版中可对信号赋无效值,以表明不改变当前驱动器的输出值。例如:a=NULL;执行该条语句,a的信号值将不发生变化。第4章 VHDL
8、的数据类型与运算操作符4.1.4 信号和变量值代入的区别信号和变量值的代入不仅形式不同,其操作过程也不相同。在变量的赋值语句中,该语句一旦被执行,其值立即被赋予变量。在执行下一条语句时,该变量的值就为上一句新赋的值。变量的赋值符为“:=”。信号代入语句采用“=”代入符,该语句即使被执行也不会使信号立即发生代入,下一条语句执行时,仍使用原来的信号值。由于信号代入语句是同时进行处理的,因此,实际代入过程和代入语句的处理是分开进行的。第4章 VHDL的数据类型与运算操作符如图4-1所示,信号C和D的代入值(A+B)和(C+B)将由PROCESS外部通过进程的敏感信号A、B、C取得。进程执行时,只从信
9、号所对应的实体取值,只要不碰到WAIT语句或进程执行结束,进程执行过程中信号值是不进行代入的。如图4-2所示,为了进行仿真,需要让代入和处理交替反复进行。第4章 VHDL的数据类型与运算操作符图4-1 信号代入值的取得 第4章 VHDL的数据类型与运算操作符图4-2 进程语句的顺序处理第4章 VHDL的数据类型与运算操作符【例4-1】以下是两个进程描述的语句。首先,由于信号A发生变化使进程语句开始启动执行。这样一来,仿真器对进程中的各语句自上至下地进行处理。当进程所有语句执行完毕,或者中途碰到WAIT语句时,该进程执行结束,信号代入过程被执行,代入同样应按顺序自上至下地进行。第4章 VHDL的
10、数据类型与运算操作符第4章 VHDL的数据类型与运算操作符结果:X=B+A;Y=B+C;在例4-1的第一个进程中,D中最初代入的值是A,接着又代入C值。尽管D中先代入A值,后代入C值,在时间上有一个的延时,但是,在代入时由于不进行处理,因此仿真时认为是时间0值延时。D的最终值应为C,这样X和Y的内容都为B+C。第4章 VHDL的数据类型与运算操作符在例4-1的第二个进程中,D是变量。在执行“D:=A;”语句以后,A的值就被赋给D,所以X为B+A。此后又执行“D:=C;”,从而使Y为B+C。从这里可以看出,信号量的值将进程语句最后所代入的值作为最终代入值,而变量的值一经赋值就变成新的值。这就是变
11、量赋值和信号代入在操作上的区别。第4章 VHDL的数据类型与运算操作符4.1.5 文件在VHDL中提供了一个预先定义的包集合文本输入/输出包集合(TEXTIO),在该TEXTIO中包含有对文本文件进行读/写的过程和函数。这些文本文件都是ASCII码文件,其格式可根据编程人员的需要设定(VHDL对文件格式不作任何限制,但是主机对此往往有一定限制)。TEXTIO按行对文件进行处理,一行为一个字符串,并以回车、换行符作为行结束符。第4章 VHDL的数据类型与运算操作符1文件类型定义的格式文件类型定义的格式如下:TYPE 类型名IS FILE OF 类型/子类型名;例如:TYPE index IS R
12、ANGE 0 TO 15;TYPE int_ftype IS FILE OF index;第4章 VHDL的数据类型与运算操作符2文件操作语句TEXTIO中提供了打开文件、关闭文件、从文件读/写一行的过程及检查文件结束的函数:FILE_OPEN(文件名,“外部文件名”,文件读写类型)FILE_CLOSE(文件名)READWRITEENDFILE(文件名)TEXTIO还隐含行读和行写两个子过程;READLINE(目的行变量,源行变量)WRITELINE(目的行变量,源行变量)第4章 VHDL的数据类型与运算操作符TEXTIO也对用于处理文本文件的数据类型作了具体说明。数据类型line(行)是读/
13、写文本文件时要用的,line的结构是TEXTIO对文件进行操作的基本单位。例如,对文件进行读操作时,首先读一行字符,并将它放到line数据类型的结构中,而后再按字段进行处理。具体应用实例将在第9章中详述。第4章 VHDL的数据类型与运算操作符4.2 VHDL的数据类型如前所述,在VHDL中信号、变量、常数都要指定数据类型,因此,VHDL提供了多种标准的数据类型。另外,为使用户设计方便,还可以由用户自定义数据类型。这样使语言的描述能力及自由度得到了更进一步的提高,从而为系统高层次的仿真提供了必要手段。与此相反,VHDL的数据类型的定义相当严格,不同类型之间的数据不能直接代入,而且即使数据类型相同
14、,位长不同也不能直接代入。这样,为了熟练地使用VHDL编写程序,必须很好地理解各种数据类型的定义。第4章 VHDL的数据类型与运算操作符4.2.1 标准的数据类型标准的数据类型共有10种,如表4-2所示。第4章 VHDL的数据类型与运算操作符下面对各数据类型作一简要说明。1整数(Integer)整数与数学中整数的定义相同。在VHDL中,整数的表示范围为-21474836472147483647,即-(231-1)(231-1)。千万不要把一个实数(含小数点的数)赋予一个整数变量,这是因为VHDL是一个强类型语言,它要求在赋值语句中的数据类型必须匹配。整数的例子如下:+136,+12456,-4
15、57第4章 VHDL的数据类型与运算操作符尽管整数值在电子系统中可能是用一系列二进制位值来表示的,但是整数不能看作位矢量,也不能按位来进行访问,对整数不能用逻辑操作符。当需要进行位操作时,可以用转换函数,将整数转换成位矢量。目前,有的CAD厂商所提供的工具中对此规定已有所突破,允许对有符号和无符号的整型量进行算术逻辑运算。在电子系统的开发过程中,整数也可以作为对信号总线状态的一种抽象手段,用来准确地表示总线的某一种状态。第4章 VHDL的数据类型与运算操作符2实数(Real)在进行算法研究或者实验时,作为对硬件方案的抽象手段,常常采用实数四则运算。实数的定义值范围为-1.0E+38+1.0E+
16、38。实数有正负数,书写时一定要有小数点。例如:-1.0,+2.5,-1.0E+38有些数可以用整数表示,也可以用实数表示。例如,数字1的整数表示为1,而用实数表示则为1.0。两个数的值是一样的,但数据类型却不一样。第4章 VHDL的数据类型与运算操作符3位(Bit)在数字系统中,信号值通常用一个位来表示。位值的表示方法是:用字符0或者1(将值放在单引号中)来表示。位与整数中的1和0不同,1和0仅仅表示一个位的两种取值。位值有时也可以显式说明,例如:BIT(1)位数据可以用来描述数字系统中总线的值。位数据不同于布尔数据,当然也可以用转换函数进行转换。第4章 VHDL的数据类型与运算操作符4位矢
17、量(Bit_Vector)位矢量是93版扩展的数据类型,它是用双引号括起来的扩展的数字序列。例如:B“001_101_010”9位二进制位串;X“A_F0_FC”20位十六进制位串;O“3701”12位八进制位串;X“”空位串。在这里,位矢量最前面的B、X、O表示二、十六、八进制。用位矢量数据表示总线状态最形象也最方便,在以后的VHDL程序中将会经常遇到。第4章 VHDL的数据类型与运算操作符5布尔量(Boolean)一个布尔量具有两种状态“真”或者“假”。虽然布尔量也是二值枚举量,但它和位不同,没有数值的含义,也不能进行算术运算。它能进行关系运算。例如,它可以在IF语句中被测试,测试结果产生
18、一个布尔量TRUE或者FALSE。一个布尔量常用来表示信号的状态或者总线上的情况。如果某个信号或者变量被定义为布尔量,那么在仿真中将自动地对其赋值进行核查。一般这一类型的数据的初始值总为FALSE。第4章 VHDL的数据类型与运算操作符6字符(Character)字符也是一种数据类型,所定义的字符量通常用单引号括起来,如A。一般情况下VHDL对大小写不敏感,但是对字符量中的大、小写字符则认为是不一样的。例如,B不同于b。字符量中的字符可以是az中的任一个字母、09中的任一个数以及空白或者特殊字符,如$、%等。包集合STANDARD中给出了预定义的128个ASCII码字符类型,不能打印的用标识符
19、给出。字符1与整数1和实数1.0都是不相同的。当要明确指出1的字符数据时,可写为CHARACTER(1)第4章 VHDL的数据类型与运算操作符7字符串(String)字符串是由双引号括起来的一个字符序列,也称为字符矢量或字符串数组。例如:integer range字符串常用于程序的提示和说明。第4章 VHDL的数据类型与运算操作符8时间(Time)时间是一个物理量数据。完整的时间量数据应包含整数和单位两部分,而且整数和单位之间至少应留一个空格的位置。例如,55sec、2min等。在包集合STANDARD中给出了时间的预定义,其单位为fs、ps、ns、ms、ms、sec、min、hr。下面是时间
20、数据的例子:20 ms,100ns,3sec在系统仿真时,时间数据特别有用,用它可以表示信号延时,从而使模型系统更逼近实际系统的运行环境。第4章 VHDL的数据类型与运算操作符9错误等级(Severity Level)错误等级类型数据用来表征系统的状态,共有4种:NOTE(注意)、WARNING(警告)、ERROR(出错)、FAILURE(失败)。在系统仿真过程中,可以用这4种状态来提示系统当前的工作情况。这样可以使操作人员随时了解当前系统工作的情况,并根据系统的不同状态采取相应的对策。第4章 VHDL的数据类型与运算操作符10大于等于零的整数(Natural,自然数)、正整数(Positiv
21、e)这两类数据是整数的子类,Natural类数据只能取值0和0以上的正整数,Positive只能为正整数。上述10种数据类型是VHDL中标准的数据类型,在编程时可以直接引用。如果用户需使用这10种以外的数据类型,则必须进行自定义。大多数CAD厂商已在包集合中对标准数据类型进行了扩展,例如数组型数据等,这一点请读者注意。第4章 VHDL的数据类型与运算操作符由于VHDL属于强类型语言,因此在仿真过程中,首先要检查赋值语句中的类型和区间,任何一个信号和变量的赋值均须落入给定的约束区间中,也就是说要落入有效数值的范围中。约束区间的说明通常跟在数据类型说明的后面。例如:INTEGER RANGE 10
22、0 DOWNTO 1BIT_VECTOR(3 DOWNTO 0)REAL RANGE 2.0 TO 30.0这里DOWNTO表示下降,TO表示上升。第4章 VHDL的数据类型与运算操作符对于一个BCD数的比较器,利用约束区间说明的端口说明语句可以写为ENTITY bcd_compare ISPORT(a,b:IN INTEGER RANGE 0 TO 9:=0;c:OUT BOOLEAN);END ENTITY bcd_compare;第4章 VHDL的数据类型与运算操作符4.2.2 用户定义的数据类型VHDL使用户最感兴趣的一个特点是:可以由用户自己来定义数据类型。用户定义数据类型的书写格式
23、如下:TYPE 数据类型名,数据类型名 数据类型定义;在VHDL语中还存在不完整的用户定义的数据类型的书写格式:TYPE 数据类型名,数据类型名;这种由用户进行的数据类型定义是一种利用其他已定义的说明所进行的“假”定义,因此它不能进行逻辑综合。第4章 VHDL的数据类型与运算操作符可由用户定义的数据类型有如下几种:枚举(Enumerated)类型;整数(Integer)类型;实数(Real)、浮点数(Floating)类型;数组(Array)类型;存取(Access)类型;文件(File)类型;记录(Recode)类型;时间(Time)类型(物理类型)。下面对常用的几种用户定义的数据类型作一说
24、明。第4章 VHDL的数据类型与运算操作符1枚举类型在逻辑电路中,所有的数据都是用“1”或“0”来表示的,但是人们在考虑逻辑关系时,只有数字往往是不方便的。在VHDL中,可以用符号名来代替数字。例如,在表示一周每一天状态的逻辑电路中,可以假设“000”为星期天,“001”为星期一。这对阅读程序是颇不方便的。为此,可以定义一个叫“week”的数据类型。TYPE week IS(sun,mon,tue,wed,thu,fri,sat);由上述定义可知,凡是用于代表星期二的日子都可以用tue来代替,这比用代码“010”表示星期二直观多了,使用时也不易出错。第4章 VHDL的数据类型与运算操作符枚举类
25、型数据的定义格式如下:TYPE 数据类型名IS(元素,元素,);这类用户定义的数据类型的应用相当广泛,例如在包集合“STD_LOGIC”和“STD_LOGIC_1164”中都有此类数据的定义。例如:TYPE STD_LOGIC IS(U,X,0,1,Z,W,L,H,-);第4章 VHDL的数据类型与运算操作符2整数类型和实数类型整数类型在VHDL中已存在,这里所说的是用户定义的整数类型,实际上可以认为是整数的一个子类。例如,在一个数码管上显示数字,其值只能取09的整数。如果由用户定义一个用于数码显示的数据类型,那么就可以写为TYPE digit IS INTEGER RANGE 0 TO 9;
26、同理,实数类型也如此。例如:TYPE current IS REAL RANGE-1E4 TO 1E4;据此可以总结出整数或实数用户定义数据类型的格式为TYPE 数据类型名 IS 数据类型定义约束范围;第4章 VHDL的数据类型与运算操作符3数组类型数组是将相同类型的数据集合在一起所形成的一个新的数据类型。它可以是一维的,也可以是二维或多维的。数组定义的书写格式如下:TYPE 数据类型名 IS ARRAY 范围 OF 原数据类型名;在这里如果范围这一项没有被指定,则使用整数数据类型。例如:TYPE word IS ARRAY(1 TO 8)OF STD_LOGIC;第4章 VHDL的数据类型与
27、运算操作符若范围这一项需用整数类型以外的其他数据类型,则在指定数据范围前应加数据类型名。例如:TYPE word IS ARRAY(INTEGER 1 TO 8)OF STD_LOGIC;TYPE instruction IS(ADD,SUB,INC,SRL,SRF,LDA,LDB,XFR);SUBTYPE digit IS INTEGER 0 TO 9;TYPE insflag IS ARRAY(instruction ADD TO SRF)OF digit;第4章 VHDL的数据类型与运算操作符数组在总线定义及ROM、RAM等的系统模型中使用。“STD_LOGIC_VECTOR”也属于数组
28、数据类型,它在包集合“STD_LOGIC_1164”中被定义:TYPE STD_LOGIC_VECTOR IS ARRAY(NATURAL RANGE)OF STD_LOGIC;这里范围由“RANGE”指定,这是一个没有范围限制的数组。在这种情况下,范围由信号说明语句等确定。例如:SIGNAL aaa:STD_LOGIC_VECTOR(3 DOWNTO 0);在函数和过程的语句中,当使用无限制范围的数组时,其范围一般由调用者所传递的参数来确定。第4章 VHDL的数据类型与运算操作符多维数组需要用两个以上的范围来描述,而且多维数组不能生成逻辑电路,只能用于生成仿真图形及硬件的抽象模型。例如:第4
29、章 VHDL的数据类型与运算操作符上述例子是二维的。在三维情况下要用3个范围来描述。在代入初值时,各范围最左边所说明的值为数组的初始位脚标。在上例中(0,7)是起始位,接下去右侧范围向右移一位变为(0,6),以后顺序为(0,5),(0,4),(0,0)。然后,左侧范围向右移一位变为(1,7),此后按此规律移动得到最后一位(5,0)。第4章 VHDL的数据类型与运算操作符4时间类型(物理类型)表示时间的数据类型在仿真时是必不可少的,其书写格式如下:TYPE 数据类型名 IS 范围;UNITS 基本单位;单位;END UNITS;第4章 VHDL的数据类型与运算操作符例如:这里的基本单位是“fs”
30、,其1000倍是“ps”,以此类推。时间是物理类型的数据。当然,对容量、阻抗值等也可以进行定义。第4章 VHDL的数据类型与运算操作符5记录类型数组是同一类型数据集合起来形成的,而记录则是将不同类型的数据和数据名组织在一起而形成的新客体。记录数据类型的定义格式如下:第4章 VHDL的数据类型与运算操作符从记录数据类型中提取元素数据类型时,应使用“.”。例如:第4章 VHDL的数据类型与运算操作符用记录描述SCSI总线及通信协议是比较方便的。在生成逻辑电路时应将记录数据类型分解开来。因此,记录类型比较适用于系统仿真。第4章 VHDL的数据类型与运算操作符4.2.3 用户定义的子类型用户定义的子类
31、型是用户对已定义的数据类型作一些范围限制而形成的一种新的数据类型。子类型的名称通常采用用户较易理解的名字。子类型定义的一般格式如下:SUBTYPE 子类型名 IS 数据类型名;例如,在“STD_LOGIC_VECTOR”基础上所形成的子类如下:SUBTYPE iobus IS STD_LOGIC_VECTOR(7 DOWNTO 0);SUBTYPE digit IS INTEGER RANGE 0 TO 9;第4章 VHDL的数据类型与运算操作符子类型可以对原数据类型指定范围而形成,也可以完全和原数据类型范围一致。例如:此外,子类型还常用于存储器阵列等的数组描述场合。新构造的数据类型及子类型通
32、常在包集合中定义,再由USE语句装载到描述语句中。第4章 VHDL的数据类型与运算操作符4.2.4 数据类型的转换在VHDL中,数据类型的定义是相当严格的,不同类型的数据是不能进行运算和直接代入的。为了实现正确的代入操作,必须将要代入的数据进行类型变换,这就是所谓的类型变换。变换函数通常由VHDL的包集合提供。例如,在“STD_LOGIC_1164”、“STD_LOGIC_ARITH”、“STD_LOGIC_UNSIGNED”的包集合中提供了如表4-3所示的数据类型变换函数。第4章 VHDL的数据类型与运算操作符第4章 VHDL的数据类型与运算操作符【例4-2】由“STD_LOGIC_VECT
33、OR”变换成“INTEGER”的实例。第4章 VHDL的数据类型与运算操作符此外,由“BIT_VECTOR”变换成“STD_LOGIC_VECTOR”也非常方便。代入“STD_LOGIC_VECTOR”的值只能是二进制数,而代入“BIT_VECTOR”的值除二进制数以外,还可能是十六进制数和八进制数。不仅如此,“BIT_VECTOR”还可以用“_”来分隔数值位。下面的几个语句表示了“BIT_VECTOR”和“STD_LOGIC_VECTOR”的赋值语句:第4章 VHDL的数据类型与运算操作符第4章 VHDL的数据类型与运算操作符4.2.5 数据类型的限定在VHDL中,有时可以用所描述文字的上下
34、关系来判断某一数据的数据类型。例如:SIGNAL a:STD_LOGIC_VECTOR(7 DOWNTO 0);a=“01101010”;联系上下文关系,可以断定“01101010”不是字符串(String),也不是位矢量(Bit_Vector),而是“STD_LOGIC_VECTOR”。但是,也有判断不出来的情况。例如:第4章 VHDL的数据类型与运算操作符在该例中,a&b&c的数据类型如果不确定,那么就会发生错误。在这种情况下就要对数据进行类型限定(这类似于C语言中的强制方式)。数据类型限定的方式是在数据前加上“类型名”。第4章 VHDL的数据类型与运算操作符例如:数据类型的限定方式与数据
35、类型的变换很相似,这一点应引起读者注意。第4章 VHDL的数据类型与运算操作符4.2.6 IEEE标准“STD_LOGIC”和“STD_LOGIC_VECTOR”在上面的数据类型介绍中,曾讲到VHDL的标准数据类型“BIT”,它是一个逻辑型的数据类型。这类数据取值只能是“0”和“1”。由于该类型数据不存在不定状态X,因此不便于仿真。另外,由于它也不存在高阻状态,因此也很难用来描述双向数据总线。为此,IEEE在1993年制定出了新的标准(IEEE STD1164),使得“STD_LOGIC”型数据可以具有如下9种不同的值:第4章 VHDL的数据类型与运算操作符U初始值;X不定;00;11;Z高阻
36、;W弱信号不定;L弱信号0;H弱信号1;不可能情况。第4章 VHDL的数据类型与运算操作符“STD_LOGIC”和“STD_LOGIC_VECTOR”是IEEE新制定的标准化数据类型,也是在VHDL语法以外所添加的数据类型,因此将它归属到用户定义的数据类型中。当使用该类型数据时,在程序中必须写出库说明语句和使用包集合的说明语句。第4章 VHDL的数据类型与运算操作符4.3 VHDL的运算操作符在VHDL中共有4类操作符,可以分别进行逻辑运算(Logical)、关系运算(Relational)、算术运算(Arithmetic)和并置运算(Concatenation)。需要注意的是,被操作符所操作
37、的对象是操作数,且操作数的类型应该和操作符所要求的类型相一致。另外,运算操作符是有优先级的,例如逻辑运算符NOT在所有操作符中其优先级最高。表4-4给出了主要操作符的优先级。第4章 VHDL的数据类型与运算操作符第4章 VHDL的数据类型与运算操作符第4章 VHDL的数据类型与运算操作符4.3.1 逻辑运算符在VHDL的87版中,逻辑运算符共有以下6种:NOT取反;AND与;OR或;NAND与非;NOR或非;XOR异或。第4章 VHDL的数据类型与运算操作符在93版中增加了6种新的逻辑运算符:SLL逻辑左移;SRL逻辑右移;SLA算术左移;SRA算术右移;ROL逻辑循环左移;ROR逻辑循环右移
38、。第4章 VHDL的数据类型与运算操作符这12种逻辑运算符可以对“STD_LOGIC”和“BIT”等的逻辑型数据、“STD_LOGIC_ VECTOR”逻辑型数组及布尔型数据进行逻辑运算。必须注意,运算符的左边和右边,以及代入信号的数据类型必须是相同的。当一个语句中存在两个以上逻辑表达式时,在C语言中运算有自左至右的优先级顺序的规定,而在VHDL中,左右没有优先级差别。例如,在下例中,如去掉式中的括号,那么从语法上来说是错误的:X=(a AND b)OR(NOT c AND d);第4章 VHDL的数据类型与运算操作符当然也有例外,如果一个逻辑表达式中只有“AND”、“OR”、“XOR”中的一
39、种运算符,那么改变运算顺序将不一定会导致逻辑的改变。此时,括号是可以省略的。例如:a=b AND c AND d AND e;a=b OR c OR d OR e;a=b XOR c XOR d XOR e;a=(b NAND c)NAND d)NAND e;(必须要括号)a=(b AND c)OR(d AND e);(必须要括号)在所有逻辑运算符中,NOT的优先级最高。第4章 VHDL的数据类型与运算操作符4.3.2 算术运算符VHDL中有以下10种算术运算符:+加;-减;*乘;/除;MOD求模;REM取余;+正(一元运算);-负(一元运算);*指数;ABS取绝对值。第4章 VHDL的数据类
40、型与运算操作符在算术运算中,一元运算的操作数(正、负)可以为任何数值类型(整数、实数、物理量)。加法和减法的操作数也可以为任意数值类型,但应具有相同的数据类型。乘、除法的操作数可以同为整数和实数。物理量可以被整数或实数相乘或相除,其结果仍为一个物理量。物理量除以同一类型的物理量即可得到一个整数量。求模和取余的操作数必须是同一整数类型的数据。一个指数的运算符的左操作数可以是任意整数或实数,而右操作数应为一整数(只有在左操作数是实数时,右操作数才可以是负整数)。第4章 VHDL的数据类型与运算操作符实际上,能够真正综合逻辑电路的算术运算符只有“+”、“-”、“*”。在数据位较长的情况下,在使用算术
41、运算符进行运算,特别是使用乘法运算符“*”时,应特别慎重。因为对于16位的乘法运算,综合时逻辑门电路会超过2000个门。对于算术运算符“”、“MOD”、“REM”,分母的操作数为2乘方的常数时,逻辑电路综合是可能的。当对“STD_LOGIC_VECTOR”进行“+”(加)、“-”(减)运算时,若两边的操作数和代入的变量位长不同,则会产生语法错误。另外,“*”运算符两边的位长相加后的值和要代入的变量的位长不相同时,同样也会出现语法错误。第4章 VHDL的数据类型与运算操作符4.3.3 关系运算符VHDL中有以下6种关系运算符:=等于;/=不等于;小于;大于;=大于等于。第4章 VHDL的数据类型
42、与运算操作符在关系运算符的左右两边是运算操作数,不同的关系运算符对两边的操作数的数据类型有不同的要求。其中,等号“=”和不等号“/=”可以适用所有类型的数据;其他关系运算符则可使用于整数(INTEGER)、实数(REAL)、位(STD_LOGIC)等枚举类型以及位矢量(STD_LOGIC_VECTOR)等数组类型的关系运算。在进行关系运算时,左右两边的操作数的数据类型必须相同,但是位长度不一定相同,当然也有例外的情况。在利用关系运算符对位矢量数据进行比较时,比较过程是从最左边的位开始,自左至右按位进行比较的。第4章 VHDL的数据类型与运算操作符在位长不同的情况下,只能将自左至右的比较结果作为
43、关系运算的结果。例如,对3位和4位的位矢量进行比较:第4章 VHDL的数据类型与运算操作符上例中,a的值为10,b的值为7,a应该比b大。但是,由于位矢量是从左至右按位比较的,当比较到次高位时,a的次高位为“0”,而b的次高位为“1”,因此比较结果b比a大。这样的比较结果显然是不符合实际情况的。为了能使位矢量进行关系运算,在包集合“STD_LOGIC_UNSIGNED”中对“STD_LOGIC_VECTOR”关系运算重新作了定义,使其可以正确地进行关系运算。注意:在使用时必须首先说明调用该包集合。当然,此时位矢量还可以和整数进行关系运算。第4章 VHDL的数据类型与运算操作符在关系运算符中,小
44、于等于符“=”和代入符“=”是相同的,在读VHDL的语句时,应按照上下文关系来判断此符号到底是关系符还是代入符。第4章 VHDL的数据类型与运算操作符4.3.4 并置运算符并置运算符“&”用于位的连接。例如,将4个位用并置运算符“&”连接起来就可以构成一个具有4位长度的位矢量。两个4位的位矢量用并置运算符“&”连接起来就可以构成8位长度的位矢量。图4-3就是使用并置运算符的实例。第4章 VHDL的数据类型与运算操作符图4-3 并置运算符使用实例第4章 VHDL的数据类型与运算操作符图4-3中,en是b(0)b(3)的允许输出信号,而y(0)y(7)中存在如下关系:y(0)=b(0)y(1)=b
45、(1)y(2)=b(2)y(3)=b(3)y(4)=a(0)y(5)=a(1)y(6)=a(2)y(7)=a(3)这种逻辑关系用并置运算符可以很容易地表达出来:tmp_b=b AND(en&en&en&en);y=a&tmp_b;第4章 VHDL的数据类型与运算操作符第一个语句表示b的4位位矢量由en进行选择得到一个4位位矢量输出。第二个语句表示4位位矢量a和4位位矢量b再次连接(并置)构成8位位矢量y输出。位的连接也可使用集合体的方法,将并置运算符换成逗号即可。例如:tmp_b=(en,en,en,en);但是,这种方法不适用于位矢量之间的连接。如下的描述方法是错误的:a=(a,tmp_b)
46、;第4章 VHDL的数据类型与运算操作符集合体也能指定位的脚标,例如上一个语句可表示如下:tmp_b en,2=en,1=en,0=en);或tmp_b en);在指定位的脚标时,也可以用“OTHERS”来说明:tmp_b en);注意:在集合体中“OTHERS”只能放在最后。假若b位矢量的脚标b(2)的选择信号为“0”,其他位的选择信号均为en,那么此时表达式可写为tmp_b 0,OTHERS=en);第4章 VHDL的数据类型与运算操作符习题与思考题4.1 VHDL中3类客体常数、变量和信号的实际物理含义是什么?4.2 信号和变量在描述和使用时有哪些主要区别?4.3 在VHDL中标准数据类
47、型有哪几类?用户可以自己定义的数据有哪几类?4.4 若一个十二进制计数器输出count12_out要用整数来描述,则应怎样进行定义?第4章 VHDL的数据类型与运算操作符4.5 下面数据类型的定义和操作是否正确?4.6 为什么要进行数据类型转换?查阅附录C,列出几种主要转换函数的名称。4.7 在习题4.5中为了实现将cint的值代入atmp,应怎样使用转换函数?第4章 VHDL的数据类型与运算操作符4.8 参阅附录C,说明STD_LOGIC、STD_ULOGIC、STD_LOGIC_VECTOR、STD_ULOGIC_VECTOR之间的关系。下列操作是否正确?第4章 VHDL的数据类型与运算操
48、作符4.9 BIT类型数据和STD_LOGIC类型数据有什么区别?4.10 VHDL有哪几类主要运算?在一个表达式中有多种运算符时应按怎样的准则进行运算?下面3个表达式是否等效?a=NOT b AND c OR d;a=(NOT b AND c)OR d;a=NOT b AND(c OR d);第4章 VHDL的数据类型与运算操作符4.11 并置运算应用于什么场合?下面的并置运算是否正确?SIGNAL a:STD_LOGIC;SIGNAL eb:STD_LOGIC;SIGNAL b:STD_LOGIC_VECTOR(3 DOWNTO 0);SIGNAL d:STD_LOGIC_VECTOR(7 DOWNTO 0);b=a&a&eb&eb;d=b&eb&eb&eb&eb;第4章 VHDL的数据类型与运算操作符感感 谢谢第4章 VHDL的数据类型与运算操作符谢谢,精品课件资料搜集