Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/13186

Change subject: systemc: Implement signal based resets.
......................................................................

systemc: Implement signal based resets.

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
---
M src/systemc/core/event.cc
M src/systemc/core/event.hh
M src/systemc/core/port.cc
M src/systemc/core/port.hh
M src/systemc/core/process.cc
M src/systemc/core/process.hh
M src/systemc/core/sc_module.cc
M src/systemc/core/sc_spawn.cc
M src/systemc/core/scheduler.cc
M src/systemc/core/scheduler.hh
M src/systemc/core/sensitivity.cc
M src/systemc/core/sensitivity.hh
M src/systemc/ext/core/sc_spawn.hh
13 files changed, 363 insertions(+), 52 deletions(-)



diff --git a/src/systemc/core/event.cc b/src/systemc/core/event.cc
index de2b634..480114f 100644
--- a/src/systemc/core/event.cc
+++ b/src/systemc/core/event.cc
@@ -155,6 +155,13 @@
 }

 void
+Event::notify(ResetSensitivities &senses)
+{
+    for (auto s: senses)
+        s->notify(this);
+}
+
+void
 Event::notify()
 {
     if (scheduler.inUpdate()) {
@@ -167,7 +174,7 @@
         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 2d620c9..ff72fd3 100644
--- a/src/systemc/core/event.hh
+++ b/src/systemc/core/event.hh
@@ -74,6 +74,7 @@

     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 @@
             }
         }
     }
+    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 @@
     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 af6ecd1..8ee0549 100644
--- a/src/systemc/core/port.cc
+++ b/src/systemc/core/port.cc
@@ -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
 {
@@ -49,6 +50,18 @@
 }

 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)
 {
     if (finalized)
@@ -67,6 +80,15 @@
 }

 void
+Port::sensitive(ResetSensitivityPort *reset)
+{
+    if (finalized)
+        finalizeReset(reset);
+    else
+        sensitivities.push_back(new Sensitivity(reset));
+}
+
+void
 Port::finalize()
 {
     if (finalized)
@@ -88,8 +110,10 @@
     for (auto &s: sensitivities) {
         if (s->port)
             finalizePort(s->port);
-        else
+        else if (s->finder)
             finalizeFinder(s->finder);
+        else
+            finalizeReset(s->reset);
         delete s;
     }

diff --git a/src/systemc/core/port.hh b/src/systemc/core/port.hh
index 217269d..eb8dbfe 100644
--- a/src/systemc/core/port.hh
+++ b/src/systemc/core/port.hh
@@ -42,6 +42,7 @@

 class StaticSensitivityPort;
 class StaticSensitivityFinder;
+class ResetSensitivityPort;

 class Port;

@@ -58,6 +59,7 @@

     void finalizePort(StaticSensitivityPort *port);
     void finalizeFinder(StaticSensitivityFinder *finder);
+    void finalizeReset(ResetSensitivityPort *reset);

     void
     addInterface(::sc_core::sc_interface *iface)
@@ -105,15 +107,20 @@
     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 @@

     void sensitive(StaticSensitivityPort *port);
     void sensitive(StaticSensitivityFinder *finder);
+    void sensitive(ResetSensitivityPort *reset);

     void finalize();

diff --git a/src/systemc/core/process.cc b/src/systemc/core/process.cc
index 45c01e9..78bbf91 100644
--- a/src/systemc/core/process.cc
+++ b/src/systemc/core/process.cc
@@ -236,6 +236,27 @@
 }

 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()
 {
     bool reset;
@@ -272,6 +293,12 @@
 }

 void
+Process::addReset(ResetSensitivity *s)
+{
+    resetSensitivities.push_back(s);
+}
+
+void
 Process::cancelTimeout()
 {
     if (timeoutEvent.scheduled())
@@ -302,6 +329,11 @@
 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 @@
     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 =
diff --git a/src/systemc/core/process.hh b/src/systemc/core/process.hh
index 9e85fc7..85a7a27 100644
--- a/src/systemc/core/process.hh
+++ b/src/systemc/core/process.hh
@@ -87,6 +87,8 @@
     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 @@
     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 @@
     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 @@

     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;

diff --git a/src/systemc/core/sc_module.cc b/src/systemc/core/sc_module.cc
index dfd8979..d4ffda4 100644
--- a/src/systemc/core/sc_module.cc
+++ b/src/systemc/core/sc_module.cc
@@ -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 @@
 }

 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 @@
         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
diff --git a/src/systemc/core/sc_spawn.cc b/src/systemc/core/sc_spawn.cc
index d2e6bd4..a751422 100644
--- a/src/systemc/core/sc_spawn.cc
+++ b/src/systemc/core/sc_spawn.cc
@@ -83,6 +83,18 @@

         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 @@


 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)
+sc_spawn_options::async_reset_signal_is(
+        const sc_signal_in_if<bool> &iface, bool value)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
-}
-
-
-void
-sc_spawn_warn_unimpl(const char *func)
-{
-    warn("%s not implemented.\n", func);
+    _if_resets.emplace_back(&iface, value, false);
 }

 } // namespace sc_core
diff --git a/src/systemc/core/scheduler.cc b/src/systemc/core/scheduler.cc
index 6d571f6..fe1d7c2 100644
--- a/src/systemc/core/scheduler.cc
+++ b/src/systemc/core/scheduler.cc
@@ -183,7 +183,7 @@
             auto ew = _current->excWrapper;
             _current->excWrapper = nullptr;
             ew->throw_it();
-        } else if (_current->syncReset()) {
+        } else if (_current->inReset()) {
             _current->reset(false);
         }
     }
diff --git a/src/systemc/core/scheduler.hh b/src/systemc/core/scheduler.hh
index 0d853f5..de9d627 100644
--- a/src/systemc/core/scheduler.hh
+++ b/src/systemc/core/scheduler.hh
@@ -209,6 +209,17 @@
         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; }

diff --git a/src/systemc/core/sensitivity.cc b/src/systemc/core/sensitivity.cc
index 2bd0b5f..b0709ee 100644
--- a/src/systemc/core/sensitivity.cc
+++ b/src/systemc/core/sensitivity.cc
@@ -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 @@
     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 @@
     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
diff --git a/src/systemc/core/sensitivity.hh b/src/systemc/core/sensitivity.hh
index a412c7a..0e2f491 100644
--- a/src/systemc/core/sensitivity.hh
+++ b/src/systemc/core/sensitivity.hh
@@ -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 @@
     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 @@
     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 @@
     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 @@
     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__
diff --git a/src/systemc/ext/core/sc_spawn.hh b/src/systemc/ext/core/sc_spawn.hh
index d978830..50378e2 100644
--- a/src/systemc/ext/core/sc_spawn.hh
+++ b/src/systemc/ext/core/sc_spawn.hh
@@ -130,6 +130,21 @@
     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; }

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/13186
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: I92f8e9a128e6618af94dc048ce570a4436e17e4b
Gerrit-Change-Number: 13186
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to