I have cycle-accurate SystemC module that is being generated automatically by a synthesizer. I need to connect this module to a library that contains untimed modules. I will provide a class from the library and an example of an automatically generated class to illustrate the dilemma.
debugdev.h (from the library)
class debugdev
: public sc_core::sc_module
{
public:
tlm_utils::simple_target_socket<debugdev> socket;
sc_out<bool> irq;
debugdev(sc_core::sc_module_name name);
virtual void b_transport(tlm::tlm_generic_payload& trans,
sc_time& delay);
virtual unsigned int transport_dbg(tlm::tlm_generic_payload& trans);
};
debugdev is a very basic class that has tlm socket connectors for sending and receiving data as well as the associated tlm methods like b_transport. https://www.doulos.com/knowhow/systemc/tlm2/tutorial__1/
add.h (automatically generated by a synthesizer)
#ifndef _add_HH_
#define _add_HH_
#include "systemc.h"
#include "AESL_pkg.h"
namespace ap_rtl {
struct add : public sc_module {
// Port declarations 8
sc_in< sc_logic > ap_start;
sc_out< sc_logic > ap_done;
sc_out< sc_logic > ap_idle;
sc_out< sc_logic > ap_ready;
sc_in< sc_lv<32> > a;
sc_in< sc_lv<32> > b;
sc_out< sc_lv<32> > c;
sc_out< sc_logic > c_ap_vld;
// Port declarations for the virtual clock.
sc_in_clk ap_virtual_clock;
// Module declarations
add(sc_module_name name);
SC_HAS_PROCESS(add);
~add();
sc_trace_file* mVcdFile;
ofstream mHdltvinHandle;
ofstream mHdltvoutHandle;
static const sc_logic ap_const_logic_1;
static const sc_logic ap_const_logic_0;
// Thread declarations
void thread_ap_done();
void thread_ap_idle();
void thread_ap_ready();
void thread_c();
void thread_c_ap_vld();
void thread_hdltv_gen();
};
}
using namespace ap_rtl;
#endif
add.h has an acute awareness of time. The signals ap_start, ap_done, ap_idle, ap_ready, c_ap_vld, and ap_virtual_clock ensure very specific timing constraints on the module so that it will behave in a timed simulation.
My best attempt at solving this problem would be to write a socket-triggered wrapper around the add module that sets all necessary timing signals to the appropriate values to emulate an untimed model. Are there any other ways to solve this problem? Is this the preferred way?
The only way is to create a wrapper that will translate TLM transactions to cycle-accurate protocol.
Tricky part here is clock generation. If you just instantiate sc_clock
inside this wrapper to drive clock pins of cycle-accurate model it will kill performance of whole simulator. Because this clock will be simulated even when cycle-accurate model does nothing (is idle).
I usually solve this by creating is_idle
or is_active
port that indicates if model needs clock signal.
So it works like this: