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