哪个区域是连续分配和原始实例化#0预定

时间:2014-12-06 01:31:07

标签: verilog system-verilog

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

  

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

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

我已经在大规模设计中运行测试用例删除/添加#0到Verilog原语。有些模拟器有其他人没有的显着变化。在LRM之后很难分辨谁做得更好或者有更聪明的优化器。

添加per-compile脚本以删除#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

Verilog原语和连续分配从一开始就与Verilog一起使用。我认为参数化延迟比无效区域长。我还没有找到有关这些条件的推荐或解释的任何文档。我的Verilog / SystemVerilog大师的本地网络都不确定它应该在哪个区域运行。是否有一个我们都忽略的细节或者它是语言中的灰色区域?如果是灰色区域,我该如何确定植入方式?

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

1 个答案:

答案 0 :(得分:4)

这很简单。部分 28.16 1800-2012 LRM的门和净延迟以及1364-2005 LRM的 7.14门和净延迟部分都说

  

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

gateName instanceName (pins);

相当于写作

gateName #0 instanceName (pins);

我不确定您引用的文字来自哪里,但是1800-2012 LRM的 4.4.2.3非活动事件区部分说

  

如果在活动区域​​集中执行事件,则显式为#0   延迟控制要求暂停进程并执行事件   预定进入当前时隙的非活动区域   该过程可以在下一个非活动迭代中恢复。

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

程序#0的问题在于它们会移动竞争条件,但它们并没有消除它们。有时您必须添加多个序列#0以远离竞赛条件,但您并不总是知道多少,因为另一段代码也添加了#0。只需看看UVM代码;它充斥着凌乱的#0,因为他们没有花时间正确编码。