cache.hh revision 4458:d43aab911e6e
1/* 2 * Copyright (c) 2002-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Erik Hallnor 29 * Dave Greene 30 * Steve Reinhardt 31 * Ron Dreslinski 32 */ 33 34/** 35 * @file 36 * Describes a cache based on template policies. 37 */ 38 39#ifndef __CACHE_HH__ 40#define __CACHE_HH__ 41 42#include "base/compression/base.hh" 43#include "base/misc.hh" // fatal, panic, and warn 44#include "cpu/smt.hh" // SMT_MAX_THREADS 45 46#include "mem/cache/base_cache.hh" 47#include "mem/cache/cache_blk.hh" 48#include "mem/cache/miss/miss_buffer.hh" 49 50#include "sim/eventq.hh" 51 52//Forward decleration 53class MSHR; 54class BasePrefetcher; 55 56/** 57 * A template-policy based cache. The behavior of the cache can be altered by 58 * supplying different template policies. TagStore handles all tag and data 59 * storage @sa TagStore. Buffering handles all misses and writes/writebacks 60 * @sa MissQueue. Coherence handles all coherence policy details @sa 61 * UniCoherence, SimpleMultiCoherence. 62 */ 63template <class TagStore, class Coherence> 64class Cache : public BaseCache 65{ 66 public: 67 /** Define the type of cache block to use. */ 68 typedef typename TagStore::BlkType BlkType; 69 /** A typedef for a list of BlkType pointers. */ 70 typedef typename TagStore::BlkList BlkList; 71 72 bool prefetchAccess; 73 74 protected: 75 76 class CpuSidePort : public CachePort 77 { 78 public: 79 CpuSidePort(const std::string &_name, 80 Cache<TagStore,Coherence> *_cache); 81 82 // BaseCache::CachePort just has a BaseCache *; this function 83 // lets us get back the type info we lost when we stored the 84 // cache pointer there. 85 Cache<TagStore,Coherence> *myCache() { 86 return static_cast<Cache<TagStore,Coherence> *>(cache); 87 } 88 89 void processRequestEvent(); 90 void processResponseEvent(); 91 92 virtual bool recvTiming(PacketPtr pkt); 93 94 virtual void recvRetry(); 95 96 virtual Tick recvAtomic(PacketPtr pkt); 97 98 virtual void recvFunctional(PacketPtr pkt); 99 100 typedef EventWrapper<CpuSidePort, &CpuSidePort::processResponseEvent> 101 ResponseEvent; 102 103 typedef EventWrapper<CpuSidePort, &CpuSidePort::processRequestEvent> 104 RequestEvent; 105 106 virtual void scheduleRequestEvent(Tick t) { 107 new RequestEvent(this, t); 108 } 109 }; 110 111 class MemSidePort : public CachePort 112 { 113 public: 114 MemSidePort(const std::string &_name, 115 Cache<TagStore,Coherence> *_cache); 116 117 // BaseCache::CachePort just has a BaseCache *; this function 118 // lets us get back the type info we lost when we stored the 119 // cache pointer there. 120 Cache<TagStore,Coherence> *myCache() { 121 return static_cast<Cache<TagStore,Coherence> *>(cache); 122 } 123 124 void processRequestEvent(); 125 void processResponseEvent(); 126 127 virtual bool recvTiming(PacketPtr pkt); 128 129 virtual void recvRetry(); 130 131 virtual Tick recvAtomic(PacketPtr pkt); 132 133 virtual void recvFunctional(PacketPtr pkt); 134 135 typedef EventWrapper<MemSidePort, &MemSidePort::processResponseEvent> 136 ResponseEvent; 137 138 typedef EventWrapper<MemSidePort, &MemSidePort::processRequestEvent> 139 RequestEvent; 140 141 virtual void scheduleRequestEvent(Tick t) { 142 new RequestEvent(this, t); 143 } 144 }; 145 146 /** Tag and data Storage */ 147 TagStore *tags; 148 /** Miss and Writeback handler */ 149 MissBuffer *missQueue; 150 /** Coherence protocol. */ 151 Coherence *coherence; 152 153 /** Prefetcher */ 154 BasePrefetcher *prefetcher; 155 156 /** 157 * The clock ratio of the outgoing bus. 158 * Used for calculating critical word first. 159 */ 160 int busRatio; 161 162 /** 163 * The bus width in bytes of the outgoing bus. 164 * Used for calculating critical word first. 165 */ 166 int busWidth; 167 168 /** 169 * The latency of a hit in this device. 170 */ 171 int hitLatency; 172 173 /** 174 * A permanent mem req to always be used to cause invalidations. 175 * Used to append to target list, to cause an invalidation. 176 */ 177 PacketPtr invalidatePkt; 178 Request *invalidateReq; 179 180 /** 181 * Policy class for performing compression. 182 */ 183 CompressionAlgorithm *compressionAlg; 184 185 /** 186 * The block size of this cache. Set to value in the Tags object. 187 */ 188 const int16_t blkSize; 189 190 /** 191 * Can this cache should allocate a block on a line-sized write miss. 192 */ 193 const bool doFastWrites; 194 195 const bool prefetchMiss; 196 197 /** 198 * Can the data can be stored in a compressed form. 199 */ 200 const bool storeCompressed; 201 202 /** 203 * Do we need to compress blocks on writebacks (i.e. because 204 * writeback bus is compressed but storage is not)? 205 */ 206 const bool compressOnWriteback; 207 208 /** 209 * The latency of a compression operation. 210 */ 211 const int16_t compLatency; 212 213 /** 214 * Should we use an adaptive compression scheme. 215 */ 216 const bool adaptiveCompression; 217 218 /** 219 * Do writebacks need to be compressed (i.e. because writeback bus 220 * is compressed), whether or not they're already compressed for 221 * storage. 222 */ 223 const bool writebackCompressed; 224 225 /** 226 * Compare the internal block data to the fast access block data. 227 * @param blk The cache block to check. 228 * @return True if the data is the same. 229 */ 230 bool verifyData(BlkType *blk); 231 232 /** 233 * Update the internal data of the block. The data to write is assumed to 234 * be in the fast access data. 235 * @param blk The block with the data to update. 236 * @param writebacks A list to store any generated writebacks. 237 * @param compress_block True if we should compress this block 238 */ 239 void updateData(BlkType *blk, PacketList &writebacks, bool compress_block); 240 241 /** 242 * Handle a replacement for the given request. 243 * @param blk A pointer to the block, usually NULL 244 * @param pkt The memory request to satisfy. 245 * @param new_state The new state of the block. 246 * @param writebacks A list to store any generated writebacks. 247 */ 248 BlkType* doReplacement(BlkType *blk, PacketPtr &pkt, 249 CacheBlk::State new_state, PacketList &writebacks); 250 251 /** 252 * Does all the processing necessary to perform the provided request. 253 * @param pkt The memory request to perform. 254 * @param lat The latency of the access. 255 * @param writebacks List for any writebacks that need to be performed. 256 * @param update True if the replacement data should be updated. 257 * @return Pointer to the cache block touched by the request. NULL if it 258 * was a miss. 259 */ 260 BlkType* handleAccess(PacketPtr &pkt, int & lat, 261 PacketList & writebacks, bool update = true); 262 263 264 /** 265 *Handle doing the Compare and Swap function for SPARC. 266 */ 267 void cmpAndSwap(BlkType *blk, PacketPtr &pkt); 268 269 /** 270 * Populates a cache block and handles all outstanding requests for the 271 * satisfied fill request. This version takes an MSHR pointer and uses its 272 * request to fill the cache block, while repsonding to its targets. 273 * @param blk The cache block if it already exists. 274 * @param mshr The MSHR that contains the fill data and targets to satisfy. 275 * @param new_state The state of the new cache block. 276 * @param writebacks List for any writebacks that need to be performed. 277 * @return Pointer to the new cache block. 278 */ 279 BlkType* handleFill(BlkType *blk, MSHR * mshr, CacheBlk::State new_state, 280 PacketList & writebacks, PacketPtr pkt); 281 282 /** 283 * Populates a cache block and handles all outstanding requests for the 284 * satisfied fill request. This version takes two memory requests. One 285 * contains the fill data, the other is an optional target to satisfy. 286 * Used for Cache::probe. 287 * @param blk The cache block if it already exists. 288 * @param pkt The memory request with the fill data. 289 * @param new_state The state of the new cache block. 290 * @param writebacks List for any writebacks that need to be performed. 291 * @param target The memory request to perform after the fill. 292 * @return Pointer to the new cache block. 293 */ 294 BlkType* handleFill(BlkType *blk, PacketPtr &pkt, 295 CacheBlk::State new_state, 296 PacketList & writebacks, PacketPtr target = NULL); 297 298 /** 299 * Sets the blk to the new state and handles the given request. 300 * @param blk The cache block being snooped. 301 * @param new_state The new coherence state for the block. 302 * @param pkt The request to satisfy 303 */ 304 void handleSnoop(BlkType *blk, CacheBlk::State new_state, 305 PacketPtr &pkt); 306 307 /** 308 * Sets the blk to the new state. 309 * @param blk The cache block being snooped. 310 * @param new_state The new coherence state for the block. 311 */ 312 void handleSnoop(BlkType *blk, CacheBlk::State new_state); 313 314 /** 315 * Create a writeback request for the given block. 316 * @param blk The block to writeback. 317 * @return The writeback request for the block. 318 */ 319 PacketPtr writebackBlk(BlkType *blk); 320 321 public: 322 323 class Params 324 { 325 public: 326 TagStore *tags; 327 MissBuffer *missQueue; 328 Coherence *coherence; 329 BaseCache::Params baseParams; 330 BasePrefetcher*prefetcher; 331 bool prefetchAccess; 332 int hitLatency; 333 CompressionAlgorithm *compressionAlg; 334 const int16_t blkSize; 335 const bool doFastWrites; 336 const bool prefetchMiss; 337 const bool storeCompressed; 338 const bool compressOnWriteback; 339 const int16_t compLatency; 340 const bool adaptiveCompression; 341 const bool writebackCompressed; 342 343 Params(TagStore *_tags, MissBuffer *mq, Coherence *coh, 344 BaseCache::Params params, 345 BasePrefetcher *_prefetcher, 346 bool prefetch_access, int hit_latency, 347 bool do_fast_writes, 348 bool store_compressed, bool adaptive_compression, 349 bool writeback_compressed, 350 CompressionAlgorithm *_compressionAlg, int comp_latency, 351 bool prefetch_miss) 352 : tags(_tags), missQueue(mq), coherence(coh), 353 baseParams(params), 354 prefetcher(_prefetcher), prefetchAccess(prefetch_access), 355 hitLatency(hit_latency), 356 compressionAlg(_compressionAlg), 357 blkSize(_tags->getBlockSize()), 358 doFastWrites(do_fast_writes), 359 prefetchMiss(prefetch_miss), 360 storeCompressed(store_compressed), 361 compressOnWriteback(!store_compressed && writeback_compressed), 362 compLatency(comp_latency), 363 adaptiveCompression(adaptive_compression), 364 writebackCompressed(writeback_compressed) 365 { 366 } 367 }; 368 369 /** Instantiates a basic cache object. */ 370 Cache(const std::string &_name, Params ¶ms); 371 372 virtual Port *getPort(const std::string &if_name, int idx = -1); 373 virtual void deletePortRefs(Port *p); 374 375 void regStats(); 376 377 /** 378 * Performs the access specified by the request. 379 * @param pkt The request to perform. 380 * @return The result of the access. 381 */ 382 bool access(PacketPtr &pkt); 383 384 /** 385 * Selects a request to send on the bus. 386 * @return The memory request to service. 387 */ 388 PacketPtr getPacket(); 389 390 /** 391 * Was the request was sent successfully? 392 * @param pkt The request. 393 * @param success True if the request was sent successfully. 394 */ 395 void sendResult(PacketPtr &pkt, MSHR* mshr, bool success); 396 397 /** 398 * Handles a response (cache line fill/write ack) from the bus. 399 * @param pkt The request being responded to. 400 */ 401 void handleResponse(PacketPtr &pkt); 402 403 /** 404 * Snoops bus transactions to maintain coherence. 405 * @param pkt The current bus transaction. 406 */ 407 void snoop(PacketPtr &pkt); 408 409 void snoopResponse(PacketPtr &pkt); 410 411 /** 412 * Squash all requests associated with specified thread. 413 * intended for use by I-cache. 414 * @param threadNum The thread to squash. 415 */ 416 void squash(int threadNum) 417 { 418 missQueue->squash(threadNum); 419 } 420 421 /** 422 * Return the number of outstanding misses in a Cache. 423 * Default returns 0. 424 * 425 * @retval unsigned The number of missing still outstanding. 426 */ 427 unsigned outstandingMisses() const 428 { 429 return missQueue->getMisses(); 430 } 431 432 /** 433 * Perform the access specified in the request and return the estimated 434 * time of completion. This function can either update the hierarchy state 435 * or just perform the access wherever the data is found depending on the 436 * state of the update flag. 437 * @param pkt The memory request to satisfy 438 * @param update If true, update the hierarchy, otherwise just perform the 439 * request. 440 * @return The estimated completion time. 441 */ 442 Tick probe(PacketPtr &pkt, bool update, CachePort * otherSidePort); 443 444 /** 445 * Snoop for the provided request in the cache and return the estimated 446 * time of completion. 447 * @todo Can a snoop probe not change state? 448 * @param pkt The memory request to satisfy 449 * @param update If true, update the hierarchy, otherwise just perform the 450 * request. 451 * @return The estimated completion time. 452 */ 453 Tick snoopProbe(PacketPtr &pkt); 454 455 bool inCache(Addr addr) { 456 return (tags->findBlock(addr) != 0); 457 } 458 459 bool inMissQueue(Addr addr) { 460 return (missQueue->findMSHR(addr) != 0); 461 } 462}; 463 464#endif // __CACHE_HH__ 465