Chapter 7: SystemC 1666-2023 LRM

LRM Bridge: TLM Reference Map

Blocking transport, non-blocking transport, generic payload, phases, sockets, DMI, debug transport, and temporal decoupling.

Listen to this lessonAudiobook mode

How to Read This Lesson

This lesson is an LRM bridge. We translate standard language into the questions you actually ask while debugging and reviewing models.

Transaction Level Modeling (TLM 2.0), defined in the IEEE 1666 standard, allows models to communicate through abstract C++ data structures (tlm_generic_payload) rather than individual pin toggles. This can dramatically increase simulation speed when the abstraction is chosen well.

Now let's look at how the Accellera TLM kernel defines these constructs under the hood.

Standard and source context

Complete TLM 2.0 Base Protocol Example

This sc_main example demonstrates the essential components of TLM: the generic payload, socket binding, blocking transport, and correct target response mechanics.

#include <systemc>
#include <tlm>
#include <tlm_utils/simple_initiator_socket.h>
#include <tlm_utils/simple_target_socket.h>
 
// 1. TLM Initiator
SC_MODULE(TLM_Initiator) {
    tlm_utils::simple_initiator_socket<TLM_Initiator> socket;
    
    SC_CTOR(TLM_Initiator) : socket("socket") {
        SC_THREAD(run);
    }
 
    void run() {
        tlm::tlm_generic_payload trans;
        sc_core::sc_time delay = sc_core::SC_ZERO_TIME;
        uint32_t data = 0x12345678;
 
        // Populate the Generic Payload (Strict LRM rules)
        trans.set_command(tlm::TLM_WRITE_COMMAND);
        trans.set_address(0x1000);
        trans.set_data_ptr(reinterpret_cast<unsigned char*>(&data));
        trans.set_data_length(4);
        trans.set_streaming_width(4); 
        trans.set_byte_enable_ptr(0); // 0 means all bytes enabled
        trans.set_dmi_allowed(false);
        trans.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE);
 
        std::cout << "@" << sc_core::sc_time_stamp() << " [Init] Sending WRITE to 0x1000" << std::endl;
        
        // Blocking Transport Call
        socket->b_transport(trans, delay);
 
        // Check Response
        if (trans.is_response_error()) {
            SC_REPORT_ERROR("TLM", "Transaction returned with error response!");
        } else {
            std::cout << "@" << sc_core::sc_time_stamp() << " [Init] WRITE Success. Delay returned: " 
                      << delay << std::endl;
            wait(delay); // Yield to the scheduler to account for annotated delay
        }
    }
};
 
// 2. TLM Target
SC_MODULE(TLM_Target) {
    tlm_utils::simple_target_socket<TLM_Target> socket;
    
    SC_CTOR(TLM_Target) : socket("socket") {
        socket.register_b_transport(this, &TLM_Target::b_transport);
    }
 
    void b_transport(tlm::tlm_generic_payload& trans, sc_core::sc_time& delay) {
        if (trans.get_address() == 0x1000 && trans.get_command() == tlm::TLM_WRITE_COMMAND) {
            // Annotate processing delay
            delay += sc_core::sc_time(10, sc_core::SC_NS);
            
            // MANDATORY: Target must explicitly set the response status
            trans.set_response_status(tlm::TLM_OK_RESPONSE);
        } else {
            trans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE);
        }
    }
};
 
int sc_main(int argc, char* argv[]) {
    TLM_Initiator init("init");
    TLM_Target target("target");
    
    init.socket.bind(target.socket);
    
    sc_core::sc_start();
    return 0;
}

Transport Interfaces & Implementations

Blocking Transport (b_transport)

Used for Loosely Timed (LT) modeling. Under the Hood: b_transport is simply a purely virtual C++ method declared in tlm_fw_transport_if. When an initiator calls it, because of sc_port proxy resolution, the execution jumps directly into the target's function implementation within the very same OS thread context. No event queues are involved.

Non-Blocking Transport (nb_transport_fw / nb_transport_bw)

Used for Approximately Timed (AT) models. Splits a transaction into explicit hardware phases (e.g., BEGIN_REQ, END_REQ, BEGIN_RESP, END_RESP) using the tlm_phase enumeration class. This supports deep pipelining and complex interconnect arbitration but is significantly slower to simulate because each phase boundary often requires a sc_event::notify() and a context switch.

Advanced Interfaces

Direct Memory Interface (DMI)

DMI allows an initiator to request a direct C++ pointer to a target's memory array. Under the Hood: An initiator calls get_direct_mem_ptr which populates a tlm_dmi struct. This struct holds unsigned char* dmi_ptr, bounding addresses dmi_start_address/dmi_end_address, and dmi_read_allowed/dmi_write_allowed enums. If granted, the initiator bypasses the b_transport socket entirely, performing native C++ array dereferencing (dmi_ptr[offset]). The LRM requires targets to use invalidate_direct_mem_ptr to revoke this pointer if the memory map changes.

Debug Transport (transport_dbg)

Debug transport is a side-effect-free access path. It is used exclusively by debuggers, GDB stubs, or memory preloaders. A debug read to a FIFO must not pop the FIFO (you must peek instead), and it does not advance simulation time.

Temporal Decoupling

Temporal decoupling allows initiators to run ahead of global simulation time locally within a "quantum". Under the Hood: The Accellera TLM library provides the tlm_quantumkeeper class. Initiators accumulate delays internally (m_local_time) without calling wait(). The keeper continuously calculates the difference between m_local_time and sc_core::sc_time_stamp(). Only when this difference exceeds a globally defined tlm_global_quantum does the keeper call wait() to sync back up with the discrete-event scheduler. This drastically reduces context switches, offering the highest possible simulation speed.

Source-reading checkpoint

For the TLM reference map, inspect tlm_core beside the sc_port and sc_export lessons. Socket convenience types still rely on the core binding machinery underneath.

Lesson self-check

Can you answer these clearly?

Keep moving when you can answer each question without looking back at the lesson.

Comments and Corrections