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比较
- for loop 由三个表达式组成(赋初值,判断,修改变量值),而while loop 仅有一个表达式。
- 在有限和确定循环次数的程序设计中,使用for循环比较简洁,程序更容易控制。
- 在循环次数不能确定时,while循环往往比for循环更好用。
- 都是可综合的语句
例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不仅能在仿真程序中使用,在可综合的实体程序中应用也非常灵活,特别是在计数次数不完全确定的时候,非常有效。
对应视频: