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

📄 bus.cc

📁 linux下基于c++的处理器仿真平台。具有处理器流水线
💻 CC
📖 第 1 页 / 共 2 页
字号:
    int responding_interface_id = -1;    MemAccessResult retval = BA_NO_RESULT;    MemAccessResult tmp_retval = BA_NO_RESULT;    DPRINTF(Bus, "issuing req %s addr %x from id %d, name %s\n",	    req->cmd.toString(), req->paddr,	    req->busId, interfaces[req->busId]->name());    for (int i = 0; i < numInterfaces; i++) {	if (interfaces[req->busId] != transmitInterfaces[i]) {	    tmp_retval = transmitInterfaces[i]->access(req);	} else {	    tmp_retval = BA_NO_RESULT;	}	if (req->isNacked()) {	    //Can only get a NACK if the block was owned, it won't satisfy	    assert(!req->isSatisfied());	    //Clear the flags before retrying request	    DPRINTF(Bus, "Blk: %x Nacked by id:%d\n",		    req->paddr & (((ULL(1))<<48)-1), i);	    req->flags &= ~NACKED_LINE;	    return false;	    //Signal failure, it will retry for bus	}	if (tmp_retval != BA_NO_RESULT) {	    if (retval != BA_NO_RESULT) {		fatal("Two suppliers for address %#x on bus %s", req->paddr,		      name());	    }	    retval = tmp_retval;	    responding_interface_id = transmitInterfaces[i]->getId();	}    }    if (retval == BA_NO_RESULT && (req->cmd.isRead() || req->cmd.isWrite())) {	fatal("No supplier for address %#x on bus %s", req->paddr, name());    }    if (retval == BA_SUCCESS) {	DPRINTF(Bus, "request for blk %x from id:%d satisfied by id:%d\n",		req->paddr & (((ULL(1))<<48)-1), req->busId,		responding_interface_id);    }    // If any request if blocked by a memory interface, it blocks    // the whole bus because the request is still outstanding on    // the wire.  We cannot let _any_ other request go through.    switch (retval) {      case BA_BLOCKED:	  DPRINTF(Bus, "Bus Blocked, waiting for id:%d on blk_adr: %x\n",		  responding_interface_id, req->paddr & (((ULL(1))<<48)-1));	  blockedReq = req;	  blockSync = true; //This is a synchronus block	  return true;	  break;      case BA_SUCCESS:	  break;      case BA_NO_RESULT:	  break;      default:	panic("Illegal bus result %d\n", retval);	break;    };        assert(curTick % clockRate == 0);        //New callback function    //May want to use this to move some requests in front of a NACKED    //request (depending on consistency model    interfaces[req->busId]->snoopResponseCall(req);    return true;}void Bus::delayData(int size){    int transfer_cycles = DivCeil(size, width);    //int transfer_time = transfer_cycles * clockRate;    assert(curTick >= nextDataFree);    dataIdleCycles += (curTick - nextDataFree);    // assumes we are cycle aligned right now    assert(curTick % clockRate == 0);    nextDataFree = nextBusClock(curTick,transfer_cycles);}voidBus::sendData(MemReqPtr &req, Tick origReqTime){    // put it here so we know requesting thread    dataRequests[req->thread_num]++;       assert(doEvents());    int transfer_cycles = DivCeil(req->size, width);        assert(curTick >= nextDataFree);    dataQdly[req->thread_num] += curTick - origReqTime;    dataIdleCycles += (curTick - nextDataFree);    nextDataFree = nextBusClock(curTick,transfer_cycles);    DeliverEvent *tmp = new DeliverEvent(interfaces[req->busId], req);    // let the cache figure out Critical word first    // schedule event after first block delivered    tmp->schedule(curTick + clockRate);}voidBus::sendAck(MemReqPtr &req, Tick origReqTime){    addrRequests[req->thread_num]++;       assert(doEvents());    addrQdly[req->thread_num] += curTick - origReqTime;    addrIdleCycles += curTick - nextAddrFree;    // Advance nextAddrFree to next clock cycle    nextAddrFree = nextBusClock(curTick);    DeliverEvent *tmp = new DeliverEvent(interfaces[req->busId], req);    tmp->schedule(curTick + clockRate);    DPRINTF(Bus, "sendAck: scheduling deliver for %x on id %d @ %d\n",            req->paddr, req->busId, curTick + clockRate);}intBus::registerInterface(BusInterface<Bus> *bi, bool master){    assert(numInterfaces == interfaces.size());    interfaces.push_back(bi);    addrBusRequests.push_back(BusRequestRecord());    dataBusRequests.push_back(BusRequestRecord());    DPRINTF(Bus, "registering interface %s as %s\n",	    bi->name(), master ? "master" : "slave");    if (master) {	transmitInterfaces.insert(transmitInterfaces.begin(),bi);    } else {	transmitInterfaces.push_back(bi);    }    return numInterfaces++;}voidBus::clearBlocked(int id){    assert(!isBlocked() || doEvents());    if (isBlocked() && waitingFor == id) {	DPRINTF(Bus, "Unblocking\n");	if (blockSync) {	    DPRINTF(Bus, "Bus UnBlocked, waiting for id:%d on blk_adr: %x\n",		    id, blockedReq->paddr & (((ULL(1))<<48)-1));	}	//Only arbitrate if request exists	//Need to make sure it wasn't requested for later time	int grant_id, old_grant_id; // used for rescheduling	if (findOldestRequest(addrBusRequests,grant_id,old_grant_id)) {	    nextAddrFree = nextBusClock(curTick,1);	    Tick time = addrBusRequests[grant_id].requestTime;	    if (time <= curTick) { 		addrArbiterEvent->schedule(nextBusClock(curTick,2));	    }	    else {		scheduleArbitrationEvent(addrArbiterEvent,time,nextAddrFree,2);	    }	}	blocked = false;	waitingFor = -1;	busBlockedCycles += curTick - busBlockedTime;    }}voidBus::setBlocked(int id){    if (blocked) warn("Blocking on a second cause???\n");    DPRINTF(Bus, "Blocked, waiting for id:%d\n", id);    blocked = true;    waitingFor = id;    busBlockedTime = curTick;    busBlocked++;    blockSync = false;    if (addrArbiterEvent->scheduled()) {	addrArbiterEvent->deschedule();    }}boolBus::findOldestRequest(std::vector<BusRequestRecord> & requests,			   int & grant_id, int & old_grant_id){    grant_id = -1;    old_grant_id = -1;    Tick grant_time = TICK_T_MAX; // set to arbitrarily large number    Tick old_grant_time = TICK_T_MAX;    for (int i=0; i<numInterfaces; i++) {	if (requests[i].requested) {	    if (requests[i].requestTime < grant_time) {		old_grant_time = grant_time;		grant_time = requests[i].requestTime;		old_grant_id = grant_id;		grant_id = i;	    }	    else if (requests[i].requestTime < old_grant_time) {		old_grant_time = requests[i].requestTime;		old_grant_id = i;	    }	}    }    return (grant_id != -1);}voidBus::scheduleArbitrationEvent(Event * arbiterEvent, Tick reqTime,			      Tick nextFreeCycle, Tick idleAdvance){    bool bus_idle = (nextFreeCycle <= curTick);    Tick next_schedule_time;    if (bus_idle) {	if (reqTime < curTick) {	    next_schedule_time = nextBusClock(curTick,idleAdvance);	} else {	    next_schedule_time = nextBusClock(reqTime,idleAdvance);	}    } else {	if (reqTime < nextFreeCycle) {	    next_schedule_time = nextFreeCycle;	} else {	    next_schedule_time = nextBusClock(reqTime,idleAdvance);	}    }    if (arbiterEvent->scheduled()) {	if (arbiterEvent->when() > next_schedule_time) {	    arbiterEvent->reschedule(next_schedule_time);            DPRINTF(Bus, "Rescheduling arbiter event for cycle %d\n",                    next_schedule_time);	}    } else {	arbiterEvent->schedule(next_schedule_time);        DPRINTF(Bus, "scheduling arbiter event for cycle %d\n",                next_schedule_time);    }}TickBus::probe(MemReqPtr &req, bool update){    bool satisfied = req->isSatisfied();    Tick time_sat = 0;    for (int i = 0; i < numInterfaces; i++) {	if (interfaces[req->busId] != transmitInterfaces[i]) {	    if (!satisfied) {		time_sat = transmitInterfaces[i]->probe(req, update);		satisfied = req->isSatisfied();	    } else {		transmitInterfaces[i]->probe(req, update);	    }	}    }    assert(satisfied);    return time_sat;}voidBus::collectRanges(list<Range<Addr> > &range_list){    for (int i = 0; i < numInterfaces; ++i) {	interfaces[i]->getRange(range_list);    }}voidBus::rangeChange(){    for (int i = 0; i < numInterfaces; ++i) {	interfaces[i]->rangeChange();    }}// Event implementationsvoidAddrArbiterEvent::process(){    bus->arbitrateAddrBus();}const char *AddrArbiterEvent::description(){    return "address bus arbitration";}voidDataArbiterEvent::process(){    DPRINTF(Bus, "Data Arb processing event\n");    bus->arbitrateDataBus();}const char *DataArbiterEvent::description(){    return "data bus arbitration";}voidDeliverEvent::process(){    bi->deliver(req);    delete this;}const char *DeliverEvent::description(){    return "bus deliver";}#ifndef DOXYGEN_SHOULD_SKIP_THISBEGIN_DECLARE_SIM_OBJECT_PARAMS(Bus)    Param<int> width;    Param<int> clock;    SimObjectParam<HierParams *> hier;END_DECLARE_SIM_OBJECT_PARAMS(Bus)BEGIN_INIT_SIM_OBJECT_PARAMS(Bus)    INIT_PARAM(width, "bus width in bytes"),    INIT_PARAM(clock, "bus frequency"),    INIT_PARAM_DFLT(hier,		    "Hierarchy global variables",		    &defaultHierParams)END_INIT_SIM_OBJECT_PARAMS(Bus)CREATE_SIM_OBJECT(Bus){    return new Bus(getInstanceName(), hier,		   width, clock);}REGISTER_SIM_OBJECT("Bus", Bus)#endif //DOXYGEN_SHOULD_SKIP_THIS

⌨️ 快捷键说明

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