fetch.hh revision 1684
1// Todo: SMT fetch, 2// Add a way to get a stage's current status. 3 4#ifndef __CPU_BETA_CPU_SIMPLE_FETCH_HH__ 5#define __CPU_BETA_CPU_SIMPLE_FETCH_HH__ 6 7#include "base/statistics.hh" 8#include "base/timebuf.hh" 9#include "cpu/pc_event.hh" 10#include "mem/mem_interface.hh" 11#include "sim/eventq.hh" 12 13/** 14 * SimpleFetch class to fetch a single instruction each cycle. SimpleFetch 15 * will stall if there's an Icache miss, but otherwise assumes a one cycle 16 * Icache hit. 17 */ 18 19template <class Impl> 20class SimpleFetch 21{ 22 public: 23 /** Typedefs from Impl. */ 24 typedef typename Impl::ISA ISA; 25 typedef typename Impl::CPUPol CPUPol; 26 typedef typename Impl::DynInst DynInst; 27 typedef typename Impl::DynInstPtr DynInstPtr; 28 typedef typename Impl::FullCPU FullCPU; 29 typedef typename Impl::Params Params; 30 31 typedef typename CPUPol::BPredUnit BPredUnit; 32 typedef typename CPUPol::FetchStruct FetchStruct; 33 typedef typename CPUPol::TimeStruct TimeStruct; 34 35 /** Typedefs from ISA. */ 36 typedef typename ISA::MachInst MachInst; 37 38 public: 39 enum Status { 40 Running, 41 Idle, 42 Squashing, 43 Blocked, 44 IcacheMissStall, 45 IcacheMissComplete 46 }; 47 48 // May eventually need statuses on a per thread basis. 49 Status _status; 50 51 bool stalled; 52 53 public: 54 class CacheCompletionEvent : public Event 55 { 56 private: 57 SimpleFetch *fetch; 58 59 public: 60 CacheCompletionEvent(SimpleFetch *_fetch); 61 62 virtual void process(); 63 virtual const char *description(); 64 }; 65 66 public: 67 /** SimpleFetch constructor. */ 68 SimpleFetch(Params ¶ms); 69 70 void regStats(); 71 72 void setCPU(FullCPU *cpu_ptr); 73 74 void setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer); 75 76 void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr); 77 78 void processCacheCompletion(); 79 80 private: 81 /** 82 * Looks up in the branch predictor to see if the next PC should be 83 * either next PC+=MachInst or a branch target. 84 * @params next_PC Next PC variable passed in by reference. It is 85 * expected to be set to the current PC; it will be updated with what 86 * the next PC will be. 87 * @return Whether or not a branch was predicted as taken. 88 */ 89 bool lookupAndUpdateNextPC(DynInstPtr &inst, Addr &next_PC); 90 91 /** 92 * Fetches the cache line that contains fetch_PC. Returns any 93 * fault that happened. Puts the data into the class variable 94 * cacheData. 95 * @params fetch_PC The PC address that is being fetched from. 96 * @return Any fault that occured. 97 */ 98 Fault fetchCacheLine(Addr fetch_PC); 99 100 inline void doSquash(const Addr &new_PC); 101 102 void squashFromDecode(const Addr &new_PC, const InstSeqNum &seq_num); 103 104 public: 105 // Figure out PC vs next PC and how it should be updated 106 void squash(const Addr &new_PC); 107 108 void tick(); 109 110 void fetch(); 111 112 // Align an address (typically a PC) to the start of an I-cache block. 113 // We fold in the PISA 64- to 32-bit conversion here as well. 114 Addr icacheBlockAlignPC(Addr addr) 115 { 116 addr = ISA::realPCToFetchPC(addr); 117 return (addr & ~(cacheBlkMask)); 118 } 119 120 private: 121 /** Pointer to the FullCPU. */ 122 FullCPU *cpu; 123 124 /** Time buffer interface. */ 125 TimeBuffer<TimeStruct> *timeBuffer; 126 127 /** Wire to get decode's information from backwards time buffer. */ 128 typename TimeBuffer<TimeStruct>::wire fromDecode; 129 130 /** Wire to get rename's information from backwards time buffer. */ 131 typename TimeBuffer<TimeStruct>::wire fromRename; 132 133 /** Wire to get iew's information from backwards time buffer. */ 134 typename TimeBuffer<TimeStruct>::wire fromIEW; 135 136 /** Wire to get commit's information from backwards time buffer. */ 137 typename TimeBuffer<TimeStruct>::wire fromCommit; 138 139 /** Internal fetch instruction queue. */ 140 TimeBuffer<FetchStruct> *fetchQueue; 141 142 //Might be annoying how this name is different than the queue. 143 /** Wire used to write any information heading to decode. */ 144 typename TimeBuffer<FetchStruct>::wire toDecode; 145 146 /** Icache interface. */ 147 MemInterface *icacheInterface; 148 149 /** BPredUnit. */ 150 BPredUnit branchPred; 151 152 /** Memory request used to access cache. */ 153 MemReqPtr memReq; 154 155 /** Decode to fetch delay, in ticks. */ 156 unsigned decodeToFetchDelay; 157 158 /** Rename to fetch delay, in ticks. */ 159 unsigned renameToFetchDelay; 160 161 /** IEW to fetch delay, in ticks. */ 162 unsigned iewToFetchDelay; 163 164 /** Commit to fetch delay, in ticks. */ 165 unsigned commitToFetchDelay; 166 167 /** The width of fetch in instructions. */ 168 unsigned fetchWidth; 169 170 /** Cache block size. */ 171 int cacheBlkSize; 172 173 /** Mask to get a cache block's address. */ 174 Addr cacheBlkMask; 175 176 /** The cache line being fetched. */ 177 uint8_t *cacheData; 178 179 /** Size of instructions. */ 180 int instSize; 181 182 /** Icache stall statistics. */ 183 Counter lastIcacheStall; 184 185 Stats::Scalar<> icacheStallCycles; 186 Stats::Scalar<> fetchedInsts; 187 Stats::Scalar<> predictedBranches; 188 Stats::Scalar<> fetchCycles; 189 Stats::Scalar<> fetchSquashCycles; 190 Stats::Scalar<> fetchBlockedCycles; 191 Stats::Scalar<> fetchedCacheLines; 192 193 Stats::Distribution<> fetch_nisn_dist; 194}; 195 196#endif //__CPU_BETA_CPU_SIMPLE_FETCH_HH__ 197