systemc: Rework how delayed sensitivities are handled.

Make BindInfo into a more general purpose Port class which mirrors
sc_module and Module, sc_object and Object, etc. This tracks multiple
bindings internally, and also pending sensitivities. Keep a global
list of ports which are added in reverse order to match Accellera, and
which is iterated over to finalize binding and for phase callbacks.
This is as opposed to doing it one module at a time, and is to better
match Accellera's ordering for the regressions.

Also the sensitivity classes are now built with factory functions,
which gets around problems calling virtual functions from their
constructors or forgetting to having to have extra boilerplate each
place they're constructed.

The port class also now finalizes port or event finder sensitivities
when its binding is completed, unless it's already complete in which
case it does so immediately.

Change-Id: I1b01689715c425b94e0f68cf0271f5c1565d8c61
Reviewed-on: https://gem5-review.googlesource.com/c/12806
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
This commit is contained in:
Gabe Black
2018-09-14 18:33:16 -07:00
parent 7bc110ce5c
commit d737358ac6
15 changed files with 445 additions and 244 deletions

View File

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

View File

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

View File

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

View File

@@ -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));
}
void
Port::sensitive(StaticSensitivityFinder *finder)
{
if (finalized)
finalizeFinder(finder);
else
sensitivities.push_back(new Sensitivity(finder));
}
void
Port::finalize()
{
if (finalized)
return;
finalized = true;
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
#endif // __SYSTEMC_CORE_BINDINFO_HH__

150
src/systemc/core/port.hh Normal file
View File

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

View File

@@ -235,13 +235,6 @@ Process::syncResetOff(bool inc_kids)
_syncReset = false;
}
void
Process::finalize()
{
for (auto s: staticSensitivities)
s->finalize();
};
void
Process::run()
{
@@ -276,8 +269,6 @@ Process::setDynamic(DynamicSensitivity *s)
delete dynamicSensitivity;
}
dynamicSensitivity = s;
if (dynamicSensitivity)
dynamicSensitivity->finalize();
}
void

View File

@@ -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 *);

View File

@@ -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();
}

View File

@@ -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) :
}
}
sc_port_base::~sc_port_base()
{
delete _gem5Port;
}
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; }
int sc_port_base::maxSize() const { return _gem5Port->maxSize(); }
int sc_port_base::size() const { return _gem5Port->size(); }
void
sc_port_base::bind(sc_interface &i)
{
_gem5BindInfo.push_back(new ::sc_gem5::BindInfo(&i));
}
void
sc_port_base::bind(sc_port_base &p)
{
_gem5BindInfo.push_back(new ::sc_gem5::BindInfo(&p));
}
void
sc_port_base::_gem5Finalize()
{
if (finalized)
return;
finalized = true;
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

View File

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

View File

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

View File

@@ -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();

View File

@@ -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,44 +86,110 @@ 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);
}
void
newStaticSensitivityFinder(Process *p, const sc_core::sc_event_finder *f)
{
auto s = new StaticSensitivityFinder(p, f);
Port *port = Port::fromPort(f->port());
port->sensitive(s);
p->addStatic(s);
}
StaticSensitivityInterface::StaticSensitivityInterface(
Process *p, const sc_core::sc_interface *i) :
Sensitivity(p), StaticSensitivity(p),
SensitivityEvent(p, &i->default_event())
{}
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
newDynamicSensitivityEvent(Process *p, const sc_core::sc_event *e)
{
auto s = new DynamicSensitivityEvent(p, e);
s->addToEvent(s->event);
p->setDynamic(s);
}
void
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)
{
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
DynamicSensitivityEventOrList::notifyWork(Event *e)
{
@@ -129,25 +204,11 @@ DynamicSensitivityEventOrList::notifyWork(Event *e)
return true;
}
DynamicSensitivityEventOrList::DynamicSensitivityEventOrList(
Process *p, const sc_core::sc_event_or_list *eol) :
Sensitivity(p), DynamicSensitivity(p), events(eol->events)
DynamicSensitivityEventAndList::DynamicSensitivityEventAndList(
Process *p, const sc_core::sc_event_and_list *eal) :
Sensitivity(p), DynamicSensitivity(p), SensitivityEvents(p, eal->events)
{}
void
DynamicSensitivityEventOrList::finalize()
{
for (auto e: events)
addToEvent(e);
}
void
DynamicSensitivityEventOrList::clear()
{
for (auto e: events)
delFromEvent(e);
}
bool
DynamicSensitivityEventAndList::notifyWork(Event *e)
{
@@ -160,23 +221,4 @@ DynamicSensitivityEventAndList::notifyWork(Event *e)
return true;
}
DynamicSensitivityEventAndList::DynamicSensitivityEventAndList(
Process *p, const sc_core::sc_event_and_list *eal) :
Sensitivity(p), DynamicSensitivity(p), events(eal->events)
{}
void
DynamicSensitivityEventAndList::finalize()
{
for (auto e: events)
addToEvent(e);
}
void
DynamicSensitivityEventAndList::clear()
{
for (auto e: events)
delFromEvent(e);
}
} // namespace sc_gem5

View File

@@ -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;
friend void newStaticSensitivityExport(
Process *p, 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)
{}
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;
friend void newDynamicSensitivityEventOrList(
Process *p, const sc_core::sc_event_or_list *eol);
protected:
bool notifyWork(Event *e) override;
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;
friend void newDynamicSensitivityEventAndList(
Process *p, const sc_core::sc_event_and_list *eal);
protected:
bool notifyWork(Event *e) override;
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

View File

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