systemc: Change how signal based resets work.

The previous implementation used the value changed event to track when
signals changed value, but there were a couple problems with this
approach. First, this piggybacked on the sensitivity mechanism in some
ways, but diverged in others. The sensitivity didn't notify a process
when it was satisfied like other sensitivity types would, and it also
ignored whether the process was disabled.

Second, the value_changed_event is notified by a signal instance as a
delta notification, but reset signals are supposed to act immediately.
That means they should happen before all delta notifications, or in
other words all delta notifications should see the reset status of a
given process. That's particularly important in the case of wait(int n)
where setting the reset clears the reset count, and the count is
checked when determining whether or not to wake up a process when its
sensitivity is satisfied, potentially by a delta notification.

Third, by removing the middle man and not trying to repurpose the
sensitivity mechanism, the code gets simpler and easier to understand.

Change-Id: I0d05d11437291d368b060f6a45a207813615f113
Reviewed-on: https://gem5-review.googlesource.com/c/13294
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
This commit is contained in:
Gabe Black
2018-10-04 14:59:28 -07:00
parent d1a86fd700
commit ee3e3278fd
13 changed files with 144 additions and 227 deletions

View File

@@ -165,11 +165,24 @@ ScSignalBaseBinary::posedge() const
{
return _posStamp == getChangeStamp();
}
bool
bool
ScSignalBaseBinary::negedge() const
{
return _negStamp == getChangeStamp();
}
void
ScSignalBaseBinary::_signalReset(sc_gem5::Reset *r)
{
r->update();
}
void
ScSignalBaseBinary::_signalReset()
{
for (auto r: _resets)
_signalReset(r);
}
} // namespace sc_gem5

View File

@@ -147,13 +147,6 @@ Event::notify(DynamicSensitivities &senses)
senses.resize(size);
}
void
Event::notify(ResetSensitivities &senses)
{
for (auto s: senses)
s->notify(this);
}
void
Event::notify()
{
@@ -167,7 +160,6 @@ Event::notify()
scheduler.deschedule(&delayedNotify);
_triggeredStamp = scheduler.changeStamp();
notify(resetSense);
notify(staticSenseMethod);
notify(dynamicSenseMethod);
notify(staticSenseThread);

View File

@@ -74,7 +74,6 @@ class Event
void notify(StaticSensitivities &senses);
void notify(DynamicSensitivities &senses);
void notify(ResetSensitivities &senses);
void notify();
void notify(const sc_core::sc_time &t);
@@ -138,22 +137,6 @@ class Event
}
}
}
void
addSensitivity(ResetSensitivity *s) const
{
resetSense.push_back(s);
}
void
delSensitivity(ResetSensitivity *s) const
{
for (auto &t: resetSense) {
if (t == s) {
t = resetSense.back();
resetSense.pop_back();
break;
}
}
}
private:
sc_core::sc_event *_sc_event;
@@ -171,7 +154,6 @@ class Event
mutable StaticSensitivities staticSenseThread;
mutable DynamicSensitivities dynamicSenseMethod;
mutable DynamicSensitivities dynamicSenseThread;
mutable ResetSensitivities resetSense;
};
extern Events topLevelEvents;

View File

@@ -29,6 +29,7 @@
#include "systemc/core/port.hh"
#include "systemc/core/process.hh"
#include "systemc/core/sensitivity.hh"
#include "systemc/ext/channel/sc_signal_in_if.hh"
@@ -50,14 +51,15 @@ Port::finalizeFinder(StaticSensitivityFinder *finder)
}
void
Port::finalizeReset(ResetSensitivityPort *reset)
Port::finalizeReset(Reset *reset)
{
assert(size() <= 1);
if (size()) {
auto iface =
dynamic_cast<sc_core::sc_signal_in_if<bool> *>(getInterface(0));
assert(iface);
reset->setSignal(iface);
if (!reset->install(iface))
delete reset;
}
}
@@ -80,12 +82,12 @@ Port::sensitive(StaticSensitivityFinder *finder)
}
void
Port::sensitive(ResetSensitivityPort *reset)
Port::addReset(Reset *reset)
{
if (finalized)
finalizeReset(reset);
else
sensitivities.push_back(new Sensitivity(reset));
resets.push_back(reset);
}
void
@@ -110,14 +112,17 @@ Port::finalize()
for (auto &s: sensitivities) {
if (s->port)
finalizePort(s->port);
else if (s->finder)
finalizeFinder(s->finder);
else
finalizeReset(s->reset);
finalizeFinder(s->finder);
delete s;
}
sensitivities.clear();
for (auto &r: resets)
finalizeReset(r);
resets.clear();
}
void

