53#include "debug/AddrRanges.hh"
54#include "debug/Drain.hh"
55#include "debug/XBar.hh"
68 p.port_mem_side_ports_connection_count, false),
73 "Transaction distribution"),
75 "Packet count per connected requestor and responder"),
77 "Cumulative packet size per connected requestor and responder")
93 if (if_name ==
"mem_side_ports" && idx <
memSidePorts.size()) {
97 }
else if (if_name ==
"default") {
99 }
else if (if_name ==
"cpu_side_ports" && idx <
cpuSidePorts.size()) {
127 "Encountered header delay exceeding 1 us\n");
145template <
typename SrcType,
typename DstType>
147 const std::string&
_name) :
151 ADD_STAT(occupancy, statistics::units::Tick::get(),
"Layer occupancy (ticks)"),
164template <
typename SrcType,
typename DstType>
180 DPRINTF(
BaseXBar,
"The crossbar layer is now busy from tick %d to %d\n",
184template <
typename SrcType,
typename DstType>
215template <
typename SrcType,
typename DstType>
227template <
typename SrcType,
typename DstType>
249template <
typename SrcType,
typename DstType>
267 DPRINTF(Drain,
"Crossbar done draining, signaling drain manager\n");
273template <
typename SrcType,
typename DstType>
308template <
typename SrcType,
typename DstType>
341 auto i =
portMap.contains(addr_range);
349 DPRINTF(AddrRanges,
" found addr %s on default\n",
354 DPRINTF(AddrRanges,
"Unable to find destination for %s, "
355 "will use default port\n", addr_range.
to_string());
361 std::string port_trace =
"";
363 std::shared_ptr<TracingExtension>
ext =
365 port_trace =
ext ?
ext->getTraceInString() :
366 "Use --debug-flags=PortTrace to see the port trace of the packet.";
368 fatal(
"Unable to find destination for %s on %s\n%s\n",
376 DPRINTF(AddrRanges,
"Received range change from cpu_side_ports %s\n",
393 DPRINTF(AddrRanges,
"Got address ranges from all responders\n");
408 if (ranges.size() != 1)
409 fatal(
"Crossbar %s may only have a single default range",
419 if (
p->second == mem_side_port_id)
431 for (
const auto&
r: ranges) {
432 DPRINTF(AddrRanges,
"Adding range %s for id %d\n",
433 r.to_string(), mem_side_port_id);
436 fatal(
"%s has two ports responding within range "
450 DPRINTF(AddrRanges,
"Aggregating address ranges\n");
456 fatal(
"Crossbar %s uses default range, but none provided",
460 DPRINTF(AddrRanges,
"-- Adding default %s\n",
469 if (
r.first.interleaved()) {
473 if (!intlv_ranges.empty() &&
474 !intlv_ranges.back().mergesWith(
r.first)) {
475 DPRINTF(AddrRanges,
"-- Merging range from %d ranges\n",
476 intlv_ranges.size());
482 DPRINTF(AddrRanges,
"-- Adding merged range %s\n",
485 intlv_ranges.clear();
487 intlv_ranges.push_back(
r.first);
493 DPRINTF(AddrRanges,
"-- Adding range %s\n",
494 r.first.to_string());
501 if (!intlv_ranges.empty()) {
502 DPRINTF(AddrRanges,
"-- Merging range from %d ranges\n",
503 intlv_ranges.size());
507 DPRINTF(AddrRanges,
"-- Adding merged range %s\n",
522 fatal(
"Range %s intersects the " \
523 "default range of %s but is not a " \
524 "subset\n",
r.to_string(),
name());
531 port->sendRangeChange();
548 DPRINTF(AddrRanges,
"Received address range request\n");
567 const std::string &cstr = cmd.
toString();
596template <
typename SrcType,
typename DstType>
604 DPRINTF(Drain,
"Crossbar not drained\n");
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
A layer is an internal crossbar arbitration point with its own flow control.
statistics::Formula utilization
statistics::Scalar occupancy
void recvRetry()
Handle a retry from a neighbouring module.
DrainState drain() override
Drain according to the normal semantics, so that the crossbar can tell the layer to drain,...
std::deque< SrcType * > waitingForLayer
A deque of ports that retry should be called on because the original send was delayed due to a busy l...
bool tryTiming(SrcType *src_port)
Determine if the layer accepts a packet from a specific port.
const std::string name() const
EventFunctionWrapper releaseEvent
Layer(DstType &_port, BaseXBar &_xbar, const std::string &_name)
Create a layer and give it a name.
ResponsePort * waitingForPeer
void occupyLayer(Tick until)
void retryWaiting()
Send a retry to the port at the head of waitingForLayer.
DstType & port
The destination port this layer converges at.
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...
void succeededTiming(Tick busy_time)
Deal with a destination port accepting a packet by potentially removing the source port from the retr...
virtual void sendRetry(SrcType *retry_port)=0
Sending the actual retry, in a manner specific to the individual layers.
BaseXBar & xbar
The crossbar this layer is a part of.
PortID defaultPortID
Port that handles requests that don't match any of the interfaces.
std::vector< RequestPort * > memSidePorts
const Cycles headerLatency
Cycles the layer is occupied processing the packet header.
const Cycles frontendLatency
Cycles of front-end pipeline including the delay to accept the request and to decode the address.
PortID findPort(AddrRange addr_range, PacketPtr pkt=nullptr)
Find which port connected to this crossbar (if any) should be given a packet with this address range.
statistics::Vector transDist
Stats for transaction distribution and data passing through the crossbar.
const bool useDefaultRange
If true, use address range provided by default device.
statistics::Vector2d pktCount
BaseXBar(const BaseXBarParams &p)
std::vector< QueuedResponsePort * > cpuSidePorts
The memory-side ports and CPU-side ports of the crossbar.
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
A function used to return the port associated with this object.
void regStats() override
Callback to set stat parameters.
const Cycles forwardLatency
AddrRangeList xbarRanges
all contigous ranges seen by this crossbar
AddrRangeMap< PortID, 3 > portMap
const uint32_t width
the width of the xbar in bytes
statistics::Vector2d pktSize
std::vector< bool > gotAddrRanges
Remember for each of the memory-side ports of the crossbar if we got an address range from the connec...
virtual void recvRangeChange(PortID mem_side_port_id)
Function called by the port when the crossbar is recieving a range change.
void calcPacketTiming(PacketPtr pkt, Tick header_delay)
Calculate the timing parameters for the packet.
const Cycles responseLatency
AddrRangeList getAddrRanges() const
Return the address ranges the crossbar is responsible for.
ClockedObject(const ClockedObjectParams &p)
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...
std::shared_ptr< T > getExtension()
Get the extension pointer by linear search with the extensionID.
const std::string & toString() const
Return the string to a cmd given by idx.
virtual std::string name() const
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
Ports are used to interface objects to each other.
TracingExtension is an Extension of the Packet for recording the trace of the Packet.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
bool isSubset(const AddrRange &r) const
Determine if this range is a subset of another range, i.e.
std::list< AddrRange > AddrRangeList
Convenience typedef for a collection of address ranges.
std::string to_string() const
Get a string representation of the range.
static constexpr T divCeil(const T &a, const U &b)
void signalDrainDone() const
Signal that an object is drained.
DrainState drainState() const
Return the current drain state of an object.
DrainState
Object drain/handover states.
@ Draining
Draining buffers pending serialization/handover.
@ Drained
Buffers drained, ready for serialization/handover.
#define fatal(...)
This implements a cprintf based fatal() function.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
virtual void regStats()
Callback to set stat parameters.
const FlagsType nonan
Don't print if this is NAN.
const FlagsType nozero
Don't print if this is zero.
const FlagsType total
Print the total.
Copyright (c) 2024 Arm Limited All rights reserved.
const PortID InvalidPortID
Tick curTick()
The universal simulation clock.
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
uint64_t Tick
Tick count type.
statistics::Value & simTicks
const std::string & name()
Declaration of an abstract crossbar base class.