01signal.com

Partielle Rekonfiguration mit Xilinx: Zurücksetzen und Entkopplung

Dies ist der dritte Beitrag in einer vierteiligen Serie über partielle Rekonfiguration (Partial Reconfiguration), auch Dynamic Function eXchange (DFX) genannt, mit Xilinx' Vivado. Während die beiden vorherigen Beiträge zeigen, wie man das FPGA-Design einrichtet, geht es hier darum, wie die statische Logik damit umgehen kann, dass die rekonfigurierbare Logik verschwindet und wieder erscheint.

Überblick

Das Laden eines partiellen Bitstroms (Bitstream) ähnelt dem Austausch physischer Hardware im laufenden Betrieb (Hot Swapping): Ein bestimmtes Teil wird abrupt entfernt, durch ein anderes ersetzt und wieder in Betrieb genommen. Dieser Beitrag behandelt die Mittel, die erforderlich sind, damit dieser Übergang reibungslos und zuverlässig abläuft.

Dieser Beitrag geht davon aus, dass die partielle Rekonfiguration von der statischen Logik auf dem FPGA selbst durchgeführt wird. Für einen reibungslosen Ablauf sollte sie in den folgenden Stufen erfolgen (Erklärungen folgen):

Warum Entkopplung nötig ist

Während des Ladens des partiellen Bitstroms befinden sich die Verbindungen zwischen der statischen und der rekonfigurierbaren Logik in einem unvorhersehbaren Zustand. Infolgedessen können die Ausgangsports des rekonfigurierbaren Moduls zufällige Muster oder unzulässige Werte erzeugen. Das passiert nicht unbedingt ständig an jedem Ausgangsport, aber die Chancen stehen gut, dass irgendein merkwürdiges Verhalten zu beobachten ist.

Da die statische Logik unabhängig vom Laden des partiellen Bitstroms weiterarbeitet, müssen die unvorhersehbaren Signale, die vom rekonfigurierbaren Modul kommen können, ignoriert werden, um unerwünschte Auswirkungen zu vermeiden. Xilinx' Benutzerhandbuch UG909 bezeichnet das als Entkopplung (Decoupling).

Wie die Entkopplung umgesetzt wird, hängt von der Art der Ausgangsports des rekonfigurierbaren Moduls ab: Der Einfluss jedes dieser Ports auf die statische Logik sollte analysiert werden, und bei Bedarf sollten vorbeugende Maßnahmen ergriffen werden. Dazu kann gehören, die Ausgangsports während der Rekonfiguration per Multiplexer auf neutrale Werte zu schalten, an Logik, die nicht ansprechen soll, eine Taktfreigabe (Clock Enable) anzulegen oder Teile der statischen Logik im Reset zu halten.

Wenn rekonfigurierbare Logik direkt mit I/O-Pads verbunden ist, kann es nötig sein, diese in den High-Z-Zustand zu versetzen oder die Taktfreigabe (Clock Enable) der I/O-Logik zu deaktivieren, falls diese I/O-Logik ein Ausgangsregister enthält. Ist die rekonfigurierbare Logik mit externen Bauelementen verbunden, kann es außerdem erforderlich sein, diese Bauelemente vor der Rekonfiguration in einen sicheren Zustand zu bringen.

Für die Entkopplung von AXI-Verbindungen steht im IP-Katalog von Vivado ein IP-Core namens Partial Reconfiguration Decoupler zur Verfügung.

Die Eingangsports des rekonfigurierbaren Moduls benötigen keine solche Behandlung – die statische Logik stört es nicht, dass die von ihr angesteuerten Signale nicht weiterverarbeitet werden.

Bei Ultrascale-Bausteinen ist vor dem Laden von „Clearing-Bitstreams“ eine Entkopplung erforderlich, da diese die rekonfigurierbare Logik abschalten.

Ein paar Worte zur STARTUP-Sequenz

