For such a large memory model you might need to use a sparse array which
AFAIK is only supported in Verilog. If you have access to a dual language
license then it is very simple to add this.
you could do two things to reduce memory:
1. As suggested, use variables instead of signals as they use far less
memory.
2. The really elegant design is to use access types and dynamically
create memory as it is used. You could tie this in with an elegant
shared variable. Heres an example:
type mem_block;
type mem_block_ptr is access mem_block;
type mem_block is array(0 to 1023) of std_logic_vector(35 downto 0);
--this defines a small portion (10 bit addressable) of memory
type mem_storage_t is array(0 to 255) of mem_block_ptr;
--this is the entire memory array type
type memory_t is protected
impure function read( addr : std_logic_vector ) return
std_logic_vector;
procedure write(addr : std_logic_vector;
data : std_logic_vector);
end protected memory_t;
--this stores and gives access to an entire memory
--this memory is broken into rows of 1024 words.
type memory_t is protected body
variable mem_storage : mem_storage_t;
impure function read(addr : std_logic_vector ) return
std_logic_vector is
variable row : integer;
variable col : integer;
variable ret_slv : std_logic_vector(35 downto 0);
begin
row := to_integer(unsigned(addr(18 downto 10) ) );
col := to_integer(unsigned(addr(9 downto 0) ) );
--break down the address so you can index into the 2D array
if mem_storage(row) = null then
ret_slv := (others => 'X');
--no memory allocated here yet
else
ret_slv := mem_storage(row)(col);
--get the memory value
end if;
return ret_slv;
end function read;
procedure write(addr : std_logic_vector;
data : std_logic_vector ) is
variable row : integer;
variable col : integer;
begin
row := to_integer(unsigned(addr(18 downto 10) ) );
col := to_integer(unsigned(addr(9 downto 0) ) );
if mem_storage(row) = null then
mem_storage(row) := new mem_block;
--dynamically create some more ram
--initialise all of the memory that were just allocated
for i in 0 to 1023 loop
mem_storage(row)(i) := (others => 'X');
end loop;
end if;
mem_storage(row)(col) := data;
end procedure write;
end protected body memory_t;
--This is the varaible you actually use.
shared variable my_memory : memory_t;
With the above method, memory is not actually allocated until you
write to it, and should save you some if you only access a small part
of it.