diff options
Diffstat (limited to 'src/systemc')
-rw-r--r-- | src/systemc/core/SConscript | 1 | ||||
-rw-r--r-- | src/systemc/core/kernel.cc | 14 | ||||
-rw-r--r-- | src/systemc/core/module.cc | 8 | ||||
-rw-r--r-- | src/systemc/core/port.cc (renamed from src/systemc/core/bindinfo.hh) | 78 | ||||
-rw-r--r-- | src/systemc/core/port.hh | 150 | ||||
-rw-r--r-- | src/systemc/core/process.cc | 9 | ||||
-rw-r--r-- | src/systemc/core/process.hh | 3 | ||||
-rw-r--r-- | src/systemc/core/sc_module.cc | 24 | ||||
-rw-r--r-- | src/systemc/core/sc_port.cc | 50 | ||||
-rw-r--r-- | src/systemc/core/sc_sensitive.cc | 12 | ||||
-rw-r--r-- | src/systemc/core/sc_spawn.cc | 10 | ||||
-rw-r--r-- | src/systemc/core/scheduler.cc | 3 | ||||
-rw-r--r-- | src/systemc/core/sensitivity.cc | 154 | ||||
-rw-r--r-- | src/systemc/core/sensitivity.hh | 151 | ||||
-rw-r--r-- | src/systemc/ext/core/sc_port.hh | 16 |
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> |