Modelsim仿真中Buffer的异常行为及原因咨询
Verilog Buffer模块仿真中buffer2输出差异的原因分析
我在Modelsim仿真Verilog编写的Buffer模块时,发现两种不同控制ena信号的方式下,buffer2的输出结果存在明显差异。以下是模块代码、测试平台代码,以及具体的原因分析:
1. Buffer模块代码
module buffer( input wire clk, input wire ena, output wire buffer, output wire buffer2 ); reg buffer_reg = 1'b0; reg buffer_next = 1'b0; reg buffer2_reg = 1'b0; assign buffer = buffer_reg; assign buffer2 = buffer2_reg; always @(*) begin buffer_next = ena; end always @(posedge clk) begin buffer_reg <= buffer_next; buffer2_reg <= ena; end endmodule
2. 测试平台代码
`timescale 1ns / 1ns module buffer_tb(); localparam CLK_CYCLE = 8; reg clk; reg ena; wire buffer; wire buffer2; buffer dut( .clk(clk), .ena(ena), .buffer(buffer), .buffer2(buffer2) ); // Clock generation initial begin clk = 1'b0; end always #(CLK_CYCLE/2) clk = ~clk; // Test sequence initial begin // Initialize signals ena = 0; // change ena values based on the posedge clk @(posedge clk) ena = 1; @(posedge clk) ena = 0; repeat(5) @(posedge clk); @(posedge clk) ena = 1; @(posedge clk) ena = 0; repeat(2) #CLK_CYCLE; // change ena values based on the CLK_CYCLE #(CLK_CYCLE) ena = 1; #CLK_CYCLE ena = 0; repeat(5) #CLK_CYCLE; #CLK_CYCLE ena = 1; #CLK_CYCLE ena = 0; // Allow simulation to run for a while #50 $stop; // Stop simulation end endmodule
3. 差异原因解析
核心问题出在Verilog仿真的事件调度顺序,以及两种控制方式下ena信号变化与时钟上升沿的时间关系:
用@(posedge clk)控制ena的情况
当用@(posedge clk)触发ena赋值时,ena的更新发生在时钟上升沿的同一仿真时间步,但晚于时钟事件的触发:
- 时钟上升沿先触发
always @(posedge clk)块执行; - 此时
ena还没完成更新,buffer2_reg采样到的是ena变化前的旧值; - 时钟事件处理完毕后,
ena的赋值才生效;
所以buffer2的变化会比ena晚一个时钟周期,和buffer的行为一致(buffer是先通过组合逻辑锁存ena,再同步到寄存器)。
用#CLK_CYCLE控制ena的情况
CLK_CYCLE设为8ns,时钟周期正好是8ns(高低电平各4ns)。用#CLK_CYCLE延时赋值ena时:
- 假设初始时钟上升沿在0ns,下一个上升沿在8ns;
#8ns的延时会让ena的变化恰好发生在时钟上升沿的同一时刻;- 仿真事件调度中,
ena的赋值事件优先级高于时钟上升沿的触发事件,会先执行; - 因此
always @(posedge clk)块执行时,会采样到已经更新后的ena新值;
最终buffer2会和ena的变化同步,没有延迟,这就和第一种控制方式的表现产生了差异。
关键总结
两种控制方式的本质区别是ena变化与时钟上升沿的相对时序:
@(posedge clk)赋值:ena在时钟沿之后更新,寄存器采样旧值;#CLK_CYCLE赋值:ena在时钟沿时刻先更新,寄存器采样新值;
这种差异是仿真事件调度规则导致的,实际硬件中如果ena是同步产生的,会和第一种情况一致;第二种情况属于仿真中人为制造的“零时间差”边界场景,硬件里几乎不会出现(信号变化不可能完全和时钟沿精准对齐)。
内容的提问来源于stack exchange,提问作者daniel danino
相关产品推荐
相关产品推荐

