[reprint] FPGA Express – How do I avoid latch inferences?

[reprint] FPGA Express – How do I avoid latch inferences?

Description

General Description:

FPGA Express will synthesize HDL code into a variety of logic elements, including flip-flops, combinatorial gates, 3-state buffers, and latches. For Xilinx devices, internal latches are not an efficient use of resources because they will be built using combinatorial logic (if the particular family targeted does not have internal latches); hence it is in your best interest to avoid latch inference whenever possible.

Latches are created when processes are left with certain conditions undefined; this leaves FPGA Express no choice but to infer a latch to “hold” the current value of the process, in case the unspecified condition appears. This can happen within CASE statements.

Solution

Include all possible cases in the case statement.

Verilog:

always @ (SEL or DIN1 or DIN2)

begin

case (SEL)

2’b00 : DOUT <= DIN1 + DIN2;

2’b01 : DOUT <= DIN1 – DIN2;

2’b10 : DOUT <= DIN1;

endcase

end

VHDL:

process (SEL, DIN1, DIN2)

begin

case SEL is

when “00” => DOUT <= DIN1 + DIN2;

when “01” => DOUT <= DIN1 – DIN2;

when “10” => DOUT <= DIN1;

end case;

end process;

These two examples will create latches because there is no provision for the case when SEL = “11”. To eliminate the latches, add another entry to address this possibility.

Verilog:

2’b11 : DOUT <= DIN2;

VHDL:

when “11” => DOUT <= DIN2;

Using the DEFAULT clause (Verilog) or WHEN OTHERS (VHDL) will always work, but this may create extraneous logic. This always the safest methodology, but it may create a larger and slower design, as any unknown state will have logic to bring it to a known state.

Assign to all of the same outputs in each case.

Verilog:

always @ (SEL or DIN1 or DIN2)

begin

case (SEL)

2’b00 : DOUT <= DIN1 + DIN2;

2’b01 : DOUT <= DIN1 – DIN2;

2’b10 : DOUT <= DIN1;

2’b11 :

begin

DOUT <= DIN2;

TEMP <= DIN1;

end

endcase

end

VHDL:

process (SEL, DIN1, DIN2)

begin

case SEL is

when “00” => DOUT <= DIN1 + DIN2;

when “01” => DOUT <= DIN1 – DIN2;

when “10” => DOUT <= DIN1;

when “11” =>

DOUT <= DIN2;

TEMP <= DIN1;

end case;

end process;

These examples will infer latches because the “11” case assigns two outputs, while the others only assign one. Looking at this case from TEMP’s point of view, only one of four possible cases are specified, so it is incomplete.

Avoid this situation by assigning values to the exact same list of outputs for each case.


补充一个例子

以下代码的else指定了if的所有可能性,因此不生成latch

module verilog_test
(
    input   [3:0] data,
    input   [1:0] valid,
    input   flag,
    output reg valid_data
);

always @ (*)
    begin
        if(valid==2'd0) valid_data = data[3]; else
        if(valid==2'd1) valid_data = data[2]; else
        if(valid==2'd2) valid_data = data[1]; else valid_data = 0;
    end


endmodule
没有生成latch
module verilog_test
(
    input   [3:0] data,
    input   [1:0] valid,
    input   flag,
    output reg valid_data
);

always @ (*)
    begin
        if(valid==2'd0) valid_data = data[3]; 
        if(valid==2'd1) valid_data = data[2]; 
        if(valid==2'd2) valid_data = data[1]; 
    end


endmodule

以下代码缺少一种if的可能性,因此综合会生成latch以锁存。

生成了latch ( LDCE )

RobertLiang

A post-graduate in USTC.

You must be logged in to post a comment