mem-cache: Use header delay on latency calculation

Previously the bus delay was being ignored for the access latency
calculation, and then applied on top of the access latency. This
patch fixes the order, as first the packet must arrive before the
access starts.

Change-Id: I6d55299a911d54625c147814dd423bfc63ef1b65
Signed-off-by: Daniel R. Carvalho <odanrc@yahoo.com.br>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/14876
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>
diff --git a/src/mem/cache/base.cc b/src/mem/cache/base.cc
index 0949e49..d4e93c0 100644
--- a/src/mem/cache/base.cc
+++ b/src/mem/cache/base.cc
@@ -365,7 +365,7 @@
     // The latency charged is just the value set by the access() function.
     // In case of a hit we are neglecting response latency.
     // In case of a miss we are neglecting forward latency.
-    Tick request_time = clockEdge(lat) + pkt->headerDelay;
+    Tick request_time = clockEdge(lat);
     // Here we reset the timing of the packet.
     pkt->headerDelay = pkt->payloadDelay = 0;
 
@@ -889,27 +889,33 @@
 //
 /////////////////////////////////////////////////////
 Cycles
-BaseCache::calculateAccessLatency(const CacheBlk* blk,
+BaseCache::calculateAccessLatency(const CacheBlk* blk, const uint32_t delay,
                                   const Cycles lookup_lat) const
 {
-    Cycles lat(lookup_lat);
+    Cycles lat(0);
 
     if (blk != nullptr) {
-        // First access tags, then data
+        // As soon as the access arrives, for sequential accesses first access
+        // tags, then the data entry. In the case of parallel accesses the
+        // latency is dictated by the slowest of tag and data latencies.
         if (sequentialAccess) {
-            lat += dataLatency;
-        // Latency is dictated by the slowest of tag and data latencies
+            lat = ticksToCycles(delay) + lookup_lat + dataLatency;
         } else {
-            lat = std::max(lookup_lat, dataLatency);
+            lat = ticksToCycles(delay) + std::max(lookup_lat, dataLatency);
         }
 
         // Check if the block to be accessed is available. If not, apply the
         // access latency on top of when the block is ready to be accessed.
+        const Tick tick = curTick() + delay;
         const Tick when_ready = blk->getWhenReady();
-        if (when_ready > curTick() &&
-            ticksToCycles(when_ready - curTick()) > lat) {
-            lat += ticksToCycles(when_ready - curTick());
+        if (when_ready > tick &&
+            ticksToCycles(when_ready - tick) > lat) {
+            lat += ticksToCycles(when_ready - tick);
         }
+    } else {
+        // In case of a miss, apply lookup latency on top of the metadata
+        // delay, as the access can only start when it arrives.
+        lat = ticksToCycles(delay) + lookup_lat;
     }
 
     return lat;
@@ -930,8 +936,10 @@
     Cycles tag_latency(0);
     blk = tags->accessBlock(pkt->getAddr(), pkt->isSecure(), tag_latency);
 
-    // Calculate access latency
-    lat = calculateAccessLatency(blk, tag_latency);
+    // Calculate access latency on top of when the packet arrives. This
+    // takes into account the bus delay.
+    lat = calculateAccessLatency(blk, pkt->headerDelay,
+                                 tag_latency);
 
     DPRINTF(Cache, "%s for %s %s\n", __func__, pkt->print(),
             blk ? "hit " + blk->print() : "miss");
diff --git a/src/mem/cache/base.hh b/src/mem/cache/base.hh
index 1137241..7bf7411 100644
--- a/src/mem/cache/base.hh
+++ b/src/mem/cache/base.hh
@@ -426,10 +426,11 @@
      * whether access was a hit or miss.
      *
      * @param blk The cache block that was accessed.
+     * @param delay The delay until the packet's metadata is present.
      * @param lookup_lat Latency of the respective tag lookup.
      * @return The number of ticks that pass due to a block access.
      */
-    Cycles calculateAccessLatency(const CacheBlk* blk,
+    Cycles calculateAccessLatency(const CacheBlk* blk, const uint32_t delay,
                                   const Cycles lookup_lat) const;
 
     /**