cpu-o3: Make the smtFetchPolicy a Param.ScopedEnum

The smtFetchPolicy is a parameter in the o3 cpu that can have 5
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: Iafb4b4b27587541185ea912e5ed581bce09695f5
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/15396
Reviewed-by: Anthony Gutierrez <anthony.gutierrez@amd.com>
Maintainer: Anthony Gutierrez <anthony.gutierrez@amd.com>
diff --git a/src/cpu/o3/O3CPU.py b/src/cpu/o3/O3CPU.py
index b8152f6..f6c395a 100644
--- a/src/cpu/o3/O3CPU.py
+++ b/src/cpu/o3/O3CPU.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2016 ARM Limited
+# Copyright (c) 2016, 2019 ARM Limited
 # All rights reserved.
 #
 # The license below extends only to copyright in the software and shall
@@ -48,6 +48,9 @@
 from O3Checker import O3Checker
 from BranchPredictor import *
 
+class FetchPolicy(ScopedEnum):
+    vals = [ 'SingleThread', 'RoundRobin', 'Branch', 'IQCount', 'LSQCount' ]
+
 class DerivO3CPU(BaseCPU):
     type = 'DerivO3CPU'
     cxx_header = 'cpu/o3/deriv.hh'
@@ -147,7 +150,7 @@
     numROBEntries = Param.Unsigned(192, "Number of reorder buffer entries")
 
     smtNumFetchingThreads = Param.Unsigned(1, "SMT Number of Fetching Threads")
-    smtFetchPolicy = Param.String('SingleThread', "SMT Fetch policy")
+    smtFetchPolicy = Param.FetchPolicy('SingleThread', "SMT Fetch policy")
     smtLSQPolicy    = Param.String('Partitioned', "SMT LSQ Sharing Policy")
     smtLSQThreshold = Param.Int(100, "SMT LSQ Threshold Sharing Parameter")
     smtIQPolicy    = Param.String('Partitioned', "SMT IQ Sharing Policy")
diff --git a/src/cpu/o3/deriv.cc b/src/cpu/o3/deriv.cc
index 6b2af76..e8ff669 100644
--- a/src/cpu/o3/deriv.cc
+++ b/src/cpu/o3/deriv.cc
@@ -57,14 +57,8 @@
 
     numThreads = actual_num_threads;
 
-    // Default smtFetchPolicy to "RoundRobin", if necessary.
-    std::string round_robin_policy = "RoundRobin";
-    std::string single_thread = "SingleThread";
-
-    if (actual_num_threads > 1 && single_thread.compare(smtFetchPolicy) == 0)
-        smtFetchPolicy = round_robin_policy;
-    else
-        smtFetchPolicy = smtFetchPolicy;
+    if (actual_num_threads > 1 && smtFetchPolicy == FetchPolicy::SingleThread)
+        smtFetchPolicy = FetchPolicy::RoundRobin;
 
     return new DerivO3CPU(this);
 }
diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh
index ce4f8b6..ee1932b 100644
--- a/src/cpu/o3/fetch.hh
+++ b/src/cpu/o3/fetch.hh
@@ -52,6 +52,7 @@
 #include "cpu/pred/bpred_unit.hh"
 #include "cpu/timebuf.hh"
 #include "cpu/translation.hh"
+#include "enums/FetchPolicy.hh"
 #include "mem/packet.hh"
 #include "mem/port.hh"
 #include "sim/eventq.hh"
@@ -172,15 +173,6 @@
         NoGoodAddr
     };
 
-    /** Fetching Policy, Add new policies here.*/
-    enum FetchPriority {
-        SingleThread,
-        RoundRobin,
-        Branch,
-        IQ,
-        LSQ
-    };
-
   private:
     /** Fetch status. */
     FetchStatus _status;
@@ -189,7 +181,7 @@
     ThreadStatus fetchStatus[Impl::MaxThreads];
 
     /** Fetch policy. */
