system = Param.System(Parent.any, "System that the crossbar belongs to.")
+ # Sanity check on max capacity to track, adjust if needed.
+ max_capacity = Param.MemorySize('8MB', "Maximum capacity of snoop filter")
+
# We use a coherent crossbar to connect multiple masters to the L2
# caches. Normally this crossbar would be part of the cache itself.
class L2XBar(CoherentXBar):
response_latency = 1
snoop_response_latency = 1
+ # Use a snoop-filter by default, and set the latency to zero as
+ # the lookup is assumed to overlap with the frontend latency of
+ # the crossbar
+ snoop_filter = SnoopFilter(lookup_latency = 0)
+
# One of the key coherent crossbar instances is the system
# interconnect, tying together the CPU clusters, GPUs, and any I/O
# coherent masters, and DRAM controllers.
auto sf_it = cachedLocations.find(line_addr);
bool is_hit = (sf_it != cachedLocations.end());
+ panic_if(!is_hit && (cachedLocations.size() >= maxEntryCount),
+ "snoop filter exceeded capacity of %d cache blocks\n",
+ maxEntryCount);
+
// If the snoop filter has no entry and its an uncacheable
// request, do not create a new snoop filter entry, simply return
// a NULL portlist.
SnoopFilter (const SnoopFilterParams *p) :
SimObject(p), reqLookupResult(cachedLocations.end()), retryItem{0, 0},
- linesize(p->system->cacheLineSize()), lookupLatency(p->lookup_latency)
+ linesize(p->system->cacheLineSize()), lookupLatency(p->lookup_latency),
+ maxEntryCount(p->max_capacity / p->system->cacheLineSize())
{
}
const unsigned linesize;
/** Latency for doing a lookup in the filter */
const Cycles lookupLatency;
+ /** Max capacity in terms of cache blocks tracked, for sanity checking */
+ const unsigned maxEntryCount;
/** Statistics */
Stats::Scalar totRequests;