quartus, vhdl und blockram

Gast #1749019
Lesenswert?

servus

gibt es eigendlich in quartus die möglichkeit ein ram in vhdl zu 
beschreiben was dann im EAB und nicht in den LE's erzeugt wird? Ich hab 
nur die möglichkeit gefunden eine ram komponente mit dem megawizard zu 
erstellen und die dann ins desigen einzubinden. Das kann doch aber nicht 
die ultimative lösung sein. Zumal es bei xilinx ja auch über vhdl code 
funktioniert.
Weiß da jemand genaueres?

gruß sunny
Gast #1749332
Lesenswert?

In der Regel wird immer ein Blockram verwendet, außer du hast eine 
krumme Anzahl an Indizes, also keinen "vollen" Ram genutzt.

In dem Fall kannst du in den Optionen aber immer noch einstellen, das 
auch für solche Fälle Blockram verwendet werden soll.


Ansonsten einfach mal den code zur Deklaration und Verwendung des Rams 
zeigen.

Weiß z.b. nicht ob es automatisch instanziiert wird, wenn man in einem 
Takt von mehreren Adressen liest oder solche Späße.
Gast #1749440
Lesenswert?

Du brauchst mindestens ein Register am Eingang oder Ausgang und darfst 
keine speziellen Operationen auf ihnen durchführen. (Aufpassen mit 
Resetsignalen) Der folgende Code inferiert RAM in Cyclone FPGAs.
1
use ieee.std_logic_1164.all;
2
use ieee.numeric_std.all;
3

4
entity SampleRecorder is
5
port(
6
    signal clk, reset : in std_logic;
7
    signal ctrl_address : in std_logic_vector(1 downto 0);
8
    signal ctrl_writedata : in std_logic_vector(31 downto 0);
9
    signal ctrl_write : in std_logic;
10
    signal samples_address : in std_logic_vector(11 downto 0);
11
    signal samples_readdata : out std_logic_vector(31 downto 0);
12
    signal samples_read : in std_logic;
13
    signal sample_in : in std_logic_vector(23 downto 0);
14
    signal sample_in_strobe : in std_logic
15
);
16
end entity;
17

18
architecture arch of SampleRecorder is
19
    subtype sample_memword_t is std_logic_vector(23 downto 0);
20
    type sample_mem_t is array(0 to 4095) of sample_memword_t;
21
    signal sample_mem : sample_mem_t;
22
    signal sample_writeaddr : unsigned(11 downto 0);
23
    signal sample_writedata : std_logic_vector(23 downto 0);
24
    signal sample_write : std_logic;
25
begin
26
    process(clk, reset)
27
    begin
28
        if reset = '1' then
29
            sample_writeaddr <= (others=>'0');
30
            sample_writedata <= (others=>'0');
31
            sample_write <= '0';
32
        elsif rising_edge(clk) then
33
            if sample_in_strobe = '1' then
34
                sample_writeaddr <= sample_writeaddr+1;
35
                sample_writedata <= sample_in;
36
                sample_write <= '1';
37
            else
38
                sample_write <= '0';
39
            end if;
40
            if sample_write = '1' then
41
                sample_mem(to_integer(sample_writeaddr)) <= sample_writedata;
42
            end if;
43
            if samples_read = '1' then
44
                samples_readdata <= X"00"&sample_mem(to_integer(unsigned(samples_address)));
45
            end if;
46
            if ctrl_write = '1' then
47
                sample_writeaddr <= unsigned(ctrl_writedata(11 downto 0));
48
            end if;
49
        end if;
50
    end process;
51
end arch;
Gast #1751630
Lesenswert?

hallo,

ich hab mal noch ein bischen weiter gespielt. wirklich weiter gekommen 
bin ich aber nicht.
meine plattform ist ein FLEX10KA (EPF10K100A...).
dieser code
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.std_logic_unsigned.all;
4

5
entity ramtest is
6
port(
7
    signal clk, wr : in std_logic;
8
    signal waddr,raddr : in std_logic_vector(7 downto 0);
9
    signal outdata : out std_logic_vector(7 downto 0);
10
  signal indata:in std_logic_vector(7 downto 0));
