Skip to content

Verilog · Chapter 14.6.5 · Behavioural Modeling

Loops Advanced Techniques in Verilog — Nested Loops, disable & Patterns

This lesson closes the loop section with the patterns that combine the basic loops. Nested loops describe two-dimensional logic, where a loop over rows inside a loop over columns unrolls into a full grid of hardware. Verilog has no break or continue keywords, so early exit from a loop is done with the disable statement on a named block, plus a guarded skip when you need continue-style behavior. A recurring judgement call is the boundary between a procedural loop, which replicates logic inside an always block, and a generate loop, which replicates structure such as module instances at elaboration time. This page drills nested loops, disable-based loop control, common loop patterns, and how to choose between procedural loops and generate.

Foundation10 min readVerilogNested Loopsdisablebreak continueLoops

Chapter 14 · Section 14.6.5 · Behavioural Modeling

1. The Engineering Problem

Beyond a single for, loops combine: nested loops for 2D logic, disable for early exit (Verilog has no break/continue), and the choice between a procedural loop and generate:

Nested loops unroll into 2D hardware; early exit uses disable on a named block (no break/continue keywords); and procedural loops replicate logic while generate replicates structure.

2. Nested Loops

Loops nest to describe 2D-replicated logic:

nested.v
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
   // a grid of per-element operations — unrolls into ROWS x COLS logic
   always @(*)
       for (r = 0; r < ROWS; r = r + 1)
           for (c = 0; c < COLS; c = c + 1)
               out[r][c] = in[r][c] & mask[r][c];

The outer loop over rows and inner loop over columns unroll into a ROWS × COLS grid of AND gates — all combinational, all parallel. Both bounds must be static (14.6.1). Nested loops express matrix operations, 2D arrays, and crossbar-like structures compactly.

3. disable — Break and Continue

Verilog has no break or continue keywords; disable on a named block provides the equivalent:

disable.v
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
   // BREAK — disable the named loop block to exit early:
   begin : search_loop
       for (i = 0; i < N; i = i + 1)
           if (data[i] == target) begin
               found = i;
               disable search_loop;     // 'break' — exit the loop
           end
   end
 
   // CONTINUE — disable a named inner block to skip to the next iteration:
   for (i = 0; i < N; i = i + 1) begin : body
       if (skip[i]) disable body;       // 'continue' — skip rest of this pass
       process(data[i]);
   end
  • disable named_loop acts like break — it terminates the named loop block.
  • disable named_body (a named inner block per iteration) acts like continue — it ends the current pass, and the loop proceeds to the next.
  • These are mostly used in testbenches (search loops, conditional skips); synthesizable loops usually express the same with conditions inside the unrolled body.

4. Procedural Loop vs generate — The Boundary

The judgement that connects to the next chapter:

  • Procedural loop (for inside always) — replicates logic: it unrolls the body's assignments into parallel combinational logic within a block.
  • generate loop (14.7) — replicates structure: module instances, always blocks, continuous assignments, indexed by a genvar, at elaboration.
loop-vs-generate.v
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
   // procedural loop — replicates LOGIC inside one always block:
   always @(*)
       for (i = 0; i < W; i = i + 1) y[i] = a[i] & b[i];
 
   // generate loop — replicates STRUCTURE (e.g. module instances) — see 14.7:
   //   genvar g;
   //   generate for (g = 0; g < W; g = g + 1) begin
   //       and_cell u (.a(a[g]), .b(b[g]), .y(y[g]));
   //   end endgenerate

Use a procedural loop to replicate logic within a block; use generate to replicate whole instances or blocks. (14.7 drills generate.)

5. Common Mistakes

  1. Expecting break/continue keywords — use disable on a named block (§3).
  2. Runtime bounds on nested loops — both bounds must be static to unroll (§2).
  3. Using a procedural loop where generate is needed — to replicate instances, use generate (§4).

6. Interview Q&A

7. Exercises

Exercise 1 — Nested loop

Write a nested for that computes the element-wise XOR of two 4×4 bit arrays.

Exercise 2 — Break

Write a named loop that searches data[0..N-1] for target and exits (via disable) when found.

Exercise 3 — Loop or generate?

For (a) a per-bit AND inside a block and (b) an array of 8 identical sub-module instances, which construct fits each?

8. Summary

Advanced loop techniques:

  • Nested loops unroll into 2D hardware (static bounds on both).
  • disable on a named block provides break (and continue via a named inner block) — Verilog has no such keywords.
  • Procedural loop vs generate — procedural replicates logic inside a block; generate replicates structure (instances/blocks) at elaboration (14.7).

Loops complete

This closes Chapter 14.6 Loopsfor (14.6.1), while (14.6.2), repeat (14.6.3), forever (14.6.4), and these advanced techniques (14.6.5) — unified by the unrolling concept: synthesizable loops replicate into parallel hardware at elaboration and need static bounds.

The chapter — and the RTL core — closes with structural replication: Chapter 14.7 Generate Block drills generate (for/if/case) — replicating module instances and blocks at elaboration, the structural counterpart to procedural loops.