systemc: Implement port binding except positional binding.
authorGabe Black <gabeblack@google.com>
Tue, 14 Aug 2018 01:19:15 +0000 (18:19 -0700)
committerGabe Black <gabeblack@google.com>
Thu, 20 Sep 2018 01:47:05 +0000 (01:47 +0000)
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>

src/systemc/core/kernel.cc
src/systemc/core/module.hh
src/systemc/core/process.hh
src/systemc/core/sc_port.cc
src/systemc/ext/core/sc_port.hh

index 4eb0bb7653f1c8b6303be701ac0ad4c2658464fb..65a444536c86ef54e091da1b1f19da26f07c65af 100644 (file)
@@ -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();
index a5bf9297565fc44117d5d9a0224e9efc8a2f94ae..0a6d9b7bb4484e1cd9c1fef7384b09b6126e4e39 100644 (file)
 #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();
index 5f0a72d1e0e770f6e19c9188c63c92a0857014f0..33dcf870d1c195b3ec1c5c6d874b128f5d6766ef 100644 (file)
@@ -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));
         }
     }
index ad228548fd80f7b3f3af56871c855e96f5cd08c0..d10ceeab3289cae88a1b1b45c19f6c9dfc88d904 100644 (file)
 
 #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
index fb7b76d2699d4a77195c332125d86802f7870b9a..6031d549502bb8402609f03ac7a3290b9df03d4b 100644 (file)
@@ -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> &) {}