1/* |
2 * Copyright (c) 2004-2006 The Regents of The University of Michigan |
3 * All rights reserved. 4 * 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 --- 8 unchanged lines hidden (view full) --- 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. |
27 */ 28 |
29#ifndef __CPU_O3_COMMIT_HH__ 30#define __CPU_O3_COMMIT_HH__ |
31 |
32#include "arch/faults.hh" |
33#include "base/statistics.hh" 34#include "base/timebuf.hh" |
35#include "cpu/exetrace.hh" 36#include "cpu/inst_seq.hh" |
37 |
38template <class> 39class O3ThreadState; 40 41/** 42 * DefaultCommit handles single threaded and SMT commit. Its width is 43 * specified by the parameters; each cycle it tries to commit that 44 * many instructions. The SMT policy decides which thread it tries to 45 * commit instructions from. Non- speculative instructions must reach 46 * the head of the ROB before they are ready to execute; once they 47 * reach the head, commit will broadcast the instruction's sequence 48 * number to the previous stages so that they can issue/ execute the 49 * instruction. Only one non-speculative instruction is handled per 50 * cycle. Commit is responsible for handling all back-end initiated 51 * redirects. It receives the redirect, and then broadcasts it to all 52 * stages, indicating the sequence number they should squash until, 53 * and any necessary branch misprediction information as well. It 54 * priortizes redirects by instruction's age, only broadcasting a 55 * redirect if it corresponds to an instruction that should currently 56 * be in the ROB. This is done by tracking the sequence number of the 57 * youngest instruction in the ROB, which gets updated to any 58 * squashing instruction's sequence number, and only broadcasting a 59 * redirect if it corresponds to an older instruction. Commit also 60 * supports multiple cycle squashing, to model a ROB that can only 61 * remove a certain number of instructions per cycle. 62 */ |
63template<class Impl> |
64class DefaultCommit |
65{ 66 public: 67 // Typedefs from the Impl. 68 typedef typename Impl::FullCPU FullCPU; 69 typedef typename Impl::DynInstPtr DynInstPtr; 70 typedef typename Impl::Params Params; 71 typedef typename Impl::CPUPol CPUPol; 72 |
73 typedef typename CPUPol::RenameMap RenameMap; |
74 typedef typename CPUPol::ROB ROB; 75 76 typedef typename CPUPol::TimeStruct TimeStruct; |
77 typedef typename CPUPol::FetchStruct FetchStruct; |
78 typedef typename CPUPol::IEWStruct IEWStruct; 79 typedef typename CPUPol::RenameStruct RenameStruct; 80 |
81 typedef typename CPUPol::Fetch Fetch; 82 typedef typename CPUPol::IEW IEW; 83 84 typedef O3ThreadState<Impl> Thread; 85 86 class TrapEvent : public Event { 87 private: 88 DefaultCommit<Impl> *commit; 89 unsigned tid; 90 91 public: 92 TrapEvent(DefaultCommit<Impl> *_commit, unsigned _tid); 93 94 void process(); 95 const char *description(); 96 }; 97 98 /** Overall commit status. Used to determine if the CPU can deschedule 99 * itself due to a lack of activity. 100 */ 101 enum CommitStatus{ 102 Active, 103 Inactive 104 }; 105 106 /** Individual thread status. */ 107 enum ThreadStatus { |
108 Running, 109 Idle, 110 ROBSquashing, |
111 TrapPending, 112 FetchTrapPending |
113 }; 114 |
115 /** Commit policy for SMT mode. */ 116 enum CommitPolicy { 117 Aggressive, 118 RoundRobin, 119 OldestReady 120 }; 121 |
122 private: |
123 /** Overall commit status. */ 124 CommitStatus _status; 125 /** Next commit status, to be set at the end of the cycle. */ 126 CommitStatus _nextStatus; 127 /** Per-thread status. */ 128 ThreadStatus commitStatus[Impl::MaxThreads]; 129 /** Commit policy used in SMT mode. */ 130 CommitPolicy commitPolicy; |
131 132 public: |
133 /** Construct a DefaultCommit with the given parameters. */ 134 DefaultCommit(Params *params); |
135 |
136 /** Returns the name of the DefaultCommit. */ 137 std::string name() const; 138 139 /** Registers statistics. */ |
140 void regStats(); 141 |
142 /** Sets the CPU pointer. */ |
143 void setCPU(FullCPU *cpu_ptr); 144 |
145 /** Sets the list of threads. */ 146 void setThreads(std::vector<Thread *> &threads); 147 148 /** Sets the main time buffer pointer, used for backwards communication. */ |
149 void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr); 150 |
151 void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr); 152 153 /** Sets the pointer to the queue coming from rename. */ |
154 void setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr); 155 |
156 /** Sets the pointer to the queue coming from IEW. */ |
157 void setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr); 158 |
159 void setFetchStage(Fetch *fetch_stage); 160 161 Fetch *fetchStage; 162 163 /** Sets the poitner to the IEW stage. */ 164 void setIEWStage(IEW *iew_stage); 165 166 /** The pointer to the IEW stage. Used solely to ensure that 167 * various events (traps, interrupts, syscalls) do not occur until 168 * all stores have written back. 169 */ 170 IEW *iewStage; 171 172 /** Sets pointer to list of active threads. */ 173 void setActiveThreads(std::list<unsigned> *at_ptr); 174 175 /** Sets pointer to the commited state rename map. */ 176 void setRenameMap(RenameMap rm_ptr[Impl::MaxThreads]); 177 178 /** Sets pointer to the ROB. */ |
179 void setROB(ROB *rob_ptr); 180 |
181 /** Initializes stage by sending back the number of free entries. */ 182 void initStage(); 183 184 void switchOut(); 185 186 void doSwitchOut(); 187 188 void takeOverFrom(); 189 190 /** Ticks the commit stage, which tries to commit instructions. */ |
191 void tick(); 192 |
193 /** Handles any squashes that are sent from IEW, and adds instructions 194 * to the ROB and tries to commit instructions. 195 */ |
196 void commit(); 197 |
198 /** Returns the number of free ROB entries for a specific thread. */ 199 unsigned numROBFreeEntries(unsigned tid); 200 201 void generateXCEvent(unsigned tid); 202 |
203 private: |
204 /** Updates the overall status of commit with the nextStatus, and 205 * tell the CPU if commit is active/inactive. */ 206 void updateStatus(); |
207 |
208 /** Sets the next status based on threads' statuses, which becomes the 209 * current status at the end of the cycle. 210 */ 211 void setNextStatus(); 212 213 /** Checks if the ROB is completed with squashing. This is for the case 214 * where the ROB can take multiple cycles to complete squashing. 215 */ 216 bool robDoneSquashing(); 217 218 /** Returns if any of the threads have the number of ROB entries changed 219 * on this cycle. Used to determine if the number of free ROB entries needs 220 * to be sent back to previous stages. 221 */ 222 bool changedROBEntries(); 223 224 void squashAll(unsigned tid); 225 226 void squashFromTrap(unsigned tid); 227 228 void squashFromXC(unsigned tid); 229 230 /** Commits as many instructions as possible. */ |
231 void commitInsts(); 232 |
233 /** Tries to commit the head ROB instruction passed in. 234 * @param head_inst The instruction to be committed. 235 */ |
236 bool commitHead(DynInstPtr &head_inst, unsigned inst_num); 237 |
238 void generateTrapEvent(unsigned tid); 239 240 /** Gets instructions from rename and inserts them into the ROB. */ |
241 void getInsts(); 242 |
243 /** Marks completed instructions using information sent from IEW. */ |
244 void markCompletedInsts(); 245 |
246 /** Gets the thread to commit, based on the SMT policy. */ 247 int getCommittingThread(); 248 249 /** Returns the thread ID to use based on a round robin policy. */ 250 int roundRobin(); 251 252 /** Returns the thread ID to use based on an oldest instruction policy. */ 253 int oldestReady(); 254 |
255 public: |
256 /** Returns the PC of the head instruction of the ROB. 257 * @todo: Probably remove this function as it returns only thread 0. 258 */ 259 uint64_t readPC() { return PC[0]; } |
260 |
261 uint64_t readPC(unsigned tid) { return PC[tid]; } |
262 |
263 void setPC(uint64_t val, unsigned tid) { PC[tid] = val; } 264 265 uint64_t readNextPC(unsigned tid) { return nextPC[tid]; } 266 267 void setNextPC(uint64_t val, unsigned tid) { nextPC[tid] = val; } 268 |
269 private: 270 /** Time buffer interface. */ 271 TimeBuffer<TimeStruct> *timeBuffer; 272 273 /** Wire to write information heading to previous stages. */ 274 typename TimeBuffer<TimeStruct>::wire toIEW; 275 276 /** Wire to read information from IEW (for ROB). */ 277 typename TimeBuffer<TimeStruct>::wire robInfoFromIEW; 278 |
279 TimeBuffer<FetchStruct> *fetchQueue; 280 281 typename TimeBuffer<FetchStruct>::wire fromFetch; 282 |
283 /** IEW instruction queue interface. */ 284 TimeBuffer<IEWStruct> *iewQueue; 285 286 /** Wire to read information from IEW queue. */ 287 typename TimeBuffer<IEWStruct>::wire fromIEW; 288 289 /** Rename instruction queue interface, for ROB. */ 290 TimeBuffer<RenameStruct> *renameQueue; 291 292 /** Wire to read information from rename queue. */ 293 typename TimeBuffer<RenameStruct>::wire fromRename; 294 |
295 public: |
296 /** ROB interface. */ 297 ROB *rob; 298 |
299 private: |
300 /** Pointer to FullCPU. */ 301 FullCPU *cpu; 302 |
303 std::vector<Thread *> thread; |
304 |
305 Fault fetchFault; 306 307 int fetchTrapWait; 308 309 /** Records that commit has written to the time buffer this cycle. Used for 310 * the CPU to determine if it can deschedule itself if there is no activity. 311 */ 312 bool wroteToTimeBuffer; 313 314 /** Records if the number of ROB entries has changed this cycle. If it has, 315 * then the number of free entries must be re-broadcast. 316 */ 317 bool changedROBNumEntries[Impl::MaxThreads]; 318 319 /** A counter of how many threads are currently squashing. */ 320 int squashCounter; 321 322 /** Records if a thread has to squash this cycle due to a trap. */ 323 bool trapSquash[Impl::MaxThreads]; 324 325 /** Records if a thread has to squash this cycle due to an XC write. */ 326 bool xcSquash[Impl::MaxThreads]; 327 328 /** Priority List used for Commit Policy */ 329 std::list<unsigned> priority_list; 330 |
331 /** IEW to Commit delay, in ticks. */ 332 unsigned iewToCommitDelay; 333 |
334 /** Commit to IEW delay, in ticks. */ 335 unsigned commitToIEWDelay; 336 |
337 /** Rename to ROB delay, in ticks. */ 338 unsigned renameToROBDelay; 339 |
340 unsigned fetchToCommitDelay; 341 |
342 /** Rename width, in instructions. Used so ROB knows how many 343 * instructions to get from the rename instruction queue. 344 */ 345 unsigned renameWidth; 346 347 /** IEW width, in instructions. Used so ROB knows how many 348 * instructions to get from the IEW instruction queue. 349 */ 350 unsigned iewWidth; 351 352 /** Commit width, in instructions. */ 353 unsigned commitWidth; 354 |
355 /** Number of Reorder Buffers */ 356 unsigned numRobs; 357 358 /** Number of Active Threads */ 359 unsigned numThreads; 360 361 bool switchPending; 362 bool switchedOut; 363 364 Tick trapLatency; 365 366 Tick fetchTrapLatency; 367 368 Tick fetchFaultTick; 369 370 Addr PC[Impl::MaxThreads]; 371 372 Addr nextPC[Impl::MaxThreads]; 373 374 /** The sequence number of the youngest valid instruction in the ROB. */ 375 InstSeqNum youngestSeqNum[Impl::MaxThreads]; 376 377 /** Pointer to the list of active threads. */ 378 std::list<unsigned> *activeThreads; 379 380 /** Rename map interface. */ 381 RenameMap *renameMap[Impl::MaxThreads]; 382 383 void updateComInstStats(DynInstPtr &inst); 384 385 /** Stat for the total number of committed instructions. */ |
386 Stats::Scalar<> commitCommittedInsts; |
387 /** Stat for the total number of squashed instructions discarded by commit. 388 */ |
389 Stats::Scalar<> commitSquashedInsts; |
390 /** Stat for the total number of times commit is told to squash. 391 * @todo: Actually increment this stat. 392 */ |
393 Stats::Scalar<> commitSquashEvents; |
394 /** Stat for the total number of times commit has had to stall due to a non- 395 * speculative instruction reaching the head of the ROB. 396 */ |
397 Stats::Scalar<> commitNonSpecStalls; |
398 /** Stat for the total number of branch mispredicts that caused a squash. */ |
399 Stats::Scalar<> branchMispredicts; |
400 /** Distribution of the number of committed instructions each cycle. */ 401 Stats::Distribution<> numCommittedDist; |
402 |
403 /** Total number of instructions committed. */ 404 Stats::Vector<> statComInst; 405 /** Total number of software prefetches committed. */ 406 Stats::Vector<> statComSwp; 407 /** Stat for the total number of committed memory references. */ 408 Stats::Vector<> statComRefs; 409 /** Stat for the total number of committed loads. */ 410 Stats::Vector<> statComLoads; 411 /** Total number of committed memory barriers. */ 412 Stats::Vector<> statComMembars; 413 /** Total number of committed branches. */ 414 Stats::Vector<> statComBranches; 415 416 Stats::Scalar<> commitEligibleSamples; 417 Stats::Vector<> commitEligible; |
418}; 419 |
420#endif // __CPU_O3_COMMIT_HH__ |