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