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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Gustl B. (-gb-)


Bewertung
0 lesenswert
nicht 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


Bewertung
1 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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-)


Bewertung
0 lesenswert
nicht 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


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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 Markus W. (elektrowagi78) Benutzerseite


Bewertung
0 lesenswert
nicht 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)


Bewertung
2 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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 Markus W. (elektrowagi78) Benutzerseite


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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-)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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-)


Bewertung
0 lesenswert
nicht 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


Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.