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
相关产品推荐
相关产品推荐