Ein wichtiger Teil des Bitstroms (sowohl des vollständigen als auch des partiellen) ist der Konfigurationsbefehl START, der die STARTUP-Sequenz anstößt. Diese Sequenz umfasst einige Mechanismen, die für ein konsistentes Hochfahren der Logik sorgen.

Der erste Teil besteht darin, dass die synchronen Elemente am Ende der Konfiguration ihre Standardwerte zugewiesen bekommen. Das gilt für Ultrascale-FPGAs und neuere immer. Bei Series-7-FPGAs gilt es für eine vollständige Konfiguration (d.h. mit einem initialen Bitstrom) und bei partieller Rekonfiguration dann, wenn RESET_AFTER_RECONFIG aktiviert ist.

Der zweite Teil ist GWE (Global Write Enable, nicht zu verwechseln mit den Freigabeeingängen synchroner Elemente oder Write-Enable-Eingängen): Dieses Signal erlaubt Flip-Flops und RAMs, ihre Werte zu ändern. Während der vollständigen Konfiguration wird GWE im gesamten FPGA auf Low gehalten und geht in einem bestimmten Schritt der Konfigurations-Startsequenz auf High. Beim Laden eines partiellen Bitstroms ist nur die neu konfigurierte Logik betroffen.

Selbstverständlich erfolgt der Wechsel von GWE asynchron zu jedem Takt, der von der Applikationslogik bereitgestellt wird. Die Timing-Beziehung zwischen diesem Wechsel und dem ersten wirksamen Takt ist daher für jedes synchrone Element unvorhersehbar.

Bei partieller Rekonfiguration bedeutet das, genau wie bei einer vollständigen Konfiguration, dass alle synchronen Elemente unmittelbar nach Abschluss des Vorgangs ihren Anfangswert haben (bei Ultrascale und neuer, oder wenn RESET_AFTER_RECONFIG gesetzt ist). Es besteht jedoch eine zufällige Möglichkeit, dass einige synchrone Elemente auf den ersten Takt der Applikationslogik reagieren und andere nicht. Dieses zufällige Verhalten hängt davon ab, wann dieser erste Takt relativ zum Wechsel von GWE auf High eintrifft. Es ist daher wichtig, alle Logik, die gegenüber einer solchen Unsicherheit empfindlich ist, ordnungsgemäß zurückzusetzen.

Die Notwendigkeit, die rekonfigurierbare Logik nach dem Laden des partiellen Bitstroms zurückzusetzen, ist dieselbe wie nach einer vollständigen Konfiguration des FPGAs. Im Fall einer vollständigen Konfiguration leuchtet die Notwendigkeit eines Resets allerdings eher ein, insbesondere weil der Reset oft aktiv gehalten wird, bis sich bestimmte Logikelemente stabilisiert haben (z.B. MMCMs oder PLLs gelockt sind, externe Hardware bereit ist usw.).

Zusammengefasst gibt es keine allgemeingültige Antwort darauf, ob die rekonfigurierbare Logik zurückgesetzt werden muss – und wenn ja, welche Teile davon. Wie bei einer vollständigen Konfiguration erhalten die synchronen Elemente ihre Standardwerte und beginnen, auf Takte zu reagieren. In manchen Situationen ist das gut genug, in anderen Szenarien ist ein Reset erforderlich.

Das Ende von STARTUP erkennen

Von den oben aufgeführten Stufen liegt nur die STARTUP-Sequenz außerhalb der Kontrolle der Applikationslogik. Es ist dennoch wichtig zu wissen, wann sie abgeschlossen ist.

Im Configuration Guide für jede FPGA-Familie gibt es eine Beschreibung der STARTUP-Sequenz. Um es kurz zu machen: Die dafür benötigte Zeit hängt stark von den Optionen des Bitstroms ab. Die Sequenz kann zum Beispiel so konfiguriert werden, dass sie auf das Locking der MMCMs wartet oder darauf, dass die DCIs ihre Impedanzanpassung abgeschlossen haben.

