Changeset 440 for branches/v5/modules/vci_mem_cache/caba/source
- Timestamp:
- Jul 17, 2013, 9:24:48 AM (11 years ago)
- Location:
- branches/v5/modules/vci_mem_cache
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/v5/modules/vci_mem_cache
-
Property
svn:mergeinfo
set to
/trunk/modules/vci_mem_cache merged eligible
-
Property
svn:mergeinfo
set to
-
branches/v5/modules/vci_mem_cache/caba/source/include/mem_cache_directory.h
r307 r440 40 40 //////////////////////////////////////////////////////////////////////// 41 41 class Owner{ 42 typedef uint32_t size_t;43 42 44 43 public: … … 92 91 93 92 typedef uint32_t tag_t; 94 typedef uint32_t size_t;95 93 96 94 public: … … 165 163 void print() 166 164 { 167 std::cout << "Valid = " << valid << " ; IS COUNT = " << is_cnt << " ; Dirty = " << dirty << " ; Lock = " 168 << lock 165 std::cout << "Valid = " << valid 166 << " ; IS COUNT = " << is_cnt 167 << " ; Dirty = " << dirty 168 << " ; Lock = " << lock 169 169 << " ; Tag = " << std::hex << tag << std::dec 170 170 << " ; Count = " << count … … 187 187 typedef uint32_t data_t; 188 188 typedef uint32_t tag_t; 189 typedef uint32_t size_t;190 189 191 190 private: … … 275 274 276 275 ///////////////////////////////////////////////////////////////////// 276 // The inval function invalidate an entry defined by the set and 277 // way arguments. 278 ///////////////////////////////////////////////////////////////////// 279 void inval( const size_t &set, const size_t &way ) 280 { 281 m_dir_tab[set][way].init(); 282 } 283 284 ///////////////////////////////////////////////////////////////////// 277 285 // The read_neutral() function reads a directory entry, without 278 286 // changing the LRU … … 321 329 // update LRU bits 322 330 bool all_recent = true; 323 for ( size_t i=0 ; i<m_ways ; i++ ) { 324 if ( i != way ) all_recent = m_lru_tab[set][i].recent && all_recent; 325 } 326 if ( all_recent ) { 327 for( size_t i=0 ; i<m_ways ; i++ ) m_lru_tab[set][i].recent = false; 328 } else { 329 m_lru_tab[set][way].recent = true; 331 for ( size_t i=0 ; i<m_ways ; i++ ) 332 { 333 if ( i != way ) all_recent = m_lru_tab[set][i].recent && all_recent; 334 } 335 if ( all_recent ) 336 { 337 for( size_t i=0 ; i<m_ways ; i++ ) m_lru_tab[set][i].recent = false; 338 } 339 else 340 { 341 m_lru_tab[set][way].recent = true; 330 342 } 331 343 } // end write() … … 408 420 /////////////////////////////////////////////////////////////////////// 409 421 class HeapEntry{ 410 typedef uint32_t size_t;411 422 412 423 public: … … 472 483 //////////////////////////////////////////////////////////////////////// 473 484 class HeapDirectory{ 474 typedef uint32_t size_t;475 485 476 486 private: -
branches/v5/modules/vci_mem_cache/caba/source/include/update_tab.h
r307 r440 11 11 //////////////////////////////////////////////////////////////////////// 12 12 class UpdateTabEntry { 13 13 14 typedef uint32_t size_t; 14 15 typedef sc_dt::sc_uint<40> addr_t; 15 16 16 17 public: 18 17 19 bool valid; // It is a valid pending transaction 18 20 bool update; // It is an update transaction 19 21 bool brdcast; // It is a broadcast invalidate 20 bool rsp; // It needs a response to the initiator 22 bool rsp; // Response to the initiator required 23 bool ack; // Acknowledge to the CONFIG FSM required 21 24 size_t srcid; // The srcid of the initiator which wrote the data 22 25 size_t trdid; // The trdid of the initiator which wrote the data … … 25 28 size_t count; // The number of acknowledge responses to receive 26 29 27 UpdateTabEntry(){ 30 UpdateTabEntry() 31 { 28 32 valid = false; 29 33 update = false; 30 34 brdcast = false; 31 35 rsp = false; 36 ack = false; 32 37 srcid = 0; 33 38 trdid = 0; … … 38 43 39 44 UpdateTabEntry(bool i_valid, 40 bool i_update, 41 bool i_brdcast, 42 bool i_rsp, 43 size_t i_srcid, 44 size_t i_trdid, 45 size_t i_pktid, 46 addr_t i_nline, 47 size_t i_count) 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) 48 54 { 49 55 valid = i_valid; … … 51 57 brdcast = i_brdcast; 52 58 rsp = i_rsp; 59 ack = i_ack; 53 60 srcid = i_srcid; 54 61 trdid = i_trdid; … … 64 71 brdcast = source.brdcast; 65 72 rsp = source.rsp; 73 ack = source.ack; 66 74 srcid = source.srcid; 67 75 trdid = source.trdid; … … 80 88 brdcast= false; 81 89 rsp = false; 90 ack = false; 82 91 srcid = 0; 83 92 trdid = 0; … … 98 107 brdcast= source.brdcast; 99 108 rsp = source.rsp; 109 ack = source.ack ; 100 110 srcid = source.srcid; 101 111 trdid = source.trdid; … … 108 118 // The print() function prints the entry 109 119 //////////////////////////////////////////////////////////////////// 110 void print(){ 111 std::cout << std::dec << "valid = " << valid << std::endl; 112 std::cout << "update = " << update << std::endl; 113 std::cout << "brdcast= " << brdcast<< std::endl; 114 std::cout << "rsp = " << rsp << std::endl; 115 std::cout << "srcid = " << srcid << std::endl; 116 std::cout << "trdid = " << trdid << std::endl; 117 std::cout << "pktid = " << pktid << std::endl; 118 std::cout << std::hex << "nline = " << nline << std::endl; 119 std::cout << std::dec << "count = " << count << std::endl; 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; 120 132 } 121 133 }; … … 126 138 class UpdateTab{ 127 139 128 typedef uint32_t size_t; 129 typedef sc_dt::sc_uint<40> addr_t; 140 typedef uint64_t addr_t; 130 141 131 142 private: 132 size_t size_tab;143 size_t size_tab; 133 144 std::vector<UpdateTabEntry> tab; 134 145 … … 150 161 // The size() function returns the size of the tab 151 162 //////////////////////////////////////////////////////////////////// 152 const size_t size(){ 163 const size_t size() 164 { 153 165 return size_tab; 154 166 } 155 167 156 157 168 //////////////////////////////////////////////////////////////////// 158 169 // The print() function diplays the tab content 159 170 //////////////////////////////////////////////////////////////////// 160 void print(){ 161 for(size_t i=0; i<size_tab; i++) { 162 std::cout << "UPDATE TAB ENTRY " << std::dec << i << "--------" << std::endl; 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 << "] "; 163 177 tab[i].print(); 164 178 } … … 166 180 } 167 181 168 169 182 ///////////////////////////////////////////////////////////////////// 170 183 // The init() function initializes the tab 171 184 ///////////////////////////////////////////////////////////////////// 172 void init(){ 173 for ( size_t i=0; i<size_tab; i++) { 174 tab[i].init(); 175 } 176 } 177 185 void init() 186 { 187 for ( size_t i=0; i<size_tab; i++) tab[i].init(); 188 } 178 189 179 190 ///////////////////////////////////////////////////////////////////// … … 201 212 /////////////////////////////////////////////////////////////////////////// 202 213 bool set(const bool update, 203 const bool brdcast, 204 const bool rsp, 205 const size_t srcid, 206 const size_t trdid, 207 const size_t pktid, 208 const addr_t nline, 209 const size_t count, 210 size_t &index) 211 { 212 for ( size_t i=0 ; i<size_tab ; i++ ) { 213 if( !tab[i].valid ) { 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 { 214 228 tab[i].valid = true; 215 229 tab[i].update = update; 216 230 tab[i].brdcast = brdcast; 217 231 tab[i].rsp = rsp; 232 tab[i].ack = ack; 218 233 tab[i].srcid = (size_t) srcid; 219 234 tab[i].trdid = (size_t) trdid; … … 236 251 ///////////////////////////////////////////////////////////////////// 237 252 bool decrement( const size_t index, 238 size_t &counter )253 size_t &counter ) 239 254 { 240 255 assert((index<size_tab) && "Bad Update Tab Entry"); 241 if ( tab[index].valid ) { 256 if ( tab[index].valid ) 257 { 242 258 tab[index].count--; 243 259 counter = tab[index].count; 244 260 return true; 245 } else { 261 } 262 else 263 { 246 264 return false; 247 265 } … … 253 271 bool is_full() 254 272 { 255 for(size_t i = 0 ; i < size_tab ; i++){ 256 if(!tab[i].valid){ 257 return false; 258 } 273 for(size_t i = 0 ; i < size_tab ; i++) 274 { 275 if(!tab[i].valid) return false; 259 276 } 260 277 return true; … … 266 283 bool is_not_empty() 267 284 { 268 for(size_t i = 0 ; i < size_tab ; i++){ 269 if(tab[i].valid){ 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 ; 270 394 return true; 271 395 } … … 275 399 276 400 ///////////////////////////////////////////////////////////////////// 277 // The need_rsp() function returns the need of a response 278 // Arguments : 279 // - index : the index of the entry 280 ///////////////////////////////////////////////////////////////////// 281 bool need_rsp(const size_t index) 282 { 283 assert(index<size_tab && "Bad Update Tab Entry"); 284 return tab[index].rsp; 285 } 286 287 ///////////////////////////////////////////////////////////////////// 288 // The is_update() function returns the transaction type 289 // Arguments : 290 // - index : the index of the entry 291 ///////////////////////////////////////////////////////////////////// 292 bool is_brdcast(const size_t index) 293 { 294 assert(index<size_tab && "Bad Update Tab Entry"); 295 return tab[index].brdcast; 296 } 297 298 ///////////////////////////////////////////////////////////////////// 299 // The is_update() function returns the transaction type 300 // Arguments : 301 // - index : the index of the entry 302 ///////////////////////////////////////////////////////////////////// 303 bool is_update(const size_t index) 304 { 305 assert(index<size_tab && "Bad Update Tab Entry"); 306 return tab[index].update; 307 } 308 309 ///////////////////////////////////////////////////////////////////// 310 // The srcid() function returns the srcid value 311 // Arguments : 312 // - index : the index of the entry 313 ///////////////////////////////////////////////////////////////////// 314 size_t srcid(const size_t index) 315 { 316 assert(index<size_tab && "Bad Update Tab Entry"); 317 return tab[index].srcid; 318 } 319 320 ///////////////////////////////////////////////////////////////////// 321 // The trdid() function returns the trdid value 322 // Arguments : 323 // - index : the index of the entry 324 ///////////////////////////////////////////////////////////////////// 325 size_t trdid(const size_t index) 326 { 327 assert(index<size_tab && "Bad Update Tab Entry"); 328 return tab[index].trdid; 329 } 330 331 ///////////////////////////////////////////////////////////////////// 332 // The pktid() function returns the pktid value 333 // Arguments : 334 // - index : the index of the entry 335 ///////////////////////////////////////////////////////////////////// 336 size_t pktid(const size_t index) 337 { 338 assert(index<size_tab && "Bad Update Tab Entry"); 339 return tab[index].pktid; 340 } 341 342 ///////////////////////////////////////////////////////////////////// 343 // The nline() function returns the nline value 344 // Arguments : 345 // - index : the index of the entry 346 ///////////////////////////////////////////////////////////////////// 347 addr_t nline(const size_t index) 348 { 349 assert(index<size_tab && "Bad Update Tab Entry"); 350 return tab[index].nline; 351 } 352 353 ///////////////////////////////////////////////////////////////////// 354 // The search_inval() function returns the index of the entry in UPT 401 // The read_nline() function returns the index of the entry in UPT 355 402 // Arguments : 356 403 // - nline : the line number of the entry in the directory 357 404 ///////////////////////////////////////////////////////////////////// 358 bool search_inval(const addr_t nline,size_t &index)405 bool read_nline(const addr_t nline,size_t &index) 359 406 { 360 407 size_t i ; 361 408 362 for (i = 0 ; i < size_tab ; i++){ 363 if((tab[i].nline == nline) && tab[i].valid){ 364 if(!tab[i].update){ 365 index = i ; 366 return true; 367 } 368 } 369 } 370 return false; 371 } 372 373 ///////////////////////////////////////////////////////////////////// 374 // The read_nline() function returns the index of the entry in UPT 375 // Arguments : 376 // - nline : the line number of the entry in the directory 377 ///////////////////////////////////////////////////////////////////// 378 bool read_nline(const addr_t nline,size_t &index) 379 { 380 size_t i ; 381 382 for (i = 0 ; i < size_tab ; i++){ 383 if((tab[i].nline == nline) && tab[i].valid){ 409 for (i = 0 ; i < size_tab ; i++) 410 { 411 if ( (tab[i].nline == nline) and tab[i].valid ) 412 { 384 413 index = i ; 385 414 return true; -
branches/v5/modules/vci_mem_cache/caba/source/include/vci_mem_cache.h
r362 r440 52 52 #include "dspin_dhccp_param.h" 53 53 54 #define TRANSACTION_TAB_LINES 4 // Number of lines in the transaction tab 55 #define UPDATE_TAB_LINES 4 // Number of lines in the update tab 54 #define TRT_ENTRIES 4 // Number of entries in TRT 55 #define UPT_ENTRIES 4 // Number of entries in UPT 56 #define HEAP_ENTRIES 1024 // Number of entries in HEAP 56 57 57 58 namespace soclib { namespace caba { 59 58 60 using namespace sc_core; 59 61 60 template<typename vci_param> 62 template<typename vci_param_int, 63 typename vci_param_ext, 64 size_t dspin_in_width, 65 size_t dspin_out_width> 61 66 class VciMemCache 62 67 : public soclib::caba::BaseModule 63 68 { 64 typedef sc_dt::sc_uint<40> addr_t; 65 typedef typename vci_param::fast_addr_t vci_addr_t; 69 typedef typename vci_param_int::fast_addr_t addr_t; 70 71 typedef typename sc_dt::sc_uint<64> wide_data_t; 72 66 73 typedef uint32_t data_t; 67 74 typedef uint32_t tag_t; 68 typedef uint32_t size_t;69 75 typedef uint32_t be_t; 70 76 typedef uint32_t copy_t; 71 77 72 78 /* States of the TGT_CMD fsm */ 73 enum tgt_cmd_fsm_state_e{ 79 enum tgt_cmd_fsm_state_e 80 { 74 81 TGT_CMD_IDLE, 82 TGT_CMD_ERROR, 75 83 TGT_CMD_READ, 76 84 TGT_CMD_WRITE, 77 TGT_CMD_CAS 85 TGT_CMD_CAS, 86 TGT_CMD_CONFIG 78 87 }; 79 88 80 89 /* States of the TGT_RSP fsm */ 81 enum tgt_rsp_fsm_state_e{ 90 enum tgt_rsp_fsm_state_e 91 { 92 TGT_RSP_CONFIG_IDLE, 93 TGT_RSP_TGT_CMD_IDLE, 82 94 TGT_RSP_READ_IDLE, 83 95 TGT_RSP_WRITE_IDLE, 84 96 TGT_RSP_CAS_IDLE, 85 97 TGT_RSP_XRAM_IDLE, 86 TGT_RSP_ INIT_IDLE,98 TGT_RSP_MULTI_ACK_IDLE, 87 99 TGT_RSP_CLEANUP_IDLE, 100 TGT_RSP_CONFIG, 101 TGT_RSP_TGT_CMD, 88 102 TGT_RSP_READ, 89 103 TGT_RSP_WRITE, 90 104 TGT_RSP_CAS, 91 105 TGT_RSP_XRAM, 92 TGT_RSP_ INIT,106 TGT_RSP_MULTI_ACK, 93 107 TGT_RSP_CLEANUP 94 108 }; 95 109 96 110 /* States of the DSPIN_TGT fsm */ 97 enum cc_receive_fsm_state_e{ 111 enum cc_receive_fsm_state_e 112 { 98 113 CC_RECEIVE_IDLE, 99 114 CC_RECEIVE_CLEANUP, 115 CC_RECEIVE_CLEANUP_EOP, 100 116 CC_RECEIVE_MULTI_ACK 101 117 }; 102 118 103 119 /* States of the CC_SEND fsm */ 104 enum cc_send_fsm_state_e{ 120 enum cc_send_fsm_state_e 121 { 122 CC_SEND_CONFIG_IDLE, 105 123 CC_SEND_XRAM_RSP_IDLE, 106 124 CC_SEND_WRITE_IDLE, 107 125 CC_SEND_CAS_IDLE, 108 126 CC_SEND_CLEANUP_IDLE, 127 CC_SEND_CONFIG_INVAL_HEADER, 128 CC_SEND_CONFIG_INVAL_NLINE, 129 CC_SEND_CONFIG_BRDCAST_HEADER, 130 CC_SEND_CONFIG_BRDCAST_NLINE, 109 131 CC_SEND_CLEANUP_ACK, 110 132 CC_SEND_XRAM_RSP_BRDCAST_HEADER, … … 126 148 127 149 /* States of the MULTI_ACK fsm */ 128 enum multi_ack_fsm_state_e{ 150 enum multi_ack_fsm_state_e 151 { 129 152 MULTI_ACK_IDLE, 130 153 MULTI_ACK_UPT_LOCK, 131 154 MULTI_ACK_UPT_CLEAR, 132 MULTI_ACK_WRITE_RSP 155 MULTI_ACK_WRITE_RSP, 156 MULTI_ACK_CONFIG_ACK 157 }; 158 159 /* States of the CONFIG fsm */ 160 enum config_fsm_state_e 161 { 162 CONFIG_IDLE, 163 CONFIG_LOOP, 164 CONFIG_RSP, 165 CONFIG_DIR_REQ, 166 CONFIG_DIR_ACCESS, 167 CONFIG_DIR_UPT_LOCK, 168 CONFIG_BC_SEND, 169 CONFIG_BC_WAIT, 170 CONFIG_INV_SEND, 171 CONFIG_HEAP_REQ, 172 CONFIG_HEAP_SCAN, 173 CONFIG_HEAP_LAST, 174 CONFIG_INV_WAIT 133 175 }; 134 176 135 177 /* States of the READ fsm */ 136 enum read_fsm_state_e{ 178 enum read_fsm_state_e 179 { 137 180 READ_IDLE, 138 181 READ_DIR_REQ, … … 151 194 152 195 /* States of the WRITE fsm */ 153 enum write_fsm_state_e{ 196 enum write_fsm_state_e 197 { 154 198 WRITE_IDLE, 155 199 WRITE_NEXT, … … 177 221 178 222 /* States of the IXR_RSP fsm */ 179 enum ixr_rsp_fsm_state_e{ 223 enum ixr_rsp_fsm_state_e 224 { 180 225 IXR_RSP_IDLE, 181 226 IXR_RSP_ACK, … … 185 230 186 231 /* States of the XRAM_RSP fsm */ 187 enum xram_rsp_fsm_state_e{ 232 enum xram_rsp_fsm_state_e 233 { 188 234 XRAM_RSP_IDLE, 189 235 XRAM_RSP_TRT_COPY, … … 204 250 205 251 /* States of the IXR_CMD fsm */ 206 enum ixr_cmd_fsm_state_e{ 252 enum ixr_cmd_fsm_state_e 253 { 207 254 IXR_CMD_READ_IDLE, 208 255 IXR_CMD_WRITE_IDLE, 209 256 IXR_CMD_CAS_IDLE, 210 257 IXR_CMD_XRAM_IDLE, 211 IXR_CMD_READ _NLINE,212 IXR_CMD_WRITE _NLINE,213 IXR_CMD_CAS _NLINE,214 IXR_CMD_XRAM _DATA258 IXR_CMD_READ, 259 IXR_CMD_WRITE, 260 IXR_CMD_CAS, 261 IXR_CMD_XRAM 215 262 }; 216 263 217 264 /* States of the CAS fsm */ 218 enum cas_fsm_state_e{ 265 enum cas_fsm_state_e 266 { 219 267 CAS_IDLE, 220 268 CAS_DIR_REQ, … … 241 289 242 290 /* States of the CLEANUP fsm */ 243 enum cleanup_fsm_state_e{ 291 enum cleanup_fsm_state_e 292 { 244 293 CLEANUP_IDLE, 245 294 CLEANUP_GET_NLINE, … … 256 305 CLEANUP_UPT_CLEAR, 257 306 CLEANUP_WRITE_RSP, 258 CLEANUP_SEND_ACK 307 CLEANUP_CONFIG_ACK, 308 CLEANUP_SEND_CLACK 259 309 }; 260 310 261 311 /* States of the ALLOC_DIR fsm */ 262 enum alloc_dir_fsm_state_e{ 312 enum alloc_dir_fsm_state_e 313 { 263 314 ALLOC_DIR_RESET, 315 ALLOC_DIR_CONFIG, 264 316 ALLOC_DIR_READ, 265 317 ALLOC_DIR_WRITE, … … 270 322 271 323 /* States of the ALLOC_TRT fsm */ 272 enum alloc_trt_fsm_state_e{ 324 enum alloc_trt_fsm_state_e 325 { 273 326 ALLOC_TRT_READ, 274 327 ALLOC_TRT_WRITE, … … 279 332 280 333 /* States of the ALLOC_UPT fsm */ 281 enum alloc_upt_fsm_state_e{ 334 enum alloc_upt_fsm_state_e 335 { 336 ALLOC_UPT_CONFIG, 282 337 ALLOC_UPT_WRITE, 283 338 ALLOC_UPT_XRAM_RSP, … … 288 343 289 344 /* States of the ALLOC_HEAP fsm */ 290 enum alloc_heap_fsm_state_e{ 345 enum alloc_heap_fsm_state_e 346 { 291 347 ALLOC_HEAP_RESET, 292 348 ALLOC_HEAP_READ, … … 294 350 ALLOC_HEAP_CAS, 295 351 ALLOC_HEAP_CLEANUP, 296 ALLOC_HEAP_XRAM_RSP 352 ALLOC_HEAP_XRAM_RSP, 353 ALLOC_HEAP_CONFIG 297 354 }; 298 355 … … 325 382 }; 326 383 384 /* Configuration commands */ 385 enum cmd_config_type_e 386 { 387 CMD_CONFIG_INVAL = 0, 388 CMD_CONFIG_SYNC = 1 389 }; 390 327 391 // debug variables (for each FSM) 328 bool m_debug_global; 329 bool m_debug_tgt_cmd_fsm; 330 bool m_debug_tgt_rsp_fsm; 331 bool m_debug_cc_send_fsm; 332 bool m_debug_cc_receive_fsm; 333 bool m_debug_multi_ack_fsm; 334 bool m_debug_read_fsm; 335 bool m_debug_write_fsm; 336 bool m_debug_cas_fsm; 337 bool m_debug_cleanup_fsm; 338 bool m_debug_ixr_cmd_fsm; 339 bool m_debug_ixr_rsp_fsm; 340 bool m_debug_xram_rsp_fsm; 392 bool m_debug; 341 393 bool m_debug_previous_hit; 342 394 size_t m_debug_previous_count; 343 395 344 396 bool m_monitor_ok; 345 vci_addr_tm_monitor_base;346 vci_addr_tm_monitor_length;397 addr_t m_monitor_base; 398 addr_t m_monitor_length; 347 399 348 400 // instrumentation counters 349 401 uint32_t m_cpt_cycles; // Counter of cycles 402 350 403 uint32_t m_cpt_read; // Number of READ transactions 404 uint32_t m_cpt_read_remote; // number of remote READ transactions 405 uint32_t m_cpt_read_flits; // number of flits for READs 406 uint32_t m_cpt_read_cost; // Number of (flits * distance) for READs 407 351 408 uint32_t m_cpt_read_miss; // Number of MISS READ 409 352 410 uint32_t m_cpt_write; // Number of WRITE transactions 411 uint32_t m_cpt_write_remote; // number of remote WRITE transactions 412 uint32_t m_cpt_write_flits; // number of flits for WRITEs 413 uint32_t m_cpt_write_cost; // Number of (flits * distance) for WRITEs 414 353 415 uint32_t m_cpt_write_miss; // Number of MISS WRITE 354 416 uint32_t m_cpt_write_cells; // Cumulated length for WRITE transactions … … 366 428 uint32_t m_cpt_cas; // Number of CAS transactions 367 429 430 uint32_t m_cpt_cleanup_cost; // Number of (flits * distance) for CLEANUPs 431 432 uint32_t m_cpt_update_flits; // Number of flits for UPDATEs 433 uint32_t m_cpt_update_cost; // Number of (flits * distance) for UPDATEs 434 435 uint32_t m_cpt_inval_cost; // Number of (flits * distance) for INVALs 436 437 uint32_t m_cpt_get; 438 439 uint32_t m_cpt_put; 440 368 441 size_t m_prev_count; 369 442 … … 373 446 374 447 public: 375 sc_in<bool> p_clk;376 sc_in<bool> p_resetn;377 soclib::caba::VciTarget<vci_param >p_vci_tgt;378 soclib::caba::VciInitiator<vci_param >p_vci_ixr;379 soclib::caba::DspinInput< 33>p_dspin_in;380 soclib::caba::DspinOutput< 40>p_dspin_out;448 sc_in<bool> p_clk; 449 sc_in<bool> p_resetn; 450 soclib::caba::VciTarget<vci_param_int> p_vci_tgt; 451 soclib::caba::VciInitiator<vci_param_ext> p_vci_ixr; 452 soclib::caba::DspinInput<dspin_in_width> p_dspin_in; 453 soclib::caba::DspinOutput<dspin_out_width> p_dspin_out; 381 454 382 455 VciMemCache( 383 456 sc_module_name name, // Instance Name 384 const soclib::common::MappingTable &mtp, // Mapping table for directnetwork385 const soclib::common::MappingTable &mtx, // Mapping table for externalnetwork386 const soclib::common::IntTab &srcid_x, // global index on externalnetwork387 const soclib::common::IntTab &tgtid_d, // global index on directnetwork388 const size_t cc_global_id, // global index on ccnetwork457 const soclib::common::MappingTable &mtp, // Mapping table INT network 458 const soclib::common::MappingTable &mtx, // Mapping table RAM network 459 const soclib::common::IntTab &srcid_x, // global index RAM network 460 const soclib::common::IntTab &tgtid_d, // global index INT network 461 const size_t cc_global_id, // global index CC network 389 462 const size_t nways, // Number of ways per set 390 463 const size_t nsets, // Number of sets 391 464 const size_t nwords, // Number of words per line 392 const size_t max_copies, // max number of copies in heap393 const size_t heap_size= 1024, // number of heap entries394 const size_t trt_lines=TR ANSACTION_TAB_LINES,395 const size_t upt_lines=UP DATE_TAB_LINES,465 const size_t max_copies, // max number of copies 466 const size_t heap_size=HEAP_ENTRIES, 467 const size_t trt_lines=TRT_ENTRIES, 468 const size_t upt_lines=UPT_ENTRIES, 396 469 const size_t debug_start_cycle=0, 397 470 const bool debug_ok=false ); … … 401 474 void print_stats(); 402 475 void print_trace(); 403 void copies_monitor( vci_addr_t addr);404 void start_monitor( vci_addr_t addr, vci_addr_t length);476 void copies_monitor(addr_t addr); 477 void start_monitor(addr_t addr, addr_t length); 405 478 void stop_monitor(); 406 479 … … 409 482 void transition(); 410 483 void genMoore(); 411 void check_monitor( const char *buf, vci_addr_t addr, data_t data); 412 void check_monitor_read( const char *buf, vci_addr_t addr); 484 void check_monitor( const char *buf, addr_t addr, data_t data, bool read); 413 485 414 486 // Component attributes 415 std::list<soclib::common::Segment> m_seglist; // segments allocated to memcache487 std::list<soclib::common::Segment> m_seglist; // segments allocated 416 488 size_t m_nseg; // number of segments 417 489 soclib::common::Segment **m_seg; // array of segments pointers 418 const size_t m_srcid_x; // global index on external network 490 size_t m_seg_config; // config segment index 491 const size_t m_srcid_x; // global index on RAM network 419 492 const size_t m_initiators; // Number of initiators 420 493 const size_t m_heap_size; // Size of the heap … … 434 507 size_t m_max_copies; // max number of copies in heap 435 508 GenericLLSCGlobalTable 436 < 32 , // number of slots 437 4096, // number of processors in the system 438 8000, // registratioçn life span (in # of LL operations) 439 typename vci_param::fast_addr_t > // address type 440 m_llsc_table; // ll/sc global registration table 509 < 32 , // number of slots 510 4096, // number of processors in the system 511 8000, // registration life (# of LL operations) 512 addr_t > m_llsc_table; // ll/sc registration table 441 513 442 514 // adress masks 443 const soclib::common::AddressMaskingTable< vci_addr_t> m_x;444 const soclib::common::AddressMaskingTable< vci_addr_t> m_y;445 const soclib::common::AddressMaskingTable< vci_addr_t> m_z;446 const soclib::common::AddressMaskingTable< vci_addr_t> m_nline;515 const soclib::common::AddressMaskingTable<addr_t> m_x; 516 const soclib::common::AddressMaskingTable<addr_t> m_y; 517 const soclib::common::AddressMaskingTable<addr_t> m_z; 518 const soclib::common::AddressMaskingTable<addr_t> m_nline; 447 519 448 520 // broadcast address 449 uint32_t m_broadcast_address;521 uint32_t m_broadcast_boundaries; 450 522 451 523 ////////////////////////////////////////////////// … … 453 525 ////////////////////////////////////////////////// 454 526 527 sc_signal<int> r_tgt_cmd_fsm; 528 455 529 // Fifo between TGT_CMD fsm and READ fsm 456 GenericFifo< uint64_t>m_cmd_read_addr_fifo;530 GenericFifo<addr_t> m_cmd_read_addr_fifo; 457 531 GenericFifo<size_t> m_cmd_read_length_fifo; 458 532 GenericFifo<size_t> m_cmd_read_srcid_fifo; … … 461 535 462 536 // Fifo between TGT_CMD fsm and WRITE fsm 463 GenericFifo< uint64_t>m_cmd_write_addr_fifo;537 GenericFifo<addr_t> m_cmd_write_addr_fifo; 464 538 GenericFifo<bool> m_cmd_write_eop_fifo; 465 539 GenericFifo<size_t> m_cmd_write_srcid_fifo; … … 470 544 471 545 // Fifo between TGT_CMD fsm and CAS fsm 472 GenericFifo< uint64_t>m_cmd_cas_addr_fifo;546 GenericFifo<addr_t> m_cmd_cas_addr_fifo; 473 547 GenericFifo<bool> m_cmd_cas_eop_fifo; 474 548 GenericFifo<size_t> m_cmd_cas_srcid_fifo; … … 477 551 GenericFifo<data_t> m_cmd_cas_wdata_fifo; 478 552 479 // Fifo between INIT_RSPfsm and CLEANUP fsm553 // Fifo between CC_RECEIVE fsm and CLEANUP fsm 480 554 GenericFifo<uint64_t> m_cc_receive_to_cleanup_fifo; 481 555 482 // Fifo between INIT_RSPfsm and MULTI_ACK fsm556 // Fifo between CC_RECEIVE fsm and MULTI_ACK fsm 483 557 GenericFifo<uint64_t> m_cc_receive_to_multi_ack_fifo; 484 558 485 sc_signal<int> r_tgt_cmd_fsm; 559 // Buffer between TGT_CMD fsm and TGT_RSP fsm 560 // (segmentation violation response request) 561 sc_signal<bool> r_tgt_cmd_to_tgt_rsp_req; 562 563 sc_signal<uint32_t> r_tgt_cmd_to_tgt_rsp_rdata; 564 sc_signal<size_t> r_tgt_cmd_to_tgt_rsp_error; 565 sc_signal<size_t> r_tgt_cmd_to_tgt_rsp_srcid; 566 sc_signal<size_t> r_tgt_cmd_to_tgt_rsp_trdid; 567 sc_signal<size_t> r_tgt_cmd_to_tgt_rsp_pktid; 568 569 sc_signal<addr_t> r_tgt_cmd_config_addr; 570 sc_signal<size_t> r_tgt_cmd_config_cmd; 571 572 /////////////////////////////////////////////////////// 573 // Registers controlled by the CONFIG fsm 574 /////////////////////////////////////////////////////// 575 576 sc_signal<int> r_config_fsm; // FSM state 577 sc_signal<bool> r_config_lock; // lock protecting exclusive access 578 sc_signal<int> r_config_cmd; // config request status 579 sc_signal<addr_t> r_config_address; // target buffer physical address 580 sc_signal<size_t> r_config_srcid; // config request srcid 581 sc_signal<size_t> r_config_trdid; // config request trdid 582 sc_signal<size_t> r_config_pktid; // config request pktid 583 sc_signal<size_t> r_config_nlines; // number of lines covering the buffer 584 sc_signal<size_t> r_config_dir_way; // DIR: selected way 585 sc_signal<size_t> r_config_dir_count; // DIR: number of copies 586 sc_signal<bool> r_config_dir_is_cnt; // DIR: counter mode (broadcast required) 587 sc_signal<size_t> r_config_dir_copy_srcid; // DIR: first copy SRCID 588 sc_signal<bool> r_config_dir_copy_inst; // DIR: first copy L1 type 589 sc_signal<size_t> r_config_dir_next_ptr; // DIR: index of next copy in HEAP 590 sc_signal<size_t> r_config_heap_next; // current pointer to scan HEAP 591 592 sc_signal<size_t> r_config_upt_index; // UPT index 593 594 // Buffer between CONFIG fsm and TGT_RSP fsm (send a done response to L1 cache) 595 sc_signal<bool> r_config_to_tgt_rsp_req; // valid request 596 sc_signal<bool> r_config_to_tgt_rsp_error; // error response 597 sc_signal<size_t> r_config_to_tgt_rsp_srcid; // Transaction srcid 598 sc_signal<size_t> r_config_to_tgt_rsp_trdid; // Transaction trdid 599 sc_signal<size_t> r_config_to_tgt_rsp_pktid; // Transaction pktid 600 601 // Buffer between CONFIG fsm and CC_SEND fsm (multi-inval / broadcast-inval) 602 sc_signal<bool> r_config_to_cc_send_multi_req; // multi-inval request 603 sc_signal<bool> r_config_to_cc_send_brdcast_req; // broadcast-inval request 604 sc_signal<addr_t> r_config_to_cc_send_nline; // line index 605 sc_signal<size_t> r_config_to_cc_send_trdid; // UPT index 606 GenericFifo<bool> m_config_to_cc_send_inst_fifo; // fifo for the L1 type 607 GenericFifo<size_t> m_config_to_cc_send_srcid_fifo; // fifo for owners srcid 608 609 #if L1_MULTI_CACHE 610 GenericFifo<size_t> m_config_to_cc_send_cache_id_fifo; // fifo for cache_id 611 #endif 486 612 487 613 /////////////////////////////////////////////////////// … … 489 615 /////////////////////////////////////////////////////// 490 616 491 sc_signal<int> r_read_fsm; // FSM state 492 sc_signal<size_t> r_read_copy; // Srcid of the first copy 493 sc_signal<size_t> r_read_copy_cache; // Srcid of the first copy 494 sc_signal<bool> r_read_copy_inst; // Type of the first copy 495 sc_signal<tag_t> r_read_tag; // cache line tag (in directory) 496 sc_signal<bool> r_read_is_cnt; // is_cnt bit (in directory) 497 sc_signal<bool> r_read_lock; // lock bit (in directory) 498 sc_signal<bool> r_read_dirty; // dirty bit (in directory) 499 sc_signal<size_t> r_read_count; // number of copies 500 sc_signal<size_t> r_read_ptr; // pointer to the heap 501 sc_signal<data_t> * r_read_data; // data (one cache line) 502 sc_signal<size_t> r_read_way; // associative way (in cache) 503 sc_signal<size_t> r_read_trt_index; // Transaction Table index 504 sc_signal<size_t> r_read_next_ptr; // Next entry to point to 505 sc_signal<bool> r_read_last_free; // Last free entry 506 sc_signal<typename vci_param::fast_addr_t> 507 r_read_ll_key; // LL key returned by the llsc_global_table 617 sc_signal<int> r_read_fsm; // FSM state 618 sc_signal<size_t> r_read_copy; // Srcid of the first copy 619 sc_signal<size_t> r_read_copy_cache; // Srcid of the first copy 620 sc_signal<bool> r_read_copy_inst; // Type of the first copy 621 sc_signal<tag_t> r_read_tag; // cache line tag (in directory) 622 sc_signal<bool> r_read_is_cnt; // is_cnt bit (in directory) 623 sc_signal<bool> r_read_lock; // lock bit (in directory) 624 sc_signal<bool> r_read_dirty; // dirty bit (in directory) 625 sc_signal<size_t> r_read_count; // number of copies 626 sc_signal<size_t> r_read_ptr; // pointer to the heap 627 sc_signal<data_t> * r_read_data; // data (one cache line) 628 sc_signal<size_t> r_read_way; // associative way (in cache) 629 sc_signal<size_t> r_read_trt_index; // Transaction Table index 630 sc_signal<size_t> r_read_next_ptr; // Next entry to point to 631 sc_signal<bool> r_read_last_free; // Last free entry 632 sc_signal<addr_t> r_read_ll_key; // LL key from the llsc_global_table 508 633 509 634 // Buffer between READ fsm and IXR_CMD fsm (ask a missing cache line to XRAM) … … 520 645 sc_signal<size_t> r_read_to_tgt_rsp_word; // first word of the response 521 646 sc_signal<size_t> r_read_to_tgt_rsp_length; // length of the response 522 sc_signal<typename vci_param::fast_addr_t> 523 r_read_to_tgt_rsp_ll_key; // LL key returned by the llsc_global_table 647 sc_signal<addr_t> r_read_to_tgt_rsp_ll_key; // LL key from the llsc_global_table 524 648 525 649 /////////////////////////////////////////////////////////////// … … 578 702 GenericFifo<bool> m_write_to_cc_send_inst_fifo; // fifo for the L1 type 579 703 GenericFifo<size_t> m_write_to_cc_send_srcid_fifo; // fifo for srcids 704 580 705 #if L1_MULTI_CACHE 581 706 GenericFifo<size_t> m_write_to_cc_send_cache_id_fifo; // fifo for srcids … … 596 721 sc_signal<size_t> r_multi_ack_pktid; // pending write pktid 597 722 sc_signal<addr_t> r_multi_ack_nline; // pending write nline 723 724 // signaling completion of multi-inval to CONFIG fsm 725 sc_signal<bool> r_multi_ack_to_config_ack; 598 726 599 727 // Buffer between MULTI_ACK fsm and TGT_RSP fsm (complete write/update transaction) … … 633 761 sc_signal<size_t> r_cleanup_way; // associative way (in cache) 634 762 635 sc_signal<size_t> r_cleanup_write_srcid; // srcid of write r esponse763 sc_signal<size_t> r_cleanup_write_srcid; // srcid of write rsp 636 764 sc_signal<size_t> r_cleanup_write_trdid; // trdid of write rsp 637 765 sc_signal<size_t> r_cleanup_write_pktid; // pktid of write rsp 638 sc_signal<bool> r_cleanup_write_need_rsp;// needs a write rsp 766 767 sc_signal<bool> r_cleanup_need_rsp; // write response required 768 sc_signal<bool> r_cleanup_need_ack; // config acknowledge required 639 769 640 770 sc_signal<size_t> r_cleanup_index; // index of the INVAL line (in the UPT) 641 771 772 // signaling completion of broadcast-inval to CONFIG fsm 773 sc_signal<bool> r_cleanup_to_config_ack; 774 642 775 // Buffer between CLEANUP fsm and TGT_RSP fsm (acknowledge a write command from L1) 643 776 sc_signal<bool> r_cleanup_to_tgt_rsp_req; // valid request … … 703 836 GenericFifo<bool> m_cas_to_cc_send_inst_fifo; // fifo for the L1 type 704 837 GenericFifo<size_t> m_cas_to_cc_send_srcid_fifo; // fifo for srcids 838 705 839 #if L1_MULTI_CACHE 706 840 GenericFifo<size_t> m_cas_to_cc_send_cache_id_fifo; // fifo for srcids … … 749 883 sc_signal<size_t> r_xram_rsp_to_tgt_rsp_length; // length of the response 750 884 sc_signal<bool> r_xram_rsp_to_tgt_rsp_rerror; // send error to requester 751 sc_signal<typename vci_param::fast_addr_t> 752 r_xram_rsp_to_tgt_rsp_ll_key; // LL key returned by the llsc_global_table 885 sc_signal<addr_t> r_xram_rsp_to_tgt_rsp_ll_key; // LL key from llsc_global_table 753 886 754 887 // Buffer between XRAM_RSP fsm and CC_SEND fsm (Inval L1 Caches) … … 759 892 GenericFifo<bool> m_xram_rsp_to_cc_send_inst_fifo; // fifo for the L1 type 760 893 GenericFifo<size_t> m_xram_rsp_to_cc_send_srcid_fifo; // fifo for srcids 894 761 895 #if L1_MULTI_CACHE 762 896 GenericFifo<size_t> m_xram_rsp_to_cc_send_cache_id_fifo; // fifo for srcids -
branches/v5/modules/vci_mem_cache/caba/source/include/xram_transaction.h
r362 r440 13 13 //////////////////////////////////////////////////////////////////////// 14 14 15 class TransactionTabEntry { 16 typedef uint32_t size_t; 15 class TransactionTabEntry 16 { 17 typedef sc_dt::sc_uint<64> wide_data_t; 18 typedef sc_dt::sc_uint<40> addr_t; 17 19 typedef uint32_t data_t; 18 typedef sc_dt::sc_uint<40> addr_t;19 20 typedef uint32_t be_t; 20 21 … … 84 85 // The print() function prints the entry 85 86 //////////////////////////////////////////////////////////////////// 86 void print(){ 87 void print() 88 { 87 89 std::cout << "valid = " << valid << std::endl; 88 90 std::cout << "xram_read = " << xram_read << std::endl; … … 137 139 // The transaction tab 138 140 //////////////////////////////////////////////////////////////////////// 139 class TransactionTab{ 140 typedef uint32_t size_t; 141 typedef uint32_t data_t; 142 typedef sc_dt::sc_uint<40> addr_t; 143 typedef uint32_t be_t; 141 class TransactionTab 142 { 143 typedef sc_dt::sc_uint<64> wide_data_t; 144 typedef sc_dt::sc_uint<40> addr_t; 145 typedef uint32_t data_t; 146 typedef uint32_t be_t; 144 147 145 148 private: 146 size_t size_tab; // The size of the tab 149 const std::string tab_name; // the name for logs 150 size_t size_tab; // the size of the tab 147 151 148 152 data_t be_to_mask(be_t be) … … 176 180 } 177 181 178 TransactionTab(size_t n_entries, size_t n_words) 179 { 180 size_tab = n_entries; 182 TransactionTab(const std::string &name, 183 size_t n_entries, 184 size_t n_words ) 185 : tab_name( name ), 186 size_tab( n_entries ) 187 { 181 188 tab = new TransactionTabEntry[size_tab]; 182 for ( size_t i=0; i<size_tab; i++) { 189 for ( size_t i=0; i<size_tab; i++) 190 { 183 191 tab[i].alloc(n_words); 184 192 } … … 368 376 369 377 ///////////////////////////////////////////////////////////////////// 370 // The write_rsp() function writes a word of the response to an371 // XRAM read transaction.378 // The write_rsp() function writes two 32 bits words of the response 379 // to a XRAM read transaction. 372 380 // The BE field in TRT is taken into account. 373 381 // Arguments : 374 382 // - index : the index of the transaction in the transaction tab 375 383 // - word_index : the index of the data in the line 376 // - data : the data to write384 // - data : a 64 bits value 377 385 // - error : invalid data 378 386 ///////////////////////////////////////////////////////////////////// 379 void write_rsp(const size_t index, 380 const size_t word, 381 const data_t data, 382 const bool rerror) 383 { 384 assert( (index < size_tab) 385 && "Selected entry out of range in write_rsp() Transaction Tab"); 386 assert( (word <= tab[index].wdata_be.size()) 387 && "Bad word_index in write_rsp() in TransactionTab"); 388 assert( tab[index].valid 389 && "Transaction Tab Entry invalid in write_rsp()"); 390 assert( tab[index].xram_read 391 && "Selected entry is not an XRAM read transaction in write_rsp()"); 392 393 data_t mask = be_to_mask(tab[index].wdata_be[word]); 394 tab[index].wdata[word] = (tab[index].wdata[word] & mask) | (data & ~mask); 387 void write_rsp(const size_t index, 388 const size_t word, 389 const wide_data_t data, 390 const bool rerror) 391 { 392 data_t value; 393 data_t mask; 394 395 if ( index >= size_tab ) 396 { 397 std::cout << "VCI_MEM_CACHE ERRROR " << tab_name 398 << " TRT entry out of range in write_rsp()" << std::endl; 399 exit(0); 400 } 401 if ( word > tab[index].wdata_be.size() ) 402 { 403 std::cout << "VCI_MEM_CACHE ERRROR " << tab_name 404 << " Bad word_index in write_rsp() in TRT" << std::endl; 405 exit(0); 406 } 407 if ( not tab[index].valid ) 408 { 409 std::cout << "VCI_MEM_CACHE ERRROR " << tab_name 410 << " TRT Entry invalid in write_rsp()" << std::endl; 411 exit(0); 412 } 413 if ( not tab[index].xram_read ) 414 { 415 std::cout << "VCI_MEM_CACHE ERRROR " << tab_name 416 << " TRT entry is not an XRAM GET in write_rsp()" << std::endl; 417 exit(0); 418 } 419 420 // first 32 bits word 421 value = (data_t)data; 422 mask = be_to_mask(tab[index].wdata_be[word]); 423 tab[index].wdata[word] = (tab[index].wdata[word] & mask) | (value & ~mask); 424 425 // second 32 bits word 426 value = (data_t)(data>>32); 427 mask = be_to_mask(tab[index].wdata_be[word+1]); 428 tab[index].wdata[word+1] = (tab[index].wdata[word+1] & mask) | (value & ~mask); 429 430 // error update 395 431 tab[index].rerror |= rerror; 396 432 } -
branches/v5/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp
r367 r440 26 26 * SOCLIB_LGPL_HEADER_END 27 27 * 28 * Maintainers: alain eric.guthmuller@polytechnique.edu 28 * Maintainers: alain.greiner@lip6.fr 29 * eric.guthmuller@polytechnique.edu 29 30 * cesar.fuguet-tortolero@lip6.fr 30 31 * alexandre.joannou@lip6.fr … … 33 34 #include "../include/vci_mem_cache.h" 34 35 35 ////// debug services /////////////////////////////////////////////////////// 36 ////// debug services ///////////////////////////////////////////////////////////// 36 37 // All debug messages are conditionned by two variables: 37 38 // - compile time : DEBUG_MEMC_*** : defined below 38 // - execution time : m_debug _*** : defined by constructor arguments39 // m_debug_* = (m_debug_ok) and (m_cpt_cycle > m_debug_start_cycle)40 ///////////////////////////////////////////////////////////////////////////////// 41 42 #define DEBUG_MEMC_ GLOBAL 0 // synthetic trace of all FSMs43 #define DEBUG_MEMC_READ 1 // detailed trace of READ FSM44 #define DEBUG_MEMC_WRITE 1 // detailed trace of WRITE FSM45 #define DEBUG_MEMC_CAS 1 // detailed trace of CAS FSM46 #define DEBUG_MEMC_IXR_CMD 1 // detailed trace of IXR_RSP FSM47 #define DEBUG_MEMC_IXR_RSP 1 // detailed trace of IXR_RSP FSM48 #define DEBUG_MEMC_XRAM_RSP 1 // detailed trace of XRAM_RSP FSM49 #define DEBUG_MEMC_CC_SEND 1 // detailed trace of CC_SEND FSM39 // - execution time : m_debug = (m_debug_ok) and (m_cpt_cycle > m_debug_start_cycle) 40 /////////////////////////////////////////////////////////////////////////////////////// 41 42 #define DEBUG_MEMC_GLOBAL 0 // synthetic trace of all FSMs 43 #define DEBUG_MEMC_CONFIG 1 // detailed trace of CONFIG FSM 44 #define DEBUG_MEMC_READ 1 // detailed trace of READ FSM 45 #define DEBUG_MEMC_WRITE 1 // detailed trace of WRITE FSM 46 #define DEBUG_MEMC_CAS 1 // detailed trace of CAS FSM 47 #define DEBUG_MEMC_IXR_CMD 1 // detailed trace of IXR_RSP FSM 48 #define DEBUG_MEMC_IXR_RSP 1 // detailed trace of IXR_RSP FSM 49 #define DEBUG_MEMC_XRAM_RSP 1 // detailed trace of XRAM_RSP FSM 50 #define DEBUG_MEMC_CC_SEND 1 // detailed trace of CC_SEND FSM 50 51 #define DEBUG_MEMC_MULTI_ACK 1 // detailed trace of MULTI_ACK FSM 51 #define DEBUG_MEMC_TGT_CMD 1 // detailed trace of TGT_CMD FSM 52 #define DEBUG_MEMC_TGT_RSP 1 // detailed trace of TGT_RSP FSM 53 #define DEBUG_MEMC_CLEANUP 1 // detailed trace of CLEANUP FSM 54 55 #define RANDOMIZE_CAS 1 56 57 namespace soclib 58 { 59 namespace caba 60 { 52 #define DEBUG_MEMC_TGT_CMD 1 // detailed trace of TGT_CMD FSM 53 #define DEBUG_MEMC_TGT_RSP 1 // detailed trace of TGT_RSP FSM 54 #define DEBUG_MEMC_CLEANUP 1 // detailed trace of CLEANUP FSM 55 56 #define RANDOMIZE_CAS 1 57 58 namespace soclib { namespace caba { 61 59 62 60 const char *tgt_cmd_fsm_str[] = 63 61 { 64 62 "TGT_CMD_IDLE", 63 "TGT_CMD_ERROR", 65 64 "TGT_CMD_READ", 66 65 "TGT_CMD_WRITE", 67 "TGT_CMD_CAS" 66 "TGT_CMD_CAS", 67 "TGT_CMD_CONFIG" 68 68 }; 69 69 const char *tgt_rsp_fsm_str[] = 70 70 { 71 "TGT_RSP_CONFIG_IDLE", 72 "TGT_RSP_TGT_CMD_IDLE", 71 73 "TGT_RSP_READ_IDLE", 72 74 "TGT_RSP_WRITE_IDLE", 73 75 "TGT_RSP_CAS_IDLE", 74 76 "TGT_RSP_XRAM_IDLE", 75 "TGT_RSP_ INIT_IDLE",77 "TGT_RSP_MULTI_ACK_IDLE", 76 78 "TGT_RSP_CLEANUP_IDLE", 79 "TGT_RSP_CONFIG", 80 "TGT_RSP_TGT_CMD", 77 81 "TGT_RSP_READ", 78 82 "TGT_RSP_WRITE", 79 83 "TGT_RSP_CAS", 80 84 "TGT_RSP_XRAM", 81 "TGT_RSP_ INIT",85 "TGT_RSP_MULTI_ACK", 82 86 "TGT_RSP_CLEANUP" 83 87 }; … … 86 90 "CC_RECEIVE_IDLE", 87 91 "CC_RECEIVE_CLEANUP", 92 "CC_RECEIVE_CLEANUP_EOP", 88 93 "CC_RECEIVE_MULTI_ACK" 89 94 }; 90 95 const char *cc_send_fsm_str[] = 91 96 { 97 "CC_SEND_CONFIG_IDLE", 92 98 "CC_SEND_XRAM_RSP_IDLE", 93 99 "CC_SEND_WRITE_IDLE", 94 100 "CC_SEND_CAS_IDLE", 95 101 "CC_SEND_CLEANUP_IDLE", 102 "CC_SEND_CONFIG_INVAL_HEADER", 103 "CC_SEND_CONFIG_INVAL_NLINE", 104 "CC_SEND_CONFIG_BRDCAST_HEADER", 105 "CC_SEND_CONFIG_BRDCAST_NLINE", 96 106 "CC_SEND_CLEANUP_ACK", 97 107 "CC_SEND_XRAM_RSP_BRDCAST_HEADER", … … 116 126 "MULTI_ACK_UPT_LOCK", 117 127 "MULTI_ACK_UPT_CLEAR", 118 "MULTI_ACK_WRITE_RSP" 128 "MULTI_ACK_WRITE_RSP", 129 "MULTI_ACK_CONFIG_ACK" 130 }; 131 const char *config_fsm_str[] = 132 { 133 "CONFIG_IDLE", 134 "CONFIG_LOOP", 135 "CONFIG_RSP", 136 "CONFIG_DIR_REQ", 137 "CONFIG_DIR_ACCESS", 138 "CONFIG_DIR_UPT_LOCK", 139 "CONFIG_BC_SEND", 140 "CONFIG_BC_WAIT", 141 "CONFIG_INV_SEND", 142 "CONFIG_HEAP_REQ", 143 "CONFIG_HEAP_SCAN", 144 "CONFIG_HEAP_LAST", 145 "CONFIG_INV_WAIT" 119 146 }; 120 147 const char *read_fsm_str[] = … … 190 217 "IXR_CMD_CAS_IDLE", 191 218 "IXR_CMD_XRAM_IDLE", 192 "IXR_CMD_READ _NLINE",193 "IXR_CMD_WRITE _NLINE",194 "IXR_CMD_CAS _NLINE",195 "IXR_CMD_XRAM _DATA"219 "IXR_CMD_READ", 220 "IXR_CMD_WRITE", 221 "IXR_CMD_CAS", 222 "IXR_CMD_XRAM" 196 223 }; 197 224 const char *cas_fsm_str[] = … … 235 262 "CLEANUP_UPT_CLEAR", 236 263 "CLEANUP_WRITE_RSP", 237 "CLEANUP_SEND_ACK" 264 "CLEANUP_CONFIG_ACK", 265 "CLEANUP_SEND_CLACK" 238 266 }; 239 267 const char *alloc_dir_fsm_str[] = … … 269 297 "ALLOC_HEAP_CAS", 270 298 "ALLOC_HEAP_CLEANUP", 271 "ALLOC_HEAP_XRAM_RSP" 299 "ALLOC_HEAP_XRAM_RSP", 300 "ALLOC_HEAP_CONFIG" 272 301 }; 273 302 274 303 #define tmpl(x) \ 275 template<typename vci_param> x \ 276 VciMemCache<vci_param> 304 template<typename vci_param_int, \ 305 typename vci_param_ext, \ 306 size_t dspin_in_width, \ 307 size_t dspin_out_width> x \ 308 VciMemCache<vci_param_int, vci_param_ext, dspin_in_width, dspin_out_width> 277 309 278 310 using namespace soclib::common; … … 288 320 const IntTab &srcid_x, // global index on external network 289 321 const IntTab &tgtid_d, // global index on direct network 290 const size_t cc_global_id, // global index on cc network 322 const size_t cc_global_id, // global index on cc network 291 323 const size_t nways, // number of ways per set 292 const size_t nsets, // number of associative sets 324 const size_t nsets, // number of associative sets 293 325 const size_t nwords, // number of words in cache line 294 326 const size_t max_copies, // max number of copies in heap … … 311 343 m_nseg( 0 ), 312 344 m_srcid_x( mtx.indexForId(srcid_x) ), 313 m_initiators( 1 << vci_param ::S ),345 m_initiators( 1 << vci_param_int::S ), 314 346 m_heap_size( heap_size ), 315 347 m_ways( nways ), … … 320 352 m_debug_ok( debug_ok ), 321 353 m_trt_lines(trt_lines), 322 m_trt(t rt_lines, nwords),354 m_trt(this->name(), trt_lines, nwords), 323 355 m_upt_lines(upt_lines), 324 356 m_upt(upt_lines), 325 m_cache_directory(nways, nsets, nwords, vci_param ::N),357 m_cache_directory(nways, nsets, nwords, vci_param_int::N), 326 358 m_cache_data(nways, nsets, nwords), 327 359 m_heap(m_heap_size), … … 332 364 m_x(L2(m_words), 2), 333 365 m_y(L2(m_sets), L2(m_words) + 2), 334 m_z(vci_param ::N - L2(m_sets) - L2(m_words) - 2, L2(m_sets) + L2(m_words) + 2),335 m_nline(vci_param ::N - L2(m_words) - 2, L2(m_words) + 2),366 m_z(vci_param_int::N - L2(m_sets) - L2(m_words) - 2, L2(m_sets) + L2(m_words) + 2), 367 m_nline(vci_param_int::N - L2(m_words) - 2, L2(m_words) + 2), 336 368 #undef L2 337 369 338 370 // XMIN(5 bits) / XMAX(5 bits) / YMIN(5 bits) / YMAX(5 bits) 339 371 // 0b00000 / 0b11111 / 0b00000 / 0b11111 340 m_broadcast_address(0x7C1F), 372 m_broadcast_boundaries(0x7C1F), 373 374 r_tgt_cmd_fsm("r_tgt_cmd_fsm"), 341 375 342 376 // FIFOs … … 365 399 m_cc_receive_to_multi_ack_fifo("m_cc_receive_to_multi_ack_fifo", 4), 366 400 367 r_tgt_cmd_fsm("r_tgt_cmd_fsm"), 368 369 r_read_fsm("r_read_fsm"), 370 371 r_write_fsm("r_write_fsm"), 401 r_config_fsm( "r_config_fsm" ), 402 403 m_config_to_cc_send_inst_fifo( "m_config_to_cc_send_inst_fifo", 8 ), 404 m_config_to_cc_send_srcid_fifo( "m_config_to_cc_send_srcid_fifo", 8 ), 405 406 r_read_fsm( "r_read_fsm" ), 407 408 r_write_fsm( "r_write_fsm" ), 372 409 373 410 m_write_to_cc_send_inst_fifo("m_write_to_cc_send_inst_fifo",8), … … 412 449 r_alloc_heap_reset_cpt("r_alloc_heap_reset_cpt") 413 450 { 451 std::cout << " - Building VciMemCache : " << name << std::endl; 452 414 453 assert(IS_POW_OF_2(nsets)); 415 454 assert(IS_POW_OF_2(nwords)); … … 420 459 421 460 // check Transaction table size 422 assert((uint32_log2(trt_lines) <= vci_param::T) and 423 "Need more bits for VCI TRDID field"); 461 assert((uint32_log2(trt_lines) <= vci_param_ext::T) and 462 "MEMC ERROR : Need more bits for VCI TRDID field"); 463 464 // check internal and external data width 465 assert( (vci_param_int::B == 4 ) and 466 "MEMC ERROR : VCI internal data width must be 32 bits"); 467 468 assert( (vci_param_ext::B == 8) and 469 "MEMC ERROR : VCI external data width must be 64 bits"); 470 471 // Check coherence between internal & external addresses 472 assert( (vci_param_int::N == vci_param_ext::N) and 473 "MEMC ERROR : VCI internal & external addresses must have the same width"); 424 474 425 475 // Get the segments associated to the MemCache … … 429 479 for(seg = m_seglist.begin(); seg != m_seglist.end() ; seg++) 430 480 { 481 std::cout << " => segment " << seg->name() 482 << " / base = " << std::hex << seg->baseAddress() 483 << " / size = " << seg->size() << std::endl; 431 484 m_nseg++; 432 485 } … … 436 489 for(seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++) 437 490 { 491 if ( seg->special() ) m_seg_config = i; 438 492 m_seg[i] = & (*seg); 439 493 i++; … … 475 529 476 530 /////////////////////////////////////////////////////////////////////// 477 tmpl(void) ::start_monitor( vci_addr_t addr, vci_addr_t length)531 tmpl(void) ::start_monitor(addr_t addr, addr_t length) 478 532 /////////////////////////////////////////////////////////////////////// 479 533 { … … 490 544 } 491 545 492 /////////////////////////////////////////////////////////////////////// 493 tmpl(void) ::check_monitor(const char *buf, vci_addr_t addr, data_t data) 494 /////////////////////////////////////////////////////////////////////// 546 //////////////////////////////////////////////// 547 tmpl(void) ::check_monitor( const char *buf, 548 addr_t addr, 549 data_t data, 550 bool read ) 551 //////////////////////////////////////////////// 495 552 { 496 553 if((addr >= m_monitor_base) and 497 554 (addr < m_monitor_base + m_monitor_length)) 498 555 { 499 std::cout << " MEMC Write Monitor : " << buf << " Address = " << std::hex << addr 500 << " / Data = " << data << " at cycle " << std::dec << m_cpt_cycles << std::endl; 556 if ( read ) std::cout << " Monitor MEMC Read "; 557 else std::cout << " Monitor MEMC Write "; 558 std::cout << buf 559 << " / Address = " << std::hex << addr 560 << " / Data = " << data 561 << " at cycle " << std::dec << m_cpt_cycles << std::endl; 501 562 } 502 563 } 503 564 504 ///////////////////////////////////////////////////////////////////////505 tmpl(void) ::check_monitor_read(const char *buf, vci_addr_t addr)506 ///////////////////////////////////////////////////////////////////////507 {508 if((addr >= m_monitor_base) and509 (addr < m_monitor_base + m_monitor_length))510 {511 std::cout << " MEMC Read Monitor : " << buf << " Address = " << std::hex << addr512 << std::endl;513 }514 }515 516 565 ///////////////////////////////////////////////////// 517 tmpl(void) ::copies_monitor( vci_addr_t addr)566 tmpl(void) ::copies_monitor(addr_t addr) 518 567 ///////////////////////////////////////////////////// 519 568 { 520 569 DirectoryEntry entry = m_cache_directory.read_neutral(addr); 570 521 571 if((entry.count != m_debug_previous_count) or 522 572 (entry.valid != m_debug_previous_hit)) 523 573 { 524 std::cout << " MEMC " << name()525 << " cache changeat cycle " << std::dec << m_cpt_cycles574 std::cout << "Monitor MEMC " << name() 575 << " at cycle " << std::dec << m_cpt_cycles 526 576 << " for address " << std::hex << addr 527 577 << " / HIT = " << entry.valid … … 537 587 { 538 588 std::cout << "MEMC " << name() << std::endl; 539 std::cout << " " << tgt_cmd_fsm_str[r_tgt_cmd_fsm] 540 << " | " << tgt_rsp_fsm_str[r_tgt_rsp_fsm] 541 << " | " << read_fsm_str[r_read_fsm] 542 << " | " << write_fsm_str[r_write_fsm] 543 << " | " << cas_fsm_str[r_cas_fsm] 544 << " | " << cleanup_fsm_str[r_cleanup_fsm] << std::endl; 545 std::cout << " " << cc_send_fsm_str[r_cc_send_fsm] 546 << " | " << cc_receive_fsm_str[r_cc_receive_fsm] 547 << " | " << multi_ack_fsm_str[r_multi_ack_fsm] 548 << " | " << ixr_cmd_fsm_str[r_ixr_cmd_fsm] 549 << " | " << ixr_rsp_fsm_str[r_ixr_rsp_fsm] 589 std::cout << " " << tgt_cmd_fsm_str[r_tgt_cmd_fsm.read()] 590 << " | " << tgt_rsp_fsm_str[r_tgt_rsp_fsm.read()] 591 << " | " << read_fsm_str[r_read_fsm.read()] 592 << " | " << write_fsm_str[r_write_fsm.read()] 593 << " | " << cas_fsm_str[r_cas_fsm.read()] 594 << " | " << config_fsm_str[r_config_fsm.read()] 595 << " | " << cleanup_fsm_str[r_cleanup_fsm.read()] << std::endl; 596 std::cout << " " << cc_send_fsm_str[r_cc_send_fsm.read()] 597 << " | " << cc_receive_fsm_str[r_cc_receive_fsm.read()] 598 << " | " << multi_ack_fsm_str[r_multi_ack_fsm.read()] 599 << " | " << ixr_cmd_fsm_str[r_ixr_cmd_fsm.read()] 600 << " | " << ixr_rsp_fsm_str[r_ixr_rsp_fsm.read()] 550 601 << " | " << xram_rsp_fsm_str[r_xram_rsp_fsm] << std::endl; 551 552 //m_llsc_table.print_trace(); 553 602 std::cout << " " << alloc_dir_fsm_str[r_alloc_dir_fsm.read()] 603 << " | " << alloc_trt_fsm_str[r_alloc_trt_fsm.read()] 604 << " | " << alloc_upt_fsm_str[r_alloc_upt_fsm.read()] 605 << " | " << alloc_heap_fsm_str[r_alloc_heap_fsm.read()] << std::endl; 554 606 } 555 607 … … 613 665 // Initializing FSMs 614 666 r_tgt_cmd_fsm = TGT_CMD_IDLE; 615 r_tgt_rsp_fsm = TGT_RSP_READ_IDLE; 667 r_config_fsm = CONFIG_IDLE; 668 r_tgt_rsp_fsm = TGT_RSP_TGT_CMD_IDLE; 616 669 r_cc_send_fsm = CC_SEND_XRAM_RSP_IDLE; 617 670 r_cc_receive_fsm = CC_RECEIVE_IDLE; … … 629 682 r_ixr_cmd_fsm = IXR_CMD_READ_IDLE; 630 683 631 m_debug_global = false; 632 m_debug_tgt_cmd_fsm = false; 633 m_debug_tgt_rsp_fsm = false; 634 m_debug_cc_send_fsm = false; 635 m_debug_cc_receive_fsm = false; 636 m_debug_multi_ack_fsm = false; 637 m_debug_read_fsm = false; 638 m_debug_write_fsm = false; 639 m_debug_cas_fsm = false; 640 m_debug_cleanup_fsm = false; 641 m_debug_ixr_cmd_fsm = false; 642 m_debug_ixr_rsp_fsm = false; 643 m_debug_xram_rsp_fsm = false; 684 m_debug = false; 644 685 m_debug_previous_hit = false; 645 686 m_debug_previous_count = 0; … … 672 713 m_cmd_cas_eop_fifo.init() ; 673 714 715 r_config_cmd = MEMC_CMD_NOP; 716 r_config_lock = false; 717 718 m_config_to_cc_send_inst_fifo.init(); 719 m_config_to_cc_send_srcid_fifo.init(); 720 #if L1_MULTI_CACHE 721 m_config_to_cc_send_cache_id_fifo.init(); 722 #endif 723 724 r_tgt_cmd_to_tgt_rsp_req = false; 725 674 726 r_read_to_tgt_rsp_req = false; 675 727 r_read_to_ixr_cmd_req = false; … … 677 729 r_write_to_tgt_rsp_req = false; 678 730 r_write_to_ixr_cmd_req = false; 679 r_write_to_cc_send_multi_req = false;680 r_write_to_cc_send_brdcast_req = false;731 r_write_to_cc_send_multi_req = false; 732 r_write_to_cc_send_brdcast_req = false; 681 733 r_write_to_multi_ack_req = false; 682 734 … … 765 817 bool cc_receive_to_cleanup_fifo_get = false; 766 818 bool cc_receive_to_cleanup_fifo_put = false; 767 819 768 820 bool cc_receive_to_multi_ack_fifo_get = false; 769 821 bool cc_receive_to_multi_ack_fifo_put = false; … … 787 839 #endif 788 840 841 bool config_to_cc_send_fifo_put = false; 842 bool config_to_cc_send_fifo_get = false; 843 bool config_to_cc_send_fifo_inst = false; 844 size_t config_to_cc_send_fifo_srcid = 0; 845 789 846 bool cas_to_cc_send_fifo_put = false; 790 847 bool cas_to_cc_send_fifo_get = false; … … 796 853 #endif 797 854 798 m_debug_global = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 799 m_debug_tgt_cmd_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 800 m_debug_tgt_rsp_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 801 m_debug_cc_send_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 802 m_debug_cc_receive_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 803 m_debug_multi_ack_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 804 m_debug_read_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 805 m_debug_write_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 806 m_debug_cas_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 807 m_debug_cleanup_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 808 m_debug_ixr_cmd_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 809 m_debug_ixr_rsp_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 810 m_debug_xram_rsp_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 855 m_debug = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 811 856 812 857 #if DEBUG_MEMC_GLOBAL 813 if(m_debug_global)814 858 if(m_debug) 859 { 815 860 std::cout 816 861 << "---------------------------------------------" << std::dec << std::endl 817 << "MEM_CACHE " << name() 862 << "MEM_CACHE " << name() 818 863 << " ; Time = " << m_cpt_cycles << std::endl 819 864 << " - TGT_CMD FSM = " << tgt_cmd_fsm_str[r_tgt_cmd_fsm.read()] << std::endl … … 833 878 << " - ALLOC_UPT FSM = " << alloc_upt_fsm_str[r_alloc_upt_fsm.read()] << std::endl 834 879 << " - ALLOC_HEAP FSM = " << alloc_heap_fsm_str[r_alloc_heap_fsm.read()] << std::endl; 835 880 } 836 881 #endif 837 882 … … 839 884 // TGT_CMD FSM 840 885 //////////////////////////////////////////////////////////////////////////////////// 841 // The TGT_CMD_FSM controls the incoming VCI command pakets from the processors 886 // The TGT_CMD_FSM controls the incoming VCI command pakets from the processors, 887 // and dispatch these commands to the proper FSM through dedicated FIFOs. 842 888 // 843 // There are 5 types of accepted commands : 844 // - READ : A READ request has a length of 1 VCI cell. It can be a single word 845 // or an entire cache line, depending on the PLEN value. 846 // - WRITE : A WRITE request has a maximum length of 16 cells, and can only 847 // concern words in a same line. 848 // - CAS : A CAS request has a length of 2 cells or 4 cells. 849 // - LL : An LL request has a length of 1 cell. 850 // - SC : An SC request has a length of 2 cells. First cell contains the 851 // acces key, second cell the data to write in case of success. 889 // There are 5 types of commands accepted in the XRAM segment: 890 // - READ : A READ request has a length of 1 VCI flit. It can be a single word 891 // or an entire cache line, depending on the PLEN value => READ FSM 892 // - WRITE : A WRITE request has a maximum length of 16 flits, and can only 893 // concern words in a same line => WRITE FSM 894 // - CAS : A CAS request has a length of 2 flits or 4 flits => CAS FSM 895 // - LL : An LL request has a length of 1 flit => READ FSM 896 // - SC : An SC request has a length of 2 flits. First flit contains the 897 // acces key, second flit the data to write => WRITE FSM. 898 // 899 // The READ/WRITE commands accepted in the configuration segment are targeting 900 // configuration or status registers. They must contain one single flit. 901 // - For almost all addressable registers, the response is returned immediately. 902 // - For MEMC_CMD_TYPE, the response is delayed until the operation is completed. 852 903 //////////////////////////////////////////////////////////////////////////////////// 853 904 854 905 switch(r_tgt_cmd_fsm.read()) 855 906 { 856 857 case TGT_CMD_IDLE: 858 859 907 ////////////////// 908 case TGT_CMD_IDLE: // waiting a VCI command (RAM or CONFIG) 909 if(p_vci_tgt.cmdval) 910 { 860 911 861 912 #if DEBUG_MEMC_TGT_CMD 862 if(m_debug_tgt_cmd_fsm) 863 { 864 std::cout 865 << " <MEMC " << name() 866 << ".TGT_CMD_IDLE> Receive command from srcid " 867 << std::dec << p_vci_tgt.srcid.read() 868 << " / for address " 869 << std::hex << p_vci_tgt.address.read() 870 << std::endl; 871 } 913 if(m_debug) 914 std::cout << " <MEMC " << name() 915 << " TGT_CMD_IDLE> Receive command from srcid " 916 << std::hex << p_vci_tgt.srcid.read() 917 << " / address " << std::hex << p_vci_tgt.address.read() << std::endl; 872 918 #endif 873 919 // checking segmentation violation 874 vci_addr_t address = p_vci_tgt.address.read(); 875 uint32_t plen = p_vci_tgt.plen.read(); 876 bool found = false; 877 for(size_t seg_id = 0 ; seg_id < m_nseg ; seg_id++) 878 { 879 if(m_seg[seg_id]->contains(address) && 880 m_seg[seg_id]->contains(address + plen - vci_param::B)) 881 { 882 found = true; 883 } 884 } 885 if(not found) 886 { 887 std::cout << "VCI_MEM_CACHE ERROR " << name() << std::endl; 888 std::cout 889 << "Out of segment VCI address in TGT_CMD_IDLE state (address = " 890 << std::hex << address << ", srcid = " << p_vci_tgt.srcid.read() 891 << std::dec << ", cycle = " << m_cpt_cycles << ")" << std::endl; 892 exit(0); 893 } 894 895 if(p_vci_tgt.cmd.read() == vci_param::CMD_READ) 896 { 897 // check that the pktid is either : 898 // TYPE_READ_DATA_UNC 899 // TYPE_READ_DATA_MISS 900 // TYPE_READ_INS_UNC 901 // TYPE_READ_INS_MISS 902 // ==> bit2 must be zero with the TSAR encoding 903 // ==> mask = 0b0100 = 0x4 904 assert(((p_vci_tgt.pktid.read() & 0x4) == 0x0) && 905 "The type specified in the pktid field is incompatible with the READ CMD"); 906 r_tgt_cmd_fsm = TGT_CMD_READ; 907 } 908 else if(p_vci_tgt.cmd.read() == vci_param::CMD_WRITE) 909 { 910 // check that the pktid is TYPE_WRITE 911 // ==> TYPE_WRITE = X100 with the TSAR encoding 912 // ==> mask = 0b0111 = 0x7 913 assert(((p_vci_tgt.pktid.read() & 0x7) == 0x4) && 914 "The type specified in the pktid field is incompatible with the WRITE CMD"); 915 r_tgt_cmd_fsm = TGT_CMD_WRITE; 916 } 917 else if(p_vci_tgt.cmd.read() == vci_param::CMD_LOCKED_READ) 918 { 919 // check that the pktid is TYPE_LL 920 // ==> TYPE_LL = X110 with the TSAR encoding 921 // ==> mask = 0b0111 = 0x7 922 assert(((p_vci_tgt.pktid.read() & 0x7) == 0x6) && 923 "The type specified in the pktid field is incompatible with the LL CMD"); 924 r_tgt_cmd_fsm = TGT_CMD_READ; 925 } 926 else if(p_vci_tgt.cmd.read() == vci_param::CMD_NOP) 927 { 928 // check that the pktid is either : 929 // TYPE_CAS 930 // TYPE_SC 931 // ==> TYPE_CAS = X101 with the TSAR encoding 932 // ==> TYPE_SC = X111 with the TSAR encoding 933 // ==> mask = 0b0101 = 0x5 934 assert(((p_vci_tgt.pktid.read() & 0x5) == 0x5) && 935 "The type specified in the pktid field is incompatible with the NOP CMD"); 936 937 if((p_vci_tgt.pktid.read() & 0x7) == TYPE_CAS) 938 r_tgt_cmd_fsm = TGT_CMD_CAS; 939 else // TYPE_SC 940 r_tgt_cmd_fsm = TGT_CMD_WRITE; 920 addr_t address = p_vci_tgt.address.read(); 921 uint32_t plen = p_vci_tgt.plen.read(); 922 bool found = false; 923 bool config = false; 924 925 // register arguments for response (segmentation violation or config) 926 r_tgt_cmd_to_tgt_rsp_srcid = p_vci_tgt.srcid.read(); 927 r_tgt_cmd_to_tgt_rsp_trdid = p_vci_tgt.trdid.read(); 928 r_tgt_cmd_to_tgt_rsp_pktid = p_vci_tgt.pktid.read(); 929 930 for(size_t seg_id = 0 ; (seg_id < m_nseg) and not found ; seg_id++) 931 { 932 if( m_seg[seg_id]->contains(address) and 933 m_seg[seg_id]->contains(address + plen - vci_param_int::B) ) 934 { 935 found = true; 936 if ( m_seg[seg_id]->special() ) config = true; 937 } 938 } 939 940 if ( not found ) /////////// out of segment error 941 { 942 r_tgt_cmd_fsm = TGT_CMD_ERROR; 943 } 944 else if ( config ) /////////// configuration command 945 { 946 if ( not p_vci_tgt.eop.read() ) r_tgt_cmd_fsm = TGT_CMD_ERROR; 947 else r_tgt_cmd_fsm = TGT_CMD_CONFIG; 948 } 949 else //////////// memory access 950 { 951 if ( p_vci_tgt.cmd.read() == vci_param_int::CMD_READ ) 952 { 953 // check that the pktid is either : 954 // TYPE_READ_DATA_UNC 955 // TYPE_READ_DATA_MISS 956 // TYPE_READ_INS_UNC 957 // TYPE_READ_INS_MISS 958 // ==> bit2 must be zero with the TSAR encoding 959 // ==> mask = 0b0100 = 0x4 960 assert( ((p_vci_tgt.pktid.read() & 0x4) == 0x0) and 961 "The type specified in the pktid field is incompatible with the READ CMD"); 962 r_tgt_cmd_fsm = TGT_CMD_READ; 963 } 964 else if(p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) 965 { 966 // check that the pktid is TYPE_WRITE 967 // ==> TYPE_WRITE = X100 with the TSAR encoding 968 // ==> mask = 0b0111 = 0x7 969 assert(((p_vci_tgt.pktid.read() & 0x7) == 0x4) and 970 "The type specified in the pktid field is incompatible with the WRITE CMD"); 971 r_tgt_cmd_fsm = TGT_CMD_WRITE; 972 } 973 else if(p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ) 974 { 975 // check that the pktid is TYPE_LL 976 // ==> TYPE_LL = X110 with the TSAR encoding 977 // ==> mask = 0b0111 = 0x7 978 assert(((p_vci_tgt.pktid.read() & 0x7) == 0x6) and 979 "The type specified in the pktid field is incompatible with the LL CMD"); 980 r_tgt_cmd_fsm = TGT_CMD_READ; 981 } 982 else if(p_vci_tgt.cmd.read() == vci_param_int::CMD_NOP) 983 { 984 // check that the pktid is either : 985 // TYPE_CAS 986 // TYPE_SC 987 // ==> TYPE_CAS = X101 with the TSAR encoding 988 // ==> TYPE_SC = X111 with the TSAR encoding 989 // ==> mask = 0b0101 = 0x5 990 assert(((p_vci_tgt.pktid.read() & 0x5) == 0x5) and 991 "The type specified in the pktid field is incompatible with the NOP CMD"); 992 993 if((p_vci_tgt.pktid.read() & 0x7) == TYPE_CAS) r_tgt_cmd_fsm = TGT_CMD_CAS; 994 else r_tgt_cmd_fsm = TGT_CMD_WRITE; 995 } 996 else 997 { 998 r_tgt_cmd_fsm = TGT_CMD_ERROR; 999 } 1000 } 1001 } 1002 break; 1003 1004 /////////////////// 1005 case TGT_CMD_ERROR: // response error must be sent 1006 1007 // wait if pending TGT_CMD request to TGT_RSP FSM 1008 if(r_tgt_cmd_to_tgt_rsp_req.read()) break; 1009 1010 // consume all the command packet flits before sending response error 1011 if ( p_vci_tgt.cmdval and p_vci_tgt.eop ) 1012 { 1013 r_tgt_cmd_to_tgt_rsp_req = true; 1014 r_tgt_cmd_to_tgt_rsp_error = 1; 1015 r_tgt_cmd_fsm = TGT_CMD_IDLE; 1016 1017 #if DEBUG_MEMC_TGT_CMD 1018 if(m_debug) 1019 std::cout << " <MEMC " << name() 1020 << " TGT_CMD_ERROR> Segmentation violation:" 1021 << " address = " << std::hex << p_vci_tgt.address.read() 1022 << " / srcid = " << p_vci_tgt.srcid.read() 1023 << " / trdid = " << p_vci_tgt.trdid.read() 1024 << " / pktid = " << p_vci_tgt.pktid.read() 1025 << " / plen = " << std::dec << p_vci_tgt.plen.read() << std::endl; 1026 #endif 1027 1028 } 1029 break; 1030 1031 //////////////////// 1032 case TGT_CMD_CONFIG: // execute config request and return response 1033 { 1034 addr_t seg_base = m_seg[m_seg_config]->baseAddress(); 1035 addr_t address = p_vci_tgt.address.read(); 1036 size_t cell = (address - seg_base)/vci_param_int::B; 1037 1038 bool need_rsp; 1039 size_t error; 1040 uint32_t rdata = 0; // default value 1041 1042 if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_READ) // get lock 1043 and (cell == MEMC_LOCK) ) 1044 { 1045 rdata = (uint32_t)r_config_lock.read(); 1046 need_rsp = true; 1047 error = 0; 1048 r_config_lock = true; 1049 } 1050 else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // release lock 1051 and (cell == MEMC_LOCK) ) 1052 { 1053 need_rsp = true; 1054 error = 0; 1055 r_config_lock = false; 1056 } 1057 else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // set addr_lo 1058 and (cell == MEMC_ADDR_LO) ) 1059 { 1060 need_rsp = true; 1061 error = 0; 1062 r_config_address = (r_config_address.read() & 0xFFFFFFFF00000000LL) | 1063 (addr_t)p_vci_tgt.wdata.read(); 1064 } 1065 else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // set addr_hi 1066 and (cell == MEMC_ADDR_HI) ) 1067 { 1068 need_rsp = true; 1069 error = 0; 1070 r_config_address = (r_config_address.read() & 0x00000000FFFFFFFFLL) | 1071 ((addr_t)p_vci_tgt.wdata.read())<<32; 1072 } 1073 else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // set buf_lines 1074 and (cell == MEMC_BUF_LENGTH) ) 1075 { 1076 need_rsp = true; 1077 error = 0; 1078 size_t lines = (size_t)(p_vci_tgt.wdata.read()/(m_words<<2)); 1079 if ( r_config_address.read()/(m_words*vci_param_int::B) ) lines++; 1080 r_config_nlines = lines; 1081 } 1082 else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE) // set cmd type 1083 and (cell == MEMC_CMD_TYPE) ) 1084 { 1085 need_rsp = false; 1086 error = 0; 1087 r_config_cmd = p_vci_tgt.wdata.read(); 1088 r_config_srcid = p_vci_tgt.srcid.read(); 1089 r_config_trdid = p_vci_tgt.trdid.read(); 1090 r_config_pktid = p_vci_tgt.pktid.read(); 941 1091 } 942 1092 else 943 1093 { 944 std::cout << "VCI_MEM_CACHE ERROR " << name() 945 << " TGT_CMD_IDLE state" << std::endl; 946 std::cout << " illegal VCI command type" << std::endl; 947 exit(0); 948 } 949 } 950 break; 951 952 ////////////////// 953 case TGT_CMD_READ: 954 // This test checks that the read does not cross a cache line limit. 955 // It must not be taken into account when dealing with an LL CMD. 956 if(((m_x[(vci_addr_t) p_vci_tgt.address.read()]+ (p_vci_tgt.plen.read() >>2)) > 16) && (p_vci_tgt.cmd.read() != vci_param::CMD_LOCKED_READ)) 957 { 958 std::cout 959 << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state" 960 << std::endl; 961 std::cout 962 << " illegal address/plen combination for VCI read command" << std::endl; 1094 need_rsp = true; 1095 error = 1; 1096 } 1097 1098 if ( need_rsp ) 1099 { 1100 // blocked if previous pending request to TGT_RSP FSM 1101 if ( r_tgt_cmd_to_tgt_rsp_req.read() ) break; 1102 1103 r_tgt_cmd_to_tgt_rsp_req = true; 1104 r_tgt_cmd_to_tgt_rsp_error = error; 1105 r_tgt_cmd_to_tgt_rsp_rdata = rdata; 1106 r_tgt_cmd_fsm = TGT_CMD_IDLE; 1107 } 1108 else 1109 { 1110 r_tgt_cmd_fsm = TGT_CMD_IDLE; 1111 } 1112 1113 #if DEBUG_MEMC_TGT_CMD 1114 if(m_debug) 1115 std::cout << " <MEMC " << name() << " TGT_CMD_CONFIG> Configuration request:" 1116 << " address = " << std::hex << p_vci_tgt.address.read() 1117 << " / wdata = " << p_vci_tgt.wdata.read() 1118 << " / error = " << error << std::endl; 1119 #endif 1120 break; 1121 } 1122 ////////////////// 1123 case TGT_CMD_READ: // Push a read request into read fifo 1124 1125 // check that the read does not cross a cache line limit. 1126 if ( ((m_x[(addr_t) p_vci_tgt.address.read()]+ (p_vci_tgt.plen.read() >>2)) > 16) and 1127 (p_vci_tgt.cmd.read() != vci_param_int::CMD_LOCKED_READ)) 1128 { 1129 std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state" 1130 << " illegal address/plen for VCI read command" << std::endl; 963 1131 exit(0); 964 } 965 if(!p_vci_tgt.eop.read()) 966 { 967 std::cout 968 << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state" 969 << std::endl; 970 std::cout 971 << " read or ll command packets must contain one single flit" 972 << std::endl; 1132 } 1133 // check single flit 1134 if(!p_vci_tgt.eop.read()) 1135 { 1136 std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state" 1137 << " read command packet must contain one single flit" << std::endl; 973 1138 exit(0); 974 } 975 if((p_vci_tgt.cmd.read() == vci_param::CMD_LOCKED_READ) && (p_vci_tgt.plen.read() != 8)) 976 { 977 std::cout 978 << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state" 979 << std::endl; 980 std::cout 981 << " ll command packets must have a plen of 8" 982 << std::endl; 1139 } 1140 // check plen for LL 1141 if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ) and 1142 (p_vci_tgt.plen.read() != 8) ) 1143 { 1144 std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state" 1145 << " ll command packets must have a plen of 8" << std::endl; 983 1146 exit(0); 984 985 986 if(p_vci_tgt.cmdval && m_cmd_read_addr_fifo.wok())987 1147 } 1148 1149 if ( p_vci_tgt.cmdval and m_cmd_read_addr_fifo.wok() ) 1150 { 988 1151 989 1152 #if DEBUG_MEMC_TGT_CMD 990 if(m_debug_tgt_cmd_fsm) 991 { 992 std::cout << " <MEMC " << name() << ".TGT_CMD_READ> Push into read_fifo:" 993 << " address = " << std::hex << p_vci_tgt.address.read() 994 << " srcid = " << std::dec << p_vci_tgt.srcid.read() 995 << " trdid = " << p_vci_tgt.trdid.read() 996 << " pktid = " << p_vci_tgt.pktid.read() 997 << " plen = " << std::dec << p_vci_tgt.plen.read() << std::endl; 998 } 1153 if(m_debug) 1154 std::cout << " <MEMC " << name() << " TGT_CMD_READ> Push into read_fifo:" 1155 << " address = " << std::hex << p_vci_tgt.address.read() 1156 << " / srcid = " << p_vci_tgt.srcid.read() 1157 << " / trdid = " << p_vci_tgt.trdid.read() 1158 << " / pktid = " << p_vci_tgt.pktid.read() 1159 << " / plen = " << std::dec << p_vci_tgt.plen.read() << std::endl; 999 1160 #endif 1000 1161 cmd_read_fifo_put = true; 1001 if(p_vci_tgt.cmd.read() == vci_param::CMD_LOCKED_READ) 1002 m_cpt_ll++; 1003 else 1004 m_cpt_read++; 1162 if(p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ) m_cpt_ll++; 1163 else m_cpt_read++; 1005 1164 r_tgt_cmd_fsm = TGT_CMD_IDLE; 1006 1007 1008 1009 1165 } 1166 break; 1167 1168 /////////////////// 1010 1169 case TGT_CMD_WRITE: 1011 if(p_vci_tgt.cmdval &&m_cmd_write_addr_fifo.wok())1012 1170 if(p_vci_tgt.cmdval and m_cmd_write_addr_fifo.wok()) 1171 { 1013 1172 1014 1173 #if DEBUG_MEMC_TGT_CMD 1015 if(m_debug_tgt_cmd_fsm) 1016 { 1017 std::cout << " <MEMC " << name() << ".TGT_CMD_WRITE> Push into write_fifo:" 1018 << " address = " << std::hex << p_vci_tgt.address.read() 1019 << " srcid = " << std::dec << p_vci_tgt.srcid.read() 1020 << " trdid = " << p_vci_tgt.trdid.read() 1021 << " pktid = " << p_vci_tgt.pktid.read() 1022 << " wdata = " << std::hex << p_vci_tgt.wdata.read() 1023 << " be = " << p_vci_tgt.be.read() 1024 << " plen = " << std::dec << p_vci_tgt.plen.read() << std::endl; 1025 } 1174 if(m_debug) 1175 std::cout << " <MEMC " << name() << " TGT_CMD_WRITE> Push into write_fifo:" 1176 << " address = " << std::hex << p_vci_tgt.address.read() 1177 << " / srcid = " << p_vci_tgt.srcid.read() 1178 << " / trdid = " << p_vci_tgt.trdid.read() 1179 << " / pktid = " << p_vci_tgt.pktid.read() 1180 << " / wdata = " << p_vci_tgt.wdata.read() 1181 << " / be = " << p_vci_tgt.be.read() 1182 << " / plen = " << std::dec << p_vci_tgt.plen.read() << std::endl; 1026 1183 #endif 1027 1184 cmd_write_fifo_put = true; 1028 1185 if(p_vci_tgt.eop) r_tgt_cmd_fsm = TGT_CMD_IDLE; 1029 1030 1031 1032 ////////////////////1186 } 1187 break; 1188 1189 ///////////////// 1033 1190 case TGT_CMD_CAS: 1034 if((p_vci_tgt.plen.read() != 8) && (p_vci_tgt.plen.read() != 16)) 1035 { 1036 std::cout 1037 << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_CAS state" 1038 << std::endl 1039 << "illegal format for CAS command " << std::endl; 1040 1191 if((p_vci_tgt.plen.read() != 8) and (p_vci_tgt.plen.read() != 16)) 1192 { 1193 std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_CAS state" 1194 << "illegal format for CAS command " << std::endl; 1041 1195 exit(0); 1042 1043 1044 if(p_vci_tgt.cmdval &&m_cmd_cas_addr_fifo.wok())1045 1196 } 1197 1198 if(p_vci_tgt.cmdval and m_cmd_cas_addr_fifo.wok()) 1199 { 1046 1200 1047 1201 #if DEBUG_MEMC_TGT_CMD 1048 if(m_debug_tgt_cmd_fsm) 1049 { 1050 std::cout << " <MEMC " << name() << ".TGT_CMD_CAS> Pushing command into cmd_cas_fifo:" 1051 << " address = " << std::hex << p_vci_tgt.address.read() 1052 << " srcid = " << std::dec << p_vci_tgt.srcid.read() 1053 << " trdid = " << p_vci_tgt.trdid.read() 1054 << " pktid = " << p_vci_tgt.pktid.read() 1055 << " wdata = " << std::hex << p_vci_tgt.wdata.read() 1056 << " be = " << p_vci_tgt.be.read() 1057 << " plen = " << std::dec << p_vci_tgt.plen.read() << std::endl; 1058 } 1202 if(m_debug) 1203 std::cout << " <MEMC " << name() << " TGT_CMD_CAS> Pushing command into cmd_cas_fifo:" 1204 << " address = " << std::hex << p_vci_tgt.address.read() 1205 << " srcid = " << p_vci_tgt.srcid.read() 1206 << " trdid = " << p_vci_tgt.trdid.read() 1207 << " pktid = " << p_vci_tgt.pktid.read() 1208 << " wdata = " << p_vci_tgt.wdata.read() 1209 << " be = " << p_vci_tgt.be.read() 1210 << " plen = " << std::dec << p_vci_tgt.plen.read() << std::endl; 1059 1211 #endif 1060 1212 cmd_cas_fifo_put = true; 1061 1213 if(p_vci_tgt.eop) r_tgt_cmd_fsm = TGT_CMD_IDLE; 1062 1063 1214 } 1215 break; 1064 1216 } // end switch tgt_cmd_fsm 1065 1217 … … 1071 1223 // update the UPT. 1072 1224 // 1073 // It can be update or inval requests initiated by the WRITE or CAS FSM, 1074 // or inval requests initiated by the XRAM_RSP FSM. 1075 // It can also be a direct request from the WRITE FSM. 1225 // - The FSM decrements the proper entry in UPT, 1226 // and clear the UPT entry when all responses have been received. 1227 // - If required, it sends a request to the TGT_RSP FSM to complete 1228 // a pending write transaction. 1229 // - If required, it sends an acknowledge to the CONFIG FSM to signal 1230 // completion of a line inval. 1076 1231 // 1077 // The FSM decrements the proper entry in UPT. 1078 // It sends a request to the TGT_RSP FSM to complete the pending 1079 // write transaction (acknowledge response to the writer processor), 1080 // and clear the UPT entry when all responses have been received. 1081 // 1082 // All those response packets are one flit packet. 1083 // The index in the Table is defined in the UPDT_TABLE INDEX field, and 1084 // the transaction type is defined in the UPT entry. 1232 // All those multi-ack packets are one flit packet. 1233 // The index in the UPT is defined in the UPDTID field. 1085 1234 //////////////////////////////////////////////////////////////////////// 1086 1235 1087 1236 switch(r_multi_ack_fsm.read()) 1088 1237 { 1238 //////////////////// 1089 1239 case MULTI_ACK_IDLE: 1090 1240 { 1091 1241 bool multi_ack_fifo_rok = m_cc_receive_to_multi_ack_fifo.rok(); 1092 1242 1093 // None Multicast Acknowledgement received and 1094 // none WRITE FSM UPT decrement request 1095 if( not multi_ack_fifo_rok and 1096 not r_write_to_multi_ack_req.read()) 1097 { 1243 // No CC_RECEIVE FSM request and no WRITE FSM request 1244 if( not multi_ack_fifo_rok and not r_write_to_multi_ack_req.read()) 1098 1245 break; 1099 } 1100 1101 // WRITE FSM request to decrement update table response counter 1102 // Priority to Multicast Acknowledgement priority 1246 1247 uint8_t updt_index; 1248 1249 // handling WRITE FSM request to decrement update table response 1250 // counter if no CC_RECEIVE FSM request 1103 1251 if(not multi_ack_fifo_rok) 1104 1252 { 1253 updt_index = r_write_to_multi_ack_upt_index.read(); 1105 1254 r_write_to_multi_ack_req = false; 1106 r_multi_ack_upt_index = r_write_to_multi_ack_upt_index.read(); 1107 r_multi_ack_fsm = MULTI_ACK_UPT_LOCK; 1108 1109 break; 1110 } 1111 1112 // Multicast Acknowledgement received 1113 uint64_t flit = m_cc_receive_to_multi_ack_fifo.read(); 1114 1115 uint8_t updt_index = 1116 DspinDhccpParam::dspin_get(flit, DspinDhccpParam::MULTI_ACK_UPDT_INDEX); 1117 1118 bool eop = 1119 (DspinDhccpParam::dspin_get(flit, DspinDhccpParam::FROM_L1_EOP) == 0x1); 1120 1121 if(updt_index >= m_upt.size()) 1122 { 1123 std::cout 1124 << "VCI_MEM_CACHE ERROR " << name() 1125 << " MULTI_ACK_IDLE state" << std::endl 1126 << "index too large for UPT: " 1127 << std::dec 1128 << " / UPT index = " << updt_index 1129 << " / UPT size = " << m_upt.size() 1130 << std::endl; 1131 1132 exit(0); 1133 } 1134 1135 if(not eop) 1136 { 1137 std::cout 1138 << "VCI_MEM_CACHE ERROR " << name() 1139 << " MULTI_ACK_IDLE state" << std::endl 1140 << "A Multicast Acknowledgement must be an one flit packet" 1141 << std::endl; 1142 1143 exit(0); 1144 } 1145 1146 cc_receive_to_multi_ack_fifo_get = true; 1147 r_multi_ack_upt_index = updt_index; 1148 r_multi_ack_fsm = MULTI_ACK_UPT_LOCK; 1255 } 1256 // Handling CC_RECEIVE FSM request 1257 else 1258 { 1259 uint64_t flit = m_cc_receive_to_multi_ack_fifo.read(); 1260 updt_index = DspinDhccpParam::dspin_get(flit, 1261 DspinDhccpParam::MULTI_ACK_UPDT_INDEX); 1262 1263 cc_receive_to_multi_ack_fifo_get = true; 1264 } 1265 1266 assert((updt_index < m_upt.size()) and 1267 "VCI_MEM_CACHE ERROR in MULTI_ACK_IDLE : " 1268 "index too large for UPT"); 1269 1270 r_multi_ack_upt_index = updt_index; 1271 r_multi_ack_fsm = MULTI_ACK_UPT_LOCK; 1149 1272 1150 1273 #if DEBUG_MEMC_MULTI_ACK 1151 if(m_debug_multi_ack_fsm) 1152 { 1153 std::cout 1154 << " <MEMC " << name() 1155 << ".MULTI_ACK_IDLE> Response for UPT entry " 1156 << updt_index 1157 << std::endl; 1158 } 1274 if(m_debug) 1275 { 1276 if (multi_ack_fifo_rok) 1277 { 1278 std::cout << " <MEMC " << name() 1279 << " MULTI_ACK_IDLE> Response for UPT entry " 1280 << (size_t)updt_index << std::endl; 1281 } 1282 else 1283 { 1284 std::cout << " <MEMC " << name() 1285 << " MULTI_ACK_IDLE> Write FSM request to decrement UPT entry " 1286 << updt_index << std::endl; 1287 } 1288 } 1159 1289 #endif 1160 1290 break; 1161 1291 } 1162 1292 1293 //////////////////////// 1163 1294 case MULTI_ACK_UPT_LOCK: 1164 1295 { 1165 1296 // get lock to the UPDATE table 1166 1297 if(r_alloc_upt_fsm.read() != ALLOC_UPT_MULTI_ACK) break; … … 1172 1303 if(not valid) 1173 1304 { 1174 std::cout 1175 << "VCI_MEM_CACHE ERROR " << name() 1176 << " MULTI_ACK_UPT_LOCK state" << std::endl 1177 << "unsuccessful access to decrement the UPT" 1178 << std::endl; 1179 1180 exit(0); 1305 std::cout << "VCI_MEM_CACHE ERROR " << name() 1306 << " MULTI_ACK_UPT_LOCK state" << std::endl 1307 << "unsuccessful access to decrement the UPT" << std::endl; 1308 exit(0); 1181 1309 } 1182 1310 … … 1191 1319 1192 1320 #if DEBUG_MEMC_MULTI_ACK 1193 if(m_debug_multi_ack_fsm) 1194 { 1195 std::cout 1196 << " <MEMC " << name() 1197 << ".MULTI_ACK_UPT_LOCK> Decrement the responses counter for UPT:" 1198 << " entry = " << r_multi_ack_upt_index.read() 1199 << " / rsp_count = " << std::dec << count 1200 << std::endl; 1201 } 1321 if(m_debug) 1322 std::cout << " <MEMC " << name() 1323 << " MULTI_ACK_UPT_LOCK> Decrement the responses counter for UPT:" 1324 << " entry = " << r_multi_ack_upt_index.read() 1325 << " / rsp_count = " << std::dec << count << std::endl; 1202 1326 #endif 1203 1327 break; 1204 } 1205 1206 case MULTI_ACK_UPT_CLEAR: 1207 { 1328 } 1329 1330 ///////////////////////// 1331 case MULTI_ACK_UPT_CLEAR: // Clear UPT entry / Test if rsp or ack required 1332 { 1208 1333 if(r_alloc_upt_fsm.read() != ALLOC_UPT_MULTI_ACK) 1209 1334 { 1210 std::cout 1211 << "VCI_MEM_CACHE ERROR " << name() 1212 << " MULTI_ACK_UPT_CLEAR state" 1213 << " bad UPT allocation" 1214 << std::endl; 1215 1216 exit(0); 1335 std::cout << "VCI_MEM_CACHE ERROR " << name() 1336 << " MULTI_ACK_UPT_CLEAR state" 1337 << " bad UPT allocation" << std::endl; 1338 exit(0); 1217 1339 } 1218 1340 … … 1222 1344 r_multi_ack_nline = m_upt.nline(r_multi_ack_upt_index.read()); 1223 1345 bool need_rsp = m_upt.need_rsp(r_multi_ack_upt_index.read()); 1346 bool need_ack = m_upt.need_ack(r_multi_ack_upt_index.read()); 1224 1347 1225 1348 // clear the UPT entry 1226 1349 m_upt.clear(r_multi_ack_upt_index.read()); 1227 1350 1228 if(need_rsp) 1229 { 1230 r_multi_ack_fsm = MULTI_ACK_WRITE_RSP; 1231 } 1232 else 1233 { 1234 r_multi_ack_fsm = MULTI_ACK_IDLE; 1235 } 1351 if ( need_rsp ) r_multi_ack_fsm = MULTI_ACK_WRITE_RSP; 1352 else if ( need_ack ) r_multi_ack_fsm = MULTI_ACK_CONFIG_ACK; 1353 else r_multi_ack_fsm = MULTI_ACK_IDLE; 1236 1354 1237 1355 #if DEBUG_MEMC_MULTI_ACK 1238 if(m_debug_multi_ack_fsm) 1239 { 1240 std::cout 1241 << " <MEMC " << name() 1242 << ".MULTI_ACK_UPT_CLEAR> Clear UPT entry " 1243 << r_multi_ack_upt_index.read() 1244 << std::endl; 1245 } 1356 if(m_debug) 1357 std::cout << " <MEMC " << name() 1358 << " MULTI_ACK_UPT_CLEAR> Clear UPT entry " 1359 << std::dec << r_multi_ack_upt_index.read() << std::endl; 1246 1360 #endif 1247 1361 break; 1248 } 1249 1250 case MULTI_ACK_WRITE_RSP: 1251 { 1252 // Post a request to TGT_RSP FSM 1253 // Wait if pending request to the TGT_RSP FSM 1254 if(r_multi_ack_to_tgt_rsp_req.read()) break; 1362 } 1363 ///////////////////////// 1364 case MULTI_ACK_WRITE_RSP: // Post a response request to TGT_RSP FSM 1365 // Wait if pending request 1366 { 1367 if ( r_multi_ack_to_tgt_rsp_req.read() ) break; 1255 1368 1256 1369 r_multi_ack_to_tgt_rsp_req = true; … … 1261 1374 1262 1375 #if DEBUG_MEMC_MULTI_ACK 1263 if(m_debug_multi_ack_fsm) 1264 { 1265 std::cout 1266 << " <MEMC " << name() 1267 << ".MULTI_ACK_WRITE_RSP> Request TGT_RSP FSM to send a response to srcid " 1268 << r_multi_ack_srcid.read() 1269 << std::endl; 1270 } 1376 if(m_debug) 1377 std::cout << " <MEMC " << name() << " MULTI_ACK_WRITE_RSP>" 1378 << " Request TGT_RSP FSM to send a response to srcid " 1379 << std::hex << r_multi_ack_srcid.read() << std::endl; 1271 1380 #endif 1272 1381 break; 1273 } 1382 } 1383 ////////////////////////// 1384 case MULTI_ACK_CONFIG_ACK: // Signals multi-inval completion to CONFIG FSM 1385 // Wait if pending request 1386 { 1387 if ( r_multi_ack_to_config_ack.read() ) break; 1388 1389 r_multi_ack_to_config_ack = true; 1390 r_multi_ack_fsm = MULTI_ACK_IDLE; 1391 1392 #if DEBUG_MEMC_MULTI_ACK 1393 if(m_debug) 1394 std::cout << " <MEMC " << name() << " MULTI_ACK_CONFIG_ACK>" 1395 << " Signals inval completion to CONFIG FSM" << std::endl; 1396 #endif 1397 break; 1398 } 1274 1399 } // end switch r_multi_ack_fsm 1400 1401 //////////////////////////////////////////////////////////////////////////////////// 1402 // CONFIG FSM 1403 //////////////////////////////////////////////////////////////////////////////////// 1404 // The CONFIG FSM handles the VCI configuration requests (INVAL & SYNC). 1405 // The target buffer can have any size, and there is one single command for 1406 // all cache lines covered by the target buffer. 1407 // An INVAL or SYNC configuration request is defined by the followinf registers: 1408 // - bool r_config_cmd : INVAL / SYNC / NOP) 1409 // - uint64_t r_config_address : buffer base address 1410 // - uint32_t r_config_nlines : number of lines covering buffer 1411 // 1412 // For both INVAL and SYNC commands, the CONFIG FSM contains the loop handling 1413 // all cache lines covered by the target buffer. 1414 // 1415 // - INVAL request: 1416 // For each line, it access to the DIR array. 1417 // In case of miss, it does nothing, and a response is requested to TGT_RSP FSM. 1418 // In case of hit, with no copies in L1 caches, the line is invalidated and 1419 // a response is requested to TGT_RSP FSM. 1420 // If there is copies, a multi-inval, or a broadcast-inval coherence transaction 1421 // is launched and registered in UPT. The multi-inval transaction is signaled 1422 // by the r_multi_ack_to config_ack or r_cleanup_to_config_ack flip-flops. 1423 // The config inval response is sent only when the last line has been invalidated. 1424 // 1425 // - SYNC request: 1426 // 1427 // ... Not implemented yet ... 1428 // 1429 // From the software point of view, a configuration request is a sequence 1430 // of 6 atomic accesses: 1431 // - Read MEMC_LOCK : Get the lock 1432 // - Write MEMC_ADDR_LO : Set the buffer address LSB 1433 // - Write MEMC_ADDR_HI : Set the buffer address MSB 1434 // - Write MEMC_BUF_LENGTH : set buffer length (bytes) 1435 // - Write MEMC_CMD_TYPE : launch the actual operation 1436 // - WRITE MEMC_LOCK : release the lock 1437 //////////////////////////////////////////////////////////////////////////////////// 1438 1439 switch( r_config_fsm.read() ) 1440 { 1441 ///////////////// 1442 case CONFIG_IDLE: // waiting a config request 1443 { 1444 if ( r_config_cmd.read() != MEMC_CMD_NOP ) 1445 { 1446 r_config_fsm = CONFIG_LOOP; 1447 1448 #if DEBUG_MEMC_CONFIG 1449 if(m_debug) 1450 std::cout << " <MEMC " << name() << " CONFIG_IDLE> Config Request received" 1451 << " address = " << std::hex << r_config_address.read() 1452 << " / nlines = " << std::dec << r_config_nlines.read() 1453 << " / type = " << r_config_cmd.read() << std::endl; 1454 #endif 1455 } 1456 break; 1457 } 1458 ///////////////// 1459 case CONFIG_LOOP: // test last line 1460 { 1461 if ( r_config_nlines.read() == 0 ) 1462 { 1463 r_config_cmd = MEMC_CMD_NOP; 1464 r_config_fsm = CONFIG_RSP; 1465 } 1466 else 1467 { 1468 r_config_fsm = CONFIG_DIR_REQ; 1469 } 1470 1471 #if DEBUG_MEMC_CONFIG 1472 if(m_debug) 1473 std::cout << " <MEMC " << name() << " CONFIG_LOOP>" 1474 << " address = " << std::hex << r_config_address.read() 1475 << " / nlines = " << std::dec << r_config_nlines.read() 1476 << " / command = " << r_config_cmd.read() << std::endl; 1477 #endif 1478 break; 1479 } 1480 //////////////////// 1481 case CONFIG_DIR_REQ: // Request directory lock 1482 { 1483 if ( r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG ) 1484 { 1485 r_config_fsm = CONFIG_DIR_ACCESS; 1486 } 1487 1488 #if DEBUG_MEMC_CONFIG 1489 if(m_debug) 1490 std::cout << " <MEMC " << name() << " CONFIG_DIR_REQ>" 1491 << " Request DIR access" << std::endl; 1492 #endif 1493 break; 1494 } 1495 /////////////////////// 1496 case CONFIG_DIR_ACCESS: // Access directory and decode config command 1497 { 1498 size_t way = 0; 1499 DirectoryEntry entry = m_cache_directory.read(r_config_address.read(), way); 1500 1501 if ( entry.valid and // hit & inval command 1502 (r_config_cmd.read() == MEMC_CMD_INVAL) ) 1503 { 1504 r_config_dir_way = way; 1505 r_config_dir_copy_inst = entry.owner.inst; 1506 r_config_dir_copy_srcid = entry.owner.srcid; 1507 r_config_dir_is_cnt = entry.is_cnt; 1508 r_config_dir_count = entry.count; 1509 r_config_dir_next_ptr = entry.ptr; 1510 1511 r_config_fsm = CONFIG_DIR_UPT_LOCK; 1512 } 1513 else if ( entry.valid and // hit & sync command 1514 entry.dirty and 1515 (r_config_cmd.read() == MEMC_CMD_SYNC) ) 1516 { 1517 std::cout << "VCI_MEM_CACHE ERROR: " 1518 << "SYNC config request not implemented yet" << std::endl; 1519 exit(0); 1520 } 1521 else // return to LOOP 1522 { 1523 r_config_nlines = r_config_nlines.read() - 1; 1524 r_config_address = r_config_address.read() + (m_words<<2); 1525 r_config_fsm = CONFIG_LOOP; 1526 } 1527 1528 #if DEBUG_MEMC_CONFIG 1529 if(m_debug) 1530 std::cout << " <MEMC " << name() << " CONFIG_DIR_ACCESS> Accessing directory: " 1531 << " address = " << std::hex << r_config_address.read() 1532 << " / hit = " << std::dec << entry.valid 1533 << " / dirty = " << entry.dirty 1534 << " / count = " << entry.count 1535 << " / is_cnt = " << entry.is_cnt << std::endl; 1536 #endif 1537 break; 1538 } 1539 ///////////////////////// 1540 case CONFIG_DIR_UPT_LOCK: // enter this state in case of INVAL command 1541 // Try to get both DIR & UPT locks, and return 1542 // to LOOP state if UPT full. 1543 // Register inval in UPT, and invalidate the 1544 // directory if UPT not full. 1545 { 1546 if ( r_alloc_upt_fsm.read() == ALLOC_UPT_CONFIG ) 1547 { 1548 size_t set = m_y[(addr_t)(r_config_address.read())]; 1549 size_t way = r_config_dir_way.read(); 1550 1551 if ( r_config_dir_count.read() == 0 ) // inval DIR and return to LOOP 1552 { 1553 m_cache_directory.inval( way, set ); 1554 r_config_nlines = r_config_nlines.read() - 1; 1555 r_config_address = r_config_address.read() + (m_words<<2); 1556 r_config_fsm = CONFIG_LOOP; 1557 1558 #if DEBUG_MEMC_CONFIG 1559 if(m_debug) 1560 std::cout << " <MEMC " << name() << " CONFIG_DIR_UPT_LOCK>" 1561 << " No copies in L1 : inval DIR entry" << std::endl; 1562 #endif 1563 } 1564 else // try to register inval in UPT 1565 { 1566 bool wok = false; 1567 size_t index = 0; 1568 bool broadcast = r_config_dir_is_cnt.read(); 1569 size_t srcid = r_config_srcid.read(); 1570 size_t trdid = r_config_trdid.read(); 1571 size_t pktid = r_config_pktid.read(); 1572 addr_t nline = m_nline[(addr_t)(r_config_address.read())]; 1573 size_t nb_copies = r_config_dir_count.read(); 1574 1575 wok = m_upt.set(false, // it's an inval transaction 1576 broadcast, 1577 false, // no response required 1578 true, // acknowledge required 1579 srcid, 1580 trdid, 1581 pktid, 1582 nline, 1583 nb_copies, 1584 index); 1585 if ( wok ) // UPT success => inval DIR slot 1586 { 1587 m_cache_directory.inval( way, set ); 1588 r_config_upt_index = index; 1589 if ( broadcast ) r_config_fsm = CONFIG_BC_SEND; 1590 else r_config_fsm = CONFIG_INV_SEND; 1591 1592 #if DEBUG_MEMC_CONFIG 1593 if(m_debug) 1594 std::cout << " <MEMC " << name() << " CONFIG_DIR_UPT_LOCK>" 1595 << " Inval DIR entry and register inval in UPT" 1596 << " : index = " << std::dec << index 1597 << " / broadcast = " << broadcast << std::endl; 1598 #endif 1599 } 1600 else // UPT full => release both DIR and UPT locks 1601 { 1602 r_config_fsm = CONFIG_LOOP; 1603 1604 #if DEBUG_MEMC_CONFIG 1605 if(m_debug) 1606 std::cout << " <MEMC " << name() << " CONFIG_DIR_UPT_LOCK>" 1607 << " UPT full : release DIR & UPT locks and retry" << std::endl; 1608 #endif 1609 } 1610 } 1611 } 1612 break; 1613 } 1614 //////////////////// 1615 case CONFIG_BC_SEND: // Post a broadcast inval request to CC_SEND FSM 1616 { 1617 if( not r_config_to_cc_send_multi_req.read() and 1618 not r_config_to_cc_send_brdcast_req.read() ) 1619 { 1620 r_config_to_cc_send_multi_req = false; 1621 r_config_to_cc_send_brdcast_req = true; 1622 r_config_to_cc_send_trdid = r_config_upt_index.read(); 1623 r_config_to_cc_send_nline = m_nline[(addr_t)(r_config_address.read())]; 1624 r_cleanup_to_config_ack = false; 1625 r_config_fsm = CONFIG_BC_WAIT; 1626 1627 #if DEBUG_MEMC_CONFIG 1628 if(m_debug) 1629 std::cout << " <MEMC " << name() << " CONFIG_BC_SEND>" 1630 << " Post a broadcast inval request to CC_SEND FSM" 1631 << " / address = " << r_config_address.read() <<std::endl; 1632 #endif 1633 } 1634 break; 1635 } 1636 //////////////////// 1637 case CONFIG_BC_WAIT: // wait broadcast completion to return to LOOP 1638 { 1639 if ( r_cleanup_to_config_ack.read() ) 1640 { 1641 r_config_fsm = CONFIG_LOOP; 1642 r_config_nlines = r_config_nlines.read() - 1; 1643 r_config_address = r_config_address.read() + (m_words<<2); 1644 } 1645 1646 #if DEBUG_MEMC_CONFIG 1647 if(m_debug) 1648 std::cout << " <MEMC " << name() << " CONFIG_BC_WAIT> Waiting BC completion " 1649 << " done = " << r_cleanup_to_config_ack.read() 1650 << std::endl; 1651 #endif 1652 break; 1653 } 1654 ///////////////////// 1655 case CONFIG_INV_SEND: // Post a multi inval request to CC_SEND FSM 1656 { 1657 if( not r_config_to_cc_send_multi_req.read() and 1658 not r_config_to_cc_send_brdcast_req.read() ) 1659 { 1660 r_config_to_cc_send_multi_req = true; 1661 r_config_to_cc_send_brdcast_req = false; 1662 r_config_to_cc_send_trdid = r_config_upt_index.read(); 1663 r_config_to_cc_send_nline = m_nline[(addr_t)(r_config_address.read())]; 1664 r_multi_ack_to_config_ack = false; 1665 1666 config_to_cc_send_fifo_srcid = r_config_dir_copy_srcid.read(); 1667 config_to_cc_send_fifo_inst = r_config_dir_copy_inst.read(); 1668 config_to_cc_send_fifo_put = true; 1669 1670 if ( r_config_dir_count.read() == 1 ) r_config_fsm = CONFIG_INV_WAIT; 1671 else r_config_fsm = CONFIG_HEAP_REQ; 1672 1673 #if DEBUG_MEMC_CONFIG 1674 if(m_debug) 1675 std::cout << " <MEMC " << name() << " CONFIG_INV_SEND>" 1676 << " Post multi inval request to CC_SEND FSM" 1677 << " / address = " << std::hex << r_config_address.read() 1678 << " / copy = " << r_config_dir_copy_srcid.read() 1679 << " / inst = " << std::dec << r_config_dir_copy_inst.read() << std::endl; 1680 #endif 1681 } 1682 break; 1683 } 1684 ///////////////////// 1685 case CONFIG_HEAP_REQ: // Try to get access to Heap 1686 { 1687 if ( r_alloc_heap_fsm.read() == ALLOC_HEAP_CONFIG ) 1688 { 1689 r_config_fsm = CONFIG_HEAP_SCAN; 1690 r_config_heap_next = r_config_dir_next_ptr.read(); 1691 } 1692 1693 #if DEBUG_MEMC_CONFIG 1694 if(m_debug) 1695 std::cout << " <MEMC " << name() << " CONFIG_HEAP_REQ>" 1696 << " Requesting HEAP lock" << std::endl; 1697 #endif 1698 break; 1699 } 1700 ////////////////////// 1701 case CONFIG_HEAP_SCAN: // scan HEAP and send inval to CC_SEND FSM 1702 { 1703 HeapEntry entry = m_heap.read( r_config_heap_next.read() ); 1704 bool last_copy = (entry.next == r_config_heap_next.read()); 1705 1706 config_to_cc_send_fifo_srcid = entry.owner.srcid; 1707 config_to_cc_send_fifo_inst = entry.owner.inst; 1708 // config_to_cc_send_fifo_last = last_copy; 1709 config_to_cc_send_fifo_put = true; 1710 1711 if ( m_config_to_cc_send_inst_fifo.wok() ) // inval request accepted 1712 { 1713 r_config_heap_next = entry.next; 1714 if ( last_copy ) r_config_fsm = CONFIG_HEAP_LAST; 1715 } 1716 1717 #if DEBUG_MEMC_CONFIG 1718 if(m_debug) 1719 std::cout << " <MEMC " << name() << " CONFIG_HEAP_SCAN>" 1720 << " Post multi inval request to CC_SEND FSM" 1721 << " / address = " << std::hex << r_config_address.read() 1722 << " / copy = " << entry.owner.srcid 1723 << " / inst = " << std::dec << entry.owner.inst << std::endl; 1724 #endif 1725 break; 1726 } 1727 ////////////////////// 1728 case CONFIG_HEAP_LAST: // HEAP housekeeping 1729 { 1730 size_t free_pointer = m_heap.next_free_ptr(); 1731 HeapEntry last_entry; 1732 last_entry.owner.srcid = 0; 1733 last_entry.owner.inst = false; 1734 1735 if ( m_heap.is_full() ) 1736 { 1737 last_entry.next = r_config_dir_next_ptr.read(); 1738 m_heap.unset_full(); 1739 } 1740 else 1741 { 1742 last_entry.next = free_pointer; 1743 } 1744 1745 m_heap.write_free_ptr( r_config_dir_next_ptr.read() ); 1746 m_heap.write( r_config_heap_next.read(), last_entry ); 1747 r_config_fsm = CONFIG_INV_WAIT; 1748 1749 #if DEBUG_MEMC_CONFIG 1750 if(m_debug) 1751 std::cout << " <MEMC " << name() << " CONFIG_HEAP_LAST>" 1752 << " Heap housekeeping" << std::endl; 1753 #endif 1754 break; 1755 } 1756 ///////////////////// 1757 case CONFIG_INV_WAIT: // wait inval completion to return to LOOP 1758 { 1759 if ( r_multi_ack_to_config_ack.read() ) 1760 { 1761 r_config_fsm = CONFIG_LOOP; 1762 r_config_nlines = r_config_nlines.read() - 1; 1763 r_config_address = r_config_address.read() + (m_words<<2); 1764 } 1765 1766 #if DEBUG_MEMC_CONFIG 1767 if(m_debug) 1768 std::cout << " <MEMC " << name() << " CONFIG_INV_WAIT> Waiting inval completion " 1769 << " done = " << r_multi_ack_to_config_ack.read() 1770 << std::endl; 1771 #endif 1772 break; 1773 } 1774 1775 //////////////// 1776 case CONFIG_RSP: // request TGT_RSP FSM to return response 1777 { 1778 if ( not r_config_to_tgt_rsp_req.read() ) 1779 { 1780 r_config_to_tgt_rsp_srcid = r_config_srcid.read(); 1781 r_config_to_tgt_rsp_trdid = r_config_trdid.read(); 1782 r_config_to_tgt_rsp_pktid = r_config_pktid.read(); 1783 r_config_to_tgt_rsp_error = false; 1784 r_config_to_tgt_rsp_req = true; 1785 r_config_fsm = CONFIG_IDLE; 1786 1787 #if DEBUG_MEMC_CONFIG 1788 if(m_debug) 1789 std::cout << " <MEMC " << name() << " CONFIG_RSP> Request TGT_RSP FSM to return response:" 1790 << " error = " << r_config_to_tgt_rsp_error.read() 1791 << " / rsrcid = " << std::hex << r_config_srcid.read() << std::endl; 1792 #endif 1793 } 1794 break; 1795 1796 } 1797 } // end switch r_config_fsm 1275 1798 1276 1799 //////////////////////////////////////////////////////////////////////////////////// … … 1300 1823 { 1301 1824 /////////////// 1302 case READ_IDLE: 1303 // waiting a read request 1304 { 1825 case READ_IDLE: // waiting a read request 1826 { 1305 1827 if(m_cmd_read_addr_fifo.rok()) 1306 1828 { 1307 1829 1308 1830 #if DEBUG_MEMC_READ 1309 if(m_debug_read_fsm) 1310 { 1311 std::cout << " <MEMC " << name() << ".READ_IDLE> Read request:" 1312 << " srcid = " << std::dec << m_cmd_read_srcid_fifo.read() 1313 << " / address = " << std::hex << m_cmd_read_addr_fifo.read() 1314 << " / pktid = " << std::hex << m_cmd_read_pktid_fifo.read() 1315 << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl; 1316 } 1831 if(m_debug) 1832 std::cout << " <MEMC " << name() << " READ_IDLE> Read request" 1833 << " : address = " << std::hex << m_cmd_read_addr_fifo.read() 1834 << " / srcid = " << m_cmd_read_srcid_fifo.read() 1835 << " / trdid = " << m_cmd_read_trdid_fifo.read() 1836 << " / pktid = " << m_cmd_read_pktid_fifo.read() 1837 << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl; 1317 1838 #endif 1318 1839 r_read_fsm = READ_DIR_REQ; … … 1321 1842 } 1322 1843 1844 ////////////////// 1845 case READ_DIR_REQ: // Get the lock to the directory 1846 { 1847 if(r_alloc_dir_fsm.read() == ALLOC_DIR_READ) 1848 { 1849 r_read_fsm = READ_DIR_LOCK; 1850 } 1851 1852 #if DEBUG_MEMC_READ 1853 if(m_debug) 1854 std::cout << " <MEMC " << name() << " READ_DIR_REQ> Requesting DIR lock " << std::endl; 1855 #endif 1856 break; 1857 } 1858 1323 1859 /////////////////// 1324 case READ_DIR_REQ: 1325 // Get the lock to the directory 1326 { 1327 if(r_alloc_dir_fsm.read() == ALLOC_DIR_READ) 1328 { 1329 r_read_fsm = READ_DIR_LOCK; 1330 } 1331 1332 #if DEBUG_MEMC_READ 1333 if(m_debug_read_fsm) 1334 { 1335 std::cout 1336 << " <MEMC " << name() << ".READ_DIR_REQ> Requesting DIR lock " 1337 << std::endl; 1338 } 1339 #endif 1340 break; 1341 } 1342 1343 /////////////////// 1344 case READ_DIR_LOCK: 1345 // check directory for hit / miss 1860 case READ_DIR_LOCK: // check directory for hit / miss 1346 1861 { 1347 1862 if(r_alloc_dir_fsm.read() == ALLOC_DIR_READ) … … 1375 1890 { 1376 1891 // test if we need to register a new copy in the heap 1377 if(entry.is_cnt || (entry.count == 0) ||!cached_read)1892 if(entry.is_cnt or (entry.count == 0) or !cached_read) 1378 1893 { 1379 1894 r_read_fsm = READ_DIR_HIT; … … 1390 1905 1391 1906 #if DEBUG_MEMC_READ 1392 if(m_debug_read_fsm) 1393 { 1394 std::cout 1395 << " <MEMC " << name() << ".READ_DIR_LOCK> Accessing directory: " 1396 << " address = " << std::hex << m_cmd_read_addr_fifo.read() 1397 << " / hit = " << std::dec << entry.valid 1398 << " / count = " <<std::dec << entry.count 1399 << " / is_cnt = " << entry.is_cnt << std::endl; 1400 if((m_cmd_read_pktid_fifo.read() & 0x7) == TYPE_LL) 1401 { 1402 std::cout 1403 << " <MEMC " << name() << ".READ_DIR_LOCK> global_llsc_table LL access" << std::endl; 1404 } 1405 } 1907 if(m_debug) 1908 { 1909 std::cout << " <MEMC " << name() << " READ_DIR_LOCK> Accessing directory: " 1910 << " address = " << std::hex << m_cmd_read_addr_fifo.read() 1911 << " / hit = " << std::dec << entry.valid 1912 << " / count = " <<std::dec << entry.count 1913 << " / is_cnt = " << entry.is_cnt; 1914 if((m_cmd_read_pktid_fifo.read() & 0x7) == TYPE_LL) std::cout << " / LL access" << std::endl; 1915 else std::cout << std::endl; 1916 } 1406 1917 #endif 1407 1918 } 1408 1919 else 1409 1920 { 1410 std::cout 1411 << "VCI_MEM_CACHE ERROR " << name() 1412 << " READ_DIR_LOCK state" << std::endl 1413 << "Bad DIR allocation" << std::endl; 1414 1921 std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_DIR_LOCK state" 1922 << "Bad DIR allocation" << std::endl; 1415 1923 exit(0); 1416 1924 } … … 1429 1937 if(r_alloc_dir_fsm.read() == ALLOC_DIR_READ) 1430 1938 { 1431 // signals generation1432 1939 // check if this is an instruction read, this means pktid is either 1433 1940 // TYPE_READ_INS_UNC 0bX010 with TSAR encoding … … 1441 1948 1442 1949 // read data in the cache 1443 size_t set = m_y[( vci_addr_t)(m_cmd_read_addr_fifo.read())];1950 size_t set = m_y[(addr_t)(m_cmd_read_addr_fifo.read())]; 1444 1951 size_t way = r_read_way.read(); 1445 1952 … … 1451 1958 entry.is_cnt = is_cnt; 1452 1959 entry.dirty = r_read_dirty.read(); 1453 entry.tag = r_read_tag.read();1960 entry.tag = r_read_tag.read(); 1454 1961 entry.lock = r_read_lock.read(); 1455 1962 entry.ptr = r_read_ptr.read(); … … 1486 1993 1487 1994 #if DEBUG_MEMC_READ 1488 if(m_debug_read_fsm) 1489 { 1490 std::cout 1491 << " <MEMC " << name() << ".READ_DIR_HIT> Update directory entry:" 1492 << " addr = " << std::hex << m_cmd_read_addr_fifo.read() 1493 << " / set = " << std::dec << set 1494 << " / way = " << way 1495 << " / owner_id = " << entry.owner.srcid 1496 << " / owner_ins = " << entry.owner.inst 1497 << " / count = " << entry.count 1498 << " / is_cnt = " << entry.is_cnt << std::endl; 1499 } 1500 #endif 1501 /**/ 1995 if(m_debug) 1996 std::cout << " <MEMC " << name() << " READ_DIR_HIT> Update directory entry:" 1997 << " addr = " << std::hex << m_cmd_read_addr_fifo.read() 1998 << " / set = " << std::dec << set 1999 << " / way = " << way 2000 << " / owner_id = " << std::hex << entry.owner.srcid 2001 << " / owner_ins = " << std::dec << entry.owner.inst 2002 << " / count = " << entry.count 2003 << " / is_cnt = " << entry.is_cnt << std::endl; 2004 #endif 2005 1502 2006 if(m_monitor_ok) 1503 2007 { 1504 2008 char buf[80]; 1505 snprintf(buf, 80, "READ_DIR_HIT srcid %d, ins %d", m_cmd_read_srcid_fifo.read(), ((m_cmd_read_pktid_fifo.read()&0x2)!=0)); 1506 check_monitor_read(buf, m_cmd_read_addr_fifo.read()); 2009 snprintf(buf, 80, "READ_DIR_HIT srcid %d, ins %d", 2010 (int)m_cmd_read_srcid_fifo.read(), 2011 (int)((m_cmd_read_pktid_fifo.read()&0x2)!=0)); 2012 check_monitor(buf, m_cmd_read_addr_fifo.read(), r_read_data[0], true); 1507 2013 } 1508 /**/ 2014 1509 2015 1510 2016 m_cache_directory.write(set, way, entry); … … 1514 2020 } 1515 2021 2022 /////////////////// 2023 case READ_HEAP_REQ: // Get the lock to the HEAP directory 2024 { 2025 if(r_alloc_heap_fsm.read() == ALLOC_HEAP_READ) 2026 { 2027 r_read_fsm = READ_HEAP_LOCK; 2028 } 2029 2030 #if DEBUG_MEMC_READ 2031 if(m_debug) 2032 std::cout << " <MEMC " << name() << " READ_HEAP_REQ>" 2033 << " Requesting HEAP lock " << std::endl; 2034 #endif 2035 break; 2036 } 2037 1516 2038 //////////////////// 1517 case READ_HEAP_REQ: 1518 // Get the lock to the HEAP directory 1519 { 1520 /**/ 1521 if(m_monitor_ok) 1522 { 1523 char buf[80]; 1524 snprintf(buf, 80, "READ_HEAP_REQ srcid %d, ins %d", m_cmd_read_srcid_fifo.read(), ((m_cmd_read_pktid_fifo.read()&0x2)!=0)); 1525 check_monitor_read(buf, m_cmd_read_addr_fifo.read()); 1526 } 1527 /**/ 2039 case READ_HEAP_LOCK: // read data in cache, update the directory 2040 // and prepare the HEAP update 2041 { 1528 2042 if(r_alloc_heap_fsm.read() == ALLOC_HEAP_READ) 1529 2043 { 1530 r_read_fsm = READ_HEAP_LOCK;1531 }1532 1533 #if DEBUG_MEMC_READ1534 if(m_debug_read_fsm)1535 {1536 std::cout1537 << " <MEMC " << name() << ".READ_HEAP_REQ> Requesting HEAP lock "1538 << std::endl;1539 }1540 #endif1541 break;1542 }1543 1544 ////////////////////1545 case READ_HEAP_LOCK:1546 // read data in cache, update the directory1547 // and prepare the HEAP update1548 {1549 if(r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)1550 {1551 2044 // enter counter mode when we reach the limit of copies or the heap is full 1552 bool go_cnt = (r_read_count.read() >= m_max_copies) ||m_heap.is_full();2045 bool go_cnt = (r_read_count.read() >= m_max_copies) or m_heap.is_full(); 1553 2046 1554 2047 // read data in the cache 1555 size_t set = m_y[( vci_addr_t)(m_cmd_read_addr_fifo.read())];2048 size_t set = m_y[(addr_t)(m_cmd_read_addr_fifo.read())]; 1556 2049 size_t way = r_read_way.read(); 1557 2050 … … 1623 2116 1624 2117 #if DEBUG_MEMC_READ 1625 if(m_debug_read_fsm) 1626 { 1627 std::cout << " <MEMC " << name() << ".READ_HEAP_LOCK> Update directory:" 1628 << " tag = " << std::hex << entry.tag 1629 << " set = " << std::dec << set 1630 << " way = " << way 1631 << " count = " << entry.count 1632 << " is_cnt = " << entry.is_cnt << std::endl; 1633 } 2118 if(m_debug) 2119 std::cout << " <MEMC " << name() << " READ_HEAP_LOCK> Update directory:" 2120 << " tag = " << std::hex << entry.tag 2121 << " set = " << std::dec << set 2122 << " way = " << way 2123 << " count = " << entry.count 2124 << " is_cnt = " << entry.is_cnt << std::endl; 1634 2125 #endif 1635 2126 } 1636 2127 else 1637 2128 { 1638 std::cout 1639 << "VCI_MEM_CACHE ERROR " << name() 1640 << " READ_HEAP_LOCK state" << std::endl 1641 << "Bad HEAP allocation" << std::endl; 1642 2129 std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_LOCK" 2130 << "Bad HEAP allocation" << std::endl; 1643 2131 exit(0); 1644 2132 } 1645 1646 break; 1647 } 1648 2133 break; 2134 } 1649 2135 ///////////////////// 1650 case READ_HEAP_WRITE: // add a entry in the heap2136 case READ_HEAP_WRITE: // add an entry in the heap 1651 2137 { 1652 2138 if(r_alloc_heap_fsm.read() == ALLOC_HEAP_READ) … … 1674 2160 1675 2161 #if DEBUG_MEMC_READ 1676 if(m_debug_read_fsm) 1677 { 1678 std::cout 1679 << " <MEMC " << name() << ".READ_HEAP_WRITE> Add an entry in the heap:" 1680 << " owner_id = " << heap_entry.owner.srcid 1681 << " owner_ins = " << heap_entry.owner.inst << std::endl; 1682 } 2162 if(m_debug) 2163 std::cout << " <MEMC " << name() << " READ_HEAP_WRITE> Add an entry in the heap:" 2164 << " owner_id = " << std::hex << heap_entry.owner.srcid 2165 << " owner_ins = " << std::dec << heap_entry.owner.inst << std::endl; 1683 2166 #endif 1684 2167 } 1685 2168 else 1686 2169 { 1687 std::cout 1688 << "VCI_MEM_CACHE ERROR " << name() 1689 << " READ_HEAP_WRITE state" << std::endl 1690 << "Bad HEAP allocation" << std::endl; 1691 2170 std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_WRITE" 2171 << "Bad HEAP allocation" << std::endl; 1692 2172 exit(0); 1693 2173 } 1694 2174 break; 1695 2175 } 1696 1697 2176 ///////////////////// 1698 2177 case READ_HEAP_ERASE: … … 1713 2192 else 1714 2193 { 1715 std::cout 1716 << "VCI_MEM_CACHE ERROR " << name() 1717 << " READ_HEAP_ERASE state" << std::endl 1718 << "Bad HEAP allocation" << std::endl; 1719 2194 std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_ERASE" 2195 << "Bad HEAP allocation" << std::endl; 1720 2196 exit(0); 1721 2197 } … … 1749 2225 else 1750 2226 { 1751 std::cout << "VCI_MEM_CACHE ERROR " << name() 1752 << " READ_HEAP_LAST state" << std::endl; 1753 std::cout << "Bad HEAP allocation" << std::endl; 2227 std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_LAST" 2228 << "Bad HEAP allocation" << std::endl; 1754 2229 exit(0); 1755 2230 } 1756 2231 break; 1757 2232 } 1758 1759 2233 ////////////// 1760 2234 case READ_RSP: // request the TGT_RSP FSM to return data … … 1763 2237 { 1764 2238 for(size_t i=0 ; i<m_words ; i++) r_read_to_tgt_rsp_data[i] = r_read_data[i]; 1765 r_read_to_tgt_rsp_word = m_x[( vci_addr_t) m_cmd_read_addr_fifo.read()];2239 r_read_to_tgt_rsp_word = m_x[(addr_t) m_cmd_read_addr_fifo.read()]; 1766 2240 r_read_to_tgt_rsp_length = m_cmd_read_length_fifo.read(); 1767 2241 r_read_to_tgt_rsp_srcid = m_cmd_read_srcid_fifo.read(); … … 1774 2248 1775 2249 #if DEBUG_MEMC_READ 1776 if(m_debug_read_fsm) 1777 { 1778 std::cout << " <MEMC " << name() << ".READ_RSP> Request the TGT_RSP FSM to return data:" 1779 << " rsrcid = " << std::dec << m_cmd_read_srcid_fifo.read() 1780 << " / address = " << std::hex << m_cmd_read_addr_fifo.read() 1781 << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl; 1782 } 1783 #endif 1784 } 1785 break; 1786 } 1787 2250 if(m_debug) 2251 std::cout << " <MEMC " << name() << " READ_RSP> Request TGT_RSP FSM to return data:" 2252 << " rsrcid = " << std::hex << m_cmd_read_srcid_fifo.read() 2253 << " / address = " << std::hex << m_cmd_read_addr_fifo.read() 2254 << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl; 2255 #endif 2256 } 2257 break; 2258 } 1788 2259 /////////////////// 1789 2260 case READ_TRT_LOCK: // read miss : check the Transaction Table … … 1792 2263 { 1793 2264 size_t index = 0; 1794 vci_addr_t addr = (vci_addr_t) m_cmd_read_addr_fifo.read();2265 addr_t addr = (addr_t) m_cmd_read_addr_fifo.read(); 1795 2266 bool hit_read = m_trt.hit_read(m_nline[addr], index); 1796 2267 bool hit_write = m_trt.hit_write(m_nline[addr]); 1797 2268 bool wok = !m_trt.full(index); 1798 2269 1799 if(hit_read || !wok ||hit_write) // missing line already requested or no space2270 if(hit_read or !wok or hit_write) // missing line already requested or no space 1800 2271 { 1801 2272 if(!wok) m_cpt_trt_full++; 1802 if(hit_read ||hit_write) m_cpt_trt_rb++;2273 if(hit_read or hit_write) m_cpt_trt_rb++; 1803 2274 r_read_fsm = READ_IDLE; 1804 2275 } … … 1811 2282 1812 2283 #if DEBUG_MEMC_READ 1813 if(m_debug_read_fsm) 1814 { 1815 std::cout << " <MEMC " << name() << ".READ_TRT_LOCK> Check TRT:" 1816 << " hit_read = " << hit_read 1817 << " / hit_write = " << hit_write 1818 << " / full = " << !wok << std::endl; 1819 } 2284 if(m_debug) 2285 std::cout << " <MEMC " << name() << " READ_TRT_LOCK> Check TRT:" 2286 << " hit_read = " << hit_read 2287 << " / hit_write = " << hit_write 2288 << " / full = " << !wok << std::endl; 1820 2289 #endif 1821 2290 } … … 1830 2299 m_trt.set(r_read_trt_index.read(), 1831 2300 true, 1832 m_nline[( vci_addr_t)(m_cmd_read_addr_fifo.read())],2301 m_nline[(addr_t)(m_cmd_read_addr_fifo.read())], 1833 2302 m_cmd_read_srcid_fifo.read(), 1834 2303 m_cmd_read_trdid_fifo.read(), … … 1836 2305 true, 1837 2306 m_cmd_read_length_fifo.read(), 1838 m_x[( vci_addr_t)(m_cmd_read_addr_fifo.read())],2307 m_x[(addr_t)(m_cmd_read_addr_fifo.read())], 1839 2308 std::vector<be_t> (m_words,0), 1840 2309 std::vector<data_t> (m_words,0), 1841 2310 r_read_ll_key.read()); 1842 2311 #if DEBUG_MEMC_READ 1843 if(m_debug_read_fsm) 1844 { 1845 std::cout << " <MEMC " << name() << ".READ_TRT_SET> Write in Transaction Table: " << std::hex 1846 << " address = " << std::hex << m_cmd_read_addr_fifo.read() 1847 << " / srcid = " << std::dec << m_cmd_read_srcid_fifo.read() 1848 << std::endl; 1849 } 2312 if(m_debug) 2313 std::cout << " <MEMC " << name() << " READ_TRT_SET> Write in Transaction Table:" 2314 << " address = " << std::hex << m_cmd_read_addr_fifo.read() 2315 << " / srcid = " << std::hex << m_cmd_read_srcid_fifo.read() << std::endl; 1850 2316 #endif 1851 2317 r_read_fsm = READ_TRT_REQ; … … 1855 2321 1856 2322 ////////////////// 1857 case READ_TRT_REQ: 1858 { 1859 // consume the read request in the FIFO, 1860 // and send it to the ixr_cmd_fsm 1861 2323 case READ_TRT_REQ: // consume the read request in FIFO and send it to IXR_CMD_FSM 2324 { 1862 2325 if(not r_read_to_ixr_cmd_req) 1863 2326 { 1864 2327 cmd_read_fifo_get = true; 1865 2328 r_read_to_ixr_cmd_req = true; 1866 r_read_to_ixr_cmd_nline = m_nline[( vci_addr_t)(m_cmd_read_addr_fifo.read())];2329 r_read_to_ixr_cmd_nline = m_nline[(addr_t)(m_cmd_read_addr_fifo.read())]; 1867 2330 r_read_to_ixr_cmd_trdid = r_read_trt_index.read(); 1868 2331 r_read_fsm = READ_IDLE; 1869 2332 1870 2333 #if DEBUG_MEMC_READ 1871 if(m_debug_read_fsm) 1872 { 1873 std::cout 1874 << " <MEMC " << name() << ".READ_TRT_REQ> Request GET transaction for address " 1875 << std::hex << m_cmd_read_addr_fifo.read() << std::endl; 1876 } 2334 if(m_debug) 2335 std::cout << " <MEMC " << name() << " READ_TRT_REQ> Request GET transaction for address " 2336 << std::hex << m_cmd_read_addr_fifo.read() << std::endl; 1877 2337 #endif 1878 2338 } … … 1914 2374 switch(r_write_fsm.read()) 1915 2375 { 1916 2376 //////////////// 1917 2377 case WRITE_IDLE: // copy first word of a write burst in local buffer 1918 2378 { … … 1929 2389 // consume a word in the FIFO & write it in the local buffer 1930 2390 cmd_write_fifo_get = true; 1931 size_t index = m_x[( vci_addr_t)(m_cmd_write_addr_fifo.read())];2391 size_t index = m_x[(addr_t)(m_cmd_write_addr_fifo.read())]; 1932 2392 1933 2393 r_write_address = (addr_t)(m_cmd_write_addr_fifo.read()); … … 1947 2407 } 1948 2408 1949 if (m_cmd_write_eop_fifo.read() ||((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC))2409 if (m_cmd_write_eop_fifo.read() or ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC)) 1950 2410 { 1951 2411 r_write_fsm = WRITE_DIR_REQ; … … 1957 2417 1958 2418 #if DEBUG_MEMC_WRITE 1959 if(m_debug _write_fsm)1960 { 1961 std::cout << " <MEMC " << name() << " .WRITE_IDLE> Write request "2419 if(m_debug) 2420 { 2421 std::cout << " <MEMC " << name() << " WRITE_IDLE> Write request " 1962 2422 << " srcid = " << std::dec << m_cmd_write_srcid_fifo.read() 1963 2423 << " / address = " << std::hex << m_cmd_write_addr_fifo.read() … … 1976 2436 1977 2437 #if DEBUG_MEMC_WRITE 1978 if(m_debug _write_fsm)2438 if(m_debug) 1979 2439 { 1980 2440 std::cout << " <MEMC " << name() 1981 << " .WRITE_NEXT> Write another word in local buffer"2441 << " WRITE_NEXT> Write another word in local buffer" 1982 2442 << std::endl; 1983 2443 } … … 1986 2446 1987 2447 // check that the next word is in the same cache line 1988 if((m_nline[( vci_addr_t)(r_write_address.read())] !=1989 m_nline[( vci_addr_t)(m_cmd_write_addr_fifo.read())]))2448 if((m_nline[(addr_t)(r_write_address.read())] != 2449 m_nline[(addr_t)(m_cmd_write_addr_fifo.read())])) 1990 2450 { 1991 2451 std::cout << "VCI_MEM_CACHE ERROR " << name() << " WRITE_NEXT state" << std::endl … … 2029 2489 if(not m_cmd_write_addr_fifo.rok()) break; 2030 2490 2031 assert(m_cmd_write_eop_fifo.read() &&2491 assert(m_cmd_write_eop_fifo.read() and 2032 2492 "Error in VCI_MEM_CACHE : " 2033 2493 "invalid packet format for SC command"); … … 2060 2520 2061 2521 #if DEBUG_MEMC_WRITE 2062 if(m_debug _write_fsm)2522 if(m_debug) 2063 2523 { 2064 2524 std::cout 2065 << " <MEMC " << name() << " .WRITE_DIR_REQ> Requesting DIR lock "2525 << " <MEMC " << name() << " WRITE_DIR_REQ> Requesting DIR lock " 2066 2526 << std::endl; 2067 2527 } … … 2095 2555 r_write_way = way; 2096 2556 2097 if(entry.is_cnt &&entry.count)2557 if(entry.is_cnt and entry.count) 2098 2558 { 2099 2559 r_write_fsm = WRITE_DIR_READ; … … 2110 2570 2111 2571 #if DEBUG_MEMC_WRITE 2112 if(m_debug _write_fsm)2113 { 2114 std::cout << " <MEMC " << name() << " .WRITE_DIR_LOCK> Check the directory: "2572 if(m_debug) 2573 { 2574 std::cout << " <MEMC " << name() << " WRITE_DIR_LOCK> Check the directory: " 2115 2575 << " address = " << std::hex << r_write_address.read() 2116 2576 << " hit = " << std::dec << entry.valid … … 2118 2578 << " is_cnt = " << entry.is_cnt << std::endl; 2119 2579 if((r_write_pktid.read() & 0x7) == TYPE_SC) 2120 std::cout << " <MEMC " << name() << " .WRITE_DIR_LOCK> global_llsc_table SC access" << std::endl;2580 std::cout << " <MEMC " << name() << " WRITE_DIR_LOCK> global_llsc_table SC access" << std::endl; 2121 2581 else 2122 std::cout << " <MEMC " << name() << " .WRITE_DIR_LOCK> global_llsc_table SW access" << std::endl;2582 std::cout << " <MEMC " << name() << " WRITE_DIR_LOCK> global_llsc_table SW access" << std::endl; 2123 2583 } 2124 2584 #endif … … 2140 2600 { 2141 2601 // update local buffer 2142 size_t set = m_y[( vci_addr_t)(r_write_address.read())];2602 size_t set = m_y[(addr_t)(r_write_address.read())]; 2143 2603 size_t way = r_write_way.read(); 2144 2604 for(size_t word=0 ; word<m_words ; word++) … … 2160 2620 2161 2621 #if DEBUG_MEMC_WRITE 2162 if(m_debug _write_fsm)2163 { 2164 std::cout << " <MEMC " << name() << " .WRITE_DIR_READ> Read the cache to complete local buffer" << std::endl;2622 if(m_debug) 2623 { 2624 std::cout << " <MEMC " << name() << " WRITE_DIR_READ> Read the cache to complete local buffer" << std::endl; 2165 2625 } 2166 2626 #endif … … 2187 2647 entry.ptr = r_write_ptr.read(); 2188 2648 2189 size_t set = m_y[( vci_addr_t)(r_write_address.read())];2649 size_t set = m_y[(addr_t)(r_write_address.read())]; 2190 2650 size_t way = r_write_way.read(); 2191 2651 … … 2202 2662 // no_update is true when there is no need for coherence transaction 2203 2663 // (tests for sc requests) 2204 bool no_update = ((r_write_count.read() ==0) || (owner && (r_write_count.read() ==1) && (r_write_pktid.read() != TYPE_SC))); 2664 bool no_update = ( (r_write_count.read() == 0) or 2665 (owner and (r_write_count.read() ==1) and (r_write_pktid.read() != TYPE_SC))); 2205 2666 2206 2667 // write data in the cache if no coherence transaction … … 2213 2674 if(m_monitor_ok) 2214 2675 { 2215 vci_addr_t address = (r_write_address.read() & ~(vci_addr_t) 0x3F) | word<<2;2676 addr_t address = (r_write_address.read() & ~(addr_t) 0x3F) | word<<2; 2216 2677 char buf[80]; 2217 snprintf(buf, 80, "WRITE_DIR_HIT srcid %d", r_write_srcid.read()); 2218 check_monitor(buf, address, r_write_data[word].read()); 2678 snprintf(buf, 80, "WRITE_DIR_HIT srcid %d", 2679 (int)r_write_srcid.read()); 2680 check_monitor(buf, address, r_write_data[word].read(), false); 2219 2681 } 2220 2682 } … … 2234 2696 // coherence update required 2235 2697 { 2236 if(!r_write_to_cc_send_multi_req.read() &&2237 2698 if(!r_write_to_cc_send_multi_req.read() and 2699 !r_write_to_cc_send_brdcast_req.read()) 2238 2700 { 2239 2701 r_write_fsm = WRITE_UPT_LOCK; … … 2246 2708 2247 2709 #if DEBUG_MEMC_WRITE 2248 if(m_debug_write_fsm)2249 2250 2251 2252 std::cout << " <MEMC " << name() << ".WRITE_DIR_HIT> Write into cache / No coherence transaction"2253 << std::endl;2254 }2255 else2256 {2257 std::cout << " <MEMC " << name() << ".WRITE_DIR_HIT> Coherence update required:"2258 << " is_cnt = " << r_write_is_cnt.read()2259 << " nb_copies = " << std::dec << r_write_count.read() << std::endl;2260 if(owner)2261 2262 2263 2710 if(m_debug) 2711 { 2712 if(no_update) 2713 { 2714 std::cout << " <MEMC " << name() 2715 << " WRITE_DIR_HIT> Write into cache / No coherence transaction" 2716 << std::endl; 2717 } 2718 else 2719 { 2720 std::cout << " <MEMC " << name() << " WRITE_DIR_HIT> Coherence update required:" 2721 << " is_cnt = " << r_write_is_cnt.read() 2722 << " nb_copies = " << std::dec << r_write_count.read() << std::endl; 2723 if(owner) std::cout << " ... but the first copy is the writer" << std::endl; 2724 } 2725 } 2264 2726 #endif 2265 2727 break; … … 2276 2738 size_t trdid = r_write_trdid.read(); 2277 2739 size_t pktid = r_write_pktid.read(); 2278 addr_t nline = m_nline[( vci_addr_t)(r_write_address.read())];2740 addr_t nline = m_nline[(addr_t)(r_write_address.read())]; 2279 2741 size_t nb_copies = r_write_count.read(); 2280 size_t set = m_y[( vci_addr_t)(r_write_address.read())];2742 size_t set = m_y[(addr_t)(r_write_address.read())]; 2281 2743 size_t way = r_write_way.read(); 2282 2744 2283 2745 wok = m_upt.set(true, // it's an update transaction 2284 false, // it's not a broadcast 2285 true, // it needs a response 2286 srcid, 2287 trdid, 2288 pktid, 2289 nline, 2290 nb_copies, 2291 index); 2746 false, // it's not a broadcast 2747 true, // response required 2748 false, // no acknowledge required 2749 srcid, 2750 trdid, 2751 pktid, 2752 nline, 2753 nb_copies, 2754 index); 2292 2755 if(wok) // write data in cache 2293 2756 { 2294 2757 for(size_t word=0 ; word<m_words ; word++) 2295 2758 { 2296 m_cache_data.write(way, set, word, r_write_data[word].read(), r_write_be[word].read()); 2759 m_cache_data.write(way, 2760 set, 2761 word, 2762 r_write_data[word].read(), 2763 r_write_be[word].read()); 2297 2764 2298 2765 if(m_monitor_ok) 2299 2766 { 2300 vci_addr_t address = (r_write_address.read() & ~(vci_addr_t) 0x3F) | word<<2;2767 addr_t address = (r_write_address.read() & ~(addr_t) 0x3F) | word<<2; 2301 2768 char buf[80]; 2302 snprintf(buf, 80, "WRITE_UPT_LOCK srcid %d", srcid);2303 check_monitor(buf, address, r_write_data[word].read() );2769 snprintf(buf, 80, "WRITE_UPT_LOCK srcid %d", (int)srcid); 2770 check_monitor(buf, address, r_write_data[word].read(), false); 2304 2771 } 2305 2772 } … … 2307 2774 2308 2775 #if DEBUG_MEMC_WRITE 2309 if(m_debug_write_fsm) 2310 { 2311 if(wok) 2312 { 2313 std::cout << " <MEMC " << name() << ".WRITE_UPT_LOCK> Register the multicast update in UPT / " 2314 << " nb_copies = " << r_write_count.read() << std::endl; 2315 } 2316 } 2776 if(m_debug) 2777 { 2778 if(wok) 2779 { 2780 std::cout << " <MEMC " << name() 2781 << " WRITE_UPT_LOCK> Register the multicast update in UPT / " 2782 << " nb_copies = " << r_write_count.read() << std::endl; 2783 } 2784 } 2317 2785 #endif 2318 2786 r_write_upt_index = index; … … 2331 2799 2332 2800 #if DEBUG_MEMC_WRITE 2333 if(m_debug_write_fsm) 2334 { 2335 std::cout << " <MEMC " << name() << ".WRITE_UPT_HEAP_LOCK> Get acces to the HEAP" << std::endl; 2336 } 2801 if(m_debug) 2802 std::cout << " <MEMC " << name() 2803 << " WRITE_UPT_HEAP_LOCK> Get acces to the HEAP" << std::endl; 2337 2804 #endif 2338 2805 r_write_fsm = WRITE_UPT_REQ; … … 2342 2809 2343 2810 ////////////////// 2344 case WRITE_UPT_REQ: 2345 { 2346 // prepare the coherence transaction for the CC_SEND FSM 2347 // and write the first copy in the FIFO 2348 // send the request if only one copy 2349 2350 if(!r_write_to_cc_send_multi_req.read() && 2351 !r_write_to_cc_send_brdcast_req.read()) // no pending coherence request 2352 { 2353 r_write_to_cc_send_brdcast_req = false; 2354 r_write_to_cc_send_trdid = r_write_upt_index.read(); 2355 r_write_to_cc_send_nline = m_nline[(vci_addr_t)(r_write_address.read())]; 2356 r_write_to_cc_send_index = r_write_word_index.read(); 2357 r_write_to_cc_send_count = r_write_word_count.read(); 2358 2359 for(size_t i=0; i<m_words ; i++) r_write_to_cc_send_be[i]=r_write_be[i].read(); 2360 2361 size_t min = r_write_word_index.read(); 2362 size_t max = r_write_word_index.read() + r_write_word_count.read(); 2363 for(size_t i=min ; i<max ; i++) r_write_to_cc_send_data[i] = r_write_data[i]; 2364 2365 if((r_write_copy.read() != r_write_srcid.read()) or(r_write_pktid.read() == TYPE_SC) or 2811 case WRITE_UPT_REQ: // prepare the coherence transaction for the CC_SEND FSM 2812 // and write the first copy in the FIFO 2813 // send the request if only one copy 2814 { 2815 assert(not r_write_to_cc_send_multi_req.read() and 2816 not r_write_to_cc_send_brdcast_req.read() and 2817 "Error in VCI_MEM_CACHE : pending multicast or broadcast\n" 2818 "transaction in WRITE_UPT_REQ state" 2819 ); 2820 2821 r_write_to_cc_send_brdcast_req = false; 2822 r_write_to_cc_send_trdid = r_write_upt_index.read(); 2823 r_write_to_cc_send_nline = m_nline[(addr_t)(r_write_address.read())]; 2824 r_write_to_cc_send_index = r_write_word_index.read(); 2825 r_write_to_cc_send_count = r_write_word_count.read(); 2826 2827 for(size_t i=0; i<m_words ; i++) r_write_to_cc_send_be[i]=r_write_be[i].read(); 2828 2829 size_t min = r_write_word_index.read(); 2830 size_t max = r_write_word_index.read() + r_write_word_count.read(); 2831 for(size_t i=min ; i<max ; i++) r_write_to_cc_send_data[i] = r_write_data[i]; 2832 2833 if((r_write_copy.read() != r_write_srcid.read()) or(r_write_pktid.read() == TYPE_SC) or 2366 2834 #if L1_MULTI_CACHE 2367 2368 #endif 2369 2370 2371 2372 2373 2374 2835 (r_write_copy_cache.read() != r_write_pktid.read()) or 2836 #endif 2837 r_write_copy_inst.read()) 2838 { 2839 // put the first srcid in the fifo 2840 write_to_cc_send_fifo_put = true; 2841 write_to_cc_send_fifo_inst = r_write_copy_inst.read(); 2842 write_to_cc_send_fifo_srcid = r_write_copy.read(); 2375 2843 #if L1_MULTI_CACHE 2376 write_to_cc_send_fifo_cache_id= r_write_copy_cache.read(); 2377 #endif 2378 if(r_write_count.read() == 1) 2379 { 2380 r_write_fsm = WRITE_IDLE; 2381 r_write_to_cc_send_multi_req = true; 2382 } 2383 else 2384 { 2385 r_write_fsm = WRITE_UPT_NEXT; 2386 r_write_to_dec = false; 2387 2388 } 2844 write_to_cc_send_fifo_cache_id= r_write_copy_cache.read(); 2845 #endif 2846 if(r_write_count.read() == 1) 2847 { 2848 r_write_fsm = WRITE_IDLE; 2849 r_write_to_cc_send_multi_req = true; 2389 2850 } 2390 2851 else … … 2392 2853 r_write_fsm = WRITE_UPT_NEXT; 2393 2854 r_write_to_dec = false; 2394 } 2855 2856 } 2857 } 2858 else 2859 { 2860 r_write_fsm = WRITE_UPT_NEXT; 2861 r_write_to_dec = false; 2862 } 2395 2863 2396 2864 #if DEBUG_MEMC_WRITE 2397 if(m_debug_write_fsm) 2398 { 2399 std::cout << " <MEMC " << name() << ".WRITE_UPT_REQ> Post first request to CC_SEND FSM" 2400 << " / srcid = " << std::dec << r_write_copy.read() 2401 << " / inst = " << std::dec << r_write_copy_inst.read() << std::endl; 2402 if(r_write_count.read() == 1) 2403 std::cout << " ... and this is the last" << std::endl; 2404 } 2405 #endif 2406 } 2865 if(m_debug) 2866 { 2867 std::cout 2868 << " <MEMC " << name() 2869 << " WRITE_UPT_REQ> Post first request to CC_SEND FSM" 2870 << " / srcid = " << std::dec << r_write_copy.read() 2871 << " / inst = " << std::dec << r_write_copy_inst.read() << std::endl; 2872 2873 if(r_write_count.read() == 1) 2874 std::cout << " ... and this is the last" << std::endl; 2875 } 2876 #endif 2407 2877 break; 2408 2878 } … … 2424 2894 bool dec_upt_counter; 2425 2895 2426 if(((entry.owner.srcid != r_write_srcid.read()) ||(r_write_pktid.read() == TYPE_SC)) or2896 if(((entry.owner.srcid != r_write_srcid.read()) or (r_write_pktid.read() == TYPE_SC)) or 2427 2897 #if L1_MULTI_CACHE 2428 2898 (entry.owner.cache_id != r_write_pktid.read()) or … … 2439 2909 2440 2910 #if DEBUG_MEMC_WRITE 2441 if(m_debug _write_fsm)2442 { 2443 std::cout << " <MEMC " << name() << " .WRITE_UPT_NEXT> Post another request to CC_SEND FSM"2911 if(m_debug) 2912 { 2913 std::cout << " <MEMC " << name() << " WRITE_UPT_NEXT> Post another request to CC_SEND FSM" 2444 2914 << " / heap_index = " << std::dec << r_write_ptr.read() 2445 2915 << " / srcid = " << std::dec << r_write_copy.read() … … 2455 2925 2456 2926 #if DEBUG_MEMC_WRITE 2457 if(m_debug _write_fsm)2458 { 2459 std::cout << " <MEMC " << name() << " .WRITE_UPT_NEXT> Skip one entry in heap matching the writer"2927 if(m_debug) 2928 { 2929 std::cout << " <MEMC " << name() << " WRITE_UPT_NEXT> Skip one entry in heap matching the writer" 2460 2930 << " / heap_index = " << std::dec << r_write_ptr.read() 2461 2931 << " / srcid = " << std::dec << r_write_copy.read() … … 2535 3005 // consume a word in the FIFO & write it in the local buffer 2536 3006 cmd_write_fifo_get = true; 2537 size_t index = m_x[( vci_addr_t)(m_cmd_write_addr_fifo.read())];3007 size_t index = m_x[(addr_t)(m_cmd_write_addr_fifo.read())]; 2538 3008 2539 3009 r_write_address = (addr_t)(m_cmd_write_addr_fifo.read()); … … 2553 3023 } 2554 3024 2555 if(m_cmd_write_eop_fifo.read() ||((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC))3025 if(m_cmd_write_eop_fifo.read() or ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC)) 2556 3026 { 2557 3027 r_write_fsm = WRITE_DIR_REQ; … … 2568 3038 2569 3039 #if DEBUG_MEMC_WRITE 2570 if(m_debug_write_fsm)2571 2572 std::cout << " <MEMC " << name() << ".WRITE_RSP> Post a request to TGT_RSP FSM: rsrcid ="2573 << std::dec<< r_write_srcid.read() << std::endl;2574 2575 2576 2577 << " srcid = " << std::dec<< m_cmd_write_srcid_fifo.read()2578 << " / address = " << std::hex<< m_cmd_write_addr_fifo.read()2579 2580 2581 3040 if(m_debug) 3041 { 3042 std::cout << " <MEMC " << name() << " WRITE_RSP> Post a request to TGT_RSP FSM" 3043 << " : rsrcid = " << std::hex << r_write_srcid.read() << std::endl; 3044 if(m_cmd_write_addr_fifo.rok()) 3045 { 3046 std::cout << " New Write request: " 3047 << " srcid = " << std::hex << m_cmd_write_srcid_fifo.read() 3048 << " / address = " << m_cmd_write_addr_fifo.read() 3049 << " / data = " << m_cmd_write_data_fifo.read() << std::endl; 3050 } 3051 } 2582 3052 #endif 2583 3053 } … … 2592 3062 2593 3063 #if DEBUG_MEMC_WRITE 2594 if(m_debug_write_fsm) 2595 { 2596 std::cout << " <MEMC " << name() << ".WRITE_MISS_TRT_LOCK> Check the TRT" << std::endl; 2597 } 3064 if(m_debug) 3065 std::cout << " <MEMC " << name() << " WRITE_MISS_TRT_LOCK> Check the TRT" << std::endl; 2598 3066 #endif 2599 3067 size_t hit_index = 0; 2600 3068 size_t wok_index = 0; 2601 vci_addr_t addr = (vci_addr_t) r_write_address.read();3069 addr_t addr = (addr_t) r_write_address.read(); 2602 3070 bool hit_read = m_trt.hit_read(m_nline[addr], hit_index); 2603 3071 bool hit_write = m_trt.hit_write(m_nline[addr]); … … 2610 3078 m_cpt_write_miss++; 2611 3079 } 2612 else if(wok &&!hit_write) // set a new entry in TRT3080 else if(wok and !hit_write) // set a new entry in TRT 2613 3081 { 2614 3082 r_write_trt_index = wok_index; … … 2628 3096 case WRITE_WAIT: // release the locks protecting the shared ressources 2629 3097 { 3098 2630 3099 #if DEBUG_MEMC_WRITE 2631 if(m_debug_write_fsm) 2632 { 2633 std::cout << " <MEMC " << name() << ".WRITE_WAIT> Releases the locks before retry" << std::endl; 2634 } 3100 if(m_debug) 3101 std::cout << " <MEMC " << name() << " WRITE_WAIT> Releases the locks before retry" << std::endl; 2635 3102 #endif 2636 3103 r_write_fsm = WRITE_DIR_REQ; … … 2654 3121 m_trt.set(r_write_trt_index.read(), 2655 3122 true, // read request to XRAM 2656 m_nline[( vci_addr_t)(r_write_address.read())],3123 m_nline[(addr_t)(r_write_address.read())], 2657 3124 r_write_srcid.read(), 2658 3125 r_write_trdid.read(), … … 2666 3133 2667 3134 #if DEBUG_MEMC_WRITE 2668 if(m_debug_write_fsm) 2669 { 2670 std::cout << " <MEMC " << name() << ".WRITE_MISS_TRT_SET> Set a new entry in TRT" << std::endl; 2671 } 3135 if(m_debug) 3136 std::cout << " <MEMC " << name() << " WRITE_MISS_TRT_SET> Set a new entry in TRT" << std::endl; 2672 3137 #endif 2673 3138 } … … 2695 3160 2696 3161 #if DEBUG_MEMC_WRITE 2697 if(m_debug_write_fsm) 2698 { 2699 std::cout << " <MEMC " << name() << ".WRITE_MISS_TRT_DATA> Modify an existing entry in TRT" << std::endl; 2700 m_trt.print(r_write_trt_index.read()); 2701 } 3162 if(m_debug) 3163 std::cout << " <MEMC " << name() << " WRITE_MISS_TRT_DATA> Modify an existing entry in TRT" << std::endl; 2702 3164 #endif 2703 3165 } … … 2712 3174 r_write_to_ixr_cmd_req = true; 2713 3175 r_write_to_ixr_cmd_write = false; 2714 r_write_to_ixr_cmd_nline = m_nline[( vci_addr_t)(r_write_address.read())];3176 r_write_to_ixr_cmd_nline = m_nline[(addr_t)(r_write_address.read())]; 2715 3177 r_write_to_ixr_cmd_trdid = r_write_trt_index.read(); 2716 3178 r_write_fsm = WRITE_RSP; 2717 3179 2718 3180 #if DEBUG_MEMC_WRITE 2719 if(m_debug_write_fsm) 2720 { 2721 std::cout << " <MEMC " << name() << ".WRITE_MISS_XRAM_REQ> Post a GET request to the IXR_CMD FSM" << std::endl; 2722 } 3181 if(m_debug) 3182 std::cout << " <MEMC " << name() << " WRITE_MISS_XRAM_REQ> Post a GET request to the IXR_CMD FSM" << std::endl; 2723 3183 #endif 2724 3184 } … … 2744 3204 2745 3205 #if DEBUG_MEMC_WRITE 2746 if(m_debug_write_fsm) 2747 { 2748 std::cout << " <MEMC " << name() << ".WRITE_BC_TRT_LOCK> Check TRT : wok = " 2749 << wok << " / index = " << wok_index << std::endl; 2750 } 3206 if(m_debug) 3207 std::cout << " <MEMC " << name() << " WRITE_BC_TRT_LOCK> Check TRT" 3208 << " : wok = " << wok << " / index = " << wok_index << std::endl; 2751 3209 #endif 2752 3210 } … … 2764 3222 size_t trdid = r_write_trdid.read(); 2765 3223 size_t pktid = r_write_pktid.read(); 2766 addr_t nline = m_nline[( vci_addr_t)(r_write_address.read())];3224 addr_t nline = m_nline[(addr_t)(r_write_address.read())]; 2767 3225 size_t nb_copies = r_write_count.read(); 2768 3226 2769 wok =m_upt.set(false, // it's an inval transaction 2770 true, // it's a broadcast 2771 true, // it needs a response 2772 srcid, 2773 trdid, 2774 pktid, 2775 nline, 2776 nb_copies, 2777 index); 3227 wok = m_upt.set(false, // it's an inval transaction 3228 true, // it's a broadcast 3229 true, // response required 3230 false, // no acknowledge required 3231 srcid, 3232 trdid, 3233 pktid, 3234 nline, 3235 nb_copies, 3236 index); 2778 3237 2779 3238 #if DEBUG_MEMC_WRITE 2780 if(m_debug_write_fsm) 2781 { 2782 if(wok) 2783 { 2784 std::cout << " <MEMC " << name() << ".WRITE_BC_UPT_LOCK> Register the broadcast inval in UPT / " 2785 << " nb_copies = " << r_write_count.read() << std::endl; 2786 } 2787 } 3239 if( m_debug and wok ) 3240 std::cout << " <MEMC " << name() << " WRITE_BC_UPT_LOCK> Register broadcast inval in UPT" 3241 << " / nb_copies = " << r_write_count.read() << std::endl; 2788 3242 #endif 2789 3243 r_write_upt_index = index; … … 2800 3254 // Register a put transaction to XRAM in TRT 2801 3255 // and invalidate the line in directory 2802 if((r_alloc_trt_fsm.read() != ALLOC_TRT_WRITE) ||2803 (r_alloc_upt_fsm.read() != ALLOC_UPT_WRITE) ||3256 if((r_alloc_trt_fsm.read() != ALLOC_TRT_WRITE) or 3257 (r_alloc_upt_fsm.read() != ALLOC_UPT_WRITE) or 2804 3258 (r_alloc_dir_fsm.read() != ALLOC_DIR_WRITE)) 2805 3259 { … … 2812 3266 m_trt.set(r_write_trt_index.read(), 2813 3267 false, // write request to XRAM 2814 m_nline[( vci_addr_t)(r_write_address.read())],3268 m_nline[(addr_t)(r_write_address.read())], 2815 3269 0, 2816 3270 0, … … 2836 3290 entry.ptr = 0; 2837 3291 entry.count = 0; 2838 size_t set = m_y[( vci_addr_t)(r_write_address.read())];3292 size_t set = m_y[(addr_t)(r_write_address.read())]; 2839 3293 size_t way = r_write_way.read(); 2840 3294 … … 2842 3296 2843 3297 #if DEBUG_MEMC_WRITE 2844 if(m_debug_write_fsm) 2845 { 2846 std::cout << " <MEMC " << name() << ".WRITE_BC_DIR_INVAL> Invalidate the directory entry: @ = " 2847 << r_write_address.read() << " / register the put transaction in TRT:" << std::endl; 2848 } 3298 if(m_debug) 3299 std::cout << " <MEMC " << name() << " WRITE_BC_DIR_INVAL> Invalidate the directory entry: @ = " 3300 << r_write_address.read() << " / register the put transaction in TRT:" << std::endl; 2849 3301 #endif 2850 3302 r_write_fsm = WRITE_BC_CC_SEND; … … 2855 3307 case WRITE_BC_CC_SEND: // Post a coherence broadcast request to CC_SEND FSM 2856 3308 { 2857 if(!r_write_to_cc_send_multi_req.read() &&!r_write_to_cc_send_brdcast_req.read())3309 if(!r_write_to_cc_send_multi_req.read() and !r_write_to_cc_send_brdcast_req.read()) 2858 3310 { 2859 3311 r_write_to_cc_send_multi_req = false; 2860 3312 r_write_to_cc_send_brdcast_req = true; 2861 3313 r_write_to_cc_send_trdid = r_write_upt_index.read(); 2862 r_write_to_cc_send_nline = m_nline[( vci_addr_t)(r_write_address.read())];3314 r_write_to_cc_send_nline = m_nline[(addr_t)(r_write_address.read())]; 2863 3315 r_write_to_cc_send_index = 0; 2864 3316 r_write_to_cc_send_count = 0; … … 2872 3324 2873 3325 #if DEBUG_MEMC_WRITE 2874 if(m_debug_write_fsm) 2875 { 2876 std::cout << " <MEMC " << name() << ".WRITE_BC_CC_SEND> Post a broadcast request to CC_SEND FSM" << std::endl; 2877 } 3326 if(m_debug) 3327 std::cout << " <MEMC " << name() 3328 << " WRITE_BC_CC_SEND> Post a broadcast request to CC_SEND FSM" << std::endl; 2878 3329 #endif 2879 3330 } … … 2888 3339 r_write_to_ixr_cmd_req = true; 2889 3340 r_write_to_ixr_cmd_write = true; 2890 r_write_to_ixr_cmd_nline = m_nline[( vci_addr_t)(r_write_address.read())];3341 r_write_to_ixr_cmd_nline = m_nline[(addr_t)(r_write_address.read())]; 2891 3342 r_write_to_ixr_cmd_trdid = r_write_trt_index.read(); 2892 3343 … … 2896 3347 2897 3348 #if DEBUG_MEMC_WRITE 2898 if(m_debug_write_fsm) 2899 { 2900 std::cout << " <MEMC " << name() << ".WRITE_BC_XRAM_REQ> Post a put request to IXR_CMD FSM" << std::endl; 2901 } 3349 if(m_debug) 3350 std::cout << " <MEMC " << name() 3351 << " WRITE_BC_XRAM_REQ> Post a put request to IXR_CMD FSM" << std::endl; 2902 3352 #endif 2903 3353 } … … 2910 3360 /////////////////////////////////////////////////////////////////////// 2911 3361 // The IXR_CMD fsm controls the command packets to the XRAM : 2912 // - It sends a single cell VCI read request to the XRAM in case of MISS 3362 // It handles requests from the READ, WRITE, CAS, XRAM_RSP FSMs 3363 // with a round-robin priority. 3364 // 3365 // - It sends a single flit VCI read request to the XRAM in case of MISS 2913 3366 // posted by the READ, WRITE or CAS FSMs : the TRDID field contains 2914 3367 // the Transaction Tab index. 2915 // The VCI response is a multi- cellpacket : the N cells contain3368 // The VCI response is a multi-flit packet : the N cells contain 2916 3369 // the N data words. 2917 // - It sends a multi-cell VCI write when the XRAM_RSP FSM, WRITE FSM 3370 // 3371 // - It sends a multi-flit VCI write when the XRAM_RSP FSM, WRITE FSM 2918 3372 // or CAS FSM request to save a dirty line to the XRAM. 2919 // The VCI response is a single cell packet. 2920 // This FSM handles requests from the READ, WRITE, CAS & XRAM_RSP FSMs 2921 // with a round-robin priority. 3373 // The VCI response is a single flit packet. 2922 3374 //////////////////////////////////////////////////////////////////////// 2923 3375 2924 3376 switch(r_ixr_cmd_fsm.read()) 2925 3377 { 2926 3378 //////////////////////// 2927 3379 case IXR_CMD_READ_IDLE: 2928 if(r_write_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE; 2929 else if(r_cas_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_CAS_NLINE; 2930 else if(r_xram_rsp_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA; 2931 else if(r_read_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_READ_NLINE; 2932 break; 2933 //////////////////////// 3380 { 3381 if (r_write_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_WRITE; 3382 else if(r_cas_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_CAS; 3383 else if(r_xram_rsp_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_XRAM; 3384 else if(r_read_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_READ; 3385 break; 3386 } 3387 //////////////////////// 2934 3388 case IXR_CMD_WRITE_IDLE: 2935 if(r_cas_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_CAS_NLINE; 2936 else if(r_xram_rsp_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA; 2937 else if(r_read_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_READ_NLINE; 2938 else if(r_write_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE; 2939 break; 2940 //////////////////////// 3389 { 3390 if (r_cas_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_CAS; 3391 else if(r_xram_rsp_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_XRAM; 3392 else if(r_read_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_READ; 3393 else if(r_write_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_WRITE; 3394 break; 3395 } 3396 //////////////////////// 2941 3397 case IXR_CMD_CAS_IDLE: 2942 if(r_xram_rsp_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA; 2943 else if(r_read_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_READ_NLINE; 2944 else if(r_write_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE; 2945 else if(r_cas_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_CAS_NLINE; 2946 break; 2947 //////////////////////// 3398 { 3399 if (r_xram_rsp_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_XRAM; 3400 else if(r_read_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_READ; 3401 else if(r_write_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_WRITE; 3402 else if(r_cas_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_CAS; 3403 break; 3404 } 3405 //////////////////////// 2948 3406 case IXR_CMD_XRAM_IDLE: 2949 if(r_read_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_READ_NLINE; 2950 else if(r_write_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE; 2951 else if(r_cas_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_CAS_NLINE; 2952 else if(r_xram_rsp_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA; 2953 break; 2954 ///////////////////////// // send a get request to XRAM 2955 case IXR_CMD_READ_NLINE: 3407 { 3408 if (r_read_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_READ; 3409 else if(r_write_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_WRITE; 3410 else if(r_cas_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_CAS; 3411 else if(r_xram_rsp_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_XRAM; 3412 break; 3413 } 3414 ////////////////// // send a get from READ FSM 3415 case IXR_CMD_READ: 3416 { 2956 3417 if(p_vci_ixr.cmdack) 2957 3418 { … … 2960 3421 2961 3422 #if DEBUG_MEMC_IXR_CMD 2962 if(m_debug_ixr_cmd_fsm) 2963 { 2964 std::cout << " <MEMC " << name() << ".IXR_CMD_READ_NLINE> Send a get request to xram" << std::endl; 2965 } 2966 #endif 2967 } 2968 break; 2969 ////////////////////////// 2970 case IXR_CMD_WRITE_NLINE: // send a put or get command to XRAM 3423 if(m_debug) 3424 std::cout << " <MEMC " << name() << " IXR_CMD_READ>" 3425 << " Send a get request to xram / address = " << std::hex 3426 << (addr_t)(r_read_to_ixr_cmd_nline.read()*m_words*4) << std::endl; 3427 #endif 3428 } 3429 break; 3430 } 3431 /////////////////// 3432 case IXR_CMD_WRITE: // send a put or get from WRITE FSM 3433 { 2971 3434 if(p_vci_ixr.cmdack) 2972 3435 { 2973 if(r_write_to_ixr_cmd_write.read()) 2974 { 2975 if(r_ixr_cmd_cpt.read() == (m_words - 1))3436 if(r_write_to_ixr_cmd_write.read()) // PUT 3437 { 3438 if(r_ixr_cmd_cpt.read() == (m_words - 2)) 2976 3439 { 2977 3440 r_ixr_cmd_cpt = 0; … … 2981 3444 else 2982 3445 { 2983 r_ixr_cmd_cpt = r_ixr_cmd_cpt + 1;3446 r_ixr_cmd_cpt = r_ixr_cmd_cpt + 2; 2984 3447 } 2985 3448 2986 3449 #if DEBUG_MEMC_IXR_CMD 2987 if(m_debug_ixr_cmd_fsm) 2988 { 2989 std::cout << " <MEMC " << name() << ".IXR_CMD_WRITE_NLINE> Send a put request to xram" << std::endl; 2990 } 2991 #endif 2992 } 2993 else 3450 if(m_debug) 3451 std::cout << " <MEMC " << name() << " IXR_CMD_WRITE>" 3452 << " Send a put request to xram / address = " << std::hex 3453 << (addr_t)((r_write_to_ixr_cmd_nline.read() * m_words + 3454 r_ixr_cmd_cpt.read()) * 4 ) << std::endl; 3455 #endif 3456 } 3457 else // GET 2994 3458 { 2995 3459 r_ixr_cmd_fsm = IXR_CMD_WRITE_IDLE; … … 2997 3461 2998 3462 #if DEBUG_MEMC_IXR_CMD 2999 if(m_debug_ixr_cmd_fsm) 3000 { 3001 std::cout << " <MEMC " << name() << ".IXR_CMD_WRITE_NLINE> Send a get request to xram" << std::endl; 3002 } 3003 #endif 3004 } 3005 } 3006 break; 3007 ////////////////////// 3008 case IXR_CMD_CAS_NLINE: // send a put or get command to XRAM 3463 if(m_debug) 3464 std::cout << " <MEMC " << name() << " IXR_CMD_WRITE>" 3465 << " Send a get request to xram / address = " << std::hex 3466 << (addr_t)(r_write_to_ixr_cmd_nline.read()*m_words*4) << std::endl; 3467 #endif 3468 } 3469 } 3470 break; 3471 } 3472 ///////////////// 3473 case IXR_CMD_CAS: // send a put or get command from CAS FSM 3474 { 3009 3475 if(p_vci_ixr.cmdack) 3010 3476 { 3011 if(r_cas_to_ixr_cmd_write.read()) 3012 { 3013 if(r_ixr_cmd_cpt.read() == (m_words - 1))3477 if(r_cas_to_ixr_cmd_write.read()) // PUT 3478 { 3479 if(r_ixr_cmd_cpt.read() == (m_words - 2)) 3014 3480 { 3015 3481 r_ixr_cmd_cpt = 0; … … 3019 3485 else 3020 3486 { 3021 r_ixr_cmd_cpt = r_ixr_cmd_cpt + 1;3487 r_ixr_cmd_cpt = r_ixr_cmd_cpt + 2; 3022 3488 } 3023 3489 3024 3490 #if DEBUG_MEMC_IXR_CMD 3025 if(m_debug_ixr_cmd_fsm) 3026 { 3027 std::cout << " <MEMC " << name() << ".IXR_CMD_CAS_NLINE> Send a put request to xram" << std::endl; 3028 } 3029 #endif 3030 } 3031 else 3491 if(m_debug) 3492 std::cout << " <MEMC " << name() << " IXR_CMD_CAS>" 3493 << " Send a put request to xram / address = " << std::hex 3494 << (addr_t)( (r_cas_to_ixr_cmd_nline.read() * m_words + 3495 r_ixr_cmd_cpt.read()) * 4 ) << std::endl; 3496 #endif 3497 } 3498 else // GET 3032 3499 { 3033 3500 r_ixr_cmd_fsm = IXR_CMD_CAS_IDLE; … … 3035 3502 3036 3503 #if DEBUG_MEMC_IXR_CMD 3037 if(m_debug_ixr_cmd_fsm) 3038 { 3039 std::cout << " <MEMC " << name() << ".IXR_CMD_CAS_NLINE> Send a get request to xram" << std::endl; 3040 } 3041 #endif 3042 } 3043 } 3044 break; 3045 //////////////////////// 3046 case IXR_CMD_XRAM_DATA: // send a put command to XRAM 3504 if(m_debug) 3505 std::cout << " <MEMC " << name() << " IXR_CMD_CAS>" 3506 << " Send a get request to xram / address = " << std::hex 3507 << (addr_t)(r_cas_to_ixr_cmd_nline.read()*m_words*4) << std::endl; 3508 #endif 3509 } 3510 } 3511 break; 3512 } 3513 ////////////////// 3514 case IXR_CMD_XRAM: // send a put from XRAM_RSP FSM 3515 { 3047 3516 if(p_vci_ixr.cmdack) 3048 3517 { 3049 if(r_ixr_cmd_cpt.read() == (m_words - 1))3518 if(r_ixr_cmd_cpt.read() == (m_words - 2)) 3050 3519 { 3051 3520 r_ixr_cmd_cpt = 0; … … 3055 3524 else 3056 3525 { 3057 r_ixr_cmd_cpt = r_ixr_cmd_cpt + 1;3526 r_ixr_cmd_cpt = r_ixr_cmd_cpt + 2; 3058 3527 } 3059 3528 3060 3529 #if DEBUG_MEMC_IXR_CMD 3061 if(m_debug_ixr_cmd_fsm) 3062 { 3063 std::cout << " <MEMC " << name() << ".IXR_CMD_XRAM_DATA> Send a put request to xram" << std::endl; 3064 } 3065 #endif 3066 } 3067 break; 3530 if(m_debug) 3531 std::cout << " <MEMC " << name() << " IXR_CMD_XRAM>" 3532 << " Send a put request to xram / address = " << std::hex 3533 << (addr_t)( (r_xram_rsp_to_ixr_cmd_nline.read() * m_words + 3534 r_ixr_cmd_cpt.read()) * 4 ) << std::endl; 3535 #endif 3536 } 3537 break; 3538 } 3068 3539 3069 3540 } // end switch r_ixr_cmd_fsm … … 3090 3561 switch(r_ixr_rsp_fsm.read()) 3091 3562 { 3092 3093 case IXR_RSP_IDLE: // test if it's a get or a put transaction3563 ////////////////// 3564 case IXR_RSP_IDLE: // test transaction type: PUT/GET 3094 3565 { 3095 3566 if(p_vci_ixr.rspval.read()) … … 3097 3568 r_ixr_rsp_cpt = 0; 3098 3569 r_ixr_rsp_trt_index = p_vci_ixr.rtrdid.read(); 3099 if(p_vci_ixr.reop.read() && !(p_vci_ixr.rerror.read() &0x1)) // puttransaction3570 if(p_vci_ixr.reop.read() and !(p_vci_ixr.rerror.read() &0x1)) // PUT transaction 3100 3571 { 3101 3572 r_ixr_rsp_fsm = IXR_RSP_ACK; 3102 3573 3103 3574 #if DEBUG_MEMC_IXR_RSP 3104 if(m_debug_ixr_rsp_fsm) 3105 { 3106 std::cout << " <MEMC " << name() << ".IXR_RSP_IDLE> Response from XRAM to a put transaction" << std::endl; 3107 } 3108 #endif 3109 } 3110 else // get transaction 3575 if(m_debug) 3576 std::cout << " <MEMC " << name() 3577 << " IXR_RSP_IDLE> Response from XRAM to a put transaction" << std::endl; 3578 #endif 3579 } 3580 else // GET transaction 3111 3581 { 3112 3582 r_ixr_rsp_fsm = IXR_RSP_TRT_READ; 3113 3583 3114 3584 #if DEBUG_MEMC_IXR_RSP 3115 if(m_debug_ixr_rsp_fsm) 3116 { 3117 std::cout << " <MEMC " << name() << ".IXR_RSP_IDLE> Response from XRAM to a get transaction" << std::endl; 3118 } 3119 #endif 3120 } 3121 } 3122 break; 3123 } 3124 //////////////////////// 3125 case IXR_RSP_ACK: // Aknowledge the VCI response 3585 if(m_debug) 3586 std::cout << " <MEMC " << name() 3587 << " IXR_RSP_IDLE> Response from XRAM to a get transaction" << std::endl; 3588 #endif 3589 } 3590 } 3591 break; 3592 } 3593 ///////////////// 3594 case IXR_RSP_ACK: // Aknowledge the VCI response for a PUT 3126 3595 { 3127 3596 if(p_vci_ixr.rspval.read()) r_ixr_rsp_fsm = IXR_RSP_TRT_ERASE; 3128 3597 3129 3598 #if DEBUG_MEMC_IXR_RSP 3130 if(m_debug_ixr_rsp_fsm) 3131 { 3132 std::cout << " <MEMC " << name() << ".IXR_RSP_ACK>" << std::endl; 3133 } 3599 if(m_debug) 3600 std::cout << " <MEMC " << name() << " IXR_RSP_ACK>" << std::endl; 3134 3601 #endif 3135 3602 break; … … 3144 3611 3145 3612 #if DEBUG_MEMC_IXR_RSP 3146 if(m_debug_ixr_rsp_fsm) 3147 { 3148 std::cout << " <MEMC " << name() << ".IXR_RSP_TRT_ERASE> Erase TRT entry " 3149 << r_ixr_rsp_trt_index.read() << std::endl; 3150 } 3151 #endif 3152 } 3153 break; 3154 } 3155 /////////////////////// 3156 case IXR_RSP_TRT_READ: // write data in the TRT 3157 { 3158 if((r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP) && p_vci_ixr.rspval) 3159 { 3160 size_t index = r_ixr_rsp_trt_index.read(); 3161 bool eop = p_vci_ixr.reop.read(); 3162 data_t data = p_vci_ixr.rdata.read(); 3163 bool error = ((p_vci_ixr.rerror.read() & 0x1) == 1); 3164 assert(((eop == (r_ixr_rsp_cpt.read() == (m_words-1))) || p_vci_ixr.rerror.read()) 3613 if(m_debug) 3614 std::cout << " <MEMC " << name() << " IXR_RSP_TRT_ERASE> Erase TRT entry " 3615 << r_ixr_rsp_trt_index.read() << std::endl; 3616 #endif 3617 } 3618 break; 3619 } 3620 ////////////////////// 3621 case IXR_RSP_TRT_READ: // write a 64 bits data in the TRT 3622 { 3623 if((r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP) and p_vci_ixr.rspval) 3624 { 3625 size_t index = r_ixr_rsp_trt_index.read(); 3626 bool eop = p_vci_ixr.reop.read(); 3627 wide_data_t data = p_vci_ixr.rdata.read(); 3628 bool error = ((p_vci_ixr.rerror.read() & 0x1) == 1); 3629 3630 assert(((eop == (r_ixr_rsp_cpt.read() == (m_words-2))) or p_vci_ixr.rerror.read()) 3165 3631 and "Error in VCI_MEM_CACHE : invalid length for a response from XRAM"); 3166 m_trt.write_rsp(index, 3167 r_ixr_rsp_cpt.read(), 3168 data, 3169 error); 3170 r_ixr_rsp_cpt = r_ixr_rsp_cpt.read() + 1; 3632 3633 m_trt.write_rsp( index, 3634 r_ixr_rsp_cpt.read(), 3635 data, 3636 error); 3637 3638 r_ixr_rsp_cpt = r_ixr_rsp_cpt.read() + 2; 3639 3171 3640 if(eop) 3172 3641 { … … 3176 3645 3177 3646 #if DEBUG_MEMC_IXR_RSP 3178 if(m_debug_ixr_rsp_fsm) 3179 { 3180 std::cout << " <MEMC " << name() << ".IXR_RSP_TRT_READ> Writing a word in TRT : " 3181 << " index = " << std::dec << index 3182 << " / word = " << r_ixr_rsp_cpt.read() 3183 << " / data = " << std::hex << data << std::endl; 3184 } 3647 if(m_debug) 3648 std::cout << " <MEMC " << name() << " IXR_RSP_TRT_READ> Writing a word in TRT : " 3649 << " index = " << std::dec << index 3650 << " / word = " << r_ixr_rsp_cpt.read() 3651 << " / data = " << std::hex << data << std::endl; 3185 3652 #endif 3186 3653 } … … 3200 3667 // 3201 3668 // When a response is available, the corresponding TRT entry 3202 // must becopied in a local buffer to be written in the cache.3669 // is copied in a local buffer to be written in the cache. 3203 3670 // The FSM takes the lock protecting the TRT, and the lock protecting the DIR. 3204 3671 // It selects a cache slot and writes the line in the cache. … … 3214 3681 switch(r_xram_rsp_fsm.read()) 3215 3682 { 3216 3217 case XRAM_RSP_IDLE: // scan the XRAM responses to get theTRT index (round robin)3683 /////////////////// 3684 case XRAM_RSP_IDLE: // scan the XRAM responses / select a TRT index (round robin) 3218 3685 { 3219 3686 size_t ptr = r_xram_rsp_trt_index.read(); … … 3221 3688 for(size_t i=0 ; i<lines ; i++) 3222 3689 { 3223 size_t index = (i+ptr+1) %lines;3690 size_t index = (i+ptr+1) %lines; 3224 3691 if(r_ixr_rsp_to_xram_rsp_rok[index]) 3225 3692 { … … 3229 3696 3230 3697 #if DEBUG_MEMC_XRAM_RSP 3231 if(m_debug_xram_rsp_fsm) 3232 { 3233 std::cout << " <MEMC " << name() << ".XRAM_RSP_IDLE> Available cache line in TRT:" 3234 << " index = " << std::dec << index << std::endl; 3235 } 3698 if(m_debug) 3699 std::cout << " <MEMC " << name() << " XRAM_RSP_IDLE>" 3700 << " Available cache line in TRT:" 3701 << " index = " << std::dec << index << std::endl; 3236 3702 #endif 3237 3703 break; … … 3241 3707 } 3242 3708 /////////////////////// 3243 case XRAM_RSP_DIR_LOCK: 3244 // Takes the lock on the directory 3245 // Takes the lock on TRT 3246 // Copy the TRT entry in a local buffer 3247 { 3248 if((r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP) && 3709 case XRAM_RSP_DIR_LOCK: // Takes the DIR lock and the TRT lock 3710 // Copy the TRT entry in a local buffer 3711 { 3712 if((r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP) and 3249 3713 (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP)) 3250 3714 { 3251 3715 // copy the TRT entry in the r_xram_rsp_trt_buf local buffer 3252 3716 size_t index = r_xram_rsp_trt_index.read(); 3253 3254 TransactionTabEntry trt_entry(m_trt.read(index)); 3255 r_xram_rsp_trt_buf.copy(trt_entry); // TRT entry local buffer 3717 r_xram_rsp_trt_buf.copy( m_trt.read(index) ); 3256 3718 3257 3719 r_xram_rsp_fsm = XRAM_RSP_TRT_COPY; 3258 3720 3259 3721 #if DEBUG_MEMC_XRAM_RSP 3260 if(m_debug_xram_rsp_fsm) 3261 { 3262 std::cout << " <MEMC " << name() << ".XRAM_RSP_DIR_LOCK> Get access to directory" << std::endl; 3263 } 3722 if(m_debug) 3723 std::cout << " <MEMC " << name() << " XRAM_RSP_DIR_LOCK>" 3724 << " Get access to DIR and TRT" << std::endl; 3264 3725 #endif 3265 3726 } … … 3267 3728 } 3268 3729 /////////////////////// 3269 case XRAM_RSP_TRT_COPY: 3270 // Select a victim cache line 3271 { 3272 if((r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP)) 3730 case XRAM_RSP_TRT_COPY: // Select a victim cache line 3731 // and copy it in a local buffer 3732 { 3733 if ( (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP) and 3734 (r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP) ) 3273 3735 { 3274 3736 // selects & extracts a victim line from cache 3275 3737 size_t way = 0; 3276 size_t set = m_y[( vci_addr_t)(r_xram_rsp_trt_buf.nline * m_words * 4)];3738 size_t set = m_y[(addr_t)(r_xram_rsp_trt_buf.nline * m_words * 4)]; 3277 3739 3278 3740 DirectoryEntry victim(m_cache_directory.select(set, way)); 3279 3741 3280 bool inval = (victim.count &&victim.valid) ;3742 bool inval = (victim.count and victim.valid) ; 3281 3743 3282 3744 // copy the victim line in a local buffer … … 3284 3746 3285 3747 r_xram_rsp_victim_copy = victim.owner.srcid; 3748 3286 3749 #if L1_MULTI_CACHE 3287 3750 r_xram_rsp_victim_copy_cache= victim.owner.cache_id; … … 3307 3770 3308 3771 #if DEBUG_MEMC_XRAM_RSP 3309 if(m_debug_xram_rsp_fsm) 3310 { 3311 std::cout << " <MEMC " << name() << ".XRAM_RSP_TRT_COPY> Select a slot: " 3312 << " way = " << std::dec << way 3313 << " / set = " << set 3314 << " / inval_required = " << inval << std::endl; 3315 } 3772 if(m_debug) 3773 std::cout << " <MEMC " << name() << " XRAM_RSP_TRT_COPY>" 3774 << " Select a slot: " 3775 << " way = " << std::dec << way 3776 << " / set = " << set 3777 << " / inval_required = " << inval << std::endl; 3316 3778 #endif 3317 3779 } 3318 3780 else 3319 3781 { 3320 std::cout << "VCI_MEM_CACHE ERROR " << name() 3321 << " XRAM_RSP_TRT_COPY state" << std::endl 3322 << "bad TRT allocation" << std::endl; 3323 3782 std::cout << "VCI_MEM_CACHE ERROR " << name() << " XRAM_RSP_TRT_COPY" 3783 << " bad TRT or DIR allocation" << std::endl; 3324 3784 exit(0); 3325 3785 } … … 3327 3787 } 3328 3788 ///////////////////////// 3329 case XRAM_RSP_INVAL_LOCK: // check a possible pending inval3789 case XRAM_RSP_INVAL_LOCK: // Take the UPT lock to check a possible pending inval 3330 3790 { 3331 3791 if(r_alloc_upt_fsm == ALLOC_UPT_XRAM_RSP) 3332 3792 { 3333 size_t index ;3334 if(m_upt.search_inval(r_xram_rsp_trt_buf.nline, index)) 3793 size_t index = 0; 3794 if(m_upt.search_inval(r_xram_rsp_trt_buf.nline, index)) // pending inval 3335 3795 { 3336 3796 r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT; 3337 3797 3338 3798 #if DEBUG_MEMC_XRAM_RSP 3339 if(m_debug_xram_rsp_fsm) 3340 { 3341 std::cout << " <MEMC " << name() << ".XRAM_RSP_INVAL_LOCK> Get acces to UPT," 3342 << " but an invalidation is already registered at this address" << std::endl; 3343 m_upt.print(); 3344 } 3345 #endif 3346 3347 } 3348 else if(m_upt.is_full() && r_xram_rsp_victim_inval.read()) 3799 if(m_debug) 3800 std::cout << " <MEMC " << name() << " XRAM_RSP_INVAL_LOCK>" 3801 << " Get acces to UPT, but line invalidation registered" 3802 << " / nline = " << std::hex << r_xram_rsp_trt_buf.nline 3803 << " / index = " << std::dec << index << std::endl; 3804 #endif 3805 3806 } 3807 else if(m_upt.is_full() and r_xram_rsp_victim_inval.read()) // UPT full 3349 3808 { 3350 3809 r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT; 3351 3810 3352 3811 #if DEBUG_MEMC_XRAM_RSP 3353 if(m_debug_xram_rsp_fsm) 3354 { 3355 std::cout << " <MEMC " << name() << ".XRAM_RSP_INVAL_LOCK> Get acces to UPT," 3356 << " but the table is full" << std::endl; 3357 m_upt.print(); 3358 } 3812 if(m_debug) 3813 std::cout << " <MEMC " << name() << " XRAM_RSP_INVAL_LOCK>" 3814 << " Get acces to UPT, but inval required and UPT full" << std::endl; 3359 3815 #endif 3360 3816 } … … 3364 3820 3365 3821 #if DEBUG_MEMC_XRAM_RSP 3366 if(m_debug_xram_rsp_fsm) 3367 { 3368 std::cout << " <MEMC " << name() << ".XRAM_RSP_INVAL_LOCK> Get acces to UPT" << std::endl; 3369 } 3822 if(m_debug) 3823 std::cout << " <MEMC " << name() << " XRAM_RSP_INVAL_LOCK>" 3824 << " Get acces to UPT" << std::endl; 3370 3825 #endif 3371 3826 } … … 3374 3829 } 3375 3830 ///////////////////////// 3376 case XRAM_RSP_INVAL_WAIT: // returns to DIR_LOCK to retry 3377 { 3831 case XRAM_RSP_INVAL_WAIT: // release all locks and returns to DIR_LOCK to retry 3832 { 3833 3834 #if DEBUG_MEMC_XRAM_RSP 3835 if(m_debug) 3836 std::cout << " <MEMC " << name() << " XRAM_RSP_INVAL_WAIT>" 3837 << " Release all locks and retry" << std::endl; 3838 #endif 3378 3839 r_xram_rsp_fsm = XRAM_RSP_DIR_LOCK; 3379 3840 break; … … 3381 3842 /////////////////////// 3382 3843 case XRAM_RSP_DIR_UPDT: // updates the cache (both data & directory) 3383 // and possibly set an inval request in UPT 3384 { 3385 // signals generation 3844 // and possibly set an inval request in UPT 3845 { 3386 3846 // check if this is an instruction read, this means pktid is either 3387 3847 // TYPE_READ_INS_UNC 0bX010 with TSAR encoding 3388 3848 // TYPE_READ_INS_MISS 0bX011 with TSAR encoding 3389 bool inst_read = (r_xram_rsp_trt_buf.pktid & 0x2) && r_xram_rsp_trt_buf.proc_read; 3849 bool inst_read = (r_xram_rsp_trt_buf.pktid & 0x2) and r_xram_rsp_trt_buf.proc_read; 3850 3390 3851 // check if this is a cached read, this means pktid is either 3391 3852 // TYPE_READ_DATA_MISS 0bX001 with TSAR encoding 3392 3853 // TYPE_READ_INS_MISS 0bX011 with TSAR encoding 3393 bool cached_read = (r_xram_rsp_trt_buf.pktid & 0x1) && r_xram_rsp_trt_buf.proc_read; 3394 3395 // update data 3854 bool cached_read = (r_xram_rsp_trt_buf.pktid & 0x1) and r_xram_rsp_trt_buf.proc_read; 3855 3856 bool dirty = false; 3857 3858 // update cache data 3396 3859 size_t set = r_xram_rsp_victim_set.read(); 3397 3860 size_t way = r_xram_rsp_victim_way.read(); … … 3400 3863 m_cache_data.write(way, set, word, r_xram_rsp_trt_buf.wdata[word]); 3401 3864 3865 dirty = dirty or (r_xram_rsp_trt_buf.wdata_be[word] != 0); 3866 3402 3867 if(m_monitor_ok) 3403 3868 { 3404 vci_addr_t address = r_xram_rsp_trt_buf.nline<<6 | word<<2; 3405 check_monitor("XRAM_RSP_DIR_UPDT", address, r_xram_rsp_trt_buf.wdata[word]); 3406 } 3407 } 3408 // compute dirty 3409 bool dirty = false; 3410 for(size_t i=0; i<m_words; i++) dirty = dirty || (r_xram_rsp_trt_buf.wdata_be[i] != 0); 3411 // update directory 3869 addr_t address = r_xram_rsp_trt_buf.nline<<6 | word<<2; 3870 check_monitor("XRAM_RSP_DIR_UPDT", address, r_xram_rsp_trt_buf.wdata[word], false); 3871 } 3872 } 3873 3874 // update cache directory 3412 3875 DirectoryEntry entry; 3413 3876 entry.valid = true; … … 3437 3900 m_cache_directory.write(set, way, entry); 3438 3901 3902 // request an invalidattion request in UPT for victim line 3439 3903 if(r_xram_rsp_victim_inval.read()) 3440 3904 { 3441 bool br dcast = r_xram_rsp_victim_is_cnt.read();3442 size_t index = 0;3443 size_t count_copies 3905 bool broadcast = r_xram_rsp_victim_is_cnt.read(); 3906 size_t index = 0; 3907 size_t count_copies = r_xram_rsp_victim_count.read(); 3444 3908 3445 3909 bool wok = m_upt.set(false, // it's an inval transaction 3446 brdcast, // set brdcast bit 3447 false, // it does not need a response 3448 0, // srcid 3449 0, // trdid 3450 0, // pktid 3451 r_xram_rsp_victim_nline.read(), 3452 count_copies, 3453 index); 3910 broadcast, // set broadcast bit 3911 false, // no response required 3912 false, // no acknowledge required 3913 0, // srcid 3914 0, // trdid 3915 0, // pktid 3916 r_xram_rsp_victim_nline.read(), 3917 count_copies, 3918 index); 3919 3454 3920 r_xram_rsp_upt_index = index; 3455 3921 3456 3922 if(!wok) 3457 3923 { 3458 std::cout << "VCI_MEM_CACHE ERROR " << name() << " XRAM_RSP_ HEAP_LAST state" << std::endl;3459 std::cout << "an update_tab entry was free but write isunsuccessful" << std::endl;3924 std::cout << "VCI_MEM_CACHE ERROR " << name() << " XRAM_RSP_DIR_UPDT" 3925 << " update_tab entry free but write unsuccessful" << std::endl; 3460 3926 exit(0); 3461 3927 } … … 3463 3929 3464 3930 #if DEBUG_MEMC_XRAM_RSP 3465 if(m_debug_xram_rsp_fsm) 3466 { 3467 std::cout << " <MEMC " << name() << ".XRAM_RSP_DIR_UPDT> Directory update: " 3468 << " way = " << std::dec << way 3469 << " / set = " << set 3470 << " / owner_id = " << entry.owner.srcid 3471 << " / owner_ins = " << entry.owner.inst 3472 << " / count = " << entry.count 3473 << " / is_cnt = " << entry.is_cnt << std::endl; 3474 if(r_xram_rsp_victim_inval.read()) 3475 std::cout << " Invalidation request for victim line " 3476 << std::hex << r_xram_rsp_victim_nline.read() 3477 << " / broadcast = " << r_xram_rsp_victim_is_cnt.read() << std::endl; 3478 } 3479 #endif 3480 3481 // If the victim is not dirty, we don't need another XRAM put transaction, 3482 // and we canwe erase the TRT entry 3931 if(m_debug) 3932 { 3933 std::cout << " <MEMC " << name() << " XRAM_RSP_DIR_UPDT>" 3934 << " Cache update: " 3935 << " way = " << std::dec << way 3936 << " / set = " << set 3937 << " / owner_id = " << std::hex << entry.owner.srcid 3938 << " / owner_ins = " << std::dec << entry.owner.inst 3939 << " / count = " << entry.count 3940 << " / is_cnt = " << entry.is_cnt << std::endl; 3941 if(r_xram_rsp_victim_inval.read()) 3942 std::cout << " Invalidation request for victim line " 3943 << std::hex << r_xram_rsp_victim_nline.read() 3944 << " / broadcast = " << r_xram_rsp_victim_is_cnt.read() << std::endl; 3945 } 3946 #endif 3947 3948 // If the victim is not dirty, we don't need another XRAM put transaction, 3949 // and we can erase the TRT entry 3483 3950 if(!r_xram_rsp_victim_dirty.read()) m_trt.erase(r_xram_rsp_trt_index.read()); 3484 3951 3485 3952 // Next state 3486 3953 if(r_xram_rsp_victim_dirty.read()) r_xram_rsp_fsm = XRAM_RSP_TRT_DIRTY; 3487 else if(r_xram_rsp_trt_buf.proc_read) 3488 else if(r_xram_rsp_victim_inval.read()) 3489 else 3954 else if(r_xram_rsp_trt_buf.proc_read) r_xram_rsp_fsm = XRAM_RSP_DIR_RSP; 3955 else if(r_xram_rsp_victim_inval.read()) r_xram_rsp_fsm = XRAM_RSP_INVAL; 3956 else r_xram_rsp_fsm = XRAM_RSP_IDLE; 3490 3957 break; 3491 3958 } 3492 3959 //////////////////////// 3493 case XRAM_RSP_TRT_DIRTY: // set the TRT entry ( writeto XRAM) if the victim is dirty3960 case XRAM_RSP_TRT_DIRTY: // set the TRT entry (PUT to XRAM) if the victim is dirty 3494 3961 { 3495 3962 if(r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP) … … 3508 3975 3509 3976 #if DEBUG_MEMC_XRAM_RSP 3510 if(m_debug_xram_rsp_fsm) 3511 { 3512 std::cout << " <MEMC " << name() << ".XRAM_RSP_TRT_DIRTY> Set TRT entry for the put transaction:" 3513 << " dirty victim line = " << r_xram_rsp_victim_nline.read() << std::endl; 3514 } 3515 #endif 3516 if(r_xram_rsp_trt_buf.proc_read) r_xram_rsp_fsm = XRAM_RSP_DIR_RSP; 3517 else if(r_xram_rsp_victim_inval.read()) r_xram_rsp_fsm = XRAM_RSP_INVAL; 3518 else r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY; 3977 if(m_debug) 3978 std::cout << " <MEMC " << name() << " XRAM_RSP_TRT_DIRTY>" 3979 << " Set TRT entry for the put transaction" 3980 << " / dirty victim line = " << r_xram_rsp_victim_nline.read() << std::endl; 3981 #endif 3982 if(r_xram_rsp_trt_buf.proc_read) r_xram_rsp_fsm = XRAM_RSP_DIR_RSP; 3983 else if(r_xram_rsp_victim_inval.read()) r_xram_rsp_fsm = XRAM_RSP_INVAL; 3984 else r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY; 3519 3985 } 3520 3986 break; … … 3528 3994 r_xram_rsp_to_tgt_rsp_trdid = r_xram_rsp_trt_buf.trdid; 3529 3995 r_xram_rsp_to_tgt_rsp_pktid = r_xram_rsp_trt_buf.pktid; 3530 for(size_t i=0; i < m_words; i++) r_xram_rsp_to_tgt_rsp_data[i] = r_xram_rsp_trt_buf.wdata[i]; 3996 for(size_t i=0; i < m_words; i++) 3997 { 3998 r_xram_rsp_to_tgt_rsp_data[i] = r_xram_rsp_trt_buf.wdata[i]; 3999 } 3531 4000 r_xram_rsp_to_tgt_rsp_word = r_xram_rsp_trt_buf.word_index; 3532 4001 r_xram_rsp_to_tgt_rsp_length = r_xram_rsp_trt_buf.read_length; … … 3535 4004 r_xram_rsp_to_tgt_rsp_req = true; 3536 4005 3537 if(r_xram_rsp_victim_inval) r_xram_rsp_fsm = XRAM_RSP_INVAL;4006 if(r_xram_rsp_victim_inval) r_xram_rsp_fsm = XRAM_RSP_INVAL; 3538 4007 else if(r_xram_rsp_victim_dirty) r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY; 3539 else r_xram_rsp_fsm = XRAM_RSP_IDLE; 3540 4008 else r_xram_rsp_fsm = XRAM_RSP_IDLE; 3541 4009 3542 4010 #if DEBUG_MEMC_XRAM_RSP 3543 if(m_debug_xram_rsp_fsm) 3544 { 3545 std::cout << " <MEMC " << name() << ".XRAM_RSP_DIR_RSP> Request the TGT_RSP FSM to return data:" 3546 << " rsrcid = " << std::dec << r_xram_rsp_trt_buf.srcid 3547 << " / address = " << std::hex << r_xram_rsp_trt_buf.nline*m_words*4 3548 << " / nwords = " << std::dec << r_xram_rsp_trt_buf.read_length << std::endl; 3549 } 4011 if(m_debug) 4012 std::cout << " <MEMC " << name() << " XRAM_RSP_DIR_RSP>" 4013 << " Request the TGT_RSP FSM to return data:" 4014 << " rsrcid = " << std::hex << r_xram_rsp_trt_buf.srcid 4015 << " / address = " << std::hex << r_xram_rsp_trt_buf.nline*m_words*4 4016 << " / nwords = " << std::dec << r_xram_rsp_trt_buf.read_length << std::endl; 3550 4017 #endif 3551 4018 } … … 3555 4022 case XRAM_RSP_INVAL: // send invalidate request to CC_SEND FSM 3556 4023 { 3557 if(!r_xram_rsp_to_cc_send_multi_req.read() &&4024 if(!r_xram_rsp_to_cc_send_multi_req.read() and 3558 4025 !r_xram_rsp_to_cc_send_brdcast_req.read()) 3559 4026 { 3560 4027 bool multi_req = !r_xram_rsp_victim_is_cnt.read(); 3561 bool last_multi_req = multi_req &&(r_xram_rsp_victim_count.read() == 1);3562 bool not_last_multi_req = multi_req &&(r_xram_rsp_victim_count.read() != 1);4028 bool last_multi_req = multi_req and (r_xram_rsp_victim_count.read() == 1); 4029 bool not_last_multi_req = multi_req and (r_xram_rsp_victim_count.read() != 1); 3563 4030 3564 4031 r_xram_rsp_to_cc_send_multi_req = last_multi_req; … … 3575 4042 3576 4043 if(r_xram_rsp_victim_dirty) r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY; 3577 else if(not_last_multi_req) 3578 else 4044 else if(not_last_multi_req) r_xram_rsp_fsm = XRAM_RSP_HEAP_REQ; 4045 else r_xram_rsp_fsm = XRAM_RSP_IDLE; 3579 4046 3580 4047 #if DEBUG_MEMC_XRAM_RSP 3581 if(m_debug_xram_rsp_fsm) 3582 { 3583 std::cout << " <MEMC " << name() << ".XRAM_RSP_INVAL> Send an inval request to CC_SEND FSM:" 3584 << " victim line = " << r_xram_rsp_victim_nline.read() << std::endl; 3585 } 4048 if(m_debug) 4049 std::cout << " <MEMC " << name() << " XRAM_RSP_INVAL>" 4050 << " Send an inval request to CC_SEND FSM" 4051 << " / victim line = " << r_xram_rsp_victim_nline.read() << std::endl; 3586 4052 #endif 3587 4053 } … … 3596 4062 r_xram_rsp_to_ixr_cmd_nline = r_xram_rsp_victim_nline.read(); 3597 4063 r_xram_rsp_to_ixr_cmd_trdid = r_xram_rsp_trt_index.read(); 3598 for(size_t i=0; i<m_words ; i++) r_xram_rsp_to_ixr_cmd_data[i] = r_xram_rsp_victim_data[i]; 4064 for(size_t i=0; i<m_words ; i++) 4065 { 4066 r_xram_rsp_to_ixr_cmd_data[i] = r_xram_rsp_victim_data[i]; 4067 } 3599 4068 m_cpt_write_dirty++; 3600 4069 3601 bool multi_req = !r_xram_rsp_victim_is_cnt.read() && r_xram_rsp_victim_inval.read(); 3602 bool not_last_multi_req = multi_req && (r_xram_rsp_victim_count.read() != 1); 4070 bool multi_req = !r_xram_rsp_victim_is_cnt.read() and r_xram_rsp_victim_inval.read(); 4071 bool not_last_multi_req = multi_req and (r_xram_rsp_victim_count.read() != 1); 4072 3603 4073 if(not_last_multi_req) r_xram_rsp_fsm = XRAM_RSP_HEAP_REQ; 3604 else 4074 else r_xram_rsp_fsm = XRAM_RSP_IDLE; 3605 4075 3606 4076 #if DEBUG_MEMC_XRAM_RSP 3607 if(m_debug_xram_rsp_fsm) 3608 { 3609 std::cout << " <MEMC " << name() << ".XRAM_RSP_WRITE_DIRTY> Send the put request to IXR_CMD FSM:" 3610 << " victim line = " << r_xram_rsp_victim_nline.read() << std::endl; 3611 } 3612 #endif 3613 } 3614 break; 3615 } 3616 4077 if(m_debug) 4078 std::cout << " <MEMC " << name() << " XRAM_RSP_WRITE_DIRTY>" 4079 << " Send the put request to IXR_CMD FSM" 4080 << " / victim line = " << r_xram_rsp_victim_nline.read() << std::endl; 4081 #endif 4082 } 4083 break; 4084 } 3617 4085 ///////////////////////// 3618 case XRAM_RSP_HEAP_REQ: 3619 // Get the lock to the HEAP directory 4086 case XRAM_RSP_HEAP_REQ: // Get the lock to the HEAP 3620 4087 { 3621 4088 if(r_alloc_heap_fsm.read() == ALLOC_HEAP_XRAM_RSP) … … 3625 4092 3626 4093 #if DEBUG_MEMC_XRAM_RSP 3627 if(m_debug_xram_rsp_fsm) 3628 { 3629 std::cout 3630 << " <MEMC " << name() << ".XRAM_RSP_HEAP_REQ> Requesting HEAP lock " 3631 << std::endl; 3632 } 3633 #endif 3634 break; 3635 } 3636 4094 if(m_debug) 4095 std::cout << " <MEMC " << name() << " XRAM_RSP_HEAP_REQ>" 4096 << " Requesting HEAP lock" << std::endl; 4097 #endif 4098 break; 4099 } 3637 4100 ///////////////////////// 3638 case XRAM_RSP_HEAP_ERASE: // erase the list of copies and sentinvalidations4101 case XRAM_RSP_HEAP_ERASE: // erase the copies and send invalidations 3639 4102 { 3640 4103 if(r_alloc_heap_fsm.read() == ALLOC_HEAP_XRAM_RSP) … … 3667 4130 3668 4131 #if DEBUG_MEMC_XRAM_RSP 3669 if(m_debug_xram_rsp_fsm) 3670 { 3671 std::cout << " <MEMC " << name() << ".XRAM_RSP_HEAP_ERASE> Erase the list of copies:" 3672 << " srcid = " << std::dec << entry.owner.srcid 3673 << " / inst = " << std::dec << entry.owner.inst << std::endl; 3674 } 4132 if(m_debug) 4133 std::cout << " <MEMC " << name() << " XRAM_RSP_HEAP_ERASE>" 4134 << " Erase copy:" 4135 << " srcid = " << std::hex << entry.owner.srcid 4136 << " / inst = " << std::dec << entry.owner.inst << std::endl; 3675 4137 #endif 3676 4138 } … … 3678 4140 } 3679 4141 ///////////////////////// 3680 case XRAM_RSP_HEAP_LAST: // last member of the list4142 case XRAM_RSP_HEAP_LAST: // last copy 3681 4143 { 3682 4144 if(r_alloc_heap_fsm.read() != ALLOC_HEAP_XRAM_RSP) 3683 4145 { 3684 std::cout << "VCI_MEM_CACHE ERROR " << name() << " XRAM_RSP_HEAP_LAST state" << std::endl;3685 std::cout << "bad HEAP allocation" << std::endl;4146 std::cout << "VCI_MEM_CACHE ERROR " << name() << " XRAM_RSP_HEAP_LAST" 4147 << " bad HEAP allocation" << std::endl; 3686 4148 exit(0); 3687 4149 } … … 3710 4172 3711 4173 #if DEBUG_MEMC_XRAM_RSP 3712 if(m_debug_xram_rsp_fsm) 3713 { 3714 std::cout << " <MEMC " << name() << ".XRAM_RSP_HEAP_LAST> Heap housekeeping" << std::endl; 3715 } 4174 if(m_debug) 4175 std::cout << " <MEMC " << name() << " XRAM_RSP_HEAP_LAST>" 4176 << " Heap housekeeping" << std::endl; 3716 4177 #endif 3717 4178 break; … … 3724 4185 // Next state 3725 4186 if(r_xram_rsp_trt_buf.proc_read) r_xram_rsp_fsm = XRAM_RSP_ERROR_RSP; 3726 else 4187 else r_xram_rsp_fsm = XRAM_RSP_IDLE; 3727 4188 3728 4189 #if DEBUG_MEMC_XRAM_RSP 3729 if(m_debug_xram_rsp_fsm) 3730 { 3731 std::cout << " <MEMC " << name() << ".XRAM_RSP_ERROR_ERASE> Error reported by XRAM / erase the TRT entry" << std::endl; 3732 } 4190 if(m_debug) 4191 std::cout << " <MEMC " << name() << " XRAM_RSP_ERROR_ERASE>" 4192 << " Error reported by XRAM / erase the TRT entry" << std::endl; 3733 4193 #endif 3734 4194 break; … … 3742 4202 r_xram_rsp_to_tgt_rsp_trdid = r_xram_rsp_trt_buf.trdid; 3743 4203 r_xram_rsp_to_tgt_rsp_pktid = r_xram_rsp_trt_buf.pktid; 3744 for(size_t i=0; i < m_words; i++) r_xram_rsp_to_tgt_rsp_data[i] = r_xram_rsp_trt_buf.wdata[i]; 4204 for(size_t i=0; i < m_words; i++) 4205 { 4206 r_xram_rsp_to_tgt_rsp_data[i] = r_xram_rsp_trt_buf.wdata[i]; 4207 } 3745 4208 r_xram_rsp_to_tgt_rsp_word = r_xram_rsp_trt_buf.word_index; 3746 4209 r_xram_rsp_to_tgt_rsp_length = r_xram_rsp_trt_buf.read_length; … … 3751 4214 3752 4215 #if DEBUG_MEMC_XRAM_RSP 3753 if(m_debug_xram_rsp_fsm) 3754 { 3755 std::cout << " <MEMC " << name() << ".XRAM_RSP_ERROR_RSP> Request a response error to TGT_RSP FSM:" 3756 << " srcid = " << std::dec << r_xram_rsp_trt_buf.srcid << std::endl; 3757 } 4216 if(m_debug) 4217 std::cout << " <MEMC " << name() 4218 << " XRAM_RSP_ERROR_RSP> Request a response error to TGT_RSP FSM:" 4219 << " srcid = " << std::dec << r_xram_rsp_trt_buf.srcid << std::endl; 3758 4220 #endif 3759 4221 } … … 3771 4233 switch(r_cleanup_fsm.read()) 3772 4234 { 3773 case CLEANUP_IDLE:3774 {3775 // Get first DSPIN flit of the CLEANUP command4235 ////////////////// 4236 case CLEANUP_IDLE: // Get first DSPIN flit of the CLEANUP command 4237 { 3776 4238 if(not m_cc_receive_to_cleanup_fifo.rok()) break; 3777 4239 … … 3796 4258 DspinDhccpParam::dspin_get( 3797 4259 flit, 3798 DspinDhccpParam::CLEANUP_NLINE_MSB) 3799 << 32; 4260 DspinDhccpParam::CLEANUP_NLINE_MSB) << 32; 3800 4261 3801 4262 r_cleanup_inst = (type == DspinDhccpParam::TYPE_CLEANUP_INST); … … 3814 4275 m_cpt_cleanup++; 3815 4276 cc_receive_to_cleanup_fifo_get = true; 3816 r_cleanup_fsm = CLEANUP_GET_NLINE;4277 r_cleanup_fsm = CLEANUP_GET_NLINE; 3817 4278 3818 4279 #if DEBUG_MEMC_CLEANUP 3819 if(m_debug_cleanup_fsm) 3820 { 3821 std::cout 3822 << " <MEMC " << name() 3823 << ".CLEANUP_IDLE> Cleanup request:" << std::hex 3824 << " / owner_id = " << srcid 3825 << " / owner_ins = " << (type == DspinDhccpParam::TYPE_CLEANUP_INST) 3826 << std::endl; 3827 } 3828 #endif 3829 break; 3830 } 3831 3832 case CLEANUP_GET_NLINE: 3833 { 3834 // Get second flit of cleanup command 4280 if(m_debug) 4281 std::cout << " <MEMC " << name() 4282 << " CLEANUP_IDLE> Cleanup request:" << std::hex 4283 << " / owner_id = " << srcid 4284 << " / owner_ins = " << (type == DspinDhccpParam::TYPE_CLEANUP_INST) << std::endl; 4285 #endif 4286 break; 4287 <