/*
- * Copyright (c) 2013 ARM Limited
+ * Copyright (c) 2013,2016 ARM Limited
* All rights reserved.
*
* The license below extends only to copyright in the software and shall
* Definitions a fully associative LRU tagstore.
*/
+#include "mem/cache/tags/fa_lru.hh"
+
#include <cassert>
#include <sstream>
#include "base/intmath.hh"
-#include "base/misc.hh"
-#include "mem/cache/tags/fa_lru.hh"
+#include "base/logging.hh"
using namespace std;
if (!isPowerOf2(blkSize))
fatal("cache block size (in bytes) `%d' must be a power of two",
blkSize);
- if (!(hitLatency > 0))
- fatal("Access latency in cycles must be at least one cycle");
if (!isPowerOf2(size))
fatal("Cache Size must be power of 2 for now");
numCaches = floorLog2(size) - 17;
if (numCaches >0){
cacheBoundaries = new FALRUBlk *[numCaches];
- cacheMask = (1 << numCaches) - 1;
+ cacheMask = (ULL(1) << numCaches) - 1;
} else {
cacheMask = 0;
}
head = &(blks[0]);
tail = &(blks[numBlocks-1]);
- head->prev = NULL;
+ head->prev = nullptr;
head->next = &(blks[1]);
head->inCache = cacheMask;
tail->prev = &(blks[numBlocks-2]);
- tail->next = NULL;
+ tail->next = nullptr;
tail->inCache = 0;
unsigned index = (1 << 17) / blkSize;
blks[i].prev = &(blks[i-1]);
blks[i].next = &(blks[i+1]);
blks[i].isTouched = false;
+ blks[i].set = 0;
+ blks[i].way = i;
}
assert(j == numCaches);
assert(index == numBlocks);
if (iter != tagHash.end()) {
return (*iter).second;
}
- return NULL;
+ return nullptr;
}
void
-FALRU::invalidate(FALRU::BlkType *blk)
+FALRU::invalidate(CacheBlk *blk)
{
assert(blk);
tagsInUse--;
}
-FALRUBlk*
-FALRU::accessBlock(Addr addr, bool is_secure, Cycles &lat, int context_src,
- int *inCache)
+CacheBlk*
+FALRU::accessBlock(Addr addr, bool is_secure, Cycles &lat)
+{
+ return accessBlock(addr, is_secure, lat, 0);
+}
+
+CacheBlk*
+FALRU::accessBlock(Addr addr, bool is_secure, Cycles &lat, int *inCache)
{
accesses++;
int tmp_in_cache = 0;
FALRUBlk* blk = hashLookup(blkAddr);
if (blk && blk->isValid()) {
+ // If a cache hit
+ lat = accessLatency;
+ // Check if the block to be accessed is available. If not,
+ // apply the accessLatency on top of block->whenReady.
+ if (blk->whenReady > curTick() &&
+ cache->ticksToCycles(blk->whenReady - curTick()) >
+ accessLatency) {
+ lat = cache->ticksToCycles(blk->whenReady - curTick()) +
+ accessLatency;
+ }
assert(blk->tag == blkAddr);
tmp_in_cache = blk->inCache;
for (unsigned i = 0; i < numCaches; i++) {
moveToHead(blk);
}
} else {
- blk = NULL;
+ // If a cache miss
+ lat = lookupLatency;
+ blk = nullptr;
for (unsigned i = 0; i <= numCaches; ++i) {
misses[i]++;
}
*inCache = tmp_in_cache;
}
- lat = hitLatency;
//assert(check());
return blk;
}
-FALRUBlk*
+CacheBlk*
FALRU::findBlock(Addr addr, bool is_secure) const
{
Addr blkAddr = blkAlign(addr);
if (blk && blk->isValid()) {
assert(blk->tag == blkAddr);
} else {
- blk = NULL;
+ blk = nullptr;
}
return blk;
}
-FALRUBlk*
+CacheBlk*
+FALRU::findBlockBySetAndWay(int set, int way) const
+{
+ assert(set == 0);
+ return &blks[way];
+}
+
+CacheBlk*
FALRU::findVictim(Addr addr)
{
FALRUBlk * blk = tail;
}
void
-FALRU::insertBlock(PacketPtr pkt, FALRU::BlkType *blk)
+FALRU::insertBlock(PacketPtr pkt, CacheBlk *blk)
{
}
blk->inCache = cacheMask;
if (blk != head) {
if (blk == tail){
- assert(blk->next == NULL);
+ assert(blk->next == nullptr);
tail = blk->prev;
- tail->next = NULL;
+ tail->next = nullptr;
} else {
blk->prev->next = blk->next;
blk->next->prev = blk->prev;
}
blk->next = head;
- blk->prev = NULL;
+ blk->prev = nullptr;
head->prev = blk;
head = blk;
}
return true;
}
-void
-FALRU::clearLocks()
-{
- for (int i = 0; i < numBlocks; i++){
- blks[i].clearLoadLocks();
- }
-}
-
FALRU *
FALRUParams::create()
{