cpu-o3: Make the smtLSQPolicy a Param.ScopedEnum

The smtLSQPolicy is a parameter in the o3 cpu that can have 3
different values. Previously this setting was done through a string
and a parser function would turn it into a c++ enum value. This
changeset turns the string into a python Param.ScopedEnum.

Change-Id: I82041b88bd914c5dc660058d9e3998e3114e7c35
Signed-off-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/15397
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Maintainer: Jason Lowe-Power <jason@lowepower.com>
diff --git a/src/cpu/o3/O3CPU.py b/src/cpu/o3/O3CPU.py
index f6c395a..02d56de 100644
--- a/src/cpu/o3/O3CPU.py
+++ b/src/cpu/o3/O3CPU.py
@@ -51,6 +51,9 @@
 class FetchPolicy(ScopedEnum):
     vals = [ 'SingleThread', 'RoundRobin', 'Branch', 'IQCount', 'LSQCount' ]
 
+class SMTQueuePolicy(ScopedEnum):
+    vals = [ 'Dynamic', 'Partitioned', 'Threshold' ]
+
 class DerivO3CPU(BaseCPU):
     type = 'DerivO3CPU'
     cxx_header = 'cpu/o3/deriv.hh'
@@ -151,7 +154,8 @@
 
     smtNumFetchingThreads = Param.Unsigned(1, "SMT Number of Fetching Threads")
     smtFetchPolicy = Param.FetchPolicy('SingleThread', "SMT Fetch policy")
-    smtLSQPolicy    = Param.String('Partitioned', "SMT LSQ Sharing Policy")
+    smtLSQPolicy    = Param.SMTQueuePolicy('Partitioned',
+                                           "SMT LSQ Sharing Policy")
     smtLSQThreshold = Param.Int(100, "SMT LSQ Threshold Sharing Parameter")
     smtIQPolicy    = Param.String('Partitioned', "SMT IQ Sharing Policy")
     smtIQThreshold = Param.Int(100, "SMT IQ Threshold Sharing Parameter")
diff --git a/src/cpu/o3/lsq.hh b/src/cpu/o3/lsq.hh
index 0c93121..2b2d39b 100644
--- a/src/cpu/o3/lsq.hh
+++ b/src/cpu/o3/lsq.hh
@@ -49,6 +49,7 @@
 
 #include "cpu/o3/lsq_unit.hh"
 #include "cpu/inst_seq.hh"
+#include "enums/SMTQueuePolicy.hh"
 #include "mem/port.hh"
 #include "sim/sim_object.hh"
 
@@ -62,13 +63,6 @@
     typedef typename Impl::CPUPol::IEW IEW;
     typedef typename Impl::CPUPol::LSQUnit LSQUnit;
 
-    /** SMT policy. */
-    enum LSQPolicy {
-        Dynamic,
-        Partitioned,
-        Threshold
-    };
-
     /** Constructs an LSQ with the given parameters. */
     LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params);
     ~LSQ() { }
@@ -306,40 +300,21 @@
 
   protected:
     /** The LSQ policy for SMT mode. */
-    LSQPolicy lsqPolicy;
-
-    /** Transform a SMT sharing policy string into a LSQPolicy value. */
-    static LSQPolicy readLSQPolicy(const std::string& policy) {
-        std::string policy_ = policy;
-        std::transform(policy_.begin(), policy_.end(), policy_.begin(),
-                   (int(*)(int)) tolower);
-        if (policy_ == "dynamic") {
-            return Dynamic;
-        } else if (policy_ == "partitioned") {
-            return Partitioned;
-        } else if (policy_ == "threshold") {
-            return Threshold;
-        }
-        assert(0 && "Invalid LSQ Sharing Policy.Options Are:{Dynamic,"
-                    "Partitioned, Threshold}");
-
-        // Some compilers complain if there is no return.
-        return Dynamic;
-    }
+    SMTQueuePolicy lsqPolicy;
 
     /** Auxiliary function to calculate per-thread max LSQ allocation limit.
      * Depending on a policy, number of entries and possibly number of threads
      * and threshold, this function calculates how many resources each thread
      * can occupy at most.
      */
-    static uint32_t maxLSQAllocation(const LSQPolicy& pol, uint32_t entries,
+    static uint32_t maxLSQAllocation(SMTQueuePolicy pol, uint32_t entries,
             uint32_t numThreads, uint32_t SMTThreshold) {
-        if (pol == Dynamic) {
+        if (pol == SMTQueuePolicy::Dynamic) {
             return entries;
-        } else if (pol == Partitioned) {
+        } else if (pol == SMTQueuePolicy::Partitioned) {
             //@todo:make work if part_amt doesnt divide evenly.
             return entries / numThreads;
-        } else if (pol == Threshold) {
+        } else if (pol == SMTQueuePolicy::Threshold) {
             //Divide up by threshold amount
             //@todo: Should threads check the max and the total
             //amount of the LSQ
diff --git a/src/cpu/o3/lsq_impl.hh b/src/cpu/o3/lsq_impl.hh
index 36bc17b..edc3f46 100644
--- a/src/cpu/o3/lsq_impl.hh
+++ b/src/cpu/o3/lsq_impl.hh
@@ -61,7 +61,7 @@
 template <class Impl>
 LSQ<Impl>::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params)
     : cpu(cpu_ptr), iewStage(iew_ptr),
-      lsqPolicy(readLSQPolicy(params->smtLSQPolicy)),
+      lsqPolicy(params->smtLSQPolicy),
       LQEntries(params->LQEntries),
       SQEntries(params->SQEntries),
       maxLQEntries(maxLSQAllocation(lsqPolicy, LQEntries, params->numThreads,
@@ -77,13 +77,13 @@
     //**********************************************/
 
     //Figure out fetch policy
-    if (lsqPolicy == Dynamic) {
+    if (lsqPolicy == SMTQueuePolicy::Dynamic) {
         DPRINTF(LSQ, "LSQ sharing policy set to Dynamic\n");
-    } else if (lsqPolicy == Partitioned) {
+    } else if (lsqPolicy == SMTQueuePolicy::Partitioned) {
         DPRINTF(Fetch, "LSQ sharing policy set to Partitioned: "
                 "%i entries per LQ | %i entries per SQ\n",
                 maxLQEntries,maxSQEntries);
-    } else if (lsqPolicy == Threshold) {
+    } else if (lsqPolicy == SMTQueuePolicy::Threshold) {
 
         assert(params->smtLSQThreshold > LQEntries);
         assert(params->smtLSQThreshold > SQEntries);
@@ -172,7 +172,7 @@
 int
 LSQ<Impl>::entryAmount(ThreadID num_threads)
 {
-    if (lsqPolicy == Partitioned) {
+    if (lsqPolicy == SMTQueuePolicy::Partitioned) {
         return LQEntries / num_threads;
     } else {
         return 0;
@@ -183,14 +183,15 @@
 void
 LSQ<Impl>::resetEntries()
 {
-    if (lsqPolicy != Dynamic || numThreads > 1) {
+    if (lsqPolicy != SMTQueuePolicy::Dynamic || numThreads > 1) {
         int active_threads = activeThreads->size();
 
         int maxEntries;
 
-        if (lsqPolicy == Partitioned) {
+        if (lsqPolicy == SMTQueuePolicy::Partitioned) {
             maxEntries = LQEntries / active_threads;
-        } else if (lsqPolicy == Threshold && active_threads == 1) {
+        } else if (lsqPolicy == SMTQueuePolicy::Threshold &&
+                   active_threads == 1) {
             maxEntries = LQEntries;
         } else {
             maxEntries = LQEntries;
@@ -500,7 +501,7 @@
 {
     //@todo: Change to Calculate All Entries for
     //Dynamic Policy
-    if (lsqPolicy == Dynamic)
+    if (lsqPolicy == SMTQueuePolicy::Dynamic)
         return isFull();
     else
         return thread[tid].lqFull() || thread[tid].sqFull();
@@ -570,7 +571,7 @@
 {
     //@todo: Change to Calculate All Entries for
     //Dynamic Policy
-    if (lsqPolicy == Dynamic)
+    if (lsqPolicy == SMTQueuePolicy::Dynamic)
         return lqFull();
     else
         return thread[tid].lqFull();
@@ -599,7 +600,7 @@
 {
      //@todo: Change to Calculate All Entries for
     //Dynamic Policy
-    if (lsqPolicy == Dynamic)
+    if (lsqPolicy == SMTQueuePolicy::Dynamic)
         return sqFull();
     else
         return thread[tid].sqFull();
@@ -626,7 +627,7 @@
 bool
 LSQ<Impl>::isStalled(ThreadID tid)
 {
-    if (lsqPolicy == Dynamic)
+    if (lsqPolicy == SMTQueuePolicy::Dynamic)
         return isStalled();
     else
         return thread[tid].isStalled();