我有以下MWE:
module test(
input wire clock,
input wire start
);
reg [7:0] x = 8'b10101010;
reg processing = 0;
wire [7:0] x_wire0 = x;
wire [7:0] x_wire1 = {4'hf, x};
wire [11:0] x_wire2 = {4'hf, x};
always @(posedge clock) begin
if (start & ~processing) begin
x = 8'h0f;
processing = 1;
end
$display("---> x=%h x_wire0=%h x_wire1=%h x_wire2=%h",
x, x_wire0, x_wire1, x_wire2);
end
endmodule
使用testbench
module test_test();
reg clock = 0;
reg start = 0;
test test(
.clock(clock),
.start(start)
);
always #5 clock = ~clock;
initial begin
$monitor("%b %b", clock, start);
#20 start = 1;
#20 start = 0;
#200 $finish;
end
endmodule
使用Icarus Verilog 0.9.7的给出了输出
0 0
---> x=aa x_wire0=aa x_wire1=aa x_wire2=faa
1 0
0 0
---> x=aa x_wire0=aa x_wire1=aa x_wire2=faa
1 0
0 1
---> x=0f x_wire0=0f x_wire1=aa x_wire2=f0f
1 1
0 1
---> x=0f x_wire0=0f x_wire1=0f x_wire2=f0f
1 1
0 0
...
我想知道为什么x_wire1在下一个时钟滴答之前不会更新,以及是否有任何(拇指)规则来避免这种情况。 如果我在display命令之前使用“#0”,则会更新。
答案 0 :(得分:2)
如果您将$display
更改为$strobe
,您将获得所需的结果。如果导线有机会在$display
之前更新,那么它在模拟中确实是一种竞争条件。 $strobe
将其输出延迟到导线结束后的时隙结束。电线的分配基本上是独立的过程。
另一种选择是对x
使用非阻止分配。您应该始终对顺序逻辑中的变量使用非块分配,这些变量将被另一个进程读取。然后您的$ display始终打印上一个时钟周期的值。
最后,您可以使用另一个always
块仅用于使用时钟下降沿的$display
语句。