fetch.hh revision 1461
1955SN/A// Todo: add in statistics, only get the MachInst and let decode actually
2955SN/A// decode, think about SMT fetch,
311408Sandreas.sandberg@arm.com// fix up branch prediction stuff into one thing,
49812Sandreas.hansson@arm.com// Figure out where to advance time buffer.  Add a way to get a
59812Sandreas.hansson@arm.com// stage's current status.
69812Sandreas.hansson@arm.com
79812Sandreas.hansson@arm.com#ifndef __CPU_BETA_CPU_SIMPLE_FETCH_HH__
89812Sandreas.hansson@arm.com#define __CPU_BETA_CPU_SIMPLE_FETCH_HH__
99812Sandreas.hansson@arm.com
109812Sandreas.hansson@arm.com//Will want to include: time buffer, structs, MemInterface, Event,
119812Sandreas.hansson@arm.com//whatever class bzero uses, MemReqPtr
129812Sandreas.hansson@arm.com
139812Sandreas.hansson@arm.com#include "base/statistics.hh"
149812Sandreas.hansson@arm.com#include "base/timebuf.hh"
157816Ssteve.reinhardt@amd.com#include "cpu/pc_event.hh"
165871Snate@binkert.org#include "mem/mem_interface.hh"
171762SN/A#include "sim/eventq.hh"
18955SN/A
19955SN/A/**
20955SN/A * SimpleFetch class to fetch a single instruction each cycle.  SimpleFetch
21955SN/A * will stall if there's an Icache miss, but otherwise assumes a one cycle
22955SN/A * Icache hit.
23955SN/A */
24955SN/A
25955SN/Atemplate <class Impl>
26955SN/Aclass SimpleFetch
27955SN/A{
28955SN/A  public:
29955SN/A    /** Typedefs from Impl. */
30955SN/A    typedef typename Impl::ISA ISA;
31955SN/A    typedef typename Impl::CPUPol CPUPol;
32955SN/A    typedef typename Impl::DynInst DynInst;
33955SN/A    typedef typename Impl::DynInstPtr DynInstPtr;
34955SN/A    typedef typename Impl::FullCPU FullCPU;
35955SN/A    typedef typename Impl::Params Params;
36955SN/A
37955SN/A    typedef typename CPUPol::BPredUnit BPredUnit;
38955SN/A    typedef typename CPUPol::FetchStruct FetchStruct;
39955SN/A    typedef typename CPUPol::TimeStruct TimeStruct;
40955SN/A
41955SN/A    /** Typedefs from ISA. */
422665Ssaidi@eecs.umich.edu    typedef typename ISA::MachInst MachInst;
432665Ssaidi@eecs.umich.edu
445863Snate@binkert.org  public:
45955SN/A    enum Status {
46955SN/A        Running,
47955SN/A        Idle,
48955SN/A        Squashing,
49955SN/A        Blocked,
508878Ssteve.reinhardt@amd.com        IcacheMissStall,
512632Sstever@eecs.umich.edu        IcacheMissComplete
528878Ssteve.reinhardt@amd.com    };
532632Sstever@eecs.umich.edu
54955SN/A    // May eventually need statuses on a per thread basis.
558878Ssteve.reinhardt@amd.com    Status _status;
562632Sstever@eecs.umich.edu
572761Sstever@eecs.umich.edu    bool stalled;
582632Sstever@eecs.umich.edu
592632Sstever@eecs.umich.edu  public:
602632Sstever@eecs.umich.edu    /** SimpleFetch constructor. */
612761Sstever@eecs.umich.edu    SimpleFetch(Params &params);
622761Sstever@eecs.umich.edu
632761Sstever@eecs.umich.edu    void regStats();
648878Ssteve.reinhardt@amd.com
658878Ssteve.reinhardt@amd.com    void setCPU(FullCPU *cpu_ptr);
662761Sstever@eecs.umich.edu
672761Sstever@eecs.umich.edu    void setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer);
682761Sstever@eecs.umich.edu
692761Sstever@eecs.umich.edu    void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr);
702761Sstever@eecs.umich.edu
718878Ssteve.reinhardt@amd.com    void tick();
728878Ssteve.reinhardt@amd.com
732632Sstever@eecs.umich.edu    void fetch();
742632Sstever@eecs.umich.edu
758878Ssteve.reinhardt@amd.com    void processCacheCompletion();
768878Ssteve.reinhardt@amd.com
772632Sstever@eecs.umich.edu//  private:
78955SN/A    // Figure out PC vs next PC and how it should be updated
79955SN/A    void squash(const Addr &new_PC);
80955SN/A
815863Snate@binkert.org  private:
825863Snate@binkert.org    inline void doSquash(const Addr &new_PC);
835863Snate@binkert.org
845863Snate@binkert.org    void squashFromDecode(const Addr &new_PC, const InstSeqNum &seq_num);
855863Snate@binkert.org
865863Snate@binkert.org    /**
875863Snate@binkert.org     * Looks up in the branch predictor to see if the next PC should be
885863Snate@binkert.org     * either next PC+=MachInst or a branch target.
895863Snate@binkert.org     * @params next_PC Next PC variable passed in by reference.  It is
905863Snate@binkert.org     * expected to be set to the current PC; it will be updated with what
915863Snate@binkert.org     * the next PC will be.
928878Ssteve.reinhardt@amd.com     * @return Whether or not a branch was predicted as taken.
935863Snate@binkert.org     */
945863Snate@binkert.org    bool lookupAndUpdateNextPC(DynInstPtr &inst, Addr &next_PC);
955863Snate@binkert.org
969812Sandreas.hansson@arm.com    // Might not want this function...
979812Sandreas.hansson@arm.com//    inline void recordGlobalHist(DynInstPtr &inst);
985863Snate@binkert.org
999812Sandreas.hansson@arm.com    /**
1005863Snate@binkert.org     * Fetches the cache line that contains fetch_PC.  Returns any
1015863Snate@binkert.org     * fault that happened.  Puts the data into the class variable
1025863Snate@binkert.org     * cacheData.
1039812Sandreas.hansson@arm.com     * @params fetch_PC The PC address that is being fetched from.
1049812Sandreas.hansson@arm.com     * @return Any fault that occured.
1055863Snate@binkert.org     */
1065863Snate@binkert.org    Fault fetchCacheLine(Addr fetch_PC);
1078878Ssteve.reinhardt@amd.com
1085863Snate@binkert.org    // Align an address (typically a PC) to the start of an I-cache block.
1095863Snate@binkert.org    // We fold in the PISA 64- to 32-bit conversion here as well.
1105863Snate@binkert.org    Addr icacheBlockAlignPC(Addr addr)
1116654Snate@binkert.org    {
11210196SCurtis.Dunham@arm.com        addr = ISA::realPCToFetchPC(addr);
113955SN/A        return (addr & ~(cacheBlkMask));
1145396Ssaidi@eecs.umich.edu    }
11511401Sandreas.sandberg@arm.com
1165863Snate@binkert.org  public:
1175863Snate@binkert.org    class CacheCompletionEvent : public Event
1184202Sbinkertn@umich.edu    {
1195863Snate@binkert.org      private:
1205863Snate@binkert.org        SimpleFetch *fetch;
1215863Snate@binkert.org
1225863Snate@binkert.org      public:
123955SN/A        CacheCompletionEvent(SimpleFetch *_fetch);
1246654Snate@binkert.org
1255273Sstever@gmail.com        virtual void process();
1265871Snate@binkert.org        virtual const char *description();
1275273Sstever@gmail.com    };
1286655Snate@binkert.org
1298878Ssteve.reinhardt@amd.com//    CacheCompletionEvent cacheCompletionEvent;
1306655Snate@binkert.org
1316655Snate@binkert.org  private:
1329219Spower.jg@gmail.com    /** Pointer to the FullCPU. */
1336655Snate@binkert.org    FullCPU *cpu;
1345871Snate@binkert.org
1356654Snate@binkert.org    /** Time buffer interface. */
1368947Sandreas.hansson@arm.com    TimeBuffer<TimeStruct> *timeBuffer;
1375396Ssaidi@eecs.umich.edu
1388120Sgblack@eecs.umich.edu    /** Wire to get decode's information from backwards time buffer. */
1398120Sgblack@eecs.umich.edu    typename TimeBuffer<TimeStruct>::wire fromDecode;
1408120Sgblack@eecs.umich.edu
1418120Sgblack@eecs.umich.edu    /** Wire to get rename's information from backwards time buffer. */
1428120Sgblack@eecs.umich.edu    typename TimeBuffer<TimeStruct>::wire fromRename;
1438120Sgblack@eecs.umich.edu
1448120Sgblack@eecs.umich.edu    /** Wire to get iew's information from backwards time buffer. */
1458120Sgblack@eecs.umich.edu    typename TimeBuffer<TimeStruct>::wire fromIEW;
1468879Ssteve.reinhardt@amd.com
1478879Ssteve.reinhardt@amd.com    /** Wire to get commit's information from backwards time buffer. */
1488879Ssteve.reinhardt@amd.com    typename TimeBuffer<TimeStruct>::wire fromCommit;
1498879Ssteve.reinhardt@amd.com
1508879Ssteve.reinhardt@amd.com    /** Internal fetch instruction queue. */
1518879Ssteve.reinhardt@amd.com    TimeBuffer<FetchStruct> *fetchQueue;
1528879Ssteve.reinhardt@amd.com
1538879Ssteve.reinhardt@amd.com    //Might be annoying how this name is different than the queue.
1548879Ssteve.reinhardt@amd.com    /** Wire used to write any information heading to decode. */
1558879Ssteve.reinhardt@amd.com    typename TimeBuffer<FetchStruct>::wire toDecode;
1568879Ssteve.reinhardt@amd.com
1578879Ssteve.reinhardt@amd.com    /** Icache interface. */
1588879Ssteve.reinhardt@amd.com    MemInterface *icacheInterface;
1598120Sgblack@eecs.umich.edu
1608120Sgblack@eecs.umich.edu    /** BPredUnit. */
1618120Sgblack@eecs.umich.edu    BPredUnit branchPred;
1628120Sgblack@eecs.umich.edu
1638120Sgblack@eecs.umich.edu    /** Memory request used to access cache. */
1648120Sgblack@eecs.umich.edu    MemReqPtr memReq;
1658120Sgblack@eecs.umich.edu
1668120Sgblack@eecs.umich.edu    /** Decode to fetch delay, in ticks. */
1678120Sgblack@eecs.umich.edu    unsigned decodeToFetchDelay;
1688120Sgblack@eecs.umich.edu
1698120Sgblack@eecs.umich.edu    /** Rename to fetch delay, in ticks. */
1708120Sgblack@eecs.umich.edu    unsigned renameToFetchDelay;
1718120Sgblack@eecs.umich.edu
1728120Sgblack@eecs.umich.edu    /** IEW to fetch delay, in ticks. */
1738879Ssteve.reinhardt@amd.com    unsigned iewToFetchDelay;
1748879Ssteve.reinhardt@amd.com
1758879Ssteve.reinhardt@amd.com    /** Commit to fetch delay, in ticks. */
1768879Ssteve.reinhardt@amd.com    unsigned commitToFetchDelay;
17710458Sandreas.hansson@arm.com
17810458Sandreas.hansson@arm.com    /** The width of fetch in instructions. */
17910458Sandreas.hansson@arm.com    unsigned fetchWidth;
1808879Ssteve.reinhardt@amd.com
1818879Ssteve.reinhardt@amd.com    /** Cache block size. */
1828879Ssteve.reinhardt@amd.com    int cacheBlkSize;
1838879Ssteve.reinhardt@amd.com
1849227Sandreas.hansson@arm.com    /** Mask to get a cache block's address. */
1859227Sandreas.hansson@arm.com    Addr cacheBlkMask;
18612063Sgabeblack@google.com
18712063Sgabeblack@google.com    /** The instruction being fetched. */
18812063Sgabeblack@google.com//    MachInst inst;
1898879Ssteve.reinhardt@amd.com
1908879Ssteve.reinhardt@amd.com    /** The cache line being fetched. */
1918879Ssteve.reinhardt@amd.com    uint8_t *cacheData;
1928879Ssteve.reinhardt@amd.com
19310453SAndrew.Bardsley@arm.com    /** Size of instructions. */
19410453SAndrew.Bardsley@arm.com    int instSize;
19510453SAndrew.Bardsley@arm.com
19610456SCurtis.Dunham@arm.com    /** Icache stall statistics. */
19710456SCurtis.Dunham@arm.com    Counter lastIcacheStall;
19810456SCurtis.Dunham@arm.com
19910457Sandreas.hansson@arm.com    Stats::Scalar<> icacheStallCycles;
20010457Sandreas.hansson@arm.com    Stats::Scalar<> fetchedInsts;
20111342Sandreas.hansson@arm.com    Stats::Scalar<> predictedBranches;
20211342Sandreas.hansson@arm.com    Stats::Scalar<> fetchCycles;
2038120Sgblack@eecs.umich.edu    Stats::Scalar<> fetchSquashCycles;
20412063Sgabeblack@google.com    Stats::Scalar<> fetchBlockedCycles;
20512063Sgabeblack@google.com    Stats::Scalar<> fetchedCacheLines;
20612063Sgabeblack@google.com
20712063Sgabeblack@google.com    Stats::Distribution<> fetch_nisn_dist;
2088947Sandreas.hansson@arm.com};
2097816Ssteve.reinhardt@amd.com
2105871Snate@binkert.org#endif //__CPU_BETA_CPU_SIMPLE_FETCH_HH__
2115871Snate@binkert.org