module sign_size;
reg [3:0] a, b;
reg [15:0] c;
initial begin
a =-1;// a 是无符号数,因此其值为 1111
b =8; c =8;// b = c = 1000
#10 b = b + a;// 结果 10111 截断, b = 0111
#10 c = c + a;// c = 10111
end
endmodule
算术操作符
+
加
-
减
*
乘
/
除
%
模
module arithops();
parameter five =5;
integer ans,int;
reg [3:0] rega, regb;
reg [3:0] num;
initial begin
rega =3;
regb =4'b1010;int=-3;//int = 1111……1111_1101
end
initial fork
#10 ans = five *int;// ans = -15
#20 ans =(int+5)/2;// ans = 1
#30 ans = five /int;// ans = -1
#40 num = rega + regb;// num = 1101
#50 num = rega +1;// num = 0100
#60 num =int;// num = 1101
#70 num = regb % rega;// num = 1
#80 $finish;
join
endmodule
当两个操作数位数不同时,位数少的操作数零扩展到相同位数。 a = 4’b1011; b = 8’b01010011; c = a | b; // a 零扩展为 8’b00001011
一元归约操作符
&
and
I
or
^
xor
~ ^
xnor
^ ~
xnor
module reduction();
reg val;
reg [3:0] rega, regb;
initial begin
rega =4'b0100;
regb =4'b1111;
end
initial fork
#10 val =& rega ;// val = 0
#20 val =| rega ;// val = 1
#30 val =& regb ;// val = 1
#40 val =| regb ;// val = 1
#50 val =^ rega ;// val = 1
#60 val =^ regb ;// val = 0
#70 val =~| rega;// (nor) val = 0
#80 val =~& rega;// (nand) val = 1
#90 val =^rega &&®b;// val = 1
$finish;
join
endmodule
归约操作符的操作数只有一个。
对操作数的所有位进行位操作。
结果只有一位,可以是 0, 1, x。
逻辑操作符
!
not
&&
and
II
or
module logical();
parameter five =5;
reg ans;
reg [3:0] rega, regb, regc;
initial begin
rega =4'b0011;// 逻辑值为 “1”
regb =4'b10xz;// 逻辑值为 “1”
regc =4'b0z0x;// 逻辑值为 “x”
end
initial fork
#10 ans = rega &&0;// ans = 0
#20 ans = rega ||0;// ans = 1
#30 ans = rega && five;// ans = 1
#40 ans = regb && rega;// ans = 1
#50 ans = regc ||0;// ans = x
#60 $finish;
join
endmodule
逻辑操作符的结果为一位 1,0 或 x。
逻辑操作符只对逻辑值运算。
如操作数为全 0,则其逻辑值为 false
如操作数有一位为 1,则其逻辑值为 true
若操作数只包含 0、x、z,则逻辑值为 x
逻辑反操作符将操作数的逻辑值取反。例如,若操作数为全 0,则其逻辑值为 0,逻辑反操作值为 1。
逻辑反与位反的对比
!
logical not
逻辑反
~
bit-wise not
位反
module negation();
reg [3:0] rega, regb;
reg [3:0] bit;
reg log;
initial begin
rega =4'b1011;
regb =4'b0000;
end
initial fork
#10 bit =~rega;// num = 0100
#20 bit =~regb;// num = 1111
#30 log =!rega;// num = 0
#40 log =!regb;// num = 1
#50 $finish;
join
endmodule
逻辑反的结果为一位 1,0 或 x。
位反的结果与操作数的位数相同。
逻辑反操作符将操作数的逻辑值取反。例如,若操作数为全 0,则其逻辑值为 0,逻辑反操作值为 1。
移位操作符
>>
逻辑右移
<<
逻辑左移
module shift();
reg [9:0] num, num1;
reg [7:0] rega, regb;
initial rega =8'b00001100;
initial fork
#10 num <= rega <<5;// num = 01_1000_0000
#10 regb <= rega <<5;// regb = 1000_0000 左移先补后移
#20 num <= rega >>3;// num = 00_0000_0001 右移先移后补
#20 regb <= rega >>3;// regb = 0000_0001
#30 num <=10'b11_1111_0000;
#40 rega <= num <<2;// rega = 1100_0000
#40 num1 <= num <<2;// num1 = 11_1100_0000
#50 rega <= num >>2;// rega = 1111_1100
#50 num1 <= num >>2;// num1 = 00_1111_1100
#60 $finish;
join
endmodule
移位操作符对其左边的操作数进行向左或向右的位移位操作。
第二个操作数(移位位数)是无符号数。
若第二个操作数是 x 或 z 则结果为 x。
“<<” 将左边的操作数左移右边操 作数指定的位数。
“>>” 将左边的操作数右移右边操 作数指定的位数。
在赋值语句中,如果右边(RHS)的结果: 位宽大于左边,则把最高位截去。 位宽小于左边,则零扩展。
建议:表达式左右位数一致。
关系操作符
>
大于
<
小于
>=
大于等于
<=
小于等于
module relationals();
reg [3:0] rega, regb, regc;
reg val;
initial begin
rega =4'b0011;
regb =4'b1010;
regc =4'b0x10;
end
initial fork
#10 val = regc > rega ;// val = x rega 和 regc 的关系取决于 x
#20 val = regb < rega ;// val = 0
#30 val = regb >= rega ;// val = 1
#40 val = regb > regc ;// val = 1 无论 x 为何值,regb > regc
#50 $finish;
join
endmodule
其结果是 1’b1、1’b0 或 1’bx。
相等操作符
= 赋值操作符,将等式右边表达式的值拷贝到左边。 == 逻辑等
a =2'b1x;
b =2'b1x;if(a == b)
$display(" a is equal to b");else
$display(" a is not equal to b");/*
2'b1x == 2'b0x
值为 0,因为不相等
2'b1x == 2'b1x
值为 x,因为可能不相等,也可能相等
*/
=== case等
a =2'b1x;
b =2'b1x;if(a === b)
$display(" a is identical to b");else
$display(" a is not identical to b");/*
2'b1x === 2'b0x
值为 0,因为不相同
2'b1x === 2'b1x
值为 1,因为相同
*/
case等只能用于行为描述,不能用于 RTL 描述。
==
逻辑等
!=
逻辑不等
module equalities1();
reg [3:0] rega, regb, regc;
reg val;
initial begin
rega =4'b0011;
regb =4'b1010;
regc =4'b1x10;
end
initial fork
#10 val = rega == regb;// val = 0
#20 val = rega != regc;// val = 1
#30 val = regb != regc;// val = x
#40 val = regc == regc;// val = x
#50 $finish;
join
endmodule
其结果是 1’b1、1’b0 或 1’bx。
如果左边及右边为确定值并且相等,则结果为 1。
如果左边及右边为确定值并且不相等,则结果为 0。
如果左边及右边有值不能确定的位,但值确定的位相等,则结果为 x。
!= 的结果与 == 相反。
值确定是指所有的位为 0 或 1。不确定值是有值为 x 或 z 的位。
===
相同(case等)
!==
不相同(case不等)
module equalities2();
reg [3:0] rega, regb, regc;
reg val;
initial begin
rega =4'b0011;
regb =4'b1010;
regc =4'b1x10;
end
initial fork
#10 val = rega === regb;// val = 0
#20 val = rega !== regc;// val = 1
#30 val = regb === regc;// val = 0
#40 val = regc === regc;// val = 1
#50 $finish;
join
endmodule
其结果是 1’b1、1’b0 或 1’bx。
如果左边及右边的值相同(包括 x、z),则结果为 1。
如果左边及右边的值不相同,则结果为 0。
!== 的结果与 === 相反。
综合工具不支持
条件操作符
? :
条件
module likebufif(in, en, out);
input in;
input en;
output out;
assign out =(en ==1)? in : 'bz;
endmodule
module like4to1(a, b, c, d, sel, out);
input a, b, c, d;
input [1:0] sel;
output out;
assign out = sel ==2'b00 ? a :
sel ==2'b01 ? b :
sel ==2'b10 ? c : d;
endmodule
module replicate();
reg [3:0] rega;
reg [1:0] regb, regc;
reg [7:0] bus;
initial begin
rega =4'b1001;
regb =2'b11;
regc =2'b00;
end
initial fork
#10 bus <={4{regb}};// bus = 11111111. regb is replicated 4 times.
#20 bus <={{2{regb}},{2{regc}}};// bus = 11110000. regc and regb are each replicated, and the resulting vectors are concatenated together
#30 bus <={{4{rega[1]}}, rega};// bus = 00001001. rega is sign-extended
#40 $finish;
join
endmodule