Yet another merge with the main repository.
[gem5.git] / src / cpu / inorder / pipeline_stage.hh
index 17ca3259586d23d84b6abe914fef1b29f6215e43..963d96afb539b7f30bce6850a39c31b5914ac740 100644 (file)
 #include <vector>
 
 #include "base/statistics.hh"
-#include "base/timebuf.hh"
-#include "cpu/inorder/inorder_dyn_inst.hh"
 #include "cpu/inorder/comm.hh"
-#include "params/InOrderCPU.hh"
+#include "cpu/inorder/inorder_dyn_inst.hh"
 #include "cpu/inorder/pipeline_traits.hh"
+#include "cpu/timebuf.hh"
+#include "params/InOrderCPU.hh"
 
 class InOrderCPU;
 
@@ -80,7 +80,7 @@ class PipelineStage
     unsigned stageWidth;
 
     /** Number of Threads*/
-    unsigned numThreads;
+    ThreadID numThreads;
 
     /** Stage status. */
     StageStatus _status;
@@ -91,13 +91,10 @@ class PipelineStage
   public:
     PipelineStage(Params *params, unsigned stage_num);
 
-    /** MUST use init() function if this constructor is used. */
-    PipelineStage() { }
-
-    virtual ~PipelineStage() { }
+    virtual ~PipelineStage();
 
     /** PipelineStage initialization. */
-    void init(Params *params, unsigned stage_num);
+    void init(Params *params);
 
     /** Returns the name of stage. */
     std::string name() const;
@@ -106,9 +103,7 @@ class PipelineStage
     void regStats();
 
     /** Sets CPU pointer. */
-    virtual void setCPU(InOrderCPU *cpu_ptr);
-
-    virtual void scheduleStageStart(int delay, int tid) { }
+    void setCPU(InOrderCPU *cpu_ptr);
 
     /** Sets the main backwards communication time buffer pointer. */
     void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);
@@ -120,11 +115,11 @@ class PipelineStage
     void setNextStageQueue(TimeBuffer<InterStageStruct> *next_stage_ptr);
 
     /** Sets pointer to list of active threads. */
-    void setActiveThreads(std::list<unsigned> *at_ptr);
+    void setActiveThreads(std::list<ThreadID> *at_ptr);
 
     bool nextStageQueueValid(int stage_num);
 
-    bool isBlocked(unsigned tid);
+    bool isBlocked(ThreadID tid);
 
     /** Changes the status of this stage to active, and indicates this
      * to the CPU.
@@ -145,19 +140,16 @@ class PipelineStage
     /** Ticks stage, processing all input signals and executing as many
      *  instructions as possible.
      */
-    virtual void tick();
-
-    /** Is out of order processing valid? */
-    bool outOfOrderValid();
+    void tick();
 
     /** Set a resource stall in the pipeline-stage */
-    void setResStall(ResReqPtr res_req, unsigned tid);
+    void setResStall(ResReqPtr res_req, ThreadID tid);
 
     /** Unset a resource stall in the pipeline-stage */
-    void unsetResStall(ResReqPtr res_req, unsigned tid);
+    void unsetResStall(ResReqPtr res_req, ThreadID tid);
 
     /** Remove all stall signals for a particular thread; */
-    virtual void removeStalls(unsigned tid);
+    void removeStalls(ThreadID tid);
 
     /** Is there room in the stage buffer? */
     int stageBufferAvail();
@@ -171,28 +163,23 @@ class PipelineStage
      * change (ie switching from from blocking to unblocking).
      * @param tid Thread id to stage instructions from.
      */
-    virtual void processThread(bool &status_change, unsigned tid);
+    void processThread(bool &status_change, ThreadID tid);
 
     /** Processes instructions from fetch and passes them on to rename.
      * Decoding of instructions actually happens when they are created in
      * fetch, so this function mostly checks if PC-relative branches are
      * correct.
      */
-    virtual void processInsts(unsigned tid);
+    virtual void processInsts(ThreadID tid);
 
     /** Process all resources on an instruction's resource schedule */
-    virtual bool processInstSchedule(DynInstPtr inst);
+    bool processInstSchedule(DynInstPtr inst, int &reqs_processed);
 
     /** Is there room in the next stage buffer for this instruction? */
-    virtual bool canSendInstToStage(unsigned stage_num);
+    bool canSendInstToStage(unsigned stage_num);
 
     /** Send an instruction to the next stage buffer */
-    virtual bool sendInstToNextStage(DynInstPtr inst);
-
-    /** Inserts a thread's instructions into the skid buffer, to be staged
-     * once stage unblocks.
-     */
-    virtual void skidInsert(unsigned tid);
+    bool sendInstToNextStage(DynInstPtr inst);
 
     /** Total size of all skid buffers */
     int skidSize();
@@ -201,7 +188,7 @@ class PipelineStage
     bool skidsEmpty();
 
     /** Updates overall stage status based on all of the threads' statuses. */
-    virtual void updateStatus();
+    void updateStatus();
 
     /** Separates instructions from fetch into individual lists of instructions
      * sorted by thread.
@@ -209,13 +196,13 @@ class PipelineStage
     void sortInsts();
 
     /** Reads all stall signals from the backwards communication timebuffer. */
-    virtual void readStallSignals(unsigned tid);
+    void readStallSignals(ThreadID tid);
 
     /** Checks all input signals and updates stage's status appropriately. */
-    virtual bool checkSignalsAndUpdate(unsigned tid);
+    bool checkSignalsAndUpdate(ThreadID tid);
 
     /** Checks all stall signals, and returns if any are true. */
-    virtual bool checkStall(unsigned tid) const;
+    bool checkStall(ThreadID tid) const;
 
     /** Returns if there any instructions from the previous stage
      * on this cycle.
@@ -226,30 +213,30 @@ class PipelineStage
      * become blocked.
      * @return Returns true if there is a status change.
      */
-    virtual bool block(unsigned tid);
+    bool block(ThreadID tid);
 
-    void blockDueToBuffer(unsigned tid);
+    void blockDueToBuffer(ThreadID tid);
 
     /** Switches stage to unblocking if the skid buffer is empty, and
      * signals back that stage has unblocked.
      * @return Returns true if there is a status change.
      */
-    virtual bool unblock(unsigned tid);
+    bool unblock(ThreadID tid);
 
 
   public:
-    /** Squashes if there is a PC-relative branch that was predicted
-     * incorrectly. Sends squash information back to fetch.
-     */
-    virtual void squashDueToBranch(DynInstPtr &inst, unsigned tid);
+    void activateThread(ThreadID tid);
+    
+    /** Setup Squashing Information to be passed back thru the pipeline */
+    void setupSquash(DynInstPtr inst, ThreadID tid);
 
-    /** Squash instructions from stage buffer  */
-    virtual void squashPrevStageInsts(InstSeqNum squash_seq_num, unsigned tid);
+    virtual void squashDueToMemStall(InstSeqNum seq_num, ThreadID tid);
 
-    /** Squashes due to commit signalling a squash. Changes status to
-     *  squashing and clears block/unblock signals as needed.
-     */
-    virtual void squash(InstSeqNum squash_num, unsigned tid);
+    /** Perform squash of instructions above seq_num */
+    virtual void squash(InstSeqNum squash_num, ThreadID tid);
+
+    /** Squash instructions from stage buffer  */
+    void squashPrevStageInsts(InstSeqNum squash_seq_num, ThreadID tid);
 
     void dumpInsts();
 
@@ -260,35 +247,39 @@ class PipelineStage
     Trace::InOrderTrace *tracer;
 
     /** List of active thread ids */
-    std::list<unsigned> *activeThreads;
+    std::list<ThreadID> *activeThreads;
 
