diff options
author | Nathan Binkert <nate@binkert.org> | 2009-07-06 15:49:47 -0700 |
---|---|---|
committer | Nathan Binkert <nate@binkert.org> | 2009-07-06 15:49:47 -0700 |
commit | 92de70b69aaf3f399a855057b556ed198139e5d8 (patch) | |
tree | f8e7d0d494df8810cc960be4c52d8b555471f157 /src/mem/ruby/system/CacheMemory.hh | |
parent | 05f6a4a6b92370162da17ef5cccb5a7e3ba508e5 (diff) | |
download | gem5-92de70b69aaf3f399a855057b556ed198139e5d8.tar.xz |
ruby: Import the latest ruby changes from gems.
This was done with an automated process, so there could be things that were
done in this tree in the past that didn't make it. One known regression
is that atomic memory operations do not seem to work properly anymore.
Diffstat (limited to 'src/mem/ruby/system/CacheMemory.hh')
-rw-r--r-- | src/mem/ruby/system/CacheMemory.hh | 381 |
1 files changed, 225 insertions, 156 deletions
diff --git a/src/mem/ruby/system/CacheMemory.hh b/src/mem/ruby/system/CacheMemory.hh index 22799ab13..4d46ac908 100644 --- a/src/mem/ruby/system/CacheMemory.hh +++ b/src/mem/ruby/system/CacheMemory.hh @@ -38,13 +38,10 @@ #ifndef CACHEMEMORY_H #define CACHEMEMORY_H -#include "mem/ruby/slicc_interface/AbstractChip.hh" #include "mem/ruby/common/Global.hh" #include "mem/protocol/AccessPermission.hh" #include "mem/ruby/common/Address.hh" - -//dsm: PRUNED -//#include "mem/ruby/recorder/CacheRecorder.hh" +#include "mem/ruby/recorder/CacheRecorder.hh" #include "mem/protocol/CacheRequestType.hh" #include "mem/gems_common/Vector.hh" #include "mem/ruby/common/DataBlock.hh" @@ -52,18 +49,25 @@ #include "mem/ruby/slicc_interface/RubySlicc_ComponentMapping.hh" #include "mem/ruby/system/PseudoLRUPolicy.hh" #include "mem/ruby/system/LRUPolicy.hh" +#include "mem/ruby/slicc_interface/AbstractCacheEntry.hh" +#include "mem/ruby/system/System.hh" +#include "mem/ruby/slicc_interface/AbstractController.hh" #include <vector> -template<class ENTRY> class CacheMemory { public: // Constructors - CacheMemory(AbstractChip* chip_ptr, int numSetBits, int cacheAssoc, const MachineType machType, const string& description); + CacheMemory(const string & name); + void init(const vector<string> & argv); // Destructor ~CacheMemory(); + // factory + // static CacheMemory* createCache(int level, int num, char split_type, AbstractCacheEntry* (*entry_factory)()); + // static CacheMemory* getCache(int cache_id); + // Public Methods void printConfig(ostream& out); @@ -82,7 +86,7 @@ public: bool cacheAvail(const Address& address) const; // find an unused entry and sets the tag appropriate for the address - void allocate(const Address& address); + void allocate(const Address& address, AbstractCacheEntry* new_entry); // Explicitly free up this address void deallocate(const Address& address); @@ -91,16 +95,18 @@ public: Address cacheProbe(const Address& address) const; // looks an address up in the cache - ENTRY& lookup(const Address& address); - const ENTRY& lookup(const Address& address) const; + AbstractCacheEntry& lookup(const Address& address); + const AbstractCacheEntry& lookup(const Address& address) const; // Get/Set permission of cache block AccessPermission getPermission(const Address& address) const; void changePermission(const Address& address, AccessPermission new_perm); + int getLatency() const { return m_latency; } + // Hook for checkpointing the contents of the cache void recordCacheContents(CacheRecorder& tr) const; - void setAsInstructionCache(bool is_icache) { m_is_instruction_cache = is_icache; } + void setAsInstructionCache(bool is_icache) { m_is_instruction_only_cache = is_icache; } // Set this address to most recently used void setMRU(const Address& address); @@ -129,15 +135,18 @@ private: CacheMemory(const CacheMemory& obj); CacheMemory& operator=(const CacheMemory& obj); +private: + const string m_cache_name; + AbstractController* m_controller; + int m_latency; + // Data Members (m_prefix) - AbstractChip* m_chip_ptr; - MachineType m_machType; - string m_description; - bool m_is_instruction_cache; + bool m_is_instruction_only_cache; + bool m_is_data_only_cache; // The first index is the # of cache lines. // The second index is the the amount associativity. - Vector<Vector<ENTRY> > m_cache; + Vector<Vector<AbstractCacheEntry*> > m_cache; AbstractReplacementPolicy *m_replacementPolicy_ptr; @@ -145,18 +154,55 @@ private: int m_cache_num_set_bits; int m_cache_assoc; - bool is_locked; // for LL/SC + static Vector< CacheMemory* > m_all_caches; }; +/* +inline +CacheMemory* CacheMemory::getCache(int cache_id) +{ + assert(cache_id < RubyConfig::getNumberOfCaches()); + if (m_all_caches[cache_id] == NULL) { + cerr << "ERROR: Tried to obtain CacheMemory that hasn't been created yet." << endl; + assert(0); + } + return m_all_caches[cache_id]; +} +inline +CacheMemory* CacheMemory::createCache(int level, int num, char split_type_c, AbstractCacheEntry* (*entry_factory)()) +{ + string split_type; + switch(split_type_c) { + case 'i': + split_type = "instruction"; break; + case 'd': + split_type = "data"; break; + default: + split_type = "unified"; break; + } + int cache_id = RubyConfig::getCacheIDFromParams(level, num, split_type); + assert(cache_id < RubyConfig::getNumberOfCaches()); + if (m_all_caches.size() == 0) { + m_all_caches.setSize(RubyConfig::getNumberOfCaches()); + for (int i=0; i<m_all_caches.size(); i++) + m_all_caches[i] = NULL; + } + + string type = RubyConfig::getCacheType(cache_id); + if ( type == "SetAssociativeCache" ) { + m_all_caches[cache_id] = new CacheMemory(cache_id, entry_factory); + } + return m_all_caches[cache_id]; +} +*/ // Output operator declaration //ostream& operator<<(ostream& out, const CacheMemory<ENTRY>& obj); // ******************* Definitions ******************* // Output operator definition -template<class ENTRY> inline -ostream& operator<<(ostream& out, const CacheMemory<ENTRY>& obj) +ostream& operator<<(ostream& out, const CacheMemory& obj) { obj.print(out); out << flush; @@ -166,112 +212,142 @@ ostream& operator<<(ostream& out, const CacheMemory<ENTRY>& obj) // **************************************************************** -template<class ENTRY> inline -CacheMemory<ENTRY>::CacheMemory(AbstractChip* chip_ptr, int numSetBits, - int cacheAssoc, const MachineType machType, const string& description) +CacheMemory::CacheMemory(const string & name) + : m_cache_name(name) +{ +} +inline +void CacheMemory::init(const vector<string> & argv) { - //cout << "CacheMemory constructor numThreads = " << numThreads << endl; - m_chip_ptr = chip_ptr; - m_machType = machType; - m_description = MachineType_to_string(m_machType)+"_"+description; - m_cache_num_set_bits = numSetBits; - m_cache_num_sets = 1 << numSetBits; - m_cache_assoc = cacheAssoc; - m_is_instruction_cache = false; + int cache_size = 0; + string policy; + + m_controller = NULL; + for (uint32 i=0; i<argv.size(); i+=2) { + if (argv[i] == "size_kb") { + cache_size = atoi(argv[i+1].c_str()); + } else if (argv[i] == "latency") { + m_latency = atoi(argv[i+1].c_str()); + } else if (argv[i] == "assoc") { + m_cache_assoc = atoi(argv[i+1].c_str()); + } else if (argv[i] == "replacement_policy") { + policy = argv[i+1]; + } else if (argv[i] == "controller") { + m_controller = RubySystem::getController(argv[i+1]); + } else { + cerr << "WARNING: CacheMemory: Unknown configuration parameter: " << argv[i] << endl; + } + } - m_cache.setSize(m_cache_num_sets); - if(strcmp(g_REPLACEMENT_POLICY, "PSEDUO_LRU") == 0) + m_cache_num_sets = cache_size / m_cache_assoc; + m_cache_num_set_bits = log_int(m_cache_num_sets); + + if(policy == "PSEUDO_LRU") m_replacementPolicy_ptr = new PseudoLRUPolicy(m_cache_num_sets, m_cache_assoc); - else if(strcmp(g_REPLACEMENT_POLICY, "LRU") == 0) + else if (policy == "LRU") m_replacementPolicy_ptr = new LRUPolicy(m_cache_num_sets, m_cache_assoc); else assert(false); + + m_cache.setSize(m_cache_num_sets); for (int i = 0; i < m_cache_num_sets; i++) { m_cache[i].setSize(m_cache_assoc); for (int j = 0; j < m_cache_assoc; j++) { - m_cache[i][j].m_Address.setAddress(0); - m_cache[i][j].m_Permission = AccessPermission_NotPresent; + m_cache[i][j] = NULL; } } +} +/* +inline +CacheMemory::CacheMemory(int cache_id, AbstractCacheEntry* (*entry_factory)()) +{ + string split_type; + + m_cache_id = cache_id; + m_entry_factory = entry_factory; + + m_cache_num_set_bits = RubyConfig::getNumberOfCacheSetBits(cache_id); + m_cache_num_sets = RubyConfig::getNumberOfCacheSets(cache_id); + m_cache_assoc = RubyConfig::getCacheAssoc(cache_id); + split_type = RubyConfig::getCacheSplitType(cache_id); + m_is_instruction_only_cache = m_is_data_only_cache = false; + if (split_type == "instruction") + m_is_instruction_only_cache = true; + else if (split_type == "data") + m_is_data_only_cache = true; + else + assert(split_type == "unified"); + if(RubyConfig::getCacheReplacementPolicy(cache_id) == "PSEUDO_LRU") + m_replacementPolicy_ptr = new PseudoLRUPolicy(m_cache_num_sets, m_cache_assoc); + else if(RubyConfig::getCacheReplacementPolicy(cache_id) == "LRU") + m_replacementPolicy_ptr = new LRUPolicy(m_cache_num_sets, m_cache_assoc); + else + assert(false); - // cout << "Before setting trans address list size" << endl; - //create a trans address for each SMT thread -// m_trans_address_list.setSize(numThreads); -// for(ThreadID tid = 0; tid < numThreads; ++tid){ -// cout << "Setting list size for list " << tid << endl; -// m_trans_address_list[tid].setSize(30); -// } - //cout << "CacheMemory constructor finished" << endl; + m_cache.setSize(m_cache_num_sets); + for (int i = 0; i < m_cache_num_sets; i++) { + m_cache[i].setSize(m_cache_assoc); + for (int j = 0; j < m_cache_assoc; j++) { + m_cache[i][j] = m_entry_factory(); + } + } } - -template<class ENTRY> +*/ inline -CacheMemory<ENTRY>::~CacheMemory() +CacheMemory::~CacheMemory() { if(m_replacementPolicy_ptr != NULL) delete m_replacementPolicy_ptr; } -template<class ENTRY> inline -void CacheMemory<ENTRY>::printConfig(ostream& out) +void CacheMemory::printConfig(ostream& out) { - out << "Cache config: " << m_description << endl; + out << "Cache config: " << m_cache_name << endl; + if (m_controller != NULL) + out << " controller: " << m_controller->getName() << endl; out << " cache_associativity: " << m_cache_assoc << endl; out << " num_cache_sets_bits: " << m_cache_num_set_bits << endl; const int cache_num_sets = 1 << m_cache_num_set_bits; out << " num_cache_sets: " << cache_num_sets << endl; - out << " cache_set_size_bytes: " << cache_num_sets * RubyConfig::dataBlockBytes() << endl; + out << " cache_set_size_bytes: " << cache_num_sets * RubySystem::getBlockSizeBytes() << endl; out << " cache_set_size_Kbytes: " - << double(cache_num_sets * RubyConfig::dataBlockBytes()) / (1<<10) << endl; + << double(cache_num_sets * RubySystem::getBlockSizeBytes()) / (1<<10) << endl; out << " cache_set_size_Mbytes: " - << double(cache_num_sets * RubyConfig::dataBlockBytes()) / (1<<20) << endl; + << double(cache_num_sets * RubySystem::getBlockSizeBytes()) / (1<<20) << endl; out << " cache_size_bytes: " - << cache_num_sets * RubyConfig::dataBlockBytes() * m_cache_assoc << endl; + << cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc << endl; out << " cache_size_Kbytes: " - << double(cache_num_sets * RubyConfig::dataBlockBytes() * m_cache_assoc) / (1<<10) << endl; + << double(cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc) / (1<<10) << endl; out << " cache_size_Mbytes: " - << double(cache_num_sets * RubyConfig::dataBlockBytes() * m_cache_assoc) / (1<<20) << endl; + << double(cache_num_sets * RubySystem::getBlockSizeBytes() * m_cache_assoc) / (1<<20) << endl; } // PRIVATE METHODS // convert a Address to its location in the cache -template<class ENTRY> inline -Index CacheMemory<ENTRY>::addressToCacheSet(const Address& address) const +Index CacheMemory::addressToCacheSet(const Address& address) const { assert(address == line_address(address)); Index temp = -1; - switch (m_machType) { - case MACHINETYPE_L1CACHE_ENUM: - temp = map_address_to_L1CacheSet(address, m_cache_num_set_bits); - break; - case MACHINETYPE_L2CACHE_ENUM: - temp = map_address_to_L2CacheSet(address, m_cache_num_set_bits); - break; - default: - ERROR_MSG("Don't recognize m_machType"); - } - assert(temp < m_cache_num_sets); - assert(temp >= 0); - return temp; + return address.bitSelect(RubySystem::getBlockSizeBits(), RubySystem::getBlockSizeBits() + m_cache_num_set_bits-1); } // Given a cache index: returns the index of the tag in a set. // returns -1 if the tag is not found. -template<class ENTRY> inline -int CacheMemory<ENTRY>::findTagInSet(Index cacheSet, const Address& tag) const +int CacheMemory::findTagInSet(Index cacheSet, const Address& tag) const { assert(tag == line_address(tag)); // search the set for the tags for (int i=0; i < m_cache_assoc; i++) { - if ((m_cache[cacheSet][i].m_Address == tag) && - (m_cache[cacheSet][i].m_Permission != AccessPermission_NotPresent)) { + if ((m_cache[cacheSet][i] != NULL) && + (m_cache[cacheSet][i]->m_Address == tag) && + (m_cache[cacheSet][i]->m_Permission != AccessPermission_NotPresent)) { return i; } } @@ -280,39 +356,37 @@ int CacheMemory<ENTRY>::findTagInSet(Index cacheSet, const Address& tag) const // Given a cache index: returns the index of the tag in a set. // returns -1 if the tag is not found. -template<class ENTRY> inline -int CacheMemory<ENTRY>::findTagInSetIgnorePermissions(Index cacheSet, const Address& tag) const +int CacheMemory::findTagInSetIgnorePermissions(Index cacheSet, const Address& tag) const { assert(tag == line_address(tag)); // search the set for the tags for (int i=0; i < m_cache_assoc; i++) { - if (m_cache[cacheSet][i].m_Address == tag) + if (m_cache[cacheSet][i] != NULL && m_cache[cacheSet][i]->m_Address == tag) return i; } return -1; // Not found } // PUBLIC METHODS -template<class ENTRY> inline -bool CacheMemory<ENTRY>::tryCacheAccess(const Address& address, - CacheRequestType type, - DataBlock*& data_ptr) +bool CacheMemory::tryCacheAccess(const Address& address, + CacheRequestType type, + DataBlock*& data_ptr) { assert(address == line_address(address)); DEBUG_EXPR(CACHE_COMP, HighPrio, address); Index cacheSet = addressToCacheSet(address); int loc = findTagInSet(cacheSet, address); if(loc != -1){ // Do we even have a tag match? - ENTRY& entry = m_cache[cacheSet][loc]; + AbstractCacheEntry* entry = m_cache[cacheSet][loc]; m_replacementPolicy_ptr->touch(cacheSet, loc, g_eventQueue_ptr->getTime()); - data_ptr = &(entry.getDataBlk()); + data_ptr = &(entry->getDataBlk()); - if(entry.m_Permission == AccessPermission_Read_Write) { + if(entry->m_Permission == AccessPermission_Read_Write) { return true; } - if ((entry.m_Permission == AccessPermission_Read_Only) && + if ((entry->m_Permission == AccessPermission_Read_Only) && (type == CacheRequestType_LD || type == CacheRequestType_IFETCH)) { return true; } @@ -322,31 +396,29 @@ bool CacheMemory<ENTRY>::tryCacheAccess(const Address& address, return false; } -template<class ENTRY> inline -bool CacheMemory<ENTRY>::testCacheAccess(const Address& address, - CacheRequestType type, - DataBlock*& data_ptr) +bool CacheMemory::testCacheAccess(const Address& address, + CacheRequestType type, + DataBlock*& data_ptr) { assert(address == line_address(address)); DEBUG_EXPR(CACHE_COMP, HighPrio, address); Index cacheSet = addressToCacheSet(address); int loc = findTagInSet(cacheSet, address); if(loc != -1){ // Do we even have a tag match? - ENTRY& entry = m_cache[cacheSet][loc]; + AbstractCacheEntry* entry = m_cache[cacheSet][loc]; m_replacementPolicy_ptr->touch(cacheSet, loc, g_eventQueue_ptr->getTime()); - data_ptr = &(entry.getDataBlk()); + data_ptr = &(entry->getDataBlk()); - return (m_cache[cacheSet][loc].m_Permission != AccessPermission_NotPresent); + return (m_cache[cacheSet][loc]->m_Permission != AccessPermission_NotPresent); } data_ptr = NULL; return false; } // tests to see if an address is present in the cache -template<class ENTRY> inline -bool CacheMemory<ENTRY>::isTagPresent(const Address& address) const +bool CacheMemory::isTagPresent(const Address& address) const { assert(address == line_address(address)); Index cacheSet = addressToCacheSet(address); @@ -366,31 +438,29 @@ bool CacheMemory<ENTRY>::isTagPresent(const Address& address) const // Returns true if there is: // a) a tag match on this address or there is // b) an unused line in the same cache "way" -template<class ENTRY> inline -bool CacheMemory<ENTRY>::cacheAvail(const Address& address) const +bool CacheMemory::cacheAvail(const Address& address) const { assert(address == line_address(address)); Index cacheSet = addressToCacheSet(address); for (int i=0; i < m_cache_assoc; i++) { - if (m_cache[cacheSet][i].m_Address == address) { - // Already in the cache - return true; - } - - if (m_cache[cacheSet][i].m_Permission == AccessPermission_NotPresent) { - // We found an empty entry + AbstractCacheEntry* entry = m_cache[cacheSet][i]; + if (entry != NULL) { + if (entry->m_Address == address || // Already in the cache + entry->m_Permission == AccessPermission_NotPresent) { // We found an empty entry + return true; + } + } else { return true; } } return false; } -template<class ENTRY> inline -void CacheMemory<ENTRY>::allocate(const Address& address) +void CacheMemory::allocate(const Address& address, AbstractCacheEntry* entry) { assert(address == line_address(address)); assert(!isTagPresent(address)); @@ -400,10 +470,11 @@ void CacheMemory<ENTRY>::allocate(const Address& address) // Find the first open slot Index cacheSet = addressToCacheSet(address); for (int i=0; i < m_cache_assoc; i++) { - if (m_cache[cacheSet][i].m_Permission == AccessPermission_NotPresent) { - m_cache[cacheSet][i] = ENTRY(); // Init entry - m_cache[cacheSet][i].m_Address = address; - m_cache[cacheSet][i].m_Permission = AccessPermission_Invalid; + if (m_cache[cacheSet][i] == NULL || + m_cache[cacheSet][i]->m_Permission == AccessPermission_NotPresent) { + m_cache[cacheSet][i] = entry; // Init entry + m_cache[cacheSet][i]->m_Address = address; + m_cache[cacheSet][i]->m_Permission = AccessPermission_Invalid; m_replacementPolicy_ptr->touch(cacheSet, i, g_eventQueue_ptr->getTime()); @@ -413,63 +484,62 @@ void CacheMemory<ENTRY>::allocate(const Address& address) ERROR_MSG("Allocate didn't find an available entry"); } -template<class ENTRY> inline -void CacheMemory<ENTRY>::deallocate(const Address& address) +void CacheMemory::deallocate(const Address& address) { assert(address == line_address(address)); assert(isTagPresent(address)); DEBUG_EXPR(CACHE_COMP, HighPrio, address); - lookup(address).m_Permission = AccessPermission_NotPresent; + Index cacheSet = addressToCacheSet(address); + int location = findTagInSet(cacheSet, address); + if (location != -1){ + delete m_cache[cacheSet][location]; + m_cache[cacheSet][location] = NULL; + } } // Returns with the physical address of the conflicting cache line -template<class ENTRY> inline -Address CacheMemory<ENTRY>::cacheProbe(const Address& address) const +Address CacheMemory::cacheProbe(const Address& address) const { assert(address == line_address(address)); assert(!cacheAvail(address)); Index cacheSet = addressToCacheSet(address); - return m_cache[cacheSet][m_replacementPolicy_ptr->getVictim(cacheSet)].m_Address; + return m_cache[cacheSet][m_replacementPolicy_ptr->getVictim(cacheSet)]->m_Address; } // looks an address up in the cache -template<class ENTRY> inline -ENTRY& CacheMemory<ENTRY>::lookup(const Address& address) +AbstractCacheEntry& CacheMemory::lookup(const Address& address) { assert(address == line_address(address)); Index cacheSet = addressToCacheSet(address); int loc = findTagInSet(cacheSet, address); assert(loc != -1); - return m_cache[cacheSet][loc]; + return *m_cache[cacheSet][loc]; } // looks an address up in the cache -template<class ENTRY> inline -const ENTRY& CacheMemory<ENTRY>::lookup(const Address& address) const +const AbstractCacheEntry& CacheMemory::lookup(const Address& address) const { assert(address == line_address(address)); Index cacheSet = addressToCacheSet(address); int loc = findTagInSet(cacheSet, address); assert(loc != -1); - return m_cache[cacheSet][loc]; + return *m_cache[cacheSet][loc]; } -template<class ENTRY> inline -AccessPermission CacheMemory<ENTRY>::getPermission(const Address& address) const +AccessPermission CacheMemory::getPermission(const Address& address) const { assert(address == line_address(address)); return lookup(address).m_Permission; } -template<class ENTRY> inline -void CacheMemory<ENTRY>::changePermission(const Address& address, AccessPermission new_perm) +void CacheMemory::changePermission(const Address& address, AccessPermission new_perm) { assert(address == line_address(address)); lookup(address).m_Permission = new_perm; @@ -477,9 +547,8 @@ void CacheMemory<ENTRY>::changePermission(const Address& address, AccessPermissi } // Sets the most recently used bit for a cache block -template<class ENTRY> inline -void CacheMemory<ENTRY>::setMRU(const Address& address) +void CacheMemory::setMRU(const Address& address) { Index cacheSet; @@ -489,19 +558,15 @@ void CacheMemory<ENTRY>::setMRU(const Address& address) g_eventQueue_ptr->getTime()); } -template<class ENTRY> inline -void CacheMemory<ENTRY>::recordCacheContents(CacheRecorder& tr) const +void CacheMemory::recordCacheContents(CacheRecorder& tr) const { -//dsm: Uses CacheRecorder, PRUNED -assert(false); - -/* for (int i = 0; i < m_cache_num_sets; i++) { + for (int i = 0; i < m_cache_num_sets; i++) { for (int j = 0; j < m_cache_assoc; j++) { - AccessPermission perm = m_cache[i][j].m_Permission; + AccessPermission perm = m_cache[i][j]->m_Permission; CacheRequestType request_type = CacheRequestType_NULL; if (perm == AccessPermission_Read_Only) { - if (m_is_instruction_cache) { + if (m_is_instruction_only_cache) { request_type = CacheRequestType_IFETCH; } else { request_type = CacheRequestType_LD; @@ -511,55 +576,59 @@ assert(false); } if (request_type != CacheRequestType_NULL) { - tr.addRecord(m_chip_ptr->getID(), m_cache[i][j].m_Address, - Address(0), request_type, m_replacementPolicy_ptr->getLastAccess(i, j)); + // tr.addRecord(m_chip_ptr->getID(), m_cache[i][j].m_Address, + // Address(0), request_type, m_replacementPolicy_ptr->getLastAccess(i, j)); } } - }*/ + } } -template<class ENTRY> inline -void CacheMemory<ENTRY>::print(ostream& out) const +void CacheMemory::print(ostream& out) const { - out << "Cache dump: " << m_description << endl; + out << "Cache dump: " << m_cache_name << endl; for (int i = 0; i < m_cache_num_sets; i++) { for (int j = 0; j < m_cache_assoc; j++) { - out << " Index: " << i - << " way: " << j - << " entry: " << m_cache[i][j] << endl; + if (m_cache[i][j] != NULL) { + out << " Index: " << i + << " way: " << j + << " entry: " << *m_cache[i][j] << endl; + } else { + out << " Index: " << i + << " way: " << j + << " entry: NULL" << endl; + } } } } -template<class ENTRY> inline -void CacheMemory<ENTRY>::printData(ostream& out) const +void CacheMemory::printData(ostream& out) const { out << "printData() not supported" << endl; } -template<class ENTRY> -void CacheMemory<ENTRY>::getMemoryValue(const Address& addr, char* value, - unsigned int size_in_bytes ){ - ENTRY entry = lookup(line_address(addr)); +inline +void CacheMemory::getMemoryValue(const Address& addr, char* value, + unsigned int size_in_bytes ){ + AbstractCacheEntry& entry = lookup(line_address(addr)); unsigned int startByte = addr.getAddress() - line_address(addr).getAddress(); for(unsigned int i=0; i<size_in_bytes; ++i){ - value[i] = entry.m_DataBlk.getByte(i + startByte); + value[i] = entry.getDataBlk().getByte(i + startByte); } } -template<class ENTRY> -void CacheMemory<ENTRY>::setMemoryValue(const Address& addr, char* value, - unsigned int size_in_bytes ){ - ENTRY& entry = lookup(line_address(addr)); +inline +void CacheMemory::setMemoryValue(const Address& addr, char* value, + unsigned int size_in_bytes ){ + AbstractCacheEntry& entry = lookup(line_address(addr)); unsigned int startByte = addr.getAddress() - line_address(addr).getAddress(); assert(size_in_bytes > 0); for(unsigned int i=0; i<size_in_bytes; ++i){ - entry.m_DataBlk.setByte(i + startByte, value[i]); + entry.getDataBlk().setByte(i + startByte, value[i]); } - entry = lookup(line_address(addr)); + // entry = lookup(line_address(addr)); } #endif //CACHEMEMORY_H |