Go to the documentation of this file.
50 #include "debug/Cache.hh"
51 #include "debug/CacheComp.hh"
52 #include "debug/CachePort.hh"
53 #include "debug/CacheRepl.hh"
54 #include "debug/CacheVerbose.hh"
60 #include "params/BaseCache.hh"
61 #include "params/WriteAllocator.hh"
68 const std::string &_label)
70 queue(*_cache, *this, true, _label),
71 blocked(false), mustSendRetry(false),
80 mshrQueue(
"MSHRs",
p->mshrs, 0,
p->demand_mshr_reserve),
92 lookupLatency(
p->tag_latency),
93 dataLatency(
p->data_latency),
94 forwardLatency(
p->tag_latency),
95 fillLatency(
p->data_latency),
96 responseLatency(
p->response_latency),
97 sequentialAccess(
p->sequential_access),
98 numTarget(
p->tgts_per_mshr),
100 clusivity(
p->clusivity),
101 isReadOnly(
p->is_read_only),
104 noTargetMSHR(
nullptr),
105 missCount(
p->max_miss_count),
106 addrRanges(
p->addr_ranges.begin(),
p->addr_ranges.end()),
123 prefetcher->setCache(
this);
135 DPRINTF(CachePort,
"Port is blocking new requests\n");
141 DPRINTF(CachePort,
"Port descheduled retry\n");
150 DPRINTF(CachePort,
"Port is accepting new requests\n");
154 owner.schedule(sendRetryEvent,
curTick() + 1);
161 DPRINTF(CachePort,
"Port is sending retry\n");
164 mustSendRetry =
false;
182 fatal(
"Cache ports on %s are not connected\n",
name());
190 if (if_name ==
"mem_side") {
192 }
else if (if_name ==
"cpu_side") {
203 if (
r.contains(
addr)) {
227 DPRINTF(
Cache,
"%s satisfied %s, no response needed\n", __func__,
240 Tick forward_time,
Tick request_time)
243 pkt && pkt->
isWrite() && !pkt->
req->isUncacheable()) {
322 pkt->
req->isCacheMaintenance());
342 bool satisfied =
false;
347 satisfied =
access(pkt, blk, lat, writebacks);
409 "%s saw a non-zero packet delay\n",
name());
411 const bool is_error = pkt->
isError();
414 DPRINTF(
Cache,
"%s: Cache received %s with error\n", __func__,
424 assert(pkt->
req->isUncacheable());
443 if (pkt->
req->isUncacheable()) {
465 if (is_fill && !is_error) {
466 DPRINTF(
Cache,
"Block for addr %#llx being updated in Cache\n",
471 blk =
handleFill(pkt, blk, writebacks, allocate);
472 assert(blk !=
nullptr);
488 if (blk && blk->
isWritable() && !pkt->
req->isCacheInvalidate()) {
534 DPRINTF(CacheVerbose,
"%s: Leaving with %s\n", __func__, pkt->
print());
552 bool satisfied =
access(pkt, blk, lat, writebacks);
559 DPRINTF(CacheVerbose,
"%s: packet %s found block: %s\n",
562 writebacks.push_back(wb_pkt);
569 assert(writebacks.empty());
637 bool have_data = blk && blk->
isValid()
644 have_data && (blk->
isDirty() ||
647 bool done = have_dirty ||
653 DPRINTF(CacheVerbose,
"%s: %s %s%s%s\n", __func__, pkt->
print(),
654 (blk && blk->
isValid()) ?
"valid " :
"",
655 have_data ?
"data " :
"", done ?
"done " :
"");
681 uint64_t overwrite_val;
683 uint64_t condition_val64;
684 uint32_t condition_val32;
689 assert(
sizeof(uint64_t) >= pkt->
getSize());
691 overwrite_mem =
true;
694 pkt->
writeData((uint8_t *)&overwrite_val);
697 if (pkt->
req->isCondSwap()) {
698 if (pkt->
getSize() ==
sizeof(uint64_t)) {
699 condition_val64 = pkt->
req->getExtraData();
700 overwrite_mem = !std::memcmp(&condition_val64, blk_data,
702 }
else if (pkt->
getSize() ==
sizeof(uint32_t)) {
703 condition_val32 = (uint32_t)pkt->
req->getExtraData();
704 overwrite_mem = !std::memcmp(&condition_val32, blk_data,
707 panic(
"Invalid size for conditional read/write\n");
711 std::memcpy(blk_data, &overwrite_val, pkt->
getSize());
731 if (conflict_mshr && conflict_mshr->
order < wq_entry->
order) {
733 return conflict_mshr;
740 }
else if (miss_mshr) {
756 return conflict_mshr;
766 assert(!miss_mshr && !wq_entry);
798 bool replacement =
false;
799 for (
const auto& blk : evict_blks) {
800 if (blk->isValid()) {
821 for (
auto& blk : evict_blks) {
822 if (blk->isValid()) {
849 const auto comp_data =
851 std::size_t compression_size = comp_data->getSizeBits();
858 const std::size_t M5_VAR_USED prev_size = compression_blk->
getSizeBits();
861 const bool is_co_allocatable = superblock->
isCompressed(compression_blk) &&
870 const bool was_compressed = compression_blk->
isCompressed();
871 if (was_compressed && !is_co_allocatable) {
873 for (
const auto& sub_blk : superblock->
blks) {
874 if (sub_blk->isValid() && (compression_blk != sub_blk)) {
875 evict_blks.push_back(sub_blk);
887 DPRINTF(CacheComp,
"Data expansion: expanding [%s] from %d to %d bits"
888 "\n", blk->
print(), prev_size, compression_size);
892 if (is_co_allocatable) {
951 DPRINTF(CacheVerbose,
"%s for %s (write)\n", __func__, pkt->
print());
952 }
else if (pkt->
isRead()) {
976 DPRINTF(CacheVerbose,
"%s for %s (invalidation)\n", __func__,
988 const Cycles lookup_lat)
const
997 const Cycles lookup_lat)
const
1001 if (blk !=
nullptr) {
1015 if (when_ready >
tick &&
1037 "Should never see a write in a read-only cache %s\n",
1045 blk ?
"hit " + blk->
print() :
"miss");
1047 if (pkt->
req->isCacheMaintenance()) {
1120 DPRINTF(
Cache,
"Clean writeback %#llx to block with MSHR, "
1121 "dropping\n", pkt->
getAddr());
1286 pkt->
req->setExtraData(0);
1335 is_secure ?
"s" :
"ns");
1345 assert(blk->
isSecure() == is_secure);
1378 "in read-only cache %s\n",
name());
1383 DPRINTF(
Cache,
"Block addr %#llx (%s) moving from state %x to %s\n",
1384 addr, is_secure ?
"s" :
"ns", old_state, blk->
print());
1409 const bool is_secure = pkt->
isSecure();
1414 std::size_t blk_size_bits =
blkSize*8;
1425 pkt->
getConstPtr<uint64_t>(), compression_lat, decompression_lat);
1426 blk_size_bits = comp_data->getSizeBits();
1439 DPRINTF(CacheRepl,
"Replacement victim: %s\n", victim->
print());
1481 writebacks.push_back(pkt);
1489 "Writeback from read-only cache");
1506 DPRINTF(
Cache,
"Create Writeback %s writable: %d, dirty: %d\n",
1547 req->setFlags(dest);
1609 RequestPtr request = std::make_shared<Request>(
1630 warn_once(
"Invalidating dirty cache lines. " \
1631 "Expect things to break.\n");
1648 nextReady = std::min(nextReady,
1677 DPRINTF(CacheVerbose,
"Delaying pkt %s %llu ticks to allow "
1678 "for write coalescing\n", tgt_pkt->
print(), delay);
1702 pkt =
new Packet(tgt_pkt,
false,
true);
1737 bool pending_modified_resp = !pkt->
hasSharers() &&
1746 DPRINTF(CacheVerbose,
"%s: packet %s found block: %s\n",
1751 writebacks.push_back(wb_pkt);
1789 warn(
"*** The cache still contains dirty data. ***\n");
1790 warn(
" Make sure to drain the system using the correct flags.\n");
1791 warn(
" This checkpoint will not restore correctly " \
1792 "and dirty data in the cache will be lost!\n");
1799 bool bad_checkpoint(dirty);
1806 bool bad_checkpoint;
1808 if (bad_checkpoint) {
1809 fatal(
"Restoring from checkpoints with dirty caches is not "
1810 "supported in the classic memory system. Please remove any "
1811 "caches or drain them properly before taking checkpoints.\n");
1817 const std::string &
name)
1821 this, (
name +
"_hits").c_str(),
1822 (
"number of " +
name +
" hits").c_str()),
1824 this, (
name +
"_misses").c_str(),
1825 (
"number of " +
name +
" misses").c_str()),
1827 this, (
name +
"_miss_latency").c_str(),
1828 (
"number of " +
name +
" miss cycles").c_str()),
1830 this, (
name +
"_accesses").c_str(),
1831 (
"number of " +
name +
" accesses(hits+misses)").c_str()),
1833 this, (
name +
"_miss_rate").c_str(),
1834 (
"miss rate for " +
name +
" accesses").c_str()),
1836 this, (
name +
"_avg_miss_latency").c_str(),
1837 (
"average " +
name +
" miss latency").c_str()),
1839 this, (
name +
"_mshr_hits").c_str(),
1840 (
"number of " +
name +
" MSHR hits").c_str()),
1842 this, (
name +
"_mshr_misses").c_str(),
1843 (
"number of " +
name +
" MSHR misses").c_str()),
1845 this, (
name +
"_mshr_uncacheable").c_str(),
1846 (
"number of " +
name +
" MSHR uncacheable").c_str()),
1848 this, (
name +
"_mshr_miss_latency").c_str(),
1849 (
"number of " +
name +
" MSHR miss cycles").c_str()),
1850 mshr_uncacheable_lat(
1851 this, (
name +
"_mshr_uncacheable_latency").c_str(),
1852 (
"number of " +
name +
" MSHR uncacheable cycles").c_str()),
1854 this, (
name +
"_mshr_miss_rate").c_str(),
1855 (
"mshr miss rate for " +
name +
" accesses").c_str()),
1857 this, (
name +
"_avg_mshr_miss_latency").c_str(),
1858 (
"average " +
name +
" mshr miss latency").c_str()),
1859 avgMshrUncacheableLatency(
1860 this, (
name +
"_avg_mshr_uncacheable_latency").c_str(),
1861 (
"average " +
name +
" mshr uncacheable latency").c_str())
1868 using namespace Stats;
1875 .init(max_requestors)
1878 for (
int i = 0;
i < max_requestors;
i++) {
1884 .init(max_requestors)
1887 for (
int i = 0;
i < max_requestors;
i++) {
1893 .init(max_requestors)
1896 for (
int i = 0;
i < max_requestors;
i++) {
1902 accesses = hits + misses;
1903 for (
int i = 0;
i < max_requestors;
i++) {
1909 missRate = misses / accesses;
1910 for (
int i = 0;
i < max_requestors;
i++) {
1916 avgMissLatency = missLatency / misses;
1917 for (
int i = 0;
i < max_requestors;
i++) {
1924 .init(max_requestors)
1927 for (
int i = 0;
i < max_requestors;
i++) {
1933 .init(max_requestors)
1936 for (
int i = 0;
i < max_requestors;
i++) {
1942 .init(max_requestors)
1945 for (
int i = 0;
i < max_requestors;
i++) {
1951 .init(max_requestors)
1954 for (
int i = 0;
i < max_requestors;
i++) {
1959 mshr_uncacheable_lat
1960 .init(max_requestors)
1963 for (
int i = 0;
i < max_requestors;
i++) {
1969 mshrMissRate = mshr_misses / accesses;
1971 for (
int i = 0;
i < max_requestors;
i++) {
1977 avgMshrMissLatency = mshr_miss_latency / mshr_misses;
1978 for (
int i = 0;
i < max_requestors;
i++) {
1984 avgMshrUncacheableLatency = mshr_uncacheable_lat / mshr_uncacheable;
1985 for (
int i = 0;
i < max_requestors;
i++) {
1993 demandHits(this,
"demand_hits",
"number of demand (read+write) hits"),
1995 overallHits(this,
"overall_hits",
"number of overall hits"),
1996 demandMisses(this,
"demand_misses",
1997 "number of demand (read+write) misses"),
1998 overallMisses(this,
"overall_misses",
"number of overall misses"),
1999 demandMissLatency(this,
"demand_miss_latency",
2000 "number of demand (read+write) miss cycles"),
2001 overallMissLatency(this,
"overall_miss_latency",
2002 "number of overall miss cycles"),
2003 demandAccesses(this,
"demand_accesses",
2004 "number of demand (read+write) accesses"),
2005 overallAccesses(this,
"overall_accesses",
2006 "number of overall (read+write) accesses"),
2007 demandMissRate(this,
"demand_miss_rate",
2008 "miss rate for demand accesses"),
2009 overallMissRate(this,
"overall_miss_rate",
2010 "miss rate for overall accesses"),
2011 demandAvgMissLatency(this,
"demand_avg_miss_latency",
2012 "average overall miss latency"),
2013 overallAvgMissLatency(this,
"overall_avg_miss_latency",
2014 "average overall miss latency"),
2015 blocked_cycles(this,
"blocked_cycles",
2016 "number of cycles access was blocked"),
2017 blocked_causes(this,
"blocked",
"number of cycles access was blocked"),
2018 avg_blocked(this,
"avg_blocked_cycles",
2019 "average number of cycles each access was blocked"),
2020 unusedPrefetches(this,
"unused_prefetches",
2021 "number of HardPF blocks evicted w/o reference"),
2022 writebacks(this,
"writebacks",
"number of writebacks"),
2023 demandMshrHits(this,
"demand_mshr_hits",
2024 "number of demand (read+write) MSHR hits"),
2025 overallMshrHits(this,
"overall_mshr_hits",
2026 "number of overall MSHR hits"),
2027 demandMshrMisses(this,
"demand_mshr_misses",
2028 "number of demand (read+write) MSHR misses"),
2029 overallMshrMisses(this,
"overall_mshr_misses",
2030 "number of overall MSHR misses"),
2031 overallMshrUncacheable(this,
"overall_mshr_uncacheable_misses",
2032 "number of overall MSHR uncacheable misses"),
2033 demandMshrMissLatency(this,
"demand_mshr_miss_latency",
2034 "number of demand (read+write) MSHR miss cycles"),
2035 overallMshrMissLatency(this,
"overall_mshr_miss_latency",
2036 "number of overall MSHR miss cycles"),
2037 overallMshrUncacheableLatency(this,
"overall_mshr_uncacheable_latency",
2038 "number of overall MSHR uncacheable cycles"),
2039 demandMshrMissRate(this,
"demand_mshr_miss_rate",
2040 "mshr miss rate for demand accesses"),
2041 overallMshrMissRate(this,
"overall_mshr_miss_rate",
2042 "mshr miss rate for overall accesses"),
2043 demandAvgMshrMissLatency(this,
"demand_avg_mshr_miss_latency",
2044 "average overall mshr miss latency"),
2045 overallAvgMshrMissLatency(this,
"overall_avg_mshr_miss_latency",
2046 "average overall mshr miss latency"),
2047 overallAvgMshrUncacheableLatency(
2048 this,
"overall_avg_mshr_uncacheable_latency",
2049 "average overall mshr uncacheable latency"),
2050 replacements(this,
"replacements",
"number of replacements"),
2052 dataExpansions(this,
"data_expansions",
"number of data expansions"),
2053 cmd(
MemCmd::NUM_MEM_CMDS)
2062 using namespace Stats;
2069 for (
auto &cs : cmd)
2070 cs->regStatsFromParent();
2075 #define SUM_DEMAND(s) \
2076 (cmd[MemCmd::ReadReq]->s + cmd[MemCmd::WriteReq]->s + \
2077 cmd[MemCmd::WriteLineReq]->s + cmd[MemCmd::ReadExReq]->s + \
2078 cmd[MemCmd::ReadCleanReq]->s + cmd[MemCmd::ReadSharedReq]->s)
2081 #define SUM_NON_DEMAND(s) \
2082 (cmd[MemCmd::SoftPFReq]->s + cmd[MemCmd::HardPFReq]->s + \
2083 cmd[MemCmd::SoftPFExReq]->s)
2087 for (
int i = 0;
i < max_requestors;
i++) {
2093 for (
int i = 0;
i < max_requestors;
i++) {
2099 for (
int i = 0;
i < max_requestors;
i++) {
2105 for (
int i = 0;
i < max_requestors;
i++) {
2111 for (
int i = 0;
i < max_requestors;
i++) {
2116 overallMissLatency = demandMissLatency +
SUM_NON_DEMAND(missLatency);
2117 for (
int i = 0;
i < max_requestors;
i++) {
2122 demandAccesses = demandHits + demandMisses;
2123 for (
int i = 0;
i < max_requestors;
i++) {
2128 overallAccesses = overallHits + overallMisses;
2129 for (
int i = 0;
i < max_requestors;
i++) {
2134 demandMissRate = demandMisses / demandAccesses;
2135 for (
int i = 0;
i < max_requestors;
i++) {
2140 overallMissRate = overallMisses / overallAccesses;
2141 for (
int i = 0;
i < max_requestors;
i++) {
2146 demandAvgMissLatency = demandMissLatency / demandMisses;
2147 for (
int i = 0;
i < max_requestors;
i++) {
2152 overallAvgMissLatency = overallMissLatency / overallMisses;
2153 for (
int i = 0;
i < max_requestors;
i++) {
2174 avg_blocked = blocked_cycles / blocked_causes;
2176 unusedPrefetches.flags(
nozero);
2179 .init(max_requestors)
2182 for (
int i = 0;
i < max_requestors;
i++) {
2188 for (
int i = 0;
i < max_requestors;
i++) {
2194 for (
int i = 0;
i < max_requestors;
i++) {
2200 for (
int i = 0;
i < max_requestors;
i++) {
2205 overallMshrMisses = demandMshrMisses +
SUM_NON_DEMAND(mshr_misses);
2206 for (
int i = 0;
i < max_requestors;
i++) {
2211 demandMshrMissLatency =
SUM_DEMAND(mshr_miss_latency);
2212 for (
int i = 0;
i < max_requestors;
i++) {
2217 overallMshrMissLatency =
2219 for (
int i = 0;
i < max_requestors;
i++) {
2224 overallMshrUncacheable =
2226 for (
int i = 0;
i < max_requestors;
i++) {
2232 overallMshrUncacheableLatency =
2235 for (
int i = 0;
i < max_requestors;
i++) {
2240 demandMshrMissRate = demandMshrMisses / demandAccesses;
2241 for (
int i = 0;
i < max_requestors;
i++) {
2246 overallMshrMissRate = overallMshrMisses / overallAccesses;
2247 for (
int i = 0;
i < max_requestors;
i++) {
2252 demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses;
2253 for (
int i = 0;
i < max_requestors;
i++) {
2258 overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses;
2259 for (
int i = 0;
i < max_requestors;
i++) {
2264 overallAvgMshrUncacheableLatency =
2265 overallMshrUncacheableLatency / overallMshrUncacheable;
2266 for (
int i = 0;
i < max_requestors;
i++) {
2290 assert(!cache->system->bypassCaches());
2295 cache->recvTimingSnoopResp(pkt);
2306 }
else if (
blocked || mustSendRetry) {
2308 mustSendRetry =
true;
2311 mustSendRetry =
false;
2320 if (cache->system->bypassCaches()) {
2323 bool M5_VAR_USED success = cache->memSidePort.sendTimingReq(pkt);
2326 }
else if (tryTiming(pkt)) {
2327 cache->recvTimingReq(pkt);
2336 if (cache->system->bypassCaches()) {
2338 return cache->memSidePort.sendAtomic(pkt);
2340 return cache->recvAtomic(pkt);
2347 if (cache->system->bypassCaches()) {
2350 cache->memSidePort.sendFunctional(pkt);
2355 cache->functionalAccess(pkt,
true);
2361 return cache->getAddrRanges();
2367 const std::string &_label)
2380 cache->recvTimingResp(pkt);
2389 assert(!cache->system->bypassCaches());
2392 cache->recvTimingSnoopReq(pkt);
2399 assert(!cache->system->bypassCaches());
2401 return cache->recvAtomicSnoop(pkt);
2408 assert(!cache->system->bypassCaches());
2413 cache->functionalAccess(pkt,
false);
2420 assert(!waitingOnRetry);
2425 assert(deferredPacketReadyTime() ==
MaxTick);
2428 QueueEntry* entry = cache.getNextQueueEntry();
2447 if (!waitingOnRetry) {
2448 schedSendEvent(cache.nextQueueReadyTime());
2454 const std::string &_label)
2456 _reqQueue(*_cache, *this, _snoopRespQueue, _label),
2457 _snoopRespQueue(*_cache, *this, true, _label), cache(_cache)
2466 if (nextAddr == write_addr) {
2467 delayCtr[blk_addr] = delayThreshold;
2469 if (
mode != WriteMode::NO_ALLOCATE) {
2470 byteCount += write_size;
2473 if (
mode == WriteMode::ALLOCATE &&
2474 byteCount > coalesceLimit) {
2475 mode = WriteMode::COALESCE;
2477 }
else if (
mode == WriteMode::COALESCE &&
2478 byteCount > noAllocateLimit) {
2481 mode = WriteMode::NO_ALLOCATE;
2488 byteCount = write_size;
2489 mode = WriteMode::ALLOCATE;
2490 resetDelay(blk_addr);
2492 nextAddr = write_addr + write_size;
2496 WriteAllocatorParams::create()
void setBlocked(BlockedCause cause)
Marks the access path of the cache as blocked for the given cause.
#define fatal(...)
This implements a cprintf based fatal() function.
bool writeThrough() const
ProbePointArg< PacketPtr > * ppFill
To probe when a cache fill occurs.
Entry * getNext() const
Returns the WriteQueueEntry at the head of the readyList.
TempCacheBlk * tempBlock
Temporary cache block for occasional transitory use.
virtual void regStats()
Callback to set stat parameters.
bool isWritable() const
Checks the write permissions of this block.
bool scheduled() const
Determine if the current event is scheduled.
void makeAtomicResponse()
void clearBlocked(BlockedCause cause)
Marks the cache as unblocked for the given cause.
WriteQueue writeBuffer
Write/writeback buffer.
void maintainClusivity(bool from_cache, CacheBlk *blk)
Maintain the clusivity of this cache by potentially invalidating a block.
bool canCoAllocate(const std::size_t compressed_size) const
Checks whether a superblock can co-allocate given compressed data block.
Cycles calculateAccessLatency(const CacheBlk *blk, const uint32_t delay, const Cycles lookup_lat) const
Calculate access latency in ticks given a tag lookup latency, and whether access was a hit or miss.
void markInService(MSHR *mshr, bool pending_modified_resp)
Mark a request as in service (sent downstream in the memory system), effectively making this MSHR the...
virtual void sendDeferredPacket()
Override the normal sendDeferredPacket and do not only consider the transmit list (used for responses...
void makeTimingResponse()
EventFunctionWrapper sendRetryEvent
bool cacheResponding() const
Addr blkAddr
Block aligned address.
virtual void functionalAccess(PacketPtr pkt, bool from_cpu_side)
Performs the access specified by the request.
const bool sequentialAccess
Whether tags and data are accessed sequentially.
A queue entry is holding packets that will be serviced as soon as resources are available.
#define UNSERIALIZE_SCALAR(scalar)
CacheBlk * handleFill(PacketPtr pkt, CacheBlk *blk, PacketList &writebacks, bool allocate)
Handle a fill operation caused by a received packet.
void schedMemSideSendEvent(Tick time)
Schedule a send event for the memory-side port.
virtual Tick recvAtomic(PacketPtr pkt) override
Receive an atomic request packet from the peer.
void cmpAndSwap(CacheBlk *blk, PacketPtr pkt)
Handle doing the Compare and Swap function for SPARC.
void setCacheResponding()
Snoop flags.
void writeData(uint8_t *p) const
Copy data from the packet to the memory at the provided pointer.
Tick getWhenReady() const
Get tick at which block's data will be available for access.
bool isExpressSnoop() const
void clearBlocked()
Return to normal operation and accept new requests.
PacketPtr writebackBlk(CacheBlk *blk)
Create a writeback request for the given block.
A cache request port is used for the memory-side port of the cache, and in addition to the basic timi...
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
bool needsWritable() const
The pending* and post* flags are only valid if inService is true.
System * system
System we are currently operating in.
virtual void serviceMSHRTargets(MSHR *mshr, const PacketPtr pkt, CacheBlk *blk)=0
Service non-deferred MSHR targets using the received response.
int getNumTargets() const
Returns the current number of allocated targets.
virtual bool recvTimingReq(PacketPtr pkt) override
Receive a timing request from the peer.
Tick nextQueueReadyTime() const
Find next request ready time from among possible sources.
const unsigned blkSize
Block size of this cache.
void setHasSharers()
On fills, the hasSharers flag is used by the caches in combination with the cacheResponding flag,...
#define SUM_NON_DEMAND(s)
void setSatisfied()
Set when a request hits in a cache and the cache is not going to respond.
void markPending(MSHR *mshr)
Mark an in service entry as pending, used to resend a request.
ProbePointArg generates a point for the class of Arg.
MSHR * noTargetMSHR
Pointer to the MSHR that has no targets.
uint64_t Tick
Tick count type.
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
QueueEntry * getNextQueueEntry()
Return the next queue entry to service, either a pending miss from the MSHR queue,...
void pushLabel(const std::string &lbl)
Push label for PrintReq (safe to call unconditionally).
bool needsWritable() const
bool isInvalidate() const
std::shared_ptr< Request > RequestPtr
@ BlkDirty
dirty (modified)
RequestPtr req
A pointer to the original request.
EventFunctionWrapper writebackTempBlockAtomicEvent
An event to writeback the tempBlock after recvAtomic finishes.
void deschedule(Event &event)
const Tick recvTime
Time when request was received (for stats)
virtual void handleTimingReqHit(PacketPtr pkt, CacheBlk *blk, Tick request_time)
virtual void recvFunctionalSnoop(PacketPtr pkt)
Receive a functional snoop request packet from the peer.
unsigned State
block state: OR of CacheBlkStatusBit
uint32_t task_id
Task Id associated with this block.
void sendFunctional(PacketPtr pkt) const
Send a functional request packet, where the data is instantly updated everywhere in the memory system...
CacheBlk * allocateBlock(const PacketPtr pkt, PacketList &writebacks)
Allocate a new block and perform any necessary writebacks.
void schedTimingResp(PacketPtr pkt, Tick when)
Schedule the sending of a timing response.
const AddrRangeList addrRanges
The address range to which the cache responds on the CPU side.
const Enums::Clusivity clusivity
Clusivity with respect to the upstream cache, determining if we fill into both this cache and the cac...
void regStatsFromParent()
Callback to register stats from parent CacheStats::regStats().
static const Priority Delayed_Writeback_Pri
For some reason "delayed" inter-cluster writebacks are scheduled before regular writebacks (which hav...
const int numTarget
The number of targets for each MSHR.
MemSidePort(const std::string &_name, BaseCache *_cache, const std::string &_label)
void writeDataToBlock(uint8_t *blk_data, int blkSize) const
Copy data from the packet to the provided block pointer, which is aligned to the given block size.
void promoteWritable()
Promotes deferred targets that do not require writable.
void invalidateVisitor(CacheBlk &blk)
Cache block visitor that invalidates all blocks in the cache.
const Cycles forwardLatency
This is the forward latency of the cache.
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
bool coalesce() const
Checks if the cache is coalescing writes.
void print(std::ostream &o, int verbosity=0, const std::string &prefix="") const
ProbePointArg< PacketPtr > * ppMiss
To probe when a cache miss occurs.
void setData(const uint8_t *p)
Copy data into the packet from the provided pointer.
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
Stats::Scalar unusedPrefetches
The number of times a HW-prefetched block is evicted w/o reference.
Stats::Scalar replacements
Number of replacements of valid blocks.
const PacketPtr pkt
Pending request packet.
bool coalesce() const
Should writes be coalesced? This is true if the mode is set to NO_ALLOCATE.
virtual std::unique_ptr< CompressionData > compress(const std::vector< Chunk > &chunks, Cycles &comp_lat, Cycles &decomp_lat)=0
Apply the compression process to the cache line.
bool isPendingModified() const
void setBlocked()
Do not accept any new requests.
virtual bool sendPacket(BaseCache &cache)=0
Send this queue entry as a downstream packet, with the exact behaviour depending on the specific entr...
Prefetcher::Base * prefetcher
Prefetcher.
Stats::Vector writebacks
Number of blocks written back per thread.
std::size_t getSizeBits() const
bool isSecure
True if the entry targets the secure memory space.
static void setDecompressionLatency(CacheBlk *blk, const Cycles lat)
Set the decompression latency of compressed block.
std::vector< SectorSubBlk * > blks
List of blocks associated to this sector.
void incMissCount(PacketPtr pkt)
void schedule(Event &event, Tick when)
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
void allocateWriteBuffer(PacketPtr pkt, Tick time)
Tick cyclesToTicks(Cycles c) const
bool promoteDeferredTargets()
@ SECURE
The request targets the secure memory space.
MSHRQueue mshrQueue
Miss status registers.
void setWriteThrough()
A writeback/writeclean cmd gets propagated further downstream by the receiver when the flag is set.
CacheResponsePort(const std::string &_name, BaseCache *_cache, const std::string &_label)
Addr regenerateBlkAddr(CacheBlk *blk)
Regenerate block address using tags.
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
bool isDirty() const
Check to see if a block has been written.
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
bool delay(Addr blk_addr)
Access whether we need to delay the current write.
bool allocOnFill(MemCmd cmd) const
Determine whether we should allocate on a fill or not.
BaseCache::CacheStats stats
std::unique_ptr< Packet > pendingDelete
Upstream caches need this packet until true is returned, so hold it for deletion until a subsequent c...
Addr getBlockAddr(unsigned int blk_size) const
uint8_t blocked
Bit vector of the blocking reasons for the access path.
void invalidateBlock(CacheBlk *blk)
Invalidate a cache block.
@ wbRequestorId
This requestor id is used for writeback requests by the caches.
bool updateCompressionData(CacheBlk *blk, const uint64_t *data, PacketList &writebacks)
When a block is overwriten, its compression information must be updated, and it may need to be recomp...
void serialize(CheckpointOut &cp) const override
Serialize the state of the caches.
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
void delay(MSHR *mshr, Tick delay_ticks)
Adds a delay to the provided MSHR and moves MSHRs that will be ready earlier than this entry to the t...
Stats::Vector mshr_uncacheable_lat
Total cycle latency of each MSHR miss, per command and thread.
void handleUncacheableWriteResp(PacketPtr pkt)
Handling the special case of uncacheable write responses to make recvTimingResp less cluttered.
Ports are used to interface objects to each other.
bool needsResponse() const
virtual void recvTimingReq(PacketPtr pkt)
Performs the access specified by the request.
Cycles getDecompressionLatency(const CacheBlk *blk)
Get the decompression latency if the block is compressed.
CacheCmdStats(BaseCache &c, const std::string &name)
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...
AtomicOpFunctor * getAtomicOp() const
Accessor function to atomic op.
State status
The current status of this block.
void setDataFromBlock(const uint8_t *blk_data, int blkSize)
Copy data into the packet from the provided block pointer, which is aligned to the given block size.
virtual Cycles handleAtomicReqMiss(PacketPtr pkt, CacheBlk *&blk, PacketList &writebacks)=0
Handle a request in atomic mode that missed in this cache.
virtual Target * getTarget()=0
Returns a pointer to the first target.
const Cycles fillLatency
The latency to fill a cache block.
bool forwardSnoops
Do we forward snoops from mem side port through to cpu side port?
#define chatty_assert(cond,...)
The chatty assert macro will function like a normal assert, but will allow the specification of addit...
void regProbePoints() override
Registers probes.
void deallocate(Entry *entry)
Removes the given entry from the queue.
BaseCache(const BaseCacheParams *p, unsigned blk_size)
bool isSnooping() const
Find out if the peer request port is snooping or not.
virtual Tick recvAtomicSnoop(PacketPtr pkt)
Receive an atomic snoop request packet from our peer.
PacketPtr writecleanBlk(CacheBlk *blk, Request::Flags dest, PacketId id)
Create a writeclean request for the given block.
virtual bool access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat, PacketList &writebacks)
Does all the processing necessary to perform the provided request.
const bool isReadOnly
Is this cache read only, for example the instruction cache, or table-walker cache.
Addr getOffset(unsigned int blk_size) const
A queued port is a port that has an infinite queue for outgoing packets and thus decouples the module...
virtual bool sendMSHRQueuePacket(MSHR *mshr)
Take an MSHR, turn it into a suitable downstream packet, and send it out.
bool isBlocked() const
Returns true if the cache is blocked for accesses.
virtual void doWritebacksAtomic(PacketList &writebacks)=0
Send writebacks down the memory hierarchy in atomic mode.
std::string print() const override
Pretty-print tag, set and way, and interpret state bits to readable form including mapping to a MOESI...
Entry * findMatch(Addr blk_addr, bool is_secure, bool ignore_uncacheable=true) const
Find the first entry that matches the provided address.
int getNumTargets() const
Returns the current number of allocated targets.
void writebackVisitor(CacheBlk &blk)
Cache block visitor that writes back dirty cache blocks using functional writes.
virtual AddrRangeList getAddrRanges() const override
Get a list of the non-overlapping address ranges the owner is responsible for.
Simple class to provide virtual print() method on cache blocks without allocating a vtable pointer fo...
const Cycles lookupLatency
The latency of tag lookup of a cache.
bool isReadable() const
Checks the read permissions of this block.
MSHR * allocateMissBuffer(PacketPtr pkt, Tick time, bool sched_send=true)
bool checkWrite(PacketPtr pkt)
Handle interaction of load-locked operations and stores.
@ BlkHWPrefetched
block was a hardware prefetch yet unaccessed
Cycles calculateTagOnlyLatency(const uint32_t delay, const Cycles lookup_lat) const
Calculate latency of accesses that only touch the tag array.
bool canPrefetch() const
Returns true if sufficient mshrs for prefetch.
Target * getTarget() override
Returns a reference to the first target.
ProbePointArg< PacketInfo > Packet
Packet probe point.
bool isCompressed() const
Check if this block holds compressed data.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
virtual PacketPtr createMissPacket(PacketPtr cpu_pkt, CacheBlk *blk, bool needs_writable, bool is_whole_line_write) const =0
Create an appropriate downstream bus request packet.
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
virtual void satisfyRequest(PacketPtr pkt, CacheBlk *blk, bool deferred_response=false, bool pending_downgrade=false)
Perform any necessary updates to the block and perform any data exchange between the packet and the b...
@ BlkReadable
read permission (yes, block can be valid but not readable)
virtual Tick nextPrefetchReadyTime() const =0
bool wasPrefetched() const
Check if this block was the result of a hardware prefetch, yet to be touched.
void insert(const Addr addr, const bool is_secure, const int src_requestor_ID=0, const uint32_t task_ID=0) override
Set member variables when a block insertion occurs.
const std::string & name()
#define SERIALIZE_SCALAR(scalar)
Counter order
Order number assigned to disambiguate writes and misses.
bool trySatisfyFunctional(PacketPtr pkt)
Check the list of buffered packets against the supplied functional request.
const FlagsType nozero
Don't print if this is zero.
ProbeManager * getProbeManager()
Get the probe manager for this object.
void setDecompressionLatency(const Cycles lat)
Set number of cycles needed to decompress this block.
QueueEntry::Target * getTarget() override
Returns a reference to the first target.
Compressor::Base * compressor
Compression method being used.
bool isCleanEviction() const
Is this packet a clean eviction, including both actual clean evict packets, but also clean writebacks...
virtual void doWritebacks(PacketList &writebacks, Tick forward_time)=0
Insert writebacks into the write buffer.
const bool writebackClean
Determine if clean lines should be written back or not.
@ funcRequestorId
This requestor id is used for functional requests that don't come from a particular device.
void setWhenReady(const Tick tick)
Set tick at which block's data will be available for access.
void setCompressed()
Set compression bit.
void setUncompressed()
Clear compression bit.
virtual const std::string name() const
MemCmd cmd
The command field of the packet.
virtual bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
BaseTags * tags
Tag and data Storage.
bool wasWholeLineWrite
Track if we sent this as a whole line write or not.
bool inService
True if the entry has been sent downstream.
Copyright (c) 2018 Inria All rights reserved.
bool isValid() const
Checks that a block is valid.
void allocateTarget(PacketPtr target, Tick when, Counter order, bool alloc_on_fill)
Add a request to the list of targets.
Entry * findPending(const QueueEntry *entry) const
Find any pending requests that overlap the given request of a different queue.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
virtual M5_NODISCARD PacketPtr evictBlock(CacheBlk *blk)=0
Evict a cache block.
void pushSenderState(SenderState *sender_state)
Push a new sender state to the packet and make the current sender state the predecessor of the new on...
@ BlkWritable
write permission
Stats::Vector mshr_misses
Number of misses that miss in the MSHRs, per command and thread.
uint8_t * data
Contains a copy of the data in this block for easy access.
bool sendWriteQueuePacket(WriteQueueEntry *wq_entry)
Similar to sendMSHR, but for a write-queue entry instead.
A basic compression superblock.
void setSizeBits(const std::size_t size)
Set size, in bits, of this compressed block's data.
void resetDelay(Addr blk_addr)
Clear delay counter for the input block.
RequestorID maxRequestors()
Get the number of requestors registered in the system.
Overload hash function for BasicBlockRange type.
bool isCompressed(const CompressionBlk *ignored_blk=nullptr) const
Returns whether the superblock contains compressed blocks or not.
Cycles ticksToCycles(Tick t) const
Stats::Scalar dataExpansions
Number of data expansions.
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
void trackLoadLocked(PacketPtr pkt)
Track the fact that a local locked was issued to the block.
virtual void handleTimingReqMiss(PacketPtr pkt, CacheBlk *blk, Tick forward_time, Tick request_time)=0
virtual bool recvTimingSnoopResp(PacketPtr pkt) override
Receive a timing snoop response from the peer.
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
WriteAllocator *const writeAllocator
The writeAllocator drive optimizations for streaming writes.
SenderState * popSenderState()
Pop the top of the state stack and return a pointer to it.
void reset()
Reset the write allocator state, meaning that it allocates for writes and has not recorded any inform...
const SectorBlk * getSectorBlock() const
Get sector block associated to this block.
void sendFunctionalSnoop(PacketPtr pkt) const
Send a functional snoop request packet, where the data is instantly updated everywhere in the memory ...
bool isConnected() const
Is this port currently connected to a peer?
bool allocate() const
Should writes allocate?
void unserialize(CheckpointIn &cp) override
Unserialize an object.
const Cycles dataLatency
The latency of data access of a cache.
Cycles is a wrapper class for representing cycle counts, i.e.
bool handleEvictions(std::vector< CacheBlk * > &evict_blks, PacketList &writebacks)
Try to evict the given blocks.
Stats::Vector mshr_miss_latency
Total cycle latency of each MSHR miss, per command and thread.
Tick nextReadyTime() const
bool isDirty() const
Determine if there are any dirty blocks in the cache.
virtual PacketPtr getPacket()=0
std::ostream CheckpointOut
std::vector< std::unique_ptr< CacheCmdStats > > cmd
Per-command statistics.
A queue entry base class, to be used by both the MSHRs and write-queue entries.
std::string getRequestorName(RequestorID requestor_id)
Get the name of an object for a given request id.
void writebackTempBlockAtomic()
Send the outstanding tempBlock writeback.
bool trySatisfyFunctional(PacketPtr pkt)
Check the list of buffered packets against the supplied functional request.
void invalidate() override
Invalidate the block and clear all state.
void updateMode(Addr write_addr, unsigned write_size, Addr blk_addr)
Update the write mode based on the current write packet.
Stats::Vector mshr_hits
Number of misses that hit in the MSHRs per command and thread.
const Cycles responseLatency
The latency of sending reponse to its upper level cache/core on a linefill.
virtual void memWriteback() override
Write back dirty blocks in the cache using functional accesses.
void incHitCount(PacketPtr pkt)
virtual void recvTimingResp(PacketPtr pkt)
Handles a response (cache line fill/write ack) from the bus.
bool isWholeLineWrite() const
Check if this MSHR contains only compatible writes, and if they span the entire cache line.
Special instance of CacheBlk for use with tempBlk that deals with its block address regeneration.
bool isForward
True if the entry is just a simple forward from an upper level.
void allocate()
Allocate memory for the packet.
A coherent cache that can be arranged in flexible topologies.
virtual bool tryTiming(PacketPtr pkt) override
Availability request from the peer.
virtual Tick recvAtomic(PacketPtr pkt)
Performs the access specified by the request.
const FlagsType total
Print the total.
void sendRangeChange() const
Called by the owner to send a range change.
bool trySatisfyFunctional(PacketPtr other)
Check a functional request against a memory value stored in another packet (i.e.
void promoteReadable()
Promotes deferred targets that do not require writable.
void regStats() override
Callback to set stat parameters.
static void setSizeBits(CacheBlk *blk, const std::size_t size_bits)
Set the size of the compressed block, in bits.
PacketPtr tempBlockWriteback
Writebacks from the tempBlock, resulting on the response path in atomic mode, must happen after the c...
const T * getConstPtr() const
A superblock is composed of sub-blocks, and each sub-block has information regarding its superblock a...
CacheCmdStats & cmdStats(const PacketPtr p)
virtual void memInvalidate() override
Invalidates all blocks in the cache.
CpuSidePort(const std::string &_name, BaseCache *_cache, const std::string &_label)
virtual void recvFunctional(PacketPtr pkt) override
Receive a functional request packet from the peer.
bool inRange(Addr addr) const
Determine if an address is in the ranges covered by this cache.
ProbePointArg< PacketPtr > * ppHit
To probe when a cache hit occurs.
bool trySatisfyFunctional(PacketPtr pkt)
bool isSecure() const
Check if this block holds data from the secure memory space.
const FlagsType nonan
Don't print if this is NAN.
virtual void recvTimingSnoopReq(PacketPtr pkt)
Receive a timing snoop request from the peer.
void popLabel()
Pop label for PrintReq (safe to call unconditionally).
The write allocator inspects write packets and detects streaming patterns.
#define panic(...)
This implements a cprintf based panic() function.
A cache response port is used for the CPU-side port of the cache, and it is basically a simple timing...
Miss Status and handling Register.
Tick curTick()
The current simulated tick.
Addr getAddr() const
Get block's address.
uint64_t order
Increasing order number assigned to each incoming request.
Generated on Wed Sep 30 2020 14:02:08 for gem5 by doxygen 1.8.17