Changeset 814 for branches/RWT
- Timestamp:
- Sep 24, 2014, 3:48:50 PM (10 years ago)
- Location:
- branches/RWT
- Files:
-
- 8 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 -
branches/RWT/modules/vci_mem_cache
- Property svn:mergeinfo changed
/trunk/modules/vci_mem_cache (added) merged: 597,599,601,603,605,617
- Property svn:mergeinfo changed
-
branches/RWT/modules/vci_mem_cache/caba/source/include
- Property svn:mergeinfo changed
/trunk/modules/vci_mem_cache/caba/source/include (added) merged: 597,599,601,605
- Property svn:mergeinfo changed
-
branches/RWT/modules/vci_mem_cache/caba/source/include/mem_cache_directory.h
r495 r814 1 1 #ifndef SOCLIB_CABA_MEM_CACHE_DIRECTORY_H 2 #define SOCLIB_CABA_MEM_CACHE_DIRECTORY_H 2 #define SOCLIB_CABA_MEM_CACHE_DIRECTORY_H 3 3 4 4 #include <inttypes.h> … … 14 14 15 15 //////////////////////////////////////////////////////////////////////// 16 // A LRU entry 16 // A LRU entry 17 17 //////////////////////////////////////////////////////////////////////// 18 18 class LruEntry { … … 20 20 public: 21 21 22 bool recent; 22 bool recent; 23 23 24 24 void init() … … 33 33 //////////////////////////////////////////////////////////////////////// 34 34 class Owner{ 35 35 36 36 public: 37 37 // Fields … … 66 66 67 67 //////////////////////////////////////////////////////////////////////// 68 // A directory entry 68 // A directory entry 69 69 //////////////////////////////////////////////////////////////////////// 70 70 class DirectoryEntry { … … 81 81 tag_t tag; // tag of the entry 82 82 size_t count; // number of copies 83 Owner owner; // an owner of the line 83 Owner owner; // an owner of the line 84 84 size_t ptr; // pointer to the next owner 85 85 … … 109 109 owner = source.owner; 110 110 ptr = source.ptr; 111 } 112 113 ///////////////////////////////////////////////////////////////////// 114 // The init() function initializes the entry 111 } 112 113 ///////////////////////////////////////////////////////////////////// 114 // The init() function initializes the entry 115 115 ///////////////////////////////////////////////////////////////////// 116 116 void init() … … 125 125 126 126 ///////////////////////////////////////////////////////////////////// 127 // The copy() function copies an existing source entry to a target 127 // The copy() function copies an existing source entry to a target 128 128 ///////////////////////////////////////////////////////////////////// 129 129 void copy(const DirectoryEntry &source) 130 130 { 131 valid 131 valid = source.valid; 132 132 cache_coherent = source.cache_coherent; 133 133 is_cnt = source.is_cnt; 134 dirty 135 lock 136 tag 134 dirty = source.dirty; 135 lock = source.lock; 136 tag = source.tag; 137 137 count = source.count; 138 138 owner = source.owner; … … 141 141 142 142 //////////////////////////////////////////////////////////////////// 143 // The print() function prints the entry 143 // The print() function prints the entry 144 144 //////////////////////////////////////////////////////////////////// 145 145 void print() 146 146 { 147 std::cout << "Valid = " << valid 147 std::cout << "Valid = " << valid 148 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 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 156 << " ; Pointer = " << ptr << std::endl; 157 157 } … … 160 160 161 161 //////////////////////////////////////////////////////////////////////// 162 // The directory 162 // The directory 163 163 //////////////////////////////////////////////////////////////////////// 164 164 class CacheDirectory { … … 171 171 172 172 // Directory constants 173 size_t 174 size_t 175 size_t 176 size_t 177 uint32_t 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 178 179 179 // the directory & lru tables 180 DirectoryEntry 181 LruEntry 180 DirectoryEntry **m_dir_tab; 181 LruEntry **m_lru_tab; 182 182 183 183 public: … … 186 186 // Constructor 187 187 //////////////////////// 188 CacheDirectory( size_t ways, size_t sets, size_t words, size_t address_width) 189 { 190 m_ways = ways; 188 CacheDirectory( size_t ways, size_t sets, size_t words, size_t address_width) 189 { 190 m_ways = ways; 191 191 m_sets = sets; 192 192 m_words = words; … … 223 223 // LRU is updated. 224 224 // Arguments : 225 // - address : the address of the entry 225 // - address : the address of the entry 226 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 227 // The function returns a copy of a (valid or invalid) entry 228 228 ///////////////////////////////////////////////////////////////////// 229 229 DirectoryEntry read(const addr_t &address, size_t &way) … … 240 240 bool valid = m_dir_tab[set][i].valid; 241 241 hit = equal && valid; 242 if ( hit ) { 242 if ( hit ) { 243 243 way = i; 244 244 break; 245 } 245 } 246 246 } 247 247 if ( hit ) { … … 255 255 ///////////////////////////////////////////////////////////////////// 256 256 // The inval function invalidate an entry defined by the set and 257 // way arguments. 257 // way arguments. 258 258 ///////////////////////////////////////////////////////////////////// 259 259 void inval( const size_t &way, const size_t &set ) … … 266 266 // changing the LRU 267 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, 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 272 size_t* ret_way, 273 273 size_t* ret_set ) … … 279 279 #undef L2 280 280 281 for ( size_t way = 0 ; way < m_ways ; way++ ) 281 for ( size_t way = 0 ; way < m_ways ; way++ ) 282 282 { 283 283 bool equal = ( m_dir_tab[set][way].tag == tag ); … … 286 286 { 287 287 *ret_set = set; 288 *ret_way = way; 288 *ret_way = way; 289 289 return DirectoryEntry(m_dir_tab[set][way]); 290 290 } 291 } 291 } 292 292 return DirectoryEntry(); 293 293 } // end read_neutral() 294 294 295 295 ///////////////////////////////////////////////////////////////////// 296 // The write function writes a new entry, 296 // The write function writes a new entry, 297 297 // and updates the LRU bits if necessary. 298 298 // Arguments : … … 301 301 // - entry : the entry value 302 302 ///////////////////////////////////////////////////////////////////// 303 void write( const size_t &set, 304 const size_t &way, 303 void write( const size_t &set, 304 const size_t &way, 305 305 const DirectoryEntry &entry) 306 306 { 307 assert( (set<m_sets) 307 assert( (set<m_sets) 308 308 && "Cache Directory write : The set index is invalid"); 309 assert( (way<m_ways) 309 assert( (way<m_ways) 310 310 && "Cache Directory write : The way index is invalid"); 311 311 … … 315 315 // update LRU bits 316 316 bool all_recent = true; 317 for ( size_t i=0 ; i<m_ways ; i++ ) 317 for ( size_t i=0 ; i<m_ways ; i++ ) 318 318 { 319 319 if ( i != way ) all_recent = m_lru_tab[set][i].recent && all_recent; 320 320 } 321 if ( all_recent ) 321 if ( all_recent ) 322 322 { 323 323 for( size_t i=0 ; i<m_ways ; i++ ) m_lru_tab[set][i].recent = false; 324 } 325 else 324 } 325 else 326 326 { 327 327 m_lru_tab[set][way].recent = true; … … 349 349 DirectoryEntry select(const size_t &set, size_t &way) 350 350 { 351 assert( (set < m_sets) 351 assert( (set < m_sets) 352 352 && "Cache Directory : (select) The set index is invalid"); 353 353 … … 404 404 405 405 ///////////////////////////////////////////////////////////////////// 406 // 406 // Global initialisation function 407 407 ///////////////////////////////////////////////////////////////////// 408 408 void init() 409 409 { 410 for ( size_t set=0 ; set<m_sets ; set++ ) 411 { 412 for ( size_t way=0 ; way<m_ways ; way++ ) 410 for ( size_t set=0 ; set<m_sets ; set++ ) 411 { 412 for ( size_t way=0 ; way<m_ways ; way++ ) 413 413 { 414 414 m_dir_tab[set][way].init(); … … 446 446 owner.inst = entry.owner.inst; 447 447 owner.srcid = entry.owner.srcid; 448 next 448 next = entry.next; 449 449 } // end constructor 450 450 451 451 ///////////////////////////////////////////////////////////////////// 452 // The copy() function copies an existing source entry to a target 452 // The copy() function copies an existing source entry to a target 453 453 ///////////////////////////////////////////////////////////////////// 454 454 void copy(const HeapEntry &entry) 455 455 { 456 owner.inst 457 owner.srcid 458 next 456 owner.inst = entry.owner.inst; 457 owner.srcid = entry.owner.srcid; 458 next = entry.next; 459 459 } // end copy() 460 460 461 461 //////////////////////////////////////////////////////////////////// 462 // The print() function prints the entry 462 // The print() function prints the entry 463 463 //////////////////////////////////////////////////////////////////// 464 464 void print(){ 465 std::cout 465 std::cout 466 466 << " -- owner.inst : " << std::dec << owner.inst << std::endl 467 467 << " -- owner.srcid : " << std::dec << owner.srcid << std::endl … … 473 473 474 474 //////////////////////////////////////////////////////////////////////// 475 // The Heap 475 // The Heap 476 476 //////////////////////////////////////////////////////////////////////// 477 477 class HeapDirectory{ 478 478 479 479 private: 480 480 // Registers and the heap … … 506 506 507 507 ///////////////////////////////////////////////////////////////////// 508 // 508 // Global initialisation function 509 509 ///////////////////////////////////////////////////////////////////// 510 510 void init(){ … … 541 541 if(ptr_temp == m_heap_tab[ptr_temp].next) end = true; 542 542 ptr_temp = m_heap_tab[ptr_temp].next; 543 } 543 } 544 544 } // end print_list() 545 545 … … 552 552 553 553 ///////////////////////////////////////////////////////////////////// 554 // The next_free_ptr() function returns the pointer 554 // The next_free_ptr() function returns the pointer 555 555 // to the next free entry. 556 556 ///////////////////////////////////////////////////////////////////// … … 560 560 561 561 ///////////////////////////////////////////////////////////////////// 562 // The next_free_entry() function returns 562 // The next_free_entry() function returns 563 563 // a copy of the next free entry. 564 564 ///////////////////////////////////////////////////////////////////// … … 566 566 return HeapEntry(m_heap_tab[ptr_free]); 567 567 } // end next_free_entry() 568 568 569 569 ///////////////////////////////////////////////////////////////////// 570 570 // The write_free_entry() function modify the next free entry. … … 624 624 625 625 //////////////////////////////////////////////////////////////////////// 626 // Cache Data 627 //////////////////////////////////////////////////////////////////////// 628 class CacheData 626 // Cache Data 627 //////////////////////////////////////////////////////////////////////// 628 class CacheData 629 629 { 630 630 private: … … 639 639 /////////////////////////////////////////////////////// 640 640 CacheData(uint32_t ways, uint32_t sets, uint32_t words) 641 : m_sets(sets), m_ways(ways), m_words(words) 641 : m_sets(sets), m_ways(ways), m_words(words) 642 642 { 643 643 m_cache_data = new uint32_t ** [ways]; 644 for ( size_t i=0 ; i < ways ; i++ ) 644 for ( size_t i=0 ; i < ways ; i++ ) 645 645 { 646 646 m_cache_data[i] = new uint32_t * [sets]; 647 647 } 648 for ( size_t i=0; i<ways; i++ ) 648 for ( size_t i=0; i<ways; i++ ) 649 649 { 650 for ( size_t j=0; j<sets; j++ ) 650 for ( size_t j=0; j<sets; j++ ) 651 651 { 652 652 m_cache_data[i][j] = new uint32_t [words]; … … 655 655 } 656 656 //////////// 657 ~CacheData() 657 ~CacheData() 658 658 { 659 659 for(size_t i=0; i<m_ways ; i++) … … 673 673 uint32_t read ( const uint32_t &way, 674 674 const uint32_t &set, 675 const uint32_t &word) const 675 const uint32_t &word) const 676 676 { 677 677 assert((set < m_sets ) && "Cache data error: Trying to read a wrong set" ); … … 697 697 const uint32_t &word, 698 698 const uint32_t &data, 699 const uint32_t &be = 0xF) 699 const uint32_t &be = 0xF) 700 700 { 701 701 … … 707 707 if (be == 0x0) return; 708 708 709 if (be == 0xF) 709 if (be == 0xF) 710 710 { 711 m_cache_data[way][set][word] = data; 711 m_cache_data[way][set][word] = data; 712 712 return; 713 713 } … … 719 719 if (be & 0x8) mask = mask | 0xFF000000; 720 720 721 m_cache_data[way][set][word] = 721 m_cache_data[way][set][word] = 722 722 (data & mask) | (m_cache_data[way][set][word] & ~mask); 723 723 } -
branches/RWT/modules/vci_mem_cache/caba/source/include/update_tab.h
r767 r814 8 8 9 9 //////////////////////////////////////////////////////////////////////// 10 // An update tab entry 10 // An update tab entry 11 11 //////////////////////////////////////////////////////////////////////// 12 12 class UpdateTabEntry { … … 17 17 public: 18 18 19 bool valid;// It is a valid pending transaction20 bool update;// It is an update transaction21 bool brdcast;// It is a broadcast invalidate22 bool rsp;// Response to the initiator required23 bool ack;// Acknowledge to the CONFIG FSM required24 size_t srcid;// The srcid of the initiator which wrote the data25 size_t trdid;// The trdid of the initiator which wrote the data26 size_t pktid;// The pktid of the initiator which wrote the data27 addr_t nline;// The identifier of the cache line28 size_t count;// The number of acknowledge responses to receive19 bool valid; // It is a valid pending transaction 20 bool update; // It is an update transaction 21 bool brdcast; // It is a broadcast invalidate 22 bool rsp; // Response to the initiator required 23 bool ack; // Acknowledge to the CONFIG FSM required 24 size_t srcid; // The srcid of the initiator which wrote the data 25 size_t trdid; // The trdid of the initiator which wrote the data 26 size_t pktid; // The pktid of the initiator which wrote the data 27 addr_t nline; // The identifier of the cache line 28 size_t count; // The number of acknowledge responses to receive 29 29 30 30 UpdateTabEntry() 31 31 { 32 valid 32 valid = false; 33 33 update = false; 34 34 brdcast = false; 35 35 rsp = false; 36 36 ack = false; 37 srcid 38 trdid 39 pktid 40 nline 41 count 42 } 43 44 UpdateTabEntry(bool i_valid, 37 srcid = 0; 38 trdid = 0; 39 pktid = 0; 40 nline = 0; 41 count = 0; 42 } 43 44 UpdateTabEntry(bool i_valid, 45 45 bool i_update, 46 46 bool i_brdcast, 47 47 bool i_rsp, 48 48 bool i_ack, 49 size_t i_srcid, 50 size_t i_trdid, 51 size_t i_pktid, 49 size_t i_srcid, 50 size_t i_trdid, 51 size_t i_pktid, 52 52 addr_t i_nline, 53 size_t i_count) 54 { 55 valid 56 update 53 size_t i_count) 54 { 55 valid = i_valid; 56 update = i_update; 57 57 brdcast = i_brdcast; 58 58 rsp = i_rsp; 59 59 ack = i_ack; 60 srcid 61 trdid 62 pktid 63 nline 64 count 60 srcid = i_srcid; 61 trdid = i_trdid; 62 pktid = i_pktid; 63 nline = i_nline; 64 count = i_count; 65 65 } 66 66 … … 80 80 81 81 //////////////////////////////////////////////////// 82 // The init() function initializes the entry 82 // The init() function initializes the entry 83 83 /////////////////////////////////////////////////// 84 84 void init() 85 85 { 86 valid = false;87 update = false;88 brdcast = false;89 rsp = false;90 ack = false;91 srcid = 0;92 trdid = 0;93 pktid = 0;94 nline = 0;95 count = 0;86 valid = false; 87 update = false; 88 brdcast = false; 89 rsp = false; 90 ack = false; 91 srcid = 0; 92 trdid = 0; 93 pktid = 0; 94 nline = 0; 95 count = 0; 96 96 } 97 97 … … 116 116 117 117 //////////////////////////////////////////////////////////////////// 118 // The print() function prints the entry 118 // The print() function prints the entry 119 119 //////////////////////////////////////////////////////////////////// 120 120 void print() 121 121 { 122 std::cout << " val = " << std::dec << valid 123 << " / updt = " << update 122 std::cout << " val = " << std::dec << valid 123 << " / updt = " << update 124 124 << " / bc = " << brdcast 125 << " / rsp = " << rsp 126 << " / ack = " << ack 125 << " / rsp = " << rsp 126 << " / ack = " << ack 127 127 << " / count = " << count 128 << " / srcid = " << std::hex << srcid 129 << " / trdid = " << trdid 128 << " / srcid = " << std::hex << srcid 129 << " / trdid = " << trdid 130 130 << " / pktid = " << pktid 131 131 << " / nline = " << nline << std::endl; … … 134 134 135 135 //////////////////////////////////////////////////////////////////////// 136 // The update tab 136 // The update tab 137 137 //////////////////////////////////////////////////////////////////////// 138 138 class UpdateTab{ … … 159 159 160 160 //////////////////////////////////////////////////////////////////// 161 // The size() function returns the size of the tab 161 // The size() function returns the size of the tab 162 162 //////////////////////////////////////////////////////////////////// 163 163 const size_t size() … … 167 167 168 168 //////////////////////////////////////////////////////////////////// 169 // The print() function diplays the tab content 169 // The print() function diplays the tab content 170 170 //////////////////////////////////////////////////////////////////// 171 171 void print() 172 172 { 173 173 std::cout << "UPDATE TABLE Content" << std::endl; 174 for(size_t i=0; i<size_tab; i++) 174 for(size_t i=0; i<size_tab; i++) 175 175 { 176 176 std::cout << "[" << std::dec << i << "] "; … … 181 181 182 182 ///////////////////////////////////////////////////////////////////// 183 // The init() function initializes the tab 183 // The init() function initializes the tab 184 184 ///////////////////////////////////////////////////////////////////// 185 185 void init() … … 189 189 190 190 ///////////////////////////////////////////////////////////////////// 191 // The reads() function reads an entry 191 // The reads() function reads an entry 192 192 // Arguments : 193 193 // - entry : the entry to read … … 211 211 // This function returns true if the write successed (an entry was empty). 212 212 /////////////////////////////////////////////////////////////////////////// 213 bool set(const bool 213 bool set(const bool update, 214 214 const bool brdcast, 215 215 const bool rsp, … … 222 222 size_t &index) 223 223 { 224 for ( size_t i=0 ; i<size_tab ; i++ ) 225 { 226 if( !tab[i].valid ) 224 for ( size_t i=0 ; i<size_tab ; i++ ) 225 { 226 if( !tab[i].valid ) 227 227 { 228 tab[i].valid 229 tab[i].update 230 tab[i].brdcast 231 tab[i].rsp 232 tab[i].ack 233 tab[i].srcid 234 tab[i].trdid 235 tab[i].pktid 236 tab[i].nline 237 tab[i].count 238 index 228 tab[i].valid = true; 229 tab[i].update = update; 230 tab[i].brdcast = brdcast; 231 tab[i].rsp = rsp; 232 tab[i].ack = ack; 233 tab[i].srcid = (size_t) srcid; 234 tab[i].trdid = (size_t) trdid; 235 tab[i].pktid = (size_t) pktid; 236 tab[i].nline = (addr_t) nline; 237 tab[i].count = (size_t) count; 238 index = i; 239 239 return true; 240 240 } … … 251 251 ///////////////////////////////////////////////////////////////////// 252 252 bool decrement( const size_t index, 253 size_t &counter ) 253 size_t &counter ) 254 254 { 255 255 assert((index<size_tab) && "Bad Update Tab Entry"); 256 if ( tab[index].valid ) 256 if ( tab[index].valid ) 257 257 { 258 258 tab[index].count--; 259 259 counter = tab[index].count; 260 260 return true; 261 } 262 else 261 } 262 else 263 263 { 264 264 return false; … … 298 298 { 299 299 assert(index<size_tab && "Bad Update Tab Entry"); 300 return tab[index].rsp; 300 return tab[index].rsp; 301 301 } 302 302 … … 309 309 { 310 310 assert(index<size_tab && "Bad Update Tab Entry"); 311 return tab[index].ack; 311 return tab[index].ack; 312 312 } 313 313 … … 320 320 { 321 321 assert(index<size_tab && "Bad Update Tab Entry"); 322 return tab[index].brdcast; 322 return tab[index].brdcast; 323 323 } 324 324 … … 331 331 { 332 332 assert(index<size_tab && "Bad Update Tab Entry"); 333 return tab[index].update; 333 return tab[index].update; 334 334 } 335 335 … … 342 342 { 343 343 assert(index<size_tab && "Bad Update Tab Entry"); 344 return tab[index].srcid; 344 return tab[index].srcid; 345 345 } 346 346 … … 353 353 { 354 354 assert(index<size_tab && "Bad Update Tab Entry"); 355 return tab[index].trdid; 355 return tab[index].trdid; 356 356 } 357 357 … … 364 364 { 365 365 assert(index<size_tab && "Bad Update Tab Entry"); 366 return tab[index].pktid; 366 return tab[index].pktid; 367 367 } 368 368 … … 403 403 // - nline : the line number of the entry in the directory 404 404 ///////////////////////////////////////////////////////////////////// 405 bool read_nline(const addr_t nline,size_t &index) 405 bool read_nline(const addr_t nline,size_t &index) 406 406 { 407 407 size_t i ; … … 422 422 // Arguments : 423 423 // - index : the index of the entry 424 ///////////////////////////////////////////////////////////////////// 424 ///////////////////////////////////////////////////////////////////// 425 425 void clear(const size_t index) 426 426 { 427 427 assert(index<size_tab && "Bad Update Tab Entry"); 428 428 tab[index].valid=false; 429 return; 429 return; 430 430 } 431 431 -
branches/RWT/modules/vci_mem_cache/caba/source/include/vci_mem_cache.h
r787 r814 25 25 * SOCLIB_LGPL_HEADER_END 26 26 * 27 * Maintainers: alain.greiner@lip6.fr 27 * Maintainers: alain.greiner@lip6.fr 28 28 * eric.guthmuller@polytechnique.edu 29 29 * cesar.fuguet-tortolero@lip6.fr … … 62 62 using namespace sc_core; 63 63 64 template<typename vci_param_int, 64 template<typename vci_param_int, 65 65 typename vci_param_ext, 66 66 size_t dspin_in_width, … … 416 416 }; 417 417 418 // debug variables 418 // debug variables 419 419 bool m_debug; 420 420 bool m_debug_previous_valid; … … 479 479 uint32_t m_cpt_heap_unused; // NB cycles HEAP LOCK unused 480 480 uint32_t m_cpt_heap_slot_available; // NB HEAP slot available refresh at each cycles 481 uint32_t m_cpt_heap_min_slot_available; // NB HEAP : Min of slot available 481 uint32_t m_cpt_heap_min_slot_available; // NB HEAP : Min of slot available 482 482 483 483 uint32_t m_cpt_ncc_to_cc_read; // NB change from NCC to CC caused by a READ … … 525 525 526 526 #if MONITOR_MEMCACHE_FSM == 1 527 sc_out<int> p_read_fsm; 528 sc_out<int> p_write_fsm; 529 sc_out<int> p_xram_rsp_fsm; 530 sc_out<int> p_cas_fsm; 531 sc_out<int> p_cleanup_fsm; 532 sc_out<int> p_config_fsm; 533 sc_out<int> p_alloc_heap_fsm; 534 sc_out<int> p_alloc_dir_fsm; 535 sc_out<int> p_alloc_trt_fsm; 536 sc_out<int> p_alloc_upt_fsm; 537 sc_out<int> p_alloc_ivt_fsm; 538 sc_out<int> p_tgt_cmd_fsm; 539 sc_out<int> p_tgt_rsp_fsm; 540 sc_out<int> p_ixr_cmd_fsm; 541 sc_out<int> p_ixr_rsp_fsm; 542 sc_out<int> p_cc_send_fsm; 543 sc_out<int> p_cc_receive_fsm; 544 sc_out<int> p_multi_ack_fsm; 527 sc_out<int> p_read_fsm; 528 sc_out<int> p_write_fsm; 529 sc_out<int> p_xram_rsp_fsm; 530 sc_out<int> p_cas_fsm; 531 sc_out<int> p_cleanup_fsm; 532 sc_out<int> p_config_fsm; 533 sc_out<int> p_alloc_heap_fsm; 534 sc_out<int> p_alloc_dir_fsm; 535 sc_out<int> p_alloc_trt_fsm; 536 sc_out<int> p_alloc_upt_fsm; 537 sc_out<int> p_alloc_ivt_fsm; 538 sc_out<int> p_tgt_cmd_fsm; 539 sc_out<int> p_tgt_rsp_fsm; 540 sc_out<int> p_ixr_cmd_fsm; 541 sc_out<int> p_ixr_rsp_fsm; 542 sc_out<int> p_cc_send_fsm; 543 sc_out<int> p_cc_receive_fsm; 544 sc_out<int> p_multi_ack_fsm; 545 545 #endif 546 546 … … 558 558 const size_t max_copies, // max number of copies 559 559 const size_t heap_size=HEAP_ENTRIES, 560 const size_t trt_lines=TRT_ENTRIES, 561 const size_t upt_lines=UPT_ENTRIES, 562 const size_t ivt_lines=IVT_ENTRIES, 560 const size_t trt_lines=TRT_ENTRIES, 561 const size_t upt_lines=UPT_ENTRIES, 562 const size_t ivt_lines=IVT_ENTRIES, 563 563 const size_t debug_start_cycle=0, 564 564 const bool debug_ok=false ); … … 584 584 585 585 // Component attributes 586 std::list<soclib::common::Segment> m_seglist; // segments allocated 586 std::list<soclib::common::Segment> m_seglist; // segments allocated 587 587 size_t m_nseg; // number of segments 588 588 soclib::common::Segment **m_seg; // array of segments pointers … … 657 657 // Fifo between CC_RECEIVE fsm and CLEANUP fsm 658 658 GenericFifo<uint64_t> m_cc_receive_to_cleanup_fifo; 659 659 660 660 // Fifo between CC_RECEIVE fsm and MULTI_ACK fsm 661 661 GenericFifo<uint64_t> m_cc_receive_to_multi_ack_fifo; … … 686 686 sc_signal<int> r_config_fsm; // FSM state 687 687 sc_signal<bool> r_config_lock; // lock protecting exclusive access 688 sc_signal<int> r_config_cmd; // config request type 688 sc_signal<int> r_config_cmd; // config request type 689 689 sc_signal<addr_t> r_config_address; // target buffer physical address 690 690 sc_signal<size_t> r_config_srcid; // config request srcid … … 702 702 sc_signal<size_t> r_config_heap_next; // current pointer to scan HEAP 703 703 sc_signal<size_t> r_config_trt_index; // selected entry in TRT 704 sc_signal<size_t> r_config_ivt_index; // selected entry in IVT 704 sc_signal<size_t> r_config_ivt_index; // selected entry in IVT 705 705 706 706 // Buffer between CONFIG fsm and IXR_CMD fsm … … 744 744 sc_signal<addr_t> r_read_ll_key; // LL key from llsc_global_table 745 745 746 // Buffer between READ fsm and IXR_CMD fsm 746 // Buffer between READ fsm and IXR_CMD fsm 747 747 sc_signal<bool> r_read_to_ixr_cmd_req; // valid request 748 748 sc_signal<size_t> r_read_to_ixr_cmd_index; // TRT index … … 764 764 sc_signal<bool> r_read_to_cc_send_inst; 765 765 766 //RWT: Buffer between READ fsm and CLEANUP fsm (wait for the data coming from L1 cache) 766 //RWT: Buffer between READ fsm and CLEANUP fsm (wait for the data coming from L1 cache) 767 767 sc_signal<bool> r_read_to_cleanup_req; // valid request 768 768 sc_signal<addr_t> r_read_to_cleanup_nline; // cache line index … … 771 771 sc_signal<size_t> r_read_to_cleanup_length; 772 772 sc_signal<size_t> r_read_to_cleanup_first_word; 773 sc_signal<bool> r_read_to_cleanup_cached_read; 773 sc_signal<bool> r_read_to_cleanup_cached_read; 774 774 sc_signal<bool> r_read_to_cleanup_is_ll; 775 775 sc_signal<addr_t> r_read_to_cleanup_addr; … … 810 810 sc_signal<data_t> r_write_sc_key; // sc command key 811 811 sc_signal<bool> r_write_bc_data_we; // Write enable for data buffer 812 812 813 813 // Buffer between WRITE fsm and TGT_RSP fsm (acknowledge a write command from L1) 814 814 sc_signal<bool> r_write_to_tgt_rsp_req; // valid request … … 818 818 sc_signal<bool> r_write_to_tgt_rsp_sc_fail; // sc command failed 819 819 820 // Buffer between WRITE fsm and IXR_CMD fsm 820 // Buffer between WRITE fsm and IXR_CMD fsm 821 821 sc_signal<bool> r_write_to_ixr_cmd_req; // valid request 822 sc_signal<size_t> r_write_to_ixr_cmd_index; // TRT index 822 sc_signal<size_t> r_write_to_ixr_cmd_index; // TRT index 823 823 824 824 // Buffer between WRITE fsm and CC_SEND fsm (Update/Invalidate L1 caches) … … 908 908 sc_signal<size_t> r_cleanup_to_tgt_rsp_trdid; // transaction trdid 909 909 sc_signal<size_t> r_cleanup_to_tgt_rsp_pktid; // transaction pktid 910 sc_signal<addr_t> 910 sc_signal<addr_t> r_cleanup_to_tgt_rsp_ll_key; 911 911 912 912 //RWT … … 948 948 // Buffer between CAS fsm and IXR_CMD fsm (XRAM write) 949 949 sc_signal<bool> r_cas_to_ixr_cmd_req; // valid request 950 sc_signal<size_t> r_cas_to_ixr_cmd_index; // TRT index 950 sc_signal<size_t> r_cas_to_ixr_cmd_index; // TRT index 951 951 952 952 // Buffer between CAS fsm and TGT_RSP fsm … … 978 978 979 979 // Buffer between IXR_RSP fsm and CONFIG fsm (response from the XRAM) 980 sc_signal<bool> r_ixr_rsp_to_config_ack; // one single bit 980 sc_signal<bool> r_ixr_rsp_to_config_ack; // one single bit 981 981 982 982 // Buffer between IXR_RSP fsm and XRAM_RSP fsm (response from the XRAM) … … 1028 1028 GenericFifo<size_t> m_xram_rsp_to_cc_send_srcid_fifo; // fifo for srcids 1029 1029 1030 // Buffer between XRAM_RSP fsm and IXR_CMD fsm 1030 // Buffer between XRAM_RSP fsm and IXR_CMD fsm 1031 1031 sc_signal<bool> r_xram_rsp_to_ixr_cmd_req; // Valid request 1032 sc_signal<size_t> r_xram_rsp_to_ixr_cmd_index; // TRT index 1032 sc_signal<size_t> r_xram_rsp_to_ixr_cmd_index; // TRT index 1033 1033 1034 1034 //RWT … … 1041 1041 sc_signal<int> r_ixr_cmd_fsm; 1042 1042 sc_signal<size_t> r_ixr_cmd_word; // word index for a put 1043 sc_signal<size_t> r_ixr_cmd_trdid; // TRT index value 1043 sc_signal<size_t> r_ixr_cmd_trdid; // TRT index value 1044 1044 sc_signal<addr_t> r_ixr_cmd_address; // address to XRAM 1045 1045 sc_signal<data_t> * r_ixr_cmd_wdata; // cache line buffer … … 1112 1112 sc_signal<data_t> *r_cleanup_old_data; 1113 1113 sc_signal<bool> r_cleanup_contains_data; 1114 1114 1115 1115 sc_signal<bool> r_cleanup_ncc; 1116 1116 sc_signal<bool> r_cleanup_to_ixr_cmd_ncc_l1_dirty; 1117 1117 sc_signal<bool> r_xram_rsp_to_ixr_cmd_inval_ncc_pending; 1118 1118 1119 1119 sc_signal<bool> r_cleanup_to_ixr_cmd_req; 1120 1120 sc_signal<data_t> *r_cleanup_to_ixr_cmd_data; -
branches/RWT/modules/vci_mem_cache/caba/source/include/xram_transaction.h
r767 r814 10 10 11 11 //////////////////////////////////////////////////////////////////////// 12 // A transaction tab entry 12 // A transaction tab entry 13 13 //////////////////////////////////////////////////////////////////////// 14 14 15 class TransactionTabEntry 15 class TransactionTabEntry 16 16 { 17 17 typedef sc_dt::sc_uint<64> wide_data_t; … … 21 21 22 22 public: 23 bool valid; // entry valid24 bool xram_read;// read request to XRAM25 addr_t nline;// index (zy) of the requested line26 size_t srcid;// processor requesting the transaction27 size_t trdid;// processor requesting the transaction28 size_t pktid;// processor requesting the transaction29 bool proc_read;// read request from processor30 size_t read_length;// length of the read (for the response)31 size_t word_index;// index of the first read word (for the response)32 std::vector<data_t> wdata; 33 std::vector<be_t> wdata_be; 34 bool rerror; 35 data_t ll_key; 36 bool config; 37 38 ///////////////////////////////////////////////////////////////////// 39 // The init() function initializes the entry 23 bool valid; // entry valid 24 bool xram_read; // read request to XRAM 25 addr_t nline; // index (zy) of the requested line 26 size_t srcid; // processor requesting the transaction 27 size_t trdid; // processor requesting the transaction 28 size_t pktid; // processor requesting the transaction 29 bool proc_read; // read request from processor 30 size_t read_length; // length of the read (for the response) 31 size_t word_index; // index of the first read word (for the response) 32 std::vector<data_t> wdata; // write buffer (one cache line) 33 std::vector<be_t> wdata_be; // be for each data in the write buffer 34 bool rerror; // error returned by xram 35 data_t ll_key; // LL key returned by the llsc_global_table 36 bool config; // transaction required by CONFIG FSM 37 38 ///////////////////////////////////////////////////////////////////// 39 // The init() function initializes the entry 40 40 ///////////////////////////////////////////////////////////////////// 41 41 void init() 42 42 { 43 valid 44 rerror 45 config 43 valid = false; 44 rerror = false; 45 config = false; 46 46 } 47 47 … … 69 69 void copy(const TransactionTabEntry &source) 70 70 { 71 valid 72 xram_read 73 nline 74 srcid 75 trdid 76 pktid 77 proc_read 71 valid = source.valid; 72 xram_read = source.xram_read; 73 nline = source.nline; 74 srcid = source.srcid; 75 trdid = source.trdid; 76 pktid = source.pktid; 77 proc_read = source.proc_read; 78 78 read_length = source.read_length; 79 word_index 79 word_index = source.word_index; 80 80 wdata_be.assign(source.wdata_be.begin(),source.wdata_be.end()); 81 81 wdata.assign(source.wdata.begin(),source.wdata.end()); … … 86 86 87 87 //////////////////////////////////////////////////////////////////// 88 // The print() function prints the entry 88 // The print() function prints the entry 89 89 //////////////////////////////////////////////////////////////////// 90 90 void print() … … 99 99 std::cout << "proc_read = " << proc_read << std::endl; 100 100 std::cout << "read_length = " << read_length << std::endl; 101 std::cout << "word_index = " << word_index << std::endl; 101 std::cout << "word_index = " << word_index << std::endl; 102 102 for(size_t i=0; i<wdata_be.size() ; i++) 103 103 { 104 std::cout << "wdata_be[" << std::dec << i << "] = " 104 std::cout << "wdata_be[" << std::dec << i << "] = " 105 105 << std::hex << wdata_be[i] << std::endl; 106 106 } 107 107 for(size_t i=0; i<wdata.size() ; i++) 108 108 { 109 std::cout << "wdata[" << std::dec << i << "] = " 109 std::cout << "wdata[" << std::dec << i << "] = " 110 110 << std::hex << wdata[i] << std::endl; 111 111 } … … 117 117 118 118 ///////////////////////////////////////////////////////////////////// 119 // 119 // Constructors 120 120 ///////////////////////////////////////////////////////////////////// 121 121 … … 131 131 TransactionTabEntry(const TransactionTabEntry &source) 132 132 { 133 valid 134 xram_read 135 nline 136 srcid 137 trdid 138 pktid 139 proc_read 133 valid = source.valid; 134 xram_read = source.xram_read; 135 nline = source.nline; 136 srcid = source.srcid; 137 trdid = source.trdid; 138 pktid = source.pktid; 139 proc_read = source.proc_read; 140 140 read_length = source.read_length; 141 word_index 141 word_index = source.word_index; 142 142 wdata_be.assign(source.wdata_be.begin(),source.wdata_be.end()); 143 wdata.assign(source.wdata.begin(),source.wdata.end()); 143 wdata.assign(source.wdata.begin(),source.wdata.end()); 144 144 rerror = source.rerror; 145 145 ll_key = source.ll_key; … … 150 150 151 151 //////////////////////////////////////////////////////////////////////// 152 // The transaction tab 152 // The transaction tab 153 153 //////////////////////////////////////////////////////////////////////// 154 154 class TransactionTab … … 185 185 186 186 //////////////////////////////////////////////////////////////////// 187 // 187 // Constructors 188 188 //////////////////////////////////////////////////////////////////// 189 189 TransactionTab() … … 194 194 195 195 TransactionTab(const std::string &name, 196 size_t n_entries, 196 size_t n_entries, 197 197 size_t n_words ) 198 198 : tab_name( name ), 199 size_tab( n_entries ) 199 size_tab( n_entries ) 200 200 { 201 201 tab = new TransactionTabEntry[size_tab]; 202 for ( size_t i=0; i<size_tab; i++) 202 for ( size_t i=0; i<size_tab; i++) 203 203 { 204 204 tab[i].alloc(n_words); … … 222 222 void init() 223 223 { 224 for ( size_t i=0; i<size_tab; i++) 224 for ( size_t i=0; i<size_tab; i++) 225 225 { 226 226 tab[i].init(); … … 247 247 TransactionTabEntry read(const size_t index) 248 248 { 249 assert( (index < size_tab) and 249 assert( (index < size_tab) and 250 250 "MEMC ERROR: Invalid Transaction Tab Entry"); 251 251 … … 255 255 // The full() function returns the state of the transaction tab 256 256 // Arguments : 257 // - index : (return argument) the index of an empty entry 257 // - index : (return argument) the index of an empty entry 258 258 // The function returns true if the transaction tab is full 259 259 ///////////////////////////////////////////////////////////////////// … … 265 265 { 266 266 index=i; 267 return false; 267 return false; 268 268 } 269 269 } … … 271 271 } 272 272 ///////////////////////////////////////////////////////////////////// 273 // The hit_read() function checks if an XRAM read transaction exists 273 // The hit_read() function checks if an XRAM read transaction exists 274 274 // for a given cache line. 275 275 // Arguments : 276 // - index : (return argument) the index of the hit entry, if there is 276 // - index : (return argument) the index of the hit entry, if there is 277 277 // - nline : the index (zy) of the requested line 278 278 // The function returns true if a read request has already been sent … … 282 282 for(size_t i=0; i<size_tab; i++) 283 283 { 284 if((tab[i].valid && (nline==tab[i].nline)) && (tab[i].xram_read)) 284 if((tab[i].valid && (nline==tab[i].nline)) && (tab[i].xram_read)) 285 285 { 286 286 index=i; 287 return true; 287 return true; 288 288 } 289 289 } … … 291 291 } 292 292 /////////////////////////////////////////////////////////////////////// 293 // The hit_write() function looks if an XRAM write transaction exists 293 // The hit_write() function looks if an XRAM write transaction exists 294 294 // for a given line. 295 295 // Arguments : … … 301 301 for(size_t i=0; i<size_tab; i++) 302 302 { 303 if(tab[i].valid && (nline==tab[i].nline) && !(tab[i].xram_read)) 303 if(tab[i].valid && (nline==tab[i].nline) && !(tab[i].xram_read)) 304 304 { 305 return true; 305 return true; 306 306 } 307 307 } … … 310 310 311 311 /////////////////////////////////////////////////////////////////////// 312 // The hit_write() function looks if an XRAM write transaction exists 312 // The hit_write() function looks if an XRAM write transaction exists 313 313 // for a given line. 314 314 // Arguments : … … 322 322 if(tab[i].valid && (nline==tab[i].nline) && !(tab[i].xram_read)) { 323 323 *index = i; 324 return true; 324 return true; 325 325 } 326 326 } … … 330 330 // The write_data_mask() function writes a vector of data (a line). 331 331 // The data is written only if the corresponding bits are set 332 // in the be vector. 332 // in the be vector. 333 333 // Arguments : 334 334 // - index : the index of the request in the transaction tab 335 // - be : vector of be 335 // - be : vector of be 336 336 // - data : vector of data 337 337 ///////////////////////////////////////////////////////////////////// 338 void write_data_mask(const size_t index, 339 const std::vector<be_t> &be, 340 const std::vector<data_t> &data) 338 void write_data_mask(const size_t index, 339 const std::vector<be_t> &be, 340 const std::vector<data_t> &data) 341 341 { 342 342 assert( (index < size_tab) and … … 349 349 "MEMC ERROR: Bad data size in TRT write_data_mask()"); 350 350 351 for(size_t i=0; i<tab[index].wdata_be.size() ; i++) 351 for(size_t i=0; i<tab[index].wdata_be.size() ; i++) 352 352 { 353 353 tab[index].wdata_be[i] = tab[index].wdata_be[i] | be[i]; … … 384 384 const size_t word_index, 385 385 const std::vector<be_t> &data_be, 386 const std::vector<data_t> &data, 386 const std::vector<data_t> &data, 387 387 const data_t ll_key = 0, 388 const bool config = false) 388 const bool config = false) 389 389 { 390 390 assert( (index < size_tab) and 391 391 "MEMC ERROR: The selected entry is out of range in TRT set()"); 392 392 393 assert( (data_be.size()==tab[index].wdata_be.size()) and 393 assert( (data_be.size()==tab[index].wdata_be.size()) and 394 394 "MEMC ERROR: Bad data_be argument in TRT set()"); 395 395 396 assert( (data.size()==tab[index].wdata.size()) and 396 assert( (data.size()==tab[index].wdata.size()) and 397 397 "MEMC ERROR: Bad data argument in TRT set()"); 398 398 399 tab[index].valid 400 tab[index].xram_read 401 tab[index].nline 402 tab[index].srcid 403 tab[index].trdid 404 tab[index].pktid 405 tab[index].proc_read 406 tab[index].read_length 407 tab[index].word_index 408 tab[index].ll_key 409 tab[index].config 410 for(size_t i=0; i<tab[index].wdata.size(); i++) 399 tab[index].valid = true; 400 tab[index].xram_read = xram_read; 401 tab[index].nline = nline; 402 tab[index].srcid = srcid; 403 tab[index].trdid = trdid; 404 tab[index].pktid = pktid; 405 tab[index].proc_read = proc_read; 406 tab[index].read_length = read_length; 407 tab[index].word_index = word_index; 408 tab[index].ll_key = ll_key; 409 tab[index].config = config; 410 for(size_t i=0; i<tab[index].wdata.size(); i++) 411 411 { 412 412 tab[index].wdata_be[i] = data_be[i]; … … 416 416 417 417 ///////////////////////////////////////////////////////////////////// 418 // The write_rsp() function writes two 32 bits words of the response 418 // The write_rsp() function writes two 32 bits words of the response 419 419 // to a XRAM read transaction. 420 420 // The BE field in TRT is taken into account. … … 435 435 "MEMC ERROR: The selected entry is out of range in TRT write_rsp()"); 436 436 437 assert( (word < tab[index].wdata_be.size()) and 437 assert( (word < tab[index].wdata_be.size()) and 438 438 "MEMC ERROR: Bad word index in TRT write_rsp()"); 439 439 … … 467 467 void erase(const size_t index) 468 468 { 469 assert( (index < size_tab) and 469 assert( (index < size_tab) and 470 470 "MEMC ERROR: The selected entry is out of range in TRT erase()"); 471 471 472 tab[index].valid 473 tab[index].rerror 472 tab[index].valid = false; 473 tab[index].rerror = false; 474 474 } 475 475 ///////////////////////////////////////////////////////////////////// -
branches/RWT/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp
r787 r814 135 135 "MULTI_ACK_UPT_LOCK", 136 136 "MULTI_ACK_UPT_CLEAR", 137 "MULTI_ACK_WRITE_RSP" ,137 "MULTI_ACK_WRITE_RSP" 138 138 }; 139 139 const char *config_fsm_str[] = … … 496 496 #if MONITOR_MEMCACHE_FSM == 1 497 497 , 498 p_read_fsm("p_read_fsm"), 499 p_write_fsm("p_write_fsm"), 500 p_xram_rsp_fsm("p_xram_rsp_fsm"), 501 p_cas_fsm("p_cas_fsm"), 502 p_cleanup_fsm("p_cleanup_fsm"), 503 p_config_fsm("p_config_fsm"), 504 p_alloc_heap_fsm("p_alloc_heap_fsm"), 505 p_alloc_dir_fsm("p_alloc_dir_fsm"), 506 p_alloc_trt_fsm("p_alloc_trt_fsm"), 507 p_alloc_upt_fsm("p_alloc_upt_fsm"), 508 p_alloc_ivt_fsm("p_alloc_ivt_fsm"), 509 p_tgt_cmd_fsm("p_tgt_cmd_fsm"), 510 p_tgt_rsp_fsm("p_tgt_rsp_fsm"), 511 p_ixr_cmd_fsm("p_ixr_cmd_fsm"), 512 p_ixr_rsp_fsm("p_ixr_rsp_fsm"), 513 p_cc_send_fsm("p_cc_send_fsm"), 498 p_read_fsm("p_read_fsm"), 499 p_write_fsm("p_write_fsm"), 500 p_xram_rsp_fsm("p_xram_rsp_fsm"), 501 p_cas_fsm("p_cas_fsm"), 502 p_cleanup_fsm("p_cleanup_fsm"), 503 p_config_fsm("p_config_fsm"), 504 p_alloc_heap_fsm("p_alloc_heap_fsm"), 505 p_alloc_dir_fsm("p_alloc_dir_fsm"), 506 p_alloc_trt_fsm("p_alloc_trt_fsm"), 507 p_alloc_upt_fsm("p_alloc_upt_fsm"), 508 p_alloc_ivt_fsm("p_alloc_ivt_fsm"), 509 p_tgt_cmd_fsm("p_tgt_cmd_fsm"), 510 p_tgt_rsp_fsm("p_tgt_rsp_fsm"), 511 p_ixr_cmd_fsm("p_ixr_cmd_fsm"), 512 p_ixr_rsp_fsm("p_ixr_rsp_fsm"), 513 p_cc_send_fsm("p_cc_send_fsm"), 514 514 p_cc_receive_fsm("p_cc_receive_fsm"), 515 515 p_multi_ack_fsm("p_multi_ack_fsm") … … 629 629 { 630 630 m_debug_data[word] = m_cache_data.read(way, set, word); 631 if ( m_debug_previous_valid and 631 if ( m_debug_previous_valid and 632 632 (m_debug_data[word] != m_debug_previous_data[word]) ) 633 633 { … … 647 647 << " / VAL = " << std::dec << entry.valid 648 648 << " / WAY = " << way 649 << " / COUNT = " << entry.count 649 << " / COUNT = " << entry.count 650 650 << " / DIRTY = " << entry.dirty 651 << " / DATA_CHANGE = " << data_change 651 << " / DATA_CHANGE = " << data_change 652 652 << std::endl; 653 653 std::cout << std::hex << " /0:" << m_debug_data[0] … … 672 672 m_debug_previous_valid = entry.valid; 673 673 m_debug_previous_dirty = entry.dirty; 674 for( size_t word=0 ; word<m_words ; word++ ) 674 for( size_t word=0 ; word<m_words ; word++ ) 675 675 m_debug_previous_data[word] = m_debug_data[word]; 676 676 } … … 840 840 } 841 841 842 842 843 843 ///////////////////////////////////////// 844 844 tmpl(void)::reset_counters() … … 874 874 m_cpt_update_remote = 0; 875 875 m_cpt_update_cost = 0; 876 876 877 877 m_cpt_minval = 0; 878 878 m_cpt_minval_local = 0; … … 893 893 m_cpt_write_miss = 0; 894 894 m_cpt_write_dirty = 0; 895 895 896 896 m_cpt_trt_rb = 0; 897 897 m_cpt_trt_full = 0; … … 1329 1329 // The READ/WRITE commands accepted in the configuration segment are targeting 1330 1330 // configuration or status registers. They must contain one single flit. 1331 // - For almost all addressable registers, the response is returned immediately. 1331 // - For almost all addressable registers, the response is returned immediately. 1332 1332 // - For MEMC_CMD_TYPE, the response is delayed until the operation is completed. 1333 1333 //////////////////////////////////////////////////////////////////////////////////// … … 1366 1366 else r_tgt_cmd_fsm = TGT_CMD_CONFIG; 1367 1367 } 1368 else //////////// memory access 1368 else //////////// memory access 1369 1369 { 1370 1370 if ( p_vci_tgt.cmd.read() == vci_param_int::CMD_READ ) … … 1411 1411 1412 1412 if((p_vci_tgt.pktid.read() & 0x7) == TYPE_CAS) r_tgt_cmd_fsm = TGT_CMD_CAS; 1413 else r_tgt_cmd_fsm = TGT_CMD_WRITE; 1413 else r_tgt_cmd_fsm = TGT_CMD_WRITE; 1414 1414 } 1415 1415 else … … 1509 1509 m_config_func_idx_mask; 1510 1510 1511 bool need_rsp; 1512 int error; 1511 bool need_rsp; 1512 int error; 1513 1513 uint32_t rdata = 0; // default value 1514 1514 uint32_t wdata = p_vci_tgt.wdata.read(); … … 1617 1617 1618 1618 break; 1619 1619 1620 1620 default: 1621 1621 error = 1; … … 1719 1719 size_t cell = (address - seg_base)/vci_param_int::B; 1720 1720 1721 bool need_rsp; 1722 size_t error; 1721 bool need_rsp; 1722 size_t error; 1723 1723 uint32_t rdata = 0; // default value 1724 uint32_t wdata = p_vci_tgt.wdata.read(); 1724 uint32_t wdata = p_vci_tgt.wdata.read(); 1725 1725 1726 1726 if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_READ) // get lock … … 1830 1830 << " read command packet must contain one single flit" << std::endl; 1831 1831 exit(0); 1832 } 1832 } 1833 1833 // check plen for LL 1834 if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ) and 1834 if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ) and 1835 1835 (p_vci_tgt.plen.read() != 8) ) 1836 1836 { … … 1867 1867 } 1868 1868 else { 1869 if (is_local_req(p_vci_tgt.srcid.read())) 1869 if (is_local_req(p_vci_tgt.srcid.read())) 1870 1870 { 1871 1871 m_cpt_read_local++; … … 1910 1910 m_cpt_write_flits_local++; 1911 1911 } 1912 else 1912 else 1913 1913 { 1914 1914 m_cpt_write_flits_remote++; … … 1926 1926 m_cpt_sc_local++; 1927 1927 } 1928 else 1928 else 1929 1929 { 1930 1930 m_cpt_sc_remote++; … … 1932 1932 } 1933 1933 else { 1934 if (is_local_req(p_vci_tgt.srcid.read())) 1934 if (is_local_req(p_vci_tgt.srcid.read())) 1935 1935 { 1936 1936 m_cpt_write_local++; … … 1973 1973 if (p_vci_tgt.eop) { 1974 1974 // <Activity counters> 1975 if (is_local_req(p_vci_tgt.srcid.read())) 1975 if (is_local_req(p_vci_tgt.srcid.read())) 1976 1976 { 1977 1977 m_cpt_cas_local++; … … 1993 1993 // MULTI_ACK FSM 1994 1994 ///////////////////////////////////////////////////////////////////////// 1995 // This FSM controls the response to the multicast update requests sent 1995 // This FSM controls the response to the multicast update requests sent 1996 1996 // by the memory cache to the L1 caches and update the UPT. 1997 1997 // … … 2133 2133 ///////////////////////// 2134 2134 case MULTI_ACK_WRITE_RSP: // Post a response request to TGT_RSP FSM 2135 // Wait if pending request 2135 // Wait if pending request 2136 2136 { 2137 2137 if ( r_multi_ack_to_tgt_rsp_req.read() ) break; … … 2168 2168 2169 2169 // 2170 // For both INVAL and SYNC commands, the CONFIG FSM contains the loop handling 2170 // For both INVAL and SYNC commands, the CONFIG FSM contains the loop handling 2171 2171 // 2172 2172 // all cache lines covered by the buffer. The various lines of a given buffer 2173 2173 // can be pipelined: the CONFIG FSM does not wait the response for line (n) to send 2174 // the command for line (n+1). It decrements the r_config_cmd_lines counter until 2174 // the command for line (n+1). It decrements the r_config_cmd_lines counter until 2175 2175 // the last request has been registered in TRT (for a SYNC), or in IVT (for an INVAL). 2176 2176 // The r_config_rsp_lines counter contains the number of expected responses from … … 2180 2180 // be concurently accessed by those three FSMs, it is implemented as an [incr/decr] 2181 2181 // counter. 2182 // 2182 // 2183 2183 // - INVAL request: 2184 // For each line, it access to the DIR. 2185 // In case of miss, it does nothing, and a response is requested to TGT_RSP FSM. 2184 // For each line, it access to the DIR. 2185 // In case of miss, it does nothing, and a response is requested to TGT_RSP FSM. 2186 2186 // In case of hit, with no copies in L1 caches, the line is invalidated and 2187 2187 // a response is requested to TGT_RSP FSM. … … 2195 2195 // This constraint can be released, but it requires to make 2 PUT transactions 2196 2196 // for the first and the last line... 2197 // 2197 // 2198 2198 // - SYNC request: 2199 // For each line, it access to the DIR. 2200 // In case of miss, it does nothing, and a response is requested to TGT_RSP FSM. 2199 // For each line, it access to the DIR. 2200 // In case of miss, it does nothing, and a response is requested to TGT_RSP FSM. 2201 2201 // In case of hit, a PUT transaction is registered in TRT and a request is sent 2202 2202 // to IXR_CMD FSM. The IXR_RSP FSM decrements the r_config_rsp_lines counter … … 2205 2205 // 2206 2206 // From the software point of view, a configuration request is a sequence 2207 // of 6 atomic accesses in an uncached segment. A dedicated lock is used 2207 // of 6 atomic accesses in an uncached segment. A dedicated lock is used 2208 2208 // to handle only one configuration command at a given time: 2209 2209 // - Read MEMC_LOCK : Get the lock … … 2218 2218 { 2219 2219 ///////////////// 2220 case CONFIG_IDLE: // waiting a config request 2221 { 2222 if ( r_config_cmd.read() != MEMC_CMD_NOP ) 2220 case CONFIG_IDLE: // waiting a config request 2221 { 2222 if ( r_config_cmd.read() != MEMC_CMD_NOP ) 2223 2223 { 2224 2224 r_config_fsm = CONFIG_LOOP; … … 2226 2226 #if DEBUG_MEMC_CONFIG 2227 2227 if(m_debug) 2228 std::cout << " <MEMC " << name() << " CONFIG_IDLE> Config Request received" 2228 std::cout << " <MEMC " << name() << " CONFIG_IDLE> Config Request received" 2229 2229 << " address = " << std::hex << r_config_address.read() 2230 2230 << " / nlines = " << std::dec << r_config_cmd_lines.read() … … 2235 2235 } 2236 2236 ///////////////// 2237 case CONFIG_LOOP: // test last line to be handled 2237 case CONFIG_LOOP: // test last line to be handled 2238 2238 { 2239 2239 if ( r_config_cmd_lines.read() == 0 ) … … 2249 2249 #if DEBUG_MEMC_CONFIG 2250 2250 if(m_debug) 2251 std::cout << " <MEMC " << name() << " CONFIG_LOOP>" 2252 << " address = " << std::hex << r_config_address.read() 2253 << " / nlines = " << std::dec << r_config_cmd_lines.read() 2251 std::cout << " <MEMC " << name() << " CONFIG_LOOP>" 2252 << " address = " << std::hex << r_config_address.read() 2253 << " / nlines = " << std::dec << r_config_cmd_lines.read() 2254 2254 << " / command = " << r_config_cmd.read() << std::endl; 2255 2255 #endif … … 2257 2257 } 2258 2258 ///////////////// 2259 case CONFIG_WAIT: // wait completion (last response) 2259 case CONFIG_WAIT: // wait completion (last response) 2260 2260 { 2261 2261 if ( r_config_rsp_lines.read() == 0 ) // last response received … … 2266 2266 #if DEBUG_MEMC_CONFIG 2267 2267 if(m_debug) 2268 std::cout << " <MEMC " << name() << " CONFIG_WAIT>" 2268 std::cout << " <MEMC " << name() << " CONFIG_WAIT>" 2269 2269 << " / lines to do = " << std::dec << r_config_rsp_lines.read() << std::endl; 2270 2270 #endif … … 2272 2272 } 2273 2273 //////////////// 2274 case CONFIG_RSP: // request TGT_RSP FSM to return response 2274 case CONFIG_RSP: // request TGT_RSP FSM to return response 2275 2275 { 2276 2276 if ( not r_config_to_tgt_rsp_req.read() ) … … 2329 2329 2330 2330 if (entry.valid and // hit & inval command 2331 (r_config_cmd.read() == MEMC_CMD_INVAL)) 2331 (r_config_cmd.read() == MEMC_CMD_INVAL)) 2332 2332 { 2333 2333 r_config_fsm = CONFIG_IVT_LOCK; … … 2336 2336 entry.dirty and 2337 2337 (r_config_cmd.read() == MEMC_CMD_SYNC) ) 2338 { 2338 { 2339 2339 r_config_fsm = CONFIG_TRT_LOCK; 2340 2340 } 2341 else // return to LOOP 2341 else // return to LOOP 2342 2342 { 2343 2343 r_config_cmd_lines = r_config_cmd_lines.read() - 1; … … 2359 2359 ///////////////////// 2360 2360 case CONFIG_TRT_LOCK: // enter this state in case of SYNC command 2361 // to a dirty cache line 2361 // to a dirty cache line 2362 2362 // keep DIR lock, and try to get TRT lock 2363 2363 // return to LOOP state if TRT full … … 2423 2423 std::vector<data_t> data_vector; 2424 2424 data_vector.clear(); 2425 for(size_t word=0; word<m_words; word++) 2425 for(size_t word=0; word<m_words; word++) 2426 2426 { 2427 2427 uint32_t data = m_cache_data.read( way, set, word ); … … 2439 2439 0, // read_length: unused 2440 2440 0, // word_index: unused 2441 std::vector<be_t>(m_words,0xF), // byte-enable: unused 2441 std::vector<be_t>(m_words,0xF), // byte-enable: unused 2442 2442 data_vector, // data to be written 2443 2443 0, // ll_key: unused … … 2470 2470 if(m_debug) 2471 2471 std::cout << " <MEMC " << name() << " CONFIG_PUT_REQ> post PUT request to IXR_CMD_FSM" 2472 << " / address = " << std::hex << r_config_address.read() << std::endl; 2472 << " / address = " << std::hex << r_config_address.read() << std::endl; 2473 2473 #endif 2474 2474 } … … 2480 2480 // Return to LOOP state if IVT full. 2481 2481 // Register inval in IVT, and invalidate the 2482 // directory if IVT not full. 2482 // directory if IVT not full. 2483 2483 { 2484 2484 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and … … 2515 2515 2516 2516 wok = m_ivt.set(false, // it's an inval transaction 2517 broadcast, 2517 broadcast, 2518 2518 false, // no response required 2519 2519 true, // acknowledge required … … 2558 2558 case CONFIG_BC_SEND: // Post a broadcast inval request to CC_SEND FSM 2559 2559 { 2560 if( not r_config_to_cc_send_multi_req.read() and 2560 if( not r_config_to_cc_send_multi_req.read() and 2561 2561 not r_config_to_cc_send_brdcast_req.read() ) 2562 2562 { … … 2575 2575 if(m_debug) 2576 2576 std::cout << " <MEMC " << name() << " CONFIG_BC_SEND>" 2577 << " Post a broadcast inval request to CC_SEND FSM" 2577 << " Post a broadcast inval request to CC_SEND FSM" 2578 2578 << " / address = " << r_config_address.read() <<std::endl; 2579 2579 #endif … … 2584 2584 case CONFIG_INVAL_SEND: // Post a multi inval request to CC_SEND FSM 2585 2585 { 2586 if( not r_config_to_cc_send_multi_req.read() and 2586 if( not r_config_to_cc_send_multi_req.read() and 2587 2587 not r_config_to_cc_send_brdcast_req.read() ) 2588 2588 { … … 2612 2612 if(m_debug) 2613 2613 std::cout << " <MEMC " << name() << " CONFIG_INVAL_SEND>" 2614 << " Post multi inval request to CC_SEND FSM" 2615 << " / address = " << std::hex << r_config_address.read() 2616 << " / copy = " << r_config_dir_copy_srcid.read() 2614 << " Post multi inval request to CC_SEND FSM" 2615 << " / address = " << std::hex << r_config_address.read() 2616 << " / copy = " << r_config_dir_copy_srcid.read() 2617 2617 << " / inst = " << std::dec << r_config_dir_copy_inst.read() << std::endl; 2618 2618 #endif … … 2640 2640 { 2641 2641 HeapEntry entry = m_heap.read( r_config_heap_next.read() ); 2642 bool last_copy = (entry.next == r_config_heap_next.read()); 2642 bool last_copy = (entry.next == r_config_heap_next.read()); 2643 2643 2644 2644 config_to_cc_send_fifo_srcid = entry.owner.srcid; … … 2660 2660 if(m_debug) 2661 2661 std::cout << " <MEMC " << name() << " CONFIG_HEAP_SCAN>" 2662 << " Post multi inval request to CC_SEND FSM" 2663 << " / address = " << std::hex << r_config_address.read() 2664 << " / copy = " << entry.owner.srcid 2662 << " Post multi inval request to CC_SEND FSM" 2663 << " / address = " << std::hex << r_config_address.read() 2664 << " / copy = " << entry.owner.srcid 2665 2665 << " / inst = " << std::dec << entry.owner.inst << std::endl; 2666 2666 #endif … … 2681 2681 } 2682 2682 else 2683 { 2683 { 2684 2684 last_entry.next = free_pointer; 2685 2685 } … … 2799 2799 2800 2800 // hit on a WT line or the owner has no more copy (if LL, the owner must be invalidated even if he made the request) 2801 if (entry.cache_coherent or (entry.count == 0))// or (entry.owner.srcid == m_cmd_read_srcid_fifo.read())) 2801 if (entry.cache_coherent or (entry.count == 0))// or (entry.owner.srcid == m_cmd_read_srcid_fifo.read())) 2802 2802 { 2803 2803 // test if we need to register a new copy in the heap … … 2851 2851 { 2852 2852 std::cout 2853 << " <MEMC " << name() << " READ_IVT_LOCK>" 2853 << " <MEMC " << name() << " READ_IVT_LOCK>" 2854 2854 << " Wait cleanup completion" 2855 2855 << std::endl; … … 2862 2862 r_read_to_cc_send_dest = r_read_copy.read(); 2863 2863 r_read_to_cc_send_nline = nline; 2864 r_read_to_cc_send_inst = ((m_cmd_read_pktid_fifo.read() & 0x2) != 0); 2864 r_read_to_cc_send_inst = ((m_cmd_read_pktid_fifo.read() & 0x2) != 0); 2865 2865 r_read_to_cleanup_req = true; 2866 2866 r_read_to_cleanup_nline = nline; 2867 2867 r_read_to_cleanup_srcid = m_cmd_read_srcid_fifo.read(); 2868 r_read_to_cleanup_inst = ((m_cmd_read_pktid_fifo.read() & 0x2) != 0); 2868 r_read_to_cleanup_inst = ((m_cmd_read_pktid_fifo.read() & 0x2) != 0); 2869 2869 r_read_to_cleanup_length = m_cmd_read_length_fifo.read(); 2870 2870 r_read_to_cleanup_first_word = m_x[(addr_t) m_cmd_read_addr_fifo.read()]; … … 2920 2920 break; 2921 2921 } 2922 /////////////////// 2922 /////////////////// 2923 2923 case READ_DIR_HIT: // read data in cache & update the directory 2924 2924 // we enter this state in 3 cases: … … 3024 3024 bool go_cnt = (r_read_count.read() >= m_max_copies) or m_heap.is_full(); 3025 3025 3026 if (!r_read_coherent.read()) 3027 { 3028 std::cout << "Address = " << std::hex << (m_cmd_read_addr_fifo.read()) << std::dec << " |count = " << r_read_count.read() << std::endl; 3029 } 3030 assert (r_read_coherent.read() && "accÚs au heap sur ncc"); 3026 assert (r_read_coherent.read() && "Heap access on line NCC"); 3031 3027 // read data in the cache 3032 3028 size_t set = m_y[(addr_t)(m_cmd_read_addr_fifo.read())]; … … 3135 3131 m_heap.set_full(); 3136 3132 } 3137 3133 3138 3134 // <Activity counters> 3139 3135 m_cpt_heap_slot_available--; … … 3418 3414 << " srcid = " << std::hex << m_cmd_write_srcid_fifo.read() 3419 3415 << " / address = " << std::hex << m_cmd_write_addr_fifo.read() 3420 << " / data = " << m_cmd_write_data_fifo.read() 3421 << " / pktid = " << m_cmd_write_pktid_fifo.read() 3416 << " / data = " << m_cmd_write_data_fifo.read() 3417 << " / pktid = " << m_cmd_write_pktid_fifo.read() 3422 3418 << std::endl; 3423 3419 #endif … … 3431 3427 3432 3428 // check that the next word is in the same cache line 3433 assert((m_nline[(addr_t)(r_write_address.read())] == 3429 assert((m_nline[(addr_t)(r_write_address.read())] == 3434 3430 m_nline[(addr_t)(m_cmd_write_addr_fifo.read())]) && 3435 3431 "MEMC ERROR in WRITE_NEXT state: Illegal write burst"); … … 3482 3478 // test address and key match of the SC command on the 3483 3479 // LL/SC table without removing reservation. The reservation 3484 // will be erased after in this FSM. 3480 // will be erased after in this FSM. 3485 3481 bool sc_success = m_llsc_table.check(r_write_address.read(), 3486 3482 r_write_sc_key.read()); … … 3493 3489 else 3494 3490 { 3495 // write burst 3491 // write burst 3496 3492 #define L2 soclib::common::uint32_log2 3497 3493 addr_t min = r_write_address.read(); … … 3594 3590 addr_t nline = m_nline[(addr_t)(r_write_address.read())]; 3595 3591 3596 //if there is a matched updt req, we should wait until it is over. Because 3592 //if there is a matched updt req, we should wait until it is over. Because 3597 3593 //we need the lastest updt data. 3598 3594 match_inval = m_ivt.search_inval(nline, index); … … 3600 3596 assert ((r_write_count.read() == 1) and "NCC to CC req without copy"); 3601 3597 3602 if( not match_inval and 3598 if( not match_inval and 3603 3599 not m_ivt.is_full() and 3604 3600 not r_write_to_cc_send_req.read() and … … 3676 3672 // no_update is true when there is no need for coherence transaction 3677 3673 bool no_update = ( (r_write_count.read() == 0) or 3678 (owner and (r_write_count.read() == 1) and 3674 (owner and (r_write_count.read() == 1) and 3679 3675 ((r_write_pktid.read() & 0x7) != TYPE_SC))); 3680 3676 … … 3682 3678 if(no_update) 3683 3679 { 3684 // SC command but zero copies 3680 // SC command but zero copies 3685 3681 if ((r_write_pktid.read() & 0x7) == TYPE_SC) 3686 3682 { … … 3726 3722 if(no_update) 3727 3723 { 3728 std::cout << " <MEMC " << name() 3724 std::cout << " <MEMC " << name() 3729 3725 << " WRITE_DIR_HIT> Write into cache / No coherence transaction" 3730 3726 << std::endl; … … 3761 3757 true, // response required 3762 3758 false, // no acknowledge required 3763 srcid, 3759 srcid, 3764 3760 trdid, 3765 3761 pktid, … … 3792 3788 if(wok) 3793 3789 { 3794 std::cout << " <MEMC " << name() 3790 std::cout << " <MEMC " << name() 3795 3791 << " WRITE_UPT_LOCK> Register the multicast update in UPT / " 3796 3792 << " nb_copies = " << r_write_count.read() << std::endl; … … 3814 3810 #if DEBUG_MEMC_WRITE 3815 3811 if(m_debug) 3816 std::cout << " <MEMC " << name() 3812 std::cout << " <MEMC " << name() 3817 3813 << " WRITE_UPT_HEAP_LOCK> Get acces to the HEAP" << std::endl; 3818 3814 #endif … … 3906 3902 3907 3903 // put the next srcid in the fifo 3908 if ((entry.owner.srcid != r_write_srcid.read()) or 3904 if ((entry.owner.srcid != r_write_srcid.read()) or 3909 3905 ((r_write_pktid.read() & 0x7) == TYPE_SC) or 3910 3906 entry.owner.inst) … … 4026 4022 4027 4023 r_write_sc_key = m_cmd_write_data_fifo.read(); 4028 } 4024 } 4029 4025 4030 4026 // initialize the be field for all words … … 4049 4045 { 4050 4046 std::cout << " <MEMC " << name() << " WRITE_RSP> Post a request to TGT_RSP FSM" 4051 << " : rsrcid = " << std::hex << r_write_srcid.read() 4052 << " : rpktid = " << std::hex << r_write_pktid.read() 4047 << " : rsrcid = " << std::hex << r_write_srcid.read() 4048 << " : rpktid = " << std::hex << r_write_pktid.read() 4053 4049 << " : sc_fail= " << std::hex << r_write_sc_fail.read() 4054 4050 << std::endl; … … 4058 4054 << " srcid = " << std::hex << m_cmd_write_srcid_fifo.read() 4059 4055 << " / address = " << m_cmd_write_addr_fifo.read() 4060 << " / data = " << m_cmd_write_data_fifo.read() 4061 << " / pktid = " << m_cmd_write_pktid_fifo.read() 4056 << " / data = " << m_cmd_write_data_fifo.read() 4057 << " / pktid = " << m_cmd_write_pktid_fifo.read() 4062 4058 << std::endl; 4063 4059 } … … 4068 4064 } 4069 4065 ///////////////////////// RWT 4070 case WRITE_MISS_IVT_LOCK: 4066 case WRITE_MISS_IVT_LOCK: 4071 4067 { 4072 4068 if (r_alloc_ivt_fsm.read() == ALLOC_IVT_WRITE) … … 4224 4220 #if DEBUG_MEMC_WRITE 4225 4221 if(m_debug) 4226 std::cout << " <MEMC " << name() 4222 std::cout << " <MEMC " << name() 4227 4223 << " WRITE_MISS_XRAM_REQ> Post a GET request to the" 4228 4224 << " IXR_CMD FSM" << std::endl; … … 4282 4278 #if DEBUG_MEMC_WRITE 4283 4279 if(m_debug) 4284 std::cout 4280 std::cout 4285 4281 << " <MEMC " << name() 4286 4282 << " WRITE_BC_TRT_LOCK> Complete data buffer" << std::endl; … … 4476 4472 // 4477 4473 // - It sends a single flit VCI read to the XRAM in case of 4478 // GET request posted by the READ, WRITE or CAS FSMs. 4474 // GET request posted by the READ, WRITE or CAS FSMs. 4479 4475 // - It sends a multi-flit VCI write in case of PUT request posted by 4480 4476 // the XRAM_RSP, WRITE, CAS, or CONFIG FSMs. … … 4535 4531 else if(r_config_to_ixr_cmd_req.read()) r_ixr_cmd_fsm = IXR_CMD_CONFIG_TRT; 4536 4532 else if(r_cleanup_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_CLEANUP_TRT; 4537 break; 4533 break; 4538 4534 ///////////////////////// 4539 4535 case IXR_CMD_CONFIG_IDLE: … … 4597 4593 } 4598 4594 ///////////////////// 4599 case IXR_CMD_CAS_TRT: // access TRT for a PUT or a GET 4595 case IXR_CMD_CAS_TRT: // access TRT for a PUT or a GET 4600 4596 { 4601 4597 if ( r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_CMD ) … … 4624 4620 } 4625 4621 ////////////////////// 4626 case IXR_CMD_XRAM_TRT: // access TRT for a PUT 4622 case IXR_CMD_XRAM_TRT: // access TRT for a PUT 4627 4623 { 4628 4624 if ( r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_CMD ) … … 4646 4642 } 4647 4643 ////////////////////// 4648 case IXR_CMD_CLEANUP_TRT: // access TRT for a PUT 4644 case IXR_CMD_CLEANUP_TRT: // access TRT for a PUT 4649 4645 { 4650 4646 if ( r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_CMD ) … … 4866 4862 // The FSM takes the lock protecting the TRT, and the corresponding 4867 4863 // entry is erased. If an acknowledge was required (in case of software SYNC) 4868 // the r_config_rsp_lines counter is decremented. 4864 // the r_config_rsp_lines counter is decremented. 4869 4865 // 4870 4866 // - A response to a GET request is a multi-cell VCI packet. … … 4873 4869 // The FSM takes the lock protecting the TRT to store the line in the TRT 4874 4870 // (taking into account the write requests already stored in the TRT). 4875 // When the line is completely written, the r_ixr_rsp_to_xram_rsp_rok[index] 4871 // When the line is completely written, the r_ixr_rsp_to_xram_rsp_rok[index] 4876 4872 // signal is set to inform the XRAM_RSP FSM. 4877 4873 /////////////////////////////////////////////////////////////////////////////// … … 4902 4898 << " IXR_RSP_IDLE> Response from XRAM to a get transaction" << std::endl; 4903 4899 #endif 4904 } 4905 } 4900 } 4901 } 4906 4902 break; 4907 4903 } … … 4919 4915 if(r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP) 4920 4916 { 4921 size_t index = r_ixr_rsp_trt_index.read(); 4917 size_t index = r_ixr_rsp_trt_index.read(); 4922 4918 if (m_trt.is_config(index)) // it's a config transaction 4923 4919 { … … 4977 4973 // The cache line has been written in the TRT by the IXR_CMD_FSM. 4978 4974 // As the IXR_RSP FSM and the XRAM_RSP FSM are running in parallel, 4979 // there is as many flip-flops r_ixr_rsp_to_xram_rsp_rok[i] as the number 4975 // there is as many flip-flops r_ixr_rsp_to_xram_rsp_rok[i] as the number 4980 4976 // of entries in the TRT, that are handled with a round-robin priority... 4981 4977 // … … 5018 5014 break; 5019 5015 } 5020 } 5016 } 5021 5017 break; 5022 5018 } … … 5074 5070 r_xram_rsp_victim_inval = inval ; 5075 5071 // a NCC line is by default considered as dirty in the L1: we must take a reservation on a TRT entry 5076 r_xram_rsp_victim_dirty = victim.dirty or (!victim.cache_coherent && (victim.count == 1)); 5072 r_xram_rsp_victim_dirty = victim.dirty or (!victim.cache_coherent && (victim.count == 1)); 5077 5073 5078 5074 5079 5075 // A line that undergoes a change in its state (ncc to cc), should not be evicted from the memory cache. 5080 if((victim.tag * m_sets + set) == r_read_to_cleanup_nline.read() and r_read_to_cleanup_req.read()) 5076 if((victim.tag * m_sets + set) == r_read_to_cleanup_nline.read() and r_read_to_cleanup_req.read()) 5081 5077 { 5082 5078 r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT; … … 5090 5086 #endif 5091 5087 } 5092 else if( not r_xram_rsp_trt_buf.rerror ) 5088 else if( not r_xram_rsp_trt_buf.rerror ) 5093 5089 { 5094 5090 r_xram_rsp_fsm = XRAM_RSP_IVT_LOCK; 5095 5091 } 5096 else 5092 else 5097 5093 { 5098 5094 r_xram_rsp_fsm = XRAM_RSP_ERROR_ERASE; … … 5111 5107 } 5112 5108 /////////////////////// 5113 case XRAM_RSP_IVT_LOCK: // Keep DIR and TRT locks and take the IVT lock 5109 case XRAM_RSP_IVT_LOCK: // Keep DIR and TRT locks and take the IVT lock 5114 5110 // to check a possible pending inval 5115 5111 { … … 5241 5237 bool wok = m_ivt.set(false, // it's an inval transaction 5242 5238 broadcast, // set broadcast bit 5243 false, // no response required 5244 false, // no acknowledge required 5239 false, // no response required 5240 false, // no acknowledge required 5245 5241 0, // srcid 5246 5242 0, // trdid … … 5252 5248 r_xram_rsp_ivt_index = index; 5253 5249 assert( wok and 5254 "MEMC ERROR in XRAM_RSP_DIR_UPDT state: IVT should not be full"); 5250 "MEMC ERROR in XRAM_RSP_DIR_UPDT state: IVT should not be full"); 5255 5251 5256 5252 } … … 5313 5309 0, // unused 5314 5310 0, // unused 5315 std::vector<be_t>(m_words,0xF), 5311 std::vector<be_t>(m_words,0xF), 5316 5312 data_vector); 5317 5313 #if DEBUG_MEMC_XRAM_RSP … … 5411 5407 m_cpt_write_dirty++; 5412 5408 5413 bool multi_req = not r_xram_rsp_victim_is_cnt.read() and 5409 bool multi_req = not r_xram_rsp_victim_is_cnt.read() and 5414 5410 r_xram_rsp_victim_inval.read(); 5415 5411 bool not_last_multi_req = multi_req and (r_xram_rsp_victim_count.read() != 1); … … 5540 5536 // acknowledged before signaling another one. 5541 5537 // Therefore, when there is an active error, and other 5542 // errors arrive, these are not considered 5538 // errors arrive, these are not considered 5543 5539 5544 5540 if (!r_xram_rsp_rerror_irq.read() && r_xram_rsp_rerror_irq_enable.read() … … 5639 5635 r_cleanup_inst = (type == DspinRwtParam::TYPE_CLEANUP_INST); 5640 5636 r_cleanup_srcid = srcid; 5641 r_cleanup_ncc = 5637 r_cleanup_ncc = 5642 5638 DspinRwtParam::dspin_get( 5643 5639 flit, … … 5738 5734 uint64_t flit = m_cc_receive_to_cleanup_fifo.read(); 5739 5735 5740 uint32_t data = 5736 uint32_t data = 5741 5737 DspinRwtParam::dspin_get (flit, DspinRwtParam::CLEANUP_DATA_UPDT); 5742 5738 … … 5809 5805 //RWT 5810 5806 size_t set = m_y[(addr_t)(cleanup_address)]; 5811 m_cache_data.read_line(way, set, r_cleanup_old_data); 5807 m_cache_data.read_line(way, set, r_cleanup_old_data); 5812 5808 r_cleanup_coherent = entry.cache_coherent; 5813 5809 … … 5911 5907 entry.lock = r_cleanup_lock.read(); 5912 5908 entry.ptr = r_cleanup_ptr.read(); 5913 if (r_read_to_cleanup_req.read() and (r_cleanup_nline.read() == r_read_to_cleanup_nline.read())) //pending READ 5909 if (r_read_to_cleanup_req.read() and (r_cleanup_nline.read() == r_read_to_cleanup_nline.read())) //pending READ 5914 5910 { 5915 5911 if (r_read_to_cleanup_cached_read.read()) … … 5937 5933 5938 5934 #if REVERT_CC_MECANISM 5939 // Revert CC to NCC if : 5935 // Revert CC to NCC if : 5940 5936 // - no more copy in L1 caches 5941 5937 // - this line is not in counter mode (broadcast) … … 5948 5944 5949 5945 #if REVERT_BC_MECANISM 5950 if ((r_cleanup_count.read() - 1) == 0) 5946 if ((r_cleanup_count.read() - 1) == 0) 5951 5947 { 5952 5948 entry.is_cnt = false; … … 6082 6078 { 6083 6079 r_cleanup_to_tgt_rsp_data[i] = r_cleanup_old_data[i].read(); 6084 } 6080 } 6085 6081 } 6086 6082 … … 6354 6350 ////////////////////// 6355 6351 case CLEANUP_IVT_LOCK: // get the lock protecting the IVT to search a pending 6356 // invalidate transaction matching the cleanup 6352 // invalidate transaction matching the cleanup 6357 6353 { 6358 6354 if(r_alloc_ivt_fsm.read() != ALLOC_IVT_CLEANUP) break; … … 6432 6428 } 6433 6429 /////////////////////// 6434 case CLEANUP_IVT_CLEAR: // Clear IVT entry 6430 case CLEANUP_IVT_CLEAR: // Clear IVT entry 6435 6431 { 6436 6432 assert( (r_alloc_ivt_fsm.read() == ALLOC_IVT_CLEANUP) and … … 6473 6469 r_cleanup_to_tgt_rsp_trdid = r_cleanup_write_trdid.read(); 6474 6470 r_cleanup_to_tgt_rsp_pktid = r_cleanup_write_pktid.read(); 6475 r_cleanup_to_tgt_rsp_type = true; 6471 r_cleanup_to_tgt_rsp_type = true; 6476 6472 6477 6473 if (r_cleanup_ncc.read() ) … … 6503 6499 { 6504 6500 size_t index = 0; 6505 bool hit = m_trt.hit_write(r_cleanup_nline.read(), &index); 6501 bool hit = m_trt.hit_write(r_cleanup_nline.read(), &index); 6506 6502 6507 6503 assert (hit and "CLEANUP_IXR_REQ found no matching entry in TRT"); … … 6510 6506 6511 6507 if (r_cleanup_contains_data.read()) 6512 { 6508 { 6513 6509 std::vector<data_t> data_vector; 6514 6510 data_vector.clear(); … … 6587 6583 << " nline = " << std::hex << r_cleanup_nline.read() 6588 6584 << " / way = " << std::dec << r_cleanup_way.read() 6589 << " / srcid = " << std::dec << r_cleanup_srcid.read() 6585 << " / srcid = " << std::dec << r_cleanup_srcid.read() 6590 6586 << std::endl; 6591 6587 #endif … … 6805 6801 if(m_debug) 6806 6802 std::cout << " <MEMC " << name() << " CAS_DIR_HIT_WRITE>" 6807 << " Broacast Inval required" 6803 << " Broacast Inval required" 6808 6804 << " / copies = " << r_cas_count.read() << std::endl; 6809 6805 #endif … … 6817 6813 if(m_debug) 6818 6814 std::cout << " <MEMC " << name() << " CAS_DIR_HIT_WRITE>" 6819 << " Multi Inval required" 6815 << " Multi Inval required" 6820 6816 << " / copies = " << r_cas_count.read() << std::endl; 6821 6817 #endif … … 6874 6870 wok = m_upt.set(true, // it's an update transaction 6875 6871 false, // it's not a broadcast 6876 true, // response required 6872 true, // response required 6877 6873 false, // no acknowledge required 6878 6874 srcid, … … 7137 7133 { 7138 7134 if(i == word) // first modified word 7139 data_vector.push_back( r_cas_wdata.read() ); 7135 data_vector.push_back( r_cas_wdata.read() ); 7140 7136 else if((i == word+1) and (r_cas_cpt.read() == 4)) // second modified word 7141 7137 data_vector.push_back( m_cmd_cas_wdata_fifo.read() ); … … 7144 7140 } 7145 7141 m_trt.set( r_cas_trt_index.read(), 7146 false, // PUT request 7142 false, // PUT request 7147 7143 m_nline[(addr_t)(m_cmd_cas_addr_fifo.read())], 7148 7144 0, … … 7364 7360 // 7365 7361 // It implements a round-robin priority between the four possible client FSMs 7366 // XRAM_RSP > CAS > READ > WRITE > CONFIG 7362 // XRAM_RSP > CAS > READ > WRITE > CONFIG 7367 7363 // 7368 7364 // Each FSM can request the next services: … … 7375 7371 // - r_config_to_cc_send_multi_req : multi-inval 7376 7372 // r_config_to_cc_send_brdcast_req : broadcast-inval 7377 // 7373 // 7378 7374 // An inval request is a double DSPIN flit command containing: 7379 7375 // 1. the index of the line to be invalidated. … … 7517 7513 } 7518 7514 /////////////////////////// 7519 case CC_SEND_READ_IDLE: 7515 case CC_SEND_READ_IDLE: 7520 7516 { 7521 7517 // WRITE … … 8264 8260 } 8265 8261 else if(r_multi_ack_to_tgt_rsp_req) r_tgt_rsp_fsm = TGT_RSP_MULTI_ACK; 8266 else if(r_cleanup_to_tgt_rsp_req) 8262 else if(r_cleanup_to_tgt_rsp_req) 8267 8263 { 8268 8264 r_tgt_rsp_fsm = TGT_RSP_CLEANUP; … … 8809 8805 // - The XRAM_RSP FSM initiates broadcast/multicast invalidate transaction and sets 8810 8806 // a new entry in the IVT 8811 // - The CONFIG FSM does the same thing as the XRAM_RSP FSM 8807 // - The CONFIG FSM does the same thing as the XRAM_RSP FSM 8812 8808 // - The CLEANUP FSM complete those trasactions and erase the IVT entry. 8813 8809 // The resource is always allocated. … … 8844 8840 ////////////////////////// 8845 8841 case ALLOC_IVT_READ: // allocated to READ FSM 8846 if (r_read_fsm.read() != READ_IVT_LOCK) 8842 if (r_read_fsm.read() != READ_IVT_LOCK) 8847 8843 { 8848 8844 if (r_xram_rsp_fsm.read() == XRAM_RSP_IVT_LOCK) … … 9231 9227 r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP; 9232 9228 9233 else if( r_config_fsm.read() == CONFIG_TRT_LOCK ) 9229 else if( r_config_fsm.read() == CONFIG_TRT_LOCK ) 9234 9230 r_alloc_trt_fsm = ALLOC_TRT_CONFIG; 9235 9231 … … 9268 9264 r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP; 9269 9265 9270 else if( r_config_fsm.read() == CONFIG_TRT_LOCK ) 9266 else if( r_config_fsm.read() == CONFIG_TRT_LOCK ) 9271 9267 r_alloc_trt_fsm = ALLOC_TRT_CONFIG; 9272 9268 … … 9304 9300 r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP; 9305 9301 9306 else if( r_config_fsm.read() == CONFIG_TRT_LOCK ) 9302 else if( r_config_fsm.read() == CONFIG_TRT_LOCK ) 9307 9303 r_alloc_trt_fsm = ALLOC_TRT_CONFIG; 9308 9304 … … 9338 9334 r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP; 9339 9335 9340 else if( r_config_fsm.read() == CONFIG_TRT_LOCK ) 9336 else if( r_config_fsm.read() == CONFIG_TRT_LOCK ) 9341 9337 r_alloc_trt_fsm = ALLOC_TRT_CONFIG; 9342 9338 … … 9369 9365 r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP; 9370 9366 9371 else if( r_config_fsm.read() == CONFIG_TRT_LOCK ) 9367 else if( r_config_fsm.read() == CONFIG_TRT_LOCK ) 9372 9368 r_alloc_trt_fsm = ALLOC_TRT_CONFIG; 9373 9369 … … 9404 9400 (r_ixr_rsp_fsm.read() != IXR_RSP_TRT_READ)) 9405 9401 { 9406 if( r_config_fsm.read() == CONFIG_TRT_LOCK ) 9402 if( r_config_fsm.read() == CONFIG_TRT_LOCK ) 9407 9403 r_alloc_trt_fsm = ALLOC_TRT_CONFIG; 9408 9404 … … 9506 9502 r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP; 9507 9503 9508 else if( r_config_fsm.read() == CONFIG_TRT_LOCK ) 9504 else if( r_config_fsm.read() == CONFIG_TRT_LOCK ) 9509 9505 r_alloc_trt_fsm = ALLOC_TRT_CONFIG; 9510 9506 } … … 9698 9694 ///////////////////////////////////////////////////////////////////// 9699 9695 9700 m_cmd_read_addr_fifo.update( cmd_read_fifo_get, cmd_read_fifo_put, 9696 m_cmd_read_addr_fifo.update( cmd_read_fifo_get, cmd_read_fifo_put, 9701 9697 p_vci_tgt.address.read() ); 9702 m_cmd_read_length_fifo.update( cmd_read_fifo_get, cmd_read_fifo_put, 9698 m_cmd_read_length_fifo.update( cmd_read_fifo_get, cmd_read_fifo_put, 9703 9699 p_vci_tgt.plen.read()>>2 ); 9704 m_cmd_read_srcid_fifo.update( cmd_read_fifo_get, cmd_read_fifo_put, 9700 m_cmd_read_srcid_fifo.update( cmd_read_fifo_get, cmd_read_fifo_put, 9705 9701 p_vci_tgt.srcid.read() ); 9706 m_cmd_read_trdid_fifo.update( cmd_read_fifo_get, cmd_read_fifo_put, 9702 m_cmd_read_trdid_fifo.update( cmd_read_fifo_get, cmd_read_fifo_put, 9707 9703 p_vci_tgt.trdid.read() ); 9708 m_cmd_read_pktid_fifo.update( cmd_read_fifo_get, cmd_read_fifo_put, 9704 m_cmd_read_pktid_fifo.update( cmd_read_fifo_get, cmd_read_fifo_put, 9709 9705 p_vci_tgt.pktid.read() ); 9710 9706 … … 9773 9769 9774 9770 m_cc_receive_to_multi_ack_fifo.update( cc_receive_to_multi_ack_fifo_get, 9775 cc_receive_to_multi_ack_fifo_put, 9771 cc_receive_to_multi_ack_fifo_put, 9776 9772 p_dspin_p2m.data.read() ); 9777 9773 … … 9817 9813 // The three sources of (increment / decrement) are CONFIG / CLEANUP / IXR_RSP FSMs 9818 9814 //////////////////////////////////////////////////////////////////////////////////// 9819 if ( config_rsp_lines_incr and not 9815 if ( config_rsp_lines_incr and not 9820 9816 (config_rsp_lines_cleanup_decr or config_rsp_lines_ixr_rsp_decr) ) 9821 9817 { 9822 9818 r_config_rsp_lines = r_config_rsp_lines.read() + 1; 9823 9819 } 9824 if ( not config_rsp_lines_incr and 9820 if ( not config_rsp_lines_incr and 9825 9821 (config_rsp_lines_cleanup_decr or config_rsp_lines_ixr_rsp_decr) ) 9826 9822 { … … 9830 9826 //////////////////////////////////////////////////////////////////////////////////// 9831 9827 // Update min m_cpt_heap_min_slot_available. 9832 // The four sources of (increment / decrement) are READ / CLEANUP / XRAM_RSP / CONFIG FSMs 9828 // The four sources of (increment / decrement) are READ / CLEANUP / XRAM_RSP / CONFIG FSMs 9833 9829 //////////////////////////////////////////////////////////////////////////////////// 9834 9830 assert((m_cpt_heap_slot_available <= m_heap_size) and "m_cpt_heap_slot_available > m_heap_size"); … … 9868 9864 // DATA width is 8 bytes 9869 9865 // The following values are not transmitted to XRAM 9870 // p_vci_ixr.be 9871 // p_vci_ixr.pktid 9872 // p_vci_ixr.cons 9873 // p_vci_ixr.wrap 9874 // p_vci_ixr.contig 9875 // p_vci_ixr.clen 9876 // p_vci_ixr.cfixed 9866 // p_vci_ixr.be 9867 // p_vci_ixr.pktid 9868 // p_vci_ixr.cons 9869 // p_vci_ixr.wrap 9870 // p_vci_ixr.contig 9871 // p_vci_ixr.clen 9872 // p_vci_ixr.cfixed 9877 9873 9878 9874 p_vci_ixr.plen = 64; … … 9880 9876 p_vci_ixr.trdid = r_ixr_cmd_trdid.read(); 9881 9877 p_vci_ixr.address = (addr_t)r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2); 9882 p_vci_ixr.be = 0xFF; 9878 p_vci_ixr.be = 0xFF; 9883 9879 p_vci_ixr.pktid = 0; 9884 9880 p_vci_ixr.cons = false; … … 9916 9912 p_vci_ixr.cmdval = true; 9917 9913 p_vci_ixr.address = (addr_t)r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2); 9918 p_vci_ixr.wdata = ((wide_data_t)(r_ixr_cmd_wdata[r_ixr_cmd_word.read()].read()) | 9914 p_vci_ixr.wdata = ((wide_data_t)(r_ixr_cmd_wdata[r_ixr_cmd_word.read()].read()) | 9919 9915 ((wide_data_t)(r_ixr_cmd_wdata[r_ixr_cmd_word.read() + 1].read()) << 32)); 9920 9916 p_vci_ixr.trdid = r_cleanup_to_ixr_cmd_index.read(); … … 9933 9929 if( (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ) or 9934 9930 (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_ERASE) ) 9935 { 9931 { 9936 9932 p_vci_ixr.rspack = (r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP); 9937 9933 } … … 10109 10105 p_vci_tgt.rspval = true; 10110 10106 10111 if( is_ll and not r_tgt_rsp_key_sent.read() ) 10107 if( is_ll and not r_tgt_rsp_key_sent.read() ) 10112 10108 { 10113 10109 // LL response first flit 10114 10110 p_vci_tgt.rdata = r_xram_rsp_to_tgt_rsp_ll_key.read(); 10115 10111 } 10116 else 10112 else 10117 10113 { 10118 10114 // LL response second flit or READ response … … 10275 10271 m_broadcast_boundaries, 10276 10272 DspinRwtParam::BROADCAST_BOX); 10277 10273 10278 10274 DspinRwtParam::dspin_set( flit, 10279 10275 1,
Note: See TracChangeset
for help on using the changeset viewer.