Was ist SystemC und warum nutzt man es?
Veröffentlicht am
- embedded systems
- informatik
- systemc
- wissenschaft
- c/cpp

Ein einsteigerfreundlicher Leitfaden zur Modellierung paralleler Hardware, simulierter physikalischer Zeit und des Zusammenspiels von Hardware und Software in modernem Standard-C++.
Inhaltsverzeichnis
- Warum Embedded-Entwickler virtuelle Hardware brauchen
- Was ist SystemC?
- Warum SystemC in Embedded Systems einsetzen?
- Installation von SystemC unter Linux
- Praxisbeispiel: Modellierung eines Embedded-Temperaturwächters
- Fazit
- Referenzen
1. Warum Embedded-Entwickler virtuelle Hardware brauchen
Ein eingebettetes System (Embedded System) ist eine spezialisierte Recheneinheit, die für eine klar definierte Aufgabe in der realen Welt entwickelt wird – oft unter strengen Vorgaben hinsichtlich Echtzeitverhalten, Speicherplatz und Energieverbrauch. Von Antiblockiersystemen im Automobil und medizinischen Wearables bis hin zu Industriesensoren und smarten Thermostaten vereint jedes eingebettete Produkt zwei eng verzahnte Welten: maßgeschneiderte digitale Hardware (Prozessoren, Timer, Bussysteme und Sensoren) sowie eingebettete Software (Firmware, Gerätetreiber und Echtzeitbetriebssysteme).
Klassischerweise führte diese enge Kopplung zu einem kostspieligen Engpass. Der Entwurf und die Fertigung eines kundenspezifischen System-on-Chip (SoC) oder einer Leiterplatte dauern viele Monate. Müssen Firmware-Entwickler warten, bis physische Chips aus der Fabrik eintreffen, bevor sie die erste Zeile Treibercode testen können, führt ein spät entdeckter Integrationsfehler im schlimmsten Fall zu einem teuren Hardware-Redesign. Moderne Entwicklerteams lösen dieses Dilemma durch Virtual Prototyping: Sie erstellen ein ausführbares Softwaremodell der Hardware, sodass Architekten und Firmware-Entwickler das Gesamtsystem bereits auf einem gewöhnlichen Computer entwerfen, testen und debuggen können, lange bevor reales Silizium existiert. Genau für diese Aufgabe wurde SystemC geschaffen.
2. Was ist SystemC?
SystemC ist eine quelloffene C++-Klassenbibliothek mit integriertem ereignisgesteuertem Simulationskern für die Modellierung auf elektronischer Systemebene (Electronic System-Level, ESL), das Hardware-Software-Co-Design und die Architekturverifikation. Ursprünglich 1999 von der Open SystemC Initiative (heute Teil der Accellera Systems Initiative) ins Leben gerufen, ist SystemC keineswegs nur ein informeller Industriestandard, sondern eine offizielle internationale Norm des IEEE unter der Bezeichnung IEEE Std 1666 (zuletzt aktualisiert als IEEE Std 1666-2023 auf Basis von modernem C++17).
Da SystemC vollständig als reguläre C++-Bibliothek und nicht als proprietäre Spezialsprache umgesetzt ist, wird kein spezieller Hardware-Compiler benötigt. Jeder standardkonforme C++-Compiler – etwa GCC oder Clang – übersetzt ein SystemC-Modell direkt in einen nativen, ausführbaren Simulator.
2.1 SystemC vs. Embedded C/C++: Ein häufiges Missverständnis
Gerade für Einsteiger im Bereich Embedded Systems ist die klare Abgrenzung zwischen Embedded C/C++ und SystemC entscheidend:
Embedded C/C++ (Ziel-Firmware): Wird in Maschinencode cross-kompiliert und direkt auf einen physischen Mikrocontroller (z. B. STM32, AVR oder ESP32) geflasht, um im fertigen Gerät zu laufen.
SystemC (Systemmodellierung & Simulation): Wird auf einer Workstation oder einem Server kompiliert und ausgeführt, um die Hardwarekomponenten selbst – Taktsignale, Leitungen, Speicherbusse, Sensoren und Hardwarebeschleuniger – im Zusammenspiel mit der Firmware zu simulieren.
Warum lässt sich digitale Hardware nicht ohne Weiteres in reinem Standard-C++ modellieren? Reguläres C++ arbeitet Befehle sequenziell (Anweisung für Anweisung) ab und kennt von Haus aus kein Konzept für Hardware-Taktzyklen. Echte digitale Schaltungen arbeiten hingegen parallel (nebenläufig) – Dutzende unabhängige Funktionsblöcke reagieren exakt in derselben Nanosekunde – und hängen von physikalischer Zeit ab. SystemC erweitert C++ sowohl um kooperative Hardware-Nebenläufigkeit als auch um eine präzise simulierte Zeitachse.
2.2 Zentrale Architekturbausteine
Jedes SystemC-Modell setzt sich aus fünf grundlegenden Konzepten im Namensraum sc_core zusammen:
Module (
SC_MODULE): Abgeschlossene Bausteine, die Hardware- oder Systemkomponenten (wie Timer, Sensorschnittstellen oder Bus-Router) repräsentieren und hierarchisch verschachtelt werden können.Ports und Kanäle (
sc_in,sc_out,sc_signal,sc_fifo): Typisierte Schnittstellen sowie Verbindungsleitungen oder Warteschlangen, die Module sauber miteinander koppeln, ohne interne Zeiger fest zu verdrahten.Nebenläufige Prozesse (
SC_METHODundSC_THREAD): Methoden, die vom Simulationskern eingeplant werden, um parallele Hardwareabläufe nachzubilden. EineSC_METHODreagiert auf Ereignisse und kehrt sofort ohne Blockieren zurück, während einSC_THREADals Koroutine läuft und sich überwait()für eine bestimmte Simulationszeit pausieren lässt.Simulierte Zeit und Ereignisse (
sc_timeundsc_event): Eine virtuelle Hardwareuhr für Zeiteinheiten von Femtosekunden (SC_FS) bis Sekunden (SC_SEC), völlig unabhängig von der Rechengeschwindigkeit des Host-PCs.Simulationseinstiegspunkt (
sc_mainundsc_start): Die SystemC-Bibliothek stellt intern die C++-Funktionmain()bereit, initialisiert den Simulationskern und ruft anschließend Ihre Funktionsc_main()auf, um Module zu verbinden und die Simulation mittelssc_start()zu starten.
Bevor wir tiefer einsteigen, zeigt das folgende kompakte Beispiel, wie übersichtlich ein zeitgesteuertes Hardwaremodul in modernem SystemC aussieht:
#include <iostream>
#include <systemc>
using namespace sc_core;
SC_MODULE(Heartbeat) {
SC_CTOR(Heartbeat) {
SC_THREAD(run); // Register a concurrent hardware thread
}
void run() {
while (true) {
std::cout << "LED toggle at " << sc_time_stamp() << '\n';
wait(500, SC_MS); // Pause this module for 500 ms of simulated time
}
}
};
int sc_main(int, char*[]) {
Heartbeat led("led"); // Instantiate hardware block
sc_start(1500, SC_MS); // Simulate 1.5 seconds of hardware time
return 0;
}
Kompiliert und gestartet ist dieses Programm auf Ihrem Computer in weniger als einer Millisekunde realer Echtzeit beendet – dennoch schreitet seine interne Simulationsuhr exakt über 0 s, 500 ms und 1 s virtueller Hardwarezeit voran.
3. Warum SystemC in Embedded Systems einsetzen?
3.1 Abstraktionsebenen: Warum SystemC so schnell simuliert
Traditionell entwerfen Hardware-Ingenieure digitale Schaltungen mithilfe von Hardwarebeschreibungssprachen (HDLs) wie VHDL, Verilog oder SystemVerilog auf der Register-Transfer-Ebene (RTL). RTL beschreibt jeden einzelnen Signalwechsel und jede Taktflanke – unverzichtbar für die spätere Synthese echter Transistoren, aber viel zu detailliert, wenn man ein Betriebssystem booten oder komplexe Firmware testen möchte. Schon wenige Sekunden Prozessorlaufzeit auf voller RTL-Ebene zu simulieren, kann Stunden dauern.
Ein verbreiteter Irrtum lautet, SystemC sei allein deshalb schneller als VHDL oder Verilog, weil es einen ereignisgesteuerten Simulationskern nutzt. Tatsächlich arbeiten VHDL- und Verilog-Simulatoren ebenfalls ereignisgesteuert. SystemC erzielt seinen enormen Geschwindigkeitsvorsprung – oft 100- bis 1.000-mal schneller als RTL – durch Transaction-Level Modeling (TLM-2.0), das direkt in IEEE Std 1666 integriert ist. Anstatt Dutzende einzelner Adress-, Daten- und Handshake-Leitungen Takt für Takt zu berechnen, überträgt ein TLM-Modell ein komplettes Datenpaket mit einem einzigen C++-Funktionsaufruf (b_transport) inklusive realistischer Zeitannotation.
| Abstraktionsebene | Typische Sprache | Zeit- & Kommunikationsdetail | Primärer Embedded-Einsatzbereich |
|---|---|---|---|
| Register-Transfer-Ebene (RTL) | Verilog, VHDL, SystemVerilog | Takt- und pin-genau (jede Taktflanke und Leitung) | Chipherstellung (Synthese) und Hardwareverifikation auf Gatterebene |
| Approximately-Timed TLM | SystemC + TLM-2.0 | Mehrphasige Bustransaktionen mit Arbitrierung und Latenz | SoC-Busarchitektur, Engpass- und Leistungsanalyse |
| Loosely-Timed TLM | SystemC + TLM-2.0 | Einzelaufruf-Transaktionen (b_transport) mit grobem Timing |
Virtuelle Prototypen sowie frühe Firmware- und OS-Entwicklung |
3.2 Wichtige Anwendungsfelder im Entwicklungszyklus
Virtual Prototyping („Shift-Left“ in der Firmware-Entwicklung): Firmware-Teams entwickeln und testen Gerätetreiber, Interrupt-Routinen und RTOS-Tasks auf einer virtuellen SystemC-Plattform, Monate bevor reale Prototypenplatinen vorliegen.
Architektur- und Entwurfsraumexploration (Design Space Exploration): Systemarchitekten vergleichen verschiedene Varianten – etwa Cache-Größen, DMA-Puffertiefen oder Bustopologien – unter realistischer Last, um Latenz und Energiebedarf frühzeitig zu optimieren.
Hardware-Software-Partitionierung: Da sowohl Hardwaremodelle als auch Softwarealgorithmen in C++ vorliegen, lassen sich rechenintensive Aufgaben (wie Signalfilterung, Motorregelung oder Kryptografie) gezielt vermessen und optimal zwischen CPU-Firmware und dedizierten Hardwarebeschleunigern aufteilen.
Pre-Silicon-Verifikation (Goldene Referenzmodelle): Verifikationsteams nutzen übersichtliche SystemC-Verhaltensmodelle als verlässliche Referenz, gegen die komplexe RTL-Entwürfe in Verilog oder VHDL automatisiert geprüft werden.
High-Level-Synthese (HLS): Spezialisierte EDA-Werkzeuge können synthetisierbare Teilmengen algorithmischen SystemC-/C++-Codes automatisch in RTL-Hardwarebeschreibungen für FPGAs und ASICs übersetzen.
4. Installation von SystemC unter Linux
Linux ist die führende Plattform für Embedded-Toolchains und Electronic Design Automation. Im Folgenden finden Sie zwei bewährte Installationswege: eine schnelle Paketinstallation für den sofortigen Einstieg sowie den offiziellen Quellcode-Build mit CMake für das aktuelle SystemC 3.0+ (IEEE Std 1666-2023), das einen C++17-fähigen Compiler (ab GCC 9.3 oder Clang 13) sowie CMake ab Version 3.16 voraussetzt.
4.1 Option A: Schnellinstallation per Paketmanager (Ubuntu / Debian)
Unter aktuellen Ubuntu- und Debian-Distributionen lassen sich die Entwicklungsheader und die Laufzeitbibliothek von Accellera SystemC direkt aus den offiziellen Paketquellen installieren:
sudo apt update
sudo apt install -y build-essential cmake libsystemc-dev
4.2 Option B: SystemC 3.0+ mit CMake aus dem Quellcode bauen
Falls Ihre Distribution eine ältere Version bereitstellt oder Sie die neuesten Upstream-Funktionen von Accellera nutzen möchten, kompilieren Sie SystemC mit CMake direkt aus dem Quellcode. Die Option -DCMAKE_INSTALL_LIBDIR=lib sorgt distributionsübergreifend für einen einheitlichen Bibliothekspfad:
# 1. Install build prerequisites
sudo apt update && sudo apt install -y build-essential cmake git
# 2. Clone the official Accellera SystemC repository (release 3.0.2)
git clone --branch 3.0.2 --depth 1 https://github.com/accellera-official/systemc.git
cd systemc
# 3. Configure an out-of-source CMake build (C++17 required for SystemC 3.0+)
cmake -B build \
-DCMAKE_CXX_STANDARD=17 \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="$HOME/systemc" \
-DCMAKE_INSTALL_LIBDIR=lib
# 4. Compile in parallel and install to ~/systemc
cmake --build build -j"$(nproc)"
cmake --install build
Wenn Sie SystemC nach $HOME/systemc installiert haben (Option B) und Programme direkt auf der Kommandozeile mit g++ übersetzen möchten, fügen Sie die Pfade zu Ihrer Shell-Konfiguration hinzu:
echo 'export SYSTEMC_HOME="$HOME/systemc"' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH="$SYSTEMC_HOME/lib:${LD_LIBRARY_PATH}"' >> ~/.bashrc
source ~/.bashrc
5. Praxisbeispiel: Modellierung eines Embedded-Temperaturwächters
Um das Zusammenspiel von Hardware und Steuerung in SystemC praktisch zu erleben, modellieren wir eine vereinfachte Temperaturüberwachung – ähnlich wie sie Batteriezellen in Elektrofahrzeugen oder Netzteilen schützt:
Sensor-Peripherie (
TemperatureSensor): Nutzt einenSC_THREAD, um alle10 mssimulierter Zeit einen Temperaturwert zu erfassen und über einen Ausgangsport (sc_out<int>) auszugeben.Embedded-Controller (
CoolingController): Nutzt eine ereignisgesteuerteSC_METHOD, die auf Änderungen am Eingangsport (sc_in<int>) reagiert und ein Lüfter-Steuersignal (sc_out<bool>) aktiviert, sobald die Temperatur mindestens75 °Cerreicht.Top-Level-Verschaltung (
sc_main): Instanziiert beide Module, verbindet ihre Ports übersc_signal-Leitungen und startet die Simulation für60 ms.
#include <iostream>
#include <systemc>
using namespace sc_core;
// 1. Hardware Peripheral Module: Periodic Temperature Sensor
SC_MODULE(TemperatureSensor) {
sc_out<int> temp_out;
SC_CTOR(TemperatureSensor) {
SC_THREAD(sample_loop);
}
void sample_loop() {
const int readings[] = {65, 72, 78, 81, 70};
for (int temp : readings) {
wait(10, SC_MS); // Advance simulated time by 10 ms
temp_out.write(temp); // Drive new reading onto signal wire
}
}
};
// 2. Embedded Controller Module: Reacts to Sensor Updates
SC_MODULE(CoolingController) {
sc_in<int> temp_in;
sc_out<bool> fan_enable;
static constexpr int THRESHOLD_C = 75;
SC_CTOR(CoolingController) {
SC_METHOD(evaluate_temperature);
sensitive << temp_in; // Trigger whenever temp_in changes
dont_initialize(); // Wait for the first real sensor event
}
void evaluate_temperature() {
int current_temp = temp_in.read();
bool turn_on = (current_temp >= THRESHOLD_C);
fan_enable.write(turn_on);
std::cout << "[" << sc_time_stamp() << "] "
<< "Temp: " << current_temp << " C -> Cooling Fan: "
<< (turn_on ? "ON" : "OFF") << '\n';
}
};
// 3. Top-Level Entry Point: Wire Modules and Start Simulation
int sc_main(int, char*[]) {
sc_signal<int> temp_wire;
sc_signal<bool> fan_wire;
TemperatureSensor sensor("sensor");
CoolingController controller("controller");
sensor.temp_out(temp_wire);
controller.temp_in(temp_wire);
controller.fan_enable(fan_wire);
sc_start(60, SC_MS); // Run simulation for 60 ms
return 0;
}
5.1 Kompilieren und Ausführen der Simulation
Speichern Sie den obigen Quellcode als thermal_monitor.cpp zusammen mit der folgenden Datei CMakeLists.txt, die sowohl mit dem APT-Paket (Option A) als auch mit einer eigenen Quellcode-Installation (Option B) automatisch funktioniert:
cmake_minimum_required(VERSION 3.16)
project(thermal_monitor LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(SystemCLanguage QUIET CONFIG)
add_executable(thermal_monitor thermal_monitor.cpp)
if(SystemCLanguage_FOUND)
target_link_libraries(thermal_monitor PRIVATE SystemC::systemc)
else()
target_link_libraries(thermal_monitor PRIVATE systemc)
endif()
Übersetzen und starten Sie die Simulation anschließend mit CMake (oder alternativ direkt mit g++):
# Build with CMake (append -DCMAKE_PREFIX_PATH="$HOME/systemc" if built from source)
cmake -B build && cmake --build build
./build/thermal_monitor
# Alternative: Compile directly in one command with g++
# For Option A (APT package):
g++ -std=c++17 -Wall -Wextra thermal_monitor.cpp -lsystemc -o thermal_monitor && ./thermal_monitor
# For Option B (Source build in $SYSTEMC_HOME):
# g++ -std=c++17 -Wall -Wextra -I"$SYSTEMC_HOME/include" -L"$SYSTEMC_HOME/lib" -Wl,-rpath,"$SYSTEMC_HOME/lib" thermal_monitor.cpp -lsystemc -o thermal_monitor && ./thermal_monitor
Beim Ausführen gibt der Simulationskern folgendes Protokoll mit exakten Zeitstempeln aus:
SystemC 3.0.2-Accellera --- Nov 5 2025 12:44:46
Copyright (c) 1996-2025 by all Contributors,
ALL RIGHTS RESERVED
[10 ms] Temp: 65 C -> Cooling Fan: OFF
[20 ms] Temp: 72 C -> Cooling Fan: OFF
[30 ms] Temp: 78 C -> Cooling Fan: ON
[40 ms] Temp: 81 C -> Cooling Fan: ON
[50 ms] Temp: 70 C -> Cooling Fan: OFF
Beachten Sie drei wesentliche Hardware-Eigenschaften, die hier in nur fünfzig Zeilen Standard-C++ abgebildet werden:
Gezielte Initialisierung: Der Aufruf von
dont_initialize()imCoolingControllerverhindert eine verfrühte Auswertung zum Zeitpunkt0 s, noch bevor der Sensor bei10 msseinen ersten Messwert liefert.Nebenläufigkeit ohne Polling: Anders als eine aktive Warteschleife in klassischer Software verbraucht
evaluate_temperature()keinerlei Simulationszeit, solange sich der Wert auftemp_wirenicht ändert – exakt wie ein Hardware-Komparator oder eine Interrupt-Leitung.Entkoppelte Architektur: Keines der beiden Module kennt die interne Implementierung des anderen; beide kommunizieren ausschließlich über typisierte Ports und
sc_signal-Kanäle insc_main(), sodass sich problemlos Signalverläufe aufzeichnen oder reale Firmware-Modelle einbinden lassen.
6. Fazit
Für Einsteiger im Bereich Embedded Systems schlägt SystemC (IEEE Std 1666) die Brücke zwischen Softwareentwicklung und digitalem Hardwaredesign. Indem es Standard-C++ um modulare Hardwarehierarchien, nebenläufige Prozesse, typisierte Kommunikationskanäle und simulierte physikalische Zeit erweitert, ermöglicht es Entwicklerteams, Architekturen zu bewerten, Peripheriebausteine zu verifizieren und Firmware auf schnellen virtuellen Prototypen zu entwickeln, lange bevor reale Chips gefertigt werden.
Sobald Sie mit modularen SC_MODULE-Entwürfen wie dem gezeigten Temperaturwächter vertraut sind, bieten sich als nächste Schritte die Aufzeichnung von Signalverläufen in VCD-Dateien (sc_create_vcd_trace_file) zur Analyse in GTKWave sowie der Einstieg in TLM-2.0-Sockets zur schnellen Modellierung speicherabgebildeter Prozessorbusse an.
7. Referenzen
IEEE Standards Association & Accellera Systems Initiative. (2023). IEEE Standard for Standard SystemC Language Reference Manual (IEEE Std 1666-2023). Kostenlos verfügbar über das IEEE GET Program unter https://systemc.org/
Accellera Systems Initiative. SystemC Standards and Proof-of-Concept Library Downloads. https://www.accellera.org/downloads/standards/systemc
Accellera Systems Initiative. Official SystemC Open-Source Reference Implementation (GitHub-Repository). https://github.com/accellera-official/systemc
Black, D. C., Donovan, J., Bunton, B., & Keist, A. (2010). SystemC: From the Ground Up (2nd ed.). Springer. https://doi.org/10.1007/978-0-387-69958-5
Grötker, T., Liao, S., Martin, G., & Swan, S. (2002). System Design with SystemC. Springer / Kluwer Academic Publishers. https://doi.org/10.1007/b116588
Kommentare 0
Noch keine Kommentare.
Kommentar schreiben