VHDL: Verwenden des Operators „*“ beim Implementieren von Multiplikatoren im Design

Heutige FPGAs haben eingebaute DSP-Blöcke, die neuesten FPGAs haben sogar eingebaute IEEE-754-konforme Gleitkommaeinheiten.

Es ist möglich, eine DSP-Entität/ein DSP-Modul unter Verwendung einer GUI zu erstellen, nachdem die erforderlichen Parameter darin ausgewählt und dann im Design instanziiert wurden.

Wann müssen wir ein solches Mikromanagement in einem Design zur Instanziierung tatsächlicher DSP-Blöcke durchführen, und wann geben wir einfach einen '*'-Operator in den Code ein und überlassen es dem Synthesetool, die Details auf niedriger Ebene zu verarbeiten? Welches ist besser?

Es gibt viele verschiedene Arten von Multiplikationsalgorithmen, wenn es um binäre Multiplikation geht. Seitdem wir DSP-Blöcke auf Silizium und sogar Gleitkommamultiplikatoren eingebaut haben, bedeutet das, dass all diese Algorithmen nicht effektiv veraltet sind.

Welches FPGA hat 754-konforme FPUs im Fabric?

Antworten (5)

Ich habe das selbst ein paar Mal gemacht.

Im Allgemeinen wählen die Design-Tools basierend auf den Syntheseeinstellungen zwischen einer Fabric-Implementierung und einem DSP-Slice.

Zum Beispiel gibt es für Xilinx ISE in den Syntheseprozesseinstellungen, HDL-Optionen, eine Einstellung „-use_dsp48“ mit den Optionen: Auto, AutoMax, Yes, No. Wie Sie sich vorstellen können, steuert dies, wie hart die Tools versuchen, zu platzieren DSP-Slices. Ich hatte einmal ein Problem, bei dem ich eine Ganzzahl mit 3 multiplizierte, was auf einen DSP-Slice schloss - außer dass ich bereits jeden DSP-Slice im Chip manuell abgeleitet hatte, sodass der Synthesizer ausfiel! Ich habe die Einstellung auf Nein geändert, da ich bereits jedes DSP-Slice verwendet habe.

Dies ist wahrscheinlich eine gute Faustregel (ich habe mir gerade ausgedacht): Wenn Ihr Design mit weniger als 50 MHz getaktet ist und Sie wahrscheinlich weniger als 50% der DSP-Slices im Chip verwenden werden, verwenden Sie einfach die *, + und - Operatoren. dies wird DSP-Slices ohne Pipeline-Register ableiten. Das schränkt die Höchstgeschwindigkeit stark ein. (Ich habe keine Ahnung, was passiert, wenn Sie Division verwenden)

Wenn es jedoch so aussieht, als würden Sie die Slices näher an der maximalen Geschwindigkeit des DSP-Slices (333 MHz für Spartan 6 mit normaler Geschwindigkeit) ausführen, wenn Sie alle Slices verwenden werden, sollten Sie sie manuell ableiten .

In diesem Fall haben Sie zwei Möglichkeiten.

Option 1: Verwenden Sie manuell die rohe DSP-Instanziierungsvorlage. Option 2: Verwenden Sie einen IP-Block von Xilinx Core Generator. (Ich würde diese Option verwenden. Gleichzeitig erfahren Sie alles über Core Gen, was in Zukunft hilfreich sein wird.)

Bevor Sie dies tun, lesen Sie die ersten paar Seiten des DSP-Slice-Benutzerhandbuchs. Im Fall von Spartan 6 (DSP48A1) wäre das Xilinx doc UG389: http://www.xilinx.com/support/documentation/user_guides/ug389.pdf

