Verilog:线值未更新

时间:2016-10-10 16:56:55

标签: verilog

我有以下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”,则会更新。

1 个答案:

答案 0 :(得分:2)

如果您将$display更改为$strobe,您将获得所需的结果。如果导线有机会在$display之前更新,那么它在模拟中确实是一种竞争条件。 $strobe将其输出延迟到导线结束后的时隙结束。电线的分配基本上是独立的过程。

另一种选择是对x使用非阻止分配。您应该始终对顺序逻辑中的变量使用非块分配,这些变量将被另一个进程读取。然后您的$ display始终打印上一个时钟周期的值。

最后,您可以使用另一个always块仅用于使用时钟下降沿的$display语句。