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