base_cache.hh
来自「linux下基于c++的处理器仿真平台。具有处理器流水线」· HH 代码 · 共 438 行
HH
438 行
/* * Copyright (c) 2003, 2004, 2005 * The Regents of The University of Michigan * All Rights Reserved * * This code is part of the M5 simulator, developed by Nathan Binkert, * Erik Hallnor, Steve Raasch, and Steve Reinhardt, with contributions * from Ron Dreslinski, Dave Greene, Lisa Hsu, Kevin Lim, Ali Saidi, * and Andrew Schultz. * * Permission is granted to use, copy, create derivative works and * redistribute this software and such derivative works for any * purpose, so long as the copyright notice above, this grant of * permission, and the disclaimer below appear in all copies made; and * so long as the name of The University of Michigan is not used in * any advertising or publicity pertaining to the use or distribution * of this software without specific, written prior authorization. * * THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION FROM THE * UNIVERSITY OF MICHIGAN AS TO ITS FITNESS FOR ANY PURPOSE, AND * WITHOUT WARRANTY BY THE UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE. THE REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE * LIABLE FOR ANY DAMAGES, INCLUDING DIRECT, SPECIAL, INDIRECT, * INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM * ARISING OUT OF OR IN CONNECTION WITH THE USE OF THE SOFTWARE, EVEN * IF IT HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH * DAMAGES. *//** * @file * Declares a basic cache interface BaseCache. */#ifndef __BASE_CACHE_HH__#define __BASE_CACHE_HH__#include <vector>#include "base/statistics.hh"#include "base/trace.hh"#include "mem/base_mem.hh"#include "mem/bus/base_interface.hh"#include "mem/mem_cmd.hh"#include "mem/mem_req.hh" // For MemReqPtr// Forward declarationsclass Bus;/** * Reasons for Caches to be Blocked. */enum BlockedCause{ Blocked_NoMSHRs, Blocked_NoTargets, Blocked_NoWBBuffers, Blocked_Coherence, Blocked_Copy, NUM_BLOCKED_CAUSES};/** * Reasons for cache to request a bus. */enum RequestCause{ Request_MSHR, Request_WB, Request_Coherence, Request_PF};/** * A basic cache interface. Implements some common functions for speed. */class BaseCache : public BaseMem { private: /** * Bit vector of the blocking reasons for the access path. * @sa #BlockedCause */ uint8_t blocked; /** * Bit vector for the blocking reasons for the snoop path. * @sa #BlockedCause */ uint8_t blockedSnoop; /** * Bit vector for the outstanding requests for the master interface. */ uint8_t masterRequests; /** * Bit vector for the outstanding requests for the slave interface. */ uint8_t slaveRequests; protected: /** The master interface, typically nearer to Main Memory */ BaseInterface *mi; /** True if this cache is connected to the CPU. */ bool topLevelCache; /** Stores time the cache blocked for statistics. */ Tick blockedCycle; /** Block size of this cache */ const int blkSize; /** The number of misses to trigger an exit event. */ Counter missCount; public: // Statistics /** * @addtogroup CacheStatistics * @{ */ /** Number of hits per thread for each type of command. @sa MemCmd */ Stats::Vector<> hits[NUM_MEM_CMDS]; /** Number of hits for demand accesses. */ Stats::Formula demandHits; /** Number of hit for all accesses. */ Stats::Formula overallHits; /** Number of misses per thread for each type of command. @sa MemCmd */ Stats::Vector<> misses[NUM_MEM_CMDS]; /** Number of misses for demand accesses. */ Stats::Formula demandMisses; /** Number of misses for all accesses. */ Stats::Formula overallMisses; /** * Total number of cycles per thread/command spent waiting for a miss. * Used to calculate the average miss latency. */ Stats::Vector<> missLatency[NUM_MEM_CMDS]; /** Total number of cycles spent waiting for demand misses. */ Stats::Formula demandMissLatency; /** Total number of cycles spent waiting for all misses. */ Stats::Formula overallMissLatency; /** The number of accesses per command and thread. */ Stats::Formula accesses[NUM_MEM_CMDS]; /** The number of demand accesses. */ Stats::Formula demandAccesses; /** The number of overall accesses. */ Stats::Formula overallAccesses; /** The miss rate per command and thread. */ Stats::Formula missRate[NUM_MEM_CMDS]; /** The miss rate of all demand accesses. */ Stats::Formula demandMissRate; /** The miss rate for all accesses. */ Stats::Formula overallMissRate; /** The average miss latency per command and thread. */ Stats::Formula avgMissLatency[NUM_MEM_CMDS]; /** The average miss latency for demand misses. */ Stats::Formula demandAvgMissLatency; /** The average miss latency for all misses. */ Stats::Formula overallAvgMissLatency; /** The total number of cycles blocked for each blocked cause. */ Stats::Vector<> blocked_cycles; /** The number of times this cache blocked for each blocked cause. */ Stats::Vector<> blocked_causes; /** The average number of cycles blocked for each blocked cause. */ Stats::Formula avg_blocked; /** The number of fast writes (WH64) performed. */ Stats::Scalar<> fastWrites; /** The number of cache copies performed. */ Stats::Scalar<> cacheCopies; /** * @} */ /** * Register stats for this object. */ virtual void regStats(); public: class Params { public: /** List of address ranges of this cache. */ std::vector<Range<Addr> > addrRange; /** The hit latency for this cache. */ int hitLatency; /** The block size of this cache. */ int blkSize; /** * The maximum number of misses this cache should handle before * ending the simulation. */ Counter maxMisses; /** * Construct an instance of this parameter class. */ Params(std::vector<Range<Addr> > addr_range, int hit_latency, int _blkSize, Counter max_misses) : addrRange(addr_range), hitLatency(hit_latency), blkSize(_blkSize), maxMisses(max_misses) { } }; /** * Create and initialize a basic cache object. * @param name The name of this cache. * @param hier_params Pointer to the HierParams object for this hierarchy * of this cache. * @param params The parameter object for this BaseCache. */ BaseCache(const std::string &name, HierParams *hier_params, Params ¶ms) : BaseMem(name, hier_params, params.hitLatency, params.addrRange), blocked(0), blockedSnoop(0), masterRequests(0), slaveRequests(0), topLevelCache(false), blkSize(params.blkSize), missCount(params.maxMisses) { } /** * Set the master interface for this cache to the one provided. * @param i The new master interface. */ void setMasterInterface(BaseInterface *i) { mi = i; std::list<Range<Addr> > ranges; si->getRange(ranges); mi->setAddrRange(ranges); } /** * Query block size of a cache. * @return The block size */ int getBlockSize() const { return blkSize; } /** * Returns true if this cache is connect to the CPU. * @return True if this is a L1 cache. */ bool isTopLevel() { return topLevelCache; } /** * Returns true if the cache is blocked for accesses. */ bool isBlocked() { return blocked != 0; } /** * Returns true if the cache is blocked for snoops. */ bool isBlockedForSnoop() { return blockedSnoop != 0; } /** * Marks the access path of the cache as blocked for the given cause. This * also sets the blocked flag in the slave interface. * @param cause The reason for the cache blocking. */ void setBlocked(BlockedCause cause) { uint8_t flag = 1 << cause; if (blocked == 0) { blocked_causes[cause]++; blockedCycle = curTick; } blocked |= flag; DPRINTF(Cache,"Blocking for cause %s\n", cause); si->setBlocked(); } /** * Marks the snoop path of the cache as blocked for the given cause. This * also sets the blocked flag in the master interface. * @param cause The reason to block the snoop path. */ void setBlockedForSnoop(BlockedCause cause) { uint8_t flag = 1 << cause; blockedSnoop |= flag; mi->setBlocked(); } /** * Marks the cache as unblocked for the given cause. This also clears the * blocked flags in the appropriate interfaces. * @param cause The newly unblocked cause. * @warning Calling this function can cause a blocked request on the bus to * access the cache. The cache must be in a state to handle that request. */ void clearBlocked(BlockedCause cause) { uint8_t flag = 1 << cause; blocked &= ~flag; blockedSnoop &= ~flag; DPRINTF(Cache,"Unblocking for cause %s, causes left=%i\n", cause, blocked); if (!isBlocked()) { blocked_cycles[cause] += curTick - blockedCycle; DPRINTF(Cache,"Unblocking from all causes\n"); si->clearBlocked(); } if (!isBlockedForSnoop()) { mi->clearBlocked(); } } /** * True if the master bus should be requested. * @return True if there are outstanding requests for the master bus. */ bool doMasterRequest() { return masterRequests != 0; } /** * Request the master bus for the given cause and time. * @param cause The reason for the request. * @param time The time to make the request. */ void setMasterRequest(RequestCause cause, Tick time) { uint8_t flag = 1<<cause; masterRequests |= flag; mi->request(time); } /** * Clear the master bus request for the given cause. * @param cause The request reason to clear. */ void clearMasterRequest(RequestCause cause) { uint8_t flag = 1<<cause; masterRequests &= ~flag; } /** * Return true if the slave bus should be requested. * @return True if there are outstanding requests for the slave bus. */ bool doSlaveRequest() { return slaveRequests != 0; } /** * Request the slave bus for the given reason and time. * @param cause The reason for the request. * @param time The time to make the request. */ void setSlaveRequest(RequestCause cause, Tick time) { uint8_t flag = 1<<cause; slaveRequests |= flag; si->request(time); } /** * Clear the slave bus request for the given reason. * @param cause The request reason to clear. */ void clearSlaveRequest(RequestCause cause) { uint8_t flag = 1<<cause; slaveRequests &= ~flag; } /** * Send a response to the slave interface. * @param req The request being responded to. * @param time The time the response is ready. */ void respond(MemReqPtr &req, Tick time) { si->respond(req,time); } /** * Send a reponse to the slave interface and calculate miss latency. * @param req The request to respond to. * @param time The time the response is ready. */ void respondToMiss(MemReqPtr &req, Tick time) { if (!req->isUncacheable()) { missLatency[req->cmd.toIndex()][req->thread_num] += time - req->time; } si->respond(req,time); } /** * Suppliess the data if cache to cache transfers are enabled. * @param req The bus transaction to fulfill. */ void respondToSnoop(MemReqPtr &req) { mi->respond(req,curTick + hitLatency); } /** * Notification from master interface that a address range changed. Nothing * to do for a cache. */ void rangeChange() {}};#endif //__BASE_CACHE_HH__
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?