Menu
CoddyTech

归约运算符

本课属于 Coddy Verilog 学习旅程的“基础知识”单元。第 25 课,共 90 课。

归约运算符会处理单个向量的所有位,并将它们归约为一个位的结果。与逐位比较两个数字的按位运算符不同,归约运算符只接收一个数字,并对它的所有位执行运算,得出一个结果。

 

运算符操作结果
&归约与如果所有位都是 1,则为 1
|归约或如果至少有一位是 1,则为 1
^归约异或如果有奇数个位是 1,则为 1
~&归约与非如果所有位都是 1,则为 0
~|归约或非如果至少有一位是 1,则为 0
~^归约同或如果有偶数个位是 1,则为 1

它们的工作原理

归约与(&):

&4'b1111 = 1   // all bits are 1
&4'b1011 = 0   // 不是所有位都是 1
&4'b0000 = 0   // all bits are 0

归约或(|):

|4'b0000 = 0   // no bits are 1
|4'b0100 = 1   // 至少有一个位是 1
|4'b1111 = 1   // all bits are 1

归约异或(^):

^4'b1010 = 0   // two 1's (even) → 0
^4'b1000 = 1   // one 1 (odd) → 1
^4'b1111 = 0   // 四个 1(偶数)→ 0

代码示例

module reduction_demo;
  reg [3:0] a, b, c;
  reg and_red, or_red, xor_red;
  
  initial begin
    a = 4'b1111;
    b = 4'b1010;
    c = 4'b1000;
    
    and_red = &a;      // 1111 → 1
    or_red  = |b;      // 1010 → 1
    xor_red = ^c;      // 1000 → 1
    
    $display("&4'b1111 = %d", and_red);
    $display("|4'b1010 = %d", or_red);
    $display("^4'b1000 = %d", xor_red);
    $finish;
  end
endmodule

输出:

&4'b1111 = 1
|4'b1010 = 1
^4'b1000 = 1

常见用途

检查所有位是否都是 1:

all_ones = &data;   // 如果 data == 8'b11111111,则为 1

检查是否有任意一位是 1:

any_one = |data;    // 如果 data != 0,则为 1

检查奇偶校验(1 的个数为奇数):

odd_parity = ^data; // 如果 1 的个数是奇数,则为 1

检查所有位是否为 0:

all_zeros = ~|data; // 如果 data == 0,则为 1
challenge icon

挑战

为每项任务写出正确的归约表达式。

要做什么:

  1. 检查 a 的所有位是否都为 1,并将结果存入 all_ones
  2. 检查 b 是否有任意一位为 1,并将结果存入 any_one
  3. 检查 c 中 1 的个数是否为奇数,并将结果存入 odd_parity

亲手试试

module reduction_challenge;
  reg [3:0] a, b, c;
  reg all_ones, any_one, odd_parity;
  
  initial begin
    a = 4'b1111;
    b = 4'b0100;
    c = 4'b1011;
    
    all_ones  = ______;   // all bits 1?
    any_one   = ______;   // any bit 1?
    odd_parity = ______;   // odd number of 1's?
    
    $display("&4'b1111 = %d", all_ones);
    $display("|4'b0100 = %d", any_one);
    $display("^4'b1011 = %d", odd_parity);
    $finish;
  end
endmodule
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

基础知识中的所有课

自己练习: Verilog 在线编译器