Changeset 789 for trunk/modules
- Timestamp:
- Sep 3, 2014, 2:38:01 PM (10 years ago)
- Location:
- trunk/modules
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/modules/vci_cc_vcache_wrapper/caba/source/src/vci_cc_vcache_wrapper.cpp
r752 r789 34 34 #include "../include/vci_cc_vcache_wrapper.h" 35 35 36 #define DEBUG_DCACHE 37 #define DEBUG_ICACHE 38 #define DEBUG_CMD 36 #define DEBUG_DCACHE 1 37 #define DEBUG_ICACHE 1 38 #define DEBUG_CMD 0 39 39 40 40 namespace soclib { … … 42 42 43 43 namespace { 44 const char * icache_fsm_state_str[] = {44 const char * icache_fsm_state_str[] = { 45 45 "ICACHE_IDLE", 46 46 … … 68 68 }; 69 69 70 const char * dcache_fsm_state_str[] = {70 const char * dcache_fsm_state_str[] = { 71 71 "DCACHE_IDLE", 72 72 … … 117 117 }; 118 118 119 const char * cmd_fsm_state_str[] = {119 const char * cmd_fsm_state_str[] = { 120 120 "CMD_IDLE", 121 121 "CMD_INS_MISS", … … 130 130 }; 131 131 132 const char * vci_pktid_type_str[] = {132 const char * vci_pktid_type_str[] = { 133 133 "TYPE_DATA_UNC", 134 134 "TYPE_READ_DATA_MISS", … … 141 141 }; 142 142 143 const char * vci_cmd_type_str[] = {143 const char * vci_cmd_type_str[] = { 144 144 "NOP or STORE_COND", 145 145 "READ", … … 148 148 }; 149 149 150 const char * rsp_fsm_state_str[] = {150 const char * rsp_fsm_state_str[] = { 151 151 "RSP_IDLE", 152 152 "RSP_INS_MISS", … … 158 158 }; 159 159 160 const char * cc_receive_fsm_state_str[] = {160 const char * cc_receive_fsm_state_str[] = { 161 161 "CC_RECEIVE_IDLE", 162 162 "CC_RECEIVE_BRDCAST_HEADER", … … 174 174 }; 175 175 176 const char * cc_send_fsm_state_str[] = {176 const char * cc_send_fsm_state_str[] = { 177 177 "CC_SEND_IDLE", 178 178 "CC_SEND_CLEANUP_1", … … 193 193 ///////////////////////////////// 194 194 tmpl(/**/)::VciCcVCacheWrapper( 195 sc_module_name 196 const int 197 const MappingTable 198 const IntTab 199 const size_t 200 const size_t 201 const size_t 202 const size_t 203 const size_t 204 const size_t 205 const size_t 206 const size_t 207 const size_t 208 const size_t 209 const size_t 210 const size_t 211 const size_t 212 const size_t 213 const size_t 214 const uint32_t 215 const uint32_t 216 const bool debug_ok)195 sc_module_name name, 196 const int proc_id, 197 const MappingTable &mtd, 198 const IntTab &srcid, 199 const size_t cc_global_id, 200 const size_t itlb_ways, 201 const size_t itlb_sets, 202 const size_t dtlb_ways, 203 const size_t dtlb_sets, 204 const size_t icache_ways, 205 const size_t icache_sets, 206 const size_t icache_words, 207 const size_t dcache_ways, 208 const size_t dcache_sets, 209 const size_t dcache_words, 210 const size_t wbuf_nlines, 211 const size_t wbuf_nwords, 212 const size_t x_width, 213 const size_t y_width, 214 const uint32_t max_frozen_cycles, 215 const uint32_t debug_start_cycle, 216 const bool debug_ok) 217 217 : soclib::caba::BaseModule(name), 218 218 … … 224 224 p_dspin_clack("p_dspin_clack"), 225 225 226 m_cacheability_table( mtd.getCacheabilityTable() 227 m_srcid( mtd.indexForId(srcid)),228 m_cc_global_id( cc_global_id),229 m_nline_width( vci_param::N - (uint32_log2(dcache_words)) - 2),230 m_itlb_ways( itlb_ways),231 m_itlb_sets( itlb_sets),232 m_dtlb_ways( dtlb_ways),233 m_dtlb_sets( dtlb_sets),234 m_icache_ways( icache_ways),235 m_icache_sets( icache_sets),236 m_icache_yzmask( (~0)<<(uint32_log2(icache_words) + 2)),237 m_icache_words( icache_words),238 m_dcache_ways( dcache_ways),239 m_dcache_sets( dcache_sets),240 m_dcache_yzmask( (~0)<<(uint32_log2(dcache_words) + 2)),241 m_dcache_words( dcache_words),242 m_x_width( x_width),243 m_y_width( y_width),244 m_proc_id( proc_id),245 m_max_frozen_cycles( max_frozen_cycles),246 m_paddr_nbits( vci_param::N),247 m_debug_start_cycle( debug_start_cycle),248 m_debug_ok( debug_ok),226 m_cacheability_table( mtd.getCacheabilityTable()), 227 m_srcid(mtd.indexForId(srcid)), 228 m_cc_global_id(cc_global_id), 229 m_nline_width(vci_param::N - (uint32_log2(dcache_words)) - 2), 230 m_itlb_ways(itlb_ways), 231 m_itlb_sets(itlb_sets), 232 m_dtlb_ways(dtlb_ways), 233 m_dtlb_sets(dtlb_sets), 234 m_icache_ways(icache_ways), 235 m_icache_sets(icache_sets), 236 m_icache_yzmask((~0) << (uint32_log2(icache_words) + 2)), 237 m_icache_words(icache_words), 238 m_dcache_ways(dcache_ways), 239 m_dcache_sets(dcache_sets), 240 m_dcache_yzmask((~0) << (uint32_log2(dcache_words) + 2)), 241 m_dcache_words(dcache_words), 242 m_x_width(x_width), 243 m_y_width(y_width), 244 m_proc_id(proc_id), 245 m_max_frozen_cycles(max_frozen_cycles), 246 m_paddr_nbits(vci_param::N), 247 m_debug_start_cycle(debug_start_cycle), 248 m_debug_ok(debug_ok), 249 249 m_dcache_paddr_ext_reset(0), 250 250 m_icache_paddr_ext_reset(0), … … 376 376 r_vci_rsp_ins_error("r_vci_rsp_ins_error"), 377 377 r_vci_rsp_data_error("r_vci_rsp_data_error"), 378 r_vci_rsp_fifo_icache("r_vci_rsp_fifo_icache", 2), 379 r_vci_rsp_fifo_dcache("r_vci_rsp_fifo_dcache", 2), 378 r_vci_rsp_fifo_icache("r_vci_rsp_fifo_icache", 2), // 2 words depth 379 r_vci_rsp_fifo_dcache("r_vci_rsp_fifo_dcache", 2), // 2 words depth 380 380 381 381 r_cc_send_fsm("r_cc_send_fsm"), … … 385 385 r_cc_receive_data_ins("r_cc_receive_data_ins"), 386 386 r_cc_receive_word_idx("r_cc_receive_word_idx"), 387 r_cc_receive_updt_fifo_be("r_cc_receive_updt_fifo_be", 2), 388 r_cc_receive_updt_fifo_data("r_cc_receive_updt_fifo_data", 2), 389 r_cc_receive_updt_fifo_eop("r_cc_receive_updt_fifo_eop", 2), 387 r_cc_receive_updt_fifo_be("r_cc_receive_updt_fifo_be", 2), // 2 words depth 388 r_cc_receive_updt_fifo_data("r_cc_receive_updt_fifo_data", 2), // 2 words depth 389 r_cc_receive_updt_fifo_eop("r_cc_receive_updt_fifo_eop", 2), // 2 words depth 390 390 391 391 r_cc_receive_icache_req("r_cc_receive_icache_req"), … … 412 412 std::cout << " - Building VciCcVcacheWrapper : " << name << std::endl; 413 413 414 assert( ((icache_words*vci_param::B) < (1<<vci_param::K)) and414 assert(((icache_words*vci_param::B) < (1 << vci_param::K)) and 415 415 "Need more PLEN bits."); 416 416 417 assert( (vci_param::T > 2) and ((1<<(vci_param::T-1)) >= (wbuf_nlines)) and417 assert((vci_param::T > 2) and ((1 << (vci_param::T - 1)) >= (wbuf_nlines)) and 418 418 "Need more TRDID bits."); 419 419 420 assert( 420 assert((icache_words == dcache_words) and 421 421 "icache_words and dcache_words parameters must be equal"); 422 422 423 assert( 423 assert((itlb_sets == dtlb_sets) and 424 424 "itlb_sets and dtlb_sets parameters must be etqual"); 425 425 426 assert( 426 assert((itlb_ways == dtlb_ways) and 427 427 "itlb_ways and dtlb_ways parameters must be etqual"); 428 428 429 r_mmu_params = (uint32_log2(m_dtlb_ways) << 29) 430 (uint32_log2(m_dcache_ways) << 22) 431 (uint32_log2(m_itlb_ways) << 15) 432 (uint32_log2(m_icache_ways) << 8) 433 (uint32_log2(m_icache_words <<2));434 435 r_mmu_release = (uint32_t) (1 << 16) | 0x1;436 437 r_dcache_in_tlb = new bool[dcache_ways *dcache_sets];438 r_dcache_contains_ptd = new bool[dcache_ways *dcache_sets];429 r_mmu_params = (uint32_log2(m_dtlb_ways) << 29) | (uint32_log2(m_dtlb_sets) << 25) | 430 (uint32_log2(m_dcache_ways) << 22) | (uint32_log2(m_dcache_sets) << 18) | 431 (uint32_log2(m_itlb_ways) << 15) | (uint32_log2(m_itlb_sets) << 11) | 432 (uint32_log2(m_icache_ways) << 8) | (uint32_log2(m_icache_sets) << 4) | 433 (uint32_log2(m_icache_words << 2)); 434 435 r_mmu_release = (uint32_t) (1 << 16) | 0x1; 436 437 r_dcache_in_tlb = new bool[dcache_ways * dcache_sets]; 438 r_dcache_contains_ptd = new bool[dcache_ways * dcache_sets]; 439 439 440 440 SC_METHOD(transition); … … 448 448 typename iss_t::CacheInfo cache_info; 449 449 cache_info.has_mmu = true; 450 cache_info.icache_line_size = icache_words *sizeof(uint32_t);450 cache_info.icache_line_size = icache_words * sizeof(uint32_t); 451 451 cache_info.icache_assoc = icache_ways; 452 452 cache_info.icache_n_lines = icache_sets; 453 cache_info.dcache_line_size = dcache_words *sizeof(uint32_t);453 cache_info.dcache_line_size = dcache_words * sizeof(uint32_t); 454 454 cache_info.dcache_assoc = dcache_ways; 455 455 cache_info.dcache_n_lines = dcache_sets; … … 500 500 << " | MMU = " << r_mmu_mode.read(); 501 501 502 if (r_dcache_updt_req.read() 503 if (r_dcache_wbuf_req.read() 502 if (r_dcache_updt_req.read()) std::cout << " | P1_UPDT"; 503 if (r_dcache_wbuf_req.read()) std::cout << " | P1_WBUF"; 504 504 std::cout << std::endl; 505 505 506 if (mode & 0x01)507 { 508 if ( r_icache_miss_req.read() )std::cout << " IMISS_REQ" << std::endl;509 if ( r_icache_unc_req.read() )std::cout << " IUNC_REQ" << std::endl;510 if ( r_dcache_vci_miss_req.read()) std::cout << " DMISS_REQ" << std::endl;511 if ( r_dcache_vci_unc_req.read() )std::cout << " DUNC_REQ" << std::endl;512 513 r_wbuf.printTrace((mode >>1)&1);514 } 515 if (mode & 0x02)506 if (mode & 0x01) 507 { 508 if (r_icache_miss_req.read()) std::cout << " IMISS_REQ" << std::endl; 509 if (r_icache_unc_req.read()) std::cout << " IUNC_REQ" << std::endl; 510 if (r_dcache_vci_miss_req.read()) std::cout << " DMISS_REQ" << std::endl; 511 if (r_dcache_vci_unc_req.read()) std::cout << " DUNC_REQ" << std::endl; 512 513 r_wbuf.printTrace((mode >> 1) & 1); 514 } 515 if (mode & 0x02) 516 516 { 517 517 r_iss.dump(); 518 518 } 519 if (mode & 0x04)519 if (mode & 0x04) 520 520 { 521 521 std::cout << " Data Cache" << std::endl; 522 522 r_dcache.printTrace(); 523 523 } 524 if (mode & 0x08)524 if (mode & 0x08) 525 525 { 526 526 std::cout << " Instruction Cache" << std::endl; 527 527 r_icache.printTrace(); 528 528 } 529 if (mode & 0x10)529 if (mode & 0x10) 530 530 { 531 531 std::cout << " Data TLB" << std::endl; 532 532 r_dtlb.printTrace(); 533 533 } 534 if (mode & 0x20)534 if (mode & 0x20) 535 535 { 536 536 std::cout << " Instruction TLB" << std::endl; 537 537 r_itlb.printTrace(); 538 538 } 539 if (mode & 0x40)540 { 541 uint32_t status = r_iss.debugGetRegisterValue( 32);539 if (mode & 0x40) 540 { 541 uint32_t status = r_iss.debugGetRegisterValue(32); 542 542 std::cout << name(); 543 if ( 543 if (status != m_previous_status ) std::cout << " NEW "; 544 544 std::cout << " status = " << std::hex << status << " " << std::endl; 545 545 m_previous_status = status; … … 548 548 549 549 ////////////////////////////////////////// 550 tmpl(void)::cache_monitor( paddr_t addr)550 tmpl(void)::cache_monitor(paddr_t addr) 551 551 ////////////////////////////////////////// 552 552 { 553 bool 554 size_t 555 size_t 556 size_t 557 uint32_t 558 559 cache_hit = r_dcache.read_neutral( 560 561 562 563 &cache_word);564 565 if ( cache_hit != m_debug_previous_d_hit)553 bool cache_hit; 554 size_t cache_way = 0; 555 size_t cache_set = 0; 556 size_t cache_word = 0; 557 uint32_t cache_rdata = 0; 558 559 cache_hit = r_dcache.read_neutral(addr, 560 &cache_rdata, 561 &cache_way, 562 &cache_set, 563 &cache_word); 564 565 if (cache_hit != m_debug_previous_d_hit) 566 566 { 567 567 std::cout << "Monitor PROC " << name() … … 571 571 << " / DATA = " << cache_rdata 572 572 << " / WAY = " << cache_way << std::endl; 573 574 } 575 576 cache_hit = r_icache.read_neutral( 577 578 579 580 &cache_word);581 582 if ( cache_hit != m_debug_previous_i_hit)573 m_debug_previous_d_hit = cache_hit; 574 } 575 576 cache_hit = r_icache.read_neutral(addr, 577 &cache_rdata, 578 &cache_way, 579 &cache_set, 580 &cache_word); 581 582 if (cache_hit != m_debug_previous_i_hit) 583 583 { 584 584 std::cout << "Monitor PROC " << name() … … 588 588 << " / DATA = " << cache_rdata 589 589 << " / WAY = " << cache_way << std::endl; 590 590 m_debug_previous_i_hit = cache_hit; 591 591 } 592 592 } … … 742 742 ///////////////////////// 743 743 { 744 if ( not p_resetn.read())744 if (not p_resetn.read()) 745 745 { 746 746 r_iss.reset(); … … 751 751 r_dtlb.reset(); 752 752 753 r_dcache_fsm 754 r_icache_fsm 755 r_vci_cmd_fsm 756 r_vci_rsp_fsm 757 r_cc_receive_fsm 758 r_cc_send_fsm 753 r_dcache_fsm = DCACHE_IDLE; 754 r_icache_fsm = ICACHE_IDLE; 755 r_vci_cmd_fsm = CMD_IDLE; 756 r_vci_rsp_fsm = RSP_IDLE; 757 r_cc_receive_fsm = CC_RECEIVE_IDLE; 758 r_cc_send_fsm = CC_SEND_IDLE; 759 759 760 760 // reset data physical address extension … … 765 765 766 766 // reset dcache directory extension 767 for (size_t i =0 ; i< m_dcache_ways*m_dcache_sets; i++)768 { 769 r_dcache_in_tlb[i] 767 for (size_t i = 0; i< m_dcache_ways * m_dcache_sets; i++) 768 { 769 r_dcache_in_tlb[i] = false; 770 770 r_dcache_contains_ptd[i] = false; 771 771 } … … 779 779 r_mmu_mode = 0x3; 780 780 781 781 // No request from ICACHE FSM to CMD FSM 782 782 r_icache_miss_req = false; 783 783 r_icache_unc_req = false; … … 807 807 808 808 // No request from DCACHE FSM to CC_SEND FSM 809 r_dcache_cc_send_req = false;809 r_dcache_cc_send_req = false; 810 810 r_dcache_cleanup_victim_req = false; 811 811 … … 836 836 m_debug_previous_i_hit = false; 837 837 m_debug_previous_d_hit = false; 838 m_debug_icache_fsm 839 m_debug_dcache_fsm 840 m_debug_cmd_fsm 838 m_debug_icache_fsm = false; 839 m_debug_dcache_fsm = false; 840 m_debug_cmd_fsm = false; 841 841 842 842 // activity counters … … 899 899 m_cost_data_tlb_occup_cache_frz = 0; 900 900 901 902 903 904 901 m_cpt_ins_tlb_inval = 0; 902 m_cpt_data_tlb_inval = 0; 903 m_cost_ins_tlb_inval_frz = 0; 904 m_cost_data_tlb_inval_frz = 0; 905 905 906 906 m_cpt_cc_broadcast = 0; 907 907 908 909 910 911 912 913 914 908 m_cost_updt_data_frz = 0; 909 m_cost_inval_ins_frz = 0; 910 m_cost_inval_data_frz = 0; 911 m_cost_broadcast_frz = 0; 912 913 m_cpt_cc_cleanup_data = 0; 914 m_cpt_cc_cleanup_ins = 0; 915 915 916 916 m_cpt_itlbmiss_transaction = 0; … … 933 933 /* 934 934 m_cpt_dcache_frz_cycles = 0; 935 m_cpt_read 936 m_cpt_write 937 938 939 935 m_cpt_read = 0; 936 m_cpt_write = 0; 937 m_cpt_cc_update_data = 0; 938 m_cpt_cc_inval_ins = 0; 939 m_cpt_cc_inval_data = 0; 940 940 */ 941 941 942 for (uint32_t i =0; i<32 ; ++i) m_cpt_fsm_icache [i]= 0;943 for (uint32_t i =0; i<32 ; ++i) m_cpt_fsm_dcache [i]= 0;944 for (uint32_t i =0; i<32 ; ++i) m_cpt_fsm_cmd [i]= 0;945 for (uint32_t i =0; i<32 ; ++i) m_cpt_fsm_rsp [i]= 0;942 for (uint32_t i = 0; i < 32; ++i) m_cpt_fsm_icache[i] = 0; 943 for (uint32_t i = 0; i < 32; ++i) m_cpt_fsm_dcache[i] = 0; 944 for (uint32_t i = 0; i < 32; ++i) m_cpt_fsm_cmd[i] = 0; 945 for (uint32_t i = 0; i < 32; ++i) m_cpt_fsm_rsp[i] = 0; 946 946 947 947 // init the llsc reservation buffer … … 953 953 954 954 // Response FIFOs default values 955 bool vci_rsp_fifo_icache_get= false;956 bool vci_rsp_fifo_icache_put= false;957 uint32_t vci_rsp_fifo_icache_data= 0;958 959 bool vci_rsp_fifo_dcache_get= false;960 bool vci_rsp_fifo_dcache_put= false;961 uint32_t vci_rsp_fifo_dcache_data= 0;955 bool vci_rsp_fifo_icache_get = false; 956 bool vci_rsp_fifo_icache_put = false; 957 uint32_t vci_rsp_fifo_icache_data = 0; 958 959 bool vci_rsp_fifo_dcache_get = false; 960 bool vci_rsp_fifo_dcache_put = false; 961 uint32_t vci_rsp_fifo_dcache_data = 0; 962 962 963 963 // updt fifo 964 bool 965 bool 966 uint32_t 967 uint32_t 968 bool 964 bool cc_receive_updt_fifo_get = false; 965 bool cc_receive_updt_fifo_put = false; 966 uint32_t cc_receive_updt_fifo_be = 0; 967 uint32_t cc_receive_updt_fifo_data = 0; 968 bool cc_receive_updt_fifo_eop = false; 969 969 970 970 #ifdef INSTRUMENTATION 971 m_cpt_fsm_dcache 972 m_cpt_fsm_icache 973 m_cpt_fsm_cmd 974 m_cpt_fsm_rsp 975 m_cpt_fsm_tgt 976 m_cpt_fsm_cleanup 971 m_cpt_fsm_dcache [r_dcache_fsm.read() ] ++; 972 m_cpt_fsm_icache [r_icache_fsm.read() ] ++; 973 m_cpt_fsm_cmd [r_vci_cmd_fsm.read()] ++; 974 m_cpt_fsm_rsp [r_vci_rsp_fsm.read()] ++; 975 m_cpt_fsm_tgt [r_tgt_fsm.read() ] ++; 976 m_cpt_fsm_cleanup[r_cleanup_cmd_fsm.read()] ++; 977 977 #endif 978 978 … … 1045 1045 1046 1046 // default value for m_irsp 1047 m_irsp.valid 1048 m_irsp.error 1047 m_irsp.valid = false; 1048 m_irsp.error = false; 1049 1049 m_irsp.instruction = 0; 1050 1050 1051 switch ( r_icache_fsm.read())1051 switch (r_icache_fsm.read()) 1052 1052 { 1053 1053 ///////////////// 1054 case ICACHE_IDLE: 1054 case ICACHE_IDLE: // In this state, we handle processor requests, XTN requests, 1055 1055 // and coherence requests with a fixed priority: 1056 1056 // 1/ Coherence requests => ICACHE_CC_CHECK … … 1061 1061 { 1062 1062 // coherence clack interrupt 1063 if ( r_icache_clack_req.read())1063 if (r_icache_clack_req.read()) 1064 1064 { 1065 1065 r_icache_fsm = ICACHE_CC_CHECK; … … 1069 1069 1070 1070 // coherence interrupt 1071 if ( 1071 if (r_cc_receive_icache_req.read() and not r_icache_cc_send_req.read()) 1072 1072 { 1073 1073 r_icache_fsm = ICACHE_CC_CHECK; … … 1079 1079 // These request are not executed in this IDLE state (except XTN_INST_PADDR_EXT), 1080 1080 // because they require access to icache or itlb, that are already accessed 1081 if ( r_dcache_xtn_req.read())1082 { 1083 if ( (int)r_dcache_xtn_opcode.read() == (int)iss_t::XTN_PTPR )1084 { 1085 r_icache_fsm 1086 } 1087 else if ( (int)r_dcache_xtn_opcode.read() == (int)iss_t::XTN_ICACHE_FLUSH)1081 if (r_dcache_xtn_req.read()) 1082 { 1083 if ((int) r_dcache_xtn_opcode.read() == (int) iss_t::XTN_PTPR ) 1084 { 1085 r_icache_fsm = ICACHE_XTN_TLB_FLUSH; 1086 } 1087 else if ((int) r_dcache_xtn_opcode.read() == (int) iss_t::XTN_ICACHE_FLUSH) 1088 1088 { 1089 1089 r_icache_flush_count = 0; 1090 r_icache_fsm 1091 } 1092 else if ( (int)r_dcache_xtn_opcode.read() == (int)iss_t::XTN_ITLB_INVAL)1093 { 1094 r_icache_fsm 1095 } 1096 else if ( (int)r_dcache_xtn_opcode.read() == (int)iss_t::XTN_ICACHE_INVAL)1097 { 1098 r_icache_fsm 1099 } 1100 else if ( (int)r_dcache_xtn_opcode.read() == (int)iss_t::XTN_MMU_ICACHE_PA_INV)1090 r_icache_fsm = ICACHE_XTN_CACHE_FLUSH; 1091 } 1092 else if ((int) r_dcache_xtn_opcode.read() == (int) iss_t::XTN_ITLB_INVAL) 1093 { 1094 r_icache_fsm = ICACHE_XTN_TLB_INVAL; 1095 } 1096 else if ((int) r_dcache_xtn_opcode.read() == (int) iss_t::XTN_ICACHE_INVAL) 1097 { 1098 r_icache_fsm = ICACHE_XTN_CACHE_INVAL_VA; 1099 } 1100 else if ((int) r_dcache_xtn_opcode.read() == (int) iss_t::XTN_MMU_ICACHE_PA_INV) 1101 1101 { 1102 1102 if (sizeof(paddr_t) <= 32) … … 1104 1104 assert(r_mmu_word_hi.read() == 0 && 1105 1105 "illegal XTN request in ICACHE: high bits should be 0 for 32bit paddr"); 1106 r_icache_vci_paddr = (paddr_t) r_mmu_word_lo.read();1106 r_icache_vci_paddr = (paddr_t) r_mmu_word_lo.read(); 1107 1107 } 1108 1108 else 1109 1109 { 1110 r_icache_vci_paddr = (paddr_t) r_mmu_word_hi.read() << 32 |1111 (paddr_t) r_mmu_word_lo.read();1110 r_icache_vci_paddr = (paddr_t) r_mmu_word_hi.read() << 32 | 1111 (paddr_t) r_mmu_word_lo.read(); 1112 1112 } 1113 1113 r_icache_fsm = ICACHE_XTN_CACHE_INVAL_PA; 1114 1114 } 1115 else if ( (int)r_dcache_xtn_opcode.read() == (int)iss_t::XTN_INST_PADDR_EXT)1115 else if ((int) r_dcache_xtn_opcode.read() == (int) iss_t::XTN_INST_PADDR_EXT) 1116 1116 { 1117 1117 r_icache_paddr_ext = r_dcache_save_wdata.read(); … … 1120 1120 else 1121 1121 { 1122 assert( 1122 assert(false and 1123 1123 "undefined XTN request received by ICACHE FSM"); 1124 1124 } … … 1127 1127 1128 1128 // processor request 1129 if ( 1130 { 1131 bool 1132 paddr_t 1133 bool 1134 pte_info_t 1135 size_t 1136 size_t 1137 paddr_t 1138 uint32_t 1139 size_t 1140 size_t 1141 size_t 1142 int 1129 if (m_ireq.valid ) 1130 { 1131 bool cacheable; 1132 paddr_t paddr; 1133 bool tlb_hit = false; 1134 pte_info_t tlb_flags; 1135 size_t tlb_way; 1136 size_t tlb_set; 1137 paddr_t tlb_nline; 1138 uint32_t cache_inst = 0; 1139 size_t cache_way; 1140 size_t cache_set; 1141 size_t cache_word; 1142 int cache_state = CACHE_SLOT_STATE_EMPTY; 1143 1143 1144 1144 // We register processor request … … 1147 1147 1148 1148 // sytematic itlb access (if activated) 1149 if ( r_mmu_mode.read() & INS_TLB_MASK)1149 if (r_mmu_mode.read() & INS_TLB_MASK) 1150 1150 { 1151 1151 1152 1152 #ifdef INSTRUMENTATION 1153 m_cpt_itlb_read++;1154 #endif 1155 tlb_hit = r_itlb.translate( 1156 1157 1158 1159 1160 &tlb_set );// unused1153 m_cpt_itlb_read++; 1154 #endif 1155 tlb_hit = r_itlb.translate(m_ireq.addr, 1156 &paddr, 1157 &tlb_flags, 1158 &tlb_nline, // unused 1159 &tlb_way, // unused 1160 &tlb_set); // unused 1161 1161 } 1162 1162 else if (vci_param::N > 32) … … 1166 1166 1167 1167 // systematic icache access (if activated) 1168 if ( r_mmu_mode.read() & INS_CACHE_MASK)1168 if (r_mmu_mode.read() & INS_CACHE_MASK) 1169 1169 { 1170 1170 1171 1171 1172 1172 #ifdef INSTRUMENTATION 1173 m_cpt_icache_data_read++;1174 m_cpt_icache_dir_read++;1175 #endif 1176 r_icache.read( 1177 1178 1179 1180 1181 &cache_state);1173 m_cpt_icache_data_read++; 1174 m_cpt_icache_dir_read++; 1175 #endif 1176 r_icache.read(paddr, 1177 &cache_inst, 1178 &cache_way, 1179 &cache_set, 1180 &cache_word, 1181 &cache_state); 1182 1182 } 1183 1183 … … 1188 1188 // and there is no access rights checking 1189 1189 1190 if ( not (r_mmu_mode.read() & INS_TLB_MASK) )// tlb not activated:1190 if (not (r_mmu_mode.read() & INS_TLB_MASK)) // tlb not activated: 1191 1191 { 1192 1192 // cacheability 1193 if ( not (r_mmu_mode.read() & INS_CACHE_MASK)) cacheable = false;1194 else cacheable = m_cacheability_table[(uint64_t)m_ireq.addr];1195 } 1196 else 1197 { 1198 if ( tlb_hit )// ITLB hit1193 if (not (r_mmu_mode.read() & INS_CACHE_MASK)) cacheable = false; 1194 else cacheable = m_cacheability_table[(uint64_t) m_ireq.addr]; 1195 } 1196 else // itlb activated 1197 { 1198 if (tlb_hit) // ITLB hit 1199 1199 { 1200 1200 // cacheability 1201 if ( not (r_mmu_mode.read() & INS_CACHE_MASK)) cacheable = false;1201 if (not (r_mmu_mode.read() & INS_CACHE_MASK)) cacheable = false; 1202 1202 else cacheable = tlb_flags.c; 1203 1203 1204 1204 // access rights checking 1205 if ( not tlb_flags.u && (m_ireq.mode == iss_t::MODE_USER))1205 if (not tlb_flags.u && (m_ireq.mode == iss_t::MODE_USER)) 1206 1206 { 1207 r_mmu_ietr 1208 r_mmu_ibvar 1209 m_irsp.valid 1210 m_irsp.error 1211 m_irsp.instruction 1207 r_mmu_ietr = MMU_READ_PRIVILEGE_VIOLATION; 1208 r_mmu_ibvar = m_ireq.addr; 1209 m_irsp.valid = true; 1210 m_irsp.error = true; 1211 m_irsp.instruction = 0; 1212 1212 break; 1213 1213 } 1214 else if ( not tlb_flags.x)1214 else if (not tlb_flags.x) 1215 1215 { 1216 r_mmu_ietr 1217 r_mmu_ibvar 1218 m_irsp.valid 1219 m_irsp.error 1220 m_irsp.instruction 1216 r_mmu_ietr = MMU_READ_EXEC_VIOLATION; 1217 r_mmu_ibvar = m_ireq.addr; 1218 m_irsp.valid = true; 1219 m_irsp.error = true; 1220 m_irsp.instruction = 0; 1221 1221 break; 1222 1222 } 1223 1223 } 1224 else 1224 else // ITLB miss 1225 1225 { 1226 1226 1227 1227 #ifdef INSTRUMENTATION 1228 m_cpt_itlb_miss++;1228 m_cpt_itlb_miss++; 1229 1229 #endif 1230 1230 r_icache_fsm = ICACHE_TLB_WAIT; … … 1235 1235 1236 1236 // physical address registration 1237 r_icache_vci_paddr 1237 r_icache_vci_paddr = paddr; 1238 1238 1239 1239 // Finally, we send the response to processor, and compute next state 1240 if ( cacheable)1241 { 1242 if (cache_state == CACHE_SLOT_STATE_EMPTY) 1240 if (cacheable) 1241 { 1242 if (cache_state == CACHE_SLOT_STATE_EMPTY) // cache miss 1243 1243 { 1244 1244 1245 1245 #ifdef INSTRUMENTATION 1246 m_cpt_icache_miss++;1246 m_cpt_icache_miss++; 1247 1247 #endif 1248 1248 // we request a VCI transaction 1249 r_icache_fsm 1249 r_icache_fsm = ICACHE_MISS_SELECT; 1250 1250 #if DEBUG_ICACHE 1251 if ( m_debug_icache_fsm)1252 std::cout << " <PROC " << name() << " ICACHE_IDLE> READ MISS in icache"1253 << " : PADDR = " << std::hex << paddr << std::endl;1251 if (m_debug_icache_fsm) 1252 std::cout << " <PROC " << name() << " ICACHE_IDLE> READ MISS in icache" 1253 << " : PADDR = " << std::hex << paddr << std::endl; 1254 1254 #endif 1255 1255 r_icache_miss_req = true; 1256 1256 } 1257 else if (cache_state == CACHE_SLOT_STATE_ZOMBI ) 1257 else if (cache_state == CACHE_SLOT_STATE_ZOMBI ) // pending cleanup 1258 1258 { 1259 1259 // stalled until cleanup is acknowledged 1260 r_icache_fsm 1260 r_icache_fsm = ICACHE_IDLE; 1261 1261 } 1262 else 1262 else // cache hit 1263 1263 { 1264 1264 1265 1265 #ifdef INSTRUMENTATION 1266 m_cpt_ins_read++;1266 m_cpt_ins_read++; 1267 1267 #endif 1268 1268 // return instruction to processor … … 1271 1271 r_icache_fsm = ICACHE_IDLE; 1272 1272 #if DEBUG_ICACHE 1273 if ( m_debug_icache_fsm)1274 std::cout << " <PROC " << name() << " ICACHE_IDLE> READ HIT in icache"1275 << " : PADDR = " << std::hex << paddr1276 << " / INST = " << cache_inst << std::endl;1273 if (m_debug_icache_fsm) 1274 std::cout << " <PROC " << name() << " ICACHE_IDLE> READ HIT in icache" 1275 << " : PADDR = " << std::hex << paddr 1276 << " / INST = " << cache_inst << std::endl; 1277 1277 #endif 1278 1278 } 1279 1279 } 1280 else 1281 { 1282 r_icache_unc_req 1283 r_icache_fsm 1280 else // non cacheable read 1281 { 1282 r_icache_unc_req = true; 1283 r_icache_fsm = ICACHE_UNC_WAIT; 1284 1284 1285 1285 #if DEBUG_ICACHE 1286 if ( m_debug_icache_fsm)1287 {1288 std::cout << " <PROC " << name()1289 << " ICACHE_IDLE> READ UNCACHEABLE in icache"1290 << " : PADDR = " << std::hex << paddr << std::endl;1291 }1286 if (m_debug_icache_fsm) 1287 { 1288 std::cout << " <PROC " << name() 1289 << " ICACHE_IDLE> READ UNCACHEABLE in icache" 1290 << " : PADDR = " << std::hex << paddr << std::endl; 1291 } 1292 1292 #endif 1293 1293 } … … 1296 1296 } 1297 1297 ///////////////////// 1298 case ICACHE_TLB_WAIT: 1298 case ICACHE_TLB_WAIT: // Waiting the itlb update by the DCACHE FSM after a tlb miss 1299 1299 // the itlb is udated by the DCACHE FSM, as well as the 1300 1300 // r_mmu_ietr and r_mmu_ibvar registers in case of error. … … 1304 1304 { 1305 1305 // coherence clack interrupt 1306 if ( r_icache_clack_req.read())1306 if (r_icache_clack_req.read()) 1307 1307 { 1308 1308 r_icache_fsm = ICACHE_CC_CHECK; … … 1312 1312 1313 1313 // coherence interrupt 1314 if ( 1314 if (r_cc_receive_icache_req.read() and not r_icache_cc_send_req.read()) 1315 1315 { 1316 1316 r_icache_fsm = ICACHE_CC_CHECK; … … 1319 1319 } 1320 1320 1321 if ( m_ireq.valid) m_cost_ins_tlb_miss_frz++;1321 if (m_ireq.valid) m_cost_ins_tlb_miss_frz++; 1322 1322 1323 1323 // DCACHE FSM signals response by reseting the request flip-flop 1324 if ( not r_icache_tlb_miss_req.read())1325 { 1326 if ( r_icache_tlb_rsp_error.read()) // error reported : tlb not updated1324 if (not r_icache_tlb_miss_req.read()) 1325 { 1326 if (r_icache_tlb_rsp_error.read()) // error reported : tlb not updated 1327 1327 { 1328 1328 r_icache_tlb_rsp_error = false; 1329 m_irsp.error 1330 m_irsp.valid 1331 r_icache_fsm 1332 } 1333 else 1329 m_irsp.error = true; 1330 m_irsp.valid = true; 1331 r_icache_fsm = ICACHE_IDLE; 1332 } 1333 else // tlb updated : return to IDLE state 1334 1334 { 1335 1335 r_icache_fsm = ICACHE_IDLE; … … 1339 1339 } 1340 1340 ////////////////////////// 1341 case ICACHE_XTN_TLB_FLUSH: 1341 case ICACHE_XTN_TLB_FLUSH: // invalidate in one cycle all non global TLB entries 1342 1342 { 1343 1343 r_itlb.flush(); 1344 r_dcache_xtn_req 1345 r_icache_fsm 1344 r_dcache_xtn_req = false; 1345 r_icache_fsm = ICACHE_IDLE; 1346 1346 break; 1347 1347 } 1348 1348 //////////////////////////// 1349 case ICACHE_XTN_CACHE_FLUSH: 1349 case ICACHE_XTN_CACHE_FLUSH: // Invalidate sequencially all cache lines, using 1350 1350 // r_icache_flush_count as a slot counter, 1351 1351 // looping in this state until all slots are visited. 1352 1352 // It can require two cycles per slot: 1353 1353 // We test here the slot state, and make the actual inval 1354 1354 // (if line is valid) in ICACHE_XTN_CACHE_FLUSH_GO state. 1355 1355 // A cleanup request is generated for each valid line 1356 1356 { 1357 1357 // coherence clack interrupt 1358 if ( r_icache_clack_req.read())1358 if (r_icache_clack_req.read()) 1359 1359 { 1360 1360 r_icache_fsm = ICACHE_CC_CHECK; … … 1364 1364 1365 1365 // coherence request (from CC_RECEIVE FSM) 1366 if ( 1366 if (r_cc_receive_icache_req.read() and not r_icache_cc_send_req.read()) 1367 1367 { 1368 1368 r_icache_fsm = ICACHE_CC_CHECK; … … 1371 1371 } 1372 1372 1373 if ( not r_icache_cc_send_req.read()) // blocked until previous cc_send request is sent1374 { 1375 int 1376 paddr_t 1377 size_t 1378 size_t 1373 if (not r_icache_cc_send_req.read()) // blocked until previous cc_send request is sent 1374 { 1375 int state; 1376 paddr_t tag; 1377 size_t way = r_icache_flush_count.read()/m_icache_sets; 1378 size_t set = r_icache_flush_count.read()%m_icache_sets; 1379 1379 1380 1380 #ifdef INSTRUMENTATION 1381 m_cpt_icache_dir_read++;1382 #endif 1383 r_icache.read_dir( 1384 1385 1386 &state);1387 1388 if ( state == CACHE_SLOT_STATE_VALID) // inval required1381 m_cpt_icache_dir_read++; 1382 #endif 1383 r_icache.read_dir(way, 1384 set, 1385 &tag, 1386 &state); 1387 1388 if (state == CACHE_SLOT_STATE_VALID) // inval required 1389 1389 { 1390 1390 // request cleanup … … 1395 1395 1396 1396 // goes to ICACHE_XTN_CACHE_FLUSH_GO to make inval 1397 r_icache_miss_way 1398 r_icache_miss_set 1399 r_icache_fsm 1400 } 1401 else if ( 1402 (m_icache_sets*m_icache_ways - 1) 1403 { 1404 1405 m_drsp.valid 1406 r_icache_fsm= ICACHE_IDLE;1397 r_icache_miss_way = way; 1398 r_icache_miss_set = set; 1399 r_icache_fsm = ICACHE_XTN_CACHE_FLUSH_GO; 1400 } 1401 else if (r_icache_flush_count.read() == 1402 (m_icache_sets*m_icache_ways - 1)) // last slot 1403 { 1404 r_dcache_xtn_req = false; 1405 m_drsp.valid = true; 1406 r_icache_fsm = ICACHE_IDLE; 1407 1407 } 1408 1408 1409 1409 // saturation counter, to have the same last slot condition 1410 1410 // in ICACHE_XTN_CACHE_FLUSH and ICACHE_XTN_CACHE_FLUSH_GO states 1411 if ( r_icache_flush_count.read() < (m_icache_sets*m_icache_ways - 1))1411 if (r_icache_flush_count.read() < (m_icache_sets * m_icache_ways - 1)) 1412 1412 { 1413 1413 r_icache_flush_count = r_icache_flush_count.read() + 1; … … 1417 1417 } 1418 1418 /////////////////////////////// 1419 case ICACHE_XTN_CACHE_FLUSH_GO: 1420 { 1421 size_t 1422 size_t 1419 case ICACHE_XTN_CACHE_FLUSH_GO: // Switch slot state to ZOMBI for an XTN flush 1420 { 1421 size_t way = r_icache_miss_way.read(); 1422 size_t set = r_icache_miss_set.read(); 1423 1423 1424 1424 #ifdef INSTRUMENTATION 1425 m_cpt_icache_dir_write++;1426 #endif 1427 1428 r_icache.write_dir( 1429 1430 CACHE_SLOT_STATE_ZOMBI);1431 1432 if ( 1433 (m_icache_sets*m_icache_ways - 1) 1434 { 1435 1436 m_drsp.valid 1437 r_icache_fsm= ICACHE_IDLE;1425 m_cpt_icache_dir_write++; 1426 #endif 1427 1428 r_icache.write_dir(way, 1429 set, 1430 CACHE_SLOT_STATE_ZOMBI); 1431 1432 if (r_icache_flush_count.read() == 1433 (m_icache_sets*m_icache_ways - 1)) // last slot 1434 { 1435 r_dcache_xtn_req = false; 1436 m_drsp.valid = true; 1437 r_icache_fsm = ICACHE_IDLE; 1438 1438 } 1439 1439 else 1440 1440 { 1441 r_icache_fsm 1441 r_icache_fsm = ICACHE_XTN_CACHE_FLUSH; 1442 1442 } 1443 1443 break; … … 1445 1445 1446 1446 ////////////////////////// 1447 case ICACHE_XTN_TLB_INVAL: 1448 1447 case ICACHE_XTN_TLB_INVAL: // invalidate one TLB entry selected by the virtual address 1448 // stored in the r_dcache_save_wdata register 1449 1449 { 1450 1450 r_itlb.inval(r_dcache_save_wdata.read()); 1451 r_dcache_xtn_req 1452 r_icache_fsm 1451 r_dcache_xtn_req = false; 1452 r_icache_fsm = ICACHE_IDLE; 1453 1453 break; 1454 1454 } 1455 1455 /////////////////////////////// 1456 case ICACHE_XTN_CACHE_INVAL_VA: 1456 case ICACHE_XTN_CACHE_INVAL_VA: // Selective cache line invalidate with virtual address 1457 1457 // requires 3 cycles (in case of hit on itlb and icache). 1458 1459 1460 { 1461 paddr_t 1462 bool 1458 // In this state, access TLB to translate virtual address 1459 // stored in the r_dcache_save_wdata register. 1460 { 1461 paddr_t paddr; 1462 bool hit; 1463 1463 1464 1464 // read physical address in TLB when MMU activated 1465 if ( r_mmu_mode.read() & INS_TLB_MASK )// itlb activated1465 if (r_mmu_mode.read() & INS_TLB_MASK) // itlb activated 1466 1466 { 1467 1467 1468 1468 #ifdef INSTRUMENTATION 1469 m_cpt_itlb_read++; 1470 #endif 1471 hit = r_itlb.translate(r_dcache_save_wdata.read(), 1472 &paddr); 1473 } 1474 else // itlb not activated 1475 { 1476 paddr = (paddr_t)r_dcache_save_wdata.read(); 1477 hit = true; 1478 } 1479 1480 if ( hit ) // continue the selective inval process 1481 { 1482 r_icache_vci_paddr = paddr; 1483 r_icache_fsm = ICACHE_XTN_CACHE_INVAL_PA; 1484 } 1485 else // miss : send a request to DCACHE FSM 1469 m_cpt_itlb_read++; 1470 #endif 1471 hit = r_itlb.translate(r_dcache_save_wdata.read(), &paddr); 1472 } 1473 else // itlb not activated 1474 { 1475 paddr = (paddr_t) r_dcache_save_wdata.read(); 1476 hit = true; 1477 } 1478 1479 if (hit) // continue the selective inval process 1480 { 1481 r_icache_vci_paddr = paddr; 1482 r_icache_fsm = ICACHE_XTN_CACHE_INVAL_PA; 1483 } 1484 else // miss : send a request to DCACHE FSM 1486 1485 { 1487 1486 1488 1487 #ifdef INSTRUMENTATION 1489 m_cpt_itlb_miss++;1488 m_cpt_itlb_miss++; 1490 1489 #endif 1491 1490 r_icache_tlb_miss_req = true; 1492 1491 r_icache_vaddr_save = r_dcache_save_wdata.read(); 1493 1492 r_icache_fsm = ICACHE_TLB_WAIT; 1494 1493 } … … 1496 1495 } 1497 1496 /////////////////////////////// 1498 case ICACHE_XTN_CACHE_INVAL_PA: 1497 case ICACHE_XTN_CACHE_INVAL_PA: // selective invalidate cache line with physical address 1499 1498 // require 2 cycles. In this state, we read directory 1500 1499 // with address stored in r_icache_vci_paddr register. 1501 1500 { 1502 int 1503 size_t 1504 size_t 1505 size_t 1501 int state; 1502 size_t way; 1503 size_t set; 1504 size_t word; 1506 1505 1507 1506 #ifdef INSTRUMENTATION 1508 m_cpt_icache_dir_read++;1507 m_cpt_icache_dir_read++; 1509 1508 #endif 1510 1509 r_icache.read_dir(r_icache_vci_paddr.read(), … … 1514 1513 &word); 1515 1514 1516 if ( state == CACHE_SLOT_STATE_VALID )// inval to be done1515 if (state == CACHE_SLOT_STATE_VALID) // inval to be done 1517 1516 { 1518 1517 r_icache_miss_way = way; … … 1520 1519 r_icache_fsm = ICACHE_XTN_CACHE_INVAL_GO; 1521 1520 } 1522 else 1521 else // miss : acknowlege the XTN request and return 1523 1522 { 1524 1523 r_dcache_xtn_req = false; … … 1530 1529 case ICACHE_XTN_CACHE_INVAL_GO: // Switch slot to ZOMBI state for an XTN inval 1531 1530 { 1532 if ( not r_icache_cc_send_req.read()) // blocked until previous cc_send request not sent1531 if (not r_icache_cc_send_req.read()) // blocked until previous cc_send request not sent 1533 1532 { 1534 1533 1535 1534 #ifdef INSTRUMENTATION 1536 m_cpt_icache_dir_write++;1537 #endif 1538 r_icache.write_dir( 1539 1540 CACHE_SLOT_STATE_ZOMBI);1535 m_cpt_icache_dir_write++; 1536 #endif 1537 r_icache.write_dir(r_icache_miss_way.read(), 1538 r_icache_miss_set.read(), 1539 CACHE_SLOT_STATE_ZOMBI); 1541 1540 1542 1541 // request cleanup 1543 1542 r_icache_cc_send_req = true; 1544 r_icache_cc_send_nline = r_icache_vci_paddr.read() / (m_icache_words <<2);1543 r_icache_cc_send_nline = r_icache_vci_paddr.read() / (m_icache_words << 2); 1545 1544 r_icache_cc_send_way = r_icache_miss_way.read(); 1546 1545 r_icache_cc_send_type = CC_TYPE_CLEANUP; 1547 1546 1548 1547 // acknowledge the XTN request and return 1549 r_dcache_xtn_req 1550 r_icache_fsm 1548 r_dcache_xtn_req = false; 1549 r_icache_fsm = ICACHE_IDLE; 1551 1550 } 1552 1551 break; … … 1566 1565 1567 1566 // coherence clack interrupt 1568 if ( r_icache_clack_req.read())1567 if (r_icache_clack_req.read()) 1569 1568 { 1570 1569 r_icache_fsm = ICACHE_CC_CHECK; … … 1574 1573 1575 1574 // coherence interrupt 1576 if ( 1575 if (r_cc_receive_icache_req.read() and not r_icache_cc_send_req.read()) 1577 1576 { 1578 1577 r_icache_fsm = ICACHE_CC_CHECK; … … 1582 1581 1583 1582 1584 bool 1585 bool 1586 size_t 1587 size_t 1588 paddr_t 1583 bool found; 1584 bool cleanup; 1585 size_t way; 1586 size_t set; 1587 paddr_t victim; 1589 1588 1590 1589 #ifdef INSTRUMENTATION 1591 m_cpt_icache_dir_read++;1590 m_cpt_icache_dir_read++; 1592 1591 #endif 1593 1592 r_icache.read_select(r_icache_vci_paddr.read(), … … 1596 1595 &set, 1597 1596 &found, 1598 &cleanup 1599 if ( not found)1597 &cleanup); 1598 if (not found) 1600 1599 { 1601 1600 break; … … 1603 1602 else 1604 1603 { 1605 r_icache_miss_way 1606 r_icache_miss_set 1607 1608 if ( cleanup)1609 { 1610 if ( not r_icache_cc_send_req.read())1604 r_icache_miss_way = way; 1605 r_icache_miss_set = set; 1606 1607 if (cleanup) 1608 { 1609 if (not r_icache_cc_send_req.read()) 1611 1610 { 1612 r_icache_cc_send_req 1613 r_icache_cc_send_nline 1614 r_icache_cc_send_way 1615 r_icache_cc_send_type 1611 r_icache_cc_send_req = true; 1612 r_icache_cc_send_nline = victim; 1613 r_icache_cc_send_way = way; 1614 r_icache_cc_send_type = CC_TYPE_CLEANUP; 1616 1615 } 1617 1616 else … … 1621 1620 } 1622 1621 1623 r_icache_miss_clack 1624 r_icache_fsm 1622 r_icache_miss_clack = true; 1623 r_icache_fsm = ICACHE_MISS_CLEAN; 1625 1624 } 1626 1625 else 1627 1626 { 1628 r_icache_fsm 1627 r_icache_fsm = ICACHE_MISS_WAIT; 1629 1628 } 1630 1629 1631 1630 #if DEBUG_ICACHE 1632 if ( m_debug_icache_fsm)1633 {1634 std::cout << " <PROC " << name()1635 << " ICACHE_MISS_SELECT> Select a slot:" << std::dec1636 << " / WAY = " << way1637 << " / SET = " << set;1638 if (cleanup) std::cout << " / VICTIM = " << std::hex << victim << std::endl;1639 else std::cout << std::endl;1640 }1631 if (m_debug_icache_fsm) 1632 { 1633 std::cout << " <PROC " << name() 1634 << " ICACHE_MISS_SELECT> Select a slot:" << std::dec 1635 << " / WAY = " << way 1636 << " / SET = " << set; 1637 if (cleanup) std::cout << " / VICTIM = " << std::hex << victim << std::endl; 1638 else std::cout << std::endl; 1639 } 1641 1640 #endif 1642 1641 } … … 1644 1643 } 1645 1644 /////////////////////// 1646 case ICACHE_MISS_CLEAN: 1645 case ICACHE_MISS_CLEAN: // switch the slot to zombi state 1647 1646 { 1648 1647 if (m_ireq.valid) m_cost_ins_miss_frz++; 1649 1648 1650 1649 #ifdef INSTRUMENTATION 1651 m_cpt_icache_dir_write++;1652 #endif 1653 r_icache.write_dir( 1654 1655 1650 m_cpt_icache_dir_write++; 1651 #endif 1652 r_icache.write_dir(r_icache_miss_way.read(), 1653 r_icache_miss_set.read(), 1654 CACHE_SLOT_STATE_ZOMBI); 1656 1655 #if DEBUG_ICACHE 1657 if ( m_debug_icache_fsm)1658 {1659 std::cout << " <PROC " << name()1660 << " ICACHE_MISS_CLEAN> Switch to ZOMBI state" << std::dec1661 << " / WAY = " << r_icache_miss_way.read()1662 << " / SET = " << r_icache_miss_set.read() << std::endl;1663 }1656 if (m_debug_icache_fsm) 1657 { 1658 std::cout << " <PROC " << name() 1659 << " ICACHE_MISS_CLEAN> Switch to ZOMBI state" << std::dec 1660 << " / WAY = " << r_icache_miss_way.read() 1661 << " / SET = " << r_icache_miss_set.read() << std::endl; 1662 } 1664 1663 #endif 1665 1664 … … 1668 1667 } 1669 1668 ////////////////////// 1670 case ICACHE_MISS_WAIT: 1669 case ICACHE_MISS_WAIT: // waiting response from VCI_RSP FSM 1671 1670 { 1672 1671 if (m_ireq.valid) m_cost_ins_miss_frz++; 1673 1672 1674 1673 // send cleanup victim request 1675 if ( r_icache_cleanup_victim_req.read() and not r_icache_cc_send_req.read())1674 if (r_icache_cleanup_victim_req.read() and not r_icache_cc_send_req.read()) 1676 1675 { 1677 1676 r_icache_cc_send_req = true; … … 1683 1682 1684 1683 // coherence clack interrupt 1685 if ( r_icache_clack_req.read())1684 if (r_icache_clack_req.read()) 1686 1685 { 1687 1686 r_icache_fsm = ICACHE_CC_CHECK; … … 1691 1690 1692 1691 // coherence interrupt 1693 if ( r_cc_receive_icache_req.read() and not r_icache_cc_send_req.read() and not r_icache_cleanup_victim_req.read())1692 if (r_cc_receive_icache_req.read() and not r_icache_cc_send_req.read() and not r_icache_cleanup_victim_req.read()) 1694 1693 { 1695 1694 r_icache_fsm = ICACHE_CC_CHECK; … … 1698 1697 } 1699 1698 1700 if ( r_vci_rsp_ins_error.read()) // bus error1699 if (r_vci_rsp_ins_error.read()) // bus error 1701 1700 { 1702 1701 r_mmu_ietr = MMU_READ_DATA_ILLEGAL_ACCESS; … … 1707 1706 r_icache_fsm = ICACHE_IDLE; 1708 1707 } 1709 else if ( r_vci_rsp_fifo_icache.rok()) // response available1708 else if (r_vci_rsp_fifo_icache.rok()) // response available 1710 1709 { 1711 1710 r_icache_miss_word = 0; … … 1715 1714 } 1716 1715 /////////////////////////// 1717 case ICACHE_MISS_DATA_UPDT: 1718 { 1719 if ( m_ireq.valid) m_cost_ins_miss_frz++;1720 1721 if ( r_vci_rsp_fifo_icache.rok() )// response available1716 case ICACHE_MISS_DATA_UPDT: // update the cache (one word per cycle) 1717 { 1718 if (m_ireq.valid) m_cost_ins_miss_frz++; 1719 1720 if (r_vci_rsp_fifo_icache.rok()) // response available 1722 1721 { 1723 1722 1724 1723 #ifdef INSTRUMENTATION 1725 m_cpt_icache_data_write++;1726 #endif 1727 r_icache.write( 1728 1729 1730 r_vci_rsp_fifo_icache.read());1724 m_cpt_icache_data_write++; 1725 #endif 1726 r_icache.write(r_icache_miss_way.read(), 1727 r_icache_miss_set.read(), 1728 r_icache_miss_word.read(), 1729 r_vci_rsp_fifo_icache.read()); 1731 1730 #if DEBUG_ICACHE 1732 if ( m_debug_icache_fsm)1733 {1734 std::cout << " <PROC " << name()1735 << " ICACHE_MISS_DATA_UPDT> Write one word:"1736 << " WDATA = " << std::hex << r_vci_rsp_fifo_icache.read()1737 << " WAY = " << r_icache_miss_way.read()1738 << " SET = " << r_icache_miss_set.read()1739 << " WORD = " << r_icache_miss_word.read() << std::endl;1740 }1731 if (m_debug_icache_fsm) 1732 { 1733 std::cout << " <PROC " << name() 1734 << " ICACHE_MISS_DATA_UPDT> Write one word:" 1735 << " WDATA = " << std::hex << r_vci_rsp_fifo_icache.read() 1736 << " WAY = " << r_icache_miss_way.read() 1737 << " SET = " << r_icache_miss_set.read() 1738 << " WORD = " << r_icache_miss_word.read() << std::endl; 1739 } 1741 1740 #endif 1742 1741 vci_rsp_fifo_icache_get = true; 1743 1742 r_icache_miss_word = r_icache_miss_word.read() + 1; 1744 1743 1745 if ( r_icache_miss_word.read() == m_icache_words-1 )// last word1744 if (r_icache_miss_word.read() == m_icache_words - 1) // last word 1746 1745 { 1747 1746 r_icache_fsm = ICACHE_MISS_DIR_UPDT; … … 1751 1750 } 1752 1751 ////////////////////////// 1753 case ICACHE_MISS_DIR_UPDT: 1752 case ICACHE_MISS_DIR_UPDT: // Stalled if a victim line has been evicted, 1754 1753 // and the cleanup ack has not been received, 1755 1754 // as indicated by r_icache_miss_clack. … … 1759 1758 // to ZOMBI state, and send a cleanup request. 1760 1759 { 1761 if ( 1760 if (m_ireq.valid ) m_cost_ins_miss_frz++; 1762 1761 1763 1762 // send cleanup victim request 1764 if ( r_icache_cleanup_victim_req.read() and not r_icache_cc_send_req.read())1763 if (r_icache_cleanup_victim_req.read() and not r_icache_cc_send_req.read()) 1765 1764 { 1766 1765 r_icache_cc_send_req = true; … … 1772 1771 1773 1772 // coherence clack interrupt 1774 if ( r_icache_clack_req.read())1773 if (r_icache_clack_req.read()) 1775 1774 { 1776 1775 r_icache_fsm = ICACHE_CC_CHECK; … … 1780 1779 1781 1780 // coherence interrupt 1782 if ( r_cc_receive_icache_req.read() and not r_icache_cc_send_req.read() and not r_icache_cleanup_victim_req.read())1781 if (r_cc_receive_icache_req.read() and not r_icache_cc_send_req.read() and not r_icache_cleanup_victim_req.read()) 1783 1782 { 1784 1783 r_icache_fsm = ICACHE_CC_CHECK; … … 1787 1786 } 1788 1787 1789 if ( not r_icache_miss_clack.read()) // waiting cleanup acknowledge for victim line1790 { 1791 if ( r_icache_miss_inval )// Switch slot to ZOMBI state, and new cleanup1792 { 1793 if ( not r_icache_cc_send_req.read())1788 if (not r_icache_miss_clack.read()) // waiting cleanup acknowledge for victim line 1789 { 1790 if (r_icache_miss_inval) // Switch slot to ZOMBI state, and new cleanup 1791 { 1792 if (not r_icache_cc_send_req.read()) 1794 1793 { 1795 1794 r_icache_miss_inval = false; 1796 1795 // request cleanup 1797 1796 r_icache_cc_send_req = true; 1798 r_icache_cc_send_nline = r_icache_vci_paddr.read() / (m_icache_words <<2);1797 r_icache_cc_send_nline = r_icache_vci_paddr.read() / (m_icache_words << 2); 1799 1798 r_icache_cc_send_way = r_icache_miss_way.read(); 1800 1799 r_icache_cc_send_type = CC_TYPE_CLEANUP; 1801 1800 1802 1801 #ifdef INSTRUMENTATION 1803 m_cpt_icache_dir_write++;1804 #endif 1805 r_icache.write_dir( 1806 1807 1808 CACHE_SLOT_STATE_ZOMBI);1802 m_cpt_icache_dir_write++; 1803 #endif 1804 r_icache.write_dir(r_icache_vci_paddr.read(), 1805 r_icache_miss_way.read(), 1806 r_icache_miss_set.read(), 1807 CACHE_SLOT_STATE_ZOMBI); 1809 1808 #if DEBUG_ICACHE 1810 if ( m_debug_icache_fsm)1811 {1812 std::cout << " <PROC " << name()1813 << " ICACHE_MISS_DIR_UPDT> Switch cache slot to ZOMBI state"1814 << " PADDR = " << std::hex << r_icache_vci_paddr.read()1815 << " WAY = " << std::dec << r_icache_miss_way.read()1816 << " SET = " << r_icache_miss_set.read() << std::endl;1817 }1809 if (m_debug_icache_fsm) 1810 { 1811 std::cout << " <PROC " << name() 1812 << " ICACHE_MISS_DIR_UPDT> Switch cache slot to ZOMBI state" 1813 << " PADDR = " << std::hex << r_icache_vci_paddr.read() 1814 << " WAY = " << std::dec << r_icache_miss_way.read() 1815 << " SET = " << r_icache_miss_set.read() << std::endl; 1816 } 1818 1817 #endif 1819 1818 } … … 1821 1820 break; 1822 1821 } 1823 else 1822 else // Switch slot to VALID state 1824 1823 { 1825 1824 1826 1825 #ifdef INSTRUMENTATION 1827 m_cpt_icache_dir_write++;1828 #endif 1829 r_icache.write_dir( 1830 1831 1832 CACHE_SLOT_STATE_VALID);1826 m_cpt_icache_dir_write++; 1827 #endif 1828 r_icache.write_dir(r_icache_vci_paddr.read(), 1829 r_icache_miss_way.read(), 1830 r_icache_miss_set.read(), 1831 CACHE_SLOT_STATE_VALID); 1833 1832 #if DEBUG_ICACHE 1834 if ( m_debug_icache_fsm)1835 {1836 std::cout << " <PROC " << name()1837 << " ICACHE_MISS_DIR_UPDT> Switch cache slot to VALID state"1838 << " PADDR = " << std::hex << r_icache_vci_paddr.read()1839 << " WAY = " << std::dec << r_icache_miss_way.read()1840 << " SET = " << r_icache_miss_set.read() << std::endl;1841 }1833 if (m_debug_icache_fsm) 1834 { 1835 std::cout << " <PROC " << name() 1836 << " ICACHE_MISS_DIR_UPDT> Switch cache slot to VALID state" 1837 << " PADDR = " << std::hex << r_icache_vci_paddr.read() 1838 << " WAY = " << std::dec << r_icache_miss_way.read() 1839 << " SET = " << r_icache_miss_set.read() << std::endl; 1840 } 1842 1841 #endif 1843 1842 } … … 1848 1847 } 1849 1848 //////////////////// 1850 case ICACHE_UNC_WAIT: 1849 case ICACHE_UNC_WAIT: // waiting a response to an uncacheable read from VCI_RSP FSM 1851 1850 { 1852 1851 // coherence clack interrupt 1853 if ( r_icache_clack_req.read())1854 { 1855 r_icache_fsm = ICACHE_CC_CHECK;1852 if (r_icache_clack_req.read()) 1853 { 1854 r_icache_fsm = ICACHE_CC_CHECK; 1856 1855 r_icache_fsm_save = r_icache_fsm.read(); 1857 1856 break; … … 1859 1858 1860 1859 // coherence interrupt 1861 if ( 1862 { 1863 r_icache_fsm = ICACHE_CC_CHECK;1860 if (r_cc_receive_icache_req.read() and not r_icache_cc_send_req.read()) 1861 { 1862 r_icache_fsm = ICACHE_CC_CHECK; 1864 1863 r_icache_fsm_save = r_icache_fsm.read(); 1865 1864 break; 1866 1865 } 1867 1866 1868 if ( r_vci_rsp_ins_error.read()) // bus error1867 if (r_vci_rsp_ins_error.read()) // bus error 1869 1868 { 1870 1869 r_mmu_ietr = MMU_READ_DATA_ILLEGAL_ACCESS; … … 1875 1874 r_icache_fsm = ICACHE_IDLE; 1876 1875 } 1877 else if (r_vci_rsp_fifo_icache.rok() 1876 else if (r_vci_rsp_fifo_icache.rok()) // instruction available 1878 1877 { 1879 1878 vci_rsp_fifo_icache_get = true; 1880 1879 r_icache_fsm = ICACHE_IDLE; 1881 if ( 1882 (m_ireq.addr == r_icache_vaddr_save.read()) 1880 if (m_ireq.valid and 1881 (m_ireq.addr == r_icache_vaddr_save.read())) // request unmodified 1883 1882 { 1884 1883 m_irsp.valid = true; … … 1889 1888 } 1890 1889 ///////////////////// 1891 case ICACHE_CC_CHECK: 1892 1893 1894 1895 1896 { 1897 paddr_t 1898 paddr_t mask = ~((m_icache_words<<2)-1);1890 case ICACHE_CC_CHECK: // This state is the entry point of a sub-fsm 1891 // handling coherence requests. 1892 // if there is a matching pending miss, it is 1893 // signaled in the r_icache_miss_inval flip-flop. 1894 // The return state is defined in r_icache_fsm_save. 1895 { 1896 paddr_t paddr = r_cc_receive_icache_nline.read() * m_icache_words * 4; 1897 paddr_t mask = ~((m_icache_words << 2) - 1); 1899 1898 1900 1899 // CLACK handler … … 1902 1901 // and reset r_icache_miss_clack if the cleanup ack 1903 1902 // is matching a pending miss. 1904 if ( r_icache_clack_req.read())1905 { 1906 1907 if ( m_ireq.valid) m_cost_ins_miss_frz++;1903 if (r_icache_clack_req.read()) 1904 { 1905 1906 if (m_ireq.valid) m_cost_ins_miss_frz++; 1908 1907 1909 1908 #ifdef INSTRUMENTATION 1910 m_cpt_icache_dir_write++;1911 #endif 1912 r_icache.write_dir( 1913 1914 1915 1916 1917 if ( 1918 (r_icache_miss_way.read() == r_icache_clack_way.read()) 1909 m_cpt_icache_dir_write++; 1910 #endif 1911 r_icache.write_dir(0, 1912 r_icache_clack_way.read(), 1913 r_icache_clack_set.read(), 1914 CACHE_SLOT_STATE_EMPTY); 1915 1916 if ((r_icache_miss_set.read() == r_icache_clack_set.read()) and 1917 (r_icache_miss_way.read() == r_icache_clack_way.read())) 1919 1918 { 1920 1919 r_icache_miss_clack = false; … … 1927 1926 1928 1927 #if DEBUG_ICACHE 1929 if ( m_debug_icache_fsm)1930 {1931 std::cout << " <PROC " << name()1932 << " ICACHE_CC_CHECK> CC_TYPE_CLACK slot returns to empty state"1933 << " set = " << r_icache_clack_set.read()1934 << " / way = " << r_icache_clack_way.read() << std::endl;1935 }1936 #endif 1937 1938 break; 1939 } 1940 1941 assert (not r_icache_cc_send_req.read() and "CC_SEND must be available in ICACHE_CC_CHECK");1928 if (m_debug_icache_fsm) 1929 { 1930 std::cout << " <PROC " << name() 1931 << " ICACHE_CC_CHECK> CC_TYPE_CLACK slot returns to empty state" 1932 << " set = " << r_icache_clack_set.read() 1933 << " / way = " << r_icache_clack_way.read() << std::endl; 1934 } 1935 #endif 1936 1937 break; 1938 } 1939 1940 assert(not r_icache_cc_send_req.read() and "CC_SEND must be available in ICACHE_CC_CHECK"); 1942 1941 1943 1942 // Match between MISS address and CC address 1944 1943 if (r_cc_receive_icache_req.read() and 1945 ((r_icache_fsm_save.read() == ICACHE_MISS_SELECT 1946 (r_icache_fsm_save.read() == ICACHE_MISS_WAIT 1944 ((r_icache_fsm_save.read() == ICACHE_MISS_SELECT) or 1945 (r_icache_fsm_save.read() == ICACHE_MISS_WAIT) or 1947 1946 (r_icache_fsm_save.read() == ICACHE_MISS_DIR_UPDT)) and 1948 ((r_icache_vci_paddr.read() & mask) == (paddr & mask)) 1947 ((r_icache_vci_paddr.read() & mask) == (paddr & mask))) // matching 1949 1948 { 1950 1949 // signaling the matching 1951 r_icache_miss_inval 1950 r_icache_miss_inval = true; 1952 1951 1953 1952 // in case of update, go to CC_UPDT … … 1955 1954 if (r_cc_receive_icache_type.read() == CC_TYPE_UPDT) 1956 1955 { 1957 r_icache_fsm 1958 r_icache_cc_word 1956 r_icache_fsm = ICACHE_CC_UPDT; 1957 r_icache_cc_word = r_cc_receive_word_idx.read(); 1959 1958 1960 1959 // just pop the fifo , don't write in icache … … 1965 1964 { 1966 1965 r_cc_receive_icache_req = false; 1967 r_icache_fsm 1966 r_icache_fsm = r_icache_fsm_save.read(); 1968 1967 } 1969 1968 #if DEBUG_ICACHE 1970 if ( m_debug_icache_fsm)1971 {1972 std::cout << " <PROC " << name()1973 << " ICACHE_CC_CHECK> Coherence request matching a pending miss:"1974 << " PADDR = " << std::hex << paddr << std::endl;1975 }1969 if (m_debug_icache_fsm) 1970 { 1971 std::cout << " <PROC " << name() 1972 << " ICACHE_CC_CHECK> Coherence request matching a pending miss:" 1973 << " PADDR = " << std::hex << paddr << std::endl; 1974 } 1976 1975 #endif 1977 1976 } … … 1979 1978 // CC request handler 1980 1979 1981 int 1982 size_t 1983 size_t 1984 size_t 1980 int state = 0; 1981 size_t way = 0; 1982 size_t set = 0; 1983 size_t word = 0; 1985 1984 1986 1985 #ifdef INSTRUMENTATION 1987 m_cpt_icache_dir_read++;1986 m_cpt_icache_dir_read++; 1988 1987 #endif 1989 1988 r_icache.read_dir(paddr, … … 1996 1995 r_icache_cc_set = set; 1997 1996 1998 if ( 1997 if (state == CACHE_SLOT_STATE_VALID) // hit 1999 1998 { 2000 1999 // need to update the cache state … … 2002 2001 { 2003 2002 r_icache_cc_need_write = true; 2004 r_icache_fsm 2005 r_icache_cc_word 2006 } 2007 else if ( r_cc_receive_icache_type.read() == CC_TYPE_INVAL) // hit inval2008 { 2009 r_icache_fsm 2003 r_icache_fsm = ICACHE_CC_UPDT; 2004 r_icache_cc_word = r_cc_receive_word_idx.read(); 2005 } 2006 else if (r_cc_receive_icache_type.read() == CC_TYPE_INVAL) // hit inval 2007 { 2008 r_icache_fsm = ICACHE_CC_INVAL; 2010 2009 } 2011 2010 } … … 2013 2012 { 2014 2013 // multicast acknowledgement required in case of update 2015 if (r_cc_receive_icache_type.read() == CC_TYPE_UPDT)2016 { 2017 r_icache_fsm 2018 r_icache_cc_word 2014 if (r_cc_receive_icache_type.read() == CC_TYPE_UPDT) 2015 { 2016 r_icache_fsm = ICACHE_CC_UPDT; 2017 r_icache_cc_word = r_cc_receive_word_idx.read(); 2019 2018 2020 2019 // just pop the fifo , don't write in icache … … 2024 2023 { 2025 2024 r_cc_receive_icache_req = false; 2026 r_icache_fsm 2025 r_icache_fsm = r_icache_fsm_save.read(); 2027 2026 } 2028 2027 } … … 2030 2029 } 2031 2030 ///////////////////// 2032 case ICACHE_CC_INVAL: 2031 case ICACHE_CC_INVAL: // hit inval : switch slot to ZOMBI state 2033 2032 { 2034 2033 assert (not r_icache_cc_send_req.read() && … … 2037 2036 2038 2037 #ifdef INSTRUMENTATION 2039 m_cpt_icache_dir_read++;2038 m_cpt_icache_dir_read++; 2040 2039 #endif 2041 2040 2042 2041 // Switch slot state to ZOMBI and send CLEANUP command 2043 r_icache.write_dir( 2044 2045 CACHE_SLOT_STATE_ZOMBI);2042 r_icache.write_dir(r_icache_cc_way.read(), 2043 r_icache_cc_set.read(), 2044 CACHE_SLOT_STATE_ZOMBI); 2046 2045 2047 2046 // coherence request completed … … 2051 2050 r_icache_cc_send_type = CC_TYPE_CLEANUP; 2052 2051 2053 r_icache_fsm 2052 r_icache_fsm = r_icache_fsm_save.read(); 2054 2053 2055 2054 #if DEBUG_ICACHE 2056 if ( m_debug_icache_fsm)2057 {2058 std::cout << " <PROC " << name()2059 << " ICACHE_CC_INVAL> slot returns to ZOMBI state"2060 << " set = " << r_icache_cc_set.read()2061 << " / way = " << r_icache_cc_way.read() << std::endl;2062 }2055 if (m_debug_icache_fsm) 2056 { 2057 std::cout << " <PROC " << name() 2058 << " ICACHE_CC_INVAL> slot returns to ZOMBI state" 2059 << " set = " << r_icache_cc_set.read() 2060 << " / way = " << r_icache_cc_way.read() << std::endl; 2061 } 2063 2062 #endif 2064 2063 … … 2066 2065 } 2067 2066 //////////////////// 2068 case ICACHE_CC_UPDT: 2067 case ICACHE_CC_UPDT: // hit update : write one word per cycle 2069 2068 { 2070 2069 assert (not r_icache_cc_send_req.read() && … … 2072 2071 "must not be set"); 2073 2072 2074 if ( not r_cc_receive_updt_fifo_be.rok()) break;2075 2076 2077 size_t word= r_icache_cc_word.read();2078 size_t way= r_icache_cc_way.read();2079 size_t set= r_icache_cc_set.read();2073 if (not r_cc_receive_updt_fifo_be.rok()) break; 2074 2075 2076 size_t word = r_icache_cc_word.read(); 2077 size_t way = r_icache_cc_way.read(); 2078 size_t set = r_icache_cc_set.read(); 2080 2079 2081 2080 if (r_icache_cc_need_write.read()) 2082 2081 { 2083 r_icache.write( 2084 2085 2086 2087 r_cc_receive_updt_fifo_be.read());2088 2089 r_icache_cc_word = word +1;2082 r_icache.write(way, 2083 set, 2084 word, 2085 r_cc_receive_updt_fifo_data.read(), 2086 r_cc_receive_updt_fifo_be.read()); 2087 2088 r_icache_cc_word = word + 1; 2090 2089 2091 2090 #ifdef INSTRUMENTATION 2092 m_cpt_icache_data_write++;2091 m_cpt_icache_data_write++; 2093 2092 #endif 2094 2093 2095 2094 #if DEBUG_ICACHE 2096 if ( m_debug_icache_fsm)2097 {2098 std::cout << " <PROC " << name()2099 << " ICACHE_CC_UPDT> Write one word "2100 << " set = " << r_icache_cc_set.read()2101 << " / way = " << r_icache_cc_way.read()2102 << " / word = " << r_icache_cc_word.read() << std::endl;2103 }2104 #endif 2105 } 2106 2107 if ( r_cc_receive_updt_fifo_eop.read() )// last word2095 if (m_debug_icache_fsm) 2096 { 2097 std::cout << " <PROC " << name() 2098 << " ICACHE_CC_UPDT> Write one word " 2099 << " set = " << r_icache_cc_set.read() 2100 << " / way = " << r_icache_cc_way.read() 2101 << " / word = " << r_icache_cc_word.read() << std::endl; 2102 } 2103 #endif 2104 } 2105 2106 if (r_cc_receive_updt_fifo_eop.read()) // last word 2108 2107 { 2109 2108 // no need to write in the cache anymore 2110 r_icache_cc_need_write 2109 r_icache_cc_need_write = false; 2111 2110 2112 2111 // coherence request completed 2113 r_cc_receive_icache_req 2112 r_cc_receive_icache_req = false; 2114 2113 2115 2114 // request multicast acknowledgement … … 2119 2118 r_icache_cc_send_type = CC_TYPE_MULTI_ACK; 2120 2119 2121 r_icache_fsm 2120 r_icache_fsm = r_icache_fsm_save.read(); 2122 2121 } 2123 2122 //consume fifo if not eop 2124 cc_receive_updt_fifo_get 2123 cc_receive_updt_fifo_get = true; 2125 2124 2126 2125 break; … … 2207 2206 m_drsp.rdata = 0; 2208 2207 2209 switch ( r_dcache_fsm.read())2208 switch (r_dcache_fsm.read()) 2210 2209 { 2211 2210 case DCACHE_IDLE: // There are 10 conditions to exit the IDLE state : … … 2244 2243 // updt_request, wbuf_request, wbuf_write_miss. 2245 2244 { 2246 paddr_t 2247 pte_info_t 2248 size_t 2249 size_t 2250 paddr_t 2251 size_t 2252 size_t 2253 size_t 2254 uint32_t 2255 bool 2256 int 2257 2258 bool tlb_inval_required = false;// request TLB inval after cache update2259 bool wbuf_write_miss = false;// miss a WBUF write request2260 bool updt_request = false;// request DCACHE update in P1 stage2261 bool wbuf_request = false;// request WBUF write in P1 stage2262 2263 // physical address computation : systematic DTLB access if activated )2245 paddr_t paddr; 2246 pte_info_t tlb_flags; 2247 size_t tlb_way; 2248 size_t tlb_set; 2249 paddr_t tlb_nline = 0; 2250 size_t cache_way; 2251 size_t cache_set; 2252 size_t cache_word; 2253 uint32_t cache_rdata = 0; 2254 bool tlb_hit = false; 2255 int cache_state = CACHE_SLOT_STATE_EMPTY; 2256 2257 bool tlb_inval_required = false; // request TLB inval after cache update 2258 bool wbuf_write_miss = false; // miss a WBUF write request 2259 bool updt_request = false; // request DCACHE update in P1 stage 2260 bool wbuf_request = false; // request WBUF write in P1 stage 2261 2262 // physical address computation : systematic DTLB access if activated 2264 2263 paddr = (paddr_t) m_dreq.addr; 2265 if ( m_dreq.valid)2266 { 2267 if ( r_mmu_mode.read() & DATA_TLB_MASK) // DTLB activated2268 { 2269 tlb_hit = r_dtlb.translate( 2270 2271 2272 2273 2274 &tlb_set);2264 if (m_dreq.valid) 2265 { 2266 if (r_mmu_mode.read() & DATA_TLB_MASK) // DTLB activated 2267 { 2268 tlb_hit = r_dtlb.translate(m_dreq.addr, 2269 &paddr, 2270 &tlb_flags, 2271 &tlb_nline, 2272 &tlb_way, 2273 &tlb_set); 2275 2274 #ifdef INSTRUMENTATION 2276 m_cpt_dtlb_read++;2277 #endif 2278 } 2279 else 2275 m_cpt_dtlb_read++; 2276 #endif 2277 } 2278 else // identity mapping 2280 2279 { 2281 2280 // we take into account the paddr extension 2282 2281 if (vci_param::N > 32) 2283 paddr = paddr | ((paddr_t) (r_dcache_paddr_ext.read()) << 32);2282 paddr = paddr | ((paddr_t) (r_dcache_paddr_ext.read()) << 32); 2284 2283 } 2285 2284 } // end physical address computation 2286 2285 2287 2286 // systematic DCACHE access depending on r_dcache_updt_req (if activated) 2288 if ( 2289 { 2290 2291 if ( m_dreq.valid and r_dcache_updt_req.read()) // read DIR and write DATA2292 { 2293 r_dcache.read_dir( 2294 2295 2296 2297 &cache_word);2298 2299 r_dcache.write( 2300 2301 2302 2303 r_dcache_save_be.read());2287 if (r_mmu_mode.read() & DATA_CACHE_MASK) 2288 { 2289 2290 if (m_dreq.valid and r_dcache_updt_req.read()) // read DIR and write DATA 2291 { 2292 r_dcache.read_dir(paddr, 2293 &cache_state, 2294 &cache_way, 2295 &cache_set, 2296 &cache_word); 2297 2298 r_dcache.write(r_dcache_save_cache_way.read(), 2299 r_dcache_save_cache_set.read(), 2300 r_dcache_save_cache_word.read(), 2301 r_dcache_save_wdata.read(), 2302 r_dcache_save_be.read()); 2304 2303 #ifdef INSTRUMENTATION 2305 m_cpt_dcache_dir_read++;2306 m_cpt_dcache_data_write++;2307 #endif 2308 } 2309 else if ( m_dreq.valid and not r_dcache_updt_req.read()) // read DIR and DATA2310 { 2311 r_dcache.read( 2312 2313 2314 2315 2316 &cache_state);2304 m_cpt_dcache_dir_read++; 2305 m_cpt_dcache_data_write++; 2306 #endif 2307 } 2308 else if (m_dreq.valid and not r_dcache_updt_req.read()) // read DIR and DATA 2309 { 2310 r_dcache.read(paddr, 2311 &cache_rdata, 2312 &cache_way, 2313 &cache_set, 2314 &cache_word, 2315 &cache_state); 2317 2316 2318 2317 #ifdef INSTRUMENTATION 2319 m_cpt_dcache_dir_read++;2320 m_cpt_dcache_data_read++;2321 #endif 2322 } 2323 else if ( not m_dreq.valid and r_dcache_updt_req.read()) // write DATA2324 { 2325 r_dcache.write( 2326 2327 2328 2329 r_dcache_save_be.read());2318 m_cpt_dcache_dir_read++; 2319 m_cpt_dcache_data_read++; 2320 #endif 2321 } 2322 else if (not m_dreq.valid and r_dcache_updt_req.read()) // write DATA 2323 { 2324 r_dcache.write(r_dcache_save_cache_way.read(), 2325 r_dcache_save_cache_set.read(), 2326 r_dcache_save_cache_word.read(), 2327 r_dcache_save_wdata.read(), 2328 r_dcache_save_be.read()); 2330 2329 #ifdef INSTRUMENTATION 2331 m_cpt_dcache_data_write++;2330 m_cpt_dcache_data_write++; 2332 2331 #endif 2333 2332 } … … 2335 2334 2336 2335 // DCACHE update in P1 stage can require ITLB / DTLB inval or flush 2337 if ( r_dcache_updt_req.read())2336 if (r_dcache_updt_req.read()) 2338 2337 { 2339 2338 size_t way = r_dcache_save_cache_way.read(); 2340 2339 size_t set = r_dcache_save_cache_set.read(); 2341 2340 2342 if ( r_dcache_in_tlb[way*m_dcache_sets+set])2343 { 2344 tlb_inval_required 2345 r_dcache_tlb_inval_set= 0;2346 r_dcache_tlb_inval_line = r_dcache_save_paddr.read()>>2347 (uint32_log2(m_dcache_words <<2));2348 r_dcache_in_tlb[way*m_dcache_sets+set] = false;2349 } 2350 else if ( r_dcache_contains_ptd[way*m_dcache_sets+set])2341 if (r_dcache_in_tlb[way * m_dcache_sets + set]) 2342 { 2343 tlb_inval_required = true; 2344 r_dcache_tlb_inval_set = 0; 2345 r_dcache_tlb_inval_line = r_dcache_save_paddr.read() >> 2346 (uint32_log2(m_dcache_words << 2)); 2347 r_dcache_in_tlb[way * m_dcache_sets + set] = false; 2348 } 2349 else if (r_dcache_contains_ptd[way * m_dcache_sets + set]) 2351 2350 { 2352 2351 r_itlb.reset(); 2353 2352 r_dtlb.reset(); 2354 r_dcache_contains_ptd[way*m_dcache_sets+set] = false;2353 r_dcache_contains_ptd[way * m_dcache_sets + set] = false; 2355 2354 } 2356 2355 2357 2356 #if DEBUG_DCACHE 2358 if ( m_debug_dcache_fsm)2359 std::cout << " <PROC " << name() << " DCACHE_IDLE>"2360 << " Cache update in P1 stage" << std::dec2361 << " / WAY = " << r_dcache_save_cache_way.read()2362 << " / SET = " << r_dcache_save_cache_set.read()2363 << " / WORD = " << r_dcache_save_cache_word.read() << std::hex2364 << " / WDATA = " << r_dcache_save_wdata.read()2365 << " / BE = " << r_dcache_save_be.read() << std::endl;2357 if (m_debug_dcache_fsm) 2358 std::cout << " <PROC " << name() << " DCACHE_IDLE>" 2359 << " Cache update in P1 stage" << std::dec 2360 << " / WAY = " << r_dcache_save_cache_way.read() 2361 << " / SET = " << r_dcache_save_cache_set.read() 2362 << " / WORD = " << r_dcache_save_cache_word.read() << std::hex 2363 << " / WDATA = " << r_dcache_save_wdata.read() 2364 << " / BE = " << r_dcache_save_be.read() << std::endl; 2366 2365 #endif 2367 2366 } // end test TLB inval … … 2370 2369 // Miss if the write request is non cacheable, and there is a pending 2371 2370 // non cacheable write, or if the write buffer is full. 2372 if ( r_dcache_wbuf_req.read())2373 { 2374 bool wok = r_wbuf.write( 2375 2376 2377 2371 if (r_dcache_wbuf_req.read()) 2372 { 2373 bool wok = r_wbuf.write(r_dcache_save_paddr.read(), 2374 r_dcache_save_be.read(), 2375 r_dcache_save_wdata.read(), 2376 true); 2378 2377 #ifdef INSTRUMENTATION 2379 m_cpt_wbuf_write++;2380 #endif 2381 if ( 2378 m_cpt_wbuf_write++; 2379 #endif 2380 if (not wok ) // miss if write buffer full 2382 2381 { 2383 2382 wbuf_write_miss = true; … … 2389 2388 2390 2389 // itlb/dtlb invalidation self-request 2391 if ( tlb_inval_required)2390 if (tlb_inval_required) 2392 2391 { 2393 2392 r_dcache_fsm_scan_save = r_dcache_fsm.read(); … … 2396 2395 2397 2396 // coherence clack request (from DSPIN CLACK) 2398 else if ( r_dcache_clack_req.read())2397 else if (r_dcache_clack_req.read()) 2399 2398 { 2400 2399 r_dcache_fsm = DCACHE_CC_CHECK; … … 2402 2401 } 2403 2402 // coherence request (from CC_RECEIVE FSM) 2404 else if ( 2403 else if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 2405 2404 { 2406 2405 r_dcache_fsm = DCACHE_CC_CHECK; … … 2411 2410 // we don't take the processor request, and registers 2412 2411 // are frozen in case of wbuf_write_miss 2413 else if ( m_dreq.valid and not wbuf_write_miss)2412 else if (m_dreq.valid and not wbuf_write_miss) 2414 2413 { 2415 2414 // register processor request and DCACHE response … … 2427 2426 if (m_dreq.type == iss_t::XTN_READ) 2428 2427 { 2429 int xtn_opcode = (int)m_dreq.addr /4;2428 int xtn_opcode = (int)m_dreq.addr / 4; 2430 2429 2431 2430 // checking processor mode: … … 2441 2440 else 2442 2441 { 2443 switch ( xtn_opcode)2442 switch (xtn_opcode) 2444 2443 { 2445 2444 case iss_t::XTN_INS_ERROR_TYPE: … … 2516 2515 2517 2516 default: 2518 r_mmu_detr = MMU_READ_UNDEFINED_XTN;2517 r_mmu_detr = MMU_READ_UNDEFINED_XTN; 2519 2518 r_mmu_dbvar = m_dreq.addr; 2520 2519 m_drsp.valid = true; … … 2534 2533 else if (m_dreq.type == iss_t::XTN_WRITE) 2535 2534 { 2536 int xtn_opcode = (int)m_dreq.addr/4;2535 int xtn_opcode = (int)m_dreq.addr / 4; 2537 2536 r_dcache_xtn_opcode = xtn_opcode; 2538 2537 2539 2538 // checking processor mode: 2540 if ( 2539 if ((m_dreq.mode == iss_t::MODE_USER) && 2541 2540 (xtn_opcode != iss_t::XTN_SYNC) && 2542 2541 (xtn_opcode != iss_t::XTN_DCACHE_INVAL) && 2543 2542 (xtn_opcode != iss_t::XTN_DCACHE_FLUSH) && 2544 2543 (xtn_opcode != iss_t::XTN_ICACHE_INVAL) && 2545 (xtn_opcode != iss_t::XTN_ICACHE_FLUSH) 2544 (xtn_opcode != iss_t::XTN_ICACHE_FLUSH)) 2546 2545 { 2547 2546 r_mmu_detr = MMU_WRITE_PRIVILEGE_VIOLATION; … … 2554 2553 else 2555 2554 { 2556 switch ( xtn_opcode)2555 switch (xtn_opcode) 2557 2556 { 2558 case iss_t::XTN_PTPR: 2557 case iss_t::XTN_PTPR: // itlb & dtlb must be flushed 2559 2558 r_dcache_xtn_req = true; 2560 2559 r_dcache_fsm = DCACHE_XTN_SWITCH; 2561 2560 break; 2562 2561 2563 case iss_t::XTN_TLB_MODE: 2564 r_mmu_mode 2565 m_drsp.valid 2566 r_dcache_fsm 2562 case iss_t::XTN_TLB_MODE: // no cache or tlb access 2563 r_mmu_mode = m_dreq.wdata; 2564 m_drsp.valid = true; 2565 r_dcache_fsm = DCACHE_IDLE; 2567 2566 break; 2568 2567 2569 case iss_t::XTN_DTLB_INVAL: 2570 r_dcache_fsm 2568 case iss_t::XTN_DTLB_INVAL: // dtlb access 2569 r_dcache_fsm = DCACHE_XTN_DT_INVAL; 2571 2570 break; 2572 2571 2573 case iss_t::XTN_ITLB_INVAL: 2572 case iss_t::XTN_ITLB_INVAL: // itlb access 2574 2573 r_dcache_xtn_req = true; 2575 2574 r_dcache_fsm = DCACHE_XTN_IT_INVAL; 2576 2575 break; 2577 2576 2578 case iss_t::XTN_DCACHE_INVAL: 2579 r_dcache_fsm 2577 case iss_t::XTN_DCACHE_INVAL: // dcache, dtlb & itlb access 2578 r_dcache_fsm = DCACHE_XTN_DC_INVAL_VA; 2580 2579 break; 2581 2580 2582 case iss_t::XTN_MMU_DCACHE_PA_INV: 2583 r_dcache_fsm 2581 case iss_t::XTN_MMU_DCACHE_PA_INV: // dcache, dtlb & itlb access 2582 r_dcache_fsm = DCACHE_XTN_DC_INVAL_PA; 2584 2583 if (sizeof(paddr_t) <= 32) 2585 2584 { … … 2595 2594 break; 2596 2595 2597 case iss_t::XTN_DCACHE_FLUSH: 2596 case iss_t::XTN_DCACHE_FLUSH: // itlb and dtlb must be reset 2598 2597 r_dcache_flush_count = 0; 2599 r_dcache_fsm = DCACHE_XTN_DC_FLUSH;2598 r_dcache_fsm = DCACHE_XTN_DC_FLUSH; 2600 2599 break; 2601 2600 2602 case iss_t::XTN_ICACHE_INVAL: 2601 case iss_t::XTN_ICACHE_INVAL: // icache and itlb access 2603 2602 r_dcache_xtn_req = true; 2604 2603 r_dcache_fsm = DCACHE_XTN_IC_INVAL_VA; 2605 2604 break; 2606 2605 2607 case iss_t::XTN_MMU_ICACHE_PA_INV: 2606 case iss_t::XTN_MMU_ICACHE_PA_INV: // icache access 2608 2607 r_dcache_xtn_req = true; 2609 2608 r_dcache_fsm = DCACHE_XTN_IC_INVAL_PA; 2610 2609 break; 2611 2610 2612 case iss_t::XTN_ICACHE_FLUSH: 2611 case iss_t::XTN_ICACHE_FLUSH: // icache access 2613 2612 r_dcache_xtn_req = true; 2614 2613 r_dcache_fsm = DCACHE_XTN_IC_FLUSH; 2615 2614 break; 2616 2615 2617 case iss_t::XTN_SYNC: 2618 r_dcache_fsm 2616 case iss_t::XTN_SYNC: // wait until write buffer empty 2617 r_dcache_fsm = DCACHE_XTN_SYNC; 2619 2618 break; 2620 2619 2621 case iss_t::XTN_MMU_WORD_LO: 2622 r_mmu_word_lo 2623 m_drsp.valid 2624 r_dcache_fsm 2620 case iss_t::XTN_MMU_WORD_LO: // no cache or tlb access 2621 r_mmu_word_lo = m_dreq.wdata; 2622 m_drsp.valid = true; 2623 r_dcache_fsm = DCACHE_IDLE; 2625 2624 break; 2626 2625 2627 case iss_t::XTN_MMU_WORD_HI: 2628 r_mmu_word_hi 2629 m_drsp.valid 2630 r_dcache_fsm 2626 case iss_t::XTN_MMU_WORD_HI: // no cache or tlb access 2627 r_mmu_word_hi = m_dreq.wdata; 2628 m_drsp.valid = true; 2629 r_dcache_fsm = DCACHE_IDLE; 2631 2630 break; 2632 2631 2633 case iss_t::XTN_MMU_LL_RESET: 2632 case iss_t::XTN_MMU_LL_RESET: // no cache or tlb access 2634 2633 r_dcache_llsc_valid = false; 2635 m_drsp.valid = true;2636 r_dcache_fsm = DCACHE_IDLE;2634 m_drsp.valid = true; 2635 r_dcache_fsm = DCACHE_IDLE; 2637 2636 break; 2638 2637 2639 case iss_t::XTN_DATA_PADDR_EXT: 2638 case iss_t::XTN_DATA_PADDR_EXT: // no cache or tlb access 2640 2639 r_dcache_paddr_ext = m_dreq.wdata; 2641 2640 m_drsp.valid = true; … … 2643 2642 break; 2644 2643 2645 case iss_t::XTN_INST_PADDR_EXT: 2644 case iss_t::XTN_INST_PADDR_EXT: // no cache or tlb access 2646 2645 r_dcache_xtn_req = true; 2647 2646 r_dcache_fsm = DCACHE_XTN_IC_PADDR_EXT; 2648 2647 break; 2649 2648 2650 case iss_t::XTN_ICACHE_PREFETCH: 2651 case iss_t::XTN_DCACHE_PREFETCH: 2652 m_drsp.valid 2653 r_dcache_fsm 2649 case iss_t::XTN_ICACHE_PREFETCH: // not implemented : no action 2650 case iss_t::XTN_DCACHE_PREFETCH: // not implemented : no action 2651 m_drsp.valid = true; 2652 r_dcache_fsm = DCACHE_IDLE; 2654 2653 break; 2655 2654 … … 2683 2682 else 2684 2683 { 2685 bool 2686 bool 2687 2688 if ( not (r_mmu_mode.read() & DATA_TLB_MASK) )// dtlb not activated2684 bool valid_req; 2685 bool cacheable; 2686 2687 if (not (r_mmu_mode.read() & DATA_TLB_MASK)) // dtlb not activated 2689 2688 { 2690 valid_req 2691 2692 if ( not (r_mmu_mode.read() & DATA_CACHE_MASK)) cacheable = false;2689 valid_req = true; 2690 2691 if (not (r_mmu_mode.read() & DATA_CACHE_MASK)) cacheable = false; 2693 2692 else cacheable = m_cacheability_table[(uint64_t)m_dreq.addr]; 2694 2693 } 2695 else 2694 else // dtlb activated 2696 2695 { 2697 if ( tlb_hit )// tlb hit2696 if (tlb_hit) // tlb hit 2698 2697 { 2699 2698 // cacheability 2700 if ( not (r_mmu_mode.read() & DATA_CACHE_MASK)) cacheable = false;2699 if (not (r_mmu_mode.read() & DATA_CACHE_MASK)) cacheable = false; 2701 2700 else cacheable = tlb_flags.c; 2702 2701 2703 2702 // access rights checking 2704 if ( 2703 if (not tlb_flags.u and (m_dreq.mode == iss_t::MODE_USER)) 2705 2704 { 2706 if ( 2707 (m_dreq.type == iss_t::DATA_LL) 2705 if ((m_dreq.type == iss_t::DATA_READ) or 2706 (m_dreq.type == iss_t::DATA_LL)) 2708 2707 { 2709 2708 r_mmu_detr = MMU_READ_PRIVILEGE_VIOLATION; … … 2719 2718 m_drsp.rdata = 0; 2720 2719 #if DEBUG_DCACHE 2721 if ( m_debug_dcache_fsm)2722 std::cout << " <PROC " << name() << " DCACHE_IDLE>"2723 << " HIT in dtlb, but privilege violation" << std::endl;2720 if (m_debug_dcache_fsm) 2721 std::cout << " <PROC " << name() << " DCACHE_IDLE>" 2722 << " HIT in dtlb, but privilege violation" << std::endl; 2724 2723 #endif 2725 2724 } 2726 else if ( 2725 else if (not tlb_flags.w and 2727 2726 ((m_dreq.type == iss_t::DATA_WRITE) or 2728 (m_dreq.type == iss_t::DATA_SC)) 2727 (m_dreq.type == iss_t::DATA_SC))) 2729 2728 { 2730 2729 r_mmu_detr = MMU_WRITE_ACCES_VIOLATION; … … 2735 2734 m_drsp.rdata = 0; 2736 2735 #if DEBUG_DCACHE 2737 if ( m_debug_dcache_fsm)2738 std::cout << " <PROC " << name() << " DCACHE_IDLE>"2739 << " HIT in dtlb, but writable violation" << std::endl;2736 if (m_debug_dcache_fsm) 2737 std::cout << " <PROC " << name() << " DCACHE_IDLE>" 2738 << " HIT in dtlb, but writable violation" << std::endl; 2740 2739 #endif 2741 2740 } 2742 2741 else 2743 2742 { 2744 valid_req 2743 valid_req = true; 2745 2744 } 2746 2745 } 2747 else 2746 else // tlb miss 2748 2747 { 2749 valid_req 2750 r_dcache_tlb_vaddr 2751 r_dcache_tlb_ins 2752 r_dcache_fsm 2748 valid_req = false; 2749 r_dcache_tlb_vaddr = m_dreq.addr; 2750 r_dcache_tlb_ins = false; 2751 r_dcache_fsm = DCACHE_TLB_MISS; 2753 2752 } 2754 2753 } // end DTLB activated 2755 2754 2756 if ( valid_req )// processor request is valid (after MMU check)2755 if (valid_req) // processor request is valid (after MMU check) 2757 2756 { 2758 2757 // READ request … … 2760 2759 // We request a VCI transaction to CMD FSM if miss or uncachable 2761 2760 2762 if ( 2763 and not r_dcache_updt_req.read() 2761 if (((m_dreq.type == iss_t::DATA_READ)) 2762 and not r_dcache_updt_req.read()) 2764 2763 { 2765 if ( cacheable )// cacheable read2764 if (cacheable) // cacheable read 2766 2765 { 2767 if ( cache_state == CACHE_SLOT_STATE_EMPTY) // cache miss2766 if (cache_state == CACHE_SLOT_STATE_EMPTY) // cache miss 2768 2767 { 2769 2768 #ifdef INSTRUMENTATION 2770 m_cpt_dcache_miss++;2769 m_cpt_dcache_miss++; 2771 2770 #endif 2772 2771 // request a VCI DMISS transaction … … 2776 2775 r_dcache_fsm = DCACHE_MISS_SELECT; 2777 2776 #if DEBUG_DCACHE 2778 if ( m_debug_dcache_fsm)2779 std::cout << " <PROC " << name() << " DCACHE_IDLE>"2780 << " READ MISS in dcache"2781 << " / PADDR = " << std::hex << paddr << std::endl;2777 if (m_debug_dcache_fsm) 2778 std::cout << " <PROC " << name() << " DCACHE_IDLE>" 2779 << " READ MISS in dcache" 2780 << " / PADDR = " << std::hex << paddr << std::endl; 2782 2781 #endif 2783 2782 } 2784 else if (cache_state == CACHE_SLOT_STATE_ZOMBI 2783 else if (cache_state == CACHE_SLOT_STATE_ZOMBI) // pending cleanup 2785 2784 { 2786 2785 // stalled until cleanup is acknowledged 2787 2786 r_dcache_fsm = DCACHE_IDLE; 2788 2787 #if DEBUG_DCACHE 2789 if ( m_debug_dcache_fsm)2790 std::cout << " <PROC " << name() << " DCACHE_IDLE>"2791 << " Pending cleanup, stalled until cleanup acknowledge"2792 << " / PADDR = " << std::hex << paddr << std::endl;2788 if (m_debug_dcache_fsm) 2789 std::cout << " <PROC " << name() << " DCACHE_IDLE>" 2790 << " Pending cleanup, stalled until cleanup acknowledge" 2791 << " / PADDR = " << std::hex << paddr << std::endl; 2793 2792 #endif 2794 2793 } … … 2796 2795 { 2797 2796 #ifdef INSTRUMENTATION 2798 m_cpt_data_read++;2797 m_cpt_data_read++; 2799 2798 #endif 2800 2799 // returns data to processor 2801 m_drsp.valid 2802 m_drsp.error 2803 m_drsp.rdata 2800 m_drsp.valid = true; 2801 m_drsp.error = false; 2802 m_drsp.rdata = cache_rdata; 2804 2803 #if DEBUG_DCACHE 2805 if ( m_debug_dcache_fsm)2806 std::cout << " <PROC " << name() << " DCACHE_IDLE>"2807 << " READ HIT in dcache"2808 << " : PADDR = " << std::hex << paddr2809 << " / DATA = " << std::hex << cache_rdata << std::endl;2804 if (m_debug_dcache_fsm) 2805 std::cout << " <PROC " << name() << " DCACHE_IDLE>" 2806 << " READ HIT in dcache" 2807 << " : PADDR = " << std::hex << paddr 2808 << " / DATA = " << std::hex << cache_rdata << std::endl; 2810 2809 #endif 2811 2810 } 2812 2811 } 2813 else 2812 else // uncacheable read 2814 2813 { 2815 r_dcache_vci_paddr 2816 r_dcache_vci_unc_be 2817 r_dcache_vci_unc_write 2818 r_dcache_vci_unc_req 2819 r_dcache_fsm 2814 r_dcache_vci_paddr = paddr; 2815 r_dcache_vci_unc_be = m_dreq.be; 2816 r_dcache_vci_unc_write = false; 2817 r_dcache_vci_unc_req = true; 2818 r_dcache_fsm = DCACHE_UNC_WAIT; 2820 2819 #if DEBUG_DCACHE 2821 if ( m_debug_dcache_fsm)2822 std::cout << " <PROC " << name() << " DCACHE_IDLE>"2823 << " READ UNCACHEABLE in dcache"2824 << " / PADDR = " << std::hex << paddr << std::endl;2820 if (m_debug_dcache_fsm) 2821 std::cout << " <PROC " << name() << " DCACHE_IDLE>" 2822 << " READ UNCACHEABLE in dcache" 2823 << " / PADDR = " << std::hex << paddr << std::endl; 2825 2824 #endif 2826 2825 } … … 2853 2852 // physical address) are registered in r_dcache_save registers, 2854 2853 // and the write will be done in the P1 pipeline stage. 2855 else if ( m_dreq.type == iss_t::DATA_WRITE)2854 else if (m_dreq.type == iss_t::DATA_WRITE) 2856 2855 { 2857 if ( (r_mmu_mode.read() & DATA_TLB_MASK)2858 and not tlb_flags.d )// Dirty bit must be set2856 if ((r_mmu_mode.read() & DATA_TLB_MASK) 2857 and not tlb_flags.d) // Dirty bit must be set 2859 2858 { 2860 2859 // The PTE physical address is obtained from the nline value (dtlb), 2861 2860 // and from the virtual address (word index) 2862 if ( tlb_flags.b )// PTE12861 if (tlb_flags.b ) // PTE1 2863 2862 { 2864 r_dcache_dirty_paddr = (paddr_t)(tlb_nline *(m_dcache_words<<2)) |2865 (paddr_t)((m_dreq.addr >>19) & 0x3c);2863 r_dcache_dirty_paddr = (paddr_t)(tlb_nline * (m_dcache_words << 2)) | 2864 (paddr_t)((m_dreq.addr >> 19) & 0x3c); 2866 2865 } 2867 else 2866 else // PTE2 2868 2867 { 2869 r_dcache_dirty_paddr = (paddr_t) (tlb_nline*(m_dcache_words<<2)) |2870 (paddr_t) ((m_dreq.addr>>9) & 0x38);2868 r_dcache_dirty_paddr = (paddr_t) (tlb_nline * (m_dcache_words << 2)) | 2869 (paddr_t) ((m_dreq.addr >> 9) & 0x38); 2871 2870 } 2872 r_dcache_fsm 2871 r_dcache_fsm = DCACHE_DIRTY_GET_PTE; 2873 2872 } 2874 else 2873 else // Write request accepted 2875 2874 { 2876 2875 #ifdef INSTRUMENTATION 2877 m_cpt_data_write++;2876 m_cpt_data_write++; 2878 2877 #endif 2879 2878 // cleaning llsc buffer if address matching 2880 if ( paddr == r_dcache_llsc_paddr.read())2879 if (paddr == r_dcache_llsc_paddr.read()) 2881 2880 r_dcache_llsc_valid = false; 2882 2881 2883 2882 if (not cacheable) 2884 2883 { 2885 r_dcache_vci_paddr 2886 r_dcache_vci_wdata 2887 r_dcache_vci_unc_write 2888 r_dcache_vci_unc_be 2889 r_dcache_vci_unc_req 2890 r_dcache_fsm 2884 r_dcache_vci_paddr = paddr; 2885 r_dcache_vci_wdata = m_dreq.wdata; 2886 r_dcache_vci_unc_write = true; 2887 r_dcache_vci_unc_be = m_dreq.be; 2888 r_dcache_vci_unc_req = true; 2889 r_dcache_fsm = DCACHE_UNC_WAIT; 2891 2890 } 2892 2891 else 2893 2892 { 2894 2893 // response to processor 2895 m_drsp.valid 2894 m_drsp.valid = true; 2896 2895 // activating P1 stage 2897 2896 wbuf_request = true; … … 2911 2910 // We don't check a possible write hit in dcache, as the cache update 2912 2911 // is done by the coherence transaction induced by the SC... 2913 else if ( m_dreq.type == iss_t::DATA_SC)2912 else if (m_dreq.type == iss_t::DATA_SC) 2914 2913 { 2915 if ( (r_mmu_mode.read() & DATA_TLB_MASK)2916 and not tlb_flags.d )// Dirty bit must be set2914 if ((r_mmu_mode.read() & DATA_TLB_MASK) 2915 and not tlb_flags.d) // Dirty bit must be set 2917 2916 { 2918 2917 // The PTE physical address is obtained from the nline value (dtlb), 2919 2918 // and the word index (virtual address) 2920 if ( tlb_flags.b )// PTE12919 if (tlb_flags.b) // PTE1 2921 2920 { 2922 r_dcache_dirty_paddr = (paddr_t) (tlb_nline*(m_dcache_words<<2)) |2923 (paddr_t) ((m_dreq.addr>>19) & 0x3c);2921 r_dcache_dirty_paddr = (paddr_t) (tlb_nline * (m_dcache_words << 2)) | 2922 (paddr_t) ((m_dreq.addr >> 19) & 0x3c); 2924 2923 } 2925 else 2924 else // PTE2 2926 2925 { 2927 r_dcache_dirty_paddr = (paddr_t) (tlb_nline*(m_dcache_words<<2)) |2928 (paddr_t) ((m_dreq.addr>>9) & 0x38);2926 r_dcache_dirty_paddr = (paddr_t) (tlb_nline * (m_dcache_words << 2)) | 2927 (paddr_t) ((m_dreq.addr >> 9) & 0x38); 2929 2928 } 2930 r_dcache_fsm 2929 r_dcache_fsm = DCACHE_DIRTY_GET_PTE; 2931 2930 m_drsp.valid = false; 2932 2931 m_drsp.error = false; 2933 2932 m_drsp.rdata = 0; 2934 2933 } 2935 else 2934 else // SC request accepted 2936 2935 { 2937 2936 #ifdef INSTRUMENTATION 2938 m_cpt_data_sc++;2937 m_cpt_data_sc++; 2939 2938 #endif 2940 2939 // checking local success 2941 if (r_dcache_llsc_valid.read() and2942 (r_dcache_llsc_paddr.read() == paddr) )// local success2940 if (r_dcache_llsc_valid.read() and 2941 (r_dcache_llsc_paddr.read() == paddr)) // local success 2943 2942 { 2944 2943 // request an SC CMD and go to DCACHE_SC_WAIT state … … 2948 2947 r_dcache_fsm = DCACHE_SC_WAIT; 2949 2948 } 2950 else 2949 else // local fail 2951 2950 { 2952 2953 2954 2951 m_drsp.valid = true; 2952 m_drsp.error = false; 2953 m_drsp.rdata = 0x1; 2955 2954 } 2956 2955 } … … 2961 2960 2962 2961 // itlb miss request 2963 else if (r_icache_tlb_miss_req.read() and not wbuf_write_miss )2962 else if (r_icache_tlb_miss_req.read() and not wbuf_write_miss ) 2964 2963 { 2965 2964 r_dcache_tlb_ins = true; … … 2987 2986 // r_mmu_ins_* or r_mmu_data* error reporting registers. 2988 2987 { 2989 uint32_t 2990 bool 2991 paddr_t 2988 uint32_t ptba = 0; 2989 bool bypass; 2990 paddr_t pte_paddr; 2992 2991 2993 2992 // evaluate bypass in order to skip first level page table access 2994 if ( r_dcache_tlb_ins.read() )// itlb miss2993 if (r_dcache_tlb_ins.read()) // itlb miss 2995 2994 { 2996 2995 bypass = r_itlb.get_bypass(r_dcache_tlb_vaddr.read(), &ptba); 2997 2996 } 2998 else 2997 else // dtlb miss 2999 2998 { 3000 2999 bypass = r_dtlb.get_bypass(r_dcache_tlb_vaddr.read(), &ptba); 3001 3000 } 3002 3001 3003 if ( not bypass )// Try to read PTE1/PTD1 in dcache3004 { 3005 pte_paddr = (((paddr_t) r_mmu_ptpr.read()) << (INDEX1_NBITS+2)) |3006 ((((paddr_t)r_dcache_tlb_vaddr.read()) >> PAGE_M_NBITS) << 2);3002 if (not bypass) // Try to read PTE1/PTD1 in dcache 3003 { 3004 pte_paddr = (((paddr_t) r_mmu_ptpr.read()) << (INDEX1_NBITS + 2)) | 3005 ((((paddr_t) r_dcache_tlb_vaddr.read()) >> PAGE_M_NBITS) << 2); 3007 3006 r_dcache_tlb_paddr = pte_paddr; 3008 3007 r_dcache_fsm = DCACHE_TLB_PTE1_GET; 3009 3008 } 3010 else 3011 { 3012 pte_paddr = (paddr_t) ptba << PAGE_K_NBITS |3013 (paddr_t) (r_dcache_tlb_vaddr.read()&PTD_ID2_MASK)>>(PAGE_K_NBITS-3);3009 else // Try to read PTE2 in dcache 3010 { 3011 pte_paddr = (paddr_t) ptba << PAGE_K_NBITS | 3012 (paddr_t) (r_dcache_tlb_vaddr.read() & PTD_ID2_MASK) >> (PAGE_K_NBITS - 3); 3014 3013 r_dcache_tlb_paddr = pte_paddr; 3015 3014 r_dcache_fsm = DCACHE_TLB_PTE2_GET; … … 3017 3016 3018 3017 #if DEBUG_DCACHE 3019 if ( m_debug_dcache_fsm)3020 {3021 if ( r_dcache_tlb_ins.read())3022 std::cout << " <PROC " << name() << " DCACHE_TLB_MISS> ITLB miss";3023 else3024 std::cout << " <PROC " << name() << " DCACHE_TLB_MISS> DTLB miss";3025 std::cout << " / VADDR = " << std::hex << r_dcache_tlb_vaddr.read()3026 << " / ptpr = " << (((paddr_t)r_mmu_ptpr.read()) << (INDEX1_NBITS+2))3027 << " / BYPASS = " << bypass3028 << " / PTE_ADR = " << pte_paddr << std::endl;3029 }3018 if (m_debug_dcache_fsm) 3019 { 3020 if (r_dcache_tlb_ins.read()) 3021 std::cout << " <PROC " << name() << " DCACHE_TLB_MISS> ITLB miss"; 3022 else 3023 std::cout << " <PROC " << name() << " DCACHE_TLB_MISS> DTLB miss"; 3024 std::cout << " / VADDR = " << std::hex << r_dcache_tlb_vaddr.read() 3025 << " / ptpr = " << (((paddr_t)r_mmu_ptpr.read()) << (INDEX1_NBITS+2)) 3026 << " / BYPASS = " << bypass 3027 << " / PTE_ADR = " << pte_paddr << std::endl; 3028 } 3030 3029 #endif 3031 3030 … … 3033 3032 } 3034 3033 ///////////////////////// 3035 case DCACHE_TLB_PTE1_GET: 3034 case DCACHE_TLB_PTE1_GET: // try to read a PT1 entry in dcache 3036 3035 { 3037 3036 // coherence clack request (from DSPIN CLACK) 3038 if ( r_dcache_clack_req.read())3037 if (r_dcache_clack_req.read()) 3039 3038 { 3040 3039 r_dcache_fsm = DCACHE_CC_CHECK; … … 3044 3043 3045 3044 // coherence request (from CC_RECEIVE FSM) 3046 if ( 3045 if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 3047 3046 { 3048 3047 r_dcache_fsm = DCACHE_CC_CHECK; … … 3051 3050 } 3052 3051 3053 uint32_t 3054 size_t 3055 size_t 3056 size_t 3057 int 3058 r_dcache.read( 3059 3060 3061 3062 3063 &cache_state);3052 uint32_t entry; 3053 size_t way; 3054 size_t set; 3055 size_t word; 3056 int cache_state; 3057 r_dcache.read(r_dcache_tlb_paddr.read(), 3058 &entry, 3059 &way, 3060 &set, 3061 &word, 3062 &cache_state); 3064 3063 #ifdef INSTRUMENTATION 3065 m_cpt_dcache_data_read++;3066 m_cpt_dcache_dir_read++;3067 #endif 3068 if ( cache_state == CACHE_SLOT_STATE_VALID) // hit in dcache3069 { 3070 if ( not (entry & PTE_V_MASK) )// unmapped3071 { 3072 if ( r_dcache_tlb_ins.read())3064 m_cpt_dcache_data_read++; 3065 m_cpt_dcache_dir_read++; 3066 #endif 3067 if (cache_state == CACHE_SLOT_STATE_VALID) // hit in dcache 3068 { 3069 if (not (entry & PTE_V_MASK)) // unmapped 3070 { 3071 if (r_dcache_tlb_ins.read()) 3073 3072 { 3074 3073 r_mmu_ietr = MMU_READ_PT1_UNMAPPED; … … 3079 3078 else 3080 3079 { 3081 r_mmu_detr 3082 r_mmu_dbvar 3083 m_drsp.valid 3084 m_drsp.error 3080 r_mmu_detr = MMU_READ_PT1_UNMAPPED; 3081 r_mmu_dbvar = r_dcache_tlb_vaddr.read(); 3082 m_drsp.valid = true; 3083 m_drsp.error = true; 3085 3084 } 3086 r_dcache_fsm 3085 r_dcache_fsm = DCACHE_IDLE; 3087 3086 3088 3087 #if DEBUG_DCACHE 3089 if ( m_debug_dcache_fsm)3090 {3091 std::cout << " <PROC " << name()3092 << " DCACHE_TLB_PTE1_GET> HIT in dcache, but unmapped"3093 << std::hex << " / paddr = " << r_dcache_tlb_paddr.read()3094 << std::dec << " / way = " << way3095 << std::dec << " / set = " << set3096 << std::dec << " / word = " << word3097 << std::hex << " / PTE1 = " << entry << std::endl;3098 }3099 #endif 3100 3101 } 3102 else if ( entry & PTE_T_MASK )// PTD : me must access PT23088 if (m_debug_dcache_fsm) 3089 { 3090 std::cout << " <PROC " << name() 3091 << " DCACHE_TLB_PTE1_GET> HIT in dcache, but unmapped" 3092 << std::hex << " / paddr = " << r_dcache_tlb_paddr.read() 3093 << std::dec << " / way = " << way 3094 << std::dec << " / set = " << set 3095 << std::dec << " / word = " << word 3096 << std::hex << " / PTE1 = " << entry << std::endl; 3097 } 3098 #endif 3099 3100 } 3101 else if (entry & PTE_T_MASK ) // PTD : me must access PT2 3103 3102 { 3104 3103 // mark the cache line ac containing a PTD 3105 r_dcache_contains_ptd[m_dcache_sets *way+set] = true;3104 r_dcache_contains_ptd[m_dcache_sets * way + set] = true; 3106 3105 3107 3106 // register bypass 3108 if ( r_dcache_tlb_ins.read() )// itlb3107 if (r_dcache_tlb_ins.read()) // itlb 3109 3108 { 3110 3109 r_itlb.set_bypass(r_dcache_tlb_vaddr.read(), 3111 3110 entry & ((1 << (m_paddr_nbits-PAGE_K_NBITS)) - 1), 3112 r_dcache_tlb_paddr.read() / (m_icache_words <<2));3111 r_dcache_tlb_paddr.read() / (m_icache_words << 2)); 3113 3112 } 3114 else 3113 else // dtlb 3115 3114 { 3116 3115 r_dtlb.set_bypass(r_dcache_tlb_vaddr.read(), 3117 3116 entry & ((1 << (m_paddr_nbits-PAGE_K_NBITS)) - 1), 3118 r_dcache_tlb_paddr.read() / (m_dcache_words <<2));3117 r_dcache_tlb_paddr.read() / (m_dcache_words << 2)); 3119 3118 } 3120 3119 r_dcache_tlb_paddr = 3121 (paddr_t)(entry & ((1 <<(m_paddr_nbits-PAGE_K_NBITS))-1)) << PAGE_K_NBITS |3120 (paddr_t)(entry & ((1 << (m_paddr_nbits - PAGE_K_NBITS)) - 1)) << PAGE_K_NBITS | 3122 3121 (paddr_t)(((r_dcache_tlb_vaddr.read() & PTD_ID2_MASK) >> PAGE_K_NBITS) << 3); 3123 r_dcache_fsm 3122 r_dcache_fsm = DCACHE_TLB_PTE2_GET; 3124 3123 3125 3124 #if DEBUG_DCACHE 3126 if ( m_debug_dcache_fsm)3127 {3128 std::cout << " <PROC " << name()3129 << " DCACHE_TLB_PTE1_GET> HIT in dcache"3130 << std::hex << " / paddr = " << r_dcache_tlb_paddr.read()3131 << std::dec << " / way = " << way3132 << std::dec << " / set = " << set3133 << std::dec << " / word = " << word3134 << std::hex << " / PTD = " << entry << std::endl;3135 }3136 #endif 3137 } 3138 else 3139 { 3140 r_dcache_in_tlb[m_icache_sets *way+set] = true;3125 if (m_debug_dcache_fsm) 3126 { 3127 std::cout << " <PROC " << name() 3128 << " DCACHE_TLB_PTE1_GET> HIT in dcache" 3129 << std::hex << " / paddr = " << r_dcache_tlb_paddr.read() 3130 << std::dec << " / way = " << way 3131 << std::dec << " / set = " << set 3132 << std::dec << " / word = " << word 3133 << std::hex << " / PTD = " << entry << std::endl; 3134 } 3135 #endif 3136 } 3137 else // PTE1 : we must update the TLB 3138 { 3139 r_dcache_in_tlb[m_icache_sets * way + set] = true; 3141 3140 r_dcache_tlb_pte_flags = entry; 3142 3141 r_dcache_tlb_cache_way = way; … … 3146 3145 3147 3146 #if DEBUG_DCACHE 3148 if ( m_debug_dcache_fsm)3149 {3150 std::cout << " <PROC " << name()3151 << " DCACHE_TLB_PTE1_GET> HIT in dcache"3152 << std::hex << " / paddr = " << r_dcache_tlb_paddr.read()3153 << std::dec << " / way = " << way3154 << std::dec << " / set = " << set3155 << std::dec << " / word = " << word3156 << std::hex << " / PTE1 = " << entry << std::endl;3157 }3158 #endif 3159 } 3160 } 3161 else if ( cache_state == CACHE_SLOT_STATE_ZOMBI) // pending cleanup3147 if (m_debug_dcache_fsm) 3148 { 3149 std::cout << " <PROC " << name() 3150 << " DCACHE_TLB_PTE1_GET> HIT in dcache" 3151 << std::hex << " / paddr = " << r_dcache_tlb_paddr.read() 3152 << std::dec << " / way = " << way 3153 << std::dec << " / set = " << set 3154 << std::dec << " / word = " << word 3155 << std::hex << " / PTE1 = " << entry << std::endl; 3156 } 3157 #endif 3158 } 3159 } 3160 else if (cache_state == CACHE_SLOT_STATE_ZOMBI) // pending cleanup 3162 3161 { 3163 3162 // stalled until cleanup is acknowledged 3164 r_dcache_fsm 3165 } 3166 else 3167 { 3168 r_dcache_vci_miss_req 3169 r_dcache_vci_paddr 3170 r_dcache_save_paddr 3171 r_dcache_miss_type 3172 r_dcache_fsm 3163 r_dcache_fsm = DCACHE_TLB_PTE1_GET; 3164 } 3165 else // we must load the missing cache line in dcache 3166 { 3167 r_dcache_vci_miss_req = true; 3168 r_dcache_vci_paddr = r_dcache_tlb_paddr.read(); 3169 r_dcache_save_paddr = r_dcache_tlb_paddr.read(); 3170 r_dcache_miss_type = PTE1_MISS; 3171 r_dcache_fsm = DCACHE_MISS_SELECT; 3173 3172 3174 3173 #if DEBUG_DCACHE 3175 if ( m_debug_dcache_fsm)3176 {3177 std::cout << " <PROC " << name()3178 << " DCACHE_TLB_PTE1_GET> MISS in dcache:"3179 << " PTE1 address = " << std::hex << r_dcache_tlb_paddr.read() << std::endl;3180 }3174 if (m_debug_dcache_fsm) 3175 { 3176 std::cout << " <PROC " << name() 3177 << " DCACHE_TLB_PTE1_GET> MISS in dcache:" 3178 << " PTE1 address = " << std::hex << r_dcache_tlb_paddr.read() << std::endl; 3179 } 3181 3180 #endif 3182 3181 } … … 3184 3183 } 3185 3184 //////////////////////////// 3186 case DCACHE_TLB_PTE1_SELECT: 3187 { 3188 size_t 3189 size_t 3190 3191 if ( r_dcache_tlb_ins.read())3192 { 3193 r_itlb.select( 3194 3195 3196 &set);3185 case DCACHE_TLB_PTE1_SELECT: // select a slot for PTE1 3186 { 3187 size_t way; 3188 size_t set; 3189 3190 if (r_dcache_tlb_ins.read()) 3191 { 3192 r_itlb.select(r_dcache_tlb_vaddr.read(), 3193 true, // PTE1 3194 &way, 3195 &set); 3197 3196 #ifdef INSTRUMENTATION 3198 m_cpt_itlb_read++;3197 m_cpt_itlb_read++; 3199 3198 #endif 3200 3199 } 3201 3200 else 3202 3201 { 3203 r_dtlb.select( 3204 3205 3206 &set);3202 r_dtlb.select(r_dcache_tlb_vaddr.read(), 3203 true, // PTE1 3204 &way, 3205 &set); 3207 3206 #ifdef INSTRUMENTATION 3208 m_cpt_dtlb_read++;3207 m_cpt_dtlb_read++; 3209 3208 #endif 3210 3209 } … … 3214 3213 3215 3214 #if DEBUG_DCACHE 3216 if ( m_debug_dcache_fsm)3217 {3218 if ( r_dcache_tlb_ins.read())3219 std::cout << " <PROC " << name()3220 << " DCACHE_TLB_PTE1_SELECT> Select a slot in ITLB:";3221 else3222 std::cout << " <PROC " << name()3223 << ".DCACHE_TLB_PTE1_SELECT> Select a slot in DTLB:";3224 std::cout << " way = " << std::dec << way3225 3226 }3215 if (m_debug_dcache_fsm) 3216 { 3217 if (r_dcache_tlb_ins.read()) 3218 std::cout << " <PROC " << name() 3219 << " DCACHE_TLB_PTE1_SELECT> Select a slot in ITLB:"; 3220 else 3221 std::cout << " <PROC " << name() 3222 << ".DCACHE_TLB_PTE1_SELECT> Select a slot in DTLB:"; 3223 std::cout << " way = " << std::dec << way 3224 << " / set = " << set << std::endl; 3225 } 3227 3226 #endif 3228 3227 break; 3229 3228 } 3230 3229 ////////////////////////// 3231 case DCACHE_TLB_PTE1_UPDT: 3230 case DCACHE_TLB_PTE1_UPDT: // write a new PTE1 in tlb after testing the L/R bit 3232 3231 // - if L/R bit already set, exit the sub-fsm. 3233 3232 // - if not, we update the page table but we dont write … … 3235 3234 // the coherence mechanism. 3236 3235 { 3237 paddr_t nline = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words)+2);3238 uint32_t pte= r_dcache_tlb_pte_flags.read();3239 bool 3240 bool 3236 paddr_t nline = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words) + 2); 3237 uint32_t pte = r_dcache_tlb_pte_flags.read(); 3238 bool pt_updt = false; 3239 bool local = true; 3241 3240 3242 3241 // We should compute the access locality: … … 3247 3246 // As long as this computation is not done, all access are local. 3248 3247 3249 if ( local )// local access3250 { 3251 if ( not ((pte & PTE_L_MASK) == PTE_L_MASK)) // we must set the L bit3248 if (local) // local access 3249 { 3250 if (not ((pte & PTE_L_MASK) == PTE_L_MASK)) // we must set the L bit 3252 3251 { 3253 3252 pt_updt = true; 3254 r_dcache_vci_cas_old 3255 r_dcache_vci_cas_new 3253 r_dcache_vci_cas_old = pte; 3254 r_dcache_vci_cas_new = pte | PTE_L_MASK; 3256 3255 pte = pte | PTE_L_MASK; 3257 3256 r_dcache_tlb_pte_flags = pte; 3258 3257 } 3259 3258 } 3260 else 3261 { 3262 if ( not ((pte & PTE_R_MASK) == PTE_R_MASK)) // we must set the R bit3259 else // remote access 3260 { 3261 if (not ((pte & PTE_R_MASK) == PTE_R_MASK)) // we must set the R bit 3263 3262 { 3264 3263 pt_updt = true; 3265 r_dcache_vci_cas_old 3266 r_dcache_vci_cas_new 3264 r_dcache_vci_cas_old = pte; 3265 r_dcache_vci_cas_new = pte | PTE_R_MASK; 3267 3266 pte = pte | PTE_R_MASK; 3268 3267 r_dcache_tlb_pte_flags = pte; … … 3270 3269 } 3271 3270 3272 if ( not pt_updt )// update TLB and return3273 { 3274 if ( r_dcache_tlb_ins.read())3275 { 3276 r_itlb.write( true,// 2M page3277 3278 0,// argument unused for a PTE13279 3280 3281 3282 nline);3271 if (not pt_updt) // update TLB and return 3272 { 3273 if (r_dcache_tlb_ins.read()) 3274 { 3275 r_itlb.write(true, // 2M page 3276 pte, 3277 0, // argument unused for a PTE1 3278 r_dcache_tlb_vaddr.read(), 3279 r_dcache_tlb_way.read(), 3280 r_dcache_tlb_set.read(), 3281 nline); 3283 3282 #ifdef INSTRUMENTATION 3284 m_cpt_itlb_write++;3283 m_cpt_itlb_write++; 3285 3284 #endif 3286 3285 3287 3286 #if DEBUG_DCACHE 3288 if ( m_debug_dcache_fsm)3289 {3290 std::cout << " <PROC " << name()3291 << " DCACHE_TLB_PTE1_UPDT> write PTE1 in ITLB"3292 << " / set = " << std::dec << r_dcache_tlb_set.read()3293 << " / way = " << r_dcache_tlb_way.read() << std::endl;3294 r_itlb.printTrace();3295 }3287 if (m_debug_dcache_fsm) 3288 { 3289 std::cout << " <PROC " << name() 3290 << " DCACHE_TLB_PTE1_UPDT> write PTE1 in ITLB" 3291 << " / set = " << std::dec << r_dcache_tlb_set.read() 3292 << " / way = " << r_dcache_tlb_way.read() << std::endl; 3293 r_itlb.printTrace(); 3294 } 3296 3295 #endif 3297 3296 } 3298 3297 else 3299 3298 { 3300 r_dtlb.write( true,// 2M page3301 3302 0,// argument unused for a PTE13303 3304 3305 3306 nline);3299 r_dtlb.write(true, // 2M page 3300 pte, 3301 0, // argument unused for a PTE1 3302 r_dcache_tlb_vaddr.read(), 3303 r_dcache_tlb_way.read(), 3304 r_dcache_tlb_set.read(), 3305 nline); 3307 3306 #ifdef INSTRUMENTATION 3308 m_cpt_dtlb_write++;3307 m_cpt_dtlb_write++; 3309 3308 #endif 3310 3309 3311 3310 #if DEBUG_DCACHE 3312 if ( m_debug_dcache_fsm)3313 {3314 std::cout << " <PROC " << name()3315 << " DCACHE_TLB_PTE1_UPDT> write PTE1 in DTLB"3316 << " / set = " << std::dec << r_dcache_tlb_set.read()3317 << " / way = " << r_dcache_tlb_way.read() << std::endl;3318 r_dtlb.printTrace();3319 }3311 if (m_debug_dcache_fsm) 3312 { 3313 std::cout << " <PROC " << name() 3314 << " DCACHE_TLB_PTE1_UPDT> write PTE1 in DTLB" 3315 << " / set = " << std::dec << r_dcache_tlb_set.read() 3316 << " / way = " << r_dcache_tlb_way.read() << std::endl; 3317 r_dtlb.printTrace(); 3318 } 3320 3319 #endif 3321 3320 } … … 3327 3326 3328 3327 #if DEBUG_DCACHE 3329 if ( m_debug_dcache_fsm)3330 {3331 std::cout << " <PROC " << name()3332 << " DCACHE_TLB_PTE1_UPDT> L/R bit update required"3333 << std::endl;3334 }3328 if (m_debug_dcache_fsm) 3329 { 3330 std::cout << " <PROC " << name() 3331 << " DCACHE_TLB_PTE1_UPDT> L/R bit update required" 3332 << std::endl; 3333 } 3335 3334 #endif 3336 3335 } … … 3338 3337 } 3339 3338 ///////////////////////// 3340 case DCACHE_TLB_PTE2_GET: 3339 case DCACHE_TLB_PTE2_GET: // Try to get a PTE2 (64 bits) in the dcache 3341 3340 { 3342 3341 // coherence clack request (from DSPIN CLACK) 3343 if ( r_dcache_clack_req.read())3342 if (r_dcache_clack_req.read()) 3344 3343 { 3345 3344 r_dcache_fsm = DCACHE_CC_CHECK; … … 3349 3348 3350 3349 // coherence request (from CC_RECEIVE FSM) 3351 if ( 3350 if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 3352 3351 { 3353 3352 r_dcache_fsm = DCACHE_CC_CHECK; … … 3356 3355 } 3357 3356 3358 uint32_t 3359 uint32_t 3360 size_t 3361 size_t 3362 size_t 3363 int 3364 3365 r_dcache.read( 3366 3367 3368 3369 3370 3371 &cache_state);3357 uint32_t pte_flags; 3358 uint32_t pte_ppn; 3359 size_t way; 3360 size_t set; 3361 size_t word; 3362 int cache_state; 3363 3364 r_dcache.read(r_dcache_tlb_paddr.read(), 3365 &pte_flags, 3366 &pte_ppn, 3367 &way, 3368 &set, 3369 &word, 3370 &cache_state); 3372 3371 #ifdef INSTRUMENTATION 3373 m_cpt_dcache_data_read++;3374 m_cpt_dcache_dir_read++;3375 #endif 3376 if ( cache_state == CACHE_SLOT_STATE_VALID )// hit in dcache3377 { 3378 if ( not (pte_flags & PTE_V_MASK) )// unmapped3379 { 3380 if ( r_dcache_tlb_ins.read())3372 m_cpt_dcache_data_read++; 3373 m_cpt_dcache_dir_read++; 3374 #endif 3375 if (cache_state == CACHE_SLOT_STATE_VALID) // hit in dcache 3376 { 3377 if (not (pte_flags & PTE_V_MASK)) // unmapped 3378 { 3379 if (r_dcache_tlb_ins.read()) 3381 3380 { 3382 3381 r_mmu_ietr = MMU_READ_PT2_UNMAPPED; … … 3387 3386 else 3388 3387 { 3389 r_mmu_detr 3390 r_mmu_dbvar 3391 m_drsp.valid 3392 m_drsp.error 3388 r_mmu_detr = MMU_READ_PT2_UNMAPPED; 3389 r_mmu_dbvar = r_dcache_tlb_vaddr.read(); 3390 m_drsp.valid = true; 3391 m_drsp.error = true; 3393 3392 } 3394 r_dcache_fsm 3393 r_dcache_fsm = DCACHE_IDLE; 3395 3394 3396 3395 #if DEBUG_DCACHE 3397 if ( m_debug_dcache_fsm)3398 {3399 std::cout << " <PROC " << name()3400 << " DCACHE_TLB_PTE2_GET> HIT in dcache, but PTE unmapped"3401 << " PTE_FLAGS = " << std::hex << pte_flags3402 << " PTE_PPN = " << std::hex << pte_ppn << std::endl;3403 }3404 #endif 3405 } 3406 else 3407 { 3408 r_dcache_in_tlb[m_dcache_sets *way+set] = true;3396 if (m_debug_dcache_fsm) 3397 { 3398 std::cout << " <PROC " << name() 3399 << " DCACHE_TLB_PTE2_GET> HIT in dcache, but PTE unmapped" 3400 << " PTE_FLAGS = " << std::hex << pte_flags 3401 << " PTE_PPN = " << std::hex << pte_ppn << std::endl; 3402 } 3403 #endif 3404 } 3405 else // mapped : we must update the TLB 3406 { 3407 r_dcache_in_tlb[m_dcache_sets * way + set] = true; 3409 3408 r_dcache_tlb_pte_flags = pte_flags; 3410 3409 r_dcache_tlb_pte_ppn = pte_ppn; … … 3415 3414 3416 3415 #if DEBUG_DCACHE 3417 if ( m_debug_dcache_fsm)3418 {3419 std::cout << " <PROC " << name()3420 << " DCACHE_TLB_PTE2_GET> HIT in dcache:"3421 << " PTE_FLAGS = " << std::hex << pte_flags3422 << " PTE_PPN = " << std::hex << pte_ppn << std::endl;3423 }3416 if (m_debug_dcache_fsm) 3417 { 3418 std::cout << " <PROC " << name() 3419 << " DCACHE_TLB_PTE2_GET> HIT in dcache:" 3420 << " PTE_FLAGS = " << std::hex << pte_flags 3421 << " PTE_PPN = " << std::hex << pte_ppn << std::endl; 3422 } 3424 3423 #endif 3425 3424 } 3426 3425 } 3427 else if ( cache_state == CACHE_SLOT_STATE_ZOMBI) // pending cleanup3426 else if (cache_state == CACHE_SLOT_STATE_ZOMBI) // pending cleanup 3428 3427 { 3429 3428 // stalled until cleanup is acknowledged … … 3431 3430 3432 3431 #if DEBUG_DCACHE 3433 if ( m_debug_dcache_fsm)3434 {3435 std::cout << " <PROC " << name()3436 << " DCACHE_TLB_PTE2_GET> ZOMBI in dcache: waiting cleanup ack"3437 << std::endl;3438 }3432 if (m_debug_dcache_fsm) 3433 { 3434 std::cout << " <PROC " << name() 3435 << " DCACHE_TLB_PTE2_GET> ZOMBI in dcache: waiting cleanup ack" 3436 << std::endl; 3437 } 3439 3438 #endif 3440 3439 } … … 3448 3447 3449 3448 #if DEBUG_DCACHE 3450 if ( m_debug_dcache_fsm)3451 {3452 std::cout << " <PROC " << name()3453 << " DCACHE_TLB_PTE2_GET> MISS in dcache:"3454 << " PTE address = " << std::hex << r_dcache_tlb_paddr.read() << std::endl;3455 }3449 if (m_debug_dcache_fsm) 3450 { 3451 std::cout << " <PROC " << name() 3452 << " DCACHE_TLB_PTE2_GET> MISS in dcache:" 3453 << " PTE address = " << std::hex << r_dcache_tlb_paddr.read() << std::endl; 3454 } 3456 3455 #endif 3457 3456 } … … 3464 3463 size_t set; 3465 3464 3466 if ( r_dcache_tlb_ins.read())3467 { 3468 r_itlb.select( 3469 false,// PTE23470 3471 &set);3465 if (r_dcache_tlb_ins.read()) 3466 { 3467 r_itlb.select(r_dcache_tlb_vaddr.read(), 3468 false, // PTE2 3469 &way, 3470 &set); 3472 3471 #ifdef INSTRUMENTATION 3473 m_cpt_itlb_read++;3472 m_cpt_itlb_read++; 3474 3473 #endif 3475 3474 } 3476 3475 else 3477 3476 { 3478 r_dtlb.select( 3479 false,// PTE23480 3481 &set);3477 r_dtlb.select(r_dcache_tlb_vaddr.read(), 3478 false, // PTE2 3479 &way, 3480 &set); 3482 3481 #ifdef INSTRUMENTATION 3483 m_cpt_dtlb_read++;3482 m_cpt_dtlb_read++; 3484 3483 #endif 3485 3484 } 3486 3485 3487 3486 #if DEBUG_DCACHE 3488 if ( m_debug_dcache_fsm)3489 {3490 if ( r_dcache_tlb_ins.read())3491 std::cout << " <PROC " << name()3492 << " DCACHE_TLB_PTE2_SELECT> Select a slot in ITLB:";3493 else3494 std::cout << " <PROC " << name()3495 << " DCACHE_TLB_PTE2_SELECT> Select a slot in DTLB:";3496 std::cout << " way = " << std::dec << way3497 3498 }3487 if (m_debug_dcache_fsm) 3488 { 3489 if (r_dcache_tlb_ins.read()) 3490 std::cout << " <PROC " << name() 3491 << " DCACHE_TLB_PTE2_SELECT> Select a slot in ITLB:"; 3492 else 3493 std::cout << " <PROC " << name() 3494 << " DCACHE_TLB_PTE2_SELECT> Select a slot in DTLB:"; 3495 std::cout << " way = " << std::dec << way 3496 << " / set = " << set << std::endl; 3497 } 3499 3498 #endif 3500 3499 r_dcache_tlb_way = way; … … 3504 3503 } 3505 3504 ////////////////////////// 3506 case DCACHE_TLB_PTE2_UPDT: 3505 case DCACHE_TLB_PTE2_UPDT: // write a new PTE2 in tlb after testing the L/R bit 3507 3506 // - if L/R bit already set, exit the sub-fsm. 3508 3507 // - if not, we update the page table but we dont write … … 3510 3509 // the coherence mechanism. 3511 3510 { 3512 paddr_t nline = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words)+2);3513 uint32_t 3514 uint32_t 3515 bool 3516 bool 3511 paddr_t nline = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words) + 2); 3512 uint32_t pte_flags = r_dcache_tlb_pte_flags.read(); 3513 uint32_t pte_ppn = r_dcache_tlb_pte_ppn.read(); 3514 bool pt_updt = false; 3515 bool local = true; 3517 3516 3518 3517 // We should compute the access locality: … … 3523 3522 // As long as this computation is not done, all access are local. 3524 3523 3525 if ( local )// local access3526 { 3527 if ( not ((pte_flags & PTE_L_MASK) == PTE_L_MASK)) // we must set the L bit3524 if (local) // local access 3525 { 3526 if (not ((pte_flags & PTE_L_MASK) == PTE_L_MASK)) // we must set the L bit 3528 3527 { 3529 3528 pt_updt = true; … … 3531 3530 r_dcache_vci_cas_new = pte_flags | PTE_L_MASK; 3532 3531 pte_flags = pte_flags | PTE_L_MASK; 3533 3532 r_dcache_tlb_pte_flags = pte_flags; 3534 3533 } 3535 3534 } 3536 3535 else // remote access 3537 3536 { 3538 if ( not ((pte_flags & PTE_R_MASK) == PTE_R_MASK)) // we must set the R bit3537 if (not ((pte_flags & PTE_R_MASK) == PTE_R_MASK)) // we must set the R bit 3539 3538 { 3540 3539 pt_updt = true; … … 3542 3541 r_dcache_vci_cas_new = pte_flags | PTE_R_MASK; 3543 3542 pte_flags = pte_flags | PTE_R_MASK; 3544 3545 } 3546 } 3547 3548 if ( not pt_updt )// update TLB3549 { 3550 if ( r_dcache_tlb_ins.read())3551 { 3552 r_itlb.write( false, 3543 r_dcache_tlb_pte_flags = pte_flags; 3544 } 3545 } 3546 3547 if (not pt_updt) // update TLB 3548 { 3549 if (r_dcache_tlb_ins.read()) 3550 { 3551 r_itlb.write( false, // 4K page 3553 3552 pte_flags, 3554 3553 pte_ppn, … … 3558 3557 nline ); 3559 3558 #ifdef INSTRUMENTATION 3560 m_cpt_itlb_write++;3559 m_cpt_itlb_write++; 3561 3560 #endif 3562 3561 3563 3562 #if DEBUG_DCACHE 3564 if ( m_debug_dcache_fsm)3565 {3566 std::cout << " <PROC " << name()3567 << " DCACHE_TLB_PTE2_UPDT> write PTE2 in ITLB"3568 << " / set = " << std::dec << r_dcache_tlb_set.read()3569 << " / way = " << r_dcache_tlb_way.read() << std::endl;3570 r_itlb.printTrace();3571 }3563 if (m_debug_dcache_fsm) 3564 { 3565 std::cout << " <PROC " << name() 3566 << " DCACHE_TLB_PTE2_UPDT> write PTE2 in ITLB" 3567 << " / set = " << std::dec << r_dcache_tlb_set.read() 3568 << " / way = " << r_dcache_tlb_way.read() << std::endl; 3569 r_itlb.printTrace(); 3570 } 3572 3571 #endif 3573 3572 } 3574 3573 else 3575 3574 { 3576 r_dtlb.write( false,// 4K page3577 3578 3579 3580 3581 3582 nline);3575 r_dtlb.write(false, // 4K page 3576 pte_flags, 3577 pte_ppn, 3578 r_dcache_tlb_vaddr.read(), 3579 r_dcache_tlb_way.read(), 3580 r_dcache_tlb_set.read(), 3581 nline); 3583 3582 #ifdef INSTRUMENTATION 3584 m_cpt_dtlb_write++;3583 m_cpt_dtlb_write++; 3585 3584 #endif 3586 3585 3587 3586 #if DEBUG_DCACHE 3588 if ( m_debug_dcache_fsm)3589 {3590 std::cout << " <PROC " << name()3591 << " DCACHE_TLB_PTE2_UPDT> write PTE2 in DTLB"3592 << " / set = " << std::dec << r_dcache_tlb_set.read()3593 << " / way = " << r_dcache_tlb_way.read() << std::endl;3594 r_dtlb.printTrace();3595 }3587 if (m_debug_dcache_fsm) 3588 { 3589 std::cout << " <PROC " << name() 3590 << " DCACHE_TLB_PTE2_UPDT> write PTE2 in DTLB" 3591 << " / set = " << std::dec << r_dcache_tlb_set.read() 3592 << " / way = " << r_dcache_tlb_way.read() << std::endl; 3593 r_dtlb.printTrace(); 3594 } 3596 3595 #endif 3597 3596 … … 3601 3600 else // update page table but not TLB 3602 3601 { 3603 r_dcache_fsm = DCACHE_TLB_LR_UPDT; 3602 r_dcache_fsm = DCACHE_TLB_LR_UPDT; // dcache and page table update 3604 3603 3605 3604 #if DEBUG_DCACHE 3606 if ( m_debug_dcache_fsm)3607 {3608 std::cout << " <PROC " << name()3609 << " DCACHE_TLB_PTE2_UPDT> L/R bit update required" << std::endl;3610 }3605 if (m_debug_dcache_fsm) 3606 { 3607 std::cout << " <PROC " << name() 3608 << " DCACHE_TLB_PTE2_UPDT> L/R bit update required" << std::endl; 3609 } 3611 3610 #endif 3612 3611 } … … 3617 3616 { 3618 3617 #if DEBUG_DCACHE 3619 if ( m_debug_dcache_fsm)3620 {3621 std::cout << " <PROC " << name()3622 << " DCACHE_TLB_LR_UPDT> Update dcache: (L/R) bit" << std::endl;3623 }3618 if (m_debug_dcache_fsm) 3619 { 3620 std::cout << " <PROC " << name() 3621 << " DCACHE_TLB_LR_UPDT> Update dcache: (L/R) bit" << std::endl; 3622 } 3624 3623 #endif 3625 3624 // r_dcache_vci_cas_old & r_dcache_vci_cas_new registers are already set … … 3627 3626 3628 3627 // checking llsc reservation buffer 3629 if ( r_dcache_llsc_paddr.read() == r_dcache_tlb_paddr.read())3628 if (r_dcache_llsc_paddr.read() == r_dcache_tlb_paddr.read()) 3630 3629 r_dcache_llsc_valid = false; 3631 3630 3632 3631 // request a CAS CMD and go to DCACHE_TLB_LR_WAIT state 3633 3632 r_dcache_vci_cas_req = true; 3634 r_dcache_fsm 3633 r_dcache_fsm = DCACHE_TLB_LR_WAIT; 3635 3634 break; 3636 3635 } 3637 3636 //////////////////////// 3638 case DCACHE_TLB_LR_WAIT: 3637 case DCACHE_TLB_LR_WAIT: // Waiting the response to SC transaction for DIRTY bit. 3639 3638 // We consume the response in rsp FIFO, 3640 3639 // and exit the sub-fsm, but we don't … … 3646 3645 { 3647 3646 // coherence clack request (from DSPIN CLACK) 3648 if ( r_dcache_clack_req.read())3647 if (r_dcache_clack_req.read()) 3649 3648 { 3650 3649 r_dcache_fsm = DCACHE_CC_CHECK; … … 3654 3653 3655 3654 // coherence request (from CC_RECEIVE FSM) 3656 if ( 3655 if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 3657 3656 { 3658 3657 r_dcache_fsm = DCACHE_CC_CHECK; … … 3661 3660 } 3662 3661 3663 if ( r_vci_rsp_data_error.read() )// bus error3662 if (r_vci_rsp_data_error.read()) // bus error 3664 3663 { 3665 3664 std::cout << "BUS ERROR in DCACHE_TLB_LR_WAIT state" << std::endl; … … 3667 3666 exit(0); 3668 3667 } 3669 else if ( r_vci_rsp_fifo_dcache.rok()) // response available3668 else if (r_vci_rsp_fifo_dcache.rok()) // response available 3670 3669 { 3671 3670 #if DEBUG_DCACHE 3672 if ( m_debug_dcache_fsm)3673 {3674 std::cout << " <PROC " << name()3675 << " DCACHE_TLB_LR_WAIT> SC response received" << std::endl;3676 }3671 if (m_debug_dcache_fsm) 3672 { 3673 std::cout << " <PROC " << name() 3674 << " DCACHE_TLB_LR_WAIT> SC response received" << std::endl; 3675 } 3677 3676 #endif 3678 3677 vci_rsp_fifo_dcache_get = true; 3679 r_dcache_fsm 3678 r_dcache_fsm = DCACHE_TLB_RETURN; 3680 3679 } 3681 3680 break; 3682 3681 } 3683 3682 /////////////////////// 3684 case DCACHE_TLB_RETURN: 3683 case DCACHE_TLB_RETURN: // return to caller depending on tlb miss type 3685 3684 { 3686 3685 #if DEBUG_DCACHE 3687 if ( m_debug_dcache_fsm)3688 {3689 std::cout << " <PROC " << name()3690 << " DCACHE_TLB_RETURN> TLB MISS completed" << std::endl;3691 }3692 #endif 3693 if ( r_dcache_tlb_ins.read()) r_icache_tlb_miss_req = false;3686 if (m_debug_dcache_fsm) 3687 { 3688 std::cout << " <PROC " << name() 3689 << " DCACHE_TLB_RETURN> TLB MISS completed" << std::endl; 3690 } 3691 #endif 3692 if (r_dcache_tlb_ins.read()) r_icache_tlb_miss_req = false; 3694 3693 r_dcache_fsm = DCACHE_IDLE; 3695 3694 break; 3696 3695 } 3697 3696 /////////////////////// 3698 case DCACHE_XTN_SWITCH: 3697 case DCACHE_XTN_SWITCH: // The r_ptpr registers must be written, 3699 3698 // and both itlb and dtlb must be flushed. 3700 3699 // Caution : the itlb miss requests must be taken … … 3704 3703 { 3705 3704 // coherence clack request (from DSPIN CLACK) 3706 if ( r_dcache_clack_req.read())3705 if (r_dcache_clack_req.read()) 3707 3706 { 3708 3707 r_dcache_fsm = DCACHE_CC_CHECK; … … 3712 3711 3713 3712 // coherence request (from CC_RECEIVE FSM) 3714 if ( 3713 if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 3715 3714 { 3716 3715 r_dcache_fsm = DCACHE_CC_CHECK; … … 3720 3719 3721 3720 // itlb miss request 3722 if ( r_icache_tlb_miss_req.read())3723 { 3724 r_dcache_tlb_ins 3725 r_dcache_tlb_vaddr 3726 r_dcache_fsm 3727 break; 3728 } 3729 3730 if ( not r_dcache_xtn_req.read())3721 if (r_icache_tlb_miss_req.read()) 3722 { 3723 r_dcache_tlb_ins = true; 3724 r_dcache_tlb_vaddr = r_icache_vaddr_save.read(); 3725 r_dcache_fsm = DCACHE_TLB_MISS; 3726 break; 3727 } 3728 3729 if (not r_dcache_xtn_req.read()) 3731 3730 { 3732 3731 r_dtlb.flush(); … … 3738 3737 } 3739 3738 ///////////////////// 3740 case DCACHE_XTN_SYNC: 3741 3742 3739 case DCACHE_XTN_SYNC: // waiting until write buffer empty 3740 // The coherence request must be taken 3741 // as there is a risk of dead-lock 3743 3742 { 3744 3743 // coherence clack request (from DSPIN CLACK) 3745 if ( r_dcache_clack_req.read())3744 if (r_dcache_clack_req.read()) 3746 3745 { 3747 3746 r_dcache_fsm = DCACHE_CC_CHECK; … … 3751 3750 3752 3751 // coherence request (from CC_RECEIVE FSM) 3753 if ( 3752 if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 3754 3753 { 3755 3754 r_dcache_fsm = DCACHE_CC_CHECK; … … 3758 3757 } 3759 3758 3760 if ( r_wbuf.empty())3761 { 3762 m_drsp.valid 3759 if (r_wbuf.empty()) 3760 { 3761 m_drsp.valid = true; 3763 3762 r_dcache_fsm = DCACHE_IDLE; 3764 3763 } … … 3774 3773 { 3775 3774 // coherence clack request (from DSPIN CLACK) 3776 if ( r_dcache_clack_req.read())3775 if (r_dcache_clack_req.read()) 3777 3776 { 3778 3777 r_dcache_fsm = DCACHE_CC_CHECK; … … 3782 3781 3783 3782 // coherence request (from CC_RECEIVE FSM) 3784 if ( 3783 if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 3785 3784 { 3786 3785 r_dcache_fsm = DCACHE_CC_CHECK; … … 3790 3789 3791 3790 // itlb miss request 3792 if ( r_icache_tlb_miss_req.read())3793 { 3794 r_dcache_tlb_ins 3795 r_dcache_tlb_vaddr 3796 r_dcache_fsm 3791 if (r_icache_tlb_miss_req.read()) 3792 { 3793 r_dcache_tlb_ins = true; 3794 r_dcache_tlb_vaddr = r_icache_vaddr_save.read(); 3795 r_dcache_fsm = DCACHE_TLB_MISS; 3797 3796 break; 3798 3797 } 3799 3798 3800 3799 // test if XTN request to icache completed 3801 if ( not r_dcache_xtn_req.read())3800 if (not r_dcache_xtn_req.read()) 3802 3801 { 3803 3802 r_dcache_fsm = DCACHE_IDLE; … … 3807 3806 } 3808 3807 ///////////////////////// 3809 case DCACHE_XTN_DC_FLUSH: 3808 case DCACHE_XTN_DC_FLUSH: // Invalidate sequencially all cache lines, using 3810 3809 // r_dcache_flush_count as a slot counter, 3811 3810 // looping in this state until all slots have been visited. … … 3817 3816 { 3818 3817 // coherence clack request (from DSPIN CLACK) 3819 if ( r_dcache_clack_req.read())3818 if (r_dcache_clack_req.read()) 3820 3819 { 3821 3820 r_dcache_fsm = DCACHE_CC_CHECK; … … 3825 3824 3826 3825 // coherence request (from CC_RECEIVE FSM) 3827 if ( 3826 if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 3828 3827 { 3829 3828 r_dcache_fsm = DCACHE_CC_CHECK; … … 3832 3831 } 3833 3832 3834 if ( not r_dcache_cc_send_req.read()) // blocked until previous cc_send request is sent3835 { 3836 int 3837 paddr_t 3838 size_t 3839 size_t 3833 if (not r_dcache_cc_send_req.read()) // blocked until previous cc_send request is sent 3834 { 3835 int state; 3836 paddr_t tag; 3837 size_t way = r_dcache_flush_count.read()/m_dcache_sets; 3838 size_t set = r_dcache_flush_count.read()%m_dcache_sets; 3840 3839 3841 3840 #ifdef INSTRUMENTATION 3842 m_cpt_dcache_dir_read++;3843 #endif 3844 r_dcache.read_dir( 3845 3846 3847 &state);3848 3849 if ( state == CACHE_SLOT_STATE_VALID )// inval required3841 m_cpt_dcache_dir_read++; 3842 #endif 3843 r_dcache.read_dir(way, 3844 set, 3845 &tag, 3846 &state); 3847 3848 if (state == CACHE_SLOT_STATE_VALID) // inval required 3850 3849 { 3851 3850 // request cleanup … … 3856 3855 3857 3856 // goes to DCACHE_XTN_DC_FLUSH_GO to inval directory 3858 r_dcache_miss_way 3859 r_dcache_miss_set 3860 r_dcache_fsm 3861 } 3862 else if ( 3863 (m_dcache_sets*m_dcache_ways - 1) 3857 r_dcache_miss_way = way; 3858 r_dcache_miss_set = set; 3859 r_dcache_fsm = DCACHE_XTN_DC_FLUSH_GO; 3860 } 3861 else if (r_dcache_flush_count.read() == 3862 (m_dcache_sets*m_dcache_ways - 1)) // last slot 3864 3863 { 3865 3864 r_dtlb.reset(); … … 3870 3869 3871 3870 // saturation counter 3872 if ( r_dcache_flush_count.read() < (m_dcache_sets*m_dcache_ways - 1))3871 if (r_dcache_flush_count.read() < (m_dcache_sets * m_dcache_ways - 1)) 3873 3872 r_dcache_flush_count = r_dcache_flush_count.read() + 1; 3874 3873 } … … 3883 3882 size_t set = r_dcache_miss_set.read(); 3884 3883 3885 r_dcache_in_tlb[m_dcache_sets *way+set] = false;3886 r_dcache_contains_ptd[m_dcache_sets *way+set] = false;3884 r_dcache_in_tlb[m_dcache_sets * way + set] = false; 3885 r_dcache_contains_ptd[m_dcache_sets * way + set] = false; 3887 3886 3888 3887 #ifdef INSTRUMENTATION 3889 m_cpt_dcache_dir_write++;3890 #endif 3891 r_dcache.write_dir( 3892 3893 CACHE_SLOT_STATE_ZOMBI);3894 3895 if ( 3896 (m_dcache_sets*m_dcache_ways - 1) 3888 m_cpt_dcache_dir_write++; 3889 #endif 3890 r_dcache.write_dir(way, 3891 set, 3892 CACHE_SLOT_STATE_ZOMBI); 3893 3894 if (r_dcache_flush_count.read() == 3895 (m_dcache_sets*m_dcache_ways - 1)) // last slot 3897 3896 { 3898 3897 r_dtlb.reset(); … … 3908 3907 } 3909 3908 ///////////////////////// 3910 case DCACHE_XTN_DT_INVAL: 3909 case DCACHE_XTN_DT_INVAL: // handling processor XTN_DTLB_INVAL request 3911 3910 { 3912 3911 r_dtlb.inval(r_dcache_save_wdata.read()); 3913 r_dcache_fsm 3914 m_drsp.valid 3912 r_dcache_fsm = DCACHE_IDLE; 3913 m_drsp.valid = true; 3915 3914 break; 3916 3915 } … … 3918 3917 case DCACHE_XTN_DC_INVAL_VA: // selective cache line invalidate with virtual address 3919 3918 // requires 3 cycles: access tlb, read cache, inval cache 3920 3919 // we compute the physical address in this state 3921 3920 { 3922 3921 paddr_t paddr; 3923 bool 3924 3925 if ( r_mmu_mode.read() & DATA_TLB_MASK )// dtlb activated3922 bool hit; 3923 3924 if (r_mmu_mode.read() & DATA_TLB_MASK) // dtlb activated 3926 3925 { 3927 3926 3928 3927 #ifdef INSTRUMENTATION 3929 m_cpt_dtlb_read++;3930 #endif 3931 hit = r_dtlb.translate( 3932 &paddr);3933 } 3934 else 3928 m_cpt_dtlb_read++; 3929 #endif 3930 hit = r_dtlb.translate(r_dcache_save_wdata.read(), 3931 &paddr); 3932 } 3933 else // dtlb not activated 3935 3934 { 3936 3935 paddr = (paddr_t)r_dcache_save_wdata.read(); 3937 3936 if (vci_param::N > 32) 3938 3937 paddr = paddr | ((paddr_t)(r_dcache_paddr_ext.read()) << 32); 3939 hit 3940 } 3941 3942 if ( hit )// tlb hit3938 hit = true; 3939 } 3940 3941 if (hit) // tlb hit 3943 3942 { 3944 3943 r_dcache_save_paddr = paddr; 3945 r_dcache_fsm 3946 } 3947 else 3948 3944 r_dcache_fsm = DCACHE_XTN_DC_INVAL_PA; 3945 } 3946 else // tlb miss 3947 { 3949 3948 3950 3949 #ifdef INSTRUMENTATION 3951 m_cpt_dtlb_miss++;3952 #endif 3953 r_dcache_tlb_ins = false;// dtlb3954 r_dcache_tlb_vaddr 3955 r_dcache_fsm 3950 m_cpt_dtlb_miss++; 3951 #endif 3952 r_dcache_tlb_ins = false; // dtlb 3953 r_dcache_tlb_vaddr = r_dcache_save_wdata.read(); 3954 r_dcache_fsm = DCACHE_TLB_MISS; 3956 3955 } 3957 3956 3958 3957 #if DEBUG_DCACHE 3959 if ( m_debug_dcache_fsm)3960 {3961 std::cout << " <PROC " << name()3962 << " DCACHE_XTN_DC_INVAL_VA> Compute physical address" << std::hex3963 << " / VADDR = " << r_dcache_save_wdata.read()3964 << " / PADDR = " << paddr << std::endl;3965 }3958 if (m_debug_dcache_fsm) 3959 { 3960 std::cout << " <PROC " << name() 3961 << " DCACHE_XTN_DC_INVAL_VA> Compute physical address" << std::hex 3962 << " / VADDR = " << r_dcache_save_wdata.read() 3963 << " / PADDR = " << paddr << std::endl; 3964 } 3966 3965 #endif 3967 3966 … … 3973 3972 // In this state we read dcache. 3974 3973 { 3975 size_t 3976 size_t 3977 size_t 3978 int 3974 size_t way; 3975 size_t set; 3976 size_t word; 3977 int state; 3979 3978 3980 3979 #ifdef INSTRUMENTATION 3981 m_cpt_dcache_dir_read++;3982 #endif 3983 r_dcache.read_dir( 3984 3985 3986 3987 &word);3988 3989 if ( state == CACHE_SLOT_STATE_VALID )// inval to be done3980 m_cpt_dcache_dir_read++; 3981 #endif 3982 r_dcache.read_dir(r_dcache_save_paddr.read(), 3983 &state, 3984 &way, 3985 &set, 3986 &word); 3987 3988 if (state == CACHE_SLOT_STATE_VALID) // inval to be done 3990 3989 { 3991 3990 r_dcache_xtn_way = way; 3992 3991 r_dcache_xtn_set = set; 3993 r_dcache_fsm 3994 } 3995 else 3996 { 3997 r_dcache_fsm 3998 m_drsp.valid 3992 r_dcache_fsm = DCACHE_XTN_DC_INVAL_GO; 3993 } 3994 else // miss : nothing to do 3995 { 3996 r_dcache_fsm = DCACHE_IDLE; 3997 m_drsp.valid = true; 3999 3998 } 4000 3999 4001 4000 #if DEBUG_DCACHE 4002 if ( m_debug_dcache_fsm)4003 {4004 std::cout << " <PROC " << name()4005 << " DCACHE_XTN_DC_INVAL_PA> Test hit in dcache" << std::hex4006 << " / PADDR = " << r_dcache_save_paddr.read() << std::dec4007 << " / HIT = " << (state == CACHE_SLOT_STATE_VALID)4008 << " / SET = " << set4009 << " / WAY = " << way << std::endl;4010 }4001 if (m_debug_dcache_fsm) 4002 { 4003 std::cout << " <PROC " << name() 4004 << " DCACHE_XTN_DC_INVAL_PA> Test hit in dcache" << std::hex 4005 << " / PADDR = " << r_dcache_save_paddr.read() << std::dec 4006 << " / HIT = " << (state == CACHE_SLOT_STATE_VALID) 4007 << " / SET = " << set 4008 << " / WAY = " << way << std::endl; 4009 } 4011 4010 #endif 4012 4011 break; … … 4014 4013 //////////////////////////// 4015 4014 case DCACHE_XTN_DC_INVAL_GO: // In this state, we invalidate the cache line 4016 4015 // Blocked if previous cleanup not completed 4017 4016 // Test if itlb or dtlb inval is required 4018 4017 { 4019 if ( not r_dcache_cc_send_req.read()) // blocked until previous cc_send request is sent4020 { 4021 size_t way= r_dcache_xtn_way.read();4022 size_t set= r_dcache_xtn_set.read();4023 paddr_t nline = r_dcache_save_paddr.read() / (m_dcache_words<<2);4018 if (not r_dcache_cc_send_req.read()) // blocked until previous cc_send request is sent 4019 { 4020 size_t way = r_dcache_xtn_way.read(); 4021 size_t set = r_dcache_xtn_set.read(); 4022 paddr_t nline = r_dcache_save_paddr.read() / (m_dcache_words << 2); 4024 4023 4025 4024 #ifdef INSTRUMENTATION 4026 m_cpt_dcache_dir_write++;4027 #endif 4028 r_dcache.write_dir( 4029 4030 CACHE_SLOT_STATE_ZOMBI);4025 m_cpt_dcache_dir_write++; 4026 #endif 4027 r_dcache.write_dir(way, 4028 set, 4029 CACHE_SLOT_STATE_ZOMBI); 4031 4030 4032 4031 // request cleanup … … 4037 4036 4038 4037 // possible itlb & dtlb invalidate 4039 if ( r_dcache_in_tlb[way*m_dcache_sets+set])4038 if (r_dcache_in_tlb[way * m_dcache_sets + set]) 4040 4039 { 4041 4040 r_dcache_tlb_inval_line = nline; … … 4043 4042 r_dcache_fsm_scan_save = DCACHE_XTN_DC_INVAL_END; 4044 4043 r_dcache_fsm = DCACHE_INVAL_TLB_SCAN; 4045 r_dcache_in_tlb[way *m_dcache_sets+set] = false;4046 } 4047 else if ( r_dcache_contains_ptd[way*m_dcache_sets+set])4044 r_dcache_in_tlb[way * m_dcache_sets + set] = false; 4045 } 4046 else if (r_dcache_contains_ptd[way * m_dcache_sets + set]) 4048 4047 { 4049 4048 r_itlb.reset(); 4050 4049 r_dtlb.reset(); 4051 r_dcache_contains_ptd[way *m_dcache_sets+set] = false;4050 r_dcache_contains_ptd[way * m_dcache_sets + set] = false; 4052 4051 r_dcache_fsm = DCACHE_IDLE; 4053 4052 m_drsp.valid = true; … … 4060 4059 4061 4060 #if DEBUG_DCACHE 4062 if ( m_debug_dcache_fsm)4063 {4064 std::cout << " <PROC " << name()4065 << " DCACHE_XTN_DC_INVAL_GO> Actual dcache inval" << std::hex4066 << " / PADDR = " << r_dcache_save_paddr.read() << std::endl;4067 }4068 #endif 4069 4061 if (m_debug_dcache_fsm) 4062 { 4063 std::cout << " <PROC " << name() 4064 << " DCACHE_XTN_DC_INVAL_GO> Actual dcache inval" << std::hex 4065 << " / PADDR = " << r_dcache_save_paddr.read() << std::endl; 4066 } 4067 #endif 4068 } 4070 4069 break; 4071 4070 } 4072 4071 ////////////////////////////// 4073 case DCACHE_XTN_DC_INVAL_END: 4072 case DCACHE_XTN_DC_INVAL_END: // send response to processor XTN request 4074 4073 { 4075 4074 r_dcache_fsm = DCACHE_IDLE; … … 4088 4087 // when a cleanup is required 4089 4088 { 4090 if ( 4089 if (m_dreq.valid) m_cost_data_miss_frz++; 4091 4090 4092 4091 // coherence clack request (from DSPIN CLACK) 4093 if ( r_dcache_clack_req.read())4092 if (r_dcache_clack_req.read()) 4094 4093 { 4095 4094 r_dcache_fsm = DCACHE_CC_CHECK; … … 4099 4098 4100 4099 // coherence request (from CC_RECEIVE FSM) 4101 if ( 4100 if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 4102 4101 { 4103 4102 r_dcache_fsm = DCACHE_CC_CHECK; … … 4106 4105 } 4107 4106 4108 bool 4109 bool 4110 size_t 4111 size_t 4112 paddr_t 4107 bool found = false; 4108 bool cleanup = false; 4109 size_t way = 0; 4110 size_t set = 0; 4111 paddr_t victim = 0; 4113 4112 4114 4113 #ifdef INSTRUMENTATION 4115 m_cpt_dcache_dir_read++;4116 #endif 4117 r_dcache.read_select( 4118 4119 4120 4121 4122 &cleanup);4123 4124 if ( not found)4114 m_cpt_dcache_dir_read++; 4115 #endif 4116 r_dcache.read_select(r_dcache_save_paddr.read(), 4117 &victim, 4118 &way, 4119 &set, 4120 &found, 4121 &cleanup); 4122 4123 if (not found) 4125 4124 { 4126 4125 break; … … 4131 4130 r_dcache_miss_set = set; 4132 4131 4133 if ( cleanup)4134 { 4135 if ( not r_dcache_cc_send_req.read())4132 if (cleanup) 4133 { 4134 if (not r_dcache_cc_send_req.read()) 4136 4135 { 4137 r_dcache_cc_send_req 4138 r_dcache_cc_send_nline 4139 r_dcache_cc_send_way 4140 r_dcache_cc_send_type 4136 r_dcache_cc_send_req = true; 4137 r_dcache_cc_send_nline = victim; 4138 r_dcache_cc_send_way = way; 4139 r_dcache_cc_send_type = CC_TYPE_CLEANUP; 4141 4140 4142 4141 } … … 4147 4146 } 4148 4147 4149 r_dcache_miss_clack 4150 r_dcache_fsm 4148 r_dcache_miss_clack = true; 4149 r_dcache_fsm = DCACHE_MISS_CLEAN; 4151 4150 } 4152 4151 else 4153 4152 { 4154 r_dcache_fsm 4153 r_dcache_fsm = DCACHE_MISS_WAIT; 4155 4154 } 4156 4155 4157 4156 #if DEBUG_DCACHE 4158 if ( m_debug_dcache_fsm)4159 {4160 std::cout << " <PROC " << name()4161 << " DCACHE_MISS_SELECT> Select a slot:" << std::dec4162 << " / WAY = " << way4163 << " / SET = " << set4164 << " / PADDR = " << std::hex << r_dcache_save_paddr.read();4165 if(cleanup) std::cout << " / VICTIM = " << (victim*m_dcache_words*4) << std::endl;4166 else std::cout << std::endl;4167 }4157 if (m_debug_dcache_fsm) 4158 { 4159 std::cout << " <PROC " << name() 4160 << " DCACHE_MISS_SELECT> Select a slot:" << std::dec 4161 << " / WAY = " << way 4162 << " / SET = " << set 4163 << " / PADDR = " << std::hex << r_dcache_save_paddr.read(); 4164 if (cleanup) std::cout << " / VICTIM = " << (victim*m_dcache_words*4) << std::endl; 4165 else std::cout << std::endl; 4166 } 4168 4167 #endif 4169 4168 } // end found … … 4171 4170 } 4172 4171 /////////////////////// 4173 case DCACHE_MISS_CLEAN: 4172 case DCACHE_MISS_CLEAN: // switch the slot to ZOMBI state 4174 4173 // and possibly request itlb or dtlb invalidate 4175 4174 { 4176 if ( 4177 4178 size_t way= r_dcache_miss_way.read();4179 size_t set= r_dcache_miss_set.read();4175 if (m_dreq.valid) m_cost_data_miss_frz++; 4176 4177 size_t way = r_dcache_miss_way.read(); 4178 size_t set = r_dcache_miss_set.read(); 4180 4179 4181 4180 #ifdef INSTRUMENTATION 4182 m_cpt_dcache_dir_read++;4183 #endif 4184 r_dcache.write_dir( 4185 4186 CACHE_SLOT_STATE_ZOMBI);4181 m_cpt_dcache_dir_read++; 4182 #endif 4183 r_dcache.write_dir(way, 4184 set, 4185 CACHE_SLOT_STATE_ZOMBI); 4187 4186 #if DEBUG_DCACHE 4188 if ( m_debug_dcache_fsm)4189 {4190 std::cout << " <PROC " << name()4191 << " DCACHE_MISS_CLEAN> Switch to ZOMBI state" << std::dec4192 << " / way = " << way4193 << " / set = " << set << std::endl;4194 }4187 if (m_debug_dcache_fsm) 4188 { 4189 std::cout << " <PROC " << name() 4190 << " DCACHE_MISS_CLEAN> Switch to ZOMBI state" << std::dec 4191 << " / way = " << way 4192 << " / set = " << set << std::endl; 4193 } 4195 4194 #endif 4196 4195 // if selective itlb & dtlb invalidate are required 4197 4196 // the miss response is not handled before invalidate completed 4198 if ( r_dcache_in_tlb[way*m_dcache_sets+set])4199 { 4200 r_dcache_in_tlb[way *m_dcache_sets+set] = false;4201 4202 if ( not r_dcache_cleanup_victim_req.read())4203 r_dcache_tlb_inval_line 4197 if (r_dcache_in_tlb[way * m_dcache_sets + set]) 4198 { 4199 r_dcache_in_tlb[way * m_dcache_sets + set] = false; 4200 4201 if (not r_dcache_cleanup_victim_req.read()) 4202 r_dcache_tlb_inval_line = r_dcache_cc_send_nline.read(); 4204 4203 else 4205 4204 r_dcache_tlb_inval_line = r_dcache_cleanup_victim_nline.read(); 4206 4205 4207 r_dcache_tlb_inval_set 4208 r_dcache_fsm_scan_save 4209 r_dcache_fsm 4210 } 4211 else if ( r_dcache_contains_ptd[way*m_dcache_sets+set])4206 r_dcache_tlb_inval_set = 0; 4207 r_dcache_fsm_scan_save = DCACHE_MISS_WAIT; 4208 r_dcache_fsm = DCACHE_INVAL_TLB_SCAN; 4209 } 4210 else if (r_dcache_contains_ptd[way * m_dcache_sets + set]) 4212 4211 { 4213 4212 r_itlb.reset(); 4214 4213 r_dtlb.reset(); 4215 r_dcache_contains_ptd[way *m_dcache_sets+set] = false;4214 r_dcache_contains_ptd[way * m_dcache_sets + set] = false; 4216 4215 r_dcache_fsm = DCACHE_MISS_WAIT; 4217 4216 } … … 4223 4222 } 4224 4223 ////////////////////// 4225 case DCACHE_MISS_WAIT: 4224 case DCACHE_MISS_WAIT: // waiting the response to a miss request from VCI_RSP FSM 4226 4225 // This state is in charge of error signaling 4227 4226 // There is 5 types of error depending on the requester 4228 4227 { 4229 if ( 4228 if (m_dreq.valid) m_cost_data_miss_frz++; 4230 4229 4231 4230 // send cleanup victim request 4232 if ( r_dcache_cleanup_victim_req.read() and not r_dcache_cc_send_req.read())4231 if (r_dcache_cleanup_victim_req.read() and not r_dcache_cc_send_req.read()) 4233 4232 { 4234 4233 r_dcache_cc_send_req = true; … … 4240 4239 4241 4240 // coherence clack request (from DSPIN CLACK) 4242 if ( r_dcache_clack_req.read())4241 if (r_dcache_clack_req.read()) 4243 4242 { 4244 4243 r_dcache_fsm = DCACHE_CC_CHECK; … … 4248 4247 4249 4248 // coherence request (from CC_RECEIVE FSM) 4250 if ( 4249 if (r_cc_receive_dcache_req.read() and 4251 4250 not r_dcache_cc_send_req.read() and 4252 4251 not r_dcache_cleanup_victim_req.read()) … … 4257 4256 } 4258 4257 4259 if ( r_vci_rsp_data_error.read() )// bus error4260 { 4261 switch ( r_dcache_miss_type.read())4258 if (r_vci_rsp_data_error.read()) // bus error 4259 { 4260 switch (r_dcache_miss_type.read()) 4262 4261 { 4263 4262 case PROC_MISS: 4264 4263 { 4265 r_mmu_detr 4266 r_mmu_dbvar 4267 m_drsp.valid 4268 m_drsp.error 4269 r_dcache_fsm 4264 r_mmu_detr = MMU_READ_DATA_ILLEGAL_ACCESS; 4265 r_mmu_dbvar = r_dcache_save_vaddr.read(); 4266 m_drsp.valid = true; 4267 m_drsp.error = true; 4268 r_dcache_fsm = DCACHE_IDLE; 4270 4269 break; 4271 4270 } 4272 4271 case PTE1_MISS: 4273 4272 { 4274 if ( r_dcache_tlb_ins.read())4273 if (r_dcache_tlb_ins.read()) 4275 4274 { 4276 r_mmu_ietr 4277 r_mmu_ibvar 4278 r_icache_tlb_miss_req 4279 r_icache_tlb_rsp_error 4275 r_mmu_ietr = MMU_READ_PT1_ILLEGAL_ACCESS; 4276 r_mmu_ibvar = r_dcache_tlb_vaddr.read(); 4277 r_icache_tlb_miss_req = false; 4278 r_icache_tlb_rsp_error = true; 4280 4279 } 4281 4280 else 4282 4281 { 4283 r_mmu_detr 4284 r_mmu_dbvar 4285 m_drsp.valid 4286 m_drsp.error 4282 r_mmu_detr = MMU_READ_PT1_ILLEGAL_ACCESS; 4283 r_mmu_dbvar = r_dcache_tlb_vaddr.read(); 4284 m_drsp.valid = true; 4285 m_drsp.error = true; 4287 4286 } 4288 r_dcache_fsm 4287 r_dcache_fsm = DCACHE_IDLE; 4289 4288 break; 4290 4289 } 4291 4290 case PTE2_MISS: 4292 4291 { 4293 if ( r_dcache_tlb_ins.read())4292 if (r_dcache_tlb_ins.read()) 4294 4293 { 4295 r_mmu_ietr 4296 r_mmu_ibvar 4297 r_icache_tlb_miss_req 4298 r_icache_tlb_rsp_error 4294 r_mmu_ietr = MMU_READ_PT2_ILLEGAL_ACCESS; 4295 r_mmu_ibvar = r_dcache_tlb_vaddr.read(); 4296 r_icache_tlb_miss_req = false; 4297 r_icache_tlb_rsp_error = true; 4299 4298 } 4300 4299 else 4301 4300 { 4302 r_mmu_detr 4303 r_mmu_dbvar 4304 m_drsp.valid 4305 m_drsp.error 4301 r_mmu_detr = MMU_READ_PT2_ILLEGAL_ACCESS; 4302 r_mmu_dbvar = r_dcache_tlb_vaddr.read(); 4303 m_drsp.valid = true; 4304 m_drsp.error = true; 4306 4305 } 4307 r_dcache_fsm 4306 r_dcache_fsm = DCACHE_IDLE; 4308 4307 break; 4309 4308 } … … 4311 4310 r_vci_rsp_data_error = false; 4312 4311 } 4313 else if ( r_vci_rsp_fifo_dcache.rok() )// valid response available4312 else if (r_vci_rsp_fifo_dcache.rok()) // valid response available 4314 4313 { 4315 4314 r_dcache_miss_word = 0; 4316 4315 r_dcache_fsm = DCACHE_MISS_DATA_UPDT; 4317 4316 } 4318 4317 break; 4319 4318 } 4320 4319 ////////////////////////// 4321 case DCACHE_MISS_DATA_UPDT: 4322 { 4323 if ( 4324 4325 if ( r_vci_rsp_fifo_dcache.rok() )// one word available4320 case DCACHE_MISS_DATA_UPDT: // update the dcache (one word per cycle) 4321 { 4322 if (m_dreq.valid) m_cost_data_miss_frz++; 4323 4324 if (r_vci_rsp_fifo_dcache.rok()) // one word available 4326 4325 { 4327 4326 #ifdef INSTRUMENTATION 4328 m_cpt_dcache_data_write++;4329 #endif 4330 r_dcache.write(r_dcache_miss_way.read(),4331 4332 4333 r_vci_rsp_fifo_dcache.read());4327 m_cpt_dcache_data_write++; 4328 #endif 4329 r_dcache.write(r_dcache_miss_way.read(), 4330 r_dcache_miss_set.read(), 4331 r_dcache_miss_word.read(), 4332 r_vci_rsp_fifo_dcache.read()); 4334 4333 #if DEBUG_DCACHE 4335 if ( m_debug_dcache_fsm)4336 {4337 std::cout << " <PROC " << name()4338 << " DCACHE_MISS_DATA_UPDT> Write one word:"4339 << " / DATA = " << std::hex << r_vci_rsp_fifo_dcache.read()4340 << " / WAY = " << std::dec << r_dcache_miss_way.read()4341 << " / SET = " << r_dcache_miss_set.read()4342 << " / WORD = " << r_dcache_miss_word.read() << std::endl;4343 }4334 if (m_debug_dcache_fsm) 4335 { 4336 std::cout << " <PROC " << name() 4337 << " DCACHE_MISS_DATA_UPDT> Write one word:" 4338 << " / DATA = " << std::hex << r_vci_rsp_fifo_dcache.read() 4339 << " / WAY = " << std::dec << r_dcache_miss_way.read() 4340 << " / SET = " << r_dcache_miss_set.read() 4341 << " / WORD = " << r_dcache_miss_word.read() << std::endl; 4342 } 4344 4343 #endif 4345 4344 vci_rsp_fifo_dcache_get = true; 4346 4345 r_dcache_miss_word = r_dcache_miss_word.read() + 1; 4347 4346 4348 if ( r_dcache_miss_word.read() == (m_dcache_words-1)) // last word4347 if (r_dcache_miss_word.read() == (m_dcache_words - 1)) // last word 4349 4348 { 4350 4349 r_dcache_fsm = DCACHE_MISS_DIR_UPDT; … … 4362 4361 // to ZOMBI state, and send a cleanup request. 4363 4362 { 4364 if ( 4363 if (m_dreq.valid) m_cost_data_miss_frz++; 4365 4364 4366 4365 // send cleanup victim request 4367 if ( r_dcache_cleanup_victim_req.read() and not r_dcache_cc_send_req.read())4366 if (r_dcache_cleanup_victim_req.read() and not r_dcache_cc_send_req.read()) 4368 4367 { 4369 4368 r_dcache_cc_send_req = true; … … 4375 4374 4376 4375 // coherence clack request (from DSPIN CLACK) 4377 if ( r_dcache_clack_req.read())4376 if (r_dcache_clack_req.read()) 4378 4377 { 4379 4378 r_dcache_fsm = DCACHE_CC_CHECK; … … 4383 4382 4384 4383 // coherence request (from CC_RECEIVE FSM) 4385 if ( 4384 if (r_cc_receive_dcache_req.read() and 4386 4385 not r_dcache_cc_send_req.read() and 4387 not r_dcache_cleanup_victim_req.read() 4386 not r_dcache_cleanup_victim_req.read()) 4388 4387 { 4389 4388 r_dcache_fsm = DCACHE_CC_CHECK; … … 4392 4391 } 4393 4392 4394 if ( not r_dcache_miss_clack.read()) // waiting cleanup acknowledge4395 { 4396 if ( r_dcache_miss_inval.read()) // switch slot to ZOMBI state, and new cleanup4397 { 4398 if ( not r_dcache_cc_send_req.read()) // blocked until previous request sent4393 if (not r_dcache_miss_clack.read()) // waiting cleanup acknowledge 4394 { 4395 if (r_dcache_miss_inval.read()) // switch slot to ZOMBI state, and new cleanup 4396 { 4397 if (not r_dcache_cc_send_req.read()) // blocked until previous request sent 4399 4398 { 4400 4399 r_dcache_miss_inval = false; 4401 4400 // request cleanup 4402 4401 r_dcache_cc_send_req = true; 4403 r_dcache_cc_send_nline = r_dcache_save_paddr.read() /(m_dcache_words<<2);4402 r_dcache_cc_send_nline = r_dcache_save_paddr.read() / (m_dcache_words << 2); 4404 4403 r_dcache_cc_send_way = r_dcache_miss_way.read(); 4405 4404 r_dcache_cc_send_type = CC_TYPE_CLEANUP; 4406 4405 4407 4406 #ifdef INSTRUMENTATION 4408 m_cpt_dcache_dir_write++;4407 m_cpt_dcache_dir_write++; 4409 4408 #endif 4410 4409 r_dcache.write_dir( r_dcache_save_paddr.read(), … … 4413 4412 CACHE_SLOT_STATE_ZOMBI ); 4414 4413 #if DEBUG_DCACHE 4415 if ( m_debug_dcache_fsm)4416 std::cout << " <PROC " << name()4417 << " DCACHE_MISS_DIR_UPDT> Switch slot to ZOMBI state"4418 << " PADDR = " << std::hex << r_dcache_save_paddr.read()4419 << " / WAY = " << std::dec << r_dcache_miss_way.read()4420 << " / SET = " << r_dcache_miss_set.read() << std::endl;4414 if (m_debug_dcache_fsm) 4415 std::cout << " <PROC " << name() 4416 << " DCACHE_MISS_DIR_UPDT> Switch slot to ZOMBI state" 4417 << " PADDR = " << std::hex << r_dcache_save_paddr.read() 4418 << " / WAY = " << std::dec << r_dcache_miss_way.read() 4419 << " / SET = " << r_dcache_miss_set.read() << std::endl; 4421 4420 #endif 4422 4421 } … … 4428 4427 4429 4428 #ifdef INSTRUMENTATION 4430 m_cpt_dcache_dir_write++;4431 #endif 4432 r_dcache.write_dir( 4433 4434 4435 CACHE_SLOT_STATE_VALID);4429 m_cpt_dcache_dir_write++; 4430 #endif 4431 r_dcache.write_dir(r_dcache_save_paddr.read(), 4432 r_dcache_miss_way.read(), 4433 r_dcache_miss_set.read(), 4434 CACHE_SLOT_STATE_VALID); 4436 4435 4437 4436 #if DEBUG_DCACHE 4438 if ( m_debug_dcache_fsm)4439 std::cout << " <PROC " << name()4440 << " DCACHE_MISS_DIR_UPDT> Switch slot to VALID state"4441 << " PADDR = " << std::hex << r_dcache_save_paddr.read()4442 << " / WAY = " << std::dec << r_dcache_miss_way.read()4443 << " / SET = " << r_dcache_miss_set.read() << std::endl;4437 if (m_debug_dcache_fsm) 4438 std::cout << " <PROC " << name() 4439 << " DCACHE_MISS_DIR_UPDT> Switch slot to VALID state" 4440 << " PADDR = " << std::hex << r_dcache_save_paddr.read() 4441 << " / WAY = " << std::dec << r_dcache_miss_way.read() 4442 << " / SET = " << r_dcache_miss_set.read() << std::endl; 4444 4443 #endif 4445 4444 // reset directory extension 4446 4445 size_t way = r_dcache_miss_way.read(); 4447 4446 size_t set = r_dcache_miss_set.read(); 4448 r_dcache_in_tlb[way *m_dcache_sets+set] = false;4449 r_dcache_contains_ptd[way *m_dcache_sets+set] = false;4447 r_dcache_in_tlb[way * m_dcache_sets + set] = false; 4448 r_dcache_contains_ptd[way * m_dcache_sets + set] = false; 4450 4449 } 4451 4450 if (r_dcache_miss_type.read()==PTE1_MISS) r_dcache_fsm = DCACHE_TLB_PTE1_GET; … … 4459 4458 { 4460 4459 // coherence clack request (from DSPIN CLACK) 4461 if ( r_dcache_clack_req.read())4460 if (r_dcache_clack_req.read()) 4462 4461 { 4463 4462 r_dcache_fsm = DCACHE_CC_CHECK; … … 4467 4466 4468 4467 // coherence request (from CC_RECEIVE FSM) 4469 if ( 4468 if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 4470 4469 { 4471 4470 r_dcache_fsm = DCACHE_CC_CHECK; … … 4474 4473 } 4475 4474 4476 if ( r_vci_rsp_data_error.read() )// bus error4477 { 4478 if (r_dcache_vci_unc_write.read())4479 r_mmu_detr 4475 if (r_vci_rsp_data_error.read()) // bus error 4476 { 4477 if (r_dcache_vci_unc_write.read()) 4478 r_mmu_detr = MMU_WRITE_DATA_ILLEGAL_ACCESS; 4480 4479 else 4481 r_mmu_detr 4480 r_mmu_detr = MMU_READ_DATA_ILLEGAL_ACCESS; 4482 4481 4483 4482 r_mmu_dbvar = m_dreq.addr; … … 4488 4487 break; 4489 4488 } 4490 else if ( r_vci_rsp_fifo_dcache.rok()) // data available4491 4489 else if (r_vci_rsp_fifo_dcache.rok()) // data available 4490 { 4492 4491 // consume data 4493 4492 vci_rsp_fifo_dcache_get = true; … … 4495 4494 4496 4495 // acknowledge the processor request if it has not been modified 4497 if ( m_dreq.valid and (m_dreq.addr == r_dcache_save_vaddr.read()))4498 { 4499 m_drsp.valid= true;4500 m_drsp.error 4501 m_drsp.rdata= r_vci_rsp_fifo_dcache.read();4502 } 4503 4496 if (m_dreq.valid and (m_dreq.addr == r_dcache_save_vaddr.read())) 4497 { 4498 m_drsp.valid = true; 4499 m_drsp.error = false; 4500 m_drsp.rdata = r_vci_rsp_fifo_dcache.read(); 4501 } 4502 } 4504 4503 break; 4505 4504 } … … 4508 4507 { 4509 4508 // coherence clack request (from DSPIN CLACK) 4510 if ( r_dcache_clack_req.read())4509 if (r_dcache_clack_req.read()) 4511 4510 { 4512 4511 r_dcache_fsm = DCACHE_CC_CHECK; … … 4516 4515 4517 4516 // coherence request (from CC_RECEIVE FSM) 4518 if ( 4517 if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 4519 4518 { 4520 4519 r_dcache_fsm = DCACHE_CC_CHECK; … … 4523 4522 } 4524 4523 4525 if ( r_vci_rsp_data_error.read() )// bus error4524 if (r_vci_rsp_data_error.read()) // bus error 4526 4525 { 4527 4526 r_mmu_detr = MMU_READ_DATA_ILLEGAL_ACCESS; … … 4533 4532 break; 4534 4533 } 4535 else if ( r_vci_rsp_fifo_dcache.rok()) // data available4536 4534 else if (r_vci_rsp_fifo_dcache.rok()) // data available 4535 { 4537 4536 // consume data 4538 4537 vci_rsp_fifo_dcache_get = true; 4539 4538 4540 if (r_dcache_ll_rsp_count.read() == 0) // first flit4539 if (r_dcache_ll_rsp_count.read() == 0) // first flit 4541 4540 { 4542 4541 // set key value in llsc reservation buffer 4543 4542 r_dcache_llsc_key = r_vci_rsp_fifo_dcache.read(); 4544 r_dcache_ll_rsp_count = r_dcache_ll_rsp_count.read() + 1 4543 r_dcache_ll_rsp_count = r_dcache_ll_rsp_count.read() + 1; 4545 4544 } 4546 4545 else // last flit 4547 4546 { 4548 4547 // acknowledge the processor request if it has not been modified 4549 if ( m_dreq.valid and (m_dreq.addr == r_dcache_save_vaddr.read()))4548 if (m_dreq.valid and (m_dreq.addr == r_dcache_save_vaddr.read())) 4550 4549 { 4551 m_drsp.valid 4552 m_drsp.error 4553 m_drsp.rdata 4550 m_drsp.valid = true; 4551 m_drsp.error = false; 4552 m_drsp.rdata = r_vci_rsp_fifo_dcache.read(); 4554 4553 } 4555 4554 r_dcache_fsm = DCACHE_IDLE; 4556 4555 } 4557 4556 } 4558 4557 break; 4559 4558 } 4560 4559 //////////////////// 4561 case DCACHE_SC_WAIT: 4560 case DCACHE_SC_WAIT: // waiting VCI response to a SC transaction 4562 4561 { 4563 4562 // coherence clack request (from DSPIN CLACK) 4564 if ( r_dcache_clack_req.read())4563 if (r_dcache_clack_req.read()) 4565 4564 { 4566 4565 r_dcache_fsm = DCACHE_CC_CHECK; … … 4570 4569 4571 4570 // coherence request (from CC_RECEIVE FSM) 4572 if ( 4571 if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 4573 4572 { 4574 4573 r_dcache_fsm = DCACHE_CC_CHECK; … … 4577 4576 } 4578 4577 4579 if ( r_vci_rsp_data_error.read() )// bus error4578 if (r_vci_rsp_data_error.read()) // bus error 4580 4579 { 4581 4580 r_mmu_detr = MMU_READ_DATA_ILLEGAL_ACCESS; … … 4587 4586 break; 4588 4587 } 4589 else if ( r_vci_rsp_fifo_dcache.rok()) // response available4590 4588 else if (r_vci_rsp_fifo_dcache.rok()) // response available 4589 { 4591 4590 // consume response 4592 4591 vci_rsp_fifo_dcache_get = true; … … 4594 4593 m_drsp.rdata = r_vci_rsp_fifo_dcache.read(); 4595 4594 r_dcache_fsm = DCACHE_IDLE; 4596 4595 } 4597 4596 break; 4598 4597 } 4599 4598 ////////////////////////// 4600 case DCACHE_DIRTY_GET_PTE: 4601 4602 4603 4604 4599 case DCACHE_DIRTY_GET_PTE: // This sub_fsm set the PTE Dirty bit in memory 4600 // before handling a processor WRITE or SC request 4601 // Input argument is r_dcache_dirty_paddr 4602 // In this first state, we get PTE value in dcache 4603 // and post a CAS request to CMD FSM 4605 4604 { 4606 4605 // get PTE in dcache … … 4612 4611 4613 4612 #ifdef INSTRUMENTATION 4614 m_cpt_dcache_data_read++;4615 m_cpt_dcache_dir_read++;4616 #endif 4617 r_dcache.read( 4618 4619 4620 4621 4622 &state);4613 m_cpt_dcache_data_read++; 4614 m_cpt_dcache_dir_read++; 4615 #endif 4616 r_dcache.read(r_dcache_dirty_paddr.read(), 4617 &pte, 4618 &way, 4619 &set, 4620 &word, 4621 &state); 4623 4622 4624 4623 assert( (state == CACHE_SLOT_STATE_VALID) and … … 4626 4625 4627 4626 // request CAS transaction to CMD_FSM 4628 r_dcache_dirty_way 4629 r_dcache_dirty_set 4627 r_dcache_dirty_way = way; 4628 r_dcache_dirty_set = set; 4630 4629 4631 4630 // check llsc reservation buffer 4632 if (r_dcache_llsc_paddr.read() == r_dcache_dirty_paddr.read() 4631 if (r_dcache_llsc_paddr.read() == r_dcache_dirty_paddr.read()) 4633 4632 r_dcache_llsc_valid = false; 4634 4633 … … 4641 4640 4642 4641 #if DEBUG_DCACHE 4643 if ( m_debug_dcache_fsm)4644 {4645 std::cout << " <PROC " << name()4646 << " DCACHE_DIRTY_GET_PTE> CAS request" << std::hex4647 << " / PTE_PADDR = " << r_dcache_dirty_paddr.read()4648 << " / PTE_VALUE = " << pte << std::dec4649 << " / SET = " << set4650 << " / WAY = " << way << std::endl;4651 }4642 if (m_debug_dcache_fsm) 4643 { 4644 std::cout << " <PROC " << name() 4645 << " DCACHE_DIRTY_GET_PTE> CAS request" << std::hex 4646 << " / PTE_PADDR = " << r_dcache_dirty_paddr.read() 4647 << " / PTE_VALUE = " << pte << std::dec 4648 << " / SET = " << set 4649 << " / WAY = " << way << std::endl; 4650 } 4652 4651 #endif 4653 4652 break; 4654 4653 } 4655 4654 /////////////////////// 4656 case DCACHE_DIRTY_WAIT: 4657 4658 4659 4660 4661 4655 case DCACHE_DIRTY_WAIT: // wait completion of CAS for PTE Dirty bit, 4656 // and return to IDLE state when response is received. 4657 // we don't care if the CAS is a failure: 4658 // - if the CAS is a success, the coherence mechanism 4659 // updates the local copy. 4660 // - if the CAS is a failure, we just retry the write. 4662 4661 { 4663 4662 // coherence clack request (from DSPIN CLACK) 4664 if ( r_dcache_clack_req.read())4663 if (r_dcache_clack_req.read()) 4665 4664 { 4666 4665 r_dcache_fsm = DCACHE_CC_CHECK; … … 4670 4669 4671 4670 // coherence request (from CC_RECEIVE FSM) 4672 if ( 4671 if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 4673 4672 { 4674 4673 r_dcache_fsm = DCACHE_CC_CHECK; … … 4677 4676 } 4678 4677 4679 if ( r_vci_rsp_data_error.read()) // bus error4678 if (r_vci_rsp_data_error.read()) // bus error 4680 4679 { 4681 4680 std::cout << "BUS ERROR in DCACHE_DIRTY_WAIT state" << std::endl; … … 4683 4682 exit(0); 4684 4683 } 4685 else if ( r_vci_rsp_fifo_dcache.rok()) // response available4684 else if (r_vci_rsp_fifo_dcache.rok()) // response available 4686 4685 { 4687 4686 vci_rsp_fifo_dcache_get = true; … … 4689 4688 4690 4689 #if DEBUG_DCACHE 4691 if ( m_debug_dcache_fsm)4692 {4693 std::cout << " <PROC " << name()4694 << " DCACHE_DIRTY_WAIT> CAS completed" << std::endl;4695 }4690 if (m_debug_dcache_fsm) 4691 { 4692 std::cout << " <PROC " << name() 4693 << " DCACHE_DIRTY_WAIT> CAS completed" << std::endl; 4694 } 4696 4695 #endif 4697 4696 } … … 4707 4706 // The return state is defined in r_dcache_fsm_cc_save 4708 4707 { 4709 paddr_t 4710 paddr_t mask = ~((m_dcache_words<<2)-1);4708 paddr_t paddr = r_cc_receive_dcache_nline.read() * m_dcache_words * 4; 4709 paddr_t mask = ~((m_dcache_words << 2) - 1); 4711 4710 4712 4711 // CLACK handler 4713 4712 // We switch the directory slot to EMPTY state and reset 4714 4713 // r_dcache_miss_clack if the cleanup ack is matching a pending miss. 4715 if ( r_dcache_clack_req.read())4716 { 4717 if ( 4714 if (r_dcache_clack_req.read()) 4715 { 4716 if (m_dreq.valid ) m_cost_data_miss_frz++; 4718 4717 4719 4718 #ifdef INSTRUMENTATION 4720 m_cpt_dcache_dir_write++;4721 #endif 4722 r_dcache.write_dir( 4723 4724 4725 4726 4727 if ( 4728 (r_dcache_miss_way.read() == r_dcache_clack_way.read()))4719 m_cpt_dcache_dir_write++; 4720 #endif 4721 r_dcache.write_dir(0, 4722 r_dcache_clack_way.read(), 4723 r_dcache_clack_set.read(), 4724 CACHE_SLOT_STATE_EMPTY); 4725 4726 if ((r_dcache_miss_set.read() == r_dcache_clack_set.read()) and 4727 (r_dcache_miss_way.read() == r_dcache_clack_way.read())) 4729 4728 { 4730 4729 r_dcache_miss_clack = false; … … 4737 4736 4738 4737 #if DEBUG_DCACHE 4739 if ( m_debug_dcache_fsm)4740 {4741 std::cout << " <PROC " << name()4742 << " DCACHE_CC_CHECK> CLACK for PADDR " << paddr4743 << " Switch slot to EMPTY state : "4744 << " set = " << r_dcache_clack_set.read()4745 << " / way = " << r_dcache_clack_way.read() << std::endl;4746 }4738 if (m_debug_dcache_fsm) 4739 { 4740 std::cout << " <PROC " << name() 4741 << " DCACHE_CC_CHECK> CLACK for PADDR " << paddr 4742 << " Switch slot to EMPTY state : " 4743 << " set = " << r_dcache_clack_set.read() 4744 << " / way = " << r_dcache_clack_way.read() << std::endl; 4745 } 4747 4746 #endif 4748 4747 break; … … 4754 4753 // Match between MISS address and CC address 4755 4754 if (r_cc_receive_dcache_req.read() and 4756 ((r_dcache_fsm_cc_save == DCACHE_MISS_SELECT 4757 (r_dcache_fsm_cc_save == DCACHE_MISS_WAIT 4755 ((r_dcache_fsm_cc_save == DCACHE_MISS_SELECT) or 4756 (r_dcache_fsm_cc_save == DCACHE_MISS_WAIT) or 4758 4757 (r_dcache_fsm_cc_save == DCACHE_MISS_DIR_UPDT)) and 4759 4758 ((r_dcache_vci_paddr.read() & mask) == (paddr & mask))) // matching … … 4766 4765 if (r_cc_receive_dcache_type.read() == CC_TYPE_UPDT) 4767 4766 { 4768 r_dcache_fsm 4769 r_dcache_cc_word 4767 r_dcache_fsm = DCACHE_CC_UPDT; 4768 r_dcache_cc_word = r_cc_receive_word_idx.read(); 4770 4769 4771 4770 // just pop the fifo , don't write in icache … … 4780 4779 4781 4780 #if DEBUG_DCACHE 4782 if ( m_debug_dcache_fsm)4783 {4784 std::cout << " <PROC " << name()4785 << " DCACHE_CC_CHECK> Coherence request matching a pending miss:"4786 << " PADDR = " << std::hex << paddr << std::endl;4787 }4781 if (m_debug_dcache_fsm) 4782 { 4783 std::cout << " <PROC " << name() 4784 << " DCACHE_CC_CHECK> Coherence request matching a pending miss:" 4785 << " PADDR = " << std::hex << paddr << std::endl; 4786 } 4788 4787 #endif 4789 4788 } … … 4797 4796 4798 4797 #ifdef INSTRUMENTATION 4799 m_cpt_dcache_dir_read++;4800 #endif 4801 r_dcache.read_dir( 4802 4803 4804 4805 &word); // unused4798 m_cpt_dcache_dir_read++; 4799 #endif 4800 r_dcache.read_dir(paddr, 4801 &state, 4802 &way, 4803 &set, 4804 &word); // unused 4806 4805 4807 4806 r_dcache_cc_way = way; 4808 4807 r_dcache_cc_set = set; 4809 4808 4810 if ( 4809 if (state == CACHE_SLOT_STATE_VALID) // hit 4811 4810 { 4812 4811 // need to update the cache state … … 4817 4816 r_dcache_cc_word = r_cc_receive_word_idx.read(); 4818 4817 } 4819 else if ( r_cc_receive_dcache_type.read() == CC_TYPE_INVAL) // hit inval4820 { 4821 r_dcache_fsm 4818 else if (r_cc_receive_dcache_type.read() == CC_TYPE_INVAL) // hit inval 4819 { 4820 r_dcache_fsm = DCACHE_CC_INVAL; 4822 4821 } 4823 4822 } … … 4825 4824 { 4826 4825 // multicast acknowledgement required in case of update 4827 if (r_cc_receive_dcache_type.read() == CC_TYPE_UPDT)4828 { 4829 r_dcache_fsm 4830 r_dcache_cc_word 4826 if (r_cc_receive_dcache_type.read() == CC_TYPE_UPDT) 4827 { 4828 r_dcache_fsm = DCACHE_CC_UPDT; 4829 r_dcache_cc_word = r_cc_receive_word_idx.read(); 4831 4830 4832 4831 // just pop the fifo , don't write in icache … … 4836 4835 { 4837 4836 r_cc_receive_dcache_req = false; 4838 r_dcache_fsm 4837 r_dcache_fsm = r_dcache_fsm_cc_save.read(); 4839 4838 } 4840 4839 } 4841 4840 4842 4841 #if DEBUG_DCACHE 4843 if ( m_debug_dcache_fsm)4844 {4845 std::cout << " <PROC " << name()4846 << " DCACHE_CC_CHECK> Coherence request received:"4847 << " PADDR = " << std::hex << paddr4848 << " / TYPE = " << std::dec << r_cc_receive_dcache_type.read()4849 << " / HIT = " << (state == CACHE_SLOT_STATE_VALID) << std::endl;4850 }4842 if (m_debug_dcache_fsm) 4843 { 4844 std::cout << " <PROC " << name() 4845 << " DCACHE_CC_CHECK> Coherence request received:" 4846 << " PADDR = " << std::hex << paddr 4847 << " / TYPE = " << std::dec << r_cc_receive_dcache_type.read() 4848 << " / HIT = " << (state == CACHE_SLOT_STATE_VALID) << std::endl; 4849 } 4851 4850 #endif 4852 4851 … … 4858 4857 // TLBs 4859 4858 { 4860 size_t way 4861 size_t set 4862 4863 if ( r_dcache_in_tlb[way*m_dcache_sets+set]) // selective TLB inval4864 { 4865 r_dcache_in_tlb[way *m_dcache_sets+set] = false;4866 r_dcache_tlb_inval_line 4867 r_dcache_tlb_inval_set 4868 r_dcache_fsm_scan_save 4869 r_dcache_fsm 4870 break; 4871 } 4872 4873 if ( r_dcache_contains_ptd[way*m_dcache_sets+set]) // TLB flush4859 size_t way = r_dcache_cc_way.read(); 4860 size_t set = r_dcache_cc_set.read(); 4861 4862 if (r_dcache_in_tlb[way * m_dcache_sets + set]) // selective TLB inval 4863 { 4864 r_dcache_in_tlb[way * m_dcache_sets + set] = false; 4865 r_dcache_tlb_inval_line = r_cc_receive_dcache_nline.read(); 4866 r_dcache_tlb_inval_set = 0; 4867 r_dcache_fsm_scan_save = r_dcache_fsm.read(); 4868 r_dcache_fsm = DCACHE_INVAL_TLB_SCAN; 4869 break; 4870 } 4871 4872 if (r_dcache_contains_ptd[way * m_dcache_sets + set]) // TLB flush 4874 4873 { 4875 4874 r_itlb.reset(); 4876 4875 r_dtlb.reset(); 4877 r_dcache_contains_ptd[way *m_dcache_sets+set] = false;4876 r_dcache_contains_ptd[way * m_dcache_sets + set] = false; 4878 4877 4879 4878 #if DEBUG_DCACHE 4880 if ( m_debug_dcache_fsm)4881 {4882 std::cout << " <PROC " << name()4883 << " DCACHE_CC_INVAL> Flush DTLB & ITLB" << std::endl;4884 }4885 #endif 4886 } 4887 4888 assert 4879 if (m_debug_dcache_fsm) 4880 { 4881 std::cout << " <PROC " << name() 4882 << " DCACHE_CC_INVAL> Flush DTLB & ITLB" << std::endl; 4883 } 4884 #endif 4885 } 4886 4887 assert(not r_dcache_cc_send_req.read() && 4889 4888 "ERROR in DCACHE_CC_INVAL: the r_dcache_cc_send_req " 4890 4889 "must not be set"); 4891 4890 4892 4891 // Switch slot state to ZOMBI and send CLEANUP command 4893 r_dcache.write_dir( 4894 4895 CACHE_SLOT_STATE_ZOMBI);4892 r_dcache.write_dir(way, 4893 set, 4894 CACHE_SLOT_STATE_ZOMBI); 4896 4895 4897 4896 // coherence request completed … … 4904 4903 4905 4904 #if DEBUG_DCACHE 4906 if ( m_debug_dcache_fsm)4907 {4908 std::cout << " <PROC " << name()4909 << " DCACHE_CC_INVAL> Switch slot to EMPTY state:" << std::dec4910 << " / WAY = " << way4911 << " / SET = " << set << std::endl;4912 }4905 if (m_debug_dcache_fsm) 4906 { 4907 std::cout << " <PROC " << name() 4908 << " DCACHE_CC_INVAL> Switch slot to EMPTY state:" << std::dec 4909 << " / WAY = " << way 4910 << " / SET = " << set << std::endl; 4911 } 4913 4912 #endif 4914 4913 break; 4915 4914 } 4916 4915 /////////////////// 4917 case DCACHE_CC_UPDT: 4918 4919 { 4920 size_t word 4921 size_t way 4922 size_t set 4923 4924 if ( r_dcache_in_tlb[way*m_dcache_sets+set]) // selective TLB inval4925 { 4926 r_dcache_in_tlb[way *m_dcache_sets+set] = false;4916 case DCACHE_CC_UPDT: // hit update: write one word per cycle, 4917 // after possible invalidation of copies in TLBs 4918 { 4919 size_t word = r_dcache_cc_word.read(); 4920 size_t way = r_dcache_cc_way.read(); 4921 size_t set = r_dcache_cc_set.read(); 4922 4923 if (r_dcache_in_tlb[way * m_dcache_sets + set]) // selective TLB inval 4924 { 4925 r_dcache_in_tlb[way * m_dcache_sets + set] = false; 4927 4926 r_dcache_tlb_inval_line = r_cc_receive_dcache_nline.read(); 4928 4927 r_dcache_tlb_inval_set = 0; … … 4933 4932 } 4934 4933 4935 if ( r_dcache_contains_ptd[way*m_dcache_sets+set]) // TLB flush4934 if (r_dcache_contains_ptd[way * m_dcache_sets + set]) // TLB flush 4936 4935 { 4937 4936 r_itlb.reset(); 4938 4937 r_dtlb.reset(); 4939 r_dcache_contains_ptd[way *m_dcache_sets+set] = false;4938 r_dcache_contains_ptd[way * m_dcache_sets + set] = false; 4940 4939 4941 4940 #if DEBUG_DCACHE 4942 if ( m_debug_dcache_fsm)4943 {4944 std::cout << " <PROC " << name()4945 << " DCACHE_CC_UPDT> Flush DTLB & ITLB" << std::endl;4946 }4941 if (m_debug_dcache_fsm) 4942 { 4943 std::cout << " <PROC " << name() 4944 << " DCACHE_CC_UPDT> Flush DTLB & ITLB" << std::endl; 4945 } 4947 4946 #endif 4948 4947 } … … 4952 4951 "must not be set"); 4953 4952 4954 if ( not r_cc_receive_updt_fifo_be.rok()) break;4953 if (not r_cc_receive_updt_fifo_be.rok()) break; 4955 4954 4956 4955 if (r_dcache_cc_need_write.read()) … … 4958 4957 4959 4958 #ifdef INSTRUMENTATION 4960 m_cpt_dcache_data_write++;4961 #endif 4962 r_dcache.write( 4963 4964 4965 4966 r_cc_receive_updt_fifo_be.read());4959 m_cpt_dcache_data_write++; 4960 #endif 4961 r_dcache.write(way, 4962 set, 4963 word, 4964 r_cc_receive_updt_fifo_data.read(), 4965 r_cc_receive_updt_fifo_be.read()); 4967 4966 4968 4967 r_dcache_cc_word = word + 1; 4969 4968 4970 4969 #if DEBUG_DCACHE 4971 if ( m_debug_dcache_fsm)4972 {4973 std::cout << " <PROC " << name()4974 << " DCACHE_CC_UPDT> Write one word" << std::dec4975 << " / WAY = " << way4976 << " / SET = " << set4977 << " / WORD = " << word4978 << " / VALUE = " << std::hex << r_cc_receive_updt_fifo_data.read() << std::endl;4979 }4980 #endif 4981 } 4982 4983 if ( r_cc_receive_updt_fifo_eop.read()) // last word4970 if (m_debug_dcache_fsm) 4971 { 4972 std::cout << " <PROC " << name() 4973 << " DCACHE_CC_UPDT> Write one word" << std::dec 4974 << " / WAY = " << way 4975 << " / SET = " << set 4976 << " / WORD = " << word 4977 << " / VALUE = " << std::hex << r_cc_receive_updt_fifo_data.read() << std::endl; 4978 } 4979 #endif 4980 } 4981 4982 if (r_cc_receive_updt_fifo_eop.read()) // last word 4984 4983 { 4985 4984 // no need to write in the cache anymore … … 4994 4993 r_dcache_cc_send_updt_tab_idx = r_cc_receive_dcache_updt_tab_idx.read(); 4995 4994 r_dcache_cc_send_type = CC_TYPE_MULTI_ACK; 4996 4997 4995 r_dcache_fsm = r_dcache_fsm_cc_save.read(); 4998 4996 } … … 5004 5002 } 5005 5003 /////////////////////////// 5006 case DCACHE_INVAL_TLB_SCAN: 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 { 5022 paddr_t 5023 size_t set= r_dcache_tlb_inval_set.read();5024 size_t 5025 bool 5026 5027 for ( way = 0 ; way < m_itlb_ways ; way++)5028 { 5029 ok = r_itlb.inval( line, way, set);5004 case DCACHE_INVAL_TLB_SCAN: // Scan sequencially all sets for both ITLB & DTLB 5005 // It makes assumption: m_itlb_sets == m_dtlb_sets 5006 // All ways are handled in parallel. 5007 // We enter this state when a DCACHE line is modified, 5008 // and there is a copy in itlb or dtlb. 5009 // It can be caused by: 5010 // - a coherence inval or updt transaction, 5011 // - a line inval caused by a cache miss 5012 // - a processor XTN inval request, 5013 // - a WRITE hit, 5014 // - a Dirty bit update 5015 // Input arguments are: 5016 // - r_dcache_tlb_inval_line 5017 // - r_dcache_tlb_inval_set 5018 // - r_dcache_fsm_scan_save 5019 { 5020 paddr_t line = r_dcache_tlb_inval_line.read(); 5021 size_t set = r_dcache_tlb_inval_set.read(); 5022 size_t way; 5023 bool ok; 5024 5025 for (way = 0; way < m_itlb_ways; way++) 5026 { 5027 ok = r_itlb.inval(line, way, set); 5030 5028 5031 5029 #if DEBUG_DCACHE 5032 if ( m_debug_dcache_fsm and ok)5033 {5034 std::cout << " <PROC " << name()5035 << ".DCACHE_INVAL_TLB_SCAN> Invalidate ITLB entry:" << std::hex5036 << " line = " << line << std::dec5037 << " / set = " << set5038 << " / way = " << way << std::endl;5039 }5040 #endif 5041 } 5042 5043 for ( way = 0 ; way < m_dtlb_ways ; way++)5044 { 5045 ok = r_dtlb.inval( line, way, set 5030 if (m_debug_dcache_fsm and ok) 5031 { 5032 std::cout << " <PROC " << name() 5033 << ".DCACHE_INVAL_TLB_SCAN> Invalidate ITLB entry:" << std::hex 5034 << " line = " << line << std::dec 5035 << " / set = " << set 5036 << " / way = " << way << std::endl; 5037 } 5038 #endif 5039 } 5040 5041 for (way = 0; way < m_dtlb_ways; way++) 5042 { 5043 ok = r_dtlb.inval( line, way, set); 5046 5044 5047 5045 #if DEBUG_DCACHE 5048 if ( m_debug_dcache_fsm and ok)5049 std::cout << " <PROC " << name() << " DCACHE_INVAL_TLB_SCAN>"5050 << " Invalidate DTLB entry" << std::hex5051 << " / line = " << line << std::dec5052 << " / set = " << set5053 << " / way = " << way << std::endl;5046 if (m_debug_dcache_fsm and ok) 5047 std::cout << " <PROC " << name() << " DCACHE_INVAL_TLB_SCAN>" 5048 << " Invalidate DTLB entry" << std::hex 5049 << " / line = " << line << std::dec 5050 << " / set = " << set 5051 << " / way = " << way << std::endl; 5054 5052 #endif 5055 5053 } 5056 5054 5057 5055 // return to the calling state when TLB inval completed 5058 if ( r_dcache_tlb_inval_set.read() == (m_dtlb_sets-1))5056 if (r_dcache_tlb_inval_set.read() == (m_dtlb_sets - 1)) 5059 5057 { 5060 5058 r_dcache_fsm = r_dcache_fsm_scan_save.read(); … … 5075 5073 // The simulation exit if the number of consecutive frozen cycles 5076 5074 // is larger than the m_max_frozen_cycles (constructor parameter) 5077 if ( (m_ireq.valid and not m_irsp.valid) or (m_dreq.valid and not m_drsp.valid))5078 { 5079 m_cpt_frz_cycles++; 5080 m_cpt_stop_simulation++; 5081 if ( m_cpt_stop_simulation > m_max_frozen_cycles)5075 if ((m_ireq.valid and not m_irsp.valid) or (m_dreq.valid and not m_drsp.valid)) 5076 { 5077 m_cpt_frz_cycles++; // used for instrumentation 5078 m_cpt_stop_simulation++; // used for debug 5079 if (m_cpt_stop_simulation > m_max_frozen_cycles) 5082 5080 { 5083 5081 std::cout << std::dec << "ERROR in CC_VCACHE_WRAPPER " << name() << std::endl … … 5096 5094 /////////// execute one iss cycle ///////////////////////////////// 5097 5095 { 5098 uint32_t it = 0;5099 for (size_t i=0; i<(size_t)iss_t::n_irq; i++) if(p_irq[i].read()) it |= (1<<i);5100 r_iss.executeNCycles(1, m_irsp, m_drsp, it);5096 uint32_t it = 0; 5097 for (size_t i = 0; i < (size_t) iss_t::n_irq; i++) if (p_irq[i].read()) it |= (1 << i); 5098 r_iss.executeNCycles(1, m_irsp, m_drsp, it); 5101 5099 } 5102 5100 … … 5142 5140 5143 5141 5144 switch ( r_vci_cmd_fsm.read())5142 switch (r_vci_cmd_fsm.read()) 5145 5143 { 5146 5144 ////////////// … … 5154 5152 // using the r_vci_cmd_imiss_prio flip-flop. 5155 5153 5156 size_t 5157 size_t 5154 size_t wbuf_min; 5155 size_t wbuf_max; 5158 5156 5159 5157 bool dcache_miss_req = r_dcache_vci_miss_req.read() and 5160 ( not r_icache_miss_req.read() or not r_vci_cmd_imiss_prio.read());5161 5162 bool dcache_ll_req 5163 ( not r_icache_miss_req.read() or not r_vci_cmd_imiss_prio.read());5164 5165 bool dcache_sc_req 5166 ( not r_icache_miss_req.read() or not r_vci_cmd_imiss_prio.read());5167 5168 bool dcache_cas_req 5169 ( not r_icache_miss_req.read() or not r_vci_cmd_imiss_prio.read());5158 (not r_icache_miss_req.read() or not r_vci_cmd_imiss_prio.read()); 5159 5160 bool dcache_ll_req = r_dcache_vci_ll_req.read() and 5161 (not r_icache_miss_req.read() or not r_vci_cmd_imiss_prio.read()); 5162 5163 bool dcache_sc_req = r_dcache_vci_sc_req.read() and 5164 (not r_icache_miss_req.read() or not r_vci_cmd_imiss_prio.read()); 5165 5166 bool dcache_cas_req = r_dcache_vci_cas_req.read() and 5167 (not r_icache_miss_req.read() or not r_vci_cmd_imiss_prio.read()); 5170 5168 5171 5169 bool icache_miss_req = r_icache_miss_req.read() and 5172 ( 5173 5174 5175 r_dcache_vci_sc_req.read())5176 or r_vci_cmd_imiss_prio.read());5170 (not (r_dcache_vci_miss_req.read() or 5171 r_dcache_vci_ll_req.read() or 5172 r_dcache_vci_cas_req.read() or 5173 r_dcache_vci_sc_req.read()) or 5174 r_vci_cmd_imiss_prio.read()); 5177 5175 5178 5176 // 1 - Data unc write 5179 if ( 5177 if (r_dcache_vci_unc_req.read() and r_dcache_vci_unc_write.read()) 5180 5178 { 5181 5179 r_vci_cmd_fsm = CMD_DATA_UNC_WRITE; 5182 5180 r_dcache_vci_unc_req = false; 5183 // m_cpt_dunc_transaction++;5184 5181 } 5185 5182 // 2 data read miss 5186 else if ( dcache_miss_req and r_wbuf.miss(r_dcache_vci_paddr.read()))5183 else if (dcache_miss_req and r_wbuf.miss(r_dcache_vci_paddr.read())) 5187 5184 { 5188 5185 r_vci_cmd_fsm = CMD_DATA_MISS; 5189 5186 r_dcache_vci_miss_req = false; 5190 5187 r_vci_cmd_imiss_prio = true; 5191 // m_cpt_dmiss_transaction++;5192 5188 } 5193 5189 // 3 - Data Read Uncachable 5194 else if ( r_dcache_vci_unc_req.read() and not r_dcache_vci_unc_write.read())5190 else if (r_dcache_vci_unc_req.read() and not r_dcache_vci_unc_write.read()) 5195 5191 { 5196 5192 r_vci_cmd_fsm = CMD_DATA_UNC_READ; 5197 5193 r_dcache_vci_unc_req = false; 5198 // m_cpt_dunc_transaction++;5199 5194 } 5200 5195 // 4 - Data Linked Load 5201 else if ( 5196 else if (dcache_ll_req and r_wbuf.miss(r_dcache_vci_paddr.read())) 5202 5197 { 5203 5198 r_vci_cmd_fsm = CMD_DATA_LL; 5204 5199 r_dcache_vci_ll_req = false; 5205 5200 r_vci_cmd_imiss_prio = true; 5206 // m_cpt_ll_transaction++;5207 5201 } 5208 5202 // 5 - Instruction Miss 5209 else if ( icache_miss_req and r_wbuf.miss(r_icache_vci_paddr.read()))5203 else if (icache_miss_req and r_wbuf.miss(r_icache_vci_paddr.read())) 5210 5204 { 5211 5205 r_vci_cmd_fsm = CMD_INS_MISS; 5212 5206 r_icache_miss_req = false; 5213 5207 r_vci_cmd_imiss_prio = false; 5214 // m_cpt_imiss_transaction++;5215 5208 } 5216 5209 // 6 - Instruction Uncachable 5217 else if ( r_icache_unc_req.read() ) 5218 { 5219 r_vci_cmd_fsm = CMD_INS_UNC; 5220 r_icache_unc_req = false; 5221 // m_cpt_iunc_transaction++; 5210 else if (r_icache_unc_req.read()) 5211 { 5212 r_vci_cmd_fsm = CMD_INS_UNC; 5213 r_icache_unc_req = false; 5222 5214 } 5223 5215 // 7 - Data Write 5224 else if ( r_wbuf.rok(&wbuf_min, &wbuf_max) ) 5225 { 5226 r_vci_cmd_fsm = CMD_DATA_WRITE; 5227 r_vci_cmd_cpt = wbuf_min; 5228 r_vci_cmd_min = wbuf_min; 5229 r_vci_cmd_max = wbuf_max; 5230 // m_cpt_write_transaction++; 5231 // m_length_write_transaction += (wbuf_max-wbuf_min+1); 5216 else if (r_wbuf.rok(&wbuf_min, &wbuf_max)) 5217 { 5218 r_vci_cmd_fsm = CMD_DATA_WRITE; 5219 r_vci_cmd_cpt = wbuf_min; 5220 r_vci_cmd_min = wbuf_min; 5221 r_vci_cmd_max = wbuf_max; 5232 5222 } 5233 5223 // 8 - Data Store Conditionnal 5234 else if ( dcache_sc_req and r_wbuf.miss(r_dcache_vci_paddr.read()) ) 5235 { 5236 r_vci_cmd_fsm = CMD_DATA_SC; 5237 r_dcache_vci_sc_req = false; 5238 r_vci_cmd_imiss_prio = true; 5239 r_vci_cmd_cpt = 0; 5240 // m_cpt_sc_transaction++; 5224 else if (dcache_sc_req and r_wbuf.miss(r_dcache_vci_paddr.read())) 5225 { 5226 r_vci_cmd_fsm = CMD_DATA_SC; 5227 r_dcache_vci_sc_req = false; 5228 r_vci_cmd_imiss_prio = true; 5229 r_vci_cmd_cpt = 0; 5241 5230 } 5242 5231 // 9 - Compare And Swap 5243 else if ( dcache_cas_req and r_wbuf.miss(r_dcache_vci_paddr.read()) ) 5244 { 5245 r_vci_cmd_fsm = CMD_DATA_CAS; 5246 r_dcache_vci_cas_req = false; 5247 r_vci_cmd_imiss_prio = true; 5248 r_vci_cmd_cpt = 0; 5249 // m_cpt_cas_transaction++; 5232 else if (dcache_cas_req and r_wbuf.miss(r_dcache_vci_paddr.read())) 5233 { 5234 r_vci_cmd_fsm = CMD_DATA_CAS; 5235 r_dcache_vci_cas_req = false; 5236 r_vci_cmd_imiss_prio = true; 5237 r_vci_cmd_cpt = 0; 5250 5238 } 5251 5239 5252 5240 #if DEBUG_CMD 5253 if (m_debug_cmd_fsm )5254 {5255 std::cout << " <PROC " << name() << " CMD_IDLE>"5256 << " / dmiss_req = " << dcache_miss_req5257 << " / imiss_req = " << icache_miss_req5258 << std::endl;5259 }5241 if (m_debug_cmd_fsm ) 5242 { 5243 std::cout << " <PROC " << name() << " CMD_IDLE>" 5244 << " / dmiss_req = " << dcache_miss_req 5245 << " / imiss_req = " << icache_miss_req 5246 << std::endl; 5247 } 5260 5248 #endif 5261 5249 break; … … 5264 5252 case CMD_DATA_WRITE: 5265 5253 { 5266 if ( p_vci.cmdack.read())5254 if (p_vci.cmdack.read()) 5267 5255 { 5268 5256 r_vci_cmd_cpt = r_vci_cmd_cpt + 1; 5269 5257 if (r_vci_cmd_cpt == r_vci_cmd_max) // last flit sent 5270 5258 { 5271 r_vci_cmd_fsm = CMD_IDLE 5272 r_wbuf.sent() 5259 r_vci_cmd_fsm = CMD_IDLE; 5260 r_wbuf.sent(); 5273 5261 } 5274 5262 } … … 5280 5268 { 5281 5269 // The CAS and SC VCI commands contain two flits 5282 if ( p_vci.cmdack.read())5270 if (p_vci.cmdack.read()) 5283 5271 { 5284 5272 r_vci_cmd_cpt = r_vci_cmd_cpt + 1; … … 5296 5284 { 5297 5285 // all read VCI commands contain one single flit 5298 if ( p_vci.cmdack.read()) {5286 if (p_vci.cmdack.read()) { 5299 5287 r_vci_cmd_fsm = CMD_IDLE; 5300 5288 } … … 5331 5319 ////////////////////////////////////////////////////////////////////////// 5332 5320 5333 switch ( r_vci_rsp_fsm.read())5321 switch (r_vci_rsp_fsm.read()) 5334 5322 { 5335 5323 ////////////// 5336 5324 case RSP_IDLE: 5337 5325 { 5338 if ( p_vci.rspval.read())5326 if (p_vci.rspval.read()) 5339 5327 { 5340 5328 r_vci_rsp_cpt = 0; 5341 5329 5342 if ( (p_vci.rpktid.read() & 0x7) == TYPE_DATA_UNC)5330 if ((p_vci.rpktid.read() & 0x7) == TYPE_DATA_UNC) 5343 5331 { 5344 5332 r_vci_rsp_fsm = RSP_DATA_UNC; 5345 5333 } 5346 else if ( (p_vci.rpktid.read() & 0x7) == TYPE_READ_DATA_MISS)5334 else if ((p_vci.rpktid.read() & 0x7) == TYPE_READ_DATA_MISS) 5347 5335 { 5348 5336 r_vci_rsp_fsm = RSP_DATA_MISS; 5349 5337 } 5350 else if ( (p_vci.rpktid.read() & 0x7) == TYPE_READ_INS_UNC)5338 else if ((p_vci.rpktid.read() & 0x7) == TYPE_READ_INS_UNC) 5351 5339 { 5352 5340 r_vci_rsp_fsm = RSP_INS_UNC; 5353 5341 } 5354 else if ( (p_vci.rpktid.read() & 0x7) == TYPE_READ_INS_MISS)5342 else if ((p_vci.rpktid.read() & 0x7) == TYPE_READ_INS_MISS) 5355 5343 { 5356 5344 r_vci_rsp_fsm = RSP_INS_MISS; 5357 5345 } 5358 else if ( (p_vci.rpktid.read() & 0x7) == TYPE_WRITE)5346 else if ((p_vci.rpktid.read() & 0x7) == TYPE_WRITE) 5359 5347 { 5360 5348 r_vci_rsp_fsm = RSP_DATA_WRITE; 5361 5349 } 5362 else if ( (p_vci.rpktid.read() & 0x7) == TYPE_CAS)5350 else if ((p_vci.rpktid.read() & 0x7) == TYPE_CAS) 5363 5351 { 5364 5352 r_vci_rsp_fsm = RSP_DATA_UNC; 5365 5353 } 5366 else if ( (p_vci.rpktid.read() & 0x7) == TYPE_LL)5354 else if ((p_vci.rpktid.read() & 0x7) == TYPE_LL) 5367 5355 { 5368 5356 r_vci_rsp_fsm = RSP_DATA_LL; 5369 5357 } 5370 else if ( (p_vci.rpktid.read() & 0x7) == TYPE_SC)5358 else if ((p_vci.rpktid.read() & 0x7) == TYPE_SC) 5371 5359 { 5372 5360 r_vci_rsp_fsm = RSP_DATA_UNC; … … 5382 5370 case RSP_INS_MISS: 5383 5371 { 5384 if ( p_vci.rspval.read())5385 { 5386 if ( (p_vci.rerror.read()&0x1) != 0) // error reported5372 if (p_vci.rspval.read()) 5373 { 5374 if ((p_vci.rerror.read() & 0x1) != 0) // error reported 5387 5375 { 5388 5376 r_vci_rsp_ins_error = true; 5389 if ( p_vci.reop.read()) r_vci_rsp_fsm = RSP_IDLE;5377 if (p_vci.reop.read()) r_vci_rsp_fsm = RSP_IDLE; 5390 5378 } 5391 5379 else // no error reported 5392 5380 { 5393 if ( r_vci_rsp_fifo_icache.wok())5381 if (r_vci_rsp_fifo_icache.wok()) 5394 5382 { 5395 if ( r_vci_rsp_cpt.read() >= m_icache_words)5383 if (r_vci_rsp_cpt.read() >= m_icache_words) 5396 5384 { 5397 5385 std::cout << "ERROR in VCI_CC_VCACHE " << name() … … 5400 5388 exit(0); 5401 5389 } 5402 r_vci_rsp_cpt 5403 vci_rsp_fifo_icache_put 5404 vci_rsp_fifo_icache_data 5405 if ( p_vci.reop.read())5390 r_vci_rsp_cpt = r_vci_rsp_cpt.read() + 1; 5391 vci_rsp_fifo_icache_put = true, 5392 vci_rsp_fifo_icache_data = p_vci.rdata.read(); 5393 if (p_vci.reop.read()) 5406 5394 { 5407 if ( r_vci_rsp_cpt.read() != (m_icache_words - 1))5395 if (r_vci_rsp_cpt.read() != (m_icache_words - 1)) 5408 5396 { 5409 5397 std::cout << "ERROR in VCI_CC_VCACHE " << name() … … 5412 5400 exit(0); 5413 5401 } 5414 r_vci_rsp_fsm 5402 r_vci_rsp_fsm = RSP_IDLE; 5415 5403 } 5416 5404 } … … 5422 5410 case RSP_INS_UNC: 5423 5411 { 5424 if (p_vci.rspval.read() 5425 { 5426 assert( 5412 if (p_vci.rspval.read()) 5413 { 5414 assert(p_vci.reop.read() and 5427 5415 "illegal VCI response packet for uncachable instruction"); 5428 5416 5429 if ( (p_vci.rerror.read()&0x1) != 0) // error reported5417 if ((p_vci.rerror.read() & 0x1) != 0) // error reported 5430 5418 { 5431 5419 r_vci_rsp_ins_error = true; … … 5434 5422 else // no error reported 5435 5423 { 5436 if ( 5424 if (r_vci_rsp_fifo_icache.wok()) 5437 5425 { 5438 vci_rsp_fifo_icache_put 5439 vci_rsp_fifo_icache_data 5426 vci_rsp_fifo_icache_put = true; 5427 vci_rsp_fifo_icache_data = p_vci.rdata.read(); 5440 5428 r_vci_rsp_fsm = RSP_IDLE; 5441 5429 } … … 5447 5435 case RSP_DATA_MISS: 5448 5436 { 5449 if ( p_vci.rspval.read())5450 { 5451 if ( (p_vci.rerror.read()&0x1) != 0) // error reported5437 if (p_vci.rspval.read()) 5438 { 5439 if ((p_vci.rerror.read() & 0x1) != 0) // error reported 5452 5440 { 5453 5441 r_vci_rsp_data_error = true; 5454 if ( p_vci.reop.read()) r_vci_rsp_fsm = RSP_IDLE;5442 if (p_vci.reop.read()) r_vci_rsp_fsm = RSP_IDLE; 5455 5443 } 5456 5444 else // no error reported 5457 5445 { 5458 if ( r_vci_rsp_fifo_dcache.wok())5446 if (r_vci_rsp_fifo_dcache.wok()) 5459 5447 { 5460 assert( 5448 assert((r_vci_rsp_cpt.read() < m_dcache_words) and 5461 5449 "The VCI response packet for data miss is too long"); 5462 5450 5463 r_vci_rsp_cpt 5464 vci_rsp_fifo_dcache_put 5465 vci_rsp_fifo_dcache_data 5466 if ( p_vci.reop.read())5451 r_vci_rsp_cpt = r_vci_rsp_cpt.read() + 1; 5452 vci_rsp_fifo_dcache_put = true, 5453 vci_rsp_fifo_dcache_data = p_vci.rdata.read(); 5454 if (p_vci.reop.read()) 5467 5455 { 5468 assert( 5456 assert((r_vci_rsp_cpt.read() == m_dcache_words - 1) and 5469 5457 "The VCI response packet for data miss is too short"); 5470 5458 5471 r_vci_rsp_fsm 5459 r_vci_rsp_fsm = RSP_IDLE; 5472 5460 } 5473 5461 } … … 5479 5467 case RSP_DATA_UNC: 5480 5468 { 5481 if (p_vci.rspval.read() 5482 { 5483 assert( 5469 if (p_vci.rspval.read()) 5470 { 5471 assert(p_vci.reop.read() and 5484 5472 "illegal VCI response packet for uncachable read data"); 5485 5473 5486 if ( (p_vci.rerror.read()&0x1) != 0) // error reported5474 if ((p_vci.rerror.read() & 0x1) != 0) // error reported 5487 5475 { 5488 5476 r_vci_rsp_data_error = true; 5489 5477 r_vci_rsp_fsm = RSP_IDLE; 5490 5478 } 5491 else 5479 else // no error reported 5492 5480 { 5493 if ( 5481 if (r_vci_rsp_fifo_dcache.wok()) 5494 5482 { 5495 vci_rsp_fifo_dcache_put 5496 vci_rsp_fifo_dcache_data 5483 vci_rsp_fifo_dcache_put = true; 5484 vci_rsp_fifo_dcache_data = p_vci.rdata.read(); 5497 5485 r_vci_rsp_fsm = RSP_IDLE; 5498 5486 } … … 5504 5492 case RSP_DATA_LL: 5505 5493 { 5506 if ( p_vci.rspval.read())5507 { 5508 if ( (p_vci.rerror.read()&0x1) != 0) // error reported5494 if (p_vci.rspval.read()) 5495 { 5496 if ((p_vci.rerror.read() & 0x1) != 0) // error reported 5509 5497 { 5510 5498 r_vci_rsp_data_error = true; … … 5514 5502 if (r_vci_rsp_cpt.read() == 0) //first flit 5515 5503 { 5516 if (r_vci_rsp_fifo_dcache.wok())5504 if (r_vci_rsp_fifo_dcache.wok()) 5517 5505 { 5518 5506 assert(!p_vci.reop.read() && … … 5526 5514 else // last flit 5527 5515 { 5528 if (r_vci_rsp_fifo_dcache.wok())5516 if (r_vci_rsp_fifo_dcache.wok()) 5529 5517 { 5530 5518 assert(p_vci.reop.read() && … … 5544 5532 if (p_vci.rspval.read()) 5545 5533 { 5546 assert( 5534 assert(p_vci.reop.read() and 5547 5535 "a VCI response packet must contain one flit for a write transaction"); 5548 5536 5549 5537 r_vci_rsp_fsm = RSP_IDLE; 5550 uint32_t 5538 uint32_t wbuf_index = p_vci.rtrdid.read(); 5551 5539 r_wbuf.completed(wbuf_index); 5552 if ( (p_vci.rerror.read()&0x1) != 0) r_iss.setWriteBerr();5540 if ((p_vci.rerror.read() & 0x1) != 0) r_iss.setWriteBerr(); 5553 5541 } 5554 5542 break; … … 5563 5551 // soon as the request has been sent. 5564 5552 ///////////////////////////////////////////////////////////////////////////////////// 5565 switch ( r_cc_send_fsm.read())5553 switch (r_cc_send_fsm.read()) 5566 5554 { 5567 5555 /////////////////////////// … … 5575 5563 /////////////////////////////////////////////////////// 5576 5564 bool update_last_client = r_cc_send_last_client.read(); 5577 if ( r_cc_send_last_client.read() == 0) // last client was dcache5565 if (r_cc_send_last_client.read() == 0) // last client was dcache 5578 5566 { 5579 5567 if (r_icache_cc_send_req.read()) // request from icache … … 5591 5579 { 5592 5580 // the new client is dcache and has a cleanup request 5593 if ((update_last_client == 0) and5581 if ((update_last_client == 0) and 5594 5582 (r_dcache_cc_send_type.read() == CC_TYPE_CLEANUP)) 5595 5583 r_cc_send_fsm = CC_SEND_CLEANUP_1; 5596 5584 // the new client is dcache and has a multi acknowledgement request 5597 else if ( 5585 else if ((update_last_client == 0) and 5598 5586 (r_dcache_cc_send_type.read() == CC_TYPE_MULTI_ACK)) 5599 5587 r_cc_send_fsm = CC_SEND_MULTI_ACK; 5600 5588 // the new client is icache and has a cleanup request 5601 else if ( 5589 else if ((update_last_client == 1) and 5602 5590 (r_icache_cc_send_type.read() == CC_TYPE_CLEANUP)) 5603 5591 r_cc_send_fsm = CC_SEND_CLEANUP_1; 5604 5592 // the new client is icache and has a multi acknowledgement request 5605 else if ( 5593 else if ((update_last_client == 1) and 5606 5594 (r_icache_cc_send_type.read() == CC_TYPE_MULTI_ACK)) 5607 5595 r_cc_send_fsm = CC_SEND_MULTI_ACK; … … 5638 5626 { 5639 5627 // wait for the flit to be consumed 5640 if (p_dspin_p2m.read.read())5641 { 5642 if (r_cc_send_last_client.read() == 0) // dcache active request5628 if (p_dspin_p2m.read.read()) 5629 { 5630 if (r_cc_send_last_client.read() == 0) // dcache active request 5643 5631 r_dcache_cc_send_req = false; // reset dcache request 5644 5632 else // icache active request … … 5661 5649 // - CC_BROADCAST : Broadcast invalidate request (both DCACHE & ICACHE) 5662 5650 ////////////////////////////////////////////////////////////////////////////// 5663 switch ( r_cc_receive_fsm.read())5651 switch (r_cc_receive_fsm.read()) 5664 5652 { 5665 5653 ///////////////////// … … 5722 5710 // request dcache to handle the BROADCAST 5723 5711 r_cc_receive_dcache_req = true; 5724 r_cc_receive_dcache_nline 5712 r_cc_receive_dcache_nline = DspinDhccpParam::dspin_get(receive_data, 5725 5713 DspinDhccpParam::BROADCAST_NLINE); 5726 5714 r_cc_receive_dcache_type = CC_TYPE_INVAL; 5727 5715 // request icache to handle the BROADCAST 5728 5716 r_cc_receive_icache_req = true; 5729 r_cc_receive_icache_nline 5717 r_cc_receive_icache_nline = DspinDhccpParam::dspin_get(receive_data, 5730 5718 DspinDhccpParam::BROADCAST_NLINE); 5731 5719 r_cc_receive_icache_type = CC_TYPE_INVAL; … … 5758 5746 // for data INVAL, wait for dcache to take the request 5759 5747 if (p_dspin_m2p.write.read() and 5760 not r_cc_receive_dcache_req.read() 5748 not r_cc_receive_dcache_req.read()) 5761 5749 { 5762 5750 // request dcache to handle the INVAL … … 5777 5765 // for ins INVAL, wait for icache to take the request 5778 5766 if (p_dspin_m2p.write.read() and 5779 not r_cc_receive_icache_req.read() 5767 not r_cc_receive_icache_req.read()) 5780 5768 { 5781 5769 // request icache to handle the INVAL … … 5798 5786 if (not r_cc_receive_dcache_req.read()) 5799 5787 { 5800 r_cc_receive_dcache_updt_tab_idx 5788 r_cc_receive_dcache_updt_tab_idx = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_UPDT_INDEX); 5801 5789 r_cc_receive_fsm = CC_RECEIVE_DATA_UPDT_NLINE; 5802 5790 break; … … 5813 5801 if (not r_cc_receive_icache_req.read()) 5814 5802 { 5815 r_cc_receive_icache_updt_tab_idx 5803 r_cc_receive_icache_updt_tab_idx = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_UPDT_INDEX); 5816 5804 r_cc_receive_fsm = CC_RECEIVE_INS_UPDT_NLINE; 5817 5805 break; … … 5827 5815 // for data INVAL, wait for dcache to take the request and fifo to 5828 5816 // be empty 5829 if ( 5830 p_dspin_m2p.write.read() 5831 { 5832 r_cc_receive_dcache_req = true;5833 r_cc_receive_dcache_nline 5834 r_cc_receive_word_idx = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_WORD_INDEX);5835 r_cc_receive_dcache_type = CC_TYPE_UPDT;5817 if (r_cc_receive_updt_fifo_be.empty() and 5818 p_dspin_m2p.write.read()) 5819 { 5820 r_cc_receive_dcache_req = true; 5821 r_cc_receive_dcache_nline = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_NLINE); 5822 r_cc_receive_word_idx = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_WORD_INDEX); 5823 r_cc_receive_dcache_type = CC_TYPE_UPDT; 5836 5824 // get back to idle state 5837 5825 r_cc_receive_fsm = CC_RECEIVE_DATA_UPDT_DATA; … … 5847 5835 // for ins INVAL, wait for icache to take the request and fifo to be 5848 5836 // empty 5849 if ( 5850 p_dspin_m2p.write.read() 5851 { 5852 r_cc_receive_icache_req = true;5853 r_cc_receive_icache_nline 5854 r_cc_receive_word_idx = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_WORD_INDEX);5855 r_cc_receive_icache_type = CC_TYPE_UPDT;5837 if (r_cc_receive_updt_fifo_be.empty() and 5838 p_dspin_m2p.write.read()) 5839 { 5840 r_cc_receive_icache_req = true; 5841 r_cc_receive_icache_nline = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_NLINE); 5842 r_cc_receive_word_idx = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_WORD_INDEX); 5843 r_cc_receive_icache_type = CC_TYPE_UPDT; 5856 5844 // get back to idle state 5857 5845 r_cc_receive_fsm = CC_RECEIVE_INS_UPDT_DATA; … … 5872 5860 cc_receive_updt_fifo_eop = receive_eop; 5873 5861 cc_receive_updt_fifo_put = true; 5874 if ( 5862 if (receive_eop ) r_cc_receive_fsm = CC_RECEIVE_IDLE; 5875 5863 } 5876 5864 break; … … 5888 5876 cc_receive_updt_fifo_eop = receive_eop; 5889 5877 cc_receive_updt_fifo_put = true; 5890 if ( 5878 if (receive_eop ) r_cc_receive_fsm = CC_RECEIVE_IDLE; 5891 5879 } 5892 5880 break; … … 5900 5888 DspinDhccpParam::CLACK_TYPE); 5901 5889 5902 size_t clack_way 5890 size_t clack_way = DspinDhccpParam::dspin_get(r_dspin_clack_flit.read(), 5903 5891 DspinDhccpParam::CLACK_WAY); 5904 5892 5905 size_t clack_set 5893 size_t clack_set = DspinDhccpParam::dspin_get(r_dspin_clack_flit.read(), 5906 5894 DspinDhccpParam::CLACK_SET); 5907 5895 5908 bool dspin_clack_get 5896 bool dspin_clack_get = false; 5909 5897 bool dcache_clack_request = (clack_type == DspinDhccpParam::TYPE_CLACK_DATA); 5910 5898 bool icache_clack_request = (clack_type == DspinDhccpParam::TYPE_CLACK_INST); … … 5913 5901 { 5914 5902 // CLACK DATA: Send request to DCACHE FSM 5915 if (dcache_clack_request and not r_dcache_clack_req.read()){ 5903 if (dcache_clack_request and not r_dcache_clack_req.read()) 5904 { 5916 5905 r_dcache_clack_req = true; 5917 r_dcache_clack_way = clack_way & ((1ULL <<(uint32_log2(m_dcache_ways)))-1);5918 r_dcache_clack_set = clack_set & ((1ULL <<(uint32_log2(m_dcache_sets)))-1);5906 r_dcache_clack_way = clack_way & ((1ULL << (uint32_log2(m_dcache_ways))) - 1); 5907 r_dcache_clack_set = clack_set & ((1ULL << (uint32_log2(m_dcache_sets))) - 1); 5919 5908 dspin_clack_get = true; 5920 5909 } 5921 5910 5922 5911 // CLACK INST: Send request to ICACHE FSM 5923 else if (icache_clack_request and not r_icache_clack_req.read()){ 5912 else if (icache_clack_request and not r_icache_clack_req.read()) 5913 { 5924 5914 r_icache_clack_req = true; 5925 5915 r_icache_clack_way = clack_way & ((1ULL<<(uint32_log2(m_dcache_ways)))-1); … … 5971 5961 5972 5962 bool is_sc_or_cas = (r_vci_cmd_fsm.read() == CMD_DATA_CAS) or 5973 (r_vci_cmd_fsm.read() == CMD_DATA_SC 5963 (r_vci_cmd_fsm.read() == CMD_DATA_SC); 5974 5964 5975 5965 p_vci.pktid = 0; … … 5981 5971 p_vci.cfixed = false; 5982 5972 5983 if ( m_monitor_ok) {5984 if ( 5973 if (m_monitor_ok) { 5974 if (p_vci.cmdack.read() == true and p_vci.cmdval == true) { 5985 5975 if (((p_vci.address.read()) >= m_monitor_base) and 5986 ((p_vci.address.read()) < m_monitor_base + m_monitor_length) 5976 ((p_vci.address.read()) < m_monitor_base + m_monitor_length)) { 5987 5977 std::cout << "CC_VCACHE Monitor " << name() << std::hex 5988 5978 << " Access type = " << vci_cmd_type_str[p_vci.cmd.read()] … … 5990 5980 << " : address = " << p_vci.address.read() 5991 5981 << " / be = " << p_vci.be.read(); 5992 if ( 5982 if (p_vci.cmd.read() == vci_param::CMD_WRITE ) { 5993 5983 std::cout << " / data = " << p_vci.wdata.read(); 5994 5984 } … … 5998 5988 } 5999 5989 6000 switch ( r_vci_cmd_fsm.read()) {5990 switch (r_vci_cmd_fsm.read()) { 6001 5991 6002 5992 case CMD_IDLE: … … 6099 6089 p_vci.cmdval = true; 6100 6090 p_vci.address = r_dcache_vci_paddr.read() & ~0x3; 6101 if ( r_vci_cmd_cpt.read() == 0) p_vci.wdata = r_dcache_llsc_key.read();6102 else 6091 if (r_vci_cmd_cpt.read() == 0) p_vci.wdata = r_dcache_llsc_key.read(); 6092 else p_vci.wdata = r_dcache_vci_sc_data.read(); 6103 6093 p_vci.be = 0xF; 6104 6094 p_vci.trdid = 0; … … 6112 6102 p_vci.cmdval = true; 6113 6103 p_vci.address = r_dcache_vci_paddr.read() & ~0x3; 6114 if ( r_vci_cmd_cpt.read() == 0) p_vci.wdata = r_dcache_vci_cas_old.read();6115 else 6104 if (r_vci_cmd_cpt.read() == 0) p_vci.wdata = r_dcache_vci_cas_old.read(); 6105 else p_vci.wdata = r_dcache_vci_cas_new.read(); 6116 6106 p_vci.be = 0xF; 6117 6107 p_vci.trdid = 0; … … 6126 6116 // it depends on the VCI_RSP FSM 6127 6117 6128 switch (r_vci_rsp_fsm.read() 6118 switch (r_vci_rsp_fsm.read()) 6129 6119 { 6130 6120 case RSP_DATA_WRITE : p_vci.rspack = true; break; … … 6142 6132 6143 6133 uint64_t dspin_send_data = 0; 6144 switch ( r_cc_send_fsm.read())6134 switch (r_cc_send_fsm.read()) 6145 6135 { 6146 6136 ////////////////// … … 6154 6144 { 6155 6145 // initialize dspin send data 6156 // DspinDhccpParam::dspin_set(dspin_send_data,6157 // 0,6158 // DspinDhccpParam::P2M_EOP);6159 6146 DspinDhccpParam::dspin_set(dspin_send_data, 6160 6147 m_cc_global_id, … … 6164 6151 DspinDhccpParam::P2M_BC); 6165 6152 6166 if (r_cc_send_last_client.read() == 0) // dcache active request6153 if (r_cc_send_last_client.read() == 0) // dcache active request 6167 6154 { 6168 6155 uint64_t dest = (uint64_t) r_dcache_cc_send_nline.read() … … 6197 6184 6198 6185 DspinDhccpParam::dspin_set(dspin_send_data, 6199 (r_icache_cc_send_nline.read() & 0x300000000ULL) >>32,6186 (r_icache_cc_send_nline.read() & 0x300000000ULL) >> 32, 6200 6187 DspinDhccpParam::CLEANUP_NLINE_MSB); 6201 6188 … … 6218 6205 { 6219 6206 // initialize dspin send data 6220 // DspinDhccpParam::dspin_set(dspin_send_data, 6221 // 1, 6222 // DspinDhccpParam::P2M_EOP); 6223 6224 if(r_cc_send_last_client.read() == 0) // dcache active request 6207 6208 if (r_cc_send_last_client.read() == 0) // dcache active request 6225 6209 { 6226 6210 DspinDhccpParam::dspin_set(dspin_send_data, … … 6244 6228 { 6245 6229 // initialize dspin send data 6246 // DspinDhccpParam::dspin_set(dspin_send_data,6247 // 1,6248 // DspinDhccpParam::P2M_EOP);6249 6230 DspinDhccpParam::dspin_set(dspin_send_data, 6250 6231 0, … … 6254 6235 DspinDhccpParam::P2M_TYPE); 6255 6236 6256 if (r_cc_send_last_client.read() == 0) // dcache active request6237 if (r_cc_send_last_client.read() == 0) // dcache active request 6257 6238 { 6258 6239 uint64_t dest = (uint64_t) r_dcache_cc_send_nline.read() … … 6294 6275 // Receive coherence packets 6295 6276 // It depends on the CC_RECEIVE FSM 6296 switch ( r_cc_receive_fsm.read())6277 switch (r_cc_receive_fsm.read()) 6297 6278 { 6298 6279 ///////////////////// … … 6350 6331 case CC_RECEIVE_INS_UPDT_HEADER: 6351 6332 { 6352 if ( 6333 if (not r_cc_receive_icache_req.read()) 6353 6334 p_dspin_m2p.read = true; 6354 6335 else … … 6360 6341 case CC_RECEIVE_INS_UPDT_NLINE: 6361 6342 { 6362 if (r_cc_receive_updt_fifo_be.empty())6343 if (r_cc_receive_updt_fifo_be.empty()) 6363 6344 p_dspin_m2p.read = true; 6364 6345 else … … 6382 6363 DspinDhccpParam::CLACK_TYPE); 6383 6364 6384 bool dspin_clack_get 6365 bool dspin_clack_get = false; 6385 6366 bool dcache_clack_request = (clack_type == DspinDhccpParam::TYPE_CLACK_DATA); 6386 6367 bool icache_clack_request = (clack_type == DspinDhccpParam::TYPE_CLACK_INST); … … 6411 6392 // This version of monitor print both Read and Write request 6412 6393 { 6413 m_monitor_ok 6414 m_monitor_base 6415 m_monitor_length 6394 m_monitor_ok = true; 6395 m_monitor_base = base; 6396 m_monitor_length = length; 6416 6397 } 6417 6398 6418 6399 tmpl(void)::stop_monitor() 6419 6400 { 6420 m_monitor_ok 6401 m_monitor_ok = false; 6421 6402 } 6422 6403 -
trunk/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp
r781 r789 827 827 { 828 828 m_cpt_reset_count = m_cpt_cycles; 829 829 830 m_cpt_read_local = 0; 830 831 m_cpt_read_remote = 0; 831 832 m_cpt_read_cost = 0; 833 832 834 m_cpt_write_local = 0; 833 835 m_cpt_write_remote = 0; … … 835 837 m_cpt_write_flits_remote = 0; 836 838 m_cpt_write_cost = 0; 839 837 840 m_cpt_ll_local = 0; 838 841 m_cpt_ll_remote = 0; 839 842 m_cpt_ll_cost = 0; 843 840 844 m_cpt_sc_local = 0; 841 845 m_cpt_sc_remote = 0; 842 846 m_cpt_sc_cost = 0; 847 843 848 m_cpt_cas_local = 0; 844 849 m_cpt_cas_remote = 0; 845 850 m_cpt_cas_cost = 0; 851 846 852 m_cpt_update = 0; 847 853 m_cpt_update_local = 0; 848 854 m_cpt_update_remote = 0; 849 855 m_cpt_update_cost = 0; 856 850 857 m_cpt_minval = 0; 851 858 m_cpt_minval_local = 0; 852 859 m_cpt_minval_remote = 0; 853 860 m_cpt_minval_cost = 0; 861 854 862 m_cpt_binval = 0; 863 m_cpt_write_broadcast = 0; 864 855 865 m_cpt_cleanup_local = 0; 856 866 m_cpt_cleanup_remote = 0; 857 867 m_cpt_cleanup_cost = 0; 868 858 869 m_cpt_read_miss = 0; 859 870 m_cpt_write_miss = 0; 860 871 m_cpt_write_dirty = 0; 872 861 873 m_cpt_trt_rb = 0; 862 874 m_cpt_trt_full = 0; … … 915 927 << "[080] BROADCAT INVAL = " << m_cpt_binval << std::endl 916 928 << "[081] WRITE BROADCAST = " << m_cpt_write_broadcast << std::endl 929 << "[082] GETM BROADCAST = " << "0" << std::endl 917 930 << std::endl 918 931 << "[090] LOCAL CLEANUP = " << m_cpt_cleanup_local << std::endl 919 932 << "[091] REMOTE CLEANUP = " << m_cpt_cleanup_remote << std::endl 920 933 << "[092] CLNUP COST (FLITS * DIST) = " << m_cpt_cleanup_cost << std::endl 921 << "[093] CLEANUP DATA = " << "0" << std::endl 934 << "[093] LOCAL CLEANUP DATA = " << "0" << std::endl 935 << "[094] REMOTE CLEANUP DATA = " << "0" << std::endl 936 << "[095] CLEANUP DATA COST = " << "0" << std::endl 922 937 << std::endl 923 938 << "[100] READ MISS = " << m_cpt_read_miss << std::endl 924 939 << "[101] WRITE MISS = " << m_cpt_write_miss << std::endl 925 940 << "[102] WRITE DIRTY = " << m_cpt_write_dirty << std::endl 941 << "[103] GETM MISS = " << "0" << std::endl 926 942 << std::endl 927 943 << "[110] RD BLOCKED BY HIT IN TRT = " << m_cpt_trt_rb << std::endl … … 933 949 << "[140] NCC TO CC (READ) = " << "0" << std::endl 934 950 << "[141] NCC TO CC (WRITE) = " << "0" << std::endl 951 << std::endl 952 << "[150] LOCAL GETM = " << "0" << std::endl 953 << "[151] REMOTE GETM = " << "0" << std::endl 954 << "[152] GETM COST (FLITS * DIST) = " << "0" << std::endl 955 << std::endl 956 << "[160] LOCAL INVAL RO = " << "0" << std::endl 957 << "[161] REMOTE INVAL RO = " << "0" << std::endl 958 << "[162] INVAL RO COST = " << "0" << std::endl 935 959 << std::endl; 936 960 } 937 938 if (stats) { 939 std::cout << "----------------------------------" << std::dec << std::endl; 940 std::cout << "--- Calculated Stats ---" << std::dec << std::endl; 941 std::cout << "----------------------------------" << std::dec << std::endl; 942 std::cout 943 << "[300] READ TOTAL = " << m_cpt_read_local + m_cpt_read_remote << std::endl 944 << "[301] READ RATE = " << (double) (m_cpt_read_local + m_cpt_read_remote) / m_cpt_cycles << std::endl 945 << "[302] LOCAL READ RATE = " << (double) m_cpt_read_local / m_cpt_cycles << std::endl 946 << "[303] REMOTE READ RATE = " << (double) m_cpt_read_remote / m_cpt_cycles << std::endl 947 << "[304] READ MISS RATE = " << (double) m_cpt_read_miss / (m_cpt_read_local + m_cpt_read_remote) << std::endl 948 << std::endl 949 << "[305] WRITE TOTAL = " << m_cpt_write_local + m_cpt_write_remote << std::endl 950 << "[306] WRITE RATE = " << (double) (m_cpt_write_local + m_cpt_write_remote) / m_cpt_cycles << std::endl 951 << "[307] LOCAL WRITE RATE = " << (double) m_cpt_write_local / m_cpt_cycles << std::endl 952 << "[308] REMOTE WRITE RATE = " << (double) m_cpt_write_remote / m_cpt_cycles << std::endl 953 << "[309] WRITE MISS RATE = " << (double) m_cpt_write_miss / (m_cpt_write_local + m_cpt_write_remote) << std::endl 954 << "[310] WRITE BURST TOTAL = " << m_cpt_write_flits_local + m_cpt_write_flits_remote << std::endl 955 << "[311] WRITE BURST AVERAGE = " << (double) (m_cpt_write_flits_local + m_cpt_write_flits_remote) / (m_cpt_write_local + m_cpt_write_remote) << std::endl 956 << "[312] LOCAL WRITE BURST AV. = " << (double) m_cpt_write_flits_local / (m_cpt_write_local + m_cpt_write_remote) << std::endl 957 << "[313] REMOTE WRITE BURST AV = " << (double) m_cpt_write_flits_remote / (m_cpt_write_local + m_cpt_write_remote) << std::endl 958 << std::endl 959 << "[314] UPDATE RATE = " << (double) m_cpt_update / m_cpt_cycles << std::endl 960 << "[315] AV. UPDATE PER UP REQ = " << (double) (m_cpt_update_local + m_cpt_update_remote) / m_cpt_update << std::endl 961 << "[316] AV. LOC UPDT PER UP REQ = " << (double) m_cpt_update_local / m_cpt_update << std::endl 962 << "[317] AV. REMOTE UPDT PER UP REQ = " << (double) m_cpt_update_remote / m_cpt_update << std::endl 963 << std::endl 964 << "[318] INVAL MULTICAST RATE = " << (double) m_cpt_minval / m_cpt_cycles << std::endl 965 << "[319] AVE. INVAL PER M_INV = " << (double) (m_cpt_minval_local + m_cpt_minval_remote) / m_cpt_minval << std::endl 966 << "[320] AV. LOC INV PER M_INV = " << (double) m_cpt_minval_local / m_cpt_minval << std::endl 967 << "[321] AV. REM INV PER M_INV = " << (double) m_cpt_minval_remote / m_cpt_minval << std::endl 968 << std::endl 969 << "[322] INVAL BROADCAST RATE = " << (double) m_cpt_binval / m_cpt_cycles << std::endl 970 << "[323] WRITE DIRTY RATE = " << (double) m_cpt_write_dirty / m_cpt_cycles << std::endl 971 << std::endl 972 << "[324] CLEANUP RATE = " << (double) (m_cpt_cleanup_local + m_cpt_cleanup_remote) / m_cpt_cycles << std::endl 973 << "[325] LOCAL CLEANUP RATE = " << (double) m_cpt_cleanup_local / m_cpt_cycles << std::endl 974 << "[326] REMOTE CLEANUP RATE = " << (double) m_cpt_cleanup_remote / m_cpt_cycles << std::endl 975 << "[327] LL RATE = " << (double) (m_cpt_ll_local + m_cpt_ll_remote) / m_cpt_cycles << std::endl 976 << "[328] LOCAL LL RATE = " << (double) m_cpt_ll_local / m_cpt_cycles << std::endl 977 << "[329] REMOTE LL RATE = " << (double) m_cpt_ll_remote / m_cpt_cycles << std::endl 978 << "[330] SC RATE = " << (double) (m_cpt_sc_local + m_cpt_sc_remote) / m_cpt_cycles << std::endl 979 << "[331] LOCAL SC RATE = " << (double) m_cpt_sc_local / m_cpt_cycles << std::endl 980 << "[332] REMOTE SC RATE = " << (double) m_cpt_sc_remote / m_cpt_cycles << std::endl 981 << "[333] CAS RATE = " << (double) (m_cpt_cas_local + m_cpt_cas_remote) / m_cpt_cycles << std::endl 982 << "[334] LOCAL CAS RATE = " << (double) m_cpt_cas_local / m_cpt_cycles << std::endl 983 << "[335] REMOTE CAS RATE = " << (double) m_cpt_cas_remote / m_cpt_cycles << std::endl 984 << std::endl 985 << std::endl; 986 } 961 // No more computed stats 987 962 } 988 963 … … 1141 1116 m_cpt_cycles = 0; 1142 1117 m_cpt_reset_count = 0; 1118 1143 1119 m_cpt_read_local = 0; 1144 1120 m_cpt_read_remote = 0; 1145 1121 m_cpt_read_cost = 0; 1122 1146 1123 m_cpt_write_local = 0; 1147 1124 m_cpt_write_remote = 0; … … 1149 1126 m_cpt_write_flits_remote = 0; 1150 1127 m_cpt_write_cost = 0; 1128 1151 1129 m_cpt_ll_local = 0; 1152 1130 m_cpt_ll_remote = 0; 1153 1131 m_cpt_ll_cost = 0; 1132 1154 1133 m_cpt_sc_local = 0; 1155 1134 m_cpt_sc_remote = 0; 1156 1135 m_cpt_sc_cost = 0; 1136 1157 1137 m_cpt_cas_local = 0; 1158 1138 m_cpt_cas_remote = 0; 1159 1139 m_cpt_cas_cost = 0; 1140 1160 1141 m_cpt_update = 0; 1161 1142 m_cpt_update_local = 0; 1162 1143 m_cpt_update_remote = 0; 1163 1144 m_cpt_update_cost = 0; 1145 1164 1146 m_cpt_minval = 0; 1165 1147 m_cpt_minval_local = 0; 1166 1148 m_cpt_minval_remote = 0; 1167 1149 m_cpt_minval_cost = 0; 1150 1168 1151 m_cpt_binval = 0; 1152 m_cpt_write_broadcast = 0; 1153 1169 1154 m_cpt_cleanup_local = 0; 1170 1155 m_cpt_cleanup_remote = 0; 1171 1156 m_cpt_cleanup_cost = 0; 1172 1157 1173 m_cpt_read_miss = 0;1174 m_cpt_write_miss = 0;1175 m_cpt_write_dirty = 0;1176 m_cpt_write_broadcast = 0;1177 m_cpt_trt_rb = 0;1178 m_cpt_trt_full = 0;1179 m_cpt_get = 0;1180 m_cpt_put = 0;1158 m_cpt_read_miss = 0; 1159 m_cpt_write_miss = 0; 1160 m_cpt_write_dirty = 0; 1161 1162 m_cpt_trt_rb = 0; 1163 m_cpt_trt_full = 0; 1164 m_cpt_get = 0; 1165 m_cpt_put = 0; 1181 1166 1182 1167 return; … … 1692 1677 // <Activity counters> 1693 1678 if (p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ) { 1694 if (is_local_req(p_vci_tgt.srcid.read())) m_cpt_ll_local++; 1695 else m_cpt_ll_remote++; 1696 m_cpt_ll_cost += req_distance(p_vci_tgt.srcid.read()); // LL on a single word 1679 if (is_local_req(p_vci_tgt.srcid.read())) 1680 { 1681 m_cpt_ll_local++; 1682 } 1683 else 1684 { 1685 m_cpt_ll_remote++; 1686 } 1687 // (1 (CMD) + 2 (RSP)) VCI flits for LL => 2 + 3 dspin flits 1688 m_cpt_ll_cost += 5 * req_distance(p_vci_tgt.srcid.read()); 1697 1689 } 1698 1690 else { 1699 if (is_local_req(p_vci_tgt.srcid.read())) m_cpt_read_local++; 1700 else m_cpt_read_remote++; 1701 m_cpt_read_cost += req_distance(p_vci_tgt.srcid.read()); 1691 if (is_local_req(p_vci_tgt.srcid.read())) 1692 { 1693 m_cpt_read_local++; 1694 } 1695 else 1696 { 1697 m_cpt_read_remote++; 1698 } 1699 // (1 (CMD) + m_words (RSP)) flits VCI => 2 + m_words + 1 flits dspin 1700 m_cpt_read_cost += (3 + m_words) * req_distance(p_vci_tgt.srcid.read()); 1702 1701 } 1703 1702 // </Activity counters> … … 1710 1709 if (p_vci_tgt.cmdval and m_cmd_write_addr_fifo.wok()) 1711 1710 { 1712 1711 uint32_t plen = p_vci_tgt.plen.read(); 1713 1712 #if DEBUG_MEMC_TGT_CMD 1714 1713 if (m_debug) … … 1725 1724 // <Activity counters> 1726 1725 if (p_vci_tgt.cmd.read() == vci_param_int::CMD_NOP) { 1727 m_cpt_sc_cost += req_distance(p_vci_tgt.srcid.read()); 1726 // (2 (CMD) + 1 (RSP)) flits VCI => 4 + (1 (success) || 2 (failure)) flits dspin 1727 m_cpt_sc_cost += 5 * req_distance(p_vci_tgt.srcid.read()); 1728 1728 } 1729 1729 else { 1730 if (is_local_req(p_vci_tgt.srcid.read())) m_cpt_write_flits_local++; 1731 else m_cpt_write_flits_remote++; 1732 m_cpt_write_cost += req_distance(p_vci_tgt.srcid.read()); 1730 if (is_local_req(p_vci_tgt.srcid.read())) 1731 { 1732 m_cpt_write_flits_local++; 1733 } 1734 else 1735 { 1736 m_cpt_write_flits_remote++; 1737 } 1738 // (burst_size (CMD) + 1 (RSP) flits VCI => 2 + burst_size + 1 flits dspin 1739 m_cpt_write_cost += (3 + (plen >> 2)) * req_distance(p_vci_tgt.srcid.read()); 1733 1740 } 1734 1741 // </Activity counters> … … 1737 1744 // <Activity counters> 1738 1745 if (p_vci_tgt.cmd.read() == vci_param_int::CMD_NOP) { 1739 if (is_local_req(p_vci_tgt.srcid.read())) m_cpt_sc_local++; 1740 else m_cpt_sc_remote++; 1741 1746 if (is_local_req(p_vci_tgt.srcid.read())) 1747 { 1748 m_cpt_sc_local++; 1749 } 1750 else 1751 { 1752 m_cpt_sc_remote++; 1753 } 1742 1754 } 1743 1755 else { 1744 if (is_local_req(p_vci_tgt.srcid.read())) m_cpt_write_local++; 1745 else m_cpt_write_remote++; 1756 if (is_local_req(p_vci_tgt.srcid.read())) 1757 { 1758 m_cpt_write_local++; 1759 } 1760 else 1761 { 1762 m_cpt_write_remote++; 1763 } 1746 1764 } 1747 1765 // </Activity counters> … … 1777 1795 if (p_vci_tgt.eop) { 1778 1796 // <Activity counters> 1779 if (is_local_req(p_vci_tgt.srcid.read())) m_cpt_cas_local++; 1780 else m_cpt_cas_remote++; 1781 m_cpt_cas_cost += req_distance(p_vci_tgt.srcid.read()); 1797 if (is_local_req(p_vci_tgt.srcid.read())) 1798 { 1799 m_cpt_cas_local++; 1800 } 1801 else 1802 { 1803 m_cpt_cas_remote++; 1804 } 1805 // (2 (CMD) + 1 (RSP)) flits VCI => 4 + (1 (success) || 2 (failure)) flits dspin 1806 m_cpt_cas_cost += 5 * req_distance(p_vci_tgt.srcid.read()); 1782 1807 // </Activity counters> 1783 1808 r_tgt_cmd_fsm = TGT_CMD_IDLE; … … 6575 6600 { 6576 6601 m_cpt_minval_remote++; 6577 m_cpt_minval_cost += req_distance(m_config_to_cc_send_srcid_fifo.read()); 6578 } 6602 } 6603 // 2 flits for multi inval 6604 m_cpt_minval_cost += 2 * req_distance(m_config_to_cc_send_srcid_fifo.read()); 6579 6605 // </Activity Counters> 6580 6606 r_cc_send_fsm = CC_SEND_CONFIG_INVAL_NLINE; … … 6642 6668 { 6643 6669 m_cpt_minval_remote++; 6644 m_cpt_minval_cost += req_distance(m_xram_rsp_to_cc_send_srcid_fifo.read()); 6645 } 6670 } 6671 // 2 flits for multi inval 6672 m_cpt_minval_cost += 2 * req_distance(m_xram_rsp_to_cc_send_srcid_fifo.read()); 6646 6673 // </Activity Counters> 6647 6674 r_cc_send_fsm = CC_SEND_XRAM_RSP_INVAL_NLINE; … … 6737 6764 { 6738 6765 m_cpt_update_remote++; 6739 m_cpt_update_cost += req_distance(m_write_to_cc_send_srcid_fifo.read()); 6740 } 6766 } 6767 // 2 flits for multi update 6768 m_cpt_update_cost += 2 * req_distance(m_write_to_cc_send_srcid_fifo.read()); 6741 6769 // </Activity Counters> 6742 6770 … … 6826 6854 { 6827 6855 m_cpt_update_remote++; 6828 m_cpt_update_cost += req_distance(m_cas_to_cc_send_srcid_fifo.read()); 6829 } 6856 } 6857 // 2 flits for multi update 6858 m_cpt_update_cost += 2 * req_distance(m_cas_to_cc_send_srcid_fifo.read()); 6830 6859 // </Activity Counters> 6831 6860 r_cc_send_fsm = CC_SEND_CAS_UPDT_NLINE; … … 6951 6980 else { 6952 6981 m_cpt_cleanup_remote++; 6953 m_cpt_cleanup_cost += req_distance(srcid); 6954 } 6982 } 6983 // 2 flits for cleanup without data 6984 m_cpt_cleanup_cost += 2 * req_distance(srcid); 6955 6985 // </Activity Counters> 6956 6986
Note: See TracChangeset
for help on using the changeset viewer.