cpu: Fixed ratio of pred to hyst bits for LTAGE Bimodal

The LTAGE paper states 1 hyst bit shared for 4 pred bits.
Made this ratio configurable use 4 by default.
Also changed the Bimodal structure to use two std::vector<bool> (one for
pred and one for hyst bits)

Change-Id: I6793e8e358be01b75b8fd181ddad50f259862d79
Signed-off-by: Pau Cabre <pau.cabre@metempsy.com>
Reviewed-on: https://gem5-review.googlesource.com/c/14120
Reviewed-by: Ilias Vougioukas <ilias.vougioukas@arm.com>
Reviewed-by: Sudhanshu Jha <sudhanshu.jha@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
diff --git a/src/cpu/pred/BranchPredictor.py b/src/cpu/pred/BranchPredictor.py
index 1b400c2..9f35165 100644
--- a/src/cpu/pred/BranchPredictor.py
+++ b/src/cpu/pred/BranchPredictor.py
@@ -92,6 +92,9 @@
     cxx_header = "cpu/pred/ltage.hh"
 
     logSizeBiMP = Param.Unsigned(14, "Log size of Bimodal predictor in bits")
+    logRatioBiModalHystEntries = Param.Unsigned(2,
+        "Log num of prediction entries for a shared hysteresis bit " \
+        "for the Bimodal")
     logSizeTagTables = Param.Unsigned(11, "Log size of tag table in LTAGE")
     logSizeLoopPred = Param.Unsigned(8, "Log size of the loop predictor")
     nHistoryTables = Param.Unsigned(12, "Number of history tables")
diff --git a/src/cpu/pred/ltage.cc b/src/cpu/pred/ltage.cc
index 86b9e99..874fbe4 100644
--- a/src/cpu/pred/ltage.cc
+++ b/src/cpu/pred/ltage.cc
@@ -50,6 +50,7 @@
 LTAGE::LTAGE(const LTAGEParams *params)
   : BPredUnit(params),
     logSizeBiMP(params->logSizeBiMP),
+    logRatioBiModalHystEntries(params->logRatioBiModalHystEntries),
     logSizeTagTables(params->logSizeTagTables),
     logSizeLoopPred(params->logSizeLoopPred),
     nHistoryTables(params->nHistoryTables),
@@ -122,7 +123,11 @@
         }
     }
 
-    btable = new BimodalEntry[ULL(1) << logSizeBiMP];
+    const uint64_t bimodalTableSize = ULL(1) << logSizeBiMP;
+    btablePrediction.resize(bimodalTableSize, false);
+    btableHysteresis.resize(bimodalTableSize >> logRatioBiModalHystEntries,
+                            true);
+
     ltable = new LoopEntry[ULL(1) << logSizeLoopPred];
     gtable = new TageEntry*[nHistoryTables + 1];
     for (int i = 1; i <= nHistoryTables; i++) {
@@ -211,27 +216,28 @@
 bool
 LTAGE::getBimodePred(Addr pc, BranchInfo* bi) const
 {
-    return (btable[bi->bimodalIndex].pred > 0);
+    return btablePrediction[bi->bimodalIndex];
 }
 
 
-// Update the bimodal predictor: a hysteresis bit is shared among 4 prediction
-// bits
+// Update the bimodal predictor: a hysteresis bit is shared among N prediction
+// bits (N = 2 ^ logRatioBiModalHystEntries)
 void
 LTAGE::baseUpdate(Addr pc, bool taken, BranchInfo* bi)
 {
-    int inter = (btable[bi->bimodalIndex].pred << 1)
-              + btable[bi->bimodalIndex ].hyst;
+    int inter = (btablePrediction[bi->bimodalIndex] << 1)
+        + btableHysteresis[bi->bimodalIndex >> logRatioBiModalHystEntries];
     if (taken) {
         if (inter < 3)
             inter++;
     } else if (inter > 0) {
         inter--;
     }
-    btable[bi->bimodalIndex].pred = inter >> 1;
-    btable[bi->bimodalIndex].hyst = (inter & 1);
-    DPRINTF(LTage, "Updating branch %lx, pred:%d, hyst:%d\n",
-            pc, btable[bi->bimodalIndex].pred,btable[bi->bimodalIndex].hyst);
+    const bool pred = inter >> 1;
+    const bool hyst = inter & 1;
+    btablePrediction[bi->bimodalIndex] = pred;
+    btableHysteresis[bi->bimodalIndex >> logRatioBiModalHystEntries] = hyst;
+    DPRINTF(LTage, "Updating branch %lx, pred:%d, hyst:%d\n", pc, pred, hyst);
 }
 
 
diff --git a/src/cpu/pred/ltage.hh b/src/cpu/pred/ltage.hh
index 60c3467..a810fb5 100644
--- a/src/cpu/pred/ltage.hh
+++ b/src/cpu/pred/ltage.hh
@@ -89,15 +89,6 @@
                       confidence(0), tag(0), age(0), dir(0) { }
     };
 
-    // Bimodal Predictor Entry
-    struct BimodalEntry
-    {
-        uint8_t pred;
-        uint8_t hyst;
-
-        BimodalEntry() : pred(0), hyst(1) { }
-    };
-
     // Tage Entry
     struct TageEntry
     {
@@ -355,6 +346,7 @@
     void specLoopUpdate(Addr pc, bool taken, BranchInfo* bi);
 
     const unsigned logSizeBiMP;
+    const unsigned logRatioBiModalHystEntries;
     const unsigned logSizeTagTables;
     const unsigned logSizeLoopPred;
     const unsigned nHistoryTables;
@@ -364,7 +356,8 @@
     const unsigned maxHist;
     const unsigned minTagWidth;
 
-    BimodalEntry *btable;
+    std::vector<bool> btablePrediction;
+    std::vector<bool> btableHysteresis;
     TageEntry **gtable;
     LoopEntry *ltable;