哪个区域是连续分配和原始实例化,#0 已调度

Gre*_*reg 4 verilog system-verilog

我找到的所有#0相关代码示例都与程序代码相关(IE代码内部begin- end)。连续赋值和原始实例化怎么样?IEEE 1364 和 IEEE 1800(分别为 Verilog 和 SystemVerilog)仅给出了我能找到的一行描述(在部分名称“分层事件队列”下引用 IEEE 1364 的所有版本):

显式零延迟 ( #0) 要求暂停进程并将其添加为当前时间的非活动事件,以便在当前时间的下一个模拟周期中恢复该进程。

我阅读了文档并与一些早在 IEEE Std 1364-1995 之前就已经使用 Verilog 的工程师进行了交谈。总之,非活动区域是无法将触发器与 Verilog 的不确定处理顺序同步的解决方案。后来Verilog创建了非阻塞赋值(<=)并解决了不确定顺序的同步问题。非活动区域保留在调度程序中,以免破坏遗留代码和一些模糊的角落情况。现代指南要求避免使用,#0因为它会产生竞争条件并可能会阻碍模拟性能。性能影响是不关心小型设计的。我运行了混合 RTL 到晶体管级模块的大型设计。因此,即使很小的性能提升也会节省时间,而且无需调试复杂的竞争条件也能节省时间。

#0我已经在大规模设计中运行了删除/添加 Verilog 原语的测试用例。一些模拟器有显着的变化,而其他模拟器则没有。很难判断谁在 LRM 后做得更好,或者谁拥有更智能的优化器。

添加预编译脚本来删除#0, 的硬编码形式非常简单。挑战在于参数化延迟。我真的需要创建生成块来避免非活动区域吗?感觉它可能会带来比解决更多的问题:

generate
  if ( RISE > 0 || FALL > 0)
    tranif1 #(RISE,FALL) ipassgate ( D, S, G );
  else
    tranif1              ipassgate ( D, S, G );
  if ( RISE > 0 || FALL > 0 || DECAY > 0)
    cmos #(RISE,FALL,DECAY) i1 ( out, in, NG, PG );
  else
    cmos                    i1 ( out, in, NG, PG );
  if (DELAY > 0)
    assign #(DELAY) io = drive ? data : 'z;
  else
    assign          io = drive ? data : 'z;
endgenerate
Run Code Online (Sandbox Code Playgroud)

Verilog 原语和连续赋值从一开始就伴随着 Verilog。我相信参数化延迟的存在时间比非活动区域更长。我还没有找到任何关于这些条件的建议或解释的文档。我本地的 Verilog/SystemVerilog 专家网络都不确定它应该在哪个区域运行。是否存在我们都忽略的细节,或者它是语言中的灰色区域?如果是灰色地带,如何确定是哪种植入方式?

接受的答案应包括对任何版本的 IEEE1364 或 IEEE1800 的引用。或者至少是一种进行概念验证测试的方法。

dav*_*_59 5

这是个简单的。1800-2012 LRM 的第 28.16节门和网络延迟以及1364-2005 LRM 的第7.14 节门和网络延迟都说

对于门和网络,当没有给出延迟规范时,默认延迟应为零。所以这意味着

gateName instanceName (pins);
Run Code Online (Sandbox Code Playgroud)

相当于写作

gateName #0 instanceName (pins);
Run Code Online (Sandbox Code Playgroud)

我不确定您引用的文本来自哪里,但1800-2012 LRM 的第4.4.2.3 节非活动事件区域说

如果事件正在活动区域​​集中执行,则显式#0 延迟控制要求挂起进程并将事件调度到当前时隙的非活动区域中,以便可以在下一个非活动到的时间段中恢复进程。主动迭代。

关键文本是delay control,它是一个程序结构。因此#0 作为非活动事件仅适用于程序语句。

程序的问题#0在于它们移动了竞争条件,而不是消除它们。有时您必须添加多个序列 #0 才能摆脱竞争条件,但您并不总是知道有多少个,因为另一段代码也在添加 #0。看看UVM代码就可以了;里面到处都是乱七八糟的#0,因为他们没有花时间正确编码。