非阻止作业的微妙之处

时间:2013-08-16 00:25:46

标签: verilog nonblocking

此示例中,非阻塞分配传播到连续分配。这可以导致任何执行范例。请详细说明这段代码 - 可能的错误,它如何被删除和良好的编码风格。

  always @(posedge clk)
        dff1 <= f(x);

    assign fsm_in = f(dff1);
    assign fsm_out = fsm_state;

    always @(fsm_in)
        fsm_state <= g(fsm_in);

3 个答案:

答案 0 :(得分:2)

首先:最佳做法是对寄存器进行无阻塞分配,对组合逻辑进行阻塞分配。我建议看看这篇论文:Clifford E. Cummings撰写的Nonblocking Assignments in Verilog Synthesis, Coding, Styles That Kill!。 §11涵盖组合逻辑。本文的指南适用于IEEE Std 1364-1995,现在仍然完全适用; Verilog和SystemVerilog。

那就是说,给定的代码将在功能上起作用,因为你有一个简单的条件。它也可能正确合成(基于Cliff的页面)。

如果使用较差的编码风格和更复杂的设计,则可能会遇到问题。有关示例,请参阅Cliff's paper。糟糕的编码风格也使其他人更难阅读 [1] 。您可以为教授和同事提供可读代码。一个理想的linting工具也会标记它。最好让自己养成编写高质量代码的习惯。

1:如果您真的不希望其他人阅读您的代码,请参阅IEEE std 1800-2012§34

答案 1 :(得分:2)

您的代码很好,但我同意Greg的观点,即在组合过程中使用阻止分配是更好的风格。

关于你的意见:

简单来说,调度程序包含5个队列(SV有17个),但是 你只对其中两个感兴趣:active event queue和。{ nonblocking assignment update queue。在给定的模拟周期中, 模拟器处理活动事件队列,然后处理非阻塞更新 队列。通常,这将创建更多事件,并且模拟器循环 以预先确定的顺序在队列周围,直到没有更多事件发生 这个模拟时间。然后模拟器继续前进到下一次 事件已安排(例如,在下一个时钟边缘)。

假设“同时发生4件事情”:fsm_state发生了变化 是f(x)的变化,你的NBA任务都被执行了。据,直到...为止 就模拟器而言,这4个语句都是在同一个语句中执行的 模拟周期,但是以不确定的顺序。 “立刻”的定义是 相当复杂,但假设它们都是由于时钟边缘而发生的, 在语句之间没有排序依赖关系。通常是模拟器 单线程,所以它实际上会执行不同的4个语句 真正的次,但它知道所有4个预计会发生在同一时间 模拟时间。

fsm_statef(dff1)上的更改为update events,并已添加到 调度程序的active event queue

立即评估两个NBAs的RHS,并且LHS更新是 已添加到nonblocking assignment update queue

模拟器现在看到一个包含4个事件的队列。它执行两个活动 事件首先以未定义的顺序排列,因此fsm_infsm_out获得新的 值。如果没有更多活动事件,则执行这两个事件 非锁定更新,以未定义的顺序排列,因此现在可以获得dff1fsm_state 他们的新价值观。

在你的情况下,模拟周期没有完成,因为改变了 fsm_in也是一个更新事件,这会触发评估/执行 始终阻止对fsm_in敏感的块。这是evaluation event。 sim执行always块,立即读取新值 fsm_in,并将fsm_state的更新添加到NBA作业更新中 队列。如果没有活动事件,则分配将被执行,并且 fsm_state获得了它的新价值。

这种情况一直持续到这个模拟周期中没有更多的事件发生了 如果将来安排某些事情,那么模拟器会提前计时。

你可以从Verilog LRM的第5部分得到所有这些,但它没有 很有道理。所有语言都是在标准化的最后阶段嫁接的 过程和使用(VHDL)术语,未在LRM中的其他地方使用。它 也是为了匹配Verilog-XL的行为而添加的 专门记录XL特有的非确定性,所以不要指望 太多了。我直到1992年才将NBAs添加到语言中 认为。不要打扰SV LRM;还有更多的队列,而且 普通文本已经改变,只是增加了另一层次的混乱。

Cliff Cummings在他的一篇论文中对其进行了简化描述 非阻塞任务),但要仔细阅读。我很确定 活动事件队列的描述不正确(用于RHS评估 NBA的)。如果他是对的,那就会引起各种各样的问题;他大概是 从早期版本的LRM获得了描述。

要做的最好的事情是在VHDL delta周期中查找任何文本。这些 很容易理解,它们起作用,而且一直都有,而且它们都有 多年来悄悄进入Verilog。细节是不同的,但你没有 我们需要知道的比你在delta周期中发现的更多。

答案 2 :(得分:0)

我建议您始终使用非阻塞时钟驱动信号并阻止组合逻辑(如果是RTL)。我已经使用了很多合成器,如果你不像我推荐的那样使用这些作业,它们会显示错误。还有其他linting工具也会显示错误。 我同意Greg的观点,为了获得更好的可读代码,您应遵循本指南。