#ifndef SOCLIB_CABA_MEM_CACHE_DIRECTORY_H #define SOCLIB_CABA_MEM_CACHE_DIRECTORY_H #include #include #include #include "arithmetics.h" // !!! // The L1_MULTI_CACHE mechanism does no longer work with the new pktid encoding // of TSAR. Turning the define below to a non null value will cause the memcache // to behave in an unpredicted way. // TODO Either remove the mechanism from the mem cache or update its behaviour. #define L1_MULTI_CACHE 0 //#define RANDOM_EVICTION namespace soclib { namespace caba { using namespace sc_core; //////////////////////////////////////////////////////////////////////// // A LRU entry //////////////////////////////////////////////////////////////////////// class LruEntry { public: bool recent; void init() { recent=false; } }; // end class LruEntry //////////////////////////////////////////////////////////////////////// // An Owner //////////////////////////////////////////////////////////////////////// class Owner{ typedef uint32_t size_t; public: // Fields bool inst; // Is the owner an ICache ? size_t srcid; // The SRCID of the owner #if L1_MULTI_CACHE size_t cache_id; // In multi_cache configuration #endif //////////////////////// // Constructors //////////////////////// Owner(bool i_inst ,size_t i_srcid #if L1_MULTI_CACHE ,size_t i_cache_id #endif ){ inst = i_inst; srcid = i_srcid; #if L1_MULTI_CACHE cache_id= i_cache_id; #endif } Owner(const Owner &a){ inst = a.inst; srcid = a.srcid; #if L1_MULTI_CACHE cache_id= a.cache_id; #endif } Owner(){ inst = false; srcid = 0; #if L1_MULTI_CACHE cache_id= 0; #endif } // end constructors }; // end class Owner //////////////////////////////////////////////////////////////////////// // A directory entry //////////////////////////////////////////////////////////////////////// class DirectoryEntry { typedef uint32_t tag_t; typedef uint32_t size_t; public: bool valid; // entry valid bool is_cnt; // directory entry is in counter mode bool dirty; // entry dirty bool lock; // entry locked tag_t tag; // tag of the entry size_t count; // number of copies Owner owner; // an owner of the line size_t ptr; // pointer to the next owner DirectoryEntry() { valid = false; is_cnt = false; dirty = false; lock = false; tag = 0; count = 0; owner.inst = 0; owner.srcid = 0; #if L1_MULTI_CACHE owner.cache_id= 0; #endif ptr = 0; } DirectoryEntry(const DirectoryEntry &source) { valid = source.valid; is_cnt = source.is_cnt; dirty = source.dirty; lock = source.lock; tag = source.tag; count = source.count; owner = source.owner; ptr = source.ptr; } ///////////////////////////////////////////////////////////////////// // The init() function initializes the entry ///////////////////////////////////////////////////////////////////// void init() { valid = false; is_cnt = false; dirty = false; lock = false; count = 0; } ///////////////////////////////////////////////////////////////////// // The copy() function copies an existing source entry to a target ///////////////////////////////////////////////////////////////////// void copy(const DirectoryEntry &source) { valid = source.valid; is_cnt = source.is_cnt; dirty = source.dirty; lock = source.lock; tag = source.tag; count = source.count; owner = source.owner; ptr = source.ptr; } //////////////////////////////////////////////////////////////////// // The print() function prints the entry //////////////////////////////////////////////////////////////////// void print() { std::cout << "Valid = " << valid << " ; IS COUNT = " << is_cnt << " ; Dirty = " << dirty << " ; Lock = " << lock << " ; Tag = " << std::hex << tag << std::dec << " ; Count = " << count << " ; Owner = " << owner.srcid #if L1_MULTI_CACHE << "." << owner.cache_id #endif << " " << owner.inst << " ; Pointer = " << ptr << std::endl; } }; // end class DirectoryEntry //////////////////////////////////////////////////////////////////////// // The directory //////////////////////////////////////////////////////////////////////// class CacheDirectory { typedef sc_dt::sc_uint<40> addr_t; typedef uint32_t data_t; typedef uint32_t tag_t; typedef uint32_t size_t; private: // Directory constants size_t m_ways; size_t m_sets; size_t m_words; size_t m_width; uint32_t lfsr; // the directory & lru tables DirectoryEntry **m_dir_tab; LruEntry **m_lru_tab; public: //////////////////////// // Constructor //////////////////////// CacheDirectory( size_t ways, size_t sets, size_t words, size_t address_width) { m_ways = ways; m_sets = sets; m_words = words; m_width = address_width; lfsr = -1; m_dir_tab = new DirectoryEntry*[sets]; for ( size_t i=0; i> (L2(m_words) + 2)) & (m_sets - 1); const tag_t tag = (tag_t)(address >> (L2(m_sets) + L2(m_words) + 2)); #undef L2 bool hit = false; for ( size_t i=0 ; i> (L2(m_words) + 2)) & (m_sets - 1); const tag_t tag = (tag_t)(address >> (L2(m_sets) + L2(m_words) + 2)); #undef L2 bool hit = false; for ( size_t i=0 ; i> 1) ^ ((-(lfsr & 1)) & 0xd0000001); way = lfsr % m_ways; return DirectoryEntry(m_dir_tab[set][way]); #endif for(size_t i=0; i0 && "Memory Cache, HeapDirectory constructor : invalid size"); ptr_free = 0; full = false; m_heap_tab = new HeapEntry[size]; tab_size = size; } // end constructor ///////////////// // Destructor ///////////////// ~HeapDirectory(){ delete [] m_heap_tab; } // end destructor ///////////////////////////////////////////////////////////////////// // Global initialisation function ///////////////////////////////////////////////////////////////////// void init(){ ptr_free=0; full=false; for(size_t i=0; i< tab_size-1;i++){ m_heap_tab[i].next = i+1; } m_heap_tab[tab_size-1].next = tab_size-1; return; } ///////////////////////////////////////////////////////////////////// // The print() function prints a selected directory entry // Arguments : // - ptr : the pointer to the entry to print ///////////////////////////////////////////////////////////////////// void print(const size_t &ptr){ std::cout << "Heap, printing the entry : " << std::dec << ptr << std::endl; m_heap_tab[ptr].print(); } // end print() ///////////////////////////////////////////////////////////////////// // The print_list() function prints a list from selected directory entry // Arguments : // - ptr : the pointer to the first entry to print ///////////////////////////////////////////////////////////////////// void print_list(const size_t &ptr){ bool end = false; size_t ptr_temp = ptr; std::cout << "Heap, printing the list from : " << std::dec << ptr << std::endl; while(!end){ m_heap_tab[ptr_temp].print(); if(ptr_temp == m_heap_tab[ptr_temp].next) end = true; ptr_temp = m_heap_tab[ptr_temp].next; } } // end print_list() ///////////////////////////////////////////////////////////////////// // The is_full() function return true if the heap is full. ///////////////////////////////////////////////////////////////////// bool is_full(){ return full; } // end is_full() ///////////////////////////////////////////////////////////////////// // The next_free_ptr() function returns the pointer // to the next free entry. ///////////////////////////////////////////////////////////////////// size_t next_free_ptr(){ return ptr_free; } // end next_free_ptr() ///////////////////////////////////////////////////////////////////// // The next_free_entry() function returns // a copy of the next free entry. ///////////////////////////////////////////////////////////////////// HeapEntry next_free_entry(){ return HeapEntry(m_heap_tab[ptr_free]); } // end next_free_entry() ///////////////////////////////////////////////////////////////////// // The write_free_entry() function modify the next free entry. // Arguments : // - entry : the entry to write ///////////////////////////////////////////////////////////////////// void write_free_entry(const HeapEntry &entry){ m_heap_tab[ptr_free].copy(entry); } // end write_free_entry() ///////////////////////////////////////////////////////////////////// // The write_free_ptr() function writes the pointer // to the next free entry ///////////////////////////////////////////////////////////////////// void write_free_ptr(const size_t &ptr){ assert( (ptr * cache_line) { assert((set < m_sets ) && "Cache data error: Trying to read a wrong set" ); assert((way < m_ways ) && "Cache data error: Trying to read a wrong way" ); for (uint32_t word=0; word