View File

@@ -43,7 +43,7 @@ namespace sc_gem5
class StaticSensitivityPort;
class StaticSensitivityFinder;
class ResetSensitivityPort;
class Reset;
class Port;
@@ -62,7 +62,7 @@ class Port
void finalizePort(StaticSensitivityPort *port);
void finalizeFinder(StaticSensitivityFinder *finder);
void finalizeReset(ResetSensitivityPort *reset);
void finalizeReset(Reset *reset);
void
addInterface(::sc_core::sc_interface *iface)
@@ -112,24 +112,20 @@ class Port
struct Sensitivity
{
Sensitivity(StaticSensitivityPort *port) :
port(port), finder(nullptr), reset(nullptr)
port(port), finder(nullptr)
{}
Sensitivity(StaticSensitivityFinder *finder) :
port(nullptr), finder(finder), reset(nullptr)
{}
Sensitivity(ResetSensitivityPort *reset) :
port(nullptr), finder(nullptr), reset(reset)
port(nullptr), finder(finder)
{}
StaticSensitivityPort *port;
StaticSensitivityFinder *finder;
ResetSensitivityPort *reset;
};
std::vector<Binding *> bindings;
std::vector<Sensitivity *> sensitivities;
std::vector<Reset *> resets;
public:
static Port *
@@ -166,7 +162,7 @@ class Port
void sensitive(StaticSensitivityPort *port);
void sensitive(StaticSensitivityFinder *finder);
void sensitive(ResetSensitivityPort *reset);
void addReset(Reset *reset);
void finalize();
void regPort();

View File

@@ -31,6 +31,7 @@
#include "base/logging.hh"
#include "systemc/core/event.hh"
#include "systemc/core/port.hh"
#include "systemc/core/scheduler.hh"
#include "systemc/ext/core/sc_join.hh"
#include "systemc/ext/core/sc_main.hh"
@@ -293,9 +294,9 @@ Process::setDynamic(DynamicSensitivity *s)
}
void
Process::addReset(ResetSensitivity *s)
Process::addReset(Reset *reset)
{
resetSensitivities.push_back(s);
resets.push_back(reset);
}
void
@@ -418,4 +419,19 @@ throw_it_wrapper(Process *p, ExceptionWrapperBase &exc, bool inc_kids)
p->throw_it(exc, inc_kids);
}
void
newReset(const sc_core::sc_port_base *pb, Process *p, bool s, bool v)
{
Port *port = Port::fromPort(pb);
port->addReset(new Reset(p, s, v));
}
void
newReset(const sc_core::sc_signal_in_if<bool> *sig, Process *p, bool s, bool v)
{
Reset *reset = new Reset(p, s, v);
if (!reset->install(sig))
delete reset;
}
} // namespace sc_gem5

View File

@@ -40,6 +40,7 @@
#include "systemc/core/object.hh"
#include "systemc/core/sched_event.hh"
#include "systemc/core/sensitivity.hh"
#include "systemc/ext/channel/sc_signal_in_if.hh"
#include "systemc/ext/core/sc_event.hh"
#include "systemc/ext/core/sc_module.hh"
#include "systemc/ext/core/sc_process_handle.hh"
@@ -57,6 +58,9 @@ namespace sc_gem5
class ScHalt
{};
class Process;
class Reset;
class Process : public ::sc_core::sc_process_b, public ListNode
{
public:
@@ -103,7 +107,7 @@ class Process : public ::sc_core::sc_process_b, public ListNode
void addStatic(StaticSensitivity *);
void setDynamic(DynamicSensitivity *);
void clearDynamic() { setDynamic(nullptr); }
void addReset(ResetSensitivity *);
void addReset(Reset *);
ScEvent timeoutEvent;
void setTimeout(::sc_core::sc_time t);
@@ -189,7 +193,7 @@ class Process : public ::sc_core::sc_process_b, public ListNode
StaticSensitivities staticSensitivities;
DynamicSensitivity *dynamicSensitivity;
ResetSensitivities resetSensitivities;
std::vector<Reset *> resets;
std::unique_ptr<::sc_core::sc_report> _lastReport;
@@ -198,6 +202,44 @@ class Process : public ::sc_core::sc_process_b, public ListNode
UniqueNameGen nameGen;
};
class Reset
{
public:
Reset(Process *p, bool s, bool v) :
_process(p), _signal(nullptr), _sync(s), _value(v)
{}
bool
install(const sc_core::sc_signal_in_if<bool> *s)
{
_signal = s;
if (_signal->_addReset(this)) {
_process->addReset(this);
if (_signal->read() == _value)
update();
return true;
}
return false;
}
void update() { _process->signalReset(_signal->read() == _value, _sync); }
Process *process() { return _process; }
const sc_core::sc_signal_in_if<bool> *signal() { return _signal; }
bool sync() { return _sync; }
bool value() { return _value; }
private:
Process *_process;
const sc_core::sc_signal_in_if<bool> *_signal;
bool _sync;
bool _value;
};
void newReset(const sc_core::sc_port_base *pb, Process *p, bool s, bool v);
void newReset(const sc_core::sc_signal_in_if<bool> *sig, Process *p,
bool s, bool v);
} // namespace sc_gem5
#endif //__SYSTEMC_CORE_PROCESS_HH__

