Family | Operators | Operates | Result |
|---|---|---|---|
Bitwise |
| bit by bit between vectors | Vector, same width |
Reduction |
| across all bits of one vector | One bit |
Logical |
| treats each operand as true (non-zero) or false | One bit |
Flag | Expression | Meaning |
|---|---|---|
All ones |
| Every bit is 1 (for example a counter at maximum) |
Any set |
| At least one bit is 1 (a non-zero test) |
Zero detect |
| All bits are 0 |
Odd parity |
| Odd number of ones; |
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.
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== 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 |
|---|---|
| 1 |
| x |
| 0 (a known bit already differs) |
| x (the unknown bit decides) |
| Fails correctly if result is |
&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.
The testbench below checks reduction flags and the difference between bitwise and logical operators.
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