fetch.hh revision 2132
1/*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29// Todo: SMT fetch,
30// Add a way to get a stage's current status.
31
32#ifndef __CPU_O3_CPU_SIMPLE_FETCH_HH__
33#define __CPU_O3_CPU_SIMPLE_FETCH_HH__
34
35#include "base/statistics.hh"
36#include "base/timebuf.hh"
37#include "cpu/pc_event.hh"
38#include "mem/mem_interface.hh"
39#include "sim/eventq.hh"
40
41/**
42 * SimpleFetch class to fetch a single instruction each cycle.  SimpleFetch
43 * will stall if there's an Icache miss, but otherwise assumes a one cycle
44 * Icache hit.
45 */
46
47template <class Impl>
48class SimpleFetch
49{
50  public:
51    /** Typedefs from Impl. */
52    typedef typename Impl::CPUPol CPUPol;
53    typedef typename Impl::DynInst DynInst;
54    typedef typename Impl::DynInstPtr DynInstPtr;
55    typedef typename Impl::FullCPU FullCPU;
56    typedef typename Impl::Params Params;
57
58    typedef typename CPUPol::BPredUnit BPredUnit;
59    typedef typename CPUPol::FetchStruct FetchStruct;
60    typedef typename CPUPol::TimeStruct TimeStruct;
61
62    /** Typedefs from ISA. */
63    typedef TheISA::MachInst MachInst;
64
65  public:
66    enum Status {
67        Running,
68        Idle,
69        Squashing,
70        Blocked,
71        IcacheMissStall,
72        IcacheMissComplete
73    };
74
75    // May eventually need statuses on a per thread basis.
76    Status _status;
77
78    bool stalled;
79
80  public:
81    class CacheCompletionEvent : public Event
82    {
83      private:
84        SimpleFetch *fetch;
85
86      public:
87        CacheCompletionEvent(SimpleFetch *_fetch);
88
89        virtual void process();
90        virtual const char *description();
91    };
92
93  public:
94    /** SimpleFetch constructor. */
95    SimpleFetch(Params &params);
96
97    void regStats();
98
99    void setCPU(FullCPU *cpu_ptr);
100
101    void setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer);
102
103    void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr);
104
105    void processCacheCompletion();
106
107  private:
108    /**
109     * Looks up in the branch predictor to see if the next PC should be
110     * either next PC+=MachInst or a branch target.
111     * @param next_PC Next PC variable passed in by reference.  It is
112     * expected to be set to the current PC; it will be updated with what
113     * the next PC will be.
114     * @return Whether or not a branch was predicted as taken.
115     */
116    bool lookupAndUpdateNextPC(DynInstPtr &inst, Addr &next_PC);
117
118    /**
119     * Fetches the cache line that contains fetch_PC.  Returns any
120     * fault that happened.  Puts the data into the class variable
121     * cacheData.
122     * @param fetch_PC The PC address that is being fetched from.
123     * @return Any fault that occured.
124     */
125    Fault fetchCacheLine(Addr fetch_PC);
126
127    inline void doSquash(const Addr &new_PC);
128
129    void squashFromDecode(const Addr &new_PC, const InstSeqNum &seq_num);
130
131  public:
132    // Figure out PC vs next PC and how it should be updated
133    void squash(const Addr &new_PC);
134
135    void tick();
136
137    void fetch();
138
139    // Align an address (typically a PC) to the start of an I-cache block.
140    // We fold in the PISA 64- to 32-bit conversion here as well.
141    Addr icacheBlockAlignPC(Addr addr)
142    {
143        addr = TheISA::realPCToFetchPC(addr);
144        return (addr & ~(cacheBlkMask));
145    }
146
147  private:
148    /** Pointer to the FullCPU. */
149    FullCPU *cpu;
150
151    /** Time buffer interface. */
152    TimeBuffer<TimeStruct> *timeBuffer;
153
154    /** Wire to get decode's information from backwards time buffer. */
155    typename TimeBuffer<TimeStruct>::wire fromDecode;
156
157    /** Wire to get rename's information from backwards time buffer. */
158    typename TimeBuffer<TimeStruct>::wire fromRename;
159
160    /** Wire to get iew's information from backwards time buffer. */
161    typename TimeBuffer<TimeStruct>::wire fromIEW;
162
163    /** Wire to get commit's information from backwards time buffer. */
164    typename TimeBuffer<TimeStruct>::wire fromCommit;
165
166    /** Internal fetch instruction queue. */
167    TimeBuffer<FetchStruct> *fetchQueue;
168
169    //Might be annoying how this name is different than the queue.
170    /** Wire used to write any information heading to decode. */
171    typename TimeBuffer<FetchStruct>::wire toDecode;
172
173    /** Icache interface. */
174    MemInterface *icacheInterface;
175
176    /** BPredUnit. */
177    BPredUnit branchPred;
178
179    /** Memory request used to access cache. */
180    MemReqPtr memReq;
181
182    /** Decode to fetch delay, in ticks. */
183    unsigned decodeToFetchDelay;
184
185    /** Rename to fetch delay, in ticks. */
186    unsigned renameToFetchDelay;
187
188    /** IEW to fetch delay, in ticks. */
189    unsigned iewToFetchDelay;
190
191    /** Commit to fetch delay, in ticks. */
192    unsigned commitToFetchDelay;
193
194    /** The width of fetch in instructions. */
195    unsigned fetchWidth;
196
197    /** Cache block size. */
198    int cacheBlkSize;
199
200    /** Mask to get a cache block's address. */
201    Addr cacheBlkMask;
202
203    /** The cache line being fetched. */
204    uint8_t *cacheData;
205
206    /** Size of instructions. */
207    int instSize;
208
209    /** Icache stall statistics. */
210    Counter lastIcacheStall;
211
212    Stats::Scalar<> icacheStallCycles;
213    Stats::Scalar<> fetchedInsts;
214    Stats::Scalar<> predictedBranches;
215    Stats::Scalar<> fetchCycles;
216    Stats::Scalar<> fetchSquashCycles;
217    Stats::Scalar<> fetchBlockedCycles;
218    Stats::Scalar<> fetchedCacheLines;
219
220    Stats::Distribution<> fetch_nisn_dist;
221};
222
223#endif //__CPU_O3_CPU_SIMPLE_FETCH_HH__
224