Code update for CPU models.
arch/alpha/isa_traits.hh: Add in clear functions. cpu/base.cc: cpu/base.hh: Add in CPU progress event. cpu/base_dyn_inst.hh: Mimic normal registers in terms of writing/reading floats. cpu/checker/cpu.cc: cpu/checker/cpu.hh: cpu/checker/cpu_builder.cc: cpu/checker/o3_cpu_builder.cc: Fix up stuff. cpu/cpu_exec_context.cc: cpu/cpu_exec_context.hh: cpu/o3/cpu.cc: cpu/o3/cpu.hh: Bring up to speed with newmem. cpu/o3/alpha_cpu_builder.cc: Allow for progress intervals. cpu/o3/tournament_pred.cc: Fix up predictor. cpu/o3/tournament_pred.hh: cpu/ozone/cpu.hh: cpu/ozone/cpu_impl.hh: cpu/simple/cpu.cc: Fixes. cpu/ozone/cpu_builder.cc: Allow progress interval. cpu/ozone/front_end_impl.hh: Comment out this message. cpu/ozone/lw_back_end_impl.hh: Remove this. python/m5/objects/BaseCPU.py: Add progress interval. python/m5/objects/Root.py: Allow for stat reset. sim/serialize.cc: sim/stat_control.cc: Add in stats reset. --HG-- extra : convert_revision : fdb5ac5542099173cc30c40ea93372a065534b5e
This commit is contained in:
parent
5ec58c4bdc
commit
716ceb6c10
25 changed files with 241 additions and 35 deletions
|
@ -168,6 +168,9 @@ namespace AlphaISA
|
||||||
typedef union {
|
typedef union {
|
||||||
uint64_t q[NumFloatRegs]; // integer qword view
|
uint64_t q[NumFloatRegs]; // integer qword view
|
||||||
double d[NumFloatRegs]; // double-precision floating point view
|
double d[NumFloatRegs]; // double-precision floating point view
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{ bzero(d, sizeof(d)); }
|
||||||
} FloatRegFile;
|
} FloatRegFile;
|
||||||
|
|
||||||
extern const Addr PageShift;
|
extern const Addr PageShift;
|
||||||
|
@ -266,6 +269,13 @@ extern const int reg_redir[NumIntRegs];
|
||||||
|
|
||||||
void serialize(std::ostream &os);
|
void serialize(std::ostream &os);
|
||||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
bzero(intRegFile, sizeof(intRegFile));
|
||||||
|
floatRegFile.clear();
|
||||||
|
miscRegs.clear();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline ExtMachInst makeExtMI(MachInst inst, const uint64_t &pc);
|
static inline ExtMachInst makeExtMI(MachInst inst, const uint64_t &pc);
|
||||||
|
|
26
cpu/base.cc
26
cpu/base.cc
|
@ -54,6 +54,26 @@ vector<BaseCPU *> BaseCPU::cpuList;
|
||||||
// been initialized
|
// been initialized
|
||||||
int maxThreadsPerCPU = 1;
|
int maxThreadsPerCPU = 1;
|
||||||
|
|
||||||
|
void
|
||||||
|
CPUProgressEvent::process()
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
Counter temp = cpu->totalInstructions();
|
||||||
|
double ipc = double(temp - lastNumInst) / (interval / cpu->cycles(1));
|
||||||
|
DPRINTFN("%s progress event, instructions committed: %lli, IPC: %0.8d\n",
|
||||||
|
cpu->name(), temp - lastNumInst, ipc);
|
||||||
|
ipc = 0.0;
|
||||||
|
lastNumInst = temp;
|
||||||
|
schedule(curTick + interval);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
CPUProgressEvent::description()
|
||||||
|
{
|
||||||
|
return "CPU Progress event";
|
||||||
|
}
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
BaseCPU::BaseCPU(Params *p)
|
BaseCPU::BaseCPU(Params *p)
|
||||||
: SimObject(p->name), clock(p->clock), checkInterrupts(true),
|
: SimObject(p->name), clock(p->clock), checkInterrupts(true),
|
||||||
|
@ -150,7 +170,6 @@ BaseCPU::BaseCPU(Params *p)
|
||||||
if (params->profile)
|
if (params->profile)
|
||||||
profileEvent = new ProfileEvent(this, params->profile);
|
profileEvent = new ProfileEvent(this, params->profile);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseCPU::Params::Params()
|
BaseCPU::Params::Params()
|
||||||
|
@ -185,6 +204,11 @@ BaseCPU::startup()
|
||||||
if (!params->deferRegistration && profileEvent)
|
if (!params->deferRegistration && profileEvent)
|
||||||
profileEvent->schedule(curTick);
|
profileEvent->schedule(curTick);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (params->progress_interval) {
|
||||||
|
new CPUProgressEvent(&mainEventQueue, params->progress_interval,
|
||||||
|
this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
18
cpu/base.hh
18
cpu/base.hh
|
@ -43,6 +43,23 @@ class CheckerCPU;
|
||||||
class ExecContext;
|
class ExecContext;
|
||||||
class System;
|
class System;
|
||||||
|
|
||||||
|
class CPUProgressEvent : public Event
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
Tick interval;
|
||||||
|
Counter lastNumInst;
|
||||||
|
BaseCPU *cpu;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CPUProgressEvent(EventQueue *q, Tick ival, BaseCPU *_cpu)
|
||||||
|
: Event(q, Event::Stat_Event_Pri), interval(ival), lastNumInst(0), cpu(_cpu)
|
||||||
|
{ schedule(curTick + interval); }
|
||||||
|
|
||||||
|
void process();
|
||||||
|
|
||||||
|
virtual const char *description();
|
||||||
|
};
|
||||||
|
|
||||||
class BaseCPU : public SimObject
|
class BaseCPU : public SimObject
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
@ -125,6 +142,7 @@ class BaseCPU : public SimObject
|
||||||
int cpu_id;
|
int cpu_id;
|
||||||
Tick profile;
|
Tick profile;
|
||||||
#endif
|
#endif
|
||||||
|
Tick progress_interval;
|
||||||
BaseCPU *checker;
|
BaseCPU *checker;
|
||||||
|
|
||||||
Params();
|
Params();
|
||||||
|
|
|
@ -200,7 +200,7 @@ class BaseDynInst : public FastAlloc, public RefCounted
|
||||||
|
|
||||||
union Result {
|
union Result {
|
||||||
uint64_t integer;
|
uint64_t integer;
|
||||||
float fp;
|
// float fp;
|
||||||
double dbl;
|
double dbl;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -394,7 +394,7 @@ class BaseDynInst : public FastAlloc, public RefCounted
|
||||||
uint64_t readIntResult() { return instResult.integer; }
|
uint64_t readIntResult() { return instResult.integer; }
|
||||||
|
|
||||||
/** Returns the result of a floating point instruction. */
|
/** Returns the result of a floating point instruction. */
|
||||||
float readFloatResult() { return instResult.fp; }
|
float readFloatResult() { return (float)instResult.dbl; }
|
||||||
|
|
||||||
/** Returns the result of a floating point (double) instruction. */
|
/** Returns the result of a floating point (double) instruction. */
|
||||||
double readDoubleResult() { return instResult.dbl; }
|
double readDoubleResult() { return instResult.dbl; }
|
||||||
|
@ -406,7 +406,8 @@ class BaseDynInst : public FastAlloc, public RefCounted
|
||||||
|
|
||||||
void setFloatRegSingle(const StaticInst *si, int idx, float val)
|
void setFloatRegSingle(const StaticInst *si, int idx, float val)
|
||||||
{
|
{
|
||||||
instResult.fp = val;
|
// instResult.fp = val;
|
||||||
|
instResult.dbl = (double)val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFloatRegDouble(const StaticInst *si, int idx, double val)
|
void setFloatRegDouble(const StaticInst *si, int idx, double val)
|
||||||
|
|
|
@ -735,9 +735,20 @@ Checker<DynInstPtr>::validateState()
|
||||||
{
|
{
|
||||||
if (updateThisCycle) {
|
if (updateThisCycle) {
|
||||||
warn("%lli: Instruction PC %#x results didn't match up, copying all "
|
warn("%lli: Instruction PC %#x results didn't match up, copying all "
|
||||||
"registers from main CPU", unverifiedInst->readPC());
|
"registers from main CPU", curTick, unverifiedInst->readPC());
|
||||||
// Heavy-weight copying of all registers
|
// Heavy-weight copying of all registers
|
||||||
cpuXC->copyArchRegs(unverifiedInst->xcBase());
|
cpuXC->copyArchRegs(unverifiedInst->xcBase());
|
||||||
|
// Also advance the PC. Hopefully no PC-based events happened.
|
||||||
|
#if THE_ISA != MIPS_ISA
|
||||||
|
// go to the next instruction
|
||||||
|
cpuXC->setPC(cpuXC->readNextPC());
|
||||||
|
cpuXC->setNextPC(cpuXC->readNextPC() + sizeof(MachInst));
|
||||||
|
#else
|
||||||
|
// go to the next instruction
|
||||||
|
cpuXC->setPC(cpuXC->readNextPC());
|
||||||
|
cpuXC->setNextPC(cpuXC->readNextNPC());
|
||||||
|
cpuXC->setNextNPC(cpuXC->readNextNPC() + sizeof(MachInst));
|
||||||
|
#endif
|
||||||
updateThisCycle = false;
|
updateThisCycle = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,7 +151,7 @@ class CheckerCPU : public BaseCPU
|
||||||
|
|
||||||
virtual Counter totalInstructions() const
|
virtual Counter totalInstructions() const
|
||||||
{
|
{
|
||||||
return numInst - startNumInst;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// number of simulated loads
|
// number of simulated loads
|
||||||
|
|
|
@ -58,6 +58,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(OzoneChecker)
|
||||||
Param<Counter> max_insts_all_threads;
|
Param<Counter> max_insts_all_threads;
|
||||||
Param<Counter> max_loads_any_thread;
|
Param<Counter> max_loads_any_thread;
|
||||||
Param<Counter> max_loads_all_threads;
|
Param<Counter> max_loads_all_threads;
|
||||||
|
Param<Tick> progress_interval;
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
SimObjectParam<AlphaITB *> itb;
|
SimObjectParam<AlphaITB *> itb;
|
||||||
|
@ -91,6 +92,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(OzoneChecker)
|
||||||
"terminate when any thread reaches this load count"),
|
"terminate when any thread reaches this load count"),
|
||||||
INIT_PARAM(max_loads_all_threads,
|
INIT_PARAM(max_loads_all_threads,
|
||||||
"terminate when all threads have reached this load count"),
|
"terminate when all threads have reached this load count"),
|
||||||
|
INIT_PARAM_DFLT(progress_interval, "CPU Progress Interval", 0),
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
INIT_PARAM(itb, "Instruction TLB"),
|
INIT_PARAM(itb, "Instruction TLB"),
|
||||||
|
@ -138,6 +140,8 @@ CREATE_SIM_OBJECT(OzoneChecker)
|
||||||
temp = max_insts_all_threads;
|
temp = max_insts_all_threads;
|
||||||
temp = max_loads_any_thread;
|
temp = max_loads_any_thread;
|
||||||
temp = max_loads_all_threads;
|
temp = max_loads_all_threads;
|
||||||
|
Tick temp2 = progress_interval;
|
||||||
|
temp2++;
|
||||||
BaseMem *cache = icache;
|
BaseMem *cache = icache;
|
||||||
cache = dcache;
|
cache = dcache;
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(O3Checker)
|
||||||
Param<Counter> max_insts_all_threads;
|
Param<Counter> max_insts_all_threads;
|
||||||
Param<Counter> max_loads_any_thread;
|
Param<Counter> max_loads_any_thread;
|
||||||
Param<Counter> max_loads_all_threads;
|
Param<Counter> max_loads_all_threads;
|
||||||
|
Param<Tick> progress_interval;
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
SimObjectParam<AlphaITB *> itb;
|
SimObjectParam<AlphaITB *> itb;
|
||||||
|
@ -75,6 +76,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(O3Checker)
|
||||||
|
|
||||||
Param<bool> defer_registration;
|
Param<bool> defer_registration;
|
||||||
Param<bool> exitOnError;
|
Param<bool> exitOnError;
|
||||||
|
Param<bool> updateOnError;
|
||||||
Param<bool> function_trace;
|
Param<bool> function_trace;
|
||||||
Param<Tick> function_trace_start;
|
Param<Tick> function_trace_start;
|
||||||
|
|
||||||
|
@ -90,6 +92,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(O3Checker)
|
||||||
"terminate when any thread reaches this load count"),
|
"terminate when any thread reaches this load count"),
|
||||||
INIT_PARAM(max_loads_all_threads,
|
INIT_PARAM(max_loads_all_threads,
|
||||||
"terminate when all threads have reached this load count"),
|
"terminate when all threads have reached this load count"),
|
||||||
|
INIT_PARAM_DFLT(progress_interval, "CPU Progress Interval", 0),
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
INIT_PARAM(itb, "Instruction TLB"),
|
INIT_PARAM(itb, "Instruction TLB"),
|
||||||
|
@ -108,6 +111,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(O3Checker)
|
||||||
|
|
||||||
INIT_PARAM(defer_registration, "defer system registration (for sampling)"),
|
INIT_PARAM(defer_registration, "defer system registration (for sampling)"),
|
||||||
INIT_PARAM(exitOnError, "exit on error"),
|
INIT_PARAM(exitOnError, "exit on error"),
|
||||||
|
INIT_PARAM(updateOnError, "Update the checker with the main CPU's state on error"),
|
||||||
INIT_PARAM(function_trace, "Enable function trace"),
|
INIT_PARAM(function_trace, "Enable function trace"),
|
||||||
INIT_PARAM(function_trace_start, "Cycle to start function trace")
|
INIT_PARAM(function_trace_start, "Cycle to start function trace")
|
||||||
|
|
||||||
|
@ -124,6 +128,7 @@ CREATE_SIM_OBJECT(O3Checker)
|
||||||
params->max_loads_any_thread = 0;
|
params->max_loads_any_thread = 0;
|
||||||
params->max_loads_all_threads = 0;
|
params->max_loads_all_threads = 0;
|
||||||
params->exitOnError = exitOnError;
|
params->exitOnError = exitOnError;
|
||||||
|
params->updateOnError = updateOnError;
|
||||||
params->deferRegistration = defer_registration;
|
params->deferRegistration = defer_registration;
|
||||||
params->functionTrace = function_trace;
|
params->functionTrace = function_trace;
|
||||||
params->functionTraceStart = function_trace_start;
|
params->functionTraceStart = function_trace_start;
|
||||||
|
@ -135,6 +140,8 @@ CREATE_SIM_OBJECT(O3Checker)
|
||||||
temp = max_insts_all_threads;
|
temp = max_insts_all_threads;
|
||||||
temp = max_loads_any_thread;
|
temp = max_loads_any_thread;
|
||||||
temp = max_loads_all_threads;
|
temp = max_loads_all_threads;
|
||||||
|
Tick temp2 = progress_interval;
|
||||||
|
temp2++;
|
||||||
BaseMem *cache = icache;
|
BaseMem *cache = icache;
|
||||||
cache = dcache;
|
cache = dcache;
|
||||||
|
|
||||||
|
|
|
@ -118,6 +118,20 @@ CPUExecContext::CPUExecContext(RegFile *regFile)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
CPUExecContext::CPUExecContext()
|
||||||
|
#if !FULL_SYSTEM
|
||||||
|
: cpu(NULL), thread_num(-1), process(NULL), mem(NULL), asid(-1),
|
||||||
|
func_exe_inst(0), storeCondFailures(0)
|
||||||
|
#else
|
||||||
|
: cpu(NULL), thread_num(-1), cpu_id(-1), lastActivate(0), lastSuspend(0),
|
||||||
|
mem(NULL), itb(NULL), dtb(NULL), system(NULL), memctrl(NULL),
|
||||||
|
physmem(NULL), profile(NULL), func_exe_inst(0), storeCondFailures(0)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
regs.clear();
|
||||||
|
proxy = new ProxyExecContext<CPUExecContext>(this);
|
||||||
|
}
|
||||||
|
|
||||||
CPUExecContext::~CPUExecContext()
|
CPUExecContext::~CPUExecContext()
|
||||||
{
|
{
|
||||||
delete proxy;
|
delete proxy;
|
||||||
|
@ -158,13 +172,8 @@ CPUExecContext::takeOverFrom(ExecContext *oldContext)
|
||||||
assert(process == oldContext->getProcessPtr());
|
assert(process == oldContext->getProcessPtr());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// copy over functional state
|
copyState(oldContext);
|
||||||
_status = oldContext->status();
|
#if FULL_SYSTEM
|
||||||
copyArchRegs(oldContext);
|
|
||||||
cpu_id = oldContext->readCpuId();
|
|
||||||
#if !FULL_SYSTEM
|
|
||||||
func_exe_inst = oldContext->readFuncExeInst();
|
|
||||||
#else
|
|
||||||
EndQuiesceEvent *quiesce = oldContext->getQuiesceEvent();
|
EndQuiesceEvent *quiesce = oldContext->getQuiesceEvent();
|
||||||
if (quiesce) {
|
if (quiesce) {
|
||||||
// Point the quiesce event's XC at this XC so that it wakes up
|
// Point the quiesce event's XC at this XC so that it wakes up
|
||||||
|
@ -181,6 +190,36 @@ CPUExecContext::takeOverFrom(ExecContext *oldContext)
|
||||||
oldContext->setStatus(ExecContext::Unallocated);
|
oldContext->setStatus(ExecContext::Unallocated);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPUExecContext::copyXC(ExecContext *context)
|
||||||
|
{
|
||||||
|
copyState(context);
|
||||||
|
|
||||||
|
#if FULL_SYSTEM
|
||||||
|
EndQuiesceEvent *quiesce = context->getQuiesceEvent();
|
||||||
|
if (quiesce) {
|
||||||
|
quiesceEvent = quiesce;
|
||||||
|
}
|
||||||
|
Kernel::Statistics *stats = context->getKernelStats();
|
||||||
|
if (stats) {
|
||||||
|
kernelStats = stats;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CPUExecContext::copyState(ExecContext *oldContext)
|
||||||
|
{
|
||||||
|
// copy over functional state
|
||||||
|
_status = oldContext->status();
|
||||||
|
copyArchRegs(oldContext);
|
||||||
|
cpu_id = oldContext->readCpuId();
|
||||||
|
#if !FULL_SYSTEM
|
||||||
|
func_exe_inst = oldContext->readFuncExeInst();
|
||||||
|
#endif
|
||||||
|
inst = oldContext->getInst();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CPUExecContext::serialize(ostream &os)
|
CPUExecContext::serialize(ostream &os)
|
||||||
{
|
{
|
||||||
|
@ -294,6 +333,8 @@ CPUExecContext::regStats(const string &name)
|
||||||
void
|
void
|
||||||
CPUExecContext::copyArchRegs(ExecContext *xc)
|
CPUExecContext::copyArchRegs(ExecContext *xc)
|
||||||
{
|
{
|
||||||
|
TheISA::copyRegs(xc, proxy);
|
||||||
|
/*
|
||||||
// First loop through the integer registers.
|
// First loop through the integer registers.
|
||||||
for (int i = 0; i < AlphaISA::NumIntRegs; ++i) {
|
for (int i = 0; i < AlphaISA::NumIntRegs; ++i) {
|
||||||
setIntReg(i, xc->readIntReg(i));
|
setIntReg(i, xc->readIntReg(i));
|
||||||
|
@ -311,5 +352,6 @@ CPUExecContext::copyArchRegs(ExecContext *xc)
|
||||||
// Lastly copy PC/NPC
|
// Lastly copy PC/NPC
|
||||||
setPC(xc->readPC());
|
setPC(xc->readPC());
|
||||||
setNextPC(xc->readNextPC());
|
setNextPC(xc->readNextPC());
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -203,12 +203,19 @@ class CPUExecContext
|
||||||
// else.
|
// else.
|
||||||
CPUExecContext(RegFile *regFile);
|
CPUExecContext(RegFile *regFile);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
CPUExecContext();
|
||||||
|
|
||||||
virtual ~CPUExecContext();
|
virtual ~CPUExecContext();
|
||||||
|
|
||||||
virtual void takeOverFrom(ExecContext *oldContext);
|
virtual void takeOverFrom(ExecContext *oldContext);
|
||||||
|
|
||||||
void regStats(const std::string &name);
|
void regStats(const std::string &name);
|
||||||
|
|
||||||
|
void copyXC(ExecContext *context);
|
||||||
|
|
||||||
|
void copyState(ExecContext *oldContext);
|
||||||
|
|
||||||
void serialize(std::ostream &os);
|
void serialize(std::ostream &os);
|
||||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,7 @@ Param<Counter> max_insts_any_thread;
|
||||||
Param<Counter> max_insts_all_threads;
|
Param<Counter> max_insts_all_threads;
|
||||||
Param<Counter> max_loads_any_thread;
|
Param<Counter> max_loads_any_thread;
|
||||||
Param<Counter> max_loads_all_threads;
|
Param<Counter> max_loads_all_threads;
|
||||||
|
Param<Tick> progress_interval;
|
||||||
|
|
||||||
SimObjectParam<BaseCache *> icache;
|
SimObjectParam<BaseCache *> icache;
|
||||||
SimObjectParam<BaseCache *> dcache;
|
SimObjectParam<BaseCache *> dcache;
|
||||||
|
@ -189,6 +190,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivAlphaFullCPU)
|
||||||
"Terminate when all threads have reached this load"
|
"Terminate when all threads have reached this load"
|
||||||
"count",
|
"count",
|
||||||
0),
|
0),
|
||||||
|
INIT_PARAM_DFLT(progress_interval, "Progress interval", 0),
|
||||||
|
|
||||||
INIT_PARAM_DFLT(icache, "L1 instruction cache", NULL),
|
INIT_PARAM_DFLT(icache, "L1 instruction cache", NULL),
|
||||||
INIT_PARAM_DFLT(dcache, "L1 data cache", NULL),
|
INIT_PARAM_DFLT(dcache, "L1 data cache", NULL),
|
||||||
|
@ -327,6 +329,7 @@ CREATE_SIM_OBJECT(DerivAlphaFullCPU)
|
||||||
params->max_insts_all_threads = max_insts_all_threads;
|
params->max_insts_all_threads = max_insts_all_threads;
|
||||||
params->max_loads_any_thread = max_loads_any_thread;
|
params->max_loads_any_thread = max_loads_any_thread;
|
||||||
params->max_loads_all_threads = max_loads_all_threads;
|
params->max_loads_all_threads = max_loads_all_threads;
|
||||||
|
params->progress_interval = progress_interval;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Caches
|
// Caches
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "config/full_system.hh"
|
#include "config/full_system.hh"
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
|
#include "cpu/quiesce_event.hh"
|
||||||
#include "sim/system.hh"
|
#include "sim/system.hh"
|
||||||
#else
|
#else
|
||||||
#include "sim/process.hh"
|
#include "sim/process.hh"
|
||||||
|
@ -598,6 +599,9 @@ FullO3CPU<Impl>::activateContext(int tid, int delay)
|
||||||
// Be sure to signal that there's some activity so the CPU doesn't
|
// Be sure to signal that there's some activity so the CPU doesn't
|
||||||
// deschedule itself.
|
// deschedule itself.
|
||||||
activityRec.activity();
|
activityRec.activity();
|
||||||
|
if (thread[tid]->quiesceEvent && thread[tid]->quiesceEvent->scheduled())
|
||||||
|
thread[tid]->quiesceEvent->deschedule();
|
||||||
|
|
||||||
fetch.wakeFromQuiesce();
|
fetch.wakeFromQuiesce();
|
||||||
|
|
||||||
_status = Running;
|
_status = Running;
|
||||||
|
@ -759,7 +763,6 @@ FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
|
||||||
tickEvent.schedule(curTick);
|
tickEvent.schedule(curTick);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
void
|
void
|
||||||
FullO3CPU<Impl>::serialize(std::ostream &os)
|
FullO3CPU<Impl>::serialize(std::ostream &os)
|
||||||
|
@ -771,11 +774,11 @@ FullO3CPU<Impl>::serialize(std::ostream &os)
|
||||||
// Use SimpleThread's ability to checkpoint to make it easier to
|
// Use SimpleThread's ability to checkpoint to make it easier to
|
||||||
// write out the registers. Also make this static so it doesn't
|
// write out the registers. Also make this static so it doesn't
|
||||||
// get instantiated multiple times (causes a panic in statistics).
|
// get instantiated multiple times (causes a panic in statistics).
|
||||||
static SimpleThread temp;
|
static CPUExecContext temp;
|
||||||
|
|
||||||
for (int i = 0; i < thread.size(); i++) {
|
for (int i = 0; i < thread.size(); i++) {
|
||||||
nameOut(os, csprintf("%s.xc.%i", name(), i));
|
nameOut(os, csprintf("%s.xc.%i", name(), i));
|
||||||
temp.copyXC(thread[i]->getXC());
|
temp.copyXC(thread[i]->getXCProxy());
|
||||||
temp.serialize(os);
|
temp.serialize(os);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -790,15 +793,15 @@ FullO3CPU<Impl>::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
// Use SimpleThread's ability to checkpoint to make it easier to
|
// Use SimpleThread's ability to checkpoint to make it easier to
|
||||||
// read in the registers. Also make this static so it doesn't
|
// read in the registers. Also make this static so it doesn't
|
||||||
// get instantiated multiple times (causes a panic in statistics).
|
// get instantiated multiple times (causes a panic in statistics).
|
||||||
static SimpleThread temp;
|
static CPUExecContext temp;
|
||||||
|
|
||||||
for (int i = 0; i < thread.size(); i++) {
|
for (int i = 0; i < thread.size(); i++) {
|
||||||
temp.copyXC(thread[i]->getXC());
|
temp.copyXC(thread[i]->getXCProxy());
|
||||||
temp.unserialize(cp, csprintf("%s.xc.%i", section, i));
|
temp.unserialize(cp, csprintf("%s.xc.%i", section, i));
|
||||||
thread[i]->getXC()->copyArchRegs(temp.getXC());
|
thread[i]->getXCProxy()->copyArchRegs(temp.getProxy());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
uint64_t
|
uint64_t
|
||||||
FullO3CPU<Impl>::readIntReg(int reg_idx)
|
FullO3CPU<Impl>::readIntReg(int reg_idx)
|
||||||
|
|
|
@ -198,6 +198,13 @@ class FullO3CPU : public BaseFullCPU
|
||||||
/** Update The Order In Which We Process Threads. */
|
/** Update The Order In Which We Process Threads. */
|
||||||
void updateThreadPriority();
|
void updateThreadPriority();
|
||||||
|
|
||||||
|
/** Serialize state. */
|
||||||
|
virtual void serialize(std::ostream &os);
|
||||||
|
|
||||||
|
/** Unserialize from a checkpoint. */
|
||||||
|
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||||
|
|
||||||
|
public:
|
||||||
/** Executes a syscall on this cycle.
|
/** Executes a syscall on this cycle.
|
||||||
* ---------------------------------------
|
* ---------------------------------------
|
||||||
* Note: this is a virtual function. CPU-Specific
|
* Note: this is a virtual function. CPU-Specific
|
||||||
|
|
|
@ -60,6 +60,8 @@ TournamentBP::TournamentBP(unsigned _localPredictorSize,
|
||||||
for (int i = 0; i < localPredictorSize; ++i)
|
for (int i = 0; i < localPredictorSize; ++i)
|
||||||
localCtrs[i].setBits(localCtrBits);
|
localCtrs[i].setBits(localCtrBits);
|
||||||
|
|
||||||
|
localPredictorMask = floorPow2(localPredictorSize) - 1;
|
||||||
|
|
||||||
if (!isPowerOf2(localHistoryTableSize)) {
|
if (!isPowerOf2(localHistoryTableSize)) {
|
||||||
fatal("Invalid local history table size!\n");
|
fatal("Invalid local history table size!\n");
|
||||||
}
|
}
|
||||||
|
@ -156,7 +158,7 @@ TournamentBP::lookup(Addr &branch_addr, void * &bp_history)
|
||||||
//Lookup in the local predictor to get its branch prediction
|
//Lookup in the local predictor to get its branch prediction
|
||||||
local_history_idx = calcLocHistIdx(branch_addr);
|
local_history_idx = calcLocHistIdx(branch_addr);
|
||||||
local_predictor_idx = localHistoryTable[local_history_idx]
|
local_predictor_idx = localHistoryTable[local_history_idx]
|
||||||
& localHistoryMask;
|
& localPredictorMask;
|
||||||
local_prediction = localCtrs[local_predictor_idx].read() > threshold;
|
local_prediction = localCtrs[local_predictor_idx].read() > threshold;
|
||||||
|
|
||||||
//Lookup in the global predictor to get its branch prediction
|
//Lookup in the global predictor to get its branch prediction
|
||||||
|
@ -174,7 +176,8 @@ TournamentBP::lookup(Addr &branch_addr, void * &bp_history)
|
||||||
bp_history = (void *)history;
|
bp_history = (void *)history;
|
||||||
|
|
||||||
assert(globalHistory < globalPredictorSize &&
|
assert(globalHistory < globalPredictorSize &&
|
||||||
local_history_idx < localPredictorSize);
|
local_history_idx < localHistoryTableSize &&
|
||||||
|
local_predictor_idx < localPredictorSize);
|
||||||
|
|
||||||
// Commented code is for doing speculative update of counters and
|
// Commented code is for doing speculative update of counters and
|
||||||
// all histories.
|
// all histories.
|
||||||
|
@ -232,7 +235,7 @@ TournamentBP::update(Addr &branch_addr, bool taken, void *bp_history)
|
||||||
// Get the local predictor's current prediction
|
// Get the local predictor's current prediction
|
||||||
local_history_idx = calcLocHistIdx(branch_addr);
|
local_history_idx = calcLocHistIdx(branch_addr);
|
||||||
local_predictor_hist = localHistoryTable[local_history_idx];
|
local_predictor_hist = localHistoryTable[local_history_idx];
|
||||||
local_predictor_idx = local_predictor_hist & localHistoryMask;
|
local_predictor_idx = local_predictor_hist & localPredictorMask;
|
||||||
|
|
||||||
// Update the choice predictor to tell it which one was correct if
|
// Update the choice predictor to tell it which one was correct if
|
||||||
// there was a prediction.
|
// there was a prediction.
|
||||||
|
@ -254,6 +257,7 @@ TournamentBP::update(Addr &branch_addr, bool taken, void *bp_history)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(globalHistory < globalPredictorSize &&
|
assert(globalHistory < globalPredictorSize &&
|
||||||
|
local_history_idx < localHistoryTableSize &&
|
||||||
local_predictor_idx < localPredictorSize);
|
local_predictor_idx < localPredictorSize);
|
||||||
|
|
||||||
// Update the counters and local history with the proper
|
// Update the counters and local history with the proper
|
||||||
|
|
|
@ -158,6 +158,9 @@ class TournamentBP
|
||||||
/** Size of the local predictor. */
|
/** Size of the local predictor. */
|
||||||
unsigned localPredictorSize;
|
unsigned localPredictorSize;
|
||||||
|
|
||||||
|
/** Mask to get the proper index bits into the predictor. */
|
||||||
|
unsigned localPredictorMask;
|
||||||
|
|
||||||
/** Number of bits of the local predictor's counters. */
|
/** Number of bits of the local predictor's counters. */
|
||||||
unsigned localCtrBits;
|
unsigned localCtrBits;
|
||||||
|
|
||||||
|
|
|
@ -300,8 +300,6 @@ class OzoneCPU : public BaseCPU
|
||||||
Status _status;
|
Status _status;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool checkInterrupts;
|
|
||||||
|
|
||||||
void post_interrupt(int int_num, int index);
|
void post_interrupt(int int_num, int index);
|
||||||
|
|
||||||
void zero_fill_64(Addr addr) {
|
void zero_fill_64(Addr addr) {
|
||||||
|
|
|
@ -84,6 +84,7 @@ Param<Counter> max_insts_any_thread;
|
||||||
Param<Counter> max_insts_all_threads;
|
Param<Counter> max_insts_all_threads;
|
||||||
Param<Counter> max_loads_any_thread;
|
Param<Counter> max_loads_any_thread;
|
||||||
Param<Counter> max_loads_all_threads;
|
Param<Counter> max_loads_all_threads;
|
||||||
|
Param<Tick> progress_interval;
|
||||||
|
|
||||||
SimObjectParam<BaseCache *> icache;
|
SimObjectParam<BaseCache *> icache;
|
||||||
SimObjectParam<BaseCache *> dcache;
|
SimObjectParam<BaseCache *> dcache;
|
||||||
|
@ -212,6 +213,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivOzoneCPU)
|
||||||
"Terminate when all threads have reached this load"
|
"Terminate when all threads have reached this load"
|
||||||
"count",
|
"count",
|
||||||
0),
|
0),
|
||||||
|
INIT_PARAM_DFLT(progress_interval, "Progress interval", 0),
|
||||||
|
|
||||||
INIT_PARAM_DFLT(icache, "L1 instruction cache", NULL),
|
INIT_PARAM_DFLT(icache, "L1 instruction cache", NULL),
|
||||||
INIT_PARAM_DFLT(dcache, "L1 data cache", NULL),
|
INIT_PARAM_DFLT(dcache, "L1 data cache", NULL),
|
||||||
|
@ -355,6 +357,7 @@ CREATE_SIM_OBJECT(DerivOzoneCPU)
|
||||||
params->max_insts_all_threads = max_insts_all_threads;
|
params->max_insts_all_threads = max_insts_all_threads;
|
||||||
params->max_loads_any_thread = max_loads_any_thread;
|
params->max_loads_any_thread = max_loads_any_thread;
|
||||||
params->max_loads_all_threads = max_loads_all_threads;
|
params->max_loads_all_threads = max_loads_all_threads;
|
||||||
|
params->progress_interval = progress_interval;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Caches
|
// Caches
|
||||||
|
|
|
@ -249,6 +249,9 @@ OzoneCPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
|
||||||
{
|
{
|
||||||
BaseCPU::takeOverFrom(oldCPU);
|
BaseCPU::takeOverFrom(oldCPU);
|
||||||
|
|
||||||
|
thread.trapPending = false;
|
||||||
|
thread.inSyscall = false;
|
||||||
|
|
||||||
backEnd->takeOverFrom();
|
backEnd->takeOverFrom();
|
||||||
frontEnd->takeOverFrom();
|
frontEnd->takeOverFrom();
|
||||||
assert(!tickEvent.scheduled());
|
assert(!tickEvent.scheduled());
|
||||||
|
@ -288,6 +291,8 @@ OzoneCPU<Impl>::activateContext(int thread_num, int delay)
|
||||||
scheduleTickEvent(delay);
|
scheduleTickEvent(delay);
|
||||||
_status = Running;
|
_status = Running;
|
||||||
thread._status = ExecContext::Active;
|
thread._status = ExecContext::Active;
|
||||||
|
if (thread.quiesceEvent && thread.quiesceEvent->scheduled())
|
||||||
|
thread.quiesceEvent->deschedule();
|
||||||
frontEnd->wakeFromQuiesce();
|
frontEnd->wakeFromQuiesce();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,11 +400,17 @@ void
|
||||||
OzoneCPU<Impl>::serialize(std::ostream &os)
|
OzoneCPU<Impl>::serialize(std::ostream &os)
|
||||||
{
|
{
|
||||||
BaseCPU::serialize(os);
|
BaseCPU::serialize(os);
|
||||||
SERIALIZE_ENUM(_status);
|
|
||||||
nameOut(os, csprintf("%s.xc", name()));
|
|
||||||
ozoneXC.serialize(os);
|
|
||||||
nameOut(os, csprintf("%s.tickEvent", name()));
|
nameOut(os, csprintf("%s.tickEvent", name()));
|
||||||
tickEvent.serialize(os);
|
tickEvent.serialize(os);
|
||||||
|
|
||||||
|
// Use SimpleThread's ability to checkpoint to make it easier to
|
||||||
|
// write out the registers. Also make this static so it doesn't
|
||||||
|
// get instantiated multiple times (causes a panic in statistics).
|
||||||
|
static CPUExecContext temp;
|
||||||
|
|
||||||
|
nameOut(os, csprintf("%s.xc.0", name()));
|
||||||
|
temp.copyXC(thread.getXCProxy());
|
||||||
|
temp.serialize(os);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
|
@ -407,9 +418,16 @@ void
|
||||||
OzoneCPU<Impl>::unserialize(Checkpoint *cp, const std::string §ion)
|
OzoneCPU<Impl>::unserialize(Checkpoint *cp, const std::string §ion)
|
||||||
{
|
{
|
||||||
BaseCPU::unserialize(cp, section);
|
BaseCPU::unserialize(cp, section);
|
||||||
UNSERIALIZE_ENUM(_status);
|
|
||||||
ozoneXC.unserialize(cp, csprintf("%s.xc", section));
|
|
||||||
tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
|
tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
|
||||||
|
|
||||||
|
// Use SimpleThread's ability to checkpoint to make it easier to
|
||||||
|
// read in the registers. Also make this static so it doesn't
|
||||||
|
// get instantiated multiple times (causes a panic in statistics).
|
||||||
|
static CPUExecContext temp;
|
||||||
|
|
||||||
|
temp.copyXC(thread.getXCProxy());
|
||||||
|
temp.unserialize(cp, csprintf("%s.xc.0", section));
|
||||||
|
thread.getXCProxy()->copyArchRegs(temp.getProxy());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Impl>
|
template <class Impl>
|
||||||
|
|
|
@ -353,7 +353,7 @@ FrontEnd<Impl>::tick()
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
if (inst->isQuiesce()) {
|
if (inst->isQuiesce()) {
|
||||||
warn("%lli: Quiesce instruction encountered, halting fetch!", curTick);
|
// warn("%lli: Quiesce instruction encountered, halting fetch!", curTick);
|
||||||
status = QuiescePending;
|
status = QuiescePending;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1499,7 +1499,6 @@ template <class Impl>
|
||||||
void
|
void
|
||||||
LWBackEnd<Impl>::takeOverFrom(ExecContext *old_xc)
|
LWBackEnd<Impl>::takeOverFrom(ExecContext *old_xc)
|
||||||
{
|
{
|
||||||
switchedOut = false;
|
|
||||||
xcSquash = false;
|
xcSquash = false;
|
||||||
trapSquash = false;
|
trapSquash = false;
|
||||||
|
|
||||||
|
|
|
@ -304,7 +304,7 @@ SimpleCPU::serialize(ostream &os)
|
||||||
BaseCPU::serialize(os);
|
BaseCPU::serialize(os);
|
||||||
SERIALIZE_ENUM(_status);
|
SERIALIZE_ENUM(_status);
|
||||||
SERIALIZE_SCALAR(inst);
|
SERIALIZE_SCALAR(inst);
|
||||||
nameOut(os, csprintf("%s.xc", name()));
|
nameOut(os, csprintf("%s.xc.0", name()));
|
||||||
cpuXC->serialize(os);
|
cpuXC->serialize(os);
|
||||||
nameOut(os, csprintf("%s.tickEvent", name()));
|
nameOut(os, csprintf("%s.tickEvent", name()));
|
||||||
tickEvent.serialize(os);
|
tickEvent.serialize(os);
|
||||||
|
@ -318,7 +318,7 @@ SimpleCPU::unserialize(Checkpoint *cp, const string §ion)
|
||||||
BaseCPU::unserialize(cp, section);
|
BaseCPU::unserialize(cp, section);
|
||||||
UNSERIALIZE_ENUM(_status);
|
UNSERIALIZE_ENUM(_status);
|
||||||
UNSERIALIZE_SCALAR(inst);
|
UNSERIALIZE_SCALAR(inst);
|
||||||
cpuXC->unserialize(cp, csprintf("%s.xc", section));
|
cpuXC->unserialize(cp, csprintf("%s.xc.0", section));
|
||||||
tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
|
tickEvent.unserialize(cp, csprintf("%s.tickEvent", section));
|
||||||
cacheCompletionEvent
|
cacheCompletionEvent
|
||||||
.unserialize(cp, csprintf("%s.cacheCompletionEvent", section));
|
.unserialize(cp, csprintf("%s.cacheCompletionEvent", section));
|
||||||
|
@ -863,6 +863,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU)
|
||||||
Param<Counter> max_insts_all_threads;
|
Param<Counter> max_insts_all_threads;
|
||||||
Param<Counter> max_loads_any_thread;
|
Param<Counter> max_loads_any_thread;
|
||||||
Param<Counter> max_loads_all_threads;
|
Param<Counter> max_loads_all_threads;
|
||||||
|
Param<Tick> progress_interval;
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
SimObjectParam<AlphaITB *> itb;
|
SimObjectParam<AlphaITB *> itb;
|
||||||
|
@ -896,6 +897,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleCPU)
|
||||||
"terminate when any thread reaches this load count"),
|
"terminate when any thread reaches this load count"),
|
||||||
INIT_PARAM(max_loads_all_threads,
|
INIT_PARAM(max_loads_all_threads,
|
||||||
"terminate when all threads have reached this load count"),
|
"terminate when all threads have reached this load count"),
|
||||||
|
INIT_PARAM_DFLT(progress_interval, "CPU Progress interval", 0),
|
||||||
|
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
INIT_PARAM(itb, "Instruction TLB"),
|
INIT_PARAM(itb, "Instruction TLB"),
|
||||||
|
@ -936,6 +938,7 @@ CREATE_SIM_OBJECT(SimpleCPU)
|
||||||
params->dcache_interface = (dcache) ? dcache->getInterface() : NULL;
|
params->dcache_interface = (dcache) ? dcache->getInterface() : NULL;
|
||||||
params->width = width;
|
params->width = width;
|
||||||
|
|
||||||
|
params->progress_interval = progress_interval;
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
params->itb = itb;
|
params->itb = itb;
|
||||||
params->dtb = dtb;
|
params->dtb = dtb;
|
||||||
|
|
|
@ -22,6 +22,7 @@ class BaseCPU(SimObject):
|
||||||
"terminate when all threads have reached this load count")
|
"terminate when all threads have reached this load count")
|
||||||
max_loads_any_thread = Param.Counter(0,
|
max_loads_any_thread = Param.Counter(0,
|
||||||
"terminate when any thread reaches this load count")
|
"terminate when any thread reaches this load count")
|
||||||
|
progress_interval = Param.Tick(0, "interval to print out the progress message")
|
||||||
|
|
||||||
defer_registration = Param.Bool(False,
|
defer_registration = Param.Bool(False,
|
||||||
"defer registration with system (for sampling)")
|
"defer registration with system (for sampling)")
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from m5 import *
|
from m5 import *
|
||||||
from HierParams import HierParams
|
from HierParams import HierParams
|
||||||
from Serialize import Serialize
|
from Serialize import Serialize
|
||||||
|
from Serialize import Statreset
|
||||||
from Statistics import Statistics
|
from Statistics import Statistics
|
||||||
from Trace import Trace
|
from Trace import Trace
|
||||||
from ExeTrace import ExecutionTrace
|
from ExeTrace import ExecutionTrace
|
||||||
|
@ -23,3 +24,4 @@ class Root(SimObject):
|
||||||
trace = Trace()
|
trace = Trace()
|
||||||
exetrace = ExecutionTrace()
|
exetrace = ExecutionTrace()
|
||||||
serialize = Serialize()
|
serialize = Serialize()
|
||||||
|
statsreset = Statreset()
|
||||||
|
|
|
@ -49,6 +49,9 @@
|
||||||
#include "sim/sim_exit.hh"
|
#include "sim/sim_exit.hh"
|
||||||
#include "sim/sim_object.hh"
|
#include "sim/sim_object.hh"
|
||||||
|
|
||||||
|
// For stat reset hack
|
||||||
|
#include "sim/stat_control.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
int Serializable::ckptMaxCount = 0;
|
int Serializable::ckptMaxCount = 0;
|
||||||
|
@ -482,3 +485,36 @@ Checkpoint::sectionExists(const std::string §ion)
|
||||||
{
|
{
|
||||||
return db->sectionExists(section);
|
return db->sectionExists(section);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Hacked stat reset event */
|
||||||
|
|
||||||
|
class StatresetParamContext : public ParamContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StatresetParamContext(const string §ion);
|
||||||
|
~StatresetParamContext();
|
||||||
|
void startup();
|
||||||
|
};
|
||||||
|
|
||||||
|
StatresetParamContext statParams("statsreset");
|
||||||
|
|
||||||
|
Param<Tick> reset_cycle(&statParams, "reset_cycle",
|
||||||
|
"Cycle to reset stats on", 0);
|
||||||
|
|
||||||
|
StatresetParamContext::StatresetParamContext(const string §ion)
|
||||||
|
: ParamContext(section)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
StatresetParamContext::~StatresetParamContext()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
StatresetParamContext::startup()
|
||||||
|
{
|
||||||
|
if (reset_cycle > 0) {
|
||||||
|
Stats::SetupEvent(Stats::Reset, curTick + reset_cycle, 0);
|
||||||
|
cprintf("Stats reset event scheduled for %lli\n",
|
||||||
|
curTick + reset_cycle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -183,8 +183,10 @@ StatEvent::process()
|
||||||
if (flags & Stats::Dump)
|
if (flags & Stats::Dump)
|
||||||
DumpNow();
|
DumpNow();
|
||||||
|
|
||||||
if (flags & Stats::Reset)
|
if (flags & Stats::Reset) {
|
||||||
|
cprintf("Resetting stats!\n");
|
||||||
reset();
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
if (repeat)
|
if (repeat)
|
||||||
schedule(curTick + repeat);
|
schedule(curTick + repeat);
|
||||||
|
|
Loading…
Reference in a new issue