iew_impl.hh revision 9427
17639Sgblack@eecs.umich.edu/*
27639Sgblack@eecs.umich.edu * Copyright (c) 2010-2011 ARM Limited
310829Sandreas.hansson@arm.com * All rights reserved.
47639Sgblack@eecs.umich.edu *
57639Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall
67639Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual
77639Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating
87639Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software
97639Sgblack@eecs.umich.edu * licensed hereunder.  You may use the software subject to the license
107639Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated
117639Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software,
127639Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form.
137639Sgblack@eecs.umich.edu *
147639Sgblack@eecs.umich.edu * Copyright (c) 2004-2006 The Regents of The University of Michigan
157639Sgblack@eecs.umich.edu * All rights reserved.
167639Sgblack@eecs.umich.edu *
177639Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
187639Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
197639Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
207639Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
217639Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
227639Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
237639Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
247639Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
257639Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
267639Sgblack@eecs.umich.edu * this software without specific prior written permission.
277639Sgblack@eecs.umich.edu *
287639Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
297639Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
307639Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
317639Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
327639Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
337639Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
347639Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
357639Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
367639Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
377639Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
387639Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
397639Sgblack@eecs.umich.edu *
407639Sgblack@eecs.umich.edu * Authors: Kevin Lim
417639Sgblack@eecs.umich.edu */
427639Sgblack@eecs.umich.edu
437639Sgblack@eecs.umich.edu// @todo: Fix the instantaneous communication among all the stages within
447639Sgblack@eecs.umich.edu// iew.  There's a clear delay between issue and execute, yet backwards
457639Sgblack@eecs.umich.edu// communication happens simultaneously.
467639Sgblack@eecs.umich.edu
477639Sgblack@eecs.umich.edu#include <queue>
487639Sgblack@eecs.umich.edu
497639Sgblack@eecs.umich.edu#include "arch/utility.hh"
507639Sgblack@eecs.umich.edu#include "config/the_isa.hh"
517639Sgblack@eecs.umich.edu#include "cpu/checker/cpu.hh"
527639Sgblack@eecs.umich.edu#include "cpu/o3/fu_pool.hh"
537639Sgblack@eecs.umich.edu#include "cpu/o3/iew.hh"
547639Sgblack@eecs.umich.edu#include "cpu/timebuf.hh"
557639Sgblack@eecs.umich.edu#include "debug/Activity.hh"
567639Sgblack@eecs.umich.edu#include "debug/Decode.hh"
577639Sgblack@eecs.umich.edu#include "debug/IEW.hh"
587639Sgblack@eecs.umich.edu#include "params/DerivO3CPU.hh"
597639Sgblack@eecs.umich.edu
607639Sgblack@eecs.umich.eduusing namespace std;
617639Sgblack@eecs.umich.edu
627639Sgblack@eecs.umich.edutemplate<class Impl>
637639Sgblack@eecs.umich.eduDefaultIEW<Impl>::DefaultIEW(O3CPU *_cpu, DerivO3CPUParams *params)
647639Sgblack@eecs.umich.edu    : issueToExecQueue(params->backComSize, params->forwardComSize),
657639Sgblack@eecs.umich.edu      cpu(_cpu),
667639Sgblack@eecs.umich.edu      instQueue(_cpu, this, params),
677639Sgblack@eecs.umich.edu      ldstQueue(_cpu, this, params),
687639Sgblack@eecs.umich.edu      fuPool(params->fuPool),
697639Sgblack@eecs.umich.edu      commitToIEWDelay(params->commitToIEWDelay),
707639Sgblack@eecs.umich.edu      renameToIEWDelay(params->renameToIEWDelay),
717639Sgblack@eecs.umich.edu      issueToExecuteDelay(params->issueToExecuteDelay),
727639Sgblack@eecs.umich.edu      dispatchWidth(params->dispatchWidth),
737639Sgblack@eecs.umich.edu      issueWidth(params->issueWidth),
747639Sgblack@eecs.umich.edu      wbOutstanding(0),
757639Sgblack@eecs.umich.edu      wbWidth(params->wbWidth),
767639Sgblack@eecs.umich.edu      numThreads(params->numThreads),
777639Sgblack@eecs.umich.edu      switchedOut(false)
787639Sgblack@eecs.umich.edu{
797639Sgblack@eecs.umich.edu    _status = Active;
807639Sgblack@eecs.umich.edu    exeStatus = Running;
817639Sgblack@eecs.umich.edu    wbStatus = Idle;
827639Sgblack@eecs.umich.edu
837639Sgblack@eecs.umich.edu    // Setup wire to read instructions coming from issue.
847639Sgblack@eecs.umich.edu    fromIssue = issueToExecQueue.getWire(-issueToExecuteDelay);
857639Sgblack@eecs.umich.edu
867639Sgblack@eecs.umich.edu    // Instruction queue needs the queue between issue and execute.
877639Sgblack@eecs.umich.edu    instQueue.setIssueToExecuteQueue(&issueToExecQueue);
887639Sgblack@eecs.umich.edu
897639Sgblack@eecs.umich.edu    for (ThreadID tid = 0; tid < numThreads; tid++) {
907639Sgblack@eecs.umich.edu        dispatchStatus[tid] = Running;
917639Sgblack@eecs.umich.edu        stalls[tid].commit = false;
927639Sgblack@eecs.umich.edu        fetchRedirect[tid] = false;
937639Sgblack@eecs.umich.edu    }
947639Sgblack@eecs.umich.edu
957639Sgblack@eecs.umich.edu    wbMax = wbWidth * params->wbDepth;
967639Sgblack@eecs.umich.edu
9710037SARM gem5 Developers    updateLSQNextCycle = false;
9810037SARM gem5 Developers
997639Sgblack@eecs.umich.edu    ableToIssue = true;
1007639Sgblack@eecs.umich.edu
1017639Sgblack@eecs.umich.edu    skidBufferMax = (3 * (renameToIEWDelay * params->renameWidth)) + issueWidth;
1027639Sgblack@eecs.umich.edu}
1037639Sgblack@eecs.umich.edu
1047639Sgblack@eecs.umich.edutemplate <class Impl>
1057639Sgblack@eecs.umich.edustd::string
1067639Sgblack@eecs.umich.eduDefaultIEW<Impl>::name() const
1077639Sgblack@eecs.umich.edu{
1087639Sgblack@eecs.umich.edu    return cpu->name() + ".iew";
1097639Sgblack@eecs.umich.edu}
1107639Sgblack@eecs.umich.edu
1117639Sgblack@eecs.umich.edutemplate <class Impl>
1127639Sgblack@eecs.umich.eduvoid
1137639Sgblack@eecs.umich.eduDefaultIEW<Impl>::regStats()
1147639Sgblack@eecs.umich.edu{
11510037SARM gem5 Developers    using namespace Stats;
11610037SARM gem5 Developers
1177639Sgblack@eecs.umich.edu    instQueue.regStats();
1187639Sgblack@eecs.umich.edu    ldstQueue.regStats();
1197639Sgblack@eecs.umich.edu
1207639Sgblack@eecs.umich.edu    iewIdleCycles
1217639Sgblack@eecs.umich.edu        .name(name() + ".iewIdleCycles")
1227639Sgblack@eecs.umich.edu        .desc("Number of cycles IEW is idle");
1237639Sgblack@eecs.umich.edu
1247639Sgblack@eecs.umich.edu    iewSquashCycles
1257639Sgblack@eecs.umich.edu        .name(name() + ".iewSquashCycles")
1267639Sgblack@eecs.umich.edu        .desc("Number of cycles IEW is squashing");
1277639Sgblack@eecs.umich.edu
1287639Sgblack@eecs.umich.edu    iewBlockCycles
1297639Sgblack@eecs.umich.edu        .name(name() + ".iewBlockCycles")
1307639Sgblack@eecs.umich.edu        .desc("Number of cycles IEW is blocking");
1317639Sgblack@eecs.umich.edu
13210037SARM gem5 Developers    iewUnblockCycles
13310037SARM gem5 Developers        .name(name() + ".iewUnblockCycles")
13410037SARM gem5 Developers        .desc("Number of cycles IEW is unblocking");
13510037SARM gem5 Developers
13610037SARM gem5 Developers    iewDispatchedInsts
13710037SARM gem5 Developers        .name(name() + ".iewDispatchedInsts")
13810037SARM gem5 Developers        .desc("Number of instructions dispatched to IQ");
13910037SARM gem5 Developers
14010037SARM gem5 Developers    iewDispSquashedInsts
14110037SARM gem5 Developers        .name(name() + ".iewDispSquashedInsts")
14210037SARM gem5 Developers        .desc("Number of squashed instructions skipped by dispatch");
14310037SARM gem5 Developers
14410037SARM gem5 Developers    iewDispLoadInsts
14510037SARM gem5 Developers        .name(name() + ".iewDispLoadInsts")
14610037SARM gem5 Developers        .desc("Number of dispatched load instructions");
14710037SARM gem5 Developers
14810037SARM gem5 Developers    iewDispStoreInsts
14910037SARM gem5 Developers        .name(name() + ".iewDispStoreInsts")
15010037SARM gem5 Developers        .desc("Number of dispatched store instructions");
15110037SARM gem5 Developers
15210037SARM gem5 Developers    iewDispNonSpecInsts
15310037SARM gem5 Developers        .name(name() + ".iewDispNonSpecInsts")
15410037SARM gem5 Developers        .desc("Number of dispatched non-speculative instructions");
15510037SARM gem5 Developers
15610037SARM gem5 Developers    iewIQFullEvents
15710037SARM gem5 Developers        .name(name() + ".iewIQFullEvents")
15810037SARM gem5 Developers        .desc("Number of times the IQ has become full, causing a stall");
15910037SARM gem5 Developers
16010037SARM gem5 Developers    iewLSQFullEvents
16110037SARM gem5 Developers        .name(name() + ".iewLSQFullEvents")
16210037SARM gem5 Developers        .desc("Number of times the LSQ has become full, causing a stall");
16310037SARM gem5 Developers
1647639Sgblack@eecs.umich.edu    memOrderViolationEvents
1657639Sgblack@eecs.umich.edu        .name(name() + ".memOrderViolationEvents")
1667639Sgblack@eecs.umich.edu        .desc("Number of memory order violations");
1677639Sgblack@eecs.umich.edu
1687639Sgblack@eecs.umich.edu    predictedTakenIncorrect
1697639Sgblack@eecs.umich.edu        .name(name() + ".predictedTakenIncorrect")
1707639Sgblack@eecs.umich.edu        .desc("Number of branches that were predicted taken incorrectly");
1717639Sgblack@eecs.umich.edu
1727639Sgblack@eecs.umich.edu    predictedNotTakenIncorrect
1737639Sgblack@eecs.umich.edu        .name(name() + ".predictedNotTakenIncorrect")
1747639Sgblack@eecs.umich.edu        .desc("Number of branches that were predicted not taken incorrectly");
1757639Sgblack@eecs.umich.edu
1767639Sgblack@eecs.umich.edu    branchMispredicts
1777639Sgblack@eecs.umich.edu        .name(name() + ".branchMispredicts")
1787639Sgblack@eecs.umich.edu        .desc("Number of branch mispredicts detected at execute");
1797639Sgblack@eecs.umich.edu
1807639Sgblack@eecs.umich.edu    branchMispredicts = predictedTakenIncorrect + predictedNotTakenIncorrect;
1817639Sgblack@eecs.umich.edu
1827639Sgblack@eecs.umich.edu    iewExecutedInsts
1837639Sgblack@eecs.umich.edu        .name(name() + ".iewExecutedInsts")
1847639Sgblack@eecs.umich.edu        .desc("Number of executed instructions");
1857639Sgblack@eecs.umich.edu
1867639Sgblack@eecs.umich.edu    iewExecLoadInsts
1877639Sgblack@eecs.umich.edu        .init(cpu->numThreads)
1887639Sgblack@eecs.umich.edu        .name(name() + ".iewExecLoadInsts")
1897639Sgblack@eecs.umich.edu        .desc("Number of load instructions executed")
1907639Sgblack@eecs.umich.edu        .flags(total);
1917639Sgblack@eecs.umich.edu
1927639Sgblack@eecs.umich.edu    iewExecSquashedInsts
1937639Sgblack@eecs.umich.edu        .name(name() + ".iewExecSquashedInsts")
1947639Sgblack@eecs.umich.edu        .desc("Number of squashed instructions skipped in execute");
1957639Sgblack@eecs.umich.edu
1967639Sgblack@eecs.umich.edu    iewExecutedSwp
1977639Sgblack@eecs.umich.edu        .init(cpu->numThreads)
1987639Sgblack@eecs.umich.edu        .name(name() + ".exec_swp")
1997639Sgblack@eecs.umich.edu        .desc("number of swp insts executed")
2007639Sgblack@eecs.umich.edu        .flags(total);
2017639Sgblack@eecs.umich.edu
2027639Sgblack@eecs.umich.edu    iewExecutedNop
2037639Sgblack@eecs.umich.edu        .init(cpu->numThreads)
2047639Sgblack@eecs.umich.edu        .name(name() + ".exec_nop")
2057639Sgblack@eecs.umich.edu        .desc("number of nop insts executed")
2067639Sgblack@eecs.umich.edu        .flags(total);
2077639Sgblack@eecs.umich.edu
2087639Sgblack@eecs.umich.edu    iewExecutedRefs
2097639Sgblack@eecs.umich.edu        .init(cpu->numThreads)
2107639Sgblack@eecs.umich.edu        .name(name() + ".exec_refs")
2117639Sgblack@eecs.umich.edu        .desc("number of memory reference insts executed")
21210037SARM gem5 Developers        .flags(total);
21310037SARM gem5 Developers
21410037SARM gem5 Developers    iewExecutedBranches
21510037SARM gem5 Developers        .init(cpu->numThreads)
21610037SARM gem5 Developers        .name(name() + ".exec_branches")
21710037SARM gem5 Developers        .desc("Number of branches executed")
21810037SARM gem5 Developers        .flags(total);
21910037SARM gem5 Developers
22010037SARM gem5 Developers    iewExecStoreInsts
22110037SARM gem5 Developers        .name(name() + ".exec_stores")
22210037SARM gem5 Developers        .desc("Number of stores executed")
22310037SARM gem5 Developers        .flags(total);
22410037SARM gem5 Developers    iewExecStoreInsts = iewExecutedRefs - iewExecLoadInsts;
22510037SARM gem5 Developers
22610037SARM gem5 Developers    iewExecRate
22710037SARM gem5 Developers        .name(name() + ".exec_rate")
22810037SARM gem5 Developers        .desc("Inst execution rate")
22910037SARM gem5 Developers        .flags(total);
23010037SARM gem5 Developers
23110037SARM gem5 Developers    iewExecRate = iewExecutedInsts / cpu->numCycles;
23210037SARM gem5 Developers
23310037SARM gem5 Developers    iewInstsToCommit
23410037SARM gem5 Developers        .init(cpu->numThreads)
23510037SARM gem5 Developers        .name(name() + ".wb_sent")
23610037SARM gem5 Developers        .desc("cumulative count of insts sent to commit")
23710037SARM gem5 Developers        .flags(total);
23810037SARM gem5 Developers
23910037SARM gem5 Developers    writebackCount
24010037SARM gem5 Developers        .init(cpu->numThreads)
24110037SARM gem5 Developers        .name(name() + ".wb_count")
24210037SARM gem5 Developers        .desc("cumulative count of insts written-back")
24310037SARM gem5 Developers        .flags(total);
2447639Sgblack@eecs.umich.edu
2457639Sgblack@eecs.umich.edu    producerInst
2467639Sgblack@eecs.umich.edu        .init(cpu->numThreads)
2477639Sgblack@eecs.umich.edu        .name(name() + ".wb_producers")
2487639Sgblack@eecs.umich.edu        .desc("num instructions producing a value")
2497639Sgblack@eecs.umich.edu        .flags(total);
2507639Sgblack@eecs.umich.edu
2517639Sgblack@eecs.umich.edu    consumerInst
2527639Sgblack@eecs.umich.edu        .init(cpu->numThreads)
2537639Sgblack@eecs.umich.edu        .name(name() + ".wb_consumers")
2547639Sgblack@eecs.umich.edu        .desc("num instructions consuming a value")
2557639Sgblack@eecs.umich.edu        .flags(total);
2567639Sgblack@eecs.umich.edu
2577639Sgblack@eecs.umich.edu    wbPenalized
2587639Sgblack@eecs.umich.edu        .init(cpu->numThreads)
2597639Sgblack@eecs.umich.edu        .name(name() + ".wb_penalized")
2607639Sgblack@eecs.umich.edu        .desc("number of instrctions required to write to 'other' IQ")
2617639Sgblack@eecs.umich.edu        .flags(total);
2627639Sgblack@eecs.umich.edu
2637639Sgblack@eecs.umich.edu    wbPenalizedRate
2647639Sgblack@eecs.umich.edu        .name(name() + ".wb_penalized_rate")
2657639Sgblack@eecs.umich.edu        .desc ("fraction of instructions written-back that wrote to 'other' IQ")
2667639Sgblack@eecs.umich.edu        .flags(total);
2677639Sgblack@eecs.umich.edu
2687639Sgblack@eecs.umich.edu    wbPenalizedRate = wbPenalized / writebackCount;
2697639Sgblack@eecs.umich.edu
2707639Sgblack@eecs.umich.edu    wbFanout
2717639Sgblack@eecs.umich.edu        .name(name() + ".wb_fanout")
2727639Sgblack@eecs.umich.edu        .desc("average fanout of values written-back")
2737639Sgblack@eecs.umich.edu        .flags(total);
2747639Sgblack@eecs.umich.edu
2757639Sgblack@eecs.umich.edu    wbFanout = producerInst / consumerInst;
2767639Sgblack@eecs.umich.edu
2777639Sgblack@eecs.umich.edu    wbRate
2787639Sgblack@eecs.umich.edu        .name(name() + ".wb_rate")
2797639Sgblack@eecs.umich.edu        .desc("insts written-back per cycle")
2807639Sgblack@eecs.umich.edu        .flags(total);
2817639Sgblack@eecs.umich.edu    wbRate = writebackCount / cpu->numCycles;
2827639Sgblack@eecs.umich.edu}
2837639Sgblack@eecs.umich.edu
2847639Sgblack@eecs.umich.edutemplate<class Impl>
2857639Sgblack@eecs.umich.eduvoid
2867639Sgblack@eecs.umich.eduDefaultIEW<Impl>::startupStage()
2877639Sgblack@eecs.umich.edu{
2887639Sgblack@eecs.umich.edu    for (ThreadID tid = 0; tid < numThreads; tid++) {
2897639Sgblack@eecs.umich.edu        toRename->iewInfo[tid].usedIQ = true;
2907639Sgblack@eecs.umich.edu        toRename->iewInfo[tid].freeIQEntries =
2917639Sgblack@eecs.umich.edu            instQueue.numFreeEntries(tid);
2927639Sgblack@eecs.umich.edu
2937639Sgblack@eecs.umich.edu        toRename->iewInfo[tid].usedLSQ = true;
2947639Sgblack@eecs.umich.edu        toRename->iewInfo[tid].freeLSQEntries =
2957639Sgblack@eecs.umich.edu            ldstQueue.numFreeEntries(tid);
2967639Sgblack@eecs.umich.edu    }
2977639Sgblack@eecs.umich.edu
2987639Sgblack@eecs.umich.edu    // Initialize the checker's dcache port here
2997639Sgblack@eecs.umich.edu    if (cpu->checker) {
3007639Sgblack@eecs.umich.edu        cpu->checker->setDcachePort(&cpu->getDataPort());
3017639Sgblack@eecs.umich.edu    }
3027639Sgblack@eecs.umich.edu
3037639Sgblack@eecs.umich.edu    cpu->activateStage(O3CPU::IEWIdx);
3047639Sgblack@eecs.umich.edu}
3057639Sgblack@eecs.umich.edu
3067639Sgblack@eecs.umich.edutemplate<class Impl>
3077639Sgblack@eecs.umich.eduvoid
30810037SARM gem5 DevelopersDefaultIEW<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
30910037SARM gem5 Developers{
31010037SARM gem5 Developers    timeBuffer = tb_ptr;
31110037SARM gem5 Developers
31210037SARM gem5 Developers    // Setup wire to read information from time buffer, from commit.
31310037SARM gem5 Developers    fromCommit = timeBuffer->getWire(-commitToIEWDelay);
31410037SARM gem5 Developers
31510037SARM gem5 Developers    // Setup wire to write information back to previous stages.
31610037SARM gem5 Developers    toRename = timeBuffer->getWire(0);
31710037SARM gem5 Developers
31810037SARM gem5 Developers    toFetch = timeBuffer->getWire(0);
31910037SARM gem5 Developers
32010037SARM gem5 Developers    // Instruction queue also needs main time buffer.
32110037SARM gem5 Developers    instQueue.setTimeBuffer(tb_ptr);
32210037SARM gem5 Developers}
32310037SARM gem5 Developers
32410037SARM gem5 Developerstemplate<class Impl>
32510037SARM gem5 Developersvoid
32610037SARM gem5 DevelopersDefaultIEW<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr)
32710037SARM gem5 Developers{
32810037SARM gem5 Developers    renameQueue = rq_ptr;
32910037SARM gem5 Developers
33010037SARM gem5 Developers    // Setup wire to read information from rename queue.
33110037SARM gem5 Developers    fromRename = renameQueue->getWire(-renameToIEWDelay);
33210037SARM gem5 Developers}
33310037SARM gem5 Developers
33410037SARM gem5 Developerstemplate<class Impl>
33510037SARM gem5 Developersvoid
33610037SARM gem5 DevelopersDefaultIEW<Impl>::setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr)
33710037SARM gem5 Developers{
33810037SARM gem5 Developers    iewQueue = iq_ptr;
33910037SARM gem5 Developers
34010037SARM gem5 Developers    // Setup wire to write instructions to commit.
34110037SARM gem5 Developers    toCommit = iewQueue->getWire(0);
34210037SARM gem5 Developers}
34310037SARM gem5 Developers
34410037SARM gem5 Developerstemplate<class Impl>
34510037SARM gem5 Developersvoid
34610037SARM gem5 DevelopersDefaultIEW<Impl>::setActiveThreads(list<ThreadID> *at_ptr)
34710037SARM gem5 Developers{
34810037SARM gem5 Developers    activeThreads = at_ptr;
34910037SARM gem5 Developers
35010037SARM gem5 Developers    ldstQueue.setActiveThreads(at_ptr);
35110037SARM gem5 Developers    instQueue.setActiveThreads(at_ptr);
35210037SARM gem5 Developers}
35310037SARM gem5 Developers
35410037SARM gem5 Developerstemplate<class Impl>
35510037SARM gem5 Developersvoid
35610037SARM gem5 DevelopersDefaultIEW<Impl>::setScoreboard(Scoreboard *sb_ptr)
35710037SARM gem5 Developers{
35810037SARM gem5 Developers    scoreboard = sb_ptr;
35910037SARM gem5 Developers}
36010037SARM gem5 Developers
36110037SARM gem5 Developerstemplate <class Impl>
36210037SARM gem5 Developersbool
36310037SARM gem5 DevelopersDefaultIEW<Impl>::drain()
36410037SARM gem5 Developers{
36510037SARM gem5 Developers    // IEW is ready to drain at any time.
36610037SARM gem5 Developers    cpu->signalDrained();
36710037SARM gem5 Developers    return true;
36810037SARM gem5 Developers}
36910037SARM gem5 Developers
37010037SARM gem5 Developerstemplate <class Impl>
37110037SARM gem5 Developersvoid
37210037SARM gem5 DevelopersDefaultIEW<Impl>::resume()
37310037SARM gem5 Developers{
37410037SARM gem5 Developers}
37510037SARM gem5 Developers
37610037SARM gem5 Developerstemplate <class Impl>
37710037SARM gem5 Developersvoid
37810037SARM gem5 DevelopersDefaultIEW<Impl>::switchOut()
37910037SARM gem5 Developers{
38010037SARM gem5 Developers    // Clear any state.
38110037SARM gem5 Developers    switchedOut = true;
38210037SARM gem5 Developers    assert(insts[0].empty());
38310037SARM gem5 Developers    assert(skidBuffer[0].empty());
38410037SARM gem5 Developers
38510037SARM gem5 Developers    instQueue.switchOut();
38610037SARM gem5 Developers    ldstQueue.switchOut();
38710037SARM gem5 Developers    fuPool->switchOut();
38810037SARM gem5 Developers
38910037SARM gem5 Developers    for (ThreadID tid = 0; tid < numThreads; tid++) {
39010037SARM gem5 Developers        while (!insts[tid].empty())
39110037SARM gem5 Developers            insts[tid].pop();
39210037SARM gem5 Developers        while (!skidBuffer[tid].empty())
39310037SARM gem5 Developers            skidBuffer[tid].pop();
39410037SARM gem5 Developers    }
39510037SARM gem5 Developers}
39610037SARM gem5 Developers
39710037SARM gem5 Developerstemplate <class Impl>
39810037SARM gem5 Developersvoid
39910037SARM gem5 DevelopersDefaultIEW<Impl>::takeOverFrom()
40010037SARM gem5 Developers{
40110037SARM gem5 Developers    // Reset all state.
40210037SARM gem5 Developers    _status = Active;
40310037SARM gem5 Developers    exeStatus = Running;
40410037SARM gem5 Developers    wbStatus = Idle;
40510037SARM gem5 Developers    switchedOut = false;
40610037SARM gem5 Developers
40710037SARM gem5 Developers    instQueue.takeOverFrom();
40810037SARM gem5 Developers    ldstQueue.takeOverFrom();
40910037SARM gem5 Developers    fuPool->takeOver();
41010037SARM gem5 Developers
41110037SARM gem5 Developers    startupStage();
41210037SARM gem5 Developers    cpu->activityThisCycle();
41310037SARM gem5 Developers
41410037SARM gem5 Developers    for (ThreadID tid = 0; tid < numThreads; tid++) {
41510037SARM gem5 Developers        dispatchStatus[tid] = Running;
41610037SARM gem5 Developers        stalls[tid].commit = false;
41710037SARM gem5 Developers        fetchRedirect[tid] = false;
41810037SARM gem5 Developers    }
41910037SARM gem5 Developers
42010037SARM gem5 Developers    updateLSQNextCycle = false;
42110037SARM gem5 Developers
42210037SARM gem5 Developers    for (int i = 0; i < issueToExecQueue.getSize(); ++i) {
42310037SARM gem5 Developers        issueToExecQueue.advance();
42410037SARM gem5 Developers    }
42510037SARM gem5 Developers}
4267639Sgblack@eecs.umich.edu
4277639Sgblack@eecs.umich.edutemplate<class Impl>
4287639Sgblack@eecs.umich.eduvoid
4297639Sgblack@eecs.umich.eduDefaultIEW<Impl>::squash(ThreadID tid)
4307639Sgblack@eecs.umich.edu{
4317639Sgblack@eecs.umich.edu    DPRINTF(IEW, "[tid:%i]: Squashing all instructions.\n", tid);
4327639Sgblack@eecs.umich.edu
4337639Sgblack@eecs.umich.edu    // Tell the IQ to start squashing.
4347639Sgblack@eecs.umich.edu    instQueue.squash(tid);
4357639Sgblack@eecs.umich.edu
4367639Sgblack@eecs.umich.edu    // Tell the LDSTQ to start squashing.
4377639Sgblack@eecs.umich.edu    ldstQueue.squash(fromCommit->commitInfo[tid].doneSeqNum, tid);
4387639Sgblack@eecs.umich.edu    updatedQueues = true;
4397639Sgblack@eecs.umich.edu
4407639Sgblack@eecs.umich.edu    // Clear the skid buffer in case it has any data in it.
4417639Sgblack@eecs.umich.edu    DPRINTF(IEW, "[tid:%i]: Removing skidbuffer instructions until [sn:%i].\n",
4427639Sgblack@eecs.umich.edu            tid, fromCommit->commitInfo[tid].doneSeqNum);
4437639Sgblack@eecs.umich.edu
4447639Sgblack@eecs.umich.edu    while (!skidBuffer[tid].empty()) {
4457639Sgblack@eecs.umich.edu        if (skidBuffer[tid].front()->isLoad() ||
4467639Sgblack@eecs.umich.edu            skidBuffer[tid].front()->isStore() ) {
4477639Sgblack@eecs.umich.edu            toRename->iewInfo[tid].dispatchedToLSQ++;
4487639Sgblack@eecs.umich.edu        }
4497639Sgblack@eecs.umich.edu
4507639Sgblack@eecs.umich.edu        toRename->iewInfo[tid].dispatched++;
4517639Sgblack@eecs.umich.edu
4527639Sgblack@eecs.umich.edu        skidBuffer[tid].pop();
4537639Sgblack@eecs.umich.edu    }
4547639Sgblack@eecs.umich.edu
4557639Sgblack@eecs.umich.edu    emptyRenameInsts(tid);
4567639Sgblack@eecs.umich.edu}
4577639Sgblack@eecs.umich.edu
4587639Sgblack@eecs.umich.edutemplate<class Impl>
4597639Sgblack@eecs.umich.eduvoid
4607639Sgblack@eecs.umich.eduDefaultIEW<Impl>::squashDueToBranch(DynInstPtr &inst, ThreadID tid)
4617639Sgblack@eecs.umich.edu{
4627639Sgblack@eecs.umich.edu    DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, PC: %s "
4637639Sgblack@eecs.umich.edu            "[sn:%i].\n", tid, inst->pcState(), inst->seqNum);
4647639Sgblack@eecs.umich.edu
4657639Sgblack@eecs.umich.edu    if (toCommit->squash[tid] == false ||
4667639Sgblack@eecs.umich.edu            inst->seqNum < toCommit->squashedSeqNum[tid]) {
4677639Sgblack@eecs.umich.edu        toCommit->squash[tid] = true;
4687639Sgblack@eecs.umich.edu        toCommit->squashedSeqNum[tid] = inst->seqNum;
4697639Sgblack@eecs.umich.edu        toCommit->branchTaken[tid] = inst->pcState().branching();
4707639Sgblack@eecs.umich.edu
4717639Sgblack@eecs.umich.edu        TheISA::PCState pc = inst->pcState();
4727639Sgblack@eecs.umich.edu        TheISA::advancePC(pc, inst->staticInst);
4737639Sgblack@eecs.umich.edu
4747639Sgblack@eecs.umich.edu        toCommit->pc[tid] = pc;
4757639Sgblack@eecs.umich.edu        toCommit->mispredictInst[tid] = inst;
4767639Sgblack@eecs.umich.edu        toCommit->includeSquashInst[tid] = false;
4777639Sgblack@eecs.umich.edu
4787639Sgblack@eecs.umich.edu        wroteToTimeBuffer = true;
4797639Sgblack@eecs.umich.edu    }
4807639Sgblack@eecs.umich.edu
4817639Sgblack@eecs.umich.edu}
4827639Sgblack@eecs.umich.edu
4837639Sgblack@eecs.umich.edutemplate<class Impl>
4847639Sgblack@eecs.umich.eduvoid
4857639Sgblack@eecs.umich.eduDefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, ThreadID tid)
4867639Sgblack@eecs.umich.edu{
4877639Sgblack@eecs.umich.edu    DPRINTF(IEW, "[tid:%i]: Memory violation, squashing violator and younger "
4887639Sgblack@eecs.umich.edu            "insts, PC: %s [sn:%i].\n", tid, inst->pcState(), inst->seqNum);
4897639Sgblack@eecs.umich.edu    // Need to include inst->seqNum in the following comparison to cover the
4907639Sgblack@eecs.umich.edu    // corner case when a branch misprediction and a memory violation for the
4917639Sgblack@eecs.umich.edu    // same instruction (e.g. load PC) are detected in the same cycle.  In this
4927639Sgblack@eecs.umich.edu    // case the memory violator should take precedence over the branch
4937639Sgblack@eecs.umich.edu    // misprediction because it requires the violator itself to be included in
4947639Sgblack@eecs.umich.edu    // the squash.
4957639Sgblack@eecs.umich.edu    if (toCommit->squash[tid] == false ||
4967639Sgblack@eecs.umich.edu            inst->seqNum <= toCommit->squashedSeqNum[tid]) {
4977639Sgblack@eecs.umich.edu        toCommit->squash[tid] = true;
4987639Sgblack@eecs.umich.edu
4997639Sgblack@eecs.umich.edu        toCommit->squashedSeqNum[tid] = inst->seqNum;
5007639Sgblack@eecs.umich.edu        toCommit->pc[tid] = inst->pcState();
5017639Sgblack@eecs.umich.edu        toCommit->mispredictInst[tid] = NULL;
5027639Sgblack@eecs.umich.edu
5037639Sgblack@eecs.umich.edu        // Must include the memory violator in the squash.
5047639Sgblack@eecs.umich.edu        toCommit->includeSquashInst[tid] = true;
5057639Sgblack@eecs.umich.edu
5067639Sgblack@eecs.umich.edu        wroteToTimeBuffer = true;
5077639Sgblack@eecs.umich.edu    }
5087639Sgblack@eecs.umich.edu}
5097639Sgblack@eecs.umich.edu
5107639Sgblack@eecs.umich.edutemplate<class Impl>
5117639Sgblack@eecs.umich.eduvoid
5127639Sgblack@eecs.umich.eduDefaultIEW<Impl>::squashDueToMemBlocked(DynInstPtr &inst, ThreadID tid)
5137639Sgblack@eecs.umich.edu{
5147639Sgblack@eecs.umich.edu    DPRINTF(IEW, "[tid:%i]: Memory blocked, squashing load and younger insts, "
5157639Sgblack@eecs.umich.edu            "PC: %s [sn:%i].\n", tid, inst->pcState(), inst->seqNum);
5167639Sgblack@eecs.umich.edu    if (toCommit->squash[tid] == false ||
5177639Sgblack@eecs.umich.edu            inst->seqNum < toCommit->squashedSeqNum[tid]) {
5187639Sgblack@eecs.umich.edu        toCommit->squash[tid] = true;
5197639Sgblack@eecs.umich.edu
5207639Sgblack@eecs.umich.edu        toCommit->squashedSeqNum[tid] = inst->seqNum;
5217639Sgblack@eecs.umich.edu        toCommit->pc[tid] = inst->pcState();
5227639Sgblack@eecs.umich.edu        toCommit->mispredictInst[tid] = NULL;
5237639Sgblack@eecs.umich.edu
5247639Sgblack@eecs.umich.edu        // Must include the broadcasted SN in the squash.
5257639Sgblack@eecs.umich.edu        toCommit->includeSquashInst[tid] = true;
5267639Sgblack@eecs.umich.edu
5277639Sgblack@eecs.umich.edu        ldstQueue.setLoadBlockedHandled(tid);
5287639Sgblack@eecs.umich.edu
5297639Sgblack@eecs.umich.edu        wroteToTimeBuffer = true;
53010037SARM gem5 Developers    }
53110037SARM gem5 Developers}
53210037SARM gem5 Developers
53310037SARM gem5 Developerstemplate<class Impl>
53410037SARM gem5 Developersvoid
53510037SARM gem5 DevelopersDefaultIEW<Impl>::block(ThreadID tid)
53610037SARM gem5 Developers{
53710037SARM gem5 Developers    DPRINTF(IEW, "[tid:%u]: Blocking.\n", tid);
53810037SARM gem5 Developers
53910037SARM gem5 Developers    if (dispatchStatus[tid] != Blocked &&
54010037SARM gem5 Developers        dispatchStatus[tid] != Unblocking) {
54110037SARM gem5 Developers        toRename->iewBlock[tid] = true;
54210037SARM gem5 Developers        wroteToTimeBuffer = true;
54310037SARM gem5 Developers    }
54410037SARM gem5 Developers
54510037SARM gem5 Developers    // Add the current inputs to the skid buffer so they can be
54610037SARM gem5 Developers    // reprocessed when this stage unblocks.
54710037SARM gem5 Developers    skidInsert(tid);
54810037SARM gem5 Developers
54910037SARM gem5 Developers    dispatchStatus[tid] = Blocked;
55010037SARM gem5 Developers}
55110037SARM gem5 Developers
55210037SARM gem5 Developerstemplate<class Impl>
55310037SARM gem5 Developersvoid
55410037SARM gem5 DevelopersDefaultIEW<Impl>::unblock(ThreadID tid)
55510037SARM gem5 Developers{
55610037SARM gem5 Developers    DPRINTF(IEW, "[tid:%i]: Reading instructions out of the skid "
55710037SARM gem5 Developers            "buffer %u.\n",tid, tid);
55810037SARM gem5 Developers
55910037SARM gem5 Developers    // If the skid bufffer is empty, signal back to previous stages to unblock.
56010037SARM gem5 Developers    // Also switch status to running.
56110037SARM gem5 Developers    if (skidBuffer[tid].empty()) {
56210037SARM gem5 Developers        toRename->iewUnblock[tid] = true;
56310037SARM gem5 Developers        wroteToTimeBuffer = true;
56410037SARM gem5 Developers        DPRINTF(IEW, "[tid:%i]: Done unblocking.\n",tid);
56510037SARM gem5 Developers        dispatchStatus[tid] = Running;
56610037SARM gem5 Developers    }
56710037SARM gem5 Developers}
56810037SARM gem5 Developers
56910037SARM gem5 Developerstemplate<class Impl>
5707639Sgblack@eecs.umich.eduvoid
5717639Sgblack@eecs.umich.eduDefaultIEW<Impl>::wakeDependents(DynInstPtr &inst)
5727639Sgblack@eecs.umich.edu{
5737639Sgblack@eecs.umich.edu    instQueue.wakeDependents(inst);
5747639Sgblack@eecs.umich.edu}
5757639Sgblack@eecs.umich.edu
5767639Sgblack@eecs.umich.edutemplate<class Impl>
5777639Sgblack@eecs.umich.eduvoid
5787639Sgblack@eecs.umich.eduDefaultIEW<Impl>::rescheduleMemInst(DynInstPtr &inst)
5797639Sgblack@eecs.umich.edu{
5807639Sgblack@eecs.umich.edu    instQueue.rescheduleMemInst(inst);
5817639Sgblack@eecs.umich.edu}
5827639Sgblack@eecs.umich.edu
5837639Sgblack@eecs.umich.edutemplate<class Impl>
5847639Sgblack@eecs.umich.eduvoid
5857639Sgblack@eecs.umich.eduDefaultIEW<Impl>::replayMemInst(DynInstPtr &inst)
5867639Sgblack@eecs.umich.edu{
5877639Sgblack@eecs.umich.edu    instQueue.replayMemInst(inst);
5887639Sgblack@eecs.umich.edu}
5897639Sgblack@eecs.umich.edu
5907639Sgblack@eecs.umich.edutemplate<class Impl>
5917639Sgblack@eecs.umich.eduvoid
5927639Sgblack@eecs.umich.eduDefaultIEW<Impl>::instToCommit(DynInstPtr &inst)
5937639Sgblack@eecs.umich.edu{
5947639Sgblack@eecs.umich.edu    // This function should not be called after writebackInsts in a
5957639Sgblack@eecs.umich.edu    // single cycle.  That will cause problems with an instruction
5967639Sgblack@eecs.umich.edu    // being added to the queue to commit without being processed by
5977639Sgblack@eecs.umich.edu    // writebackInsts prior to being sent to commit.
5987639Sgblack@eecs.umich.edu
5997639Sgblack@eecs.umich.edu    // First check the time slot that this instruction will write
6007639Sgblack@eecs.umich.edu    // to.  If there are free write ports at the time, then go ahead
6017639Sgblack@eecs.umich.edu    // and write the instruction to that time.  If there are not,
6027639Sgblack@eecs.umich.edu    // keep looking back to see where's the first time there's a
6037639Sgblack@eecs.umich.edu    // free slot.
6047639Sgblack@eecs.umich.edu    while ((*iewQueue)[wbCycle].insts[wbNumInst]) {
6057639Sgblack@eecs.umich.edu        ++wbNumInst;
6067639Sgblack@eecs.umich.edu        if (wbNumInst == wbWidth) {
6077639Sgblack@eecs.umich.edu            ++wbCycle;
6087639Sgblack@eecs.umich.edu            wbNumInst = 0;
6097639Sgblack@eecs.umich.edu        }
6107639Sgblack@eecs.umich.edu
6117639Sgblack@eecs.umich.edu        assert((wbCycle * wbWidth + wbNumInst) <= wbMax);
6127639Sgblack@eecs.umich.edu    }
6137639Sgblack@eecs.umich.edu
6147639Sgblack@eecs.umich.edu    DPRINTF(IEW, "Current wb cycle: %i, width: %i, numInst: %i\nwbActual:%i\n",
6157639Sgblack@eecs.umich.edu            wbCycle, wbWidth, wbNumInst, wbCycle * wbWidth + wbNumInst);
6167639Sgblack@eecs.umich.edu    // Add finished instruction to queue to commit.
6177639Sgblack@eecs.umich.edu    (*iewQueue)[wbCycle].insts[wbNumInst] = inst;
6187639Sgblack@eecs.umich.edu    (*iewQueue)[wbCycle].size++;
6197639Sgblack@eecs.umich.edu}
6207639Sgblack@eecs.umich.edu
6217639Sgblack@eecs.umich.edutemplate <class Impl>
6227639Sgblack@eecs.umich.eduunsigned
6237639Sgblack@eecs.umich.eduDefaultIEW<Impl>::validInstsFromRename()
6247639Sgblack@eecs.umich.edu{
6257639Sgblack@eecs.umich.edu    unsigned inst_count = 0;
6267639Sgblack@eecs.umich.edu
6277639Sgblack@eecs.umich.edu    for (int i=0; i<fromRename->size; i++) {
6287639Sgblack@eecs.umich.edu        if (!fromRename->insts[i]->isSquashed())
6297639Sgblack@eecs.umich.edu            inst_count++;
6307639Sgblack@eecs.umich.edu    }
6317639Sgblack@eecs.umich.edu
6327639Sgblack@eecs.umich.edu    return inst_count;
6337639Sgblack@eecs.umich.edu}
6347639Sgblack@eecs.umich.edu
6357639Sgblack@eecs.umich.edutemplate<class Impl>
63610037SARM gem5 Developersvoid
63710037SARM gem5 DevelopersDefaultIEW<Impl>::skidInsert(ThreadID tid)
63810037SARM gem5 Developers{
63910037SARM gem5 Developers    DynInstPtr inst = NULL;
64010037SARM gem5 Developers
64110037SARM gem5 Developers    while (!insts[tid].empty()) {
64210037SARM gem5 Developers        inst = insts[tid].front();
64310037SARM gem5 Developers
64410037SARM gem5 Developers        insts[tid].pop();
64510037SARM gem5 Developers
64610037SARM gem5 Developers        DPRINTF(Decode,"[tid:%i]: Inserting [sn:%lli] PC:%s into "
64710037SARM gem5 Developers                "dispatch skidBuffer %i\n",tid, inst->seqNum,
64810037SARM gem5 Developers                inst->pcState(),tid);
64910037SARM gem5 Developers
65010037SARM gem5 Developers        skidBuffer[tid].push(inst);
65110037SARM gem5 Developers    }
65210037SARM gem5 Developers
65310037SARM gem5 Developers    assert(skidBuffer[tid].size() <= skidBufferMax &&
65410037SARM gem5 Developers           "Skidbuffer Exceeded Max Size");
65510037SARM gem5 Developers}
65610037SARM gem5 Developers
65710037SARM gem5 Developerstemplate<class Impl>
65810037SARM gem5 Developersint
65910037SARM gem5 DevelopersDefaultIEW<Impl>::skidCount()
66010037SARM gem5 Developers{
66110037SARM gem5 Developers    int max=0;
66210037SARM gem5 Developers
66310037SARM gem5 Developers    list<ThreadID>::iterator threads = activeThreads->begin();
66410037SARM gem5 Developers    list<ThreadID>::iterator end = activeThreads->end();
66510037SARM gem5 Developers
66610037SARM gem5 Developers    while (threads != end) {
66710037SARM gem5 Developers        ThreadID tid = *threads++;
66810037SARM gem5 Developers        unsigned thread_count = skidBuffer[tid].size();
66910037SARM gem5 Developers        if (max < thread_count)
67010037SARM gem5 Developers            max = thread_count;
67110037SARM gem5 Developers    }
67210037SARM gem5 Developers
67310037SARM gem5 Developers    return max;
67410037SARM gem5 Developers}
67510037SARM gem5 Developers
67610037SARM gem5 Developerstemplate<class Impl>
67710037SARM gem5 Developersbool
67810037SARM gem5 DevelopersDefaultIEW<Impl>::skidsEmpty()
67910037SARM gem5 Developers{
68010037SARM gem5 Developers    list<ThreadID>::iterator threads = activeThreads->begin();
68110037SARM gem5 Developers    list<ThreadID>::iterator end = activeThreads->end();
68210037SARM gem5 Developers
68310037SARM gem5 Developers    while (threads != end) {
68410037SARM gem5 Developers        ThreadID tid = *threads++;
68510037SARM gem5 Developers
68610037SARM gem5 Developers        if (!skidBuffer[tid].empty())
68710037SARM gem5 Developers            return false;
68810037SARM gem5 Developers    }
68910037SARM gem5 Developers
69010037SARM gem5 Developers    return true;
69110037SARM gem5 Developers}
69210037SARM gem5 Developers
69310037SARM gem5 Developerstemplate <class Impl>
69410037SARM gem5 Developersvoid
69510037SARM gem5 DevelopersDefaultIEW<Impl>::updateStatus()
6967639Sgblack@eecs.umich.edu{
6977639Sgblack@eecs.umich.edu    bool any_unblocking = false;
6987639Sgblack@eecs.umich.edu
6997639Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
7007639Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
7017639Sgblack@eecs.umich.edu
7027639Sgblack@eecs.umich.edu    while (threads != end) {
7037639Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
7047639Sgblack@eecs.umich.edu
7057639Sgblack@eecs.umich.edu        if (dispatchStatus[tid] == Unblocking) {
7067639Sgblack@eecs.umich.edu            any_unblocking = true;
7077639Sgblack@eecs.umich.edu            break;
7087639Sgblack@eecs.umich.edu        }
7097639Sgblack@eecs.umich.edu    }
7107639Sgblack@eecs.umich.edu
7117639Sgblack@eecs.umich.edu    // If there are no ready instructions waiting to be scheduled by the IQ,
7127639Sgblack@eecs.umich.edu    // and there's no stores waiting to write back, and dispatch is not
7137639Sgblack@eecs.umich.edu    // unblocking, then there is no internal activity for the IEW stage.
7147639Sgblack@eecs.umich.edu    instQueue.intInstQueueReads++;
7157639Sgblack@eecs.umich.edu    if (_status == Active && !instQueue.hasReadyInsts() &&
7167639Sgblack@eecs.umich.edu        !ldstQueue.willWB() && !any_unblocking) {
7177639Sgblack@eecs.umich.edu        DPRINTF(IEW, "IEW switching to idle\n");
7187639Sgblack@eecs.umich.edu
7197639Sgblack@eecs.umich.edu        deactivateStage();
7207639Sgblack@eecs.umich.edu
7217639Sgblack@eecs.umich.edu        _status = Inactive;
7227639Sgblack@eecs.umich.edu    } else if (_status == Inactive && (instQueue.hasReadyInsts() ||
7237639Sgblack@eecs.umich.edu                                       ldstQueue.willWB() ||
7247639Sgblack@eecs.umich.edu                                       any_unblocking)) {
7257639Sgblack@eecs.umich.edu        // Otherwise there is internal activity.  Set to active.
7267639Sgblack@eecs.umich.edu        DPRINTF(IEW, "IEW switching to active\n");
7277639Sgblack@eecs.umich.edu
7287639Sgblack@eecs.umich.edu        activateStage();
7297639Sgblack@eecs.umich.edu
7307639Sgblack@eecs.umich.edu        _status = Active;
7317639Sgblack@eecs.umich.edu    }
7327639Sgblack@eecs.umich.edu}
7337639Sgblack@eecs.umich.edu
7347639Sgblack@eecs.umich.edutemplate <class Impl>
7357639Sgblack@eecs.umich.eduvoid
73610037SARM gem5 DevelopersDefaultIEW<Impl>::resetEntries()
73710037SARM gem5 Developers{
7387639Sgblack@eecs.umich.edu    instQueue.resetEntries();
7397639Sgblack@eecs.umich.edu    ldstQueue.resetEntries();
7407639Sgblack@eecs.umich.edu}
7417639Sgblack@eecs.umich.edu
7427639Sgblack@eecs.umich.edutemplate <class Impl>
7437639Sgblack@eecs.umich.eduvoid
7447639Sgblack@eecs.umich.eduDefaultIEW<Impl>::readStallSignals(ThreadID tid)
7457639Sgblack@eecs.umich.edu{
7467639Sgblack@eecs.umich.edu    if (fromCommit->commitBlock[tid]) {
7477639Sgblack@eecs.umich.edu        stalls[tid].commit = true;
7487639Sgblack@eecs.umich.edu    }
7497639Sgblack@eecs.umich.edu
75010037SARM gem5 Developers    if (fromCommit->commitUnblock[tid]) {
75110037SARM gem5 Developers        assert(stalls[tid].commit);
7527639Sgblack@eecs.umich.edu        stalls[tid].commit = false;
7537639Sgblack@eecs.umich.edu    }
7547639Sgblack@eecs.umich.edu}
7557639Sgblack@eecs.umich.edu
7567639Sgblack@eecs.umich.edutemplate <class Impl>
7577639Sgblack@eecs.umich.edubool
7587639Sgblack@eecs.umich.eduDefaultIEW<Impl>::checkStall(ThreadID tid)
7597639Sgblack@eecs.umich.edu{
7607639Sgblack@eecs.umich.edu    bool ret_val(false);
7617639Sgblack@eecs.umich.edu
7627639Sgblack@eecs.umich.edu    if (stalls[tid].commit) {
7637639Sgblack@eecs.umich.edu        DPRINTF(IEW,"[tid:%i]: Stall from Commit stage detected.\n",tid);
7647639Sgblack@eecs.umich.edu        ret_val = true;
7657639Sgblack@eecs.umich.edu    } else if (instQueue.isFull(tid)) {
7667639Sgblack@eecs.umich.edu        DPRINTF(IEW,"[tid:%i]: Stall: IQ  is full.\n",tid);
7677639Sgblack@eecs.umich.edu        ret_val = true;
7687639Sgblack@eecs.umich.edu    } else if (ldstQueue.isFull(tid)) {
7697639Sgblack@eecs.umich.edu        DPRINTF(IEW,"[tid:%i]: Stall: LSQ is full\n",tid);
7707639Sgblack@eecs.umich.edu
7717639Sgblack@eecs.umich.edu        if (ldstQueue.numLoads(tid) > 0 ) {
7727639Sgblack@eecs.umich.edu
7737639Sgblack@eecs.umich.edu            DPRINTF(IEW,"[tid:%i]: LSQ oldest load: [sn:%i] \n",
7747639Sgblack@eecs.umich.edu                    tid,ldstQueue.getLoadHeadSeqNum(tid));
7757639Sgblack@eecs.umich.edu        }
7767639Sgblack@eecs.umich.edu
7777639Sgblack@eecs.umich.edu        if (ldstQueue.numStores(tid) > 0) {
7787639Sgblack@eecs.umich.edu
7797639Sgblack@eecs.umich.edu            DPRINTF(IEW,"[tid:%i]: LSQ oldest store: [sn:%i] \n",
7807639Sgblack@eecs.umich.edu                    tid,ldstQueue.getStoreHeadSeqNum(tid));
7817639Sgblack@eecs.umich.edu        }
7827639Sgblack@eecs.umich.edu
78310037SARM gem5 Developers        ret_val = true;
78410037SARM gem5 Developers    } else if (ldstQueue.isStalled(tid)) {
7857639Sgblack@eecs.umich.edu        DPRINTF(IEW,"[tid:%i]: Stall: LSQ stall detected.\n",tid);
7867639Sgblack@eecs.umich.edu        ret_val = true;
7877639Sgblack@eecs.umich.edu    }
7887639Sgblack@eecs.umich.edu
7897639Sgblack@eecs.umich.edu    return ret_val;
7907639Sgblack@eecs.umich.edu}
7917639Sgblack@eecs.umich.edu
7927639Sgblack@eecs.umich.edutemplate <class Impl>
7937639Sgblack@eecs.umich.eduvoid
7947639Sgblack@eecs.umich.eduDefaultIEW<Impl>::checkSignalsAndUpdate(ThreadID tid)
7957639Sgblack@eecs.umich.edu{
7967639Sgblack@eecs.umich.edu    // Check if there's a squash signal, squash if there is
7977639Sgblack@eecs.umich.edu    // Check stall signals, block if there is.
7987639Sgblack@eecs.umich.edu    // If status was Blocked
7997639Sgblack@eecs.umich.edu    //     if so then go to unblocking
8007639Sgblack@eecs.umich.edu    // If status was Squashing
8017639Sgblack@eecs.umich.edu    //     check if squashing is not high.  Switch to running this cycle.
8027639Sgblack@eecs.umich.edu
8037639Sgblack@eecs.umich.edu    readStallSignals(tid);
8047639Sgblack@eecs.umich.edu
8057639Sgblack@eecs.umich.edu    if (fromCommit->commitInfo[tid].squash) {
8067639Sgblack@eecs.umich.edu        squash(tid);
8077639Sgblack@eecs.umich.edu
8087639Sgblack@eecs.umich.edu        if (dispatchStatus[tid] == Blocked ||
8097639Sgblack@eecs.umich.edu            dispatchStatus[tid] == Unblocking) {
8107639Sgblack@eecs.umich.edu            toRename->iewUnblock[tid] = true;
8117639Sgblack@eecs.umich.edu            wroteToTimeBuffer = true;
8127639Sgblack@eecs.umich.edu        }
8137639Sgblack@eecs.umich.edu
8147639Sgblack@eecs.umich.edu        dispatchStatus[tid] = Squashing;
8157639Sgblack@eecs.umich.edu        fetchRedirect[tid] = false;
8167639Sgblack@eecs.umich.edu        return;
8177639Sgblack@eecs.umich.edu    }
8187639Sgblack@eecs.umich.edu
8197639Sgblack@eecs.umich.edu    if (fromCommit->commitInfo[tid].robSquashing) {
8207639Sgblack@eecs.umich.edu        DPRINTF(IEW, "[tid:%i]: ROB is still squashing.\n", tid);
8217639Sgblack@eecs.umich.edu
8227639Sgblack@eecs.umich.edu        dispatchStatus[tid] = Squashing;
8237639Sgblack@eecs.umich.edu        emptyRenameInsts(tid);
8247639Sgblack@eecs.umich.edu        wroteToTimeBuffer = true;
8257639Sgblack@eecs.umich.edu        return;
8267639Sgblack@eecs.umich.edu    }
8277639Sgblack@eecs.umich.edu
8287639Sgblack@eecs.umich.edu    if (checkStall(tid)) {
8297639Sgblack@eecs.umich.edu        block(tid);
8307639Sgblack@eecs.umich.edu        dispatchStatus[tid] = Blocked;
8317639Sgblack@eecs.umich.edu        return;
8327639Sgblack@eecs.umich.edu    }
8337639Sgblack@eecs.umich.edu
8347639Sgblack@eecs.umich.edu    if (dispatchStatus[tid] == Blocked) {
8357639Sgblack@eecs.umich.edu        // Status from previous cycle was blocked, but there are no more stall
8367639Sgblack@eecs.umich.edu        // conditions.  Switch over to unblocking.
8377639Sgblack@eecs.umich.edu        DPRINTF(IEW, "[tid:%i]: Done blocking, switching to unblocking.\n",
8387639Sgblack@eecs.umich.edu                tid);
8397639Sgblack@eecs.umich.edu
8407639Sgblack@eecs.umich.edu        dispatchStatus[tid] = Unblocking;
8417639Sgblack@eecs.umich.edu
8427639Sgblack@eecs.umich.edu        unblock(tid);
8437639Sgblack@eecs.umich.edu
84410037SARM gem5 Developers        return;
84510037SARM gem5 Developers    }
84610037SARM gem5 Developers
84710037SARM gem5 Developers    if (dispatchStatus[tid] == Squashing) {
84810037SARM gem5 Developers        // Switch status to running if rename isn't being told to block or
84910037SARM gem5 Developers        // squash this cycle.
85010037SARM gem5 Developers        DPRINTF(IEW, "[tid:%i]: Done squashing, switching to running.\n",
85110037SARM gem5 Developers                tid);
85210037SARM gem5 Developers
85310037SARM gem5 Developers        dispatchStatus[tid] = Running;
85410037SARM gem5 Developers
85510037SARM gem5 Developers        return;
85610037SARM gem5 Developers    }
85710037SARM gem5 Developers}
85810037SARM gem5 Developers
85910037SARM gem5 Developerstemplate <class Impl>
86010037SARM gem5 Developersvoid
86110037SARM gem5 DevelopersDefaultIEW<Impl>::sortInsts()
86210037SARM gem5 Developers{
86310037SARM gem5 Developers    int insts_from_rename = fromRename->size;
86410037SARM gem5 Developers#ifdef DEBUG
86510037SARM gem5 Developers    for (ThreadID tid = 0; tid < numThreads; tid++)
86610037SARM gem5 Developers        assert(insts[tid].empty());
86710037SARM gem5 Developers#endif
86810037SARM gem5 Developers    for (int i = 0; i < insts_from_rename; ++i) {
86910037SARM gem5 Developers        insts[fromRename->insts[i]->threadNumber].push(fromRename->insts[i]);
87010037SARM gem5 Developers    }
87110037SARM gem5 Developers}
87210037SARM gem5 Developers
87310037SARM gem5 Developerstemplate <class Impl>
87410037SARM gem5 Developersvoid
87510037SARM gem5 DevelopersDefaultIEW<Impl>::emptyRenameInsts(ThreadID tid)
87610037SARM gem5 Developers{
87710037SARM gem5 Developers    DPRINTF(IEW, "[tid:%i]: Removing incoming rename instructions\n", tid);
87810037SARM gem5 Developers
87910037SARM gem5 Developers    while (!insts[tid].empty()) {
88010037SARM gem5 Developers
88110037SARM gem5 Developers        if (insts[tid].front()->isLoad() ||
88210037SARM gem5 Developers            insts[tid].front()->isStore() ) {
88310037SARM gem5 Developers            toRename->iewInfo[tid].dispatchedToLSQ++;
88410037SARM gem5 Developers        }
88510037SARM gem5 Developers
88610037SARM gem5 Developers        toRename->iewInfo[tid].dispatched++;
88710037SARM gem5 Developers
88810037SARM gem5 Developers        insts[tid].pop();
88910037SARM gem5 Developers    }
89010037SARM gem5 Developers}
89110037SARM gem5 Developers
89210037SARM gem5 Developerstemplate <class Impl>
89310037SARM gem5 Developersvoid
89410037SARM gem5 DevelopersDefaultIEW<Impl>::wakeCPU()
89510037SARM gem5 Developers{
89610037SARM gem5 Developers    cpu->wakeCPU();
89710037SARM gem5 Developers}
89810037SARM gem5 Developers
89910037SARM gem5 Developerstemplate <class Impl>
90010037SARM gem5 Developersvoid
90110037SARM gem5 DevelopersDefaultIEW<Impl>::activityThisCycle()
90210037SARM gem5 Developers{
90310037SARM gem5 Developers    DPRINTF(Activity, "Activity this cycle.\n");
90410037SARM gem5 Developers    cpu->activityThisCycle();
90510037SARM gem5 Developers}
90610037SARM gem5 Developers
90710037SARM gem5 Developerstemplate <class Impl>
90810037SARM gem5 Developersinline void
90910037SARM gem5 DevelopersDefaultIEW<Impl>::activateStage()
91010037SARM gem5 Developers{
91110037SARM gem5 Developers    DPRINTF(Activity, "Activating stage.\n");
91210037SARM gem5 Developers    cpu->activateStage(O3CPU::IEWIdx);
91310037SARM gem5 Developers}
91410037SARM gem5 Developers
91510037SARM gem5 Developerstemplate <class Impl>
91610037SARM gem5 Developersinline void
91710037SARM gem5 DevelopersDefaultIEW<Impl>::deactivateStage()
91810037SARM gem5 Developers{
91910037SARM gem5 Developers    DPRINTF(Activity, "Deactivating stage.\n");
92010037SARM gem5 Developers    cpu->deactivateStage(O3CPU::IEWIdx);
92110037SARM gem5 Developers}
92210037SARM gem5 Developers
92310037SARM gem5 Developerstemplate<class Impl>
92410037SARM gem5 Developersvoid
92510037SARM gem5 DevelopersDefaultIEW<Impl>::dispatch(ThreadID tid)
92610037SARM gem5 Developers{
92710037SARM gem5 Developers    // If status is Running or idle,
92810037SARM gem5 Developers    //     call dispatchInsts()
92910037SARM gem5 Developers    // If status is Unblocking,
93010037SARM gem5 Developers    //     buffer any instructions coming from rename
93110037SARM gem5 Developers    //     continue trying to empty skid buffer
93210037SARM gem5 Developers    //     check if stall conditions have passed
93310037SARM gem5 Developers
93410037SARM gem5 Developers    if (dispatchStatus[tid] == Blocked) {
93510037SARM gem5 Developers        ++iewBlockCycles;
93610037SARM gem5 Developers
93710037SARM gem5 Developers    } else if (dispatchStatus[tid] == Squashing) {
93810037SARM gem5 Developers        ++iewSquashCycles;
93910037SARM gem5 Developers    }
94010037SARM gem5 Developers
94110037SARM gem5 Developers    // Dispatch should try to dispatch as many instructions as its bandwidth
94210037SARM gem5 Developers    // will allow, as long as it is not currently blocked.
94310037SARM gem5 Developers    if (dispatchStatus[tid] == Running ||
94410037SARM gem5 Developers        dispatchStatus[tid] == Idle) {
94510037SARM gem5 Developers        DPRINTF(IEW, "[tid:%i] Not blocked, so attempting to run "
94610037SARM gem5 Developers                "dispatch.\n", tid);
94710037SARM gem5 Developers
94810037SARM gem5 Developers        dispatchInsts(tid);
94910037SARM gem5 Developers    } else if (dispatchStatus[tid] == Unblocking) {
95010037SARM gem5 Developers        // Make sure that the skid buffer has something in it if the
95110037SARM gem5 Developers        // status is unblocking.
95210037SARM gem5 Developers        assert(!skidsEmpty());
95310037SARM gem5 Developers
95410037SARM gem5 Developers        // If the status was unblocking, then instructions from the skid
95510037SARM gem5 Developers        // buffer were used.  Remove those instructions and handle
95610037SARM gem5 Developers        // the rest of unblocking.
95710037SARM gem5 Developers        dispatchInsts(tid);
95810037SARM gem5 Developers
95910037SARM gem5 Developers        ++iewUnblockCycles;
96010037SARM gem5 Developers
96110037SARM gem5 Developers        if (validInstsFromRename()) {
96210037SARM gem5 Developers            // Add the current inputs to the skid buffer so they can be
96310037SARM gem5 Developers            // reprocessed when this stage unblocks.
96410037SARM gem5 Developers            skidInsert(tid);
96510037SARM gem5 Developers        }
96610037SARM gem5 Developers
96710037SARM gem5 Developers        unblock(tid);
96810037SARM gem5 Developers    }
96910037SARM gem5 Developers}
97010037SARM gem5 Developers
97110037SARM gem5 Developerstemplate <class Impl>
97210037SARM gem5 Developersvoid
97310037SARM gem5 DevelopersDefaultIEW<Impl>::dispatchInsts(ThreadID tid)
97410037SARM gem5 Developers{
97510037SARM gem5 Developers    // Obtain instructions from skid buffer if unblocking, or queue from rename
97610037SARM gem5 Developers    // otherwise.
97710037SARM gem5 Developers    std::queue<DynInstPtr> &insts_to_dispatch =
97810037SARM gem5 Developers        dispatchStatus[tid] == Unblocking ?
97910037SARM gem5 Developers        skidBuffer[tid] : insts[tid];
98010037SARM gem5 Developers
98110037SARM gem5 Developers    int insts_to_add = insts_to_dispatch.size();
98210037SARM gem5 Developers
98310037SARM gem5 Developers    DynInstPtr inst;
98410037SARM gem5 Developers    bool add_to_iq = false;
98510037SARM gem5 Developers    int dis_num_inst = 0;
98610037SARM gem5 Developers
98710037SARM gem5 Developers    // Loop through the instructions, putting them in the instruction
98810037SARM gem5 Developers    // queue.
98910037SARM gem5 Developers    for ( ; dis_num_inst < insts_to_add &&
99010037SARM gem5 Developers              dis_num_inst < dispatchWidth;
99110037SARM gem5 Developers          ++dis_num_inst)
99210037SARM gem5 Developers    {
99310037SARM gem5 Developers        inst = insts_to_dispatch.front();
99410037SARM gem5 Developers
99510037SARM gem5 Developers        if (dispatchStatus[tid] == Unblocking) {
99610037SARM gem5 Developers            DPRINTF(IEW, "[tid:%i]: Issue: Examining instruction from skid "
99710037SARM gem5 Developers                    "buffer\n", tid);
99810037SARM gem5 Developers        }
99910037SARM gem5 Developers
100010037SARM gem5 Developers        // Make sure there's a valid instruction there.
100110037SARM gem5 Developers        assert(inst);
100210037SARM gem5 Developers
100310037SARM gem5 Developers        DPRINTF(IEW, "[tid:%i]: Issue: Adding PC %s [sn:%lli] [tid:%i] to "
100410037SARM gem5 Developers                "IQ.\n",
100510037SARM gem5 Developers                tid, inst->pcState(), inst->seqNum, inst->threadNumber);
100610037SARM gem5 Developers
100710037SARM gem5 Developers        // Be sure to mark these instructions as ready so that the
100810037SARM gem5 Developers        // commit stage can go ahead and execute them, and mark
100910037SARM gem5 Developers        // them as issued so the IQ doesn't reprocess them.
101010037SARM gem5 Developers
101110037SARM gem5 Developers        // Check for squashed instructions.
101210037SARM gem5 Developers        if (inst->isSquashed()) {
101310037SARM gem5 Developers            DPRINTF(IEW, "[tid:%i]: Issue: Squashed instruction encountered, "
101410037SARM gem5 Developers                    "not adding to IQ.\n", tid);
101510037SARM gem5 Developers
101610037SARM gem5 Developers            ++iewDispSquashedInsts;
101710037SARM gem5 Developers
101810037SARM gem5 Developers            insts_to_dispatch.pop();
101910037SARM gem5 Developers
102010037SARM gem5 Developers            //Tell Rename That An Instruction has been processed
102110037SARM gem5 Developers            if (inst->isLoad() || inst->isStore()) {
102210037SARM gem5 Developers                toRename->iewInfo[tid].dispatchedToLSQ++;
102310037SARM gem5 Developers            }
102410037SARM gem5 Developers            toRename->iewInfo[tid].dispatched++;
102510037SARM gem5 Developers
102610037SARM gem5 Developers            continue;
102710037SARM gem5 Developers        }
102810037SARM gem5 Developers
102910037SARM gem5 Developers        // Check for full conditions.
103010037SARM gem5 Developers        if (instQueue.isFull(tid)) {
103110037SARM gem5 Developers            DPRINTF(IEW, "[tid:%i]: Issue: IQ has become full.\n", tid);
103210037SARM gem5 Developers
103310037SARM gem5 Developers            // Call function to start blocking.
103410037SARM gem5 Developers            block(tid);
103510037SARM gem5 Developers
103610037SARM gem5 Developers            // Set unblock to false. Special case where we are using
103710037SARM gem5 Developers            // skidbuffer (unblocking) instructions but then we still
103810037SARM gem5 Developers            // get full in the IQ.
103910037SARM gem5 Developers            toRename->iewUnblock[tid] = false;
104010037SARM gem5 Developers
104110037SARM gem5 Developers            ++iewIQFullEvents;
104210037SARM gem5 Developers            break;
104310037SARM gem5 Developers        } else if (ldstQueue.isFull(tid)) {
104410037SARM gem5 Developers            DPRINTF(IEW, "[tid:%i]: Issue: LSQ has become full.\n",tid);
104510037SARM gem5 Developers
104610037SARM gem5 Developers            // Call function to start blocking.
104710037SARM gem5 Developers            block(tid);
104810037SARM gem5 Developers
104910037SARM gem5 Developers            // Set unblock to false. Special case where we are using
105010037SARM gem5 Developers            // skidbuffer (unblocking) instructions but then we still
105110037SARM gem5 Developers            // get full in the IQ.
105210037SARM gem5 Developers            toRename->iewUnblock[tid] = false;
105310037SARM gem5 Developers
105410037SARM gem5 Developers            ++iewLSQFullEvents;
105510037SARM gem5 Developers            break;
105610037SARM gem5 Developers        }
105710037SARM gem5 Developers
105810037SARM gem5 Developers        // Otherwise issue the instruction just fine.
10597639Sgblack@eecs.umich.edu        if (inst->isLoad()) {
10607639Sgblack@eecs.umich.edu            DPRINTF(IEW, "[tid:%i]: Issue: Memory instruction "
106110197SCurtis.Dunham@arm.com                    "encountered, adding to LSQ.\n", tid);
106210197SCurtis.Dunham@arm.com
106310197SCurtis.Dunham@arm.com            // Reserve a spot in the load store queue for this
106410197SCurtis.Dunham@arm.com            // memory access.
106510197SCurtis.Dunham@arm.com            ldstQueue.insertLoad(inst);
10667639Sgblack@eecs.umich.edu
10677639Sgblack@eecs.umich.edu            ++iewDispLoadInsts;
10687639Sgblack@eecs.umich.edu
10699517SAli.Saidi@ARM.com            add_to_iq = true;
10707639Sgblack@eecs.umich.edu
10717639Sgblack@eecs.umich.edu            toRename->iewInfo[tid].dispatchedToLSQ++;
10727639Sgblack@eecs.umich.edu        } else if (inst->isStore()) {
10737639Sgblack@eecs.umich.edu            DPRINTF(IEW, "[tid:%i]: Issue: Memory instruction "
10747639Sgblack@eecs.umich.edu                    "encountered, adding to LSQ.\n", tid);
10757639Sgblack@eecs.umich.edu
10767639Sgblack@eecs.umich.edu            ldstQueue.insertStore(inst);
10779517SAli.Saidi@ARM.com
10787639Sgblack@eecs.umich.edu            ++iewDispStoreInsts;
10797639Sgblack@eecs.umich.edu
10807639Sgblack@eecs.umich.edu            if (inst->isStoreConditional()) {
10817639Sgblack@eecs.umich.edu                // Store conditionals need to be set as "canCommit()"
10827639Sgblack@eecs.umich.edu                // so that commit can process them when they reach the
10837639Sgblack@eecs.umich.edu                // head of commit.
10847639Sgblack@eecs.umich.edu                // @todo: This is somewhat specific to Alpha.
10857639Sgblack@eecs.umich.edu                inst->setCanCommit();
10867639Sgblack@eecs.umich.edu                instQueue.insertNonSpec(inst);
10877639Sgblack@eecs.umich.edu                add_to_iq = false;
10887639Sgblack@eecs.umich.edu
108910197SCurtis.Dunham@arm.com                ++iewDispNonSpecInsts;
109010197SCurtis.Dunham@arm.com            } else {
10917639Sgblack@eecs.umich.edu                add_to_iq = true;
10927639Sgblack@eecs.umich.edu            }
10937639Sgblack@eecs.umich.edu
10949517SAli.Saidi@ARM.com            toRename->iewInfo[tid].dispatchedToLSQ++;
10957639Sgblack@eecs.umich.edu        } else if (inst->isMemBarrier() || inst->isWriteBarrier()) {
10967639Sgblack@eecs.umich.edu            // Same as non-speculative stores.
10977639Sgblack@eecs.umich.edu            inst->setCanCommit();
10987639Sgblack@eecs.umich.edu            instQueue.insertBarrier(inst);
10997639Sgblack@eecs.umich.edu            add_to_iq = false;
11007639Sgblack@eecs.umich.edu        } else if (inst->isNop()) {
11017639Sgblack@eecs.umich.edu            DPRINTF(IEW, "[tid:%i]: Issue: Nop instruction encountered, "
11029517SAli.Saidi@ARM.com                    "skipping.\n", tid);
11037639Sgblack@eecs.umich.edu
11047639Sgblack@eecs.umich.edu            inst->setIssued();
11057639Sgblack@eecs.umich.edu            inst->setExecuted();
110610197SCurtis.Dunham@arm.com            inst->setCanCommit();
110710197SCurtis.Dunham@arm.com
11087639Sgblack@eecs.umich.edu            instQueue.recordProducer(inst);
11097639Sgblack@eecs.umich.edu
11107639Sgblack@eecs.umich.edu            iewExecutedNop[tid]++;
11119517SAli.Saidi@ARM.com
11127639Sgblack@eecs.umich.edu            add_to_iq = false;
11137639Sgblack@eecs.umich.edu        } else if (inst->isExecuted()) {
11147639Sgblack@eecs.umich.edu            assert(0 && "Instruction shouldn't be executed.\n");
11157639Sgblack@eecs.umich.edu            DPRINTF(IEW, "Issue: Executed branch encountered, "
11167639Sgblack@eecs.umich.edu                    "skipping.\n");
11177639Sgblack@eecs.umich.edu
11187639Sgblack@eecs.umich.edu            inst->setIssued();
11199517SAli.Saidi@ARM.com            inst->setCanCommit();
11207639Sgblack@eecs.umich.edu
11217639Sgblack@eecs.umich.edu            instQueue.recordProducer(inst);
11227639Sgblack@eecs.umich.edu
112310197SCurtis.Dunham@arm.com            add_to_iq = false;
11247639Sgblack@eecs.umich.edu        } else {
112510197SCurtis.Dunham@arm.com            add_to_iq = true;
11267639Sgblack@eecs.umich.edu        }
11277639Sgblack@eecs.umich.edu        if (inst->isNonSpeculative()) {
11287639Sgblack@eecs.umich.edu            DPRINTF(IEW, "[tid:%i]: Issue: Nonspeculative instruction "
11297639Sgblack@eecs.umich.edu                    "encountered, skipping.\n", tid);
11307639Sgblack@eecs.umich.edu
11317639Sgblack@eecs.umich.edu            // Same as non-speculative stores.
11327639Sgblack@eecs.umich.edu            inst->setCanCommit();
11337639Sgblack@eecs.umich.edu
11347760SGiacomo.Gabrielli@arm.com            // Specifically insert it as nonspeculative.
11357639Sgblack@eecs.umich.edu            instQueue.insertNonSpec(inst);
11367639Sgblack@eecs.umich.edu
11377640Sgblack@eecs.umich.edu            ++iewDispNonSpecInsts;
11387639Sgblack@eecs.umich.edu
11397639Sgblack@eecs.umich.edu            add_to_iq = false;
11407639Sgblack@eecs.umich.edu        }
11417639Sgblack@eecs.umich.edu
11428588Sgblack@eecs.umich.edu        // If the instruction queue is not full, then add the
11438588Sgblack@eecs.umich.edu        // instruction.
11447639Sgblack@eecs.umich.edu        if (add_to_iq) {
11457639Sgblack@eecs.umich.edu            instQueue.insert(inst);
11467639Sgblack@eecs.umich.edu        }
11478588Sgblack@eecs.umich.edu
11487639Sgblack@eecs.umich.edu        insts_to_dispatch.pop();
11497639Sgblack@eecs.umich.edu
11507639Sgblack@eecs.umich.edu        toRename->iewInfo[tid].dispatched++;
11517639Sgblack@eecs.umich.edu
11527639Sgblack@eecs.umich.edu        ++iewDispatchedInsts;
11537639Sgblack@eecs.umich.edu
11547639Sgblack@eecs.umich.edu#if TRACING_ON
11557639Sgblack@eecs.umich.edu        inst->dispatchTick = curTick() - inst->fetchTick;
11567639Sgblack@eecs.umich.edu#endif
11577639Sgblack@eecs.umich.edu    }
11587639Sgblack@eecs.umich.edu
11597639Sgblack@eecs.umich.edu    if (!insts_to_dispatch.empty()) {
11607639Sgblack@eecs.umich.edu        DPRINTF(IEW,"[tid:%i]: Issue: Bandwidth Full. Blocking.\n", tid);
11617639Sgblack@eecs.umich.edu        block(tid);
11627639Sgblack@eecs.umich.edu        toRename->iewUnblock[tid] = false;
11637639Sgblack@eecs.umich.edu    }
11647639Sgblack@eecs.umich.edu
11657639Sgblack@eecs.umich.edu    if (dispatchStatus[tid] == Idle && dis_num_inst) {
11667639Sgblack@eecs.umich.edu        dispatchStatus[tid] = Running;
11677639Sgblack@eecs.umich.edu
11687639Sgblack@eecs.umich.edu        updatedQueues = true;
11697639Sgblack@eecs.umich.edu    }
11707639Sgblack@eecs.umich.edu
11717639Sgblack@eecs.umich.edu    dis_num_inst = 0;
11727639Sgblack@eecs.umich.edu}
11737639Sgblack@eecs.umich.edu
11747639Sgblack@eecs.umich.edutemplate <class Impl>
11757639Sgblack@eecs.umich.eduvoid
11767639Sgblack@eecs.umich.eduDefaultIEW<Impl>::printAvailableInsts()
11777639Sgblack@eecs.umich.edu{
11787639Sgblack@eecs.umich.edu    int inst = 0;
11797639Sgblack@eecs.umich.edu
11808588Sgblack@eecs.umich.edu    std::cout << "Available Instructions: ";
11817639Sgblack@eecs.umich.edu
11827639Sgblack@eecs.umich.edu    while (fromIssue->insts[inst]) {
11837639Sgblack@eecs.umich.edu
11847639Sgblack@eecs.umich.edu        if (inst%3==0) std::cout << "\n\t";
11857639Sgblack@eecs.umich.edu
11867760SGiacomo.Gabrielli@arm.com        std::cout << "PC: " << fromIssue->insts[inst]->pcState()
11877760SGiacomo.Gabrielli@arm.com             << " TN: " << fromIssue->insts[inst]->threadNumber
11887639Sgblack@eecs.umich.edu             << " SN: " << fromIssue->insts[inst]->seqNum << " | ";
11897639Sgblack@eecs.umich.edu
11907639Sgblack@eecs.umich.edu        inst++;
11917639Sgblack@eecs.umich.edu
11927639Sgblack@eecs.umich.edu    }
11937639Sgblack@eecs.umich.edu
11947639Sgblack@eecs.umich.edu    std::cout << "\n";
11957760SGiacomo.Gabrielli@arm.com}
11967639Sgblack@eecs.umich.edu
11977639Sgblack@eecs.umich.edutemplate <class Impl>
11987640Sgblack@eecs.umich.eduvoid
11997639Sgblack@eecs.umich.eduDefaultIEW<Impl>::executeInsts()
12007639Sgblack@eecs.umich.edu{
12017639Sgblack@eecs.umich.edu    wbNumInst = 0;
12027639Sgblack@eecs.umich.edu    wbCycle = 0;
12037639Sgblack@eecs.umich.edu
12047639Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
12057639Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
12067639Sgblack@eecs.umich.edu
12077639Sgblack@eecs.umich.edu    while (threads != end) {
12087639Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
12097639Sgblack@eecs.umich.edu        fetchRedirect[tid] = false;
12107639Sgblack@eecs.umich.edu    }
12117639Sgblack@eecs.umich.edu
12127639Sgblack@eecs.umich.edu    // Uncomment this if you want to see all available instructions.
12137639Sgblack@eecs.umich.edu    // @todo This doesn't actually work anymore, we should fix it.
12147639Sgblack@eecs.umich.edu//    printAvailableInsts();
12157639Sgblack@eecs.umich.edu
12167639Sgblack@eecs.umich.edu    // Execute/writeback any instructions that are available.
12177639Sgblack@eecs.umich.edu    int insts_to_execute = fromIssue->size;
12187639Sgblack@eecs.umich.edu    int inst_num = 0;
12197639Sgblack@eecs.umich.edu    for (; inst_num < insts_to_execute;
12207639Sgblack@eecs.umich.edu          ++inst_num) {
12217639Sgblack@eecs.umich.edu
12227639Sgblack@eecs.umich.edu        DPRINTF(IEW, "Execute: Executing instructions from IQ.\n");
12237639Sgblack@eecs.umich.edu
12247639Sgblack@eecs.umich.edu        DynInstPtr inst = instQueue.getInstToExecute();
12257639Sgblack@eecs.umich.edu
12267639Sgblack@eecs.umich.edu        DPRINTF(IEW, "Execute: Processing PC %s, [tid:%i] [sn:%i].\n",
12277639Sgblack@eecs.umich.edu                inst->pcState(), inst->threadNumber,inst->seqNum);
12287639Sgblack@eecs.umich.edu
12297639Sgblack@eecs.umich.edu        // Check if the instruction is squashed; if so then skip it
12307639Sgblack@eecs.umich.edu        if (inst->isSquashed()) {
12317639Sgblack@eecs.umich.edu            DPRINTF(IEW, "Execute: Instruction was squashed. PC: %s, [tid:%i]"
12327639Sgblack@eecs.umich.edu                         " [sn:%i]\n", inst->pcState(), inst->threadNumber,
12337639Sgblack@eecs.umich.edu                         inst->seqNum);
12347639Sgblack@eecs.umich.edu
12357639Sgblack@eecs.umich.edu            // Consider this instruction executed so that commit can go
12367639Sgblack@eecs.umich.edu            // ahead and retire the instruction.
12377639Sgblack@eecs.umich.edu            inst->setExecuted();
12387639Sgblack@eecs.umich.edu
12397639Sgblack@eecs.umich.edu            // Not sure if I should set this here or just let commit try to
12407639Sgblack@eecs.umich.edu            // commit any squashed instructions.  I like the latter a bit more.
12417639Sgblack@eecs.umich.edu            inst->setCanCommit();
12427639Sgblack@eecs.umich.edu
12437639Sgblack@eecs.umich.edu            ++iewExecSquashedInsts;
12447639Sgblack@eecs.umich.edu
12457639Sgblack@eecs.umich.edu            decrWb(inst->seqNum);
12467639Sgblack@eecs.umich.edu            continue;
12477639Sgblack@eecs.umich.edu        }
12487639Sgblack@eecs.umich.edu
12497639Sgblack@eecs.umich.edu        Fault fault = NoFault;
12507639Sgblack@eecs.umich.edu
12517639Sgblack@eecs.umich.edu        // Execute instruction.
12527639Sgblack@eecs.umich.edu        // Note that if the instruction faults, it will be handled
12537639Sgblack@eecs.umich.edu        // at the commit stage.
12547639Sgblack@eecs.umich.edu        if (inst->isMemRef()) {
12557639Sgblack@eecs.umich.edu            DPRINTF(IEW, "Execute: Calculating address for memory "
12567639Sgblack@eecs.umich.edu                    "reference.\n");
12577639Sgblack@eecs.umich.edu
12587639Sgblack@eecs.umich.edu            // Tell the LDSTQ to execute this instruction (if it is a load).
12597639Sgblack@eecs.umich.edu            if (inst->isLoad()) {
12607639Sgblack@eecs.umich.edu                // Loads will mark themselves as executed, and their writeback
12618588Sgblack@eecs.umich.edu                // event adds the instruction to the queue to commit
12627639Sgblack@eecs.umich.edu                fault = ldstQueue.executeLoad(inst);
12637639Sgblack@eecs.umich.edu
12647639Sgblack@eecs.umich.edu                if (inst->isTranslationDelayed() &&
12657639Sgblack@eecs.umich.edu                    fault == NoFault) {
12667639Sgblack@eecs.umich.edu                    // A hw page table walk is currently going on; the
12677639Sgblack@eecs.umich.edu                    // instruction must be deferred.
12687639Sgblack@eecs.umich.edu                    DPRINTF(IEW, "Execute: Delayed translation, deferring "
12697639Sgblack@eecs.umich.edu                            "load.\n");
12707639Sgblack@eecs.umich.edu                    instQueue.deferMemInst(inst);
12717760SGiacomo.Gabrielli@arm.com                    continue;
12727760SGiacomo.Gabrielli@arm.com                }
12737639Sgblack@eecs.umich.edu
12747639Sgblack@eecs.umich.edu                if (inst->isDataPrefetch() || inst->isInstPrefetch()) {
12757639Sgblack@eecs.umich.edu                    inst->fault = NoFault;
12767639Sgblack@eecs.umich.edu                }
12777639Sgblack@eecs.umich.edu            } else if (inst->isStore()) {
12787639Sgblack@eecs.umich.edu                fault = ldstQueue.executeStore(inst);
12797639Sgblack@eecs.umich.edu
12807760SGiacomo.Gabrielli@arm.com                if (inst->isTranslationDelayed() &&
12817639Sgblack@eecs.umich.edu                    fault == NoFault) {
12827639Sgblack@eecs.umich.edu                    // A hw page table walk is currently going on; the
12837639Sgblack@eecs.umich.edu                    // instruction must be deferred.
12847639Sgblack@eecs.umich.edu                    DPRINTF(IEW, "Execute: Delayed translation, deferring "
12857639Sgblack@eecs.umich.edu                            "store.\n");
12867639Sgblack@eecs.umich.edu                    instQueue.deferMemInst(inst);
12877639Sgblack@eecs.umich.edu                    continue;
12887639Sgblack@eecs.umich.edu                }
12897639Sgblack@eecs.umich.edu
12907639Sgblack@eecs.umich.edu                // If the store had a fault then it may not have a mem req
12917639Sgblack@eecs.umich.edu                if (fault != NoFault || inst->readPredicate() == false ||
12927639Sgblack@eecs.umich.edu                        !inst->isStoreConditional()) {
12937639Sgblack@eecs.umich.edu                    // If the instruction faulted, then we need to send it along
12947640Sgblack@eecs.umich.edu                    // to commit without the instruction completing.
12957639Sgblack@eecs.umich.edu                    // Send this instruction to commit, also make sure iew stage
12967639Sgblack@eecs.umich.edu                    // realizes there is activity.
12977639Sgblack@eecs.umich.edu                    inst->setExecuted();
12987639Sgblack@eecs.umich.edu                    instToCommit(inst);
12997639Sgblack@eecs.umich.edu                    activityThisCycle();
13007639Sgblack@eecs.umich.edu                }
13018588Sgblack@eecs.umich.edu
13027639Sgblack@eecs.umich.edu                // Store conditionals will mark themselves as
13037639Sgblack@eecs.umich.edu                // executed, and their writeback event will add the
13047639Sgblack@eecs.umich.edu                // instruction to the queue to commit.
13058588Sgblack@eecs.umich.edu            } else {
13067639Sgblack@eecs.umich.edu                panic("Unexpected memory type!\n");
13077639Sgblack@eecs.umich.edu            }
13087639Sgblack@eecs.umich.edu
13097639Sgblack@eecs.umich.edu        } else {
13108588Sgblack@eecs.umich.edu            // If the instruction has already faulted, then skip executing it.
13117639Sgblack@eecs.umich.edu            // Such case can happen when it faulted during ITLB translation.
13127639Sgblack@eecs.umich.edu            // If we execute the instruction (even if it's a nop) the fault
13137639Sgblack@eecs.umich.edu            // will be replaced and we will lose it.
13147639Sgblack@eecs.umich.edu            if (inst->getFault() == NoFault) {
13157639Sgblack@eecs.umich.edu                inst->execute();
13167639Sgblack@eecs.umich.edu                if (inst->readPredicate() == false)
13177639Sgblack@eecs.umich.edu                    inst->forwardOldRegs();
13187639Sgblack@eecs.umich.edu            }
13197639Sgblack@eecs.umich.edu
13207639Sgblack@eecs.umich.edu            inst->setExecuted();
13217639Sgblack@eecs.umich.edu
13227639Sgblack@eecs.umich.edu            instToCommit(inst);
13237639Sgblack@eecs.umich.edu        }
13247639Sgblack@eecs.umich.edu
13257639Sgblack@eecs.umich.edu        updateExeInstStats(inst);
13267639Sgblack@eecs.umich.edu
13277639Sgblack@eecs.umich.edu        // Check if branch prediction was correct, if not then we need
13287639Sgblack@eecs.umich.edu        // to tell commit to squash in flight instructions.  Only
13298588Sgblack@eecs.umich.edu        // handle this if there hasn't already been something that
13307639Sgblack@eecs.umich.edu        // redirects fetch in this group of instructions.
13317639Sgblack@eecs.umich.edu
13327639Sgblack@eecs.umich.edu        // This probably needs to prioritize the redirects if a different
13337639Sgblack@eecs.umich.edu        // scheduler is used.  Currently the scheduler schedules the oldest
13347639Sgblack@eecs.umich.edu        // instruction first, so the branch resolution order will be correct.
13357760SGiacomo.Gabrielli@arm.com        ThreadID tid = inst->threadNumber;
13367760SGiacomo.Gabrielli@arm.com
13377639Sgblack@eecs.umich.edu        if (!fetchRedirect[tid] ||
13387639Sgblack@eecs.umich.edu            !toCommit->squash[tid] ||
13397639Sgblack@eecs.umich.edu            toCommit->squashedSeqNum[tid] > inst->seqNum) {
13407639Sgblack@eecs.umich.edu
13417639Sgblack@eecs.umich.edu            // Prevent testing for misprediction on load instructions,
13427639Sgblack@eecs.umich.edu            // that have not been executed.
13437639Sgblack@eecs.umich.edu            bool loadNotExecuted = !inst->isExecuted() && inst->isLoad();
13447760SGiacomo.Gabrielli@arm.com
13457760SGiacomo.Gabrielli@arm.com            if (inst->mispredicted() && !loadNotExecuted) {
13467639Sgblack@eecs.umich.edu                fetchRedirect[tid] = true;
13477639Sgblack@eecs.umich.edu
13487760SGiacomo.Gabrielli@arm.com                DPRINTF(IEW, "Execute: Branch mispredict detected.\n");
13497760SGiacomo.Gabrielli@arm.com                DPRINTF(IEW, "Predicted target was PC: %s.\n",
13507639Sgblack@eecs.umich.edu                        inst->readPredTarg());
13517639Sgblack@eecs.umich.edu                DPRINTF(IEW, "Execute: Redirecting fetch to PC: %s.\n",
13527760SGiacomo.Gabrielli@arm.com                        inst->pcState());
13537760SGiacomo.Gabrielli@arm.com                // If incorrect, then signal the ROB that it must be squashed.
13547639Sgblack@eecs.umich.edu                squashDueToBranch(inst, tid);
13557639Sgblack@eecs.umich.edu
13567760SGiacomo.Gabrielli@arm.com                if (inst->readPredTaken()) {
13577639Sgblack@eecs.umich.edu                    predictedTakenIncorrect++;
13587640Sgblack@eecs.umich.edu                } else {
13597639Sgblack@eecs.umich.edu                    predictedNotTakenIncorrect++;
13607639Sgblack@eecs.umich.edu                }
13617639Sgblack@eecs.umich.edu            } else if (ldstQueue.violation(tid)) {
13627639Sgblack@eecs.umich.edu                assert(inst->isMemRef());
13638588Sgblack@eecs.umich.edu                // If there was an ordering violation, then get the
13648588Sgblack@eecs.umich.edu                // DynInst that caused the violation.  Note that this
13657639Sgblack@eecs.umich.edu                // clears the violation signal.
13667639Sgblack@eecs.umich.edu                DynInstPtr violator;
13677639Sgblack@eecs.umich.edu                violator = ldstQueue.getMemDepViolator(tid);
13688588Sgblack@eecs.umich.edu
13697639Sgblack@eecs.umich.edu                DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: %s "
13707639Sgblack@eecs.umich.edu                        "[sn:%lli], inst PC: %s [sn:%lli]. Addr is: %#x.\n",
13717639Sgblack@eecs.umich.edu                        violator->pcState(), violator->seqNum,
13727639Sgblack@eecs.umich.edu                        inst->pcState(), inst->seqNum, inst->physEffAddr);
13737639Sgblack@eecs.umich.edu
13747853SMatt.Horsnell@ARM.com                fetchRedirect[tid] = true;
137510474Sandreas.hansson@arm.com
137610474Sandreas.hansson@arm.com                // Tell the instruction queue that a violation has occured.
13777853SMatt.Horsnell@ARM.com                instQueue.violation(inst, violator);
13787853SMatt.Horsnell@ARM.com
13797853SMatt.Horsnell@ARM.com                // Squash.
13807853SMatt.Horsnell@ARM.com                squashDueToMemOrder(violator, tid);
13817853SMatt.Horsnell@ARM.com
13827853SMatt.Horsnell@ARM.com                ++memOrderViolationEvents;
13837853SMatt.Horsnell@ARM.com            } else if (ldstQueue.loadBlocked(tid) &&
13847853SMatt.Horsnell@ARM.com                       !ldstQueue.isLoadBlockedHandled(tid)) {
13857853SMatt.Horsnell@ARM.com                fetchRedirect[tid] = true;
13867639Sgblack@eecs.umich.edu
13877639Sgblack@eecs.umich.edu                DPRINTF(IEW, "Load operation couldn't execute because the "
13887639Sgblack@eecs.umich.edu                        "memory system is blocked.  PC: %s [sn:%lli]\n",
13897639Sgblack@eecs.umich.edu                        inst->pcState(), inst->seqNum);
13908588Sgblack@eecs.umich.edu
13917639Sgblack@eecs.umich.edu                squashDueToMemBlocked(inst, tid);
13927639Sgblack@eecs.umich.edu            }
13937639Sgblack@eecs.umich.edu        } else {
13947639Sgblack@eecs.umich.edu            // Reset any state associated with redirects that will not
13957639Sgblack@eecs.umich.edu            // be used.
13967760SGiacomo.Gabrielli@arm.com            if (ldstQueue.violation(tid)) {
13977760SGiacomo.Gabrielli@arm.com                assert(inst->isMemRef());
13987639Sgblack@eecs.umich.edu
13997639Sgblack@eecs.umich.edu                DynInstPtr violator = ldstQueue.getMemDepViolator(tid);
14007639Sgblack@eecs.umich.edu
14017639Sgblack@eecs.umich.edu                DPRINTF(IEW, "LDSTQ detected a violation.  Violator PC: "
14027639Sgblack@eecs.umich.edu                        "%s, inst PC: %s.  Addr is: %#x.\n",
14037639Sgblack@eecs.umich.edu                        violator->pcState(), inst->pcState(),
14047639Sgblack@eecs.umich.edu                        inst->physEffAddr);
14057760SGiacomo.Gabrielli@arm.com                DPRINTF(IEW, "Violation will not be handled because "
14067639Sgblack@eecs.umich.edu                        "already squashing\n");
14077639Sgblack@eecs.umich.edu
14087640Sgblack@eecs.umich.edu                ++memOrderViolationEvents;
14097639Sgblack@eecs.umich.edu            }
14107639Sgblack@eecs.umich.edu            if (ldstQueue.loadBlocked(tid) &&
14117639Sgblack@eecs.umich.edu                !ldstQueue.isLoadBlockedHandled(tid)) {
14127639Sgblack@eecs.umich.edu                DPRINTF(IEW, "Load operation couldn't execute because the "
14137639Sgblack@eecs.umich.edu                        "memory system is blocked.  PC: %s [sn:%lli]\n",
14148588Sgblack@eecs.umich.edu                        inst->pcState(), inst->seqNum);
14158588Sgblack@eecs.umich.edu                DPRINTF(IEW, "Blocked load will not be handled because "
14167639Sgblack@eecs.umich.edu                        "already squashing\n");
14177639Sgblack@eecs.umich.edu
14187639Sgblack@eecs.umich.edu                ldstQueue.setLoadBlockedHandled(tid);
14197639Sgblack@eecs.umich.edu            }
14208588Sgblack@eecs.umich.edu
14217639Sgblack@eecs.umich.edu        }
14227639Sgblack@eecs.umich.edu    }
14237639Sgblack@eecs.umich.edu
14247639Sgblack@eecs.umich.edu    // Update and record activity if we processed any instructions.
14257639Sgblack@eecs.umich.edu    if (inst_num) {
14267853SMatt.Horsnell@ARM.com        if (exeStatus == Idle) {
142710474Sandreas.hansson@arm.com            exeStatus = Running;
142810474Sandreas.hansson@arm.com        }
14297853SMatt.Horsnell@ARM.com
14307853SMatt.Horsnell@ARM.com        updatedQueues = true;
14317853SMatt.Horsnell@ARM.com
14327853SMatt.Horsnell@ARM.com        cpu->activityThisCycle();
14337853SMatt.Horsnell@ARM.com    }
14347853SMatt.Horsnell@ARM.com
14357853SMatt.Horsnell@ARM.com    // Need to reset this in case a writeback event needs to write into the
14367853SMatt.Horsnell@ARM.com    // iew queue.  That way the writeback event will write into the correct
14377853SMatt.Horsnell@ARM.com    // spot in the queue.
14387639Sgblack@eecs.umich.edu    wbNumInst = 0;
14397639Sgblack@eecs.umich.edu
14407639Sgblack@eecs.umich.edu}
14417639Sgblack@eecs.umich.edu
14428588Sgblack@eecs.umich.edutemplate <class Impl>
14437639Sgblack@eecs.umich.eduvoid
14447639Sgblack@eecs.umich.eduDefaultIEW<Impl>::writebackInsts()
14457639Sgblack@eecs.umich.edu{
14467639Sgblack@eecs.umich.edu    // Loop through the head of the time buffer and wake any
14477639Sgblack@eecs.umich.edu    // dependents.  These instructions are about to write back.  Also
14487760SGiacomo.Gabrielli@arm.com    // mark scoreboard that this instruction is finally complete.
14497760SGiacomo.Gabrielli@arm.com    // Either have IEW have direct access to scoreboard, or have this
14507639Sgblack@eecs.umich.edu    // as part of backwards communication.
14517639Sgblack@eecs.umich.edu    for (int inst_num = 0; inst_num < wbWidth &&
14527639Sgblack@eecs.umich.edu             toCommit->insts[inst_num]; inst_num++) {
14537639Sgblack@eecs.umich.edu        DynInstPtr inst = toCommit->insts[inst_num];
14547639Sgblack@eecs.umich.edu        ThreadID tid = inst->threadNumber;
14557639Sgblack@eecs.umich.edu
14567639Sgblack@eecs.umich.edu        DPRINTF(IEW, "Sending instructions to commit, [sn:%lli] PC %s.\n",
14577760SGiacomo.Gabrielli@arm.com                inst->seqNum, inst->pcState());
14587639Sgblack@eecs.umich.edu
14597640Sgblack@eecs.umich.edu        iewInstsToCommit[tid]++;
14607639Sgblack@eecs.umich.edu
14617639Sgblack@eecs.umich.edu        // Some instructions will be sent to commit without having
14627639Sgblack@eecs.umich.edu        // executed because they need commit to handle them.
14637639Sgblack@eecs.umich.edu        // E.g. Uncached loads have not actually executed when they
14647639Sgblack@eecs.umich.edu        // are first sent to commit.  Instead commit must tell the LSQ
14657639Sgblack@eecs.umich.edu        // when it's ready to execute the uncached load.
14667639Sgblack@eecs.umich.edu        if (!inst->isSquashed() && inst->isExecuted() && inst->getFault() == NoFault) {
14677639Sgblack@eecs.umich.edu            int dependents = instQueue.wakeDependents(inst);
14687639Sgblack@eecs.umich.edu
14697639Sgblack@eecs.umich.edu            for (int i = 0; i < inst->numDestRegs(); i++) {
14707639Sgblack@eecs.umich.edu                //mark as Ready
14717639Sgblack@eecs.umich.edu                DPRINTF(IEW,"Setting Destination Register %i\n",
14727639Sgblack@eecs.umich.edu                        inst->renamedDestRegIdx(i));
14737639Sgblack@eecs.umich.edu                scoreboard->setReg(inst->renamedDestRegIdx(i));
14747639Sgblack@eecs.umich.edu            }
14757639Sgblack@eecs.umich.edu
14767853SMatt.Horsnell@ARM.com            if (dependents) {
147710474Sandreas.hansson@arm.com                producerInst[tid]++;
147810474Sandreas.hansson@arm.com                consumerInst[tid]+= dependents;
14797853SMatt.Horsnell@ARM.com            }
14807853SMatt.Horsnell@ARM.com            writebackCount[tid]++;
14817853SMatt.Horsnell@ARM.com        }
14827853SMatt.Horsnell@ARM.com
14837853SMatt.Horsnell@ARM.com        decrWb(inst->seqNum);
14847853SMatt.Horsnell@ARM.com    }
14857853SMatt.Horsnell@ARM.com}
14867853SMatt.Horsnell@ARM.com
14877853SMatt.Horsnell@ARM.comtemplate<class Impl>
14887639Sgblack@eecs.umich.eduvoid
14897639Sgblack@eecs.umich.eduDefaultIEW<Impl>::tick()
14907639Sgblack@eecs.umich.edu{
14917639Sgblack@eecs.umich.edu    wbNumInst = 0;
14927639Sgblack@eecs.umich.edu    wbCycle = 0;
14937639Sgblack@eecs.umich.edu
14947639Sgblack@eecs.umich.edu    wroteToTimeBuffer = false;
14957639Sgblack@eecs.umich.edu    updatedQueues = false;
14967639Sgblack@eecs.umich.edu
14977639Sgblack@eecs.umich.edu    sortInsts();
14987760SGiacomo.Gabrielli@arm.com
14997760SGiacomo.Gabrielli@arm.com    // Free function units marked as being freed this cycle.
15007639Sgblack@eecs.umich.edu    fuPool->processFreeUnits();
15017639Sgblack@eecs.umich.edu
15027639Sgblack@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
15037639Sgblack@eecs.umich.edu    list<ThreadID>::iterator end = activeThreads->end();
15047639Sgblack@eecs.umich.edu
15057639Sgblack@eecs.umich.edu    // Check stall and squash signals, dispatch any instructions.
15067639Sgblack@eecs.umich.edu    while (threads != end) {
15077760SGiacomo.Gabrielli@arm.com        ThreadID tid = *threads++;
15087639Sgblack@eecs.umich.edu
15097639Sgblack@eecs.umich.edu        DPRINTF(IEW,"Issue: Processing [tid:%i]\n",tid);
15107640Sgblack@eecs.umich.edu
15117639Sgblack@eecs.umich.edu        checkSignalsAndUpdate(tid);
15127639Sgblack@eecs.umich.edu        dispatch(tid);
15137639Sgblack@eecs.umich.edu    }
15147639Sgblack@eecs.umich.edu
15158588Sgblack@eecs.umich.edu    if (exeStatus != Squashing) {
15167639Sgblack@eecs.umich.edu        executeInsts();
15177639Sgblack@eecs.umich.edu
15187639Sgblack@eecs.umich.edu        writebackInsts();
15198588Sgblack@eecs.umich.edu
15207639Sgblack@eecs.umich.edu        // Have the instruction queue try to schedule any ready instructions.
15217639Sgblack@eecs.umich.edu        // (In actuality, this scheduling is for instructions that will
15227639Sgblack@eecs.umich.edu        // be executed next cycle.)
15237639Sgblack@eecs.umich.edu        instQueue.scheduleReadyInsts();
15247639Sgblack@eecs.umich.edu
15257639Sgblack@eecs.umich.edu        // Also should advance its own time buffers if the stage ran.
15267639Sgblack@eecs.umich.edu        // Not the best place for it, but this works (hopefully).
15277639Sgblack@eecs.umich.edu        issueToExecQueue.advance();
15287639Sgblack@eecs.umich.edu    }
15297639Sgblack@eecs.umich.edu
15307639Sgblack@eecs.umich.edu    bool broadcast_free_entries = false;
15317639Sgblack@eecs.umich.edu
15327639Sgblack@eecs.umich.edu    if (updatedQueues || exeStatus == Running || updateLSQNextCycle) {
15337639Sgblack@eecs.umich.edu        exeStatus = Idle;
15347639Sgblack@eecs.umich.edu        updateLSQNextCycle = false;
15357639Sgblack@eecs.umich.edu
15367639Sgblack@eecs.umich.edu        broadcast_free_entries = true;
15377639Sgblack@eecs.umich.edu    }
15387639Sgblack@eecs.umich.edu
15397639Sgblack@eecs.umich.edu    // Writeback any stores using any leftover bandwidth.
15407639Sgblack@eecs.umich.edu    ldstQueue.writebackStores();
15417639Sgblack@eecs.umich.edu
15427639Sgblack@eecs.umich.edu    // Check the committed load/store signals to see if there's a load
15437639Sgblack@eecs.umich.edu    // or store to commit.  Also check if it's being told to execute a
15447639Sgblack@eecs.umich.edu    // nonspeculative instruction.
15457639Sgblack@eecs.umich.edu    // This is pretty inefficient...
15467639Sgblack@eecs.umich.edu
15477639Sgblack@eecs.umich.edu    threads = activeThreads->begin();
15487639Sgblack@eecs.umich.edu    while (threads != end) {
15498588Sgblack@eecs.umich.edu        ThreadID tid = (*threads++);
15507639Sgblack@eecs.umich.edu
15517639Sgblack@eecs.umich.edu        DPRINTF(IEW,"Processing [tid:%i]\n",tid);
15527639Sgblack@eecs.umich.edu
15537639Sgblack@eecs.umich.edu        // Update structures based on instructions committed.
15547639Sgblack@eecs.umich.edu        if (fromCommit->commitInfo[tid].doneSeqNum != 0 &&
15557760SGiacomo.Gabrielli@arm.com            !fromCommit->commitInfo[tid].squash &&
15567760SGiacomo.Gabrielli@arm.com            !fromCommit->commitInfo[tid].robSquashing) {
15577639Sgblack@eecs.umich.edu
15587639Sgblack@eecs.umich.edu            ldstQueue.commitStores(fromCommit->commitInfo[tid].doneSeqNum,tid);
15597639Sgblack@eecs.umich.edu
15607639Sgblack@eecs.umich.edu            ldstQueue.commitLoads(fromCommit->commitInfo[tid].doneSeqNum,tid);
15617639Sgblack@eecs.umich.edu
15627639Sgblack@eecs.umich.edu            updateLSQNextCycle = true;
15637639Sgblack@eecs.umich.edu            instQueue.commit(fromCommit->commitInfo[tid].doneSeqNum,tid);
15647760SGiacomo.Gabrielli@arm.com        }
15657639Sgblack@eecs.umich.edu
15667640Sgblack@eecs.umich.edu        if (fromCommit->commitInfo[tid].nonSpecSeqNum != 0) {
15677639Sgblack@eecs.umich.edu
15687639Sgblack@eecs.umich.edu            //DPRINTF(IEW,"NonspecInst from thread %i",tid);
15697639Sgblack@eecs.umich.edu            if (fromCommit->commitInfo[tid].uncached) {
15707639Sgblack@eecs.umich.edu                instQueue.replayMemInst(fromCommit->commitInfo[tid].uncachedLoad);
15717639Sgblack@eecs.umich.edu                fromCommit->commitInfo[tid].uncachedLoad->setAtCommit();
15728588Sgblack@eecs.umich.edu            } else {
15737639Sgblack@eecs.umich.edu                instQueue.scheduleNonSpec(
15747639Sgblack@eecs.umich.edu                    fromCommit->commitInfo[tid].nonSpecSeqNum);
15757639Sgblack@eecs.umich.edu            }
15767639Sgblack@eecs.umich.edu        }
15778588Sgblack@eecs.umich.edu
15787639Sgblack@eecs.umich.edu        if (broadcast_free_entries) {
15797639Sgblack@eecs.umich.edu            toFetch->iewInfo[tid].iqCount =
15807639Sgblack@eecs.umich.edu                instQueue.getCount(tid);
15817639Sgblack@eecs.umich.edu            toFetch->iewInfo[tid].ldstqCount =
15827639Sgblack@eecs.umich.edu                ldstQueue.getCount(tid);
15837639Sgblack@eecs.umich.edu
15847639Sgblack@eecs.umich.edu            toRename->iewInfo[tid].usedIQ = true;
15857639Sgblack@eecs.umich.edu            toRename->iewInfo[tid].freeIQEntries =
15867639Sgblack@eecs.umich.edu                instQueue.numFreeEntries();
15877639Sgblack@eecs.umich.edu            toRename->iewInfo[tid].usedLSQ = true;
15887639Sgblack@eecs.umich.edu            toRename->iewInfo[tid].freeLSQEntries =
15897639Sgblack@eecs.umich.edu                ldstQueue.numFreeEntries(tid);
15907639Sgblack@eecs.umich.edu
15917639Sgblack@eecs.umich.edu            wroteToTimeBuffer = true;
15927639Sgblack@eecs.umich.edu        }
15938588Sgblack@eecs.umich.edu
15947639Sgblack@eecs.umich.edu        DPRINTF(IEW, "[tid:%i], Dispatch dispatched %i instructions.\n",
15957639Sgblack@eecs.umich.edu                tid, toRename->iewInfo[tid].dispatched);
15967639Sgblack@eecs.umich.edu    }
15977639Sgblack@eecs.umich.edu
15987639Sgblack@eecs.umich.edu    DPRINTF(IEW, "IQ has %i free entries (Can schedule: %i).  "
15997760SGiacomo.Gabrielli@arm.com            "LSQ has %i free entries.\n",
16007760SGiacomo.Gabrielli@arm.com            instQueue.numFreeEntries(), instQueue.hasReadyInsts(),
16017639Sgblack@eecs.umich.edu            ldstQueue.numFreeEntries());
16027639Sgblack@eecs.umich.edu
16037639Sgblack@eecs.umich.edu    updateStatus();
16047639Sgblack@eecs.umich.edu
16057639Sgblack@eecs.umich.edu    if (wroteToTimeBuffer) {
16067639Sgblack@eecs.umich.edu        DPRINTF(Activity, "Activity this cycle.\n");
16077639Sgblack@eecs.umich.edu        cpu->activityThisCycle();
16087760SGiacomo.Gabrielli@arm.com    }
16097639Sgblack@eecs.umich.edu}
16107640Sgblack@eecs.umich.edu
16117639Sgblack@eecs.umich.edutemplate <class Impl>
16127639Sgblack@eecs.umich.eduvoid
16137639Sgblack@eecs.umich.eduDefaultIEW<Impl>::updateExeInstStats(DynInstPtr &inst)
16147639Sgblack@eecs.umich.edu{
16157639Sgblack@eecs.umich.edu    ThreadID tid = inst->threadNumber;
16168588Sgblack@eecs.umich.edu
16177639Sgblack@eecs.umich.edu    iewExecutedInsts++;
16187639Sgblack@eecs.umich.edu
16197639Sgblack@eecs.umich.edu#if TRACING_ON
16207639Sgblack@eecs.umich.edu    inst->completeTick = curTick() - inst->fetchTick;
16218588Sgblack@eecs.umich.edu#endif
16227639Sgblack@eecs.umich.edu
16237639Sgblack@eecs.umich.edu    //
16247639Sgblack@eecs.umich.edu    //  Control operations
16257639Sgblack@eecs.umich.edu    //
16267639Sgblack@eecs.umich.edu    if (inst->isControl())
16277639Sgblack@eecs.umich.edu        iewExecutedBranches[tid]++;
16287639Sgblack@eecs.umich.edu
16297639Sgblack@eecs.umich.edu    //
16307639Sgblack@eecs.umich.edu    //  Memory operations
16317639Sgblack@eecs.umich.edu    //
16327639Sgblack@eecs.umich.edu    if (inst->isMemRef()) {
16337639Sgblack@eecs.umich.edu        iewExecutedRefs[tid]++;
16347639Sgblack@eecs.umich.edu
16357639Sgblack@eecs.umich.edu        if (inst->isLoad()) {
16367639Sgblack@eecs.umich.edu            iewExecLoadInsts[tid]++;
16378588Sgblack@eecs.umich.edu        }
16387639Sgblack@eecs.umich.edu    }
16397639Sgblack@eecs.umich.edu}
16407639Sgblack@eecs.umich.edu
16417639Sgblack@eecs.umich.edutemplate <class Impl>
16427639Sgblack@eecs.umich.eduvoid
16437760SGiacomo.Gabrielli@arm.comDefaultIEW<Impl>::checkMisprediction(DynInstPtr &inst)
16447760SGiacomo.Gabrielli@arm.com{
16457639Sgblack@eecs.umich.edu    ThreadID tid = inst->threadNumber;
16467639Sgblack@eecs.umich.edu
16477639Sgblack@eecs.umich.edu    if (!fetchRedirect[tid] ||
16487639Sgblack@eecs.umich.edu        !toCommit->squash[tid] ||
16497639Sgblack@eecs.umich.edu        toCommit->squashedSeqNum[tid] > inst->seqNum) {
16507639Sgblack@eecs.umich.edu
16517639Sgblack@eecs.umich.edu        if (inst->mispredicted()) {
16527760SGiacomo.Gabrielli@arm.com            fetchRedirect[tid] = true;
16537639Sgblack@eecs.umich.edu
16547640Sgblack@eecs.umich.edu            DPRINTF(IEW, "Execute: Branch mispredict detected.\n");
16557639Sgblack@eecs.umich.edu            DPRINTF(IEW, "Predicted target was PC:%#x, NPC:%#x.\n",
16567639Sgblack@eecs.umich.edu                    inst->predInstAddr(), inst->predNextInstAddr());
16577639Sgblack@eecs.umich.edu            DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x,"
16587639Sgblack@eecs.umich.edu                    " NPC: %#x.\n", inst->nextInstAddr(),
16598588Sgblack@eecs.umich.edu                    inst->nextInstAddr());
16607639Sgblack@eecs.umich.edu            // If incorrect, then signal the ROB that it must be squashed.
16617639Sgblack@eecs.umich.edu            squashDueToBranch(inst, tid);
16627639Sgblack@eecs.umich.edu
16638588Sgblack@eecs.umich.edu            if (inst->readPredTaken()) {
16647639Sgblack@eecs.umich.edu                predictedTakenIncorrect++;
16657639Sgblack@eecs.umich.edu            } else {
16667639Sgblack@eecs.umich.edu                predictedNotTakenIncorrect++;
16677639Sgblack@eecs.umich.edu            }
16687639Sgblack@eecs.umich.edu        }
16697639Sgblack@eecs.umich.edu    }
16707639Sgblack@eecs.umich.edu}
16717639Sgblack@eecs.umich.edu