Show gs_dust_port.h syntax highlighted
// ============================================================================
// DUST - Dynamic and Universal SystemC Transaction Logger
//
// (C) 2006 Technical University of Braunschweig, Dept. E.I.S.
// Manuel Geffken, Wolfgang Klingauf
// <klingauf@eis.cs.tu-bs.de>
//
// ============================================================================//
#ifndef _GS_DUST_PORT_H_
#define _GS_DUST_PORT_H_
#include <systemc.h>
#include <scv.h>
#include <string>
#include <sstream>
#include "xml_log/static_model/model_builder.h"
// DUST id prefix
#define DUST_ID_PREFIX_STRING "id"
// SCV stream name _reserved_ for port call transaction recording
#define DUST_PORT_STREAM_NAME "port_stream"
// SCV stream kind for port call transaction recording
#define DUST_PORT_STREAM_KIND "transactor"
// SCV generator name _reserved_ for port call transaction recording
#define DUST_PORT_GEN_NAME "call_gen"
// SCV begin attribute name for port call transaction recording
#define DUST_PORT_CALL_BEGIN_NAME "attrib1"
// SCV end attribute name for port call transaction recording
#define DUST_PORT_CALL_END_NAME "attrib2"
//unfortunately we have to use a global variable here (instead of a static member) as there would be
//a static member for each template specialisation of the dust port and not a single global one
bool dust_static_model_has_already_been_dumped=false;
/**
* Template class which can be used to replace the original class sc_port to
* enable transaction recording and later visualisation of SystemC port calls.
*
* This class works just in the same way as its base class sc_port.
*/
template <class IF, int N = 1>
class gs_dust_port
: public sc_port<IF, N>
{
public:
// typdefs
typedef sc_port_b<IF> base_type;
typedef sc_port<IF,N> this_type;
// constructors (analog to base class)
#ifdef DUST_RECORD_TRANSACTIONS
gs_dust_port()
: sc_port<IF, N>(),
// instantiate tr. stream with stream name and stream kind
port_stream(DUST_PORT_STREAM_NAME, DUST_PORT_STREAM_KIND),
// instantiate tr. generator with name, stream, begin attribute name
call_gen(DUST_PORT_GEN_NAME, port_stream,
DUST_PORT_CALL_BEGIN_NAME, DUST_PORT_CALL_END_NAME)
{
}
explicit gs_dust_port( const char* name_ )
: sc_port<IF, N>(name_),
port_stream(DUST_PORT_STREAM_NAME, DUST_PORT_STREAM_KIND),
call_gen(DUST_PORT_GEN_NAME, port_stream,
DUST_PORT_CALL_BEGIN_NAME, DUST_PORT_CALL_END_NAME)
{
}
explicit gs_dust_port( IF& interface_ )
: sc_port<IF, N>(interface_),
port_stream(DUST_PORT_STREAM_NAME, DUST_PORT_STREAM_KIND),
call_gen(DUST_PORT_GEN_NAME, port_stream,
DUST_PORT_CALL_BEGIN_NAME, DUST_PORT_CALL_END_NAME)
{
}
gs_dust_port( const char* name_, IF& interface_ )
: sc_port<IF, N>(name_, interface_),
port_stream(DUST_PORT_STREAM_NAME, DUST_PORT_STREAM_KIND),
call_gen(DUST_PORT_GEN_NAME, port_stream,
DUST_PORT_CALL_BEGIN_NAME, DUST_PORT_CALL_END_NAME)
{
}
explicit gs_dust_port( base_type& parent_ )
: sc_port<IF, N>(parent_),
port_stream(DUST_PORT_STREAM_NAME, DUST_PORT_STREAM_KIND),
call_gen(DUST_PORT_GEN_NAME, port_stream,
DUST_PORT_CALL_BEGIN_NAME, DUST_PORT_CALL_END_NAME)
{
}
gs_dust_port( const char* name_, base_type& parent_ )
: sc_port<IF, N>(name_, parent_),
port_stream(DUST_PORT_STREAM_NAME, DUST_PORT_STREAM_KIND),
call_gen(DUST_PORT_GEN_NAME, port_stream,
DUST_PORT_CALL_BEGIN_NAME, DUST_PORT_CALL_END_NAME)
{
}
gs_dust_port( this_type& parent_ )
: sc_port<IF, N>(parent_),
port_stream(DUST_PORT_STREAM_NAME, DUST_PORT_STREAM_KIND),
call_gen(DUST_PORT_GEN_NAME, port_stream,
DUST_PORT_CALL_BEGIN_NAME, DUST_PORT_CALL_END_NAME)
{
}
gs_dust_port( const char* name_, this_type& parent_ )
: sc_port<IF, N>(name_, parent_),
port_stream(DUST_PORT_STREAM_NAME, DUST_PORT_STREAM_KIND),
call_gen(DUST_PORT_GEN_NAME, port_stream,
DUST_PORT_CALL_BEGIN_NAME, DUST_PORT_CALL_END_NAME)
{
}
#else
gs_dust_port()
: sc_port<IF, N>()
{
}
explicit gs_dust_port( const char* name_ )
: sc_port<IF, N>(name_)
{
}
explicit gs_dust_port( IF& interface_ )
: sc_port<IF, N>(interface_)
{
}
gs_dust_port( const char* name_, IF& interface_ )
: sc_port<IF, N>(name_, interface_)
{
}
explicit gs_dust_port( base_type& parent_ )
: sc_port<IF, N>(parent_)
{
}
gs_dust_port( const char* name_, base_type& parent_ )
: sc_port<IF, N>(name_, parent_)
{
}
gs_dust_port( this_type& parent_ )
: sc_port<IF, N>(parent_)
{
}
gs_dust_port( const char* name_, this_type& parent_ )
: sc_port<IF, N>(name_, parent_)
{
}
#endif
// destructor
virtual ~gs_dust_port() {
}
// analog to base class
inline IF* operator -> ()
{
IF *ret = sc_port<IF, N>::operator -> ();
record_tr_attribute(ret);
return ret;
}
// analog to base class
inline const IF* operator -> () const
{
IF *ret = sc_port<IF, N>::operator -> ();
record_tr_attribute(ret);
return ret;
}
/**
* This function performs the recording of the port call via SCV.
* The recorded data includes the caller and the invoked channel/module.
*
* @param IF the interface bound to this port
*
*/
virtual void record_tr_attribute(IF* interface) {
if (interface != NULL) {
stringstream stream;
// module?
if (dynamic_cast<sc_module *>(interface)) {
sc_module *p = dynamic_cast<sc_module *>(interface);
stream << DUST_ID_PREFIX_STRING << p;
}
// prim channel?
else if (dynamic_cast<sc_prim_channel *>(interface)) {
sc_prim_channel *p = dynamic_cast<sc_prim_channel *>(interface);
stream << DUST_ID_PREFIX_STRING << p;
}
#ifdef DUST_RECORD_TRANSACTIONS
// record invoked interface
scv_tr_handle h = call_gen.begin_transaction(stream.str());
h.record_attribute("master_id", id);
stream.str("");
stream.clear();
stream << DUST_ID_PREFIX_STRING << dynamic_cast<sc_port_base *>(this);
// record port (sc_port_base) belonging to the caller
call_gen.end_transaction(h, stream.str());
#endif
}
}
// analog to base class
inline IF* operator [] (int index_)
{
IF *ret = sc_port<IF, N>::operator [] (index_);
record_tr_attribute(ret);
return ret;
}
// analog to base class
inline const IF* operator [] (int index_) const
{
IF *ret = sc_port<IF, N>::operator [] (index_);
record_tr_attribute(ret);
return ret;
}
/**
* Set the master ID of this port. Used for transaction recording.
*/
void setMasterID(unsigned long _id)
{
id = _id;
}
virtual void start_of_simulation(){
if(!dust_static_model_has_already_been_dumped){
// cout<<"Dumpdy dump"<<endl<<flush;
model_builder mb(true);
dust_static_model_has_already_been_dumped=true;
}
}
protected:
unsigned long id;
private:
#ifdef DUST_RECORD_TRANSACTIONS
/* for SCV transaction recording */
scv_tr_stream port_stream;
scv_tr_generator<std::string, std::string> call_gen;
#endif
/*
* Note:
* Common _static_ SCV stream and generator for port call recording
* with the aim to reduce the amount of data in transaction model. The
* concept does not work so far due to missing SCV database when static
* members are instantiated. Therefore no SCV database is assigned to
* the common SCV stream therefore SCV transaction recording does
* not work.
*/
//static scv_tr_stream port_stream2;
//static scv_tr_generator <std::string, std::string> call_gen2;
};
// static members (see note above)
//template <class IF, int N> scv_tr_stream
// gs_dust_port<IF, N>::port_stream2(DUST_PORT_STREAM_NAME,
// DUST_PORT_STREAM_KIND);
//template <class IF, int N> scv_tr_generator<std::string, std::string>
// gs_dust_port<IF, N>::call_gen2(DUST_PORT_GEN_NAME,
// port_stream2,
// DUST_PORT_CALL_BEGIN_NAME, DUST_PORT_CALL_END_NAME);
#endif //_GS_DUST_PORT_H_
See more files for this project here