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

Verilog 4位计数器Testbench监控内部模块寄存器输出异常求助

4位计数器仿真异常问题排查

问题背景

刚接触Verilog,测试自行编写的4位计数器模块时遇到异常:仿真时外部测试模块中的out信号除初始0外全显示X;但把$monitor移到计数器内部模块后,能打印出正确值,可外部波形里out还是X。

初始测试代码

计数器模块

module Counter4bit(input clk,rst,load, input[3:0] parallel_input,
 output reg[3:0] o);

    always @(posedge clk, posedge rst) begin
        if(rst) begin
            o <= 4'b0000;
        end
        else if(load)   o <= parallel_input;
        else begin
            o <= o + 4'b0001;
        end
    end

endmodule

测试模块

module CT4TB;

    reg[3:0] Pinp = 4'b0000;
    wire[3:0] out = 4'b0000;
    reg rst=0;
    reg ld=0;
    reg clk=0;

    Counter4bit ct(clk,rst,ld,Pinp,out);

    initial begin
        #15 rst = 1;
        #15 rst = 0;
        $monitor("%t |clk = %d |output = %d",$time,clk,out);

        repeat(35) #50 clk = ~clk;

    end

endmodule

修改后的代码(仅移动$monitor位置)

计数器模块

module Counter4bit(input clk,rst,load, input[3:0] parallel_input,
 output reg[3:0] o);

    always @(posedge clk, posedge rst) begin
        if(rst) begin
            o <= 4'b0000;
        end
        else if(load)   o <= parallel_input;
        else begin
            o <= o + 4'b0001;
        end
        $monitor("%t |clk = %d |output = %d",$time,clk,o);
    end

endmodule

测试模块

module CT4TB;

    reg[3:0] Pinp = 4'b0000;
    wire[3:0] out = 4'b0000;
    reg rst=0;
    reg ld=0;
    reg clk=0;

    Counter4bit ct(clk,rst,ld,Pinp,out);

    initial begin
        #15 rst = 1;
        #15 rst = 0;
        

        repeat(35) #50 clk = ~clk;

    end
endmodule

仿真现象

  • 初始代码:$monitor打印out除初始0外全为X,波形中out信号全程显示未知态(X)
  • 修改后代码:计数器内部的$monitor能打印出正确的递增计数值,但外部测试模块的out信号波形仍显示未知态(X)

问题根源

核心错误出在测试模块中对out的声明:wire[3:0] out = 4'b0000;。

在Verilog中,wire类型的信号不能被连续赋值初始化,这种写法属于语法错误。部分仿真器可能不会直接报错,但会导致信号驱动冲突:你试图给wire信号赋一个固定值0,同时计数器模块的输出o也在驱动这个wire,两者冲突后,仿真器就会将信号置为X(未知态)。

把$monitor移到内部模块后,打印的是计数器内部的o信号,这个信号没有被外部的错误赋值干扰,所以能显示正确值;但外部的out因为驱动冲突,依然是X。

解决方案

修改测试模块中out的声明,去掉错误的初始化赋值,只保留wire类型声明:

module CT4TB;

    reg[3:0] Pinp = 4'b0000;
    wire[3:0] out;  // 去掉=4'b0000的错误初始化
    reg rst=0;
    reg ld=0;
    reg clk=0;

    Counter4bit ct(clk,rst,ld,Pinp,out);

    initial begin
        #15 rst = 1;
        #15 rst = 0;
        $monitor("%t |clk = %d |output = %d",$time,clk,out);

        repeat(35) #50 clk = ~clk;

    end

endmodule

这样修改后,out仅由计数器模块的输出驱动,没有冲突,仿真时就能正常显示计数数值,不管是$monitor打印还是波形查看都能得到正确结果。


内容的提问来源于stack exchange,提问作者Amirreza Nadi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 11:53:22