Ich habe eine besonders große Signalverarbeitungstransformation, die von Matlab nach VHDL portiert werden muss. Es erfordert definitiv eine Art Ressourcenteilung. Ein bisschen rechnen hat mir folgendes gebracht:
Wenn man bedenkt, dass das größte Virtex 6 FPGA ungefähr 2000 DSP48E-Blöcke hat, weiß ich, dass ich Ressourcen teilen kann, um die Ressourcen mehrmals wiederzuverwenden. Die Ausführungszeit ist nicht wirklich ein Problem, die Verarbeitungszeit kann in FPGA-Begriffen relativ lang dauern.
Wenn ich die Ressourcennutzung betrachte, bekomme ich mit der Radix-2 Lite-Architektur 4dsp-Blöcke/FFT-Operation = 2048 DSP-Blöcke, insgesamt ~43k. Das größte Virtex-FPGA hat 2k-Blöcke oder 20 Operationen/Mux.
Offensichtlich wird das Einfügen solch großer Muxes in den Fabric auch Slices beanspruchen. Wo finde ich das obere Ende dieser Grenze? Ich kann die FPGA-Ressourcen nicht unendlich teilen. Ist 41210 Multiplikatoren zu groß? Wie berechne ich, was zu groß ist?
Ich habe mir auch andere Ressourcen angesehen (Slices, Brams usw.). Radix-2 Lite liefert auch 4 x 18k Brams/fft = 2048 Brams. Das größte Xilinx FPGA enthält 2128 Brams. sehr grenzwertig. Ich mache mir Sorgen, dass mein Design einfach zu groß ist.
AKTUALISIEREN:
Einige weitere Informationen zum Design selbst. Ich kann nicht ins Detail gehen, aber hier ist, was ich geben kann:
Initial conditions -> 512 ffts -> 40k multipliers ---------|----> output data to host
^------re-calculate initial conditions----|
Ausgabedatenratenspezifikation: "schneller als die Matlab-Simulation"
Rechentechnisch bin ich hier:
FFT-Stufe: einfach. Ich kann 1/2/4/8 FFTs implementieren, die Ergebnisse im SDRAM speichern und später darauf zugreifen. Relativ klein, auch wenn es lange dauert, ist es ok. Mit Radix-2 Lite kann ich 2 DSP48Es und 2 18k BRAMS/FFT erhalten. Streaming ergibt 6 DSP48Es 0BRAMS/FFT. In beiden Fällen ist die 64-Punkt-FFT in Bezug auf die FPGA-Ressourcen klein.
Multiplikatoren : Das ist mein Problem. Die Multiplikationseingaben werden entweder aus Nachschlagetabellen oder FFT-Daten genommen. Es ist wirklich nur eine ganze Reihe von Multiply-Adds. Da gibt es nicht viel zu optimieren. Kein Filter, hat aber ähnliche Eigenschaften wie ein Filter.
Betrachtet man die gemeinsame Nutzung von Ressourcen auf dem FPGA, funktioniert die Mathematik wie folgt: Ein LUT-6 kann als 4-Wege-Mux verwendet werden. Die Formel für einen N-Wege-M-Bit-Mux lautet wie folgt:
N*M/3 = number of luts, or N*M/12 = slices (4 LUTS/slice).
Das Knirschen der Zahlen für meine Implementierung ergibt keine guten Ergebnisse. 90 % der virtix-6-Familie haben nicht genug Slices, um ihre DSPs gemeinsam zu nutzen, um 40.000 Operationen auszuführen.
Ich frage mich, ob es eine andere Möglichkeit gibt, das Problem zu betrachten?
Wenn Sie Ihre Schätzung von 512 FFT-Operationen (jeweils 64 Punkte) und 42.000 MAC-Operationen ausspielen ... Ich nehme an, das ist es, was Sie für einen Durchgang durch den Algorithmus benötigen?
Jetzt haben Sie einen FFT-Kern gefunden, der 4 DSP-Einheiten verwendet ... aber wie viele Taktzyklen dauert es pro FFT? (Durchsatz, nicht Latenz)? Sagen wir 64 oder 1 Zyklus pro Punkt. Dann müssen Sie diese 42.000 Mac-Operationen in 64 Zyklen abschließen - vielleicht 1.000 MACs pro Zyklus, wobei jede MAC 42 Operationen verarbeitet.
Jetzt ist es an der Zeit, sich den Rest des Algorithmus genauer anzusehen: Identifizieren Sie nicht MACs, sondern Operationen auf höherer Ebene (Filterung, Korrelation, was auch immer), die wiederverwendet werden können. Erstellen Sie Kerne für jede dieser Operationen mit Wiederverwendbarkeit (z. B. Filter mit unterschiedlichen wählbaren Koeffizientensätzen) und bald werden Sie feststellen, dass zwischen relativ großen Kernen relativ wenige Multiplexer erforderlich sind ...
Ist auch eine Kraftreduzierung möglich? Ich hatte einige Fälle, in denen Multiplikationen in Schleifen erforderlich waren, um Quadrate (und höher) zu erzeugen. Ich entrollte sie und konnte sie iterativ ohne Multiplikation generieren: Ich war an dem Tag, als ich eine Differenz-Engine auf FPGA baute, sehr zufrieden mit mir!
Ohne die Anwendung zu kennen, kann ich keine weiteren Details geben, aber eine solche Analyse wird wahrscheinlich einige wesentliche Vereinfachungen ermöglichen.
Da es sich so anhört, als hätten Sie keine bestimmte Plattform im Sinn, überlegen Sie auch, ob Sie über mehrere FPGAs partitionieren können ... werfen Sie einen Blick auf dieses oder dieses Board , das mehrere FPGAs auf einer praktischen Plattform bietet. Sie haben auch ein Board mit 100 Spartan-3-Geräten ...
(ps Ich war enttäuscht, als die Software-Jungs diese andere Frage schlossen - ich denke, es ist dort mindestens genauso angebracht)
Bearbeiten: Bezüglich Ihrer Bearbeitung - ich denke, Sie fangen an, dorthin zu gelangen. Wenn alle Multiplikatoreingänge entweder FFT-Ausgänge oder "Nicht-Filter"-Koeffizienten sind, sehen Sie allmählich die Art von Regelmäßigkeit, die Sie ausnutzen müssen. Ein Eingang jedes Multiplizierers ist mit einem FFT-Ausgang verbunden, der andere Eingang mit einem Koeffizienten-ROM (BlockRam ist als konstantes Array implementiert).
Durch Sequenzieren verschiedener FFT-Operationen durch dieselbe FFT-Einheit werden die FFT-Ausgänge automatisch an diesem Multiplikator vorbei sequenziert. Das Sequenzieren der korrekten Koeffizienten in die andere MPY-Eingabe ist jetzt "nur" eine Frage des Organisierens der korrekten ROM-Adressen zur richtigen Zeit: ein organisatorisches Problem, eher als ein großes Kopfzerbrechen von MUXen.
Zur Leistung: Ich denke, Dave Tweed war unnötig pessimistisch - die FFT nimmt n * log (n) Operationen, aber Sie können O (n) Butterfly-Einheiten und O (log N) Zyklen oder O (log N) Einheiten und O ( n) Zyklen oder eine andere Kombination, die Ihren Ressourcen- und Geschwindigkeitszielen entspricht. Eine solche Kombination kann die Post-FFT-Multiplikationsstruktur viel einfacher machen als andere ...
Wenn dieses Problem keine harten Echtzeitbeschränkungen hat und es sich so anhört, als ob es nicht so wäre – Sie möchten nur, dass es „schneller“ läuft, dann scheint es, als wäre es für die Beschleunigung auf einer oder mehreren GPUs ziemlich zugänglich. Es gibt mehrere Softwarebibliotheken, die dies zu einem relativ einfachen Vorschlag machen, und dies wäre um eine Größenordnung einfacher, als direkt zu benutzerdefinierter FPGA-Hardware zu gehen.
Googlen Sie einfach nach „GPU-fähige Bibliothek“ oder „GPU-beschleunigte Bibliothek“, um loszulegen.
Wie wenig stört uns die Ausführungszeit?
Dies scheint wirklich eine Situation zu sein, in der Sie wirklich eine Soft-MCU, ein FPGA mit einer integrierten Hard-MCU oder sogar ein separates MCU-Gerät implementieren und alle Ihre Operationen serialisieren sollten.
Vorausgesetzt, Sie haben die Ausführungszeit, ist das Ausführen Ihrer FFTs in Software sowohl viel einfacher zu debuggen als auch wahrscheinlich viel einfacher zu entwerfen.
Es ist möglich, eine spezielle Hardware oder ein FPGA (oder sogar ein CPLD) zu verwenden, um bestimmte Arten von mathematischen Operationen stark zu beschleunigen. Wenn Sie versuchen, Hardware (Schaltkreise oder FPGA-Logik) zu entwerfen, um mathematische Operationen zu beschleunigen, müssen Sie unbedingt herausfinden, welche Auftragsdaten in Ihr Gerät ein- und ausgehen müssen. Ein Gerät mit einem effizienten E/A-Layout bietet möglicherweise eine viel bessere Leistung als eines mit einem ineffizienten Layout, selbst wenn das letztere Gerät viel mehr Schaltungen erfordert.
Ich habe nicht versucht, ein hardwareunterstütztes Design für eine FFT auszuarbeiten, aber eines, das ich mir angesehen habe, ist die Hardwareunterstützung für große Multiplikationsoperationen (wie sie für die RSA-Verschlüsselung verwendet werden könnten). Viele Mikrocontroller, selbst solche mit spezieller Schnellmultiplikationshardware, sind bei solchen Operationen nicht besonders effizient, da sie eine Menge Register-Shuffling erfordern. Hardware, die entwickelt wurde, um das Austauschen von Registern zu minimieren, könnte mit multipräzisen Multiplikationsoperationen eine viel bessere Leistung erzielen, selbst wenn die Hardware selbst nicht so ausgefeilt wäre. Zum Beispiel kann Hardware, die eine 16xN-Multiplikation im Pipeline-Verfahren mit jeweils zwei Bits gleichzeitig durchführen kann (Verschieben von zwei unteren Bits von Multiplcand und Herausschieben von zwei oberen Bits des Ergebnisses), eine bessere Leistung erzielen als Hardware, die eine 8x8-Multiplikation in einem Zyklus durchführen kann. obwohl erstere möglicherweise weniger Schaltkreise benötigen (und aufgrund von Pipelining einen kürzeren kritischen Datenpfad haben). Der Schlüssel liegt darin, herauszufinden, wie die „innere Schleife“ des erforderlichen Codes aussehen wird, und herauszufinden, ob es Ineffizienzen gibt, die leicht beseitigt werden können.
Chris Stratton
Das Photon
Gustavo Litowski
Stanri
Das Photon
Das Photon
Stanri
Das Photon
Stanri
Stanri
Das Photon
David Tweed
Kortuk
shuckc
mult_in <= mux[n]
won
in jedem Zyklus um eins erhöht wird, massiv minimiert werden kann.