mem_side = MasterPort("Port on side closer to MEM")
addr_ranges = VectorParam.AddrRange([AllMemory], "The address range for the CPU-side port")
system = Param.System(Parent.any, "System we belong to")
+ sequential_access = Param.Bool(False,
+ "Whether to access tags and data sequentially")
tags = Param.BaseTags(LRU(), "Tag Store for LRU caches")
cxx_class = 'LRU'
cxx_header = "mem/cache/tags/lru.hh"
assoc = Param.Int(Parent.assoc, "associativity")
+ sequential_access = Param.Bool(Parent.sequential_access,
+ "Whether to access tags and data sequentially")
class FALRU(BaseTags):
type = 'FALRU'
percentOccsTaskId = occupanciesTaskId / Stats::constant(numBlocks);
+ tagAccesses
+ .name(name() + ".tag_accesses")
+ .desc("Number of tag accesses")
+ ;
+
+ dataAccesses
+ .name(name() + ".data_accesses")
+ .desc("Number of data accesses")
+ ;
+
registerDumpCallback(new BaseTagsDumpCallback(this));
registerExitCallback(new BaseTagsCallback(this));
}
/** Occ % of each context/cpu using the cache */
Stats::Formula percentOccsTaskId;
+ /** Number of tags consulted over all accesses. */
+ Stats::Scalar tagAccesses;
+ /** Number of data blocks consulted over all accesses. */
+ Stats::Scalar dataAccesses;
+
/**
* @}
*/
LRU::LRU(const Params *p)
:BaseTags(p), assoc(p->assoc),
- numSets(p->size / (p->block_size * p->assoc))
+ numSets(p->size / (p->block_size * p->assoc)),
+ sequentialAccess(p->sequential_access)
{
// Check parameters
if (blkSize < 4 || !isPowerOf2(blkSize)) {
unsigned set = extractSet(addr);
BlkType *blk = sets[set].findBlk(tag);
lat = hitLatency;
+
+ // Access all tags in parallel, hence one in each way. The data side
+ // either accesses all blocks in parallel, or one block sequentially on
+ // a hit. Sequential access with a miss doesn't access data.
+ tagAccesses += assoc;
+ if (sequentialAccess) {
+ if (blk != NULL) {
+ dataAccesses += 1;
+ }
+ } else {
+ dataAccesses += assoc;
+ }
+
if (blk != NULL) {
// move this block to head of the MRU list
sets[set].moveToHead(blk);
unsigned set = extractSet(addr);
sets[set].moveToHead(blk);
+
+ // We only need to write into one tag and one data block.
+ tagAccesses += 1;
+ dataAccesses += 1;
}
void
const unsigned assoc;
/** The number of sets in the cache. */
const unsigned numSets;
+ /** Whether tags and data are accessed sequentially. */
+ const bool sequentialAccess;
/** The cache sets. */
SetType *sets;