CacheMemory.hh revision 10970
16145SN/A/* 28683SN/A * Copyright (c) 1999-2012 Mark D. Hill and David A. Wood 36145SN/A * All rights reserved. 46145SN/A * 56145SN/A * Redistribution and use in source and binary forms, with or without 66145SN/A * modification, are permitted provided that the following conditions are 76145SN/A * met: redistributions of source code must retain the above copyright 86145SN/A * notice, this list of conditions and the following disclaimer; 96145SN/A * redistributions in binary form must reproduce the above copyright 106145SN/A * notice, this list of conditions and the following disclaimer in the 116145SN/A * documentation and/or other materials provided with the distribution; 126145SN/A * neither the name of the copyright holders nor the names of its 136145SN/A * contributors may be used to endorse or promote products derived from 146145SN/A * this software without specific prior written permission. 156145SN/A * 166145SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176145SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186145SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196145SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206145SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216145SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226145SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236145SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246145SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256145SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266145SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276145SN/A */ 286145SN/A 2910441Snilay@cs.wisc.edu#ifndef __MEM_RUBY_STRUCTURES_CACHEMEMORY_HH__ 3010441Snilay@cs.wisc.edu#define __MEM_RUBY_STRUCTURES_CACHEMEMORY_HH__ 316145SN/A 327055SN/A#include <string> 336145SN/A#include <vector> 346145SN/A 357039SN/A#include "base/hashmap.hh" 369104SN/A#include "base/statistics.hh" 3710301Snilay@cs.wisc.edu#include "mem/protocol/CacheRequestType.hh" 389105SN/A#include "mem/protocol/CacheResourceType.hh" 398174SN/A#include "mem/protocol/RubyRequest.hh" 407039SN/A#include "mem/ruby/common/DataBlock.hh" 417039SN/A#include "mem/ruby/slicc_interface/AbstractCacheEntry.hh" 427039SN/A#include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh" 4310970Sdavid.hashe@amd.com#include "mem/ruby/structures/AbstractReplacementPolicy.hh" 4410301Snilay@cs.wisc.edu#include "mem/ruby/structures/BankedArray.hh" 4510301Snilay@cs.wisc.edu#include "mem/ruby/system/CacheRecorder.hh" 467039SN/A#include "params/RubyCache.hh" 477039SN/A#include "sim/sim_object.hh" 486145SN/A 497039SN/Aclass CacheMemory : public SimObject 507039SN/A{ 517039SN/A public: 526876SN/A typedef RubyCacheParams Params; 537039SN/A CacheMemory(const Params *p); 547039SN/A ~CacheMemory(); 556145SN/A 567039SN/A void init(); 576145SN/A 587039SN/A // Public Methods 597039SN/A // perform a cache access and see if we hit or not. Return true on a hit. 608165SN/A bool tryCacheAccess(const Address& address, RubyRequestType type, 617039SN/A DataBlock*& data_ptr); 626145SN/A 637039SN/A // similar to above, but doesn't require full access check 648165SN/A bool testCacheAccess(const Address& address, RubyRequestType type, 657039SN/A DataBlock*& data_ptr); 666145SN/A 677039SN/A // tests to see if an address is present in the cache 687039SN/A bool isTagPresent(const Address& address) const; 696145SN/A 707039SN/A // Returns true if there is: 717039SN/A // a) a tag match on this address or there is 727039SN/A // b) an unused line in the same cache "way" 737039SN/A bool cacheAvail(const Address& address) const; 746145SN/A 757039SN/A // find an unused entry and sets the tag appropriate for the address 767839SN/A AbstractCacheEntry* allocate(const Address& address, AbstractCacheEntry* new_entry); 778193SN/A void allocateVoid(const Address& address, AbstractCacheEntry* new_entry) 788193SN/A { 798193SN/A allocate(address, new_entry); 808193SN/A } 816145SN/A 827039SN/A // Explicitly free up this address 837039SN/A void deallocate(const Address& address); 846145SN/A 857039SN/A // Returns with the physical address of the conflicting cache line 867039SN/A Address cacheProbe(const Address& address) const; 876145SN/A 887039SN/A // looks an address up in the cache 897839SN/A AbstractCacheEntry* lookup(const Address& address); 907839SN/A const AbstractCacheEntry* lookup(const Address& address) const; 916145SN/A 929499SN/A Cycles getLatency() const { return m_latency; } 9310969Sdavid.hashe@amd.com Cycles getTagLatency() const { return tagArray.getLatency(); } 9410969Sdavid.hashe@amd.com Cycles getDataLatency() const { return dataArray.getLatency(); } 9510969Sdavid.hashe@amd.com 966285SN/A 977039SN/A // Hook for checkpointing the contents of the cache 988683SN/A void recordCacheContents(int cntrl, CacheRecorder* tr) const; 996145SN/A 1007039SN/A // Set this address to most recently used 1017039SN/A void setMRU(const Address& address); 1026145SN/A 1037039SN/A void setLocked (const Address& addr, int context); 1047039SN/A void clearLocked (const Address& addr); 1057039SN/A bool isLocked (const Address& addr, int context); 1069692SN/A 1077039SN/A // Print cache contents 1087055SN/A void print(std::ostream& out) const; 1097055SN/A void printData(std::ostream& out) const; 1106145SN/A 1119692SN/A void regStats(); 1129692SN/A bool checkResourceAvailable(CacheResourceType res, Address addr); 1139692SN/A void recordRequestType(CacheRequestType requestType); 1146374SN/A 1159692SN/A public: 1169692SN/A Stats::Scalar m_demand_hits; 1179692SN/A Stats::Scalar m_demand_misses; 1189692SN/A Stats::Formula m_demand_accesses; 1199692SN/A 1209692SN/A Stats::Scalar m_sw_prefetches; 1219692SN/A Stats::Scalar m_hw_prefetches; 1229692SN/A Stats::Formula m_prefetches; 1239692SN/A 1249692SN/A Stats::Vector m_accessModeType; 1259104SN/A 1269104SN/A Stats::Scalar numDataArrayReads; 1279104SN/A Stats::Scalar numDataArrayWrites; 1289104SN/A Stats::Scalar numTagArrayReads; 1299104SN/A Stats::Scalar numTagArrayWrites; 1309104SN/A 1319105SN/A Stats::Scalar numTagArrayStalls; 1329105SN/A Stats::Scalar numDataArrayStalls; 1339692SN/A 1347039SN/A private: 1357039SN/A // convert a Address to its location in the cache 13610314Snilay@cs.wisc.edu int64 addressToCacheSet(const Address& address) const; 1376145SN/A 1387039SN/A // Given a cache tag: returns the index of the tag in a set. 1397039SN/A // returns -1 if the tag is not found. 14010314Snilay@cs.wisc.edu int findTagInSet(int64 line, const Address& tag) const; 14110314Snilay@cs.wisc.edu int findTagInSetIgnorePermissions(int64 cacheSet, 1427039SN/A const Address& tag) const; 1436145SN/A 1447039SN/A // Private copy constructor and assignment operator 1457039SN/A CacheMemory(const CacheMemory& obj); 1467039SN/A CacheMemory& operator=(const CacheMemory& obj); 1476145SN/A 1487039SN/A private: 1499499SN/A Cycles m_latency; 1506145SN/A 1517039SN/A // Data Members (m_prefix) 1527039SN/A bool m_is_instruction_only_cache; 1536285SN/A 1547039SN/A // The first index is the # of cache lines. 1557039SN/A // The second index is the the amount associativity. 1567039SN/A m5::hash_map<Address, int> m_tag_index; 1577454SN/A std::vector<std::vector<AbstractCacheEntry*> > m_cache; 1586145SN/A 1597039SN/A AbstractReplacementPolicy *m_replacementPolicy_ptr; 1606145SN/A 1619105SN/A BankedArray dataArray; 1629105SN/A BankedArray tagArray; 1639105SN/A 1647039SN/A int m_cache_size; 1657039SN/A int m_cache_num_sets; 1667039SN/A int m_cache_num_set_bits; 1677039SN/A int m_cache_assoc; 1687564SN/A int m_start_index_bit; 1699105SN/A bool m_resource_stalls; 1706145SN/A}; 1716145SN/A 1729554SN/Astd::ostream& operator<<(std::ostream& out, const CacheMemory& obj); 1739554SN/A 17410441Snilay@cs.wisc.edu#endif // __MEM_RUBY_STRUCTURES_CACHEMEMORY_HH__ 175