base.cc (13941:2c19da00ef9c) base.cc (13945:a573bed35a8b)
1/*
2 * Copyright (c) 2012-2013, 2018-2019 ARM Limited
3 * All rights reserved.
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software

--- 40 unchanged lines hidden (view full) ---

49#include "mem/cache/base.hh"
50
51#include "base/compiler.hh"
52#include "base/logging.hh"
53#include "debug/Cache.hh"
54#include "debug/CachePort.hh"
55#include "debug/CacheRepl.hh"
56#include "debug/CacheVerbose.hh"
1/*
2 * Copyright (c) 2012-2013, 2018-2019 ARM Limited
3 * All rights reserved.
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software

--- 40 unchanged lines hidden (view full) ---

49#include "mem/cache/base.hh"
50
51#include "base/compiler.hh"
52#include "base/logging.hh"
53#include "debug/Cache.hh"
54#include "debug/CachePort.hh"
55#include "debug/CacheRepl.hh"
56#include "debug/CacheVerbose.hh"
57#include "mem/cache/compressors/base.hh"
57#include "mem/cache/mshr.hh"
58#include "mem/cache/prefetch/base.hh"
59#include "mem/cache/queue_entry.hh"
60#include "params/BaseCache.hh"
61#include "params/WriteAllocator.hh"
62#include "sim/core.hh"
63
64class BaseMasterPort;

--- 13 unchanged lines hidden (view full) ---

78
79BaseCache::BaseCache(const BaseCacheParams *p, unsigned blk_size)
80 : ClockedObject(p),
81 cpuSidePort (p->name + ".cpu_side", this, "CpuSidePort"),
82 memSidePort(p->name + ".mem_side", this, "MemSidePort"),
83 mshrQueue("MSHRs", p->mshrs, 0, p->demand_mshr_reserve), // see below
84 writeBuffer("write buffer", p->write_buffers, p->mshrs), // see below
85 tags(p->tags),
58#include "mem/cache/mshr.hh"
59#include "mem/cache/prefetch/base.hh"
60#include "mem/cache/queue_entry.hh"
61#include "params/BaseCache.hh"
62#include "params/WriteAllocator.hh"
63#include "sim/core.hh"
64
65class BaseMasterPort;

--- 13 unchanged lines hidden (view full) ---

79
80BaseCache::BaseCache(const BaseCacheParams *p, unsigned blk_size)
81 : ClockedObject(p),
82 cpuSidePort (p->name + ".cpu_side", this, "CpuSidePort"),
83 memSidePort(p->name + ".mem_side", this, "MemSidePort"),
84 mshrQueue("MSHRs", p->mshrs, 0, p->demand_mshr_reserve), // see below
85 writeBuffer("write buffer", p->write_buffers, p->mshrs), // see below
86 tags(p->tags),
87 compressor(p->compressor),
86 prefetcher(p->prefetcher),
87 writeAllocator(p->write_allocator),
88 writebackClean(p->writeback_clean),
89 tempBlockWriteback(nullptr),
90 writebackTempBlockAtomicEvent([this]{ writebackTempBlockAtomic(); },
91 name(), false,
92 EventBase::Delayed_Writeback_Pri),
93 blkSize(blk_size),

--- 935 unchanged lines hidden (view full) ---

1029 // A writeback searches for the block, then writes the data.
1030 // As the block could not be found, it was a tag-only access.
1031 lat = calculateTagOnlyLatency(pkt->headerDelay, tag_latency);
1032
1033 return false;
1034 }
1035
1036 blk->status |= BlkReadable;
88 prefetcher(p->prefetcher),
89 writeAllocator(p->write_allocator),
90 writebackClean(p->writeback_clean),
91 tempBlockWriteback(nullptr),
92 writebackTempBlockAtomicEvent([this]{ writebackTempBlockAtomic(); },
93 name(), false,
94 EventBase::Delayed_Writeback_Pri),
95 blkSize(blk_size),

--- 935 unchanged lines hidden (view full) ---

1031 // A writeback searches for the block, then writes the data.
1032 // As the block could not be found, it was a tag-only access.
1033 lat = calculateTagOnlyLatency(pkt->headerDelay, tag_latency);
1034
1035 return false;
1036 }
1037
1038 blk->status |= BlkReadable;
1039 } else {
1040 if (compressor) {
1041 // This is an overwrite to an existing block, therefore we need
1042 // to check for data expansion (i.e., block was compressed with
1043 // a smaller size, and now it doesn't fit the entry anymore).
1044 // If that is the case we might need to evict blocks.
1045 // @todo Update compression data
1046 }
1037 }
1047 }
1048
1038 // only mark the block dirty if we got a writeback command,
1039 // and leave it as is for a clean writeback
1040 if (pkt->cmd == MemCmd::WritebackDirty) {
1041 // TODO: the coherent cache can assert(!blk->isDirty());
1042 blk->status |= BlkDirty;
1043 }
1044 // if the packet does not have sharers, it is passing
1045 // writable, and we got the writeback in Modified or Exclusive

--- 63 unchanged lines hidden (view full) ---

1109 lat = calculateTagOnlyLatency(pkt->headerDelay,
1110 tag_latency);
1111
1112 return false;
1113 }
1114
1115 blk->status |= BlkReadable;
1116 }
1049 // only mark the block dirty if we got a writeback command,
1050 // and leave it as is for a clean writeback
1051 if (pkt->cmd == MemCmd::WritebackDirty) {
1052 // TODO: the coherent cache can assert(!blk->isDirty());
1053 blk->status |= BlkDirty;
1054 }
1055 // if the packet does not have sharers, it is passing
1056 // writable, and we got the writeback in Modified or Exclusive

--- 63 unchanged lines hidden (view full) ---

1120 lat = calculateTagOnlyLatency(pkt->headerDelay,
1121 tag_latency);
1122
1123 return false;
1124 }
1125
1126 blk->status |= BlkReadable;
1127 }
1128 } else {
1129 if (compressor) {
1130 // @todo Update compression data
1131 }
1117 }
1118
1119 // at this point either this is a writeback or a write-through
1120 // write clean operation and the block is already in this
1121 // cache, we need to update the data and the block flags
1122 assert(blk);
1123 // TODO: the coherent cache can assert(!blk->isDirty());
1124 if (!pkt->writeThrough()) {

--- 21 unchanged lines hidden (view full) ---

1146 } else if (blk && (pkt->needsWritable() ? blk->isWritable() :
1147 blk->isReadable())) {
1148 // OK to satisfy access
1149 incHitCount(pkt);
1150
1151 // Calculate access latency based on the need to access the data array
1152 if (pkt->isRead() || pkt->isWrite()) {
1153 lat = calculateAccessLatency(blk, pkt->headerDelay, tag_latency);
1132 }
1133
1134 // at this point either this is a writeback or a write-through
1135 // write clean operation and the block is already in this
1136 // cache, we need to update the data and the block flags
1137 assert(blk);
1138 // TODO: the coherent cache can assert(!blk->isDirty());
1139 if (!pkt->writeThrough()) {

--- 21 unchanged lines hidden (view full) ---

1161 } else if (blk && (pkt->needsWritable() ? blk->isWritable() :
1162 blk->isReadable())) {
1163 // OK to satisfy access
1164 incHitCount(pkt);
1165
1166 // Calculate access latency based on the need to access the data array
1167 if (pkt->isRead() || pkt->isWrite()) {
1168 lat = calculateAccessLatency(blk, pkt->headerDelay, tag_latency);
1169
1170 // When a block is compressed, it must first be decompressed
1171 // before being read. This adds to the access latency.
1172 if (compressor && pkt->isRead()) {
1173 lat += compressor->getDecompressionLatency(blk);
1174 }
1154 } else {
1155 lat = calculateTagOnlyLatency(pkt->headerDelay, tag_latency);
1156 }
1157
1158 satisfyRequest(pkt, blk);
1159 maintainClusivity(pkt->fromCache(), blk);
1160
1161 return true;

--- 152 unchanged lines hidden (view full) ---

1314BaseCache::allocateBlock(const PacketPtr pkt, PacketList &writebacks)
1315{
1316 // Get address
1317 const Addr addr = pkt->getAddr();
1318
1319 // Get secure bit
1320 const bool is_secure = pkt->isSecure();
1321
1175 } else {
1176 lat = calculateTagOnlyLatency(pkt->headerDelay, tag_latency);
1177 }
1178
1179 satisfyRequest(pkt, blk);
1180 maintainClusivity(pkt->fromCache(), blk);
1181
1182 return true;

--- 152 unchanged lines hidden (view full) ---

1335BaseCache::allocateBlock(const PacketPtr pkt, PacketList &writebacks)
1336{
1337 // Get address
1338 const Addr addr = pkt->getAddr();
1339
1340 // Get secure bit
1341 const bool is_secure = pkt->isSecure();
1342
1322 // @todo Compress and get compression related data
1343 // Block size and compression related access latency. Only relevant if
1344 // using a compressor, otherwise there is no extra delay, and the block
1345 // is fully sized
1323 std::size_t blk_size_bits = blkSize*8;
1346 std::size_t blk_size_bits = blkSize*8;
1347 Cycles compression_lat = Cycles(0);
1348 Cycles decompression_lat = Cycles(0);
1324
1349
1350 // If a compressor is being used, it is called to compress data before
1351 // insertion. Although in Gem5 the data is stored uncompressed, even if a
1352 // compressor is used, the compression/decompression methods are called to
1353 // calculate the amount of extra cycles needed to read or write compressed
1354 // blocks.
1355 if (compressor) {
1356 compressor->compress(pkt->getConstPtr<uint64_t>(), compression_lat,
1357 decompression_lat, blk_size_bits);
1358 }
1359
1325 // Find replacement victim
1326 std::vector<CacheBlk*> evict_blks;
1327 CacheBlk *victim = tags->findVictim(addr, is_secure, blk_size_bits,
1328 evict_blks);
1329
1330 // It is valid to return nullptr if there is no victim
1331 if (!victim)
1332 return nullptr;

--- 39 unchanged lines hidden (view full) ---

1372
1373 evictBlock(blk, writebacks);
1374 }
1375 }
1376
1377 replacements++;
1378 }
1379
1360 // Find replacement victim
1361 std::vector<CacheBlk*> evict_blks;
1362 CacheBlk *victim = tags->findVictim(addr, is_secure, blk_size_bits,
1363 evict_blks);
1364
1365 // It is valid to return nullptr if there is no victim
1366 if (!victim)
1367 return nullptr;

--- 39 unchanged lines hidden (view full) ---

1407
1408 evictBlock(blk, writebacks);
1409 }
1410 }
1411
1412 replacements++;
1413 }
1414
1415 // If using a compressor, set compression data. This must be done before
1416 // block insertion, as compressed tags use this information.
1417 if (compressor) {
1418 compressor->setSizeBits(victim, blk_size_bits);
1419 compressor->setDecompressionLatency(victim, decompression_lat);
1420 }
1421
1380 // Insert new block at victimized entry
1381 tags->insertBlock(pkt, victim);
1382
1383 return victim;
1384}
1385
1386void
1387BaseCache::invalidateBlock(CacheBlk *blk)

--- 50 unchanged lines hidden (view full) ---

1438 }
1439
1440 // make sure the block is not marked dirty
1441 blk->status &= ~BlkDirty;
1442
1443 pkt->allocate();
1444 pkt->setDataFromBlock(blk->data, blkSize);
1445
1422 // Insert new block at victimized entry
1423 tags->insertBlock(pkt, victim);
1424
1425 return victim;
1426}
1427
1428void
1429BaseCache::invalidateBlock(CacheBlk *blk)

--- 50 unchanged lines hidden (view full) ---

1480 }
1481
1482 // make sure the block is not marked dirty
1483 blk->status &= ~BlkDirty;
1484
1485 pkt->allocate();
1486 pkt->setDataFromBlock(blk->data, blkSize);
1487
1488 // When a block is compressed, it must first be decompressed before being
1489 // sent for writeback.
1490 if (compressor) {
1491 pkt->payloadDelay = compressor->getDecompressionLatency(blk);
1492 }
1493
1446 return pkt;
1447}
1448
1449PacketPtr
1450BaseCache::writecleanBlk(CacheBlk *blk, Request::Flags dest, PacketId id)
1451{
1452 RequestPtr req = std::make_shared<Request>(
1453 regenerateBlkAddr(blk), blkSize, 0, Request::wbMasterId);

--- 23 unchanged lines hidden (view full) ---

1477 }
1478
1479 // make sure the block is not marked dirty
1480 blk->status &= ~BlkDirty;
1481
1482 pkt->allocate();
1483 pkt->setDataFromBlock(blk->data, blkSize);
1484
1494 return pkt;
1495}
1496
1497PacketPtr
1498BaseCache::writecleanBlk(CacheBlk *blk, Request::Flags dest, PacketId id)
1499{
1500 RequestPtr req = std::make_shared<Request>(
1501 regenerateBlkAddr(blk), blkSize, 0, Request::wbMasterId);

--- 23 unchanged lines hidden (view full) ---

1525 }
1526
1527 // make sure the block is not marked dirty
1528 blk->status &= ~BlkDirty;
1529
1530 pkt->allocate();
1531 pkt->setDataFromBlock(blk->data, blkSize);
1532
1533 // When a block is compressed, it must first be decompressed before being
1534 // sent for writeback.
1535 if (compressor) {
1536 pkt->payloadDelay = compressor->getDecompressionLatency(blk);
1537 }
1538
1485 return pkt;
1486}
1487
1488
1489void
1490BaseCache::memWriteback()
1491{
1492 tags->forEachBlk([this](CacheBlk &blk) { writebackVisitor(blk); });

--- 1050 unchanged lines hidden ---
1539 return pkt;
1540}
1541
1542
1543void
1544BaseCache::memWriteback()
1545{
1546 tags->forEachBlk([this](CacheBlk &blk) { writebackVisitor(blk); });

--- 1050 unchanged lines hidden ---