Xilinx Vivado meistern: Integrated Logic Analyzer (ILA) & Virtual Input/Output (VIO) Debugging
Dieses Tutorial führt Sie durch die Verwendung der Integrated Logic Analyzer (ILA)- und Virtual Input/Output (VIO)-Kerne von Xilinx Vivado zum Debuggen und Überwachen von VHDL-Designs on-Chip. Am Ende wissen Sie, wie Sie Sonden einfügen, Trigger konfigurieren und präzises Signalverhalten ohne externe Ausrüstung erfassen.
Überblick
Im gesamten Artikel referenzieren wir Vivado-Screenshots. Klicken Sie auf jedes Bild, um es zu vergrößern. Nutzen Sie die Seitenleiste oder die mobile Pop-up-Navigation für schnellen Zugriff.
ILA und VIO
Der ILA-IP-Kern ermöglicht das Echtzeit-Probing interner FPGA-Signale, während der VIO-IP-Kern das Steuern interner Signale aus Vivado heraus erlaubt. Beide sind kostenlos, hochkonfigurierbar und fügen sich nahtlos in den Vivado-Workflow ein.
- Xilinx IP: Integrated Logic Analyzer (ILA)
- Xilinx IP: Virtual Input/Output (VIO)
Voraussetzungen
- Ein Xilinx FPGA-Board
- Vivado Design Suite (2020.2 oder neuer)
- Grundlegende VHDL-Kenntnisse
In den Beispielen verwenden wir das Kintex-7 KC705 Evaluation Kit, die Schritte gelten jedoch für jedes moderne Xilinx FPGA.
Beispielprojekt herunterladen
Laden Sie die ZIP-Datei mit dem Beispiel-Design und den VHDL-Dateien herunter. Öffnen Sie ila_tutorial.xpr in Vivado, um das Design zu erkunden, oder lesen Sie weiter, um es von Grund auf neu zu erstellen.
Projekt mit Vivado erstellen
Starten Sie Vivado und klicken Sie auf dem Willkommensbildschirm auf Create Project.
Gehen Sie durch den Assistenten: Benennen Sie das Projekt ila_tutorial (keine Leerzeichen), wählen Sie RTL Project und fügen Sie die Quellen counter.vhdl und counter_top.vhdl hinzu. Aktivieren Sie Copy sources into project und fahren Sie fort.
Fügen Sie die Constraints-Datei top.xdc hinzu und kopieren Sie sie in das Projekt. Passen Sie Takt- und LED-Pins an Ihr Board an und setzen Sie die korrekte Takperiode.
Wählen Sie Ihr Board aus der Liste und klicken Sie auf Finish, um das Projekt zu öffnen.
Design-Beispiel Übersicht
Das Beispiel besteht aus zwei 4-Bit-Zählern, die kaskadiert sind. counter.vhdl implementiert einen Zähler, der bei aktiviertem Enable inkrementiert und einen 1-Bit-trigger-Ausgang zwischen den Zählerständen 12 und 15 assertiert.
Entity-Deklaration:
---------------------------------------------------------------------------- -- ENTITY DECLARATION. ---------------------------------------------------------------------------- ENTITY counter IS PORT(clk : IN STD_LOGIC; -- Haupttakt reset : IN STD_LOGIC; -- Reset, active_high enable : IN STD_LOGIC; -- aktiviert den nächsten Zähler trigger : OUT STD_LOGIC -- triggert den nächsten Zähler ); END ENTITY;
Interne Signale:
count– der 4-Bit-Zählerwert.trigger_o– intermediäres Signal, verbunden mit demtrigger-Ausgang.
Attribut-Verwendung (wird später erklärt):
ATTRIBUTE MARK_DEBUG : STRING; ATTRIBUTE MARK_DEBUG OF count : SIGNAL IS "true";
Sequenzielle Logik:
seq_proc: PROCESS (reset, clk) BEGIN -- for seq_proc IF (reset = '1') THEN count <= (OTHERS => '0'); trigger_o <= '0'; ELSIF rising_edge(clk) THEN IF (enable = '1') THEN count <= count + 1; IF (count > x"B" AND count <= x"F") THEN trigger_o <= '1'; ELSE trigger_o <= '0'; END IF; END IF; END IF; END PROCESS;
counter_top.vhdl instanziiert zwei Zähler. counter_1_inst ist immer aktiviert und taktet counter_2_inst über seinen trigger-Ausgang. Folglich inkrementiert counter_2_inst nur viermal pro 16-Zyklus-Periode von counter_1_inst.
VIO-Kern für RESET erstellen
Wir generieren einen VIO, der den reset-Eingang des Designs steuert und manuelles Umschalten aus Vivado ermöglicht.
Öffnen Sie den IP Catalog, suchen Sie nach VIO, doppelklicken Sie auf VIO (Virtual Input/Output) und benennen Sie ihn in vio_reset um. Setzen Sie Input Probe Count auf 0 und Output Probe Count auf 1.
Konfigurieren Sie den Output-Probe: Breite = 1, Initialwert = 0x1, dann klicken Sie auf OK und Generate.
Nach der Synthese deklarieren Sie eine Komponente in counter_top.vhdl und instanziieren sie. Vergessen Sie nicht, flatten_hierarchy vor der erneuten Synthese auf None zu setzen.
COMPONENT vio_reset PORT( clk : IN STD_LOGIC; probe_out0 : OUT STD_LOGIC_VECTOR(0 DOWNTO 0) ); END COMPONENT;
Debugging-Sonden einfügen
Signale können auf drei Arten geprobt werden:
- Aus der VHDL-Quelle (über
MARK_DEBUG-Attribute). - Aus dem Netlist oder Schematic (Rechtsklick Mark Debug).
- Aus einer XDC/TCL-Datei (hier nicht behandelt).
Einfügen aus VHDL-Datei
Deklarieren Sie das MARK_DEBUG-Attribut einmal pro Datei und wenden Sie es auf die gewünschten Signale an:
ATTRIBUTE MARK_DEBUG : STRING; ATTRIBUTE MARK_DEBUG OF count : SIGNAL IS "true";
Im synthetisierten Design erscheint count unter Unassigned Debug Nets mit einem Bug-Symbol.
Einfügen aus dem Netlist
Navigieren Sie zu Netlist oder Schematic, lokalisieren Sie das trigger-Net, klicken Sie mit der rechten Maustaste und wählen Sie Mark Debug für beide Zähler.
ILA-Debug-Kern erstellen
Öffnen Sie Set Up Debug aus dem IP Catalog. Vivado listet alle Debug-Nets und ihre Taktdomänen. Behalten Sie für dieses Tutorial alle vier Signale bei.
Konfigurieren Sie die ILA-FIFO-Tiefe (1024 ist ausreichend) und aktivieren Sie Capture control. Beenden Sie den Assistenten; Vivado generiert einen ILA-Kern und eine Constraints-Datei.
Speichern Sie die Constraints als ila_core.xdc. Diese Datei wendet die Debug-Attribute an, erstellt den ILA-Kern, konfiguriert jede Probe und instanziiert einen dbg_hub, der den Kern mit Vivado verbindet. Aktualisieren Sie die Takfrequenz des Hubs passend zu Ihrem Design.
Führen Sie Synthese und Implementation erneut aus und generieren Sie den Bitstream. Öffnen Sie den Hardware Manager, verbinden Sie automatisch und programmieren Sie das Device zusammen mit der .ltx-Probe-Datei.
ILA-Trigger konfigurieren
Nach der Programmierung erscheint das ILA-Dashboard. Aktivieren Sie den VIO-Tab und entfernen Sie unnötige Fenster. Fügen Sie den reset-Probe zum VIO hinzu, um ihn während der Erfassung umschalten zu können.
Richten Sie einen Trigger auf counter_1_inst/trigger mit Flankenbedingung (rising-edge) und einem Pre-Trigger-Fenster von 32 Samples ein.
ILA mit einem Trigger ausführen
Armen Sie den Trigger (Status wechselt zu waiting for trigger) und schalten Sie reset auf 0. Sobald der Trigger auslöst, zeichnet die ILA 32 Samples vor dem Ereignis auf und fährt fort, bis die FIFO voll ist.
Beim Herauszoomen wird das Verhalten von counter_2_inst sichtbar.
ILA mit mehreren Triggern ausführen
Für komplexe Szenarien können mehrere Trigger verkettet werden. Beispiel: Triggern, wenn counter_1_inst/count == 9 UND counter_2_inst/count > 2, wobei die FIFO in vier Fenster aufgeteilt wird.
Auto Re-Trigger Modus
Aktivieren Sie Auto re-trigger, um sporadisch oder hochfrequent auftretende Ereignisse zu erfassen. Konfigurieren Sie einen einzelnen Trigger, setzen Sie die FIFO-Tiefe und armen Sie den Kern.
Capture Modus
Der Capture-Modus zeichnet nur Samples auf, die eine globale Bedingung erfüllen. Beispiel: Erfassen, wenn counter_1_inst/trigger == 1 UND counter_2_inst/trigger == 0 gleichzeitig gelten.
Fazit
ILA und VIO sind leistungsstarke, kostenlose Werkzeuge für On-Chip-Debugging. Durch den Einsatz von Sonden, multiplen Triggern und Capture-Modi können Sie komplexe FPGA-Designs präzise direkt aus Vivado überwachen und steuern.
VHDL
- VHDL & Verilog meistern: Saubere kombinatorische & sequentielle Logik schreiben
- Cloud-Horizonte erweitern: Neue Zonen, Container und Multicloud-Strategien
- C# Grundlagen: Eingabe und Ausgabe Essentials
- C++-Eingabe und Ausgabe meistern: Ein praktischer Leitfaden
- C Eingabe und Ausgabe (I/O) meistern: scanf() und printf() erklärt
- Python I/O & Modul-Importe meistern: Praxisleitfaden
- Java Ein- und Ausgabe meistern: Drucken, Lesen und Formatieren Ihrer Daten
- D-Latches meistern: Design, Funktionsweise und wesentliche Unterschiede
- Eingabe und Ausgabe in C meistern: scanf, printf & Co.
- RightHand Robotics und Element Logic präsentieren integriertes robotergestütztes Piece-Picking-System