fetch.hh revision 2669:f2b336e89d2a
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 29#ifndef __CPU_O3_FETCH_HH__ 30#define __CPU_O3_FETCH_HH__ 31 32#include "arch/utility.hh" 33#include "base/statistics.hh" 34#include "base/timebuf.hh" 35#include "cpu/pc_event.hh" 36#include "mem/packet.hh" 37#include "mem/port.hh" 38#include "sim/eventq.hh" 39 40class Sampler; 41 42/** 43 * DefaultFetch class handles both single threaded and SMT fetch. Its 44 * width is specified by the parameters; each cycle it tries to fetch 45 * that many instructions. It supports using a branch predictor to 46 * predict direction and targets. 47 * It supports the idling functionalitiy of the CPU by indicating to 48 * the CPU when it is active and inactive. 49 */ 50template <class Impl> 51class DefaultFetch 52{ 53 public: 54 /** Typedefs from Impl. */ 55 typedef typename Impl::CPUPol CPUPol; 56 typedef typename Impl::DynInst DynInst; 57 typedef typename Impl::DynInstPtr DynInstPtr; 58 typedef typename Impl::FullCPU FullCPU; 59 typedef typename Impl::Params Params; 60 61 /** Typedefs from the CPU policy. */ 62 typedef typename CPUPol::BPredUnit BPredUnit; 63 typedef typename CPUPol::FetchStruct FetchStruct; 64 typedef typename CPUPol::TimeStruct TimeStruct; 65 66 /** Typedefs from ISA. */ 67 typedef TheISA::MachInst MachInst; 68 typedef TheISA::ExtMachInst ExtMachInst; 69 70 class IcachePort : public Port 71 { 72 protected: 73 DefaultFetch<Impl> *fetch; 74 75 public: 76 IcachePort(DefaultFetch<Impl> *_fetch) 77 : Port(_fetch->name() + "-iport"), fetch(_fetch) 78 { } 79 80 protected: 81 virtual Tick recvAtomic(PacketPtr pkt); 82 83 virtual void recvFunctional(PacketPtr pkt); 84 85 virtual void recvStatusChange(Status status); 86 87 virtual void getDeviceAddressRanges(AddrRangeList &resp, 88 AddrRangeList &snoop) 89 { resp.clear(); snoop.clear(); } 90 91 virtual bool recvTiming(PacketPtr pkt); 92 93 virtual void recvRetry(); 94 }; 95 96 public: 97 /** Overall fetch status. Used to determine if the CPU can 98 * deschedule itsef due to a lack of activity. 99 */ 100 enum FetchStatus { 101 Active, 102 Inactive 103 }; 104 105 /** Individual thread status. */ 106 enum ThreadStatus { 107 Running, 108 Idle, 109 Squashing, 110 Blocked, 111 Fetching, 112 TrapPending, 113 QuiescePending, 114 SwitchOut, 115 IcacheWaitResponse, 116 IcacheRetry, 117 IcacheAccessComplete 118 }; 119 120 /** Fetching Policy, Add new policies here.*/ 121 enum FetchPriority { 122 SingleThread, 123 RoundRobin, 124 Branch, 125 IQ, 126 LSQ 127 }; 128 129 private: 130 /** Fetch status. */ 131 FetchStatus _status; 132 133 /** Per-thread status. */ 134 ThreadStatus fetchStatus[Impl::MaxThreads]; 135 136 /** Fetch policy. */ 137 FetchPriority fetchPolicy; 138 139 /** List that has the threads organized by priority. */ 140 std::list<unsigned> priorityList; 141 142 public: 143 /** DefaultFetch constructor. */ 144 DefaultFetch(Params *params); 145 146 /** Returns the name of fetch. */ 147 std::string name() const; 148 149 /** Registers statistics. */ 150 void regStats(); 151 152 /** Sets CPU pointer. */ 153 void setCPU(FullCPU *cpu_ptr); 154 155 /** Sets the main backwards communication time buffer pointer. */ 156 void setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer); 157 158 /** Sets pointer to list of active threads. */ 159 void setActiveThreads(std::list<unsigned> *at_ptr); 160 161 /** Sets pointer to time buffer used to communicate to the next stage. */ 162 void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr); 163 164 /** Sets pointer to page table. */ 165// void setPageTable(PageTable *pt_ptr); 166 167 /** Initialize stage. */ 168 void initStage(); 169 170 /** Processes cache completion event. */ 171 void processCacheCompletion(PacketPtr pkt); 172 173 void switchOut(); 174 175 void doSwitchOut(); 176 177 void takeOverFrom(); 178 179 bool isSwitchedOut() { return switchedOut; } 180 181 void wakeFromQuiesce(); 182 183 private: 184 /** Changes the status of this stage to active, and indicates this 185 * to the CPU. 186 */ 187 inline void switchToActive(); 188 189 /** Changes the status of this stage to inactive, and indicates 190 * this to the CPU. 191 */ 192 inline void switchToInactive(); 193 194 /** 195 * Looks up in the branch predictor to see if the next PC should be 196 * either next PC+=MachInst or a branch target. 197 * @param next_PC Next PC variable passed in by reference. It is 198 * expected to be set to the current PC; it will be updated with what 199 * the next PC will be. 200 * @return Whether or not a branch was predicted as taken. 201 */ 202 bool lookupAndUpdateNextPC(DynInstPtr &inst, Addr &next_PC); 203 204 /** 205 * Fetches the cache line that contains fetch_PC. Returns any 206 * fault that happened. Puts the data into the class variable 207 * cacheData. 208 * @param fetch_PC The PC address that is being fetched from. 209 * @param ret_fault The fault reference that will be set to the result of 210 * the icache access. 211 * @param tid Thread id. 212 * @return Any fault that occured. 213 */ 214 bool fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid); 215 216 /** Squashes a specific thread and resets the PC. */ 217 inline void doSquash(const Addr &new_PC, unsigned tid); 218 219 /** Squashes a specific thread and resets the PC. Also tells the CPU to 220 * remove any instructions between fetch and decode that should be sqaushed. 221 */ 222 void squashFromDecode(const Addr &new_PC, const InstSeqNum &seq_num, 223 unsigned tid); 224 225 /** Checks if a thread is stalled. */ 226 bool checkStall(unsigned tid) const; 227 228 /** Updates overall fetch stage status; to be called at the end of each 229 * cycle. */ 230 FetchStatus updateFetchStatus(); 231 232 public: 233 /** Squashes a specific thread and resets the PC. Also tells the CPU to 234 * remove any instructions that are not in the ROB. The source of this 235 * squash should be the commit stage. 236 */ 237 void squash(const Addr &new_PC, unsigned tid); 238 239 /** Ticks the fetch stage, processing all inputs signals and fetching 240 * as many instructions as possible. 241 */ 242 void tick(); 243 244 /** Checks all input signals and updates the status as necessary. 245 * @return: Returns if the status has changed due to input signals. 246 */ 247 bool checkSignalsAndUpdate(unsigned tid); 248 249 /** Does the actual fetching of instructions and passing them on to the 250 * next stage. 251 * @param status_change fetch() sets this variable if there was a status 252 * change (ie switching to IcacheMissStall). 253 */ 254 void fetch(bool &status_change); 255 256 /** Align a PC to the start of an I-cache block. */ 257 Addr icacheBlockAlignPC(Addr addr) 258 { 259 addr = TheISA::realPCToFetchPC(addr); 260 return (addr & ~(cacheBlkMask)); 261 } 262 263 private: 264 /** Returns the appropriate thread to fetch, given the fetch policy. */ 265 int getFetchingThread(FetchPriority &fetch_priority); 266 267 /** Returns the appropriate thread to fetch using a round robin policy. */ 268 int roundRobin(); 269 270 /** Returns the appropriate thread to fetch using the IQ count policy. */ 271 int iqCount(); 272 273 /** Returns the appropriate thread to fetch using the LSQ count policy. */ 274 int lsqCount(); 275 276 /** Returns the appropriate thread to fetch using the branch count policy. */ 277 int branchCount(); 278 279 private: 280 /** Pointer to the FullCPU. */ 281 FullCPU *cpu; 282 283 /** Time buffer interface. */ 284 TimeBuffer<TimeStruct> *timeBuffer; 285 286 /** Wire to get decode's information from backwards time buffer. */ 287 typename TimeBuffer<TimeStruct>::wire fromDecode; 288 289 /** Wire to get rename's information from backwards time buffer. */ 290 typename TimeBuffer<TimeStruct>::wire fromRename; 291 292 /** Wire to get iew's information from backwards time buffer. */ 293 typename TimeBuffer<TimeStruct>::wire fromIEW; 294 295 /** Wire to get commit's information from backwards time buffer. */ 296 typename TimeBuffer<TimeStruct>::wire fromCommit; 297 298 /** Internal fetch instruction queue. */ 299 TimeBuffer<FetchStruct> *fetchQueue; 300 301 //Might be annoying how this name is different than the queue. 302 /** Wire used to write any information heading to decode. */ 303 typename TimeBuffer<FetchStruct>::wire toDecode; 304 305 MemObject *mem; 306 307 /** Icache interface. */ 308 IcachePort *icachePort; 309 310 /** BPredUnit. */ 311 BPredUnit branchPred; 312 313 Addr PC[Impl::MaxThreads]; 314 315 Addr nextPC[Impl::MaxThreads]; 316 317 /** Memory packet used to access cache. */ 318 PacketPtr memPkt[Impl::MaxThreads]; 319 320 /** Variable that tracks if fetch has written to the time buffer this 321 * cycle. Used to tell CPU if there is activity this cycle. 322 */ 323 bool wroteToTimeBuffer; 324 325 /** Tracks how many instructions has been fetched this cycle. */ 326 int numInst; 327 328 /** Source of possible stalls. */ 329 struct Stalls { 330 bool decode; 331 bool rename; 332 bool iew; 333 bool commit; 334 }; 335 336 /** Tracks which stages are telling fetch to stall. */ 337 Stalls stalls[Impl::MaxThreads]; 338 339 /** Decode to fetch delay, in ticks. */ 340 unsigned decodeToFetchDelay; 341 342 /** Rename to fetch delay, in ticks. */ 343 unsigned renameToFetchDelay; 344 345 /** IEW to fetch delay, in ticks. */ 346 unsigned iewToFetchDelay; 347 348 /** Commit to fetch delay, in ticks. */ 349 unsigned commitToFetchDelay; 350 351 /** The width of fetch in instructions. */ 352 unsigned fetchWidth; 353 354 /** Cache block size. */ 355 int cacheBlkSize; 356 357 /** Mask to get a cache block's address. */ 358 Addr cacheBlkMask; 359 360 /** The cache line being fetched. */ 361 uint8_t *cacheData[Impl::MaxThreads]; 362 363 /** Size of instructions. */ 364 int instSize; 365 366 /** Icache stall statistics. */ 367 Counter lastIcacheStall[Impl::MaxThreads]; 368 369 /** List of Active Threads */ 370 std::list<unsigned> *activeThreads; 371 372 /** Number of threads. */ 373 unsigned numThreads; 374 375 /** Number of threads that are actively fetching. */ 376 unsigned numFetchingThreads; 377 378 /** Thread ID being fetched. */ 379 int threadFetched; 380 381 bool interruptPending; 382 383 bool switchedOut; 384 385#if !FULL_SYSTEM 386 /** Page table pointer. */ 387// PageTable *pTable; 388#endif 389 390 // @todo: Consider making these vectors and tracking on a per thread basis. 391 /** Stat for total number of cycles stalled due to an icache miss. */ 392 Stats::Scalar<> icacheStallCycles; 393 /** Stat for total number of fetched instructions. */ 394 Stats::Scalar<> fetchedInsts; 395 Stats::Scalar<> fetchedBranches; 396 /** Stat for total number of predicted branches. */ 397 Stats::Scalar<> predictedBranches; 398 /** Stat for total number of cycles spent fetching. */ 399 Stats::Scalar<> fetchCycles; 400 /** Stat for total number of cycles spent squashing. */ 401 Stats::Scalar<> fetchSquashCycles; 402 /** Stat for total number of cycles spent blocked due to other stages in 403 * the pipeline. 404 */ 405 Stats::Scalar<> fetchIdleCycles; 406 Stats::Scalar<> fetchBlockedCycles; 407 408 Stats::Scalar<> fetchMiscStallCycles; 409 /** Stat for total number of fetched cache lines. */ 410 Stats::Scalar<> fetchedCacheLines; 411 412 Stats::Scalar<> fetchIcacheSquashes; 413 /** Distribution of number of instructions fetched each cycle. */ 414 Stats::Distribution<> fetchNisnDist; 415 Stats::Formula idleRate; 416 Stats::Formula branchRate; 417 Stats::Formula fetchRate; 418}; 419 420#endif //__CPU_O3_FETCH_HH__ 421