系统 Verilog 的always_latch 与always_ff

cam*_*nso 3 register-transfer-level system-verilog vlsi

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

always_ff @ (posedge clk)
begin
    a <= b;
end
Run Code Online (Sandbox Code Playgroud)

而后者:

always_latch
begin
    a <= b;
end
Run Code Online (Sandbox Code Playgroud)

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

显然被always_latch认为代表锁存器,但是为什么要使用非阻塞赋值呢?

always_comb使用阻塞赋值不是更好吗?

Emm*_*man 5

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

例如:

always_ff @ (posedge clk or negedge rst) 
begin
  if (!rst)
    a <= '0;
end
Run Code Online (Sandbox Code Playgroud)

对于上述代码,设计者只想获得顺序逻辑而不是锁存器,但实际上会生成锁存器(任何静态工具都会生成警告消息,因为“将为逻辑推断锁存器”)

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

    always_latch
    begin
      if (rst)
        a <= b;
    end
Run Code Online (Sandbox Code Playgroud)

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

一般来说,最佳实践是对顺序逻辑使用非阻塞分配,对组合逻辑使用阻塞分配,这在 Verilog综合中的非阻塞分配、致命的编码风格第 5.0 节 Verilog 编码指南中有详细解释。

准则#2:在对锁存器建模时,使用非阻塞分配。