mcpat: Adds McPAT performance counters
authorJoel Hestness <hestness@cs.utexas.edu>
Mon, 7 Feb 2011 06:14:17 +0000 (22:14 -0800)
committerJoel Hestness <hestness@cs.utexas.edu>
Mon, 7 Feb 2011 06:14:17 +0000 (22:14 -0800)
Updated patches from Rick Strong's set that modify performance counters for
McPAT

21 files changed:
src/cpu/BaseCPU.py
src/cpu/base.cc
src/cpu/base.hh
src/cpu/o3/commit.hh
src/cpu/o3/commit_impl.hh
src/cpu/o3/cpu.cc
src/cpu/o3/cpu.hh
src/cpu/o3/iew_impl.hh
src/cpu/o3/inst_queue.hh
src/cpu/o3/inst_queue_impl.hh
src/cpu/o3/rename.hh
src/cpu/o3/rename_impl.hh
src/cpu/o3/rob.hh
src/cpu/o3/rob_impl.hh
src/cpu/simple/atomic.cc
src/cpu/simple/base.cc
src/cpu/simple/base.hh
src/cpu/simple/timing.cc
src/sim/System.py
src/sim/system.cc
src/sim/system.hh

index de8499ef5198ad88a857c24aca0259fd918474c3..9786283a2560d49f4f2d65cdc160cc9d710fb0cf 100644 (file)
@@ -1,4 +1,5 @@
 # Copyright (c) 2005-2008 The Regents of The University of Michigan
+# Copyright (c) 2011 Regents of the University of California
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -25,6 +26,7 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #
 # Authors: Nathan Binkert
+#          Rick Strong
 
 import sys
 
index 1816568ce523a899d18d788d6335f51a7e076821..b7decaec13e77914c871d377061a7c833af437c9 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * Copyright (c) 2011 Regents of the University of California
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,6 +28,7 @@
  *
  * Authors: Steve Reinhardt
  *          Nathan Binkert
+ *          Rick Strong
  */
 
 #include <iostream>
index e0491a84aae198d13d5260f02c835b58662506f3..bea15aa0800b205e830b3487206ae1802fec735c 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * Copyright (c) 2011 Regents of the University of California
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,6 +28,7 @@
  *
  * Authors: Steve Reinhardt
  *          Nathan Binkert
+ *          Rick Strong
  */
 
 #ifndef __CPU_BASE_HH__
index 659b0ad5fd53a87e6b0246ebc6a90c35c7ee0614..047e29f5d805adc8e82b9007e1e7ff8df8658401 100644 (file)
@@ -473,6 +473,12 @@ class DefaultCommit
     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;
index a49e1497ef03c9956d4afc042c9bea4326a91526..50c08e1622dc37fd427f1a7ff57d2fc4feffe650 100644 (file)
@@ -230,6 +230,27 @@ DefaultCommit<Impl>::regStats()
         .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")
@@ -1321,6 +1342,19 @@ DefaultCommit<Impl>::updateComInstStats(DynInstPtr &inst)
     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]++;
+
 }
 
 ////////////////////////////////////////
index 9becc66010faf86ad828abd4f5537996a74f14a5..2d3bc3f724c2b9a7364812d6be6204b97059f595 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2004-2006 The Regents of The University of Michigan
+ * Copyright (c) 2011 Regents of the University of California
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,6 +28,7 @@
  *
  * Authors: Kevin Lim
  *          Korey Sewell
+ *          Rick Strong
  */
 
 #include "config/full_system.hh"
@@ -480,6 +482,37 @@ FullO3CPU<Impl>::regStats()
     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 <class Impl>
@@ -1184,6 +1217,7 @@ template <class Impl>
 TheISA::MiscReg
 FullO3CPU<Impl>::readMiscReg(int misc_reg, ThreadID tid)
 {
+    miscRegfileReads++;
     return this->isa[tid].readMiscReg(misc_reg, tcBase(tid));
 }
 
@@ -1200,6 +1234,7 @@ void
 FullO3CPU<Impl>::setMiscReg(int misc_reg,
         const TheISA::MiscReg &val, ThreadID tid)
 {
+    miscRegfileWrites++;
     this->isa[tid].setMiscReg(misc_reg, val, tcBase(tid));
 }
 
@@ -1207,6 +1242,7 @@ template <class Impl>
 uint64_t
 FullO3CPU<Impl>::readIntReg(int reg_idx)
 {
+    intRegfileReads++;
     return regFile.readIntReg(reg_idx);
 }
 
