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
This commit is contained in:
parent
2df9053bb0
commit
187dcb18bf
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue