iew_impl.hh
来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· HH 代码 · 共 1,585 行 · 第 1/4 页
HH
1,585 行
/* * Copyright (c) 2004, 2005, 2006 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator. * * Permission is granted to use, copy, create derivative works and * redistribute this software and such derivative works for any * purpose, so long as the copyright notice above, this grant of * permission, and the disclaimer below appear in all copies made; and * so long as the name of The University of Michigan is not used in * any advertising or publicity pertaining to the use or distribution * of this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. * * Authors: Kevin T. Lim */// @todo: Fix the instantaneous communication among all the stages within// iew. There's a clear delay between issue and execute, yet backwards// communication happens simultaneously.#include <queue>#include "base/timebuf.hh"#include "cpu/o3/fu_pool.hh"#include "cpu/o3/iew.hh"template<class Impl>DefaultIEW<Impl>::DefaultIEW(O3CPU *_cpu, Params *params) : issueToExecQueue(params->backComSize, params->forwardComSize), cpu(_cpu), instQueue(_cpu, this, params), ldstQueue(_cpu, this, params), fuPool(params->fuPool), commitToIEWDelay(params->commitToIEWDelay), renameToIEWDelay(params->renameToIEWDelay), issueToExecuteDelay(params->issueToExecuteDelay), dispatchWidth(params->dispatchWidth), issueWidth(params->issueWidth), wbOutstanding(0), wbWidth(params->wbWidth), numThreads(params->numberOfThreads), switchedOut(false){ _status = Active; exeStatus = Running; wbStatus = Idle; // Setup wire to read instructions coming from issue. fromIssue = issueToExecQueue.getWire(-issueToExecuteDelay); // Instruction queue needs the queue between issue and execute. instQueue.setIssueToExecuteQueue(&issueToExecQueue); for (int i=0; i < numThreads; i++) { dispatchStatus[i] = Running; stalls[i].commit = false; fetchRedirect[i] = false; } wbMax = wbWidth * params->wbDepth; updateLSQNextCycle = false; ableToIssue = true; skidBufferMax = (3 * (renameToIEWDelay * params->renameWidth)) + issueWidth;}template <class Impl>std::stringDefaultIEW<Impl>::name() const{ return cpu->name() + ".iew";}template <class Impl>voidDefaultIEW<Impl>::regStats(){ using namespace Stats; instQueue.regStats(); ldstQueue.regStats(); iewIdleCycles .name(name() + ".iewIdleCycles") .desc("Number of cycles IEW is idle"); iewSquashCycles .name(name() + ".iewSquashCycles") .desc("Number of cycles IEW is squashing"); iewBlockCycles .name(name() + ".iewBlockCycles") .desc("Number of cycles IEW is blocking"); iewUnblockCycles .name(name() + ".iewUnblockCycles") .desc("Number of cycles IEW is unblocking"); iewDispatchedInsts .name(name() + ".iewDispatchedInsts") .desc("Number of instructions dispatched to IQ"); iewDispSquashedInsts .name(name() + ".iewDispSquashedInsts") .desc("Number of squashed instructions skipped by dispatch"); iewDispLoadInsts .name(name() + ".iewDispLoadInsts") .desc("Number of dispatched load instructions"); iewDispStoreInsts .name(name() + ".iewDispStoreInsts") .desc("Number of dispatched store instructions"); iewDispNonSpecInsts .name(name() + ".iewDispNonSpecInsts") .desc("Number of dispatched non-speculative instructions"); iewIQFullEvents .name(name() + ".iewIQFullEvents") .desc("Number of times the IQ has become full, causing a stall"); iewLSQFullEvents .name(name() + ".iewLSQFullEvents") .desc("Number of times the LSQ has become full, causing a stall"); memOrderViolationEvents .name(name() + ".memOrderViolationEvents") .desc("Number of memory order violations"); predictedTakenIncorrect .name(name() + ".predictedTakenIncorrect") .desc("Number of branches that were predicted taken incorrectly"); predictedNotTakenIncorrect .name(name() + ".predictedNotTakenIncorrect") .desc("Number of branches that were predicted not taken incorrectly"); branchMispredicts .name(name() + ".branchMispredicts") .desc("Number of branch mispredicts detected at execute"); branchMispredicts = predictedTakenIncorrect + predictedNotTakenIncorrect; iewExecutedInsts .name(name() + ".iewExecutedInsts") .desc("Number of executed instructions"); iewExecLoadInsts .init(cpu->number_of_threads) .name(name() + ".iewExecLoadInsts") .desc("Number of load instructions executed") .flags(total); iewExecSquashedInsts .name(name() + ".iewExecSquashedInsts") .desc("Number of squashed instructions skipped in execute"); iewExecutedSwp .init(cpu->number_of_threads) .name(name() + ".EXEC:swp") .desc("number of swp insts executed") .flags(total); iewExecutedNop .init(cpu->number_of_threads) .name(name() + ".EXEC:nop") .desc("number of nop insts executed") .flags(total); iewExecutedRefs .init(cpu->number_of_threads) .name(name() + ".EXEC:refs") .desc("number of memory reference insts executed") .flags(total); iewExecutedBranches .init(cpu->number_of_threads) .name(name() + ".EXEC:branches") .desc("Number of branches executed") .flags(total); iewExecStoreInsts .name(name() + ".EXEC:stores") .desc("Number of stores executed") .flags(total); iewExecStoreInsts = iewExecutedRefs - iewExecLoadInsts; iewExecRate .name(name() + ".EXEC:rate") .desc("Inst execution rate") .flags(total); iewExecRate = iewExecutedInsts / cpu->numCycles; iewInstsToCommit .init(cpu->number_of_threads) .name(name() + ".WB:sent") .desc("cumulative count of insts sent to commit") .flags(total); writebackCount .init(cpu->number_of_threads) .name(name() + ".WB:count") .desc("cumulative count of insts written-back") .flags(total); producerInst .init(cpu->number_of_threads) .name(name() + ".WB:producers") .desc("num instructions producing a value") .flags(total); consumerInst .init(cpu->number_of_threads) .name(name() + ".WB:consumers") .desc("num instructions consuming a value") .flags(total); wbPenalized .init(cpu->number_of_threads) .name(name() + ".WB:penalized") .desc("number of instrctions required to write to 'other' IQ") .flags(total); wbPenalizedRate .name(name() + ".WB:penalized_rate") .desc ("fraction of instructions written-back that wrote to 'other' IQ") .flags(total); wbPenalizedRate = wbPenalized / writebackCount; wbFanout .name(name() + ".WB:fanout") .desc("average fanout of values written-back") .flags(total); wbFanout = producerInst / consumerInst; wbRate .name(name() + ".WB:rate") .desc("insts written-back per cycle") .flags(total); wbRate = writebackCount / cpu->numCycles;}template<class Impl>voidDefaultIEW<Impl>::initStage(){ for (int tid=0; tid < numThreads; tid++) { toRename->iewInfo[tid].usedIQ = true; toRename->iewInfo[tid].freeIQEntries = instQueue.numFreeEntries(tid); toRename->iewInfo[tid].usedLSQ = true; toRename->iewInfo[tid].freeLSQEntries = ldstQueue.numFreeEntries(tid); } cpu->activateStage(O3CPU::IEWIdx);}template<class Impl>voidDefaultIEW<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr){ timeBuffer = tb_ptr; // Setup wire to read information from time buffer, from commit. fromCommit = timeBuffer->getWire(-commitToIEWDelay); // Setup wire to write information back to previous stages. toRename = timeBuffer->getWire(0); toFetch = timeBuffer->getWire(0); // Instruction queue also needs main time buffer. instQueue.setTimeBuffer(tb_ptr);}template<class Impl>voidDefaultIEW<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr){ renameQueue = rq_ptr; // Setup wire to read information from rename queue. fromRename = renameQueue->getWire(-renameToIEWDelay);}template<class Impl>voidDefaultIEW<Impl>::setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr){ iewQueue = iq_ptr; // Setup wire to write instructions to commit. toCommit = iewQueue->getWire(0);}template<class Impl>voidDefaultIEW<Impl>::setActiveThreads(std::list<unsigned> *at_ptr){ activeThreads = at_ptr; ldstQueue.setActiveThreads(at_ptr); instQueue.setActiveThreads(at_ptr);}template<class Impl>voidDefaultIEW<Impl>::setScoreboard(Scoreboard *sb_ptr){ scoreboard = sb_ptr;}template <class Impl>boolDefaultIEW<Impl>::drain(){ // IEW is ready to drain at any time. cpu->signalDrained(); return true;}template <class Impl>voidDefaultIEW<Impl>::resume(){}template <class Impl>voidDefaultIEW<Impl>::switchOut(){ // Clear any state. switchedOut = true; assert(insts[0].empty()); assert(skidBuffer[0].empty()); instQueue.switchOut(); ldstQueue.switchOut(); fuPool->switchOut(); for (int i = 0; i < numThreads; i++) { while (!insts[i].empty()) insts[i].pop(); while (!skidBuffer[i].empty()) skidBuffer[i].pop(); }}template <class Impl>voidDefaultIEW<Impl>::takeOverFrom(){ // Reset all state. _status = Active; exeStatus = Running; wbStatus = Idle; switchedOut = false; instQueue.takeOverFrom(); ldstQueue.takeOverFrom(); fuPool->takeOverFrom(); initStage(); cpu->activityThisCycle(); for (int i=0; i < numThreads; i++) { dispatchStatus[i] = Running; stalls[i].commit = false; fetchRedirect[i] = false; } updateLSQNextCycle = false; for (int i = 0; i < issueToExecQueue.getSize(); ++i) { issueToExecQueue.advance();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?