fetch.hh revision 8460:3893d9d2c6c2
111012Sandreas.sandberg@arm.com/* 211897Ssudhanshu.jha@arm.com * Copyright (c) 2010 ARM Limited 311012Sandreas.sandberg@arm.com * All rights reserved 411012Sandreas.sandberg@arm.com * 511012Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall 611012Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual 711012Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating 811012Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software 911012Sandreas.sandberg@arm.com * licensed hereunder. You may use the software subject to the license 1011012Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated 1111012Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software, 1211012Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form. 1311012Sandreas.sandberg@arm.com * 1411012Sandreas.sandberg@arm.com * Copyright (c) 2004-2006 The Regents of The University of Michigan 1511012Sandreas.sandberg@arm.com * All rights reserved. 1611012Sandreas.sandberg@arm.com * 1711012Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without 1811012Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are 1911012Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright 2011012Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer; 2111012Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright 2211012Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the 2311012Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution; 2411012Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its 2511012Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from 2611012Sandreas.sandberg@arm.com * this software without specific prior written permission. 2711012Sandreas.sandberg@arm.com * 2811012Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2911012Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3011012Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3111012Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3211012Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3311012Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3411012Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3511012Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3611012Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3711012Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3811012Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3911012Sandreas.sandberg@arm.com * 4011012Sandreas.sandberg@arm.com * Authors: Kevin Lim 4111012Sandreas.sandberg@arm.com * Korey Sewell 4211012Sandreas.sandberg@arm.com */ 4311012Sandreas.sandberg@arm.com 4411012Sandreas.sandberg@arm.com#ifndef __CPU_O3_FETCH_HH__ 4511012Sandreas.sandberg@arm.com#define __CPU_O3_FETCH_HH__ 4611012Sandreas.sandberg@arm.com 4711012Sandreas.sandberg@arm.com#include "arch/predecoder.hh" 4811012Sandreas.sandberg@arm.com#include "arch/utility.hh" 4911012Sandreas.sandberg@arm.com#include "base/statistics.hh" 5011012Sandreas.sandberg@arm.com#include "config/the_isa.hh" 5111012Sandreas.sandberg@arm.com#include "cpu/pc_event.hh" 5211012Sandreas.sandberg@arm.com#include "cpu/timebuf.hh" 5311012Sandreas.sandberg@arm.com#include "cpu/translation.hh" 5411012Sandreas.sandberg@arm.com#include "mem/packet.hh" 5511012Sandreas.sandberg@arm.com#include "mem/port.hh" 5611012Sandreas.sandberg@arm.com#include "sim/eventq.hh" 5711012Sandreas.sandberg@arm.com 5811012Sandreas.sandberg@arm.comclass DerivO3CPUParams; 5911012Sandreas.sandberg@arm.com 6011012Sandreas.sandberg@arm.com/** 6111012Sandreas.sandberg@arm.com * DefaultFetch class handles both single threaded and SMT fetch. Its 6211012Sandreas.sandberg@arm.com * width is specified by the parameters; each cycle it tries to fetch 6311012Sandreas.sandberg@arm.com * that many instructions. It supports using a branch predictor to 6411012Sandreas.sandberg@arm.com * predict direction and targets. 6511012Sandreas.sandberg@arm.com * It supports the idling functionality of the CPU by indicating to 6611012Sandreas.sandberg@arm.com * the CPU when it is active and inactive. 6711012Sandreas.sandberg@arm.com */ 6811012Sandreas.sandberg@arm.comtemplate <class Impl> 6911012Sandreas.sandberg@arm.comclass DefaultFetch 7011012Sandreas.sandberg@arm.com{ 7111012Sandreas.sandberg@arm.com public: 7211012Sandreas.sandberg@arm.com /** Typedefs from Impl. */ 7311012Sandreas.sandberg@arm.com typedef typename Impl::CPUPol CPUPol; 7411012Sandreas.sandberg@arm.com typedef typename Impl::DynInst DynInst; 7511012Sandreas.sandberg@arm.com typedef typename Impl::DynInstPtr DynInstPtr; 7611012Sandreas.sandberg@arm.com typedef typename Impl::O3CPU O3CPU; 7711012Sandreas.sandberg@arm.com 7811012Sandreas.sandberg@arm.com /** Typedefs from the CPU policy. */ 7911012Sandreas.sandberg@arm.com typedef typename CPUPol::BPredUnit BPredUnit; 8011012Sandreas.sandberg@arm.com typedef typename CPUPol::FetchStruct FetchStruct; 8111012Sandreas.sandberg@arm.com typedef typename CPUPol::TimeStruct TimeStruct; 8211012Sandreas.sandberg@arm.com 8311012Sandreas.sandberg@arm.com /** Typedefs from ISA. */ 8411012Sandreas.sandberg@arm.com typedef TheISA::MachInst MachInst; 8511012Sandreas.sandberg@arm.com typedef TheISA::ExtMachInst ExtMachInst; 8611012Sandreas.sandberg@arm.com 8711012Sandreas.sandberg@arm.com /** IcachePort class for DefaultFetch. Handles doing the 8811012Sandreas.sandberg@arm.com * communication with the cache/memory. 8911012Sandreas.sandberg@arm.com */ 9011012Sandreas.sandberg@arm.com class IcachePort : public Port 9111012Sandreas.sandberg@arm.com { 9211012Sandreas.sandberg@arm.com protected: 9311012Sandreas.sandberg@arm.com /** Pointer to fetch. */ 9411012Sandreas.sandberg@arm.com DefaultFetch<Impl> *fetch; 9511012Sandreas.sandberg@arm.com 9611012Sandreas.sandberg@arm.com public: 9711012Sandreas.sandberg@arm.com /** Default constructor. */ 9811012Sandreas.sandberg@arm.com IcachePort(DefaultFetch<Impl> *_fetch) 9911012Sandreas.sandberg@arm.com : Port(_fetch->name() + "-iport", _fetch->cpu), fetch(_fetch) 10011012Sandreas.sandberg@arm.com { } 10111012Sandreas.sandberg@arm.com 10211012Sandreas.sandberg@arm.com bool snoopRangeSent; 10311012Sandreas.sandberg@arm.com 10411012Sandreas.sandberg@arm.com virtual void setPeer(Port *port); 10511012Sandreas.sandberg@arm.com 10611012Sandreas.sandberg@arm.com protected: 10711012Sandreas.sandberg@arm.com /** Atomic version of receive. Panics. */ 10811012Sandreas.sandberg@arm.com virtual Tick recvAtomic(PacketPtr pkt); 10911012Sandreas.sandberg@arm.com 11011012Sandreas.sandberg@arm.com /** Functional version of receive. Panics. */ 11111012Sandreas.sandberg@arm.com virtual void recvFunctional(PacketPtr pkt); 11211012Sandreas.sandberg@arm.com 11311012Sandreas.sandberg@arm.com /** Receives status change. Other than range changing, panics. */ 11411012Sandreas.sandberg@arm.com virtual void recvStatusChange(Status status); 11511012Sandreas.sandberg@arm.com 11611012Sandreas.sandberg@arm.com /** Returns the address ranges of this device. */ 11711012Sandreas.sandberg@arm.com virtual void getDeviceAddressRanges(AddrRangeList &resp, 11811012Sandreas.sandberg@arm.com bool &snoop) 11911012Sandreas.sandberg@arm.com { resp.clear(); snoop = true; } 12011012Sandreas.sandberg@arm.com 12111012Sandreas.sandberg@arm.com /** Timing version of receive. Handles setting fetch to the 12211012Sandreas.sandberg@arm.com * proper status to start fetching. */ 12311012Sandreas.sandberg@arm.com virtual bool recvTiming(PacketPtr pkt); 12411012Sandreas.sandberg@arm.com 12511012Sandreas.sandberg@arm.com /** Handles doing a retry of a failed fetch. */ 12611012Sandreas.sandberg@arm.com virtual void recvRetry(); 12711012Sandreas.sandberg@arm.com }; 12811012Sandreas.sandberg@arm.com 12911012Sandreas.sandberg@arm.com class FetchTranslation : public BaseTLB::Translation 13011012Sandreas.sandberg@arm.com { 13111012Sandreas.sandberg@arm.com protected: 13211012Sandreas.sandberg@arm.com DefaultFetch<Impl> *fetch; 13311012Sandreas.sandberg@arm.com 13411012Sandreas.sandberg@arm.com public: 13511012Sandreas.sandberg@arm.com FetchTranslation(DefaultFetch<Impl> *_fetch) 13611012Sandreas.sandberg@arm.com : fetch(_fetch) 13711012Sandreas.sandberg@arm.com {} 13811012Sandreas.sandberg@arm.com 13911897Ssudhanshu.jha@arm.com void 14011897Ssudhanshu.jha@arm.com markDelayed() 14111897Ssudhanshu.jha@arm.com {} 14211897Ssudhanshu.jha@arm.com 14311012Sandreas.sandberg@arm.com void 14411012Sandreas.sandberg@arm.com finish(Fault fault, RequestPtr req, ThreadContext *tc, 14511012Sandreas.sandberg@arm.com BaseTLB::Mode mode) 14611012Sandreas.sandberg@arm.com { 14711012Sandreas.sandberg@arm.com assert(mode == BaseTLB::Execute); 14811012Sandreas.sandberg@arm.com fetch->finishTranslation(fault, req); 14911012Sandreas.sandberg@arm.com delete this; 15011012Sandreas.sandberg@arm.com } 15111012Sandreas.sandberg@arm.com }; 15211012Sandreas.sandberg@arm.com 15311897Ssudhanshu.jha@arm.com public: 15411897Ssudhanshu.jha@arm.com /** Overall fetch status. Used to determine if the CPU can 15511897Ssudhanshu.jha@arm.com * deschedule itsef due to a lack of activity. 15611897Ssudhanshu.jha@arm.com */ 15711897Ssudhanshu.jha@arm.com enum FetchStatus { 15811012Sandreas.sandberg@arm.com Active, 15911012Sandreas.sandberg@arm.com Inactive 16011012Sandreas.sandberg@arm.com }; 16111897Ssudhanshu.jha@arm.com 16211012Sandreas.sandberg@arm.com /** Individual thread status. */ 16311012Sandreas.sandberg@arm.com enum ThreadStatus { 16411012Sandreas.sandberg@arm.com Running, 16511012Sandreas.sandberg@arm.com Idle, 16611012Sandreas.sandberg@arm.com Squashing, 16711012Sandreas.sandberg@arm.com Blocked, 16811012Sandreas.sandberg@arm.com Fetching, 16911012Sandreas.sandberg@arm.com TrapPending, 17011012Sandreas.sandberg@arm.com QuiescePending, 17111012Sandreas.sandberg@arm.com SwitchOut, 17211012Sandreas.sandberg@arm.com ItlbWait, 17311012Sandreas.sandberg@arm.com IcacheWaitResponse, 17411012Sandreas.sandberg@arm.com IcacheWaitRetry, 17511012Sandreas.sandberg@arm.com IcacheAccessComplete, 17611012Sandreas.sandberg@arm.com NoGoodAddr 17711012Sandreas.sandberg@arm.com }; 17811012Sandreas.sandberg@arm.com 17911012Sandreas.sandberg@arm.com /** Fetching Policy, Add new policies here.*/ 18011012Sandreas.sandberg@arm.com enum FetchPriority { 18111012Sandreas.sandberg@arm.com SingleThread, 18211012Sandreas.sandberg@arm.com RoundRobin, 18311012Sandreas.sandberg@arm.com Branch, 18411012Sandreas.sandberg@arm.com IQ, 18511012Sandreas.sandberg@arm.com LSQ 18611012Sandreas.sandberg@arm.com }; 18711012Sandreas.sandberg@arm.com 18811012Sandreas.sandberg@arm.com private: 18911012Sandreas.sandberg@arm.com /** Fetch status. */ 19011012Sandreas.sandberg@arm.com FetchStatus _status; 19111012Sandreas.sandberg@arm.com 19211012Sandreas.sandberg@arm.com /** Per-thread status. */ 19311012Sandreas.sandberg@arm.com ThreadStatus fetchStatus[Impl::MaxThreads]; 19411012Sandreas.sandberg@arm.com 19511012Sandreas.sandberg@arm.com /** Fetch policy. */ 19611012Sandreas.sandberg@arm.com FetchPriority fetchPolicy; 19711012Sandreas.sandberg@arm.com 19811012Sandreas.sandberg@arm.com /** List that has the threads organized by priority. */ 19911012Sandreas.sandberg@arm.com std::list<ThreadID> priorityList; 20011012Sandreas.sandberg@arm.com 20111012Sandreas.sandberg@arm.com public: 20211012Sandreas.sandberg@arm.com /** DefaultFetch constructor. */ 20311012Sandreas.sandberg@arm.com DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params); 20411012Sandreas.sandberg@arm.com 20511012Sandreas.sandberg@arm.com /** Returns the name of fetch. */ 20611012Sandreas.sandberg@arm.com std::string name() const; 20711012Sandreas.sandberg@arm.com 20811012Sandreas.sandberg@arm.com /** Registers statistics. */ 20911012Sandreas.sandberg@arm.com void regStats(); 21011012Sandreas.sandberg@arm.com 21111012Sandreas.sandberg@arm.com /** Returns the icache port. */ 21211012Sandreas.sandberg@arm.com Port *getIcachePort() { return icachePort; } 21311012Sandreas.sandberg@arm.com 21411012Sandreas.sandberg@arm.com /** Sets the main backwards communication time buffer pointer. */ 21511012Sandreas.sandberg@arm.com void setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer); 21611012Sandreas.sandberg@arm.com 21711012Sandreas.sandberg@arm.com /** Sets pointer to list of active threads. */ 21811012Sandreas.sandberg@arm.com void setActiveThreads(std::list<ThreadID> *at_ptr); 21911012Sandreas.sandberg@arm.com 22011012Sandreas.sandberg@arm.com /** Sets pointer to time buffer used to communicate to the next stage. */ 22111012Sandreas.sandberg@arm.com void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr); 22211012Sandreas.sandberg@arm.com 22311012Sandreas.sandberg@arm.com /** Initialize stage. */ 22411012Sandreas.sandberg@arm.com void initStage(); 22511012Sandreas.sandberg@arm.com 22611012Sandreas.sandberg@arm.com /** Tells the fetch stage that the Icache is set. */ 22711012Sandreas.sandberg@arm.com void setIcache(); 22811012Sandreas.sandberg@arm.com 22911012Sandreas.sandberg@arm.com /** Processes cache completion event. */ 23011012Sandreas.sandberg@arm.com void processCacheCompletion(PacketPtr pkt); 23111012Sandreas.sandberg@arm.com 23211012Sandreas.sandberg@arm.com /** Begins the drain of the fetch stage. */ 23311012Sandreas.sandberg@arm.com bool drain(); 23411012Sandreas.sandberg@arm.com 23511012Sandreas.sandberg@arm.com /** Resumes execution after a drain. */ 23611012Sandreas.sandberg@arm.com void resume(); 23711012Sandreas.sandberg@arm.com 23811012Sandreas.sandberg@arm.com /** Tells fetch stage to prepare to be switched out. */ 23911012Sandreas.sandberg@arm.com void switchOut(); 24011012Sandreas.sandberg@arm.com 24111012Sandreas.sandberg@arm.com /** Takes over from another CPU's thread. */ 24211012Sandreas.sandberg@arm.com void takeOverFrom(); 24311012Sandreas.sandberg@arm.com 24411012Sandreas.sandberg@arm.com /** Checks if the fetch stage is switched out. */ 24511012Sandreas.sandberg@arm.com bool isSwitchedOut() { return switchedOut; } 24611012Sandreas.sandberg@arm.com 24711012Sandreas.sandberg@arm.com /** Tells fetch to wake up from a quiesce instruction. */ 24811012Sandreas.sandberg@arm.com void wakeFromQuiesce(); 24911012Sandreas.sandberg@arm.com 25011012Sandreas.sandberg@arm.com private: 25111897Ssudhanshu.jha@arm.com /** Changes the status of this stage to active, and indicates this 25211897Ssudhanshu.jha@arm.com * to the CPU. 25311897Ssudhanshu.jha@arm.com */ 25411897Ssudhanshu.jha@arm.com inline void switchToActive(); 25511897Ssudhanshu.jha@arm.com 25611897Ssudhanshu.jha@arm.com /** Changes the status of this stage to inactive, and indicates 25711897Ssudhanshu.jha@arm.com * this to the CPU. 25811897Ssudhanshu.jha@arm.com */ 25911897Ssudhanshu.jha@arm.com inline void switchToInactive(); 26011897Ssudhanshu.jha@arm.com 26111897Ssudhanshu.jha@arm.com /** 26211897Ssudhanshu.jha@arm.com * Looks up in the branch predictor to see if the next PC should be 26311897Ssudhanshu.jha@arm.com * either next PC+=MachInst or a branch target. 26411897Ssudhanshu.jha@arm.com * @param next_PC Next PC variable passed in by reference. It is 26511897Ssudhanshu.jha@arm.com * expected to be set to the current PC; it will be updated with what 26611897Ssudhanshu.jha@arm.com * the next PC will be. 26711897Ssudhanshu.jha@arm.com * @param next_NPC Used for ISAs which use delay slots. 26811897Ssudhanshu.jha@arm.com * @return Whether or not a branch was predicted as taken. 26911897Ssudhanshu.jha@arm.com */ 27011897Ssudhanshu.jha@arm.com bool lookupAndUpdateNextPC(DynInstPtr &inst, TheISA::PCState &pc); 27111897Ssudhanshu.jha@arm.com 27211897Ssudhanshu.jha@arm.com /** 27311897Ssudhanshu.jha@arm.com * Fetches the cache line that contains fetch_PC. Returns any 27411897Ssudhanshu.jha@arm.com * fault that happened. Puts the data into the class variable 27511897Ssudhanshu.jha@arm.com * cacheData. 27611897Ssudhanshu.jha@arm.com * @param vaddr The memory address that is being fetched from. 27711897Ssudhanshu.jha@arm.com * @param ret_fault The fault reference that will be set to the result of 27811897Ssudhanshu.jha@arm.com * the icache access. 27911897Ssudhanshu.jha@arm.com * @param tid Thread id. 28011897Ssudhanshu.jha@arm.com * @param pc The actual PC of the current instruction. 28111897Ssudhanshu.jha@arm.com * @return Any fault that occured. 28211897Ssudhanshu.jha@arm.com */ 28311897Ssudhanshu.jha@arm.com bool fetchCacheLine(Addr vaddr, ThreadID tid, Addr pc); 28411897Ssudhanshu.jha@arm.com void finishTranslation(Fault fault, RequestPtr mem_req); 28511897Ssudhanshu.jha@arm.com 28611897Ssudhanshu.jha@arm.com 28711897Ssudhanshu.jha@arm.com /** Check if an interrupt is pending and that we need to handle 28811897Ssudhanshu.jha@arm.com */ 28911897Ssudhanshu.jha@arm.com bool 29011897Ssudhanshu.jha@arm.com checkInterrupt(Addr pc) 29111897Ssudhanshu.jha@arm.com { 29211897Ssudhanshu.jha@arm.com return (interruptPending && (THE_ISA != ALPHA_ISA || !(pc & 0x3))); 29311897Ssudhanshu.jha@arm.com } 29411897Ssudhanshu.jha@arm.com 29511897Ssudhanshu.jha@arm.com /** Squashes a specific thread and resets the PC. */ 29611897Ssudhanshu.jha@arm.com inline void doSquash(const TheISA::PCState &newPC, ThreadID tid); 29711897Ssudhanshu.jha@arm.com 29811897Ssudhanshu.jha@arm.com /** Squashes a specific thread and resets the PC. Also tells the CPU to 29911012Sandreas.sandberg@arm.com * remove any instructions between fetch and decode that should be sqaushed. 30011012Sandreas.sandberg@arm.com */ 30111012Sandreas.sandberg@arm.com void squashFromDecode(const TheISA::PCState &newPC, 30211012Sandreas.sandberg@arm.com const InstSeqNum &seq_num, ThreadID tid); 30311012Sandreas.sandberg@arm.com 30411012Sandreas.sandberg@arm.com /** Checks if a thread is stalled. */ 30511012Sandreas.sandberg@arm.com bool checkStall(ThreadID tid) const; 30611012Sandreas.sandberg@arm.com 30711012Sandreas.sandberg@arm.com /** Updates overall fetch stage status; to be called at the end of each 30811012Sandreas.sandberg@arm.com * cycle. */ 30911012Sandreas.sandberg@arm.com FetchStatus updateFetchStatus(); 31011012Sandreas.sandberg@arm.com 31111012Sandreas.sandberg@arm.com public: 31211012Sandreas.sandberg@arm.com /** Squashes a specific thread and resets the PC. Also tells the CPU to 31311012Sandreas.sandberg@arm.com * remove any instructions that are not in the ROB. The source of this 31411012Sandreas.sandberg@arm.com * squash should be the commit stage. 31511012Sandreas.sandberg@arm.com */ 31611012Sandreas.sandberg@arm.com void squash(const TheISA::PCState &newPC, const InstSeqNum &seq_num, 31711012Sandreas.sandberg@arm.com DynInstPtr &squashInst, ThreadID tid); 31811012Sandreas.sandberg@arm.com 31911012Sandreas.sandberg@arm.com /** Ticks the fetch stage, processing all inputs signals and fetching 32011012Sandreas.sandberg@arm.com * as many instructions as possible. 32111012Sandreas.sandberg@arm.com */ 32211012Sandreas.sandberg@arm.com void tick(); 32311012Sandreas.sandberg@arm.com 32411012Sandreas.sandberg@arm.com /** Checks all input signals and updates the status as necessary. 32511012Sandreas.sandberg@arm.com * @return: Returns if the status has changed due to input signals. 32611012Sandreas.sandberg@arm.com */ 32711012Sandreas.sandberg@arm.com bool checkSignalsAndUpdate(ThreadID tid); 32811012Sandreas.sandberg@arm.com 32911012Sandreas.sandberg@arm.com /** Does the actual fetching of instructions and passing them on to the 33011012Sandreas.sandberg@arm.com * next stage. 33111012Sandreas.sandberg@arm.com * @param status_change fetch() sets this variable if there was a status 33211012Sandreas.sandberg@arm.com * change (ie switching to IcacheMissStall). 33311012Sandreas.sandberg@arm.com */ 33411012Sandreas.sandberg@arm.com void fetch(bool &status_change); 33511012Sandreas.sandberg@arm.com 33611012Sandreas.sandberg@arm.com /** Align a PC to the start of an I-cache block. */ 33711012Sandreas.sandberg@arm.com Addr icacheBlockAlignPC(Addr addr) 33811012Sandreas.sandberg@arm.com { 33911012Sandreas.sandberg@arm.com return (addr & ~(cacheBlkMask)); 34011012Sandreas.sandberg@arm.com } 34111012Sandreas.sandberg@arm.com 34211012Sandreas.sandberg@arm.com private: 34311012Sandreas.sandberg@arm.com DynInstPtr buildInst(ThreadID tid, StaticInstPtr staticInst, 34411012Sandreas.sandberg@arm.com StaticInstPtr curMacroop, TheISA::PCState thisPC, 34511012Sandreas.sandberg@arm.com TheISA::PCState nextPC, bool trace); 34611012Sandreas.sandberg@arm.com 34711012Sandreas.sandberg@arm.com /** Handles retrying the fetch access. */ 34811012Sandreas.sandberg@arm.com void recvRetry(); 34911012Sandreas.sandberg@arm.com 35011012Sandreas.sandberg@arm.com /** Returns the appropriate thread to fetch, given the fetch policy. */ 35111012Sandreas.sandberg@arm.com ThreadID getFetchingThread(FetchPriority &fetch_priority); 35211012Sandreas.sandberg@arm.com 35311012Sandreas.sandberg@arm.com /** Returns the appropriate thread to fetch using a round robin policy. */ 35411012Sandreas.sandberg@arm.com ThreadID roundRobin(); 35511012Sandreas.sandberg@arm.com 35611012Sandreas.sandberg@arm.com /** Returns the appropriate thread to fetch using the IQ count policy. */ 35711012Sandreas.sandberg@arm.com ThreadID iqCount(); 35811012Sandreas.sandberg@arm.com 35911012Sandreas.sandberg@arm.com /** Returns the appropriate thread to fetch using the LSQ count policy. */ 36011012Sandreas.sandberg@arm.com ThreadID lsqCount(); 36111012Sandreas.sandberg@arm.com 362 /** Returns the appropriate thread to fetch using the branch count 363 * policy. */ 364 ThreadID branchCount(); 365 366 private: 367 /** Pointer to the O3CPU. */ 368 O3CPU *cpu; 369 370 /** Time buffer interface. */ 371 TimeBuffer<TimeStruct> *timeBuffer; 372 373 /** Wire to get decode's information from backwards time buffer. */ 374 typename TimeBuffer<TimeStruct>::wire fromDecode; 375 376 /** Wire to get rename's information from backwards time buffer. */ 377 typename TimeBuffer<TimeStruct>::wire fromRename; 378 379 /** Wire to get iew's information from backwards time buffer. */ 380 typename TimeBuffer<TimeStruct>::wire fromIEW; 381 382 /** Wire to get commit's information from backwards time buffer. */ 383 typename TimeBuffer<TimeStruct>::wire fromCommit; 384 385 /** Internal fetch instruction queue. */ 386 TimeBuffer<FetchStruct> *fetchQueue; 387 388 //Might be annoying how this name is different than the queue. 389 /** Wire used to write any information heading to decode. */ 390 typename TimeBuffer<FetchStruct>::wire toDecode; 391 392 /** Icache interface. */ 393 IcachePort *icachePort; 394 395 /** BPredUnit. */ 396 BPredUnit branchPred; 397 398 /** Predecoder. */ 399 TheISA::Predecoder predecoder; 400 401 TheISA::PCState pc[Impl::MaxThreads]; 402 403 Addr fetchOffset[Impl::MaxThreads]; 404 405 StaticInstPtr macroop[Impl::MaxThreads]; 406 407 /** Can the fetch stage redirect from an interrupt on this instruction? */ 408 bool delayedCommit[Impl::MaxThreads]; 409 410 /** Memory request used to access cache. */ 411 RequestPtr memReq[Impl::MaxThreads]; 412 413 /** Variable that tracks if fetch has written to the time buffer this 414 * cycle. Used to tell CPU if there is activity this cycle. 415 */ 416 bool wroteToTimeBuffer; 417 418 /** Tracks how many instructions has been fetched this cycle. */ 419 int numInst; 420 421 /** Source of possible stalls. */ 422 struct Stalls { 423 bool decode; 424 bool rename; 425 bool iew; 426 bool commit; 427 }; 428 429 /** Tracks which stages are telling fetch to stall. */ 430 Stalls stalls[Impl::MaxThreads]; 431 432 /** Decode to fetch delay, in ticks. */ 433 unsigned decodeToFetchDelay; 434 435 /** Rename to fetch delay, in ticks. */ 436 unsigned renameToFetchDelay; 437 438 /** IEW to fetch delay, in ticks. */ 439 unsigned iewToFetchDelay; 440 441 /** Commit to fetch delay, in ticks. */ 442 unsigned commitToFetchDelay; 443 444 /** The width of fetch in instructions. */ 445 unsigned fetchWidth; 446 447 /** Is the cache blocked? If so no threads can access it. */ 448 bool cacheBlocked; 449 450 /** The packet that is waiting to be retried. */ 451 PacketPtr retryPkt; 452 453 /** The thread that is waiting on the cache to tell fetch to retry. */ 454 ThreadID retryTid; 455 456 /** Cache block size. */ 457 int cacheBlkSize; 458 459 /** Mask to get a cache block's address. */ 460 Addr cacheBlkMask; 461 462 /** The cache line being fetched. */ 463 uint8_t *cacheData[Impl::MaxThreads]; 464 465 /** The PC of the cacheline that has been loaded. */ 466 Addr cacheDataPC[Impl::MaxThreads]; 467 468 /** Whether or not the cache data is valid. */ 469 bool cacheDataValid[Impl::MaxThreads]; 470 471 /** Size of instructions. */ 472 int instSize; 473 474 /** Icache stall statistics. */ 475 Counter lastIcacheStall[Impl::MaxThreads]; 476 477 /** List of Active Threads */ 478 std::list<ThreadID> *activeThreads; 479 480 /** Number of threads. */ 481 ThreadID numThreads; 482 483 /** Number of threads that are actively fetching. */ 484 ThreadID numFetchingThreads; 485 486 /** Thread ID being fetched. */ 487 ThreadID threadFetched; 488 489 /** Checks if there is an interrupt pending. If there is, fetch 490 * must stop once it is not fetching PAL instructions. 491 */ 492 bool interruptPending; 493 494 /** Is there a drain pending. */ 495 bool drainPending; 496 497 /** Records if fetch is switched out. */ 498 bool switchedOut; 499 500 // @todo: Consider making these vectors and tracking on a per thread basis. 501 /** Stat for total number of cycles stalled due to an icache miss. */ 502 Stats::Scalar icacheStallCycles; 503 /** Stat for total number of fetched instructions. */ 504 Stats::Scalar fetchedInsts; 505 /** Total number of fetched branches. */ 506 Stats::Scalar fetchedBranches; 507 /** Stat for total number of predicted branches. */ 508 Stats::Scalar predictedBranches; 509 /** Stat for total number of cycles spent fetching. */ 510 Stats::Scalar fetchCycles; 511 /** Stat for total number of cycles spent squashing. */ 512 Stats::Scalar fetchSquashCycles; 513 /** Stat for total number of cycles spent waiting for translation */ 514 Stats::Scalar fetchTlbCycles; 515 /** Stat for total number of cycles spent blocked due to other stages in 516 * the pipeline. 517 */ 518 Stats::Scalar fetchIdleCycles; 519 /** Total number of cycles spent blocked. */ 520 Stats::Scalar fetchBlockedCycles; 521 /** Total number of cycles spent in any other state. */ 522 Stats::Scalar fetchMiscStallCycles; 523 /** Stat for total number of fetched cache lines. */ 524 Stats::Scalar fetchedCacheLines; 525 /** Total number of outstanding icache accesses that were dropped 526 * due to a squash. 527 */ 528 Stats::Scalar fetchIcacheSquashes; 529 /** Total number of outstanding tlb accesses that were dropped 530 * due to a squash. 531 */ 532 Stats::Scalar fetchTlbSquashes; 533 /** Distribution of number of instructions fetched each cycle. */ 534 Stats::Distribution fetchNisnDist; 535 /** Rate of how often fetch was idle. */ 536 Stats::Formula idleRate; 537 /** Number of branch fetches per cycle. */ 538 Stats::Formula branchRate; 539 /** Number of instruction fetched per cycle. */ 540 Stats::Formula fetchRate; 541}; 542 543#endif //__CPU_O3_FETCH_HH__ 544