From f9298649bb4d1f20b244a6e0930bb82be5ec7397 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 15 Aug 2018 23:35:38 -0700 Subject: [PATCH] systemc: Track exports and prim channels, and call their callbacks. Also call the callbacks on the ports which were already being tracked. Change-Id: I5ba8ea366e87fc48b58712f35b93c27bccf92cb3 Reviewed-on: https://gem5-review.googlesource.com/12210 Reviewed-by: Gabe Black Maintainer: Gabe Black --- src/systemc/core/channel.cc | 12 +++++++++++ src/systemc/core/channel.hh | 8 ++++++-- src/systemc/core/kernel.cc | 34 ++++++++++++++++++++++++++++--- src/systemc/core/module.hh | 2 ++ src/systemc/core/sc_export.cc | 7 ++++++- src/systemc/ext/core/sc_export.hh | 16 +++++++++++---- src/systemc/ext/core/sc_port.hh | 13 ++++++++---- src/systemc/ext/core/sc_prim.hh | 2 ++ 8 files changed, 80 insertions(+), 14 deletions(-) diff --git a/src/systemc/core/channel.cc b/src/systemc/core/channel.cc index 4a862b8aa..49d9f6cb7 100644 --- a/src/systemc/core/channel.cc +++ b/src/systemc/core/channel.cc @@ -34,6 +34,16 @@ namespace sc_gem5 { +Channel::Channel(sc_core::sc_prim_channel *_sc_chan) : _sc_chan(_sc_chan) +{ + allChannels.insert(this); +} + +Channel::~Channel() +{ + allChannels.erase(this); +} + void Channel::requestUpdate() { @@ -47,4 +57,6 @@ Channel::asyncRequestUpdate() scheduler.requestUpdate(this); } +std::set allChannels; + } // namespace sc_gem5 diff --git a/src/systemc/core/channel.hh b/src/systemc/core/channel.hh index 7ce437572..6111e3c16 100644 --- a/src/systemc/core/channel.hh +++ b/src/systemc/core/channel.hh @@ -30,6 +30,8 @@ #ifndef __SYSTEMC_CORE_CHANNEL_HH__ #define __SYSTEMC_CORE_CHANNEL_HH__ +#include + #include "systemc/core/list.hh" #include "systemc/ext/core/sc_prim.hh" @@ -39,9 +41,9 @@ namespace sc_gem5 class Channel : public ListNode { public: - Channel(sc_core::sc_prim_channel *_sc_chan) : _sc_chan(_sc_chan) {} + Channel(sc_core::sc_prim_channel *_sc_chan); - virtual ~Channel() {} + virtual ~Channel(); void requestUpdate(); void asyncRequestUpdate(); @@ -53,6 +55,8 @@ class Channel : public ListNode sc_core::sc_prim_channel *_sc_chan; }; +extern std::set allChannels; + } // namespace sc_gem5 #endif //__SYSTEMC_CORE_CHANNEL_HH__ diff --git a/src/systemc/core/kernel.cc b/src/systemc/core/kernel.cc index 65a444536..84bdfd13f 100644 --- a/src/systemc/core/kernel.cc +++ b/src/systemc/core/kernel.cc @@ -30,6 +30,7 @@ #include "systemc/core/kernel.hh" #include "base/logging.hh" +#include "systemc/core/channel.hh" #include "systemc/core/module.hh" #include "systemc/core/scheduler.hh" @@ -67,8 +68,14 @@ Kernel::init() for (auto m: sc_gem5::allModules) { callbackModule(m); m->sc_mod()->before_end_of_elaboration(); + for (auto p: m->ports) + p->before_end_of_elaboration(); + for (auto e: m->exports) + e->before_end_of_elaboration(); } callbackModule(nullptr); + for (auto c: sc_gem5::allChannels) + c->sc_chan()->before_end_of_elaboration(); if (stopAfterCallbacks) stopWork(); @@ -82,8 +89,15 @@ Kernel::regStats() p->_gem5Finalize(); status(::sc_core::SC_END_OF_ELABORATION); - for (auto m: sc_gem5::allModules) + for (auto m: sc_gem5::allModules) { m->sc_mod()->end_of_elaboration(); + for (auto p: m->ports) + p->end_of_elaboration(); + for (auto e: m->exports) + e->end_of_elaboration(); + } + for (auto c: sc_gem5::allChannels) + c->sc_chan()->end_of_elaboration(); if (stopAfterCallbacks) stopWork(); @@ -93,8 +107,15 @@ void Kernel::startup() { status(::sc_core::SC_START_OF_SIMULATION); - for (auto m: sc_gem5::allModules) + for (auto m: sc_gem5::allModules) { m->sc_mod()->start_of_simulation(); + for (auto p: m->ports) + p->start_of_simulation(); + for (auto e: m->exports) + e->start_of_simulation(); + } + for (auto c: sc_gem5::allChannels) + c->sc_chan()->start_of_simulation(); startComplete = true; @@ -121,8 +142,15 @@ void Kernel::stopWork() { status(::sc_core::SC_END_OF_SIMULATION); - for (auto m: sc_gem5::allModules) + for (auto m: sc_gem5::allModules) { m->sc_mod()->end_of_simulation(); + for (auto p: m->ports) + p->end_of_simulation(); + for (auto e: m->exports) + e->end_of_simulation(); + } + for (auto c: sc_gem5::allChannels) + c->sc_chan()->end_of_simulation(); endComplete = true; diff --git a/src/systemc/core/module.hh b/src/systemc/core/module.hh index 0a6d9b7bb..e988b9667 100644 --- a/src/systemc/core/module.hh +++ b/src/systemc/core/module.hh @@ -44,6 +44,7 @@ namespace sc_core { class sc_port_base; +class sc_export_base; } // namespace sc_core @@ -111,6 +112,7 @@ class Module const char *uniqueName(const char *seed) { return nameGen.gen(seed); } std::vector<::sc_core::sc_port_base *> ports; + std::vector<::sc_core::sc_export_base *> exports; }; Module *currentModule(); diff --git a/src/systemc/core/sc_export.cc b/src/systemc/core/sc_export.cc index 8340cf9c6..383552b1a 100644 --- a/src/systemc/core/sc_export.cc +++ b/src/systemc/core/sc_export.cc @@ -28,12 +28,17 @@ */ #include "base/logging.hh" +#include "systemc/core/module.hh" #include "systemc/ext/core/sc_export.hh" namespace sc_core { -sc_export_base::sc_export_base(const char *n) : sc_object(n) {} +sc_export_base::sc_export_base(const char *n) : sc_object(n) +{ + ::sc_gem5::Module *m = ::sc_gem5::currentModule(); + m->exports.push_back(this); +} sc_export_base::~sc_export_base() {} } // namespace sc_core diff --git a/src/systemc/ext/core/sc_export.hh b/src/systemc/ext/core/sc_export.hh index f3cf81619..f5ce894b8 100644 --- a/src/systemc/ext/core/sc_export.hh +++ b/src/systemc/ext/core/sc_export.hh @@ -46,6 +46,14 @@ class sc_export_base : public sc_object virtual sc_interface *get_iterface() = 0; virtual const sc_interface *get_interface() const = 0; + + protected: + friend class sc_gem5::Kernel; + + virtual void before_end_of_elaboration() = 0; + virtual void end_of_elaboration() = 0; + virtual void start_of_simulation() = 0; + virtual void end_of_simulation() = 0; }; template @@ -74,10 +82,10 @@ class sc_export : public sc_export_base const sc_interface *get_interface() const override { return interface; } protected: - virtual void before_end_of_elaboration() {} - virtual void end_of_elaboration() {} - virtual void start_of_simulation() {} - virtual void end_of_simulation() {} + void before_end_of_elaboration() {} + void end_of_elaboration() {} + void start_of_simulation() {} + void end_of_simulation() {} private: IF *interface; diff --git a/src/systemc/ext/core/sc_port.hh b/src/systemc/ext/core/sc_port.hh index 6031d5495..73f5362b6 100644 --- a/src/systemc/ext/core/sc_port.hh +++ b/src/systemc/ext/core/sc_port.hh @@ -75,6 +75,11 @@ class sc_port_base : public sc_object virtual int vbind(sc_interface &) = 0; virtual int vbind(sc_port_base &) = 0; + virtual void before_end_of_elaboration() = 0; + virtual void end_of_elaboration() = 0; + virtual void start_of_simulation() = 0; + virtual void end_of_simulation() = 0; + private: friend class ::sc_gem5::PendingSensitivityPort; friend class ::sc_gem5::Kernel; @@ -110,10 +115,10 @@ class sc_port_b : public sc_port_base const sc_interface *get_interface() const { return _interfaces.at(0); } protected: - virtual void before_end_of_elaboration() {} - virtual void end_of_elaboration() {} - virtual void start_of_elaboration() {} - virtual void end_of_simulation() {} + void before_end_of_elaboration() {} + void end_of_elaboration() {} + void start_of_simulation() {} + void end_of_simulation() {} explicit sc_port_b(int n, sc_port_policy p) : sc_port_base(sc_gen_unique_name("port"), n, p) diff --git a/src/systemc/ext/core/sc_prim.hh b/src/systemc/ext/core/sc_prim.hh index 106489280..99e231456 100644 --- a/src/systemc/ext/core/sc_prim.hh +++ b/src/systemc/ext/core/sc_prim.hh @@ -91,6 +91,8 @@ class sc_prim_channel : public sc_object void wait(const sc_time &, const sc_event_and_list &); void wait(double, sc_time_unit, const sc_event_and_list &); + friend class sc_gem5::Kernel; + virtual void before_end_of_elaboration() {} virtual void end_of_elaboration() {} virtual void start_of_simulation() {} -- 2.30.2