Skip to content

Verilog · Chapter 14.7.4 · Behavioural Modeling

Generate Advanced Techniques in Verilog — Nested Generate, Scopes & Combining

This lesson closes the generate section, and the RTL core, with the patterns that combine the generate constructs into sophisticated parameterized structure. Nested generate loops build two-dimensional instance arrays, such as a grid of cells, a systolic array, or a crossbar, where an outer loop variable and an inner loop variable together index the replicas. Named generate scopes create the hierarchical paths used to reference, constrain, and debug specific replicas. The constructs also combine, so a generate loop can contain a conditional block to specialize some replicas, for example a different cell at the array boundary. This page drills nested generate, named scopes and hierarchical referencing, and the combination of loops with conditionals and case selection, completing the generate construct and the register-transfer-level design toolkit.

Foundation11 min readVerilogNested GenerateHierarchyParameterizedRTL Design

Chapter 14 · Section 14.7.4 · Behavioural Modeling

1. The Engineering Problem

Sophisticated parameterized structure needs the generate constructs combined: 2D arrays via nested loops, hierarchical names for referencing, and conditional specialization within a loop:

Nested generate loops build 2D instance arrays; named generate scopes give hierarchical paths; and for/if/case combine to specialize replicas — the advanced parameterized-structure patterns.

This page drills these, closing the generate construct and the RTL core.

2. Nested Generate — 2D Instance Arrays

Nested generate for loops build 2D-replicated structure:

nested-generate.v
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
   genvar r, c;
   generate
       for (r = 0; r < ROWS; r = r + 1) begin : gen_rows
           for (c = 0; c < COLS; c = c + 1) begin : gen_cols
               pe_cell u (.in(in[r][c]), .out(out[r][c]));   // ROWS x COLS cells
           end
       end
   endgenerate

The outer and inner genvars index a grid of ROWS × COLS instances — a systolic array, a crossbar, a 2D processing array. Each cell is addressable as gen_rows[r].gen_cols[c].u. Both bounds are static parameters; the structure scales in two dimensions.

3. Named Scopes and Hierarchical Referencing

Named generate blocks create hierarchical paths used throughout the flow:

hierarchy.v
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
   // referencing a specific replica's internal signal:
   //   gen_rows[2].gen_cols[3].u.internal_reg
   // in a waveform viewer, assertion, or timing constraint.
 
   generate
       for (i = 0; i < N; i = i + 1) begin : gen_stage
           pipe_stage u (...);
       end
   endgenerate
   // gen_stage[0].u, gen_stage[1].u, ... — addressable pipeline stages

The block label plus the genvar index forms each replica's hierarchical name. These paths are how a specific generated instance is referenced in waveform tools, hierarchical assertions, timing/physical constraints (e.g. constraining gen_stage[3].u), and debug. Always name generate blocks — unnamed ones are hard or impossible to address.

4. Combining for / if / case

The constructs nest to specialize replicas:

combining.v
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
   genvar i;
   generate
       for (i = 0; i < WIDTH; i = i + 1) begin : gen_cell
           if (i == 0) begin : g_first
               first_cell u (.in(in[i]), .out(out[i]));     // special boundary cell
           end else if (i == WIDTH-1) begin : g_last
               last_cell u (.in(in[i]), .out(out[i]));
           end else begin : g_mid
               mid_cell u (.in(in[i]), .out(out[i]));        // interior cells
           end
       end
   endgenerate

A generate for with a generate if inside builds a row of cells where the boundary cells (first, last) differ from the interior ones — a common pattern in arrays with edge conditions (the first/last stage of a pipeline, the carry boundary of an adder). The loop replicates; the conditional specializes per index. This composition expresses sophisticated parameterized structure that scales and adapts.

Visual A — combining generate constructs

generate for + if — replicate and specialize

data flow
generate for + if — replicate and specializegenerate for (i)replicate WIDTH cellsgenerate if (i==0/ i==WIDTH-1)specialize boundariesarray withspecial edgesfirst/last differ from interior
Combining a generate for (replicate) with a generate if (specialize) builds a parameterized array where boundary cells differ from interior ones — e.g. special first/last pipeline stages or adder carry boundaries. The loop replicates; the conditional adapts each index. This composition expresses sophisticated, scalable hardware structure.

5. Common Mistakes

  1. Unnamed nested generate blocks — hierarchical referencing breaks; name every level (§3).
  2. Runtime bounds/conditions — all generate bounds and conditions must be static (parameters/genvars).
  3. Forgetting boundary specialization — array edges often need different cells; combine for with if (§4).

6. Interview Q&A

7. Exercises

Exercise 1 — 2D array

Write a nested generate for that instantiates a ROWS × COLS grid of pe_cell instances.

Exercise 2 — Boundary specialization

Write a generate for with an inner generate if that uses a head_cell for index 0 and a body_cell for all others.

Exercise 3 — Hierarchical name

For a nested generate with outer block gen_r and inner gen_c containing instance u, give the hierarchical name of the cell at row 1, column 2.

8. Summary

Advanced generate techniques combine the constructs:

  • Nested generate — outer + inner genvars build 2D instance arrays (grids, systolic arrays, crossbars).
  • Named scopes — block labels + indices form hierarchical paths (gen[i].u) for referencing, constraints, and debug; always name generate blocks.
  • Combining for/if/case — replicate and specialize (boundary cells differing from interior) for sophisticated parameterized structure.

Chapter 14 — and the RTL core — complete

This closes Chapter 14 Behavioural Modeling — the always/initial blocks (14.1), statement grouping (14.2), the crown-jewel blocking-vs-non-blocking rule (14.3), timing controls (14.4), branching and latch avoidance (14.5), loops and unrolling (14.6), and the generate construct (14.7). You can now describe combinational and sequential hardware procedurally — registers, counters, FSMs, pipelines, and parameterized structure.

And with it, the RTL core is complete. Across the design chapters you have learned to compute with operators (Chapter 10), describe combinational logic with dataflow (Chapter 13), and now model sequential, stateful, parameterized hardware with behavioural constructs (Chapter 14) — the full toolkit of register-transfer-level design. The counter that dataflow could not build, the FSM that drives a controller, the pipeline that moves data across cycles, the parameterized datapath that scales with configuration — all are now within reach. You have crossed from reading Verilog and assembling modules to designing real synchronous RTL.