【发布时间】:2012-06-27 06:21:54
【问题描述】:
我已阅读“Verilog 综合中的非阻塞分配,致命的编码风格!”通过克利福德卡明斯。他说以下代码(第 12 页,简化版)是教科书中经常使用的触发器的正确实现,即使不是任何人都应该使用的那种。 document 获得了最佳论文奖,所以我认为这个说法是正确的。
module ff (q, d, clk)
output q;
input d, clk;
reg q;
always @(posedge clk)
q = d;
endmodule
我想知道如果两个或多个这样的触发器串联连接,为什么它会继续正常工作。说
module two_ffs (q, d, clk)
input d, clk;
output q;
wire tmp;
ff firstff (tmp, d, clk);
ff secondff (q, tmp, clk);
endmodule
在我看来,tmp 的值可能在被 secondff 使用之前被更新,从而导致一个触发器而不是两个。有人可以告诉我标准的哪一部分说不能发生吗?非常感谢。
[并不是说我会考虑编写这样的代码,我只是想了解阻塞/非阻塞行为,即使在糟糕的编码风格导致含义不明显的情况下]
稍后添加:
我现在认为这篇论文不太可能是正确的。 1364-2201 Verilog 标准的第 5 节“调度语义”解释了会发生什么。特别是,第 68 页的第 5.6.6 节“端口连接”说单向端口就像连续分配一样。反过来,连续分配只是对所有内容都敏感的始终块。所以底线是,在我下面的示例中,ff 的两个实例化等效于具有多个 always 子句的模块,每个人都会同意它被破坏了。
在 Clive Cummings 回答问题后添加:
感谢 CC 指出,上述从标准第 5 节中摘录的陈述仅指更新事件的时间,并不意味着 e.g.一些连续的分配和总是阻塞。尽管如此,我认为他们解释了为什么某些模拟器(例如 Icarus Verilog)会在“触发器”中产生不同的模拟结果,其中包含阻塞和非阻塞分配。 [在一个更大的例子中,我得到了 2 个带有阻塞分配的明显 ffs,而正确的 5 个带有非阻塞分配。] 其他模拟器(例如具有默认选项的 Modelsim 或 Cver)似乎产生相同的结果,无论哪种形式使用赋值。
【问题讨论】:
-
你确定这是一个正确实现的例子吗?对我来说,这看起来像是一个错误设计的教科书示例。我认为你的理解是正确的。
-
我实际上在 this paper 的任何地方都看不到第一部分。我认为您可能误读了它,或者您能指出您从哪里获得该代码示例吗?我在第 12 页上没有看到它(我的版本可能与你不同)。
-
Tim:很抱歉没有提供链接(现在添加)。我指的是文档的 rev 1.3,而您找到的是 rev 1.2。再次抱歉。这两份文件都在第 9 节中。 “示例 13 显示了出现在大多数 Verilog 测试书中的触发器模型”。然后它的标题是“简单有缺陷......但它有效!”。
-
好的,我知道了。嗯,我想不出他为什么会这么说。无论如何:“我们鼓励读者在发现潜在错误或希望提出改进建议时向 Cliff Cummings(已编辑)发送电子邮件。” 也许您可以询问作者 :)
-
如果您可以访问大学图书馆,您可能需要考虑获得 IEEE 1364.1 Verilog 寄存器传输级综合标准。