summaryrefslogtreecommitdiff
path: root/cpu/beta_cpu/iew.hh
blob: e3e7c6db53a343da9aafd85de63a136ba01018da (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
//Todo: Update with statuses.
//Need to handle delaying writes to the writeback bus if it's full at the
//given time.  Load store queue.

#ifndef __CPU_BETA_CPU_SIMPLE_IEW_HH__
#define __CPU_BETA_CPU_SIMPLE_IEW_HH__

#include <queue>

#include "base/statistics.hh"
#include "base/timebuf.hh"
#include "cpu/beta_cpu/comm.hh"

//Can IEW even stall?  Space should be available/allocated already...maybe
//if there's not enough write ports on the ROB or waiting for CDB
//arbitration.
template<class Impl, class IQ>
class SimpleIEW
{
  private:
    //Typedefs from Impl
    typedef typename Impl::ISA ISA;
    typedef typename Impl::CPUPol CPUPol;
    typedef typename Impl::DynInstPtr DynInstPtr;
    typedef typename Impl::FullCPU FullCPU;
    typedef typename Impl::Params Params;

    typedef typename CPUPol::RenameMap RenameMap;
    typedef typename CPUPol::LDSTQ LDSTQ;

    typedef typename CPUPol::TimeStruct TimeStruct;
    typedef typename CPUPol::IEWStruct IEWStruct;
    typedef typename CPUPol::RenameStruct RenameStruct;
    typedef typename CPUPol::IssueStruct IssueStruct;

  public:
    enum Status {
        Running,
        Blocked,
        Idle,
        Squashing,
        Unblocking
    };

  private:
    Status _status;
    Status _issueStatus;
    Status _exeStatus;
    Status _wbStatus;

  public:
    void squash();

    void squashDueToBranch(DynInstPtr &inst);

    void squashDueToMem(DynInstPtr &inst);

    void block();

    inline void unblock();

  public:
    SimpleIEW(Params &params);

    void regStats();

    void setCPU(FullCPU *cpu_ptr);

    void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr);

    void setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr);

    void setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr);

    void setRenameMap(RenameMap *rm_ptr);

    void wakeDependents(DynInstPtr &inst);

    void tick();

    void iew();

  private:
    void dispatchInsts();

    void executeInsts();

    //Interfaces to objects inside and outside of IEW.
    /** Time buffer interface. */
    TimeBuffer<TimeStruct> *timeBuffer;

    /** Wire to get commit's output from backwards time buffer. */
    typename TimeBuffer<TimeStruct>::wire fromCommit;

    /** Wire to write information heading to previous stages. */
    typename TimeBuffer<TimeStruct>::wire toRename;

    /** Rename instruction queue interface. */
    TimeBuffer<RenameStruct> *renameQueue;

    /** Wire to get rename's output from rename queue. */
    typename TimeBuffer<RenameStruct>::wire fromRename;

    /** Issue stage queue. */
    TimeBuffer<IssueStruct> issueToExecQueue;

    /** Wire to read information from the issue stage time queue. */
    typename TimeBuffer<IssueStruct>::wire fromIssue;

    /**
     * IEW stage time buffer.  Holds ROB indices of instructions that
     * can be marked as completed.
     */
    TimeBuffer<IEWStruct> *iewQueue;

    /** Wire to write infromation heading to commit. */
    typename TimeBuffer<IEWStruct>::wire toCommit;

    //Will need internal queue to hold onto instructions coming from
    //the rename stage in case of a stall.
    /** Skid buffer between rename and IEW. */
    std::queue<RenameStruct> skidBuffer;

    /** Instruction queue. */
    IQ instQueue;

    LDSTQ ldstQueue;

    /** Pointer to rename map.  Might not want this stage to directly
     *  access this though...
     */
    RenameMap *renameMap;

    /** CPU interface. */
    FullCPU *cpu;

  private:
    /** Commit to IEW delay, in ticks. */
    unsigned commitToIEWDelay;

    /** Rename to IEW delay, in ticks. */
    unsigned renameToIEWDelay;

    /**
     * Issue to execute delay, in ticks.  What this actually represents is
     * the amount of time it takes for an instruction to wake up, be
     * scheduled, and sent to a FU for execution.
     */
    unsigned issueToExecuteDelay;

    /** Width of issue's read path, in instructions.  The read path is both
     *  the skid buffer and the rename instruction queue.
     *  Note to self: is this really different than issueWidth?
     */
    unsigned issueReadWidth;

    /** Width of issue, in instructions. */
    unsigned issueWidth;

    /** Width of execute, in instructions.  Might make more sense to break
     *  down into FP vs int.
     */
    unsigned executeWidth;

    /** Number of cycles stage has been squashing.  Used so that the stage
     *  knows when it can start unblocking, which is when the previous stage
     *  has received the stall signal and clears up its outputs.
     */
    unsigned cyclesSquashing;

    Stats::Scalar<> iewIdleCycles;
    Stats::Scalar<> iewSquashCycles;
    Stats::Scalar<> iewBlockCycles;
    Stats::Scalar<> iewUnblockCycles;
//    Stats::Scalar<> iewWBInsts;
    Stats::Scalar<> iewDispatchedInsts;
    Stats::Scalar<> iewDispSquashedInsts;
    Stats::Scalar<> iewDispLoadInsts;
    Stats::Scalar<> iewDispStoreInsts;
    Stats::Scalar<> iewDispNonSpecInsts;
    Stats::Scalar<> iewIQFullEvents;
    Stats::Scalar<> iewExecutedInsts;
    Stats::Scalar<> iewExecLoadInsts;
    Stats::Scalar<> iewExecStoreInsts;
    Stats::Scalar<> iewExecSquashedInsts;
    Stats::Scalar<> memOrderViolationEvents;
    Stats::Scalar<> predictedTakenIncorrect;
};

#endif // __CPU_BETA_CPU_IEW_HH__