systemc: Implement signal based resets.
authorGabe Black <gabeblack@google.com>
Wed, 26 Sep 2018 10:20:09 +0000 (03:20 -0700)
committerGabe Black <gabeblack@google.com>
Tue, 16 Oct 2018 00:35:50 +0000 (00:35 +0000)
The implementation is based on sc_event sensitivities.

Also of note is that the way reset works in the Accellera
implementation isn't consistent with the spec. That says that
wait(int n) is supposed to be equivalent to calling wait() n times,
assuming n is greater than 0.

Instead, Accellera stores that count and then doesn't wake up the
process until the count is 0, decrementing it otherwise.

That means that when the process is in reset, it won't actually reset
for those intermediate wait()s which it would if wait() was called
repeatedly. Also, oddly, when a reset becomes asserted, it will clear
the count to 0 explicitly. That may have been an attempt to make the
behavior of wait(int n) match the spec, but it doesn't handle cases
where the reset is already set when wait(int n) is called.

Change-Id: I92f8e9a128e6618af94dc048ce570a4436e17e4b
Reviewed-on: https://gem5-review.googlesource.com/c/13186
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>

13 files changed:
src/systemc/core/event.cc
src/systemc/core/event.hh
src/systemc/core/port.cc
src/systemc/core/port.hh
src/systemc/core/process.cc
src/systemc/core/process.hh
src/systemc/core/sc_module.cc
src/systemc/core/sc_spawn.cc
src/systemc/core/scheduler.cc
src/systemc/core/scheduler.hh
src/systemc/core/sensitivity.cc
src/systemc/core/sensitivity.hh
src/systemc/ext/core/sc_spawn.hh

index 4fb99e6d92b18d780484d1688ad2492624a317f9..097961e99f751ba2bd3cdbc675224468638bc722 100644 (file)
@@ -154,6 +154,13 @@ Event::notify(DynamicSensitivities &senses)
     senses.resize(size);
 }
 
+void
+Event::notify(ResetSensitivities &senses)
+{
+    for (auto s: senses)
+        s->notify(this);
+}
+
 void
 Event::notify()
 {
@@ -167,7 +174,7 @@ Event::notify()
         scheduler.deschedule(&delayedNotify);
 
     _triggeredStamp = scheduler.changeStamp();
-
+    notify(resetSense);
     notify(staticSenseMethod);
     notify(dynamicSenseMethod);
     notify(staticSenseThread);
index 2d620c91bb0aa4cf4764414994749d97ae9071ea..ff72fd3b0c0e17e0d661cb5f6f6bf0e617d4a12c 100644 (file)
@@ -74,6 +74,7 @@ class Event
 
     void notify(StaticSensitivities &senses);
     void notify(DynamicSensitivities &senses);
+    void notify(ResetSensitivities &senses);
 
     void notify();
     void notify(const sc_core::sc_time &t);
@@ -137,6 +138,22 @@ 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;
@@ -154,6 +171,7 @@ class Event
     mutable StaticSensitivities staticSenseThread;
     mutable DynamicSensitivities dynamicSenseMethod;
     mutable DynamicSensitivities dynamicSenseThread;
+    mutable ResetSensitivities resetSense;
 };
 
 extern Events topLevelEvents;
index af6ecd125b6e87fd2ca5fd9e07d01d996857ace4..8ee0549a4193cac3250cdc3d241407d2d264c753 100644 (file)
@@ -30,6 +30,7 @@
 #include "systemc/core/port.hh"
 
 #include "systemc/core/sensitivity.hh"
+#include "systemc/ext/channel/sc_signal_in_if.hh"
 
 namespace sc_gem5
 {
@@ -48,6 +49,18 @@ Port::finalizeFinder(StaticSensitivityFinder *finder)
         finder->addEvent(&finder->find(getInterface(i)));
 }
 
