cpu_impl.hh

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

HH
484
字号
/* * Copyright (c) 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 */#include <list>#include <string>#include "base/refcnt.hh"#include "cpu/base_dyn_inst.hh"#include "cpu/checker/cpu.hh"#include "cpu/simple_thread.hh"#include "cpu/thread_context.hh"#include "cpu/static_inst.hh"#include "sim/sim_object.hh"#include "sim/stats.hh"#if FULL_SYSTEM#include "arch/vtophys.hh"#endif // FULL_SYSTEMusing namespace std;//The CheckerCPU does alpha onlyusing namespace AlphaISA;template <class DynInstPtr>voidChecker<DynInstPtr>::verify(DynInstPtr &completed_inst){    DynInstPtr inst;    // Either check this instruction, or add it to a list of    // instructions waiting to be checked.  Instructions must be    // checked in program order, so if a store has committed yet not    // completed, there may be some instructions that are waiting    // behind it that have completed and must be checked.    if (!instList.empty()) {        if (youngestSN < completed_inst->seqNum) {            DPRINTF(Checker, "Adding instruction [sn:%lli] PC:%#x to list.\n",                    completed_inst->seqNum, completed_inst->readPC());            instList.push_back(completed_inst);            youngestSN = completed_inst->seqNum;        }        if (!instList.front()->isCompleted()) {            return;        } else {            inst = instList.front();            instList.pop_front();        }    } else {        if (!completed_inst->isCompleted()) {            if (youngestSN < completed_inst->seqNum) {                DPRINTF(Checker, "Adding instruction [sn:%lli] PC:%#x to list.\n",                        completed_inst->seqNum, completed_inst->readPC());                instList.push_back(completed_inst);                youngestSN = completed_inst->seqNum;            }            return;        } else {            if (youngestSN < completed_inst->seqNum) {                inst = completed_inst;                youngestSN = completed_inst->seqNum;            } else {                return;            }        }    }    unverifiedInst = inst;    // Try to check all instructions that are completed, ending if we    // run out of instructions to check or if an instruction is not    // yet completed.    while (1) {        DPRINTF(Checker, "Processing instruction [sn:%lli] PC:%#x.\n",                inst->seqNum, inst->readPC());        unverifiedResult.integer = inst->readIntResult();        unverifiedReq = inst->req;        unverifiedMemData = inst->memData;        numCycles++;        Fault fault = NoFault;        // maintain $r0 semantics        thread->setIntReg(ZeroReg, 0);#ifdef TARGET_ALPHA        thread->setFloatRegDouble(ZeroReg, 0.0);#endif // TARGET_ALPHA        // Check if any recent PC changes match up with anything we        // expect to happen.  This is mostly to check if traps or        // PC-based events have occurred in both the checker and CPU.        if (changedPC) {            DPRINTF(Checker, "Changed PC recently to %#x\n",                    thread->readPC());            if (willChangePC) {                if (newPC == thread->readPC()) {                    DPRINTF(Checker, "Changed PC matches expected PC\n");                } else {                    warn("%lli: Changed PC does not match expected PC, "                         "changed: %#x, expected: %#x",                         curTick, thread->readPC(), newPC);                    CheckerCPU::handleError();                }                willChangePC = false;            }            changedPC = false;        }        if (changedNextPC) {            DPRINTF(Checker, "Changed NextPC recently to %#x\n",                    thread->readNextPC());            changedNextPC = false;        }        // Try to fetch the instruction#if FULL_SYSTEM#define IFETCH_FLAGS(pc)	((pc) & 1) ? PHYSICAL : 0#else#define IFETCH_FLAGS(pc)	0#endif        uint64_t fetch_PC = thread->readPC() & ~3;        // set up memory request for instruction fetch        memReq = new Request(inst->threadNumber, fetch_PC,                             sizeof(uint32_t),                             IFETCH_FLAGS(thread->readPC()),                             fetch_PC, thread->readCpuId(), inst->threadNumber);        bool succeeded = translateInstReq(memReq);        if (!succeeded) {            if (inst->getFault() == NoFault) {                // In this case the instruction was not a dummy                // instruction carrying an ITB fault.  In the single                // threaded case the ITB should still be able to                // translate this instruction; in the SMT case it's                // possible that its ITB entry was kicked out.                warn("%lli: Instruction PC %#x was not found in the ITB!",                     curTick, thread->readPC());                handleError(inst);                // go to the next instruction                thread->setPC(thread->readNextPC());                thread->setNextPC(thread->readNextPC() + sizeof(MachInst));                break;            } else {                // The instruction is carrying an ITB fault.  Handle                // the fault and see if our results match the CPU on                // the next tick().                fault = inst->getFault();            }        }        if (fault == NoFault) {            PacketPtr pkt = new Packet(memReq, Packet::ReadReq,                                     Packet::Broadcast);            pkt->dataStatic(&machInst);            icachePort->sendFunctional(pkt);            delete pkt;            // keep an instruction count            numInst++;            // decode the instruction            machInst = gtoh(machInst);            // Checks that the instruction matches what we expected it to be.            // Checks both the machine instruction and the PC.            validateInst(inst);#if THE_ISA == ALPHA_ISA            curStaticInst = StaticInst::decode(makeExtMI(machInst,                                                         thread->readPC()));#elif THE_ISA == SPARC_ISA            curStaticInst = StaticInst::decode(makeExtMI(machInst,                                                         thread->getTC()));#endif#if FULL_SYSTEM            thread->setInst(machInst);#endif // FULL_SYSTEM            fault = inst->getFault();        }        // Discard fetch's memReq.        delete memReq;        memReq = NULL;        // Either the instruction was a fault and we should process the fault,        // or we should just go ahead execute the instruction.  This assumes        // that the instruction is properly marked as a fault.        if (fault == NoFault) {            thread->funcExeInst++;            if (!inst->isUnverifiable())                fault = curStaticInst->execute(this, NULL);            // Checks to make sure instrution results are correct.            validateExecution(inst);            if (curStaticInst->isLoad()) {                ++numLoad;            }        }        if (fault != NoFault) {#if FULL_SYSTEM            fault->invoke(tc);            willChangePC = true;

⌨️ 快捷键说明

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