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