Is an inferred latch in Quartus II necessarily transparent

1k views Asked by At

I have a module that should represent a "distributed RAM", where multiple registers can be written in parallel and read through a single MUX. A minimal example would be:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity memory is 
    port
    (
        i_clk               : in  std_logic;
        i_reset_n           : in  std_logic;
        i_write_en          : in  std_logic;
        i_some_condition    : in  std_logic;
        i_other_condition   : in  std_logic;
        i_data              : in  std_logic_vector(15 downto 0);
        i_addr              : in  std_logic_vector(3 downto 0);
        o_data              : out std_logic_vector(15 downto 0)
    );
end memory;

architecture synthesis of memory is
    type RAM_T is array (15 downto 0) of std_logic_vector(15 downto 0);
    signal ram : RAM_T;
begin
    p: process(i_clk, i_reset_n)
    begin
        if i_reset_n = '0' then     
            ram <= (others => (others => '0'));
        elsif i_clk'event and i_clk = '1' then
            if i_write_en = '1' then
                if i_some_condition = '1' then
                    ram(1) <= i_data;
                end if;
                if i_other_condition = '1' then
                    ram(2) <= i_data;
                end if;
                -- and so on
            end if;            
        end if;
    end process p;

    o_data <= ram(to_integer(unsigned(i_addr)));
end;

Now Quartus II (14.1 Web Edition) warns that

Warning (10631): VHDL Process Statement warning at memory.vhd(21): inferring latch(es) for signal or variable "ram", which holds its previous value in one or more paths through the process

If I look at the RTL and technology map view, I see only edge triggered flip-flops. If "latch inference" here means "flip flop inference", then that is exactly what I intended. But how can I be sure that "latch" does not mean "transparent latch", i.e. a level sensitiv storage element? How could I distinguish this in the warning messages?

(This question is related, but asks why this is happening, I'm asking about the terminology and use of the word "latch".)

1

There are 1 answers

0
Renaud Pacalet On BEST ANSWER

If each bit of ram can be assigned in the:

elsif i_clk'event and i_clk = '1' then
  ...
end if;

part of your process, then your code is fine and it is Quartus that is wrong. No latches should be inferred here. Only DFFs with active low asynchronous reset.

But if some bits are never assigned (e.g. ram(0)), then, according the VHDL semantics, these bits are only assigned (and they are always assigned '0') when

  • there is an event on i_clk or i_reset_n and
  • i_reset_n is low.

In any other circumstance that resumes your process (event on i_clk or i_reset_n where i_reset_n is not low) they retain their value.

There are several ways to interpret and implement this behaviour (remember that VHDL simulation semantics is accurately defined by the Language Reference Manual but that the synthesis semantics is far less well defined and strongly depends on the particular synthesis tool you are using):

  • Some synthesizers could decide that these bits are constant '0' and shall be simplified out. This interpretation is not technically right because if i_reset_n is never asserted the bits will never be assigned and should retain their power-up value, which is not necessarily known. But with some FPGA targets it makes sense.

  • Some other synthesizers could decide that this is a typical latch behaviour with active low enable (i_reset_n) and a constant '0' input or something equivalent. They will probably also simplify by keeping only one single latch for all these bits.

I tried two versions of your code with Vivado 2014.4:

  • The one you posted (with the -- and so on comment); Vivado infers 32 DFFs and one single latch for the 224 remaining bits of ram.

  • A variant where the -- and so on comment is replaced by some code that can assign any of ram(15 downto 3) and ram(0). Vivado infers 256 DFFs and no latches.

Summary: check that each bit of ram can actually be assigned in the

elsif i_clk'event and i_clk = '1' then
  ...
end if;