fetch.hh revision 2329
112837Sgabeblack@google.com/* 212837Sgabeblack@google.com * Copyright (c) 2004-2006 The Regents of The University of Michigan 312837Sgabeblack@google.com * All rights reserved. 412837Sgabeblack@google.com * 512837Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 612837Sgabeblack@google.com * modification, are permitted provided that the following conditions are 712837Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 812837Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 912837Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 1012837Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1112837Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1212837Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1312837Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1412837Sgabeblack@google.com * this software without specific prior written permission. 1512837Sgabeblack@google.com * 1612837Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1712837Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1812837Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1912837Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2012837Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2112837Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2212837Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2312837Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2412837Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2512837Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2612837Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2712837Sgabeblack@google.com */ 2812837Sgabeblack@google.com 2912837Sgabeblack@google.com#ifndef __CPU_O3_FETCH_HH__ 3012837Sgabeblack@google.com#define __CPU_O3_FETCH_HH__ 3112837Sgabeblack@google.com 3212862Sgabeblack@google.com#include "base/statistics.hh" 3312837Sgabeblack@google.com#include "base/timebuf.hh" 3412862Sgabeblack@google.com#include "cpu/pc_event.hh" 3512956Sgabeblack@google.com#include "mem/mem_interface.hh" 3612862Sgabeblack@google.com#include "sim/eventq.hh" 3712837Sgabeblack@google.com 3812982Sgabeblack@google.comclass Sampler; 3913038Sgabeblack@google.com 4012956Sgabeblack@google.com/** 4112837Sgabeblack@google.com * DefaultFetch class handles both single threaded and SMT fetch. Its 4212861Sgabeblack@google.com * width is specified by the parameters; each cycle it tries to fetch 4312837Sgabeblack@google.com * that many instructions. It supports using a branch predictor to 4412949Sgabeblack@google.com * predict direction and targets. 4512949Sgabeblack@google.com * It supports the idling functionalitiy of the CPU by indicating to 4612837Sgabeblack@google.com * the CPU when it is active and inactive. 4712837Sgabeblack@google.com */ 4812837Sgabeblack@google.comtemplate <class Impl> 4912837Sgabeblack@google.comclass DefaultFetch 5012837Sgabeblack@google.com{ 5112837Sgabeblack@google.com public: 5212837Sgabeblack@google.com /** Typedefs from Impl. */ 5312837Sgabeblack@google.com typedef typename Impl::CPUPol CPUPol; 5412837Sgabeblack@google.com typedef typename Impl::DynInst DynInst; 5512837Sgabeblack@google.com typedef typename Impl::DynInstPtr DynInstPtr; 5612837Sgabeblack@google.com typedef typename Impl::FullCPU FullCPU; 5712837Sgabeblack@google.com typedef typename Impl::Params Params; 5812862Sgabeblack@google.com 5912862Sgabeblack@google.com /** Typedefs from the CPU policy. */ 6012862Sgabeblack@google.com typedef typename CPUPol::BPredUnit BPredUnit; 6112862Sgabeblack@google.com typedef typename CPUPol::FetchStruct FetchStruct; 6212862Sgabeblack@google.com typedef typename CPUPol::TimeStruct TimeStruct; 6312949Sgabeblack@google.com 6412949Sgabeblack@google.com /** Typedefs from ISA. */ 6513077Sgabeblack@google.com typedef TheISA::MachInst MachInst; 6613077Sgabeblack@google.com typedef TheISA::ExtMachInst ExtMachInst; 6713077Sgabeblack@google.com 6813077Sgabeblack@google.com public: 6912949Sgabeblack@google.com /** Overall fetch status. Used to determine if the CPU can 7012949Sgabeblack@google.com * deschedule itsef due to a lack of activity. 7112949Sgabeblack@google.com */ 7212949Sgabeblack@google.com enum FetchStatus { 7312862Sgabeblack@google.com Active, 7412862Sgabeblack@google.com Inactive 7512862Sgabeblack@google.com }; 7612862Sgabeblack@google.com 7712862Sgabeblack@google.com /** Individual thread status. */ 7812837Sgabeblack@google.com enum ThreadStatus { 7912837Sgabeblack@google.com Running, 8012837Sgabeblack@google.com Idle, 8112837Sgabeblack@google.com Squashing, 8212837Sgabeblack@google.com Blocked, 8312837Sgabeblack@google.com Fetching, 8412837Sgabeblack@google.com TrapPending, 8512837Sgabeblack@google.com QuiescePending, 8612837Sgabeblack@google.com SwitchOut, 8712837Sgabeblack@google.com IcacheMissStall, 8812837Sgabeblack@google.com IcacheMissComplete 8912837Sgabeblack@google.com }; 9012837Sgabeblack@google.com 9112837Sgabeblack@google.com /** Fetching Policy, Add new policies here.*/ 9212837Sgabeblack@google.com enum FetchPriority { 9312837Sgabeblack@google.com SingleThread, 9412837Sgabeblack@google.com RoundRobin, 9512837Sgabeblack@google.com Branch, 9612837Sgabeblack@google.com IQ, 9712837Sgabeblack@google.com LSQ 9812837Sgabeblack@google.com }; 9912837Sgabeblack@google.com 10012837Sgabeblack@google.com private: 10112837Sgabeblack@google.com /** Fetch status. */ 10212837Sgabeblack@google.com FetchStatus _status; 10312837Sgabeblack@google.com 10412837Sgabeblack@google.com /** Per-thread status. */ 10512837Sgabeblack@google.com ThreadStatus fetchStatus[Impl::MaxThreads]; 10612837Sgabeblack@google.com 10712837Sgabeblack@google.com /** Fetch policy. */ 10812837Sgabeblack@google.com FetchPriority fetchPolicy; 10912837Sgabeblack@google.com 11012837Sgabeblack@google.com /** List that has the threads organized by priority. */ 11112837Sgabeblack@google.com std::list<unsigned> priorityList; 11212837Sgabeblack@google.com 11312837Sgabeblack@google.com public: 11412837Sgabeblack@google.com class CacheCompletionEvent : public Event 11512862Sgabeblack@google.com { 11612837Sgabeblack@google.com private: 11712837Sgabeblack@google.com MemReqPtr req; 11812837Sgabeblack@google.com /** Pointer to fetch. */ 11912837Sgabeblack@google.com DefaultFetch *fetch; 12013038Sgabeblack@google.com /** Thread id. */ 12113038Sgabeblack@google.com// unsigned threadId; 12212837Sgabeblack@google.com 12313038Sgabeblack@google.com public: 12413038Sgabeblack@google.com /** Constructs a cache completion event, which tells fetch when the 12513038Sgabeblack@google.com * cache miss is complete. 12613038Sgabeblack@google.com */ 12713038Sgabeblack@google.com CacheCompletionEvent(MemReqPtr &_req, DefaultFetch *_fetch); 12813038Sgabeblack@google.com 12912837Sgabeblack@google.com /** Processes cache completion event. */ 13012861Sgabeblack@google.com virtual void process(); 13112861Sgabeblack@google.com /** Returns the description of the cache completion event. */ 13212837Sgabeblack@google.com virtual const char *description(); 13312837Sgabeblack@google.com }; 13412837Sgabeblack@google.com 13512837Sgabeblack@google.com public: 13612837Sgabeblack@google.com /** DefaultFetch constructor. */ 13712837Sgabeblack@google.com DefaultFetch(Params *params); 13812837Sgabeblack@google.com 13912837Sgabeblack@google.com /** Returns the name of fetch. */ 14012837Sgabeblack@google.com std::string name() const; 14112837Sgabeblack@google.com 14212837Sgabeblack@google.com /** Registers statistics. */ 14312837Sgabeblack@google.com void regStats(); 14412837Sgabeblack@google.com 14512837Sgabeblack@google.com /** Sets CPU pointer. */ 14612860Sgabeblack@google.com void setCPU(FullCPU *cpu_ptr); 14712860Sgabeblack@google.com 14812860Sgabeblack@google.com /** Sets the main backwards communication time buffer pointer. */ 14912962Sgabeblack@google.com void setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer); 15012961Sgabeblack@google.com 15112860Sgabeblack@google.com /** Sets pointer to list of active threads. */ 15212860Sgabeblack@google.com void setActiveThreads(std::list<unsigned> *at_ptr); 15312860Sgabeblack@google.com 15412860Sgabeblack@google.com /** Sets pointer to time buffer used to communicate to the next stage. */ 15512860Sgabeblack@google.com void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr); 15612990Sgabeblack@google.com 15712961Sgabeblack@google.com /** Sets pointer to page table. */ 15812860Sgabeblack@google.com// void setPageTable(PageTable *pt_ptr); 15912860Sgabeblack@google.com 16012860Sgabeblack@google.com /** Initialize stage. */ 16112860Sgabeblack@google.com void initStage(); 16212860Sgabeblack@google.com 16313061Sgabeblack@google.com /** Processes cache completion event. */ 16413061Sgabeblack@google.com void processCacheCompletion(MemReqPtr &req); 16513061Sgabeblack@google.com 16613061Sgabeblack@google.com void switchOut(); 16713061Sgabeblack@google.com 16813061Sgabeblack@google.com void doSwitchOut(); 16912860Sgabeblack@google.com 17012860Sgabeblack@google.com void takeOverFrom(); 17112860Sgabeblack@google.com 17212860Sgabeblack@google.com bool isSwitchedOut() { return switchedOut; } 17312860Sgabeblack@google.com 17412861Sgabeblack@google.com void wakeFromQuiesce(); 17512861Sgabeblack@google.com 17612861Sgabeblack@google.com private: 17712861Sgabeblack@google.com /** Changes the status of this stage to active, and indicates this 17812861Sgabeblack@google.com * to the CPU. 17912861Sgabeblack@google.com */ 18012860Sgabeblack@google.com inline void switchToActive(); 18112860Sgabeblack@google.com 18212860Sgabeblack@google.com /** Changes the status of this stage to inactive, and indicates 18312860Sgabeblack@google.com * this to the CPU. 18412860Sgabeblack@google.com */ 18512861Sgabeblack@google.com inline void switchToInactive(); 18612860Sgabeblack@google.com 18712860Sgabeblack@google.com /** 18812860Sgabeblack@google.com * Looks up in the branch predictor to see if the next PC should be 18912860Sgabeblack@google.com * either next PC+=MachInst or a branch target. 19012860Sgabeblack@google.com * @param next_PC Next PC variable passed in by reference. It is 19112990Sgabeblack@google.com * expected to be set to the current PC; it will be updated with what 19212961Sgabeblack@google.com * the next PC will be. 19312961Sgabeblack@google.com * @return Whether or not a branch was predicted as taken. 19412961Sgabeblack@google.com */ 19512961Sgabeblack@google.com bool lookupAndUpdateNextPC(DynInstPtr &inst, Addr &next_PC); 19612961Sgabeblack@google.com 19712961Sgabeblack@google.com /** 19812990Sgabeblack@google.com * Fetches the cache line that contains fetch_PC. Returns any 19912961Sgabeblack@google.com * fault that happened. Puts the data into the class variable 20012860Sgabeblack@google.com * cacheData. 20112860Sgabeblack@google.com * @param fetch_PC The PC address that is being fetched from. 20212860Sgabeblack@google.com * @param ret_fault The fault reference that will be set to the result of 20312860Sgabeblack@google.com * the icache access. 20412860Sgabeblack@google.com * @param tid Thread id. 20512956Sgabeblack@google.com * @return Any fault that occured. 20612962Sgabeblack@google.com */ 20712956Sgabeblack@google.com bool fetchCacheLine(Addr fetch_PC, Fault &ret_fault, unsigned tid); 20812956Sgabeblack@google.com 20912956Sgabeblack@google.com /** Squashes a specific thread and resets the PC. */ 21012860Sgabeblack@google.com inline void doSquash(const Addr &new_PC, unsigned tid); 21112860Sgabeblack@google.com 21212860Sgabeblack@google.com /** Squashes a specific thread and resets the PC. Also tells the CPU to 21312860Sgabeblack@google.com * remove any instructions between fetch and decode that should be sqaushed. 21412860Sgabeblack@google.com */ 21512956Sgabeblack@google.com void squashFromDecode(const Addr &new_PC, const InstSeqNum &seq_num, 21612860Sgabeblack@google.com unsigned tid); 21712860Sgabeblack@google.com 21812860Sgabeblack@google.com /** Checks if a thread is stalled. */ 21912860Sgabeblack@google.com bool checkStall(unsigned tid) const; 22012860Sgabeblack@google.com 22112982Sgabeblack@google.com /** Updates overall fetch stage status; to be called at the end of each 22212860Sgabeblack@google.com * cycle. */ 22312860Sgabeblack@google.com FetchStatus updateFetchStatus(); 22412860Sgabeblack@google.com 22512860Sgabeblack@google.com public: 22612860Sgabeblack@google.com /** Squashes a specific thread and resets the PC. Also tells the CPU to 22712962Sgabeblack@google.com * remove any instructions that are not in the ROB. The source of this 22812860Sgabeblack@google.com * squash should be the commit stage. 22912860Sgabeblack@google.com */ 23012860Sgabeblack@google.com void squash(const Addr &new_PC, unsigned tid); 23112860Sgabeblack@google.com 23212860Sgabeblack@google.com /** Ticks the fetch stage, processing all inputs signals and fetching 23312962Sgabeblack@google.com * as many instructions as possible. 23412860Sgabeblack@google.com */ 23512860Sgabeblack@google.com void tick(); 23612860Sgabeblack@google.com 23712860Sgabeblack@google.com /** Checks all input signals and updates the status as necessary. 23812860Sgabeblack@google.com * @return: Returns if the status has changed due to input signals. 23912861Sgabeblack@google.com */ 24012861Sgabeblack@google.com bool checkSignalsAndUpdate(unsigned tid); 24112860Sgabeblack@google.com 24212860Sgabeblack@google.com /** Does the actual fetching of instructions and passing them on to the 24312860Sgabeblack@google.com * next stage. 24412860Sgabeblack@google.com * @param status_change fetch() sets this variable if there was a status 24512860Sgabeblack@google.com * change (ie switching to IcacheMissStall). 24612962Sgabeblack@google.com */ 24712860Sgabeblack@google.com void fetch(bool &status_change); 24812860Sgabeblack@google.com 24912860Sgabeblack@google.com /** Align a PC to the start of an I-cache block. */ 25012860Sgabeblack@google.com Addr icacheBlockAlignPC(Addr addr) 25112860Sgabeblack@google.com { 25212982Sgabeblack@google.com addr = TheISA::realPCToFetchPC(addr); 25312860Sgabeblack@google.com return (addr & ~(cacheBlkMask)); 25412860Sgabeblack@google.com } 25513043Sgabeblack@google.com 25613043Sgabeblack@google.com private: 25713043Sgabeblack@google.com /** Returns the appropriate thread to fetch, given the fetch policy. */ 25813043Sgabeblack@google.com int getFetchingThread(FetchPriority &fetch_priority); 25913043Sgabeblack@google.com 26013043Sgabeblack@google.com /** Returns the appropriate thread to fetch using a round robin policy. */ 26113043Sgabeblack@google.com int roundRobin(); 26213043Sgabeblack@google.com 26313043Sgabeblack@google.com /** Returns the appropriate thread to fetch using the IQ count policy. */ 26413043Sgabeblack@google.com int iqCount(); 26513043Sgabeblack@google.com 26613043Sgabeblack@google.com /** Returns the appropriate thread to fetch using the LSQ count policy. */ 26713043Sgabeblack@google.com int lsqCount(); 26813043Sgabeblack@google.com 26913043Sgabeblack@google.com /** Returns the appropriate thread to fetch using the branch count policy. */ 27013043Sgabeblack@google.com int branchCount(); 27113043Sgabeblack@google.com 27213043Sgabeblack@google.com private: 27313043Sgabeblack@google.com /** Pointer to the FullCPU. */ 27413043Sgabeblack@google.com FullCPU *cpu; 27513043Sgabeblack@google.com 27613043Sgabeblack@google.com /** Time buffer interface. */ 27713043Sgabeblack@google.com TimeBuffer<TimeStruct> *timeBuffer; 27813043Sgabeblack@google.com 27913043Sgabeblack@google.com /** Wire to get decode's information from backwards time buffer. */ 28013043Sgabeblack@google.com typename TimeBuffer<TimeStruct>::wire fromDecode; 28113043Sgabeblack@google.com 28213043Sgabeblack@google.com /** Wire to get rename's information from backwards time buffer. */ 28313043Sgabeblack@google.com typename TimeBuffer<TimeStruct>::wire fromRename; 28413043Sgabeblack@google.com 28513043Sgabeblack@google.com /** Wire to get iew's information from backwards time buffer. */ 28613043Sgabeblack@google.com typename TimeBuffer<TimeStruct>::wire fromIEW; 28713043Sgabeblack@google.com 28813043Sgabeblack@google.com /** Wire to get commit's information from backwards time buffer. */ 28913043Sgabeblack@google.com typename TimeBuffer<TimeStruct>::wire fromCommit; 29013043Sgabeblack@google.com 29113043Sgabeblack@google.com /** Internal fetch instruction queue. */ 29213043Sgabeblack@google.com TimeBuffer<FetchStruct> *fetchQueue; 29313043Sgabeblack@google.com 29413043Sgabeblack@google.com //Might be annoying how this name is different than the queue. 29513043Sgabeblack@google.com /** Wire used to write any information heading to decode. */ 29613043Sgabeblack@google.com typename TimeBuffer<FetchStruct>::wire toDecode; 29713043Sgabeblack@google.com 29813043Sgabeblack@google.com /** Icache interface. */ 29913043Sgabeblack@google.com MemInterface *icacheInterface; 30013043Sgabeblack@google.com 30113043Sgabeblack@google.com /** BPredUnit. */ 30213043Sgabeblack@google.com BPredUnit branchPred; 30313043Sgabeblack@google.com 30413043Sgabeblack@google.com Addr PC[Impl::MaxThreads]; 30513043Sgabeblack@google.com 30613043Sgabeblack@google.com Addr nextPC[Impl::MaxThreads]; 30713043Sgabeblack@google.com 30813043Sgabeblack@google.com /** Memory request used to access cache. */ 30913043Sgabeblack@google.com MemReqPtr memReq[Impl::MaxThreads]; 31013043Sgabeblack@google.com 31113043Sgabeblack@google.com /** Variable that tracks if fetch has written to the time buffer this 31213043Sgabeblack@google.com * cycle. Used to tell CPU if there is activity this cycle. 31313043Sgabeblack@google.com */ 31413043Sgabeblack@google.com bool wroteToTimeBuffer; 31512837Sgabeblack@google.com 316 /** Tracks how many instructions has been fetched this cycle. */ 317 int numInst; 318 319 /** Source of possible stalls. */ 320 struct Stalls { 321 bool decode; 322 bool rename; 323 bool iew; 324 bool commit; 325 }; 326 327 /** Tracks which stages are telling fetch to stall. */ 328 Stalls stalls[Impl::MaxThreads]; 329 330 /** Decode to fetch delay, in ticks. */ 331 unsigned decodeToFetchDelay; 332 333 /** Rename to fetch delay, in ticks. */ 334 unsigned renameToFetchDelay; 335 336 /** IEW to fetch delay, in ticks. */ 337 unsigned iewToFetchDelay; 338 339 /** Commit to fetch delay, in ticks. */ 340 unsigned commitToFetchDelay; 341 342 /** The width of fetch in instructions. */ 343 unsigned fetchWidth; 344 345 /** Cache block size. */ 346 int cacheBlkSize; 347 348 /** Mask to get a cache block's address. */ 349 Addr cacheBlkMask; 350 351 /** The cache line being fetched. */ 352 uint8_t *cacheData[Impl::MaxThreads]; 353 354 /** Size of instructions. */ 355 int instSize; 356 357 /** Icache stall statistics. */ 358 Counter lastIcacheStall[Impl::MaxThreads]; 359 360 /** List of Active Threads */ 361 std::list<unsigned> *activeThreads; 362 363 /** Number of threads. */ 364 unsigned numThreads; 365 366 /** Number of threads that are actively fetching. */ 367 unsigned numFetchingThreads; 368 369 /** Thread ID being fetched. */ 370 int threadFetched; 371 372 bool interruptPending; 373 374 bool switchedOut; 375 376#if !FULL_SYSTEM 377 /** Page table pointer. */ 378// PageTable *pTable; 379#endif 380 381 // @todo: Consider making these vectors and tracking on a per thread basis. 382 /** Stat for total number of cycles stalled due to an icache miss. */ 383 Stats::Scalar<> icacheStallCycles; 384 /** Stat for total number of fetched instructions. */ 385 Stats::Scalar<> fetchedInsts; 386 Stats::Scalar<> fetchedBranches; 387 /** Stat for total number of predicted branches. */ 388 Stats::Scalar<> predictedBranches; 389 /** Stat for total number of cycles spent fetching. */ 390 Stats::Scalar<> fetchCycles; 391 /** Stat for total number of cycles spent squashing. */ 392 Stats::Scalar<> fetchSquashCycles; 393 /** Stat for total number of cycles spent blocked due to other stages in 394 * the pipeline. 395 */ 396 Stats::Scalar<> fetchIdleCycles; 397 Stats::Scalar<> fetchBlockedCycles; 398 399 Stats::Scalar<> fetchMiscStallCycles; 400 /** Stat for total number of fetched cache lines. */ 401 Stats::Scalar<> fetchedCacheLines; 402 403 Stats::Scalar<> fetchIcacheSquashes; 404 /** Distribution of number of instructions fetched each cycle. */ 405 Stats::Distribution<> fetchNisnDist; 406 Stats::Formula idleRate; 407 Stats::Formula branchRate; 408 Stats::Formula fetchRate; 409}; 410 411#endif //__CPU_O3_FETCH_HH__ 412