Betrachten Sie zuerst die Core-Generator-Option. Normalerweise erstelle ich in Core Generator ein Testprojekt für den Teil, mit dem ich arbeite, wo ich eine beliebige Anzahl von IP-Blöcken erstelle, nur um das System kennenzulernen. Wenn ich dann bereit bin, einen zu meinem Design in ISE hinzuzufügen, klicke ich mit der rechten Maustaste in die Designhierarchie, klicke auf Neue Quelle und wähle „IP (CORE Generator & Architecture Wizard)“, damit ich den Block direkt bearbeiten und neu generieren kann aus meinem Projekt.

Werfen Sie in Core Gen einen Blick auf die verschiedenen IP-Blöcke, aus denen Sie wählen können – es gibt ein paar Dutzend, von denen die meisten ziemlich cool sind.

Der Multiplikatorkern ist das, was Sie sich zuerst ansehen sollten. Schauen Sie sich jede Seite an und klicken Sie auf die Schaltfläche „Datenblatt“. Die wichtigen Teile sind die ganzzahligen Bitbreiten, die Pipeline-Stufen (Latenz) und alle Steuersignale. Dies erzeugt den einfachsten möglichen Block, indem alle Ports entfernt werden, die Sie nicht benötigen.

Als ich letztes Jahr einen IIR-Filter der Ordnung 5 x 3 erstellte, musste ich die manuelle Instanziierungsvorlage verwenden, da ich eine sehr benutzerdefinierte Implementierung erstellte, bei der 2 DSP-Slices 4x schneller als die Abtastrate getaktet wurden. Es war ein totaler Schmerz.

Wenn Sie nur zwei Zahlen multiplizieren möchten und sie zum DSP-Block passen *, sollte der Operator auf einen DSP-Block schließen. Wenn nicht, senden Sie das Synthesetool zurück :)

Um jedoch die komplexeren Kombinationen der DSP-Funktionalität nutzen zu können, ist häufig eine direkte Instanziierung des Blocks und eine Konfiguration seiner Parameter erforderlich. Beispiele für Dinge, die durch Schlussfolgerung möglicherweise nicht gut abgebildet werden (am Beispiel des Xilinx DSP48E1 ):

  • Verwendung eines Voraddierers
  • Nutzung des Nachspeichers
  • Verwendung eines Musterdetektors
  • Verwendung der Logikeinheit

Und insbesondere Kombinationen der oben genannten.

Die Synthesewerkzeuge sind noch nicht gut genug, um völlig beliebige Kombinationen aus Logik und Arithmetik so effizient abzubilden, wie man es sich erhofft.

Wenn DSP-Blöcke vorhanden sind, sollten Sie sie verwenden, wenn Sie können, da dies effizienter ist, als LUTs zu verwenden, um dasselbe zu tun. Es sei denn, Sie benötigen keine Hochleistungsmultiplikation. In diesem Fall sollten Sie beispielsweise einen Pipeline-Addierer und ein Schieberegister implementieren, um Platz zu sparen.

Ich würde mir jedoch das Ableiten von DSP-Blöcken ansehen, bevor ich auf die GUI-Tools eingehe. Das Xilinx XST-Handbuch enthält HDL-'Rezepte' zum Instanziieren von DSP-Blöcken mit reinem Verilog/VHDL. Wenn Sie genügend Register vor und/oder nach den Multiplikatoren hinzufügen, verwendet XST grundsätzlich einen DSP-Block, um die Operation automatisch zu implementieren. Sie können in den Syntheseprotokollen nachsehen, ob die DSP-Blöcke korrekt abgeleitet werden. Ich nehme an, Altera hat etwas Ähnliches.

Übrigens habe ich gerade vor ein paar Minuten darüber nachgedacht, da ich gerade an einer Mersenne-Twister-Implementierung arbeite, die nur einen Multiplikator für den anfänglichen Seed verwendet. Meine First-Pass-Implementierung entspricht nicht dem Timing, aber die Funktionalität ist korrekt. XST hat auch die Multiplikationsoperation in DSP-Blöcke eingefügt, sie ist jedoch nicht optimiert, sodass sie etwa halb so schnell läuft, wie ich möchte. Ich werde das Multiplizieren wahrscheinlich mit einer Shift-and-Add-Technik neu implementieren, die die 32-fache Anzahl von Taktzyklen benötigt, aber keinen Hardware-Multiplikator mehr benötigt.

