summaryrefslogtreecommitdiff
path: root/src/mem/bus.cc
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2008-02-26 02:20:08 -0500
committerGabe Black <gblack@eecs.umich.edu>2008-02-26 02:20:08 -0500
commitec1a4cbbc73ecc1d7456d11c571c425e226a7d3b (patch)
treef6d238a8385a5bdcfedb39239ccd14a69ea83976 /src/mem/bus.cc
parent2e079ce038dcce2c5328d840f8b57290bef8c794 (diff)
downloadgem5-ec1a4cbbc73ecc1d7456d11c571c425e226a7d3b.tar.xz
Bus: Fix the bus timing to be more realistic.
--HG-- extra : convert_revision : acd70dc98ab840e55b114706fbb6afb2a95e54bc
Diffstat (limited to 'src/mem/bus.cc')
-rw-r--r--src/mem/bus.cc48
1 files changed, 25 insertions, 23 deletions
diff --git a/src/mem/bus.cc b/src/mem/bus.cc
index f47d48d0b..ff4512aca 100644
--- a/src/mem/bus.cc
+++ b/src/mem/bus.cc
@@ -110,7 +110,7 @@ const char * Bus::BusFreeEvent::description() const
return "bus became available";
}
-void Bus::occupyBus(PacketPtr pkt)
+void Bus::preparePacket(PacketPtr pkt, Tick & headerTime)
{
//Bring tickNextIdle up to the present tick
//There is some potential ambiguity where a cycle starts, which might make
@@ -124,34 +124,30 @@ void Bus::occupyBus(PacketPtr pkt)
tickNextIdle = curTick - (curTick % clock) + clock;
}
+ headerTime = tickNextIdle + headerCycles * 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())
- numCycles++;
- else if (pkt->isResponse() || pkt->hasData()) {
+ if (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();
- numCycles += dataSize/width;
- if (dataSize % 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.
+ int dataSize = pkt->getSize();
+ numCycles += dataSize/width;
+ if (dataSize % width)
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;
+ pkt->firstWordTime = headerTime + clock;
+
+ pkt->finishTime = headerTime + numCycles * clock;
+}
+
+void Bus::occupyBus(Tick until)
+{
+ tickNextIdle = until;
- //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 {
@@ -159,9 +155,6 @@ void Bus::occupyBus(PacketPtr pkt)
}
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;
}
/** Function called by the port when the bus is receiving a Timing
@@ -197,8 +190,10 @@ Bus::recvTiming(PacketPtr pkt)
DPRINTF(Bus, "recvTiming: src %d dst %d %s 0x%x\n",
src, pkt->getDest(), pkt->cmdString(), pkt->getAddr());
+ Tick headerTime = 0;
+
if (!pkt->isExpressSnoop()) {
- occupyBus(pkt);
+ preparePacket(pkt, headerTime);
}
short dest = pkt->getDest();
@@ -248,11 +243,18 @@ Bus::recvTiming(PacketPtr pkt)
DPRINTF(Bus, "recvTiming: src %d dst %d %s 0x%x TGT RETRY\n",
src, pkt->getDest(), pkt->cmdString(), pkt->getAddr());
addToRetryList(src_port);
+ if (!pkt->isExpressSnoop()) {
+ occupyBus(headerTime);
+ }
return false;
}
// send OK, fall through
}
+ if (!pkt->isExpressSnoop()) {
+ occupyBus(pkt->finishTime);
+ }
+
// Packet was successfully sent.
// Also take care of retries
if (inRetry) {