16145SN/A/* 28683SN/A * Copyright (c) 1999-2012 Mark D. Hill and David A. Wood 310973Sdavid.hashe@amd.com * Copyright (c) 2013 Advanced Micro Devices, Inc. 46145SN/A * All rights reserved. 56145SN/A * 66145SN/A * Redistribution and use in source and binary forms, with or without 76145SN/A * modification, are permitted provided that the following conditions are 86145SN/A * met: redistributions of source code must retain the above copyright 96145SN/A * notice, this list of conditions and the following disclaimer; 106145SN/A * redistributions in binary form must reproduce the above copyright 116145SN/A * notice, this list of conditions and the following disclaimer in the 126145SN/A * documentation and/or other materials provided with the distribution; 136145SN/A * neither the name of the copyright holders nor the names of its 146145SN/A * contributors may be used to endorse or promote products derived from 156145SN/A * this software without specific prior written permission. 166145SN/A * 176145SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 186145SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 196145SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 206145SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 216145SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 226145SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 236145SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 246145SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 256145SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 266145SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 276145SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 286145SN/A */ 296145SN/A 3010441Snilay@cs.wisc.edu#ifndef __MEM_RUBY_STRUCTURES_CACHEMEMORY_HH__ 3110441Snilay@cs.wisc.edu#define __MEM_RUBY_STRUCTURES_CACHEMEMORY_HH__ 326145SN/A 337055SN/A#include <string> 3411168Sandreas.hansson@arm.com#include <unordered_map> 356145SN/A#include <vector> 366145SN/A 379104SN/A#include "base/statistics.hh" 387039SN/A#include "mem/ruby/common/DataBlock.hh" 3914184Sgabeblack@google.com#include "mem/ruby/protocol/CacheRequestType.hh" 4014184Sgabeblack@google.com#include "mem/ruby/protocol/CacheResourceType.hh" 4114184Sgabeblack@google.com#include "mem/ruby/protocol/RubyRequest.hh" 427039SN/A#include "mem/ruby/slicc_interface/AbstractCacheEntry.hh" 437039SN/A#include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh" 4410970Sdavid.hashe@amd.com#include "mem/ruby/structures/AbstractReplacementPolicy.hh" 4510301Snilay@cs.wisc.edu#include "mem/ruby/structures/BankedArray.hh" 4610301Snilay@cs.wisc.edu#include "mem/ruby/system/CacheRecorder.hh" 477039SN/A#include "params/RubyCache.hh" 487039SN/A#include "sim/sim_object.hh" 496145SN/A 507039SN/Aclass CacheMemory : public SimObject 517039SN/A{ 527039SN/A public: 536876SN/A typedef RubyCacheParams Params; 547039SN/A CacheMemory(const Params *p); 557039SN/A ~CacheMemory(); 566145SN/A 577039SN/A void init(); 586145SN/A 5911049Snilay@cs.wisc.edu // Public Methods 6011049Snilay@cs.wisc.edu // perform a cache access and see if we hit or not. Return true on a hit. 6111049Snilay@cs.wisc.edu bool tryCacheAccess(Addr address, RubyRequestType type, 6211049Snilay@cs.wisc.edu DataBlock*& data_ptr); 6311049Snilay@cs.wisc.edu 6411049Snilay@cs.wisc.edu // similar to above, but doesn't require full access check 6511049Snilay@cs.wisc.edu bool testCacheAccess(Addr address, RubyRequestType type, 6611049Snilay@cs.wisc.edu DataBlock*& data_ptr); 6711049Snilay@cs.wisc.edu 687039SN/A // tests to see if an address is present in the cache 6911025Snilay@cs.wisc.edu bool isTagPresent(Addr address) const; 706145SN/A 717039SN/A // Returns true if there is: 727039SN/A // a) a tag match on this address or there is 737039SN/A // b) an unused line in the same cache "way" 7411025Snilay@cs.wisc.edu bool cacheAvail(Addr address) const; 756145SN/A 767039SN/A // find an unused entry and sets the tag appropriate for the address 7711025Snilay@cs.wisc.edu AbstractCacheEntry* allocate(Addr address, 7810974Sdavid.hashe@amd.com AbstractCacheEntry* new_entry, bool touch); 7911025Snilay@cs.wisc.edu AbstractCacheEntry* allocate(Addr address, AbstractCacheEntry* new_entry) 8010974Sdavid.hashe@amd.com { 8110974Sdavid.hashe@amd.com return allocate(address, new_entry, true); 8210974Sdavid.hashe@amd.com } 8311025Snilay@cs.wisc.edu void allocateVoid(Addr address, AbstractCacheEntry* new_entry) 848193SN/A { 8510974Sdavid.hashe@amd.com allocate(address, new_entry, true); 868193SN/A } 876145SN/A 887039SN/A // Explicitly free up this address 8911025Snilay@cs.wisc.edu void deallocate(Addr address); 906145SN/A 917039SN/A // Returns with the physical address of the conflicting cache line 9211025Snilay@cs.wisc.edu Addr cacheProbe(Addr address) const; 936145SN/A 947039SN/A // looks an address up in the cache 9511025Snilay@cs.wisc.edu AbstractCacheEntry* lookup(Addr address); 9611025Snilay@cs.wisc.edu const AbstractCacheEntry* lookup(Addr address) const; 976145SN/A 9810969Sdavid.hashe@amd.com Cycles getTagLatency() const { return tagArray.getLatency(); } 9910969Sdavid.hashe@amd.com Cycles getDataLatency() const { return dataArray.getLatency(); } 10010969Sdavid.hashe@amd.com 10111061Snilay@cs.wisc.edu bool isBlockInvalid(int64_t cache_set, int64_t loc); 10211061Snilay@cs.wisc.edu bool isBlockNotBusy(int64_t cache_set, int64_t loc); 1036285SN/A 1047039SN/A // Hook for checkpointing the contents of the cache 1058683SN/A void recordCacheContents(int cntrl, CacheRecorder* tr) const; 1066145SN/A 1077039SN/A // Set this address to most recently used 10811025Snilay@cs.wisc.edu void setMRU(Addr address); 10911308Santhony.gutierrez@amd.com void setMRU(Addr addr, int occupancy); 11011308Santhony.gutierrez@amd.com int getReplacementWeight(int64_t set, int64_t loc); 11111087Snilay@cs.wisc.edu void setMRU(const AbstractCacheEntry *e); 1126145SN/A 11311059Snilay@cs.wisc.edu // Functions for locking and unlocking cache lines corresponding to the 11411059Snilay@cs.wisc.edu // provided address. These are required for supporting atomic memory 11511059Snilay@cs.wisc.edu // accesses. These are to be used when only the address of the cache entry 11611059Snilay@cs.wisc.edu // is available. In case the entry itself is available. use the functions 11711059Snilay@cs.wisc.edu // provided by the AbstractCacheEntry class. 11811025Snilay@cs.wisc.edu void setLocked (Addr addr, int context); 11911025Snilay@cs.wisc.edu void clearLocked (Addr addr); 12011025Snilay@cs.wisc.edu bool isLocked (Addr addr, int context); 1219692SN/A 1227039SN/A // Print cache contents 1237055SN/A void print(std::ostream& out) const; 1247055SN/A void printData(std::ostream& out) const; 1256145SN/A 1269692SN/A void regStats(); 12711025Snilay@cs.wisc.edu bool checkResourceAvailable(CacheResourceType res, Addr addr); 12811025Snilay@cs.wisc.edu void recordRequestType(CacheRequestType requestType, Addr addr); 1296374SN/A 1309692SN/A public: 1319692SN/A Stats::Scalar m_demand_hits; 1329692SN/A Stats::Scalar m_demand_misses; 1339692SN/A Stats::Formula m_demand_accesses; 1349692SN/A 1359692SN/A Stats::Scalar m_sw_prefetches; 1369692SN/A Stats::Scalar m_hw_prefetches; 1379692SN/A Stats::Formula m_prefetches; 1389692SN/A 1399692SN/A Stats::Vector m_accessModeType; 1409104SN/A 1419104SN/A Stats::Scalar numDataArrayReads; 1429104SN/A Stats::Scalar numDataArrayWrites; 1439104SN/A Stats::Scalar numTagArrayReads; 1449104SN/A Stats::Scalar numTagArrayWrites; 1459104SN/A 1469105SN/A Stats::Scalar numTagArrayStalls; 1479105SN/A Stats::Scalar numDataArrayStalls; 1489692SN/A 14910973Sdavid.hashe@amd.com int getCacheSize() const { return m_cache_size; } 15011308Santhony.gutierrez@amd.com int getCacheAssoc() const { return m_cache_assoc; } 15110973Sdavid.hashe@amd.com int getNumBlocks() const { return m_cache_num_sets * m_cache_assoc; } 15211025Snilay@cs.wisc.edu Addr getAddressAtIdx(int idx) const; 15310973Sdavid.hashe@amd.com 1547039SN/A private: 1557039SN/A // convert a Address to its location in the cache 15611061Snilay@cs.wisc.edu int64_t addressToCacheSet(Addr address) const; 1576145SN/A 1587039SN/A // Given a cache tag: returns the index of the tag in a set. 1597039SN/A // returns -1 if the tag is not found. 16011061Snilay@cs.wisc.edu int findTagInSet(int64_t line, Addr tag) const; 16111061Snilay@cs.wisc.edu int findTagInSetIgnorePermissions(int64_t cacheSet, Addr tag) const; 1626145SN/A 1637039SN/A // Private copy constructor and assignment operator 1647039SN/A CacheMemory(const CacheMemory& obj); 1657039SN/A CacheMemory& operator=(const CacheMemory& obj); 1666145SN/A 1677039SN/A private: 1687039SN/A // Data Members (m_prefix) 1697039SN/A bool m_is_instruction_only_cache; 1706285SN/A 1717039SN/A // The first index is the # of cache lines. 1727039SN/A // The second index is the the amount associativity. 17311168Sandreas.hansson@arm.com std::unordered_map<Addr, int> m_tag_index; 1747454SN/A std::vector<std::vector<AbstractCacheEntry*> > m_cache; 1756145SN/A 1767039SN/A AbstractReplacementPolicy *m_replacementPolicy_ptr; 1776145SN/A 1789105SN/A BankedArray dataArray; 1799105SN/A BankedArray tagArray; 1809105SN/A 1817039SN/A int m_cache_size; 1827039SN/A int m_cache_num_sets; 1837039SN/A int m_cache_num_set_bits; 1847039SN/A int m_cache_assoc; 1857564SN/A int m_start_index_bit; 1869105SN/A bool m_resource_stalls; 18711308Santhony.gutierrez@amd.com int m_block_size; 1886145SN/A}; 1896145SN/A 1909554SN/Astd::ostream& operator<<(std::ostream& out, const CacheMemory& obj); 1919554SN/A 19210441Snilay@cs.wisc.edu#endif // __MEM_RUBY_STRUCTURES_CACHEMEMORY_HH__ 193