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:
Kevin Lim 2006-08-11 17:42:59 -04:00
parent 5ec58c4bdc
commit 716ceb6c10
25 changed files with 241 additions and 35 deletions

View file

@ -168,6 +168,9 @@ namespace AlphaISA
typedef union {
uint64_t q[NumFloatRegs]; // integer qword view
double d[NumFloatRegs]; // double-precision floating point view
void clear()
{ bzero(d, sizeof(d)); }
} FloatRegFile;
extern const Addr PageShift;
@ -266,6 +269,13 @@ extern const int reg_redir[NumIntRegs];
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
void clear()
{
bzero(intRegFile, sizeof(intRegFile));
floatRegFile.clear();
miscRegs.clear();
}
};
static inline ExtMachInst makeExtMI(MachInst inst, const uint64_t &pc);

View file

@ -54,6 +54,26 @@ vector<BaseCPU *> BaseCPU::cpuList;
// been initialized
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
BaseCPU::BaseCPU(Params *p)
: SimObject(p->name), clock(p->clock), checkInterrupts(true),
@ -150,7 +170,6 @@ BaseCPU::BaseCPU(Params *p)
if (params->profile)
profileEvent = new ProfileEvent(this, params->profile);
#endif
}
BaseCPU::Params::Params()
@ -185,6 +204,11 @@ BaseCPU::startup()
if (!params->deferRegistration && profileEvent)
profileEvent->schedule(curTick);
#endif
if (params->progress_interval) {
new CPUProgressEvent(&mainEventQueue, params->progress_interval,
this);
}
}

View file

@ -43,6 +43,23 @@ class CheckerCPU;
class ExecContext;
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
{
protected:
@ -125,6 +142,7 @@ class BaseCPU : public SimObject
int cpu_id;
Tick profile;
#endif
Tick progress_interval;
BaseCPU *checker;
Params();

View file

@ -200,7 +200,7 @@ class BaseDynInst : public FastAlloc, public RefCounted
union Result {
uint64_t integer;
float fp;
// float fp;
double dbl;
};
@ -394,7 +394,7 @@ class BaseDynInst : public FastAlloc, public RefCounted
uint64_t readIntResult() { return instResult.integer; }
/** 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. */
double readDoubleResult() { return instResult.dbl; }
@ -406,7 +406,8 @@ class BaseDynInst : public FastAlloc, public RefCounted
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)

View file

@ -735,9 +735,20 @@ Checker<DynInstPtr>::validateState()
{
if (updateThisCycle) {
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
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;
}
}

View file

@ -151,7 +151,7 @@ class CheckerCPU : public BaseCPU
virtual Counter totalInstructions() const
{
return numInst - startNumInst;
return 0;
}
// number of simulated loads

View file

@ -58,6 +58,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(OzoneChecker)
Param<Counter> max_insts_all_threads;
Param<Counter> max_loads_any_thread;
Param<Counter> max_loads_all_threads;
Param<Tick> progress_interval;
#if FULL_SYSTEM
SimObjectParam<AlphaITB *> itb;
@ -91,6 +92,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(OzoneChecker)
"terminate when any thread reaches this load count"),
INIT_PARAM(max_loads_all_threads,
"terminate when all threads have reached this load count"),
INIT_PARAM_DFLT(progress_interval, "CPU Progress Interval", 0),
#if FULL_SYSTEM
INIT_PARAM(itb, "Instruction TLB"),
@ -138,6 +140,8 @@ CREATE_SIM_OBJECT(OzoneChecker)
temp = max_insts_all_threads;
temp = max_loads_any_thread;
temp = max_loads_all_threads;
Tick temp2 = progress_interval;
temp2++;
BaseMem *cache = icache;
cache = dcache;

View file