@@ -1214,6 +1250,7 @@ template <class Impl>
 FloatReg
 FullO3CPU<Impl>::readFloatReg(int reg_idx)
 {
+    fpRegfileReads++;
     return regFile.readFloatReg(reg_idx);
 }
 
@@ -1221,6 +1258,7 @@ template <class Impl>
 FloatRegBits
 FullO3CPU<Impl>::readFloatRegBits(int reg_idx)
 {
+    fpRegfileReads++;
     return regFile.readFloatRegBits(reg_idx);
 }
 
@@ -1228,6 +1266,7 @@ template <class Impl>
 void
 FullO3CPU<Impl>::setIntReg(int reg_idx, uint64_t val)
 {
+    intRegfileWrites++;
     regFile.setIntReg(reg_idx, val);
 }
 
@@ -1235,6 +1274,7 @@ template <class Impl>
 void
 FullO3CPU<Impl>::setFloatReg(int reg_idx, FloatReg val)
 {
+    fpRegfileWrites++;
     regFile.setFloatReg(reg_idx, val);
 }
 
@@ -1242,6 +1282,7 @@ template <class Impl>
 void
 FullO3CPU<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val)
 {
+    fpRegfileWrites++;
     regFile.setFloatRegBits(reg_idx, val);
 }
 
@@ -1249,6 +1290,7 @@ template <class Impl>
 uint64_t
 FullO3CPU<Impl>::readArchIntReg(int reg_idx, ThreadID tid)
 {
+    intRegfileReads++;
     PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx);
 
     return regFile.readIntReg(phys_reg);
@@ -1258,6 +1300,7 @@ template <class Impl>
 float
 FullO3CPU<Impl>::readArchFloatReg(int reg_idx, ThreadID tid)
 {
+    fpRegfileReads++;
     int idx = reg_idx + TheISA::NumIntRegs;
     PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx);
 
@@ -1268,6 +1311,7 @@ template <class Impl>
 uint64_t
 FullO3CPU<Impl>::readArchFloatRegInt(int reg_idx, ThreadID tid)
 {
+    fpRegfileReads++;
     int idx = reg_idx + TheISA::NumIntRegs;
     PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx);
 
@@ -1278,6 +1322,7 @@ template <class Impl>
 void
 FullO3CPU<Impl>::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 +1332,7 @@ template <class Impl>
 void
 FullO3CPU<Impl>::setArchFloatReg(int reg_idx, float val, ThreadID tid)
 {
+    fpRegfileWrites++;
     int idx = reg_idx + TheISA::NumIntRegs;
     PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx);
 
@@ -1297,6 +1343,7 @@ template <class Impl>
 void
 FullO3CPU<Impl>::setArchFloatRegInt(int reg_idx, uint64_t val, ThreadID tid)
 {
+    fpRegfileWrites++;
     int idx = reg_idx + TheISA::NumIntRegs;
     PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx);
 
@@ -1364,9 +1411,10 @@ FullO3CPU<Impl>::instDone(ThreadID tid)
     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 <class Impl>
index e3d13c8403a20d13334b67880ab4ca2874d422fe..69289996be3db8ce7f360ee97435351cfb60b099 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * Copyright (c) 2011 Regents of the University of California
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,6 +28,7 @@
  *
  * Authors: Kevin Lim
  *          Korey Sewell
+ *          Rick Strong
  */
 
 #ifndef __CPU_O3_CPU_HH__
@@ -726,6 +728,16 @@ class FullO3CPU : public BaseO3CPU
     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__
index ce58868ba12423b73dc47cd59f11b0ac3afac007..3f3761ff32942c019b5e7a53065406535fd328c4 100644 (file)
@@ -698,6 +698,7 @@ DefaultIEW<Impl>::updateStatus()
     // 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");
index 56124d60f59a645bf779f49050fb27bf101fea5e..be936e2045df1f73928ee50b84add5e89aada5b5 100644 (file)
@@ -497,6 +497,16 @@ class InstructionQueue
     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__
index ce408dfd01b79be72ba6751e7c82d81778ae0dfd..91cb2f0c82a3040373ed64e25b7b95da98b8d400 100644 (file)
@@ -320,6 +320,47 @@ InstructionQueue<Impl>::regStats()
         // 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 <class Impl>
