0

我试图了解 Verilog 调度算法是如何工作的。下面的示例输出0, xxxxand not 1010。我不清楚为什么。如果我之前确实放了一个延迟$display,它会输出1010

module test;
  reg [3:0] t_var;
  initial begin
    t_var <= 4'b1010;
    $display("%0t, %b", $realtime, t_var);
  end
endmodule

0, xxxx对于以下示例,相同的输出 , :

module test;
  reg [3:0] t_var;
  wire [3:0] y;
  assign y = ~t_var;
  initial begin
    t_var = 4'b1010;
    $display("%0t, %b, %b", $realtime, t_var, y);
  end
endmodule

根据示例,似乎非阻塞分配连续分配都是两步过程,其中 RHS 在当前时间步进行评估,LHS 计划在下一个时间步(如果未指定延迟)或在稍后的时间步长(如果指定了延迟)。

有人可以确认并向我解释以下算法的逐步流程(来自 Clifford Cummings),因为它适用于上面的示例吗?

谢谢!

在此处输入图像描述

4

1 回答 1

2

您说非阻塞分配(NBA)和连续分配(CA)就像两步过程是正确的,因为它们是。问题是您所说的“下一个时间步”不是时间提前;它是 while() 循环的迭代,没有提前时间。这通常被称为delta-step

使用 NBA 时,LHS 被安排为 NBA 更新事件,但紧随其后的$display是下一个要执行的活动事件。它会在 NBA 更新事件有机会执行之前打印 y 的值。一旦您引入延迟,NBA 就有机会在进入下一个赛事时间之前执行。

使用 CA 时,您正在创建一个单独的进程,该进程会在 RHS 更改时激活,它会分配给同一活动区域中的 LHS。和 CA 是两个独立的initial过程,活动区域中语句之间的顺序是不确定的。因此,您是否看到y更新值的旧未初始化值y是竞争条件。您将看到模拟器之间的差异,具体取决于它们如何优化此代码。

于 2019-10-19T23:19:37.977 回答