Mem: Use cycles to express cache-related latencies
[gem5.git] / src / mem / cache / tags / iic.cc
index 31fd87df6d133148017e4884a3a0d8254bcd702b..b9e582c290cb144572eb2cf872da4c7ec74f3b22 100644 (file)
  */
 
 #include <algorithm>
+#include <cmath>
 #include <string>
 #include <vector>
 
-#include <math.h>
-
-#include "mem/cache/base.hh"
-#include "mem/cache/tags/iic.hh"
 #include "base/intmath.hh"
-#include "sim/core.hh" // for curTick
-
-#include "base/trace.hh" // for DPRINTF
-
+#include "base/trace.hh"
+#include "debug/Cache.hh"
+#include "debug/IIC.hh"
+#include "debug/IICMore.hh"
+#include "mem/cache/tags/iic.hh"
+#include "mem/cache/base.hh"
+#include "sim/core.hh"
 
 using namespace std;
 
@@ -60,14 +60,11 @@ IIC::IIC(IIC::Params &params) :
     tagShift(floorLog2(blkSize)), blkMask(blkSize - 1),
     subShift(floorLog2(subSize)), subMask(numSub - 1),
     hashDelay(params.hashDelay),
-    numBlocks(params.size/subSize),
     numTags(hashSets * assoc + params.size/blkSize -1),
     numSecondary(params.size/blkSize),
     tagNull(numTags),
     primaryBound(hashSets * assoc)
 {
-    int i;
-
     // Check parameters
     if (blkSize < 4 || !isPowerOf2(blkSize)) {
         fatal("Block size must be at least 4 and a power of 2");
@@ -90,6 +87,7 @@ IIC::IIC(IIC::Params &params) :
 
     warmedUp = false;
     warmupBound = params.size/blkSize;
+    numBlocks = params.size/subSize;
 
     // Replacement Policy Initialization
     repl = params.rp;
@@ -104,10 +102,10 @@ IIC::IIC(IIC::Params &params) :
     // Allocate storage for both internal data and block fast access data.
     // We allocate it as one large chunk to reduce overhead and to make
     // deletion easier.
-    int data_index = 0;
+    unsigned data_index = 0;
     dataStore = new uint8_t[(numBlocks + numTags) * blkSize];
     dataBlks = new uint8_t*[numBlocks];
-    for (i = 0; i < numBlocks; ++i) {
+    for (unsigned i = 0; i < numBlocks; ++i) {
         dataBlks[i] = &dataStore[data_index];
         freeDataBlock(i);
         data_index += subSize;
@@ -118,15 +116,15 @@ IIC::IIC(IIC::Params &params) :
     // allocate and init tag store
     tagStore = new IICTag[numTags];
 
-    int blkIndex = 0;
+    unsigned blkIndex = 0;
     // allocate and init sets
     sets = new IICSet[hashSets];
-    for (i = 0; i < hashSets; ++i) {
+    for (unsigned i = 0; i < hashSets; ++i) {
         sets[i].assoc = assoc;
         sets[i].tags = new IICTag*[assoc];
         sets[i].chain_ptr = tagNull;
 
-        for (int j = 0; j < assoc; ++j) {
+        for (unsigned j = 0; j < assoc; ++j) {
             IICTag *tag = &tagStore[blkIndex++];
             tag->chain_ptr = tagNull;
             tag->data_ptr.resize(numSub);
@@ -142,7 +140,7 @@ IIC::IIC(IIC::Params &params) :
 
     assert(blkIndex == primaryBound);
 
-    for (i = primaryBound; i < tagNull; i++) {
+    for (unsigned i = primaryBound; i < tagNull; i++) {
         tagStore[i].chain_ptr = i+1;
         //setup data ptrs to subblocks
         tagStore[i].data_ptr.resize(numSub);
@@ -162,6 +160,7 @@ IIC::~IIC()
     delete [] dataStore;
     delete [] tagStore;
     delete [] sets;
+    delete [] dataBlks;
 }
 
 /* register cache stats */
@@ -189,7 +188,7 @@ IIC::regStats(const string &name)
         .flags(pdf)
         ;
 
-    repl->regStats(name);
+    repl->regStatsWithSuffix(name);
 
     if (PROFILE_IIC)
         setAccess
@@ -221,11 +220,11 @@ IIC::regStats(const string &name)
 
 
 IICTag*
-IIC::findBlock(Addr addr, int &lat)
+IIC::accessBlock(Addr addr, Cycles &lat, int context_src)
 {
     Addr tag = extractTag(addr);
     unsigned set = hash(addr);
-    int set_lat;
+    Cycles set_lat;
 
     unsigned long chain_ptr = tagNull;
 
@@ -233,11 +232,11 @@ IIC::findBlock(Addr addr, int &lat)
         setAccess.sample(set);
 
     IICTag *tag_ptr = sets[set].findTag(tag, chain_ptr);
-    set_lat = 1;
+    set_lat = Cycles(1);
     if (tag_ptr == NULL && chain_ptr != tagNull) {
         int secondary_depth;
         tag_ptr = secondaryChain(tag, chain_ptr, &secondary_depth);
-        set_lat += secondary_depth;
+        set_lat += Cycles(secondary_depth);
         // set depth for statistics fix this later!!! egh
         sets[set].depth = set_lat;
 
@@ -251,7 +250,7 @@ IIC::findBlock(Addr addr, int &lat)
         }
 
     }
-    set_lat = set_lat * hashDelay + hitLatency;
+    set_lat = Cycles(set_lat * hashDelay + hitLatency);
     if (tag_ptr != NULL) {
         // IIC replacement: if this is not the first element of
         //   list, reorder
@@ -262,8 +261,9 @@ IIC::findBlock(Addr addr, int &lat)
         hitDepthTotal += sets[set].depth;
         tag_ptr->status |= BlkReferenced;
         lat = set_lat;
-        if (tag_ptr->whenReady > curTick && tag_ptr->whenReady - curTick > set_lat) {
-            lat = tag_ptr->whenReady - curTick;
+        if (tag_ptr->whenReady > curTick() &&
+            cache->ticksToCycles(tag_ptr->whenReady - curTick()) > set_lat) {
+            lat = cache->ticksToCycles(tag_ptr->whenReady - curTick());
         }
 
         tag_ptr->refCount += 1;
@@ -297,7 +297,7 @@ IIC::findBlock(Addr addr) const
 
 
 IICTag*
-IIC::findReplacement(Addr addr, PacketList &writebacks)
+IIC::findVictim(Addr addr, PacketList &writebacks)
 {
     DPRINTF(IIC, "Finding Replacement for %x\n", addr);
     unsigned set = hash(addr);
@@ -305,7 +305,7 @@ IIC::findReplacement(Addr addr, PacketList &writebacks)
     unsigned long *tmp_data = new unsigned long[numSub];
 
     // Get a enough subblocks for a full cache line
-    for (int i = 0; i < numSub; ++i){
+    for (unsigned i = 0; i < numSub; ++i){
         tmp_data[i] = getFreeDataBlock(writebacks);
         assert(dataReferenceCount[tmp_data[i]]==0);
     }
@@ -313,7 +313,7 @@ IIC::findReplacement(Addr addr, PacketList &writebacks)
     tag_ptr = getFreeTag(set, writebacks);
 
     tag_ptr->set = set;
-    for (int i=0; i< numSub; ++i) {
+    for (unsigned i = 0; i < numSub; ++i) {
         tag_ptr->data_ptr[i] = tmp_data[i];
         dataReferenceCount[tag_ptr->data_ptr[i]]++;
     }
@@ -339,6 +339,11 @@ IIC::findReplacement(Addr addr, PacketList &writebacks)
     return tag_ptr;
 }
 
+void
+IIC::insertBlock(Addr addr, BlkType* blk, int context_src)
+{
+}
+
 void
 IIC::freeReplacementBlock(PacketList & writebacks)
 {
@@ -346,34 +351,32 @@ IIC::freeReplacementBlock(PacketList & writebacks)
     unsigned long data_ptr;
     /* consult replacement policy */
     tag_ptr = &tagStore[repl->getRepl()];
+    assert(tag_ptr != NULL);
     assert(tag_ptr->isValid());
 
     DPRINTF(Cache, "Replacing %x in IIC: %s\n",
             regenerateBlkAddr(tag_ptr->tag,0),
             tag_ptr->isDirty() ? "writeback" : "clean");
     /* write back replaced block data */
-    if (tag_ptr && (tag_ptr->isValid())) {
-        replacements[0]++;
-        totalRefs += tag_ptr->refCount;
-        ++sampledRefs;
-        tag_ptr->refCount = 0;
+    replacements[0]++;
+    totalRefs += tag_ptr->refCount;
+    ++sampledRefs;
+    tag_ptr->refCount = 0;
 
-        if (tag_ptr->isDirty()) {
+    if (tag_ptr->isDirty()) {
 /*          PacketPtr writeback =
-                buildWritebackReq(regenerateBlkAddr(tag_ptr->tag, 0),
-                                  tag_ptr->req->asid, tag_ptr->xc, blkSize,
-                                  tag_ptr->data,
-                                  tag_ptr->size);
+            buildWritebackReq(regenerateBlkAddr(tag_ptr->tag, 0),
+            tag_ptr->req->asid, tag_ptr->xc, blkSize,
+            tag_ptr->data,
+            tag_ptr->size);
 */
-            Request *writebackReq = new Request(regenerateBlkAddr(tag_ptr->tag, 0),
-                                           blkSize, 0);
-            PacketPtr writeback = new Packet(writebackReq, MemCmd::Writeback,
-                                             -1);
-            writeback->allocate();
-            memcpy(writeback->getPtr<uint8_t>(), tag_ptr->data, blkSize);
-
-            writebacks.push_back(writeback);
-        }
+        Request *writebackReq = new Request(regenerateBlkAddr(tag_ptr->tag, 0),
+                                            blkSize, 0, Request::wbMasterId);
+        PacketPtr writeback = new Packet(writebackReq, MemCmd::Writeback);
+        writeback->allocate();
+        memcpy(writeback->getPtr<uint8_t>(), tag_ptr->data, blkSize);
+
+        writebacks.push_back(writeback);
     }
 
     // free the data blocks
@@ -390,10 +393,8 @@ IIC::freeReplacementBlock(PacketList & writebacks)
 unsigned long
 IIC::getFreeDataBlock(PacketList & writebacks)
 {
-    struct IICTag *tag_ptr;
     unsigned long data_ptr;
 
-    tag_ptr = NULL;
     /* find data block */
     while (blkFreelist.empty()) {
         freeReplacementBlock(writebacks);
@@ -437,7 +438,7 @@ IIC::getFreeTag(int set, PacketList & writebacks)
     tagsInUse++;
     if (!warmedUp && tagsInUse.value() >= warmupBound) {
         warmedUp = true;
-        warmupCycle = curTick;
+        warmupCycle = curTick();
     }
 
     return tag_ptr;
@@ -614,7 +615,7 @@ IIC::secondaryChain(Addr tag, unsigned long chain_ptr,
 }
 
 void
-IIC::invalidateBlk(IIC::BlkType *tag_ptr)
+IIC::invalidate(IIC::BlkType *tag_ptr)
 {
     if (tag_ptr) {
         for (int i = 0; i < tag_ptr->numData; ++i) {
@@ -629,69 +630,17 @@ IIC::invalidateBlk(IIC::BlkType *tag_ptr)
 }
 
 void
-IIC::readData(IICTag *blk, uint8_t *data)
+IIC::clearLocks()
 {
-    assert(blk->size <= trivialSize || blk->numData > 0);
-    int data_size = blk->size;
-    if (data_size > trivialSize) {
-        for (int i = 0; i < blk->numData; ++i){
-            memcpy(data+i*subSize,
-                   &(dataBlks[blk->data_ptr[i]][0]),
-                   (data_size>subSize)?subSize:data_size);
-            data_size -= subSize;
-        }
-    } else {
-        memcpy(data,blk->trivialData,data_size);
-    }
-}
-
-void
-IIC::writeData(IICTag *blk, uint8_t *write_data, int size,
-               PacketList & writebacks)
-{
-    DPRINTF(IIC, "Writing %d bytes to %x\n", size,
-            blk->tag<<tagShift);
-    // Find the number of subblocks needed, (round up)
-    int num_subs = (size + (subSize -1))/subSize;
-    if (size <= trivialSize) {
-        num_subs = 0;
-    }
-    assert(num_subs <= numSub);
-    if (num_subs > blk->numData) {
-        // need to allocate more data blocks
-        for (int i = blk->numData; i < num_subs; ++i){
-            blk->data_ptr[i] = getFreeDataBlock(writebacks);
-            dataReferenceCount[blk->data_ptr[i]] += 1;
-        }
-    } else if (num_subs < blk->numData){
-        // can free data blocks
-        for (int i=num_subs; i < blk->numData; ++i){
-            // decrement reference count and compare to zero
-            if (--dataReferenceCount[blk->data_ptr[i]] == 0) {
-                freeDataBlock(blk->data_ptr[i]);
-            }
-        }
-    }
-
-    blk->numData = num_subs;
-    blk->size = size;
-    assert(size <= trivialSize || blk->numData > 0);
-    if (size > trivialSize){
-        for (int i = 0; i < blk->numData; ++i){
-            memcpy(&dataBlks[blk->data_ptr[i]][0], write_data + i*subSize,
-                   (size>subSize)?subSize:size);
-            size -= subSize;
-        }
-    } else {
-        memcpy(blk->trivialData,write_data,size);
+    for (int i = 0; i < numTags; i++){
+        tagStore[i].clearLoadLocks();
     }
 }
 
-
 void
 IIC::cleanupRefs()
 {
-    for (int i = 0; i < numTags; ++i) {
+    for (unsigned i = 0; i < numTags; ++i) {
         if (tagStore[i].isValid()) {
             totalRefs += tagStore[i].refCount;
             ++sampledRefs;