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 🙂
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:
Functionally guaranteed that bank_addra
entries will have unique values, then the synthesizer should not infer a latch. This can be challenging.
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]];
.
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
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP