`timescale 1ns/1ns

module test ;

   //(1) while-loop sentense
   reg [3:0]    counter ;
   initial begin
      counter = 'b0 ;
      while (counter<=10) begin
         #10 ;
         counter = counter + 1'b1 ;
      end

   end

   //(2) for-loop sentense
   integer      i ;
   reg [3:0]    counter2 ;
   initial begin
      counter2 = 'b0 ;
      for (i=0; i<=10; i=i+1) begin
         #10 ;
         counter2 = counter2 + 1'b1 ;
      end
   end

   //(3) repeat-loop sentense
   reg [3:0]    counter3 ;
   initial begin
      counter3 = 'b0 ;
      repeat (11) begin
         #10 ;
         counter3 = counter3 + 1'b1 ;
      end
   end

   //(3)
   reg          clk ;
   reg          rstn ;
   reg          enable ;
   reg [3:0]    buffer [7:0] ;
   integer      j ;

   initial begin
      clk       = 0 ;
      rstn      = 1 ;
      enable    = 0 ;
      #3;
      rstn      = 0 ;
      #3;
      rstn      = 1 ;
      enable    = 1 ;
      forever begin
         clk = ~clk ;
         #5 ;
      end
   end

   always @(posedge clk or negedge rstn) begin
      j = 0  ;
      if (!rstn) begin
         repeat (8) begin
            buffer[j]   <= 'b0 ;
            j = j + 1 ;
         end
      end
      else if (enable) begin
         repeat (8) begin
            @(posedge clk) buffer[j]    <= counter3 ;
            j = j + 1 ;
         end
      end
   end



   //stop the simulation
   always begin
      #10 ;
      if ($time >= 1000) $finish ;
   end

endmodule
我用的是 vivado 21 秒学会 vivado 仿真

Verilog 循环语句_循环语句


关键词:while, for, repeat, forever

Verilog 循环语句有 4 种类型,分别是 while,for,repeat,和 forever 循环。循环语句只能在 always 或 initial 块中使用,但可以包含延迟表达式。

while 循环

while 循环语法格式如下:

while (condition) begin
    …
end

while 循环中止条件为 condition 为假。

如果开始执行到 while 循环时 condition 已经为假,那么循环语句一次也不会执行。

当然,执行语句只有一条时,关键字 begin 与 end 可以省略。

下面代码执行时,counter 执行了 11 次。


实例



`timescale 
  1ns
  /
  1ns
  
  
  
 
  module test 
  ;
  
  
  
     
  reg 
  [
  3
  :
  0
  ]    counter 
  ;
  
     
  initial 
  begin
  
         counter 
  = 'b0 
  ;
  
         
  while 
  (counter
  <=
  10
  ) 
  begin
  
             
  #
  10 
  ;
  
             counter 
  = counter 
  + 
  1'b1 
  ;
  
         
  end
  
     
  end
  
  
  
    
  //stop the simulation
  
     
  always 
  begin
  
         
  #
  10 
  ;  
  if 
  (
  $time 
  >= 
  1000
  ) 
  $finish 
  ;
  
     
  end
  
  
  
 
  endmodule

仿真结果如下:

Verilog 循环语句_循环语句_02

for 循环

for 循环语法格式如下:

for(initial_assignment; condition ; step_assignment)  begin
    …
end

initial_assignment 为初始条件。

condition 为终止条件,condition 为假时,立即跳出循环。

step_assignment 为改变控制变量的过程赋值语句,通常为增加或减少循环变量计数。

一般来说,因为初始条件和自加操作等过程都已经包含在 for 循环中,所以 for 循环写法比 while 更为紧凑,但也不是所有的情况下都能使用 for 循环来代替 while 循环。

下面 for 循环的例子,实现了与 while 循环中例子一样的效果。需要注意的是,i = i + 1 不能像 C 语言那样写成 i++ 的形式,i = i -1 也不能写成 i -- 的形式。


实例



// for 循环语句
   
  integer      i 
  ;
   
  reg 
  [
  3
  :
  0
  ]    counter2 
  ;
   
  initial 
  begin
       counter2 
  = 'b0 
  ;
       
  for 
  (i
  =
  0
  ; i
  <=
  10
  ; i
  =i
  +
  1
  ) 
  begin
           
  #
  10 
  ;
           counter2 
  = counter2 
  + 
  1'b1 
  ;
       
  end
   
  end


repeat 循环

repeat 循环语法格式如下:

repeat (loop_times) begin
    …
end

repeat 的功能是执行固定次数的循环,它不能像 while 循环那样用一个逻辑表达式来确定循环是否继续执行。repeat 循环的次数必须是一个常量、变量或信号。如果循环次数是变量信号,则循环次数是开始执行 repeat 循环时变量信号的值。即便执行期间,循环次数代表的变量信号值发生了变化,repeat 执行次数也不会改变。

下面 repeat 循环例子,实现了与 while 循环中的例子一样的效果。


实例


// repeat 循环语句
  
 
  reg 
  [
  3
  :
  0
  ]    counter3 
  ;
  
 
  initial 
  begin
  
     counter3 
  = 'b0 
  ;
  
     
  repeat 
  (
  11
  ) 
  begin  
  //重复11次
  
         
  #
  10 
  ;
  
         counter3 
  = counter3 
  + 
  1'b1 
  ;
  
     
  end
  
 
  end

下面 repeat 循环例子,实现了连续存储 8 个数据的功能:


实例


always @ ( posedge clk or negedge rstn ) begin
    j = 0   ;
    if ( !rstn ) begin
        repeat ( 8 ) begin
            buffer [j ]   <= 'b0 ;       //没有延迟的赋值,即同时赋值为0
            j = j + 1 ;
        end
    end
    else if (enable ) begin
        repeat ( 8 ) begin
            @ ( posedge clk ) buffer [j ]     <= counter3 ;       //在下一个clk的上升沿赋值
            j = j + 1 ;
        end
      end
end


仿真结果如下图。

由图可知,rstn 拉高时,buffer 的 8 个向量同时赋值为 0。

第二个时钟周期后,buffer 依次被 counter3 赋值,实现了连续存储 8 个数据的功能。

Verilog 循环语句_循环语句_03

forever 循环

forever 循环语法格式如下:

forever begin
    …
end

forever 语句表示永久循环,不包含任何条件表达式,一旦执行便无限的执行下去,系统函数 $finish 可退出 forever。

forever 相当于 while(1) 。

通常,forever 循环是和时序控制结构配合使用的。

例如,使用 forever 语句产生一个时钟:


实例



reg          clk ;
initial begin
    clk       = 0 ;
    forever begin
        clk = ~clk ;
        # 5 ;
    end
end


例如,使用 forever 语句实现一个时钟边沿控制的寄存器间数据传输功能:


实例



reg    clk ;
reg    data_in , data_temp ;
initial begin
    forever @ ( posedge clk )      data_temp = data_in ;
end