coherent_xbar.hh revision 12351
17585SAli.Saidi@arm.com/* 27585SAli.Saidi@arm.com * Copyright (c) 2011-2015, 2017 ARM Limited 37585SAli.Saidi@arm.com * All rights reserved 47585SAli.Saidi@arm.com * 57585SAli.Saidi@arm.com * The license below extends only to copyright in the software and shall 67585SAli.Saidi@arm.com * not be construed as granting a license to any other intellectual 77585SAli.Saidi@arm.com * property including but not limited to intellectual property relating 87585SAli.Saidi@arm.com * to a hardware implementation of the functionality of the software 97585SAli.Saidi@arm.com * licensed hereunder. You may use the software subject to the license 107585SAli.Saidi@arm.com * terms below provided that you ensure that this notice is replicated 117585SAli.Saidi@arm.com * unmodified and in its entirety in all distributions of the software, 127585SAli.Saidi@arm.com * modified or unmodified, in source code or in binary form. 137585SAli.Saidi@arm.com * 147585SAli.Saidi@arm.com * Copyright (c) 2002-2005 The Regents of The University of Michigan 157585SAli.Saidi@arm.com * All rights reserved. 167585SAli.Saidi@arm.com * 177585SAli.Saidi@arm.com * Redistribution and use in source and binary forms, with or without 187585SAli.Saidi@arm.com * modification, are permitted provided that the following conditions are 197585SAli.Saidi@arm.com * met: redistributions of source code must retain the above copyright 207585SAli.Saidi@arm.com * notice, this list of conditions and the following disclaimer; 217585SAli.Saidi@arm.com * redistributions in binary form must reproduce the above copyright 227585SAli.Saidi@arm.com * notice, this list of conditions and the following disclaimer in the 237585SAli.Saidi@arm.com * documentation and/or other materials provided with the distribution; 247585SAli.Saidi@arm.com * neither the name of the copyright holders nor the names of its 257585SAli.Saidi@arm.com * contributors may be used to endorse or promote products derived from 267585SAli.Saidi@arm.com * this software without specific prior written permission. 277585SAli.Saidi@arm.com * 287585SAli.Saidi@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 297585SAli.Saidi@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 307585SAli.Saidi@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 317585SAli.Saidi@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 327585SAli.Saidi@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 337585SAli.Saidi@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 347585SAli.Saidi@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 357585SAli.Saidi@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 367585SAli.Saidi@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 377585SAli.Saidi@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 387585SAli.Saidi@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 397585SAli.Saidi@arm.com * 407585SAli.Saidi@arm.com * Authors: Ron Dreslinski 417585SAli.Saidi@arm.com * Ali Saidi 427585SAli.Saidi@arm.com * Andreas Hansson 437585SAli.Saidi@arm.com * William Wang 447585SAli.Saidi@arm.com */ 457585SAli.Saidi@arm.com 467585SAli.Saidi@arm.com/** 477585SAli.Saidi@arm.com * @file 487585SAli.Saidi@arm.com * Declaration of a coherent crossbar. 497585SAli.Saidi@arm.com */ 507585SAli.Saidi@arm.com 517585SAli.Saidi@arm.com#ifndef __MEM_COHERENT_XBAR_HH__ 527585SAli.Saidi@arm.com#define __MEM_COHERENT_XBAR_HH__ 537585SAli.Saidi@arm.com 547585SAli.Saidi@arm.com#include <unordered_map> 557585SAli.Saidi@arm.com#include <unordered_set> 567585SAli.Saidi@arm.com 577585SAli.Saidi@arm.com#include "mem/snoop_filter.hh" 587585SAli.Saidi@arm.com#include "mem/xbar.hh" 597585SAli.Saidi@arm.com#include "params/CoherentXBar.hh" 607585SAli.Saidi@arm.com 617585SAli.Saidi@arm.com/** 627585SAli.Saidi@arm.com * A coherent crossbar connects a number of (potentially) snooping 637585SAli.Saidi@arm.com * masters and slaves, and routes the request and response packets 647585SAli.Saidi@arm.com * based on the address, and also forwards all requests to the 657585SAli.Saidi@arm.com * snoopers and deals with the snoop responses. 667585SAli.Saidi@arm.com * 677585SAli.Saidi@arm.com * The coherent crossbar can be used as a template for modelling QPI, 687585SAli.Saidi@arm.com * HyperTransport, ACE and coherent OCP buses, and is typically used 697585SAli.Saidi@arm.com * for the L1-to-L2 buses and as the main system interconnect. @sa 707585SAli.Saidi@arm.com * \ref gem5MemorySystem "gem5 Memory System" 717585SAli.Saidi@arm.com */ 727585SAli.Saidi@arm.comclass CoherentXBar : public BaseXBar 737585SAli.Saidi@arm.com{ 747585SAli.Saidi@arm.com 757585SAli.Saidi@arm.com protected: 767585SAli.Saidi@arm.com 777585SAli.Saidi@arm.com /** 787585SAli.Saidi@arm.com * Declare the layers of this crossbar, one vector for requests, 797585SAli.Saidi@arm.com * one for responses, and one for snoop responses 807585SAli.Saidi@arm.com */ 817585SAli.Saidi@arm.com std::vector<ReqLayer*> reqLayers; 827585SAli.Saidi@arm.com std::vector<RespLayer*> respLayers; 837585SAli.Saidi@arm.com std::vector<SnoopRespLayer*> snoopLayers; 847585SAli.Saidi@arm.com 857585SAli.Saidi@arm.com /** 867585SAli.Saidi@arm.com * Declaration of the coherent crossbar slave port type, one will 877585SAli.Saidi@arm.com * be instantiated for each of the master ports connecting to the 887585SAli.Saidi@arm.com * crossbar. 897585SAli.Saidi@arm.com */ 907585SAli.Saidi@arm.com class CoherentXBarSlavePort : public QueuedSlavePort 917585SAli.Saidi@arm.com { 927585SAli.Saidi@arm.com 937585SAli.Saidi@arm.com private: 947585SAli.Saidi@arm.com 957585SAli.Saidi@arm.com /** A reference to the crossbar to which this port belongs. */ 967585SAli.Saidi@arm.com CoherentXBar &xbar; 977585SAli.Saidi@arm.com 987585SAli.Saidi@arm.com /** A normal packet queue used to store responses. */ 997585SAli.Saidi@arm.com RespPacketQueue queue; 1007585SAli.Saidi@arm.com 1017585SAli.Saidi@arm.com public: 1027585SAli.Saidi@arm.com 1037585SAli.Saidi@arm.com CoherentXBarSlavePort(const std::string &_name, 1047585SAli.Saidi@arm.com CoherentXBar &_xbar, PortID _id) 1057585SAli.Saidi@arm.com : QueuedSlavePort(_name, &_xbar, queue, _id), xbar(_xbar), 1067585SAli.Saidi@arm.com queue(_xbar, *this) 1077585SAli.Saidi@arm.com { } 1087585SAli.Saidi@arm.com 1097585SAli.Saidi@arm.com protected: 1107585SAli.Saidi@arm.com 1117585SAli.Saidi@arm.com /** 1127585SAli.Saidi@arm.com * When receiving a timing request, pass it to the crossbar. 1137585SAli.Saidi@arm.com */ 1147585SAli.Saidi@arm.com virtual bool recvTimingReq(PacketPtr pkt) 1157585SAli.Saidi@arm.com { return xbar.recvTimingReq(pkt, id); } 1167585SAli.Saidi@arm.com 1177585SAli.Saidi@arm.com /** 1187585SAli.Saidi@arm.com * When receiving a timing snoop response, pass it to the crossbar. 1197585SAli.Saidi@arm.com */ 1207585SAli.Saidi@arm.com virtual bool recvTimingSnoopResp(PacketPtr pkt) 1217585SAli.Saidi@arm.com { return xbar.recvTimingSnoopResp(pkt, id); } 1227585SAli.Saidi@arm.com 1237585SAli.Saidi@arm.com /** 1247585SAli.Saidi@arm.com * When receiving an atomic request, pass it to the crossbar. 1257585SAli.Saidi@arm.com */ 1267585SAli.Saidi@arm.com virtual Tick recvAtomic(PacketPtr pkt) 1277585SAli.Saidi@arm.com { return xbar.recvAtomic(pkt, id); } 1287585SAli.Saidi@arm.com 1297585SAli.Saidi@arm.com /** 1307585SAli.Saidi@arm.com * When receiving a functional request, pass it to the crossbar. 1317585SAli.Saidi@arm.com */ 1327585SAli.Saidi@arm.com virtual void recvFunctional(PacketPtr pkt) 1337585SAli.Saidi@arm.com { xbar.recvFunctional(pkt, id); } 1347585SAli.Saidi@arm.com 1357585SAli.Saidi@arm.com /** 1367585SAli.Saidi@arm.com * Return the union of all adress ranges seen by this crossbar. 1377585SAli.Saidi@arm.com */ 1387585SAli.Saidi@arm.com virtual AddrRangeList getAddrRanges() const 1397585SAli.Saidi@arm.com { return xbar.getAddrRanges(); } 1407585SAli.Saidi@arm.com 1417585SAli.Saidi@arm.com }; 1427585SAli.Saidi@arm.com 1437585SAli.Saidi@arm.com /** 1447585SAli.Saidi@arm.com * Declaration of the coherent crossbar master port type, one will be 1457585SAli.Saidi@arm.com * instantiated for each of the slave interfaces connecting to the 1467585SAli.Saidi@arm.com * crossbar. 1477585SAli.Saidi@arm.com */ 1487585SAli.Saidi@arm.com class CoherentXBarMasterPort : public MasterPort 1497585SAli.Saidi@arm.com { 1507585SAli.Saidi@arm.com private: 1517585SAli.Saidi@arm.com /** A reference to the crossbar to which this port belongs. */ 1527585SAli.Saidi@arm.com CoherentXBar &xbar; 1537585SAli.Saidi@arm.com 1547585SAli.Saidi@arm.com public: 1557585SAli.Saidi@arm.com 1567585SAli.Saidi@arm.com CoherentXBarMasterPort(const std::string &_name, 1577585SAli.Saidi@arm.com CoherentXBar &_xbar, PortID _id) 1587585SAli.Saidi@arm.com : MasterPort(_name, &_xbar, _id), xbar(_xbar) 1597585SAli.Saidi@arm.com { } 1607585SAli.Saidi@arm.com 1617585SAli.Saidi@arm.com protected: 1627585SAli.Saidi@arm.com 1637585SAli.Saidi@arm.com /** 1647585SAli.Saidi@arm.com * Determine if this port should be considered a snooper. For 1657585SAli.Saidi@arm.com * a coherent crossbar master port this is always true. 1667585SAli.Saidi@arm.com * 1677585SAli.Saidi@arm.com * @return a boolean that is true if this port is snooping 1687585SAli.Saidi@arm.com */ 1697585SAli.Saidi@arm.com virtual bool isSnooping() const 1707585SAli.Saidi@arm.com { return true; } 1717585SAli.Saidi@arm.com 1727585SAli.Saidi@arm.com /** 1737585SAli.Saidi@arm.com * When receiving a timing response, pass it to the crossbar. 1747585SAli.Saidi@arm.com */ 1757585SAli.Saidi@arm.com virtual bool recvTimingResp(PacketPtr pkt) 1767585SAli.Saidi@arm.com { return xbar.recvTimingResp(pkt, id); } 1777585SAli.Saidi@arm.com 1787585SAli.Saidi@arm.com /** 1797585SAli.Saidi@arm.com * When receiving a timing snoop request, pass it to the crossbar. 1807585SAli.Saidi@arm.com */ 1817585SAli.Saidi@arm.com virtual void recvTimingSnoopReq(PacketPtr pkt) 1827585SAli.Saidi@arm.com { return xbar.recvTimingSnoopReq(pkt, id); } 1837585SAli.Saidi@arm.com 1847585SAli.Saidi@arm.com /** 1857585SAli.Saidi@arm.com * When receiving an atomic snoop request, pass it to the crossbar. 1867585SAli.Saidi@arm.com */ 1877585SAli.Saidi@arm.com virtual Tick recvAtomicSnoop(PacketPtr pkt) 1887585SAli.Saidi@arm.com { return xbar.recvAtomicSnoop(pkt, id); } 1897585SAli.Saidi@arm.com 1907585SAli.Saidi@arm.com /** 1917585SAli.Saidi@arm.com * When receiving a functional snoop request, pass it to the crossbar. 1927585SAli.Saidi@arm.com */ 1937585SAli.Saidi@arm.com virtual void recvFunctionalSnoop(PacketPtr pkt) 1947585SAli.Saidi@arm.com { xbar.recvFunctionalSnoop(pkt, id); } 1957585SAli.Saidi@arm.com 1967585SAli.Saidi@arm.com /** When reciving a range change from the peer port (at id), 1977585SAli.Saidi@arm.com pass it to the crossbar. */ 1987585SAli.Saidi@arm.com virtual void recvRangeChange() 1997585SAli.Saidi@arm.com { xbar.recvRangeChange(id); } 2007585SAli.Saidi@arm.com 2017585SAli.Saidi@arm.com /** When reciving a retry from the peer port (at id), 2027585SAli.Saidi@arm.com pass it to the crossbar. */ 2037585SAli.Saidi@arm.com virtual void recvReqRetry() 2047585SAli.Saidi@arm.com { xbar.recvReqRetry(id); } 2057585SAli.Saidi@arm.com 2067585SAli.Saidi@arm.com }; 2077585SAli.Saidi@arm.com 2087585SAli.Saidi@arm.com /** 2097585SAli.Saidi@arm.com * Internal class to bridge between an incoming snoop response 2107585SAli.Saidi@arm.com * from a slave port and forwarding it through an outgoing slave 2117585SAli.Saidi@arm.com * port. It is effectively a dangling master port. 2127585SAli.Saidi@arm.com */ 2137585SAli.Saidi@arm.com class SnoopRespPort : public MasterPort 2147585SAli.Saidi@arm.com { 2157585SAli.Saidi@arm.com 2167585SAli.Saidi@arm.com private: 2177585SAli.Saidi@arm.com 2187585SAli.Saidi@arm.com /** The port which we mirror internally. */ 2197585SAli.Saidi@arm.com QueuedSlavePort& slavePort; 2207585SAli.Saidi@arm.com 2217585SAli.Saidi@arm.com public: 2227585SAli.Saidi@arm.com 2237585SAli.Saidi@arm.com /** 2247585SAli.Saidi@arm.com * Create a snoop response port that mirrors a given slave port. 2257585SAli.Saidi@arm.com */ 2267585SAli.Saidi@arm.com SnoopRespPort(QueuedSlavePort& slave_port, CoherentXBar& _xbar) : 2277585SAli.Saidi@arm.com MasterPort(slave_port.name() + ".snoopRespPort", &_xbar), 2287585SAli.Saidi@arm.com slavePort(slave_port) { } 2297585SAli.Saidi@arm.com 2307585SAli.Saidi@arm.com /** 2317585SAli.Saidi@arm.com * Override the sending of retries and pass them on through 2327585SAli.Saidi@arm.com * the mirrored slave port. 2337585SAli.Saidi@arm.com */ 2347585SAli.Saidi@arm.com void sendRetryResp() { 2357585SAli.Saidi@arm.com // forward it as a snoop response retry 2367585SAli.Saidi@arm.com slavePort.sendRetrySnoopResp(); 2377585SAli.Saidi@arm.com } 2387585SAli.Saidi@arm.com 2397585SAli.Saidi@arm.com /** 2407585SAli.Saidi@arm.com * Provided as necessary. 2417585SAli.Saidi@arm.com */ 2427585SAli.Saidi@arm.com void recvReqRetry() { panic("SnoopRespPort should never see retry\n"); } 2437585SAli.Saidi@arm.com 2447585SAli.Saidi@arm.com /** 2457585SAli.Saidi@arm.com * Provided as necessary. 2467585SAli.Saidi@arm.com */ 2477585SAli.Saidi@arm.com bool recvTimingResp(PacketPtr pkt) 2487585SAli.Saidi@arm.com { 2497585SAli.Saidi@arm.com panic("SnoopRespPort should never see timing response\n"); 2507585SAli.Saidi@arm.com return false; 2517585SAli.Saidi@arm.com } 2527585SAli.Saidi@arm.com 2537585SAli.Saidi@arm.com }; 2547585SAli.Saidi@arm.com 2557585SAli.Saidi@arm.com std::vector<SnoopRespPort*> snoopRespPorts; 2567585SAli.Saidi@arm.com 2577585SAli.Saidi@arm.com std::vector<QueuedSlavePort*> snoopPorts; 2587585SAli.Saidi@arm.com 2597585SAli.Saidi@arm.com /** 2607585SAli.Saidi@arm.com * Store the outstanding requests that we are expecting snoop 2617585SAli.Saidi@arm.com * responses from so we can determine which snoop responses we 2627585SAli.Saidi@arm.com * generated and which ones were merely forwarded. 2637585SAli.Saidi@arm.com */ 2647585SAli.Saidi@arm.com std::unordered_set<RequestPtr> outstandingSnoop; 2657585SAli.Saidi@arm.com 2667585SAli.Saidi@arm.com /** 2677585SAli.Saidi@arm.com * Store the outstanding cache maintenance that we are expecting 2687585SAli.Saidi@arm.com * snoop responses from so we can determine when we received all 2697585SAli.Saidi@arm.com * snoop responses and if any of the agents satisfied the request. 2707585SAli.Saidi@arm.com */ 2717585SAli.Saidi@arm.com std::unordered_map<PacketId, PacketPtr> outstandingCMO; 2727585SAli.Saidi@arm.com 2737585SAli.Saidi@arm.com /** 2747585SAli.Saidi@arm.com * Keep a pointer to the system to be allow to querying memory system 2757585SAli.Saidi@arm.com * properties. 2767585SAli.Saidi@arm.com */ 2777585SAli.Saidi@arm.com System *system; 2787585SAli.Saidi@arm.com 2797585SAli.Saidi@arm.com /** A snoop filter that tracks cache line residency and can restrict the 2807585SAli.Saidi@arm.com * broadcast needed for probes. NULL denotes an absent filter. */ 2817585SAli.Saidi@arm.com SnoopFilter *snoopFilter; 2827585SAli.Saidi@arm.com 283 /** Cycles of snoop response latency.*/ 284 const Cycles snoopResponseLatency; 285 286 /** Is this crossbar the point of coherency? **/ 287 const bool pointOfCoherency; 288 289 /** Is this crossbar the point of unification? **/ 290 const bool pointOfUnification; 291 292 /** 293 * Upstream caches need this packet until true is returned, so 294 * hold it for deletion until a subsequent call 295 */ 296 std::unique_ptr<Packet> pendingDelete; 297 298 /** Function called by the port when the crossbar is recieving a Timing 299 request packet.*/ 300 bool recvTimingReq(PacketPtr pkt, PortID slave_port_id); 301 302 /** Function called by the port when the crossbar is recieving a Timing 303 response packet.*/ 304 bool recvTimingResp(PacketPtr pkt, PortID master_port_id); 305 306 /** Function called by the port when the crossbar is recieving a timing 307 snoop request.*/ 308 void recvTimingSnoopReq(PacketPtr pkt, PortID master_port_id); 309 310 /** Function called by the port when the crossbar is recieving a timing 311 snoop response.*/ 312 bool recvTimingSnoopResp(PacketPtr pkt, PortID slave_port_id); 313 314 /** Timing function called by port when it is once again able to process 315 * requests. */ 316 void recvReqRetry(PortID master_port_id); 317 318 /** 319 * Forward a timing packet to our snoopers, potentially excluding 320 * one of the connected coherent masters to avoid sending a packet 321 * back to where it came from. 322 * 323 * @param pkt Packet to forward 324 * @param exclude_slave_port_id Id of slave port to exclude 325 */ 326 void forwardTiming(PacketPtr pkt, PortID exclude_slave_port_id) { 327 forwardTiming(pkt, exclude_slave_port_id, snoopPorts); 328 } 329 330 /** 331 * Forward a timing packet to a selected list of snoopers, potentially 332 * excluding one of the connected coherent masters to avoid sending a packet 333 * back to where it came from. 334 * 335 * @param pkt Packet to forward 336 * @param exclude_slave_port_id Id of slave port to exclude 337 * @param dests Vector of destination ports for the forwarded pkt 338 */ 339 void forwardTiming(PacketPtr pkt, PortID exclude_slave_port_id, 340 const std::vector<QueuedSlavePort*>& dests); 341 342 /** Function called by the port when the crossbar is recieving a Atomic 343 transaction.*/ 344 Tick recvAtomic(PacketPtr pkt, PortID slave_port_id); 345 346 /** Function called by the port when the crossbar is recieving an 347 atomic snoop transaction.*/ 348 Tick recvAtomicSnoop(PacketPtr pkt, PortID master_port_id); 349 350 /** 351 * Forward an atomic packet to our snoopers, potentially excluding 352 * one of the connected coherent masters to avoid sending a packet 353 * back to where it came from. 354 * 355 * @param pkt Packet to forward 356 * @param exclude_slave_port_id Id of slave port to exclude 357 * 358 * @return a pair containing the snoop response and snoop latency 359 */ 360 std::pair<MemCmd, Tick> forwardAtomic(PacketPtr pkt, 361 PortID exclude_slave_port_id) 362 { 363 return forwardAtomic(pkt, exclude_slave_port_id, InvalidPortID, 364 snoopPorts); 365 } 366 367 /** 368 * Forward an atomic packet to a selected list of snoopers, potentially 369 * excluding one of the connected coherent masters to avoid sending a packet 370 * back to where it came from. 371 * 372 * @param pkt Packet to forward 373 * @param exclude_slave_port_id Id of slave port to exclude 374 * @param source_master_port_id Id of the master port for snoops from below 375 * @param dests Vector of destination ports for the forwarded pkt 376 * 377 * @return a pair containing the snoop response and snoop latency 378 */ 379 std::pair<MemCmd, Tick> forwardAtomic(PacketPtr pkt, 380 PortID exclude_slave_port_id, 381 PortID source_master_port_id, 382 const std::vector<QueuedSlavePort*>& 383 dests); 384 385 /** Function called by the port when the crossbar is recieving a Functional 386 transaction.*/ 387 void recvFunctional(PacketPtr pkt, PortID slave_port_id); 388 389 /** Function called by the port when the crossbar is recieving a functional 390 snoop transaction.*/ 391 void recvFunctionalSnoop(PacketPtr pkt, PortID master_port_id); 392 393 /** 394 * Forward a functional packet to our snoopers, potentially 395 * excluding one of the connected coherent masters to avoid 396 * sending a packet back to where it came from. 397 * 398 * @param pkt Packet to forward 399 * @param exclude_slave_port_id Id of slave port to exclude 400 */ 401 void forwardFunctional(PacketPtr pkt, PortID exclude_slave_port_id); 402 403 /** 404 * Determine if the crossbar should sink the packet, as opposed to 405 * forwarding it, or responding. 406 */ 407 bool sinkPacket(const PacketPtr pkt) const; 408 409 /** 410 * Determine if the crossbar should forward the packet, as opposed to 411 * responding to it. 412 */ 413 bool forwardPacket(const PacketPtr pkt); 414 415 /** 416 * Determine if the packet's destination is the memory below 417 * 418 * The memory below is the destination for a cache mainteance 419 * operation to the Point of Coherence/Unification if this is the 420 * Point of Coherence/Unification. 421 * 422 * @param pkt The processed packet 423 * 424 * @return Whether the memory below is the destination for the packet 425 */ 426 bool isDestination(const PacketPtr pkt) const 427 { 428 return (pkt->req->isToPOC() && pointOfCoherency) || 429 (pkt->req->isToPOU() && pointOfUnification); 430 } 431 432 Stats::Scalar snoops; 433 Stats::Scalar snoopTraffic; 434 Stats::Distribution snoopFanout; 435 436 public: 437 438 virtual void init(); 439 440 CoherentXBar(const CoherentXBarParams *p); 441 442 virtual ~CoherentXBar(); 443 444 virtual void regStats(); 445}; 446 447#endif //__MEM_COHERENT_XBAR_HH__ 448