iew.hh revision 1681
1//Todo: Update with statuses.
2//Need to handle delaying writes to the writeback bus if it's full at the
3//given time.  Load store queue.
4
5#ifndef __CPU_BETA_CPU_SIMPLE_IEW_HH__
6#define __CPU_BETA_CPU_SIMPLE_IEW_HH__
7
8#include <queue>
9
10#include "base/statistics.hh"
11#include "base/timebuf.hh"
12#include "cpu/beta_cpu/comm.hh"
13
14//Can IEW even stall?  Space should be available/allocated already...maybe
15//if there's not enough write ports on the ROB or waiting for CDB
16//arbitration.
17template<class Impl>
18class SimpleIEW
19{
20  private:
21    //Typedefs from Impl
22    typedef typename Impl::ISA ISA;
23    typedef typename Impl::CPUPol CPUPol;
24    typedef typename Impl::DynInstPtr DynInstPtr;
25    typedef typename Impl::FullCPU FullCPU;
26    typedef typename Impl::Params Params;
27
28    typedef typename CPUPol::IQ IQ;
29    typedef typename CPUPol::RenameMap RenameMap;
30    typedef typename CPUPol::LDSTQ LDSTQ;
31
32    typedef typename CPUPol::TimeStruct TimeStruct;
33    typedef typename CPUPol::IEWStruct IEWStruct;
34    typedef typename CPUPol::RenameStruct RenameStruct;
35    typedef typename CPUPol::IssueStruct IssueStruct;
36
37    friend class Impl::FullCPU;
38  public:
39    enum Status {
40        Running,
41        Blocked,
42        Idle,
43        Squashing,
44        Unblocking
45    };
46
47  private:
48    Status _status;
49    Status _issueStatus;
50    Status _exeStatus;
51    Status _wbStatus;
52
53  public:
54    class WritebackEvent : public Event {
55      private:
56        DynInstPtr inst;
57        SimpleIEW<Impl> *iewStage;
58
59      public:
60        WritebackEvent(DynInstPtr &_inst, SimpleIEW<Impl> *_iew);
61
62        virtual void process();
63        virtual const char *description();
64    };
65
66  public:
67    SimpleIEW(Params &params);
68
69    void regStats();
70
71    void setCPU(FullCPU *cpu_ptr);
72
73    void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);
74
75    void setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr);
76
77    void setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr);
78
79    void setRenameMap(RenameMap *rm_ptr);
80
81    void squash();
82
83    void squashDueToBranch(DynInstPtr &inst);
84
85    void squashDueToMem(DynInstPtr &inst);
86
87    void block();
88
89    inline void unblock();
90
91    void wakeDependents(DynInstPtr &inst);
92
93    void instToCommit(DynInstPtr &inst);
94
95  private:
96    void dispatchInsts();
97
98    void executeInsts();
99
100  public:
101    void tick();
102
103    void iew();
104
105    //Interfaces to objects inside and outside of IEW.
106    /** Time buffer interface. */
107    TimeBuffer<TimeStruct> *timeBuffer;
108
109    /** Wire to get commit's output from backwards time buffer. */
110    typename TimeBuffer<TimeStruct>::wire fromCommit;
111
112    /** Wire to write information heading to previous stages. */
113    typename TimeBuffer<TimeStruct>::wire toRename;
114
115    /** Rename instruction queue interface. */
116    TimeBuffer<RenameStruct> *renameQueue;
117
118    /** Wire to get rename's output from rename queue. */
119    typename TimeBuffer<RenameStruct>::wire fromRename;
120
121    /** Issue stage queue. */
122    TimeBuffer<IssueStruct> issueToExecQueue;
123
124    /** Wire to read information from the issue stage time queue. */
125    typename TimeBuffer<IssueStruct>::wire fromIssue;
126
127    /**
128     * IEW stage time buffer.  Holds ROB indices of instructions that
129     * can be marked as completed.
130     */
131    TimeBuffer<IEWStruct> *iewQueue;
132
133    /** Wire to write infromation heading to commit. */
134    typename TimeBuffer<IEWStruct>::wire toCommit;
135
136    //Will need internal queue to hold onto instructions coming from
137    //the rename stage in case of a stall.
138    /** Skid buffer between rename and IEW. */
139    std::queue<RenameStruct> skidBuffer;
140
141  protected:
142    /** Instruction queue. */
143    IQ instQueue;
144
145    LDSTQ ldstQueue;
146
147#ifndef FULL_SYSTEM
148  public:
149    void lsqWriteback();
150#endif
151
152  private:
153    /** Pointer to rename map.  Might not want this stage to directly
154     *  access this though...
155     */
156    RenameMap *renameMap;
157
158    /** CPU interface. */
159    FullCPU *cpu;
160
161  private:
162    /** Commit to IEW delay, in ticks. */
163    unsigned commitToIEWDelay;
164
165    /** Rename to IEW delay, in ticks. */
166    unsigned renameToIEWDelay;
167
168    /**
169     * Issue to execute delay, in ticks.  What this actually represents is
170     * the amount of time it takes for an instruction to wake up, be
171     * scheduled, and sent to a FU for execution.
172     */
173    unsigned issueToExecuteDelay;
174
175    /** Width of issue's read path, in instructions.  The read path is both
176     *  the skid buffer and the rename instruction queue.
177     *  Note to self: is this really different than issueWidth?
178     */
179    unsigned issueReadWidth;
180
181    /** Width of issue, in instructions. */
182    unsigned issueWidth;
183
184    /** Width of execute, in instructions.  Might make more sense to break
185     *  down into FP vs int.
186     */
187    unsigned executeWidth;
188
189    /** Number of cycles stage has been squashing.  Used so that the stage
190     *  knows when it can start unblocking, which is when the previous stage
191     *  has received the stall signal and clears up its outputs.
192     */
193    unsigned cyclesSquashing;
194
195    Stats::Scalar<> iewIdleCycles;
196    Stats::Scalar<> iewSquashCycles;
197    Stats::Scalar<> iewBlockCycles;
198    Stats::Scalar<> iewUnblockCycles;
199//    Stats::Scalar<> iewWBInsts;
200    Stats::Scalar<> iewDispatchedInsts;
201    Stats::Scalar<> iewDispSquashedInsts;
202    Stats::Scalar<> iewDispLoadInsts;
203    Stats::Scalar<> iewDispStoreInsts;
204    Stats::Scalar<> iewDispNonSpecInsts;
205    Stats::Scalar<> iewIQFullEvents;
206    Stats::Scalar<> iewExecutedInsts;
207    Stats::Scalar<> iewExecLoadInsts;
208    Stats::Scalar<> iewExecStoreInsts;
209    Stats::Scalar<> iewExecSquashedInsts;
210    Stats::Scalar<> memOrderViolationEvents;
211    Stats::Scalar<> predictedTakenIncorrect;
212};
213
214#endif // __CPU_BETA_CPU_IEW_HH__
215