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
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
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
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).
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
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
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
Ich habe die RAMB gefunden (man muss nur die Augen auf machen :-) ) Nur trootzdem findet man kein timing.
> 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
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
> 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
oder du inferierst es in VHDL: TYPE MEM IS ARRAY(0 to 1499) of std_logic_vector(17 downto 0); signal ram_block: MEM;
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
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
Mensch das nenne ich mal Service (und das in Deutschland :-)) ) Vielen Dank
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?
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.
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.
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...
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.
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.
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
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 ;-)
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
>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;
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
>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 ..."
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
>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;
@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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.