Go to the documentation of this file.
50 #include "debug/AddrRanges.hh"
51 #include "debug/Drain.hh"
52 #include "debug/XBar.hh"
56 frontendLatency(
p->frontend_latency),
57 forwardLatency(
p->forward_latency),
58 responseLatency(
p->response_latency),
59 headerLatency(
p->header_latency),
61 gotAddrRanges(
p->port_default_connection_count +
62 p->port_mem_side_ports_connection_count, false),
64 useDefaultRange(
p->use_default_range),
66 transDist(this,
"trans_dist",
"Transaction distribution"),
67 pktCount(this,
"pkt_count",
68 "Packet count per connected requestor and responder (bytes)"),
69 pktSize(this,
"pkt_size",
"Cumulative packet size per connected "
70 "requestor and responder (bytes)")
86 if (if_name ==
"mem_side_ports" && idx <
memSidePorts.size()) {
90 }
else if (if_name ==
"default") {
92 }
else if (if_name ==
"cpu_side_ports" && idx <
cpuSidePorts.size()) {
120 "Encountered header delay exceeding 1 us\n");
138 template <
typename SrcType,
typename DstType>
140 const std::string& _name) :
141 Stats::Group(&_xbar, _name.c_str()),
142 port(_port), xbar(_xbar), _name(xbar.
name() +
"." + _name), state(IDLE),
143 waitingForPeer(NULL), releaseEvent([this]{ releaseLayer(); },
name()),
144 ADD_STAT(occupancy,
"Layer occupancy (ticks)"),
145 ADD_STAT(utilization,
"Layer utilization (%)")
154 utilization = 100 * occupancy /
simTicks;
157 template <
typename SrcType,
typename DstType>
164 assert(state == BUSY);
168 xbar.schedule(releaseEvent, until);
171 occupancy += until -
curTick();
173 DPRINTF(
BaseXBar,
"The crossbar layer is now busy from tick %d to %d\n",
177 template <
typename SrcType,
typename DstType>
190 if (state == BUSY || waitingForPeer != NULL) {
192 assert(std::find(waitingForLayer.begin(), waitingForLayer.end(),
193 src_port) == waitingForLayer.end());
199 waitingForLayer.push_back(src_port);
208 template <
typename SrcType,
typename DstType>
214 assert(state == BUSY);
217 occupyLayer(busy_time);
220 template <
typename SrcType,
typename DstType>
227 assert(waitingForPeer == NULL);
232 waitingForPeer = src_port;
236 assert(state == BUSY);
239 occupyLayer(busy_time);
242 template <
typename SrcType,
typename DstType>
247 assert(state == BUSY);
248 assert(!releaseEvent.scheduled());
254 if (!waitingForLayer.empty()) {
257 if (waitingForPeer == NULL)
260 DPRINTF(Drain,
"Crossbar done draining, signaling drain manager\n");
266 template <
typename SrcType,
typename DstType>
271 assert(!waitingForLayer.empty());
274 assert(state == IDLE);
281 SrcType* retryingPort = waitingForLayer.front();
282 waitingForLayer.pop_front();
286 sendRetry(retryingPort);
291 if (state == RETRY) {
297 occupyLayer(xbar.clockEdge());
301 template <
typename SrcType,
typename DstType>
307 assert(waitingForPeer != NULL);
312 waitingForLayer.push_front(waitingForPeer);
315 waitingForPeer = NULL;
322 assert(state == BUSY);
342 DPRINTF(AddrRanges,
" found addr %s on default\n",
347 DPRINTF(AddrRanges,
"Unable to find destination for %s, "
348 "will use default port\n", addr_range.
to_string());
354 fatal(
"Unable to find destination for %s on %s\n", addr_range.
to_string(),
362 DPRINTF(AddrRanges,
"Received range change from cpu_side_ports %s\n",
379 DPRINTF(AddrRanges,
"Got address ranges from all responders\n");
394 if (ranges.size() != 1)
395 fatal(
"Crossbar %s may only have a single default range",
405 if (
p->second == mem_side_port_id)
417 for (
const auto&
r: ranges) {
418 DPRINTF(AddrRanges,
"Adding range %s for id %d\n",
419 r.to_string(), mem_side_port_id);
422 fatal(
"%s has two ports responding within range "
436 DPRINTF(AddrRanges,
"Aggregating address ranges\n");
442 fatal(
"Crossbar %s uses default range, but none provided",
446 DPRINTF(AddrRanges,
"-- Adding default %s\n",
455 if (
r.first.interleaved()) {
459 if (!intlv_ranges.empty() &&
460 !intlv_ranges.back().mergesWith(
r.first)) {
461 DPRINTF(AddrRanges,
"-- Merging range from %d ranges\n",
462 intlv_ranges.size());
468 DPRINTF(AddrRanges,
"-- Adding merged range %s\n",
471 intlv_ranges.clear();
473 intlv_ranges.push_back(
r.first);
479 DPRINTF(AddrRanges,
"-- Adding range %s\n",
480 r.first.to_string());
487 if (!intlv_ranges.empty()) {
488 DPRINTF(AddrRanges,
"-- Merging range from %d ranges\n",
489 intlv_ranges.size());
493 DPRINTF(AddrRanges,
"-- Adding merged range %s\n",
508 fatal(
"Range %s intersects the " \
509 "default range of %s but is not a " \
510 "subset\n",
r.to_string(),
name());
517 port->sendRangeChange();
534 DPRINTF(AddrRanges,
"Received address range request\n");
544 using namespace Stats;
553 const std::string &cstr = cmd.
toString();
582 template <
typename SrcType,
typename DstType>
590 DPRINTF(Drain,
"Crossbar not drained\n");
void retryWaiting()
Send a retry to the port at the head of waitingForLayer.
#define fatal(...)
This implements a cprintf based fatal() function.
virtual void regStats()
Callback to set stat parameters.
std::vector< QueuedResponsePort * > cpuSidePorts
The memory-side ports and CPU-side ports of the crossbar.
std::vector< bool > gotAddrRanges
Remember for each of the memory-side ports of the crossbar if we got an address range from the connec...
Stats::Vector transDist
Stats for transaction distribution and data passing through the crossbar.
iterator insert(const AddrRange &r, const V &d)
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
const PortID InvalidPortID
const_iterator end() const
Derived & ysubname(off_type index, const std::string &subname)
uint64_t Tick
Tick count type.
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
A function used to return the port associated with this object.
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
PortID findPort(AddrRange addr_range)
Find which port connected to this crossbar (if any) should be given a packet with this address range.
AddrRangeList getAddrRanges() const
Return the address ranges the crossbar is responsible for.
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
BaseXBar(const BaseXBarParams *p)
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
PortID defaultPortID
Port that handles requests that don't match any of the interfaces.
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
@ Drained
Buffers drained, ready for serialization/handover.
const_iterator begin() const
DrainState
Object drain/handover states.
T divCeil(const T &a, const U &b)
void succeededTiming(Tick busy_time)
Deal with a destination port accepting a packet by potentially removing the source port from the retr...
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
const std::string & toString() const
Return the string to a cmd given by idx.
void failedTiming(SrcType *src_port, Tick busy_time)
Deal with a destination port not accepting a packet by potentially adding the source port to the retr...
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Ports are used to interface objects to each other.
const bool useDefaultRange
If true, use address range provided by default device.
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
void occupyLayer(Tick until)
const std::string & name()
Derived & init(size_type size)
Set this vector to have the given size.
Layer(DstType &_port, BaseXBar &_xbar, const std::string &_name)
Create a layer and give it a name.
const FlagsType nozero
Don't print if this is zero.
virtual const std::string name() const
AddrRangeMap< PortID, 3 > portMap
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
virtual void recvRangeChange(PortID mem_side_port_id)
Function called by the port when the crossbar is recieving a range change.
DrainState drain() override
Drain according to the normal semantics, so that the crossbar can tell the layer to drain,...
std::string to_string() const
Get a string representation of the range.
const_iterator contains(const AddrRange &r) const
Find entry that contains the given address range.
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
const_iterator intersects(const AddrRange &r) const
Find entry that intersects with the given address range.
bool tryTiming(SrcType *src_port)
Determine if the layer accepts a packet from a specific port.
Derived & init(size_type _x, size_type _y)
Derived & subname(off_type index, const std::string &name)
Set the subfield name for the given index, and marks this stat to print at the end of simulation.
bool isSubset(const AddrRange &r) const
Determine if this range is a subset of another range, i.e.
void releaseLayer()
Release the layer after being occupied and return to an idle state where we proceed to send a retry t...
AddrRangeList xbarRanges
all contigous ranges seen by this crossbar
void regStats() override
Callback to set stat parameters.
The base crossbar contains the common elements of the non-coherent and coherent crossbar.
void recvRetry()
Handle a retry from a neighbouring module.
const FlagsType total
Print the total.
void calcPacketTiming(PacketPtr pkt, Tick header_delay)
Calculate the timing parameters for the packet.
std::vector< RequestPort * > memSidePorts
const FlagsType nonan
Don't print if this is NAN.
@ Draining
Draining buffers pending serialization/handover.
const uint32_t width
the width of the xbar in bytes
Tick curTick()
The current simulated tick.
Generated on Wed Sep 30 2020 14:02:14 for gem5 by doxygen 1.8.17