rename_impl.hh

来自「linux下基于c++的处理器仿真平台。具有处理器流水线」· HH 代码 · 共 758 行 · 第 1/2 页

HH
758
字号
/* * Copyright (c) 2004, 2005 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator, developed by Nathan Binkert, * Erik Hallnor, Steve Raasch, and Steve Reinhardt, with contributions * from Ron Dreslinski, Dave Greene, Lisa Hsu, Kevin Lim, Ali Saidi,  * and Andrew Schultz. * * 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. */#include <list>#include "config/full_system.hh"#include "cpu/o3/rename.hh"template <class Impl>SimpleRename<Impl>::SimpleRename(Params &params)    : iewToRenameDelay(params.iewToRenameDelay),      decodeToRenameDelay(params.decodeToRenameDelay),      commitToRenameDelay(params.commitToRenameDelay),      renameWidth(params.renameWidth),      commitWidth(params.commitWidth),      numInst(0){    _status = Idle;}template <class Impl>voidSimpleRename<Impl>::regStats(){    renameSquashCycles        .name(name() + ".renameSquashCycles")        .desc("Number of cycles rename is squashing")        .prereq(renameSquashCycles);    renameIdleCycles        .name(name() + ".renameIdleCycles")        .desc("Number of cycles rename is idle")        .prereq(renameIdleCycles);    renameBlockCycles        .name(name() + ".renameBlockCycles")        .desc("Number of cycles rename is blocking")        .prereq(renameBlockCycles);    renameUnblockCycles        .name(name() + ".renameUnblockCycles")        .desc("Number of cycles rename is unblocking")        .prereq(renameUnblockCycles);    renameRenamedInsts        .name(name() + ".renameRenamedInsts")        .desc("Number of instructions processed by rename")        .prereq(renameRenamedInsts);    renameSquashedInsts        .name(name() + ".renameSquashedInsts")        .desc("Number of squashed instructions processed by rename")        .prereq(renameSquashedInsts);    renameROBFullEvents        .name(name() + ".renameROBFullEvents")        .desc("Number of times rename has considered the ROB 'full'")        .prereq(renameROBFullEvents);    renameIQFullEvents        .name(name() + ".renameIQFullEvents")        .desc("Number of times rename has considered the IQ 'full'")        .prereq(renameIQFullEvents);    renameFullRegistersEvents        .name(name() + ".renameFullRegisterEvents")        .desc("Number of times there has been no free registers")        .prereq(renameFullRegistersEvents);    renameRenamedOperands        .name(name() + ".renameRenamedOperands")        .desc("Number of destination operands rename has renamed")        .prereq(renameRenamedOperands);    renameRenameLookups        .name(name() + ".renameRenameLookups")        .desc("Number of register rename lookups that rename has made")        .prereq(renameRenameLookups);    renameHBPlaceHolders        .name(name() + ".renameHBPlaceHolders")        .desc("Number of place holders added to the history buffer")        .prereq(renameHBPlaceHolders);    renameCommittedMaps        .name(name() + ".renameCommittedMaps")        .desc("Number of HB maps that are committed")        .prereq(renameCommittedMaps);    renameUndoneMaps        .name(name() + ".renameUndoneMaps")        .desc("Number of HB maps that are undone due to squashing")        .prereq(renameUndoneMaps);    renameValidUndoneMaps        .name(name() + ".renameValidUndoneMaps")        .desc("Number of HB maps that are undone, and are not place holders")        .prereq(renameValidUndoneMaps);}template <class Impl>voidSimpleRename<Impl>::setCPU(FullCPU *cpu_ptr){    DPRINTF(Rename, "Rename: Setting CPU pointer.\n");    cpu = cpu_ptr;}template <class Impl>voidSimpleRename<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr){    DPRINTF(Rename, "Rename: Setting time buffer pointer.\n");    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>voidSimpleRename<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr){    DPRINTF(Rename, "Rename: Setting rename queue pointer.\n");    renameQueue = rq_ptr;    // Setup wire to write information to future stages.    toIEW = renameQueue->getWire(0);}template <class Impl>voidSimpleRename<Impl>::setDecodeQueue(TimeBuffer<DecodeStruct> *dq_ptr){    DPRINTF(Rename, "Rename: Setting decode queue pointer.\n");    decodeQueue = dq_ptr;    // Setup wire to get information from decode.    fromDecode = decodeQueue->getWire(-decodeToRenameDelay);}template <class Impl>voidSimpleRename<Impl>::setRenameMap(RenameMap *rm_ptr){    DPRINTF(Rename, "Rename: Setting rename map pointer.\n");    renameMap = rm_ptr;}template <class Impl>voidSimpleRename<Impl>::setFreeList(FreeList *fl_ptr){    DPRINTF(Rename, "Rename: Setting free list pointer.\n");    freeList = fl_ptr;}template <class Impl>voidSimpleRename<Impl>::dumpHistory(){    typename list<RenameHistory>::iterator buf_it = historyBuffer.begin();    while (buf_it != historyBuffer.end())    {        cprintf("Seq num: %i\nArch reg: %i New phys reg: %i Old phys "                "reg: %i\n", (*buf_it).instSeqNum, (int)(*buf_it).archReg,                (int)(*buf_it).newPhysReg, (int)(*buf_it).prevPhysReg);        buf_it++;    }}template <class Impl>voidSimpleRename<Impl>::block(){    DPRINTF(Rename, "Rename: Blocking.\n");    // Set status to Blocked.    _status = Blocked;        // Add the current inputs onto the skid buffer, so they can be    // reprocessed when this stage unblocks.    skidBuffer.push(*fromDecode);        // Note that this stage only signals previous stages to stall when    // it is the cause of the stall originates at this stage.  Otherwise    // the previous stages are expected to check all possible stall signals.}template <class Impl>inline voidSimpleRename<Impl>::unblock(){    DPRINTF(Rename, "Rename: Read instructions out of skid buffer this "            "cycle.\n");    // Remove the now processed instructions from the skid buffer.    skidBuffer.pop();        // If there's still information in the skid buffer, then     // continue to tell previous stages to stall.  They will be     // able to restart once the skid buffer is empty.       if (!skidBuffer.empty()) {        toDecode->renameInfo.stall = true;    } else {        DPRINTF(Rename, "Rename: Done unblocking.\n");        _status = Running;    }}template <class Impl>voidSimpleRename<Impl>::doSquash(){    typename list<RenameHistory>::iterator hb_it = historyBuffer.begin();    InstSeqNum squashed_seq_num = fromCommit->commitInfo.doneSeqNum;#if FULL_SYSTEM    assert(!historyBuffer.empty());#else    // After a syscall squashes everything, the history buffer may be empty    // but the ROB may still be squashing instructions.    if (historyBuffer.empty()) {        return;    }#endif // FULL_SYSTEM    // Go through the most recent instructions, undoing the mappings    // they did and freeing up the registers.    while ((*hb_it).instSeqNum > squashed_seq_num)    {        assert(hb_it != historyBuffer.end());        DPRINTF(Rename, "Rename: Removing history entry with sequence "                "number %i.\n", (*hb_it).instSeqNum);        // If it's not simply a place holder, then add the registers.        if (!(*hb_it).placeHolder) {            // Tell the rename map to set the architected register to the            // previous physical register that it was renamed to.            renameMap->setEntry(hb_it->archReg, hb_it->prevPhysReg);                        // Put the renamed physical register back on the free list.            freeList->addReg(hb_it->newPhysReg);            ++renameValidUndoneMaps;        }        historyBuffer.erase(hb_it++);        ++renameUndoneMaps;    }}template <class Impl>voidSimpleRename<Impl>::squash(){    DPRINTF(Rename, "Rename: Squashing instructions.\n");    // Set the status to Squashing.    _status = Squashing;    numInst = 0;        // Clear the skid buffer in case it has any data in it.    while (!skidBuffer.empty())    {        skidBuffer.pop();    }    doSquash();}template<class Impl>voidSimpleRename<Impl>::removeFromHistory(InstSeqNum inst_seq_num){    DPRINTF(Rename, "Rename: Removing a committed instruction from the "            "history buffer, until sequence number %lli.\n", inst_seq_num);    typename list<RenameHistory>::iterator hb_it = historyBuffer.end();    --hb_it;    if (hb_it->instSeqNum > inst_seq_num) {        DPRINTF(Rename, "Rename: Old sequence number encountered.  Ensure "                "that a syscall happened recently.\n");        return;    }    while ((*hb_it).instSeqNum != inst_seq_num)    {         // Make sure we haven't gone off the end of the list.        assert(hb_it != historyBuffer.end());        // In theory instructions at the end of the history buffer        // should be older than the instruction being removed, which        // means they will have a lower sequence number.  Also the        // instruction being removed from the history really should        // be the last instruction in the list, as it is the instruction        // that was just committed that is being removed.        assert(hb_it->instSeqNum < inst_seq_num);        DPRINTF(Rename, "Rename: Freeing up older rename of reg %i, sequence"                " number %i.\n",                (*hb_it).prevPhysReg, (*hb_it).instSeqNum);        if (!(*hb_it).placeHolder) {            freeList->addReg((*hb_it).prevPhysReg);            ++renameCommittedMaps;        }                historyBuffer.erase(hb_it--);    }    // Finally free up the previous register of the finished instruction    // itself.    if (!(*hb_it).placeHolder) {        freeList->addReg(hb_it->prevPhysReg);        ++renameCommittedMaps;    }    historyBuffer.erase(hb_it);   }template <class Impl>inline voidSimpleRename<Impl>::renameSrcRegs(DynInstPtr &inst){    unsigned num_src_regs = inst->numSrcRegs();    // Get the architectual register numbers from the source and    // destination operands, and redirect them to the right register.    // Will need to mark dependencies though.    for (int src_idx = 0; src_idx < num_src_regs; src_idx++)    {        RegIndex src_reg = inst->srcRegIdx(src_idx);                // Look up the source registers to get the phys. register they've        // been renamed to, and set the sources to those registers.        PhysRegIndex renamed_reg = renameMap->lookup(src_reg);                DPRINTF(Rename, "Rename: Looking up arch reg %i, got "                "physical reg %i.\n", (int)src_reg, (int)renamed_reg);                inst->renameSrcReg(src_idx, renamed_reg);                // Either incorporate it into the info passed back,        // or make another function call to see if that register is        // ready or not.        if (renameMap->isReady(renamed_reg)) {            DPRINTF(Rename, "Rename: Register is ready.\n");                        inst->markSrcRegReady(src_idx);        }        ++renameRenameLookups;    }}

⌨️ 快捷键说明

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