FPGA-Design Auf Wanzenjagd

Wenn sich ein FPGA-Design nicht synthetisieren lässt oder sich auf dem Board nicht wie erwartet verhält, sind Entwickler gezwungen, nach Methoden zu suchen, mit denen sie sich auf die Validierung des Designs auf dem Board konzentrieren können.

Spezifische Fehler zu entdecken, die nur unter bestimmten Bedingungen auftreten, ist immer kompliziert - sind sie einmal identifiziert, geht es darum, von den Schaltungsteilen, die sich fehlerhaft verhalten, auf den Quellcode zurückzuschließen sowie schließlich inkrementelle Korrekturen vorzunehmen. Solche Probleme lassen sich zwar nicht ganz ausschließen, aber doch wenigstens durch eine gute Spezifikation minimieren.

Wenn funktionale Fehler auf dem Board sichtbar werden, kann es eine ziemliche Herausforderung sein, deren Ursache einzugrenzen. Zum Debuggen des Designs ist es erforderlich, zusätzliche Schaltelemente einzusetzen und bestimmte Schaltungspunkte aufrechtzuerhalten, von denen aus sich die vom Design während des Betriebs generierten Daten prüfen, abgreifen und analysieren lassen.

Board-Level-Debug-Software kann bei der Fehlersuche helfen. Mittels eines vierstufigen Ansatzes mit einem RTL-Debugger lassen sich Fehler genau lokalisieren und dann
die relevanten Signale und Bedingungen abfragen. Anschließend gilt es, die Beobachtungen in Beziehung zum originalen RTL-Code zu setzen, um die Fehlerursache einzugrenzen, die in der RTL-Spezifikation oder dem Constraint-Setup liegen kann. Ein »Kochrezept«:

Schritt 1: Spezifikation von Testpunkten. Legen Sie im RTL-Code genau fest, welche Signale und Bedingungen Sie überwachen möchten. Hier definieren Sie Beobachtungspunkte (zu beobachtende Signale oder Verbindungen) und Breakpoints (RTL-Kontrollflussanweisungen wie IF, THEN und CASE), deren Funktion für Sie von Interesse ist.

Schritt 2: Erstellen des Designs mit Testpunkten. Synthetisieren Sie das FPGA-Design mit zusätzlicher Überwachungsschaltung: ein »intelligenter« In-Circuit-Emulator (IICE), der Debug-Daten gemäß der Spezifikation dessen, was überwacht werden soll, erfasst und exportiert.

Schritt 3: Analyse und Debugging. Nach der Synthese nehmen Sie das Design in Betrieb und beobachten die Daten unter Verwendung des RTL-Debuggers. Wenn der Test auf dem Board läuft, lösen die Überwachungspunkte und Breakpoints gemeinsam die Datenerfassung aus. Dadurch können Sie das Schaltkreisverhalten an ganz bestimmten relevanten Verbindungspunkten und unter speziellen Bedingungen beobachten und debuggen. Die erfassten Daten lassen sich in eine VCD-Datei schreiben und zum RTL-Code in Beziehung bringen.

Schritt 4: Durchführung einer inkrementellen Korrektur. Haben Sie einen Entwurfsfehler gefunden, können Sie ihn unter Verwendung hierarchischer und inkrementeller Flows inkrementell im RTL-Code oder in den Constraints beheben.

Visuelle Untersuchung von Fehlern

FPGA-Entwurfs- und -Debugging-Werkzeuge haben den Vorteil, dass sie Schaltpläne auf Register-Transfer- und Netzlisten-Ebene anzeigen können. Beispielsweise stellt ein Schaltplanbetrachtungs-Tool mit inter-aktiven Debug-Fähigkeiten die RTL- und Netzlisten-Repräsentationen des Designs grafisch dar, sodass sich Timing-Reports und VCD-Daten (vom Betrieb des Designs auf dem Board) visualisieren und auf den RTL-Quellcode abbilden lassen.

Der Viewer beinhaltet eine unmittelbar nach dem RTL-Kompilieren verfügbare RTL-Ansicht, die das Design durch technologieunabhängige Komponenten wie Addierer, Register, große Multiplexer und Zustandsmaschinen darstellt. Von diesem RTL-Schaltplan gibt es Rückverbindungen zum originalen RTL-Code, um Anpassungen vorzunehmen, außerdem zum Constraint-Editor, wo der Anwender Randbedingungen aktualisieren und einfacher spezifizieren kann (Bild 1).

Nicht synthetisierbare Entwürfe

