Verilog 中归约运算符包含归约与(&),归约与非(~&),归约或(|),归约或非(~|),归约异或(^),归约同或(~^)。
1.归约运算符
归约运算符是一元操作符,相当于C中的单目运算符。它是对一个操作数进行位操作,最后得到的结果是位宽为一位的数或变量。
归约运算的过程是第一步先用操作数的第一位和第二位进行位操作,然后再用第一步的结果和操作的数的下一位进行位操作,如此重复直到最后一位。
例:
&a[3:0] = a[3] & a[2] & a[1] & a[0];
|a[3:0] = a[3] | a[2] | a[1] | a[0];
^a[3:0] = a[3] ^ a[2] ^ a[1] ^ a[0];
2.归约运算符与位运算的异同:
(1)相同点:
- 归约运算符与位运算符使用的符号相同。
- 逻辑运算结果遵从相同的运算规则,见表一
- 基本运算符只有三个&,|,^,其它的在这三个的基础上取反组成,如~&
(2)区别:
- 位运算为二元操作符,而归约运算符为一元操作符。
- 位运算符运算结果可以为一位位宽,也可以多位位宽(向量运算);而归约运算符只有位宽为一位的运算结果。
3.归约运算表
表1 归约与(&)
| & | 0 | 1 | x | z |
| 0 | 0 | 0 | 0 | 0 |
| 1 | 0 | 1 | x | x |
| x | 0 | x | x | x |
| z | 0 | x | x | x |
表2 归约或( | )
| | | 0 | 1 | x | z |
| 0 | 0 | 1 | x | x |
| 1 | 1 | 1 | 1 | 1 |
| x | x | 1 | x | x |
| z | x | 1 | x | x |
表3 归约异或 (^)
| ^ | 0 | 1 | x | z |
| 0 | 0 | 1 | x | x |
| 1 | 1 | 0 | x | x |
| x | x | x | x | x |
| z | x | x | x | x |
4.归约运算符的使用
- 作为结果赋给位宽为1的变量,如
wire a; wire [3:0] b; wire [3:0] c; wire [3:0] d; assign a = &b;
- 作为判断语句的条件,如:
assign c = &b ? {3'b0, a} : d;
always@(*)
if(&b)
c <= {3'b0, a};
else
c <= d;
上面代码的含义是变量b中的位是否都为1;如果都为1,则&b为1,执行
c <= {3’b0, a};
否则执行语句
c <= d;
设b == 4’b11x1; 比较if(b)与 if(&b)的异同。
例1:
设计文件 cmp.v
module cmp
(
input [3:0] a, b, c,
output reg [3:0] d, e
);
always@(*)
begin
if(a)
d = b;
else
d = c;
if(&a)
e = b;
else
e = c;
end
endmodule
仿真文件: tb.v
`timescale 1ns/1ps
module tb
(
);
reg [3:0] a, b, c;
wire [3:0] d;
wire [3:0] e;
initial
begin
a = 'b0;
b = 'b0;
c = 'b0;
#10
a = 'd7;
b = 'd9;
c = 'd12;
#10
a = 'b11x1;
end
cmp cmp_dut
(
.a (a),
.b (b),
.c (c),
.d (d),
.e (e)
);
endmodule
Modelsim 仿真结果

图1
从上面的结果可以看出,在a = 4’b11x1 条件下:
if(a)等效为 if(a != 0), 条件满足,因此执行 d=b;语句
而if(&a),由于(1 & 1 & x & 1) = x, 不为1, 不满足if条件,因此执行语句e = c;
其它的归约运算符计算类似,这里不再举例。
对应视频:
学习本篇文章后有几点收获,1、归约运算符是一元操作符,相当于C中的单目运算符;2、归约运算符包括基本运算符三个&,|,^,其它的在这三个的基础上取反组成;3、归约运算的过程是第一步先用操作数的第一位和第二位进行位操作,然后再用第一步的结果和操作数的下一位进行位操作,如此重复直到最后一位;4、位运算为二元操作符,而归约运算符为一元操作符;5、位运算符运算结果可以为一位位宽,也可以多位位宽(向量运算);而归约运算符只有位宽为一位的运算结果;
文章总结的很全面,通过学习文章以及教学视频,感觉对归约运算符的认知非常清晰了。