01signal.com

How-To: Partielle Rekonfiguration mit Vivado

Einführung

Dies ist der zweite Beitrag in einer vierteiligen Serie über partielle Rekonfiguration (Partial Reconfiguration) beziehungsweise Dynamic Function eXchange (DFX) mit Xilinx' Vivado. Dieser Beitrag soll die Schritte zur Aktivierung der partiellen Rekonfiguration in einem FPGA-Design erläutern. Es empfiehlt sich, den ersten Beitrag zu lesen, falls Sie das nicht schon getan haben, denn dort werden die Konzepte hinter diesen Schritten erklärt.

Xilinx hat die partielle Rekonfiguration (Partial Reconfiguration) im Jahr 2020 in „Dynamic Function eXchange“ (DFX) umbenannt. DFX ist der Ausdruck, der in Vivados Menüs und Hinweistexten verwendet wird. Der technische Begriff „Partielle Rekonfiguration“ wird hier trotzdem benutzt.

Der Einfachheit halber wird in diesem Beitrag angenommen, dass das Projekt nur eine rekonfigurierbare Partition enthält. Die Erweiterung auf mehrere Partitionen ist relativ unkompliziert.

Das hier beschriebene Verfahren beginnt bevor das Projekt für partielle Rekonfiguration aktiviert wurde. Grob zusammengefasst sind die Schritte:

Vorbereitung für das Floorplanning

Mehr als jede andere Aufgabe erfordert das Floorplanning Denkarbeit. Es ist eine feine Balance zwischen dem Vermeiden von verschwendeter FPGA-Fläche und der Gewissheit, dass weder die statische Partition noch die rekonfigurierbaren Partitionen beim Platzieren und Verdrahten (Place and Route) vor größeren Hindernissen stehen.

Entsprechend widmet sich der Großteil dieses Beitrags genau diesem Thema.

In der fernen Vergangenheit war Floorplanning eine Technik, um die Timing-Constraints einzuhalten (Timing Closure). Es half den Tools, die Logik sinnvoll anzuordnen. Da die FPGA-Design-Tools im Laufe der Zeit immer besser geworden sind, ist es viele Jahre her, seit ich zuletzt gesehen habe, dass Floorplanning tatsächlich zum Erreichen der Timing-Constraints beigetragen hat. Heutzutage ist die beste Strategie fast immer, die Entscheidungen den Tools zu überlassen.

Bei der partiellen Rekonfiguration ist Floorplanning jedoch ein Muss. Das Ziel ist also, nichts schlimmer zu machen. Das ist meist eine Sache von Versuch und Irrtum. Der einfachste Weg zu guten Ergebnissen ist jedoch, zunächst eine Implementierung des Designs ohne Floorplanning durchzuführen und dann von der natürlichen Platzierung der Logik auszugehen. Im nächsten Schritt versucht man, die Bereiche so zu organisieren, dass es im Sinne der partiellen Rekonfiguration Sinn ergibt – mit der ursprünglichen Platzierung der Logik als Leitlinie.

Im Plugin-Nutzungsszenario kann das Floorplanning angepasst werden, während sich das Projekt im Laufe der Zeit weiterentwickelt. Das gilt jedoch nicht für das Remote-Update-Szenario, also wenn partielle Rekonfiguration dazu dient, Versionen eines bereits freigegebenen Designs zu aktualisieren: Beim Remote Update müssen alle partiellen Bitströme zum initialen Bitstrom passen. Dementsprechend ist der Teil des Designs mit statischer Logik eingefroren, sobald der initiale Bitstrom freigegeben wurde. Das bedeutet unter anderem, dass auch das Floorplanning unverändert bleiben muss.

Schon bevor man mit der partiellen Rekonfiguration beginnt, besteht die erste Aufgabe also darin, einen geeigneten Bereich im FPGA für die statische Logik zu finden. Es hat keinen Sinn, zu viel Zeit darauf zu verwenden – es reicht, einen Ausgangspunkt zu haben, mit dem man weitermachen kann, nachdem das Projekt in zwei Teile aufgeteilt wurde.

Lassen Sie sich nicht verwirren: Der Zweck dieses ersten Schritts ist nicht das Floorplanning an sich, sondern zu sehen, wie Vivado die Logik ohne Einschränkungen platziert, um daraus abzuleiten, welcher Bereich für die statische Logik reserviert werden soll. Die Schritte sind also:

Ein Projekt für partielle Rekonfiguration einrichten

Xilinx' UG909 schlägt zwei Arbeitsabläufe für die partielle Rekonfiguration vor:

Ich verwende hier den Project-Flow, auch wenn er einige Einschränkungen hat, von denen manche die Art der Quellen im rekonfigurierbaren Modul betreffen (insbesondere bei der Verwendung von Blockdesigns). Wie auch immer, es ist besser, mit dem Project-Flow zu beginnen, denn die dabei erzeugten Skripte für die Implementierung sind eine gute Grundlage für den Non-Project-Flow, falls dieser später benötigt wird.

Das sind die Schritte, um die Unterstützung für partielle Rekonfiguration in einem bestehenden Projekt zu aktivieren:

Der Versuch, in diesem Stadium eine Implementierung des Projekts durchzuführen, schlägt höchstwahrscheinlich mit einem Fehler fehl, der etwa so aussieht: „[DRP HDPR-30] Missing PBLOCK On Reconfigurable Cell: HD.RECONFIGURABLE cell 'pr_block_ins' must have PBLOCK assigned to itself or its descendant cells“. Einfach ausgedrückt bedeutet das, dass ein Floorplanning nötig ist.

Floorplanning durchführen

In diesem Stadium ist das Projekt gerade so weit eingerichtet, dass die Floorplanning-Aufgabe durchgeführt werden kann.

Bevor wir diese Aufgabe in kleine Schritte zerlegen, sind ein paar Dinge zu beachten:

Nun zu den Schritten:

Floorplanning korrigieren

Das ist wahrscheinlich der unangenehmste Teil der partiellen Rekonfiguration: das Floorplanning richtig hinzubekommen. Wenn Sie das für den Remote-Update-Einsatzzweck tun, ist diese Phase besonders wichtig, denn dieses Floorplanning bleibt während der gesamten Lebensdauer des Projekts bestehen.

Korrekturen am Floorplanning sind aus zwei Hauptgründen nötig: als Reaktion auf kritische Warnungen und in einer späteren Phase zur Optimierung der FPGA-Ausnutzung. Das Ziel ist, die Verschwendung von Ressourcen zu reduzieren und gleichzeitig Hindernisse für die Platzierung und Verdrahtung zu vermeiden.

Änderungen sind nicht schwierig, denn die Grenzen eines Pblocks lassen sich leicht verschieben. Man kann einen Pblock auch um weitere Rechtecke erweitern: Mit der rechten Maustaste auf den Pblock klicken und „Add Pblock Rectangle“ wählen.

Die kritischen Warnungen sagen oft, welche Korrekturen nötig sind. Lesen Sie trotzdem das jeweils relevante Kapitel (6, 7 oder 8) in Xilinx' Benutzerhandbuch UG909 zu den Einschränkungen des Floorplannings für Ihr FPGA.

Der Rest dieses Abschnitts behandelt mögliche Probleme mit Series-7-FPGAs. Ultrascale-FPGAs sind deutlich einfacher zu handhaben.

Ein häufiger Fehler bei Series-7-FPGAs ist die Aufteilung von Interconnect-Tile-Spalten, zum Beispiel:

[Constraints 18-993] The Pblock pblock_pr_block_ins has defined an area that causes the splitting of interconnect tile columns. Dynamic Function eXchange requires that the left and right paired interconnect tile columns cannot be split by a reconfigurable boundary.  This is caused by either the left or right edge of a Pblock boundary, or by the Pblock spanning over logic types not included in the Pblock ranges.  To avoid an unroutable situation, placement will be prohibited from both of these columns. To avoid placement restrictions, modify the Pblock to avoid splitting the two columns.
The column of the split contains interconnect tile INT_L_X48Y299  (SLICE_X79Y299 SLICE_X78Y299).
Please refer to the Xilinx document on Dynamic Function eXchange.
Resolution: Set the Pblock property SNAPPING_MODE to value of ON, or modify the column/X specification of the pblock to avoid this edge.

und

[Constraints 18-996] The split between the left and right columns occurs between a reconfigurable Pblock and Static logic. The static sites are not reconfigurable. The Pblock should be adjusted to remove the column from the Pblock, unless the excluded reconfigurable and static sites are not needed for the design. Note that adjusting the Pblock will prevent prohibits and improve placement of the design, but may reduce the routability if the removed sites were needed to span across the static logic. Failure to modify the Pblock may lead to an unplaceable design if these prohibited sites are required by the design. Resolution: Set the Pblock property SNAPPING_MODE to value of ON, or modify the column/X specification of the pblock to avoid this edge. and