Um die Spur einer inkorrekten Operation zum RTL-Code selbst zurückzuverfolgen, kann etwa das Werkzeug »Identify RTL Debugger« von Synopsys zum Einsatz kommen, das die aufgenommenen Betriebsdaten live in die RTL-Schematic-Darstellung einblendet. Schematic-Viewer bieten auch eine Ansicht auf Netzlisten-Ebene, welche die tatsächliche Design-Implementierung nach der Synthese zeigt.

Im Schaltplanbetrachter »HDL-Analyst« basiert diese Sicht auf den grundlegenden Funktionen von Xilinx-Bausteinen wie Look-up-Tables, Registern und DSP-Slices. Sowohl Pfade als auch eventuell nach der Synthese oder nach Place&Route generierte Timing-Reports lassen sich hier auf den ursprünglichen RTL-Code abbilden, um die Gesamtperformance zu ermitteln und zu verbessern.

Alle Signale zu untersuchen verbietet sich in einem großen Design, weil die generierte Datenmenge astronomisch und zu viel zusätzliche Debugging-Logik erforderlich wäre, um die Daten zu analysieren. Ein gängiges Problem mit On-Chip-Debugging-Methoden besteht darin, dass es schwierig sein kann, im Vorfeld die zu untersuchenden und zu überwachenden Signale zu bestimmen.

Manche Debugging-Software löst dieses Problem durch gemultiplexte Sample-Gruppen. Diese erlauben den Entwicklern, selektiv abzutasten und durch einen Multiplexpfad und Shared-IICEs zwischen Signalgruppen umzuschal-ten. Diese Strategie erhöht die Anzahl an Signalen und Bedingungen, die analysiert werden können, ohne die Anforderungen an die Datenspeicherung zu erhöhen.

Der Anwender kann dabei jederzeit zwischen den jeweils gewünschten Signalgruppen umschalten, ohne Zeit für die Rekonfiguration aufbringen zu müssen, und ein neu konfiguriertes Design synthetisieren. Unglücklicherweise beansprucht eben jene IICE-Debugging-Logik Chipressourcen einschließlich Memory-Block-RAMs. Nutzt man On-Chip-Block-RAM, reduzieren sich jedoch durch externes Speichern, etwa auf SRAM-Speicherkarten, die IICE-Daten.

Dieser Ansatz hat den zusätzlichen Vorteil, dass die Tiefe der Messdaten zunimmt. Es können Entwurfsfehler auftreten, die einen sauberen Synthese- und Place&Route-Lauf verhindern. Tausende von RTL- und Constraint-Dateien können den ersten erfolgreichen Synthese- und Place&Route-Lauf in ein mehrwöchiges Abenteuer verwandeln.

Für ein Prototyping auf der Basis von FPGAs ist es notwendig, die ASIC-Entwurfsdateien für FPGAs aufzubereiten. Ein Beispiel ist die Notwendigkeit, Gated-Clocks umzuwandeln. Gated-Clock-Strukturen in einem ASIC, der als FPGA-Prototyp realisiert werden soll, sind in der FPGA-Implementierung nicht erforderlich und würden die FPGA-Ressourcen ineffizient nutzen.

Ein effizienter Weg, dieses Problem zu lösen, besteht darin, dass die FPGA-Synthesesoftware die Taktsignale konvertiert. Beispielsweise würde ein Gated-/Generated-Clock-Conversion-Feature intern generierte Taktsig-nale und Gated-Clock-Logik vom Clock-Pin eines sequenziellen Elements zum Enable-Pin verlagern. So lassen sich sequenzielle Elemente direkt mit dem Originaltakt verbinden, sodass Skew-Probleme vermieden, die Anzahl der Taktsignale im Design verringert und Ressourcen eingespart werden.

Zu einem »vollständigen« Satz von Clock-Constraints gehört, dass der Takt an allen richtigen Stellen definiert wurde und dass auch die Beziehungen zwischen den intern generierten Taktsignalen korrekt beschrieben sind. Es kann passieren, dass die Taktumwandlung beim ersten Versuch fehlschlägt, weil Clock-Constraints fehlen, beispielsweise wenn ein Takt, der sequenzielle Elemente steuert, nicht definiert wurde, oder weil sie falsch platziert wurden.

