base.hh revision 4626
111515Sandreas.sandberg@arm.com/* 211515Sandreas.sandberg@arm.com * Copyright (c) 2003-2005 The Regents of The University of Michigan 38721SN/A * All rights reserved. 48721SN/A * 57513SN/A * Redistribution and use in source and binary forms, with or without 611960Sgabeblack@google.com * modification, are permitted provided that the following conditions are 711960Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 811960Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 911960Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 1011219Snilay@cs.wisc.edu * notice, this list of conditions and the following disclaimer in the 1111570SCurtis.Dunham@arm.com * documentation and/or other materials provided with the distribution; 1211570SCurtis.Dunham@arm.com * neither the name of the copyright holders nor the names of its 137513SN/A * contributors may be used to endorse or promote products derived from 147513SN/A * this software without specific prior written permission. 157513SN/A * 167513SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 177513SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 187513SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 197513SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 207513SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 217513SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 227513SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 237513SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 247513SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 257513SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 267513SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2711960Sgabeblack@google.com * 28 * Authors: Erik Hallnor 29 * Steve Reinhardt 30 * Ron Dreslinski 31 */ 32 33/** 34 * @file 35 * Declares a basic cache interface BaseCache. 36 */ 37 38#ifndef __BASE_CACHE_HH__ 39#define __BASE_CACHE_HH__ 40 41#include <vector> 42#include <string> 43#include <list> 44#include <inttypes.h> 45 46#include "base/misc.hh" 47#include "base/statistics.hh" 48#include "base/trace.hh" 49#include "mem/cache/miss/mshr_queue.hh" 50#include "mem/mem_object.hh" 51#include "mem/packet.hh" 52#include "mem/tport.hh" 53#include "mem/request.hh" 54#include "sim/eventq.hh" 55#include "sim/sim_exit.hh" 56 57/** 58 * Reasons for Caches to be Blocked. 59 */ 60enum BlockedCause{ 61 Blocked_NoMSHRs, 62 Blocked_NoTargets, 63 Blocked_NoWBBuffers, 64 Blocked_Coherence, 65 NUM_BLOCKED_CAUSES 66}; 67 68/** 69 * Reasons for cache to request a bus. 70 */ 71enum RequestCause{ 72 Request_MSHR, 73 Request_WB, 74 Request_Coherence, 75 Request_PF 76}; 77 78class MSHR; 79/** 80 * A basic cache interface. Implements some common functions for speed. 81 */ 82class BaseCache : public MemObject 83{ 84 class CachePort : public SimpleTimingPort 85 { 86 public: 87 BaseCache *cache; 88 89 protected: 90 Event *responseEvent; 91 92 CachePort(const std::string &_name, BaseCache *_cache); 93 94 virtual void recvStatusChange(Status status); 95 96 virtual int deviceBlockSize(); 97 98 bool recvRetryCommon(); 99 100 public: 101 void setOtherPort(CachePort *_otherPort) { otherPort = _otherPort; } 102 103 void setBlocked(); 104 105 void clearBlocked(); 106 107 void checkAndSendFunctional(PacketPtr pkt); 108 109 CachePort *otherPort; 110 111 bool blocked; 112 113 bool waitingOnRetry; 114 115 bool mustSendRetry; 116 117 /** 118 * Bit vector for the outstanding requests for the master interface. 119 */ 120 uint8_t requestCauses; 121 122 bool isBusRequested() { return requestCauses != 0; } 123 124 void requestBus(RequestCause cause, Tick time) 125 { 126 DPRINTF(Cache, "Asserting bus request for cause %d\n", cause); 127 if (!isBusRequested() && !waitingOnRetry) { 128 assert(!sendEvent->scheduled()); 129 sendEvent->schedule(time); 130 } 131 requestCauses |= (1 << cause); 132 } 133 134 void deassertBusRequest(RequestCause cause) 135 { 136 DPRINTF(Cache, "Deasserting bus request for cause %d\n", cause); 137 requestCauses &= ~(1 << cause); 138 } 139 140 void respond(PacketPtr pkt, Tick time) { 141 schedSendTiming(pkt, time); 142 } 143 }; 144 145 public: //Made public so coherence can get at it. 146 CachePort *cpuSidePort; 147 CachePort *memSidePort; 148 149 protected: 150 151 /** Miss status registers */ 152 MSHRQueue mshrQueue; 153 154 /** Write/writeback buffer */ 155 MSHRQueue writeBuffer; 156 157 /** Block size of this cache */ 158 const int blkSize; 159 160 /** The number of targets for each MSHR. */ 161 const int numTarget; 162 163 /** Increasing order number assigned to each incoming request. */ 164 uint64_t order; 165 166 /** 167 * Bit vector of the blocking reasons for the access path. 168 * @sa #BlockedCause 169 */ 170 uint8_t blocked; 171 172 /** Stores time the cache blocked for statistics. */ 173 Tick blockedCycle; 174 175 /** Pointer to the MSHR that has no targets. */ 176 MSHR *noTargetMSHR; 177 178 /** The number of misses to trigger an exit event. */ 179 Counter missCount; 180 181 /** The drain event. */ 182 Event *drainEvent; 183 184 public: 185 // Statistics 186 /** 187 * @addtogroup CacheStatistics 188 * @{ 189 */ 190 191 /** Number of hits per thread for each type of command. @sa Packet::Command */ 192 Stats::Vector<> hits[MemCmd::NUM_MEM_CMDS]; 193 /** Number of hits for demand accesses. */ 194 Stats::Formula demandHits; 195 /** Number of hit for all accesses. */ 196 Stats::Formula overallHits; 197 198 /** Number of misses per thread for each type of command. @sa Packet::Command */ 199 Stats::Vector<> misses[MemCmd::NUM_MEM_CMDS]; 200 /** Number of misses for demand accesses. */ 201 Stats::Formula demandMisses; 202 /** Number of misses for all accesses. */ 203 Stats::Formula overallMisses; 204 205 /** 206 * Total number of cycles per thread/command spent waiting for a miss. 207 * Used to calculate the average miss latency. 208 */ 209 Stats::Vector<> missLatency[MemCmd::NUM_MEM_CMDS]; 210 /** Total number of cycles spent waiting for demand misses. */ 211 Stats::Formula demandMissLatency; 212 /** Total number of cycles spent waiting for all misses. */ 213 Stats::Formula overallMissLatency; 214 215 /** The number of accesses per command and thread. */ 216 Stats::Formula accesses[MemCmd::NUM_MEM_CMDS]; 217 /** The number of demand accesses. */ 218 Stats::Formula demandAccesses; 219 /** The number of overall accesses. */ 220 Stats::Formula overallAccesses; 221 222 /** The miss rate per command and thread. */ 223 Stats::Formula missRate[MemCmd::NUM_MEM_CMDS]; 224 /** The miss rate of all demand accesses. */ 225 Stats::Formula demandMissRate; 226 /** The miss rate for all accesses. */ 227 Stats::Formula overallMissRate; 228 229 /** The average miss latency per command and thread. */ 230 Stats::Formula avgMissLatency[MemCmd::NUM_MEM_CMDS]; 231 /** The average miss latency for demand misses. */ 232 Stats::Formula demandAvgMissLatency; 233 /** The average miss latency for all misses. */ 234 Stats::Formula overallAvgMissLatency; 235 236 /** The total number of cycles blocked for each blocked cause. */ 237 Stats::Vector<> blocked_cycles; 238 /** The number of times this cache blocked for each blocked cause. */ 239 Stats::Vector<> blocked_causes; 240 241 /** The average number of cycles blocked for each blocked cause. */ 242 Stats::Formula avg_blocked; 243 244 /** The number of fast writes (WH64) performed. */ 245 Stats::Scalar<> fastWrites; 246 247 /** The number of cache copies performed. */ 248 Stats::Scalar<> cacheCopies; 249 250 /** Number of blocks written back per thread. */ 251 Stats::Vector<> writebacks; 252 253 /** Number of misses that hit in the MSHRs per command and thread. */ 254 Stats::Vector<> mshr_hits[MemCmd::NUM_MEM_CMDS]; 255 /** Demand misses that hit in the MSHRs. */ 256 Stats::Formula demandMshrHits; 257 /** Total number of misses that hit in the MSHRs. */ 258 Stats::Formula overallMshrHits; 259 260 /** Number of misses that miss in the MSHRs, per command and thread. */ 261 Stats::Vector<> mshr_misses[MemCmd::NUM_MEM_CMDS]; 262 /** Demand misses that miss in the MSHRs. */ 263 Stats::Formula demandMshrMisses; 264 /** Total number of misses that miss in the MSHRs. */ 265 Stats::Formula overallMshrMisses; 266 267 /** Number of misses that miss in the MSHRs, per command and thread. */ 268 Stats::Vector<> mshr_uncacheable[MemCmd::NUM_MEM_CMDS]; 269 /** Total number of misses that miss in the MSHRs. */ 270 Stats::Formula overallMshrUncacheable; 271 272 /** Total cycle latency of each MSHR miss, per command and thread. */ 273 Stats::Vector<> mshr_miss_latency[MemCmd::NUM_MEM_CMDS]; 274 /** Total cycle latency of demand MSHR misses. */ 275 Stats::Formula demandMshrMissLatency; 276 /** Total cycle latency of overall MSHR misses. */ 277 Stats::Formula overallMshrMissLatency; 278 279 /** Total cycle latency of each MSHR miss, per command and thread. */ 280 Stats::Vector<> mshr_uncacheable_lat[MemCmd::NUM_MEM_CMDS]; 281 /** Total cycle latency of overall MSHR misses. */ 282 Stats::Formula overallMshrUncacheableLatency; 283 284 /** The total number of MSHR accesses per command and thread. */ 285 Stats::Formula mshrAccesses[MemCmd::NUM_MEM_CMDS]; 286 /** The total number of demand MSHR accesses. */ 287 Stats::Formula demandMshrAccesses; 288 /** The total number of MSHR accesses. */ 289 Stats::Formula overallMshrAccesses; 290 291 /** The miss rate in the MSHRs pre command and thread. */ 292 Stats::Formula mshrMissRate[MemCmd::NUM_MEM_CMDS]; 293 /** The demand miss rate in the MSHRs. */ 294 Stats::Formula demandMshrMissRate; 295 /** The overall miss rate in the MSHRs. */ 296 Stats::Formula overallMshrMissRate; 297 298 /** The average latency of an MSHR miss, per command and thread. */ 299 Stats::Formula avgMshrMissLatency[MemCmd::NUM_MEM_CMDS]; 300 /** The average latency of a demand MSHR miss. */ 301 Stats::Formula demandAvgMshrMissLatency; 302 /** The average overall latency of an MSHR miss. */ 303 Stats::Formula overallAvgMshrMissLatency; 304 305 /** The average latency of an MSHR miss, per command and thread. */ 306 Stats::Formula avgMshrUncacheableLatency[MemCmd::NUM_MEM_CMDS]; 307 /** The average overall latency of an MSHR miss. */ 308 Stats::Formula overallAvgMshrUncacheableLatency; 309 310 /** The number of times a thread hit its MSHR cap. */ 311 Stats::Vector<> mshr_cap_events; 312 /** The number of times software prefetches caused the MSHR to block. */ 313 Stats::Vector<> soft_prefetch_mshr_full; 314 315 Stats::Scalar<> mshr_no_allocate_misses; 316 317 /** 318 * @} 319 */ 320 321 /** 322 * Register stats for this object. 323 */ 324 virtual void regStats(); 325 326 public: 327 328 class Params 329 { 330 public: 331 /** The hit latency for this cache. */ 332 int hitLatency; 333 /** The block size of this cache. */ 334 int blkSize; 335 int numMSHRs; 336 int numTargets; 337 int numWriteBuffers; 338 /** 339 * The maximum number of misses this cache should handle before 340 * ending the simulation. 341 */ 342 Counter maxMisses; 343 344 /** 345 * Construct an instance of this parameter class. 346 */ 347 Params(int _hitLatency, int _blkSize, 348 int _numMSHRs, int _numTargets, int _numWriteBuffers, 349 Counter _maxMisses) 350 : hitLatency(_hitLatency), blkSize(_blkSize), 351 numMSHRs(_numMSHRs), numTargets(_numTargets), 352 numWriteBuffers(_numWriteBuffers), maxMisses(_maxMisses) 353 { 354 } 355 }; 356 357 /** 358 * Create and initialize a basic cache object. 359 * @param name The name of this cache. 360 * @param hier_params Pointer to the HierParams object for this hierarchy 361 * of this cache. 362 * @param params The parameter object for this BaseCache. 363 */ 364 BaseCache(const std::string &name, Params ¶ms); 365 366 ~BaseCache() 367 { 368 } 369 370 virtual void init(); 371 372 /** 373 * Query block size of a cache. 374 * @return The block size 375 */ 376 int getBlockSize() const 377 { 378 return blkSize; 379 } 380 381 382 Addr blockAlign(Addr addr) const { return (addr & ~(blkSize - 1)); } 383 384 385 /** 386 * Returns true if the cache is blocked for accesses. 387 */ 388 bool isBlocked() 389 { 390 return blocked != 0; 391 } 392 393 /** 394 * Marks the access path of the cache as blocked for the given cause. This 395 * also sets the blocked flag in the slave interface. 396 * @param cause The reason for the cache blocking. 397 */ 398 void setBlocked(BlockedCause cause) 399 { 400 uint8_t flag = 1 << cause; 401 if (blocked == 0) { 402 blocked_causes[cause]++; 403 blockedCycle = curTick; 404 } 405 int old_state = blocked; 406 if (!(blocked & flag)) { 407 //Wasn't already blocked for this cause 408 blocked |= flag; 409 DPRINTF(Cache,"Blocking for cause %s\n", cause); 410 if (!old_state) 411 cpuSidePort->setBlocked(); 412 } 413 } 414 415 /** 416 * Marks the cache as unblocked for the given cause. This also clears the 417 * blocked flags in the appropriate interfaces. 418 * @param cause The newly unblocked cause. 419 * @warning Calling this function can cause a blocked request on the bus to 420 * access the cache. The cache must be in a state to handle that request. 421 */ 422 void clearBlocked(BlockedCause cause) 423 { 424 uint8_t flag = 1 << cause; 425 DPRINTF(Cache,"Unblocking for cause %s, causes left=%i\n", 426 cause, blocked); 427 if (blocked & flag) 428 { 429 blocked &= ~flag; 430 if (!isBlocked()) { 431 blocked_cycles[cause] += curTick - blockedCycle; 432 DPRINTF(Cache,"Unblocking from all causes\n"); 433 cpuSidePort->clearBlocked(); 434 } 435 } 436 } 437 438 /** 439 * True if the memory-side bus should be requested. 440 * @return True if there are outstanding requests for the master bus. 441 */ 442 bool isMemSideBusRequested() 443 { 444 return memSidePort->isBusRequested(); 445 } 446 447 /** 448 * Request the master bus for the given cause and time. 449 * @param cause The reason for the request. 450 * @param time The time to make the request. 451 */ 452 void requestMemSideBus(RequestCause cause, Tick time) 453 { 454 memSidePort->requestBus(cause, time); 455 } 456 457 /** 458 * Clear the master bus request for the given cause. 459 * @param cause The request reason to clear. 460 */ 461 void deassertMemSideBusRequest(RequestCause cause) 462 { 463 memSidePort->deassertBusRequest(cause); 464 // checkDrain(); 465 } 466 467 virtual unsigned int drain(Event *de); 468 469 virtual bool inCache(Addr addr) = 0; 470 471 virtual bool inMissQueue(Addr addr) = 0; 472 473 void incMissCount(PacketPtr pkt) 474 { 475 misses[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++; 476 477 if (missCount) { 478 --missCount; 479 if (missCount == 0) 480 exitSimLoop("A cache reached the maximum miss count"); 481 } 482 } 483 484}; 485 486#endif //__BASE_CACHE_HH__ 487