Um das zu beheben, setzen Sie die SNAPPING_MODE-Eigenschaft des Pblocks auf ROUTING oder ON (die Chancen stehen gut, dass ROUTING nicht ausreicht, also wählen Sie ON), wie in der ersten Warnung vorgeschlagen. Dadurch werden der XDC-Datei wahrscheinlich viele Constraints hinzugefügt, etwa dieser Art:

set_property PROHIBIT true [get_sites SLICE_X79Y349]
set_property PROHIBIT true [get_sites SLICE_X78Y349]
[ ... ]
set_property PROHIBIT true [get_sites SLICE_X79Y191]
set_property PROHIBIT true [get_sites SLICE_X78Y191]
set_property PROHIBIT true [get_sites PMV_X0Y2]
set_property PROHIBIT true [get_sites SLICE_X36Y190]
set_property PROHIBIT true [get_sites SLICE_X37Y190]
[ ... ]
set_property PROHIBIT true [get_sites SLICE_X79Y176]
set_property PROHIBIT true [get_sites SLICE_X78Y176]
set_property PROHIBIT true [get_sites T14]
set_property PROHIBIT true [get_sites R15]
set_property PROHIBIT true [get_sites XADC_X0Y0]
set_property PROHIBIT true [get_sites SLICE_X36Y175]
set_property PROHIBIT true [get_sites SLICE_X37Y175]
[ ... ]

und so weiter.

Die PROHIBIT-Einstellungen für die Slice-Sites sind diejenigen, die die genannte Critical Warning zum Schweigen bringen. Die übrigen PROHIBIT-Zuweisungen werden für Logik-Sites hinzugefügt, die zwar im geometrischen Bereich liegen, aber auf dem verwendeten FPGA für partielle Rekonfiguration nicht zulässig sind. Ultrascale-FPGAs und neuere erzeugen deutlich weniger PROHIBIT-Zeilen, wenn überhaupt.

Wenn es nur darum geht, die Critical Warning zu unterdrücken, kann man vermutlich alle PROHIBIT-Zeilen entfernen und eine einzige Zeile für die Slice-Sites stehen lassen. Dazu deckt man den Bereich von Slices ab, den Vivado als Reaktion auf die Änderung von SNAPPING_MODE hinzugefügt hat. Verwandeln Sie diesen Bereich also in etwas wie:

set_property PROHIBIT true [get_sites -range {SLICE_X79Y0 SLICE_X79Y349}]

Eine solche Zeile in der XDC-Datei kann das Problem mit der Aufteilung der Interconnect-Spalten lösen, ohne die Datei riesig zu machen.

Unabhängig davon kann auch eine Zeile dieser Art in der XDC-Datei auftauchen. Auch diese Zeile zu entfernen ist offenbar in Ordnung:

set_property HD.PLATFORM_WRAPPER true [get_cells pr_block_ins]

Die XDC-Datei auf das Minimum zu reduzieren, das die Critical Warnings unterdrückt, mag oberflächlich wirken. Die Alternative ist jedoch eine riesige Constraint-Datei, die später nur für Verwirrung sorgt. Meiner Erfahrung nach kann das Fehlen von Warnungen dieser Art als Bestätigung gewertet werden, dass der Floorplan des Designs in Ordnung ist.

Es ist wahrscheinlich, dass das Zurücksetzen der SNAPPING_MODE-Eigenschaft auf OFF unabhängig von den Änderungen an der XDC-Datei wieder Probleme verursacht.

Ein rekonfigurierbares Modul hinzufügen

Bisher erreicht die Implementierung praktisch dasselbe wie ein hierarchisches Design, nur mit ein paar zusätzlichen Einschränkungen. Obwohl ein partieller Bitstrom erzeugt wird, ist er ziemlich nutzlos, denn beim Laden bleibt das Design unverändert.

Das Ziel ist es also, einen weiteren partiellen Bitstrom zu erzeugen, der auf einem anderen rekonfigurierbaren Modul basiert. Dazu muss eine Child-Implementierung hinzugefügt werden.