+void
+Port::finalizeReset(ResetSensitivityPort *reset)
+{
+    assert(size() <= 1);
+    if (size()) {
+        auto iface =
+            dynamic_cast<sc_core::sc_signal_in_if<bool> *>(getInterface(0));
+        assert(iface);
+        reset->setSignal(iface);
+    }
+}
+
 void
 Port::sensitive(StaticSensitivityPort *port)
 {
@@ -66,6 +79,15 @@ Port::sensitive(StaticSensitivityFinder *finder)
         sensitivities.push_back(new Sensitivity(finder));
 }
 
+void
+Port::sensitive(ResetSensitivityPort *reset)
+{
+    if (finalized)
+        finalizeReset(reset);
+    else
+        sensitivities.push_back(new Sensitivity(reset));
+}
+
 void
 Port::finalize()
 {
@@ -88,8 +110,10 @@ Port::finalize()
     for (auto &s: sensitivities) {
         if (s->port)
             finalizePort(s->port);
-        else
+        else if (s->finder)
             finalizeFinder(s->finder);
+        else
+            finalizeReset(s->reset);
         delete s;
     }
 
index 217269d8697465d7be09303653322dd8bdf2360b..eb8dbfef319ccbbe5866cb45c4e342af33a33ed7 100644 (file)
@@ -42,6 +42,7 @@ namespace sc_gem5
 
 class StaticSensitivityPort;
 class StaticSensitivityFinder;
+class ResetSensitivityPort;
 
 class Port;
 
@@ -58,6 +59,7 @@ class Port
 
     void finalizePort(StaticSensitivityPort *port);
     void finalizeFinder(StaticSensitivityFinder *finder);
+    void finalizeReset(ResetSensitivityPort *reset);
 
     void
     addInterface(::sc_core::sc_interface *iface)
@@ -105,15 +107,20 @@ class Port
     struct Sensitivity
     {
         Sensitivity(StaticSensitivityPort *port) :
-            port(port), finder(nullptr)
+            port(port), finder(nullptr), reset(nullptr)
         {}
 
         Sensitivity(StaticSensitivityFinder *finder) :
-            port(nullptr), finder(finder)
+            port(nullptr), finder(finder), reset(nullptr)
+        {}
+
+        Sensitivity(ResetSensitivityPort *reset) :
+            port(nullptr), finder(nullptr), reset(reset)
         {}
 
         StaticSensitivityPort *port;
         StaticSensitivityFinder *finder;
+        ResetSensitivityPort *reset;
     };
 
     std::vector<Binding *> bindings;
@@ -148,6 +155,7 @@ class Port
 
     void sensitive(StaticSensitivityPort *port);
     void sensitive(StaticSensitivityFinder *finder);
+    void sensitive(ResetSensitivityPort *reset);
 
     void finalize();
 
index 45c01e916c83d665b8a2e5050a6910437cd3cdf2..78bbf91d50bb0b2efafa7d4c1f652eae7f7c0480 100644 (file)
@@ -235,6 +235,27 @@ Process::syncResetOff(bool inc_kids)
     _syncReset = false;
 }
 
+void
+Process::signalReset(bool set, bool sync)
+{
+    if (set) {
+        waitCount(0);
+        if (sync) {
+            syncResetCount++;
+        } else {
+            asyncResetCount++;
+            cancelTimeout();
+            clearDynamic();
+            scheduler.runNext(this);
+        }
+    } else {
+        if (sync)
+            syncResetCount--;
+        else
+            asyncResetCount--;
+    }
+}
+
 void
 Process::run()
 {
@@ -271,6 +292,12 @@ Process::setDynamic(DynamicSensitivity *s)
     dynamicSensitivity = s;
 }
 
