Skip to content
DenseChip
Learn
PracticeCode labInterview

DenseChip

Navigate

Menu

LearnPracticeCode labInterview

Tools

All toolsSV editorCode repoResume
DenseChip

Practice, courses, and chip-design tools in one focused workspace.

LearnPracticeCode labInterviewToolsLearning paths

© 2026 DenseChip

AboutContactPrivacyTerms
Skip to lesson

Course contents

  • RTL Foundations36
    • Digital Logic for RTL Engineers
    • Number Systems for RTL Engineers
    • Verilog Fundamentals
    • Verilog Operators and Types
      • Width Discipline
      • Bit Vectors and Slicing
      • Concatenation and Replication
      • Reduction and Logical Operators
      • Shift and Arithmetic Intent
      • Parameterized, Type-Safe Design
    • SystemVerilog for RTL
    • Simulation and Testbenches
  • Combinational Design25
  • Sequential Design27
  • FSM & Control27
  • Timing & Clocking39
  • Reset & CDC34
  • Memory & Buses57
  • Advanced RTL28
  • Senior & Interview76
  • Glossary and Notation
Loading lesson

‹Verilog Operators and Types
  1. Topics
  2. RTL Design
  3. RTL Foundations
  4. Verilog Operators and Types
  5. Reduction and Logical Operators

Part 1 · Foundations · Beginner

Reduction and Logical Operators

Reduction, bitwise and logical operators, flags, and safe equality checks with unknowns.

On this page

    Why this matters

    For 4'b0101 and 4'b0010 the bitwise a & b is 0000 but the logical a && b is 1. And a compare against an x bit returns x, which an if treats as false: the bug takes the else branch quietly.

    After this lesson you can: choose bitwise, reduction or logical operators, write flag idioms, and compare values that may contain x.

    Three operator families

    Family

    Operators

    Operates

    Result

    Bitwise

    ~ & | ^

    bit by bit between vectors

    Vector, same width

    Reduction

    &v |v ^v ~&v ~|v

    across all bits of one vector

    One bit

    Logical

    ! && ||

    treats each operand as true (non-zero) or false

    One bit

    Common pitfall

    a & b and a && b give different answers for 4'b0101 and 4'b0010: the bitwise AND is 0000, but the logical AND is 1 because both are non-zero. Use bitwise for bit manipulation and logical for true/false conditions in if.

    Status-flag idioms

    Flag

    Expression

    Meaning

    All ones

    &v

    Every bit is 1 (for example a counter at maximum)

    Any set

    |v

    At least one bit is 1 (a non-zero test)

    Zero detect

    ~|v or v == 0

    All bits are 0

    Odd parity

    ^v

    Odd number of ones; ~^v is even parity

    ^v for v = 4'b0111 built as a two-level tree of XOR gates, with the value on every wire

    Read the tree left to right; the orange digits are the values each wire carries for v = 4'b0111.

    • Level 1 pairs the bits: 0 ^ 1 = 1 and 1 ^ 1 = 0.

    • Level 2 combines the pairs: 1 ^ 0 = 1, so the vector has an odd number of ones (three).

    • `&v` and `|v` are the same tree with AND or OR gates. A 16-bit ^v, as in status_flags below, needs 15 two-input gates in 4 levels.

    status_flags.v
    1
    2
    3
    4
    5
    6
    7
    8
    9
    module status_flags (
      input  wire [15:0] v,
      output wire        all_ones, any_set, is_zero, odd_parity
    );
      assign all_ones   = &v;
      assign any_set    = |v;
      assign is_zero    = ~|v;
      assign odd_parity = ^v;
    endmodule

    Equality and unknowns

    == returns x only when the unknown bits make the comparison ambiguous: if any pair of known bits already differs, the result is a definite 0. 4'bx000 == 4'b0001 is 0 because the low bit already differs, while 4'bx000 == 4'b0000 is x because the unknown bit decides the answer. An if treats that x as false and takes the else branch.

    === and !== compare x and z literally and always return 0 or 1, so they are simulation semantics for testbenches. Hardware has no x or z value to detect, so the check cannot be reproduced in real logic, and synthesis support varies: some tools reject them while others accept them by treating them like ==, which silently removes the check. The coding rule is: do not use them in synthesisable RTL; use them in testbenches.

    Expression

    Result

    4'bx === 4'bx

    1

    4'bx == 4'bx

    x

    4'bx000 == 4'b0001

    0 (a known bit already differs)

    4'bx000 == 4'b0000

    x (the unknown bit decides)

    result !== expected in a check

    Fails correctly if result is x; != would not

    Tip

    In self-checking tests always compare with !== so that an x output is reported as a mismatch instead of being ignored.

    Check yourself Write an expression for “the 8-bit counter is at maximum: all bits are 1”. When does it actually wrap?

    &count is 1 only when every bit is 1, so it flags maximum. The wrap happens on the next accepted increment, for example &count && inc.

    Testbench

    The testbench below checks reduction flags and the difference between bitwise and logical operators.

    design.sv
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    module tb_reduction;
      logic [3:0] a = 4'b0101;
      logic [3:0] b = 4'b0010;
      logic [31:0] word = 32'hDEADBEEF;
      int errors = 0;
    
      initial begin
        // reduction: collapse one vector to a flag
        if ((&4'b1111) !== 1'b1) errors++;          // all ones
        if ((|4'b0000) !== 1'b0) errors++;          // any set? no
        if ((^4'b0111) !== 1'b1) errors++;          // odd parity of three ones
        if ((~|4'b0000) !== 1'b1) errors++;         // zero detect
    
        // bitwise vs logical on the same operands
        if ((a & b)  !== 4'b0000) errors++;         // no common 1 bits
        if ((a && b) !== 1'b1)    errors++;         // both non-zero -> true
    
        // parity of a 32-bit word: even number of ones gives 0
        if ((^word) !== 1'b0) errors++;
    
        if (errors == 0) $display("PASS: operator families behave as described");
        $finish;
      end
    endmodule

    Remember

    • Reduction operators (&v, |v, ^v) collapse a vector to one bit: all-ones, any-one, parity.

    • == gives x when unknown bits decide the answer; === and !== compare x and z literally and belong in testbenches only.

    • Use !== in self-checking tests so an x output counts as a mismatch.

    Rule of thumb: bitwise for bits, logical for conditions.

    Keep going

    • Code lab: Build an even parity generator

    • Interview: run a mock interview on this topic

    Related topics

    • Shift and arithmetic intent

    Previous

    22 / 350

    Next: Shift and Arithmetic Intent

    Up next

    Up nextShift and Arithmetic Intent

    Sign in to save progress

    Practice this lessonReport an error

    See also

    • Width Discipline
    • Bit Vectors and Slicing
    • Parameterized, Type-Safe Design