表达式有操作数和操作符组成。
操作数
操作数分为:常数、参数、线网、寄存器、位选择、部分选择、存储器单元、函数调用
常数:表达时间中的整数值可被解释为有符号数或无符号数。如果表达式中是十进制整数,那么被解释为有符号数。
如果整数是基数型整数(定长或非定长),该整数作为无符号数对待。
对基数表示或非基数表示的负整数处理方式不同。非基数表示形式的负整数作为有符号数处理,而基数表示形式的负整数作为无符号数。
参数:参数类似于常量,并且使用参数声明进行说明。 例如:parameter LOAD = 4‘d12,STORE = 4‘d10 此时,LOAD和STORE的值分别声明为12,10
线网:可在表达式中使用标量线网(1位)和向量线网(多位)
例如: wire [0:3] Prt; //prt为4位向量线网 wire Bdq; //Bbq是标量线网。 线网中的值被解释为无符号数。在连续赋值中assign Prt = -3; Prt被赋于位向量1101.assign Prt = 4‘HA;Prt被赋于位向量1010.
寄存器:标量和向量寄存器可在表达式中使用。寄存器变量使用寄存器声明进行说明。
例如:integer TemA,TemB; reg [1:5] State; time Que [1:5]; 整型寄存器中的值被解释为有符号的二进制补码数,而reg寄存器或者时间寄存器中的值被解释成无符号数。实数和实数时间类型寄存器中的值被解释为有符号浮点数。
TemA = -10; //TemA值为位向量10110
TemA = ‘b1011; //TemA值为十进制数11
位选择:位选择从向量中抽取特定的位,形式如下: net_or_reg_vector [bit_select_expr]
例如:State [1] && State [4] //寄存器位选择 Prt [0] | Bbq //线网位选择 如果选择表达式的值为x,z或越界,则位选择的值为x。
部分选择: 向量的连续序列被选择,net_or_reg_vector[msb_const_expr:lsb_const_expr] 范围表达式必须为常数表达式。例如:State [1:4]
选择范围越界或者为x、z时,部分选择的值为x
存储器单元:存储器单元从存储器中选择一个字。memory [word_address]
例如:reg [1:8] Ack,Dram [0:63]; ... Ack = Dram [60];------->选择存储器的第60个单元
不允许对存储器变量值部分选择或位选择。读取一个位或者部分选择一个字的方法:将存储器单元赋值给寄存器变量,然后对该寄存器采用部分选择或位选择操作。
函数调用:表达式中可使用函数调用。函数调用可以是系统函数调用(以$字符开始)或者用户定义的函数调用。
例如:$time + SumOfEvents
操作符
操作符可以:算术操作符、关系操作符、相等操作符、逻辑操作符、按位操作符、归约操作符、移位操作符、条件操作符、连接和复制操作符
所有操作如下表:
除了条件操作符从右向左关联外,其余所有操作符自左向右关联。
算术操作符:+、-、*、/、%
整数除法截断任何小数部分。
取模操作符求出与第一个操作符符号相同的余数。
如果算术操作符中的任意操作数是X或Z,那么整个结果为X。
1.算术操作结果的长度
算术表达式结果的长度由最长的操作数决定。在赋值语句下,算术操作结果的长度由操作符左端目标长度决定。
表达式中的所有中间结果应取最大操作数的长度。
2.无符号数和有符号数
执行算术操作和赋值时,注意操作数的类型。
无符号数存储在:线网、一般寄存器、基数格式表示形式的整数
有符号数存储在:整数寄存器、十进制形式的整数
例如:reg [0:5] Bar; integer Tab; ...... Bar = -4‘d12;//寄存器向量Bar中的向量值为110100 Tab = -4‘d12 //位形式为110100
因为Bar是普通寄存器类型变量,只存储无符号数。右端表达式的值为‘b110100(12的二进制补码),而Tab为整数寄存器,存入的数为有符号数。Tab存储十进制-12.
关系操作符: >,<,>=,<=
关系操作符的结果为真(1)或假(0)。如果操作数中有一位为x或z,那么结果为x。如23>45,结果为假0。而52<8‘hxFF,结果为x。如果操作数长度不同,较短的操作数需要填0补齐。
相等关系操作符:
==(逻辑相等)、!=(逻辑不等)、===(全等)、!==(非全等)
如果比较结果为假,则结果为0,否则结果为1.在全等比较中,值x和z严格按位比较。在逻辑比较中,值x和z具有通常的意义,且结果可以不为x。也就是说,在逻辑比较中,如果两个操作数之一包含x或z,结果为未知的值x。
逻辑操作符:&&(逻辑与)、||(逻辑或),!(逻辑非)。这些操作在逻辑值为0或1上操作。逻辑操作的结构为0或1.如果任意一个操作数包含x,结果也为x。
按位操作符
~(一元非),&(二元与)、|(二元或)、^(二元异或)、~^,^~(二元异或非)。具体运算规则见下表:
如果操作数长度不相等,长度较小的操作数在最左侧添0补位。
归约操作符
归约操作符在单一操作数的所有位上操作,并产生1位结果。归约操作符有:
&(归约与)-------->如果存在位值为0,那么结果为0,如果存在位值为x或z,结果为x,否则结果为1。
~&(归约与非)---->与归约操作符&相反
|(归约或) -------->如果存在位值为1,那么结果为1,如果存在位x或z,结果为x,否则结果为0。
~|归约或非 ----->与归约操作符|相反
^归约异或 ------>如果存在位值为x或z,那么结果为x;否则如果操作数中有偶数个1,结果为0,否则结果为1.
~^(归约异或非)-->与归约操作符^正好相反
注意逻辑相等(==)操作符不能用于比较,逻辑相等操作符比较将只会产生结果x。全等操作符期望的结果为值1.
移位操作符
<<(左移)、>>(右移)
移位操作符左侧操作数移动右侧操作数表示的次数,它是一个逻辑移位。空闲位添0补位。如果右侧操作数的值为x或z,移位操作的结果位x。
例如:reg [0:7] Qreq;……Qreq = 4‘b0111; 则Qreq >> 2 是8‘b0000_0001
Verilog HDL中没有指数操作符。移位操作符可用于支持部分指数操作。
条件操作符
条件操作符根据条件表达式的值选择表达式,形式如下:cond_expr ? expr1:expr2
如果cond_expr为真,则选择expr1否则选择expr2
如果cond_expr为x或z,结果将是按以下逻辑expr1和expr2按位操作的值:0与0得0,1与1为1,其余情况为x
连接和复制操作
连接操作是将小表达式合并形成大表达式的操作,例如{expr1,expr2,expr3....}
assign Dbus[7:4] = {Dbus[0],Dbus[1], Dbus[2], Dbus[3] }-------->以反转的顺序将低端4位赋给高端4位。