此示例中,非阻塞分配传播到连续分配。这可以导致任何执行范例。请详细说明这段代码 - 可能的错误,它如何被删除和良好的编码风格。
always @(posedge clk)
dff1 <= f(x);
assign fsm_in = f(dff1);
assign fsm_out = fsm_state;
always @(fsm_in)
fsm_state <= g(fsm_in);
答案 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_state
和f(dff1)
上的更改为update events
,并已添加到
调度程序的active event queue
。
立即评估两个NBAs的RHS,并且LHS更新是
已添加到nonblocking assignment update queue
。
模拟器现在看到一个包含4个事件的队列。它执行两个活动
事件首先以未定义的顺序排列,因此fsm_in
和fsm_out
获得新的
值。如果没有更多活动事件,则执行这两个事件
非锁定更新,以未定义的顺序排列,因此现在可以获得dff1
和fsm_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的观点,为了获得更好的可读代码,您应遵循本指南。