iew_impl.hh revision 10231
1360SN/A/*
210850SGiacomo.Gabrielli@arm.com * Copyright (c) 2010-2013 ARM Limited
310796Sbrandon.potter@amd.com * All rights reserved.
410027SChris.Adeniyi-Jones@arm.com *
510027SChris.Adeniyi-Jones@arm.com * The license below extends only to copyright in the software and shall
610027SChris.Adeniyi-Jones@arm.com * not be construed as granting a license to any other intellectual
710027SChris.Adeniyi-Jones@arm.com * property including but not limited to intellectual property relating
810027SChris.Adeniyi-Jones@arm.com * to a hardware implementation of the functionality of the software
910027SChris.Adeniyi-Jones@arm.com * licensed hereunder.  You may use the software subject to the license
1010027SChris.Adeniyi-Jones@arm.com * terms below provided that you ensure that this notice is replicated
1110027SChris.Adeniyi-Jones@arm.com * unmodified and in its entirety in all distributions of the software,
1210027SChris.Adeniyi-Jones@arm.com * modified or unmodified, in source code or in binary form.
1310027SChris.Adeniyi-Jones@arm.com *
1410027SChris.Adeniyi-Jones@arm.com * Copyright (c) 2004-2006 The Regents of The University of Michigan
151458SN/A * All rights reserved.
16360SN/A *
17360SN/A * Redistribution and use in source and binary forms, with or without
18360SN/A * modification, are permitted provided that the following conditions are
19360SN/A * met: redistributions of source code must retain the above copyright
20360SN/A * notice, this list of conditions and the following disclaimer;
21360SN/A * redistributions in binary form must reproduce the above copyright
22360SN/A * notice, this list of conditions and the following disclaimer in the
23360SN/A * documentation and/or other materials provided with the distribution;
24360SN/A * neither the name of the copyright holders nor the names of its
25360SN/A * contributors may be used to endorse or promote products derived from
26360SN/A * this software without specific prior written permission.
27360SN/A *
28360SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29360SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30360SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31360SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32360SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33360SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34360SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35360SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36360SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37360SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38360SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39360SN/A *
402665Ssaidi@eecs.umich.edu * Authors: Kevin Lim
412665Ssaidi@eecs.umich.edu */
422665Ssaidi@eecs.umich.edu
43360SN/A#ifndef __CPU_O3_IEW_IMPL_IMPL_HH__
44360SN/A#define __CPU_O3_IEW_IMPL_IMPL_HH__
451354SN/A
461354SN/A// @todo: Fix the instantaneous communication among all the stages within
47360SN/A// iew.  There's a clear delay between issue and execute, yet backwards
4812018Sandreas.sandberg@arm.com// communication happens simultaneously.
4912018Sandreas.sandberg@arm.com
5012018Sandreas.sandberg@arm.com#include <queue>
5112018Sandreas.sandberg@arm.com
5212018Sandreas.sandberg@arm.com#include "arch/utility.hh"
5312018Sandreas.sandberg@arm.com#include "config/the_isa.hh"
5412018Sandreas.sandberg@arm.com#include "cpu/checker/cpu.hh"
552064SN/A#include "cpu/o3/fu_pool.hh"
5612018Sandreas.sandberg@arm.com#include "cpu/o3/iew.hh"
5712018Sandreas.sandberg@arm.com#include "cpu/timebuf.hh"
5812018Sandreas.sandberg@arm.com#include "debug/Activity.hh"
5912018Sandreas.sandberg@arm.com#include "debug/Drain.hh"
6012018Sandreas.sandberg@arm.com#include "debug/IEW.hh"
6112018Sandreas.sandberg@arm.com#include "debug/O3PipeView.hh"
6211799Sbrandon.potter@amd.com#include "params/DerivO3CPU.hh"
6312018Sandreas.sandberg@arm.com
6412018Sandreas.sandberg@arm.comusing namespace std;
6512018Sandreas.sandberg@arm.com
6612018Sandreas.sandberg@arm.comtemplate<class Impl>
6712018Sandreas.sandberg@arm.comDefaultIEW<Impl>::DefaultIEW(O3CPU *_cpu, DerivO3CPUParams *params)
6812018Sandreas.sandberg@arm.com    : issueToExecQueue(params->backComSize, params->forwardComSize),
6911799Sbrandon.potter@amd.com      cpu(_cpu),
70360SN/A      instQueue(_cpu, this, params),
71360SN/A      ldstQueue(_cpu, this, params),
72360SN/A      fuPool(params->fuPool),
73360SN/A      commitToIEWDelay(params->commitToIEWDelay),
74360SN/A      renameToIEWDelay(params->renameToIEWDelay),
75360SN/A      issueToExecuteDelay(params->issueToExecuteDelay),
761809SN/A      dispatchWidth(params->dispatchWidth),
7711800Sbrandon.potter@amd.com      issueWidth(params->issueWidth),
7811392Sbrandon.potter@amd.com      wbOutstanding(0),
791809SN/A      wbWidth(params->wbWidth),
8011392Sbrandon.potter@amd.com      numThreads(params->numThreads)
8113570Sbrandon.potter@amd.com{
8211383Sbrandon.potter@amd.com    if (dispatchWidth > Impl::MaxWidth)
8313568Sbrandon.potter@amd.com        fatal("dispatchWidth (%d) is larger than compiled limit (%d),\n"
843113Sgblack@eecs.umich.edu             "\tincrease MaxWidth in src/cpu/o3/impl.hh\n",
8511799Sbrandon.potter@amd.com             dispatchWidth, static_cast<int>(Impl::MaxWidth));
8611759Sbrandon.potter@amd.com    if (issueWidth > Impl::MaxWidth)
8711812Sbaz21@cam.ac.uk        fatal("issueWidth (%d) is larger than compiled limit (%d),\n"
8811812Sbaz21@cam.ac.uk             "\tincrease MaxWidth in src/cpu/o3/impl.hh\n",
8911799Sbrandon.potter@amd.com             issueWidth, static_cast<int>(Impl::MaxWidth));
908229Snate@binkert.org    if (wbWidth > Impl::MaxWidth)
9113570Sbrandon.potter@amd.com        fatal("wbWidth (%d) is larger than compiled limit (%d),\n"
928229Snate@binkert.org             "\tincrease MaxWidth in src/cpu/o3/impl.hh\n",
9311594Santhony.gutierrez@amd.com             wbWidth, static_cast<int>(Impl::MaxWidth));
947075Snate@binkert.org
958229Snate@binkert.org    _status = Active;
9611856Sbrandon.potter@amd.com    exeStatus = Running;
977075Snate@binkert.org    wbStatus = Idle;
98360SN/A
9912461Sgabeblack@google.com    // Setup wire to read instructions coming from issue.
10011886Sbrandon.potter@amd.com    fromIssue = issueToExecQueue.getWire(-issueToExecuteDelay);
10111800Sbrandon.potter@amd.com
10211392Sbrandon.potter@amd.com    // Instruction queue needs the queue between issue and execute.
10312334Sgabeblack@google.com    instQueue.setIssueToExecuteQueue(&issueToExecQueue);
1041354SN/A
1056216Snate@binkert.org    for (ThreadID tid = 0; tid < numThreads; tid++) {
1066658Snate@binkert.org        dispatchStatus[tid] = Running;
1072474SN/A        stalls[tid].commit = false;
1082680Sktlim@umich.edu        fetchRedirect[tid] = false;
1098229Snate@binkert.org    }
11011886Sbrandon.potter@amd.com
11110496Ssteve.reinhardt@amd.com    wbMax = wbWidth * params->wbDepth;
11211911SBrandon.Potter@amd.com
1138229Snate@binkert.org    updateLSQNextCycle = false;
11411794Sbrandon.potter@amd.com
11511886Sbrandon.potter@amd.com    ableToIssue = true;
11610497Ssteve.reinhardt@amd.com
11711794Sbrandon.potter@amd.com    skidBufferMax = (3 * (renameToIEWDelay * params->renameWidth)) + issueWidth;
118360SN/A}
11913629SAndrea.Mondelli@ucf.edu
12013629SAndrea.Mondelli@ucf.edutemplate <class Impl>
12113629SAndrea.Mondelli@ucf.edustd::string
12213629SAndrea.Mondelli@ucf.eduDefaultIEW<Impl>::name() const
123360SN/A{
124360SN/A    return cpu->name() + ".iew";
125360SN/A}
126360SN/A
127360SN/Atemplate <class Impl>
128360SN/Avoid
129360SN/ADefaultIEW<Impl>::regProbePoints()
130360SN/A{
131360SN/A    ppDispatch = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Dispatch");
132378SN/A    ppMispredict = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Mispredict");
1331706SN/A}
13411851Sbrandon.potter@amd.com
135378SN/Atemplate <class Impl>
136378SN/Avoid
137378SN/ADefaultIEW<Impl>::regStats()
138378SN/A{
139378SN/A    using namespace Stats;
1401706SN/A
14111851Sbrandon.potter@amd.com    instQueue.regStats();
142360SN/A    ldstQueue.regStats();
14311760Sbrandon.potter@amd.com
14411760Sbrandon.potter@amd.com    iewIdleCycles
14511851Sbrandon.potter@amd.com        .name(name() + ".iewIdleCycles")
14611760Sbrandon.potter@amd.com        .desc("Number of cycles IEW is idle");
1476109Ssanchezd@stanford.edu
1481706SN/A    iewSquashCycles
14911851Sbrandon.potter@amd.com        .name(name() + ".iewSquashCycles")
150378SN/A        .desc("Number of cycles IEW is squashing");
1516109Ssanchezd@stanford.edu
1526109Ssanchezd@stanford.edu    iewBlockCycles
15311851Sbrandon.potter@amd.com        .name(name() + ".iewBlockCycles")
1546109Ssanchezd@stanford.edu        .desc("Number of cycles IEW is blocking");
15511886Sbrandon.potter@amd.com
15611886Sbrandon.potter@amd.com    iewUnblockCycles
15711886Sbrandon.potter@amd.com        .name(name() + ".iewUnblockCycles")
15811886Sbrandon.potter@amd.com        .desc("Number of cycles IEW is unblocking");
159378SN/A
1601706SN/A    iewDispatchedInsts
16111851Sbrandon.potter@amd.com        .name(name() + ".iewDispatchedInsts")
162378SN/A        .desc("Number of instructions dispatched to IQ");
1635748SSteve.Reinhardt@amd.com
1645748SSteve.Reinhardt@amd.com    iewDispSquashedInsts
16511851Sbrandon.potter@amd.com        .name(name() + ".iewDispSquashedInsts")
166378SN/A        .desc("Number of squashed instructions skipped by dispatch");
167378SN/A
1681706SN/A    iewDispLoadInsts
16911851Sbrandon.potter@amd.com        .name(name() + ".iewDispLoadInsts")
170378SN/A        .desc("Number of dispatched load instructions");
171378SN/A
1721706SN/A    iewDispStoreInsts
17311851Sbrandon.potter@amd.com        .name(name() + ".iewDispStoreInsts")
174378SN/A        .desc("Number of dispatched store instructions");
1754118Sgblack@eecs.umich.edu
1764118Sgblack@eecs.umich.edu    iewDispNonSpecInsts
17711851Sbrandon.potter@amd.com        .name(name() + ".iewDispNonSpecInsts")
1784118Sgblack@eecs.umich.edu        .desc("Number of dispatched non-speculative instructions");
179378SN/A
1801706SN/A    iewIQFullEvents
18111851Sbrandon.potter@amd.com        .name(name() + ".iewIQFullEvents")
182378SN/A        .desc("Number of times the IQ has become full, causing a stall");
18313568Sbrandon.potter@amd.com
18413568Sbrandon.potter@amd.com    iewLSQFullEvents
18513568Sbrandon.potter@amd.com        .name(name() + ".iewLSQFullEvents")
18613568Sbrandon.potter@amd.com        .desc("Number of times the LSQ has become full, causing a stall");
187378SN/A
1881706SN/A    memOrderViolationEvents
18911851Sbrandon.potter@amd.com        .name(name() + ".memOrderViolationEvents")
190360SN/A        .desc("Number of memory order violations");
1915513SMichael.Adler@intel.com
1925513SMichael.Adler@intel.com    predictedTakenIncorrect
19311851Sbrandon.potter@amd.com        .name(name() + ".predictedTakenIncorrect")
1945513SMichael.Adler@intel.com        .desc("Number of branches that were predicted taken incorrectly");
19510203SAli.Saidi@ARM.com
19610203SAli.Saidi@ARM.com    predictedNotTakenIncorrect
19711851Sbrandon.potter@amd.com        .name(name() + ".predictedNotTakenIncorrect")
19810203SAli.Saidi@ARM.com        .desc("Number of branches that were predicted not taken incorrectly");
1995513SMichael.Adler@intel.com
20011851Sbrandon.potter@amd.com    branchMispredicts
2015513SMichael.Adler@intel.com        .name(name() + ".branchMispredicts")
202511SN/A        .desc("Number of branch mispredicts detected at execute");
20310633Smichaelupton@gmail.com
20411851Sbrandon.potter@amd.com    branchMispredicts = predictedTakenIncorrect + predictedNotTakenIncorrect;
20510633Smichaelupton@gmail.com
2061706SN/A    iewExecutedInsts
20711851Sbrandon.potter@amd.com        .name(name() + ".iewExecutedInsts")
208511SN/A        .desc("Number of executed instructions");
20912795Smattdsinclair@gmail.com
21012795Smattdsinclair@gmail.com    iewExecLoadInsts
21112795Smattdsinclair@gmail.com        .init(cpu->numThreads)
21212795Smattdsinclair@gmail.com        .name(name() + ".iewExecLoadInsts")
21312796Smattdsinclair@gmail.com        .desc("Number of load instructions executed")
21412796Smattdsinclair@gmail.com        .flags(total);
21512796Smattdsinclair@gmail.com
21612796Smattdsinclair@gmail.com    iewExecSquashedInsts
2175513SMichael.Adler@intel.com        .name(name() + ".iewExecSquashedInsts")
2185513SMichael.Adler@intel.com        .desc("Number of squashed instructions skipped in execute");
21911851Sbrandon.potter@amd.com
2205513SMichael.Adler@intel.com    iewExecutedSwp
22113031Sbrandon.potter@amd.com        .init(cpu->numThreads)
22213031Sbrandon.potter@amd.com        .name(name() + ".exec_swp")
22313031Sbrandon.potter@amd.com        .desc("number of swp insts executed")
22413031Sbrandon.potter@amd.com        .flags(total);
22513031Sbrandon.potter@amd.com
22613031Sbrandon.potter@amd.com    iewExecutedNop
22713031Sbrandon.potter@amd.com        .init(cpu->numThreads)
22813031Sbrandon.potter@amd.com        .name(name() + ".exec_nop")
22913031Sbrandon.potter@amd.com        .desc("number of nop insts executed")
23013031Sbrandon.potter@amd.com        .flags(total);
23113031Sbrandon.potter@amd.com
23213031Sbrandon.potter@amd.com    iewExecutedRefs
233511SN/A        .init(cpu->numThreads)
2341706SN/A        .name(name() + ".exec_refs")
23511851Sbrandon.potter@amd.com        .desc("number of memory reference insts executed")
2361706SN/A        .flags(total);
2371706SN/A
2381706SN/A    iewExecutedBranches
2391706SN/A        .init(cpu->numThreads)
24011851Sbrandon.potter@amd.com        .name(name() + ".exec_branches")
2411706SN/A        .desc("Number of branches executed")
2421706SN/A        .flags(total);
2431706SN/A
2441706SN/A    iewExecStoreInsts
24511851Sbrandon.potter@amd.com        .name(name() + ".exec_stores")
2461706SN/A        .desc("Number of stores executed")
247511SN/A        .flags(total);
2486703Svince@csl.cornell.edu    iewExecStoreInsts = iewExecutedRefs - iewExecLoadInsts;
2496703Svince@csl.cornell.edu
25011851Sbrandon.potter@amd.com    iewExecRate
2516703Svince@csl.cornell.edu        .name(name() + ".exec_rate")
2526685Stjones1@inf.ed.ac.uk        .desc("Inst execution rate")
2536685Stjones1@inf.ed.ac.uk        .flags(total);
25411851Sbrandon.potter@amd.com
2556685Stjones1@inf.ed.ac.uk    iewExecRate = iewExecutedInsts / cpu->numCycles;
2566685Stjones1@inf.ed.ac.uk
2575513SMichael.Adler@intel.com    iewInstsToCommit
2585513SMichael.Adler@intel.com        .init(cpu->numThreads)
25911851Sbrandon.potter@amd.com        .name(name() + ".wb_sent")
2605513SMichael.Adler@intel.com        .desc("cumulative count of insts sent to commit")
26111885Sbrandon.potter@amd.com        .flags(total);
26211885Sbrandon.potter@amd.com
26311885Sbrandon.potter@amd.com    writebackCount
2645513SMichael.Adler@intel.com        .init(cpu->numThreads)
2651999SN/A        .name(name() + ".wb_count")
2661999SN/A        .desc("cumulative count of insts written-back")
26711851Sbrandon.potter@amd.com        .flags(total);
2681999SN/A
26911885Sbrandon.potter@amd.com    producerInst
27011885Sbrandon.potter@amd.com        .init(cpu->numThreads)
27111885Sbrandon.potter@amd.com        .name(name() + ".wb_producers")
2721999SN/A        .desc("num instructions producing a value")
2731999SN/A        .flags(total);
2741999SN/A
27511851Sbrandon.potter@amd.com    consumerInst
2761999SN/A        .init(cpu->numThreads)
2773079Sstever@eecs.umich.edu        .name(name() + ".wb_consumers")
2783079Sstever@eecs.umich.edu        .desc("num instructions consuming a value")
27911851Sbrandon.potter@amd.com        .flags(total);
2803079Sstever@eecs.umich.edu
28111908SBrandon.Potter@amd.com    wbPenalized
28211908SBrandon.Potter@amd.com        .init(cpu->numThreads)
28311908SBrandon.Potter@amd.com        .name(name() + ".wb_penalized")
28411908SBrandon.Potter@amd.com        .desc("number of instrctions required to write to 'other' IQ")
28511875Sbrandon.potter@amd.com        .flags(total);
2862093SN/A
28711851Sbrandon.potter@amd.com    wbPenalizedRate
2882093SN/A        .name(name() + ".wb_penalized_rate")
2892687Sksewell@umich.edu        .desc ("fraction of instructions written-back that wrote to 'other' IQ")
2902687Sksewell@umich.edu        .flags(total);
29111851Sbrandon.potter@amd.com
2922687Sksewell@umich.edu    wbPenalizedRate = wbPenalized / writebackCount;
2932238SN/A
2942238SN/A    wbFanout
29511851Sbrandon.potter@amd.com        .name(name() + ".wb_fanout")
2962238SN/A        .desc("average fanout of values written-back")
29711908SBrandon.Potter@amd.com        .flags(total);
29811908SBrandon.Potter@amd.com
29911908SBrandon.Potter@amd.com    wbFanout = producerInst / consumerInst;
30011908SBrandon.Potter@amd.com
30111908SBrandon.Potter@amd.com    wbRate
30211908SBrandon.Potter@amd.com        .name(name() + ".wb_rate")
30311908SBrandon.Potter@amd.com        .desc("insts written-back per cycle")
30411908SBrandon.Potter@amd.com        .flags(total);
3052238SN/A    wbRate = writebackCount / cpu->numCycles;
3062238SN/A}
30711851Sbrandon.potter@amd.com
3082238SN/Atemplate<class Impl>
30913571Sbrandon.potter@amd.comvoid
31013571Sbrandon.potter@amd.comDefaultIEW<Impl>::startupStage()
31113571Sbrandon.potter@amd.com{
31213571Sbrandon.potter@amd.com    for (ThreadID tid = 0; tid < numThreads; tid++) {
31313568Sbrandon.potter@amd.com        toRename->iewInfo[tid].usedIQ = true;
31413568Sbrandon.potter@amd.com        toRename->iewInfo[tid].freeIQEntries =
31513568Sbrandon.potter@amd.com            instQueue.numFreeEntries(tid);
31613568Sbrandon.potter@amd.com
31713568Sbrandon.potter@amd.com        toRename->iewInfo[tid].usedLSQ = true;
31813568Sbrandon.potter@amd.com        toRename->iewInfo[tid].freeLSQEntries =
31913568Sbrandon.potter@amd.com            ldstQueue.numFreeEntries(tid);
32013568Sbrandon.potter@amd.com    }
32113568Sbrandon.potter@amd.com
32213568Sbrandon.potter@amd.com    // Initialize the checker's dcache port here
32313568Sbrandon.potter@amd.com    if (cpu->checker) {
32413568Sbrandon.potter@amd.com        cpu->checker->setDcachePort(&cpu->getDataPort());
32513448Sciro.santilli@arm.com    }
32613031Sbrandon.potter@amd.com
32713031Sbrandon.potter@amd.com    cpu->activateStage(O3CPU::IEWIdx);
32813031Sbrandon.potter@amd.com}
32913448Sciro.santilli@arm.com
33013031Sbrandon.potter@amd.comtemplate<class Impl>
33113539Sjavier.setoain@arm.comvoid
33213539Sjavier.setoain@arm.comDefaultIEW<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr)
33313539Sjavier.setoain@arm.com{
33413539Sjavier.setoain@arm.com    timeBuffer = tb_ptr;
33513539Sjavier.setoain@arm.com
33613539Sjavier.setoain@arm.com    // Setup wire to read information from time buffer, from commit.
33713569Sbrandon.potter@amd.com    fromCommit = timeBuffer->getWire(-commitToIEWDelay);
33813569Sbrandon.potter@amd.com
33913569Sbrandon.potter@amd.com    // Setup wire to write information back to previous stages.
34013569Sbrandon.potter@amd.com    toRename = timeBuffer->getWire(0);
34113569Sbrandon.potter@amd.com
34213569Sbrandon.potter@amd.com    toFetch = timeBuffer->getWire(0);
34313569Sbrandon.potter@amd.com
34413569Sbrandon.potter@amd.com    // Instruction queue also needs main time buffer.
34513569Sbrandon.potter@amd.com    instQueue.setTimeBuffer(tb_ptr);
34613569Sbrandon.potter@amd.com}
34713569Sbrandon.potter@amd.com
34813569Sbrandon.potter@amd.comtemplate<class Impl>
34913569Sbrandon.potter@amd.comvoid
35013569Sbrandon.potter@amd.comDefaultIEW<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr)
35113569Sbrandon.potter@amd.com{
35213569Sbrandon.potter@amd.com    renameQueue = rq_ptr;
35313031Sbrandon.potter@amd.com
3542238SN/A    // Setup wire to read information from rename queue.
35511851Sbrandon.potter@amd.com    fromRename = renameQueue->getWire(-renameToIEWDelay);
3562238SN/A}
3572238SN/A
3582238SN/Atemplate<class Impl>
35911851Sbrandon.potter@amd.comvoid
3602238SN/ADefaultIEW<Impl>::setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr)
3612238SN/A{
3622238SN/A    iewQueue = iq_ptr;
36311851Sbrandon.potter@amd.com
3642238SN/A    // Setup wire to write instructions to commit.
3652238SN/A    toCommit = iewQueue->getWire(0);
3662238SN/A}
36711851Sbrandon.potter@amd.com
3682238SN/Atemplate<class Impl>
3692238SN/Avoid
3702238SN/ADefaultIEW<Impl>::setActiveThreads(list<ThreadID> *at_ptr)
37111851Sbrandon.potter@amd.com{
3722238SN/A    activeThreads = at_ptr;
3739455Smitch.hayenga+gem5@gmail.com
3749455Smitch.hayenga+gem5@gmail.com    ldstQueue.setActiveThreads(at_ptr);
37511851Sbrandon.potter@amd.com    instQueue.setActiveThreads(at_ptr);
37610203SAli.Saidi@ARM.com}
37711851Sbrandon.potter@amd.com
37811851Sbrandon.potter@amd.comtemplate<class Impl>
3799455Smitch.hayenga+gem5@gmail.comvoid
38013571Sbrandon.potter@amd.comDefaultIEW<Impl>::setScoreboard(Scoreboard *sb_ptr)
38113571Sbrandon.potter@amd.com{
38213571Sbrandon.potter@amd.com    scoreboard = sb_ptr;
38313571Sbrandon.potter@amd.com}
38413571Sbrandon.potter@amd.com
38513571Sbrandon.potter@amd.comtemplate <class Impl>
38613571Sbrandon.potter@amd.combool
38713571Sbrandon.potter@amd.comDefaultIEW<Impl>::isDrained() const
38813571Sbrandon.potter@amd.com{
38913571Sbrandon.potter@amd.com    bool drained(ldstQueue.isDrained());
39013571Sbrandon.potter@amd.com
39113571Sbrandon.potter@amd.com    for (ThreadID tid = 0; tid < numThreads; tid++) {
3929112Smarc.orr@gmail.com        if (!insts[tid].empty()) {
39311906SBrandon.Potter@amd.com            DPRINTF(Drain, "%i: Insts not empty.\n", tid);
39411906SBrandon.Potter@amd.com            drained = false;
3959112Smarc.orr@gmail.com        }
3969112Smarc.orr@gmail.com        if (!skidBuffer[tid].empty()) {
39711851Sbrandon.potter@amd.com            DPRINTF(Drain, "%i: Skid buffer not empty.\n", tid);
3989112Smarc.orr@gmail.com            drained = false;
3999112Smarc.orr@gmail.com        }
40011911SBrandon.Potter@amd.com    }
4019112Smarc.orr@gmail.com
40211911SBrandon.Potter@amd.com    // Also check the FU pool as instructions are "stored" in FU
40311911SBrandon.Potter@amd.com    // completion events until they are done and not accounted for
40411911SBrandon.Potter@amd.com    // above
40511911SBrandon.Potter@amd.com    if (drained && !fuPool->isDrained()) {
40613642Sqtt2@cornell.edu        DPRINTF(Drain, "FU pool still busy.\n");
40713642Sqtt2@cornell.edu        drained = false;
40813642Sqtt2@cornell.edu    }
4099112Smarc.orr@gmail.com
41011911SBrandon.Potter@amd.com    return drained;
41111911SBrandon.Potter@amd.com}
41211911SBrandon.Potter@amd.com
41311911SBrandon.Potter@amd.comtemplate <class Impl>
4149238Slluc.alvarez@bsc.esvoid
41513642Sqtt2@cornell.eduDefaultIEW<Impl>::drainSanityCheck() const
4169112Smarc.orr@gmail.com{
41711911SBrandon.Potter@amd.com    assert(isDrained());
4189112Smarc.orr@gmail.com
41913642Sqtt2@cornell.edu    instQueue.drainSanityCheck();
42011911SBrandon.Potter@amd.com    ldstQueue.drainSanityCheck();
42111911SBrandon.Potter@amd.com}
42211911SBrandon.Potter@amd.com
42311911SBrandon.Potter@amd.comtemplate <class Impl>
4249112Smarc.orr@gmail.comvoid
42511911SBrandon.Potter@amd.comDefaultIEW<Impl>::takeOverFrom()
42611911SBrandon.Potter@amd.com{
42711911SBrandon.Potter@amd.com    // Reset all state.
42811911SBrandon.Potter@amd.com    _status = Active;
42911911SBrandon.Potter@amd.com    exeStatus = Running;
43011911SBrandon.Potter@amd.com    wbStatus = Idle;
4319112Smarc.orr@gmail.com
4329112Smarc.orr@gmail.com    instQueue.takeOverFrom();
43313642Sqtt2@cornell.edu    ldstQueue.takeOverFrom();
43413642Sqtt2@cornell.edu    fuPool->takeOverFrom();
43513642Sqtt2@cornell.edu
43613642Sqtt2@cornell.edu    startupStage();
43713642Sqtt2@cornell.edu    cpu->activityThisCycle();
43811911SBrandon.Potter@amd.com
4399112Smarc.orr@gmail.com    for (ThreadID tid = 0; tid < numThreads; tid++) {
44011911SBrandon.Potter@amd.com        dispatchStatus[tid] = Running;
44111911SBrandon.Potter@amd.com        stalls[tid].commit = false;
44213642Sqtt2@cornell.edu        fetchRedirect[tid] = false;
44313642Sqtt2@cornell.edu    }
44413650Smw828@cornell.edu
44513650Smw828@cornell.edu    updateLSQNextCycle = false;
44613650Smw828@cornell.edu
44713650Smw828@cornell.edu    for (int i = 0; i < issueToExecQueue.getSize(); ++i) {
44813650Smw828@cornell.edu        issueToExecQueue.advance();
44913650Smw828@cornell.edu    }
45013650Smw828@cornell.edu}
45113650Smw828@cornell.edu
45213650Smw828@cornell.edutemplate<class Impl>
45313650Smw828@cornell.eduvoid
45413650Smw828@cornell.eduDefaultIEW<Impl>::squash(ThreadID tid)
45513650Smw828@cornell.edu{
45613650Smw828@cornell.edu    DPRINTF(IEW, "[tid:%i]: Squashing all instructions.\n", tid);
45713650Smw828@cornell.edu
45813651Smw828@cornell.edu    // Tell the IQ to start squashing.
45913651Smw828@cornell.edu    instQueue.squash(tid);
46013651Smw828@cornell.edu
46113651Smw828@cornell.edu    // Tell the LDSTQ to start squashing.
46213651Smw828@cornell.edu    ldstQueue.squash(fromCommit->commitInfo[tid].doneSeqNum, tid);
46313651Smw828@cornell.edu    updatedQueues = true;
46413651Smw828@cornell.edu
46513651Smw828@cornell.edu    // Clear the skid buffer in case it has any data in it.
46613651Smw828@cornell.edu    DPRINTF(IEW, "[tid:%i]: Removing skidbuffer instructions until [sn:%i].\n",
46713651Smw828@cornell.edu            tid, fromCommit->commitInfo[tid].doneSeqNum);
46813651Smw828@cornell.edu
46913651Smw828@cornell.edu    while (!skidBuffer[tid].empty()) {
47013651Smw828@cornell.edu        if (skidBuffer[tid].front()->isLoad() ||
47113651Smw828@cornell.edu            skidBuffer[tid].front()->isStore() ) {
47213651Smw828@cornell.edu            toRename->iewInfo[tid].dispatchedToLSQ++;
47313651Smw828@cornell.edu        }
47413651Smw828@cornell.edu
47513651Smw828@cornell.edu        toRename->iewInfo[tid].dispatched++;
47613651Smw828@cornell.edu
47713651Smw828@cornell.edu        skidBuffer[tid].pop();
47813651Smw828@cornell.edu    }
47913651Smw828@cornell.edu
48013651Smw828@cornell.edu    emptyRenameInsts(tid);
48113651Smw828@cornell.edu}
48213651Smw828@cornell.edu
48313651Smw828@cornell.edutemplate<class Impl>
48413651Smw828@cornell.eduvoid
48513651Smw828@cornell.eduDefaultIEW<Impl>::squashDueToBranch(DynInstPtr &inst, ThreadID tid)
48613651Smw828@cornell.edu{
48713651Smw828@cornell.edu    DPRINTF(IEW, "[tid:%i]: Squashing from a specific instruction, PC: %s "
48813651Smw828@cornell.edu            "[sn:%i].\n", tid, inst->pcState(), inst->seqNum);
48913651Smw828@cornell.edu
49013651Smw828@cornell.edu    if (!toCommit->squash[tid] ||
49113651Smw828@cornell.edu            inst->seqNum < toCommit->squashedSeqNum[tid]) {
49213651Smw828@cornell.edu        toCommit->squash[tid] = true;
49313651Smw828@cornell.edu        toCommit->squashedSeqNum[tid] = inst->seqNum;
49413651Smw828@cornell.edu        toCommit->branchTaken[tid] = inst->pcState().branching();
49513651Smw828@cornell.edu
49613651Smw828@cornell.edu        TheISA::PCState pc = inst->pcState();
49713651Smw828@cornell.edu        TheISA::advancePC(pc, inst->staticInst);
49813651Smw828@cornell.edu
49913651Smw828@cornell.edu        toCommit->pc[tid] = pc;
50013651Smw828@cornell.edu        toCommit->mispredictInst[tid] = inst;
50113651Smw828@cornell.edu        toCommit->includeSquashInst[tid] = false;
50213651Smw828@cornell.edu
50313651Smw828@cornell.edu        wroteToTimeBuffer = true;
50413651Smw828@cornell.edu    }
50513651Smw828@cornell.edu
50613651Smw828@cornell.edu}
50713651Smw828@cornell.edu
50813651Smw828@cornell.edutemplate<class Impl>
50913651Smw828@cornell.eduvoid
51013651Smw828@cornell.eduDefaultIEW<Impl>::squashDueToMemOrder(DynInstPtr &inst, ThreadID tid)
51113651Smw828@cornell.edu{
51213651Smw828@cornell.edu    DPRINTF(IEW, "[tid:%i]: Memory violation, squashing violator and younger "
51313651Smw828@cornell.edu            "insts, PC: %s [sn:%i].\n", tid, inst->pcState(), inst->seqNum);
51413651Smw828@cornell.edu    // Need to include inst->seqNum in the following comparison to cover the
51513651Smw828@cornell.edu    // corner case when a branch misprediction and a memory violation for the
51613651Smw828@cornell.edu    // same instruction (e.g. load PC) are detected in the same cycle.  In this
51713651Smw828@cornell.edu    // case the memory violator should take precedence over the branch
51813651Smw828@cornell.edu    // misprediction because it requires the violator itself to be included in
51913651Smw828@cornell.edu    // the squash.
52013651Smw828@cornell.edu    if (!toCommit->squash[tid] ||
52113651Smw828@cornell.edu            inst->seqNum <= toCommit->squashedSeqNum[tid]) {
52213651Smw828@cornell.edu        toCommit->squash[tid] = true;
52313651Smw828@cornell.edu
52413651Smw828@cornell.edu        toCommit->squashedSeqNum[tid] = inst->seqNum;
52513651Smw828@cornell.edu        toCommit->pc[tid] = inst->pcState();
52613651Smw828@cornell.edu        toCommit->mispredictInst[tid] = NULL;
52713651Smw828@cornell.edu
52813651Smw828@cornell.edu        // Must include the memory violator in the squash.
5299112Smarc.orr@gmail.com        toCommit->includeSquashInst[tid] = true;
53011911SBrandon.Potter@amd.com
53111911SBrandon.Potter@amd.com        wroteToTimeBuffer = true;
5329112Smarc.orr@gmail.com    }
5339112Smarc.orr@gmail.com}
5342238SN/A
5352238SN/Atemplate<class Impl>
5362238SN/Avoid
5372238SN/ADefaultIEW<Impl>::squashDueToMemBlocked(DynInstPtr &inst, ThreadID tid)
53811851Sbrandon.potter@amd.com{
5392238SN/A    DPRINTF(IEW, "[tid:%i]: Memory blocked, squashing load and younger insts, "
5402238SN/A            "PC: %s [sn:%i].\n", tid, inst->pcState(), inst->seqNum);
5412238SN/A    if (!toCommit->squash[tid] ||
54211851Sbrandon.potter@amd.com            inst->seqNum < toCommit->squashedSeqNum[tid]) {
5432238SN/A        toCommit->squash[tid] = true;
5442238SN/A
5452238SN/A        toCommit->squashedSeqNum[tid] = inst->seqNum;
54611851Sbrandon.potter@amd.com        toCommit->pc[tid] = inst->pcState();
5472238SN/A        toCommit->mispredictInst[tid] = NULL;
5482238SN/A
5492238SN/A        // Must include the broadcasted SN in the squash.
55011851Sbrandon.potter@amd.com        toCommit->includeSquashInst[tid] = true;
5512238SN/A
5522238SN/A        ldstQueue.setLoadBlockedHandled(tid);
5531354SN/A
5541354SN/A        wroteToTimeBuffer = true;
55510796Sbrandon.potter@amd.com    }
55610796Sbrandon.potter@amd.com}
5571354SN/A
5581354SN/Atemplate<class Impl>
5591354SN/Avoid
5601354SN/ADefaultIEW<Impl>::block(ThreadID tid)
5611354SN/A{
5621354SN/A    DPRINTF(IEW, "[tid:%u]: Blocking.\n", tid);
5631354SN/A
5641354SN/A    if (dispatchStatus[tid] != Blocked &&
5651354SN/A        dispatchStatus[tid] != Unblocking) {
5661354SN/A        toRename->iewBlock[tid] = true;
56710796Sbrandon.potter@amd.com        wroteToTimeBuffer = true;
5681354SN/A    }
56910796Sbrandon.potter@amd.com
5701354SN/A    // Add the current inputs to the skid buffer so they can be
5711354SN/A    // reprocessed when this stage unblocks.
5721354SN/A    skidInsert(tid);
5731354SN/A
57410796Sbrandon.potter@amd.com    dispatchStatus[tid] = Blocked;
57510796Sbrandon.potter@amd.com}
57610796Sbrandon.potter@amd.com
57710796Sbrandon.potter@amd.comtemplate<class Impl>
57810796Sbrandon.potter@amd.comvoid
57910796Sbrandon.potter@amd.comDefaultIEW<Impl>::unblock(ThreadID tid)
58010796Sbrandon.potter@amd.com{
58110796Sbrandon.potter@amd.com    DPRINTF(IEW, "[tid:%i]: Reading instructions out of the skid "
58210796Sbrandon.potter@amd.com            "buffer %u.\n",tid, tid);
58310796Sbrandon.potter@amd.com
58410796Sbrandon.potter@amd.com    // If the skid bufffer is empty, signal back to previous stages to unblock.
585360SN/A    // Also switch status to running.
586360SN/A    if (skidBuffer[tid].empty()) {
587360SN/A        toRename->iewUnblock[tid] = true;
588360SN/A        wroteToTimeBuffer = true;
589360SN/A        DPRINTF(IEW, "[tid:%i]: Done unblocking.\n",tid);
590360SN/A        dispatchStatus[tid] = Running;
591360SN/A    }
59211759Sbrandon.potter@amd.com}
5933113Sgblack@eecs.umich.edu
5943113Sgblack@eecs.umich.edutemplate<class Impl>
5953113Sgblack@eecs.umich.eduvoid
5963113Sgblack@eecs.umich.eduDefaultIEW<Impl>::wakeDependents(DynInstPtr &inst)
5973113Sgblack@eecs.umich.edu{
5983113Sgblack@eecs.umich.edu    instQueue.wakeDependents(inst);
5993113Sgblack@eecs.umich.edu}
6003113Sgblack@eecs.umich.edu
6013113Sgblack@eecs.umich.edutemplate<class Impl>
6023113Sgblack@eecs.umich.eduvoid
6033113Sgblack@eecs.umich.eduDefaultIEW<Impl>::rescheduleMemInst(DynInstPtr &inst)
6043113Sgblack@eecs.umich.edu{
6053113Sgblack@eecs.umich.edu    instQueue.rescheduleMemInst(inst);
60612032Sandreas.sandberg@arm.com}
6073113Sgblack@eecs.umich.edu
6083113Sgblack@eecs.umich.edutemplate<class Impl>
6094189Sgblack@eecs.umich.eduvoid
6104189Sgblack@eecs.umich.eduDefaultIEW<Impl>::replayMemInst(DynInstPtr &inst)
6113113Sgblack@eecs.umich.edu{
6123113Sgblack@eecs.umich.edu    instQueue.replayMemInst(inst);
6133113Sgblack@eecs.umich.edu}
6143113Sgblack@eecs.umich.edu
6158737Skoansin.tan@gmail.comtemplate<class Impl>
6163113Sgblack@eecs.umich.eduvoid
6178737Skoansin.tan@gmail.comDefaultIEW<Impl>::instToCommit(DynInstPtr &inst)
6183277Sgblack@eecs.umich.edu{
6195515SMichael.Adler@intel.com    // This function should not be called after writebackInsts in a
6205515SMichael.Adler@intel.com    // single cycle.  That will cause problems with an instruction
6215515SMichael.Adler@intel.com    // being added to the queue to commit without being processed by
6225515SMichael.Adler@intel.com    // writebackInsts prior to being sent to commit.
6235515SMichael.Adler@intel.com
6248737Skoansin.tan@gmail.com    // First check the time slot that this instruction will write
6253277Sgblack@eecs.umich.edu    // to.  If there are free write ports at the time, then go ahead
6268737Skoansin.tan@gmail.com    // and write the instruction to that time.  If there are not,
6273277Sgblack@eecs.umich.edu    // keep looking back to see where's the first time there's a
6288737Skoansin.tan@gmail.com    // free slot.
6293277Sgblack@eecs.umich.edu    while ((*iewQueue)[wbCycle].insts[wbNumInst]) {
6308737Skoansin.tan@gmail.com        ++wbNumInst;
6313113Sgblack@eecs.umich.edu        if (wbNumInst == wbWidth) {
6323113Sgblack@eecs.umich.edu            ++wbCycle;
6333113Sgblack@eecs.umich.edu            wbNumInst = 0;
6343113Sgblack@eecs.umich.edu        }
6358737Skoansin.tan@gmail.com
6363113Sgblack@eecs.umich.edu        assert((wbCycle * wbWidth + wbNumInst) <= wbMax);
6378737Skoansin.tan@gmail.com    }
6383114Sgblack@eecs.umich.edu
6398737Skoansin.tan@gmail.com    DPRINTF(IEW, "Current wb cycle: %i, width: %i, numInst: %i\nwbActual:%i\n",
6403114Sgblack@eecs.umich.edu            wbCycle, wbWidth, wbNumInst, wbCycle * wbWidth + wbNumInst);
6418737Skoansin.tan@gmail.com    // Add finished instruction to queue to commit.
6423114Sgblack@eecs.umich.edu    (*iewQueue)[wbCycle].insts[wbNumInst] = inst;
6438737Skoansin.tan@gmail.com    (*iewQueue)[wbCycle].size++;
64411906SBrandon.Potter@amd.com}
6454061Sgblack@eecs.umich.edu
6464061Sgblack@eecs.umich.edutemplate <class Impl>
6478737Skoansin.tan@gmail.comunsigned
6483113Sgblack@eecs.umich.eduDefaultIEW<Impl>::validInstsFromRename()
6498737Skoansin.tan@gmail.com{
6503113Sgblack@eecs.umich.edu    unsigned inst_count = 0;
6513113Sgblack@eecs.umich.edu
6523113Sgblack@eecs.umich.edu    for (int i=0; i<fromRename->size; i++) {
6533113Sgblack@eecs.umich.edu        if (!fromRename->insts[i]->isSquashed())
6543113Sgblack@eecs.umich.edu            inst_count++;
65512032Sandreas.sandberg@arm.com    }
6563113Sgblack@eecs.umich.edu
6573113Sgblack@eecs.umich.edu    return inst_count;
6584189Sgblack@eecs.umich.edu}
6594189Sgblack@eecs.umich.edu
6603113Sgblack@eecs.umich.edutemplate<class Impl>
6613113Sgblack@eecs.umich.eduvoid
6623113Sgblack@eecs.umich.eduDefaultIEW<Impl>::skidInsert(ThreadID tid)
6638737Skoansin.tan@gmail.com{
6643113Sgblack@eecs.umich.edu    DynInstPtr inst = NULL;
6658737Skoansin.tan@gmail.com
6663113Sgblack@eecs.umich.edu    while (!insts[tid].empty()) {
6678737Skoansin.tan@gmail.com        inst = insts[tid].front();
6683113Sgblack@eecs.umich.edu
6693113Sgblack@eecs.umich.edu        insts[tid].pop();
6703113Sgblack@eecs.umich.edu
6713113Sgblack@eecs.umich.edu        DPRINTF(IEW,"[tid:%i]: Inserting [sn:%lli] PC:%s into "
6723113Sgblack@eecs.umich.edu                "dispatch skidBuffer %i\n",tid, inst->seqNum,
6733113Sgblack@eecs.umich.edu                inst->pcState(),tid);
6743113Sgblack@eecs.umich.edu
67511906SBrandon.Potter@amd.com        skidBuffer[tid].push(inst);
6763113Sgblack@eecs.umich.edu    }
67712032Sandreas.sandberg@arm.com
6788852Sandreas.hansson@arm.com    assert(skidBuffer[tid].size() <= skidBufferMax &&
67911906SBrandon.Potter@amd.com           "Skidbuffer Exceeded Max Size");
6803113Sgblack@eecs.umich.edu}
6813113Sgblack@eecs.umich.edu
6823113Sgblack@eecs.umich.edutemplate<class Impl>
6833113Sgblack@eecs.umich.eduint
6843113Sgblack@eecs.umich.eduDefaultIEW<Impl>::skidCount()
6853113Sgblack@eecs.umich.edu{
6863113Sgblack@eecs.umich.edu    int max=0;
6873113Sgblack@eecs.umich.edu
68812032Sandreas.sandberg@arm.com    list<ThreadID>::iterator threads = activeThreads->begin();
6898852Sandreas.hansson@arm.com    list<ThreadID>::iterator end = activeThreads->end();
69011906SBrandon.Potter@amd.com
6913113Sgblack@eecs.umich.edu    while (threads != end) {
6923113Sgblack@eecs.umich.edu        ThreadID tid = *threads++;
6933113Sgblack@eecs.umich.edu        unsigned thread_count = skidBuffer[tid].size();
6946686Stjones1@inf.ed.ac.uk        if (max < thread_count)
6953113Sgblack@eecs.umich.edu            max = thread_count;
6963113Sgblack@eecs.umich.edu    }
6973113Sgblack@eecs.umich.edu
69811759Sbrandon.potter@amd.com    return max;
69912032Sandreas.sandberg@arm.com}
70011759Sbrandon.potter@amd.com
70111759Sbrandon.potter@amd.comtemplate<class Impl>
70211759Sbrandon.potter@amd.combool
70311759Sbrandon.potter@amd.comDefaultIEW<Impl>::skidsEmpty()
70411759Sbrandon.potter@amd.com{
70511812Sbaz21@cam.ac.uk    list<ThreadID>::iterator threads = activeThreads->begin();
70611812Sbaz21@cam.ac.uk    list<ThreadID>::iterator end = activeThreads->end();
70711812Sbaz21@cam.ac.uk
70811759Sbrandon.potter@amd.com    while (threads != end) {
70911812Sbaz21@cam.ac.uk        ThreadID tid = *threads++;
71011759Sbrandon.potter@amd.com
71111759Sbrandon.potter@amd.com        if (!skidBuffer[tid].empty())
71211759Sbrandon.potter@amd.com            return false;
71311759Sbrandon.potter@amd.com    }
71411759Sbrandon.potter@amd.com
71511759Sbrandon.potter@amd.com    return true;
71611759Sbrandon.potter@amd.com}
71711812Sbaz21@cam.ac.uk
71811812Sbaz21@cam.ac.uktemplate <class Impl>
71911812Sbaz21@cam.ac.ukvoid
72011812Sbaz21@cam.ac.ukDefaultIEW<Impl>::updateStatus()
72111812Sbaz21@cam.ac.uk{
72211812Sbaz21@cam.ac.uk    bool any_unblocking = false;
72311812Sbaz21@cam.ac.uk
72411759Sbrandon.potter@amd.com    list<ThreadID>::iterator threads = activeThreads->begin();
72511759Sbrandon.potter@amd.com    list<ThreadID>::iterator end = activeThreads->end();
72611812Sbaz21@cam.ac.uk
72711812Sbaz21@cam.ac.uk    while (threads != end) {
72811759Sbrandon.potter@amd.com        ThreadID tid = *threads++;
72911812Sbaz21@cam.ac.uk
73011812Sbaz21@cam.ac.uk        if (dispatchStatus[tid] == Unblocking) {
73111812Sbaz21@cam.ac.uk            any_unblocking = true;
73211812Sbaz21@cam.ac.uk            break;
73311812Sbaz21@cam.ac.uk        }
73411812Sbaz21@cam.ac.uk    }
73511812Sbaz21@cam.ac.uk
73611759Sbrandon.potter@amd.com    // If there are no ready instructions waiting to be scheduled by the IQ,
73711759Sbrandon.potter@amd.com    // and there's no stores waiting to write back, and dispatch is not
73811759Sbrandon.potter@amd.com    // unblocking, then there is no internal activity for the IEW stage.
73911759Sbrandon.potter@amd.com    instQueue.intInstQueueReads++;
740378SN/A    if (_status == Active && !instQueue.hasReadyInsts() &&
741378SN/A        !ldstQueue.willWB() && !any_unblocking) {
7429141Smarc.orr@gmail.com        DPRINTF(IEW, "IEW switching to idle\n");
7439141Smarc.orr@gmail.com
744360SN/A        deactivateStage();
7451450SN/A
74611856Sbrandon.potter@amd.com        _status = Inactive;
747360SN/A    } else if (_status == Inactive && (instQueue.hasReadyInsts() ||
7486701Sgblack@eecs.umich.edu                                       ldstQueue.willWB() ||
74911856Sbrandon.potter@amd.com                                       any_unblocking)) {
75011856Sbrandon.potter@amd.com        // Otherwise there is internal activity.  Set to active.
751360SN/A        DPRINTF(IEW, "IEW switching to active\n");
75210930Sbrandon.potter@amd.com
753360SN/A        activateStage();
75411856Sbrandon.potter@amd.com
75511856Sbrandon.potter@amd.com        _status = Active;
75610496Ssteve.reinhardt@amd.com    }
75711856Sbrandon.potter@amd.com}
75811856Sbrandon.potter@amd.com
7591458SN/Atemplate <class Impl>
760360SN/Avoid
76111856Sbrandon.potter@amd.comDefaultIEW<Impl>::resetEntries()
76211856Sbrandon.potter@amd.com{
76311856Sbrandon.potter@amd.com    instQueue.resetEntries();
76411856Sbrandon.potter@amd.com    ldstQueue.resetEntries();
76511856Sbrandon.potter@amd.com}
76611856Sbrandon.potter@amd.com
76711856Sbrandon.potter@amd.comtemplate <class Impl>
76811856Sbrandon.potter@amd.comvoid
76910496Ssteve.reinhardt@amd.comDefaultIEW<Impl>::readStallSignals(ThreadID tid)
77011856Sbrandon.potter@amd.com{
77111856Sbrandon.potter@amd.com    if (fromCommit->commitBlock[tid]) {
77211856Sbrandon.potter@amd.com        stalls[tid].commit = true;
77311856Sbrandon.potter@amd.com    }
77411856Sbrandon.potter@amd.com
77510930Sbrandon.potter@amd.com    if (fromCommit->commitUnblock[tid]) {
7769141Smarc.orr@gmail.com        assert(stalls[tid].commit);
777360SN/A        stalls[tid].commit = false;
778360SN/A    }
779360SN/A}
78011907SBrandon.Potter@amd.com
78111907SBrandon.Potter@amd.comtemplate <class Impl>
78211907SBrandon.Potter@amd.combool
783360SN/ADefaultIEW<Impl>::checkStall(ThreadID tid)
78411907SBrandon.Potter@amd.com{
78511907SBrandon.Potter@amd.com    bool ret_val(false);
78611907SBrandon.Potter@amd.com
78711907SBrandon.Potter@amd.com    if (stalls[tid].commit) {
78811907SBrandon.Potter@amd.com        DPRINTF(IEW,"[tid:%i]: Stall from Commit stage detected.\n",tid);
78911907SBrandon.Potter@amd.com        ret_val = true;
79011907SBrandon.Potter@amd.com    } else if (instQueue.isFull(tid)) {
79111907SBrandon.Potter@amd.com        DPRINTF(IEW,"[tid:%i]: Stall: IQ  is full.\n",tid);
79211907SBrandon.Potter@amd.com        ret_val = true;
79311907SBrandon.Potter@amd.com    } else if (ldstQueue.isFull(tid)) {
79411907SBrandon.Potter@amd.com        DPRINTF(IEW,"[tid:%i]: Stall: LSQ is full\n",tid);
79511907SBrandon.Potter@amd.com
79611907SBrandon.Potter@amd.com        if (ldstQueue.numLoads(tid) > 0 ) {
79711907SBrandon.Potter@amd.com
798360SN/A            DPRINTF(IEW,"[tid:%i]: LSQ oldest load: [sn:%i] \n",
79911907SBrandon.Potter@amd.com                    tid,ldstQueue.getLoadHeadSeqNum(tid));
8001458SN/A        }
801360SN/A
80211907SBrandon.Potter@amd.com        if (ldstQueue.numStores(tid) > 0) {
80311907SBrandon.Potter@amd.com
80411907SBrandon.Potter@amd.com            DPRINTF(IEW,"[tid:%i]: LSQ oldest store: [sn:%i] \n",
80511907SBrandon.Potter@amd.com                    tid,ldstQueue.getStoreHeadSeqNum(tid));
80611907SBrandon.Potter@amd.com        }
80711907SBrandon.Potter@amd.com
80811907SBrandon.Potter@amd.com        ret_val = true;
80911907SBrandon.Potter@amd.com    } else if (ldstQueue.isStalled(tid)) {
81011907SBrandon.Potter@amd.com        DPRINTF(IEW,"[tid:%i]: Stall: LSQ stall detected.\n",tid);
81111907SBrandon.Potter@amd.com        ret_val = true;
812360SN/A    }
81311907SBrandon.Potter@amd.com
81411907SBrandon.Potter@amd.com    return ret_val;
81511907SBrandon.Potter@amd.com}
816360SN/A
817360SN/Atemplate <class Impl>
81811907SBrandon.Potter@amd.comvoid
81911907SBrandon.Potter@amd.comDefaultIEW<Impl>::checkSignalsAndUpdate(ThreadID tid)
82011907SBrandon.Potter@amd.com{
82111907SBrandon.Potter@amd.com    // Check if there's a squash signal, squash if there is
822360SN/A    // Check stall signals, block if there is.
82311907SBrandon.Potter@amd.com    // If status was Blocked
824360SN/A    //     if so then go to unblocking
825360SN/A    // If status was Squashing
82611907SBrandon.Potter@amd.com    //     check if squashing is not high.  Switch to running this cycle.
8273669Sbinkertn@umich.edu
82811907SBrandon.Potter@amd.com    readStallSignals(tid);
82911907SBrandon.Potter@amd.com
83011907SBrandon.Potter@amd.com    if (fromCommit->commitInfo[tid].squash) {
83111907SBrandon.Potter@amd.com        squash(tid);
83211907SBrandon.Potter@amd.com
83311907SBrandon.Potter@amd.com        if (dispatchStatus[tid] == Blocked ||
83411907SBrandon.Potter@amd.com            dispatchStatus[tid] == Unblocking) {
83511907SBrandon.Potter@amd.com            toRename->iewUnblock[tid] = true;
83611907SBrandon.Potter@amd.com            wroteToTimeBuffer = true;
83711907SBrandon.Potter@amd.com        }
83811907SBrandon.Potter@amd.com
83911907SBrandon.Potter@amd.com        dispatchStatus[tid] = Squashing;
84011907SBrandon.Potter@amd.com        fetchRedirect[tid] = false;
84111907SBrandon.Potter@amd.com        return;
84211907SBrandon.Potter@amd.com    }
84311907SBrandon.Potter@amd.com
84411907SBrandon.Potter@amd.com    if (fromCommit->commitInfo[tid].robSquashing) {
84511907SBrandon.Potter@amd.com        DPRINTF(IEW, "[tid:%i]: ROB is still squashing.\n", tid);
84611907SBrandon.Potter@amd.com
84713371Sciro.santilli@arm.com        dispatchStatus[tid] = Squashing;
84811907SBrandon.Potter@amd.com        emptyRenameInsts(tid);
8491706SN/A        wroteToTimeBuffer = true;
85011907SBrandon.Potter@amd.com        return;
85111907SBrandon.Potter@amd.com    }
85211907SBrandon.Potter@amd.com
85311907SBrandon.Potter@amd.com    if (checkStall(tid)) {
85411907SBrandon.Potter@amd.com        block(tid);
85511907SBrandon.Potter@amd.com        dispatchStatus[tid] = Blocked;
85610496Ssteve.reinhardt@amd.com        return;
85710496Ssteve.reinhardt@amd.com    }
85811907SBrandon.Potter@amd.com
85911907SBrandon.Potter@amd.com    if (dispatchStatus[tid] == Blocked) {
86011907SBrandon.Potter@amd.com        // Status from previous cycle was blocked, but there are no more stall
86111907SBrandon.Potter@amd.com        // conditions.  Switch over to unblocking.
86211907SBrandon.Potter@amd.com        DPRINTF(IEW, "[tid:%i]: Done blocking, switching to unblocking.\n",
86311907SBrandon.Potter@amd.com                tid);
86410496Ssteve.reinhardt@amd.com
86511907SBrandon.Potter@amd.com        dispatchStatus[tid] = Unblocking;
86611907SBrandon.Potter@amd.com
86711907SBrandon.Potter@amd.com        unblock(tid);
86811907SBrandon.Potter@amd.com
86910496Ssteve.reinhardt@amd.com        return;
87010496Ssteve.reinhardt@amd.com    }
87111907SBrandon.Potter@amd.com
87211907SBrandon.Potter@amd.com    if (dispatchStatus[tid] == Squashing) {
87311907SBrandon.Potter@amd.com        // Switch status to running if rename isn't being told to block or
87411907SBrandon.Potter@amd.com        // squash this cycle.
87511907SBrandon.Potter@amd.com        DPRINTF(IEW, "[tid:%i]: Done squashing, switching to running.\n",
87611907SBrandon.Potter@amd.com                tid);
87711907SBrandon.Potter@amd.com
87811907SBrandon.Potter@amd.com        dispatchStatus[tid] = Running;
87911907SBrandon.Potter@amd.com
88011907SBrandon.Potter@amd.com        return;
88111907SBrandon.Potter@amd.com    }
88211907SBrandon.Potter@amd.com}
88311907SBrandon.Potter@amd.com
88411907SBrandon.Potter@amd.comtemplate <class Impl>
88511907SBrandon.Potter@amd.comvoid
88611907SBrandon.Potter@amd.comDefaultIEW<Impl>::sortInsts()
88711907SBrandon.Potter@amd.com{
88811907SBrandon.Potter@amd.com    int insts_from_rename = fromRename->size;
88911907SBrandon.Potter@amd.com#ifdef DEBUG
89011907SBrandon.Potter@amd.com    for (ThreadID tid = 0; tid < numThreads; tid++)
89111907SBrandon.Potter@amd.com        assert(insts[tid].empty());
89211907SBrandon.Potter@amd.com#endif
89311907SBrandon.Potter@amd.com    for (int i = 0; i < insts_from_rename; ++i) {
89411907SBrandon.Potter@amd.com        insts[fromRename->insts[i]->threadNumber].push(fromRename->insts[i]);
89511907SBrandon.Potter@amd.com    }
896360SN/A}
89711907SBrandon.Potter@amd.com
89811907SBrandon.Potter@amd.comtemplate <class Impl>
89911907SBrandon.Potter@amd.comvoid
90011907SBrandon.Potter@amd.comDefaultIEW<Impl>::emptyRenameInsts(ThreadID tid)
90111907SBrandon.Potter@amd.com{
90211907SBrandon.Potter@amd.com    DPRINTF(IEW, "[tid:%i]: Removing incoming rename instructions\n", tid);
90311907SBrandon.Potter@amd.com
90411907SBrandon.Potter@amd.com    while (!insts[tid].empty()) {
90511907SBrandon.Potter@amd.com
90611907SBrandon.Potter@amd.com        if (insts[tid].front()->isLoad() ||
90711907SBrandon.Potter@amd.com            insts[tid].front()->isStore() ) {
90811907SBrandon.Potter@amd.com            toRename->iewInfo[tid].dispatchedToLSQ++;
90911907SBrandon.Potter@amd.com        }
910360SN/A
911360SN/A        toRename->iewInfo[tid].dispatched++;
91210027SChris.Adeniyi-Jones@arm.com
91310027SChris.Adeniyi-Jones@arm.com        insts[tid].pop();
91410027SChris.Adeniyi-Jones@arm.com    }
91511851Sbrandon.potter@amd.com}
91610027SChris.Adeniyi-Jones@arm.com
91710027SChris.Adeniyi-Jones@arm.comtemplate <class Impl>
91811907SBrandon.Potter@amd.comvoid
91910027SChris.Adeniyi-Jones@arm.comDefaultIEW<Impl>::wakeCPU()
92010027SChris.Adeniyi-Jones@arm.com{
92110027SChris.Adeniyi-Jones@arm.com    cpu->wakeCPU();
92210027SChris.Adeniyi-Jones@arm.com}
92310027SChris.Adeniyi-Jones@arm.com
92411851Sbrandon.potter@amd.comtemplate <class Impl>
92511851Sbrandon.potter@amd.comvoid
92610027SChris.Adeniyi-Jones@arm.comDefaultIEW<Impl>::activityThisCycle()
92711907SBrandon.Potter@amd.com{
92810027SChris.Adeniyi-Jones@arm.com    DPRINTF(Activity, "Activity this cycle.\n");
92910027SChris.Adeniyi-Jones@arm.com    cpu->activityThisCycle();
93010633Smichaelupton@gmail.com}
93110633Smichaelupton@gmail.com
93210633Smichaelupton@gmail.comtemplate <class Impl>
93311851Sbrandon.potter@amd.cominline void
93410633Smichaelupton@gmail.comDefaultIEW<Impl>::activateStage()
93510633Smichaelupton@gmail.com{
93610633Smichaelupton@gmail.com    DPRINTF(Activity, "Activating stage.\n");
93710633Smichaelupton@gmail.com    cpu->activateStage(O3CPU::IEWIdx);
93810633Smichaelupton@gmail.com}
93910633Smichaelupton@gmail.com
94010633Smichaelupton@gmail.comtemplate <class Impl>
94110633Smichaelupton@gmail.cominline void
94210633Smichaelupton@gmail.comDefaultIEW<Impl>::deactivateStage()
94310633Smichaelupton@gmail.com{
94410203SAli.Saidi@ARM.com    DPRINTF(Activity, "Deactivating stage.\n");
94510203SAli.Saidi@ARM.com    cpu->deactivateStage(O3CPU::IEWIdx);
94610203SAli.Saidi@ARM.com}
94711851Sbrandon.potter@amd.com
94811851Sbrandon.potter@amd.comtemplate<class Impl>
94910203SAli.Saidi@ARM.comvoid
95010203SAli.Saidi@ARM.comDefaultIEW<Impl>::dispatch(ThreadID tid)
95110203SAli.Saidi@ARM.com{
95210203SAli.Saidi@ARM.com    // If status is Running or idle,
95310203SAli.Saidi@ARM.com    //     call dispatchInsts()
95410203SAli.Saidi@ARM.com    // If status is Unblocking,
95510203SAli.Saidi@ARM.com    //     buffer any instructions coming from rename
95610203SAli.Saidi@ARM.com    //     continue trying to empty skid buffer
95710203SAli.Saidi@ARM.com    //     check if stall conditions have passed
95810203SAli.Saidi@ARM.com
95910203SAli.Saidi@ARM.com    if (dispatchStatus[tid] == Blocked) {
96011851Sbrandon.potter@amd.com        ++iewBlockCycles;
96111851Sbrandon.potter@amd.com
96210203SAli.Saidi@ARM.com    } else if (dispatchStatus[tid] == Squashing) {
96310203SAli.Saidi@ARM.com        ++iewSquashCycles;
96410203SAli.Saidi@ARM.com    }
96510203SAli.Saidi@ARM.com
96610203SAli.Saidi@ARM.com    // Dispatch should try to dispatch as many instructions as its bandwidth
96710203SAli.Saidi@ARM.com    // will allow, as long as it is not currently blocked.
96810203SAli.Saidi@ARM.com    if (dispatchStatus[tid] == Running ||
96910203SAli.Saidi@ARM.com        dispatchStatus[tid] == Idle) {
97010850SGiacomo.Gabrielli@arm.com        DPRINTF(IEW, "[tid:%i] Not blocked, so attempting to run "
97110850SGiacomo.Gabrielli@arm.com                "dispatch.\n", tid);
97210850SGiacomo.Gabrielli@arm.com
97311851Sbrandon.potter@amd.com        dispatchInsts(tid);
97410850SGiacomo.Gabrielli@arm.com    } else if (dispatchStatus[tid] == Unblocking) {
97510850SGiacomo.Gabrielli@arm.com        // Make sure that the skid buffer has something in it if the
97610850SGiacomo.Gabrielli@arm.com        // status is unblocking.
97710850SGiacomo.Gabrielli@arm.com        assert(!skidsEmpty());
97810850SGiacomo.Gabrielli@arm.com
97910850SGiacomo.Gabrielli@arm.com        // If the status was unblocking, then instructions from the skid
98010850SGiacomo.Gabrielli@arm.com        // buffer were used.  Remove those instructions and handle
98110850SGiacomo.Gabrielli@arm.com        // the rest of unblocking.
98210850SGiacomo.Gabrielli@arm.com        dispatchInsts(tid);
98310850SGiacomo.Gabrielli@arm.com
98410850SGiacomo.Gabrielli@arm.com        ++iewUnblockCycles;
98510850SGiacomo.Gabrielli@arm.com
98610850SGiacomo.Gabrielli@arm.com        if (validInstsFromRename()) {
98710850SGiacomo.Gabrielli@arm.com            // Add the current inputs to the skid buffer so they can be
98810850SGiacomo.Gabrielli@arm.com            // reprocessed when this stage unblocks.
98910850SGiacomo.Gabrielli@arm.com            skidInsert(tid);
99010850SGiacomo.Gabrielli@arm.com        }
99110850SGiacomo.Gabrielli@arm.com
99210850SGiacomo.Gabrielli@arm.com        unblock(tid);
99310850SGiacomo.Gabrielli@arm.com    }
99410850SGiacomo.Gabrielli@arm.com}
99510850SGiacomo.Gabrielli@arm.com
99610850SGiacomo.Gabrielli@arm.comtemplate <class Impl>
99710850SGiacomo.Gabrielli@arm.comvoid
99810850SGiacomo.Gabrielli@arm.comDefaultIEW<Impl>::dispatchInsts(ThreadID tid)
99910850SGiacomo.Gabrielli@arm.com{
100010850SGiacomo.Gabrielli@arm.com    // Obtain instructions from skid buffer if unblocking, or queue from rename
100110850SGiacomo.Gabrielli@arm.com    // otherwise.
100210850SGiacomo.Gabrielli@arm.com    std::queue<DynInstPtr> &insts_to_dispatch =
100310850SGiacomo.Gabrielli@arm.com        dispatchStatus[tid] == Unblocking ?
100410850SGiacomo.Gabrielli@arm.com        skidBuffer[tid] : insts[tid];
100510850SGiacomo.Gabrielli@arm.com
10066640Svince@csl.cornell.edu    int insts_to_add = insts_to_dispatch.size();
10076640Svince@csl.cornell.edu
10086640Svince@csl.cornell.edu    DynInstPtr inst;
100911851Sbrandon.potter@amd.com    bool add_to_iq = false;
101011851Sbrandon.potter@amd.com    int dis_num_inst = 0;
10116640Svince@csl.cornell.edu
10126640Svince@csl.cornell.edu    // Loop through the instructions, putting them in the instruction
10136701Sgblack@eecs.umich.edu    // queue.
10146701Sgblack@eecs.umich.edu    for ( ; dis_num_inst < insts_to_add &&
101510793Sbrandon.potter@amd.com              dis_num_inst < dispatchWidth;
10166640Svince@csl.cornell.edu          ++dis_num_inst)
101711758Sbrandon.potter@amd.com    {
101811758Sbrandon.potter@amd.com        inst = insts_to_dispatch.front();
101911758Sbrandon.potter@amd.com
10206640Svince@csl.cornell.edu        if (dispatchStatus[tid] == Unblocking) {
10218706Sandreas.hansson@arm.com            DPRINTF(IEW, "[tid:%i]: Issue: Examining instruction from skid "
10226640Svince@csl.cornell.edu                    "buffer\n", tid);
10236701Sgblack@eecs.umich.edu        }
10246640Svince@csl.cornell.edu
1025360SN/A        // Make sure there's a valid instruction there.
10261999SN/A        assert(inst);
10271999SN/A
10281999SN/A        DPRINTF(IEW, "[tid:%i]: Issue: Adding PC %s [sn:%lli] [tid:%i] to "
102911851Sbrandon.potter@amd.com                "IQ.\n",
10302680Sktlim@umich.edu                tid, inst->pcState(), inst->seqNum, inst->threadNumber);
10311999SN/A
10321999SN/A        // Be sure to mark these instructions as ready so that the
10331999SN/A        // commit stage can go ahead and execute them, and mark
10346701Sgblack@eecs.umich.edu        // them as issued so the IQ doesn't reprocess them.
10358852Sandreas.hansson@arm.com
10366701Sgblack@eecs.umich.edu        // Check for squashed instructions.
10371999SN/A        if (inst->isSquashed()) {
10386701Sgblack@eecs.umich.edu            DPRINTF(IEW, "[tid:%i]: Issue: Squashed instruction encountered, "
10391999SN/A                    "not adding to IQ.\n", tid);
10406701Sgblack@eecs.umich.edu
10411999SN/A            ++iewDispSquashedInsts;
10421999SN/A
10431999SN/A            insts_to_dispatch.pop();
10441999SN/A
10451999SN/A            //Tell Rename That An Instruction has been processed
10463669Sbinkertn@umich.edu            if (inst->isLoad() || inst->isStore()) {
10473669Sbinkertn@umich.edu                toRename->iewInfo[tid].dispatchedToLSQ++;
10483669Sbinkertn@umich.edu            }
10491999SN/A            toRename->iewInfo[tid].dispatched++;
10501999SN/A
10511999SN/A            continue;
10522218SN/A        }
10531999SN/A
10541999SN/A        // Check for full conditions.
10551999SN/A        if (instQueue.isFull(tid)) {
10561999SN/A            DPRINTF(IEW, "[tid:%i]: Issue: IQ has become full.\n", tid);
105713570Sbrandon.potter@amd.com
105813570Sbrandon.potter@amd.com            // Call function to start blocking.
105913570Sbrandon.potter@amd.com            block(tid);
106013570Sbrandon.potter@amd.com
106113570Sbrandon.potter@amd.com            // Set unblock to false. Special case where we are using
106213570Sbrandon.potter@amd.com            // skidbuffer (unblocking) instructions but then we still
106313570Sbrandon.potter@amd.com            // get full in the IQ.
106413570Sbrandon.potter@amd.com            toRename->iewUnblock[tid] = false;
106513570Sbrandon.potter@amd.com
106613570Sbrandon.potter@amd.com            ++iewIQFullEvents;
106713570Sbrandon.potter@amd.com            break;
106813570Sbrandon.potter@amd.com        } else if (ldstQueue.isFull(tid)) {
106913570Sbrandon.potter@amd.com            DPRINTF(IEW, "[tid:%i]: Issue: LSQ has become full.\n",tid);
107013570Sbrandon.potter@amd.com
107113570Sbrandon.potter@amd.com            // Call function to start blocking.
107213570Sbrandon.potter@amd.com            block(tid);
107313570Sbrandon.potter@amd.com
107413570Sbrandon.potter@amd.com            // Set unblock to false. Special case where we are using
107513570Sbrandon.potter@amd.com            // skidbuffer (unblocking) instructions but then we still
107613570Sbrandon.potter@amd.com            // get full in the IQ.
107713570Sbrandon.potter@amd.com            toRename->iewUnblock[tid] = false;
107813570Sbrandon.potter@amd.com
107913570Sbrandon.potter@amd.com            ++iewLSQFullEvents;
108013570Sbrandon.potter@amd.com            break;
108113570Sbrandon.potter@amd.com        }
108213570Sbrandon.potter@amd.com
108313570Sbrandon.potter@amd.com        // Otherwise issue the instruction just fine.
108413570Sbrandon.potter@amd.com        if (inst->isLoad()) {
108513570Sbrandon.potter@amd.com            DPRINTF(IEW, "[tid:%i]: Issue: Memory instruction "
108613570Sbrandon.potter@amd.com                    "encountered, adding to LSQ.\n", tid);
108713570Sbrandon.potter@amd.com
108813570Sbrandon.potter@amd.com            // Reserve a spot in the load store queue for this
108913570Sbrandon.potter@amd.com            // memory access.
109013570Sbrandon.potter@amd.com            ldstQueue.insertLoad(inst);
109113570Sbrandon.potter@amd.com
109213570Sbrandon.potter@amd.com            ++iewDispLoadInsts;
109313570Sbrandon.potter@amd.com
109413570Sbrandon.potter@amd.com            add_to_iq = true;
109513570Sbrandon.potter@amd.com
109613570Sbrandon.potter@amd.com            toRename->iewInfo[tid].dispatchedToLSQ++;
109713570Sbrandon.potter@amd.com        } else if (inst->isStore()) {
109813570Sbrandon.potter@amd.com            DPRINTF(IEW, "[tid:%i]: Issue: Memory instruction "
109913570Sbrandon.potter@amd.com                    "encountered, adding to LSQ.\n", tid);
110013570Sbrandon.potter@amd.com
110113570Sbrandon.potter@amd.com            ldstQueue.insertStore(inst);
110213570Sbrandon.potter@amd.com
110313570Sbrandon.potter@amd.com            ++iewDispStoreInsts;
110413570Sbrandon.potter@amd.com
110513570Sbrandon.potter@amd.com            if (inst->isStoreConditional()) {
110613570Sbrandon.potter@amd.com                // Store conditionals need to be set as "canCommit()"
110713570Sbrandon.potter@amd.com                // so that commit can process them when they reach the
110813570Sbrandon.potter@amd.com                // head of commit.
110913570Sbrandon.potter@amd.com                // @todo: This is somewhat specific to Alpha.
111013570Sbrandon.potter@amd.com                inst->setCanCommit();
111113570Sbrandon.potter@amd.com                instQueue.insertNonSpec(inst);
111213570Sbrandon.potter@amd.com                add_to_iq = false;
111313570Sbrandon.potter@amd.com
111413570Sbrandon.potter@amd.com                ++iewDispNonSpecInsts;
111513570Sbrandon.potter@amd.com            } else {
111613570Sbrandon.potter@amd.com                add_to_iq = true;
111713570Sbrandon.potter@amd.com            }
111813570Sbrandon.potter@amd.com
111913570Sbrandon.potter@amd.com            toRename->iewInfo[tid].dispatchedToLSQ++;
112013570Sbrandon.potter@amd.com        } else if (inst->isMemBarrier() || inst->isWriteBarrier()) {
112113570Sbrandon.potter@amd.com            // Same as non-speculative stores.
112213570Sbrandon.potter@amd.com            inst->setCanCommit();
112313570Sbrandon.potter@amd.com            instQueue.insertBarrier(inst);
112413570Sbrandon.potter@amd.com            add_to_iq = false;
112513570Sbrandon.potter@amd.com        } else if (inst->isNop()) {
112613570Sbrandon.potter@amd.com            DPRINTF(IEW, "[tid:%i]: Issue: Nop instruction encountered, "
112713570Sbrandon.potter@amd.com                    "skipping.\n", tid);
112813570Sbrandon.potter@amd.com
112913570Sbrandon.potter@amd.com            inst->setIssued();
113013570Sbrandon.potter@amd.com            inst->setExecuted();
11311999SN/A            inst->setCanCommit();
11321999SN/A
11331999SN/A            instQueue.recordProducer(inst);
11341999SN/A
113511856Sbrandon.potter@amd.com            iewExecutedNop[tid]++;
11361999SN/A
11376701Sgblack@eecs.umich.edu            add_to_iq = false;
113811856Sbrandon.potter@amd.com        } else if (inst->isExecuted()) {
113911856Sbrandon.potter@amd.com            assert(0 && "Instruction shouldn't be executed.\n");
114010931Sbrandon.potter@amd.com            DPRINTF(IEW, "Issue: Executed branch encountered, "
114111856Sbrandon.potter@amd.com                    "skipping.\n");
114211856Sbrandon.potter@amd.com
11431999SN/A            inst->setIssued();
114411856Sbrandon.potter@amd.com            inst->setCanCommit();
11451999SN/A
114611856Sbrandon.potter@amd.com            instQueue.recordProducer(inst);
11471999SN/A
114811856Sbrandon.potter@amd.com            add_to_iq = false;
11491999SN/A        } else {
115011856Sbrandon.potter@amd.com            add_to_iq = true;
11511999SN/A        }
11521999SN/A        if (inst->isNonSpeculative()) {
11535877Shsul@eecs.umich.edu            DPRINTF(IEW, "[tid:%i]: Issue: Nonspeculative instruction "
11545877Shsul@eecs.umich.edu                    "encountered, skipping.\n", tid);
11555877Shsul@eecs.umich.edu
115611851Sbrandon.potter@amd.com            // Same as non-speculative stores.
11575877Shsul@eecs.umich.edu            inst->setCanCommit();
11586701Sgblack@eecs.umich.edu
11596701Sgblack@eecs.umich.edu            // Specifically insert it as nonspeculative.
11606701Sgblack@eecs.umich.edu            instQueue.insertNonSpec(inst);
11616701Sgblack@eecs.umich.edu
11626701Sgblack@eecs.umich.edu            ++iewDispNonSpecInsts;
116310027SChris.Adeniyi-Jones@arm.com
116410027SChris.Adeniyi-Jones@arm.com            add_to_iq = false;
116510027SChris.Adeniyi-Jones@arm.com        }
116610027SChris.Adeniyi-Jones@arm.com
116710027SChris.Adeniyi-Jones@arm.com        // If the instruction queue is not full, then add the
11685877Shsul@eecs.umich.edu        // instruction.
116910318Sandreas.hansson@arm.com        if (add_to_iq) {
117010318Sandreas.hansson@arm.com            instQueue.insert(inst);
11715877Shsul@eecs.umich.edu        }
11725877Shsul@eecs.umich.edu
11735877Shsul@eecs.umich.edu        insts_to_dispatch.pop();
11745877Shsul@eecs.umich.edu
117510486Stjablin@gmail.com        toRename->iewInfo[tid].dispatched++;
117610486Stjablin@gmail.com
11775877Shsul@eecs.umich.edu        ++iewDispatchedInsts;
117811905SBrandon.Potter@amd.com
117911905SBrandon.Potter@amd.com#if TRACING_ON
118011905SBrandon.Potter@amd.com        inst->dispatchTick = curTick() - inst->fetchTick;
118111905SBrandon.Potter@amd.com#endif
118210027SChris.Adeniyi-Jones@arm.com        ppDispatch->notify(inst);
118312206Srico.amslinger@informatik.uni-augsburg.de    }
118412206Srico.amslinger@informatik.uni-augsburg.de
11855877Shsul@eecs.umich.edu    if (!insts_to_dispatch.empty()) {
118611905SBrandon.Potter@amd.com        DPRINTF(IEW,"[tid:%i]: Issue: Bandwidth Full. Blocking.\n", tid);
118711905SBrandon.Potter@amd.com        block(tid);
11885877Shsul@eecs.umich.edu        toRename->iewUnblock[tid] = false;
11895877Shsul@eecs.umich.edu    }
119010027SChris.Adeniyi-Jones@arm.com
11915877Shsul@eecs.umich.edu    if (dispatchStatus[tid] == Idle && dis_num_inst) {
11925877Shsul@eecs.umich.edu        dispatchStatus[tid] = Running;
11935877Shsul@eecs.umich.edu
119412206Srico.amslinger@informatik.uni-augsburg.de        updatedQueues = true;
119512206Srico.amslinger@informatik.uni-augsburg.de    }
119612206Srico.amslinger@informatik.uni-augsburg.de
119712206Srico.amslinger@informatik.uni-augsburg.de    dis_num_inst = 0;
119812206Srico.amslinger@informatik.uni-augsburg.de}
119912206Srico.amslinger@informatik.uni-augsburg.de
120012206Srico.amslinger@informatik.uni-augsburg.detemplate <class Impl>
120112206Srico.amslinger@informatik.uni-augsburg.devoid
120212206Srico.amslinger@informatik.uni-augsburg.deDefaultIEW<Impl>::printAvailableInsts()
120310027SChris.Adeniyi-Jones@arm.com{
120410027SChris.Adeniyi-Jones@arm.com    int inst = 0;
120510027SChris.Adeniyi-Jones@arm.com
120610027SChris.Adeniyi-Jones@arm.com    std::cout << "Available Instructions: ";
12075877Shsul@eecs.umich.edu
120810027SChris.Adeniyi-Jones@arm.com    while (fromIssue->insts[inst]) {
120910027SChris.Adeniyi-Jones@arm.com
121010027SChris.Adeniyi-Jones@arm.com        if (inst%3==0) std::cout << "\n\t";
121110027SChris.Adeniyi-Jones@arm.com
121212206Srico.amslinger@informatik.uni-augsburg.de        std::cout << "PC: " << fromIssue->insts[inst]->pcState()
121312206Srico.amslinger@informatik.uni-augsburg.de             << " TN: " << fromIssue->insts[inst]->threadNumber
121412206Srico.amslinger@informatik.uni-augsburg.de             << " SN: " << fromIssue->insts[inst]->seqNum << " | ";
121512206Srico.amslinger@informatik.uni-augsburg.de
121610027SChris.Adeniyi-Jones@arm.com        inst++;
121710027SChris.Adeniyi-Jones@arm.com
121810027SChris.Adeniyi-Jones@arm.com    }
121910027SChris.Adeniyi-Jones@arm.com
122010027SChris.Adeniyi-Jones@arm.com    std::cout << "\n";
122110027SChris.Adeniyi-Jones@arm.com}
12225877Shsul@eecs.umich.edu
12235877Shsul@eecs.umich.edutemplate <class Impl>
12245877Shsul@eecs.umich.eduvoid
122510027SChris.Adeniyi-Jones@arm.comDefaultIEW<Impl>::executeInsts()
122610027SChris.Adeniyi-Jones@arm.com{
12278601Ssteve.reinhardt@amd.com    wbNumInst = 0;
122810027SChris.Adeniyi-Jones@arm.com    wbCycle = 0;
12295877Shsul@eecs.umich.edu
12305877Shsul@eecs.umich.edu    list<ThreadID>::iterator threads = activeThreads->begin();
12311999SN/A    list<ThreadID>::iterator end = activeThreads->end();
1232378SN/A
1233360SN/A    while (threads != end) {
12341450SN/A        ThreadID tid = *threads++;
123511851Sbrandon.potter@amd.com        fetchRedirect[tid] = false;
12362680Sktlim@umich.edu    }
1237360SN/A
1238360SN/A    // Uncomment this if you want to see all available instructions.
1239360SN/A    // @todo This doesn't actually work anymore, we should fix it.
12406701Sgblack@eecs.umich.edu//    printAvailableInsts();
12418852Sandreas.hansson@arm.com
12426701Sgblack@eecs.umich.edu    // Execute/writeback any instructions that are available.
12436701Sgblack@eecs.umich.edu    int insts_to_execute = fromIssue->size;
12446701Sgblack@eecs.umich.edu    int inst_num = 0;
12456701Sgblack@eecs.umich.edu    for (; inst_num < insts_to_execute;
1246360SN/A          ++inst_num) {
12473669Sbinkertn@umich.edu
12483669Sbinkertn@umich.edu        DPRINTF(IEW, "Execute: Executing instructions from IQ.\n");
12493669Sbinkertn@umich.edu
1250360SN/A        DynInstPtr inst = instQueue.getInstToExecute();
1251360SN/A
1252360SN/A        DPRINTF(IEW, "Execute: Processing PC %s, [tid:%i] [sn:%i].\n",
1253360SN/A                inst->pcState(), inst->threadNumber,inst->seqNum);
12542218SN/A
1255360SN/A        // Check if the instruction is squashed; if so then skip it
12568706Sandreas.hansson@arm.com        if (inst->isSquashed()) {
1257360SN/A            DPRINTF(IEW, "Execute: Instruction was squashed. PC: %s, [tid:%i]"
12581458SN/A                         " [sn:%i]\n", inst->pcState(), inst->threadNumber,
1259360SN/A                         inst->seqNum);
1260360SN/A
1261360SN/A            // Consider this instruction executed so that commit can go
12625074Ssaidi@eecs.umich.edu            // ahead and retire the instruction.
12635074Ssaidi@eecs.umich.edu            inst->setExecuted();
12645074Ssaidi@eecs.umich.edu
126511851Sbrandon.potter@amd.com            // Not sure if I should set this here or just let commit try to
12665074Ssaidi@eecs.umich.edu            // commit any squashed instructions.  I like the latter a bit more.
12675074Ssaidi@eecs.umich.edu            inst->setCanCommit();
12685074Ssaidi@eecs.umich.edu
12695074Ssaidi@eecs.umich.edu            ++iewExecSquashedInsts;
12706701Sgblack@eecs.umich.edu
12718852Sandreas.hansson@arm.com            decrWb(inst->seqNum);
12726701Sgblack@eecs.umich.edu            continue;
12735074Ssaidi@eecs.umich.edu        }
12746701Sgblack@eecs.umich.edu
12755074Ssaidi@eecs.umich.edu        Fault fault = NoFault;
12765074Ssaidi@eecs.umich.edu
12775074Ssaidi@eecs.umich.edu        // Execute instruction.
12785074Ssaidi@eecs.umich.edu        // Note that if the instruction faults, it will be handled
12795208Ssaidi@eecs.umich.edu        // at the commit stage.
12805208Ssaidi@eecs.umich.edu        if (inst->isMemRef()) {
12815208Ssaidi@eecs.umich.edu            DPRINTF(IEW, "Execute: Calculating address for memory "
12825208Ssaidi@eecs.umich.edu                    "reference.\n");
12835074Ssaidi@eecs.umich.edu
12845074Ssaidi@eecs.umich.edu            // Tell the LDSTQ to execute this instruction (if it is a load).
12855208Ssaidi@eecs.umich.edu            if (inst->isLoad()) {
12865074Ssaidi@eecs.umich.edu                // Loads will mark themselves as executed, and their writeback
12875074Ssaidi@eecs.umich.edu                // event adds the instruction to the queue to commit
12885074Ssaidi@eecs.umich.edu                fault = ldstQueue.executeLoad(inst);
12895074Ssaidi@eecs.umich.edu
12908706Sandreas.hansson@arm.com                if (inst->isTranslationDelayed() &&
12915074Ssaidi@eecs.umich.edu                    fault == NoFault) {
12925074Ssaidi@eecs.umich.edu                    // A hw page table walk is currently going on; the
12935074Ssaidi@eecs.umich.edu                    // instruction must be deferred.
12945074Ssaidi@eecs.umich.edu                    DPRINTF(IEW, "Execute: Delayed translation, deferring "
12955074Ssaidi@eecs.umich.edu                            "load.\n");
129610027SChris.Adeniyi-Jones@arm.com                    instQueue.deferMemInst(inst);
129710027SChris.Adeniyi-Jones@arm.com                    continue;
129810027SChris.Adeniyi-Jones@arm.com                }
129911851Sbrandon.potter@amd.com
130010027SChris.Adeniyi-Jones@arm.com                if (inst->isDataPrefetch() || inst->isInstPrefetch()) {
130110027SChris.Adeniyi-Jones@arm.com                    inst->fault = NoFault;
130210027SChris.Adeniyi-Jones@arm.com                }
130310027SChris.Adeniyi-Jones@arm.com            } else if (inst->isStore()) {
130410027SChris.Adeniyi-Jones@arm.com                fault = ldstQueue.executeStore(inst);
130510793Sbrandon.potter@amd.com
130610027SChris.Adeniyi-Jones@arm.com                if (inst->isTranslationDelayed() &&
130710027SChris.Adeniyi-Jones@arm.com                    fault == NoFault) {
130810027SChris.Adeniyi-Jones@arm.com                    // A hw page table walk is currently going on; the
130910027SChris.Adeniyi-Jones@arm.com                    // instruction must be deferred.
131010027SChris.Adeniyi-Jones@arm.com                    DPRINTF(IEW, "Execute: Delayed translation, deferring "
131110027SChris.Adeniyi-Jones@arm.com                            "store.\n");
131210027SChris.Adeniyi-Jones@arm.com                    instQueue.deferMemInst(inst);
131310027SChris.Adeniyi-Jones@arm.com                    continue;
131410027SChris.Adeniyi-Jones@arm.com                }
131510027SChris.Adeniyi-Jones@arm.com
131610027SChris.Adeniyi-Jones@arm.com                // If the store had a fault then it may not have a mem req
131710027SChris.Adeniyi-Jones@arm.com                if (fault != NoFault || !inst->readPredicate() ||
131810027SChris.Adeniyi-Jones@arm.com                        !inst->isStoreConditional()) {
131910027SChris.Adeniyi-Jones@arm.com                    // If the instruction faulted, then we need to send it along
132010027SChris.Adeniyi-Jones@arm.com                    // to commit without the instruction completing.
132110027SChris.Adeniyi-Jones@arm.com                    // Send this instruction to commit, also make sure iew stage
132210027SChris.Adeniyi-Jones@arm.com                    // realizes there is activity.
132310027SChris.Adeniyi-Jones@arm.com                    inst->setExecuted();
132410027SChris.Adeniyi-Jones@arm.com                    instToCommit(inst);
132510027SChris.Adeniyi-Jones@arm.com                    activityThisCycle();
132610027SChris.Adeniyi-Jones@arm.com                }
132710027SChris.Adeniyi-Jones@arm.com
132810027SChris.Adeniyi-Jones@arm.com                // Store conditionals will mark themselves as
132910027SChris.Adeniyi-Jones@arm.com                // executed, and their writeback event will add the
133010027SChris.Adeniyi-Jones@arm.com                // instruction to the queue to commit.
133110027SChris.Adeniyi-Jones@arm.com            } else {
133210027SChris.Adeniyi-Jones@arm.com                panic("Unexpected memory type!\n");
13331999SN/A            }
13341999SN/A
13351999SN/A        } else {
133611856Sbrandon.potter@amd.com            // If the instruction has already faulted, then skip executing it.
13371999SN/A            // Such case can happen when it faulted during ITLB translation.
13386701Sgblack@eecs.umich.edu            // If we execute the instruction (even if it's a nop) the fault
133911856Sbrandon.potter@amd.com            // will be replaced and we will lose it.
134011856Sbrandon.potter@amd.com            if (inst->getFault() == NoFault) {
134110931Sbrandon.potter@amd.com                inst->execute();
134211856Sbrandon.potter@amd.com                if (!inst->readPredicate())
134311856Sbrandon.potter@amd.com                    inst->forwardOldRegs();
13441999SN/A            }
134511856Sbrandon.potter@amd.com
13461999SN/A            inst->setExecuted();
13472764Sstever@eecs.umich.edu
13482064SN/A            instToCommit(inst);
134910931Sbrandon.potter@amd.com        }
13502064SN/A
13512064SN/A        updateExeInstStats(inst);
135210931Sbrandon.potter@amd.com
13532064SN/A        // Check if branch prediction was correct, if not then we need
13541999SN/A        // to tell commit to squash in flight instructions.  Only
13551999SN/A        // handle this if there hasn't already been something that
13562218SN/A        // redirects fetch in this group of instructions.
13571999SN/A
135810931Sbrandon.potter@amd.com        // This probably needs to prioritize the redirects if a different
13591999SN/A        // scheduler is used.  Currently the scheduler schedules the oldest
13601999SN/A        // instruction first, so the branch resolution order will be correct.
13611999SN/A        ThreadID tid = inst->threadNumber;
13621999SN/A
13631999SN/A        if (!fetchRedirect[tid] ||
1364378SN/A            !toCommit->squash[tid] ||
1365360SN/A            toCommit->squashedSeqNum[tid] > inst->seqNum) {
13661450SN/A
136711851Sbrandon.potter@amd.com            // Prevent testing for misprediction on load instructions,
13682680Sktlim@umich.edu            // that have not been executed.
1369360SN/A            bool loadNotExecuted = !inst->isExecuted() && inst->isLoad();
1370360SN/A
1371360SN/A            if (inst->mispredicted() && !loadNotExecuted) {
13726701Sgblack@eecs.umich.edu                fetchRedirect[tid] = true;
13738852Sandreas.hansson@arm.com
13746701Sgblack@eecs.umich.edu                DPRINTF(IEW, "Execute: Branch mispredict detected.\n");
13756701Sgblack@eecs.umich.edu                DPRINTF(IEW, "Predicted target was PC: %s.\n",
13766701Sgblack@eecs.umich.edu                        inst->readPredTarg());
13776701Sgblack@eecs.umich.edu                DPRINTF(IEW, "Execute: Redirecting fetch to PC: %s.\n",
1378360SN/A                        inst->pcState());
13793669Sbinkertn@umich.edu                // If incorrect, then signal the ROB that it must be squashed.
13803669Sbinkertn@umich.edu                squashDueToBranch(inst, tid);
13813669Sbinkertn@umich.edu
1382360SN/A                ppMispredict->notify(inst);
1383360SN/A
1384360SN/A                if (inst->readPredTaken()) {
1385360SN/A                    predictedTakenIncorrect++;
13861458SN/A                } else {
1387360SN/A                    predictedNotTakenIncorrect++;
13888706Sandreas.hansson@arm.com                }
1389360SN/A            } else if (ldstQueue.violation(tid)) {
13901458SN/A                assert(inst->isMemRef());
1391360SN/A                // If there was an ordering violation, then get the
1392360SN/A                // DynInst that caused the violation.  Note that this
13931999SN/A                // clears the violation signal.
13941999SN/A                DynInstPtr violator;
13951999SN/A                violator = ldstQueue.getMemDepViolator(tid);
139611851Sbrandon.potter@amd.com
13972680Sktlim@umich.edu                DPRINTF(IEW, "LDSTQ detected a violation. Violator PC: %s "
13981999SN/A                        "[sn:%lli], inst PC: %s [sn:%lli]. Addr is: %#x.\n",
13991999SN/A                        violator->pcState(), violator->seqNum,
14001999SN/A                        inst->pcState(), inst->seqNum, inst->physEffAddr);
14016701Sgblack@eecs.umich.edu
14028852Sandreas.hansson@arm.com                fetchRedirect[tid] = true;
14036701Sgblack@eecs.umich.edu
14046701Sgblack@eecs.umich.edu                // Tell the instruction queue that a violation has occured.
14056701Sgblack@eecs.umich.edu                instQueue.violation(inst, violator);
14066701Sgblack@eecs.umich.edu
14071999SN/A                // Squash.
14083669Sbinkertn@umich.edu                squashDueToMemOrder(violator, tid);
14093669Sbinkertn@umich.edu
14103669Sbinkertn@umich.edu                ++memOrderViolationEvents;
14112764Sstever@eecs.umich.edu            } else if (ldstQueue.loadBlocked(tid) &&
14122064SN/A                       !ldstQueue.isLoadBlockedHandled(tid)) {
14132064SN/A                fetchRedirect[tid] = true;
14142064SN/A
14151999SN/A                DPRINTF(IEW, "Load operation couldn't execute because the "
14161999SN/A                        "memory system is blocked.  PC: %s [sn:%lli]\n",
14172064SN/A                        inst->pcState(), inst->seqNum);
14181999SN/A
14191999SN/A                squashDueToMemBlocked(inst, tid);
14201999SN/A            }
14211999SN/A        } else {
14228706Sandreas.hansson@arm.com            // Reset any state associated with redirects that will not
14231999SN/A            // be used.
14241999SN/A            if (ldstQueue.violation(tid)) {
14251999SN/A                assert(inst->isMemRef());
14261999SN/A
1427378SN/A                DynInstPtr violator = ldstQueue.getMemDepViolator(tid);
1428360SN/A
14291450SN/A                DPRINTF(IEW, "LDSTQ detected a violation.  Violator PC: "
143011856Sbrandon.potter@amd.com                        "%s, inst PC: %s.  Addr is: %#x.\n",
1431360SN/A                        violator->pcState(), inst->pcState(),
14326701Sgblack@eecs.umich.edu                        inst->physEffAddr);
143311856Sbrandon.potter@amd.com                DPRINTF(IEW, "Violation will not be handled because "
143411856Sbrandon.potter@amd.com                        "already squashing\n");
1435360SN/A
143611380Salexandru.dutu@amd.com                ++memOrderViolationEvents;
1437360SN/A            }
143811856Sbrandon.potter@amd.com            if (ldstQueue.loadBlocked(tid) &&
143911856Sbrandon.potter@amd.com                !ldstQueue.isLoadBlockedHandled(tid)) {
14401458SN/A                DPRINTF(IEW, "Load operation couldn't execute because the "
144111856Sbrandon.potter@amd.com                        "memory system is blocked.  PC: %s [sn:%lli]\n",
1442360SN/A                        inst->pcState(), inst->seqNum);
1443360SN/A                DPRINTF(IEW, "Blocked load will not be handled because "
144410931Sbrandon.potter@amd.com                        "already squashing\n");
1445360SN/A
1446360SN/A                ldstQueue.setLoadBlockedHandled(tid);
14471458SN/A            }
1448360SN/A
144910931Sbrandon.potter@amd.com        }
14502021SN/A    }
14511458SN/A
1452360SN/A    // Update and record activity if we processed any instructions.
1453360SN/A    if (inst_num) {
14541706SN/A        if (exeStatus == Idle) {
14551706SN/A            exeStatus = Running;
14561706SN/A        }
145711851Sbrandon.potter@amd.com
14582680Sktlim@umich.edu        updatedQueues = true;
14591706SN/A
146011799Sbrandon.potter@amd.com        cpu->activityThisCycle();
146111799Sbrandon.potter@amd.com    }
146211799Sbrandon.potter@amd.com
14631706SN/A    // Need to reset this in case a writeback event needs to write into the
14641706SN/A    // iew queue.  That way the writeback event will write into the correct
14656701Sgblack@eecs.umich.edu    // spot in the queue.
14668852Sandreas.hansson@arm.com    wbNumInst = 0;
14676701Sgblack@eecs.umich.edu
14686701Sgblack@eecs.umich.edu}
14696701Sgblack@eecs.umich.edu
14706701Sgblack@eecs.umich.edutemplate <class Impl>
14711706SN/Avoid
14723669Sbinkertn@umich.eduDefaultIEW<Impl>::writebackInsts()
14733669Sbinkertn@umich.edu{
14743669Sbinkertn@umich.edu    // Loop through the head of the time buffer and wake any
14751706SN/A    // dependents.  These instructions are about to write back.  Also
14761706SN/A    // mark scoreboard that this instruction is finally complete.
14771706SN/A    // Either have IEW have direct access to scoreboard, or have this
14781706SN/A    // as part of backwards communication.
14792218SN/A    for (int inst_num = 0; inst_num < wbWidth &&
14801706SN/A             toCommit->insts[inst_num]; inst_num++) {
148111759Sbrandon.potter@amd.com        DynInstPtr inst = toCommit->insts[inst_num];
148211799Sbrandon.potter@amd.com        ThreadID tid = inst->threadNumber;
14831706SN/A
14841706SN/A        DPRINTF(IEW, "Sending instructions to commit, [sn:%lli] PC %s.\n",
14851706SN/A                inst->seqNum, inst->pcState());
148611886Sbrandon.potter@amd.com
148711886Sbrandon.potter@amd.com        iewInstsToCommit[tid]++;
148811886Sbrandon.potter@amd.com
148911886Sbrandon.potter@amd.com        // Some instructions will be sent to commit without having
149011886Sbrandon.potter@amd.com        // executed because they need commit to handle them.
149112426Sqtt2@cornell.edu        // E.g. Uncached loads have not actually executed when they
149213557Sgabeblack@google.com        // are first sent to commit.  Instead commit must tell the LSQ
149313557Sgabeblack@google.com        // when it's ready to execute the uncached load.
149411886Sbrandon.potter@amd.com        if (!inst->isSquashed() && inst->isExecuted() && inst->getFault() == NoFault) {
149512426Sqtt2@cornell.edu            int dependents = instQueue.wakeDependents(inst);
149613534Sandreas.sandberg@arm.com
149712426Sqtt2@cornell.edu            for (int i = 0; i < inst->numDestRegs(); i++) {
149813534Sandreas.sandberg@arm.com                //mark as Ready
149912426Sqtt2@cornell.edu                DPRINTF(IEW,"Setting Destination Register %i\n",
150012426Sqtt2@cornell.edu                        inst->renamedDestRegIdx(i));
150112426Sqtt2@cornell.edu                scoreboard->setReg(inst->renamedDestRegIdx(i));
150213536Sandreas.sandberg@arm.com            }
150312426Sqtt2@cornell.edu
150412426Sqtt2@cornell.edu            if (dependents) {
150511886Sbrandon.potter@amd.com                producerInst[tid]++;
150613536Sandreas.sandberg@arm.com                consumerInst[tid]+= dependents;
150712426Sqtt2@cornell.edu            }
150811886Sbrandon.potter@amd.com            writebackCount[tid]++;
150911886Sbrandon.potter@amd.com        }
151011886Sbrandon.potter@amd.com
151111886Sbrandon.potter@amd.com        decrWb(inst->seqNum);
151211886Sbrandon.potter@amd.com    }
151311886Sbrandon.potter@amd.com}
151411886Sbrandon.potter@amd.com
151511886Sbrandon.potter@amd.comtemplate<class Impl>
151611886Sbrandon.potter@amd.comvoid
151711886Sbrandon.potter@amd.comDefaultIEW<Impl>::tick()
151813649Sqtt2@cornell.edu{
151913649Sqtt2@cornell.edu    wbNumInst = 0;
152013649Sqtt2@cornell.edu    wbCycle = 0;
152113649Sqtt2@cornell.edu
152213649Sqtt2@cornell.edu    wroteToTimeBuffer = false;
152311886Sbrandon.potter@amd.com    updatedQueues = false;
152411886Sbrandon.potter@amd.com
152511886Sbrandon.potter@amd.com    sortInsts();
152611886Sbrandon.potter@amd.com
152711886Sbrandon.potter@amd.com    // Free function units marked as being freed this cycle.
152811886Sbrandon.potter@amd.com    fuPool->processFreeUnits();
152911886Sbrandon.potter@amd.com
153011886Sbrandon.potter@amd.com    list<ThreadID>::iterator threads = activeThreads->begin();
153111886Sbrandon.potter@amd.com    list<ThreadID>::iterator end = activeThreads->end();
153211886Sbrandon.potter@amd.com
153311886Sbrandon.potter@amd.com    // Check stall and squash signals, dispatch any instructions.
153411886Sbrandon.potter@amd.com    while (threads != end) {
153511886Sbrandon.potter@amd.com        ThreadID tid = *threads++;
153611886Sbrandon.potter@amd.com
153711886Sbrandon.potter@amd.com        DPRINTF(IEW,"Issue: Processing [tid:%i]\n",tid);
153811886Sbrandon.potter@amd.com
153911886Sbrandon.potter@amd.com        checkSignalsAndUpdate(tid);
154011886Sbrandon.potter@amd.com        dispatch(tid);
154111886Sbrandon.potter@amd.com    }
154211886Sbrandon.potter@amd.com
154311886Sbrandon.potter@amd.com    if (exeStatus != Squashing) {
154411886Sbrandon.potter@amd.com        executeInsts();
154511886Sbrandon.potter@amd.com
154611886Sbrandon.potter@amd.com        writebackInsts();
154711886Sbrandon.potter@amd.com
154811886Sbrandon.potter@amd.com        // Have the instruction queue try to schedule any ready instructions.
154911886Sbrandon.potter@amd.com        // (In actuality, this scheduling is for instructions that will
155011886Sbrandon.potter@amd.com        // be executed next cycle.)
155111886Sbrandon.potter@amd.com        instQueue.scheduleReadyInsts();
155211886Sbrandon.potter@amd.com
155311886Sbrandon.potter@amd.com        // Also should advance its own time buffers if the stage ran.
155413867Salexandru.dutu@amd.com        // Not the best place for it, but this works (hopefully).
155513867Salexandru.dutu@amd.com        issueToExecQueue.advance();
155611886Sbrandon.potter@amd.com    }
155711886Sbrandon.potter@amd.com
155811886Sbrandon.potter@amd.com    bool broadcast_free_entries = false;
155911886Sbrandon.potter@amd.com
156011886Sbrandon.potter@amd.com    if (updatedQueues || exeStatus == Running || updateLSQNextCycle) {
156111886Sbrandon.potter@amd.com        exeStatus = Idle;
156211886Sbrandon.potter@amd.com        updateLSQNextCycle = false;
156311886Sbrandon.potter@amd.com
156411886Sbrandon.potter@amd.com        broadcast_free_entries = true;
156511886Sbrandon.potter@amd.com    }
156611886Sbrandon.potter@amd.com
156711886Sbrandon.potter@amd.com    // Writeback any stores using any leftover bandwidth.
156811886Sbrandon.potter@amd.com    ldstQueue.writebackStores();
156911886Sbrandon.potter@amd.com
157011886Sbrandon.potter@amd.com    // Check the committed load/store signals to see if there's a load
157113867Salexandru.dutu@amd.com    // or store to commit.  Also check if it's being told to execute a
157213867Salexandru.dutu@amd.com    // nonspeculative instruction.
157313867Salexandru.dutu@amd.com    // This is pretty inefficient...
157413867Salexandru.dutu@amd.com
157511886Sbrandon.potter@amd.com    threads = activeThreads->begin();
157611886Sbrandon.potter@amd.com    while (threads != end) {
157711886Sbrandon.potter@amd.com        ThreadID tid = (*threads++);
157811911SBrandon.Potter@amd.com
157911911SBrandon.Potter@amd.com        DPRINTF(IEW,"Processing [tid:%i]\n",tid);
158011911SBrandon.Potter@amd.com
158111911SBrandon.Potter@amd.com        // Update structures based on instructions committed.
158211911SBrandon.Potter@amd.com        if (fromCommit->commitInfo[tid].doneSeqNum != 0 &&
158311911SBrandon.Potter@amd.com            !fromCommit->commitInfo[tid].squash &&
158411911SBrandon.Potter@amd.com            !fromCommit->commitInfo[tid].robSquashing) {
158511886Sbrandon.potter@amd.com
158611886Sbrandon.potter@amd.com            ldstQueue.commitStores(fromCommit->commitInfo[tid].doneSeqNum,tid);
158711886Sbrandon.potter@amd.com
158811886Sbrandon.potter@amd.com            ldstQueue.commitLoads(fromCommit->commitInfo[tid].doneSeqNum,tid);
158911886Sbrandon.potter@amd.com
159011886Sbrandon.potter@amd.com            updateLSQNextCycle = true;
159111886Sbrandon.potter@amd.com            instQueue.commit(fromCommit->commitInfo[tid].doneSeqNum,tid);
159211886Sbrandon.potter@amd.com        }
159311886Sbrandon.potter@amd.com
159411886Sbrandon.potter@amd.com        if (fromCommit->commitInfo[tid].nonSpecSeqNum != 0) {
159511886Sbrandon.potter@amd.com
159611886Sbrandon.potter@amd.com            //DPRINTF(IEW,"NonspecInst from thread %i",tid);
159713536Sandreas.sandberg@arm.com            if (fromCommit->commitInfo[tid].uncached) {
159811886Sbrandon.potter@amd.com                instQueue.replayMemInst(fromCommit->commitInfo[tid].uncachedLoad);
159911886Sbrandon.potter@amd.com                fromCommit->commitInfo[tid].uncachedLoad->setAtCommit();
160011886Sbrandon.potter@amd.com            } else {
160111886Sbrandon.potter@amd.com                instQueue.scheduleNonSpec(
160211886Sbrandon.potter@amd.com                    fromCommit->commitInfo[tid].nonSpecSeqNum);
160311886Sbrandon.potter@amd.com            }
160411886Sbrandon.potter@amd.com        }
160511886Sbrandon.potter@amd.com
160611886Sbrandon.potter@amd.com        if (broadcast_free_entries) {
160711886Sbrandon.potter@amd.com            toFetch->iewInfo[tid].iqCount =
160813867Salexandru.dutu@amd.com                instQueue.getCount(tid);
160913867Salexandru.dutu@amd.com            toFetch->iewInfo[tid].ldstqCount =
161013867Salexandru.dutu@amd.com                ldstQueue.getCount(tid);
161113867Salexandru.dutu@amd.com
161213867Salexandru.dutu@amd.com            toRename->iewInfo[tid].usedIQ = true;
161313867Salexandru.dutu@amd.com            toRename->iewInfo[tid].freeIQEntries =
161413867Salexandru.dutu@amd.com                instQueue.numFreeEntries(tid);
161513867Salexandru.dutu@amd.com            toRename->iewInfo[tid].usedLSQ = true;
161613867Salexandru.dutu@amd.com            toRename->iewInfo[tid].freeLSQEntries =
161713867Salexandru.dutu@amd.com                ldstQueue.numFreeEntries(tid);
161813867Salexandru.dutu@amd.com
161911886Sbrandon.potter@amd.com            wroteToTimeBuffer = true;
162011886Sbrandon.potter@amd.com        }
162111886Sbrandon.potter@amd.com
162211886Sbrandon.potter@amd.com        DPRINTF(IEW, "[tid:%i], Dispatch dispatched %i instructions.\n",
16231706SN/A                tid, toRename->iewInfo[tid].dispatched);
16241706SN/A    }
16251706SN/A
16261706SN/A    DPRINTF(IEW, "IQ has %i free entries (Can schedule: %i).  "
162711856Sbrandon.potter@amd.com            "LSQ has %i free entries.\n",
16281706SN/A            instQueue.numFreeEntries(), instQueue.hasReadyInsts(),
16296701Sgblack@eecs.umich.edu            ldstQueue.numFreeEntries());
163011856Sbrandon.potter@amd.com
163111856Sbrandon.potter@amd.com    updateStatus();
16321706SN/A
163311856Sbrandon.potter@amd.com    if (wroteToTimeBuffer) {
163411856Sbrandon.potter@amd.com        DPRINTF(Activity, "Activity this cycle.\n");
16351706SN/A        cpu->activityThisCycle();
163611856Sbrandon.potter@amd.com    }
16371706SN/A}
16381706SN/A
163910931Sbrandon.potter@amd.comtemplate <class Impl>
16401706SN/Avoid
16411706SN/ADefaultIEW<Impl>::updateExeInstStats(DynInstPtr &inst)
16422218SN/A{
16431706SN/A    ThreadID tid = inst->threadNumber;
164411759Sbrandon.potter@amd.com
16451706SN/A    iewExecutedInsts++;
16461706SN/A
16471706SN/A#if TRACING_ON
16481706SN/A    if (DTRACE(O3PipeView)) {
164913572Sbrandon.potter@amd.com        inst->completeTick = curTick() - inst->fetchTick;
165013572Sbrandon.potter@amd.com    }
165113572Sbrandon.potter@amd.com#endif
165213572Sbrandon.potter@amd.com
165313572Sbrandon.potter@amd.com    //
165413572Sbrandon.potter@amd.com    //  Control operations
165513572Sbrandon.potter@amd.com    //
165613572Sbrandon.potter@amd.com    if (inst->isControl())
165713572Sbrandon.potter@amd.com        iewExecutedBranches[tid]++;
165813572Sbrandon.potter@amd.com
165913572Sbrandon.potter@amd.com    //
166013572Sbrandon.potter@amd.com    //  Memory operations
166113572Sbrandon.potter@amd.com    //
166213572Sbrandon.potter@amd.com    if (inst->isMemRef()) {
166313572Sbrandon.potter@amd.com        iewExecutedRefs[tid]++;
166413572Sbrandon.potter@amd.com
166513572Sbrandon.potter@amd.com        if (inst->isLoad()) {
166613572Sbrandon.potter@amd.com            iewExecLoadInsts[tid]++;
166713572Sbrandon.potter@amd.com        }
166813572Sbrandon.potter@amd.com    }
166913572Sbrandon.potter@amd.com}
167013572Sbrandon.potter@amd.com
167113572Sbrandon.potter@amd.comtemplate <class Impl>
167213572Sbrandon.potter@amd.comvoid
167313572Sbrandon.potter@amd.comDefaultIEW<Impl>::checkMisprediction(DynInstPtr &inst)
167413572Sbrandon.potter@amd.com{
167513572Sbrandon.potter@amd.com    ThreadID tid = inst->threadNumber;
167613572Sbrandon.potter@amd.com
167713572Sbrandon.potter@amd.com    if (!fetchRedirect[tid] ||
167813572Sbrandon.potter@amd.com        !toCommit->squash[tid] ||
167913572Sbrandon.potter@amd.com        toCommit->squashedSeqNum[tid] > inst->seqNum) {
168013572Sbrandon.potter@amd.com
168113572Sbrandon.potter@amd.com        if (inst->mispredicted()) {
168213572Sbrandon.potter@amd.com            fetchRedirect[tid] = true;
168313572Sbrandon.potter@amd.com
168413572Sbrandon.potter@amd.com            DPRINTF(IEW, "Execute: Branch mispredict detected.\n");
168513572Sbrandon.potter@amd.com            DPRINTF(IEW, "Predicted target was PC:%#x, NPC:%#x.\n",
168613572Sbrandon.potter@amd.com                    inst->predInstAddr(), inst->predNextInstAddr());
16871706SN/A            DPRINTF(IEW, "Execute: Redirecting fetch to PC: %#x,"
16881999SN/A                    " NPC: %#x.\n", inst->nextInstAddr(),
16891999SN/A                    inst->nextInstAddr());
16901999SN/A            // If incorrect, then signal the ROB that it must be squashed.
169111856Sbrandon.potter@amd.com            squashDueToBranch(inst, tid);
16921999SN/A
16936701Sgblack@eecs.umich.edu            if (inst->readPredTaken()) {
169411856Sbrandon.potter@amd.com                predictedTakenIncorrect++;
169510931Sbrandon.potter@amd.com            } else {
169611856Sbrandon.potter@amd.com                predictedNotTakenIncorrect++;
169711856Sbrandon.potter@amd.com            }
16981999SN/A        }
169911856Sbrandon.potter@amd.com    }
17001999SN/A}
170111856Sbrandon.potter@amd.com
170211856Sbrandon.potter@amd.com#endif//__CPU_O3_IEW_IMPL_IMPL_HH__
170311856Sbrandon.potter@amd.com