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 + -
显示快捷键?