systemc: Implement positional binding.
authorGabe Black <gabeblack@google.com>
Fri, 24 Aug 2018 00:55:18 +0000 (17:55 -0700)
committerGabe Black <gabeblack@google.com>
Wed, 26 Sep 2018 00:01:23 +0000 (00:01 +0000)
Change-Id: Ifbcd7e4148b82b9bf5241e040e812925daea3705
Reviewed-on: https://gem5-review.googlesource.com/12263
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>

src/systemc/core/module.cc
src/systemc/core/module.hh
src/systemc/core/sc_module.cc
src/systemc/ext/core/sc_module.hh
src/systemc/ext/core/sc_port.hh

index 0c118e0c5d17a33cbf7c74ffd2f52f55c32c4be9..78ce2c6fbd14bad7c8aa6ca8a4548ab43c618c58 100644 (file)
@@ -32,6 +32,7 @@
 #include <cassert>
 
 #include "base/logging.hh"
+#include "systemc/ext/core/sc_port.hh"
 #include "systemc/ext/utils/sc_report_handler.hh"
 
 namespace sc_gem5
@@ -85,6 +86,25 @@ Module::pop()
     _modules.pop_back();
 }
 
+void
+Module::bindPorts(std::vector<const ::sc_core::sc_bind_proxy *> &proxies)
+{
+    panic_if(proxies.size() > ports.size(),
+            "Trying to bind %d interfaces/ports to %d ports.\n",
+            proxies.size(), ports.size());
+
+    auto proxyIt = proxies.begin();
+    auto portIt = ports.begin();
+    for (; proxyIt != proxies.end(); proxyIt++, portIt++) {
+        auto proxy = *proxyIt;
+        auto port = *portIt;
+        if (proxy->interface())
+            port->vbind(*proxy->interface());
+        else
+            port->vbind(*proxy->port());
+    }
+}
+
 Module *
 currentModule()
 {
index e276dad199dce12f1a1dfd25fdb7ad42e47a4db5..e60018e2b9aae147e33a9b6aa4e304be9b10b034 100644 (file)
@@ -111,6 +111,8 @@ class Module
 
     const char *uniqueName(const char *seed) { return nameGen.gen(seed); }
 
+    void bindPorts(std::vector<const ::sc_core::sc_bind_proxy *> &proxies);
+
     std::vector<::sc_core::sc_port_base *> ports;
     std::vector<::sc_core::sc_export_base *> exports;
 };
index c515aaf0980795fbbf6122f44d9eb3045f8af7a1..bbb9993be636c0e886bf31c2ec7ed47f77e1a509 100644 (file)
@@ -72,19 +72,19 @@ UniqueNameGen nameGen;
 namespace sc_core
 {
 
-sc_bind_proxy::sc_bind_proxy(const sc_interface &_interface) :
+sc_bind_proxy::sc_bind_proxy(sc_interface &_interface) :
     _interface(&_interface), _port(nullptr)
 {}
 
-sc_bind_proxy::sc_bind_proxy(const sc_port_base &_port) :
+sc_bind_proxy::sc_bind_proxy(sc_port_base &_port) :
     _interface(nullptr), _port(&_port)
 {}
 
-const sc_bind_proxy SC_BIND_PROXY_NUL(*(const sc_port_base *)nullptr);
+const sc_bind_proxy SC_BIND_PROXY_NUL(*(sc_port_base *)nullptr);
 
 sc_module::~sc_module() { delete _gem5_module; }
 
-const sc_bind_proxy SC_BIND_PROXY_NIL(*(const sc_port_base *)nullptr);
+const sc_bind_proxy SC_BIND_PROXY_NIL(*(sc_port_base *)nullptr);
 
 void
 sc_module::operator () (const sc_bind_proxy &p001,
@@ -152,7 +152,30 @@ sc_module::operator () (const sc_bind_proxy &p001,
                         const sc_bind_proxy &p063,
                         const sc_bind_proxy &p064)
 {
-    warn("%s not implemented.\n", __PRETTY_FUNCTION__);
+    std::vector<const ::sc_core::sc_bind_proxy *> proxies;
+    auto insert = [&proxies](const ::sc_core::sc_bind_proxy &p) -> bool {
+        if (!p.port() && !p.interface())
+            return false;
+        proxies.push_back(&p);
+        return true;
+    };
+    insert(p001) && insert(p002) && insert(p003) && insert(p004) &&
+    insert(p005) && insert(p006) && insert(p007) && insert(p008) &&
+    insert(p009) && insert(p010) && insert(p011) && insert(p012) &&
+    insert(p013) && insert(p014) && insert(p015) && insert(p016) &&
+    insert(p017) && insert(p018) && insert(p019) && insert(p020) &&
+    insert(p021) && insert(p022) && insert(p023) && insert(p024) &&
+    insert(p025) && insert(p026) && insert(p027) && insert(p028) &&
+    insert(p029) && insert(p030) && insert(p031) && insert(p032) &&
+    insert(p033) && insert(p034) && insert(p035) && insert(p036) &&
+    insert(p037) && insert(p038) && insert(p039) && insert(p040) &&
+    insert(p041) && insert(p042) && insert(p043) && insert(p044) &&
+    insert(p045) && insert(p046) && insert(p047) && insert(p048) &&
+    insert(p049) && insert(p050) && insert(p051) && insert(p052) &&
+    insert(p053) && insert(p054) && insert(p055) && insert(p056) &&
+    insert(p057) && insert(p058) && insert(p059) && insert(p060) &&
+    insert(p061) && insert(p062) && insert(p063) && insert(p064);
+    _gem5_module->bindPorts(proxies);
 }
 
 const std::vector<sc_object *> &
index 8de57b57562b02d198b54e4249a4da80cb4afb79..539d275ece51c4bf861c1294b1b1d8d9f1709779 100644 (file)
@@ -78,14 +78,15 @@ class sc_module_name;
 class sc_bind_proxy
 {
   private:
-    const sc_interface *_interface;
-    const sc_port_base *_port;
-
-    friend class sc_module;
+    sc_interface *_interface;
+    sc_port_base *_port;
 
   public:
-    sc_bind_proxy(const sc_interface &_interface);
-    sc_bind_proxy(const sc_port_base &_port);
+    sc_bind_proxy(sc_interface &_interface);
+    sc_bind_proxy(sc_port_base &_port);
+
+    sc_interface *interface() const { return _interface; }
+    sc_port_base *port() const { return _port; }
 };
 
 extern const sc_bind_proxy SC_BIND_PROXY_NIL;
index f9e50da2ea5489bcdd1d92b7c4af1ef43d97a044..b392359602e484081db353d569b880c1fc3573af 100644 (file)
@@ -40,6 +40,7 @@ namespace sc_gem5
 {
 
 class BindInfo;
+class Module;
 class PendingSensitivityPort;
 
 };
@@ -71,6 +72,8 @@ class sc_port_base : public sc_object
     void bind(sc_interface &);
     void bind(sc_port_base &);
 
+    friend class ::sc_gem5::Module;
+
     // Implementation defined, but depended on by the tests.
     virtual int vbind(sc_interface &) = 0;
     virtual int vbind(sc_port_base &) = 0;