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",
|
DPRINTF(Bus, "recvTiming: packet src %d dest %d addr 0x%x cmd %s\n",
|
||||||
pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString());
|
pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString());
|
||||||
|
|
||||||
|
Port *pktPort = interfaces[pkt->getSrc()];
|
||||||
|
|
||||||
short dest = pkt->getDest();
|
short dest = pkt->getDest();
|
||||||
if (dest == Packet::Broadcast) {
|
if (dest == Packet::Broadcast) {
|
||||||
if ( timingSnoopPhase1(pkt) )
|
if (timingSnoop(pkt)) {
|
||||||
if (timingSnoop(pkt))
|
|
||||||
{
|
|
||||||
timingSnoopPhase2(pkt);
|
|
||||||
pkt->flags |= SNOOP_COMMIT;
|
pkt->flags |= SNOOP_COMMIT;
|
||||||
bool success = timingSnoop(pkt);
|
bool success = timingSnoop(pkt);
|
||||||
assert(success);
|
assert(success);
|
||||||
if (pkt->flags & SATISFIED) {
|
if (pkt->flags & SATISFIED) {
|
||||||
//Cache-Cache transfer occuring
|
//Cache-Cache transfer occuring
|
||||||
|
if (retryingPort) {
|
||||||
|
retryList.pop_front();
|
||||||
|
retryingPort = NULL;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
port = findPort(pkt->getAddr(), pkt->getSrc());
|
port = findPort(pkt->getAddr(), pkt->getSrc());
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
//Snoop didn't succeed
|
//Snoop didn't succeed
|
||||||
retryList.push_back(interfaces[pkt->getSrc()]);
|
addToRetryList(pktPort);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -144,6 +145,30 @@ Bus::recvTiming(Packet *pkt)
|
||||||
assert(dest != pkt->getSrc()); // catch infinite loops
|
assert(dest != pkt->getSrc()); // catch infinite loops
|
||||||
port = interfaces[dest];
|
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)) {
|
if (port->sendTiming(pkt)) {
|
||||||
// Packet was successfully sent. Return true.
|
// Packet was successfully sent. Return true.
|
||||||
// Also take care of retries
|
// 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 *
|
Port *
|
||||||
Bus::findPort(Addr addr, int id)
|
Bus::findPort(Addr addr, int id)
|
||||||
{
|
{
|
||||||
|
|
|
@ -97,15 +97,6 @@ class Bus : public MemObject
|
||||||
*/
|
*/
|
||||||
Port *findPort(Addr addr, int id);
|
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
|
/** 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
|
* that the ranges shouldn't overlap or you will get a double snoop to the same
|
||||||
* interface.and the cache will assert out.
|
* interface.and the cache will assert out.
|
||||||
|
|
Loading…
Reference in a new issue