Das FPGA liefert ein Signal namens End Of Startup (EOS), das in der letzten Stufe der STARTUP-Sequenz (also wenn diese abgeschlossen ist) auf High geht. Sich auf EOS zu verlassen, ist der formal korrekte Weg zu erkennen, wann die rekonfigurierbare Logik wieder in Betrieb genommen werden kann, indem man einen Reset auslöst und mit der Wiedereinkopplung der Ausgangsports beginnt.

Das EOS-Signal ist nur von der Logic Fabric aus verfügbar, über eine Instanziierung (Instantiation) eines STARTUPE2-Primitivs (Primitive), etwa wie folgt:

wire eos;

STARTUPE2 #(.PROG_USR("FALSE")) startup_ins
  (
   .CLK(1'b0),
   .GSR(1'b0),
   .GTS(1'b0),
   .KEYCLEARB(1'b1),
   .PACK(1'b0),
   .USRCCLKO(1'b0),
   .USRCCLKTS(1'b0),
   .USRDONEO(1'b1),
   .USRDONETS(1'b1),
   .CFGCLK(),
   .CFGMCLK(),
   .EOS(eos),
   .PREQ());

Sobald der Bitstrom vollständig in den ICAP geladen wurde, warten Sie also darauf, dass EOS auf High geht, und beginnen Sie dann mit dem Zurücksetzen und der Wiedereinkopplung.

Ultrascale-FPGAs besitzen stattdessen ein STARTUPE3-Primitiv. Vivado akzeptiert für diese FPGAs aber auch STARTUPE2-Primitive und übersetzt sie korrekt in STARTUPE3. Das Codebeispiel oben deckt also alle FPGA-Familien ab.

Ich habe einige anekdotische Tests durchgeführt, um zu messen, wie lange es dauert, bis EOS nach dem Eintreffen des START-Befehls des Bitstroms im ICAP auf High geht.

Mit einem Kintex-7 dauerte das bei den Standardeinstellungen des Bitstroms 26 Taktzyklen (bei 100 MHz, also etwa 260 ns). Da sich im Bitstrom weitere Daten befanden, unter anderem NOPs, ist es gut möglich, dass EOS sehr bald nach dem letzten Wort des Bitstroms, das dem ICAP zugeführt wurde, auf High ging.

Derselbe Test mit einem Kintex-Ultrascale-FPGA ergab jedoch völlig andere Ergebnisse: EOS ging nach dem START-Befehl zufällig irgendwann zwischen 0,8 ms und 4,5 ms auf High.

Obwohl es ziemlich einfach ist, das STARTUPE2-Primitiv wie oben gezeigt zu verwenden, ist es auch möglich, die Wiedereinkopplung erst nach einer festen Zeitspanne nach Abschluss des Ladens auszulösen. So ist es zum Beispiel kaum vorstellbar, dass die STARTUP-Sequenz 100 ms dauert, und für einen Menschen ist eine solche Verzögerung praktisch unbemerkt. Angesichts der beiden oben genannten Testergebnisse scheint die Verwendung des STARTUPE2-Primitivs jedoch der sichere Weg zu sein.

Was Ultrascale-FPGAs betrifft, ist das Verhalten von EOS nach dem Laden eines Clearing-Bitstreams offenbar nicht dokumentiert. In einem anekdotischen Test blieb EOS jedoch nach dem Laden des Clearing-Bitstreams auf Low und ging erst nach dem anschließend geladenen partiellen Bitstrom auf High.


An dieser Stelle endet der dritte Beitrag. Der letzte Beitrag schaut hinter die Kulissen von Vivados Umgang mit der Beziehung zwischen statischer und rekonfigurierbarer Logik mithilfe von OOCs und DCPs – und wie das Verständnis dieser Zusammenhänge den Weg für eine zuverlässige Erzeugung partieller Bitströme im Remote-Update-Szenario ebnet.

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