38d37
< #include "sim/eventq.hh"
40d38
< #include "systemc/core/event.hh"
43a42
> #include "systemc/core/sensitivity.hh"
45,46d43
< #include "systemc/ext/core/sc_export.hh"
< #include "systemc/ext/core/sc_interface.hh"
48d44
< #include "systemc/ext/core/sc_port.hh"
50d45
< #include "systemc/ext/utils/sc_report.hh"
65,291d59
< class Sensitivity
< {
< protected:
< Process *process;
<
< public:
< Sensitivity(Process *p) : process(p) {}
< virtual ~Sensitivity() {}
<
< void satisfy(bool timedOut=false);
<
< virtual void notifyWork(Event *e) { satisfy(); }
< void notify(Event *e);
< void notify() { notify(nullptr); }
<
< const std::string name();
< };
<
< class SensitivityTimeout : virtual public Sensitivity
< {
< private:
< void timeout();
< ScEvent timeoutEvent;
<
< public:
< SensitivityTimeout(Process *p, ::sc_core::sc_time t);
< ~SensitivityTimeout();
< };
<
< class SensitivityEvent : virtual public Sensitivity
< {
< private:
< const ::sc_core::sc_event *event;
<
< public:
< SensitivityEvent(Process *p, const ::sc_core::sc_event *e);
< ~SensitivityEvent();
< };
<
< //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 SensitivityEventAndList : virtual public Sensitivity
< {
< private:
< const ::sc_core::sc_event_and_list *list;
< int count;
<
< public:
< SensitivityEventAndList(
< Process *p, const ::sc_core::sc_event_and_list *list);
< ~SensitivityEventAndList();
<
< void notifyWork(Event *e) override;
< };
<
< class SensitivityEventOrList : virtual public Sensitivity
< {
< private:
< const ::sc_core::sc_event_or_list *list;
<
< public:
< SensitivityEventOrList(
< Process *p, const ::sc_core::sc_event_or_list *list);
< ~SensitivityEventOrList();
< };
<
< // Combined sensitivities. These trigger when any of their parts do.
<
< class SensitivityTimeoutAndEvent :
< public SensitivityTimeout, public SensitivityEvent
< {
< public:
< SensitivityTimeoutAndEvent(
< Process *p, ::sc_core::sc_time t, const ::sc_core::sc_event *e) :
< Sensitivity(p), SensitivityTimeout(p, t), SensitivityEvent(p, e)
< {}
<
< void notifyWork(Event *e) override { satisfy(e == nullptr); }
< };
<
< class SensitivityTimeoutAndEventAndList :
< public SensitivityTimeout, public SensitivityEventAndList
< {
< public:
< SensitivityTimeoutAndEventAndList(
< Process *p, ::sc_core::sc_time t,
< const ::sc_core::sc_event_and_list *eal) :
< Sensitivity(p), SensitivityTimeout(p, t),
< SensitivityEventAndList(p, eal)
< {}
<
< void notifyWork(Event *e) override;
< };
<
< class SensitivityTimeoutAndEventOrList :
< public SensitivityTimeout, public SensitivityEventOrList
< {
< public:
< SensitivityTimeoutAndEventOrList(
< Process *p, ::sc_core::sc_time t,
< const ::sc_core::sc_event_or_list *eol) :
< Sensitivity(p), SensitivityTimeout(p, t),
< SensitivityEventOrList(p, eol)
< {}
<
< void notifyWork(Event *e) override { satisfy(e == nullptr); }
< };
<
< typedef std::vector<Sensitivity *> Sensitivities;
<
<
< /*
< * Pending sensitivities. These are records of sensitivities to install later,
< * once all the information to configure them is available.
< */
<
< class PendingSensitivity
< {
< protected:
< Process *process;
<
< public:
< virtual void finalize(Sensitivities &s) = 0;
< PendingSensitivity(Process *p) : process(p) {}
< virtual ~PendingSensitivity() {}
< };
<
< class PendingSensitivityEvent : public PendingSensitivity
< {
< private:
< const sc_core::sc_event *event;
<
< public:
< PendingSensitivityEvent(Process *p, const sc_core::sc_event *e) :
< PendingSensitivity(p), event(e) {}
<
< void
< finalize(Sensitivities &s) override
< {
< s.push_back(new SensitivityEvent(process, event));
< }
< };
<
< class PendingSensitivityInterface : public PendingSensitivity
< {
< private:
< const sc_core::sc_interface *interface;
<
< public:
< PendingSensitivityInterface(Process *p, const sc_core::sc_interface *i) :
< PendingSensitivity(p), interface(i)
< {}
<
< void
< finalize(Sensitivities &s) override
< {
< s.push_back(new SensitivityEvent(process,
< &interface->default_event()));
< }
< };
<
< class PendingSensitivityPort : public PendingSensitivity
< {
< private:
< const sc_core::sc_port_base *port;
<
< public:
< PendingSensitivityPort(Process *p, const sc_core::sc_port_base *pb) :
< PendingSensitivity(p), port(pb)
< {}
<
< void
< finalize(Sensitivities &s) override
< {
< for (int i = 0; i < port->size(); i++) {
< const ::sc_core::sc_event *e =
< &port->_gem5Interface(i)->default_event();
< s.push_back(new SensitivityEvent(process, e));
< }
< }
< };
<
< class PendingSensitivityExport : public PendingSensitivity
< {
< private:
< const sc_core::sc_export_base *exp;
<
< public:
< PendingSensitivityExport(Process *p, const sc_core::sc_export_base *exp) :
< PendingSensitivity(p), exp(exp)
< {}
<
< void
< finalize(Sensitivities &s) override
< {
< s.push_back(new SensitivityEvent(process,
< &exp->get_interface()->default_event()));
< }
< };
<
< class PendingSensitivityFinder : public PendingSensitivity
< {
< private:
< const sc_core::sc_event_finder *finder;
<
< public:
< PendingSensitivityFinder(Process *p, const sc_core::sc_event_finder *f) :
< PendingSensitivity(p), finder(f)
< {}
<
< void
< finalize(Sensitivities &s) override
< {
< 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);
< s.push_back(new SensitivityEvent(process, event));
< }
< }
< };
<
< typedef std::vector<PendingSensitivity *> PendingSensitivities;
<
<
335,336c103,105
< void addStatic(PendingSensitivity *);
< void setDynamic(Sensitivity *);
---
> void addStatic(StaticSensitivity *);
> void setDynamic(DynamicSensitivity *);
> void clearDynamic() { setDynamic(nullptr); }
337a107,110
> ScEvent timeoutEvent;
> void setTimeout(::sc_core::sc_time t);
> void cancelTimeout();
>
352d124
< void timedOut(bool to) { _timedOut = to; }
359a132,133
> void timeout();
>
368c142,143
< for (auto s: staticSensitivities)
---
> for (auto s: staticSensitivities) {
> s->clear();
369a145,146
> }
> clearDynamic();
402,403c179,180
< Sensitivities staticSensitivities;
< PendingSensitivities pendingStaticSensitivities;
---
> StaticSensitivities staticSensitivities;
> DynamicSensitivity *dynamicSensitivity;
405,406d181
< Sensitivity *dynamicSensitivity;
<
412,431d186
< inline void
< Sensitivity::satisfy(bool timedOut)
< {
< process->timedOut(timedOut);
< process->satisfySensitivity(this);
< }
<
< inline void
< Sensitivity::notify(Event *e)
< {
< if (!process->disabled())
< notifyWork(e);
< }
<
< inline const std::string
< Sensitivity::name()
< {
< return std::string(process->name()) + ".timeout";
< }
<