2c2
< * Copyright (c) 2004-2006 The Regents of The University of Michigan
---
> * Copyright (c) 2004-2005 The Regents of The University of Michigan
26a27,28
> *
> * Authors: Kevin Lim
29,30c31,43
< #ifndef __CPU_O3_COMMIT_HH__
< #define __CPU_O3_COMMIT_HH__
---
> // 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.
32c45,47
< #include "arch/faults.hh"
---
> #ifndef __CPU_O3_CPU_SIMPLE_COMMIT_HH__
> #define __CPU_O3_CPU_SIMPLE_COMMIT_HH__
>
35,36d49
< #include "cpu/exetrace.hh"
< #include "cpu/inst_seq.hh"
39,63d51
< 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.
< */
65c53
< class DefaultCommit
---
> class SimpleCommit
74d61
< typedef typename CPUPol::RenameMap RenameMap;
78d64
< typedef typename CPUPol::FetchStruct FetchStruct;
82,108c68,74
< 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 {
---
> 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 {
112,113c78,79
< TrapPending,
< FetchTrapPending
---
> DcacheMissStall,
> DcacheMissComplete
116,122d81
< /** Commit policy for SMT mode. */
< enum CommitPolicy {
< Aggressive,
< RoundRobin,
< OldestReady
< };
<
124,131c83
< /** 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;
---
> Status _status;
134,135c86
< /** Construct a DefaultCommit with the given parameters. */
< DefaultCommit(Params *params);
---
> SimpleCommit(Params &params);
137,140d87
< /** Returns the name of the DefaultCommit. */
< std::string name() const;
<
< /** Registers statistics. */
143d89
< /** Sets the CPU pointer. */
146,149d91
< /** Sets the list of threads. */
< void setThreads(std::vector<Thread *> &threads);
<
< /** Sets the main time buffer pointer, used for backwards communication. */
152,154d93
< void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr);
<
< /** Sets the pointer to the queue coming from rename. */
157d95
< /** Sets the pointer to the queue coming from IEW. */
160,179d97
< 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. */
182,191d99
< /** 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. */
194,196d101
< /** Handles any squashes that are sent from IEW, and adds instructions
< * to the ROB and tries to commit instructions.
< */
199,203d103
< /** Returns the number of free ROB entries for a specific thread. */
< unsigned numROBFreeEntries(unsigned tid);
<
< void generateXCEvent(unsigned tid);
<
205,207d104
< /** Updates the overall status of commit with the nextStatus, and
< * tell the CPU if commit is active/inactive. */
< void updateStatus();
209,231d105
< /** 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. */
234,236d107
< /** Tries to commit the head ROB instruction passed in.
< * @param head_inst The instruction to be committed.
< */
239,241d109
< void generateTrapEvent(unsigned tid);
<
< /** Gets instructions from rename and inserts them into the ROB. */
244d111
< /** Marks completed instructions using information sent from IEW. */
247,255d113
< /** 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();
<
257,260c115
< /** 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]; }
---
> uint64_t readCommitPC();
262c117
< uint64_t readPC(unsigned tid) { return PC[tid]; }
---
> void setSquashing() { _status = ROBSquashing; }
264,269d118
< 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; }
<
280,283d128
< TimeBuffer<FetchStruct> *fetchQueue;
<
< typename TimeBuffer<FetchStruct>::wire fromFetch;
<
296d140
< public:
300d143
< private:
307,334c150
< std::vector<Thread *> thread;
<
< 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;
<
---
> private:
338,340d153
< /** Commit to IEW delay, in ticks. */
< unsigned commitToIEWDelay;
<
344,345d156
< unsigned fetchToCommitDelay;
<
359,389d169
< /** 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. */
391,392d170
< /** Stat for the total number of squashed instructions discarded by commit.
< */
394,396d171
< /** Stat for the total number of times commit is told to squash.
< * @todo: Actually increment this stat.
< */
398,400d172
< /** Stat for the total number of times commit has had to stall due to a non-
< * speculative instruction reaching the head of the ROB.
< */
402c174,176
< /** Stat for the total number of branch mispredicts that caused a squash. */
---
> Stats::Scalar<> commitCommittedBranches;
> Stats::Scalar<> commitCommittedLoads;
> Stats::Scalar<> commitCommittedMemRefs;
404,405d177
< /** Distribution of the number of committed instructions each cycle. */
< Stats::Distribution<> numCommittedDist;
407,421c179
< /** 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;
---
> Stats::Distribution<> n_committed_dist;
424c182
< #endif // __CPU_O3_COMMIT_HH__
---
> #endif // __CPU_O3_CPU_SIMPLE_COMMIT_HH__