View File

@@ -36,8 +36,12 @@
#include "systemc/core/kernel.hh"
#include "systemc/core/module.hh"
#include "systemc/core/object.hh"
#include "systemc/core/port.hh"
#include "systemc/core/process_types.hh"
#include "systemc/core/sensitivity.hh"
#include "systemc/ext/channel/sc_in.hh"
#include "systemc/ext/channel/sc_inout.hh"
#include "systemc/ext/channel/sc_out.hh"
#include "systemc/ext/channel/sc_signal_in_if.hh"
#include "systemc/ext/core/sc_module.hh"
#include "systemc/ext/core/sc_module_name.hh"
@@ -258,58 +262,50 @@ sc_module::end_module()
void
sc_module::reset_signal_is(const sc_in<bool> &port, bool val)
{
sc_gem5::newResetSensitivityPort(
::sc_gem5::Process::newest(), &port, val, true);
::sc_gem5::newReset(&port, ::sc_gem5::Process::newest(), true, val);
}
void
sc_module::reset_signal_is(const sc_inout<bool> &port, bool val)
{
sc_gem5::newResetSensitivityPort(
::sc_gem5::Process::newest(), &port, val, true);
::sc_gem5::newReset(&port, ::sc_gem5::Process::newest(), true, val);
}
void
sc_module::reset_signal_is(const sc_out<bool> &port, bool val)
{
sc_gem5::newResetSensitivityPort(
::sc_gem5::Process::newest(), &port, val, true);
::sc_gem5::newReset(&port, ::sc_gem5::Process::newest(), true, val);
}
void
sc_module::reset_signal_is(const sc_signal_in_if<bool> &signal, bool val)
{
sc_gem5::newResetSensitivitySignal(
::sc_gem5::Process::newest(), &signal, val, true);
::sc_gem5::newReset(&signal, ::sc_gem5::Process::newest(), true, val);
}
void
sc_module::async_reset_signal_is(const sc_in<bool> &port, bool val)
{
sc_gem5::newResetSensitivityPort(
::sc_gem5::Process::newest(), &port, val, false);
::sc_gem5::newReset(&port, ::sc_gem5::Process::newest(), false, val);
}
void
sc_module::async_reset_signal_is(const sc_inout<bool> &port, bool val)
{
sc_gem5::newResetSensitivityPort(
::sc_gem5::Process::newest(), &port, val, false);
::sc_gem5::newReset(&port, ::sc_gem5::Process::newest(), false, val);
}
void
sc_module::async_reset_signal_is(const sc_out<bool> &port, bool val)
{
sc_gem5::newResetSensitivityPort(
::sc_gem5::Process::newest(), &port, val, false);
::sc_gem5::newReset(&port, ::sc_gem5::Process::newest(), false, val);
}
void
sc_module::async_reset_signal_is(const sc_signal_in_if<bool> &signal, bool val)
{
sc_gem5::newResetSensitivitySignal(
::sc_gem5::Process::newest(), &signal, val, false);
::sc_gem5::newReset(&signal, ::sc_gem5::Process::newest(), false, val);
}

View File

