Verilog · Chapter 11.1 · Gate-Level Modeling
Predefined Gate Primitives in Verilog — and, or, not, xor & Tri-State Gates
Verilog ships with a set of built-in gate primitives, logic gates you can instantiate directly with no definition needed. They are the alphabet of gate-level structural modeling: the multi-input logic gates such as and, nand, or, nor, xor, and xnor, the buffers and inverters buf and not, and the tri-state gates that drive a high-impedance value under control. This lesson drills their syntax, including the terminal-ordering rule that the output comes first, the multi-input and multi-output forms, and the tri-state control behaviour, and how they wire together into structural circuits. You read gate primitives far more often than you write them, since synthesized netlists are made of them, so the goal here is fluency in recognizing and reasoning about gate-level structure rather than authoring functional RTL this way.
Foundation15 min readVerilogGate PrimitivesStructuralTri-StateNetlistRTL Design
Chapter 11 · Section 11.1 · Gate-Level Modeling
1. The Engineering Problem
Open a synthesized netlist and you see thousands of lines like `and U123 (n45, n12, n33);`. To read it — to follow how the gates connect, debug a gate-level simulation, or understand a library cell — you must know the gate primitives and the one rule that governs them:
Verilog's built-in gate primitives instantiate logic gates directly, with the output terminal first and inputs after. Reading gate-level structure means knowing the primitives and this terminal order.
This page teaches the primitives — the logic gates, buffers, and tri-state gates — and how they compose. It is the vocabulary for reading the netlist level.
2. Mental Model — Gates Instantiated Like Tiny Modules
3. Multi-Input Logic Gates
The core logic gates take any number of inputs and produce one output:
and (y, a, b); // y = a & b
and (y, a, b, c, d); // y = a & b & c & d (any number of inputs)
nand (y, a, b); // y = ~(a & b)
or (y, a, b); // y = a | b
nor (y, a, b); // y = ~(a | b)
xor (y, a, b); // y = a ^ b
xnor (y, a, b); // y = ~(a ^ b)- The first terminal is the output, the rest are inputs.
- They accept two or more inputs —
`and (y, a, b, c, d)`is a 5-input AND. The function extends naturally (AND of all inputs, OR of all inputs, XOR/parity of all inputs). - These are the structural equivalents of the bitwise operators (10.4) on scalars —
`and (y, a, b)`is the gate-level form of`assign y = a & b;`.
4. Buffers and Inverters
buf (buffer) and not (inverter) have one input but may drive multiple outputs — so their terminal order is reversed: outputs first, the single input last.
not (y, a); // y = ~a
buf (y, a); // y = a (drives/strengthens the signal)
not (y1, y2, a); // TWO outputs, one input: y1 = ~a, y2 = ~a
buf (z1, z2, z3, a); // three outputs, one input`not`inverts;`buf`passes through (used to drive a signal to multiple loads or strengthen it).- The last terminal is the single input; all earlier terminals are outputs. This is the inverse of the logic-gate convention — a frequent point of confusion.
- The multi-output form is a structural convenience (fan-out from one input).
5. Tri-State Gates
The tri-state gates drive their output or put it in high-impedance (z) based on a control input — the structural form of a tri-state driver (Chapter 5):
bufif1 (y, a, ctrl); // y = ctrl ? a : 1'bz (drive when ctrl=1)
bufif0 (y, a, ctrl); // y = ctrl ? 1'bz : a (drive when ctrl=0)
notif1 (y, a, ctrl); // y = ctrl ? ~a : 1'bz (inverting, drive when ctrl=1)
notif0 (y, a, ctrl); // y = ctrl ? 1'bz : ~a (inverting, drive when ctrl=0)- Terminals: output, input, control —
`bufif1 (out, in, ctrl)`. `bufif1`drives when control is 1, high-impedance otherwise;`bufif0`is the opposite polarity; the`notif`variants invert the data.- These build tri-state buses: multiple
`bufif`gates driving a shared net, one enabled at a time (the shared net is atri, Chapter 5.1.1). If two drive at once, the net contends.
6. Building Structural Circuits
Gate primitives compose into circuits by wiring their terminals through internal nets:
module mux2_gates (
input a, b, sel,
output y
);
wire nsel, a_path, b_path;
not (nsel, sel); // nsel = ~sel
and (a_path, a, nsel); // a when sel=0
and (b_path, b, sel); // b when sel=1
or (y, a_path, b_path); // combine
endmoduleThis 2:1 mux is four gate instances and three internal nets — the structural equivalent of `assign y = sel ? a : b;` (Chapter 13.2). Notice the verbosity: four lines and three named nets for what dataflow does in one line. That contrast is exactly why gate-level is reference, not authoring: you read this in a netlist, but you write the dataflow form.
Visual A — gate primitives wire into a structural circuit
7. Industry Perspective
- Netlists are gate primitives (or cells). A synthesized netlist instantiates standard-cell modules (or, for simple cases, gate primitives) wired by nets — reading it is reading gate-level structure.
- Tri-state gates model real bus drivers.
`bufif`structures model on-chip and off-chip tri-state buses, where multiple drivers share a net under enable control. - Hand gate-level is rare and deliberate. Engineers occasionally hand-instantiate a specific gate (a particular cell, a clock buffer, a tri-state driver) where they need exact control, but functional logic is written in dataflow/behavioural.
- Terminal order is a reading discipline. Knowing output-first for logic gates and output(s)-first/input-last for buffers is essential to correctly follow signal flow in a netlist.
8. Common Mistakes
- Misreading the output terminal as an input — the output is first for logic gates (§2/§3).
- Confusing buf/not terminal order — buffers/inverters put outputs first and the single input last (§4).
- Tri-state contention — two
`bufif`gates enabled onto one net at once contend (§5). - Hand-writing gate-level for functional logic — verbose and error-prone; use dataflow (§6).
- Expecting to define primitives — they are built in; no module definition (Ch 11 overview).
9. Debugging Lab
Two gate-primitive debug post-mortems
10. Interview Q&A
11. Exercises
Exercise 1 — Read the gate
Give the function of each: (a) and (y, a, b, c); (b) nor (y, a, b); (c) not (z, x); (d) bufif0 (y, d, en); (e) xor (p, a, b, c).
Exercise 2 — Identify the output
For each instance, name the output terminal: (a) or (w, x, y, z); (b) buf (a, b); (c) not (m, n, p); (d) nand (q, r, s).
Exercise 3 — Build structurally
Write a gate-level (structural) half adder: sum = a ^ b, carry = a & b, using gate primitives.
Exercise 4 — Fix the gate-level bugs
Identify and fix each: (a) and (a, b, y) intending y = a & b; (b) not (a, y1, y2) intending two inverted outputs of one input.
12. Summary
Verilog's built-in gate primitives instantiate logic gates directly for structural (gate-level) modeling:
- Multi-input logic —
and,nand,or,nor,xor,xnor: output terminal first, then any number of inputs. - Buffers/inverters —
buf,not: output(s) first, single input last; can fan out to multiple outputs. - Tri-state —
bufif0/1,notif0/1: output, input, control; drive or high-impedance, for tri-state buses with mutually-exclusive enables.
The discipline this page instils:
- Output terminal first for logic gates (and outputs-first/input-last for buffers) — the key reading rule.
- One enable at a time on a tri-state bus — multiple drivers contend.
- Read gate-level, author dataflow — netlists are gate primitives; new RTL is not.
The next page adds timing: Chapter 11.2 Gate Delays covers the delay specifications you can put on gate primitives — rise, fall, and turn-off delays, the min:typ:max form, and why they are a simulation-only modeling tool.
Related Tutorials
- Gate-Level Modeling — Chapter 11 overview; the structural-modeling context for these primitives.
- Bitwise Operators — Chapter 10.4; the dataflow equivalents of the logic gates.
- wire and tri Nets — Chapter 5.1.1; the nets that wire gates and the tri-state bus.
- Dataflow Practical Examples — Chapter 13.2; the same circuits at the higher dataflow abstraction.