我学习 Verilog 有一段时间了,但在测试我创建的模块(它是一个 4 位计数器)时遇到了麻烦。
这是我的代码:
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
当我模拟这个时,除了 0 之外的所有值我都会在“out”上得到 X。如下图所示。
有趣的是,如果我将“$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
但是,如果我在外部模块中添加一个“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
结果:
第二个代码:
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
结果:
有一些问题。
您的“输出”始终显示为 X 或 0,因为您在测试平台模块中存在争用。
out
信号有多个驱动器:
wire
声明连续将其赋值为0。o
。当
o
为0时,与wire
值(0)匹配。这就是为什么您看到输出=0。当 o
是 0 以外的任何值(如 1、2 等)时,就会出现争用,并且您会看到输出=X。
要解决争用,请更改:
wire[3:0] out = 4'b0000;
至:
wire[3:0] out
使用
$monitor
并不是完成这项工作的最佳工具。它在每个时钟边沿都会发生变化,这通常没有多大意义。我建议删除 $monitor
行,并将此代码添加到测试台中:
always @(negedge clk) begin
$display("%t |output = %d", $time, out);
end
我从显示屏上删除了
clk
信号。此代码将在每个时钟周期显示一次 out
信号。我选择 negedge
以避免竞争条件。
输出:
130 |output = 1
230 |output = 2
330 |output = 3
430 |output = 4
530 |output = 5
630 |output = 6
730 |output = 7
830 |output = 8
930 |output = 9
1030 |output = 10
1130 |output = 11
1230 |output = 12
1330 |output = 13
1430 |output = 14
1530 |output = 15
1630 |output = 0
1730 |output = 1
虽然
$monitor
块中的 always
可以实现您想要的功能,但这不是一个好的做法。当您使用它时,您应该只在 $monitor
块中调用 initial
一次。