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