循环

循环只不过是将需要多次运行的语句包含在循环中,而不是重复编写这些语句。循环将根据条件语句运行多次,如果条件始终为真,则它会变成无限循环,系统将挂起。

Untitled Diagram-Page-6 drawio (2)

循环一览表#

序号循环变量解释
1.while根据条件重复语句集
2.do_while先运行语句而不检查条件,行为就像 while
3.repeat仅重复语句特定次数
4.for_loop与 while 类似,但比 while 更紧凑
5.foreach仅用于遍历数组的每个元素
6.forever在整个模拟过程中重复这些语句

1. while#

在 while 循环中,首先我们需要检查条件,然后才能执行语句。我们需要在执行之前初始化条件中的变量。
while 循环首先检查条件是否为真,如果为真则执行语句。如果条件为假,循环就在那里结束。

语法 -

while(condition)begin
 Statements;
end

流程图:

nanoo dig

2. do-while#

在do-while循环中,首先执行一次条件,然后检查条件是否成立。如果条件为真,则执行该组语句,直到条件为假为止。如果条件为假,循环就在那里结束。

语法 -

do begin 
 Statements; 
end
while(condition)begin 
 Statements;
end   

流程图:

nanoo dig2

3.repeat#

该循环用于将语句或操作重复固定给定的次数。

语法 -

repeat(no. of times)begin  
 statements;
end  

示例: -

下面的示例显示了重复循环的工作原理。这里,重复循环内有三个语句。重复4次。

代码快照

    module repeat_code;  
    initial begin ;  
     repeat(4)begin   // Repeat the statements inside 4 times  
       $display ("Good morning");  
       $display ("Keep shining");  
       $display ("--------------");  
     end  
    end  

流程图:

repeat

4.for#

for 循环只是 while 循环的一种更简洁的形式。在 for 循环的赋值语句中,有三个部分:

  • 初始化 - 初始化运行循环所需的变量。
  • 条件 - 根据此条件,for 循环的重复次数取决于条件的满足情况。
  • 修改器 - 增加/减少变量的值。

语法:

for ( Initialization; condition; modifier ) 
begin
statement1;
statement2 
.   
.  
statementN;
end    

示例:

          for (int i=1;i<=5;i++)    
          begin     
          $display(" Iteration %0d ",i);     
          end   
          $display(" out of loop ");  

在上述示例中,i 是一个被初始化和声明为 1 的变量,在这里 i 是局部作用域,意味着我们不能在 for 循环外部使用 i。在条件部分,i 应该小于或等于 5,这意味着只有当 i 的值满足条件时,for 循环语句才会执行,否则退出循环。最后一部分是修改器,它将 i 的值增加 1。

流程图:

forloop

注意:如果您尝试在外部使用局部作用域变量,则编译器会抛出如下错误。

for error1


嵌套 for 循环

语法:

for ( Initialization ; condition; modifier ) 
 begin
  statements;
   for ( Initialization ; condition ; modifier )
    begin
     statements;
   end  
 end 

示例::

          for (int i=1;i<=2;i++)   
          begin   
          $display("\n\t%0d Table:\n",i);   
          for(int j=1,k=0;j<=10;j++)    
          begin   
          k=i*j;   
          $display("\t %0d X %0d = %0d",i,j,k);   
          end   
          end   

在上面的示例中,我们使用嵌套的 for 循环来打印乘法表,因此取 i 作为表号,j 用于从 1 到 10 循环,k 用于存储乘法的结果。在这里可以注意到 j 和 k 在同一初始化步骤中被使用,您也可以在条件和修改器中做同样的操作,以一次处理多个变量。

优点:

  • 可读性强
  • 语法更简单(可以在单个位置提及所有的初始化、条件、修改器)

限制:

  • 初始化的变量仅在本地范围内有效。

5.foreach#

这个循环是 for 循环的升级版,用于遍历数组的每个元素。它从索引 0 开始迭代,直到数组的大小为止。

foreach 是以下 for 循环的简短版本。

for(int i=0;i<$size(array);i++)

语法:

foreach(array[i])  
begin  
statement1;
statement2  
.`  
.  
statementN;
end   

示例::

          int array[5]   
          foreach(array[i])     
          begin      
          array[i]=i;    
          $display("\tarray[%0d]=%0d",i,array[i]);     
          end     
          $display(" out of loop ");   

在上述示例中,我们取了一个大小为 5 的固定数组,使用 foreach 循环遍历每个元素,并执行 foreach 循环中的语句,从 array[0] 到 array[4]。

流程图:

foreach flowchart

我们可以通过使用 for 循环来实现上述程序的相同功能,替换以下行的 foreach 部分。

for(int i=0;i<$size(array);i++)

注意: 我们可以类似于嵌套 for 循环一样使用嵌套 foreach,并且可以访问多维数组。

优点:

  • 语法更简单。
  • 可读性强。

限制:

  • 它只能用于数组。
  • 无法访问修改器(如果我们只想在偶数位置存储数组,则 foreach 不是一个好的选择)。
  • 不能以相反的方式遍历数组。

6.forever#

forever 循环的名称本身表明它将永远运行,即在整个仿真过程中或强制关闭 forever 循环之前。
它类似于 SystemVerilog 中的 always procedural block,但通常无法在类中使用 always 来实现该概念,因此我们可以使用 forever 循环。
如果我们使用 forever 循环而不强制停止,编译器将挂起。
停止 forever 循环有两种方法:

  • $finish;
  • break;

使用 $finish 的 forever 循环:#

forever 循环没有任何条件,因为重复循环的次数是无限的,所以不需要条件。

语法:

forever
begin  
statement1;  
statement2
.  
.  
statementN;  
end  

示例::

          forever   
          begin    
          $display("\t @ %0d ns Iteration %0d",$time,a);   
          a++;   
          #4;   
          end   
          initial begin   
          #20 $display("\n\t@ %0d ns Stopped using $finish",$time);   
          $finish;   
          end   

在上述示例中,使用了 forever 循环,其中包含显示语句和对变量 a 进行递增,并在每次重复后延迟 4ns,这样它将永远运行。但是,在另一个 initial 块中,有一个 $finish 语句,它将停止仿真,因此也会停止 forever 循环。

流程图:

forever finish

使用 break 的 forever 循环:#

语法:

forever 
begin 
statement1; 
statement2 
.
.
statementN;
end   

示例::

          forever   
          begin   
          $display("\t @ %0d ns Iteration %0d",$time,a);   
          a++;   
          #4;   
          if(a>8)   
          break;   
          end   
          $display("\n\t@ %0d ns Stopped using break",$time);    
          end   

这个示例类似于使用 $finish 的 forever 循环,但这里我们使用了 break 条件,条件是基于一个大于 8 的值。

流程图:

forever break

优点:

  • 我们无法在 always 块内部或类中使用另一个 always 块,因此使用 forever 可以达到相同的目的。

限制:

  • 如果我们不退出 forever 循环,仿真器将挂起。