commit_impl.hh

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

HH
506
字号
/* * 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 "base/timebuf.hh"#include "cpu/o3/commit.hh"#include "cpu/exetrace.hh"template <class Impl>SimpleCommit<Impl>::SimpleCommit(Params &params)    : dcacheInterface(params.dcacheInterface),      iewToCommitDelay(params.iewToCommitDelay),      renameToROBDelay(params.renameToROBDelay),      renameWidth(params.renameWidth),      iewWidth(params.executeWidth),      commitWidth(params.commitWidth){    _status = Idle;}template <class Impl>voidSimpleCommit<Impl>::regStats(){    commitCommittedInsts        .name(name() + ".commitCommittedInsts")        .desc("The number of committed instructions")        .prereq(commitCommittedInsts);    commitSquashedInsts        .name(name() + ".commitSquashedInsts")        .desc("The number of squashed insts skipped by commit")        .prereq(commitSquashedInsts);    commitSquashEvents        .name(name() + ".commitSquashEvents")        .desc("The number of times commit is told to squash")        .prereq(commitSquashEvents);    commitNonSpecStalls        .name(name() + ".commitNonSpecStalls")        .desc("The number of times commit has been forced to stall to "              "communicate backwards")        .prereq(commitNonSpecStalls);    commitCommittedBranches        .name(name() + ".commitCommittedBranches")        .desc("The number of committed branches")        .prereq(commitCommittedBranches);    commitCommittedLoads        .name(name() + ".commitCommittedLoads")        .desc("The number of committed loads")        .prereq(commitCommittedLoads);    commitCommittedMemRefs        .name(name() + ".commitCommittedMemRefs")        .desc("The number of committed memory references")        .prereq(commitCommittedMemRefs);    branchMispredicts        .name(name() + ".branchMispredicts")        .desc("The number of times a branch was mispredicted")        .prereq(branchMispredicts);    n_committed_dist	.init(0,commitWidth,1)	.name(name() + ".COM:committed_per_cycle")	.desc("Number of insts commited each cycle")	.flags(Stats::pdf)	;}template <class Impl>voidSimpleCommit<Impl>::setCPU(FullCPU *cpu_ptr){    DPRINTF(Commit, "Commit: Setting CPU pointer.\n");    cpu = cpu_ptr;}template <class Impl>voidSimpleCommit<Impl>::setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr){    DPRINTF(Commit, "Commit: Setting time buffer pointer.\n");    timeBuffer = tb_ptr;    // Setup wire to send information back to IEW.    toIEW = timeBuffer->getWire(0);    // Setup wire to read data from IEW (for the ROB).    robInfoFromIEW = timeBuffer->getWire(-iewToCommitDelay);}template <class Impl>voidSimpleCommit<Impl>::setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr){    DPRINTF(Commit, "Commit: Setting rename queue pointer.\n");    renameQueue = rq_ptr;    // Setup wire to get instructions from rename (for the ROB).    fromRename = renameQueue->getWire(-renameToROBDelay);}template <class Impl>voidSimpleCommit<Impl>::setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr){    DPRINTF(Commit, "Commit: Setting IEW queue pointer.\n");    iewQueue = iq_ptr;    // Setup wire to get instructions from IEW.    fromIEW = iewQueue->getWire(-iewToCommitDelay);}template <class Impl>voidSimpleCommit<Impl>::setROB(ROB *rob_ptr){    DPRINTF(Commit, "Commit: Setting ROB pointer.\n");    rob = rob_ptr;}template <class Impl>voidSimpleCommit<Impl>::tick(){    // If the ROB is currently in its squash sequence, then continue    // to squash.  In this case, commit does not do anything.  Otherwise    // run commit.    if (_status == ROBSquashing) {        if (rob->isDoneSquashing()) {            _status = Running;        } else {            rob->doSquash();                    // Send back sequence number of tail of ROB, so other stages            // can squash younger instructions.  Note that really the only            // stage that this is important for is the IEW stage; other            // stages can just clear all their state as long as selective            // replay isn't used.            toIEW->commitInfo.doneSeqNum = rob->readTailSeqNum();            toIEW->commitInfo.robSquashing = true;        }    } else {        commit();    }    markCompletedInsts();    // Writeback number of free ROB entries here.    DPRINTF(Commit, "Commit: ROB has %d free entries.\n",            rob->numFreeEntries());    toIEW->commitInfo.freeROBEntries = rob->numFreeEntries();}template <class Impl>voidSimpleCommit<Impl>::commit(){    //////////////////////////////////////    // Check for interrupts    //////////////////////////////////////    // Process interrupts if interrupts are enabled and not in PAL mode.    // Take the PC from commit and write it to the IPR, then squash.  The     // interrupt completing will take care of restoring the PC from that value    // in the IPR.  Look at IPR[EXC_ADDR];    // hwrei() is what resets the PC to the place where instruction execution    // beings again.#if FULL_SYSTEM    if (//checkInterrupts &&        cpu->check_interrupts() &&        !cpu->inPalMode(readCommitPC())) {        // Will need to squash all instructions currently in flight and have        // the interrupt handler restart at the last non-committed inst.        // Most of that can be handled through the trap() function.  The        // processInterrupts() function really just checks for interrupts        // and then calls trap() if there is an interrupt present.        // CPU will handle implementation of the interrupt.        cpu->processInterrupts();    }#endif // FULL_SYSTEM    ////////////////////////////////////    // Check for squash signal, handle that first    ////////////////////////////////////    // Want to mainly check if the IEW stage is telling the ROB to squash.    // Should I also check if the commit stage is telling the ROB to squah?    // This might be necessary to keep the same timing between the IQ and    // the ROB...    if (fromIEW->squash) {        DPRINTF(Commit, "Commit: Squashing instructions in the ROB.\n");        _status = ROBSquashing;        InstSeqNum squashed_inst = fromIEW->squashedSeqNum;        rob->squash(squashed_inst);        // Send back the sequence number of the squashed instruction.        toIEW->commitInfo.doneSeqNum = squashed_inst;        // Send back the squash signal to tell stages that they should squash.        toIEW->commitInfo.squash = true;        // Send back the rob squashing signal so other stages know that the        // ROB is in the process of squashing.        toIEW->commitInfo.robSquashing = true;        toIEW->commitInfo.branchMispredict = fromIEW->branchMispredict;        toIEW->commitInfo.branchTaken = fromIEW->branchTaken;        toIEW->commitInfo.nextPC = fromIEW->nextPC;        toIEW->commitInfo.mispredPC = fromIEW->mispredPC;        if (toIEW->commitInfo.branchMispredict) {            ++branchMispredicts;        }    }     if (_status != ROBSquashing) {        // If we're not currently squashing, then get instructions.        getInsts();        // Try to commit any instructions.        commitInsts();    }

⌨️ 快捷键说明

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