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 ¶ms); | 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__ |