always_ff、always_comb、always_latch和always的区别是什么?

40

我对这四个术语感到非常困惑:always_ffalways_combalways_latchalways。它们可以如何使用,以及用于什么目的?

1个回答

49

always 是Verilog中的一种主要进程类型,另一种是 initial,该进程在模拟开始时运行一次。

always_ff @(posedge clk)
代表触发器(ff),该进程在时钟的每个上升沿上被触发(执行)。这替代了 always @(posedge clk)

always_ff @(posedge clk) begin
  a <= b;
end

always_latch:用于表示锁存器。

使用方法如下:

always_latch begin
  if (enable) begin
     a_latch <= something;
  end
  //No else clause so a_latch's value
  //is not always defined, so it holds its value
end

这取代了:

always @* begin
  if (enable) begin
     a_latch = something;
  end
  //No else clause so a_latch's value
  //is not always defined, so it holds its value
end

always_comb:
用于组合逻辑,是 always @* 的替代品,当您不想要锁存器时可以使用。现在我们可以区分设计意图,知道什么时候需要和不需要锁存器。

SystemVerilog 命名为 always_ffalways_latchalways_comb,它们在被触发时有更严格的标准,这意味着 RTL 到门级(后合成)不匹配的可能性降低了。这也意味着它们与其 always @ 对应部分并非完全等效,可能会改变一些模拟行为。


15
always_combalways @*并不等同,你不应该再使用always @*。最大的原因是当逻辑中涉及常量或参数时,always @*无法工作。它们不会生成事件来触发块的执行。而使用always_comb可以保证在时间0执行。 - dave_59
1
感谢@dave_59,我试图在最后一段中涵盖确切的相等性。它们是SystemVerilog,IP通常设计为向后兼容Verilog,因此将继续使用always @*。考虑到有多少初学者发布手动灵敏度列表的问题,我认为在always_comb成为常态之前我们还有很长的路要走。 - Morgan
2
是的,想一想人们从使用注释指示符(如//synthesis translate on)转向使用 ifdef SYNTHESIS需要多长时间。自从25年前将ifdef`添加到Verilog以来,已经过去了这么久。 - dave_59
4
IEEE标准使用always_latch与非阻塞赋值。您在回复中使用阻塞式赋值的特定原因是什么? - Ari
1
@ Ari 我认为 always_latchalways @* 的扩展。<= 模拟了锁存器的行为,当锁存器打开时是透明的,所以我认为 = 更加合适。我之前没有注意到他们在 LRM 中使用非阻塞 (<=)。 - Morgan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接