Forum: FPGA, VHDL & Co. RAM Initialisierung in VHDL


von Flori K. (jasi)


Lesenswert?

Hallo ich habe eine Frage zur richtigen RAM Initialisierung in VHDL.
Ich will ein RAM (1024 Bit breit) anlegen, diesem 16 mal 64 Bit Blöcke 
zuweisen und danach wieder ausgeben.
Bei der Simulation klappt alles, bei der Synthese wird aber kein BRAM 
synthetisiert sondern Flip Flops, ich benutze Xilinx ISE 10.1.
Als Fehlermeldung bekomme ich:
INFO:Xst:738 - HDL ADVISOR - 1024 flip-flops were inferred…describe a 
RAM in a way that is incompatible…

Wenn ich den Eingangsvektor „di“ genauso groß wähle wie die RAM breite 
wird BRAM synthetisiert.
1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
5
entity ram_test is
6
      port (clk : in std_logic;
7
            ce  : in std_logic;
8
            rst : in std_logic;
9
            di : in std_logic_vector(63 downto 0);   --(1023 downto 0)  --// zu b.)
10
            do : out std_logic_vector(63 downto 0)); --(1023 downto 0)  --// zu b.)
11
end ram_test;
12
13
architecture syn of ram_test is
14
      
15
      type ram_type is array (0 downto 0) of std_logic_vector (1023 downto 0);      --// zu a.) 
16
      signal RAM : ram_type;                                                        --// zu a.) 
17
      
18
      --type ram_type_2 is array (63 downto 0) of std_logic_vector (1023 downto 0); --// zu b.)
19
      --signal RAM_2 : ram_type_2;                                                  --// zu b.)
20
      
21
      signal counter : integer range -1 to 16;
22
      signal counter2 : integer range -1 to 16;
23
      begin
24
          process (clk)
25
            begin
26
                if rising_edge (clk) then
27
                  if rst ='1' then
28
                     counter <= 0;
29
                     counter2 <= 0;
30
                     elsif ce ='1' then                    
31
                           if counter >= 0  and counter2 <= 0 then
32
                              RAM (0)  ((1024-1-(64*counter)) downto (1024-64-(64*counter)))  <= di; --// zu a.) 
33
                              --RAM_2 (counter)  <= di; --// zu b.)
34
                              counter <= counter + 1;
35
                           end if;
36
                           if counter >= 15 and counter2 >=0 then
37
                              do <= RAM (0) ((1024-1-(64*counter2)) downto (1024-64-(64*counter2))); --// zu a.) 
38
                              --do <= RAM_2 (counter2); --// zu b.)
39
                              counter2 <= counter2 + 1;
40
                           end if;
41
                           if counter2 >= 15  then
42
                              counter <= 0;
43
                              counter2 <= 0;
44
                           end if;
45
                  end if;                            
46
                end if;    
47
          end process;         
48
end syn;

Das XST User Guide hilft mir auch nicht weiter.
Wie löse ich das Problem, ist so etwas überhaupt als BRAM realisierbar?

Gruß
Flori

von Klaus F. (kfalser)


Lesenswert?

Muß es nicht heißen :

type ram_type_2 is array (3 downto 0) of std_logic_vector (63 downto 0);

Das ergäbe 16 Zeilen zu je 64 Bit.

von Klaus F. (kfalser)


Lesenswert?

Denkfehler :

type ram_type_2 is array (15 downto 0) of std_logic_vector (63 downto 
0);

von Flori K. (jasi)


Lesenswert?

Also ich will beim ersten Takt den Adressen 1023 bis 960 einen Wert di 
zuweisen.
Beim nächsten Takt den Adressen 959 bis 896 eine Wert di zuweisen usw…
1
type ram_type_2 is array (15 downto 0) of std_logic_vector (63 downto
2
0);
Damit erstelle ich ja ein Feld 16 Zeilen a 64 Bit breite.

Ich möchte “nur“ ein RAM mit einer Breite von 1x1024 erstellen.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

> 16 mal 64 Bit Blöcke
> zuweisen und danach wieder ausgeben.
Warum machst du das den nicht sondern so komisch?
Mach doch einfach ein Ram mit Tiefe 16 und Breite 64 oder was erhoffst 
du dir aus der Beschreibung?

von Flori K. (jasi)


Lesenswert?

Ich möchte zwei oder mehrere 1024 Bit Vektoren erzeugen, diese dann 
addieren (voneinander subtrahieren usw.), wenn ich den eingelesen Wert 
in verschieden Vektoren Splitte wird das weiterverarbeiten unmöglich.

