diff options
Diffstat (limited to 'src/systemc/core/process.hh')
-rw-r--r-- | src/systemc/core/process.hh | 233 |
1 files changed, 231 insertions, 2 deletions
diff --git a/src/systemc/core/process.hh b/src/systemc/core/process.hh index bb9a9c60c..cd92992eb 100644 --- a/src/systemc/core/process.hh +++ b/src/systemc/core/process.hh @@ -31,17 +31,218 @@ #define __SYSTEMC_CORE_PROCESS_HH__ #include <functional> +#include <vector> #include "base/fiber.hh" +#include "sim/eventq.hh" +#include "systemc/core/bindinfo.hh" #include "systemc/core/list.hh" #include "systemc/core/object.hh" #include "systemc/ext/core/sc_event.hh" +#include "systemc/ext/core/sc_interface.hh" #include "systemc/ext/core/sc_module.hh" +#include "systemc/ext/core/sc_port.hh" #include "systemc/ext/core/sc_process_handle.hh" namespace sc_gem5 { +class Sensitivity +{ + protected: + Process *process; + void satisfy(); + + public: + Sensitivity(Process *p) : process(p) {} + virtual ~Sensitivity() {} + + virtual void notifyWork(Event *e) { satisfy(); } + void notify(Event *e); + void notify() { notify(nullptr); } + + const std::string name(); +}; + +class SensitivityTimeout : virtual public Sensitivity +{ + private: + EventWrapper<Sensitivity, &Sensitivity::notify> timeoutEvent; + ::sc_core::sc_time timeout; + + 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(); + + virtual 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) + {} +}; + +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) + {} +}; + +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) + {} +}; + +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->_gem5BindInfo[i]->interface->default_event(); + s.push_back(new SensitivityEvent(process, e)); + } + } +}; + +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 + { + s.push_back(new SensitivityEvent(process, &finder->find_event())); + } +}; + +typedef std::vector<PendingSensitivity *> PendingSensitivities; + + class Process : public ::sc_core::sc_object, public ListNode { public: @@ -78,12 +279,17 @@ class Process : public ::sc_core::sc_object, public ListNode const ::sc_core::sc_event &terminatedEvent() { return _terminatedEvent; } // This should only be called before initialization. - void dontInitialize() { popListNode(); } + void dontInitialize(); void setStackSize(size_t size) { stackSize = size; } + void finalize(); + void run(); + void addStatic(PendingSensitivity *); + void setDynamic(Sensitivity *); + virtual Fiber *fiber() { return Fiber::primaryFiber(); } static Process *newest() { return _newest; } @@ -93,7 +299,12 @@ class Process : public ::sc_core::sc_object, public ListNode static Process *_newest; - virtual ~Process() { delete func; } + virtual ~Process() + { + delete func; + for (auto s: staticSensitivities) + delete s; + } ::sc_core::sc_event _resetEvent; ::sc_core::sc_event _terminatedEvent; @@ -113,8 +324,26 @@ class Process : public ::sc_core::sc_object, public ListNode int refCount; size_t stackSize; + + Sensitivities staticSensitivities; + PendingSensitivities pendingStaticSensitivities; + + Sensitivity *dynamicSensitivity; }; +inline void +Sensitivity::notify(Event *e) +{ + if (!process->disabled()) + notifyWork(e); +} + +inline const std::string +Sensitivity::name() +{ + return std::string(process->name()) + ".timeout"; +} + } // namespace sc_gem5 #endif //__SYSTEMC_CORE_PROCESS_HH__ |