rob.hh revision 2292
1/*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef __CPU_O3_ROB_HH__
30#define __CPU_O3_ROB_HH__
31
32#include <string>
33#include <utility>
34#include <vector>
35
36/**
37 * ROB class.  The ROB is largely what drives squashing.
38 */
39template <class Impl>
40class ROB
41{
42  protected:
43    typedef TheISA::RegIndex RegIndex;
44  public:
45    //Typedefs from the Impl.
46    typedef typename Impl::FullCPU FullCPU;
47    typedef typename Impl::DynInstPtr DynInstPtr;
48
49    typedef std::pair<RegIndex, PhysRegIndex> UnmapInfo;
50    typedef typename std::list<DynInstPtr>::iterator InstIt;
51
52    /** Possible ROB statuses. */
53    enum Status {
54        Running,
55        Idle,
56        ROBSquashing,
57        DcacheMissStall,
58        DcacheMissComplete
59    };
60
61    /** SMT ROB Sharing Policy */
62    enum ROBPolicy{
63        Dynamic,
64        Partitioned,
65        Threshold
66    };
67
68  private:
69    /** Per-thread ROB status. */
70    Status robStatus[Impl::MaxThreads];
71
72    /** ROB resource sharing policy for SMT mode. */
73    ROBPolicy robPolicy;
74
75  public:
76    /** ROB constructor.
77     *  @param _numEntries      Number of entries in ROB.
78     *  @param _squashWidth     Number of instructions that can be squashed in a
79     *                          single cycle.
80     *  @param _smtROBPolicy    ROB Partitioning Scheme for SMT.
81     *  @param _smtROBThreshold Max Resources(by %) a thread can have in the ROB.
82     *  @param _numThreads      The number of active threads.
83     */
84    ROB(unsigned _numEntries, unsigned _squashWidth, std::string smtROBPolicy,
85        unsigned _smtROBThreshold, unsigned _numThreads);
86
87    std::string name() const;
88
89    /** Function to set the CPU pointer, necessary due to which object the ROB
90     *  is created within.
91     *  @param cpu_ptr Pointer to the implementation specific full CPU object.
92     */
93    void setCPU(FullCPU *cpu_ptr);
94
95    /** Sets pointer to the list of active threads.
96     *  @param at_ptr Pointer to the list of active threads.
97     */
98    void setActiveThreads(std::list<unsigned>* at_ptr);
99
100    /** Function to insert an instruction into the ROB. Note that whatever
101     *  calls this function must ensure that there is enough space within the
102     *  ROB for the new instruction.
103     *  @param inst The instruction being inserted into the ROB.
104     */
105    void insertInst(DynInstPtr &inst);
106
107    /** Returns pointer to the head instruction within the ROB.  There is
108     *  no guarantee as to the return value if the ROB is empty.
109     *  @retval Pointer to the DynInst that is at the head of the ROB.
110     */
111    DynInstPtr readHeadInst();
112
113    /** Returns a pointer to the head instruction of a specific thread within
114     *  the ROB.
115     *  @return Pointer to the DynInst that is at the head of the ROB.
116     */
117    DynInstPtr readHeadInst(unsigned tid);
118
119    /** Returns pointer to the tail instruction within the ROB.  There is
120     *  no guarantee as to the return value if the ROB is empty.
121     *  @retval Pointer to the DynInst that is at the tail of the ROB.
122     */
123    DynInstPtr readTailInst();
124
125    /** Returns a pointer to the tail instruction of a specific thread within
126     *  the ROB.
127     *  @return Pointer to the DynInst that is at the tail of the ROB.
128     */
129    DynInstPtr readTailInst(unsigned tid);
130
131    /** Retires the head instruction, removing it from the ROB. */
132    void retireHead();
133
134    /** Retires the head instruction of a specific thread, removing it from the
135     *  ROB.
136     */
137    void retireHead(unsigned tid);
138
139    /** Is the oldest instruction across all threads ready. */
140    bool isHeadReady();
141
142    /** Is the oldest instruction across a particular thread ready. */
143    bool isHeadReady(unsigned tid);
144
145    /** Is there any commitable head instruction across all threads ready. */
146    bool canCommit();
147
148    /** Re-adjust ROB partitioning. */
149    void resetEntries();
150
151    /** Number of entries needed For 'num_threads' amount of threads. */
152    int entryAmount(int num_threads);
153
154    /** Returns the number of total free entries in the ROB. */
155    unsigned numFreeEntries();
156
157    /** Returns the number of free entries in a specific ROB paritition. */
158    unsigned numFreeEntries(unsigned tid);
159
160    /** Returns the maximum number of entries for a specific thread. */
161    unsigned getMaxEntries(unsigned tid)
162    { return maxEntries[tid]; }
163
164    /** Returns the number of entries being used by a specific thread. */
165    unsigned getThreadEntries(unsigned tid)
166    { return threadEntries[tid]; }
167
168    /** Returns if the ROB is full. */
169    bool isFull()
170    { return numInstsInROB == numEntries; }
171
172    /** Returns if a specific thread's partition is full. */
173    bool isFull(unsigned tid)
174    { return threadEntries[tid] == numEntries; }
175
176    /** Returns if the ROB is empty. */
177    bool isEmpty()
178    { return numInstsInROB == 0; }
179
180    /** Returns if a specific thread's partition is empty. */
181    bool isEmpty(unsigned tid)
182    { return threadEntries[tid] == 0; }
183
184    /** Executes the squash, marking squashed instructions. */
185    void doSquash(unsigned tid);
186
187    /** Squashes all instructions younger than the given sequence number for
188     *  the specific thread.
189     */
190    void squash(InstSeqNum squash_num, unsigned tid);
191
192    /** Updates the head instruction with the new oldest instruction. */
193    void updateHead();
194
195    /** Updates the tail instruction with the new youngest instruction. */
196    void updateTail();
197
198    /** Reads the PC of the oldest head instruction. */
199    uint64_t readHeadPC();
200
201    /** Reads the PC of the head instruction of a specific thread. */
202    uint64_t readHeadPC(unsigned tid);
203
204    /** Reads the next PC of the oldest head instruction. */
205    uint64_t readHeadNextPC();
206
207    /** Reads the next PC of the head instruction of a specific thread. */
208    uint64_t readHeadNextPC(unsigned tid);
209
210    /** Reads the sequence number of the oldest head instruction. */
211    InstSeqNum readHeadSeqNum();
212
213    /** Reads the sequence number of the head instruction of a specific thread.
214     */
215    InstSeqNum readHeadSeqNum(unsigned tid);
216
217    /** Reads the PC of the youngest tail instruction. */
218    uint64_t readTailPC();
219
220    /** Reads the PC of the tail instruction of a specific thread. */
221    uint64_t readTailPC(unsigned tid);
222
223    /** Reads the sequence number of the youngest tail instruction. */
224    InstSeqNum readTailSeqNum();
225
226    /** Reads the sequence number of tail instruction of a specific thread. */
227    InstSeqNum readTailSeqNum(unsigned tid);
228
229    /** Checks if the ROB is still in the process of squashing instructions.
230     *  @retval Whether or not the ROB is done squashing.
231     */
232    bool isDoneSquashing(unsigned tid) const
233    { return doneSquashing[tid]; }
234
235    /** Checks if the ROB is still in the process of squashing instructions for
236     *  any thread.
237     */
238    bool isDoneSquashing();
239
240    /** This is more of a debugging function than anything.  Use
241     *  numInstsInROB to get the instructions in the ROB unless you are
242     *  double checking that variable.
243     */
244    int countInsts();
245
246    /** This is more of a debugging function than anything.  Use
247     *  threadEntries to get the instructions in the ROB unless you are
248     *  double checking that variable.
249     */
250    int countInsts(unsigned tid);
251
252  private:
253    /** Pointer to the CPU. */
254    FullCPU *cpu;
255
256    /** Active Threads in CPU */
257    std::list<unsigned>* activeThreads;
258
259    /** Number of instructions in the ROB. */
260    unsigned numEntries;
261
262    /** Entries Per Thread */
263    unsigned threadEntries[Impl::MaxThreads];
264
265    /** Max Insts a Thread Can Have in the ROB */
266    unsigned maxEntries[Impl::MaxThreads];
267
268    /** ROB List of Instructions */
269    std::list<DynInstPtr> instList[Impl::MaxThreads];
270
271    /** Number of instructions that can be squashed in a single cycle. */
272    unsigned squashWidth;
273
274  public:
275    /** Iterator pointing to the instruction which is the last instruction
276     *  in the ROB.  This may at times be invalid (ie when the ROB is empty),
277     *  however it should never be incorrect.
278     */
279    InstIt tail;
280
281    /** Iterator pointing to the instruction which is the first instruction in
282     *  in the ROB*/
283    InstIt head;
284
285  private:
286    /** Iterator used for walking through the list of instructions when
287     *  squashing.  Used so that there is persistent state between cycles;
288     *  when squashing, the instructions are marked as squashed but not
289     *  immediately removed, meaning the tail iterator remains the same before
290     *  and after a squash.
291     *  This will always be set to cpu->instList.end() if it is invalid.
292     */
293    InstIt squashIt[Impl::MaxThreads];
294
295  public:
296    /** Number of instructions in the ROB. */
297    int numInstsInROB;
298
299    DynInstPtr dummyInst;
300
301  private:
302    /** The sequence number of the squashed instruction. */
303    InstSeqNum squashedSeqNum;
304
305    /** Is the ROB done squashing. */
306    bool doneSquashing[Impl::MaxThreads];
307
308    /** Number of active threads. */
309    unsigned numThreads;
310};
311
312#endif //__CPU_O3_ROB_HH__
313