Das ganze will ich dann auf einem FPGA Board laufen lassen, deswegen 
kann ich nicht einfach ein signal mit beliebiger länge definieren.
Weil dann die vorhanden Ressourcen aufgebraucht werden.

von Klaus F. (kfalser)


Lesenswert?

Eben, deshalb klappt es wahrscheinlich nicht.
Du definierst ein Ram, das 1 Zeile hat und diese Zeile ist 1024 Bit 
breit.
Das geht mit BlockRam nicht, die maximale Breite ist 32 Bit, obwohl der 
Compiler bei 64 Bit vielleicht auch automatisch 2 BRAM parallel 
verwendet.

Verwende 16 Zeilen zu 64 Bits, dann versteht der Compiler dass das Ram 
in einem 64 Bit breiten Datenpfad angesprochen werden soll und wird 
(hoffentlich) BRAM verwenden.

Oder Du erzeugst Dir dein RAM mit dem Core Generator und bindest es ein. 
Dann bekommst Du vielleicht auch ein Gefühl dafür, über welche 
Datenpfade man es am besten anspricht.

von Klaus F. (kfalser)


Lesenswert?

Flori K. schrieb:
> Ich möchte zwei oder mehrere 1024 Bit Vektoren erzeugen, diese dann
> addieren (voneinander subtrahieren usw.), wenn ich den eingelesen Wert
> in verschieden Vektoren Splitte wird das weiterverarbeiten unmöglich.
>
> Das ganze will ich dann auf einem FPGA Board laufen lassen, deswegen
> kann ich nicht einfach ein signal mit beliebiger länge definieren.
> Weil dann die vorhanden Ressourcen aufgebraucht werden.

Wenn Du mit den Vektoren rechnen willst, dann kannst Du sie sowieso 
nicht im Block Ram ablegen

von Iulius (Gast)


Lesenswert?

doofe Frage : wenn man schreibt
1
 sram_io_3 <= sram_io_1 + sram_io_1;

ist das dann nicht auch snythetisierbar ohne ein FF dazwischen ?

(jetzt mal unabhängig von der Größe)

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Ja, es geht ohne Register.

> sram_io_3 <= sram_io_1 + sram_io_1;
ist funktionell das selbe wie
> sram_io_3 <= sram_io_1 & '0';

Zu klären wäre, wie die Synthese das sieht  ;-)

von Iulius (Gast)


Lesenswert?

hmm dachte es ist ersichtlich das ich mich verschrieben habe.

gemeint war natürlich :

sram_io_3 <= sram_io_1 + sram_io_2;

so wie Flori das wollte.


das 2 mal der gleiche wert nur mal 2 -> leftshift bedeuted ist klar ;)

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> hmm dachte es ist ersichtlich das ich mich verschrieben habe.
Der Synthesizer hätte an dieser falsch getippten Zeile auch nichts 
auszusetzen, und daraus dann die falsch Hardware gemacht. So ersichtlich 
ist dieser Schreibfehler also nicht  :-/

> sram_io_3 <= sram_io_1 + sram_io_2;
Aber auch diese Addition geht ohne Register.

von Michael (Gast)


Lesenswert?

Ist das nicht eine einfache Delayline mit 64 bit?

Wenn Du sicher gehen willst, dass BRAM genommen werden soll, dann nimm 
ihn halt von Hand. (Bei mir hat XST bisher nur versucht reine Logik in 
BRAMs zu packen, aber noch nie FFs mit irgendwelcher Logik drumherum.)

Im Prinzip brauchst du nur deine zwei Zähler aussen und einen 
Zugriffsmechanismus für den BRAM. In meinen Augen die saubere Lösung, 
selbst wenn XST jetzt ein BRAM implementiert und du eine Zeile Code 
nachträglich ändert die wiederum nicht realisierbar wäre, fängt das 
Spiel von Vorne an.

Du hast uns noch nicht verraten welches FPGA von Xilinx du nutzt.
Mit den Instanzierungen RAMB16_S36 könntest Du 32 bit plus Parity 
direkt ansprechen.

von Flori K. (jasi)


Lesenswert?

Hallo Michael, benutze ein Virtex 4 Board.
Was ich aber dennoch nicht verstehe, ist warum erkennt ISE bei der 
Synthese ein RAM wenn der Eingangsvektor genauso groß ist wie die RAM 
breite.
1
port (di : in std_logic_vector(1024 downto 0)); 
2
type ram_type is array (0 downto 0) of std_logic_vector (1023 downto 0);      --// zu a.) 
3
signal RAM : ram_type; 
4
  
5
RAM (0)  <= di; 
6
……

