Question: I want to test a video IP core that reads a block of memory and writes to it again. The IP core is using the VFBC. My idea for testing was to write a core that looks like the VFBC, but just uses a simple 32Meg RAM as back-end.

It is allocated like this:

```
memory_size : NATURAL := ((2 * 2048) * 2048)
type memory_array is array (0 to (memory_size - 1)) of std_logic_vector(31 downto 0);
signal memory : memory_array;

```

ISim is crashing claiming that it needs more than 2 gig of ram, and questasim is allocating 12gig in the process of compilation for simulation.

**Note: I don't want to synthesize this. It is for simulation only!**

So the question is: how can I simulate such an RAM efficiently in VHDL?

Answer: 
If the memory you are simulating can fit into the ram of the workstation then using a fixed-size storage is the easiest to use. But as you have seen, signals are much more expensive compared to variables. This difference is related to the *discrete event simulation* model that VHDL is based on. A signal assignment schedules a transaction at a given point in time, but a variable assignment is strictly a sequential statement that execute in zero simulation time. The difference can be seen in the memory usage of the two different models. The results are obtained by running the example code below in Riviera PRO.

Memory allocation when using a signal for data storage:

```
Allocation: Simulator allocated 891567 kB (elbread=1023 elab2=890389 kernel=154 sdf=0)

```

Memory allocation when using a variable for data storage:

```
 Allocation: Simulator allocated 39599 kB (elbread=1023 elab2=38421 kernel=154 sdf=0)

```

Example code
------------

```
library ieee;
use ieee.std_logic_1164.all;
use std.env;

entity memtest is
end;

architecture sim of memtest is
    signal clk : std_logic := '0';

    signal we : std_logic;
    signal writedata, q : integer;
    signal addr : natural;

    -- Uncomment or comment to switch between variable or signal for memory storage.
    --signal mem : integer_vector(0 to 2 * 2048**2-1);

begin

    clk <= not clk after 10 ns;

    -----------------------------------
    stimulus :
    -----------------------------------    
        process 
    begin
        for n in 0 to 100 loop
            wait until falling_edge(clk);
            we <= '1' ; 
            writedata <= n;
            addr <= n;
        end loop;
        env.stop;
    end process;

    -----------------------------------    
    memory :
    -----------------------------------
    process ( clk )
            -- Uncomment or comment to switch between variable or signal for memory storage.
        variable mem : integer_vector(0 to 2 * 2048**2-1);
    begin
        if rising_edge(clk) then
            q <= mem(addr);

            if we = '1' then
                                -- Remember to modify assignment operator when switching data storage.
                mem(addr) := writedata;
            end if;
        end if;
    end process;
end;

```
Are you needing to use all of that memory?

Could you get away with simulating a sparse memory...

Using some data structure like a dictionary (I have an [AVL tree](http://en.wikipedia.org/wiki/AVL_tree) - in my 'made-at-work' library, so i can't share it I'm afraid :( ) you can store just the values which have been written and the addresses they were written to. If your simulation only touches a small fraction of the array, you can save a lot!

Micron's memory models used to do this kind of thing, they would use `new` to allocate a row at a time as they were accessed. See if you can dig up their old single-data-rate synchronous DRAM models, they were quite instructive as I recall.