如果算术操作符中的任意操作数是X或Z,那么整个结果为X。例如:
'b10x1 + 'b01111 结果为不确定数'bxxxxx 1. 算术操作结果的长度
算术表达式结果的长度由最长的操作数决定。在赋值语句下,算术操作结果的长度由操作符左端目标长度决定。考虑如下实例: reg [0:3] Arc, Bar, Crt; reg [0:5] Frx; . . .
Arc = Bar + Crt; Frx = Bar + Crt;
第一个加的结果长度由Bar,Crt和Arc长度决定,长度为4位。第二个加法操作的长度同样由Frx的长度决定(Frx、Bat和Crt中的最长长度),长度为6位。在第一个赋值中,加法操作的溢出部分被丢弃;而在第二个赋值中,任何溢出的位存储在结果位Frx[1]中。
在较大的表达式中,中间结果的长度如何确定?在Verilog HDL中定义了如下规则:表达式中的所有中间结果应取最大操作数的长度(赋值时,此规则也包括左端目标)。考虑另一个实例: wire [4:1] Box, Drt; wire [1:5] Cfg; wire [1:6] Peg; wire [1:8] Adt; . . .
assign Adt = (Box + Cfg) + (Drt + Peg);
表达式左端的操作数最长为6,但是将左端包含在内时,最大长度为8。所以所有的加操作使用8位进行。例如:Box和Cfg相加的结果长度为8位。
2. 无符号数和有符号数
执行算术操作和赋值时,注意哪些操作数为无符号数、哪些操作数为有符号数非常重要。无符号数存储在: * 线网 * 一般寄存器
* 基数格式表示形式的整数 有符号数存储在: * 整数寄存器
* 十进制形式的整数
下面是一些赋值语句的实例: reg [0:5] Bar; integer Tab; . . .
Bar = -4'd12; //寄存器变量Bar的十进制数为52,向量值为110100。 Tab = -4'd12; //整数Tab的十进制数为-12,位形式为110100。 -4'd12 / 4 //结果是1073741821。 -12 / 4 //结果是-3
因为Bar是普通寄存器类型变量,只存储无符号数。右端表达式的值为'b110100(12的二进制补码)。因此在赋值后,Bar存储十进制值52。在第二个赋值中,右端表达式相同,值为'b110100,但此时被赋值为存储有符号数的整数寄存器。Tab存储十进制值-12(位向量为110100)。注意在两种情况下,位向量存储内容都相同;但是在第一种情况下,向量被解释为无符号数,而在第二种情况下,向量被解释为有符号数。 下面为具体实例: Bar = - 4'd12/4; Tab = - 4'd12 /4; Bar = - 12/4 Tab = - 12/4
在第一次赋值中,Bar被赋于十进制值61(位向量为111101)。而在第二个赋值中,Tab被赋于与十进制1073741821(位值为0011...11101)。Bar在第三个赋值中赋于与第一个赋值相同的值。这是因为Bar只存储无符号数。在第四个赋值中,Bar被赋于十进制值-3。 下面是另一些例子: Bar = 4 - 6; Tab = 4 - 6;
Bar被赋于十进制值62(-2的二进制补码),而Tab被赋于十进制值-2(位向量为111110)。 下面为另一个实例: Bar = -2 + (-4); Tab = -2 + (-4);
Bar被赋于十进制值58(位向量为111010),而Tab被赋于十进制值-6(位向量为111010)。 4.2.2 关系操作符
关系操作符有: * >(大于) * <(小于) * >=(不小于) * <=(不大于)
关系操作符的结果为真(1)或假(0)。如果操作数中有一位为X或Z,那么结果为X。例如: 23 > 45
结果为假(0),而: 52< 8'hxFF
结果为x。如果操作数长度不同,长度较短的操作数在最重要的位方向(左方)添0补齐。例如: 'b1000 > = 'b01110 等价于:
'b01000 > = 'b01110 结果为假(0)。 4.2.3 相等关系操作符 相等关系操作符有: * = =(逻辑相等) * !=(逻辑不等) * = = =(全等) * != =(非全等)
如果比较结果为假,则结果为0;否则结果为1。在全等比较中,值x和z严格按位比较。也就是说,不进行解释,并且结果一定可知。而在逻辑比较中,值x和z具有通常的意义,且结果可以不为x。也就是说,在逻辑比较中,如果两个操作数之一包含x或z,结果为未知的值(x)。 如下例,假定: Data = 'b11x0; Addr = 'b11x0; 那么: Data = = Addr
不定,也就是说值为x,但: Data = = = Addr 为真,也就是说值为1。
如果操作数的长度不相等,长度较小的操作数在左侧添0补位,例如:
2'b10 = = 4'b0010 与下面的表达式相同: 4'b0010 = = 4'b0010 结果为真(1)。 4.2.4 逻辑操作符 逻辑操作符有: * && (逻辑与) * || (逻辑或) * !(逻辑非)
这些操作符在逻辑值0或1上操作。逻辑操作的结构为0或1。例如, 假定:
Crd = 'b0; //0为假 Dgs = 'b1; //1为真 那么:
Crd && Dgs 结果为0 (假) Crd || Dgs 结果为1 (真) ! Dgs 结果为0 (假)
对于向量操作, 非0向量作为1处理。例如,假定: A_Bus = 'b0110; B_Bus = 'b0100; 那么:
A_Bus || B_Bus 结果为1 A_Bus && B_Bus 结果为 1 并且:
! A_Bus 与! B_Bus的结果相同。 结果为0。
如果任意一个操作数包含x,结果也为x。 !x 结果为x 4.2.5 按位操作符 按位操作符有: * ~(一元非) * &(二元与) * |(二元或)
* ^(二元异或) * ~^, ^~(二元异或非)
这些操作符在输入操作数的对应位上按位操作,并产生向量结果。下表显示对于不同操作符按步操作的结果。 例如,假定, A = 'b0110; B = 'b0100; 那么:
A | B 结果为0110 A & B 结果为0100
如果操作数长度不相等, 长度较小的操作数在最左侧添0补位。例如, 'b0110 ^ 'b10000 与如下式的操作相同: 'b00110 ^ 'b10000 结果为'b10110。 4.2.6 归约操作符
归约操作符在单一操作数的所有位上操作,并产生1位结果。归约操作符有: * & (归约与)
如果存在位值为0, 那么结果为0;若如果存在位值为x或z,结果为x;否则结果为1。 * ~& (归约与非) 与归约操作符&相反。 * | (归约或)
如果存在位值为1,那么结果为1;如果存在位x或z,结果为x;否则结果为0。
* ~| (归约或非) 与归约操作符|相反。 * ^ (归约异或)
如果存在位值为x或z,那么结果为x;否则如果操作数中有偶数个1, 结果为0;否则结果为1。 * ~^ (归约异或非) 与归约操作符^正好相反。 如下所示。假定, A = 'b0110;