@ -58,6 +58,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(O3Checker)
Param<Counter> max_insts_all_threads;
Param<Counter> max_loads_any_thread;
Param<Counter> max_loads_all_threads;
Param<Tick> progress_interval;
#if FULL_SYSTEM
SimObjectParam<AlphaITB *> itb;
@ -75,6 +76,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(O3Checker)
Param<bool> defer_registration;
Param<bool> exitOnError;
Param<bool> updateOnError;
Param<bool> function_trace;
Param<Tick> function_trace_start;
@ -90,6 +92,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(O3Checker)
"terminate when any thread reaches this load count"),
INIT_PARAM(max_loads_all_threads,
"terminate when all threads have reached this load count"),
INIT_PARAM_DFLT(progress_interval, "CPU Progress Interval", 0),
#if FULL_SYSTEM
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(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_start, "Cycle to start function trace")
@ -124,6 +128,7 @@ CREATE_SIM_OBJECT(O3Checker)
params->max_loads_any_thread = 0;
params->max_loads_all_threads = 0;
params->exitOnError = exitOnError;
params->updateOnError = updateOnError;
params->deferRegistration = defer_registration;
params->functionTrace = function_trace;
params->functionTraceStart = function_trace_start;
@ -135,6 +140,8 @@ CREATE_SIM_OBJECT(O3Checker)
temp = max_insts_all_threads;
temp = max_loads_any_thread;
temp = max_loads_all_threads;
Tick temp2 = progress_interval;
temp2++;
BaseMem *cache = icache;
cache = dcache;

View file

@ -118,6 +118,20 @@ CPUExecContext::CPUExecContext(RegFile *regFile)
#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()
{
delete proxy;
@ -158,13 +172,8 @@ CPUExecContext::takeOverFrom(ExecContext *oldContext)
assert(process == oldContext->getProcessPtr());
#endif
// copy over functional state
_status = oldContext->status();
copyArchRegs(oldContext);
cpu_id = oldContext->readCpuId();
#if !FULL_SYSTEM
func_exe_inst = oldContext->readFuncExeInst();
#else
copyState(oldContext);
#if FULL_SYSTEM
EndQuiesceEvent *quiesce = oldContext->getQuiesceEvent();
if (quiesce) {
// 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);
}
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
CPUExecContext::serialize(ostream &os)
{
@ -294,6 +333,8 @@ CPUExecContext::regStats(const string &name)
void
CPUExecContext::copyArchRegs(ExecContext *xc)
{
TheISA::copyRegs(xc, proxy);
/*
// First loop through the integer registers.
for (int i = 0; i < AlphaISA::NumIntRegs; ++i) {
setIntReg(i, xc->readIntReg(i));
@ -311,5 +352,6 @@ CPUExecContext::copyArchRegs(ExecContext *xc)
// Lastly copy PC/NPC
setPC(xc->readPC());
setNextPC(xc->readNextPC());
*/
}

View file

@ -203,12 +203,19 @@ class CPUExecContext
// else.
CPUExecContext(RegFile *regFile);
#endif
CPUExecContext();
virtual ~CPUExecContext();
virtual void takeOverFrom(ExecContext *oldContext);
void regStats(const std::string &name);
void copyXC(ExecContext *context);
void copyState(ExecContext *oldContext);
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);

View file

@ -68,6 +68,7 @@ Param<Counter> max_insts_any_thread;
Param<Counter> max_insts_all_threads;
Param<Counter> max_loads_any_thread;
Param<Counter> max_loads_all_threads;
Param<Tick> progress_interval;
SimObjectParam<BaseCache *> icache;
SimObjectParam<BaseCache *> dcache;
@ -189,6 +190,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivAlphaFullCPU)
"Terminate when all threads have reached this load"
"count",
0),
INIT_PARAM_DFLT(progress_interval, "Progress interval", 0),
INIT_PARAM_DFLT(icache, "L1 instruction 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_loads_any_thread = max_loads_any_thread;
params->max_loads_all_threads = max_loads_all_threads;
params->progress_interval = progress_interval;
//
// Caches

View file

@ -29,6 +29,7 @@
#include "config/full_system.hh"
#if FULL_SYSTEM
#include "cpu/quiesce_event.hh"
#include "sim/system.hh"
#else
#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
// deschedule itself.
activityRec.activity();
if (thread[tid]->quiesceEvent && thread[tid]->quiesceEvent->scheduled())
thread[tid]->quiesceEvent->deschedule();
fetch.wakeFromQuiesce();
_status = Running;
@ -759,7 +763,6 @@ FullO3CPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
tickEvent.schedule(curTick);
}
/*
template <class Impl>
void
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
// write out the registers. Also make this static so it doesn't
// get instantiated multiple times (causes a panic in statistics).
static SimpleThread temp;
static CPUExecContext temp;
for (int i = 0; i < thread.size(); i++) {
nameOut(os, csprintf("%s.xc.%i", name(), i));
temp.copyXC(thread[i]->getXC());
temp.copyXC(thread[i]->getXCProxy());
temp.serialize(os);
}
}
@ -790,15 +793,15 @@ FullO3CPU<Impl>::unserialize(Checkpoint *cp, const std::string &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 SimpleThread temp;
static CPUExecContext temp;
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));
thread[i]->getXC()->copyArchRegs(temp.getXC());
thread[i]->getXCProxy()->copyArchRegs(temp.getProxy());
}
}
*/
template <class Impl>
uint64_t
FullO3CPU<Impl>::readIntReg(int reg_idx)

