iew_impl.hh revision 1681
14486Sbinkertn@umich.edu// @todo: Fix the instantaneous communication among all the stages within
24486Sbinkertn@umich.edu// iew.  There's a clear delay between issue and execute, yet backwards
34486Sbinkertn@umich.edu// communication happens simultaneously.  Might not be that bad really...
44486Sbinkertn@umich.edu// it might skew stats a bit though.  Issue would otherwise try to issue
54486Sbinkertn@umich.edu// instructions that would never be executed if there were a delay; without
64486Sbinkertn@umich.edu// it issue will simply squash.  Make this stage block properly.
74486Sbinkertn@umich.edu// Update the statuses for each stage.
84486Sbinkertn@umich.edu// Actually read instructions out of the skid buffer.
94486Sbinkertn@umich.edu
104486Sbinkertn@umich.edu#include <queue>
114486Sbinkertn@umich.edu
124486Sbinkertn@umich.edu#include "base/timebuf.hh"
134486Sbinkertn@umich.edu#include "cpu/beta_cpu/iew.hh"
144486Sbinkertn@umich.edu
154486Sbinkertn@umich.edutemplate<class Impl>
164486Sbinkertn@umich.eduSimpleIEW<Impl>::WritebackEvent::WritebackEvent(DynInstPtr &_inst,
174486Sbinkertn@umich.edu                                                SimpleIEW<Impl> *_iew)
184486Sbinkertn@umich.edu    : Event(&mainEventQueue, CPU_Tick_Pri), inst(_inst), iewStage(_iew)
194486Sbinkertn@umich.edu{
204486Sbinkertn@umich.edu    this->setFlags(Event::AutoDelete);
214486Sbinkertn@umich.edu}
224486Sbinkertn@umich.edu
234486Sbinkertn@umich.edutemplate<class Impl>
244486Sbinkertn@umich.eduvoid
254486Sbinkertn@umich.eduSimpleIEW<Impl>::WritebackEvent::process()
264486Sbinkertn@umich.edu{
274486Sbinkertn@umich.edu    DPRINTF(IEW, "IEW: WRITEBACK EVENT!!!!\n");
284486Sbinkertn@umich.edu
293102SN/A    // Need to insert instruction into queue to commit
303102SN/A    iewStage->instToCommit(inst);
313102SN/A    // Need to execute second half of the instruction, do actual writing to
322667SN/A    // registers and such
332998SN/A    inst->execute();
343584SN/A}
352667SN/A
364486Sbinkertn@umich.edutemplate<class Impl>
374486Sbinkertn@umich.educonst char *
384486Sbinkertn@umich.eduSimpleIEW<Impl>::WritebackEvent::description()
394486Sbinkertn@umich.edu{
404486Sbinkertn@umich.edu    return "LSQ writeback event";
414486Sbinkertn@umich.edu}
424486Sbinkertn@umich.edu
431692SN/Atemplate<class Impl>
441366SN/ASimpleIEW<Impl>::SimpleIEW(Params &params)
451310SN/A    : // Just make this time buffer really big for now
461310SN/A      issueToExecQueue(5, 5),
472901SN/A      instQueue(params),
483170SN/A      ldstQueue(params),
493170SN/A      commitToIEWDelay(params.commitToIEWDelay),
501530SN/A      renameToIEWDelay(params.renameToIEWDelay),
513620SN/A      issueToExecuteDelay(params.issueToExecuteDelay),
523617SN/A      issueReadWidth(params.issueWidth),
533617SN/A      issueWidth(params.issueWidth),
543617SN/A      executeWidth(params.executeWidth)
553617SN/A{
563617SN/A    DPRINTF(IEW, "IEW: executeIntWidth: %i.\n", params.executeIntWidth);
573584SN/A    _status = Idle;
583584SN/A    _issueStatus = Idle;
593584SN/A    _exeStatus = Idle;
603584SN/A    _wbStatus = Idle;
613584SN/A
623584SN/A    // Setup wire to read instructions coming from issue.
633584SN/A    fromIssue = issueToExecQueue.getWire(-issueToExecuteDelay);
643584SN/A
653584SN/A    // Instruction queue needs the queue between issue and execute.
661445SN/A    instQueue.setIssueToExecuteQueue(&issueToExecQueue);
671445SN/A
681310SN/A    ldstQueue.setIEW(this);
691310SN/A}
701310SN/A
711310SN/Atemplate <class Impl>
721310SN/Avoid
731310SN/ASimpleIEW<Impl>::regStats()
741310SN/A{
751310SN/A    instQueue.regStats();
761310SN/A
773878SN/A    iewIdleCycles
783878SN/A        .name(name() + ".iewIdleCycles")
791310SN/A        .desc("Number of cycles IEW is idle");
801369SN/A
811310SN/A    iewSquashCycles
821634SN/A        .name(name() + ".iewSquashCycles")
834167SN/A        .desc("Number of cycles IEW is squashing");
844167SN/A
852998SN/A    iewBlockCycles
862998SN/A        .name(name() + ".iewBlockCycles")
872998SN/A        .desc("Number of cycles IEW is blocking");
882998SN/A
892998SN/A    iewUnblockCycles
902998SN/A        .name(name() + ".iewUnblockCycles")
912998SN/A        .desc("Number of cycles IEW is unblocking");
922998SN/A
932998SN/A//    iewWBInsts;
942998SN/A
952998SN/A    iewDispatchedInsts
962998SN/A        .name(name() + ".iewDispatchedInsts")
972998SN/A        .desc("Number of instructions dispatched to IQ");
982998SN/A
992998SN/A    iewDispSquashedInsts
1002998SN/A        .name(name() + ".iewDispSquashedInsts")
1012998SN/A        .desc("Number of squashed instructions skipped by dispatch");
1022998SN/A
1032998SN/A    iewDispLoadInsts
1042998SN/A        .name(name() + ".iewDispLoadInsts")
1053017SN/A        .desc("Number of dispatched load instructions");
1062998SN/A
107    iewDispStoreInsts
108        .name(name() + ".iewDispStoreInsts")
109        .desc("Number of dispatched store instructions");
110
111    iewDispNonSpecInsts
112        .name(name() + ".iewDispNonSpecInsts")
113        .desc("Number of dispatched non-speculative instructions");
114
115    iewIQFullEvents
116        .name(name() + ".iewIQFullEvents")
117        .desc("Number of times the IQ has become full, causing a stall");
118
119    iewExecutedInsts
120        .name(name() + ".iewExecutedInsts")
121        .desc("Number of executed instructions");
122
123    iewExecLoadInsts
124        .name(name() + ".iewExecLoadInsts")
125        .desc("Number of load instructions executed");
126
127    iewExecStoreInsts
128        .name(name() + ".iewExecStoreInsts")
129        .desc("Number of store instructions executed");
130
131    iewExecSquashedInsts
132        .name(name() + ".iewExecSquashedInsts")
133        .desc("Number of squashed instructions skipped in execute");
134
135    memOrderViolationEvents
136        .name(name() + ".memOrderViolationEvents")
137        .desc("Number of memory order violations");
138
139    predictedTakenIncorrect
140        .name(name() + ".predictedTakenIncorrect")
141        .desc("Number of branches that were predicted taken incorrectly");
142}
143
144template<class Impl>
145void
146SimpleIEW<Impl>::setCPU(FullCPU *cpu_ptr)
147{
148    DPRINTF(IEW, "IEW: Setting CPU pointer.\n");
149    cpu = cpu_ptr;
150
151    instQueue.setCPU(cpu_ptr);
152    ldstQueue.setCPU(cpu_ptr);
153}
154
155template<class Impl>
156void
157SimpleIEW<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
158{
159    DPRINTF(IEW, "IEW: Setting time buffer pointer.\n");
160    timeBuffer = tb_ptr;
161
162    // Setup wire to read information from time buffer, from commit.
163    fromCommit = timeBuffer->getWire(-commitToIEWDelay);
164
165    // Setup wire to write information back to previous stages.
166    toRename = timeBuffer->getWire(0);
167
168    // Instruction queue also needs main time buffer.
169    instQueue.setTimeBuffer(tb_ptr);
170}
171
172template<class Impl>
173void
174SimpleIEW<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr)
175{
176    DPRINTF(IEW, "IEW: Setting rename queue pointer.\n");
177    renameQueue = rq_ptr;
178
179    // Setup wire to read information from rename queue.
180    fromRename = renameQueue->getWire(-renameToIEWDelay);
181}
182
183template<class Impl>
184void
185SimpleIEW<Impl>::setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr)
186{
187    DPRINTF(IEW, "IEW: Setting IEW queue pointer.\n");
188    iewQueue = iq_ptr;
189
190    // Setup wire to write instructions to commit.
191    toCommit = iewQueue->getWire(0);
192}
193
194template<class Impl>
195void
196SimpleIEW<Impl>::setRenameMap(RenameMap *rm_ptr)
197{
198    DPRINTF(IEW, "IEW: Setting rename map pointer.\n");
199    renameMap = rm_ptr;
200}
201
202template<class Impl>
203void
204SimpleIEW<Impl>::squash()
205{
206    DPRINTF(IEW, "IEW: Squashing all instructions.\n");
207    _status = Squashing;
208
209    // Tell the IQ to start squashing.
210    instQueue.squash();
211
212    // Tell the LDSTQ to start squashing.
213    ldstQueue.squash(fromCommit->commitInfo.doneSeqNum);
214}
215
216template<class Impl>
217void
218SimpleIEW<Impl>::squashDueToBranch(DynInstPtr &inst)
219{
220    DPRINTF(IEW, "IEW: Squashing from a specific instruction, PC: %#x.\n",
221            inst->PC);
222    // Perhaps leave the squashing up to the ROB stage to tell it when to
223    // squash?
224    _status = Squashing;
225
226    // Tell rename to squash through the time buffer.
227    toCommit->squash = true;
228    // Also send PC update information back to prior stages.
229    toCommit->squashedSeqNum = inst->seqNum;
230    toCommit->mispredPC = inst->readPC();
231    toCommit->nextPC = inst->readNextPC();
232    toCommit->branchMispredict = true;
233    // Prediction was incorrect, so send back inverse.
234    toCommit->branchTaken = inst->readNextPC() !=
235        (inst->readPC() + sizeof(MachInst));
236}
237
238template<class Impl>
239void
240SimpleIEW<Impl>::squashDueToMem(DynInstPtr &inst)
241{
242    DPRINTF(IEW, "IEW: Squashing from a specific instruction, PC: %#x.\n",
243            inst->PC);
244    // Perhaps leave the squashing up to the ROB stage to tell it when to
245    // squash?
246    _status = Squashing;
247
248    // Tell rename to squash through the time buffer.
249    toCommit->squash = true;
250    // Also send PC update information back to prior stages.
251    toCommit->squashedSeqNum = inst->seqNum;
252    toCommit->nextPC = inst->readNextPC();
253}
254
255template<class Impl>
256void
257SimpleIEW<Impl>::block()
258{
259    DPRINTF(IEW, "IEW: Blocking.\n");
260    // Set the status to Blocked.
261    _status = Blocked;
262
263    // Add the current inputs to the skid buffer so they can be
264    // reprocessed when this stage unblocks.
265    skidBuffer.push(*fromRename);
266
267    // Note that this stage only signals previous stages to stall when
268    // it is the cause of the stall originates at this stage.  Otherwise
269    // the previous stages are expected to check all possible stall signals.
270}
271
272template<class Impl>
273inline void
274SimpleIEW<Impl>::unblock()
275{
276    // Check if there's information in the skid buffer.  If there is, then
277    // set status to unblocking, otherwise set it directly to running.
278    DPRINTF(IEW, "IEW: Reading instructions out of the skid "
279            "buffer.\n");
280    // Remove the now processed instructions from the skid buffer.
281    skidBuffer.pop();
282
283    // If there's still information in the skid buffer, then
284    // continue to tell previous stages to stall.  They will be
285    // able to restart once the skid buffer is empty.
286    if (!skidBuffer.empty()) {
287        toRename->iewInfo.stall = true;
288    } else {
289        DPRINTF(IEW, "IEW: Stage is done unblocking.\n");
290        _status = Running;
291    }
292}
293
294template<class Impl>
295void
296SimpleIEW<Impl>::wakeDependents(DynInstPtr &inst)
297{
298    instQueue.wakeDependents(inst);
299}
300
301
302template<class Impl>
303void
304SimpleIEW<Impl>::instToCommit(DynInstPtr &inst)
305{
306
307}
308
309template <class Impl>
310void
311SimpleIEW<Impl>::dispatchInsts()
312{
313    ////////////////////////////////////////
314    // DISPATCH/ISSUE stage
315    ////////////////////////////////////////
316
317    //Put into its own function?
318    //Add instructions to IQ if there are any instructions there
319
320    // Check if there are any instructions coming from rename, and we're.
321    // not squashing.
322    if (fromRename->size > 0) {
323        int insts_to_add = fromRename->size;
324
325        // Loop through the instructions, putting them in the instruction
326        // queue.
327        for (int inst_num = 0; inst_num < insts_to_add; ++inst_num)
328        {
329            DynInstPtr inst = fromRename->insts[inst_num];
330
331            // Make sure there's a valid instruction there.
332            assert(inst);
333
334            DPRINTF(IEW, "IEW: Issue: Adding PC %#x to IQ.\n",
335                    inst->readPC());
336
337            // Be sure to mark these instructions as ready so that the
338            // commit stage can go ahead and execute them, and mark
339            // them as issued so the IQ doesn't reprocess them.
340            if (inst->isSquashed()) {
341                ++iewDispSquashedInsts;
342                continue;
343            } else if (instQueue.isFull()) {
344                DPRINTF(IEW, "IEW: Issue: IQ has become full.\n");
345                // Call function to start blocking.
346                block();
347                // Tell previous stage to stall.
348                toRename->iewInfo.stall = true;
349
350                ++iewIQFullEvents;
351                break;
352            } else if (inst->isLoad()) {
353                DPRINTF(IEW, "IEW: Issue: Memory instruction "
354                        "encountered, adding to LDSTQ.\n");
355
356                // Reserve a spot in the load store queue for this
357                // memory access.
358                ldstQueue.insertLoad(inst);
359
360                ++iewDispLoadInsts;
361            } else if (inst->isStore()) {
362                ldstQueue.insertStore(inst);
363
364                // A bit of a hack.  Set that it can commit so that
365                // the commit stage will try committing it, and then
366                // once commit realizes it's a store it will send back
367                // a signal to this stage to issue and execute that
368                // store.  Change to be a bit that says the instruction
369                // has extra work to do at commit.
370//                inst->setCanCommit();
371
372//                instQueue.insertNonSpec(inst);
373
374                ++iewDispStoreInsts;
375//                ++iewDispNonSpecInsts;
376
377//                continue;
378            } else if (inst->isNonSpeculative()) {
379                DPRINTF(IEW, "IEW: Issue: Nonspeculative instruction "
380                        "encountered, skipping.\n");
381
382                // Same hack as with stores.
383                inst->setCanCommit();
384
385                // Specificall insert it as nonspeculative.
386                instQueue.insertNonSpec(inst);
387
388                ++iewDispNonSpecInsts;
389
390                continue;
391            } else if (inst->isNop()) {
392                DPRINTF(IEW, "IEW: Issue: Nop instruction encountered "
393                        ", skipping.\n");
394
395                inst->setIssued();
396                inst->setExecuted();
397                inst->setCanCommit();
398
399                instQueue.advanceTail(inst);
400
401                continue;
402            } else if (inst->isExecuted()) {
403                assert(0 && "Instruction shouldn't be executed.\n");
404                DPRINTF(IEW, "IEW: Issue: Executed branch encountered, "
405                        "skipping.\n");
406
407//                assert(inst->isDirectCtrl());
408
409                inst->setIssued();
410                inst->setCanCommit();
411
412                instQueue.advanceTail(inst);
413
414                continue;
415            }
416
417            // If the instruction queue is not full, then add the
418            // instruction.
419            instQueue.insert(fromRename->insts[inst_num]);
420
421            ++iewDispatchedInsts;
422        }
423    }
424}
425
426template <class Impl>
427void
428SimpleIEW<Impl>::executeInsts()
429{
430    ////////////////////////////////////////
431    //EXECUTE/WRITEBACK stage
432    ////////////////////////////////////////
433
434    //Put into its own function?
435    //Similarly should probably have separate execution for int vs FP.
436    // Above comment is handled by the issue queue only issuing a valid
437    // mix of int/fp instructions.
438    //Actually okay to just have one execution, buuuuuut will need
439    //somewhere that defines the execution latency of all instructions.
440    // @todo: Move to the FU pool used in the current full cpu.
441
442    int fu_usage = 0;
443    bool fetch_redirect = false;
444    int inst_slot = 0;
445    int time_slot = 0;
446
447    // Execute/writeback any instructions that are available.
448    for (int inst_num = 0;
449         fu_usage < executeWidth && /* Haven't exceeded available FU's. */
450             inst_num < issueWidth &&
451             fromIssue->insts[inst_num];
452         ++inst_num) {
453
454        DPRINTF(IEW, "IEW: Execute: Executing instructions from IQ.\n");
455
456        // Get instruction from issue's queue.
457        DynInstPtr inst = fromIssue->insts[inst_num];
458
459        DPRINTF(IEW, "IEW: Execute: Processing PC %#x.\n", inst->readPC());
460
461        // Check if the instruction is squashed; if so then skip it
462        // and don't count it towards the FU usage.
463        if (inst->isSquashed()) {
464            DPRINTF(IEW, "IEW: Execute: Instruction was squashed.\n");
465
466            // Consider this instruction executed so that commit can go
467            // ahead and retire the instruction.
468            inst->setExecuted();
469
470            toCommit->insts[inst_num] = inst;
471
472            ++iewExecSquashedInsts;
473
474            continue;
475        }
476
477        inst->setExecuted();
478
479        // If an instruction is executed, then count it towards FU usage.
480        ++fu_usage;
481
482        // Execute instruction.
483        // Note that if the instruction faults, it will be handled
484        // at the commit stage.
485        if (inst->isMemRef()) {
486            DPRINTF(IEW, "IEW: Execute: Calculating address for memory "
487                    "reference.\n");
488
489            // Tell the LDSTQ to execute this instruction (if it is a load).
490            if (inst->isLoad()) {
491                ldstQueue.executeLoad(inst);
492
493                ++iewExecLoadInsts;
494            } else if (inst->isStore()) {
495                ldstQueue.executeStore(inst);
496
497                ++iewExecStoreInsts;
498            } else {
499                panic("IEW: Unexpected memory type!\n");
500            }
501
502        } else {
503            inst->execute();
504
505            ++iewExecutedInsts;
506        }
507
508        // First check the time slot that this instruction will write
509        // to.  If there are free write ports at the time, then go ahead
510        // and write the instruction to that time.  If there are not,
511        // keep looking back to see where's the first time there's a
512        // free slot.  What happens if you run out of free spaces?
513        // For now naively assume that all instructions take one cycle.
514        // Otherwise would have to look into the time buffer based on the
515        // latency of the instruction.
516        (*iewQueue)[time_slot].insts[inst_slot];
517        while ((*iewQueue)[time_slot].insts[inst_slot]) {
518            if (inst_slot < issueWidth) {
519                ++inst_slot;
520            } else {
521                ++time_slot;
522                inst_slot = 0;
523            }
524
525            assert(time_slot < 5);
526        }
527
528        // May actually have to work this out, especially with loads and stores
529
530        // Add finished instruction to queue to commit.
531        (*iewQueue)[time_slot].insts[inst_slot] = inst;
532        (*iewQueue)[time_slot].size++;
533
534        // Check if branch was correct.  This check happens after the
535        // instruction is added to the queue because even if the branch
536        // is mispredicted, the branch instruction itself is still valid.
537        // Only handle this if there hasn't already been something that
538        // redirects fetch in this group of instructions.
539        if (!fetch_redirect) {
540            if (inst->mispredicted()) {
541                fetch_redirect = true;
542
543                DPRINTF(IEW, "IEW: Execute: Branch mispredict detected.\n");
544                DPRINTF(IEW, "IEW: Execute: Redirecting fetch to PC: %#x.\n",
545                        inst->nextPC);
546
547                // If incorrect, then signal the ROB that it must be squashed.
548                squashDueToBranch(inst);
549
550                if (inst->predTaken()) {
551                    predictedTakenIncorrect++;
552                }
553            } else if (ldstQueue.violation()) {
554                fetch_redirect = true;
555
556                // Get the DynInst that caused the violation.
557                DynInstPtr violator = ldstQueue.getMemDepViolator();
558
559                DPRINTF(IEW, "IEW: LDSTQ detected a violation.  Violator PC: "
560                        "%#x, inst PC: %#x.  Addr is: %#x.\n",
561                        violator->readPC(), inst->readPC(), inst->physEffAddr);
562
563                // Tell the instruction queue that a violation has occured.
564                instQueue.violation(inst, violator);
565
566                // Squash.
567                squashDueToMem(inst);
568
569                ++memOrderViolationEvents;
570            }
571        }
572    }
573}
574
575template<class Impl>
576void
577SimpleIEW<Impl>::tick()
578{
579    // Considering putting all the state-determining stuff in this section.
580
581    // Try to fill up issue queue with as many instructions as bandwidth
582    // allows.
583    // Decode should try to execute as many instructions as its bandwidth
584    // will allow, as long as it is not currently blocked.
585
586    // Check if the stage is in a running status.
587    if (_status != Blocked && _status != Squashing) {
588        DPRINTF(IEW, "IEW: Status is not blocked, attempting to run "
589                     "stage.\n");
590        iew();
591
592        // If it's currently unblocking, check to see if it should switch
593        // to running.
594        if (_status == Unblocking) {
595            unblock();
596
597            ++iewUnblockCycles;
598        }
599    } else if (_status == Squashing) {
600
601        DPRINTF(IEW, "IEW: Still squashing.\n");
602
603        // Check if stage should remain squashing.  Stop squashing if the
604        // squash signal clears.
605        if (!fromCommit->commitInfo.squash &&
606            !fromCommit->commitInfo.robSquashing) {
607            DPRINTF(IEW, "IEW: Done squashing, changing status to "
608                    "running.\n");
609
610            _status = Running;
611            instQueue.stopSquash();
612        } else {
613            instQueue.doSquash();
614        }
615
616        ++iewSquashCycles;
617
618        // Also should advance its own time buffers if the stage ran.
619        // Not sure about this...
620//        issueToExecQueue.advance();
621    } else if (_status == Blocked) {
622        // Continue to tell previous stage to stall.
623        toRename->iewInfo.stall = true;
624
625        // Check if possible stall conditions have cleared.
626        if (!fromCommit->commitInfo.stall &&
627            !instQueue.isFull()) {
628            DPRINTF(IEW, "IEW: Stall signals cleared, going to unblock.\n");
629            _status = Unblocking;
630        }
631
632        // If there's still instructions coming from rename, continue to
633        // put them on the skid buffer.
634        if (fromRename->size == 0) {
635            block();
636        }
637
638        if (fromCommit->commitInfo.squash ||
639            fromCommit->commitInfo.robSquashing) {
640            squash();
641        }
642
643        ++iewBlockCycles;
644    }
645
646    // @todo: Maybe put these at the beginning, so if it's idle it can
647    // return early.
648    // Write back number of free IQ entries here.
649    toRename->iewInfo.freeIQEntries = instQueue.numFreeEntries();
650
651    ldstQueue.writebackStores();
652
653    // Check the committed load/store signals to see if there's a load
654    // or store to commit.  Also check if it's being told to execute a
655    // nonspeculative instruction.
656    // This is pretty inefficient...
657//    if (0/*fromCommit->commitInfo.commitIsStore*/) {
658    if (!fromCommit->commitInfo.squash &&
659        !fromCommit->commitInfo.robSquashing) {
660        ldstQueue.commitStores(fromCommit->commitInfo.doneSeqNum);
661//    } else if (fromCommit->commitInfo.commitIsLoad) {
662        ldstQueue.commitLoads(fromCommit->commitInfo.doneSeqNum);
663    }
664//    }
665
666    if (fromCommit->commitInfo.nonSpecSeqNum != 0) {
667        instQueue.scheduleNonSpec(fromCommit->commitInfo.nonSpecSeqNum);
668    }
669
670    DPRINTF(IEW, "IEW: IQ has %i free entries.\n",
671            instQueue.numFreeEntries());
672}
673
674template<class Impl>
675void
676SimpleIEW<Impl>::iew()
677{
678    // Might want to put all state checks in the tick() function.
679    // Check if being told to stall from commit.
680    if (fromCommit->commitInfo.stall) {
681        block();
682        return;
683    } else if (fromCommit->commitInfo.squash ||
684               fromCommit->commitInfo.robSquashing) {
685        // Also check if commit is telling this stage to squash.
686        squash();
687        return;
688    }
689
690    dispatchInsts();
691
692    // Have the instruction queue try to schedule any ready instructions.
693    instQueue.scheduleReadyInsts();
694
695    executeInsts();
696
697    // Loop through the head of the time buffer and wake any dependents.
698    // These instructions are about to write back.  In the simple model
699    // this loop can really happen within the previous loop, but when
700    // instructions have actual latencies, this loop must be separate.
701    // Also mark scoreboard that this instruction is finally complete.
702    // Either have IEW have direct access to rename map, or have this as
703    // part of backwards communication.
704    for (int inst_num = 0; inst_num < issueWidth &&
705             toCommit->insts[inst_num]; inst_num++)
706    {
707        DynInstPtr inst = toCommit->insts[inst_num];
708
709        DPRINTF(IEW, "IEW: Sending instructions to commit, PC %#x.\n",
710                inst->readPC());
711
712        if(!inst->isSquashed()) {
713            instQueue.wakeDependents(inst);
714
715            for (int i = 0; i < inst->numDestRegs(); i++)
716            {
717                renameMap->markAsReady(inst->renamedDestRegIdx(i));
718            }
719        }
720    }
721
722    // Also should advance its own time buffers if the stage ran.
723    // Not the best place for it, but this works (hopefully).
724    issueToExecQueue.advance();
725}
726
727#ifndef FULL_SYSTEM
728template<class Impl>
729void
730SimpleIEW<Impl>::lsqWriteback()
731{
732    ldstQueue.writebackAllInsts();
733}
734#endif
735