diff options
Diffstat (limited to 'cpu/simple_cpu/simple_cpu.cc')
-rw-r--r-- | cpu/simple_cpu/simple_cpu.cc | 221 |
1 files changed, 112 insertions, 109 deletions
diff --git a/cpu/simple_cpu/simple_cpu.cc b/cpu/simple_cpu/simple_cpu.cc index d48f93663..86aeab7d7 100644 --- a/cpu/simple_cpu/simple_cpu.cc +++ b/cpu/simple_cpu/simple_cpu.cc @@ -47,6 +47,7 @@ #include "cpu/exec_context.hh" #include "cpu/exetrace.hh" #include "cpu/full_cpu/smt.hh" +#include "cpu/sampling_cpu/sampling_cpu.hh" #include "cpu/simple_cpu/simple_cpu.hh" #include "cpu/static_inst.hh" #include "mem/base_mem.hh" @@ -74,15 +75,16 @@ using namespace std; -SimpleCPU::TickEvent::TickEvent(SimpleCPU *c) - : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c), multiplier(1) + +SimpleCPU::TickEvent::TickEvent(SimpleCPU *c, int w) + : Event(&mainEventQueue, CPU_Tick_Pri), cpu(c), width(w) { } void SimpleCPU::TickEvent::process() { - int count = multiplier; + int count = width; do { cpu->tick(); } while (--count > 0 && cpu->status() == Running); @@ -96,8 +98,7 @@ SimpleCPU::TickEvent::description() SimpleCPU::CacheCompletionEvent::CacheCompletionEvent(SimpleCPU *_cpu) - : Event(&mainEventQueue), - cpu(_cpu) + : Event(&mainEventQueue), cpu(_cpu) { } @@ -112,52 +113,22 @@ SimpleCPU::CacheCompletionEvent::description() return "SimpleCPU cache completion event"; } -#ifdef FULL_SYSTEM -SimpleCPU::SimpleCPU(const string &_name, - System *_system, - Counter max_insts_any_thread, - Counter max_insts_all_threads, - Counter max_loads_any_thread, - Counter max_loads_all_threads, - AlphaITB *itb, AlphaDTB *dtb, - FunctionalMemory *mem, - MemInterface *icache_interface, - MemInterface *dcache_interface, - bool _def_reg, Tick freq, - bool _function_trace, Tick _function_trace_start) - : BaseCPU(_name, /* number_of_threads */ 1, _def_reg, - max_insts_any_thread, max_insts_all_threads, - max_loads_any_thread, max_loads_all_threads, - _system, freq, _function_trace, _function_trace_start), -#else -SimpleCPU::SimpleCPU(const string &_name, Process *_process, - Counter max_insts_any_thread, - Counter max_insts_all_threads, - Counter max_loads_any_thread, - Counter max_loads_all_threads, - MemInterface *icache_interface, - MemInterface *dcache_interface, - bool _def_reg, - bool _function_trace, Tick _function_trace_start) - : BaseCPU(_name, /* number_of_threads */ 1, _def_reg, - max_insts_any_thread, max_insts_all_threads, - max_loads_any_thread, max_loads_all_threads, - _function_trace, _function_trace_start), -#endif - tickEvent(this), xc(NULL), cacheCompletionEvent(this) +SimpleCPU::SimpleCPU(Params *p) + : BaseCPU(p), tickEvent(this, p->width), xc(NULL), + cacheCompletionEvent(this) { _status = Idle; #ifdef FULL_SYSTEM - xc = new ExecContext(this, 0, system, itb, dtb, mem); + xc = new ExecContext(this, 0, p->system, p->itb, p->dtb, p->mem); // initialize CPU, including PC TheISA::initCPU(&xc->regs); #else - xc = new ExecContext(this, /* thread_num */ 0, _process, /* asid */ 0); + xc = new ExecContext(this, /* thread_num */ 0, p->process, /* asid */ 0); #endif // !FULL_SYSTEM - icacheInterface = icache_interface; - dcacheInterface = dcache_interface; + icacheInterface = p->icache_interface; + dcacheInterface = p->dcache_interface; memReq = new MemReq(); memReq->xc = xc; @@ -179,11 +150,21 @@ SimpleCPU::~SimpleCPU() } void -SimpleCPU::switchOut() +SimpleCPU::switchOut(SamplingCPU *s) { - _status = SwitchedOut; - if (tickEvent.scheduled()) - tickEvent.squash(); + sampler = s; + if (status() == DcacheMissStall) { + DPRINTF(Sampler,"Outstanding dcache access, waiting for completion\n"); + _status = DcacheMissSwitch; + } + else { + _status = SwitchedOut; + + if (tickEvent.scheduled()) + tickEvent.squash(); + + sampler->signalSwitched(); + } } @@ -203,8 +184,6 @@ SimpleCPU::takeOverFrom(BaseCPU *oldCPU) tickEvent.schedule(curTick); } } - - oldCPU->switchOut(); } @@ -414,21 +393,22 @@ template <class T> Fault SimpleCPU::read(Addr addr, T &data, unsigned flags) { + if (status() == DcacheMissStall) { + Fault fault = xc->read(memReq,data); + + if (traceData) { + traceData->setAddr(addr); + if (fault == No_Fault) + traceData->setData(data); + } + return fault; + } + memReq->reset(addr, sizeof(T), flags); // translate to physical address Fault fault = xc->translateDataReadReq(memReq); - // do functional access - if (fault == No_Fault) - fault = xc->read(memReq, data); - - if (traceData) { - traceData->setAddr(addr); - if (fault == No_Fault) - traceData->setData(data); - } - // if we have a cache, do cache access too if (fault == No_Fault && dcacheInterface) { memReq->cmd = Read; @@ -444,6 +424,24 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags) lastDcacheStall = curTick; unscheduleTickEvent(); _status = DcacheMissStall; + } else { + // do functional access + fault = xc->read(memReq, data); + + if (traceData) { + traceData->setAddr(addr); + if (fault == No_Fault) + traceData->setData(data); + } + } + } else if(fault == No_Fault) { + // do functional access + fault = xc->read(memReq, data); + + if (traceData) { + traceData->setAddr(addr); + if (fault == No_Fault) + traceData->setData(data); } } @@ -605,10 +603,19 @@ SimpleCPU::processCacheCompletion() scheduleTickEvent(1); break; case DcacheMissStall: + if (memReq->cmd.isRead()) { + curStaticInst->execute(this,traceData); + } dcacheStallCycles += curTick - lastDcacheStall; _status = Running; scheduleTickEvent(1); break; + case DcacheMissSwitch: + if (memReq->cmd.isRead()) { + curStaticInst->execute(this,traceData); + } + _status = SwitchedOut; + sampler->signalSwitched(); case SwitchedOut: // If this CPU has been switched out due to sampling/warm-up, // ignore any further status changes (e.g., due to cache @@ -750,10 +757,10 @@ SimpleCPU::tick() comInstEventQueue[0]->serviceEvents(numInst); // decode the instruction - inst = htoa(inst); - StaticInstPtr<TheISA> si(inst); + inst = htoa(inst); + curStaticInst = StaticInst<TheISA>::decode(inst); - traceData = Trace::getInstRecord(curTick, xc, this, si, + traceData = Trace::getInstRecord(curTick, xc, this, curStaticInst, xc->regs.pc); #ifdef FULL_SYSTEM @@ -762,18 +769,18 @@ SimpleCPU::tick() xc->func_exe_inst++; - fault = si->execute(this, traceData); + fault = curStaticInst->execute(this, traceData); #ifdef FULL_SYSTEM if (xc->fnbin) - xc->execute(si.get()); + xc->execute(curStaticInst.get()); #endif - if (si->isMemRef()) { + if (curStaticInst->isMemRef()) { numMemRefs++; } - if (si->isLoad()) { + if (curStaticInst->isLoad()) { ++numLoad; comLoadEventQueue[0]->serviceEvents(numLoad); } @@ -840,7 +847,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU) SimObjectParam<BaseMem *> dcache; Param<bool> defer_registration; - Param<int> multiplier; + Param<int> width; Param<bool> function_trace; Param<Tick> function_trace_start; @@ -848,71 +855,67 @@ END_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU) BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleCPU) - INIT_PARAM_DFLT(max_insts_any_thread, - "terminate when any thread reaches this inst count", - 0), - INIT_PARAM_DFLT(max_insts_all_threads, - "terminate when all threads have reached this inst count", - 0), - INIT_PARAM_DFLT(max_loads_any_thread, - "terminate when any thread reaches this load count", - 0), - INIT_PARAM_DFLT(max_loads_all_threads, - "terminate when all threads have reached this load count", - 0), + INIT_PARAM(max_insts_any_thread, + "terminate when any thread reaches this inst count"), + INIT_PARAM(max_insts_all_threads, + "terminate when all threads have reached this inst count"), + INIT_PARAM(max_loads_any_thread, + "terminate when any thread reaches this load count"), + INIT_PARAM(max_loads_all_threads, + "terminate when all threads have reached this load count"), #ifdef FULL_SYSTEM INIT_PARAM(itb, "Instruction TLB"), INIT_PARAM(dtb, "Data TLB"), INIT_PARAM(mem, "memory"), INIT_PARAM(system, "system object"), - INIT_PARAM_DFLT(mult, "system clock multiplier", 1), + INIT_PARAM(mult, "system clock multiplier"), #else INIT_PARAM(workload, "processes to run"), #endif // FULL_SYSTEM - INIT_PARAM_DFLT(icache, "L1 instruction cache object", NULL), - INIT_PARAM_DFLT(dcache, "L1 data cache object", NULL), - INIT_PARAM_DFLT(defer_registration, "defer registration with system " - "(for sampling)", false), - - INIT_PARAM_DFLT(multiplier, "clock multiplier", 1), - INIT_PARAM_DFLT(function_trace, "Enable function trace", false), - INIT_PARAM_DFLT(function_trace_start, "Cycle to start function trace", 0) + INIT_PARAM(icache, "L1 instruction cache object"), + INIT_PARAM(dcache, "L1 data cache object"), + INIT_PARAM(defer_registration, "defer system registration (for sampling)"), + INIT_PARAM(width, "cpu width"), + INIT_PARAM(function_trace, "Enable function trace"), + INIT_PARAM(function_trace_start, "Cycle to start function trace") END_INIT_SIM_OBJECT_PARAMS(SimpleCPU) CREATE_SIM_OBJECT(SimpleCPU) { - SimpleCPU *cpu; #ifdef FULL_SYSTEM if (mult != 1) panic("processor clock multiplier must be 1\n"); +#endif - cpu = new SimpleCPU(getInstanceName(), system, - max_insts_any_thread, max_insts_all_threads, - max_loads_any_thread, max_loads_all_threads, - itb, dtb, mem, - (icache) ? icache->getInterface() : NULL, - (dcache) ? dcache->getInterface() : NULL, - defer_registration, - ticksPerSecond * mult, - function_trace, function_trace_start); -#else - - cpu = new SimpleCPU(getInstanceName(), workload, - max_insts_any_thread, max_insts_all_threads, - max_loads_any_thread, max_loads_all_threads, - (icache) ? icache->getInterface() : NULL, - (dcache) ? dcache->getInterface() : NULL, - defer_registration, - function_trace, function_trace_start); + SimpleCPU::Params *params = new SimpleCPU::Params(); + params->name = getInstanceName(); + params->numberOfThreads = 1; + params->max_insts_any_thread = max_insts_any_thread; + params->max_insts_all_threads = max_insts_all_threads; + params->max_loads_any_thread = max_loads_any_thread; + params->max_loads_all_threads = max_loads_all_threads; + params->deferRegistration = defer_registration; + params->freq = ticksPerSecond; + params->functionTrace = function_trace; + params->functionTraceStart = function_trace_start; + params->icache_interface = (icache) ? icache->getInterface() : NULL; + params->dcache_interface = (dcache) ? dcache->getInterface() : NULL; + params->width = width; -#endif // FULL_SYSTEM - - cpu->setTickMultiplier(multiplier); +#ifdef FULL_SYSTEM + params->itb = itb; + params->dtb = dtb; + params->mem = mem; + params->system = system; +#else + params->process = workload; +#endif + SimpleCPU *cpu = new SimpleCPU(params); return cpu; } |