summaryrefslogtreecommitdiff
path: root/src/mem/bus.cc
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2006-10-09 23:24:21 -0400
committerGabe Black <gblack@eecs.umich.edu>2006-10-09 23:24:21 -0400
commitab444172828e26dfdd35f4a9fcc9c73b9693f7fe (patch)
tree80b469846871fbfda2d8c084441dc7a3f757aea1 /src/mem/bus.cc
parent5448517da4cd13e3c8438850f04367d9614d686b (diff)
downloadgem5-ab444172828e26dfdd35f4a9fcc9c73b9693f7fe.tar.xz
Fixes to the bus, and added fields to the packet.
src/mem/bus.cc: Put back the check to see if the bus is busy. Also, populate the fields in the packet to indicate when the first word and the entire packet will be delivered. src/mem/bus.hh: Remove the occupyBus function. src/mem/packet.hh: Added fields to the packet to indicate when the first chunk of a packet arrives, and when the entire packet arrives. --HG-- extra : convert_revision : cfc7670a33913d48a04d02c6d2448290a51f2d3c
Diffstat (limited to 'src/mem/bus.cc')
-rw-r--r--src/mem/bus.cc68
1 files changed, 39 insertions, 29 deletions
diff --git a/src/mem/bus.cc b/src/mem/bus.cc
index 7584ffffd..66cd581e7 100644
--- a/src/mem/bus.cc
+++ b/src/mem/bus.cc
@@ -82,33 +82,6 @@ const char * Bus::BusFreeEvent::description()
return "bus became available";
}
-void
-Bus::occupyBus(int numCycles)
-{
- //Move up when the bus will next be free
- //We avoid the use of divide by adding repeatedly
- //This should be faster if the value is updated frequently, but should
- //be may be slower otherwise.
-
- //Bring tickNextIdle up to the present tick
- //There is some potential ambiguity where a cycle starts, which might make
- //a difference when devices are acting right around a cycle boundary. Using
- //a < allows things which happen exactly on a cycle boundary to take up only
- //the following cycle. Anthing that happens later will have to "wait" for the
- //end of that cycle, and then start using the bus after that.
- while (tickNextIdle < curTick)
- tickNextIdle += clock;
- //Advance it numCycles bus cycles.
- //XXX Should this use the repeating add trick as well?
- tickNextIdle += (numCycles * clock);
- if (!busIdle.scheduled()) {
- busIdle.schedule(tickNextIdle);
- } else {
- busIdle.reschedule(tickNextIdle);
- }
- DPRINTF(Bus, "The bus is now occupied from tick %d to %d\n", curTick, tickNextIdle);
-}
-
/** Function called by the port when the bus is receiving a Timing
* transaction.*/
bool
@@ -120,6 +93,14 @@ Bus::recvTiming(Packet *pkt)
Port *pktPort = interfaces[pkt->getSrc()];
+ // If the bus is busy, or other devices are in line ahead of the current
+ // one, put this device on the retry list.
+ if (tickNextIdle > curTick ||
+ (retryList.size() && pktPort != retryingPort)) {
+ addToRetryList(pktPort);
+ return false;
+ }
+
short dest = pkt->getDest();
if (dest == Packet::Broadcast) {
if (timingSnoop(pkt)) {
@@ -146,7 +127,17 @@ Bus::recvTiming(Packet *pkt)
port = interfaces[dest];
}
- // The packet will be sent. Figure out how long it occupies the bus.
+ //Bring tickNextIdle up to the present tick
+ //There is some potential ambiguity where a cycle starts, which might make
+ //a difference when devices are acting right around a cycle boundary. Using
+ //a < allows things which happen exactly on a cycle boundary to take up only
+ //the following cycle. Anthing that happens later will have to "wait" for
+ //the end of that cycle, and then start using the bus after that.
+ while (tickNextIdle < curTick)
+ tickNextIdle += clock;
+
+ // The packet will be sent. Figure out how long it occupies the bus, and
+ // how much of that time is for the first "word", aka bus width.
int numCycles = 0;
// Requests need one cycle to send an address
if (pkt->isRequest())
@@ -167,7 +158,26 @@ Bus::recvTiming(Packet *pkt)
}
}
- occupyBus(numCycles);
+ // The first word will be delivered after the current tick, the delivery
+ // of the address if any, and one bus cycle to deliver the data
+ pkt->firstWordTime =
+ tickNextIdle +
+ pkt->isRequest() ? clock : 0 +
+ clock;
+
+ //Advance it numCycles bus cycles.
+ //XXX Should this use the repeated addition trick as well?
+ tickNextIdle += (numCycles * clock);
+ if (!busIdle.scheduled()) {
+ busIdle.schedule(tickNextIdle);
+ } else {
+ busIdle.reschedule(tickNextIdle);
+ }
+ DPRINTF(Bus, "The bus is now occupied from tick %d to %d\n",
+ curTick, tickNextIdle);
+
+ // The bus will become idle once the current packet is delivered.
+ pkt->finishTime = tickNextIdle;
if (port->sendTiming(pkt)) {
// Packet was successfully sent. Return true.