commit.hh revision 2301
1/* 2 * Copyright (c) 2004-2005 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 29#ifndef __CPU_O3_COMMIT_HH__ 30#define __CPU_O3_COMMIT_HH__ 31 32#include "arch/faults.hh" 33#include "cpu/inst_seq.hh" 34#include "base/statistics.hh" 35#include "base/timebuf.hh" 36#include "cpu/exetrace.hh" 37#include "mem/memory_interface.hh" 38 39template <class> 40class O3ThreadState; 41 42/** 43 * DefaultCommit handles single threaded and SMT commit. Its width is specified 44 * by the parameters; each cycle it tries to commit that many instructions. The 45 * SMT policy decides which thread it tries to commit instructions from. Non- 46 * speculative instructions must reach the head of the ROB before they are 47 * ready to execute; once they reach the head, commit will broadcast the 48 * instruction's sequence number to the previous stages so that they can issue/ 49 * execute the instruction. Only one non-speculative instruction is handled per 50 * cycle. Commit is responsible for handling all back-end initiated redirects. 51 * It receives the redirect, and then broadcasts it to all stages, indicating 52 * the sequence number they should squash until, and any necessary branch mis- 53 * prediction information as well. It priortizes redirects by instruction's age, 54 * only broadcasting a redirect if it corresponds to an instruction that should 55 * currently be in the ROB. This is done by tracking the sequence number of the 56 * youngest instruction in the ROB, which gets updated to any squashing 57 * instruction's sequence number, and only broadcasting a redirect if it 58 * corresponds to an older instruction. Commit also supports multiple cycle 59 * squashing, to model a ROB that can only remove a certain number of 60 * instructions per cycle. Eventually traps and interrupts will most likely 61 * be handled here as well. 62 */ 63template<class Impl> 64class DefaultCommit 65{ 66 public: 67 // Typedefs from the Impl. 68 typedef typename Impl::FullCPU FullCPU; 69 typedef typename Impl::DynInstPtr DynInstPtr; 70 typedef typename Impl::Params Params; 71 typedef typename Impl::CPUPol CPUPol; 72 73 typedef typename CPUPol::RenameMap RenameMap; 74 typedef typename CPUPol::ROB ROB; 75 76 typedef typename CPUPol::TimeStruct TimeStruct; 77 typedef typename CPUPol::FetchStruct FetchStruct; 78 typedef typename CPUPol::IEWStruct IEWStruct; 79 typedef typename CPUPol::RenameStruct RenameStruct; 80 81 typedef typename CPUPol::IEW IEW; 82 83 typedef O3ThreadState<Impl> Thread; 84 85 class TrapEvent : public Event { 86 private: 87 DefaultCommit<Impl> *commit; 88 unsigned tid; 89 90 public: 91 TrapEvent(DefaultCommit<Impl> *_commit, unsigned _tid); 92 93 void process(); 94 const char *description(); 95 }; 96 97 /** Overall commit status. Used to determine if the CPU can deschedule 98 * itself due to a lack of activity. 99 */ 100 enum CommitStatus{ 101 Active, 102 Inactive 103 }; 104 105 /** Individual thread status. */ 106 enum ThreadStatus { 107 Running, 108 Idle, 109 ROBSquashing, 110 TrapPending, 111 FetchTrapPending 112 }; 113 114 /** Commit policy for SMT mode. */ 115 enum CommitPolicy { 116 Aggressive, 117 RoundRobin, 118 OldestReady 119 }; 120 121 private: 122 /** Overall commit status. */ 123 CommitStatus _status; 124 /** Next commit status, to be set at the end of the cycle. */ 125 CommitStatus _nextStatus; 126 /** Per-thread status. */ 127 ThreadStatus commitStatus[Impl::MaxThreads]; 128 /** Commit policy used in SMT mode. */ 129 CommitPolicy commitPolicy; 130 131 public: 132 /** Construct a DefaultCommit with the given parameters. */ 133 DefaultCommit(Params *params); 134 135 /** Returns the name of the DefaultCommit. */ 136 std::string name() const; 137 138 /** Registers statistics. */ 139 void regStats(); 140 141 /** Sets the CPU pointer. */ 142 void setCPU(FullCPU *cpu_ptr); 143 144 /** Sets the list of threads. */ 145 void setThreads(std::vector<Thread *> &threads); 146 147 /** Sets the main time buffer pointer, used for backwards communication. */ 148 void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr); 149 150 void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr); 151 152 /** Sets the pointer to the queue coming from rename. */ 153 void setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr); 154 155 /** Sets the pointer to the queue coming from IEW. */ 156 void setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr); 157 158 /** Sets the poitner to the IEW stage. */ 159 void setIEWStage(IEW *iew_stage); 160 161 /** The pointer to the IEW stage. Used solely to ensure that syscalls do 162 * not execute until all stores have written back. 163 */ 164 IEW *iewStage; 165 166 /** Sets pointer to list of active threads. */ 167 void setActiveThreads(std::list<unsigned> *at_ptr); 168 169 /** Sets pointer to the commited state rename map. */ 170 void setRenameMap(RenameMap rm_ptr[Impl::MaxThreads]); 171 172 /** Sets pointer to the ROB. */ 173 void setROB(ROB *rob_ptr); 174 175 /** Initializes stage by sending back the number of free entries. */ 176 void initStage(); 177 178 /** Ticks the commit stage, which tries to commit instructions. */ 179 void tick(); 180 181 /** Handles any squashes that are sent from IEW, and adds instructions 182 * to the ROB and tries to commit instructions. 183 */ 184 void commit(); 185 186 /** Returns the number of free ROB entries for a specific thread. */ 187 unsigned numROBFreeEntries(unsigned tid); 188 189 void generateXCEvent(unsigned tid); 190 191 private: 192 /** Updates the overall status of commit with the nextStatus, and 193 * tell the CPU if commit is active/inactive. */ 194 void updateStatus(); 195 196 /** Sets the next status based on threads' statuses, which becomes the 197 * current status at the end of the cycle. 198 */ 199 void setNextStatus(); 200 201 /** Checks if the ROB is completed with squashing. This is for the case 202 * where the ROB can take multiple cycles to complete squashing. 203 */ 204 bool robDoneSquashing(); 205 206 /** Returns if any of the threads have the number of ROB entries changed 207 * on this cycle. Used to determine if the number of free ROB entries needs 208 * to be sent back to previous stages. 209 */ 210 bool changedROBEntries(); 211 212 void squashFromTrap(unsigned tid); 213 214 void squashFromXC(unsigned tid); 215 216 void squashInFlightInsts(unsigned tid); 217 218 private: 219 /** Commits as many instructions as possible. */ 220 void commitInsts(); 221 222 /** Tries to commit the head ROB instruction passed in. 223 * @param head_inst The instruction to be committed. 224 */ 225 bool commitHead(DynInstPtr &head_inst, unsigned inst_num); 226 227 void generateTrapEvent(unsigned tid); 228 229 /** Gets instructions from rename and inserts them into the ROB. */ 230 void getInsts(); 231 232 /** Marks completed instructions using information sent from IEW. */ 233 void markCompletedInsts(); 234 235 /** Gets the thread to commit, based on the SMT policy. */ 236 int getCommittingThread(); 237 238 /** Returns the thread ID to use based on a round robin policy. */ 239 int roundRobin(); 240 241 /** Returns the thread ID to use based on an oldest instruction policy. */ 242 int oldestReady(); 243 244 public: 245 /** Returns the PC of the head instruction of the ROB. */ 246 uint64_t readPC(); 247 248 uint64_t readPC(unsigned tid) { return PC[tid]; } 249 250 void setPC(uint64_t val, unsigned tid) { PC[tid] = val; } 251 252 uint64_t readNextPC(unsigned tid) { return nextPC[tid]; } 253 254 void setNextPC(uint64_t val, unsigned tid) { nextPC[tid] = val; } 255 256 /** Sets that the ROB is currently squashing. */ 257 void setSquashing(unsigned tid); 258 259 private: 260 /** Time buffer interface. */ 261 TimeBuffer<TimeStruct> *timeBuffer; 262 263 /** Wire to write information heading to previous stages. */ 264 typename TimeBuffer<TimeStruct>::wire toIEW; 265 266 /** Wire to read information from IEW (for ROB). */ 267 typename TimeBuffer<TimeStruct>::wire robInfoFromIEW; 268 269 TimeBuffer<FetchStruct> *fetchQueue; 270 271 typename TimeBuffer<FetchStruct>::wire fromFetch; 272 273 /** IEW instruction queue interface. */ 274 TimeBuffer<IEWStruct> *iewQueue; 275 276 /** Wire to read information from IEW queue. */ 277 typename TimeBuffer<IEWStruct>::wire fromIEW; 278 279 /** Rename instruction queue interface, for ROB. */ 280 TimeBuffer<RenameStruct> *renameQueue; 281 282 /** Wire to read information from rename queue. */ 283 typename TimeBuffer<RenameStruct>::wire fromRename; 284 285 public: 286 /** ROB interface. */ 287 ROB *rob; 288 289 private: 290 /** Pointer to FullCPU. */ 291 FullCPU *cpu; 292 293 /** Memory interface. Used for d-cache accesses. */ 294 MemInterface *dcacheInterface; 295 296 std::vector<Thread *> thread; 297 298 private: 299 Fault fetchFault; 300 InstSeqNum fetchFaultSN; 301 int fetchTrapWait; 302 /** Records that commit has written to the time buffer this cycle. Used for 303 * the CPU to determine if it can deschedule itself if there is no activity. 304 */ 305 bool wroteToTimeBuffer; 306 307 /** Records if the number of ROB entries has changed this cycle. If it has, 308 * then the number of free entries must be re-broadcast. 309 */ 310 bool changedROBNumEntries[Impl::MaxThreads]; 311 312 /** A counter of how many threads are currently squashing. */ 313 int squashCounter; 314 315 /** Records if a thread has to squash this cycle due to a trap. */ 316 bool trapSquash[Impl::MaxThreads]; 317 318 /** Records if a thread has to squash this cycle due to an XC write. */ 319 bool xcSquash[Impl::MaxThreads]; 320 321 /** Priority List used for Commit Policy */ 322 std::list<unsigned> priority_list; 323 324 /** IEW to Commit delay, in ticks. */ 325 unsigned iewToCommitDelay; 326 327 /** Commit to IEW delay, in ticks. */ 328 unsigned commitToIEWDelay; 329 330 /** Rename to ROB delay, in ticks. */ 331 unsigned renameToROBDelay; 332 333 unsigned fetchToCommitDelay; 334 335 /** Rename width, in instructions. Used so ROB knows how many 336 * instructions to get from the rename instruction queue. 337 */ 338 unsigned renameWidth; 339 340 /** IEW width, in instructions. Used so ROB knows how many 341 * instructions to get from the IEW instruction queue. 342 */ 343 unsigned iewWidth; 344 345 /** Commit width, in instructions. */ 346 unsigned commitWidth; 347 348 /** Number of Reorder Buffers */ 349 unsigned numRobs; 350 351 /** Number of Active Threads */ 352 unsigned numThreads; 353 354 Tick trapLatency; 355 356 Tick fetchTrapLatency; 357 Tick fetchFaultTick; 358 359 Addr PC[Impl::MaxThreads]; 360 361 Addr nextPC[Impl::MaxThreads]; 362 363 /** The sequence number of the youngest valid instruction in the ROB. */ 364 InstSeqNum youngestSeqNum[Impl::MaxThreads]; 365 366 /** Pointer to the list of active threads. */ 367 std::list<unsigned> *activeThreads; 368 369 /** Rename map interface. */ 370 RenameMap *renameMap[Impl::MaxThreads]; 371 372 void updateComInstStats(DynInstPtr &inst); 373 374 /** Stat for the total number of committed instructions. */ 375 Stats::Scalar<> commitCommittedInsts; 376 /** Stat for the total number of squashed instructions discarded by commit. 377 */ 378 Stats::Scalar<> commitSquashedInsts; 379 /** Stat for the total number of times commit is told to squash. 380 * @todo: Actually increment this stat. 381 */ 382 Stats::Scalar<> commitSquashEvents; 383 /** Stat for the total number of times commit has had to stall due to a non- 384 * speculative instruction reaching the head of the ROB. 385 */ 386 Stats::Scalar<> commitNonSpecStalls; 387 /** Stat for the total number of committed branches. */ 388// Stats::Scalar<> commitCommittedBranches; 389 /** Stat for the total number of committed loads. */ 390// Stats::Scalar<> commitCommittedLoads; 391 /** Stat for the total number of committed memory references. */ 392// Stats::Scalar<> commitCommittedMemRefs; 393 /** Stat for the total number of branch mispredicts that caused a squash. */ 394 Stats::Scalar<> branchMispredicts; 395 /** Distribution of the number of committed instructions each cycle. */ 396 Stats::Distribution<> numCommittedDist; 397 398 // total number of instructions committed 399 Stats::Vector<> stat_com_inst; 400 Stats::Vector<> stat_com_swp; 401 Stats::Vector<> stat_com_refs; 402 Stats::Vector<> stat_com_loads; 403 Stats::Vector<> stat_com_membars; 404 Stats::Vector<> stat_com_branches; 405 406 Stats::Scalar<> commit_eligible_samples; 407 Stats::Vector<> commit_eligible; 408}; 409 410#endif // __CPU_O3_COMMIT_HH__ 411