rob.hh (2665:a124942bacb8) rob.hh (2670:9107b8bd08cd)
1/*
1/*
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
2 * Copyright (c) 2004-2006 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

--- 12 unchanged lines hidden (view full) ---

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 * Authors: Kevin Lim
29 */
30
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

--- 12 unchanged lines hidden (view full) ---

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 * Authors: Kevin Lim
29 */
30
31// Todo: Probably add in support for scheduling events (more than one as
32// well) on the case of the ROB being empty or full. Considering tracking
33// free entries instead of insts in ROB. Differentiate between squashing
34// all instructions after the instruction, and all instructions after *and*
35// including that instruction.
31#ifndef __CPU_O3_ROB_HH__
32#define __CPU_O3_ROB_HH__
36
33
37#ifndef __CPU_O3_CPU_ROB_HH__
38#define __CPU_O3_CPU_ROB_HH__
39
34#include <string>
40#include <utility>
41#include <vector>
42
43/**
35#include <utility>
36#include <vector>
37
38/**
44 * ROB class. Uses the instruction list that exists within the CPU to
45 * represent the ROB. This class doesn't contain that list, but instead
46 * a pointer to the CPU to get access to the list. The ROB, in this first
47 * implementation, is largely what drives squashing.
39 * ROB class. The ROB is largely what drives squashing.
48 */
49template <class Impl>
50class ROB
51{
52 protected:
53 typedef TheISA::RegIndex RegIndex;
54 public:
55 //Typedefs from the Impl.
56 typedef typename Impl::FullCPU FullCPU;
57 typedef typename Impl::DynInstPtr DynInstPtr;
58
40 */
41template <class Impl>
42class ROB
43{
44 protected:
45 typedef TheISA::RegIndex RegIndex;
46 public:
47 //Typedefs from the Impl.
48 typedef typename Impl::FullCPU FullCPU;
49 typedef typename Impl::DynInstPtr DynInstPtr;
50
59 typedef std::pair<RegIndex, PhysRegIndex> UnmapInfo_t;
60 typedef typename list<DynInstPtr>::iterator InstIt_t;
51 typedef std::pair UnmapInfo;
52 typedef typename std::list<DynInstPtr>::iterator InstIt;
61
53
54 /** Possible ROB statuses. */
55 enum Status {
56 Running,
57 Idle,
58 ROBSquashing
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
62 public:
63 /** ROB constructor.
75 public:
76 /** ROB constructor.
64 * @param _numEntries Number of entries in ROB.
65 * @param _squashWidth Number of instructions that can be squashed in a
66 * single cycle.
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.
67 */
83 */
68 ROB(unsigned _numEntries, unsigned _squashWidth);
84 ROB(unsigned _numEntries, unsigned _squashWidth, std::string smtROBPolicy,
85 unsigned _smtROBThreshold, unsigned _numThreads);
69
86
87 std::string name() const;
88
70 /** Function to set the CPU pointer, necessary due to which object the ROB
71 * is created within.
72 * @param cpu_ptr Pointer to the implementation specific full CPU object.
73 */
74 void setCPU(FullCPU *cpu_ptr);
75
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
76 /** Function to insert an instruction into the ROB. The parameter inst is
77 * not truly required, but is useful for checking correctness. Note
78 * that whatever calls this function must ensure that there is enough
79 * space within the ROB for the new instruction.
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 void switchOut();
101
102 void takeOverFrom();
103
104 /** Function to insert an instruction into the ROB. Note that whatever
105 * calls this function must ensure that there is enough space within the
106 * ROB for the new instruction.
80 * @param inst The instruction being inserted into the ROB.
107 * @param inst The instruction being inserted into the ROB.
81 * @todo Remove the parameter once correctness is ensured.
82 */
83 void insertInst(DynInstPtr &inst);
84
85 /** Returns pointer to the head instruction within the ROB. There is
86 * no guarantee as to the return value if the ROB is empty.
87 * @retval Pointer to the DynInst that is at the head of the ROB.
88 */
108 */
109 void insertInst(DynInstPtr &inst);
110
111 /** Returns pointer to the head instruction within the ROB. There is
112 * no guarantee as to the return value if the ROB is empty.
113 * @retval Pointer to the DynInst that is at the head of the ROB.
114 */
89 DynInstPtr readHeadInst() { return cpu->instList.front(); }
115// DynInstPtr readHeadInst();
90
116
91 DynInstPtr readTailInst() { return (*tail); }
117 /** Returns a pointer to the head instruction of a specific thread within
118 * the ROB.
119 * @return Pointer to the DynInst that is at the head of the ROB.
120 */
121 DynInstPtr readHeadInst(unsigned tid);
92
122
93 void retireHead();
123 /** Returns pointer to the tail instruction within the ROB. There is
124 * no guarantee as to the return value if the ROB is empty.
125 * @retval Pointer to the DynInst that is at the tail of the ROB.
126 */
127// DynInstPtr readTailInst();
94
128
95 bool isHeadReady();
129 /** Returns a pointer to the tail instruction of a specific thread within
130 * the ROB.
131 * @return Pointer to the DynInst that is at the tail of the ROB.
132 */
133 DynInstPtr readTailInst(unsigned tid);
96
134
135 /** Retires the head instruction, removing it from the ROB. */
136// void retireHead();
137
138 /** Retires the head instruction of a specific thread, removing it from the
139 * ROB.
140 */
141 void retireHead(unsigned tid);
142
143 /** Is the oldest instruction across all threads ready. */
144// bool isHeadReady();
145
146 /** Is the oldest instruction across a particular thread ready. */
147 bool isHeadReady(unsigned tid);
148
149 /** Is there any commitable head instruction across all threads ready. */
150 bool canCommit();
151
152 /** Re-adjust ROB partitioning. */
153 void resetEntries();
154
155 /** Number of entries needed For 'num_threads' amount of threads. */
156 int entryAmount(int num_threads);
157
158 /** Returns the number of total free entries in the ROB. */
97 unsigned numFreeEntries();
98
159 unsigned numFreeEntries();
160
161 /** Returns the number of free entries in a specific ROB paritition. */
162 unsigned numFreeEntries(unsigned tid);
163
164 /** Returns the maximum number of entries for a specific thread. */
165 unsigned getMaxEntries(unsigned tid)
166 { return maxEntries[tid]; }
167
168 /** Returns the number of entries being used by a specific thread. */
169 unsigned getThreadEntries(unsigned tid)
170 { return threadEntries[tid]; }
171
172 /** Returns if the ROB is full. */
99 bool isFull()
100 { return numInstsInROB == numEntries; }
101
173 bool isFull()
174 { return numInstsInROB == numEntries; }
175
176 /** Returns if a specific thread's partition is full. */
177 bool isFull(unsigned tid)
178 { return threadEntries[tid] == numEntries; }
179
180 /** Returns if the ROB is empty. */
102 bool isEmpty()
103 { return numInstsInROB == 0; }
104
181 bool isEmpty()
182 { return numInstsInROB == 0; }
183
105 void doSquash();
184 /** Returns if a specific thread's partition is empty. */
185 bool isEmpty(unsigned tid)
186 { return threadEntries[tid] == 0; }
106
187
107 void squash(InstSeqNum squash_num);
188 /** Executes the squash, marking squashed instructions. */
189 void doSquash(unsigned tid);
108
190
109 uint64_t readHeadPC();
191 /** Squashes all instructions younger than the given sequence number for
192 * the specific thread.
193 */
194 void squash(InstSeqNum squash_num, unsigned tid);
110
195
111 uint64_t readHeadNextPC();
196 /** Updates the head instruction with the new oldest instruction. */
197 void updateHead();
112
198
113 InstSeqNum readHeadSeqNum();
199 /** Updates the tail instruction with the new youngest instruction. */
200 void updateTail();
114
201
115 uint64_t readTailPC();
202 /** Reads the PC of the oldest head instruction. */
203// uint64_t readHeadPC();
116
204
117 InstSeqNum readTailSeqNum();
205 /** Reads the PC of the head instruction of a specific thread. */
206// uint64_t readHeadPC(unsigned tid);
118
207
208 /** Reads the next PC of the oldest head instruction. */
209// uint64_t readHeadNextPC();
210
211 /** Reads the next PC of the head instruction of a specific thread. */
212// uint64_t readHeadNextPC(unsigned tid);
213
214 /** Reads the sequence number of the oldest head instruction. */
215// InstSeqNum readHeadSeqNum();
216
217 /** Reads the sequence number of the head instruction of a specific thread.
218 */
219// InstSeqNum readHeadSeqNum(unsigned tid);
220
221 /** Reads the PC of the youngest tail instruction. */
222// uint64_t readTailPC();
223
224 /** Reads the PC of the tail instruction of a specific thread. */
225// uint64_t readTailPC(unsigned tid);
226
227 /** Reads the sequence number of the youngest tail instruction. */
228// InstSeqNum readTailSeqNum();
229
230 /** Reads the sequence number of tail instruction of a specific thread. */
231// InstSeqNum readTailSeqNum(unsigned tid);
232
119 /** Checks if the ROB is still in the process of squashing instructions.
120 * @retval Whether or not the ROB is done squashing.
121 */
233 /** Checks if the ROB is still in the process of squashing instructions.
234 * @retval Whether or not the ROB is done squashing.
235 */
122 bool isDoneSquashing() const { return doneSquashing; }
236 bool isDoneSquashing(unsigned tid) const
237 { return doneSquashing[tid]; }
123
238
239 /** Checks if the ROB is still in the process of squashing instructions for
240 * any thread.
241 */
242 bool isDoneSquashing();
243
124 /** This is more of a debugging function than anything. Use
125 * numInstsInROB to get the instructions in the ROB unless you are
126 * double checking that variable.
127 */
128 int countInsts();
129
244 /** This is more of a debugging function than anything. Use
245 * numInstsInROB to get the instructions in the ROB unless you are
246 * double checking that variable.
247 */
248 int countInsts();
249
130 private:
250 /** This is more of a debugging function than anything. Use
251 * threadEntries to get the instructions in the ROB unless you are
252 * double checking that variable.
253 */
254 int countInsts(unsigned tid);
131
255
256 private:
132 /** Pointer to the CPU. */
133 FullCPU *cpu;
134
257 /** Pointer to the CPU. */
258 FullCPU *cpu;
259
260 /** Active Threads in CPU */
261 std::list<unsigned>* activeThreads;
262
135 /** Number of instructions in the ROB. */
136 unsigned numEntries;
137
263 /** Number of instructions in the ROB. */
264 unsigned numEntries;
265
266 /** Entries Per Thread */
267 unsigned threadEntries[Impl::MaxThreads];
268
269 /** Max Insts a Thread Can Have in the ROB */
270 unsigned maxEntries[Impl::MaxThreads];
271
272 /** ROB List of Instructions */
273 std::list<DynInstPtr> instList[Impl::MaxThreads];
274
138 /** Number of instructions that can be squashed in a single cycle. */
139 unsigned squashWidth;
140
275 /** Number of instructions that can be squashed in a single cycle. */
276 unsigned squashWidth;
277
278 public:
141 /** Iterator pointing to the instruction which is the last instruction
142 * in the ROB. This may at times be invalid (ie when the ROB is empty),
143 * however it should never be incorrect.
144 */
279 /** Iterator pointing to the instruction which is the last instruction
280 * in the ROB. This may at times be invalid (ie when the ROB is empty),
281 * however it should never be incorrect.
282 */
145 InstIt_t tail;
283 InstIt tail;
146
284
285 /** Iterator pointing to the instruction which is the first instruction in
286 * in the ROB*/
287 InstIt head;
288
289 private:
147 /** Iterator used for walking through the list of instructions when
148 * squashing. Used so that there is persistent state between cycles;
149 * when squashing, the instructions are marked as squashed but not
150 * immediately removed, meaning the tail iterator remains the same before
151 * and after a squash.
152 * This will always be set to cpu->instList.end() if it is invalid.
153 */
290 /** Iterator used for walking through the list of instructions when
291 * squashing. Used so that there is persistent state between cycles;
292 * when squashing, the instructions are marked as squashed but not
293 * immediately removed, meaning the tail iterator remains the same before
294 * and after a squash.
295 * This will always be set to cpu->instList.end() if it is invalid.
296 */
154 InstIt_t squashIt;
297 InstIt squashIt[Impl::MaxThreads];
155
298
299 public:
156 /** Number of instructions in the ROB. */
157 int numInstsInROB;
158
300 /** Number of instructions in the ROB. */
301 int numInstsInROB;
302
303 DynInstPtr dummyInst;
304
305 private:
159 /** The sequence number of the squashed instruction. */
160 InstSeqNum squashedSeqNum;
161
162 /** Is the ROB done squashing. */
306 /** The sequence number of the squashed instruction. */
307 InstSeqNum squashedSeqNum;
308
309 /** Is the ROB done squashing. */
163 bool doneSquashing;
310 bool doneSquashing[Impl::MaxThreads];
311
312 /** Number of active threads. */
313 unsigned numThreads;
164};
165
314};
315
166#endif //__CPU_O3_CPU_ROB_HH__
316#endif //__CPU_O3_ROB_HH__