Go to the documentation of this file.
50 #include "debug/AddrRanges.hh"
51 #include "debug/CoherentXBar.hh"
56 snoopResponseLatency(
p->snoop_response_latency),
57 maxOutstandingSnoopCheck(
p->max_outstanding_snoops),
58 maxRoutingTableSizeCheck(
p->max_routing_table_size),
59 pointOfCoherency(
p->point_of_coherency),
60 pointOfUnification(
p->point_of_unification),
62 snoops(this,
"snoops",
"Total snoops (count)"),
63 snoopTraffic(this,
"snoopTraffic",
"Total snoop traffic (bytes)"),
64 snoopFanout(this,
"snoop_fanout",
"Request fanout histogram")
69 for (
int i = 0;
i <
p->port_mem_side_ports_connection_count; ++
i) {
70 std::string portName =
csprintf(
"%s.mem_side_port[%d]",
name(),
i);
81 if (
p->port_default_connection_count) {
83 std::string portName =
name() +
".default";
95 for (
int i = 0;
i <
p->port_cpu_side_ports_connection_count; ++
i) {
96 std::string portName =
csprintf(
"%s.cpu_side_port[%d]",
name(),
i);
127 if (
p->isSnooping()) {
128 DPRINTF(AddrRanges,
"Adding snooping requestor %s\n",
135 warn(
"CoherentXBar %s has no snooping ports attached!\n",
name());
154 assert(is_express_snoop == cache_responding);
161 if (!is_express_snoop &&
162 !
reqLayers[mem_side_port_id]->tryTiming(src_port)) {
199 if (pkt->
isClean() && !is_destination) {
208 reqLayers[mem_side_port_id]->failedTiming(src_port,
225 __func__, src_port->
name(), pkt->
print(),
226 sf_res.first.size(), sf_res.second);
234 if (!sf_res.first.empty())
254 const bool expect_snoop_resp = !cache_responding && pkt->
cacheResponding();
260 bool respond_directly =
false;
283 if (pkt->
isWrite() && is_destination) {
288 success =
memSidePorts[mem_side_port_id]->sendTimingReq(pkt);
294 respond_directly =
true;
295 assert(!expect_snoop_resp);
296 expect_response =
false;
308 assert(!is_express_snoop);
317 reqLayers[mem_side_port_id]->failedTiming(src_port,
321 if (!is_express_snoop) {
324 if (expect_snoop_resp) {
332 "%s: Outstanding snoop requests exceeded %d\n",
337 if (expect_response || expect_snoop_resp) {
342 "%s: Routing table exceeds %d packets\n",
347 reqLayers[mem_side_port_id]->succeededTiming(packetFinishTime);
351 pktCount[cpu_side_port_id][mem_side_port_id]++;
352 pktSize[cpu_side_port_id][mem_side_port_id] += pkt_size;
355 if (is_express_snoop) {
367 PortID rsp_port_id = cpu_side_port_id;
387 respond_directly =
true;
389 rsp_pkt = cmo_lookup->second;
393 const auto route_lookup =
routeTo.find(rsp_pkt->
req);
394 assert(route_lookup !=
routeTo.end());
395 rsp_port_id = route_lookup->second;
403 respond_directly =
false;
410 "%s: Routing table exceeds %d packets\n",
417 if (respond_directly) {
435 cpuSidePorts[rsp_port_id]->schedTimingResp(rsp_pkt, response_time);
448 const auto route_lookup =
routeTo.find(pkt->
req);
449 assert(route_lookup !=
routeTo.end());
450 const PortID cpu_side_port_id = route_lookup->second;
456 if (!
respLayers[cpu_side_port_id]->tryTiming(src_port)) {
494 respLayers[cpu_side_port_id]->succeededTiming(packetFinishTime);
497 pktCount[cpu_side_port_id][mem_side_port_id]++;
498 pktSize[cpu_side_port_id][mem_side_port_id] += pkt_size;
538 pkt->
print(), sf_res.first.size(), sf_res.second);
571 const auto route_lookup =
routeTo.find(pkt->
req);
572 assert(route_lookup !=
routeTo.end());
573 const PortID dest_port_id = route_lookup->second;
587 if (forwardAsSnoop) {
589 if (!
snoopLayers[dest_port_id]->tryTiming(src_port)) {
598 if (!
respLayers[dest_port_id]->tryTiming(snoop_port)) {
629 if (forwardAsSnoop) {
641 bool success M5_VAR_USED =
643 pktCount[cpu_side_port_id][dest_port_id]++;
644 pktSize[cpu_side_port_id][dest_port_id] += pkt_size;
647 snoopLayers[dest_port_id]->succeededTiming(packetFinishTime);
658 assert(cpu_side_port_id != dest_port_id);
679 respLayers[dest_port_id]->succeededTiming(packetFinishTime);
705 for (
const auto&
p: dests) {
711 p->getId() != exclude_cpu_side_port_id) {
713 p->sendTimingSnoopReq(pkt);
728 reqLayers[mem_side_port_id]->recvRetry();
742 Tick snoop_response_latency = 0;
760 snoop_response_latency += sf_res.second *
clockPeriod();
763 pkt->
print(), sf_res.first.size(), sf_res.second);
777 if (!sf_res.first.empty())
786 snoop_response_cmd = snoop_result.first;
787 snoop_response_latency += snoop_result.second;
791 Tick response_latency = 0;
807 if (pkt->
isWrite() && is_destination) {
813 response_latency = backdoor ?
814 mem_side_port->sendAtomicBackdoor(pkt, *backdoor) :
815 mem_side_port->sendAtomic(pkt);
825 pktCount[cpu_side_port_id][mem_side_port_id]++;
826 pktSize[cpu_side_port_id][mem_side_port_id] += pkt_size;
839 pkt->
cmd = snoop_response_cmd;
840 response_latency = snoop_response_latency;
873 pktCount[cpu_side_port_id][mem_side_port_id]++;
874 pktSize[cpu_side_port_id][mem_side_port_id] += pkt_size;
880 return response_latency;
896 Tick snoop_response_latency = 0;
899 snoop_response_latency += sf_res.second *
clockPeriod();
902 pkt->
print(), sf_res.first.size(), sf_res.second);
908 MemCmd snoop_response_cmd = snoop_result.first;
909 snoop_response_latency += snoop_result.second;
912 pkt->
cmd = snoop_response_cmd;
921 return snoop_response_latency;
926 PortID source_mem_side_port_id,
934 Tick snoop_response_latency = 0;
941 for (
const auto&
p: dests) {
947 p->getId() == exclude_cpu_side_port_id)
950 Tick latency =
p->sendAtomicSnoop(pkt);
960 assert(pkt->
cmd != orig_cmd);
965 snoop_response_cmd = pkt->
cmd;
966 snoop_response_latency = latency;
992 return std::make_pair(snoop_response_cmd, snoop_response_latency);
1018 if (
p->trySatisfyFunctional(pkt)) {
1041 if (
p->trySatisfyFunctional(pkt)) {
1064 p->getId() != exclude_cpu_side_port_id)
1065 p->sendFunctionalSnoop(pkt);
1122 CoherentXBarParams::create()
void updateSnoopForward(const Packet *cpkt, const ResponsePort &rsp_port, const RequestPort &req_port)
Pass snoop responses that travel downward through the snoop filter and let them update the snoop filt...
void recvFunctionalSnoop(PacketPtr pkt, PortID mem_side_port_id)
Function called by the port when the crossbar is receiving a functional snoop transaction.
const Cycles forwardLatency
A ResponsePort is a specialization of a port.
std::vector< QueuedResponsePort * > cpuSidePorts
The memory-side ports and CPU-side ports of the crossbar.
AddrRange getAddrRange() const
Get address range to which this packet belongs.
void setCPUSidePorts(const SnoopList &_cpu_side_ports)
Init a new snoop filter and tell it about all the cpu_sideports of the enclosing bus.
bool cacheResponding() const
Stats::Vector transDist
Stats for transaction distribution and data passing through the crossbar.
bool recvTimingResp(PacketPtr pkt, PortID mem_side_port_id)
bool forwardPacket(const PacketPtr pkt)
Determine if the crossbar should forward the packet, as opposed to responding to it.
bool recvTimingReq(PacketPtr pkt, PortID cpu_side_port_id)
bool isExpressSnoop() const
bool responderHadWritable() const
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
Stats::Distribution snoopFanout
const PortID InvalidPortID
System * system
Keep a pointer to the system to be allow to querying memory system properties.
uint64_t Tick
Tick count type.
Internal class to bridge between an incoming snoop response from a CPU-side port and forwarding it th...
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
bool needsWritable() const
void finishRequest(bool will_retry, Addr addr, bool is_secure)
For an un-successful request, revert the change to the snoop filter.
RequestPtr req
A pointer to the original request.
PortID findPort(AddrRange addr_range)
Find which port connected to this crossbar (if any) should be given a packet with this address range.
bool sinkPacket(const PacketPtr pkt) const
Determine if the crossbar should sink the packet, as opposed to forwarding it, or responding.
std::pair< SnoopList, Cycles > lookupSnoop(const Packet *cpkt)
Handle an incoming snoop from below (the memory-side port).
const Cycles frontendLatency
Cycles of front-end pipeline including the delay to accept the request and to decode the address.
Tick recvAtomicSnoop(PacketPtr pkt, PortID mem_side_port_id)
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
void print(std::ostream &o, int verbosity=0, const std::string &prefix="") const
PortID defaultPortID
Port that handles requests that don't match any of the interfaces.
void recvReqRetry(PortID mem_side_port_id)
std::vector< RespLayer * > respLayers
void recvTimingSnoopReq(PacketPtr pkt, PortID mem_side_port_id)
void recvFunctional(PacketPtr pkt, PortID cpu_side_port_id)
Function called by the port when the crossbar is receiving a Functional transaction.
std::unique_ptr< Packet > pendingDelete
Upstream caches need this packet until true is returned, so hold it for deletion until a subsequent c...
CoherentXBar(const CoherentXBarParams *p)
Declaration of the coherent crossbar memory-side port type, one will be instantiated for each of the ...
bool needsResponse() const
std::vector< SnoopRespLayer * > snoopLayers
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...
virtual void init()
init() is called after all C++ SimObjects have been created and all ports are connected.
std::unordered_map< RequestPtr, PortID > routeTo
Remember where request packets came from so that we can route responses to the appropriate port.
std::unordered_map< PacketId, PacketPtr > outstandingCMO
Store the outstanding cache maintenance that we are expecting snoop responses from so we can determin...
bool bypassCaches() const
Should caches be bypassed?
A queued port is a port that has an infinite queue for outgoing packets and thus decouples the module...
uint32_t snoopDelay
Keep track of the extra delay incurred by snooping upwards before sending a request down the memory s...
int cmdToIndex() const
Return the index of this command.
A RequestPort is a specialisation of a Port, which implements the default protocol for the three diff...
std::vector< ReqLayer * > reqLayers
Declare the layers of this crossbar, one vector for requests, one for responses, and one for snoop re...
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
const std::string name() const
Return port name (for DPRINTF).
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
const bool pointOfCoherency
Is this crossbar the point of coherency?
SnoopFilter * snoopFilter
A snoop filter that tracks cache line residency and can restrict the broadcast needed for probes.
bool recvTimingSnoopResp(PacketPtr pkt, PortID cpu_side_port_id)
virtual void regStats()
Callback to set stat parameters.
bool isCleanEviction() const
Is this packet a clean eviction, including both actual clean evict packets, but also clean writebacks...
Tick recvAtomicBackdoor(PacketPtr pkt, PortID cpu_side_port_id, MemBackdoorPtr *backdoor=nullptr)
void forwardTiming(PacketPtr pkt, PortID exclude_cpu_side_port_id)
Forward a timing packet to our snoopers, potentially excluding one of the connected coherent requesto...
virtual const std::string name() const
MemCmd cmd
The command field of the packet.
const unsigned int maxOutstandingSnoopCheck
Maximum number of outstading snoops sanity check.
std::pair< SnoopList, Cycles > lookupRequest(const Packet *cpkt, const ResponsePort &cpu_side_port)
Lookup a request (from a CPU-side port) in the snoop filter and return a list of other CPU-side ports...
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
std::vector< SnoopRespPort * > snoopRespPorts
void updateSnoopResponse(const Packet *cpkt, const ResponsePort &rsp_port, const ResponsePort &req_port)
Let the snoop filter see any snoop responses that turn into request responses and indicate cache to c...
void setExpressSnoop()
The express snoop flag is used for two purposes.
Distribution & init(Counter min, Counter max, Counter bkt)
Set the parameters of this distribution.
const Cycles headerLatency
Cycles the layer is occupied processing the packet header.
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
const unsigned int maxRoutingTableSizeCheck
Maximum routing table size sanity check.
bool isDestination(const PacketPtr pkt) const
Determine if the packet's destination is the memory below.
const Cycles responseLatency
virtual void init()
init() is called after all C++ SimObjects have been created and all ports are connected.
const Cycles snoopResponseLatency
Cycles of snoop response latency.
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
Cycles is a wrapper class for representing cycle counts, i.e.
void updateResponse(const Packet *cpkt, const ResponsePort &cpu_side_port)
Update the snoop filter with a response from below (outer / other cache, or memory) and update the tr...
bool isBlockCached() const
std::vector< QueuedResponsePort * > snoopPorts
void regStats() override
Callback to set stat parameters.
The base crossbar contains the common elements of the non-coherent and coherent crossbar.
A coherent crossbar connects a number of (potentially) snooping requestors and responders,...
std::unordered_set< RequestPtr > outstandingSnoop
Store the outstanding requests that we are expecting snoop responses from so we can determine which s...
void calcPacketTiming(PacketPtr pkt, Tick header_delay)
Calculate the timing parameters for the packet.
std::string csprintf(const char *format, const Args &...args)
std::vector< RequestPort * > memSidePorts
std::pair< MemCmd, Tick > forwardAtomic(PacketPtr pkt, PortID exclude_cpu_side_port_id)
Forward an atomic packet to our snoopers, potentially excluding one of the connected coherent request...
Stats::Scalar snoopTraffic
Declaration of the coherent crossbar CPU-side port type, one will be instantiated for each of the mem...
void forwardFunctional(PacketPtr pkt, PortID exclude_cpu_side_port_id)
Forward a functional packet to our snoopers, potentially excluding one of the connected coherent requ...
Tick curTick()
The current simulated tick.
Generated on Wed Sep 30 2020 14:02:13 for gem5 by doxygen 1.8.17