From ee3e3278fd7e0d805ea0ecbf97a113cc5086c0af Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 4 Oct 2018 14:59:28 -0700 Subject: [PATCH] systemc: Change how signal based resets work. The previous implementation used the value changed event to track when signals changed value, but there were a couple problems with this approach. First, this piggybacked on the sensitivity mechanism in some ways, but diverged in others. The sensitivity didn't notify a process when it was satisfied like other sensitivity types would, and it also ignored whether the process was disabled. Second, the value_changed_event is notified by a signal instance as a delta notification, but reset signals are supposed to act immediately. That means they should happen before all delta notifications, or in other words all delta notifications should see the reset status of a given process. That's particularly important in the case of wait(int n) where setting the reset clears the reset count, and the count is checked when determining whether or not to wake up a process when its sensitivity is satisfied, potentially by a delta notification. Third, by removing the middle man and not trying to repurpose the sensitivity mechanism, the code gets simpler and easier to understand. Change-Id: I0d05d11437291d368b060f6a45a207813615f113 Reviewed-on: https://gem5-review.googlesource.com/c/13294 Reviewed-by: Gabe Black Maintainer: Gabe Black --- src/systemc/channel/sc_signal.cc | 15 +++- src/systemc/core/event.cc | 8 --- src/systemc/core/event.hh | 18 ----- src/systemc/core/port.cc | 19 +++-- src/systemc/core/port.hh | 16 ++--- src/systemc/core/process.cc | 20 +++++- src/systemc/core/process.hh | 46 +++++++++++- src/systemc/core/sc_module.cc | 28 ++++---- src/systemc/core/sc_spawn.cc | 12 ++-- src/systemc/core/sensitivity.cc | 80 +-------------------- src/systemc/core/sensitivity.hh | 82 +--------------------- src/systemc/ext/channel/sc_signal.hh | 13 ++++ src/systemc/ext/channel/sc_signal_in_if.hh | 14 ++++ 13 files changed, 144 insertions(+), 227 deletions(-) diff --git a/src/systemc/channel/sc_signal.cc b/src/systemc/channel/sc_signal.cc index 702f20901..14ee8a6e4 100644 --- a/src/systemc/channel/sc_signal.cc +++ b/src/systemc/channel/sc_signal.cc @@ -165,11 +165,24 @@ ScSignalBaseBinary::posedge() const { return _posStamp == getChangeStamp(); } -bool +bool ScSignalBaseBinary::negedge() const { return _negStamp == getChangeStamp(); } +void +ScSignalBaseBinary::_signalReset(sc_gem5::Reset *r) +{ + r->update(); +} + +void +ScSignalBaseBinary::_signalReset() +{ + for (auto r: _resets) + _signalReset(r); +} + } // namespace sc_gem5 diff --git a/src/systemc/core/event.cc b/src/systemc/core/event.cc index 36830b308..aa4a71315 100644 --- a/src/systemc/core/event.cc +++ b/src/systemc/core/event.cc @@ -147,13 +147,6 @@ Event::notify(DynamicSensitivities &senses) senses.resize(size); } -void -Event::notify(ResetSensitivities &senses) -{ - for (auto s: senses) - s->notify(this); -} - void Event::notify() { @@ -167,7 +160,6 @@ Event::notify() scheduler.deschedule(&delayedNotify); _triggeredStamp = scheduler.changeStamp(); - notify(resetSense); notify(staticSenseMethod); notify(dynamicSenseMethod); notify(staticSenseThread); diff --git a/src/systemc/core/event.hh b/src/systemc/core/event.hh index ff72fd3b0..2d620c91b 100644 --- a/src/systemc/core/event.hh +++ b/src/systemc/core/event.hh @@ -74,7 +74,6 @@ class Event void notify(StaticSensitivities &senses); void notify(DynamicSensitivities &senses); - void notify(ResetSensitivities &senses); void notify(); void notify(const sc_core::sc_time &t); @@ -138,22 +137,6 @@ class Event } } } - void - addSensitivity(ResetSensitivity *s) const - { - resetSense.push_back(s); - } - void - delSensitivity(ResetSensitivity *s) const - { - for (auto &t: resetSense) { - if (t == s) { - t = resetSense.back(); - resetSense.pop_back(); - break; - } - } - } private: sc_core::sc_event *_sc_event; @@ -171,7 +154,6 @@ class Event mutable StaticSensitivities staticSenseThread; mutable DynamicSensitivities dynamicSenseMethod; mutable DynamicSensitivities dynamicSenseThread; - mutable ResetSensitivities resetSense; }; extern Events topLevelEvents; diff --git a/src/systemc/core/port.cc b/src/systemc/core/port.cc index db025bbfe..b7120efa4 100644 --- a/src/systemc/core/port.cc +++ b/src/systemc/core/port.cc @@ -29,6 +29,7 @@ #include "systemc/core/port.hh" +#include "systemc/core/process.hh" #include "systemc/core/sensitivity.hh" #include "systemc/ext/channel/sc_signal_in_if.hh" @@ -50,14 +51,15 @@ Port::finalizeFinder(StaticSensitivityFinder *finder) } void -Port::finalizeReset(ResetSensitivityPort *reset) +Port::finalizeReset(Reset *reset) { assert(size() <= 1); if (size()) { auto iface = dynamic_cast *>(getInterface(0)); assert(iface); - reset->setSignal(iface); + if (!reset->install(iface)) + delete reset; } } @@ -80,12 +82,12 @@ Port::sensitive(StaticSensitivityFinder *finder) } void -Port::sensitive(ResetSensitivityPort *reset) +Port::addReset(Reset *reset) { if (finalized) finalizeReset(reset); else - sensitivities.push_back(new Sensitivity(reset)); + resets.push_back(reset); } void @@ -110,14 +112,17 @@ Port::finalize() for (auto &s: sensitivities) { if (s->port) finalizePort(s->port); - else if (s->finder) - finalizeFinder(s->finder); else - finalizeReset(s->reset); + finalizeFinder(s->finder); delete s; } sensitivities.clear(); + + for (auto &r: resets) + finalizeReset(r); + + resets.clear(); } void diff --git a/src/systemc/core/port.hh b/src/systemc/core/port.hh index f7b1bbce4..fa98c6002 100644 --- a/src/systemc/core/port.hh +++ b/src/systemc/core/port.hh @@ -43,7 +43,7 @@ namespace sc_gem5 class StaticSensitivityPort; class StaticSensitivityFinder; -class ResetSensitivityPort; +class Reset; class Port; @@ -62,7 +62,7 @@ class Port void finalizePort(StaticSensitivityPort *port); void finalizeFinder(StaticSensitivityFinder *finder); - void finalizeReset(ResetSensitivityPort *reset); + void finalizeReset(Reset *reset); void addInterface(::sc_core::sc_interface *iface) @@ -112,24 +112,20 @@ class Port struct Sensitivity { Sensitivity(StaticSensitivityPort *port) : - port(port), finder(nullptr), reset(nullptr) + port(port), finder(nullptr) {} Sensitivity(StaticSensitivityFinder *finder) : - port(nullptr), finder(finder), reset(nullptr) - {} - - Sensitivity(ResetSensitivityPort *reset) : - port(nullptr), finder(nullptr), reset(reset) + port(nullptr), finder(finder) {} StaticSensitivityPort *port; StaticSensitivityFinder *finder; - ResetSensitivityPort *reset; }; std::vector bindings; std::vector sensitivities; + std::vector resets; public: static Port * @@ -166,7 +162,7 @@ class Port void sensitive(StaticSensitivityPort *port); void sensitive(StaticSensitivityFinder *finder); - void sensitive(ResetSensitivityPort *reset); + void addReset(Reset *reset); void finalize(); void regPort(); diff --git a/src/systemc/core/process.cc b/src/systemc/core/process.cc index d8ed5ffba..3bf7ead07 100644 --- a/src/systemc/core/process.cc +++ b/src/systemc/core/process.cc @@ -31,6 +31,7 @@ #include "base/logging.hh" #include "systemc/core/event.hh" +#include "systemc/core/port.hh" #include "systemc/core/scheduler.hh" #include "systemc/ext/core/sc_join.hh" #include "systemc/ext/core/sc_main.hh" @@ -293,9 +294,9 @@ Process::setDynamic(DynamicSensitivity *s) } void -Process::addReset(ResetSensitivity *s) +Process::addReset(Reset *reset) { - resetSensitivities.push_back(s); + resets.push_back(reset); } void @@ -418,4 +419,19 @@ throw_it_wrapper(Process *p, ExceptionWrapperBase &exc, bool inc_kids) p->throw_it(exc, inc_kids); } +void +newReset(const sc_core::sc_port_base *pb, Process *p, bool s, bool v) +{ + Port *port = Port::fromPort(pb); + port->addReset(new Reset(p, s, v)); +} + +void +newReset(const sc_core::sc_signal_in_if *sig, Process *p, bool s, bool v) +{ + Reset *reset = new Reset(p, s, v); + if (!reset->install(sig)) + delete reset; +} + } // namespace sc_gem5 diff --git a/src/systemc/core/process.hh b/src/systemc/core/process.hh index 9bddbdd04..a0657f4be 100644 --- a/src/systemc/core/process.hh +++ b/src/systemc/core/process.hh @@ -40,6 +40,7 @@ #include "systemc/core/object.hh" #include "systemc/core/sched_event.hh" #include "systemc/core/sensitivity.hh" +#include "systemc/ext/channel/sc_signal_in_if.hh" #include "systemc/ext/core/sc_event.hh" #include "systemc/ext/core/sc_module.hh" #include "systemc/ext/core/sc_process_handle.hh" @@ -57,6 +58,9 @@ namespace sc_gem5 class ScHalt {}; +class Process; +class Reset; + class Process : public ::sc_core::sc_process_b, public ListNode { public: @@ -103,7 +107,7 @@ class Process : public ::sc_core::sc_process_b, public ListNode void addStatic(StaticSensitivity *); void setDynamic(DynamicSensitivity *); void clearDynamic() { setDynamic(nullptr); } - void addReset(ResetSensitivity *); + void addReset(Reset *); ScEvent timeoutEvent; void setTimeout(::sc_core::sc_time t); @@ -189,7 +193,7 @@ class Process : public ::sc_core::sc_process_b, public ListNode StaticSensitivities staticSensitivities; DynamicSensitivity *dynamicSensitivity; - ResetSensitivities resetSensitivities; + std::vector resets; std::unique_ptr<::sc_core::sc_report> _lastReport; @@ -198,6 +202,44 @@ class Process : public ::sc_core::sc_process_b, public ListNode UniqueNameGen nameGen; }; +class Reset +{ + public: + Reset(Process *p, bool s, bool v) : + _process(p), _signal(nullptr), _sync(s), _value(v) + {} + + bool + install(const sc_core::sc_signal_in_if *s) + { + _signal = s; + + if (_signal->_addReset(this)) { + _process->addReset(this); + if (_signal->read() == _value) + update(); + return true; + } + return false; + } + void update() { _process->signalReset(_signal->read() == _value, _sync); } + + Process *process() { return _process; } + const sc_core::sc_signal_in_if *signal() { return _signal; } + bool sync() { return _sync; } + bool value() { return _value; } + + private: + Process *_process; + const sc_core::sc_signal_in_if *_signal; + bool _sync; + bool _value; +}; + +void newReset(const sc_core::sc_port_base *pb, Process *p, bool s, bool v); +void newReset(const sc_core::sc_signal_in_if *sig, Process *p, + bool s, bool v); + } // namespace sc_gem5 #endif //__SYSTEMC_CORE_PROCESS_HH__ diff --git a/src/systemc/core/sc_module.cc b/src/systemc/core/sc_module.cc index fe4b5cdb6..42fff3271 100644 --- a/src/systemc/core/sc_module.cc +++ b/src/systemc/core/sc_module.cc @@ -36,8 +36,12 @@ #include "systemc/core/kernel.hh" #include "systemc/core/module.hh" #include "systemc/core/object.hh" +#include "systemc/core/port.hh" #include "systemc/core/process_types.hh" #include "systemc/core/sensitivity.hh" +#include "systemc/ext/channel/sc_in.hh" +#include "systemc/ext/channel/sc_inout.hh" +#include "systemc/ext/channel/sc_out.hh" #include "systemc/ext/channel/sc_signal_in_if.hh" #include "systemc/ext/core/sc_module.hh" #include "systemc/ext/core/sc_module_name.hh" @@ -258,58 +262,50 @@ sc_module::end_module() void sc_module::reset_signal_is(const sc_in &port, bool val) { - sc_gem5::newResetSensitivityPort( - ::sc_gem5::Process::newest(), &port, val, true); + ::sc_gem5::newReset(&port, ::sc_gem5::Process::newest(), true, val); } void sc_module::reset_signal_is(const sc_inout &port, bool val) { - sc_gem5::newResetSensitivityPort( - ::sc_gem5::Process::newest(), &port, val, true); + ::sc_gem5::newReset(&port, ::sc_gem5::Process::newest(), true, val); } void sc_module::reset_signal_is(const sc_out &port, bool val) { - sc_gem5::newResetSensitivityPort( - ::sc_gem5::Process::newest(), &port, val, true); + ::sc_gem5::newReset(&port, ::sc_gem5::Process::newest(), true, val); } void sc_module::reset_signal_is(const sc_signal_in_if &signal, bool val) { - sc_gem5::newResetSensitivitySignal( - ::sc_gem5::Process::newest(), &signal, val, true); + ::sc_gem5::newReset(&signal, ::sc_gem5::Process::newest(), true, val); } void sc_module::async_reset_signal_is(const sc_in &port, bool val) { - sc_gem5::newResetSensitivityPort( - ::sc_gem5::Process::newest(), &port, val, false); + ::sc_gem5::newReset(&port, ::sc_gem5::Process::newest(), false, val); } void sc_module::async_reset_signal_is(const sc_inout &port, bool val) { - sc_gem5::newResetSensitivityPort( - ::sc_gem5::Process::newest(), &port, val, false); + ::sc_gem5::newReset(&port, ::sc_gem5::Process::newest(), false, val); } void sc_module::async_reset_signal_is(const sc_out &port, bool val) { - sc_gem5::newResetSensitivityPort( - ::sc_gem5::Process::newest(), &port, val, false); + ::sc_gem5::newReset(&port, ::sc_gem5::Process::newest(), false, val); } void sc_module::async_reset_signal_is(const sc_signal_in_if &signal, bool val) { - sc_gem5::newResetSensitivitySignal( - ::sc_gem5::Process::newest(), &signal, val, false); + ::sc_gem5::newReset(&signal, ::sc_gem5::Process::newest(), false, val); } diff --git a/src/systemc/core/sc_spawn.cc b/src/systemc/core/sc_spawn.cc index ed7f2f22b..8c4d2bc72 100644 --- a/src/systemc/core/sc_spawn.cc +++ b/src/systemc/core/sc_spawn.cc @@ -31,6 +31,10 @@ #include "systemc/core/process.hh" #include "systemc/core/process_types.hh" #include "systemc/core/scheduler.hh" +#include "systemc/ext/channel/sc_in.hh" +#include "systemc/ext/channel/sc_inout.hh" +#include "systemc/ext/channel/sc_out.hh" +#include "systemc/ext/channel/sc_signal_in_if.hh" #include "systemc/ext/core/sc_main.hh" #include "systemc/ext/core/sc_module.hh" #include "systemc/ext/core/sc_spawn.hh" @@ -85,16 +89,16 @@ spawnWork(ProcessFuncWrapper *func, const char *name, newStaticSensitivityFinder(proc, f); for (auto p: opts->_in_resets) - newResetSensitivityPort(proc, p.target, p.value, p.sync); + newReset(p.target, proc, p.sync, p.value); for (auto p: opts->_inout_resets) - newResetSensitivityPort(proc, p.target, p.value, p.sync); + newReset(p.target, proc, p.sync, p.value); for (auto p: opts->_out_resets) - newResetSensitivityPort(proc, p.target, p.value, p.sync); + newReset(p.target, proc, p.sync, p.value); for (auto i: opts->_if_resets) - newResetSensitivitySignal(proc, i.target, i.value, i.sync); + newReset(i.target, proc, i.sync, i.value); } if (opts && opts->_dontInitialize && diff --git a/src/systemc/core/sensitivity.cc b/src/systemc/core/sensitivity.cc index 9ce6fc4de..4f84ce0e9 100644 --- a/src/systemc/core/sensitivity.cc +++ b/src/systemc/core/sensitivity.cc @@ -29,6 +29,7 @@ #include "systemc/core/sensitivity.hh" +#include "base/logging.hh" #include "systemc/core/event.hh" #include "systemc/core/port.hh" #include "systemc/core/process.hh" @@ -97,18 +98,6 @@ StaticSensitivity::delFromEvent(const ::sc_core::sc_event *e) Event::getFromScEvent(e)->delSensitivity(this); } -void -ResetSensitivity::addToEvent(const ::sc_core::sc_event *e) -{ - Event::getFromScEvent(e)->addSensitivity(this); -} - -void -ResetSensitivity::delFromEvent(const ::sc_core::sc_event *e) -{ - Event::getFromScEvent(e)->delSensitivity(this); -} - /* * Static sensitivities. @@ -250,71 +239,4 @@ DynamicSensitivityEventAndList::notify(Event *e) return true; } -/* - * Reset sensitivities. - */ - -void -newResetSensitivitySignal( - Process *p, const sc_core::sc_signal_in_if *signal, - bool val, bool sync) -{ - auto s = new ResetSensitivitySignal(p, signal, val, sync); - s->addToEvent(s->event); - p->addReset(s); -} - -void -newResetSensitivityPort(Process *p, const sc_core::sc_in *port, - bool val, bool sync) -{ - auto s = new ResetSensitivityPort(p, port, val, sync); - Port::fromPort(port)->sensitive(s); - p->addReset(s); -} -void -newResetSensitivityPort(Process *p, const sc_core::sc_inout *port, - bool val, bool sync) -{ - auto s = new ResetSensitivityPort(p, port, val, sync); - Port::fromPort(port)->sensitive(s); - p->addReset(s); -} -void -newResetSensitivityPort(Process *p, const sc_core::sc_out *port, - bool val, bool sync) -{ - auto s = new ResetSensitivityPort(p, port, val, sync); - Port::fromPort(port)->sensitive(s); - p->addReset(s); -} - -ResetSensitivitySignal::ResetSensitivitySignal( - Process *p, const sc_core::sc_signal_in_if *signal, - bool _val, bool _sync) : - Sensitivity(p), ResetSensitivity(p, _val, _sync), - SensitivityEvent(p, signal ? &signal->value_changed_event() : nullptr), - _signal(signal) -{ - if (signal && signal->read() == val()) - process->signalReset(true, sync()); -} - -bool -ResetSensitivitySignal::notify(Event *e) -{ - process->signalReset(_signal->read() == val(), sync()); - return true; -} - -void -ResetSensitivityPort::setSignal(const ::sc_core::sc_signal_in_if *signal) -{ - _signal = signal; - event = &_signal->value_changed_event(); - addToEvent(event); - if (signal->read() == val()) - process->signalReset(true, sync()); -} - } // namespace sc_gem5 diff --git a/src/systemc/core/sensitivity.hh b/src/systemc/core/sensitivity.hh index 62c9682c3..7a065d2a8 100644 --- a/src/systemc/core/sensitivity.hh +++ b/src/systemc/core/sensitivity.hh @@ -81,8 +81,7 @@ class Sensitivity enum Category { Static, - Dynamic, - Reset + Dynamic }; virtual Category category() = 0; @@ -92,7 +91,7 @@ class Sensitivity /* - * Dynamic vs. static vs. reset sensitivity. + * Dynamic vs. static sensitivity. */ class DynamicSensitivity : virtual public Sensitivity @@ -124,29 +123,6 @@ class StaticSensitivity : virtual public Sensitivity typedef std::vector StaticSensitivities; -class ResetSensitivity : virtual public Sensitivity -{ - private: - bool _val; - bool _sync; - - protected: - ResetSensitivity(Process *p, bool _val, bool _sync) : - Sensitivity(p), _val(_val), _sync(_sync) - {} - - void addToEvent(const ::sc_core::sc_event *e) override; - void delFromEvent(const ::sc_core::sc_event *e) override; - - bool val() { return _val; } - bool sync() { return _sync; } - - public: - Category category() override { return Reset; } -}; - -typedef std::vector ResetSensitivities; - /* * Sensitivity to an event or events, which can be static or dynamic. @@ -319,60 +295,6 @@ class DynamicSensitivityEventAndList : bool notify(Event *e) override; }; -/* - * Reset sensitivities. - */ - -void newResetSensitivitySignal( - Process *p, const sc_core::sc_signal_in_if *signal, - bool val, bool sync); - -void newResetSensitivityPort( - Process *p, const sc_core::sc_in *port, bool val, bool sync); -void newResetSensitivityPort( - Process *p, const sc_core::sc_inout *port, bool val, bool sync); -void newResetSensitivityPort( - Process *p, const sc_core::sc_out *port, bool val, bool sync); - -class ResetSensitivitySignal : - public ResetSensitivity, public SensitivityEvent -{ - protected: - const sc_core::sc_signal_in_if *_signal; - - friend void newResetSensitivitySignal( - Process *p, const sc_core::sc_signal_in_if *signal, - bool val, bool sync); - - ResetSensitivitySignal( - Process *p, const sc_core::sc_signal_in_if *signal, - bool _val, bool _sync); - - bool notify(Event *e) override; -}; - -class ResetSensitivityPort : public ResetSensitivitySignal -{ - private: - friend void newResetSensitivityPort( - Process *p, const sc_core::sc_in *port, bool val, bool sync); - friend void newResetSensitivityPort( - Process *p, const sc_core::sc_inout *port, - bool val, bool sync); - friend void newResetSensitivityPort( - Process *p, const sc_core::sc_out *port, - bool val, bool sync); - - ResetSensitivityPort( - Process *p, const sc_core::sc_port_base *port, - bool _val, bool _sync) : - Sensitivity(p), ResetSensitivitySignal(p, nullptr, _val, _sync) - {} - - public: - void setSignal(const ::sc_core::sc_signal_in_if *signal); -}; - } // namespace sc_gem5 #endif //__SYSTEMC_CORE_SENSITIVITY_HH__ diff --git a/src/systemc/ext/channel/sc_signal.hh b/src/systemc/ext/channel/sc_signal.hh index e4300343d..3b2765db5 100644 --- a/src/systemc/ext/channel/sc_signal.hh +++ b/src/systemc/ext/channel/sc_signal.hh @@ -51,6 +51,7 @@ namespace sc_gem5 { class Process; +class Reset; class ScSignalBase : public sc_core::sc_prim_channel { @@ -80,6 +81,10 @@ class ScSignalBaseBinary : public ScSignalBase protected: ScSignalBaseBinary(const char *_name); + mutable std::vector _resets; + void _signalReset(sc_gem5::Reset *reset); + void _signalReset(); + const sc_core::sc_event &posedgeEvent() const; const sc_core::sc_event &negedgeEvent() const; @@ -352,6 +357,7 @@ class sc_signal : return; this->m_cur_val = this->m_new_val; + this->_signalReset(); this->_signalChange(); if (this->m_cur_val) { this->_posStamp = ::sc_gem5::getChangeStamp(); @@ -363,6 +369,13 @@ class sc_signal : } private: + bool + _addReset(sc_gem5::Reset *reset) const + { + this->_resets.push_back(reset); + return true; + } + // Disabled sc_signal(const sc_signal &); }; diff --git a/src/systemc/ext/channel/sc_signal_in_if.hh b/src/systemc/ext/channel/sc_signal_in_if.hh index 6fac35860..008516495 100644 --- a/src/systemc/ext/channel/sc_signal_in_if.hh +++ b/src/systemc/ext/channel/sc_signal_in_if.hh @@ -39,6 +39,13 @@ class sc_logic; }; +namespace sc_gem5 +{ + +class Reset; + +} // namespace sc_gem5 + namespace sc_core { @@ -83,6 +90,13 @@ class sc_signal_in_if : virtual public sc_interface sc_signal_in_if() : sc_interface() {} private: + friend class sc_gem5::Reset; + virtual bool + _addReset(sc_gem5::Reset *reset) const + { + return false; + } + // Disabled sc_signal_in_if(const sc_signal_in_if &) : sc_interface() {} sc_signal_in_if & -- 2.30.2