Forum Discussion

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

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

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;

2 Replies

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

    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;
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.