0
0
VerilogHow-ToBeginner · 3 min read

How to Write Synthesizable For Loop in Verilog

To write a synthesizable for loop in Verilog, use it inside procedural blocks like always or initial with a fixed loop count known at compile time. The loop variable must be a local integer and the loop must not depend on runtime conditions to ensure synthesis tools can unroll it.
📐

Syntax

A synthesizable for loop in Verilog follows this pattern:

  • Initialization: Set the loop variable before the loop starts.
  • Condition: A fixed condition that the loop checks before each iteration.
  • Increment: Change the loop variable each iteration.
  • The loop runs inside an always or initial block for synthesis.
verilog
integer i;
always @(posedge clk) begin
  for (i = 0; i < 8; i = i + 1) begin
    // loop body
  end
end
💻

Example

This example shows a synthesizable for loop that copies an 8-bit input bus to an 8-bit output bus bit by bit on each clock cycle.

verilog
module for_loop_example(
  input wire clk,
  input wire [7:0] data_in,
  output reg [7:0] data_out
);

  integer i;

  always @(posedge clk) begin
    for (i = 0; i < 8; i = i + 1) begin
      data_out[i] <= data_in[i];
    end
  end

endmodule
⚠️

Common Pitfalls

Common mistakes when writing synthesizable for loops include:

  • Using variables that are not local integers as loop counters.
  • Using loops with variable or runtime-dependent bounds, which synthesis tools cannot unroll.
  • Placing loops outside procedural blocks like always or initial.
  • Using loops to create combinational logic without proper blocking assignments.

Example of wrong and right usage:

verilog
// Wrong: loop variable is a wire (not synthesizable)
wire [3:0] i;

always @(posedge clk) begin
  for (i = 0; i < 4; i = i + 1) begin
    // invalid
  end
end

// Right: loop variable is integer
integer j;
always @(posedge clk) begin
  for (j = 0; j < 4; j = j + 1) begin
    // valid
  end
end
📊

Quick Reference

AspectDetails
Loop variableDeclare as integer inside the module
Loop boundsFixed constants or parameters, known at compile time
PlacementInside procedural blocks like always or initial
AssignmentsUse non-blocking (<=) in sequential logic
SynthesisLoop must be unrollable by synthesis tools

Key Takeaways

Use an integer loop variable declared locally inside the module.
Write the for loop inside an always or initial procedural block.
Keep loop bounds fixed and known at compile time for synthesis.
Avoid runtime-dependent loop conditions to ensure unrolling.
Use non-blocking assignments (<=) for sequential logic inside loops.