- Timestamp:
- Sep 30, 2014, 3:32:13 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/RWT/modules/vci_mem_cache/caba/source/include/mem_cache_directory.h
r814 r823 18 18 class LruEntry { 19 19 20 public: 21 22 bool recent; 23 20 public: 21 22 bool recent; 23 24 void init() 25 { 26 recent=false; 27 } 28 29 }; // end class LruEntry 30 31 //////////////////////////////////////////////////////////////////////// 32 // An Owner 33 //////////////////////////////////////////////////////////////////////// 34 class Owner{ 35 36 public: 37 38 // Fields 39 bool inst; // Is the owner an ICache ? 40 size_t srcid; // The SRCID of the owner 41 42 //////////////////////// 43 // Constructors 44 //////////////////////// 45 Owner(bool i_inst, 46 size_t i_srcid) 47 { 48 inst = i_inst; 49 srcid = i_srcid; 50 } 51 52 Owner(const Owner &a) 53 { 54 inst = a.inst; 55 srcid = a.srcid; 56 } 57 58 Owner() 59 { 60 inst = false; 61 srcid = 0; 62 } 63 // end constructors 64 65 }; // end class Owner 66 67 68 //////////////////////////////////////////////////////////////////////// 69 // A directory entry 70 //////////////////////////////////////////////////////////////////////// 71 class DirectoryEntry { 72 73 typedef uint32_t tag_t; 74 75 public: 76 77 bool valid; // entry valid 78 bool cache_coherent; // WB or WT policy 79 bool is_cnt; // directory entry is in counter mode 80 bool dirty; // entry dirty 81 bool lock; // entry locked 82 tag_t tag; // tag of the entry 83 size_t count; // number of copies 84 Owner owner; // an owner of the line 85 size_t ptr; // pointer to the next owner 86 87 DirectoryEntry() 88 { 89 valid = false; 90 cache_coherent = false; 91 is_cnt = false; 92 dirty = false; 93 lock = false; 94 tag = 0; 95 count = 0; 96 owner.inst = 0; 97 owner.srcid = 0; 98 ptr = 0; 99 } 100 101 DirectoryEntry(const DirectoryEntry &source) 102 { 103 valid = source.valid; 104 cache_coherent = source.cache_coherent; 105 is_cnt = source.is_cnt; 106 dirty = source.dirty; 107 lock = source.lock; 108 tag = source.tag; 109 count = source.count; 110 owner = source.owner; 111 ptr = source.ptr; 112 } 113 114 ///////////////////////////////////////////////////////////////////// 115 // The init() function initializes the entry 116 ///////////////////////////////////////////////////////////////////// 24 117 void init() 25 118 { 26 recent=false; 119 valid = false; 120 cache_coherent = false; 121 is_cnt = false; 122 dirty = false; 123 lock = false; 124 count = 0; 27 125 } 28 126 29 }; // end class LruEntry 30 31 //////////////////////////////////////////////////////////////////////// 32 // An Owner 33 //////////////////////////////////////////////////////////////////////// 34 class Owner{ 35 36 public: 37 // Fields 38 bool inst; // Is the owner an ICache ? 39 size_t srcid; // The SRCID of the owner 40 41 //////////////////////// 42 // Constructors 43 //////////////////////// 44 Owner(bool i_inst, 45 size_t i_srcid) 46 { 47 inst = i_inst; 48 srcid = i_srcid; 127 ///////////////////////////////////////////////////////////////////// 128 // The copy() function copies an existing source entry to a target 129 ///////////////////////////////////////////////////////////////////// 130 void copy(const DirectoryEntry &source) 131 { 132 valid = source.valid; 133 cache_coherent = source.cache_coherent; 134 is_cnt = source.is_cnt; 135 dirty = source.dirty; 136 lock = source.lock; 137 tag = source.tag; 138 count = source.count; 139 owner = source.owner; 140 ptr = source.ptr; 49 141 } 50 142 51 Owner(const Owner &a) 52 { 53 inst = a.inst; 54 srcid = a.srcid; 143 //////////////////////////////////////////////////////////////////// 144 // The print() function prints the entry 145 //////////////////////////////////////////////////////////////////// 146 void print() 147 { 148 std::cout << "Valid = " << valid 149 << " ; COHERENCE = " << cache_coherent 150 << " ; IS COUNT = " << is_cnt 151 << " ; Dirty = " << dirty 152 << " ; Lock = " << lock 153 << " ; Tag = " << std::hex << tag << std::dec 154 << " ; Count = " << count 155 << " ; Owner = " << owner.srcid 156 << " " << owner.inst 157 << " ; Pointer = " << ptr << std::endl; 55 158 } 56 159 57 Owner() 58 { 59 inst = false; 60 srcid = 0; 160 }; // end class DirectoryEntry 161 162 //////////////////////////////////////////////////////////////////////// 163 // The directory 164 //////////////////////////////////////////////////////////////////////// 165 class CacheDirectory { 166 167 typedef sc_dt::sc_uint<40> addr_t; 168 typedef uint32_t data_t; 169 typedef uint32_t tag_t; 170 171 private: 172 173 // Directory constants 174 size_t m_ways; 175 size_t m_sets; 176 size_t m_words; 177 size_t m_width; 178 uint32_t lfsr; 179 180 // the directory & lru tables 181 DirectoryEntry **m_dir_tab; 182 LruEntry **m_lru_tab; 183 184 public: 185 186 //////////////////////// 187 // Constructor 188 //////////////////////// 189 CacheDirectory(size_t ways, size_t sets, size_t words, size_t address_width) 190 { 191 m_ways = ways; 192 m_sets = sets; 193 m_words = words; 194 m_width = address_width; 195 lfsr = -1; 196 197 m_dir_tab = new DirectoryEntry*[sets]; 198 for (size_t i = 0; i < sets; i++) { 199 m_dir_tab[i] = new DirectoryEntry[ways]; 200 for (size_t j = 0; j < ways; j++) { 201 m_dir_tab[i][j].init(); 202 } 203 } 204 205 m_lru_tab = new LruEntry*[sets]; 206 for (size_t i = 0; i < sets; i++) { 207 m_lru_tab[i] = new LruEntry[ways]; 208 for (size_t j = 0; j < ways; j++) { 209 m_lru_tab[i][j].init(); 210 } 211 } 212 } // end constructor 213 214 ///////////////// 215 // Destructor 216 ///////////////// 217 ~CacheDirectory() 218 { 219 for (size_t i = 0; i < m_sets; i++) { 220 delete [] m_dir_tab[i]; 221 delete [] m_lru_tab[i]; 222 } 223 delete [] m_dir_tab; 224 delete [] m_lru_tab; 225 } // end destructor 226 227 ///////////////////////////////////////////////////////////////////// 228 // The read() function reads a directory entry. In case of hit, the 229 // LRU is updated. 230 // Arguments : 231 // - address : the address of the entry 232 // - way : (return argument) the way of the entry in case of hit 233 // The function returns a copy of a (valid or invalid) entry 234 ///////////////////////////////////////////////////////////////////// 235 DirectoryEntry read(const addr_t &address, size_t &way) 236 { 237 238 #define L2 soclib::common::uint32_log2 239 const size_t set = (size_t) (address >> (L2(m_words) + 2)) & (m_sets - 1); 240 const tag_t tag = (tag_t) (address >> (L2(m_sets) + L2(m_words) + 2)); 241 #undef L2 242 243 bool hit = false; 244 245 for (size_t i = 0; i < m_ways; i++) { 246 bool equal = (m_dir_tab[set][i].tag == tag); 247 bool valid = m_dir_tab[set][i].valid; 248 hit = equal && valid; 249 if (hit) { 250 way = i; 251 break; 252 } 253 } 254 if (hit) { 255 m_lru_tab[set][way].recent = true; 256 return DirectoryEntry(m_dir_tab[set][way]); 257 } else { 258 return DirectoryEntry(); 259 } 260 } // end read() 261 262 ///////////////////////////////////////////////////////////////////// 263 // The inval function invalidate an entry defined by the set and 264 // way arguments. 265 ///////////////////////////////////////////////////////////////////// 266 void inval( const size_t &way, const size_t &set ) 267 { 268 m_dir_tab[set][way].init(); 61 269 } 62 // end constructors 63 64 }; // end class Owner 65 66 67 //////////////////////////////////////////////////////////////////////// 68 // A directory entry 69 //////////////////////////////////////////////////////////////////////// 70 class DirectoryEntry { 71 72 typedef uint32_t tag_t; 73 74 public: 75 76 bool valid; // entry valid 77 bool cache_coherent; // WB or WT policy 78 bool is_cnt; // directory entry is in counter mode 79 bool dirty; // entry dirty 80 bool lock; // entry locked 81 tag_t tag; // tag of the entry 82 size_t count; // number of copies 83 Owner owner; // an owner of the line 84 size_t ptr; // pointer to the next owner 85 86 DirectoryEntry() 87 { 88 valid = false; 89 cache_coherent= false; 90 is_cnt = false; 91 dirty = false; 92 lock = false; 93 tag = 0; 94 count = 0; 95 owner.inst = 0; 96 owner.srcid = 0; 97 ptr = 0; 98 } 99 100 DirectoryEntry(const DirectoryEntry &source) 101 { 102 valid = source.valid; 103 cache_coherent= source.cache_coherent; 104 is_cnt = source.is_cnt; 105 dirty = source.dirty; 106 lock = source.lock; 107 tag = source.tag; 108 count = source.count; 109 owner = source.owner; 110 ptr = source.ptr; 111 } 112 113 ///////////////////////////////////////////////////////////////////// 114 // The init() function initializes the entry 115 ///////////////////////////////////////////////////////////////////// 116 void init() 117 { 118 valid = false; 119 cache_coherent = false; 120 is_cnt = false; 121 dirty = false; 122 lock = false; 123 count = 0; 124 } 125 126 ///////////////////////////////////////////////////////////////////// 127 // The copy() function copies an existing source entry to a target 128 ///////////////////////////////////////////////////////////////////// 129 void copy(const DirectoryEntry &source) 130 { 131 valid = source.valid; 132 cache_coherent = source.cache_coherent; 133 is_cnt = source.is_cnt; 134 dirty = source.dirty; 135 lock = source.lock; 136 tag = source.tag; 137 count = source.count; 138 owner = source.owner; 139 ptr = source.ptr; 140 } 141 142 //////////////////////////////////////////////////////////////////// 143 // The print() function prints the entry 144 //////////////////////////////////////////////////////////////////// 145 void print() 146 { 147 std::cout << "Valid = " << valid 148 << " ; COHERENCE = " << cache_coherent 149 << " ; IS COUNT = " << is_cnt 150 << " ; Dirty = " << dirty 151 << " ; Lock = " << lock 152 << " ; Tag = " << std::hex << tag << std::dec 153 << " ; Count = " << count 154 << " ; Owner = " << owner.srcid 155 << " " << owner.inst 156 << " ; Pointer = " << ptr << std::endl; 157 } 158 159 }; // end class DirectoryEntry 160 161 //////////////////////////////////////////////////////////////////////// 162 // The directory 163 //////////////////////////////////////////////////////////////////////// 164 class CacheDirectory { 165 166 typedef sc_dt::sc_uint<40> addr_t; 167 typedef uint32_t data_t; 168 typedef uint32_t tag_t; 169 170 private: 171 172 // Directory constants 173 size_t m_ways; 174 size_t m_sets; 175 size_t m_words; 176 size_t m_width; 177 uint32_t lfsr; 178 179 // the directory & lru tables 180 DirectoryEntry **m_dir_tab; 181 LruEntry **m_lru_tab; 182 183 public: 184 185 //////////////////////// 186 // Constructor 187 //////////////////////// 188 CacheDirectory( size_t ways, size_t sets, size_t words, size_t address_width) 189 { 190 m_ways = ways; 191 m_sets = sets; 192 m_words = words; 193 m_width = address_width; 194 lfsr = -1; 195 196 m_dir_tab = new DirectoryEntry*[sets]; 197 for ( size_t i=0; i<sets; i++ ) { 198 m_dir_tab[i] = new DirectoryEntry[ways]; 199 for ( size_t j=0 ; j<ways ; j++) m_dir_tab[i][j].init(); 200 } 201 m_lru_tab = new LruEntry*[sets]; 202 for ( size_t i=0; i<sets; i++ ) { 203 m_lru_tab[i] = new LruEntry[ways]; 204 for ( size_t j=0 ; j<ways ; j++) m_lru_tab[i][j].init(); 205 } 206 } // end constructor 207 208 ///////////////// 209 // Destructor 210 ///////////////// 211 ~CacheDirectory() 212 { 213 for(size_t i=0 ; i<m_sets ; i++){ 214 delete [] m_dir_tab[i]; 215 delete [] m_lru_tab[i]; 216 } 217 delete [] m_dir_tab; 218 delete [] m_lru_tab; 219 } // end destructor 220 221 ///////////////////////////////////////////////////////////////////// 222 // The read() function reads a directory entry. In case of hit, the 223 // LRU is updated. 224 // Arguments : 225 // - address : the address of the entry 226 // - way : (return argument) the way of the entry in case of hit 227 // The function returns a copy of a (valid or invalid) entry 228 ///////////////////////////////////////////////////////////////////// 229 DirectoryEntry read(const addr_t &address, size_t &way) 230 { 270 271 ///////////////////////////////////////////////////////////////////// 272 // The read_neutral() function reads a directory entry, without 273 // changing the LRU 274 // Arguments : 275 // - address : the address of the entry 276 // The function returns a copy of a (valid or invalid) entry 277 ///////////////////////////////////////////////////////////////////// 278 DirectoryEntry read_neutral(const addr_t &address, 279 size_t* ret_way, 280 size_t* ret_set) 281 { 231 282 232 283 #define L2 soclib::common::uint32_log2 233 constsize_t set = (size_t)(address >> (L2(m_words) + 2)) & (m_sets - 1);234 consttag_t tag = (tag_t)(address >> (L2(m_sets) + L2(m_words) + 2));284 size_t set = (size_t)(address >> (L2(m_words) + 2)) & (m_sets - 1); 285 tag_t tag = (tag_t)(address >> (L2(m_sets) + L2(m_words) + 2)); 235 286 #undef L2 236 287 237 bool hit = false; 238 for ( size_t i=0 ; i<m_ways ; i++ ) { 239 bool equal = ( m_dir_tab[set][i].tag == tag ); 240 bool valid = m_dir_tab[set][i].valid; 241 hit = equal && valid; 242 if ( hit ) { 243 way = i; 244 break; 245 } 246 } 247 if ( hit ) { 248 m_lru_tab[set][way].recent = true; 249 return DirectoryEntry(m_dir_tab[set][way]); 250 } else { 251 return DirectoryEntry(); 252 } 253 } // end read() 254 255 ///////////////////////////////////////////////////////////////////// 256 // The inval function invalidate an entry defined by the set and 257 // way arguments. 258 ///////////////////////////////////////////////////////////////////// 259 void inval( const size_t &way, const size_t &set ) 260 { 261 m_dir_tab[set][way].init(); 262 } 263 264 ///////////////////////////////////////////////////////////////////// 265 // The read_neutral() function reads a directory entry, without 266 // changing the LRU 267 // Arguments : 268 // - address : the address of the entry 269 // The function returns a copy of a (valid or invalid) entry 270 ///////////////////////////////////////////////////////////////////// 271 DirectoryEntry read_neutral( const addr_t &address, 272 size_t* ret_way, 273 size_t* ret_set ) 274 { 275 276 #define L2 soclib::common::uint32_log2 277 size_t set = (size_t)(address >> (L2(m_words) + 2)) & (m_sets - 1); 278 tag_t tag = (tag_t)(address >> (L2(m_sets) + L2(m_words) + 2)); 279 #undef L2 280 281 for ( size_t way = 0 ; way < m_ways ; way++ ) 282 { 283 bool equal = ( m_dir_tab[set][way].tag == tag ); 284 bool valid = m_dir_tab[set][way].valid; 285 if ( equal and valid ) 286 { 287 *ret_set = set; 288 *ret_way = way; 289 return DirectoryEntry(m_dir_tab[set][way]); 290 } 291 } 292 return DirectoryEntry(); 293 } // end read_neutral() 294 295 ///////////////////////////////////////////////////////////////////// 296 // The write function writes a new entry, 297 // and updates the LRU bits if necessary. 298 // Arguments : 299 // - set : the set of the entry 300 // - way : the way of the entry 301 // - entry : the entry value 302 ///////////////////////////////////////////////////////////////////// 303 void write( const size_t &set, 304 const size_t &way, 305 const DirectoryEntry &entry) 306 { 307 assert( (set<m_sets) 308 && "Cache Directory write : The set index is invalid"); 309 assert( (way<m_ways) 310 && "Cache Directory write : The way index is invalid"); 311 312 // update Directory 313 m_dir_tab[set][way].copy(entry); 314 315 // update LRU bits 316 bool all_recent = true; 317 for ( size_t i=0 ; i<m_ways ; i++ ) 318 { 319 if ( i != way ) all_recent = m_lru_tab[set][i].recent && all_recent; 320 } 321 if ( all_recent ) 322 { 323 for( size_t i=0 ; i<m_ways ; i++ ) m_lru_tab[set][i].recent = false; 324 } 325 else 326 { 327 m_lru_tab[set][way].recent = true; 328 } 329 } // end write() 330 331 ///////////////////////////////////////////////////////////////////// 332 // The print() function prints a selected directory entry 333 // Arguments : 334 // - set : the set of the entry to print 335 // - way : the way of the entry to print 336 ///////////////////////////////////////////////////////////////////// 337 void print(const size_t &set, const size_t &way) 338 { 339 std::cout << std::dec << " set : " << set << " ; way : " << way << " ; " ; 340 m_dir_tab[set][way].print(); 341 } // end print() 342 343 ///////////////////////////////////////////////////////////////////// 344 // The select() function selects a directory entry to evince. 345 // Arguments : 346 // - set : (input argument) the set to modify 347 // - way : (return argument) the way to evince 348 ///////////////////////////////////////////////////////////////////// 349 DirectoryEntry select(const size_t &set, size_t &way) 350 { 351 assert( (set < m_sets) 352 && "Cache Directory : (select) The set index is invalid"); 353 354 // looking for an empty slot 355 for(size_t i=0; i<m_ways; i++) 356 { 357 if( not m_dir_tab[set][i].valid ) 358 { 359 way=i; 360 return DirectoryEntry(m_dir_tab[set][way]); 361 } 362 } 288 for (size_t way = 0; way < m_ways; way++) 289 { 290 bool equal = (m_dir_tab[set][way].tag == tag); 291 bool valid = m_dir_tab[set][way].valid; 292 if (equal and valid) 293 { 294 *ret_set = set; 295 *ret_way = way; 296 return DirectoryEntry(m_dir_tab[set][way]); 297 } 298 } 299 return DirectoryEntry(); 300 } // end read_neutral() 301 302 ///////////////////////////////////////////////////////////////////// 303 // The write function writes a new entry, 304 // and updates the LRU bits if necessary. 305 // Arguments : 306 // - set : the set of the entry 307 // - way : the way of the entry 308 // - entry : the entry value 309 ///////////////////////////////////////////////////////////////////// 310 void write(const size_t &set, 311 const size_t &way, 312 const DirectoryEntry &entry) 313 { 314 assert((set<m_sets) 315 && "Cache Directory write : The set index is invalid"); 316 assert((way<m_ways) 317 && "Cache Directory write : The way index is invalid"); 318 319 // update Directory 320 m_dir_tab[set][way].copy(entry); 321 322 // update LRU bits 323 bool all_recent = true; 324 for (size_t i = 0; i < m_ways; i++) 325 { 326 if (i != way) 327 { 328 all_recent = m_lru_tab[set][i].recent && all_recent; 329 } 330 } 331 if (all_recent) 332 { 333 for (size_t i = 0; i < m_ways; i++) 334 { 335 m_lru_tab[set][i].recent = false; 336 } 337 } 338 else 339 { 340 m_lru_tab[set][way].recent = true; 341 } 342 } // end write() 343 344 ///////////////////////////////////////////////////////////////////// 345 // The print() function prints a selected directory entry 346 // Arguments : 347 // - set : the set of the entry to print 348 // - way : the way of the entry to print 349 ///////////////////////////////////////////////////////////////////// 350 void print(const size_t &set, const size_t &way) 351 { 352 std::cout << std::dec << " set : " << set << " ; way : " << way << " ; "; 353 m_dir_tab[set][way].print(); 354 } // end print() 355 356 ///////////////////////////////////////////////////////////////////// 357 // The select() function selects a directory entry to evince. 358 // Arguments : 359 // - set : (input argument) the set to modify 360 // - way : (return argument) the way to evince 361 ///////////////////////////////////////////////////////////////////// 362 DirectoryEntry select(const size_t &set, size_t &way) 363 { 364 assert((set < m_sets) 365 && "Cache Directory : (select) The set index is invalid"); 366 367 // looking for an empty slot 368 for (size_t i = 0; i < m_ways; i++) 369 { 370 if (not m_dir_tab[set][i].valid) 371 { 372 way = i; 373 return DirectoryEntry(m_dir_tab[set][way]); 374 } 375 } 363 376 364 377 #ifdef RANDOM_EVICTION 365 lfsr = (lfsr >> 1) ^ ((-(lfsr & 1)) & 0xd0000001);366 way = lfsr % m_ways;367 return DirectoryEntry(m_dir_tab[set][way]);378 lfsr = (lfsr >> 1) ^ ((-(lfsr & 1)) & 0xd0000001); 379 way = lfsr % m_ways; 380 return DirectoryEntry(m_dir_tab[set][way]); 368 381 #endif 369 382 370 // looking for a not locked and not recently used entry371 for(size_t i=0; i<m_ways; i++)372 {373 if((not m_lru_tab[set][i].recent) && (not m_dir_tab[set][i].lock))374 {375 way=i;376 return DirectoryEntry(m_dir_tab[set][way]);377 }378 }379 380 // looking for a locked not recently used entry381 for(size_t i=0; i<m_ways; i++)382 {383 if( (not m_lru_tab[set][i].recent) &&(m_dir_tab[set][i].lock))384 {385 way=i;386 return DirectoryEntry(m_dir_tab[set][way]);387 }388 }389 390 // looking for a recently used entry not locked391 for(size_t i=0; i<m_ways; i++)392 {393 if( (m_lru_tab[set][i].recent) &&(not m_dir_tab[set][i].lock))394 {395 way=i;396 return DirectoryEntry(m_dir_tab[set][way]);397 }398 }399 400 // select way 0 (even if entry is locked and recently used)401 way = 0;402 return DirectoryEntry(m_dir_tab[set][0]);403 } // end select()404 405 /////////////////////////////////////////////////////////////////////406 // Global initialisation function407 /////////////////////////////////////////////////////////////////////408 void init()409 {410 for ( size_t set=0 ; set<m_sets ; set++)411 {412 for ( size_t way=0 ; way<m_ways ; way++)413 {414 m_dir_tab[set][way].init();415 m_lru_tab[set][way].init();416 }417 }418 } // end init()383 // looking for a not locked and not recently used entry 384 for (size_t i = 0; i < m_ways; i++) 385 { 386 if ((not m_lru_tab[set][i].recent) and (not m_dir_tab[set][i].lock)) 387 { 388 way = i; 389 return DirectoryEntry(m_dir_tab[set][way]); 390 } 391 } 392 393 // looking for a locked not recently used entry 394 for (size_t i = 0; i < m_ways; i++) 395 { 396 if ((not m_lru_tab[set][i].recent) and (m_dir_tab[set][i].lock)) 397 { 398 way = i; 399 return DirectoryEntry(m_dir_tab[set][way]); 400 } 401 } 402 403 // looking for a recently used entry not locked 404 for (size_t i = 0; i < m_ways; i++) 405 { 406 if ((m_lru_tab[set][i].recent) and (not m_dir_tab[set][i].lock)) 407 { 408 way = i; 409 return DirectoryEntry(m_dir_tab[set][way]); 410 } 411 } 412 413 // select way 0 (even if entry is locked and recently used) 414 way = 0; 415 return DirectoryEntry(m_dir_tab[set][0]); 416 } // end select() 417 418 ///////////////////////////////////////////////////////////////////// 419 // Global initialisation function 420 ///////////////////////////////////////////////////////////////////// 421 void init() 422 { 423 for (size_t set = 0; set < m_sets; set++) 424 { 425 for (size_t way = 0; way < m_ways; way++) 426 { 427 m_dir_tab[set][way].init(); 428 m_lru_tab[set][way].init(); 429 } 430 } 431 } // end init() 419 432 420 433 }; // end class CacheDirectory … … 425 438 class HeapEntry{ 426 439 427 public: 428 // Fields of the entry 429 Owner owner; 430 size_t next; 431 432 //////////////////////// 433 // Constructor 434 //////////////////////// 435 HeapEntry() 436 :owner(false,0) 437 { 438 next = 0; 439 } // end constructor 440 441 //////////////////////// 442 // Constructor 443 //////////////////////// 444 HeapEntry(const HeapEntry &entry) 445 { 446 owner.inst = entry.owner.inst; 447 owner.srcid = entry.owner.srcid; 448 next = entry.next; 449 } // end constructor 450 451 ///////////////////////////////////////////////////////////////////// 452 // The copy() function copies an existing source entry to a target 453 ///////////////////////////////////////////////////////////////////// 454 void copy(const HeapEntry &entry) 455 { 456 owner.inst = entry.owner.inst; 457 owner.srcid = entry.owner.srcid; 458 next = entry.next; 459 } // end copy() 460 461 //////////////////////////////////////////////////////////////////// 462 // The print() function prints the entry 463 //////////////////////////////////////////////////////////////////// 464 void print(){ 465 std::cout 466 << " -- owner.inst : " << std::dec << owner.inst << std::endl 467 << " -- owner.srcid : " << std::dec << owner.srcid << std::endl 468 << " -- next : " << std::dec << next << std::endl; 469 470 } // end print() 440 public: 441 // Fields of the entry 442 Owner owner; 443 size_t next; 444 445 //////////////////////// 446 // Constructor 447 //////////////////////// 448 HeapEntry() 449 :owner(false, 0) 450 { 451 next = 0; 452 } // end constructor 453 454 //////////////////////// 455 // Constructor 456 //////////////////////// 457 HeapEntry(const HeapEntry &entry) 458 { 459 owner.inst = entry.owner.inst; 460 owner.srcid = entry.owner.srcid; 461 next = entry.next; 462 } // end constructor 463 464 ///////////////////////////////////////////////////////////////////// 465 // The copy() function copies an existing source entry to a target 466 ///////////////////////////////////////////////////////////////////// 467 void copy(const HeapEntry &entry) 468 { 469 owner.inst = entry.owner.inst; 470 owner.srcid = entry.owner.srcid; 471 next = entry.next; 472 } // end copy() 473 474 //////////////////////////////////////////////////////////////////// 475 // The print() function prints the entry 476 //////////////////////////////////////////////////////////////////// 477 void print() 478 { 479 std::cout 480 << " -- owner.inst : " << std::dec << owner.inst << std::endl 481 << " -- owner.srcid : " << std::dec << owner.srcid << std::endl 482 << " -- next : " << std::dec << next << std::endl; 483 484 } // end print() 471 485 472 486 }; // end class HeapEntry … … 477 491 class HeapDirectory{ 478 492 479 private: 480 // Registers and the heap 481 size_t ptr_free; 482 bool full; 483 HeapEntry *m_heap_tab; 484 485 // Constants for debugging purpose 486 size_t tab_size; 487 488 public: 489 //////////////////////// 490 // Constructor 491 //////////////////////// 492 HeapDirectory(uint32_t size){ 493 assert(size>0 && "Memory Cache, HeapDirectory constructor : invalid size"); 494 ptr_free = 0; 495 full = false; 496 m_heap_tab = new HeapEntry[size]; 497 tab_size = size; 498 } // end constructor 499 500 ///////////////// 501 // Destructor 502 ///////////////// 503 ~HeapDirectory(){ 504 delete [] m_heap_tab; 505 } // end destructor 506 507 ///////////////////////////////////////////////////////////////////// 508 // Global initialisation function 509 ///////////////////////////////////////////////////////////////////// 510 void init(){ 511 ptr_free=0; 512 full=false; 513 for(size_t i=0; i< tab_size-1;i++){ 514 m_heap_tab[i].next = i+1; 515 } 516 m_heap_tab[tab_size-1].next = tab_size-1; 517 return; 518 } 519 520 ///////////////////////////////////////////////////////////////////// 521 // The print() function prints a selected directory entry 522 // Arguments : 523 // - ptr : the pointer to the entry to print 524 ///////////////////////////////////////////////////////////////////// 525 void print(const size_t &ptr){ 526 std::cout << "Heap, printing the entry : " << std::dec << ptr << std::endl; 527 m_heap_tab[ptr].print(); 528 } // end print() 529 530 ///////////////////////////////////////////////////////////////////// 531 // The print_list() function prints a list from selected directory entry 532 // Arguments : 533 // - ptr : the pointer to the first entry to print 534 ///////////////////////////////////////////////////////////////////// 535 void print_list(const size_t &ptr){ 536 bool end = false; 537 size_t ptr_temp = ptr; 538 std::cout << "Heap, printing the list from : " << std::dec << ptr << std::endl; 539 while(!end){ 540 m_heap_tab[ptr_temp].print(); 541 if(ptr_temp == m_heap_tab[ptr_temp].next) end = true; 542 ptr_temp = m_heap_tab[ptr_temp].next; 543 } 544 } // end print_list() 545 546 ///////////////////////////////////////////////////////////////////// 547 // The is_full() function return true if the heap is full. 548 ///////////////////////////////////////////////////////////////////// 549 bool is_full(){ 550 return full; 551 } // end is_full() 552 553 ///////////////////////////////////////////////////////////////////// 554 // The next_free_ptr() function returns the pointer 555 // to the next free entry. 556 ///////////////////////////////////////////////////////////////////// 557 size_t next_free_ptr(){ 558 return ptr_free; 559 } // end next_free_ptr() 560 561 ///////////////////////////////////////////////////////////////////// 562 // The next_free_entry() function returns 563 // a copy of the next free entry. 564 ///////////////////////////////////////////////////////////////////// 565 HeapEntry next_free_entry(){ 566 return HeapEntry(m_heap_tab[ptr_free]); 567 } // end next_free_entry() 568 569 ///////////////////////////////////////////////////////////////////// 570 // The write_free_entry() function modify the next free entry. 571 // Arguments : 572 // - entry : the entry to write 573 ///////////////////////////////////////////////////////////////////// 574 void write_free_entry(const HeapEntry &entry){ 575 m_heap_tab[ptr_free].copy(entry); 576 } // end write_free_entry() 577 578 ///////////////////////////////////////////////////////////////////// 579 // The write_free_ptr() function writes the pointer 580 // to the next free entry 581 ///////////////////////////////////////////////////////////////////// 582 void write_free_ptr(const size_t &ptr){ 583 assert( (ptr<tab_size) && "HeapDirectory error : try to write a wrong free pointer"); 584 ptr_free = ptr; 585 } // end write_free_ptr() 586 587 ///////////////////////////////////////////////////////////////////// 588 // The set_full() function sets the full bit (to true). 589 ///////////////////////////////////////////////////////////////////// 590 void set_full(){ 591 full = true; 592 } // end set_full() 593 594 ///////////////////////////////////////////////////////////////////// 595 // The unset_full() function unsets the full bit (to false). 596 ///////////////////////////////////////////////////////////////////// 597 void unset_full(){ 598 full = false; 599 } // end unset_full() 600 601 ///////////////////////////////////////////////////////////////////// 602 // The read() function returns a copy of 603 // the entry pointed by the argument 604 // Arguments : 605 // - ptr : the pointer to the entry to read 606 ///////////////////////////////////////////////////////////////////// 607 HeapEntry read(const size_t &ptr){ 608 assert( (ptr<tab_size) && "HeapDirectory error : try to write a wrong free pointer"); 609 return HeapEntry(m_heap_tab[ptr]); 610 } // end read() 611 612 ///////////////////////////////////////////////////////////////////// 613 // The write() function writes an entry in the heap 614 // Arguments : 615 // - ptr : the pointer to the entry to replace 616 // - entry : the entry to write 617 ///////////////////////////////////////////////////////////////////// 618 void write(const size_t &ptr, const HeapEntry &entry){ 619 assert( (ptr<tab_size) && "HeapDirectory error : try to write a wrong free pointer"); 620 m_heap_tab[ptr].copy(entry); 621 } // end write() 493 private: 494 // Registers and the heap 495 size_t ptr_free; 496 bool full; 497 HeapEntry *m_heap_tab; 498 499 // Constants for debugging purpose 500 size_t tab_size; 501 502 public: 503 //////////////////////// 504 // Constructor 505 //////////////////////// 506 HeapDirectory(uint32_t size) 507 { 508 assert(size > 0 && "Memory Cache, HeapDirectory constructor : invalid size"); 509 ptr_free = 0; 510 full = false; 511 m_heap_tab = new HeapEntry[size]; 512 tab_size = size; 513 } // end constructor 514 515 ///////////////// 516 // Destructor 517 ///////////////// 518 ~HeapDirectory() 519 { 520 delete [] m_heap_tab; 521 } // end destructor 522 523 ///////////////////////////////////////////////////////////////////// 524 // Global initialisation function 525 ///////////////////////////////////////////////////////////////////// 526 void init() 527 { 528 ptr_free = 0; 529 full = false; 530 for (size_t i = 0; i < tab_size - 1; i++) { 531 m_heap_tab[i].next = i + 1; 532 } 533 m_heap_tab[tab_size - 1].next = tab_size - 1; 534 return; 535 } 536 537 ///////////////////////////////////////////////////////////////////// 538 // The print() function prints a selected directory entry 539 // Arguments : 540 // - ptr : the pointer to the entry to print 541 ///////////////////////////////////////////////////////////////////// 542 void print(const size_t &ptr) 543 { 544 std::cout << "Heap, printing the entry : " << std::dec << ptr << std::endl; 545 m_heap_tab[ptr].print(); 546 } // end print() 547 548 ///////////////////////////////////////////////////////////////////// 549 // The print_list() function prints a list from selected directory entry 550 // Arguments : 551 // - ptr : the pointer to the first entry to print 552 ///////////////////////////////////////////////////////////////////// 553 void print_list(const size_t &ptr) 554 { 555 bool end = false; 556 size_t ptr_temp = ptr; 557 std::cout << "Heap, printing the list from : " << std::dec << ptr << std::endl; 558 while (!end) { 559 m_heap_tab[ptr_temp].print(); 560 if (ptr_temp == m_heap_tab[ptr_temp].next) { 561 end = true; 562 } 563 ptr_temp = m_heap_tab[ptr_temp].next; 564 } 565 } // end print_list() 566 567 ///////////////////////////////////////////////////////////////////// 568 // The is_full() function return true if the heap is full. 569 ///////////////////////////////////////////////////////////////////// 570 bool is_full() 571 { 572 return full; 573 } // end is_full() 574 575 ///////////////////////////////////////////////////////////////////// 576 // The next_free_ptr() function returns the pointer 577 // to the next free entry. 578 ///////////////////////////////////////////////////////////////////// 579 size_t next_free_ptr() 580 { 581 return ptr_free; 582 } // end next_free_ptr() 583 584 ///////////////////////////////////////////////////////////////////// 585 // The next_free_entry() function returns 586 // a copy of the next free entry. 587 ///////////////////////////////////////////////////////////////////// 588 HeapEntry next_free_entry() 589 { 590 return HeapEntry(m_heap_tab[ptr_free]); 591 } // end next_free_entry() 592 593 ///////////////////////////////////////////////////////////////////// 594 // The write_free_entry() function modify the next free entry. 595 // Arguments : 596 // - entry : the entry to write 597 ///////////////////////////////////////////////////////////////////// 598 void write_free_entry(const HeapEntry &entry) 599 { 600 m_heap_tab[ptr_free].copy(entry); 601 } // end write_free_entry() 602 603 ///////////////////////////////////////////////////////////////////// 604 // The write_free_ptr() function writes the pointer 605 // to the next free entry 606 ///////////////////////////////////////////////////////////////////// 607 void write_free_ptr(const size_t &ptr) 608 { 609 assert((ptr < tab_size) && "HeapDirectory error : try to write a wrong free pointer"); 610 ptr_free = ptr; 611 } // end write_free_ptr() 612 613 ///////////////////////////////////////////////////////////////////// 614 // The set_full() function sets the full bit (to true). 615 ///////////////////////////////////////////////////////////////////// 616 void set_full() 617 { 618 full = true; 619 } // end set_full() 620 621 ///////////////////////////////////////////////////////////////////// 622 // The unset_full() function unsets the full bit (to false). 623 ///////////////////////////////////////////////////////////////////// 624 void unset_full() 625 { 626 full = false; 627 } // end unset_full() 628 629 ///////////////////////////////////////////////////////////////////// 630 // The read() function returns a copy of 631 // the entry pointed by the argument 632 // Arguments : 633 // - ptr : the pointer to the entry to read 634 ///////////////////////////////////////////////////////////////////// 635 HeapEntry read(const size_t &ptr) 636 { 637 assert((ptr < tab_size) && "HeapDirectory error : try to write a wrong free pointer"); 638 return HeapEntry(m_heap_tab[ptr]); 639 } // end read() 640 641 ///////////////////////////////////////////////////////////////////// 642 // The write() function writes an entry in the heap 643 // Arguments : 644 // - ptr : the pointer to the entry to replace 645 // - entry : the entry to write 646 ///////////////////////////////////////////////////////////////////// 647 void write(const size_t &ptr, const HeapEntry &entry) 648 { 649 assert((ptr < tab_size) && "HeapDirectory error : try to write a wrong free pointer"); 650 m_heap_tab[ptr].copy(entry); 651 } // end write() 622 652 623 653 }; // end class HeapDirectory … … 628 658 class CacheData 629 659 { 630 private:631 const uint32_t m_sets;632 const uint32_t m_ways;633 const uint32_t m_words;634 635 uint32_t *** m_cache_data;636 637 public:638 639 ///////////////////////////////////////////////////////640 CacheData(uint32_t ways, uint32_t sets, uint32_t words)641 : m_sets(sets), m_ways(ways), m_words(words)642 {643 m_cache_data = new uint32_t ** [ways];644 for ( size_t i=0 ; i < ways ; i++)645 {646 m_cache_data[i] = new uint32_t * [sets];647 }648 for ( size_t i=0; i<ways; i++)649 {650 for ( size_t j=0; j<sets; j++)651 {652 m_cache_data[i][j] = new uint32_t [words];653 }654 }655 }656 ////////////657 ~CacheData()658 {659 for(size_t i=0; i<m_ways; i++)660 {661 for(size_t j=0; j<m_sets; j++)662 {663 delete [] m_cache_data[i][j];664 }665 }666 for(size_t i=0; i<m_ways; i++)667 {668 delete [] m_cache_data[i];669 }670 delete [] m_cache_data;671 }672 //////////////////////////////////////////673 uint32_t read (const uint32_t &way,674 const uint32_t &set,675 const uint32_t &word) const676 {677 assert((set < m_sets ) && "Cache data error: Trying to read a wrong set");678 assert((way < m_ways ) && "Cache data error: Trying to read a wrong way");679 assert((word < m_words) && "Cache data error: Trying to read a wrong word");680 681 return m_cache_data[way][set][word];682 }683 //////////////////////////////////////////684 void read_line(const uint32_t &way,685 const uint32_t &set,686 sc_core::sc_signal<uint32_t> * cache_line)687 {688 assert((set < m_sets ) && "Cache data error: Trying to read a wrong set");689 assert((way < m_ways ) && "Cache data error: Trying to read a wrong way");690 691 for (uint32_t word=0; word<m_words; word++)692 cache_line[word].write(m_cache_data[way][set][word]);693 }694 /////////////////////////////////////////695 void write ( const uint32_t &way,696 const uint32_t &set,697 const uint32_t &word,698 const uint32_t &data,699 const uint32_t &be = 0xF)700 {701 702 assert((set < m_sets ) && "Cache data error: Trying to write a wrong set");703 assert((way < m_ways ) && "Cache data error: Trying to write a wrong way");704 assert((word < m_words) && "Cache data error: Trying to write a wrong word");705 assert((be <= 0xF ) && "Cache data error: Trying to write a wrong be");706 707 if (be == 0x0) return;708 709 if (be == 0xF)710 {711 m_cache_data[way][set][word] = data;712 return;713 }714 715 uint32_t mask = 0;716 if(be & 0x1) mask = mask | 0x000000FF;717 if(be & 0x2) mask = mask | 0x0000FF00;718 if(be & 0x4) mask = mask | 0x00FF0000;719 if(be & 0x8) mask = mask | 0xFF000000;720 721 m_cache_data[way][set][word] =722 (data & mask) | (m_cache_data[way][set][word] & ~mask);723 }660 private: 661 const uint32_t m_sets; 662 const uint32_t m_ways; 663 const uint32_t m_words; 664 665 uint32_t *** m_cache_data; 666 667 public: 668 669 /////////////////////////////////////////////////////// 670 CacheData(uint32_t ways, uint32_t sets, uint32_t words) 671 : m_sets(sets), m_ways(ways), m_words(words) 672 { 673 m_cache_data = new uint32_t ** [ways]; 674 for (size_t i = 0; i < ways; i++) 675 { 676 m_cache_data[i] = new uint32_t * [sets]; 677 } 678 for (size_t i = 0; i < ways; i++) 679 { 680 for (size_t j = 0; j < sets; j++) 681 { 682 m_cache_data[i][j] = new uint32_t [words]; 683 } 684 } 685 } 686 //////////// 687 ~CacheData() 688 { 689 for (size_t i = 0; i < m_ways; i++) 690 { 691 for (size_t j = 0; j < m_sets; j++) 692 { 693 delete [] m_cache_data[i][j]; 694 } 695 } 696 for (size_t i = 0; i < m_ways; i++) 697 { 698 delete [] m_cache_data[i]; 699 } 700 delete [] m_cache_data; 701 } 702 ////////////////////////////////////////// 703 uint32_t read(const uint32_t &way, 704 const uint32_t &set, 705 const uint32_t &word) const 706 { 707 assert((set < m_sets ) && "Cache data error: Trying to read a wrong set"); 708 assert((way < m_ways ) && "Cache data error: Trying to read a wrong way"); 709 assert((word < m_words) && "Cache data error: Trying to read a wrong word"); 710 711 return m_cache_data[way][set][word]; 712 } 713 ////////////////////////////////////////// 714 void read_line(const uint32_t &way, 715 const uint32_t &set, 716 sc_core::sc_signal<uint32_t> * cache_line) 717 { 718 assert((set < m_sets) && "Cache data error: Trying to read a wrong set"); 719 assert((way < m_ways) && "Cache data error: Trying to read a wrong way"); 720 721 for (uint32_t word = 0; word < m_words; word++) { 722 cache_line[word].write(m_cache_data[way][set][word]); 723 } 724 } 725 ///////////////////////////////////////// 726 void write(const uint32_t &way, 727 const uint32_t &set, 728 const uint32_t &word, 729 const uint32_t &data, 730 const uint32_t &be = 0xF) 731 { 732 assert((set < m_sets ) && "Cache data error: Trying to write a wrong set"); 733 assert((way < m_ways ) && "Cache data error: Trying to write a wrong way"); 734 assert((word < m_words) && "Cache data error: Trying to write a wrong word"); 735 assert((be <= 0xF ) && "Cache data error: Trying to write a wrong be"); 736 737 if (be == 0x0) return; 738 739 if (be == 0xF) 740 { 741 m_cache_data[way][set][word] = data; 742 return; 743 } 744 745 uint32_t mask = 0; 746 if (be & 0x1) mask = mask | 0x000000FF; 747 if (be & 0x2) mask = mask | 0x0000FF00; 748 if (be & 0x4) mask = mask | 0x00FF0000; 749 if (be & 0x8) mask = mask | 0xFF000000; 750 751 m_cache_data[way][set][word] = 752 (data & mask) | (m_cache_data[way][set][word] & ~mask); 753 } 724 754 }; // end class CacheData 725 755
Note: See TracChangeset
for help on using the changeset viewer.