TransWikia.com

Warning: Inferring latch for variable 'w_addra_t' (in Verilog/SystemVerilog with FOR loop)

Stack Overflow Asked by France on February 24, 2021

I have an inferred latch problem after synthesis when I designed a simple dual port RAM block. Due to large code size, I have just embedded this always block code as follows:

integer i;
always_latch
begin
    for (i=0;i<NUM_RAMS;i=i+1) begin
        if (ena_t == 1) begin   
            w_addra_t[i] = w_addra[i];
        end
        else begin
            w_addra_t[bank_addra[i]] = w_addra[i];
        end
    end
end

My RAM block includes NUM_RAMS numbers of banks. The addresses of respective input data are stored in w_addra.

Data with given w_addra addresses are scrambled into w_addra_t depend on the values of respective bank_addra (depend on access pattern) when ena_t = 0.

I tried to replace for loop with if…else, switch…case, generate but the problem is same. With different always block in my code that the left-side is with only w_addra_t[i] in both if.else of ena_t, there is no error.

I would like to get your suggestion if you have any idea. I did look for similar issue but getting no results.

Thanks very much 🙂

2 Answers

My guess is the entries for bank_addra are not guaranteed to be unique. If two or more entries hold the same values then an index hole is created for w_addra_t; which will infer a latch.

Here are three possible solution:

  1. Functionally guaranteed that bank_addra entries will have unique values, then the synthesizer should not infer a latch. This can be challenging.

  2. Move the address variation from the LHS to the RHS so that each index of w_addra_t is guaranteed to be assigned a value. Ex change w_addra_t[bank_addra[i]] = w_addra[i]; to w_addra_t[i] = w_addra[bank_addra_lookup[i]];.

  3. Assign all entries of w_addra_t to a known value (constant, flip-flop, or deterministic value) before other logic. You can put this default assignment at the top of your always block (option 1 example) or above the logic where the latches were about to be inferred (option 2 example). This is the simplest solution to implement assuming it still satisfies relational requirements with your other code.

    // NOTE: SystemVerilog supports full array assignments (Verilog requires a for-loop)
    always_comb
    begin
      w_addra_t = '{default:'0}; // <-- default assignment : option 1
      if (ena_t == 1) begin
        w_addra_t = w_addra; 
      end
      else begin
        w_addra_t = w_addra_t_ff; // <-- default assignment : option 2
        for (i=0;i<NUM_RAMS;i=i+1) begin
          w_addra_t[bank_addra[i]] = w_addra[i];
        end
      end
    end
    always_ff @(posedge clk) begin
      w_addra_t_ff <= w_addra_t; // assuming w_addra_t should hold it current values
    end
    

TL;DR
always_latch is a SystemVerilog keyword to identify explicit latches. Some tools will auto-waive the warning when the keyword is used, but will throw an error/warning if the keyword is used and a latch is not detected.

If you know it should be combinational logic, then use the always_comb SystemVerilog keyword. With always_comb, if the synthesis detects a latch then it should report an error.

Read related question: What is inferred latch and how it is created when it is missing else statement in if condition. Can anybody explain briefly?

Correct answer by Greg on February 24, 2021

I don't know if it will solve your problem by changing to

int i
always_comb

instead. Perhaps the tool gets sad when you use a 4-state variable like integer?

Answered by akerlund on February 24, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP