What are loops ?
A loop is a piece of code that keeps executing over and over. A conditional statement is typically included in a loop so that it can terminate once the condition becomes true. If the loop runs forever, then the simulation will hang indefinitely.
Different types of looping constructs in SystemVerilog are given in the table below.
forever | Runs the given set of statements forever |
repeat | Repeats the given set of statements for a given number of times |
while | Repeats the given set of statments as long as given condition is true |
for | Similar to while loop, but more condense and popular form |
do while | Repeats the given set of statements atleast once, and then loops as long as condition is true |
foreach | Used mainly to iterate through all elements in an array |
forever
This is an infinite loop, just like while (1)
. Note that your simulation will hang unless you include a time delay inside the forever
block to advance simulation time.
module tb;
// This initial block has a forever loop which will "run forever"
// Hence this block will never finish in simulation
initial begin
forever begin
#5 $display ("Hello World !");
end
end
// Because the other initial block will run forever, our simulation will hang!
// To avoid that, we will explicity terminate simulation after 50ns using $finish
initial
#50 $finish;
endmodule
Note that simulation would have continued indefinitely if $finish
was not called.
ncsim> run Hello World ! Hello World ! Hello World ! Hello World ! Hello World ! Hello World ! Hello World ! Hello World ! Hello World ! Simulation complete via $finish(1) at time 50 NS + 0
repeat
Used to repeat statements in a block a certain number of times. The example shown below will display the message 5 times and continues with rest of the code.
module tb;
// This initial block will execute a repeat statement that will run 5 times and exit
initial begin
// Repeat everything within begin end 5 times and exit "repeat" block
repeat(5) begin
$display ("Hello World !");
end
end
endmodule
ncsim> run Hello World ! Hello World ! Hello World ! Hello World ! Hello World ! ncsim: *W,RNQUIE: Simulation is complete.
while
You already know this if you know verilog/C. It'll repeat the block as long as the condition is true. Counter is initially zero and increments until it reaches 10.
module tb;
bit clk;
always #10 clk = ~clk;
initial begin
bit [3:0] counter;
$display ("Counter = %0d", counter); // Counter = 0
while (counter < 10) begin
@(posedge clk);
counter++;
$display ("Counter = %0d", counter); // Counter increments
end
$display ("Counter = %0d", counter); // Counter = 10
$finish;
end
endmodule
ncsim> run Counter = 0 Counter = 1 Counter = 2 Counter = 3 Counter = 4 Counter = 5 Counter = 6 Counter = 7 Counter = 8 Counter = 9 Counter = 10 Counter = 10 Simulation complete via $finish(1) at time 190 NS + 0
for
Similar to verilog/C, this allows you to mention starting value, condition and incremental expression all on the same line.
module tb;
bit clk;
always #10 clk = ~clk;
initial begin
bit [3:0] counter;
$display ("Counter = %0d", counter); // Counter = 0
for (counter = 2; counter < 14; counter = counter + 2) begin
@(posedge clk);
$display ("Counter = %0d", counter); // Counter increments
end
$display ("Counter = %0d", counter); // Counter = 14
$finish;
end
endmodule
ncsim> run Counter = 0 Counter = 2 Counter = 4 Counter = 6 Counter = 8 Counter = 10 Counter = 12 Counter = 14 Simulation complete via $finish(1) at time 110 NS + 0
do while
This executes the code first and then checks for the condition to see if the code should be executed again.
module tb;
bit clk;
always #10 clk = ~clk;
initial begin
bit [3:0] counter;
$display ("Counter = %0d", counter); // Counter = 0
do begin
@ (posedge clk);
counter ++;
$display ("Counter = %0d", counter); // Counter increments
end while (counter < 5);
$display ("Counter = %0d", counter); // Counter = 14
$finish;
end
endmodule
ncsim> run Counter = 0 Counter = 1 Counter = 2 Counter = 3 Counter = 4 Counter = 5 Counter = 5 Simulation complete via $finish(1) at time 90 NS + 0
foreach
This is best suited to loop through array variables, because you don't have to find the array size, set up a variable to start from 0 until array_size-1 and increment it on every iteration.
module tb_top;
bit [7:0] array [8]; // Create a fixed size array
initial begin
// Assign a value to each location in the array
foreach (array [index]) begin
array[index] = index;
end
// Iterate through each location and print the value of current location
foreach (array [index]) begin
$display ("array[%0d] = 0x%0d", index, array[index]);
end
end
endmodule
ncsim> run array[0] = 0x0 array[1] = 0x1 array[2] = 0x2 array[3] = 0x3 array[4] = 0x4 array[5] = 0x5 array[6] = 0x6 array[7] = 0x7 ncsim: *W,RNQUIE: Simulation is complete.