fetch.hh (2665:a124942bacb8) fetch.hh (2669:f2b336e89d2a)
1/*
1/*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
2 * Copyright (c) 2004-2006 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

--- 8 unchanged lines hidden (view full) ---

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.
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

--- 8 unchanged lines hidden (view full) ---

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 * Authors: Kevin Lim
29 */
30
27 */
28
31// Todo: SMT fetch,
32// Add a way to get a stage's current status.
29#ifndef __CPU_O3_FETCH_HH__
30#define __CPU_O3_FETCH_HH__
33
31
34#ifndef __CPU_O3_CPU_SIMPLE_FETCH_HH__
35#define __CPU_O3_CPU_SIMPLE_FETCH_HH__
36
32#include "arch/utility.hh"
37#include "base/statistics.hh"
38#include "base/timebuf.hh"
39#include "cpu/pc_event.hh"
33#include "base/statistics.hh"
34#include "base/timebuf.hh"
35#include "cpu/pc_event.hh"
40#include "mem/mem_interface.hh"
36#include "mem/packet.hh"
37#include "mem/port.hh"
41#include "sim/eventq.hh"
42
38#include "sim/eventq.hh"
39
40class Sampler;
41
43/**
42/**
44 * SimpleFetch class to fetch a single instruction each cycle. SimpleFetch
45 * will stall if there's an Icache miss, but otherwise assumes a one cycle
46 * Icache hit.
43 * DefaultFetch class handles both single threaded and SMT fetch. Its
44 * width is specified by the parameters; each cycle it tries to fetch
45 * that many instructions. It supports using a branch predictor to
46 * predict direction and targets.
47 * It supports the idling functionalitiy of the CPU by indicating to
48 * the CPU when it is active and inactive.
47 */
49 */
48
49template <class Impl>
50template <class Impl>
50class SimpleFetch
51class DefaultFetch
51{
52 public:
53 /** Typedefs from Impl. */
54 typedef typename Impl::CPUPol CPUPol;
55 typedef typename Impl::DynInst DynInst;
56 typedef typename Impl::DynInstPtr DynInstPtr;
57 typedef typename Impl::FullCPU FullCPU;
58 typedef typename Impl::Params Params;
59
52{
53 public:
54 /** Typedefs from Impl. */
55 typedef typename Impl::CPUPol CPUPol;
56 typedef typename Impl::DynInst DynInst;
57 typedef typename Impl::DynInstPtr DynInstPtr;
58 typedef typename Impl::FullCPU FullCPU;
59 typedef typename Impl::Params Params;
60
61 /** Typedefs from the CPU policy. */
60 typedef typename CPUPol::BPredUnit BPredUnit;
61 typedef typename CPUPol::FetchStruct FetchStruct;
62 typedef typename CPUPol::TimeStruct TimeStruct;
63
64 /** Typedefs from ISA. */
65 typedef TheISA::MachInst MachInst;
62 typedef typename CPUPol::BPredUnit BPredUnit;
63 typedef typename CPUPol::FetchStruct FetchStruct;
64 typedef typename CPUPol::TimeStruct TimeStruct;
65
66 /** Typedefs from ISA. */
67 typedef TheISA::MachInst MachInst;
68 typedef TheISA::ExtMachInst ExtMachInst;
66
69
70 class IcachePort : public Port
71 {
72 protected:
73 DefaultFetch<Impl> *fetch;
74
75 public:
76 IcachePort(DefaultFetch<Impl> *_fetch)
77 : Port(_fetch->name() + "-iport"), fetch(_fetch)
78 { }
79
80 protected:
81 virtual Tick recvAtomic(PacketPtr pkt);
82
83 virtual void recvFunctional(PacketPtr pkt);
84
85 virtual void recvStatusChange(Status status);
86
87 virtual void getDeviceAddressRanges(AddrRangeList &resp,
88 AddrRangeList &snoop)
89 { resp.clear(); snoop.clear(); }
90
91 virtual bool recvTiming(PacketPtr pkt);
92
93 virtual void recvRetry();
94 };
95
67 public:
96 public:
68 enum Status {
97 /** Overall fetch status. Used to determine if the CPU can
98 * deschedule itsef due to a lack of activity.
99 */
100 enum FetchStatus {
101 Active,
102 Inactive
103 };
104
105 /** Individual thread status. */
106 enum ThreadStatus {
69 Running,
70 Idle,
71 Squashing,
72 Blocked,
107 Running,
108 Idle,
109 Squashing,
110 Blocked,
73 IcacheMissStall,
74 IcacheMissComplete
111 Fetching,
112 TrapPending,
113 QuiescePending,
114 SwitchOut,
115 IcacheWaitResponse,
116 IcacheRetry,
117 IcacheAccessComplete
75 };
76
118 };
119
77 // May eventually need statuses on a per thread basis.
78 Status _status;
120 /** Fetching Policy, Add new policies here.*/
121 enum FetchPriority {
122 SingleThread,
123 RoundRobin,
124 Branch,
125 IQ,
126 LSQ
127 };
79
128
80 bool stalled;
129 private:
130 /** Fetch status. */
131 FetchStatus _status;
81
132
82 public:
83 class CacheCompletionEvent : public Event
84 {
85 private:
86 SimpleFetch *fetch;
133 /** Per-thread status. */
134 ThreadStatus fetchStatus[Impl::MaxThreads];
87
135
88 public:
89 CacheCompletionEvent(SimpleFetch *_fetch);
136 /** Fetch policy. */
137 FetchPriority fetchPolicy;
90
138
91 virtual void process();
92 virtual const char *description();
93 };
139 /** List that has the threads organized by priority. */
140 std::list<unsigned> priorityList;
94
95 public:
141
142 public:
96 /** SimpleFetch constructor. */
97 SimpleFetch(Params &params);
143 /** DefaultFetch constructor. */
144 DefaultFetch(Params *params);
98
145
146 /** Returns the name of fetch. */
147 std::string name() const;
148
149 /** Registers statistics. */
99 void regStats();
100
150 void regStats();
151
152 /** Sets CPU pointer. */
101 void setCPU(FullCPU *cpu_ptr);
102
153 void setCPU(FullCPU *cpu_ptr);
154
155 /** Sets the main backwards communication time buffer pointer. */
103 void setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer);
104
156 void setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer);
157
158 /** Sets pointer to list of active threads. */
159 void setActiveThreads(std::list<unsigned> *at_ptr);
160
161 /** Sets pointer to time buffer used to communicate to the next stage. */
105 void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr);
106
162 void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr);
163
107 void processCacheCompletion();
164 /** Sets pointer to page table. */
165// void setPageTable(PageTable *pt_ptr);
108
166
167 /** Initialize stage. */
168 void initStage();
169
170 /** Processes cache completion event. */
171 void processCacheCompletion(PacketPtr pkt);
172
173 void switchOut();
174
175 void doSwitchOut();
176
177 void takeOverFrom();
178
179 bool isSwitchedOut() { return switchedOut; }
180
181 void wakeFromQuiesce();
182
109 private:
183 private:
184 /** Changes the status of this stage to active, and indicates this
185 * to the CPU.
186 */
187 inline void switchToActive();
188
189 /** Changes the status of this stage to inactive, and indicates
190 * this to the CPU.
191 */
192 inline void switchToInactive();
193
110 /**
111 * Looks up in the branch predictor to see if the next PC should be
112 * either next PC+=MachInst or a branch target.
113 * @param next_PC Next PC variable passed in by reference. It is
114 * expected to be set to the current PC; it will be updated with what
115 * the next PC will be.
116 * @return Whether or not a branch was predicted as taken.
117 */
118 bool lookupAndUpdateNextPC(DynInstPtr &inst, Addr &next_PC);
119
120 /**
121 * Fetches the cache line that contains fetch_PC. Returns any
122 * fault that happened. Puts the data into the class variable
123 * cacheData.
124 * @param fetch_PC The PC address that is being fetched from.
194 /**
195 * Looks up in the branch predictor to see if the next PC should be
196 * either next PC+=MachInst or a branch target.
197 * @param next_PC Next PC variable passed in by reference. It is
198 * expected to be set to the current PC; it will be updated with what
199 * the next PC will be.
200 * @return Whether or not a branch was predicted as taken.
201 */
202 bool lookupAndUpdateNextPC(DynInstPtr &inst, Addr &next_PC);
203
204 /**
205 * Fetches the cache line that contains fetch_PC. Returns any
206 * fault that happened. Puts the data into the class variable
207 * cacheData.
208 * @param fetch_PC The PC address that is being fetched from.
209 * @param ret_fault The fault reference that will be set to the result of
210 * the icache access.
211 * @param tid Thread id.
125 * @return Any fault that occured.
126 */
212 * @return Any fault that occured.
213 */
127 Fault fetchCacheLine(Addr fetch_PC);
214 bool fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid);
128
215
129 inline void doSquash(const Addr &new_PC);
216 /** Squashes a specific thread and resets the PC. */
217 inline void doSquash(const Addr &new_PC, unsigned tid);
130
218
131 void squashFromDecode(const Addr &new_PC, const InstSeqNum &seq_num);
219 /** Squashes a specific thread and resets the PC. Also tells the CPU to
220 * remove any instructions between fetch and decode that should be sqaushed.
221 */
222 void squashFromDecode(const Addr &new_PC, const InstSeqNum &seq_num,
223 unsigned tid);
132
224
225 /** Checks if a thread is stalled. */
226 bool checkStall(unsigned tid) const;
227
228 /** Updates overall fetch stage status; to be called at the end of each
229 * cycle. */
230 FetchStatus updateFetchStatus();
231
133 public:
232 public:
134 // Figure out PC vs next PC and how it should be updated
135 void squash(const Addr &new_PC);
233 /** Squashes a specific thread and resets the PC. Also tells the CPU to
234 * remove any instructions that are not in the ROB. The source of this
235 * squash should be the commit stage.
236 */
237 void squash(const Addr &new_PC, unsigned tid);
136
238
239 /** Ticks the fetch stage, processing all inputs signals and fetching
240 * as many instructions as possible.
241 */
137 void tick();
138
242 void tick();
243
139 void fetch();
244 /** Checks all input signals and updates the status as necessary.
245 * @return: Returns if the status has changed due to input signals.
246 */
247 bool checkSignalsAndUpdate(unsigned tid);
140
248
141 // Align an address (typically a PC) to the start of an I-cache block.
142 // We fold in the PISA 64- to 32-bit conversion here as well.
249 /** Does the actual fetching of instructions and passing them on to the
250 * next stage.
251 * @param status_change fetch() sets this variable if there was a status
252 * change (ie switching to IcacheMissStall).
253 */
254 void fetch(bool &status_change);
255
256 /** Align a PC to the start of an I-cache block. */
143 Addr icacheBlockAlignPC(Addr addr)
144 {
145 addr = TheISA::realPCToFetchPC(addr);
146 return (addr & ~(cacheBlkMask));
147 }
148
149 private:
257 Addr icacheBlockAlignPC(Addr addr)
258 {
259 addr = TheISA::realPCToFetchPC(addr);
260 return (addr & ~(cacheBlkMask));
261 }
262
263 private:
264 /** Returns the appropriate thread to fetch, given the fetch policy. */
265 int getFetchingThread(FetchPriority &fetch_priority);
266
267 /** Returns the appropriate thread to fetch using a round robin policy. */
268 int roundRobin();
269
270 /** Returns the appropriate thread to fetch using the IQ count policy. */
271 int iqCount();
272
273 /** Returns the appropriate thread to fetch using the LSQ count policy. */
274 int lsqCount();
275
276 /** Returns the appropriate thread to fetch using the branch count policy. */
277 int branchCount();
278
279 private:
150 /** Pointer to the FullCPU. */
151 FullCPU *cpu;
152
153 /** Time buffer interface. */
154 TimeBuffer<TimeStruct> *timeBuffer;
155
156 /** Wire to get decode's information from backwards time buffer. */
157 typename TimeBuffer<TimeStruct>::wire fromDecode;