11
end entity;
12

13
architecture arch of ramtest is
14
    subtype sample_memword_t is std_logic_vector(7 downto 0);
15
    type sample_mem_t is array(0 to 255) of sample_memword_t;
16
    signal mem : sample_mem_t;
17
begin
18
    process(clk,raddr)
19
    variable adv:integer range 0 to 255;
20
    begin
21
    adv:=conv_integer(waddr);
22
        if wr = '1' then
23
            if rising_edge(clk) then
24
        mem(adv)<=indata;
25
            end if;
26
    else
27
     null;
28
     end if;
29
   adv:=conv_integer(raddr);
30
  outdata<=mem(adv);
31
    end process;
32
end arch;

sollte doch eigendlich ein RAM in einem der EAB's erzeugen? (würde auch 
genau in einen rein passen) tut er aber nicht. er bildet das ram aus 
knapp 3700 LE's. es macht auch keinen unterschied ob ich die 
ein/ausgänge registered mache oder nicht. immer das selbe. das ram 
landet in den LE's.
welche option muss ich denn setzen oder wie muss ich den code schreiben 
damit es hin haut?

@serioussam
mit dem code funktioniert es auch nicht. das ram wird dabei auch in den 
LE's erzeugt. zumindest bei mir. egal ob ich cyclone oder flex10k als 
zielplattform auswähle.

gruß sunny
Gast #1751847
Lesenswert?

Du musst entweder outdata oder raddr (und ev. auch waddr und indata) 
registrieren, damit ein RAM-Block gebraucht werden kann. Der Compiler 
schiebt dann das Register an den richtigen Platz (Eingang,Adresse).
Gast #1752306
Lesenswert?

kenn mich eher mit Xilinx aus, aber vielleicht ist es ja ähnlich:

Kann man überhaupt ein RAM direkt aus VHDL erzeugen? Für die Simulation 
ja, aber für FPGA sollte normalerweise mit einem Werkzeug des 
Herstellers ein RAM-Block als IP erzeugt werden. Da wird dann eine Datei 
erzeugt, die man bei der Synthese mit einbindet. Dieser IP hat dann alle 
RAM-Signale wie Adressbits/Datenbits und R/W OE usw....Der IP kann dann 
als BlackBox im VHDL instantiiert werden....als COMPONENT mit der 
richtigen Bezeichnung, so dass die Synthesesoftware dann den fertig 
erzeugten Core benutzt.
Gast #1752396
Lesenswert?

ein_unwissender schrieb:
> Kann man überhaupt ein RAM direkt aus VHDL erzeugen?
Ja, man kann. Bei Xilinx steht das im "XST User Guide". Bei Altera wird 
es ein ähnliches Dokument geben.

Ich persönliche finde diese Schreibweise schöner, als einen 
instanziierten Blockram, der komische (und evtl. überflüssige) 
Signalnamen verwendet.

Duke
Gast #1752397
Lesenswert?

ok, wieder was gelernt.

Jedoch denke ich, dass man mit der BlackBox-Methode vielleicht als 
RAM-Neuling anfangen sollte um keinen unsinnigen RAM zu erstellen. Für 
die Profis ist es natürlich Geschmackssache, wenn man weiss was man tut.
Gast #1752405
Lesenswert?

tatsache! raddr muss registered sein!?!
1
    process(clk,raddr)
2
    variable adv,adv2:integer range 0 to 255;
3
    begin
4
        adv:=conv_integer(waddr);
5
        if rising_edge(clk) then
6
        if wr = '1' then
7
        mem(adv)<=indata;
8
        else
9
        adv2:=conv_integer(raddr);
10
        end if;
11
        end if;
12
        outdata<=mem(adv2);
13
    end process;
so funktionierts. ist ja doof. das auch das lesen taktsyncron erfolgen 
muss. aber o.k. damit muss man dann warscheinlich leben.
danke für eure hilfe!

gruß sunny

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren