2 * Copyright (c) 2007 MIPS Technologies, Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * Authors: Korey Sewell
32 #ifndef __CPU_INORDER_PIPELINE_STAGE_HH__
33 #define __CPU_INORDER_PIPELINE_STAGE_HH__
38 #include "base/statistics.hh"
39 #include "cpu/inorder/comm.hh"
40 #include "cpu/inorder/inorder_dyn_inst.hh"
41 #include "cpu/inorder/pipeline_traits.hh"
42 #include "cpu/timebuf.hh"
43 #include "params/InOrderCPU.hh"
50 typedef ThePipeline::Params Params;
51 typedef ThePipeline::DynInstPtr DynInstPtr;
54 /** Overall stage status. Used to determine if the CPU can
55 * deschedule itself due to a lack of activity.
62 /** Individual thread status. */
76 /** The Number of This Pipeline Stage */
79 /** The width of stage, in instructions. */
82 /** Number of Threads*/
88 /** Per-thread status. */
89 ThreadStatus stageStatus[ThePipeline::MaxThreads];
92 PipelineStage(Params *params, unsigned stage_num);
94 virtual ~PipelineStage();
96 /** PipelineStage initialization. */
97 void init(Params *params);
99 /** Returns the name of stage. */
100 std::string name() const;
102 /** Registers statistics. */
105 /** Sets CPU pointer. */
106 void setCPU(InOrderCPU *cpu_ptr);
108 /** Sets the main backwards communication time buffer pointer. */
109 void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);
111 /** Sets pointer to time buffer coming from fetch. */
112 void setPrevStageQueue(TimeBuffer<InterStageStruct> *prev_stage_ptr);
114 /** Sets pointer to time buffer used to communicate to the next stage. */
115 void setNextStageQueue(TimeBuffer<InterStageStruct> *next_stage_ptr);
117 /** Sets pointer to list of active threads. */
118 void setActiveThreads(std::list<ThreadID> *at_ptr);
120 bool nextStageQueueValid(int stage_num);
122 bool isBlocked(ThreadID tid);
124 /** Changes the status of this stage to active, and indicates this
127 //inline void switchToActive();
129 /** Changes the status of this stage to inactive, and indicates
132 //inline void switchToInactive();
134 /** Switches out the stage stage. */
137 /** Takes over from another CPU's thread. */
140 /** Ticks stage, processing all input signals and executing as many
141 * instructions as possible.
145 /** Set a resource stall in the pipeline-stage */
146 void setResStall(ResReqPtr res_req, ThreadID tid);
148 /** Unset a resource stall in the pipeline-stage */
149 void unsetResStall(ResReqPtr res_req, ThreadID tid);
151 /** Remove all stall signals for a particular thread; */
152 void removeStalls(ThreadID tid);
154 /** Is there room in the stage buffer? */
155 int stageBufferAvail();
158 /** Evaluate Stage Conditions and then process stage */
159 virtual void processStage(bool &status_change);
161 /** Determines what to do based on stage's current status.
162 * @param status_change stage() sets this variable if there was a status
163 * change (ie switching from from blocking to unblocking).
164 * @param tid Thread id to stage instructions from.
166 void processThread(bool &status_change, ThreadID tid);
168 /** Processes instructions from fetch and passes them on to rename.
169 * Decoding of instructions actually happens when they are created in
170 * fetch, so this function mostly checks if PC-relative branches are
173 virtual void processInsts(ThreadID tid);
175 /** Process all resources on an instruction's resource schedule */
176 bool processInstSchedule(DynInstPtr inst, int &reqs_processed);
178 /** Is there room in the next stage buffer for this instruction? */
179 bool canSendInstToStage(unsigned stage_num);
181 /** Send an instruction to the next stage buffer */
182 bool sendInstToNextStage(DynInstPtr inst);
184 /** Total size of all skid buffers */
187 /** Returns if all of the skid buffers are empty. */
190 /** Updates overall stage status based on all of the threads' statuses. */
193 /** Separates instructions from fetch into individual lists of instructions
198 /** Reads all stall signals from the backwards communication timebuffer. */
199 void readStallSignals(ThreadID tid);
201 /** Checks all input signals and updates stage's status appropriately. */
202 bool checkSignalsAndUpdate(ThreadID tid);
204 /** Checks all stall signals, and returns if any are true. */
205 bool checkStall(ThreadID tid) const;
207 /** Returns if there any instructions from the previous stage
210 inline bool prevStageInstsValid();
212 /** Switches stage to blocking, and signals back that stage has
214 * @return Returns true if there is a status change.
216 bool block(ThreadID tid);
218 void blockDueToBuffer(ThreadID tid);
220 /** Switches stage to unblocking if the skid buffer is empty, and
221 * signals back that stage has unblocked.
222 * @return Returns true if there is a status change.
224 bool unblock(ThreadID tid);
228 void activateThread(ThreadID tid);
230 /** Setup Squashing Information to be passed back thru the pipeline */
231 void setupSquash(DynInstPtr inst, ThreadID tid);
233 virtual void squashDueToMemStall(InstSeqNum seq_num, ThreadID tid);
235 /** Perform squash of instructions above seq_num */
236 virtual void squash(InstSeqNum squash_num, ThreadID tid);
238 /** Squash instructions from stage buffer */
239 void squashPrevStageInsts(InstSeqNum squash_seq_num, ThreadID tid);
244 /** CPU interface. */
247 Trace::InOrderTrace *tracer;
249 /** List of active thread ids */
250 std::list<ThreadID> *activeThreads;
252 /** Buffer of instructions switched out to mem-stall.
253 * Only used when using SwitchOnCacheMiss threading model
254 * Used as 1-to-1 mapping between ThreadID and Entry.
256 std::vector<DynInstPtr> switchedOutBuffer;
257 std::vector<bool> switchedOutValid;
259 /** Instructions that we've processed this tick
260 * NOTE: "Processed" means completed at least 1 instruction request
262 unsigned instsProcessed;
264 /** Skid buffer between previous stage and this one. */
265 std::list<DynInstPtr> skidBuffer[ThePipeline::MaxThreads];
267 /** Instruction used to signify that there is no *real* instruction in
269 DynInstPtr dummyBufferInst;
271 /** SeqNum of Squashing Branch Delay Instruction (used for MIPS) */
272 Addr bdelayDoneSeqNum[ThePipeline::MaxThreads];
274 /** Tells when their is a pending delay slot inst. to send
275 * to rename. If there is, then wait squash after the next
276 * instruction (used for MIPS).
278 bool squashAfterDelaySlot[ThePipeline::MaxThreads];
280 /** Instruction used for squashing branch (used for MIPS) */
281 DynInstPtr squashInst[ThePipeline::MaxThreads];
283 /** Maximum size of the inter-stage buffer connecting the previous stage to
284 * this stage (which we call a skid buffer) */
285 unsigned stageBufferMax;
287 /** Variable that tracks if stage has written to the time buffer this
288 * cycle. Used to tell CPU if there is activity this cycle.
290 bool wroteToTimeBuffer;
292 /** Index of instructions being sent to the next stage. */
293 unsigned toNextStageIndex;
295 /** The last stage that this particular stage should look for stalls */
296 int lastStallingStage[ThePipeline::MaxThreads];
298 /** Time buffer interface. */
299 TimeBuffer<TimeStruct> *timeBuffer;
302 /** Wire to get rename's output from backwards time buffer. */
303 TimeBuffer<TimeStruct>::wire fromNextStages;
305 /** Wire to get iew's information from backwards time buffer. */
306 TimeBuffer<TimeStruct>::wire toPrevStages;
308 /** Instruction queue linking previous stage */
309 TimeBuffer<InterStageStruct> *prevStageQueue;
311 /** Wire to get the previous stage's. */
312 TimeBuffer<InterStageStruct>::wire prevStage;
314 /** Instruction queue linking next stage */
315 TimeBuffer<InterStageStruct> *nextStageQueue;
317 /** Wire to write to the next stage */
318 TimeBuffer<InterStageStruct>::wire nextStage;
320 /** Is Previous Stage Valid? */
323 /** Is Next Stage Valid? */
328 /** Source of possible stalls. */
330 bool stage[ThePipeline::NumStages];
331 std::vector<ResReqPtr> resources;
334 /** Tracks stage/resource stalls */
335 Stalls stalls[ThePipeline::MaxThreads];
337 /** Number of cycles 0 instruction(s) are processed. */
338 Stats::Scalar idleCycles;
340 /** Number of cycles 1+ instructions are processed. */
341 Stats::Scalar runCycles;
343 /** Percentage of cycles 1+ instructions are processed. */
344 Stats::Formula utilization;