Beispiel #1
0
void SMPCache::returnAccess(MemRequest *mreq)
{
  SMPMemRequest *sreq = static_cast<SMPMemRequest *>(mreq);
  MemOperation memOp = sreq->getMemOperation();

  if(sreq->getRequestor() == this) {
    // request from this cache (response is ready)

    if(memOp == MemRead) {
      protocol->readMissAckHandler(sreq);
    } 
    else if(memOp == MemReadW) {
      if(sreq->needsData()) {
	protocol->writeMissAckHandler(sreq);
      } else {
	protocol->invalidateAckHandler(sreq);
      }
    } 
    else if(memOp == MemWrite) {
      I(!sreq->needsData());
      I(sreq->needsSnoop());
      protocol->invalidateAckHandler(sreq);
    }
    else if(memOp == MemPush) {
      protocol->writeBackAckHandler(sreq);
    }
  } else {
    receiveFromBelow(sreq);
  }
}
Beispiel #2
0
void SMPSystemBus::doWrite(MemRequest *mreq)
{
  SMPMemRequest *sreq = static_cast<SMPMemRequest *>(mreq);

  // no need to snoop, go straight to memory
  if(!sreq->needsSnoop()) {
    goToMem(mreq);
    return;
  }

  if(pendReqsTable.find(mreq) == pendReqsTable.end()) {

    unsigned numSnoops = getNumSnoopCaches(sreq);

    // operation is starting now, add it to the pending requests buffer
    pendReqsTable[mreq] = getNumSnoopCaches(sreq);

    if(!numSnoops) { 
      // nothing to snoop on this chip
      finalizeWrite(mreq);
      return;
      // TODO: even if there is only one processor on each chip, 
      // request is doing two rounds: snoop and memory
    }

	//VERSION COMBINING REGISTER ALLOCATED HERE
	#ifdef TLS
		if (mreq->isDataReq()&& sreq->needsData())VCRCount++;
	#endif
    // distribute requests to other caches, wait for responses
	 for(uint i = 0; i < upperLevel.size(); i++) {
      if(upperLevel[i] != static_cast<SMPMemRequest *>(mreq)->getRequestor()) {
	upperLevel[i]->returnAccess(mreq);
      }
    }
  } 
  else {
    // operation has already been sent to other caches, receive responses

    I(pendReqsTable[mreq] > 0);
    I(pendReqsTable[mreq] <= (int) upperLevel.size());

    pendReqsTable[mreq]--;
    if(pendReqsTable[mreq] != 0) {
      // this is an intermediate response, request is not serviced yet
      return;
    }

    // this is the final response, request can go up now
    finalizeWrite(mreq);
  }
}
Beispiel #3
0
void SMPSystemBus::doPush(MemRequest *mreq)
{
#ifdef TLS
   SMPMemRequest *sreq = static_cast<SMPMemRequest *>(mreq);
   TimeDelta_t VCRDelay;
   PAddr addr= mreq->getPAddr();
  // no need to snoop, go straight to memory
  if(!sreq->needsSnoop()) {
    goToMem(mreq);
    return;
  }

  if(pendReqsTable.find(mreq) == pendReqsTable.end()) {

    unsigned numSnoops = getNumSnoopCaches(sreq);

    // operation is starting now, add it to the pending requests buffer
    pendReqsTable[mreq] = getNumSnoopCaches(sreq);

   	VCRCount++;
    // distribute requests to other caches, wait for responses
    for(uint i = 0; i < upperLevel.size(); i++) {
      if(upperLevel[i] != static_cast<SMPMemRequest *>(mreq)->getRequestor()) {
	upperLevel[i]->returnAccess(mreq);
      }
    }
  return;
  } 
  else {
    // operation has already been sent to other caches, receive responses

    I(pendReqsTable[mreq] > 0);
    I(pendReqsTable[mreq] <= (int) upperLevel.size());

    pendReqsTable[mreq]--;
    if(pendReqsTable[mreq] != 0) {
      // this is an intermediate response, request is not serviced yet
      return;
    }

    // this is the final response, Request will now be sent down
    VCRDelay=finalizePush(mreq);
    mreq->goDown(VCRDelay+delay, lowerLevel[0]);
  }
 #else 
  	mreq->goDown(delay, lowerLevel[0]);
 #endif
}