Vergewissern Sie sich, dass Sie den vorherigen Beitrag frisch im Kopf haben, bevor Sie weiterlesen – insbesondere den Teil über Parent- und Child-Implementierungen sowie den Dynamic Function eXchange Wizard. Erinnern Sie sich außerdem an das, was weiter oben in diesem Beitrag gesagt wurde: Der Reiter „Partition Definitions“ enthält die aktuell definierten rekonfigurierbaren Module und ihre Quellen.

Öffnen Sie den Dynamic Function eXchange Wizard über das Menü Tools und klicken Sie im Willkommensfenster auf Next.

Klicken Sie im Fenster Edit Reconfigurable Modules auf „+“. Dadurch öffnet sich ein Dialog zum Hinzufügen eines rekonfigurierbaren Moduls. Das einzig Interessante an diesem Dialog ist der Name des rekonfigurierbaren Moduls (Reconfigurable Module Name): Das ist der Name, mit dem die rekonfigurierbare Logik identifiziert wird, wie oben bereits erklärt.

Der Dialog verlangt außerdem, dieses Modul mit dem Namen einer Partition Definition zu verknüpfen. Es gibt aber ohnehin nur eine solche Definition (weil dieser Beitrag annimmt, dass nur eine Partition definiert ist).

Mindestens eine Verilog-/VHDL-Quelldatei muss hinzugefügt werden, um fortzufahren: Weitere können später über den Reiter „Partition Definitions“ ergänzt werden. Es schadet nicht, den Namen des Top-Level-Moduls dieses rekonfigurierbaren Moduls anzugeben, insbesondere wenn er aus den Quelldateien selbst nicht hervorgeht.

Zurück im Wizard: Klicken Sie erneut auf Next, zum Fenster Edit Configurations. Klicken Sie auf „+“ und geben Sie einen Konfigurationsnamen ein. Dieser Name ist nur insofern wichtig, als er im Fenster Design Runs erscheint. Ein Name wie config_2 ist in Ordnung.

In der Liste der Konfigurationen erscheint eine neue Zeile. Ändern Sie das rekonfigurierbare Modul in der Spalte für die Partition so, dass jede Konfiguration ein anderes rekonfigurierbares Modul hat.

Das letzte Fenster ist Edit Configuration Runs und dient dazu, Runs Konfigurationen zuzuordnen. Der einfache Weg ist, alle in diesem Fenster aufgeführten Runs zu löschen (falls vorhanden) und auf „automatically create configuration runs“ zu klicken. Das bewirkt, was man ohnehin manuell tun würde: einen Parent-Run anlegen und ihn „impl_1“ nennen, dann Child-Runs anlegen, nach Belieben benennen und sie zu Kindern von „impl_1“ machen.

Der Wizard wählt für jeden Run eine Konfiguration aus – das lässt sich aber leicht ändern. Das einzig Wichtige ist, welche Konfiguration dem Parent-Run zugeordnet ist.

Übrigens: Wenn Sie im Wizard alle Runs löschen, verschwinden alle Child-Runs, aber impl_1 bleibt erhalten.

Endlich: Implementierung des Designs

Zum Erzeugen der Bitströme klicken Sie einfach wie gewohnt auf „Generate Bitstreams“ in Vivado. Wie bereits im vorherigen Beitrag erwähnt, werden bei einem Projekt mit partieller Rekonfiguration für jede Konfiguration zwei oder drei Bitströme erzeugt.

Bei einem Ultrascale-FPGA können die Bitfiles zum Beispiel sein:

Beachten Sie, dass für alle Implementierungen dieselbe Anzahl an Bitstrom-Dateien erzeugt wird. Mit anderen Worten: Auch für die Child-Implementierungen wird eine initiale Bitstrom-Datei erzeugt. Es ist also ohne Weiteres möglich, das FPGA mit einem der initialen Bitströme einer Child-Implementierung zu laden und von dort aus weiterzumachen.

Für einen einfachen Weg, partielle Bitströme über PCIe oder USB 3.x zu laden, siehe diese Seite.

Keine der Implementierungen sollte Critical Warnings aufweisen oder wegen Beschwerden über den Pblock bzw. das Floorplanning im Allgemeinen fehlschlagen, denn solche Probleme sollten bereits gelöst sein. Sollte so etwas trotzdem passieren, muss das Floorplanning wie oben beschrieben korrigiert werden.