--- 9 unchanged lines hidden (view full) ---

167
168 /** Internal fetch instruction queue. */
169 TimeBuffer<FetchStruct> *fetchQueue;
170
171 //Might be annoying how this name is different than the queue.
172 /** Wire used to write any information heading to decode. */
173 typename TimeBuffer<FetchStruct>::wire toDecode;
174
280 /** Pointer to the FullCPU. */
281 FullCPU *cpu;
282
283 /** Time buffer interface. */
284 TimeBuffer<TimeStruct> *timeBuffer;
285
286 /** Wire to get decode's information from backwards time buffer. */
287 typename TimeBuffer<TimeStruct>::wire fromDecode;

--- 9 unchanged lines hidden (view full) ---

297
298 /** Internal fetch instruction queue. */
299 TimeBuffer<FetchStruct> *fetchQueue;
300
301 //Might be annoying how this name is different than the queue.
302 /** Wire used to write any information heading to decode. */
303 typename TimeBuffer<FetchStruct>::wire toDecode;
304
305 MemObject *mem;
306
175 /** Icache interface. */
307 /** Icache interface. */
176 MemInterface *icacheInterface;
308 IcachePort *icachePort;
177
178 /** BPredUnit. */
179 BPredUnit branchPred;
180
309
310 /** BPredUnit. */
311 BPredUnit branchPred;
312
181 /** Memory request used to access cache. */
182 MemReqPtr memReq;
313 Addr PC[Impl::MaxThreads];
183
314
315 Addr nextPC[Impl::MaxThreads];
316
317 /** Memory packet used to access cache. */
318 PacketPtr memPkt[Impl::MaxThreads];
319
320 /** Variable that tracks if fetch has written to the time buffer this
321 * cycle. Used to tell CPU if there is activity this cycle.
322 */
323 bool wroteToTimeBuffer;
324
325 /** Tracks how many instructions has been fetched this cycle. */
326 int numInst;
327
328 /** Source of possible stalls. */
329 struct Stalls {
330 bool decode;
331 bool rename;
332 bool iew;
333 bool commit;
334 };
335
336 /** Tracks which stages are telling fetch to stall. */
337 Stalls stalls[Impl::MaxThreads];
338
184 /** Decode to fetch delay, in ticks. */
185 unsigned decodeToFetchDelay;
186
187 /** Rename to fetch delay, in ticks. */
188 unsigned renameToFetchDelay;
189
190 /** IEW to fetch delay, in ticks. */
191 unsigned iewToFetchDelay;

--- 6 unchanged lines hidden (view full) ---

198
199 /** Cache block size. */
200 int cacheBlkSize;
201
202 /** Mask to get a cache block's address. */
203 Addr cacheBlkMask;
204
205 /** The cache line being fetched. */
339 /** Decode to fetch delay, in ticks. */
340 unsigned decodeToFetchDelay;
341
342 /** Rename to fetch delay, in ticks. */
343 unsigned renameToFetchDelay;
344
345 /** IEW to fetch delay, in ticks. */
346 unsigned iewToFetchDelay;

--- 6 unchanged lines hidden (view full) ---

353
354 /** Cache block size. */
355 int cacheBlkSize;
356
357 /** Mask to get a cache block's address. */
358 Addr cacheBlkMask;
359
360 /** The cache line being fetched. */
206 uint8_t *cacheData;
361 uint8_t *cacheData[Impl::MaxThreads];
207
208 /** Size of instructions. */
209 int instSize;
210
211 /** Icache stall statistics. */
362
363 /** Size of instructions. */
364 int instSize;
365
366 /** Icache stall statistics. */
212 Counter lastIcacheStall;
367 Counter lastIcacheStall[Impl::MaxThreads];
213
368
369 /** List of Active Threads */
370 std::list<unsigned> *activeThreads;
371
372 /** Number of threads. */
373 unsigned numThreads;
374
375 /** Number of threads that are actively fetching. */
376 unsigned numFetchingThreads;
377
378 /** Thread ID being fetched. */
379 int threadFetched;
380
381 bool interruptPending;
382
383 bool switchedOut;
384
385#if !FULL_SYSTEM
386 /** Page table pointer. */
387// PageTable *pTable;
388#endif
389
390 // @todo: Consider making these vectors and tracking on a per thread basis.
391 /** Stat for total number of cycles stalled due to an icache miss. */
214 Stats::Scalar<> icacheStallCycles;
392 Stats::Scalar<> icacheStallCycles;
393 /** Stat for total number of fetched instructions. */
215 Stats::Scalar<> fetchedInsts;
394 Stats::Scalar<> fetchedInsts;
395 Stats::Scalar<> fetchedBranches;
396 /** Stat for total number of predicted branches. */
216 Stats::Scalar<> predictedBranches;
397 Stats::Scalar<> predictedBranches;
398 /** Stat for total number of cycles spent fetching. */
217 Stats::Scalar<> fetchCycles;
399 Stats::Scalar<> fetchCycles;
400 /** Stat for total number of cycles spent squashing. */
218 Stats::Scalar<> fetchSquashCycles;
401 Stats::Scalar<> fetchSquashCycles;
402 /** Stat for total number of cycles spent blocked due to other stages in
403 * the pipeline.
404 */
405 Stats::Scalar<> fetchIdleCycles;
219 Stats::Scalar<> fetchBlockedCycles;
406 Stats::Scalar<> fetchBlockedCycles;
407
408 Stats::Scalar<> fetchMiscStallCycles;
409 /** Stat for total number of fetched cache lines. */
220 Stats::Scalar<> fetchedCacheLines;
221
410 Stats::Scalar<> fetchedCacheLines;
411
222 Stats::Distribution<> fetch_nisn_dist;
412 Stats::Scalar<> fetchIcacheSquashes;
413 /** Distribution of number of instructions fetched each cycle. */
414 Stats::Distribution<> fetchNisnDist;
415 Stats::Formula idleRate;
416 Stats::Formula branchRate;
417 Stats::Formula fetchRate;
223};
224
418};
419
225#endif //__CPU_O3_CPU_SIMPLE_FETCH_HH__
420#endif //__CPU_O3_FETCH_HH__