+void
+Process::addReset(ResetSensitivity *s)
+{
+    resetSensitivities.push_back(s);
+}
+
 void
 Process::cancelTimeout()
 {
@@ -302,6 +329,11 @@ Process::timeout()
 void
 Process::satisfySensitivity(Sensitivity *s)
 {
+    if (_waitCount) {
+        _waitCount--;
+        return;
+    }
+
     // If there's a dynamic sensitivity and this wasn't it, ignore.
     if ((dynamicSensitivity || timeoutEvent.scheduled()) &&
             dynamicSensitivity != s) {
@@ -346,7 +378,8 @@ Process::Process(const char *name, ProcessFuncWrapper *func, bool internal) :
     timeoutEvent([this]() { this->timeout(); }),
     func(func), _internal(internal), _timedOut(false), _dontInitialize(false),
     _needsStart(true), _isUnwinding(false), _terminated(false),
-    _suspended(false), _disabled(false), _syncReset(false), refCount(0),
+    _suspended(false), _disabled(false), _syncReset(false), syncResetCount(0),
+    asyncResetCount(0), _waitCount(0), refCount(0),
     stackSize(::Fiber::DefaultStackSize), dynamicSensitivity(nullptr)
 {
     _dynamic =
index 9e85fc7cc3e6f77ec57962b8746b806f70128898..85a7a27a88513297ca0f35b2fafb4d2c1ca841f5 100644 (file)
@@ -87,6 +87,8 @@ class Process : public ::sc_core::sc_process_b, public ListNode
     void syncResetOn(bool inc_kids);
     void syncResetOff(bool inc_kids);
 
+    void signalReset(bool set, bool sync);
+
     void incref() { refCount++; }
     void decref() { refCount--; }
 
@@ -100,6 +102,7 @@ class Process : public ::sc_core::sc_process_b, public ListNode
     void addStatic(StaticSensitivity *);
     void setDynamic(DynamicSensitivity *);
     void clearDynamic() { setDynamic(nullptr); }
+    void addReset(ResetSensitivity *);
 
     ScEvent timeoutEvent;
     void setTimeout(::sc_core::sc_time t);
@@ -119,13 +122,15 @@ class Process : public ::sc_core::sc_process_b, public ListNode
     bool hasStaticSensitivities() { return !staticSensitivities.empty(); }
     bool internal() { return _internal; }
     bool timedOut() { return _timedOut; }
-    bool syncReset() { return _syncReset; }
+    bool inReset() { return _syncReset || syncResetCount || asyncResetCount; }
 
     bool dontInitialize() { return _dontInitialize; }
     void dontInitialize(bool di) { _dontInitialize = di; }
 
     void joinWait(::sc_core::sc_join *join) { joinWaiters.push_back(join); }
 
+    void waitCount(int count) { _waitCount = count; }
+
   protected:
     void timeout();
 
@@ -170,12 +175,18 @@ class Process : public ::sc_core::sc_process_b, public ListNode
 
     bool _syncReset;
 
+    int syncResetCount;
+    int asyncResetCount;
+
+    int _waitCount;
+
     int refCount;
 
     size_t stackSize;
 
     StaticSensitivities staticSensitivities;
     DynamicSensitivity *dynamicSensitivity;
+    ResetSensitivities resetSensitivities;
 
     std::unique_ptr<::sc_core::sc_report> _lastReport;
 
index dfd89790c4648f9d83b6b03877dc67e378e19b95..d4ffda4e2917d85f5b61a0160d0c4fa7699fb0e9 100644 (file)
@@ -35,6 +35,7 @@
 #include "systemc/core/kernel.hh"
 #include "systemc/core/module.hh"
 #include "systemc/core/process_types.hh"
+#include "systemc/core/sensitivity.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"
@@ -244,52 +245,60 @@ sc_module::end_module()
 }
 
 void
-sc_module::reset_signal_is(const sc_in<bool> &, bool)
+sc_module::reset_signal_is(const sc_in<bool> &port, bool val)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    sc_gem5::newResetSensitivityPort(
+            ::sc_gem5::Process::newest(), &port, val, true);
 }
 
 void
-sc_module::reset_signal_is(const sc_inout<bool> &, bool)
+sc_module::reset_signal_is(const sc_inout<bool> &port, bool val)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    sc_gem5::newResetSensitivityPort(
+            ::sc_gem5::Process::newest(), &port, val, true);
 }
 
 void
-sc_module::reset_signal_is(const sc_out<bool> &, bool)
+sc_module::reset_signal_is(const sc_out<bool> &port, bool val)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    sc_gem5::newResetSensitivityPort(
+            ::sc_gem5::Process::newest(), &port, val, true);
 }
 
 void
