You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:29:46