ine andere Möglichkeit ist, dass ein Taktsignal aus irgendeinem Grund von seiner tatsächlichen Quelle getrennt wurde, beispielsweise beim Platzieren einer Black-Box zwischen der Taktquelle und dem Zielelement. In vielen Fällen scheitert die Takt-umwandlung an unvollständigen Constraints. So könnte sich in der Clock-Gating-Logik eine kombinatorische Schleife befinden, die durch ein Exception-Constraint aufgebrochen werden muss, bevor die Taktumwandlung stattfinden kann.

Ein Gated-Clock-Report, der nach der Compile-Phase der Synthese verfügbar ist, informiert über konvertierte Gated- und Generated-Clocks sowie über deren Namen, Typen, Gruppen und zugeordnete Constraints. Auch mit Black-Boxes lassen sich Gated-Clocks durch Einsetzen codespezifischer Direktiven umwandeln. So erlaubt es die Direktive »syn_gatedclk_clock_en«, den Namen des Enable-Pins innerhalb der Black-Box anzugeben, während »syn_gatedclk_clock_en_polarity« die Polarität des Clock-Enable-Ports einer Black-Box anzeigt. Jeder konvertierten Instanz und jedem Clock-Pin, der die Instanz treibt, wird ein suchbares Merkmal zugewiesen.

Kürzer Debuggen

Es kann durchaus mehrere Stunden dauern, bis die Ergebnisse der Implementierung einer potenziellen RTL- oder Constraint-Korrektur vorliegen. Diese Zeit lässt sich durch eine geringere Zahl an Iterationen verkürzen. Um Laufzeit einzusparen, sind blockbasierte Flows zu einer Notwendigkeit geworden. Durch diese Flows lassen sich die Teile des Designs, die bereits funktionieren, vor weiteren Veränderungen schützen.

Mit einem Tool, das blockbasierte Flows unterstützt, können Entwickler RTL-Partitionen, sogenannte Compile-Points, einrichten, bevor die Synthese beginnt. Manche Software ermöglicht Entwicklern, einen fehlerbehafteten Teil des Designs als Black-Box zu definieren und diesen Teil zwecks Überarbeitung komplett als eigenständiges Subprojekt zu exportieren.

Sobald das Unterprojekt in Ordnung gebracht wurde, wird es wieder in das Gesamtprojekt integriert, und zwar entweder als Netzliste im Rahmen eines Bottom-up-Flows oder als RTL-Code in einem Top-down-Flow - oder gar mittels eines gemischten Top-down- und Bottom-up-Flows. Um umfangreiche Designs zu integrieren und von Fehlern zu bereinigen, ist es wichtig, Gruppen von Spezifikationsfehlern so früh wie möglich im Entwurfsprozess aufzuspüren.

Beispielsweise stellt ein CoE-Feature (Continue-on-Error, beispielsweise in »Synplify Premier« einfach per Checkbox zu aktivieren) einen gesammelten Fehlerbericht für jeden Synthesedurchgang zur Verfügung. CoE toleriert nicht-fatale, nicht-syntaxbezogene HDL-Kompilationsprobleme sowie bestimmte Mapping-Fehler, sodass Entwickler mit jeder Synthese-Iteration einen größtmöglichen Teil des Designs analysieren und vervollständigen können.

Fehlerhafte Module sowie das übergeordnete Modul von Instanzen mit Interface-Fehlern werden mit dem Merkmal »is_error_blackbox=1« versehen und in der grafischen Darstellung hervorgehoben, siehe Bild 2. Fehlerhafte Module, die bereit sind für die Black-Box-Modellierung oder für den Export, stellt der RTL-View in »HDL-Analyst« als rote Kästen dar (Bild 2).

Problembehebung durch Export

Fehlerhafte Module lassen sich als vollständig eigenständiges Syntheseprojekt exportieren, um sie gezielt zu debuggen. Der Exportprozess erzeugt ein separates Syntheseprojekt, das alle individuellen Modul-Quelldateien, den Sprachstandard und Compiled-Libraries umfasst, einschließlich der Verzeichnispfade und der Pfadreihenfolge für eingebundene Dateien, die für die Synthese und das Debuggen des separaten Moduls erforderlich sind.

Fehlerbehaftete Module werden in der Design-Datenbank automatisch mit einem Fehlermerkmal versehen. Auf diese Weise lassen sich die Module, für die eine separate Überarbeitung angebracht ist, leicht identifizieren. Sobald das jeweilige hierarchische Modul korrigiert ist, lässt es sich als RTL-Code oder Netzliste wieder in das Gesamtdesign integrieren (Bild 3).

Über die Autorin:

Angela Sutton ist Staff Product Marketing Manager bei Synopsys.