-sc_module::reset_signal_is(const sc_signal_in_if<bool> &, bool)
+sc_module::reset_signal_is(const sc_signal_in_if<bool> &signal, bool val)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    sc_gem5::newResetSensitivitySignal(
+            ::sc_gem5::Process::newest(), &signal, val, true);
 }
 
 
 void
-sc_module::async_reset_signal_is(const sc_in<bool> &, bool)
+sc_module::async_reset_signal_is(const sc_in<bool> &port, bool val)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    sc_gem5::newResetSensitivityPort(
+            ::sc_gem5::Process::newest(), &port, val, false);
 }
 
 void
-sc_module::async_reset_signal_is(const sc_inout<bool> &, bool)
+sc_module::async_reset_signal_is(const sc_inout<bool> &port, bool val)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    sc_gem5::newResetSensitivityPort(
+            ::sc_gem5::Process::newest(), &port, val, false);
 }
 
 void
-sc_module::async_reset_signal_is(const sc_out<bool> &, bool)
+sc_module::async_reset_signal_is(const sc_out<bool> &port, bool val)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    sc_gem5::newResetSensitivityPort(
+            ::sc_gem5::Process::newest(), &port, val, false);
 }
 
 void
-sc_module::async_reset_signal_is(const sc_signal_in_if<bool> &, bool)
+sc_module::async_reset_signal_is(const sc_signal_in_if<bool> &signal, bool val)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    sc_gem5::newResetSensitivitySignal(
+            ::sc_gem5::Process::newest(), &signal, val, false);
 }
 
 
@@ -626,8 +635,9 @@ wait(int n)
         std::string msg = csprintf("n = %d", n);
         SC_REPORT_ERROR("(E525) wait(n) is only valid for n > 0", msg.c_str());
     }
-    for (int i = 0; i < n; i++)
-        wait();
+    sc_gem5::Process *p = sc_gem5::scheduler.current();
+    p->waitCount(n - 1);
+    wait();
 }
 
 void
index 8c936bfe9189526fbae115223ad2cea6e509958f..4618ea8c243b6b84e5e4b5637ea5fd090e5a9f4a 100644 (file)
@@ -83,6 +83,18 @@ spawnWork(ProcessFuncWrapper *func, const char *name,
 
         for (auto f: opts->_finders)
             newStaticSensitivityFinder(proc, f);
+
+        for (auto p: opts->_in_resets)
+            newResetSensitivityPort(proc, p.target, p.value, p.sync);
+
+        for (auto p: opts->_inout_resets)
+            newResetSensitivityPort(proc, p.target, p.value, p.sync);
+
+        for (auto p: opts->_out_resets)
+            newResetSensitivityPort(proc, p.target, p.value, p.sync);
+
+        for (auto i: opts->_if_resets)
+            newResetSensitivitySignal(proc, i.target, i.value, i.sync);
     }
 
     if (opts && opts->_dontInitialize &&
@@ -161,59 +173,54 @@ sc_spawn_options::set_sensitivity(sc_event_finder *f)
 
 
 void
-sc_spawn_options::reset_signal_is(const sc_in<bool> &, bool)
+sc_spawn_options::reset_signal_is(const sc_in<bool> &port, bool value)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    _in_resets.emplace_back(&port, value, true);
 }
 
 void
-sc_spawn_options::reset_signal_is(const sc_inout<bool> &, bool)
+sc_spawn_options::reset_signal_is(const sc_inout<bool> &port, bool value)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    _inout_resets.emplace_back(&port, value, true);
 }
 
 void
-sc_spawn_options::reset_signal_is(const sc_out<bool> &, bool)
+sc_spawn_options::reset_signal_is(const sc_out<bool> &port, bool value)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    _out_resets.emplace_back(&port, value, true);
 }
 
 void
-sc_spawn_options::reset_signal_is(const sc_signal_in_if<bool> &, bool)
+sc_spawn_options::reset_signal_is(
+        const sc_signal_in_if<bool> &iface, bool value)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    _if_resets.emplace_back(&iface, value, true);
 }
 
 
 void