@@ -31,6 +31,10 @@
#include "systemc/core/process.hh"
#include "systemc/core/process_types.hh"
#include "systemc/core/scheduler.hh"
#include "systemc/ext/channel/sc_in.hh"
#include "systemc/ext/channel/sc_inout.hh"
#include "systemc/ext/channel/sc_out.hh"
#include "systemc/ext/channel/sc_signal_in_if.hh"
#include "systemc/ext/core/sc_main.hh"
#include "systemc/ext/core/sc_module.hh"
#include "systemc/ext/core/sc_spawn.hh"
@@ -85,16 +89,16 @@ spawnWork(ProcessFuncWrapper *func, const char *name,
newStaticSensitivityFinder(proc, f);
for (auto p: opts->_in_resets)
newResetSensitivityPort(proc, p.target, p.value, p.sync);
newReset(p.target, proc, p.sync, p.value);
for (auto p: opts->_inout_resets)
newResetSensitivityPort(proc, p.target, p.value, p.sync);
newReset(p.target, proc, p.sync, p.value);
for (auto p: opts->_out_resets)
newResetSensitivityPort(proc, p.target, p.value, p.sync);
newReset(p.target, proc, p.sync, p.value);
for (auto i: opts->_if_resets)
newResetSensitivitySignal(proc, i.target, i.value, i.sync);
newReset(i.target, proc, i.sync, i.value);
}
if (opts && opts->_dontInitialize &&

View File

@@ -29,6 +29,7 @@
#include "systemc/core/sensitivity.hh"
#include "base/logging.hh"
#include "systemc/core/event.hh"
#include "systemc/core/port.hh"
#include "systemc/core/process.hh"
@@ -97,18 +98,6 @@ StaticSensitivity::delFromEvent(const ::sc_core::sc_event *e)
Event::getFromScEvent(e)->delSensitivity(this);
}
void
ResetSensitivity::addToEvent(const ::sc_core::sc_event *e)
{
Event::getFromScEvent(e)->addSensitivity(this);
}
void
ResetSensitivity::delFromEvent(const ::sc_core::sc_event *e)
{
Event::getFromScEvent(e)->delSensitivity(this);
}
/*
* Static sensitivities.
@@ -250,71 +239,4 @@ DynamicSensitivityEventAndList::notify(Event *e)
return true;
}
/*
* Reset sensitivities.
*/
void
newResetSensitivitySignal(
Process *p, const sc_core::sc_signal_in_if<bool> *signal,
bool val, bool sync)
{
auto s = new ResetSensitivitySignal(p, signal, val, sync);
s->addToEvent(s->event);
p->addReset(s);
}
void
newResetSensitivityPort(Process *p, const sc_core::sc_in<bool> *port,
bool val, bool sync)
{
auto s = new ResetSensitivityPort(p, port, val, sync);
Port::fromPort(port)->sensitive(s);
p->addReset(s);
}
void
newResetSensitivityPort(Process *p, const sc_core::sc_inout<bool> *port,
bool val, bool sync)
{
auto s = new ResetSensitivityPort(p, port, val, sync);
Port::fromPort(port)->sensitive(s);
p->addReset(s);
}
void
newResetSensitivityPort(Process *p, const sc_core::sc_out<bool> *port,
bool val, bool sync)
{
auto s = new ResetSensitivityPort(p, port, val, sync);
Port::fromPort(port)->sensitive(s);
p->addReset(s);
}
ResetSensitivitySignal::ResetSensitivitySignal(
Process *p, const sc_core::sc_signal_in_if<bool> *signal,
bool _val, bool _sync) :
Sensitivity(p), ResetSensitivity(p, _val, _sync),
SensitivityEvent(p, signal ? &signal->value_changed_event() : nullptr),
_signal(signal)
{
if (signal && signal->read() == val())
process->signalReset(true, sync());
}
bool
ResetSensitivitySignal::notify(Event *e)
{
process->signalReset(_signal->read() == val(), sync());
return true;
}
void
ResetSensitivityPort::setSignal(const ::sc_core::sc_signal_in_if<bool> *signal)
{
_signal = signal;
event = &_signal->value_changed_event();
addToEvent(event);
if (signal->read() == val())
process->signalReset(true, sync());
}
} // namespace sc_gem5

View File

