commit.hh revision 10731:17c5d36dfdac
16019Shines@cs.fsu.edu/* 26019Shines@cs.fsu.edu * Copyright (c) 2010-2012, 2014 ARM Limited 310037SARM gem5 Developers * All rights reserved. 47100Sgblack@eecs.umich.edu * 57100Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 67100Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 77100Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 87100Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 97100Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 107100Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 117100Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 127100Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 137100Sgblack@eecs.umich.edu * 147100Sgblack@eecs.umich.edu * Copyright (c) 2004-2006 The Regents of The University of Michigan 156019Shines@cs.fsu.edu * All rights reserved. 166019Shines@cs.fsu.edu * 176019Shines@cs.fsu.edu * Redistribution and use in source and binary forms, with or without 186019Shines@cs.fsu.edu * modification, are permitted provided that the following conditions are 196019Shines@cs.fsu.edu * met: redistributions of source code must retain the above copyright 206019Shines@cs.fsu.edu * notice, this list of conditions and the following disclaimer; 216019Shines@cs.fsu.edu * redistributions in binary form must reproduce the above copyright 226019Shines@cs.fsu.edu * notice, this list of conditions and the following disclaimer in the 236019Shines@cs.fsu.edu * documentation and/or other materials provided with the distribution; 246019Shines@cs.fsu.edu * neither the name of the copyright holders nor the names of its 256019Shines@cs.fsu.edu * contributors may be used to endorse or promote products derived from 266019Shines@cs.fsu.edu * this software without specific prior written permission. 276019Shines@cs.fsu.edu * 286019Shines@cs.fsu.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 296019Shines@cs.fsu.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 306019Shines@cs.fsu.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 316019Shines@cs.fsu.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 326019Shines@cs.fsu.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 336019Shines@cs.fsu.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 346019Shines@cs.fsu.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 356019Shines@cs.fsu.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 366019Shines@cs.fsu.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 376019Shines@cs.fsu.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 386019Shines@cs.fsu.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 396019Shines@cs.fsu.edu * 406019Shines@cs.fsu.edu * Authors: Kevin Lim 416019Shines@cs.fsu.edu * Korey Sewell 426757SAli.Saidi@ARM.com */ 436019Shines@cs.fsu.edu 446019Shines@cs.fsu.edu#ifndef __CPU_O3_COMMIT_HH__ 456019Shines@cs.fsu.edu#define __CPU_O3_COMMIT_HH__ 466019Shines@cs.fsu.edu 476019Shines@cs.fsu.edu#include <queue> 4811320Ssteve.reinhardt@amd.com 496019Shines@cs.fsu.edu#include "base/statistics.hh" 509022Sgblack@eecs.umich.edu#include "cpu/exetrace.hh" 516019Shines@cs.fsu.edu#include "cpu/inst_seq.hh" 5212640Sgiacomo.travaglini@arm.com#include "cpu/timebuf.hh" 5310037SARM gem5 Developers#include "sim/probe/probe.hh" 5410037SARM gem5 Developers 557170Sgblack@eecs.umich.edustruct DerivO3CPUParams; 566253Sgblack@eecs.umich.edu 5710037SARM gem5 Developerstemplate <class> 587202Sgblack@eecs.umich.edustruct O3ThreadState; 5910037SARM gem5 Developers 606253Sgblack@eecs.umich.edu/** 6110611SAndreas.Sandberg@ARM.com * DefaultCommit handles single threaded and SMT commit. Its width is 626253Sgblack@eecs.umich.edu * specified by the parameters; each cycle it tries to commit that 637396Sgblack@eecs.umich.edu * many instructions. The SMT policy decides which thread it tries to 6410037SARM gem5 Developers * commit instructions from. Non- speculative instructions must reach 658745Sgblack@eecs.umich.edu * the head of the ROB before they are ready to execute; once they 667405SAli.Saidi@ARM.com * reach the head, commit will broadcast the instruction's sequence 6710461SAndreas.Sandberg@ARM.com * number to the previous stages so that they can issue/ execute the 688782Sgblack@eecs.umich.edu * instruction. Only one non-speculative instruction is handled per 698782Sgblack@eecs.umich.edu * cycle. Commit is responsible for handling all back-end initiated 708782Sgblack@eecs.umich.edu * redirects. It receives the redirect, and then broadcasts it to all 7110810Sbr@bsdpad.com * stages, indicating the sequence number they should squash until, 7210810Sbr@bsdpad.com * and any necessary branch misprediction information as well. It 7310810Sbr@bsdpad.com * priortizes redirects by instruction's age, only broadcasting a 747259Sgblack@eecs.umich.edu * redirect if it corresponds to an instruction that should currently 758757Sgblack@eecs.umich.edu * be in the ROB. This is done by tracking the sequence number of the 7610461SAndreas.Sandberg@ARM.com * youngest instruction in the ROB, which gets updated to any 778782Sgblack@eecs.umich.edu * squashing instruction's sequence number, and only broadcasting a 788757Sgblack@eecs.umich.edu * redirect if it corresponds to an older instruction. Commit also 7912531Sandreas.sandberg@arm.com * supports multiple cycle squashing, to model a ROB that can only 808777Sgblack@eecs.umich.edu * remove a certain number of instructions per cycle. 818782Sgblack@eecs.umich.edu */ 828756Sgblack@eecs.umich.edutemplate<class Impl> 8310037SARM gem5 Developersclass DefaultCommit 8410037SARM gem5 Developers{ 856019Shines@cs.fsu.edu public: 8612605Sgiacomo.travaglini@arm.com // Typedefs from the Impl. 876757SAli.Saidi@ARM.com typedef typename Impl::O3CPU O3CPU; 888757Sgblack@eecs.umich.edu typedef typename Impl::DynInstPtr DynInstPtr; 896019Shines@cs.fsu.edu typedef typename Impl::CPUPol CPUPol; 908745Sgblack@eecs.umich.edu 919384SAndreas.Sandberg@arm.com typedef typename CPUPol::RenameMap RenameMap; 926397Sgblack@eecs.umich.edu typedef typename CPUPol::ROB ROB; 9312531Sandreas.sandberg@arm.com 948782Sgblack@eecs.umich.edu typedef typename CPUPol::TimeStruct TimeStruct; 956019Shines@cs.fsu.edu typedef typename CPUPol::FetchStruct FetchStruct; 9610461SAndreas.Sandberg@ARM.com typedef typename CPUPol::IEWStruct IEWStruct; 976397Sgblack@eecs.umich.edu typedef typename CPUPol::RenameStruct RenameStruct; 988335Snate@binkert.org 9912531Sandreas.sandberg@arm.com typedef typename CPUPol::Fetch Fetch; 1009023Sgblack@eecs.umich.edu typedef typename CPUPol::IEW IEW; 1019023Sgblack@eecs.umich.edu 10210461SAndreas.Sandberg@ARM.com typedef O3ThreadState<Impl> Thread; 1038335Snate@binkert.org 1046019Shines@cs.fsu.edu /** Event class used to schedule a squash due to a trap (fault or 10510196SCurtis.Dunham@arm.com * interrupt) to happen on a specific cycle. 10612222Sgabeblack@google.com */ 107 class TrapEvent : public Event { 108 private: 109 DefaultCommit<Impl> *commit; 110 ThreadID tid; 111 112 public: 113 TrapEvent(DefaultCommit<Impl> *_commit, ThreadID _tid); 114 115 void process(); 116 const char *description() const; 117 }; 118 119 /** Overall commit status. Used to determine if the CPU can deschedule 120 * itself due to a lack of activity. 121 */ 122 enum CommitStatus{ 123 Active, 124 Inactive 125 }; 126 127 /** Individual thread status. */ 128 enum ThreadStatus { 129 Running, 130 Idle, 131 ROBSquashing, 132 TrapPending, 133 FetchTrapPending, 134 SquashAfterPending, //< Committing instructions before a squash. 135 }; 136 137 /** Commit policy for SMT mode. */ 138 enum CommitPolicy { 139 Aggressive, 140 RoundRobin, 141 OldestReady 142 }; 143 144 private: 145 /** Overall commit status. */ 146 CommitStatus _status; 147 /** Next commit status, to be set at the end of the cycle. */ 148 CommitStatus _nextStatus; 149 /** Per-thread status. */ 150 ThreadStatus commitStatus[Impl::MaxThreads]; 151 /** Commit policy used in SMT mode. */ 152 CommitPolicy commitPolicy; 153 154 /** Probe Points. */ 155 ProbePointArg<DynInstPtr> *ppCommit; 156 ProbePointArg<DynInstPtr> *ppCommitStall; 157 158 public: 159 /** Construct a DefaultCommit with the given parameters. */ 160 DefaultCommit(O3CPU *_cpu, DerivO3CPUParams *params); 161 162 /** Returns the name of the DefaultCommit. */ 163 std::string name() const; 164 165 /** Registers statistics. */ 166 void regStats(); 167 168 /** Registers probes. */ 169 void regProbePoints(); 170 171 /** Sets the list of threads. */ 172 void setThreads(std::vector<Thread *> &threads); 173 174 /** Sets the main time buffer pointer, used for backwards communication. */ 175 void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr); 176 177 void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr); 178 179 /** Sets the pointer to the queue coming from rename. */ 180 void setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr); 181 182 /** Sets the pointer to the queue coming from IEW. */ 183 void setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr); 184 185 /** Sets the pointer to the IEW stage. */ 186 void setIEWStage(IEW *iew_stage); 187 188 /** The pointer to the IEW stage. Used solely to ensure that 189 * various events (traps, interrupts, syscalls) do not occur until 190 * all stores have written back. 191 */ 192 IEW *iewStage; 193 194 /** Sets pointer to list of active threads. */ 195 void setActiveThreads(std::list<ThreadID> *at_ptr); 196 197 /** Sets pointer to the commited state rename map. */ 198 void setRenameMap(RenameMap rm_ptr[Impl::MaxThreads]); 199 200 /** Sets pointer to the ROB. */ 201 void setROB(ROB *rob_ptr); 202 203 /** Initializes stage by sending back the number of free entries. */ 204 void startupStage(); 205 206 /** Initializes the draining of commit. */ 207 void drain(); 208 209 /** Resumes execution after draining. */ 210 void drainResume(); 211 212 /** Perform sanity checks after a drain. */ 213 void drainSanityCheck() const; 214 215 /** Has the stage drained? */ 216 bool isDrained() const; 217 218 /** Takes over from another CPU's thread. */ 219 void takeOverFrom(); 220 221 /** Deschedules a thread from scheduling */ 222 void deactivateThread(ThreadID tid); 223 224 /** Ticks the commit stage, which tries to commit instructions. */ 225 void tick(); 226 227 /** Handles any squashes that are sent from IEW, and adds instructions 228 * to the ROB and tries to commit instructions. 229 */ 230 void commit(); 231 232 /** Returns the number of free ROB entries for a specific thread. */ 233 size_t numROBFreeEntries(ThreadID tid); 234 235 /** Generates an event to schedule a squash due to a trap. */ 236 void generateTrapEvent(ThreadID tid); 237 238 /** Records that commit needs to initiate a squash due to an 239 * external state update through the TC. 240 */ 241 void generateTCEvent(ThreadID tid); 242 243 private: 244 /** Updates the overall status of commit with the nextStatus, and 245 * tell the CPU if commit is active/inactive. 246 */ 247 void updateStatus(); 248 249 /** Returns if any of the threads have the number of ROB entries changed 250 * on this cycle. Used to determine if the number of free ROB entries needs 251 * to be sent back to previous stages. 252 */ 253 bool changedROBEntries(); 254 255 /** Squashes all in flight instructions. */ 256 void squashAll(ThreadID tid); 257 258 /** Handles squashing due to a trap. */ 259 void squashFromTrap(ThreadID tid); 260 261 /** Handles squashing due to an TC write. */ 262 void squashFromTC(ThreadID tid); 263 264 /** Handles a squash from a squashAfter() request. */ 265 void squashFromSquashAfter(ThreadID tid); 266 267 /** 268 * Handle squashing from instruction with SquashAfter set. 269 * 270 * This differs from the other squashes as it squashes following 271 * instructions instead of the current instruction and doesn't 272 * clean up various status bits about traps/tc writes 273 * pending. Since there might have been instructions committed by 274 * the commit stage before the squashing instruction was reached 275 * and we can't commit and squash in the same cycle, we have to 276 * squash in two steps: 277 * 278 * <ol> 279 * <li>Immediately set the commit status of the thread of 280 * SquashAfterPending. This forces the thread to stop 281 * committing instructions in this cycle. The last 282 * instruction to be committed in this cycle will be the 283 * SquashAfter instruction. 284 * <li>In the next cycle, commit() checks for the 285 * SquashAfterPending state and squashes <i>all</i> 286 * in-flight instructions. Since the SquashAfter instruction 287 * was the last instruction to be committed in the previous 288 * cycle, this causes all subsequent instructions to be 289 * squashed. 290 * </ol> 291 * 292 * @param tid ID of the thread to squash. 293 * @param head_inst Instruction that requested the squash. 294 */ 295 void squashAfter(ThreadID tid, DynInstPtr &head_inst); 296 297 /** Handles processing an interrupt. */ 298 void handleInterrupt(); 299 300 /** Get fetch redirecting so we can handle an interrupt */ 301 void propagateInterrupt(); 302 303 /** Commits as many instructions as possible. */ 304 void commitInsts(); 305 306 /** Tries to commit the head ROB instruction passed in. 307 * @param head_inst The instruction to be committed. 308 */ 309 bool commitHead(DynInstPtr &head_inst, unsigned inst_num); 310 311 /** Gets instructions from rename and inserts them into the ROB. */ 312 void getInsts(); 313 314 /** Marks completed instructions using information sent from IEW. */ 315 void markCompletedInsts(); 316 317 /** Gets the thread to commit, based on the SMT policy. */ 318 ThreadID getCommittingThread(); 319 320 /** Returns the thread ID to use based on a round robin policy. */ 321 ThreadID roundRobin(); 322 323 /** Returns the thread ID to use based on an oldest instruction policy. */ 324 ThreadID oldestReady(); 325 326 public: 327 /** Reads the PC of a specific thread. */ 328 TheISA::PCState pcState(ThreadID tid) { return pc[tid]; } 329 330 /** Sets the PC of a specific thread. */ 331 void pcState(const TheISA::PCState &val, ThreadID tid) 332 { pc[tid] = val; } 333 334 /** Returns the PC of a specific thread. */ 335 Addr instAddr(ThreadID tid) { return pc[tid].instAddr(); } 336 337 /** Returns the next PC of a specific thread. */ 338 Addr nextInstAddr(ThreadID tid) { return pc[tid].nextInstAddr(); } 339 340 /** Reads the micro PC of a specific thread. */ 341 Addr microPC(ThreadID tid) { return pc[tid].microPC(); } 342 343 private: 344 /** Time buffer interface. */ 345 TimeBuffer<TimeStruct> *timeBuffer; 346 347 /** Wire to write information heading to previous stages. */ 348 typename TimeBuffer<TimeStruct>::wire toIEW; 349 350 /** Wire to read information from IEW (for ROB). */ 351 typename TimeBuffer<TimeStruct>::wire robInfoFromIEW; 352 353 TimeBuffer<FetchStruct> *fetchQueue; 354 355 typename TimeBuffer<FetchStruct>::wire fromFetch; 356 357 /** IEW instruction queue interface. */ 358 TimeBuffer<IEWStruct> *iewQueue; 359 360 /** Wire to read information from IEW queue. */ 361 typename TimeBuffer<IEWStruct>::wire fromIEW; 362 363 /** Rename instruction queue interface, for ROB. */ 364 TimeBuffer<RenameStruct> *renameQueue; 365 366 /** Wire to read information from rename queue. */ 367 typename TimeBuffer<RenameStruct>::wire fromRename; 368 369 public: 370 /** ROB interface. */ 371 ROB *rob; 372 373 private: 374 /** Pointer to O3CPU. */ 375 O3CPU *cpu; 376 377 /** Vector of all of the threads. */ 378 std::vector<Thread *> thread; 379 380 /** Records that commit has written to the time buffer this cycle. Used for 381 * the CPU to determine if it can deschedule itself if there is no activity. 382 */ 383 bool wroteToTimeBuffer; 384 385 /** Records if the number of ROB entries has changed this cycle. If it has, 386 * then the number of free entries must be re-broadcast. 387 */ 388 bool changedROBNumEntries[Impl::MaxThreads]; 389 390 /** Records if a thread has to squash this cycle due to a trap. */ 391 bool trapSquash[Impl::MaxThreads]; 392 393 /** Records if a thread has to squash this cycle due to an XC write. */ 394 bool tcSquash[Impl::MaxThreads]; 395 396 /** 397 * Instruction passed to squashAfter(). 398 * 399 * The squash after implementation needs to buffer the instruction 400 * that caused a squash since this needs to be passed to the fetch 401 * stage once squashing starts. 402 */ 403 DynInstPtr squashAfterInst[Impl::MaxThreads]; 404 405 /** Priority List used for Commit Policy */ 406 std::list<ThreadID> priority_list; 407 408 /** IEW to Commit delay. */ 409 Cycles iewToCommitDelay; 410 411 /** Commit to IEW delay. */ 412 Cycles commitToIEWDelay; 413 414 /** Rename to ROB delay. */ 415 Cycles renameToROBDelay; 416 417 Cycles fetchToCommitDelay; 418 419 /** Rename width, in instructions. Used so ROB knows how many 420 * instructions to get from the rename instruction queue. 421 */ 422 unsigned renameWidth; 423 424 /** Commit width, in instructions. */ 425 unsigned commitWidth; 426 427 /** Number of Reorder Buffers */ 428 unsigned numRobs; 429 430 /** Number of Active Threads */ 431 ThreadID numThreads; 432 433 /** Is a drain pending? Commit is looking for an instruction boundary while 434 * there are no pending interrupts 435 */ 436 bool drainPending; 437 438 /** Is a drain imminent? Commit has found an instruction boundary while no 439 * interrupts were present or in flight. This was the last architecturally 440 * committed instruction. Interrupts disabled and pipeline flushed. 441 * Waiting for structures to finish draining. 442 */ 443 bool drainImminent; 444 445 /** The latency to handle a trap. Used when scheduling trap 446 * squash event. 447 */ 448 Cycles trapLatency; 449 450 /** The interrupt fault. */ 451 Fault interrupt; 452 453 /** The commit PC state of each thread. Refers to the instruction that 454 * is currently being processed/committed. 455 */ 456 TheISA::PCState pc[Impl::MaxThreads]; 457 458 /** The sequence number of the youngest valid instruction in the ROB. */ 459 InstSeqNum youngestSeqNum[Impl::MaxThreads]; 460 461 /** The sequence number of the last commited instruction. */ 462 InstSeqNum lastCommitedSeqNum[Impl::MaxThreads]; 463 464 /** Records if there is a trap currently in flight. */ 465 bool trapInFlight[Impl::MaxThreads]; 466 467 /** Records if there were any stores committed this cycle. */ 468 bool committedStores[Impl::MaxThreads]; 469 470 /** Records if commit should check if the ROB is truly empty (see 471 commit_impl.hh). */ 472 bool checkEmptyROB[Impl::MaxThreads]; 473 474 /** Pointer to the list of active threads. */ 475 std::list<ThreadID> *activeThreads; 476 477 /** Rename map interface. */ 478 RenameMap *renameMap[Impl::MaxThreads]; 479 480 /** True if last committed microop can be followed by an interrupt */ 481 bool canHandleInterrupts; 482 483 /** Have we had an interrupt pending and then seen it de-asserted because 484 of a masking change? In this case the variable is set and the next time 485 interrupts are enabled and pending the pipeline will squash to avoid 486 a possible livelock senario. */ 487 bool avoidQuiesceLiveLock; 488 489 /** Updates commit stats based on this instruction. */ 490 void updateComInstStats(DynInstPtr &inst); 491 492 /** Stat for the total number of squashed instructions discarded by commit. 493 */ 494 Stats::Scalar commitSquashedInsts; 495 /** Stat for the total number of times commit has had to stall due to a non- 496 * speculative instruction reaching the head of the ROB. 497 */ 498 Stats::Scalar commitNonSpecStalls; 499 /** Stat for the total number of branch mispredicts that caused a squash. */ 500 Stats::Scalar branchMispredicts; 501 /** Distribution of the number of committed instructions each cycle. */ 502 Stats::Distribution numCommittedDist; 503 504 /** Total number of instructions committed. */ 505 Stats::Vector instsCommitted; 506 /** Total number of ops (including micro ops) committed. */ 507 Stats::Vector opsCommitted; 508 /** Total number of software prefetches committed. */ 509 Stats::Vector statComSwp; 510 /** Stat for the total number of committed memory references. */ 511 Stats::Vector statComRefs; 512 /** Stat for the total number of committed loads. */ 513 Stats::Vector statComLoads; 514 /** Total number of committed memory barriers. */ 515 Stats::Vector statComMembars; 516 /** Total number of committed branches. */ 517 Stats::Vector statComBranches; 518 /** Total number of floating point instructions */ 519 Stats::Vector statComFloating; 520 /** Total number of integer instructions */ 521 Stats::Vector statComInteger; 522 /** Total number of function calls */ 523 Stats::Vector statComFunctionCalls; 524 /** Committed instructions by instruction type (OpClass) */ 525 Stats::Vector2d statCommittedInstType; 526 527 /** Number of cycles where the commit bandwidth limit is reached. */ 528 Stats::Scalar commitEligibleSamples; 529}; 530 531#endif // __CPU_O3_COMMIT_HH__ 532