Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
21345 Discussions

Unwanted inference of RAMs

Altera_Forum
Honored Contributor II
1,934 Views

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
0 Kudos
8 Replies
Altera_Forum
Honored Contributor II
812 Views

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?

0 Kudos
Altera_Forum
Honored Contributor II
812 Views

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

0 Kudos
Altera_Forum
Honored Contributor II
812 Views

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
0 Kudos
Altera_Forum
Honored Contributor II
812 Views

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

0 Kudos
Altera_Forum
Honored Contributor II
812 Views

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?

0 Kudos
Altera_Forum
Honored Contributor II
812 Views

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;
0 Kudos
Altera_Forum
Honored Contributor II
812 Views

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'.
0 Kudos
Altera_Forum
Honored Contributor II
812 Views

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
0 Kudos
Reply