iew_impl.hh revision 2367
11376Sbinkertn@umich.edu/*
21376Sbinkertn@umich.edu * Copyright (c) 2004-2006 The Regents of The University of Michigan
31376Sbinkertn@umich.edu * All rights reserved.
41376Sbinkertn@umich.edu *
51376Sbinkertn@umich.edu * Redistribution and use in source and binary forms, with or without
61376Sbinkertn@umich.edu * modification, are permitted provided that the following conditions are
71376Sbinkertn@umich.edu * met: redistributions of source code must retain the above copyright
81376Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer;
91376Sbinkertn@umich.edu * redistributions in binary form must reproduce the above copyright
101376Sbinkertn@umich.edu * notice, this list of conditions and the following disclaimer in the
111376Sbinkertn@umich.edu * documentation and/or other materials provided with the distribution;
121376Sbinkertn@umich.edu * neither the name of the copyright holders nor the names of its
131376Sbinkertn@umich.edu * contributors may be used to endorse or promote products derived from
141376Sbinkertn@umich.edu * this software without specific prior written permission.
151376Sbinkertn@umich.edu *
161376Sbinkertn@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171376Sbinkertn@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181376Sbinkertn@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191376Sbinkertn@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201376Sbinkertn@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211376Sbinkertn@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221376Sbinkertn@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231376Sbinkertn@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241376Sbinkertn@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251376Sbinkertn@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261376Sbinkertn@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
271376Sbinkertn@umich.edu */
281376Sbinkertn@umich.edu
291376Sbinkertn@umich.edu// @todo: Fix the instantaneous communication among all the stages within
301376Sbinkertn@umich.edu// iew.  There's a clear delay between issue and execute, yet backwards
311385Sbinkertn@umich.edu// communication happens simultaneously.
321376Sbinkertn@umich.edu
331376Sbinkertn@umich.edu#include <queue>
341376Sbinkertn@umich.edu
351376Sbinkertn@umich.edu#include "base/timebuf.hh"
361376Sbinkertn@umich.edu#include "cpu/o3/fu_pool.hh"
371385Sbinkertn@umich.edu#include "cpu/o3/iew.hh"
381385Sbinkertn@umich.edu
391385Sbinkertn@umich.eduusing namespace std;
401385Sbinkertn@umich.edu
411385Sbinkertn@umich.edutemplate<class Impl>
421385Sbinkertn@umich.eduDefaultIEW<Impl>::LdWritebackEvent::LdWritebackEvent(DynInstPtr &_inst,
431385Sbinkertn@umich.edu                                                     DefaultIEW<Impl> *_iew)
441385Sbinkertn@umich.edu    : Event(&mainEventQueue), inst(_inst), iewStage(_iew)
451376Sbinkertn@umich.edu{
461376Sbinkertn@umich.edu    this->setFlags(Event::AutoDelete);
471376Sbinkertn@umich.edu}
481602Sbinkertn@umich.edu
491376Sbinkertn@umich.edutemplate<class Impl>
501376Sbinkertn@umich.eduvoid
511376Sbinkertn@umich.eduDefaultIEW<Impl>::LdWritebackEvent::process()
521376Sbinkertn@umich.edu{
531602Sbinkertn@umich.edu    DPRINTF(IEW, "Load writeback event [sn:%lli]\n", inst->seqNum);
541376Sbinkertn@umich.edu    DPRINTF(Activity, "Activity: Ld Writeback event [sn:%lli]\n", inst->seqNum);
551376Sbinkertn@umich.edu
561602Sbinkertn@umich.edu    //iewStage->ldstQueue.removeMSHR(inst->threadNumber,inst->seqNum);
571602Sbinkertn@umich.edu
581376Sbinkertn@umich.edu    if (iewStage->isSwitchedOut()) {
591376Sbinkertn@umich.edu        iewStage->decrWb(inst->seqNum);
601376Sbinkertn@umich.edu        inst = NULL;
611376Sbinkertn@umich.edu        return;
621376Sbinkertn@umich.edu    } else if (inst->isSquashed()) {
631376Sbinkertn@umich.edu        iewStage->decrWb(inst->seqNum);
641376Sbinkertn@umich.edu        iewStage->wakeCPU();
651376Sbinkertn@umich.edu        inst = NULL;
661376Sbinkertn@umich.edu        return;
671602Sbinkertn@umich.edu    }
681376Sbinkertn@umich.edu
691376Sbinkertn@umich.edu    iewStage->wakeCPU();
701376Sbinkertn@umich.edu
711376Sbinkertn@umich.edu    if (!inst->isExecuted()) {
721376Sbinkertn@umich.edu        inst->setExecuted();
731376Sbinkertn@umich.edu
741376Sbinkertn@umich.edu        // Complete access to copy data to proper place.
751376Sbinkertn@umich.edu        if (inst->isStore()) {
761376Sbinkertn@umich.edu            inst->completeAcc();
771376Sbinkertn@umich.edu        }
781385Sbinkertn@umich.edu    }
791602Sbinkertn@umich.edu
801381Sbinkertn@umich.edu    // Need to insert instruction into queue to commit
811381Sbinkertn@umich.edu    iewStage->instToCommit(inst);
821376Sbinkertn@umich.edu
831381Sbinkertn@umich.edu    iewStage->activityThisCycle();
841381Sbinkertn@umich.edu
851381Sbinkertn@umich.edu    inst = NULL;
861376Sbinkertn@umich.edu}
871381Sbinkertn@umich.edu
881376Sbinkertn@umich.edutemplate<class Impl>
891381Sbinkertn@umich.educonst char *
901376Sbinkertn@umich.eduDefaultIEW<Impl>::LdWritebackEvent::description()
911376Sbinkertn@umich.edu{
921602Sbinkertn@umich.edu    return "Load writeback event";
931602Sbinkertn@umich.edu}
941381Sbinkertn@umich.edu
951376Sbinkertn@umich.edutemplate<class Impl>
961381Sbinkertn@umich.eduDefaultIEW<Impl>::DefaultIEW(Params *params)
971381Sbinkertn@umich.edu    : // @todo: Make this into a parameter.
981381Sbinkertn@umich.edu      issueToExecQueue(params->backComSize, params->forwardComSize),
991376Sbinkertn@umich.edu      instQueue(params),
1001376Sbinkertn@umich.edu      ldstQueue(params),
1011381Sbinkertn@umich.edu      fuPool(params->fuPool),
1021381Sbinkertn@umich.edu      commitToIEWDelay(params->commitToIEWDelay),
1031381Sbinkertn@umich.edu      renameToIEWDelay(params->renameToIEWDelay),
1041376Sbinkertn@umich.edu      issueToExecuteDelay(params->issueToExecuteDelay),
1051376Sbinkertn@umich.edu      dispatchWidth(params->dispatchWidth),
1061376Sbinkertn@umich.edu      issueWidth(params->issueWidth),
1071381Sbinkertn@umich.edu      wbOutstanding(0),
1081385Sbinkertn@umich.edu      wbWidth(params->wbWidth),
1091385Sbinkertn@umich.edu      numThreads(params->numberOfThreads),
1101381Sbinkertn@umich.edu      switchedOut(false)
1111376Sbinkertn@umich.edu{
1121381Sbinkertn@umich.edu    _status = Active;
1131381Sbinkertn@umich.edu    exeStatus = Running;
1141376Sbinkertn@umich.edu    wbStatus = Idle;
1151376Sbinkertn@umich.edu
1161381Sbinkertn@umich.edu    // Setup wire to read instructions coming from issue.
1171376Sbinkertn@umich.edu    fromIssue = issueToExecQueue.getWire(-issueToExecuteDelay);
1181381Sbinkertn@umich.edu
1191376Sbinkertn@umich.edu    // Instruction queue needs the queue between issue and execute.
1201376Sbinkertn@umich.edu    instQueue.setIssueToExecuteQueue(&issueToExecQueue);
1211376Sbinkertn@umich.edu
1221376Sbinkertn@umich.edu    instQueue.setIEW(this);
1231602Sbinkertn@umich.edu    ldstQueue.setIEW(this);
1241376Sbinkertn@umich.edu
1251376Sbinkertn@umich.edu    for (int i=0; i < numThreads; i++) {
1261376Sbinkertn@umich.edu        dispatchStatus[i] = Running;
1271376Sbinkertn@umich.edu        stalls[i].commit = false;
1281376Sbinkertn@umich.edu        fetchRedirect[i] = false;
1291376Sbinkertn@umich.edu    }
1301376Sbinkertn@umich.edu
1311376Sbinkertn@umich.edu    wbMax = wbWidth * params->wbDepth;
1321376Sbinkertn@umich.edu
1331376Sbinkertn@umich.edu    updateLSQNextCycle = false;
1341376Sbinkertn@umich.edu
1351376Sbinkertn@umich.edu    ableToIssue = true;
1361376Sbinkertn@umich.edu
1371376Sbinkertn@umich.edu    skidBufferMax = (3 * (renameToIEWDelay * params->renameWidth)) + issueWidth;
1381376Sbinkertn@umich.edu}
1391376Sbinkertn@umich.edu
1401376Sbinkertn@umich.edutemplate <class Impl>
1411376Sbinkertn@umich.edustd::string
1421376Sbinkertn@umich.eduDefaultIEW<Impl>::name() const
1431376Sbinkertn@umich.edu{
1441376Sbinkertn@umich.edu    return cpu->name() + ".iew";
1451376Sbinkertn@umich.edu}
1461376Sbinkertn@umich.edu
1471376Sbinkertn@umich.edutemplate <class Impl>
1481383Sbinkertn@umich.eduvoid
1491376Sbinkertn@umich.eduDefaultIEW<Impl>::regStats()
1501376Sbinkertn@umich.edu{
1511383Sbinkertn@umich.edu    using namespace Stats;
1521376Sbinkertn@umich.edu
1531376Sbinkertn@umich.edu    instQueue.regStats();
1541383Sbinkertn@umich.edu    ldstQueue.regStats();
1551383Sbinkertn@umich.edu
1561376Sbinkertn@umich.edu    iewIdleCycles
1571376Sbinkertn@umich.edu        .name(name() + ".iewIdleCycles")
1581376Sbinkertn@umich.edu        .desc("Number of cycles IEW is idle");
1591376Sbinkertn@umich.edu
1601376Sbinkertn@umich.edu    iewSquashCycles
1611383Sbinkertn@umich.edu        .name(name() + ".iewSquashCycles")
1621376Sbinkertn@umich.edu        .desc("Number of cycles IEW is squashing");
1631383Sbinkertn@umich.edu
1641393Sbinkertn@umich.edu    iewBlockCycles
1651376Sbinkertn@umich.edu        .name(name() + ".iewBlockCycles")
1661376Sbinkertn@umich.edu        .desc("Number of cycles IEW is blocking");
1671376Sbinkertn@umich.edu
1681376Sbinkertn@umich.edu    iewUnblockCycles
1691376Sbinkertn@umich.edu        .name(name() + ".iewUnblockCycles")
1701376Sbinkertn@umich.edu        .desc("Number of cycles IEW is unblocking");
1711376Sbinkertn@umich.edu
1721376Sbinkertn@umich.edu    iewDispatchedInsts
1731385Sbinkertn@umich.edu        .name(name() + ".iewDispatchedInsts")
1741385Sbinkertn@umich.edu        .desc("Number of instructions dispatched to IQ");
1751376Sbinkertn@umich.edu
1761376Sbinkertn@umich.edu    iewDispSquashedInsts
1771376Sbinkertn@umich.edu        .name(name() + ".iewDispSquashedInsts")
1781376Sbinkertn@umich.edu        .desc("Number of squashed instructions skipped by dispatch");
1791376Sbinkertn@umich.edu
1801376Sbinkertn@umich.edu    iewDispLoadInsts
1811376Sbinkertn@umich.edu        .name(name() + ".iewDispLoadInsts")
1821376Sbinkertn@umich.edu        .desc("Number of dispatched load instructions");
1831376Sbinkertn@umich.edu
1841376Sbinkertn@umich.edu    iewDispStoreInsts
1851385Sbinkertn@umich.edu        .name(name() + ".iewDispStoreInsts")
1861376Sbinkertn@umich.edu        .desc("Number of dispatched store instructions");
1871385Sbinkertn@umich.edu
1881385Sbinkertn@umich.edu    iewDispNonSpecInsts
1891385Sbinkertn@umich.edu        .name(name() + ".iewDispNonSpecInsts")
1901385Sbinkertn@umich.edu        .desc("Number of dispatched non-speculative instructions");
1911385Sbinkertn@umich.edu
1921385Sbinkertn@umich.edu    iewIQFullEvents
1931385Sbinkertn@umich.edu        .name(name() + ".iewIQFullEvents")
1941385Sbinkertn@umich.edu        .desc("Number of times the IQ has become full, causing a stall");
1951385Sbinkertn@umich.edu
196    iewLSQFullEvents
197        .name(name() + ".iewLSQFullEvents")
198        .desc("Number of times the LSQ has become full, causing a stall");
199
200    memOrderViolationEvents
201        .name(name() + ".memOrderViolationEvents")
202        .desc("Number of memory order violations");
203
204    predictedTakenIncorrect
205        .name(name() + ".predictedTakenIncorrect")
206        .desc("Number of branches that were predicted taken incorrectly");
207
208    predictedNotTakenIncorrect
209        .name(name() + ".predictedNotTakenIncorrect")
210        .desc("Number of branches that were predicted not taken incorrectly");
211
212    branchMispredicts
213        .name(name() + ".branchMispredicts")
214        .desc("Number of branch mispredicts detected at execute");
215
216    branchMispredicts = predictedTakenIncorrect + predictedNotTakenIncorrect;
217
218    iewExecutedInsts
219        .name(name() + ".iewExecutedInsts")
220        .desc("Number of executed instructions");
221
222    iewExecLoadInsts
223        .init(cpu->number_of_threads)
224        .name(name() + ".iewExecLoadInsts")
225        .desc("Number of load instructions executed")
226        .flags(total);
227
228    iewExecSquashedInsts
229        .name(name() + ".iewExecSquashedInsts")
230        .desc("Number of squashed instructions skipped in execute");
231
232    iewExecutedSwp
233        .init(cpu->number_of_threads)
234        .name(name() + ".EXEC:swp")
235        .desc("number of swp insts executed")
236        .flags(total);
237
238    iewExecutedNop
239        .init(cpu->number_of_threads)
240        .name(name() + ".EXEC:nop")
241        .desc("number of nop insts executed")
242        .flags(total);
243
244    iewExecutedRefs
245        .init(cpu->number_of_threads)
246        .name(name() + ".EXEC:refs")
247        .desc("number of memory reference insts executed")
248        .flags(total);
249
250    iewExecutedBranches
251        .init(cpu->number_of_threads)
252        .name(name() + ".EXEC:branches")
253        .desc("Number of branches executed")
254        .flags(total);
255
256    iewExecStoreInsts
257        .name(name() + ".EXEC:stores")
258        .desc("Number of stores executed")
259        .flags(total);
260    iewExecStoreInsts = iewExecutedRefs - iewExecLoadInsts;
261/*
262    for (int i=0; i<Num_OpClasses; ++i) {
263        stringstream subname;
264        subname << opClassStrings[i] << "_delay";
265        issue_delay_dist.subname(i, subname.str());
266    }
267*/
268    //
269    //  Other stats
270    //
271
272    iewInstsToCommit
273        .init(cpu->number_of_threads)
274        .name(name() + ".WB:sent")
275        .desc("cumulative count of insts sent to commit")
276        .flags(total);
277
278    writebackCount
279        .init(cpu->number_of_threads)
280        .name(name() + ".WB:count")
281        .desc("cumulative count of insts written-back")
282        .flags(total);
283
284    producerInst
285        .init(cpu->number_of_threads)
286        .name(name() + ".WB:producers")
287        .desc("num instructions producing a value")
288        .flags(total);
289
290    consumerInst
291        .init(cpu->number_of_threads)
292        .name(name() + ".WB:consumers")
293        .desc("num instructions consuming a value")
294        .flags(total);
295
296    wbPenalized
297        .init(cpu->number_of_threads)
298        .name(name() + ".WB:penalized")
299        .desc("number of instrctions required to write to 'other' IQ")
300        .flags(total);
301
302    wbPenalizedRate
303        .name(name() + ".WB:penalized_rate")
304        .desc ("fraction of instructions written-back that wrote to 'other' IQ")
305        .flags(total);
306
307    wbPenalizedRate = wbPenalized / writebackCount;
308
309    wbFanout
310        .name(name() + ".WB:fanout")
311        .desc("average fanout of values written-back")
312        .flags(total);
313
314    wbFanout = producerInst / consumerInst;
315
316    wbRate
317        .name(name() + ".WB:rate")
318        .desc("insts written-back per cycle")
319        .flags(total);
320    wbRate = writebackCount / cpu->numCycles;
321}
322
323template<class Impl>
324void
325DefaultIEW<Impl>::initStage()
326{
327    for (int tid=0; tid < numThreads; tid++) {
328        toRename->iewInfo[tid].usedIQ = true;
329        toRename->iewInfo[tid].freeIQEntries =
330            instQueue.numFreeEntries(tid);
331
332        toRename->iewInfo[tid].usedLSQ = true;
333        toRename->iewInfo[tid].freeLSQEntries =
334            ldstQueue.numFreeEntries(tid);
335    }
336}
337
338template<class Impl>
339void
340DefaultIEW<Impl>::setCPU(FullCPU *cpu_ptr)
341{
342    DPRINTF(IEW, "Setting CPU pointer.\n");
343    cpu = cpu_ptr;
344
345    instQueue.setCPU(cpu_ptr);
346    ldstQueue.setCPU(cpu_ptr);
347
348    cpu->activateStage(FullCPU::IEWIdx);
349}
350
351template<class Impl>
352void
353DefaultIEW<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
354{
355    DPRINTF(IEW, "Setting time buffer pointer.\n");
356    timeBuffer = tb_ptr;
357
358    // Setup wire to read information from time buffer, from commit.
359    fromCommit = timeBuffer->getWire(-commitToIEWDelay);
360
361    // Setup wire to write information back to previous stages.
362    toRename = timeBuffer->getWire(0);
363
364    toFetch = timeBuffer->getWire(0);
365
366    // Instruction queue also needs main time buffer.
367    instQueue.setTimeBuffer(tb_ptr);
368}
369
370template<class Impl>
371void
372DefaultIEW<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr)
373{
374    DPRINTF(IEW, "Setting rename queue pointer.\n");
375    renameQueue = rq_ptr;
376
377    // Setup wire to read information from rename queue.
378    fromRename = renameQueue->getWire(-renameToIEWDelay);
379}
380
381template<class Impl>
382void
383DefaultIEW<Impl>::setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr)
384{
385    DPRINTF(IEW, "Setting IEW queue pointer.\n");
386    iewQueue = iq_ptr;
387
388    // Setup wire to write instructions to commit.
389    toCommit = iewQueue->getWire(0);
390}
391
392template<class Impl>
393void
394DefaultIEW<Impl>::setActiveThreads(list<unsigned> *at_ptr)
395{
396    DPRINTF(IEW, "Setting active threads list pointer.\n");
397    activeThreads = at_ptr;
398
399    ldstQueue.setActiveThreads(at_ptr);
400    instQueue.setActiveThreads(at_ptr);
401}
402
403template<class Impl>
404void
405DefaultIEW<Impl>::setScoreboard(Scoreboard *sb_ptr)
406{
407    DPRINTF(IEW, "Setting scoreboard pointer.\n");
408    scoreboard = sb_ptr;
409}
410
411#if 0
412template<class Impl>
413void
414DefaultIEW<Impl>::setPageTable(PageTable *pt_ptr)
415{
416    ldstQueue.setPageTable(pt_ptr);
417}
418#endif
419
420template <class Impl>
421void
422DefaultIEW<Impl>::switchOut()
423{
424    // IEW is ready to switch out at any time.
425    cpu->signalSwitched();
426}
427
428template <class Impl>
429void
430DefaultIEW<Impl>::doSwitchOut()
431{
432    // Clear any state.
433    switchedOut = true;
434    assert(insts[0].empty());
435    assert(skidBuffer[0].empty());
436
437    instQueue.switchOut();
438    ldstQueue.switchOut();
439    fuPool->switchOut();
440
441    for (int i = 0; i < numThreads; i++) {
442        while (!insts[i].empty())
443            insts[i].pop();
444        while (!skidBuffer[i].empty())
445            skidBuffer[i].pop();
446    }
447}
448
449template <class Impl>
450void
451DefaultIEW<Impl>::takeOverFrom()
452{
453    // Reset all state.
454    _status = Active;
455    exeStatus = Running;
456    wbStatus = Idle;
457    switchedOut = false;
458
459    instQueue.takeOverFrom();
460    ldstQueue.takeOverFrom();
461    fuPool->takeOverFrom();
462
463    initStage();
464    cpu->activityThisCycle();
465
466    for (int i=0; i < numThreads; i++) {
467        dispatchStatus[i] = Running;
468        stalls[i].commit = false;
469        fetchRedirect[i] = false;
470    }
471
472    updateLSQNextCycle = false;
473
474    for (int i = 0; i < issueToExecQueue.getSize(); ++i) {
475        issueToExecQueue.advance();
476    }
477}
478
479template<class Impl>
480void
481DefaultIEW<Impl>::squash(unsigned tid)
482{
483    DPRINTF(IEW, "[tid:%i]: Squashing all instructions.\n",
484            tid);
485
486    // Tell the IQ to start squashing.
487    instQueue.squash(tid);
488
489    // Tell the LDSTQ to start squashing.
490    ldstQueue.squash(fromCommit->commitInfo[tid].doneSeqNum, tid);
491
492    updatedQueues = true;
493
494    // Clear the skid buffer in case it has any data in it.
495    while (!skidBuffer[tid].empty()) {
496
497        if (skidBuffer[tid].front()->isLoad() ||
498            skidBuffer[tid].front()->isStore() ) {
499            toRename->iewInfo[tid].dispatchedToLSQ++;
500        }
501
502        toRename->iewInfo[tid].dispatched++;
503
504        skidBuffer[tid].pop();
505    }
506
507    emptyRenameInsts(tid);
508}
509
510template<class Impl>
511void
512DefaultIEW<Impl>::squashDueToBranch(DynInstPtr &inst, unsigned tid)
513{
514    DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, PC: %#x "
515            "[sn:%i].\n", tid, inst->readPC(), inst->seqNum);
516
517    toCommit->squash[tid] = true;
518    toCommit->squashedSeqNum[tid] = inst->seqNum;
519    toCommit->mispredPC[tid] = inst->readPC();
520    toCommit->nextPC[tid] = inst->readNextPC();
521    toCommit->branchMispredict[tid] = true;
522    toCommit->branchTaken[tid] = inst->readNextPC() !=
523        (inst->readPC() + sizeof(TheISA::MachInst));
524
525    toCommit->includeSquashInst[tid] = false;
526
527    wroteToTimeBuffer = true;
528}
529
530template<class Impl>
531void
532DefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, unsigned tid)
533{
534    DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, "
535            "PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum);
536
537    toCommit->squash[tid] = true;
538    toCommit->squashedSeqNum[tid] = inst->seqNum;
539    toCommit->nextPC[tid] = inst->readNextPC();
540
541    toCommit->includeSquashInst[tid] = false;
542
543    wroteToTimeBuffer = true;
544}
545
546template<class Impl>
547void
548DefaultIEW<Impl>::squashDueToMemBlocked(DynInstPtr &inst, unsigned tid)
549{
550    DPRINTF(IEW, "[tid:%i]: Memory blocked, squashing load and younger insts, "
551            "PC: %#x [sn:%i].\n", tid, inst->readPC(), inst->seqNum);
552
553    toCommit->squash[tid] = true;
554    toCommit->squashedSeqNum[tid] = inst->seqNum;
555    toCommit->nextPC[tid] = inst->readPC();
556
557    // Must include the broadcasted SN in the squash.
558    toCommit->includeSquashInst[tid] = true;
559
560    ldstQueue.setLoadBlockedHandled(tid);
561
562    wroteToTimeBuffer = true;
563}
564
565template<class Impl>
566void
567DefaultIEW<Impl>::block(unsigned tid)
568{
569    DPRINTF(IEW, "[tid:%u]: Blocking.\n", tid);
570
571    if (dispatchStatus[tid] != Blocked &&
572        dispatchStatus[tid] != Unblocking) {
573        toRename->iewBlock[tid] = true;
574        wroteToTimeBuffer = true;
575    }
576
577    // Add the current inputs to the skid buffer so they can be
578    // reprocessed when this stage unblocks.
579    skidInsert(tid);
580
581    dispatchStatus[tid] = Blocked;
582}
583
584template<class Impl>
585void
586DefaultIEW<Impl>::unblock(unsigned tid)
587{
588    DPRINTF(IEW, "[tid:%i]: Reading instructions out of the skid "
589            "buffer %u.\n",tid, tid);
590
591    // If the skid bufffer is empty, signal back to previous stages to unblock.
592    // Also switch status to running.
593    if (skidBuffer[tid].empty()) {
594        toRename->iewUnblock[tid] = true;
595        wroteToTimeBuffer = true;
596        DPRINTF(IEW, "[tid:%i]: Done unblocking.\n",tid);
597        dispatchStatus[tid] = Running;
598    }
599}
600
601template<class Impl>
602void
603DefaultIEW<Impl>::wakeDependents(DynInstPtr &inst)
604{
605    instQueue.wakeDependents(inst);
606}
607
608template<class Impl>
609void
610DefaultIEW<Impl>::rescheduleMemInst(DynInstPtr &inst)
611{
612    instQueue.rescheduleMemInst(inst);
613}
614
615template<class Impl>
616void
617DefaultIEW<Impl>::replayMemInst(DynInstPtr &inst)
618{
619    instQueue.replayMemInst(inst);
620}
621
622template<class Impl>
623void
624DefaultIEW<Impl>::instToCommit(DynInstPtr &inst)
625{
626    // First check the time slot that this instruction will write
627    // to.  If there are free write ports at the time, then go ahead
628    // and write the instruction to that time.  If there are not,
629    // keep looking back to see where's the first time there's a
630    // free slot.
631    while ((*iewQueue)[wbCycle].insts[wbNumInst]) {
632        ++wbNumInst;
633        if (wbNumInst == wbWidth) {
634            ++wbCycle;
635            wbNumInst = 0;
636        }
637
638        assert((wbCycle * wbWidth + wbNumInst) <= wbMax);
639    }
640
641    DPRINTF(IEW, "Current wb cycle: %i, width: %i, numInst: %i\nwbActual:%i\n",
642            wbCycle, wbWidth, wbNumInst, wbCycle * wbWidth + wbNumInst);
643    // Add finished instruction to queue to commit.
644    (*iewQueue)[wbCycle].insts[wbNumInst] = inst;
645    (*iewQueue)[wbCycle].size++;
646}
647
648template <class Impl>
649unsigned
650DefaultIEW<Impl>::validInstsFromRename()
651{
652    unsigned inst_count = 0;
653
654    for (int i=0; i<fromRename->size; i++) {
655        if (!fromRename->insts[i]->isSquashed())
656            inst_count++;
657    }
658
659    return inst_count;
660}
661
662template<class Impl>
663void
664DefaultIEW<Impl>::skidInsert(unsigned tid)
665{
666    DynInstPtr inst = NULL;
667
668    while (!insts[tid].empty()) {
669        inst = insts[tid].front();
670
671        insts[tid].pop();
672
673        DPRINTF(Decode,"[tid:%i]: Inserting [sn:%lli] PC:%#x into "
674                "dispatch skidBuffer %i\n",tid, inst->seqNum,
675                inst->readPC(),tid);
676
677        skidBuffer[tid].push(inst);
678    }
679
680    assert(skidBuffer[tid].size() <= skidBufferMax &&
681           "Skidbuffer Exceeded Max Size");
682}
683
684template<class Impl>
685int
686DefaultIEW<Impl>::skidCount()
687{
688    int max=0;
689
690    list<unsigned>::iterator threads = (*activeThreads).begin();
691
692    while (threads != (*activeThreads).end()) {
693        unsigned thread_count = skidBuffer[*threads++].size();
694        if (max < thread_count)
695            max = thread_count;
696    }
697
698    return max;
699}
700
701template<class Impl>
702bool
703DefaultIEW<Impl>::skidsEmpty()
704{
705    list<unsigned>::iterator threads = (*activeThreads).begin();
706
707    while (threads != (*activeThreads).end()) {
708        if (!skidBuffer[*threads++].empty())
709            return false;
710    }
711
712    return true;
713}
714
715template <class Impl>
716void
717DefaultIEW<Impl>::updateStatus()
718{
719    bool any_unblocking = false;
720
721    list<unsigned>::iterator threads = (*activeThreads).begin();
722
723    threads = (*activeThreads).begin();
724
725    while (threads != (*activeThreads).end()) {
726        unsigned tid = *threads++;
727
728        if (dispatchStatus[tid] == Unblocking) {
729            any_unblocking = true;
730            break;
731        }
732    }
733
734    // If there are no ready instructions waiting to be scheduled by the IQ,
735    // and there's no stores waiting to write back, and dispatch is not
736    // unblocking, then there is no internal activity for the IEW stage.
737    if (_status == Active && !instQueue.hasReadyInsts() &&
738        !ldstQueue.willWB() && !any_unblocking) {
739        DPRINTF(IEW, "IEW switching to idle\n");
740
741        deactivateStage();
742
743        _status = Inactive;
744    } else if (_status == Inactive && (instQueue.hasReadyInsts() ||
745                                       ldstQueue.willWB() ||
746                                       any_unblocking)) {
747        // Otherwise there is internal activity.  Set to active.
748        DPRINTF(IEW, "IEW switching to active\n");
749
750        activateStage();
751
752        _status = Active;
753    }
754}
755
756template <class Impl>
757void
758DefaultIEW<Impl>::resetEntries()
759{
760    instQueue.resetEntries();
761    ldstQueue.resetEntries();
762}
763
764template <class Impl>
765void
766DefaultIEW<Impl>::readStallSignals(unsigned tid)
767{
768    if (fromCommit->commitBlock[tid]) {
769        stalls[tid].commit = true;
770    }
771
772    if (fromCommit->commitUnblock[tid]) {
773        assert(stalls[tid].commit);
774        stalls[tid].commit = false;
775    }
776}
777
778template <class Impl>
779bool
780DefaultIEW<Impl>::checkStall(unsigned tid)
781{
782    bool ret_val(false);
783
784    if (stalls[tid].commit) {
785        DPRINTF(IEW,"[tid:%i]: Stall from Commit stage detected.\n",tid);
786        ret_val = true;
787    } else if (instQueue.isFull(tid)) {
788        DPRINTF(IEW,"[tid:%i]: Stall: IQ  is full.\n",tid);
789        ret_val = true;
790    } else if (ldstQueue.isFull(tid)) {
791        DPRINTF(IEW,"[tid:%i]: Stall: LSQ is full\n",tid);
792
793        if (ldstQueue.numLoads(tid) > 0 ) {
794
795            DPRINTF(IEW,"[tid:%i]: LSQ oldest load: [sn:%i] \n",
796                    tid,ldstQueue.getLoadHeadSeqNum(tid));
797        }
798
799        if (ldstQueue.numStores(tid) > 0) {
800
801            DPRINTF(IEW,"[tid:%i]: LSQ oldest store: [sn:%i] \n",
802                    tid,ldstQueue.getStoreHeadSeqNum(tid));
803        }
804
805        ret_val = true;
806    } else if (ldstQueue.isStalled(tid)) {
807        DPRINTF(IEW,"[tid:%i]: Stall: LSQ stall detected.\n",tid);
808        ret_val = true;
809    }
810
811    return ret_val;
812}
813
814template <class Impl>
815void
816DefaultIEW<Impl>::checkSignalsAndUpdate(unsigned tid)
817{
818    // Check if there's a squash signal, squash if there is
819    // Check stall signals, block if there is.
820    // If status was Blocked
821    //     if so then go to unblocking
822    // If status was Squashing
823    //     check if squashing is not high.  Switch to running this cycle.
824
825    readStallSignals(tid);
826
827    if (fromCommit->commitInfo[tid].squash) {
828        squash(tid);
829
830        if (dispatchStatus[tid] == Blocked ||
831            dispatchStatus[tid] == Unblocking) {
832            toRename->iewUnblock[tid] = true;
833            wroteToTimeBuffer = true;
834        }
835
836        dispatchStatus[tid] = Squashing;
837
838        fetchRedirect[tid] = false;
839        return;
840    }
841
842    if (fromCommit->commitInfo[tid].robSquashing) {
843        DPRINTF(IEW, "[tid:%i]: ROB is still squashing.\n", tid);
844
845        dispatchStatus[tid] = Squashing;
846
847        emptyRenameInsts(tid);
848        wroteToTimeBuffer = true;
849        return;
850    }
851
852    if (checkStall(tid)) {
853        block(tid);
854        dispatchStatus[tid] = Blocked;
855        return;
856    }
857
858    if (dispatchStatus[tid] == Blocked) {
859        // Status from previous cycle was blocked, but there are no more stall
860        // conditions.  Switch over to unblocking.
861        DPRINTF(IEW, "[tid:%i]: Done blocking, switching to unblocking.\n",
862                tid);
863
864        dispatchStatus[tid] = Unblocking;
865
866        unblock(tid);
867
868        return;
869    }
870
871    if (dispatchStatus[tid] == Squashing) {
872        // Switch status to running if rename isn't being told to block or
873        // squash this cycle.
874        DPRINTF(IEW, "[tid:%i]: Done squashing, switching to running.\n",
875                tid);
876
877        dispatchStatus[tid] = Running;
878
879        return;
880    }
881}
882
883template <class Impl>
884void
885DefaultIEW<Impl>::sortInsts()
886{
887    int insts_from_rename = fromRename->size;
888#ifdef DEBUG
889    for (int i = 0; i < numThreads; i++)
890        assert(insts[i].empty());
891#endif
892    for (int i = 0; i < insts_from_rename; ++i) {
893        insts[fromRename->insts[i]->threadNumber].push(fromRename->insts[i]);
894    }
895}
896
897template <class Impl>
898void
899DefaultIEW<Impl>::emptyRenameInsts(unsigned tid)
900{
901    while (!insts[tid].empty()) {
902        if (insts[tid].front()->isLoad() ||
903            insts[tid].front()->isStore() ) {
904            toRename->iewInfo[tid].dispatchedToLSQ++;
905        }
906
907        toRename->iewInfo[tid].dispatched++;
908
909        insts[tid].pop();
910    }
911}
912
913template <class Impl>
914void
915DefaultIEW<Impl>::wakeCPU()
916{
917    cpu->wakeCPU();
918}
919
920template <class Impl>
921void
922DefaultIEW<Impl>::activityThisCycle()
923{
924    DPRINTF(Activity, "Activity this cycle.\n");
925    cpu->activityThisCycle();
926}
927
928template <class Impl>
929inline void
930DefaultIEW<Impl>::activateStage()
931{
932    DPRINTF(Activity, "Activating stage.\n");
933    cpu->activateStage(FullCPU::IEWIdx);
934}
935
936template <class Impl>
937inline void
938DefaultIEW<Impl>::deactivateStage()
939{
940    DPRINTF(Activity, "Deactivating stage.\n");
941    cpu->deactivateStage(FullCPU::IEWIdx);
942}
943
944template<class Impl>
945void
946DefaultIEW<Impl>::dispatch(unsigned tid)
947{
948    // If status is Running or idle,
949    //     call dispatchInsts()
950    // If status is Unblocking,
951    //     buffer any instructions coming from rename
952    //     continue trying to empty skid buffer
953    //     check if stall conditions have passed
954
955    if (dispatchStatus[tid] == Blocked) {
956        ++iewBlockCycles;
957
958    } else if (dispatchStatus[tid] == Squashing) {
959        ++iewSquashCycles;
960    }
961
962    // Dispatch should try to dispatch as many instructions as its bandwidth
963    // will allow, as long as it is not currently blocked.
964    if (dispatchStatus[tid] == Running ||
965        dispatchStatus[tid] == Idle) {
966        DPRINTF(IEW, "[tid:%i] Not blocked, so attempting to run "
967                "dispatch.\n", tid);
968
969        dispatchInsts(tid);
970    } else if (dispatchStatus[tid] == Unblocking) {
971        // Make sure that the skid buffer has something in it if the
972        // status is unblocking.
973        assert(!skidsEmpty());
974
975        // If the status was unblocking, then instructions from the skid
976        // buffer were used.  Remove those instructions and handle
977        // the rest of unblocking.
978        dispatchInsts(tid);
979
980        ++iewUnblockCycles;
981
982        if (validInstsFromRename() && dispatchedAllInsts) {
983            // Add the current inputs to the skid buffer so they can be
984            // reprocessed when this stage unblocks.
985            skidInsert(tid);
986        }
987
988        unblock(tid);
989    }
990}
991
992template <class Impl>
993void
994DefaultIEW<Impl>::dispatchInsts(unsigned tid)
995{
996    dispatchedAllInsts = true;
997
998    // Obtain instructions from skid buffer if unblocking, or queue from rename
999    // otherwise.
1000    std::queue<DynInstPtr> &insts_to_dispatch =
1001        dispatchStatus[tid] == Unblocking ?
1002        skidBuffer[tid] : insts[tid];
1003
1004    int insts_to_add = insts_to_dispatch.size();
1005
1006    DynInstPtr inst;
1007    bool add_to_iq = false;
1008    int dis_num_inst = 0;
1009
1010    // Loop through the instructions, putting them in the instruction
1011    // queue.
1012    for ( ; dis_num_inst < insts_to_add &&
1013              dis_num_inst < dispatchWidth;
1014          ++dis_num_inst)
1015    {
1016        inst = insts_to_dispatch.front();
1017
1018        if (dispatchStatus[tid] == Unblocking) {
1019            DPRINTF(IEW, "[tid:%i]: Issue: Examining instruction from skid "
1020                    "buffer\n", tid);
1021        }
1022
1023        // Make sure there's a valid instruction there.
1024        assert(inst);
1025
1026        DPRINTF(IEW, "[tid:%i]: Issue: Adding PC %#x [sn:%lli] [tid:%i] to "
1027                "IQ.\n",
1028                tid, inst->readPC(), inst->seqNum, inst->threadNumber);
1029
1030        // Be sure to mark these instructions as ready so that the
1031        // commit stage can go ahead and execute them, and mark
1032        // them as issued so the IQ doesn't reprocess them.
1033
1034        // Check for squashed instructions.
1035        if (inst->isSquashed()) {
1036            DPRINTF(IEW, "[tid:%i]: Issue: Squashed instruction encountered, "
1037                    "not adding to IQ.\n", tid);
1038
1039            ++iewDispSquashedInsts;
1040
1041            insts_to_dispatch.pop();
1042
1043            //Tell Rename That An Instruction has been processed
1044            if (inst->isLoad() || inst->isStore()) {
1045                toRename->iewInfo[tid].dispatchedToLSQ++;
1046            }
1047            toRename->iewInfo[tid].dispatched++;
1048
1049            continue;
1050        }
1051
1052        // Check for full conditions.
1053        if (instQueue.isFull(tid)) {
1054            DPRINTF(IEW, "[tid:%i]: Issue: IQ has become full.\n", tid);
1055
1056            // Call function to start blocking.
1057            block(tid);
1058
1059            // Set unblock to false. Special case where we are using
1060            // skidbuffer (unblocking) instructions but then we still
1061            // get full in the IQ.
1062            toRename->iewUnblock[tid] = false;
1063
1064            dispatchedAllInsts = false;
1065
1066            ++iewIQFullEvents;
1067            break;
1068        } else if (ldstQueue.isFull(tid)) {
1069            DPRINTF(IEW, "[tid:%i]: Issue: LSQ has become full.\n",tid);
1070
1071            // Call function to start blocking.
1072            block(tid);
1073
1074            // Set unblock to false. Special case where we are using
1075            // skidbuffer (unblocking) instructions but then we still
1076            // get full in the IQ.
1077            toRename->iewUnblock[tid] = false;
1078
1079            dispatchedAllInsts = false;
1080
1081            ++iewLSQFullEvents;
1082            break;
1083        }
1084
1085        // Otherwise issue the instruction just fine.
1086        if (inst->isLoad()) {
1087            DPRINTF(IEW, "[tid:%i]: Issue: Memory instruction "
1088                    "encountered, adding to LSQ.\n", tid);
1089
1090            // Reserve a spot in the load store queue for this
1091            // memory access.
1092            ldstQueue.insertLoad(inst);
1093
1094            ++iewDispLoadInsts;
1095
1096            add_to_iq = true;
1097
1098            toRename->iewInfo[tid].dispatchedToLSQ++;
1099        } else if (inst->isStore()) {
1100            DPRINTF(IEW, "[tid:%i]: Issue: Memory instruction "
1101                    "encountered, adding to LSQ.\n", tid);
1102
1103            ldstQueue.insertStore(inst);
1104
1105            ++iewDispStoreInsts;
1106
1107            if (inst->isStoreConditional()) {
1108                // Store conditionals need to be set as "canCommit()"
1109                // so that commit can process them when they reach the
1110                // head of commit.
1111                // @todo: This is somewhat specific to Alpha.
1112                inst->setCanCommit();
1113                instQueue.insertNonSpec(inst);
1114                add_to_iq = false;
1115
1116                ++iewDispNonSpecInsts;
1117            } else {
1118                add_to_iq = true;
1119            }
1120
1121            toRename->iewInfo[tid].dispatchedToLSQ++;
1122#if FULL_SYSTEM
1123        } else if (inst->isMemBarrier() || inst->isWriteBarrier()) {
1124            // Same as non-speculative stores.
1125            inst->setCanCommit();
1126            instQueue.insertBarrier(inst);
1127            add_to_iq = false;
1128#endif
1129        } else if (inst->isNonSpeculative()) {
1130            DPRINTF(IEW, "[tid:%i]: Issue: Nonspeculative instruction "
1131                    "encountered, skipping.\n", tid);
1132
1133            // Same as non-speculative stores.
1134            inst->setCanCommit();
1135
1136            // Specifically insert it as nonspeculative.
1137            instQueue.insertNonSpec(inst);
1138
1139            ++iewDispNonSpecInsts;
1140
1141            add_to_iq = false;
1142        } else if (inst->isNop()) {
1143            DPRINTF(IEW, "[tid:%i]: Issue: Nop instruction encountered, "
1144                    "skipping.\n", tid);
1145
1146            inst->setIssued();
1147            inst->setExecuted();
1148            inst->setCanCommit();
1149
1150            instQueue.recordProducer(inst);
1151
1152            iewExecutedNop[tid]++;
1153
1154            add_to_iq = false;
1155        } else if (inst->isExecuted()) {
1156            assert(0 && "Instruction shouldn't be executed.\n");
1157            DPRINTF(IEW, "Issue: Executed branch encountered, "
1158                    "skipping.\n");
1159
1160            inst->setIssued();
1161            inst->setCanCommit();
1162
1163            instQueue.recordProducer(inst);
1164
1165            add_to_iq = false;
1166        } else {
1167            add_to_iq = true;
1168        }
1169
1170        // If the instruction queue is not full, then add the
1171        // instruction.
1172        if (add_to_iq) {
1173            instQueue.insert(inst);
1174        }
1175
1176        insts_to_dispatch.pop();
1177
1178        toRename->iewInfo[tid].dispatched++;
1179
1180        ++iewDispatchedInsts;
1181    }
1182
1183    if (!insts_to_dispatch.empty()) {
1184        DPRINTF(IEW,"[tid:%i]: Issue: Bandwidth Full. Blocking.\n");
1185        block(tid);
1186        toRename->iewUnblock[tid] = false;
1187    }
1188
1189    if (dispatchStatus[tid] == Idle && dis_num_inst) {
1190        dispatchStatus[tid] = Running;
1191
1192        updatedQueues = true;
1193    }
1194
1195    dis_num_inst = 0;
1196}
1197
1198template <class Impl>
1199void
1200DefaultIEW<Impl>::printAvailableInsts()
1201{
1202    int inst = 0;
1203
1204    cout << "Available Instructions: ";
1205
1206    while (fromIssue->insts[inst]) {
1207
1208        if (inst%3==0) cout << "\n\t";
1209
1210        cout << "PC: " << fromIssue->insts[inst]->readPC()
1211             << " TN: " << fromIssue->insts[inst]->threadNumber
1212             << " SN: " << fromIssue->insts[inst]->seqNum << " | ";
1213
1214        inst++;
1215
1216    }
1217
1218    cout << "\n";
1219}
1220
1221template <class Impl>
1222void
1223DefaultIEW<Impl>::executeInsts()
1224{
1225    wbNumInst = 0;
1226    wbCycle = 0;
1227
1228    list<unsigned>::iterator threads = (*activeThreads).begin();
1229
1230    while (threads != (*activeThreads).end()) {
1231        unsigned tid = *threads++;
1232        fetchRedirect[tid] = false;
1233    }
1234
1235#if 0
1236    printAvailableInsts();
1237#endif
1238
1239    // Execute/writeback any instructions that are available.
1240    int insts_to_execute = fromIssue->size;
1241    int inst_num = 0;
1242    for (; inst_num < insts_to_execute;
1243          ++inst_num) {
1244
1245        DPRINTF(IEW, "Execute: Executing instructions from IQ.\n");
1246
1247        DynInstPtr inst = instQueue.getInstToExecute();
1248
1249        DPRINTF(IEW, "Execute: Processing PC %#x, [tid:%i] [sn:%i].\n",
1250                inst->readPC(), inst->threadNumber,inst->seqNum);
1251
1252        // Check if the instruction is squashed; if so then skip it
1253        if (inst->isSquashed()) {
1254            DPRINTF(IEW, "Execute: Instruction was squashed.\n");
1255
1256            // Consider this instruction executed so that commit can go
1257            // ahead and retire the instruction.
1258            inst->setExecuted();
1259
1260            // Not sure if I should set this here or just let commit try to
1261            // commit any squashed instructions.  I like the latter a bit more.
1262            inst->setCanCommit();
1263
1264            ++iewExecSquashedInsts;
1265
1266            decrWb(inst->seqNum);
1267            continue;
1268        }
1269
1270        Fault fault = NoFault;
1271
1272        // Execute instruction.
1273        // Note that if the instruction faults, it will be handled
1274        // at the commit stage.
1275        if (inst->isMemRef() &&
1276            (!inst->isDataPrefetch() && !inst->isInstPrefetch())) {
1277            DPRINTF(IEW, "Execute: Calculating address for memory "
1278                    "reference.\n");
1279
1280            // Tell the LDSTQ to execute this instruction (if it is a load).
1281            if (inst->isLoad()) {
1282                // Loads will mark themselves as executed, and their writeback
1283                // event adds the instruction to the queue to commit
1284                fault = ldstQueue.executeLoad(inst);
1285            } else if (inst->isStore()) {
1286                fault = ldstQueue.executeStore(inst);
1287
1288                // If the store had a fault then it may not have a mem req
1289                if (!inst->isStoreConditional() && fault == NoFault) {
1290                    inst->setExecuted();
1291
1292                    instToCommit(inst);
1293                } else if (fault != NoFault) {
1294                    // If the instruction faulted, then we need to send it along to commit
1295                    // without the instruction completing.
1296
1297                    // Send this instruction to commit, also make sure iew stage
1298                    // realizes there is activity.
1299                    inst->setExecuted();
1300
1301                    instToCommit(inst);
1302                    activityThisCycle();
1303                }
1304
1305                // Store conditionals will mark themselves as
1306                // executed, and their writeback event will add the
1307                // instruction to the queue to commit.
1308            } else {
1309                panic("Unexpected memory type!\n");
1310            }
1311
1312        } else {
1313            inst->execute();
1314
1315            inst->setExecuted();
1316
1317            instToCommit(inst);
1318        }
1319
1320        updateExeInstStats(inst);
1321
1322        // Check if branch prediction was correct, if not then we need
1323        // to tell commit to squash in flight instructions.  Only
1324        // handle this if there hasn't already been something that
1325        // redirects fetch in this group of instructions.
1326
1327        // This probably needs to prioritize the redirects if a different
1328        // scheduler is used.  Currently the scheduler schedules the oldest
1329        // instruction first, so the branch resolution order will be correct.
1330        unsigned tid = inst->threadNumber;
1331
1332        if (!fetchRedirect[tid]) {
1333
1334            if (inst->mispredicted()) {
1335                fetchRedirect[tid] = true;
1336
1337                DPRINTF(IEW, "Execute: Branch mispredict detected.\n");
1338                DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x.\n",
1339                        inst->nextPC);
1340
1341                // If incorrect, then signal the ROB that it must be squashed.
1342                squashDueToBranch(inst, tid);
1343
1344                if (inst->predTaken()) {
1345                    predictedTakenIncorrect++;
1346                } else {
1347                    predictedNotTakenIncorrect++;
1348                }
1349            } else if (ldstQueue.violation(tid)) {
1350                fetchRedirect[tid] = true;
1351
1352                // If there was an ordering violation, then get the
1353                // DynInst that caused the violation.  Note that this
1354                // clears the violation signal.
1355                DynInstPtr violator;
1356                violator = ldstQueue.getMemDepViolator(tid);
1357
1358                DPRINTF(IEW, "LDSTQ detected a violation.  Violator PC: "
1359                        "%#x, inst PC: %#x.  Addr is: %#x.\n",
1360                        violator->readPC(), inst->readPC(), inst->physEffAddr);
1361
1362                // Tell the instruction queue that a violation has occured.
1363                instQueue.violation(inst, violator);
1364
1365                // Squash.
1366                squashDueToMemOrder(inst,tid);
1367
1368                ++memOrderViolationEvents;
1369            } else if (ldstQueue.loadBlocked(tid) &&
1370                       !ldstQueue.isLoadBlockedHandled(tid)) {
1371                fetchRedirect[tid] = true;
1372
1373                DPRINTF(IEW, "Load operation couldn't execute because the "
1374                        "memory system is blocked.  PC: %#x [sn:%lli]\n",
1375                        inst->readPC(), inst->seqNum);
1376
1377                squashDueToMemBlocked(inst, tid);
1378            }
1379        }
1380    }
1381
1382    // Update and record activity if we processed any instructions.
1383    if (inst_num) {
1384        if (exeStatus == Idle) {
1385            exeStatus = Running;
1386        }
1387
1388        updatedQueues = true;
1389
1390        cpu->activityThisCycle();
1391    }
1392
1393    // Need to reset this in case a writeback event needs to write into the
1394    // iew queue.  That way the writeback event will write into the correct
1395    // spot in the queue.
1396    wbNumInst = 0;
1397}
1398
1399template <class Impl>
1400void
1401DefaultIEW<Impl>::writebackInsts()
1402{
1403    // Loop through the head of the time buffer and wake any
1404    // dependents.  These instructions are about to write back.  Also
1405    // mark scoreboard that this instruction is finally complete.
1406    // Either have IEW have direct access to scoreboard, or have this
1407    // as part of backwards communication.
1408    for (int inst_num = 0; inst_num < issueWidth &&
1409             toCommit->insts[inst_num]; inst_num++) {
1410        DynInstPtr inst = toCommit->insts[inst_num];
1411        int tid = inst->threadNumber;
1412
1413        DPRINTF(IEW, "Sending instructions to commit, [sn:%lli] PC %#x.\n",
1414                inst->seqNum, inst->readPC());
1415
1416        iewInstsToCommit[tid]++;
1417
1418        // Some instructions will be sent to commit without having
1419        // executed because they need commit to handle them.
1420        // E.g. Uncached loads have not actually executed when they
1421        // are first sent to commit.  Instead commit must tell the LSQ
1422        // when it's ready to execute the uncached load.
1423        if (!inst->isSquashed() && inst->isExecuted() && inst->getFault() == NoFault) {
1424            int dependents = instQueue.wakeDependents(inst);
1425
1426            for (int i = 0; i < inst->numDestRegs(); i++) {
1427                //mark as Ready
1428                DPRINTF(IEW,"Setting Destination Register %i\n",
1429                        inst->renamedDestRegIdx(i));
1430                scoreboard->setReg(inst->renamedDestRegIdx(i));
1431            }
1432
1433            if (dependents) {
1434                producerInst[tid]++;
1435                consumerInst[tid]+= dependents;
1436            }
1437            writebackCount[tid]++;
1438        }
1439
1440        decrWb(inst->seqNum);
1441    }
1442}
1443
1444template<class Impl>
1445void
1446DefaultIEW<Impl>::tick()
1447{
1448    wbNumInst = 0;
1449    wbCycle = 0;
1450
1451    wroteToTimeBuffer = false;
1452    updatedQueues = false;
1453
1454    sortInsts();
1455
1456    // Free function units marked as being freed this cycle.
1457    fuPool->processFreeUnits();
1458
1459    list<unsigned>::iterator threads = (*activeThreads).begin();
1460
1461    // Check stall and squash signals, dispatch any instructions.
1462    while (threads != (*activeThreads).end()) {
1463           unsigned tid = *threads++;
1464
1465        DPRINTF(IEW,"Issue: Processing [tid:%i]\n",tid);
1466
1467        checkSignalsAndUpdate(tid);
1468        dispatch(tid);
1469    }
1470
1471    if (exeStatus != Squashing) {
1472        executeInsts();
1473
1474        writebackInsts();
1475
1476        // Have the instruction queue try to schedule any ready instructions.
1477        // (In actuality, this scheduling is for instructions that will
1478        // be executed next cycle.)
1479        instQueue.scheduleReadyInsts();
1480
1481        // Also should advance its own time buffers if the stage ran.
1482        // Not the best place for it, but this works (hopefully).
1483        issueToExecQueue.advance();
1484    }
1485
1486    bool broadcast_free_entries = false;
1487
1488    if (updatedQueues || exeStatus == Running || updateLSQNextCycle) {
1489        exeStatus = Idle;
1490        updateLSQNextCycle = false;
1491
1492        broadcast_free_entries = true;
1493    }
1494
1495    // Writeback any stores using any leftover bandwidth.
1496    ldstQueue.writebackStores();
1497
1498    // Check the committed load/store signals to see if there's a load
1499    // or store to commit.  Also check if it's being told to execute a
1500    // nonspeculative instruction.
1501    // This is pretty inefficient...
1502
1503    threads = (*activeThreads).begin();
1504    while (threads != (*activeThreads).end()) {
1505        unsigned tid = (*threads++);
1506
1507        DPRINTF(IEW,"Processing [tid:%i]\n",tid);
1508
1509        // Update structures based on instructions committed.
1510        if (fromCommit->commitInfo[tid].doneSeqNum != 0 &&
1511            !fromCommit->commitInfo[tid].squash &&
1512            !fromCommit->commitInfo[tid].robSquashing) {
1513
1514            ldstQueue.commitStores(fromCommit->commitInfo[tid].doneSeqNum,tid);
1515
1516            ldstQueue.commitLoads(fromCommit->commitInfo[tid].doneSeqNum,tid);
1517
1518            updateLSQNextCycle = true;
1519            instQueue.commit(fromCommit->commitInfo[tid].doneSeqNum,tid);
1520        }
1521
1522        if (fromCommit->commitInfo[tid].nonSpecSeqNum != 0) {
1523
1524            //DPRINTF(IEW,"NonspecInst from thread %i",tid);
1525            if (fromCommit->commitInfo[tid].uncached) {
1526                instQueue.replayMemInst(fromCommit->commitInfo[tid].uncachedLoad);
1527            } else {
1528                instQueue.scheduleNonSpec(
1529                    fromCommit->commitInfo[tid].nonSpecSeqNum);
1530            }
1531        }
1532
1533        if (broadcast_free_entries) {
1534            toFetch->iewInfo[tid].iqCount =
1535                instQueue.getCount(tid);
1536            toFetch->iewInfo[tid].ldstqCount =
1537                ldstQueue.getCount(tid);
1538
1539            toRename->iewInfo[tid].usedIQ = true;
1540            toRename->iewInfo[tid].freeIQEntries =
1541                instQueue.numFreeEntries();
1542            toRename->iewInfo[tid].usedLSQ = true;
1543            toRename->iewInfo[tid].freeLSQEntries =
1544                ldstQueue.numFreeEntries(tid);
1545
1546            wroteToTimeBuffer = true;
1547        }
1548
1549        DPRINTF(IEW, "[tid:%i], Dispatch dispatched %i instructions.\n",
1550                tid, toRename->iewInfo[tid].dispatched);
1551    }
1552
1553    DPRINTF(IEW, "IQ has %i free entries (Can schedule: %i).  "
1554            "LSQ has %i free entries.\n",
1555            instQueue.numFreeEntries(), instQueue.hasReadyInsts(),
1556            ldstQueue.numFreeEntries());
1557
1558    updateStatus();
1559
1560    if (wroteToTimeBuffer) {
1561        DPRINTF(Activity, "Activity this cycle.\n");
1562        cpu->activityThisCycle();
1563    }
1564}
1565
1566template <class Impl>
1567void
1568DefaultIEW<Impl>::updateExeInstStats(DynInstPtr &inst)
1569{
1570    int thread_number = inst->threadNumber;
1571
1572    //
1573    //  Pick off the software prefetches
1574    //
1575#ifdef TARGET_ALPHA
1576    if (inst->isDataPrefetch())
1577        iewExecutedSwp[thread_number]++;
1578    else
1579        iewExecutedInsts++;
1580#else
1581    iewExecutedInsts[thread_number]++;
1582#endif
1583
1584    //
1585    //  Control operations
1586    //
1587    if (inst->isControl())
1588        iewExecutedBranches[thread_number]++;
1589
1590    //
1591    //  Memory operations
1592    //
1593    if (inst->isMemRef()) {
1594        iewExecutedRefs[thread_number]++;
1595
1596        if (inst->isLoad()) {
1597            iewExecLoadInsts[thread_number]++;
1598        }
1599    }
1600}
1601