diff options
-rw-r--r-- | src/mem/bus.cc | 61 | ||||
-rw-r--r-- | 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 @@ -176,26 +201,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) { /* An interval tree would be a better way to do this. --ali. */ 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. |