fetch.hh revision 1461
1// Todo: add in statistics, only get the MachInst and let decode actually
2// decode, think about SMT fetch,
3// fix up branch prediction stuff into one thing,
4// Figure out where to advance time buffer.  Add a way to get a
5// stage's current status.
6
7#ifndef __CPU_BETA_CPU_SIMPLE_FETCH_HH__
8#define __CPU_BETA_CPU_SIMPLE_FETCH_HH__
9
10//Will want to include: time buffer, structs, MemInterface, Event,
11//whatever class bzero uses, MemReqPtr
12
13#include "base/statistics.hh"
14#include "base/timebuf.hh"
15#include "cpu/pc_event.hh"
16#include "mem/mem_interface.hh"
17#include "sim/eventq.hh"
18
19/**
20 * SimpleFetch class to fetch a single instruction each cycle.  SimpleFetch
21 * will stall if there's an Icache miss, but otherwise assumes a one cycle
22 * Icache hit.
23 */
24
25template <class Impl>
26class SimpleFetch
27{
28  public:
29    /** Typedefs from Impl. */
30    typedef typename Impl::ISA ISA;
31    typedef typename Impl::CPUPol CPUPol;
32    typedef typename Impl::DynInst DynInst;
33    typedef typename Impl::DynInstPtr DynInstPtr;
34    typedef typename Impl::FullCPU FullCPU;
35    typedef typename Impl::Params Params;
36
37    typedef typename CPUPol::BPredUnit BPredUnit;
38    typedef typename CPUPol::FetchStruct FetchStruct;
39    typedef typename CPUPol::TimeStruct TimeStruct;
40
41    /** Typedefs from ISA. */
42    typedef typename ISA::MachInst MachInst;
43
44  public:
45    enum Status {
46        Running,
47        Idle,
48        Squashing,
49        Blocked,
50        IcacheMissStall,
51        IcacheMissComplete
52    };
53
54    // May eventually need statuses on a per thread basis.
55    Status _status;
56
57    bool stalled;
58
59  public:
60    /** SimpleFetch constructor. */
61    SimpleFetch(Params &params);
62
63    void regStats();
64
65    void setCPU(FullCPU *cpu_ptr);
66
67    void setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer);
68
69    void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr);
70
71    void tick();
72
73    void fetch();
74
75    void processCacheCompletion();
76
77//  private:
78    // Figure out PC vs next PC and how it should be updated
79    void squash(const Addr &new_PC);
80
81  private:
82    inline void doSquash(const Addr &new_PC);
83
84    void squashFromDecode(const Addr &new_PC, const InstSeqNum &seq_num);
85
86    /**
87     * Looks up in the branch predictor to see if the next PC should be
88     * either next PC+=MachInst or a branch target.
89     * @params next_PC Next PC variable passed in by reference.  It is
90     * expected to be set to the current PC; it will be updated with what
91     * the next PC will be.
92     * @return Whether or not a branch was predicted as taken.
93     */
94    bool lookupAndUpdateNextPC(DynInstPtr &inst, Addr &next_PC);
95
96    // Might not want this function...
97//    inline void recordGlobalHist(DynInstPtr &inst);
98
99    /**
100     * Fetches the cache line that contains fetch_PC.  Returns any
101     * fault that happened.  Puts the data into the class variable
102     * cacheData.
103     * @params fetch_PC The PC address that is being fetched from.
104     * @return Any fault that occured.
105     */
106    Fault fetchCacheLine(Addr fetch_PC);
107
108    // Align an address (typically a PC) to the start of an I-cache block.
109    // We fold in the PISA 64- to 32-bit conversion here as well.
110    Addr icacheBlockAlignPC(Addr addr)
111    {
112        addr = ISA::realPCToFetchPC(addr);
113        return (addr & ~(cacheBlkMask));
114    }
115
116  public:
117    class CacheCompletionEvent : public Event
118    {
119      private:
120        SimpleFetch *fetch;
121
122      public:
123        CacheCompletionEvent(SimpleFetch *_fetch);
124
125        virtual void process();
126        virtual const char *description();
127    };
128
129//    CacheCompletionEvent cacheCompletionEvent;
130
131  private:
132    /** Pointer to the FullCPU. */
133    FullCPU *cpu;
134
135    /** Time buffer interface. */
136    TimeBuffer<TimeStruct> *timeBuffer;
137
138    /** Wire to get decode's information from backwards time buffer. */
139    typename TimeBuffer<TimeStruct>::wire fromDecode;
140
141    /** Wire to get rename's information from backwards time buffer. */
142    typename TimeBuffer<TimeStruct>::wire fromRename;
143
144    /** Wire to get iew's information from backwards time buffer. */
145    typename TimeBuffer<TimeStruct>::wire fromIEW;
146
147    /** Wire to get commit's information from backwards time buffer. */
148    typename TimeBuffer<TimeStruct>::wire fromCommit;
149
150    /** Internal fetch instruction queue. */
151    TimeBuffer<FetchStruct> *fetchQueue;
152
153    //Might be annoying how this name is different than the queue.
154    /** Wire used to write any information heading to decode. */
155    typename TimeBuffer<FetchStruct>::wire toDecode;
156
157    /** Icache interface. */
158    MemInterface *icacheInterface;
159
160    /** BPredUnit. */
161    BPredUnit branchPred;
162
163    /** Memory request used to access cache. */
164    MemReqPtr memReq;
165
166    /** Decode to fetch delay, in ticks. */
167    unsigned decodeToFetchDelay;
168
169    /** Rename to fetch delay, in ticks. */
170    unsigned renameToFetchDelay;
171
172    /** IEW to fetch delay, in ticks. */
173    unsigned iewToFetchDelay;
174
175    /** Commit to fetch delay, in ticks. */
176    unsigned commitToFetchDelay;
177
178    /** The width of fetch in instructions. */
179    unsigned fetchWidth;
180
181    /** Cache block size. */
182    int cacheBlkSize;
183
184    /** Mask to get a cache block's address. */
185    Addr cacheBlkMask;
186
187    /** The instruction being fetched. */
188//    MachInst inst;
189
190    /** The cache line being fetched. */
191    uint8_t *cacheData;
192
193    /** Size of instructions. */
194    int instSize;
195
196    /** Icache stall statistics. */
197    Counter lastIcacheStall;
198
199    Stats::Scalar<> icacheStallCycles;
200    Stats::Scalar<> fetchedInsts;
201    Stats::Scalar<> predictedBranches;
202    Stats::Scalar<> fetchCycles;
203    Stats::Scalar<> fetchSquashCycles;
204    Stats::Scalar<> fetchBlockedCycles;
205    Stats::Scalar<> fetchedCacheLines;
206
207    Stats::Distribution<> fetch_nisn_dist;
208};
209
210#endif //__CPU_BETA_CPU_SIMPLE_FETCH_HH__
211