Get rid of generic CacheTags object (fold back into Cache).
authorSteve Reinhardt <stever@eecs.umich.edu>
Tue, 19 Dec 2006 04:47:12 +0000 (20:47 -0800)
committerSteve Reinhardt <stever@eecs.umich.edu>
Tue, 19 Dec 2006 04:47:12 +0000 (20:47 -0800)
--HG--
extra : convert_revision : 8769bd8cc358ab3cbbdbbcd909b2e0f1515e09da

src/SConscript
src/mem/cache/cache.cc
src/mem/cache/cache.hh
src/mem/cache/cache_builder.cc
src/mem/cache/cache_impl.hh
src/mem/cache/prefetch/ghb_prefetcher.cc
src/mem/cache/prefetch/stride_prefetcher.cc

index f54e1de0de14f4329cbf32df1c4907996a952e86..3149f0e59e3d54d87c835d380628aa5f57f67661 100644 (file)
@@ -118,7 +118,6 @@ base_sources = Split('''
         mem/cache/prefetch/stride_prefetcher.cc
         mem/cache/prefetch/tagged_prefetcher.cc
         mem/cache/tags/base_tags.cc
-        mem/cache/tags/cache_tags.cc
         mem/cache/tags/fa_lru.cc
         mem/cache/tags/iic.cc
         mem/cache/tags/lru.cc
index 29ca09060e61727830cacbf42772179ce7205a41..cb4e7f62e0c69de5e325bc37b1377f7c8ec2ebf3 100644 (file)
@@ -38,8 +38,6 @@
 
 #include "mem/config/cache.hh"
 
-#include "mem/cache/tags/cache_tags.hh"
-
 #if defined(USE_CACHE_LRU)
 #include "mem/cache/tags/lru.hh"
 #endif
 
 
 #if defined(USE_CACHE_FALRU)
-template class Cache<CacheTags<FALRU>, SimpleCoherence>;
-template class Cache<CacheTags<FALRU>, UniCoherence>;
+template class Cache<FALRU, SimpleCoherence>;
+template class Cache<FALRU, UniCoherence>;
 #endif
 
 #if defined(USE_CACHE_IIC)
-template class Cache<CacheTags<IIC>, SimpleCoherence>;
-template class Cache<CacheTags<IIC>, UniCoherence>;
+template class Cache<IIC, SimpleCoherence>;
+template class Cache<IIC, UniCoherence>;
 #endif
 
 #if defined(USE_CACHE_LRU)
-template class Cache<CacheTags<LRU>, SimpleCoherence>;
-template class Cache<CacheTags<LRU>, UniCoherence>;
+template class Cache<LRU, SimpleCoherence>;
+template class Cache<LRU, UniCoherence>;
 #endif
 
 #if defined(USE_CACHE_SPLIT)
-template class Cache<CacheTags<Split>, SimpleCoherence>;
-template class Cache<CacheTags<Split>, UniCoherence>;
+template class Cache<Split, SimpleCoherence>;
+template class Cache<Split, UniCoherence>;
 #endif
 
 #if defined(USE_CACHE_SPLIT_LIFO)
-template class Cache<CacheTags<SplitLIFO>, SimpleCoherence>;
-template class Cache<CacheTags<SplitLIFO>, UniCoherence>;
+template class Cache<SplitLIFO, SimpleCoherence>;
+template class Cache<SplitLIFO, UniCoherence>;
 #endif
 
 #endif //DOXYGEN_SHOULD_SKIP_THIS
index 097b0f513c51a0beafe4cfb1588d0ec8fd81afaa..bd88849deb77852d51ee6f80d233342b82c1f1e5 100644 (file)
 #ifndef __CACHE_HH__
 #define __CACHE_HH__
 
+#include "base/compression/base.hh"
 #include "base/misc.hh" // fatal, panic, and warn
 #include "cpu/smt.hh" // SMT_MAX_THREADS
 
 #include "mem/cache/base_cache.hh"
+#include "mem/cache/cache_blk.hh"
 #include "mem/cache/miss/miss_buffer.hh"
 #include "mem/cache/prefetch/prefetcher.hh"
 
@@ -62,6 +64,8 @@ class Cache : public BaseCache
   public:
     /** Define the type of cache block to use. */
     typedef typename TagStore::BlkType BlkType;
+    /** A typedef for a list of BlkType pointers. */
+    typedef typename TagStore::BlkList BlkList;
 
     bool prefetchAccess;
 
@@ -141,6 +145,156 @@ class Cache : public BaseCache
     PacketPtr invalidatePkt;
     Request *invalidateReq;
 
+    /**
+     * Policy class for performing compression.
+     */
+    CompressionAlgorithm *compressionAlg;
+
+    /**
+     * The block size of this cache. Set to value in the Tags object.
+     */
+    const int16_t blkSize;
+
+    /**
+     * Can this cache should allocate a block on a line-sized write miss.
+     */
+    const bool doFastWrites;
+
+    const bool prefetchMiss;
+
+    /**
+     * Can the data can be stored in a compressed form.
+     */
+    const bool storeCompressed;
+
+    /**
+     * Do we need to compress blocks on writebacks (i.e. because
+     * writeback bus is compressed but storage is not)?
+     */
+    const bool compressOnWriteback;
+
+    /**
+     * The latency of a compression operation.
+     */
+    const int16_t compLatency;
+
+    /**
+     * Should we use an adaptive compression scheme.
+     */
+    const bool adaptiveCompression;
+
+    /**
+     * Do writebacks need to be compressed (i.e. because writeback bus
+     * is compressed), whether or not they're already compressed for
+     * storage.
+     */
+    const bool writebackCompressed;
+
+    /**
+     * Compare the internal block data to the fast access block data.
+     * @param blk The cache block to check.
+     * @return True if the data is the same.
+     */
+    bool verifyData(BlkType *blk);
+
+    /**
+     * Update the internal data of the block. The data to write is assumed to
+     * be in the fast access data.
+     * @param blk The block with the data to update.
+     * @param writebacks A list to store any generated writebacks.
+     * @param compress_block True if we should compress this block
+     */
+    void updateData(BlkType *blk, PacketList &writebacks, bool compress_block);
+
+    /**
+     * Handle a replacement for the given request.
+     * @param blk A pointer to the block, usually NULL
+     * @param pkt The memory request to satisfy.
+     * @param new_state The new state of the block.
+     * @param writebacks A list to store any generated writebacks.
+     */
+    BlkType* doReplacement(BlkType *blk, PacketPtr &pkt,
+                           CacheBlk::State new_state, PacketList &writebacks);
+
+    /**
+     * Does all the processing necessary to perform the provided request.
+     * @param pkt The memory request to perform.
+     * @param lat The latency of the access.
+     * @param writebacks List for any writebacks that need to be performed.
+     * @param update True if the replacement data should be updated.
+     * @return Pointer to the cache block touched by the request. NULL if it
+     * was a miss.
+     */
+    BlkType* handleAccess(PacketPtr &pkt, int & lat,
+                          PacketList & writebacks, bool update = true);
+
+    /**
+     * Populates a cache block and handles all outstanding requests for the
+     * satisfied fill request. This version takes an MSHR pointer and uses its
+     * request to fill the cache block, while repsonding to its targets.
+     * @param blk The cache block if it already exists.
+     * @param mshr The MSHR that contains the fill data and targets to satisfy.
+     * @param new_state The state of the new cache block.
+     * @param writebacks List for any writebacks that need to be performed.
+     * @return Pointer to the new cache block.
+     */
+    BlkType* handleFill(BlkType *blk, MSHR * mshr, CacheBlk::State new_state,
+                        PacketList & writebacks, PacketPtr pkt);
+
+    /**
+     * Populates a cache block and handles all outstanding requests for the
+     * satisfied fill request. This version takes two memory requests. One
+     * contains the fill data, the other is an optional target to satisfy.
+     * Used for Cache::probe.
+     * @param blk The cache block if it already exists.
+     * @param pkt The memory request with the fill data.
+     * @param new_state The state of the new cache block.
+     * @param writebacks List for any writebacks that need to be performed.
+     * @param target The memory request to perform after the fill.
+     * @return Pointer to the new cache block.
+     */
+    BlkType* handleFill(BlkType *blk, PacketPtr &pkt,
+                        CacheBlk::State new_state,
+                        PacketList & writebacks, PacketPtr target = NULL);
+
+    /**
+     * Sets the blk to the new state and handles the given request.
+     * @param blk The cache block being snooped.
+     * @param new_state The new coherence state for the block.
+     * @param pkt The request to satisfy
+     */
+    void handleSnoop(BlkType *blk, CacheBlk::State new_state,
+                     PacketPtr &pkt);
+
+    /**
+     * Sets the blk to the new state.
+     * @param blk The cache block being snooped.
+     * @param new_state The new coherence state for the block.
+     */
+    void handleSnoop(BlkType *blk, CacheBlk::State new_state);
+
+    /**
+     * Create a writeback request for the given block.
+     * @param blk The block to writeback.
+     * @return The writeback request for the block.
+     */
+    PacketPtr writebackBlk(BlkType *blk);
+
+    BlkType* findBlock(Addr addr)
+    {
+        return tags->findBlock(addr);
+    }
+
+    BlkType* findBlock(PacketPtr &pkt)
+    {
+        return tags->findBlock(pkt->getAddr());
+    }
+
+    void invalidateBlk(CacheBlk *blk)
+    {
+        tags->invalidateBlk(tags->regenerateBlkAddr(blk->tag, blk->set));
+    }
+
   public:
 
     class Params
@@ -153,15 +307,38 @@ class Cache : public BaseCache
         Prefetcher<TagStore> *prefetcher;
         bool prefetchAccess;
         int hitLatency;
+        CompressionAlgorithm *compressionAlg;
+        const int16_t blkSize;
+        const bool doFastWrites;
+        const bool prefetchMiss;
+        const bool storeCompressed;
+        const bool compressOnWriteback;
+        const int16_t compLatency;
+        const bool adaptiveCompression;
+        const bool writebackCompressed;
 
         Params(TagStore *_tags, MissBuffer *mq, Coherence *coh,
                BaseCache::Params params,
                Prefetcher<TagStore> *_prefetcher,
-               bool prefetch_access, int hit_latency)
+               bool prefetch_access, int hit_latency,
+               bool do_fast_writes,
+               bool store_compressed, bool adaptive_compression,
+               bool writeback_compressed,
+               CompressionAlgorithm *_compressionAlg, int comp_latency,
+               bool prefetch_miss)
             : tags(_tags), missQueue(mq), coherence(coh),
               baseParams(params),
               prefetcher(_prefetcher), prefetchAccess(prefetch_access),
-              hitLatency(hit_latency)
+              hitLatency(hit_latency),
+              compressionAlg(_compressionAlg),
+              blkSize(_tags->getBlockSize()),
+              doFastWrites(do_fast_writes),
+              prefetchMiss(prefetch_miss),
+              storeCompressed(store_compressed),
+              compressOnWriteback(!store_compressed && writeback_compressed),
+              compLatency(comp_latency),
+              adaptiveCompression(adaptive_compression),
+              writebackCompressed(writeback_compressed)
         {
         }
     };
index 4b1b19718fa4f2cfa6b5c1a11b86f8516bc0c077..e212650f2fab951a25cd82133f538d715931cde5 100644 (file)
@@ -70,9 +70,6 @@
 #include "base/compression/null_compression.hh"
 #include "base/compression/lzss_compression.hh"
 
-// CacheTags Templates
-#include "mem/cache/tags/cache_tags.hh"
-
 // MissQueue Templates
 #include "mem/cache/miss/miss_queue.hh"
 #include "mem/cache/miss/blocking_buffer.hh"
@@ -108,8 +105,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(BaseCache)
     Param<int> tgts_per_mshr;
     Param<int> write_buffers;
     Param<bool> prioritizeRequests;
-//    SimObjectParam<Bus *> in_bus;
-//    SimObjectParam<Bus *> out_bus;
     SimObjectParam<CoherenceProtocol *> protocol;
     Param<Addr> trace_addr;
     Param<int> hash_delay;
@@ -122,7 +117,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(BaseCache)
     Param<int> compression_latency;
     Param<int> subblock_size;
     Param<Counter> max_miss_count;
-//    SimObjectParam<HierParams *> hier;
     VectorParam<Range<Addr> > addr_range;
 //    SimObjectParam<MemTraceWriter *> mem_trace;
     Param<bool> split;
@@ -156,9 +150,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(BaseCache)
     INIT_PARAM_DFLT(write_buffers, "number of write buffers", 8),
     INIT_PARAM_DFLT(prioritizeRequests, "always service demand misses first",
                     false),
-/*    INIT_PARAM_DFLT(in_bus, "incoming bus object", NULL),
-    INIT_PARAM(out_bus, "outgoing bus object"),
-*/
     INIT_PARAM_DFLT(protocol, "coherence protocol to use in the cache", NULL),
     INIT_PARAM_DFLT(trace_addr, "address to trace", 0),
 
@@ -182,10 +173,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(BaseCache)
     INIT_PARAM_DFLT(max_miss_count,
                     "The number of misses to handle before calling exit",
                     0),
-/*    INIT_PARAM_DFLT(hier,
-                    "Hierarchy global variables",
-                    &defaultHierParams),
-*/
     INIT_PARAM_DFLT(addr_range, "The address range in bytes",
                     vector<Range<Addr> >(1,RangeIn((Addr)0, MaxAddr))),
 //    INIT_PARAM_DFLT(mem_trace, "Memory trace to write accesses to", NULL),
@@ -208,47 +195,47 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(BaseCache)
 END_INIT_SIM_OBJECT_PARAMS(BaseCache)
 
 
-#define BUILD_CACHE(t, c) do {                                 \
-        Prefetcher<CacheTags<t> > *pf; \
-        if (pf_policy == "tagged") {      \
-             BUILD_TAGGED_PREFETCHER(t); \
-        }            \
-        else if (pf_policy == "stride") {       \
-             BUILD_STRIDED_PREFETCHER(t); \
-        } \
-        else if (pf_policy == "ghb") {       \
-             BUILD_GHB_PREFETCHER(t); \
-        } \
-        else { \
-             BUILD_NULL_PREFETCHER(t); \
-        } \
-        Cache<CacheTags<t>, c>::Params params(tagStore, mq, coh, \
-                                                       base_params, \
-                                                       pf,  \
-                                                       prefetch_access, hit_latency); \
-        Cache<CacheTags<t>, c> *retval =                       \
-            new Cache<CacheTags<t>, c>(getInstanceName(), params);             \
-return retval;                                                          \
+#define BUILD_CACHE(TAGS, tags, c)                                      \
+    do {                                                                \
+        Prefetcher<TAGS> *pf;                                           \
+        if (pf_policy == "tagged") {                                    \
+            BUILD_TAGGED_PREFETCHER(TAGS);                              \
+        }                                                               \
+        else if (pf_policy == "stride") {                               \
+            BUILD_STRIDED_PREFETCHER(TAGS);                             \
+        }                                                               \
+        else if (pf_policy == "ghb") {                                  \
+            BUILD_GHB_PREFETCHER(TAGS);                                 \
+        }                                                               \
+        else {                                                          \
+            BUILD_NULL_PREFETCHER(TAGS);                                \
+        }                                                               \
+        Cache<TAGS, c>::Params params(tags, mq, coh, base_params,       \
+                                      pf, prefetch_access, hit_latency, \
+                                      true,                             \
+                                      store_compressed,                 \
+                                      adaptive_compression,             \
+                                      compressed_bus,                   \
+                                      compAlg, compression_latency,     \
+                                      prefetch_miss);                   \
+        Cache<TAGS, c> *retval =                                        \
+            new Cache<TAGS, c>(getInstanceName(), params);              \
+        return retval;                                                  \
     } while (0)
 
 #define BUILD_CACHE_PANIC(x) do {                      \
         panic("%s not compiled into M5", x);           \
     } while (0)
 
-#define BUILD_COMPRESSED_CACHE(TAGS, tags, c)                  \
-    do {                                                               \
-        CompressionAlgorithm *compAlg;                                 \
-        if (compressed_bus || store_compressed) {                      \
-            compAlg = new LZSSCompression();                           \
-        } else {                                                       \
-            compAlg = new NullCompression();                           \
-        }                                                              \
-        CacheTags<TAGS> *tagStore =                                    \
-            new CacheTags<TAGS>(tags, compression_latency, true,       \
-                                store_compressed, adaptive_compression,        \
-                                compressed_bus,                                \
-                                compAlg, prefetch_miss);               \
-            BUILD_CACHE(TAGS, c);                                      \
+#define BUILD_COMPRESSED_CACHE(TAGS, tags, c)           \
+    do {                                                \
+        CompressionAlgorithm *compAlg;                  \
+        if (compressed_bus || store_compressed) {       \
+            compAlg = new LZSSCompression();            \
+        } else {                                        \
+            compAlg = new NullCompression();            \
+        }                                               \
+        BUILD_CACHE(TAGS, tags, c);                     \
     } while (0)
 
 #if defined(USE_CACHE_FALRU)
@@ -328,7 +315,7 @@ return retval;                                                          \
 
 #if defined(USE_TAGGED)
 #define BUILD_TAGGED_PREFETCHER(t) pf = new   \
-                TaggedPrefetcher<CacheTags<t> >(prefetcher_size, \
+                TaggedPrefetcher<t >(prefetcher_size, \
                                                         !prefetch_past_page, \
                                                         prefetch_serial_squash, \
                                                         prefetch_cache_check_push, \
@@ -341,7 +328,7 @@ return retval;                                                          \
 
 #if defined(USE_STRIDED)
 #define BUILD_STRIDED_PREFETCHER(t) pf = new  \
-                StridePrefetcher<CacheTags<t> >(prefetcher_size, \
+                StridePrefetcher<t >(prefetcher_size, \
                                                         !prefetch_past_page, \
                                                         prefetch_serial_squash, \
                                                         prefetch_cache_check_push, \
@@ -355,7 +342,7 @@ return retval;                                                          \
 
 #if defined(USE_GHB)
 #define BUILD_GHB_PREFETCHER(t) pf = new  \
-                GHBPrefetcher<CacheTags<t> >(prefetcher_size, \
+                GHBPrefetcher<t >(prefetcher_size, \
                                                      !prefetch_past_page, \
                                                      prefetch_serial_squash, \
                                                      prefetch_cache_check_push, \
@@ -369,7 +356,7 @@ return retval;                                                          \
 
 #if defined(USE_TAGGED)
 #define BUILD_NULL_PREFETCHER(t) pf = new  \
-                TaggedPrefetcher<CacheTags<t> >(prefetcher_size, \
+                TaggedPrefetcher<t >(prefetcher_size, \
                                                         !prefetch_past_page, \
                                                         prefetch_serial_squash, \
                                                         prefetch_cache_check_push, \
index 9f48ff1f38c9b4366aa67dc615ea3837be8d8e7e..1d78b03c749bba0a81deb1287ae13e94d260d603 100644 (file)
@@ -72,10 +72,18 @@ Cache(const std::string &_name,
       prefetchAccess(params.prefetchAccess),
       tags(params.tags), missQueue(params.missQueue),
       coherence(params.coherence), prefetcher(params.prefetcher),
-      hitLatency(params.hitLatency)
+      hitLatency(params.hitLatency),
+      compressionAlg(params.compressionAlg),
+      blkSize(params.blkSize),
+      doFastWrites(params.doFastWrites),
+      prefetchMiss(params.prefetchMiss),
+      storeCompressed(params.storeCompressed),
+      compressOnWriteback(params.compressOnWriteback),
+      compLatency(params.compLatency),
+      adaptiveCompression(params.adaptiveCompression),
+      writebackCompressed(params.writebackCompressed)
 {
     tags->setCache(this);
-    tags->setPrefetcher(prefetcher);
     missQueue->setCache(this);
     missQueue->setPrefetcher(prefetcher);
     coherence->setCache(this);
@@ -97,6 +105,433 @@ Cache<TagStore,Coherence>::regStats()
     prefetcher->regStats(name());
 }
 
+template<class TagStore, class Coherence>
+typename Cache<TagStore,Coherence>::BlkType*
+Cache<TagStore,Coherence>::handleAccess(PacketPtr &pkt, int & lat,
+                                        PacketList & writebacks, bool update)
+{
+    // Set the block offset here
+    int offset = tags->extractBlkOffset(pkt->getAddr());
+
+    BlkType *blk = NULL;
+    if (update) {
+        blk = tags->findBlock(pkt, lat);
+    } else {
+        blk = tags->findBlock(pkt->getAddr());
+        lat = 0;
+    }
+    if (blk != NULL) {
+
+        if (!update) {
+            if (pkt->isWrite()){
+                assert(offset < blkSize);
+                assert(pkt->getSize() <= blkSize);
+                assert(offset+pkt->getSize() <= blkSize);
+                memcpy(blk->data + offset, pkt->getPtr<uint8_t>(),
+                       pkt->getSize());
+            } else if (!(pkt->flags & SATISFIED)) {
+                pkt->flags |= SATISFIED;
+                pkt->result = Packet::Success;
+                assert(offset < blkSize);
+                assert(pkt->getSize() <= blkSize);
+                assert(offset + pkt->getSize() <=blkSize);
+                memcpy(pkt->getPtr<uint8_t>(), blk->data + offset,
+                       pkt->getSize());
+            }
+            return blk;
+        }
+
+        // Hit
+        if (blk->isPrefetch()) {
+            //Signal that this was a hit under prefetch (no need for
+            //use prefetch (only can get here if true)
+            DPRINTF(HWPrefetch, "Hit a block that was prefetched\n");
+            blk->status &= ~BlkHWPrefetched;
+            if (prefetchMiss) {
+                //If we are using the miss stream, signal the
+                //prefetcher otherwise the access stream would have
+                //already signaled this hit
+                prefetcher->handleMiss(pkt, curTick);
+            }
+        }
+
+        if ((pkt->isWrite() && blk->isWritable()) ||
+            (pkt->isRead() && blk->isValid())) {
+
+            // We are satisfying the request
+            pkt->flags |= SATISFIED;
+
+            if (blk->isCompressed()) {
+                // If the data is compressed, need to increase the latency
+                lat += (compLatency/4);
+            }
+
+            bool write_data = false;
+
+            assert(verifyData(blk));
+
+            assert(offset < blkSize);
+            assert(pkt->getSize() <= blkSize);
+            assert(offset+pkt->getSize() <= blkSize);
+
+            if (pkt->isWrite()) {
+                if (blk->checkWrite(pkt->req)) {
+                    write_data = true;
+                    blk->status |= BlkDirty;
+                    memcpy(blk->data + offset, pkt->getPtr<uint8_t>(),
+                           pkt->getSize());
+                }
+            } else {
+                assert(pkt->isRead());
+                if (pkt->req->isLocked()) {
+                    blk->trackLoadLocked(pkt->req);
+                }
+                memcpy(pkt->getPtr<uint8_t>(), blk->data + offset,
+                       pkt->getSize());
+            }
+
+            if (write_data ||
+                (adaptiveCompression && blk->isCompressed()))
+            {
+                // If we wrote data, need to update the internal block
+                // data.
+                updateData(blk, writebacks,
+                           !(adaptiveCompression &&
+                             blk->isReferenced()));
+            }
+        } else {
+            // permission violation, treat it as a miss
+            blk = NULL;
+        }
+    } else {
+        // complete miss (no matching block)
+        if (pkt->req->isLocked() && pkt->isWrite()) {
+            // miss on store conditional... just give up now
+            pkt->req->setScResult(0);
+            pkt->flags |= SATISFIED;
+        }
+    }
+
+    return blk;
+}
+
+template<class TagStore, class Coherence>
+typename Cache<TagStore,Coherence>::BlkType*
+Cache<TagStore,Coherence>::handleFill(BlkType *blk, PacketPtr &pkt,
+                                      CacheBlk::State new_state,
+                                      PacketList & writebacks,
+                                      PacketPtr target)
+{
+#ifndef NDEBUG
+    BlkType *tmp_blk = findBlock(pkt->getAddr());
+    assert(tmp_blk == blk);
+#endif
+    blk = doReplacement(blk, pkt, new_state, writebacks);
+
+
+    if (pkt->isRead()) {
+        memcpy(blk->data, pkt->getPtr<uint8_t>(), blkSize);
+    }
+
+        blk->whenReady = pkt->finishTime;
+
+    // Respond to target, if any
+    if (target) {
+
+        target->flags |= SATISFIED;
+
+        if (target->cmd == Packet::InvalidateReq) {
+            invalidateBlk(blk);
+            blk = NULL;
+        }
+
+        if (blk && (target->isWrite() ? blk->isWritable() : blk->isValid())) {
+            assert(target->isWrite() || target->isRead());
+            assert(target->getOffset(blkSize) + target->getSize() <= blkSize);
+            if (target->isWrite()) {
+                if (blk->checkWrite(pkt->req)) {
+                    blk->status |= BlkDirty;
+                    memcpy(blk->data + target->getOffset(blkSize),
+                           target->getPtr<uint8_t>(), target->getSize());
+                }
+            } else {
+                if (pkt->req->isLocked()) {
+                    blk->trackLoadLocked(pkt->req);
+                }
+                memcpy(target->getPtr<uint8_t>(),
+                       blk->data + target->getOffset(blkSize),
+                       target->getSize());
+            }
+        }
+    }
+
+    if (blk) {
+        // Need to write the data into the block
+        updateData(blk, writebacks, !adaptiveCompression || true);
+    }
+    return blk;
+}
+
+template<class TagStore, class Coherence>
+typename Cache<TagStore,Coherence>::BlkType*
+Cache<TagStore,Coherence>::handleFill(BlkType *blk, MSHR * mshr,
+                                      CacheBlk::State new_state,
+                                      PacketList & writebacks, PacketPtr pkt)
+{
+/*
+#ifndef NDEBUG
+    BlkType *tmp_blk = findBlock(mshr->pkt->getAddr());
+    assert(tmp_blk == blk);
+#endif
+    PacketPtr pkt = mshr->pkt;*/
+    blk = doReplacement(blk, pkt, new_state, writebacks);
+
+    if (pkt->isRead()) {
+        memcpy(blk->data, pkt->getPtr<uint8_t>(), blkSize);
+    }
+
+    blk->whenReady = pkt->finishTime;
+
+
+    // respond to MSHR targets, if any
+
+    // First offset for critical word first calculations
+    int initial_offset = 0;
+
+    if (mshr->hasTargets()) {
+        initial_offset = mshr->getTarget()->getOffset(blkSize);
+    }
+
+    while (mshr->hasTargets()) {
+        PacketPtr target = mshr->getTarget();
+
+        target->flags |= SATISFIED;
+
+        // How many bytes pass the first request is this one
+        int transfer_offset = target->getOffset(blkSize) - initial_offset;
+        if (transfer_offset < 0) {
+            transfer_offset += blkSize;
+        }
+
+        // If critical word (no offset) return first word time
+        Tick completion_time = tags->getHitLatency() +
+            transfer_offset ? pkt->finishTime : pkt->firstWordTime;
+
+        if (target->cmd == Packet::InvalidateReq) {
+            //Mark the blk as invalid now, if it hasn't been already
+            if (blk) {
+                invalidateBlk(blk);
+                blk = NULL;
+            }
+
+            //Also get rid of the invalidate
+            mshr->popTarget();
+
+            DPRINTF(Cache, "Popping off a Invalidate for addr %x\n",
+                    pkt->getAddr());
+
+            continue;
+        }
+
+        if (blk && (target->isWrite() ? blk->isWritable() : blk->isValid())) {
+            assert(target->isWrite() || target->isRead());
+            assert(target->getOffset(blkSize) + target->getSize() <= blkSize);
+            if (target->isWrite()) {
+                if (blk->checkWrite(pkt->req)) {
+                    blk->status |= BlkDirty;
+                    memcpy(blk->data + target->getOffset(blkSize),
+                           target->getPtr<uint8_t>(), target->getSize());
+                }
+            } else {
+                if (pkt->req->isLocked()) {
+                    blk->trackLoadLocked(pkt->req);
+                }
+                memcpy(target->getPtr<uint8_t>(),
+                       blk->data + target->getOffset(blkSize),
+                       target->getSize());
+            }
+        } else {
+            // Invalid access, need to do another request
+            // can occur if block is invalidated, or not correct
+            // permissions
+//            mshr->pkt = pkt;
+            break;
+        }
+        respondToMiss(target, completion_time);
+        mshr->popTarget();
+    }
+
+    if (blk) {
+        // Need to write the data into the block
+        updateData(blk, writebacks, !adaptiveCompression || true);
+    }
+
+    return blk;
+}
+
+
+template<class TagStore, class Coherence>
+void
+Cache<TagStore,Coherence>::handleSnoop(BlkType *blk,
+                                       CacheBlk::State new_state,
+                                       PacketPtr &pkt)
+{
+    //Must have the block to supply
+    assert(blk);
+    // Can only supply data, and if it hasn't already been supllied
+    assert(pkt->isRead());
+    assert(!(pkt->flags & SATISFIED));
+    pkt->flags |= SATISFIED;
+    Addr offset = pkt->getOffset(blkSize);
+    assert(offset < blkSize);
+    assert(pkt->getSize() <= blkSize);
+    assert(offset + pkt->getSize() <=blkSize);
+    memcpy(pkt->getPtr<uint8_t>(), blk->data + offset, pkt->getSize());
+
+    handleSnoop(blk, new_state);
+}
+
+template<class TagStore, class Coherence>
+void
+Cache<TagStore,Coherence>::handleSnoop(BlkType *blk,
+                                       CacheBlk::State new_state)
+{
+    if (blk && blk->status != new_state) {
+        if ((new_state && BlkValid) == 0) {
+            invalidateBlk(blk);
+        } else {
+            assert(new_state >= 0 && new_state < 128);
+            blk->status = new_state;
+        }
+    }
+}
+
+template<class TagStore, class Coherence>
+PacketPtr
+Cache<TagStore,Coherence>::writebackBlk(BlkType *blk)
+{
+    assert(blk && blk->isValid() && blk->isModified());
+    int data_size = blkSize;
+    data_size = blk->size;
+    if (compressOnWriteback) {
+        // not already compressed
+        // need to compress to ship it
+        assert(data_size == blkSize);
+        uint8_t *tmp_data = new uint8_t[blkSize];
+        data_size = compressionAlg->compress(tmp_data,blk->data,
+                                      data_size);
+        delete [] tmp_data;
+    }
+
+/*    PacketPtr writeback =
+        buildWritebackReq(tags->regenerateBlkAddr(blk->tag, blk->set),
+                          blk->asid, blkSize,
+                          blk->data, data_size);
+*/
+
+    Request *writebackReq =
+        new Request(tags->regenerateBlkAddr(blk->tag, blk->set), blkSize, 0);
+    PacketPtr writeback = new Packet(writebackReq, Packet::Writeback, -1);
+    writeback->allocate();
+    memcpy(writeback->getPtr<uint8_t>(),blk->data,blkSize);
+
+    blk->status &= ~BlkDirty;
+    return writeback;
+}
+
+
+template<class TagStore, class Coherence>
+bool
+Cache<TagStore,Coherence>::verifyData(BlkType *blk)
+{
+    bool retval;
+    // The data stored in the blk
+    uint8_t *blk_data = new uint8_t[blkSize];
+    tags->readData(blk, blk_data);
+    // Pointer for uncompressed data, assumed uncompressed
+    uint8_t *tmp_data = blk_data;
+    // The size of the data being stored, assumed uncompressed
+    int data_size = blkSize;
+
+    // If the block is compressed need to uncompress to access
+    if (blk->isCompressed()){
+        // Allocate new storage for the data
+        tmp_data = new uint8_t[blkSize];
+        data_size = compressionAlg->uncompress(tmp_data,blk_data, blk->size);
+        assert(data_size == blkSize);
+        // Don't need to keep blk_data around
+        delete [] blk_data;
+    } else {
+        assert(blkSize == blk->size);
+    }
+
+    retval = memcmp(tmp_data, blk->data, blkSize) == 0;
+    delete [] tmp_data;
+    return retval;
+}
+
+template<class TagStore, class Coherence>
+void
+Cache<TagStore,Coherence>::updateData(BlkType *blk, PacketList &writebacks,
+                                        bool compress_block)
+{
+    if (storeCompressed && compress_block) {
+        uint8_t *comp_data = new uint8_t[blkSize];
+        int new_size = compressionAlg->compress(comp_data, blk->data, blkSize);
+        if (new_size > (blkSize - tags->getSubBlockSize())){
+            // no benefit to storing it compressed
+            blk->status &= ~BlkCompressed;
+            tags->writeData(blk, blk->data, blkSize,
+                          writebacks);
+        } else {
+            // Store the data compressed
+            blk->status |= BlkCompressed;
+            tags->writeData(blk, comp_data, new_size,
+                          writebacks);
+        }
+        delete [] comp_data;
+    } else {
+        blk->status &= ~BlkCompressed;
+        tags->writeData(blk, blk->data, blkSize, writebacks);
+    }
+}
+
+template<class TagStore, class Coherence>
+typename Cache<TagStore,Coherence>::BlkType*
+Cache<TagStore,Coherence>::doReplacement(BlkType *blk, PacketPtr &pkt,
+                                         CacheBlk::State new_state,
+                                         PacketList &writebacks)
+{
+    if (blk == NULL) {
+        // need to do a replacement
+        BlkList compress_list;
+        blk = tags->findReplacement(pkt, writebacks, compress_list);
+        while (adaptiveCompression && !compress_list.empty()) {
+            updateData(compress_list.front(), writebacks, true);
+            compress_list.pop_front();
+        }
+        if (blk->isValid()) {
+            DPRINTF(Cache, "replacement: replacing %x with %x: %s\n",
+                    tags->regenerateBlkAddr(blk->tag,blk->set), pkt->getAddr(),
+                    (blk->isModified()) ? "writeback" : "clean");
+
+            if (blk->isModified()) {
+                // Need to write the data back
+                writebacks.push_back(writebackBlk(blk));
+            }
+        }
+        blk->tag = tags->extractTag(pkt->getAddr(), blk);
+    } else {
+        // must be a status change
+        // assert(blk->status != new_state);
+        if (blk->status == new_state) warn("Changing state to same value\n");
+    }
+
+    blk->status = new_state;
+    return blk;
+}
+
+
 template<class TagStore, class Coherence>
 bool
 Cache<TagStore,Coherence>::access(PacketPtr &pkt)
@@ -112,7 +547,7 @@ Cache<TagStore,Coherence>::access(PacketPtr &pkt)
         prefetcher->handleMiss(pkt, curTick);
     }
     if (!pkt->req->isUncacheable()) {
-        blk = tags->handleAccess(pkt, lat, writebacks);
+        blk = handleAccess(pkt, lat, writebacks);
     } else {
         size = pkt->getSize();
     }
@@ -130,7 +565,7 @@ Cache<TagStore,Coherence>::access(PacketPtr &pkt)
                 warn("WriteInv doing a fastallocate"
                      "with an outstanding miss to the same address\n");
             }
-            blk = tags->handleFill(NULL, pkt, BlkValid | BlkWritable,
+            blk = handleFill(NULL, pkt, BlkValid | BlkWritable,
                                    writebacks);
             ++fastWrites;
         }
@@ -195,7 +630,7 @@ Cache<TagStore,Coherence>::getPacket()
         if (!pkt->req->isUncacheable()) {
             if (pkt->cmd == Packet::HardPFReq)
                 misses[Packet::HardPFReq][0/*pkt->req->getThreadNum()*/]++;
-            BlkType *blk = tags->findBlock(pkt);
+            BlkType *blk = findBlock(pkt);
             Packet::Command cmd = coherence->getBusCmd(pkt->cmd,
                                               (blk)? blk->status : 0);
             missQueue->setBusCmd(pkt, cmd);
@@ -224,7 +659,7 @@ Cache<TagStore,Coherence>::sendResult(PacketPtr &pkt, MSHR* mshr,
         if (upgrade) {
             assert(pkt);  //Upgrades need to be fixed
             pkt->flags &= ~CACHE_LINE_FILL;
-            BlkType *blk = tags->findBlock(pkt);
+            BlkType *blk = findBlock(pkt);
             CacheBlk::State old_state = (blk) ? blk->status : 0;
             CacheBlk::State new_state = coherence->getNewState(pkt,old_state);
             if (old_state != new_state)
@@ -233,7 +668,7 @@ Cache<TagStore,Coherence>::sendResult(PacketPtr &pkt, MSHR* mshr,
             //Set the state on the upgrade
             memcpy(pkt->getPtr<uint8_t>(), blk->data, blkSize);
             PacketList writebacks;
-            tags->handleFill(blk, mshr, new_state, writebacks, pkt);
+            handleFill(blk, mshr, new_state, writebacks, pkt);
             assert(writebacks.empty());
             missQueue->handleResponse(pkt, curTick + hitLatency);
         }
@@ -275,7 +710,7 @@ Cache<TagStore,Coherence>::handleResponse(PacketPtr &pkt)
         if (pkt->isCacheFill() && !pkt->isNoAllocate()) {
             DPRINTF(Cache, "Block for addr %x being updated in Cache\n",
                     pkt->getAddr());
-            blk = tags->findBlock(pkt);
+            blk = findBlock(pkt);
             CacheBlk::State old_state = (blk) ? blk->status : 0;
             PacketList writebacks;
             CacheBlk::State new_state = coherence->getNewState(pkt,old_state);
@@ -284,7 +719,7 @@ Cache<TagStore,Coherence>::handleResponse(PacketPtr &pkt)
                         "state %i to %i\n",
                         pkt->getAddr(),
                         old_state, new_state);
-            blk = tags->handleFill(blk, (MSHR*)pkt->senderState,
+            blk = handleFill(blk, (MSHR*)pkt->senderState,
                                    new_state, writebacks, pkt);
             while (!writebacks.empty()) {
                     missQueue->doWriteback(writebacks.front());
@@ -332,7 +767,7 @@ Cache<TagStore,Coherence>::snoop(PacketPtr &pkt)
     }
 
     Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1));
-    BlkType *blk = tags->findBlock(pkt);
+    BlkType *blk = findBlock(pkt);
     MSHR *mshr = missQueue->findMSHR(blk_addr);
     if (coherence->hasProtocol() || pkt->isInvalidate()) {
         //@todo Move this into handle bus req
@@ -435,7 +870,7 @@ Cache<TagStore,Coherence>::snoop(PacketPtr &pkt)
                 "now supplying data, new state is %i\n",
                 pkt->cmdString(), blk_addr, new_state);
 
-        tags->handleSnoop(blk, new_state, pkt);
+        handleSnoop(blk, new_state, pkt);
         respondToSnoop(pkt, curTick + hitLatency);
         return;
     }
@@ -443,7 +878,7 @@ Cache<TagStore,Coherence>::snoop(PacketPtr &pkt)
         DPRINTF(Cache, "Cache snooped a %s request for addr %x, "
                 "new state is %i\n", pkt->cmdString(), blk_addr, new_state);
 
-    tags->handleSnoop(blk, new_state);
+    handleSnoop(blk, new_state);
 }
 
 template<class TagStore, class Coherence>
@@ -501,7 +936,7 @@ Cache<TagStore,Coherence>::probe(PacketPtr &pkt, bool update,
     PacketList writebacks;
     int lat;
 
-    BlkType *blk = tags->handleAccess(pkt, lat, writebacks, update);
+    BlkType *blk = handleAccess(pkt, lat, writebacks, update);
 
     DPRINTF(Cache, "%s %x %s\n", pkt->cmdString(),
             pkt->getAddr(), (blk) ? "hit" : "miss");
@@ -557,7 +992,7 @@ Cache<TagStore,Coherence>::probe(PacketPtr &pkt, bool update,
         if (!pkt->req->isUncacheable() /*Uncacheables just go through*/
             && (pkt->cmd != Packet::Writeback)/*Writebacks on miss fall through*/) {
                 // Fetch the cache block to fill
-            BlkType *blk = tags->findBlock(pkt);
+            BlkType *blk = findBlock(pkt);
             Packet::Command temp_cmd = coherence->getBusCmd(pkt->cmd,
                                                             (blk)? blk->status : 0);
 
@@ -593,7 +1028,7 @@ return 0;
                 DPRINTF(Cache, "Block for blk addr %x moving from state "
                         "%i to %i\n", busPkt->getAddr(), old_state, new_state);
 
-            tags->handleFill(blk, busPkt, new_state, writebacks, pkt);
+            handleFill(blk, busPkt, new_state, writebacks, pkt);
             //Free the packet
             delete busPkt;
 
@@ -639,7 +1074,7 @@ Cache<TagStore,Coherence>::snoopProbe(PacketPtr &pkt)
     }
 
     Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1));
-    BlkType *blk = tags->findBlock(pkt);
+    BlkType *blk = findBlock(pkt);
     MSHR *mshr = missQueue->findMSHR(blk_addr);
     CacheBlk::State new_state = 0;
     bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state);
@@ -648,14 +1083,14 @@ Cache<TagStore,Coherence>::snoopProbe(PacketPtr &pkt)
                 "now supplying data, new state is %i\n",
                 pkt->cmdString(), blk_addr, new_state);
 
-            tags->handleSnoop(blk, new_state, pkt);
+            handleSnoop(blk, new_state, pkt);
             return hitLatency;
     }
     if (blk)
         DPRINTF(Cache, "Cache snooped a %s request for addr %x, "
                 "new state is %i\n",
                     pkt->cmdString(), blk_addr, new_state);
-    tags->handleSnoop(blk, new_state);
+    handleSnoop(blk, new_state);
     return 0;
 }
 
index a6c4191133fe42e24ae26f7b3c6417c60466d2ce..7d537641eb8eb4034ccaf05bcbc19cbbdae680d1 100644 (file)
@@ -34,8 +34,6 @@
  * GHB Prefetcher template instantiations.
  */
 
-#include "mem/cache/tags/cache_tags.hh"
-
 #include "mem/cache/tags/lru.hh"
 
 #include "mem/cache/prefetch/ghb_prefetcher.hh"
@@ -43,6 +41,6 @@
 // Template Instantiations
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 
-template class GHBPrefetcher<CacheTags<LRU> >;
+template class GHBPrefetcher<LRU >;
 
 #endif //DOXYGEN_SHOULD_SKIP_THIS
index 2204871cc2075acc15d4d5bacb1f29643d42e56b..847f2979ea5ac1bdc17b986ec40ba5897774936b 100644 (file)
@@ -34,8 +34,6 @@
  * Stride Prefetcher template instantiations.
  */
 
-#include "mem/cache/tags/cache_tags.hh"
-
 #include "mem/cache/tags/lru.hh"
 
 #include "mem/cache/prefetch/stride_prefetcher.hh"
@@ -43,6 +41,6 @@
 // Template Instantiations
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 
-template class StridePrefetcher<CacheTags<LRU> >;
+template class StridePrefetcher<LRU >;
 
 #endif //DOXYGEN_SHOULD_SKIP_THIS