我试图了解Verilog调度算法的工作原理。以下示例输出0, xxxx
而不是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),因为它适用于上面的示例?
谢谢!
答案 0 :(得分:2)
您正确地说非阻塞作业(NBA)和连续作业(CA)就像两步过程一样,因为它们是。问题是您所说的“下一个时间步长”不是时间上的进步;它是while()循环的迭代,没有提前的时间。这通常称为 delta-step 。
使用NBA时,LHS被安排为NBA更新事件,但此后不久,$display
是要执行的下一个活动事件。在NBA更新事件有机会执行之前,它会打印y的值。一旦引入延迟,NBA就有机会在执行下一个赛事时间之前执行。
使用CA时,您将创建一个单独的进程,该进程会在RHS更改时随时激活,并在同一活动区域中分配给LHS。 initial
和CA是两个独立的过程,并且活动区域中语句之间的顺序是不确定的。因此,是否看到y
更新值的旧y
的旧未初始化值是竞争条件。您将看到模拟器之间的差异,具体取决于它们如何优化此代码。