- Timestamp:
- Jun 8, 2010, 5:04:20 PM (15 years ago)
- Location:
- trunk/modules/vci_cc_xcache_wrapper_multi/caba/source
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/modules/vci_cc_xcache_wrapper_multi/caba/source/include/vci_cc_xcache_wrapper_multi.h
r2 r45 65 65 DCACHE_MISS_UPDT, 66 66 DCACHE_UNC_WAIT, 67 DCACHE_UNC_GO, 67 68 DCACHE_INVAL, 68 69 DCACHE_SYNC, … … 80 81 ICACHE_MISS_UPDT, 81 82 ICACHE_UNC_WAIT, 83 ICACHE_UNC_GO, 82 84 ICACHE_ERROR, 83 85 ICACHE_CC_CHECK, … … 117 119 118 120 enum cleanup_fsm_state_e { 119 CLEANUP_ CMD,120 CLEANUP_DCACHE _RSP,121 CLEANUP_ICACHE _RSP,121 CLEANUP_IDLE, 122 CLEANUP_DCACHE, 123 CLEANUP_ICACHE, 122 124 }; 123 125 … … 148 150 const uint32_t m_srcid_c; 149 151 150 const size_t m_wbuf_nlines;151 152 const size_t m_dcache_ways; 152 153 const size_t m_dcache_words; … … 233 234 uint32_t m_cpt_icache_dir_write; // ICACHE DIR WRITE 234 235 235 uint32_t m_cpt_cc_update; // number of coherence update packets 236 uint32_t m_cpt_cc_inval; // number of coherence inval packets 236 uint32_t m_cpt_cc_broadcast; // number of coherence broadcast packets 237 uint32_t m_cpt_cc_update_data; // number of coherence data update packets 238 uint32_t m_cpt_cc_update_ins; // number of coherence instruction update packets 239 uint32_t m_cpt_cc_inval_data; // number of coherence data inval packets 240 uint32_t m_cpt_cc_inval_ins; // number of coherence instruction inval packets 241 uint32_t m_cpt_cc_cleanup_data; // number of coherence data cleanup packets 242 uint32_t m_cpt_cc_cleanup_ins; // number of coherence instruction cleanup packets 237 243 238 244 uint32_t m_cpt_frz_cycles; // number of cycles where the cpu is frozen 239 245 uint32_t m_cpt_total_cycles; // total number of cycles 240 246 241 uint32_t m_cpt_read; // total number of read instructions 242 uint32_t m_cpt_write; // total number of write instructions 247 uint32_t m_cpt_read; // total number of read requests 248 uint32_t m_cpt_write; // total number of write requests 249 uint32_t m_cpt_write_cached; // number of cached write requests 250 uint32_t m_cpt_data_unc; // number of uncachable data requests 251 uint32_t m_cpt_ins_unc; // number of uncachable instruction requests 252 uint32_t m_cpt_ll; // number of ll requests 253 uint32_t m_cpt_sc; // number of sc requests 243 254 uint32_t m_cpt_data_miss; // number of read miss 244 255 uint32_t m_cpt_ins_miss; // number of instruction miss 245 uint32_t m_cpt_unc_read; // number of read uncached246 uint32_t m_cpt_write_cached; // number of cached write247 256 248 257 uint32_t m_cost_write_frz; // number of frozen cycles related to write buffer 249 258 uint32_t m_cost_data_miss_frz; // number of frozen cycles related to data miss 250 uint32_t m_cost_unc_ read_frz;// number of frozen cycles related to uncached read259 uint32_t m_cost_unc_frz; // number of frozen cycles related to uncached read 251 260 uint32_t m_cost_ins_miss_frz; // number of frozen cycles related to ins miss 252 261 253 262 uint32_t m_cpt_imiss_transaction; // number of VCI instruction miss transactions 254 263 uint32_t m_cpt_dmiss_transaction; // number of VCI data miss transactions 255 uint32_t m_cpt_unc_transaction; // number of VCI uncached read transactions 264 uint32_t m_cpt_data_unc_transaction; // number of VCI instruction uncached transactions 265 uint32_t m_cpt_ins_unc_transaction; // number of VCI data uncached transactions 256 266 uint32_t m_cpt_write_transaction; // number of VCI write transactions 257 267 … … 278 288 size_t dcache_words, 279 289 size_t wbuf_nwords, 280 size_t wbuf_nlines ); 290 size_t wbuf_nlines, 291 size_t wbuf_timeout); 281 292 282 293 ~VciCcXCacheWrapperMulti(); 283 294 284 void print _cpi();285 void print _stats();295 void printTrace(size_t mode); 296 void printStatistics(); 286 297 287 298 private: … … 290 301 void genMoore(); 291 302 292 s oclib_static_assert((int)iss_t::SC_ATOMIC == (int)vci_param::STORE_COND_ATOMIC);293 s oclib_static_assert((int)iss_t::SC_NOT_ATOMIC == (int)vci_param::STORE_COND_NOT_ATOMIC);303 static_assert((int)iss_t::SC_ATOMIC == (int)vci_param::STORE_COND_ATOMIC); 304 static_assert((int)iss_t::SC_NOT_ATOMIC == (int)vci_param::STORE_COND_NOT_ATOMIC); 294 305 }; 295 306 -
trunk/modules/vci_cc_xcache_wrapper_multi/caba/source/src/vci_cc_xcache_wrapper_multi.cpp
r2 r45 54 54 // WRITE_WORD requests in the same word, only the last request is conserved. 55 55 // In case of several WRITE_HALF or WRITE_WORD requests in the same word, 56 // the requests are merged in the same word. In case of uncach edwrite56 // the requests are merged in the same word. In case of uncachable write 57 57 // requests, each request is transmited as a single VCI transaction. 58 58 // Both the data & instruction caches can be flushed in one single cycle. … … 65 65 // introduced. The VCI command & response FSMs are not synchronized anymore: 66 66 // The read requests can be transmitted before previous write requests 67 // (if the missing address does not match a pending write in the write buffer)67 // (if the missing address does not match a pending write in the write buffer) 68 68 // and several read & write requests can be simultaneously transmitted. 69 69 // The transactions can complete in any order, depending on the network. … … 76 76 // on the line index in the write buffer: PKTID = 2*wbuf_index + 1 77 77 // The transaction index has an even value for a read transaction, with only 78 // only four possible values, depending on cach ed/uncached& data/instruction.78 // only four possible values, depending on cachable/uncachable & data/instruction. 79 79 // A new CLEANUP FSM has been introduced to transmit the cleanups 80 80 // request from the DCACHE & ICACHE FSM on the coherence network. 81 // The LL/SC requests are still uncached. 81 // The LL/SC requests are still uncachable. 82 // - 07/06/2010 83 // The DCACHE FSM has been modified to enforce a well defined consistency model: 84 // 1) All uncachable acces (both read and write) are now blocking 85 // the processor until the VCI response is received. 86 // Uncachable access are considered as I/O access and must respect 87 // a strict sequencial policy. 88 // 2) For cachable access, the write buffer supports the "read after write" 89 // rule, and the "write after write" rule : registered write requests 90 // are tested before handling a read miss, and before locking a buffer line. 91 // The MultiWriteBuffer component has been modified, to support 92 // these rules, and to have an associative behavior: it can exist several 93 // open lines, with a private time-out for each open line. 94 // A printTrace() method has been defined. 82 95 /////////////////////////////////////////////////////////////////////////////// 83 84 //#define SOCLIB_MODULE_DEBUG 185 96 86 97 #include <cassert> … … 91 102 namespace caba { 92 103 93 #if SOCLIB_MODULE_DEBUG94 104 namespace { 95 105 const char *dcache_fsm_state_str[] = { … … 102 112 "DCACHE_MISS_UPDT ", 103 113 "DCACHE_UNC_WAIT ", 114 "DCACHE_UNC_GO ", 104 115 "DCACHE_INVAL ", 105 116 "DCACHE_SYNC ", … … 116 127 "ICACHE_MISS_UPDT ", 117 128 "ICACHE_UNC_WAIT ", 129 "ICACHE_UNC_GO ", 118 130 "ICACHE_ERROR ", 119 131 "ICACHE_CC_CHECK ", … … 149 161 }; 150 162 const char *cleanup_fsm_state_str[] = { 151 "CLEANUP_ CMD",152 "CLEANUP_DCACHE _RSP",153 "CLEANUP_ICACHE _RSP",163 "CLEANUP_IDLE", 164 "CLEANUP_DCACHE", 165 "CLEANUP_ICACHE", 154 166 }; 155 167 } 156 #endif157 168 158 169 #define tmpl(...) template<typename vci_param, typename iss_t> __VA_ARGS__ VciCcXCacheWrapperMulti<vci_param, iss_t> … … 162 173 ///////////////////////////////////// 163 174 tmpl(/**/)::VciCcXCacheWrapperMulti( 164 /////////////////////////////////////165 175 sc_module_name name, 166 176 int proc_id, … … 177 187 size_t dcache_words, 178 188 size_t wbuf_nwords, 179 size_t wbuf_nlines ) 189 size_t wbuf_nlines, 190 size_t wbuf_timeout) 180 191 : 181 192 soclib::caba::BaseModule(name), … … 199 210 m_icache_words(icache_words), 200 211 m_icache_yzmask((~0)<<(uint32_log2(icache_words) + 2)), 201 m_wbuf_nlines(wbuf_nlines),202 212 203 213 r_dcache_fsm("r_dcache_fsm"), … … 253 263 r_cleanup_fsm("r_cleanup_fsm"), 254 264 255 r_wbuf("r_wbuf", wbuf_nwords, wbuf_nlines ),265 r_wbuf("r_wbuf", wbuf_nwords, wbuf_nlines, wbuf_timeout), 256 266 r_icache("icache", icache_ways, icache_sets, icache_words), 257 267 r_dcache("dcache", dcache_ways, dcache_sets, dcache_words) 258 268 259 269 { 260 261 assert( (m_wbuf_nlines== 1 || m_wbuf_nlines == 2 || m_wbuf_nlines == 4 || m_wbuf_nlines == 8 || m_wbuf_nlines == 16) && 262 "number of lines must be power of 2, no larger than 16"); 270 assert( (icache_words*vci_param::B) < (1<<vci_param::K) && 271 "I need more PLEN bits"); 272 273 assert( (vci_param::T > 2) && ((1<<(vci_param::T-1)) >= wbuf_nlines) && 274 "I need more TRDID bits"); 263 275 264 276 r_icache_miss_buf = new data_t[icache_words]; … … 289 301 ////////////////////////////////////// 290 302 tmpl(/**/)::~VciCcXCacheWrapperMulti() 291 //////////////////////////////////////292 303 { 293 304 delete [] r_icache_miss_buf; … … 297 308 } 298 309 299 //////////////////////// 300 tmpl(void)::print_cpi() 301 //////////////////////// 310 /////////////////////////////////// 311 tmpl(void)::printTrace(size_t mode) 302 312 { 303 std::cout << "CPU " << m_srcid_d << " : CPI = " 304 << (float)m_cpt_total_cycles/(m_cpt_total_cycles - m_cpt_frz_cycles) << std::endl ; 313 typename iss_t::InstructionRequest ireq; 314 typename iss_t::DataRequest dreq; 315 316 m_iss.getRequests( ireq, dreq ); 317 std::cout << std::dec << "Proc " << m_srcid_d << std::endl; 318 std::cout << ireq << std::endl; 319 std::cout << dreq << std::endl; 320 std::cout << " " << dcache_fsm_state_str[r_dcache_fsm] 321 << " " << icache_fsm_state_str[r_icache_fsm] 322 << " " << cmd_fsm_state_str[r_cmd_fsm] 323 << " " << rsp_fsm_state_str[r_rsp_fsm] 324 << " " << tgt_fsm_state_str[r_tgt_fsm] 325 << " " << cleanup_fsm_state_str[r_cleanup_fsm] << std::endl; 326 if(mode & 0x1) 327 { 328 r_wbuf.printTrace(); 329 } 330 if(mode & 0x2) 331 { 332 std::cout << " Data cache" << std::endl; 333 r_dcache.printTrace(); 334 } 335 if(mode & 0x4) 336 { 337 std::cout << " Instruction cache" << std::endl; 338 r_icache.printTrace(); 339 } 305 340 } 306 //////////////////////// 307 tmpl(void)::print_stats() 308 //////////////////////// 341 ///////////////////////////// 342 tmpl(void)::printStatistics() 309 343 { 310 344 float run_cycles = (float)(m_cpt_total_cycles - m_cpt_frz_cycles); 311 345 std::cout << "------------------------------------" << std:: dec << std::endl 312 << "CPU " << m_srcid_d << " / Time= " << m_cpt_total_cycles << std::endl346 << "CPU " << m_srcid_d << " / cycles = " << m_cpt_total_cycles << std::endl 313 347 << "- CPI = " << (float)m_cpt_total_cycles/run_cycles << std::endl 314 348 << "- READ RATE = " << (float)m_cpt_read/run_cycles << std::endl 315 << "- UNC READ RATE = " << (float)m_cpt_unc_read/m_cpt_read << std::endl316 349 << "- WRITE RATE = " << (float)m_cpt_write/run_cycles << std::endl 317 350 << "- CACHED WRITE RATE = " << (float)m_cpt_write_cached/m_cpt_write << std::endl 351 << "- UNC RATE = " << (float)m_cpt_data_unc/run_cycles << std::endl 352 << "- LL RATE = " << (float)m_cpt_ll/run_cycles << std::endl 353 << "- SC RATE = " << (float)m_cpt_sc/run_cycles << std::endl 318 354 << "- IMISS_RATE = " << (float)m_cpt_ins_miss/run_cycles << std::endl 319 355 << "- IMISS COST = " << (float)m_cost_ins_miss_frz/m_cpt_ins_miss << std::endl 320 << "- DMISS RATE = " << (float)m_cpt_data_miss/ (m_cpt_read-m_cpt_unc_read)<< std::endl356 << "- DMISS RATE = " << (float)m_cpt_data_miss/m_cpt_read << std::endl 321 357 << "- DMISS COST = " << (float)m_cost_data_miss_frz/m_cpt_data_miss << std::endl 322 << "- UNC COST = " << (float)m_cost_unc_ read_frz/m_cpt_unc_read<< std::endl358 << "- UNC COST = " << (float)m_cost_unc_frz/m_cpt_data_unc << std::endl 323 359 << "- WRITE COST = " << (float)m_cost_write_frz/m_cpt_write << std::endl 324 << "- WRITE LENGTH = " << (float)m_length_write_transaction/m_cpt_write_transaction 325 << std::endl; 360 << "- WRITE LENGTH = " << (float)m_length_write_transaction/m_cpt_write_transaction << std::endl 361 << "- CC_BROADCAST = " << m_cpt_cc_broadcast << std::endl 362 << "- CC_UPDATE_DATA = " << m_cpt_cc_update_data << std::endl 363 << "- CC_UPDATE_INS = " << m_cpt_cc_update_ins << std::endl 364 << "- CC_INVAL_DATA = " << m_cpt_cc_inval_data << std::endl 365 << "- CC_INVAL_INS = " << m_cpt_cc_inval_ins << std::endl 366 << "- CC_CLEANUP_DATA = " << m_cpt_cc_cleanup_data << std::endl 367 << "- CC_CLEANUP_INS = " << m_cpt_cc_cleanup_ins << std::endl; 326 368 } 327 369 328 370 ////////////////////////// 329 371 tmpl(void)::transition() 330 //////////////////////////331 372 { 332 373 if ( ! p_resetn.read() ) { … … 340 381 r_rsp_fsm = RSP_IDLE; 341 382 r_tgt_fsm = TGT_IDLE; 342 r_cleanup_fsm = CLEANUP_ CMD;383 r_cleanup_fsm = CLEANUP_IDLE; 343 384 344 385 // write buffer & caches … … 378 419 m_cpt_dcache_dir_read = 0; 379 420 m_cpt_dcache_dir_write = 0; 421 380 422 m_cpt_icache_data_read = 0; 381 423 m_cpt_icache_data_write = 0; … … 383 425 m_cpt_icache_dir_write = 0; 384 426 385 m_cpt_cc_update = 0; 386 m_cpt_cc_inval = 0; 427 m_cpt_cc_broadcast = 0; 428 m_cpt_cc_update_data = 0; 429 m_cpt_cc_inval_data = 0; 430 m_cpt_cc_cleanup_data = 0; 431 m_cpt_cc_update_ins = 0; 432 m_cpt_cc_inval_ins = 0; 433 m_cpt_cc_cleanup_ins = 0; 387 434 388 435 m_cpt_frz_cycles = 0; … … 391 438 m_cpt_read = 0; 392 439 m_cpt_write = 0; 440 m_cpt_write_cached = 0; 441 m_cpt_data_unc = 0; 442 m_cpt_ins_unc = 0; 443 m_cpt_ll = 0; 444 m_cpt_sc = 0; 393 445 m_cpt_data_miss = 0; 394 446 m_cpt_ins_miss = 0; 395 m_cpt_unc_read = 0;396 m_cpt_write_cached = 0;397 447 398 448 m_cost_write_frz = 0; 399 449 m_cost_data_miss_frz = 0; 400 m_cost_unc_ read_frz = 0;450 m_cost_unc_frz = 0; 401 451 m_cost_ins_miss_frz = 0; 402 452 403 453 m_cpt_imiss_transaction = 0; 404 454 m_cpt_dmiss_transaction = 0; 405 m_cpt_unc_transaction = 0; 455 m_cpt_data_unc_transaction = 0; 456 m_cpt_ins_unc_transaction = 0; 406 457 m_cpt_write_transaction = 0; 407 458 … … 412 463 if ( m_srcid_d == 0 ) 413 464 { 414 std::cout << "--------------------------------------------" << std::endl 415 << std::dec << "CACHE " << m_srcid_d << " / Time = " << m_cpt_total_cycles << std::endl 465 std::cout << std::dec << "CcXcache " << m_srcid_d << " / Time = " << m_cpt_total_cycles << std::endl 416 466 << " " << dcache_fsm_state_str[r_dcache_fsm] 417 467 << " " << icache_fsm_state_str[r_icache_fsm] … … 420 470 << " " << cleanup_fsm_state_str[r_cleanup_fsm] 421 471 << " " << tgt_fsm_state_str[r_tgt_fsm] << std::endl; 422 r_wbuf.print();423 472 } 424 473 #endif … … 499 548 r_tgt_brdcast= true; 500 549 r_tgt_fsm = TGT_REQ_BROADCAST; 501 m_cpt_cc_ inval++;550 m_cpt_cc_broadcast++; 502 551 } 503 552 else // multicast-update or multicast-invalidate … … 516 565 r_tgt_data = true; 517 566 r_tgt_fsm = TGT_REQ_DCACHE; 518 m_cpt_cc_inval ++;567 m_cpt_cc_inval_data++; 519 568 } 520 569 else if (cell == 4) // update data … … 530 579 r_tgt_data = true; 531 580 r_tgt_fsm = TGT_UPDT_WORD; 532 m_cpt_cc_update ++;581 m_cpt_cc_update_data++; 533 582 } 534 583 else if (cell == 8) // invalidate instruction … … 544 593 r_tgt_update = false; 545 594 r_tgt_fsm = TGT_REQ_ICACHE; 546 m_cpt_cc_inval ++;595 m_cpt_cc_inval_ins++; 547 596 } 548 597 else if (cell == 12) // update ins … … 558 607 r_tgt_data = false; 559 608 r_tgt_fsm = TGT_UPDT_WORD; 560 m_cpt_cc_update ++;609 m_cpt_cc_update_ins++; 561 610 } 562 611 … … 680 729 } // end switch TGT_FSM 681 730 731 typename iss_t::InstructionRequest ireq; 732 typename iss_t::InstructionResponse irsp; 733 734 typename iss_t::DataRequest dreq; 735 typename iss_t::DataResponse drsp; 736 737 ireq.valid = false; 738 dreq.valid = false; 739 irsp.valid = false; 740 irsp.error = false; 741 drsp.valid = false; 742 drsp.error = false; 743 744 m_iss.getRequests( ireq, dreq ); 745 682 746 ////////////////////////////////////////////////////////////////////////////// 683 747 // The ICACHE FSM controls the following ressources: 684 748 // - r_icache_fsm 685 749 // - r_icache_fsm_save 686 // - r_icache instruction cache access750 // - r_icache (read & write) 687 751 // - r_icache_addr_save 688 // - r_icache_miss_req set689 // - r_icache_unc_req set690 // - r_rsp_ins_ok reset691 // - r_rsp_ins_error reset692 // - r_tgt_icache_req reset752 // - r_icache_miss_req (set) 753 // - r_icache_unc_req (set) 754 // - r_rsp_ins_ok (reset) 755 // - r_rsp_ins_error (reset) 756 // - r_tgt_icache_req (reset) 693 757 // - r_tgt_icache_rsp 694 // - r_icache_cleanup_req set695 // - r_icache_cleanup_ ine696 // - ireq & irsp structures for communication with the processor758 // - r_icache_cleanup_req (set) 759 // - r_icache_cleanup_line 760 // - ireq & irsp structures (communication with the processor) 697 761 // 698 // 1/ External requests (update or invalidate)762 // 1/ External coherence requests (update or invalidate) 699 763 // There is an external request when the r_tgt_icache_req flip-flop is set, 700 764 // These requests are taken into account in the IDLE and WAIT states. … … 704 768 // 705 769 // 2/ Processor requests are taken into account only in the IDLE state. 706 // In case of MISS, or in case of uncached instruction, the FSM 770 // The cache access takes into account the cacheability_table. 771 // In case of MISS, or in case of uncachable instruction, the FSM 707 772 // writes the missing address line in the r_icache_addr_save register 708 773 // and sets the r_icache_miss_req or the r_icache_unc_req flip-flops. … … 719 784 //////////////////////////////////////////////////////////////////////////////////// 720 785 721 typename iss_t::InstructionRequest ireq = ISS_IREQ_INITIALIZER;722 typename iss_t::InstructionResponse irsp = ISS_IRSP_INITIALIZER;723 724 typename iss_t::DataRequest dreq = ISS_DREQ_INITIALIZER;725 typename iss_t::DataResponse drsp = ISS_DRSP_INITIALIZER;726 727 m_iss.getRequests( ireq, dreq );728 729 786 switch(r_icache_fsm) { 730 787 731 case ICACHE_IDLE: 732 { 733 if ( r_tgt_icache_req ) // external request 734 { 735 if ( ireq.valid ) m_cost_ins_miss_frz++; 736 r_icache_fsm = ICACHE_CC_CHECK; 737 r_icache_fsm_save = r_icache_fsm; 738 break; 739 } 740 if ( ireq.valid ) 741 { 742 data_t icache_ins = 0; 743 bool icache_hit = false; 744 bool icache_cached = m_cacheability_table[(addr_t)ireq.addr]; 745 // icache_hit & icache_ins evaluation 746 if ( icache_cached ) 747 { 748 icache_hit = r_icache.read((addr_t)ireq.addr, &icache_ins); 749 } 750 else 751 { 752 icache_hit = (r_rsp_ins_ok && ( (addr_t)ireq.addr == (addr_t)r_icache_addr_save)); 753 icache_ins = r_icache_miss_buf[0]; 754 } 755 if ( ! icache_hit ) // miss 788 case ICACHE_IDLE: 789 { 790 if ( r_tgt_icache_req ) // external request 791 { 792 if ( ireq.valid ) m_cost_ins_miss_frz++; 793 r_icache_fsm = ICACHE_CC_CHECK; 794 r_icache_fsm_save = r_icache_fsm; 795 break; 796 } 797 if ( ireq.valid ) 798 { 799 data_t icache_ins; 800 bool icache_cachable = m_cacheability_table[(addr_t)ireq.addr]; 801 m_cpt_icache_dir_read += m_icache_ways; 802 m_cpt_icache_data_read += m_icache_ways; 803 if ( icache_cachable ) 804 { 805 if ( r_icache.read((addr_t)ireq.addr, &icache_ins) ) // hit 806 { 807 r_icache_fsm = ICACHE_IDLE; 808 irsp.valid = true; 809 irsp.instruction = icache_ins; 810 } 811 else // miss 756 812 { 757 813 m_cpt_ins_miss++; 758 814 m_cost_ins_miss_frz++; 759 r_icache_addr_save = (addr_t)ireq.addr; 760 if ( icache_cached ) // cached line 761 { 762 // if the missing line corresponds to a pending cleanup 763 // the miss request to the CMD FSM must be delayed 764 if ( r_icache_cleanup_req && 765 ((addr_t)r_icache_cleanup_line == (addr_t)(ireq.addr/(m_icache_words*4))) ) 766 { 767 break; 768 } 769 else 770 { 771 r_icache_fsm = ICACHE_MISS_SELECT; 772 r_icache_miss_req = true; 773 r_rsp_ins_ok = false; 774 } 775 } 776 else // uncached line 777 { 778 r_icache_fsm = ICACHE_UNC_WAIT; 779 r_icache_unc_req = true; 780 r_rsp_ins_ok = false; 781 } 782 } 783 else // hit : the uncached data should not be re-used 784 { 785 r_rsp_ins_ok = false; 786 } 787 m_cpt_icache_dir_read += m_icache_ways; 788 m_cpt_icache_data_read += m_icache_ways; 789 irsp.valid = icache_hit; 790 irsp.instruction = icache_ins; 791 } // end if ireq.valid 792 break; 793 } 794 case ICACHE_MISS_SELECT: 795 { 796 m_cost_ins_miss_frz++; 797 size_t way; 798 addr_t index; 799 addr_t ad = r_icache_addr_save; 800 if ( r_icache.select_before_update( ad, &way, &index) ) 801 { 802 r_icache_fsm = ICACHE_MISS_CLEANUP; 803 r_icache_cleanup_save = index; 804 r_icache_way_save = way; 805 } 806 else 807 { 808 r_icache_way_save = way; 809 r_icache_fsm = ICACHE_MISS_WAIT; 810 } 811 break; 812 } 813 case ICACHE_MISS_CLEANUP: // try to post a cleanup request to the CLEANUP FSM 814 { 815 m_cost_ins_miss_frz++; 816 if ( r_tgt_icache_req ) // coherence request 817 { 818 r_icache_fsm = ICACHE_CC_CHECK; 819 r_icache_fsm_save = r_icache_fsm; 820 break; 821 } 822 if ( !r_icache_cleanup_req ) // no pending cleanup 823 { 824 r_icache_cleanup_req = true; 825 r_icache_cleanup_line = r_icache_cleanup_save.read(); 826 r_icache_fsm = ICACHE_MISS_WAIT; 827 } 828 break; 829 } 830 case ICACHE_MISS_WAIT: // waiting the response from the RSP FSM 831 { 832 m_cost_ins_miss_frz++; 833 if ( r_tgt_icache_req ) // coherence request 834 { 835 r_icache_fsm = ICACHE_CC_CHECK; 836 r_icache_fsm_save = r_icache_fsm; 837 break; 838 } 839 if ( r_rsp_ins_ok ) // there is a response 840 { 841 if ( r_rsp_ins_error ) r_icache_fsm = ICACHE_ERROR; 842 else if ( !r_icache_inval_pending ) r_icache_fsm = ICACHE_MISS_UPDT; 843 else 844 { 845 if ( r_icache_cleanup_req ) 815 // if the missing line corresponds to a pending cleanup 816 // the miss request to the CMD FSM must be delayed 817 if ( r_icache_cleanup_req && 818 ((addr_t)r_icache_cleanup_line == (addr_t)(ireq.addr/(m_icache_words*4))) ) 846 819 { 847 820 break; … … 849 822 else 850 823 { 851 r_icache_ cleanup_req = true;852 r_icache_ cleanup_line = r_icache_addr_save.read() >> (uint32_log2(m_icache_words) + 2);853 r_icache_ fsm = ICACHE_IDLE;854 r_ icache_inval_pending= false;824 r_icache_fsm = ICACHE_MISS_SELECT; 825 r_icache_addr_save = ireq.addr; 826 r_icache_miss_req = true; 827 r_rsp_ins_ok = false; 855 828 } 856 829 } 857 830 } 858 break; 859 } 860 case ICACHE_MISS_UPDT: // update the cache 861 { 862 m_cost_ins_miss_frz++; 863 m_cpt_icache_dir_write++; 864 m_cpt_icache_data_write++; 865 addr_t ad = (addr_t) r_icache_addr_save; 866 data_t* buf = (data_t*) r_icache_miss_buf; 867 size_t way = (size_t) r_icache_way_save; 868 r_icache.update_after_select( buf, way, ad ); 869 r_icache_fsm = ICACHE_IDLE; 870 break; 871 } 872 case ICACHE_UNC_WAIT: 873 { 874 m_cost_ins_miss_frz++; 875 if ( r_tgt_icache_req ) // external request 876 { 877 r_icache_fsm = ICACHE_CC_CHECK; 878 r_icache_fsm_save = r_icache_fsm; 879 break; 831 else // uncachable instruction 832 { 833 m_cpt_ins_unc++; 834 m_cost_ins_miss_frz++; 835 r_icache_addr_save = ireq.addr; 836 r_icache_fsm = ICACHE_UNC_WAIT; 837 r_icache_unc_req = true; 838 r_rsp_ins_ok = false; 839 } 840 } 841 break; 842 } 843 case ICACHE_MISS_SELECT: // select a victim 844 { 845 m_cost_ins_miss_frz++; 846 size_t way; 847 addr_t index; 848 addr_t ad = r_icache_addr_save; 849 if ( r_icache.select_before_update( ad, &way, &index) ) 850 { 851 r_icache_fsm = ICACHE_MISS_CLEANUP; 852 r_icache_cleanup_save = index; 853 r_icache_way_save = way; 854 } 855 else 856 { 857 r_icache_way_save = way; 858 r_icache_fsm = ICACHE_MISS_WAIT; 859 } 860 break; 861 } 862 case ICACHE_MISS_CLEANUP: // try to post a cleanup request to the CLEANUP FSM 863 { 864 m_cost_ins_miss_frz++; 865 if ( r_tgt_icache_req ) // coherence request 866 { 867 r_icache_fsm = ICACHE_CC_CHECK; 868 r_icache_fsm_save = r_icache_fsm; 869 break; 870 } 871 if ( !r_icache_cleanup_req ) // no pending cleanup 872 { 873 r_icache_cleanup_req = true; 874 r_icache_cleanup_line = r_icache_cleanup_save; 875 r_icache_fsm = ICACHE_MISS_WAIT; 876 } 877 break; 878 } 879 case ICACHE_MISS_WAIT: // waiting the response from the RSP FSM 880 { 881 m_cost_ins_miss_frz++; 882 if ( r_tgt_icache_req ) // coherence request 883 { 884 r_icache_fsm = ICACHE_CC_CHECK; 885 r_icache_fsm_save = r_icache_fsm; 886 break; 887 } 888 if ( r_rsp_ins_ok ) // there is a response 889 { 890 if ( r_rsp_ins_error ) r_icache_fsm = ICACHE_ERROR; 891 else if ( !r_icache_inval_pending ) r_icache_fsm = ICACHE_MISS_UPDT; 892 else 893 { 894 if ( r_icache_cleanup_req ) 895 { 896 break; 897 } 898 else 899 { 900 // the cache is not updated in case of pending inval 901 r_icache_cleanup_req = true; 902 r_icache_cleanup_line = r_icache_addr_save.read() >> (uint32_log2(m_icache_words) + 2); 903 r_icache_fsm = ICACHE_IDLE; 904 r_icache_inval_pending = false; 905 } 906 } 907 } 908 break; 909 } 910 case ICACHE_MISS_UPDT: // update the cache 911 { 912 m_cost_ins_miss_frz++; 913 m_cpt_icache_dir_write++; 914 m_cpt_icache_data_write++; 915 addr_t ad = (addr_t) r_icache_addr_save; 916 data_t* buf = (data_t*) r_icache_miss_buf; 917 size_t way = (size_t) r_icache_way_save; 918 r_icache.update_after_select( buf, way, ad ); 919 r_icache_fsm = ICACHE_IDLE; 920 break; 921 } 922 case ICACHE_UNC_WAIT: 923 { 924 m_cost_ins_miss_frz++; 925 if ( r_tgt_icache_req ) // external request 926 { 927 r_icache_fsm = ICACHE_CC_CHECK; 928 r_icache_fsm_save = r_icache_fsm; 929 break; 930 } 931 if ( r_rsp_ins_ok ) 932 { 933 if ( r_rsp_ins_error ) r_icache_fsm = ICACHE_ERROR; 934 else r_icache_fsm = ICACHE_UNC_GO; 935 } 936 break; 937 } 938 case ICACHE_UNC_GO: 939 { 940 r_icache_fsm = ICACHE_IDLE; 941 if( ireq.addr == r_icache_addr_save ) 942 { 943 irsp.valid = true; 944 irsp.instruction = r_icache_miss_buf[0]; 945 } 946 } 947 case ICACHE_ERROR: 948 { 949 r_icache_fsm = ICACHE_IDLE; 950 r_rsp_ins_error = false; 951 irsp.error = true; 952 irsp.valid = true; 953 break; 954 } 955 case ICACHE_CC_CHECK: // read directory in case of external request 956 { 957 m_cpt_icache_dir_read += m_icache_ways; 958 m_cpt_icache_data_read += m_icache_ways; 959 if ( ( (r_icache_fsm_save == ICACHE_MISS_WAIT) || (r_icache_fsm_save == ICACHE_MISS_CLEANUP) ) && 960 ((r_icache_addr_save & ~((m_icache_words<<2)-1))==(r_tgt_addr & ~((m_icache_words<<2)-1)))) 961 // the external request matches a miss 962 { 963 r_icache_inval_pending = true; 964 r_tgt_icache_req = false; 965 r_tgt_icache_rsp = r_tgt_update; // always a response in case of update 966 r_icache_fsm = r_icache_fsm_save; 967 } 968 else // the external request is not matching a pending miss 969 { 970 data_t data; 971 bool icache_hit = r_icache.read(r_tgt_addr, &data); 972 if ( icache_hit && r_tgt_update ) // hit update 973 { 974 r_icache_fsm = ICACHE_CC_UPDT; 880 975 } 881 if ( r_rsp_ins_ok ) 882 { 883 if ( r_rsp_ins_error ) r_icache_fsm = ICACHE_ERROR; 884 else r_icache_fsm = ICACHE_IDLE; 885 } 886 break; 887 } 888 case ICACHE_ERROR: 889 { 890 r_icache_fsm = ICACHE_IDLE; 891 r_rsp_ins_error = false; 892 irsp.error = true; 893 irsp.valid = true; 894 break; 895 } 896 case ICACHE_CC_CHECK: // read directory in case of external request 897 { 898 m_cpt_icache_dir_read += m_icache_ways; 899 m_cpt_icache_data_read += m_icache_ways; 900 if ( ( (r_icache_fsm_save == ICACHE_MISS_WAIT) || (r_icache_fsm_save == ICACHE_MISS_CLEANUP) ) && // external request matches a miss 901 ((r_icache_addr_save & ~((m_icache_words<<2)-1))==(r_tgt_addr & ~((m_icache_words<<2)-1)))) 902 { 903 r_icache_inval_pending = true; 904 r_tgt_icache_req = false; 905 r_tgt_icache_rsp = r_tgt_update; // always a response n case of update 906 r_icache_fsm = r_icache_fsm_save; 976 else if ( icache_hit && !r_tgt_update ) // hit inval 977 { 978 r_icache_fsm = ICACHE_CC_INVAL; 907 979 } 908 else // the external request is not matching a pending miss 909 { 910 data_t data; 911 bool icache_hit = r_icache.read(r_tgt_addr, &data); 912 if ( icache_hit && r_tgt_update ) // hit update 913 { 914 r_icache_fsm = ICACHE_CC_UPDT; 915 } 916 else if ( icache_hit && !r_tgt_update ) // hit inval 917 { 918 r_icache_fsm = ICACHE_CC_INVAL; 919 } 920 else // miss 921 { 922 r_tgt_icache_req = false; 923 r_tgt_icache_rsp = r_tgt_update; // alaways a response in case of update 924 r_icache_fsm = r_icache_fsm_save; 925 } 926 } 927 break; 928 } 929 case ICACHE_CC_UPDT: // update the cache line 930 { 931 m_cpt_icache_dir_write++; 932 m_cpt_icache_data_write++; 933 for(size_t i=0; i<m_icache_words; i++) 934 { 935 if(r_tgt_val[i]) r_icache.write( (r_tgt_addr + i*4), r_tgt_buf[i] ); 936 } 937 r_tgt_icache_rsp = true; 938 r_tgt_icache_req = false; 939 r_icache_fsm = r_icache_fsm_save; 940 break; 941 } 942 case ICACHE_CC_INVAL: // invalidate a cache line 943 { 944 r_icache.inval(r_tgt_addr); 945 r_tgt_icache_rsp = true; 946 r_tgt_icache_req = false; 947 r_icache_fsm = r_icache_fsm_save; 948 break; 949 } 980 else // miss 981 { 982 r_tgt_icache_req = false; 983 r_tgt_icache_rsp = r_tgt_update; // alaways a response in case of update 984 r_icache_fsm = r_icache_fsm_save; 985 } 986 } 987 break; 988 } 989 case ICACHE_CC_UPDT: // update the cache line 990 { 991 m_cpt_icache_dir_write++; 992 m_cpt_icache_data_write++; 993 for(size_t i=0; i<m_icache_words; i++) 994 { 995 if(r_tgt_val[i]) r_icache.write( (r_tgt_addr + i*4), r_tgt_buf[i] ); 996 } 997 r_tgt_icache_rsp = true; 998 r_tgt_icache_req = false; 999 r_icache_fsm = r_icache_fsm_save; 1000 break; 1001 } 1002 case ICACHE_CC_INVAL: // invalidate a cache line 1003 { 1004 r_icache.inval(r_tgt_addr); 1005 r_tgt_icache_rsp = true; 1006 r_tgt_icache_req = false; 1007 r_icache_fsm = r_icache_fsm_save; 1008 break; 1009 } 950 1010 } // end switch r_icache_fsm 951 1011 … … 954 1014 // - r_dcache_fsm 955 1015 // - r_dcache_fsm_save 956 // - r_dcache ( data cache access)1016 // - r_dcache (read and write) 957 1017 // - r_dcache_addr_save 958 1018 // - r_dcache_wdata_save … … 960 1020 // - r_dcache_type_save 961 1021 // - r_dcache_be_save 962 // - r_dcache_miss_req set963 // - r_dcache_unc_req set964 // - r_rsp_data_ok reset965 // - r_rsp_data_error reset966 // - r_dcache_cleanup_req set1022 // - r_dcache_miss_req (set) 1023 // - r_dcache_unc_req (set) 1024 // - r_rsp_data_ok (reset) 1025 // - r_rsp_data_error (reset) 1026 // - r_dcache_cleanup_req (set) 967 1027 // - r_dcache_cleanup_ine 968 // - r_tgt_dcache_req reset1028 // - r_tgt_dcache_req (reset) 969 1029 // - r_tgt_dcache_rsp 970 // - r_wbuf write()971 // - dreq & drsp structures for communication with the processor1030 // - r_wbuf (write) 1031 // - dreq & drsp structures (communication with the processor) 972 1032 // 973 1033 // 1/ external request (invalidate or update) … … 982 1042 // In order to support VCI write burst, the processor requests are taken into account 983 1043 // in the WRITE_REQ state as well as in the IDLE state. 984 // - In the IDLE state, the processor request cannot be satisfied if985 // there is a cached read miss, or an uncached read.986 // - In the WRITE_REQ state, the request cannot be satisfied if987 // there is a cached read miss, or an uncached read,988 // or when the write buffer is full.989 // - In all other states, the processor request is not satisfied.1044 // - In IDLE state, the request is satisfied if it is a cachable read hit, 1045 // an XTN request, or a cachable write. 1046 // - In WRITE_REQ state, the request is satisfied if it is a cachable read hit, 1047 // an XTN request, or a write when the write buffer is not full. 1048 // - Both the uncachable read and the uncachable write requests block the processor 1049 // until the corresponding VCI transaction is completed. 990 1050 // 991 1051 // The cache access takes into account the cacheability_table. 992 1052 // In case of processor request, there is six conditions to exit the IDLE state: 993 // - CACHED READ MISS => to the MISS_WAIT state, waiting the r_rsp_data_ok signal. 994 // It can be delayed in the MISS_DELAY state in case of matching pending 995 // cleanup request. Then it goes to the MISS_UPDT state, then to the CLEANUP_REQ 996 // state (if necessary), and finally to the IDLE state. 997 // - UNCACHED READ => to the UNC_WAIT state, waiting the r_rsp_data_ok signal, 998 // and back to the IDLE state. LL & SC are handled as uncached read. 999 // - WRITE MISS => directly to the WRITE_REQ state to post a request in the 1000 // write buffer. 1053 // - CACHED READ MISS => to the MISS_WAIT state (waiting r_rsp_data_ok), 1054 // then to the MISS_UPDT state, and finally to the IDLE state. 1055 // - UNCACHED READ or WRITE => to the UNC_WAIT state (waiting r_rsp_data_ok), 1056 // then to the UNC_GO state, and finally to the IDLE state. 1057 // - XTN_INVAL => to the INVAL state for one cycle, then to IDLE state. 1058 // - XTN_SYNC => to the SYNC state until write buffer empty, then to IDLE state. 1059 // - WRITE MISS => directly to the WRITE_REQ state to access the write buffer. 1001 1060 // - WRITE HIT => to the WRITE_UPDT state, then to the WRITE_REQ state. 1002 // - LINE INVALIDATE => to the INVAL state for one cycle, then to IDLE state.1003 // - SYNC REQUEST => to the SYNC state until the write buffer is empty.1061 // 1062 // All LL or SC requests are handled as uncachable. 1004 1063 // 1005 1064 // Error handling : Read Bus Errors are synchronous events, but … … 1022 1081 break; 1023 1082 } 1024 if( !r_wbuf.w ok(r_dcache_addr_save) )1083 if( !r_wbuf.write(r_dcache_addr_save, r_dcache_be_save, r_dcache_wdata_save) ) 1025 1084 { 1026 1085 // stay in DCACHE_WRITEREQ state if the write request is not accepted 1027 // by the write buffer1028 1086 m_cost_write_frz++; 1029 drsp.valid = false;1030 drsp.rdata = 0;1031 1087 break; 1032 1088 } … … 1045 1101 if ( dreq.valid ) 1046 1102 { 1047 bool dcache_hit = false; 1048 data_t dcache_rdata = 0; 1049 bool dcache_cached; 1103 bool dcache_hit; 1104 data_t dcache_rdata; 1105 bool dcache_cachable; 1106 1107 // dcache_cachable, dcache_hit & dcache_rdata evaluation 1050 1108 m_cpt_dcache_data_read += m_dcache_ways; 1051 1109 m_cpt_dcache_dir_read += m_dcache_ways; 1052 1053 // dcache_cached evaluation 1054 switch (dreq.type) { 1055 case iss_t::DATA_LL: 1056 case iss_t::DATA_SC: 1057 case iss_t::XTN_READ: 1058 case iss_t::XTN_WRITE: 1059 dcache_cached = false; 1060 break; 1061 default: 1062 dcache_cached = m_cacheability_table[dreq.addr]; 1063 } 1064 1065 // dcache_hit & dcache_rdata evaluation 1066 if ( dcache_cached ) 1067 { 1068 dcache_hit = r_dcache.read((addr_t) dreq.addr, &dcache_rdata); 1069 } 1070 else 1071 { 1072 dcache_hit = ( r_rsp_data_ok && ( dreq.addr == r_dcache_addr_save) ); 1073 dcache_rdata = r_dcache_miss_buf[0]; 1074 } 1075 1076 // next state & response evaluation 1077 switch( dreq.type ) { 1078 case iss_t::DATA_READ: 1079 case iss_t::DATA_LL: 1080 case iss_t::DATA_SC: 1081 m_cpt_read++; 1082 if ( dcache_hit ) 1083 { 1084 r_dcache_fsm = DCACHE_IDLE; 1085 drsp.valid = true; 1086 drsp.rdata = dcache_rdata; 1087 r_rsp_data_ok = false; 1088 } 1089 else 1090 { 1091 if ( dcache_cached ) // miss 1092 { 1093 m_cpt_data_miss++; 1094 m_cost_data_miss_frz++; 1095 // if the missing line corresponds to a pending cleanup 1096 // the miss request to the CMD FSM must be delayed 1097 if ( r_dcache_cleanup_req && 1098 ((addr_t)r_dcache_cleanup_line == (addr_t)(dreq.addr/(m_dcache_words*4))) ) 1099 { 1100 break; 1101 } 1102 else 1103 { 1104 r_dcache_miss_req = true; 1105 r_rsp_data_ok = false; 1106 r_dcache_fsm = DCACHE_MISS_SELECT; 1107 } 1108 drsp.valid = false; 1109 drsp.rdata = 0; 1110 } 1111 else // uncached 1112 { 1113 m_cpt_unc_read++; 1114 m_cost_unc_read_frz++; 1115 r_dcache_unc_req = true; 1116 r_rsp_data_ok = false; 1117 r_dcache_fsm = DCACHE_UNC_WAIT; 1118 drsp.valid = false; 1119 drsp.rdata = 0; 1120 } 1121 } 1122 break; 1123 case iss_t::XTN_READ: 1124 case iss_t::XTN_WRITE: 1125 // only DCACHE_INVAL & SYNC requests are supported 1126 if ( dreq.addr/4 == iss_t::XTN_DCACHE_INVAL ) 1127 { 1128 r_dcache_fsm = DCACHE_INVAL; 1129 } 1130 else if ( dreq.addr/4 == iss_t::XTN_SYNC ) 1131 { 1132 r_dcache_fsm = DCACHE_SYNC; 1133 } 1134 else 1135 { 1136 // std::cout << "warning in VCI_CC_XCACHE_WRAPPER " << name() << std::endl; 1137 // std::cout << "unsupported external access " << dreq.addr/4 << std::endl; 1138 // std::cout << "only XTN_DCACHE_INVAL & XTN_SYNC are supported" << std::endl; 1139 } 1140 r_dcache_fsm = DCACHE_IDLE; 1141 drsp.valid = true; 1142 drsp.rdata = 0; 1143 break; 1144 case iss_t::DATA_WRITE: 1145 m_cpt_write++; 1146 if ( dcache_hit && dcache_cached ) 1147 { 1148 m_cpt_write_cached++; 1149 r_dcache_fsm = DCACHE_WRITE_UPDT; 1150 drsp.valid = true; 1151 drsp.rdata = 0; 1152 } 1153 else 1154 { 1155 r_dcache_fsm = DCACHE_WRITE_REQ; 1156 drsp.valid = true; 1157 drsp.rdata = 0; 1158 } 1159 break; 1160 } // end switch dreq.type 1161 1110 dcache_cachable = m_cacheability_table[dreq.addr]; 1111 dcache_hit = r_dcache.read(dreq.addr, &dcache_rdata); 1112 1113 // Save data request 1162 1114 r_dcache_addr_save = dreq.addr; 1163 1115 r_dcache_type_save = dreq.type; … … 1165 1117 r_dcache_be_save = dreq.be; 1166 1118 r_dcache_rdata_save = dcache_rdata; 1167 } 1168 else // no dreq.valid 1169 { 1170 drsp.valid = false; 1171 drsp.rdata = 0; 1172 r_dcache_fsm = DCACHE_IDLE; 1173 } 1174 break; 1175 } 1119 1120 // reset r_rsp_data_ok 1121 r_rsp_data_ok = false; 1122 1123 // next FSM state, request to VCI, and processor response 1124 if(dreq.type == iss_t::DATA_READ) 1125 { 1126 if(!dcache_cachable) // uncachable read 1127 { 1128 m_cpt_data_unc++; 1129 m_cost_unc_frz++; 1130 r_dcache_unc_req = true; 1131 r_dcache_fsm = DCACHE_UNC_WAIT; 1132 } 1133 else 1134 { 1135 m_cpt_read++; 1136 if(dcache_hit) // cachable read hit 1137 { 1138 drsp.valid = true; 1139 drsp.rdata = dcache_rdata; 1140 r_dcache_fsm = DCACHE_IDLE; 1141 } 1142 else // cachable read miss 1143 { 1144 m_cost_data_miss_frz++; 1145 // if the missing line corresponds to a pending cleanup 1146 // the miss request to the CMD FSM must be delayed 1147 if ( r_dcache_cleanup_req && 1148 ((addr_t)r_dcache_cleanup_line == (addr_t)(dreq.addr/(m_dcache_words*4))) ) 1149 { 1150 break; 1151 } 1152 else 1153 { 1154 m_cpt_data_miss++; 1155 r_dcache_miss_req = true; 1156 r_dcache_fsm = DCACHE_MISS_SELECT; 1157 } 1158 } 1159 } 1160 } 1161 else if(dreq.type == iss_t::DATA_WRITE) 1162 { 1163 if(!dcache_cachable) // uncachable write 1164 { 1165 m_cpt_data_unc++; 1166 m_cost_unc_frz++; 1167 r_dcache_unc_req = true; 1168 r_dcache_fsm = DCACHE_UNC_WAIT; 1169 } 1170 else 1171 { 1172 m_cpt_write++; 1173 if(!dcache_hit) // cachable write miss 1174 { 1175 drsp.rdata = 0; 1176 drsp.valid = true; 1177 r_dcache_fsm = DCACHE_WRITE_REQ; 1178 } 1179 else // cachable write hit 1180 { 1181 m_cpt_write_cached++; 1182 drsp.rdata = 0; 1183 drsp.valid = true; 1184 r_dcache_fsm = DCACHE_WRITE_UPDT; 1185 } 1186 } 1187 } 1188 else if(dreq.type == iss_t::DATA_LL) // linked read 1189 // all LL requests are handled as uncachable 1190 { 1191 m_cpt_ll++; 1192 m_cost_unc_frz++; 1193 r_dcache_unc_req = true; 1194 r_dcache_fsm = DCACHE_UNC_WAIT; 1195 } 1196 else if(dreq.type == iss_t::DATA_SC) // conditional write 1197 // all SC requests are handled as uncachable 1198 { 1199 m_cpt_sc++; 1200 m_cost_unc_frz++; 1201 r_dcache_unc_req = true; 1202 r_dcache_fsm = DCACHE_UNC_WAIT; 1203 } 1204 else if((dreq.type == iss_t::XTN_WRITE) || (dreq.type == iss_t::XTN_READ)) // XTN access 1205 // only INVAL & SYNC requests are supported 1206 { 1207 drsp.valid = true; 1208 drsp.rdata = 0; 1209 if ( dreq.addr/4 == iss_t::XTN_DCACHE_INVAL ) 1210 { 1211 r_dcache_fsm = DCACHE_INVAL; 1212 } 1213 else if ( dreq.addr/4 == iss_t::XTN_SYNC ) 1214 { 1215 r_dcache_fsm = DCACHE_SYNC; 1216 } 1217 else if ( dreq.addr/4 == iss_t::XTN_TLB_MODE ) 1218 { 1219 r_dcache_fsm = DCACHE_IDLE; 1220 } 1221 else 1222 { 1223 std::cout << "warning in VCI_CC_XCACHE_WRAPPER " << name() << std::endl; 1224 std::cout << "unsupported external access : " << dreq.addr/4 << std::endl; 1225 std::cout << "only TLB_MODE, DCACHE_INVAL & SYNC are supported" << std::endl; 1226 } 1227 } 1228 } 1229 else // no dreq.valid 1230 { 1231 r_dcache_fsm = DCACHE_IDLE; 1232 drsp.valid = true; 1233 drsp.rdata = 0; 1234 } 1235 break; 1236 } 1176 1237 case DCACHE_WRITE_UPDT: 1177 1238 { … … 1188 1249 size_t way; 1189 1250 addr_t index; 1190 addr_t ad= r_dcache_addr_save;1191 if ( r_dcache.select_before_update( ad , &way, &index) )1251 addr_t addr = r_dcache_addr_save; 1252 if ( r_dcache.select_before_update( addr, &way, &index) ) 1192 1253 { 1193 1254 r_dcache_fsm = DCACHE_MISS_CLEANUP; … … 1240 1301 else 1241 1302 { 1303 // the cache is not updated in case of pending inval 1242 1304 r_dcache_cleanup_req = true; 1243 1305 r_dcache_cleanup_line = r_dcache_addr_save >> (uint32_log2(m_icache_words) + 2); … … 1263 1325 case DCACHE_UNC_WAIT: 1264 1326 { 1265 if ( dreq.valid ) m_cost_unc_ read_frz++;1327 if ( dreq.valid ) m_cost_unc_frz++; 1266 1328 if ( r_tgt_dcache_req ) // external request 1267 1329 { … … 1272 1334 if ( r_rsp_data_ok ) 1273 1335 { 1274 if ( r_rsp_data_error ) r_dcache_fsm = DCACHE_ERROR; 1275 else 1276 { 1277 // If request is a DATA_SC we need to invalidate the corresponding cache line, 1278 // so that subsequent access to this line are read from RAM 1279 if (dreq.type == iss_t::DATA_SC) 1280 { 1281 r_dcache_fsm = DCACHE_INVAL; 1282 r_dcache_wdata_save = r_dcache_addr_save; 1283 } 1284 else 1285 { 1286 r_dcache_fsm = DCACHE_IDLE; 1287 } 1288 } 1289 } 1336 if ( r_rsp_data_error ) r_dcache_fsm = DCACHE_ERROR; 1337 else r_dcache_fsm = DCACHE_UNC_GO; 1338 } 1339 break; 1340 } 1341 case DCACHE_UNC_GO: 1342 { 1343 r_dcache_fsm = DCACHE_IDLE; 1344 drsp.valid = true; 1345 drsp.rdata = r_dcache_miss_buf[0]; 1290 1346 break; 1291 1347 } … … 1298 1354 break; 1299 1355 } 1300 case DCACHE_INVAL: 1356 case DCACHE_INVAL: // local inval requiring a cleanup in case of hit 1301 1357 { 1302 1358 if( !r_dcache_cleanup_req ) … … 1315 1371 } 1316 1372 case DCACHE_CC_CHECK: // read directory in case of external request 1373 { 1317 1374 m_cpt_dcache_dir_read += m_dcache_ways; 1318 1375 m_cpt_dcache_data_read += m_dcache_ways; 1319 if ( ( (r_dcache_fsm_save == DCACHE_MISS_WAIT) || (r_dcache_fsm_save == DCACHE_MISS_CLEANUP) ) && // external request matches a miss1376 if ( ( (r_dcache_fsm_save == DCACHE_MISS_WAIT) || (r_dcache_fsm_save == DCACHE_MISS_CLEANUP) ) && 1320 1377 ((r_dcache_addr_save & ~((m_dcache_words<<2)-1))==(r_tgt_addr & ~((m_dcache_words<<2)-1)))) 1321 { 1322 r_dcache_inval_pending = true; 1323 r_tgt_dcache_req = false; 1324 r_tgt_dcache_rsp = r_tgt_update; // always a response to an update 1325 r_dcache_fsm = r_dcache_fsm_save; 1378 // external request matches a miss 1379 { 1380 r_dcache_inval_pending = true; 1381 r_tgt_dcache_req = false; 1382 r_tgt_dcache_rsp = r_tgt_update; // always a response to an update 1383 r_dcache_fsm = r_dcache_fsm_save; 1384 } 1385 else // the external request is not matching a pending miss 1386 { 1387 data_t data; 1388 bool dcache_hit = r_dcache.read(r_tgt_addr, &data); 1389 if ( dcache_hit && r_tgt_update ) // hit update 1390 { 1391 r_dcache_fsm = DCACHE_CC_UPDT; 1326 1392 } 1327 else // the external request is not matching a pending miss 1328 { 1329 data_t data; 1330 bool dcache_hit = r_dcache.read(r_tgt_addr, &data); 1331 if ( dcache_hit && r_tgt_update ) // hit update 1332 { 1333 r_dcache_fsm = DCACHE_CC_UPDT; 1334 } 1335 else if ( dcache_hit && !r_tgt_update ) // hit inval 1336 { 1337 r_dcache_fsm = DCACHE_CC_INVAL; 1338 } 1339 else // miss 1340 { 1341 r_tgt_dcache_req = false; 1342 r_tgt_dcache_rsp = r_tgt_update; // always a respons in case of update 1343 r_dcache_fsm = r_dcache_fsm_save; 1344 } 1345 } 1346 break; 1347 1348 case DCACHE_CC_UPDT: // update the cache line 1349 m_cpt_dcache_dir_write++; 1350 m_cpt_dcache_data_write++; 1351 for(size_t i=0; i<m_dcache_words; i++) 1352 { 1353 if(r_tgt_val[i]) r_dcache.write( (r_tgt_addr + i*4), r_tgt_buf[i] ); 1354 } 1355 r_tgt_dcache_rsp = true; 1356 r_tgt_dcache_req = false; 1357 r_dcache_fsm = r_dcache_fsm_save; 1358 break; 1359 1360 case DCACHE_CC_INVAL: // invalidate a cache line 1393 else if ( dcache_hit && !r_tgt_update ) // hit inval 1394 { 1395 r_dcache_fsm = DCACHE_CC_INVAL; 1396 } 1397 else // miss 1398 { 1399 r_tgt_dcache_req = false; 1400 r_tgt_dcache_rsp = r_tgt_update; // always a respons in case of update 1401 r_dcache_fsm = r_dcache_fsm_save; 1402 } 1403 } 1404 break; 1405 } 1406 case DCACHE_CC_UPDT: // update the cache line 1407 { 1408 m_cpt_dcache_dir_write++; 1409 m_cpt_dcache_data_write++; 1410 for(size_t i=0; i<m_dcache_words; i++) 1411 { 1412 if(r_tgt_val[i]) r_dcache.write( (r_tgt_addr + i*4), r_tgt_buf[i] ); 1413 } 1414 r_tgt_dcache_rsp = true; 1415 r_tgt_dcache_req = false; 1416 r_dcache_fsm = r_dcache_fsm_save; 1417 break; 1418 } 1419 case DCACHE_CC_INVAL: // invalidate a cache line 1420 { 1361 1421 r_dcache.inval(r_tgt_addr); 1362 1422 r_tgt_dcache_rsp = true; … … 1364 1424 r_dcache_fsm = r_dcache_fsm_save; 1365 1425 break; 1426 } 1366 1427 } // end switch r_dcache_fsm 1367 1428 1368 ////////// write buffer handling ////////////////// 1369 if( r_dcache_fsm == DCACHE_WRITE_REQ ) 1370 r_wbuf.write(true, r_dcache_addr_save, r_dcache_be_save, r_dcache_wdata_save); 1371 else 1372 r_wbuf.write(false, 0, 0, 0); 1429 ////////// write buffer state update ///////////// 1430 // The update() method must be called at each cycle to update the internal state. 1431 // All pending write requests must be locked in case of SYNC or in case of MISS. 1432 if( (r_dcache_fsm == DCACHE_SYNC) || (r_dcache_fsm == DCACHE_MISS_WAIT) ) 1433 { 1434 r_wbuf.update(true); 1435 } 1436 else 1437 { 1438 r_wbuf.update(false); 1439 } 1373 1440 1374 1441 #if SOCLIB_MODULE_DEBUG 1375 if ( m_srcid_d == 0 )1376 1442 std::cout << ireq << std::endl << irsp << std::endl << dreq << std::endl << drsp << std::endl; 1377 1443 #endif … … 1391 1457 // on the coherence network. It controls the following ressources: 1392 1458 // - r_cleanup_fsm 1393 // - r_dcache_cleanup_req reset1394 // - r_icache_cleanup_req reset1459 // - r_dcache_cleanup_req (reset) 1460 // - r_icache_cleanup_req (reset) 1395 1461 // 1396 1462 // This FSM handles cleanup requests from both the DCACHE FSM & ICACHE FSM 1397 // 1- Instruction Cleanup : r_icache_cleanup_req1398 // 2- Data Cleanup : r_dcache_cleanup_req1463 // - Instruction Cleanup : r_icache_cleanup_req 1464 // - Data Cleanup : r_dcache_cleanup_req 1399 1465 // In case of simultaneous requests, the data request have highest priority. 1400 1466 // There is only one cleanup transaction at a given time (sequencial behavior) … … 1409 1475 switch (r_cleanup_fsm) { 1410 1476 1411 case CLEANUP_ CMD:1477 case CLEANUP_IDLE: 1412 1478 { 1413 1479 if ( p_vci_ini_c.cmdack ) 1414 1480 { 1415 if (r_dcache_cleanup_req) r_cleanup_fsm = CLEANUP_DCACHE _RSP;1416 else if (r_icache_cleanup_req) r_cleanup_fsm = CLEANUP_ICACHE _RSP;1417 } 1418 break; 1419 } 1420 case CLEANUP_DCACHE _RSP:1481 if (r_dcache_cleanup_req) r_cleanup_fsm = CLEANUP_DCACHE; 1482 else if (r_icache_cleanup_req) r_cleanup_fsm = CLEANUP_ICACHE; 1483 } 1484 break; 1485 } 1486 case CLEANUP_DCACHE: 1421 1487 { 1422 1488 if ( p_vci_ini_c.rspval ) … … 1427 1493 "error signaled in a cleanup response" ); 1428 1494 1429 r_cleanup_fsm = CLEANUP_ CMD;1495 r_cleanup_fsm = CLEANUP_IDLE; 1430 1496 r_dcache_cleanup_req = false; 1431 } 1432 break; 1433 } 1434 case CLEANUP_ICACHE_RSP: 1497 m_cpt_cc_cleanup_data++; 1498 } 1499 break; 1500 } 1501 case CLEANUP_ICACHE: 1435 1502 { 1436 1503 if ( p_vci_ini_c.rspval ) … … 1441 1508 "error signaled in a cleanup response" ); 1442 1509 1443 r_cleanup_fsm = CLEANUP_ CMD;1510 r_cleanup_fsm = CLEANUP_IDLE; 1444 1511 r_icache_cleanup_req = false; 1512 m_cpt_cc_cleanup_ins++; 1445 1513 } 1446 1514 break; … … 1464 1532 // There is 5 request types, with the following priorities : 1465 1533 // 1 - Data Read Miss : r_dcache_miss_req (if no hit in the write buffer) 1466 // 2 - Data Read Uncach ed: r_dcache_unc_req (if no hit in the write buffer)1534 // 2 - Data Read Uncachable : r_dcache_unc_req (if no hit in the write buffer) 1467 1535 // 3 - Instruction Miss : r_icache_miss_req (if no hit in the write buffer) 1468 // 4 - Instruction Uncach ed: r_icache_unc_req (if no hit in the write buffer)1536 // 4 - Instruction Uncachable : r_icache_unc_req (if no hit in the write buffer) 1469 1537 // 5 - Data Write : r_wbuf.rok() 1470 1538 // The read requests have highest priority, because the processor is blocked. … … 1472 1540 // VCI formats: 1473 1541 // According to the VCI advanced specification, all read requests packets 1474 // (read Uncach ed, Miss data, Miss instruction) are one word packets.1542 // (read Uncachable, Miss data, Miss instruction) are one word packets. 1475 1543 // For write burst packets, all words must be in the same cache line, 1476 1544 // and addresses must be contiguous (the BE field is 0 in case of "holes"). 1477 1545 // The PLEN VCI field is always documented. 1478 // - Read transactions : index = 4*cached + 2*instruction (even values) 1479 ////////////////////////////////////////////////////////////////////////////// 1546 // As simultaneous VCI transactions are supported, the TRDID field is used: 1547 // - Write transactions : TRDID = wbuf_index + (1<<(trdid_size-1)) 1548 // - Read transactions : TRDID = 2*cachable + instruction 1549 /////////////////////////////////////////////////////////////////////////////////// 1480 1550 1481 1551 switch (r_cmd_fsm) { 1482 1552 1483 1553 case CMD_IDLE: 1554 { 1555 size_t min; 1556 size_t max; 1484 1557 if ( r_dcache_miss_req & r_wbuf.miss( r_dcache_addr_save ) ) 1485 1558 { … … 1488 1561 m_cpt_dmiss_transaction++; 1489 1562 } 1490 else if ( r_dcache_unc_req & r_wbuf.miss( r_dcache_addr_save ) )1491 {1492 r_cmd_fsm = CMD_DATA_UNC;1493 r_dcache_unc_req = false;1494 m_cpt_unc_transaction++;1495 }1496 1563 else if ( r_icache_miss_req & r_wbuf.miss( r_icache_addr_save ) ) 1497 1564 { … … 1500 1567 m_cpt_imiss_transaction++; 1501 1568 } 1502 else if ( r_icache_unc_req & r_wbuf.miss( r_icache_addr_save ) ) 1569 else if ( r_wbuf.rok(&min, &max) ) 1570 { 1571 r_cmd_fsm = CMD_DATA_WRITE; 1572 r_cmd_cpt = min; 1573 r_cmd_min = min; 1574 r_cmd_max = max; 1575 m_cpt_write_transaction++; 1576 m_length_write_transaction += (max-min+1); 1577 } 1578 else if ( r_dcache_unc_req ) 1579 { 1580 r_cmd_fsm = CMD_DATA_UNC; 1581 r_dcache_unc_req = false; 1582 m_cpt_data_unc_transaction++; 1583 } 1584 else if ( r_icache_unc_req ) 1503 1585 { 1504 1586 r_cmd_fsm = CMD_INS_UNC; 1505 1587 r_icache_unc_req = false; 1506 m_cpt_imiss_transaction++; 1507 } 1508 else if ( r_wbuf.rok() ) 1509 { 1510 r_cmd_fsm = CMD_DATA_WRITE; 1511 r_cmd_cpt = r_wbuf.getMin(); 1512 r_cmd_min = r_wbuf.getMin(); 1513 r_cmd_max = r_wbuf.getMax(); 1514 m_cpt_write_transaction++; 1515 m_length_write_transaction += (r_wbuf.getMax() - r_wbuf.getMin() + 1); 1516 } 1517 break; 1518 1588 m_cpt_ins_unc_transaction++; 1589 } 1590 break; 1591 } 1519 1592 case CMD_DATA_WRITE: 1593 { 1520 1594 if ( p_vci_ini_d.cmdack.read() ) 1521 1595 { … … 1528 1602 } 1529 1603 break; 1530 1604 } 1531 1605 case CMD_INS_MISS: 1532 1606 case CMD_INS_UNC: 1533 1607 case CMD_DATA_MISS: 1534 1608 case CMD_DATA_UNC: 1609 { 1535 1610 if ( p_vci_ini_d.cmdack.read() ) r_cmd_fsm = CMD_IDLE; 1536 1611 break; 1612 } 1537 1613 } // end switch r_cmd_fsm 1538 1614 … … 1557 1633 // VCI formats: 1558 1634 // This component accepts only single word write response packets. 1635 // As simultaneous VCI transactions are supported, the TRDID field is used: 1636 // - Write transactions : TRDID = wbuf_index + (1<<(trdid_size-1)) 1637 // - Read transactions : TRDID = 2*cachable + instruction 1559 1638 // 1560 1639 // Error handling: 1561 // This FSM analyzes the VCI error code and signals the Write Bus Error.1562 // In case of Read Data Error, the VCI_RSP FSM sets the r_rsp_data_error1563 // flip_flop and the error is signaled by the DCACHE FSM.1564 // In case of Instruction Error, the VCI_RSP FSM sets the r_rsp_ins_error1565 // flip_flop and the error is signaled by the DCACHE FSM.1640 // - In case of Write error, the error is directly signaled by the RSP FSM. 1641 // - In case of Read Data Error, the VCI_RSP FSM sets the r_rsp_data_error 1642 // flip_flop and the error is signaled by the DCACHE FSM. 1643 // - In case of Instruction Error, the VCI_RSP FSM sets the r_rsp_ins_error 1644 // flip_flop and the error is signaled by the ICACHE FSM. 1566 1645 ////////////////////////////////////////////////////////////////////////// 1646 // Implementation note 1647 // It should be possible to save one cycle on the MISS cost by a simple 1648 // modification of this RSP FSM : The first flit of a valid response 1649 // could be decoded and handled directly in the IDLE state. 1650 // The computation of the RSPACK condition become more complex... 1651 //////////////////////////////////////////////////////////////////////////: 1567 1652 1568 1653 switch (r_rsp_fsm) { 1569 1654 1570 1655 case RSP_IDLE: 1656 { 1571 1657 if( p_vci_ini_d.rspval.read() ) 1572 1658 { 1573 1659 r_rsp_cpt = 0; 1574 if ( p_vci_ini_d.rtrdid.read()/m_wbuf_nlines != 0 )r_rsp_fsm = RSP_DATA_WRITE;1575 else if ( p_vci_ini_d.rtrdid.read() == TYPE_DATA_MISS ) r_rsp_fsm = RSP_DATA_MISS;1576 else if ( p_vci_ini_d.rtrdid.read() == TYPE_DATA_UNC ) r_rsp_fsm = RSP_DATA_UNC;1577 else if ( p_vci_ini_d.rtrdid.read() == TYPE_INS_MISS ) r_rsp_fsm = RSP_INS_MISS;1578 else if ( p_vci_ini_d.rtrdid.read() == TYPE_INS_UNC ) r_rsp_fsm = RSP_INS_UNC;1579 } 1580 break; 1581 1660 if ( (p_vci_ini_d.rtrdid.read()>>(vci_param::T-1)) != 0 ) r_rsp_fsm = RSP_DATA_WRITE; 1661 else if ( p_vci_ini_d.rtrdid.read() == TYPE_DATA_MISS ) r_rsp_fsm = RSP_DATA_MISS; 1662 else if ( p_vci_ini_d.rtrdid.read() == TYPE_DATA_UNC ) r_rsp_fsm = RSP_DATA_UNC; 1663 else if ( p_vci_ini_d.rtrdid.read() == TYPE_INS_MISS ) r_rsp_fsm = RSP_INS_MISS; 1664 else if ( p_vci_ini_d.rtrdid.read() == TYPE_INS_UNC ) r_rsp_fsm = RSP_INS_UNC; 1665 } 1666 break; 1667 } 1582 1668 case RSP_DATA_WRITE: 1669 { 1583 1670 if ( p_vci_ini_d.rspval.read() ) 1584 1671 { 1585 1672 assert(p_vci_ini_d.reop.read() && 1586 " illegal VCI response packet for a write transaction");1673 "A VCI response packet must contain one flit for a write transaction"); 1587 1674 r_rsp_fsm = RSP_IDLE; 1588 r_wbuf.completed( p_vci_ini_d.rtrdid.read() - m_wbuf_nlines);1675 r_wbuf.completed( p_vci_ini_d.rtrdid.read() - (1<<(vci_param::T-1)) ); 1589 1676 if ( p_vci_ini_d.rerror.read() != vci_param::ERR_NORMAL ) m_iss.setWriteBerr(); 1590 1677 } 1591 1678 break; 1592 1679 } 1593 1680 case RSP_INS_MISS: 1681 { 1594 1682 if ( p_vci_ini_d.rspval.read() ) 1595 1683 { … … 1607 1695 } 1608 1696 break; 1609 1697 } 1610 1698 case RSP_INS_UNC: 1699 { 1611 1700 if ( p_vci_ini_d.rspval.read() ) 1612 1701 { 1613 1702 assert(p_vci_ini_d.reop.read() && 1614 "illegal VCI response packet for uncach edinstruction");1703 "illegal VCI response packet for uncachable instruction"); 1615 1704 r_icache_miss_buf[0] = (data_t)p_vci_ini_d.rdata.read(); 1616 1705 r_rsp_ins_ok = true; … … 1619 1708 } 1620 1709 break; 1621 1710 } 1622 1711 case RSP_DATA_MISS: 1712 { 1623 1713 if ( p_vci_ini_d.rspval.read() ) 1624 1714 { 1625 assert( r_rsp_cpt != m_dcache_words&&1626 "illegal VCI response packet for data read miss");1715 assert( (r_rsp_cpt < m_dcache_words) && 1716 "The VCI response packet for data miss is too long" ); 1627 1717 r_rsp_cpt = r_rsp_cpt + 1; 1628 1718 r_dcache_miss_buf[r_rsp_cpt] = (data_t)p_vci_ini_d.rdata.read(); … … 1630 1720 { 1631 1721 assert(r_rsp_cpt == m_dcache_words - 1 && 1632 "illegal VCI response packet for instruction miss");1722 "The VCI response packet for data miss is too short" ); 1633 1723 r_rsp_data_ok = true; 1634 1724 r_rsp_fsm = RSP_IDLE; … … 1637 1727 } 1638 1728 break; 1639 1729 } 1640 1730 case RSP_DATA_UNC: 1731 { 1641 1732 if ( p_vci_ini_d.rspval.read() ) 1642 1733 { 1643 1734 assert(p_vci_ini_d.reop.read() && 1644 "illegal VCI response packet for uncach ed readdata");1735 "illegal VCI response packet for uncachable data"); 1645 1736 r_dcache_miss_buf[0] = (data_t)p_vci_ini_d.rdata.read(); 1646 1737 r_rsp_data_ok = true; … … 1649 1740 } 1650 1741 break; 1742 } 1651 1743 } // end switch r_rsp_fsm 1652 1744 1653 1745 } // end transition() 1654 1746 1655 ////////////////////// ////////////////////////////////////////////////////////////1747 ////////////////////// 1656 1748 tmpl(void)::genMoore() 1657 //////////////////////////////////////////////////////////////////////////////////1658 1749 { 1659 1750 // Coherence network (initiator port) … … 1661 1752 switch ( r_cleanup_fsm.read() ) { 1662 1753 1663 case CLEANUP_ CMD:1754 case CLEANUP_IDLE: 1664 1755 p_vci_ini_c.rspack = false; 1665 1756 p_vci_ini_c.cmdval = r_icache_cleanup_req || r_dcache_cleanup_req; 1666 1757 if ( r_dcache_cleanup_req ) 1667 1758 { 1668 p_vci_ini_c.address = r_dcache_cleanup_line.read() * m_dcache_words * 4;1759 p_vci_ini_c.address = r_dcache_cleanup_line.read() * (m_dcache_words << 2); 1669 1760 p_vci_ini_c.trdid = 0; 1670 1761 } 1671 1762 else 1672 1763 { 1673 p_vci_ini_c.address = r_icache_cleanup_line.read() * (m_icache_words << 2); //* 4;1764 p_vci_ini_c.address = r_icache_cleanup_line.read() * (m_icache_words << 2); 1674 1765 p_vci_ini_c.trdid = 1; 1675 1766 } … … 1688 1779 break; 1689 1780 1690 case CLEANUP_DCACHE _RSP:1781 case CLEANUP_DCACHE: 1691 1782 p_vci_ini_c.rspack = true; 1692 1783 p_vci_ini_c.cmdval = false; … … 1707 1798 break; 1708 1799 1709 case CLEANUP_ICACHE _RSP:1800 case CLEANUP_ICACHE: 1710 1801 p_vci_ini_c.rspack = true; 1711 1802 p_vci_ini_c.cmdval = false; … … 1755 1846 case CMD_DATA_WRITE: 1756 1847 p_vci_ini_d.cmdval = true; 1757 p_vci_ini_d.address = r_wbuf.getAddress(r_cmd_cpt) &~0x3;1848 p_vci_ini_d.address = r_wbuf.getAddress(r_cmd_cpt); 1758 1849 p_vci_ini_d.wdata = r_wbuf.getData(r_cmd_cpt); 1759 1850 p_vci_ini_d.be = r_wbuf.getBe(r_cmd_cpt); 1760 1851 p_vci_ini_d.plen = (r_cmd_max - r_cmd_min + 1)<<2; 1761 1852 p_vci_ini_d.cmd = vci_param::CMD_WRITE; 1853 p_vci_ini_d.trdid = r_wbuf.getIndex() + (1<<(vci_param::T-1)); 1762 1854 p_vci_ini_d.pktid = 0; 1763 p_vci_ini_d.trdid = r_wbuf.getIndex() + m_wbuf_nlines;1764 1855 p_vci_ini_d.srcid = m_srcid_d; 1765 1856 p_vci_ini_d.cons = false; … … 1771 1862 break; 1772 1863 1864 case CMD_DATA_MISS: 1865 p_vci_ini_d.cmdval = true; 1866 p_vci_ini_d.address = r_dcache_addr_save & (addr_t)m_dcache_yzmask; 1867 p_vci_ini_d.be = 0xF; 1868 p_vci_ini_d.plen = m_dcache_words << 2; 1869 p_vci_ini_d.cmd = vci_param::CMD_READ; 1870 p_vci_ini_d.trdid = TYPE_DATA_MISS; 1871 p_vci_ini_d.pktid = 0; 1872 p_vci_ini_d.srcid = m_srcid_d; 1873 p_vci_ini_d.cons = false; 1874 p_vci_ini_d.wrap = false; 1875 p_vci_ini_d.contig = true; 1876 p_vci_ini_d.clen = 0; 1877 p_vci_ini_d.cfixed = false; 1878 p_vci_ini_d.eop = true; 1879 break; 1880 1773 1881 case CMD_DATA_UNC: 1774 1882 p_vci_ini_d.cmdval = true; 1775 1883 p_vci_ini_d.address = r_dcache_addr_save & ~0x3; 1776 1884 switch( r_dcache_type_save ) { 1885 case iss_t::DATA_WRITE: 1886 p_vci_ini_d.wdata = r_dcache_wdata_save.read(); 1887 p_vci_ini_d.be = r_dcache_be_save.read(); 1888 p_vci_ini_d.cmd = vci_param::CMD_WRITE; 1889 break; 1777 1890 case iss_t::DATA_READ: 1778 1891 p_vci_ini_d.wdata = 0; … … 1793 1906 assert("this should not happen"); 1794 1907 } 1795 p_vci_ini_d.plen = 4;1908 p_vci_ini_d.plen = 4; 1796 1909 p_vci_ini_d.trdid = TYPE_DATA_UNC; 1797 1910 p_vci_ini_d.pktid = 0; … … 1805 1918 break; 1806 1919 1807 case CMD_DATA_MISS:1808 p_vci_ini_d.cmdval = true;1809 p_vci_ini_d.address = r_dcache_addr_save.read() & (addr_t) m_dcache_yzmask;1810 p_vci_ini_d.be = 0xF;1811 p_vci_ini_d.plen = m_dcache_words << 2;1812 p_vci_ini_d.cmd = vci_param::CMD_READ;1813 p_vci_ini_d.trdid = TYPE_DATA_MISS;1814 p_vci_ini_d.pktid = 0;1815 p_vci_ini_d.srcid = m_srcid_d;1816 p_vci_ini_d.cons = false;1817 p_vci_ini_d.wrap = false;1818 p_vci_ini_d.contig = true;1819 p_vci_ini_d.clen = 0;1820 p_vci_ini_d.cfixed = false;1821 p_vci_ini_d.eop = true;1822 break;1823 1824 1920 case CMD_INS_MISS: 1825 1921 p_vci_ini_d.cmdval = true; 1826 p_vci_ini_d.address = r_icache_addr_save & (addr_t) 1922 p_vci_ini_d.address = r_icache_addr_save & (addr_t)m_icache_yzmask; 1827 1923 p_vci_ini_d.be = 0xF; 1828 1924 p_vci_ini_d.plen = m_icache_words << 2;
Note: See TracChangeset
for help on using the changeset viewer.