在Verilog 语法中forever语句可以用于产生无限循环的过程,但在组合逻辑电路中这种情况是不能综合的,即使在激励文件中也要加以特殊的限制,才能正常运行。但由于forever能提供无限循环,因此特别适合时序逻辑的设计。在仿真文件一般用于时钟产生。
由于forever是无限循环的,一般在激励文件中加延迟语句或使用时钟边沿来约束forever语句,防止零延迟死循环。
forever一般用在initial过程中。
例1:在testbench 文件中利用forever 产生时钟激励。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
`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 生成计数器
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
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 乘法器
仿真文件:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
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,则计算直接跳过。上例中的判断语句也可以用位与(&)逻辑替代。如:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
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下可以编译和仿真。
对应视频: