cpu.hh revision 2690:f4337c0d9e6f
16973Stjones1@inf.ed.ac.uk/* 26973Stjones1@inf.ed.ac.uk * Copyright (c) 2004-2005 The Regents of The University of Michigan 36973Stjones1@inf.ed.ac.uk * All rights reserved. 46973Stjones1@inf.ed.ac.uk * 56973Stjones1@inf.ed.ac.uk * Redistribution and use in source and binary forms, with or without 66973Stjones1@inf.ed.ac.uk * modification, are permitted provided that the following conditions are 76973Stjones1@inf.ed.ac.uk * met: redistributions of source code must retain the above copyright 86973Stjones1@inf.ed.ac.uk * notice, this list of conditions and the following disclaimer; 96973Stjones1@inf.ed.ac.uk * redistributions in binary form must reproduce the above copyright 106973Stjones1@inf.ed.ac.uk * notice, this list of conditions and the following disclaimer in the 116973Stjones1@inf.ed.ac.uk * documentation and/or other materials provided with the distribution; 126973Stjones1@inf.ed.ac.uk * neither the name of the copyright holders nor the names of its 136973Stjones1@inf.ed.ac.uk * contributors may be used to endorse or promote products derived from 146973Stjones1@inf.ed.ac.uk * this software without specific prior written permission. 156973Stjones1@inf.ed.ac.uk * 166973Stjones1@inf.ed.ac.uk * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176973Stjones1@inf.ed.ac.uk * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186973Stjones1@inf.ed.ac.uk * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196973Stjones1@inf.ed.ac.uk * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206973Stjones1@inf.ed.ac.uk * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216973Stjones1@inf.ed.ac.uk * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226973Stjones1@inf.ed.ac.uk * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236973Stjones1@inf.ed.ac.uk * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246973Stjones1@inf.ed.ac.uk * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256973Stjones1@inf.ed.ac.uk * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266973Stjones1@inf.ed.ac.uk * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276973Stjones1@inf.ed.ac.uk * 286973Stjones1@inf.ed.ac.uk * Authors: Kevin Lim 296973Stjones1@inf.ed.ac.uk */ 306973Stjones1@inf.ed.ac.uk 316973Stjones1@inf.ed.ac.uk#ifndef __CPU_O3_CPU_HH__ 326973Stjones1@inf.ed.ac.uk#define __CPU_O3_CPU_HH__ 336973Stjones1@inf.ed.ac.uk 346973Stjones1@inf.ed.ac.uk#include <iostream> 356973Stjones1@inf.ed.ac.uk#include <list> 366973Stjones1@inf.ed.ac.uk#include <queue> 376973Stjones1@inf.ed.ac.uk#include <set> 387049Stjones1@inf.ed.ac.uk#include <vector> 397049Stjones1@inf.ed.ac.uk 407049Stjones1@inf.ed.ac.uk#include "arch/isa_traits.hh" 417049Stjones1@inf.ed.ac.uk#include "base/statistics.hh" 427049Stjones1@inf.ed.ac.uk#include "base/timebuf.hh" 437049Stjones1@inf.ed.ac.uk#include "config/full_system.hh" 447049Stjones1@inf.ed.ac.uk#include "cpu/activity.hh" 457049Stjones1@inf.ed.ac.uk#include "cpu/base.hh" 467049Stjones1@inf.ed.ac.uk#include "cpu/simple_thread.hh" 477049Stjones1@inf.ed.ac.uk#include "cpu/o3/comm.hh" 486973Stjones1@inf.ed.ac.uk#include "cpu/o3/cpu_policy.hh" 496973Stjones1@inf.ed.ac.uk#include "cpu/o3/scoreboard.hh" 506973Stjones1@inf.ed.ac.uk#include "cpu/o3/thread_state.hh" 516973Stjones1@inf.ed.ac.uk#include "sim/process.hh" 526973Stjones1@inf.ed.ac.uk 536973Stjones1@inf.ed.ac.uktemplate <class> 546973Stjones1@inf.ed.ac.ukclass Checker; 556973Stjones1@inf.ed.ac.ukclass ThreadContext; 566973Stjones1@inf.ed.ac.ukclass MemObject; 576973Stjones1@inf.ed.ac.ukclass Process; 586973Stjones1@inf.ed.ac.uk 596973Stjones1@inf.ed.ac.ukclass BaseFullCPU : public BaseCPU 606973Stjones1@inf.ed.ac.uk{ 616973Stjones1@inf.ed.ac.uk //Stuff that's pretty ISA independent will go here. 626973Stjones1@inf.ed.ac.uk public: 637049Stjones1@inf.ed.ac.uk typedef BaseCPU::Params Params; 647049Stjones1@inf.ed.ac.uk 657049Stjones1@inf.ed.ac.uk BaseFullCPU(Params *params); 667049Stjones1@inf.ed.ac.uk 676973Stjones1@inf.ed.ac.uk void regStats(); 686973Stjones1@inf.ed.ac.uk 696973Stjones1@inf.ed.ac.uk int readCpuId() { return cpu_id; } 706973Stjones1@inf.ed.ac.uk 716973Stjones1@inf.ed.ac.uk protected: 726973Stjones1@inf.ed.ac.uk int cpu_id; 736973Stjones1@inf.ed.ac.uk}; 746973Stjones1@inf.ed.ac.uk 756973Stjones1@inf.ed.ac.uk/** 767049Stjones1@inf.ed.ac.uk * FullO3CPU class, has each of the stages (fetch through commit) 777049Stjones1@inf.ed.ac.uk * within it, as well as all of the time buffers between stages. The 787049Stjones1@inf.ed.ac.uk * tick() function for the CPU is defined here. 797049Stjones1@inf.ed.ac.uk */ 807049Stjones1@inf.ed.ac.uktemplate <class Impl> 816973Stjones1@inf.ed.ac.ukclass FullO3CPU : public BaseFullCPU 826973Stjones1@inf.ed.ac.uk{ 836973Stjones1@inf.ed.ac.uk public: 846973Stjones1@inf.ed.ac.uk typedef TheISA::FloatReg FloatReg; 856973Stjones1@inf.ed.ac.uk typedef TheISA::FloatRegBits FloatRegBits; 866973Stjones1@inf.ed.ac.uk 876973Stjones1@inf.ed.ac.uk // Typedefs from the Impl here. 886973Stjones1@inf.ed.ac.uk typedef typename Impl::CPUPol CPUPolicy; 896973Stjones1@inf.ed.ac.uk typedef typename Impl::Params Params; 906973Stjones1@inf.ed.ac.uk typedef typename Impl::DynInstPtr DynInstPtr; 917049Stjones1@inf.ed.ac.uk 927049Stjones1@inf.ed.ac.uk typedef O3ThreadState<Impl> Thread; 937049Stjones1@inf.ed.ac.uk 947049Stjones1@inf.ed.ac.uk typedef typename std::list<DynInstPtr>::iterator ListIt; 957049Stjones1@inf.ed.ac.uk 967049Stjones1@inf.ed.ac.uk public: 977049Stjones1@inf.ed.ac.uk enum Status { 986973Stjones1@inf.ed.ac.uk Running, 996973Stjones1@inf.ed.ac.uk Idle, 1006973Stjones1@inf.ed.ac.uk Halted, 1016973Stjones1@inf.ed.ac.uk Blocked, 1026973Stjones1@inf.ed.ac.uk SwitchedOut 1036973Stjones1@inf.ed.ac.uk }; 1046973Stjones1@inf.ed.ac.uk 1056973Stjones1@inf.ed.ac.uk /** Overall CPU status. */ 1066973Stjones1@inf.ed.ac.uk Status _status; 1076973Stjones1@inf.ed.ac.uk 1086973Stjones1@inf.ed.ac.uk private: 1096973Stjones1@inf.ed.ac.uk class TickEvent : public Event 1106973Stjones1@inf.ed.ac.uk { 1116973Stjones1@inf.ed.ac.uk private: 1126973Stjones1@inf.ed.ac.uk /** Pointer to the CPU. */ 1136973Stjones1@inf.ed.ac.uk FullO3CPU<Impl> *cpu; 1146973Stjones1@inf.ed.ac.uk 1156973Stjones1@inf.ed.ac.uk public: 1167049Stjones1@inf.ed.ac.uk /** Constructs a tick event. */ 1177049Stjones1@inf.ed.ac.uk TickEvent(FullO3CPU<Impl> *c); 1187049Stjones1@inf.ed.ac.uk 1197049Stjones1@inf.ed.ac.uk /** Processes a tick event, calling tick() on the CPU. */ 1206973Stjones1@inf.ed.ac.uk void process(); 1216973Stjones1@inf.ed.ac.uk /** Returns the description of the tick event. */ 1226973Stjones1@inf.ed.ac.uk const char *description(); 1236973Stjones1@inf.ed.ac.uk }; 1246973Stjones1@inf.ed.ac.uk 1256973Stjones1@inf.ed.ac.uk /** The tick event used for scheduling CPU ticks. */ 1266973Stjones1@inf.ed.ac.uk TickEvent tickEvent; 1276973Stjones1@inf.ed.ac.uk 1286973Stjones1@inf.ed.ac.uk /** Schedule tick event, regardless of its current state. */ 1296973Stjones1@inf.ed.ac.uk void scheduleTickEvent(int delay) 1306973Stjones1@inf.ed.ac.uk { 1316973Stjones1@inf.ed.ac.uk if (tickEvent.squashed()) 1326973Stjones1@inf.ed.ac.uk tickEvent.reschedule(curTick + cycles(delay)); 1337049Stjones1@inf.ed.ac.uk else if (!tickEvent.scheduled()) 1346973Stjones1@inf.ed.ac.uk tickEvent.schedule(curTick + cycles(delay)); 1356973Stjones1@inf.ed.ac.uk } 1366973Stjones1@inf.ed.ac.uk 1376973Stjones1@inf.ed.ac.uk /** Unschedule tick event, regardless of its current state. */ 1386973Stjones1@inf.ed.ac.uk void unscheduleTickEvent() 1396973Stjones1@inf.ed.ac.uk { 1407049Stjones1@inf.ed.ac.uk if (tickEvent.scheduled()) 1417049Stjones1@inf.ed.ac.uk tickEvent.squash(); 1427049Stjones1@inf.ed.ac.uk } 1437049Stjones1@inf.ed.ac.uk 1447049Stjones1@inf.ed.ac.uk public: 1456973Stjones1@inf.ed.ac.uk /** Constructs a CPU with the given parameters. */ 1466973Stjones1@inf.ed.ac.uk FullO3CPU(Params *params); 1476973Stjones1@inf.ed.ac.uk /** Destructor. */ 1486973Stjones1@inf.ed.ac.uk ~FullO3CPU(); 1496973Stjones1@inf.ed.ac.uk 1506973Stjones1@inf.ed.ac.uk /** Registers statistics. */ 1517049Stjones1@inf.ed.ac.uk void fullCPURegStats(); 1527049Stjones1@inf.ed.ac.uk 1537049Stjones1@inf.ed.ac.uk /** Ticks CPU, calling tick() on each stage, and checking the overall 1547049Stjones1@inf.ed.ac.uk * activity to see if the CPU should deschedule itself. 1557049Stjones1@inf.ed.ac.uk */ 1566973Stjones1@inf.ed.ac.uk void tick(); 1576973Stjones1@inf.ed.ac.uk 1586973Stjones1@inf.ed.ac.uk /** Initialize the CPU */ 1596973Stjones1@inf.ed.ac.uk void init(); 1606973Stjones1@inf.ed.ac.uk 1616973Stjones1@inf.ed.ac.uk /** Setup CPU to insert a thread's context */ 1627049Stjones1@inf.ed.ac.uk void insertThread(unsigned tid); 1636973Stjones1@inf.ed.ac.uk 1646973Stjones1@inf.ed.ac.uk /** Remove all of a thread's context from CPU */ 1656973Stjones1@inf.ed.ac.uk void removeThread(unsigned tid); 1666973Stjones1@inf.ed.ac.uk 1676973Stjones1@inf.ed.ac.uk /** Count the Total Instructions Committed in the CPU. */ 1686973Stjones1@inf.ed.ac.uk virtual Counter totalInstructions() const 1697049Stjones1@inf.ed.ac.uk { 1707049Stjones1@inf.ed.ac.uk Counter total(0); 1717049Stjones1@inf.ed.ac.uk 1727049Stjones1@inf.ed.ac.uk for (int i=0; i < thread.size(); i++) 1737049Stjones1@inf.ed.ac.uk total += thread[i]->numInst; 1746973Stjones1@inf.ed.ac.uk 1756973Stjones1@inf.ed.ac.uk return total; 1766973Stjones1@inf.ed.ac.uk } 1776973Stjones1@inf.ed.ac.uk 1786973Stjones1@inf.ed.ac.uk /** Add Thread to Active Threads List. */ 1796973Stjones1@inf.ed.ac.uk void activateContext(int tid, int delay); 1807049Stjones1@inf.ed.ac.uk 1816973Stjones1@inf.ed.ac.uk /** Remove Thread from Active Threads List */ 1826973Stjones1@inf.ed.ac.uk void suspendContext(int tid); 1836973Stjones1@inf.ed.ac.uk 1846973Stjones1@inf.ed.ac.uk /** Remove Thread from Active Threads List && 1856973Stjones1@inf.ed.ac.uk * Remove Thread Context from CPU. 1866973Stjones1@inf.ed.ac.uk */ 1876973Stjones1@inf.ed.ac.uk void deallocateContext(int tid); 1886973Stjones1@inf.ed.ac.uk 1896973Stjones1@inf.ed.ac.uk /** Remove Thread from Active Threads List && 1906973Stjones1@inf.ed.ac.uk * Remove Thread Context from CPU. 1916973Stjones1@inf.ed.ac.uk */ 1927049Stjones1@inf.ed.ac.uk void haltContext(int tid); 1937049Stjones1@inf.ed.ac.uk 1947049Stjones1@inf.ed.ac.uk /** Activate a Thread When CPU Resources are Available. */ 1957049Stjones1@inf.ed.ac.uk void activateWhenReady(int tid); 1967049Stjones1@inf.ed.ac.uk 1977049Stjones1@inf.ed.ac.uk /** Add or Remove a Thread Context in the CPU. */ 1987049Stjones1@inf.ed.ac.uk void doContextSwitch(); 1997049Stjones1@inf.ed.ac.uk 2007049Stjones1@inf.ed.ac.uk /** Update The Order In Which We Process Threads. */ 2017049Stjones1@inf.ed.ac.uk void updateThreadPriority(); 2026973Stjones1@inf.ed.ac.uk 2036973Stjones1@inf.ed.ac.uk /** Executes a syscall on this cycle. 2046973Stjones1@inf.ed.ac.uk * --------------------------------------- 2056973Stjones1@inf.ed.ac.uk * Note: this is a virtual function. CPU-Specific 2066973Stjones1@inf.ed.ac.uk * functionality defined in derived classes 2076973Stjones1@inf.ed.ac.uk */ 2086973Stjones1@inf.ed.ac.uk virtual void syscall(int tid) { panic("Unimplemented!"); } 2096973Stjones1@inf.ed.ac.uk 2106973Stjones1@inf.ed.ac.uk /** Switches out this CPU. */ 2116973Stjones1@inf.ed.ac.uk void switchOut(Sampler *sampler); 2126973Stjones1@inf.ed.ac.uk 2136973Stjones1@inf.ed.ac.uk /** Signals to this CPU that a stage has completed switching out. */ 2146973Stjones1@inf.ed.ac.uk void signalSwitched(); 2156973Stjones1@inf.ed.ac.uk 2166973Stjones1@inf.ed.ac.uk /** Takes over from another CPU. */ 2176973Stjones1@inf.ed.ac.uk void takeOverFrom(BaseCPU *oldCPU); 2186973Stjones1@inf.ed.ac.uk 2196973Stjones1@inf.ed.ac.uk /** Get the current instruction sequence number, and increment it. */ 2206973Stjones1@inf.ed.ac.uk InstSeqNum getAndIncrementInstSeq() 2216973Stjones1@inf.ed.ac.uk { return globalSeqNum++; } 2227049Stjones1@inf.ed.ac.uk 2237049Stjones1@inf.ed.ac.uk#if FULL_SYSTEM 2247049Stjones1@inf.ed.ac.uk /** Check if this address is a valid instruction address. */ 2257049Stjones1@inf.ed.ac.uk bool validInstAddr(Addr addr) { return true; } 2266973Stjones1@inf.ed.ac.uk 2276973Stjones1@inf.ed.ac.uk /** Check if this address is a valid data address. */ 2286973Stjones1@inf.ed.ac.uk bool validDataAddr(Addr addr) { return true; } 2296973Stjones1@inf.ed.ac.uk 2306973Stjones1@inf.ed.ac.uk /** Get instruction asid. */ 2316973Stjones1@inf.ed.ac.uk int getInstAsid(unsigned tid) 2326973Stjones1@inf.ed.ac.uk { return regFile.miscRegs[tid].getInstAsid(); } 2336973Stjones1@inf.ed.ac.uk 2346973Stjones1@inf.ed.ac.uk /** Get data asid. */ 2356973Stjones1@inf.ed.ac.uk int getDataAsid(unsigned tid) 2366973Stjones1@inf.ed.ac.uk { return regFile.miscRegs[tid].getDataAsid(); } 2376973Stjones1@inf.ed.ac.uk#else 2386973Stjones1@inf.ed.ac.uk /** Get instruction asid. */ 2396973Stjones1@inf.ed.ac.uk int getInstAsid(unsigned tid) 240 { return thread[tid]->getInstAsid(); } 241 242 /** Get data asid. */ 243 int getDataAsid(unsigned tid) 244 { return thread[tid]->getDataAsid(); } 245 246#endif 247 248 /** Register accessors. Index refers to the physical register index. */ 249 uint64_t readIntReg(int reg_idx); 250 251 FloatReg readFloatReg(int reg_idx); 252 253 FloatReg readFloatReg(int reg_idx, int width); 254 255 FloatRegBits readFloatRegBits(int reg_idx); 256 257 FloatRegBits readFloatRegBits(int reg_idx, int width); 258 259 void setIntReg(int reg_idx, uint64_t val); 260 261 void setFloatReg(int reg_idx, FloatReg val); 262 263 void setFloatReg(int reg_idx, FloatReg val, int width); 264 265 void setFloatRegBits(int reg_idx, FloatRegBits val); 266 267 void setFloatRegBits(int reg_idx, FloatRegBits val, int width); 268 269 uint64_t readArchIntReg(int reg_idx, unsigned tid); 270 271 float readArchFloatRegSingle(int reg_idx, unsigned tid); 272 273 double readArchFloatRegDouble(int reg_idx, unsigned tid); 274 275 uint64_t readArchFloatRegInt(int reg_idx, unsigned tid); 276 277 /** Architectural register accessors. Looks up in the commit 278 * rename table to obtain the true physical index of the 279 * architected register first, then accesses that physical 280 * register. 281 */ 282 void setArchIntReg(int reg_idx, uint64_t val, unsigned tid); 283 284 void setArchFloatRegSingle(int reg_idx, float val, unsigned tid); 285 286 void setArchFloatRegDouble(int reg_idx, double val, unsigned tid); 287 288 void setArchFloatRegInt(int reg_idx, uint64_t val, unsigned tid); 289 290 /** Reads the commit PC of a specific thread. */ 291 uint64_t readPC(unsigned tid); 292 293 /** Sets the commit PC of a specific thread. */ 294 void setPC(Addr new_PC, unsigned tid); 295 296 /** Reads the next PC of a specific thread. */ 297 uint64_t readNextPC(unsigned tid); 298 299 /** Sets the next PC of a specific thread. */ 300 void setNextPC(uint64_t val, unsigned tid); 301 302 /** Function to add instruction onto the head of the list of the 303 * instructions. Used when new instructions are fetched. 304 */ 305 ListIt addInst(DynInstPtr &inst); 306 307 /** Function to tell the CPU that an instruction has completed. */ 308 void instDone(unsigned tid); 309 310 /** Add Instructions to the CPU Remove List*/ 311 void addToRemoveList(DynInstPtr &inst); 312 313 /** Remove an instruction from the front end of the list. There's 314 * no restriction on location of the instruction. 315 */ 316 void removeFrontInst(DynInstPtr &inst); 317 318 /** Remove all instructions that are not currently in the ROB. */ 319 void removeInstsNotInROB(unsigned tid); 320 321 /** Remove all instructions younger than the given sequence number. */ 322 void removeInstsUntil(const InstSeqNum &seq_num,unsigned tid); 323 324 /** Removes the instruction pointed to by the iterator. */ 325 inline void squashInstIt(const ListIt &instIt, const unsigned &tid); 326 327 /** Cleans up all instructions on the remove list. */ 328 void cleanUpRemovedInsts(); 329 330 /** Debug function to print all instructions on the list. */ 331 void dumpInsts(); 332 333 public: 334 /** List of all the instructions in flight. */ 335 std::list<DynInstPtr> instList; 336 337 /** List of all the instructions that will be removed at the end of this 338 * cycle. 339 */ 340 std::queue<ListIt> removeList; 341 342#ifdef DEBUG 343 /** Debug structure to keep track of the sequence numbers still in 344 * flight. 345 */ 346 std::set<InstSeqNum> snList; 347#endif 348 349 /** Records if instructions need to be removed this cycle due to 350 * being retired or squashed. 351 */ 352 bool removeInstsThisCycle; 353 354 protected: 355 /** The fetch stage. */ 356 typename CPUPolicy::Fetch fetch; 357 358 /** The decode stage. */ 359 typename CPUPolicy::Decode decode; 360 361 /** The dispatch stage. */ 362 typename CPUPolicy::Rename rename; 363 364 /** The issue/execute/writeback stages. */ 365 typename CPUPolicy::IEW iew; 366 367 /** The commit stage. */ 368 typename CPUPolicy::Commit commit; 369 370 /** The register file. */ 371 typename CPUPolicy::RegFile regFile; 372 373 /** The free list. */ 374 typename CPUPolicy::FreeList freeList; 375 376 /** The rename map. */ 377 typename CPUPolicy::RenameMap renameMap[Impl::MaxThreads]; 378 379 /** The commit rename map. */ 380 typename CPUPolicy::RenameMap commitRenameMap[Impl::MaxThreads]; 381 382 /** The re-order buffer. */ 383 typename CPUPolicy::ROB rob; 384 385 /** Active Threads List */ 386 std::list<unsigned> activeThreads; 387 388 /** Integer Register Scoreboard */ 389 Scoreboard scoreboard; 390 391 public: 392 /** Enum to give each stage a specific index, so when calling 393 * activateStage() or deactivateStage(), they can specify which stage 394 * is being activated/deactivated. 395 */ 396 enum StageIdx { 397 FetchIdx, 398 DecodeIdx, 399 RenameIdx, 400 IEWIdx, 401 CommitIdx, 402 NumStages }; 403 404 /** Typedefs from the Impl to get the structs that each of the 405 * time buffers should use. 406 */ 407 typedef typename CPUPolicy::TimeStruct TimeStruct; 408 409 typedef typename CPUPolicy::FetchStruct FetchStruct; 410 411 typedef typename CPUPolicy::DecodeStruct DecodeStruct; 412 413 typedef typename CPUPolicy::RenameStruct RenameStruct; 414 415 typedef typename CPUPolicy::IEWStruct IEWStruct; 416 417 /** The main time buffer to do backwards communication. */ 418 TimeBuffer<TimeStruct> timeBuffer; 419 420 /** The fetch stage's instruction queue. */ 421 TimeBuffer<FetchStruct> fetchQueue; 422 423 /** The decode stage's instruction queue. */ 424 TimeBuffer<DecodeStruct> decodeQueue; 425 426 /** The rename stage's instruction queue. */ 427 TimeBuffer<RenameStruct> renameQueue; 428 429 /** The IEW stage's instruction queue. */ 430 TimeBuffer<IEWStruct> iewQueue; 431 432 private: 433 /** The activity recorder; used to tell if the CPU has any 434 * activity remaining or if it can go to idle and deschedule 435 * itself. 436 */ 437 ActivityRecorder activityRec; 438 439 public: 440 /** Records that there was time buffer activity this cycle. */ 441 void activityThisCycle() { activityRec.activity(); } 442 443 /** Changes a stage's status to active within the activity recorder. */ 444 void activateStage(const StageIdx idx) 445 { activityRec.activateStage(idx); } 446 447 /** Changes a stage's status to inactive within the activity recorder. */ 448 void deactivateStage(const StageIdx idx) 449 { activityRec.deactivateStage(idx); } 450 451 /** Wakes the CPU, rescheduling the CPU if it's not already active. */ 452 void wakeCPU(); 453 454 /** Gets a free thread id. Use if thread ids change across system. */ 455 int getFreeTid(); 456 457 public: 458 /** Returns a pointer to a thread context. */ 459 ThreadContext *tcBase(unsigned tid) 460 { 461 return thread[tid]->getTC(); 462 } 463 464 /** The global sequence number counter. */ 465 InstSeqNum globalSeqNum; 466 467 /** Pointer to the checker, which can dynamically verify 468 * instruction results at run time. This can be set to NULL if it 469 * is not being used. 470 */ 471 Checker<DynInstPtr> *checker; 472 473#if FULL_SYSTEM 474 /** Pointer to the system. */ 475 System *system; 476 477 /** Pointer to physical memory. */ 478 PhysicalMemory *physmem; 479#endif 480 481 /** Pointer to memory. */ 482 MemObject *mem; 483 484 /** Pointer to the sampler */ 485 Sampler *sampler; 486 487 /** Counter of how many stages have completed switching out. */ 488 int switchCount; 489 490 /** Pointers to all of the threads in the CPU. */ 491 std::vector<Thread *> thread; 492 493#if 0 494 /** Page table pointer. */ 495 PageTable *pTable; 496#endif 497 498 /** Pointer to the icache interface. */ 499 MemInterface *icacheInterface; 500 /** Pointer to the dcache interface. */ 501 MemInterface *dcacheInterface; 502 503 /** Whether or not the CPU should defer its registration. */ 504 bool deferRegistration; 505 506 /** Is there a context switch pending? */ 507 bool contextSwitch; 508 509 /** Threads Scheduled to Enter CPU */ 510 std::list<int> cpuWaitList; 511 512 /** The cycle that the CPU was last running, used for statistics. */ 513 Tick lastRunningCycle; 514 515 /** Number of Threads CPU can process */ 516 unsigned numThreads; 517 518 /** Mapping for system thread id to cpu id */ 519 std::map<unsigned,unsigned> threadMap; 520 521 /** Available thread ids in the cpu*/ 522 std::vector<unsigned> tids; 523 524 /** Stat for total number of times the CPU is descheduled. */ 525 Stats::Scalar<> timesIdled; 526 /** Stat for total number of cycles the CPU spends descheduled. */ 527 Stats::Scalar<> idleCycles; 528 /** Stat for the number of committed instructions per thread. */ 529 Stats::Vector<> committedInsts; 530 /** Stat for the total number of committed instructions. */ 531 Stats::Scalar<> totalCommittedInsts; 532 /** Stat for the CPI per thread. */ 533 Stats::Formula cpi; 534 /** Stat for the total CPI. */ 535 Stats::Formula totalCpi; 536 /** Stat for the IPC per thread. */ 537 Stats::Formula ipc; 538 /** Stat for the total IPC. */ 539 Stats::Formula totalIpc; 540}; 541 542#endif // __CPU_O3_CPU_HH__ 543