5. 基本运算符
VHDL定义了丰富的运算符,主要有算术运算符、关系运算符、逻辑运算符、赋值运算符、关联运算符和其他运算符。需要注意的是,操作数的数据类型应当与操作符所要求的数据类型一致。到目前为止,VHDL共有3个版本:VHDL87、VHDL93和VHDL2002。不同的版本对操作符的支持程度不同,具体可参见VHDL的参考手册。1)算术运算符(见表2-5)
乘方运算的左边可以是整数或实数,右边必须是整数,且只有左边为实数时,其右边才可以为负数。乘方运算只有在操作数是常数或2的乘方时,才能被综合。除法运算只有在除数为2的幂次时,才能被综合。
2)关系运算符(见表2-6)
要注意从程序的上下文区别关系运算符小于或等于“<=”和信号赋值运算符的不同。
3)逻辑运算符(见表2-7)
表2-7 逻辑运算符
其中sll将逻辑型数据左移,右端空出来的位置填充“0”;srl将逻辑型数据右移,左端空出来的位置填充“0”。而sla将逻辑型数据左移,同时复制最右端的位,在数据左移操作后填充在右端空出的位置上;sra将逻辑型数据右移,同时复制最左端的位,在数据右移操作后填充在左端空出的位置上。
循环逻辑左移rol将数据左移,同时从左端移出的位依次填充到右端空出的位置上,循环逻辑右移ror将数据右移,同时从右端移出的位依次填充到左端空出的位置上。其语法结构为:
<左操作数> <移位操作符> <右操作数>
其中,左操作数必须是bit_vector类型或boolean型的一维数组,右操作数必须是integer类型(前面可以加正负号)。
例如:
在此需要注意的是移位运算符是在VHDL93中引入的,如果在VHDL87下编译,则会提示出现操作符未定义的错误。
4)其他运算符(见表2-8)
表2-8 其他运算符
并置运算符“&”用于位连接,例如:
a <="1001"; b <="1100"; c <=a&b;
则:c为"10011100"。
在所有的运算符中,其优先级顺序按照从高到低依次为(1)乘方(**)、取绝对值(abs)、非(not)运算;
(2)乘(*)、除(/)、取模(mod)、求余(rem)运算;
(3)正(+)、负(-)号运算符;
(4)加(+)、减(-)、并置运算符;
(5)移位运算符;
(6)关系运算符;
(7)逻辑运算符。
在同一项中,运算符的优先级相同,在表达式中按“从左到右”的顺序依次计算,因此为了防止出错,建议在表达式中,不同的运算符之间尽量使用圆括号“()”。
另外,运算符在使用时,需要注意以下几个问题:
(1)尽可能用加法运算实现其他算术运算,以节约硬件资源。例如乘法运算符常常使逻辑门数大大增加。
(2)操作数的长度必须一致。操作符不同时,尽量加括号。
(3)移位操作的操作数必须是一维数组,数组中的元素必须是bit或布尔数据类型。
需要注意的是,EDA综合软件对运算符支持程度各不相同,使用时应参考综合工具的说明。
2.3 并行语句
VHDL内部的语句分为两大类:并行语句和顺序语句。并行语句是VHDL语言与传统软件描述语言最大的不同,所谓并行,是指这些语句相互之间是并行运行的,其执行方式与书写的顺序无关。并行语句放在结构体中,在执行中,并行语句之间可以有信息往来,也可以是互为独立、互不相关、异步运行的(如多时钟情况)。每一并行语句内部的语句运行方式可以有两种不同的方式,即并行执行方式(如块语句)和顺序执行方式(如进程语句)。
常用的并行语句有信号赋值语句、进程语句(process)、块语句(block)、元件例化语句(component)、生成语句(generate)和并行过程调用语句。
1. 信号赋值语句
信