SystemVerilog Loops

什么是循环?

循环是一段不断执行的代码。 条件语句通常包含在循环中,以便条件变为真时可以终止。 如果循环永远运行,则仿真将无限期挂起。

下表列出了SystemVerilog中不同类型的循环构造。

forever 永远运行给定的语句集
repeat 将给定的语句集重复给定的次数
while 只要给定条件为真,就重复给定的一组语句
for 与while循环类似,但更简洁,更流行
do while 至少重复一次给定的语句集,然后在条件为true时循环
foreach 主要用于遍历数组中的所有元素

forever

就像while(1)一样,这是一个无限循环。请注意,除非您在永久块内添加时间延迟以延长仿真时间,否则仿真将挂起。
注意:
【1】while(1)其中1代表一个常量表达式,它永远不会等于0。循环会一直执行下去。
【2】线程是占用cpu资源的,但是如果挂起的话,操作系统就不给这个现成分配cpu资源,除非以后再恢复,所以线程挂起的作用就是节省cpu资源

module tb;
 
  // 此初始块有一个永久循环,它将“永久运行”,仿真不会停止
  initial begin
    forever begin
      #5 $display ("Hello World !");
    end
  end
 
  // 因为另一个初始块将永远运行,所以我们的仿真将挂起!
  //为了避免这种情况,我们将在50ns后使用$ finish明确终止仿真。
  initial 
    #50 $finish;    
endmodule

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

用于在一个块中重复语句一定次数。下面显示的示例将显示该消息5次,并继续执行其余代码。

module tb;
 
    // 此初始块将执行重复语句,该语句将运行5次并退出
  initial begin
 
        // 在开始结尾重复5次,然后退出“repeat”块
    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

如果您知道verilog / C,您已经知道这一点。只要条件为真,它将重复该块。计数器最初为零,并递增直到达到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);      // 计数器增量
    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

与verilog / C类似,这使您可以在同一行上提及起始值,条件和增量表达式。

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 well

首先执行代码,然后检查条件以查看是否应再次执行该代码。

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

这是最适合遍历数组变量的方法,因为您不必查找数组大小,而是将变量设置为从0开始直到array_size-1,并在每次迭代时递增。

module tb_top;
   bit [7:0] array [8];   // 创建一个固定大小的数组
 
   initial begin
 
      // 为数组中的每个位置分配一个值
      foreach (array [index]) begin
         array[index] = index;
      end
 
      // 遍历每个位置并打印当前位置的值
      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.

参考文献:
【1】https://www.chipverify.com/systemverilog/systemverilog-control-flow-loops

发布了91 篇原创文章 · 获赞 7 · 访问量 5256

猜你喜欢

转载自blog.csdn.net/qq_43042339/article/details/104459642