59c59,62
< headerCycles(p->header_cycles), width(p->width),
---
> frontendLatency(p->frontend_latency),
> forwardLatency(p->forward_latency),
> responseLatency(p->response_latency),
> width(p->width),
105c108
< BaseXBar::calcPacketTiming(PacketPtr pkt)
---
> BaseXBar::calcPacketTiming(PacketPtr pkt, Tick header_delay)
112,115c115,118
< // 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;
---
> // 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;
117,122c120,121
< // 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);
---
> // note that we add the header delay to the existing value, and
> // align it to the crossbar clock
124,127c123,127
< // 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;
---
> // 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");
129,132c129,142
< // 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;
---
> 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
277c287,288
< // 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)
283,284c294,295
< // 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());