Boolean gates are the atoms of combinational RTL. Synthesis maps expressions onto technology cells; you usually write the expression, not a gate instance.
Common operators (Verilog / SV)
| Operator | Meaning | Notes |
|---|---|---|
~ |
NOT | Bitwise; unary |
& \| ^ |
AND / OR / XOR | Bitwise |
~& ~\| ~^ |
NAND / NOR / XNOR | Useful but less common in RTL |
&& \|\| ! |
Logical | Collapse to true/false (1-bit) |
&a \|a ^a |
Reduction | Fold a vector to 1 bit |
Coding patterns
assign and2 = a & b;
assign xor2 = a ^ b;
always_comb begin
y = (sel) ? (a & b) : (a | b);
end
Prefer bitwise ops on multi-bit buses. Use logical ops for conditions (if (valid && ready)).
De Morgan & cleanup
Rewrite to keep polarity clear:
~(a & b)≡~a | ~b~(a | b)≡~a & ~b
Active-low signals (*_n) are easier if you name them consistently and invert once at the boundary.
Hazards
AND/OR trees can glitch when inputs change at different times. For status LEDs that is fine; for async resets, clocks, or CDC pulse detection, do not rely on combo glitches — use registered / synchronized control.
Practice tips
- Write truth tables for non-obvious control decode.
- Use
default_nettype noneso undeclared nets fail lint early (RTL Studio Lint helps here). - Keep one clear meaning per signal name (
hit,grant,err).