mem-cache: Use SatCounter in Stride prefetcher

There is no need to reimplement saturating counter functionality.

Change-Id: Ie7753089873f41a378ab88fd5f095302c3428797
Signed-off-by: Daniel R. Carvalho <odanrc@yahoo.com.br>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/24542
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
diff --git a/src/mem/cache/prefetch/Prefetcher.py b/src/mem/cache/prefetch/Prefetcher.py
index 8cfefe1..51132f9 100644
--- a/src/mem/cache/prefetch/Prefetcher.py
+++ b/src/mem/cache/prefetch/Prefetcher.py
@@ -147,10 +147,12 @@
     # Do not consult stride prefetcher on instruction accesses
     on_inst = False
 
-    max_conf = Param.Int(7, "Maximum confidence level")
-    thresh_conf = Param.Int(4, "Threshold confidence level")
-    min_conf = Param.Int(0, "Minimum confidence level")
-    start_conf = Param.Int(4, "Starting confidence for new entries")
+    confidence_counter_bits = Param.Unsigned(3,
+        "Number of bits of the confidence counter")
+    initial_confidence = Param.Unsigned(4,
+        "Starting confidence of new entries")
+    confidence_threshold = Param.Percent(50,
+        "Prefetch generation confidence threshold")
 
     table_sets = Param.Int(16, "Number of sets in PC lookup table")
     table_assoc = Param.Int(4, "Associativity of PC lookup table")
diff --git a/src/mem/cache/prefetch/stride.cc b/src/mem/cache/prefetch/stride.cc
index 8e47d9b..101adf2 100644
--- a/src/mem/cache/prefetch/stride.cc
+++ b/src/mem/cache/prefetch/stride.cc
@@ -58,7 +58,8 @@
 
 namespace Prefetcher {
 
-Stride::StrideEntry::StrideEntry()
+Stride::StrideEntry::StrideEntry(const SatCounter& init_confidence)
+  : ReplaceableEntry(), confidence(init_confidence)
 {
     invalidate();
 }
@@ -70,20 +71,18 @@
     lastAddr = 0;
     isSecure = false;
     stride = 0;
-    confidence = 0;
+    confidence.reset();
 }
 
 Stride::Stride(const StridePrefetcherParams *p)
-    : Queued(p),
-      maxConf(p->max_conf),
-      threshConf(p->thresh_conf),
-      minConf(p->min_conf),
-      startConf(p->start_conf),
-      pcTableAssoc(p->table_assoc),
-      pcTableSets(p->table_sets),
-      useMasterId(p->use_master_id),
-      degree(p->degree),
-      replacementPolicy(p->replacement_policy)
+  : Queued(p),
+    initConfidence(p->confidence_counter_bits, p->initial_confidence),
+    threshConf(p->confidence_threshold/100.0),
+    pcTableAssoc(p->table_assoc),
+    pcTableSets(p->table_sets),
+    useMasterId(p->use_master_id),
+    degree(p->degree),
+    replacementPolicy(p->replacement_policy)
 {
     assert(isPowerOf2(pcTableSets));
 }
@@ -105,7 +104,8 @@
 {
     // Create new table
     auto insertion_result = pcTables.insert(std::make_pair(context,
-        PCTable(pcTableAssoc, pcTableSets, name(), replacementPolicy)));
+        PCTable(pcTableAssoc, pcTableSets, name(), replacementPolicy,
+        StrideEntry(initConfidence))));
 
     DPRINTF(HWPrefetch, "Adding context %i with stride entries\n", context);
 
@@ -114,12 +114,12 @@
 }
 
 Stride::PCTable::PCTable(int assoc, int sets, const std::string name,
-                                   BaseReplacementPolicy* replacementPolicy)
+    BaseReplacementPolicy* replacementPolicy, StrideEntry init_confidence)
     : pcTableSets(sets), _name(name), entries(pcTableSets),
       replacementPolicy(replacementPolicy)
 {
     for (int set = 0; set < sets; set++) {
-        entries[set].resize(assoc);
+        entries[set].resize(assoc, init_confidence);
         for (int way = 0; way < assoc; way++) {
             // Inform the entry its position
             entries[set][way].setPosition(set, way);
@@ -163,26 +163,26 @@
 
         // Adjust confidence for stride entry
         if (stride_match && new_stride != 0) {
-            if (entry->confidence < maxConf)
-                entry->confidence++;
+            entry->confidence++;
         } else {
-            if (entry->confidence > minConf)
-                entry->confidence--;
+            entry->confidence--;
             // If confidence has dropped below the threshold, train new stride
-            if (entry->confidence < threshConf)
+            if (entry->confidence.calcSaturation() < threshConf) {
                 entry->stride = new_stride;
+            }
         }
 
         DPRINTF(HWPrefetch, "Hit: PC %x pkt_addr %x (%s) stride %d (%s), "
                 "conf %d\n", pc, pf_addr, is_secure ? "s" : "ns",
                 new_stride, stride_match ? "match" : "change",
-                entry->confidence);
+                (int)entry->confidence);
 
         entry->lastAddr = pf_addr;
 
         // Abort prefetch generation if below confidence threshold
-        if (entry->confidence < threshConf)
+        if (entry->confidence.calcSaturation() < threshConf) {
             return;
+        }
 
         // Generate up to degree prefetches
         for (int d = 1; d <= degree; d++) {
@@ -210,7 +210,6 @@
         entry->instAddr = pc;
         entry->lastAddr = pf_addr;
         entry->isSecure = is_secure;
-        entry->confidence = startConf;
         replacementPolicy->reset(entry->replacementData);
     }
 }
diff --git a/src/mem/cache/prefetch/stride.hh b/src/mem/cache/prefetch/stride.hh
index f483527..090c13a 100644
--- a/src/mem/cache/prefetch/stride.hh
+++ b/src/mem/cache/prefetch/stride.hh
@@ -51,6 +51,7 @@
 #include <unordered_map>
 #include <vector>
 
+#include "base/sat_counter.hh"
 #include "base/types.hh"
 #include "mem/cache/prefetch/queued.hh"
 #include "mem/cache/replacement_policies/replaceable_entry.hh"
@@ -64,10 +65,11 @@
 class Stride : public Queued
 {
   protected:
-    const int maxConf;
-    const int threshConf;
-    const int minConf;
-    const int startConf;
+    /** Initial confidence counter value for the pc tables. */
+    const SatCounter initConfidence;
+
+    /** Confidence threshold for prefetch generation. */
+    const double threshConf;
 
     const int pcTableAssoc;
     const int pcTableSets;
@@ -81,8 +83,7 @@
 
     struct StrideEntry : public ReplaceableEntry
     {
-        /** Default constructor */
-        StrideEntry();
+        StrideEntry(const SatCounter& init_confidence);
 
         /** Invalidate the entry */
         void invalidate();
@@ -91,7 +92,7 @@
         Addr lastAddr;
         bool isSecure;
         int stride;
-        int confidence;
+        SatCounter confidence;
     };
 
     class PCTable
@@ -106,7 +107,8 @@
          * @param replacementPolicy Replacement policy used by the table.
          */
         PCTable(int assoc, int sets, const std::string name,
-                BaseReplacementPolicy* replacementPolicy);
+                BaseReplacementPolicy* replacementPolicy,
+                StrideEntry init_confidence);
 
         /**
          * Default destructor.