Forum: FPGA, VHDL & Co. Block Ram vs distributed RAM


von Michael (Gast)


Lesenswert?

Hi @ all

Ich habe mal ne Frage. Worin besteht der Unterschied zwichen
distributed RAM und Block RAM. Diese beiden Ram-Angaben werden immer in
den Datenblättern von Xilinx gemacht. Ich weiß das man den FPGA auch als
Speicher benutzen kann. Dafür gibt es extra IP-Cores in Bibliotheken.
Jedoch welchen Vorteil hat welcher Ram und wofür wird er genau
verwendet?

Wenn ich den RAM als Speicher benutzte um Ergebnise
zwischenzuspeichern, geht denn was von meinen Logikzellen verloren oder
wird der RAM ohne Logikzellen realisiert?

Grüsse

Michael

von tobias hofer (Gast)


Lesenswert?

block ram ist ein echtes sram bei den xilinx bausteinen.
distributed ram ist ein ram das mit den logikresourcen der bausteine
gebilded wird.

gruss tobias

von Christian (Gast)


Lesenswert?

Hi,
der Unterschied der beiden RAM-Sorten lässt sich doch schon fast aus
dem Namen ableiten. Das BlockRAM wird mit speziellen RAM-Blöcken (1kx18
echtes RAM in den Chip gegossen) realisiert. Distributed RAM wird aus
den gewöhnlichen Logikzellen generiert. Das geht aber auch eindeutig
aus den Datenblättern hervor...
Beides hat natürlich Vor- und Nachteile, so kann man mit den BlockRAMs
große Speicher realisieren, die keine Logikzellen verbrauchen.
Distributed RAMs können dafür in beliebiger Konfiguration genutz werden
und dadurch erhebliche Geschwindigkeitsvorteile bringen (z.B. sehr
breite Datenbusse). Pauschal läßt sich nicht einfach so sagen, welches
RAM besser ist.

Grüße
Christian

von Michael (Gast)


Lesenswert?

Wie kann ich denn den RAM nutzen? Oder noch besser wie kann ich ihn
ansteuern oder ansprechen? Es ist ja schön wenn man weiß, dass es ihn
gibt (man muss ihn aber uach nutzen können).

von Christian (Gast)


Lesenswert?

Mit dem ISE Core Generator das entsprechende RAM erzeugen. Das kann dann
als component in VHDL instanziert werden. Der Core Generator erzeugt
auch direkt einen VHDL-Wrapper.
Ansteuerung: ja, wie man ein SRAM halt ansteuert, gell? Siehe
Datenblätter...

Grüße
Christian

von Jörn (Gast)


Lesenswert?

Schau mal in die Xilinx Lib:
www.xilinx.com/support/sw_manuals/xilinx7/download/lib.zip

Dort sind die verschieden RAM Konfigurationen und deren Inferierung
beschrieben

von Michael (Gast)


Lesenswert?

Oh danke erst mal für den interessanten Link. Habe auch gleich
reingeschaut. Habe dort auch Ram-Module gefunden. z.B. "RAM16X4S" das
ist nicht wirklich groß. :-( Vor allem steht dort kein Timing, d.h. wie
lange muss die Adresse anstehen, bevor die Clock-Flanke erscheint. (das
ist ganz schön schwach von Xilinx)

Was mir noch aufgefallen ist, die haben kein Modul für den "Block
Ram" in ihrer Library zumindestens nicht im PDF-File

von Michael (Gast)


Lesenswert?

Ich habe die RAMB gefunden (man muss nur die Augen auf machen :-) )

Nur trootzdem findet man kein timing.

von Christian (Gast)


Lesenswert?

> Nur trootzdem findet man kein timing.

Hmpf, z.B. Virtex2-Datenblatt (liegt hier gerade rum): "Functional
Description -> 18 Kbit Block SelectRAM Resources -> Configuration ->
Read/Write Operations", in meiner Revision Seite 23...

...Oder im Core Generator auf "Datasheet" klicken... Da gibt es noch
viel ausführlichere Informationen. Inkl. Timing-Diagrammen.

> das ist nicht wirklich groß. :-(

Wenn dir ein Block nicht reicht, kannst du im Core-Generator mehrere
Blöcke zu einem RAM verbinden... kostet allerdings Logik. Die BlockRAMs
sollen auch nicht gerade die 32MB-SDRAM für den Prozessor ersetzen.
Dafür sind FPGAs zu teuer ;-)

Christian

von Michael (Gast)


Lesenswert?

Ok habe mal die Datenblätter durchgelesen :-))

Eine Frage habe ich aber noch.

