Forum: FPGA, VHDL & Co. "Infer" BRAM - Bedingungen?


von Gustl B. (-gb-)


Lesenswert?

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
von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

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.

von Burkhard K. (buks)


Lesenswert?

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.

von Gustl B. (-gb-)


Lesenswert?

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.

von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

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.

von S. R. (svenska)


Lesenswert?

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.

von Michael W. (Gast)


Lesenswert?

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.

von S. R. (svenska)


Lesenswert?

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.

von Klakx -. (klakx)


Lesenswert?

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.

von S. R. (svenska)


Lesenswert?

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.

von Michael W. (Gast)


Lesenswert?

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.

von Klakx -. (klakx)


Lesenswert?

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.

von Gustl B. (-gb-)


Lesenswert?

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?

von Martin S. (strubi)


Lesenswert?

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..

von Gustl B. (-gb-)


Lesenswert?

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 )-:

von Tobias B. (Firma: www.elpra.de) (ttobsen) Benutzerseite


Lesenswert?

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.

von Duke Scarring (Gast)


Lesenswert?

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

von -gb- (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.