Verilog · Chapter 14.7 · Behavioural Modeling
Generate Block in Verilog — Structural Replication at Elaboration
The generate construct is the Verilog tool for building hardware structure programmatically. It replicates and conditionally includes module instances, always blocks, continuous assignments, and declarations at elaboration, controlled by parameters and a special compile-time loop variable. Where a procedural loop replicates logic inside an always block, a generate loop replicates structure, such as an array of identical sub-module instances, a row of registers, or a bit-sliced datapath built from cells. Where a runtime conditional builds a multiplexer, a generate conditional includes or excludes whole blocks of hardware based on a parameter, at elaboration and with no runtime cost. This makes generate the backbone of parameterized, reusable RTL, where one module scales its structure with a width parameter or includes optional features by configuration. This page surveys the construct and sets up the sub-topics.
Foundation15 min readVeriloggenerategenvarStructuralParameterizedRTL Design
Chapter 14 · Section 14.7 · Behavioural Modeling
1. The Engineering Problem
You want a parameterized N-bit ripple-carry adder built from N full_adder instances — and N is a parameter. A procedural for loop (14.6) cannot do this: it replicates logic inside an always block, not module instances. You need to generate structure:
genvar i;
generate
for (i = 0; i < WIDTH; i = i + 1) begin : adder_chain
full_adder u_fa (.a(a[i]), .b(b[i]), .cin(carry[i]),
.sum(sum[i]), .cout(carry[i+1]));
end
endgenerateThis generate for loop, at elaboration, instantiates WIDTH full_adder modules — adder_chain[0].u_fa, adder_chain[1].u_fa, … — wired into a chain. The number of instances scales with the parameter, all created at build time. This is structural replication — generating hardware structure (instances and blocks), not runtime logic.
The
generateconstruct replicates and conditionally includes hardware structure — module instances,alwaysblocks, assignments — at elaboration, controlled by parameters andgenvars. It is the structural counterpart to procedural loops.
This page surveys generate — for, if, case, and the genvar — the tool of parameterized, reusable RTL.
2. Mental Model — Generate Replicates Structure at Elaboration
Visual A — generate replicates structure
generate — structural replication at elaboration
data flow3. generate for — Replicate Structure
A generate for loop replicates structural items, indexed by a genvar:
genvar i; // elaboration-time loop variable
generate
for (i = 0; i < WIDTH; i = i + 1) begin : gen_cells
and_cell u (.a(a[i]), .b(b[i]), .y(y[i])); // WIDTH instances
end
endgenerate- The
genvaris a compile-time loop variable (not a runtime reg). - The loop body can contain module instances,
alwaysblocks, continuous assignments, and declarations — replicatedWIDTHtimes at elaboration. - The named block (
begin : gen_cells) gives each replica a hierarchical name (gen_cells[0].u,gen_cells[1].u, …) for referencing.
This builds arrays of instances (a ripple adder, a register file, a bit-sliced datapath) that scale with the parameter. (Drilled in 14.7.1.)
4. generate if — Conditionally Include Structure
A generate if includes or excludes structure based on a parameter — at elaboration:
generate
if (HAS_PARITY) begin : gen_parity
assign parity = ^data; // this logic exists ONLY if HAS_PARITY
end else begin : gen_no_parity
assign parity = 1'b0;
end
endgenerate- The condition is a parameter/
localparam(a compile-time constant), not a runtime signal. - The selected branch's structure is built; the unselected branch is not elaborated — it produces no hardware.
- This differs from a runtime
if(which builds a mux for both branches) and from`ifdef(a preprocessor/macro mechanism):generate ifis parameter-driven, language-level, elaboration-time structure selection. (Drilled in 14.7.2.)
5. generate case — Select Structure by Parameter
A generate case selects among structural variants by a parameter:
generate
case (IMPL)
"FAST": fast_mult u (.a(a), .b(b), .y(y)); // structure per parameter
"SMALL": small_mult u (.a(a), .b(b), .y(y));
default: gen_mult u (.a(a), .b(b), .y(y));
endcase
endgenerateSelects which implementation (instance/block) to elaborate based on the IMPL parameter — only the chosen variant is built. Used to pick among implementation options per configuration. (Drilled in 14.7.3.)
6. The genvar
The genvar is what makes generate for an elaboration-time construct:
genvar g; // declared with 'genvar', not 'integer'
generate for (g = 0; g < N; g = g + 1) begin : loop ... end endgenerate- A
genvaris an elaboration-time integer used only as agenerate forindex — it does not exist as runtime hardware. - It must be statically bounded (like all unrolled loops), and the body is replicated once per
genvarvalue at build time. - Contrast the
integerused in a proceduralfor(14.6.1), which is a runtime loop variable inside analwaysblock.
7. What This Chapter Covers
| § | Sub-topic | Covers |
|---|---|---|
| 14.7.1 | Generate for | replicating instances/blocks; instance arrays; genvar |
| 14.7.2 | Generate if | conditional structure by parameter; vs runtime if and `ifdef |
| 14.7.3 | Generate case | selecting structure variants by parameter |
| 14.7.4 | Generate Advanced Techniques | nested generate, named scopes/hierarchy, combining |
8. Industry Perspective
generateis the backbone of parameterized IP. Reusable modules usegenerate forto scale their structure (an N-wide datapath, an N-entry register file) andgenerate if/caseto include optional features and select implementations — one source serving every configuration.- It replaces copy-paste structure. Instead of hand-writing N identical instances, a
generate forcreates them, scaling with a parameter — less code, fewer errors. - Conditional structure has no runtime cost.
generate ifincludes or excludes hardware at elaboration, so unused features produce no gates — unlike a runtimeif, which builds logic for both branches. - Named generate blocks give navigable hierarchy. The block labels create hierarchical paths (
gen_cells[3].u) used in waveform tools, constraints, and debug.
9. Common Misconceptions
"generate runs at runtime." False. generate is resolved at elaboration (build time) — it constructs structure before simulation/synthesis runs. There is no runtime "generate."
"A genvar is a register." False. A genvar is an elaboration-time loop index, not runtime hardware — it disappears after the structure is generated (contrast the integer in a procedural for).
"generate if is the same as a runtime if." False. A generate if includes/excludes structure based on a parameter at elaboration (the unselected branch produces no hardware); a runtime if builds a mux selecting between branches that both exist in hardware.
10. Debugging Lab
One generate debug post-mortem
Pitfall — trying to instantiate a module inside an always block
module ripple_adder #(parameter N = 4) (input [N-1:0] a, b, output [N-1:0] sum);
wire [N:0] carry;
assign carry[0] = 1'b0;
integer i;
// Intent: build N full-adder INSTANCES. But this is a PROCEDURAL for loop
// inside an always block — it executes behaviour, it cannot create structure.
always @(*)
for (i = 0; i < N; i = i + 1)
full_adder fa (a[i], b[i], carry[i], sum[i], carry[i+1]); // ILLEGAL
endmodule
// A module instance is STRUCTURE — it must exist before simulation/synthesis
// runs. A procedural for loop runs at RUNTIME and executes statements; you
// cannot instantiate a module inside it (the compiler rejects it). Building a
// row of full adders is a structural-replication job, which is exactly what
// 'generate for' with a genvar is for.The compiler errors on the module instantiation inside the always block — a message that instances are not allowed in procedural code. The parameterized "array of N adders" cannot be built this way, and the design will not elaborate.
Procedural loops and generate loops do fundamentally different things. A procedural 'for' (inside always/initial) executes BEHAVIOUR at runtime — it runs statements, with an 'integer' index that exists during simulation. A module instance, by contrast, is STRUCTURE that must be built at ELABORATION, before any runtime. You cannot create structure (an instance) from a construct that runs at runtime, so instantiating a module inside an always-for is illegal.
Replicating structure — N module instances, N always blocks, N assignments — is the job of a 'generate for' loop, which runs at elaboration and uses a 'genvar' (an elaboration-time index, not runtime hardware) plus a named block.
module ripple_adder #(parameter N = 4) (input [N-1:0] a, b, output [N-1:0] sum);
wire [N:0] carry;
assign carry[0] = 1'b0;
genvar i; // elaboration-time index (not a register)
generate
for (i = 0; i < N; i = i + 1) begin : g_fa // NAMED block required
full_adder fa (a[i], b[i], carry[i], sum[i], carry[i+1]);
end
endgenerate
endmodule
// 'generate for' with a 'genvar' replicates the instance N times at
// elaboration, building the structural array. The named block (begin : g_fa)
// gives each instance a hierarchical name (g_fa[0].fa, g_fa[1].fa, ...).
// Structure → generate; behaviour → procedural for. (Drilled in 14.7.1.)11. Interview Q&A
12. Summary
The generate construct builds hardware structure programmatically at elaboration:
generate forreplicates structure (module instances,alwaysblocks, assignments), indexed by agenvar— instance arrays that scale with a parameter.generate if/caseconditionally include or select structure by a parameter — at elaboration, with no runtime cost for the unselected branches.genvaris the elaboration-time loop variable (not runtime hardware).- vs procedural loops —
generatereplicates structure; a proceduralforreplicates logic.
The discipline: use generate to build parameterized, configurable structure — scaling instances, including optional features, selecting implementations — all at elaboration.
The sub-topics drill each: Chapter 14.7.1 Generate for (instance arrays), 14.7.2 Generate if (conditional structure), 14.7.3 Generate case (variant selection), and 14.7.4 Generate Advanced Techniques. This closes Chapter 14 — and the RTL core.
Related Tutorials
- Loops — Chapter 14.6; the procedural loops
generatecontrasts with (logic vs structure). - Module Instantiation — Chapter 9.2; the instances
generate forreplicates. - parameter — Chapter 6.1; the parameters that drive
generate. - Conditional Compilation — Chapter 7.4; the
`ifdefmechanismgenerate ifcontrasts with.