diff -r 08b1188e55dd -r 7f2de0cd1ea1 src/cpu/BaseCPU.py --- a/src/cpu/BaseCPU.py Fri Jan 07 12:11:09 2011 -0800 +++ b/src/cpu/BaseCPU.py Mon Jan 10 10:46:30 2011 -0800 @@ -179,6 +179,20 @@ if buildEnv['TARGET_ISA'] == 'x86': self._mem_ports += ["interrupts.pio", "interrupts.int_port"] + def addPrivateSplitL1CachesWithMemDebuggers(self, ic, dc, mt_i, mt_d): + assert(len(self._mem_ports) < 6) + self.icache = ic + self.dcache = dc + self.memtester_i = mt_i + self.memtester_d = mt_d + self.icache_port = mt_i.cpu_side + self.dcache_port = mt_d.cpu_side + mt_i.mem_side = ic.cpu_side + mt_d.mem_side = dc.cpu_side + self._mem_ports = ['icache.mem_side','dcache.mem_side'] + if build_env['TARGET_ISA'] == 'x86' and build_env['FULL_SYSTEM']: + self._mem_ports += ["itb.walker_port", "dtb.walker_port"] + def addTwoLevelCacheHierarchy(self, ic, dc, l2c): self.addPrivateSplitL1Caches(ic, dc) self.toL2Bus = Bus() diff -r 08b1188e55dd -r 7f2de0cd1ea1 src/cpu/base.cc --- a/src/cpu/base.cc Fri Jan 07 12:11:09 2011 -0800 +++ b/src/cpu/base.cc Mon Jan 10 10:46:30 2011 -0800 @@ -97,6 +97,7 @@ return "CPU Progress"; } + #if FULL_SYSTEM BaseCPU::BaseCPU(Params *p) : MemObject(p), clock(p->clock), instCnt(0), _cpuId(p->cpu_id), @@ -135,7 +136,7 @@ // set up instruction-count-based termination events, if any // if (p->max_insts_any_thread != 0) { - const char *cause = "a thread reached the max instruction count"; + static const char *cause = "a thread reached the max instruction count"; for (ThreadID tid = 0; tid < numThreads; ++tid) { Event *event = new SimLoopExitEvent(cause, 0); comInstEventQueue[tid]->schedule(event, p->max_insts_any_thread); diff -r 08b1188e55dd -r 7f2de0cd1ea1 src/cpu/o3/commit.hh --- a/src/cpu/o3/commit.hh Fri Jan 07 12:11:09 2011 -0800 +++ b/src/cpu/o3/commit.hh Mon Jan 10 10:46:30 2011 -0800 @@ -455,6 +455,12 @@ Stats::Vector statComMembars; /** Total number of committed branches. */ Stats::Vector statComBranches; + /** Total number of floating point instructions */ + Stats::Vector statComFloating; + /** Total number of integer instructions */ + Stats::Vector statComInteger; + /** Total number of function calls */ + Stats::Vector statComFunctionCalls; /** Number of cycles where the commit bandwidth limit is reached. */ Stats::Scalar commitEligibleSamples; diff -r 08b1188e55dd -r 7f2de0cd1ea1 src/cpu/o3/commit_impl.hh --- a/src/cpu/o3/commit_impl.hh Fri Jan 07 12:11:09 2011 -0800 +++ b/src/cpu/o3/commit_impl.hh Mon Jan 10 10:46:30 2011 -0800 @@ -229,6 +229,27 @@ .flags(total) ; + statComFloating + .init(cpu->numThreads) + .name(name() + ".COM:fp_insts") + .desc("Number of committed floating point instructions.") + .flags(total) + ; + + statComInteger + .init(cpu->numThreads) + .name(name()+".COM:int_insts") + .desc("Number of committed integer instructions.") + .flags(total) + ; + + statComFunctionCalls + .init(cpu->numThreads) + .name(name()+".COM:function_calls") + .desc("Number of function calls committed.") + .flags(total) + ; + commitEligible .init(cpu->numThreads) .name(name() + ".COM:bw_limited") @@ -1301,6 +1322,19 @@ if (inst->isMemBarrier()) { statComMembars[tid]++; } + + // Integer Instruction + if (inst->isInteger()) + statComInteger[tid]++; + + // Floating Point Instruction + if (inst->isFloating()) + statComFloating[tid]++; + + // Function Calls + if (inst->isCall()) + statComFunctionCalls[tid]++; + } //////////////////////////////////////// diff -r 08b1188e55dd -r 7f2de0cd1ea1 src/cpu/o3/cpu.hh --- a/src/cpu/o3/cpu.hh Fri Jan 07 12:11:09 2011 -0800 +++ b/src/cpu/o3/cpu.hh Mon Jan 10 10:46:30 2011 -0800 @@ -726,6 +726,16 @@ Stats::Formula ipc; /** Stat for the total IPC. */ Stats::Formula totalIpc; + + //number of integer register file accesses + Stats::Scalar intRegfileReads; + Stats::Scalar intRegfileWrites; + //number of float register file accesses + Stats::Scalar fpRegfileReads; + Stats::Scalar fpRegfileWrites; + //number of misc + Stats::Scalar miscRegfileReads; + Stats::Scalar miscRegfileWrites; }; #endif // __CPU_O3_CPU_HH__ diff -r 08b1188e55dd -r 7f2de0cd1ea1 src/cpu/o3/cpu.cc --- a/src/cpu/o3/cpu.cc Fri Jan 07 12:11:09 2011 -0800 +++ b/src/cpu/o3/cpu.cc Mon Jan 10 10:46:30 2011 -0800 @@ -480,6 +480,37 @@ this->rename.regStats(); this->iew.regStats(); this->commit.regStats(); + this->rob.regStats(); + + intRegfileReads + .name(name() + ".int_regfile_reads") + .desc("number of integer regfile reads") + .prereq(intRegfileReads); + + intRegfileWrites + .name(name() + ".int_regfile_writes") + .desc("number of integer regfile writes") + .prereq(intRegfileWrites); + + fpRegfileReads + .name(name() + ".fp_regfile_reads") + .desc("number of floating regfile reads") + .prereq(fpRegfileReads); + + fpRegfileWrites + .name(name() + ".fp_regfile_writes") + .desc("number of floating regfile writes") + .prereq(fpRegfileWrites); + + miscRegfileReads + .name(name() + ".misc_regfile_reads") + .desc("number of misc regfile reads") + .prereq(miscRegfileReads); + + miscRegfileWrites + .name(name() + ".misc_regfile_writes") + .desc("number of misc regfile writes") + .prereq(miscRegfileWrites); } template @@ -1074,6 +1105,7 @@ if (!tickEvent.scheduled()) schedule(tickEvent, nextCycle()); _status = Running; + system->totalNumInsts = 0; } template @@ -1177,6 +1209,7 @@ TheISA::MiscReg FullO3CPU::readMiscRegNoEffect(int misc_reg, ThreadID tid) { + miscRegfileReads++; return this->isa[tid].readMiscRegNoEffect(misc_reg); } @@ -1184,6 +1217,7 @@ TheISA::MiscReg FullO3CPU::readMiscReg(int misc_reg, ThreadID tid) { + miscRegfileReads++; return this->isa[tid].readMiscReg(misc_reg, tcBase(tid)); } @@ -1192,6 +1226,7 @@ FullO3CPU::setMiscRegNoEffect(int misc_reg, const TheISA::MiscReg &val, ThreadID tid) { + miscRegfileWrites++; this->isa[tid].setMiscRegNoEffect(misc_reg, val); } @@ -1200,6 +1235,7 @@ FullO3CPU::setMiscReg(int misc_reg, const TheISA::MiscReg &val, ThreadID tid) { + miscRegfileWrites++; this->isa[tid].setMiscReg(misc_reg, val, tcBase(tid)); } @@ -1207,6 +1243,7 @@ uint64_t FullO3CPU::readIntReg(int reg_idx) { + intRegfileReads++; return regFile.readIntReg(reg_idx); } @@ -1214,6 +1251,7 @@ FloatReg FullO3CPU::readFloatReg(int reg_idx) { + fpRegfileReads++; return regFile.readFloatReg(reg_idx); } @@ -1221,6 +1259,7 @@ FloatRegBits FullO3CPU::readFloatRegBits(int reg_idx) { + fpRegfileReads++; return regFile.readFloatRegBits(reg_idx); } @@ -1228,6 +1267,7 @@ void FullO3CPU::setIntReg(int reg_idx, uint64_t val) { + intRegfileWrites++; regFile.setIntReg(reg_idx, val); } @@ -1235,6 +1275,7 @@ void FullO3CPU::setFloatReg(int reg_idx, FloatReg val) { + fpRegfileWrites++; regFile.setFloatReg(reg_idx, val); } @@ -1242,6 +1283,7 @@ void FullO3CPU::setFloatRegBits(int reg_idx, FloatRegBits val) { + fpRegfileWrites++; regFile.setFloatRegBits(reg_idx, val); } @@ -1249,6 +1291,7 @@ uint64_t FullO3CPU::readArchIntReg(int reg_idx, ThreadID tid) { + intRegfileReads++; PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx); return regFile.readIntReg(phys_reg); @@ -1258,6 +1301,7 @@ float FullO3CPU::readArchFloatReg(int reg_idx, ThreadID tid) { + fpRegfileReads++; int idx = reg_idx + TheISA::NumIntRegs; PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx); @@ -1268,6 +1312,7 @@ uint64_t FullO3CPU::readArchFloatRegInt(int reg_idx, ThreadID tid) { + fpRegfileReads++; // Should I increment by two? int idx = reg_idx + TheISA::NumIntRegs; PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx); @@ -1278,6 +1323,7 @@ void FullO3CPU::setArchIntReg(int reg_idx, uint64_t val, ThreadID tid) { + intRegfileWrites++; PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx); regFile.setIntReg(phys_reg, val); @@ -1287,6 +1333,7 @@ void FullO3CPU::setArchFloatReg(int reg_idx, float val, ThreadID tid) { + fpRegfileWrites++; int idx = reg_idx + TheISA::NumIntRegs; PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx); @@ -1297,6 +1344,7 @@ void FullO3CPU::setArchFloatRegInt(int reg_idx, uint64_t val, ThreadID tid) { + fpRegfileWrites++; // Should I increment this stat twice? int idx = reg_idx + TheISA::NumIntRegs; PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx); @@ -1364,9 +1412,10 @@ thread[tid]->numInsts++; committedInsts[tid]++; totalCommittedInsts++; - + system->totalNumInsts++; // Check for instruction-count-based events. comInstEventQueue[tid]->serviceEvents(thread[tid]->numInst); + system->instEventQueue.serviceEvents(system->totalNumInsts); } template diff -r 08b1188e55dd -r 7f2de0cd1ea1 src/cpu/o3/iew_impl.hh --- a/src/cpu/o3/iew_impl.hh Fri Jan 07 12:11:09 2011 -0800 +++ b/src/cpu/o3/iew_impl.hh Mon Jan 10 10:46:30 2011 -0800 @@ -687,6 +687,7 @@ // If there are no ready instructions waiting to be scheduled by the IQ, // and there's no stores waiting to write back, and dispatch is not // unblocking, then there is no internal activity for the IEW stage. + instQueue.intInstQueueReads++; if (_status == Active && !instQueue.hasReadyInsts() && !ldstQueue.willWB() && !any_unblocking) { DPRINTF(IEW, "IEW switching to idle\n"); diff -r 08b1188e55dd -r 7f2de0cd1ea1 src/cpu/o3/inst_queue.hh --- a/src/cpu/o3/inst_queue.hh Fri Jan 07 12:11:09 2011 -0800 +++ b/src/cpu/o3/inst_queue.hh Mon Jan 10 10:46:30 2011 -0800 @@ -497,6 +497,16 @@ Stats::Vector fuBusy; /** Number of times the FU was busy per instruction issued. */ Stats::Formula fuBusyRate; + public: + Stats::Scalar intInstQueueReads; + Stats::Scalar intInstQueueWrites; + Stats::Scalar intInstQueueWakeupAccesses; + Stats::Scalar fpInstQueueReads; + Stats::Scalar fpInstQueueWrites; + Stats::Scalar fpInstQueueWakeupQccesses; + + Stats::Scalar intAluAccesses; + Stats::Scalar fpAluAccesses; }; #endif //__CPU_O3_INST_QUEUE_HH__ diff -r 08b1188e55dd -r 7f2de0cd1ea1 src/cpu/o3/inst_queue_impl.hh --- a/src/cpu/o3/inst_queue_impl.hh Fri Jan 07 12:11:09 2011 -0800 +++ b/src/cpu/o3/inst_queue_impl.hh Mon Jan 10 10:46:30 2011 -0800 @@ -320,6 +320,47 @@ // Tell mem dependence unit to reg stats as well. memDepUnit[tid].regStats(); } + + intInstQueueReads + .name(name() + ".int_inst_queue_reads") + .desc("Number of integer instruction queue reads") + .flags(total); + + intInstQueueWrites + .name(name() + ".int_inst_queue_writes") + .desc("Number of integer instruction queue writes") + .flags(total); + + intInstQueueWakeupAccesses + .name(name() + ".int_inst_queue_wakeup_accesses") + .desc("Number of integer instruction queue wakeup accesses") + .flags(total); + + fpInstQueueReads + .name(name() + ".fp_inst_queue_reads") + .desc("Number of floating instruction queue reads") + .flags(total); + + fpInstQueueWrites + .name(name() + ".fp_inst_queue_writes") + .desc("Number of floating instruction queue writes") + .flags(total); + + fpInstQueueWakeupQccesses + .name(name() + ".fp_inst_queue_wakeup_accesses") + .desc("Number of floating instruction queue wakeup accesses") + .flags(total); + + intAluAccesses + .name(name() + ".int_alu_accesses") + .desc("Number of integer alu accesses") + .flags(total); + + fpAluAccesses + .name(name() + ".fp_alu_accesses") + .desc("Number of floating point alu accesses") + .flags(total); + } template @@ -501,6 +542,7 @@ void InstructionQueue::insert(DynInstPtr &new_inst) { + new_inst->isFloating() ? fpInstQueueWrites++ : intInstQueueWrites++; // Make sure the instruction is valid assert(new_inst); @@ -542,6 +584,7 @@ { // @todo: Clean up this code; can do it by setting inst as unable // to issue, then calling normal insert on the inst. + new_inst->isFloating() ? fpInstQueueWrites++ : intInstQueueWrites++; assert(new_inst); @@ -592,6 +635,13 @@ assert(!instsToExecute.empty()); DynInstPtr inst = instsToExecute.front(); instsToExecute.pop_front(); + if (inst->isFloating()){ + fpInstQueueWrites++; + fpInstQueueReads++; + } else { + intInstQueueWrites++; + intInstQueueReads++; + } return inst; } @@ -706,6 +756,8 @@ DynInstPtr issuing_inst = readyInsts[op_class].top(); + issuing_inst->isFloating() ? fpInstQueueReads++ : intInstQueueReads++; + assert(issuing_inst->seqNum == (*order_it).oldestInst); if (issuing_inst->isSquashed()) { @@ -731,7 +783,7 @@ if (op_class != No_OpClass) { idx = fuPool->getUnit(op_class); - + issuing_inst->isFloating() ? fpAluAccesses++ : intAluAccesses++; if (idx > -1) { op_latency = fuPool->getOpLatency(op_class); } @@ -867,6 +919,13 @@ { int dependents = 0; + // The instruction queue here takes care of both floating and int operations + if (completed_inst->isFloating()) { + fpInstQueueWakeupQccesses++; + } else { + intInstQueueWakeupAccesses++; + } + DPRINTF(IQ, "Waking dependents of completed instruction.\n"); assert(!completed_inst->isSquashed()); @@ -997,6 +1056,7 @@ InstructionQueue::violation(DynInstPtr &store, DynInstPtr &faulting_load) { + intInstQueueWrites++; memDepUnit[store->threadNumber].violation(store, faulting_load); } @@ -1037,6 +1097,7 @@ (*squash_it)->seqNum > squashedSeqNum[tid]) { DynInstPtr squashed_inst = (*squash_it); + squashed_inst->isFloating() ? fpInstQueueWrites++ : intInstQueueWrites++; // Only handle the instruction if it actually is in the IQ and // hasn't already been squashed in the IQ. diff -r 08b1188e55dd -r 7f2de0cd1ea1 src/cpu/o3/rename.hh --- a/src/cpu/o3/rename.hh Fri Jan 07 12:11:09 2011 -0800 +++ b/src/cpu/o3/rename.hh Mon Jan 10 10:46:30 2011 -0800 @@ -470,6 +470,8 @@ Stats::Scalar renameRenamedOperands; /** Stat for total number of source register rename lookups. */ Stats::Scalar renameRenameLookups; + Stats::Scalar intRenameLookups; + Stats::Scalar fpRenameLookups; /** Stat for total number of committed renaming mappings. */ Stats::Scalar renameCommittedMaps; /** Stat for total number of mappings that were undone due to a squash. */ diff -r 08b1188e55dd -r 7f2de0cd1ea1 src/cpu/o3/rename_impl.hh --- a/src/cpu/o3/rename_impl.hh Fri Jan 07 12:11:09 2011 -0800 +++ b/src/cpu/o3/rename_impl.hh Mon Jan 10 10:46:30 2011 -0800 @@ -167,6 +167,14 @@ .desc("count of insts added to the skid buffer") .flags(Stats::total) ; + intRenameLookups + .name(name() + ".RENAME:int_rename_lookups") + .desc("Number of integer rename lookups") + .prereq(intRenameLookups); + fpRenameLookups + .name(name() + ".RENAME:fp_rename_lookups") + .desc("Number of floating rename lookups") + .prereq(fpRenameLookups); } template @@ -1000,6 +1008,7 @@ } ++renameRenameLookups; + inst->isFloating() ? fpRenameLookups++ : intRenameLookups++; } } diff -r 08b1188e55dd -r 7f2de0cd1ea1 src/cpu/o3/rob.hh --- a/src/cpu/o3/rob.hh Fri Jan 07 12:11:09 2011 -0800 +++ b/src/cpu/o3/rob.hh Mon Jan 10 10:46:30 2011 -0800 @@ -253,6 +253,9 @@ */ int countInsts(ThreadID tid); + /** Registers statistics. */ + void regStats(); + private: /** Pointer to the CPU. */ O3CPU *cpu; @@ -312,6 +315,11 @@ /** Number of active threads. */ ThreadID numThreads; + + // The number of rob_reads + Stats::Scalar robReads; + // The number of rob_writes + Stats::Scalar robWrites; }; #endif //__CPU_O3_ROB_HH__ diff -r 08b1188e55dd -r 7f2de0cd1ea1 src/cpu/o3/rob_impl.hh --- a/src/cpu/o3/rob_impl.hh Fri Jan 07 12:11:09 2011 -0800 +++ b/src/cpu/o3/rob_impl.hh Mon Jan 10 10:46:30 2011 -0800 @@ -204,6 +204,8 @@ { assert(inst); + robWrites++; + DPRINTF(ROB, "Adding inst PC %s to the ROB.\n", inst->pcState()); assert(numInstsInROB != numEntries); @@ -237,6 +239,8 @@ void ROB::retireHead(ThreadID tid) { + robWrites++; + assert(numInstsInROB > 0); // Get the head ROB instruction. @@ -271,6 +275,7 @@ bool ROB::isHeadReady(ThreadID tid) { + robReads++; if (threadEntries[tid] != 0) { return instList[tid].front()->readyToCommit(); } @@ -315,6 +320,7 @@ void ROB::doSquash(ThreadID tid) { + robWrites++; DPRINTF(ROB, "[tid:%u]: Squashing instructions until [sn:%i].\n", tid, squashedSeqNum[tid]); @@ -523,3 +529,17 @@ return *tail_thread; } +template +void +ROB::regStats() +{ + using namespace Stats; + robReads + .name(name() + ".rob_reads") + .desc("The number of ROB reads"); + + robWrites + .name(name() + ".rob_writes") + .desc("The number of ROB writes"); +} + diff -r 08b1188e55dd -r 7f2de0cd1ea1 src/cpu/simple/atomic.cc --- a/src/cpu/simple/atomic.cc Fri Jan 07 12:11:09 2011 -0800 +++ b/src/cpu/simple/atomic.cc Mon Jan 10 10:46:30 2011 -0800 @@ -212,6 +212,7 @@ if (!tickEvent.scheduled()) schedule(tickEvent, nextCycle()); } + system->totalNumInsts = 0; } void diff -r 08b1188e55dd -r 7f2de0cd1ea1 src/cpu/simple/base.hh --- a/src/cpu/simple/base.hh Fri Jan 07 12:11:09 2011 -0800 +++ b/src/cpu/simple/base.hh Mon Jan 10 10:46:30 2011 -0800 @@ -182,7 +182,7 @@ { numInst++; numInsts++; - + system->totalNumInsts++; thread->funcExeInst++; } @@ -191,8 +191,42 @@ return numInst - startNumInst; } + //number of integer alu accesses + Stats::Scalar numIntAluAccesses; + + //number of float alu accesses + Stats::Scalar numFpAluAccesses; + + //number of function calls/returns + Stats::Scalar numCallsReturns; + + //conditional control instructions; + Stats::Scalar numCondCtrlInsts; + + //number of int instructions + Stats::Scalar numIntInsts; + + //number of float instructions + Stats::Scalar numFpInsts; + + //number of integer register file accesses + Stats::Scalar numIntRegReads; + Stats::Scalar numIntRegWrites; + + //number of float register file accesses + Stats::Scalar numFpRegReads; + Stats::Scalar numFpRegWrites; + // number of simulated memory references Stats::Scalar numMemRefs; + Stats::Scalar numLoadInsts; + Stats::Scalar numStoreInsts; + + // number of idle cycles + Stats::Formula numIdleCycles; + + // number of busy cycles + Stats::Formula numBusyCycles; // number of simulated loads Counter numLoad; @@ -240,28 +274,33 @@ uint64_t readIntRegOperand(const StaticInst *si, int idx) { + numIntRegReads++; return thread->readIntReg(si->srcRegIdx(idx)); } FloatReg readFloatRegOperand(const StaticInst *si, int idx) { + numFpRegReads++; int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; return thread->readFloatReg(reg_idx); } FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) { + numFpRegReads++; int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; return thread->readFloatRegBits(reg_idx); } void setIntRegOperand(const StaticInst *si, int idx, uint64_t val) { + numIntRegWrites++; thread->setIntReg(si->destRegIdx(idx), val); } void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val) { + numFpRegWrites++; int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; thread->setFloatReg(reg_idx, val); } @@ -269,6 +308,7 @@ void setFloatRegOperandBits(const StaticInst *si, int idx, FloatRegBits val) { + numFpRegWrites++; int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; thread->setFloatRegBits(reg_idx, val); } @@ -289,21 +329,25 @@ MiscReg readMiscRegNoEffect(int misc_reg) { + numIntRegReads++; return thread->readMiscRegNoEffect(misc_reg); } MiscReg readMiscReg(int misc_reg) { + numIntRegReads++; return thread->readMiscReg(misc_reg); } void setMiscReg(int misc_reg, const MiscReg &val) { + numIntRegWrites++; return thread->setMiscReg(misc_reg, val); } MiscReg readMiscRegOperand(const StaticInst *si, int idx) { + numIntRegReads++; int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag; return thread->readMiscReg(reg_idx); } @@ -311,6 +355,7 @@ void setMiscRegOperand( const StaticInst *si, int idx, const MiscReg &val) { + numIntRegWrites++; int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag; return thread->setMiscReg(reg_idx, val); } diff -r 08b1188e55dd -r 7f2de0cd1ea1 src/cpu/simple/base.cc --- a/src/cpu/simple/base.cc Fri Jan 07 12:11:09 2011 -0800 +++ b/src/cpu/simple/base.cc Mon Jan 10 10:46:30 2011 -0800 @@ -142,9 +142,69 @@ .desc("Number of instructions executed") ; + numIntAluAccesses + .name(name() + ".num_int_alu_accesses") + .desc("Number of integer alu accesses") + ; + + numFpAluAccesses + .name(name() + ".num_fp_alu_accesses") + .desc("Number of float alu accesses") + ; + + numCallsReturns + .name(name() + ".num_func_calls") + .desc("number of times a function call or return occured") + ; + + numCondCtrlInsts + .name(name() + ".num_conditional_control_insts") + .desc("number of instructions that are conditional controls") + ; + + numIntInsts + .name(name() + ".num_int_insts") + .desc("number of integer instructions") + ; + + numFpInsts + .name(name() + ".num_fp_insts") + .desc("number of float instructions") + ; + + numIntRegReads + .name(name() + ".num_int_register_reads") + .desc("number of times the integer registers were read") + ; + + numIntRegWrites + .name(name() + ".num_int_register_writes") + .desc("number of times the integer registers were written") + ; + + numFpRegReads + .name(name() + ".num_fp_register_reads") + .desc("number of times the floating registers were read") + ; + + numFpRegWrites + .name(name() + ".num_fp_register_writes") + .desc("number of times the floating registers were written") + ; + numMemRefs - .name(name() + ".num_refs") - .desc("Number of memory references") + .name(name()+".num_mem_refs") + .desc("number of memory refs") + ; + + numStoreInsts + .name(name() + ".num_store_insts") + .desc("Number of store instructions") + ; + + numLoadInsts + .name(name() + ".num_load_insts") + .desc("Number of load instructions") ; notIdleFraction @@ -157,6 +217,16 @@ .desc("Percentage of idle cycles") ; + numBusyCycles + .name(name() + ".num_busy_cycles") + .desc("Number of busy cycles") + ; + + numIdleCycles + .name(name()+".num_idle_cycles") + .desc("Number of idle cycles") + ; + icacheStallCycles .name(name() + ".icache_stall_cycles") .desc("ICache total stall cycles") @@ -182,6 +252,8 @@ ; idleFraction = constant(1.0) - notIdleFraction; + numIdleCycles = (constant(1.0) - notIdleFraction)*numCycles; + numBusyCycles = (notIdleFraction)*numCycles; } void @@ -277,6 +349,7 @@ // check for instruction-count-based events comInstEventQueue[0]->serviceEvents(numInst); + system->instEventQueue.serviceEvents(system->totalNumInsts); // decode the instruction inst = gtoh(inst); @@ -369,6 +442,39 @@ CPA::cpa()->swAutoBegin(tc, pc.nextInstAddr()); } + /* POWER MODEL STATISTIC ADDITION */ + //integer alu accesses + if (curStaticInst->isInteger()){ + numIntAluAccesses++; + numIntInsts++; + } + + //float alu accesses + if (curStaticInst->isFloating()){ + numFpAluAccesses++; + numFpInsts++; + } + + //number of function calls/returns to get window accesses + if (curStaticInst->isCall() || curStaticInst->isReturn()){ + numCallsReturns++; + } + + //the number of branch predictions that will be made + if (curStaticInst->isCondCtrl()){ + numCondCtrlInsts++; + } + + //result bus acceses + if (curStaticInst->isLoad()){ + numLoadInsts++; + } + + if (curStaticInst->isStore()){ + numStoreInsts++; + } + /* END POWER MODEL STATISTICS */ + traceFunctions(instAddr); if (traceData) { diff -r 08b1188e55dd -r 7f2de0cd1ea1 src/cpu/simple/timing.cc --- a/src/cpu/simple/timing.cc Fri Jan 07 12:11:09 2011 -0800 +++ b/src/cpu/simple/timing.cc Mon Jan 10 10:46:30 2011 -0800 @@ -130,6 +130,7 @@ drainEvent = NULL; previousTick = 0; changeState(SimObject::Running); + system->totalNumInsts = 0; } diff -r 08b1188e55dd -r 7f2de0cd1ea1 src/sim/System.py --- a/src/sim/System.py Fri Jan 07 12:11:09 2011 -0800 +++ b/src/sim/System.py Mon Jan 10 10:46:30 2011 -0800 @@ -44,6 +44,10 @@ physmem = Param.PhysicalMemory(Parent.any, "physical memory") mem_mode = Param.MemoryMode('atomic', "The mode the memory system is in") + + max_total_system_insts = Param.Counter(0, + "terminate when the entire system has executed this instruction count") + if buildEnv['FULL_SYSTEM']: abstract = True boot_cpu_frequency = Param.Frequency(Self.cpu[0].clock.frequency, diff -r 08b1188e55dd -r 7f2de0cd1ea1 src/sim/system.hh --- a/src/sim/system.hh Fri Jan 07 12:11:09 2011 -0800 +++ b/src/sim/system.hh Mon Jan 10 10:46:30 2011 -0800 @@ -246,6 +246,14 @@ void unserialize(Checkpoint *cp, const std::string §ion); public: + Counter totalNumInsts; + /** + * Vector of per-thread instruction-based event queues. Used for + * scheduling events based on number of instructions committed by + * a particular thread. + */ + EventQueue instEventQueue; + //////////////////////////////////////////// // // STATIC GLOBAL SYSTEM LIST diff -r 08b1188e55dd -r 7f2de0cd1ea1 src/sim/system.cc --- a/src/sim/system.cc Fri Jan 07 12:11:09 2011 -0800 +++ b/src/sim/system.cc Mon Jan 10 10:46:30 2011 -0800 @@ -70,7 +70,9 @@ pagePtr(0), nextPID(0), #endif - memoryMode(p->mem_mode), _params(p) + memoryMode(p->mem_mode), _params(p), + totalNumInsts(0), + instEventQueue("system instruction-based event queue") { // add self to global system list systemList.push_back(this);