🔁 SystemVerilog Loops & Control Flow Statements#
SystemVerilog provides several looping constructs and control flow mechanisms that make it easy to write flexible and dynamic RTL logic and testbench behavior. These constructs resemble those in traditional programming languages like C, but with simulation and hardware modeling in mind.
🔄 Loop Types in SystemVerilog#
1. for
Loop#
The most common loop, similar to C-style syntax.
for (int i = 0; i < 10; i++) begin
$display("i = %0d", i);
end
- Suitable for known iteration counts
- Can declare loop variable inside or outside
2. while
Loop#
Executes as long as the condition is true.
int i = 0;
while (i < 5) begin
$display("i = %0d", i);
i++;
end
- Use with caution in hardware: avoid unbounded loops in RTL
3. do...while
Loop#
Executes at least once, checks condition at the end.
int i = 0;
do begin
$display("i = %0d", i);
i++;
end while (i < 3);
- Useful when you want to run the loop body at least once
4. foreach
Loop#
Special loop to iterate over arrays (packed, unpacked, dynamic, associative).
int arr[5] = '{0, 1, 2, 3, 4};
foreach (arr[i]) begin
$display("arr[%0d] = %0d", i, arr[i]);
end
- Simplifies array traversal
- Works well in testbenches
5. repeat
Loop#
Repeats the loop body a fixed number of times.
repeat (4) begin
$display("Repeat block running");
end
- Simpler alternative to
for
when you don’t need a loop variable - Synthesizable if the count is static
6. forever
Loop#
Repeats indefinitely until explicitly broken (e.g., via disable
, break
, or return
).
forever begin
@(posedge clk);
$display("Clock tick");
end
- Great for clock-driven always blocks or simulation-only behavior
- Not synthesizable unless guarded with proper control logic
🧭 Control Flow Statements#
break
#
Exits the current loop immediately.
for (int i = 0; i < 10; i++) begin
if (i == 5) break;
$display("i = %0d", i);
end
💡 Use
break
when you want to stop iterating under certain conditions.
continue
#
Skips the rest of the current iteration and goes to the next.
for (int i = 0; i < 5; i++) begin
if (i == 2) continue;
$display("i = %0d", i);
end
💡 Useful to skip unwanted values or conditions.
return
#
Used inside a task or function to exit early and optionally return a value.
function int square(int x);
if (x < 0)
return 0;
return x * x;
endfunction
- Not used to exit loops, but to exit functions/tasks
⚠️ Hardware Design Tip#
- Avoid using unbounded
while
,do...while
, orforever
in synthesizable RTL break
andcontinue
are not synthesizable in RTL — use FSM logic instead- These constructs are mainly useful in testbenches, UVM, and behavioral models
✅ Summary Table#
Keyword | Purpose | Synthesizable? | Common Use Case |
---|---|---|---|
for | Loop with counter | ✅ (if bounded) | Iterating over indexes |
while | Loop with condition | ⚠️ (avoid infinite) | Testbench control |
do...while | Executes loop at least once | ❌ | Behavioral models |
foreach | Array iteration | ❌ (testbench only) | Array access in TB |
repeat | Fixed-count loop | ✅ (if static count) | Protocol/handshake logic |
forever | Infinite loop | ❌ (unless guarded) | Clock-driven simulation |
break | Exit loop immediately | ❌ | Skip remaining loop |
continue | Skip current iteration | ❌ | Ignore specific values |
return | Exit function/task early | ✅ | Conditional returns |
SystemVerilog’s control flow features help create intuitive and flexible logic, especially in testbenches. In synthesizable design, always ensure loops are bounded and deterministic.
module tb_loops_and_flow;
// For loop
initial begin
for (int i = 0; i < 3; i++)
$display("for loop i = %0d", i);
end
// While loop
initial begin
int j = 0;
while (j < 2) begin
$display("while loop j = %0d", j);
j++;
end
end
// Do...while loop
initial begin
int k = 0;
do begin
$display("do-while k = %0d", k);
k++;
end while (k < 2);
end
// Foreach loop
int arr[3] = '{10, 20, 30};
initial begin
foreach (arr[i])
$display("arr[%0d] = %0d", i, arr[i]);
end
// Repeat loop
initial begin
repeat (2)
$display("repeat loop running");
end
// Forever loop (terminated after short sim)
initial begin
int cnt = 0;
forever begin : forever_loop
#5 $display("forever loop cnt = %0d", cnt++);
if (cnt == 2) break;
end
end
// Break and continue
initial begin
for (int m = 0; m < 5; m++) begin
if (m == 2) continue;
if (m == 4) break;
$display("loop with break/continue m = %0d", m);
end
end
// Return example
initial begin
int val = square(-4);
$display("square(-4) = %0d", val);
end
function int square(int x);
if (x < 0)
return 0;
return x * x;
endfunction
endmodule