@@ -501,6 +542,7 @@ template <class Impl>
 void
 InstructionQueue<Impl>::insert(DynInstPtr &new_inst)
 {
+    new_inst->isFloating() ? fpInstQueueWrites++ : intInstQueueWrites++;
     // Make sure the instruction is valid
     assert(new_inst);
 
@@ -542,6 +584,7 @@ InstructionQueue<Impl>::insertNonSpec(DynInstPtr &new_inst)
 {
     // @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,11 @@ InstructionQueue<Impl>::getInstToExecute()
     assert(!instsToExecute.empty());
     DynInstPtr inst = instsToExecute.front();
     instsToExecute.pop_front();
+    if (inst->isFloating()){
+        fpInstQueueReads++;
+    } else {
+        intInstQueueReads++;
+    }
     return inst;
 }
 
@@ -706,6 +754,8 @@ InstructionQueue<Impl>::scheduleReadyInsts()
 
         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 +781,7 @@ InstructionQueue<Impl>::scheduleReadyInsts()
 
         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 +917,13 @@ InstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst)
 {
     int dependents = 0;
 
+    // The instruction queue here takes care of both floating and int ops
+    if (completed_inst->isFloating()) {
+        fpInstQueueWakeupQccesses++;
+    } else {
+        intInstQueueWakeupAccesses++;
+    }
+
     DPRINTF(IQ, "Waking dependents of completed instruction.\n");
 
     assert(!completed_inst->isSquashed());
@@ -997,6 +1054,7 @@ void
 InstructionQueue<Impl>::violation(DynInstPtr &store,
                                   DynInstPtr &faulting_load)
 {
+    intInstQueueWrites++;
     memDepUnit[store->threadNumber].violation(store, faulting_load);
 }
 
@@ -1037,6 +1095,7 @@ InstructionQueue<Impl>::doSquash(ThreadID tid)
            (*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.
index 4598a8d7bc6c40444c9b53aab41b5dc6fab5959c..90128311101df833328d1d8ba039df496c791724 100644 (file)
@@ -470,6 +470,8 @@ class DefaultRename
     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. */
index ac2421dc7ccf59dadcab72209c78b218f251be9d..1f34b72554adfa24892b2b8ac6eecc6cdc7d6ade 100644 (file)
@@ -179,6 +179,14 @@ DefaultRename<Impl>::regStats()
         .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 <class Impl>
@@ -1012,6 +1020,7 @@ DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst, ThreadID tid)
         }
 
         ++renameRenameLookups;
+        inst->isFloating() ? fpRenameLookups++ : intRenameLookups++;
     }
 }
 
index bdea07d1a45e7c7fe23dcdd311c9989784038ea3..510c8c5dc031d29ae3ad383abc90e129d12a8ffa 100644 (file)
@@ -253,6 +253,9 @@ class ROB
      */
     int countInsts(ThreadID tid);
 
+    /** Registers statistics. */
+    void regStats();
+
   private:
     /** Pointer to the CPU. */
     O3CPU *cpu;
@@ -312,6 +315,11 @@ class ROB
 
     /** 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__
index 37f1c55046761f5b5d53321299126209db1201b5..d9d1daded20e287e846b40ae9a87ff4701d39d05 100644 (file)
@@ -204,6 +204,8 @@ ROB<Impl>::insertInst(DynInstPtr &inst)
 {
     assert(inst);
 
+    robWrites++;
+
     DPRINTF(ROB, "Adding inst PC %s to the ROB.\n", inst->pcState());
 
     assert(numInstsInROB != numEntries);
@@ -237,6 +239,8 @@ template <class Impl>
 void
 ROB<Impl>::retireHead(ThreadID tid)
 {
+    robWrites++;
+
     assert(numInstsInROB > 0);
 
     // Get the head ROB instruction.
@@ -271,6 +275,7 @@ template <class Impl>
 bool
 ROB<Impl>::isHeadReady(ThreadID tid)
 {
+    robReads++;
     if (threadEntries[tid] != 0) {
         return instList[tid].front()->readyToCommit();
     }
@@ -315,6 +320,7 @@ template <class Impl>
 void
 ROB<Impl>::doSquash(ThreadID tid)
 {
+    robWrites++;
     DPRINTF(ROB, "[tid:%u]: Squashing instructions until [sn:%i].\n",
             tid, squashedSeqNum[tid]);
 
@@ -523,3 +529,17 @@ ROB<Impl>::readTailInst(ThreadID tid)
     return *tail_thread;
 }
 
+template <class Impl>
+void
+ROB<Impl>::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");
+}
+
index 35ad461589277cf93235b9ba4b26eb53d39b694f..da4258fb9d793bed8a35df3334d9723cbe91da13 100644 (file)
@@ -212,6 +212,7 @@ AtomicSimpleCPU::resume()
         if (!tickEvent.scheduled())
             schedule(tickEvent, nextCycle());
     }
+    system->totalNumInsts = 0;
 }
 
 void
index 13ef0648ca2c1336cc685cd0e152e9d30bd664d5..8d7a1b11951a322d15b1ffc80b0b6d35fcf2b104 100644 (file)
@@ -142,9 +142,69 @@ BaseSimpleCPU::regStats()
         .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 @@ BaseSimpleCPU::regStats()
         .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 @@ BaseSimpleCPU::regStats()
         ;
 
     idleFraction = constant(1.0) - notIdleFraction;
+    numIdleCycles = idleFraction * numCycles;
+    numBusyCycles = (notIdleFraction)*numCycles;
 }
 
 void
@@ -277,6 +349,7 @@ BaseSimpleCPU::preExecute()
 
     // 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 @@ BaseSimpleCPU::postExecute()
         CPA::cpa()->swAutoBegin(tc, pc.nextInstAddr());
     }
 
+    /* Power model statistics */
+    //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) {
index bd967b1853cd64764c72eaf34236bbb99fcd9f8b..628432d7667c53360a3b701679488bcbe510a027 100644 (file)
@@ -182,7 +182,7 @@ class BaseSimpleCPU : public BaseCPU
     {
         numInst++;
         numInsts++;
-
+        system->totalNumInsts++;
         thread->funcExeInst++;
     }
 
