SystemVerilog:always_ff,always_comb,always_latch

一、简介

Verilog中只有一个通用的always过程块,SystemVerilog中追加了3个具有更明确目的专用always块。

  • always_ff
  • always_comb
  • always_latch

always_ff, always_comb, always_latch分别是用于寄存器(flip-flop,代表时序逻辑sequential logic), 组合逻辑以及锁存器的建模。
事实上,always_ff, always_comb, always_latch能实现的,always都能够实现。

新增的always语句具有如下的特点:

  1. always_comb用于可综合组合逻辑的建模,不需要明确地定义敏感列表。
    always_combalways @(*)在表达组合逻辑时几乎是等价的。
  2. always_ff用于可综合时序逻辑的建模,必须带由posedge或者negedge所定义的敏感列表。

可综合设计规则

  1. 使用always_comb进行组合逻辑建模,always_comb中使用阻塞赋值;
  2. 使用always_ff进行时序逻辑建模,always_ff中只能使用非阻塞赋值。只有非阻塞赋值才能正确描述时钟沿触发的同步逻辑行为。
  3. 同步设计中一般不允许使用latch,因此不要使用always_latch;
  4. 通用的always只用于testbench的设计;
  5. 在always_comb/always_ff/always_latch不允许使用时间和事件控制语句;
  6. 绝对不允许在同一个过程块内混合使用阻塞(=)和非阻塞(<=)两种赋值。
  7. 组合逻辑和时序逻辑尽量不要在一个过程块中描述。

二、示例

时序逻辑

always_ff @(posedge clk_in or negedge rst_n_in) begin
    if( !rst_n_in ) begin
        d <= 'b0;
    end else begin
        d <= (a & b) | c;
    end
end

组合逻辑

always_comb begin
    case(curr_state)
    s0: begin
        out1 = 1'b1;
        out2 = 1'b0;
    end
    s1: begin
        out1 = in1;   
        out2 = 1'b1;
    end
    s2: begin
        out1 = 1'b1;
        out2 = in2;
    end
    default: begin
        out1 = 1'b0;   
        out2 = 1'b0;
    end
    endcase
end