摘要:本文章主要介绍了Verilog语法中的运算符部分的内容,本部分包括语法的讲解,是否可综合的性质以及可以进行实际操作的例子,如果有需要相关的工程文件,可以留言(使用Modelsim软件进行编译仿真)。
1.运算符概述
Verilog的运算符与C语言基本类似,包括算术运算符、关系运算符、灯饰运算符、逻辑运算符、位运算、缩减运算符、移位运算符、条件运算符、拼接运算符等。各种运算符与条件运算符在同时使用时,具有一定优先级顺序(从高到低)。
2.算术运算符
注意:除法(/)或取模(%)运算时,如果B取值为0,那么仿真输出的运算结果将会是不确定值x;如果进行运算的值A或C有任何位的值是x或z,那么运算的整个结果值都会是x。取模(%)运算结果的符号只与A的符号一致。以下是一个可以进行实际运行的testbench文件,用以观察这些运算的实际效果。
module testbench_top(); integer A,B; integer C; initial begin A=100; B=33; C=A+B; $display("%0d + %0d = %0d", A, B, C); C=A-B; $display("%0d - %0d = %0d", A, B, C); C=A*B; $display("%0d * %0d = %0d", A, B, C); C=A/B; $display("%0d / %0d = %0d", A, B, C); A=10; B=3; C=A**B; $display("%0d ** %0d = %0d", A, B, C); C=A%B; $display("%0d %% %0d = %0d", A, B, C); A=100; B=20; C=A%B; $display("%0d %% %0d = %0d", A, B, C); A=-100; B=33; C=A%B; $display("%0d %% %0d = %0d", A, B, C); A=100; B=-33; C=A%B; $display("%0d %% %0d = %0d", A, B, C); $stop; end endmodule
运算结果如下:
3.关系运算符
使用关系运算符的表达式结果若是true,则返回结果1,否则返回结果0。参与关系运算的任意一个数据中若包含x或z,则其仿真结果必定是一位不确定值x。当关系运算符两侧的数据位宽不一致时,位宽较少的数据会自动扩展到与位宽较多的数据一样的位宽,扩展位的数据都以0填充。所有关系运算符具有相同的运算优先级。
4.等式运算符
等式运算符包括逻辑等号==、逻辑不等号!=、全等号===和不全等号!==。
等式运算符将会实现逐位比较,若等式两侧的位宽不同,则位宽较少的数据将自动扩展位宽并与位宽较多的数据位宽相等,扩展位以0填充。与关系运算操作一样,灯饰运算操作在结果为true时,返回结果1,否则返回结果0。
全等号===和不全等号!==可用于仿真测试脚本,但不可综合。全等式中可以包含x和z,并参与逐位比较。逻辑等式运算的任意一个数据中若包含x或z,则其仿真结果必定是一位的不确定值x。
5.逻辑运算符
逻辑与(&&)、逻辑或(||)、逻辑非(!)。
!A if(!A) if(A==0) A&&B A||B
6.位运算符
位运算符包括与(&)、位或(|)、位取反(~)、位异或(^)、位同或(~^或^~)。位运算符实现运算数值间的逻辑运算操作。
module testbench_top; reg [7:0] A,B; reg [7:0] C; initial begin A=8'b10101110; B=8'b10010110; C=A&B; $display("%b & %b = %b", A, B, C); C=A|B; $display("%b | %b = %b", A, B, C); C=~A; $display("~%b = %b", A, C); C=A^B; $display("%b ^ %b = %b", A, B, C); C=A~^B; $display("%b ~^ %b = %b", A, B, C); $stop; end endmodule
运算结果如下:
7.缩减运算符
缩减运算符对单个操作数的每个位之间进行递推运算,最后的运算结果是一位的二进制数。缩减运算符包括缩减与(&)、缩减或(|)、缩减与非(~&)、缩减或非(~|)、缩减异或(^)、缩减同或(~^)。
module testbench_top(); reg [3:0] A,B,C,D; initial begin A=4'b1111; B=4'b0000; C=4'b0110; D=4'b1000; $display("A=%b, B=%b, C=%b, D=%b", A, B, C, D); $display("&A=%b, &B=%b, &C=%b, &D=%b", &A, &B, &C, &D); $display("|A=%b, |B=%b, |C=%b, |D=%b", |A, |B, |C, |D); $display("~&A=%b, ~&B=%b, ~&C=%b, ~&D=%b", ~&A, ~&B, ~&C, ~&D); $display("~|A=%b, ~|B=%b, ~|C=%b, ~|D=%b", ~|A, ~|B, ~|C, ~|D); $display("^A=%b, ^B=%b, ^C=%b, ^D=%b", ^A, ^B, ^C, ^D); $display("~^A=%b, ~^B=%b, ~^C=%b, ~^D=%b", ~^A, ~^B, ~^C, ~^D); $stop; end endmodule
运算结果如下:
8.移位运算符
移位运算符包括逻辑运算符何算术运算符。左移运算符将运算符左侧的数值(A或B)向左移动num个位,低位补0;右移运算符将运算符左侧的数值向右移动num个位,高位补0。如果赋值的结果是无符号数,则算术右移(>>>)的高位补0;如果赋值结果是有符号数,则算术右移(>>>)高位补1。
语法示例:
A<<num B<<<num C>>num D>>>num
代码示例:
module testbench_top(); reg [3:0] A,B; reg signed [3:0] C,D; initial begin A=4'b0001; B=(A<<2); $display("(A<<2) = %b", B); C=4'b1000; D=(C>>>2); $display("(C>>>2) = %b", D); $stop; end endmodule
结果如下:
9.条件运算符
条件运算符?:的基本格式如下:
A=B?C:D;
如果B的表达式为True,那么将C的值赋给A;否则将D的值赋给A。
示例代码如下:
module testbench_top(); reg flag; reg [3:0] A,B,C; wire [3:0] D; initial begin A=8; B=2; flag=1; #20; flag=0; #20; $stop; end assign D=flag ? (A+B) : (A-B); always @(*) begin C=flag ? A:B; end endmodule
10.拼接运算符
拼接运算符使用一对大括号{}实现。在{}中将几个信号的某些位详细列出来,中间使用逗号分隔开,表示一个由多个位拼接在一起的信号。常量或变量都可以使用拼接运算符。拼接运算符允许嵌套使用。具体使用方式如下:
{A,B,C} {3{A}} {A,{2{A,B}},C}
具体示例代码如下:
module testbench_top(); reg [1:0] A=2'b00, B=2'b11, C=2'b10; reg [5:0] D= 6'd0; reg [5:0] E= 6'd0; reg [11:0] F= 12'd0; initial begin #10; D={A,B,C}; $display("D={A,B,C} = {%b,%b,%b}=%b", A, B, C,D); E={3{A}}; $display("E={3{A}}={3{%b}}=%b", A, E); F={A, {2{A,B}}, C}; $display("F={A, {2{A,B}}, C} = {%b,{2{%b,%b}},%b}=%b", A, A, B, C, F); #10; $stop; end endmodule
结果如下:
End!