diff -r 9b73215e2d5d -r 6c866abfa8d9 src/mem/cache/BaseCache.py --- a/src/mem/cache/BaseCache.py Thu Nov 14 15:05:34 2013 -0600 +++ b/src/mem/cache/BaseCache.py Thu Nov 14 15:05:41 2013 -0600 @@ -69,4 +69,6 @@ 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") diff -r 9b73215e2d5d -r 6c866abfa8d9 src/mem/cache/tags/Tags.py --- a/src/mem/cache/tags/Tags.py Thu Nov 14 15:05:34 2013 -0600 +++ b/src/mem/cache/tags/Tags.py Thu Nov 14 15:05:41 2013 -0600 @@ -58,6 +58,8 @@ 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' diff -r 9b73215e2d5d -r 6c866abfa8d9 src/mem/cache/tags/base.hh --- a/src/mem/cache/tags/base.hh Thu Nov 14 15:05:34 2013 -0600 +++ b/src/mem/cache/tags/base.hh Thu Nov 14 15:05:41 2013 -0600 @@ -130,6 +130,11 @@ /** 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; + /** * @} */ diff -r 9b73215e2d5d -r 6c866abfa8d9 src/mem/cache/tags/base.cc --- a/src/mem/cache/tags/base.cc Thu Nov 14 15:05:34 2013 -0600 +++ b/src/mem/cache/tags/base.cc Thu Nov 14 15:05:41 2013 -0600 @@ -147,6 +147,16 @@ 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)); } diff -r 9b73215e2d5d -r 6c866abfa8d9 src/mem/cache/tags/lru.hh --- a/src/mem/cache/tags/lru.hh Thu Nov 14 15:05:34 2013 -0600 +++ b/src/mem/cache/tags/lru.hh Thu Nov 14 15:05:41 2013 -0600 @@ -81,6 +81,8 @@ 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; diff -r 9b73215e2d5d -r 6c866abfa8d9 src/mem/cache/tags/lru.cc --- a/src/mem/cache/tags/lru.cc Thu Nov 14 15:05:34 2013 -0600 +++ b/src/mem/cache/tags/lru.cc Thu Nov 14 15:05:41 2013 -0600 @@ -58,7 +58,8 @@ 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)) { @@ -132,6 +133,19 @@ 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); @@ -216,6 +230,10 @@ 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