systemc: Implement general and VCD trace support.
This doesn't include WIF trace support, but does make allowances for adding it in the future. Change-Id: Ifb62f40a7d8a13e94463930a44ac4b1cf41e3009 Reviewed-on: https://gem5-review.googlesource.com/c/12826 Reviewed-by: Gabe Black <gabeblack@google.com> Maintainer: Gabe Black <gabeblack@google.com>
This commit is contained in:
@@ -36,6 +36,7 @@
|
||||
#include "systemc/ext/core/sc_main.hh"
|
||||
#include "systemc/ext/utils/sc_report.hh"
|
||||
#include "systemc/ext/utils/sc_report_handler.hh"
|
||||
#include "systemc/utils/tracefile.hh"
|
||||
|
||||
namespace sc_gem5
|
||||
{
|
||||
@@ -48,8 +49,8 @@ Scheduler::Scheduler() :
|
||||
starvationEvent(this, false, StarvationPriority),
|
||||
_elaborationDone(false), _started(false), _stopNow(false),
|
||||
_status(StatusOther), maxTickEvent(this, false, MaxTickPriority),
|
||||
_numCycles(0), _changeStamp(0), _current(nullptr), initDone(false),
|
||||
runOnce(false)
|
||||
timeAdvancesEvent(this, false, TimeAdvancesPriority), _numCycles(0),
|
||||
_changeStamp(0), _current(nullptr), initDone(false), runOnce(false)
|
||||
{}
|
||||
|
||||
Scheduler::~Scheduler()
|
||||
@@ -86,6 +87,8 @@ Scheduler::clear()
|
||||
deschedule(&starvationEvent);
|
||||
if (maxTickEvent.scheduled())
|
||||
deschedule(&maxTickEvent);
|
||||
if (timeAdvancesEvent.scheduled())
|
||||
deschedule(&timeAdvancesEvent);
|
||||
|
||||
Process *p;
|
||||
while ((p = initList.getNext()))
|
||||
@@ -134,6 +137,8 @@ Scheduler::initPhase()
|
||||
initDone = true;
|
||||
|
||||
status(StatusOther);
|
||||
|
||||
scheduleTimeAdvancesEvent();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -263,10 +268,13 @@ Scheduler::scheduleStarvationEvent()
|
||||
void
|
||||
Scheduler::runReady()
|
||||
{
|
||||
scheduleTimeAdvancesEvent();
|
||||
|
||||
bool empty = readyListMethods.empty() && readyListThreads.empty();
|
||||
lastReadyTick = getCurTick();
|
||||
|
||||
// The evaluation phase.
|
||||
status(StatusEvaluate);
|
||||
do {
|
||||
yield();
|
||||
} while (getNextReady());
|
||||
@@ -282,6 +290,8 @@ Scheduler::runReady()
|
||||
}
|
||||
|
||||
runUpdate();
|
||||
if (!traceFiles.empty())
|
||||
trace(true);
|
||||
runDelta();
|
||||
|
||||
if (!runToTime && starved())
|
||||
@@ -367,6 +377,7 @@ Scheduler::start(Tick max_tick, bool run_to_time)
|
||||
}
|
||||
|
||||
schedule(&maxTickEvent, maxTick);
|
||||
scheduleTimeAdvancesEvent();
|
||||
|
||||
// Return to gem5 to let it run events, etc.
|
||||
Fiber::primaryFiber()->run();
|
||||
@@ -429,6 +440,13 @@ Scheduler::scheduleStop(bool finish_delta)
|
||||
schedule(&stopEvent);
|
||||
}
|
||||
|
||||
void
|
||||
Scheduler::trace(bool delta)
|
||||
{
|
||||
for (auto tf: traceFiles)
|
||||
tf->trace(delta);
|
||||
}
|
||||
|
||||
Scheduler scheduler;
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -48,6 +48,8 @@ class Fiber;
|
||||
namespace sc_gem5
|
||||
{
|
||||
|
||||
class TraceFile;
|
||||
|
||||
typedef NodeList<Process> ProcessList;
|
||||
typedef NodeList<Channel> ChannelList;
|
||||
|
||||
@@ -280,6 +282,7 @@ class Scheduler
|
||||
timeSlots.erase(timeSlots.begin());
|
||||
if (!runToTime && starved())
|
||||
scheduleStarvationEvent();
|
||||
scheduleTimeAdvancesEvent();
|
||||
}
|
||||
|
||||
// Pending activity ignores gem5 activity, much like how a systemc
|
||||
@@ -357,6 +360,9 @@ class Scheduler
|
||||
Status status() { return _status; }
|
||||
void status(Status s) { _status = s; }
|
||||
|
||||
void registerTraceFile(TraceFile *tf) { traceFiles.insert(tf); }
|
||||
void unregisterTraceFile(TraceFile *tf) { traceFiles.erase(tf); }
|
||||
|
||||
private:
|
||||
typedef const EventBase::Priority Priority;
|
||||
static Priority DefaultPriority = EventBase::Default_Pri;
|
||||
@@ -366,6 +372,7 @@ class Scheduler
|
||||
static Priority MaxTickPriority = DefaultPriority + 2;
|
||||
static Priority ReadyPriority = DefaultPriority + 3;
|
||||
static Priority StarvationPriority = ReadyPriority;
|
||||
static Priority TimeAdvancesPriority = EventBase::Maximum_Pri;
|
||||
|
||||
EventQueue *eq;
|
||||
|
||||
@@ -440,6 +447,15 @@ class Scheduler
|
||||
}
|
||||
EventWrapper<Scheduler, &Scheduler::maxTickFunc> maxTickEvent;
|
||||
|
||||
void timeAdvances() { trace(false); }
|
||||
EventWrapper<Scheduler, &Scheduler::timeAdvances> timeAdvancesEvent;
|
||||
void
|
||||
scheduleTimeAdvancesEvent()
|
||||
{
|
||||
if (!traceFiles.empty() && !timeAdvancesEvent.scheduled())
|
||||
schedule(&timeAdvancesEvent);
|
||||
}
|
||||
|
||||
uint64_t _numCycles;
|
||||
uint64_t _changeStamp;
|
||||
|
||||
@@ -457,6 +473,10 @@ class Scheduler
|
||||
ChannelList updateList;
|
||||
|
||||
std::map<::Event *, Tick> eventsToSchedule;
|
||||
|
||||
std::set<TraceFile *> traceFiles;
|
||||
|
||||
void trace(bool delta);
|
||||
};
|
||||
|
||||
extern Scheduler scheduler;
|
||||
|
||||
@@ -34,9 +34,9 @@
|
||||
|
||||
#include "../core/sc_event.hh"
|
||||
#include "../core/sc_port.hh"
|
||||
#include "../utils/sc_trace_file.hh"
|
||||
#include "sc_signal_in_if.hh"
|
||||
#include "sc_signal_inout_if.hh"
|
||||
#include "warn_unimpl.hh"
|
||||
|
||||
namespace sc_core
|
||||
{
|
||||
@@ -112,7 +112,14 @@ class sc_in : public sc_port<sc_signal_in_if<T>, 1>
|
||||
bind(p);
|
||||
}
|
||||
|
||||
virtual void end_of_elaboration() { /* Implementation defined. */ }
|
||||
virtual void
|
||||
end_of_elaboration()
|
||||
{
|
||||
for (auto params: traceParamsVec)
|
||||
sc_trace(params->tf, (*this)->read(), params->name);
|
||||
|
||||
traceParamsVec.clear();
|
||||
}
|
||||
|
||||
const T &read() const { return (*this)->read(); }
|
||||
operator const T& () const { return (*this)->read(); }
|
||||
@@ -128,9 +135,17 @@ class sc_in : public sc_port<sc_signal_in_if<T>, 1>
|
||||
|
||||
virtual const char *kind() const { return "sc_in"; }
|
||||
|
||||
void
|
||||
add_trace(sc_trace_file *tf, const std::string &name) const
|
||||
{
|
||||
traceParamsVec.push_back(new sc_trace_params(tf, name));
|
||||
}
|
||||
|
||||
private:
|
||||
mutable sc_event_finder_t<sc_signal_in_if<T> > _valueChangedFinder;
|
||||
|
||||
mutable sc_trace_params_vec traceParamsVec;
|
||||
|
||||
// Disabled
|
||||
sc_in(const sc_in<T> &);
|
||||
sc_in<T> &operator = (const sc_in<T> &);
|
||||
@@ -138,9 +153,12 @@ class sc_in : public sc_port<sc_signal_in_if<T>, 1>
|
||||
|
||||
template <class T>
|
||||
inline void
|
||||
sc_trace(sc_trace_file *, const sc_in<T> &, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_in<T> &i, const std::string &name)
|
||||
{
|
||||
sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
if (i.size())
|
||||
sc_trace(tf, i->read(), name);
|
||||
else
|
||||
i.add_trace(tf, name);
|
||||
}
|
||||
|
||||
template <>
|
||||
@@ -236,7 +254,14 @@ class sc_in<bool> : public sc_port<sc_signal_in_if<bool>, 1>
|
||||
bind(p);
|
||||
}
|
||||
|
||||
virtual void end_of_elaboration() { /* Implementation defined. */ }
|
||||
virtual void
|
||||
end_of_elaboration()
|
||||
{
|
||||
for (auto params: traceParamsVec)
|
||||
sc_trace(params->tf, (*this)->read(), params->name);
|
||||
|
||||
traceParamsVec.clear();
|
||||
}
|
||||
|
||||
const bool &read() const { return (*this)->read(); }
|
||||
operator const bool& () const { return (*this)->read(); }
|
||||
@@ -268,11 +293,19 @@ class sc_in<bool> : public sc_port<sc_signal_in_if<bool>, 1>
|
||||
|
||||
virtual const char *kind() const { return "sc_in"; }
|
||||
|
||||
void
|
||||
add_trace(sc_trace_file *tf, const std::string &name) const
|
||||
{
|
||||
traceParamsVec.push_back(new sc_trace_params(tf, name));
|
||||
}
|
||||
|
||||
private:
|
||||
mutable sc_event_finder_t<sc_signal_in_if<bool> > _valueChangedFinder;
|
||||
mutable sc_event_finder_t<sc_signal_in_if<bool> > _posFinder;
|
||||
mutable sc_event_finder_t<sc_signal_in_if<bool> > _negFinder;
|
||||
|
||||
mutable sc_trace_params_vec traceParamsVec;
|
||||
|
||||
// Disabled
|
||||
sc_in(const sc_in<bool> &);
|
||||
sc_in<bool> &operator = (const sc_in<bool> &);
|
||||
@@ -280,9 +313,13 @@ class sc_in<bool> : public sc_port<sc_signal_in_if<bool>, 1>
|
||||
|
||||
template <>
|
||||
inline void
|
||||
sc_trace<bool>(sc_trace_file *, const sc_in<bool> &, const std::string &)
|
||||
sc_trace<bool>(sc_trace_file *tf, const sc_in<bool> &i,
|
||||
const std::string &name)
|
||||
{
|
||||
sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
if (i.size())
|
||||
sc_trace(tf, i->read(), name);
|
||||
else
|
||||
i.add_trace(tf, name);
|
||||
}
|
||||
|
||||
template <>
|
||||
@@ -383,7 +420,14 @@ class sc_in<sc_dt::sc_logic> :
|
||||
bind(p);
|
||||
}
|
||||
|
||||
virtual void end_of_elaboration() { /* Implementation defined. */ }
|
||||
virtual void
|
||||
end_of_elaboration()
|
||||
{
|
||||
for (auto params: traceParamsVec)
|
||||
sc_trace(params->tf, (*this)->read(), params->name);
|
||||
|
||||
traceParamsVec.clear();
|
||||
}
|
||||
|
||||
const sc_dt::sc_logic &read() const { return (*this)->read(); }
|
||||
operator const sc_dt::sc_logic& () const { return (*this)->read(); }
|
||||
@@ -407,12 +451,20 @@ class sc_in<sc_dt::sc_logic> :
|
||||
|
||||
virtual const char *kind() const { return "sc_in"; }
|
||||
|
||||
void
|
||||
add_trace(sc_trace_file *tf, const std::string &name) const
|
||||
{
|
||||
traceParamsVec.push_back(new sc_trace_params(tf, name));
|
||||
}
|
||||
|
||||
private:
|
||||
mutable sc_event_finder_t<sc_signal_in_if<sc_dt::sc_logic> >
|
||||
_valueChangedFinder;
|
||||
mutable sc_event_finder_t<sc_signal_in_if<sc_dt::sc_logic> > _posFinder;
|
||||
mutable sc_event_finder_t<sc_signal_in_if<sc_dt::sc_logic> > _negFinder;
|
||||
|
||||
mutable sc_trace_params_vec traceParamsVec;
|
||||
|
||||
// Disabled
|
||||
sc_in(const sc_in<sc_dt::sc_logic> &);
|
||||
sc_in<sc_dt::sc_logic> &operator = (const sc_in<sc_dt::sc_logic> &);
|
||||
@@ -420,10 +472,13 @@ class sc_in<sc_dt::sc_logic> :
|
||||
|
||||
template <>
|
||||
inline void
|
||||
sc_trace<sc_dt::sc_logic>(
|
||||
sc_trace_file *, const sc_in<sc_dt::sc_logic> &, const std::string &)
|
||||
sc_trace<sc_dt::sc_logic>(sc_trace_file *tf, const sc_in<sc_dt::sc_logic> &i,
|
||||
const std::string &name)
|
||||
{
|
||||
sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
if (i.size())
|
||||
sc_trace(tf, i->read(), name);
|
||||
else
|
||||
i.add_trace(tf, name);
|
||||
}
|
||||
|
||||
} // namespace sc_core
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
#include "../core/sc_event.hh"
|
||||
#include "../core/sc_port.hh"
|
||||
#include "../dt/bit/sc_logic.hh"
|
||||
#include "../utils/sc_trace_file.hh"
|
||||
#include "sc_signal_inout_if.hh"
|
||||
#include "warn_unimpl.hh"
|
||||
|
||||
namespace sc_dt
|
||||
{
|
||||
@@ -111,6 +111,11 @@ class sc_inout : public sc_port<sc_signal_inout_if<T>, 1>
|
||||
delete initValue;
|
||||
initValue = nullptr;
|
||||
}
|
||||
|
||||
for (auto params: traceParamsVec)
|
||||
sc_trace(params->tf, (*this)->read(), params->name);
|
||||
|
||||
traceParamsVec.clear();
|
||||
}
|
||||
|
||||
const T &read() const { return (*this)->read(); }
|
||||
@@ -159,19 +164,30 @@ class sc_inout : public sc_port<sc_signal_inout_if<T>, 1>
|
||||
|
||||
virtual const char *kind() const { return "sc_inout"; }
|
||||
|
||||
void
|
||||
add_trace(sc_trace_file *tf, const std::string &name) const
|
||||
{
|
||||
traceParamsVec.push_back(new sc_trace_params(tf, name));
|
||||
}
|
||||
|
||||
private:
|
||||
T *initValue;
|
||||
mutable sc_event_finder_t<sc_signal_inout_if<T> > _valueChangedFinder;
|
||||
|
||||
mutable sc_trace_params_vec traceParamsVec;
|
||||
|
||||
// Disabled
|
||||
sc_inout(const sc_inout<T> &);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline void
|
||||
sc_trace(sc_trace_file *, const sc_inout<T> &, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_inout<T> &i, const std::string &name)
|
||||
{
|
||||
sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
if (i.size())
|
||||
sc_trace(tf, i->read(), name);
|
||||
else
|
||||
i.add_trace(tf, name);
|
||||
}
|
||||
|
||||
template <>
|
||||
@@ -259,6 +275,11 @@ class sc_inout<bool> : public sc_port<sc_signal_inout_if<bool>, 1>
|
||||
delete initValue;
|
||||
initValue = nullptr;
|
||||
}
|
||||
|
||||
for (auto params: traceParamsVec)
|
||||
sc_trace(params->tf, (*this)->read(), params->name);
|
||||
|
||||
traceParamsVec.clear();
|
||||
}
|
||||
|
||||
const bool &read() const { return (*this)->read(); }
|
||||
@@ -314,21 +335,32 @@ class sc_inout<bool> : public sc_port<sc_signal_inout_if<bool>, 1>
|
||||
|
||||
virtual const char *kind() const { return "sc_inout"; }
|
||||
|
||||
void
|
||||
add_trace(sc_trace_file *tf, const std::string &name) const
|
||||
{
|
||||
traceParamsVec.push_back(new sc_trace_params(tf, name));
|
||||
}
|
||||
|
||||
private:
|
||||
bool *initValue;
|
||||
mutable sc_event_finder_t<sc_signal_inout_if<bool> > _valueChangedFinder;
|
||||
mutable sc_event_finder_t<sc_signal_inout_if<bool> > _posFinder;
|
||||
mutable sc_event_finder_t<sc_signal_inout_if<bool> > _negFinder;
|
||||
|
||||
mutable sc_trace_params_vec traceParamsVec;
|
||||
|
||||
// Disabled
|
||||
sc_inout(const sc_inout<bool> &);
|
||||
};
|
||||
|
||||
template <>
|
||||
inline void sc_trace<bool>(
|
||||
sc_trace_file *, const sc_inout<bool> &, const std::string &)
|
||||
sc_trace_file *tf, const sc_inout<bool> &i, const std::string &name)
|
||||
{
|
||||
sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
if (i.size())
|
||||
sc_trace(tf, i->read(), name);
|
||||
else
|
||||
i.add_trace(tf, name);
|
||||
}
|
||||
|
||||
template <>
|
||||
@@ -433,6 +465,11 @@ class sc_inout<sc_dt::sc_logic> :
|
||||
delete initValue;
|
||||
initValue = nullptr;
|
||||
}
|
||||
|
||||
for (auto params: traceParamsVec)
|
||||
sc_trace(params->tf, (*this)->read(), params->name);
|
||||
|
||||
traceParamsVec.clear();
|
||||
}
|
||||
|
||||
const sc_dt::sc_logic &read() const { return (*this)->read(); }
|
||||
@@ -488,6 +525,12 @@ class sc_inout<sc_dt::sc_logic> :
|
||||
|
||||
virtual const char *kind() const { return "sc_inout"; }
|
||||
|
||||
void
|
||||
add_trace(sc_trace_file *tf, const std::string &name) const
|
||||
{
|
||||
traceParamsVec.push_back(new sc_trace_params(tf, name));
|
||||
}
|
||||
|
||||
private:
|
||||
sc_dt::sc_logic *initValue;
|
||||
mutable sc_event_finder_t<
|
||||
@@ -495,16 +538,21 @@ class sc_inout<sc_dt::sc_logic> :
|
||||
mutable sc_event_finder_t<sc_signal_inout_if<sc_dt::sc_logic> > _posFinder;
|
||||
mutable sc_event_finder_t<sc_signal_inout_if<sc_dt::sc_logic> > _negFinder;
|
||||
|
||||
mutable sc_trace_params_vec traceParamsVec;
|
||||
|
||||
// Disabled
|
||||
sc_inout(const sc_inout<sc_dt::sc_logic> &);
|
||||
};
|
||||
|
||||
template <>
|
||||
inline void
|
||||
sc_trace<sc_dt::sc_logic>(sc_trace_file *, const sc_inout<sc_dt::sc_logic> &,
|
||||
const std::string &)
|
||||
sc_trace<sc_dt::sc_logic>(sc_trace_file *tf,
|
||||
const sc_inout<sc_dt::sc_logic> &i, const std::string &name)
|
||||
{
|
||||
sc_channel_warn_unimpl(__PRETTY_FUNCTION__);
|
||||
if (i.size())
|
||||
sc_trace(tf, i->read(), name);
|
||||
else
|
||||
i.add_trace(tf, name);
|
||||
}
|
||||
|
||||
} // namespace sc_core
|
||||
|
||||
@@ -45,22 +45,6 @@ namespace sc_core
|
||||
{
|
||||
|
||||
class sc_port_base;
|
||||
class sc_trace_file;
|
||||
|
||||
// Nonstandard
|
||||
// Despite having a warning "FOR INTERNAL USE ONLY!" in all caps above this
|
||||
// class definition in the Accellera implementation, it appears in their
|
||||
// examples and test programs, and so we need to have it here as well.
|
||||
struct sc_trace_params
|
||||
{
|
||||
sc_trace_file *tf;
|
||||
std::string name;
|
||||
|
||||
sc_trace_params(sc_trace_file *tf, const std::string &name) :
|
||||
tf(tf), name(name)
|
||||
{}
|
||||
};
|
||||
typedef std::vector<sc_trace_params *> sc_trace_params_vec;
|
||||
|
||||
template <class T, sc_writer_policy WRITER_POLICY=SC_ONE_WRITER>
|
||||
class sc_signal : public sc_signal_inout_if<T>,
|
||||
|
||||
@@ -47,6 +47,22 @@ namespace sc_core
|
||||
{
|
||||
|
||||
class sc_interface;
|
||||
class sc_trace_file;
|
||||
|
||||
// Nonstandard
|
||||
// Despite having a warning "FOR INTERNAL USE ONLY!" in all caps above this
|
||||
// class definition in the Accellera implementation, it appears in their
|
||||
// examples and test programs, and so we need to have it here as well.
|
||||
struct sc_trace_params
|
||||
{
|
||||
sc_trace_file *tf;
|
||||
std::string name;
|
||||
|
||||
sc_trace_params(sc_trace_file *tf, const std::string &name) :
|
||||
tf(tf), name(name)
|
||||
{}
|
||||
};
|
||||
typedef std::vector<sc_trace_params *> sc_trace_params_vec;
|
||||
|
||||
enum sc_port_policy
|
||||
{
|
||||
|
||||
@@ -66,13 +66,11 @@
|
||||
#include "sc_fxval.hh"
|
||||
#include "scfx_params.hh"
|
||||
|
||||
namespace sc_core
|
||||
namespace sc_gem5
|
||||
{
|
||||
|
||||
class vcd_sc_fxnum_trace;
|
||||
class vcd_sc_fxnum_fast_trace;
|
||||
class wif_sc_fxnum_trace;
|
||||
class wif_sc_fxnum_fast_trace;
|
||||
template <typename T, typename B>
|
||||
class TraceValFxnumBase;
|
||||
|
||||
} // namespace sc_core
|
||||
|
||||
@@ -490,8 +488,8 @@ class sc_fxnum
|
||||
friend class sc_fxnum_fast_bitref;
|
||||
friend class sc_fxnum_fast_subref;
|
||||
|
||||
friend class sc_core::vcd_sc_fxnum_trace;
|
||||
friend class sc_core::wif_sc_fxnum_trace;
|
||||
template <typename T, typename B>
|
||||
friend class sc_gem5::TraceValFxnumBase;
|
||||
|
||||
protected:
|
||||
sc_fxnum_observer *observer() const;
|
||||
@@ -851,8 +849,8 @@ class sc_fxnum_fast
|
||||
friend class sc_fxnum_fast_bitref;
|
||||
friend class sc_fxnum_fast_subref;
|
||||
|
||||
friend class sc_core::vcd_sc_fxnum_fast_trace;
|
||||
friend class sc_core::wif_sc_fxnum_fast_trace;
|
||||
template <typename T, typename B>
|
||||
friend class sc_gem5::TraceValFxnumBase;
|
||||
|
||||
protected:
|
||||
sc_fxnum_fast_observer *observer() const;
|
||||
|
||||
@@ -63,7 +63,12 @@ class sc_time;
|
||||
|
||||
class sc_trace_file
|
||||
{
|
||||
protected:
|
||||
sc_trace_file();
|
||||
|
||||
public:
|
||||
virtual ~sc_trace_file();
|
||||
|
||||
virtual void set_time_unit(double, sc_time_unit) = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -33,4 +33,6 @@ if env['USE_SYSTEMC']:
|
||||
Source('sc_report_handler.cc')
|
||||
Source('sc_trace_file.cc')
|
||||
Source('sc_vector.cc')
|
||||
Source('tracefile.cc')
|
||||
Source('vcd.cc')
|
||||
Source('warn_unimpl.cc')
|
||||
|
||||
@@ -27,390 +27,439 @@
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/logging.hh"
|
||||
#include "systemc/core/scheduler.hh"
|
||||
#include "systemc/ext/channel/sc_signal_in_if.hh"
|
||||
#include "systemc/ext/core/sc_event.hh"
|
||||
#include "systemc/ext/core/sc_time.hh"
|
||||
#include "systemc/ext/dt/bit/sc_bv_base.hh"
|
||||
#include "systemc/ext/dt/bit/sc_logic.hh"
|
||||
#include "systemc/ext/dt/bit/sc_lv_base.hh"
|
||||
#include "systemc/ext/dt/fx/sc_fxnum.hh"
|
||||
#include "systemc/ext/dt/fx/sc_fxval.hh"
|
||||
#include "systemc/ext/dt/int/sc_int_base.hh"
|
||||
#include "systemc/ext/dt/int/sc_signed.hh"
|
||||
#include "systemc/ext/dt/int/sc_uint_base.hh"
|
||||
#include "systemc/ext/dt/int/sc_unsigned.hh"
|
||||
#include "systemc/ext/utils/sc_trace_file.hh"
|
||||
#include "systemc/utils/vcd.hh"
|
||||
|
||||
namespace sc_core
|
||||
{
|
||||
|
||||
sc_trace_file::sc_trace_file() {}
|
||||
sc_trace_file::~sc_trace_file() {}
|
||||
|
||||
sc_trace_file *
|
||||
sc_create_vcd_trace_file(const char *name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
return nullptr;
|
||||
auto tf = new ::sc_gem5::VcdTraceFile(name);
|
||||
::sc_gem5::scheduler.registerTraceFile(tf);
|
||||
return tf;
|
||||
}
|
||||
|
||||
void
|
||||
sc_close_vcd_trace_file(sc_trace_file *tf)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
::sc_gem5::scheduler.unregisterTraceFile(
|
||||
static_cast<::sc_gem5::TraceFile *>(tf));
|
||||
delete tf;
|
||||
}
|
||||
|
||||
void
|
||||
sc_write_comment(sc_trace_file *tf, const std::string &comment)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->writeComment(comment);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const bool &, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const bool &v, const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const bool *, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const bool *v, const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const float &, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const float &v, const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const float *, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const float *v, const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const double &, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const double &v, const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const double *, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const double *v, const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::sc_logic &, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::sc_logic &v, const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::sc_logic *, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::sc_logic *v, const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::sc_int_base &, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::sc_int_base &v,
|
||||
const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::sc_int_base *, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::sc_int_base *v,
|
||||
const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::sc_uint_base &, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::sc_uint_base &v,
|
||||
const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::sc_uint_base *, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::sc_uint_base *v,
|
||||
const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::sc_signed &, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::sc_signed &v,
|
||||
const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::sc_signed *, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::sc_signed *v,
|
||||
const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::sc_unsigned &, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::sc_unsigned &v,
|
||||
const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::sc_unsigned *, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::sc_unsigned *v,
|
||||
const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::sc_bv_base &, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::sc_bv_base &v,
|
||||
const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::sc_bv_base *, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::sc_bv_base *v,
|
||||
const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::sc_lv_base &, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::sc_lv_base &v,
|
||||
const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::sc_lv_base *, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::sc_lv_base *v,
|
||||
const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::sc_fxval &, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::sc_fxval &v, const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::sc_fxval *, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::sc_fxval *v, const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::sc_fxval_fast &, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::sc_fxval_fast &v,
|
||||
const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::sc_fxval_fast *, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::sc_fxval_fast *v,
|
||||
const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::sc_fxnum &, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::sc_fxnum &v, const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::sc_fxnum *, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::sc_fxnum *v, const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::sc_fxnum_fast &, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::sc_fxnum_fast &v,
|
||||
const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::sc_fxnum_fast *, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::sc_fxnum_fast *v,
|
||||
const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_event &, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_event &v, const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_event *, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_event *v, const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_time &, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_time &v, const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_time *, const std::string &)
|
||||
sc_trace(sc_trace_file *tf, const sc_time *v, const std::string &name)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const unsigned char &,
|
||||
const std::string &, int width)
|
||||
sc_trace(sc_trace_file *tf, const unsigned char &v,
|
||||
const std::string &name, int width)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name, width);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const unsigned char *,
|
||||
const std::string &, int width)
|
||||
sc_trace(sc_trace_file *tf, const unsigned char *v,
|
||||
const std::string &name, int width)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name, width);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const unsigned short &,
|
||||
const std::string &, int width)
|
||||
sc_trace(sc_trace_file *tf, const unsigned short &v,
|
||||
const std::string &name, int width)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name, width);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const unsigned short *,
|
||||
const std::string &, int width)
|
||||
sc_trace(sc_trace_file *tf, const unsigned short *v,
|
||||
const std::string &name, int width)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name, width);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const unsigned int &, const std::string &, int width)
|
||||
sc_trace(sc_trace_file *tf, const unsigned int &v,
|
||||
const std::string &name, int width)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name, width);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const unsigned int *, const std::string &, int width)
|
||||
sc_trace(sc_trace_file *tf, const unsigned int *v,
|
||||
const std::string &name, int width)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name, width);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const unsigned long &,
|
||||
const std::string &, int width)
|
||||
sc_trace(sc_trace_file *tf, const unsigned long &v,
|
||||
const std::string &name, int width)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name, width);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const unsigned long *,
|
||||
const std::string &, int width)
|
||||
sc_trace(sc_trace_file *tf, const unsigned long *v,
|
||||
const std::string &name, int width)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name, width);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const char &, const std::string &, int width)
|
||||
sc_trace(sc_trace_file *tf, const char &v, const std::string &name, int width)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name, width);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const char *, const std::string &, int width)
|
||||
sc_trace(sc_trace_file *tf, const char *v, const std::string &name, int width)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name, width);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const short &, const std::string &, int width)
|
||||
sc_trace(sc_trace_file *tf, const short &v,
|
||||
const std::string &name, int width)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name, width);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const short *, const std::string &, int width)
|
||||
sc_trace(sc_trace_file *tf, const short *v,
|
||||
const std::string &name, int width)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name, width);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const int &, const std::string &, int width)
|
||||
sc_trace(sc_trace_file *tf, const int &v, const std::string &name, int width)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name, width);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const int *, const std::string &, int width)
|
||||
sc_trace(sc_trace_file *tf, const int *v, const std::string &name, int width)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name, width);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const long &, const std::string &, int width)
|
||||
sc_trace(sc_trace_file *tf, const long &v, const std::string &name, int width)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name, width);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const long *, const std::string &, int width)
|
||||
sc_trace(sc_trace_file *tf, const long *v, const std::string &name, int width)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name, width);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::int64 &, const std::string &, int width)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::int64 &v,
|
||||
const std::string &name, int width)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name, width);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::int64 *, const std::string &, int width)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::int64 *v,
|
||||
const std::string &name, int width)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name, width);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::uint64 &,
|
||||
const std::string &, int width)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::uint64 &v,
|
||||
const std::string &name, int width)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(&v, name, width);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_dt::uint64 *,
|
||||
const std::string &, int width)
|
||||
sc_trace(sc_trace_file *tf, const sc_dt::uint64 *v,
|
||||
const std::string &name, int width)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->addTraceVal(v, name, width);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_signal_in_if<char> &,
|
||||
const std::string &, int width)
|
||||
sc_trace(sc_trace_file *tf, const sc_signal_in_if<char> &v,
|
||||
const std::string &name, int width)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->
|
||||
addTraceVal(&v.read(), name, width);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_signal_in_if<short> &,
|
||||
const std::string &, int width)
|
||||
sc_trace(sc_trace_file *tf, const sc_signal_in_if<short> &v,
|
||||
const std::string &name, int width)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->
|
||||
addTraceVal(&v.read(), name, width);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_signal_in_if<int> &,
|
||||
const std::string &, int width)
|
||||
sc_trace(sc_trace_file *tf, const sc_signal_in_if<int> &v,
|
||||
const std::string &name, int width)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->
|
||||
addTraceVal(&v.read(), name, width);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const sc_signal_in_if<long> &,
|
||||
const std::string &, int width)
|
||||
sc_trace(sc_trace_file *tf, const sc_signal_in_if<long> &v,
|
||||
const std::string &name, int width)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->
|
||||
addTraceVal(&v.read(), name, width);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace(sc_trace_file *, const unsigned int &,
|
||||
const std::string &, const char **enum_literals)
|
||||
sc_trace(sc_trace_file *tf, const unsigned int &v,
|
||||
const std::string &name, const char **enum_literals)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->
|
||||
addTraceVal(&v, name, enum_literals);
|
||||
}
|
||||
|
||||
void
|
||||
sc_trace_delta_cycles(sc_trace_file *, bool on)
|
||||
sc_trace_delta_cycles(sc_trace_file *tf, bool on)
|
||||
{
|
||||
warn("%s not implemented.\n", __PRETTY_FUNCTION__);
|
||||
static_cast<::sc_gem5::TraceFile *>(tf)->traceDeltas(on);
|
||||
}
|
||||
|
||||
} // namespace sc_core
|
||||
|
||||
69
src/systemc/utils/tracefile.cc
Normal file
69
src/systemc/utils/tracefile.cc
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2018 Google, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#include "systemc/utils/tracefile.hh"
|
||||
|
||||
#include <ctime>
|
||||
#include <iomanip>
|
||||
|
||||
#include "base/logging.hh"
|
||||
#include "base/output.hh"
|
||||
#include "sim/core.hh"
|
||||
#include "systemc/ext/core/sc_main.hh"
|
||||
#include "systemc/ext/utils/functions.hh"
|
||||
|
||||
namespace sc_gem5
|
||||
{
|
||||
|
||||
TraceFile::TraceFile(const std::string &name) :
|
||||
_os(simout.create(name, true, true)), timeUnitTicks(0),
|
||||
timeUnitValue(1.0), timeUnitUnit(::sc_core::SC_PS), _traceDeltas(false)
|
||||
{}
|
||||
|
||||
TraceFile::~TraceFile()
|
||||
{
|
||||
simout.close(_os);
|
||||
}
|
||||
|
||||
std::ostream &TraceFile::stream() { return *_os->stream(); }
|
||||
|
||||
void
|
||||
TraceFile::set_time_unit(double d, ::sc_core::sc_time_unit tu)
|
||||
{
|
||||
timeUnitValue = d;
|
||||
timeUnitUnit = tu;
|
||||
}
|
||||
|
||||
void
|
||||
TraceFile::finalizeTime()
|
||||
{
|
||||
timeUnitTicks = ::sc_core::sc_time(timeUnitValue, timeUnitUnit).value();
|
||||
}
|
||||
|
||||
} // namespace sc_gem5
|
||||
279
src/systemc/utils/tracefile.hh
Normal file
279
src/systemc/utils/tracefile.hh
Normal file
@@ -0,0 +1,279 @@
|
||||
/*
|
||||
* Copyright 2018 Google, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#ifndef __SYSTEMC_UTILS_TRACEFILE_HH__
|
||||
#define __SYSTEMC_UTILS_TRACEFILE_HH__
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "systemc/core/event.hh"
|
||||
#include "systemc/ext/channel/sc_signal_in_if.hh"
|
||||
#include "systemc/ext/core/sc_event.hh"
|
||||
#include "systemc/ext/dt/fx/sc_fxnum.hh"
|
||||
#include "systemc/ext/utils/sc_trace_file.hh"
|
||||
|
||||
class OutputStream;
|
||||
|
||||
namespace sc_gem5
|
||||
{
|
||||
|
||||
class TraceValBase
|
||||
{
|
||||
protected:
|
||||
int _width;
|
||||
|
||||
public:
|
||||
TraceValBase(int _width) : _width(_width) {}
|
||||
virtual ~TraceValBase() {}
|
||||
|
||||
int width() { return _width; }
|
||||
|
||||
virtual void finalize() {};
|
||||
virtual bool check() = 0;
|
||||
};
|
||||
|
||||
template <typename T, typename Base=TraceValBase>
|
||||
class TraceVal : public Base
|
||||
{
|
||||
private:
|
||||
const T *t;
|
||||
T oldVal;
|
||||
|
||||
public:
|
||||
TraceVal(const T *_t, int _width) : Base(_width), t(_t), oldVal(*t)
|
||||
{}
|
||||
~TraceVal() {}
|
||||
|
||||
void finalize() override { oldVal = *t; }
|
||||
const T &value() { return oldVal; }
|
||||
|
||||
bool
|
||||
check() override
|
||||
{
|
||||
bool changed = (*t != oldVal);
|
||||
oldVal = *t;
|
||||
return changed;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Base>
|
||||
class TraceVal<::sc_core::sc_signal_in_if<T>, Base> : public Base
|
||||
{
|
||||
private:
|
||||
const ::sc_core::sc_signal_in_if<T> *iface;
|
||||
T oldVal;
|
||||
|
||||
public:
|
||||
TraceVal(const ::sc_core::sc_signal_in_if<T> *_iface, int _width) :
|
||||
Base(_width), iface(_iface), oldVal(iface->read())
|
||||
{}
|
||||
~TraceVal() {}
|
||||
|
||||
void finalize() override { oldVal = iface->read(); }
|
||||
const T &value() { return oldVal; }
|
||||
|
||||
bool
|
||||
check() override
|
||||
{
|
||||
T newVal = iface->read();
|
||||
bool changed = (newVal != oldVal);
|
||||
oldVal = newVal;
|
||||
return changed;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Base>
|
||||
class TraceVal<::sc_core::sc_event, Base> : public Base
|
||||
{
|
||||
private:
|
||||
bool triggered;
|
||||
uint64_t oldStamp;
|
||||
const Event *event;
|
||||
|
||||
public:
|
||||
TraceVal(const ::sc_core::sc_event *_event, int _width) :
|
||||
Base(_width), triggered(false), oldStamp(0),
|
||||
event(Event::getFromScEvent(_event))
|
||||
{}
|
||||
~TraceVal() {}
|
||||
|
||||
bool value() { return triggered; }
|
||||
void finalize() override { oldStamp = event->triggeredStamp(); }
|
||||
|
||||
bool
|
||||
check() override
|
||||
{
|
||||
uint64_t newStamp = event->triggeredStamp();
|
||||
triggered = (oldStamp != newStamp);
|
||||
oldStamp = newStamp;
|
||||
return triggered;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, typename Base>
|
||||
class TraceValFxnumBase : public Base
|
||||
{
|
||||
private:
|
||||
const T *t;
|
||||
T oldVal;
|
||||
|
||||
public:
|
||||
TraceValFxnumBase(const T *_t, int _width) :
|
||||
Base(_width), t(_t),
|
||||
oldVal(_t->m_params.type_params(), _t->m_params.enc(),
|
||||
_t->m_params.cast_switch(), 0)
|
||||
{}
|
||||
~TraceValFxnumBase() {}
|
||||
|
||||
void
|
||||
finalize() override
|
||||
{
|
||||
oldVal = *t;
|
||||
this->_width = t->wl();
|
||||
}
|
||||
|
||||
const T &value() { return oldVal; }
|
||||
|
||||
bool
|
||||
check() override
|
||||
{
|
||||
bool changed = (*t != oldVal);
|
||||
oldVal = *t;
|
||||
return changed;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Base>
|
||||
class TraceVal<::sc_dt::sc_fxnum, Base> :
|
||||
public TraceValFxnumBase<::sc_dt::sc_fxnum, Base>
|
||||
{
|
||||
public:
|
||||
using TraceValFxnumBase<::sc_dt::sc_fxnum, Base>::TraceValFxnumBase;
|
||||
~TraceVal() {}
|
||||
};
|
||||
|
||||
template <typename Base>
|
||||
class TraceVal<::sc_dt::sc_fxnum_fast, Base> :
|
||||
public TraceValFxnumBase<::sc_dt::sc_fxnum_fast, Base>
|
||||
{
|
||||
public:
|
||||
using TraceValFxnumBase<::sc_dt::sc_fxnum_fast, Base>::TraceValFxnumBase;
|
||||
~TraceVal() {}
|
||||
};
|
||||
|
||||
class TraceFile : public sc_core::sc_trace_file
|
||||
{
|
||||
protected:
|
||||
OutputStream *_os;
|
||||
uint64_t timeUnitTicks;
|
||||
double timeUnitValue;
|
||||
::sc_core::sc_time_unit timeUnitUnit;
|
||||
|
||||
bool _traceDeltas;
|
||||
|
||||
TraceFile(const std::string &name);
|
||||
|
||||
std::ostream &stream();
|
||||
|
||||
public:
|
||||
~TraceFile();
|
||||
|
||||
void traceDeltas(bool on) { _traceDeltas = on; }
|
||||
|
||||
void set_time_unit(double, ::sc_core::sc_time_unit) override;
|
||||
void finalizeTime();
|
||||
|
||||
virtual void trace(bool delta) = 0;
|
||||
|
||||
virtual void addTraceVal(const bool *v, const std::string &name) = 0;
|
||||
virtual void addTraceVal(const float *v, const std::string &name) = 0;
|
||||
virtual void addTraceVal(const double *v, const std::string &name) = 0;
|
||||
|
||||
virtual void addTraceVal(const sc_dt::sc_logic *v,
|
||||
const std::string &name) = 0;
|
||||
virtual void addTraceVal(const sc_dt::sc_int_base *v,
|
||||
const std::string &name) = 0;
|
||||
virtual void addTraceVal(const sc_dt::sc_uint_base *v,
|
||||
const std::string &name) = 0;
|
||||
virtual void addTraceVal(const sc_dt::sc_signed *v,
|
||||
const std::string &name) = 0;
|
||||
virtual void addTraceVal(const sc_dt::sc_unsigned *v,
|
||||
const std::string &name) = 0;
|
||||
virtual void addTraceVal(const sc_dt::sc_bv_base *v,
|
||||
const std::string &name) = 0;
|
||||
virtual void addTraceVal(const sc_dt::sc_lv_base *v,
|
||||
const std::string &name) = 0;
|
||||
virtual void addTraceVal(const sc_dt::sc_fxval *v,
|
||||
const std::string &name) = 0;
|
||||
virtual void addTraceVal(const sc_dt::sc_fxval_fast *v,
|
||||
const std::string &name) = 0;
|
||||
virtual void addTraceVal(const sc_dt::sc_fxnum *v,
|
||||
const std::string &name) = 0;
|
||||
virtual void addTraceVal(const sc_dt::sc_fxnum_fast *v,
|
||||
const std::string &name) = 0;
|
||||
|
||||
virtual void addTraceVal(const sc_core::sc_event *v,
|
||||
const std::string &name) = 0;
|
||||
virtual void addTraceVal(const sc_core::sc_time *v,
|
||||
const std::string &name) = 0;
|
||||
|
||||
virtual void addTraceVal(const unsigned char *v,
|
||||
const std::string &name, int width) = 0;
|
||||
virtual void addTraceVal(const char *v, const std::string &name,
|
||||
int width) = 0;
|
||||
virtual void addTraceVal(const unsigned short *v,
|
||||
const std::string &name, int width) = 0;
|
||||
virtual void addTraceVal(const short *v, const std::string &name,
|
||||
int width) = 0;
|
||||
virtual void addTraceVal(const unsigned int *v,
|
||||
const std::string &name, int width) = 0;
|
||||
virtual void addTraceVal(const int *v, const std::string &name,
|
||||
int width) = 0;
|
||||
virtual void addTraceVal(const unsigned long *v,
|
||||
const std::string &name, int width) = 0;
|
||||
virtual void addTraceVal(const long *v, const std::string &name,
|
||||
int width) = 0;
|
||||
|
||||
virtual void addTraceVal(const sc_dt::int64 *v,
|
||||
const std::string &name, int width) = 0;
|
||||
virtual void addTraceVal(const sc_dt::uint64 *v,
|
||||
const std::string &name, int width) = 0;
|
||||
|
||||
virtual void addTraceVal(const unsigned int *,
|
||||
const std::string &name,
|
||||
const char **literals) = 0;
|
||||
|
||||
virtual void writeComment(const std::string &comment) = 0;
|
||||
};
|
||||
|
||||
} // namespace sc_gem5
|
||||
|
||||
#endif // __SYSTEMC_UTILS_TRACEFILE_HH__
|
||||
703
src/systemc/utils/vcd.cc
Normal file
703
src/systemc/utils/vcd.cc
Normal file
@@ -0,0 +1,703 @@
|
||||
/*
|
||||
* Copyright 2018 Google, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#include "systemc/utils/vcd.hh"
|
||||
|
||||
#include <ctime>
|
||||
#include <iomanip>
|
||||
|
||||
#include "base/bitfield.hh"
|
||||
#include "base/cprintf.hh"
|
||||
#include "base/logging.hh"
|
||||
#include "systemc/core/scheduler.hh"
|
||||
#include "systemc/ext/core/sc_event.hh"
|
||||
#include "systemc/ext/core/sc_main.hh"
|
||||
#include "systemc/ext/core/sc_time.hh"
|
||||
#include "systemc/ext/dt/bit/sc_bv_base.hh"
|
||||
#include "systemc/ext/dt/bit/sc_logic.hh"
|
||||
#include "systemc/ext/dt/bit/sc_lv_base.hh"
|
||||
#include "systemc/ext/dt/fx/sc_fxnum.hh"
|
||||
#include "systemc/ext/dt/fx/sc_fxval.hh"
|
||||
#include "systemc/ext/dt/int/sc_int_base.hh"
|
||||
#include "systemc/ext/dt/int/sc_signed.hh"
|
||||
#include "systemc/ext/dt/int/sc_uint_base.hh"
|
||||
#include "systemc/ext/dt/int/sc_unsigned.hh"
|
||||
#include "systemc/ext/utils/functions.hh"
|
||||
|
||||
namespace sc_gem5
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
std::string
|
||||
cleanName(std::string name)
|
||||
{
|
||||
for (int i = 0; i < name.length(); i++) {
|
||||
if (name[i] == '[')
|
||||
name[i] = '(';
|
||||
else if (name[i] == ']')
|
||||
name[i] = ')';
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
class VcdTraceValBase : public TraceValBase
|
||||
{
|
||||
protected:
|
||||
std::string _vcdName;
|
||||
|
||||
const char *
|
||||
stripLeadingBits(const char *orig)
|
||||
{
|
||||
const char first = orig[0];
|
||||
|
||||
if (first != 'z' && first != 'x' && first != '0')
|
||||
return orig;
|
||||
|
||||
const char *res = orig;
|
||||
while (*++res == first) {}
|
||||
|
||||
if (first != '0' || *res != '1')
|
||||
res--;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
char
|
||||
scLogicToVcdState(char in)
|
||||
{
|
||||
switch (in) {
|
||||
case 'U':
|
||||
case 'X':
|
||||
case 'W':
|
||||
case 'D':
|
||||
return 'x';
|
||||
case '0':
|
||||
case 'L':
|
||||
return '0';
|
||||
case '1':
|
||||
case 'H':
|
||||
return '1';
|
||||
case 'Z':
|
||||
return 'z';
|
||||
default:
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
printVal(std::ostream &os, const std::string &rep)
|
||||
{
|
||||
switch (width()) {
|
||||
case 0:
|
||||
return;
|
||||
case 1:
|
||||
os << rep << vcdName() << std::endl;;
|
||||
return;
|
||||
default:
|
||||
os << "b" << stripLeadingBits(rep.c_str()) << " " <<
|
||||
vcdName() << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
VcdTraceValBase(int width) : TraceValBase(width) {}
|
||||
~VcdTraceValBase() {}
|
||||
|
||||
void vcdName(const std::string &vcd_name) { _vcdName = vcd_name; }
|
||||
const std::string &vcdName() { return _vcdName; }
|
||||
virtual std::string vcdType() { return "wire"; }
|
||||
|
||||
virtual void output(std::ostream &os) = 0;
|
||||
};
|
||||
|
||||
void
|
||||
VcdTraceScope::addValue(const std::string &name, VcdTraceValBase *value)
|
||||
{
|
||||
size_t pos = name.find_first_of('.');
|
||||
if (pos == std::string::npos) {
|
||||
values.emplace_back(name, value);
|
||||
} else {
|
||||
std::string sname = name.substr(0, pos);
|
||||
auto it = scopes.find(sname);
|
||||
if (it == scopes.end())
|
||||
it = scopes.emplace(sname, new VcdTraceScope).first;
|
||||
it->second->addValue(name.substr(pos + 1), value);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VcdTraceScope::output(const std::string &name, std::ostream &os)
|
||||
{
|
||||
os << "$scope module " << name << " $end" << std::endl;
|
||||
|
||||
for (auto &p: values) {
|
||||
const std::string &name = p.first;
|
||||
VcdTraceValBase *value = p.second;
|
||||
|
||||
int w = value->width();
|
||||
if (w <= 0) {
|
||||
std::string msg = csprintf("'%s' has 0 bits", name);
|
||||
// The typo in this error message is intentional to match the
|
||||
// Accellera output.
|
||||
SC_REPORT_ERROR("(E710) object cannot not be traced", msg.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
std::string clean_name = cleanName(name);
|
||||
if (w == 1) {
|
||||
ccprintf(os, "$var %s % 3d %s %s $end\n",
|
||||
value->vcdType(), w, value->vcdName(), clean_name);
|
||||
} else {
|
||||
ccprintf(os, "$var %s % 3d %s %s [%d:0] $end\n",
|
||||
value->vcdType(), w, value->vcdName(), clean_name, w - 1);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &p: scopes)
|
||||
p.second->output(p.first, os);
|
||||
|
||||
os << "$upscope $end" << std::endl;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class VcdTraceVal : public TraceVal<T, VcdTraceValBase>
|
||||
{
|
||||
public:
|
||||
typedef T TracedType;
|
||||
|
||||
VcdTraceVal(const T* t, const std::string &vcd_name, int width) :
|
||||
TraceVal<T, VcdTraceValBase>(t, width)
|
||||
{
|
||||
this->vcdName(vcd_name);
|
||||
}
|
||||
};
|
||||
|
||||
std::string
|
||||
VcdTraceFile::nextSignalName()
|
||||
{
|
||||
std::string name(_nextName);
|
||||
|
||||
bool carry = false;
|
||||
int pos = NextNameChars - 1;
|
||||
do {
|
||||
carry = (_nextName[pos] == 'z');
|
||||
if (carry)
|
||||
_nextName[pos--] = 'a';
|
||||
else
|
||||
_nextName[pos--]++;
|
||||
} while (carry && pos >= 0);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
void
|
||||
VcdTraceFile::initialize()
|
||||
{
|
||||
finalizeTime();
|
||||
|
||||
// Date.
|
||||
stream() << "$date" << std::endl;
|
||||
time_t long_time;
|
||||
time(&long_time);
|
||||
struct tm *p_tm = localtime(&long_time);
|
||||
stream() << std::put_time(p_tm, " %b %d, %Y %H:%M:%S\n");
|
||||
stream() << "$end" << std::endl << std::endl;
|
||||
|
||||
// Version.
|
||||
stream() << "$version" << std::endl;
|
||||
stream() << " " << ::sc_core::sc_version() << std::endl;
|
||||
stream() << "$end" << std::endl << std::endl;
|
||||
|
||||
// Timescale.
|
||||
stream() << "$timescale" << std::endl;
|
||||
stream() << " " << ::sc_core::sc_time::from_value(timeUnitTicks) <<
|
||||
std::endl;
|
||||
stream() << "$end" << std::endl << std::endl;
|
||||
|
||||
for (auto tv: traceVals)
|
||||
tv->finalize();
|
||||
|
||||
topScope.output("SystemC", stream());
|
||||
|
||||
stream() << "$enddefinitions $end" << std::endl << std::endl;
|
||||
|
||||
Tick now = scheduler.getCurTick();
|
||||
|
||||
std::string timedump_comment =
|
||||
csprintf("All initial values are dumped below at time "
|
||||
"%g sec = %g timescale units.",
|
||||
static_cast<double>(now) / SimClock::Float::s,
|
||||
static_cast<double>(now / timeUnitTicks));
|
||||
writeComment(timedump_comment);
|
||||
|
||||
lastPrintedTime = now / timeUnitTicks;
|
||||
|
||||
stream() << "$dumpvars" << std::endl;
|
||||
for (auto tv: traceVals)
|
||||
tv->output(stream());
|
||||
stream() << "$end" << std::endl << std::endl;
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
VcdTraceFile::~VcdTraceFile()
|
||||
{
|
||||
for (auto tv: traceVals)
|
||||
delete tv;
|
||||
traceVals.clear();
|
||||
|
||||
if (timeUnitTicks)
|
||||
ccprintf(stream(), "#%u\n", scheduler.getCurTick() / timeUnitTicks);
|
||||
}
|
||||
|
||||
void
|
||||
VcdTraceFile::trace(bool delta)
|
||||
{
|
||||
if (!delta)
|
||||
deltasAtNow = 0;
|
||||
|
||||
uint64_t deltaOffset = deltasAtNow;
|
||||
|
||||
if (delta)
|
||||
deltaOffset = deltasAtNow++;
|
||||
|
||||
if (_traceDeltas != delta)
|
||||
return;
|
||||
|
||||
if (!initialized) {
|
||||
initialize();
|
||||
return;
|
||||
}
|
||||
|
||||
Tick now = scheduler.getCurTick() / timeUnitTicks + deltaOffset;
|
||||
|
||||
if (now <= lastPrintedTime) {
|
||||
// TODO warn about reversed time?
|
||||
return;
|
||||
}
|
||||
|
||||
bool time_printed = false;
|
||||
for (auto tv: traceVals) {
|
||||
if (tv->check()) {
|
||||
if (!time_printed) {
|
||||
lastPrintedTime = now;
|
||||
ccprintf(stream(), "#%u\n", now);
|
||||
time_printed = true;
|
||||
}
|
||||
|
||||
tv->output(stream());
|
||||
}
|
||||
}
|
||||
if (time_printed)
|
||||
stream() << std::endl;
|
||||
}
|
||||
|
||||
class VcdTraceValBool : public VcdTraceVal<bool>
|
||||
{
|
||||
public:
|
||||
using VcdTraceVal<bool>::VcdTraceVal;
|
||||
|
||||
void
|
||||
output(std::ostream &os) override
|
||||
{
|
||||
printVal(os, this->value() ? "1" : "0");
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const bool *v, const std::string &name)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValBool>(v, name);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class VcdTraceValFloat : public VcdTraceVal<T>
|
||||
{
|
||||
public:
|
||||
using VcdTraceVal<T>::VcdTraceVal;
|
||||
|
||||
std::string vcdType() override { return "real"; }
|
||||
|
||||
void
|
||||
output(std::ostream &os) override
|
||||
{
|
||||
ccprintf(os, "r%.16g %s\n", this->value(), this->vcdName());
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const float *v, const std::string &name)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValFloat<float>>(v, name);
|
||||
}
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const double *v, const std::string &name)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValFloat<double>>(v, name);
|
||||
}
|
||||
|
||||
class VcdTraceValScLogic : public VcdTraceVal<sc_dt::sc_logic>
|
||||
{
|
||||
public:
|
||||
using VcdTraceVal<sc_dt::sc_logic>::VcdTraceVal;
|
||||
|
||||
void
|
||||
output(std::ostream &os) override
|
||||
{
|
||||
char str[2] = {
|
||||
scLogicToVcdState(value().to_char()),
|
||||
'\0'
|
||||
};
|
||||
printVal(os, str);
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const sc_dt::sc_logic *v, const std::string &name)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValScLogic>(v, name);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class VcdTraceValFinite : public VcdTraceVal<T>
|
||||
{
|
||||
public:
|
||||
using VcdTraceVal<T>::VcdTraceVal;
|
||||
|
||||
void
|
||||
finalize() override
|
||||
{
|
||||
VcdTraceVal<T>::finalize();
|
||||
this->_width = this->value().length();
|
||||
}
|
||||
|
||||
void
|
||||
output(std::ostream &os) override
|
||||
{
|
||||
std::string str;
|
||||
const int w = this->width();
|
||||
|
||||
str.reserve(w);
|
||||
for (int i = w - 1; i >= 0; i--)
|
||||
str += this->value()[i].to_bool() ? '1' : '0';
|
||||
|
||||
this->printVal(os, str);
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const sc_dt::sc_int_base *v,
|
||||
const std::string &name)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValFinite<sc_dt::sc_int_base>>(v, name);
|
||||
}
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const sc_dt::sc_uint_base *v,
|
||||
const std::string &name)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValFinite<sc_dt::sc_uint_base>>(v, name);
|
||||
}
|
||||
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const sc_dt::sc_signed *v, const std::string &name)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValFinite<sc_dt::sc_signed>>(v, name);
|
||||
}
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const sc_dt::sc_unsigned *v,
|
||||
const std::string &name)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValFinite<sc_dt::sc_unsigned>>(v, name);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class VcdTraceValLogic : public VcdTraceVal<T>
|
||||
{
|
||||
public:
|
||||
using VcdTraceVal<T>::VcdTraceVal;
|
||||
|
||||
void
|
||||
finalize() override
|
||||
{
|
||||
VcdTraceVal<T>::finalize();
|
||||
this->_width = this->value().length();
|
||||
}
|
||||
|
||||
void
|
||||
output(std::ostream &os) override
|
||||
{
|
||||
this->printVal(os, this->value().to_string());
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const sc_dt::sc_bv_base *v, const std::string &name)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValLogic<::sc_dt::sc_bv_base>>(v, name);
|
||||
}
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const sc_dt::sc_lv_base *v, const std::string &name)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValLogic<::sc_dt::sc_lv_base>>(v, name);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class VcdTraceValFxval : public VcdTraceVal<T>
|
||||
{
|
||||
public:
|
||||
using VcdTraceVal<T>::VcdTraceVal;
|
||||
|
||||
std::string vcdType() override { return "real"; }
|
||||
|
||||
void
|
||||
output(std::ostream &os) override
|
||||
{
|
||||
ccprintf(os, "r%.16g %s\n",
|
||||
this->value().to_double(), this->vcdName());
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const sc_dt::sc_fxval *v, const std::string &name)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValFxval<sc_dt::sc_fxval>>(v, name);
|
||||
}
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const sc_dt::sc_fxval_fast *v,
|
||||
const std::string &name)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValFxval<sc_dt::sc_fxval_fast>>(v, name);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class VcdTraceValFxnum : public VcdTraceVal<T>
|
||||
{
|
||||
public:
|
||||
using VcdTraceVal<T>::VcdTraceVal;
|
||||
|
||||
void
|
||||
output(std::ostream &os) override
|
||||
{
|
||||
std::string str;
|
||||
const int w = this->width();
|
||||
|
||||
str.reserve(w);
|
||||
for (int i = w - 1; i >= 0; i--)
|
||||
str += this->value()[i] ? '1' : '0';
|
||||
|
||||
this->printVal(os, str);
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const sc_dt::sc_fxnum *v, const std::string &name)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValFxnum<::sc_dt::sc_fxnum>>(v, name);
|
||||
}
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const sc_dt::sc_fxnum_fast *v,
|
||||
const std::string &name)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValFxnum<::sc_dt::sc_fxnum_fast>>(v, name);
|
||||
}
|
||||
|
||||
class VcdTraceValEvent : public VcdTraceVal<::sc_core::sc_event>
|
||||
{
|
||||
public:
|
||||
using VcdTraceVal<::sc_core::sc_event>::VcdTraceVal;
|
||||
|
||||
std::string vcdType() override { return "event"; }
|
||||
|
||||
void
|
||||
output(std::ostream &os) override
|
||||
{
|
||||
if (value())
|
||||
printVal(os, "1");
|
||||
else
|
||||
os << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const sc_core::sc_event *v, const std::string &name)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValEvent>(v, name);
|
||||
}
|
||||
|
||||
class VcdTraceValTime : public VcdTraceVal<::sc_core::sc_time>
|
||||
{
|
||||
private:
|
||||
static const int TimeWidth = 64;
|
||||
|
||||
public:
|
||||
using VcdTraceVal<::sc_core::sc_time>::VcdTraceVal;
|
||||
|
||||
std::string vcdType() override { return "time"; }
|
||||
|
||||
void
|
||||
finalize() override
|
||||
{
|
||||
VcdTraceVal<::sc_core::sc_time>::finalize();
|
||||
_width = TimeWidth;
|
||||
}
|
||||
|
||||
void
|
||||
output(std::ostream &os) override
|
||||
{
|
||||
char str[TimeWidth + 1];
|
||||
str[TimeWidth] = '\0';
|
||||
|
||||
const uint64_t val = value().value();
|
||||
for (int i = 0; i < TimeWidth; i++)
|
||||
str[i] = ::bits(val, TimeWidth - i - 1) ? '1' : '0';
|
||||
|
||||
printVal(os, str);
|
||||
}
|
||||
};
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const sc_core::sc_time *v, const std::string &name)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValTime>(v, name);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class VcdTraceValInt : public VcdTraceVal<T>
|
||||
{
|
||||
public:
|
||||
using VcdTraceVal<T>::VcdTraceVal;
|
||||
|
||||
void
|
||||
output(std::ostream &os) override
|
||||
{
|
||||
const int w = this->width();
|
||||
char str[w + 1];
|
||||
str[w] = '\0';
|
||||
|
||||
const uint64_t val =
|
||||
static_cast<uint64_t>(this->value()) & ::mask(sizeof(T) * 8);
|
||||
|
||||
if (::mask(w) < val) {
|
||||
for (int i = 0; i < w; i++)
|
||||
str[i] = 'x';
|
||||
} else {
|
||||
for (int i = 0; i < w; i++)
|
||||
str[i] = ::bits(val, w - i - 1) ? '1' : '0';
|
||||
}
|
||||
|
||||
this->printVal(os, str);
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const unsigned char *v, const std::string &name,
|
||||
int width)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValInt<unsigned char>>(v, name, width);
|
||||
}
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const char *v, const std::string &name, int width)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValInt<char>>(v, name, width);
|
||||
}
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const unsigned short *v, const std::string &name,
|
||||
int width)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValInt<unsigned short>>(v, name, width);
|
||||
}
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const short *v, const std::string &name, int width)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValInt<short>>(v, name, width);
|
||||
}
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const unsigned int *v, const std::string &name,
|
||||
int width)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValInt<unsigned int>>(v, name, width);
|
||||
}
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const int *v, const std::string &name, int width)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValInt<int>>(v, name, width);
|
||||
}
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const unsigned long *v, const std::string &name,
|
||||
int width)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValInt<unsigned long>>(v, name, width);
|
||||
}
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const long *v, const std::string &name, int width)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValInt<long>>(v, name, width);
|
||||
}
|
||||
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const sc_dt::int64 *v, const std::string &name,
|
||||
int width)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValInt<sc_dt::int64>>(v, name, width);
|
||||
}
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const sc_dt::uint64 *v, const std::string &name,
|
||||
int width)
|
||||
{
|
||||
addNewTraceVal<VcdTraceValInt<sc_dt::uint64>>(v, name, width);
|
||||
}
|
||||
|
||||
void
|
||||
VcdTraceFile::addTraceVal(const unsigned int *v, const std::string &name,
|
||||
const char **literals)
|
||||
{
|
||||
uint64_t count = 0;
|
||||
while (*literals++)
|
||||
count++;
|
||||
|
||||
int bits = 0;
|
||||
while (count >> bits)
|
||||
bits++;
|
||||
|
||||
addNewTraceVal<VcdTraceValInt<unsigned int>>(v, name, bits);
|
||||
}
|
||||
|
||||
void
|
||||
VcdTraceFile::writeComment(const std::string &comment)
|
||||
{
|
||||
stream() << "$comment" << std::endl;
|
||||
stream() << comment << std::endl;
|
||||
stream() << "$end" << std::endl << std::endl;
|
||||
}
|
||||
|
||||
} // namespace sc_gem5
|
||||
154
src/systemc/utils/vcd.hh
Normal file
154
src/systemc/utils/vcd.hh
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright 2018 Google, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#ifndef __SYSTEMC_UTILS_VCD_HH__
|
||||
#define __SYSTEMC_UTILS_VCD_HH__
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "systemc/utils/tracefile.hh"
|
||||
|
||||
namespace sc_gem5
|
||||
{
|
||||
|
||||
class VcdTraceValBase;
|
||||
|
||||
class VcdTraceScope
|
||||
{
|
||||
private:
|
||||
std::vector<std::pair<std::string, VcdTraceValBase *>> values;
|
||||
std::map<std::string, VcdTraceScope *> scopes;
|
||||
|
||||
public:
|
||||
void addValue(const std::string &name, VcdTraceValBase *value);
|
||||
void output(const std::string &name, std::ostream &os);
|
||||
};
|
||||
|
||||
class VcdTraceFile : public TraceFile
|
||||
{
|
||||
private:
|
||||
Tick lastPrintedTime;
|
||||
uint64_t deltasAtNow;
|
||||
|
||||
static const int NextNameChars = 5;
|
||||
char _nextName[NextNameChars + 1];
|
||||
std::string nextSignalName();
|
||||
|
||||
bool initialized;
|
||||
void initialize();
|
||||
|
||||
std::vector<VcdTraceValBase *> traceVals;
|
||||
VcdTraceScope topScope;
|
||||
|
||||
public:
|
||||
VcdTraceFile(const std::string &name) :
|
||||
TraceFile(name + ".vcd"), lastPrintedTime(0), deltasAtNow(0),
|
||||
initialized(false)
|
||||
{
|
||||
_nextName[NextNameChars] = '\0';
|
||||
for (int i = 0; i < NextNameChars; i++)
|
||||
_nextName[i] = 'a';
|
||||
}
|
||||
~VcdTraceFile();
|
||||
|
||||
void trace(bool delta) override;
|
||||
|
||||
template<typename TV>
|
||||
void
|
||||
addNewTraceVal(const typename TV::TracedType *v, const std::string &name,
|
||||
int width=1)
|
||||
{
|
||||
VcdTraceValBase *tv = new TV(v, nextSignalName(), width);
|
||||
traceVals.push_back(tv);
|
||||
topScope.addValue(name, tv);
|
||||
}
|
||||
|
||||
void addTraceVal(const bool *v, const std::string &name) override;
|
||||
void addTraceVal(const float *v, const std::string &name) override;
|
||||
void addTraceVal(const double *v, const std::string &name) override;
|
||||
|
||||
void addTraceVal(const sc_dt::sc_logic *v,
|
||||
const std::string &name) override;
|
||||
void addTraceVal(const sc_dt::sc_int_base *v,
|
||||
const std::string &name) override;
|
||||
void addTraceVal(const sc_dt::sc_uint_base *v,
|
||||
const std::string &name) override;
|
||||
void addTraceVal(const sc_dt::sc_signed *v,
|
||||
const std::string &name) override;
|
||||
void addTraceVal(const sc_dt::sc_unsigned *v,
|
||||
const std::string &name) override;
|
||||
void addTraceVal(const sc_dt::sc_bv_base *v,
|
||||
const std::string &name) override;
|
||||
void addTraceVal(const sc_dt::sc_lv_base *v,
|
||||
const std::string &name) override;
|
||||
void addTraceVal(const sc_dt::sc_fxval *v,
|
||||
const std::string &name) override;
|
||||
void addTraceVal(const sc_dt::sc_fxval_fast *v,
|
||||
const std::string &name) override;
|
||||
void addTraceVal(const sc_dt::sc_fxnum *v,
|
||||
const std::string &name) override;
|
||||
void addTraceVal(const sc_dt::sc_fxnum_fast *v,
|
||||
const std::string &name) override;
|
||||
|
||||
void addTraceVal(const sc_core::sc_event *v,
|
||||
const std::string &name) override;
|
||||
void addTraceVal(const sc_core::sc_time *v,
|
||||
const std::string &name) override;
|
||||
|
||||
void addTraceVal(const unsigned char *v,
|
||||
const std::string &name, int width) override;
|
||||
void addTraceVal(const char *v, const std::string &name,
|
||||
int width) override;
|
||||
void addTraceVal(const unsigned short *v,
|
||||
const std::string &name, int width) override;
|
||||
void addTraceVal(const short *v, const std::string &name,
|
||||
int width) override;
|
||||
void addTraceVal(const unsigned int *v,
|
||||
const std::string &name, int width) override;
|
||||
void addTraceVal(const int *v, const std::string &name,
|
||||
int width) override;
|
||||
void addTraceVal(const unsigned long *v,
|
||||
const std::string &name, int width) override;
|
||||
void addTraceVal(const long *v, const std::string &name,
|
||||
int width) override;
|
||||
|
||||
void addTraceVal(const sc_dt::int64 *v,
|
||||
const std::string &name, int width) override;
|
||||
void addTraceVal(const sc_dt::uint64 *v,
|
||||
const std::string &name, int width) override;
|
||||
|
||||
void addTraceVal(const unsigned int *, const std::string &name,
|
||||
const char **literals) override;
|
||||
|
||||
void writeComment(const std::string &comment) override;
|
||||
};
|
||||
|
||||
} // namespace sc_gem5
|
||||
|
||||
#endif // __SYSTEMC_UTILS_VCD_HH__
|
||||
Reference in New Issue
Block a user