Menu Close

Verilog 中While 循环语句

while语句和for语句一样都是循环语句。一般来说,for循环是靠不断更新”表达式3″以满足终止循环条件。while是先判断表达式的条件后执行,如果表达式不满足条件,while循环甚至一次都不会得到执行。在使用时要注意终止循环表达式的编写,原因是在Verilog中不仅包含’0′, ‘1’数字值,还有’X’,’Z’值都可能影响到条件判断。while也是可综合语句,但相对for循环,while使用相对较少。在仿真程序中while使用相对更广泛些。

例1:利用while loop实现乘法器

module while_mult
#( parameter WIDTH = 4 )
(
    input       [WIDTH-1:0]   a, b,
    output reg  [WIDTH*2-1:0] p
);
 
integer  cnt;
 
reg [WIDTH*2-1:0] a_tmp;
 
always @(a or b) 
begin
    p = 0;
    a_tmp = a;
    cnt = 0;
 
    while(cnt != WIDTH) 
    begin
        if (b[ cnt ]) 
        begin
            p = p + a_tmp;    
        end
 
        cnt = cnt + 1;
        a_tmp = a_tmp << 1;
    end
end
 
endmodule

 

仿真激励文件:

`timescale 1 ns / 1 ps
 
module tb_test
(
 
);
 
reg   clk;
 
parameter PERIOD = 20;
 
initial 
begin
    clk = 1'b0;
    #(PERIOD/2);
 
    forever
        #(PERIOD/2) clk = ~clk;
end
 
reg [3:0] ta = 0;
reg [3:0] tb = 0;
 
wire [7:0] tp;
 
always@(posedge clk)  
begin
    ta <= ta + 1;
    if(ta == 15)
        tb <= tb + 1;
end
 
 
while_mult  #(.WIDTH(4)) 
mult_inst
(
    .a (ta),
    .b (tb),
    .p (tp)
);
 
 
endmodule

 

Modelsim仿真波形如图1:

图1

在激励文件中使用while loop

例2:利用while循环求整数平方表,在平方值大于等于1000时退出。

module while_test (); 
 
integer i;
 
reg [15:0] Data[63:0]; 
 
initial
begin
    i = 0;
    Data = i*i;
 
    while (Data < 1000)  
    begin
        $display("Time %4d: Data at Index %2d is %4d", $time, i, Data);
        i = i + 1;
        Data = i * i;
        #10;
    end
end
 
endmodule

 

仿真结果:

Modelsim $display函数显示计算值

modelsim 波形:

图2

while loop与for loop比较

  1. for loop 由三个表达式组成(赋初值,判断,修改变量值),而while loop 仅有一个表达式。
  2. 在有限和确定循环次数的程序设计中,使用for循环比较简洁,程序更容易控制。
  3. 在循环次数不能确定时,while循环往往比for循环更好用。
  4. 都是可综合的语句

例3:自然数累加

module acc
(
    input      [7:0]   a,
    output reg [15:0]  b
); 
 
integer i = 0;
 
always@(a)
begin
    i = 0;
    b = 0;
  
    while ((b < 10000) && (i < a))  
    begin
        i = i + 1;
        b = b + i;
    end
end
 
endmodule

 

testbench 仿真程序

module while_test (); 
parameter Period = 20;
 
reg clk;
 
initial 
begin
    clk = 0;
 
    forever 
        #(Period/2) clk = ~clk;
end
 
reg  rst;
reg  [7:0] a;
 
wire [15:0] b;
 
initial 
begin
    rst = 1'b1;
    #20
 
    rst = 0;
end
 
always@(posedge clk or posedge rst)
if(rst)
    a = 0;
else 
    a = a + 1;
 
acc  acc_inst
(
    .a (a),
    .b (b)
);
 
endmodule

 

图3

可见while loop不仅能在仿真程序中使用,在可综合的实体程序中应用也非常灵活,特别是在计数次数不完全确定的时候,非常有效。

 

对应视频:

Posted in FPGA, FPGA 教材教案, Verilog, Verilog

发表回复

相关链接