View file

@ -198,6 +198,13 @@ class FullO3CPU : public BaseFullCPU
/** Update The Order In Which We Process Threads. */
void updateThreadPriority();
/** Serialize state. */
virtual void serialize(std::ostream &os);
/** Unserialize from a checkpoint. */
virtual void unserialize(Checkpoint *cp, const std::string &section);
public:
/** Executes a syscall on this cycle.
* ---------------------------------------
* Note: this is a virtual function. CPU-Specific

View file

@ -60,6 +60,8 @@ TournamentBP::TournamentBP(unsigned _localPredictorSize,
for (int i = 0; i < localPredictorSize; ++i)
localCtrs[i].setBits(localCtrBits);
localPredictorMask = floorPow2(localPredictorSize) - 1;
if (!isPowerOf2(localHistoryTableSize)) {
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
local_history_idx = calcLocHistIdx(branch_addr);
local_predictor_idx = localHistoryTable[local_history_idx]
& localHistoryMask;
& localPredictorMask;
local_prediction = localCtrs[local_predictor_idx].read() > threshold;
//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;
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
// all histories.
@ -232,7 +235,7 @@ TournamentBP::update(Addr &branch_addr, bool taken, void *bp_history)
// Get the local predictor's current prediction
local_history_idx = calcLocHistIdx(branch_addr);
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
// there was a prediction.
@ -254,6 +257,7 @@ TournamentBP::update(Addr &branch_addr, bool taken, void *bp_history)
}
assert(globalHistory < globalPredictorSize &&
local_history_idx < localHistoryTableSize &&
local_predictor_idx < localPredictorSize);
// Update the counters and local history with the proper

View file

@ -158,6 +158,9 @@ class TournamentBP
/** Size of the local predictor. */
unsigned localPredictorSize;
/** Mask to get the proper index bits into the predictor. */
unsigned localPredictorMask;
/** Number of bits of the local predictor's counters. */
unsigned localCtrBits;

View file

