系统 Verilog always_latch 与 always_ff

System Verilog always_latch vs. always_ff

我对语句 always_ffalways_latch 的用法感到困惑。 前者将用作:

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

而后者:

always_latch
begin
    a <= b;
end

第一个仅由时钟的上升沿激活,并与非阻塞分配相结合,产生一个 FF。

always_latch明明被认为是latch,那为什么要用非阻塞赋值呢?

使用带有阻塞分配的 always_comb 不是更好吗?

来自 IEEE 标准 1800-2012,“9.2.2.3 锁存逻辑 always_latch 程序”部分:

The always_latch construct is identical to the always_comb construct except that software tools should perform additional checks and warn if the behavior in an always_latch construct does not represent latched logic, whereas in an always_comb construct, tools should check and warn if the behavior does not represent combinational logic.

Std 中的代码示例显示 always_latch 使用非阻塞赋值。

通过使用 always_latch 或 always_ff 设计人员意图分别推断锁存器或时序逻辑,但如果逻辑不正确,软件工具可以警告设计人员预期的硬件逻辑是没有正确推断。

例如:

always_ff @ (posedge clk or negedge rst) 
begin
  if (!rst)
    a <= '0;
end

对于上面的代码,设计者只打算得到一个时序逻辑,而不是一个锁存器,但实际上会生成一个锁存器(任何静态工具都会生成一个警告消息,如"Latch will be inferred for the logic")

类似地,对于下面的代码,设计者的意图是推断硬件锁存器,以便工具(更好地理解您的逻辑)并且不会报告它。

    always_latch
    begin
      if (rst)
        a <= b;
    end

锁存器是一种时序逻辑,它在时钟电平而不是时钟边沿上工作。

一般来说,最佳做法是对顺序逻辑使用非阻塞赋值,对组合逻辑使用阻塞赋值,这在第 5.0 节中有详细说明 Nonblocking Assignments in Verilog Synthesis, Coding Styles That Kill!

的 Verilog 编码指南

Guideline #2: When modeling latches, use nonblocking assignments.