-sc_spawn_options::async_reset_signal_is(const sc_in<bool> &, bool)
+sc_spawn_options::async_reset_signal_is(const sc_in<bool> &port, bool value)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    _in_resets.emplace_back(&port, value, false);
 }
 
 void
-sc_spawn_options::async_reset_signal_is(const sc_inout<bool> &, bool)
+sc_spawn_options::async_reset_signal_is(const sc_inout<bool> &port, bool value)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    _inout_resets.emplace_back(&port, value, false);
 }
 
 void
-sc_spawn_options::async_reset_signal_is(const sc_out<bool> &, bool)
+sc_spawn_options::async_reset_signal_is(const sc_out<bool> &port, bool value)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    _out_resets.emplace_back(&port, value, false);
 }
 
 void
-sc_spawn_options::async_reset_signal_is(const sc_signal_in_if<bool> &, bool)
-{
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-}
-
-
-void
-sc_spawn_warn_unimpl(const char *func)
+sc_spawn_options::async_reset_signal_is(
+        const sc_signal_in_if<bool> &iface, bool value)
 {
-    warn("%s not implemented.\n", func);
+    _if_resets.emplace_back(&iface, value, false);
 }
 
 } // namespace sc_core
index 6d571f60b765db6db0b22d6ecafdb1ce839bded1..fe1d7c2e4bf6cc8a6b7e71a42804423ed43c179d 100644 (file)
@@ -183,7 +183,7 @@ Scheduler::yield()
             auto ew = _current->excWrapper;
             _current->excWrapper = nullptr;
             ew->throw_it();
-        } else if (_current->syncReset()) {
+        } else if (_current->inReset()) {
             _current->reset(false);
         }
     }
index 0d853f5c68f9d48005ba8598d9cc19dfaa5e52a1..de9d627c163ee3befbd5196356486ea6d7dd7249 100644 (file)
@@ -209,6 +209,17 @@ class Scheduler
         yield();
     }
 
+    // Run this process at the next opportunity.
+    void
+    runNext(Process *p)
+    {
+        // Like above, it's ok if this isn't a method. Putting it on this list
+        // just gives it priority.
+        readyListMethods.pushFirst(p);
+        if (!inEvaluate())
+            scheduleReadyEvent();
+    }
+
     // Set an event queue for scheduling events.
     void setEventQueue(EventQueue *_eq) { eq = _eq; }
 
index 2bd0b5fcb50b959379eb2d95e796f6ff04baa137..b0709ee9188afb9356e631c5b318c707894596a3 100644 (file)
@@ -33,6 +33,9 @@
 #include "systemc/core/port.hh"
 #include "systemc/core/process.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/core/sc_export.hh"
 #include "systemc/ext/core/sc_interface.hh"
 #include "systemc/ext/core/sc_port.hh"
@@ -93,6 +96,18 @@ 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.
@@ -228,4 +243,71 @@ DynamicSensitivityEventAndList::notifyWork(Event *e)
     return true;
 }
 
+/*
+ * Reset sensitivities.
+ */
+
+void
+newResetSensitivitySignal(
+        Process *p, const sc_core::sc_signal_in_if<bool> *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<bool> *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<bool> *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<bool> *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<bool> *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::notifyWork(Event *e)
+{
+    process->signalReset(_signal->read() == val(), sync());
+    return true;
+}
+
+void
+ResetSensitivityPort::setSignal(const ::sc_core::sc_signal_in_if<bool> *signal)
+{
+    _signal = signal;
+    event = &_signal->value_changed_event();
+    addToEvent(event);
+    if (signal->read() == val())
+        process->signalReset(true, sync());
+}
+
 } // namespace sc_gem5
index a412c7a63f163c05a2cffb28677f74e71a000514..0e2f4919d63fce62fe68678afcf20be3da41ac77 100644 (file)
@@ -36,6 +36,7 @@
 #include "sim/eventq.hh"
 #include "systemc/core/sched_event.hh"
 #include "systemc/ext/core/sc_module.hh"
