Das Grundprinzip des Hardware/Software-Codesigns besteht in dem aufeinander bezogenen Entwurf von Hardware- und Softwarekomponenten eines Systems, wobei bestimmte Teilprozesse in eigens darauf spezialisierten ICs, wie z. B. Hardwarebeschleunigern, ausgeführt werden, denen der nach wie vor universelle Hauptprozessor gegenübersteht. Es bedeutet, dass Teile des Prozesses in Hardware und andere Teile parallel dazu in Software ausgeführt werden.
In der Regel machen hohe Leistungsanforderungen dieses Codesign notwendig. Systeme, bei denen bestimmte Anteile der Rechenoperationen auf Hardwarebeschleuniger ausgelagert wurden, existieren an sich seit vielen Jahren. Anfangs wurden sie noch in ASICs realisiert. Aufgrund des deutlich erhöhten Entwicklungsaufwands von ASICs war dies aber nur in seltenen Fällen wirtschaftlich. Heute sind sie längst durch in SoCs integrierte FPGAs abgelöst. Zusammen mit leistungsfähigen und automatisierten Tools ist HW/SW-Codesign mittlerweile in vielen Bereichen ohne hohen Aufwand einsetzbar, auch und gerade für Echtzeitsysteme. Hier ist HW/SW-Codesign unter Verwendung von Hardwarebeschleunigern in FPGAs eine sehr effiziente Möglichkeit zur Erfüllung von Echtzeitanforderungen, da sie neben der potenziellen Leistungssteigerung im Allgemeinen eine relativ einfach vorherzusagende Laufzeit haben. Durch die Verifikation des Designs mit modernen Co-Simulationen bzw. Co-Emulationen kann dabei die Entwicklungszeit und damit die Time-to-Market reduziert werden.
Hardwarebeschleuniger in FPGAs werden klassischerweise in Hardwarebeschreibungssprachen wie VHDL oder Verilog geschrieben. Im Gegensatz zur Softwareentwicklung erfordert dies aufgrund der aufwendigeren Umsetzung und Verifikation einen deutlich höheren Entwicklungsaufwand. Daher werden zunehmend Tools eingesetzt, die aus einer abstrakten Beschreibung in höheren Sprachen wie C oder C++ automatisiert HDL-Code erzeugen. So stellen beispielsweise die FPGA-Hersteller Intel und Xilinx jeweils ein High-Level-Synthesis(HLS)-Tool zur Verfügung. Wang et al. haben 2020 in [1] gezeigt, wie ein HLS-Compiler sehr einfach verwendet werden kann, um Teile des in KI-Systemen verwendeten YOLO-v2-Objekterkennungsalgorithmus (You Only Look Once) auf einen FPGA auszulagern.
Limitierend wirkt allerdings auch hier die Datenübertragungsgeschwindigkeit zum und vom Hardwarebeschleuniger. Daher werden hierfür oft DMA-Einheiten verwendet, die Daten möglichst effizient in Bursts und ohne Zutun des Prozessors übertragen. Hierbei ist die oben erwähnte Cache-Hierarchie (Bild 1) zu beachten. So sollten die Daten entweder in einem nicht vom Cache verwendeten Datenbereich liegen oder es muss Cache-Kohärenz sichergestellt werden. Dies kann entweder durch einen Snoop-Controller oder durch manuelles Cache-Management bewerkstelligt werden.
Bild 4 zeigt beispielhaft, wie die zeitliche Abfolge bei der Verwendung eines Hardwarebeschleunigers in einem Echtzeitsystem für einen Regelungszyklus n aussehen könnte. Der Hardwarebeschleuniger könnte z. B. aus einer oder mehreren Datenverarbeitungs-Pipelines oder aus einer Vielzahl von spezialisierten Prozessoren mit eigenem Befehlssatz bestehen, an die der Prozessor Teilaufgaben delegiert. Hier steht zu Beginn des Echtzeitzyklus das Auslesen von Sensorwerten als Eingabedaten. Anschließend werden sie auf den Hardwarebeschleuniger übertragen, der sie verarbeitet. Parallel führt der Prozessor weiter Rechenoperationen aus bzw. wartet auf die Ergebnisse. Typischerweise müssen die Daten vor Ende des Echtzeitzyklus zurückübertragen werden, um berechnete Stellgrößen ggf. an die Aktoren weitergeben zu können.
Die optimale Partitionierung, welche Prozessanteile in Software und welche Teile auf einem Hardwarebeschleuniger laufen sollen, ist im Allgemeinen aufgrund der hohen Anzahl an möglichen Partitionierungen ein »NP-vollständiges« Problem [2]. Die Forschung beschäftigt sich zwar seit vielen Jahren damit, möglichst effiziente heuristische Verfahren zu finden, mit denen eine vollautomatisierte Partitionierung möglich ist. Allerdings muss aufgrund der vielen Randbedingungen in der Praxis letztlich auf die Erfahrung des Entwicklers zurückgegriffen werden, der ein tiefes Verständnis sowohl des High-Level-Systems als auch der Low-Level-Eigenschaften der vorhandenen Hardware haben sollte. Im Allgemeinen ist die Reichweite der möglichen Leistungssteigerungen sehr stark von der Anwendung bzw. der zu lösenden Aufgabe selbst abhängig, z. B. von der Parallelisierbarkeit der Prozesse sowie Datenabhängigkeiten, von der verwendeten Architektur sowie anderer Eigenschaften wie der FPGA-Taktfrequenz.
Damit dürfte klargeworden sein, dass es unerlässlich ist, sein System genau zu kennen: die Leistungsfähigkeit des Speichers ebenso wie die Systemarchitektur sowie die Datenflüsse. Zudem ist eine zuverlässige Leistungsanalyse nötig. Bei Cortex-A- und Cortex-R-Prozessoren von ARM beispielsweise gibt es eine Performance Monitoring Unit (PMU) pro Kern. Allerdings lauern hier eine Reihe von Fallstricken wie die Beeinflussung durch die Messung selbst, Verfälschungen durch Optimierung über die Zeitmessung hinweg sowie Störeinflüsse anderer Busteilnehmer.
Entwickler müssen jedoch achtgeben: Nicht immer erreichen sie ihr Ziel, in ungünstigen Konstellationen kann sogar eine Verschlechterung der Leistungsfähigkeit eintreten. Mit einiger Erfahrung jedoch sind Leistungssteigerungen bis zur Verzehn- oder Verzwanzigfachung – als Worst Case Execution Time – möglich. In der Praxis konnte beispielsweise die Leistung eines echtzeitkritischen Regelungssystems mit über 60 Freiheitsgraden durch Verwendung von mehreren parallel laufenden Hardwarebeschleunigern um etwas mehr als das Zehnfache gesteigert werden; ohne diese wären unter Einhaltung der harten Echtzeitanforderungen nur wenige Freiheitsgrade regelbar gewesen. Dabei konnte auch die vorgegebene Latenz von 20 kHz erreicht werden, indem ausschließlich lineare, sprunglose Programmabläufe implementiert wurden, bei denen genau die jeweilige Ausführungszeit bekannt war. In anderen Anwendungsfällen können Sprünge oder Schleifen durchaus erlaubt sein und dennoch lässt sich eine Verbesserung der Leistung erzielen: Auf den Einzelfall kommt es an.
Literatur
Wang, Z.; et al.: Sparse-YOLO: Hardware/Software Co-Design of an FPGA Accelerator for YOLOv2. IEEE Access, Juni 2020, DOI: 10.1109/ACCESS.2020.3004198.
Li, Y.; et al.: Hardware-Software Co-Design of Embedded Reconfigurable Architectures. Proceedings of the 37th Annual Design Automation Conference DAC ’00, Juni 2000, S. 507–512, ISBN: 1581131879, DOI: 10.1145/337292.337559.
Der Autor
Marian Braendle
studierte von 2012 bis 2019 Bachelor + Master an der TU München in Elektro- und Informationstechnik mit dem Schwerpunkt in Embedded Systems und integrierten Systemen (FPGAs). Seit 2019 arbeitet er bei Ingenics Digital im Bereich hardwarenahe Programmierung und FPGA-Entwicklung. Braendle beschäftigt sich unter anderem auch mit der Leistungsanalyse und Leistungsoptimierung in Echtzeitsystemen