#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;
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);
void regStats();
/** Sets CPU pointer. */
- virtual void setCPU(InOrderCPU *cpu_ptr);
-
- virtual void scheduleStageStart(int delay, ThreadID tid) { }
+ void setCPU(InOrderCPU *cpu_ptr);
/** Sets the main backwards communication time buffer pointer. */
void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);
/** Ticks stage, processing all input signals and executing as many
* instructions as possible.
*/
- virtual void tick();
+ void tick();
/** Set a resource stall in the pipeline-stage */
void setResStall(ResReqPtr res_req, ThreadID tid);
void unsetResStall(ResReqPtr res_req, ThreadID tid);
/** Remove all stall signals for a particular thread; */
- virtual void removeStalls(ThreadID tid);
+ void removeStalls(ThreadID tid);
/** Is there room in the stage buffer? */
int stageBufferAvail();
* change (ie switching from from blocking to unblocking).
* @param tid Thread id to stage instructions from.
*/
- virtual void processThread(bool &status_change, ThreadID 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
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(ThreadID tid);
+ bool sendInstToNextStage(DynInstPtr inst);
/** Total size of all skid buffers */
int skidSize();
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.
void sortInsts();
/** Reads all stall signals from the backwards communication timebuffer. */
- virtual void readStallSignals(ThreadID tid);
+ void readStallSignals(ThreadID tid);
/** Checks all input signals and updates stage's status appropriately. */
- virtual bool checkSignalsAndUpdate(ThreadID tid);
+ bool checkSignalsAndUpdate(ThreadID tid);
/** Checks all stall signals, and returns if any are true. */
- virtual bool checkStall(ThreadID tid) const;
+ bool checkStall(ThreadID tid) const;
/** Returns if there any instructions from the previous stage
* on this cycle.
* become blocked.
* @return Returns true if there is a status change.
*/
- virtual bool block(ThreadID tid);
+ bool block(ThreadID tid);
void blockDueToBuffer(ThreadID tid);
* signals back that stage has unblocked.
* @return Returns true if there is a status change.
*/
- virtual bool unblock(ThreadID 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, ThreadID tid);
-
- virtual void squashDueToMemStall(DynInstPtr &inst, ThreadID 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, ThreadID 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.
- */
+ /** 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();
protected:
std::vector<DynInstPtr> switchedOutBuffer;
std::vector<bool> switchedOutValid;
- /** Queue of all instructions coming from previous stage on this cycle. */
- std::queue<DynInstPtr> insts[ThePipeline::MaxThreads];
-
- /** 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 */
/** 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;
/** 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