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
alwaysorinitialblock 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
alwaysorinitial. - 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
| Aspect | Details |
|---|---|
| Loop variable | Declare as integer inside the module |
| Loop bounds | Fixed constants or parameters, known at compile time |
| Placement | Inside procedural blocks like always or initial |
| Assignments | Use non-blocking (<=) in sequential logic |
| Synthesis | Loop 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.