1/* |
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. |
27 */ 28 |
29#ifndef __CPU_O3_FETCH_HH__ 30#define __CPU_O3_FETCH_HH__ |
31 |
32#include "arch/utility.hh" |
33#include "base/statistics.hh" 34#include "base/timebuf.hh" 35#include "cpu/pc_event.hh" |
36#include "mem/packet.hh" 37#include "mem/port.hh" |
38#include "sim/eventq.hh" 39 |
40class Sampler; 41 |
42/** |
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. |
49 */ |
50template <class Impl> |
51class DefaultFetch |
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. */ |
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; |
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 |
96 public: |
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 { |
107 Running, 108 Idle, 109 Squashing, 110 Blocked, |
111 Fetching, 112 TrapPending, 113 QuiescePending, 114 SwitchOut, 115 IcacheWaitResponse, 116 IcacheRetry, 117 IcacheAccessComplete |
118 }; 119 |
120 /** Fetching Policy, Add new policies here.*/ 121 enum FetchPriority { 122 SingleThread, 123 RoundRobin, 124 Branch, 125 IQ, 126 LSQ 127 }; |
128 |
129 private: 130 /** Fetch status. */ 131 FetchStatus _status; |
132 |
133 /** Per-thread status. */ 134 ThreadStatus fetchStatus[Impl::MaxThreads]; |
135 |
136 /** Fetch policy. */ 137 FetchPriority fetchPolicy; |
138 |
139 /** List that has the threads organized by priority. */ 140 std::list<unsigned> priorityList; |
141 142 public: |
143 /** DefaultFetch constructor. */ 144 DefaultFetch(Params *params); |
145 |
146 /** Returns the name of fetch. */ 147 std::string name() const; 148 149 /** Registers statistics. */ |
150 void regStats(); 151 |
152 /** Sets CPU pointer. */ |
153 void setCPU(FullCPU *cpu_ptr); 154 |
155 /** Sets the main backwards communication time buffer pointer. */ |
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. */ |
162 void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr); 163 |
164 /** Sets pointer to page table. */ 165// void setPageTable(PageTable *pt_ptr); |
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 |
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 |
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. |
212 * @return Any fault that occured. 213 */ |
214 bool fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid); |
215 |
216 /** Squashes a specific thread and resets the PC. */ 217 inline void doSquash(const Addr &new_PC, unsigned tid); |
218 |
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); |
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 |
232 public: |
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); |
238 |
239 /** Ticks the fetch stage, processing all inputs signals and fetching 240 * as many instructions as possible. 241 */ |
242 void tick(); 243 |
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); |
248 |
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. */ |
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: |
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 |
307 /** Icache interface. */ |
308 IcachePort *icachePort; |
309 310 /** BPredUnit. */ 311 BPredUnit branchPred; 312 |
313 Addr PC[Impl::MaxThreads]; |
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 |
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. */ |
361 uint8_t *cacheData[Impl::MaxThreads]; |
362 363 /** Size of instructions. */ 364 int instSize; 365 366 /** Icache stall statistics. */ |
367 Counter lastIcacheStall[Impl::MaxThreads]; |
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. */ |
392 Stats::Scalar<> icacheStallCycles; |
393 /** Stat for total number of fetched instructions. */ |
394 Stats::Scalar<> fetchedInsts; |
395 Stats::Scalar<> fetchedBranches; 396 /** Stat for total number of predicted branches. */ |
397 Stats::Scalar<> predictedBranches; |
398 /** Stat for total number of cycles spent fetching. */ |
399 Stats::Scalar<> fetchCycles; |
400 /** Stat for total number of cycles spent squashing. */ |
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; |
406 Stats::Scalar<> fetchBlockedCycles; |
407 408 Stats::Scalar<> fetchMiscStallCycles; 409 /** Stat for total number of fetched cache lines. */ |
410 Stats::Scalar<> fetchedCacheLines; 411 |
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; |
418}; 419 |
420#endif //__CPU_O3_FETCH_HH__ |