summaryrefslogtreecommitdiff
path: root/src/mem/coherent_xbar.cc
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2015-09-25 07:13:54 -0400
committerAndreas Hansson <andreas.hansson@arm.com>2015-09-25 07:13:54 -0400
commit462c288a757bc4fd50324ebe2f1fd697d53838ab (patch)
tree02cc70a4d0682136b458ee59d5c9dad0dfdec00a /src/mem/coherent_xbar.cc
parent3bd78a141ec60ae65d910286c3d99ae7030ba703 (diff)
downloadgem5-462c288a757bc4fd50324ebe2f1fd697d53838ab.tar.xz
mem: Make the coherent crossbar account for timing snoops
This patch introduces the concept of a snoop latency. Given the requirement to snoop and forward packets in zero time (due to the coherency mechanism), the latency is accounted for later. On a snoop, we establish the latency, and later add it to the header delay of the packet. To allow multiple caches to contribute to the snoop latency, we use a separate variable in the packet, and then take the maximum before adding it to the header delay.
Diffstat (limited to 'src/mem/coherent_xbar.cc')
-rw-r--r--src/mem/coherent_xbar.cc16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/mem/coherent_xbar.cc b/src/mem/coherent_xbar.cc
index 52f69e0c9..32ca6d02d 100644
--- a/src/mem/coherent_xbar.cc
+++ b/src/mem/coherent_xbar.cc
@@ -187,6 +187,8 @@ CoherentXBar::recvTimingReq(PacketPtr pkt, PortID slave_port_id)
Tick packetFinishTime = clockEdge(Cycles(1)) + pkt->payloadDelay;
if (!system->bypassCaches()) {
+ assert(pkt->snoopDelay == 0);
+
// the packet is a memory-mapped request and should be
// broadcasted to our snoopers but the source
if (snoopFilter) {
@@ -204,6 +206,10 @@ CoherentXBar::recvTimingReq(PacketPtr pkt, PortID slave_port_id)
} else {
forwardTiming(pkt, slave_port_id);
}
+
+ // add the snoop delay to our header delay, and then reset it
+ pkt->headerDelay += pkt->snoopDelay;
+ pkt->snoopDelay = 0;
}
// forwardTiming snooped into peer caches of the sender, and if
@@ -377,9 +383,15 @@ CoherentXBar::recvTimingSnoopReq(PacketPtr pkt, PortID master_port_id)
// we should only see express snoops from caches
assert(pkt->isExpressSnoop());
+ // set the packet header and payload delay, for now use forward latency
+ // @todo Assess the choice of latency further
+ calcPacketTiming(pkt, forwardLatency * clockPeriod());
+
// remeber if the packet is inhibited so we can see if it changes
const bool is_inhibited = pkt->memInhibitAsserted();
+ assert(pkt->snoopDelay == 0);
+
if (snoopFilter) {
// let the Snoop Filter work its magic and guide probing
auto sf_res = snoopFilter->lookupSnoop(pkt);
@@ -398,6 +410,10 @@ CoherentXBar::recvTimingSnoopReq(PacketPtr pkt, PortID master_port_id)
forwardTiming(pkt, InvalidPortID);
}
+ // add the snoop delay to our header delay, and then reset it
+ pkt->headerDelay += pkt->snoopDelay;
+ pkt->snoopDelay = 0;
+
// if we can expect a response, remember how to route it
if (!is_inhibited && pkt->memInhibitAsserted()) {
assert(routeTo.find(pkt->req) == routeTo.end());