Automatic lowering to primitive gates with full netlist generation. AND, OR, XOR, NOT, MUX, and DFF primitives form the foundation of every digital circuit.
CIRCT synthesizes down to six fundamental gate types. Every digital circuit, no matter how complex, is built from these primitives.
| Gate | Inputs | Function | Use Case |
|---|---|---|---|
| AND | 2+ | Output high when all inputs high | Masking, enable logic |
| OR | 2+ | Output high when any input high | Flag combining, priority logic |
| XOR | 2+ | Output high when odd number of inputs high | Parity, comparison, arithmetic |
| NOT | 1 | Output is complement of input | Inversion, active-low signals |
| MUX | 2 data + 1 select | Select between inputs based on control | Data routing, conditionals |
| DFF | D + CLK | Capture input on clock edge | State storage, registers, pipelines |
The synthesis pipeline transforms high-level RTL through multiple passes, progressively lowering abstractions until only primitive gates remain.
High-level operators, case statements
AND/OR/NOT/XOR expressions
Gate instances, wire connections
A simple 2-to-1 multiplexer at the RTL level uses a mux call.
class Mux2 < RHDL::Sim::Component
input :a, :b, :sel
output :y
behavior do
y <= mux(sel, a, b)
end
end
After synthesis: y = (a AND NOT sel) OR (b AND sel).
# NOT g0 (.in(sel), .out(sel_n))
# AND g1 (.in(a, sel_n), .out(t0))
# AND g2 (.in(b, sel), .out(t1))
# OR g3 (.in(t0, t1), .out(y))
#
# Total: 4 gates, 1 level of logic
alu = SimpleALU.new
netlist = alu.synthesize(target: :gates)
netlist.stats
# => { and: 24, or: 16, xor: 8, not: 12, mux: 4, dff: 0 }
# => Total: 64 gates
netlist.to_verilog("alu_gates.v")
netlist.to_dot("alu_gates.dot")