diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/systemc/core/kernel.cc | 4 | ||||
-rw-r--r-- | src/systemc/core/module.hh | 10 | ||||
-rw-r--r-- | src/systemc/core/process.hh | 2 | ||||
-rw-r--r-- | src/systemc/core/sc_port.cc | 44 | ||||
-rw-r--r-- | src/systemc/ext/core/sc_port.hh | 112 |
5 files changed, 92 insertions, 80 deletions
diff --git a/src/systemc/core/kernel.cc b/src/systemc/core/kernel.cc index 4eb0bb765..65a444536 100644 --- a/src/systemc/core/kernel.cc +++ b/src/systemc/core/kernel.cc @@ -77,6 +77,10 @@ Kernel::init() void Kernel::regStats() { + for (auto m: sc_gem5::allModules) + for (auto p: m->ports) + p->_gem5Finalize(); + status(::sc_core::SC_END_OF_ELABORATION); for (auto m: sc_gem5::allModules) m->sc_mod()->end_of_elaboration(); diff --git a/src/systemc/core/module.hh b/src/systemc/core/module.hh index a5bf92975..0a6d9b7bb 100644 --- a/src/systemc/core/module.hh +++ b/src/systemc/core/module.hh @@ -35,10 +35,18 @@ #include <map> #include <sstream> #include <string> +#include <vector> #include "systemc/core/object.hh" #include "systemc/ext/core/sc_module.hh" +namespace sc_core +{ + +class sc_port_base; + +} // namespace sc_core + namespace sc_gem5 { @@ -101,6 +109,8 @@ class Module void pop(); const char *uniqueName(const char *seed) { return nameGen.gen(seed); } + + std::vector<::sc_core::sc_port_base *> ports; }; Module *currentModule(); diff --git a/src/systemc/core/process.hh b/src/systemc/core/process.hh index 5f0a72d1e..33dcf870d 100644 --- a/src/systemc/core/process.hh +++ b/src/systemc/core/process.hh @@ -221,7 +221,7 @@ class PendingSensitivityPort : public PendingSensitivity { for (int i = 0; i < port->size(); i++) { const ::sc_core::sc_event *e = - &port->_gem5BindInfo[i]->interface->default_event(); + &port->_gem5Interface(i)->default_event(); s.push_back(new SensitivityEvent(process, e)); } } diff --git a/src/systemc/core/sc_port.cc b/src/systemc/core/sc_port.cc index ad228548f..d10ceeab3 100644 --- a/src/systemc/core/sc_port.cc +++ b/src/systemc/core/sc_port.cc @@ -29,14 +29,18 @@ #include "base/logging.hh" #include "systemc/core/bindinfo.hh" +#include "systemc/core/module.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) -{} + sc_object(name), _maxSize(n), _size(0), finalized(false) +{ + ::sc_gem5::Module *m = ::sc_gem5::currentModule(); + m->ports.push_back(this); +} void sc_port_base::warn_unimpl(const char *func) const @@ -45,18 +49,44 @@ sc_port_base::warn_unimpl(const char *func) const } int sc_port_base::maxSize() const { return _maxSize; } -int sc_port_base::size() const { return _gem5BindInfo.size(); } +int sc_port_base::size() const { return _size; } + +void +sc_port_base::bind(sc_interface &i) +{ + _gem5BindInfo.push_back(new ::sc_gem5::BindInfo(&i)); +} void -sc_port_base::bind(sc_interface &) +sc_port_base::bind(sc_port_base &p) { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + _gem5BindInfo.push_back(new ::sc_gem5::BindInfo(&p)); } void -sc_port_base::bind(sc_port_base &) +sc_port_base::_gem5Finalize() { - warn("%s not implemented.\n", __PRETTY_FUNCTION__); + if (finalized) + return; + finalized = true; + + for (auto &bi: _gem5BindInfo) { + if (bi->interface) { + _size++; + _gem5AddInterface(bi->interface); + } else { + sc_port_base *port = bi->port; + port->_gem5Finalize(); + int size = port->size(); + for (int i = 0; i < size; i++) { + _size++; + _gem5AddInterface(port->_gem5Interface(i)); + } + } + delete bi; + } + + _gem5BindInfo.clear(); } } // namespace sc_core diff --git a/src/systemc/ext/core/sc_port.hh b/src/systemc/ext/core/sc_port.hh index fb7b76d26..6031d5495 100644 --- a/src/systemc/ext/core/sc_port.hh +++ b/src/systemc/ext/core/sc_port.hh @@ -32,6 +32,7 @@ #include <vector> +#include "../utils/sc_report_handler.hh" #include "sc_module.hh" // for sc_gen_unique_name #include "sc_object.hh" @@ -76,87 +77,37 @@ class sc_port_base : public sc_object private: friend class ::sc_gem5::PendingSensitivityPort; + friend class ::sc_gem5::Kernel; + + void _gem5Finalize(); + + virtual sc_interface *_gem5Interface(int n) const = 0; + virtual void _gem5AddInterface(sc_interface *i) = 0; std::vector<::sc_gem5::BindInfo *> _gem5BindInfo; int _maxSize; + int _size; + bool finalized; }; template <class IF> class sc_port_b : public sc_port_base { public: - void - operator () (IF &) - { - this->warn_unimpl(__PRETTY_FUNCTION__); - } - - void - operator () (sc_port_b<IF> &) - { - this->warn_unimpl(__PRETTY_FUNCTION__); - } - - virtual void - bind(IF &) - { - this->warn_unimpl(__PRETTY_FUNCTION__); - } - - virtual void - bind(sc_port_b<IF> &) - { - this->warn_unimpl(__PRETTY_FUNCTION__); - } - - int - size() const - { - this->warn_unimpl(__PRETTY_FUNCTION__); - return 0; - } - - IF * - operator -> () - { - this->warn_unimpl(__PRETTY_FUNCTION__); - return (IF *)nullptr; - } + void operator () (IF &i) { bind(i); } + void operator () (sc_port_b<IF> &p) { bind(p); } - const IF * - operator -> () const - { - this->warn_unimpl(__PRETTY_FUNCTION__); - return (IF *)nullptr; - } + virtual void bind(IF &i) { sc_port_base::bind(i); } + virtual void bind(sc_port_b<IF> &p) { sc_port_base::bind(p); } - IF * - operator [] (int) - { - this->warn_unimpl(__PRETTY_FUNCTION__); - return (IF *)nullptr; - } - - const IF * - operator [] (int) const - { - this->warn_unimpl(__PRETTY_FUNCTION__); - return (IF *)nullptr; - } + IF *operator -> () { return _interfaces.at(0); } + const IF *operator -> () const { return _interfaces.at(0); } - virtual sc_interface * - get_interface() - { - this->warn_unimpl(__PRETTY_FUNCTION__); - return (sc_interface *)nullptr; - } + IF *operator [] (int n) { return _interfaces.at(n); } + const IF *operator [] (int n) const { return _interfaces.at(n); } - virtual const sc_interface * - get_interface() const - { - this->warn_unimpl(__PRETTY_FUNCTION__); - return (sc_interface *)nullptr; - } + sc_interface *get_interface() { return _interfaces.at(0); } + const sc_interface *get_interface() const { return _interfaces.at(0); } protected: virtual void before_end_of_elaboration() {} @@ -174,19 +125,36 @@ class sc_port_b : public sc_port_base // Implementation defined, but depended on by the tests. int - vbind(sc_interface &) + vbind(sc_interface &i) { - this->warn_unimpl(__PRETTY_FUNCTION__); + IF *interface = dynamic_cast<IF *>(&i); + if (!interface) + return 2; + sc_port_base::bind(*interface); return 0; } int - vbind(sc_port_base &) + vbind(sc_port_base &pb) { - this->warn_unimpl(__PRETTY_FUNCTION__); + sc_port_b<IF> *p = dynamic_cast<sc_port_b<IF> *>(&pb); + if (!p) + return 2; + sc_port_base::bind(*p); return 0; } private: + std::vector<IF *> _interfaces; + + sc_interface *_gem5Interface(int n) const { return _interfaces.at(n); } + void + _gem5AddInterface(sc_interface *i) + { + IF *interface = dynamic_cast<IF *>(i); + sc_assert(interface); + _interfaces.push_back(interface); + } + // Disabled sc_port_b() {} sc_port_b(const sc_port_b<IF> &) {} |