The short answer: Verilog lets you describe the same circuit at different levels of abstraction: switch level (transistors), gate level (primitives like and, or, not), dataflow (continuous assign statements with Boolean expressions) and behavioural (always blocks with if, case and loops). Structural modelling means building a design by instantiating and connecting smaller modules. Almost all modern RTL is written at the dataflow and behavioural levels; gate level is what synthesis produces.
Textbooks often present these levels as four separate topics. In practice, you’ll write behavioural and dataflow code every day, read gate-level netlists when debugging synthesis, and almost never write switch-level code. I’ll show one 2:1 multiplexer at every level so you can compare them directly.
This post replaces my older separate posts on switch-level, gate-level, structural, behavioural modelling and primitives.
- The four levels at a glance
- Switch level
- Gate level
- User-defined primitives (UDPs)
- Dataflow
- Behavioural
- Structural modelling
- Which level should you use?
Table of Contents
Part 1: The four levels at a glance

Part 2: Switch level
Verilog has transistor primitives (nmos, pmos, cmos) and supply nets. Here’s a CMOS inverter:
module inv_sw (input wire a, output wire y);
supply1 vdd;
supply0 gnd;
pmos p1 (y, vdd, a); // (drain, source, gate): on when a = 0
nmos n1 (y, gnd, a); // on when a = 1
endmodule
Switch-level models are used for some custom-circuit and library modelling, but they’re not synthesisable and you won’t write them for RTL. It’s enough to recognise them.
Part 3: Gate level
Built-in gate primitives (and, or, nand, nor, xor, xnor, not, buf, and tri-state bufif0/1, notif0/1) take the output first, then the inputs:
module mux2_gate (input wire a, b, s, output wire y);
wire sn, a0, b0;
not g0 (sn, s);
and g1 (a0, a, sn);
and g2 (b0, b, s);
or g3 (y, a0, b0);
endmodule
This is exactly what a synthesised netlist looks like, except the gates are library cells (like AND2X1) instead of primitives. Reading netlists is a real skill for synthesis, STA and DFT engineers.
Part 4: User-defined primitives (UDPs)
primitive mux2_udp (output y, input s, a, b);
table
// s a b : y
0 0 ? : 0;
0 1 ? : 1;
1 ? 0 : 0;
1 ? 1 : 1;
endtable
endprimitive
UDPs describe a small function with a truth table, and can also model sequential cells. They show up in standard-cell simulation libraries; in RTL you’d use a module instead.
Part 5: Dataflow
module mux2_df (input wire a, b, s, output wire y);
assign y = s ? b : a; // or: (a & ~s) | (b & s)
endmodule
Continuous assignments describe combinational logic as expressions. They’re ideal for simple logic, muxes and arithmetic. More in my post on dataflow modelling.
Part 6: Behavioural
module mux2_bh (input wire a, b, s, output reg y);
always @(*) begin
if (s) y = b;
else y = a;
end
endmodule
Behavioural code uses always blocks with if, case and loops. It’s the only practical way to write sequential logic and complex control, and it’s what most RTL looks like. Despite the name, synthesisable behavioural code still describes hardware; it’s just more readable.
Part 7: Structural modelling
Structural modelling isn’t really a separate level: it means building a design from instances of other modules, connected by wires. Every real design is structural at the top (a top module full of instances) and behavioural or dataflow at the leaves. See modules, ports and hierarchy.
Part 8: Which level should you use?
| Level | Synthesisable | When I use it |
|---|---|---|
| Switch | No | Never for RTL; recognise it in library models |
| Gate | Yes | Reading netlists, small hand-instantiated cells like synchronisers |
| Dataflow | Yes | Simple combinational logic and arithmetic |
| Behavioural | Yes (with rules) | Sequential logic, FSMs, complex combinational logic |
| Structural | Yes | Connecting blocks at every level of hierarchy |
Practise this on VLSI Forge
I built VLSI Forge so you can write RTL in your browser, run it on a real simulator and check every signal in the waveform. Free, nothing to install.
Previous in my Verilog series: Modules, ports and hierarchy. Next: Dataflow modelling and continuous assignments.
FAQ
What are the levels of modelling in Verilog?
Switch level, gate level, dataflow and behavioural. Structural modelling, connecting module instances, is used at every level.
Which modelling style is best?
For RTL, behavioural and dataflow. They’re readable and synthesise well. Gate level is mostly what tools generate.
Is behavioural code synthesisable?
Yes, if it follows the synthesis rules: no delays, complete assignments in combinational blocks, and clocked blocks for registers.
What is a UDP in Verilog?
A user-defined primitive: a small combinational or sequential function described by a truth table, mostly used in cell libraries.
