⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpu.cc

📁 linux下基于c++的处理器仿真平台。具有处理器流水线
💻 CC
📖 第 1 页 / 共 2 页
字号:
templateFaultSimpleCPU::read(Addr addr, uint8_t &data, unsigned flags);#endif //DOXYGEN_SHOULD_SKIP_THIStemplate<>FaultSimpleCPU::read(Addr addr, double &data, unsigned flags){    return read(addr, *(uint64_t*)&data, flags);}template<>FaultSimpleCPU::read(Addr addr, float &data, unsigned flags){    return read(addr, *(uint32_t*)&data, flags);}template<>FaultSimpleCPU::read(Addr addr, int32_t &data, unsigned flags){    return read(addr, (uint32_t&)data, flags);}template <class T>FaultSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res){    memReq->reset(addr, sizeof(T), flags);    // translate to physical address    Fault fault = xc->translateDataWriteReq(memReq);    // do functional access    if (fault == No_Fault)	fault = xc->write(memReq, data);    if (fault == No_Fault && dcacheInterface) {	memReq->cmd = Write;	memcpy(memReq->data,(uint8_t *)&data,memReq->size);	memReq->completionEvent = NULL;	memReq->time = curTick;	MemAccessResult result = dcacheInterface->access(memReq);	// Ugly hack to get an event scheduled *only* if the access is	// a miss.  We really should add first-class support for this	// at some point.	if (result != MA_HIT && dcacheInterface->doEvents()) {	    memReq->completionEvent = &cacheCompletionEvent;	    lastDcacheStall = curTick;	    unscheduleTickEvent();	    _status = DcacheMissStall;	}    }    if (res && (fault == No_Fault))	*res = memReq->result;    if (!dcacheInterface && (memReq->flags & UNCACHEABLE))	recordEvent("Uncached Write");    return fault;}#ifndef DOXYGEN_SHOULD_SKIP_THIStemplateFaultSimpleCPU::write(uint64_t data, Addr addr, unsigned flags, uint64_t *res);templateFaultSimpleCPU::write(uint32_t data, Addr addr, unsigned flags, uint64_t *res);templateFaultSimpleCPU::write(uint16_t data, Addr addr, unsigned flags, uint64_t *res);templateFaultSimpleCPU::write(uint8_t data, Addr addr, unsigned flags, uint64_t *res);#endif //DOXYGEN_SHOULD_SKIP_THIStemplate<>FaultSimpleCPU::write(double data, Addr addr, unsigned flags, uint64_t *res){    return write(*(uint64_t*)&data, addr, flags, res);}template<>FaultSimpleCPU::write(float data, Addr addr, unsigned flags, uint64_t *res){    return write(*(uint32_t*)&data, addr, flags, res);}template<>FaultSimpleCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res){    return write((uint32_t)data, addr, flags, res);}#if FULL_SYSTEMAddrSimpleCPU::dbg_vtophys(Addr addr){    return vtophys(xc, addr);}#endif // FULL_SYSTEMvoidSimpleCPU::processCacheCompletion(){    switch (status()) {      case IcacheMissStall:	icacheStallCycles += curTick - lastIcacheStall;	_status = IcacheMissComplete;	scheduleTickEvent(1);	break;      case DcacheMissStall:	if (memReq->cmd.isRead()) {	    curStaticInst->execute(this,traceData);            if (traceData)                traceData->finalize();	}	dcacheStallCycles += curTick - lastDcacheStall;	_status = Running;	scheduleTickEvent(1);	break;      case DcacheMissSwitch:	if (memReq->cmd.isRead()) {	    curStaticInst->execute(this,traceData);            if (traceData)                traceData->finalize();	}	_status = SwitchedOut;    	sampler->signalSwitched();      case SwitchedOut:	// If this CPU has been switched out due to sampling/warm-up,	// ignore any further status changes (e.g., due to cache	// misses outstanding at the time of the switch).	return;      default:	panic("SimpleCPU::processCacheCompletion: bad state");	break;    }}#if FULL_SYSTEMvoidSimpleCPU::post_interrupt(int int_num, int index){    BaseCPU::post_interrupt(int_num, index);    if (xc->status() == ExecContext::Suspended) {		DPRINTF(IPI,"Suspended Processor awoke\n");	xc->activate();    }}#endif // FULL_SYSTEM/* start simulation, program loaded, processor precise state initialized */voidSimpleCPU::tick(){    numCycles++;    traceData = NULL;    Fault fault = No_Fault;#if FULL_SYSTEM    if (checkInterrupts && check_interrupts() && !xc->inPalMode() &&	status() != IcacheMissComplete) {	int ipl = 0;	int summary = 0;	checkInterrupts = false;	IntReg *ipr = xc->regs.ipr;	if (xc->regs.ipr[TheISA::IPR_SIRR]) {	    for (int i = TheISA::INTLEVEL_SOFTWARE_MIN;		 i < TheISA::INTLEVEL_SOFTWARE_MAX; i++) {		if (ipr[TheISA::IPR_SIRR] & (ULL(1) << i)) {		    // See table 4-19 of 21164 hardware reference		    ipl = (i - TheISA::INTLEVEL_SOFTWARE_MIN) + 1;		    summary |= (ULL(1) << i);		}	    }	}	uint64_t interrupts = xc->cpu->intr_status();	for (int i = TheISA::INTLEVEL_EXTERNAL_MIN;	    i < TheISA::INTLEVEL_EXTERNAL_MAX; i++) {	    if (interrupts & (ULL(1) << i)) {		// See table 4-19 of 21164 hardware reference		ipl = i;		summary |= (ULL(1) << i);	    }	}	if (ipr[TheISA::IPR_ASTRR])	    panic("asynchronous traps not implemented\n");	if (ipl && ipl > xc->regs.ipr[TheISA::IPR_IPLR]) {	    ipr[TheISA::IPR_ISR] = summary;	    ipr[TheISA::IPR_INTID] = ipl;	    xc->ev5_trap(Interrupt_Fault);	    DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",		    ipr[TheISA::IPR_IPLR], ipl, summary);	}    }#endif    // maintain $r0 semantics    xc->regs.intRegFile[ZeroReg] = 0;#ifdef TARGET_ALPHA    xc->regs.floatRegFile.d[ZeroReg] = 0.0;#endif // TARGET_ALPHA    if (status() == IcacheMissComplete) {	// We've already fetched an instruction and were stalled on an	// I-cache miss.  No need to fetch it again.	// Set status to running; tick event will get rescheduled if	// necessary at end of tick() function.	_status = Running;    }    else {	// Try to fetch an instruction	// set up memory request for instruction fetch#if FULL_SYSTEM#define IFETCH_FLAGS(pc)	((pc) & 1) ? PHYSICAL : 0#else#define IFETCH_FLAGS(pc)	0#endif	memReq->cmd = Read;	memReq->reset(xc->regs.pc & ~3, sizeof(uint32_t),		     IFETCH_FLAGS(xc->regs.pc));	fault = xc->translateInstReq(memReq);	if (fault == No_Fault)	    fault = xc->mem->read(memReq, inst);	if (icacheInterface && fault == No_Fault) {	    memReq->completionEvent = NULL;	    memReq->time = curTick;	    MemAccessResult result = icacheInterface->access(memReq);	    // Ugly hack to get an event scheduled *only* if the access is	    // a miss.  We really should add first-class support for this	    // at some point.	    if (result != MA_HIT && icacheInterface->doEvents()) {		memReq->completionEvent = &cacheCompletionEvent;		lastIcacheStall = curTick;		unscheduleTickEvent();		_status = IcacheMissStall;		return;	    }	}    }    // If we've got a valid instruction (i.e., no fault on instruction    // fetch), then execute it.    if (fault == No_Fault) {	// keep an instruction count	numInst++;	numInsts++;	// check for instruction-count-based events	comInstEventQueue[0]->serviceEvents(numInst);	// decode the instruction	inst = gtoh(inst);	curStaticInst = StaticInst<TheISA>::decode(inst);	traceData = Trace::getInstRecord(curTick, xc, this, curStaticInst,					 xc->regs.pc);#if FULL_SYSTEM        xc->setInst(inst);#endif // FULL_SYSTEM	xc->func_exe_inst++;	fault = curStaticInst->execute(this, traceData);#if FULL_SYSTEM	if (xc->fnbin)	    xc->execute(curStaticInst.get());#endif	if (curStaticInst->isMemRef()) {	    numMemRefs++;	}		if (curStaticInst->isLoad()) {	    ++numLoad;	    comLoadEventQueue[0]->serviceEvents(numLoad);	}           // If we have a dcache miss, then we can't finialize the instruction        // trace yet because we want to populate it with the data later	if (traceData &&                 !(status() == DcacheMissStall && memReq->cmd.isRead())) {	    traceData->finalize();        }	traceFunctions(xc->regs.pc);    }	// if (fault == No_Fault)    if (fault != No_Fault) {#if FULL_SYSTEM	xc->ev5_trap(fault);#else // !FULL_SYSTEM	fatal("fault (%d) detected @ PC 0x%08p", fault, xc->regs.pc);#endif // FULL_SYSTEM    }    else {	// go to the next instruction	xc->regs.pc = xc->regs.npc;	xc->regs.npc += sizeof(MachInst);    }#if FULL_SYSTEM    Addr oldpc;    do {	oldpc = xc->regs.pc;	system->pcEventQueue.service(xc);    } while (oldpc != xc->regs.pc);#endif    assert(status() == Running ||	   status() == Idle ||	   status() == DcacheMissStall);    if (status() == Running && !tickEvent.scheduled())	tickEvent.schedule(curTick + cycles(1));}////////////////////////////////////////////////////////////////////////////  SimpleCPU Simulation Object//BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU)    Param<Counter> max_insts_any_thread;    Param<Counter> max_insts_all_threads;    Param<Counter> max_loads_any_thread;    Param<Counter> max_loads_all_threads;#if FULL_SYSTEM    SimObjectParam<AlphaITB *> itb;    SimObjectParam<AlphaDTB *> dtb;    SimObjectParam<FunctionalMemory *> mem;    SimObjectParam<System *> system;    Param<int> cpu_id;#else    SimObjectParam<Process *> workload;#endif // FULL_SYSTEM    Param<int> clock;    SimObjectParam<BaseMem *> icache;    SimObjectParam<BaseMem *> dcache;    Param<bool> defer_registration;    Param<int> width;    Param<bool> function_trace;    Param<Tick> function_trace_start;END_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU)BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleCPU)    INIT_PARAM(max_insts_any_thread,	       "terminate when any thread reaches this inst count"),    INIT_PARAM(max_insts_all_threads,	       "terminate when all threads have reached this inst count"),    INIT_PARAM(max_loads_any_thread,	       "terminate when any thread reaches this load count"),    INIT_PARAM(max_loads_all_threads,	       "terminate when all threads have reached this load count"),#if FULL_SYSTEM    INIT_PARAM(itb, "Instruction TLB"),    INIT_PARAM(dtb, "Data TLB"),    INIT_PARAM(mem, "memory"),    INIT_PARAM(system, "system object"),    INIT_PARAM(cpu_id, "processor ID"),#else    INIT_PARAM(workload, "processes to run"),#endif // FULL_SYSTEM    INIT_PARAM(clock, "clock speed"),    INIT_PARAM(icache, "L1 instruction cache object"),    INIT_PARAM(dcache, "L1 data cache object"),    INIT_PARAM(defer_registration, "defer system registration (for sampling)"),    INIT_PARAM(width, "cpu width"),    INIT_PARAM(function_trace, "Enable function trace"),    INIT_PARAM(function_trace_start, "Cycle to start function trace")END_INIT_SIM_OBJECT_PARAMS(SimpleCPU)CREATE_SIM_OBJECT(SimpleCPU){    SimpleCPU::Params *params = new SimpleCPU::Params();    params->name = getInstanceName();    params->numberOfThreads = 1;    params->max_insts_any_thread = max_insts_any_thread;    params->max_insts_all_threads = max_insts_all_threads;    params->max_loads_any_thread = max_loads_any_thread;    params->max_loads_all_threads = max_loads_all_threads;    params->deferRegistration = defer_registration;    params->clock = clock;    params->functionTrace = function_trace;    params->functionTraceStart = function_trace_start;    params->icache_interface = (icache) ? icache->getInterface() : NULL;    params->dcache_interface = (dcache) ? dcache->getInterface() : NULL;    params->width = width;#if FULL_SYSTEM    params->itb = itb;    params->dtb = dtb;    params->mem = mem;    params->system = system;    params->cpu_id = cpu_id;#else    params->process = workload;#endif    SimpleCPU *cpu = new SimpleCPU(params);    return cpu;}REGISTER_SIM_OBJECT("SimpleCPU", SimpleCPU)

⌨️ 快捷键说明

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