Zum Hauptinhalt springen

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

  1. Warum Embedded-Entwickler virtuelle Hardware brauchen
  2. Was ist SystemC?
  3. Warum SystemC in Embedded Systems einsetzen?
  4. Installation von SystemC unter Linux
  5. Praxisbeispiel: Modellierung eines Embedded-Temperaturwächters
  6. Fazit
  7. 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_METHOD und SC_THREAD): Methoden, die vom Simulationskern eingeplant werden, um parallele Hardwareabläufe nachzubilden. Eine SC_METHOD reagiert auf Ereignisse und kehrt sofort ohne Blockieren zurück, während ein SC_THREAD als Koroutine läuft und sich über wait() für eine bestimmte Simulationszeit pausieren lässt.

  • Simulierte Zeit und Ereignisse (sc_time und sc_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_main und sc_start): Die SystemC-Bibliothek stellt intern die C++-Funktion main() bereit, initialisiert den Simulationskern und ruft anschließend Ihre Funktion sc_main() auf, um Module zu verbinden und die Simulation mittels sc_start() zu starten.

Bevor wir tiefer einsteigen, zeigt das folgende kompakte Beispiel, wie übersichtlich ein zeitgesteuertes Hardwaremodul in modernem SystemC aussieht:

heartbeat.cpp — Minimales SystemC-Modul mit simulierter Zeit
#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

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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:

SystemC per APT installieren (Ubuntu/Debian)
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:

SystemC 3.0.2 aus dem Quellcode kompilieren und installieren
# 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:

Optional: SYSTEMC_HOME in ~/.bashrc einrichten
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 einen SC_THREAD, um alle 10 ms simulierter Zeit einen Temperaturwert zu erfassen und über einen Ausgangsport (sc_out<int>) auszugeben.

  • Embedded-Controller (CoolingController): Nutzt eine ereignisgesteuerte SC_METHOD, die auf Änderungen am Eingangsport (sc_in<int>) reagiert und ein Lüfter-Steuersignal (sc_out<bool>) aktiviert, sobald die Temperatur mindestens 75 °C erreicht.

  • Top-Level-Verschaltung (sc_main): Instanziiert beide Module, verbindet ihre Ports über sc_signal-Leitungen und startet die Simulation für 60 ms.

thermal_monitor.cpp
#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:

CMakeLists.txt
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++):

Simulation kompilieren und starten
# 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:

Simulationsausgabe
        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() im CoolingController verhindert eine verfrühte Auswertung zum Zeitpunkt 0 s, noch bevor der Sensor bei 10 ms seinen ersten Messwert liefert.

  • Nebenläufigkeit ohne Polling: Anders als eine aktive Warteschleife in klassischer Software verbraucht evaluate_temperature() keinerlei Simulationszeit, solange sich der Wert auf temp_wire nicht ä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 in sc_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

  1. 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/

  2. Accellera Systems Initiative. SystemC Standards and Proof-of-Concept Library Downloads. https://www.accellera.org/downloads/standards/systemc

  3. Accellera Systems Initiative. Official SystemC Open-Source Reference Implementation (GitHub-Repository). https://github.com/accellera-official/systemc

  4. 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

  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