Verilog LRM 非确定性
Verilog LRM Nondeterminism
我对 Verilog LRM 中提到的 Verilog 调度语义中的不确定性存在一些疑问。以下是我无法理解的摘录:
"Another source of nondeterminism is that statements without time-control constructs in behavioral blocks do not have to be
executed as one event. Time control statements are the # expression
and @ expression constructs (see 9.7). At any time while evaluating a
behavioral statement, the simulator may suspend execution and place
the partially completed event as a pending active event on the event
queue. The effect of this is to allow the interleaving of process
execution. Note that the order of interleaved execution is
non-deterministic and not under control of the user."
我能做出的唯一推断是,行为块中的语句可能会暂停以执行其他行为块(在同一时间步中处于活动状态),以便交错执行进程,但我不确定。
此外,我不明白“行为中没有时间控制结构的陈述”这一行
块不必作为一个事件执行”。LRM 说它不作为一个事件执行是什么意思,如果行为块包含所有时间控制的语句会发生什么?
任何人都可以借助一些示例来解释这一点吗?提前致谢。
模拟唯一保证的是always块中的所有语句都将按顺序执行。说,如以下块:
always @(b,c,e,f) begin
a = b | c;
d = e & f;
g = a ^ d ^ x;
...
end
但是,模拟器可以决定连续执行前 2 个语句,然后在最后一个语句之前停止执行此块,让其他块继续执行。然后它将 return 到最后一个语句。从这个意义上说,您有一个不确定的语句执行顺序。
你猜怎么着?! x
的值在等待时肯定会发生变化。 a
和 d
也可能在执行其他语句时发生变化。因此,g
的结果可能是不确定的。良好的编程将有助于消除这种类型的不确定性:在敏感列表中列出所有事件,不要乘以驱动信号,......然后模拟器将尽最大努力避免这些情况。
这种交叉模拟的需要是为了让模拟器能够出于性能原因进行更好的优化,并允许其他块在非常长且循环的语句的情况下继续进行。
回答关于时间和事件控制的评论
在上面的块中,模拟器可以决定何时中断执行。从程序员的角度来看,它是不确定的。你不知道它什么时候会发生。唯一已知的是它会在同一个模拟(时间)滴答中发生。一个好的模拟器会尽力避免这种情况的任何副作用。
定时和延迟控制提供确定性停止。例如,
always @(b,c,e,f) begin
a = b | c;
d = e & f;
#1 g = a ^ d ^ x;
...
end
在上面带有 #1
的语句中,您实际上告诉模拟器停止执行语句并等待下一个时间点。
always @(b,c,e,f) begin
a = b | c;
d = e & f;
@(posedge clk)
g = a ^ d ^ x;
...
end
这里会停止执行,等待posedge clk
事件。
请注意,以上示例不可综合,只能用于行为代码(测试台)。对于综合,您必须坚持使用第一个示例,并确保您的代码是根据良好的 Verilog 编码实践编写的。
我对 Verilog LRM 中提到的 Verilog 调度语义中的不确定性存在一些疑问。以下是我无法理解的摘录:
"Another source of nondeterminism is that statements without time-control constructs in behavioral blocks do not have to be executed as one event. Time control statements are the # expression and @ expression constructs (see 9.7). At any time while evaluating a behavioral statement, the simulator may suspend execution and place the partially completed event as a pending active event on the event queue. The effect of this is to allow the interleaving of process execution. Note that the order of interleaved execution is non-deterministic and not under control of the user."
我能做出的唯一推断是,行为块中的语句可能会暂停以执行其他行为块(在同一时间步中处于活动状态),以便交错执行进程,但我不确定。
此外,我不明白“行为中没有时间控制结构的陈述”这一行 块不必作为一个事件执行”。LRM 说它不作为一个事件执行是什么意思,如果行为块包含所有时间控制的语句会发生什么?
任何人都可以借助一些示例来解释这一点吗?提前致谢。
模拟唯一保证的是always块中的所有语句都将按顺序执行。说,如以下块:
always @(b,c,e,f) begin
a = b | c;
d = e & f;
g = a ^ d ^ x;
...
end
但是,模拟器可以决定连续执行前 2 个语句,然后在最后一个语句之前停止执行此块,让其他块继续执行。然后它将 return 到最后一个语句。从这个意义上说,您有一个不确定的语句执行顺序。
你猜怎么着?! x
的值在等待时肯定会发生变化。 a
和 d
也可能在执行其他语句时发生变化。因此,g
的结果可能是不确定的。良好的编程将有助于消除这种类型的不确定性:在敏感列表中列出所有事件,不要乘以驱动信号,......然后模拟器将尽最大努力避免这些情况。
这种交叉模拟的需要是为了让模拟器能够出于性能原因进行更好的优化,并允许其他块在非常长且循环的语句的情况下继续进行。
回答关于时间和事件控制的评论
在上面的块中,模拟器可以决定何时中断执行。从程序员的角度来看,它是不确定的。你不知道它什么时候会发生。唯一已知的是它会在同一个模拟(时间)滴答中发生。一个好的模拟器会尽力避免这种情况的任何副作用。
定时和延迟控制提供确定性停止。例如,
always @(b,c,e,f) begin
a = b | c;
d = e & f;
#1 g = a ^ d ^ x;
...
end
在上面带有 #1
的语句中,您实际上告诉模拟器停止执行语句并等待下一个时间点。
always @(b,c,e,f) begin
a = b | c;
d = e & f;
@(posedge clk)
g = a ^ d ^ x;
...
end
这里会停止执行,等待posedge clk
事件。
请注意,以上示例不可综合,只能用于行为代码(测试台)。对于综合,您必须坚持使用第一个示例,并确保您的代码是根据良好的 Verilog 编码实践编写的。