@@ -81,8 +81,7 @@ class Sensitivity
enum Category
{
Static,
Dynamic,
Reset
Dynamic
};
virtual Category category() = 0;
@@ -92,7 +91,7 @@ class Sensitivity
/*
* Dynamic vs. static vs. reset sensitivity.
* Dynamic vs. static sensitivity.
*/
class DynamicSensitivity : virtual public Sensitivity
@@ -124,29 +123,6 @@ class StaticSensitivity : virtual public Sensitivity
typedef std::vector<StaticSensitivity *> StaticSensitivities;
class ResetSensitivity : virtual public Sensitivity
{
private:
bool _val;
bool _sync;
protected:
ResetSensitivity(Process *p, bool _val, bool _sync) :
Sensitivity(p), _val(_val), _sync(_sync)
{}
void addToEvent(const ::sc_core::sc_event *e) override;
void delFromEvent(const ::sc_core::sc_event *e) override;
bool val() { return _val; }
bool sync() { return _sync; }
public:
Category category() override { return Reset; }
};
typedef std::vector<ResetSensitivity *> ResetSensitivities;
/*
* Sensitivity to an event or events, which can be static or dynamic.
@@ -319,60 +295,6 @@ class DynamicSensitivityEventAndList :
bool notify(Event *e) override;
};
/*
* Reset sensitivities.
*/
void newResetSensitivitySignal(
Process *p, const sc_core::sc_signal_in_if<bool> *signal,
bool val, bool sync);
void newResetSensitivityPort(
Process *p, const sc_core::sc_in<bool> *port, bool val, bool sync);
void newResetSensitivityPort(
Process *p, const sc_core::sc_inout<bool> *port, bool val, bool sync);
void newResetSensitivityPort(
Process *p, const sc_core::sc_out<bool> *port, bool val, bool sync);
class ResetSensitivitySignal :
public ResetSensitivity, public SensitivityEvent
{
protected:
const sc_core::sc_signal_in_if<bool> *_signal;
friend void newResetSensitivitySignal(
Process *p, const sc_core::sc_signal_in_if<bool> *signal,
bool val, bool sync);
ResetSensitivitySignal(
Process *p, const sc_core::sc_signal_in_if<bool> *signal,
bool _val, bool _sync);
bool notify(Event *e) override;
};
class ResetSensitivityPort : public ResetSensitivitySignal
{
private:
friend void newResetSensitivityPort(
Process *p, const sc_core::sc_in<bool> *port, bool val, bool sync);
friend void newResetSensitivityPort(
Process *p, const sc_core::sc_inout<bool> *port,
bool val, bool sync);
friend void newResetSensitivityPort(
Process *p, const sc_core::sc_out<bool> *port,
bool val, bool sync);
ResetSensitivityPort(
Process *p, const sc_core::sc_port_base *port,
bool _val, bool _sync) :
Sensitivity(p), ResetSensitivitySignal(p, nullptr, _val, _sync)
{}
public:
void setSignal(const ::sc_core::sc_signal_in_if<bool> *signal);
};
} // namespace sc_gem5
#endif //__SYSTEMC_CORE_SENSITIVITY_HH__

View File

@@ -51,6 +51,7 @@ namespace sc_gem5
{
class Process;
class Reset;
class ScSignalBase : public sc_core::sc_prim_channel
{
@@ -80,6 +81,10 @@ class ScSignalBaseBinary : public ScSignalBase
protected:
ScSignalBaseBinary(const char *_name);
mutable std::vector<sc_gem5::Reset *> _resets;
void _signalReset(sc_gem5::Reset *reset);
void _signalReset();
const sc_core::sc_event &posedgeEvent() const;
const sc_core::sc_event &negedgeEvent() const;
@@ -352,6 +357,7 @@ class sc_signal<bool, WRITER_POLICY> :
return;
this->m_cur_val = this->m_new_val;
this->_signalReset();
this->_signalChange();
if (this->m_cur_val) {
this->_posStamp = ::sc_gem5::getChangeStamp();
@@ -363,6 +369,13 @@ class sc_signal<bool, WRITER_POLICY> :
}
private:
bool
_addReset(sc_gem5::Reset *reset) const
{
this->_resets.push_back(reset);
return true;
}
// Disabled
sc_signal(const sc_signal<bool, WRITER_POLICY> &);
};

View File

@@ -39,6 +39,13 @@ class sc_logic;
};
namespace sc_gem5
{
class Reset;
} // namespace sc_gem5
namespace sc_core
{
@@ -83,6 +90,13 @@ class sc_signal_in_if<bool> : virtual public sc_interface
sc_signal_in_if() : sc_interface() {}
private:
friend class sc_gem5::Reset;
virtual bool
_addReset(sc_gem5::Reset *reset) const
{
return false;
}
// Disabled
sc_signal_in_if(const sc_signal_in_if<bool> &) : sc_interface() {}
sc_signal_in_if<bool> &