Beim Spartan 3 hat z.B. ein Block 18k Byte und insgesagmt hat so ein
FPGA X Blöcke (abhängig vom Typ). Wenn der RAM-Block 18 Datenleitungen
besitzt, dann stehen mir 1k Speicheradressen mit je 18Bit zur
Verfügung. Nun brauche ich aber 1500 Adressen mit je 18 Bit. Wie gehe
ich da vor?

Plaziere ich 2 RAM-Blöcke im Schematic und benutze ich einen
Multiplexer um seperat auf jeden zuzugreifen oder wie mache ich es am
besten?


Gruss

Michael

von Christian (Gast)


Lesenswert?

> Ok habe mal die Datenblätter durchgelesen :-))

na also, geht ja.

> Nun brauche ich aber 1500 Adressen mit je 18 Bit. Wie gehe
> ich da vor?

genau, wie oben bereits beschrieben:

> Wenn dir ein Block nicht reicht, kannst du im Core-Generator mehrere
> Blöcke zu einem RAM verbinden... kostet allerdings Logik.

Core-Generator starten, Datenbreite auf 18bit und Speichertiefe auf
1500, oder was immer du brauchst. Der Core-Generator erstellt dir einen
Entity, der die BlockRAMs und die benötigte Logik enthält. Nach außen
verhält sich das immer noch wie ein großer Speicher.

Grüße
Christian

von Jörn (Gast)


Lesenswert?

oder du inferierst es in VHDL:

TYPE MEM IS ARRAY(0 to 1499) of std_logic_vector(17 downto 0);
signal ram_block: MEM;

von Michael (Gast)


Lesenswert?

Schön wenn ISE einen Core-Generator besitzt :-)

Ich benutze aber ProtelDXP 2004, da es beim Erstellen von
Top-Down-Designs sehr viel besser ist als ISE. Außerdem besitzt die
Umgebung auch schon einen tollen Simulator und auch noch IP-Cores (z.B.
µP mit 32 Bit)

Das Problem ist, dass es hier keine Core-Generator wie bei ISE gibt.
Demnach bleibt mir nur übrig zwei RAM-Blöcke zu nehmen und eine Logik
zu erstellen, die dafür sorgt, dass wenn der eine Speicher voll ist,
der zweite beschriben wird, oder ich versuche den unter ISE erzeugten
Core in Protel DXP zu integrieren. (war das nicht ein toller Satz)

Aber vielen Dank für Deine Hilfe.

Ich werde ich ein paar Wochen selber ein Forum über FPGAs, µP und DSP
erstellen. Wenn Du Lust hast kannste ja mitwirken.

Grüsse Michael

von Christian (Gast)


Angehängte Dateien:

Lesenswert?

Hi,

> Schön wenn ISE einen Core-Generator besitzt :-)
> Ich benutze aber ProtelDXP 2004

tja, Pech gehabt ;-) Sorry, mein Fehler.
Aber ernsthaft: das Importieren sollte kein Problem sein; ich habe dir
einfach mal schnell die Ausgabe vom Core-Generator angehängt.

Grüße
Christian

von Jörn (Gast)


Angehängte Dateien:

Lesenswert?

Ich hab es mal als VHDL beschreiben und das ISE Ergebniss angehängt.

von Michael (Gast)


Lesenswert?

Mensch das nenne ich mal Service (und das in Deutschland :-)) )

Vielen Dank

von Michael (Gast)


Lesenswert?

Ach was ich noch fragen wollte. Es gibt ja laut Datenblatt den
Betriebsmode "First_Write", "First_Read" und "No_Change" bei
Block-RAM. Wo kann ich das einstellen?

Wenn ich die Datei RAM18x1500.vhd öffne, dann steht dort "c_write_mode
=> 0," muss ich einfach nur den Wert auf 2 ändern wenn ich z.B. den
Betriebsmode "NO-Change" einstellen möchte?

von 123 (Gast)


Lesenswert?

hallo

der threat hat mir schon sehr weitergeholfe.

ich benötige 480 mal 6bit. wenn ich es mit logiczellen machen würde
dann währen das 480+6=2,8k ist das richtig?

normal benutze ich hdldesigner besseres top-down.

hab aber auch ISE webpack 7.1 find aber leider den Core-generator
nicht.

von nimbus4 (Gast)


Lesenswert?

Den Core-generator findest du über Project->New Source und dann im
Dialogfenster IP(Coregen....) auswählen

Bei BlockRAM wirst du eine 8bit version nehmen müssen und dann 2 bits
verwerfen.

von T.M. (Gast)