-    /** Queue of all instructions coming from previous stage on this cycle. */
-    std::queue<DynInstPtr> insts[ThePipeline::MaxThreads];
+    /** Buffer of instructions switched out to mem-stall. 
+     *  Only used when using SwitchOnCacheMiss threading model
+     *  Used as 1-to-1 mapping between ThreadID and Entry. 
+     */
+    std::vector<DynInstPtr> switchedOutBuffer;
+    std::vector<bool> switchedOutValid;
 
-    /** Queue of instructions that are finished processing and ready to go next stage.
-     *  This is used to prevent from processing an instrution more than once on any
-     *  stage. NOTE: It is up to the PROGRAMMER must manage this as a queue
+    /** Instructions that we've processed this tick
+     *  NOTE: "Processed" means completed at least 1 instruction request 
      */
-    std::list<DynInstPtr> instsToNextStage;
+    unsigned instsProcessed;    
 
     /** Skid buffer between previous stage and this one. */
-    std::queue<DynInstPtr> skidBuffer[ThePipeline::MaxThreads];
+    std::list<DynInstPtr> skidBuffer[ThePipeline::MaxThreads];
 
-    /** Instruction used to signify that there is no *real* instruction in buffer slot */
+    /** Instruction used to signify that there is no *real* instruction in
+     *  buffer slot */
     DynInstPtr dummyBufferInst;
 
     /** SeqNum of Squashing Branch Delay Instruction (used for MIPS) */
     Addr bdelayDoneSeqNum[ThePipeline::MaxThreads];
 
-    /** Instruction used for squashing branch (used for MIPS) */
-    DynInstPtr squashInst[ThePipeline::MaxThreads];
-
     /** Tells when their is a pending delay slot inst. to send
      *  to rename. If there is, then wait squash after the next
      *  instruction (used for MIPS).
      */
     bool squashAfterDelaySlot[ThePipeline::MaxThreads];
 
+    /** Instruction used for squashing branch (used for MIPS) */
+    DynInstPtr squashInst[ThePipeline::MaxThreads];
+
     /** Maximum size of the inter-stage buffer connecting the previous stage to
      *  this stage (which we call a skid buffer) */
     unsigned stageBufferMax;
@@ -332,30 +323,27 @@ class PipelineStage
     /** Is Next Stage Valid? */
     bool nextStageValid;
 
+    bool idle;
+    
     /** Source of possible stalls. */
     struct Stalls {
         bool stage[ThePipeline::NumStages];
         std::vector<ResReqPtr> resources;
     };
 
-    /** Tracks which stages are telling decode to stall. */
+    /** Tracks stage/resource stalls */
     Stalls stalls[ThePipeline::MaxThreads];
 
-    //@TODO: Use Stats for the pipeline stages
-    /** Stat for total number of idle cycles. */
-    //Stats::Scalar<> stageIdleCycles;
-    /** Stat for total number of blocked cycles. */
-    //Stats::Scalar<> stageBlockedCycles;
-    /** Stat for total number of normal running cycles. */
-    //Stats::Scalar<> stageRunCycles;
-    /** Stat for total number of unblocking cycles. */
-    //Stats::Scalar<> stageUnblockCycles;
-    /** Stat for total number of squashing cycles. */
-    //Stats::Scalar<> stageSquashCycles;
-    /** Stat for total number of staged instructions. */
-    //Stats::Scalar<> stageProcessedInsts;
-    /** Stat for total number of squashed instructions. */
-    //Stats::Scalar<> stageSquashedInsts;
+    /** Number of cycles 0 instruction(s) are processed. */
+    Stats::Scalar idleCycles;
+
+    /** Number of cycles 1+ instructions are processed. */
+    Stats::Scalar runCycles;
+
+    /** Percentage of cycles 1+ instructions are processed. */
+    Stats::Formula utilization;
+
+
 };
 
 #endif