rename_impl.hh

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· HH 代码 · 共 1,362 行 · 第 1/3 页

HH
1,362
字号
/* * 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 *          Korey L. Sewell */#include <list>#include "arch/isa_traits.hh"#include "arch/regfile.hh"#include "config/full_system.hh"#include "cpu/o3/rename.hh"template <class Impl>DefaultRename<Impl>::DefaultRename(O3CPU *_cpu, Params *params)    : cpu(_cpu),      iewToRenameDelay(params->iewToRenameDelay),      decodeToRenameDelay(params->decodeToRenameDelay),      commitToRenameDelay(params->commitToRenameDelay),      renameWidth(params->renameWidth),      commitWidth(params->commitWidth),      resumeSerialize(false),      resumeUnblocking(false),      numThreads(params->numberOfThreads),      maxPhysicalRegs(params->numPhysIntRegs + params->numPhysFloatRegs){    _status = Inactive;    for (int i=0; i< numThreads; i++) {        renameStatus[i] = Idle;        freeEntries[i].iqEntries = 0;        freeEntries[i].lsqEntries = 0;        freeEntries[i].robEntries = 0;        stalls[i].iew = false;        stalls[i].commit = false;        serializeInst[i] = NULL;        instsInProgress[i] = 0;        emptyROB[i] = true;        serializeOnNextInst[i] = false;    }    // @todo: Make into a parameter.    skidBufferMax = (2 * (iewToRenameDelay * params->decodeWidth)) + renameWidth;}template <class Impl>std::stringDefaultRename<Impl>::name() const{    return cpu->name() + ".rename";}template <class Impl>voidDefaultRename<Impl>::regStats(){    renameSquashCycles        .name(name() + ".RENAME:SquashCycles")        .desc("Number of cycles rename is squashing")        .prereq(renameSquashCycles);    renameIdleCycles        .name(name() + ".RENAME:IdleCycles")        .desc("Number of cycles rename is idle")        .prereq(renameIdleCycles);    renameBlockCycles        .name(name() + ".RENAME:BlockCycles")        .desc("Number of cycles rename is blocking")        .prereq(renameBlockCycles);    renameSerializeStallCycles        .name(name() + ".RENAME:serializeStallCycles")        .desc("count of cycles rename stalled for serializing inst")        .flags(Stats::total);    renameRunCycles        .name(name() + ".RENAME:RunCycles")        .desc("Number of cycles rename is running")        .prereq(renameIdleCycles);    renameUnblockCycles        .name(name() + ".RENAME:UnblockCycles")        .desc("Number of cycles rename is unblocking")        .prereq(renameUnblockCycles);    renameRenamedInsts        .name(name() + ".RENAME:RenamedInsts")        .desc("Number of instructions processed by rename")        .prereq(renameRenamedInsts);    renameSquashedInsts        .name(name() + ".RENAME:SquashedInsts")        .desc("Number of squashed instructions processed by rename")        .prereq(renameSquashedInsts);    renameROBFullEvents        .name(name() + ".RENAME:ROBFullEvents")        .desc("Number of times rename has blocked due to ROB full")        .prereq(renameROBFullEvents);    renameIQFullEvents        .name(name() + ".RENAME:IQFullEvents")        .desc("Number of times rename has blocked due to IQ full")        .prereq(renameIQFullEvents);    renameLSQFullEvents        .name(name() + ".RENAME:LSQFullEvents")        .desc("Number of times rename has blocked due to LSQ full")        .prereq(renameLSQFullEvents);    renameFullRegistersEvents        .name(name() + ".RENAME:FullRegisterEvents")        .desc("Number of times there has been no free registers")        .prereq(renameFullRegistersEvents);    renameRenamedOperands        .name(name() + ".RENAME:RenamedOperands")        .desc("Number of destination operands rename has renamed")        .prereq(renameRenamedOperands);    renameRenameLookups        .name(name() + ".RENAME:RenameLookups")        .desc("Number of register rename lookups that rename has made")        .prereq(renameRenameLookups);    renameCommittedMaps        .name(name() + ".RENAME:CommittedMaps")        .desc("Number of HB maps that are committed")        .prereq(renameCommittedMaps);    renameUndoneMaps        .name(name() + ".RENAME:UndoneMaps")        .desc("Number of HB maps that are undone due to squashing")        .prereq(renameUndoneMaps);    renamedSerializing        .name(name() + ".RENAME:serializingInsts")        .desc("count of serializing insts renamed")        .flags(Stats::total)        ;    renamedTempSerializing        .name(name() + ".RENAME:tempSerializingInsts")        .desc("count of temporary serializing insts renamed")        .flags(Stats::total)        ;    renameSkidInsts        .name(name() + ".RENAME:skidInsts")        .desc("count of insts added to the skid buffer")        .flags(Stats::total)        ;}template <class Impl>voidDefaultRename<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr){    timeBuffer = tb_ptr;    // Setup wire to read information from time buffer, from IEW stage.    fromIEW = timeBuffer->getWire(-iewToRenameDelay);    // Setup wire to read infromation from time buffer, from commit stage.    fromCommit = timeBuffer->getWire(-commitToRenameDelay);    // Setup wire to write information to previous stages.    toDecode = timeBuffer->getWire(0);}template <class Impl>voidDefaultRename<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr){    renameQueue = rq_ptr;    // Setup wire to write information to future stages.    toIEW = renameQueue->getWire(0);}template <class Impl>voidDefaultRename<Impl>::setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr){    decodeQueue = dq_ptr;    // Setup wire to get information from decode.    fromDecode = decodeQueue->getWire(-decodeToRenameDelay);}template <class Impl>voidDefaultRename<Impl>::initStage(){    // Grab the number of free entries directly from the stages.    for (int tid=0; tid < numThreads; tid++) {        freeEntries[tid].iqEntries = iew_ptr->instQueue.numFreeEntries(tid);        freeEntries[tid].lsqEntries = iew_ptr->ldstQueue.numFreeEntries(tid);        freeEntries[tid].robEntries = commit_ptr->numROBFreeEntries(tid);        emptyROB[tid] = true;    }}template<class Impl>voidDefaultRename<Impl>::setActiveThreads(std::list<unsigned> *at_ptr){    activeThreads = at_ptr;}template <class Impl>voidDefaultRename<Impl>::setRenameMap(RenameMap rm_ptr[]){    for (int i=0; i<numThreads; i++) {        renameMap[i] = &rm_ptr[i];    }}template <class Impl>voidDefaultRename<Impl>::setFreeList(FreeList *fl_ptr){    freeList = fl_ptr;}template<class Impl>voidDefaultRename<Impl>::setScoreboard(Scoreboard *_scoreboard){    scoreboard = _scoreboard;}template <class Impl>boolDefaultRename<Impl>::drain(){    // Rename is ready to switch out at any time.    cpu->signalDrained();    return true;}template <class Impl>voidDefaultRename<Impl>::switchOut(){    // Clear any state, fix up the rename map.    for (int i = 0; i < numThreads; i++) {        typename std::list<RenameHistory>::iterator hb_it =            historyBuffer[i].begin();        while (!historyBuffer[i].empty()) {            assert(hb_it != historyBuffer[i].end());            DPRINTF(Rename, "[tid:%u]: Removing history entry with sequence "                    "number %i.\n", i, (*hb_it).instSeqNum);            // Tell the rename map to set the architected register to the            // previous physical register that it was renamed to.            renameMap[i]->setEntry(hb_it->archReg, hb_it->prevPhysReg);            // Put the renamed physical register back on the free list.            freeList->addReg(hb_it->newPhysReg);            // Be sure to mark its register as ready if it's a misc register.            if (hb_it->newPhysReg >= maxPhysicalRegs) {                scoreboard->setReg(hb_it->newPhysReg);            }            historyBuffer[i].erase(hb_it++);        }        insts[i].clear();        skidBuffer[i].clear();    }}template <class Impl>voidDefaultRename<Impl>::takeOverFrom(){    _status = Inactive;    initStage();    // Reset all state prior to taking over from the other CPU.    for (int i=0; i< numThreads; i++) {        renameStatus[i] = Idle;        stalls[i].iew = false;        stalls[i].commit = false;        serializeInst[i] = NULL;        instsInProgress[i] = 0;        emptyROB[i] = true;        serializeOnNextInst[i] = false;    }}template <class Impl>voidDefaultRename<Impl>::squash(const InstSeqNum &squash_seq_num, unsigned tid){    DPRINTF(Rename, "[tid:%u]: Squashing instructions.\n",tid);    // Clear the stall signal if rename was blocked or unblocking before.    // If it still needs to block, the blocking should happen the next    // cycle and there should be space to hold everything due to the squash.    if (renameStatus[tid] == Blocked ||        renameStatus[tid] == Unblocking) {        toDecode->renameUnblock[tid] = 1;        resumeSerialize = false;        serializeInst[tid] = NULL;    } else if (renameStatus[tid] == SerializeStall) {        if (serializeInst[tid]->seqNum <= squash_seq_num) {            DPRINTF(Rename, "Rename will resume serializing after squash\n");            resumeSerialize = true;            assert(serializeInst[tid]);        } else {            resumeSerialize = false;            toDecode->renameUnblock[tid] = 1;            serializeInst[tid] = NULL;        }    }    // Set the status to Squashing.    renameStatus[tid] = Squashing;    // Squash any instructions from decode.    unsigned squashCount = 0;    for (int i=0; i<fromDecode->size; i++) {        if (fromDecode->insts[i]->threadNumber == tid &&            fromDecode->insts[i]->seqNum > squash_seq_num) {            fromDecode->insts[i]->setSquashed();            wroteToTimeBuffer = true;            squashCount++;        }    }    // Clear the instruction list and skid buffer in case they have any    // insts in them.    insts[tid].clear();    // Clear the skid buffer in case it has any data in it.    skidBuffer[tid].clear();    doSquash(squash_seq_num, tid);}template <class Impl>voidDefaultRename<Impl>::tick(){    wroteToTimeBuffer = false;    blockThisCycle = false;    bool status_change = false;    toIEWIndex = 0;    sortInsts();    std::list<unsigned>::iterator threads = activeThreads->begin();    std::list<unsigned>::iterator end = activeThreads->end();    // Check stall and squash signals.    while (threads != end) {        unsigned tid = *threads++;        DPRINTF(Rename, "Processing [tid:%i]\n", tid);        status_change = checkSignalsAndUpdate(tid) || status_change;        rename(status_change, tid);    }    if (status_change) {        updateStatus();    }    if (wroteToTimeBuffer) {        DPRINTF(Activity, "Activity this cycle.\n");        cpu->activityThisCycle();    }    threads = activeThreads->begin();    while (threads != end) {        unsigned tid = *threads++;        // If we committed this cycle then doneSeqNum will be > 0        if (fromCommit->commitInfo[tid].doneSeqNum != 0 &&            !fromCommit->commitInfo[tid].squash &&            renameStatus[tid] != Squashing) {            removeFromHistory(fromCommit->commitInfo[tid].doneSeqNum,                                  tid);        }    }    // @todo: make into updateProgress function    for (int tid=0; tid < numThreads; tid++) {        instsInProgress[tid] -= fromIEW->iewInfo[tid].dispatched;        assert(instsInProgress[tid] >=0);    }}template<class Impl>voidDefaultRename<Impl>::rename(bool &status_change, unsigned tid){    // If status is Running or idle,    //     call renameInsts()    // If status is Unblocking,    //     buffer any instructions coming from decode    //     continue trying to empty skid buffer    //     check if stall conditions have passed    if (renameStatus[tid] == Blocked) {        ++renameBlockCycles;    } else if (renameStatus[tid] == Squashing) {        ++renameSquashCycles;    } else if (renameStatus[tid] == SerializeStall) {        ++renameSerializeStallCycles;        // If we are currently in SerializeStall and resumeSerialize        // was set, then that means that we are resuming serializing        // this cycle.  Tell the previous stages to block.        if (resumeSerialize) {            resumeSerialize = false;            block(tid);            toDecode->renameUnblock[tid] = false;        }    } else if (renameStatus[tid] == Unblocking) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?