HDMI

Allgemeines

In diesem Projekt ging es darum, sich genauer mit der Video- und Signalverarbeitung auf Basis eines FPGAs zu beschäftigen. Konkret ging es darum sich mit der bestehenden Plattform vertraut zu machen, sowie sich die grundlegenden Kenntnisse für die Video- und Signalverarbeitung anzueignen.

Die ersten Schritte dazu wurden mit dem PYNQ Z2 Development Board unternommen. Der Grund hierzu lag an der relativ kurzen Synthese Zeit, sowie der geringeren Komplexität des Boards, im Vergleich zum ZCU106. Wie bereits in dem Kapitel Continuous Integration (https://videosigxilinx.projekte.fh-hagenberg.at/continuous-integration/) beschrieben, wurde gleich zu Beginn versucht eine entsprechende Build-Infrastruktur zu schaffen, um die Vivado Projekte zu versionieren und auf einem eigenen Buildserver automatisch synthetisieren zu können. Nachdem die Grundkenntnisse auf dem PYNQ Z2 Board erschlossen wurden, sowie die Continuous Integration aufgesetzt war, konnte die Signalverarbeitungskette auf das eigentliche ZCU106 Board portiert werden. Weitere FPGA Entwicklungen sowie High Level Synthese für eigene Verarbeitungsblöcke wurden dann entsprechend auf Basis des ZCU106 Boards umgesetzt.

Basis Videoverarbeitung

Wie bereits erwähnt mussten zuerst Grundkenntnisse der Videoverarbeitung erlangt werden. Diese wurden anhand eines Vivado Beispielprojektes erlangt, welches weiter abgewandelt wurde, um sich mit den einzelnen Komponenten sowie deren Gesamtfunktion vertraut zu machen. Es gelang schließlich, ein HDMI Eingangssignal in ein entsprechendes Video- und Audiosignal aufzuspalten und dies über den AXI Stream weiteren Komponenten zur Verfügung zu stellen.

Im ersten Schritt wurden diese beiden Eingangssignale lediglich wieder zu einem HDMI Ausgangssignal zusammengefasst und dies an dem HDMI-out Kanal ausgegeben. Weiter gibt es die Möglichkeit das Verhalten über ein entsprechendes UART Interface zu verändern. Damit ist es möglich die Auflösung des Ausgangssignals abzuändern sowie ebenfalls ein Testsignal auszugeben. Die Ausgabe des Testsignals ermöglicht somit den HDMI-out Kanal ohne entsprechendes Eingangssignal zu testen.

Folgendes Design wurde für die Umsetzung der oben beschriebenen Funktion verwendet. Die Darstellung wurde hierbei vereinfacht, indem nur Interface Connections dargestellt werden. Sämtliche IO Ports sind ausgeblendet, um eine Übersicht zu ermöglichen.
Die orange markierten Verbindungen representieren den Datenpfad für den HDMI Video Stream.

Basis High-Level-Synthese und Integration

Im nächsten Schritt wurde versucht, eigene Verarbeitungsblöcke mittels High-Level-Synthese (HLS) zu entwickeln. Wichtig hierbei war auch die Integration in das zuvor erstellte Design. Hierzu wurde ein eigener IP Block programmiert, welcher die Farben des Videosignals vor der Ausgabe an dem HDMI-out Kanal lediglich invertiert. Hierbei soll die Quelle des Videosignals keine Rolle spielen. Es wird somit entweder das Eingangssignal von dem HDMI-in Kanal, oder das vom Testbildgenerator erzeugte Signal invertiert.

Die High-Level-Synthese bietet die Möglichkeit, RTL Code aufgrund einer Beschreibung in C/C++ zu generieren. Es muss somit kein RTL Code manuell geschrieben werden. Der generierte RTL Code kann wie üblich als Vivado IP Block in ein Block Design integriert werden. Weiter ist es mit HLS möglich, Testbenches ebenfalls in C/C++ zu schreiben. Das vereinfacht das Testen des IP Cores deutlich.

Der entwickelte IP Block invertiert die Farben jedes einzelnen Pixels des Eingangssignals und gibt das invertierte Signal entsprechend wieder auf einen AXI Stream Bus weiter. Für die Integration in das oben erwähnte Block Design wurde der neu erstellte IP Core in Serie mit dem Test Pattern Generator (TPG) geschaltet. Es ergibt sich folgende Änderung zum oben angeführtem Board-Design.

Das folgende Video präsentiert die erfolgreiche Implementation des Farb Inverter IP.
Im Testaufbau ist ein PC über HDMI als Bildquelle am ZCU106 angeschlossen. Dieses Bild wird invertiert und am zweiten Monitor (links im Bild) angezeigt. Der rechte Ausschnitt im Video repräsentiert die Menüführung auf der seriellen Konsole, die vom ZCU106 geliefert wird.
Die Verzögerung zwischen Eingaben in der Konsole und Reaktion am Monitor stammt lediglich vom Videoschnitt, und ist in der Realität nicht vorhanden.

Advanced High-Level-Synthese

Nachdem die grundlegenden Kenntnisse für die Videoverarbeitung, sowie die Erstellung eigener IP Cores durch die High-Level-Synthese erworben wurden, konnten komplexere IP Cores durch HLS erstellt und ebenfalls in das Board-Design integriert werden. Weitere Anpassungen auf die Anforderungen wurden unternommen. Folgende Passagen verdeutlichen hierbei die einzelnen Schritte, die dazu notwendig waren.

Testbild Generator IP

Es wurde ein eigener IP Core entwickelt, welcher ein benutzerdefiniertes Testbild erzeugen kann. Durch die Beschäftigung mit diesem IP konnten weitere Erkenntnisse über HLS gewonnen werden.

Zu den Anforderungen an diesen IP Block gehört die Möglichkeit, das Testbild zur Laufzeit verändern zu können. Hierzu wurde zuerst das EBU-Farbbalken Testbild als Vorlage herangezogen, welches in dem entwickelten IP Core erzeugt werden soll. Dabei wird einschränkend die Auflösung für die Erzeugung vorgegeben und wurde mit 1920×1080 fixiert. Der Testbildgenerator bietet neben der Ausgabe des Standard EBU-Farbbalken Testbilds die Möglichkeit die Rot- und Blauanteile des Testbilds zu invertieren. Dies kann durch Setzen von Registern über einen AXI Memory-Mapped Bus bewirkt werden. In weiteren Schritten sollte einerseits die Auflösung einstellbar gestaltet werden und es die Möglichkeit geben, dass sich das Testbild linear bewegt. Allerdings wurde dieses Vorhaben durch die Corona-Krise und der dadurch entstandenen Zeitverschiebung bei der Umsetzung des Projekts nicht erreicht.

Folgendes Video zeigt die erfolgreiche Implementierung eines einfacheren Pattern Generator IPs, inklusive der Menüführung über die serielle Konsole.
Das generierte Pattern wird als Overlay über die externe Bildquelle (HDMI Input von PC) dargestellt.

Mandelbrot Generator IP

Das bisher gewonnene Know-How im Umgang mit HLS wurde hier in vollem Umfang eingesetzt. Der IP Block soll das berühmte Mandelbrot Muster generieren. Der Algorithmus soll rein in Hardware das Muster generieren und über den HDMI-out Kanal ausgeben. Die Herausforderung lag hierbei bei der Optimierung des komplexen und berechnungsintensiven Mandelbrot Algorithmus, um die erzeugten Bilder mit einer entsprechend ausreichenden Rate erzeugen zu können.

Der Fokus der Optimierungen lag hierbei vor allem auf der Reduktion der Chip-Fläche. Die beiden effektivsten Änderungen waren die Umstellung von floating-point auf fixed-point Berechnungen, sowie das Anlegen von Look-up Tables für die Farbgebung des Mandelbrot Musters.

Folgendes Video zeigt, dass der Mandelbrot IP Core erfolgreich implementiert werden konnte.
Das Mandelbrot Muster kann durch die Menüführung in der seriellen Konsole verschoben werden. Weiters kann das Muster durch Zoom vergrößert werden.

Integration

Schlussendlich soll noch kurz auf die Integration der entwickelten IP Cores in das vorhandene Board Design eingegangen werden. Es war somit nur mehr notwendig die einzelnen erzeugten IP Cores in das bestehende Design zu integrieren.

Die drei IP Cores wurden so ins Block Design integriert, dass die wechselweise verwendet werden können. Die Konfiguration, welcher IP Core in die Signalverarbeitungskette geschaltet wird, funktioniert über zwei AXI Stream Switches. Diese können wieder über ein AXI MM Interface gesteuert werden.

Am Ende des Projektes ergibt sich somit folgendes Board Design für das HDMI Projekt.

Finales Block Diagramm des HDMI Projekts.

Herausforderungen

  • Die Synthesezeiten waren durch die Komplexität des Designs und Größe des FPGAs im Bereich von 1 – 1,5 Stunden.
    Das stellte eine erhebliche Schwierigkeit in den Iterationen der Entwicklung dar.
  • HLS C++ Code funktioniert immer richtig in Simulation, jedoch aus (aktuell) unerklärlichen Gründen nicht auf der Hardware.
  • Vivado SDK 2018.2 hat sehr viele Bugs…
    • FPGA flashen failt (Abhilfe: Mehrmals Power-Off, SDK neu öffnen, wieder versuchen…)
    • Selbes Problem mit Start von Debugging
    • Bei genannten Bugs treten SegFaults auf.

Trotz dieser teils schwierigen Herausforderungen konnten erfolgreich HLS IP Blöcke entwickelt werden, wie in den Videos zuvor präsentiert wird.