Lesenswert?

Den Coregenerator gibts doch eh nur in der Vollversion von ISE, nicht im
Webpack, ich hab da zumindestens nichts gefunden. Beispiele für die
BockRAM Instantiierung findet man in den Language Templates bei zB VHDL
unter Device primitive instantiation. Da ist es ganz gut erklärt für die
verschiedenen Arten...

von 123 (Gast)


Lesenswert?

vielen dank. T.M. hat recht im webpack gibt es kein coregenerator;-(
die ein passendes template hab ich schon gefunden 2k+8, werd ich mir
mal morgen anschaun.

von J. S. (engineer) Benutzerseite


Lesenswert?

Also für das Zusammenstöpseln von Blockramzellen braucht man nun
wirklich keinen Code-Generator. Wenn es Deine APP nicht schon hergibt
muss man eben noch eine Decoder/Multiplexer-Architektur davorsetzen.

Um aber noch etwas zur Frage zur sagen: Ein wesentlicher Punkt ist das
Routing: Block-Ram liegt meist irgendwo kompakt im FPGA vergraben und
erfordert Routing-Resorucen. Die aus den LE gebildeten
RAM-Architekruren können hingegen an Ort und Stelle liegen, wo sie
benötigt werden.

von ope (Gast)


Lesenswert?

wird bei infering wirklich auch blockram benutzt?

Folgender code auf einem 2s100tq144-5
(http://direct.xilinx.com/bvdocs/publications/ds001.pdf) mit angeblich
10*4096 kbit:

[vhdl]
entity ram_512x80 is

   generic (
      RESET_ACTIVE   : std_logic := '1'
   );
   port (
      clk            : in  std_logic;
      reset          : in  std_logic;
      en             : in  std_logic;
      AB             : in  std_logic_vector(8 downto 0);
      DB_I           : in  std_logic_vector(79 downto 0);
      DB_O           : out std_logic_vector(79 downto 0);
      we             : in  std_logic
   );

end entity ram_512x80;

architecture infering of ram_512x80 is

   constant BIT_DEPTH      : positive  := 512;
   constant BIT_WIDTH      : positive  := 80;

   type ram_t is array(BIT_DEPTH-1 downto 0)
      of std_logic_vector(BIT_WIDTH-1 downto 0);

   -- infer RAM
   signal blockram   : ram_t;

begin

   write_proc: process (clk)
   begin
      if rising_edge(clk) then
         if (en = '1') and (we = '1') then
            blockram(conv_integer(AB)) <= DB_I;
         end if;
      end if;
   end process;

   read_proc: process (clk)
   begin
      if rising_edge(clk) then
         if (en = '1') and (we = '0') then
            DB_O <= blockram(conv_integer(AB));
         end if;
      end if;
   end process;

end architecture infering;

[vhdl]

macht in der Synthese mit xst Probleme:

Synthesizing Unit <ram_512x80>.
    Related source file is
"D:/electronic/projects/la/la/ise/../source/vhdl/xc2s100_xram.vhd".
WARNING:Xst:647 - Input <reset> is never used.
    Found 512x80-bit single-port distributed RAM for signal
<blockram>.

-----------------------------------------------------------------------
    | aspect ratio       | 512-word x 80-bit                   |
  |
    | clock              | connected to signal <clk>           | rise
  |
    | write enable       | connected to internal node          | high
  |
    | address            | connected to signal <AB>            |
  |
    | data in            | connected to signal <DB_I>          |
  |
    | data out           | connected to internal node          |
  |
    | ram_style          | Auto                                |
  |

-----------------------------------------------------------------------
    Found 80-bit register for signal <DB_O>.
    Summary:
  inferred   1 RAM(s).
  inferred  80 D-type flip-flop(s).
Unit <ram_512x80> synthesized.

.......

======================================================================== 
=
*                            Final Report
*
======================================================================== 
=

Device utilization summary:
---------------------------

Selected Device : 2s100tq144-5

 Number of Slices:                    2941  out of   1200   245% (*)
 Number of Slice Flip Flops:            80  out of   2400     3%
 Number of 4 input LUTs:              3306  out of   2400   137% (*)
 Number of bonded IOBs:                173  out of     96   180% (*)
 Number of GCLKs:                        1  out of      4    25%

WARNING:Xst:1336 -  (*) More than 100% of Device resources are used

Er hat distributed Ram 'draus gemacht. Gilt es irgendwelche attribute
'dranzuheften?

BTW, was macht bei den Blockrams von Xilinx der reset? kann man den
hier sinnvoll verbraten?

Viele Grüße
Olaf

von T.M. (Gast)


Lesenswert?

Willst du wirklich einen 80bit breiten BlockRam initialisieren? Ich
nehme mal an, dass du den BlockRAM nur bis 16bit Breite initialisieren
kannst. Wenn ich nach der Tabelle im Datasheet gehe. Ich hab bei einem
Projekt einen solchen benutzt und er hat dafür den BlockRam genommen.
Mit dem Reset wirst du den Inhalt des Rams löschen können, nehm ich mal
an. Ob man das sinnvoll verbraten kann, hängt vom Design ab ;-)

von ope (Gast)


Lesenswert?

Ja, 80 bit Breite soll es sein. Hintergrund: Ich habe Datenwörter mit 26
bit Breite (Datentupel), somit passen in die 80 bit drei dieser
Datentupel rein und zwei bit bleiben zur anderweitigen Verwendungen.
Lesen muss ich diese mit 8 bit Breite, d.h. ich habe einen Eingangs-
und Ausgangsmuxer.

Allerdings habe ich keine Beschränkungen bei xilinx gefunden, warum
mein  Datenbus nicht 80 bit breit sein kann. XC2S100 hat 10 Blöcke a
4096 bit, organisierbar jeweils zu 512x8 - ich nehme halt die 10 Stck.
parallel bzw. überlasse es der Synthese für mich.

Reset: Einige nehmen eine Schleife und setzen bei reset alles zu Null.
Imo benötigt dies einen counter extra + logik, was kontra produktiv
ist. Aber etwas muss der interne Blockram ja mit dem reset machen -
alles zu Null setzten?

Viele Grüße
Olaf

von Xenu (Gast)


Lesenswert?

>Er hat distributed Ram 'draus gemacht. Gilt es irgendwelche attribute
>'dranzuheften?

Nö, wenn man es richtig kodiert, wird Block-RAM draus:
(siehe XST User Guide)


   process (clk)
   begin

     if rising_edge(clk) then
       if(en = '1') then
         if (we = '1') then
           blockram(conv_integer(AB)) <= DB_I;
         else
           DB_O <= blockram(conv_integer(AB));
         end if;
       end if;
     end if;

   end process;

von Cpt (Gast)


Lesenswert?

Im Spartan 2 zieht der Blockram bei reset alle Ausgänge auf 0 (solange
reset aktiv ist).
Die Daten bleiben aber erhalten ... merkwürdig aber so ist es.

Cpt

von Xenu (Gast)


Lesenswert?

>merkwürdig aber so ist es.

Und was daran ist merkwürdig?

In der Application Note 173 findet sich dazu folgender Satz:

"The reset pin forces the data output bus latches to zero
synchronously. This does not affect the memory cells of the RAM ..."

von ope (Gast)


Lesenswert?

Immerhin wird xst jetzt konkreter mit Xenu's Bsp.:

INFO:Xst:1436 - HDL ADVISOR - Unable to extract a block RAM for signal
<blockram>. The read/write synchronization appears to be NO_CHANGE and
is not available for the selected family. A distributed RAM will
usually be created instead. To take advantage of block RAM resources,
you may want to revisit your RAM synchronization or check available
device families.

Zumindest kann der XC2
(http://direct.xilinx.com/bvdocs/publications/ds001_2.pdf S.24)
wirklich nur ReadTrough und WriteBack, kein NoChange mode wie XC3S u.a.
Was nun?

Viele Grüße
Olaf

von Xenu (Gast)


Lesenswert?

>Was nun?

Hallo nochmal,

ich habe vorhin übersehen daß Du einen Spartan-II benutzt, und nicht
Spartan-3.

Ein Block-RAM mit "write first"-Eigenschaft geht so:


   process (clk)
   begin

     if rising_edge(clk) then
       if(en = '1') then
         if (we = '1') then
           blockram(conv_integer(AB)) <= DB_I;
           DB_O <= DB_I;
         else
           DB_O <= blockram(conv_integer(AB));
         end if;
       end if;
     end if;

   end process;

von ope (Gast)


Lesenswert?

Vielen Dank!

von Cpt (Gast)


Lesenswert?

@Xenu
Ja ich kenne die Appclication Note. Mit merkwürdig meinte ich auch
eher, daß mir bis jetzt noch kein konkreter Verwendungszweck für den
Block Ram Reset eingefallen ist bzw. ich ihn noch nie wirklich
gebraucht habe ...

Cpt

von Cpt (Gast)


Lesenswert?

Ok sonst stehen nach einem reset ja noch die alten Daten am Ausgang.

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.