cpu.hh revision 1685
1//Todo: Add in a lot of the functions that are ISA specific. Also define 2//the functions that currently exist within the base cpu class. Define 3//everything for the simobject stuff so it can be serialized and 4//instantiated, add in debugging statements everywhere. Have CPU schedule 5//itself properly. Constructor. Derived alpha class. Threads! 6// Avoid running stages and advancing queues if idle/stalled. 7 8#ifndef __CPU_BETA_CPU_FULL_CPU_HH__ 9#define __CPU_BETA_CPU_FULL_CPU_HH__ 10 11#include <iostream> 12#include <list> 13#include <vector> 14 15#include "base/statistics.hh" 16#include "base/timebuf.hh" 17#include "cpu/base_cpu.hh" 18#include "cpu/beta_cpu/comm.hh" 19#include "cpu/beta_cpu/cpu_policy.hh" 20#include "cpu/exec_context.hh" 21#include "sim/process.hh" 22 23#ifdef FULL_SYSTEM 24#include "arch/alpha/ev5.hh" 25using namespace EV5; 26#endif 27 28class FunctionalMemory; 29class Process; 30 31class BaseFullCPU : public BaseCPU 32{ 33 //Stuff that's pretty ISA independent will go here. 34 public: 35 typedef BaseCPU::Params Params; 36 37#ifdef FULL_SYSTEM 38 BaseFullCPU(Params ¶ms); 39#else 40 BaseFullCPU(Params ¶ms); 41#endif // FULL_SYSTEM 42 43 protected: 44 int cpu_id; 45}; 46 47template <class Impl> 48class FullBetaCPU : public BaseFullCPU 49{ 50 public: 51 //Put typedefs from the Impl here. 52 typedef typename Impl::ISA ISA; 53 typedef typename Impl::CPUPol CPUPolicy; 54 typedef typename Impl::Params Params; 55 typedef typename Impl::DynInstPtr DynInstPtr; 56 57 public: 58 enum Status { 59 Running, 60 Idle, 61 Halted, 62 Blocked // ? 63 }; 64 65 Status _status; 66 67 private: 68 class TickEvent : public Event 69 { 70 private: 71 FullBetaCPU<Impl> *cpu; 72 73 public: 74 TickEvent(FullBetaCPU<Impl> *c); 75 void process(); 76 const char *description(); 77 }; 78 79 TickEvent tickEvent; 80 81 /// Schedule tick event, regardless of its current state. 82 void scheduleTickEvent(int delay) 83 { 84 if (tickEvent.squashed()) 85 tickEvent.reschedule(curTick + delay); 86 else if (!tickEvent.scheduled()) 87 tickEvent.schedule(curTick + delay); 88 } 89 90 /// Unschedule tick event, regardless of its current state. 91 void unscheduleTickEvent() 92 { 93 if (tickEvent.scheduled()) 94 tickEvent.squash(); 95 } 96 97 public: 98 FullBetaCPU(Params ¶ms); 99 ~FullBetaCPU(); 100 101 void fullCPURegStats(); 102 103 void tick(); 104 105 void init(); 106 107 void activateContext(int thread_num, int delay); 108 void suspendContext(int thread_num); 109 void deallocateContext(int thread_num); 110 void haltContext(int thread_num); 111 112 void switchOut(); 113 void takeOverFrom(BaseCPU *oldCPU); 114 115 /** Get the current instruction sequence number, and increment it. */ 116 InstSeqNum getAndIncrementInstSeq(); 117 118#ifdef FULL_SYSTEM 119 /** Check if this address is a valid instruction address. */ 120 bool validInstAddr(Addr addr) { return true; } 121 122 /** Check if this address is a valid data address. */ 123 bool validDataAddr(Addr addr) { return true; } 124 125 /** Get instruction asid. */ 126 int getInstAsid() 127 { return ITB_ASN_ASN(regFile.getIpr()[ISA::IPR_ITB_ASN]); } 128 129 /** Get data asid. */ 130 int getDataAsid() 131 { return DTB_ASN_ASN(regFile.getIpr()[ISA::IPR_DTB_ASN]); } 132#else 133 bool validInstAddr(Addr addr) 134 { return thread[0]->validInstAddr(addr); } 135 136 bool validDataAddr(Addr addr) 137 { return thread[0]->validDataAddr(addr); } 138 139 int getInstAsid() { return thread[0]->asid; } 140 int getDataAsid() { return thread[0]->asid; } 141 142#endif 143 144 // 145 // New accessors for new decoder. 146 // 147 uint64_t readIntReg(int reg_idx); 148 149 float readFloatRegSingle(int reg_idx); 150 151 double readFloatRegDouble(int reg_idx); 152 153 uint64_t readFloatRegInt(int reg_idx); 154 155 void setIntReg(int reg_idx, uint64_t val); 156 157 void setFloatRegSingle(int reg_idx, float val); 158 159 void setFloatRegDouble(int reg_idx, double val); 160 161 void setFloatRegInt(int reg_idx, uint64_t val); 162 163 uint64_t readPC(); 164 165 void setNextPC(uint64_t val); 166 167 void setPC(Addr new_PC); 168 169 /** Function to add instruction onto the head of the list of the 170 * instructions. Used when new instructions are fetched. 171 */ 172 void addInst(DynInstPtr &inst); 173 174 /** Function to tell the CPU that an instruction has completed. */ 175 void instDone(); 176 177 /** Remove all instructions in back of the given instruction, but leave 178 * that instruction in the list. This is useful in a squash, when there 179 * are instructions in this list that don't exist in structures such as 180 * the ROB. The instruction doesn't have to be the last instruction in 181 * the list, but will be once this function completes. 182 * @todo: Remove only up until that inst? Squashed inst is most likely 183 * valid. 184 */ 185 void removeBackInst(DynInstPtr &inst); 186 187 /** Remove an instruction from the front of the list. It is expected 188 * that there are no instructions in front of it (that is, none are older 189 * than the instruction being removed). Used when retiring instructions. 190 * @todo: Remove the argument to this function, and just have it remove 191 * last instruction once it's verified that commit has the same ordering 192 * as the instruction list. 193 */ 194 void removeFrontInst(DynInstPtr &inst); 195 196 /** Remove all instructions that are not currently in the ROB. */ 197 void removeInstsNotInROB(); 198 199 /** Remove all instructions younger than the given sequence number. */ 200 void removeInstsUntil(const InstSeqNum &seq_num); 201 202 /** Remove all instructions from the list. */ 203 void removeAllInsts(); 204 205 void dumpInsts(); 206 207 /** Basically a wrapper function so that instructions executed at 208 * commit can tell the instruction queue that they have completed. 209 * Eventually this hack should be removed. 210 */ 211 void wakeDependents(DynInstPtr &inst); 212 213 public: 214 /** List of all the instructions in flight. */ 215 list<DynInstPtr> instList; 216 217 //not sure these should be private. 218 protected: 219 /** The fetch stage. */ 220 typename CPUPolicy::Fetch fetch; 221 222 /** The fetch stage's status. */ 223 typename CPUPolicy::Fetch::Status fetchStatus; 224 225 /** The decode stage. */ 226 typename CPUPolicy::Decode decode; 227 228 /** The decode stage's status. */ 229 typename CPUPolicy::Decode::Status decodeStatus; 230 231 /** The dispatch stage. */ 232 typename CPUPolicy::Rename rename; 233 234 /** The dispatch stage's status. */ 235 typename CPUPolicy::Rename::Status renameStatus; 236 237 /** The issue/execute/writeback stages. */ 238 typename CPUPolicy::IEW iew; 239 240 /** The issue/execute/writeback stage's status. */ 241 typename CPUPolicy::IEW::Status iewStatus; 242 243 /** The commit stage. */ 244 typename CPUPolicy::Commit commit; 245 246 /** The fetch stage's status. */ 247 typename CPUPolicy::Commit::Status commitStatus; 248 249 //Might want to just pass these objects in to the constructors of the 250 //appropriate stage. regFile is in iew, freeList in dispatch, renameMap 251 //in dispatch, and the rob in commit. 252 /** The register file. */ 253 typename CPUPolicy::RegFile regFile; 254 255 /** The free list. */ 256 typename CPUPolicy::FreeList freeList; 257 258 /** The rename map. */ 259 typename CPUPolicy::RenameMap renameMap; 260 261 /** The re-order buffer. */ 262 typename CPUPolicy::ROB rob; 263 264 public: 265 /** Typedefs from the Impl to get the structs that each of the 266 * time buffers should use. 267 */ 268 typedef typename CPUPolicy::TimeStruct TimeStruct; 269 270 typedef typename CPUPolicy::FetchStruct FetchStruct; 271 272 typedef typename CPUPolicy::DecodeStruct DecodeStruct; 273 274 typedef typename CPUPolicy::RenameStruct RenameStruct; 275 276 typedef typename CPUPolicy::IEWStruct IEWStruct; 277 278 /** The main time buffer to do backwards communication. */ 279 TimeBuffer<TimeStruct> timeBuffer; 280 281 /** The fetch stage's instruction queue. */ 282 TimeBuffer<FetchStruct> fetchQueue; 283 284 /** The decode stage's instruction queue. */ 285 TimeBuffer<DecodeStruct> decodeQueue; 286 287 /** The rename stage's instruction queue. */ 288 TimeBuffer<RenameStruct> renameQueue; 289 290 /** The IEW stage's instruction queue. */ 291 TimeBuffer<IEWStruct> iewQueue; 292 293 public: 294 /** The temporary exec context to support older accessors. */ 295 ExecContext *xc; 296 297 /** Temporary function to get pointer to exec context. */ 298 ExecContext *xcBase() 299 { 300#ifdef FULL_SYSTEM 301 return system->execContexts[0]; 302#else 303 return thread[0]; 304#endif 305 } 306 307 InstSeqNum globalSeqNum; 308 309#ifdef FULL_SYSTEM 310 System *system; 311 312 MemoryController *memCtrl; 313 PhysicalMemory *physmem; 314 315 AlphaITB *itb; 316 AlphaDTB *dtb; 317 318// SWContext *swCtx; 319#else 320 std::vector<ExecContext *> thread; 321#endif 322 323 FunctionalMemory *mem; 324 325 MemInterface *icacheInterface; 326 MemInterface *dcacheInterface; 327 328 bool deferRegistration; 329 330 Counter numInsts; 331 332 Counter funcExeInst; 333}; 334 335#endif 336