SystemVerilog gives you two statements for changing a loop's flow from inside the loop. break exits the loop immediately. continue skips the rest of the current pass and moves on to the next one. Both are borrowed from C and were added in SystemVerilog. Plain Verilog-2001 had neither, and designers had to use disable on a named block to get the same effect.
6 min read | Intermediate Level
What You'll Learn
- How
breakandcontinuechange the flow of any loop - How they behave in nested loops and in
whileloops - How to use
breakto build a synthesizable "find first" circuit - Where these statements are not allowed, and what to use instead
Syntax
break; // exit the innermost enclosing loop now
continue; // skip to the next pass of the innermost enclosing loop
Both work in every SystemVerilog loop: for, foreach, while, do while, repeat and forever. Both act only on the innermost loop that contains them.
break
The loop below would normally print iterations 0 to 9. When i becomes 7, break ends the loop at once, and execution continues with the first statement after the loop.
module tb;
initial begin
// This for loop increments i from 0 to 9 and exit
for (int i = 0 ; i < 10; i++) begin
$display ("Iteration [%0d]", i);
// Let's create a condition such that the
// for loop exits when i becomes 7
if (i == 7)
break;
end
end
endmodule
ncsim> run Iteration [0] Iteration [1] Iteration [2] Iteration [3] Iteration [4] Iteration [5] Iteration [6] Iteration [7] ncsim: *W,RNQUIE: Simulation is complete.
Iteration 7 is still printed, because the $display comes before the if. The step expression i++ does not run after a break.
continue
Here, when i is 7, continue skips the $display for that pass only. The loop then carries on with 8 and 9.
module tb;
initial begin
// This for loop increments i from 0 to 9 and exit
for (int i = 0 ; i < 10; i++) begin
// Let's create a condition such that the
// for loop
if (i == 7)
continue;
$display ("Iteration [%0d]", i);
end
end
endmodule
ncsim> run Iteration [0] Iteration [1] Iteration [2] Iteration [3] Iteration [4] Iteration [5] Iteration [6] Iteration [8] Iteration [9] ncsim: *W,RNQUIE: Simulation is complete.
In a for loop, continue jumps to the step expression (i++) and then to the condition check. In a while or do while loop it jumps straight to the condition check, because those loops have no separate step.
Quick Check
Q: In the continue example, what would print if continue were replaced with break?
Show Answer
Iterations 0 to 6. When i reaches 7, break exits the loop before the $display runs, so 7, 8 and 9 never print.
break in Nested Loops
break leaves only the loop it is directly inside. The outer loop keeps running.
module tb;
initial begin
for (int row = 0; row < 3; row++) begin
for (int col = 0; col < 3; col++) begin
if (col == 1)
break; // leaves the inner (col) loop only
$display ("row %0d col %0d", row, col);
end
end
end
endmodule
// Prints: row 0 col 0, row 1 col 0, row 2 col 0
To leave both loops at once, set a flag before the inner break and test it in the outer loop. Alternatively, put the loops in a named block and use disable on it.
Using break in Digital Design
Most current synthesis tools accept break and continue inside loops with constant bounds. The loop is still unrolled. break simply turns the remaining iterations into logic that is gated off once the exit condition is met.
A "find first" circuit is a natural fit. The module below returns the index of the lowest set bit of req:
module find_first_one (
input logic [7:0] req,
output logic [2:0] idx,
output logic found
);
always_comb begin
idx = '0; // defaults when no bit is set
found = 1'b0;
for (int i = 0; i < 8; i++) begin
if (req[i]) begin
idx = i; // lowest set bit wins
found = 1'b1;
break; // stop scanning after the first match
end
end
end
endmodule
For req = 8'b0010_0110, idx is 1. Without the break, later matches would overwrite idx and the result would be the highest set bit, 5. The synthesized hardware is a priority chain from bit 0 upwards.
Where are break and continue used?
In RTL, break keeps leading-one detectors, free-slot finders in buffer allocators and first-match lookups compact and readable. In testbenches, continue skips transactions a scoreboard should ignore, such as idle cycles, and break ends a forever polling loop once a completion flag or timeout is seen.
Where break and continue Are Not Allowed
- Outside a loop. Using
breakto leave anifor abegin ... endblock is a compile error. To leave a task or function early, usereturn. - Across a
forkboundary. Abreakinside afork ... joincannot exit a loop that surrounds the fork, because each forked branch is a separate process.
Common Beginner Mistakes
Mistake #1: continue before the increment in a while loop
Wrong:
int i = 0;
while (i < 10) begin
if (i == 7) continue; // jumps back to the check with i still 7
$display ("i = %0d", i);
i++;
end
Right: increment before the continue, or use a for loop, where continue still runs the step.
Why? A while loop has no step expression. Skipping the rest of the body also skips i++, so i stays at 7 forever.
Mistake #2: Expecting break to exit every nested loop
break exits only the innermost loop. Why? It is defined relative to the nearest enclosing loop. Use a flag or disable on a named block to exit several levels at once.
Mistake #3: Using break where return belongs
Wrong: if (error) break; at the top level of a task, outside any loop
Right: if (error) return;
Why? break is only legal inside a loop. return exits the task or function from anywhere in its body.
Practice Exercise
Challenge: Sum the even values, stop at a marker
Given int data[6] = '{4, 7, 10, 3, -1, 8};, add up only the even values, and stop as soon as you reach -1, which marks the end of valid data. The expected sum is 14.
Hint
Use foreach. Check for the -1 marker first with break, then skip odd values with continue.
Solution
module tb;
int data[6] = '{4, 7, 10, 3, -1, 8};
int sum;
initial begin
foreach (data[i]) begin
if (data[i] == -1) break; // end-of-data marker: stop scanning
if (data[i] % 2 != 0) continue; // skip odd values
sum += data[i];
end
$display ("sum = %0d", sum); // sum = 14 (4 + 10); 8 is never reached
end
endmodule
The order of the two checks matters. The marker test comes first so that -1 is never treated as data.
Summary
In this tutorial, you learned:
breakexits the innermost loop immediately;continueskips to its next pass- Both work in all six SystemVerilog loops and act only on the innermost one
- In a
forloop,continuestill runs the step; in awhileloop, it jumps straight to the condition breakinside a constant-bound loop is synthesizable and gives first-match priority logic- Outside a loop, use
returnto leave a task or function, ordisableto leave a named block