Manchmal kann es vorkommen, dass Vivado beim Klicken auf „Generate Bitstream“ – wenn nur an den Child-Implementierungen Änderungen vorgenommen wurden – antwortet: „Bitstream generation has already completed and is up-to-date. Re-run anyway?“. Das ist etwas verwirrend, aber ein Klick auf „Yes“ führt die Child-Implementierungen ordnungsgemäß aus. Diese ganze Sache mit der Child-Implementierung ist ein kleines Add-on zu Vivado, weshalb in der Statuszeile während der Implementierung auch so etwas wie „write_bitstream complete. Child running“ steht.

Die Ergebnisse überprüfen

Da es bei der partiellen Rekonfiguration stark um Platzierung geht, ist es eine gute Idee, die implementierten Designs zu überprüfen. Sie können eine bestimmte Implementierung öffnen, indem Sie mit der rechten Maustaste auf „Open Implemented Design“ klicken und dann mit der Maus über den Menüpunkt „Open Implemented Design“ (erneut) fahren. Wählen Sie dann aus der Liste die zu öffnende Implementierung aus. Wenn eine Implementierung in der Liste fehlt, ist sie vermutlich bereits geöffnet.

Versuchen Sie, im Bereich Netlist der Implemented-Design-Ansicht mit der rechten Maustaste auf die oberste Zeile der rekonfigurierbaren Logik zu klicken und „Highlight Leaf cells“ zu wählen. Machen Sie dasselbe dann mit der statischen Logik, in einer anderen Farbe.

Mit demselben Rechtsklick gibt es auch „Show Connectivity“. Damit werden gerade weiße Linien zwischen verbundenen Logikelementen gezeichnet. Die tatsächlichen Routing-Pfade auf dem FPGA sind natürlich anders, daher hat es keine Bedeutung, welche Floorplanning-Bereiche diese Linien kreuzen. Die Betrachtung der Verbindungen kann aber trotzdem helfen zu erkennen, wenn die Gesamtorganisation eines Floorplans den Tools das Leben schwer macht.

Es ist völlig normal und in Ordnung, dass einige Zellen, die offenbar zur statischen Logik gehören, innerhalb des rekonfigurierbaren Bereichs platziert sind – und umgekehrt. Worauf man achten sollte, ist, ob es irgendwo eine Überlastung zu geben scheint, also ob die Logik allgemein oder in einer bestimmten Region zu dicht gepackt ist. Falls möglich, können Änderungen am Floorplanning das verbessern.

Ein weiterer Punkt sind die Positionen der Partition Pins. Sie erscheinen als weiße horizontale Balken in der Device-Ansicht, etwa so (Bild zum Vergrößern anklicken):

Partition pins in Vivado's device view

Wie bereits im vorherigen Beitrag erwähnt, können sich Partition Pins überall innerhalb der rekonfigurierbaren Partition befinden. Wenn die Partition Pins jedoch weit von den Rändern der Partition entfernt liegen, kann das darauf hindeuten, dass der Router während der Parent-Implementierung mit dem Timing zu kämpfen hatte.

Eine Textliste mit den Koordinaten der Partition Pins erhalten Sie mit diesem Tcl-Befehl (ändern Sie pr_block_ins in den Namen der rekonfigurierbaren Logikzelle):

foreach s [get_pins -of [get_cells pr_block_ins]] { set partpin [get_pplocs -quiet -pins [get_pins $s]] ; puts "$s => $partpin"; }

Die Koordinaten der Partition Pins entsprechen dem Raster der CLBs (und nicht dem der Slices). In der angezeigten Zeichnung werden diese Pins als „Cell pins“ bezeichnet.

Einige Pins der Zelle haben möglicherweise keinen Partition Pin zugewiesen. Das passiert, wenn die Portliste des rekonfigurierbaren Moduls (und/oder die Breiten von Vektoren) nicht zu seiner Instanziierung durch die statische Logik passt. Eine solche Diskrepanz ist in Verilog völlig legal, aber das Ergebnis kann unerwünscht sein. Mit diesem Tcl-Befehl lassen sich solche unerreichbaren Ports erkennen, insbesondere wenn das nicht beabsichtigt ist.


Damit endet der technische Teil zum Einrichten des Vivado-Projekts. Der nächste Beitrag behandelt jedoch einen wichtigen Aspekt des FPGA-Designs: Wie man sicherstellt, dass der Austausch von Logik zuverlässig und reibungslos abläuft.

Diese Seite wurde maschinell aus dem Englischen übersetzt. Im Zweifelsfall siehe den Originaltext.
Copyright © 2021-2026. All rights reserved. (dcc38493)