xbar.cc (10713:eddb533708cb) xbar.cc (10719:b4fc9ad648aa)
1/*
2 * Copyright (c) 2011-2015 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software

--- 42 unchanged lines hidden (view full) ---

51#include "base/trace.hh"
52#include "debug/AddrRanges.hh"
53#include "debug/Drain.hh"
54#include "debug/XBar.hh"
55#include "mem/xbar.hh"
56
57BaseXBar::BaseXBar(const BaseXBarParams *p)
58 : MemObject(p),
1/*
2 * Copyright (c) 2011-2015 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software

--- 42 unchanged lines hidden (view full) ---

51#include "base/trace.hh"
52#include "debug/AddrRanges.hh"
53#include "debug/Drain.hh"
54#include "debug/XBar.hh"
55#include "mem/xbar.hh"
56
57BaseXBar::BaseXBar(const BaseXBarParams *p)
58 : MemObject(p),
59 headerCycles(p->header_cycles), width(p->width),
59 frontendLatency(p->frontend_latency),
60 forwardLatency(p->forward_latency),
61 responseLatency(p->response_latency),
62 width(p->width),
60 gotAddrRanges(p->port_default_connection_count +
61 p->port_master_connection_count, false),
62 gotAllAddrRanges(false), defaultPortID(InvalidPortID),
63 useDefaultRange(p->use_default_range)
64{}
65
66BaseXBar::~BaseXBar()
67{

--- 29 unchanged lines hidden (view full) ---

97 // the slave port index translates directly to the vector position
98 return *slavePorts[idx];
99 } else {
100 return MemObject::getSlavePort(if_name, idx);
101 }
102}
103
104void
63 gotAddrRanges(p->port_default_connection_count +
64 p->port_master_connection_count, false),
65 gotAllAddrRanges(false), defaultPortID(InvalidPortID),
66 useDefaultRange(p->use_default_range)
67{}
68
69BaseXBar::~BaseXBar()
70{

--- 29 unchanged lines hidden (view full) ---

100 // the slave port index translates directly to the vector position
101 return *slavePorts[idx];
102 } else {
103 return MemObject::getSlavePort(if_name, idx);
104 }
105}
106
107void
105BaseXBar::calcPacketTiming(PacketPtr pkt)
108BaseXBar::calcPacketTiming(PacketPtr pkt, Tick header_delay)
106{
107 // the crossbar will be called at a time that is not necessarily
108 // coinciding with its own clock, so start by determining how long
109 // until the next clock edge (could be zero)
110 Tick offset = clockEdge() - curTick();
111
109{
110 // the crossbar will be called at a time that is not necessarily
111 // coinciding with its own clock, so start by determining how long
112 // until the next clock edge (could be zero)
113 Tick offset = clockEdge() - curTick();
114
112 // Determine how many cycles are needed to send the data
113 // If the packet has no data we take into account just the cycle to send
114 // the header.
115 unsigned dataCycles = pkt->hasData() ? divCeil(pkt->getSize(), width) : 0;
115 // the header delay depends on the path through the crossbar, and
116 // we therefore rely on the caller to provide the actual
117 // value
118 pkt->headerDelay += offset + header_delay;
116
119
117 // before setting the bus delay fields of the packet, ensure that
118 // the delay from any previous crossbar has been accounted for
119 if (pkt->headerDelay != 0 || pkt->payloadDelay != 0)
120 panic("Packet %s already has delay (%d, %d) that should be "
121 "accounted for.\n", pkt->cmdString(), pkt->headerDelay,
122 pkt->payloadDelay);
120 // note that we add the header delay to the existing value, and
121 // align it to the crossbar clock
123
122
124 // The headerDelay takes into account the relative time to deliver the
125 // header of the packet. It will be charged of the additional delay of
126 // the xbar if the packet goes through it.
127 pkt->headerDelay = (headerCycles + 1) * clockPeriod() + offset;
123 // do a quick sanity check to ensure the timings are not being
124 // ignored, note that this specific value may cause problems for
125 // slower interconnects
126 panic_if(pkt->headerDelay > SimClock::Int::us,
127 "Encountered header delay exceeding 1 us\n");
128
128
129 // The payloadDelay takes into account the relative time to deliver the
130 // payload of the packet. If the packet has no data its value is just one
131 // tick (due to header) plus the offset value.
132 pkt->payloadDelay = (headerCycles + dataCycles) * clockPeriod() + offset;
129 if (pkt->hasData()) {
130 // the payloadDelay takes into account the relative time to
131 // deliver the payload of the packet, after the header delay,
132 // we take the maximum since the payload delay could already
133 // be longer than what this parcitular crossbar enforces.
134 pkt->payloadDelay = std::max<Tick>(pkt->payloadDelay,
135 divCeil(pkt->getSize(), width) *
136 clockPeriod());
137 }
138
139 // the payload delay is not paying for the clock offset as that is
140 // already done using the header delay, and the payload delay is
141 // also used to determine how long the crossbar layer is busy and
142 // thus regulates throughput
133}
134
135template <typename SrcType, typename DstType>
136BaseXBar::Layer<SrcType,DstType>::Layer(DstType& _port, BaseXBar& _xbar,
137 const std::string& _name) :
138 port(_port), xbar(_xbar), _name(_name), state(IDLE), drainManager(NULL),
139 waitingForPeer(NULL), releaseEvent(this)
140{

--- 128 unchanged lines hidden (view full) ---

269 SrcType* retryingPort = waitingForLayer.front();
270 waitingForLayer.pop_front();
271
272 // tell the port to retry, which in some cases ends up calling the
273 // layer again
274 sendRetry(retryingPort);
275
276 // If the layer is still in the retry state, sendTiming wasn't
143}
144
145template <typename SrcType, typename DstType>
146BaseXBar::Layer<SrcType,DstType>::Layer(DstType& _port, BaseXBar& _xbar,
147 const std::string& _name) :
148 port(_port), xbar(_xbar), _name(_name), state(IDLE), drainManager(NULL),
149 waitingForPeer(NULL), releaseEvent(this)
150{

--- 128 unchanged lines hidden (view full) ---

279 SrcType* retryingPort = waitingForLayer.front();
280 waitingForLayer.pop_front();
281
282 // tell the port to retry, which in some cases ends up calling the
283 // layer again
284 sendRetry(retryingPort);
285
286 // If the layer is still in the retry state, sendTiming wasn't
277 // called in zero time (e.g. the cache does this), burn a cycle
287 // called in zero time (e.g. the cache does this when a writeback
288 // is squashed)
278 if (state == RETRY) {
279 // update the state to busy and reset the retrying port, we
280 // have done our bit and sent the retry
281 state = BUSY;
282
289 if (state == RETRY) {
290 // update the state to busy and reset the retrying port, we
291 // have done our bit and sent the retry
292 state = BUSY;
293
283 // occupy the crossbar layer until the next cycle ends
284 occupyLayer(xbar.clockEdge(Cycles(1)));
294 // occupy the crossbar layer until the next clock edge
295 occupyLayer(xbar.clockEdge());
285 }
286}
287
288template <typename SrcType, typename DstType>
289void
290BaseXBar::Layer<SrcType,DstType>::recvRetry()
291{
292 // we should never get a retry without having failed to forward

--- 327 unchanged lines hidden ---
296 }
297}
298
299template <typename SrcType, typename DstType>
300void
301BaseXBar::Layer<SrcType,DstType>::recvRetry()
302{
303 // we should never get a retry without having failed to forward

--- 327 unchanged lines hidden ---