summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/systemc/core/SConscript1
-rw-r--r--src/systemc/core/kernel.cc14
-rw-r--r--src/systemc/core/module.cc8
-rw-r--r--src/systemc/core/port.cc (renamed from src/systemc/core/bindinfo.hh)78
-rw-r--r--src/systemc/core/port.hh150
-rw-r--r--src/systemc/core/process.cc9
-rw-r--r--src/systemc/core/process.hh3
-rw-r--r--src/systemc/core/sc_module.cc24
-rw-r--r--src/systemc/core/sc_port.cc50
-rw-r--r--src/systemc/core/sc_sensitive.cc12
-rw-r--r--src/systemc/core/sc_spawn.cc10
-rw-r--r--src/systemc/core/scheduler.cc3
-rw-r--r--src/systemc/core/sensitivity.cc154
-rw-r--r--src/systemc/core/sensitivity.hh151
-rw-r--r--src/systemc/ext/core/sc_port.hh16
15 files changed, 442 insertions, 241 deletions
diff --git a/src/systemc/core/SConscript b/src/systemc/core/SConscript
index 1d291ef4d..0aa59944d 100644
--- a/src/systemc/core/SConscript
+++ b/src/systemc/core/SConscript
@@ -35,6 +35,7 @@ if env['USE_SYSTEMC']:
Source('kernel.cc')
Source('module.cc')
Source('object.cc')
+ Source('port.cc')
Source('process.cc')
Source('process_types.cc')
Source('python.cc')
diff --git a/src/systemc/core/kernel.cc b/src/systemc/core/kernel.cc
index ca99e1932..ff8e24e6a 100644
--- a/src/systemc/core/kernel.cc
+++ b/src/systemc/core/kernel.cc
@@ -32,6 +32,7 @@
#include "base/logging.hh"
#include "systemc/core/channel.hh"
#include "systemc/core/module.hh"
+#include "systemc/core/port.hh"
#include "systemc/core/scheduler.hh"
namespace sc_gem5
@@ -75,6 +76,8 @@ Kernel::init()
fatal("Simulation called sc_stop during elaboration.\n");
status(::sc_core::SC_BEFORE_END_OF_ELABORATION);
+ for (auto p: allPorts)
+ p->sc_port_base()->before_end_of_elaboration();
for (auto m: sc_gem5::allModules)
m->beforeEndOfElaboration();
for (auto c: sc_gem5::allChannels)
@@ -88,11 +91,12 @@ Kernel::regStats()
return;
try {
- for (auto m: sc_gem5::allModules)
- for (auto p: m->ports)
- p->_gem5Finalize();
+ for (auto p: allPorts)
+ p->finalize();
status(::sc_core::SC_END_OF_ELABORATION);
+ for (auto p: allPorts)
+ p->sc_port_base()->end_of_elaboration();
for (auto m: sc_gem5::allModules)
m->endOfElaboration();
for (auto c: sc_gem5::allChannels)
@@ -117,6 +121,8 @@ Kernel::startup()
try {
status(::sc_core::SC_START_OF_SIMULATION);
+ for (auto p: allPorts)
+ p->sc_port_base()->start_of_simulation();
for (auto m: sc_gem5::allModules)
m->startOfSimulation();
for (auto c: sc_gem5::allChannels)
@@ -147,6 +153,8 @@ Kernel::stopWork()
{
status(::sc_core::SC_END_OF_SIMULATION);
try {
+ for (auto p: allPorts)
+ p->sc_port_base()->end_of_simulation();
for (auto m: sc_gem5::allModules)
m->endOfSimulation();
for (auto c: sc_gem5::allChannels)
diff --git a/src/systemc/core/module.cc b/src/systemc/core/module.cc
index dcd6faa53..afc3bf241 100644
--- a/src/systemc/core/module.cc
+++ b/src/systemc/core/module.cc
@@ -113,8 +113,6 @@ Module::beforeEndOfElaboration()
{
callbackModule(this);
_sc_mod->before_end_of_elaboration();
- for (auto p: ports)
- p->before_end_of_elaboration();
for (auto e: exports)
e->before_end_of_elaboration();
callbackModule(nullptr);
@@ -131,8 +129,6 @@ Module::endOfElaboration()
}
callbackModule(this);
_sc_mod->end_of_elaboration();
- for (auto p: ports)
- p->end_of_elaboration();
for (auto e: exports)
e->end_of_elaboration();
callbackModule(nullptr);
@@ -143,8 +139,6 @@ Module::startOfSimulation()
{
callbackModule(this);
_sc_mod->start_of_simulation();
- for (auto p: ports)
- p->start_of_simulation();
for (auto e: exports)
e->start_of_simulation();
callbackModule(nullptr);
@@ -155,8 +149,6 @@ Module::endOfSimulation()
{
callbackModule(this);
_sc_mod->end_of_simulation();
- for (auto p: ports)
- p->end_of_simulation();
for (auto e: exports)
e->end_of_simulation();
callbackModule(nullptr);
diff --git a/src/systemc/core/bindinfo.hh b/src/systemc/core/port.cc
index 9e636a696..af6ecd125 100644
--- a/src/systemc/core/bindinfo.hh
+++ b/src/systemc/core/port.cc
@@ -27,29 +27,75 @@
* Authors: Gabe Black
*/
-#ifndef __SYSTEMC_CORE_BINDINFO_HH__
-#define __SYSTEMC_CORE_BINDINFO_HH__
+#include "systemc/core/port.hh"
-#include "systemc/ext/core/sc_interface.hh"
+#include "systemc/core/sensitivity.hh"
namespace sc_gem5
{
-class BindInfo
+void
+Port::finalizePort(StaticSensitivityPort *port)
{
- public:
- BindInfo(::sc_core::sc_interface *interface) :
- interface(interface), port(nullptr)
- {}
+ for (int i = 0; i < size(); i++)
+ port->addEvent(&getInterface(i)->default_event());
+}
- BindInfo(::sc_core::sc_port_base *port) :
- interface(nullptr), port(port)
- {}
+void
+Port::finalizeFinder(StaticSensitivityFinder *finder)
+{
+ for (int i = 0; i < size(); i++)
+ finder->addEvent(&finder->find(getInterface(i)));
+}
- ::sc_core::sc_interface *interface;
- ::sc_core::sc_port_base *port;
-};
+void
+Port::sensitive(StaticSensitivityPort *port)
+{
+ if (finalized)
+ finalizePort(port);
+ else
+ sensitivities.push_back(new Sensitivity(port));
+}
-} // namespace sc_gem5
+void
+Port::sensitive(StaticSensitivityFinder *finder)
+{
+ if (finalized)
+ finalizeFinder(finder);
+ else
+ sensitivities.push_back(new Sensitivity(finder));
+}
+
+void
+Port::finalize()
+{
+ if (finalized)
+ return;
+ finalized = true;
-#endif // __SYSTEMC_CORE_BINDINFO_HH__
+ for (auto &b: bindings) {
+ if (b->interface) {
+ addInterface(b->interface);
+ } else {
+ b->port->_gem5Port->finalize();
+ addInterfaces(b->port);
+ }
+ delete b;
+ }
+
+ bindings.clear();
+
+ for (auto &s: sensitivities) {
+ if (s->port)
+ finalizePort(s->port);
+ else
+ finalizeFinder(s->finder);
+ delete s;
+ }
+
+ sensitivities.clear();
+}
+
+std::list<Port *> allPorts;
+
+} // namespace sc_gem5
diff --git a/src/systemc/core/port.hh b/src/systemc/core/port.hh
new file mode 100644
index 000000000..15e7bbed1
--- /dev/null
+++ b/src/systemc/core/port.hh
@@ -0,0 +1,150 @@
+/*
+ * 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_CORE_PORT_HH__
+#define __SYSTEMC_CORE_PORT_HH__
+
+#include <list>
+#include <vector>
+
+#include "systemc/ext/core/sc_interface.hh"
+#include "systemc/ext/core/sc_port.hh"
+
+namespace sc_gem5
+{
+
+class StaticSensitivityPort;
+class StaticSensitivityFinder;
+
+class Port;
+
+extern std::list<Port *> allPorts;
+
+class Port
+{
+ private:
+ ::sc_core::sc_port_base *portBase;
+
+ bool finalized;
+ int _maxSize;
+ int _size;
+
+ void finalizePort(StaticSensitivityPort *port);
+ void finalizeFinder(StaticSensitivityFinder *finder);
+
+ void
+ addInterface(::sc_core::sc_interface *i)
+ {
+ _size++;
+ portBase->_gem5AddInterface(i);
+ }
+
+ void
+ addInterfaces(::sc_core::sc_port_base *pb)
+ {
+ for (int i = 0; i < pb->size(); i++)
+ addInterface(pb->_gem5Interface(i));
+ }
+
+ ::sc_core::sc_interface *
+ getInterface(int i)
+ {
+ return portBase->_gem5Interface(i);
+ }
+
+ struct Binding
+ {
+ explicit Binding(::sc_core::sc_interface *interface) :
+ interface(interface), port(nullptr)
+ {}
+
+ explicit Binding(::sc_core::sc_port_base *port) :
+ interface(nullptr), port(port)
+ {}
+
+ ::sc_core::sc_interface *interface;
+ ::sc_core::sc_port_base *port;
+ };
+
+ struct Sensitivity
+ {
+ Sensitivity(StaticSensitivityPort *port) :
+ port(port), finder(nullptr)
+ {}
+
+ Sensitivity(StaticSensitivityFinder *finder) :
+ port(nullptr), finder(finder)
+ {}
+
+ StaticSensitivityPort *port;
+ StaticSensitivityFinder *finder;
+ };
+
+ std::vector<Binding *> bindings;
+ std::vector<Sensitivity *> sensitivities;
+
+ public:
+ static Port *
+ fromPort(const ::sc_core::sc_port_base *pb)
+ {
+ return pb->_gem5Port;
+ }
+
+ ::sc_core::sc_port_base *sc_port_base() { return portBase; }
+
+ Port(::sc_core::sc_port_base *port_base, int max) :
+ portBase(port_base), finalized(false), _maxSize(max), _size(0)
+ {
+ allPorts.push_front(this);
+ }
+
+ void
+ bind(::sc_core::sc_interface *interface)
+ {
+ bindings.push_back(new Binding(interface));
+ }
+
+ void
+ bind(::sc_core::sc_port_base *port)
+ {
+ bindings.push_back(new Binding(port));
+ }
+
+ void sensitive(StaticSensitivityPort *port);
+ void sensitive(StaticSensitivityFinder *finder);
+
+ void finalize();
+
+ int size() { return _size; }
+ int maxSize() { return _maxSize; }
+};
+
+} // namespace sc_gem5
+
+#endif // __SYSTEMC_CORE_PORT_HH__
diff --git a/src/systemc/core/process.cc b/src/systemc/core/process.cc
index e977713f4..45c01e916 100644
--- a/src/systemc/core/process.cc
+++ b/src/systemc/core/process.cc
@@ -236,13 +236,6 @@ Process::syncResetOff(bool inc_kids)
}
void
-Process::finalize()
-{
- for (auto s: staticSensitivities)
- s->finalize();
-};
-
-void
Process::run()
{
bool reset;
@@ -276,8 +269,6 @@ Process::setDynamic(DynamicSensitivity *s)
delete dynamicSensitivity;
}
dynamicSensitivity = s;
- if (dynamicSensitivity)
- dynamicSensitivity->finalize();
}
void
diff --git a/src/systemc/core/process.hh b/src/systemc/core/process.hh
index 0a312e28e..4266c2d7d 100644
--- a/src/systemc/core/process.hh
+++ b/src/systemc/core/process.hh
@@ -35,7 +35,6 @@
#include <vector>
#include "base/fiber.hh"
-#include "systemc/core/bindinfo.hh"
#include "systemc/core/list.hh"
#include "systemc/core/object.hh"
#include "systemc/core/sched_event.hh"
@@ -96,8 +95,6 @@ class Process : public ::sc_core::sc_process_b, public ListNode
void setStackSize(size_t size) { stackSize = size; }
- void finalize();
-
void run();
void addStatic(StaticSensitivity *);
diff --git a/src/systemc/core/sc_module.cc b/src/systemc/core/sc_module.cc
index 3e900f658..32d1c979a 100644
--- a/src/systemc/core/sc_module.cc
+++ b/src/systemc/core/sc_module.cc
@@ -505,7 +505,7 @@ next_trigger(const sc_event &e)
{
sc_gem5::Process *p = sc_gem5::scheduler.current();
p->cancelTimeout();
- p->setDynamic(new ::sc_gem5::DynamicSensitivityEvent(p, &e));
+ ::sc_gem5::newDynamicSensitivityEvent(p, &e);
}
void
@@ -513,7 +513,7 @@ next_trigger(const sc_event_or_list &eol)
{
sc_gem5::Process *p = sc_gem5::scheduler.current();
p->cancelTimeout();
- p->setDynamic(new ::sc_gem5::DynamicSensitivityEventOrList(p, &eol));
+ ::sc_gem5::newDynamicSensitivityEventOrList(p, &eol);
}
void
@@ -521,7 +521,7 @@ next_trigger(const sc_event_and_list &eal)
{
sc_gem5::Process *p = sc_gem5::scheduler.current();
p->cancelTimeout();
- p->setDynamic(new ::sc_gem5::DynamicSensitivityEventAndList(p, &eal));
+ ::sc_gem5::newDynamicSensitivityEventAndList(p, &eal);
}
void
@@ -543,7 +543,7 @@ next_trigger(const sc_time &t, const sc_event &e)
{
sc_gem5::Process *p = sc_gem5::scheduler.current();
p->setTimeout(t);
- p->setDynamic(new ::sc_gem5::DynamicSensitivityEvent(p, &e));
+ ::sc_gem5::newDynamicSensitivityEvent(p, &e);
}
void
@@ -557,7 +557,7 @@ next_trigger(const sc_time &t, const sc_event_or_list &eol)
{
sc_gem5::Process *p = sc_gem5::scheduler.current();
p->setTimeout(t);
- p->setDynamic(new ::sc_gem5::DynamicSensitivityEventOrList(p, &eol));
+ ::sc_gem5::newDynamicSensitivityEventOrList(p, &eol);
}
void
@@ -571,7 +571,7 @@ next_trigger(const sc_time &t, const sc_event_and_list &eal)
{
sc_gem5::Process *p = sc_gem5::scheduler.current();
p->setTimeout(t);
- p->setDynamic(new ::sc_gem5::DynamicSensitivityEventAndList(p, &eal));
+ ::sc_gem5::newDynamicSensitivityEventAndList(p, &eal);
}
void
@@ -616,7 +616,7 @@ wait(const sc_event &e)
{
sc_gem5::Process *p = sc_gem5::scheduler.current();
p->cancelTimeout();
- p->setDynamic(new ::sc_gem5::DynamicSensitivityEvent(p, &e));
+ ::sc_gem5::newDynamicSensitivityEvent(p, &e);
sc_gem5::scheduler.yield();
}
@@ -625,7 +625,7 @@ wait(const sc_event_or_list &eol)
{
sc_gem5::Process *p = sc_gem5::scheduler.current();
p->cancelTimeout();
- p->setDynamic(new ::sc_gem5::DynamicSensitivityEventOrList(p, &eol));
+ ::sc_gem5::newDynamicSensitivityEventOrList(p, &eol);
sc_gem5::scheduler.yield();
}
@@ -634,7 +634,7 @@ wait(const sc_event_and_list &eal)
{
sc_gem5::Process *p = sc_gem5::scheduler.current();
p->cancelTimeout();
- p->setDynamic(new ::sc_gem5::DynamicSensitivityEventAndList(p, &eal));
+ ::sc_gem5::newDynamicSensitivityEventAndList(p, &eal);
sc_gem5::scheduler.yield();
}
@@ -658,7 +658,7 @@ wait(const sc_time &t, const sc_event &e)
{
sc_gem5::Process *p = sc_gem5::scheduler.current();
p->setTimeout(t);
- p->setDynamic(new ::sc_gem5::DynamicSensitivityEvent(p, &e));
+ ::sc_gem5::newDynamicSensitivityEvent(p, &e);
sc_gem5::scheduler.yield();
}
@@ -673,7 +673,7 @@ wait(const sc_time &t, const sc_event_or_list &eol)
{
sc_gem5::Process *p = sc_gem5::scheduler.current();
p->setTimeout(t);
- p->setDynamic(new ::sc_gem5::DynamicSensitivityEventOrList(p, &eol));
+ ::sc_gem5::newDynamicSensitivityEventOrList(p, &eol);
sc_gem5::scheduler.yield();
}
@@ -688,7 +688,7 @@ wait(const sc_time &t, const sc_event_and_list &eal)
{
sc_gem5::Process *p = sc_gem5::scheduler.current();
p->setTimeout(t);
- p->setDynamic(new ::sc_gem5::DynamicSensitivityEventAndList(p, &eal));
+ ::sc_gem5::newDynamicSensitivityEventAndList(p, &eal);
sc_gem5::scheduler.yield();
}
diff --git a/src/systemc/core/sc_port.cc b/src/systemc/core/sc_port.cc
index c822e966e..52f66b70d 100644
--- a/src/systemc/core/sc_port.cc
+++ b/src/systemc/core/sc_port.cc
@@ -28,8 +28,8 @@
*/
#include "base/logging.hh"
-#include "systemc/core/bindinfo.hh"
#include "systemc/core/module.hh"
+#include "systemc/core/port.hh"
#include "systemc/core/scheduler.hh"
#include "systemc/ext/core/sc_main.hh"
#include "systemc/ext/core/sc_port.hh"
@@ -56,7 +56,7 @@ reportError(const char *id, const char *add_msg,
}
sc_port_base::sc_port_base(const char *name, int n, sc_port_policy p) :
- sc_object(name), _maxSize(n), _size(0), finalized(false)
+ sc_object(name), _gem5Port(new ::sc_gem5::Port(this, n))
{
if (sc_is_running()) {
reportError("(E110) insert port failed", "simulation running",
@@ -76,51 +76,21 @@ sc_port_base::sc_port_base(const char *name, int n, sc_port_policy p) :
}
}
-void
-sc_port_base::warn_unimpl(const char *func) const
-{
- warn("%s not implemented.\n", func);
-}
-
-int sc_port_base::maxSize() const { return _maxSize; }
-int sc_port_base::size() const { return _size; }
-
-void
-sc_port_base::bind(sc_interface &i)
+sc_port_base::~sc_port_base()
{
- _gem5BindInfo.push_back(new ::sc_gem5::BindInfo(&i));
+ delete _gem5Port;
}
void
-sc_port_base::bind(sc_port_base &p)
+sc_port_base::warn_unimpl(const char *func) const
{
- _gem5BindInfo.push_back(new ::sc_gem5::BindInfo(&p));
+ warn("%s not implemented.\n", func);
}
-void
-sc_port_base::_gem5Finalize()
-{
- if (finalized)
- return;
- finalized = true;
+int sc_port_base::maxSize() const { return _gem5Port->maxSize(); }
+int sc_port_base::size() const { return _gem5Port->size(); }
- for (auto &bi: _gem5BindInfo) {
- if (bi->interface) {
- _size++;
- _gem5AddInterface(bi->interface);
- } else {
- sc_port_base *port = bi->port;
- port->_gem5Finalize();
- int size = port->size();
- for (int i = 0; i < size; i++) {
- _size++;
- _gem5AddInterface(port->_gem5Interface(i));
- }
- }
- delete bi;
- }
-
- _gem5BindInfo.clear();
-}
+void sc_port_base::bind(sc_interface &i) { _gem5Port->bind(&i); }
+void sc_port_base::bind(sc_port_base &p) { _gem5Port->bind(&p); }
} // namespace sc_core
diff --git a/src/systemc/core/sc_sensitive.cc b/src/systemc/core/sc_sensitive.cc
index 93b460a4b..b254f6861 100644
--- a/src/systemc/core/sc_sensitive.cc
+++ b/src/systemc/core/sc_sensitive.cc
@@ -40,32 +40,28 @@ sc_sensitive::sc_sensitive() : currentProcess(nullptr) {}
sc_sensitive &
sc_sensitive::operator << (const sc_event &e)
{
- currentProcess->addStatic(
- new sc_gem5::StaticSensitivityEvent(currentProcess, &e));
+ sc_gem5::newStaticSensitivityEvent(currentProcess, &e);
return *this;
}
sc_sensitive &
sc_sensitive::operator << (const sc_interface &i)
{
- currentProcess->addStatic(
- new sc_gem5::StaticSensitivityInterface(currentProcess, &i));
+ sc_gem5::newStaticSensitivityInterface(currentProcess, &i);
return *this;
}
sc_sensitive &
sc_sensitive::operator << (const sc_port_base &b)
{
- currentProcess->addStatic(
- new sc_gem5::StaticSensitivityPort(currentProcess, &b));
+ sc_gem5::newStaticSensitivityPort(currentProcess, &b);
return *this;
}
sc_sensitive &
sc_sensitive::operator << (sc_event_finder &f)
{
- currentProcess->addStatic(
- new sc_gem5::StaticSensitivityFinder(currentProcess, &f));
+ sc_gem5::newStaticSensitivityFinder(currentProcess, &f);
return *this;
}
diff --git a/src/systemc/core/sc_spawn.cc b/src/systemc/core/sc_spawn.cc
index 02f1fa6c9..8c936bfe9 100644
--- a/src/systemc/core/sc_spawn.cc
+++ b/src/systemc/core/sc_spawn.cc
@@ -70,19 +70,19 @@ spawnWork(ProcessFuncWrapper *func, const char *name,
if (opts) {
for (auto e: opts->_events)
- proc->addStatic(new StaticSensitivityEvent(proc, e));
+ newStaticSensitivityEvent(proc, e);
for (auto p: opts->_ports)
- proc->addStatic(new StaticSensitivityPort(proc, p));
+ newStaticSensitivityPort(proc, p);
for (auto e: opts->_exports)
- proc->addStatic(new StaticSensitivityExport(proc, e));
+ newStaticSensitivityExport(proc, e);
for (auto i: opts->_interfaces)
- proc->addStatic(new StaticSensitivityInterface(proc, i));
+ newStaticSensitivityInterface(proc, i);
for (auto f: opts->_finders)
- proc->addStatic(new StaticSensitivityFinder(proc, f));
+ newStaticSensitivityFinder(proc, f);
}
if (opts && opts->_dontInitialize &&
diff --git a/src/systemc/core/scheduler.cc b/src/systemc/core/scheduler.cc
index a0695a395..8a796bb5b 100644
--- a/src/systemc/core/scheduler.cc
+++ b/src/systemc/core/scheduler.cc
@@ -104,7 +104,6 @@ void
Scheduler::initPhase()
{
for (Process *p = initList.getNext(); p; p = initList.getNext()) {
- p->finalize();
p->popListNode();
if (p->dontInitialize()) {
@@ -141,8 +140,6 @@ void
Scheduler::reg(Process *p)
{
if (initDone) {
- // If we're past initialization, finalize static sensitivity.
- p->finalize();
// If not marked as dontInitialize, mark as ready.
if (!p->dontInitialize())
p->ready();
diff --git a/src/systemc/core/sensitivity.cc b/src/systemc/core/sensitivity.cc
index 77aacb56a..740090cd9 100644
--- a/src/systemc/core/sensitivity.cc
+++ b/src/systemc/core/sensitivity.cc
@@ -30,6 +30,7 @@
#include "systemc/core/sensitivity.hh"
#include "systemc/core/event.hh"
+#include "systemc/core/port.hh"
#include "systemc/core/scheduler.hh"
#include "systemc/ext/core/sc_export.hh"
#include "systemc/ext/core/sc_interface.hh"
@@ -38,6 +39,10 @@
namespace sc_gem5
{
+/*
+ * Common sensitivity interface.
+ */
+
void
Sensitivity::satisfy()
{
@@ -53,6 +58,10 @@ Sensitivity::notify(Event *e)
}
+/*
+ * Dynamic vs. static sensitivity.
+ */
+
void
DynamicSensitivity::addToEvent(const ::sc_core::sc_event *e)
{
@@ -77,106 +86,139 @@ StaticSensitivity::delFromEvent(const ::sc_core::sc_event *e)
Event::getFromScEvent(e)->delSensitivity(this);
}
+
+/*
+ * Static sensitivities.
+ */
+
void
-StaticSensitivityInterface::finalize()
+newStaticSensitivityEvent(Process *p, const sc_core::sc_event *e)
{
- event = &interface->default_event();
- SensitivityEvent::finalize();
+ auto s = new StaticSensitivityEvent(p, e);
+ s->addToEvent(s->event);
+ p->addStatic(s);
}
void
-StaticSensitivityPort::finalize()
+newStaticSensitivityInterface(Process *p, const sc_core::sc_interface *i)
{
- for (int i = 0; i < port->size(); i++) {
- const ::sc_core::sc_event *event =
- &port->_gem5Interface(i)->default_event();
- events.insert(event);
- addToEvent(event);
- }
+ auto s = new StaticSensitivityInterface(p, i);
+ s->addToEvent(s->event);
+ p->addStatic(s);
}
void
-StaticSensitivityExport::finalize()
+newStaticSensitivityPort(Process *p, const sc_core::sc_port_base *pb)
{
- event = &exp->get_interface()->default_event();
- SensitivityEvent::finalize();
+ auto s = new StaticSensitivityPort(p);
+ Port *port = Port::fromPort(pb);
+ port->sensitive(s);
+ p->addStatic(s);
}
void
-StaticSensitivityFinder::finalize()
+newStaticSensitivityExport(Process *p, const sc_core::sc_export_base *exp)
{
- const ::sc_core::sc_port_base *port = finder->port();
- int size = port->size();
- for (int i = 0; i < size; i++) {
- ::sc_core::sc_interface *interface = port->_gem5Interface(i);
- const ::sc_core::sc_event *event = &finder->find_event(interface);
- events.insert(event);
- addToEvent(event);
- }
+ auto s = new StaticSensitivityExport(p, exp);
+ s->addToEvent(s->event);
+ p->addStatic(s);
}
-bool
-DynamicSensitivityEventOrList::notifyWork(Event *e)
+void
+newStaticSensitivityFinder(Process *p, const sc_core::sc_event_finder *f)
{
- events.erase(e->sc_event());
+ auto s = new StaticSensitivityFinder(p, f);
+ Port *port = Port::fromPort(f->port());
+ port->sensitive(s);
+ p->addStatic(s);
+}
- // All the other events need this deleted from their lists since this
- // sensitivity has been satisfied without them triggering.
- for (auto le: events)
- delFromEvent(le);
- satisfy();
- return true;
-}
+StaticSensitivityInterface::StaticSensitivityInterface(
+ Process *p, const sc_core::sc_interface *i) :
+ Sensitivity(p), StaticSensitivity(p),
+ SensitivityEvent(p, &i->default_event())
+{}
-DynamicSensitivityEventOrList::DynamicSensitivityEventOrList(
- Process *p, const sc_core::sc_event_or_list *eol) :
- Sensitivity(p), DynamicSensitivity(p), events(eol->events)
+StaticSensitivityExport::StaticSensitivityExport(
+ Process *p, const sc_core::sc_export_base *exp) :
+ Sensitivity(p), StaticSensitivity(p),
+ SensitivityEvent(p, &exp->get_interface()->default_event())
{}
+const ::sc_core::sc_event &
+StaticSensitivityFinder::find(::sc_core::sc_interface *i)
+{
+ return finder->find_event(i);
+}
+
+
+/*
+ * Dynamic sensitivities.
+ */
+
void
-DynamicSensitivityEventOrList::finalize()
+newDynamicSensitivityEvent(Process *p, const sc_core::sc_event *e)
{
- for (auto e: events)
- addToEvent(e);
+ auto s = new DynamicSensitivityEvent(p, e);
+ s->addToEvent(s->event);
+ p->setDynamic(s);
}
void
-DynamicSensitivityEventOrList::clear()
+newDynamicSensitivityEventOrList(
+ Process *p, const sc_core::sc_event_or_list *eol)
+{
+ auto s = new DynamicSensitivityEventOrList(p, eol);
+ for (auto event: s->events)
+ s->addToEvent(event);
+ p->setDynamic(s);
+}
+
+void newDynamicSensitivityEventAndList(
+ Process *p, const sc_core::sc_event_and_list *eal)
{
- for (auto e: events)
- delFromEvent(e);
+ auto s = new DynamicSensitivityEventAndList(p, eal);
+ for (auto event: s->events)
+ s->addToEvent(event);
+ p->setDynamic(s);
}
+
+DynamicSensitivityEventOrList::DynamicSensitivityEventOrList(
+ Process *p, const sc_core::sc_event_or_list *eol) :
+ Sensitivity(p), DynamicSensitivity(p), SensitivityEvents(p, eol->events)
+{}
+
bool
-DynamicSensitivityEventAndList::notifyWork(Event *e)
+DynamicSensitivityEventOrList::notifyWork(Event *e)
{
events.erase(e->sc_event());
- // This sensitivity is satisfied if all events have triggered.
- if (events.empty())
- satisfy();
+ // All the other events need this deleted from their lists since this
+ // sensitivity has been satisfied without them triggering.
+ for (auto le: events)
+ delFromEvent(le);
+ satisfy();
return true;
}
DynamicSensitivityEventAndList::DynamicSensitivityEventAndList(
Process *p, const sc_core::sc_event_and_list *eal) :
- Sensitivity(p), DynamicSensitivity(p), events(eal->events)
+ Sensitivity(p), DynamicSensitivity(p), SensitivityEvents(p, eal->events)
{}
-void
-DynamicSensitivityEventAndList::finalize()
+bool
+DynamicSensitivityEventAndList::notifyWork(Event *e)
{
- for (auto e: events)
- addToEvent(e);
-}
+ events.erase(e->sc_event());
-void
-DynamicSensitivityEventAndList::clear()
-{
- for (auto e: events)
- delFromEvent(e);
+ // This sensitivity is satisfied if all events have triggered.
+ if (events.empty())
+ satisfy();
+
+ return true;
}
} // namespace sc_gem5
diff --git a/src/systemc/core/sensitivity.hh b/src/systemc/core/sensitivity.hh
index f032630ec..b3f9a2e49 100644
--- a/src/systemc/core/sensitivity.hh
+++ b/src/systemc/core/sensitivity.hh
@@ -79,7 +79,6 @@ class Sensitivity
}
public:
- virtual void finalize() = 0;
virtual void clear() = 0;
void satisfy();
@@ -124,7 +123,7 @@ typedef std::vector<StaticSensitivity *> StaticSensitivities;
/*
- * Sensitivity to events, which can be static or dynamic.
+ * Sensitivity to an event or events, which can be static or dynamic.
*/
class SensitivityEvent : virtual public Sensitivity
@@ -137,19 +136,57 @@ class SensitivityEvent : virtual public Sensitivity
{}
public:
- void finalize() override { addToEvent(event); }
void clear() override { delFromEvent(event); }
};
+class SensitivityEvents : virtual public Sensitivity
+{
+ protected:
+ std::set<const ::sc_core::sc_event *> events;
+
+ SensitivityEvents(Process *p) : Sensitivity(p) {}
+ SensitivityEvents(
+ Process *p, const std::set<const ::sc_core::sc_event *> &s) :
+ Sensitivity(p), events(s)
+ {}
+
+ public:
+ void
+ clear() override
+ {
+ for (auto event: events)
+ delFromEvent(event);
+ }
+
+ void
+ addEvent(const ::sc_core::sc_event *event)
+ {
+ events.insert(event);
+ addToEvent(event);
+ }
+};
+
/*
* Static sensitivities.
*/
+void newStaticSensitivityEvent(Process *p, const sc_core::sc_event *e);
+void newStaticSensitivityInterface(Process *p, const sc_core::sc_interface *i);
+void newStaticSensitivityPort(Process *p, const sc_core::sc_port_base *pb);
+void newStaticSensitivityExport(
+ Process *p, const sc_core::sc_export_base *exp);
+void newStaticSensitivityFinder(
+ Process *p, const sc_core::sc_event_finder *f);
+
+
class StaticSensitivityEvent :
public StaticSensitivity, public SensitivityEvent
{
- public:
+ friend void newStaticSensitivityEvent(
+ Process *p, const sc_core::sc_event *e);
+
+ protected:
StaticSensitivityEvent(Process *p, const sc_core::sc_event *e) :
Sensitivity(p), StaticSensitivity(p), SensitivityEvent(p, e)
{}
@@ -158,71 +195,50 @@ class StaticSensitivityEvent :
class StaticSensitivityInterface :
public StaticSensitivity, public SensitivityEvent
{
- private:
- const sc_core::sc_interface *interface;
-
- public:
- StaticSensitivityInterface(Process *p, const sc_core::sc_interface *i) :
- Sensitivity(p), StaticSensitivity(p), SensitivityEvent(p), interface(i)
- {}
-
- void finalize() override;
+ friend void newStaticSensitivityInterface(
+ Process *p, const sc_core::sc_interface *i);
+ protected:
+ StaticSensitivityInterface(Process *p, const sc_core::sc_interface *i);
};
-class StaticSensitivityPort : public StaticSensitivity
+class StaticSensitivityPort :
+ public StaticSensitivity, public SensitivityEvents
{
- private:
- const ::sc_core::sc_port_base *port;
- std::set<const ::sc_core::sc_event *> events;
+ friend void newStaticSensitivityPort(
+ Process *p, const sc_core::sc_port_base *pb);
- public:
- StaticSensitivityPort(Process *p, const sc_core::sc_port_base *pb) :
- Sensitivity(p), StaticSensitivity(p), port(pb)
+ protected:
+ StaticSensitivityPort(Process *p) :
+ Sensitivity(p), StaticSensitivity(p), SensitivityEvents(p)
{}
-
- void finalize() override;
-
- void
- clear() override
- {
- for (auto event: events)
- delFromEvent(event);
- }
};
class StaticSensitivityExport :
public StaticSensitivity, public SensitivityEvent
{
private:
- const sc_core::sc_export_base *exp;
-
- public:
- StaticSensitivityExport(Process *p, const sc_core::sc_export_base *exp) :
- Sensitivity(p), StaticSensitivity(p), SensitivityEvent(p), exp(exp)
- {}
+ friend void newStaticSensitivityExport(
+ Process *p, const sc_core::sc_export_base *exp);
- void finalize() override;
+ StaticSensitivityExport(Process *p, const sc_core::sc_export_base *exp);
};
-class StaticSensitivityFinder : public StaticSensitivity
+
+class StaticSensitivityFinder :
+ public StaticSensitivity, public SensitivityEvents
{
private:
- const ::sc_core::sc_event_finder *finder;
- std::set<const ::sc_core::sc_event *> events;
+ const sc_core::sc_event_finder *finder;
+
+ friend void newStaticSensitivityFinder(
+ Process *p, const sc_core::sc_event_finder *f);
- public:
StaticSensitivityFinder(Process *p, const sc_core::sc_event_finder *f) :
- Sensitivity(p), StaticSensitivity(p), finder(f)
+ Sensitivity(p), StaticSensitivity(p), SensitivityEvents(p), finder(f)
{}
- void finalize() override;
-
- void
- clear() override
- {
- for (auto event: events)
- delFromEvent(event);
- }
+ public:
+ const ::sc_core::sc_event &find(::sc_core::sc_interface *i);
};
@@ -230,48 +246,51 @@ class StaticSensitivityFinder : public StaticSensitivity
* Dynamic sensitivities.
*/
+void newDynamicSensitivityEvent(Process *p, const sc_core::sc_event *e);
+void newDynamicSensitivityEventOrList(
+ Process *p, const sc_core::sc_event_or_list *eol);
+void newDynamicSensitivityEventAndList(
+ Process *p, const sc_core::sc_event_and_list *eal);
+
class DynamicSensitivityEvent :
public DynamicSensitivity, public SensitivityEvent
{
- public:
+ private:
+ friend void newDynamicSensitivityEvent(
+ Process *p, const sc_core::sc_event *e);
+
DynamicSensitivityEvent(Process *p, const sc_core::sc_event *e) :
Sensitivity(p), DynamicSensitivity(p), SensitivityEvent(p, e)
{}
};
-class DynamicSensitivityEventOrList : public DynamicSensitivity
+class DynamicSensitivityEventOrList :
+ public DynamicSensitivity, public SensitivityEvents
{
private:
- std::set<const ::sc_core::sc_event *> events;
-
- protected:
- bool notifyWork(Event *e) override;
+ friend void newDynamicSensitivityEventOrList(
+ Process *p, const sc_core::sc_event_or_list *eol);
- public:
DynamicSensitivityEventOrList(
Process *p, const sc_core::sc_event_or_list *eol);
- void finalize() override;
- void clear() override;
+ bool notifyWork(Event *e) override;
};
//XXX This sensitivity can't be reused. To reset it, it has to be deleted and
//recreated. That works for dynamic sensitivities, but not for static.
//Fortunately processes can't be statically sensitive to sc_event_and_lists.
-class DynamicSensitivityEventAndList : public DynamicSensitivity
+class DynamicSensitivityEventAndList :
+ public DynamicSensitivity, public SensitivityEvents
{
private:
- std::set<const ::sc_core::sc_event *> events;
-
- protected:
- bool notifyWork(Event *e) override;
+ friend void newDynamicSensitivityEventAndList(
+ Process *p, const sc_core::sc_event_and_list *eal);
- public:
DynamicSensitivityEventAndList(
Process *p, const sc_core::sc_event_and_list *eal);
- void finalize() override;
- void clear() override;
+ bool notifyWork(Event *e) override;
};
} // namespace sc_gem5
diff --git a/src/systemc/ext/core/sc_port.hh b/src/systemc/ext/core/sc_port.hh
index de26f5ae5..c9d436ec3 100644
--- a/src/systemc/ext/core/sc_port.hh
+++ b/src/systemc/ext/core/sc_port.hh
@@ -39,10 +39,7 @@
namespace sc_gem5
{
-class BindInfo;
-class Module;
-class StaticSensitivityPort;
-class StaticSensitivityFinder;
+class Port;
};
@@ -62,6 +59,7 @@ class sc_port_base : public sc_object
{
public:
sc_port_base(const char *name, int n, sc_port_policy p);
+ virtual ~sc_port_base();
void warn_unimpl(const char *func) const;
@@ -87,19 +85,13 @@ class sc_port_base : public sc_object
virtual void end_of_simulation() = 0;
private:
- friend class ::sc_gem5::StaticSensitivityPort;
- friend class ::sc_gem5::StaticSensitivityFinder;
+ friend class ::sc_gem5::Port;
friend class ::sc_gem5::Kernel;
- void _gem5Finalize();
-
virtual sc_interface *_gem5Interface(int n) const = 0;
virtual void _gem5AddInterface(sc_interface *i) = 0;
- std::vector<::sc_gem5::BindInfo *> _gem5BindInfo;
- int _maxSize;
- int _size;
- bool finalized;
+ ::sc_gem5::Port *_gem5Port;
};
template <class IF>