Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
13 years ago

Inferring FIFO in VHDL

I'm trying to write a synchronous FIFO in VHDL, and I get the following message :

Info (276007): RAM logic "sRAM" is uninferred due to asynchronous read logic

I already asked google, and did some modification to my code, but without success.

Here is the code :

architecture arch of fifo is
    type ram_t is array (0 to depth) of std_logic_vector(data_in'range);
    signal sRAM : ram_t;
    signal sRead_ptr : unsigned(unsigned_num_bits(depth-1)-1 downto 0) := (others => '0');
    signal sWrite_ptr : unsigned(unsigned_num_bits(depth-1)-1 downto 0) := (others => '0');
begin
    pRam : process(clk) is
    begin
        if rising_edge(clk) and EN = '1'then
            if W = '1' then
                sRam(to_integer(sWrite_ptr)) <= data_in;
                if sWrite_ptr > to_unsigned(depth, sWrite_ptr'length) then
                    sWrite_ptr <= (others => '0');
                else
                    sWrite_ptr <= sWrite_ptr + 1;
                end if;
            end if;
            
            if R = '1' then
                if sRead_ptr > to_unsigned(depth, sRead_ptr'length) then
                    sRead_ptr <= (others => '0');
                else
                    sRead_ptr <= sRead_ptr + 1;
                end if;
            end if;
        end if;
    end process pRam;
    
    data_out <= sRam(to_integer(sRead_ptr));
end architecture arch;
How can I modify my code for quartus to infer my RAM ?

4 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    In fact, in the first design I tried, the reading was in the process and it didn't infer. When I googled it I found that it has to be outside (http://www.alteraforum.com/forum/showthread.php?t=28242).

    But now I found a solution. I first put an inferable ram block (thanks to the previous thread), and then I just rewrite it.

    architecture arch of fifo is
        signal sRead_ptr : unsigned(unsigned_num_bits(depth-1)-1 downto 0) := (others => '0');
        signal sWrite_ptr : unsigned(unsigned_num_bits(depth-1)-1 downto 0) := (others => '0');
        
        type ram_t is array (0 to depth-1) of std_logic_vector(data_in'range);
        signal sRam : ram_t;
        signal sAddr_read : std_logic_vector(sRead_ptr'range);
    begin
        pRam : process(clk) is
        begin
            if rising_edge(clk) then
                if W = '1' then
                    sRam(to_integer(sWrite_ptr)) <= data_in;
                end if;
                sAddr_read <= std_logic_vector(sRead_ptr);
            end if;
        end process pRam;
        data_out <= sRam(to_integer(unsigned(sAddr_read)));
        pRead_ptr : process(clk) is
        begin
            if rising_edge(clk) and EN = '1'then
                if R = '1' then
                    if sRead_ptr > to_unsigned(depth-2, sRead_ptr'length) then
                        sRead_ptr <= (others => '0');
                    else
                        sRead_ptr <= sRead_ptr + 1;
                    end if;
                end if;
            end if;
        end process pRead_ptr;
        
        pWrite_ptr : process(clk) is
        begin
            if rising_edge(clk) and EN = '1'then
                if W = '1' then
                    if sWrite_ptr > to_unsigned(depth-2, sWrite_ptr'length) then
                        sWrite_ptr <= (others => '0');
                    else
                        sWrite_ptr <= sWrite_ptr + 1;
                    end if;
                end if;
            end if;
        end process pWrite_ptr;
    end architecture arch;
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    No clue, actually. That looks inferrable to me.

    My suggestion: start with the basic template from the HDL coding guidelines, and work from there.

    Which FPGA are you using? There are some differences between M4K and M9K blocks, though they shouldn't affect you here.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The problem is i think in using the readptr as asynchronous address AND doing calculations on it. If you put the read statement inside the process it willl probalby infer (but with slightly different behaviour of course). Worth a try?

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Review the paragraph inferring memory functions from hdl code in the Altera software handbook or the Quartus editor VHDL templates. They are expecting the read action data_out <= sram(to_integer(sread_ptr)); inside a clock edge sensitive block.