在Verilog 语法中forever语句可以用于产生无限循环的过程,但在组合逻辑电路中这种情况是不能综合的,即使在激励文件中也要加以特殊的限制,才能正常运行。但由于forever能提供无限循环,因此特别适合时序逻辑的设计。在仿真文件一般用于时钟产生。
由于forever是无限循环的,一般在激励文件中加延迟语句或使用时钟边沿来约束forever语句,防止零延迟死循环。
forever一般用在initial过程中。
例1:在testbench 文件中利用forever 产生时钟激励。
`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; //注意这里一定要有延迟语句 #(PERIOD/2) ,否则会报语法错误。
end
endmodule
例2:在仿真文件中利用forever 生成计数器
module test_forever
(
input inclk,
output reg[3:0] count
);
initial
begin
count = 0;
forever
@(posedge inclk)
begin
if(count == 9)
count = 0;
else
count = count + 1;
end
end
endmodule
例3:利用forever生成4 X 4 乘法器
仿真文件:
module for_mult
(
input inclk,
input [3:0] a,b,
output reg [7:0] p
);
integer i;
initial
begin
p = 0;
forever
@(posedge inclk)
begin
p = 0; //注意这里P=0;是必须的,否则会有累加效果。
for(i = 0; i < 4; i = i + 1)
begin
if(b[ i ]) p = p + (a << i);
end
end
end
endmodule
上例中就是利用时钟上升沿,对被乘数左移对应的位数,if(b[i]) 不满足,也就是b[i]==0,则计算直接跳过。上例中的判断语句也可以用位与(&)逻辑替代。如:
initial
begin
p = 0;
forever
@(posedge inclk)
begin
p = 0; //注意这里P=0;是必须的,否则会有累加效果。
for(i = 0; i < 4; i = i + 1)
begin
// if(b)
p = p + ( (a<<i) & {i{b}} );
end
end
end
在Vivado下的仿真波形如图1:

图1
关于在Quartus II prime lite版本下使用forever的限制:
- Quartus II prime lite对于循环迭代次数不能超过250次,因此在该版本下forever在实体设计文件不能用。在编译时会报如下错误。

图2
- 图2指出在没有明确限定仿真次数的循环中,Quartus II 在综合时报错,这样会阻止modelsim 启动。但在Modelsim 或Vivado下可以编译和仿真。
对应视频: