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