Example #1
0
void PriorityBus::processQ()
{
  // if this was called, there *must* be a req waiting
  I(!allQueuesEmpty());

  int32_t selectedQ = -1; 
  for(int32_t q = 0; q < LastQ; q++) {
    if(!reqQs[q].empty()) {
      selectedQ = q;
      break;
    }
  }

  I(selectedQ != -1);

  MemRequest *mreq = reqQs[selectedQ].front();
  reqQs[selectedQ].pop_front();

  Time_t reqArrivalTime = timeQs[selectedQ].front();
  timeQs[selectedQ].pop_front();

  //determining when to dispatch the request
  bool goUp = ((selectedQ == upHighP) || (selectedQ == upLowP));
  Time_t when = 0;
  if(goUp) {
    if (mreq->getMemOperation() == MemPush || mreq->getMemOperation() == MemWrite) {
      when = busPort->nextSlot(controlOcc);
    }else{
      when = busPort->nextSlot(dataOcc)+delay;
    }
  } else { // req is going down
    if (mreq->getMemOperation() == MemPush || mreq->getMemOperation() == MemWrite) {
      when = busPort->nextSlot(dataOcc)+delay;
    }else{
      when = busPort->nextSlot(controlOcc);
    }
  }

  tHist[selectedQ]->sample(reqQs[selectedQ].size());
  avgTime[selectedQ]->sample(when - reqArrivalTime);

  //counting the different types of bypass
  if(selectedQ == upHighP && !timeQs[upLowP].empty()) {
    if(reqArrivalTime > timeQs[upLowP].front())
      nBypassUp.inc();
  }
  if(selectedQ == downHighP && !timeQs[downLowP].empty()) {
    if(reqArrivalTime > timeQs[downLowP].front())
      nBypassDown.inc();
  }
  if(selectedQ == upHighP && !timeQs[downLowP].empty()) {
    // a req with high prio going up bypassed a low prio req going down
    if(reqArrivalTime > timeQs[downLowP].front())
      nBypassDirection.inc();
  }

  // scheduling next callback *has* to be before sending reqs up or down.
  if(!allQueuesEmpty())
    processQCB.scheduleAbs(busPort->calcNextSlot());

  // dispatching the request
  if(goUp)
    mreq->goUpAbs(when);
  else
    mreq->goDownAbs(when, lowerLevel[0]);
}