Universelle ProgrammierspracheErweiterung von eingebetteter Software auf FPGA-Hardware
Von
Denis Vasilik*
10 min Lesedauer
FPGA-Entwicklung über Auszeichnungssprachen wie Verilog und VHDL gilt als schwer zugänglich. Doch Software-Programmiersprachen wie C oder C++ sind hierfür häufig unzureichend. Eine universelle Sprache für FPGA/ASIC-Design mit Software-Tools und Abstraktionen wie Livt könnte diese Lücke schließen.
FPGAs lösen Performance-Engpässe, gelten aber in der Programmierung als schwer zugänglich. Die universelle Programmiersprache Livt soll die Hürde senken – korrekt, deterministisch und HDL-kompatibel.
(Bild: Toby Giessen / VCG)
Seit Jahrzehnten existiert die FPGA- und ASIC-Entwicklung in einer Welt für sich. Hardwarebeschreibungssprachen wie VHDL und Verilog sind leistungsstark und präzise, aber sie sind mit einer langen Lernkurve, einer ausführlichen Syntax und Arbeitsabläufen verbunden, die sich von modernen Software-Engineering-Praktiken losgelöst anfühlen.
Gleichzeitig stoßen Entwickler von Embedded Software häufig an die Grenzen von MCUs und CPUs. Latenz, Determinismus, Energieeffizienz und Parallelität werden schließlich zu Engpässen. Obwohl FPGAs oft die richtige technische Lösung sind, ist die Einstiegshürde so hoch, dass viele Teams sie ganz vermeiden.
Livt wurde entwickelt, um diese Lücke zu schließen. Livt ist eine universelle Programmiersprache für FPGA- und ASIC-Design, die Abstraktion, Werkzeuge und Arbeitsabläufe im Stil von Software in den Hardwarebereich bringt, ohne dabei die Korrektheit, den Determinismus oder die Interoperabilität mit bestehendem HDL-Code zu beeinträchtigen.
Warum eine weitere Sprache für die FPGA-Entwicklung?
Die traditionelle HDL-Entwicklung zwingt Entwickler dazu, von der ersten Zeile des Codes an in Begriffen der Low-Level-Hardware zu denken. Dieser Grad an Kontrolle ist zwar für ein korrektes und effizientes Hardware-Design unerlässlich, bedeutet aber auch, dass selbst einfache Verhaltensweisen oft umfangreiche Boilerplate-Code und ein tiefes Verständnis der hardwarespezifischen Details erfordern.
In der Praxis erfordert die traditionelle HDL-Entwicklung, dass Sie in folgenden Begriffen denken:
Signale statt Variablen;
Prozesse statt Funktionen;
Explizite Takte und Resets im gesamten Design;
Handgeschriebene Testbenches zur Verifizierung; sowie
Herstellerspezifische Tool-Flows und Workflows.
Diese Konzepte sind leistungsstark, erschweren jedoch die FPGA-Entwicklung, verlangsamen die Iteration und erschweren die Wartung – insbesondere für Entwickler mit Software-Hintergrund.
Livt verfolgt einen anderen Ansatz. Anstatt mit Low-Level-Mechanismen zu beginnen, beschreiben Sie, was ein Design leisten soll, und der Compiler leitet aus dieser Beschreibung eine korrekte und lesbare VHDL-Darstellung ab. Die generierte HDL lässt sich nahtlos in bestehende Toolchains integrieren und kann mit handgeschriebenem VHDL oder Verilog koexistieren, wenn eine tiefere Kontrolle oder Optimierung erforderlich ist.
Livt wurde entwickelt, um alle Anforderungen der modernen Entwicklung abzudecken:
Sie beschreiben zuerst das Verhalten.
Der Compiler leitet daraus korrektes VHDL ab.
Bei Bedarf behalten Sie vollen Zugriff auf VHDL und Verilog.
Sie arbeiten in einem softwareorientierten Ökosystem, einschließlich Paketverwaltung, Unit-Tests, CI/CD-Integration und KI-gestützten Tools.
Das Ergebnis ist nicht „HDL replaced”, sondern „HDL extended” – was sich auch im Namen „Livt” widerspiegelt. Die Absicht besteht nicht darin, Hardwarebeschreibungssprachen zu ersetzen, sondern den Abstraktionsgrad zu erhöhen, auf dem der größte Teil des Systems ausgedrückt wird. Hardware-Ingenieure behalten die volle Kontrolle, wo es darauf ankommt, während große Teile eines Designs schneller, sicherer und mit deutlich verbesserter Lesbarkeit und Wartbarkeit entwickelt werden können.
Hardware-Software-Integration über HxS
Ein wesentlicher Faktor für den Ansatz von Livt ist die enge Integration mit der bestehenden domänenspezifischen Sprache HxS. HxS konzentriert sich auf die Beschreibung von Hardware-Software-Schnittstellen, insbesondere Registerzuordnungen und CPU-sichtbaren Kontrollpunkten.
Mit Livt und HxS zusammen wird es einfach, ein für den Prozessor zugängliches Register mit einem Wert innerhalb des FPGA oder sogar mit einer in der Hardware-Logik implementierten Funktion zu verknüpfen. Anstatt fragile Glue-Logik zu schreiben, definieren Sie klare und explizite Schnittstellen zwischen Software und Hardware.
Dies verändert grundlegend die Art und Weise, wie die Kommunikation zwischen Prozessor und FPGA gestaltet wird. Die Hardware-Logikwird nicht mehr nur passiv über Register gesteuert, sondern kann ihr Verhalten über klar definierte APIs aktiv offenlegen.
Warum MCU-Entwickler sich für FPGAs interessieren sollten
Aus Sicht eines MCU-Entwicklers werden FPGAs dann relevant, wenn Software allein die Systemanforderungen nicht mehr erfüllen kann. Dies ist häufig der Fall, wenn striktes Echtzeitverhalten erforderlich ist, wenn die Latenz auf ein absolutes Minimum reduziert werden muss oder wenn Aufgaben von massiver Parallelität profitieren können.
Typische Beispiele sind Hochgeschwindigkeits-Sensorschnittstellen, Motorsteuerung, Protokollverarbeitung, Signalvorverarbeitung oder energieeffiziente Datenverarbeitung. In vielen dieser Fälle ist die Implementierung eines Teils der Funktionalität in Hardware die technisch richtige Lösung.
Was bisher gefehlt hat, ist ein zugänglicher Weg, dies zu tun, ohne vollständig auf eine HDL-zentrierte Denkweise umzusteigen. Livt schließt diese Lücke, indem es ein Programmiermodell bietet, das Embedded-Entwicklern vertraut ist und gleichzeitig effiziente, synthetisierbare Hardware erzeugt.
Stand: 08.12.2025
Es ist für uns eine Selbstverständlichkeit, dass wir verantwortungsvoll mit Ihren personenbezogenen Daten umgehen. Sofern wir personenbezogene Daten von Ihnen erheben, verarbeiten wir diese unter Beachtung der geltenden Datenschutzvorschriften. Detaillierte Informationen finden Sie in unserer Datenschutzerklärung.
Einwilligung in die Verwendung von Daten zu Werbezwecken
Ich bin damit einverstanden, dass die Vogel Communications Group GmbH & Co. KG, Max-Planckstr. 7-9, 97082 Würzburg einschließlich aller mit ihr im Sinne der §§ 15 ff. AktG verbundenen Unternehmen (im weiteren: Vogel Communications Group) meine E-Mail-Adresse für die Zusendung von redaktionellen Newslettern nutzt. Auflistungen der jeweils zugehörigen Unternehmen können hier abgerufen werden.
Der Newsletterinhalt erstreckt sich dabei auf Produkte und Dienstleistungen aller zuvor genannten Unternehmen, darunter beispielsweise Fachzeitschriften und Fachbücher, Veranstaltungen und Messen sowie veranstaltungsbezogene Produkte und Dienstleistungen, Print- und Digital-Mediaangebote und Services wie weitere (redaktionelle) Newsletter, Gewinnspiele, Lead-Kampagnen, Marktforschung im Online- und Offline-Bereich, fachspezifische Webportale und E-Learning-Angebote. Wenn auch meine persönliche Telefonnummer erhoben wurde, darf diese für die Unterbreitung von Angeboten der vorgenannten Produkte und Dienstleistungen der vorgenannten Unternehmen und Marktforschung genutzt werden.
Meine Einwilligung umfasst zudem die Verarbeitung meiner E-Mail-Adresse und Telefonnummer für den Datenabgleich zu Marketingzwecken mit ausgewählten Werbepartnern wie z.B. LinkedIN, Google und Meta. Hierfür darf die Vogel Communications Group die genannten Daten gehasht an Werbepartner übermitteln, die diese Daten dann nutzen, um feststellen zu können, ob ich ebenfalls Mitglied auf den besagten Werbepartnerportalen bin. Die Vogel Communications Group nutzt diese Funktion zu Zwecken des Retargeting (Upselling, Crossselling und Kundenbindung), der Generierung von sog. Lookalike Audiences zur Neukundengewinnung und als Ausschlussgrundlage für laufende Werbekampagnen. Weitere Informationen kann ich dem Abschnitt „Datenabgleich zu Marketingzwecken“ in der Datenschutzerklärung entnehmen.
Falls ich im Internet auf Portalen der Vogel Communications Group einschließlich deren mit ihr im Sinne der §§ 15 ff. AktG verbundenen Unternehmen geschützte Inhalte abrufe, muss ich mich mit weiteren Daten für den Zugang zu diesen Inhalten registrieren. Im Gegenzug für diesen gebührenlosen Zugang zu redaktionellen Inhalten dürfen meine Daten im Sinne dieser Einwilligung für die hier genannten Zwecke verwendet werden. Dies gilt nicht für den Datenabgleich zu Marketingzwecken.
Recht auf Widerruf
Mir ist bewusst, dass ich diese Einwilligung jederzeit für die Zukunft widerrufen kann. Durch meinen Widerruf wird die Rechtmäßigkeit der aufgrund meiner Einwilligung bis zum Widerruf erfolgten Verarbeitung nicht berührt. Um meinen Widerruf zu erklären, kann ich als eine Möglichkeit das unter https://contact.vogel.de abrufbare Kontaktformular nutzen. Sofern ich einzelne von mir abonnierte Newsletter nicht mehr erhalten möchte, kann ich darüber hinaus auch den am Ende eines Newsletters eingebundenen Abmeldelink anklicken. Weitere Informationen zu meinem Widerrufsrecht und dessen Ausübung sowie zu den Folgen meines Widerrufs finde ich in der Datenschutzerklärung, Abschnitt Redaktionelle Newsletter.
Ein softwareorientiertes Programmiermodell
Livt übernimmt bewusst Konzepte, die aus modernen Programmiersprachen bekannt sind. Der Code wird mithilfe von Namespaces und Komponenten organisiert. Der Status wird durch Felder ausgedrückt. Das Verhalten ist in Funktionen und Prozessen mit klaren Sichtbarkeitsregeln gekapselt. Konstruktoren beschreiben, wie Komponenten miteinander verbunden sind, anstatt den Entwickler zu zwingen, Signalverbindungen auf niedriger Ebene manuell zu verwalten.
Gleichzeitig bleibt die Sprache eindeutig in Bezug darauf, was kombinatorisch und was sequenziell ist und wie das Timing definiert wird. Dadurch wird sichergestellt, dass die resultierende Hardware deterministisch und vorhersagbar bleibt, was für das FPGA- und ASIC-Design von entscheidender Bedeutung ist.
Dieses Modell ermöglicht es gemischten Teams, effektiv zu arbeiten. Entwickler von Embedded Software können nicht kritische oder anwendungsspezifische Logik implementieren, während sich FPGA-Ingenieure auf Architektur, Timing-Closure und Optimierung konzentrieren, wo ihr Fachwissen den größten Einfluss hat.
Ein Beispiel: Auslösen der FPGA-Logik über ein CPU-Register
Ein einfaches, aber repräsentatives Beispiel ist ein Prozessor, der durch Schreiben in ein speicherabgebildetes Register ein Verhalten innerhalb des FPGA auslöst. In Livt wird diese Grenze direkt dort ausgedrückt, wo das Verhalten definiert ist. Die folgende Komponente deklariert eine Busschnittstelle und bindet ein für die CPU sichtbares Registerbit mit HxS-Annotationen an einen Funktionsaufruf.
Im folgenden Beispiel wird ein AXI4-Lite-Bus verwendet. Avalon und Wishbone werden auf die gleiche Weise unterstützt, indem ein anderer Bustyp ausgewählt wird.
namespace Demo.Appusing Livt.HxS@Interface(BusType="AXI4Lite")component LedController{ led: out logic // A write to bit 0 of this register triggers Toggle(). // Because Toggle() has no parameters and no return value, // the compiler infers pure trigger semantics. @Register(Id="LedToggleTrigger", Address=0x4000_0000) public fn Toggle() { this.led = !this.led }}
An dieser Stelle ist es erwähnenswert, wie kompakt der Livt-Code bleibt. Die Komponente drückt nur das für die Aufgabe erforderliche wesentliche Verhalten aus, während die gesamte busbezogene Infrastruktur – einschließlich Registerdecodierung, Adresszuordnung, Zugriffshandshaking und protokollkonforme Bus-Transaktionen – automatisch vom Compiler und dem zugrunde liegenden Framework generiert wird. Dadurch wird eine ganze Klasse von busbezogenen Fehlern vermieden, die häufig bei der manuellen Implementierung von AXI4-Lite-Slave-Schnittstellen auftreten.
Ein Schreibvorgang in das Register an der Adresse 0x4000_0000 mit gesetztem Bit 0 bewirkt die Ausführung der Funktion. Aus Sicht des Compilers handelt es sich hierbei eindeutig um einen Trigger und nicht um ein Wertregister, da die Funktion keine Parameter akzeptiert und keinen Wert zurückgibt.
Wenn sich die Funktionssignatur in Zukunft ändert, kann der Compiler die Registersemantik automatisch anpassen. Ein geschriebener Wert kann an die Funktion übergeben oder ein Rückgabewert zum Zurücklesen bereitgestellt werden, ohne das gesamte Integrationskonzept zu ändern.
Verwendung auf der MCU-Seite (C, Memory-Mapped I/O)
Von der MCU-Seite aus sieht dies wie ein gewöhnlicher speicherabgebildeter Registerzugriff aus.
#include <stdint.h>#define LED_TOGGLE_TRIGGER_ADDR (0x40000000u)#define LED_TOGGLE_TRIGGER_BIT (1u << 0)static inline void Led_Toggle(void){ *(volatile uint32_t*)LED_TOGGLE_TRIGGER_ADDR = LED_TOGGLE_TRIGGER_BIT;}int main(void){ while (1) { Led_Toggle(); // delay via timer, busy wait, or RTOS service }}
Die Firmware bleibt trivial, während das Verhalten der Hardware klar definiert ist und sich eng an die Schnittstellenbeschreibung hält. Diese enge Kopplung von Verhalten und Registerzuordnung reduziert Integrationsfehler erheblich und verbessert die Wartbarkeit.
Ein Software-Ökosystem für das Hardware-Design
Livt ist nicht nur eine Sprache, sondern ein komplettes Ökosystem. Projekte folgen einer klaren Struktur, unterstützen Unit-Tests, lassen sich nahtlos in CI/CD-Pipelines integrieren und profitieren von KI-gestützten Tools. Dadurch können Hardware-Projekte Workflows übernehmen, die in der Softwareentwicklung seit Jahren Standard sind, und so die Zuverlässigkeit, Wartbarkeit und Entwicklungsgeschwindigkeit verbessern.
Ein wichtiger Teil dieses Ökosystems ist die Livt-Basisbibliothek. Sie bietet grundlegende Sprachfunktionen und wiederverwendbare Bausteine, die sonst immer wieder neu implementiert werden müssten. Anstatt mit rohen Primitiven zu beginnen, können Entwickler auf klar definierte, getestete Abstraktionen zurückgreifen, die sich projektübergreifend konsistent verhalten.
Der folgende Auszug gibt einen kleinen Einblick in die Namespaces, die bei der Verwendung von Livt verfügbar sind:
Livt.Protocol Namespace o SPI-, I2C-, UART-Master/Slaves o AXI-, Wishbone-, Avalon-Schnittstellen o Ethernet-Frame-Parser/Generatoren o USB-Paket-Handler
Livt.Math Namespace o Grundlegende Operationen (Abs, Min, Max, Clamp, Saturate) o Transzendentale Funktionen (Sin, Cos, Sqrt, Log, Exp, Pow) o Hilfsfunktionen für Festkommaarithmetik o Bitmanipulation (CountLeadingZeros, PopCount, BitReverse, RotateLeft/Right) o Statistische Funktionen (Average, Median, Variance, StdDev)
Livt.Signal-Namespace o FIR/IIR-Filterimplementierungen o FFT/IFFT o Fensterfunktionen (Hamming, Hanning, Blackman) o Korrelation und Konvolution o CRC/Prüfsummenrechner
Dies behebt direkt ein seit langem bestehendes Problem in der traditionellen HDL-basierten Entwicklung. VHDL leidet unter fragmentierten und inkonsistenten benutzerdefinierten Paket-Ökosystemen, in denen jedes Team – und oft jeder Entwickler – seine eigenen Hilfsfunktionen erstellt. Dies führt zu fehleranfälligen Code-Duplikaten, inkompatiblen Datentypdefinitionen zwischen Projekten und einem erheblichen langfristigen Wartungsaufwand. Das Fehlen einer umfassenden Standardbibliothek über die Grundtypen hinaus zwingt Ingenieure dazu, gängige Funktionen immer wieder neu zu erfinden.
Livt entfernt sich von diesem Modell. Anstatt Ad-hoc-Dienstprogramm-Pakete zu fördern, bietet es eine kohärente Basisbibliothek und ein strukturiertes Paketsystem. Darüber hinaus fördert Livt die Entwicklung auf Paket- und Framework-Ebene, anstatt Hardware als fertige, undurchsichtige IP-Blöcke mit nur minimalen Konfigurationsoptionen zu verteilen. Pakete und Frameworks legen Struktur und Absicht offen, wodurch sie leichter zu verstehen, anzupassen und zu erweitern sind.
Das folgende Beispiel veranschaulicht, wie diese Bausteine in der Praxis zusammenwirken. Die Komponente „UartController“ wird unter Verwendung von Funktionen aus dem Namespace „Livt.Protocol“ zusammengestellt und über eine HxS-Register-Schnittstelle einem Prozessor zur Verfügung gestellt. Anstatt eine fertige Black-Box-IP zu integrieren, baut das Design auf der wiederverwendbaren Komponente „BufferedUart“ auf Framework-Ebene auf und fügt mit wenigen Zeilen Code anwendungsspezifisches Verhalten hinzu.
namespace Demo.Appusing Livt.HxSusing Livt.Protocol@Interface(BusType="AXI4Lite")component UartController{ uart: BufferedUart new (rx: in logic, tx: out logic) { this.uart = new BufferedUart(rx, tx) } @Register(Id="SayHelloWorldTrigger", Address=0x4000_0000) public fn SayHelloWorld() { let greeting = "Hello, World!".Encode() this.uart.Send(greeting) }}
Dieser Ansatz reduziert die Lernkurve für neue Entwickler erheblich, verbessert die Wiederverwendbarkeit über Teams und Projekte hinweg und ermöglicht eine Skalierung der Hardwareentwicklung, wie sie auch in modernen Software-Ökosystemen üblich ist.
Kein Ersatz für FPGA-Ingenieure
Livt macht FPGA-Ingenieure nicht überflüssig, und das ist auch nicht sein Ziel. Low-Level-Optimierung, Timing-Closure, Clock-Domain-Design, FSM-Tuning und herstellerspezifische Primitive erfordern nach wie vor fundiertes Hardware-Know-how.
Livt sorgt dafür, dass dieses Fachwissen dort eingesetzt wird, wo es wirklich wichtig ist. Ingenieure verbringen weniger Zeit mit sich wiederholenden Standardaufgaben und haben mehr Zeit für Architektur, Leistung und Korrektheit.
Livt verändert die Art und Weise, wie FPGA- und ASIC-Entwicklung in moderne Engineering-Teams integriert wird. Es senkt die Hürden für Softwareentwickler, einen sinnvollen Beitrag zur Hardware-Logik zu leisten, und bewahrt gleichzeitig die für echte Hardware erforderliche Präzision und Zuverlässigkeit.
Gleichzeitig wird die Übernahme moderner Softwarekonzepte immer wichtiger, um die Vorteile der KI-gestützten Programmierung und autonomer Entwicklungsagenten nutzen zu können. Diese Tools basieren auf einer klaren Struktur, einer expliziten Absicht und konsistenten Abstraktionen – Eigenschaften, die in traditionellen HDL-basierten Workflows weitgehend fehlen. Durch die Übernahme softwareorientierter Designprinzipien macht Livt Hardware-Designs nicht nur für Menschen, sondern auch für KI-basierte Tools zugänglicher, die vom Livt-Ökosystem vollständig unterstützt werden.
Wenn Sie jemals an einen Punkt gelangt sind, an dem Software allein nicht mehr ausreichte, Hardware aber unerreichbar schien, dann ist Livt genau für diesen Moment konzipiert. (sg)