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