Hallo zusammen. Erstmal Entschuldigung für den Titel, aber für "infer" finde ich keine schöne Übersetzung die aus einem Wort besteht. Ich möchte wissen was die Bedingungen sind, dass eine Toolchain wie die von Vivado, ein Array in BRAMs packt. Eine Bedingung ist klar, die Leseadresse muss getaktet sein. Es scheint aber noch weitere Bedingungen zu geben, wie ist das also wenn a) die Tiefe ein BRAM nur minimal nutzen würde, z. B. ein Array aus 8x32 Bits oder 8*36 Bits würde ja von der Breite gut passen, aber eben einen BRAM36 (das sind 4 kByte) kaum nutzen. b) oder die Breite sehr ungünstig ist wie z. B. ein Array aus 1024x5 Bits. Gibt es da feste Grenzen ab denen das Tool dann entscheidet dass da doch kein BRAM draus wird weil das Verschwendung wäre? Oder hängt das vom Design ab, also guckt das Tool viel viele BRAMs noch ungenutzt sind und wie viele LUTs ungenutzt sind und entscheidet dann was sinnvoller ist? Und gibt es auch Fälle in denen nur Teile des Array als BRAM implementiert werden? Ich denke da an ein Array wie 1024x38 Bits. Das passt gerade so nicht in ein BRAM36, aber die restlichen 1024x2 Bits (oder 1024x6 Bits ohne Parity) sind vielleicht zu wenige damit das Tool ein weiteres BRAM verwendet. Man bekommt also ein BRAM36 und den Rest in LUTs. Bonusfrage: Gibt es eine Option mit der ich das Tool dazu zwingen kann ein Array vollständig entweder als distributed RAM oder als BRAM zu bauen (wenn die Beschreibung die jeweilige Implementation erlaubt)? Vielen Dank!
:
Bearbeitet durch User
UG901 ist fuer Vivado der entsprechende Userguide zu dem Thema. Gustl B. schrieb: > Bonusfrage: > Gibt es eine Option mit der ich das Tool dazu zwingen kann ein Array > vollständig entweder als distributed RAM oder als BRAM zu bauen (wenn > die Beschreibung die jeweilige Implementation erlaubt)? Klar. Steht auch in UG901. Leider weiss ich das nicht auswendig, irgendwas mit RAM Style koennte das entsprechende VHDL Attribut heissen.
Tobias B. schrieb: > irgendwas mit RAM Style koennte das entsprechende VHDL Attribut heissen. attribute rom_style : string; attribute rom_style of tw_rom : constant is "block"; Sollte analog für "ram_style" gehen.
Danke, Seite 55 liefert. Man kann also einstellen was gemacht werden soll. Was man nicht machen kann ist die Schwelle zu verschieben ab der zwischen den Implementierungen unterschieden wird. Und was auch nicht dabei steht ist wie der automatische Default Modus das entscheidet. Aber das war schon eine große Hilfe, jetzt kann ich das zumindest erzwingen wie ich will.
Die Heuristik wird deutlich komplexer sein, als nur eine Analyse der RAM Geometrie. Da spielen auch globale Synthese Einstellungen eine Rolle, z.B. Area und Speed Opmtimierungen. Auch Power Optimeirungen koennten eine Rolle spielen. Ein wichtiges Kriterium wird definitiv die Design Groesse sein. Sind keine LE mehr frei, bleibt nur noch der Gang ueber BRAM (oder Ultra RAM bei den neueren Devices). Daher sollte es in der Praxis mehr als ausreichend sein, einen Schalter zu haben um den RAM Style waehlen zu koennen. Und selbst da hat man eigentlich kaum einen Grund daran rumspielen zu muessen.
Den folgenden Blog-Artikel habe ich schon mehrfach verlinkt, und obwohl er inzwischen schon deutlich gealtert ist, beschreibt er sehr schön, wie die unterschiedlichen Toolchains ihre Blockrams inferieren: https://danstrother.com/2010/09/11/inferring-rams-in-fpgas/ Wenn es etwas komplexer wird, gibt es da nämlich deutliche Unterschiede zwischen den Herstellern. In den Tools selbst gibt es meist irgendwo versteckt ein VHDL/Verilog-Template für bestimmte Anwendungsfälle, die dann in diesem Tool zuverlässig funktionieren sollten.
S. R. schrieb: > Wenn es etwas komplexer wird, gibt es da nämlich deutliche Unterschiede > zwischen den Herstellern. Das ist in der Tat schon recht stark gealtert. Das Spartan 6 Problem ist 10 Jahre her! (Have a look at this excerpt from the “Conflict Avoidance” section of Xilinx’s) Ich bin vom inferrieren wieder weg, weil die BRAMs der Hersteller doch recht unterschiedlich funktionieren und konfiguriert werden können, um das Verhalten bei Kollision zu steuern. In Abhänhigkeit wofür man baut, nehme ich lieber ein angepasstes VHDL als wrapper, das die richtig Funktion hat und Nachteile des einen gegenüber dem anderen kompensiert.
Markus W. schrieb: > Das ist in der Tat schon recht stark gealtert. > Das Spartan 6 Problem ist 10 Jahre her! Mir ging es nicht darum zu zeigen, wie man es richtig macht, sondern um den eindeutigen Hinweis, dass es für komplexere Varianten sehr schnell herstellerabhängig wird, trotz generischem VHDL/Verilog. Markus W. schrieb: > In Abhänhigkeit wofür man baut, > nehme ich lieber ein angepasstes VHDL als wrapper Und das, zusammen mit einem generischen Fallback, scheint (leider) die optimale Vorgehensweise zu sein. Ähnlich wie bei optimiertem C/C++ (z.B. Codecs), wo man eine generische Implementation zusammen mit optimierten Assemblerroutinen ausliefert und nachträglich auswählt.
Ich nutze fast ausschließlich inferred RAM und ROMs. Die Synthese arbeitet eigentlich hierbei sehr intelligent und wandelt am BRAM-limit den weiteren Speicher in distributed um. Auch wird dadurch das Design wieder viel portabler und die Simulation bleibt schlank. Mit ram-styles arbeite ich nur selten. Diese sind aber die nächste Stufe, wenn es genauer werden soll. Core-Generator RAMs sind wirklich die seltene Ausnahme.
Klakx -. schrieb: > Ich nutze fast ausschließlich inferred RAM und ROMs. Nutzt du komplizierte Varianten (dual-port mit unterschiedlichen Breiten, gemeinsamem Lese-/Schreibzugriff etc) oder eher nur die Standardvarianten? Für letztere reichen inferierte Lösungen nämlich oft aus.
Klakx -. schrieb: > Core-Generator RAMs sind wirklich > die seltene Ausnahme. Wie machst du es dann mit dem Timing? Wenn es aus dem BRAM nich tmit dem Tempo klappt, muss ein Register her, das dort instanziiert werden muss, will man interne Resourven nutzen und dann ist das Timing syntheseabhängig.
S. R. schrieb: > Nutzt du komplizierte Varianten (dual-port mit unterschiedlichen > Breiten, gemeinsamem Lese-/Schreibzugriff etc) oder eher nur die > Standardvarianten? Dual-Port ja, unterschiedliche Breiten habe ich bisher nicht direkt am Ram verwendet. Markus W. schrieb: > Wie machst du es dann mit dem Timing? Wenn es aus dem BRAM nich tmit dem > Tempo klappt, muss ein Register her, das dort instanziiert werden muss, > will man interne Resourven nutzen und dann ist das Timing > syntheseabhängig. Durch das Beschreiben einer Registerstufe am Ausgang kann das Tool diese in die BRAM-Instanz ziehen. Das kann man auch in den FIFO sources von Intel sehen.
So, da bin ich wieder. Also RAM für Xilinx zu beschreiben ist relativ einfach. Auch True Dualport mit unterschiedlichen Breiten und zwei Takten. Es gibt da auch keinen Unterschied zwischen den FPGA Familien, eine Beschreibung funktioniert einfach. Bei Intel hingegen ist das nicht so. In der Quartus Standard Version ist ein Template dabei, das funktioniert nicht in der Pro Version, anders herum aber schon. Der Unterschied ist, dass das Template in der Pro Version eine shared Variabe verwendet, die Standard Version aber ein signal. Seltsam ist dabei: Im Template der Standard Version wird das signal in zwei Prozessen mit unterschiedlichem Takt zugewiesen. Vivado würde das nicht erlauben, Quartus Pro auch nicht, Quartus Standard und Lite aber schon. Auch seltsam ist, dass sowohl Quartus Pro als auch Vivado/Xilinx shared variable verwenden - aber bei Beiden gibt es eine Warnung, dass das "protected" sein muss/müsste. Frage 1: Man kann das offenbar auch ohne "protected" verwenden und die Hersteller machen das auch in den Templates, welchen Vorteil hat dieses "protected" und sollte man das verwenden? Frage 2: Das Quartus Pro Template funktioniert (modifiziert) nicht für den Stratix10, also True Dualport mit unterschiedlichen Breiten und zwei Takten. Ist eine generische Beschreibung überhaupt möglich oder geht das bei dieser FPGA Familie schlicht nicht?
Gustl B. schrieb: > Es gibt da auch keinen Unterschied zwischen den FPGA Familien, > eine Beschreibung funktioniert einfach. Siehe: Markus W. schrieb: > Das ist in der Tat schon recht stark gealtert. Das Spartan 6 Problem ist > 10 Jahre her! Sp3 und Sp6 synthetisierten mindestens bis ISE v13 noch unterschiedlich. Gustl B. schrieb: > Man kann das offenbar auch ohne "protected" verwenden und die Hersteller > machen das auch in den Templates, welchen Vorteil hat dieses "protected" > und sollte man das verwenden? Reine 'shared' Variablen koennen von mehreren Prozessen modifiziert werden, wer aber zuerst randarf, ist nicht deterministisch. Also kann es fuer den selben Code von unterschiedlichen Simulatoren entsprechend unterschiedliche Resultate geben. Ist zwar gerade beim DP-RAM ein Szenario, was eben nicht auftreten sollte. Habe dazu mal (laenger her) Experimente gemacht, und bei dual-clock-FIFOs (mit EBR) keine Gray-Counter verwendet, die Architekturen glitchen dabei sehr unterschiedlich, was bei Xilinx gut laeuft, laeuft bei Lattice z.B. nicht mehr. Bin mir nicht ganz sicher ob `protected` erst mit VHDL2008 geht. Es gibt noch diesen Mischmasch vhdl93c, koennte sein, dass es da auch schon erlaubt ist. Auf jeden Fall ist dabei der Zugriff strenger geregelt, d.h. man muss a la C++ getter/setter-Routinen angeben und kann dort auch seine eigenen 'Waechter' unterbringen. Der VHDL2008-Support ist halt bei vielen Tools (wie Vivado) schlecht. Das RAM-Thema ist leider derart komplex, dass es die eierlegende Wollmilchsau-Synthese wohl nie geben wird. Und somit nie Konsens betr. einer universalen RAM-Library..
Martin S. schrieb: > Sp3 und Sp6 synthetisierten mindestens bis ISE v13 noch unterschiedlich. Ja, mir geht es eigentlich um die aktuellen Versionen. Martin S. schrieb: > Reine 'shared' Variablen koennen von mehreren Prozessen modifiziert > werden Genau. Aber in Quartus Standard/Lite geht das auch mit Signalen. Finde ich seltsam. Martin S. schrieb: > Bin mir nicht ganz sicher ob `protected` erst mit VHDL2008 geht. Martin S. schrieb: > Der VHDL2008-Support ist halt bei vielen Tools > (wie Vivado) schlecht. Ja naja, ich finde es seltsam, dass alle Synthesetools die ich hier habe warnen, dass eine shared Variable protected sein muss, aber gleichzeitig ist in den Sprachtemplates genau dieser Tools nix von protected drinnen. Martin S. schrieb: > Das RAM-Thema ist leider derart komplex, dass es die eierlegende > Wollmilchsau-Synthese wohl nie geben wird. Und somit nie Konsens betr. > einer universalen RAM-Library.. Das merke ich gerade )-:
Gustl B. schrieb: > Martin S. schrieb: >> Reine 'shared' Variablen koennen von mehreren Prozessen modifiziert >> werden > > Genau. Aber in Quartus Standard/Lite geht das auch mit Signalen. Finde > ich seltsam. Das haengt davon ab was die Synthese optimiert. Multiple Drivers koennen die FPGAs per se nicht. Die eine Version wird das halt soweit runterbrechen und ueber mehrere Prozesse hinweg optimieren. Die andere Quartus Version hat vll. einen SCA Check drin, der scho nenn Fehler wirft bevor die Synthese ueberhaupt startet. Gustl B. schrieb: > Ja naja, ich finde es seltsam, dass alle Synthesetools die ich hier habe > warnen, dass eine shared Variable protected sein muss, aber gleichzeitig > ist in den Sprachtemplates genau dieser Tools nix von protected drinnen. Ob eine shared Variable protected ist oder nicht, ist auf Syntehse Ebene voellig unerheblich, da wird schliesslich nichts Technologie spezifisches abgebidlet. Der Knackpunkt entsteht beim simulieren, wenn etwa im gleichen Delta Cycle eine Variable geschrieben werden soll. Das hier verdeutlicht es ganz gut, ist auch nicht so kompliziert beschrieben: https://www.fpgatutorial.com/vhdl-shared-variable-protected-type/ Die meisten Synthese Tools sollten eigentlich damit klarkommen einen BRAM zu erkennen, sobald ein Array von Vektoren verwendet wird. Speziell wird es dann bei Builtin True Dual Port RAMs, da koennen dann womoeglich spezielle Strukturen noetig sein, damit die Logic im RAM verwendet wird und das nicht im FPGA Logik abgebildet wird.
Es gab mal einen IEEE-Standard, der synthesefähiges VHDL 'genormt' hat: 1076.6-2004 - IEEE Standard for VHDL Register Transfer Level (RTL) Synthesis Da stehen WIMRE auch ein paar RAM-Konstrukte drin. Aber so wie es aussieht kocht nun wieder jeder Hersteller seine eigene Suppe... Duke
https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/hb/stratix-10/ug-s10-memory.pdf Seite 21 unten und Seite 22. Scheinbar kann die Technik im Stratix10 Dinge nicht, die der Arria10 kann. Finde ich seltsam, denn der Stratix ist ja das Highendprodukt. Aber gut.
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.