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'
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")
#include "cpu/o3/lsq_unit.hh"
#include "cpu/inst_seq.hh"
+#include "enums/SMTQueuePolicy.hh"
#include "mem/port.hh"
#include "sim/sim_object.hh"
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() { }
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
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,
//**********************************************/
//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);
int
LSQ<Impl>::entryAmount(ThreadID num_threads)
{
- if (lsqPolicy == Partitioned) {
+ if (lsqPolicy == SMTQueuePolicy::Partitioned) {
return LQEntries / num_threads;
} else {
return 0;
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;
{
//@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();
{
//@todo: Change to Calculate All Entries for
//Dynamic Policy
- if (lsqPolicy == Dynamic)
+ if (lsqPolicy == SMTQueuePolicy::Dynamic)
return lqFull();
else
return thread[tid].lqFull();
{
//@todo: Change to Calculate All Entries for
//Dynamic Policy
- if (lsqPolicy == Dynamic)
+ if (lsqPolicy == SMTQueuePolicy::Dynamic)
return sqFull();
else
return thread[tid].sqFull();
bool
LSQ<Impl>::isStalled(ThreadID tid)
{
- if (lsqPolicy == Dynamic)
+ if (lsqPolicy == SMTQueuePolicy::Dynamic)
return isStalled();
else
return thread[tid].isStalled();