diff options
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 |