53#include "debug/AddrRanges.hh"
54#include "debug/Drain.hh"
55#include "debug/XBar.hh"
62 frontendLatency(
p.frontend_latency),
63 forwardLatency(
p.forward_latency),
64 responseLatency(
p.response_latency),
65 headerLatency(
p.header_latency),
67 gotAddrRanges(
p.port_default_connection_count +
68 p.port_mem_side_ports_connection_count, false),
70 useDefaultRange(
p.use_default_range),
72 ADD_STAT(transDist, statistics::units::Count::get(),
73 "Transaction distribution"),
74 ADD_STAT(pktCount, statistics::units::Count::get(),
75 "Packet count per connected requestor and responder"),
76 ADD_STAT(pktSize, statistics::units::Byte::get(),
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) :
148 statistics::
Group(&_xbar, _name.c_str()),
149 port(_port), xbar(_xbar), _name(xbar.
name() +
"." + _name),
state(IDLE),
150 waitingForPeer(NULL), releaseEvent([this]{ releaseLayer(); },
name()),
151 ADD_STAT(occupancy, statistics::units::Tick::get(),
"Layer occupancy (ticks)"),
164template <
typename SrcType,
typename DstType>
175 xbar.schedule(releaseEvent, until);
178 occupancy += until -
curTick();
180 DPRINTF(
BaseXBar,
"The crossbar layer is now busy from tick %d to %d\n",
184template <
typename SrcType,
typename DstType>
197 if (
state ==
BUSY || waitingForPeer != NULL) {
199 assert(std::find(waitingForLayer.begin(), waitingForLayer.end(),
200 src_port) == waitingForLayer.end());
206 waitingForLayer.push_back(src_port);
215template <
typename SrcType,
typename DstType>
224 occupyLayer(busy_time);
227template <
typename SrcType,
typename DstType>
234 assert(waitingForPeer == NULL);
239 waitingForPeer = src_port;
246 occupyLayer(busy_time);
249template <
typename SrcType,
typename DstType>
255 assert(!releaseEvent.scheduled());
261 if (!waitingForLayer.empty()) {
264 if (waitingForPeer == NULL)
267 DPRINTF(Drain,
"Crossbar done draining, signaling drain manager\n");
273template <
typename SrcType,
typename DstType>
278 assert(!waitingForLayer.empty());
281 assert(
state == IDLE);
288 SrcType* retryingPort = waitingForLayer.front();
289 waitingForLayer.pop_front();
293 sendRetry(retryingPort);
298 if (
state == RETRY) {
304 occupyLayer(xbar.clockEdge());
308template <
typename SrcType,
typename DstType>
314 assert(waitingForPeer != NULL);
319 waitingForLayer.push_front(waitingForPeer);
322 waitingForPeer = NULL;
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 =
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");
558 using namespace statistics;
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.
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,...
bool tryTiming(SrcType *src_port)
Determine if the layer accepts a packet from a specific port.
Layer(DstType &_port, BaseXBar &_xbar, const std::string &_name)
Create a layer and give it a name.
void occupyLayer(Tick until)
void retryWaiting()
Send a retry to the port at the head of waitingForLayer.
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 releaseLayer()
Release the layer after being occupied and return to an idle state where we proceed to send a retry t...
void succeededTiming(Tick busy_time)
Deal with a destination port accepting a packet by potentially removing the source port from the retr...
The base crossbar contains the common elements of the non-coherent and coherent crossbar.
PortID defaultPortID
Port that handles requests that don't match any of the interfaces.
std::vector< RequestPort * > memSidePorts
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.
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.
AddrRangeList getAddrRanges() const
Return the address ranges the crossbar is responsible for.
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
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
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
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.
std::string getTraceInString()
Derived & ysubname(off_type index, const std::string &subname)
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.
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
Derived & init(size_type _x, size_type _y)
Derived & init(size_type size)
Set this vector to have the given size.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
const_iterator begin() const
bool isSubset(const AddrRange &r) const
Determine if this range is a subset of another range, i.e.
const_iterator intersects(const AddrRange &r) const
Find entry that intersects with the given address range.
iterator insert(const AddrRange &r, const V &d)
const_iterator contains(const AddrRange &r) const
Find entry that contains the given address range.
const_iterator end() const
std::string to_string() const
Get a string representation of the range.
static constexpr T divCeil(const T &a, const U &b)
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 - Pranith Kumar Copyright (c) 2020 Inria 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.