我对 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."
我可以做出的唯一推断是,行为 block 中的语句可能会暂停以执行其他行为 block (在同一时间步中处于事件状态),以便交错流程执行,尽管我不确定。
此外,我不明白“行为中没有时间控制结构的语句” block 不必作为一个事件执行”。LRM 说它不作为一个事件执行是什么意思?如果行为 block 包含所有时间控制语句会发生什么?
有人可以通过一些例子来解释一下吗?提前致谢。
最佳答案
模拟唯一保证的是always block 中的所有语句都将按顺序执行。比如说,如以下 block 所示:
always @(b,c,e,f) begin
a = b | c;
d = e & f;
g = a ^ d ^ x;
...
end
但是,模拟器可以决定连续执行前 2 个语句,但然后在最后一个语句之前停止执行此 block ,并让其他 block 继续执行。然后它会返回到最后一条语句。从这个意义上说,语句的执行顺序是不确定的。
你猜怎么着? x
的值在等待期间肯定会发生变化。在执行其他语句时,a
和 d
也可能会发生变化。因此,g
的结果可能是不确定的。良好的编程将有助于消除这种类型的不确定性:在敏感度列表中列出所有事件,不要多重驱动信号,......然后模拟器将尽力避免这些情况。
这种交错模拟的需要是允许模拟器出于性能原因进行更好的优化,并允许其他 block 在非常长和循环语句的情况下继续进行。
回答有关时间和事件控制的评论
在上面的 block 中,模拟器可以决定何时中断执行。从程序员的角度来看,它是不确定的。你不知道它什么时候会发生。唯一知道的是它会在同一个模拟(时间)滴答内发生。一个好的模拟器会尽力避免由此产生的任何副作用。
定时和延迟控制提供确定性停止。例如,
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
这里它将停止执行并等待posege clk
事件。
请注意,上述示例不可综合,仅应在行为代码(测试平台)中使用。对于综合,您必须坚持使用第一个示例,并确保您的代码是按照良好的 Verilog 编码实践编写的。
关于Verilog LRM 非确定性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60259922/