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 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.
| 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 * 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; 158 159 /** Wire to get rename's information from backwards time buffer. */ 160 typename TimeBuffer<TimeStruct>::wire fromRename; 161 162 /** Wire to get iew's information from backwards time buffer. */ 163 typename TimeBuffer<TimeStruct>::wire fromIEW; 164 165 /** Wire to get commit's information from backwards time buffer. */ 166 typename TimeBuffer<TimeStruct>::wire fromCommit; 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; 288 289 /** Wire to get rename's information from backwards time buffer. */ 290 typename TimeBuffer<TimeStruct>::wire fromRename; 291 292 /** Wire to get iew's information from backwards time buffer. */ 293 typename TimeBuffer<TimeStruct>::wire fromIEW; 294 295 /** Wire to get commit's information from backwards time buffer. */ 296 typename TimeBuffer<TimeStruct>::wire fromCommit; 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; 192 193 /** Commit to fetch delay, in ticks. */ 194 unsigned commitToFetchDelay; 195 196 /** The width of fetch in instructions. */ 197 unsigned fetchWidth; 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; 347 348 /** Commit to fetch delay, in ticks. */ 349 unsigned commitToFetchDelay; 350 351 /** The width of fetch in instructions. */ 352 unsigned fetchWidth; 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__
|
| |