#include <string>
#include "cpu/base.hh"
-#include "cpu/o3/alpha_cpu.hh"
-#include "cpu/o3/alpha_impl.hh"
-#include "cpu/o3/alpha_params.hh"
+#include "cpu/o3/alpha/cpu.hh"
+#include "cpu/o3/alpha/impl.hh"
+#include "cpu/o3/alpha/params.hh"
#include "cpu/o3/fu_pool.hh"
#include "sim/builder.hh"
-class DerivAlphaO3CPU : public AlphaO3CPU<AlphaSimpleImpl>
+class DerivO3CPU : public AlphaO3CPU<AlphaSimpleImpl>
{
public:
- DerivAlphaO3CPU(AlphaSimpleParams *p)
+ DerivO3CPU(AlphaSimpleParams *p)
: AlphaO3CPU<AlphaSimpleImpl>(p)
{ }
};
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(DerivAlphaO3CPU)
+BEGIN_DECLARE_SIM_OBJECT_PARAMS(DerivO3CPU)
Param<int> clock;
Param<int> numThreads;
Param<bool> function_trace;
Param<Tick> function_trace_start;
-END_DECLARE_SIM_OBJECT_PARAMS(DerivAlphaO3CPU)
+END_DECLARE_SIM_OBJECT_PARAMS(DerivO3CPU)
-BEGIN_INIT_SIM_OBJECT_PARAMS(DerivAlphaO3CPU)
+BEGIN_INIT_SIM_OBJECT_PARAMS(DerivO3CPU)
INIT_PARAM(clock, "clock speed"),
INIT_PARAM(numThreads, "number of HW thread contexts"),
INIT_PARAM(function_trace, "Enable function trace"),
INIT_PARAM(function_trace_start, "Cycle to start function trace")
-END_INIT_SIM_OBJECT_PARAMS(DerivAlphaO3CPU)
+END_INIT_SIM_OBJECT_PARAMS(DerivO3CPU)
-CREATE_SIM_OBJECT(DerivAlphaO3CPU)
+CREATE_SIM_OBJECT(DerivO3CPU)
{
- DerivAlphaO3CPU *cpu;
+ DerivO3CPU *cpu;
#if FULL_SYSTEM
// Full-system only supports a single thread for the moment.
params->functionTrace = function_trace;
params->functionTraceStart = function_trace_start;
- cpu = new DerivAlphaO3CPU(params);
+ cpu = new DerivO3CPU(params);
return cpu;
}
-REGISTER_SIM_OBJECT("DerivAlphaO3CPU", DerivAlphaO3CPU)
+REGISTER_SIM_OBJECT("DerivO3CPU", DerivO3CPU)
return "FullO3CPU tick event";
}
+template <class Impl>
+FullO3CPU<Impl>::ActivateThreadEvent::ActivateThreadEvent()
+ : Event(&mainEventQueue, CPU_Tick_Pri)
+{
+}
+
+template <class Impl>
+void
+FullO3CPU<Impl>::ActivateThreadEvent::init(int thread_num,
+ FullO3CPU<Impl> *thread_cpu)
+{
+ tid = thread_num;
+ cpu = thread_cpu;
+}
+
+template <class Impl>
+void
+FullO3CPU<Impl>::ActivateThreadEvent::process()
+{
+ cpu->activateThread(tid);
+}
+
+template <class Impl>
+const char *
+FullO3CPU<Impl>::ActivateThreadEvent::description()
+{
+ return "FullO3CPU \"Activate Thread\" event";
+}
+
template <class Impl>
FullO3CPU<Impl>::FullO3CPU(Params *params)
: BaseO3CPU(params),
lastRunningCycle = curTick;
+ lastActivatedCycle = -1;
+
contextSwitch = false;
}
template <class Impl>
void
-FullO3CPU<Impl>::activateContext(int tid, int delay)
+FullO3CPU<Impl>::activateThread(unsigned int tid)
{
- // Needs to set each stage to running as well.
list<unsigned>::iterator isActive = find(
activeThreads.begin(), activeThreads.end(), tid);
if (isActive == activeThreads.end()) {
- //May Need to Re-code this if the delay variable is the
- //delay needed for thread to activate
- DPRINTF(O3CPU, "Adding Thread %i to active threads list\n",
+ DPRINTF(O3CPU, "[tid:%i]: Adding to active threads list\n",
tid);
activeThreads.push_back(tid);
}
+}
- assert(_status == Idle || _status == SwitchedOut);
- scheduleTickEvent(delay);
+template <class Impl>
+void
+FullO3CPU<Impl>::activateContext(int tid, int delay)
+{
+ // Needs to set each stage to running as well.
+ if (delay){
+ DPRINTF(O3CPU, "[tid:%i]: Scheduling thread context to activate "
+ "on cycle %d\n", tid, curTick + cycles(delay));
+ scheduleActivateThreadEvent(tid, delay);
+ } else {
+ activateThread(tid);
+ }
- // Be sure to signal that there's some activity so the CPU doesn't
- // deschedule itself.
- activityRec.activity();
- fetch.wakeFromQuiesce();
+ if(lastActivatedCycle < curTick) {
+ scheduleTickEvent(delay);
+
+ // Be sure to signal that there's some activity so the CPU doesn't
+ // deschedule itself.
+ activityRec.activity();
+ fetch.wakeFromQuiesce();
- _status = Running;
+ lastActivatedCycle = curTick;
+
+ _status = Running;
+ }
}
template <class Impl>
typedef typename std::list<DynInstPtr>::iterator ListIt;
friend class O3ThreadContext<Impl>;
+
public:
enum Status {
Running,
/** Overall CPU status. */
Status _status;
+ /** Per-thread status in CPU, used for SMT. */
+ Status _threadStatus[Impl::MaxThreads];
+
private:
class TickEvent : public Event
{
tickEvent.squash();
}
+ class ActivateThreadEvent : public Event
+ {
+ private:
+ /** Number of Thread to Activate */
+ int tid;
+
+ /** Pointer to the CPU. */
+ FullO3CPU<Impl> *cpu;
+
+ public:
+ /** Constructs the event. */
+ ActivateThreadEvent();
+
+ /** Initialize Event */
+ void init(int thread_num, FullO3CPU<Impl> *thread_cpu);
+
+ /** Processes the event, calling activateThread() on the CPU. */
+ void process();
+
+ /** Returns the description of the event. */
+ const char *description();
+ };
+
+ /** Schedule thread to activate , regardless of its current state. */
+ void scheduleActivateThreadEvent(int tid, int delay)
+ {
+ // Schedule thread to activate, regardless of its current state.
+ if (activateThreadEvent[tid].squashed())
+ activateThreadEvent[tid].reschedule(curTick + cycles(delay));
+ else if (!activateThreadEvent[tid].scheduled())
+ activateThreadEvent[tid].schedule(curTick + cycles(delay));
+ }
+
+ /** Unschedule actiavte thread event, regardless of its current state. */
+ void unscheduleActivateThreadEvent(int tid)
+ {
+ if (activateThreadEvent[tid].scheduled())
+ activateThreadEvent[tid].squash();
+ }
+
+ /** The tick event used for scheduling CPU ticks. */
+ ActivateThreadEvent activateThreadEvent[Impl::MaxThreads];
+
public:
/** Constructs a CPU with the given parameters. */
FullO3CPU(Params *params);
/** Initialize the CPU */
void init();
+ /** Add Thread to Active Threads List */
+ void activateThread(unsigned int tid);
+
/** Setup CPU to insert a thread's context */
void insertThread(unsigned tid);
/** The cycle that the CPU was last running, used for statistics. */
Tick lastRunningCycle;
+ /** The cycle that the CPU was last activated by a new thread*/
+ Tick lastActivatedCycle;
+
/** Number of Threads CPU can process */
unsigned numThreads;