From 187dcb18bfd87db63ad914d2ba04f0bd2dc0637d Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 9 Oct 2006 18:12:45 -0400 Subject: [PATCH] Potentially functional partially timed bandwidth limitted bus model. src/mem/bus.cc: Fixes to the previous hand merging, and put the snooping back into recvTiming and out of it's own function. src/mem/bus.hh: Put snooping back into recvTiming and not in it's own function. --HG-- extra : convert_revision : fd031b7e6051a5be07ed6926454fde73b1739dc6 --- src/mem/bus.cc | 61 +++++++++++++++++++++++++++----------------------- src/mem/bus.hh | 9 -------- 2 files changed, 33 insertions(+), 37 deletions(-) diff --git a/src/mem/bus.cc b/src/mem/bus.cc index df85ee0d9..c288e34c0 100644 --- a/src/mem/bus.cc +++ b/src/mem/bus.cc @@ -118,25 +118,26 @@ Bus::recvTiming(Packet *pkt) DPRINTF(Bus, "recvTiming: packet src %d dest %d addr 0x%x cmd %s\n", pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString()); + Port *pktPort = interfaces[pkt->getSrc()]; + short dest = pkt->getDest(); if (dest == Packet::Broadcast) { - if ( timingSnoopPhase1(pkt) ) - if (timingSnoop(pkt)) - { - timingSnoopPhase2(pkt); + if (timingSnoop(pkt)) { pkt->flags |= SNOOP_COMMIT; bool success = timingSnoop(pkt); assert(success); if (pkt->flags & SATISFIED) { //Cache-Cache transfer occuring + if (retryingPort) { + retryList.pop_front(); + retryingPort = NULL; + } return true; } port = findPort(pkt->getAddr(), pkt->getSrc()); - } - else - { + } else { //Snoop didn't succeed - retryList.push_back(interfaces[pkt->getSrc()]); + addToRetryList(pktPort); return false; } } else { @@ -144,6 +145,30 @@ Bus::recvTiming(Packet *pkt) assert(dest != pkt->getSrc()); // catch infinite loops port = interfaces[dest]; } + + // The packet will be sent. Figure out how long it occupies the bus. + int numCycles = 0; + // Requests need one cycle to send an address + if (pkt->isRequest()) + numCycles++; + else if (pkt->isResponse() || pkt->hasData()) { + // If a packet has data, it needs ceil(size/width) cycles to send it + // We're using the "adding instead of dividing" trick again here + if (pkt->hasData()) { + int dataSize = pkt->getSize(); + for (int transmitted = 0; transmitted < dataSize; + transmitted += width) { + numCycles++; + } + } else { + // If the packet didn't have data, it must have been a response. + // Those use the bus for one cycle to send their data. + numCycles++; + } + } + + occupyBus(numCycles); + if (port->sendTiming(pkt)) { // Packet was successfully sent. Return true. // Also take care of retries @@ -175,26 +200,6 @@ Bus::recvRetry(int id) } } -Port * -Bus::findDestPort(PacketPtr pkt, int id) -{ - Port * port = NULL; - short dest = pkt->getDest(); - - if (dest == Packet::Broadcast) { - if (timingSnoopPhase1(pkt)) { - timingSnoopPhase2(pkt); - port = findPort(pkt->getAddr(), pkt->getSrc()); - } - //else, port stays NULL - } else { - assert(dest >= 0 && dest < interfaces.size()); - assert(dest != pkt->getSrc()); // catch infinite loops - port = interfaces[dest]; - } - return port; -} - Port * Bus::findPort(Addr addr, int id) { diff --git a/src/mem/bus.hh b/src/mem/bus.hh index f8a006911..c9b0a76a0 100644 --- a/src/mem/bus.hh +++ b/src/mem/bus.hh @@ -97,15 +97,6 @@ class Bus : public MemObject */ Port *findPort(Addr addr, int id); - /** Finds the port a packet should be sent to. If the bus is blocked, no port - * is returned. - * @param pkt Packet to find a destination port for. - * @param id Id of the port this packet was received from - * (to prevent loops) - */ - - Port *findDestPort(PacketPtr pkt, int id); - /** Find all ports with a matching snoop range, except src port. Keep in mind * that the ranges shouldn't overlap or you will get a double snoop to the same * interface.and the cache will assert out.