iew_impl.hh (2665:a124942bacb8) iew_impl.hh (2669:f2b336e89d2a)
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

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

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.
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

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

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 * Authors: Kevin Lim
29 */
30
31// @todo: Fix the instantaneous communication among all the stages within
32// iew. There's a clear delay between issue and execute, yet backwards
33// communication happens simultaneously.
27 */
28
29// @todo: Fix the instantaneous communication among all the stages within
30// iew. There's a clear delay between issue and execute, yet backwards
31// communication happens simultaneously.
34// Update the statuses for each stage.
35
36#include <queue>
37
38#include "base/timebuf.hh"
32
33#include <queue>
34
35#include "base/timebuf.hh"
36#include "cpu/o3/fu_pool.hh"
39#include "cpu/o3/iew.hh"
40
37#include "cpu/o3/iew.hh"
38
41template<class Impl>
42SimpleIEW<Impl>::WritebackEvent::WritebackEvent(DynInstPtr &_inst,
43 SimpleIEW<Impl> *_iew)
44 : Event(&mainEventQueue, CPU_Tick_Pri), inst(_inst), iewStage(_iew)
45{
46 this->setFlags(Event::AutoDelete);
47}
39using namespace std;
48
49template<class Impl>
40
41template<class Impl>
50void
51SimpleIEW<Impl>::WritebackEvent::process()
52{
53 DPRINTF(IEW, "IEW: WRITEBACK EVENT!!!!\n");
54
55 // Need to insert instruction into queue to commit
56 iewStage->instToCommit(inst);
57 // Need to execute second half of the instruction, do actual writing to
58 // registers and such
59 inst->execute();
60}
61
62template<class Impl>
63const char *
64SimpleIEW<Impl>::WritebackEvent::description()
65{
66 return "LSQ writeback event";
67}
68
69template<class Impl>
70SimpleIEW<Impl>::SimpleIEW(Params &params)
71 : // Just make this time buffer really big for now
42DefaultIEW<Impl>::DefaultIEW(Params *params)
43 : // @todo: Make this into a parameter.
72 issueToExecQueue(5, 5),
73 instQueue(params),
74 ldstQueue(params),
44 issueToExecQueue(5, 5),
45 instQueue(params),
46 ldstQueue(params),
75 commitToIEWDelay(params.commitToIEWDelay),
76 renameToIEWDelay(params.renameToIEWDelay),
77 issueToExecuteDelay(params.issueToExecuteDelay),
78 issueReadWidth(params.issueWidth),
79 issueWidth(params.issueWidth),
80 executeWidth(params.executeWidth)
47 fuPool(params->fuPool),
48 commitToIEWDelay(params->commitToIEWDelay),
49 renameToIEWDelay(params->renameToIEWDelay),
50 issueToExecuteDelay(params->issueToExecuteDelay),
51 issueReadWidth(params->issueWidth),
52 issueWidth(params->issueWidth),
53 executeWidth(params->executeWidth),
54 numThreads(params->numberOfThreads),
55 switchedOut(false)
81{
56{
82 DPRINTF(IEW, "IEW: executeIntWidth: %i.\n", params.executeIntWidth);
83 _status = Idle;
84 _issueStatus = Idle;
85 _exeStatus = Idle;
86 _wbStatus = Idle;
57 _status = Active;
58 exeStatus = Running;
59 wbStatus = Idle;
87
88 // Setup wire to read instructions coming from issue.
89 fromIssue = issueToExecQueue.getWire(-issueToExecuteDelay);
90
91 // Instruction queue needs the queue between issue and execute.
92 instQueue.setIssueToExecuteQueue(&issueToExecQueue);
93
60
61 // Setup wire to read instructions coming from issue.
62 fromIssue = issueToExecQueue.getWire(-issueToExecuteDelay);
63
64 // Instruction queue needs the queue between issue and execute.
65 instQueue.setIssueToExecuteQueue(&issueToExecQueue);
66
67 instQueue.setIEW(this);
94 ldstQueue.setIEW(this);
68 ldstQueue.setIEW(this);
69
70 for (int i=0; i < numThreads; i++) {
71 dispatchStatus[i] = Running;
72 stalls[i].commit = false;
73 fetchRedirect[i] = false;
74 }
75
76 updateLSQNextCycle = false;
77
78 skidBufferMax = (3 * (renameToIEWDelay * params->renameWidth)) + issueWidth;
95}
96
97template <class Impl>
79}
80
81template <class Impl>
82std::string
83DefaultIEW<Impl>::name() const
84{
85 return cpu->name() + ".iew";
86}
87
88template <class Impl>
98void
89void
99SimpleIEW<Impl>::regStats()
90DefaultIEW<Impl>::regStats()
100{
91{
92 using namespace Stats;
93
101 instQueue.regStats();
102
103 iewIdleCycles
104 .name(name() + ".iewIdleCycles")
105 .desc("Number of cycles IEW is idle");
106
107 iewSquashCycles
108 .name(name() + ".iewSquashCycles")
109 .desc("Number of cycles IEW is squashing");
110
111 iewBlockCycles
112 .name(name() + ".iewBlockCycles")
113 .desc("Number of cycles IEW is blocking");
114
115 iewUnblockCycles
116 .name(name() + ".iewUnblockCycles")
117 .desc("Number of cycles IEW is unblocking");
118
94 instQueue.regStats();
95
96 iewIdleCycles
97 .name(name() + ".iewIdleCycles")
98 .desc("Number of cycles IEW is idle");
99
100 iewSquashCycles
101 .name(name() + ".iewSquashCycles")
102 .desc("Number of cycles IEW is squashing");
103
104 iewBlockCycles
105 .name(name() + ".iewBlockCycles")
106 .desc("Number of cycles IEW is blocking");
107
108 iewUnblockCycles
109 .name(name() + ".iewUnblockCycles")
110 .desc("Number of cycles IEW is unblocking");
111
119// iewWBInsts;
120
121 iewDispatchedInsts
122 .name(name() + ".iewDispatchedInsts")
123 .desc("Number of instructions dispatched to IQ");
124
125 iewDispSquashedInsts
126 .name(name() + ".iewDispSquashedInsts")
127 .desc("Number of squashed instructions skipped by dispatch");
128

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

137 iewDispNonSpecInsts
138 .name(name() + ".iewDispNonSpecInsts")
139 .desc("Number of dispatched non-speculative instructions");
140
141 iewIQFullEvents
142 .name(name() + ".iewIQFullEvents")
143 .desc("Number of times the IQ has become full, causing a stall");
144
112 iewDispatchedInsts
113 .name(name() + ".iewDispatchedInsts")
114 .desc("Number of instructions dispatched to IQ");
115
116 iewDispSquashedInsts
117 .name(name() + ".iewDispSquashedInsts")
118 .desc("Number of squashed instructions skipped by dispatch");
119

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

128 iewDispNonSpecInsts
129 .name(name() + ".iewDispNonSpecInsts")
130 .desc("Number of dispatched non-speculative instructions");
131
132 iewIQFullEvents
133 .name(name() + ".iewIQFullEvents")
134 .desc("Number of times the IQ has become full, causing a stall");
135
136 iewLSQFullEvents
137 .name(name() + ".iewLSQFullEvents")
138 .desc("Number of times the LSQ has become full, causing a stall");
139
145 iewExecutedInsts
146 .name(name() + ".iewExecutedInsts")
147 .desc("Number of executed instructions");
148
149 iewExecLoadInsts
140 iewExecutedInsts
141 .name(name() + ".iewExecutedInsts")
142 .desc("Number of executed instructions");
143
144 iewExecLoadInsts
145 .init(cpu->number_of_threads)
150 .name(name() + ".iewExecLoadInsts")
146 .name(name() + ".iewExecLoadInsts")
151 .desc("Number of load instructions executed");
147 .desc("Number of load instructions executed")
148 .flags(total);
152
149
153 iewExecStoreInsts
154 .name(name() + ".iewExecStoreInsts")
155 .desc("Number of store instructions executed");
156
157 iewExecSquashedInsts
158 .name(name() + ".iewExecSquashedInsts")
159 .desc("Number of squashed instructions skipped in execute");
160
161 memOrderViolationEvents
162 .name(name() + ".memOrderViolationEvents")
163 .desc("Number of memory order violations");
164
165 predictedTakenIncorrect
166 .name(name() + ".predictedTakenIncorrect")
167 .desc("Number of branches that were predicted taken incorrectly");
150 iewExecSquashedInsts
151 .name(name() + ".iewExecSquashedInsts")
152 .desc("Number of squashed instructions skipped in execute");
153
154 memOrderViolationEvents
155 .name(name() + ".memOrderViolationEvents")
156 .desc("Number of memory order violations");
157
158 predictedTakenIncorrect
159 .name(name() + ".predictedTakenIncorrect")
160 .desc("Number of branches that were predicted taken incorrectly");
161
162 predictedNotTakenIncorrect
163 .name(name() + ".predictedNotTakenIncorrect")
164 .desc("Number of branches that were predicted not taken incorrectly");
165
166 branchMispredicts
167 .name(name() + ".branchMispredicts")
168 .desc("Number of branch mispredicts detected at execute");
169
170 branchMispredicts = predictedTakenIncorrect + predictedNotTakenIncorrect;
171
172 exeSwp
173 .init(cpu->number_of_threads)
174 .name(name() + ".EXEC:swp")
175 .desc("number of swp insts executed")
176 .flags(total)
177 ;
178
179 exeNop
180 .init(cpu->number_of_threads)
181 .name(name() + ".EXEC:nop")
182 .desc("number of nop insts executed")
183 .flags(total)
184 ;
185
186 exeRefs
187 .init(cpu->number_of_threads)
188 .name(name() + ".EXEC:refs")
189 .desc("number of memory reference insts executed")
190 .flags(total)
191 ;
192
193 exeBranches
194 .init(cpu->number_of_threads)
195 .name(name() + ".EXEC:branches")
196 .desc("Number of branches executed")
197 .flags(total)
198 ;
199
200 issueRate
201 .name(name() + ".EXEC:rate")
202 .desc("Inst execution rate")
203 .flags(total)
204 ;
205 issueRate = iewExecutedInsts / cpu->numCycles;
206
207 iewExecStoreInsts
208 .name(name() + ".EXEC:stores")
209 .desc("Number of stores executed")
210 .flags(total)
211 ;
212 iewExecStoreInsts = exeRefs - iewExecLoadInsts;
213/*
214 for (int i=0; i<Num_OpClasses; ++i) {
215 stringstream subname;
216 subname << opClassStrings[i] << "_delay";
217 issue_delay_dist.subname(i, subname.str());
218 }
219*/
220 //
221 // Other stats
222 //
223
224 iewInstsToCommit
225 .init(cpu->number_of_threads)
226 .name(name() + ".WB:sent")
227 .desc("cumulative count of insts sent to commit")
228 .flags(total)
229 ;
230
231 writebackCount
232 .init(cpu->number_of_threads)
233 .name(name() + ".WB:count")
234 .desc("cumulative count of insts written-back")
235 .flags(total)
236 ;
237
238 producerInst
239 .init(cpu->number_of_threads)
240 .name(name() + ".WB:producers")
241 .desc("num instructions producing a value")
242 .flags(total)
243 ;
244
245 consumerInst
246 .init(cpu->number_of_threads)
247 .name(name() + ".WB:consumers")
248 .desc("num instructions consuming a value")
249 .flags(total)
250 ;
251
252 wbPenalized
253 .init(cpu->number_of_threads)
254 .name(name() + ".WB:penalized")
255 .desc("number of instrctions required to write to 'other' IQ")
256 .flags(total)
257 ;
258
259 wbPenalizedRate
260 .name(name() + ".WB:penalized_rate")
261 .desc ("fraction of instructions written-back that wrote to 'other' IQ")
262 .flags(total)
263 ;
264
265 wbPenalizedRate = wbPenalized / writebackCount;
266
267 wbFanout
268 .name(name() + ".WB:fanout")
269 .desc("average fanout of values written-back")
270 .flags(total)
271 ;
272
273 wbFanout = producerInst / consumerInst;
274
275 wbRate
276 .name(name() + ".WB:rate")
277 .desc("insts written-back per cycle")
278 .flags(total)
279 ;
280 wbRate = writebackCount / cpu->numCycles;
168}
169
170template<class Impl>
171void
281}
282
283template<class Impl>
284void
172SimpleIEW<Impl>::setCPU(FullCPU *cpu_ptr)
285DefaultIEW<Impl>::initStage()
173{
286{
174 DPRINTF(IEW, "IEW: Setting CPU pointer.\n");
287 for (int tid=0; tid < numThreads; tid++) {
288 toRename->iewInfo[tid].usedIQ = true;
289 toRename->iewInfo[tid].freeIQEntries =
290 instQueue.numFreeEntries(tid);
291
292 toRename->iewInfo[tid].usedLSQ = true;
293 toRename->iewInfo[tid].freeLSQEntries =
294 ldstQueue.numFreeEntries(tid);
295 }
296}
297
298template<class Impl>
299void
300DefaultIEW<Impl>::setCPU(FullCPU *cpu_ptr)
301{
302 DPRINTF(IEW, "Setting CPU pointer.\n");
175 cpu = cpu_ptr;
176
177 instQueue.setCPU(cpu_ptr);
178 ldstQueue.setCPU(cpu_ptr);
303 cpu = cpu_ptr;
304
305 instQueue.setCPU(cpu_ptr);
306 ldstQueue.setCPU(cpu_ptr);
307
308 cpu->activateStage(FullCPU::IEWIdx);
179}
180
181template<class Impl>
182void
309}
310
311template<class Impl>
312void
183SimpleIEW<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
313DefaultIEW<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
184{
314{
185 DPRINTF(IEW, "IEW: Setting time buffer pointer.\n");
315 DPRINTF(IEW, "Setting time buffer pointer.\n");
186 timeBuffer = tb_ptr;
187
188 // Setup wire to read information from time buffer, from commit.
189 fromCommit = timeBuffer->getWire(-commitToIEWDelay);
190
191 // Setup wire to write information back to previous stages.
192 toRename = timeBuffer->getWire(0);
193
316 timeBuffer = tb_ptr;
317
318 // Setup wire to read information from time buffer, from commit.
319 fromCommit = timeBuffer->getWire(-commitToIEWDelay);
320
321 // Setup wire to write information back to previous stages.
322 toRename = timeBuffer->getWire(0);
323
324 toFetch = timeBuffer->getWire(0);
325
194 // Instruction queue also needs main time buffer.
195 instQueue.setTimeBuffer(tb_ptr);
196}
197
198template<class Impl>
199void
326 // Instruction queue also needs main time buffer.
327 instQueue.setTimeBuffer(tb_ptr);
328}
329
330template<class Impl>
331void
200SimpleIEW<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr)
332DefaultIEW<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr)
201{
333{
202 DPRINTF(IEW, "IEW: Setting rename queue pointer.\n");
334 DPRINTF(IEW, "Setting rename queue pointer.\n");
203 renameQueue = rq_ptr;
204
205 // Setup wire to read information from rename queue.
206 fromRename = renameQueue->getWire(-renameToIEWDelay);
207}
208
209template<class Impl>
210void
335 renameQueue = rq_ptr;
336
337 // Setup wire to read information from rename queue.
338 fromRename = renameQueue->getWire(-renameToIEWDelay);
339}
340
341template<class Impl>
342void
211SimpleIEW<Impl>::setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr)
343DefaultIEW<Impl>::setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr)
212{
344{
213 DPRINTF(IEW, "IEW: Setting IEW queue pointer.\n");
345 DPRINTF(IEW, "Setting IEW queue pointer.\n");
214 iewQueue = iq_ptr;
215
216 // Setup wire to write instructions to commit.
217 toCommit = iewQueue->getWire(0);
218}
219
220template<class Impl>
221void
346 iewQueue = iq_ptr;
347
348 // Setup wire to write instructions to commit.
349 toCommit = iewQueue->getWire(0);
350}
351
352template<class Impl>
353void
222SimpleIEW<Impl>::setRenameMap(RenameMap *rm_ptr)
354DefaultIEW<Impl>::setActiveThreads(list<unsigned> *at_ptr)
223{
355{
224 DPRINTF(IEW, "IEW: Setting rename map pointer.\n");
225 renameMap = rm_ptr;
356 DPRINTF(IEW, "Setting active threads list pointer.\n");
357 activeThreads = at_ptr;
358
359 ldstQueue.setActiveThreads(at_ptr);
360 instQueue.setActiveThreads(at_ptr);
226}
227
228template<class Impl>
229void
361}
362
363template<class Impl>
364void
230SimpleIEW<Impl>::squash()
365DefaultIEW<Impl>::setScoreboard(Scoreboard *sb_ptr)
231{
366{
232 DPRINTF(IEW, "IEW: Squashing all instructions.\n");
233 _status = Squashing;
367 DPRINTF(IEW, "Setting scoreboard pointer.\n");
368 scoreboard = sb_ptr;
369}
234
370
371#if 0
372template<class Impl>
373void
374DefaultIEW<Impl>::setPageTable(PageTable *pt_ptr)
375{
376 ldstQueue.setPageTable(pt_ptr);
377}
378#endif
379
380template <class Impl>
381void
382DefaultIEW<Impl>::switchOut()
383{
384 cpu->signalSwitched();
385}
386
387template <class Impl>
388void
389DefaultIEW<Impl>::doSwitchOut()
390{
391 switchedOut = true;
392
393 instQueue.switchOut();
394 ldstQueue.switchOut();
395 fuPool->switchOut();
396
397 for (int i = 0; i < numThreads; i++) {
398 while (!insts[i].empty())
399 insts[i].pop();
400 while (!skidBuffer[i].empty())
401 skidBuffer[i].pop();
402 }
403}
404
405template <class Impl>
406void
407DefaultIEW<Impl>::takeOverFrom()
408{
409 _status = Active;
410 exeStatus = Running;
411 wbStatus = Idle;
412 switchedOut = false;
413
414 instQueue.takeOverFrom();
415 ldstQueue.takeOverFrom();
416 fuPool->takeOverFrom();
417
418 initStage();
419 cpu->activityThisCycle();
420
421 for (int i=0; i < numThreads; i++) {
422 dispatchStatus[i] = Running;
423 stalls[i].commit = false;
424 fetchRedirect[i] = false;
425 }
426
427 updateLSQNextCycle = false;
428
429 // @todo: Fix hardcoded number
430 for (int i = 0; i < 6; ++i) {
431 issueToExecQueue.advance();
432 }
433}
434
435template<class Impl>
436void
437DefaultIEW<Impl>::squash(unsigned tid)
438{
439 DPRINTF(IEW, "[tid:%i]: Squashing all instructions.\n",
440 tid);
441
235 // Tell the IQ to start squashing.
442 // Tell the IQ to start squashing.
236 instQueue.squash();
443 instQueue.squash(tid);
237
238 // Tell the LDSTQ to start squashing.
444
445 // Tell the LDSTQ to start squashing.
239 ldstQueue.squash(fromCommit->commitInfo.doneSeqNum);
446 ldstQueue.squash(fromCommit->commitInfo[tid].doneSeqNum, tid);
447
448 updatedQueues = true;
449
450 // Clear the skid buffer in case it has any data in it.
451 while (!skidBuffer[tid].empty()) {
452
453 if (skidBuffer[tid].front()->isLoad() ||
454 skidBuffer[tid].front()->isStore() ) {
455 toRename->iewInfo[tid].dispatchedToLSQ++;
456 }
457
458 toRename->iewInfo[tid].dispatched++;
459
460 skidBuffer[tid].pop();
461 }
462
463 while (!insts[tid].empty()) {
464 if (insts[tid].front()->isLoad() ||
465 insts[tid].front()->isStore() ) {
466 toRename->iewInfo[tid].dispatchedToLSQ++;
467 }
468
469 toRename->iewInfo[tid].dispatched++;
470
471 insts[tid].pop();
472 }
240}
241
242template<class Impl>
243void
473}
474
475template<class Impl>
476void
244SimpleIEW<Impl>::squashDueToBranch(DynInstPtr &inst)
477DefaultIEW<Impl>::squashDueToBranch(DynInstPtr &inst, unsigned tid)
245{
478{
246 DPRINTF(IEW, "IEW: Squashing from a specific instruction, PC: %#x.\n",
247 inst->PC);
248 // Perhaps leave the squashing up to the ROB stage to tell it when to
249 // squash?
250 _status = Squashing;
479 DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, PC: %#x "
480 "[sn:%i].\n", tid, inst->readPC(), inst->seqNum);
251
481
252 // Tell rename to squash through the time buffer.
253 toCommit->squash = true;
254 // Also send PC update information back to prior stages.
255 toCommit->squashedSeqNum = inst->seqNum;
256 toCommit->mispredPC = inst->readPC();
257 toCommit->nextPC = inst->readNextPC();
258 toCommit->branchMispredict = true;
259 // Prediction was incorrect, so send back inverse.
260 toCommit->branchTaken = inst->readNextPC() !=
482 toCommit->squash[tid] = true;
483 toCommit->squashedSeqNum[tid] = inst->seqNum;
484 toCommit->mispredPC[tid] = inst->readPC();
485 toCommit->nextPC[tid] = inst->readNextPC();
486 toCommit->branchMispredict[tid] = true;
487 toCommit->branchTaken[tid] = inst->readNextPC() !=
261 (inst->readPC() + sizeof(TheISA::MachInst));
488 (inst->readPC() + sizeof(TheISA::MachInst));
489
490 toCommit->includeSquashInst[tid] = false;
491
492 wroteToTimeBuffer = true;
262}
263
264template<class Impl>
265void
493}
494
495template<class Impl>
496void
266SimpleIEW<Impl>::squashDueToMem(DynInstPtr &inst)
497DefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, unsigned tid)
267{
498{
268 DPRINTF(IEW, "IEW: Squashing from a specific instruction, PC: %#x.\n",
269 inst->PC);
270 // Perhaps leave the squashing up to the ROB stage to tell it when to
271 // squash?
272 _status = Squashing;
499 DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, "
500 "PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum);
273
501
274 // Tell rename to squash through the time buffer.
275 toCommit->squash = true;
276 // Also send PC update information back to prior stages.
277 toCommit->squashedSeqNum = inst->seqNum;
278 toCommit->nextPC = inst->readNextPC();
502 toCommit->squash[tid] = true;
503 toCommit->squashedSeqNum[tid] = inst->seqNum;
504 toCommit->nextPC[tid] = inst->readNextPC();
505
506 toCommit->includeSquashInst[tid] = false;
507
508 wroteToTimeBuffer = true;
279}
280
281template<class Impl>
282void
509}
510
511template<class Impl>
512void
283SimpleIEW<Impl>::block()
513DefaultIEW<Impl>::squashDueToMemBlocked(DynInstPtr &inst, unsigned tid)
284{
514{
285 DPRINTF(IEW, "IEW: Blocking.\n");
286 // Set the status to Blocked.
287 _status = Blocked;
515 DPRINTF(IEW, "[tid:%i]: Memory blocked, squashing load and younger insts, "
516 "PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum);
288
517
518 toCommit->squash[tid] = true;
519 toCommit->squashedSeqNum[tid] = inst->seqNum;
520 toCommit->nextPC[tid] = inst->readPC();
521
522 toCommit->includeSquashInst[tid] = true;
523
524 ldstQueue.setLoadBlockedHandled(tid);
525
526 wroteToTimeBuffer = true;
527}
528
529template<class Impl>
530void
531DefaultIEW<Impl>::block(unsigned tid)
532{
533 DPRINTF(IEW, "[tid:%u]: Blocking.\n", tid);
534
535 if (dispatchStatus[tid] != Blocked &&
536 dispatchStatus[tid] != Unblocking) {
537 toRename->iewBlock[tid] = true;
538 wroteToTimeBuffer = true;
539 }
540
289 // Add the current inputs to the skid buffer so they can be
290 // reprocessed when this stage unblocks.
541 // Add the current inputs to the skid buffer so they can be
542 // reprocessed when this stage unblocks.
291 skidBuffer.push(*fromRename);
543 skidInsert(tid);
292
544
293 // Note that this stage only signals previous stages to stall when
294 // it is the cause of the stall originates at this stage. Otherwise
295 // the previous stages are expected to check all possible stall signals.
545 dispatchStatus[tid] = Blocked;
296}
297
298template<class Impl>
546}
547
548template<class Impl>
299inline void
300SimpleIEW<Impl>::unblock()
549void
550DefaultIEW<Impl>::unblock(unsigned tid)
301{
551{
302 // Check if there's information in the skid buffer. If there is, then
303 // set status to unblocking, otherwise set it directly to running.
304 DPRINTF(IEW, "IEW: Reading instructions out of the skid "
305 "buffer.\n");
306 // Remove the now processed instructions from the skid buffer.
307 skidBuffer.pop();
552 DPRINTF(IEW, "[tid:%i]: Reading instructions out of the skid "
553 "buffer %u.\n",tid, tid);
308
554
309 // If there's still information in the skid buffer, then
310 // continue to tell previous stages to stall. They will be
311 // able to restart once the skid buffer is empty.
312 if (!skidBuffer.empty()) {
313 toRename->iewInfo.stall = true;
314 } else {
315 DPRINTF(IEW, "IEW: Stage is done unblocking.\n");
316 _status = Running;
555 // If the skid bufffer is empty, signal back to previous stages to unblock.
556 // Also switch status to running.
557 if (skidBuffer[tid].empty()) {
558 toRename->iewUnblock[tid] = true;
559 wroteToTimeBuffer = true;
560 DPRINTF(IEW, "[tid:%i]: Done unblocking.\n",tid);
561 dispatchStatus[tid] = Running;
317 }
318}
319
320template<class Impl>
321void
562 }
563}
564
565template<class Impl>
566void
322SimpleIEW<Impl>::wakeDependents(DynInstPtr &inst)
567DefaultIEW<Impl>::wakeDependents(DynInstPtr &inst)
323{
324 instQueue.wakeDependents(inst);
325}
326
568{
569 instQueue.wakeDependents(inst);
570}
571
572template<class Impl>
573void
574DefaultIEW<Impl>::rescheduleMemInst(DynInstPtr &inst)
575{
576 instQueue.rescheduleMemInst(inst);
577}
327
328template<class Impl>
329void
578
579template<class Impl>
580void
330SimpleIEW<Impl>::instToCommit(DynInstPtr &inst)
581DefaultIEW<Impl>::replayMemInst(DynInstPtr &inst)
331{
582{
583 instQueue.replayMemInst(inst);
584}
332
585
586template<class Impl>
587void
588DefaultIEW<Impl>::instToCommit(DynInstPtr &inst)
589{
590 // First check the time slot that this instruction will write
591 // to. If there are free write ports at the time, then go ahead
592 // and write the instruction to that time. If there are not,
593 // keep looking back to see where's the first time there's a
594 // free slot.
595 while ((*iewQueue)[wbCycle].insts[wbNumInst]) {
596 ++wbNumInst;
597 if (wbNumInst == issueWidth) {
598 ++wbCycle;
599 wbNumInst = 0;
600 }
601
602 assert(wbCycle < 5);
603 }
604
605 // Add finished instruction to queue to commit.
606 (*iewQueue)[wbCycle].insts[wbNumInst] = inst;
607 (*iewQueue)[wbCycle].size++;
333}
334
335template <class Impl>
608}
609
610template <class Impl>
611unsigned
612DefaultIEW<Impl>::validInstsFromRename()
613{
614 unsigned inst_count = 0;
615
616 for (int i=0; i<fromRename->size; i++) {
617 if (!fromRename->insts[i]->squashed)
618 inst_count++;
619 }
620
621 return inst_count;
622}
623
624template<class Impl>
336void
625void
337SimpleIEW<Impl>::dispatchInsts()
626DefaultIEW<Impl>::skidInsert(unsigned tid)
338{
627{
339 ////////////////////////////////////////
340 // DISPATCH/ISSUE stage
341 ////////////////////////////////////////
628 DynInstPtr inst = NULL;
342
629
343 //Put into its own function?
344 //Add instructions to IQ if there are any instructions there
630 while (!insts[tid].empty()) {
631 inst = insts[tid].front();
345
632
346 // Check if there are any instructions coming from rename, and we're.
347 // not squashing.
348 if (fromRename->size > 0) {
349 int insts_to_add = fromRename->size;
633 insts[tid].pop();
350
634
351 // Loop through the instructions, putting them in the instruction
352 // queue.
353 for (int inst_num = 0; inst_num < insts_to_add; ++inst_num)
354 {
355 DynInstPtr inst = fromRename->insts[inst_num];
635 DPRINTF(Decode,"[tid:%i]: Inserting [sn:%lli] PC:%#x into "
636 "dispatch skidBuffer %i\n",tid, inst->seqNum,
637 inst->readPC(),tid);
356
638
357 // Make sure there's a valid instruction there.
358 assert(inst);
639 skidBuffer[tid].push(inst);
640 }
359
641
360 DPRINTF(IEW, "IEW: Issue: Adding PC %#x to IQ.\n",
361 inst->readPC());
642 assert(skidBuffer[tid].size() <= skidBufferMax &&
643 "Skidbuffer Exceeded Max Size");
644}
362
645
363 // Be sure to mark these instructions as ready so that the
364 // commit stage can go ahead and execute them, and mark
365 // them as issued so the IQ doesn't reprocess them.
366 if (inst->isSquashed()) {
367 ++iewDispSquashedInsts;
368 continue;
369 } else if (instQueue.isFull()) {
370 DPRINTF(IEW, "IEW: Issue: IQ has become full.\n");
371 // Call function to start blocking.
372 block();
373 // Tell previous stage to stall.
374 toRename->iewInfo.stall = true;
646template<class Impl>
647int
648DefaultIEW<Impl>::skidCount()
649{
650 int max=0;
375
651
376 ++iewIQFullEvents;
377 break;
378 } else if (inst->isLoad()) {
379 DPRINTF(IEW, "IEW: Issue: Memory instruction "
380 "encountered, adding to LDSTQ.\n");
652 list<unsigned>::iterator threads = (*activeThreads).begin();
381
653
382 // Reserve a spot in the load store queue for this
383 // memory access.
384 ldstQueue.insertLoad(inst);
654 while (threads != (*activeThreads).end()) {
655 unsigned thread_count = skidBuffer[*threads++].size();
656 if (max < thread_count)
657 max = thread_count;
658 }
385
659
386 ++iewDispLoadInsts;
387 } else if (inst->isStore()) {
388 ldstQueue.insertStore(inst);
660 return max;
661}
389
662
390 ++iewDispStoreInsts;
391 } else if (inst->isNonSpeculative()) {
392 DPRINTF(IEW, "IEW: Issue: Nonspeculative instruction "
393 "encountered, skipping.\n");
663template<class Impl>
664bool
665DefaultIEW<Impl>::skidsEmpty()
666{
667 list<unsigned>::iterator threads = (*activeThreads).begin();
394
668
395 // Same hack as with stores.
396 inst->setCanCommit();
669 while (threads != (*activeThreads).end()) {
670 if (!skidBuffer[*threads++].empty())
671 return false;
672 }
397
673
398 // Specificall insert it as nonspeculative.
674 return true;
675}
676
677template <class Impl>
678void
679DefaultIEW<Impl>::updateStatus()
680{
681 bool any_unblocking = false;
682
683 list<unsigned>::iterator threads = (*activeThreads).begin();
684
685 threads = (*activeThreads).begin();
686
687 while (threads != (*activeThreads).end()) {
688 unsigned tid = *threads++;
689
690 if (dispatchStatus[tid] == Unblocking) {
691 any_unblocking = true;
692 break;
693 }
694 }
695
696 // If there are no ready instructions waiting to be scheduled by the IQ,
697 // and there's no stores waiting to write back, and dispatch is not
698 // unblocking, then there is no internal activity for the IEW stage.
699 if (_status == Active && !instQueue.hasReadyInsts() &&
700 !ldstQueue.willWB() && !any_unblocking) {
701 DPRINTF(IEW, "IEW switching to idle\n");
702
703 deactivateStage();
704
705 _status = Inactive;
706 } else if (_status == Inactive && (instQueue.hasReadyInsts() ||
707 ldstQueue.willWB() ||
708 any_unblocking)) {
709 // Otherwise there is internal activity. Set to active.
710 DPRINTF(IEW, "IEW switching to active\n");
711
712 activateStage();
713
714 _status = Active;
715 }
716}
717
718template <class Impl>
719void
720DefaultIEW<Impl>::resetEntries()
721{
722 instQueue.resetEntries();
723 ldstQueue.resetEntries();
724}
725
726template <class Impl>
727void
728DefaultIEW<Impl>::readStallSignals(unsigned tid)
729{
730 if (fromCommit->commitBlock[tid]) {
731 stalls[tid].commit = true;
732 }
733
734 if (fromCommit->commitUnblock[tid]) {
735 assert(stalls[tid].commit);
736 stalls[tid].commit = false;
737 }
738}
739
740template <class Impl>
741bool
742DefaultIEW<Impl>::checkStall(unsigned tid)
743{
744 bool ret_val(false);
745
746 if (stalls[tid].commit) {
747 DPRINTF(IEW,"[tid:%i]: Stall from Commit stage detected.\n",tid);
748 ret_val = true;
749 } else if (instQueue.isFull(tid)) {
750 DPRINTF(IEW,"[tid:%i]: Stall: IQ is full.\n",tid);
751 ret_val = true;
752 } else if (ldstQueue.isFull(tid)) {
753 DPRINTF(IEW,"[tid:%i]: Stall: LSQ is full\n",tid);
754
755 if (ldstQueue.numLoads(tid) > 0 ) {
756
757 DPRINTF(IEW,"[tid:%i]: LSQ oldest load: [sn:%i] \n",
758 tid,ldstQueue.getLoadHeadSeqNum(tid));
759 }
760
761 if (ldstQueue.numStores(tid) > 0) {
762
763 DPRINTF(IEW,"[tid:%i]: LSQ oldest store: [sn:%i] \n",
764 tid,ldstQueue.getStoreHeadSeqNum(tid));
765 }
766
767 ret_val = true;
768 } else if (ldstQueue.isStalled(tid)) {
769 DPRINTF(IEW,"[tid:%i]: Stall: LSQ stall detected.\n",tid);
770 ret_val = true;
771 }
772
773 return ret_val;
774}
775
776template <class Impl>
777void
778DefaultIEW<Impl>::checkSignalsAndUpdate(unsigned tid)
779{
780 // Check if there's a squash signal, squash if there is
781 // Check stall signals, block if there is.
782 // If status was Blocked
783 // if so then go to unblocking
784 // If status was Squashing
785 // check if squashing is not high. Switch to running this cycle.
786
787 readStallSignals(tid);
788
789 if (fromCommit->commitInfo[tid].squash) {
790 squash(tid);
791
792 if (dispatchStatus[tid] == Blocked ||
793 dispatchStatus[tid] == Unblocking) {
794 toRename->iewUnblock[tid] = true;
795 wroteToTimeBuffer = true;
796 }
797
798 dispatchStatus[tid] = Squashing;
799
800 fetchRedirect[tid] = false;
801 return;
802 }
803
804 if (fromCommit->commitInfo[tid].robSquashing) {
805 DPRINTF(IEW, "[tid:%i]: ROB is still squashing.\n");
806
807 dispatchStatus[tid] = Squashing;
808
809 return;
810 }
811
812 if (checkStall(tid)) {
813 block(tid);
814 dispatchStatus[tid] = Blocked;
815 return;
816 }
817
818 if (dispatchStatus[tid] == Blocked) {
819 // Status from previous cycle was blocked, but there are no more stall
820 // conditions. Switch over to unblocking.
821 DPRINTF(IEW, "[tid:%i]: Done blocking, switching to unblocking.\n",
822 tid);
823
824 dispatchStatus[tid] = Unblocking;
825
826 unblock(tid);
827
828 return;
829 }
830
831 if (dispatchStatus[tid] == Squashing) {
832 // Switch status to running if rename isn't being told to block or
833 // squash this cycle.
834 DPRINTF(IEW, "[tid:%i]: Done squashing, switching to running.\n",
835 tid);
836
837 dispatchStatus[tid] = Running;
838
839 return;
840 }
841}
842
843template <class Impl>
844void
845DefaultIEW<Impl>::sortInsts()
846{
847 int insts_from_rename = fromRename->size;
848#ifdef DEBUG
849 for (int i = 0; i < numThreads; i++)
850 assert(insts[i].empty());
851#endif
852 for (int i = 0; i < insts_from_rename; ++i) {
853 insts[fromRename->insts[i]->threadNumber].push(fromRename->insts[i]);
854 }
855}
856
857template <class Impl>
858void
859DefaultIEW<Impl>::wakeCPU()
860{
861 cpu->wakeCPU();
862}
863
864template <class Impl>
865void
866DefaultIEW<Impl>::activityThisCycle()
867{
868 DPRINTF(Activity, "Activity this cycle.\n");
869 cpu->activityThisCycle();
870}
871
872template <class Impl>
873inline void
874DefaultIEW<Impl>::activateStage()
875{
876 DPRINTF(Activity, "Activating stage.\n");
877 cpu->activateStage(FullCPU::IEWIdx);
878}
879
880template <class Impl>
881inline void
882DefaultIEW<Impl>::deactivateStage()
883{
884 DPRINTF(Activity, "Deactivating stage.\n");
885 cpu->deactivateStage(FullCPU::IEWIdx);
886}
887
888template<class Impl>
889void
890DefaultIEW<Impl>::dispatch(unsigned tid)
891{
892 // If status is Running or idle,
893 // call dispatchInsts()
894 // If status is Unblocking,
895 // buffer any instructions coming from rename
896 // continue trying to empty skid buffer
897 // check if stall conditions have passed
898
899 if (dispatchStatus[tid] == Blocked) {
900 ++iewBlockCycles;
901
902 } else if (dispatchStatus[tid] == Squashing) {
903 ++iewSquashCycles;
904 }
905
906 // Dispatch should try to dispatch as many instructions as its bandwidth
907 // will allow, as long as it is not currently blocked.
908 if (dispatchStatus[tid] == Running ||
909 dispatchStatus[tid] == Idle) {
910 DPRINTF(IEW, "[tid:%i] Not blocked, so attempting to run "
911 "dispatch.\n", tid);
912
913 dispatchInsts(tid);
914 } else if (dispatchStatus[tid] == Unblocking) {
915 // Make sure that the skid buffer has something in it if the
916 // status is unblocking.
917 assert(!skidsEmpty());
918
919 // If the status was unblocking, then instructions from the skid
920 // buffer were used. Remove those instructions and handle
921 // the rest of unblocking.
922 dispatchInsts(tid);
923
924 ++iewUnblockCycles;
925
926 if (validInstsFromRename() && dispatchedAllInsts) {
927 // Add the current inputs to the skid buffer so they can be
928 // reprocessed when this stage unblocks.
929 skidInsert(tid);
930 }
931
932 unblock(tid);
933 }
934}
935
936template <class Impl>
937void
938DefaultIEW<Impl>::dispatchInsts(unsigned tid)
939{
940 dispatchedAllInsts = true;
941
942 // Obtain instructions from skid buffer if unblocking, or queue from rename
943 // otherwise.
944 std::queue<DynInstPtr> &insts_to_dispatch =
945 dispatchStatus[tid] == Unblocking ?
946 skidBuffer[tid] : insts[tid];
947
948 int insts_to_add = insts_to_dispatch.size();
949
950 DynInstPtr inst;
951 bool add_to_iq = false;
952 int dis_num_inst = 0;
953
954 // Loop through the instructions, putting them in the instruction
955 // queue.
956 for ( ; dis_num_inst < insts_to_add &&
957 dis_num_inst < issueReadWidth;
958 ++dis_num_inst)
959 {
960 inst = insts_to_dispatch.front();
961
962 if (dispatchStatus[tid] == Unblocking) {
963 DPRINTF(IEW, "[tid:%i]: Issue: Examining instruction from skid "
964 "buffer\n", tid);
965 }
966
967 // Make sure there's a valid instruction there.
968 assert(inst);
969
970 DPRINTF(IEW, "[tid:%i]: Issue: Adding PC %#x [sn:%lli] [tid:%i] to "
971 "IQ.\n",
972 tid, inst->readPC(), inst->seqNum, inst->threadNumber);
973
974 // Be sure to mark these instructions as ready so that the
975 // commit stage can go ahead and execute them, and mark
976 // them as issued so the IQ doesn't reprocess them.
977
978 // Check for squashed instructions.
979 if (inst->isSquashed()) {
980 DPRINTF(IEW, "[tid:%i]: Issue: Squashed instruction encountered, "
981 "not adding to IQ.\n", tid);
982
983 ++iewDispSquashedInsts;
984
985 insts_to_dispatch.pop();
986
987 //Tell Rename That An Instruction has been processed
988 if (inst->isLoad() || inst->isStore()) {
989 toRename->iewInfo[tid].dispatchedToLSQ++;
990 }
991 toRename->iewInfo[tid].dispatched++;
992
993 continue;
994 }
995
996 // Check for full conditions.
997 if (instQueue.isFull(tid)) {
998 DPRINTF(IEW, "[tid:%i]: Issue: IQ has become full.\n", tid);
999
1000 // Call function to start blocking.
1001 block(tid);
1002
1003 // Set unblock to false. Special case where we are using
1004 // skidbuffer (unblocking) instructions but then we still
1005 // get full in the IQ.
1006 toRename->iewUnblock[tid] = false;
1007
1008 dispatchedAllInsts = false;
1009
1010 ++iewIQFullEvents;
1011 break;
1012 } else if (ldstQueue.isFull(tid)) {
1013 DPRINTF(IEW, "[tid:%i]: Issue: LSQ has become full.\n",tid);
1014
1015 // Call function to start blocking.
1016 block(tid);
1017
1018 // Set unblock to false. Special case where we are using
1019 // skidbuffer (unblocking) instructions but then we still
1020 // get full in the IQ.
1021 toRename->iewUnblock[tid] = false;
1022
1023 dispatchedAllInsts = false;
1024
1025 ++iewLSQFullEvents;
1026 break;
1027 }
1028
1029 // Otherwise issue the instruction just fine.
1030 if (inst->isLoad()) {
1031 DPRINTF(IEW, "[tid:%i]: Issue: Memory instruction "
1032 "encountered, adding to LSQ.\n", tid);
1033
1034 // Reserve a spot in the load store queue for this
1035 // memory access.
1036 ldstQueue.insertLoad(inst);
1037
1038 ++iewDispLoadInsts;
1039
1040 add_to_iq = true;
1041
1042 toRename->iewInfo[tid].dispatchedToLSQ++;
1043 } else if (inst->isStore()) {
1044 DPRINTF(IEW, "[tid:%i]: Issue: Memory instruction "
1045 "encountered, adding to LSQ.\n", tid);
1046
1047 ldstQueue.insertStore(inst);
1048
1049 ++iewDispStoreInsts;
1050
1051 if (inst->isStoreConditional()) {
1052 // Store conditionals need to be set as "canCommit()"
1053 // so that commit can process them when they reach the
1054 // head of commit.
1055 inst->setCanCommit();
399 instQueue.insertNonSpec(inst);
1056 instQueue.insertNonSpec(inst);
1057 add_to_iq = false;
400
401 ++iewDispNonSpecInsts;
1058
1059 ++iewDispNonSpecInsts;
1060 } else {
1061 add_to_iq = true;
1062 }
402
1063
403 continue;
404 } else if (inst->isNop()) {
405 DPRINTF(IEW, "IEW: Issue: Nop instruction encountered "
406 ", skipping.\n");
1064 toRename->iewInfo[tid].dispatchedToLSQ++;
1065#if FULL_SYSTEM
1066 } else if (inst->isMemBarrier() || inst->isWriteBarrier()) {
1067 // Same as non-speculative stores.
1068 inst->setCanCommit();
1069 instQueue.insertBarrier(inst);
1070 add_to_iq = false;
1071#endif
1072 } else if (inst->isNonSpeculative()) {
1073 DPRINTF(IEW, "[tid:%i]: Issue: Nonspeculative instruction "
1074 "encountered, skipping.\n", tid);
407
1075
408 inst->setIssued();
409 inst->setExecuted();
410 inst->setCanCommit();
1076 // Same as non-speculative stores.
1077 inst->setCanCommit();
411
1078
412 instQueue.advanceTail(inst);
1079 // Specifically insert it as nonspeculative.
1080 instQueue.insertNonSpec(inst);
413
1081
414 continue;
415 } else if (inst->isExecuted()) {
416 assert(0 && "Instruction shouldn't be executed.\n");
417 DPRINTF(IEW, "IEW: Issue: Executed branch encountered, "
418 "skipping.\n");
1082 ++iewDispNonSpecInsts;
419
1083
420 inst->setIssued();
421 inst->setCanCommit();
1084 add_to_iq = false;
1085 } else if (inst->isNop()) {
1086 DPRINTF(IEW, "[tid:%i]: Issue: Nop instruction encountered, "
1087 "skipping.\n", tid);
422
1088
423 instQueue.advanceTail(inst);
1089 inst->setIssued();
1090 inst->setExecuted();
1091 inst->setCanCommit();
424
1092
425 continue;
426 }
1093 instQueue.recordProducer(inst);
427
1094
428 // If the instruction queue is not full, then add the
429 // instruction.
430 instQueue.insert(fromRename->insts[inst_num]);
1095 exeNop[tid]++;
431
1096
432 ++iewDispatchedInsts;
1097 add_to_iq = false;
1098 } else if (inst->isExecuted()) {
1099 assert(0 && "Instruction shouldn't be executed.\n");
1100 DPRINTF(IEW, "Issue: Executed branch encountered, "
1101 "skipping.\n");
1102
1103 inst->setIssued();
1104 inst->setCanCommit();
1105
1106 instQueue.recordProducer(inst);
1107
1108 add_to_iq = false;
1109 } else {
1110 add_to_iq = true;
433 }
1111 }
1112
1113 // If the instruction queue is not full, then add the
1114 // instruction.
1115 if (add_to_iq) {
1116 instQueue.insert(inst);
1117 }
1118
1119 insts_to_dispatch.pop();
1120
1121 toRename->iewInfo[tid].dispatched++;
1122
1123 ++iewDispatchedInsts;
434 }
1124 }
1125
1126 if (!insts_to_dispatch.empty()) {
1127 DPRINTF(IEW,"[tid:%i]: Issue: Bandwidth Full. Blocking.\n");
1128 block(tid);
1129 toRename->iewUnblock[tid] = false;
1130 }
1131
1132 if (dispatchStatus[tid] == Idle && dis_num_inst) {
1133 dispatchStatus[tid] = Running;
1134
1135 updatedQueues = true;
1136 }
1137
1138 dis_num_inst = 0;
435}
436
437template <class Impl>
438void
1139}
1140
1141template <class Impl>
1142void
439SimpleIEW<Impl>::executeInsts()
1143DefaultIEW<Impl>::printAvailableInsts()
440{
1144{
441 ////////////////////////////////////////
442 //EXECUTE/WRITEBACK stage
443 ////////////////////////////////////////
1145 int inst = 0;
444
1146
445 //Put into its own function?
446 //Similarly should probably have separate execution for int vs FP.
447 // Above comment is handled by the issue queue only issuing a valid
448 // mix of int/fp instructions.
449 //Actually okay to just have one execution, buuuuuut will need
450 //somewhere that defines the execution latency of all instructions.
451 // @todo: Move to the FU pool used in the current full cpu.
1147 cout << "Available Instructions: ";
452
1148
453 int fu_usage = 0;
454 bool fetch_redirect = false;
455 int inst_slot = 0;
456 int time_slot = 0;
1149 while (fromIssue->insts[inst]) {
457
1150
1151 if (inst%3==0) cout << "\n\t";
1152
1153 cout << "PC: " << fromIssue->insts[inst]->readPC()
1154 << " TN: " << fromIssue->insts[inst]->threadNumber
1155 << " SN: " << fromIssue->insts[inst]->seqNum << " | ";
1156
1157 inst++;
1158
1159 }
1160
1161 cout << "\n";
1162}
1163
1164template <class Impl>
1165void
1166DefaultIEW<Impl>::executeInsts()
1167{
1168 wbNumInst = 0;
1169 wbCycle = 0;
1170
1171 list<unsigned>::iterator threads = (*activeThreads).begin();
1172
1173 while (threads != (*activeThreads).end()) {
1174 unsigned tid = *threads++;
1175 fetchRedirect[tid] = false;
1176 }
1177
1178#if 0
1179 printAvailableInsts();
1180#endif
1181
458 // Execute/writeback any instructions that are available.
1182 // Execute/writeback any instructions that are available.
459 for (int inst_num = 0;
460 fu_usage < executeWidth && /* Haven't exceeded available FU's. */
461 inst_num < issueWidth &&
462 fromIssue->insts[inst_num];
463 ++inst_num) {
1183 int insts_to_execute = fromIssue->size;
1184 int inst_num = 0;
1185 for (; inst_num < insts_to_execute;
1186 ++inst_num) {
464
1187
465 DPRINTF(IEW, "IEW: Execute: Executing instructions from IQ.\n");
1188 DPRINTF(IEW, "Execute: Executing instructions from IQ.\n");
466
1189
467 // Get instruction from issue's queue.
468 DynInstPtr inst = fromIssue->insts[inst_num];
1190 DynInstPtr inst = instQueue.getInstToExecute();
469
1191
470 DPRINTF(IEW, "IEW: Execute: Processing PC %#x.\n", inst->readPC());
1192 DPRINTF(IEW, "Execute: Processing PC %#x, [tid:%i] [sn:%i].\n",
1193 inst->readPC(), inst->threadNumber,inst->seqNum);
471
472 // Check if the instruction is squashed; if so then skip it
1194
1195 // Check if the instruction is squashed; if so then skip it
473 // and don't count it towards the FU usage.
474 if (inst->isSquashed()) {
1196 if (inst->isSquashed()) {
475 DPRINTF(IEW, "IEW: Execute: Instruction was squashed.\n");
1197 DPRINTF(IEW, "Execute: Instruction was squashed.\n");
476
477 // Consider this instruction executed so that commit can go
478 // ahead and retire the instruction.
479 inst->setExecuted();
480
1198
1199 // Consider this instruction executed so that commit can go
1200 // ahead and retire the instruction.
1201 inst->setExecuted();
1202
481 toCommit->insts[inst_num] = inst;
1203 // Not sure if I should set this here or just let commit try to
1204 // commit any squashed instructions. I like the latter a bit more.
1205 inst->setCanCommit();
482
483 ++iewExecSquashedInsts;
484
485 continue;
486 }
487
1206
1207 ++iewExecSquashedInsts;
1208
1209 continue;
1210 }
1211
488 inst->setExecuted();
1212 Fault fault = NoFault;
489
1213
490 // If an instruction is executed, then count it towards FU usage.
491 ++fu_usage;
492
493 // Execute instruction.
494 // Note that if the instruction faults, it will be handled
495 // at the commit stage.
1214 // Execute instruction.
1215 // Note that if the instruction faults, it will be handled
1216 // at the commit stage.
496 if (inst->isMemRef()) {
497 DPRINTF(IEW, "IEW: Execute: Calculating address for memory "
1217 if (inst->isMemRef() &&
1218 (!inst->isDataPrefetch() && !inst->isInstPrefetch())) {
1219 DPRINTF(IEW, "Execute: Calculating address for memory "
498 "reference.\n");
499
500 // Tell the LDSTQ to execute this instruction (if it is a load).
501 if (inst->isLoad()) {
1220 "reference.\n");
1221
1222 // Tell the LDSTQ to execute this instruction (if it is a load).
1223 if (inst->isLoad()) {
502 ldstQueue.executeLoad(inst);
503
504 ++iewExecLoadInsts;
1224 // Loads will mark themselves as executed, and their writeback
1225 // event adds the instruction to the queue to commit
1226 fault = ldstQueue.executeLoad(inst);
505 } else if (inst->isStore()) {
506 ldstQueue.executeStore(inst);
507
1227 } else if (inst->isStore()) {
1228 ldstQueue.executeStore(inst);
1229
508 ++iewExecStoreInsts;
1230 // If the store had a fault then it may not have a mem req
1231 if (inst->req && !(inst->req->getFlags() & LOCKED)) {
1232 inst->setExecuted();
1233
1234 instToCommit(inst);
1235 }
1236
1237 // Store conditionals will mark themselves as
1238 // executed, and their writeback event will add the
1239 // instruction to the queue to commit.
509 } else {
1240 } else {
510 panic("IEW: Unexpected memory type!\n");
1241 panic("Unexpected memory type!\n");
511 }
512
513 } else {
514 inst->execute();
515
1242 }
1243
1244 } else {
1245 inst->execute();
1246
516 ++iewExecutedInsts;
1247 inst->setExecuted();
1248
1249 instToCommit(inst);
517 }
518
1250 }
1251
519 // First check the time slot that this instruction will write
520 // to. If there are free write ports at the time, then go ahead
521 // and write the instruction to that time. If there are not,
522 // keep looking back to see where's the first time there's a
523 // free slot. What happens if you run out of free spaces?
524 // For now naively assume that all instructions take one cycle.
525 // Otherwise would have to look into the time buffer based on the
526 // latency of the instruction.
527 (*iewQueue)[time_slot].insts[inst_slot];
528 while ((*iewQueue)[time_slot].insts[inst_slot]) {
529 if (inst_slot < issueWidth) {
530 ++inst_slot;
531 } else {
532 ++time_slot;
533 inst_slot = 0;
534 }
1252 updateExeInstStats(inst);
535
1253
536 assert(time_slot < 5);
537 }
1254 // Check if branch prediction was correct, if not then we need
1255 // to tell commit to squash in flight instructions. Only
1256 // handle this if there hasn't already been something that
1257 // redirects fetch in this group of instructions.
538
1258
539 // May actually have to work this out, especially with loads and stores
1259 // This probably needs to prioritize the redirects if a different
1260 // scheduler is used. Currently the scheduler schedules the oldest
1261 // instruction first, so the branch resolution order will be correct.
1262 unsigned tid = inst->threadNumber;
540
1263
541 // Add finished instruction to queue to commit.
542 (*iewQueue)[time_slot].insts[inst_slot] = inst;
543 (*iewQueue)[time_slot].size++;
1264 if (!fetchRedirect[tid]) {
544
1265
545 // Check if branch was correct. This check happens after the
546 // instruction is added to the queue because even if the branch
547 // is mispredicted, the branch instruction itself is still valid.
548 // Only handle this if there hasn't already been something that
549 // redirects fetch in this group of instructions.
550 if (!fetch_redirect) {
551 if (inst->mispredicted()) {
1266 if (inst->mispredicted()) {
552 fetch_redirect = true;
1267 fetchRedirect[tid] = true;
553
1268
554 DPRINTF(IEW, "IEW: Execute: Branch mispredict detected.\n");
555 DPRINTF(IEW, "IEW: Execute: Redirecting fetch to PC: %#x.\n",
1269 DPRINTF(IEW, "Execute: Branch mispredict detected.\n");
1270 DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x.\n",
556 inst->nextPC);
557
558 // If incorrect, then signal the ROB that it must be squashed.
1271 inst->nextPC);
1272
1273 // If incorrect, then signal the ROB that it must be squashed.
559 squashDueToBranch(inst);
1274 squashDueToBranch(inst, tid);
560
561 if (inst->predTaken()) {
562 predictedTakenIncorrect++;
1275
1276 if (inst->predTaken()) {
1277 predictedTakenIncorrect++;
1278 } else {
1279 predictedNotTakenIncorrect++;
563 }
1280 }
564 } else if (ldstQueue.violation()) {
565 fetch_redirect = true;
1281 } else if (ldstQueue.violation(tid)) {
1282 fetchRedirect[tid] = true;
566
1283
567 // Get the DynInst that caused the violation.
568 DynInstPtr violator = ldstQueue.getMemDepViolator();
1284 // If there was an ordering violation, then get the
1285 // DynInst that caused the violation. Note that this
1286 // clears the violation signal.
1287 DynInstPtr violator;
1288 violator = ldstQueue.getMemDepViolator(tid);
569
1289
570 DPRINTF(IEW, "IEW: LDSTQ detected a violation. Violator PC: "
1290 DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: "
571 "%#x, inst PC: %#x. Addr is: %#x.\n",
572 violator->readPC(), inst->readPC(), inst->physEffAddr);
573
574 // Tell the instruction queue that a violation has occured.
575 instQueue.violation(inst, violator);
576
577 // Squash.
1291 "%#x, inst PC: %#x. Addr is: %#x.\n",
1292 violator->readPC(), inst->readPC(), inst->physEffAddr);
1293
1294 // Tell the instruction queue that a violation has occured.
1295 instQueue.violation(inst, violator);
1296
1297 // Squash.
578 squashDueToMem(inst);
1298 squashDueToMemOrder(inst,tid);
579
580 ++memOrderViolationEvents;
1299
1300 ++memOrderViolationEvents;
1301 } else if (ldstQueue.loadBlocked(tid) &&
1302 !ldstQueue.isLoadBlockedHandled(tid)) {
1303 fetchRedirect[tid] = true;
1304
1305 DPRINTF(IEW, "Load operation couldn't execute because the "
1306 "memory system is blocked. PC: %#x [sn:%lli]\n",
1307 inst->readPC(), inst->seqNum);
1308
1309 squashDueToMemBlocked(inst, tid);
581 }
582 }
583 }
1310 }
1311 }
1312 }
1313
1314 if (inst_num) {
1315 if (exeStatus == Idle) {
1316 exeStatus = Running;
1317 }
1318
1319 updatedQueues = true;
1320
1321 cpu->activityThisCycle();
1322 }
1323
1324 // Need to reset this in case a writeback event needs to write into the
1325 // iew queue. That way the writeback event will write into the correct
1326 // spot in the queue.
1327 wbNumInst = 0;
584}
585
1328}
1329
586template
1330template <class Impl>
587void
1331void
588SimpleIEW<Impl>::tick()
1332DefaultIEW<Impl>::writebackInsts()
589{
1333{
590 // Considering putting all the state-determining stuff in this section.
1334 // Loop through the head of the time buffer and wake any
1335 // dependents. These instructions are about to write back. Also
1336 // mark scoreboard that this instruction is finally complete.
1337 // Either have IEW have direct access to scoreboard, or have this
1338 // as part of backwards communication.
1339 for (int inst_num = 0; inst_num < issueWidth &&
1340 toCommit->insts[inst_num]; inst_num++) {
1341 DynInstPtr inst = toCommit->insts[inst_num];
1342 int tid = inst->threadNumber;
591
1343
592 // Try to fill up issue queue with as many instructions as bandwidth
593 // allows.
594 // Decode should try to execute as many instructions as its bandwidth
595 // will allow, as long as it is not currently blocked.
1344 DPRINTF(IEW, "Sending instructions to commit, PC %#x.\n",
1345 inst->readPC());
596
1346
597 // Check if the stage is in a running status.
598 if (_status != Blocked && _status != Squashing) {
599 DPRINTF(IEW, "IEW: Status is not blocked, attempting to run "
600 "stage.\n");
601 iew();
1347 iewInstsToCommit[tid]++;
602
1348
603 // If it's currently unblocking, check to see if it should switch
604 // to running.
605 if (_status == Unblocking) {
606 unblock();
1349 // Some instructions will be sent to commit without having
1350 // executed because they need commit to handle them.
1351 // E.g. Uncached loads have not actually executed when they
1352 // are first sent to commit. Instead commit must tell the LSQ
1353 // when it's ready to execute the uncached load.
1354 if (!inst->isSquashed() && inst->isExecuted()) {
1355 int dependents = instQueue.wakeDependents(inst);
607
1356
608 ++iewUnblockCycles;
1357 for (int i = 0; i < inst->numDestRegs(); i++) {
1358 //mark as Ready
1359 DPRINTF(IEW,"Setting Destination Register %i\n",
1360 inst->renamedDestRegIdx(i));
1361 scoreboard->setReg(inst->renamedDestRegIdx(i));
1362 }
1363
1364 producerInst[tid]++;
1365 consumerInst[tid]+= dependents;
1366 writebackCount[tid]++;
609 }
1367 }
610 } else if (_status == Squashing) {
1368 }
1369}
611
1370
612 DPRINTF(IEW, "IEW: Still squashing.\n");
1371template<class Impl>
1372void
1373DefaultIEW<Impl>::tick()
1374{
1375 wbNumInst = 0;
1376 wbCycle = 0;
613
1377
614 // Check if stage should remain squashing. Stop squashing if the
615 // squash signal clears.
616 if (!fromCommit->commitInfo.squash &&
617 !fromCommit->commitInfo.robSquashing) {
618 DPRINTF(IEW, "IEW: Done squashing, changing status to "
619 "running.\n");
1378 wroteToTimeBuffer = false;
1379 updatedQueues = false;
620
1380
621 _status = Running;
622 instQueue.stopSquash();
623 } else {
624 instQueue.doSquash();
625 }
1381 sortInsts();
626
1382
627 ++iewSquashCycles;
628 } else if (_status == Blocked) {
629 // Continue to tell previous stage to stall.
630 toRename->iewInfo.stall = true;
1383 // Free function units marked as being freed this cycle.
1384 fuPool->processFreeUnits();
631
1385
632 // Check if possible stall conditions have cleared.
633 if (!fromCommit->commitInfo.stall &&
634 !instQueue.isFull()) {
635 DPRINTF(IEW, "IEW: Stall signals cleared, going to unblock.\n");
636 _status = Unblocking;
637 }
1386 list<unsigned>::iterator threads = (*activeThreads).begin();
638
1387
639 // If there's still instructions coming from rename, continue to
640 // put them on the skid buffer.
641 if (fromRename->size == 0) {
642 block();
643 }
1388 // Check stall and squash signals, dispatch any instructions.
1389 while (threads != (*activeThreads).end()) {
1390 unsigned tid = *threads++;
644
1391
645 if (fromCommit->commitInfo.squash ||
646 fromCommit->commitInfo.robSquashing) {
647 squash();
648 }
1392 DPRINTF(IEW,"Issue: Processing [tid:%i]\n",tid);
649
1393
650 ++iewBlockCycles;
1394 checkSignalsAndUpdate(tid);
1395 dispatch(tid);
651 }
652
1396 }
1397
653 // @todo: Maybe put these at the beginning, so if it's idle it can
654 // return early.
655 // Write back number of free IQ entries here.
656 toRename->iewInfo.freeIQEntries = instQueue.numFreeEntries();
1398 if (exeStatus != Squashing) {
1399 executeInsts();
657
1400
1401 writebackInsts();
1402
1403 // Have the instruction queue try to schedule any ready instructions.
1404 // (In actuality, this scheduling is for instructions that will
1405 // be executed next cycle.)
1406 instQueue.scheduleReadyInsts();
1407
1408 // Also should advance its own time buffers if the stage ran.
1409 // Not the best place for it, but this works (hopefully).
1410 issueToExecQueue.advance();
1411 }
1412
1413 bool broadcast_free_entries = false;
1414
1415 if (updatedQueues || exeStatus == Running || updateLSQNextCycle) {
1416 exeStatus = Idle;
1417 updateLSQNextCycle = false;
1418
1419 broadcast_free_entries = true;
1420 }
1421
1422 // Writeback any stores using any leftover bandwidth.
658 ldstQueue.writebackStores();
659
660 // Check the committed load/store signals to see if there's a load
661 // or store to commit. Also check if it's being told to execute a
662 // nonspeculative instruction.
663 // This is pretty inefficient...
1423 ldstQueue.writebackStores();
1424
1425 // Check the committed load/store signals to see if there's a load
1426 // or store to commit. Also check if it's being told to execute a
1427 // nonspeculative instruction.
1428 // This is pretty inefficient...
664 if (!fromCommit->commitInfo.squash &&
665 !fromCommit->commitInfo.robSquashing) {
666 ldstQueue.commitStores(fromCommit->commitInfo.doneSeqNum);
667 ldstQueue.commitLoads(fromCommit->commitInfo.doneSeqNum);
668 }
669
1429
670 if (fromCommit->commitInfo.nonSpecSeqNum != 0) {
671 instQueue.scheduleNonSpec(fromCommit->commitInfo.nonSpecSeqNum);
672 }
1430 threads = (*activeThreads).begin();
1431 while (threads != (*activeThreads).end()) {
1432 unsigned tid = (*threads++);
673
1433
674 DPRINTF(IEW, "IEW: IQ has %i free entries.\n",
675 instQueue.numFreeEntries());
676}
1434 DPRINTF(IEW,"Processing [tid:%i]\n",tid);
677
1435
678template<class Impl>
679void
680SimpleIEW<Impl>::iew()
681{
682 // Might want to put all state checks in the tick() function.
683 // Check if being told to stall from commit.
684 if (fromCommit->commitInfo.stall) {
685 block();
686 return;
687 } else if (fromCommit->commitInfo.squash ||
688 fromCommit->commitInfo.robSquashing) {
689 // Also check if commit is telling this stage to squash.
690 squash();
691 return;
692 }
1436 if (fromCommit->commitInfo[tid].doneSeqNum != 0 &&
1437 !fromCommit->commitInfo[tid].squash &&
1438 !fromCommit->commitInfo[tid].robSquashing) {
693
1439
694 dispatchInsts();
1440 ldstQueue.commitStores(fromCommit->commitInfo[tid].doneSeqNum,tid);
695
1441
696 // Have the instruction queue try to schedule any ready instructions.
697 instQueue.scheduleReadyInsts();
1442 ldstQueue.commitLoads(fromCommit->commitInfo[tid].doneSeqNum,tid);
698
1443
699 executeInsts();
1444 updateLSQNextCycle = true;
1445 instQueue.commit(fromCommit->commitInfo[tid].doneSeqNum,tid);
1446 }
700
1447
701 // Loop through the head of the time buffer and wake any dependents.
702 // These instructions are about to write back. In the simple model
703 // this loop can really happen within the previous loop, but when
704 // instructions have actual latencies, this loop must be separate.
705 // Also mark scoreboard that this instruction is finally complete.
706 // Either have IEW have direct access to rename map, or have this as
707 // part of backwards communication.
708 for (int inst_num = 0; inst_num < issueWidth &&
709 toCommit->insts[inst_num]; inst_num++)
710 {
711 DynInstPtr inst = toCommit->insts[inst_num];
1448 if (fromCommit->commitInfo[tid].nonSpecSeqNum != 0) {
712
1449
713 DPRINTF(IEW, "IEW: Sending instructions to commit, PC %#x.\n",
714 inst->readPC());
1450 //DPRINTF(IEW,"NonspecInst from thread %i",tid);
1451 if (fromCommit->commitInfo[tid].uncached) {
1452 instQueue.replayMemInst(fromCommit->commitInfo[tid].uncachedLoad);
1453 } else {
1454 instQueue.scheduleNonSpec(
1455 fromCommit->commitInfo[tid].nonSpecSeqNum);
1456 }
1457 }
715
1458
716 if(!inst->isSquashed()) {
717 instQueue.wakeDependents(inst);
1459 if (broadcast_free_entries) {
1460 toFetch->iewInfo[tid].iqCount =
1461 instQueue.getCount(tid);
1462 toFetch->iewInfo[tid].ldstqCount =
1463 ldstQueue.getCount(tid);
718
1464
719 for (int i = 0; i < inst->numDestRegs(); i++)
720 {
721 renameMap->markAsReady(inst->renamedDestRegIdx(i));
722 }
1465 toRename->iewInfo[tid].usedIQ = true;
1466 toRename->iewInfo[tid].freeIQEntries =
1467 instQueue.numFreeEntries();
1468 toRename->iewInfo[tid].usedLSQ = true;
1469 toRename->iewInfo[tid].freeLSQEntries =
1470 ldstQueue.numFreeEntries(tid);
1471
1472 wroteToTimeBuffer = true;
723 }
1473 }
1474
1475 DPRINTF(IEW, "[tid:%i], Dispatch dispatched %i instructions.\n",
1476 tid, toRename->iewInfo[tid].dispatched);
724 }
725
1477 }
1478
726 // Also should advance its own time buffers if the stage ran.
727 // Not the best place for it, but this works (hopefully).
728 issueToExecQueue.advance();
1479 DPRINTF(IEW, "IQ has %i free entries (Can schedule: %i). "
1480 "LSQ has %i free entries.\n",
1481 instQueue.numFreeEntries(), instQueue.hasReadyInsts(),
1482 ldstQueue.numFreeEntries());
1483
1484 updateStatus();
1485
1486 if (wroteToTimeBuffer) {
1487 DPRINTF(Activity, "Activity this cycle.\n");
1488 cpu->activityThisCycle();
1489 }
729}
730
1490}
1491
731#if !FULL_SYSTEM
732template<class Impl>
1492template <class Impl>
733void
1493void
734SimpleIEW<Impl>::lsqWriteback()
1494DefaultIEW<Impl>::updateExeInstStats(DynInstPtr &inst)
735{
1495{
736 ldstQueue.writebackAllInsts();
737}
1496 int thread_number = inst->threadNumber;
1497
1498 //
1499 // Pick off the software prefetches
1500 //
1501#ifdef TARGET_ALPHA
1502 if (inst->isDataPrefetch())
1503 exeSwp[thread_number]++;
1504 else
1505 iewExecutedInsts++;
1506#else
1507 iewExecutedInsts++;
738#endif
1508#endif
1509
1510 //
1511 // Control operations
1512 //
1513 if (inst->isControl())
1514 exeBranches[thread_number]++;
1515
1516 //
1517 // Memory operations
1518 //
1519 if (inst->isMemRef()) {
1520 exeRefs[thread_number]++;
1521
1522 if (inst->isLoad()) {
1523 iewExecLoadInsts[thread_number]++;
1524 }
1525 }
1526}