mem, sim, systemc: Reorganize Port and co.s bind, unbind slightly.
authorGabe Black <gabeblack@google.com>
Fri, 16 Aug 2019 22:27:35 +0000 (15:27 -0700)
committerGabe Black <gabeblack@google.com>
Tue, 27 Aug 2019 22:17:45 +0000 (22:17 +0000)
The base Port class can keep track of its peer, and also whether it's
connected. This is partially delegated away from the port subclasses
which still keep track of a cast version of their peer pointer for
their own conveneince, so that it can be used by generic code. Even
with the Port mechanism's new flexibility, each port still has
exactly one peer and is either connected or not based on whether there
is a peer currently.

Change-Id: Id3228617dd1604d196814254a1aadeac5ade7cde
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20232
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Gabe Black <gabeblack@google.com>

src/mem/port.cc
src/mem/port.hh
src/sim/port.cc
src/sim/port.hh
src/systemc/sc_port_wrapper.hh
src/systemc/tlm_port_wrapper.hh

index 40481b0bbc7ef25355b04b51cd3b0a05063f4264..303d1bc413388b85ec21844b165cf973be25faa0 100644 (file)
@@ -70,6 +70,22 @@ BaseMasterPort::getSlavePort() const
     return *_baseSlavePort;
 }
 
+void
+BaseMasterPort::bind(Port &peer)
+{
+    _baseSlavePort = dynamic_cast<BaseSlavePort *>(&peer);
+    fatal_if(!_baseSlavePort, "Attempt to bind port %s to non-master port %s.",
+             name(), peer.name());
+    Port::bind(peer);
+}
+
+void
+BaseMasterPort::unbind()
+{
+    _baseSlavePort = nullptr;
+    Port::unbind();
+}
+
 BaseSlavePort::BaseSlavePort(const std::string &name, PortID _id)
     : Port(name, _id), _baseMasterPort(NULL)
 {
@@ -89,6 +105,22 @@ BaseSlavePort::getMasterPort() const
     return *_baseMasterPort;
 }
 
+void
+BaseSlavePort::bind(Port &peer)
+{
+    _baseMasterPort = dynamic_cast<BaseMasterPort *>(&peer);
+    fatal_if(!_baseMasterPort, "Attempt to bind port %s to non-slave port %s.",
+             name(), peer.name());
+    Port::bind(peer);
+}
+
+void
+BaseSlavePort::unbind()
+{
+    _baseMasterPort = nullptr;
+    Port::unbind();
+}
+
 /**
  * Master port
  */
@@ -109,12 +141,9 @@ MasterPort::bind(Port &peer)
         fatal("Attempt to bind port %s to non-slave port %s.",
                 name(), peer.name());
     }
-    // bind on the level of the base ports
-    _baseSlavePort = slave_port;
-
     // master port keeps track of the slave port
     _slavePort = slave_port;
-    _connected = true;
+    BaseMasterPort::bind(peer);
     // slave port also keeps track of master port
     _slavePort->slaveBind(*this);
 }
@@ -126,9 +155,8 @@ MasterPort::unbind()
         panic("Attempting to unbind master port %s that is not connected\n",
               name());
     _slavePort->slaveUnbind();
-    _slavePort = NULL;
-    _connected = false;
-    _baseSlavePort = NULL;
+    _slavePort = nullptr;
+    BaseMasterPort::unbind();
 }
 
 AddrRangeList
@@ -166,17 +194,15 @@ SlavePort::~SlavePort()
 void
 SlavePort::slaveUnbind()
 {
-    _baseMasterPort = NULL;
     _masterPort = NULL;
-    _connected = false;
+    BaseSlavePort::unbind();
 }
 
 void
 SlavePort::slaveBind(MasterPort& master_port)
 {
-    _baseMasterPort = &master_port;
     _masterPort = &master_port;
-    _connected = true;
+    BaseSlavePort::bind(master_port);
 }
 
 Tick
