- Timestamp:
- Nov 28, 2012, 11:51:48 AM (12 years ago)
- Location:
- trunk/modules/vci_mem_cache_v4/caba
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/modules/vci_mem_cache_v4/caba/metadata/vci_mem_cache_v4.sd
r20 r273 6 6 7 7 Module('caba:vci_mem_cache_v4', 8 classname = 'soclib::caba::VciMemCacheV4', 9 tmpl_parameters = [parameter.Module('vci_param', default = 'caba:vci_param'),], 10 header_files = ['../source/include/vci_mem_cache_v4.h', 11 '../source/include/xram_transaction_v4.h', 12 '../source/include/mem_cache_directory_v4.h', 13 '../source/include/update_tab_v4.h',], 14 implementation_files = ['../source/src/vci_mem_cache_v4.cpp',], 15 uses = [Uses('caba:base_module'), 16 Uses('common:loader'), 17 Uses('common:mapping_table'), 18 Uses('caba:generic_fifo'), 19 ], 20 ports = [Port('caba:vci_target', 'p_vci_tgt'), 21 Port('caba:vci_target','p_vci_tgt_cleanup'), 22 Port('caba:vci_initiator','p_vci_ini'), 23 Port('caba:vci_initiator','p_vci_ixr'), 24 Port('caba:bit_in', 'p_resetn', auto = 'resetn'), 25 Port('caba:clock_in', 'p_clk', auto = 'clock'),], 26 instance_parameters = [ 27 parameter.Module('mtp', 'common:mapping_table'), 28 parameter.Module('mtc', 'common:mapping_table'), 29 parameter.Module('mtx', 'common:mapping_table'), 30 parameter.IntTab('vci_ixr_index'), 31 parameter.IntTab('vci_ini_index'), 32 parameter.IntTab('vci_tgt_index'), 33 parameter.IntTab('vci_tgt_index_cleanup'), 34 parameter.Int('nways'), 35 parameter.Int('nsets'), 36 parameter.Int('nwords'), 37 parameter.Int('heap_size'), 38 ], 39 extensions = [ 40 'dsx:get_ident=' 41 'vci_ini_index:p_vci_ini:mtc,' 42 'vci_tgt_index_cleanup:p_vci_tgt_cleanup:mtc,' 43 'vci_tgt_index:p_vci_tgt:mtp,' 44 'vci_ixr_index:p_vci_ixr:mtx', 45 'dsx:addressable=vci_tgt_index,vci_tgt_index_cleanup', 46 ], 8 classname = 'soclib::caba::VciMemCacheV4', 9 10 tmpl_parameters = [ parameter.Module('vci_param', default = 'caba:vci_param') ], 11 12 header_files = [ 13 '../source/include/vci_mem_cache_v4.h', 14 '../source/include/xram_transaction_v4.h', 15 '../source/include/mem_cache_directory_v4.h', 16 '../source/include/update_tab_v4.h' 17 ], 18 19 implementation_files = [ '../source/src/vci_mem_cache_v4.cpp' ], 20 21 uses = [ 22 Uses('caba:base_module'), 23 Uses('common:loader'), 24 Uses('common:mapping_table'), 25 Uses('caba:generic_fifo'), 26 ], 27 28 ports = [ 29 Port( 'caba:vci_target' , 'p_vci_tgt' ), 30 Port( 'caba:vci_target' , 'p_vci_tgt_cleanup' ), 31 Port( 'caba:vci_initiator', 'p_vci_ini' ), 32 Port( 'caba:vci_initiator', 'p_vci_ixr' ), 33 Port( 'caba:bit_in' , 'p_resetn' , auto = 'resetn' ), 34 Port( 'caba:clock_in' , 'p_clk' , auto = 'clock' ), 35 ], 36 37 instance_parameters = [ 38 parameter.Module( 'mtp', 'common:mapping_table' ), 39 parameter.Module( 'mtc', 'common:mapping_table' ), 40 parameter.Module( 'mtx', 'common:mapping_table' ), 41 parameter.IntTab( 'vci_ixr_index' ), 42 parameter.IntTab( 'vci_ini_index' ), 43 parameter.IntTab( 'vci_tgt_index' ), 44 parameter.IntTab( 'vci_tgt_index_cleanup '), 45 parameter.Int ( 'nways' ), 46 parameter.Int ( 'nsets' ), 47 parameter.Int ( 'nwords' ), 48 parameter.Int ( 'heap_size' ), 49 ], 50 51 extensions = [ 52 'dsx:get_ident=' 53 'vci_ini_index:p_vci_ini:mtc,' 54 'vci_tgt_index_cleanup:p_vci_tgt_cleanup:mtc,' 55 'vci_tgt_index:p_vci_tgt:mtp,' 56 'vci_ixr_index:p_vci_ixr:mtx', 57 'dsx:addressable=vci_tgt_index,vci_tgt_index_cleanup', 58 ], 47 59 ) -
trunk/modules/vci_mem_cache_v4/caba/source/include/vci_mem_cache_v4.h
r245 r273 26 26 * 27 27 * Maintainers: alain eric.guthmuller@polytechnique.edu 28 */ 29 /* 28 * cesar.fuguet-tortolero@lip6.fr 30 29 * 31 30 * Modifications done by Christophe Choichillon on the 7/04/2009: … … 33 32 * - Adding a new VCI target port for the CLEANUP network 34 33 * - Adding new state in the ALLOC_UPT_FSM : ALLOC_UPT_CLEANUP 35 * 34 * 36 35 * Modifications to do : 37 36 * - Adding new variables used by the CLEANUP FSM … … 58 57 #include "update_tab_v4.h" 59 58 60 #define TRANSACTION_TAB_LINES 4// Number of lines in the transaction tab61 #define UPDATE_TAB_LINES 4// Number of lines in the update tab59 #define TRANSACTION_TAB_LINES 4 // Number of lines in the transaction tab 60 #define UPDATE_TAB_LINES 4 // Number of lines in the update tab 62 61 63 62 namespace soclib { namespace caba { … … 81 80 TGT_CMD_READ, 82 81 TGT_CMD_WRITE, 83 TGT_CMD_ATOMIC ,82 TGT_CMD_ATOMIC 84 83 }; 85 84 … … 97 96 TGT_RSP_XRAM, 98 97 TGT_RSP_INIT, 99 TGT_RSP_CLEANUP ,98 TGT_RSP_CLEANUP 100 99 }; 101 100 … … 115 114 INIT_CMD_SC_UPDT_INDEX, 116 115 INIT_CMD_SC_UPDT_DATA, 117 INIT_CMD_SC_UPDT_DATA_HIGH ,116 INIT_CMD_SC_UPDT_DATA_HIGH 118 117 }; 119 118 … … 123 122 INIT_RSP_UPT_LOCK, 124 123 INIT_RSP_UPT_CLEAR, 125 INIT_RSP_END ,124 INIT_RSP_END 126 125 }; 127 126 … … 129 128 enum read_fsm_state_e{ 130 129 READ_IDLE, 130 READ_DIR_REQ, 131 131 READ_DIR_LOCK, 132 132 READ_DIR_HIT, 133 READ_HEAP_REQ, 133 134 READ_HEAP_LOCK, 134 135 READ_HEAP_WRITE, … … 138 139 READ_TRT_LOCK, 139 140 READ_TRT_SET, 140 READ_TRT_REQ ,141 READ_TRT_REQ 141 142 }; 142 143 … … 145 146 WRITE_IDLE, 146 147 WRITE_NEXT, 148 WRITE_DIR_REQ, 147 149 WRITE_DIR_LOCK, 148 150 WRITE_DIR_READ, … … 163 165 WRITE_BC_CC_SEND, 164 166 WRITE_BC_XRAM_REQ, 165 WRITE_WAIT ,167 WRITE_WAIT 166 168 }; 167 169 … … 171 173 IXR_RSP_ACK, 172 174 IXR_RSP_TRT_ERASE, 173 IXR_RSP_TRT_READ ,175 IXR_RSP_TRT_READ 174 176 }; 175 177 … … 186 188 XRAM_RSP_INVAL, 187 189 XRAM_RSP_WRITE_DIRTY, 190 XRAM_RSP_HEAP_REQ, 188 191 XRAM_RSP_HEAP_ERASE, 189 192 XRAM_RSP_HEAP_LAST, 190 193 XRAM_RSP_ERROR_ERASE, 191 XRAM_RSP_ERROR_RSP ,194 XRAM_RSP_ERROR_RSP 192 195 }; 193 196 … … 201 204 IXR_CMD_WRITE_NLINE, 202 205 IXR_CMD_SC_NLINE, 203 IXR_CMD_XRAM_DATA ,206 IXR_CMD_XRAM_DATA 204 207 }; 205 208 … … 207 210 enum sc_fsm_state_e{ 208 211 SC_IDLE, 212 SC_DIR_REQ, 209 213 SC_DIR_LOCK, 210 214 SC_DIR_HIT_READ, … … 224 228 SC_MISS_TRT_SET, 225 229 SC_MISS_XRAM_REQ, 226 SC_WAIT ,230 SC_WAIT 227 231 }; 228 232 … … 230 234 enum cleanup_fsm_state_e{ 231 235 CLEANUP_IDLE, 236 CLEANUP_DIR_REQ, 232 237 CLEANUP_DIR_LOCK, 233 238 CLEANUP_DIR_WRITE, 239 CLEANUP_HEAP_REQ, 234 240 CLEANUP_HEAP_LOCK, 235 241 CLEANUP_HEAP_SEARCH, … … 239 245 CLEANUP_UPT_WRITE, 240 246 CLEANUP_WRITE_RSP, 241 CLEANUP_RSP ,247 CLEANUP_RSP 242 248 }; 243 249 244 250 /* States of the ALLOC_DIR fsm */ 245 251 enum alloc_dir_fsm_state_e{ 252 ALLOC_DIR_RESET, 246 253 ALLOC_DIR_READ, 247 254 ALLOC_DIR_WRITE, 248 255 ALLOC_DIR_SC, 249 256 ALLOC_DIR_CLEANUP, 250 ALLOC_DIR_XRAM_RSP ,257 ALLOC_DIR_XRAM_RSP 251 258 }; 252 259 … … 257 264 ALLOC_TRT_SC, 258 265 ALLOC_TRT_XRAM_RSP, 259 ALLOC_TRT_IXR_RSP ,266 ALLOC_TRT_IXR_RSP 260 267 }; 261 268 … … 266 273 ALLOC_UPT_INIT_RSP, 267 274 ALLOC_UPT_CLEANUP, 268 ALLOC_UPT_SC ,275 ALLOC_UPT_SC 269 276 }; 270 277 271 278 /* States of the ALLOC_HEAP fsm */ 272 279 enum alloc_heap_fsm_state_e{ 280 ALLOC_HEAP_RESET, 273 281 ALLOC_HEAP_READ, 274 282 ALLOC_HEAP_WRITE, 275 283 ALLOC_HEAP_SC, 276 284 ALLOC_HEAP_CLEANUP, 277 ALLOC_HEAP_XRAM_RSP ,285 ALLOC_HEAP_XRAM_RSP 278 286 }; 279 287 … … 301 309 302 310 // instrumentation counters 303 uint32_t m_cpt_cycles; // Counter of cycles304 uint32_t m_cpt_read;// Number of READ transactions305 uint32_t m_cpt_read_miss; // Number of MISS READ306 uint32_t m_cpt_write;// Number of WRITE transactions307 uint32_t m_cpt_write_miss;// Number of MISS WRITE308 uint32_t m_cpt_write_cells; 309 uint32_t m_cpt_write_dirty; 310 uint32_t m_cpt_update;// Number of UPDATE transactions311 uint32_t m_cpt_trt_rb; 312 uint32_t m_cpt_trt_full; 313 uint32_t m_cpt_update_mult;// Number of targets for UPDATE314 uint32_t m_cpt_inval;// Number of INVAL transactions315 uint32_t m_cpt_inval_mult; // Number of targets for INVAL316 uint32_t m_cpt_inval_brdcast; // Number of BROADCAST INVAL317 uint32_t m_cpt_cleanup;// Number of CLEANUP transactions318 uint32_t m_cpt_ll;// Number of LL transactions319 uint32_t m_cpt_sc;// Number of SC transactions311 uint32_t m_cpt_cycles; // Counter of cycles 312 uint32_t m_cpt_read; // Number of READ transactions 313 uint32_t m_cpt_read_miss; // Number of MISS READ 314 uint32_t m_cpt_write; // Number of WRITE transactions 315 uint32_t m_cpt_write_miss; // Number of MISS WRITE 316 uint32_t m_cpt_write_cells; // Cumulated length for WRITE transactions 317 uint32_t m_cpt_write_dirty; // Cumulated length for WRITE transactions 318 uint32_t m_cpt_update; // Number of UPDATE transactions 319 uint32_t m_cpt_trt_rb; // Read blocked by a hit in trt 320 uint32_t m_cpt_trt_full; // Transaction blocked due to a full trt 321 uint32_t m_cpt_update_mult; // Number of targets for UPDATE 322 uint32_t m_cpt_inval; // Number of INVAL transactions 323 uint32_t m_cpt_inval_mult; // Number of targets for INVAL 324 uint32_t m_cpt_inval_brdcast; // Number of BROADCAST INVAL 325 uint32_t m_cpt_cleanup; // Number of CLEANUP transactions 326 uint32_t m_cpt_ll; // Number of LL transactions 327 uint32_t m_cpt_sc; // Number of SC transactions 320 328 321 329 size_t m_prev_count; … … 326 334 327 335 public: 328 sc_in<bool> 329 sc_in<bool> 330 soclib::caba::VciTarget<vci_param> 331 soclib::caba::VciTarget<vci_param> 332 soclib::caba::VciInitiator<vci_param> p_vci_ini;333 soclib::caba::VciInitiator<vci_param> 336 sc_in<bool> p_clk; 337 sc_in<bool> p_resetn; 338 soclib::caba::VciTarget<vci_param> p_vci_tgt; 339 soclib::caba::VciTarget<vci_param> p_vci_tgt_cleanup; 340 soclib::caba::VciInitiator<vci_param> p_vci_ini; 341 soclib::caba::VciInitiator<vci_param> p_vci_ixr; 334 342 335 343 VciMemCacheV4( 336 sc_module_name name, // Instance Name 344 sc_module_name name, // Instance Name 337 345 const soclib::common::MappingTable &mtp, // Mapping table for primary requets 338 346 const soclib::common::MappingTable &mtc, // Mapping table for coherence requets … … 342 350 const soclib::common::IntTab &vci_tgt_index, // VCI port to PROC (target) 343 351 const soclib::common::IntTab &vci_tgt_index_cleanup,// VCI port to PROC (target) for cleanup 344 size_t nways, // Number of ways per set 352 size_t nways, // Number of ways per set 345 353 size_t nsets, // Number of sets 346 354 size_t nwords, // Number of words per line … … 348 356 size_t transaction_tab_lines=TRANSACTION_TAB_LINES, // Size of the TRT 349 357 size_t update_tab_lines=UPDATE_TAB_LINES, // Size of the UPT 350 size_t debug_start_cycle=0, 358 size_t debug_start_cycle=0, 351 359 bool debug_ok=false); 352 360 … … 366 374 367 375 // Component attributes 368 const size_t m_initiators; // Number of initiators 369 const size_t m_heap_size; // Size of the heap 370 const size_t m_ways; // Number of ways in a set 371 const size_t m_sets; // Number of cache sets 372 const size_t m_words; // Number of words in a line 373 const size_t m_srcid_ixr; // Srcid for requests to XRAM 374 const size_t m_srcid_ini; // Srcid for requests to processors 375 std::list<soclib::common::Segment> m_seglist; // memory cached into the cache 376 std::list<soclib::common::Segment> m_cseglist; // coherence segment for the cache 377 vci_addr_t *m_coherence_table; // address(srcid) 378 uint32_t m_transaction_tab_lines; 379 TransactionTab m_transaction_tab; // xram transaction table 380 uint32_t m_update_tab_lines; 381 UpdateTab m_update_tab; // pending update & invalidate 382 CacheDirectory m_cache_directory; // data cache directory 383 HeapDirectory m_heap; // heap for copies 384 385 data_t ***m_cache_data; // data array[set][way][word] 376 std::list<soclib::common::Segment> m_seglist; // memory cached into the cache 377 std::list<soclib::common::Segment> m_cseglist; // coherence segment for the cache 378 379 const size_t m_initiators; // Number of initiators 380 const size_t m_heap_size; // Size of the heap 381 const size_t m_ways; // Number of ways in a set 382 const size_t m_sets; // Number of cache sets 383 const size_t m_words; // Number of words in a line 384 const size_t m_srcid_ixr; // Srcid for requests to XRAM 385 const size_t m_srcid_ini; // Srcid for requests to processors 386 387 uint32_t m_transaction_tab_lines; 388 TransactionTab m_transaction_tab; // xram transaction table 389 uint32_t m_update_tab_lines; 390 UpdateTab m_update_tab; // pending update & invalidate 391 CacheDirectory m_cache_directory; // data cache directory 392 HeapDirectory m_heap; // heap for copies 393 394 data_t *** m_cache_data; // data array[set][way][word] 386 395 387 396 // adress masks 388 const soclib::common::AddressMaskingTable<vci_addr_t> 389 const soclib::common::AddressMaskingTable<vci_addr_t> 390 const soclib::common::AddressMaskingTable<vci_addr_t> 391 const soclib::common::AddressMaskingTable<vci_addr_t> m_nline;397 const soclib::common::AddressMaskingTable<vci_addr_t> m_x; 398 const soclib::common::AddressMaskingTable<vci_addr_t> m_y; 399 const soclib::common::AddressMaskingTable<vci_addr_t> m_z; 400 const soclib::common::AddressMaskingTable<vci_addr_t> m_nline; 392 401 393 402 // broadcast address 394 vci_addr_t 403 vci_addr_t m_broadcast_address; 395 404 396 405 ////////////////////////////////////////////////// 397 406 // Others registers 398 407 ////////////////////////////////////////////////// 399 sc_signal<size_t> 400 sc_signal<size_t> 408 sc_signal<size_t> r_copies_limit; // Limit of the number of copies for one line 409 sc_signal<size_t> xxx_count; 401 410 402 411 ////////////////////////////////////////////////// … … 411 420 GenericFifo<size_t> m_cmd_read_pktid_fifo; 412 421 413 // Fifo between TGT_CMD fsm and WRITE fsm 422 // Fifo between TGT_CMD fsm and WRITE fsm 414 423 GenericFifo<uint64_t> m_cmd_write_addr_fifo; 415 424 GenericFifo<bool> m_cmd_write_eop_fifo; … … 418 427 GenericFifo<size_t> m_cmd_write_pktid_fifo; 419 428 GenericFifo<data_t> m_cmd_write_data_fifo; 420 GenericFifo<be_t> 429 GenericFifo<be_t> m_cmd_write_be_fifo; 421 430 422 431 // Fifo between TGT_CMD fsm and SC fsm … … 434 443 soclib::common::Segment **m_seg; 435 444 soclib::common::Segment **m_cseg; 436 437 445 /////////////////////////////////////////////////////// 438 446 // Registers controlled by the READ fsm 439 447 /////////////////////////////////////////////////////// 440 448 441 sc_signal<int> r_read_fsm; // FSM state442 sc_signal<size_t> 443 sc_signal<size_t> 444 sc_signal<bool> 445 sc_signal<tag_t> r_read_tag;// cache line tag (in directory)446 sc_signal<bool> r_read_is_cnt;// is_cnt bit (in directory)447 sc_signal<bool> r_read_lock;// lock bit (in directory)448 sc_signal<bool> r_read_dirty;// dirty bit (in directory)449 sc_signal<size_t> 450 sc_signal<size_t> 451 sc_signal<data_t> *r_read_data; // data (one cache line)452 sc_signal<size_t> 453 sc_signal<size_t> 454 sc_signal<size_t> 455 sc_signal<bool> 456 457 // Buffer between READ fsm and IXR_CMD fsm (ask a missing cache line to XRAM) 458 sc_signal<bool> r_read_to_ixr_cmd_req;// valid request459 sc_signal<addr_t> r_read_to_ixr_cmd_nline;// cache line index460 sc_signal<size_t> r_read_to_ixr_cmd_trdid;// index in Transaction Table449 sc_signal<int> r_read_fsm; // FSM state 450 sc_signal<size_t> r_read_copy; // Srcid of the first copy 451 sc_signal<size_t> r_read_copy_cache; // Srcid of the first copy 452 sc_signal<bool> r_read_copy_inst; // Type of the first copy 453 sc_signal<tag_t> r_read_tag; // cache line tag (in directory) 454 sc_signal<bool> r_read_is_cnt; // is_cnt bit (in directory) 455 sc_signal<bool> r_read_lock; // lock bit (in directory) 456 sc_signal<bool> r_read_dirty; // dirty bit (in directory) 457 sc_signal<size_t> r_read_count; // number of copies 458 sc_signal<size_t> r_read_ptr; // pointer to the heap 459 sc_signal<data_t> * r_read_data; // data (one cache line) 460 sc_signal<size_t> r_read_way; // associative way (in cache) 461 sc_signal<size_t> r_read_trt_index; // Transaction Table index 462 sc_signal<size_t> r_read_next_ptr; // Next entry to point to 463 sc_signal<bool> r_read_last_free; // Last free entry 464 465 // Buffer between READ fsm and IXR_CMD fsm (ask a missing cache line to XRAM) 466 sc_signal<bool> r_read_to_ixr_cmd_req; // valid request 467 sc_signal<addr_t> r_read_to_ixr_cmd_nline; // cache line index 468 sc_signal<size_t> r_read_to_ixr_cmd_trdid; // index in Transaction Table 461 469 462 470 // Buffer between READ fsm and TGT_RSP fsm (send a hit read response to L1 cache) 463 sc_signal<bool> r_read_to_tgt_rsp_req;// valid request464 sc_signal<size_t> r_read_to_tgt_rsp_srcid;// Transaction srcid465 sc_signal<size_t> r_read_to_tgt_rsp_trdid;// Transaction trdid466 sc_signal<size_t> r_read_to_tgt_rsp_pktid;// Transaction pktid467 sc_signal<data_t> *r_read_to_tgt_rsp_data;// data (one cache line)468 sc_signal<size_t> r_read_to_tgt_rsp_word;// first word of the response469 sc_signal<size_t> r_read_to_tgt_rsp_length;// length of the response471 sc_signal<bool> r_read_to_tgt_rsp_req; // valid request 472 sc_signal<size_t> r_read_to_tgt_rsp_srcid; // Transaction srcid 473 sc_signal<size_t> r_read_to_tgt_rsp_trdid; // Transaction trdid 474 sc_signal<size_t> r_read_to_tgt_rsp_pktid; // Transaction pktid 475 sc_signal<data_t> * r_read_to_tgt_rsp_data; // data (one cache line) 476 sc_signal<size_t> r_read_to_tgt_rsp_word; // first word of the response 477 sc_signal<size_t> r_read_to_tgt_rsp_length; // length of the response 470 478 471 479 /////////////////////////////////////////////////////////////// … … 473 481 /////////////////////////////////////////////////////////////// 474 482 475 sc_signal<int> r_write_fsm;// FSM state476 sc_signal<addr_t> r_write_address;// first word address477 sc_signal<size_t> r_write_word_index;// first word index in line478 sc_signal<size_t> r_write_word_count;// number of words in line479 sc_signal<size_t> r_write_srcid;// transaction srcid480 sc_signal<size_t> r_write_trdid;// transaction trdid481 sc_signal<size_t> r_write_pktid;// transaction pktid482 sc_signal<data_t> *r_write_data; // data (one cache line)483 sc_signal<be_t> *r_write_be;// one byte enable per word484 sc_signal<bool> r_write_byte;// (BE != 0X0) and (BE != 0xF)485 sc_signal<bool> r_write_is_cnt;// is_cnt bit (in directory)486 sc_signal<bool> r_write_lock;// lock bit (in directory)487 sc_signal<tag_t> r_write_tag;// cache line tag (in directory)488 sc_signal<size_t> r_write_copy;// first owner of the line489 sc_signal<size_t> r_write_copy_cache;// first owner of the line490 sc_signal<bool> r_write_copy_inst;// is this owner a ICache ?491 sc_signal<size_t> r_write_count;// number of copies492 sc_signal<size_t> r_write_ptr;// pointer to the heap493 sc_signal<size_t> r_write_next_ptr;// next pointer to the heap494 sc_signal<bool> r_write_to_dec;// need to decrement update counter495 sc_signal<size_t> r_write_way;// way of the line496 sc_signal<size_t> r_write_trt_index;// index in Transaction Table497 sc_signal<size_t> r_write_upt_index;// index in Update Table483 sc_signal<int> r_write_fsm; // FSM state 484 sc_signal<addr_t> r_write_address; // first word address 485 sc_signal<size_t> r_write_word_index; // first word index in line 486 sc_signal<size_t> r_write_word_count; // number of words in line 487 sc_signal<size_t> r_write_srcid; // transaction srcid 488 sc_signal<size_t> r_write_trdid; // transaction trdid 489 sc_signal<size_t> r_write_pktid; // transaction pktid 490 sc_signal<data_t> * r_write_data; // data (one cache line) 491 sc_signal<be_t> * r_write_be; // one byte enable per word 492 sc_signal<bool> r_write_byte; // (BE != 0X0) and (BE != 0xF) 493 sc_signal<bool> r_write_is_cnt; // is_cnt bit (in directory) 494 sc_signal<bool> r_write_lock; // lock bit (in directory) 495 sc_signal<tag_t> r_write_tag; // cache line tag (in directory) 496 sc_signal<size_t> r_write_copy; // first owner of the line 497 sc_signal<size_t> r_write_copy_cache; // first owner of the line 498 sc_signal<bool> r_write_copy_inst; // is this owner a ICache ? 499 sc_signal<size_t> r_write_count; // number of copies 500 sc_signal<size_t> r_write_ptr; // pointer to the heap 501 sc_signal<size_t> r_write_next_ptr; // next pointer to the heap 502 sc_signal<bool> r_write_to_dec; // need to decrement update counter 503 sc_signal<size_t> r_write_way; // way of the line 504 sc_signal<size_t> r_write_trt_index; // index in Transaction Table 505 sc_signal<size_t> r_write_upt_index; // index in Update Table 498 506 499 507 // Buffer between WRITE fsm and TGT_RSP fsm (acknowledge a write command from L1) 500 sc_signal<bool> r_write_to_tgt_rsp_req;// valid request501 sc_signal<size_t> r_write_to_tgt_rsp_srcid;// transaction srcid502 sc_signal<size_t> r_write_to_tgt_rsp_trdid;// transaction trdid503 sc_signal<size_t> r_write_to_tgt_rsp_pktid;// transaction pktid504 505 // Buffer between WRITE fsm and IXR_CMD fsm (ask a missing cache line to XRAM) 506 sc_signal<bool> r_write_to_ixr_cmd_req;// valid request507 sc_signal<bool> r_write_to_ixr_cmd_write;// write request508 sc_signal<addr_t> r_write_to_ixr_cmd_nline;// cache line index509 sc_signal<data_t> *r_write_to_ixr_cmd_data;// cache line data510 sc_signal<size_t> r_write_to_ixr_cmd_trdid;// index in Transaction Table508 sc_signal<bool> r_write_to_tgt_rsp_req; // valid request 509 sc_signal<size_t> r_write_to_tgt_rsp_srcid; // transaction srcid 510 sc_signal<size_t> r_write_to_tgt_rsp_trdid; // transaction trdid 511 sc_signal<size_t> r_write_to_tgt_rsp_pktid; // transaction pktid 512 513 // Buffer between WRITE fsm and IXR_CMD fsm (ask a missing cache line to XRAM) 514 sc_signal<bool> r_write_to_ixr_cmd_req; // valid request 515 sc_signal<bool> r_write_to_ixr_cmd_write; // write request 516 sc_signal<addr_t> r_write_to_ixr_cmd_nline; // cache line index 517 sc_signal<data_t> * r_write_to_ixr_cmd_data; // cache line data 518 sc_signal<size_t> r_write_to_ixr_cmd_trdid; // index in Transaction Table 511 519 512 520 // Buffer between WRITE fsm and INIT_CMD fsm (Update/Invalidate L1 caches) 513 sc_signal<bool> r_write_to_init_cmd_multi_req;// valid multicast request514 sc_signal<bool> r_write_to_init_cmd_brdcast_req;// valid brdcast request515 sc_signal<addr_t> r_write_to_init_cmd_nline;// cache line index516 sc_signal<size_t> r_write_to_init_cmd_trdid;// index in Update Table517 sc_signal<data_t> *r_write_to_init_cmd_data;// data (one cache line)518 sc_signal<be_t> *r_write_to_init_cmd_be;// word enable519 sc_signal<size_t> r_write_to_init_cmd_count;// number of words in line520 sc_signal<size_t> r_write_to_init_cmd_index;// index of first word in line521 GenericFifo<bool> m_write_to_init_cmd_inst_fifo;// fifo for the L1 type522 GenericFifo<size_t> m_write_to_init_cmd_srcid_fifo;// fifo for srcids523 GenericFifo<size_t> m_write_to_init_cmd_cache_id_fifo;// fifo for srcids521 sc_signal<bool> r_write_to_init_cmd_multi_req; // valid multicast request 522 sc_signal<bool> r_write_to_init_cmd_brdcast_req; // valid brdcast request 523 sc_signal<addr_t> r_write_to_init_cmd_nline; // cache line index 524 sc_signal<size_t> r_write_to_init_cmd_trdid; // index in Update Table 525 sc_signal<data_t> * r_write_to_init_cmd_data; // data (one cache line) 526 sc_signal<be_t> * r_write_to_init_cmd_be; // word enable 527 sc_signal<size_t> r_write_to_init_cmd_count; // number of words in line 528 sc_signal<size_t> r_write_to_init_cmd_index; // index of first word in line 529 GenericFifo<bool> m_write_to_init_cmd_inst_fifo; // fifo for the L1 type 530 GenericFifo<size_t> m_write_to_init_cmd_srcid_fifo; // fifo for srcids 531 GenericFifo<size_t> m_write_to_init_cmd_cache_id_fifo; // fifo for srcids 524 532 525 533 // Buffer between WRITE fsm and INIT_RSP fsm (Decrement UPT entry) 526 sc_signal<bool> r_write_to_init_rsp_req;// valid request527 sc_signal<size_t> r_write_to_init_rsp_upt_index;// index in update table534 sc_signal<bool> r_write_to_init_rsp_req; // valid request 535 sc_signal<size_t> r_write_to_init_rsp_upt_index; // index in update table 528 536 529 537 ///////////////////////////////////////////////////////// … … 531 539 ////////////////////////////////////////////////////////// 532 540 533 sc_signal<int> r_init_rsp_fsm;// FSM state534 sc_signal<size_t> r_init_rsp_upt_index;// index in the Update Table535 sc_signal<size_t> r_init_rsp_srcid; // pending write srcid536 sc_signal<size_t> r_init_rsp_trdid; // pending write trdid537 sc_signal<size_t> r_init_rsp_pktid; // pending write pktid538 sc_signal<addr_t> r_init_rsp_nline; // pending write nline541 sc_signal<int> r_init_rsp_fsm; // FSM state 542 sc_signal<size_t> r_init_rsp_upt_index; // index in the Update Table 543 sc_signal<size_t> r_init_rsp_srcid; // pending write srcid 544 sc_signal<size_t> r_init_rsp_trdid; // pending write trdid 545 sc_signal<size_t> r_init_rsp_pktid; // pending write pktid 546 sc_signal<addr_t> r_init_rsp_nline; // pending write nline 539 547 540 548 // Buffer between INIT_RSP fsm and TGT_RSP fsm (complete write/update transaction) 541 sc_signal<bool> r_init_rsp_to_tgt_rsp_req;// valid request542 sc_signal<size_t> r_init_rsp_to_tgt_rsp_srcid;// Transaction srcid543 sc_signal<size_t> r_init_rsp_to_tgt_rsp_trdid;// Transaction trdid544 sc_signal<size_t> r_init_rsp_to_tgt_rsp_pktid;// Transaction pktid549 sc_signal<bool> r_init_rsp_to_tgt_rsp_req; // valid request 550 sc_signal<size_t> r_init_rsp_to_tgt_rsp_srcid; // Transaction srcid 551 sc_signal<size_t> r_init_rsp_to_tgt_rsp_trdid; // Transaction trdid 552 sc_signal<size_t> r_init_rsp_to_tgt_rsp_pktid; // Transaction pktid 545 553 546 554 /////////////////////////////////////////////////////// … … 548 556 /////////////////////////////////////////////////////// 549 557 550 sc_signal<int> r_cleanup_fsm;// FSM state551 sc_signal<size_t> r_cleanup_srcid;// transaction srcid552 sc_signal<size_t> r_cleanup_trdid;// transaction trdid553 sc_signal<size_t> r_cleanup_pktid;// transaction pktid554 sc_signal<addr_t> r_cleanup_nline;// cache line index555 556 sc_signal<copy_t> r_cleanup_copy;// first copy557 sc_signal<copy_t> r_cleanup_copy_cache;// first copy558 sc_signal<size_t> r_cleanup_copy_inst;// type of the first copy559 sc_signal<copy_t> r_cleanup_count; // number of copies560 sc_signal<size_t> r_cleanup_ptr;// pointer to the heap561 sc_signal<size_t> r_cleanup_prev_ptr;// previous pointer to the heap562 sc_signal<size_t> r_cleanup_prev_srcid;// srcid of previous heap entry563 sc_signal<size_t> r_cleanup_prev_cache_id;// srcid of previous heap entry564 sc_signal<bool> r_cleanup_prev_inst;// inst bit of previous heap entry565 sc_signal<size_t> r_cleanup_next_ptr;// next pointer to the heap566 sc_signal<tag_t> r_cleanup_tag;// cache line tag (in directory)567 sc_signal<bool> r_cleanup_is_cnt;// inst bit (in directory)568 sc_signal<bool> r_cleanup_lock;// lock bit (in directory)569 sc_signal<bool> r_cleanup_dirty;// dirty bit (in directory)570 sc_signal<size_t> r_cleanup_way;// associative way (in cache)571 572 sc_signal<size_t> r_cleanup_write_srcid;// srcid of write response573 sc_signal<size_t> r_cleanup_write_trdid;// trdid of write rsp574 sc_signal<size_t> r_cleanup_write_pktid;// pktid of write rsp575 sc_signal<bool> r_cleanup_need_rsp;// needs a write rsp576 577 sc_signal<size_t> r_cleanup_index;// index of the INVAL line (in the UPT)558 sc_signal<int> r_cleanup_fsm; // FSM state 559 sc_signal<size_t> r_cleanup_srcid; // transaction srcid 560 sc_signal<size_t> r_cleanup_trdid; // transaction trdid 561 sc_signal<size_t> r_cleanup_pktid; // transaction pktid 562 sc_signal<addr_t> r_cleanup_nline; // cache line index 563 564 sc_signal<copy_t> r_cleanup_copy; // first copy 565 sc_signal<copy_t> r_cleanup_copy_cache; // first copy 566 sc_signal<size_t> r_cleanup_copy_inst; // type of the first copy 567 sc_signal<copy_t> r_cleanup_count; // number of copies 568 sc_signal<size_t> r_cleanup_ptr; // pointer to the heap 569 sc_signal<size_t> r_cleanup_prev_ptr; // previous pointer to the heap 570 sc_signal<size_t> r_cleanup_prev_srcid; // srcid of previous heap entry 571 sc_signal<size_t> r_cleanup_prev_cache_id; // srcid of previous heap entry 572 sc_signal<bool> r_cleanup_prev_inst; // inst bit of previous heap entry 573 sc_signal<size_t> r_cleanup_next_ptr; // next pointer to the heap 574 sc_signal<tag_t> r_cleanup_tag; // cache line tag (in directory) 575 sc_signal<bool> r_cleanup_is_cnt; // inst bit (in directory) 576 sc_signal<bool> r_cleanup_lock; // lock bit (in directory) 577 sc_signal<bool> r_cleanup_dirty; // dirty bit (in directory) 578 sc_signal<size_t> r_cleanup_way; // associative way (in cache) 579 580 sc_signal<size_t> r_cleanup_write_srcid; // srcid of write response 581 sc_signal<size_t> r_cleanup_write_trdid; // trdid of write rsp 582 sc_signal<size_t> r_cleanup_write_pktid; // pktid of write rsp 583 sc_signal<bool> r_cleanup_need_rsp; // needs a write rsp 584 585 sc_signal<size_t> r_cleanup_index; // index of the INVAL line (in the UPT) 578 586 579 587 // Buffer between CLEANUP fsm and TGT_RSP fsm (acknowledge a write command from L1) 580 sc_signal<bool> r_cleanup_to_tgt_rsp_req;// valid request581 sc_signal<size_t> r_cleanup_to_tgt_rsp_srcid;// transaction srcid582 sc_signal<size_t> r_cleanup_to_tgt_rsp_trdid;// transaction trdid583 sc_signal<size_t> r_cleanup_to_tgt_rsp_pktid;// transaction pktid588 sc_signal<bool> r_cleanup_to_tgt_rsp_req; // valid request 589 sc_signal<size_t> r_cleanup_to_tgt_rsp_srcid; // transaction srcid 590 sc_signal<size_t> r_cleanup_to_tgt_rsp_trdid; // transaction trdid 591 sc_signal<size_t> r_cleanup_to_tgt_rsp_pktid; // transaction pktid 584 592 585 593 /////////////////////////////////////////////////////// … … 587 595 /////////////////////////////////////////////////////// 588 596 589 sc_signal<int> r_sc_fsm;// FSM state590 sc_signal<data_t> r_sc_wdata;// write data word591 sc_signal<data_t> *r_sc_rdata;// read data word592 sc_signal<uint32_t> r_sc_lfsr;// lfsr for random introducing593 sc_signal<size_t> r_sc_cpt;// size of command594 sc_signal<copy_t> r_sc_copy;// Srcid of the first copy595 sc_signal<copy_t> r_sc_copy_cache;// Srcid of the first copy596 sc_signal<bool> r_sc_copy_inst;// Type of the first copy597 sc_signal<size_t> r_sc_count;// number of copies598 sc_signal<size_t> r_sc_ptr;// pointer to the heap599 sc_signal<size_t> r_sc_next_ptr;// next pointer to the heap600 sc_signal<bool> r_sc_is_cnt;// is_cnt bit (in directory)601 sc_signal<bool> r_sc_dirty;// dirty bit (in directory)602 sc_signal<size_t> r_sc_way;// way in directory603 sc_signal<size_t> r_sc_set;// set in directory604 sc_signal<data_t> r_sc_tag;// cache line tag (in directory)605 sc_signal<size_t> r_sc_trt_index;// Transaction Table index606 sc_signal<size_t> r_sc_upt_index;// Update Table index607 608 // Buffer between SC fsm and INIT_CMD fsm (XRAM read) 609 sc_signal<bool> r_sc_to_ixr_cmd_req;// valid request610 sc_signal<addr_t> r_sc_to_ixr_cmd_nline;// cache line index611 sc_signal<size_t> r_sc_to_ixr_cmd_trdid;// index in Transaction Table612 sc_signal<bool> r_sc_to_ixr_cmd_write;// write request613 sc_signal<data_t> *r_sc_to_ixr_cmd_data;// cache line data597 sc_signal<int> r_sc_fsm; // FSM state 598 sc_signal<data_t> r_sc_wdata; // write data word 599 sc_signal<data_t> * r_sc_rdata; // read data word 600 sc_signal<uint32_t> r_sc_lfsr; // lfsr for random introducing 601 sc_signal<size_t> r_sc_cpt; // size of command 602 sc_signal<copy_t> r_sc_copy; // Srcid of the first copy 603 sc_signal<copy_t> r_sc_copy_cache; // Srcid of the first copy 604 sc_signal<bool> r_sc_copy_inst; // Type of the first copy 605 sc_signal<size_t> r_sc_count; // number of copies 606 sc_signal<size_t> r_sc_ptr; // pointer to the heap 607 sc_signal<size_t> r_sc_next_ptr; // next pointer to the heap 608 sc_signal<bool> r_sc_is_cnt; // is_cnt bit (in directory) 609 sc_signal<bool> r_sc_dirty; // dirty bit (in directory) 610 sc_signal<size_t> r_sc_way; // way in directory 611 sc_signal<size_t> r_sc_set; // set in directory 612 sc_signal<data_t> r_sc_tag; // cache line tag (in directory) 613 sc_signal<size_t> r_sc_trt_index; // Transaction Table index 614 sc_signal<size_t> r_sc_upt_index; // Update Table index 615 616 // Buffer between SC fsm and INIT_CMD fsm (XRAM read) 617 sc_signal<bool> r_sc_to_ixr_cmd_req; // valid request 618 sc_signal<addr_t> r_sc_to_ixr_cmd_nline; // cache line index 619 sc_signal<size_t> r_sc_to_ixr_cmd_trdid; // index in Transaction Table 620 sc_signal<bool> r_sc_to_ixr_cmd_write; // write request 621 sc_signal<data_t> * r_sc_to_ixr_cmd_data; // cache line data 614 622 615 623 616 624 // Buffer between SC fsm and TGT_RSP fsm 617 sc_signal<bool> r_sc_to_tgt_rsp_req;// valid request618 sc_signal<data_t> r_sc_to_tgt_rsp_data;// read data word619 sc_signal<size_t> r_sc_to_tgt_rsp_srcid;// Transaction srcid620 sc_signal<size_t> r_sc_to_tgt_rsp_trdid;// Transaction trdid621 sc_signal<size_t> r_sc_to_tgt_rsp_pktid;// Transaction pktid625 sc_signal<bool> r_sc_to_tgt_rsp_req; // valid request 626 sc_signal<data_t> r_sc_to_tgt_rsp_data; // read data word 627 sc_signal<size_t> r_sc_to_tgt_rsp_srcid; // Transaction srcid 628 sc_signal<size_t> r_sc_to_tgt_rsp_trdid; // Transaction trdid 629 sc_signal<size_t> r_sc_to_tgt_rsp_pktid; // Transaction pktid 622 630 623 631 // Buffer between SC fsm and INIT_CMD fsm (Update/Invalidate L1 caches) 624 sc_signal<bool> r_sc_to_init_cmd_multi_req;// valid request625 sc_signal<bool> r_sc_to_init_cmd_brdcast_req;// brdcast request626 sc_signal<addr_t> r_sc_to_init_cmd_nline;// cache line index627 sc_signal<size_t> r_sc_to_init_cmd_trdid;// index in Update Table628 sc_signal<data_t> r_sc_to_init_cmd_wdata;// data (one word)629 sc_signal<bool> r_sc_to_init_cmd_is_long;// it is a 64 bits SC630 sc_signal<data_t> r_sc_to_init_cmd_wdata_high;// data high (one word)631 sc_signal<size_t> r_sc_to_init_cmd_index;// index of the word in line632 GenericFifo<bool> m_sc_to_init_cmd_inst_fifo;// fifo for the L1 type633 GenericFifo<size_t> m_sc_to_init_cmd_srcid_fifo;// fifo for srcids634 GenericFifo<size_t> m_sc_to_init_cmd_cache_id_fifo;// fifo for srcids632 sc_signal<bool> r_sc_to_init_cmd_multi_req; // valid request 633 sc_signal<bool> r_sc_to_init_cmd_brdcast_req; // brdcast request 634 sc_signal<addr_t> r_sc_to_init_cmd_nline; // cache line index 635 sc_signal<size_t> r_sc_to_init_cmd_trdid; // index in Update Table 636 sc_signal<data_t> r_sc_to_init_cmd_wdata; // data (one word) 637 sc_signal<bool> r_sc_to_init_cmd_is_long; // it is a 64 bits SC 638 sc_signal<data_t> r_sc_to_init_cmd_wdata_high; // data high (one word) 639 sc_signal<size_t> r_sc_to_init_cmd_index; // index of the word in line 640 GenericFifo<bool> m_sc_to_init_cmd_inst_fifo; // fifo for the L1 type 641 GenericFifo<size_t> m_sc_to_init_cmd_srcid_fifo; // fifo for srcids 642 GenericFifo<size_t> m_sc_to_init_cmd_cache_id_fifo; // fifo for srcids 635 643 636 644 // Buffer between SC fsm and INIT_RSP fsm (Decrement UPT entry) 637 sc_signal<bool> r_sc_to_init_rsp_req;// valid request638 sc_signal<size_t> r_sc_to_init_rsp_upt_index;// index in update table645 sc_signal<bool> r_sc_to_init_rsp_req; // valid request 646 sc_signal<size_t> r_sc_to_init_rsp_upt_index; // index in update table 639 647 640 648 //////////////////////////////////////////////////// … … 642 650 //////////////////////////////////////////////////// 643 651 644 sc_signal<int> 645 sc_signal<size_t> r_ixr_rsp_trt_index;// TRT entry index646 sc_signal<size_t> r_ixr_rsp_cpt;// word counter652 sc_signal<int> r_ixr_rsp_fsm; // FSM state 653 sc_signal<size_t> r_ixr_rsp_trt_index; // TRT entry index 654 sc_signal<size_t> r_ixr_rsp_cpt; // word counter 647 655 648 656 // Buffer between IXR_RSP fsm and XRAM_RSP fsm (response from the XRAM) 649 sc_signal<bool> *r_ixr_rsp_to_xram_rsp_rok;// A xram response is ready657 sc_signal<bool> * r_ixr_rsp_to_xram_rsp_rok; // A xram response is ready 650 658 651 659 //////////////////////////////////////////////////// … … 653 661 //////////////////////////////////////////////////// 654 662 655 sc_signal<int> r_xram_rsp_fsm;// FSM state656 sc_signal<size_t> r_xram_rsp_trt_index;// TRT entry index657 TransactionTabEntry r_xram_rsp_trt_buf;// TRT entry local buffer658 sc_signal<bool> r_xram_rsp_victim_inval; // victim line invalidate659 sc_signal<bool> r_xram_rsp_victim_is_cnt;// victim line inst bit660 sc_signal<bool> r_xram_rsp_victim_dirty;// victim line dirty bit661 sc_signal<size_t> r_xram_rsp_victim_way;// victim line way662 sc_signal<size_t> r_xram_rsp_victim_set;// victim line set663 sc_signal<addr_t> r_xram_rsp_victim_nline;// victim line index664 sc_signal<copy_t> r_xram_rsp_victim_copy;// victim line first copy665 sc_signal<copy_t> r_xram_rsp_victim_copy_cache;// victim line first copy666 sc_signal<bool> r_xram_rsp_victim_copy_inst;// victim line type of first copy667 sc_signal<size_t> r_xram_rsp_victim_count;// victim line number of copies668 sc_signal<size_t> r_xram_rsp_victim_ptr;// victim line pointer to the heap669 sc_signal<data_t> *r_xram_rsp_victim_data;// victim line data670 sc_signal<size_t> r_xram_rsp_upt_index;// UPT entry index671 sc_signal<size_t> r_xram_rsp_next_ptr;// Next pointer to the heap663 sc_signal<int> r_xram_rsp_fsm; // FSM state 664 sc_signal<size_t> r_xram_rsp_trt_index; // TRT entry index 665 TransactionTabEntry r_xram_rsp_trt_buf; // TRT entry local buffer 666 sc_signal<bool> r_xram_rsp_victim_inval; // victim line invalidate 667 sc_signal<bool> r_xram_rsp_victim_is_cnt; // victim line inst bit 668 sc_signal<bool> r_xram_rsp_victim_dirty; // victim line dirty bit 669 sc_signal<size_t> r_xram_rsp_victim_way; // victim line way 670 sc_signal<size_t> r_xram_rsp_victim_set; // victim line set 671 sc_signal<addr_t> r_xram_rsp_victim_nline; // victim line index 672 sc_signal<copy_t> r_xram_rsp_victim_copy; // victim line first copy 673 sc_signal<copy_t> r_xram_rsp_victim_copy_cache; // victim line first copy 674 sc_signal<bool> r_xram_rsp_victim_copy_inst; // victim line type of first copy 675 sc_signal<size_t> r_xram_rsp_victim_count; // victim line number of copies 676 sc_signal<size_t> r_xram_rsp_victim_ptr; // victim line pointer to the heap 677 sc_signal<data_t> * r_xram_rsp_victim_data; // victim line data 678 sc_signal<size_t> r_xram_rsp_upt_index; // UPT entry index 679 sc_signal<size_t> r_xram_rsp_next_ptr; // Next pointer to the heap 672 680 673 681 // Buffer between XRAM_RSP fsm and TGT_RSP fsm (response to L1 cache) 674 sc_signal<bool> r_xram_rsp_to_tgt_rsp_req;// Valid request675 sc_signal<size_t> r_xram_rsp_to_tgt_rsp_srcid;// Transaction srcid676 sc_signal<size_t> r_xram_rsp_to_tgt_rsp_trdid;// Transaction trdid677 sc_signal<size_t> r_xram_rsp_to_tgt_rsp_pktid;// Transaction pktid678 sc_signal<data_t> *r_xram_rsp_to_tgt_rsp_data;// data (one cache line)679 sc_signal<size_t> r_xram_rsp_to_tgt_rsp_word;// first word index680 sc_signal<size_t> r_xram_rsp_to_tgt_rsp_length;// length of the response681 sc_signal<bool> r_xram_rsp_to_tgt_rsp_rerror;// send error to requester682 683 // Buffer between XRAM_RSP fsm and INIT_CMD fsm (Inval L1 Caches) 684 sc_signal<bool> r_xram_rsp_to_init_cmd_multi_req;// Valid request685 sc_signal<bool> r_xram_rsp_to_init_cmd_brdcast_req;// Broadcast request686 sc_signal<addr_t> r_xram_rsp_to_init_cmd_nline;// cache line index;687 sc_signal<size_t> r_xram_rsp_to_init_cmd_trdid;// index of UPT entry688 GenericFifo<bool> m_xram_rsp_to_init_cmd_inst_fifo;// fifo for the L1 type689 GenericFifo<size_t> m_xram_rsp_to_init_cmd_srcid_fifo;// fifo for srcids690 GenericFifo<size_t> m_xram_rsp_to_init_cmd_cache_id_fifo;// fifo for srcids682 sc_signal<bool> r_xram_rsp_to_tgt_rsp_req; // Valid request 683 sc_signal<size_t> r_xram_rsp_to_tgt_rsp_srcid; // Transaction srcid 684 sc_signal<size_t> r_xram_rsp_to_tgt_rsp_trdid; // Transaction trdid 685 sc_signal<size_t> r_xram_rsp_to_tgt_rsp_pktid; // Transaction pktid 686 sc_signal<data_t> * r_xram_rsp_to_tgt_rsp_data; // data (one cache line) 687 sc_signal<size_t> r_xram_rsp_to_tgt_rsp_word; // first word index 688 sc_signal<size_t> r_xram_rsp_to_tgt_rsp_length; // length of the response 689 sc_signal<bool> r_xram_rsp_to_tgt_rsp_rerror; // send error to requester 690 691 // Buffer between XRAM_RSP fsm and INIT_CMD fsm (Inval L1 Caches) 692 sc_signal<bool> r_xram_rsp_to_init_cmd_multi_req; // Valid request 693 sc_signal<bool> r_xram_rsp_to_init_cmd_brdcast_req; // Broadcast request 694 sc_signal<addr_t> r_xram_rsp_to_init_cmd_nline; // cache line index; 695 sc_signal<size_t> r_xram_rsp_to_init_cmd_trdid; // index of UPT entry 696 GenericFifo<bool> m_xram_rsp_to_init_cmd_inst_fifo; // fifo for the L1 type 697 GenericFifo<size_t> m_xram_rsp_to_init_cmd_srcid_fifo; // fifo for srcids 698 GenericFifo<size_t> m_xram_rsp_to_init_cmd_cache_id_fifo; // fifo for srcids 691 699 692 700 // Buffer between XRAM_RSP fsm and IXR_CMD fsm (XRAM write) 693 sc_signal<bool> r_xram_rsp_to_ixr_cmd_req;// Valid request694 sc_signal<addr_t> r_xram_rsp_to_ixr_cmd_nline;// cache line index695 sc_signal<data_t> *r_xram_rsp_to_ixr_cmd_data;// cache line data696 sc_signal<size_t> r_xram_rsp_to_ixr_cmd_trdid;// index in transaction table701 sc_signal<bool> r_xram_rsp_to_ixr_cmd_req; // Valid request 702 sc_signal<addr_t> r_xram_rsp_to_ixr_cmd_nline; // cache line index 703 sc_signal<data_t> * r_xram_rsp_to_ixr_cmd_data; // cache line data 704 sc_signal<size_t> r_xram_rsp_to_ixr_cmd_trdid; // index in transaction table 697 705 698 706 //////////////////////////////////////////////////// … … 700 708 //////////////////////////////////////////////////// 701 709 702 sc_signal<int> 703 sc_signal<size_t> 710 sc_signal<int> r_ixr_cmd_fsm; 711 sc_signal<size_t> r_ixr_cmd_cpt; 704 712 705 713 //////////////////////////////////////////////////// … … 707 715 //////////////////////////////////////////////////// 708 716 709 sc_signal<int> 710 sc_signal<size_t> 717 sc_signal<int> r_tgt_rsp_fsm; 718 sc_signal<size_t> r_tgt_rsp_cpt; 711 719 712 720 //////////////////////////////////////////////////// … … 714 722 //////////////////////////////////////////////////// 715 723 716 sc_signal<int> 724 sc_signal<int> r_init_cmd_fsm; 717 725 sc_signal<size_t> r_init_cmd_cpt; 718 726 sc_signal<bool> r_init_cmd_inst; … … 722 730 //////////////////////////////////////////////////// 723 731 724 sc_signal<int> r_alloc_dir_fsm; 732 sc_signal<int> r_alloc_dir_fsm; 733 sc_signal<unsigned> r_alloc_dir_reset_cpt; 725 734 726 735 //////////////////////////////////////////////////// … … 728 737 //////////////////////////////////////////////////// 729 738 730 sc_signal<int> 739 sc_signal<int> r_alloc_trt_fsm; 731 740 732 741 //////////////////////////////////////////////////// … … 734 743 //////////////////////////////////////////////////// 735 744 736 sc_signal<int> 745 sc_signal<int> r_alloc_upt_fsm; 737 746 738 747 //////////////////////////////////////////////////// … … 740 749 //////////////////////////////////////////////////// 741 750 742 sc_signal<int> 743 751 sc_signal<int> r_alloc_heap_fsm; 752 sc_signal<unsigned> r_alloc_heap_reset_cpt; 744 753 }; // end class VciMemCacheV4 745 754 … … 755 764 // End: 756 765 757 // vim: filetype=cpp:expandtab:shiftwidth= 4:tabstop=4:softtabstop=4758 766 // vim: filetype=cpp:expandtab:shiftwidth=2:tabstop=2:softtabstop=2 767 -
trunk/modules/vci_mem_cache_v4/caba/source/src/vci_mem_cache_v4.cpp
r253 r273 1 1 /* -*- c++ -*- 2 * File 3 * Date 4 * Copyright 5 * Authors 2 * File : vci_mem_cache_v4.cpp 3 * Date : 30/10/2008 4 * Copyright : UPMC / LIP6 5 * Authors : Alain Greiner / Eric Guthmuller 6 6 * 7 7 * SOCLIB_LGPL_HEADER_BEGIN … … 26 26 * 27 27 * Maintainers: alain eric.guthmuller@polytechnique.edu 28 * cesar.fuguet-tortolero@lip6.fr 28 29 */ 29 30 … … 32 33 ////// debug services /////////////////////////////////////////////////////// 33 34 // All debug messages are conditionned by two variables: 34 // - compile time : DEBUG_MEMC_*** : defined below35 // - execution time : m_debug_*** : defined by constructor arguments35 // - compile time : DEBUG_MEMC_*** : defined below 36 // - execution time : m_debug_*** : defined by constructor arguments 36 37 // m_debug_* = (m_debug_ok) and (m_cpt_cycle > m_debug_start_cycle) 37 38 ///////////////////////////////////////////////////////////////////////////////// 38 39 39 #define DEBUG_MEMC_GLOBAL 0// synthetic trace of all FSMs40 #define DEBUG_MEMC_READ 1// detailed trace of READ FSM41 #define DEBUG_MEMC_WRITE 1 // detailed trace of WRITE FSM42 #define DEBUG_MEMC_SC 1 // detailed trace of SC FSM43 #define DEBUG_MEMC_IXR_CMD 1// detailed trace of IXR_RSP FSM44 #define DEBUG_MEMC_IXR_RSP 1// detailed trace of IXR_RSP FSM45 #define DEBUG_MEMC_XRAM_RSP 1 // detailed trace of XRAM_RSP FSM46 #define DEBUG_MEMC_INIT_CMD 1 // detailed trace of INIT_CMD FSM47 #define DEBUG_MEMC_INIT_RSP 1 // detailed trace of INIT_RSP FSM48 #define DEBUG_MEMC_TGT_CMD 1 // detailed trace of TGT_CMD FSM49 #define DEBUG_MEMC_TGT_RSP 1 // detailed trace of TGT_RSP FSM50 #define DEBUG_MEMC_CLEANUP 1 // detailed trace of CLEANUP FSM51 52 #define RANDOMIZE_SC 40 #define DEBUG_MEMC_GLOBAL 0 // synthetic trace of all FSMs 41 #define DEBUG_MEMC_READ 1 // detailed trace of READ FSM 42 #define DEBUG_MEMC_WRITE 1 // detailed trace of WRITE FSM 43 #define DEBUG_MEMC_SC 1 // detailed trace of SC FSM 44 #define DEBUG_MEMC_IXR_CMD 1 // detailed trace of IXR_RSP FSM 45 #define DEBUG_MEMC_IXR_RSP 1 // detailed trace of IXR_RSP FSM 46 #define DEBUG_MEMC_XRAM_RSP 1 // detailed trace of XRAM_RSP FSM 47 #define DEBUG_MEMC_INIT_CMD 1 // detailed trace of INIT_CMD FSM 48 #define DEBUG_MEMC_INIT_RSP 1 // detailed trace of INIT_RSP FSM 49 #define DEBUG_MEMC_TGT_CMD 1 // detailed trace of TGT_CMD FSM 50 #define DEBUG_MEMC_TGT_RSP 1 // detailed trace of TGT_RSP FSM 51 #define DEBUG_MEMC_CLEANUP 1 // detailed trace of CLEANUP FSM 52 53 #define RANDOMIZE_SC 1 53 54 54 55 namespace soclib { namespace caba { … … 58 59 "TGT_CMD_READ", 59 60 "TGT_CMD_WRITE", 60 "TGT_CMD_ATOMIC" ,61 "TGT_CMD_ATOMIC" 61 62 }; 62 63 const char *tgt_rsp_fsm_str[] = { … … 72 73 "TGT_RSP_XRAM", 73 74 "TGT_RSP_INIT", 74 "TGT_RSP_CLEANUP" ,75 "TGT_RSP_CLEANUP" 75 76 }; 76 77 const char *init_cmd_fsm_str[] = { … … 88 89 "INIT_CMD_SC_UPDT_INDEX", 89 90 "INIT_CMD_SC_UPDT_DATA", 90 "INIT_CMD_SC_UPDT_DATA_HIGH" ,91 "INIT_CMD_SC_UPDT_DATA_HIGH" 91 92 }; 92 93 const char *init_rsp_fsm_str[] = { … … 94 95 "INIT_RSP_UPT_LOCK", 95 96 "INIT_RSP_UPT_CLEAR", 96 "INIT_RSP_END" ,97 "INIT_RSP_END" 97 98 }; 98 99 const char *read_fsm_str[] = { 99 100 "READ_IDLE", 101 "READ_DIR_REQ", 100 102 "READ_DIR_LOCK", 101 103 "READ_DIR_HIT", 104 "READ_HEAP_REQ", 102 105 "READ_HEAP_LOCK", 103 106 "READ_HEAP_WRITE", … … 107 110 "READ_TRT_LOCK", 108 111 "READ_TRT_SET", 109 "READ_TRT_REQ" ,112 "READ_TRT_REQ" 110 113 }; 111 114 const char *write_fsm_str[] = { 112 115 "WRITE_IDLE", 113 116 "WRITE_NEXT", 117 "WRITE_DIR_REQ", 114 118 "WRITE_DIR_LOCK", 115 119 "WRITE_DIR_READ", … … 130 134 "WRITE_BC_CC_SEND", 131 135 "WRITE_BC_XRAM_REQ", 132 "WRITE_WAIT" ,136 "WRITE_WAIT" 133 137 }; 134 138 const char *ixr_rsp_fsm_str[] = { … … 136 140 "IXR_RSP_ACK", 137 141 "IXR_RSP_TRT_ERASE", 138 "IXR_RSP_TRT_READ" ,142 "IXR_RSP_TRT_READ" 139 143 }; 140 144 const char *xram_rsp_fsm_str[] = { … … 149 153 "XRAM_RSP_INVAL", 150 154 "XRAM_RSP_WRITE_DIRTY", 155 "XRAM_RSP_HEAP_REQ", 151 156 "XRAM_RSP_HEAP_ERASE", 152 157 "XRAM_RSP_HEAP_LAST", 153 158 "XRAM_RSP_ERROR_ERASE", 154 "XRAM_RSP_ERROR_RSP" ,159 "XRAM_RSP_ERROR_RSP" 155 160 }; 156 161 const char *ixr_cmd_fsm_str[] = { … … 162 167 "IXR_CMD_WRITE_NLINE", 163 168 "IXR_CMD_SC_NLINE", 164 "IXR_CMD_XRAM_DATA" ,169 "IXR_CMD_XRAM_DATA" 165 170 }; 166 171 const char *sc_fsm_str[] = { 167 172 "SC_IDLE", 173 "SC_DIR_REQ", 168 174 "SC_DIR_LOCK", 169 175 "SC_DIR_HIT_READ", … … 183 189 "SC_MISS_TRT_SET", 184 190 "SC_MISS_XRAM_REQ", 185 "SC_WAIT" ,191 "SC_WAIT" 186 192 }; 187 193 const char *cleanup_fsm_str[] = { 188 194 "CLEANUP_IDLE", 195 "CLEANUP_DIR_REQ", 189 196 "CLEANUP_DIR_LOCK", 190 197 "CLEANUP_DIR_WRITE", 198 "CLEANUP_HEAP_REQ", 191 199 "CLEANUP_HEAP_LOCK", 192 200 "CLEANUP_HEAP_SEARCH", … … 196 204 "CLEANUP_UPT_WRITE", 197 205 "CLEANUP_WRITE_RSP", 198 "CLEANUP_RSP" ,206 "CLEANUP_RSP" 199 207 }; 200 208 const char *alloc_dir_fsm_str[] = { 209 "ALLOC_DIR_RESET", 201 210 "ALLOC_DIR_READ", 202 211 "ALLOC_DIR_WRITE", 203 212 "ALLOC_DIR_SC", 204 213 "ALLOC_DIR_CLEANUP", 205 "ALLOC_DIR_XRAM_RSP" ,214 "ALLOC_DIR_XRAM_RSP" 206 215 }; 207 216 const char *alloc_trt_fsm_str[] = { … … 210 219 "ALLOC_TRT_SC", 211 220 "ALLOC_TRT_XRAM_RSP", 212 "ALLOC_TRT_IXR_RSP" ,221 "ALLOC_TRT_IXR_RSP" 213 222 }; 214 223 const char *alloc_upt_fsm_str[] = { … … 217 226 "ALLOC_UPT_INIT_RSP", 218 227 "ALLOC_UPT_CLEANUP", 228 "ALLOC_UPT_SC" 219 229 }; 220 230 const char *alloc_heap_fsm_str[] = { 231 "ALLOC_HEAP_RESET", 221 232 "ALLOC_HEAP_READ", 222 233 "ALLOC_HEAP_WRITE", 223 234 "ALLOC_HEAP_SC", 224 235 "ALLOC_HEAP_CLEANUP", 225 "ALLOC_HEAP_XRAM_RSP" ,236 "ALLOC_HEAP_XRAM_RSP" 226 237 }; 227 238 … … 231 242 232 243 //////////////////////////////// 233 // Constructor244 // Constructor 234 245 //////////////////////////////// 235 246 236 tmpl(/**/)::VciMemCacheV4( 247 tmpl(/**/)::VciMemCacheV4( 237 248 sc_module_name name, 238 249 const soclib::common::MappingTable &mtp, … … 243 254 const soclib::common::IntTab &vci_tgt_index, 244 255 const soclib::common::IntTab &vci_tgt_index_cleanup, 245 size_t nways, 246 size_t nsets, 247 size_t nwords, 248 size_t heap_size, 249 size_t transaction_tab_lines, 250 size_t update_tab_lines, 256 size_t nways, // number of ways per set 257 size_t nsets, // number of cache sets 258 size_t nwords, // number of words in cache line 259 size_t heap_size, // number of heap entries 260 size_t transaction_tab_lines, // number of TRT entries 261 size_t update_tab_lines, // number of UPT entries 251 262 size_t debug_start_cycle, 252 263 bool debug_ok) … … 287 298 #undef L2 288 299 289 // FIFOs 300 // FIFOs 290 301 291 302 m_cmd_read_addr_fifo("m_cmd_read_addr_fifo", 4), … … 311 322 312 323 r_tgt_cmd_fsm("r_tgt_cmd_fsm"), 313 314 m_nseg(0), 315 m_ncseg(0), 324 325 m_nseg(0), 326 m_ncseg(0), 316 327 317 328 r_read_fsm("r_read_fsm"), … … 352 363 353 364 r_alloc_dir_fsm("r_alloc_dir_fsm"), 365 r_alloc_dir_reset_cpt("r_alloc_dir_reset_cpt"), 354 366 r_alloc_trt_fsm("r_alloc_trt_fsm"), 355 367 r_alloc_upt_fsm("r_alloc_upt_fsm"), 356 r_alloc_heap_fsm("r_alloc_heap_fsm") 368 r_alloc_heap_fsm("r_alloc_heap_fsm"), 369 r_alloc_heap_reset_cpt("r_alloc_heap_reset_cpt") 357 370 { 358 371 assert(IS_POW_OF_2(nsets)); … … 370 383 m_broadcast_address = 0x3 | (0x7C1F << (vci_param::N-20)); 371 384 372 // Get the segments associated to the MemCache 385 // Get the segments associated to the MemCache 373 386 std::list<soclib::common::Segment>::iterator seg; 374 387 size_t i; … … 384 397 385 398 i = 0; 386 for ( seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++ ) { 399 for ( seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++ ) { 387 400 m_seg[i] = &(*seg); 388 401 i++; … … 392 405 393 406 i = 0; 394 for ( seg = m_cseglist.begin() ; seg != m_cseglist.end() ; seg++ ) { 407 for ( seg = m_cseglist.begin() ; seg != m_cseglist.end() ; seg++ ) { 395 408 m_cseg[i] = &(*seg); 396 409 i++; … … 407 420 for ( size_t k=0; k<nwords; k++){ 408 421 m_cache_data[i][j][k]=0; 409 } 422 } 410 423 } 411 424 } 412 425 413 426 // Allocation for IXR_RSP FSM 414 r_ixr_rsp_to_xram_rsp_rok 427 r_ixr_rsp_to_xram_rsp_rok = new sc_signal<bool>[m_transaction_tab_lines]; 415 428 416 429 // Allocation for XRAM_RSP FSM 417 r_xram_rsp_victim_data 418 r_xram_rsp_to_tgt_rsp_data 419 r_xram_rsp_to_ixr_cmd_data 430 r_xram_rsp_victim_data = new sc_signal<data_t>[nwords]; 431 r_xram_rsp_to_tgt_rsp_data = new sc_signal<data_t>[nwords]; 432 r_xram_rsp_to_ixr_cmd_data = new sc_signal<data_t>[nwords]; 420 433 421 434 // Allocation for READ FSM 422 r_read_data 423 r_read_to_tgt_rsp_data 435 r_read_data = new sc_signal<data_t>[nwords]; 436 r_read_to_tgt_rsp_data = new sc_signal<data_t>[nwords]; 424 437 425 438 // Allocation for WRITE FSM 426 r_write_data 427 r_write_be 428 r_write_to_init_cmd_data 429 r_write_to_init_cmd_be 430 r_write_to_ixr_cmd_data 439 r_write_data = new sc_signal<data_t>[nwords]; 440 r_write_be = new sc_signal<be_t>[nwords]; 441 r_write_to_init_cmd_data = new sc_signal<data_t>[nwords]; 442 r_write_to_init_cmd_be = new sc_signal<be_t>[nwords]; 443 r_write_to_ixr_cmd_data = new sc_signal<data_t>[nwords]; 431 444 432 445 // Allocation for SC FSM 433 r_sc_to_ixr_cmd_data 434 r_sc_rdata 446 r_sc_to_ixr_cmd_data = new sc_signal<data_t>[nwords]; 447 r_sc_rdata = new sc_signal<data_t>[2]; 435 448 436 449 … … 471 484 { 472 485 std::cout << " MEMC Write Monitor : " << buf << " Address = " << std::hex << addr 473 << " / Data = " << data << std::endl; 486 << " / Data = " << data << std::endl; 474 487 } 475 488 } … … 480 493 { 481 494 DirectoryEntry entry = m_cache_directory.read_neutral(addr); 482 if ( (entry.count != m_debug_previous_count) or 495 if ( (entry.count != m_debug_previous_count) or 483 496 (entry.valid != m_debug_previous_hit) ) 484 497 { … … 498 511 { 499 512 std::cout << "MEMC " << name() << std::endl; 500 std::cout << " " << tgt_cmd_fsm_str[r_tgt_cmd_fsm] 501 << " | " << tgt_rsp_fsm_str[r_tgt_rsp_fsm] 513 std::cout << " " << tgt_cmd_fsm_str[r_tgt_cmd_fsm] 514 << " | " << tgt_rsp_fsm_str[r_tgt_rsp_fsm] 502 515 << " | " << read_fsm_str[r_read_fsm] 503 << " | " << write_fsm_str[r_write_fsm] 504 << " | " << sc_fsm_str[r_sc_fsm] 516 << " | " << write_fsm_str[r_write_fsm] 517 << " | " << sc_fsm_str[r_sc_fsm] 505 518 << " | " << cleanup_fsm_str[r_cleanup_fsm] << std::endl; 506 519 std::cout << " " << init_cmd_fsm_str[r_init_cmd_fsm] 507 << " | " << init_rsp_fsm_str[r_init_rsp_fsm] 508 << " | " << ixr_cmd_fsm_str[r_ixr_cmd_fsm] 520 << " | " << init_rsp_fsm_str[r_init_rsp_fsm] 521 << " | " << ixr_cmd_fsm_str[r_ixr_cmd_fsm] 509 522 << " | " << ixr_rsp_fsm_str[r_ixr_rsp_fsm] 510 523 << " | " << xram_rsp_fsm_str[r_xram_rsp_fsm] << std::endl; … … 515 528 ///////////////////////////////////////// 516 529 { 517 std::cout << "----------------------------------" << std::dec << std::endl; 518 std::cout << "MEM_CACHE " << m_srcid_ini << " / Time = " << m_cpt_cycles << std::endl 519 << "- READ RATE = " << (double)m_cpt_read/m_cpt_cycles << std::endl 520 << "- READ TOTAL = " << m_cpt_read << std::endl 521 << "- READ MISS RATE = " << (double)m_cpt_read_miss/m_cpt_read << std::endl 522 << "- WRITE RATE = " << (double)m_cpt_write/m_cpt_cycles << std::endl 523 << "- WRITE TOTAL = " << m_cpt_write << std::endl 524 << "- WRITE MISS RATE = " << (double)m_cpt_write_miss/m_cpt_write << std::endl 525 << "- WRITE BURST LENGTH = " << (double)m_cpt_write_cells/m_cpt_write << std::endl 526 << "- WRITE BURST TOTAL = " << m_cpt_write_cells << std::endl 527 << "- REQUESTS TRT FULL = " << m_cpt_trt_full << std::endl 528 << "- READ TRT BLOKED HIT = " << m_cpt_trt_rb << std::endl 529 << "- UPDATE RATE = " << (double)m_cpt_update/m_cpt_cycles << std::endl 530 << "- UPDATE ARITY = " << (double)m_cpt_update_mult/m_cpt_update << std::endl 531 << "- INVAL MULTICAST RATE = " << (double)(m_cpt_inval-m_cpt_inval_brdcast)/m_cpt_cycles << std::endl 532 << "- INVAL MULTICAST ARITY= " << (double)m_cpt_inval_mult/(m_cpt_inval-m_cpt_inval_brdcast) << std::endl 533 << "- INVAL BROADCAST RATE = " << (double)m_cpt_inval_brdcast/m_cpt_cycles << std::endl 534 << "- SAVE DIRTY RATE = " << (double)m_cpt_write_dirty/m_cpt_cycles << std::endl 535 << "- CLEANUP RATE = " << (double)m_cpt_cleanup/m_cpt_cycles << std::endl 536 << "- LL RATE = " << (double)m_cpt_ll/m_cpt_cycles << std::endl 537 << "- SC RATE = " << (double)m_cpt_sc/m_cpt_cycles << std::endl; 530 std::cout << "----------------------------------" << std::dec << std::endl; 531 std::cout 532 << "MEM_CACHE " << m_srcid_ini << " / Time = " << m_cpt_cycles << std::endl 533 << "- READ RATE = " << (double) m_cpt_read/m_cpt_cycles << std::endl 534 << "- READ TOTAL = " << m_cpt_read << std::endl 535 << "- READ MISS RATE = " << (double) m_cpt_read_miss/m_cpt_read << std::endl 536 << "- WRITE RATE = " << (double) m_cpt_write/m_cpt_cycles << std::endl 537 << "- WRITE TOTAL = " << m_cpt_write << std::endl 538 << "- WRITE MISS RATE = " << (double) m_cpt_write_miss/m_cpt_write << std::endl 539 << "- WRITE BURST LENGTH = " << (double) m_cpt_write_cells/m_cpt_write << std::endl 540 << "- WRITE BURST TOTAL = " << m_cpt_write_cells << std::endl 541 << "- REQUESTS TRT FULL = " << m_cpt_trt_full << std::endl 542 << "- READ TRT BLOKED HIT = " << m_cpt_trt_rb << std::endl 543 << "- UPDATE RATE = " << (double) m_cpt_update/m_cpt_cycles << std::endl 544 << "- UPDATE ARITY = " << (double) m_cpt_update_mult/m_cpt_update << std::endl 545 << "- INVAL MULTICAST RATE = " << (double) (m_cpt_inval-m_cpt_inval_brdcast)/m_cpt_cycles << std::endl 546 << "- INVAL MULTICAST ARITY= " << (double) m_cpt_inval_mult/(m_cpt_inval-m_cpt_inval_brdcast) << std::endl 547 << "- INVAL BROADCAST RATE = " << (double) m_cpt_inval_brdcast/m_cpt_cycles << std::endl 548 << "- SAVE DIRTY RATE = " << (double) m_cpt_write_dirty/m_cpt_cycles << std::endl 549 << "- CLEANUP RATE = " << (double) m_cpt_cleanup/m_cpt_cycles << std::endl 550 << "- LL RATE = " << (double) m_cpt_ll/m_cpt_cycles << std::endl 551 << "- SC RATE = " << (double) m_cpt_sc/m_cpt_cycles << std::endl; 538 552 } 539 553 … … 570 584 ////////////////////////////////// 571 585 { 572 573 574 // RESET575 576 577 //Initializing FSMs578 r_tgt_cmd_fsm= TGT_CMD_IDLE;579 r_tgt_rsp_fsm= TGT_RSP_READ_IDLE;580 r_init_cmd_fsm= INIT_CMD_INVAL_IDLE;581 r_init_rsp_fsm= INIT_RSP_IDLE;582 r_read_fsm= READ_IDLE;583 r_write_fsm= WRITE_IDLE;584 r_sc_fsm= SC_IDLE;585 r_cleanup_fsm= CLEANUP_IDLE;586 r_alloc_dir_fsm = ALLOC_DIR_READ;587 r_alloc_heap_fsm = ALLOC_HEAP_READ;588 r_alloc_trt_fsm= ALLOC_TRT_READ;589 r_alloc_upt_fsm= ALLOC_UPT_WRITE;590 r_ixr_rsp_fsm= IXR_RSP_IDLE;591 r_xram_rsp_fsm= XRAM_RSP_IDLE;592 r_ixr_cmd_fsm= IXR_CMD_READ_IDLE;593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 m_cache_directory.init();611 m_transaction_tab.init();612 m_heap.init(); 613 614 // initializing FIFOs and communication Buffers 615 616 m_cmd_read_addr_fifo.init();617 m_cmd_read_length_fifo.init();618 m_cmd_read_srcid_fifo.init();619 m_cmd_read_trdid_fifo.init();620 m_cmd_read_pktid_fifo.init(); 621 622 m_cmd_write_addr_fifo.init();623 m_cmd_write_eop_fifo.init();624 m_cmd_write_srcid_fifo.init();625 m_cmd_write_trdid_fifo.init();626 m_cmd_write_pktid_fifo.init();627 m_cmd_write_data_fifo.init(); 628 629 m_cmd_sc_addr_fifo.init();630 m_cmd_sc_srcid_fifo.init();631 m_cmd_sc_trdid_fifo.init();632 m_cmd_sc_pktid_fifo.init();633 m_cmd_sc_wdata_fifo.init();634 m_cmd_sc_eop_fifo.init(); 635 636 r_read_to_tgt_rsp_req= false;637 r_read_to_ixr_cmd_req = false; 638 639 r_write_to_tgt_rsp_req= false;640 r_write_to_ixr_cmd_req= false;641 r_write_to_init_cmd_multi_req= false;642 r_write_to_init_cmd_brdcast_req= false;643 r_write_to_init_rsp_req = false; 644 645 586 using soclib::common::uint32_log2; 587 588 // RESET 589 if ( ! p_resetn.read() ) { 590 591 // Initializing FSMs 592 r_tgt_cmd_fsm = TGT_CMD_IDLE; 593 r_tgt_rsp_fsm = TGT_RSP_READ_IDLE; 594 r_init_cmd_fsm = INIT_CMD_INVAL_IDLE; 595 r_init_rsp_fsm = INIT_RSP_IDLE; 596 r_read_fsm = READ_IDLE; 597 r_write_fsm = WRITE_IDLE; 598 r_sc_fsm = SC_IDLE; 599 r_cleanup_fsm = CLEANUP_IDLE; 600 r_alloc_dir_fsm = ALLOC_DIR_RESET; 601 r_alloc_heap_fsm = ALLOC_HEAP_RESET; 602 r_alloc_trt_fsm = ALLOC_TRT_READ; 603 r_alloc_upt_fsm = ALLOC_UPT_WRITE; 604 r_ixr_rsp_fsm = IXR_RSP_IDLE; 605 r_xram_rsp_fsm = XRAM_RSP_IDLE; 606 r_ixr_cmd_fsm = IXR_CMD_READ_IDLE; 607 608 m_debug_global = false; 609 m_debug_tgt_cmd_fsm = false; 610 m_debug_tgt_rsp_fsm = false; 611 m_debug_init_cmd_fsm = false; 612 m_debug_init_rsp_fsm = false; 613 m_debug_read_fsm = false; 614 m_debug_write_fsm = false; 615 m_debug_sc_fsm = false; 616 m_debug_cleanup_fsm = false; 617 m_debug_ixr_cmd_fsm = false; 618 m_debug_ixr_rsp_fsm = false; 619 m_debug_xram_rsp_fsm = false; 620 m_debug_previous_hit = false; 621 m_debug_previous_count = 0; 622 623 // Initializing Tables 624 m_transaction_tab.init(); 625 m_update_tab.init(); 626 627 // initializing FIFOs and communication Buffers 628 629 m_cmd_read_addr_fifo.init(); 630 m_cmd_read_length_fifo.init(); 631 m_cmd_read_srcid_fifo.init(); 632 m_cmd_read_trdid_fifo.init(); 633 m_cmd_read_pktid_fifo.init(); 634 635 m_cmd_write_addr_fifo.init(); 636 m_cmd_write_eop_fifo.init(); 637 m_cmd_write_srcid_fifo.init(); 638 m_cmd_write_trdid_fifo.init(); 639 m_cmd_write_pktid_fifo.init(); 640 m_cmd_write_data_fifo.init(); 641 642 m_cmd_sc_addr_fifo.init(); 643 m_cmd_sc_srcid_fifo.init(); 644 m_cmd_sc_trdid_fifo.init(); 645 m_cmd_sc_pktid_fifo.init(); 646 m_cmd_sc_wdata_fifo.init(); 647 m_cmd_sc_eop_fifo.init(); 648 649 r_read_to_tgt_rsp_req = false; 650 r_read_to_ixr_cmd_req = false; 651 652 r_write_to_tgt_rsp_req = false; 653 r_write_to_ixr_cmd_req = false; 654 r_write_to_init_cmd_multi_req = false; 655 r_write_to_init_cmd_brdcast_req = false; 656 r_write_to_init_rsp_req = false; 657 658 m_write_to_init_cmd_inst_fifo.init(); 659 m_write_to_init_cmd_srcid_fifo.init(); 646 660 #if L1_MULTI_CACHE 647 m_write_to_init_cmd_cache_id_fifo.init(); 648 #endif 649 650 r_cleanup_to_tgt_rsp_req = false; 651 652 r_init_rsp_to_tgt_rsp_req = false; 653 654 r_sc_to_tgt_rsp_req = false; 655 r_sc_cpt = 0; 656 r_sc_lfsr = -1; 657 r_sc_to_ixr_cmd_req = false; 658 r_sc_to_init_cmd_multi_req = false; 659 r_sc_to_init_cmd_brdcast_req = false; 660 m_sc_to_init_cmd_inst_fifo.init(); 661 m_sc_to_init_cmd_srcid_fifo.init(); 661 m_write_to_init_cmd_cache_id_fifo.init(); 662 #endif 663 664 r_cleanup_to_tgt_rsp_req = false; 665 666 r_init_rsp_to_tgt_rsp_req = false; 667 668 r_sc_to_tgt_rsp_req = false; 669 r_sc_cpt = 0; 670 r_sc_lfsr = -1; 671 r_sc_to_ixr_cmd_req = false; 672 r_sc_to_init_cmd_multi_req = false; 673 r_sc_to_init_cmd_brdcast_req = false; 674 675 m_sc_to_init_cmd_inst_fifo.init(); 676 m_sc_to_init_cmd_srcid_fifo.init(); 662 677 #if L1_MULTI_CACHE 663 m_sc_to_init_cmd_cache_id_fifo.init(); 664 #endif 665 666 for(size_t i=0; i<m_transaction_tab_lines ; i++){ 667 r_ixr_rsp_to_xram_rsp_rok[i] = false; 668 } 669 670 r_xram_rsp_to_tgt_rsp_req = false; 671 r_xram_rsp_to_init_cmd_multi_req = false; 672 r_xram_rsp_to_init_cmd_brdcast_req = false; 673 r_xram_rsp_to_ixr_cmd_req = false; 674 r_xram_rsp_trt_index = 0; 675 m_xram_rsp_to_init_cmd_inst_fifo.init(); 676 m_xram_rsp_to_init_cmd_srcid_fifo.init(); 678 m_sc_to_init_cmd_cache_id_fifo.init(); 679 #endif 680 681 for(size_t i=0; i<m_transaction_tab_lines ; i++){ 682 r_ixr_rsp_to_xram_rsp_rok[i] = false; 683 } 684 685 r_xram_rsp_to_tgt_rsp_req = false; 686 r_xram_rsp_to_init_cmd_multi_req = false; 687 r_xram_rsp_to_init_cmd_brdcast_req = false; 688 r_xram_rsp_to_ixr_cmd_req = false; 689 r_xram_rsp_trt_index = 0; 690 691 m_xram_rsp_to_init_cmd_inst_fifo.init(); 692 m_xram_rsp_to_init_cmd_srcid_fifo.init(); 677 693 #if L1_MULTI_CACHE 678 m_xram_rsp_to_init_cmd_cache_id_fifo.init(); 679 #endif 680 681 r_ixr_cmd_cpt = 0; 682 683 r_copies_limit = 3; 684 685 // Activity counters 686 m_cpt_cycles = 0; 687 m_cpt_read = 0; 688 m_cpt_read_miss = 0; 689 m_cpt_write = 0; 690 m_cpt_write_miss = 0; 691 m_cpt_write_cells = 0; 692 m_cpt_write_dirty = 0; 693 m_cpt_update = 0; 694 m_cpt_update_mult = 0; 695 m_cpt_inval_brdcast = 0; 696 m_cpt_inval = 0; 697 m_cpt_inval_mult = 0; 698 m_cpt_cleanup = 0; 699 m_cpt_ll = 0; 700 m_cpt_sc = 0; 701 m_cpt_trt_full = 0; 702 m_cpt_trt_rb = 0; 703 704 return; 705 } 706 707 bool cmd_read_fifo_put = false; 708 bool cmd_read_fifo_get = false; 709 710 bool cmd_write_fifo_put = false; 711 bool cmd_write_fifo_get = false; 712 713 bool cmd_sc_fifo_put = false; 714 bool cmd_sc_fifo_get = false; 715 716 bool write_to_init_cmd_fifo_put = false; 717 bool write_to_init_cmd_fifo_get = false; 718 bool write_to_init_cmd_fifo_inst = false; 719 size_t write_to_init_cmd_fifo_srcid = 0; 694 m_xram_rsp_to_init_cmd_cache_id_fifo.init(); 695 #endif 696 697 r_ixr_cmd_cpt = 0; 698 r_alloc_dir_reset_cpt = 0; 699 r_alloc_heap_reset_cpt = 0; 700 701 r_copies_limit = 3; 702 703 // Activity counters 704 m_cpt_cycles = 0; 705 m_cpt_read = 0; 706 m_cpt_read_miss = 0; 707 m_cpt_write = 0; 708 m_cpt_write_miss = 0; 709 m_cpt_write_cells = 0; 710 m_cpt_write_dirty = 0; 711 m_cpt_update = 0; 712 m_cpt_update_mult = 0; 713 m_cpt_inval_brdcast = 0; 714 m_cpt_inval = 0; 715 m_cpt_inval_mult = 0; 716 m_cpt_cleanup = 0; 717 m_cpt_ll = 0; 718 m_cpt_sc = 0; 719 m_cpt_trt_full = 0; 720 m_cpt_trt_rb = 0; 721 722 return; 723 } 724 725 bool cmd_read_fifo_put = false; 726 bool cmd_read_fifo_get = false; 727 728 bool cmd_write_fifo_put = false; 729 bool cmd_write_fifo_get = false; 730 731 bool cmd_sc_fifo_put = false; 732 bool cmd_sc_fifo_get = false; 733 734 bool write_to_init_cmd_fifo_put = false; 735 bool write_to_init_cmd_fifo_get = false; 736 bool write_to_init_cmd_fifo_inst = false; 737 size_t write_to_init_cmd_fifo_srcid = 0; 720 738 721 739 #if L1_MULTI_CACHE 722 723 #endif 724 725 bool xram_rsp_to_init_cmd_fifo_put= false;726 bool xram_rsp_to_init_cmd_fifo_get= false;727 bool xram_rsp_to_init_cmd_fifo_inst= false;728 size_t xram_rsp_to_init_cmd_fifo_srcid= 0;740 size_t write_to_init_cmd_fifo_cache_id = 0; 741 #endif 742 743 bool xram_rsp_to_init_cmd_fifo_put = false; 744 bool xram_rsp_to_init_cmd_fifo_get = false; 745 bool xram_rsp_to_init_cmd_fifo_inst = false; 746 size_t xram_rsp_to_init_cmd_fifo_srcid = 0; 729 747 730 748 #if L1_MULTI_CACHE 731 732 #endif 733 734 bool sc_to_init_cmd_fifo_put= false;735 bool sc_to_init_cmd_fifo_get= false;736 bool sc_to_init_cmd_fifo_inst= false;737 size_t sc_to_init_cmd_fifo_srcid= 0;749 size_t xram_rsp_to_init_cmd_fifo_cache_id = 0; 750 #endif 751 752 bool sc_to_init_cmd_fifo_put = false; 753 bool sc_to_init_cmd_fifo_get = false; 754 bool sc_to_init_cmd_fifo_inst = false; 755 size_t sc_to_init_cmd_fifo_srcid = 0; 738 756 739 757 #if L1_MULTI_CACHE 740 741 #endif 742 743 m_debug_global = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;744 m_debug_tgt_cmd_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;745 m_debug_tgt_rsp_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;746 m_debug_init_cmd_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;747 m_debug_init_rsp_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;748 m_debug_read_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;749 m_debug_write_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;750 m_debug_sc_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;751 m_debug_cleanup_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;752 m_debug_ixr_cmd_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;753 m_debug_ixr_rsp_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;754 m_debug_xram_rsp_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;755 756 757 #if DEBUG_MEMC_GLOBAL 758 if( m_debug_global ) 759 { 760 std::cout << "---------------------------------------------" << std::dec << std::endl;761 std::cout<< "MEM_CACHE " << m_srcid_ini << " ; Time = " << m_cpt_cycles << std::endl758 size_t sc_to_init_cmd_fifo_cache_id = 0; 759 #endif 760 761 m_debug_global = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 762 m_debug_tgt_cmd_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 763 m_debug_tgt_rsp_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 764 m_debug_init_cmd_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 765 m_debug_init_rsp_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 766 m_debug_read_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 767 m_debug_write_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 768 m_debug_sc_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 769 m_debug_cleanup_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 770 m_debug_ixr_cmd_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 771 m_debug_ixr_rsp_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 772 m_debug_xram_rsp_fsm = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok; 773 774 #if DEBUG_MEMC_GLOBAL 775 if( m_debug_global ) 776 { 777 std::cout 778 << "---------------------------------------------" << std::dec << std::endl 779 << "MEM_CACHE " << m_srcid_ini << " ; Time = " << m_cpt_cycles << std::endl 762 780 << " - TGT_CMD FSM = " << tgt_cmd_fsm_str[r_tgt_cmd_fsm] << std::endl 763 781 << " - TGT_RSP FSM = " << tgt_rsp_fsm_str[r_tgt_rsp_fsm] << std::endl … … 775 793 << " - ALLOC_UPT FSM = " << alloc_upt_fsm_str[r_alloc_upt_fsm] << std::endl 776 794 << " - ALLOC_HEAP FSM = " << alloc_heap_fsm_str[r_alloc_heap_fsm] << std::endl; 777 } 778 #endif 779 780 //////////////////////////////////////////////////////////////////////////////////// 781 // TGT_CMD FSM 782 //////////////////////////////////////////////////////////////////////////////////// 783 // The TGT_CMD_FSM controls the incoming VCI command pakets from the processors 784 // 785 // There is 3 types of accepted commands : 786 // - READ : a READ request has a length of 1 VCI cell. It can be a single word 787 // or an entire cache line, depending on the PLEN value. 788 // - WRITE : a WRITE request has a maximum length of 16 cells, and can only 789 // concern words in a same line. 790 // - SC : The SC request has a length of 2 cells or 4 cells. 791 //////////////////////////////////////////////////////////////////////////////////// 792 793 switch ( r_tgt_cmd_fsm.read() ) 795 } 796 #endif 797 798 //////////////////////////////////////////////////////////////////////////////////// 799 // TGT_CMD FSM 800 //////////////////////////////////////////////////////////////////////////////////// 801 // The TGT_CMD_FSM controls the incoming VCI command pakets from the processors 802 // 803 // There is 3 types of accepted commands : 804 // - READ : a READ request has a length of 1 VCI cell. It can be a single word 805 // or an entire cache line, depending on the PLEN value. 806 // - WRITE : a WRITE request has a maximum length of 16 cells, and can only 807 // concern words in a same line. 808 // - SC : The SC request has a length of 2 cells or 4 cells. 809 //////////////////////////////////////////////////////////////////////////////////// 810 811 switch ( r_tgt_cmd_fsm.read() ) 812 { 813 ////////////////// 814 case TGT_CMD_IDLE: 815 if ( p_vci_tgt.cmdval ) 816 { 817 818 #if DEBUG_MEMC_TGT_CMD 819 if( m_debug_tgt_cmd_fsm ) 820 { 821 std::cout 822 << " <MEMC " << name() << ".TGT_CMD_IDLE> Receive command from srcid " 823 << std::dec << p_vci_tgt.srcid.read() 824 << " / for address " << std::hex << p_vci_tgt.address.read() << std::endl; 825 } 826 #endif 827 // checking segmentation violation 828 vci_addr_t address = p_vci_tgt.address.read(); 829 uint32_t plen = p_vci_tgt.plen.read(); 830 bool found = false; 831 for ( size_t seg_id = 0 ; seg_id < m_nseg ; seg_id++ ) 832 { 833 if ( m_seg[seg_id]->contains(address) && 834 m_seg[seg_id]->contains(address + plen - vci_param::B) ) 835 { 836 found = true; 837 } 838 } 839 if ( not found ) 840 { 841 std::cout << "VCI_MEM_CACHE ERROR " << name() << std::endl; 842 std::cout 843 << "Out of segment VCI address in TGT_CMD_IDLE state (address = " 844 << std::hex << address << ", srcid = " << p_vci_tgt.srcid.read() 845 << std::dec << ", cycle = " << m_cpt_cycles << ")" << std::endl; 846 exit(0); 847 } 848 849 if ( p_vci_tgt.cmd.read() == vci_param::CMD_READ ) 850 { 851 r_tgt_cmd_fsm = TGT_CMD_READ; 852 } 853 else if ( p_vci_tgt.cmd.read() == vci_param::CMD_WRITE ) 854 { 855 r_tgt_cmd_fsm = TGT_CMD_WRITE; 856 } 857 else if ( p_vci_tgt.cmd.read() == vci_param::CMD_STORE_COND ) 858 { 859 r_tgt_cmd_fsm = TGT_CMD_ATOMIC; 860 } 861 else 862 { 863 std::cout << "VCI_MEM_CACHE ERROR " << name() 864 << " TGT_CMD_IDLE state" << std::endl; 865 std::cout << " illegal VCI command type" << std::endl; 866 exit(0); 867 } 868 } 869 break; 870 871 ////////////////// 872 case TGT_CMD_READ: 873 if ((m_x[(vci_addr_t)p_vci_tgt.address.read()]+(p_vci_tgt.plen.read()>>2)) > 16) 874 { 875 std::cout 876 << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state" 877 << std::endl; 878 std::cout 879 << " illegal address/plen combination for VCI read command" << std::endl; 880 exit(0); 881 } 882 if ( !p_vci_tgt.eop.read() ) 883 { 884 std::cout 885 << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state" 886 << std::endl; 887 std::cout 888 << " read command packets must contain one single flit" 889 << std::endl; 890 exit(0); 891 } 892 893 if ( p_vci_tgt.cmdval && m_cmd_read_addr_fifo.wok() ) 894 { 895 896 #if DEBUG_MEMC_TGT_CMD 897 if( m_debug_tgt_cmd_fsm ) 898 { 899 std::cout << " <MEMC " << name() << ".TGT_CMD_READ> Push into read_fifo:" 900 << " address = " << std::hex << p_vci_tgt.address.read() 901 << " srcid = " << std::dec << p_vci_tgt.srcid.read() 902 << " trdid = " << p_vci_tgt.trdid.read() 903 << " plen = " << std::dec << p_vci_tgt.plen.read() << std::endl; 904 } 905 #endif 906 cmd_read_fifo_put = true; 907 m_cpt_read++; 908 r_tgt_cmd_fsm = TGT_CMD_IDLE; 909 } 910 break; 911 912 /////////////////// 913 case TGT_CMD_WRITE: 914 if ( p_vci_tgt.cmdval && m_cmd_write_addr_fifo.wok() ) 915 { 916 917 #if DEBUG_MEMC_TGT_CMD 918 if( m_debug_tgt_cmd_fsm ) 919 { 920 std::cout << " <MEMC " << name() << ".TGT_CMD_WRITE> Push into write_fifo:" 921 << " address = " << std::hex << p_vci_tgt.address.read() 922 << " srcid = " << std::dec << p_vci_tgt.srcid.read() 923 << " trdid = " << p_vci_tgt.trdid.read() 924 << " wdata = " << std::hex << p_vci_tgt.wdata.read() 925 << " be = " << p_vci_tgt.be.read() 926 << " plen = " << std::dec << p_vci_tgt.plen.read() << std::endl; 927 } 928 #endif 929 cmd_write_fifo_put = true; 930 if( p_vci_tgt.eop ) r_tgt_cmd_fsm = TGT_CMD_IDLE; 931 } 932 break; 933 934 //////////////////// 935 case TGT_CMD_ATOMIC: 936 if ( (p_vci_tgt.plen.read() != 8) && (p_vci_tgt.plen.read() != 16) ) 937 { 938 std::cout 939 << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_ATOMIC state" 940 << std::endl 941 << "illegal format for sc command " << std::endl; 942 943 exit(0); 944 } 945 946 if ( p_vci_tgt.cmdval && m_cmd_sc_addr_fifo.wok() ) 947 { 948 949 #if DEBUG_MEMC_TGT_CMD 950 if( m_debug_tgt_cmd_fsm ) 951 { 952 std::cout << " <MEMC " << name() << ".TGT_CMD_ATOMIC> Pushing command into cmd_sc_fifo:" 953 << " address = " << std::hex << p_vci_tgt.address.read() 954 << " srcid = " << std::dec << p_vci_tgt.srcid.read() 955 << " trdid = " << p_vci_tgt.trdid.read() 956 << " wdata = " << std::hex << p_vci_tgt.wdata.read() 957 << " be = " << p_vci_tgt.be.read() 958 << " plen = " << std::dec << p_vci_tgt.plen.read() << std::endl; 959 } 960 #endif 961 cmd_sc_fifo_put = true; 962 if( p_vci_tgt.eop ) r_tgt_cmd_fsm = TGT_CMD_IDLE; 963 } 964 break; 965 } // end switch tgt_cmd_fsm 966 967 ///////////////////////////////////////////////////////////////////////// 968 // INIT_RSP FSM 969 ///////////////////////////////////////////////////////////////////////// 970 // This FSM controls the response to the update or inval coherence 971 // requests sent by the memory cache to the L1 caches and update the UPT. 972 // 973 // It can be update or inval requests initiated by the WRITE FSM, 974 // or inval requests initiated by the XRAM_RSP FSM. 975 // It can also be a direct request from the WRITE FSM. 976 // 977 // The FSM decrements the proper entry in UPT. 978 // It sends a request to the TGT_RSP FSM to complete the pending 979 // write transaction (acknowledge response to the writer processor), 980 // and clear the UPT entry when all responses have been received. 981 // 982 // All those response packets are one word, compact 983 // packets complying with the VCI advanced format. 984 // The index in the Table is defined in the RTRDID field, and 985 // the transaction type is defined in the UPT entry. 986 ///////////////////////////////////////////////////////////////////// 987 988 switch ( r_init_rsp_fsm.read() ) 989 { 990 /////////////////// 991 case INIT_RSP_IDLE: // wait a response for a coherence transaction 992 if ( p_vci_ini.rspval ) 993 { 994 995 #if DEBUG_MEMC_INIT_RSP 996 if( m_debug_init_rsp_fsm ) 997 { 998 std::cout << " <MEMC " << name() << ".INIT_RSP_IDLE> Response for UPT entry " 999 << p_vci_ini.rtrdid.read() << std::endl; 1000 } 1001 #endif 1002 if ( p_vci_ini.rtrdid.read() >= m_update_tab.size() ) 1003 { 1004 std::cout 1005 << "VCI_MEM_CACHE ERROR " << name() 1006 << " INIT_RSP_IDLE state" << std::endl 1007 << "index too large for UPT: " 1008 << " / rtrdid = " << std::dec << p_vci_ini.rtrdid.read() 1009 << " / UPT size = " << std::dec << m_update_tab.size() 1010 << std::endl; 1011 1012 exit(0); 1013 } 1014 if ( !p_vci_ini.reop.read() ) 1015 { 1016 std::cout 1017 << "VCI_MEM_CACHE ERROR " << name() 1018 << " INIT_RSP_IDLE state" << std::endl 1019 << "all coherence response packets must be one flit" 1020 << std::endl; 1021 1022 exit(0); 1023 } 1024 1025 r_init_rsp_upt_index = p_vci_ini.rtrdid.read(); 1026 r_init_rsp_fsm = INIT_RSP_UPT_LOCK; 1027 } 1028 else if( r_write_to_init_rsp_req.read() ) 1029 { 1030 r_init_rsp_upt_index = r_write_to_init_rsp_upt_index.read(); 1031 r_write_to_init_rsp_req = false; 1032 r_init_rsp_fsm = INIT_RSP_UPT_LOCK; 1033 } 1034 break; 1035 1036 /////////////////////// 1037 case INIT_RSP_UPT_LOCK: // decrement the number of expected responses 1038 if ( r_alloc_upt_fsm.read() == ALLOC_UPT_INIT_RSP ) 1039 { 1040 size_t count = 0; 1041 bool valid = m_update_tab.decrement(r_init_rsp_upt_index.read(), count); 1042 1043 #if DEBUG_MEMC_INIT_RSP 1044 if( m_debug_init_rsp_fsm ) 1045 { 1046 std::cout << " <MEMC " << name() << ".INIT_RSP_UPT_LOCK> Decrement the responses counter for UPT:" 1047 << " entry = " << r_init_rsp_upt_index.read() 1048 << " / rsp_count = " << std::dec << count << std::endl; 1049 } 1050 #endif 1051 if ( not valid ) 1052 { 1053 std::cout << "VCI_MEM_CACHE ERROR " << name() 1054 << " INIT_RSP_UPT_LOCK state" << std::endl 1055 << "unsuccessful access to decrement the UPT" << std::endl; 1056 1057 exit(0); 1058 } 1059 1060 if ( count == 0 ) r_init_rsp_fsm = INIT_RSP_UPT_CLEAR; 1061 else r_init_rsp_fsm = INIT_RSP_IDLE; 1062 } 1063 break; 1064 1065 //////////////////////// 1066 case INIT_RSP_UPT_CLEAR: // clear the UPT entry 1067 if ( r_alloc_upt_fsm.read() == ALLOC_UPT_INIT_RSP ) 1068 { 1069 r_init_rsp_srcid = m_update_tab.srcid(r_init_rsp_upt_index.read()); 1070 r_init_rsp_trdid = m_update_tab.trdid(r_init_rsp_upt_index.read()); 1071 r_init_rsp_pktid = m_update_tab.pktid(r_init_rsp_upt_index.read()); 1072 r_init_rsp_nline = m_update_tab.nline(r_init_rsp_upt_index.read()); 1073 bool need_rsp = m_update_tab.need_rsp(r_init_rsp_upt_index.read()); 1074 1075 if ( need_rsp ) r_init_rsp_fsm = INIT_RSP_END; 1076 else r_init_rsp_fsm = INIT_RSP_IDLE; 1077 1078 m_update_tab.clear(r_init_rsp_upt_index.read()); 1079 1080 #if DEBUG_MEMC_INIT_RSP 1081 if ( m_debug_init_rsp_fsm ) 1082 { 1083 std::cout << " <MEMC " << name() << ".INIT_RSP_UPT_CLEAR> Clear UPT entry " 1084 << r_init_rsp_upt_index.read() << std::endl; 1085 } 1086 #endif 1087 } 1088 break; 1089 1090 ////////////////// 1091 case INIT_RSP_END: // Post a request to TGT_RSP FSM 1092 if ( !r_init_rsp_to_tgt_rsp_req ) 1093 { 1094 r_init_rsp_to_tgt_rsp_req = true; 1095 r_init_rsp_to_tgt_rsp_srcid = r_init_rsp_srcid.read(); 1096 r_init_rsp_to_tgt_rsp_trdid = r_init_rsp_trdid.read(); 1097 r_init_rsp_to_tgt_rsp_pktid = r_init_rsp_pktid.read(); 1098 r_init_rsp_fsm = INIT_RSP_IDLE; 1099 1100 #if DEBUG_MEMC_INIT_RSP 1101 if ( m_debug_init_rsp_fsm ) 1102 { 1103 std::cout 1104 << " <MEMC " << name() 1105 << ".INIT_RSP_END> Request TGT_RSP FSM to send a response to srcid " 1106 << r_init_rsp_srcid.read() 1107 << std::endl; 1108 } 1109 #endif 1110 } 1111 break; 1112 } // end switch r_init_rsp_fsm 1113 1114 //////////////////////////////////////////////////////////////////////////////////// 1115 // READ FSM 1116 //////////////////////////////////////////////////////////////////////////////////// 1117 // The READ FSM controls the VCI read requests. 1118 // It takes the lock protecting the cache directory to check the cache line status: 1119 // - In case of HIT 1120 // The fsm copies the data (one line, or one single word) 1121 // in the r_read_to_tgt_rsp buffer. It waits if this buffer is not empty. 1122 // The requesting initiator is registered in the cache directory. 1123 // If the number of copy is larger than 1, the new copy is registered 1124 // in the HEAP. 1125 // If the number of copy is larger than the threshold, the HEAP is cleared, 1126 // and the corresponding line switches to the counter mode. 1127 // - In case of MISS 1128 // The READ fsm takes the lock protecting the transaction tab. 1129 // If a read transaction to the XRAM for this line already exists, 1130 // or if the transaction tab is full, the fsm is stalled. 1131 // If a TRT entry is free, the READ request is registered in TRT, 1132 // it is consumed in the request FIFO, and transmited to the IXR_CMD FSM. 1133 // The READ FSM returns in the IDLE state as the read transaction will be 1134 // completed when the missing line will be received. 1135 //////////////////////////////////////////////////////////////////////////////////// 1136 1137 switch ( r_read_fsm.read() ) 1138 { 1139 /////////////// 1140 case READ_IDLE: 1141 // waiting a read request 794 1142 { 795 ////////////////// 796 case TGT_CMD_IDLE: 797 { 798 if ( p_vci_tgt.cmdval ) 799 { 800 801 #if DEBUG_MEMC_TGT_CMD 802 if( m_debug_tgt_cmd_fsm ) 803 { 804 std::cout << " <MEMC " << name() << ".TGT_CMD_IDLE> Receive command from srcid " << std::dec << p_vci_tgt.srcid.read() 805 << " / for address " << std::hex << p_vci_tgt.address.read() << std::endl; 806 } 807 #endif 808 // checking segmentation violation 809 vci_addr_t address = p_vci_tgt.address.read(); 810 uint32_t plen = p_vci_tgt.plen.read(); 811 bool found = false; 812 for ( size_t seg_id = 0 ; seg_id < m_nseg ; seg_id++ ) 813 { 814 if ( m_seg[seg_id]->contains(address) && 815 m_seg[seg_id]->contains(address + plen - vci_param::B) ) 816 { 817 found = true; 818 } 819 } 820 if ( not found ) 821 { 822 std::cout << "VCI_MEM_CACHE ERROR " << name() << std::endl; 823 std::cout << "Out of segment VCI address in TGT_CMD_IDLE state (address = " << std::hex << address << ", srcid = " << p_vci_tgt.srcid.read() << std::dec << ", cycle = " << m_cpt_cycles << ")" << std::endl; 824 exit(0); 825 } 826 827 if ( p_vci_tgt.cmd.read() == vci_param::CMD_READ ) 828 { 829 r_tgt_cmd_fsm = TGT_CMD_READ; 830 } 831 else if ( p_vci_tgt.cmd.read() == vci_param::CMD_WRITE ) 832 { 833 r_tgt_cmd_fsm = TGT_CMD_WRITE; 834 } 835 else if ( p_vci_tgt.cmd.read() == vci_param::CMD_STORE_COND ) 836 { 837 r_tgt_cmd_fsm = TGT_CMD_ATOMIC; 838 } 839 else 840 { 841 std::cout << "VCI_MEM_CACHE ERROR " << name() 842 << " TGT_CMD_IDLE state" << std::endl; 843 std::cout << " illegal VCI command type" << std::endl; 844 exit(0); 845 } 846 } 847 break; 848 } 849 ////////////////// 850 case TGT_CMD_READ: 851 { 852 if ((m_x[(vci_addr_t)p_vci_tgt.address.read()]+(p_vci_tgt.plen.read()>>2)) > 16) 853 { 854 std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state" << std::endl; 855 std::cout << " illegal address/plen combination for VCI read command" << std::endl; 856 exit(0); 857 } 858 if ( !p_vci_tgt.eop.read() ) 859 { 860 std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_READ state" << std::endl; 861 std::cout << " read command packets must contain one single flit" << std::endl; 862 exit(0); 863 } 864 865 if ( p_vci_tgt.cmdval && m_cmd_read_addr_fifo.wok() ) 866 { 867 868 #if DEBUG_MEMC_TGT_CMD 869 if( m_debug_tgt_cmd_fsm ) 870 { 871 std::cout << " <MEMC " << name() << ".TGT_CMD_READ> Push into read_fifo:" 872 << " address = " << std::hex << p_vci_tgt.address.read() 873 << " srcid = " << std::dec << p_vci_tgt.srcid.read() 874 << " trdid = " << p_vci_tgt.trdid.read() 875 << " plen = " << std::dec << p_vci_tgt.plen.read() << std::endl; 876 } 877 #endif 878 cmd_read_fifo_put = true; 879 m_cpt_read++; 880 r_tgt_cmd_fsm = TGT_CMD_IDLE; 881 } 882 break; 883 } 884 /////////////////// 885 case TGT_CMD_WRITE: 886 { 887 if ( p_vci_tgt.cmdval && m_cmd_write_addr_fifo.wok() ) 888 { 889 890 #if DEBUG_MEMC_TGT_CMD 891 if( m_debug_tgt_cmd_fsm ) 892 { 893 std::cout << " <MEMC " << name() << ".TGT_CMD_WRITE> Push into write_fifo:" 894 << " address = " << std::hex << p_vci_tgt.address.read() 895 << " srcid = " << std::dec << p_vci_tgt.srcid.read() 896 << " trdid = " << p_vci_tgt.trdid.read() 897 << " wdata = " << std::hex << p_vci_tgt.wdata.read() 898 << " be = " << p_vci_tgt.be.read() 899 << " plen = " << std::dec << p_vci_tgt.plen.read() << std::endl; 900 } 901 #endif 902 cmd_write_fifo_put = true; 903 if( p_vci_tgt.eop ) r_tgt_cmd_fsm = TGT_CMD_IDLE; 904 } 905 break; 906 } 907 //////////////////// 908 case TGT_CMD_ATOMIC: 909 { 910 if ( (p_vci_tgt.plen.read() != 8) && (p_vci_tgt.plen.read() != 16) ) 911 { 912 std::cout << "VCI_MEM_CACHE ERROR " << name() << " TGT_CMD_ATOMIC state" << std::endl; 913 std::cout << "illegal format for sc command " << std::endl; 914 exit(0); 915 } 916 917 if ( p_vci_tgt.cmdval && m_cmd_sc_addr_fifo.wok() ) 918 { 919 920 #if DEBUG_MEMC_TGT_CMD 921 if( m_debug_tgt_cmd_fsm ) 922 { 923 std::cout << " <MEMC " << name() << ".TGT_CMD_ATOMIC> Pushing command into cmd_sc_fifo:" 924 << " address = " << std::hex << p_vci_tgt.address.read() 925 << " srcid = " << std::dec << p_vci_tgt.srcid.read() 926 << " trdid = " << p_vci_tgt.trdid.read() 927 << " wdata = " << std::hex << p_vci_tgt.wdata.read() 928 << " be = " << p_vci_tgt.be.read() 929 << " plen = " << std::dec << p_vci_tgt.plen.read() << std::endl; 930 } 931 #endif 932 cmd_sc_fifo_put = true; 933 if( p_vci_tgt.eop ) r_tgt_cmd_fsm = TGT_CMD_IDLE; 934 } 935 break; 936 } 937 } // end switch tgt_cmd_fsm 938 939 ///////////////////////////////////////////////////////////////////////// 940 // INIT_RSP FSM 941 ///////////////////////////////////////////////////////////////////////// 942 // This FSM controls the response to the update or inval coherence 943 // requests sent by the memory cache to the L1 caches and update the UPT. 944 // 945 // It can be update or inval requests initiated by the WRITE FSM, 946 // or inval requests initiated by the XRAM_RSP FSM. 947 // It can also be a direct request from the WRITE FSM. 948 // 949 // The FSM decrements the proper entry in UPT. 950 // It sends a request to the TGT_RSP FSM to complete the pending 951 // write transaction (acknowledge response to the writer processor), 952 // and clear the UPT entry when all responses have been received. 953 // 954 // All those response packets are one word, compact 955 // packets complying with the VCI advanced format. 956 // The index in the Table is defined in the RTRDID field, and 957 // the transaction type is defined in the UPT entry. 958 ///////////////////////////////////////////////////////////////////// 959 960 switch ( r_init_rsp_fsm.read() ) 1143 if (m_cmd_read_addr_fifo.rok()) 1144 { 1145 1146 #if DEBUG_MEMC_READ 1147 if( m_debug_read_fsm ) 1148 { 1149 std::cout << " <MEMC " << name() << ".READ_IDLE> Read request:" 1150 << " srcid = " << std::dec << m_cmd_read_srcid_fifo.read() 1151 << " / address = " << std::hex << m_cmd_read_addr_fifo.read() 1152 << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl; 1153 } 1154 #endif 1155 r_read_fsm = READ_DIR_REQ; 1156 } 1157 break; 1158 } 1159 1160 /////////////////// 1161 case READ_DIR_REQ: 1162 // Get the lock to the directory 961 1163 { 962 /////////////////// 963 case INIT_RSP_IDLE: // wait a response for a coherence transaction 964 { 965 if ( p_vci_ini.rspval ) 966 { 967 968 #if DEBUG_MEMC_INIT_RSP 969 if( m_debug_init_rsp_fsm ) 970 { 971 std::cout << " <MEMC " << name() << ".INIT_RSP_IDLE> Response for UPT entry " 972 << p_vci_ini.rtrdid.read() << std::endl; 973 } 974 #endif 975 if ( p_vci_ini.rtrdid.read() >= m_update_tab.size() ) 976 { 977 std::cout << "VCI_MEM_CACHE ERROR " << name() 978 << " INIT_RSP_IDLE state" << std::endl 979 << "index too large for UPT: " 980 << " / rtrdid = " << std::dec << p_vci_ini.rtrdid.read() 981 << " / UPT size = " << std::dec << m_update_tab.size() << std::endl; 982 exit(0); 983 } 984 if ( !p_vci_ini.reop.read() ) 985 { 986 std::cout << "VCI_MEM_CACHE ERROR " << name() 987 << " INIT_RSP_IDLE state" << std::endl; 988 std::cout << "all coherence response packets must be one flit" << std::endl; 989 exit(0); 990 } 991 992 r_init_rsp_upt_index = p_vci_ini.rtrdid.read(); 993 r_init_rsp_fsm = INIT_RSP_UPT_LOCK; 994 } 995 else if( r_write_to_init_rsp_req.read() ) 996 { 997 r_init_rsp_upt_index = r_write_to_init_rsp_upt_index.read(); 998 r_write_to_init_rsp_req = false; 999 r_init_rsp_fsm = INIT_RSP_UPT_LOCK; 1000 } 1001 break; 1002 } 1003 /////////////////////// 1004 case INIT_RSP_UPT_LOCK: // decrement the number of expected responses 1005 { 1006 if ( r_alloc_upt_fsm.read() == ALLOC_UPT_INIT_RSP ) 1007 { 1008 size_t count = 0; 1009 bool valid = m_update_tab.decrement(r_init_rsp_upt_index.read(), count); 1010 1011 #if DEBUG_MEMC_INIT_RSP 1012 if( m_debug_init_rsp_fsm ) 1013 { 1014 std::cout << " <MEMC " << name() << ".INIT_RSP_UPT_LOCK> Decrement the responses counter for UPT:" 1015 << " entry = " << r_init_rsp_upt_index.read() 1016 << " / rsp_count = " << std::dec << count << std::endl; 1017 } 1018 #endif 1019 if ( not valid ) 1020 { 1021 std::cout << "VCI_MEM_CACHE ERROR " << name() 1022 << " INIT_RSP_UPT_LOCK state" << std::endl 1023 << "unsuccessful access to decrement the UPT" << std::endl; 1024 exit(0); 1025 } 1026 1027 if ( count == 0 ) r_init_rsp_fsm = INIT_RSP_UPT_CLEAR; 1028 else r_init_rsp_fsm = INIT_RSP_IDLE; 1029 } 1030 break; 1031 } 1032 //////////////////////// 1033 case INIT_RSP_UPT_CLEAR: // clear the UPT entry 1034 { 1035 if ( r_alloc_upt_fsm.read() == ALLOC_UPT_INIT_RSP ) 1036 { 1037 r_init_rsp_srcid = m_update_tab.srcid(r_init_rsp_upt_index.read()); 1038 r_init_rsp_trdid = m_update_tab.trdid(r_init_rsp_upt_index.read()); 1039 r_init_rsp_pktid = m_update_tab.pktid(r_init_rsp_upt_index.read()); 1040 r_init_rsp_nline = m_update_tab.nline(r_init_rsp_upt_index.read()); 1041 bool need_rsp = m_update_tab.need_rsp(r_init_rsp_upt_index.read()); 1042 1043 if ( need_rsp ) r_init_rsp_fsm = INIT_RSP_END; 1044 else r_init_rsp_fsm = INIT_RSP_IDLE; 1045 1046 m_update_tab.clear(r_init_rsp_upt_index.read()); 1047 1048 #if DEBUG_MEMC_INIT_RSP 1049 if ( m_debug_init_rsp_fsm ) 1050 { 1051 std::cout << " <MEMC " << name() << ".INIT_RSP_UPT_CLEAR> Clear UPT entry " 1052 << r_init_rsp_upt_index.read() << std::endl; 1053 } 1054 #endif 1055 } 1056 break; 1057 } 1058 ////////////////// 1059 case INIT_RSP_END: // Post a request to TGT_RSP FSM 1060 { 1061 if ( !r_init_rsp_to_tgt_rsp_req ) 1062 { 1063 r_init_rsp_to_tgt_rsp_req = true; 1064 r_init_rsp_to_tgt_rsp_srcid = r_init_rsp_srcid.read(); 1065 r_init_rsp_to_tgt_rsp_trdid = r_init_rsp_trdid.read(); 1066 r_init_rsp_to_tgt_rsp_pktid = r_init_rsp_pktid.read(); 1067 r_init_rsp_fsm = INIT_RSP_IDLE; 1068 1069 #if DEBUG_MEMC_INIT_RSP 1070 if ( m_debug_init_rsp_fsm ) 1071 { 1072 std::cout << " <MEMC " << name() << ".INIT_RSP_END> Request TGT_RSP FSM to send a response to srcid " 1073 << r_init_rsp_srcid.read() << std::endl; 1074 } 1075 #endif 1076 } 1077 break; 1078 } 1079 } // end switch r_init_rsp_fsm 1080 1081 //////////////////////////////////////////////////////////////////////////////////// 1082 // READ FSM 1083 //////////////////////////////////////////////////////////////////////////////////// 1084 // The READ FSM controls the VCI read requests. 1085 // It takes the lock protecting the cache directory to check the cache line status: 1086 // - In case of HIT 1087 // The fsm copies the data (one line, or one single word) 1088 // in the r_read_to_tgt_rsp buffer. It waits if this buffer is not empty. 1089 // The requesting initiator is registered in the cache directory. 1090 // If the number of copy is larger than 1, the new copy is registered 1091 // in the HEAP. 1092 // If the number of copy is larger than the threshold, the HEAP is cleared, 1093 // and the corresponding line switches to the counter mode. 1094 // - In case of MISS 1095 // The READ fsm takes the lock protecting the transaction tab. 1096 // If a read transaction to the XRAM for this line already exists, 1097 // or if the transaction tab is full, the fsm is stalled. 1098 // If a TRT entry is free, the READ request is registered in TRT, 1099 // it is consumed in the request FIFO, and transmited to the IXR_CMD FSM. 1100 // The READ FSM returns in the IDLE state as the read transaction will be 1101 // completed when the missing line will be received. 1102 //////////////////////////////////////////////////////////////////////////////////// 1103 1104 switch ( r_read_fsm.read() ) 1164 if ( r_alloc_dir_fsm.read() == ALLOC_DIR_READ ) 1165 { 1166 r_read_fsm = READ_DIR_LOCK; 1167 } 1168 1169 #if DEBUG_MEMC_READ 1170 if( m_debug_read_fsm ) 1171 { 1172 std::cout 1173 << " <MEMC " << name() << ".READ_DIR_REQ> Requesting DIR lock " 1174 << std::endl; 1175 } 1176 #endif 1177 break; 1178 } 1179 1180 /////////////////// 1181 case READ_DIR_LOCK: 1182 // check directory for hit / miss 1105 1183 { 1106 /////////////// 1107 case READ_IDLE: // waiting a read request 1108 { 1109 if (m_cmd_read_addr_fifo.rok()) 1110 { 1184 if ( r_alloc_dir_fsm.read() == ALLOC_DIR_READ ) 1185 { 1186 size_t way = 0; 1187 DirectoryEntry entry = 1188 m_cache_directory.read(m_cmd_read_addr_fifo.read(), way); 1189 1190 r_read_is_cnt = entry.is_cnt; 1191 r_read_dirty = entry.dirty; 1192 r_read_lock = entry.lock; 1193 r_read_tag = entry.tag; 1194 r_read_way = way; 1195 r_read_count = entry.count; 1196 r_read_copy = entry.owner.srcid; 1197 1198 #if L1_MULTI_CACHE 1199 r_read_copy_cache = entry.owner.cache_id; 1200 #endif 1201 r_read_copy_inst = entry.owner.inst; 1202 r_read_ptr = entry.ptr; // pointer to the heap 1203 1204 bool cached_read = (m_cmd_read_trdid_fifo.read() & 0x1); 1205 if( entry.valid ) // hit 1206 { 1207 // test if we need to register a new copy in the heap 1208 if ( entry.is_cnt || (entry.count == 0) || !cached_read ) 1209 { 1210 r_read_fsm = READ_DIR_HIT; 1211 } 1212 else 1213 { 1214 r_read_fsm = READ_HEAP_REQ; 1215 } 1216 } 1217 else // miss 1218 { 1219 r_read_fsm = READ_TRT_LOCK; 1220 } 1111 1221 1112 1222 #if DEBUG_MEMC_READ 1113 if( m_debug_read_fsm ) 1114 { 1115 std::cout << " <MEMC " << name() << ".READ_IDLE> Read request:" 1116 << " srcid = " << std::dec << m_cmd_read_srcid_fifo.read() 1117 << " / address = " << std::hex << m_cmd_read_addr_fifo.read() 1118 << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl; 1119 } 1120 #endif 1121 r_read_fsm = READ_DIR_LOCK; 1122 } 1123 break; 1124 } 1125 /////////////////// 1126 case READ_DIR_LOCK: // check directory for hit / miss 1127 { 1128 if ( r_alloc_dir_fsm.read() == ALLOC_DIR_READ ) 1129 { 1130 size_t way = 0; 1131 DirectoryEntry entry = m_cache_directory.read(m_cmd_read_addr_fifo.read(), way); 1132 1133 r_read_is_cnt = entry.is_cnt; 1134 r_read_dirty = entry.dirty; 1135 r_read_lock = entry.lock; 1136 r_read_tag = entry.tag; 1137 r_read_way = way; 1138 r_read_count = entry.count; 1139 r_read_copy = entry.owner.srcid; 1140 1223 if( m_debug_read_fsm ) 1224 { 1225 std::cout 1226 << " <MEMC " << name() << ".READ_DIR_LOCK> Accessing directory: " 1227 << " address = " << std::hex << m_cmd_read_addr_fifo.read() 1228 << " / hit = " << std::dec << entry.valid 1229 << " / count = " <<std::dec << entry.count 1230 << " / is_cnt = " << entry.is_cnt << std::endl; 1231 } 1232 #endif 1233 } 1234 else 1235 { 1236 std::cout 1237 << "VCI_MEM_CACHE ERROR " << name() 1238 << " READ_DIR_LOCK state" << std::endl 1239 << "Bad DIR allocation" << std::endl; 1240 1241 exit(0); 1242 } 1243 break; 1244 } 1245 1246 ////////////////// 1247 case READ_DIR_HIT: 1248 { 1249 // read data in cache & update the directory 1250 // we enter this state in 3 cases: 1251 // - the read request is uncachable 1252 // - the cache line is in counter mode 1253 // - the cache line is valid but not replcated 1254 1255 if( r_alloc_dir_fsm.read() == ALLOC_DIR_READ ) 1256 { 1257 // signals generation 1258 bool inst_read = (m_cmd_read_trdid_fifo.read() & 0x2); 1259 bool cached_read = (m_cmd_read_trdid_fifo.read() & 0x1); 1260 bool is_cnt = r_read_is_cnt.read(); 1261 1262 // read data in the cache 1263 size_t set = m_y[(vci_addr_t)(m_cmd_read_addr_fifo.read())]; 1264 size_t way = r_read_way.read(); 1265 for ( size_t i=0 ; i<m_words ; i++ ) r_read_data[i] = m_cache_data[way][set][i]; 1266 1267 // update the cache directory 1268 DirectoryEntry entry; 1269 entry.valid = true; 1270 entry.is_cnt = is_cnt; 1271 entry.dirty = r_read_dirty.read(); 1272 entry.tag = r_read_tag.read(); 1273 entry.lock = r_read_lock.read(); 1274 entry.ptr = r_read_ptr.read(); 1275 if (cached_read) // Cached read => we must update the copies 1276 { 1277 if (!is_cnt) // Not counter mode 1278 { 1279 entry.owner.srcid = m_cmd_read_srcid_fifo.read(); 1141 1280 #if L1_MULTI_CACHE 1142 r_read_copy_cache = entry.owner.cache_id; 1143 #endif 1144 r_read_copy_inst = entry.owner.inst; 1145 r_read_ptr = entry.ptr; // pointer to the heap 1146 1147 bool cached_read = (m_cmd_read_trdid_fifo.read() & 0x1); 1148 if( entry.valid ) // hit 1149 { 1150 // test if we need to register a new copy in the heap 1151 if ( entry.is_cnt || (entry.count == 0) || !cached_read ) 1152 r_read_fsm = READ_DIR_HIT; 1153 else 1154 r_read_fsm = READ_HEAP_LOCK; 1155 } 1156 else // miss 1157 { 1158 r_read_fsm = READ_TRT_LOCK; 1159 } 1281 entry.owner.cache_id = m_cmd_read_pktid_fifo.read(); 1282 #endif 1283 entry.owner.inst = inst_read; 1284 entry.count = r_read_count.read() + 1; 1285 } 1286 else // Counter mode 1287 { 1288 entry.owner.srcid = 0; 1289 #if L1_MULTI_CACHE 1290 entry.owner.cache_id = 0; 1291 #endif 1292 entry.owner.inst = false; 1293 entry.count = r_read_count.read() + 1; 1294 } 1295 } 1296 else // Uncached read 1297 { 1298 entry.owner.srcid = r_read_copy.read(); 1299 #if L1_MULTI_CACHE 1300 entry.owner.cache_id = r_read_copy_cache.read(); 1301 #endif 1302 entry.owner.inst = r_read_copy_inst.read(); 1303 entry.count = r_read_count.read(); 1304 } 1160 1305 1161 1306 #if DEBUG_MEMC_READ 1162 if( m_debug_read_fsm ) 1163 { 1164 std::cout << " <MEMC " << name() << ".READ_DIR_LOCK> Accessing directory: " 1165 << " address = " << std::hex << m_cmd_read_addr_fifo.read() 1166 << " / hit = " << std::dec << entry.valid 1167 << " / count = " <<std::dec << entry.count 1168 << " / is_cnt = " << entry.is_cnt << std::endl; 1169 } 1170 #endif 1171 } 1172 break; 1173 } 1174 ////////////////// 1175 case READ_DIR_HIT: // read data in cache & update the directory 1176 // we enter this state in 3 cases: 1177 // - the read request is uncachable 1178 // - the cache line is in counter mode 1179 // - the cache line is valid but not replcated 1180 { 1181 if( r_alloc_dir_fsm.read() == ALLOC_DIR_READ ) 1182 { 1183 // signals generation 1184 bool inst_read = (m_cmd_read_trdid_fifo.read() & 0x2); 1185 bool cached_read = (m_cmd_read_trdid_fifo.read() & 0x1); 1186 bool is_cnt = r_read_is_cnt.read(); 1187 1188 // read data in the cache 1189 size_t set = m_y[(vci_addr_t)(m_cmd_read_addr_fifo.read())]; 1190 size_t way = r_read_way.read(); 1191 for ( size_t i=0 ; i<m_words ; i++ ) r_read_data[i] = m_cache_data[way][set][i]; 1192 1193 // update the cache directory 1194 DirectoryEntry entry; 1195 entry.valid = true; 1196 entry.is_cnt = is_cnt; 1197 entry.dirty = r_read_dirty.read(); 1198 entry.tag = r_read_tag.read(); 1199 entry.lock = r_read_lock.read(); 1200 entry.ptr = r_read_ptr.read(); 1201 if (cached_read) // Cached read => we must update the copies 1202 { 1203 if (!is_cnt) // Not counter mode 1204 { 1205 entry.owner.srcid = m_cmd_read_srcid_fifo.read(); 1307 if( m_debug_read_fsm ) 1308 { 1309 std::cout 1310 << " <MEMC " << name() << ".READ_DIR_HIT> Update directory entry:" 1311 << " set = " << std::dec << set 1312 << " / way = " << way 1313 << " / owner_id = " << entry.owner.srcid 1314 << " / owner_ins = " << entry.owner.inst 1315 << " / count = " << entry.count 1316 << " / is_cnt = " << entry.is_cnt << std::endl; 1317 } 1318 #endif 1319 1320 m_cache_directory.write(set, way, entry); 1321 r_read_fsm = READ_RSP; 1322 } 1323 break; 1324 } 1325 1326 //////////////////// 1327 case READ_HEAP_REQ: 1328 // Get the lock to the HEAP directory 1329 { 1330 if( r_alloc_heap_fsm.read() == ALLOC_HEAP_READ ) 1331 { 1332 r_read_fsm = READ_HEAP_LOCK; 1333 } 1334 1335 #if DEBUG_MEMC_READ 1336 if( m_debug_read_fsm ) 1337 { 1338 std::cout 1339 << " <MEMC " << name() << ".READ_HEAP_REQ> Requesting HEAP lock " 1340 << std::endl; 1341 } 1342 #endif 1343 break; 1344 } 1345 1346 //////////////////// 1347 case READ_HEAP_LOCK: 1348 // read data in cache, update the directory 1349 // and prepare the HEAP update 1350 { 1351 if( r_alloc_heap_fsm.read() == ALLOC_HEAP_READ ) 1352 { 1353 // enter counter mode when we reach the limit of copies or the heap is full 1354 bool go_cnt = (r_read_count.read() >= r_copies_limit.read()) || m_heap.is_full(); 1355 1356 // read data in the cache 1357 size_t set = m_y[(vci_addr_t)(m_cmd_read_addr_fifo.read())]; 1358 size_t way = r_read_way.read(); 1359 for ( size_t i=0 ; i<m_words ; i++ ) r_read_data[i] = m_cache_data[way][set][i]; 1360 1361 // update the cache directory 1362 DirectoryEntry entry; 1363 entry.valid = true; 1364 entry.is_cnt = go_cnt; 1365 entry.dirty = r_read_dirty.read(); 1366 entry.tag = r_read_tag.read(); 1367 entry.lock = r_read_lock.read(); 1368 entry.count = r_read_count.read() + 1; 1369 1370 if (not go_cnt) // Not entering counter mode 1371 { 1372 entry.owner.srcid = r_read_copy.read(); 1206 1373 #if L1_MULTI_CACHE 1207 entry.owner.cache_id = m_cmd_read_pktid_fifo.read();1208 #endif 1209 entry.owner.inst = inst_read;1210 entry.count = r_read_count.read() + 1;1211 }1212 else //Counter mode1213 1214 1374 entry.owner.cache_id = r_read_copy_cache.read(); 1375 #endif 1376 entry.owner.inst = r_read_copy_inst.read(); 1377 entry.ptr = m_heap.next_free_ptr(); // set pointer on the heap 1378 } 1379 else // Entering Counter mode 1380 { 1381 entry.owner.srcid = 0; 1215 1382 #if L1_MULTI_CACHE 1216 entry.owner.cache_id = 0; 1217 #endif 1218 entry.owner.inst = false; 1219 entry.count = r_read_count.read() + 1; 1220 } 1221 } 1222 else // Uncached read 1223 { 1224 entry.owner.srcid = r_read_copy.read(); 1383 entry.owner.cache_id = 0; 1384 #endif 1385 entry.owner.inst = false; 1386 entry.ptr = 0; 1387 } 1388 1389 m_cache_directory.write(set, way, entry); 1390 1391 // prepare the heap update (add an entry, or clear the linked list) 1392 if (not go_cnt) // not switching to counter mode 1393 { 1394 // We test if the next free entry in the heap is the last 1395 HeapEntry heap_entry = m_heap.next_free_entry(); 1396 r_read_next_ptr = heap_entry.next; 1397 r_read_last_free = ( heap_entry.next == m_heap.next_free_ptr() ); 1398 1399 r_read_fsm = READ_HEAP_WRITE; // add an entry in the HEAP 1400 } 1401 else // switching to counter mode 1402 { 1403 if ( r_read_count.read()>1 ) // heap must be cleared 1404 { 1405 HeapEntry next_entry = m_heap.read(r_read_ptr.read()); 1406 r_read_next_ptr = m_heap.next_free_ptr(); 1407 m_heap.write_free_ptr(r_read_ptr.read()); 1408 1409 if( next_entry.next == r_read_ptr.read() ) // last entry 1410 { 1411 r_read_fsm = READ_HEAP_LAST; // erase the entry 1412 } 1413 else // not the last entry 1414 { 1415 r_read_ptr = next_entry.next; 1416 r_read_fsm = READ_HEAP_ERASE; // erase the list 1417 } 1418 } 1419 else // the heap is not used / nothing to do 1420 { 1421 r_read_fsm = READ_RSP; 1422 } 1423 } 1424 1425 #if DEBUG_MEMC_READ 1426 if( m_debug_read_fsm ) 1427 { 1428 std::cout << " <MEMC " << name() << ".READ_HEAP_LOCK> Update directory:" 1429 << " tag = " << std::hex << entry.tag 1430 << " set = " << std::dec << set 1431 << " way = " << way 1432 << " count = " << entry.count 1433 << " is_cnt = " << entry.is_cnt << std::endl; 1434 } 1435 #endif 1436 } 1437 else 1438 { 1439 std::cout 1440 << "VCI_MEM_CACHE ERROR " << name() 1441 << " READ_HEAP_LOCK state" << std::endl 1442 << "Bad HEAP allocation" << std::endl; 1443 1444 exit(0); 1445 } 1446 1447 break; 1448 } 1449 1450 ///////////////////// 1451 case READ_HEAP_WRITE: // add a entry in the heap 1452 { 1453 if ( r_alloc_heap_fsm.read() == ALLOC_HEAP_READ ) 1454 { 1455 HeapEntry heap_entry; 1456 heap_entry.owner.srcid = m_cmd_read_srcid_fifo.read(); 1225 1457 #if L1_MULTI_CACHE 1226 entry.owner.cache_id = r_read_copy_cache.read(); 1227 #endif 1228 entry.owner.inst = r_read_copy_inst.read(); 1229 entry.count = r_read_count.read(); 1230 } 1458 heap_entry.owner.cache_id = m_cmd_read_pktid_fifo.read(); 1459 #endif 1460 heap_entry.owner.inst = (m_cmd_read_trdid_fifo.read() & 0x2); 1461 1462 if(r_read_count.read() == 1) // creation of a new linked list 1463 { 1464 heap_entry.next = m_heap.next_free_ptr(); 1465 } 1466 else // head insertion in existing list 1467 { 1468 heap_entry.next = r_read_ptr.read(); 1469 } 1470 m_heap.write_free_entry(heap_entry); 1471 m_heap.write_free_ptr(r_read_next_ptr.read()); 1472 if(r_read_last_free.read()) m_heap.set_full(); 1473 1474 r_read_fsm = READ_RSP; 1231 1475 1232 1476 #if DEBUG_MEMC_READ 1233 if( m_debug_read_fsm ) 1234 { 1235 std::cout << " <MEMC " << name() << ".READ_DIR_HIT> Update directory entry:" 1236 << " set = " << std::dec << set 1237 << " / way = " << way 1238 << " / owner_id = " << entry.owner.srcid 1239 << " / owner_ins = " << entry.owner.inst 1240 << " / count = " << entry.count 1241 << " / is_cnt = " << entry.is_cnt << std::endl; 1242 } 1243 #endif 1244 1245 m_cache_directory.write(set, way, entry); 1246 r_read_fsm = READ_RSP; 1247 } 1248 break; 1249 } 1250 //////////////////// 1251 case READ_HEAP_LOCK: // read data in cache, update the directory 1252 // and prepare the HEAP update 1253 { 1254 if( r_alloc_heap_fsm.read() == ALLOC_HEAP_READ ) 1255 { 1256 // enter counter mode when we reach the limit of copies or the heap is full 1257 bool go_cnt = (r_read_count.read() >= r_copies_limit.read()) || m_heap.is_full(); 1258 1259 // read data in the cache 1260 size_t set = m_y[(vci_addr_t)(m_cmd_read_addr_fifo.read())]; 1261 size_t way = r_read_way.read(); 1262 for ( size_t i=0 ; i<m_words ; i++ ) r_read_data[i] = m_cache_data[way][set][i]; 1263 1264 // update the cache directory 1265 DirectoryEntry entry; 1266 entry.valid = true; 1267 entry.is_cnt = go_cnt; 1268 entry.dirty = r_read_dirty.read(); 1269 entry.tag = r_read_tag.read(); 1270 entry.lock = r_read_lock.read(); 1271 entry.count = r_read_count.read() + 1; 1272 1273 if (not go_cnt) // Not entering counter mode 1274 { 1275 entry.owner.srcid = r_read_copy.read(); 1477 if( m_debug_read_fsm ) 1478 { 1479 std::cout 1480 << " <MEMC " << name() << ".READ_HEAP_WRITE> Add an entry in the heap:" 1481 << " owner_id = " << heap_entry.owner.srcid 1482 << " owner_ins = " << heap_entry.owner.inst << std::endl; 1483 } 1484 #endif 1485 } 1486 else 1487 { 1488 std::cout 1489 << "VCI_MEM_CACHE ERROR " << name() 1490 << " READ_HEAP_WRITE state" << std::endl 1491 << "Bad HEAP allocation" << std::endl; 1492 1493 exit(0); 1494 } 1495 break; 1496 } 1497 1498 ///////////////////// 1499 case READ_HEAP_ERASE: 1500 { 1501 if ( r_alloc_heap_fsm.read() == ALLOC_HEAP_READ ) 1502 { 1503 HeapEntry next_entry = m_heap.read(r_read_ptr.read()); 1504 if( next_entry.next == r_read_ptr.read() ) 1505 { 1506 r_read_fsm = READ_HEAP_LAST; 1507 } 1508 else 1509 { 1510 r_read_ptr = next_entry.next; 1511 r_read_fsm = READ_HEAP_ERASE; 1512 } 1513 } 1514 else 1515 { 1516 std::cout 1517 << "VCI_MEM_CACHE ERROR " << name() 1518 << " READ_HEAP_ERASE state" << std::endl 1519 << "Bad HEAP allocation" << std::endl; 1520 1521 exit(0); 1522 } 1523 break; 1524 } 1525 1526 //////////////////// 1527 case READ_HEAP_LAST: 1528 { 1529 if ( r_alloc_heap_fsm.read() == ALLOC_HEAP_READ ) 1530 { 1531 HeapEntry last_entry; 1532 last_entry.owner.srcid = 0; 1276 1533 #if L1_MULTI_CACHE 1277 entry.owner.cache_id= r_read_copy_cache.read(); 1278 #endif 1279 entry.owner.inst = r_read_copy_inst.read(); 1280 entry.ptr = m_heap.next_free_ptr(); // set pointer on the heap 1281 } 1282 else // Entering Counter mode 1283 { 1284 entry.owner.srcid = 0; 1534 last_entry.owner.cache_id = 0; 1535 #endif 1536 last_entry.owner.inst = false; 1537 1538 if(m_heap.is_full()) 1539 { 1540 last_entry.next = r_read_ptr.read(); 1541 m_heap.unset_full(); 1542 } 1543 else 1544 { 1545 last_entry.next = r_read_next_ptr.read(); 1546 } 1547 m_heap.write(r_read_ptr.read(),last_entry); 1548 r_read_fsm = READ_RSP; 1549 } 1550 else 1551 { 1552 std::cout << "VCI_MEM_CACHE ERROR " << name() 1553 << " READ_HEAP_LAST state" << std::endl; 1554 std::cout << "Bad HEAP allocation" << std::endl; 1555 exit(0); 1556 } 1557 break; 1558 } 1559 1560 ////////////// 1561 case READ_RSP: // request the TGT_RSP FSM to return data 1562 { 1563 if( !r_read_to_tgt_rsp_req ) 1564 { 1565 for ( size_t i=0 ; i<m_words ; i++ ) r_read_to_tgt_rsp_data[i] = r_read_data[i]; 1566 r_read_to_tgt_rsp_word = m_x[(vci_addr_t)m_cmd_read_addr_fifo.read()]; 1567 r_read_to_tgt_rsp_length = m_cmd_read_length_fifo.read(); 1568 r_read_to_tgt_rsp_srcid = m_cmd_read_srcid_fifo.read(); 1569 r_read_to_tgt_rsp_trdid = m_cmd_read_trdid_fifo.read(); 1570 r_read_to_tgt_rsp_pktid = m_cmd_read_pktid_fifo.read(); 1571 cmd_read_fifo_get = true; 1572 r_read_to_tgt_rsp_req = true; 1573 r_read_fsm = READ_IDLE; 1574 1575 #if DEBUG_MEMC_READ 1576 if( m_debug_read_fsm ) 1577 { 1578 std::cout << " <MEMC " << name() << ".READ_RSP> Request the TGT_RSP FSM to return data:" 1579 << " rsrcid = " << std::dec << m_cmd_read_srcid_fifo.read() 1580 << " / address = " << std::hex << m_cmd_read_addr_fifo.read() 1581 << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl; 1582 } 1583 #endif 1584 } 1585 break; 1586 } 1587 1588 /////////////////// 1589 case READ_TRT_LOCK: // read miss : check the Transaction Table 1590 { 1591 if ( r_alloc_trt_fsm.read() == ALLOC_TRT_READ ) 1592 { 1593 size_t index = 0; 1594 vci_addr_t addr = (vci_addr_t)m_cmd_read_addr_fifo.read(); 1595 bool hit_read = m_transaction_tab.hit_read(m_nline[addr], index); 1596 bool hit_write = m_transaction_tab.hit_write(m_nline[addr]); 1597 bool wok = !m_transaction_tab.full(index); 1598 1599 if( hit_read || !wok || hit_write ) // missing line already requested or no space 1600 { 1601 if(!wok) m_cpt_trt_full++; 1602 if(hit_read || hit_write) m_cpt_trt_rb++; 1603 r_read_fsm = READ_IDLE; 1604 } 1605 else // missing line is requested to the XRAM 1606 { 1607 m_cpt_read_miss++; 1608 r_read_trt_index = index; 1609 r_read_fsm = READ_TRT_SET; 1610 } 1611 1612 #if DEBUG_MEMC_READ 1613 if( m_debug_read_fsm ) 1614 { 1615 std::cout << " <MEMC " << name() << ".READ_TRT_LOCK> Check TRT:" 1616 << " hit_read = " << hit_read 1617 << " / hit_write = " << hit_write 1618 << " / full = " << !wok << std::endl; 1619 } 1620 #endif 1621 } 1622 break; 1623 } 1624 1625 ////////////////// 1626 case READ_TRT_SET: // register get transaction in TRT 1627 { 1628 if ( r_alloc_trt_fsm.read() == ALLOC_TRT_READ ) 1629 { 1630 m_transaction_tab.set(r_read_trt_index.read(), 1631 true, 1632 m_nline[(vci_addr_t)(m_cmd_read_addr_fifo.read())], 1633 m_cmd_read_srcid_fifo.read(), 1634 m_cmd_read_trdid_fifo.read(), 1635 m_cmd_read_pktid_fifo.read(), 1636 true, 1637 m_cmd_read_length_fifo.read(), 1638 m_x[(vci_addr_t)(m_cmd_read_addr_fifo.read())], 1639 std::vector<be_t>(m_words,0), 1640 std::vector<data_t>(m_words,0)); 1641 #if DEBUG_MEMC_READ 1642 if( m_debug_read_fsm ) 1643 { 1644 std::cout << " <MEMC " << name() << ".READ_TRT_SET> Write in Transaction Table: " << std::hex 1645 << " address = " << std::hex << m_cmd_read_addr_fifo.read() 1646 << " / srcid = " << std::dec << m_cmd_read_srcid_fifo.read() 1647 << std::endl; 1648 } 1649 #endif 1650 r_read_fsm = READ_TRT_REQ; 1651 } 1652 break; 1653 } 1654 1655 ////////////////// 1656 case READ_TRT_REQ: 1657 { 1658 // consume the read request in the FIFO, 1659 // and send it to the ixr_cmd_fsm 1660 1661 if( not r_read_to_ixr_cmd_req ) 1662 { 1663 cmd_read_fifo_get = true; 1664 r_read_to_ixr_cmd_req = true; 1665 r_read_to_ixr_cmd_nline = m_nline[(vci_addr_t)(m_cmd_read_addr_fifo.read())]; 1666 r_read_to_ixr_cmd_trdid = r_read_trt_index.read(); 1667 r_read_fsm = READ_IDLE; 1668 1669 #if DEBUG_MEMC_READ 1670 if( m_debug_read_fsm ) 1671 { 1672 std::cout 1673 << " <MEMC " << name() << ".READ_TRT_REQ> Request GET transaction for address " 1674 << std::hex << m_cmd_read_addr_fifo.read() << std::endl; 1675 } 1676 #endif 1677 } 1678 break; 1679 } 1680 } // end switch read_fsm 1681 1682 /////////////////////////////////////////////////////////////////////////////////// 1683 // WRITE FSM 1684 /////////////////////////////////////////////////////////////////////////////////// 1685 // The WRITE FSM handles the write bursts sent by the processors. 1686 // All addresses in a burst must be in the same cache line. 1687 // A complete write burst is consumed in the FIFO & copied to a local buffer. 1688 // Then the FSM takes the lock protecting the cache directory, to check 1689 // if the line is in the cache. 1690 // 1691 // - In case of HIT, the cache is updated. 1692 // If there is no other copy, an acknowledge response is immediately 1693 // returned to the writing processor. 1694 // If the data is cached by other processors, a coherence transaction must 1695 // be launched: 1696 // It is a multicast update if the line is not in counter mode, and the processor 1697 // takes the lock protecting the Update Table (UPT) to register this transaction. 1698 // It is a broadcast invalidate if the line is in counter mode. 1699 // If the UPT is full, it releases the lock(s) and retry. Then, it sends 1700 // a multi-update request to all owners of the line (but the writer), 1701 // through the INIT_CMD FSM. In case of coherence transaction, the WRITE FSM 1702 // does not respond to the writing processor, as this response will be sent by 1703 // the INIT_RSP FSM when all update responses have been received. 1704 // 1705 // - In case of MISS, the WRITE FSM takes the lock protecting the transaction 1706 // table (TRT). If a read transaction to the XRAM for this line already exists, 1707 // it writes in the TRT (write buffer). Otherwise, if a TRT entry is free, 1708 // the WRITE FSM register a new transaction in TRT, and sends a read line request 1709 // to the XRAM. If the TRT is full, it releases the lock, and waits. 1710 // Finally, the WRITE FSM returns an aknowledge response to the writing processor. 1711 ///////////////////////////////////////////////////////////////////////////////////// 1712 1713 switch ( r_write_fsm.read() ) 1714 { 1715 //////////////// 1716 case WRITE_IDLE: // copy first word of a write burst in local buffer 1717 { 1718 if ( m_cmd_write_addr_fifo.rok() ) 1719 { 1720 m_cpt_write++; 1721 m_cpt_write_cells++; 1722 1723 // consume a word in the FIFO & write it in the local buffer 1724 cmd_write_fifo_get = true; 1725 size_t index = m_x[(vci_addr_t)(m_cmd_write_addr_fifo.read())]; 1726 1727 r_write_address = (addr_t)(m_cmd_write_addr_fifo.read()); 1728 r_write_word_index = index; 1729 r_write_word_count = 1; 1730 r_write_data[index] = m_cmd_write_data_fifo.read(); 1731 r_write_srcid = m_cmd_write_srcid_fifo.read(); 1732 r_write_trdid = m_cmd_write_trdid_fifo.read(); 1733 r_write_pktid = m_cmd_write_pktid_fifo.read(); 1734 1735 // initialize the be field for all words 1736 for ( size_t i=0 ; i<m_words ; i++ ) 1737 { 1738 if ( i == index ) r_write_be[i] = m_cmd_write_be_fifo.read(); 1739 else r_write_be[i] = 0x0; 1740 } 1741 1742 if( !((m_cmd_write_be_fifo.read() == 0x0)||(m_cmd_write_be_fifo.read() == 0xF)) ) 1743 r_write_byte = true; 1744 else 1745 r_write_byte = false; 1746 1747 if( m_cmd_write_eop_fifo.read() ) 1748 { 1749 r_write_fsm = WRITE_DIR_REQ; 1750 } 1751 else 1752 { 1753 r_write_fsm = WRITE_NEXT; 1754 } 1755 1756 #if DEBUG_MEMC_WRITE 1757 if( m_debug_write_fsm ) 1758 { 1759 std::cout << " <MEMC " << name() << ".WRITE_IDLE> Write request " 1760 << " srcid = " << std::dec << m_cmd_write_srcid_fifo.read() 1761 << " / address = " << std::hex << m_cmd_write_addr_fifo.read() 1762 << " / data = " << m_cmd_write_data_fifo.read() << std::endl; 1763 } 1764 #endif 1765 } 1766 break; 1767 } 1768 1769 //////////////// 1770 case WRITE_NEXT: // copy next word of a write burst in local buffer 1771 { 1772 if ( m_cmd_write_addr_fifo.rok() ) 1773 { 1774 1775 #if DEBUG_MEMC_WRITE 1776 if( m_debug_write_fsm ) 1777 { 1778 std::cout << " <MEMC " << name() << ".WRITE_NEXT> Write another word in local buffer" 1779 << std::endl; 1780 } 1781 #endif 1782 m_cpt_write_cells++; 1783 1784 // check that the next word is in the same cache line 1785 if (( m_nline[(vci_addr_t)(r_write_address.read())] != 1786 m_nline[(vci_addr_t)(m_cmd_write_addr_fifo.read())] )) 1787 { 1788 std::cout << "VCI_MEM_CACHE ERROR " << name() << " WRITE_NEXT state" << std::endl 1789 << "all words in a write burst must be in same cache line" << std::endl; 1790 1791 exit(0); 1792 } 1793 1794 // consume a word in the FIFO & write it in the local buffer 1795 cmd_write_fifo_get = true; 1796 size_t index = r_write_word_index.read() + r_write_word_count.read(); 1797 1798 r_write_be[index] = m_cmd_write_be_fifo.read(); 1799 r_write_data[index] = m_cmd_write_data_fifo.read(); 1800 r_write_word_count = r_write_word_count.read() + 1; 1801 1802 if( !((m_cmd_write_be_fifo.read() == 0x0)||(m_cmd_write_be_fifo.read() == 0xF)) ) 1803 r_write_byte = true; 1804 1805 if ( m_cmd_write_eop_fifo.read() ) 1806 { 1807 r_write_fsm = WRITE_DIR_REQ; 1808 } 1809 } 1810 break; 1811 } 1812 1813 //////////////////// 1814 case WRITE_DIR_REQ: 1815 // Get the lock to the directory 1816 { 1817 if ( r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE ) 1818 { 1819 r_write_fsm = WRITE_DIR_LOCK; 1820 } 1821 1822 #if DEBUG_MEMC_WRITE 1823 if( m_debug_write_fsm ) 1824 { 1825 std::cout 1826 << " <MEMC " << name() << ".WRITE_DIR_REQ> Requesting DIR lock " 1827 << std::endl; 1828 } 1829 #endif 1830 1831 break; 1832 } 1833 1834 //////////////////// 1835 case WRITE_DIR_LOCK: 1836 // access directory to check hit/miss 1837 { 1838 if ( r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE ) 1839 { 1840 size_t way = 0; 1841 DirectoryEntry entry(m_cache_directory.read(r_write_address.read(), way)); 1842 1843 if ( entry.valid ) // hit 1844 { 1845 // copy directory entry in local buffer in case of hit 1846 r_write_is_cnt = entry.is_cnt; 1847 r_write_lock = entry.lock; 1848 r_write_tag = entry.tag; 1849 r_write_copy = entry.owner.srcid; 1285 1850 #if L1_MULTI_CACHE 1286 entry.owner.cache_id= 0; 1287 #endif 1288 entry.owner.inst = false; 1289 entry.ptr = 0; 1290 } 1291 1292 m_cache_directory.write(set, way, entry); 1293 1294 // prepare the heap update (add an entry, or clear the linked list) 1295 if (not go_cnt) // not switching to counter mode 1296 { 1297 // We test if the next free entry in the heap is the last 1298 HeapEntry heap_entry = m_heap.next_free_entry(); 1299 r_read_next_ptr = heap_entry.next; 1300 r_read_last_free = ( heap_entry.next == m_heap.next_free_ptr() ); 1301 1302 r_read_fsm = READ_HEAP_WRITE; // add an entry in the HEAP 1303 } 1304 else // switching to counter mode 1305 { 1306 if ( r_read_count.read()>1 ) // heap must be cleared 1307 { 1308 HeapEntry next_entry = m_heap.read(r_read_ptr.read()); 1309 r_read_next_ptr = m_heap.next_free_ptr(); 1310 m_heap.write_free_ptr(r_read_ptr.read()); 1311 1312 if( next_entry.next == r_read_ptr.read() ) // last entry 1313 { 1314 r_read_fsm = READ_HEAP_LAST; // erase the entry 1315 } 1316 else // not the last entry 1317 { 1318 r_read_ptr = next_entry.next; 1319 r_read_fsm = READ_HEAP_ERASE; // erase the list 1320 } 1321 } 1322 else // the heap is not used / nothing to do 1323 { 1324 r_read_fsm = READ_RSP; 1325 } 1326 } 1327 1328 #if DEBUG_MEMC_READ 1329 if( m_debug_read_fsm ) 1330 { 1331 std::cout << " <MEMC " << name() << ".READ_HEAP_LOCK> Update directory:" 1332 << " tag = " << std::hex << entry.tag 1333 << " set = " << std::dec << set 1334 << " way = " << way 1335 << " count = " << entry.count 1336 << " is_cnt = " << entry.is_cnt << std::endl; 1337 } 1338 #endif 1339 } 1340 break; 1341 } 1342 ///////////////////// 1343 case READ_HEAP_WRITE: // add a entry in the heap 1344 { 1345 if ( r_alloc_heap_fsm.read() == ALLOC_HEAP_READ ) 1346 { 1347 HeapEntry heap_entry; 1348 heap_entry.owner.srcid = m_cmd_read_srcid_fifo.read(); 1851 r_write_copy_cache = entry.owner.cache_id; 1852 #endif 1853 r_write_copy_inst = entry.owner.inst; 1854 r_write_count = entry.count; 1855 r_write_ptr = entry.ptr; 1856 r_write_way = way; 1857 1858 if( entry.is_cnt && entry.count ) 1859 { 1860 r_write_fsm = WRITE_DIR_READ; 1861 } 1862 else 1863 { 1864 if (r_write_byte.read()) 1865 { 1866 r_write_fsm = WRITE_DIR_READ; 1867 } 1868 else 1869 { 1870 r_write_fsm = WRITE_DIR_HIT; 1871 } 1872 } 1873 } 1874 else // miss 1875 { 1876 r_write_fsm = WRITE_MISS_TRT_LOCK; 1877 } 1878 1879 #if DEBUG_MEMC_WRITE 1880 if( m_debug_write_fsm ) 1881 { 1882 std::cout << " <MEMC " << name() << ".WRITE_DIR_LOCK> Check the directory: " 1883 << " address = " << std::hex << r_write_address.read() 1884 << " hit = " << std::dec << entry.valid 1885 << " count = " << entry.count 1886 << " is_cnt = " << entry.is_cnt << std::endl; 1887 } 1888 #endif 1889 } 1890 else 1891 { 1892 std::cout << "VCI_MEM_CACHE ERROR " << name() 1893 << " WRITE_DIR_LOCK state" << std::endl 1894 << "bad DIR allocation" << std::endl; 1895 1896 exit(0); 1897 } 1898 1899 break; 1900 } 1901 1902 //////////////////// 1903 case WRITE_DIR_READ: // read the cache and complete the buffer when be!=0xF 1904 { 1905 // update local buffer 1906 size_t set = m_y[(vci_addr_t)(r_write_address.read())]; 1907 size_t way = r_write_way.read(); 1908 for(size_t i=0 ; i<m_words ; i++) 1909 { 1910 data_t mask = 0; 1911 if (r_write_be[i].read() & 0x1) mask = mask | 0x000000FF; 1912 if (r_write_be[i].read() & 0x2) mask = mask | 0x0000FF00; 1913 if (r_write_be[i].read() & 0x4) mask = mask | 0x00FF0000; 1914 if (r_write_be[i].read() & 0x8) mask = mask | 0xFF000000; 1915 1916 // complete only if mask is not null (for energy consumption) 1917 if ( r_write_be[i].read() || r_write_is_cnt.read() ) 1918 { 1919 r_write_data[i] = (r_write_data[i].read() & mask) | 1920 (m_cache_data[way][set][i] & ~mask); 1921 } 1922 } // end for 1923 1924 // test if a coherence broadcast is required 1925 if( r_write_is_cnt.read() && r_write_count.read() ) 1926 { 1927 r_write_fsm = WRITE_BC_TRT_LOCK; 1928 } 1929 else 1930 { 1931 r_write_fsm = WRITE_DIR_HIT; 1932 } 1933 1934 #if DEBUG_MEMC_WRITE 1935 if( m_debug_write_fsm ) 1936 { 1937 std::cout << " <MEMC " << name() << ".WRITE_DIR_READ> Read the cache to complete local buffer" << std::endl; 1938 } 1939 #endif 1940 break; 1941 } 1942 1943 /////////////////// 1944 case WRITE_DIR_HIT: 1945 { 1946 // update the cache directory 1947 // update directory with Dirty bit 1948 DirectoryEntry entry; 1949 entry.valid = true; 1950 entry.dirty = true; 1951 entry.tag = r_write_tag.read(); 1952 entry.is_cnt = r_write_is_cnt.read(); 1953 entry.lock = r_write_lock.read(); 1954 entry.owner.srcid = r_write_copy.read(); 1349 1955 #if L1_MULTI_CACHE 1350 heap_entry.owner.cache_id = m_cmd_read_pktid_fifo.read(); 1351 #endif 1352 heap_entry.owner.inst = (m_cmd_read_trdid_fifo.read() & 0x2); 1353 1354 if(r_read_count.read() == 1) // creation of a new linked list 1355 { 1356 heap_entry.next = m_heap.next_free_ptr(); 1357 } 1358 else // head insertion in existing list 1359 { 1360 heap_entry.next = r_read_ptr.read(); 1361 } 1362 m_heap.write_free_entry(heap_entry); 1363 m_heap.write_free_ptr(r_read_next_ptr.read()); 1364 if(r_read_last_free.read()) m_heap.set_full(); 1365 1366 r_read_fsm = READ_RSP; 1367 1368 #if DEBUG_MEMC_READ 1369 if( m_debug_read_fsm ) 1370 { 1371 std::cout << " <MEMC " << name() << ".READ_HEAP_WRITE> Add an entry in the heap:" 1372 << " owner_id = " << heap_entry.owner.srcid 1373 << " owner_ins = " << heap_entry.owner.inst << std::endl; 1374 } 1375 #endif 1376 } 1377 else 1378 { 1379 std::cout << "VCI_MEM_CACHE ERROR " << name() 1380 << " READ_HEAP_WRITE state" << std::endl; 1381 std::cout << "Bad HEAP allocation" << std::endl; 1382 exit(0); 1383 } 1384 break; 1385 } 1386 ///////////////////// 1387 case READ_HEAP_ERASE: 1388 { 1389 if ( r_alloc_heap_fsm.read() == ALLOC_HEAP_READ ) 1390 { 1391 HeapEntry next_entry = m_heap.read(r_read_ptr.read()); 1392 if( next_entry.next == r_read_ptr.read() ) 1393 { 1394 r_read_fsm = READ_HEAP_LAST; 1395 } 1396 else 1397 { 1398 r_read_ptr = next_entry.next; 1399 r_read_fsm = READ_HEAP_ERASE; 1400 } 1401 } 1402 else 1403 { 1404 std::cout << "VCI_MEM_CACHE ERROR " << name() 1405 << " READ_HEAP_ERASE state" << std::endl; 1406 std::cout << "Bad HEAP allocation" << std::endl; 1407 exit(0); 1408 } 1409 break; 1410 } 1411 //////////////////// 1412 case READ_HEAP_LAST: 1413 { 1414 if ( r_alloc_heap_fsm.read() == ALLOC_HEAP_READ ) 1415 { 1416 HeapEntry last_entry; 1417 last_entry.owner.srcid = 0; 1956 entry.owner.cache_id = r_write_copy_cache.read(); 1957 #endif 1958 entry.owner.inst = r_write_copy_inst.read(); 1959 entry.count = r_write_count.read(); 1960 entry.ptr = r_write_ptr.read(); 1961 1962 size_t set = m_y[(vci_addr_t)(r_write_address.read())]; 1963 size_t way = r_write_way.read(); 1964 1965 // update directory 1966 m_cache_directory.write(set, way, entry); 1967 1968 // owner is true when the the first registered copy is the writer itself 1969 bool owner = (((r_write_copy.read() == r_write_srcid.read()) 1418 1970 #if L1_MULTI_CACHE 1419 last_entry.owner.cache_id = 0; 1420 #endif 1421 last_entry.owner.inst = false; 1422 1423 if(m_heap.is_full()) 1424 { 1425 last_entry.next = r_read_ptr.read(); 1426 m_heap.unset_full(); 1427 } 1428 else 1429 { 1430 last_entry.next = r_read_next_ptr.read(); 1431 } 1432 m_heap.write(r_read_ptr.read(),last_entry); 1433 r_read_fsm = READ_RSP; 1434 } 1435 else 1436 { 1437 std::cout << "VCI_MEM_CACHE ERROR " << name() 1438 << " READ_HEAP_LAST state" << std::endl; 1439 std::cout << "Bad HEAP allocation" << std::endl; 1440 exit(0); 1441 } 1442 break; 1443 } 1444 ////////////// 1445 case READ_RSP: // request the TGT_RSP FSM to return data 1446 { 1447 if( !r_read_to_tgt_rsp_req ) 1448 { 1449 for ( size_t i=0 ; i<m_words ; i++ ) r_read_to_tgt_rsp_data[i] = r_read_data[i]; 1450 r_read_to_tgt_rsp_word = m_x[(vci_addr_t)m_cmd_read_addr_fifo.read()]; 1451 r_read_to_tgt_rsp_length = m_cmd_read_length_fifo.read(); 1452 r_read_to_tgt_rsp_srcid = m_cmd_read_srcid_fifo.read(); 1453 r_read_to_tgt_rsp_trdid = m_cmd_read_trdid_fifo.read(); 1454 r_read_to_tgt_rsp_pktid = m_cmd_read_pktid_fifo.read(); 1455 cmd_read_fifo_get = true; 1456 r_read_to_tgt_rsp_req = true; 1457 r_read_fsm = READ_IDLE; 1458 1459 #if DEBUG_MEMC_READ 1460 if( m_debug_read_fsm ) 1461 { 1462 std::cout << " <MEMC " << name() << ".READ_RSP> Request the TGT_RSP FSM to return data:" 1463 << " rsrcid = " << std::dec << m_cmd_read_srcid_fifo.read() 1464 << " / address = " << std::hex << m_cmd_read_addr_fifo.read() 1465 << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl; 1466 } 1467 #endif 1468 } 1469 break; 1470 } 1471 /////////////////// 1472 case READ_TRT_LOCK: // read miss : check the Transaction Table 1473 { 1474 if ( r_alloc_trt_fsm.read() == ALLOC_TRT_READ ) 1475 { 1476 size_t index = 0; 1477 vci_addr_t addr = (vci_addr_t)m_cmd_read_addr_fifo.read(); 1478 bool hit_read = m_transaction_tab.hit_read(m_nline[addr], index); 1479 bool hit_write = m_transaction_tab.hit_write(m_nline[addr]); 1480 bool wok = !m_transaction_tab.full(index); 1481 1482 if( hit_read || !wok || hit_write ) // missing line already requested or no space 1483 { 1484 if(!wok) m_cpt_trt_full++; 1485 if(hit_read || hit_write) m_cpt_trt_rb++; 1486 r_read_fsm = READ_IDLE; 1487 } 1488 else // missing line is requested to the XRAM 1489 { 1490 m_cpt_read_miss++; 1491 r_read_trt_index = index; 1492 r_read_fsm = READ_TRT_SET; 1493 } 1494 1495 #if DEBUG_MEMC_READ 1496 if( m_debug_read_fsm ) 1497 { 1498 std::cout << " <MEMC " << name() << ".READ_TRT_LOCK> Check TRT:" 1499 << " hit_read = " << hit_read 1500 << " / hit_write = " << hit_write 1501 << " / full = " << !wok << std::endl; 1502 } 1503 #endif 1504 } 1505 break; 1506 } 1507 ////////////////// 1508 case READ_TRT_SET: // register get transaction in TRT 1509 { 1510 if ( r_alloc_trt_fsm.read() == ALLOC_TRT_READ ) 1511 { 1512 m_transaction_tab.set(r_read_trt_index.read(), 1513 true, 1514 m_nline[(vci_addr_t)(m_cmd_read_addr_fifo.read())], 1515 m_cmd_read_srcid_fifo.read(), 1516 m_cmd_read_trdid_fifo.read(), 1517 m_cmd_read_pktid_fifo.read(), 1518 true, 1519 m_cmd_read_length_fifo.read(), 1520 m_x[(vci_addr_t)(m_cmd_read_addr_fifo.read())], 1521 std::vector<be_t>(m_words,0), 1522 std::vector<data_t>(m_words,0)); 1523 #if DEBUG_MEMC_READ 1524 if( m_debug_read_fsm ) 1525 { 1526 std::cout << " <MEMC " << name() << ".READ_TRT_SET> Write in Transaction Table: " << std::hex 1527 << " address = " << std::hex << m_cmd_read_addr_fifo.read() 1528 << " / srcid = " << std::dec << m_cmd_read_srcid_fifo.read() 1529 << std::endl; 1530 } 1531 #endif 1532 r_read_fsm = READ_TRT_REQ; 1533 } 1534 break; 1535 } 1536 ////////////////// 1537 case READ_TRT_REQ: // consume the read request in the FIFO, 1538 // and send it to the ixr_cmd_fsm 1539 { 1540 if( not r_read_to_ixr_cmd_req ) 1541 { 1542 cmd_read_fifo_get = true; 1543 r_read_to_ixr_cmd_req = true; 1544 r_read_to_ixr_cmd_nline = m_nline[(vci_addr_t)(m_cmd_read_addr_fifo.read())]; 1545 r_read_to_ixr_cmd_trdid = r_read_trt_index.read(); 1546 r_read_fsm = READ_IDLE; 1547 1548 #if DEBUG_MEMC_READ 1549 if( m_debug_read_fsm ) 1550 { 1551 std::cout << " <MEMC " << name() << ".READ_TRT_REQ> Request GET transaction for address " 1552 << std::hex << m_cmd_read_addr_fifo.read() << std::endl; 1553 } 1554 #endif 1555 } 1556 break; 1557 } 1558 } // end switch read_fsm 1559 1560 /////////////////////////////////////////////////////////////////////////////////// 1561 // WRITE FSM 1562 /////////////////////////////////////////////////////////////////////////////////// 1563 // The WRITE FSM handles the write bursts sent by the processors. 1564 // All addresses in a burst must be in the same cache line. 1565 // A complete write burst is consumed in the FIFO & copied to a local buffer. 1566 // Then the FSM takes the lock protecting the cache directory, to check 1567 // if the line is in the cache. 1568 // 1569 // - In case of HIT, the cache is updated. 1570 // If there is no other copy, an acknowledge response is immediately 1571 // returned to the writing processor. 1572 // If the data is cached by other processors, a coherence transaction must 1573 // be launched: 1574 // It is a multicast update if the line is not in counter mode, and the processor 1575 // takes the lock protecting the Update Table (UPT) to register this transaction. 1576 // It is a broadcast invalidate if the line is in counter mode. 1577 // If the UPT is full, it releases the lock(s) and retry. Then, it sends 1578 // a multi-update request to all owners of the line (but the writer), 1579 // through the INIT_CMD FSM. In case of coherence transaction, the WRITE FSM 1580 // does not respond to the writing processor, as this response will be sent by 1581 // the INIT_RSP FSM when all update responses have been received. 1582 // 1583 // - In case of MISS, the WRITE FSM takes the lock protecting the transaction 1584 // table (TRT). If a read transaction to the XRAM for this line already exists, 1585 // it writes in the TRT (write buffer). Otherwise, if a TRT entry is free, 1586 // the WRITE FSM register a new transaction in TRT, and sends a read line request 1587 // to the XRAM. If the TRT is full, it releases the lock, and waits. 1588 // Finally, the WRITE FSM returns an aknowledge response to the writing processor. 1589 ///////////////////////////////////////////////////////////////////////////////////// 1590 1591 switch ( r_write_fsm.read() ) 1971 and (r_write_copy_cache.read()==r_write_pktid.read()) 1972 #endif 1973 ) and not r_write_copy_inst.read()); 1974 1975 // no_update is true when there is no need for coherence transaction 1976 bool no_update = (r_write_count.read()==0) || ( owner && (r_write_count.read()==1)); 1977 1978 // write data in the cache if no coherence transaction 1979 if( no_update ) 1980 { 1981 for(size_t i=0 ; i<m_words ; i++) 1982 { 1983 if ( r_write_be[i].read() ) 1984 { 1985 m_cache_data[way][set][i] = r_write_data[i].read(); 1986 1987 if ( m_monitor_ok ) 1988 { 1989 vci_addr_t address = (r_write_address.read() & ~(vci_addr_t)0x3F) | i<<2; 1990 char buf[80]; 1991 snprintf(buf, 80, "WRITE_DIR_HIT srcid %d", r_write_srcid.read()); 1992 check_monitor( buf, address, r_write_data[i].read() ); 1993 } 1994 } 1995 } 1996 } 1997 1998 if ( owner and not no_update ) 1999 { 2000 r_write_count = r_write_count.read() - 1; 2001 } 2002 2003 if ( no_update ) 2004 // Write transaction completed 2005 { 2006 r_write_fsm = WRITE_RSP; 2007 } 2008 else 2009 // coherence update required 2010 { 2011 if( !r_write_to_init_cmd_multi_req.read() && 2012 !r_write_to_init_cmd_brdcast_req.read() ) 2013 { 2014 r_write_fsm = WRITE_UPT_LOCK; 2015 } 2016 else 2017 { 2018 r_write_fsm = WRITE_WAIT; 2019 } 2020 } 2021 2022 #if DEBUG_MEMC_WRITE 2023 if( m_debug_write_fsm ) 2024 { 2025 if ( no_update ) 2026 { 2027 std::cout << " <MEMC " << name() << ".WRITE_DIR_HIT> Write into cache / No coherence transaction" 2028 << std::endl; 2029 } 2030 else 2031 { 2032 std::cout << " <MEMC " << name() << ".WRITE_DIR_HIT> Coherence update required:" 2033 << " is_cnt = " << r_write_is_cnt.read() 2034 << " nb_copies = " << std::dec << r_write_count.read() << std::endl; 2035 if (owner) 2036 std::cout << " ... but the first copy is the writer" << std::endl; 2037 } 2038 } 2039 #endif 2040 break; 2041 } 2042 2043 //////////////////// 2044 case WRITE_UPT_LOCK: // Try to register the update request in UPT 1592 2045 { 1593 //////////////// 1594 case WRITE_IDLE: // copy first word of a write burst in local buffer 1595 { 1596 if ( m_cmd_write_addr_fifo.rok() ) 1597 { 1598 m_cpt_write++; 1599 m_cpt_write_cells++; 1600 1601 // consume a word in the FIFO & write it in the local buffer 1602 cmd_write_fifo_get = true; 1603 size_t index = m_x[(vci_addr_t)(m_cmd_write_addr_fifo.read())]; 1604 1605 r_write_address = (addr_t)(m_cmd_write_addr_fifo.read()); 1606 r_write_word_index = index; 1607 r_write_word_count = 1; 1608 r_write_data[index] = m_cmd_write_data_fifo.read(); 1609 r_write_srcid = m_cmd_write_srcid_fifo.read(); 1610 r_write_trdid = m_cmd_write_trdid_fifo.read(); 1611 r_write_pktid = m_cmd_write_pktid_fifo.read(); 1612 1613 // initialize the be field for all words 1614 for ( size_t i=0 ; i<m_words ; i++ ) 1615 { 1616 if ( i == index ) r_write_be[i] = m_cmd_write_be_fifo.read(); 1617 else r_write_be[i] = 0x0; 1618 } 1619 1620 if( !((m_cmd_write_be_fifo.read() == 0x0)||(m_cmd_write_be_fifo.read() == 0xF)) ) 1621 r_write_byte = true; 1622 else 1623 r_write_byte = false; 1624 1625 if( m_cmd_write_eop_fifo.read() ) r_write_fsm = WRITE_DIR_LOCK; 1626 else r_write_fsm = WRITE_NEXT; 2046 if ( r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE ) 2047 { 2048 bool wok = false; 2049 size_t index = 0; 2050 size_t srcid = r_write_srcid.read(); 2051 size_t trdid = r_write_trdid.read(); 2052 size_t pktid = r_write_pktid.read(); 2053 addr_t nline = m_nline[(vci_addr_t)(r_write_address.read())]; 2054 size_t nb_copies = r_write_count.read(); 2055 size_t set = m_y[(vci_addr_t)(r_write_address.read())]; 2056 size_t way = r_write_way.read(); 2057 2058 wok = m_update_tab.set(true, // it's an update transaction 2059 false, // it's not a broadcast 2060 true, // it needs a response 2061 srcid, 2062 trdid, 2063 pktid, 2064 nline, 2065 nb_copies, 2066 index); 2067 if ( wok ) // write data in cache 2068 { 2069 for(size_t i=0 ; i<m_words ; i++) 2070 { 2071 if ( r_write_be[i].read() ) 2072 { 2073 m_cache_data[way][set][i] = r_write_data[i].read(); 2074 2075 if ( m_monitor_ok ) 2076 { 2077 vci_addr_t address = (r_write_address.read() & ~(vci_addr_t)0x3F) | i<<2; 2078 char buf[80]; 2079 snprintf(buf, 80, "WRITE_UPT_LOCK srcid %d", srcid); 2080 check_monitor(buf, address, r_write_data[i].read() ); 2081 } 2082 } 2083 } 2084 } 1627 2085 1628 2086 #if DEBUG_MEMC_WRITE 1629 if( m_debug_write_fsm ) 1630 { 1631 std::cout << " <MEMC " << name() << ".WRITE_IDLE> Write request " 2087 if( m_debug_write_fsm ) 2088 { 2089 if ( wok ) 2090 { 2091 std::cout << " <MEMC " << name() << ".WRITE_UPT_LOCK> Register the multicast update in UPT / " 2092 << " nb_copies = " << r_write_count.read() << std::endl; 2093 } 2094 } 2095 #endif 2096 r_write_upt_index = index; 2097 // releases the lock protecting UPT and the DIR if no entry... 2098 if ( wok ) r_write_fsm = WRITE_UPT_HEAP_LOCK; 2099 else r_write_fsm = WRITE_WAIT; 2100 } 2101 break; 2102 } 2103 2104 ///////////////////////// 2105 case WRITE_UPT_HEAP_LOCK: // get access to heap 2106 { 2107 if( r_alloc_heap_fsm.read() == ALLOC_HEAP_WRITE ) 2108 { 2109 2110 #if DEBUG_MEMC_WRITE 2111 if( m_debug_write_fsm ) 2112 { 2113 std::cout << " <MEMC " << name() << ".WRITE_UPT_HEAP_LOCK> Get acces to the HEAP" << std::endl; 2114 } 2115 #endif 2116 r_write_fsm = WRITE_UPT_REQ; 2117 } 2118 break; 2119 } 2120 2121 ////////////////// 2122 case WRITE_UPT_REQ: 2123 { 2124 // prepare the coherence ransaction for the INIT_CMD FSM 2125 // and write the first copy in the FIFO 2126 // send the request if only one copy 2127 2128 if( !r_write_to_init_cmd_multi_req.read() && 2129 !r_write_to_init_cmd_brdcast_req.read() ) // no pending coherence request 2130 { 2131 r_write_to_init_cmd_brdcast_req = false; 2132 r_write_to_init_cmd_trdid = r_write_upt_index.read(); 2133 r_write_to_init_cmd_nline = m_nline[(vci_addr_t)(r_write_address.read())]; 2134 r_write_to_init_cmd_index = r_write_word_index.read(); 2135 r_write_to_init_cmd_count = r_write_word_count.read(); 2136 2137 for(size_t i=0; i<m_words ; i++) r_write_to_init_cmd_be[i]=r_write_be[i].read(); 2138 2139 size_t min = r_write_word_index.read(); 2140 size_t max = r_write_word_index.read() + r_write_word_count.read(); 2141 for (size_t i=min ; i<max ; i++) r_write_to_init_cmd_data[i] = r_write_data[i]; 2142 2143 if( (r_write_copy.read() != r_write_srcid.read()) or 2144 #if L1_MULTI_CACHE 2145 (r_write_copy_cache.read() != r_write_pktid.read()) or 2146 #endif 2147 r_write_copy_inst.read() ) 2148 { 2149 // put the first srcid in the fifo 2150 write_to_init_cmd_fifo_put = true; 2151 write_to_init_cmd_fifo_inst = r_write_copy_inst.read(); 2152 write_to_init_cmd_fifo_srcid = r_write_copy.read(); 2153 #if L1_MULTI_CACHE 2154 write_to_init_cmd_fifo_cache_id= r_write_copy_cache.read(); 2155 #endif 2156 if(r_write_count.read() == 1) 2157 { 2158 r_write_fsm = WRITE_IDLE; 2159 r_write_to_init_cmd_multi_req = true; 2160 } 2161 else 2162 { 2163 r_write_fsm = WRITE_UPT_NEXT; 2164 r_write_to_dec = false; 2165 2166 } 2167 } 2168 else 2169 { 2170 r_write_fsm = WRITE_UPT_NEXT; 2171 r_write_to_dec = false; 2172 } 2173 2174 #if DEBUG_MEMC_WRITE 2175 if( m_debug_write_fsm ) 2176 { 2177 std::cout << " <MEMC " << name() << ".WRITE_UPT_REQ> Post first request to INIT_CMD FSM" 2178 << " / srcid = " << std::dec << r_write_copy.read() 2179 << " / inst = " << std::dec << r_write_copy_inst.read() << std::endl; 2180 if ( r_write_count.read() == 1) 2181 std::cout << " ... and this is the last" << std::endl; 2182 } 2183 #endif 2184 } 2185 break; 2186 } 2187 2188 /////////////////// 2189 case WRITE_UPT_NEXT: 2190 { 2191 // continue the multi-update request to INIT_CMD fsm 2192 // when there is copies in the heap. 2193 // if one copy in the heap is the writer itself 2194 // the corresponding SRCID should not be written in the fifo, 2195 // but the UPT counter must be decremented. 2196 // As this decrement is done in the WRITE_UPT_DEC state, 2197 // after the last copy has been found, the decrement request 2198 // must be registered in the r_write_to_dec flip-flop. 2199 2200 HeapEntry entry = m_heap.read(r_write_ptr.read()); 2201 2202 bool dec_upt_counter; 2203 2204 if( (entry.owner.srcid != r_write_srcid.read()) or 2205 #if L1_MULTI_CACHE 2206 (entry.owner.cache_id != r_write_pktid.read()) or 2207 #endif 2208 entry.owner.inst) // put te next srcid in the fifo 2209 { 2210 dec_upt_counter = false; 2211 write_to_init_cmd_fifo_put = true; 2212 write_to_init_cmd_fifo_inst = entry.owner.inst; 2213 write_to_init_cmd_fifo_srcid = entry.owner.srcid; 2214 #if L1_MULTI_CACHE 2215 write_to_init_cmd_fifo_cache_id = entry.owner.cache_id; 2216 #endif 2217 2218 #if DEBUG_MEMC_WRITE 2219 if( m_debug_write_fsm ) 2220 { 2221 std::cout << " <MEMC " << name() << ".WRITE_UPT_NEXT> Post another request to INIT_CMD FSM" 2222 << " / heap_index = " << std::dec << r_write_ptr.read() 2223 << " / srcid = " << std::dec << r_write_copy.read() 2224 << " / inst = " << std::dec << r_write_copy_inst.read() << std::endl; 2225 if( entry.next == r_write_ptr.read() ) 2226 std::cout << " ... and this is the last" << std::endl; 2227 } 2228 #endif 2229 } 2230 else // the UPT counter must be decremented 2231 { 2232 dec_upt_counter = true; 2233 2234 #if DEBUG_MEMC_WRITE 2235 if( m_debug_write_fsm ) 2236 { 2237 std::cout << " <MEMC " << name() << ".WRITE_UPT_NEXT> Skip one entry in heap matching the writer" 2238 << " / heap_index = " << std::dec << r_write_ptr.read() 2239 << " / srcid = " << std::dec << r_write_copy.read() 2240 << " / inst = " << std::dec << r_write_copy_inst.read() << std::endl; 2241 if( entry.next == r_write_ptr.read() ) 2242 std::cout << " ... and this is the last" << std::endl; 2243 } 2244 #endif 2245 } 2246 2247 // register the possible UPT decrement request 2248 r_write_to_dec = dec_upt_counter or r_write_to_dec.read(); 2249 2250 if( not m_write_to_init_cmd_inst_fifo.wok() ) 2251 { 2252 std::cout << "VCI_MEM_CACHE ERROR " << name() << " WRITE_UPT_NEXT state" << std::endl 2253 << "The write_to_init_cmd_fifo should not be full" << std::endl 2254 << "as the depth should be larger than the max number of copies" << std::endl; 2255 exit(0); 2256 } 2257 2258 r_write_ptr = entry.next; 2259 2260 if( entry.next == r_write_ptr.read() ) // last copy 2261 { 2262 r_write_to_init_cmd_multi_req = true; 2263 if( r_write_to_dec.read() or dec_upt_counter) r_write_fsm = WRITE_UPT_DEC; 2264 else r_write_fsm = WRITE_IDLE; 2265 } 2266 break; 2267 } 2268 2269 ////////////////// 2270 case WRITE_UPT_DEC: 2271 { 2272 // If the initial writer has a copy, it should not 2273 // receive an update request, but the counter in the 2274 // update table must be decremented by the INIT_RSP FSM. 2275 2276 if ( !r_write_to_init_rsp_req.read() ) 2277 { 2278 r_write_to_init_rsp_req = true; 2279 r_write_to_init_rsp_upt_index = r_write_upt_index.read(); 2280 r_write_fsm = WRITE_IDLE; 2281 } 2282 break; 2283 } 2284 2285 /////////////// 2286 case WRITE_RSP: 2287 { 2288 // Post a request to TGT_RSP FSM to acknowledge the write 2289 // In order to increase the Write requests throughput, 2290 // we don't wait to return in the IDLE state to consume 2291 // a new request in the write FIFO 2292 2293 if ( !r_write_to_tgt_rsp_req.read() ) 2294 { 2295 // post the request to TGT_RSP_FSM 2296 r_write_to_tgt_rsp_req = true; 2297 r_write_to_tgt_rsp_srcid = r_write_srcid.read(); 2298 r_write_to_tgt_rsp_trdid = r_write_trdid.read(); 2299 r_write_to_tgt_rsp_pktid = r_write_pktid.read(); 2300 2301 // try to get a new write request from the FIFO 2302 if ( m_cmd_write_addr_fifo.rok() ) 2303 { 2304 m_cpt_write++; 2305 m_cpt_write_cells++; 2306 2307 // consume a word in the FIFO & write it in the local buffer 2308 cmd_write_fifo_get = true; 2309 size_t index = m_x[(vci_addr_t)(m_cmd_write_addr_fifo.read())]; 2310 2311 r_write_address = (addr_t)(m_cmd_write_addr_fifo.read()); 2312 r_write_word_index = index; 2313 r_write_word_count = 1; 2314 r_write_data[index] = m_cmd_write_data_fifo.read(); 2315 r_write_srcid = m_cmd_write_srcid_fifo.read(); 2316 r_write_trdid = m_cmd_write_trdid_fifo.read(); 2317 r_write_pktid = m_cmd_write_pktid_fifo.read(); 2318 2319 // initialize the be field for all words 2320 for ( size_t i=0 ; i<m_words ; i++ ) 2321 { 2322 if ( i == index ) r_write_be[i] = m_cmd_write_be_fifo.read(); 2323 else r_write_be[i] = 0x0; 2324 } 2325 2326 if( !((m_cmd_write_be_fifo.read() == 0x0)||(m_cmd_write_be_fifo.read() == 0xF)) ) 2327 r_write_byte = true; 2328 else 2329 r_write_byte = false; 2330 2331 if( m_cmd_write_eop_fifo.read() ) 2332 { 2333 r_write_fsm = WRITE_DIR_REQ; 2334 } 2335 else 2336 { 2337 r_write_fsm = WRITE_NEXT; 2338 } 2339 } 2340 else 2341 { 2342 r_write_fsm = WRITE_IDLE; 2343 } 2344 2345 #if DEBUG_MEMC_WRITE 2346 if( m_debug_write_fsm ) 2347 { 2348 std::cout << " <MEMC " << name() << ".WRITE_RSP> Post a request to TGT_RSP FSM: rsrcid = " 2349 << std::dec << r_write_srcid.read() << std::endl; 2350 if ( m_cmd_write_addr_fifo.rok() ) 2351 { 2352 std::cout << " New Write request: " 1632 2353 << " srcid = " << std::dec << m_cmd_write_srcid_fifo.read() 1633 << " / address = " << std::hex << m_cmd_write_addr_fifo.read() 2354 << " / address = " << std::hex << m_cmd_write_addr_fifo.read() 1634 2355 << " / data = " << m_cmd_write_data_fifo.read() << std::endl; 1635 } 1636 #endif 1637 } 1638 break; 1639 } 1640 //////////////// 1641 case WRITE_NEXT: // copy next word of a write burst in local buffer 1642 { 1643 if ( m_cmd_write_addr_fifo.rok() ) 1644 { 2356 } 2357 } 2358 #endif 2359 } 2360 break; 2361 } 2362 2363 ///////////////////////// 2364 case WRITE_MISS_TRT_LOCK: // Miss : check Transaction Table 2365 { 2366 if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE ) 2367 { 1645 2368 1646 2369 #if DEBUG_MEMC_WRITE 1647 if( m_debug_write_fsm ) 1648 { 1649 std::cout << " <MEMC " << name() << ".WRITE_NEXT> Write another word in local buffer" << std::endl; 1650 } 1651 #endif 1652 m_cpt_write_cells++; 1653 1654 // check that the next word is in the same cache line 1655 if ( (m_nline[(vci_addr_t)(r_write_address.read())] != 1656 m_nline[(vci_addr_t)(m_cmd_write_addr_fifo.read())]) ) 1657 { 1658 std::cout << "VCI_MEM_CACHE ERROR " << name() << " WRITE_NEXT state" << std::endl; 1659 std::cout << "all words in a write burst must be in same cache line" << std::endl; 1660 exit(0); 1661 } 1662 1663 // consume a word in the FIFO & write it in the local buffer 1664 cmd_write_fifo_get=true; 1665 size_t index = r_write_word_index.read() + r_write_word_count.read(); 1666 1667 r_write_be[index] = m_cmd_write_be_fifo.read(); 1668 r_write_data[index] = m_cmd_write_data_fifo.read(); 1669 r_write_word_count = r_write_word_count.read() + 1; 1670 1671 if( !((m_cmd_write_be_fifo.read() == 0x0)||(m_cmd_write_be_fifo.read() == 0xF)) ) 1672 r_write_byte = true; 1673 1674 if ( m_cmd_write_eop_fifo.read() ) r_write_fsm = WRITE_DIR_LOCK; 1675 } 1676 break; 1677 } 1678 //////////////////// 1679 case WRITE_DIR_LOCK: // access directory to check hit/miss 1680 { 1681 if ( r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE ) 1682 { 1683 size_t way = 0; 1684 DirectoryEntry entry(m_cache_directory.read(r_write_address.read(), way)); 1685 1686 if ( entry.valid ) // hit 1687 { 1688 // copy directory entry in local buffer in case of hit 1689 r_write_is_cnt = entry.is_cnt; 1690 r_write_lock = entry.lock; 1691 r_write_tag = entry.tag; 1692 r_write_copy = entry.owner.srcid; 2370 if( m_debug_write_fsm ) 2371 { 2372 std::cout << " <MEMC " << name() << ".WRITE_MISS_TRT_LOCK> Check the TRT" << std::endl; 2373 } 2374 #endif 2375 size_t hit_index = 0; 2376 size_t wok_index = 0; 2377 vci_addr_t addr = (vci_addr_t)r_write_address.read(); 2378 bool hit_read = m_transaction_tab.hit_read(m_nline[addr], hit_index); 2379 bool hit_write = m_transaction_tab.hit_write(m_nline[addr]); 2380 bool wok = !m_transaction_tab.full(wok_index); 2381 2382 if ( hit_read ) // register the modified data in TRT 2383 { 2384 r_write_trt_index = hit_index; 2385 r_write_fsm = WRITE_MISS_TRT_DATA; 2386 m_cpt_write_miss++; 2387 } 2388 else if ( wok && !hit_write ) // set a new entry in TRT 2389 { 2390 r_write_trt_index = wok_index; 2391 r_write_fsm = WRITE_MISS_TRT_SET; 2392 m_cpt_write_miss++; 2393 } 2394 else // wait an empty entry in TRT 2395 { 2396 r_write_fsm = WRITE_WAIT; 2397 m_cpt_trt_full++; 2398 } 2399 } 2400 break; 2401 } 2402 2403 //////////////// 2404 case WRITE_WAIT: // release the locks protecting the shared ressources 2405 { 2406 #if DEBUG_MEMC_WRITE 2407 if( m_debug_write_fsm ) 2408 { 2409 std::cout << " <MEMC " << name() << ".WRITE_WAIT> Releases the locks before retry" << std::endl; 2410 } 2411 #endif 2412 r_write_fsm = WRITE_DIR_REQ; 2413 break; 2414 } 2415 2416 //////////////////////// 2417 case WRITE_MISS_TRT_SET: // register a new transaction in TRT (Write Buffer) 2418 { 2419 if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE ) 2420 { 2421 std::vector<be_t> be_vector; 2422 std::vector<data_t> data_vector; 2423 be_vector.clear(); 2424 data_vector.clear(); 2425 for ( size_t i=0; i<m_words; i++ ) 2426 { 2427 be_vector.push_back(r_write_be[i]); 2428 data_vector.push_back(r_write_data[i]); 2429 } 2430 m_transaction_tab.set(r_write_trt_index.read(), 2431 true, // read request to XRAM 2432 m_nline[(vci_addr_t)(r_write_address.read())], 2433 r_write_srcid.read(), 2434 r_write_trdid.read(), 2435 r_write_pktid.read(), 2436 false, // not a processor read 2437 0, // not a single word 2438 0, // word index 2439 be_vector, 2440 data_vector); 2441 r_write_fsm = WRITE_MISS_XRAM_REQ; 2442 2443 #if DEBUG_MEMC_WRITE 2444 if( m_debug_write_fsm ) 2445 { 2446 std::cout << " <MEMC " << name() << ".WRITE_MISS_TRT_SET> Set a new entry in TRT" << std::endl; 2447 } 2448 #endif 2449 } 2450 break; 2451 } 2452 2453 ///////////////////////// 2454 case WRITE_MISS_TRT_DATA: // update an entry in TRT (used as a Write Buffer) 2455 { 2456 if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE ) 2457 { 2458 std::vector<be_t> be_vector; 2459 std::vector<data_t> data_vector; 2460 be_vector.clear(); 2461 data_vector.clear(); 2462 for ( size_t i=0; i<m_words; i++ ) 2463 { 2464 be_vector.push_back(r_write_be[i]); 2465 data_vector.push_back(r_write_data[i]); 2466 } 2467 m_transaction_tab.write_data_mask(r_write_trt_index.read(), 2468 be_vector, 2469 data_vector); 2470 r_write_fsm = WRITE_RSP; 2471 2472 #if DEBUG_MEMC_WRITE 2473 if( m_debug_write_fsm ) 2474 { 2475 std::cout << " <MEMC " << name() << ".WRITE_MISS_TRT_DATA> Modify an existing entry in TRT" << std::endl; 2476 m_transaction_tab.print( r_write_trt_index.read() ); 2477 } 2478 #endif 2479 } 2480 break; 2481 } 2482 2483 ///////////////////////// 2484 case WRITE_MISS_XRAM_REQ: // send a GET request to IXR_CMD FSM 2485 { 2486 if ( !r_write_to_ixr_cmd_req ) 2487 { 2488 r_write_to_ixr_cmd_req = true; 2489 r_write_to_ixr_cmd_write = false; 2490 r_write_to_ixr_cmd_nline = m_nline[(vci_addr_t)(r_write_address.read())]; 2491 r_write_to_ixr_cmd_trdid = r_write_trt_index.read(); 2492 r_write_fsm = WRITE_RSP; 2493 2494 #if DEBUG_MEMC_WRITE 2495 if( m_debug_write_fsm ) 2496 { 2497 std::cout << " <MEMC " << name() << ".WRITE_MISS_XRAM_REQ> Post a GET request to the IXR_CMD FSM" << std::endl; 2498 } 2499 #endif 2500 } 2501 break; 2502 } 2503 2504 /////////////////////// 2505 case WRITE_BC_TRT_LOCK: // Check TRT not full 2506 { 2507 if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE ) 2508 { 2509 size_t wok_index = 0; 2510 bool wok = !m_transaction_tab.full( wok_index ); 2511 if ( wok ) // set a new entry in TRT 2512 { 2513 r_write_trt_index = wok_index; 2514 r_write_fsm = WRITE_BC_UPT_LOCK; 2515 } 2516 else // wait an empty entry in TRT 2517 { 2518 r_write_fsm = WRITE_WAIT; 2519 } 2520 2521 #if DEBUG_MEMC_WRITE 2522 if( m_debug_write_fsm ) 2523 { 2524 std::cout << " <MEMC " << name() << ".WRITE_BC_TRT_LOCK> Check TRT : wok = " 2525 << wok << " / index = " << wok_index << std::endl; 2526 } 2527 #endif 2528 } 2529 break; 2530 } 2531 2532 ////////////////////// 2533 case WRITE_BC_UPT_LOCK: // register BC transaction in UPT 2534 { 2535 if ( r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE ) 2536 { 2537 bool wok = false; 2538 size_t index = 0; 2539 size_t srcid = r_write_srcid.read(); 2540 size_t trdid = r_write_trdid.read(); 2541 size_t pktid = r_write_pktid.read(); 2542 addr_t nline = m_nline[(vci_addr_t)(r_write_address.read())]; 2543 size_t nb_copies = r_write_count.read(); 2544 2545 wok =m_update_tab.set(false, // it's an inval transaction 2546 true, // it's a broadcast 2547 true, // it needs a response 2548 srcid, 2549 trdid, 2550 pktid, 2551 nline, 2552 nb_copies, 2553 index); 2554 2555 #if DEBUG_MEMC_WRITE 2556 if( m_debug_write_fsm ) 2557 { 2558 if ( wok ) 2559 { 2560 std::cout << " <MEMC " << name() << ".WRITE_BC_UPT_LOCK> Register the broadcast inval in UPT / " 2561 << " nb_copies = " << r_write_count.read() << std::endl; 2562 } 2563 } 2564 #endif 2565 r_write_upt_index = index; 2566 2567 if ( wok ) r_write_fsm = WRITE_BC_DIR_INVAL; 2568 else r_write_fsm = WRITE_WAIT; 2569 } 2570 break; 2571 } 2572 2573 //////////////////////// 2574 case WRITE_BC_DIR_INVAL: 2575 { 2576 // Register a put transaction to XRAM in TRT 2577 // and invalidate the line in directory 2578 if ( (r_alloc_trt_fsm.read() != ALLOC_TRT_WRITE ) || 2579 (r_alloc_upt_fsm.read() != ALLOC_UPT_WRITE ) || 2580 (r_alloc_dir_fsm.read() != ALLOC_DIR_WRITE ) ) 2581 { 2582 std::cout << "VCI_MEM_CACHE ERROR " << name() << " WRITE_BC_DIR_INVAL state" << std::endl; 2583 std::cout << "bad TRT, DIR, or UPT allocation" << std::endl; 2584 exit(0); 2585 } 2586 2587 // register a write request to XRAM in TRT 2588 m_transaction_tab.set(r_write_trt_index.read(), 2589 false, // write request to XRAM 2590 m_nline[(vci_addr_t)(r_write_address.read())], 2591 0, 2592 0, 2593 0, 2594 false, // not a processor read 2595 0, // not a single word 2596 0, // word index 2597 std::vector<be_t>(m_words,0), 2598 std::vector<data_t>(m_words,0)); 2599 2600 // invalidate directory entry 2601 DirectoryEntry entry; 2602 entry.valid = false; 2603 entry.dirty = false; 2604 entry.tag = 0; 2605 entry.is_cnt = false; 2606 entry.lock = false; 2607 entry.owner.srcid = 0; 1693 2608 #if L1_MULTI_CACHE 1694 r_write_copy_cache = entry.owner.cache_id; 1695 #endif 1696 r_write_copy_inst = entry.owner.inst; 1697 r_write_count = entry.count; 1698 r_write_ptr = entry.ptr; 1699 r_write_way = way; 1700 1701 if( entry.is_cnt && entry.count ) 1702 { 1703 r_write_fsm = WRITE_DIR_READ; 1704 } 1705 else 1706 { 1707 if (r_write_byte.read()) r_write_fsm = WRITE_DIR_READ; 1708 else r_write_fsm = WRITE_DIR_HIT; 1709 } 1710 } 1711 else // miss 1712 { 1713 r_write_fsm = WRITE_MISS_TRT_LOCK; 1714 } 2609 entry.owner.cache_id= 0; 2610 #endif 2611 entry.owner.inst = false; 2612 entry.ptr = 0; 2613 entry.count = 0; 2614 size_t set = m_y[(vci_addr_t)(r_write_address.read())]; 2615 size_t way = r_write_way.read(); 2616 2617 m_cache_directory.write(set, way, entry); 1715 2618 1716 2619 #if DEBUG_MEMC_WRITE 1717 if( m_debug_write_fsm ) 1718 { 1719 std::cout << " <MEMC " << name() << ".WRITE_DIR_LOCK> Check the directory: " 1720 << " address = " << std::hex << r_write_address.read() 1721 << " hit = " << std::dec << entry.valid 1722 << " count = " << entry.count 1723 << " is_cnt = " << entry.is_cnt << std::endl; 1724 } 1725 #endif 1726 } 1727 break; 1728 } 1729 //////////////////// 1730 case WRITE_DIR_READ: // read the cache and complete the buffer when be!=0xF 1731 { 1732 // update local buffer 1733 size_t set = m_y[(vci_addr_t)(r_write_address.read())]; 1734 size_t way = r_write_way.read(); 1735 for(size_t i=0 ; i<m_words ; i++) 1736 { 1737 data_t mask = 0; 1738 if (r_write_be[i].read() & 0x1) mask = mask | 0x000000FF; 1739 if (r_write_be[i].read() & 0x2) mask = mask | 0x0000FF00; 1740 if (r_write_be[i].read() & 0x4) mask = mask | 0x00FF0000; 1741 if (r_write_be[i].read() & 0x8) mask = mask | 0xFF000000; 1742 1743 // complete only if mask is not null (for energy consumption) 1744 if ( r_write_be[i].read() || r_write_is_cnt.read() ) 1745 { 1746 r_write_data[i] = (r_write_data[i].read() & mask) | 1747 (m_cache_data[way][set][i] & ~mask); 1748 } 1749 } // end for 1750 1751 // test if a coherence broadcast is required 1752 if( r_write_is_cnt.read() && r_write_count.read() ) r_write_fsm = WRITE_BC_TRT_LOCK; 1753 else r_write_fsm = WRITE_DIR_HIT; 2620 if( m_debug_write_fsm ) 2621 { 2622 std::cout << " <MEMC " << name() << ".WRITE_BC_DIR_INVAL> Invalidate the directory entry: @ = " 2623 << r_write_address.read() << " / register the put transaction in TRT:" << std::endl; 2624 } 2625 #endif 2626 r_write_fsm = WRITE_BC_CC_SEND; 2627 break; 2628 } 2629 2630 ////////////////////// 2631 case WRITE_BC_CC_SEND: // Post a coherence broadcast request to INIT_CMD FSM 2632 { 2633 if ( !r_write_to_init_cmd_multi_req.read() && !r_write_to_init_cmd_brdcast_req.read() ) 2634 { 2635 r_write_to_init_cmd_multi_req = false; 2636 r_write_to_init_cmd_brdcast_req = true; 2637 r_write_to_init_cmd_trdid = r_write_upt_index.read(); 2638 r_write_to_init_cmd_nline = m_nline[(vci_addr_t)(r_write_address.read())]; 2639 r_write_to_init_cmd_index = 0; 2640 r_write_to_init_cmd_count = 0; 2641 2642 for(size_t i=0; i<m_words ; i++) 2643 { 2644 r_write_to_init_cmd_be[i]=0; 2645 r_write_to_init_cmd_data[i] = 0; 2646 } 2647 r_write_fsm = WRITE_BC_XRAM_REQ; 1754 2648 1755 2649 #if DEBUG_MEMC_WRITE 1756 if( m_debug_write_fsm ) 1757 { 1758 std::cout << " <MEMC " << name() << ".WRITE_DIR_READ> Read the cache to complete local buffer" << std::endl; 1759 } 1760 #endif 1761 break; 1762 } 1763 /////////////////// 1764 case WRITE_DIR_HIT: // update the cache directory 1765 { 1766 // update directory with Dirty bit 1767 DirectoryEntry entry; 1768 entry.valid = true; 1769 entry.dirty = true; 1770 entry.tag = r_write_tag.read(); 1771 entry.is_cnt = r_write_is_cnt.read(); 1772 entry.lock = r_write_lock.read(); 1773 entry.owner.srcid = r_write_copy.read(); 1774 #if L1_MULTI_CACHE 1775 entry.owner.cache_id = r_write_copy_cache.read(); 1776 #endif 1777 entry.owner.inst = r_write_copy_inst.read(); 1778 entry.count = r_write_count.read(); 1779 entry.ptr = r_write_ptr.read(); 1780 size_t set = m_y[(vci_addr_t)(r_write_address.read())]; 1781 size_t way = r_write_way.read(); 1782 1783 // update directory 1784 m_cache_directory.write(set, way, entry); 1785 1786 // owner is true when the the first registered copy is the writer itself 1787 bool owner = (((r_write_copy.read() == r_write_srcid.read()) 1788 #if L1_MULTI_CACHE 1789 and (r_write_copy_cache.read()==r_write_pktid.read()) 1790 #endif 1791 ) and not r_write_copy_inst.read()); 1792 1793 // no_update is true when there is no need for coherence transaction 1794 bool no_update = (r_write_count.read()==0) || ( owner && (r_write_count.read()==1)); 1795 1796 // write data in the cache if no coherence transaction 1797 if( no_update ) 1798 { 1799 for(size_t i=0 ; i<m_words ; i++) 1800 { 1801 if ( r_write_be[i].read() ) 1802 { 1803 m_cache_data[way][set][i] = r_write_data[i].read(); 1804 1805 if ( m_monitor_ok ) 1806 { 1807 vci_addr_t address = (r_write_address.read() & ~(vci_addr_t)0x3F) | i<<2; 1808 char buf[80]; 1809 snprintf(buf, 80, "WRITE_DIR_HIT srcid %d", r_write_srcid.read()); 1810 check_monitor( buf, address, r_write_data[i].read() ); 1811 } 1812 } 1813 } 1814 } 1815 1816 if ( owner and not no_update ) r_write_count = r_write_count.read() - 1; 1817 1818 if ( no_update ) // Write transaction completed 1819 { 1820 r_write_fsm = WRITE_RSP; 1821 } 1822 else // coherence update required 1823 { 1824 if( !r_write_to_init_cmd_multi_req.read() && 1825 !r_write_to_init_cmd_brdcast_req.read() ) r_write_fsm = WRITE_UPT_LOCK; 1826 else r_write_fsm = WRITE_WAIT; 1827 } 2650 if( m_debug_write_fsm ) 2651 { 2652 std::cout << " <MEMC " << name() << ".WRITE_BC_CC_SEND> Post a broadcast request to INIT_CMD FSM" << std::endl; 2653 } 2654 #endif 2655 } 2656 break; 2657 } 2658 2659 /////////////////////// 2660 case WRITE_BC_XRAM_REQ: // Post a put request to IXR_CMD FSM 2661 { 2662 if ( !r_write_to_ixr_cmd_req ) 2663 { 2664 r_write_to_ixr_cmd_req = true; 2665 r_write_to_ixr_cmd_write = true; 2666 r_write_to_ixr_cmd_nline = m_nline[(vci_addr_t)(r_write_address.read())]; 2667 r_write_to_ixr_cmd_trdid = r_write_trt_index.read(); 2668 2669 for(size_t i=0; i<m_words; i++) r_write_to_ixr_cmd_data[i] = r_write_data[i]; 2670 2671 r_write_fsm = WRITE_IDLE; 1828 2672 1829 2673 #if DEBUG_MEMC_WRITE 1830 if( m_debug_write_fsm ) 1831 { 1832 if ( no_update ) 1833 { 1834 std::cout << " <MEMC " << name() << ".WRITE_DIR_HIT> Write into cache / No coherence transaction" 1835 << std::endl; 2674 if( m_debug_write_fsm ) 2675 { 2676 std::cout << " <MEMC " << name() << ".WRITE_BC_XRAM_REQ> Post a put request to IXR_CMD FSM" << std::endl; 2677 } 2678 #endif 2679 } 2680 break; 1836 2681 } 1837 else 1838 { 1839 std::cout << " <MEMC " << name() << ".WRITE_DIR_HIT> Coherence update required:" 1840 << " is_cnt = " << r_write_is_cnt.read() 1841 << " nb_copies = " << std::dec << r_write_count.read() << std::endl; 1842 if (owner) 1843 std::cout << " ... but the first copy is the writer" << std::endl; 1844 } 1845 } 1846 #endif 1847 break; 1848 } 1849 //////////////////// 1850 case WRITE_UPT_LOCK: // Try to register the update request in UPT 1851 { 1852 if ( r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE ) 1853 { 1854 bool wok = false; 1855 size_t index = 0; 1856 size_t srcid = r_write_srcid.read(); 1857 size_t trdid = r_write_trdid.read(); 1858 size_t pktid = r_write_pktid.read(); 1859 addr_t nline = m_nline[(vci_addr_t)(r_write_address.read())]; 1860 size_t nb_copies = r_write_count.read(); 1861 size_t set = m_y[(vci_addr_t)(r_write_address.read())]; 1862 size_t way = r_write_way.read(); 1863 1864 wok = m_update_tab.set(true, // it's an update transaction 1865 false, // it's not a broadcast 1866 true, // it needs a response 1867 srcid, 1868 trdid, 1869 pktid, 1870 nline, 1871 nb_copies, 1872 index); 1873 if ( wok ) // write data in cache 1874 { 1875 for(size_t i=0 ; i<m_words ; i++) 1876 { 1877 if ( r_write_be[i].read() ) 1878 { 1879 m_cache_data[way][set][i] = r_write_data[i].read(); 1880 1881 if ( m_monitor_ok ) 1882 { 1883 vci_addr_t address = (r_write_address.read() & ~(vci_addr_t)0x3F) | i<<2; 1884 char buf[80]; 1885 snprintf(buf, 80, "WRITE_UPT_LOCK srcid %d", srcid); 1886 check_monitor(buf, address, r_write_data[i].read() ); 1887 } 1888 } 1889 } 1890 } 1891 1892 #if DEBUG_MEMC_WRITE 1893 if( m_debug_write_fsm ) 1894 { 1895 if ( wok ) 1896 { 1897 std::cout << " <MEMC " << name() << ".WRITE_UPT_LOCK> Register the multicast update in UPT / " 1898 << " nb_copies = " << r_write_count.read() << std::endl; 1899 } 1900 } 1901 #endif 1902 r_write_upt_index = index; 1903 // releases the lock protecting UPT and the DIR if no entry... 1904 if ( wok ) r_write_fsm = WRITE_UPT_HEAP_LOCK; 1905 else r_write_fsm = WRITE_WAIT; 1906 } 1907 break; 1908 } 1909 ///////////////////////// 1910 case WRITE_UPT_HEAP_LOCK: // get access to heap 1911 { 1912 if( r_alloc_heap_fsm.read() == ALLOC_HEAP_WRITE ) 1913 { 1914 1915 #if DEBUG_MEMC_WRITE 1916 if( m_debug_write_fsm ) 1917 { 1918 std::cout << " <MEMC " << name() << ".WRITE_UPT_HEAP_LOCK> Get acces to the HEAP" << std::endl; 1919 } 1920 #endif 1921 r_write_fsm = WRITE_UPT_REQ; 1922 } 1923 break; 1924 } 1925 ////////////////// 1926 case WRITE_UPT_REQ: // prepare the coherence ransaction for the INIT_CMD FSM 1927 // and write the first copy in the FIFO 1928 // send the request if only one copy 1929 { 1930 if( !r_write_to_init_cmd_multi_req.read() && 1931 !r_write_to_init_cmd_brdcast_req.read() ) // no pending coherence request 1932 { 1933 r_write_to_init_cmd_brdcast_req = false; 1934 r_write_to_init_cmd_trdid = r_write_upt_index.read(); 1935 r_write_to_init_cmd_nline = m_nline[(vci_addr_t)(r_write_address.read())]; 1936 r_write_to_init_cmd_index = r_write_word_index.read(); 1937 r_write_to_init_cmd_count = r_write_word_count.read(); 1938 1939 for(size_t i=0; i<m_words ; i++) r_write_to_init_cmd_be[i]=r_write_be[i].read(); 1940 1941 size_t min = r_write_word_index.read(); 1942 size_t max = r_write_word_index.read() + r_write_word_count.read(); 1943 for (size_t i=min ; i<max ; i++) r_write_to_init_cmd_data[i] = r_write_data[i]; 1944 1945 if( (r_write_copy.read() != r_write_srcid.read()) or 1946 #if L1_MULTI_CACHE 1947 (r_write_copy_cache.read() != r_write_pktid.read()) or 1948 #endif 1949 r_write_copy_inst.read() ) 1950 { 1951 // put the first srcid in the fifo 1952 write_to_init_cmd_fifo_put = true; 1953 write_to_init_cmd_fifo_inst = r_write_copy_inst.read(); 1954 write_to_init_cmd_fifo_srcid = r_write_copy.read(); 1955 #if L1_MULTI_CACHE 1956 write_to_init_cmd_fifo_cache_id= r_write_copy_cache.read(); 1957 #endif 1958 if(r_write_count.read() == 1) 1959 { 1960 r_write_fsm = WRITE_IDLE; 1961 r_write_to_init_cmd_multi_req = true; 1962 } 1963 else 1964 { 1965 r_write_fsm = WRITE_UPT_NEXT; 1966 r_write_to_dec = false; 1967 1968 } 1969 } 1970 else 1971 { 1972 r_write_fsm = WRITE_UPT_NEXT; 1973 r_write_to_dec = false; 1974 } 1975 1976 #if DEBUG_MEMC_WRITE 1977 if( m_debug_write_fsm ) 1978 { 1979 std::cout << " <MEMC " << name() << ".WRITE_UPT_REQ> Post first request to INIT_CMD FSM" 1980 << " / srcid = " << std::dec << r_write_copy.read() 1981 << " / inst = " << std::dec << r_write_copy_inst.read() << std::endl; 1982 if ( r_write_count.read() == 1) 1983 std::cout << " ... and this is the last" << std::endl; 1984 } 1985 #endif 1986 } 1987 break; 1988 } 1989 /////////////////// 1990 case WRITE_UPT_NEXT: // continue the multi-update request to INIT_CMD fsm 1991 // when there is copies in the heap. 1992 // if one copy in the heap is the writer itself 1993 // the corresponding SRCID should not be written in the fifo, 1994 // but the UPT counter must be decremented. 1995 // As this decrement is done in the WRITE_UPT_DEC state, 1996 // after the last copy has been found, the decrement request 1997 // must be registered in the r_write_to_dec flip-flop. 1998 { 1999 HeapEntry entry = m_heap.read(r_write_ptr.read()); 2000 2001 bool dec_upt_counter; 2002 2003 if( (entry.owner.srcid != r_write_srcid.read()) or 2004 #if L1_MULTI_CACHE 2005 (entry.owner.cache_id != r_write_pktid.read()) or 2006 #endif 2007 entry.owner.inst) // put te next srcid in the fifo 2008 { 2009 dec_upt_counter = false; 2010 write_to_init_cmd_fifo_put = true; 2011 write_to_init_cmd_fifo_inst = entry.owner.inst; 2012 write_to_init_cmd_fifo_srcid = entry.owner.srcid; 2013 #if L1_MULTI_CACHE 2014 write_to_init_cmd_fifo_cache_id = entry.owner.cache_id; 2015 #endif 2016 2017 #if DEBUG_MEMC_WRITE 2018 if( m_debug_write_fsm ) 2019 { 2020 std::cout << " <MEMC " << name() << ".WRITE_UPT_NEXT> Post another request to INIT_CMD FSM" 2021 << " / heap_index = " << std::dec << r_write_ptr.read() 2022 << " / srcid = " << std::dec << r_write_copy.read() 2023 << " / inst = " << std::dec << r_write_copy_inst.read() << std::endl; 2024 if( entry.next == r_write_ptr.read() ) 2025 std::cout << " ... and this is the last" << std::endl; 2026 } 2027 #endif 2028 } 2029 else // the UPT counter must be decremented 2030 { 2031 dec_upt_counter = true; 2032 2033 #if DEBUG_MEMC_WRITE 2034 if( m_debug_write_fsm ) 2035 { 2036 std::cout << " <MEMC " << name() << ".WRITE_UPT_NEXT> Skip one entry in heap matching the writer" 2037 << " / heap_index = " << std::dec << r_write_ptr.read() 2038 << " / srcid = " << std::dec << r_write_copy.read() 2039 << " / inst = " << std::dec << r_write_copy_inst.read() << std::endl; 2040 if( entry.next == r_write_ptr.read() ) 2041 std::cout << " ... and this is the last" << std::endl; 2042 } 2043 #endif 2044 } 2045 2046 // register the possible UPT decrement request 2047 r_write_to_dec = dec_upt_counter or r_write_to_dec.read(); 2048 2049 if( not m_write_to_init_cmd_inst_fifo.wok() ) 2050 { 2051 std::cout << "VCI_MEM_CACHE ERROR " << name() << " WRITE_UPT_NEXT state" << std::endl 2052 << "The write_to_init_cmd_fifo should not be full" << std::endl 2053 << "as the depth should be larger than the max number of copies" << std::endl; 2054 exit(0); 2055 } 2056 2057 r_write_ptr = entry.next; 2058 2059 if( entry.next == r_write_ptr.read() ) // last copy 2060 { 2061 r_write_to_init_cmd_multi_req = true; 2062 if( r_write_to_dec.read() or dec_upt_counter) r_write_fsm = WRITE_UPT_DEC; 2063 else r_write_fsm = WRITE_IDLE; 2064 } 2065 break; 2066 } 2067 ////////////////// 2068 case WRITE_UPT_DEC: // If the initial writer has a copy, it should not 2069 // receive an update request, but the counter in the 2070 // update table must be decremented by the INIT_RSP FSM. 2071 { 2072 if ( !r_write_to_init_rsp_req.read() ) 2073 { 2074 r_write_to_init_rsp_req = true; 2075 r_write_to_init_rsp_upt_index = r_write_upt_index.read(); 2076 r_write_fsm = WRITE_IDLE; 2077 } 2078 break; 2079 } 2080 /////////////// 2081 case WRITE_RSP: // Post a request to TGT_RSP FSM to acknowledge the write 2082 // In order to increase the Write requests throughput, 2083 // we don't wait to return in the IDLE state to consume 2084 // a new request in the write FIFO 2085 { 2086 if ( !r_write_to_tgt_rsp_req.read() ) 2087 { 2088 // post the request to TGT_RSP_FSM 2089 r_write_to_tgt_rsp_req = true; 2090 r_write_to_tgt_rsp_srcid = r_write_srcid.read(); 2091 r_write_to_tgt_rsp_trdid = r_write_trdid.read(); 2092 r_write_to_tgt_rsp_pktid = r_write_pktid.read(); 2093 2094 // try to get a new write request from the FIFO 2095 if ( m_cmd_write_addr_fifo.rok() ) 2096 { 2097 m_cpt_write++; 2098 m_cpt_write_cells++; 2099 2100 // consume a word in the FIFO & write it in the local buffer 2101 cmd_write_fifo_get = true; 2102 size_t index = m_x[(vci_addr_t)(m_cmd_write_addr_fifo.read())]; 2103 2104 r_write_address = (addr_t)(m_cmd_write_addr_fifo.read()); 2105 r_write_word_index = index; 2106 r_write_word_count = 1; 2107 r_write_data[index] = m_cmd_write_data_fifo.read(); 2108 r_write_srcid = m_cmd_write_srcid_fifo.read(); 2109 r_write_trdid = m_cmd_write_trdid_fifo.read(); 2110 r_write_pktid = m_cmd_write_pktid_fifo.read(); 2111 2112 // initialize the be field for all words 2113 for ( size_t i=0 ; i<m_words ; i++ ) 2114 { 2115 if ( i == index ) r_write_be[i] = m_cmd_write_be_fifo.read(); 2116 else r_write_be[i] = 0x0; 2117 } 2118 2119 if( !((m_cmd_write_be_fifo.read() == 0x0)||(m_cmd_write_be_fifo.read() == 0xF)) ) 2120 r_write_byte = true; 2121 else 2122 r_write_byte = false; 2123 2124 if( m_cmd_write_eop_fifo.read() ) r_write_fsm = WRITE_DIR_LOCK; 2125 else r_write_fsm = WRITE_NEXT; 2126 } 2127 else 2128 { 2129 r_write_fsm = WRITE_IDLE; 2130 } 2131 2132 #if DEBUG_MEMC_WRITE 2133 if( m_debug_write_fsm ) 2134 { 2135 std::cout << " <MEMC " << name() << ".WRITE_RSP> Post a request to TGT_RSP FSM: rsrcid = " 2136 << std::dec << r_write_srcid.read() << std::endl; 2137 if ( m_cmd_write_addr_fifo.rok() ) 2138 { 2139 std::cout << " New Write request: " 2140 << " srcid = " << std::dec << m_cmd_write_srcid_fifo.read() 2141 << " / address = " << std::hex << m_cmd_write_addr_fifo.read() 2142 << " / data = " << m_cmd_write_data_fifo.read() << std::endl; 2143 } 2144 } 2145 #endif 2146 } 2147 break; 2148 } 2149 ///////////////////////// 2150 case WRITE_MISS_TRT_LOCK: // Miss : check Transaction Table 2151 { 2152 if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE ) 2153 { 2154 2155 #if DEBUG_MEMC_WRITE 2156 if( m_debug_write_fsm ) 2157 { 2158 std::cout << " <MEMC " << name() << ".WRITE_MISS_TRT_LOCK> Check the TRT" << std::endl; 2159 } 2160 #endif 2161 size_t hit_index = 0; 2162 size_t wok_index = 0; 2163 vci_addr_t addr = (vci_addr_t)r_write_address.read(); 2164 bool hit_read = m_transaction_tab.hit_read(m_nline[addr], hit_index); 2165 bool hit_write = m_transaction_tab.hit_write(m_nline[addr]); 2166 bool wok = !m_transaction_tab.full(wok_index); 2167 2168 if ( hit_read ) // register the modified data in TRT 2169 { 2170 r_write_trt_index = hit_index; 2171 r_write_fsm = WRITE_MISS_TRT_DATA; 2172 m_cpt_write_miss++; 2173 } 2174 else if ( wok && !hit_write ) // set a new entry in TRT 2175 { 2176 r_write_trt_index = wok_index; 2177 r_write_fsm = WRITE_MISS_TRT_SET; 2178 m_cpt_write_miss++; 2179 } 2180 else // wait an empty entry in TRT 2181 { 2182 r_write_fsm = WRITE_WAIT; 2183 m_cpt_trt_full++; 2184 } 2185 } 2186 break; 2187 } 2188 //////////////// 2189 case WRITE_WAIT: // release the locks protecting the shared ressources 2190 { 2191 2192 #if DEBUG_MEMC_WRITE 2193 if( m_debug_write_fsm ) 2194 { 2195 std::cout << " <MEMC " << name() << ".WRITE_WAIT> Releases the locks before retry" << std::endl; 2196 } 2197 #endif 2198 r_write_fsm = WRITE_DIR_LOCK; 2199 break; 2200 } 2201 //////////////////////// 2202 case WRITE_MISS_TRT_SET: // register a new transaction in TRT (Write Buffer) 2203 { 2204 if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE ) 2205 { 2206 std::vector<be_t> be_vector; 2207 std::vector<data_t> data_vector; 2208 be_vector.clear(); 2209 data_vector.clear(); 2210 for ( size_t i=0; i<m_words; i++ ) 2211 { 2212 be_vector.push_back(r_write_be[i]); 2213 data_vector.push_back(r_write_data[i]); 2214 } 2215 m_transaction_tab.set(r_write_trt_index.read(), 2216 true, // read request to XRAM 2217 m_nline[(vci_addr_t)(r_write_address.read())], 2218 r_write_srcid.read(), 2219 r_write_trdid.read(), 2220 r_write_pktid.read(), 2221 false, // not a processor read 2222 0, // not a single word 2223 0, // word index 2224 be_vector, 2225 data_vector); 2226 r_write_fsm = WRITE_MISS_XRAM_REQ; 2227 2228 #if DEBUG_MEMC_WRITE 2229 if( m_debug_write_fsm ) 2230 { 2231 std::cout << " <MEMC " << name() << ".WRITE_MISS_TRT_SET> Set a new entry in TRT" << std::endl; 2232 } 2233 #endif 2234 } 2235 break; 2236 } 2237 ///////////////////////// 2238 case WRITE_MISS_TRT_DATA: // update an entry in TRT (used as a Write Buffer) 2239 { 2240 if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE ) 2241 { 2242 std::vector<be_t> be_vector; 2243 std::vector<data_t> data_vector; 2244 be_vector.clear(); 2245 data_vector.clear(); 2246 for ( size_t i=0; i<m_words; i++ ) 2247 { 2248 be_vector.push_back(r_write_be[i]); 2249 data_vector.push_back(r_write_data[i]); 2250 } 2251 m_transaction_tab.write_data_mask(r_write_trt_index.read(), 2252 be_vector, 2253 data_vector); 2254 r_write_fsm = WRITE_RSP; 2255 2256 #if DEBUG_MEMC_WRITE 2257 if( m_debug_write_fsm ) 2258 { 2259 std::cout << " <MEMC " << name() << ".WRITE_MISS_TRT_DATA> Modify an existing entry in TRT" << std::endl; 2260 m_transaction_tab.print( r_write_trt_index.read() ); 2261 } 2262 #endif 2263 } 2264 break; 2265 } 2266 ///////////////////////// 2267 case WRITE_MISS_XRAM_REQ: // send a GET request to IXR_CMD FSM 2268 { 2269 if ( !r_write_to_ixr_cmd_req ) 2270 { 2271 r_write_to_ixr_cmd_req = true; 2272 r_write_to_ixr_cmd_write = false; 2273 r_write_to_ixr_cmd_nline = m_nline[(vci_addr_t)(r_write_address.read())]; 2274 r_write_to_ixr_cmd_trdid = r_write_trt_index.read(); 2275 r_write_fsm = WRITE_RSP; 2276 2277 #if DEBUG_MEMC_WRITE 2278 if( m_debug_write_fsm ) 2279 { 2280 std::cout << " <MEMC " << name() << ".WRITE_MISS_XRAM_REQ> Post a GET request to the IXR_CMD FSM" << std::endl; 2281 } 2282 #endif 2283 } 2284 break; 2285 } 2286 /////////////////////// 2287 case WRITE_BC_TRT_LOCK: // Check TRT not full 2288 { 2289 if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE ) 2290 { 2291 size_t wok_index = 0; 2292 bool wok = !m_transaction_tab.full( wok_index ); 2293 if ( wok ) // set a new entry in TRT 2294 { 2295 r_write_trt_index = wok_index; 2296 r_write_fsm = WRITE_BC_UPT_LOCK; 2297 } 2298 else // wait an empty entry in TRT 2299 { 2300 r_write_fsm = WRITE_WAIT; 2301 } 2302 2303 #if DEBUG_MEMC_WRITE 2304 if( m_debug_write_fsm ) 2305 { 2306 std::cout << " <MEMC " << name() << ".WRITE_BC_TRT_LOCK> Check TRT : wok = " 2307 << wok << " / index = " << wok_index << std::endl; 2308 } 2309 #endif 2310 } 2311 break; 2312 } 2313 ////////////////////// 2314 case WRITE_BC_UPT_LOCK: // register BC transaction in UPT 2315 { 2316 if ( r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE ) 2317 { 2318 bool wok = false; 2319 size_t index = 0; 2320 size_t srcid = r_write_srcid.read(); 2321 size_t trdid = r_write_trdid.read(); 2322 size_t pktid = r_write_pktid.read(); 2323 addr_t nline = m_nline[(vci_addr_t)(r_write_address.read())]; 2324 size_t nb_copies = r_write_count.read(); 2325 2326 wok =m_update_tab.set(false, // it's an inval transaction 2327 true, // it's a broadcast 2328 true, // it needs a response 2329 srcid, 2330 trdid, 2331 pktid, 2332 nline, 2333 nb_copies, 2334 index); 2335 2336 #if DEBUG_MEMC_WRITE 2337 if( m_debug_write_fsm ) 2338 { 2339 if ( wok ) 2340 { 2341 std::cout << " <MEMC " << name() << ".WRITE_BC_UPT_LOCK> Register the broadcast inval in UPT / " 2342 << " nb_copies = " << r_write_count.read() << std::endl; 2343 } 2344 } 2345 #endif 2346 r_write_upt_index = index; 2347 2348 if ( wok ) r_write_fsm = WRITE_BC_DIR_INVAL; 2349 else r_write_fsm = WRITE_WAIT; 2350 } 2351 break; 2352 } 2353 //////////////////////// 2354 case WRITE_BC_DIR_INVAL: // Register a put transaction to XRAM in TRT 2355 // and invalidate the line in directory 2356 { 2357 if ( (r_alloc_trt_fsm.read() != ALLOC_TRT_WRITE ) || 2358 (r_alloc_upt_fsm.read() != ALLOC_UPT_WRITE ) || 2359 (r_alloc_dir_fsm.read() != ALLOC_DIR_WRITE ) ) 2360 { 2361 std::cout << "VCI_MEM_CACHE ERROR " << name() << " WRITE_BC_DIR_INVAL state" << std::endl; 2362 std::cout << "bad TRT, DIR, or UPT allocation" << std::endl; 2363 exit(0); 2364 } 2365 2366 // register a write request to XRAM in TRT 2367 m_transaction_tab.set(r_write_trt_index.read(), 2368 false, // write request to XRAM 2369 m_nline[(vci_addr_t)(r_write_address.read())], 2370 0, 2371 0, 2372 0, 2373 false, // not a processor read 2374 0, // not a single word 2375 0, // word index 2376 std::vector<be_t>(m_words,0), 2377 std::vector<data_t>(m_words,0)); 2378 // invalidate directory entry 2379 DirectoryEntry entry; 2380 entry.valid = false; 2381 entry.dirty = false; 2382 entry.tag = 0; 2383 entry.is_cnt = false; 2384 entry.lock = false; 2385 entry.owner.srcid = 0; 2386 #if L1_MULTI_CACHE 2387 entry.owner.cache_id= 0; 2388 #endif 2389 entry.owner.inst = false; 2390 entry.ptr = 0; 2391 entry.count = 0; 2392 size_t set = m_y[(vci_addr_t)(r_write_address.read())]; 2393 size_t way = r_write_way.read(); 2394 2395 m_cache_directory.write(set, way, entry); 2396 2397 #if DEBUG_MEMC_WRITE 2398 if( m_debug_write_fsm ) 2399 { 2400 std::cout << " <MEMC " << name() << ".WRITE_BC_DIR_INVAL> Invalidate the directory entry: @ = " 2401 << r_write_address.read() << " / register the put transaction in TRT:" << std::endl; 2402 } 2403 #endif 2404 r_write_fsm = WRITE_BC_CC_SEND; 2405 break; 2406 } 2407 ////////////////////// 2408 case WRITE_BC_CC_SEND: // Post a coherence broadcast request to INIT_CMD FSM 2409 { 2410 if ( !r_write_to_init_cmd_multi_req.read() && !r_write_to_init_cmd_brdcast_req.read() ) 2411 { 2412 r_write_to_init_cmd_multi_req = false; 2413 r_write_to_init_cmd_brdcast_req = true; 2414 r_write_to_init_cmd_trdid = r_write_upt_index.read(); 2415 r_write_to_init_cmd_nline = m_nline[(vci_addr_t)(r_write_address.read())]; 2416 r_write_to_init_cmd_index = 0; 2417 r_write_to_init_cmd_count = 0; 2418 2419 for(size_t i=0; i<m_words ; i++) 2420 { 2421 r_write_to_init_cmd_be[i]=0; 2422 r_write_to_init_cmd_data[i] = 0; 2423 } 2424 r_write_fsm = WRITE_BC_XRAM_REQ; 2425 2426 #if DEBUG_MEMC_WRITE 2427 if( m_debug_write_fsm ) 2428 { 2429 std::cout << " <MEMC " << name() << ".WRITE_BC_CC_SEND> Post a broadcast request to INIT_CMD FSM" << std::endl; 2430 } 2431 #endif 2432 } 2433 break; 2434 } 2435 /////////////////////// 2436 case WRITE_BC_XRAM_REQ: // Post a put request to IXR_CMD FSM 2437 { 2438 if ( !r_write_to_ixr_cmd_req ) 2439 { 2440 r_write_to_ixr_cmd_req = true; 2441 r_write_to_ixr_cmd_write = true; 2442 r_write_to_ixr_cmd_nline = m_nline[(vci_addr_t)(r_write_address.read())]; 2443 r_write_to_ixr_cmd_trdid = r_write_trt_index.read(); 2444 2445 for(size_t i=0; i<m_words; i++) r_write_to_ixr_cmd_data[i] = r_write_data[i]; 2446 2447 r_write_fsm = WRITE_IDLE; 2448 2449 #if DEBUG_MEMC_WRITE 2450 if( m_debug_write_fsm ) 2451 { 2452 std::cout << " <MEMC " << name() << ".WRITE_BC_XRAM_REQ> Post a put request to IXR_CMD FSM" << std::endl; 2453 } 2454 #endif 2455 } 2456 break; 2457 } 2458 } // end switch r_write_fsm 2682 } // end switch r_write_fsm 2459 2683 2460 2684 /////////////////////////////////////////////////////////////////////// 2461 // 2685 // IXR_CMD FSM 2462 2686 /////////////////////////////////////////////////////////////////////// 2463 2687 // The IXR_CMD fsm controls the command packets to the XRAM : 2464 2688 // - It sends a single cell VCI read request to the XRAM in case of MISS 2465 // posted by the READ, WRITE or SC FSMs : the TRDID field contains 2689 // posted by the READ, WRITE or SC FSMs : the TRDID field contains 2466 2690 // the Transaction Tab index. 2467 2691 // The VCI response is a multi-cell packet : the N cells contain 2468 2692 // the N data words. 2469 2693 // - It sends a multi-cell VCI write when the XRAM_RSP FSM, WRITE FSM 2470 // or SC FSM request to save a dirty line to the XRAM. 2694 // or SC FSM request to save a dirty line to the XRAM. 2471 2695 // The VCI response is a single cell packet. 2472 // This FSM handles requests from the READ, WRITE, SC & XRAM_RSP FSMs 2696 // This FSM handles requests from the READ, WRITE, SC & XRAM_RSP FSMs 2473 2697 // with a round-robin priority. 2474 2698 //////////////////////////////////////////////////////////////////////// 2475 2699 2476 switch ( r_ixr_cmd_fsm.read() ) 2700 switch ( r_ixr_cmd_fsm.read() ) 2477 2701 { 2478 //////////////////////// 2702 //////////////////////// 2479 2703 case IXR_CMD_READ_IDLE: 2480 2704 if ( r_write_to_ixr_cmd_req ) r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE; … … 2483 2707 else if ( r_read_to_ixr_cmd_req ) r_ixr_cmd_fsm = IXR_CMD_READ_NLINE; 2484 2708 break; 2485 //////////////////////// 2709 //////////////////////// 2486 2710 case IXR_CMD_WRITE_IDLE: 2487 2711 if ( r_sc_to_ixr_cmd_req ) r_ixr_cmd_fsm = IXR_CMD_SC_NLINE; … … 2490 2714 else if ( r_write_to_ixr_cmd_req ) r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE; 2491 2715 break; 2492 //////////////////////// 2716 //////////////////////// 2493 2717 case IXR_CMD_SC_IDLE: 2494 2718 if ( r_xram_rsp_to_ixr_cmd_req ) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA; … … 2497 2721 else if ( r_sc_to_ixr_cmd_req ) r_ixr_cmd_fsm = IXR_CMD_SC_NLINE; 2498 2722 break; 2499 //////////////////////// 2723 //////////////////////// 2500 2724 case IXR_CMD_XRAM_IDLE: 2501 2725 if ( r_read_to_ixr_cmd_req ) r_ixr_cmd_fsm = IXR_CMD_READ_NLINE; … … 2506 2730 ///////////////////////// // send a get request to XRAM 2507 2731 case IXR_CMD_READ_NLINE: 2508 if ( p_vci_ixr.cmdack ) 2509 { 2510 r_ixr_cmd_fsm = IXR_CMD_READ_IDLE; 2732 if ( p_vci_ixr.cmdack ) 2733 { 2734 r_ixr_cmd_fsm = IXR_CMD_READ_IDLE; 2511 2735 r_read_to_ixr_cmd_req = false; 2512 2736 … … 2520 2744 break; 2521 2745 ////////////////////////// 2522 case IXR_CMD_WRITE_NLINE: 2523 if ( p_vci_ixr.cmdack ) 2746 case IXR_CMD_WRITE_NLINE: // send a put or get command to XRAM 2747 if ( p_vci_ixr.cmdack ) 2524 2748 { 2525 2749 if( r_write_to_ixr_cmd_write.read()) 2526 2750 { 2527 if ( r_ixr_cmd_cpt.read() == (m_words - 1) ) 2751 if ( r_ixr_cmd_cpt.read() == (m_words - 1) ) 2528 2752 { 2529 2753 r_ixr_cmd_cpt = 0; 2530 2754 r_ixr_cmd_fsm = IXR_CMD_WRITE_IDLE; 2531 2755 r_write_to_ixr_cmd_req = false; 2532 } 2533 else 2756 } 2757 else 2534 2758 { 2535 2759 r_ixr_cmd_cpt = r_ixr_cmd_cpt + 1; … … 2542 2766 } 2543 2767 #endif 2544 } 2545 else 2546 { 2547 r_ixr_cmd_fsm = IXR_CMD_WRITE_IDLE; 2768 } 2769 else 2770 { 2771 r_ixr_cmd_fsm = IXR_CMD_WRITE_IDLE; 2548 2772 r_write_to_ixr_cmd_req = false; 2549 2773 … … 2559 2783 ////////////////////// 2560 2784 case IXR_CMD_SC_NLINE: // send a put or get command to XRAM 2561 if ( p_vci_ixr.cmdack ) 2785 if ( p_vci_ixr.cmdack ) 2562 2786 { 2563 2787 if( r_sc_to_ixr_cmd_write.read()) 2564 2788 { 2565 if ( r_ixr_cmd_cpt.read() == (m_words - 1) ) 2789 if ( r_ixr_cmd_cpt.read() == (m_words - 1) ) 2566 2790 { 2567 2791 r_ixr_cmd_cpt = 0; 2568 2792 r_ixr_cmd_fsm = IXR_CMD_SC_IDLE; 2569 2793 r_sc_to_ixr_cmd_req = false; 2570 } 2571 else 2794 } 2795 else 2572 2796 { 2573 2797 r_ixr_cmd_cpt = r_ixr_cmd_cpt + 1;