CacheMemory.hh revision 10974
16145Snate@binkert.org/* 26145Snate@binkert.org * Copyright (c) 1999-2012 Mark D. Hill and David A. Wood 36145Snate@binkert.org * Copyright (c) 2013 Advanced Micro Devices, Inc. 46145Snate@binkert.org * All rights reserved. 56145Snate@binkert.org * 66145Snate@binkert.org * Redistribution and use in source and binary forms, with or without 76145Snate@binkert.org * modification, are permitted provided that the following conditions are 86145Snate@binkert.org * met: redistributions of source code must retain the above copyright 96145Snate@binkert.org * notice, this list of conditions and the following disclaimer; 106145Snate@binkert.org * redistributions in binary form must reproduce the above copyright 116145Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 126145Snate@binkert.org * documentation and/or other materials provided with the distribution; 136145Snate@binkert.org * neither the name of the copyright holders nor the names of its 146145Snate@binkert.org * contributors may be used to endorse or promote products derived from 156145Snate@binkert.org * this software without specific prior written permission. 166145Snate@binkert.org * 176145Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 186145Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 196145Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 206145Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 216145Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 226145Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 236145Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 246145Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 256145Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 266145Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 276145Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 286145Snate@binkert.org */ 296145Snate@binkert.org 307039Snate@binkert.org#ifndef __MEM_RUBY_STRUCTURES_CACHEMEMORY_HH__ 317039Snate@binkert.org#define __MEM_RUBY_STRUCTURES_CACHEMEMORY_HH__ 327039Snate@binkert.org 336145Snate@binkert.org#include <string> 346145Snate@binkert.org#include <vector> 357039Snate@binkert.org 367039Snate@binkert.org#include "base/hashmap.hh" 376145Snate@binkert.org#include "base/statistics.hh" 387002Snate@binkert.org#include "mem/protocol/CacheRequestType.hh" 397021Stushar@csail.mit.edu#include "mem/protocol/CacheResourceType.hh" 407002Snate@binkert.org#include "mem/protocol/RubyRequest.hh" 419171Snilay@cs.wisc.edu#include "mem/ruby/common/DataBlock.hh" 429465Snilay@cs.wisc.edu#include "mem/ruby/slicc_interface/AbstractCacheEntry.hh" 436145Snate@binkert.org#include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh" 447039Snate@binkert.org#include "mem/ruby/structures/AbstractReplacementPolicy.hh" 457039Snate@binkert.org#include "mem/ruby/structures/BankedArray.hh" 467039Snate@binkert.org#include "mem/ruby/system/CacheRecorder.hh" 479465Snilay@cs.wisc.edu#include "params/RubyCache.hh" 489230Snilay@cs.wisc.edu#include "sim/sim_object.hh" 497039Snate@binkert.org 507039Snate@binkert.orgclass CacheMemory : public SimObject 516145Snate@binkert.org{ 527039Snate@binkert.org public: 537039Snate@binkert.org typedef RubyCacheParams Params; 547039Snate@binkert.org CacheMemory(const Params *p); 556145Snate@binkert.org ~CacheMemory(); 567039Snate@binkert.org 577039Snate@binkert.org void init(); 587973Snilay@cs.wisc.edu 596145Snate@binkert.org // Public Methods 609171Snilay@cs.wisc.edu // perform a cache access and see if we hit or not. Return true on a hit. 617039Snate@binkert.org bool tryCacheAccess(const Address& address, RubyRequestType type, 627039Snate@binkert.org DataBlock*& data_ptr); 637039Snate@binkert.org 647039Snate@binkert.org // similar to above, but doesn't require full access check 657039Snate@binkert.org bool testCacheAccess(const Address& address, RubyRequestType type, 667039Snate@binkert.org DataBlock*& data_ptr); 679171Snilay@cs.wisc.edu 687039Snate@binkert.org // tests to see if an address is present in the cache 697039Snate@binkert.org bool isTagPresent(const Address& address) const; 707039Snate@binkert.org 717039Snate@binkert.org // Returns true if there is: 727039Snate@binkert.org // a) a tag match on this address or there is 739171Snilay@cs.wisc.edu // b) an unused line in the same cache "way" 747039Snate@binkert.org bool cacheAvail(const Address& address) const; 757039Snate@binkert.org 767039Snate@binkert.org // find an unused entry and sets the tag appropriate for the address 777039Snate@binkert.org AbstractCacheEntry* allocate(const Address& address, 787039Snate@binkert.org AbstractCacheEntry* new_entry, bool touch); 799171Snilay@cs.wisc.edu AbstractCacheEntry* allocate(const Address& address, 807039Snate@binkert.org AbstractCacheEntry* new_entry) 817039Snate@binkert.org { 827039Snate@binkert.org return allocate(address, new_entry, true); 837039Snate@binkert.org } 847039Snate@binkert.org void allocateVoid(const Address& address, AbstractCacheEntry* new_entry) 859171Snilay@cs.wisc.edu { 867039Snate@binkert.org allocate(address, new_entry, true); 877039Snate@binkert.org } 887039Snate@binkert.org 897039Snate@binkert.org // Explicitly free up this address 907039Snate@binkert.org void deallocate(const Address& address); 919171Snilay@cs.wisc.edu 929171Snilay@cs.wisc.edu // Returns with the physical address of the conflicting cache line 939171Snilay@cs.wisc.edu Address cacheProbe(const Address& address) const; 947039Snate@binkert.org 959171Snilay@cs.wisc.edu // looks an address up in the cache 969171Snilay@cs.wisc.edu AbstractCacheEntry* lookup(const Address& address); 979171Snilay@cs.wisc.edu const AbstractCacheEntry* lookup(const Address& address) const; 989465Snilay@cs.wisc.edu 999171Snilay@cs.wisc.edu Cycles getLatency() const { return m_latency; } 1009171Snilay@cs.wisc.edu Cycles getTagLatency() const { return tagArray.getLatency(); } 1019171Snilay@cs.wisc.edu Cycles getDataLatency() const { return dataArray.getLatency(); } 1029171Snilay@cs.wisc.edu 1039171Snilay@cs.wisc.edu 1049171Snilay@cs.wisc.edu // Hook for checkpointing the contents of the cache 1059171Snilay@cs.wisc.edu void recordCacheContents(int cntrl, CacheRecorder* tr) const; 1069171Snilay@cs.wisc.edu 1079171Snilay@cs.wisc.edu // Set this address to most recently used 1089171Snilay@cs.wisc.edu void setMRU(const Address& address); 1099171Snilay@cs.wisc.edu 1109171Snilay@cs.wisc.edu void setLocked (const Address& addr, int context); 1119171Snilay@cs.wisc.edu void clearLocked (const Address& addr); 1129171Snilay@cs.wisc.edu bool isLocked (const Address& addr, int context); 1139171Snilay@cs.wisc.edu 1149171Snilay@cs.wisc.edu // Print cache contents 1159171Snilay@cs.wisc.edu void print(std::ostream& out) const; 1169171Snilay@cs.wisc.edu void printData(std::ostream& out) const; 1176145Snate@binkert.org 1186145Snate@binkert.org void regStats(); 1197039Snate@binkert.org bool checkResourceAvailable(CacheResourceType res, Address addr); 1207039Snate@binkert.org void recordRequestType(CacheRequestType requestType); 1216145Snate@binkert.org 1227039Snate@binkert.org public: 1237039Snate@binkert.org Stats::Scalar m_demand_hits; 1247039Snate@binkert.org Stats::Scalar m_demand_misses; 1256145Snate@binkert.org Stats::Formula m_demand_accesses; 1266145Snate@binkert.org 1277039Snate@binkert.org Stats::Scalar m_sw_prefetches; 128 Stats::Scalar m_hw_prefetches; 129 Stats::Formula m_prefetches; 130 131 Stats::Vector m_accessModeType; 132 133 Stats::Scalar numDataArrayReads; 134 Stats::Scalar numDataArrayWrites; 135 Stats::Scalar numTagArrayReads; 136 Stats::Scalar numTagArrayWrites; 137 138 Stats::Scalar numTagArrayStalls; 139 Stats::Scalar numDataArrayStalls; 140 141 int getCacheSize() const { return m_cache_size; } 142 int getNumBlocks() const { return m_cache_num_sets * m_cache_assoc; } 143 Address getAddressAtIdx(int idx) const; 144 145 private: 146 // convert a Address to its location in the cache 147 int64 addressToCacheSet(const Address& address) const; 148 149 // Given a cache tag: returns the index of the tag in a set. 150 // returns -1 if the tag is not found. 151 int findTagInSet(int64 line, const Address& tag) const; 152 int findTagInSetIgnorePermissions(int64 cacheSet, 153 const Address& tag) const; 154 155 // Private copy constructor and assignment operator 156 CacheMemory(const CacheMemory& obj); 157 CacheMemory& operator=(const CacheMemory& obj); 158 159 private: 160 Cycles m_latency; 161 162 // Data Members (m_prefix) 163 bool m_is_instruction_only_cache; 164 165 // The first index is the # of cache lines. 166 // The second index is the the amount associativity. 167 m5::hash_map<Address, int> m_tag_index; 168 std::vector<std::vector<AbstractCacheEntry*> > m_cache; 169 170 AbstractReplacementPolicy *m_replacementPolicy_ptr; 171 172 BankedArray dataArray; 173 BankedArray tagArray; 174 175 int m_cache_size; 176 int m_cache_num_sets; 177 int m_cache_num_set_bits; 178 int m_cache_assoc; 179 int m_start_index_bit; 180 bool m_resource_stalls; 181}; 182 183std::ostream& operator<<(std::ostream& out, const CacheMemory& obj); 184 185#endif // __MEM_RUBY_STRUCTURES_CACHEMEMORY_HH__ 186