index 847bd1e7dc81ce54c18ab679ebc30cfbcea38dfd..0b589dafc78ff685c03f29a81949a1887de0a7f8 100644 (file)
@@ -78,6 +78,8 @@ class BaseMasterPort : public Port
 
   public:
     BaseSlavePort& getSlavePort() const;
+    void bind(Port &peer) override;
+    void unbind() override;
 };
 
 /**
@@ -94,6 +96,8 @@ class BaseSlavePort : public Port
 
   public:
     BaseMasterPort& getMasterPort() const;
+    void bind(Port &peer) override;
+    void unbind() override;
 };
 
 /** Forward declaration */
index b3139a630a639c0067a5345a154b26075cbcd059..fa7df18cf01c0cd555bca601bbc5555db18f5aa0 100644 (file)
@@ -50,6 +50,6 @@
 #include "sim/port.hh"
 
 Port::Port(const std::string& _name, PortID _id) :
-    portName(_name), id(_id), _connected(false)
+    portName(_name), id(_id), _peer(nullptr), _connected(false)
 {}
 Port::~Port() {}
index e1811643f555fd7f0e42329128c00173028abb41..ee4b548a5e019ed5c16fe20e73a6688af81a6c21 100644 (file)
@@ -72,6 +72,13 @@ class Port
      * to InvalidPortID in case this port is not part of a vector.
      */
     const PortID id;
+
+    /**
+     * A pointer to this port's peer.
+     */
+    Port *_peer;
+
+
     /**
      * Whether this port is currently connected to a peer port.
      */
@@ -92,6 +99,9 @@ class Port
 
   public:
 
+    /** Return a reference to this port's peer. */
+    Port &getPeer() { return *_peer; }
+
     /** Return port name (for DPRINTF). */
     const std::string name() const { return portName; }
 
@@ -99,10 +109,20 @@ class Port
     PortID getId() const { return id; }
 
     /** Attach to a peer port. */
-    virtual void bind(Port &peer) = 0;
+    virtual void
+    bind(Port &peer)
+    {
+        _peer = &peer;
+        _connected = true;
+    }
 
     /** Dettach from a peer port. */
-    virtual void unbind() = 0;
+    virtual void
+    unbind()
+    {
+        _peer = nullptr;
+        _connected = false;
+    }
 
     /** Is this port currently connected to a peer? */
     bool isConnected() const { return _connected; }
index b6f6f8504a0286a0ea05b995c804dade5a770429..9f7d80de83bc639376c2c008b7e55482b40db95e 100644 (file)
@@ -85,6 +85,7 @@ class ScPortWrapper : public ::Port
             fatal("Attempt to bind sc_port %s to incompatible port %s.",
                   name(), peer.name());
         }
+        Port::bind(peer);
     }
 
   private:
@@ -123,6 +124,7 @@ class ScInterfaceWrapper : public ::Port
         // Don't bind to peer otherwise we may have error messages saying that
         // this interface has already be bound since the peer may already did
         // that. Just let sc_port or sc_export do the binding
+        Port::bind(peer);
     }
 
   private:
@@ -160,6 +162,7 @@ class ScExportWrapper : public ::Port
                  name(), peer.name());
 
         port_.bind(iface->interface());
+        Port::bind(peer);
     }
 
   private:
index 0553a18ef96df40c214914bce01705e330486fc9..59f8d9fe00c8415bfd30c24aefe67b96c69040e9 100644 (file)
@@ -74,6 +74,7 @@ class TlmInitiatorWrapper : public ::Port
                 "incompatible port %s.", name(), peer.name());
 
         initiator().bind(target->target());
+        Port::bind(peer);
     }
 
     void
@@ -107,6 +108,7 @@ class TlmTargetWrapper : public ::Port
     {
         // Ignore attempts to bind a target socket. The initiator will
         // handle it.
+        Port::bind(peer);
     }
 
     void