Verilog-非阻塞语句混乱

时间:2018-08-30 15:04:10

标签: verilog

我一直认为,对于非阻塞语句,它们都在always语句的末尾并行发生。

但是考虑一下我发现的这个例子:

https://www.nandland.com/articles/blocking-nonblocking-verilog.html

always @(posedge i_clock)
begin
  r_Test_1 <= 1'b1;
  r_Test_2 <= r_Test_1;
  r_Test_3 <= r_Test_2;
end

它说:“上面的Verilog代码中的always块使用Nonblocking分配,这意味着值1从r_Test_1传播到r_Test_3需要3个时钟周期。”

那没有任何意义。如果该值传播需要3个时钟周期,那么是否肯定也是串行发生而不是并行发生?

1 个答案:

答案 0 :(得分:0)

非阻塞语句在每次Always块运行时都并行运行。但是,每个分配在分配时都使用右侧的先前值。如果我们模拟设计,则可以看到以下行为:

enter image description here

最初,所有信号的值为0,但是在第一个上升沿r_Test_1的值为1,而其他两个寄存器保持为0。这是因为r_Test_2为在时钟边沿之前 分配了r_Test_1的值,而在上升沿之前r_Test_1为0。

类似的行为发生在第二个上升沿,这次是r_Test_2r_Test_3r_Test_2在第二个上升沿变为1,因为这次r_Test_1在时钟沿之前为1,但是由于r_Test_2在该沿之前仍为0,因此{{1} }保持为0。

我们将此与代码的行为进行对比:

r_Test_3

enter image description here

因为我在这里使用了阻塞分配,所以每个寄存器都立即分配了值,而不是将分配推迟到Always块的末尾。因此,在分配always @(posedge i_clock) begin r_Test_1 = 1'b1; r_Test_2 = r_Test_1; r_Test_3 = r_Test_2; end 时,r_Test_2的值已经为1,并且对于r_Test_1r_Test_3同样,因此所有3个信号的值都为1在第一个周期。

现在我正在使用阻止分配,顺序变得很重要。因此,如果我重新排列代码,使其看起来像这样:

r_Test_2

然后我从第二次仿真中得到了不同的结果: enter image description here

挑战:为什么会这样?

完整的测试平台:

always @(posedge i_clock)
begin
    r_Test_1 = 1'b1;
    r_Test_3 = r_Test_2;
    r_Test_2 = r_Test_1;
end