Changeset 814 for branches/RWT/lib
- Timestamp:
- Sep 24, 2014, 3:48:50 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/RWT/lib/generic_cache_tsar/include/generic_cache.h
r771 r814 38 38 // Hit if ( (matching tag) and (state == VALID). 39 39 // The replacement policy is pseudo-LRU. The victim selection process cannot 40 // fail if the ZOMBI state is not used. 40 // fail if the ZOMBI state is not used. 41 41 // But it can fail if all ways are in ZOMBI state. 42 42 ///////////////////////////////////////////////////////////////////////////////// … … 49 49 // Constructor parameters are : 50 50 // - std::string &name 51 // - size_t nways : number of associativity levels 51 // - size_t nways : number of associativity levels 52 52 // - size_t nsets : number of sets 53 53 // - size_t nwords : number of words in a cache line … … 58 58 ///////////////////////////////////////////////////////////////////////////////// 59 59 // Template parameter is : 60 // - addr_t : address format to access the cache 60 // - addr_t : address format to access the cache 61 61 ///////////////////////////////////////////////////////////////////////////////// 62 62 … … 71 71 #include <cstring> 72 72 73 namespace soclib { 73 namespace soclib { 74 74 75 75 enum cache_slot_state_e … … 83 83 ////////////////////////// 84 84 template<typename addr_t> 85 class GenericCache 85 class GenericCache 86 86 ////////////////////////// 87 87 { … … 94 94 bool *r_lru ; 95 95 96 size_t m_ways; 97 size_t m_sets; 96 size_t m_ways; 97 size_t m_sets; 98 98 size_t m_words; 99 99 … … 119 119 return r_lru[(way*m_sets)+set]; 120 120 } 121 121 122 122 ////////////////////////////////////////////// 123 123 inline int &cache_state(size_t way, size_t set) … … 126 126 } 127 127 128 128 129 129 ///////////////////////////////////////////////// 130 130 inline void cache_set_lru(size_t way, size_t set) 131 131 { 132 132 size_t way2; 133 133 134 134 cache_lru(way, set) = true; 135 135 136 for (way2 = 0; way2 < m_ways; way2++) 137 { 138 139 140 // all lines are new -> they all become old141 for (way2 = 0; way2 < m_ways; way2++) 142 { 143 144 136 for (way2 = 0; way2 < m_ways; way2++) 137 { 138 if (cache_lru(way2, set) == false) return; 139 } 140 // all lines are new -> they all become old 141 for (way2 = 0; way2 < m_ways; way2++) 142 { 143 cache_lru(way2, set) = false; 144 } 145 145 } 146 146 … … 160 160 ////////////////////////////////////////// 161 161 GenericCache(const std::string &name, 162 size_t nways, 163 size_t nsets, 162 size_t nways, 163 size_t nsets, 164 164 size_t nwords) 165 165 : m_ways(nways), … … 190 190 << "- nsets = " << nsets << std::endl 191 191 << "- nwords = " << nwords << std::endl 192 << " m_x: " << m_x 192 << " m_x: " << m_x 193 193 << " m_y: " << m_y 194 194 << " m_z: " << m_z … … 224 224 return cache_state(way,set); 225 225 } 226 226 227 227 ///////////////////////////////////////////////////////////////////// 228 228 // Read a single 32 bits word. 229 // returns true if (matching tag) and (state == VALID) 230 // Both data & directory are accessed. 229 // returns true if (matching tag) and (state == VALID) 230 // Both data & directory are accessed. 231 231 ///////////////////////////////////////////////////////////////////// 232 inline bool read(addr_t ad, 232 inline bool read(addr_t ad, 233 233 data_t* dt) 234 234 { … … 237 237 const size_t word = m_x[ad]; 238 238 239 for (size_t way = 0; way < m_ways; way++) 240 { 241 if ((tag == cache_tag(way, set)) 239 for (size_t way = 0; way < m_ways; way++) 240 { 241 if ((tag == cache_tag(way, set)) 242 242 && ((cache_state(way, set) == CACHE_SLOT_STATE_VALID_CC) or (cache_state(way, set) == CACHE_SLOT_STATE_VALID_NCC)) ) 243 243 { … … 252 252 //////////////////////////////////////////////////////////////////// 253 253 // Read a single 32 bits word. 254 // returns true if (matching tag) and (state == VALID) 255 // Both data & directory are accessed. 254 // returns true if (matching tag) and (state == VALID) 255 // Both data & directory are accessed. 256 256 // The selected way, set and word index are returned in case of hit. 257 257 ///////////////////////////////////////////////////////////////////// 258 inline bool read(addr_t ad, 258 inline bool read(addr_t ad, 259 259 data_t* dt, 260 260 size_t* selway, 261 261 size_t* selset, 262 size_t* selword) 262 size_t* selword) 263 263 { 264 264 const addr_t tag = m_z[ad]; … … 266 266 const size_t word = m_x[ad]; 267 267 268 for (size_t way = 0; way < m_ways; way++) 268 for (size_t way = 0; way < m_ways; way++) 269 269 { 270 270 if ((tag == cache_tag(way, set)) and … … 286 286 // Both data and directory are accessed. 287 287 // returns the access status in the state argument: 288 // - VALID : (matching tag) and (state == VALID) 289 // - ZOMBI : (matching tag) and (state == ZOMBI) 288 // - VALID : (matching tag) and (state == VALID) 289 // - ZOMBI : (matching tag) and (state == ZOMBI) 290 290 // - MISS : no matching tag or EMPTY state 291 // If VALID or ZOMBI, the data, the way, set and word index are 291 // If VALID or ZOMBI, the data, the way, set and word index are 292 292 // returned in the other arguments. 293 293 //////////////////////////////////////////////////////////////////// … … 297 297 size_t* selset, 298 298 size_t* selword, 299 int* state) 299 int* state) 300 300 { 301 301 const addr_t tag = m_z[ad]; … … 303 303 const size_t word = m_x[ad]; 304 304 305 // default return values 305 // default return values 306 306 *state = CACHE_SLOT_STATE_EMPTY; 307 307 *selway = 0; … … 310 310 *dt = 0; 311 311 312 for (size_t way = 0; way < m_ways; way++) 312 for (size_t way = 0; way < m_ways; way++) 313 313 { 314 314 if (tag == cache_tag(way, set)) // matching tag … … 343 343 } 344 344 } 345 345 346 346 //////////////////////////////////////////////////////////////////// 347 347 // Read a single 32 bits word, without LRU update. 348 // returns true if (matching tag) and (state == VALID) 349 // Both data & directory are accessed. 348 // returns true if (matching tag) and (state == VALID) 349 // Both data & directory are accessed. 350 350 // The selected way, set and word index are returned in case of hit. 351 351 ///////////////////////////////////////////////////////////////////// 352 inline bool read_neutral(addr_t ad, 352 inline bool read_neutral(addr_t ad, 353 353 data_t* dt, 354 354 size_t* selway, 355 355 size_t* selset, 356 size_t* selword) 356 size_t* selword) 357 357 { 358 358 const addr_t tag = m_z[ad]; … … 360 360 const size_t word = m_x[ad]; 361 361 362 for (size_t way = 0; way < m_ways; way++) 363 { 364 if ((tag == cache_tag(way, set)) 362 for (size_t way = 0; way < m_ways; way++) 363 { 364 if ((tag == cache_tag(way, set)) 365 365 && ((cache_state(way, set) == CACHE_SLOT_STATE_VALID_CC) or (cache_state(way, set) == CACHE_SLOT_STATE_VALID_NCC) )) 366 366 { … … 377 377 ///////////////////////////////////////////////////////////////////////////// 378 378 // Read one or two 32 bits word. 379 // Both data & directory are accessed. 380 // Hit if (matching tag) and (valid == true) and (zombi == false) 379 // Both data & directory are accessed. 380 // Hit if (matching tag) and (valid == true) and (zombi == false) 381 381 // If the addressed word is not the last in the cache line, 382 382 // two successive words are returned. … … 384 384 // This function is used by the cc_vcache to get a 64 bits page table entry. 385 385 ///////////////////////////////////////////////////////////////////////////// 386 inline bool read( addr_t ad, 387 data_t* dt, 386 inline bool read( addr_t ad, 387 data_t* dt, 388 388 data_t* dt_next, 389 389 size_t* selway, … … 395 395 const size_t word = m_x[ad]; 396 396 397 for (size_t way = 0; way < m_ways; way++) 398 { 399 if ((tag == cache_tag(way, set)) 400 &&( (cache_state(way, set) == CACHE_SLOT_STATE_VALID_CC))) 397 for (size_t way = 0; way < m_ways; way++) 398 { 399 if ((tag == cache_tag(way, set)) 400 &&( (cache_state(way, set) == CACHE_SLOT_STATE_VALID_CC))) 401 401 { 402 402 *dt = cache_data(way, set, word); 403 if (word + 1 < m_words) 403 if (word + 1 < m_words) 404 404 { 405 405 *dt_next = cache_data(way, set, word + 1); … … 419 419 // Both data and directory are accessed. 420 420 // returns the access status in the state argument: 421 // - VALID : (matching tag) and (state == VALID) 422 // - ZOMBI : (matching tag) and (state == ZOMBI) 421 // - VALID : (matching tag) and (state == VALID) 422 // - ZOMBI : (matching tag) and (state == ZOMBI) 423 423 // - MISS : no matching tag or EMPTY state 424 // If VALID or ZOMBI, the data, the way, set and word index are 424 // If VALID or ZOMBI, the data, the way, set and word index are 425 425 // returned in the other arguments. 426 426 //////////////////////////////////////////////////////////////////// … … 431 431 size_t* selset, 432 432 size_t* selword, 433 int* state) 433 int* state) 434 434 { 435 435 const addr_t tag = m_z[ad]; … … 437 437 const size_t word = m_x[ad]; 438 438 439 // default return values 439 // default return values 440 440 *state = CACHE_SLOT_STATE_EMPTY; 441 441 *selway = 0; … … 444 444 *dt = 0; 445 445 446 for (size_t way = 0; way < m_ways; way++) 446 for (size_t way = 0; way < m_ways; way++) 447 447 { 448 448 if (tag == cache_tag(way, set)) // matching tag … … 456 456 *selword = word; 457 457 *dt = cache_data(way, set, word); 458 if (word + 1 < m_words) 458 if (word + 1 < m_words) 459 459 { 460 460 *dt_next = cache_data(way, set, word+1); … … 470 470 *selword = word; 471 471 *dt = cache_data(way, set, word); 472 if (word + 1 < m_words) 472 if (word + 1 < m_words) 473 473 { 474 474 *dt_next = cache_data(way, set, word + 1); … … 490 490 /////////////////////////////////////////////////////////////////////////////// 491 491 // Checks the cache state for a given address. 492 // Only the directory is accessed. 493 // returns true if (matching tag) and (state == VALID) 492 // Only the directory is accessed. 493 // returns true if (matching tag) and (state == VALID) 494 494 // The selected way, set and first word index are returned in case of hit. 495 495 // This function can be used when we need to access the directory 496 496 // while we write in the data part with a different address in the same cycle. 497 497 /////////////////////////////////////////////////////////////////////////////// 498 inline bool hit(addr_t ad, 498 inline bool hit(addr_t ad, 499 499 size_t* selway, 500 500 size_t* selset, … … 505 505 const size_t word = m_x[ad]; 506 506 507 for (size_t way = 0; way < m_ways; way++) 508 { 509 if ((tag == cache_tag(way, set)) 510 && ((cache_state(way, set) == CACHE_SLOT_STATE_VALID_CC)or(cache_state(way, set) == CACHE_SLOT_STATE_VALID_NCC))) 507 for (size_t way = 0; way < m_ways; way++) 508 { 509 if ((tag == cache_tag(way, set)) 510 && ((cache_state(way, set) == CACHE_SLOT_STATE_VALID_CC)or(cache_state(way, set) == CACHE_SLOT_STATE_VALID_NCC))) 511 511 { 512 512 *selway = way; … … 519 519 return false; 520 520 } 521 521 522 522 /////////////////////////////////////////////////////////////////////////////// 523 523 // Checks the cache state for a given address, when the ZOMBI state is used. 524 // Only the directory is accessed. 524 // Only the directory is accessed. 525 525 // Returns the access status in the state argument: 526 // - VALID if (matching tag) and (state == VALID) 527 // - ZOMBI if (matching tag) and (state == ZOMBI) 526 // - VALID if (matching tag) and (state == VALID) 527 // - ZOMBI if (matching tag) and (state == ZOMBI) 528 528 // - EMPTY if no match or (state == EMPTY) 529 529 // The selected way, set and first word index are returned if not empty. … … 531 531 // while we write in the data part with a different address in the same cycle. 532 532 /////////////////////////////////////////////////////////////////////////////// 533 inline void read_dir(addr_t ad, 533 inline void read_dir(addr_t ad, 534 534 int* state, 535 535 size_t* way, … … 540 540 const size_t ad_set = m_y[ad]; 541 541 const size_t ad_word = m_x[ad]; 542 for (size_t _way = 0; _way < m_ways; _way++) 543 { 544 if ((ad_tag == cache_tag(_way, ad_set)) and 545 (cache_state(_way, ad_set) != CACHE_SLOT_STATE_EMPTY)) 542 for (size_t _way = 0; _way < m_ways; _way++) 543 { 544 if ((ad_tag == cache_tag(_way, ad_set)) and 545 (cache_state(_way, ad_set) != CACHE_SLOT_STATE_EMPTY)) 546 546 { 547 547 *state = cache_state(_way, ad_set); … … 552 552 } 553 553 } 554 554 555 555 // return value if not (VALID or ZOMBI) 556 556 *state = CACHE_SLOT_STATE_EMPTY; … … 559 559 /////////////////////////////////////////////////////////////////////////////// 560 560 // Checks the cache state for a slot (set,way), when the ZOMBI state is used. 561 // Only the directory is accessed. 561 // Only the directory is accessed. 562 562 // Returns the access status and the tag value in the state and tag argument. 563 563 /////////////////////////////////////////////////////////////////////////////// … … 581 581 // It does not use the directory and cannot miss. 582 582 ////////////////////////////////////////////////////////////////// 583 inline void write(size_t way, 584 size_t set, 585 size_t word, 583 inline void write(size_t way, 584 size_t set, 585 size_t word, 586 586 data_t data) 587 587 { … … 594 594 // It does not use the directory and cannot miss. 595 595 //////////////////////////////////////////////////////////////////////////// 596 inline void write(size_t way, 597 size_t set, 598 size_t word, 599 data_t data, 596 inline void write(size_t way, 597 size_t set, 598 size_t word, 599 data_t data, 600 600 be_t be) 601 601 { … … 610 610 // It returns true if the line was valid, and returns the line index. 611 611 ////////////////////////////////////////////////////////////////////////// 612 inline bool inval(size_t way, 613 size_t set, 612 inline bool inval(size_t way, 613 size_t set, 614 614 addr_t* nline) 615 615 { … … 626 626 // This function selects a victim slot in an associative set. 627 627 // It cannot fail, as a slot in ZOMBI state is considered EMPTY. 628 // - we search first an EMPTY slot 628 // - we search first an EMPTY slot 629 629 // - if no EMPTY slot, we search an OLD slot, using lru 630 // It returns the line index (Z + Y fields), the selected slot way and set, 630 // It returns the line index (Z + Y fields), the selected slot way and set, 631 631 // and a Boolean indicating that a cleanup is requested. 632 632 ////////////////////////////////////////////////////////////////////////////////// 633 inline bool victim_select(addr_t ad, 634 addr_t* victim, 635 size_t* way, 633 inline bool victim_select(addr_t ad, 634 addr_t* victim, 635 size_t* way, 636 636 size_t* set) 637 637 { … … 642 642 *way = 0; 643 643 644 // Search first empty slot 644 // Search first empty slot 645 645 for (size_t _way = 0 ; _way < m_ways && !found ; _way++) 646 646 { … … 653 653 } 654 654 655 // If no empty slot, search first old slot (lru == false) 655 // If no empty slot, search first old slot (lru == false) 656 656 if (!found) 657 { 657 { 658 658 for (size_t _way = 0 ; _way < m_ways && !found ; _way++) 659 659 { … … 678 678 // - if no empty slot, we search an OLD slot not in ZOMBI state, 679 679 // - if not found, we take the first not ZOMBI slot. 680 // It returns the line index (Z + Y fields), the selected slot way and set, 680 // It returns the line index (Z + Y fields), the selected slot way and set, 681 681 // and two Boolean indicating success and a required cleanup. 682 682 ////////////////////////////////////////////////////////////////////////////////// 683 inline void read_select(addr_t ad, 684 addr_t* victim, 685 size_t* way, 683 inline void read_select(addr_t ad, 684 addr_t* victim, 685 size_t* way, 686 686 size_t* set, 687 687 bool* found, … … 692 692 *found = false; 693 693 694 // Search first empty slot 694 // Search first empty slot 695 695 for (size_t _way = 0 ; _way < m_ways && !(*found) ; _way++) 696 696 { … … 704 704 } 705 705 } 706 707 // Search first not zombi old slot 706 707 // Search first not zombi old slot 708 708 for (size_t _way = 0 ; _way < m_ways && !(*found) ; _way++) 709 709 { 710 if (not cache_lru(_way, _set) and 710 if (not cache_lru(_way, _set) and 711 711 (cache_state(_way, _set) != CACHE_SLOT_STATE_ZOMBI)) 712 712 { … … 722 722 for (size_t _way = 0 ; _way < m_ways && !(*found) ; _way++) 723 723 { 724 if (cache_state(_way, _set) != CACHE_SLOT_STATE_ZOMBI) 724 if (cache_state(_way, _set) != CACHE_SLOT_STATE_ZOMBI) 725 725 { 726 726 *found = true; … … 742 742 // identified by the way & set. 743 743 ////////////////////////////////////////////////////////////////// 744 inline void victim_update_tag(addr_t ad, 745 size_t way, 744 inline void victim_update_tag(addr_t ad, 745 size_t way, 746 746 size_t set) 747 747 { … … 757 757 // identified by the way & set, when using the ZOMBI state. 758 758 ////////////////////////////////////////////////////////////////// 759 inline void write_dir(addr_t ad, 760 size_t way, 759 inline void write_dir(addr_t ad, 760 size_t way, 761 761 size_t set, 762 762 int state) … … 787 787 // It does not affect the tag 788 788 ////////////////////////////////////////////////////////////////// 789 inline void write_dir(size_t way, 789 inline void write_dir(size_t way, 790 790 size_t set, 791 791 int state) … … 813 813 // Both DATA and DIRECTORY are written 814 814 /////////////////////////////////////////////////////////////////// 815 inline void update(addr_t ad, 816 size_t way, 817 size_t set, 815 inline void update(addr_t ad, 816 size_t way, 817 size_t set, 818 818 data_t* buf) 819 819 { … … 823 823 cache_state(way, set) = CACHE_SLOT_STATE_VALID_CC; 824 824 cache_set_lru(way, set); 825 for (size_t word = 0 ; word < m_words ; word++) 825 for (size_t word = 0 ; word < m_words ; word++) 826 826 { 827 827 cache_data(way, set, word) = buf[word] ; … … 832 832 void fileTrace(FILE* file) 833 833 { 834 for (size_t nway = 0 ; nway < m_ways ; nway++) 835 { 836 for (size_t nset = 0 ; nset < m_sets ; nset++) 834 for (size_t nway = 0 ; nway < m_ways ; nway++) 835 { 836 for (size_t nset = 0 ; nset < m_sets ; nset++) 837 837 { 838 838 fprintf(file, "%d / ", (int)cache_state(nway, nset)); 839 839 fprintf(file, "way %d / ", (int)nway); 840 840 fprintf(file, "set %d / ", (int)nset); 841 fprintf(file, "@ = %08zX / ", 841 fprintf(file, "@ = %08zX / ", 842 842 ((cache_tag(nway, nset) * m_sets + nset) * m_words * 4)); 843 for (size_t nword = m_words ; nword > 0 ; nword--) 843 for (size_t nword = m_words ; nword > 0 ; nword--) 844 844 { 845 845 unsigned int data = cache_data(nway, nset, nword - 1); … … 854 854 inline void printTrace() 855 855 { 856 for (size_t way = 0; way < m_ways ; way++) 856 for (size_t way = 0; way < m_ways ; way++) 857 857 { 858 858 for (size_t set = 0 ; set < m_sets ; set++) 859 859 { 860 860 addr_t addr = (((addr_t)cache_tag(way,set))*m_words*m_sets+m_words*set)*4; 861 std::cout << std::dec << cache_state(way, set) 862 << " | way " << way 863 << " | set " << set 861 std::cout << std::dec << cache_state(way, set) 862 << " | way " << way 863 << " | set " << set 864 864 << std::hex << " | @ " << addr; 865 865 … … 872 872 } 873 873 } 874 874 875 875 }; 876 876
Note: See TracChangeset
for help on using the changeset viewer.