-    FetchPriority fetchPolicy;
+    FetchPolicy fetchPolicy;
 
     /** List that has the threads organized by priority. */
     std::list<ThreadID> priorityList;
@@ -364,7 +356,7 @@
                          TheISA::PCState nextPC, bool trace);
 
     /** Returns the appropriate thread to fetch, given the fetch policy. */
-    ThreadID getFetchingThread(FetchPriority &fetch_priority);
+    ThreadID getFetchingThread();
 
     /** Returns the appropriate thread to fetch using a round robin policy. */
     ThreadID roundRobin();
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index 537f930..73c1ed1 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -79,7 +79,8 @@
 
 template<class Impl>
 DefaultFetch<Impl>::DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params)
-    : cpu(_cpu),
+    : fetchPolicy(params->smtFetchPolicy),
+      cpu(_cpu),
       branchPred(nullptr),
       decodeToFetchDelay(params->decodeToFetchDelay),
       renameToFetchDelay(params->renameToFetchDelay),
@@ -112,33 +113,9 @@
         fatal("cache block (%u bytes) is not a multiple of the "
               "fetch buffer (%u bytes)\n", cacheBlkSize, fetchBufferSize);
 
-    std::string policy = params->smtFetchPolicy;
-
-    // Convert string to lowercase
-    std::transform(policy.begin(), policy.end(), policy.begin(),
-                   (int(*)(int)) tolower);
-
     // Figure out fetch policy
-    if (policy == "singlethread") {
-        fetchPolicy = SingleThread;
-        if (numThreads > 1)
-            panic("Invalid Fetch Policy for a SMT workload.");
-    } else if (policy == "roundrobin") {
-        fetchPolicy = RoundRobin;
-        DPRINTF(Fetch, "Fetch policy set to Round Robin\n");
-    } else if (policy == "branch") {
-        fetchPolicy = Branch;
-        DPRINTF(Fetch, "Fetch policy set to Branch Count\n");
-    } else if (policy == "iqcount") {
-        fetchPolicy = IQ;
-        DPRINTF(Fetch, "Fetch policy set to IQ count\n");
-    } else if (policy == "lsqcount") {
-        fetchPolicy = LSQ;
-        DPRINTF(Fetch, "Fetch policy set to LSQ count\n");
-    } else {
-        fatal("Invalid Fetch Policy. Options Are: {SingleThread,"
-              " RoundRobin,LSQcount,IQcount}\n");
-    }
+    panic_if(fetchPolicy == FetchPolicy::SingleThread && numThreads > 1,
+             "Invalid Fetch Policy for a SMT workload.");
 
     // Get the size of an instruction.
     instSize = sizeof(TheISA::MachInst);
@@ -1157,7 +1134,7 @@
     //////////////////////////////////////////
     // Start actual fetch
     //////////////////////////////////////////
-    ThreadID tid = getFetchingThread(fetchPolicy);
+    ThreadID tid = getFetchingThread();
 
     assert(!cpu->switchedOut());
 
@@ -1446,26 +1423,18 @@
 ///////////////////////////////////////
 template<class Impl>
 ThreadID
-DefaultFetch<Impl>::getFetchingThread(FetchPriority &fetch_priority)
+DefaultFetch<Impl>::getFetchingThread()
 {
     if (numThreads > 1) {
-        switch (fetch_priority) {
-
-          case SingleThread:
-            return 0;
-
-          case RoundRobin:
+        switch (fetchPolicy) {
+          case FetchPolicy::RoundRobin:
             return roundRobin();
-
-          case IQ:
+          case FetchPolicy::IQCount:
             return iqCount();
-
-          case LSQ:
+          case FetchPolicy::LSQCount:
             return lsqCount();
-
-          case Branch:
+          case FetchPolicy::Branch:
             return branchCount();
-
           default:
             return InvalidThreadID;
         }