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语句具有如下的特点:
- always_comb用于可综合组合逻辑的建模,不需要明确地定义敏感列表。
always_comb
与always @(*)
在表达组合逻辑时几乎是等价的。 - always_ff用于可综合时序逻辑的建模,必须带由
posedge
或者negedge
所定义的敏感列表。
可综合设计规则
- 使用always_comb进行组合逻辑建模,always_comb中使用阻塞赋值;
- 使用always_ff进行时序逻辑建模,always_ff中只能使用非阻塞赋值。只有非阻塞赋值才能正确描述时钟沿触发的同步逻辑行为。
- 同步设计中一般不允许使用latch,因此不要使用always_latch;
- 通用的always只用于testbench的设计;
- 在always_comb/always_ff/always_latch不允许使用时间和事件控制语句;
- 绝对不允许在同一个过程块内混合使用阻塞(=)和非阻塞(<=)两种赋值。
- 组合逻辑和时序逻辑尽量不要在一个过程块中描述。
二、示例
时序逻辑
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