Warum sollte das Timing fehlschlagen, wenn ein Hardware-Multiplikator verwendet wird?
Die 32-Bit-mal-32-Bit-Multiplikation ohne Pipeline dauert anscheinend mehr als 8 ns.
hmm verstehe, nicht bedacht. Die DSP-Blöcke werden also nicht gepipelinet. Ich frage mich, wie genau sie die Multiplikation implementieren. Ist es ein tatsächlich harter paralleler Multiplikator?
Ich denke, es kann so konfiguriert werden, dass es auf verschiedene Arten funktioniert. Laut dem XST-Handbuch ermöglicht das Hinzufügen von genügend Registern am Eingang und am Ausgang XST, einen Pipeline-Multiplikator in einem DSP48-Slice zu verwenden. In meinem Fall gab es nur ein Ausgangsregister und keine Eingangsregister, sodass dies nicht genutzt werden konnte. Da dies nur zur Initialisierung (Seeding des PRNG) diente, habe ich die parallele Multiplikation durch einen bitseriellen Multiplikator ersetzt, um die Ressourcennutzung zu sparen.

Es hängt davon ab, wie viel Optimierung Sie benötigen und wie tragbar Ihr Design sein soll. Es ist ein bisschen wie Software, die durch ein bisschen Assemblieren optimiert wird oder den Compiler die Anweisungen auswählen lässt. Möglicherweise müssen Sie auch einige Kompromisse zwischen Größe und Geschwindigkeit eingehen, sodass Sie sich keinen kombinatorischen Multiplikator mit doppelter Genauigkeit leisten können.

Ich wusste nicht, wo fest verdrahtete FP-Multiplikatoren in FPGAs sind.

Ein tatsächlicher IEEE P754-konformer Multiplikationsoperator, der für eine CPU geeignet ist, beinhaltet mehr als einen großen Multiplikator: Sie müssen die Exponenten addieren, Denormale verschieben, Unendlichkeiten und ein paar meist nutzlose Flags (ungenau, Unterlauf ...) verwalten.

Die FPGAs der neuesten Generation wie die Altera 10-Serie haben IEEE-754-konforme Gleitkommamultiplikatoren auf der Hardware selbst! Ich hatte jedoch keine Gelegenheit, sie selbst zu verwenden.
Wenn wir DSP-Blöcke eingebaut haben, sollte FPGA sie anstelle des kombinatorischen Multiplikators verwenden oder einen anderen Algorithmus verwenden, der zB Speicherblöcke verwendet, richtig?

Ich habe dieses Dokument gelesen http://www2.warwick.ac.uk/fac/sci/eng/staff/saf/papers/fpl2014-ronak.pdf :

Während Funktionen, die in einen einzelnen DSP-Block passen, effizient aus Pipeline-RTL-Code synthetisiert werden können, haben wir festgestellt, dass komplexere Funktionen, die mehrere DSP-Blöcke erfordern, unter einer geringeren Leistung leiden. Eine standardmäßige RTL-Beschreibung einer mathematischen Funktion kann stark gepipelinet werden, zum Beispiel nach jeder Operation, da diese Pipelining jedoch möglicherweise die Struktur und die internen Stufen des DSP-Blocks nicht berücksichtigt, kann das resultierende synthetisierte Design eine unter dem Standard liegende Leistung aufweisen Die DSP-Blöcke sind so kombiniert, dass sie nicht mit voller Geschwindigkeit laufen können.

Ich wünschte, ich könnte die Quelle ihrer Werkzeuge finden, um ihre Ergebnisse zu überprüfen.