Simulation von großem Arbeitsspeicher

Ich möchte einen Video-IP-Core testen, der einen Speicherblock liest und erneut darauf schreibt. Der IP-Core verwendet den VFBC. Meine Idee zum Testen war, einen Kern zu schreiben, der wie der VFBC aussieht, aber nur einen einfachen 32-Meg-RAM als Back-End verwendet.

Es wird so zugeteilt:

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 stürzt ab und behauptet, dass es mehr als 2 GB RAM benötigt, und Questasim weist 12 GB im Kompilierungsprozess für die Simulation zu.

Hinweis: Ich möchte dies nicht synthetisieren. Es dient nur der Simulation!

Die Frage ist also: Wie kann ich einen solchen RAM effizient in VHDL simulieren?

Verwenden Sie anstelle von std_logic_vector einen viel einfacheren Datentyp für das Speicherarray, z. B. Integer
Danke, das hat es deutlich verbessert. Die Ladezeiten sind nicht akzeptabel. Ich frage mich immer noch, warum es 2 GB RAM benötigt. Jedenfalls besser als 12 :)

Antworten (2)

Wenn der Speicher, den Sie simulieren, in den Arbeitsspeicher der Workstation passt, ist die Verwendung eines Speichers mit fester Größe am einfachsten zu verwenden. Aber wie Sie gesehen haben, sind Signale im Vergleich zu Variablen viel teurer. Dieser Unterschied hängt mit dem diskreten Ereignissimulationsmodell zusammen , auf dem VHDL basiert. Eine Signalzuweisung plant eine Transaktion zu einem bestimmten Zeitpunkt, aber eine Variablenzuweisung ist streng genommen eine sequentielle Anweisung, die ohne Simulationszeit ausgeführt wird. Der Unterschied zeigt sich in der Speichernutzung der beiden unterschiedlichen Modelle. Die Ergebnisse werden erhalten, indem der Beispielcode unten in Riviera PRO ausgeführt wird.

Speicherbelegung bei Verwendung eines Signals zur Datenspeicherung:

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

Speicherbelegung bei Verwendung einer Variablen zur Datenspeicherung:

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

Beispielcode

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;
Wow, ich hätte nicht gedacht, dass dies einen so großen Unterschied in der Simulation macht.

Müssen Sie all diesen Speicher verwenden?

Könnten Sie damit durchkommen, eine spärliche Erinnerung zu simulieren ...

Verwenden Sie eine Datenstruktur wie ein Wörterbuch (ich habe einen AVL-Baum - in meiner 'Made-at-Work'-Bibliothek, daher kann ich ihn leider nicht teilen: () Sie können nur die Werte speichern, die geschrieben wurden und die Adressen, an die sie geschrieben wurden Wenn Ihre Simulation nur einen kleinen Bruchteil des Arrays berührt, können Sie viel sparen!

Die Speichermodelle von Micron haben früher so etwas gemacht, sie haben verwendet, newum eine Zeile nach der anderen zuzuweisen, wenn auf sie zugegriffen wurde. Sehen Sie, ob Sie ihre alten synchronen Single-Data-Rate-DRAM-Modelle ausgraben können, sie waren ziemlich lehrreich, soweit ich mich erinnere.

In meinem Fall speichert der Speicher das gesamte Bild und das resultierende Bild. Die Größe wird also voll ausgenutzt, sodass Ihre Vorgehensweise wahrscheinlich keine Einsparungen bringen würde. Aber die Idee an sich klingt gut.