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.

foreverRuns the given set of statements forever
repeatRepeats the given set of statements for a given number of times
whileRepeats the given set of statments as long as given condition is true
forSimilar to while loop, but more condense and popular form
do whileRepeats the given set of statements atleast once, and then loops as long as condition is true
foreachUsed 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.

 Simulation Log
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
 Simulation Log
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
 Simulation Log
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
 Simulation Log
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
 Simulation Log
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
 Simulation Log
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.