@ -300,8 +300,6 @@ class OzoneCPU : public BaseCPU
Status _status;
public:
bool checkInterrupts;
void post_interrupt(int int_num, int index);
void zero_fill_64(Addr addr) {

View file

@ -84,6 +84,7 @@ Param<Counter> max_insts_any_thread;
Param<Counter> max_insts_all_threads;
Param<Counter> max_loads_any_thread;
Param<Counter> max_loads_all_threads;
Param<Tick> progress_interval;
SimObjectParam<BaseCache *> icache;
SimObjectParam<BaseCache *> dcache;
@ -212,6 +213,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(DerivOzoneCPU)
"Terminate when all threads have reached this load"
"count",
0),
INIT_PARAM_DFLT(progress_interval, "Progress interval", 0),
INIT_PARAM_DFLT(icache, "L1 instruction 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_loads_any_thread = max_loads_any_thread;
params->max_loads_all_threads = max_loads_all_threads;
params->progress_interval = progress_interval;
//
// Caches

View file

@ -249,6 +249,9 @@ OzoneCPU<Impl>::takeOverFrom(BaseCPU *oldCPU)
{
BaseCPU::takeOverFrom(oldCPU);
thread.trapPending = false;
thread.inSyscall = false;
backEnd->takeOverFrom();
frontEnd->takeOverFrom();
assert(!tickEvent.scheduled());
@ -288,6 +291,8 @@ OzoneCPU<Impl>::activateContext(int thread_num, int delay)
scheduleTickEvent(delay);
_status = Running;
thread._status = ExecContext::Active;
if (thread.quiesceEvent && thread.quiesceEvent->scheduled())
thread.quiesceEvent->deschedule();
frontEnd->wakeFromQuiesce();
}
@ -395,11 +400,17 @@ void
OzoneCPU<Impl>::serialize(std::ostream &os)
{
BaseCPU::serialize(os);
SERIALIZE_ENUM(_status);
nameOut(os, csprintf("%s.xc", name()));
ozoneXC.serialize(os);
nameOut(os, csprintf("%s.tickEvent", name()));
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>
@ -407,9 +418,16 @@ void
OzoneCPU<Impl>::unserialize(Checkpoint *cp, const std::string &section)
{
BaseCPU::unserialize(cp, section);
UNSERIALIZE_ENUM(_status);
ozoneXC.unserialize(cp, csprintf("%s.xc", 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>

View file

@ -353,7 +353,7 @@ FrontEnd<Impl>::tick()
#if FULL_SYSTEM
if (inst->isQuiesce()) {
warn("%lli: Quiesce instruction encountered, halting fetch!", curTick);
// warn("%lli: Quiesce instruction encountered, halting fetch!", curTick);
status = QuiescePending;
break;
}

View file

@ -1499,7 +1499,6 @@ template <class Impl>
void
LWBackEnd<Impl>::takeOverFrom(ExecContext *old_xc)
{
switchedOut = false;
xcSquash = false;
trapSquash = false;

View file

@ -304,7 +304,7 @@ SimpleCPU::serialize(ostream &os)
BaseCPU::serialize(os);
SERIALIZE_ENUM(_status);
SERIALIZE_SCALAR(inst);
nameOut(os, csprintf("%s.xc", name()));
nameOut(os, csprintf("%s.xc.0", name()));
cpuXC->serialize(os);
nameOut(os, csprintf("%s.tickEvent", name()));
tickEvent.serialize(os);
@ -318,7 +318,7 @@ SimpleCPU::unserialize(Checkpoint *cp, const string &section)
BaseCPU::unserialize(cp, section);
UNSERIALIZE_ENUM(_status);
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));
cacheCompletionEvent
.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_loads_any_thread;
Param<Counter> max_loads_all_threads;
Param<Tick> progress_interval;
#if FULL_SYSTEM
SimObjectParam<AlphaITB *> itb;
@ -896,6 +897,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleCPU)
"terminate when any thread reaches this load count"),
INIT_PARAM(max_loads_all_threads,
"terminate when all threads have reached this load count"),
INIT_PARAM_DFLT(progress_interval, "CPU Progress interval", 0),
#if FULL_SYSTEM
INIT_PARAM(itb, "Instruction TLB"),
@ -936,6 +938,7 @@ CREATE_SIM_OBJECT(SimpleCPU)
params->dcache_interface = (dcache) ? dcache->getInterface() : NULL;
params->width = width;
params->progress_interval = progress_interval;
#if FULL_SYSTEM
params->itb = itb;
params->dtb = dtb;

View file

@ -22,6 +22,7 @@ class BaseCPU(SimObject):
"terminate when all threads have reached this load count")
max_loads_any_thread = Param.Counter(0,
"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 with system (for sampling)")

View file

@ -1,6 +1,7 @@
from m5 import *
from HierParams import HierParams
from Serialize import Serialize
from Serialize import Statreset
from Statistics import Statistics
from Trace import Trace
from ExeTrace import ExecutionTrace
@ -23,3 +24,4 @@ class Root(SimObject):
trace = Trace()
exetrace = ExecutionTrace()
serialize = Serialize()
statsreset = Statreset()

View file

@ -49,6 +49,9 @@
#include "sim/sim_exit.hh"
#include "sim/sim_object.hh"
// For stat reset hack
#include "sim/stat_control.hh"
using namespace std;
int Serializable::ckptMaxCount = 0;
@ -482,3 +485,36 @@ Checkpoint::sectionExists(const std::string &section)
{
return db->sectionExists(section);
}
/** Hacked stat reset event */
class StatresetParamContext : public ParamContext
{
public:
StatresetParamContext(const string &section);
~StatresetParamContext();
void startup();
};
StatresetParamContext statParams("statsreset");
Param<Tick> reset_cycle(&statParams, "reset_cycle",
"Cycle to reset stats on", 0);
StatresetParamContext::StatresetParamContext(const string &section)
: 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);
}
}

View file

@ -183,8 +183,10 @@ StatEvent::process()
if (flags & Stats::Dump)
DumpNow();
if (flags & Stats::Reset)
if (flags & Stats::Reset) {
cprintf("Resetting stats!\n");
reset();
}
if (repeat)
schedule(curTick + repeat);