电子说
本章讲述在Verilog HDL中编写表达式的基础。
表达式由操作数和操作符组成。表达式可以在出现数值的任何地方使用。
4.1 操作数
操作数可以是以下类型中的一种:
1) 常数
2) 参数
3) 线网
4) 寄存器
5) 位选择
6) 部分选择
7) 存储器单元
8) 函数调用
4.1.1 常数
前面的章节已讲述了如何书写常量。下面是一些实例。
256,7 // 非定长的十进制数。
4'b10_11, 8'h0A // 定长的整型常量。
'b1, 'hFBA // 非定长的整数常量。
90.00006 // 实数型常量。
"BOND" // 串常量;每个字符作为8位A S C I I值存储。
表达式中的整数值可被解释为有符号数或无符号数。如果表达式中是十进制整数,例如,12被解释为有符号数。如果整数是基数型整数(定长或非定长),那么该整数作为无符号数对
待。下面举例说明。
12是01100的5位向量形式(有符号)
- 12是10100的5位向量形式(有符号)
5 ' b 01100是十进制数1 2(无符号)
5 ' b 10100是十进制数2 0(无符号)
4 ' d12是十进制数1 2(无符号)
更为重要的是对基数表示或非基数表示的负整数处理方式不同。非基数表示形式的负整数作为有符号数处理,而基数表示形式的负整数值作为无符号数。因此-4 4和-6'o54 (十进制的4 4等于八进制的5 4)在下例中处理不同。
integerCone;
. . .
cone= -44/4
cone = -6'o54/ 4;
注意-4 4和-6 'o54以相同的位模式求值;但是-4 4作为有符号数处理,而-6 'o54作为无符号数处理。因此第一个字符中Cone的值-11,而在第二个赋值中Co e的值为1073741813
4.1.2 参数
前一章中已对参数作了介绍。参数类似于常量,并且使用参数声明进行说明。下面是参数说明实例。
p a r a m e t e r L O A D = 4'd12, S T O R E = 4'd10;
L O A D 和S TO R E为参数的例子,值分别被声明为1 2和1 0。
4.1.3 线网
可在表达式中使用标量线网(1位)和向量线网(多位)。下面是线网说明实例。
w i r e [0:3] P r t; //P r t 为4位向量线网。
w i r e B d q; //B b q 是标量线网。
线网中的值被解释为无符号数。在连续赋值语句中,
a s s i g n P r t = -3;
P rt被赋于位向量11 0 1,实际上为十进制的1 3。在下面的连续赋值中,
a s s i g n P r t = 4'HA;
P rt被赋于位向量1 0 1 0,即为十进制的1 0。
4.1.4 寄存器
标量和向量寄存器可在表达式中使用。寄存器变量使用寄存器声明进行说明。例如 :
i n t e g e r TemA, TemB;
r e g [1:5] S t a t e;
t i m e Q u e [ 1 : 5 ] ;
整型寄存器中的值被解释为有符号的二进制补码数,而 r e g寄存器或时间寄存器中的值被解释为无符号数。实数和实数时间类型寄存器中的值被解释为有符号浮点数。
TemA = -10; // T e m A值为位向量1 0 1 1 0,是1 0的二进制补码。
TemA = 'b1011; // T e m A值为十进制数1 1。
State = -10; // S t a t e值为位向量1 0 1 1 0,即十进制数2 2。
State = 'b1011; // S t a t e值为位向量0 1 0 1 1,是十进制值1 1。
4.1.5 位选择
位选择从向量中抽取特定的位。形式如下:
n e t _ o r _ r e g _ v e c t o r [b i t _ s e l e c t _ e x p r]
下面是表达式中应用位选择的例子。
S t a t e [1] && S t a t e [4] //寄存器位选择。
P r t [0] | Bbq // 线网位选择。
如果选择表达式的值为x、z,或越界,则位选择的值为x。例如S t a t e [x]值为x。
4.1.6 部分选择
在部分选择中,向量的连续序列被选择。形式如下:
因为C o n e 为非定长整型变量,基数表示形式的负数在机内以补码形式出现。 — 译者注
net _ or _ reg _ vector[msb _ const _ expr: 1sb _ const _expr]
其中范围表达式必须为常数表达式。例如。
state[1:4] // 寄存器部分选择。
P r t [1:3] // 线网部分选择。
选择范围越界或为x,z时,部分选择的值为x。
4.1.7 存储器单元
存储器单元从存储器中选择一个字。形式如下:
memory [word _ address]
例如:
reg [1:8] Ack, Dram[0 :63] ;
. . .
Ack =Dram [60]; //存储器的第6 0个单元。
不允许对存储器变量值部分选择或位选择。例如,
Dram [60] [2] 不允许。
Dram [60] [2:4] 也不允许。
在存储器中读取一个位或部分选择一个字的方法如下:将存储器单元赋值给寄存器变量,然后对该寄存器变量采用部分选择或位选择操作。例如, A c k [2] 和Ack [ 2 : 4 ]是合法的表达式。
4.1.8 函数调用
表达式中可使用函数调用。函数调用可以是系统函数调用(以 $字符开始)或用户定义的函数调用。例如:
$t i m e + S u m O f E v e n t s (A, B)
/ * $t i m e是系统函数,并且S u m O f E v e n t s是在别处定义的用户自定义函数。* /
4.2 操作符
Verilog HDL中的操作符可以分为下述类型:
1) 算术操作符
2) 关系操作符
3) 相等操作符
4) 逻辑操作符
5) 按位操作符
6) 归约操作符
7) 移位操作符
8) 条件操作符
9) 连接和复制操作符
下表显示了所有操作符的优先级和名称。操作符从最高优先级(顶行)到最低优先级(底行)排列。同一行中的操作符优先级相同。
归约操作符为一元操作符,对操作数的各位进行逻辑操作,结果为二进制数。
除条件操作符从右向左关联外,其余所有
操作符自左向右关联。下面的表达式:
A + B - C
等价于:
(A + B ) - C / /自左向右
而表达式:
A ? B : C ? D : F
等价于:
A ? B : (C ? D : F) //从右向左
圆扩号能够用于改变优先级的顺序,如以下表达式:
(A ? B : C) ? D : F
4.2.1 算术操作符
算术操作符有:
• +(一元加和二元加)
• -(一元减和二元减)
• *(乘)
• /(除)
• %(取模)
整数除法截断任何小数部分。例如:
7/4 结果为 1
取模操作符求出与第一个操作符符号相同的余数。
7%4 结果为 3
而:
- 7%4 结果为 - 3
如果算术操作符中的任意操作数是 X或Z,那么整个结果为X。例如:
'b10x1 + 'b01111 结果为不确定数' bx x x x x
1. 算术操作结果的长度
算术表达式结果的长度由最长的操作数决定。在赋值语句下,算术操作结果的长度由操
作符左端目标长度决定。考虑如下实例:
reg [0:3] Arc, Bar, Crt ;
reg [0:5] F r x;
. . .
Arc = B a r + C r t;
F r x = B a r + C r t;
第一个加的结果长度由 B a r,C rt和A rc长度决定,长度为 4位。第二个加法操作的长度同样由F rx的长度决定(F rx、B a t和C rt中的最长长度),长度为6位。在第一个赋值中,加法操
作的溢出部分被丢弃;而在第二个赋值中,任何溢出的位存储在结果位 F r x [ 1 ]中。在较大的表达式中,中间结果的长度如何确定?在 Verilog HDL中定义了如下规则:表达式中的所有中间结果应取最大操作数的长度(赋值时,此规则也包括左端目标)。考虑另一个
实例:
w i r e [4:1] Box, Drt;
w i r e [1:5] C f g;
w i r e [1:6] P e g;
w i r e [1:8] A d t;
. . .
a s s i g n A d t = (B o x + C f g) + (D r t + P e g) ;
表达式左端的操作数最长为 6,但是将左端包含在内时,最大长度为 8。所以所有的加操作使用8位进行。例如:B o x和C f g相加的结果长度为8位。
2. 无符号数和有符号数
执行算术操作和赋值时,注意哪些操作数为无符号数、哪些操作数为有符号数非常重要。
无符号数存储在:
• 线网
• 一般寄存器
• 基数格式表示形式的整数
有符号数存储在:
• 整数寄存器
• 十进制形式的整数
下面是一些赋值语句的实例:
r e g [0:5] B a r;
i n t e g e r T a b;
. . .
B a r = -4'd12; //寄存器变量B a r的十进制数为5 2,向量值为1 1 0 1 0 0。
T a b = -4'd12; // 整数T a b的十进制数为- 1 2,位形式为1 1 0 1 0 0。
-4'd12 / 4 // 结果是1 0 7 3 7 4 1 8 2 1。
-12 / 4 // 结果是- 3
因为B a r是普通寄存器类型变量,只存储无符号数。右端表达式的值为 ' b 11 0 1 0 0(1 2的二进制补码)。因此在赋值后, B a r存储十进制值5 2。在第二个赋值中,右端表达式相同,值为' b 11 0 1 0 0,但此时被赋值为存储有符号数的整数寄存器。Ta b存储十进制值- 1 2(位向量为11 0 1 0 0)。注意在两种情况下,位向量存储内容都相同;但是在第一种情况下,向量被解释为无符号数,而在第二种情况下,向量被解释为有符号数。
下面为具体实例:
B a r = - 4'd12/4;
T a b = - 4'd12 /4;
B a r = - 12/4
T a b = - 12/4
在第一次赋值中,B a r被赋于十进制值6 1(位向量为1111 0 1)。而在第二个赋值中,Ta b被赋于与十进制1 0 7 3 7 4 1 8 2 1(位值为0 0 11 . . . 111 0 1)。B a r在第三个赋值中赋于与第一个赋值相同的值。这是因为B a r只存储无符号数。在第四个赋值中, B a r被赋于十进制值-3。
下面是另一些例子:
B a r = 4 - 6;
T a b = 4 - 6;
B a r被赋于十进制值6 2(-2的二进制补码),而Ta b被赋于十进制值-2(位向量为11111 0)。
下面为另一个实例:
B a r = -2 + (-4);
T a b = -2 + (-4);
B a r被赋于十进制值5 8(位向量为111 0 1 0),而Ta b被赋于十进制值-6(位向量为111 0 1 0)。
4.2.2 关系操作符
关系操作符有:
• >(大于)
• <(小于)
• >=(不小于)
• <=(不大于)
关系操作符的结果为真( 1)或假(0)。如果操作数中有一位为 X或Z,那么结果为X。例
如:
23 > 45
结果为假(0),而:
52< 8'hxFF
结果为x。如果操作数长度不同,长度较短的操作数在最重要的位方向(左方)添 0补齐。例
如:
'b1000 > = 'b01110
等价于:
'b01000 > = 'b01110
结果为假(0)。
4.2.3 相等关系操作符
相等关系操作符有:
• = =(逻辑相等)
• !=(逻辑不等)
第4章 表 达 式 33
下载
• = = =(全等)
• != =(非全等)
如果比较结果为假,则结果为 0;否则结果为 1。在全等比较中,值 x和z严格按位比较。也就是说,不进行解释,并且结果一定可知。而在逻辑比较中,值 x和z具有通常的意义,且结果可以不为x。也就是说,在逻辑比较中,如果两个操作数之一包含 x或z,结果为未知的值(x)。如下例,假定:
D a t a = 'b11x0;
A d d r = 'b11x0;
那么:
D a t a = = A d d r
不定,也就是说值为x,但:
D a t a = = = A d d r
为真,也就是说值为1。
如果操作数的长度不相等,长度较小的操作数在左侧添 0补位,例如:
2'b10 = = 4'b0010
与下面的表达式相同:
4'b0010 = = 4'b0010
结果为真(1)。
4.2.4 逻辑操作符
逻辑操作符有:
• && (逻辑与)
• || (逻辑或)
• !(逻辑非)
这些操作符在逻辑值0或1上操作。逻辑操作的结构为0或1。例如, 假定:
C r d = 'b0; //0 为假
Dgs = 'b1; //1 为真
那么:
C r d && D g s 结果为0 (假)
C r d || D g s 结果为1 (真)
!D g s 结果为0 (假)
对于向量操作, 非0向量作为1处理。例如,假定:
A _ B u s = 'b0110;
B _ B u s = 'b0100;
那么:
A _ B u s || B _ B u s 结果为1
A _ B u s && B _ B u s 结果为 1
并且:
! A _ B u s 与! B _ B u s的结果相同。
结果为0。
如果任意一个操作数包含x,结果也为x。
34 Verilog HDL 硬件描述语言
下载
!x 结果为x
4.2.5 按位操作符
按位操作符有:
• ~(一元非)
• &(二元与)
• |(二元或)
• ^(二元异或)
• ~^, ^~(二元异或非)
这些操作符在输入操作数的对应位上按位操作,并产生向量结果。下表显示对于不同操作符按步操作的结果。
例如,假定,
A = 'b0110;
B = 'b0100;
那么:
A | B 结果为0 1 1 0
A & B 结果为0 1 0 0
如果操作数长度不相等, 长度较小的操作数在最左侧添0补位。例如,
'b0110 ^ 'b10000
与如下式的操作相同:
'b00110 ^ 'b10000
结果为' b 1 0 11 0。
第4章 表 达 式 35
下载
与
或
异或 异或非
非
4.2.6 归约操作符
归约操作符在单一操作数的所有位上操作,并产生 1位结果。归约操作符有:
• & (归约与)
如果存在位值为0, 那么结果为0;若如果存在位值为 x或z,结果为x;否则结果为1。
• ~& (归约与非)
与归约操作符&相反。
• | (归约或)
如果存在位值为1,那么结果为1;如果存在位 x或z,结果为x;否则结果为0。
• ~| (归约或非)
与归约操作符|相反。
• ^ (归约异或)
如果存在位值为x或z,那么结果为x;否则如果操作数中有偶数个 1, 结果为0;否则结果
为1。
• ~^ (归约异或非)
与归约操作符^正好相反。
如下所示。假定,
A = 'b0110;
B = 'b0100;
那么:
|B 结果为1
& B 结果为0
~ A 结果为1
归约异或操作符用于决定向量中是否有位为 x。假定,
M y R e g = 4'b01x0 ;
那么:
^M y R e g 结果为x
上述功能使用如下的i f语句检测:
i f ( ^M y R e g = = = 1'bx)
$ d i s p l a y ("There is an unknown in the vector MyReg !")
注意逻辑相等( = = )操作符不能用于比较;逻辑相等操作符比较将只会产生结果 x。全等操作符期望的结果为值1。
4.2.7 移位操作符
移位操作符有:
• << (左移)
• >> (右移)
移位操作符左侧操作数移动右侧操作数表示的次数,它是一个逻辑移位。空闲位添 0补位。如果右侧操作数的值为x或z, 移位操作的结果为x。假定:
r e g [ 0:7] Q r e g;
. . .
Q r e g = 4'b0111;
那么:
Q r e g >> 2 是 8 ' b 0 0 0 0 _ 0 0 0 1
V erilog H D L中没有指数操作符。但是,移位操作符可用于支持部分指数操作。例如,如果要计算Z
N u m B i t s 的值,可以使用移位操作实现,例如:
32'b1 << N u m B i t s / /N u m B i t s必须小于3 2。
同理,可使用移位操作为2 - 4解码器建模,如
w i r e [0:3] D e c o d e O u t = 4'b1 << A d d r e s s [ 0 : 1 ] ;
A d d re s s[0:1] 可取值0 , 1 , 2和3。与之相应,D e c o d e O u t可以取值4 ' b 0 0 0 1、4 ' b 0 0 1 0、4 ' b 0 1 0 0
和4 ' b 1 0 0 0,从而为解码器建模。
4.2.8 条件操作符
条件操作符根据条件表达式的值选择表达式,形式如下 :
c o n d_e x p r ? e x p r 1 : e x p r 2
如果c o n d _ e x p r 为真(即值为1 ),选择e x p r 1;如果c o n d _ e x p r为假(值为0 ),选择e x p r 2。如果c o n d _ e x p r 为x或z,结果将是按以下逻辑 e x p r 1和e x p r 2按位操作的值: 0与0得0,1与1得1,其余情况为x。
如下所示:
w i r e [0:2] S t u d e n t = M a r k s > 18 ? G r a d e _ A : G r a d e _ C;
计算表达式M a r k s > 18; 如果真, G r a d e _ A 赋值为S t u d e n t; 如果M a r k s < =18, G r a d e _ C 赋值为S t u d e n t。下面为另一实例:
a l w a y s
#5 C t r = (C t r != 25) ? (C t r + 1) : 5;
过程赋值中的表达式表明如果C t r不等于25, 则加1;否则如果C t r值为2 5时, 将C t r值重新置
为5。
4.2.9 连接和复制操作
连接操作是将小表达式合并形成大表达式的操作。形式如下 :
{e x p r 1, e x p r 2, . . .,e x p r N}
实例如下所示:
w i r e [7:0] D b u s;
w i r e [11:0] A b u s;
a s s i g n D b u s [7:4] = {D b u s [0], D b u s [1], D b u s[2], D b u s[ 3 ] } ;
/ /以反转的顺序将低端4位赋给高端4位。
a s s i g n D b u s = {Dbus [3:0], D b u s [ 7 : 4 ] } ;
/ /高4位与低4位交换。
由于非定长常数的长度未知, 不允许连接非定长常数。例如, 下列式子非法:
{D b u s,5} / /不允许连接操作非定长常数。
复制通过指定重复次数来执行操作。形式如下 :
{r e p e t i t i o n _ n u m b e r {expr1, expr2, ...,exprN } }
以下是一些实例:
A b u s = {3{4'b1011}}; // 位向量1 2 ' b 1 0 1 1 _ 1 0 1 1 _ 1 0 1 1)
A b u s = {{4{D b u s[7]}}, D b u s}; / * 符号扩展 * /
第4章 表 达 式 37
下载
{3{1'b1}} 结果为1 1 1
{3{Ack}} 结果与{A c k, A c k, A c k}相同。
4.3 表达式种类
常量表达式是在编译时就计算出常数值的表达式。通常,常量表达式可由下列要素构成 :
1) 表示常量文字, 如' b 1 0和3 2 6。
2) 参数名,如R E D的参数表明:
p a r a m e t e r R E D = 4'b1110;
标量表达式是计算结果为 1位的表达式。如果希望产生标量结果 , 但是表达式产生的结果
为向量, 则最终结果为向量最右侧的位值。
习题
1. 说明参数G AT E _ D E L AY, 参数值为5。
2. 假定长度为6 4个字的存储器, 每个字8位,编写Verilog 代码,按逆序交换存储器的内容。即
将第0个字与第6 3个字交换,第1个字与第6 2个字交换,依此类推。
3. 假定3 2位总线A d d re s s _ B u s, 编写一个表达式,计算从第11位到第2 0位的归约与非。
4. 假定一条总线C o n t ro l _ B u s [ 1 5 : 0 ],编写赋值语句将总线分为两条总线:A b u s [ 0 : 9 ]和B b u s
[ 6 : 1 ]。
5. 编写一个表达式,执行算术移位,将 Qparity 中包含的8位有符号数算术移位。
6. 使用条件操作符 , 编写赋值语句选择 N e x t S t a t e的值。如果C u rre n t S t a t e的值为R E S E T, 那么N e x t S t a t e的值为 G O;如果 C u rre n t S t a t e的值为 G O,则 N e x t S t a t e 的值为 B U S Y;如果C u rre n t S t a t e的值为B U S Y;则N e x t S t a t e的值为R E S E T。
7. 使用单一连续赋值语句为图2 - 2所示的2 - 4解码器电路的行为建模。[提示:使用移位操作符、条件操作符和连接操作符。]
8. 如何从标量变量 A,B,C和D中产生总线 B u s Q[0:3]? 如何从两条总线 B u s A [ 0 : 3 ]和B u s Y
[ 2 0 : 1 5 ]形成新的总线B u s R [ 1 0 : 1 ] ?
原文标题:Verilog入门4-Verilog表达式
文章出处:【微信公众号:FPGA设计论坛】欢迎添加关注!文章转载请注明出处。
责任编辑:haq
全部0条评论
快来发表一下你的评论吧 !