Forum Discussion

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

Unwanted inference of RAMs

I am working with an SOPC system design that includes a custom UART component. In the VHDL design of this component, I specify a memory using:

type fifo_type is array (0 to NUMWORDS-1) of std_logic_vector(0 to FIFO_WIDTH-1);

signal fifo_sig : fifo_type;

Up until know, it is OK that the tool places this into an M4K RAM block. However, at this point I need to implment this as registers instead of RAM - the RAM is needed for other memories. Within the context of my SOPC design, I have tried both project settings and attributes to try and prevent the RAM from being used. But the system always grabs this and puts into a RAM.

This does not work in my SOPC system:

attribute ramstyle : string;

attribute ramstyle of fifo_sig : signal is "logic";

So in contrast, if I create a small project that consists only of my VHDL, I can use both the attributes and the global quartus settings to prevent a RAM from being used.

WHY is this happening?

Thanks,

Kevin

8 Replies

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

    Apparently, fifo_sig isn't the correct instance name or you're not in the correct hierarchy scope. Did you try to adjust global RAM inference synthesis rules?

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

    Try sticking an async reset on fifo_sig - that behaviour is not allowed in RAMs so it will have to place registers.

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

    I have tried to the global synthesis rules. If my UART is its own project, the global settings work, as do the attribute statements. When the UART is taken as a component within the SOPC, these things no longer work.

    within the VHDL that instantiates the memory, fifo_sig is the correct name.

    here is an exerpt from the fitter report (reformatted) when the RAM is extracted:

    |UART_TOP:UART_TOP_0| --> |fifo_sync:FIFO_SYNC_RX| --> |altsyncram:fifo_sig_rtl_0| --> |altsyncram_iog1:auto_generated| --> M4Ks = 1
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    quite confused now. added the async reset and get the same results. M4K.

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

    Post up your code. Adding an async reset that is tied low might have been removed during synthesis. Could you tie it to a real reset?

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

    the code. comments are in italian, sorry. i am working with the design of my colleagues from Italy.

    LIBRARY ieee;

    USE ieee.std_logic_1164.ALL;

    USE ieee.std_logic_signed.ALL;

    USE ieee.numeric_std.all;

    entity fifo_sync is

    generic(

    NUMBIT : integer; -- numero di bit dimensione

    FIFO_FULL_PROTECTION : integer; -- margine in scrittura

    FIFO_WIDTH : integer -- profondità dati

    );

    port(

    clk : in std_logic;

    reset : in std_logic;

    data : in std_logic_vector (0 to FIFO_WIDTH-1);

    rdreq : in std_logic;

    wrreq : in std_logic;

    q : out std_logic_vector(0 to FIFO_WIDTH-1);

    empty : out std_logic;

    full : out std_logic;

    flush : in std_logic);

    end fifo_sync;

    architecture Behavioral of fifo_sync is

    -- Impiegati per realizzare una FIFO di dimensione di potenza di 2

    type lut_type is array (integer range 0 to 8) of integer range 0 to 256;

    constant lut_square : lut_type :=(0, 2, 4, 8, 16, 32, 64, 128, 256);

    -- Numero words FIFO

    constant NUMWORDS : integer := lut_square(NUMBIT);

    -- Dati accessibili con controllo FIFO FULL PROTECTION

    constant numwords_ffp : integer := (NUMWORDS - FIFO_FULL_PROTECTION)-1;

    type fifo_type is array (0 to NUMWORDS-1) of std_logic_vector(0 to FIFO_WIDTH-1);

    signal fifo_sig : fifo_type;

    -- Indirizzi per lettura e scrittura

    signal addr_wr : std_logic_vector(0 to NUMBIT-1);

    signal addr_rd : std_logic_vector(0 to NUMBIT-1);

    -- Numero di dati presenti in FIFO

    signal data_count : std_logic_vector(0 to NUMBIT-1);

    -- Segnali FIFO FULL e EMPTY

    signal full_sig : std_logic;

    signal empty_sig : std_logic;

    -- Abilitazione scrittura e lettura

    signal wr_en : std_logic;

    signal rd_en : std_logic;

    -- knw 2/14/11

    attribute ramstyle : string;

    attribute ramstyle of fifo_sig : signal is "logic";

    begin

    full <= full_sig;

    empty <= empty_sig;

    -- Abilito la scrittura solo se la fifo non è piena

    wr_en <= wrreq and (not full_sig);

    -- Abilito la lettura solo se la fifo non è vuota

    rd_en <= rdreq and (not empty_sig);

    -- Gestione scrittura e lettura FIFO

    PROC_FIFO: process ( clk, reset )

    begin

    if (reset = '1') then

    for x in 0 to (NUMWORDS-1) loop

    fifo_sig(x) <= (others => '0');

    end loop;

    elsif (clk'event and clk = '1')then

    if(wr_en = '1')then

    fifo_sig(TO_INTEGER(unsigned(addr_wr)))<= data;

    end if;

    q <= fifo_sig(TO_INTEGER(unsigned(addr_rd)));

    end if;

    end process PROC_FIFO;

    -- Calcolo degli indirizzi per lettura, scrittura e numero di dati in FIFO

    -- ad un accesso in scrittura incremento il conteggio dei dati presenti "data_count"

    -- e incremento l'indirizzo per scrivere nella prossima locazione, in lettura

    -- decremento il conteggio dei dati e incremento l'indirizzo per leggere la locazione

    -- successiva

    PROC_CNT_DATA: process ( clk, reset )

    begin

    if (reset = '1')then

    data_count <= (others => '0');

    addr_rd <= (others => '0');

    addr_wr <= (others => '0');

    elsif (clk'event and clk = '1')then

    if (flush = '1') then

    data_count <= (others => '0');

    addr_rd <= (others => '0');

    addr_wr <= (others => '0');

    elsif ((wr_en = '1') and (rd_en = '1')) then

    data_count <= data_count; -- incremento e decremento -> conteggio invariato

    addr_rd <= addr_rd + 1;

    addr_wr <= addr_wr + 1;

    elsif (rd_en = '1') then

    data_count <= data_count - 1;

    addr_rd <= addr_rd + 1;

    elsif (wr_en = '1') then -- empty

    data_count <= data_count + 1;

    addr_wr <= addr_wr + 1;

    end if;

    end if;

    end process PROC_CNT_DATA;

    -- Gestione dei segnali full e empty

    process ( clk, reset )

    begin

    if (reset = '1')then

    full_sig <= '0';

    empty_sig <= '1';

    elsif (clk'event and clk = '1')then

    if(TO_INTEGER(unsigned(data_count)) = 0)then

    empty_sig <= '1';

    full_sig <= '0';

    elsif(TO_INTEGER(unsigned(data_count)) >= numwords_ffp )then

    full_sig <= '1';

    empty_sig <= '0';

    else

    full_sig <= '0';

    empty_sig <= '0';

    end if;

    end if;

    end process;

    end Behavioral;
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Can you use code tags next time you post code please :)

    I compiled it with and without a reset. I get an M4K (I used a Cyclone 1) with no reset and logic when there is a reset. When I made a reset signal stuck at '0', it also placed an M4K, so I can only assume your reset is set to '0'.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thakns for the feedback. I mentioned above that using this code alone as it's own project, I can get logic or M4K as I prefer. But this logic is part of a component created for SOPC builder. Regardless of what I do to the logic at this level, I compile my desing (build SOPC system first) and get the M4K. This is why I am stumped.

    Apologies, had not posted code before.

    Thanks,

    Kevin