2c2
< * Copyright (c) 2004-2005 The Regents of The University of Michigan
---
> * Copyright (c) 2004-2006 The Regents of The University of Michigan
27,28d26
< *
< * Authors: Kevin Lim
31,43c29,30
< // Todo: Maybe have a special method for handling interrupts/traps.
< //
< // Traps: Have IEW send a signal to commit saying that there's a trap to
< // be handled. Have commit send the PC back to the fetch stage, along
< // with the current commit PC. Fetch will directly access the IPR and save
< // off all the proper stuff. Commit can send out a squash, or something
< // close to it.
< // Do the same for hwrei(). However, requires that commit be specifically
< // built to support that kind of stuff. Probably not horrible to have
< // commit support having the CPU tell it to squash the other stages and
< // restart at a given address. The IPR register does become an issue.
< // Probably not a big deal if the IPR stuff isn't cycle accurate. Can just
< // have the original function handle writing to the IPR register.
---
> #ifndef __CPU_O3_COMMIT_HH__
> #define __CPU_O3_COMMIT_HH__
45,47c32
< #ifndef __CPU_O3_CPU_SIMPLE_COMMIT_HH__
< #define __CPU_O3_CPU_SIMPLE_COMMIT_HH__
<
---
> #include "arch/faults.hh"
50c35,36
< #include "mem/memory_interface.hh"
---
> #include "cpu/exetrace.hh"
> #include "cpu/inst_seq.hh"
51a38,62
> template <class>
> class O3ThreadState;
>
> /**
> * DefaultCommit handles single threaded and SMT commit. Its width is
> * specified by the parameters; each cycle it tries to commit that
> * many instructions. The SMT policy decides which thread it tries to
> * commit instructions from. Non- speculative instructions must reach
> * the head of the ROB before they are ready to execute; once they
> * reach the head, commit will broadcast the instruction's sequence
> * number to the previous stages so that they can issue/ execute the
> * instruction. Only one non-speculative instruction is handled per
> * cycle. Commit is responsible for handling all back-end initiated
> * redirects. It receives the redirect, and then broadcasts it to all
> * stages, indicating the sequence number they should squash until,
> * and any necessary branch misprediction information as well. It
> * priortizes redirects by instruction's age, only broadcasting a
> * redirect if it corresponds to an instruction that should currently
> * be in the ROB. This is done by tracking the sequence number of the
> * youngest instruction in the ROB, which gets updated to any
> * squashing instruction's sequence number, and only broadcasting a
> * redirect if it corresponds to an older instruction. Commit also
> * supports multiple cycle squashing, to model a ROB that can only
> * remove a certain number of instructions per cycle.
> */
53c64
< class SimpleCommit
---
> class DefaultCommit
61a73
> typedef typename CPUPol::RenameMap RenameMap;
64a77
> typedef typename CPUPol::FetchStruct FetchStruct;
68,74c81,107
< public:
< // I don't believe commit can block, so it will only have two
< // statuses for now.
< // Actually if there's a cache access that needs to block (ie
< // uncachable load or just a mem access in commit) then the stage
< // may have to wait.
< enum Status {
---
> typedef typename CPUPol::Fetch Fetch;
> typedef typename CPUPol::IEW IEW;
>
> typedef O3ThreadState<Impl> Thread;
>
> class TrapEvent : public Event {
> private:
> DefaultCommit<Impl> *commit;
> unsigned tid;
>
> public:
> TrapEvent(DefaultCommit<Impl> *_commit, unsigned _tid);
>
> void process();
> const char *description();
> };
>
> /** Overall commit status. Used to determine if the CPU can deschedule
> * itself due to a lack of activity.
> */
> enum CommitStatus{
> Active,
> Inactive
> };
>
> /** Individual thread status. */
> enum ThreadStatus {
78,79c111,112
< DcacheMissStall,
< DcacheMissComplete
---
> TrapPending,
> FetchTrapPending
81a115,121
> /** Commit policy for SMT mode. */
> enum CommitPolicy {
> Aggressive,
> RoundRobin,
> OldestReady
> };
>
83c123,130
< Status _status;
---
> /** Overall commit status. */
> CommitStatus _status;
> /** Next commit status, to be set at the end of the cycle. */
> CommitStatus _nextStatus;
> /** Per-thread status. */
> ThreadStatus commitStatus[Impl::MaxThreads];
> /** Commit policy used in SMT mode. */
> CommitPolicy commitPolicy;
86c133,134
< SimpleCommit(Params &params);
---
> /** Construct a DefaultCommit with the given parameters. */
> DefaultCommit(Params *params);
87a136,139
> /** Returns the name of the DefaultCommit. */
> std::string name() const;
>
> /** Registers statistics. */
89a142
> /** Sets the CPU pointer. */
91a145,148
> /** Sets the list of threads. */
> void setThreads(std::vector<Thread *> &threads);
>
> /** Sets the main time buffer pointer, used for backwards communication. */
93a151,153
> void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr);
>
> /** Sets the pointer to the queue coming from rename. */
95a156
> /** Sets the pointer to the queue coming from IEW. */
97a159,178
> void setFetchStage(Fetch *fetch_stage);
>
> Fetch *fetchStage;
>
> /** Sets the poitner to the IEW stage. */
> void setIEWStage(IEW *iew_stage);
>
> /** The pointer to the IEW stage. Used solely to ensure that
> * various events (traps, interrupts, syscalls) do not occur until
> * all stores have written back.
> */
> IEW *iewStage;
>
> /** Sets pointer to list of active threads. */
> void setActiveThreads(std::list<unsigned> *at_ptr);
>
> /** Sets pointer to the commited state rename map. */
> void setRenameMap(RenameMap rm_ptr[Impl::MaxThreads]);
>
> /** Sets pointer to the ROB. */
99a181,190
> /** Initializes stage by sending back the number of free entries. */
> void initStage();
>
> void switchOut();
>
> void doSwitchOut();
>
> void takeOverFrom();
>
> /** Ticks the commit stage, which tries to commit instructions. */
101a193,195
> /** Handles any squashes that are sent from IEW, and adds instructions
> * to the ROB and tries to commit instructions.
> */
103a198,202
> /** Returns the number of free ROB entries for a specific thread. */
> unsigned numROBFreeEntries(unsigned tid);
>
> void generateXCEvent(unsigned tid);
>
104a204,206
> /** Updates the overall status of commit with the nextStatus, and
> * tell the CPU if commit is active/inactive. */
> void updateStatus();
105a208,230
> /** Sets the next status based on threads' statuses, which becomes the
> * current status at the end of the cycle.
> */
> void setNextStatus();
>
> /** Checks if the ROB is completed with squashing. This is for the case
> * where the ROB can take multiple cycles to complete squashing.
> */
> bool robDoneSquashing();
>
> /** Returns if any of the threads have the number of ROB entries changed
> * on this cycle. Used to determine if the number of free ROB entries needs
> * to be sent back to previous stages.
> */
> bool changedROBEntries();
>
> void squashAll(unsigned tid);
>
> void squashFromTrap(unsigned tid);
>
> void squashFromXC(unsigned tid);
>
> /** Commits as many instructions as possible. */
107a233,235
> /** Tries to commit the head ROB instruction passed in.
> * @param head_inst The instruction to be committed.
> */
109a238,240
> void generateTrapEvent(unsigned tid);
>
> /** Gets instructions from rename and inserts them into the ROB. */
111a243
> /** Marks completed instructions using information sent from IEW. */
113a246,254
> /** Gets the thread to commit, based on the SMT policy. */
> int getCommittingThread();
>
> /** Returns the thread ID to use based on a round robin policy. */
> int roundRobin();
>
> /** Returns the thread ID to use based on an oldest instruction policy. */
> int oldestReady();
>
115c256,259
< uint64_t readCommitPC();
---
> /** Returns the PC of the head instruction of the ROB.
> * @todo: Probably remove this function as it returns only thread 0.
> */
> uint64_t readPC() { return PC[0]; }
117c261
< void setSquashing() { _status = ROBSquashing; }
---
> uint64_t readPC(unsigned tid) { return PC[tid]; }
118a263,268
> void setPC(uint64_t val, unsigned tid) { PC[tid] = val; }
>
> uint64_t readNextPC(unsigned tid) { return nextPC[tid]; }
>
> void setNextPC(uint64_t val, unsigned tid) { nextPC[tid] = val; }
>
128a279,282
> TimeBuffer<FetchStruct> *fetchQueue;
>
> typename TimeBuffer<FetchStruct>::wire fromFetch;
>
140a295
> public:
143a299
> private:
147,148c303
< /** Memory interface. Used for d-cache accesses. */
< MemInterface *dcacheInterface;
---
> std::vector<Thread *> thread;
150c305,330
< private:
---
> Fault fetchFault;
>
> int fetchTrapWait;
>
> /** Records that commit has written to the time buffer this cycle. Used for
> * the CPU to determine if it can deschedule itself if there is no activity.
> */
> bool wroteToTimeBuffer;
>
> /** Records if the number of ROB entries has changed this cycle. If it has,
> * then the number of free entries must be re-broadcast.
> */
> bool changedROBNumEntries[Impl::MaxThreads];
>
> /** A counter of how many threads are currently squashing. */
> int squashCounter;
>
> /** Records if a thread has to squash this cycle due to a trap. */
> bool trapSquash[Impl::MaxThreads];
>
> /** Records if a thread has to squash this cycle due to an XC write. */
> bool xcSquash[Impl::MaxThreads];
>
> /** Priority List used for Commit Policy */
> std::list<unsigned> priority_list;
>
153a334,336
> /** Commit to IEW delay, in ticks. */
> unsigned commitToIEWDelay;
>
156a340,341
> unsigned fetchToCommitDelay;
>
169a355,385
> /** Number of Reorder Buffers */
> unsigned numRobs;
>
> /** Number of Active Threads */
> unsigned numThreads;
>
> bool switchPending;
> bool switchedOut;
>
> Tick trapLatency;
>
> Tick fetchTrapLatency;
>
> Tick fetchFaultTick;
>
> Addr PC[Impl::MaxThreads];
>
> Addr nextPC[Impl::MaxThreads];
>
> /** The sequence number of the youngest valid instruction in the ROB. */
> InstSeqNum youngestSeqNum[Impl::MaxThreads];
>
> /** Pointer to the list of active threads. */
> std::list<unsigned> *activeThreads;
>
> /** Rename map interface. */
> RenameMap *renameMap[Impl::MaxThreads];
>
> void updateComInstStats(DynInstPtr &inst);
>
> /** Stat for the total number of committed instructions. */
170a387,388
> /** Stat for the total number of squashed instructions discarded by commit.
> */
171a390,392
> /** Stat for the total number of times commit is told to squash.
> * @todo: Actually increment this stat.
> */
172a394,396
> /** Stat for the total number of times commit has had to stall due to a non-
> * speculative instruction reaching the head of the ROB.
> */
174,176c398
< Stats::Scalar<> commitCommittedBranches;
< Stats::Scalar<> commitCommittedLoads;
< Stats::Scalar<> commitCommittedMemRefs;
---
> /** Stat for the total number of branch mispredicts that caused a squash. */
177a400,401
> /** Distribution of the number of committed instructions each cycle. */
> Stats::Distribution<> numCommittedDist;
179c403,417
< Stats::Distribution<> n_committed_dist;
---
> /** Total number of instructions committed. */
> Stats::Vector<> statComInst;
> /** Total number of software prefetches committed. */
> Stats::Vector<> statComSwp;
> /** Stat for the total number of committed memory references. */
> Stats::Vector<> statComRefs;
> /** Stat for the total number of committed loads. */
> Stats::Vector<> statComLoads;
> /** Total number of committed memory barriers. */
> Stats::Vector<> statComMembars;
> /** Total number of committed branches. */
> Stats::Vector<> statComBranches;
>
> Stats::Scalar<> commitEligibleSamples;
> Stats::Vector<> commitEligible;
182c420
< #endif // __CPU_O3_CPU_SIMPLE_COMMIT_HH__
---
> #endif // __CPU_O3_COMMIT_HH__