summaryrefslogtreecommitdiff
path: root/src/systemc/core/process.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/systemc/core/process.hh')
-rw-r--r--src/systemc/core/process.hh233
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__