@@ -191,8 +191,42 @@ class BaseSimpleCPU : public BaseCPU
         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 @@ class BaseSimpleCPU : public BaseCPU
 
     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 @@ class BaseSimpleCPU : public BaseCPU
     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);
     }
@@ -294,16 +334,19 @@ class BaseSimpleCPU : public BaseCPU
 
     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 +354,7 @@ class BaseSimpleCPU : public BaseCPU
     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);
     }
index 9192c080892db39c2fc56d8fbd65b728f08499ad..47f99cd6d5c304018b833aac7cbd91fa1530c955 100644 (file)
@@ -130,6 +130,7 @@ TimingSimpleCPU::TimingSimpleCPU(TimingSimpleCPUParams *p)
     drainEvent = NULL;
     previousTick = 0;
     changeState(SimObject::Running);
+    system->totalNumInsts = 0;
 }
 
 
index eec7b4ae5d344646edcc773091f217b218020fea..e2d5b279bfc8ca014c1bc482ab18df079c8af55e 100644 (file)
@@ -1,4 +1,5 @@
 # Copyright (c) 2005-2007 The Regents of The University of Michigan
+# Copyright (c) 2011 Regents of the University of California
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -25,6 +26,7 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #
 # Authors: Nathan Binkert
+#          Rick Strong
 
 from m5.SimObject import SimObject
 from m5.defines import buildEnv
@@ -44,6 +46,7 @@ class System(SimObject):
 
     physmem = Param.PhysicalMemory(Parent.any, "physical memory")
     mem_mode = Param.MemoryMode('atomic', "The mode the memory system is in")
+
     if buildEnv['FULL_SYSTEM']:
         abstract = True
         boot_cpu_frequency = Param.Frequency(Self.cpu[0].clock.frequency,
index d590adc91ff26d80033bfb476e9fcf504693a6be..68b02272eb9bc37e889030396ff6b1eec32686f5 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2003-2006 The Regents of The University of Michigan
+ * Copyright (c) 2011 Regents of the University of California
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -29,6 +30,7 @@
  *          Lisa Hsu
  *          Nathan Binkert
  *          Ali Saidi
+ *          Rick Strong
  */
 
 #include "arch/isa_traits.hh"
@@ -70,7 +72,9 @@ System::System(Params *p)
       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);
@@ -276,6 +280,13 @@ System::freeMemSize()
 
 #endif
 
+void
+System::resume()
+{
+    SimObject::resume();
+    totalNumInsts = 0;
+}
+
 void
 System::serialize(ostream &os)
 {
index cdf7d3d7e9d606c6a4c796a867fb10eacbdcfc43..6c4f3e9ed09b2b2b986688b953983c9b20fc9def 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2002-2005 The Regents of The University of Michigan
+ * Copyright (c) 2011 Regents of the University of California
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -28,6 +29,7 @@
  * Authors: Steve Reinhardt
  *          Lisa Hsu
  *          Nathan Binkert
+ *          Rick Strong
  */
 
 #ifndef __SYSTEM_HH__
@@ -244,8 +246,12 @@ class System : public SimObject
 
     void serialize(std::ostream &os);
     void unserialize(Checkpoint *cp, const std::string &section);
+    virtual void resume();
 
   public:
+    Counter totalNumInsts;
+    EventQueue instEventQueue;
+
     ////////////////////////////////////////////
     //
     // STATIC GLOBAL SYSTEM LIST