fetch.hh revision 2863
11689SN/A/* 22329SN/A * Copyright (c) 2004-2006 The Regents of The University of Michigan 31689SN/A * All rights reserved. 41689SN/A * 51689SN/A * Redistribution and use in source and binary forms, with or without 61689SN/A * modification, are permitted provided that the following conditions are 71689SN/A * met: redistributions of source code must retain the above copyright 81689SN/A * notice, this list of conditions and the following disclaimer; 91689SN/A * redistributions in binary form must reproduce the above copyright 101689SN/A * notice, this list of conditions and the following disclaimer in the 111689SN/A * documentation and/or other materials provided with the distribution; 121689SN/A * neither the name of the copyright holders nor the names of its 131689SN/A * contributors may be used to endorse or promote products derived from 141689SN/A * this software without specific prior written permission. 151689SN/A * 161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Kevin Lim 292756Sksewell@umich.edu * Korey Sewell 301689SN/A */ 311689SN/A 322292SN/A#ifndef __CPU_O3_FETCH_HH__ 332292SN/A#define __CPU_O3_FETCH_HH__ 341060SN/A 352669Sktlim@umich.edu#include "arch/utility.hh" 361461SN/A#include "base/statistics.hh" 371060SN/A#include "base/timebuf.hh" 381060SN/A#include "cpu/pc_event.hh" 392808Ssaidi@eecs.umich.edu#include "mem/packet_impl.hh" 402669Sktlim@umich.edu#include "mem/port.hh" 411461SN/A#include "sim/eventq.hh" 421060SN/A 431060SN/A/** 442329SN/A * DefaultFetch class handles both single threaded and SMT fetch. Its 452329SN/A * width is specified by the parameters; each cycle it tries to fetch 462329SN/A * that many instructions. It supports using a branch predictor to 472329SN/A * predict direction and targets. 482348SN/A * It supports the idling functionality of the CPU by indicating to 492329SN/A * the CPU when it is active and inactive. 501060SN/A */ 511060SN/Atemplate <class Impl> 522292SN/Aclass DefaultFetch 531060SN/A{ 541060SN/A public: 551060SN/A /** Typedefs from Impl. */ 561061SN/A typedef typename Impl::CPUPol CPUPol; 571060SN/A typedef typename Impl::DynInst DynInst; 581061SN/A typedef typename Impl::DynInstPtr DynInstPtr; 592733Sktlim@umich.edu typedef typename Impl::O3CPU O3CPU; 601060SN/A typedef typename Impl::Params Params; 611060SN/A 622292SN/A /** Typedefs from the CPU policy. */ 631061SN/A typedef typename CPUPol::BPredUnit BPredUnit; 641061SN/A typedef typename CPUPol::FetchStruct FetchStruct; 651061SN/A typedef typename CPUPol::TimeStruct TimeStruct; 661060SN/A 671060SN/A /** Typedefs from ISA. */ 682107SN/A typedef TheISA::MachInst MachInst; 692292SN/A typedef TheISA::ExtMachInst ExtMachInst; 702632Sstever@eecs.umich.edu 712698Sktlim@umich.edu /** IcachePort class for DefaultFetch. Handles doing the 722698Sktlim@umich.edu * communication with the cache/memory. 732698Sktlim@umich.edu */ 742669Sktlim@umich.edu class IcachePort : public Port 752669Sktlim@umich.edu { 762669Sktlim@umich.edu protected: 772698Sktlim@umich.edu /** Pointer to fetch. */ 782669Sktlim@umich.edu DefaultFetch<Impl> *fetch; 792669Sktlim@umich.edu 802669Sktlim@umich.edu public: 812698Sktlim@umich.edu /** Default constructor. */ 822669Sktlim@umich.edu IcachePort(DefaultFetch<Impl> *_fetch) 832669Sktlim@umich.edu : Port(_fetch->name() + "-iport"), fetch(_fetch) 842669Sktlim@umich.edu { } 852669Sktlim@umich.edu 862669Sktlim@umich.edu protected: 872698Sktlim@umich.edu /** Atomic version of receive. Panics. */ 882669Sktlim@umich.edu virtual Tick recvAtomic(PacketPtr pkt); 892669Sktlim@umich.edu 902698Sktlim@umich.edu /** Functional version of receive. Panics. */ 912669Sktlim@umich.edu virtual void recvFunctional(PacketPtr pkt); 922669Sktlim@umich.edu 932698Sktlim@umich.edu /** Receives status change. Other than range changing, panics. */ 942669Sktlim@umich.edu virtual void recvStatusChange(Status status); 952669Sktlim@umich.edu 962698Sktlim@umich.edu /** Returns the address ranges of this device. */ 972669Sktlim@umich.edu virtual void getDeviceAddressRanges(AddrRangeList &resp, 982669Sktlim@umich.edu AddrRangeList &snoop) 992669Sktlim@umich.edu { resp.clear(); snoop.clear(); } 1002669Sktlim@umich.edu 1012698Sktlim@umich.edu /** Timing version of receive. Handles setting fetch to the 1022698Sktlim@umich.edu * proper status to start fetching. */ 1032669Sktlim@umich.edu virtual bool recvTiming(PacketPtr pkt); 1042669Sktlim@umich.edu 1052698Sktlim@umich.edu /** Handles doing a retry of a failed fetch. */ 1062669Sktlim@umich.edu virtual void recvRetry(); 1072669Sktlim@umich.edu }; 1081060SN/A 1091060SN/A public: 1102329SN/A /** Overall fetch status. Used to determine if the CPU can 1112329SN/A * deschedule itsef due to a lack of activity. 1122292SN/A */ 1132292SN/A enum FetchStatus { 1142292SN/A Active, 1152292SN/A Inactive 1162292SN/A }; 1172292SN/A 1182292SN/A /** Individual thread status. */ 1192292SN/A enum ThreadStatus { 1201060SN/A Running, 1211060SN/A Idle, 1221060SN/A Squashing, 1231060SN/A Blocked, 1242292SN/A Fetching, 1252292SN/A TrapPending, 1262292SN/A QuiescePending, 1272307SN/A SwitchOut, 1282669Sktlim@umich.edu IcacheWaitResponse, 1292696Sktlim@umich.edu IcacheWaitRetry, 1302669Sktlim@umich.edu IcacheAccessComplete 1311060SN/A }; 1321060SN/A 1332292SN/A /** Fetching Policy, Add new policies here.*/ 1342292SN/A enum FetchPriority { 1352292SN/A SingleThread, 1362292SN/A RoundRobin, 1372292SN/A Branch, 1382292SN/A IQ, 1392292SN/A LSQ 1402292SN/A }; 1411060SN/A 1422292SN/A private: 1432292SN/A /** Fetch status. */ 1442292SN/A FetchStatus _status; 1452292SN/A 1462292SN/A /** Per-thread status. */ 1472292SN/A ThreadStatus fetchStatus[Impl::MaxThreads]; 1482292SN/A 1492292SN/A /** Fetch policy. */ 1502292SN/A FetchPriority fetchPolicy; 1512292SN/A 1522292SN/A /** List that has the threads organized by priority. */ 1532292SN/A std::list<unsigned> priorityList; 1541060SN/A 1551060SN/A public: 1562292SN/A /** DefaultFetch constructor. */ 1572292SN/A DefaultFetch(Params *params); 1581684SN/A 1592292SN/A /** Returns the name of fetch. */ 1602292SN/A std::string name() const; 1611684SN/A 1622292SN/A /** Registers statistics. */ 1631062SN/A void regStats(); 1641062SN/A 1652292SN/A /** Sets CPU pointer. */ 1662733Sktlim@umich.edu void setCPU(O3CPU *cpu_ptr); 1671060SN/A 1682292SN/A /** Sets the main backwards communication time buffer pointer. */ 1691060SN/A void setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer); 1701060SN/A 1712292SN/A /** Sets pointer to list of active threads. */ 1722292SN/A void setActiveThreads(std::list<unsigned> *at_ptr); 1732292SN/A 1742292SN/A /** Sets pointer to time buffer used to communicate to the next stage. */ 1751060SN/A void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr); 1761060SN/A 1772292SN/A /** Initialize stage. */ 1782292SN/A void initStage(); 1792292SN/A 1802292SN/A /** Processes cache completion event. */ 1812669Sktlim@umich.edu void processCacheCompletion(PacketPtr pkt); 1822292SN/A 1832843Sktlim@umich.edu /** Begins the drain of the fetch stage. */ 1842863Sktlim@umich.edu bool drain(); 1852843Sktlim@umich.edu 1862843Sktlim@umich.edu /** Resumes execution after a drain. */ 1872843Sktlim@umich.edu void resume(); 1882843Sktlim@umich.edu 1892843Sktlim@umich.edu /** Tells fetch stage to prepare to be switched out. */ 1902307SN/A void switchOut(); 1912307SN/A 1922348SN/A /** Takes over from another CPU's thread. */ 1932307SN/A void takeOverFrom(); 1942307SN/A 1952348SN/A /** Checks if the fetch stage is switched out. */ 1962307SN/A bool isSwitchedOut() { return switchedOut; } 1972307SN/A 1982348SN/A /** Tells fetch to wake up from a quiesce instruction. */ 1992292SN/A void wakeFromQuiesce(); 2001060SN/A 2011061SN/A private: 2022329SN/A /** Changes the status of this stage to active, and indicates this 2032329SN/A * to the CPU. 2042292SN/A */ 2052292SN/A inline void switchToActive(); 2062292SN/A 2072329SN/A /** Changes the status of this stage to inactive, and indicates 2082329SN/A * this to the CPU. 2092292SN/A */ 2102292SN/A inline void switchToInactive(); 2112292SN/A 2121061SN/A /** 2131061SN/A * Looks up in the branch predictor to see if the next PC should be 2141061SN/A * either next PC+=MachInst or a branch target. 2151763SN/A * @param next_PC Next PC variable passed in by reference. It is 2161061SN/A * expected to be set to the current PC; it will be updated with what 2171061SN/A * the next PC will be. 2181061SN/A * @return Whether or not a branch was predicted as taken. 2191061SN/A */ 2201062SN/A bool lookupAndUpdateNextPC(DynInstPtr &inst, Addr &next_PC); 2211062SN/A 2221062SN/A /** 2231062SN/A * Fetches the cache line that contains fetch_PC. Returns any 2241062SN/A * fault that happened. Puts the data into the class variable 2251062SN/A * cacheData. 2261763SN/A * @param fetch_PC The PC address that is being fetched from. 2272292SN/A * @param ret_fault The fault reference that will be set to the result of 2282292SN/A * the icache access. 2292292SN/A * @param tid Thread id. 2301062SN/A * @return Any fault that occured. 2311062SN/A */ 2322292SN/A bool fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid); 2331062SN/A 2342292SN/A /** Squashes a specific thread and resets the PC. */ 2352292SN/A inline void doSquash(const Addr &new_PC, unsigned tid); 2361684SN/A 2372292SN/A /** Squashes a specific thread and resets the PC. Also tells the CPU to 2382292SN/A * remove any instructions between fetch and decode that should be sqaushed. 2392292SN/A */ 2402292SN/A void squashFromDecode(const Addr &new_PC, const InstSeqNum &seq_num, 2412292SN/A unsigned tid); 2422292SN/A 2432292SN/A /** Checks if a thread is stalled. */ 2442292SN/A bool checkStall(unsigned tid) const; 2452292SN/A 2462292SN/A /** Updates overall fetch stage status; to be called at the end of each 2472292SN/A * cycle. */ 2482292SN/A FetchStatus updateFetchStatus(); 2491684SN/A 2501684SN/A public: 2512292SN/A /** Squashes a specific thread and resets the PC. Also tells the CPU to 2522292SN/A * remove any instructions that are not in the ROB. The source of this 2532292SN/A * squash should be the commit stage. 2542292SN/A */ 2552292SN/A void squash(const Addr &new_PC, unsigned tid); 2561684SN/A 2572292SN/A /** Ticks the fetch stage, processing all inputs signals and fetching 2582292SN/A * as many instructions as possible. 2592292SN/A */ 2601684SN/A void tick(); 2611684SN/A 2622292SN/A /** Checks all input signals and updates the status as necessary. 2632292SN/A * @return: Returns if the status has changed due to input signals. 2642292SN/A */ 2652292SN/A bool checkSignalsAndUpdate(unsigned tid); 2661684SN/A 2672292SN/A /** Does the actual fetching of instructions and passing them on to the 2682292SN/A * next stage. 2692292SN/A * @param status_change fetch() sets this variable if there was a status 2702292SN/A * change (ie switching to IcacheMissStall). 2712292SN/A */ 2722292SN/A void fetch(bool &status_change); 2732292SN/A 2742292SN/A /** Align a PC to the start of an I-cache block. */ 2751062SN/A Addr icacheBlockAlignPC(Addr addr) 2761062SN/A { 2772107SN/A addr = TheISA::realPCToFetchPC(addr); 2781062SN/A return (addr & ~(cacheBlkMask)); 2791062SN/A } 2801061SN/A 2811060SN/A private: 2822698Sktlim@umich.edu /** Handles retrying the fetch access. */ 2832696Sktlim@umich.edu void recvRetry(); 2842696Sktlim@umich.edu 2852292SN/A /** Returns the appropriate thread to fetch, given the fetch policy. */ 2862292SN/A int getFetchingThread(FetchPriority &fetch_priority); 2872292SN/A 2882292SN/A /** Returns the appropriate thread to fetch using a round robin policy. */ 2892292SN/A int roundRobin(); 2902292SN/A 2912292SN/A /** Returns the appropriate thread to fetch using the IQ count policy. */ 2922292SN/A int iqCount(); 2932292SN/A 2942292SN/A /** Returns the appropriate thread to fetch using the LSQ count policy. */ 2952292SN/A int lsqCount(); 2962292SN/A 2972292SN/A /** Returns the appropriate thread to fetch using the branch count policy. */ 2982292SN/A int branchCount(); 2992292SN/A 3002292SN/A private: 3012733Sktlim@umich.edu /** Pointer to the O3CPU. */ 3022733Sktlim@umich.edu O3CPU *cpu; 3031060SN/A 3041060SN/A /** Time buffer interface. */ 3051060SN/A TimeBuffer<TimeStruct> *timeBuffer; 3061060SN/A 3071060SN/A /** Wire to get decode's information from backwards time buffer. */ 3081060SN/A typename TimeBuffer<TimeStruct>::wire fromDecode; 3091060SN/A 3101060SN/A /** Wire to get rename's information from backwards time buffer. */ 3111060SN/A typename TimeBuffer<TimeStruct>::wire fromRename; 3121060SN/A 3131060SN/A /** Wire to get iew's information from backwards time buffer. */ 3141060SN/A typename TimeBuffer<TimeStruct>::wire fromIEW; 3151060SN/A 3161060SN/A /** Wire to get commit's information from backwards time buffer. */ 3171060SN/A typename TimeBuffer<TimeStruct>::wire fromCommit; 3181060SN/A 3191060SN/A /** Internal fetch instruction queue. */ 3201060SN/A TimeBuffer<FetchStruct> *fetchQueue; 3211060SN/A 3221060SN/A //Might be annoying how this name is different than the queue. 3231060SN/A /** Wire used to write any information heading to decode. */ 3241060SN/A typename TimeBuffer<FetchStruct>::wire toDecode; 3251060SN/A 3262669Sktlim@umich.edu MemObject *mem; 3272669Sktlim@umich.edu 3281060SN/A /** Icache interface. */ 3292669Sktlim@umich.edu IcachePort *icachePort; 3301060SN/A 3311061SN/A /** BPredUnit. */ 3321061SN/A BPredUnit branchPred; 3331061SN/A 3342348SN/A /** Per-thread fetch PC. */ 3352292SN/A Addr PC[Impl::MaxThreads]; 3362292SN/A 3372348SN/A /** Per-thread next PC. */ 3382292SN/A Addr nextPC[Impl::MaxThreads]; 3392292SN/A 3402756Sksewell@umich.edu#if THE_ISA != ALPHA_ISA 3412756Sksewell@umich.edu /** Per-thread next Next PC. 3422756Sksewell@umich.edu * This is not a real register but is used for 3432756Sksewell@umich.edu * architectures that use a branch-delay slot. 3442756Sksewell@umich.edu * (such as MIPS or Sparc) 3452756Sksewell@umich.edu */ 3462756Sksewell@umich.edu Addr nextNPC[Impl::MaxThreads]; 3472756Sksewell@umich.edu#endif 3482756Sksewell@umich.edu 3492678Sktlim@umich.edu /** Memory request used to access cache. */ 3502678Sktlim@umich.edu RequestPtr memReq[Impl::MaxThreads]; 3512292SN/A 3522292SN/A /** Variable that tracks if fetch has written to the time buffer this 3532292SN/A * cycle. Used to tell CPU if there is activity this cycle. 3542292SN/A */ 3552292SN/A bool wroteToTimeBuffer; 3562292SN/A 3572292SN/A /** Tracks how many instructions has been fetched this cycle. */ 3582292SN/A int numInst; 3592292SN/A 3602292SN/A /** Source of possible stalls. */ 3612292SN/A struct Stalls { 3622292SN/A bool decode; 3632292SN/A bool rename; 3642292SN/A bool iew; 3652292SN/A bool commit; 3662292SN/A }; 3672292SN/A 3682292SN/A /** Tracks which stages are telling fetch to stall. */ 3692292SN/A Stalls stalls[Impl::MaxThreads]; 3701060SN/A 3711060SN/A /** Decode to fetch delay, in ticks. */ 3721060SN/A unsigned decodeToFetchDelay; 3731060SN/A 3741060SN/A /** Rename to fetch delay, in ticks. */ 3751060SN/A unsigned renameToFetchDelay; 3761060SN/A 3771060SN/A /** IEW to fetch delay, in ticks. */ 3781060SN/A unsigned iewToFetchDelay; 3791060SN/A 3801060SN/A /** Commit to fetch delay, in ticks. */ 3811060SN/A unsigned commitToFetchDelay; 3821060SN/A 3831060SN/A /** The width of fetch in instructions. */ 3841060SN/A unsigned fetchWidth; 3851060SN/A 3862696Sktlim@umich.edu /** Is the cache blocked? If so no threads can access it. */ 3872696Sktlim@umich.edu bool cacheBlocked; 3882696Sktlim@umich.edu 3892696Sktlim@umich.edu /** The packet that is waiting to be retried. */ 3902696Sktlim@umich.edu PacketPtr retryPkt; 3912696Sktlim@umich.edu 3922696Sktlim@umich.edu /** The thread that is waiting on the cache to tell fetch to retry. */ 3932696Sktlim@umich.edu int retryTid; 3942696Sktlim@umich.edu 3951060SN/A /** Cache block size. */ 3961062SN/A int cacheBlkSize; 3971060SN/A 3981060SN/A /** Mask to get a cache block's address. */ 3991062SN/A Addr cacheBlkMask; 4001060SN/A 4011062SN/A /** The cache line being fetched. */ 4022292SN/A uint8_t *cacheData[Impl::MaxThreads]; 4031060SN/A 4041060SN/A /** Size of instructions. */ 4051060SN/A int instSize; 4061060SN/A 4071060SN/A /** Icache stall statistics. */ 4082292SN/A Counter lastIcacheStall[Impl::MaxThreads]; 4091062SN/A 4102292SN/A /** List of Active Threads */ 4112292SN/A std::list<unsigned> *activeThreads; 4122292SN/A 4132292SN/A /** Number of threads. */ 4142292SN/A unsigned numThreads; 4152292SN/A 4162292SN/A /** Number of threads that are actively fetching. */ 4172292SN/A unsigned numFetchingThreads; 4182292SN/A 4192292SN/A /** Thread ID being fetched. */ 4202292SN/A int threadFetched; 4212292SN/A 4222348SN/A /** Checks if there is an interrupt pending. If there is, fetch 4232348SN/A * must stop once it is not fetching PAL instructions. 4242348SN/A */ 4252292SN/A bool interruptPending; 4262292SN/A 4272843Sktlim@umich.edu /** Is there a drain pending. */ 4282843Sktlim@umich.edu bool drainPending; 4292843Sktlim@umich.edu 4302348SN/A /** Records if fetch is switched out. */ 4312307SN/A bool switchedOut; 4322307SN/A 4332292SN/A // @todo: Consider making these vectors and tracking on a per thread basis. 4342292SN/A /** Stat for total number of cycles stalled due to an icache miss. */ 4351062SN/A Stats::Scalar<> icacheStallCycles; 4362292SN/A /** Stat for total number of fetched instructions. */ 4371062SN/A Stats::Scalar<> fetchedInsts; 4382727Sktlim@umich.edu /** Total number of fetched branches. */ 4392301SN/A Stats::Scalar<> fetchedBranches; 4402292SN/A /** Stat for total number of predicted branches. */ 4411062SN/A Stats::Scalar<> predictedBranches; 4422292SN/A /** Stat for total number of cycles spent fetching. */ 4431062SN/A Stats::Scalar<> fetchCycles; 4442292SN/A /** Stat for total number of cycles spent squashing. */ 4451062SN/A Stats::Scalar<> fetchSquashCycles; 4462292SN/A /** Stat for total number of cycles spent blocked due to other stages in 4472292SN/A * the pipeline. 4482292SN/A */ 4492292SN/A Stats::Scalar<> fetchIdleCycles; 4502348SN/A /** Total number of cycles spent blocked. */ 4511062SN/A Stats::Scalar<> fetchBlockedCycles; 4522348SN/A /** Total number of cycles spent in any other state. */ 4532307SN/A Stats::Scalar<> fetchMiscStallCycles; 4542292SN/A /** Stat for total number of fetched cache lines. */ 4551062SN/A Stats::Scalar<> fetchedCacheLines; 4562348SN/A /** Total number of outstanding icache accesses that were dropped 4572348SN/A * due to a squash. 4582348SN/A */ 4592301SN/A Stats::Scalar<> fetchIcacheSquashes; 4602292SN/A /** Distribution of number of instructions fetched each cycle. */ 4612292SN/A Stats::Distribution<> fetchNisnDist; 4622348SN/A /** Rate of how often fetch was idle. */ 4632292SN/A Stats::Formula idleRate; 4642348SN/A /** Number of branch fetches per cycle. */ 4652292SN/A Stats::Formula branchRate; 4662348SN/A /** Number of instruction fetched per cycle. */ 4672292SN/A Stats::Formula fetchRate; 4681060SN/A}; 4691060SN/A 4702292SN/A#endif //__CPU_O3_FETCH_HH__ 471