Chapter 13: Modeling Best Practices

AMS Tracing and Domain Boundaries

Dumping waveforms for continuous-time signals and resolving boundary issues between discrete and continuous domains.

AMS Tracing and Domain Boundaries

Debugging mixed-signal systems requires generating waveforms that visualize the interplay between continuous analog curves and discrete digital events.

SystemC AMS provides a native tracing API (sca_util::sca_trace) that safely samples continuous solver results and outputs them alongside standard SystemC discrete traces (sc_core::sc_trace).

Complete AMS Tracing Example

This example generates a VCD (Value Change Dump) file containing both a continuous AMS Sine wave and a discrete SystemC digital trigger.

#include <systemc>
#include <systemc-ams.h>
 
// 1. TDF Continuous Sine Source
SCA_TDF_MODULE(TracedSine) {
    sca_tdf::sca_out<double> out;
    SCA_CTOR(TracedSine) {}
    void set_attributes() { set_timestep(10, sc_core::SC_US); }
    void processing() {
        double val = 5.0 * std::sin(2.0 * M_PI * 1000.0 * get_time().to_seconds());
        out.write(val);
    }
};
 
// 2. TDF ADC (Mixed-Domain)
SCA_TDF_MODULE(TracedADC) {
    sca_tdf::sca_in<double> in;
    sca_tdf::sca_de::sca_out<bool> discrete_trigger;
 
    SCA_CTOR(TracedADC) {}
    void set_attributes() { set_timestep(10, sc_core::SC_US); }
    void processing() {
        // Trigger digital logic when analog wave crosses 3.0V
        discrete_trigger.write(in.read() > 3.0);
    }
};
 
int sc_main(int argc, char* argv[]) {
    sca_tdf::sca_signal<double> analog_sig("analog_sig");
    sc_core::sc_signal<bool> digital_sig("digital_sig");
 
    TracedSine sine("sine");
    TracedADC adc("adc");
 
    sine.out(analog_sig);
    adc.in(analog_sig);
    adc.discrete_trigger(digital_sig);
 
    // --- Create AMS VCD Trace File ---
    sca_util::sca_trace_file* tf = sca_util::sca_create_vcd_trace_file("ams_mixed_trace");
    
    // Trace continuous AMS signals
    sca_util::sca_trace(tf, analog_sig, "Analog_Sine_Wave");
    
    // Trace discrete DE signals
    sca_util::sca_trace(tf, digital_sig, "Digital_Threshold_Trigger");
 
    std::cout << "Running Mixed-Signal Trace..." << std::endl;
    sc_core::sc_start(2, sc_core::SC_MS);
 
    // Close file properly
    sca_util::sca_close_vcd_trace_file(tf);
 
    return 0;
}

Domain Boundaries

When crossing from AMS (TDF) into standard SystemC (DE), you must use converter ports like sca_tdf::sca_de::sca_out<T>.

Because TDF evaluates on a strict, statically scheduled timestep, any write to a discrete DE signal schedules an update request in the standard SystemC delta-cycle scheduler. This forces the two mathematical solvers to synchronize. Overuse of domain crossings can severely degrade the performance benefits of AMS, so limit crossings to necessary structural boundaries (like an ADC/DAC interface).

Comments and Corrections