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