summaryrefslogtreecommitdiff
path: root/src/systemc
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2018-08-13 18:19:15 -0700
committerGabe Black <gabeblack@google.com>2018-09-20 01:47:05 +0000
commit8e91764a3642c3ef5e630d02908f8c9072d5b538 (patch)
tree2c7f8f759781dea2cb3eb689a8850b6f7e113dfd /src/systemc
parent1e091040f93ef99a639980a70c2204cb3caadfaa (diff)
downloadgem5-8e91764a3642c3ef5e630d02908f8c9072d5b538.tar.xz
systemc: Implement port binding except positional binding.
This change adds code which keeps track of ports and interfaces which are being bound to be finalized later, and the actual port binding of interfaces and recursive binding port ports. Change-Id: Ifa885ed44b667254762cc101580be4f0a7d7a131 Reviewed-on: https://gem5-review.googlesource.com/12084 Reviewed-by: Gabe Black <gabeblack@google.com> Maintainer: Gabe Black <gabeblack@google.com>
Diffstat (limited to 'src/systemc')
-rw-r--r--src/systemc/core/kernel.cc4
-rw-r--r--src/systemc/core/module.hh10
-rw-r--r--src/systemc/core/process.hh2
-rw-r--r--src/systemc/core/sc_port.cc44
-rw-r--r--src/systemc/ext/core/sc_port.hh112
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> &) {}