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"
55 #include "debug/HWPrefetch.hh"
62 #include "params/BaseCache.hh"
63 #include "params/WriteAllocator.hh"
71 const std::string &_label)
73 queue(*_cache, *this, true, _label),
74 blocked(false), mustSendRetry(false),
95 lookupLatency(
p.tag_latency),
96 dataLatency(
p.data_latency),
97 forwardLatency(
p.tag_latency),
98 fillLatency(
p.data_latency),
99 responseLatency(
p.response_latency),
100 sequentialAccess(
p.sequential_access),
101 numTarget(
p.tgts_per_mshr),
103 clusivity(
p.clusivity),
104 isReadOnly(
p.is_read_only),
105 replaceExpansions(
p.replace_expansions),
106 moveContractions(
p.move_contractions),
109 noTargetMSHR(
nullptr),
110 missCount(
p.max_miss_count),
111 addrRanges(
p.addr_ranges.begin(),
p.addr_ranges.end()),
128 prefetcher->setCache(
this);
131 "The tags of compressed cache %s must derive from CompressedTags",
134 "Compressed cache %s does not have a compression algorithm",
name());
136 compressor->setCache(
this);
148 DPRINTF(CachePort,
"Port is blocking new requests\n");
154 DPRINTF(CachePort,
"Port descheduled retry\n");
163 DPRINTF(CachePort,
"Port is accepting new requests\n");
167 owner.schedule(sendRetryEvent,
curTick() + 1);
174 DPRINTF(CachePort,
"Port is sending retry\n");
177 mustSendRetry =
false;
195 fatal(
"Cache ports on %s are not connected\n",
name());
203 if (if_name ==
"mem_side") {
205 }
else if (if_name ==
"cpu_side") {
216 if (
r.contains(
addr)) {
240 DPRINTF(
Cache,
"%s satisfied %s, no response needed\n", __func__,
253 Tick forward_time,
Tick request_time)
256 pkt && pkt->
isWrite() && !pkt->
req->isUncacheable()) {
338 pkt->
req->isCacheMaintenance());
358 bool satisfied =
false;
363 satisfied =
access(pkt, blk, lat, writebacks);
427 "%s saw a non-zero packet delay\n",
name());
429 const bool is_error = pkt->
isError();
432 DPRINTF(
Cache,
"%s: Cache received %s with error\n", __func__,
442 assert(pkt->
req->isUncacheable());
461 if (pkt->
req->isUncacheable()) {
483 if (is_fill && !is_error) {
484 DPRINTF(
Cache,
"Block for addr %#llx being updated in Cache\n",
489 blk =
handleFill(pkt, blk, writebacks, allocate);
490 assert(blk !=
nullptr);
507 !pkt->
req->isCacheInvalidate()) {
553 DPRINTF(CacheVerbose,
"%s: Leaving with %s\n", __func__, pkt->
print());
571 bool satisfied =
access(pkt, blk, lat, writebacks);
578 DPRINTF(CacheVerbose,
"%s: packet %s found block: %s\n",
581 writebacks.push_back(wb_pkt);
588 assert(writebacks.empty());
656 bool have_data = blk && blk->
isValid()
666 bool done = have_dirty ||
672 DPRINTF(CacheVerbose,
"%s: %s %s%s%s\n", __func__, pkt->
print(),
673 (blk && blk->
isValid()) ?
"valid " :
"",
674 have_data ?
"data " :
"", done ?
"done " :
"");
725 uint64_t overwrite_val;
727 uint64_t condition_val64;
728 uint32_t condition_val32;
733 assert(
sizeof(uint64_t) >= pkt->
getSize());
742 overwrite_mem =
true;
745 pkt->
writeData((uint8_t *)&overwrite_val);
748 if (pkt->
req->isCondSwap()) {
749 if (pkt->
getSize() ==
sizeof(uint64_t)) {
750 condition_val64 = pkt->
req->getExtraData();
751 overwrite_mem = !std::memcmp(&condition_val64, blk_data,
753 }
else if (pkt->
getSize() ==
sizeof(uint32_t)) {
754 condition_val32 = (uint32_t)pkt->
req->getExtraData();
755 overwrite_mem = !std::memcmp(&condition_val32, blk_data,
758 panic(
"Invalid size for conditional read/write\n");
762 std::memcpy(blk_data, &overwrite_val, pkt->
getSize());
788 if (conflict_mshr && conflict_mshr->
order < wq_entry->
order) {
790 return conflict_mshr;
797 }
else if (miss_mshr) {
813 return conflict_mshr;
823 assert(!miss_mshr && !wq_entry);
830 DPRINTF(HWPrefetch,
"Prefetch %#x has hit in cache, "
831 "dropped.\n", pf_addr);
836 DPRINTF(HWPrefetch,
"Prefetch %#x has hit in a MSHR, "
837 "dropped.\n", pf_addr);
842 DPRINTF(HWPrefetch,
"Prefetch %#x has hit in the "
843 "Write Buffer, dropped.\n", pf_addr);
868 bool replacement =
false;
869 for (
const auto& blk : evict_blks) {
870 if (blk->isValid()) {
891 for (
auto& blk : evict_blks) {
892 if (blk->isValid()) {
914 const auto comp_data =
916 std::size_t compression_size = comp_data->getSizeBits();
920 [[maybe_unused]]
const std::size_t prev_size =
927 bool is_data_expansion =
false;
928 bool is_data_contraction =
false;
931 std::string op_name =
"";
933 op_name =
"expansion";
934 is_data_expansion =
true;
937 op_name =
"contraction";
938 is_data_contraction =
true;
945 if (is_data_expansion || is_data_contraction) {
947 bool victim_itself =
false;
951 blk->
isSecure(), compression_size, evict_blks);
961 victim_itself =
true;
962 auto it = std::find_if(evict_blks.begin(), evict_blks.end(),
963 [&blk](
CacheBlk* evict_blk){ return evict_blk == blk; });
964 evict_blks.erase(it);
968 DPRINTF(CacheRepl,
"Data %s replacement victim: %s\n",
969 op_name, victim->
print());
975 for (
auto& sub_blk : superblock->
blks) {
976 if (sub_blk->isValid() && (blk != sub_blk)) {
977 evict_blks.push_back(sub_blk);
987 DPRINTF(CacheComp,
"Data %s: [%s] from %d to %d bits\n",
988 op_name, blk->
print(), prev_size, compression_size);
1000 if (is_data_expansion) {
1002 }
else if (is_data_contraction) {
1017 assert(blk && blk->
isValid());
1075 DPRINTF(CacheVerbose,
"%s for %s (write)\n", __func__, pkt->
print());
1076 }
else if (pkt->
isRead()) {
1100 DPRINTF(CacheVerbose,
"%s for %s (invalidation)\n", __func__,
1112 const Cycles lookup_lat)
const
1121 const Cycles lookup_lat)
const
1125 if (blk !=
nullptr) {
1139 if (when_ready >
tick &&
1161 "Should never see a write in a read-only cache %s\n",
1169 blk ?
"hit " + blk->
print() :
"miss");
1171 if (pkt->
req->isCacheMaintenance()) {
1244 DPRINTF(
Cache,
"Clean writeback %#llx to block with MSHR, "
1245 "dropping\n", pkt->
getAddr());
1255 const bool has_old_data = blk && blk->
isValid();
1327 const bool has_old_data = blk && blk->
isValid();
1415 pkt->
req->setExtraData(0);
1425 if (from_cache && blk && blk->
isValid() &&
1441 const bool has_old_data = blk && blk->
isValid();
1442 const std::string old_state = (debug::Cache && blk) ? blk->
print() :
"";
1463 is_secure ?
"s" :
"ns");
1473 assert(blk->
isSecure() == is_secure);
1506 "in read-only cache %s\n",
name());
1511 DPRINTF(
Cache,
"Block addr %#llx (%s) moving from %s to %s\n",
1512 addr, is_secure ?
"s" :
"ns", old_state, blk->
print());
1537 const bool is_secure = pkt->
isSecure();
1542 std::size_t blk_size_bits =
blkSize*8;
1553 pkt->
getConstPtr<uint64_t>(), compression_lat, decompression_lat);
1554 blk_size_bits = comp_data->getSizeBits();
1567 DPRINTF(CacheRepl,
"Replacement victim: %s\n", victim->
print());
1612 writebacks.push_back(pkt);
1620 "Writeback from read-only cache");
1621 assert(blk && blk->
isValid() &&
1638 DPRINTF(
Cache,
"Create Writeback %s writable: %d, dirty: %d\n",
1680 req->setFlags(dest);
1743 RequestPtr request = std::make_shared<Request>(
1764 warn_once(
"Invalidating dirty cache lines. " \
1765 "Expect things to break.\n");
1782 nextReady = std::min(nextReady,
1811 DPRINTF(CacheVerbose,
"Delaying pkt %s %llu ticks to allow "
1812 "for write coalescing\n", tgt_pkt->
print(), delay);
1836 pkt =
new Packet(tgt_pkt,
false,
true);
1871 bool pending_modified_resp = !pkt->
hasSharers() &&
1880 DPRINTF(CacheVerbose,
"%s: packet %s found block: %s\n",
1885 writebacks.push_back(wb_pkt);
1923 warn(
"*** The cache still contains dirty data. ***\n");
1924 warn(
" Make sure to drain the system using the correct flags.\n");
1925 warn(
" This checkpoint will not restore correctly " \
1926 "and dirty data in the cache will be lost!\n");
1933 bool bad_checkpoint(dirty);
1940 bool bad_checkpoint;
1942 if (bad_checkpoint) {
1943 fatal(
"Restoring from checkpoints with dirty caches is not "
1944 "supported in the classic memory system. Please remove any "
1945 "caches or drain them properly before taking checkpoints.\n");
1951 const std::string &
name)
1953 ADD_STAT(hits, statistics::units::Count::get(),
1954 (
"number of " +
name +
" hits").c_str()),
1955 ADD_STAT(misses, statistics::units::Count::get(),
1956 (
"number of " +
name +
" misses").c_str()),
1958 (
"number of " +
name +
" hit ticks").c_str()),
1960 (
"number of " +
name +
" miss ticks").c_str()),
1961 ADD_STAT(accesses, statistics::units::Count::get(),
1962 (
"number of " +
name +
" accesses(hits+misses)").c_str()),
1963 ADD_STAT(missRate, statistics::units::Ratio::get(),
1964 (
"miss rate for " +
name +
" accesses").c_str()),
1965 ADD_STAT(avgMissLatency, statistics::units::Rate<
1966 statistics::units::
Tick, statistics::units::Count>::get(),
1967 (
"average " +
name +
" miss latency").c_str()),
1968 ADD_STAT(mshrHits, statistics::units::Count::get(),
1969 (
"number of " +
name +
" MSHR hits").c_str()),
1970 ADD_STAT(mshrMisses, statistics::units::Count::get(),
1971 (
"number of " +
name +
" MSHR misses").c_str()),
1972 ADD_STAT(mshrUncacheable, statistics::units::Count::get(),
1973 (
"number of " +
name +
" MSHR uncacheable").c_str()),
1974 ADD_STAT(mshrMissLatency, statistics::units::
Tick::get(),
1975 (
"number of " +
name +
" MSHR miss ticks").c_str()),
1976 ADD_STAT(mshrUncacheableLatency, statistics::units::
Tick::get(),
1977 (
"number of " +
name +
" MSHR uncacheable ticks").c_str()),
1978 ADD_STAT(mshrMissRate, statistics::units::Ratio::get(),
1979 (
"mshr miss rate for " +
name +
" accesses").c_str()),
1980 ADD_STAT(avgMshrMissLatency, statistics::units::Rate<
1981 statistics::units::
Tick, statistics::units::Count>::get(),
1982 (
"average " +
name +
" mshr miss latency").c_str()),
1983 ADD_STAT(avgMshrUncacheableLatency, statistics::units::Rate<
1984 statistics::units::
Tick, statistics::units::Count>::get(),
1985 (
"average " +
name +
" mshr uncacheable latency").c_str())
1992 using namespace statistics;
1999 .init(max_requestors)
2002 for (
int i = 0;
i < max_requestors;
i++) {
2008 .init(max_requestors)
2011 for (
int i = 0;
i < max_requestors;
i++) {
2017 .init(max_requestors)
2020 for (
int i = 0;
i < max_requestors;
i++) {
2026 .init(max_requestors)
2029 for (
int i = 0;
i < max_requestors;
i++) {
2035 accesses = hits + misses;
2036 for (
int i = 0;
i < max_requestors;
i++) {
2042 missRate = misses / accesses;
2043 for (
int i = 0;
i < max_requestors;
i++) {
2049 avgMissLatency = missLatency / misses;
2050 for (
int i = 0;
i < max_requestors;
i++) {
2057 .init(max_requestors)
2060 for (
int i = 0;
i < max_requestors;
i++) {
2066 .init(max_requestors)
2069 for (
int i = 0;
i < max_requestors;
i++) {
2075 .init(max_requestors)
2078 for (
int i = 0;
i < max_requestors;
i++) {
2084 .init(max_requestors)
2087 for (
int i = 0;
i < max_requestors;
i++) {
2092 mshrUncacheableLatency
2093 .init(max_requestors)
2096 for (
int i = 0;
i < max_requestors;
i++) {
2102 mshrMissRate = mshrMisses / accesses;
2104 for (
int i = 0;
i < max_requestors;
i++) {
2110 avgMshrMissLatency = mshrMissLatency / mshrMisses;
2111 for (
int i = 0;
i < max_requestors;
i++) {
2117 avgMshrUncacheableLatency = mshrUncacheableLatency / mshrUncacheable;
2118 for (
int i = 0;
i < max_requestors;
i++) {
2124 : statistics::
Group(&
c), cache(
c),
2126 ADD_STAT(demandHits, statistics::units::Count::get(),
2127 "number of demand (read+write) hits"),
2128 ADD_STAT(overallHits, statistics::units::Count::get(),
2129 "number of overall hits"),
2130 ADD_STAT(demandHitLatency, statistics::units::
Tick::get(),
2131 "number of demand (read+write) hit ticks"),
2132 ADD_STAT(overallHitLatency, statistics::units::
Tick::get(),
2133 "number of overall hit ticks"),
2134 ADD_STAT(demandMisses, statistics::units::Count::get(),
2135 "number of demand (read+write) misses"),
2136 ADD_STAT(overallMisses, statistics::units::Count::get(),
2137 "number of overall misses"),
2138 ADD_STAT(demandMissLatency, statistics::units::
Tick::get(),
2139 "number of demand (read+write) miss ticks"),
2140 ADD_STAT(overallMissLatency, statistics::units::
Tick::get(),
2141 "number of overall miss ticks"),
2142 ADD_STAT(demandAccesses, statistics::units::Count::get(),
2143 "number of demand (read+write) accesses"),
2144 ADD_STAT(overallAccesses, statistics::units::Count::get(),
2145 "number of overall (read+write) accesses"),
2146 ADD_STAT(demandMissRate, statistics::units::Ratio::get(),
2147 "miss rate for demand accesses"),
2148 ADD_STAT(overallMissRate, statistics::units::Ratio::get(),
2149 "miss rate for overall accesses"),
2150 ADD_STAT(demandAvgMissLatency, statistics::units::Rate<
2151 statistics::units::Cycle, statistics::units::Count>::get(),
2152 "average overall miss latency"),
2153 ADD_STAT(overallAvgMissLatency, statistics::units::Rate<
2154 statistics::units::Cycle, statistics::units::Count>::get(),
2155 "average overall miss latency"),
2156 ADD_STAT(blockedCycles, statistics::units::Cycle::get(),
2157 "number of cycles access was blocked"),
2158 ADD_STAT(blockedCauses, statistics::units::Count::get(),
2159 "number of times access was blocked"),
2160 ADD_STAT(avgBlocked, statistics::units::Rate<
2161 statistics::units::Cycle, statistics::units::Count>::get(),
2162 "average number of cycles each access was blocked"),
2163 ADD_STAT(writebacks, statistics::units::Count::get(),
2164 "number of writebacks"),
2165 ADD_STAT(demandMshrHits, statistics::units::Count::get(),
2166 "number of demand (read+write) MSHR hits"),
2167 ADD_STAT(overallMshrHits, statistics::units::Count::get(),
2168 "number of overall MSHR hits"),
2169 ADD_STAT(demandMshrMisses, statistics::units::Count::get(),
2170 "number of demand (read+write) MSHR misses"),
2171 ADD_STAT(overallMshrMisses, statistics::units::Count::get(),
2172 "number of overall MSHR misses"),
2173 ADD_STAT(overallMshrUncacheable, statistics::units::Count::get(),
2174 "number of overall MSHR uncacheable misses"),
2175 ADD_STAT(demandMshrMissLatency, statistics::units::
Tick::get(),
2176 "number of demand (read+write) MSHR miss ticks"),
2177 ADD_STAT(overallMshrMissLatency, statistics::units::
Tick::get(),
2178 "number of overall MSHR miss ticks"),
2179 ADD_STAT(overallMshrUncacheableLatency, statistics::units::
Tick::get(),
2180 "number of overall MSHR uncacheable ticks"),
2181 ADD_STAT(demandMshrMissRate, statistics::units::Ratio::get(),
2182 "mshr miss ratio for demand accesses"),
2183 ADD_STAT(overallMshrMissRate, statistics::units::Ratio::get(),
2184 "mshr miss ratio for overall accesses"),
2185 ADD_STAT(demandAvgMshrMissLatency, statistics::units::Rate<
2186 statistics::units::Cycle, statistics::units::Count>::get(),
2187 "average overall mshr miss latency"),
2188 ADD_STAT(overallAvgMshrMissLatency, statistics::units::Rate<
2189 statistics::units::Cycle, statistics::units::Count>::get(),
2190 "average overall mshr miss latency"),
2191 ADD_STAT(overallAvgMshrUncacheableLatency, statistics::units::Rate<
2192 statistics::units::Cycle, statistics::units::Count>::get(),
2193 "average overall mshr uncacheable latency"),
2194 ADD_STAT(replacements, statistics::units::Count::get(),
2195 "number of replacements"),
2196 ADD_STAT(dataExpansions, statistics::units::Count::get(),
2197 "number of data expansions"),
2198 ADD_STAT(dataContractions, statistics::units::Count::get(),
2199 "number of data contractions"),
2200 cmd(
MemCmd::NUM_MEM_CMDS)
2209 using namespace statistics;
2216 for (
auto &cs : cmd)
2217 cs->regStatsFromParent();
2222 #define SUM_DEMAND(s) \
2223 (cmd[MemCmd::ReadReq]->s + cmd[MemCmd::WriteReq]->s + \
2224 cmd[MemCmd::WriteLineReq]->s + cmd[MemCmd::ReadExReq]->s + \
2225 cmd[MemCmd::ReadCleanReq]->s + cmd[MemCmd::ReadSharedReq]->s)
2228 #define SUM_NON_DEMAND(s) \
2229 (cmd[MemCmd::SoftPFReq]->s + cmd[MemCmd::HardPFReq]->s + \
2230 cmd[MemCmd::SoftPFExReq]->s)
2234 for (
int i = 0;
i < max_requestors;
i++) {
2240 for (
int i = 0;
i < max_requestors;
i++) {
2246 for (
int i = 0;
i < max_requestors;
i++) {
2252 for (
int i = 0;
i < max_requestors;
i++) {
2258 for (
int i = 0;
i < max_requestors;
i++) {
2263 overallMissLatency = demandMissLatency +
SUM_NON_DEMAND(missLatency);
2264 for (
int i = 0;
i < max_requestors;
i++) {
2270 for (
int i = 0;
i < max_requestors;
i++) {
2274 overallHitLatency = demandHitLatency +
SUM_NON_DEMAND(hitLatency);
2275 for (
int i = 0;
i < max_requestors;
i++) {
2280 demandAccesses = demandHits + demandMisses;
2281 for (
int i = 0;
i < max_requestors;
i++) {
2286 overallAccesses = overallHits + overallMisses;
2287 for (
int i = 0;
i < max_requestors;
i++) {
2292 demandMissRate = demandMisses / demandAccesses;
2293 for (
int i = 0;
i < max_requestors;
i++) {
2298 overallMissRate = overallMisses / overallAccesses;
2299 for (
int i = 0;
i < max_requestors;
i++) {
2304 demandAvgMissLatency = demandMissLatency / demandMisses;
2305 for (
int i = 0;
i < max_requestors;
i++) {
2310 overallAvgMissLatency = overallMissLatency / overallMisses;
2311 for (
int i = 0;
i < max_requestors;
i++) {
2332 avgBlocked = blockedCycles / blockedCauses;
2335 .init(max_requestors)
2338 for (
int i = 0;
i < max_requestors;
i++) {
2344 for (
int i = 0;
i < max_requestors;
i++) {
2350 for (
int i = 0;
i < max_requestors;
i++) {
2356 for (
int i = 0;
i < max_requestors;
i++) {
2361 overallMshrMisses = demandMshrMisses +
SUM_NON_DEMAND(mshrMisses);
2362 for (
int i = 0;
i < max_requestors;
i++) {
2367 demandMshrMissLatency =
SUM_DEMAND(mshrMissLatency);
2368 for (
int i = 0;
i < max_requestors;
i++) {
2373 overallMshrMissLatency =
2375 for (
int i = 0;
i < max_requestors;
i++) {
2380 overallMshrUncacheable =
2382 for (
int i = 0;
i < max_requestors;
i++) {
2388 overallMshrUncacheableLatency =
2391 for (
int i = 0;
i < max_requestors;
i++) {
2396 demandMshrMissRate = demandMshrMisses / demandAccesses;
2397 for (
int i = 0;
i < max_requestors;
i++) {
2402 overallMshrMissRate = overallMshrMisses / overallAccesses;
2403 for (
int i = 0;
i < max_requestors;
i++) {
2408 demandAvgMshrMissLatency = demandMshrMissLatency / demandMshrMisses;
2409 for (
int i = 0;
i < max_requestors;
i++) {
2414 overallAvgMshrMissLatency = overallMshrMissLatency / overallMshrMisses;
2415 for (
int i = 0;
i < max_requestors;
i++) {
2420 overallAvgMshrUncacheableLatency =
2421 overallMshrUncacheableLatency / overallMshrUncacheable;
2422 for (
int i = 0;
i < max_requestors;
i++) {
2423 overallAvgMshrUncacheableLatency.subname(
i,
2450 assert(!cache->system->bypassCaches());
2455 cache->recvTimingSnoopResp(pkt);
2466 }
else if (
blocked || mustSendRetry) {
2468 mustSendRetry =
true;
2471 mustSendRetry =
false;
2480 if (cache->system->bypassCaches()) {
2483 [[maybe_unused]]
bool success = cache->memSidePort.sendTimingReq(pkt);
2486 }
else if (tryTiming(pkt)) {
2487 cache->recvTimingReq(pkt);
2496 if (cache->system->bypassCaches()) {
2498 return cache->memSidePort.sendAtomic(pkt);
2500 return cache->recvAtomic(pkt);
2507 if (cache->system->bypassCaches()) {
2510 cache->memSidePort.sendFunctional(pkt);
2515 cache->functionalAccess(pkt,
true);
2521 return cache->getAddrRanges();
2527 const std::string &_label)
2540 cache->recvTimingResp(pkt);
2549 assert(!cache->system->bypassCaches());
2552 cache->recvTimingSnoopReq(pkt);
2559 assert(!cache->system->bypassCaches());
2561 return cache->recvAtomicSnoop(pkt);
2568 assert(!cache->system->bypassCaches());
2573 cache->functionalAccess(pkt,
false);
2580 assert(!waitingOnRetry);
2585 assert(deferredPacketReadyTime() ==
MaxTick);
2588 QueueEntry* entry = cache.getNextQueueEntry();
2607 if (!waitingOnRetry) {
2608 schedSendEvent(cache.nextQueueReadyTime());
2614 const std::string &_label)
2616 _reqQueue(*_cache, *this, _snoopRespQueue, _label),
2617 _snoopRespQueue(*_cache, *this, true, _label), cache(_cache)
2626 if (nextAddr == write_addr) {
2627 delayCtr[blk_addr] = delayThreshold;
2629 if (
mode != WriteMode::NO_ALLOCATE) {
2630 byteCount += write_size;
2633 if (
mode == WriteMode::ALLOCATE &&
2634 byteCount > coalesceLimit) {
2635 mode = WriteMode::COALESCE;
2637 }
else if (
mode == WriteMode::COALESCE &&
2638 byteCount > noAllocateLimit) {
2641 mode = WriteMode::NO_ALLOCATE;
2648 byteCount = write_size;
2649 mode = WriteMode::ALLOCATE;
2650 resetDelay(blk_addr);
2652 nextAddr = write_addr + write_size;
Addr getBlockAddr(unsigned int blk_size) const
virtual void memWriteback() override
Write back dirty blocks in the cache using functional accesses.
Tick curTick()
The universal simulation clock.
#define fatal(...)
This implements a cprintf based fatal() function.
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Miss Status and handling Register.
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
MemSidePort(const std::string &_name, BaseCache *_cache, const std::string &_label)
void incMissCount(PacketPtr pkt)
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
virtual void handleTimingReqMiss(PacketPtr pkt, CacheBlk *blk, Tick forward_time, Tick request_time)=0
void regStatsFromParent()
Callback to register stats from parent CacheStats::regStats().
void reset()
Reset the write allocator state, meaning that it allocates for writes and has not recorded any inform...
void invalidateBlock(CacheBlk *blk)
Invalidate a cache block.
std::vector< uint64_t > oldData
The stale data contents.
Addr getOffset(unsigned int blk_size) const
statistics::Scalar replacements
Number of replacements of valid blocks.
void sendFunctionalSnoop(PacketPtr pkt) const
Send a functional snoop request packet, where the data is instantly updated everywhere in the memory ...
void clearPrefetched()
Clear the prefetching bit.
void cmpAndSwap(CacheBlk *blk, PacketPtr pkt)
Handle doing the Compare and Swap function for SPARC.
ProbePointArg< DataUpdate > * ppDataUpdate
To probe when the contents of a block are updated.
#define UNSERIALIZE_SCALAR(scalar)
A cache request port is used for the memory-side port of the cache, and in addition to the basic timi...
virtual bool access(PacketPtr pkt, CacheBlk *&blk, Cycles &lat, PacketList &writebacks)
Does all the processing necessary to perform the provided request.
bool forwardSnoops
Do we forward snoops from mem side port through to cpu side port?
const PacketPtr pkt
Pending request packet.
bool isCleanEviction() const
Is this packet a clean eviction, including both actual clean evict packets, but also clean writebacks...
statistics::Vector mshrHits
Number of misses that hit in the MSHRs per command and thread.
void invalidate() override
Invalidate the block and clear all state.
WriteQueue writeBuffer
Write/writeback buffer.
void setData(const uint8_t *p)
Copy data into the packet from the provided pointer.
const bool moveContractions
Similar to data expansions, after a block improves its compression, it may need to be moved elsewhere...
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...
virtual void recvTimingResp(PacketPtr pkt)
Handles a response (cache line fill/write ack) from the bus.
CacheResponsePort(const std::string &_name, BaseCache *_cache, const std::string &_label)
RequestPtr req
A pointer to the original request.
bool isForward
True if the entry is just a simple forward from an upper level.
virtual void recvFunctionalSnoop(PacketPtr pkt)
Receive a functional snoop request packet from the peer.
bool coalesce() const
Checks if the cache is coalescing writes.
Cycles getDecompressionLatency(const CacheBlk *blk)
Get the decompression latency if the block is compressed.
void setSizeBits(const std::size_t size)
Set size, in bits, of this compressed block's data.
static const Priority Delayed_Writeback_Pri
For some reason "delayed" inter-cluster writebacks are scheduled before regular writebacks (which hav...
bool canPrefetch() const
Returns true if sufficient mshrs for prefetch.
#define SUM_NON_DEMAND(s)
bool writeThrough() const
const FlagsType nozero
Don't print if this is zero.
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
@ SECURE
The request targets the secure memory space.
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...
void setCacheResponding()
Snoop flags.
bool promoteDeferredTargets()
void promoteWritable()
Promotes deferred targets that do not require writable.
bool cacheResponding() const
Target * getTarget() override
Returns a reference to the first target.
Special instance of CacheBlk for use with tempBlk that deals with its block address regeneration.
void clearCoherenceBits(unsigned bits)
Clear the corresponding coherence bits.
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...
void setWriteThrough()
A writeback/writeclean cmd gets propagated further downstream by the receiver when the flag is set.
void clearBlocked(BlockedCause cause)
Marks the cache as unblocked for the given cause.
const Cycles dataLatency
The latency of data access of a cache.
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...
statistics::Vector mshrMisses
Number of misses that miss in the MSHRs, per command and thread.
std::size_t getSizeBits() const
const bool replaceExpansions
when a data expansion of a compressed block happens it will not be able to co-allocate where it is at...
uint8_t blocked
Bit vector of the blocking reasons for the access path.
A queue entry is holding packets that will be serviced as soon as resources are available.
void schedule(Event &event, Tick when)
void updateMode(Addr write_addr, unsigned write_size, Addr blk_addr)
Update the write mode based on the current write packet.
const FlagsType nonan
Don't print if this is NAN.
bool checkWrite(PacketPtr pkt)
Handle interaction of load-locked operations and stores.
const bool sequentialAccess
Whether tags and data are accessed sequentially.
BaseCache(const BaseCacheParams &p, unsigned blk_size)
void updateBlockData(CacheBlk *blk, const PacketPtr cpkt, bool has_old_data)
Update the data contents of a block.
void makeAtomicResponse()
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.
std::unique_ptr< Packet > pendingDelete
Upstream caches need this packet until true is returned, so hold it for deletion until a subsequent c...
A cache response port is used for the CPU-side port of the cache, and it is basically a simple timing...
@ WritableBit
write permission
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
SectorBlk * getSectorBlock() const
Get sector block associated to this block.
void setSatisfied()
Set when a request hits in a cache and the cache is not going to respond.
Addr blkAddr
Block aligned address.
std::vector< SectorSubBlk * > blks
List of blocks associated to this sector.
@ funcRequestorId
This requestor id is used for functional requests that don't come from a particular device.
Counter order
Order number assigned to disambiguate writes and misses.
@ DATA_EXPANSION
New data contents are considered larger than previous contents.
TempCacheBlk * tempBlock
Temporary cache block for occasional transitory use.
virtual Cycles handleAtomicReqMiss(PacketPtr pkt, CacheBlk *&blk, PacketList &writebacks)=0
Handle a request in atomic mode that missed in this cache.
bool sendWriteQueuePacket(WriteQueueEntry *wq_entry)
Similar to sendMSHR, but for a write-queue entry instead.
statistics::Vector mshrMissLatency
Total cycle latency of each MSHR miss, per command and thread.
virtual bool recvTimingReq(PacketPtr pkt) override
Receive a timing request from the peer.
void setBlocked()
Do not accept any new requests.
bool isBlocked() const
Returns true if the cache is blocked for accesses.
Cycles is a wrapper class for representing cycle counts, i.e.
WriteAllocator *const writeAllocator
The writeAllocator drive optimizations for streaming writes.
Addr getAddr() const
Get block's address.
bool inRange(Addr addr) const
Determine if an address is in the ranges covered by this cache.
std::vector< uint64_t > newData
The new data contents.
AtomicOpFunctor * getAtomicOp() const
Accessor function to atomic op.
EventFunctionWrapper writebackTempBlockAtomicEvent
An event to writeback the tempBlock after recvAtomic finishes.
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
A data contents update is composed of the updated block's address, the old contents,...
const Tick recvTime
Time when request was received (for stats)
uint64_t order
Increasing order number assigned to each incoming request.
uint32_t getTaskId() const
Get the task id associated to this block.
void serialize(CheckpointOut &cp) const override
Serialize the state of the caches.
ProbePointArg< PacketPtr > * ppMiss
To probe when a cache miss occurs.
RequestorID maxRequestors()
Get the number of requestors registered in the system.
void sendFunctional(PacketPtr pkt) const
Send a functional request packet, where the data is instantly updated everywhere in the memory system...
void setWhenReady(const Tick tick)
Set tick at which block's data will be available for access.
prefetch::Base * prefetcher
Prefetcher.
BaseTags * tags
Tag and data Storage.
bool allocate() const
Should writes allocate?
void regStats() override
Callback to set stat parameters.
bool needsWritable() const
ProbePointArg< PacketPtr > * ppFill
To probe when a cache fill occurs.
Tick nextReadyTime() const
void allocateTarget(PacketPtr target, Tick when, Counter order, bool alloc_on_fill)
Add a request to the list of targets.
std::vector< std::unique_ptr< CacheCmdStats > > cmd
Per-command statistics.
void allocateWriteBuffer(PacketPtr pkt, Tick time)
virtual std::string name() const
bool needsWritable() const
The pending* and post* flags are only valid if inService is true.
virtual bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
void print(std::ostream &o, int verbosity=0, const std::string &prefix="") const
gem5::BaseCache::CacheStats stats
A basic compression superblock.
Tick cyclesToTicks(Cycles c) const
A queued port is a port that has an infinite queue for outgoing packets and thus decouples the module...
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Cycles calculateTagOnlyLatency(const uint32_t delay, const Cycles lookup_lat) const
Calculate latency of accesses that only touch the tag array.
virtual bool sendMSHRQueuePacket(MSHR *mshr)
Take an MSHR, turn it into a suitable downstream packet, and send it out.
bool isPendingModified() const
PacketPtr writecleanBlk(CacheBlk *blk, Request::Flags dest, PacketId id)
Create a writeclean request for the given block.
ProbePointArg< PacketInfo > Packet
Packet probe point.
const unsigned blkSize
Block size of this cache.
uint64_t Tick
Tick count type.
Entry * getNext() const
Returns the WriteQueueEntry at the head of the readyList.
Addr regenerateBlkAddr(CacheBlk *blk)
Regenerate block address using tags.
bool isSnooping() const
Find out if the peer request port is snooping or not.
ProbePointArg< PacketPtr > * ppHit
To probe when a cache hit occurs.
bool isSecure
True if the entry targets the secure memory space.
void clearBlocked()
Return to normal operation and accept new requests.
virtual Tick recvAtomic(PacketPtr pkt)
Performs the access specified by the request.
std::string getRequestorName(RequestorID requestor_id)
Get the name of an object for a given request id.
virtual bool recvTimingSnoopResp(PacketPtr pkt) override
Receive a timing snoop response from the peer.
std::shared_ptr< Request > RequestPtr
const T * getConstPtr() const
void setCoherenceBits(unsigned bits)
Sets the corresponding coherence bits.
statistics::Vector writebacks
Number of blocks written back per thread.
static void setSizeBits(CacheBlk *blk, const std::size_t size_bits)
Set the size of the compressed block, in bits.
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
CpuSidePort(const std::string &_name, BaseCache *_cache, const std::string &_label)
@ wbRequestorId
This requestor id is used for writeback requests by the caches.
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.
bool isConnected() const
Is this port currently connected to a peer?
statistics::Scalar dataExpansions
Number of data expansions.
bool isWholeLineWrite() const
Check if this MSHR contains only compatible writes, and if they span the entire cache line.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
bool allocOnFill(MemCmd cmd) const
Determine whether we should allocate on a fill or not.
void incHitCount(PacketPtr pkt)
bool trySatisfyFunctional(PacketPtr pkt)
void pushLabel(const std::string &lbl)
Push label for PrintReq (safe to call unconditionally).
MemCmd cmd
The command field of the packet.
void popLabel()
Pop label for PrintReq (safe to call unconditionally).
virtual void recvFunctional(PacketPtr pkt) override
Receive a functional request packet from the peer.
bool needsResponse() const
void writeData(uint8_t *p) const
Copy data from the packet to the memory at the provided pointer.
bool wasWholeLineWrite
Track if we sent this as a whole line write or not.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
virtual void doWritebacksAtomic(PacketList &writebacks)=0
Send writebacks down the memory hierarchy in atomic mode.
const std::string & name()
#define SERIALIZE_SCALAR(scalar)
PacketPtr tempBlockWriteback
Writebacks from the tempBlock, resulting on the response path in atomic mode, must happen after the c...
@ DirtyBit
dirty (modified)
virtual void regStats()
Callback to set stat parameters.
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...
virtual void recvTimingReq(PacketPtr pkt)
Performs the access specified by the request.
void sendRangeChange() const
Called by the owner to send a range change.
void markPending(MSHR *mshr)
Mark an in service entry as pending, used to resend a request.
virtual void recvTimingSnoopReq(PacketPtr pkt)
Receive a timing snoop request from the peer.
void deschedule(Event &event)
virtual Tick nextPrefetchReadyTime() const =0
SenderState * popSenderState()
Pop the top of the state stack and return a pointer to it.
A coherent cache that can be arranged in flexible topologies.
virtual Tick recvAtomicSnoop(PacketPtr pkt)
Receive an atomic snoop request packet from our peer.
void schedMemSideSendEvent(Tick time)
Schedule a send event for the memory-side port.
ProbePointArg generates a point for the class of Arg.
uint8_t * data
Contains a copy of the data in this block for easy access.
void maintainClusivity(bool from_cache, CacheBlk *blk)
Maintain the clusivity of this cache by potentially invalidating a block.
Tick getWhenReady() const
Get tick at which block's data will be available for access.
void deallocate(MSHR *mshr) override
Deallocate a MSHR and its targets.
const bool isReadOnly
Is this cache read only, for example the instruction cache, or table-walker cache.
virtual void sendDeferredPacket()
Override the normal sendDeferredPacket and do not only consider the transmit list (used for responses...
void setHasSharers()
On fills, the hasSharers flag is used by the caches in combination with the cacheResponding flag,...
MSHR * noTargetMSHR
Pointer to the MSHR that has no targets.
ProbeManager * getProbeManager()
Get the probe manager for this object.
const enums::Clusivity clusivity
Clusivity with respect to the upstream cache, determining if we fill into both this cache and the cac...
#define warn_if(cond,...)
Conditional warning macro that checks the supplied condition and only prints a warning if the conditi...
Copyright (c) 2018 Inria All rights reserved.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
virtual void memInvalidate() override
Invalidates all blocks in the cache.
CacheCmdStats(BaseCache &c, const std::string &name)
void makeTimingResponse()
void regProbePoints() override
Registers probes.
void allocate()
Allocate memory for the packet.
Ports are used to interface objects to each other.
bool isDirty() const
Determine if there are any dirty blocks in the cache.
CacheCmdStats & cmdStats(const PacketPtr p)
A superblock is composed of sub-blocks, and each sub-block has information regarding its superblock a...
CacheBlk * allocateBlock(const PacketPtr pkt, PacketList &writebacks)
Allocate a new block and perform any necessary writebacks.
statistics::Scalar dataContractions
Number of data contractions (blocks that had their compression factor improved).
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.
int getNumTargets() const
Returns the current number of allocated targets.
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.
const Cycles fillLatency
The latency to fill a cache block.
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
virtual void handleTimingReqHit(PacketPtr pkt, CacheBlk *blk, Tick request_time)
virtual PacketPtr evictBlock(CacheBlk *blk)=0
Evict a cache block.
const AddrRangeList addrRanges
The address range to which the cache responds on the CPU side.
System * system
System we are currently operating in.
bool delay(Addr blk_addr)
Access whether we need to delay the current write.
MSHRQueue mshrQueue
Miss status registers.
bool wasPrefetched() const
Check if this block was the result of a hardware prefetch, yet to be touched.
void handleUncacheableWriteResp(PacketPtr pkt)
Handling the special case of uncacheable write responses to make recvTimingResp less cluttered.
const bool writebackClean
Determine if clean lines should be written back or not.
bool trySatisfyFunctional(PacketPtr pkt)
Check the list of buffered packets against the supplied functional request.
OverwriteType checkExpansionContraction(const std::size_t size) const
Determines if changing the size of the block will cause a data expansion (new size is bigger) or cont...
void trackLoadLocked(PacketPtr pkt)
Track the fact that a local locked was issued to the block.
bool isSecure() const
Check if this block holds data from the secure memory space.
bool isSet(unsigned bits) const
Checks the given coherence bits are set.
void promoteReadable()
Promotes deferred targets that do not require writable.
statistics::Vector mshrUncacheableLatency
Total cycle latency of each MSHR miss, per command and thread.
A queue entry base class, to be used by both the MSHRs and write-queue entries.
void insert(const Addr addr, const bool is_secure) override
Insert the block by assigning it a tag and marking it valid.
void invalidateVisitor(CacheBlk &blk)
Cache block visitor that invalidates all blocks in the cache.
void writebackTempBlockAtomic()
Send the outstanding tempBlock writeback.
QueueEntry * getNextQueueEntry()
Return the next queue entry to service, either a pending miss from the MSHR queue,...
bool trySatisfyFunctional(PacketPtr other)
Check a functional request against a memory value stored in another packet (i.e.
bool trySatisfyFunctional(PacketPtr pkt)
Check the list of buffered packets against the supplied functional request.
virtual void serviceMSHRTargets(MSHR *mshr, const PacketPtr pkt, CacheBlk *blk)=0
Service non-deferred MSHR targets using the received response.
const Cycles lookupLatency
The latency of tag lookup of a cache.
int getNumTargets() const
Returns the current number of allocated targets.
void incrDemandMhsrMisses()
std::ostream CheckpointOut
MSHR * allocateMissBuffer(PacketPtr pkt, Tick time, bool sched_send=true)
bool coalesce() const
Should writes be coalesced? This is true if the mode is set to NO_ALLOCATE.
Simple class to provide virtual print() method on cache blocks without allocating a vtable pointer fo...
@ DATA_CONTRACTION
New data contents are considered smaller than previous contents.
bool isExpressSnoop() const
virtual void doWritebacks(PacketList &writebacks, Tick forward_time)=0
Insert writebacks into the write buffer.
void setBlocked(BlockedCause cause)
Marks the access path of the cache as blocked for the given cause.
#define gem5_assert(cond,...)
The assert macro will function like a normal assert, but will use panic instead of straight abort().
Cycles ticksToCycles(Tick t) const
void writebackVisitor(CacheBlk &blk)
Cache block visitor that writes back dirty cache blocks using functional writes.
const int numTarget
The number of targets for each MSHR.
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.
OverwriteType
When an overwrite happens, the data size may change an not fit in its current container any longer.
void setDecompressionLatency(const Cycles lat)
Set number of cycles needed to decompress this block.
void schedTimingResp(PacketPtr pkt, Tick when)
Schedule the sending of a timing response.
static void setDecompressionLatency(CacheBlk *blk, const Cycles lat)
Set the decompression latency of compressed block.
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
virtual void functionalAccess(PacketPtr pkt, bool from_cpu_side)
Performs the access specified by the request.
virtual PacketPtr getPacket()=0
EventFunctionWrapper sendRetryEvent
bool handleEvictions(std::vector< CacheBlk * > &evict_blks, PacketList &writebacks)
Try to evict the given blocks.
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
virtual bool sendPacket(BaseCache &cache)=0
Send this queue entry as a downstream packet, with the exact behaviour depending on the specific entr...
const FlagsType total
Print the total.
const Cycles forwardLatency
This is the forward latency of the cache.
Tick nextQueueReadyTime() const
Find next request ready time from among possible sources.
QueueEntry::Target * getTarget() override
Returns a reference to the first target.
virtual AddrRangeList getAddrRanges() const override
Get a list of the non-overlapping address ranges the owner is responsible for.
bool inService
True if the entry has been sent downstream.
virtual Tick recvAtomic(PacketPtr pkt) override
Receive an atomic request packet from the peer.
CacheBlk * handleFill(PacketPtr pkt, CacheBlk *blk, PacketList &writebacks, bool allocate)
Handle a fill operation caused by a received packet.
Entry * findPending(const QueueEntry *entry) const
Find any pending requests that overlap the given request of a different queue.
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.
virtual Target * getTarget()=0
Returns a pointer to the first target.
bool scheduled() const
Determine if the current event is scheduled.
PacketPtr writebackBlk(CacheBlk *blk)
Create a writeback request for the given block.
virtual bool tryTiming(PacketPtr pkt) override
Availability request from the peer.
virtual bool isValid() const
Checks if the entry is valid.
void resetDelay(Addr blk_addr)
Clear delay counter for the input block.
bool isInvalidate() const
#define panic(...)
This implements a cprintf based panic() function.
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...
@ ReadableBit
Read permission.
const Cycles responseLatency
The latency of sending reponse to its upper level cache/core on a linefill.
compression::Base * compressor
Compression method being used.
Generated on Tue Feb 8 2022 11:47:02 for gem5 by doxygen 1.8.17