SystemC Source Map & LRM Alignment
A guided map of the official source tree: kernel, communication, datatypes, TLM, and utilities.
SystemC Source Map & LRM Alignment
The official SystemC implementation is worth reading because it explains the API design. You do not need to read it linearly. Read it as a map of responsibilities, aligned directly with the IEEE 1666 Language Reference Manual (LRM).
The public repository is accellera-official/systemc. Directory names can move across releases, but the conceptual areas remain stable. Understanding how these conceptual areas map to the C++ implementation is the key to deep SystemC mastery.
1. Kernel (LRM Section 4: Elaboration and Simulation)
The kernel area contains the scheduler, simulation context, process classes, events, time, reports, and object hierarchy. Names you will encounter include:
sc_simcontext: the central simulation context. It holds the event queues and Delta Cycle loop.sc_object: the base class for hierarchical objects.sc_module: structural hierarchy and process registration support.sc_event: event notification and wait support.sc_process_b,sc_method_process,sc_thread_process: implementation of methods and coroutines.
Read this area when you want to understand sc_start(), delta cycles, process readiness, and why wait() is legal in an SC_THREAD but throws an exception in an SC_METHOD.
2. Communication (LRM Section 6 & 7: Channels and Interfaces)
The communication area contains ports, exports, interfaces, primitive channels, signals, FIFOs, mutexes, semaphores, and clocks.
sc_interface: Pure virtual base class.sc_port: The mechanism for a module to call an interface.sc_signal: The fundamental channel implementing request-update semantics.
This is where the object model becomes a network. Ports do not merely hold C++ pointers. They participate in binding policy, interface checking, and simulation setup.
3. Datatypes (LRM Section 7: Data Types)
SystemC includes hardware-friendly datatypes such as:
- Arbitrary precision integers (
sc_bigint,sc_biguint) - Bit vectors (
sc_bv) - Logic vectors (
sc_lv,sc_logic) - Fixed-point types (
sc_fixed)
These types exist because plain C++ integer behavior cannot model hardware realities like four-state logic ('0', '1', 'Z', 'X') or precise bit-width truncation.
4. TLM (LRM Section 10-16: TLM-2.0)
The TLM area includes generic payloads, phases, sockets, target and initiator interfaces, and utility helpers. Sockets are not a separate universe. They package standard SystemC ports, exports, callbacks, and interfaces into a highly optimized bus-modeling form.
Bringing it All Together: Complete Example
To illustrate how these four main quadrants of the SystemC source map (Kernel, Communication, Datatypes, TLM) synthesize into a single LRM-compliant model, here is a complete executable example.
#include <systemc>
#include <tlm>
#include <tlm_utils/simple_initiator_socket.h>
#include <tlm_utils/simple_target_socket.h>
#include <iostream>
using namespace sc_core;
using namespace sc_dt; // Datatypes
// ---------------------------------------------------------
// A module demonstrating Kernel processes, Communication
// channels, Datatypes, and TLM-2.0 Sockets.
// ---------------------------------------------------------
SC_MODULE(SourceMapDemo) {
// --- COMMUNICATION ---
sc_in<bool> clk{"clk"};
// --- COMMUNICATION & DATATYPES ---
// A primitive channel wrapping a 4-bit unsigned integer
sc_signal<sc_uint<4>> counter{"counter"};
// --- TLM ---
tlm_utils::simple_initiator_socket<SourceMapDemo> init_socket{"init_socket"};
SC_CTOR(SourceMapDemo) {
// --- KERNEL ---
// Registering a clocked thread with the simulation context
SC_CTHREAD(clocked_thread, clk.pos());
}
void clocked_thread() {
// Initialization
counter.write(0);
while (true) {
// Kernel: Yield execution back to the scheduler
wait();
// Datatypes: Read, manipulate, and write the 4-bit type
sc_uint<4> val = counter.read() + 1;
counter.write(val);
std::cout << "[Demo] Clock ticked. Counter: " << val << "\n";
// TLM: Generate a transaction when the counter overflows (4-bit overflow)
if (val == 0) {
std::cout << "[Demo] Counter overflowed! Sending TLM transaction.\n";
tlm::tlm_generic_payload trans;
sc_time delay = SC_ZERO_TIME;
trans.set_command(tlm::TLM_WRITE_COMMAND);
trans.set_address(0x100);
trans.set_data_length(4);
trans.set_streaming_width(4);
trans.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
// Blocking transport call
init_socket->b_transport(trans, delay);
if (trans.is_response_ok()) {
std::cout << "[Demo] TLM transaction completed successfully.\n";
}
}
}
}
};
// Target to satisfy the TLM binding
SC_MODULE(DummyTarget) {
tlm_utils::simple_target_socket<DummyTarget> target_socket{"target_socket"};
SC_CTOR(DummyTarget) {
target_socket.register_b_transport(this, &DummyTarget::b_transport);
}
void b_transport(tlm::tlm_generic_payload& trans, sc_time& delay) {
std::cout << " -> [Target] Received transaction at address 0x"
<< std::hex << trans.get_address() << "\n";
trans.set_response_status(tlm::TLM_OK_RESPONSE);
}
};
// Top Level
int sc_main(int argc, char* argv[]) {
// Kernel: Clock generation
sc_clock clk("clk", 10, SC_NS);
SourceMapDemo demo("demo");
DummyTarget tgt("tgt");
// Communication: Structural binding during Elaboration Phase
demo.clk(clk);
demo.init_socket.bind(tgt.target_socket);
std::cout << "Starting Simulation...\n";
// Kernel: Enter Simulation Phase
sc_start(170, SC_NS);
std::cout << "Simulation Complete.\n";
return 0;
}Explanation of the Execution
When you run this simulation, the sc_clock drives the SC_CTHREAD. The sc_uint<4> datatype safely rolls over from 15 to 0. When it hits 0, it triggers the TLM-2.0 socket, bridging the cycle-accurate RTL abstraction with the Loosely Timed VP abstraction.
By understanding how these source map quadrants interact, you can read any SystemC codebase with confidence.
Comments and Corrections