Testbench仿真无法脱离初始状态问题排查求助
嘿,我立刻就发现了你代码里的核心问题——你的顶层main模块里藏着一个会直接掐断仿真的initial块!
问题根源:顶层模块的
$finish语句 你的main模块末尾有这么一段代码:
initial begin $display("end of main module"); $finish; end
这个initial块会在仿真启动的瞬间(t=0)就执行$finish命令,直接终止整个仿真流程——不管你的Testbench里写了多少时延、多少激励,根本没机会运行!这就是为什么你调整任何时延参数,仿真都在t=0就结束的原因。
排查思路&修复步骤
我给你整理了一步步的解决和优化方案:
第一步:移除顶层模块的
$finish
顶层设计模块只需要负责实现硬件功能,仿真的启动、激励、终止逻辑完全交给Testbench处理。直接把main模块里的这个initial块删掉就行。第二步:优化DFF的复位逻辑(可选但推荐)
看你的DFF代码,复位条件是if (reset == 0),也就是低电平复位,但Testbench里初始把reset设为1'b1,逻辑是对的,但建议把复位条件的优先级明确出来,代码可读性更高:always @ (reset or posedge clk) begin if (reset == 1'b1) begin // 高电平复位,优先级最高 q<=1'b0; q_not <= 1'b1; end else begin // 复位释放后,时钟上升沿采样输入d q<=d; q_not <= ~d; end end第三步:确认Testbench的仿真控制
你的Testbench最后已经有#50000ns $finish;来控制仿真结束时机,这就足够了,不需要顶层模块再插手。另外可以把timescale行的冗余注释去掉,改成timescale 1ns / 100ps更规范。
修复后的顶层模块代码
module d_ff(d, clk, reset, q, q_not); input d, clk, reset; output q, q_not; reg q, q_not; always @ (reset or posedge clk) begin if (reset == 1'b1) begin // 高电平复位 q<=1'b0; q_not <= 1'b1; end else begin // 时钟上升沿更新输出 q<=d; q_not <= ~d; end end endmodule module main(d, clk, reset, q2, q2_not, q1_not); input d, clk, reset; output q2, q2_not, q1_not; wire d2; d_ff dup(.d(d), .clk(clk), .reset(reset), .q(d2), .q_not(q1_not)); d_ff dup2(.d(d2), .clk(clk), .reset(reset), .q(q2), .q_not(q2_not)); endmodule
总结
这个问题属于典型的仿真控制逻辑放错位置,硬件设计模块和Testbench的职责要清晰分开。删掉顶层的$finish后,你再跑仿真就能正常看到两级DFF级联的移位效果了。
内容的提问来源于stack exchange,提问作者Yaswanth
相关产品推荐
相关产品推荐

