summaryrefslogtreecommitdiff
path: root/src/mem/xbar.cc
diff options
context:
space:
mode:
authorMarco Balboni <Marco.Balboni@ARM.com>2015-03-02 04:00:46 -0500
committerMarco Balboni <Marco.Balboni@ARM.com>2015-03-02 04:00:46 -0500
commitd35dd71ab4ac44a79ac22dca82277a43cd59f3c6 (patch)
treeeb42b8079289e3cef8f265556944941dc012e66c /src/mem/xbar.cc
parent7be9d4eb673b9d9b45eabfd40a56718569a2a1be (diff)
downloadgem5-d35dd71ab4ac44a79ac22dca82277a43cd59f3c6.tar.xz
mem: Add crossbar latencies
This patch introduces latencies in crossbar that were neglected before. In particular, it adds three parameters in crossbar model: front_end_latency, forward_latency, and response_latency. Along with these parameters, three corresponding members are added: frontEndLatency, forwardLatency, and responseLatency. The coherent crossbar has an additional snoop_response_latency. The latency of the request path through the xbar is set as --> frontEndLatency + forwardLatency In case the snoop filter is enabled, the request path latency is charged also by look-up latency of the snoop filter. --> frontEndLatency + SF(lookupLatency) + forwardLatency. The latency of the response path through the xbar is set instead as --> responseLatency. In case of snoop response, if the response is treated as a normal response the latency associated is again --> responseLatency; If instead it is forwarded as snoop response we add an additional variable + snoopResponseLatency and the latency associated is --> snoopResponseLatency; Furthermore, this patch lets the crossbar progress on the next clock edge after an unused retry, changing the time the crossbar considers itself busy after sending a retry that was not acted upon.
Diffstat (limited to 'src/mem/xbar.cc')
-rw-r--r--src/mem/xbar.cc63
1 files changed, 37 insertions, 26 deletions
diff --git a/src/mem/xbar.cc b/src/mem/xbar.cc
index 7ac937177..bc649581b 100644
--- a/src/mem/xbar.cc
+++ b/src/mem/xbar.cc
@@ -56,7 +56,10 @@
BaseXBar::BaseXBar(const BaseXBarParams *p)
: MemObject(p),
- headerCycles(p->header_cycles), width(p->width),
+ frontendLatency(p->frontend_latency),
+ forwardLatency(p->forward_latency),
+ responseLatency(p->response_latency),
+ width(p->width),
gotAddrRanges(p->port_default_connection_count +
p->port_master_connection_count, false),
gotAllAddrRanges(false), defaultPortID(InvalidPortID),
@@ -102,34 +105,41 @@ BaseXBar::getSlavePort(const std::string &if_name, PortID idx)
}
void
-BaseXBar::calcPacketTiming(PacketPtr pkt)
+BaseXBar::calcPacketTiming(PacketPtr pkt, Tick header_delay)
{
// the crossbar will be called at a time that is not necessarily
// coinciding with its own clock, so start by determining how long
// until the next clock edge (could be zero)
Tick offset = clockEdge() - curTick();
- // Determine how many cycles are needed to send the data
- // If the packet has no data we take into account just the cycle to send
- // the header.
- unsigned dataCycles = pkt->hasData() ? divCeil(pkt->getSize(), width) : 0;
-
- // before setting the bus delay fields of the packet, ensure that
- // the delay from any previous crossbar has been accounted for
- if (pkt->headerDelay != 0 || pkt->payloadDelay != 0)
- panic("Packet %s already has delay (%d, %d) that should be "
- "accounted for.\n", pkt->cmdString(), pkt->headerDelay,
- pkt->payloadDelay);
-
- // The headerDelay takes into account the relative time to deliver the
- // header of the packet. It will be charged of the additional delay of
- // the xbar if the packet goes through it.
- pkt->headerDelay = (headerCycles + 1) * clockPeriod() + offset;
-
- // The payloadDelay takes into account the relative time to deliver the
- // payload of the packet. If the packet has no data its value is just one
- // tick (due to header) plus the offset value.
- pkt->payloadDelay = (headerCycles + dataCycles) * clockPeriod() + offset;
+ // the header delay depends on the path through the crossbar, and
+ // we therefore rely on the caller to provide the actual
+ // value
+ pkt->headerDelay += offset + header_delay;
+
+ // note that we add the header delay to the existing value, and
+ // align it to the crossbar clock
+
+ // do a quick sanity check to ensure the timings are not being
+ // ignored, note that this specific value may cause problems for
+ // slower interconnects
+ panic_if(pkt->headerDelay > SimClock::Int::us,
+ "Encountered header delay exceeding 1 us\n");
+
+ if (pkt->hasData()) {
+ // the payloadDelay takes into account the relative time to
+ // deliver the payload of the packet, after the header delay,
+ // we take the maximum since the payload delay could already
+ // be longer than what this parcitular crossbar enforces.
+ pkt->payloadDelay = std::max<Tick>(pkt->payloadDelay,
+ divCeil(pkt->getSize(), width) *
+ clockPeriod());
+ }
+
+ // the payload delay is not paying for the clock offset as that is
+ // already done using the header delay, and the payload delay is
+ // also used to determine how long the crossbar layer is busy and
+ // thus regulates throughput
}
template <typename SrcType, typename DstType>
@@ -274,14 +284,15 @@ BaseXBar::Layer<SrcType,DstType>::retryWaiting()
sendRetry(retryingPort);
// If the layer is still in the retry state, sendTiming wasn't
- // called in zero time (e.g. the cache does this), burn a cycle
+ // called in zero time (e.g. the cache does this when a writeback
+ // is squashed)
if (state == RETRY) {
// update the state to busy and reset the retrying port, we
// have done our bit and sent the retry
state = BUSY;
- // occupy the crossbar layer until the next cycle ends
- occupyLayer(xbar.clockEdge(Cycles(1)));
+ // occupy the crossbar layer until the next clock edge
+ occupyLayer(xbar.clockEdge());
}
}