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

How to write a 88bit*4096 ram in VHDL?

Altera_Forum
Honored Contributor II
1,105 Views

Hi everyone, 

 

I am trying to write a 88bit*4096 RAM all in VHDL. I defined an array as RAM and use package to initialize it.  

 

But there is an error when I compile it saying that *Error: Cannot convert all sets of registers into RAM megafunctions when creating nodes. The resulting number of registers remaining in design exceeds the number of registers in the device* 

 

Can anybody shed some light on how to fix the error? Thanks. Following is 

my VHDL code. 

 

/* RAM */ 

library IEEE; 

use IEEE.STD_LOGIC_1164.ALL; 

use IEEE.STD_LOGIC_UNSIGNED.ALL; 

library work; 

use work.pack.all; 

entity RAM_test is 

port( 

clk : in std_logic;  

addr :in std_logic_vector(11 downto 0);  

cs : in std_logic;  

oe : in std_logic;  

data_i: in std_logic_vector(87 downto 0);  

data_o: out std_logic_vector(87 downto 0)  

); 

end RAM_test; 

architecture Behavioral of RAM_test is 

signal ram1 : RamType := MEM_INIT; 

begin 

process(clk) 

begin 

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

if(cs = '0') then  

if(oe = '0') then 

data_o <= ram1(conv_integer(addr)); 

else 

ram1(conv_integer(addr)) <= data_i; 

end if; 

end if; 

end if; 

end process; 

end Behavioral; 

 

/*Package*/ 

library IEEE; 

use IEEE.STD_LOGIC_1164.ALL; 

package pack is 

type RamType is array (0 to 4095) of std_logic_vector(87 downto 0); 

constant MEM_INIT : RamType := ( 

/*content of RAM*/ 

); 

end package pack;
0 Kudos
2 Replies
Altera_Forum
Honored Contributor II
404 Views

The original warning message is preceeded by this important line  

 

--- Quote Start ---  

Info: RAM logic "ram1" is uninferred due to asynchronous read logic 

--- Quote End ---  

In my opinion, the analysis is incorrect. Quartus apparently doesn't like the nested if control signals. Try with this logically equivalent construct: 

if cs = '0' and oe = '0' then data_o <= ram1(conv_integer(addr)); end if; if cs = '0' and oe = '1' then ram1(conv_integer(addr)) <= data_i; end if;
0 Kudos
Altera_Forum
Honored Contributor II
404 Views

Quartus can be a bit tempremental in infering rams if you dont follow their coding guidlines properly. I have previously had problems (pre Q9, seems ok now) with some rams not being infered if there is no write-enable (some would work, some would not), and the response I got back was that "there is no write enable, so you're not following the coding guidelines). 

 

With the OP could, I agree it should work, but I get the feeling it has built an asynchronous read mux in-front of the output register because of the if/else condition. It is always safer to completly separate your read and write logic, the way FvM suggested.
0 Kudos
Reply