mem-ruby: more specialized address to node mapping
authorTiago Mück <tiago.muck@arm.com>
Wed, 4 Sep 2019 17:26:02 +0000 (12:26 -0500)
committerTiago Mück <tiago.muck@arm.com>
Tue, 13 Oct 2020 15:25:34 +0000 (15:25 +0000)
Added mapAddressToDownstreamMachine that may be used by the protocols
to map an address to different target donwstream controller of the same
type.

These functions do not use the global mapping provided by the network
and map addresses to one of the controllers specified in the
downstream_destinations parameter.

This change facilitates reusing the same cache state-machine/controllers
to model different levels of the cache hierarchy.

Change-Id: I9a202e9461e0d2f16ed232ff8b60bbde2d15570d
Signed-off-by: Tiago Mück <tiago.muck@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/31415
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/mem/ruby/common/MachineID.hh
src/mem/ruby/slicc_interface/AbstractController.cc
src/mem/ruby/slicc_interface/AbstractController.hh
src/mem/ruby/slicc_interface/Controller.py

index 3ef7b8876ed03e6b55750971054b32b6e37f552b..3d0827f4f43621ba2ea5ff87632e3283d2fd7dc7 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2020 ARM Limited
+ * All rights reserved.
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
  * All rights reserved.
  *
@@ -37,7 +49,7 @@
 
 struct MachineID
 {
-    MachineID() : type(MachineType_NULL), num(0) { }
+    MachineID() : type(MachineType_NUM), num(0) { }
     MachineID(MachineType mach_type, NodeID node_id)
         : type(mach_type), num(node_id) { }
 
@@ -47,6 +59,8 @@ struct MachineID
 
     MachineType getType() const { return type; }
     NodeID getNum() const { return num; }
+
+    bool isValid() const { return type != MachineType_NUM; }
 };
 
 inline std::string
index 5d9e5f680d9be78879a6670a2e854deb4670e0fe..a211c558aaef3ec342e321dd37f7b814db419bff 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017,2019 ARM Limited
+ * Copyright (c) 2017,2019,2020 ARM Limited
  * All rights reserved.
  *
  * The license below extends only to copyright in the software and shall
@@ -78,6 +78,29 @@ AbstractController::init()
     if (getMemReqQueue()) {
         getMemReqQueue()->setConsumer(this);
     }
+
+    // Initialize the addr->downstream machine mappings. Multiple machines
+    // in downstream_destinations can have the same address range if they have
+    // different types. If this is the case, mapAddressToDownstreamMachine
+    // needs to specify the machine type
+    downstreamDestinations.resize();
+    for (auto abs_cntrl : params()->downstream_destinations) {
+        MachineID mid = abs_cntrl->getMachineID();
+        const AddrRangeList &ranges = abs_cntrl->getAddrRanges();
+        for (const auto addr_range : ranges) {
+            auto i = downstreamAddrMap.intersects(addr_range);
+            if (i == downstreamAddrMap.end()) {
+                i = downstreamAddrMap.insert(addr_range, AddrMapEntry());
+            }
+            AddrMapEntry &entry = i->second;
+            fatal_if(entry.count(mid.getType()) > 0,
+                     "%s: %s mapped to multiple machines of the same type\n",
+                     name(), addr_range.to_string());
+            entry[mid.getType()] = mid;
+        }
+        downstreamDestinations.add(mid);
+    }
+
 }
 
 void
@@ -357,6 +380,30 @@ AbstractController::mapAddressToMachine(Addr addr, MachineType mtype) const
     return mach;
 }
 
+MachineID
+AbstractController::mapAddressToDownstreamMachine(Addr addr, MachineType mtype)
+const
+{
+    const auto i = downstreamAddrMap.contains(addr);
+    fatal_if(i == downstreamAddrMap.end(),
+      "%s: couldn't find mapping for address %x\n", name(), addr);
+
+    const AddrMapEntry &entry = i->second;
+    assert(!entry.empty());
+
+    if (mtype == MachineType_NUM) {
+        fatal_if(entry.size() > 1,
+          "%s: address %x mapped to multiple machine types.\n", name(), addr);
+        return entry.begin()->second;
+    } else {
+        auto j = entry.find(mtype);
+        fatal_if(j == entry.end(),
+          "%s: couldn't find mapping for address %x\n", name(), addr);
+        return j->second;
+    }
+}
+
+
 bool
 AbstractController::MemoryPort::recvTimingResp(PacketPtr pkt)
 {
index 28103f98ee66ccae8bbc3552d832e9aac772afb8..2f3355686726f1e974d4c87b0be86536d9ea35ed 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017,2019 ARM Limited
+ * Copyright (c) 2017,2019,2020 ARM Limited
  * All rights reserved.
  *
  * The license below extends only to copyright in the software and shall
 #include <exception>
 #include <iostream>
 #include <string>
+#include <unordered_map>
 
 #include "base/addr_range.hh"
+#include "base/addr_range_map.hh"
 #include "base/callback.hh"
 #include "mem/packet.hh"
 #include "mem/qport.hh"
@@ -175,6 +177,22 @@ class AbstractController : public ClockedObject, public Consumer
      */
     MachineID mapAddressToMachine(Addr addr, MachineType mtype) const;
 
+    /**
+     * Maps an address to the correct dowstream MachineID (i.e. the component
+     * in the next level of the cache hierarchy towards memory)
+     *
+     * This function uses the local list of possible destinations instead of
+     * querying the network.
+     *
+     * @param the destination address
+     * @param the type of the destination (optional)
+     * @return the MachineID of the destination
+     */
+    MachineID mapAddressToDownstreamMachine(Addr addr,
+                                    MachineType mtype = MachineType_NUM) const;
+
+    const NetDest& allDownstreamDest() const { return downstreamDestinations; }
+
   protected:
     //! Profiles original cache requests including PUTs
     void profileRequest(const std::string &request);
@@ -338,6 +356,13 @@ class AbstractController : public ClockedObject, public Consumer
   private:
     /** The address range to which the controller responds on the CPU side. */
     const AddrRangeList addrRanges;
+
+    typedef std::unordered_map<MachineType, MachineID> AddrMapEntry;
+
+    AddrRangeMap<AddrMapEntry, 3> downstreamAddrMap;
+
+    NetDest downstreamDestinations;
+
 };
 
 #endif // __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCONTROLLER_HH__
index 1f9c0dbb850278db7b0f768b37c579cc751009be..ee6ca60e44052154395f4c0a2fa57db12af92427 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2017,2019 ARM Limited
+# Copyright (c) 2017,2019,2020 ARM Limited
 # All rights reserved.
 #
 # The license below extends only to copyright in the software and shall
@@ -71,3 +71,8 @@ class RubyController(ClockedObject):
         "memory output to the main memory is now called `memory_out_port`")
 
     system = Param.System(Parent.any, "system object parameter")
+
+    # These can be used by a protocol to enable reuse of the same machine
+    # types to model different levels of the cache hierarchy
+    downstream_destinations = VectorParam.RubyController([],
+                    "Possible destinations for requests sent towards memory")