fetch.hh revision 2893:58c423134221
16973Stjones1@inf.ed.ac.uk/* 27944SGiacomo.Gabrielli@arm.com * Copyright (c) 2004-2006 The Regents of The University of Michigan 37944SGiacomo.Gabrielli@arm.com * All rights reserved. 47944SGiacomo.Gabrielli@arm.com * 57944SGiacomo.Gabrielli@arm.com * Redistribution and use in source and binary forms, with or without 67944SGiacomo.Gabrielli@arm.com * modification, are permitted provided that the following conditions are 77944SGiacomo.Gabrielli@arm.com * met: redistributions of source code must retain the above copyright 87944SGiacomo.Gabrielli@arm.com * notice, this list of conditions and the following disclaimer; 97944SGiacomo.Gabrielli@arm.com * redistributions in binary form must reproduce the above copyright 107944SGiacomo.Gabrielli@arm.com * notice, this list of conditions and the following disclaimer in the 117944SGiacomo.Gabrielli@arm.com * documentation and/or other materials provided with the distribution; 127944SGiacomo.Gabrielli@arm.com * neither the name of the copyright holders nor the names of its 137944SGiacomo.Gabrielli@arm.com * contributors may be used to endorse or promote products derived from 146973Stjones1@inf.ed.ac.uk * this software without specific prior written permission. 156973Stjones1@inf.ed.ac.uk * 166973Stjones1@inf.ed.ac.uk * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176973Stjones1@inf.ed.ac.uk * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186973Stjones1@inf.ed.ac.uk * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196973Stjones1@inf.ed.ac.uk * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206973Stjones1@inf.ed.ac.uk * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216973Stjones1@inf.ed.ac.uk * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226973Stjones1@inf.ed.ac.uk * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236973Stjones1@inf.ed.ac.uk * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246973Stjones1@inf.ed.ac.uk * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256973Stjones1@inf.ed.ac.uk * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266973Stjones1@inf.ed.ac.uk * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276973Stjones1@inf.ed.ac.uk * 286973Stjones1@inf.ed.ac.uk * Authors: Kevin Lim 296973Stjones1@inf.ed.ac.uk * Korey Sewell 306973Stjones1@inf.ed.ac.uk */ 316973Stjones1@inf.ed.ac.uk 326973Stjones1@inf.ed.ac.uk#ifndef __CPU_O3_FETCH_HH__ 336973Stjones1@inf.ed.ac.uk#define __CPU_O3_FETCH_HH__ 346973Stjones1@inf.ed.ac.uk 356973Stjones1@inf.ed.ac.uk#include "arch/utility.hh" 366973Stjones1@inf.ed.ac.uk#include "base/statistics.hh" 376973Stjones1@inf.ed.ac.uk#include "base/timebuf.hh" 386973Stjones1@inf.ed.ac.uk#include "cpu/pc_event.hh" 396973Stjones1@inf.ed.ac.uk#include "mem/packet_impl.hh" 406973Stjones1@inf.ed.ac.uk#include "mem/port.hh" 416973Stjones1@inf.ed.ac.uk#include "sim/eventq.hh" 426973Stjones1@inf.ed.ac.uk 436973Stjones1@inf.ed.ac.uk/** 446973Stjones1@inf.ed.ac.uk * DefaultFetch class handles both single threaded and SMT fetch. Its 456973Stjones1@inf.ed.ac.uk * width is specified by the parameters; each cycle it tries to fetch 466973Stjones1@inf.ed.ac.uk * that many instructions. It supports using a branch predictor to 476973Stjones1@inf.ed.ac.uk * predict direction and targets. 487678Sgblack@eecs.umich.edu * It supports the idling functionality of the CPU by indicating to 496973Stjones1@inf.ed.ac.uk * the CPU when it is active and inactive. 506973Stjones1@inf.ed.ac.uk */ 517049Stjones1@inf.ed.ac.uktemplate <class Impl> 527049Stjones1@inf.ed.ac.ukclass DefaultFetch 537049Stjones1@inf.ed.ac.uk{ 547049Stjones1@inf.ed.ac.uk public: 557049Stjones1@inf.ed.ac.uk /** Typedefs from Impl. */ 567049Stjones1@inf.ed.ac.uk typedef typename Impl::CPUPol CPUPol; 577049Stjones1@inf.ed.ac.uk typedef typename Impl::DynInst DynInst; 587049Stjones1@inf.ed.ac.uk typedef typename Impl::DynInstPtr DynInstPtr; 597049Stjones1@inf.ed.ac.uk typedef typename Impl::O3CPU O3CPU; 607049Stjones1@inf.ed.ac.uk typedef typename Impl::Params Params; 616973Stjones1@inf.ed.ac.uk 626973Stjones1@inf.ed.ac.uk /** Typedefs from the CPU policy. */ 636973Stjones1@inf.ed.ac.uk typedef typename CPUPol::BPredUnit BPredUnit; 646973Stjones1@inf.ed.ac.uk typedef typename CPUPol::FetchStruct FetchStruct; 656973Stjones1@inf.ed.ac.uk typedef typename CPUPol::TimeStruct TimeStruct; 666973Stjones1@inf.ed.ac.uk 676973Stjones1@inf.ed.ac.uk /** Typedefs from ISA. */ 687944SGiacomo.Gabrielli@arm.com typedef TheISA::MachInst MachInst; 696973Stjones1@inf.ed.ac.uk typedef TheISA::ExtMachInst ExtMachInst; 706973Stjones1@inf.ed.ac.uk 716973Stjones1@inf.ed.ac.uk /** IcachePort class for DefaultFetch. Handles doing the 726973Stjones1@inf.ed.ac.uk * communication with the cache/memory. 736973Stjones1@inf.ed.ac.uk */ 746973Stjones1@inf.ed.ac.uk class IcachePort : public Port 756973Stjones1@inf.ed.ac.uk { 766973Stjones1@inf.ed.ac.uk protected: 777049Stjones1@inf.ed.ac.uk /** Pointer to fetch. */ 787049Stjones1@inf.ed.ac.uk DefaultFetch<Impl> *fetch; 797049Stjones1@inf.ed.ac.uk 807049Stjones1@inf.ed.ac.uk public: 816973Stjones1@inf.ed.ac.uk /** Default constructor. */ 826973Stjones1@inf.ed.ac.uk IcachePort(DefaultFetch<Impl> *_fetch) 837944SGiacomo.Gabrielli@arm.com : Port(_fetch->name() + "-iport"), fetch(_fetch) 847944SGiacomo.Gabrielli@arm.com { } 856973Stjones1@inf.ed.ac.uk 866973Stjones1@inf.ed.ac.uk protected: 876973Stjones1@inf.ed.ac.uk /** Atomic version of receive. Panics. */ 886973Stjones1@inf.ed.ac.uk virtual Tick recvAtomic(PacketPtr pkt); 896973Stjones1@inf.ed.ac.uk 907049Stjones1@inf.ed.ac.uk /** Functional version of receive. Panics. */ 917049Stjones1@inf.ed.ac.uk virtual void recvFunctional(PacketPtr pkt); 927049Stjones1@inf.ed.ac.uk 937049Stjones1@inf.ed.ac.uk /** Receives status change. Other than range changing, panics. */ 947049Stjones1@inf.ed.ac.uk virtual void recvStatusChange(Status status); 956973Stjones1@inf.ed.ac.uk 966973Stjones1@inf.ed.ac.uk /** Returns the address ranges of this device. */ 976973Stjones1@inf.ed.ac.uk virtual void getDeviceAddressRanges(AddrRangeList &resp, 987944SGiacomo.Gabrielli@arm.com AddrRangeList &snoop) 997944SGiacomo.Gabrielli@arm.com { resp.clear(); snoop.clear(); } 1007944SGiacomo.Gabrielli@arm.com 1016973Stjones1@inf.ed.ac.uk /** Timing version of receive. Handles setting fetch to the 1026973Stjones1@inf.ed.ac.uk * proper status to start fetching. */ 1036973Stjones1@inf.ed.ac.uk virtual bool recvTiming(PacketPtr pkt); 1046973Stjones1@inf.ed.ac.uk 1056973Stjones1@inf.ed.ac.uk /** Handles doing a retry of a failed fetch. */ 1067049Stjones1@inf.ed.ac.uk virtual void recvRetry(); 1077049Stjones1@inf.ed.ac.uk }; 1087049Stjones1@inf.ed.ac.uk 1097049Stjones1@inf.ed.ac.uk public: 1107049Stjones1@inf.ed.ac.uk /** Overall fetch status. Used to determine if the CPU can 1117049Stjones1@inf.ed.ac.uk * deschedule itsef due to a lack of activity. 1127049Stjones1@inf.ed.ac.uk */ 1136973Stjones1@inf.ed.ac.uk enum FetchStatus { 1146973Stjones1@inf.ed.ac.uk Active, 1156973Stjones1@inf.ed.ac.uk Inactive 1166973Stjones1@inf.ed.ac.uk }; 1176973Stjones1@inf.ed.ac.uk 1186973Stjones1@inf.ed.ac.uk /** Individual thread status. */ 1196973Stjones1@inf.ed.ac.uk enum ThreadStatus { 1206973Stjones1@inf.ed.ac.uk Running, 1216973Stjones1@inf.ed.ac.uk Idle, 1226973Stjones1@inf.ed.ac.uk Squashing, 1236973Stjones1@inf.ed.ac.uk Blocked, 1246973Stjones1@inf.ed.ac.uk Fetching, 1256973Stjones1@inf.ed.ac.uk TrapPending, 1266973Stjones1@inf.ed.ac.uk QuiescePending, 1276973Stjones1@inf.ed.ac.uk SwitchOut, 1286973Stjones1@inf.ed.ac.uk IcacheWaitResponse, 1296973Stjones1@inf.ed.ac.uk IcacheWaitRetry, 1306973Stjones1@inf.ed.ac.uk IcacheAccessComplete 1317049Stjones1@inf.ed.ac.uk }; 1327049Stjones1@inf.ed.ac.uk 1337049Stjones1@inf.ed.ac.uk /** Fetching Policy, Add new policies here.*/ 1347049Stjones1@inf.ed.ac.uk enum FetchPriority { 1356973Stjones1@inf.ed.ac.uk SingleThread, 1366973Stjones1@inf.ed.ac.uk RoundRobin, 1376973Stjones1@inf.ed.ac.uk Branch, 1386973Stjones1@inf.ed.ac.uk IQ, 1396973Stjones1@inf.ed.ac.uk LSQ 1406973Stjones1@inf.ed.ac.uk }; 1416973Stjones1@inf.ed.ac.uk 1426973Stjones1@inf.ed.ac.uk private: 1436973Stjones1@inf.ed.ac.uk /** Fetch status. */ 1446973Stjones1@inf.ed.ac.uk FetchStatus _status; 1456973Stjones1@inf.ed.ac.uk 1466973Stjones1@inf.ed.ac.uk /** Per-thread status. */ 1476973Stjones1@inf.ed.ac.uk ThreadStatus fetchStatus[Impl::MaxThreads]; 1487049Stjones1@inf.ed.ac.uk 1496973Stjones1@inf.ed.ac.uk /** Fetch policy. */ 1506973Stjones1@inf.ed.ac.uk FetchPriority fetchPolicy; 1516973Stjones1@inf.ed.ac.uk 1526973Stjones1@inf.ed.ac.uk /** List that has the threads organized by priority. */ 1536973Stjones1@inf.ed.ac.uk std::list<unsigned> priorityList; 1546973Stjones1@inf.ed.ac.uk 1557049Stjones1@inf.ed.ac.uk public: 1567049Stjones1@inf.ed.ac.uk /** DefaultFetch constructor. */ 1577049Stjones1@inf.ed.ac.uk DefaultFetch(Params *params); 1587049Stjones1@inf.ed.ac.uk 1597049Stjones1@inf.ed.ac.uk /** Returns the name of fetch. */ 1606973Stjones1@inf.ed.ac.uk std::string name() const; 1616973Stjones1@inf.ed.ac.uk 1626973Stjones1@inf.ed.ac.uk /** Registers statistics. */ 1636973Stjones1@inf.ed.ac.uk void regStats(); 1646973Stjones1@inf.ed.ac.uk 1656973Stjones1@inf.ed.ac.uk /** Returns the icache port. */ 1667049Stjones1@inf.ed.ac.uk Port *getIcachePort() { return icachePort; } 1677049Stjones1@inf.ed.ac.uk 1687049Stjones1@inf.ed.ac.uk /** Sets CPU pointer. */ 1697049Stjones1@inf.ed.ac.uk void setCPU(O3CPU *cpu_ptr); 1707049Stjones1@inf.ed.ac.uk 1716973Stjones1@inf.ed.ac.uk /** Sets the main backwards communication time buffer pointer. */ 1726973Stjones1@inf.ed.ac.uk void setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer); 1736973Stjones1@inf.ed.ac.uk 1746973Stjones1@inf.ed.ac.uk /** Sets pointer to list of active threads. */ 1756973Stjones1@inf.ed.ac.uk void setActiveThreads(std::list<unsigned> *at_ptr); 1766973Stjones1@inf.ed.ac.uk 1777049Stjones1@inf.ed.ac.uk /** Sets pointer to time buffer used to communicate to the next stage. */ 1786973Stjones1@inf.ed.ac.uk void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr); 1796973Stjones1@inf.ed.ac.uk 1806973Stjones1@inf.ed.ac.uk /** Initialize stage. */ 1816973Stjones1@inf.ed.ac.uk void initStage(); 1826973Stjones1@inf.ed.ac.uk 1836973Stjones1@inf.ed.ac.uk /** Processes cache completion event. */ 1847049Stjones1@inf.ed.ac.uk void processCacheCompletion(PacketPtr pkt); 1857049Stjones1@inf.ed.ac.uk 1867049Stjones1@inf.ed.ac.uk /** Begins the drain of the fetch stage. */ 1877049Stjones1@inf.ed.ac.uk bool drain(); 1887049Stjones1@inf.ed.ac.uk 1896973Stjones1@inf.ed.ac.uk /** Resumes execution after a drain. */ 1906973Stjones1@inf.ed.ac.uk void resume(); 1916973Stjones1@inf.ed.ac.uk 1926973Stjones1@inf.ed.ac.uk /** Tells fetch stage to prepare to be switched out. */ 1936973Stjones1@inf.ed.ac.uk void switchOut(); 1946973Stjones1@inf.ed.ac.uk 1957049Stjones1@inf.ed.ac.uk /** Takes over from another CPU's thread. */ 1966973Stjones1@inf.ed.ac.uk void takeOverFrom(); 1976973Stjones1@inf.ed.ac.uk 1986973Stjones1@inf.ed.ac.uk /** Checks if the fetch stage is switched out. */ 1996973Stjones1@inf.ed.ac.uk bool isSwitchedOut() { return switchedOut; } 2006973Stjones1@inf.ed.ac.uk 2016973Stjones1@inf.ed.ac.uk /** Tells fetch to wake up from a quiesce instruction. */ 2026973Stjones1@inf.ed.ac.uk void wakeFromQuiesce(); 2036973Stjones1@inf.ed.ac.uk 2046973Stjones1@inf.ed.ac.uk private: 2056973Stjones1@inf.ed.ac.uk /** Changes the status of this stage to active, and indicates this 2066973Stjones1@inf.ed.ac.uk * to the CPU. 2077049Stjones1@inf.ed.ac.uk */ 2087049Stjones1@inf.ed.ac.uk inline void switchToActive(); 2097049Stjones1@inf.ed.ac.uk 2107049Stjones1@inf.ed.ac.uk /** Changes the status of this stage to inactive, and indicates 2117049Stjones1@inf.ed.ac.uk * this to the CPU. 2127049Stjones1@inf.ed.ac.uk */ 2137049Stjones1@inf.ed.ac.uk inline void switchToInactive(); 2147049Stjones1@inf.ed.ac.uk 2157049Stjones1@inf.ed.ac.uk /** 2167049Stjones1@inf.ed.ac.uk * Looks up in the branch predictor to see if the next PC should be 2178486Sgblack@eecs.umich.edu * either next PC+=MachInst or a branch target. 2186973Stjones1@inf.ed.ac.uk * @param next_PC Next PC variable passed in by reference. It is 2196973Stjones1@inf.ed.ac.uk * expected to be set to the current PC; it will be updated with what 2206973Stjones1@inf.ed.ac.uk * the next PC will be. 2218486Sgblack@eecs.umich.edu * @return Whether or not a branch was predicted as taken. 2226973Stjones1@inf.ed.ac.uk */ 2236973Stjones1@inf.ed.ac.uk bool lookupAndUpdateNextPC(DynInstPtr &inst, Addr &next_PC); 2246973Stjones1@inf.ed.ac.uk 2256973Stjones1@inf.ed.ac.uk /** 2268486Sgblack@eecs.umich.edu * Fetches the cache line that contains fetch_PC. Returns any 2276973Stjones1@inf.ed.ac.uk * fault that happened. Puts the data into the class variable 2286973Stjones1@inf.ed.ac.uk * cacheData. 2296973Stjones1@inf.ed.ac.uk * @param fetch_PC The PC address that is being fetched from. 2306973Stjones1@inf.ed.ac.uk * @param ret_fault The fault reference that will be set to the result of 2318486Sgblack@eecs.umich.edu * the icache access. 2326973Stjones1@inf.ed.ac.uk * @param tid Thread id. 2336973Stjones1@inf.ed.ac.uk * @return Any fault that occured. 2346973Stjones1@inf.ed.ac.uk */ 2356973Stjones1@inf.ed.ac.uk bool fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid); 2366973Stjones1@inf.ed.ac.uk 2377049Stjones1@inf.ed.ac.uk /** Squashes a specific thread and resets the PC. */ 2387944SGiacomo.Gabrielli@arm.com inline void doSquash(const Addr &new_PC, unsigned tid); 2397944SGiacomo.Gabrielli@arm.com 2407944SGiacomo.Gabrielli@arm.com /** Squashes a specific thread and resets the PC. Also tells the CPU to 2417944SGiacomo.Gabrielli@arm.com * remove any instructions between fetch and decode that should be sqaushed. 2427944SGiacomo.Gabrielli@arm.com */ 2437944SGiacomo.Gabrielli@arm.com void squashFromDecode(const Addr &new_PC, const InstSeqNum &seq_num, 2447944SGiacomo.Gabrielli@arm.com unsigned tid); 2457944SGiacomo.Gabrielli@arm.com 2467944SGiacomo.Gabrielli@arm.com /** Checks if a thread is stalled. */ 2477944SGiacomo.Gabrielli@arm.com bool checkStall(unsigned tid) const; 2487049Stjones1@inf.ed.ac.uk 2497049Stjones1@inf.ed.ac.uk /** Updates overall fetch stage status; to be called at the end of each 2507049Stjones1@inf.ed.ac.uk * cycle. */ 2516973Stjones1@inf.ed.ac.uk FetchStatus updateFetchStatus(); 2526973Stjones1@inf.ed.ac.uk 2536973Stjones1@inf.ed.ac.uk public: 2546973Stjones1@inf.ed.ac.uk /** Squashes a specific thread and resets the PC. Also tells the CPU to 2556973Stjones1@inf.ed.ac.uk * remove any instructions that are not in the ROB. The source of this 2566973Stjones1@inf.ed.ac.uk * squash should be the commit stage. 2576973Stjones1@inf.ed.ac.uk */ 2586973Stjones1@inf.ed.ac.uk void squash(const Addr &new_PC, unsigned tid); 2596973Stjones1@inf.ed.ac.uk 2606973Stjones1@inf.ed.ac.uk /** Ticks the fetch stage, processing all inputs signals and fetching 2616973Stjones1@inf.ed.ac.uk * as many instructions as possible. 2629258SAli.Saidi@ARM.com */ 2639258SAli.Saidi@ARM.com void tick(); 2649258SAli.Saidi@ARM.com 2659258SAli.Saidi@ARM.com /** Checks all input signals and updates the status as necessary. 2669258SAli.Saidi@ARM.com * @return: Returns if the status has changed due to input signals. 2679258SAli.Saidi@ARM.com */ 2686973Stjones1@inf.ed.ac.uk bool checkSignalsAndUpdate(unsigned tid); 2696973Stjones1@inf.ed.ac.uk 2706973Stjones1@inf.ed.ac.uk /** Does the actual fetching of instructions and passing them on to the 271 * next stage. 272 * @param status_change fetch() sets this variable if there was a status 273 * change (ie switching to IcacheMissStall). 274 */ 275 void fetch(bool &status_change); 276 277 /** Align a PC to the start of an I-cache block. */ 278 Addr icacheBlockAlignPC(Addr addr) 279 { 280 addr = TheISA::realPCToFetchPC(addr); 281 return (addr & ~(cacheBlkMask)); 282 } 283 284 private: 285 /** Handles retrying the fetch access. */ 286 void recvRetry(); 287 288 /** Returns the appropriate thread to fetch, given the fetch policy. */ 289 int getFetchingThread(FetchPriority &fetch_priority); 290 291 /** Returns the appropriate thread to fetch using a round robin policy. */ 292 int roundRobin(); 293 294 /** Returns the appropriate thread to fetch using the IQ count policy. */ 295 int iqCount(); 296 297 /** Returns the appropriate thread to fetch using the LSQ count policy. */ 298 int lsqCount(); 299 300 /** Returns the appropriate thread to fetch using the branch count policy. */ 301 int branchCount(); 302 303 private: 304 /** Pointer to the O3CPU. */ 305 O3CPU *cpu; 306 307 /** Time buffer interface. */ 308 TimeBuffer<TimeStruct> *timeBuffer; 309 310 /** Wire to get decode's information from backwards time buffer. */ 311 typename TimeBuffer<TimeStruct>::wire fromDecode; 312 313 /** Wire to get rename's information from backwards time buffer. */ 314 typename TimeBuffer<TimeStruct>::wire fromRename; 315 316 /** Wire to get iew's information from backwards time buffer. */ 317 typename TimeBuffer<TimeStruct>::wire fromIEW; 318 319 /** Wire to get commit's information from backwards time buffer. */ 320 typename TimeBuffer<TimeStruct>::wire fromCommit; 321 322 /** Internal fetch instruction queue. */ 323 TimeBuffer<FetchStruct> *fetchQueue; 324 325 //Might be annoying how this name is different than the queue. 326 /** Wire used to write any information heading to decode. */ 327 typename TimeBuffer<FetchStruct>::wire toDecode; 328 329 MemObject *mem; 330 331 /** Icache interface. */ 332 IcachePort *icachePort; 333 334 /** BPredUnit. */ 335 BPredUnit branchPred; 336 337 /** Per-thread fetch PC. */ 338 Addr PC[Impl::MaxThreads]; 339 340 /** Per-thread next PC. */ 341 Addr nextPC[Impl::MaxThreads]; 342 343#if THE_ISA != ALPHA_ISA 344 /** Per-thread next Next PC. 345 * This is not a real register but is used for 346 * architectures that use a branch-delay slot. 347 * (such as MIPS or Sparc) 348 */ 349 Addr nextNPC[Impl::MaxThreads]; 350#endif 351 352 /** Memory request used to access cache. */ 353 RequestPtr memReq[Impl::MaxThreads]; 354 355 /** Variable that tracks if fetch has written to the time buffer this 356 * cycle. Used to tell CPU if there is activity this cycle. 357 */ 358 bool wroteToTimeBuffer; 359 360 /** Tracks how many instructions has been fetched this cycle. */ 361 int numInst; 362 363 /** Source of possible stalls. */ 364 struct Stalls { 365 bool decode; 366 bool rename; 367 bool iew; 368 bool commit; 369 }; 370 371 /** Tracks which stages are telling fetch to stall. */ 372 Stalls stalls[Impl::MaxThreads]; 373 374 /** Decode to fetch delay, in ticks. */ 375 unsigned decodeToFetchDelay; 376 377 /** Rename to fetch delay, in ticks. */ 378 unsigned renameToFetchDelay; 379 380 /** IEW to fetch delay, in ticks. */ 381 unsigned iewToFetchDelay; 382 383 /** Commit to fetch delay, in ticks. */ 384 unsigned commitToFetchDelay; 385 386 /** The width of fetch in instructions. */ 387 unsigned fetchWidth; 388 389 /** Is the cache blocked? If so no threads can access it. */ 390 bool cacheBlocked; 391 392 /** The packet that is waiting to be retried. */ 393 PacketPtr retryPkt; 394 395 /** The thread that is waiting on the cache to tell fetch to retry. */ 396 int retryTid; 397 398 /** Cache block size. */ 399 int cacheBlkSize; 400 401 /** Mask to get a cache block's address. */ 402 Addr cacheBlkMask; 403 404 /** The cache line being fetched. */ 405 uint8_t *cacheData[Impl::MaxThreads]; 406 407 /** The PC of the cacheline that has been loaded. */ 408 Addr cacheDataPC[Impl::MaxThreads]; 409 410 /** Size of instructions. */ 411 int instSize; 412 413 /** Icache stall statistics. */ 414 Counter lastIcacheStall[Impl::MaxThreads]; 415 416 /** List of Active Threads */ 417 std::list<unsigned> *activeThreads; 418 419 /** Number of threads. */ 420 unsigned numThreads; 421 422 /** Number of threads that are actively fetching. */ 423 unsigned numFetchingThreads; 424 425 /** Thread ID being fetched. */ 426 int threadFetched; 427 428 /** Checks if there is an interrupt pending. If there is, fetch 429 * must stop once it is not fetching PAL instructions. 430 */ 431 bool interruptPending; 432 433 /** Is there a drain pending. */ 434 bool drainPending; 435 436 /** Records if fetch is switched out. */ 437 bool switchedOut; 438 439 // @todo: Consider making these vectors and tracking on a per thread basis. 440 /** Stat for total number of cycles stalled due to an icache miss. */ 441 Stats::Scalar<> icacheStallCycles; 442 /** Stat for total number of fetched instructions. */ 443 Stats::Scalar<> fetchedInsts; 444 /** Total number of fetched branches. */ 445 Stats::Scalar<> fetchedBranches; 446 /** Stat for total number of predicted branches. */ 447 Stats::Scalar<> predictedBranches; 448 /** Stat for total number of cycles spent fetching. */ 449 Stats::Scalar<> fetchCycles; 450 /** Stat for total number of cycles spent squashing. */ 451 Stats::Scalar<> fetchSquashCycles; 452 /** Stat for total number of cycles spent blocked due to other stages in 453 * the pipeline. 454 */ 455 Stats::Scalar<> fetchIdleCycles; 456 /** Total number of cycles spent blocked. */ 457 Stats::Scalar<> fetchBlockedCycles; 458 /** Total number of cycles spent in any other state. */ 459 Stats::Scalar<> fetchMiscStallCycles; 460 /** Stat for total number of fetched cache lines. */ 461 Stats::Scalar<> fetchedCacheLines; 462 /** Total number of outstanding icache accesses that were dropped 463 * due to a squash. 464 */ 465 Stats::Scalar<> fetchIcacheSquashes; 466 /** Distribution of number of instructions fetched each cycle. */ 467 Stats::Distribution<> fetchNisnDist; 468 /** Rate of how often fetch was idle. */ 469 Stats::Formula idleRate; 470 /** Number of branch fetches per cycle. */ 471 Stats::Formula branchRate; 472 /** Number of instruction fetched per cycle. */ 473 Stats::Formula fetchRate; 474}; 475 476#endif //__CPU_O3_FETCH_HH__ 477