diff options
author | Gabe Black <gabeblack@google.com> | 2018-08-16 19:10:09 -0700 |
---|---|---|
committer | Gabe Black <gabeblack@google.com> | 2018-09-25 23:50:23 +0000 |
commit | df50b775cb04bb22fd583cee40af870f2c80b65e (patch) | |
tree | ef484ac37ee32438d19f7a64d34031deb38a7de2 /src/systemc/channel | |
parent | 440b143742ece282c2b0497c70818a5796f66f1a (diff) | |
download | gem5-df50b775cb04bb22fd583cee40af870f2c80b65e.tar.xz |
systemc: Implement a significant portion of sc_clock.
Change-Id: Ic195f46ac13b46a02c86a5fc8d90ba66a415a9c8
Reviewed-on: https://gem5-review.googlesource.com/12215
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
Diffstat (limited to 'src/systemc/channel')
-rw-r--r-- | src/systemc/channel/sc_clock.cc | 151 |
1 files changed, 99 insertions, 52 deletions
diff --git a/src/systemc/channel/sc_clock.cc b/src/systemc/channel/sc_clock.cc index 65f1f100d..6736e57cf 100644 --- a/src/systemc/channel/sc_clock.cc +++ b/src/systemc/channel/sc_clock.cc @@ -28,94 +28,141 @@ */ #include "base/logging.hh" +#include "base/types.hh" +#include "sim/core.hh" +#include "sim/eventq.hh" +#include "systemc/core/kernel.hh" +#include "systemc/core/sched_event.hh" +#include "systemc/core/scheduler.hh" #include "systemc/ext/channel/sc_clock.hh" #include "systemc/ext/core/sc_module.hh" // for sc_gen_unique_name -namespace sc_core +namespace sc_gem5 { -sc_clock::sc_clock() : - sc_interface(), sc_signal<bool>(sc_gen_unique_name("clock")) +class ClockTick : public ScEvent { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); -} + private: + ::sc_core::sc_clock *clock; + ::sc_core::sc_time _period; + std::string _name; + Process *p; + ProcessMemberFuncWrapper<::sc_core::sc_clock> funcWrapper; + std::string _procName; + + public: + ClockTick(::sc_core::sc_clock *clock, bool to, + ::sc_core::sc_time _period) : + ScEvent([this]() { tick(); }), + clock(clock), _period(_period), _name(clock->name()), + funcWrapper(clock, to ? &::sc_core::sc_clock::tickUp : + &::sc_core::sc_clock::tickDown) + { + _name += (to ? ".up_tick" : ".down_tick"); + _procName = _name + ".p"; + p = newMethodProcess(_procName.c_str(), &funcWrapper); + scheduler.dontInitialize(p); + } + + ~ClockTick() + { + if (scheduled()) + scheduler.deschedule(this); + p->popListNode(); + } + + void + tick() + { + scheduler.schedule(this, _period); + p->ready(); + } +}; + +}; -sc_clock::sc_clock(const char *name) : sc_interface(), sc_signal<bool>(name) +namespace sc_core { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); -} + +sc_clock::sc_clock() : + sc_clock(sc_gen_unique_name("clock"), sc_time(1.0, SC_NS), + 0.5, SC_ZERO_TIME, true) +{} + +sc_clock::sc_clock(const char *name) : + sc_clock(name, sc_time(1.0, SC_NS), 0.5, SC_ZERO_TIME, true) +{} sc_clock::sc_clock(const char *name, const sc_time &period, double duty_cycle, const sc_time &start_time, - bool posedge_first) + bool posedge_first) : + sc_interface(), sc_signal<bool>(name, posedge_first ? false : true), + _period(period), _dutyCycle(duty_cycle), _startTime(start_time), + _posedgeFirst(posedge_first) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + _gem5UpEdge = new ::sc_gem5::ClockTick(this, true, period); + _gem5DownEdge = new ::sc_gem5::ClockTick(this, false, period); } sc_clock::sc_clock(const char *name, double period_v, sc_time_unit period_tu, - double duty_cycle) -{ - warn("%s not implemented.\n", __PRETTY_FUNCTION__); -} + double duty_cycle) : + sc_clock(name, sc_time(period_v, period_tu), duty_cycle, SC_ZERO_TIME, + true) +{} sc_clock::sc_clock(const char *name, double period_v, sc_time_unit period_tu, double duty_cycle, double start_time_v, - sc_time_unit start_time_tu, bool posedge_first) -{ - warn("%s not implemented.\n", __PRETTY_FUNCTION__); -} + sc_time_unit start_time_tu, bool posedge_first) : + sc_clock(name, sc_time(period_v, period_tu), duty_cycle, + sc_time(start_time_v, start_time_tu), posedge_first) +{} sc_clock::sc_clock(const char *name, double period, double duty_cycle, - double start_time, bool posedge_first) + double start_time, bool posedge_first) : + sc_clock(name, sc_time(period, true), duty_cycle, + sc_time(start_time, true), posedge_first) +{} + +sc_clock::~sc_clock() { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + if (_gem5UpEdge->scheduled()) + ::sc_gem5::scheduler.deschedule(_gem5UpEdge); + if (_gem5DownEdge->scheduled()) + ::sc_gem5::scheduler.deschedule(_gem5DownEdge); + delete _gem5UpEdge; + delete _gem5DownEdge; } -sc_clock::~sc_clock() {} - void sc_clock::write(const bool &) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); -} - -const sc_time & -sc_clock::period() const -{ - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return *(const sc_time *)nullptr; + panic("write() called on sc_clock."); } -double -sc_clock::duty_cycle() const -{ - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return 0.0; -} +const sc_time &sc_clock::period() const { return _period; } +double sc_clock::duty_cycle() const { return _dutyCycle; } +const sc_time &sc_clock::start_time() const { return _startTime; } +bool sc_clock::posedge_first() const { return _posedgeFirst; } const sc_time & -sc_clock::start_time() const +sc_clock::time_stamp() { warn("%s not implemented.\n", __PRETTY_FUNCTION__); return *(const sc_time *)nullptr; } -bool -sc_clock::posedge_first() const -{ - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return false; -} - -const sc_time & -sc_clock::time_stamp() +void +sc_clock::before_end_of_elaboration() { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); - return *(const sc_time *)nullptr; + if (_posedgeFirst) { + ::sc_gem5::scheduler.schedule(_gem5UpEdge, _startTime); + ::sc_gem5::scheduler.schedule(_gem5DownEdge, + _startTime + _period * _dutyCycle); + } else { + ::sc_gem5::scheduler.schedule(_gem5DownEdge, _startTime); + ::sc_gem5::scheduler.schedule(_gem5UpEdge, + _startTime + _period * (1.0 - _dutyCycle)); + } } -const char *sc_clock::kind() const { return "sc_clock"; } - -void sc_clock::before_end_of_elaboration() {} - } // namespace sc_core |