默认情况下,一切都在 Active 区域中运行。例外情况是:
- #0 个阻止分配位于非活动区域
- 非阻塞分配位于 NBA 地区
- $monitor、$strobe 和 PLI/VPI 位于 Monitor 区域
我们可以通过在任何现有模拟器中运行以下命令来证明@ 发生在活动区域:
int x;
initial begin
$monitor("From $monitor: x is %0d",x);
#0 x = 5; // inactive event
x = 3; // active event (after inactive event)
#1; // go to next time stamp
fork
#0 x = 7; // inactive event
x = 11; // active event
join
#0 fork // inactive region
#0 x = 2; // inactive event
x = 5; // active event
x <= 4; // NBA event
join
end
// active event region
always @* $display("From @* $display: x is %0d",x);
输出:
从@* $display: x 是 3
从 $monitor: x 是 3
从@* $display: x 是 11
从@* $display: x 是 7
从@* $display: x 是 5
从@* $display: x 是 2
从@* $display: x 是 4
从 $monitor: x 是 4
显示报告的次数多于监控次数。这排除了 @ 在 Monitor 或 Future 区域中的累积。显示正在报告每个事件区域。每个事件区域只能循环回活动区域。因此,@ 必须在 Active 区域中处理,并且每个更新变量 x 的区域都会触发新的 Active 区域事件。
这也可以通过查看 Verilog 的历史来证明。不幸的是,这没有很好的记录。我是通过 80 年代末 90 年代初使用/开发 verilog 的人了解到的。总的解释是:在 IEEE Std 1364-1995、@ 早于这两个区域之前,将 Inactive 和 NBA 区域添加到 Verilog。添加这些区域是为了向非确定性模拟器添加确定性。
always @(posedge clk) pipe0 = in;
always @(posedge clk) pipe1 = pipe0; // unpredictable, non-deterministic order
always @(posedge clk) #0 pipe0 = in; // Inactive region added some determinism
always @(posedge clk) pipe1 = pipe0;
always @(posedge clk) #0 pipe0 = in; // But was fragile
always @(posedge clk) #0 pipe1 = pipe0; // unpredictable order again
always @(posedge clk) pipe2 = pipe1;
always @(posedge clk) pipe0 <= in;
always @(posedge clk) pipe1 <= pipe0;
always @(posedge clk) pipe2 <= pipe1; // NBA region fixed it
...
always @(posedge clk) pipeN <= pipeM; // and made it scalable
根据 cmets 的反馈进行澄清
事件被
激活,而不是
移动。激活的 NBA 事件进入
if (E is an update event) 的真实条件,修改对象并安排新的
评估事件(在下次进入
Active 区域时处理)。一旦所有的
activated 事件都完成了,调度就会回到while 循环的顶部。
NBA 区域仅分配值,评估实际上是在较早的
Active 区域阶段完成的。
从您的示例中:
module TEST;
reg test = 0;
reg test2 = 0;
reg clk = 0;
initial begin
clk <= 1;
test <= 1;
end
always @(posedge clk) begin
test2 <= test;
end
endmodule
while 循环的每次迭代都将如下所示:
迭代:0
Active: 非活动:
NBA:
clk = clk$tmp
测试 = 测试$tmp
迭代:1
活动:
非活动:
NBA: Active: 非活动:
NBA:
迭代:3
Active: 非活动:
NBA:
测试2 = 测试2$tmp
迭代:4
活动:
非活动:
NBA: 下一个模拟周期