+#include "systemc/ext/core/sc_port.hh"
 
 namespace sc_core
 {
@@ -84,14 +85,21 @@ class Sensitivity
     void satisfy();
     bool notify(Event *e);
 
-    virtual bool dynamic() = 0;
+    enum Category
+    {
+        Static,
+        Dynamic,
+        Reset
+    };
+
+    virtual Category category() = 0;
 
     bool ofMethod();
 };
 
 
 /*
- * Dynamic vs. static sensitivity.
+ * Dynamic vs. static vs. reset sensitivity.
  */
 
 class DynamicSensitivity : virtual public Sensitivity
@@ -103,7 +111,7 @@ class DynamicSensitivity : virtual public Sensitivity
     void delFromEvent(const ::sc_core::sc_event *e) override;
 
   public:
-    bool dynamic() override { return true; }
+    Category category() override { return Dynamic; }
 };
 
 typedef std::vector<DynamicSensitivity *> DynamicSensitivities;
@@ -118,11 +126,34 @@ class StaticSensitivity : virtual public Sensitivity
     void delFromEvent(const ::sc_core::sc_event *e) override;
 
   public:
-    bool dynamic() override { return false; }
+    Category category() override { return Static; }
 };
 
 typedef std::vector<StaticSensitivity *> 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<ResetSensitivity *> ResetSensitivities;
+
 
 /*
  * Sensitivity to an event or events, which can be static or dynamic.
@@ -295,6 +326,60 @@ class DynamicSensitivityEventAndList :
     bool notifyWork(Event *e) override;
 };
 
+/*
+ * Reset sensitivities.
+ */
+
+void newResetSensitivitySignal(
+        Process *p, const sc_core::sc_signal_in_if<bool> *signal,
+        bool val, bool sync);
+
+void newResetSensitivityPort(
+        Process *p, const sc_core::sc_in<bool> *port, bool val, bool sync);
+void newResetSensitivityPort(
+        Process *p, const sc_core::sc_inout<bool> *port, bool val, bool sync);
+void newResetSensitivityPort(
+        Process *p, const sc_core::sc_out<bool> *port, bool val, bool sync);
+
+class ResetSensitivitySignal :
+    public ResetSensitivity, public SensitivityEvent
+{
+  protected:
+    const sc_core::sc_signal_in_if<bool> *_signal;
+
+    friend void newResetSensitivitySignal(
+            Process *p, const sc_core::sc_signal_in_if<bool> *signal,
+            bool val, bool sync);
+
+    ResetSensitivitySignal(
+            Process *p, const sc_core::sc_signal_in_if<bool> *signal,
+            bool _val, bool _sync);
+
+    bool notifyWork(Event *e) override;
+};
+
+class ResetSensitivityPort : public ResetSensitivitySignal
+{
+  private:
+    friend void newResetSensitivityPort(
+            Process *p, const sc_core::sc_in<bool> *port, bool val, bool sync);
+    friend void newResetSensitivityPort(
+            Process *p, const sc_core::sc_inout<bool> *port,
+            bool val, bool sync);
+    friend void newResetSensitivityPort(
+            Process *p, const sc_core::sc_out<bool> *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<bool> *signal);
+};
+
 } // namespace sc_gem5
 
 #endif  //__SYSTEMC_CORE_SENSITIVITY_HH__
index d97883035d53851473666c1cba1310a750aa42a6..50378e23da3e2575156f9d8e8184606807543d7b 100644 (file)
@@ -130,6 +130,21 @@ class sc_spawn_options
     std::vector<sc_interface *> _interfaces;
     std::vector<sc_event_finder *> _finders;
 
+    template <typename T>
+    struct Reset
+    {
+        Reset(T *t, bool v, bool s) : target(t), value(v), sync(s) {}
+
+        T *target;
+        bool value;
+        bool sync;
+    };
+
+    std::vector<Reset<const sc_in<bool> > > _in_resets;
+    std::vector<Reset<const sc_inout<bool> > > _inout_resets;
+    std::vector<Reset<const sc_out<bool> > > _out_resets;
+    std::vector<Reset<const sc_signal_in_if<bool> > > _if_resets;
+
     // Disabled
     sc_spawn_options(const sc_spawn_options &) {}
     sc_spawn_options &operator = (const sc_spawn_options &) { return *this; }