27,28d26
< *
< * Authors: Kevin Lim
31,36c29,30
< //Todo: Add in a lot of the functions that are ISA specific. Also define
< //the functions that currently exist within the base cpu class. Define
< //everything for the simobject stuff so it can be serialized and
< //instantiated, add in debugging statements everywhere. Have CPU schedule
< //itself properly. Threads!
< // Avoid running stages and advancing queues if idle/stalled.
---
> #ifndef __CPU_O3_CPU_HH__
> #define __CPU_O3_CPU_HH__
38,40d31
< #ifndef __CPU_O3_CPU_FULL_CPU_HH__
< #define __CPU_O3_CPU_FULL_CPU_HH__
<
42a34,35
> #include <queue>
> #include <set>
44a38
> #include "arch/isa_traits.hh"
47a42
> #include "cpu/activity.hh"
51a47,48
> #include "cpu/o3/scoreboard.hh"
> #include "cpu/o3/thread_state.hh"
53a51,52
> template <class>
> class Checker;
55c54
< class FunctionalMemory;
---
> class MemObject;
64,68c63
< #if FULL_SYSTEM
< BaseFullCPU(Params &params);
< #else
< BaseFullCPU(Params &params);
< #endif // FULL_SYSTEM
---
> BaseFullCPU(Params *params);
69a65,68
> void regStats();
>
> int readCpuId() { return cpu_id; }
>
78c77,80
< //Put typedefs from the Impl here.
---
> typedef TheISA::FloatReg FloatReg;
> typedef TheISA::FloatRegBits FloatRegBits;
>
> // Typedefs from the Impl here.
82a85,88
> typedef O3ThreadState<Impl> Thread;
>
> typedef typename std::list<DynInstPtr>::iterator ListIt;
>
88c94,95
< Blocked // ?
---
> Blocked,
> SwitchedOut
90a98
> /** Overall CPU status. */
96a105
> /** Pointer to the CPU. */
99a109
> /** Constructs a tick event. */
100a111,112
>
> /** Processes a tick event, calling tick() on the CPU. */
101a114
> /** Returns the description of the tick event. */
104a118
> /** The tick event used for scheduling CPU ticks. */
107c121
< /// Schedule tick event, regardless of its current state.
---
> /** Schedule tick event, regardless of its current state. */
111c125
< tickEvent.reschedule(curTick + delay);
---
> tickEvent.reschedule(curTick + cycles(delay));
113c127
< tickEvent.schedule(curTick + delay);
---
> tickEvent.schedule(curTick + cycles(delay));
116c130
< /// Unschedule tick event, regardless of its current state.
---
> /** Unschedule tick event, regardless of its current state. */
124c138,140
< FullO3CPU(Params &params);
---
> /** Constructs a CPU with the given parameters. */
> FullO3CPU(Params *params);
> /** Destructor. */
126a143
> /** Registers statistics. */
128a146,148
> /** Ticks CPU, calling tick() on each stage, and checking the overall
> * activity to see if the CPU should deschedule itself.
> */
130a151
> /** Initialize the CPU */
133,136c154,155
< void activateContext(int thread_num, int delay);
< void suspendContext(int thread_num);
< void deallocateContext(int thread_num);
< void haltContext(int thread_num);
---
> /** Setup CPU to insert a thread's context */
> void insertThread(unsigned tid);
138c157,213
< void switchOut();
---
> /** Remove all of a thread's context from CPU */
> void removeThread(unsigned tid);
>
> /** Count the Total Instructions Committed in the CPU. */
> virtual Counter totalInstructions() const
> {
> Counter total(0);
>
> for (int i=0; i < thread.size(); i++)
> total += thread[i]->numInst;
>
> return total;
> }
>
> /** Add Thread to Active Threads List. */
> void activateContext(int tid, int delay);
>
> /** Remove Thread from Active Threads List */
> void suspendContext(int tid);
>
> /** Remove Thread from Active Threads List &&
> * Remove Thread Context from CPU.
> */
> void deallocateContext(int tid);
>
> /** Remove Thread from Active Threads List &&
> * Remove Thread Context from CPU.
> */
> void haltContext(int tid);
>
> /** Activate a Thread When CPU Resources are Available. */
> void activateWhenReady(int tid);
>
> /** Add or Remove a Thread Context in the CPU. */
> void doContextSwitch();
>
> /** Update The Order In Which We Process Threads. */
> void updateThreadPriority();
>
> /** Executes a syscall on this cycle.
> * ---------------------------------------
> * Note: this is a virtual function. CPU-Specific
> * functionality defined in derived classes
> */
> virtual void syscall(int tid) { panic("Unimplemented!"); }
>
> /** Check if there are any system calls pending. */
> void checkSyscalls();
>
> /** Switches out this CPU.
> */
> void switchOut(Sampler *sampler);
>
> void signalSwitched();
>
> /** Takes over from another CPU.
> */
142c217,218
< InstSeqNum getAndIncrementInstSeq();
---
> InstSeqNum getAndIncrementInstSeq()
> { return globalSeqNum++; }
152,153c228,229
< int getInstAsid()
< { return regFile.miscRegs.getInstAsid(); }
---
> int getInstAsid(unsigned tid)
> { return regFile.miscRegs[tid].getInstAsid(); }
156,157c232,233
< int getDataAsid()
< { return regFile.miscRegs.getDataAsid(); }
---
> int getDataAsid(unsigned tid)
> { return regFile.miscRegs[tid].getDataAsid(); }
159,160c235,237
< bool validInstAddr(Addr addr)
< { return thread[0]->validInstAddr(addr); }
---
> /** Get instruction asid. */
> int getInstAsid(unsigned tid)
> { return thread[tid]->asid; }
162,163c239,241
< bool validDataAddr(Addr addr)
< { return thread[0]->validDataAddr(addr); }
---
> /** Get data asid. */
> int getDataAsid(unsigned tid)
> { return thread[tid]->asid; }
165,167d242
< int getInstAsid() { return thread[0]->getInstAsid(); }
< int getDataAsid() { return thread[0]->getDataAsid(); }
<
185c260
< void setFloatReg(int reg_idx, FloatReg val, int width);
---
> void setFloatReg(int reg_idx, FloatReg val);
191c266
< void setFloatRegBits(int reg_idx, FloatRegBits val);
---
> void setFloatRegBits(int reg_idx, FloatRegBits val, int width);
193c268
< uint64_t readPC();
---
> uint64_t readArchIntReg(int reg_idx, unsigned tid);
195c270
< void setNextPC(uint64_t val);
---
> float readArchFloatRegSingle(int reg_idx, unsigned tid);
197c272
< void setPC(Addr new_PC);
---
> double readArchFloatRegDouble(int reg_idx, unsigned tid);
198a274,291
> uint64_t readArchFloatRegInt(int reg_idx, unsigned tid);
>
> void setArchIntReg(int reg_idx, uint64_t val, unsigned tid);
>
> void setArchFloatRegSingle(int reg_idx, float val, unsigned tid);
>
> void setArchFloatRegDouble(int reg_idx, double val, unsigned tid);
>
> void setArchFloatRegInt(int reg_idx, uint64_t val, unsigned tid);
>
> uint64_t readPC(unsigned tid);
>
> void setPC(Addr new_PC,unsigned tid);
>
> uint64_t readNextPC(unsigned tid);
>
> void setNextPC(uint64_t val,unsigned tid);
>
202c295
< void addInst(DynInstPtr &inst);
---
> ListIt addInst(DynInstPtr &inst);
205c298
< void instDone();
---
> void instDone(unsigned tid);
207,215c300,301
< /** Remove all instructions in back of the given instruction, but leave
< * that instruction in the list. This is useful in a squash, when there
< * are instructions in this list that don't exist in structures such as
< * the ROB. The instruction doesn't have to be the last instruction in
< * the list, but will be once this function completes.
< * @todo: Remove only up until that inst? Squashed inst is most likely
< * valid.
< */
< void removeBackInst(DynInstPtr &inst);
---
> /** Add Instructions to the CPU Remove List*/
> void addToRemoveList(DynInstPtr &inst);
217,222c303,304
< /** Remove an instruction from the front of the list. It is expected
< * that there are no instructions in front of it (that is, none are older
< * than the instruction being removed). Used when retiring instructions.
< * @todo: Remove the argument to this function, and just have it remove
< * last instruction once it's verified that commit has the same ordering
< * as the instruction list.
---
> /** Remove an instruction from the front end of the list. There's
> * no restriction on location of the instruction.
227c309
< void removeInstsNotInROB();
---
> void removeInstsNotInROB(unsigned tid);
230c312
< void removeInstsUntil(const InstSeqNum &seq_num);
---
> void removeInstsUntil(const InstSeqNum &seq_num,unsigned tid);
231a314,317
> inline void squashInstIt(const ListIt &instIt, const unsigned &tid);
>
> void cleanUpRemovedInsts();
>
233c319
< void removeAllInsts();
---
> // void removeAllInsts();
238,239c324,325
< * commit can tell the instruction queue that they have completed.
< * Eventually this hack should be removed.
---
> * commit can tell the instruction queue that they have
> * completed. Eventually this hack should be removed.
241c327
< void wakeDependents(DynInstPtr &inst);
---
> // void wakeDependents(DynInstPtr &inst);
245c331
< list<DynInstPtr> instList;
---
> std::list<DynInstPtr> instList;
247c333,346
< //not sure these should be private.
---
> /** List of all the instructions that will be removed at the end of this
> * cycle.
> */
> std::queue<ListIt> removeList;
>
> #ifdef DEBUG
> std::set<InstSeqNum> snList;
> #endif
>
> /** Records if instructions need to be removed this cycle due to
> * being retired or squashed.
> */
> bool removeInstsThisCycle;
>
252,254d350
< /** The fetch stage's status. */
< typename CPUPolicy::Fetch::Status fetchStatus;
<
258,260d353
< /** The decode stage's status. */
< typename CPUPolicy::Decode::Status decodeStatus;
<
264,266d356
< /** The dispatch stage's status. */
< typename CPUPolicy::Rename::Status renameStatus;
<
270,272d359
< /** The issue/execute/writeback stage's status. */
< typename CPUPolicy::IEW::Status iewStatus;
<
276,281d362
< /** The fetch stage's status. */
< typename CPUPolicy::Commit::Status commitStatus;
<
< //Might want to just pass these objects in to the constructors of the
< //appropriate stage. regFile is in iew, freeList in dispatch, renameMap
< //in dispatch, and the rob in commit.
289c370
< typename CPUPolicy::RenameMap renameMap;
---
> typename CPUPolicy::RenameMap renameMap[Impl::MaxThreads];
290a372,374
> /** The commit rename map. */
> typename CPUPolicy::RenameMap commitRenameMap[Impl::MaxThreads];
>
293a378,383
> /** Active Threads List */
> std::list<unsigned> activeThreads;
>
> /** Integer Register Scoreboard */
> Scoreboard scoreboard;
>
294a385,396
> /** Enum to give each stage a specific index, so when calling
> * activateStage() or deactivateStage(), they can specify which stage
> * is being activated/deactivated.
> */
> enum StageIdx {
> FetchIdx,
> DecodeIdx,
> RenameIdx,
> IEWIdx,
> CommitIdx,
> NumStages };
>
324,325c426
< /** The temporary exec context to support older accessors. */
< CPUExecContext *cpuXC;
---
> ActivityRecorder activityRec;
326a428,442
> void activityThisCycle() { activityRec.activity(); }
>
> void activateStage(const StageIdx idx)
> { activityRec.activateStage(idx); }
>
> void deactivateStage(const StageIdx idx)
> { activityRec.deactivateStage(idx); }
>
> /** Wakes the CPU, rescheduling the CPU if it's not already active. */
> void wakeCPU();
>
> /** Gets a free thread id. Use if thread ids change across system. */
> int getFreeTid();
>
> public:
328c444
< ExecContext *xcBase()
---
> ExecContext *xcBase(unsigned tid)
330c446
< return thread[0]->getProxy();
---
> return thread[tid]->getXCProxy();
333,337c449
< CPUExecContext *cpuXCBase()
< {
< return thread[0];
< }
<
---
> /** The global sequence number counter. */
339a452,453
> Checker<DynInstPtr> *checker;
>
340a455
> /** Pointer to the system. */
342a458
> /** Pointer to the memory controller. */
343a460
> /** Pointer to physical memory. */
344a462
> #endif
346,347c464,465
< AlphaITB *itb;
< AlphaDTB *dtb;
---
> /** Pointer to memory. */
> MemObject *mem;
349,351c467
< // SWContext *swCtx;
< #endif
< std::vector<CPUExecContext *> thread;
---
> Sampler *sampler;
353c469
< FunctionalMemory *mem;
---
> int switchCount;
354a471,479
> // List of all ExecContexts.
> std::vector<Thread *> thread;
>
> #if 0
> /** Page table pointer. */
> PageTable *pTable;
> #endif
>
> /** Pointer to the icache interface. */
355a481
> /** Pointer to the dcache interface. */
357a484
> /** Whether or not the CPU should defer its registration. */
360c487,488
< Counter numInsts;
---
> /** Is there a context switch pending? */
> bool contextSwitch;
362c490,520
< Counter funcExeInst;
---
> /** Threads Scheduled to Enter CPU */
> std::list<int> cpuWaitList;
>
> /** The cycle that the CPU was last running, used for statistics. */
> Tick lastRunningCycle;
>
> /** Number of Threads CPU can process */
> unsigned numThreads;
>
> /** Mapping for system thread id to cpu id */
> std::map<unsigned,unsigned> threadMap;
>
> /** Available thread ids in the cpu*/
> std::vector<unsigned> tids;
>
> /** Stat for total number of times the CPU is descheduled. */
> Stats::Scalar<> timesIdled;
> /** Stat for total number of cycles the CPU spends descheduled. */
> Stats::Scalar<> idleCycles;
> /** Stat for the number of committed instructions per thread. */
> Stats::Vector<> committedInsts;
> /** Stat for the total number of committed instructions. */
> Stats::Scalar<> totalCommittedInsts;
> /** Stat for the CPI per thread. */
> Stats::Formula cpi;
> /** Stat for the total CPI. */
> Stats::Formula totalCpi;
> /** Stat for the IPC per thread. */
> Stats::Formula ipc;
> /** Stat for the total IPC. */
> Stats::Formula totalIpc;
365c523
< #endif
---
> #endif // __CPU_O3_CPU_HH__