Simulación de RAM grande

3

Quiero probar un núcleo de video IP que lee un bloque de memoria y lo escribe de nuevo. El núcleo de IP está utilizando el VFBC. Mi idea para las pruebas fue escribir un núcleo que se pareciera al VFBC, pero que solo use una memoria RAM de 32Meg simple como back-end.

Se asigna de esta manera:

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 se está estrellando al afirmar que necesita más de 2 gigas de ram, y questasim está asignando 12gig en el proceso de compilación para la simulación.

Nota: No quiero sintetizar esto. Es solo para simulación!

Entonces, la pregunta es: ¿cómo puedo simular una memoria RAM de este tipo en VHDL?

    
pregunta Karsten Becker

2 respuestas

5

Si la memoria que está simulando puede caber en el ram de la estación de trabajo, usar un almacenamiento de tamaño fijo es lo más fácil de usar. Pero, como ha visto, las señales son mucho más caras en comparación con las variables. Esta diferencia está relacionada con el modelo de simulación de eventos discretos en el que se basa VHDL. Una asignación de señal programa una transacción en un punto dado en el tiempo, pero una asignación de variable es estrictamente una declaración secuencial que se ejecuta en tiempo de simulación de cero. La diferencia se puede ver en el uso de la memoria de los dos modelos diferentes. Los resultados se obtienen ejecutando el siguiente código de ejemplo en Riviera PRO.

Asignación de memoria cuando se usa una señal para el almacenamiento de datos:

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

Asignación de memoria cuando se utiliza una variable para el almacenamiento de datos:

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

Código de ejemplo

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;
    
respondido por el trondd
1

¿Necesita utilizar toda esa memoria?

¿Podrías escapar simulando una memoria dispersa ...

Uso de alguna estructura de datos como un diccionario (tengo un árbol AVL - en mi 'hecho en el trabajo' me temo :() puedes almacenar solo los valores que se han escrito y las direcciones en las que se escribieron. Si tu simulación solo toca una pequeña fracción de la matriz, puedes guardar una mucho!

Los modelos de memoria de Micron solían hacer este tipo de cosas, usarían new para asignar una fila a la vez a medida que se accedía. A ver si puedes desenterrar sus viejos modelos DRAM síncronos de velocidad de datos únicos, fueron bastante instructivos, según recuerdo.

    
respondido por el Martin Thompson

Lea otras preguntas en las etiquetas