summaryrefslogtreecommitdiff
path: root/cpu/simple_cpu/simple_cpu.cc
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/simple_cpu/simple_cpu.cc')
-rw-r--r--cpu/simple_cpu/simple_cpu.cc221
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;
}