Changeset 823 for branches/RWT/modules
- Timestamp:
- Sep 30, 2014, 3:32:13 PM (10 years ago)
- Location:
- branches/RWT/modules/vci_mem_cache/caba/source
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/RWT/modules/vci_mem_cache/caba/source/include/mem_cache_directory.h
r814 r823 18 18 class LruEntry { 19 19 20 public: 21 22 bool recent; 23 20 public: 21 22 bool recent; 23 24 void init() 25 { 26 recent=false; 27 } 28 29 }; // end class LruEntry 30 31 //////////////////////////////////////////////////////////////////////// 32 // An Owner 33 //////////////////////////////////////////////////////////////////////// 34 class Owner{ 35 36 public: 37 38 // Fields 39 bool inst; // Is the owner an ICache ? 40 size_t srcid; // The SRCID of the owner 41 42 //////////////////////// 43 // Constructors 44 //////////////////////// 45 Owner(bool i_inst, 46 size_t i_srcid) 47 { 48 inst = i_inst; 49 srcid = i_srcid; 50 } 51 52 Owner(const Owner &a) 53 { 54 inst = a.inst; 55 srcid = a.srcid; 56 } 57 58 Owner() 59 { 60 inst = false; 61 srcid = 0; 62 } 63 // end constructors 64 65 }; // end class Owner 66 67 68 //////////////////////////////////////////////////////////////////////// 69 // A directory entry 70 //////////////////////////////////////////////////////////////////////// 71 class DirectoryEntry { 72 73 typedef uint32_t tag_t; 74 75 public: 76 77 bool valid; // entry valid 78 bool cache_coherent; // WB or WT policy 79 bool is_cnt; // directory entry is in counter mode 80 bool dirty; // entry dirty 81 bool lock; // entry locked 82 tag_t tag; // tag of the entry 83 size_t count; // number of copies 84 Owner owner; // an owner of the line 85 size_t ptr; // pointer to the next owner 86 87 DirectoryEntry() 88 { 89 valid = false; 90 cache_coherent = false; 91 is_cnt = false; 92 dirty = false; 93 lock = false; 94 tag = 0; 95 count = 0; 96 owner.inst = 0; 97 owner.srcid = 0; 98 ptr = 0; 99 } 100 101 DirectoryEntry(const DirectoryEntry &source) 102 { 103 valid = source.valid; 104 cache_coherent = source.cache_coherent; 105 is_cnt = source.is_cnt; 106 dirty = source.dirty; 107 lock = source.lock; 108 tag = source.tag; 109 count = source.count; 110 owner = source.owner; 111 ptr = source.ptr; 112 } 113 114 ///////////////////////////////////////////////////////////////////// 115 // The init() function initializes the entry 116 ///////////////////////////////////////////////////////////////////// 24 117 void init() 25 118 { 26 recent=false; 119 valid = false; 120 cache_coherent = false; 121 is_cnt = false; 122 dirty = false; 123 lock = false; 124 count = 0; 27 125 } 28 126 29 }; // end class LruEntry 30 31 //////////////////////////////////////////////////////////////////////// 32 // An Owner 33 //////////////////////////////////////////////////////////////////////// 34 class Owner{ 35 36 public: 37 // Fields 38 bool inst; // Is the owner an ICache ? 39 size_t srcid; // The SRCID of the owner 40 41 //////////////////////// 42 // Constructors 43 //////////////////////// 44 Owner(bool i_inst, 45 size_t i_srcid) 46 { 47 inst = i_inst; 48 srcid = i_srcid; 127 ///////////////////////////////////////////////////////////////////// 128 // The copy() function copies an existing source entry to a target 129 ///////////////////////////////////////////////////////////////////// 130 void copy(const DirectoryEntry &source) 131 { 132 valid = source.valid; 133 cache_coherent = source.cache_coherent; 134 is_cnt = source.is_cnt; 135 dirty = source.dirty; 136 lock = source.lock; 137 tag = source.tag; 138 count = source.count; 139 owner = source.owner; 140 ptr = source.ptr; 49 141 } 50 142 51 Owner(const Owner &a) 52 { 53 inst = a.inst; 54 srcid = a.srcid; 143 //////////////////////////////////////////////////////////////////// 144 // The print() function prints the entry 145 //////////////////////////////////////////////////////////////////// 146 void print() 147 { 148 std::cout << "Valid = " << valid 149 << " ; COHERENCE = " << cache_coherent 150 << " ; IS COUNT = " << is_cnt 151 << " ; Dirty = " << dirty 152 << " ; Lock = " << lock 153 << " ; Tag = " << std::hex << tag << std::dec 154 << " ; Count = " << count 155 << " ; Owner = " << owner.srcid 156 << " " << owner.inst 157 << " ; Pointer = " << ptr << std::endl; 55 158 } 56 159 57 Owner() 58 { 59 inst = false; 60 srcid = 0; 160 }; // end class DirectoryEntry 161 162 //////////////////////////////////////////////////////////////////////// 163 // The directory 164 //////////////////////////////////////////////////////////////////////// 165 class CacheDirectory { 166 167 typedef sc_dt::sc_uint<40> addr_t; 168 typedef uint32_t data_t; 169 typedef uint32_t tag_t; 170 171 private: 172 173 // Directory constants 174 size_t m_ways; 175 size_t m_sets; 176 size_t m_words; 177 size_t m_width; 178 uint32_t lfsr; 179 180 // the directory & lru tables 181 DirectoryEntry **m_dir_tab; 182 LruEntry **m_lru_tab; 183 184 public: 185 186 //////////////////////// 187 // Constructor 188 //////////////////////// 189 CacheDirectory(size_t ways, size_t sets, size_t words, size_t address_width) 190 { 191 m_ways = ways; 192 m_sets = sets; 193 m_words = words; 194 m_width = address_width; 195 lfsr = -1; 196 197 m_dir_tab = new DirectoryEntry*[sets]; 198 for (size_t i = 0; i < sets; i++) { 199 m_dir_tab[i] = new DirectoryEntry[ways]; 200 for (size_t j = 0; j < ways; j++) { 201 m_dir_tab[i][j].init(); 202 } 203 } 204 205 m_lru_tab = new LruEntry*[sets]; 206 for (size_t i = 0; i < sets; i++) { 207 m_lru_tab[i] = new LruEntry[ways]; 208 for (size_t j = 0; j < ways; j++) { 209 m_lru_tab[i][j].init(); 210 } 211 } 212 } // end constructor 213 214 ///////////////// 215 // Destructor 216 ///////////////// 217 ~CacheDirectory() 218 { 219 for (size_t i = 0; i < m_sets; i++) { 220 delete [] m_dir_tab[i]; 221 delete [] m_lru_tab[i]; 222 } 223 delete [] m_dir_tab; 224 delete [] m_lru_tab; 225 } // end destructor 226 227 ///////////////////////////////////////////////////////////////////// 228 // The read() function reads a directory entry. In case of hit, the 229 // LRU is updated. 230 // Arguments : 231 // - address : the address of the entry 232 // - way : (return argument) the way of the entry in case of hit 233 // The function returns a copy of a (valid or invalid) entry 234 ///////////////////////////////////////////////////////////////////// 235 DirectoryEntry read(const addr_t &address, size_t &way) 236 { 237 238 #define L2 soclib::common::uint32_log2 239 const size_t set = (size_t) (address >> (L2(m_words) + 2)) & (m_sets - 1); 240 const tag_t tag = (tag_t) (address >> (L2(m_sets) + L2(m_words) + 2)); 241 #undef L2 242 243 bool hit = false; 244 245 for (size_t i = 0; i < m_ways; i++) { 246 bool equal = (m_dir_tab[set][i].tag == tag); 247 bool valid = m_dir_tab[set][i].valid; 248 hit = equal && valid; 249 if (hit) { 250 way = i; 251 break; 252 } 253 } 254 if (hit) { 255 m_lru_tab[set][way].recent = true; 256 return DirectoryEntry(m_dir_tab[set][way]); 257 } else { 258 return DirectoryEntry(); 259 } 260 } // end read() 261 262 ///////////////////////////////////////////////////////////////////// 263 // The inval function invalidate an entry defined by the set and 264 // way arguments. 265 ///////////////////////////////////////////////////////////////////// 266 void inval( const size_t &way, const size_t &set ) 267 { 268 m_dir_tab[set][way].init(); 61 269 } 62 // end constructors 63 64 }; // end class Owner 65 66 67 //////////////////////////////////////////////////////////////////////// 68 // A directory entry 69 //////////////////////////////////////////////////////////////////////// 70 class DirectoryEntry { 71 72 typedef uint32_t tag_t; 73 74 public: 75 76 bool valid; // entry valid 77 bool cache_coherent; // WB or WT policy 78 bool is_cnt; // directory entry is in counter mode 79 bool dirty; // entry dirty 80 bool lock; // entry locked 81 tag_t tag; // tag of the entry 82 size_t count; // number of copies 83 Owner owner; // an owner of the line 84 size_t ptr; // pointer to the next owner 85 86 DirectoryEntry() 87 { 88 valid = false; 89 cache_coherent= false; 90 is_cnt = false; 91 dirty = false; 92 lock = false; 93 tag = 0; 94 count = 0; 95 owner.inst = 0; 96 owner.srcid = 0; 97 ptr = 0; 98 } 99 100 DirectoryEntry(const DirectoryEntry &source) 101 { 102 valid = source.valid; 103 cache_coherent= source.cache_coherent; 104 is_cnt = source.is_cnt; 105 dirty = source.dirty; 106 lock = source.lock; 107 tag = source.tag; 108 count = source.count; 109 owner = source.owner; 110 ptr = source.ptr; 111 } 112 113 ///////////////////////////////////////////////////////////////////// 114 // The init() function initializes the entry 115 ///////////////////////////////////////////////////////////////////// 116 void init() 117 { 118 valid = false; 119 cache_coherent = false; 120 is_cnt = false; 121 dirty = false; 122 lock = false; 123 count = 0; 124 } 125 126 ///////////////////////////////////////////////////////////////////// 127 // The copy() function copies an existing source entry to a target 128 ///////////////////////////////////////////////////////////////////// 129 void copy(const DirectoryEntry &source) 130 { 131 valid = source.valid; 132 cache_coherent = source.cache_coherent; 133 is_cnt = source.is_cnt; 134 dirty = source.dirty; 135 lock = source.lock; 136 tag = source.tag; 137 count = source.count; 138 owner = source.owner; 139 ptr = source.ptr; 140 } 141 142 //////////////////////////////////////////////////////////////////// 143 // The print() function prints the entry 144 //////////////////////////////////////////////////////////////////// 145 void print() 146 { 147 std::cout << "Valid = " << valid 148 << " ; COHERENCE = " << cache_coherent 149 << " ; IS COUNT = " << is_cnt 150 << " ; Dirty = " << dirty 151 << " ; Lock = " << lock 152 << " ; Tag = " << std::hex << tag << std::dec 153 << " ; Count = " << count 154 << " ; Owner = " << owner.srcid 155 << " " << owner.inst 156 << " ; Pointer = " << ptr << std::endl; 157 } 158 159 }; // end class DirectoryEntry 160 161 //////////////////////////////////////////////////////////////////////// 162 // The directory 163 //////////////////////////////////////////////////////////////////////// 164 class CacheDirectory { 165 166 typedef sc_dt::sc_uint<40> addr_t; 167 typedef uint32_t data_t; 168 typedef uint32_t tag_t; 169 170 private: 171 172 // Directory constants 173 size_t m_ways; 174 size_t m_sets; 175 size_t m_words; 176 size_t m_width; 177 uint32_t lfsr; 178 179 // the directory & lru tables 180 DirectoryEntry **m_dir_tab; 181 LruEntry **m_lru_tab; 182 183 public: 184 185 //////////////////////// 186 // Constructor 187 //////////////////////// 188 CacheDirectory( size_t ways, size_t sets, size_t words, size_t address_width) 189 { 190 m_ways = ways; 191 m_sets = sets; 192 m_words = words; 193 m_width = address_width; 194 lfsr = -1; 195 196 m_dir_tab = new DirectoryEntry*[sets]; 197 for ( size_t i=0; i<sets; i++ ) { 198 m_dir_tab[i] = new DirectoryEntry[ways]; 199 for ( size_t j=0 ; j<ways ; j++) m_dir_tab[i][j].init(); 200 } 201 m_lru_tab = new LruEntry*[sets]; 202 for ( size_t i=0; i<sets; i++ ) { 203 m_lru_tab[i] = new LruEntry[ways]; 204 for ( size_t j=0 ; j<ways ; j++) m_lru_tab[i][j].init(); 205 } 206 } // end constructor 207 208 ///////////////// 209 // Destructor 210 ///////////////// 211 ~CacheDirectory() 212 { 213 for(size_t i=0 ; i<m_sets ; i++){ 214 delete [] m_dir_tab[i]; 215 delete [] m_lru_tab[i]; 216 } 217 delete [] m_dir_tab; 218 delete [] m_lru_tab; 219 } // end destructor 220 221 ///////////////////////////////////////////////////////////////////// 222 // The read() function reads a directory entry. In case of hit, the 223 // LRU is updated. 224 // Arguments : 225 // - address : the address of the entry 226 // - way : (return argument) the way of the entry in case of hit 227 // The function returns a copy of a (valid or invalid) entry 228 ///////////////////////////////////////////////////////////////////// 229 DirectoryEntry read(const addr_t &address, size_t &way) 230 { 270 271 ///////////////////////////////////////////////////////////////////// 272 // The read_neutral() function reads a directory entry, without 273 // changing the LRU 274 // Arguments : 275 // - address : the address of the entry 276 // The function returns a copy of a (valid or invalid) entry 277 ///////////////////////////////////////////////////////////////////// 278 DirectoryEntry read_neutral(const addr_t &address, 279 size_t* ret_way, 280 size_t* ret_set) 281 { 231 282 232 283 #define L2 soclib::common::uint32_log2 233 constsize_t set = (size_t)(address >> (L2(m_words) + 2)) & (m_sets - 1);234 consttag_t tag = (tag_t)(address >> (L2(m_sets) + L2(m_words) + 2));284 size_t set = (size_t)(address >> (L2(m_words) + 2)) & (m_sets - 1); 285 tag_t tag = (tag_t)(address >> (L2(m_sets) + L2(m_words) + 2)); 235 286 #undef L2 236 287 237 bool hit = false; 238 for ( size_t i=0 ; i<m_ways ; i++ ) { 239 bool equal = ( m_dir_tab[set][i].tag == tag ); 240 bool valid = m_dir_tab[set][i].valid; 241 hit = equal && valid; 242 if ( hit ) { 243 way = i; 244 break; 245 } 246 } 247 if ( hit ) { 248 m_lru_tab[set][way].recent = true; 249 return DirectoryEntry(m_dir_tab[set][way]); 250 } else { 251 return DirectoryEntry(); 252 } 253 } // end read() 254 255 ///////////////////////////////////////////////////////////////////// 256 // The inval function invalidate an entry defined by the set and 257 // way arguments. 258 ///////////////////////////////////////////////////////////////////// 259 void inval( const size_t &way, const size_t &set ) 260 { 261 m_dir_tab[set][way].init(); 262 } 263 264 ///////////////////////////////////////////////////////////////////// 265 // The read_neutral() function reads a directory entry, without 266 // changing the LRU 267 // Arguments : 268 // - address : the address of the entry 269 // The function returns a copy of a (valid or invalid) entry 270 ///////////////////////////////////////////////////////////////////// 271 DirectoryEntry read_neutral( const addr_t &address, 272 size_t* ret_way, 273 size_t* ret_set ) 274 { 275 276 #define L2 soclib::common::uint32_log2 277 size_t set = (size_t)(address >> (L2(m_words) + 2)) & (m_sets - 1); 278 tag_t tag = (tag_t)(address >> (L2(m_sets) + L2(m_words) + 2)); 279 #undef L2 280 281 for ( size_t way = 0 ; way < m_ways ; way++ ) 282 { 283 bool equal = ( m_dir_tab[set][way].tag == tag ); 284 bool valid = m_dir_tab[set][way].valid; 285 if ( equal and valid ) 286 { 287 *ret_set = set; 288 *ret_way = way; 289 return DirectoryEntry(m_dir_tab[set][way]); 290 } 291 } 292 return DirectoryEntry(); 293 } // end read_neutral() 294 295 ///////////////////////////////////////////////////////////////////// 296 // The write function writes a new entry, 297 // and updates the LRU bits if necessary. 298 // Arguments : 299 // - set : the set of the entry 300 // - way : the way of the entry 301 // - entry : the entry value 302 ///////////////////////////////////////////////////////////////////// 303 void write( const size_t &set, 304 const size_t &way, 305 const DirectoryEntry &entry) 306 { 307 assert( (set<m_sets) 308 && "Cache Directory write : The set index is invalid"); 309 assert( (way<m_ways) 310 && "Cache Directory write : The way index is invalid"); 311 312 // update Directory 313 m_dir_tab[set][way].copy(entry); 314 315 // update LRU bits 316 bool all_recent = true; 317 for ( size_t i=0 ; i<m_ways ; i++ ) 318 { 319 if ( i != way ) all_recent = m_lru_tab[set][i].recent && all_recent; 320 } 321 if ( all_recent ) 322 { 323 for( size_t i=0 ; i<m_ways ; i++ ) m_lru_tab[set][i].recent = false; 324 } 325 else 326 { 327 m_lru_tab[set][way].recent = true; 328 } 329 } // end write() 330 331 ///////////////////////////////////////////////////////////////////// 332 // The print() function prints a selected directory entry 333 // Arguments : 334 // - set : the set of the entry to print 335 // - way : the way of the entry to print 336 ///////////////////////////////////////////////////////////////////// 337 void print(const size_t &set, const size_t &way) 338 { 339 std::cout << std::dec << " set : " << set << " ; way : " << way << " ; " ; 340 m_dir_tab[set][way].print(); 341 } // end print() 342 343 ///////////////////////////////////////////////////////////////////// 344 // The select() function selects a directory entry to evince. 345 // Arguments : 346 // - set : (input argument) the set to modify 347 // - way : (return argument) the way to evince 348 ///////////////////////////////////////////////////////////////////// 349 DirectoryEntry select(const size_t &set, size_t &way) 350 { 351 assert( (set < m_sets) 352 && "Cache Directory : (select) The set index is invalid"); 353 354 // looking for an empty slot 355 for(size_t i=0; i<m_ways; i++) 356 { 357 if( not m_dir_tab[set][i].valid ) 358 { 359 way=i; 360 return DirectoryEntry(m_dir_tab[set][way]); 361 } 362 } 288 for (size_t way = 0; way < m_ways; way++) 289 { 290 bool equal = (m_dir_tab[set][way].tag == tag); 291 bool valid = m_dir_tab[set][way].valid; 292 if (equal and valid) 293 { 294 *ret_set = set; 295 *ret_way = way; 296 return DirectoryEntry(m_dir_tab[set][way]); 297 } 298 } 299 return DirectoryEntry(); 300 } // end read_neutral() 301 302 ///////////////////////////////////////////////////////////////////// 303 // The write function writes a new entry, 304 // and updates the LRU bits if necessary. 305 // Arguments : 306 // - set : the set of the entry 307 // - way : the way of the entry 308 // - entry : the entry value 309 ///////////////////////////////////////////////////////////////////// 310 void write(const size_t &set, 311 const size_t &way, 312 const DirectoryEntry &entry) 313 { 314 assert((set<m_sets) 315 && "Cache Directory write : The set index is invalid"); 316 assert((way<m_ways) 317 && "Cache Directory write : The way index is invalid"); 318 319 // update Directory 320 m_dir_tab[set][way].copy(entry); 321 322 // update LRU bits 323 bool all_recent = true; 324 for (size_t i = 0; i < m_ways; i++) 325 { 326 if (i != way) 327 { 328 all_recent = m_lru_tab[set][i].recent && all_recent; 329 } 330 } 331 if (all_recent) 332 { 333 for (size_t i = 0; i < m_ways; i++) 334 { 335 m_lru_tab[set][i].recent = false; 336 } 337 } 338 else 339 { 340 m_lru_tab[set][way].recent = true; 341 } 342 } // end write() 343 344 ///////////////////////////////////////////////////////////////////// 345 // The print() function prints a selected directory entry 346 // Arguments : 347 // - set : the set of the entry to print 348 // - way : the way of the entry to print 349 ///////////////////////////////////////////////////////////////////// 350 void print(const size_t &set, const size_t &way) 351 { 352 std::cout << std::dec << " set : " << set << " ; way : " << way << " ; "; 353 m_dir_tab[set][way].print(); 354 } // end print() 355 356 ///////////////////////////////////////////////////////////////////// 357 // The select() function selects a directory entry to evince. 358 // Arguments : 359 // - set : (input argument) the set to modify 360 // - way : (return argument) the way to evince 361 ///////////////////////////////////////////////////////////////////// 362 DirectoryEntry select(const size_t &set, size_t &way) 363 { 364 assert((set < m_sets) 365 && "Cache Directory : (select) The set index is invalid"); 366 367 // looking for an empty slot 368 for (size_t i = 0; i < m_ways; i++) 369 { 370 if (not m_dir_tab[set][i].valid) 371 { 372 way = i; 373 return DirectoryEntry(m_dir_tab[set][way]); 374 } 375 } 363 376 364 377 #ifdef RANDOM_EVICTION 365 lfsr = (lfsr >> 1) ^ ((-(lfsr & 1)) & 0xd0000001);366 way = lfsr % m_ways;367 return DirectoryEntry(m_dir_tab[set][way]);378 lfsr = (lfsr >> 1) ^ ((-(lfsr & 1)) & 0xd0000001); 379 way = lfsr % m_ways; 380 return DirectoryEntry(m_dir_tab[set][way]); 368 381 #endif 369 382 370 // looking for a not locked and not recently used entry371 for(size_t i=0; i<m_ways; i++)372 {373 if((not m_lru_tab[set][i].recent) && (not m_dir_tab[set][i].lock))374 {375 way=i;376 return DirectoryEntry(m_dir_tab[set][way]);377 }378 }379 380 // looking for a locked not recently used entry381 for(size_t i=0; i<m_ways; i++)382 {383 if( (not m_lru_tab[set][i].recent) &&(m_dir_tab[set][i].lock))384 {385 way=i;386 return DirectoryEntry(m_dir_tab[set][way]);387 }388 }389 390 // looking for a recently used entry not locked391 for(size_t i=0; i<m_ways; i++)392 {393 if( (m_lru_tab[set][i].recent) &&(not m_dir_tab[set][i].lock))394 {395 way=i;396 return DirectoryEntry(m_dir_tab[set][way]);397 }398 }399 400 // select way 0 (even if entry is locked and recently used)401 way = 0;402 return DirectoryEntry(m_dir_tab[set][0]);403 } // end select()404 405 /////////////////////////////////////////////////////////////////////406 // Global initialisation function407 /////////////////////////////////////////////////////////////////////408 void init()409 {410 for ( size_t set=0 ; set<m_sets ; set++)411 {412 for ( size_t way=0 ; way<m_ways ; way++)413 {414 m_dir_tab[set][way].init();415 m_lru_tab[set][way].init();416 }417 }418 } // end init()383 // looking for a not locked and not recently used entry 384 for (size_t i = 0; i < m_ways; i++) 385 { 386 if ((not m_lru_tab[set][i].recent) and (not m_dir_tab[set][i].lock)) 387 { 388 way = i; 389 return DirectoryEntry(m_dir_tab[set][way]); 390 } 391 } 392 393 // looking for a locked not recently used entry 394 for (size_t i = 0; i < m_ways; i++) 395 { 396 if ((not m_lru_tab[set][i].recent) and (m_dir_tab[set][i].lock)) 397 { 398 way = i; 399 return DirectoryEntry(m_dir_tab[set][way]); 400 } 401 } 402 403 // looking for a recently used entry not locked 404 for (size_t i = 0; i < m_ways; i++) 405 { 406 if ((m_lru_tab[set][i].recent) and (not m_dir_tab[set][i].lock)) 407 { 408 way = i; 409 return DirectoryEntry(m_dir_tab[set][way]); 410 } 411 } 412 413 // select way 0 (even if entry is locked and recently used) 414 way = 0; 415 return DirectoryEntry(m_dir_tab[set][0]); 416 } // end select() 417 418 ///////////////////////////////////////////////////////////////////// 419 // Global initialisation function 420 ///////////////////////////////////////////////////////////////////// 421 void init() 422 { 423 for (size_t set = 0; set < m_sets; set++) 424 { 425 for (size_t way = 0; way < m_ways; way++) 426 { 427 m_dir_tab[set][way].init(); 428 m_lru_tab[set][way].init(); 429 } 430 } 431 } // end init() 419 432 420 433 }; // end class CacheDirectory … … 425 438 class HeapEntry{ 426 439 427 public: 428 // Fields of the entry 429 Owner owner; 430 size_t next; 431 432 //////////////////////// 433 // Constructor 434 //////////////////////// 435 HeapEntry() 436 :owner(false,0) 437 { 438 next = 0; 439 } // end constructor 440 441 //////////////////////// 442 // Constructor 443 //////////////////////// 444 HeapEntry(const HeapEntry &entry) 445 { 446 owner.inst = entry.owner.inst; 447 owner.srcid = entry.owner.srcid; 448 next = entry.next; 449 } // end constructor 450 451 ///////////////////////////////////////////////////////////////////// 452 // The copy() function copies an existing source entry to a target 453 ///////////////////////////////////////////////////////////////////// 454 void copy(const HeapEntry &entry) 455 { 456 owner.inst = entry.owner.inst; 457 owner.srcid = entry.owner.srcid; 458 next = entry.next; 459 } // end copy() 460 461 //////////////////////////////////////////////////////////////////// 462 // The print() function prints the entry 463 //////////////////////////////////////////////////////////////////// 464 void print(){ 465 std::cout 466 << " -- owner.inst : " << std::dec << owner.inst << std::endl 467 << " -- owner.srcid : " << std::dec << owner.srcid << std::endl 468 << " -- next : " << std::dec << next << std::endl; 469 470 } // end print() 440 public: 441 // Fields of the entry 442 Owner owner; 443 size_t next; 444 445 //////////////////////// 446 // Constructor 447 //////////////////////// 448 HeapEntry() 449 :owner(false, 0) 450 { 451 next = 0; 452 } // end constructor 453 454 //////////////////////// 455 // Constructor 456 //////////////////////// 457 HeapEntry(const HeapEntry &entry) 458 { 459 owner.inst = entry.owner.inst; 460 owner.srcid = entry.owner.srcid; 461 next = entry.next; 462 } // end constructor 463 464 ///////////////////////////////////////////////////////////////////// 465 // The copy() function copies an existing source entry to a target 466 ///////////////////////////////////////////////////////////////////// 467 void copy(const HeapEntry &entry) 468 { 469 owner.inst = entry.owner.inst; 470 owner.srcid = entry.owner.srcid; 471 next = entry.next; 472 } // end copy() 473 474 //////////////////////////////////////////////////////////////////// 475 // The print() function prints the entry 476 //////////////////////////////////////////////////////////////////// 477 void print() 478 { 479 std::cout 480 << " -- owner.inst : " << std::dec << owner.inst << std::endl 481 << " -- owner.srcid : " << std::dec << owner.srcid << std::endl 482 << " -- next : " << std::dec << next << std::endl; 483 484 } // end print() 471 485 472 486 }; // end class HeapEntry … … 477 491 class HeapDirectory{ 478 492 479 private: 480 // Registers and the heap 481 size_t ptr_free; 482 bool full; 483 HeapEntry *m_heap_tab; 484 485 // Constants for debugging purpose 486 size_t tab_size; 487 488 public: 489 //////////////////////// 490 // Constructor 491 //////////////////////// 492 HeapDirectory(uint32_t size){ 493 assert(size>0 && "Memory Cache, HeapDirectory constructor : invalid size"); 494 ptr_free = 0; 495 full = false; 496 m_heap_tab = new HeapEntry[size]; 497 tab_size = size; 498 } // end constructor 499 500 ///////////////// 501 // Destructor 502 ///////////////// 503 ~HeapDirectory(){ 504 delete [] m_heap_tab; 505 } // end destructor 506 507 ///////////////////////////////////////////////////////////////////// 508 // Global initialisation function 509 ///////////////////////////////////////////////////////////////////// 510 void init(){ 511 ptr_free=0; 512 full=false; 513 for(size_t i=0; i< tab_size-1;i++){ 514 m_heap_tab[i].next = i+1; 515 } 516 m_heap_tab[tab_size-1].next = tab_size-1; 517 return; 518 } 519 520 ///////////////////////////////////////////////////////////////////// 521 // The print() function prints a selected directory entry 522 // Arguments : 523 // - ptr : the pointer to the entry to print 524 ///////////////////////////////////////////////////////////////////// 525 void print(const size_t &ptr){ 526 std::cout << "Heap, printing the entry : " << std::dec << ptr << std::endl; 527 m_heap_tab[ptr].print(); 528 } // end print() 529 530 ///////////////////////////////////////////////////////////////////// 531 // The print_list() function prints a list from selected directory entry 532 // Arguments : 533 // - ptr : the pointer to the first entry to print 534 ///////////////////////////////////////////////////////////////////// 535 void print_list(const size_t &ptr){ 536 bool end = false; 537 size_t ptr_temp = ptr; 538 std::cout << "Heap, printing the list from : " << std::dec << ptr << std::endl; 539 while(!end){ 540 m_heap_tab[ptr_temp].print(); 541 if(ptr_temp == m_heap_tab[ptr_temp].next) end = true; 542 ptr_temp = m_heap_tab[ptr_temp].next; 543 } 544 } // end print_list() 545 546 ///////////////////////////////////////////////////////////////////// 547 // The is_full() function return true if the heap is full. 548 ///////////////////////////////////////////////////////////////////// 549 bool is_full(){ 550 return full; 551 } // end is_full() 552 553 ///////////////////////////////////////////////////////////////////// 554 // The next_free_ptr() function returns the pointer 555 // to the next free entry. 556 ///////////////////////////////////////////////////////////////////// 557 size_t next_free_ptr(){ 558 return ptr_free; 559 } // end next_free_ptr() 560 561 ///////////////////////////////////////////////////////////////////// 562 // The next_free_entry() function returns 563 // a copy of the next free entry. 564 ///////////////////////////////////////////////////////////////////// 565 HeapEntry next_free_entry(){ 566 return HeapEntry(m_heap_tab[ptr_free]); 567 } // end next_free_entry() 568 569 ///////////////////////////////////////////////////////////////////// 570 // The write_free_entry() function modify the next free entry. 571 // Arguments : 572 // - entry : the entry to write 573 ///////////////////////////////////////////////////////////////////// 574 void write_free_entry(const HeapEntry &entry){ 575 m_heap_tab[ptr_free].copy(entry); 576 } // end write_free_entry() 577 578 ///////////////////////////////////////////////////////////////////// 579 // The write_free_ptr() function writes the pointer 580 // to the next free entry 581 ///////////////////////////////////////////////////////////////////// 582 void write_free_ptr(const size_t &ptr){ 583 assert( (ptr<tab_size) && "HeapDirectory error : try to write a wrong free pointer"); 584 ptr_free = ptr; 585 } // end write_free_ptr() 586 587 ///////////////////////////////////////////////////////////////////// 588 // The set_full() function sets the full bit (to true). 589 ///////////////////////////////////////////////////////////////////// 590 void set_full(){ 591 full = true; 592 } // end set_full() 593 594 ///////////////////////////////////////////////////////////////////// 595 // The unset_full() function unsets the full bit (to false). 596 ///////////////////////////////////////////////////////////////////// 597 void unset_full(){ 598 full = false; 599 } // end unset_full() 600 601 ///////////////////////////////////////////////////////////////////// 602 // The read() function returns a copy of 603 // the entry pointed by the argument 604 // Arguments : 605 // - ptr : the pointer to the entry to read 606 ///////////////////////////////////////////////////////////////////// 607 HeapEntry read(const size_t &ptr){ 608 assert( (ptr<tab_size) && "HeapDirectory error : try to write a wrong free pointer"); 609 return HeapEntry(m_heap_tab[ptr]); 610 } // end read() 611 612 ///////////////////////////////////////////////////////////////////// 613 // The write() function writes an entry in the heap 614 // Arguments : 615 // - ptr : the pointer to the entry to replace 616 // - entry : the entry to write 617 ///////////////////////////////////////////////////////////////////// 618 void write(const size_t &ptr, const HeapEntry &entry){ 619 assert( (ptr<tab_size) && "HeapDirectory error : try to write a wrong free pointer"); 620 m_heap_tab[ptr].copy(entry); 621 } // end write() 493 private: 494 // Registers and the heap 495 size_t ptr_free; 496 bool full; 497 HeapEntry *m_heap_tab; 498 499 // Constants for debugging purpose 500 size_t tab_size; 501 502 public: 503 //////////////////////// 504 // Constructor 505 //////////////////////// 506 HeapDirectory(uint32_t size) 507 { 508 assert(size > 0 && "Memory Cache, HeapDirectory constructor : invalid size"); 509 ptr_free = 0; 510 full = false; 511 m_heap_tab = new HeapEntry[size]; 512 tab_size = size; 513 } // end constructor 514 515 ///////////////// 516 // Destructor 517 ///////////////// 518 ~HeapDirectory() 519 { 520 delete [] m_heap_tab; 521 } // end destructor 522 523 ///////////////////////////////////////////////////////////////////// 524 // Global initialisation function 525 ///////////////////////////////////////////////////////////////////// 526 void init() 527 { 528 ptr_free = 0; 529 full = false; 530 for (size_t i = 0; i < tab_size - 1; i++) { 531 m_heap_tab[i].next = i + 1; 532 } 533 m_heap_tab[tab_size - 1].next = tab_size - 1; 534 return; 535 } 536 537 ///////////////////////////////////////////////////////////////////// 538 // The print() function prints a selected directory entry 539 // Arguments : 540 // - ptr : the pointer to the entry to print 541 ///////////////////////////////////////////////////////////////////// 542 void print(const size_t &ptr) 543 { 544 std::cout << "Heap, printing the entry : " << std::dec << ptr << std::endl; 545 m_heap_tab[ptr].print(); 546 } // end print() 547 548 ///////////////////////////////////////////////////////////////////// 549 // The print_list() function prints a list from selected directory entry 550 // Arguments : 551 // - ptr : the pointer to the first entry to print 552 ///////////////////////////////////////////////////////////////////// 553 void print_list(const size_t &ptr) 554 { 555 bool end = false; 556 size_t ptr_temp = ptr; 557 std::cout << "Heap, printing the list from : " << std::dec << ptr << std::endl; 558 while (!end) { 559 m_heap_tab[ptr_temp].print(); 560 if (ptr_temp == m_heap_tab[ptr_temp].next) { 561 end = true; 562 } 563 ptr_temp = m_heap_tab[ptr_temp].next; 564 } 565 } // end print_list() 566 567 ///////////////////////////////////////////////////////////////////// 568 // The is_full() function return true if the heap is full. 569 ///////////////////////////////////////////////////////////////////// 570 bool is_full() 571 { 572 return full; 573 } // end is_full() 574 575 ///////////////////////////////////////////////////////////////////// 576 // The next_free_ptr() function returns the pointer 577 // to the next free entry. 578 ///////////////////////////////////////////////////////////////////// 579 size_t next_free_ptr() 580 { 581 return ptr_free; 582 } // end next_free_ptr() 583 584 ///////////////////////////////////////////////////////////////////// 585 // The next_free_entry() function returns 586 // a copy of the next free entry. 587 ///////////////////////////////////////////////////////////////////// 588 HeapEntry next_free_entry() 589 { 590 return HeapEntry(m_heap_tab[ptr_free]); 591 } // end next_free_entry() 592 593 ///////////////////////////////////////////////////////////////////// 594 // The write_free_entry() function modify the next free entry. 595 // Arguments : 596 // - entry : the entry to write 597 ///////////////////////////////////////////////////////////////////// 598 void write_free_entry(const HeapEntry &entry) 599 { 600 m_heap_tab[ptr_free].copy(entry); 601 } // end write_free_entry() 602 603 ///////////////////////////////////////////////////////////////////// 604 // The write_free_ptr() function writes the pointer 605 // to the next free entry 606 ///////////////////////////////////////////////////////////////////// 607 void write_free_ptr(const size_t &ptr) 608 { 609 assert((ptr < tab_size) && "HeapDirectory error : try to write a wrong free pointer"); 610 ptr_free = ptr; 611 } // end write_free_ptr() 612 613 ///////////////////////////////////////////////////////////////////// 614 // The set_full() function sets the full bit (to true). 615 ///////////////////////////////////////////////////////////////////// 616 void set_full() 617 { 618 full = true; 619 } // end set_full() 620 621 ///////////////////////////////////////////////////////////////////// 622 // The unset_full() function unsets the full bit (to false). 623 ///////////////////////////////////////////////////////////////////// 624 void unset_full() 625 { 626 full = false; 627 } // end unset_full() 628 629 ///////////////////////////////////////////////////////////////////// 630 // The read() function returns a copy of 631 // the entry pointed by the argument 632 // Arguments : 633 // - ptr : the pointer to the entry to read 634 ///////////////////////////////////////////////////////////////////// 635 HeapEntry read(const size_t &ptr) 636 { 637 assert((ptr < tab_size) && "HeapDirectory error : try to write a wrong free pointer"); 638 return HeapEntry(m_heap_tab[ptr]); 639 } // end read() 640 641 ///////////////////////////////////////////////////////////////////// 642 // The write() function writes an entry in the heap 643 // Arguments : 644 // - ptr : the pointer to the entry to replace 645 // - entry : the entry to write 646 ///////////////////////////////////////////////////////////////////// 647 void write(const size_t &ptr, const HeapEntry &entry) 648 { 649 assert((ptr < tab_size) && "HeapDirectory error : try to write a wrong free pointer"); 650 m_heap_tab[ptr].copy(entry); 651 } // end write() 622 652 623 653 }; // end class HeapDirectory … … 628 658 class CacheData 629 659 { 630 private:631 const uint32_t m_sets;632 const uint32_t m_ways;633 const uint32_t m_words;634 635 uint32_t *** m_cache_data;636 637 public:638 639 ///////////////////////////////////////////////////////640 CacheData(uint32_t ways, uint32_t sets, uint32_t words)641 : m_sets(sets), m_ways(ways), m_words(words)642 {643 m_cache_data = new uint32_t ** [ways];644 for ( size_t i=0 ; i < ways ; i++)645 {646 m_cache_data[i] = new uint32_t * [sets];647 }648 for ( size_t i=0; i<ways; i++)649 {650 for ( size_t j=0; j<sets; j++)651 {652 m_cache_data[i][j] = new uint32_t [words];653 }654 }655 }656 ////////////657 ~CacheData()658 {659 for(size_t i=0; i<m_ways; i++)660 {661 for(size_t j=0; j<m_sets; j++)662 {663 delete [] m_cache_data[i][j];664 }665 }666 for(size_t i=0; i<m_ways; i++)667 {668 delete [] m_cache_data[i];669 }670 delete [] m_cache_data;671 }672 //////////////////////////////////////////673 uint32_t read (const uint32_t &way,674 const uint32_t &set,675 const uint32_t &word) const676 {677 assert((set < m_sets ) && "Cache data error: Trying to read a wrong set");678 assert((way < m_ways ) && "Cache data error: Trying to read a wrong way");679 assert((word < m_words) && "Cache data error: Trying to read a wrong word");680 681 return m_cache_data[way][set][word];682 }683 //////////////////////////////////////////684 void read_line(const uint32_t &way,685 const uint32_t &set,686 sc_core::sc_signal<uint32_t> * cache_line)687 {688 assert((set < m_sets ) && "Cache data error: Trying to read a wrong set");689 assert((way < m_ways ) && "Cache data error: Trying to read a wrong way");690 691 for (uint32_t word=0; word<m_words; word++)692 cache_line[word].write(m_cache_data[way][set][word]);693 }694 /////////////////////////////////////////695 void write ( const uint32_t &way,696 const uint32_t &set,697 const uint32_t &word,698 const uint32_t &data,699 const uint32_t &be = 0xF)700 {701 702 assert((set < m_sets ) && "Cache data error: Trying to write a wrong set");703 assert((way < m_ways ) && "Cache data error: Trying to write a wrong way");704 assert((word < m_words) && "Cache data error: Trying to write a wrong word");705 assert((be <= 0xF ) && "Cache data error: Trying to write a wrong be");706 707 if (be == 0x0) return;708 709 if (be == 0xF)710 {711 m_cache_data[way][set][word] = data;712 return;713 }714 715 uint32_t mask = 0;716 if(be & 0x1) mask = mask | 0x000000FF;717 if(be & 0x2) mask = mask | 0x0000FF00;718 if(be & 0x4) mask = mask | 0x00FF0000;719 if(be & 0x8) mask = mask | 0xFF000000;720 721 m_cache_data[way][set][word] =722 (data & mask) | (m_cache_data[way][set][word] & ~mask);723 }660 private: 661 const uint32_t m_sets; 662 const uint32_t m_ways; 663 const uint32_t m_words; 664 665 uint32_t *** m_cache_data; 666 667 public: 668 669 /////////////////////////////////////////////////////// 670 CacheData(uint32_t ways, uint32_t sets, uint32_t words) 671 : m_sets(sets), m_ways(ways), m_words(words) 672 { 673 m_cache_data = new uint32_t ** [ways]; 674 for (size_t i = 0; i < ways; i++) 675 { 676 m_cache_data[i] = new uint32_t * [sets]; 677 } 678 for (size_t i = 0; i < ways; i++) 679 { 680 for (size_t j = 0; j < sets; j++) 681 { 682 m_cache_data[i][j] = new uint32_t [words]; 683 } 684 } 685 } 686 //////////// 687 ~CacheData() 688 { 689 for (size_t i = 0; i < m_ways; i++) 690 { 691 for (size_t j = 0; j < m_sets; j++) 692 { 693 delete [] m_cache_data[i][j]; 694 } 695 } 696 for (size_t i = 0; i < m_ways; i++) 697 { 698 delete [] m_cache_data[i]; 699 } 700 delete [] m_cache_data; 701 } 702 ////////////////////////////////////////// 703 uint32_t read(const uint32_t &way, 704 const uint32_t &set, 705 const uint32_t &word) const 706 { 707 assert((set < m_sets ) && "Cache data error: Trying to read a wrong set"); 708 assert((way < m_ways ) && "Cache data error: Trying to read a wrong way"); 709 assert((word < m_words) && "Cache data error: Trying to read a wrong word"); 710 711 return m_cache_data[way][set][word]; 712 } 713 ////////////////////////////////////////// 714 void read_line(const uint32_t &way, 715 const uint32_t &set, 716 sc_core::sc_signal<uint32_t> * cache_line) 717 { 718 assert((set < m_sets) && "Cache data error: Trying to read a wrong set"); 719 assert((way < m_ways) && "Cache data error: Trying to read a wrong way"); 720 721 for (uint32_t word = 0; word < m_words; word++) { 722 cache_line[word].write(m_cache_data[way][set][word]); 723 } 724 } 725 ///////////////////////////////////////// 726 void write(const uint32_t &way, 727 const uint32_t &set, 728 const uint32_t &word, 729 const uint32_t &data, 730 const uint32_t &be = 0xF) 731 { 732 assert((set < m_sets ) && "Cache data error: Trying to write a wrong set"); 733 assert((way < m_ways ) && "Cache data error: Trying to write a wrong way"); 734 assert((word < m_words) && "Cache data error: Trying to write a wrong word"); 735 assert((be <= 0xF ) && "Cache data error: Trying to write a wrong be"); 736 737 if (be == 0x0) return; 738 739 if (be == 0xF) 740 { 741 m_cache_data[way][set][word] = data; 742 return; 743 } 744 745 uint32_t mask = 0; 746 if (be & 0x1) mask = mask | 0x000000FF; 747 if (be & 0x2) mask = mask | 0x0000FF00; 748 if (be & 0x4) mask = mask | 0x00FF0000; 749 if (be & 0x8) mask = mask | 0xFF000000; 750 751 m_cache_data[way][set][word] = 752 (data & mask) | (m_cache_data[way][set][word] & ~mask); 753 } 724 754 }; // end class CacheData 725 755 -
branches/RWT/modules/vci_mem_cache/caba/source/include/update_tab.h
r814 r823 12 12 class UpdateTabEntry { 13 13 14 typedef uint32_t size_t;15 typedef sc_dt::sc_uint<40> addr_t;16 17 public: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 receive29 30 UpdateTabEntry()31 {32 valid = false;33 update = false;34 brdcast = false;35 rsp = false;36 ack = false;37 srcid = 0;38 trdid = 0;39 pktid = 0;40 nline = 0;41 count = 0;42 }43 44 UpdateTabEntry(bool i_valid,45 bool i_update,46 bool i_brdcast,47 bool i_rsp,48 bool i_ack,49 size_t i_srcid,50 size_t i_trdid,51 size_t i_pktid,52 addr_t i_nline,53 size_t i_count)54 {55 valid = i_valid;56 update = i_update;57 brdcast = i_brdcast;58 rsp = i_rsp;59 ack = i_ack;60 srcid = i_srcid;61 trdid = i_trdid;62 pktid = i_pktid;63 nline = i_nline;64 count = i_count;65 }66 67 UpdateTabEntry(const UpdateTabEntry &source)68 {69 valid = source.valid;70 update = source.update;71 brdcast = source.brdcast;72 rsp = source.rsp;73 ack = source.ack;74 srcid = source.srcid;75 trdid = source.trdid;76 pktid = source.pktid;77 nline = source.nline;78 count = source.count;79 }80 81 ////////////////////////////////////////////////////82 // The init() function initializes the entry83 ///////////////////////////////////////////////////84 void init()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;96 }97 98 ////////////////////////////////////////////////////////////////////99 // The copy() function copies an existing entry100 // Its arguments are :101 // - source : the update tab entry to copy102 ////////////////////////////////////////////////////////////////////103 void copy(const UpdateTabEntry &source)104 {105 valid= source.valid;106 update= source.update;107 brdcast= source.brdcast;108 rsp= source.rsp;109 ack = source.ack;110 srcid= source.srcid;111 trdid= source.trdid;112 pktid= source.pktid;113 nline= source.nline;114 count= source.count;115 }116 117 ////////////////////////////////////////////////////////////////////118 // The print() function prints the entry119 ////////////////////////////////////////////////////////////////////120 void print()121 {122 std::cout << " val = " << std::dec << valid123 << " / updt = " << update124 << " / bc = " << brdcast125 << " / rsp = " << rsp126 << " / ack = " << ack127 << " / count = " << count128 << " / srcid = " << std::hex << srcid129 << " / trdid = " << trdid130 << " / pktid = " << pktid131 << " / nline = " << nline<< std::endl;132 }14 typedef uint32_t size_t; 15 typedef sc_dt::sc_uint<40> addr_t; 16 17 public: 18 19 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 30 UpdateTabEntry() 31 { 32 valid = false; 33 update = false; 34 brdcast = false; 35 rsp = false; 36 ack = false; 37 srcid = 0; 38 trdid = 0; 39 pktid = 0; 40 nline = 0; 41 count = 0; 42 } 43 44 UpdateTabEntry(bool i_valid, 45 bool i_update, 46 bool i_brdcast, 47 bool i_rsp, 48 bool i_ack, 49 size_t i_srcid, 50 size_t i_trdid, 51 size_t i_pktid, 52 addr_t i_nline, 53 size_t i_count) 54 { 55 valid = i_valid; 56 update = i_update; 57 brdcast = i_brdcast; 58 rsp = i_rsp; 59 ack = i_ack; 60 srcid = i_srcid; 61 trdid = i_trdid; 62 pktid = i_pktid; 63 nline = i_nline; 64 count = i_count; 65 } 66 67 UpdateTabEntry(const UpdateTabEntry &source) 68 { 69 valid = source.valid; 70 update = source.update; 71 brdcast = source.brdcast; 72 rsp = source.rsp; 73 ack = source.ack; 74 srcid = source.srcid; 75 trdid = source.trdid; 76 pktid = source.pktid; 77 nline = source.nline; 78 count = source.count; 79 } 80 81 //////////////////////////////////////////////////// 82 // The init() function initializes the entry 83 /////////////////////////////////////////////////// 84 void init() 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; 96 } 97 98 //////////////////////////////////////////////////////////////////// 99 // The copy() function copies an existing entry 100 // Its arguments are : 101 // - source : the update tab entry to copy 102 //////////////////////////////////////////////////////////////////// 103 void copy(const UpdateTabEntry &source) 104 { 105 valid = source.valid; 106 update = source.update; 107 brdcast = source.brdcast; 108 rsp = source.rsp; 109 ack = source.ack; 110 srcid = source.srcid; 111 trdid = source.trdid; 112 pktid = source.pktid; 113 nline = source.nline; 114 count = source.count; 115 } 116 117 //////////////////////////////////////////////////////////////////// 118 // The print() function prints the entry 119 //////////////////////////////////////////////////////////////////// 120 void print() 121 { 122 std::cout << " val = " << std::dec << valid 123 << " / updt = " << update 124 << " / bc = " << brdcast 125 << " / rsp = " << rsp 126 << " / ack = " << ack 127 << " / count = " << count 128 << " / srcid = " << std::hex << srcid 129 << " / trdid = " << trdid 130 << " / pktid = " << pktid 131 << " / nline = " << nline << std::endl; 132 } 133 133 }; 134 134 … … 138 138 class UpdateTab{ 139 139 140 typedef uint64_t addr_t; 141 142 private: 143 size_t size_tab; 144 std::vector<UpdateTabEntry> tab; 145 146 public: 147 148 UpdateTab() 149 : tab(0) 150 { 151 size_tab=0; 152 } 153 154 UpdateTab(size_t size_tab_i) 155 : tab(size_tab_i) 156 { 157 size_tab=size_tab_i; 158 } 159 160 //////////////////////////////////////////////////////////////////// 161 // The size() function returns the size of the tab 162 //////////////////////////////////////////////////////////////////// 163 const size_t size() 164 { 165 return size_tab; 166 } 167 168 //////////////////////////////////////////////////////////////////// 169 // The print() function diplays the tab content 170 //////////////////////////////////////////////////////////////////// 171 void print() 172 { 173 std::cout << "UPDATE TABLE Content" << std::endl; 174 for(size_t i=0; i<size_tab; i++) 175 { 176 std::cout << "[" << std::dec << i << "] "; 177 tab[i].print(); 178 } 179 return; 180 } 181 182 ///////////////////////////////////////////////////////////////////// 183 // The init() function initializes the tab 184 ///////////////////////////////////////////////////////////////////// 185 void init() 186 { 187 for ( size_t i=0; i<size_tab; i++) tab[i].init(); 188 } 189 190 ///////////////////////////////////////////////////////////////////// 191 // The reads() function reads an entry 192 // Arguments : 193 // - entry : the entry to read 194 // This function returns a copy of the entry. 195 ///////////////////////////////////////////////////////////////////// 196 UpdateTabEntry read (size_t entry) 197 { 198 assert(entry<size_tab && "Bad Update Tab Entry"); 199 return UpdateTabEntry(tab[entry]); 200 } 201 202 /////////////////////////////////////////////////////////////////////////// 203 // The set() function writes an entry in the Update Table 204 // Arguments : 205 // - update : transaction type (bool) 206 // - srcid : srcid of the initiator 207 // - trdid : trdid of the initiator 208 // - pktid : pktid of the initiator 209 // - count : number of expected responses 210 // - index : (return argument) index of the selected entry 211 // This function returns true if the write successed (an entry was empty). 212 /////////////////////////////////////////////////////////////////////////// 213 bool set(const bool update, 214 const bool brdcast, 215 const bool rsp, 216 const bool ack, 217 const size_t srcid, 218 const size_t trdid, 219 const size_t pktid, 220 const addr_t nline, 221 const size_t count, 222 size_t &index) 223 { 224 for ( size_t i=0 ; i<size_tab ; i++ ) 225 { 226 if( !tab[i].valid ) 227 { 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; 140 typedef uint64_t addr_t; 141 142 private: 143 size_t size_tab; 144 std::vector<UpdateTabEntry> tab; 145 146 public: 147 148 UpdateTab() 149 : tab(0) 150 { 151 size_tab = 0; 152 } 153 154 UpdateTab(size_t size_tab_i) 155 : tab(size_tab_i) 156 { 157 size_tab = size_tab_i; 158 } 159 160 //////////////////////////////////////////////////////////////////// 161 // The size() function returns the size of the tab 162 //////////////////////////////////////////////////////////////////// 163 const size_t size() 164 { 165 return size_tab; 166 } 167 168 //////////////////////////////////////////////////////////////////// 169 // The print() function diplays the tab content 170 //////////////////////////////////////////////////////////////////// 171 void print() 172 { 173 std::cout << "UPDATE TABLE Content" << std::endl; 174 for (size_t i = 0; i < size_tab; i++) 175 { 176 std::cout << "[" << std::dec << i << "] "; 177 tab[i].print(); 178 } 179 return; 180 } 181 182 ///////////////////////////////////////////////////////////////////// 183 // The init() function initializes the tab 184 ///////////////////////////////////////////////////////////////////// 185 void init() 186 { 187 for (size_t i = 0; i < size_tab; i++) 188 { 189 tab[i].init(); 190 } 191 } 192 193 ///////////////////////////////////////////////////////////////////// 194 // The reads() function reads an entry 195 // Arguments : 196 // - entry : the entry to read 197 // This function returns a copy of the entry. 198 ///////////////////////////////////////////////////////////////////// 199 UpdateTabEntry read(size_t entry) 200 { 201 assert(entry < size_tab && "Bad Update Tab Entry"); 202 return UpdateTabEntry(tab[entry]); 203 } 204 205 /////////////////////////////////////////////////////////////////////////// 206 // The set() function writes an entry in the Update Table 207 // Arguments : 208 // - update : transaction type (bool) 209 // - srcid : srcid of the initiator 210 // - trdid : trdid of the initiator 211 // - pktid : pktid of the initiator 212 // - count : number of expected responses 213 // - index : (return argument) index of the selected entry 214 // This function returns true if the write successed (an entry was empty). 215 /////////////////////////////////////////////////////////////////////////// 216 bool set(const bool update, 217 const bool brdcast, 218 const bool rsp, 219 const bool ack, 220 const size_t srcid, 221 const size_t trdid, 222 const size_t pktid, 223 const addr_t nline, 224 const size_t count, 225 size_t &index) 226 { 227 for (size_t i = 0; i < size_tab; i++) 228 { 229 if (!tab[i].valid) 230 { 231 tab[i].valid = true; 232 tab[i].update = update; 233 tab[i].brdcast = brdcast; 234 tab[i].rsp = rsp; 235 tab[i].ack = ack; 236 tab[i].srcid = (size_t) srcid; 237 tab[i].trdid = (size_t) trdid; 238 tab[i].pktid = (size_t) pktid; 239 tab[i].nline = (addr_t) nline; 240 tab[i].count = (size_t) count; 241 index = i; 242 return true; 243 } 244 } 245 return false; 246 } // end set() 247 248 ///////////////////////////////////////////////////////////////////// 249 // The decrement() function decrements the counter for a given entry. 250 // Arguments : 251 // - index : the index of the entry 252 // - counter : (return argument) value of the counter after decrement 253 // This function returns true if the entry is valid. 254 ///////////////////////////////////////////////////////////////////// 255 bool decrement(const size_t index, 256 size_t &counter) 257 { 258 assert((index < size_tab) && "Bad Update Tab Entry"); 259 if (tab[index].valid) 260 { 261 tab[index].count--; 262 counter = tab[index].count; 263 return true; 264 } 265 else 266 { 267 return false; 268 } 269 } 270 271 ///////////////////////////////////////////////////////////////////// 272 // The is_full() function returns true if the table is full 273 ///////////////////////////////////////////////////////////////////// 274 bool is_full() 275 { 276 for (size_t i = 0; i < size_tab; i++) 277 { 278 if (!tab[i].valid) 279 { 280 return false; 281 } 282 } 239 283 return true; 240 } 241 } 242 return false; 243 } // end set() 244 245 ///////////////////////////////////////////////////////////////////// 246 // The decrement() function decrements the counter for a given entry. 247 // Arguments : 248 // - index : the index of the entry 249 // - counter : (return argument) value of the counter after decrement 250 // This function returns true if the entry is valid. 251 ///////////////////////////////////////////////////////////////////// 252 bool decrement( const size_t index, 253 size_t &counter ) 254 { 255 assert((index<size_tab) && "Bad Update Tab Entry"); 256 if ( tab[index].valid ) 257 { 258 tab[index].count--; 259 counter = tab[index].count; 260 return true; 261 } 262 else 263 { 264 return false; 265 } 266 } 267 268 ///////////////////////////////////////////////////////////////////// 269 // The is_full() function returns true if the table is full 270 ///////////////////////////////////////////////////////////////////// 271 bool is_full() 272 { 273 for(size_t i = 0 ; i < size_tab ; i++) 274 { 275 if(!tab[i].valid) return false; 276 } 277 return true; 278 } 279 280 ///////////////////////////////////////////////////////////////////// 281 // The is_not_empty() function returns true if the table is not empty 282 ///////////////////////////////////////////////////////////////////// 283 bool is_not_empty() 284 { 285 for(size_t i = 0 ; i < size_tab ; i++) 286 { 287 if(tab[i].valid) return true; 288 } 289 return false; 290 } 291 292 ///////////////////////////////////////////////////////////////////// 293 // The need_rsp() function returns the need of a response 294 // Arguments : 295 // - index : the index of the entry 296 ///////////////////////////////////////////////////////////////////// 297 bool need_rsp(const size_t index) 298 { 299 assert(index<size_tab && "Bad Update Tab Entry"); 300 return tab[index].rsp; 301 } 302 303 ///////////////////////////////////////////////////////////////////// 304 // The need_ack() function returns the need of an acknowledge 305 // Arguments : 306 // - index : the index of the entry 307 ///////////////////////////////////////////////////////////////////// 308 bool need_ack(const size_t index) 309 { 310 assert(index<size_tab && "Bad Update Tab Entry"); 311 return tab[index].ack; 312 } 313 314 ///////////////////////////////////////////////////////////////////// 315 // The is_brdcast() function returns the transaction type 316 // Arguments : 317 // - index : the index of the entry 318 ///////////////////////////////////////////////////////////////////// 319 bool is_brdcast(const size_t index) 320 { 321 assert(index<size_tab && "Bad Update Tab Entry"); 322 return tab[index].brdcast; 323 } 324 325 ///////////////////////////////////////////////////////////////////// 326 // The is_update() function returns the transaction type 327 // Arguments : 328 // - index : the index of the entry 329 ///////////////////////////////////////////////////////////////////// 330 bool is_update(const size_t index) 331 { 332 assert(index<size_tab && "Bad Update Tab Entry"); 333 return tab[index].update; 334 } 335 336 ///////////////////////////////////////////////////////////////////// 337 // The srcid() function returns the srcid value 338 // Arguments : 339 // - index : the index of the entry 340 ///////////////////////////////////////////////////////////////////// 341 size_t srcid(const size_t index) 342 { 343 assert(index<size_tab && "Bad Update Tab Entry"); 344 return tab[index].srcid; 345 } 346 347 ///////////////////////////////////////////////////////////////////// 348 // The trdid() function returns the trdid value 349 // Arguments : 350 // - index : the index of the entry 351 ///////////////////////////////////////////////////////////////////// 352 size_t trdid(const size_t index) 353 { 354 assert(index<size_tab && "Bad Update Tab Entry"); 355 return tab[index].trdid; 356 } 357 358 ///////////////////////////////////////////////////////////////////// 359 // The pktid() function returns the pktid value 360 // Arguments : 361 // - index : the index of the entry 362 ///////////////////////////////////////////////////////////////////// 363 size_t pktid(const size_t index) 364 { 365 assert(index<size_tab && "Bad Update Tab Entry"); 366 return tab[index].pktid; 367 } 368 369 ///////////////////////////////////////////////////////////////////// 370 // The nline() function returns the nline value 371 // Arguments : 372 // - index : the index of the entry 373 ///////////////////////////////////////////////////////////////////// 374 addr_t nline(const size_t index) 375 { 376 assert(index<size_tab && "Bad Update Tab Entry"); 377 return tab[index].nline; 378 } 379 380 ///////////////////////////////////////////////////////////////////// 381 // The search_inval() function returns the index of the entry in UPT 382 // Arguments : 383 // - nline : the line number of the entry in the directory 384 ///////////////////////////////////////////////////////////////////// 385 bool search_inval(const addr_t nline,size_t &index) 386 { 387 size_t i ; 388 389 for (i = 0 ; i < size_tab ; i++) 390 { 391 if ( (tab[i].nline == nline) and tab[i].valid and not tab[i].update ) 392 { 393 index = i ; 394 return true; 395 } 396 } 397 return false; 398 } 399 400 ///////////////////////////////////////////////////////////////////// 401 // The read_nline() function returns the index of the entry in UPT 402 // Arguments : 403 // - nline : the line number of the entry in the directory 404 ///////////////////////////////////////////////////////////////////// 405 bool read_nline(const addr_t nline,size_t &index) 406 { 407 size_t i ; 408 409 for (i = 0 ; i < size_tab ; i++) 410 { 411 if ( (tab[i].nline == nline) and tab[i].valid ) 412 { 413 index = i ; 414 return true; 415 } 416 } 417 return false; 418 } 419 420 ///////////////////////////////////////////////////////////////////// 421 // The clear() function erases an entry of the tab 422 // Arguments : 423 // - index : the index of the entry 424 ///////////////////////////////////////////////////////////////////// 425 void clear(const size_t index) 426 { 427 assert(index<size_tab && "Bad Update Tab Entry"); 428 tab[index].valid=false; 429 return; 430 } 284 } 285 286 ///////////////////////////////////////////////////////////////////// 287 // The is_not_empty() function returns true if the table is not empty 288 ///////////////////////////////////////////////////////////////////// 289 bool is_not_empty() 290 { 291 for (size_t i = 0; i < size_tab; i++) 292 { 293 if (tab[i].valid) 294 { 295 return true; 296 } 297 } 298 return false; 299 } 300 301 ///////////////////////////////////////////////////////////////////// 302 // The need_rsp() function returns the need of a response 303 // Arguments : 304 // - index : the index of the entry 305 ///////////////////////////////////////////////////////////////////// 306 bool need_rsp(const size_t index) 307 { 308 assert(index < size_tab && "Bad Update Tab Entry"); 309 return tab[index].rsp; 310 } 311 312 ///////////////////////////////////////////////////////////////////// 313 // The need_ack() function returns the need of an acknowledge 314 // Arguments : 315 // - index : the index of the entry 316 ///////////////////////////////////////////////////////////////////// 317 bool need_ack(const size_t index) 318 { 319 assert(index < size_tab && "Bad Update Tab Entry"); 320 return tab[index].ack; 321 } 322 323 ///////////////////////////////////////////////////////////////////// 324 // The is_brdcast() function returns the transaction type 325 // Arguments : 326 // - index : the index of the entry 327 ///////////////////////////////////////////////////////////////////// 328 bool is_brdcast(const size_t index) 329 { 330 assert(index < size_tab && "Bad Update Tab Entry"); 331 return tab[index].brdcast; 332 } 333 334 ///////////////////////////////////////////////////////////////////// 335 // The is_update() function returns the transaction type 336 // Arguments : 337 // - index : the index of the entry 338 ///////////////////////////////////////////////////////////////////// 339 bool is_update(const size_t index) 340 { 341 assert(index < size_tab && "Bad Update Tab Entry"); 342 return tab[index].update; 343 } 344 345 ///////////////////////////////////////////////////////////////////// 346 // The srcid() function returns the srcid value 347 // Arguments : 348 // - index : the index of the entry 349 ///////////////////////////////////////////////////////////////////// 350 size_t srcid(const size_t index) 351 { 352 assert(index < size_tab && "Bad Update Tab Entry"); 353 return tab[index].srcid; 354 } 355 356 ///////////////////////////////////////////////////////////////////// 357 // The trdid() function returns the trdid value 358 // Arguments : 359 // - index : the index of the entry 360 ///////////////////////////////////////////////////////////////////// 361 size_t trdid(const size_t index) 362 { 363 assert(index < size_tab && "Bad Update Tab Entry"); 364 return tab[index].trdid; 365 } 366 367 ///////////////////////////////////////////////////////////////////// 368 // The pktid() function returns the pktid value 369 // Arguments : 370 // - index : the index of the entry 371 ///////////////////////////////////////////////////////////////////// 372 size_t pktid(const size_t index) 373 { 374 assert(index < size_tab && "Bad Update Tab Entry"); 375 return tab[index].pktid; 376 } 377 378 ///////////////////////////////////////////////////////////////////// 379 // The nline() function returns the nline value 380 // Arguments : 381 // - index : the index of the entry 382 ///////////////////////////////////////////////////////////////////// 383 addr_t nline(const size_t index) 384 { 385 assert(index < size_tab && "Bad Update Tab Entry"); 386 return tab[index].nline; 387 } 388 389 ///////////////////////////////////////////////////////////////////// 390 // The search_inval() function returns the index of the entry in UPT 391 // Arguments : 392 // - nline : the line number of the entry in the directory 393 ///////////////////////////////////////////////////////////////////// 394 bool search_inval(const addr_t nline, size_t &index) 395 { 396 size_t i; 397 398 for (i = 0; i < size_tab; i++) 399 { 400 if ((tab[i].nline == nline) and tab[i].valid and not tab[i].update) 401 { 402 index = i; 403 return true; 404 } 405 } 406 return false; 407 } 408 409 ///////////////////////////////////////////////////////////////////// 410 // The read_nline() function returns the index of the entry in UPT 411 // Arguments : 412 // - nline : the line number of the entry in the directory 413 ///////////////////////////////////////////////////////////////////// 414 bool read_nline(const addr_t nline, size_t &index) 415 { 416 size_t i; 417 418 for (i = 0; i < size_tab; i++) 419 { 420 if ((tab[i].nline == nline) and tab[i].valid) 421 { 422 index = i; 423 return true; 424 } 425 } 426 return false; 427 } 428 429 ///////////////////////////////////////////////////////////////////// 430 // The clear() function erases an entry of the tab 431 // Arguments : 432 // - index : the index of the entry 433 ///////////////////////////////////////////////////////////////////// 434 void clear(const size_t index) 435 { 436 assert(index < size_tab && "Bad Update Tab Entry"); 437 tab[index].valid = false; 438 return; 439 } 431 440 432 441 }; -
branches/RWT/modules/vci_mem_cache/caba/source/include/vci_mem_cache.h
r814 r823 69 69 : public soclib::caba::BaseModule 70 70 { 71 typedef typename vci_param_int::fast_addr_t 72 typedef typename sc_dt::sc_uint<64> 73 typedef uint32_t 74 typedef uint32_t 75 typedef uint32_t 76 typedef uint32_t 71 typedef typename vci_param_int::fast_addr_t addr_t; 72 typedef typename sc_dt::sc_uint<64> wide_data_t; 73 typedef uint32_t data_t; 74 typedef uint32_t tag_t; 75 typedef uint32_t be_t; 76 typedef uint32_t copy_t; 77 77 78 78 /* States of the TGT_CMD fsm */ … … 113 113 CC_RECEIVE_IDLE, 114 114 CC_RECEIVE_CLEANUP, 115 CC_RECEIVE_CLEANUP_EOP,116 115 CC_RECEIVE_MULTI_ACK 117 116 }; … … 232 231 { 233 232 IXR_RSP_IDLE, 234 IXR_RSP_ACK,235 233 IXR_RSP_TRT_ERASE, 236 234 IXR_RSP_TRT_READ … … 399 397 // b1 accÚs table llsc type SW / other 400 398 // b2 WRITE/CAS/LL/SC 401 TYPE_READ_DATA_UNC 402 TYPE_READ_DATA_MISS 403 TYPE_READ_INS_UNC 404 TYPE_READ_INS_MISS 405 TYPE_WRITE 406 TYPE_CAS 407 TYPE_LL 408 TYPE_SC 399 TYPE_READ_DATA_UNC = 0x0, 400 TYPE_READ_DATA_MISS = 0x1, 401 TYPE_READ_INS_UNC = 0x2, 402 TYPE_READ_INS_MISS = 0x3, 403 TYPE_WRITE = 0x4, 404 TYPE_CAS = 0x5, 405 TYPE_LL = 0x6, 406 TYPE_SC = 0x7 409 407 }; 410 408 … … 425 423 426 424 // instrumentation counters 427 uint32_t m_cpt_cycles; // Counter of cycles425 uint32_t m_cpt_cycles; // Counter of cycles 428 426 429 427 // Counters accessible in software (not yet but eventually) and tagged 430 uint32_t m_cpt_reset_count; // Last cycle at which counters have been reset431 uint32_t m_cpt_read_local; // Number of local READ transactions432 uint32_t m_cpt_read_remote; // number of remote READ transactions433 uint32_t m_cpt_read_cost; // Number of (flits * distance) for READs434 435 uint32_t m_cpt_write_local; // Number of local WRITE transactions436 uint32_t m_cpt_write_remote; // number of remote WRITE transactions437 uint32_t m_cpt_write_flits_local; // number of flits for local WRITEs438 uint32_t m_cpt_write_flits_remote; // number of flits for remote WRITEs439 uint32_t m_cpt_write_cost; // Number of (flits * distance) for WRITEs440 uint32_t m_cpt_write_ncc_miss; // Number of write on ncc line441 442 uint32_t m_cpt_ll_local; // Number of local LL transactions443 uint32_t m_cpt_ll_remote; // number of remote LL transactions444 uint32_t m_cpt_ll_cost; // Number of (flits * distance) for LLs445 446 uint32_t m_cpt_sc_local; // Number of local SC transactions447 uint32_t m_cpt_sc_remote; // number of remote SC transactions448 uint32_t m_cpt_sc_cost; // Number of (flits * distance) for SCs449 450 uint32_t m_cpt_cas_local; // Number of local SC transactions451 uint32_t m_cpt_cas_remote; // number of remote SC transactions452 uint32_t m_cpt_cas_cost; // Number of (flits * distance) for SCs453 454 uint32_t m_cpt_update; // Number of requests causing an UPDATE455 uint32_t m_cpt_update_local; // Number of local UPDATE transactions456 uint32_t m_cpt_update_remote; // Number of remote UPDATE transactions457 uint32_t m_cpt_update_cost; // Number of (flits * distance) for UPDT458 459 uint32_t m_cpt_minval; // Number of requests causing M_INV460 uint32_t m_cpt_minval_local; // Number of local M_INV transactions461 uint32_t m_cpt_minval_remote; // Number of remote M_INV transactions462 uint32_t m_cpt_minval_cost; // Number of (flits * distance) for M_INV463 464 uint32_t m_cpt_binval; // Number of BROADCAST INVAL465 466 uint32_t m_cpt_cleanup_local; // Number of local CLEANUP transactions (all cleanup types)467 uint32_t m_cpt_cleanup_remote; // Number of remote CLEANUP transactions (all cleanup types)468 uint32_t m_cpt_cleanup_cost; // Number of (flits * distance) for CLEANUPs (all types)428 uint32_t m_cpt_reset_count; // Last cycle at which counters have been reset 429 uint32_t m_cpt_read_local; // Number of local READ transactions 430 uint32_t m_cpt_read_remote; // number of remote READ transactions 431 uint32_t m_cpt_read_cost; // Number of (flits * distance) for READs 432 433 uint32_t m_cpt_write_local; // Number of local WRITE transactions 434 uint32_t m_cpt_write_remote; // number of remote WRITE transactions 435 uint32_t m_cpt_write_flits_local; // number of flits for local WRITEs 436 uint32_t m_cpt_write_flits_remote; // number of flits for remote WRITEs 437 uint32_t m_cpt_write_cost; // Number of (flits * distance) for WRITEs 438 uint32_t m_cpt_write_ncc_miss; // Number of write on ncc line 439 440 uint32_t m_cpt_ll_local; // Number of local LL transactions 441 uint32_t m_cpt_ll_remote; // number of remote LL transactions 442 uint32_t m_cpt_ll_cost; // Number of (flits * distance) for LLs 443 444 uint32_t m_cpt_sc_local; // Number of local SC transactions 445 uint32_t m_cpt_sc_remote; // number of remote SC transactions 446 uint32_t m_cpt_sc_cost; // Number of (flits * distance) for SCs 447 448 uint32_t m_cpt_cas_local; // Number of local SC transactions 449 uint32_t m_cpt_cas_remote; // number of remote SC transactions 450 uint32_t m_cpt_cas_cost; // Number of (flits * distance) for SCs 451 452 uint32_t m_cpt_update; // Number of requests causing an UPDATE 453 uint32_t m_cpt_update_local; // Number of local UPDATE transactions 454 uint32_t m_cpt_update_remote; // Number of remote UPDATE transactions 455 uint32_t m_cpt_update_cost; // Number of (flits * distance) for UPDT 456 457 uint32_t m_cpt_minval; // Number of requests causing M_INV 458 uint32_t m_cpt_minval_local; // Number of local M_INV transactions 459 uint32_t m_cpt_minval_remote; // Number of remote M_INV transactions 460 uint32_t m_cpt_minval_cost; // Number of (flits * distance) for M_INV 461 462 uint32_t m_cpt_binval; // Number of BROADCAST INVAL 463 464 uint32_t m_cpt_cleanup_local; // Number of local CLEANUP transactions (all cleanup types) 465 uint32_t m_cpt_cleanup_remote; // Number of remote CLEANUP transactions (all cleanup types) 466 uint32_t m_cpt_cleanup_cost; // Number of (flits * distance) for CLEANUPs (all types) 469 467 470 468 // Counters not accessible by software, but tagged 471 uint32_t m_cpt_read_miss; // Number of MISS READ472 uint32_t m_cpt_write_miss; // Number of MISS WRITE473 uint32_t m_cpt_write_dirty; // Cumulated length for WRITE transactions474 uint32_t m_cpt_write_broadcast; // Number of BROADCAST INVAL because write475 476 uint32_t m_cpt_trt_rb; // Read blocked by a hit in trt477 uint32_t m_cpt_trt_full; // Transaction blocked due to a full trt469 uint32_t m_cpt_read_miss; // Number of MISS READ 470 uint32_t m_cpt_write_miss; // Number of MISS WRITE 471 uint32_t m_cpt_write_dirty; // Cumulated length for WRITE transactions 472 uint32_t m_cpt_write_broadcast; // Number of BROADCAST INVAL because write 473 474 uint32_t m_cpt_trt_rb; // Read blocked by a hit in trt 475 uint32_t m_cpt_trt_full; // Transaction blocked due to a full trt 478 476 479 477 uint32_t m_cpt_heap_unused; // NB cycles HEAP LOCK unused … … 481 479 uint32_t m_cpt_heap_min_slot_available; // NB HEAP : Min of slot available 482 480 483 uint32_t m_cpt_ncc_to_cc_read; // NB change from NCC to CC caused by a READ484 uint32_t m_cpt_ncc_to_cc_write; // NB change from NCC to CC caused by a WRITE485 486 uint32_t m_cpt_cleanup_data_local; // Number of local cleanups with data487 uint32_t m_cpt_cleanup_data_remote; // Number of remote cleanups with data488 uint32_t m_cpt_cleanup_data_cost; // Cost for cleanups with data489 490 uint32_t m_cpt_update_flits; // Number of flits for UPDATEs491 uint32_t m_cpt_inval_cost; // Number of (flits * distance) for INVALs481 uint32_t m_cpt_ncc_to_cc_read; // NB change from NCC to CC caused by a READ 482 uint32_t m_cpt_ncc_to_cc_write; // NB change from NCC to CC caused by a WRITE 483 484 uint32_t m_cpt_cleanup_data_local; // Number of local cleanups with data 485 uint32_t m_cpt_cleanup_data_remote; // Number of remote cleanups with data 486 uint32_t m_cpt_cleanup_data_cost; // Cost for cleanups with data 487 488 uint32_t m_cpt_update_flits; // Number of flits for UPDATEs 489 uint32_t m_cpt_inval_cost; // Number of (flits * distance) for INVALs 492 490 493 491 uint32_t m_cpt_get; … … 499 497 uint32_t m_cpt_upt_unused; // NB cycles UPT LOCK unused 500 498 501 // Unused502 uint32_t m_cpt_read_data_unc;503 uint32_t m_cpt_read_data_miss_CC;504 uint32_t m_cpt_read_ins_unc;505 uint32_t m_cpt_read_ins_miss;506 uint32_t m_cpt_read_ll_CC;507 uint32_t m_cpt_read_data_miss_NCC;508 uint32_t m_cpt_read_ll_NCC;509 510 499 size_t m_prev_count; 511 500 … … 515 504 516 505 public: 517 sc_in<bool> 518 sc_in<bool> 519 sc_out<bool> 520 soclib::caba::VciTarget<vci_param_int> 521 soclib::caba::VciInitiator<vci_param_ext> 522 soclib::caba::DspinInput<dspin_in_width> 523 soclib::caba::DspinOutput<dspin_out_width> 524 soclib::caba::DspinOutput<dspin_out_width> 506 sc_in<bool> p_clk; 507 sc_in<bool> p_resetn; 508 sc_out<bool> p_irq; 509 soclib::caba::VciTarget<vci_param_int> p_vci_tgt; 510 soclib::caba::VciInitiator<vci_param_ext> p_vci_ixr; 511 soclib::caba::DspinInput<dspin_in_width> p_dspin_p2m; 512 soclib::caba::DspinOutput<dspin_out_width> p_dspin_m2p; 513 soclib::caba::DspinOutput<dspin_out_width> p_dspin_clack; 525 514 526 515 #if MONITOR_MEMCACHE_FSM == 1 … … 557 546 const size_t nwords, // Number of words per line 558 547 const size_t max_copies, // max number of copies 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,563 const size_t debug_start_cycle =0,564 const bool debug_ok =false );548 const size_t heap_size = HEAP_ENTRIES, 549 const size_t trt_lines = TRT_ENTRIES, 550 const size_t upt_lines = UPT_ENTRIES, 551 const size_t ivt_lines = IVT_ENTRIES, 552 const size_t debug_start_cycle = 0, 553 const bool debug_ok = false ); 565 554 566 555 ~VciMemCache(); … … 568 557 void reset_counters(); 569 558 void print_stats(bool activity_counters = true, bool stats = false); 570 void print_trace( size_t detailled = 0);559 void print_trace(size_t detailled = 0); 571 560 void cache_monitor(addr_t addr); 572 561 void start_monitor(addr_t addr, addr_t length); … … 581 570 uint32_t min_value(uint32_t old_value, uint32_t new_value); 582 571 bool is_local_req(uint32_t req_srcid); 583 int 572 int read_instrumentation(uint32_t regr, uint32_t & rdata); 584 573 585 574 // Component attributes … … 616 605 617 606 // adress masks 618 const soclib::common::AddressMaskingTable<addr_t> 619 const soclib::common::AddressMaskingTable<addr_t> 620 const soclib::common::AddressMaskingTable<addr_t> 621 const soclib::common::AddressMaskingTable<addr_t> 607 const soclib::common::AddressMaskingTable<addr_t> m_x; 608 const soclib::common::AddressMaskingTable<addr_t> m_y; 609 const soclib::common::AddressMaskingTable<addr_t> m_z; 610 const soclib::common::AddressMaskingTable<addr_t> m_nline; 622 611 623 612 // broadcast address 624 uint32_t 613 uint32_t m_broadcast_boundaries; 625 614 626 615 // configuration interface constants … … 632 621 633 622 // Fifo between TGT_CMD fsm and READ fsm 634 GenericFifo<addr_t> 635 GenericFifo<size_t> 636 GenericFifo<size_t> 637 GenericFifo<size_t> 638 GenericFifo<size_t> 623 GenericFifo<addr_t> m_cmd_read_addr_fifo; 624 GenericFifo<size_t> m_cmd_read_length_fifo; 625 GenericFifo<size_t> m_cmd_read_srcid_fifo; 626 GenericFifo<size_t> m_cmd_read_trdid_fifo; 627 GenericFifo<size_t> m_cmd_read_pktid_fifo; 639 628 640 629 // Fifo between TGT_CMD fsm and WRITE fsm 641 GenericFifo<addr_t> 642 GenericFifo<bool> 643 GenericFifo<size_t> 644 GenericFifo<size_t> 645 GenericFifo<size_t> 646 GenericFifo<data_t> 647 GenericFifo<be_t> 630 GenericFifo<addr_t> m_cmd_write_addr_fifo; 631 GenericFifo<bool> m_cmd_write_eop_fifo; 632 GenericFifo<size_t> m_cmd_write_srcid_fifo; 633 GenericFifo<size_t> m_cmd_write_trdid_fifo; 634 GenericFifo<size_t> m_cmd_write_pktid_fifo; 635 GenericFifo<data_t> m_cmd_write_data_fifo; 636 GenericFifo<be_t> m_cmd_write_be_fifo; 648 637 649 638 // Fifo between TGT_CMD fsm and CAS fsm 650 GenericFifo<addr_t> 651 GenericFifo<bool> 652 GenericFifo<size_t> 653 GenericFifo<size_t> 654 GenericFifo<size_t> 655 GenericFifo<data_t> 639 GenericFifo<addr_t> m_cmd_cas_addr_fifo; 640 GenericFifo<bool> m_cmd_cas_eop_fifo; 641 GenericFifo<size_t> m_cmd_cas_srcid_fifo; 642 GenericFifo<size_t> m_cmd_cas_trdid_fifo; 643 GenericFifo<size_t> m_cmd_cas_pktid_fifo; 644 GenericFifo<data_t> m_cmd_cas_wdata_fifo; 656 645 657 646 // Fifo between CC_RECEIVE fsm and CLEANUP fsm 658 GenericFifo<uint64_t> 647 GenericFifo<uint64_t> m_cc_receive_to_cleanup_fifo; 659 648 660 649 // Fifo between CC_RECEIVE fsm and MULTI_ACK fsm 661 GenericFifo<uint64_t> 650 GenericFifo<uint64_t> m_cc_receive_to_multi_ack_fifo; 662 651 663 652 // Buffer between TGT_CMD fsm and TGT_RSP fsm … … 678 667 ////////////////////////////////////////////////// 679 668 680 sc_signal<int> 669 sc_signal<int> r_tgt_cmd_fsm; 681 670 682 671 /////////////////////////////////////////////////////// … … 684 673 /////////////////////////////////////////////////////// 685 674 686 sc_signal<int> r_config_fsm;// FSM state687 sc_signal<bool> r_config_lock;// lock protecting exclusive access688 sc_signal<int> r_config_cmd;// config request type689 sc_signal<addr_t> r_config_address;// target buffer physical address690 sc_signal<size_t> r_config_srcid;// config request srcid691 sc_signal<size_t> r_config_trdid;// config request trdid692 sc_signal<size_t> r_config_pktid;// config request pktid693 sc_signal<size_t> r_config_cmd_lines;// number of lines to be handled694 sc_signal<size_t> r_config_rsp_lines;// number of lines not completed695 sc_signal<size_t> r_config_dir_way;// DIR: selected way696 sc_signal<bool> r_config_dir_lock;// DIR: locked entry697 sc_signal<size_t> r_config_dir_count;// DIR: number of copies698 sc_signal<bool> r_config_dir_is_cnt;// DIR: counter mode (broadcast)699 sc_signal<size_t> r_config_dir_copy_srcid;// DIR: first copy SRCID700 sc_signal<bool> r_config_dir_copy_inst;// DIR: first copy L1 type701 sc_signal<size_t> r_config_dir_ptr;// DIR: index of next copy in HEAP702 sc_signal<size_t> r_config_heap_next;// current pointer to scan HEAP703 sc_signal<size_t> r_config_trt_index;// selected entry in TRT704 sc_signal<size_t> r_config_ivt_index;// selected entry in IVT675 sc_signal<int> r_config_fsm; // FSM state 676 sc_signal<bool> r_config_lock; // lock protecting exclusive access 677 sc_signal<int> r_config_cmd; // config request type 678 sc_signal<addr_t> r_config_address; // target buffer physical address 679 sc_signal<size_t> r_config_srcid; // config request srcid 680 sc_signal<size_t> r_config_trdid; // config request trdid 681 sc_signal<size_t> r_config_pktid; // config request pktid 682 sc_signal<size_t> r_config_cmd_lines; // number of lines to be handled 683 sc_signal<size_t> r_config_rsp_lines; // number of lines not completed 684 sc_signal<size_t> r_config_dir_way; // DIR: selected way 685 sc_signal<bool> r_config_dir_lock; // DIR: locked entry 686 sc_signal<size_t> r_config_dir_count; // DIR: number of copies 687 sc_signal<bool> r_config_dir_is_cnt; // DIR: counter mode (broadcast) 688 sc_signal<size_t> r_config_dir_copy_srcid; // DIR: first copy SRCID 689 sc_signal<bool> r_config_dir_copy_inst; // DIR: first copy L1 type 690 sc_signal<size_t> r_config_dir_ptr; // DIR: index of next copy in HEAP 691 sc_signal<size_t> r_config_heap_next; // current pointer to scan HEAP 692 sc_signal<size_t> r_config_trt_index; // selected entry in TRT 693 sc_signal<size_t> r_config_ivt_index; // selected entry in IVT 705 694 706 695 // Buffer between CONFIG fsm and IXR_CMD fsm 707 sc_signal<bool> r_config_to_ixr_cmd_req;// valid request708 sc_signal<size_t> r_config_to_ixr_cmd_index;// TRT index696 sc_signal<bool> r_config_to_ixr_cmd_req; // valid request 697 sc_signal<size_t> r_config_to_ixr_cmd_index; // TRT index 709 698 710 699 // Buffer between CONFIG fsm and TGT_RSP fsm (send a done response to L1 cache) 711 sc_signal<bool> r_config_to_tgt_rsp_req;// valid request712 sc_signal<bool> r_config_to_tgt_rsp_error;// error response713 sc_signal<size_t> r_config_to_tgt_rsp_srcid;// Transaction srcid714 sc_signal<size_t> r_config_to_tgt_rsp_trdid;// Transaction trdid715 sc_signal<size_t> r_config_to_tgt_rsp_pktid;// Transaction pktid700 sc_signal<bool> r_config_to_tgt_rsp_req; // valid request 701 sc_signal<bool> r_config_to_tgt_rsp_error; // error response 702 sc_signal<size_t> r_config_to_tgt_rsp_srcid; // Transaction srcid 703 sc_signal<size_t> r_config_to_tgt_rsp_trdid; // Transaction trdid 704 sc_signal<size_t> r_config_to_tgt_rsp_pktid; // Transaction pktid 716 705 717 706 // Buffer between CONFIG fsm and CC_SEND fsm (multi-inval / broadcast-inval) 718 sc_signal<bool> r_config_to_cc_send_multi_req; 719 sc_signal<bool> r_config_to_cc_send_brdcast_req; 720 sc_signal<addr_t> r_config_to_cc_send_nline; 721 sc_signal<size_t> r_config_to_cc_send_trdid; 722 GenericFifo<bool> m_config_to_cc_send_inst_fifo; 723 GenericFifo<size_t> m_config_to_cc_send_srcid_fifo; 707 sc_signal<bool> r_config_to_cc_send_multi_req; // multi-inval request 708 sc_signal<bool> r_config_to_cc_send_brdcast_req; // broadcast-inval request 709 sc_signal<addr_t> r_config_to_cc_send_nline; // line index 710 sc_signal<size_t> r_config_to_cc_send_trdid; // UPT index 711 GenericFifo<bool> m_config_to_cc_send_inst_fifo; // fifo for the L1 type 712 GenericFifo<size_t> m_config_to_cc_send_srcid_fifo; // fifo for owners srcid 724 713 725 714 /////////////////////////////////////////////////////// … … 727 716 /////////////////////////////////////////////////////// 728 717 729 sc_signal<int> r_read_fsm; 730 sc_signal<size_t> r_read_copy; 731 sc_signal<size_t> r_read_copy_cache; 732 sc_signal<bool> r_read_copy_inst; 733 sc_signal<tag_t> r_read_tag; 734 sc_signal<bool> r_read_is_cnt; 735 sc_signal<bool> r_read_lock; 736 sc_signal<bool> r_read_dirty; 737 sc_signal<size_t> r_read_count; 738 sc_signal<size_t> r_read_ptr; 739 sc_signal<data_t> * r_read_data; 740 sc_signal<size_t> r_read_way; 741 sc_signal<size_t> r_read_trt_index; 742 sc_signal<size_t> r_read_next_ptr; 743 sc_signal<bool> r_read_last_free; 744 sc_signal<addr_t> r_read_ll_key; 718 sc_signal<int> r_read_fsm; // FSM state 719 sc_signal<size_t> r_read_copy; // Srcid of the first copy 720 sc_signal<size_t> r_read_copy_cache; // Srcid of the first copy 721 sc_signal<bool> r_read_copy_inst; // Type of the first copy 722 sc_signal<tag_t> r_read_tag; // cache line tag (in directory) 723 sc_signal<bool> r_read_is_cnt; // is_cnt bit (in directory) 724 sc_signal<bool> r_read_lock; // lock bit (in directory) 725 sc_signal<bool> r_read_dirty; // dirty bit (in directory) 726 sc_signal<size_t> r_read_count; // number of copies 727 sc_signal<size_t> r_read_ptr; // pointer to the heap 728 sc_signal<data_t> * r_read_data; // data (one cache line) 729 sc_signal<size_t> r_read_way; // associative way (in cache) 730 sc_signal<size_t> r_read_trt_index; // Transaction Table index 731 sc_signal<size_t> r_read_next_ptr; // Next entry to point to 732 sc_signal<bool> r_read_last_free; // Last free entry 733 sc_signal<addr_t> r_read_ll_key; // LL key from llsc_global_table 745 734 746 735 // Buffer between READ fsm and IXR_CMD fsm 747 sc_signal<bool> r_read_to_ixr_cmd_req; 748 sc_signal<size_t> r_read_to_ixr_cmd_index; 736 sc_signal<bool> r_read_to_ixr_cmd_req; // valid request 737 sc_signal<size_t> r_read_to_ixr_cmd_index; // TRT index 749 738 750 739 // Buffer between READ fsm and TGT_RSP fsm (send a hit read response to L1 cache) 751 sc_signal<bool> r_read_to_tgt_rsp_req; 752 sc_signal<size_t> r_read_to_tgt_rsp_srcid; 753 sc_signal<size_t> r_read_to_tgt_rsp_trdid; 754 sc_signal<size_t> r_read_to_tgt_rsp_pktid; 755 sc_signal<data_t> * r_read_to_tgt_rsp_data; 756 sc_signal<size_t> r_read_to_tgt_rsp_word; 757 sc_signal<size_t> r_read_to_tgt_rsp_length; 758 sc_signal<addr_t> r_read_to_tgt_rsp_ll_key; 740 sc_signal<bool> r_read_to_tgt_rsp_req; // valid request 741 sc_signal<size_t> r_read_to_tgt_rsp_srcid; // Transaction srcid 742 sc_signal<size_t> r_read_to_tgt_rsp_trdid; // Transaction trdid 743 sc_signal<size_t> r_read_to_tgt_rsp_pktid; // Transaction pktid 744 sc_signal<data_t> * r_read_to_tgt_rsp_data; // data (one cache line) 745 sc_signal<size_t> r_read_to_tgt_rsp_word; // first word of the response 746 sc_signal<size_t> r_read_to_tgt_rsp_length; // length of the response 747 sc_signal<addr_t> r_read_to_tgt_rsp_ll_key; // LL key from llsc_global_table 759 748 760 749 //RWT: Buffer between READ fsm and CC_SEND fsm (send inval) … … 777 766 778 767 //RWT: 779 sc_signal<bool> r_read_coherent; 768 sc_signal<bool> r_read_coherent; // State of the cache slot after transaction 780 769 sc_signal<bool> r_read_ll_done; 781 770 … … 839 828 840 829 // RWT: Buffer between WRITE fsm and CLEANUP fsm (change slot state) 841 sc_signal<bool> r_write_to_cleanup_req; 842 sc_signal<addr_t> r_write_to_cleanup_nline; 830 sc_signal<bool> r_write_to_cleanup_req; // valid request 831 sc_signal<addr_t> r_write_to_cleanup_nline; // cache line index 843 832 844 833 // RWT 845 sc_signal<bool> r_write_coherent; 834 sc_signal<bool> r_write_coherent; // cache slot state after transaction 846 835 847 836 //Buffer between WRITE fsm and CC_SEND fsm (INVAL for RWT) … … 1114 1103 1115 1104 sc_signal<bool> r_cleanup_ncc; 1116 sc_signal<bool> r_cleanup_to_ixr_cmd_ncc_l1_dirty;1117 sc_signal<bool> r_xram_rsp_to_ixr_cmd_inval_ncc_pending;1118 1105 1119 1106 sc_signal<bool> r_cleanup_to_ixr_cmd_req; -
branches/RWT/modules/vci_mem_cache/caba/source/include/xram_transaction.h
r814 r823 15 15 class TransactionTabEntry 16 16 { 17 typedef sc_dt::sc_uint<64> 18 typedef sc_dt::sc_uint<40> 19 typedef uint32_t 20 typedef uint32_t 17 typedef sc_dt::sc_uint<64> wide_data_t; 18 typedef sc_dt::sc_uint<40> addr_t; 19 typedef uint32_t data_t; 20 typedef uint32_t be_t; 21 21 22 22 public: … … 154 154 class TransactionTab 155 155 { 156 typedef sc_dt::sc_uint<64> 157 typedef sc_dt::sc_uint<40> 158 typedef uint32_t 159 typedef uint32_t 156 typedef sc_dt::sc_uint<64> wide_data_t; 157 typedef sc_dt::sc_uint<40> addr_t; 158 typedef uint32_t data_t; 159 typedef uint32_t be_t; 160 160 161 161 private: 162 const std::string tab_name; 163 size_t size_tab; 162 const std::string tab_name; // the name for logs 163 size_t size_tab; // the size of the tab 164 164 165 165 data_t be_to_mask(be_t be) 166 166 { 167 167 data_t ret = 0; 168 if ( be&0x1) {168 if (be & 0x1) { 169 169 ret = ret | 0x000000FF; 170 170 } 171 if ( be&0x2) {171 if (be & 0x2) { 172 172 ret = ret | 0x0000FF00; 173 173 } 174 if ( be&0x4) {174 if (be & 0x4) { 175 175 ret = ret | 0x00FF0000; 176 176 } 177 if ( be&0x8) {177 if (be & 0x8) { 178 178 ret = ret | 0xFF000000; 179 179 } … … 189 189 TransactionTab() 190 190 { 191 size_tab =0;192 tab =NULL;191 size_tab = 0; 192 tab = NULL; 193 193 } 194 194 … … 196 196 size_t n_entries, 197 197 size_t n_words ) 198 : tab_name( name),199 size_tab( n_entries)198 : tab_name(name), 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(); … … 234 234 void print(const size_t index) 235 235 { 236 assert( 236 assert((index < size_tab) and 237 237 "MEMC ERROR: The selected entry is out of range in TRT write_data_mask()"); 238 238 … … 247 247 TransactionTabEntry read(const size_t index) 248 248 { 249 assert( 249 assert((index < size_tab) and 250 250 "MEMC ERROR: Invalid Transaction Tab Entry"); 251 251 … … 260 260 bool full(size_t &index) 261 261 { 262 for (size_t i=0; i<size_tab; i++)263 { 264 if (!tab[i].valid)262 for (size_t i = 0; i < size_tab; i++) 263 { 264 if (!tab[i].valid) 265 265 { 266 index =i;266 index = i; 267 267 return false; 268 268 } … … 278 278 // The function returns true if a read request has already been sent 279 279 ////////////////////////////////////////////////////////////////////// 280 bool hit_read(const addr_t nline, size_t &index)281 { 282 for (size_t i=0; i<size_tab; i++)283 { 284 if ((tab[i].valid && (nline==tab[i].nline)) && (tab[i].xram_read))280 bool hit_read(const addr_t nline, size_t &index) 281 { 282 for (size_t i = 0; i < size_tab; i++) 283 { 284 if ((tab[i].valid && (nline == tab[i].nline)) && (tab[i].xram_read)) 285 285 { 286 index =i;286 index = i; 287 287 return true; 288 288 } … … 299 299 bool hit_write(const addr_t nline) 300 300 { 301 for (size_t i=0; i<size_tab; i++)302 { 303 if(tab[i].valid && (nline ==tab[i].nline) && !(tab[i].xram_read))301 for (size_t i = 0; i < size_tab; i++) 302 { 303 if(tab[i].valid && (nline == tab[i].nline) && !(tab[i].xram_read)) 304 304 { 305 305 return true; … … 319 319 bool hit_write(const addr_t nline, size_t* index) 320 320 { 321 for (size_t i=0; i<size_tab; i++){322 if (tab[i].valid && (nline==tab[i].nline) && !(tab[i].xram_read)) {321 for (size_t i = 0; i < size_tab; i++){ 322 if (tab[i].valid && (nline == tab[i].nline) && !(tab[i].xram_read)) { 323 323 *index = i; 324 324 return true; … … 337 337 ///////////////////////////////////////////////////////////////////// 338 338 void write_data_mask(const size_t index, 339 const std::vector<be_t> &be,340 const std::vector<data_t> &data)341 { 342 assert( 339 const std::vector<be_t> &be, 340 const std::vector<data_t> &data) 341 { 342 assert((index < size_tab) and 343 343 "MEMC ERROR: The selected entry is out of range in TRT write_data_mask()"); 344 344 345 assert( (be.size()==tab[index].wdata_be.size()) and345 assert((be.size() == tab[index].wdata_be.size()) and 346 346 "MEMC ERROR: Bad be size in TRT write_data_mask()"); 347 347 348 assert( (data.size()==tab[index].wdata.size()) and348 assert((data.size() == tab[index].wdata.size()) 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]; … … 375 375 ///////////////////////////////////////////////////////////////////// 376 376 void set(const size_t index, 377 const bool xram_read,378 const addr_t nline,379 const size_t srcid,380 const size_t trdid,381 const size_t pktid,382 const bool proc_read,383 const size_t read_length,384 const size_t word_index,385 const std::vector<be_t> &data_be,386 const std::vector<data_t> &data,387 const data_t ll_key = 0,388 const bool config = false)389 { 390 assert( 377 const bool xram_read, 378 const addr_t nline, 379 const size_t srcid, 380 const size_t trdid, 381 const size_t pktid, 382 const bool proc_read, 383 const size_t read_length, 384 const size_t word_index, 385 const std::vector<be_t> &data_be, 386 const std::vector<data_t> &data, 387 const data_t ll_key = 0, 388 const bool config = false) 389 { 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()) and393 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()) and396 assert((data.size() == tab[index].wdata.size()) and 397 397 "MEMC ERROR: Bad data argument in TRT set()"); 398 398 … … 408 408 tab[index].ll_key = ll_key; 409 409 tab[index].config = config; 410 for (size_t i=0; i<tab[index].wdata.size(); i++)411 { 412 tab[index].wdata_be[i] 413 tab[index].wdata[i] 410 for (size_t i = 0; i < tab[index].wdata.size(); i++) 411 { 412 tab[index].wdata_be[i] = data_be[i]; 413 tab[index].wdata[i] = data[i]; 414 414 } 415 415 } … … 429 429 const bool rerror) 430 430 { 431 data_t 432 data_t 433 434 assert( 431 data_t value; 432 data_t mask; 433 434 assert((index < size_tab) and 435 435 "MEMC ERROR: The selected entry is out of range in TRT write_rsp()"); 436 436 437 assert( 437 assert((word < tab[index].wdata_be.size()) and 438 438 "MEMC ERROR: Bad word index in TRT write_rsp()"); 439 439 440 assert( 440 assert((tab[index].valid) and 441 441 "MEMC ERROR: TRT entry not valid in TRT write_rsp()"); 442 442 443 assert( 443 assert((tab[index].xram_read ) and 444 444 "MEMC ERROR: TRT entry is not a GET in TRT write_rsp()"); 445 445 446 if ( rerror)446 if (rerror) 447 447 { 448 448 tab[index].rerror = true; … … 456 456 457 457 // second 32 bits word 458 value = (data_t)(data >>32);459 mask = be_to_mask(tab[index].wdata_be[word +1]);460 tab[index].wdata[word +1] = (tab[index].wdata[word+1] & mask) | (value & ~mask);458 value = (data_t)(data >> 32); 459 mask = be_to_mask(tab[index].wdata_be[word + 1]); 460 tab[index].wdata[word + 1] = (tab[index].wdata[word + 1] & mask) | (value & ~mask); 461 461 } 462 462 ///////////////////////////////////////////////////////////////////// … … 467 467 void erase(const size_t index) 468 468 { 469 assert( 469 assert((index < size_tab) and 470 470 "MEMC ERROR: The selected entry is out of range in TRT erase()"); 471 471 … … 480 480 bool is_config(const size_t index) 481 481 { 482 assert( 482 assert((index < size_tab) and 483 483 "MEMC ERROR: The selected entry is out of range in TRT is_config()"); 484 484 -
branches/RWT/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp
r814 r823 1 1 /* -*- c++ -*- 2 * 3 * File : vci_mem_cache.cpp 4 * Date : 30/10/2008 5 * Copyright : UPMC / LIP6 6 * Authors : Alain Greiner / Eric Guthmuller 7 * 8 * SOCLIB_LGPL_HEADER_BEGIN 9 * 10 * This file is part of SoCLib, GNU LGPLv2.1. 11 * 12 * SoCLib is free software; you can redistribute it and/or modify it 13 * under the terms of the GNU Lesser General Public License as published 14 * by the Free Software Foundation; version 2.1 of the License. 15 * 16 * SoCLib is distributed in the hope that it will be useful, but 17 * WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 * Lesser General Public License for more details. 20 * 21 * You should have received a copy of the GNU Lesser General Public 22 * License along with SoCLib; if not, write to the Free Software 23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 24 * 02110-1301 USA 25 * 26 * SOCLIB_LGPL_HEADER_END 27 * 28 * Maintainers: alain.greiner@lip6.fr 29 * eric.guthmuller@polytechnique.edu 30 * cesar.fuguet-tortolero@lip6.fr 31 * alexandre.joannou@lip6.fr 32 */ 2 * 3 * File : vci_mem_cache.cpp 4 * Date : 30/10/2008 5 * Copyright : UPMC / LIP6 6 * Authors : Alain Greiner / Eric Guthmuller 7 * 8 * SOCLIB_LGPL_HEADER_BEGIN 9 * 10 * This file is part of SoCLib, GNU LGPLv2.1. 11 * 12 * SoCLib is free software; you can redistribute it and/or modify it 13 * under the terms of the GNU Lesser General Public License as published 14 * by the Free Software Foundation; version 2.1 of the License. 15 * 16 * SoCLib is distributed in the hope that it will be useful, but 17 * WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 * Lesser General Public License for more details. 20 * 21 * You should have received a copy of the GNU Lesser General Public 22 * License along with SoCLib; if not, write to the Free Software 23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 24 * 02110-1301 USA 25 * 26 * SOCLIB_LGPL_HEADER_END 27 * 28 * Maintainers: alain.greiner@lip6.fr 29 * eric.guthmuller@polytechnique.edu 30 * cesar.fuguet-tortolero@lip6.fr 31 * alexandre.joannou@lip6.fr 32 */ 33 33 34 34 35 #include "../include/vci_mem_cache.h" 36 #include "mem_cache.h" 35 37 36 38 ////// debug services ///////////////////////////////////////////////////////////// … … 96 98 "CC_RECEIVE_IDLE", 97 99 "CC_RECEIVE_CLEANUP", 98 "CC_RECEIVE_CLEANUP_EOP",99 100 "CC_RECEIVE_MULTI_ACK" 100 101 }; … … 203 204 { 204 205 "IXR_RSP_IDLE", 205 "IXR_RSP_ACK",206 206 "IXR_RSP_TRT_ERASE", 207 207 "IXR_RSP_TRT_READ" … … 355 355 356 356 tmpl(/**/) ::VciMemCache( 357 sc_module_name 358 const MappingTable &mtp,// mapping table for direct network359 const MappingTable &mtx,// mapping table for external network360 const IntTab &srcid_x,// global index on external network361 const IntTab &tgtid_d,// global index on direct network362 const size_t x_width,// number of x bits in platform363 const size_t y_width,// number of x bits in platform364 const size_t nways,// number of ways per set365 const size_t nsets,// number of associative sets366 const size_t nwords,// number of words in cache line367 const size_t max_copies,// max number of copies in heap368 const size_t heap_size,// number of heap entries369 const size_t trt_lines,// number of TRT entries370 const size_t upt_lines,// number of UPT entries371 const size_t ivt_lines,// number of IVT entries372 const size_t 373 const bool 357 sc_module_name name, 358 const MappingTable &mtp, // mapping table for direct network 359 const MappingTable &mtx, // mapping table for external network 360 const IntTab &srcid_x, // global index on external network 361 const IntTab &tgtid_d, // global index on direct network 362 const size_t x_width, // number of x bits in platform 363 const size_t y_width, // number of x bits in platform 364 const size_t nways, // number of ways per set 365 const size_t nsets, // number of associative sets 366 const size_t nwords, // number of words in cache line 367 const size_t max_copies, // max number of copies in heap 368 const size_t heap_size, // number of heap entries 369 const size_t trt_lines, // number of TRT entries 370 const size_t upt_lines, // number of UPT entries 371 const size_t ivt_lines, // number of IVT entries 372 const size_t debug_start_cycle, 373 const bool debug_ok) 374 374 375 375 : soclib::caba::BaseModule(name), 376 376 377 p_clk( "p_clk"),378 p_resetn( "p_resetn"),379 p_irq( "p_irq"),380 p_vci_tgt( "p_vci_tgt"),381 p_vci_ixr( "p_vci_ixr"),382 p_dspin_p2m( "p_dspin_p2m"),383 p_dspin_m2p( "p_dspin_m2p"),384 p_dspin_clack( "p_dspin_clack"),377 p_clk("p_clk"), 378 p_resetn("p_resetn"), 379 p_irq("p_irq"), 380 p_vci_tgt("p_vci_tgt"), 381 p_vci_ixr("p_vci_ixr"), 382 p_dspin_p2m("p_dspin_p2m"), 383 p_dspin_m2p("p_dspin_m2p"), 384 p_dspin_clack("p_dspin_clack"), 385 385 386 386 m_seglist(mtp.getSegmentList(tgtid_d)), 387 387 m_nseg(0), 388 m_srcid_x( 388 m_srcid_x(mtx.indexForId(srcid_x)), 389 389 m_initiators(1 << vci_param_int::S), 390 390 m_heap_size(heap_size), … … 394 394 m_x_width(x_width), 395 395 m_y_width(y_width), 396 m_debug_start_cycle( debug_start_cycle),397 m_debug_ok( debug_ok),396 m_debug_start_cycle(debug_start_cycle), 397 m_debug_ok(debug_ok), 398 398 m_trt_lines(trt_lines), 399 399 m_trt(this->name(), trt_lines, nwords), … … 404 404 m_cache_data(nways, nsets, nwords), 405 405 m_heap(m_heap_size), 406 m_max_copies( max_copies),406 m_max_copies(max_copies), 407 407 m_llsc_table(), 408 408 … … 419 419 420 420 // CONFIG interface 421 m_config_addr_mask((1 <<12)-1),421 m_config_addr_mask((1 << 12) - 1), 422 422 423 423 m_config_regr_width(7), 424 424 m_config_func_width(3), 425 m_config_regr_idx_mask((1 <<m_config_regr_width)-1),426 m_config_func_idx_mask((1 <<m_config_func_width)-1),425 m_config_regr_idx_mask((1 << m_config_regr_width) - 1), 426 m_config_func_idx_mask((1 << m_config_func_width) - 1), 427 427 428 428 // FIFOs … … 453 453 r_tgt_cmd_fsm("r_tgt_cmd_fsm"), 454 454 455 r_config_fsm( "r_config_fsm"),456 457 m_config_to_cc_send_inst_fifo( "m_config_to_cc_send_inst_fifo", 8),458 m_config_to_cc_send_srcid_fifo( "m_config_to_cc_send_srcid_fifo", 8),459 460 r_read_fsm( "r_read_fsm"),461 462 r_write_fsm( "r_write_fsm"),455 r_config_fsm("r_config_fsm"), 456 457 m_config_to_cc_send_inst_fifo("m_config_to_cc_send_inst_fifo", 8), 458 m_config_to_cc_send_srcid_fifo("m_config_to_cc_send_srcid_fifo", 8), 459 460 r_read_fsm("r_read_fsm"), 461 462 r_write_fsm("r_write_fsm"), 463 463 464 464 m_write_to_cc_send_inst_fifo("m_write_to_cc_send_inst_fifo",8), … … 495 495 r_alloc_heap_reset_cpt("r_alloc_heap_reset_cpt") 496 496 #if MONITOR_MEMCACHE_FSM == 1 497 497 , 498 498 p_read_fsm("p_read_fsm"), 499 499 p_write_fsm("p_write_fsm"), … … 530 530 531 531 // check internal and external data width 532 assert( (vci_param_int::B == 4) and532 assert((vci_param_int::B == 4) and 533 533 "MEMC ERROR : VCI internal data width must be 32 bits"); 534 534 535 assert( 535 assert((vci_param_ext::B == 8) and 536 536 "MEMC ERROR : VCI external data width must be 64 bits"); 537 537 538 538 // Check coherence between internal & external addresses 539 assert( 539 assert((vci_param_int::N == vci_param_ext::N) and 540 540 "MEMC ERROR : VCI internal & external addresses must have the same width"); 541 541 … … 544 544 size_t i = 0; 545 545 546 for (seg = m_seglist.begin(); seg != m_seglist.end(); seg++)546 for (seg = m_seglist.begin(); seg != m_seglist.end(); seg++) 547 547 { 548 548 std::cout << " => segment " << seg->name() … … 552 552 } 553 553 554 assert( 554 assert((m_nseg > 0) and 555 555 "MEMC ERROR : At least one segment must be mapped to this component"); 556 556 557 557 m_seg = new soclib::common::Segment*[m_nseg]; 558 558 559 for (seg = m_seglist.begin() ; seg != m_seglist.end(); seg++)560 { 561 if ( seg->special()) m_seg_config = i;559 for (seg = m_seglist.begin(); seg != m_seglist.end(); seg++) 560 { 561 if (seg->special()) m_seg_config = i; 562 562 m_seg[i] = & (*seg); 563 563 i++; … … 574 574 r_xram_rsp_victim_data = new sc_signal<data_t>[nwords]; 575 575 r_xram_rsp_to_tgt_rsp_data = new sc_signal<data_t>[nwords]; 576 //r_xram_rsp_to_ixr_cmd_data = new sc_signal<data_t>[nwords];577 576 578 577 // Allocation for READ FSM … … 585 584 r_write_to_cc_send_data = new sc_signal<data_t>[nwords]; 586 585 r_write_to_cc_send_be = new sc_signal<be_t>[nwords]; 587 //r_write_to_ixr_cmd_data = new sc_signal<data_t>[nwords];588 586 589 587 // Allocation for CAS FSM 590 //r_cas_to_ixr_cmd_data = new sc_signal<data_t>[nwords];591 588 r_cas_data = new sc_signal<data_t>[nwords]; 592 589 r_cas_rdata = new sc_signal<data_t>[2]; … … 624 621 bool data_change = false; 625 622 626 if ( entry.valid)623 if (entry.valid) 627 624 { 628 for ( size_t word = 0 ; word<m_words ; word++)625 for (size_t word = 0; word < m_words; word++) 629 626 { 630 627 m_debug_data[word] = m_cache_data.read(way, set, word); 631 if ( 632 (m_debug_data[word] != m_debug_previous_data[word]))628 if (m_debug_previous_valid and 629 (m_debug_data[word] != m_debug_previous_data[word])) 633 630 { 634 631 data_change = true; … … 638 635 639 636 // print values if any change 640 if ( 641 642 (entry.valid and (entry.dirty != m_debug_previous_dirty)) or data_change)637 if ((entry.valid != m_debug_previous_valid) or 638 (entry.valid and (entry.count != m_debug_previous_count)) or 639 (entry.valid and (entry.dirty != m_debug_previous_dirty)) or data_change) 643 640 { 644 641 std::cout << "Monitor MEMC " << name() … … 672 669 m_debug_previous_valid = entry.valid; 673 670 m_debug_previous_dirty = entry.dirty; 674 for ( size_t word=0 ; word<m_words ; word++)671 for (size_t word = 0; word < m_words; word++) 675 672 m_debug_previous_data[word] = m_debug_data[word]; 676 673 } … … 814 811 815 812 ////////////////////////////////////////////////// 816 tmpl(void)::print_trace( size_t detailed)813 tmpl(void)::print_trace(size_t detailed) 817 814 ////////////////////////////////////////////////// 818 815 { … … 837 834 << " | " << alloc_heap_fsm_str[r_alloc_heap_fsm.read()] << std::endl; 838 835 839 if ( detailed) m_trt.print(0);836 if (detailed) m_trt.print(0); 840 837 } 841 838 … … 910 907 std::cout << "*** MEM_CACHE " << name() << std::endl; 911 908 std::cout << "**********************************" << std::dec << std::endl; 912 if (activity_counters) { 909 if (activity_counters) 910 { 913 911 std::cout << "----------------------------------" << std::dec << std::endl; 914 912 std::cout << "--- Activity Counters ---" << std::dec << std::endl; … … 1026 1024 1027 1025 // RESET 1028 if (!p_resetn.read())1026 if (!p_resetn.read()) 1029 1027 { 1030 1028 … … 1075 1073 m_cmd_write_data_fifo.init(); 1076 1074 1077 m_cmd_cas_addr_fifo.init() 1078 m_cmd_cas_srcid_fifo.init() 1079 m_cmd_cas_trdid_fifo.init() 1080 m_cmd_cas_pktid_fifo.init() 1081 m_cmd_cas_wdata_fifo.init() 1082 m_cmd_cas_eop_fifo.init() 1075 m_cmd_cas_addr_fifo.init(); 1076 m_cmd_cas_srcid_fifo.init(); 1077 m_cmd_cas_trdid_fifo.init(); 1078 m_cmd_cas_pktid_fifo.init(); 1079 m_cmd_cas_wdata_fifo.init(); 1080 m_cmd_cas_eop_fifo.init(); 1083 1081 1084 1082 r_config_cmd = MEMC_CMD_NOP; … … 1095 1093 r_read_to_cleanup_req = false; 1096 1094 1097 r_write_to_tgt_rsp_req 1098 r_write_to_ixr_cmd_req 1099 r_write_to_cc_send_multi_req 1100 r_write_to_cc_send_brdcast_req 1101 r_write_to_multi_ack_req 1095 r_write_to_tgt_rsp_req = false; 1096 r_write_to_ixr_cmd_req = false; 1097 r_write_to_cc_send_multi_req = false; 1098 r_write_to_cc_send_brdcast_req = false; 1099 r_write_to_multi_ack_req = false; 1102 1100 1103 1101 m_write_to_cc_send_inst_fifo.init(); … … 1108 1106 m_cc_receive_to_cleanup_fifo.init(); 1109 1107 1110 r_multi_ack_to_tgt_rsp_req 1108 r_multi_ack_to_tgt_rsp_req = false; 1111 1109 1112 1110 m_cc_receive_to_multi_ack_fifo.init(); … … 1121 1119 m_cas_to_cc_send_inst_fifo.init(); 1122 1120 m_cas_to_cc_send_srcid_fifo.init(); 1123 #if L1_MULTI_CACHE 1124 m_cas_to_cc_send_cache_id_fifo.init(); 1125 #endif 1126 1127 for(size_t i=0; i<m_trt_lines ; i++) 1121 1122 for (size_t i = 0; i < m_trt_lines; i++) 1128 1123 { 1129 1124 r_ixr_rsp_to_xram_rsp_rok[i] = false; … … 1152 1147 r_cleanup_contains_data = false; 1153 1148 r_cleanup_ncc = false; 1154 r_cleanup_to_ixr_cmd_ncc_l1_dirty = false;1155 r_xram_rsp_to_ixr_cmd_inval_ncc_pending = false;1156 1149 r_cleanup_to_ixr_cmd_req = false; 1157 1150 r_cleanup_to_ixr_cmd_srcid = 0; … … 1166 1159 1167 1160 // Activity counters 1161 m_cpt_cycles = 0; 1168 1162 m_cpt_reset_count = 0; 1169 m_cpt_cycles = 0;1170 1163 m_cpt_read_local = 0; 1171 1164 m_cpt_read_remote = 0; … … 1220 1213 m_cpt_put = 0; 1221 1214 1222 m_cpt_ncc_to_cc_read = 0; 1223 m_cpt_ncc_to_cc_write = 0; 1215 m_cpt_ncc_to_cc_read = 0; 1216 m_cpt_ncc_to_cc_write = 0; 1217 1218 m_cpt_dir_unused = 0; 1219 m_cpt_upt_unused = 0; 1220 m_cpt_ivt_unused = 0; 1221 m_cpt_heap_unused = 0; 1222 m_cpt_trt_unused = 0; 1224 1223 1225 1224 m_cpt_heap_min_slot_available = m_heap_size; 1226 1225 m_cpt_heap_slot_available = m_heap_size; 1227 1226 1228 m_cpt_dir_unused = 0;1229 m_cpt_upt_unused = 0;1230 m_cpt_ivt_unused = 0;1231 m_cpt_heap_unused = 0;1232 m_cpt_trt_unused = 0;1233 1234 // Unused1235 m_cpt_read_data_unc = 0;1236 m_cpt_read_data_miss_CC = 0;1237 m_cpt_read_ins_unc = 0;1238 m_cpt_read_ins_miss = 0;1239 m_cpt_read_ll_CC = 0;1240 m_cpt_read_data_miss_NCC = 0;1241 m_cpt_read_ll_NCC = 0;1242 1243 1227 return; 1244 1228 } 1245 1229 1246 bool 1247 bool 1248 1249 bool 1250 bool 1251 1252 bool 1253 bool 1254 1255 bool 1256 bool 1257 1258 bool 1259 bool 1260 1261 bool 1262 bool 1263 bool 1264 size_t 1265 1266 bool 1267 bool 1268 bool 1269 size_t 1230 bool cmd_read_fifo_put = false; 1231 bool cmd_read_fifo_get = false; 1232 1233 bool cmd_write_fifo_put = false; 1234 bool cmd_write_fifo_get = false; 1235 1236 bool cmd_cas_fifo_put = false; 1237 bool cmd_cas_fifo_get = false; 1238 1239 bool cc_receive_to_cleanup_fifo_get = false; 1240 bool cc_receive_to_cleanup_fifo_put = false; 1241 1242 bool cc_receive_to_multi_ack_fifo_get = false; 1243 bool cc_receive_to_multi_ack_fifo_put = false; 1244 1245 bool write_to_cc_send_fifo_put = false; 1246 bool write_to_cc_send_fifo_get = false; 1247 bool write_to_cc_send_fifo_inst = false; 1248 size_t write_to_cc_send_fifo_srcid = 0; 1249 1250 bool xram_rsp_to_cc_send_fifo_put = false; 1251 bool xram_rsp_to_cc_send_fifo_get = false; 1252 bool xram_rsp_to_cc_send_fifo_inst = false; 1253 size_t xram_rsp_to_cc_send_fifo_srcid = 0; 1270 1254 1271 1255 bool config_rsp_lines_incr = false; … … 1273 1257 bool config_rsp_lines_ixr_rsp_decr = false; 1274 1258 1275 bool 1276 bool 1277 bool 1278 size_t 1279 1280 bool 1281 bool 1282 bool 1283 size_t 1259 bool config_to_cc_send_fifo_put = false; 1260 bool config_to_cc_send_fifo_get = false; 1261 bool config_to_cc_send_fifo_inst = false; 1262 size_t config_to_cc_send_fifo_srcid = 0; 1263 1264 bool cas_to_cc_send_fifo_put = false; 1265 bool cas_to_cc_send_fifo_get = false; 1266 bool cas_to_cc_send_fifo_inst = false; 1267 size_t cas_to_cc_send_fifo_srcid = 0; 1284 1268 1285 1269 m_debug = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 1286 1270 1287 1271 #if DEBUG_MEMC_GLOBAL 1288 if (m_debug)1272 if (m_debug) 1289 1273 { 1290 1274 std::cout … … 1336 1320 ////////////////// 1337 1321 case TGT_CMD_IDLE: // waiting a VCI command (RAM or CONFIG) 1338 if(p_vci_tgt.cmdval) 1339 { 1340 1341 1322 if (p_vci_tgt.cmdval) 1323 { 1342 1324 #if DEBUG_MEMC_TGT_CMD 1343 if(m_debug) 1325 if (m_debug) 1326 { 1344 1327 std::cout << " <MEMC " << name() 1345 1328 << " TGT_CMD_IDLE> Receive command from srcid " 1346 1329 << std::hex << p_vci_tgt.srcid.read() 1347 1330 << " / address " << std::hex << p_vci_tgt.address.read() << std::endl; 1331 } 1348 1332 #endif 1349 1333 // checking segmentation violation … … 1352 1336 bool config = false; 1353 1337 1354 for (size_t seg_id = 0; (seg_id < m_nseg); seg_id++)1338 for (size_t seg_id = 0; seg_id < m_nseg; seg_id++) 1355 1339 { 1356 1340 if (m_seg[seg_id]->contains(address) && 1357 m_seg[seg_id]->contains(address + plen - vci_param_int::B) 1341 m_seg[seg_id]->contains(address + plen - vci_param_int::B)) 1358 1342 { 1359 if ( m_seg[seg_id]->special()) config = true;1343 if (m_seg[seg_id]->special()) config = true; 1360 1344 } 1361 1345 } 1362 1346 1363 if (config) 1347 if (config) /////////// configuration command 1364 1348 { 1365 1349 if (!p_vci_tgt.eop.read()) r_tgt_cmd_fsm = TGT_CMD_ERROR; 1366 1350 else r_tgt_cmd_fsm = TGT_CMD_CONFIG; 1367 1351 } 1368 else 1369 { 1370 if ( p_vci_tgt.cmd.read() == vci_param_int::CMD_READ)1352 else //////////// memory access 1353 { 1354 if (p_vci_tgt.cmd.read() == vci_param_int::CMD_READ) 1371 1355 { 1372 1356 // check that the pktid is either : … … 1377 1361 // ==> bit2 must be zero with the TSAR encoding 1378 1362 // ==> mask = 0b0100 = 0x4 1379 assert( 1363 assert(((p_vci_tgt.pktid.read() & 0x4) == 0x0) and 1380 1364 "The type specified in the pktid field is incompatible with the READ CMD"); 1381 1365 r_tgt_cmd_fsm = TGT_CMD_READ; 1382 1366 } 1383 else if (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)1367 else if (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) 1384 1368 { 1385 1369 // check that the pktid is TYPE_WRITE … … 1390 1374 r_tgt_cmd_fsm = TGT_CMD_WRITE; 1391 1375 } 1392 else if (p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ)1376 else if (p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ) 1393 1377 { 1394 1378 // check that the pktid is TYPE_LL … … 1399 1383 r_tgt_cmd_fsm = TGT_CMD_READ; 1400 1384 } 1401 else if (p_vci_tgt.cmd.read() == vci_param_int::CMD_NOP)1385 else if (p_vci_tgt.cmd.read() == vci_param_int::CMD_NOP) 1402 1386 { 1403 1387 // check that the pktid is either : … … 1410 1394 "The type specified in the pktid field is incompatible with the NOP CMD"); 1411 1395 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; 1396 if ((p_vci_tgt.pktid.read() & 0x7) == TYPE_CAS) 1397 { 1398 r_tgt_cmd_fsm = TGT_CMD_CAS; 1399 } 1400 else 1401 { 1402 r_tgt_cmd_fsm = TGT_CMD_WRITE; 1403 } 1414 1404 } 1415 1405 else … … 1425 1415 1426 1416 // wait if pending request 1427 if (r_tgt_cmd_to_tgt_rsp_req.read()) break;1417 if (r_tgt_cmd_to_tgt_rsp_req.read()) break; 1428 1418 1429 1419 // consume all the command packet flits before sending response error 1430 if ( p_vci_tgt.cmdval and p_vci_tgt.eop)1420 if (p_vci_tgt.cmdval and p_vci_tgt.eop) 1431 1421 { 1432 1422 r_tgt_cmd_to_tgt_rsp_srcid = p_vci_tgt.srcid.read(); … … 1438 1428 1439 1429 #if DEBUG_MEMC_TGT_CMD 1440 if(m_debug) 1430 if (m_debug) 1431 { 1441 1432 std::cout << " <MEMC " << name() 1442 1433 << " TGT_CMD_ERROR> Segmentation violation:" … … 1446 1437 << " / pktid = " << p_vci_tgt.pktid.read() 1447 1438 << " / plen = " << std::dec << p_vci_tgt.plen.read() << std::endl; 1448 #endif 1449 1439 } 1440 #endif 1450 1441 } 1451 1442 break; … … 1453 1444 //////////////////// 1454 1445 case TGT_CMD_CONFIG: // execute config request and return response 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 // Y : SUBTYPE ( LOCAL, REMOTE, OTHER )//1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 addr_t addr_lsb = p_vci_tgt.address.read() &1501 m_config_addr_mask; 1502 1503 addr_t cell = (addr_lsb / vci_param_int::B); 1504 1505 size_t regr = cell & 1506 m_config_regr_idx_mask;1507 1508 size_t func = (cell >> m_config_regr_width) &1509 m_config_func_idx_mask;1510 1511 bool need_rsp;1512 int error; 1513 uint32_t rdata = 0; // default value1514 uint32_t wdata = p_vci_tgt.wdata.read();1515 1516 switch(func)1517 { 1518 // memory operation1519 case MEMC_CONFIG:1446 { 1447 /////////////////////////////////////////////////////////// 1448 // Decoding CONFIG interface commands // 1449 // // 1450 // VCI ADDRESS // 1451 // ================================================ // 1452 // GLOBAL | LOCAL | ... | FUNC_IDX | REGS_IDX | 00 // 1453 // IDX | IDX | | (3 bits) | (7 bits) | // 1454 // ================================================ // 1455 // // 1456 // For instrumentation : FUNC_IDX = 0b001 // 1457 // // 1458 // REGS_IDX // 1459 // ============================================ // 1460 // Z | Y | X | W // 1461 // (1 bit) | (2 bits) | (3 bits) | (1 bit) // 1462 // ============================================ // 1463 // // 1464 // Z : DIRECT / COHERENCE // 1465 // Y : SUBTYPE (LOCAL, REMOTE, OTHER) // 1466 // X : REGISTER INDEX // 1467 // W : HI / LO // 1468 // // 1469 // For configuration: FUNC_IDX = 0b000 // 1470 // // 1471 // REGS_IDX // 1472 // ============================================ // 1473 // RESERVED | X | // 1474 // (4 bits) | (3 bits) | // 1475 // ============================================ // 1476 // // 1477 // X : REGISTER INDEX // 1478 // // 1479 // For WRITE MISS error signaling: FUNC = 0x010 // 1480 // // 1481 // REGS_IDX // 1482 // ============================================ // 1483 // RESERVED | X | // 1484 // (4 bits) | (3 bits) | // 1485 // ============================================ // 1486 // // 1487 // X : REGISTER INDEX // 1488 // // 1489 /////////////////////////////////////////////////////////// 1490 1491 addr_t addr_lsb = p_vci_tgt.address.read() & m_config_addr_mask; 1492 1493 addr_t cell = (addr_lsb / vci_param_int::B); 1494 1495 size_t regr = cell & m_config_regr_idx_mask; 1496 1497 size_t func = (cell >> m_config_regr_width) & m_config_func_idx_mask; 1498 1499 bool need_rsp; 1500 int error; 1501 uint32_t rdata = 0; // default value 1502 uint32_t wdata = p_vci_tgt.wdata.read(); 1503 1504 switch (func) 1505 { 1506 // memory operation 1507 case MEMC_CONFIG: 1508 { 1509 if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_READ) // get lock 1510 and (regr == MEMC_LOCK)) 1520 1511 { 1521 if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_READ) // get lock 1522 and (regr == MEMC_LOCK)) 1523 { 1524 rdata = (uint32_t) r_config_lock.read(); 1525 need_rsp = true; 1526 error = 0; 1527 r_config_lock = true; 1528 } 1529 else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // release lock 1530 and (regr == MEMC_LOCK)) 1531 { 1532 need_rsp = true; 1533 error = 0; 1534 r_config_lock = false; 1535 } 1536 else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // set addr_lo 1537 and (regr == MEMC_ADDR_LO)) 1538 { 1539 assert( ((wdata % (m_words * vci_param_int::B)) == 0) and 1540 "VCI_MEM_CACHE CONFIG ERROR: The buffer must be aligned on a cache line"); 1541 1542 need_rsp = true; 1543 error = 0; 1544 r_config_address = (r_config_address.read() & 0xFFFFFFFF00000000LL) | 1545 ((addr_t)wdata); 1546 } 1547 else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // set addr_hi 1548 and (regr == MEMC_ADDR_HI)) 1549 1550 { 1551 need_rsp = true; 1552 error = 0; 1553 r_config_address = (r_config_address.read() & 0x00000000FFFFFFFFLL) | 1554 (((addr_t) wdata) << 32); 1555 } 1556 else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // set buf_lines 1557 and (regr == MEMC_BUF_LENGTH)) 1558 { 1559 need_rsp = true; 1560 error = 0; 1561 size_t lines = wdata / (m_words << 2); 1562 if (wdata % (m_words << 2)) lines++; 1563 r_config_cmd_lines = lines; 1564 r_config_rsp_lines = 0; 1565 } 1566 else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // set cmd type 1567 and (regr == MEMC_CMD_TYPE)) 1568 { 1569 need_rsp = false; 1570 error = 0; 1571 r_config_cmd = wdata; 1572 1573 // prepare delayed response from CONFIG FSM 1574 r_config_srcid = p_vci_tgt.srcid.read(); 1575 r_config_trdid = p_vci_tgt.trdid.read(); 1576 r_config_pktid = p_vci_tgt.pktid.read(); 1577 } 1578 else 1579 { 1580 need_rsp = true; 1581 error = 1; 1582 } 1583 1584 break; 1512 rdata = (uint32_t) r_config_lock.read(); 1513 need_rsp = true; 1514 error = 0; 1515 r_config_lock = true; 1585 1516 } 1586 1587 // instrumentation registers 1588 case MEMC_INSTRM: 1589 { 1590 need_rsp = true; 1591 1592 if (p_vci_tgt.cmd.read() == vci_param_int::CMD_READ) 1593 { 1594 error = read_instrumentation(regr, rdata); 1595 } 1596 else 1597 { 1598 error = 1; 1599 } 1600 1601 break; 1602 } 1603 1604 // xram GET bus error registers 1605 case MEMC_RERROR: 1517 else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // release lock 1518 and (regr == MEMC_LOCK)) 1606 1519 { 1607 1520 need_rsp = true; 1608 1521 error = 0; 1609 1610 if (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) 1611 { 1612 switch (regr) 1613 { 1614 case MEMC_RERROR_IRQ_ENABLE: 1615 r_xram_rsp_rerror_irq_enable = 1616 (p_vci_tgt.wdata.read() != 0); 1617 1618 break; 1619 1620 default: 1621 error = 1; 1622 break; 1623 } 1624 } 1625 else if (p_vci_tgt.cmd.read() == vci_param_int::CMD_READ) 1626 { 1627 switch (regr) 1628 { 1629 case MEMC_RERROR_SRCID: 1630 rdata = (uint32_t) 1631 r_xram_rsp_rerror_rsrcid.read(); 1632 1633 break; 1634 1635 case MEMC_RERROR_ADDR_LO: 1636 rdata = (uint32_t) 1637 (r_xram_rsp_rerror_address.read()) & 1638 ((1ULL<<32)-1); 1639 1640 break; 1641 1642 case MEMC_RERROR_ADDR_HI: 1643 rdata = (uint32_t) 1644 (r_xram_rsp_rerror_address.read() >> 32) & 1645 ((1ULL<<32)-1); 1646 1647 break; 1648 1649 case MEMC_RERROR_IRQ_RESET: 1650 if (not r_xram_rsp_rerror_irq.read()) break; 1651 1652 r_xram_rsp_rerror_irq = false; 1653 1654 break; 1655 1656 case MEMC_RERROR_IRQ_ENABLE: 1657 rdata = (uint32_t) 1658 (r_xram_rsp_rerror_irq_enable.read()) ? 1 : 0; 1659 1660 break; 1661 1662 default: 1663 error = 1; 1664 break; 1665 } 1666 } 1667 else 1668 { 1669 error = 1; 1670 } 1671 1672 break; 1522 r_config_lock = false; 1673 1523 } 1674 1675 //unknown function 1676 default: 1524 else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // set addr_lo 1525 and (regr == MEMC_ADDR_LO)) 1526 { 1527 assert(((wdata % (m_words * vci_param_int::B)) == 0) and 1528 "VCI_MEM_CACHE CONFIG ERROR: The buffer must be aligned on a cache line"); 1529 1530 need_rsp = true; 1531 error = 0; 1532 r_config_address = (r_config_address.read() & 0xFFFFFFFF00000000LL) | 1533 ((addr_t)wdata); 1534 } 1535 else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // set addr_hi 1536 and (regr == MEMC_ADDR_HI)) 1537 1538 { 1539 need_rsp = true; 1540 error = 0; 1541 r_config_address = (r_config_address.read() & 0x00000000FFFFFFFFLL) | 1542 (((addr_t) wdata) << 32); 1543 } 1544 else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // set buf_lines 1545 and (regr == MEMC_BUF_LENGTH)) 1546 { 1547 need_rsp = true; 1548 error = 0; 1549 size_t lines = wdata / (m_words << 2); 1550 if (wdata % (m_words << 2)) lines++; 1551 r_config_cmd_lines = lines; 1552 r_config_rsp_lines = 0; 1553 } 1554 else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // set cmd type 1555 and (regr == MEMC_CMD_TYPE)) 1556 { 1557 need_rsp = false; 1558 error = 0; 1559 r_config_cmd = wdata; 1560 1561 // prepare delayed response from CONFIG FSM 1562 r_config_srcid = p_vci_tgt.srcid.read(); 1563 r_config_trdid = p_vci_tgt.trdid.read(); 1564 r_config_pktid = p_vci_tgt.pktid.read(); 1565 } 1566 else 1677 1567 { 1678 1568 need_rsp = true; 1679 1569 error = 1; 1680 1681 break;1682 1570 } 1683 } 1684 1685 if (need_rsp) 1686 { 1687 // blocked if previous pending request to TGT_RSP FSM 1688 if (r_tgt_cmd_to_tgt_rsp_req.read()) break; 1689 1690 r_tgt_cmd_to_tgt_rsp_srcid = p_vci_tgt.srcid.read(); 1691 r_tgt_cmd_to_tgt_rsp_trdid = p_vci_tgt.trdid.read(); 1692 r_tgt_cmd_to_tgt_rsp_pktid = p_vci_tgt.pktid.read(); 1693 r_tgt_cmd_to_tgt_rsp_req = true; 1694 r_tgt_cmd_to_tgt_rsp_error = error; 1695 r_tgt_cmd_to_tgt_rsp_rdata = rdata; 1696 } 1697 1698 r_tgt_cmd_fsm = TGT_CMD_IDLE; 1571 1572 break; 1573 } 1574 1575 // instrumentation registers 1576 case MEMC_INSTRM: 1577 { 1578 need_rsp = true; 1579 1580 if (p_vci_tgt.cmd.read() == vci_param_int::CMD_READ) 1581 { 1582 error = read_instrumentation(regr, rdata); 1583 } 1584 else 1585 { 1586 error = 1; 1587 } 1588 1589 break; 1590 } 1591 1592 // xram GET bus error registers 1593 case MEMC_RERROR: 1594 { 1595 need_rsp = true; 1596 error = 0; 1597 1598 if (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) 1599 { 1600 switch (regr) 1601 { 1602 case MEMC_RERROR_IRQ_ENABLE: 1603 r_xram_rsp_rerror_irq_enable = 1604 (p_vci_tgt.wdata.read() != 0); 1605 1606 break; 1607 1608 default: 1609 error = 1; 1610 break; 1611 } 1612 } 1613 else if (p_vci_tgt.cmd.read() == vci_param_int::CMD_READ) 1614 { 1615 switch (regr) 1616 { 1617 case MEMC_RERROR_SRCID: 1618 rdata = (uint32_t) 1619 r_xram_rsp_rerror_rsrcid.read(); 1620 break; 1621 1622 case MEMC_RERROR_ADDR_LO: 1623 rdata = (uint32_t) 1624 (r_xram_rsp_rerror_address.read()) & ((1ULL << 32) - 1); 1625 break; 1626 1627 case MEMC_RERROR_ADDR_HI: 1628 rdata = (uint32_t) 1629 (r_xram_rsp_rerror_address.read() >> 32) & ((1ULL << 32) - 1); 1630 break; 1631 1632 case MEMC_RERROR_IRQ_RESET: 1633 if (not r_xram_rsp_rerror_irq.read()) break; 1634 r_xram_rsp_rerror_irq = false; 1635 break; 1636 1637 case MEMC_RERROR_IRQ_ENABLE: 1638 rdata = (uint32_t) (r_xram_rsp_rerror_irq_enable.read()) ? 1 : 0; 1639 break; 1640 1641 default: 1642 error = 1; 1643 break; 1644 } 1645 } 1646 else 1647 { 1648 error = 1; 1649 } 1650 1651 break; 1652 } 1653 1654 //unknown function 1655 default: 1656 { 1657 need_rsp = true; 1658 error = 1; 1659 break; 1660 } 1661 } 1662 1663 if (need_rsp) 1664 { 1665 // blocked if previous pending request to TGT_RSP FSM 1666 if (r_tgt_cmd_to_tgt_rsp_req.read()) break; 1667 1668 r_tgt_cmd_to_tgt_rsp_srcid = p_vci_tgt.srcid.read(); 1669 r_tgt_cmd_to_tgt_rsp_trdid = p_vci_tgt.trdid.read(); 1670 r_tgt_cmd_to_tgt_rsp_pktid = p_vci_tgt.pktid.read(); 1671 r_tgt_cmd_to_tgt_rsp_req = true; 1672 r_tgt_cmd_to_tgt_rsp_error = error; 1673 r_tgt_cmd_to_tgt_rsp_rdata = rdata; 1674 } 1675 1676 r_tgt_cmd_fsm = TGT_CMD_IDLE; 1699 1677 1700 1678 #if DEBUG_MEMC_TGT_CMD 1701 if (m_debug) 1702 std::cout << " <MEMC " << name() << " TGT_CMD_CONFIG> Configuration request:" 1703 << " address = " << std::hex << p_vci_tgt.address.read() 1704 << " / func = " << func 1705 << " / regr = " << regr 1706 << " / rdata = " << rdata 1707 << " / wdata = " << p_vci_tgt.wdata.read() 1708 << " / need_rsp = " << need_rsp 1709 << " / error = " << error << std::endl; 1710 #endif 1711 break; 1712 } 1713 1714 #if 0 1715 case TGT_CMD_CONFIG: // execute config request and return response 1716 { 1717 addr_t seg_base = m_seg[m_seg_config]->baseAddress(); 1718 addr_t address = p_vci_tgt.address.read(); 1719 size_t cell = (address - seg_base)/vci_param_int::B; 1720 1721 bool need_rsp; 1722 size_t error; 1723 uint32_t rdata = 0; // default value 1724 uint32_t wdata = p_vci_tgt.wdata.read(); 1725 1726 if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_READ) // get lock 1727 and (cell == MEMC_LOCK) ) 1728 { 1729 rdata = (uint32_t)r_config_lock.read(); 1730 need_rsp = true; 1731 error = 0; 1732 r_config_lock = true; 1733 } 1734 else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // release lock 1735 and (cell == MEMC_LOCK)) 1736 { 1737 need_rsp = true; 1738 error = 0; 1739 r_config_lock = false; 1740 } 1741 else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // set addr_lo 1742 and (cell == MEMC_ADDR_LO)) 1743 { 1744 assert( ((wdata % (m_words*vci_param_int::B)) == 0) and 1745 "VCI_MEM_CACHE CONFIG ERROR: The buffer must be aligned on a cache line"); 1746 1747 need_rsp = true; 1748 error = 0; 1749 r_config_address = (r_config_address.read() & 0xFFFFFFFF00000000LL) | 1750 ((addr_t)wdata); 1751 } 1752 else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // set addr_hi 1753 and (cell == MEMC_ADDR_HI)) 1754 { 1755 need_rsp = true; 1756 error = 0; 1757 r_config_address = (r_config_address.read() & 0x00000000FFFFFFFFLL) | 1758 (((addr_t) wdata) << 32); 1759 } 1760 else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // set buf_lines 1761 and (cell == MEMC_BUF_LENGTH)) 1762 { 1763 need_rsp = true; 1764 error = 0; 1765 size_t lines = wdata / (m_words << 2); 1766 if (wdata % (m_words << 2)) lines++; 1767 r_config_cmd_lines = lines; 1768 r_config_rsp_lines = 0; 1769 } 1770 else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // set cmd type 1771 and (cell == MEMC_CMD_TYPE)) 1772 { 1773 need_rsp = false; 1774 error = 0; 1775 r_config_cmd = wdata; 1776 r_config_srcid = p_vci_tgt.srcid.read(); 1777 r_config_trdid = p_vci_tgt.trdid.read(); 1778 r_config_pktid = p_vci_tgt.pktid.read(); 1779 } 1780 else 1781 { 1782 need_rsp = true; 1783 error = 1; 1784 } 1785 1786 if ( need_rsp ) 1787 { 1788 // blocked if previous pending request to TGT_RSP FSM 1789 if ( r_tgt_cmd_to_tgt_rsp_req.read() ) break; 1790 1791 r_tgt_cmd_to_tgt_rsp_srcid = p_vci_tgt.srcid.read(); 1792 r_tgt_cmd_to_tgt_rsp_trdid = p_vci_tgt.trdid.read(); 1793 r_tgt_cmd_to_tgt_rsp_pktid = p_vci_tgt.pktid.read(); 1794 r_tgt_cmd_to_tgt_rsp_req = true; 1795 r_tgt_cmd_to_tgt_rsp_error = error; 1796 r_tgt_cmd_to_tgt_rsp_rdata = rdata; 1797 r_tgt_cmd_fsm = TGT_CMD_IDLE; 1798 } 1799 else 1800 { 1801 r_tgt_cmd_fsm = TGT_CMD_IDLE; 1802 } 1803 1804 #if DEBUG_MEMC_TGT_CMD 1805 if(m_debug) 1806 std::cout << " <MEMC " << name() << " TGT_CMD_CONFIG> Configuration request:" 1807 << " address = " << std::hex << p_vci_tgt.address.read() 1808 << " / wdata = " << p_vci_tgt.wdata.read() 1809 << " / need_rsp = " << need_rsp 1810 << " / error = " << error << std::endl; 1811 #endif 1812 break; 1813 } 1814 #endif // #if 0 1815 ////////////////// 1679 if (m_debug) 1680 { 1681 std::cout << " <MEMC " << name() << " TGT_CMD_CONFIG> Configuration request:" 1682 << " address = " << std::hex << p_vci_tgt.address.read() 1683 << " / func = " << func 1684 << " / regr = " << regr 1685 << " / rdata = " << rdata 1686 << " / wdata = " << p_vci_tgt.wdata.read() 1687 << " / need_rsp = " << need_rsp 1688 << " / error = " << error << std::endl; 1689 } 1690 #endif 1691 break; 1692 } 1693 ////////////////// 1816 1694 case TGT_CMD_READ: // Push a read request into read fifo 1817 1695 1818 1696 // check that the read does not cross a cache line limit. 1819 if ( ((m_x[(addr_t) p_vci_tgt.address.read()]+ (p_vci_tgt.plen.read() >>2)) > 16) and1697 if (((m_x[(addr_t) p_vci_tgt.address.read()] + (p_vci_tgt.plen.read() >> 2)) > 16) and 1820 1698 (p_vci_tgt.cmd.read() != vci_param_int::CMD_LOCKED_READ)) 1821 1699 { … … 1825 1703 } 1826 1704 // check single flit 1827 if (!p_vci_tgt.eop.read())1705 if (!p_vci_tgt.eop.read()) 1828 1706 { 1829 1707 std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state" … … 1832 1710 } 1833 1711 // check plen for LL 1834 if ( 1835 (p_vci_tgt.plen.read() != 8) 1712 if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ) and 1713 (p_vci_tgt.plen.read() != 8)) 1836 1714 { 1837 1715 std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state" … … 1840 1718 } 1841 1719 1842 if ( p_vci_tgt.cmdval and m_cmd_read_addr_fifo.wok())1720 if (p_vci_tgt.cmdval and m_cmd_read_addr_fifo.wok()) 1843 1721 { 1844 1722 1845 1723 #if DEBUG_MEMC_TGT_CMD 1846 if(m_debug) 1724 if (m_debug) 1725 { 1847 1726 std::cout << " <MEMC " << name() << " TGT_CMD_READ> Push into read_fifo:" 1848 1727 << " address = " << std::hex << p_vci_tgt.address.read() … … 1851 1730 << " / pktid = " << p_vci_tgt.pktid.read() 1852 1731 << " / plen = " << std::dec << p_vci_tgt.plen.read() << std::endl; 1732 } 1853 1733 #endif 1854 1734 cmd_read_fifo_put = true; 1855 1735 // <Activity counters> 1856 if (p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ) { 1736 if (p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ) 1737 { 1857 1738 if (is_local_req(p_vci_tgt.srcid.read())) 1858 1739 { … … 1864 1745 } 1865 1746 // (1 (CMD) + 2 (RSP)) VCI flits for LL => 2 + 3 dspin flits 1866 m_cpt_ll_cost += 5 * req_distance(p_vci_tgt.srcid.read()); // LL on a single word1747 m_cpt_ll_cost += 5 * req_distance(p_vci_tgt.srcid.read()); 1867 1748 } 1868 1749 else { … … 1885 1766 /////////////////// 1886 1767 case TGT_CMD_WRITE: 1887 if (p_vci_tgt.cmdval and m_cmd_write_addr_fifo.wok())1768 if (p_vci_tgt.cmdval and m_cmd_write_addr_fifo.wok()) 1888 1769 { 1889 1770 uint32_t plen = p_vci_tgt.plen.read(); 1890 1771 #if DEBUG_MEMC_TGT_CMD 1891 if(m_debug) 1772 if (m_debug) 1773 { 1892 1774 std::cout << " <MEMC " << name() << " TGT_CMD_WRITE> Push into write_fifo:" 1893 1775 << " address = " << std::hex << p_vci_tgt.address.read() … … 1898 1780 << " / be = " << p_vci_tgt.be.read() 1899 1781 << " / plen = " << std::dec << p_vci_tgt.plen.read() << std::endl; 1782 } 1900 1783 #endif 1901 1784 cmd_write_fifo_put = true; 1902 1785 // <Activity counters> 1903 if (p_vci_tgt.cmd.read() == vci_param_int::CMD_NOP) { 1786 if (p_vci_tgt.cmd.read() == vci_param_int::CMD_NOP) 1787 { 1904 1788 // (2 (CMD) + 1 (RSP)) flits VCI => 4 + (1 (success) || 2 (failure)) flits dspin 1905 1789 m_cpt_sc_cost += 5 * req_distance(p_vci_tgt.srcid.read()); … … 1919 1803 // </Activity counters> 1920 1804 1921 if (p_vci_tgt.eop) { 1805 if (p_vci_tgt.eop) 1806 { 1922 1807 // <Activity counters> 1923 if (p_vci_tgt.cmd.read() == vci_param_int::CMD_NOP) { 1808 if (p_vci_tgt.cmd.read() == vci_param_int::CMD_NOP) 1809 { 1924 1810 if (is_local_req(p_vci_tgt.srcid.read())) 1925 1811 { … … 1949 1835 ///////////////// 1950 1836 case TGT_CMD_CAS: 1951 if ((p_vci_tgt.plen.read() != 8) and (p_vci_tgt.plen.read() != 16))1837 if ((p_vci_tgt.plen.read() != 8) and (p_vci_tgt.plen.read() != 16)) 1952 1838 { 1953 1839 std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_CAS state" … … 1956 1842 } 1957 1843 1958 if (p_vci_tgt.cmdval and m_cmd_cas_addr_fifo.wok())1844 if (p_vci_tgt.cmdval and m_cmd_cas_addr_fifo.wok()) 1959 1845 { 1960 1846 1961 1847 #if DEBUG_MEMC_TGT_CMD 1962 if(m_debug) 1848 if (m_debug) 1849 { 1963 1850 std::cout << " <MEMC " << name() << " TGT_CMD_CAS> Pushing command into cmd_cas_fifo:" 1964 1851 << " address = " << std::hex << p_vci_tgt.address.read() … … 1969 1856 << " be = " << p_vci_tgt.be.read() 1970 1857 << " plen = " << std::dec << p_vci_tgt.plen.read() << std::endl; 1858 } 1971 1859 #endif 1972 1860 cmd_cas_fifo_put = true; 1973 if (p_vci_tgt.eop) { 1861 if (p_vci_tgt.eop) 1862 { 1974 1863 // <Activity counters> 1975 1864 if (is_local_req(p_vci_tgt.srcid.read())) … … 2005 1894 //////////////////////////////////////////////////////////////////////// 2006 1895 2007 switch (r_multi_ack_fsm.read())1896 switch (r_multi_ack_fsm.read()) 2008 1897 { 2009 1898 //////////////////// 2010 1899 case MULTI_ACK_IDLE: 2011 { 2012 bool multi_ack_fifo_rok = m_cc_receive_to_multi_ack_fifo.rok(); 2013 2014 // No CC_RECEIVE FSM request and no WRITE FSM request 2015 if( not multi_ack_fifo_rok and not r_write_to_multi_ack_req.read()) 2016 break; 2017 2018 uint8_t updt_index; 2019 2020 // handling WRITE FSM request to decrement update table response 2021 // counter if no CC_RECEIVE FSM request 2022 if(not multi_ack_fifo_rok) 2023 { 2024 updt_index = r_write_to_multi_ack_upt_index.read(); 2025 r_write_to_multi_ack_req = false; 2026 } 2027 // Handling CC_RECEIVE FSM request 1900 { 1901 bool multi_ack_fifo_rok = m_cc_receive_to_multi_ack_fifo.rok(); 1902 1903 // No CC_RECEIVE FSM request and no WRITE FSM request 1904 if (not multi_ack_fifo_rok and not r_write_to_multi_ack_req.read()) 1905 break; 1906 1907 uint8_t updt_index; 1908 1909 // handling WRITE FSM request to decrement update table response 1910 // counter if no CC_RECEIVE FSM request 1911 if (not multi_ack_fifo_rok) 1912 { 1913 updt_index = r_write_to_multi_ack_upt_index.read(); 1914 r_write_to_multi_ack_req = false; 1915 } 1916 // Handling CC_RECEIVE FSM request 1917 else 1918 { 1919 uint64_t flit = m_cc_receive_to_multi_ack_fifo.read(); 1920 updt_index = DspinRwtParam::dspin_get(flit, 1921 DspinRwtParam::MULTI_ACK_UPDT_INDEX); 1922 1923 cc_receive_to_multi_ack_fifo_get = true; 1924 } 1925 1926 assert((updt_index < m_upt.size()) and 1927 "VCI_MEM_CACHE ERROR in MULTI_ACK_IDLE : " 1928 "index too large for UPT"); 1929 1930 r_multi_ack_upt_index = updt_index; 1931 r_multi_ack_fsm = MULTI_ACK_UPT_LOCK; 1932 1933 #if DEBUG_MEMC_MULTI_ACK 1934 if (m_debug) 1935 { 1936 if (multi_ack_fifo_rok) 1937 { 1938 std::cout << " <MEMC " << name() 1939 << " MULTI_ACK_IDLE> Response for UPT entry " 1940 << (size_t) updt_index << std::endl; 1941 } 2028 1942 else 2029 1943 { 2030 uint64_t flit = m_cc_receive_to_multi_ack_fifo.read(); 2031 updt_index = DspinRwtParam::dspin_get(flit, 2032 DspinRwtParam::MULTI_ACK_UPDT_INDEX); 2033 2034 cc_receive_to_multi_ack_fifo_get = true; 2035 } 2036 2037 assert((updt_index < m_upt.size()) and 2038 "VCI_MEM_CACHE ERROR in MULTI_ACK_IDLE : " 2039 "index too large for UPT"); 2040 2041 r_multi_ack_upt_index = updt_index; 2042 r_multi_ack_fsm = MULTI_ACK_UPT_LOCK; 1944 std::cout << " <MEMC " << name() 1945 << " MULTI_ACK_IDLE> Write FSM request to decrement UPT entry " 1946 << updt_index << std::endl; 1947 } 1948 } 1949 #endif 1950 break; 1951 } 1952 1953 //////////////////////// 1954 case MULTI_ACK_UPT_LOCK: 1955 { 1956 // get lock to the UPDATE table 1957 if (r_alloc_upt_fsm.read() != ALLOC_UPT_MULTI_ACK) break; 1958 1959 // decrement the number of expected responses 1960 size_t count = 0; 1961 bool valid = m_upt.decrement(r_multi_ack_upt_index.read(), count); 1962 1963 if (not valid) 1964 { 1965 std::cout << "VCI_MEM_CACHE ERROR " << name() 1966 << " MULTI_ACK_UPT_LOCK state" << std::endl 1967 << "unsuccessful access to decrement the UPT" << std::endl; 1968 exit(0); 1969 } 1970 1971 if (count == 0) 1972 { 1973 r_multi_ack_fsm = MULTI_ACK_UPT_CLEAR; 1974 } 1975 else 1976 { 1977 r_multi_ack_fsm = MULTI_ACK_IDLE; 1978 } 2043 1979 2044 1980 #if DEBUG_MEMC_MULTI_ACK 2045 if(m_debug) 2046 { 2047 if (multi_ack_fifo_rok) 2048 { 2049 std::cout << " <MEMC " << name() 2050 << " MULTI_ACK_IDLE> Response for UPT entry " 2051 << (size_t)updt_index << std::endl; 2052 } 2053 else 2054 { 2055 std::cout << " <MEMC " << name() 2056 << " MULTI_ACK_IDLE> Write FSM request to decrement UPT entry " 2057 << updt_index << std::endl; 2058 } 2059 } 2060 #endif 2061 break; 2062 } 2063 2064 //////////////////////// 2065 case MULTI_ACK_UPT_LOCK: 2066 { 2067 // get lock to the UPDATE table 2068 if(r_alloc_upt_fsm.read() != ALLOC_UPT_MULTI_ACK) break; 2069 2070 // decrement the number of expected responses 2071 size_t count = 0; 2072 bool valid = m_upt.decrement(r_multi_ack_upt_index.read(), count); 2073 2074 2075 if(not valid) 2076 { 2077 std::cout << "VCI_MEM_CACHE ERROR " << name() 2078 << " MULTI_ACK_UPT_LOCK state" << std::endl 2079 << "unsuccessful access to decrement the UPT" << std::endl; 2080 exit(0); 2081 } 2082 2083 if(count == 0) 2084 { 2085 r_multi_ack_fsm = MULTI_ACK_UPT_CLEAR; 2086 } 2087 else 2088 { 2089 r_multi_ack_fsm = MULTI_ACK_IDLE; 2090 } 1981 if (m_debug) 1982 { 1983 std::cout << " <MEMC " << name() 1984 << " MULTI_ACK_UPT_LOCK> Decrement the responses counter for UPT:" 1985 << " entry = " << r_multi_ack_upt_index.read() 1986 << " / rsp_count = " << std::dec << count << std::endl; 1987 } 1988 #endif 1989 break; 1990 } 1991 1992 ///////////////////////// 1993 case MULTI_ACK_UPT_CLEAR: // Clear UPT entry / Test if rsp or ack required 1994 { 1995 if (r_alloc_upt_fsm.read() != ALLOC_UPT_MULTI_ACK) 1996 { 1997 std::cout << "VCI_MEM_CACHE ERROR " << name() 1998 << " MULTI_ACK_UPT_CLEAR state" 1999 << " bad UPT allocation" << std::endl; 2000 exit(0); 2001 } 2002 2003 r_multi_ack_srcid = m_upt.srcid(r_multi_ack_upt_index.read()); 2004 r_multi_ack_trdid = m_upt.trdid(r_multi_ack_upt_index.read()); 2005 r_multi_ack_pktid = m_upt.pktid(r_multi_ack_upt_index.read()); 2006 r_multi_ack_nline = m_upt.nline(r_multi_ack_upt_index.read()); 2007 bool need_rsp = m_upt.need_rsp(r_multi_ack_upt_index.read()); 2008 2009 // clear the UPT entry 2010 m_upt.clear(r_multi_ack_upt_index.read()); 2011 2012 if (need_rsp) r_multi_ack_fsm = MULTI_ACK_WRITE_RSP; 2013 else r_multi_ack_fsm = MULTI_ACK_IDLE; 2091 2014 2092 2015 #if DEBUG_MEMC_MULTI_ACK 2093 if(m_debug) 2094 std::cout << " <MEMC " << name() 2095 << " MULTI_ACK_UPT_LOCK> Decrement the responses counter for UPT:" 2096 << " entry = " << r_multi_ack_upt_index.read() 2097 << " / rsp_count = " << std::dec << count << std::endl; 2098 #endif 2099 break; 2100 } 2101 2102 ///////////////////////// 2103 case MULTI_ACK_UPT_CLEAR: // Clear UPT entry / Test if rsp or ack required 2104 { 2105 if(r_alloc_upt_fsm.read() != ALLOC_UPT_MULTI_ACK) 2106 { 2107 std::cout << "VCI_MEM_CACHE ERROR " << name() 2108 << " MULTI_ACK_UPT_CLEAR state" 2109 << " bad UPT allocation" << std::endl; 2110 exit(0); 2111 } 2112 2113 r_multi_ack_srcid = m_upt.srcid(r_multi_ack_upt_index.read()); 2114 r_multi_ack_trdid = m_upt.trdid(r_multi_ack_upt_index.read()); 2115 r_multi_ack_pktid = m_upt.pktid(r_multi_ack_upt_index.read()); 2116 r_multi_ack_nline = m_upt.nline(r_multi_ack_upt_index.read()); 2117 bool need_rsp = m_upt.need_rsp(r_multi_ack_upt_index.read()); 2118 2119 // clear the UPT entry 2120 m_upt.clear(r_multi_ack_upt_index.read()); 2121 2122 if ( need_rsp ) r_multi_ack_fsm = MULTI_ACK_WRITE_RSP; 2123 else r_multi_ack_fsm = MULTI_ACK_IDLE; 2016 if (m_debug) 2017 { 2018 std::cout << " <MEMC " << name() 2019 << " MULTI_ACK_UPT_CLEAR> Clear UPT entry " 2020 << std::dec << r_multi_ack_upt_index.read() << std::endl; 2021 } 2022 #endif 2023 break; 2024 } 2025 ///////////////////////// 2026 case MULTI_ACK_WRITE_RSP: // Post a response request to TGT_RSP FSM 2027 // Wait if pending request 2028 { 2029 if (r_multi_ack_to_tgt_rsp_req.read()) break; 2030 2031 r_multi_ack_to_tgt_rsp_req = true; 2032 r_multi_ack_to_tgt_rsp_srcid = r_multi_ack_srcid.read(); 2033 r_multi_ack_to_tgt_rsp_trdid = r_multi_ack_trdid.read(); 2034 r_multi_ack_to_tgt_rsp_pktid = r_multi_ack_pktid.read(); 2035 r_multi_ack_fsm = MULTI_ACK_IDLE; 2124 2036 2125 2037 #if DEBUG_MEMC_MULTI_ACK 2126 if(m_debug) 2127 std::cout << " <MEMC " << name() 2128 << " MULTI_ACK_UPT_CLEAR> Clear UPT entry " 2129 << std::dec << r_multi_ack_upt_index.read() << std::endl; 2130 #endif 2131 break; 2132 } 2133 ///////////////////////// 2134 case MULTI_ACK_WRITE_RSP: // Post a response request to TGT_RSP FSM 2135 // Wait if pending request 2136 { 2137 if ( r_multi_ack_to_tgt_rsp_req.read() ) break; 2138 2139 r_multi_ack_to_tgt_rsp_req = true; 2140 r_multi_ack_to_tgt_rsp_srcid = r_multi_ack_srcid.read(); 2141 r_multi_ack_to_tgt_rsp_trdid = r_multi_ack_trdid.read(); 2142 r_multi_ack_to_tgt_rsp_pktid = r_multi_ack_pktid.read(); 2143 r_multi_ack_fsm = MULTI_ACK_IDLE; 2144 2145 #if DEBUG_MEMC_MULTI_ACK 2146 if(m_debug) 2147 std::cout << " <MEMC " << name() << " MULTI_ACK_WRITE_RSP>" 2148 << " Request TGT_RSP FSM to send a response to srcid " 2149 << std::hex << r_multi_ack_srcid.read() << std::endl; 2150 #endif 2151 break; 2152 } 2038 if (m_debug) 2039 { 2040 std::cout << " <MEMC " << name() << " MULTI_ACK_WRITE_RSP>" 2041 << " Request TGT_RSP FSM to send a response to srcid " 2042 << std::hex << r_multi_ack_srcid.read() << std::endl; 2043 } 2044 #endif 2045 break; 2046 } 2153 2047 } // end switch r_multi_ack_fsm 2154 2048 … … 2162 2056 // An INVAL or SYNC configuration operation is defined by the following registers: 2163 2057 // - bool r_config_cmd : INVAL / SYNC / NOP 2164 2165 2058 // - uint64_t r_config_address : buffer base address 2166 2059 // - uint32_t r_config_cmd_lines : number of lines to be handled 2167 2060 // - uint32_t r_config_rsp_lines : number of lines not completed 2168 2169 2061 // 2170 2062 // For both INVAL and SYNC commands, the CONFIG FSM contains the loop handling 2171 //2172 2063 // all cache lines covered by the buffer. The various lines of a given buffer 2173 2064 // can be pipelined: the CONFIG FSM does not wait the response for line (n) to send … … 2187 2078 // a response is requested to TGT_RSP FSM. 2188 2079 // If there is copies, a multi-inval, or a broadcast-inval coherence transaction 2189 //2190 2080 // is launched and registered in UPT. The multi-inval transaction completion 2191 2081 // is signaled by the CLEANUP FSM by decrementing the r_config_rsp_lines counter. … … 2215 2105 //////////////////////////////////////////////////////////////////////////////////// 2216 2106 2217 switch ( r_config_fsm.read())2107 switch (r_config_fsm.read()) 2218 2108 { 2219 2109 ///////////////// 2220 2110 case CONFIG_IDLE: // waiting a config request 2221 2222 if ( r_config_cmd.read() != MEMC_CMD_NOP)2223 2224 r_config_fsm= CONFIG_LOOP;2111 { 2112 if (r_config_cmd.read() != MEMC_CMD_NOP) 2113 { 2114 r_config_fsm = CONFIG_LOOP; 2225 2115 2226 2116 #if DEBUG_MEMC_CONFIG 2227 if(m_debug) 2228 std::cout << " <MEMC " << name() << " CONFIG_IDLE> Config Request received" 2229 << " address = " << std::hex << r_config_address.read() 2230 << " / nlines = " << std::dec << r_config_cmd_lines.read() 2231 << " / type = " << r_config_cmd.read() << std::endl; 2232 #endif 2233 } 2234 break; 2235 } 2236 ///////////////// 2237 case CONFIG_LOOP: // test last line to be handled 2238 { 2239 if ( r_config_cmd_lines.read() == 0 ) 2240 { 2241 r_config_cmd = MEMC_CMD_NOP; 2242 r_config_fsm = CONFIG_WAIT; 2117 if (m_debug) 2118 { 2119 std::cout << " <MEMC " << name() << " CONFIG_IDLE> Config Request received" 2120 << " / address = " << std::hex << r_config_address.read() 2121 << " / lines = " << std::dec << r_config_cmd_lines.read() 2122 << " / type = " << r_config_cmd.read() << std::endl; 2123 } 2124 #endif 2125 } 2126 break; 2127 } 2128 ///////////////// 2129 case CONFIG_LOOP: // test if last line to be handled 2130 { 2131 if (r_config_cmd_lines.read() == 0) 2132 { 2133 r_config_cmd = MEMC_CMD_NOP; 2134 r_config_fsm = CONFIG_WAIT; 2135 } 2136 else 2137 { 2138 r_config_fsm = CONFIG_DIR_REQ; 2139 } 2140 2141 #if DEBUG_MEMC_CONFIG 2142 if (m_debug) 2143 { 2144 std::cout << " <MEMC " << name() << " CONFIG_LOOP>" 2145 << " / address = " << std::hex << r_config_address.read() 2146 << " / lines not handled = " << std::dec << r_config_cmd_lines.read() 2147 << " / command = " << r_config_cmd.read() << std::endl; 2148 } 2149 #endif 2150 break; 2151 } 2152 ///////////////// 2153 case CONFIG_WAIT: // wait completion (last response) 2154 { 2155 if (r_config_rsp_lines.read() == 0) // last response received 2156 { 2157 r_config_fsm = CONFIG_RSP; 2158 } 2159 2160 #if DEBUG_MEMC_CONFIG 2161 if (m_debug) 2162 { 2163 std::cout << " <MEMC " << name() << " CONFIG_WAIT>" 2164 << " / lines to do = " << std::dec << r_config_rsp_lines.read() << std::endl; 2165 } 2166 #endif 2167 break; 2168 } 2169 //////////////// 2170 case CONFIG_RSP: // request TGT_RSP FSM to return response 2171 { 2172 if (not r_config_to_tgt_rsp_req.read()) 2173 { 2174 r_config_to_tgt_rsp_srcid = r_config_srcid.read(); 2175 r_config_to_tgt_rsp_trdid = r_config_trdid.read(); 2176 r_config_to_tgt_rsp_pktid = r_config_pktid.read(); 2177 r_config_to_tgt_rsp_error = false; 2178 r_config_to_tgt_rsp_req = true; 2179 r_config_fsm = CONFIG_IDLE; 2180 2181 #if DEBUG_MEMC_CONFIG 2182 if (m_debug) 2183 { 2184 std::cout << " <MEMC " << name() << " CONFIG_RSP> Request TGT_RSP FSM to send response:" 2185 << " error = " << r_config_to_tgt_rsp_error.read() 2186 << " / rsrcid = " << std::hex << r_config_srcid.read() 2187 << " / rtrdid = " << std::hex << r_config_trdid.read() 2188 << " / rpktid = " << std::hex << r_config_pktid.read() << std::endl; 2189 } 2190 #endif 2191 } 2192 break; 2193 } 2194 //////////////////// 2195 case CONFIG_DIR_REQ: // Request directory lock 2196 { 2197 if (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) 2198 { 2199 r_config_fsm = CONFIG_DIR_ACCESS; 2200 } 2201 2202 #if DEBUG_MEMC_CONFIG 2203 if (m_debug) 2204 { 2205 std::cout << " <MEMC " << name() << " CONFIG_DIR_REQ>" 2206 << " Request DIR access" << std::endl; 2207 } 2208 #endif 2209 break; 2210 } 2211 /////////////////////// 2212 case CONFIG_DIR_ACCESS: // Access directory and decode config command 2213 { 2214 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and 2215 "MEMC ERROR in CONFIG_DIR_ACCESS state: bad DIR allocation"); 2216 2217 size_t way = 0; 2218 DirectoryEntry entry = m_cache_directory.read(r_config_address.read(), way); 2219 2220 r_config_dir_way = way; 2221 r_config_dir_copy_inst = entry.owner.inst; 2222 r_config_dir_copy_srcid = entry.owner.srcid; 2223 r_config_dir_is_cnt = entry.is_cnt; 2224 r_config_dir_lock = entry.lock; 2225 r_config_dir_count = entry.count; 2226 r_config_dir_ptr = entry.ptr; 2227 2228 if (entry.valid and // hit & inval command 2229 (r_config_cmd.read() == MEMC_CMD_INVAL)) 2230 { 2231 r_config_fsm = CONFIG_IVT_LOCK; 2232 } 2233 else if (entry.valid and // hit & sync command 2234 entry.dirty and 2235 (r_config_cmd.read() == MEMC_CMD_SYNC)) 2236 { 2237 r_config_fsm = CONFIG_TRT_LOCK; 2238 } 2239 else // miss : return to LOOP 2240 { 2241 r_config_cmd_lines = r_config_cmd_lines.read() - 1; 2242 r_config_address = r_config_address.read() + (m_words << 2); 2243 r_config_fsm = CONFIG_LOOP; 2244 } 2245 2246 #if DEBUG_MEMC_CONFIG 2247 if (m_debug) 2248 { 2249 std::cout << " <MEMC " << name() << " CONFIG_DIR_ACCESS> Accessing directory: " 2250 << " address = " << std::hex << r_config_address.read() 2251 << " / hit = " << std::dec << entry.valid 2252 << " / dirty = " << entry.dirty 2253 << " / count = " << entry.count 2254 << " / is_cnt = " << entry.is_cnt << std::endl; 2255 } 2256 #endif 2257 break; 2258 } 2259 ///////////////////// 2260 case CONFIG_TRT_LOCK: // enter this state in case of SYNC command 2261 // to a dirty cache line 2262 // keep DIR lock, and try to get TRT lock 2263 // return to LOOP state if TRT full 2264 // reset dirty bit in DIR and register a PUT 2265 // transaction in TRT if not full. 2266 { 2267 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and 2268 "MEMC ERROR in CONFIG_TRT_LOCK state: bad DIR allocation"); 2269 2270 if (r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG) 2271 { 2272 size_t index = 0; 2273 bool wok = not m_trt.full(index); 2274 2275 if (not wok) 2276 { 2277 r_config_fsm = CONFIG_LOOP; 2243 2278 } 2244 2279 else 2245 2280 { 2246 r_config_fsm = CONFIG_DIR_REQ; 2281 size_t way = r_config_dir_way.read(); 2282 size_t set = m_y[r_config_address.read()]; 2283 2284 // reset dirty bit in DIR 2285 DirectoryEntry entry; 2286 entry.valid = true; 2287 entry.dirty = false; 2288 entry.tag = m_z[r_config_address.read()]; 2289 entry.is_cnt = r_config_dir_is_cnt.read(); 2290 entry.lock = r_config_dir_lock.read(); 2291 entry.ptr = r_config_dir_ptr.read(); 2292 entry.count = r_config_dir_count.read(); 2293 entry.owner.inst = r_config_dir_copy_inst.read(); 2294 entry.owner.srcid = r_config_dir_copy_srcid.read(); 2295 m_cache_directory.write(set, way, entry); 2296 2297 r_config_trt_index = index; 2298 r_config_fsm = CONFIG_TRT_SET; 2247 2299 } 2248 2300 2249 2301 #if DEBUG_MEMC_CONFIG 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() 2254 << " / command = " << r_config_cmd.read() << std::endl; 2255 #endif 2256 break; 2257 } 2258 ///////////////// 2259 case CONFIG_WAIT: // wait completion (last response) 2260 { 2261 if ( r_config_rsp_lines.read() == 0 ) // last response received 2262 { 2263 r_config_fsm = CONFIG_RSP; 2264 } 2302 if (m_debug) 2303 { 2304 std::cout << " <MEMC " << name() << " CONFIG_TRT_LOCK> Access TRT: " 2305 << " wok = " << std::dec << wok 2306 << " index = " << index << std::endl; 2307 } 2308 #endif 2309 } 2310 break; 2311 } 2312 //////////////////// 2313 case CONFIG_TRT_SET: // read data in cache 2314 // and post a PUT request in TRT 2315 { 2316 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and 2317 "MEMC ERROR in CONFIG_TRT_SET state: bad DIR allocation"); 2318 2319 assert((r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG) and 2320 "MEMC ERROR in CONFIG_TRT_SET state: bad TRT allocation"); 2321 2322 // read data into cache 2323 size_t way = r_config_dir_way.read(); 2324 size_t set = m_y[r_config_address.read()]; 2325 std::vector<data_t> data_vector; 2326 data_vector.clear(); 2327 for (size_t word = 0; word < m_words; word++) 2328 { 2329 uint32_t data = m_cache_data.read(way, set, word); 2330 data_vector.push_back(data); 2331 } 2332 2333 // post the PUT request in TRT 2334 m_trt.set(r_config_trt_index.read(), 2335 false, // PUT transaction 2336 m_nline[r_config_address.read()], // line index 2337 0, // srcid: unused 2338 0, // trdid: unused 2339 0, // pktid: unused 2340 false, // not proc_read 2341 0, // read_length: unused 2342 0, // word_index: unused 2343 std::vector<be_t>(m_words, 0xF), // byte-enable: unused 2344 data_vector, // data to be written 2345 0, // ll_key: unused 2346 true); // requested by config FSM 2347 config_rsp_lines_incr = true; 2348 r_config_fsm = CONFIG_PUT_REQ; 2265 2349 2266 2350 #if DEBUG_MEMC_CONFIG 2267 if(m_debug) 2268 std::cout << " <MEMC " << name() << " CONFIG_WAIT>" 2269 << " / lines to do = " << std::dec << r_config_rsp_lines.read() << std::endl; 2270 #endif 2271 break; 2272 } 2273 //////////////// 2274 case CONFIG_RSP: // request TGT_RSP FSM to return response 2275 { 2276 if ( not r_config_to_tgt_rsp_req.read() ) 2277 { 2278 r_config_to_tgt_rsp_srcid = r_config_srcid.read(); 2279 r_config_to_tgt_rsp_trdid = r_config_trdid.read(); 2280 r_config_to_tgt_rsp_pktid = r_config_pktid.read(); 2281 r_config_to_tgt_rsp_error = false; 2282 r_config_to_tgt_rsp_req = true; 2283 r_config_fsm = CONFIG_IDLE; 2351 if (m_debug) 2352 { 2353 std::cout << " <MEMC " << name() << " CONFIG_TRT_SET> PUT request in TRT:" 2354 << " address = " << std::hex << r_config_address.read() 2355 << " index = " << std::dec << r_config_trt_index.read() << std::endl; 2356 } 2357 #endif 2358 break; 2359 } 2360 //////////////////// 2361 case CONFIG_PUT_REQ: // post PUT request to IXR_CMD_FSM 2362 { 2363 if (not r_config_to_ixr_cmd_req.read()) 2364 { 2365 r_config_to_ixr_cmd_req = true; 2366 r_config_to_ixr_cmd_index = r_config_trt_index.read(); 2367 2368 // prepare next iteration 2369 r_config_cmd_lines = r_config_cmd_lines.read() - 1; 2370 r_config_address = r_config_address.read() + (m_words << 2); 2371 r_config_fsm = CONFIG_LOOP; 2284 2372 2285 2373 #if DEBUG_MEMC_CONFIG 2286 if(m_debug) 2287 std::cout << " <MEMC " << name() << " CONFIG_RSP> Request TGT_RSP FSM to return response:" 2288 << " error = " << r_config_to_tgt_rsp_error.read() 2289 << " / rsrcid = " << std::hex << r_config_srcid.read() 2290 << " / rtrdid = " << std::hex << r_config_trdid.read() 2291 << " / rpktid = " << std::hex << r_config_pktid.read() << std::endl; 2292 #endif 2293 } 2294 break; 2295 2296 } 2297 2298 //////////////////// 2299 case CONFIG_DIR_REQ: // Request directory lock 2300 { 2301 if ( r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG ) 2302 { 2303 r_config_fsm = CONFIG_DIR_ACCESS; 2304 } 2374 if (m_debug) 2375 { 2376 std::cout << " <MEMC " << name() << " CONFIG_PUT_REQ> post PUT request to IXR_CMD_FSM" 2377 << " / address = " << std::hex << r_config_address.read() << std::endl; 2378 } 2379 #endif 2380 } 2381 break; 2382 } 2383 ///////////////////// 2384 case CONFIG_IVT_LOCK: // enter this state in case of INVAL command 2385 // Keep DIR lock and Try to get IVT lock. 2386 // Return to LOOP state if IVT full. 2387 // Register inval in IVT, and invalidate the 2388 // directory if IVT not full. 2389 { 2390 assert((r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and 2391 "MEMC ERROR in CONFIG_IVT_LOCK state: bad DIR allocation"); 2392 2393 if (r_alloc_ivt_fsm.read() == ALLOC_IVT_CONFIG) 2394 { 2395 size_t set = m_y[(addr_t) (r_config_address.read())]; 2396 size_t way = r_config_dir_way.read(); 2397 2398 if (r_config_dir_count.read() == 0) // inval DIR and return to LOOP 2399 { 2400 m_cache_directory.inval(way, set); 2401 r_config_cmd_lines = r_config_cmd_lines.read() - 1; 2402 r_config_address = r_config_address.read() + (m_words << 2); 2403 r_config_fsm = CONFIG_LOOP; 2305 2404 2306 2405 #if DEBUG_MEMC_CONFIG 2307 if(m_debug) 2308 std::cout << " <MEMC " << name() << " CONFIG_DIR_REQ>" 2309 << " Request DIR access" << std::endl; 2310 #endif 2311 break; 2312 } 2313 /////////////////////// 2314 case CONFIG_DIR_ACCESS: // Access directory and decode config command 2315 { 2316 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and 2317 "MEMC ERROR in CONFIG_DIR_ACCESS state: bad DIR allocation"); 2318 2319 size_t way = 0; 2320 DirectoryEntry entry = m_cache_directory.read(r_config_address.read(), way); 2321 2322 r_config_dir_way = way; 2323 r_config_dir_copy_inst = entry.owner.inst; 2324 r_config_dir_copy_srcid = entry.owner.srcid; 2325 r_config_dir_is_cnt = entry.is_cnt; 2326 r_config_dir_count = entry.count; 2327 r_config_dir_lock = entry.lock; 2328 r_config_dir_ptr = entry.ptr; 2329 2330 if (entry.valid and // hit & inval command 2331 (r_config_cmd.read() == MEMC_CMD_INVAL)) 2332 { 2333 r_config_fsm = CONFIG_IVT_LOCK; 2334 } 2335 else if ( entry.valid and // hit & sync command 2336 entry.dirty and 2337 (r_config_cmd.read() == MEMC_CMD_SYNC) ) 2338 { 2339 r_config_fsm = CONFIG_TRT_LOCK; 2340 } 2341 else // return to LOOP 2342 { 2343 r_config_cmd_lines = r_config_cmd_lines.read() - 1; 2344 r_config_address = r_config_address.read() + (m_words<<2); 2345 r_config_fsm = CONFIG_LOOP; 2346 } 2406 if (m_debug) 2407 { 2408 std::cout << " <MEMC " << name() << " CONFIG_IVT_LOCK>" 2409 << " No copies in L1 : inval DIR entry" << std::endl; 2410 } 2411 #endif 2412 } 2413 else // try to register inval in IVT 2414 { 2415 bool wok = false; 2416 size_t index = 0; 2417 bool broadcast = r_config_dir_is_cnt.read(); 2418 size_t srcid = r_config_srcid.read(); 2419 size_t trdid = r_config_trdid.read(); 2420 size_t pktid = r_config_pktid.read(); 2421 addr_t nline = m_nline[(addr_t) (r_config_address.read())]; 2422 size_t nb_copies = r_config_dir_count.read(); 2423 2424 wok = m_ivt.set(false, // it's an inval transaction 2425 broadcast, 2426 false, // no response required 2427 true, // acknowledge required 2428 srcid, 2429 trdid, 2430 pktid, 2431 nline, 2432 nb_copies, 2433 index); 2434 2435 if (wok) // IVT success => inval DIR slot 2436 { 2437 m_cache_directory.inval(way, set); 2438 r_config_ivt_index = index; 2439 config_rsp_lines_incr = true; 2440 if (broadcast) 2441 { 2442 r_config_fsm = CONFIG_BC_SEND; 2443 } 2444 else 2445 { 2446 r_config_fsm = CONFIG_INVAL_SEND; 2447 } 2347 2448 2348 2449 #if DEBUG_MEMC_CONFIG 2349 if(m_debug) 2350 std::cout << " <MEMC " << name() << " CONFIG_DIR_ACCESS> Accessing directory: " 2351 << " address = " << std::hex << r_config_address.read() 2352 << " / hit = " << std::dec << entry.valid 2353 << " / dirty = " << entry.dirty 2354 << " / count = " << entry.count 2355 << " / is_cnt = " << entry.is_cnt << std::endl; 2356 #endif 2357 break; 2358 } 2359 ///////////////////// 2360 case CONFIG_TRT_LOCK: // enter this state in case of SYNC command 2361 // to a dirty cache line 2362 // keep DIR lock, and try to get TRT lock 2363 // return to LOOP state if TRT full 2364 // reset dirty bit in DIR and register a PUT 2365 // trabsaction in TRT if not full. 2366 { 2367 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and 2368 "MEMC ERROR in CONFIG_TRT_LOCK state: bad DIR allocation"); 2369 2370 if ( r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG ) 2371 { 2372 size_t index = 0; 2373 bool wok = not m_trt.full(index); 2374 2375 if ( not wok ) 2450 if (m_debug) 2451 { 2452 std::cout << " <MEMC " << name() << " CONFIG_IVT_LOCK>" 2453 << " Inval DIR entry and register inval in IVT" 2454 << " / index = " << std::dec << index 2455 << " / broadcast = " << broadcast << std::endl; 2456 } 2457 #endif 2458 } 2459 else // IVT full => release both DIR and IVT locks 2376 2460 { 2377 2