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