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