From f2ab5e7a9e11783da3b9d7338775cf4b5fe2c29c Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 16 Jul 2018 16:14:33 -0700 Subject: systemc: Implement the sensitivity mechanism. This change lets processes be sensitive to events, timeouts, etc. Change-Id: If30a256dfa8a2e92192c1f9c96b48e2aa28ec27e Reviewed-on: https://gem5-review.googlesource.com/11713 Reviewed-by: Gabe Black Maintainer: Gabe Black --- src/systemc/core/bindinfo.hh | 46 ++++++++ src/systemc/core/event.cc | 25 ++++- src/systemc/core/event.hh | 11 ++ src/systemc/core/kernel.cc | 2 +- src/systemc/core/process.cc | 112 ++++++++++++++++++- src/systemc/core/process.hh | 233 ++++++++++++++++++++++++++++++++++++++- src/systemc/core/sc_port.cc | 8 ++ src/systemc/core/sc_sensitive.cc | 22 ++-- src/systemc/core/scheduler.cc | 46 +++++++- src/systemc/core/scheduler.hh | 18 ++- src/systemc/ext/core/sc_event.hh | 4 + src/systemc/ext/core/sc_port.hh | 22 +++- 12 files changed, 523 insertions(+), 26 deletions(-) create mode 100644 src/systemc/core/bindinfo.hh diff --git a/src/systemc/core/bindinfo.hh b/src/systemc/core/bindinfo.hh new file mode 100644 index 000000000..332fb1330 --- /dev/null +++ b/src/systemc/core/bindinfo.hh @@ -0,0 +1,46 @@ +/* + * 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_BINDINFO_HH__ +#define __SYSTEMC_CORE_BINDINFO_HH__ + +#include "systemc/ext/core/sc_interface.hh" + +namespace sc_gem5 +{ + +class BindInfo +{ + public: + ::sc_core::sc_interface *interface; +}; + +} // namespace sc_gem5 + +#endif // __SYSTEMC_CORE_BINDINFO_HH__ diff --git a/src/systemc/core/event.cc b/src/systemc/core/event.cc index 63fcabe4f..5008074f6 100644 --- a/src/systemc/core/event.cc +++ b/src/systemc/core/event.cc @@ -32,6 +32,8 @@ #include #include +#include "base/logging.hh" +#include "sim/core.hh" #include "systemc/core/module.hh" #include "systemc/core/scheduler.hh" @@ -41,7 +43,7 @@ namespace sc_gem5 Event::Event(sc_core::sc_event *_sc_event) : Event(_sc_event, "") {} Event::Event(sc_core::sc_event *_sc_event, const char *_basename) : - _sc_event(_sc_event), _basename(_basename) + _sc_event(_sc_event), _basename(_basename), delayedNotify(this) { Module *p = currentModule(); @@ -81,6 +83,9 @@ Event::~Event() EventsIt it = findEvent(_name); std::swap(*it, allEvents.back()); allEvents.pop_back(); + + if (delayedNotifyEvent.scheduled()) + scheduler.deschedule(&delayedNotifyEvent); } const std::string & @@ -110,16 +115,34 @@ Event::getParentObject() const void Event::notify() { + auto local_sensitivities = sensitivities; + for (auto s: local_sensitivities) + s->notify(this); } void Event::notify(const sc_core::sc_time &t) { + //XXX We're assuming the systemc time resolution is in ps. + Tick new_tick = t.value() * SimClock::Int::ps + + scheduler.eventQueue().getCurTick(); + if (delayedNotify.scheduled()) { + Tick old_tick = delayedNotify.when(); + + if (new_tick >= old_tick) + return; + + scheduler.eventQueue().deschedule(&delayedNotify); + } + + scheduler.eventQueue().schedule(&delayedNotify, new_tick); } void Event::cancel() { + if (delayedNotify.scheduled()) + scheduler.eventQueue().deschedule(&delayedNotify); } bool diff --git a/src/systemc/core/event.hh b/src/systemc/core/event.hh index bf9afd40f..a9d318382 100644 --- a/src/systemc/core/event.hh +++ b/src/systemc/core/event.hh @@ -30,9 +30,11 @@ #ifndef __SYSTEMC_CORE_EVENT_HH__ #define __SYSTEMC_CORE_EVENT_HH__ +#include #include #include +#include "sim/eventq.hh" #include "systemc/core/list.hh" #include "systemc/core/object.hh" #include "systemc/ext/core/sc_prim.hh" @@ -50,6 +52,8 @@ namespace sc_gem5 typedef std::vector Events; +class Sensitivity; + class Event { public: @@ -88,6 +92,9 @@ class Event return e->_gem5_event; } + void addSensitivity(Sensitivity *s) const { sensitivities.insert(s); } + void delSensitivity(Sensitivity *s) const { sensitivities.erase(s); } + private: sc_core::sc_event *_sc_event; @@ -97,6 +104,10 @@ class Event sc_core::sc_object *parent; EventsIt parentIt; + + EventWrapper delayedNotify; + + mutable std::set sensitivities; }; extern Events topLevelEvents; diff --git a/src/systemc/core/kernel.cc b/src/systemc/core/kernel.cc index e93236541..3b75c2fd2 100644 --- a/src/systemc/core/kernel.cc +++ b/src/systemc/core/kernel.cc @@ -56,7 +56,7 @@ Kernel::t0Handler() // happen before them, honoring the ordering for the initialization phase // in the spec. The delta phase will happen at normal priority, and then // the event which runs the processes which is at a lower priority. - ::sc_gem5::scheduler.initToReady(); + ::sc_gem5::scheduler.prepareForInit(); } } // namespace SystemC diff --git a/src/systemc/core/process.cc b/src/systemc/core/process.cc index 26cfb7ecd..a949c9dee 100644 --- a/src/systemc/core/process.cc +++ b/src/systemc/core/process.cc @@ -28,11 +28,84 @@ */ #include "systemc/core/process.hh" + +#include "base/logging.hh" +#include "systemc/core/event.hh" #include "systemc/core/scheduler.hh" namespace sc_gem5 { +void +Sensitivity::satisfy() +{ + warn_once("Ignoring suspended status for now.\n"); + process->setDynamic(nullptr); + scheduler.ready(process); +} + +SensitivityTimeout::SensitivityTimeout(Process *p, ::sc_core::sc_time t) : + Sensitivity(p), timeoutEvent(this), timeout(t) +{ + Tick when = scheduler.eventQueue().getCurTick() + timeout.value(); + scheduler.eventQueue().schedule(&timeoutEvent, when); +} + +SensitivityTimeout::~SensitivityTimeout() +{ + if (timeoutEvent.scheduled()) + scheduler.eventQueue().deschedule(&timeoutEvent); +} + +SensitivityEvent::SensitivityEvent( + Process *p, const ::sc_core::sc_event *e) : Sensitivity(p), event(e) +{ + Event::getFromScEvent(event)->addSensitivity(this); +} + +SensitivityEvent::~SensitivityEvent() +{ + Event::getFromScEvent(event)->delSensitivity(this); +} + +SensitivityEventAndList::SensitivityEventAndList( + Process *p, const ::sc_core::sc_event_and_list *list) : + Sensitivity(p), list(list), count(0) +{ + for (auto e: list->events) + Event::getFromScEvent(e)->addSensitivity(this); +} + +SensitivityEventAndList::~SensitivityEventAndList() +{ + for (auto e: list->events) + Event::getFromScEvent(e)->delSensitivity(this); +} + +void +SensitivityEventAndList::notifyWork(Event *e) +{ + e->delSensitivity(this); + count++; + if (count == list->events.size()) + satisfy(); +} + +SensitivityEventOrList::SensitivityEventOrList( + Process *p, const ::sc_core::sc_event_or_list *list) : + Sensitivity(p), list(list) +{ + for (auto e: list->events) + Event::getFromScEvent(e)->addSensitivity(this); +} + +SensitivityEventOrList::~SensitivityEventOrList() +{ + for (auto e: list->events) + Event::getFromScEvent(e)->delSensitivity(this); +} + + class UnwindExceptionReset : public ::sc_core::sc_unwind_exception { public: @@ -190,6 +263,23 @@ Process::syncResetOff(bool inc_kids) _syncReset = false; } +void +Process::dontInitialize() +{ + scheduler.dontInitialize(this); +} + +void +Process::finalize() +{ + for (auto &s: pendingStaticSensitivities) { + s->finalize(staticSensitivities); + delete s; + s = nullptr; + } + pendingStaticSensitivities.clear(); +}; + void Process::run() { @@ -206,15 +296,31 @@ Process::run() _running = false; } +void +Process::addStatic(PendingSensitivity *s) +{ + pendingStaticSensitivities.push_back(s); +} + +void +Process::setDynamic(Sensitivity *s) +{ + delete dynamicSensitivity; + dynamicSensitivity = s; +} + Process::Process(const char *name, ProcessFuncWrapper *func, bool _dynamic) : ::sc_core::sc_object(name), excWrapper(nullptr), func(func), _running(false), _dynamic(_dynamic), _isUnwinding(false), _terminated(false), _suspended(false), _disabled(false), - _syncReset(false), refCount(0), stackSize(::Fiber::DefaultStackSize) + _syncReset(false), refCount(0), stackSize(::Fiber::DefaultStackSize), + dynamicSensitivity(nullptr) { _newest = this; - if (!_dynamic) - scheduler.init(this); + if (_dynamic) + finalize(); + else + scheduler.reg(this); } Process *Process::_newest; 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 +#include #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 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 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 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__ diff --git a/src/systemc/core/sc_port.cc b/src/systemc/core/sc_port.cc index 0f981ea54..ad228548f 100644 --- a/src/systemc/core/sc_port.cc +++ b/src/systemc/core/sc_port.cc @@ -28,17 +28,25 @@ */ #include "base/logging.hh" +#include "systemc/core/bindinfo.hh" #include "systemc/ext/core/sc_port.hh" namespace sc_core { +sc_port_base::sc_port_base(const char *name, int n, sc_port_policy p) : + sc_object(name) +{} + 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 _gem5BindInfo.size(); } + void sc_port_base::bind(sc_interface &) { diff --git a/src/systemc/core/sc_sensitive.cc b/src/systemc/core/sc_sensitive.cc index d233cda6a..25bc1bb08 100644 --- a/src/systemc/core/sc_sensitive.cc +++ b/src/systemc/core/sc_sensitive.cc @@ -28,6 +28,8 @@ */ #include "base/logging.hh" +#include "systemc/core/process.hh" +#include "systemc/ext/core/sc_interface.hh" #include "systemc/ext/core/sc_sensitive.hh" namespace sc_core @@ -36,30 +38,34 @@ namespace sc_core sc_sensitive::sc_sensitive() : currentProcess(nullptr) {} sc_sensitive & -sc_sensitive::operator << (const sc_event &) +sc_sensitive::operator << (const sc_event &e) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + currentProcess->addStatic( + new sc_gem5::PendingSensitivityEvent(currentProcess, &e)); return *this; } sc_sensitive & -sc_sensitive::operator << (const sc_interface &) +sc_sensitive::operator << (const sc_interface &i) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + currentProcess->addStatic( + new sc_gem5::PendingSensitivityInterface(currentProcess, &i)); return *this; } sc_sensitive & -sc_sensitive::operator << (const sc_port_base &) +sc_sensitive::operator << (const sc_port_base &b) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + currentProcess->addStatic( + new sc_gem5::PendingSensitivityPort(currentProcess, &b)); return *this; } sc_sensitive & -sc_sensitive::operator << (sc_event_finder &) +sc_sensitive::operator << (sc_event_finder &f) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + currentProcess->addStatic( + new sc_gem5::PendingSensitivityFinder(currentProcess, &f)); return *this; } diff --git a/src/systemc/core/scheduler.cc b/src/systemc/core/scheduler.cc index 17e7dc43e..8ea090f57 100644 --- a/src/systemc/core/scheduler.cc +++ b/src/systemc/core/scheduler.cc @@ -38,14 +38,52 @@ namespace sc_gem5 Scheduler::Scheduler() : eq(nullptr), readyEvent(this, false, EventBase::Default_Pri + 1), - _numCycles(0), _current(nullptr) + _numCycles(0), _current(nullptr), initReady(false) {} void -Scheduler::initToReady() +Scheduler::prepareForInit() { - while (!initList.empty()) - ready(initList.getNext()); + for (Process *p = toFinalize.getNext(); p; p = toFinalize.getNext()) { + p->finalize(); + p->popListNode(); + } + + for (Process *p = initList.getNext(); p; p = initList.getNext()) { + p->finalize(); + ready(p); + } + + initReady = true; +} + +void +Scheduler::reg(Process *p) +{ + if (initReady) { + // If we're past initialization, finalize static sensitivity. + p->finalize(); + // Mark the process as ready. + ready(p); + } else { + // Otherwise, record that this process should be initialized once we + // get there. + initList.pushLast(p); + } +} + +void +Scheduler::dontInitialize(Process *p) +{ + if (initReady) { + // Pop this process off of the ready list. + p->popListNode(); + } else { + // Push this process onto the list of processes which still need + // their static sensitivity to be finalized. That implicitly pops it + // off the list of processes to be initialized/marked ready. + toFinalize.pushLast(p); + } } void diff --git a/src/systemc/core/scheduler.hh b/src/systemc/core/scheduler.hh index e1ad21a57..aa8ec9aa4 100644 --- a/src/systemc/core/scheduler.hh +++ b/src/systemc/core/scheduler.hh @@ -30,6 +30,8 @@ #ifndef __SYSTEMC_CORE_SCHEDULER_HH__ #define __SYSTEMC_CORE_SCHEDULER_HH__ +#include + #include "sim/eventq.hh" #include "systemc/core/channel.hh" #include "systemc/core/list.hh" @@ -58,7 +60,7 @@ typedef NodeList ChannelList; * schedules an event to be run at time 0 with a slightly elevated priority * so that it happens before any "normal" event. * - * When that t0 event happens, it calls the schedulers initToReady method + * When that t0 event happens, it calls the schedulers prepareForInit method * which performs step 2 above. That indirectly causes the scheduler's * readyEvent to be scheduled with slightly lowered priority, ensuring it * happens after any "normal" event. @@ -115,11 +117,14 @@ class Scheduler uint64_t numCycles() { return _numCycles; } Process *current() { return _current; } - // Mark processes that need to be initialized as ready. - void initToReady(); + // Prepare for initialization. + void prepareForInit(); + + // Register a process with the scheduler. + void reg(Process *p); - // Put a process on the list of processes to be initialized. - void init(Process *p) { initList.pushLast(p); } + // Tell the scheduler not to initialize a process. + void dontInitialize(Process *p); // Run the next process, if there is one. void yield(); @@ -162,7 +167,10 @@ class Scheduler Process *_current; + bool initReady; + ProcessList initList; + ProcessList toFinalize; ProcessList readyList; ChannelList updateList; diff --git a/src/systemc/ext/core/sc_event.hh b/src/systemc/ext/core/sc_event.hh index d037a84bf..c2154967d 100644 --- a/src/systemc/ext/core/sc_event.hh +++ b/src/systemc/ext/core/sc_event.hh @@ -39,6 +39,8 @@ namespace sc_gem5 { class Event; +class SensitivityEventAndList; +class SensitivityEventOrList; } @@ -100,6 +102,7 @@ class sc_event_and_list private: friend class sc_event_and_expr; + friend class sc_gem5::SensitivityEventAndList; explicit sc_event_and_list(bool auto_delete); @@ -131,6 +134,7 @@ class sc_event_or_list private: friend class sc_event_or_expr; + friend class sc_gem5::SensitivityEventOrList; explicit sc_event_or_list(bool auto_delete); diff --git a/src/systemc/ext/core/sc_port.hh b/src/systemc/ext/core/sc_port.hh index 262ca382b..0f5a66189 100644 --- a/src/systemc/ext/core/sc_port.hh +++ b/src/systemc/ext/core/sc_port.hh @@ -30,9 +30,19 @@ #ifndef __SYSTEMC_EXT_CORE_SC_PORT_HH__ #define __SYSTEMC_EXT_CORE_SC_PORT_HH__ +#include + #include "sc_module.hh" // for sc_gen_unique_name #include "sc_object.hh" +namespace sc_gem5 +{ + +class BindInfo; +class PendingSensitivityPort; + +}; + namespace sc_core { @@ -48,11 +58,13 @@ enum sc_port_policy class sc_port_base : public sc_object { public: - sc_port_base(const char *name, int n, sc_port_policy p) : sc_object(name) - {} + sc_port_base(const char *name, int n, sc_port_policy p); void warn_unimpl(const char *func) const; + int maxSize() const; + int size() const; + protected: // Implementation defined, but depended on by the tests. void bind(sc_interface &); @@ -61,6 +73,12 @@ class sc_port_base : public sc_object // Implementation defined, but depended on by the tests. virtual int vbind(sc_interface &) = 0; virtual int vbind(sc_port_base &) = 0; + + private: + friend class ::sc_gem5::PendingSensitivityPort; + + std::vector<::sc_gem5::BindInfo *> _gem5BindInfo; + int _maxSize; }; template -- cgit v1.2.3