了解 Verilog 分层事件队列
Understanding the Verilog Stratified Event Queue
我正在尝试了解 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),因为它适用于上述示例吗?
谢谢!
你说非阻塞赋值 (NBA) 和连续赋值 (CA) 就像两步过程一样,这是正确的,因为它们是。问题是你所说的 "the next time-step" 不是时间的提前;它是 while() 循环的迭代,没有提前时间。这通常称为 delta-step。
使用 NBA 时,LHS 被安排为 NBA 更新事件,但在那之后,$display
是下一个要执行的活动事件。它在 NBA 更新事件有机会执行之前打印 y 的值。一旦你引入延迟,NBA 就有机会在推进到下一个事件时间之前执行。
使用 CA 时,您正在创建一个单独的进程,该进程在 RHS 更改时激活,它在同一活动区域中对 LHS 进行分配。 initial
和 CA 是两个独立的进程,活动区域中语句之间的顺序是不确定的。因此,无论您看到 y
的旧未初始化值还是 y
的更新值,都是竞争条件。您将看到模拟器之间的差异,具体取决于它们如何优化此代码。
我正在尝试了解 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),因为它适用于上述示例吗?
谢谢!
你说非阻塞赋值 (NBA) 和连续赋值 (CA) 就像两步过程一样,这是正确的,因为它们是。问题是你所说的 "the next time-step" 不是时间的提前;它是 while() 循环的迭代,没有提前时间。这通常称为 delta-step。
使用 NBA 时,LHS 被安排为 NBA 更新事件,但在那之后,$display
是下一个要执行的活动事件。它在 NBA 更新事件有机会执行之前打印 y 的值。一旦你引入延迟,NBA 就有机会在推进到下一个事件时间之前执行。
使用 CA 时,您正在创建一个单独的进程,该进程在 RHS 更改时激活,它在同一活动区域中对 LHS 进行分配。 initial
和 CA 是两个独立的进程,活动区域中语句之间的顺序是不确定的。因此,无论您看到 y
的旧未初始化值还是 y
的更新值,都是竞争条件。您将看到模拟器之间的差异,具体取决于它们如何优化此代码。