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