Aber wenn ich bei jedem Takt etwas in das RAM schreiben will wird kein 
RAM synthetisiert.
1
port (di : in std_logic_vector(64 downto 0));
2
type ram_type is array (0 downto 0) of std_logic_vector (1023 downto 0);     
3
signal RAM : ram_type;  
4
 
5
RAM (0)  ((1024-1-(64*counter)) downto (1024-64-(64*counter)))  <= di; 
6


Oder wenn das RAM ein Bit größer ist, als der Eingangsvektor wird 
ebenfalls kein RAM bei der Synthese erkannt.
1
port (di : in std_logic_vector(1023 downto 0));
2
type ram_type is array (0 downto 0) of std_logic_vector (1024 downto 0);     
3
signal RAM : ram_type; 
4
.  
5
RAM (0) (1023 downto 0)  <= di (1023 downto 0);
6


Gibt es denn noch andere pdf´s in denen beschrieben ist, wie man RAM 
(BRAM) richtig initialisiert.
Das  XST User Guide und das VHDL Buch von Peter J.Ashenden helfen mir 
nicht wirklich weiter.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Weil du gleichzeitig lesen und schreiben willst!
Überleg dir einfach wie du ein echtes Ram ansprechen würdest was 1024 
bit breit ist du aber nur 64 bit schreiben willst.

Du könntest aber ein Ram dir generieren lassen was auf der einen Seite 
mit 1024bit gelesen werden kann und auf der anderen mit 64 bit 
geschrieben.
Für mich hat es sich bewährt die RAM beschreibung in eine Seperate 
entity zu stecken und das dann ganz normal als component einzubinden.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> Wie löse ich das Problem, ist so etwas überhaupt als BRAM realisierbar?
Es gibt keine BRAMS mit 1024 Bit Breite. Für eine Verktorbreite von 1024 
müssten 1024/36 = 29 BRAMs parallel geschaltet werden. Hast du so viele?

Das hier:
1
port (di : in std_logic_vector(1023 downto 0));
2
type ram_type is array (0 downto 0) of std_logic_vector (1024 downto 0);     
3
signal RAM : ram_type; 
4
:  
5
RAM (0)  <= di;
6
:
könnte genausogut so geschrieben werden:
1
port (di : in std_logic_vector(1023 downto 0));
2
type ram_type is std_logic_vector (1023 downto 0);     
3
signal RAM : ram_type; 
4
:  
5
RAM <= di;
6
:
oder gleich so:
1
port (di : in std_logic_vector(1023 downto 0));
2
signal RAM : std_logic_vector (1023 downto 0); 
3
:  
4
RAM <= di;
5
:
Und dafür brauchst du überhaupt kein RAM.
Lies nochmal den Beitrag "Re: RAM Initialisierung in VHDL"

BTW:
1
   signal counter : integer range -1 to 16;
2
   signal counter2 : integer range -1 to 16;
Du hast m.E. offenbar noch grundlegende Probleme mit irgendwelchen 
Randbedingungen.

Deine Ablaufsteuerung sollte besser über ein Zustandssignal geschehen, 
nicht über die Counter.
1
architecture syn of ram_test is
2
      
3
      signal RAM : std_logic_vector (1023 downto 0);   
4
      signal counter : integer range 0 to 15;
5
      signal write   : std_logic := '1';
6
      signal read    : std_logic := '1';
7
      begin
8
          process begin
9
              wait until rising_edge (clk);
10
              if rst ='1' then
11
                  counter <= 0;
12
                  write  <= '1';
13
                  read   <= '0'; 
14
              elsif ce ='1' then           
15
                  -- Schreiben         
16
                  if write='1' then
17
                      RAM(1023-(64*counter) downto 1023-63-(64*counter))  <= di;
18
                  end if;
19
                  -- Lesen
20
                  if read = '1' then
21
                      do <= RAM(1023-(64*counter2) downto 1023-63-(64*counter2));
22
                  end if;
23
                  -- Verwaltung
24
                  if counter < 15  then
25
                      counter <= counter + 1;
26
                  else                        -- fertig gezählt
27
                      counter <= 0;
28
                      if (write='1) then      -- wenn schreiben fertig:
29
                           write <= '0';      -- mit lesen weitermachen
30
                           read  <= '1';
31
                      end if;
32
                      if (read='1) then       -- wenn lesen fertig:
33
                          read  <= '0';       -- ende
34
                      end if;
35
                  end if;
36
              end if;    
37
          end process;         
38
end syn;

Insgesamt habe ich den Eindruck, du willst was Einfaches unnötig 
kompliziert machen... :-/

von Flori K. (jasi)


Lesenswert?

Danke euch allen für die Tipps.
Ich werde mir noch mal das Kapitel über RAM’s im XST genau durchlesen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.