Verilog LRM 非确定性

标签 verilog hdl

我对 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 的值在等待期间肯定会发生变化。在执行其他语句时,ad 也可能会发生变化。因此,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/

相关文章:

compiler-errors - 针对别名声明的错误10500

verilog - 为什么在此 Verilog HDL 代码中使用两个触发器而不是一个?

Verilog 中的 ASCII 到整数转换

vhdl - 估计 VHDL 实现所需的面积

c++ - SystemC 错误,使用 Visual C++ 2008

hardware - 编译器的bug,还是对SystemVerilog的误解?未声明的端口类型在模拟中工作

arrays - 在 Verilog 中移动 2D 数组

regex - 使用正则表达式进行 Verilog 端口映射

verilog - 将 Verilog 中的二进制文件数据读入二维数组

verilog - always_comb 和 always@(*) 之间的行为差​​异