- Timestamp:
- Oct 1, 2014, 5:44:55 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/RWT/modules/vci_cc_vcache_wrapper/caba/source/src/vci_cc_vcache_wrapper.cpp
r824 r827 37 37 #define DEBUG_ICACHE 1 38 38 #define DEBUG_CMD 0 39 #define INSTRUMENTATION 140 39 41 40 namespace soclib { … … 43 42 44 43 namespace { 45 const char * icache_fsm_state_str[] = {44 const char * icache_fsm_state_str[] = { 46 45 "ICACHE_IDLE", 47 46 … … 69 68 }; 70 69 71 const char * dcache_fsm_state_str[] = {70 const char * dcache_fsm_state_str[] = { 72 71 "DCACHE_IDLE", 73 72 … … 122 121 }; 123 122 124 const char * cmd_fsm_state_str[] = {123 const char * cmd_fsm_state_str[] = { 125 124 "CMD_IDLE", 126 125 "CMD_INS_MISS", … … 135 134 }; 136 135 137 const char * vci_pktid_type_str[] = {136 const char * vci_pktid_type_str[] = { 138 137 "TYPE_DATA_UNC", 139 138 "TYPE_READ_DATA_MISS", … … 146 145 }; 147 146 148 const char * vci_cmd_type_str[] = {147 const char * vci_cmd_type_str[] = { 149 148 "NOP or STORE_COND", 150 149 "READ", … … 153 152 }; 154 153 155 const char * rsp_fsm_state_str[] = {154 const char * rsp_fsm_state_str[] = { 156 155 "RSP_IDLE", 157 156 "RSP_INS_MISS", … … 163 162 }; 164 163 165 const char * cc_receive_fsm_state_str[] = {164 const char * cc_receive_fsm_state_str[] = { 166 165 "CC_RECEIVE_IDLE", 167 166 "CC_RECEIVE_BRDCAST_HEADER", … … 179 178 }; 180 179 181 const char * cc_send_fsm_state_str[] = {180 const char * cc_send_fsm_state_str[] = { 182 181 "CC_SEND_IDLE", 183 182 "CC_SEND_CLEANUP_1", … … 199 198 ///////////////////////////////// 200 199 tmpl(/**/)::VciCcVCacheWrapper( 201 sc_module_name 202 const int 203 const MappingTable 204 const IntTab 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 size_t 215 const size_t 216 const size_t 217 const size_t 218 const size_t 219 const size_t 220 const uint32_t 221 const uint32_t 222 const bool debug_ok)200 sc_module_name name, 201 const int proc_id, 202 const MappingTable &mtd, 203 const IntTab &srcid, 204 const size_t cc_global_id, 205 const size_t itlb_ways, 206 const size_t itlb_sets, 207 const size_t dtlb_ways, 208 const size_t dtlb_sets, 209 const size_t icache_ways, 210 const size_t icache_sets, 211 const size_t icache_words, 212 const size_t dcache_ways, 213 const size_t dcache_sets, 214 const size_t dcache_words, 215 const size_t wbuf_nlines, 216 const size_t wbuf_nwords, 217 const size_t x_width, 218 const size_t y_width, 219 const uint32_t max_frozen_cycles, 220 const uint32_t debug_start_cycle, 221 const bool debug_ok) 223 222 : soclib::caba::BaseModule(name), 224 223 … … 230 229 p_dspin_clack("p_dspin_clack"), 231 230 232 m_cacheability_table( mtd.getCacheabilityTable()),233 m_srcid( mtd.indexForId(srcid)),234 m_cc_global_id( cc_global_id),235 m_nline_width( vci_param::N - (uint32_log2(dcache_words)) - 2),236 m_itlb_ways( itlb_ways),237 m_itlb_sets( itlb_sets),238 m_dtlb_ways( dtlb_ways),239 m_dtlb_sets( dtlb_sets),240 m_icache_ways( icache_ways),241 m_icache_sets( icache_sets),242 m_icache_yzmask( (~0)<<(uint32_log2(icache_words) + 2)),243 m_icache_words( icache_words),244 m_dcache_ways( dcache_ways),245 m_dcache_sets( dcache_sets),246 m_dcache_yzmask( (~0)<<(uint32_log2(dcache_words) + 2)),247 m_dcache_words( dcache_words),248 m_x_width( x_width),249 m_y_width( y_width),250 m_proc_id( proc_id),251 m_max_frozen_cycles( max_frozen_cycles),252 m_paddr_nbits( vci_param::N),253 m_debug_start_cycle( debug_start_cycle),254 m_debug_ok( debug_ok),231 m_cacheability_table(mtd.getCacheabilityTable()), 232 m_srcid(mtd.indexForId(srcid)), 233 m_cc_global_id(cc_global_id), 234 m_nline_width(vci_param::N - (uint32_log2(dcache_words)) - 2), 235 m_itlb_ways(itlb_ways), 236 m_itlb_sets(itlb_sets), 237 m_dtlb_ways(dtlb_ways), 238 m_dtlb_sets(dtlb_sets), 239 m_icache_ways(icache_ways), 240 m_icache_sets(icache_sets), 241 m_icache_yzmask((~0) << (uint32_log2(icache_words) + 2)), 242 m_icache_words(icache_words), 243 m_dcache_ways(dcache_ways), 244 m_dcache_sets(dcache_sets), 245 m_dcache_yzmask((~0) << (uint32_log2(dcache_words) + 2)), 246 m_dcache_words(dcache_words), 247 m_x_width(x_width), 248 m_y_width(y_width), 249 m_proc_id(proc_id), 250 m_max_frozen_cycles(max_frozen_cycles), 251 m_paddr_nbits(vci_param::N), 252 m_debug_start_cycle(debug_start_cycle), 253 m_debug_ok(debug_ok), 255 254 m_dcache_paddr_ext_reset(0), 256 255 m_icache_paddr_ext_reset(0), … … 281 280 r_icache_cc_need_write("r_icache_cc_need_write"), 282 281 282 r_icache_clack_req("r_icache_clack_req"), 283 r_icache_clack_way("r_icache_clack_way"), 284 r_icache_clack_set("r_icache_clack_set"), 285 283 286 r_icache_flush_count("r_icache_flush_count"), 284 287 … … 286 289 r_icache_unc_req("r_icache_unc_req"), 287 290 288 r_icache_tlb_miss_req("r_icache_tlb_ read_req"),291 r_icache_tlb_miss_req("r_icache_tlb_miss_req"), 289 292 r_icache_tlb_rsp_error("r_icache_tlb_rsp_error"), 290 293 … … 297 300 r_icache_cc_send_way("r_icache_cc_send_way"), 298 301 r_icache_cc_send_updt_tab_idx("r_icache_cc_send_updt_tab_idx"), 302 303 r_icache_paddr_ext("r_icache_paddr_ext"), 299 304 300 305 r_dcache_fsm("r_dcache_fsm"), … … 329 334 r_dcache_vci_sc_data("r_dcache_vci_sc_data"), 330 335 336 r_cas_islocal("r_cas_islocal"), 337 r_cas_local_way("r_cas_local_way"), 338 r_cas_local_set("r_cas_local_set"), 339 r_cas_local_word("r_cas_local_word"), 340 331 341 r_dcache_xtn_way("r_dcache_xtn_way"), 332 342 r_dcache_xtn_set("r_dcache_xtn_set"), … … 337 347 r_dcache_miss_set("r_dcache_miss_set"), 338 348 r_dcache_miss_inval("r_dcache_miss_inval"), 349 r_dcache_miss_clack("r_dcache_miss_clack"), 339 350 340 351 r_dcache_cc_way("r_dcache_cc_way"), 341 352 r_dcache_cc_set("r_dcache_cc_set"), 353 r_dcache_cc_state("r_dcache_cc_state"), 342 354 r_dcache_cc_word("r_dcache_cc_word"), 343 355 r_dcache_cc_need_write("r_dcache_cc_need_write"), 356 r_dcache_cc_inval_addr("r_dcache_cc_inval_addr"), 357 r_dcache_cc_inval_data_cpt("r_dcache_cc_inval_data_cpt"), 358 359 r_dcache_clack_req("r_dcache_clack_req"), 360 r_dcache_clack_way("r_dcache_clack_way"), 361 r_dcache_clack_set("r_dcache_clack_set"), 344 362 345 363 r_dcache_flush_count("r_dcache_flush_count"), … … 349 367 r_dcache_tlb_vaddr("r_dcache_tlb_vaddr"), 350 368 r_dcache_tlb_ins("r_dcache_tlb_ins"), 369 r_dcache_tlb_paddr("r_dcache_tlb_paddr"), 351 370 r_dcache_tlb_pte_flags("r_dcache_tlb_pte_flags"), 352 371 r_dcache_tlb_pte_ppn("r_dcache_tlb_pte_ppn"), 372 r_dcache_tlb_cache_way("r_dcache_tlb_cache_way"), 373 r_dcache_tlb_cache_set("r_dcache_tlb_cache_set"), 374 r_dcache_tlb_cache_word("r_dcache_tlb_cache_word"), 353 375 r_dcache_tlb_way("r_dcache_tlb_way"), 354 376 r_dcache_tlb_set("r_dcache_tlb_set"), … … 361 383 362 384 r_dcache_cleanup_victim_req("r_dcache_cleanup_victim_req"), 385 r_dcache_cleanup_victim_line_ncc("r_dcache_cleanup_victim_line_ncc"), 386 r_dcache_cleanup_victim_updt_data("r_dcache_cleanup_victim_updt_data"), 363 387 r_dcache_cleanup_victim_nline("r_dcache_cleanup_victim_nline"), 364 388 … … 369 393 r_dcache_cc_send_updt_tab_idx("r_dcache_cc_send_updt_tab_idx"), 370 394 395 r_dcache_cc_cleanup_updt_data("r_dcache_cc_cleanup_updt_data"), 396 r_dcache_cc_cleanup_line_ncc("r_dcache_cc_cleanup_line_ncc"), 397 r_dcache_dirty_save("r_dcache_dirty_save"), 398 r_cc_send_cpt_word("r_cc_send_cpt_word"), 399 r_dcache_miss_data_cpt("r_dcache_miss_data_cpt"), 400 r_dcache_miss_data_addr("r_dcache_miss_data_addr"), 401 r_dcache_xtn_flush_data_cpt("r_dcache_xtn_flush_data_cpt"), 402 r_dcache_xtn_flush_addr_data("r_dcache_xtn_flush_addr_data"), 403 r_dcache_xtn_state("r_dcache_xtn_state"), 404 r_dcache_xtn_data_addr("r_dcache_xtn_data_addr"), 405 r_dcache_xtn_data_cpt("r_dcache_xtn_data_cpt"), 406 r_dcache_read_state("r_dcache_read_state"), 407 408 r_dcache_paddr_ext("r_dcache_paddr_ext"), 409 371 410 r_vci_cmd_fsm("r_vci_cmd_fsm"), 372 411 r_vci_cmd_min("r_vci_cmd_min"), … … 379 418 r_vci_rsp_ins_error("r_vci_rsp_ins_error"), 380 419 r_vci_rsp_data_error("r_vci_rsp_data_error"), 381 r_vci_rsp_fifo_icache("r_vci_rsp_fifo_icache", 2), 382 r_vci_rsp_fifo_dcache("r_vci_rsp_fifo_dcache", 2), 383 r_vci_rsp_fifo_rpktid("r_vci_rsp_fifo_rpktid", 2), 420 r_vci_rsp_fifo_icache("r_vci_rsp_fifo_icache", 2), // 2 words depth 421 r_vci_rsp_fifo_dcache("r_vci_rsp_fifo_dcache", 2), // 2 words depth 422 r_vci_rsp_fifo_rpktid("r_vci_rsp_fifo_rpktid", 2), // 2 words depth 384 423 r_cc_send_data_fifo("r_cc_send_data_fifo", 16), 385 424 … … 407 446 r_cc_receive_dcache_updt_tab_idx("r_cc_receive_dcache_updt_tab_idx"), 408 447 r_cc_receive_dcache_nline("r_cc_receive_dcache_nline"), 448 r_cc_receive_dcache_inval_is_config("r_cc_receive_dcache_inval_is_config"), 449 450 r_dspin_clack_req("r_dspin_clack_req"), 451 r_dspin_clack_flit("r_dspin_clack_flit"), 409 452 410 453 r_iss(this->name(), proc_id), … … 412 455 r_icache("icache", icache_ways, icache_sets, icache_words), 413 456 r_dcache("dcache", dcache_ways, dcache_sets, dcache_words), 414 r_itlb("itlb", proc_id, itlb_ways,itlb_sets,vci_param::N), 415 r_dtlb("dtlb", proc_id, dtlb_ways,dtlb_sets,vci_param::N) 457 r_itlb("itlb", proc_id, itlb_ways, itlb_sets, vci_param::N), 458 r_dtlb("dtlb", proc_id, dtlb_ways, dtlb_sets, vci_param::N), 459 460 r_dcache_llsc_paddr("r_dcache_llsc_paddr"), 461 r_dcache_llsc_key("r_dcache_llsc_key"), 462 r_dcache_llsc_count("r_dcache_llsc_count"), 463 r_dcache_llsc_valid("r_dcache_llsc_valid") 416 464 { 417 465 std::cout << " - Building VciCcVcacheWrapper : " << name << std::endl; 418 466 419 assert( ((icache_words*vci_param::B) < (1<<vci_param::K)) and467 assert(((icache_words*vci_param::B) < (1 << vci_param::K)) and 420 468 "Need more PLEN bits."); 421 469 422 assert( (vci_param::T > 2) and ((1<<(vci_param::T-1)) >= (wbuf_nlines)) and470 assert((vci_param::T > 2) and ((1 << (vci_param::T - 1)) >= (wbuf_nlines)) and 423 471 "Need more TRDID bits."); 424 472 425 assert( 473 assert((icache_words == dcache_words) and 426 474 "icache_words and dcache_words parameters must be equal"); 427 475 428 assert( 476 assert((itlb_sets == dtlb_sets) and 429 477 "itlb_sets and dtlb_sets parameters must be equal"); 430 478 431 assert( 479 assert((itlb_ways == dtlb_ways) and 432 480 "itlb_ways and dtlb_ways parameters must be equal"); 433 481 … … 436 484 (uint32_log2(m_itlb_ways) << 15) | (uint32_log2(m_itlb_sets) << 11) | 437 485 (uint32_log2(m_icache_ways) << 8) | (uint32_log2(m_icache_sets) << 4) | 438 (uint32_log2(m_icache_words<<2)); 439 440 r_mmu_release = (uint32_t)(1 << 16) | 0x1; 441 442 ////////////////////MODIFIED/////////////////////////////// 443 //r_dcache_in_tlb = new bool[dcache_ways*dcache_sets]; 444 //r_dcache_contains_ptd = new bool[dcache_ways*dcache_sets]; 445 r_dcache_content_state = new int [dcache_ways*dcache_sets]; 446 r_dcache_dirty_word = new int [dcache_ways*dcache_sets*dcache_words]; 447 r_dcache_zombi_ncc = new bool [dcache_ways*dcache_sets]; 448 /////////////////////////////////////////////////////////// 486 (uint32_log2(m_icache_words << 2)); 487 488 r_mmu_release = (uint32_t) (1 << 16) | 0x1; 489 490 r_dcache_content_state = new int[dcache_ways * dcache_sets]; 491 r_dcache_dirty_word = new int[dcache_ways * dcache_sets * dcache_words]; 492 r_dcache_zombi_ncc = new bool[dcache_ways * dcache_sets]; 449 493 450 494 … … 459 503 typename iss_t::CacheInfo cache_info; 460 504 cache_info.has_mmu = true; 461 cache_info.icache_line_size = icache_words *sizeof(uint32_t);505 cache_info.icache_line_size = icache_words * sizeof(uint32_t); 462 506 cache_info.icache_assoc = icache_ways; 463 507 cache_info.icache_n_lines = icache_sets; 464 cache_info.dcache_line_size = dcache_words *sizeof(uint32_t);508 cache_info.dcache_line_size = dcache_words * sizeof(uint32_t); 465 509 cache_info.dcache_assoc = dcache_ways; 466 510 cache_info.dcache_n_lines = dcache_sets; … … 475 519 delete [] r_dcache_dirty_word; 476 520 delete [] r_dcache_zombi_ncc; 477 /////////////////////////////////478 //print_stats();479 521 } 480 522 … … 515 557 << " | MMU = " << r_mmu_mode.read(); 516 558 517 if (r_dcache_updt_req.read() 518 if (r_dcache_wbuf_req.read() 559 if (r_dcache_updt_req.read()) std::cout << " | P1_UPDT"; 560 if (r_dcache_wbuf_req.read()) std::cout << " | P1_WBUF"; 519 561 std::cout << std::endl; 520 562 521 if (mode & 0x01)522 { 523 if ( r_icache_miss_req.read() )std::cout << " IMISS_REQ" << std::endl;524 if ( r_icache_unc_req.read() )std::cout << " IUNC_REQ" << std::endl;525 if ( r_dcache_vci_miss_req.read()) std::cout << " DMISS_REQ" << std::endl;526 if ( r_dcache_vci_unc_req.read() )std::cout << " DUNC_REQ" << std::endl;527 528 r_wbuf.printTrace((mode >>1)&1);529 } 530 if (mode & 0x02)563 if (mode & 0x01) 564 { 565 if (r_icache_miss_req.read()) std::cout << " IMISS_REQ" << std::endl; 566 if (r_icache_unc_req.read()) std::cout << " IUNC_REQ" << std::endl; 567 if (r_dcache_vci_miss_req.read()) std::cout << " DMISS_REQ" << std::endl; 568 if (r_dcache_vci_unc_req.read()) std::cout << " DUNC_REQ" << std::endl; 569 570 r_wbuf.printTrace((mode >> 1) & 1); 571 } 572 if (mode & 0x02) 531 573 { 532 574 r_iss.dump(); 533 575 } 534 if (mode & 0x04)576 if (mode & 0x04) 535 577 { 536 578 std::cout << " Data Cache" << std::endl; 537 579 r_dcache.printTrace(); 538 580 } 539 if (mode & 0x08)581 if (mode & 0x08) 540 582 { 541 583 std::cout << " Instruction Cache" << std::endl; 542 584 r_icache.printTrace(); 543 585 } 544 if (mode & 0x10)586 if (mode & 0x10) 545 587 { 546 588 std::cout << " Data TLB" << std::endl; 547 589 r_dtlb.printTrace(); 548 590 } 549 if (mode & 0x20)591 if (mode & 0x20) 550 592 { 551 593 std::cout << " Instruction TLB" << std::endl; … … 555 597 556 598 ////////////////////////////////////////// 557 tmpl(void)::cache_monitor( paddr_t addr)599 tmpl(void)::cache_monitor(paddr_t addr) 558 600 ////////////////////////////////////////// 559 601 { 560 bool 561 size_t 562 size_t 563 size_t 564 uint32_t 565 566 cache_hit = r_dcache.read_neutral( 567 568 569 570 &cache_word);571 572 if ( cache_hit != m_debug_previous_d_hit)602 bool cache_hit; 603 size_t cache_way = 0; 604 size_t cache_set = 0; 605 size_t cache_word = 0; 606 uint32_t cache_rdata = 0; 607 608 cache_hit = r_dcache.read_neutral(addr, 609 &cache_rdata, 610 &cache_way, 611 &cache_set, 612 &cache_word); 613 614 if (cache_hit != m_debug_previous_d_hit) 573 615 { 574 616 std::cout << "Monitor PROC " << name() … … 581 623 } 582 624 583 cache_hit = r_icache.read_neutral( 584 585 586 587 &cache_word);588 589 if ( cache_hit != m_debug_previous_i_hit)625 cache_hit = r_icache.read_neutral(addr, 626 &cache_rdata, 627 &cache_way, 628 &cache_set, 629 &cache_word); 630 631 if (cache_hit != m_debug_previous_i_hit) 590 632 { 591 633 std::cout << "Monitor PROC " << name() … … 609 651 << "- READ RATE = " << (float)m_cpt_data_read/run_cycles << std::endl 610 652 << "- WRITE RATE = " << (float)m_cpt_data_write/run_cycles << std::endl 611 << "- IMISS_RATE = " << (float)m_cpt_i ns_miss/m_cpt_ins_read << std::endl612 << "- DMISS RATE = " << (float)m_cpt_d ata_miss/(m_cpt_data_read-m_cpt_unc_read) << std::endl613 << "- INS MISS COST = " << (float)m_cost_ins_miss_frz/m_cpt_i ns_miss << std::endl614 << "- DATA MISS COST = " << (float)m_cost_data_miss_frz/m_cpt_d ata_miss << std::endl653 << "- IMISS_RATE = " << (float)m_cpt_icache_miss/m_cpt_ins_read << std::endl 654 << "- DMISS RATE = " << (float)m_cpt_dcache_miss/(m_cpt_data_read-m_cpt_unc_read) << std::endl 655 << "- INS MISS COST = " << (float)m_cost_ins_miss_frz/m_cpt_icache_miss << std::endl 656 << "- DATA MISS COST = " << (float)m_cost_data_miss_frz/m_cpt_dcache_miss << std::endl 615 657 << "- WRITE COST = " << (float)m_cost_write_frz/m_cpt_data_write << std::endl 616 658 << "- UNC COST = " << (float)m_cost_unc_read_frz/m_cpt_unc_read << std::endl 617 659 << "- UNCACHED READ RATE = " << (float)m_cpt_unc_read/m_cpt_data_read << std::endl 618 660 << "- CACHED WRITE RATE = " << (float)m_cpt_write_cached/m_cpt_data_write << std::endl 619 << "- INS TLB MISS RATE = " << (float)m_cpt_i ns_tlb_miss/m_cpt_ins_tlb_read << std::endl620 << "- DATA TLB MISS RATE = " << (float)m_cpt_d ata_tlb_miss/m_cpt_data_tlb_read << std::endl621 << "- ITLB MISS COST = " << (float)m_cost_ins_tlb_miss_frz/m_cpt_i ns_tlb_miss << std::endl622 << "- DTLB MISS COST = " << (float)m_cost_data_tlb_miss_frz/m_cpt_d ata_tlb_miss << std::endl623 << "- ITLB UPDATE ACC COST = " << (float)m_cost_ins_tlb_update_acc_frz/m_cpt_i ns_tlb_update_acc<< std::endl624 << "- DTLB UPDATE ACC COST = " << (float)m_cost_data_tlb_update_acc_frz/m_cpt_d ata_tlb_update_acc<< std::endl661 << "- INS TLB MISS RATE = " << (float)m_cpt_itlb_miss/m_cpt_itlb_read << std::endl 662 << "- DATA TLB MISS RATE = " << (float)m_cpt_dtlb_miss/m_cpt_dtlb_read << std::endl 663 << "- ITLB MISS COST = " << (float)m_cost_ins_tlb_miss_frz/m_cpt_itlb_miss << std::endl 664 << "- DTLB MISS COST = " << (float)m_cost_data_tlb_miss_frz/m_cpt_dtlb_miss << std::endl 665 << "- ITLB UPDATE ACC COST = " << (float)m_cost_ins_tlb_update_acc_frz/m_cpt_itlb_write << std::endl 666 << "- DTLB UPDATE ACC COST = " << (float)m_cost_data_tlb_update_acc_frz/m_cpt_dtlb_write << std::endl 625 667 << "- DTLB UPDATE DIRTY COST = " << (float)m_cost_data_tlb_update_dirty_frz/m_cpt_data_tlb_update_dirty << std::endl 626 << "- ITLB HIT IN DCACHE RATE = " << (float)m_cpt_ins_tlb_hit_dcache/m_cpt_ins_tlb_miss << std::endl 627 << "- DTLB HIT IN DCACHE RATE = " << (float)m_cpt_data_tlb_hit_dcache/m_cpt_data_tlb_miss << std::endl 628 //<< "- DCACHE FROZEN BY ITLB = " << (float)m_cost_ins_tlb_occup_cache_frz/m_cpt_dcache_frz_cycles << std::endl 668 << "- ITLB HIT IN DCACHE RATE = " << (float)m_cpt_ins_tlb_hit_dcache/m_cpt_itlb_miss << std::endl 669 << "- DTLB HIT IN DCACHE RATE = " << (float)m_cpt_data_tlb_hit_dcache/m_cpt_dtlb_miss << std::endl 629 670 << "- DCACHE FOR TLB % = " << (float)m_cpt_tlb_occup_dcache/(m_dcache_ways*m_dcache_sets) << std::endl 630 671 << "- NB CC BROADCAST = " << m_cpt_cc_broadcast << std::endl … … 666 707 //////////////////////// 667 708 { 668 m_cpt_dcache_data_read 709 m_cpt_dcache_data_read = 0; 669 710 m_cpt_dcache_data_write = 0; 670 m_cpt_dcache_dir_read 671 m_cpt_dcache_dir_write 672 m_cpt_icache_data_read 711 m_cpt_dcache_dir_read = 0; 712 m_cpt_dcache_dir_write = 0; 713 m_cpt_icache_data_read = 0; 673 714 m_cpt_icache_data_write = 0; 674 m_cpt_icache_dir_read 675 m_cpt_icache_dir_write 676 677 m_cpt_frz_cycles 678 // m_cpt_dcache_frz_cycles = 0;679 m_cpt_total_cycles = 0; 680 681 // m_cpt_read= 0;682 // m_cpt_write= 0;683 m_cpt_data_ miss= 0;684 m_cpt_ ins_miss= 0;685 m_cpt_unc_read = 0; 686 m_cpt_ write_cached= 0;687 m_cpt_i ns_read= 0;688 689 m_cost_write_frz = 0; 715 m_cpt_icache_dir_read = 0; 716 m_cpt_icache_dir_write = 0; 717 718 m_cpt_frz_cycles = 0; 719 m_cpt_total_cycles = 0; 720 721 m_cpt_data_read = 0; 722 m_cpt_data_write = 0; 723 m_cpt_data_write_back = 0; 724 m_cpt_data_cleanup = 0; 725 m_cpt_data_sc = 0; 726 727 m_cpt_dcache_miss = 0; 728 m_cpt_icache_miss = 0; 729 m_cpt_ins_read = 0; 730 690 731 m_cost_data_miss_frz = 0; 691 m_cost_unc_read_frz = 0; 692 m_cost_ins_miss_frz = 0; 693 694 m_cpt_imiss_transaction = 0; 695 m_cpt_dmiss_transaction = 0; 696 m_cpt_unc_transaction = 0; 697 m_cpt_write_transaction = 0; 698 m_cpt_icache_unc_transaction = 0; 699 700 m_cost_imiss_transaction = 0; 701 m_cost_dmiss_transaction = 0; 702 m_cost_unc_transaction = 0; 703 m_cost_write_transaction = 0; 704 m_cost_icache_unc_transaction = 0; 705 m_length_write_transaction = 0; 706 707 m_cpt_ins_tlb_read = 0; 708 m_cpt_ins_tlb_miss = 0; 709 m_cpt_ins_tlb_update_acc = 0; 710 711 m_cpt_data_tlb_read = 0; 712 m_cpt_data_tlb_miss = 0; 713 m_cpt_data_tlb_update_acc = 0; 714 m_cpt_data_tlb_update_dirty = 0; 715 m_cpt_ins_tlb_hit_dcache = 0; 716 m_cpt_data_tlb_hit_dcache = 0; 717 m_cpt_ins_tlb_occup_cache = 0; 718 m_cpt_data_tlb_occup_cache = 0; 719 720 m_cost_ins_tlb_miss_frz = 0; 721 m_cost_data_tlb_miss_frz = 0; 722 m_cost_ins_tlb_update_acc_frz = 0; 723 m_cost_data_tlb_update_acc_frz = 0; 724 m_cost_data_tlb_update_dirty_frz = 0; 725 m_cost_ins_tlb_occup_cache_frz = 0; 726 m_cost_data_tlb_occup_cache_frz = 0; 727 728 m_cpt_itlbmiss_transaction = 0; 729 m_cpt_itlb_ll_transaction = 0; 730 m_cpt_itlb_sc_transaction = 0; 731 m_cpt_dtlbmiss_transaction = 0; 732 m_cpt_dtlb_ll_transaction = 0; 733 m_cpt_dtlb_sc_transaction = 0; 734 m_cpt_dtlb_ll_dirty_transaction = 0; 735 m_cpt_dtlb_sc_dirty_transaction = 0; 736 737 m_cost_itlbmiss_transaction = 0; 738 m_cost_itlb_ll_transaction = 0; 739 m_cost_itlb_sc_transaction = 0; 740 m_cost_dtlbmiss_transaction = 0; 741 m_cost_dtlb_ll_transaction = 0; 742 m_cost_dtlb_sc_transaction = 0; 743 m_cost_dtlb_ll_dirty_transaction = 0; 744 m_cost_dtlb_sc_dirty_transaction = 0; 745 746 // m_cpt_cc_update_data = 0; 747 // m_cpt_cc_inval_ins = 0; 748 // m_cpt_cc_inval_data = 0; 749 m_cpt_cc_broadcast = 0; 750 751 m_cost_updt_data_frz = 0; 752 m_cost_inval_ins_frz = 0; 753 m_cost_inval_data_frz = 0; 754 m_cost_broadcast_frz = 0; 755 756 m_cpt_cc_cleanup_data = 0; 757 m_cpt_cc_cleanup_ins = 0; 758 759 m_cpt_cleanup_data_not_dirty = 0; 732 m_cost_ins_miss_frz = 0; 733 734 m_cpt_write_transaction = 0; 735 m_length_write_transaction = 0; 736 737 m_cpt_itlb_read = 0; 738 m_cpt_itlb_miss = 0; 739 m_cpt_itlb_write = 0; 740 m_cost_ins_tlb_miss_frz = 0; 741 742 m_cpt_dtlb_read = 0; 743 m_cpt_dtlb_miss = 0; 744 m_cpt_dtlb_write = 0; 745 746 m_cpt_cleanup_data_not_dirty = 0; 760 747 m_cpt_cleanup_data_dirty_word = 0; 761 748 m_cpt_data_write_miss = 0; 762 749 m_cpt_data_write_on_zombi = 0; 763 750 m_cpt_data_write_on_zombi_ncc = 0; 764 765 751 } 766 767 768 752 769 753 ///////////////////////// … … 771 755 ///////////////////////// 772 756 { 773 if ( not p_resetn.read())757 if (not p_resetn.read()) 774 758 { 775 759 r_iss.reset(); … … 780 764 r_dtlb.reset(); 781 765 782 r_dcache_fsm 783 r_icache_fsm 784 r_vci_cmd_fsm 785 r_vci_rsp_fsm 786 r_cc_receive_fsm 787 r_cc_send_fsm 766 r_dcache_fsm = DCACHE_IDLE; 767 r_icache_fsm = ICACHE_IDLE; 768 r_vci_cmd_fsm = CMD_IDLE; 769 r_vci_rsp_fsm = RSP_IDLE; 770 r_cc_receive_fsm = CC_RECEIVE_IDLE; 771 r_cc_send_fsm = CC_SEND_IDLE; 788 772 789 773 // reset data physical address extension … … 794 778 795 779 // reset dcache directory extension 796 for (size_t i =0 ; i< m_dcache_ways*m_dcache_sets; i++)780 for (size_t i = 0; i < m_dcache_ways * m_dcache_sets; i++) 797 781 { 798 782 r_dcache_content_state[i] = LINE_CACHE_DATA_NOT_DIRTY; 799 r_dcache_dirty_word[i] 800 r_dcache_zombi_ncc[i] 783 r_dcache_dirty_word[i] = 0; 784 r_dcache_zombi_ncc[i] = false; 801 785 } 802 786 … … 838 822 839 823 // No request from DCACHE FSM to CC_SEND FSM 840 r_dcache_cc_send_req = false; 824 r_dcache_cc_send_req = false; 825 r_dcache_cleanup_victim_req = false; 826 841 827 r_dcache_clack_req = false; 842 828 … … 867 853 m_debug_activated = false; 868 854 869 // SPECIAL REGISTERS ODCCP855 // RWT 870 856 r_dcache_cc_cleanup_updt_data = false; 871 857 r_dcache_cc_cleanup_line_ncc = false; 872 r_dcache_miss_victim_no_coherence = false;873 r_dcache_line_no_coherence = false;874 858 r_cc_send_cpt_word = 0; 875 859 r_dcache_miss_data_cpt = 0; 876 860 r_dcache_miss_data_addr = 0; 877 861 878 r_dcache_cleanup_victim_req = false;879 862 r_dcache_cleanup_victim_line_ncc = false; 880 863 r_dcache_cleanup_victim_updt_data = false; … … 894 877 m_cpt_stop_simulation = 0; 895 878 896 m_cpt_data_miss = 0; 879 m_cpt_data_read = 0; 880 881 m_cpt_dcache_miss = 0; 897 882 m_cpt_data_write = 0; 898 883 m_cpt_data_sc = 0; … … 900 885 m_cpt_data_cleanup = 0; 901 886 m_cpt_cleanup_data_not_dirty = 0; 902 m_cpt_i ns_miss= 0;887 m_cpt_icache_miss = 0; 903 888 m_cpt_unc_read = 0; 904 889 m_cpt_write_cached = 0; … … 910 895 m_cost_ins_miss_frz = 0; 911 896 897 m_cpt_dunc_transaction = 0; 898 m_cpt_ll_transaction = 0; 899 912 900 m_cpt_imiss_transaction = 0; 913 901 m_cpt_dmiss_transaction = 0; 914 902 m_cpt_unc_transaction = 0; 915 903 m_cpt_write_transaction = 0; 916 m_cpt_icache_unc_transaction = 0;917 904 918 905 m_cost_imiss_transaction = 0; … … 920 907 m_cost_unc_transaction = 0; 921 908 m_cost_write_transaction = 0; 922 m_cost_icache_unc_transaction = 0;923 909 m_length_write_transaction = 0; 924 910 925 m_cpt_ins_tlb_read = 0; 926 m_cpt_ins_tlb_miss = 0; 927 m_cpt_ins_tlb_update_acc = 0; 928 929 m_cpt_data_tlb_read = 0; 930 m_cpt_data_tlb_miss = 0; 931 m_cpt_data_tlb_update_acc = 0; 911 m_cpt_itlb_read = 0; 912 m_cpt_itlb_miss = 0; 913 m_cpt_itlb_write = 0; 914 915 m_cpt_dtlb_read = 0; 916 m_cpt_dtlb_miss = 0; 917 m_cpt_dtlb_write = 0; 918 919 m_cpt_tlb_occup_dcache = 0; 932 920 m_cpt_data_tlb_update_dirty = 0; 933 921 m_cpt_ins_tlb_hit_dcache = 0; 934 922 m_cpt_data_tlb_hit_dcache = 0; 935 m_cpt_ins_tlb_occup_cache = 0;936 m_cpt_data_tlb_occup_cache = 0;937 923 938 924 m_cost_ins_tlb_miss_frz = 0; … … 941 927 m_cost_data_tlb_update_acc_frz = 0; 942 928 m_cost_data_tlb_update_dirty_frz = 0; 943 m_cost_ins_tlb_occup_cache_frz = 0; 944 m_cost_data_tlb_occup_cache_frz = 0; 945 946 m_cpt_ins_tlb_inval = 0; 947 m_cpt_data_tlb_inval = 0; 948 m_cost_ins_tlb_inval_frz = 0; 949 m_cost_data_tlb_inval_frz = 0; 929 930 m_cpt_cc_update_dcache = 0; 931 m_cpt_cc_inval_icache = 0; 932 m_cpt_cc_inval_dcache = 0; 950 933 951 934 m_cpt_cc_broadcast = 0; … … 966 949 967 950 m_cpt_itlbmiss_transaction = 0; 968 m_cpt_itlb_ll_transaction = 0;969 m_cpt_itlb_sc_transaction = 0;970 951 m_cpt_dtlbmiss_transaction = 0; 971 m_cpt_dtlb_ll_transaction = 0;972 m_cpt_dtlb_sc_transaction = 0;973 m_cpt_dtlb_ll_dirty_transaction = 0;974 m_cpt_dtlb_sc_dirty_transaction = 0;975 952 976 953 m_cost_itlbmiss_transaction = 0; 977 m_cost_itlb_ll_transaction = 0;978 m_cost_itlb_sc_transaction = 0;979 954 m_cost_dtlbmiss_transaction = 0; 980 m_cost_dtlb_ll_transaction = 0; 981 m_cost_dtlb_sc_transaction = 0; 982 m_cost_dtlb_ll_dirty_transaction = 0; 983 m_cost_dtlb_sc_dirty_transaction = 0; 984 /* 985 m_cpt_dcache_frz_cycles = 0; 986 m_cpt_read = 0; 987 m_cpt_write = 0; 988 m_cpt_cc_update_data = 0; 989 m_cpt_cc_inval_ins = 0; 990 m_cpt_cc_inval_data = 0; 991 */ 992 993 for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_icache [i] = 0; 994 for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_dcache [i] = 0; 995 for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_cmd [i] = 0; 996 for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_rsp [i] = 0; 955 956 for (uint32_t i = 0; i < 32; ++i) m_cpt_fsm_icache[i] = 0; 957 for (uint32_t i = 0; i < 32; ++i) m_cpt_fsm_dcache[i] = 0; 958 for (uint32_t i = 0; i < 32; ++i) m_cpt_fsm_cmd[i] = 0; 959 for (uint32_t i = 0; i < 32; ++i) m_cpt_fsm_rsp[i] = 0; 997 960 998 961 // init the llsc reservation buffer … … 1004 967 1005 968 // Response FIFOs default values 1006 bool vci_rsp_fifo_icache_get = false; 1007 bool vci_rsp_fifo_icache_put = false; 1008 uint32_t vci_rsp_fifo_icache_data = 0; 1009 1010 bool vci_rsp_fifo_dcache_get = false; 1011 bool vci_rsp_fifo_dcache_put = false; 1012 uint32_t vci_rsp_fifo_dcache_data = 0; 1013 bool vci_rsp_fifo_rpktid_get = false; 1014 bool vci_rsp_fifo_rpktid_put = false; 1015 bool vci_rsp_fifo_rpktid = false; 969 bool vci_rsp_fifo_icache_get = false; 970 bool vci_rsp_fifo_icache_put = false; 971 uint32_t vci_rsp_fifo_icache_data = 0; 972 973 bool vci_rsp_fifo_dcache_get = false; 974 bool vci_rsp_fifo_dcache_put = false; 975 uint32_t vci_rsp_fifo_dcache_data = 0; 976 977 bool vci_rsp_fifo_rpktid_get = false; 978 bool vci_rsp_fifo_rpktid_put = false; 979 bool vci_rsp_fifo_rpktid = false; 1016 980 1017 981 // FIFO for cleanup data updt 1018 bool cleanup_data_updt_fifo_dcache_get= false;1019 bool cleanup_data_updt_fifo_dcache_put= false;1020 uint32_t cleanup_data_updt_fifo_dcache_data= 0;982 bool cleanup_data_updt_fifo_dcache_get = false; 983 bool cleanup_data_updt_fifo_dcache_put = false; 984 uint32_t cleanup_data_updt_fifo_dcache_data = 0; 1021 985 1022 986 // updt fifo 1023 bool 1024 bool 1025 uint32_t 1026 uint32_t 1027 bool 987 bool cc_receive_updt_fifo_get = false; 988 bool cc_receive_updt_fifo_put = false; 989 uint32_t cc_receive_updt_fifo_be = 0; 990 uint32_t cc_receive_updt_fifo_data = 0; 991 bool cc_receive_updt_fifo_eop = false; 1028 992 1029 993 #ifdef INSTRUMENTATION … … 1099 1063 1100 1064 // default value for m_irsp 1101 m_irsp.valid 1102 m_irsp.error 1065 m_irsp.valid = false; 1066 m_irsp.error = false; 1103 1067 m_irsp.instruction = 0; 1104 1068 1105 switch ( r_icache_fsm.read())1069 switch (r_icache_fsm.read()) 1106 1070 { 1107 1071 ///////////////// … … 1115 1079 { 1116 1080 // coherence clack interrupt 1117 if ( r_icache_clack_req.read())1081 if (r_icache_clack_req.read()) 1118 1082 { 1119 1083 r_icache_fsm = ICACHE_CC_CHECK; … … 1123 1087 1124 1088 // coherence interrupt 1125 if ( 1089 if (r_cc_receive_icache_req.read() and not r_icache_cc_send_req.read()) 1126 1090 { 1127 1091 r_icache_fsm = ICACHE_CC_CHECK; … … 1133 1097 // These request are not executed in this IDLE state (except XTN_INST_PADDR_EXT), 1134 1098 // because they require access to icache or itlb, that are already accessed 1135 if ( r_dcache_xtn_req.read())1136 { 1137 if ( (int)r_dcache_xtn_opcode.read() == (int)iss_t::XTN_PTPR)1138 { 1139 r_icache_fsm 1140 } 1141 else if ( (int)r_dcache_xtn_opcode.read() == (int)iss_t::XTN_ICACHE_FLUSH)1099 if (r_dcache_xtn_req.read()) 1100 { 1101 if ((int) r_dcache_xtn_opcode.read() == (int) iss_t::XTN_PTPR) 1102 { 1103 r_icache_fsm = ICACHE_XTN_TLB_FLUSH; 1104 } 1105 else if ((int) r_dcache_xtn_opcode.read() == (int) iss_t::XTN_ICACHE_FLUSH) 1142 1106 { 1143 1107 r_icache_flush_count = 0; 1144 r_icache_fsm 1145 } 1146 else if ( (int)r_dcache_xtn_opcode.read() == (int)iss_t::XTN_ITLB_INVAL)1147 { 1148 r_icache_fsm 1149 } 1150 else if ( (int)r_dcache_xtn_opcode.read() == (int)iss_t::XTN_ICACHE_INVAL)1151 { 1152 r_icache_fsm 1153 } 1154 else if ( (int)r_dcache_xtn_opcode.read() == (int)iss_t::XTN_MMU_ICACHE_PA_INV)1108 r_icache_fsm = ICACHE_XTN_CACHE_FLUSH; 1109 } 1110 else if ((int) r_dcache_xtn_opcode.read() == (int) iss_t::XTN_ITLB_INVAL) 1111 { 1112 r_icache_fsm = ICACHE_XTN_TLB_INVAL; 1113 } 1114 else if ((int) r_dcache_xtn_opcode.read() == (int) iss_t::XTN_ICACHE_INVAL) 1115 { 1116 r_icache_fsm = ICACHE_XTN_CACHE_INVAL_VA; 1117 } 1118 else if ((int) r_dcache_xtn_opcode.read() == (int) iss_t::XTN_MMU_ICACHE_PA_INV) 1155 1119 { 1156 1120 if (sizeof(paddr_t) <= 32) … … 1158 1122 assert(r_mmu_word_hi.read() == 0 && 1159 1123 "illegal XTN request in ICACHE: high bits should be 0 for 32bit paddr"); 1160 r_icache_vci_paddr = (paddr_t) r_mmu_word_lo.read();1124 r_icache_vci_paddr = (paddr_t) r_mmu_word_lo.read(); 1161 1125 } 1162 1126 else 1163 1127 { 1164 r_icache_vci_paddr = (paddr_t) r_mmu_word_hi.read() << 32 |1165 (paddr_t) r_mmu_word_lo.read();1128 r_icache_vci_paddr = (paddr_t) r_mmu_word_hi.read() << 32 | 1129 (paddr_t) r_mmu_word_lo.read(); 1166 1130 } 1167 1131 r_icache_fsm = ICACHE_XTN_CACHE_INVAL_PA; 1168 1132 } 1169 else if ( (int)r_dcache_xtn_opcode.read() == (int)iss_t::XTN_INST_PADDR_EXT)1133 else if ((int) r_dcache_xtn_opcode.read() == (int) iss_t::XTN_INST_PADDR_EXT) 1170 1134 { 1171 1135 r_icache_paddr_ext = r_dcache_save_wdata.read(); … … 1174 1138 else 1175 1139 { 1176 assert( 1140 assert(false and 1177 1141 "undefined XTN request received by ICACHE FSM"); 1178 1142 } … … 1181 1145 1182 1146 // processor request 1183 if ( m_ireq.valid)1184 { 1185 bool 1186 paddr_t 1187 bool 1188 pte_info_t 1189 size_t 1190 size_t 1191 paddr_t 1192 uint32_t 1193 size_t 1194 size_t 1195 size_t 1196 int 1147 if (m_ireq.valid) 1148 { 1149 bool cacheable; 1150 paddr_t paddr; 1151 bool tlb_hit = false; 1152 pte_info_t tlb_flags; 1153 size_t tlb_way; 1154 size_t tlb_set; 1155 paddr_t tlb_nline; 1156 uint32_t cache_inst = 0; 1157 size_t cache_way; 1158 size_t cache_set; 1159 size_t cache_word; 1160 int cache_state = CACHE_SLOT_STATE_EMPTY; 1197 1161 1198 1162 // We register processor request … … 1201 1165 1202 1166 // sytematic itlb access (if activated) 1203 if ( r_mmu_mode.read() & INS_TLB_MASK)1167 if (r_mmu_mode.read() & INS_TLB_MASK) 1204 1168 { 1205 1169 1206 1170 #ifdef INSTRUMENTATION 1207 m_cpt_ins_tlb_read++;1208 #endif 1209 tlb_hit = r_itlb.translate( 1210 1211 1212 1213 1214 &tlb_set );// unused1171 m_cpt_itlb_read++; 1172 #endif 1173 tlb_hit = r_itlb.translate(m_ireq.addr, 1174 &paddr, 1175 &tlb_flags, 1176 &tlb_nline, // unused 1177 &tlb_way, // unused 1178 &tlb_set); // unused 1215 1179 } 1216 1180 else if (vci_param::N > 32) … … 1220 1184 1221 1185 // systematic icache access (if activated) 1222 if ( r_mmu_mode.read() & INS_CACHE_MASK)1186 if (r_mmu_mode.read() & INS_CACHE_MASK) 1223 1187 { 1224 1188 1225 1189 1226 1190 #ifdef INSTRUMENTATION 1227 m_cpt_icache_data_read++;1228 m_cpt_icache_dir_read++;1229 #endif 1230 r_icache.read( 1231 1232 1233 1234 1235 &cache_state);1191 m_cpt_icache_data_read++; 1192 m_cpt_icache_dir_read++; 1193 #endif 1194 r_icache.read(paddr, 1195 &cache_inst, 1196 &cache_way, 1197 &cache_set, 1198 &cache_word, 1199 &cache_state); 1236 1200 } 1237 1201 … … 1242 1206 // and there is no access rights checking 1243 1207 1244 if ( not (r_mmu_mode.read() & INS_TLB_MASK) )// tlb not activated:1208 if (not (r_mmu_mode.read() & INS_TLB_MASK)) // tlb not activated: 1245 1209 { 1246 1210 // cacheability 1247 if ( not (r_mmu_mode.read() & INS_CACHE_MASK)) cacheable = false;1248 else cacheable = m_cacheability_table[(uint64_t)m_ireq.addr];1249 } 1250 else 1251 { 1252 if ( tlb_hit )// ITLB hit1211 if (not (r_mmu_mode.read() & INS_CACHE_MASK)) cacheable = false; 1212 else cacheable = m_cacheability_table[(uint64_t) m_ireq.addr]; 1213 } 1214 else // itlb activated 1215 { 1216 if (tlb_hit) // ITLB hit 1253 1217 { 1254 1218 // cacheability 1255 if ( not (r_mmu_mode.read() & INS_CACHE_MASK)) cacheable = false;1256 else 1219 if (not (r_mmu_mode.read() & INS_CACHE_MASK)) cacheable = false; 1220 else cacheable = tlb_flags.c; 1257 1221 1258 1222 // access rights checking 1259 if ( not tlb_flags.u && (m_ireq.mode == iss_t::MODE_USER))1223 if (not tlb_flags.u && (m_ireq.mode == iss_t::MODE_USER)) 1260 1224 { 1261 r_mmu_ietr = MMU_READ_PRIVILEGE_VIOLATION; 1262 r_mmu_ibvar = m_ireq.addr; 1263 m_irsp.valid = true; 1264 m_irsp.error = true; 1265 m_irsp.instruction = 0; 1225 1226 #if DEBUG_ICACHE 1227 if (m_debug_activated) 1228 std::cout << " <PROC " << name() << " ICACHE_IDLE> MMU Privilege Violation" 1229 << " : PADDR = " << std::hex << paddr << std::endl; 1230 #endif 1231 r_mmu_ietr = MMU_READ_PRIVILEGE_VIOLATION; 1232 r_mmu_ibvar = m_ireq.addr; 1233 m_irsp.valid = true; 1234 m_irsp.error = true; 1235 m_irsp.instruction = 0; 1266 1236 break; 1267 1237 } 1268 else if ( not tlb_flags.x)1238 else if (not tlb_flags.x) 1269 1239 { 1270 r_mmu_ietr = MMU_READ_EXEC_VIOLATION; 1271 r_mmu_ibvar = m_ireq.addr; 1272 m_irsp.valid = true; 1273 m_irsp.error = true; 1274 m_irsp.instruction = 0; 1240 1241 #if DEBUG_ICACHE 1242 if (m_debug_activated) 1243 { 1244 std::cout << " <PROC " << name() << " ICACHE_IDLE> MMU Executable Violation" 1245 << " : PADDR = " << std::hex << paddr << std::endl; 1246 } 1247 #endif 1248 r_mmu_ietr = MMU_READ_EXEC_VIOLATION; 1249 r_mmu_ibvar = m_ireq.addr; 1250 m_irsp.valid = true; 1251 m_irsp.error = true; 1252 m_irsp.instruction = 0; 1275 1253 break; 1276 1254 } 1277 1255 } 1278 else 1256 else // ITLB miss 1279 1257 { 1280 1258 1281 1259 #ifdef INSTRUMENTATION 1282 m_cpt_ins_tlb_miss++;1260 m_cpt_itlb_miss++; 1283 1261 #endif 1284 1262 r_icache_fsm = ICACHE_TLB_WAIT; … … 1289 1267 1290 1268 // physical address registration 1291 r_icache_vci_paddr 1269 r_icache_vci_paddr = paddr; 1292 1270 1293 1271 // Finally, we send the response to processor, and compute next state 1294 if ( cacheable ) 1295 { 1296 1297 if (cache_state == CACHE_SLOT_STATE_EMPTY) // cache miss 1272 if (cacheable) 1273 { 1274 if (cache_state == CACHE_SLOT_STATE_EMPTY) // cache miss 1298 1275 { 1299 1276 1300 1277 #ifdef INSTRUMENTATION 1301 m_cpt_ins_miss++;1278 m_cpt_icache_miss++; 1302 1279 #endif 1303 1280 // we request a VCI transaction 1304 r_icache_fsm 1281 r_icache_fsm = ICACHE_MISS_SELECT; 1305 1282 #if DEBUG_ICACHE 1306 if ( m_debug_activated ) 1307 std::cout << " <PROC " << name() << " ICACHE_IDLE> READ MISS in icache" 1308 << " : PADDR = " << std::hex << paddr << std::endl; 1283 if (m_debug_activated) 1284 { 1285 std::cout << " <PROC " << name() << " ICACHE_IDLE> READ MISS in icache" 1286 << " : PADDR = " << std::hex << paddr << std::endl; 1287 } 1309 1288 #endif 1310 1289 r_icache_miss_req = true; 1311 1290 } 1312 else if (cache_state == CACHE_SLOT_STATE_ZOMBI ) 1291 else if (cache_state == CACHE_SLOT_STATE_ZOMBI ) // pending cleanup 1313 1292 { 1314 1293 // stalled until cleanup is acknowledged 1315 r_icache_fsm 1316 } 1317 else 1294 r_icache_fsm = ICACHE_IDLE; 1295 } 1296 else // cache hit 1318 1297 { 1319 1298 1320 1299 #ifdef INSTRUMENTATION 1321 m_cpt_ins_read++;1300 m_cpt_ins_read++; 1322 1301 #endif 1323 1302 // return instruction to processor … … 1326 1305 r_icache_fsm = ICACHE_IDLE; 1327 1306 #if DEBUG_ICACHE 1328 if ( m_debug_activated ) 1329 std::cout << " <PROC " << name() << " ICACHE_IDLE> READ HIT in icache" 1330 << " : PADDR = " << std::hex << paddr 1331 << " / INST = " << cache_inst << std::dec << std::endl; 1332 #endif 1333 } 1334 } 1335 else // non cacheable read 1336 { 1337 r_icache_unc_req = true; 1338 r_icache_fsm = ICACHE_UNC_WAIT; 1307 if (m_debug_activated) 1308 { 1309 std::cout << " <PROC " << name() << " ICACHE_IDLE> READ HIT in icache" 1310 << " : PADDR = " << std::hex << paddr 1311 << " / INST = " << cache_inst << std::dec << std::endl; 1312 } 1313 #endif 1314 } 1315 } 1316 else // non cacheable read 1317 { 1318 r_icache_unc_req = true; 1319 r_icache_fsm = ICACHE_UNC_WAIT; 1339 1320 1340 1321 #if DEBUG_ICACHE 1341 if ( m_debug_activated)1342 {1343 std::cout << " <PROC " << name()1344 << " ICACHE_IDLE> READ UNCACHEABLE in icache"1345 << " : PADDR = " << std::hex << paddr << std::endl;1346 }1322 if (m_debug_activated) 1323 { 1324 std::cout << " <PROC " << name() 1325 << " ICACHE_IDLE> READ UNCACHEABLE in icache" 1326 << " : PADDR = " << std::hex << paddr << std::endl; 1327 } 1347 1328 #endif 1348 1329 } … … 1359 1340 { 1360 1341 // coherence clack interrupt 1361 if ( r_icache_clack_req.read())1342 if (r_icache_clack_req.read()) 1362 1343 { 1363 1344 r_icache_fsm = ICACHE_CC_CHECK; … … 1367 1348 1368 1349 // coherence interrupt 1369 if ( 1350 if (r_cc_receive_icache_req.read() and not r_icache_cc_send_req.read()) 1370 1351 { 1371 1352 r_icache_fsm = ICACHE_CC_CHECK; … … 1374 1355 } 1375 1356 1376 if ( m_ireq.valid) m_cost_ins_tlb_miss_frz++;1357 if (m_ireq.valid) m_cost_ins_tlb_miss_frz++; 1377 1358 1378 1359 // DCACHE FSM signals response by reseting the request flip-flop 1379 if ( not r_icache_tlb_miss_req.read())1380 { 1381 if ( r_icache_tlb_rsp_error.read()) // error reported : tlb not updated1360 if (not r_icache_tlb_miss_req.read()) 1361 { 1362 if (r_icache_tlb_rsp_error.read()) // error reported : tlb not updated 1382 1363 { 1383 1364 r_icache_tlb_rsp_error = false; 1384 m_irsp.error 1385 m_irsp.valid 1386 r_icache_fsm 1387 } 1388 else 1365 m_irsp.error = true; 1366 m_irsp.valid = true; 1367 r_icache_fsm = ICACHE_IDLE; 1368 } 1369 else // tlb updated : return to IDLE state 1389 1370 { 1390 1371 r_icache_fsm = ICACHE_IDLE; … … 1394 1375 } 1395 1376 ////////////////////////// 1396 case ICACHE_XTN_TLB_FLUSH: 1377 case ICACHE_XTN_TLB_FLUSH: // invalidate in one cycle all non global TLB entries 1397 1378 { 1398 1379 r_itlb.flush(); 1399 r_dcache_xtn_req 1400 r_icache_fsm 1380 r_dcache_xtn_req = false; 1381 r_icache_fsm = ICACHE_IDLE; 1401 1382 break; 1402 1383 } … … 1411 1392 { 1412 1393 // coherence clack interrupt 1413 if ( r_icache_clack_req.read())1394 if (r_icache_clack_req.read()) 1414 1395 { 1415 1396 r_icache_fsm = ICACHE_CC_CHECK; … … 1419 1400 1420 1401 // coherence request (from CC_RECEIVE FSM) 1421 if ( 1402 if (r_cc_receive_icache_req.read() and not r_icache_cc_send_req.read()) 1422 1403 { 1423 1404 r_icache_fsm = ICACHE_CC_CHECK; … … 1426 1407 } 1427 1408 1428 if ( not r_icache_cc_send_req.read()) // blocked until previous cc_send request is sent1429 { 1430 int 1431 paddr_t 1432 size_t way = r_icache_flush_count.read()/m_icache_sets;1433 size_t set = r_icache_flush_count.read()%m_icache_sets;1409 if (not r_icache_cc_send_req.read()) // blocked until previous cc_send request is sent 1410 { 1411 int state; 1412 paddr_t tag; 1413 size_t way = r_icache_flush_count.read() / m_icache_sets; 1414 size_t set = r_icache_flush_count.read() % m_icache_sets; 1434 1415 1435 1416 #ifdef INSTRUMENTATION 1436 m_cpt_icache_dir_read++;1437 #endif 1438 r_icache.read_dir( 1439 1440 1441 &state);1442 1443 if ( state == CACHE_SLOT_STATE_VALID_CC) // inval required1417 m_cpt_icache_dir_read++; 1418 #endif 1419 r_icache.read_dir(way, 1420 set, 1421 &tag, 1422 &state); 1423 1424 if (state == CACHE_SLOT_STATE_VALID_CC) // inval required 1444 1425 { 1445 1426 // request cleanup … … 1450 1431 1451 1432 // goes to ICACHE_XTN_CACHE_FLUSH_GO to make inval 1452 r_icache_miss_way 1453 r_icache_miss_set 1454 r_icache_fsm 1455 } 1456 else if ( 1457 (m_icache_sets*m_icache_ways - 1) 1433 r_icache_miss_way = way; 1434 r_icache_miss_set = set; 1435 r_icache_fsm = ICACHE_XTN_CACHE_FLUSH_GO; 1436 } 1437 else if (r_icache_flush_count.read() == 1438 (m_icache_sets*m_icache_ways - 1)) // last slot 1458 1439 { 1459 1440 r_dcache_xtn_req = false; 1460 m_drsp.valid 1461 r_icache_fsm 1441 m_drsp.valid = true; 1442 r_icache_fsm = ICACHE_IDLE; 1462 1443 } 1463 1444 1464 1445 // saturation counter, to have the same last slot condition 1465 1446 // in ICACHE_XTN_CACHE_FLUSH and ICACHE_XTN_CACHE_FLUSH_GO states 1466 if ( r_icache_flush_count.read() < (m_icache_sets*m_icache_ways - 1))1447 if (r_icache_flush_count.read() < (m_icache_sets * m_icache_ways - 1)) 1467 1448 { 1468 1449 r_icache_flush_count = r_icache_flush_count.read() + 1; … … 1472 1453 } 1473 1454 /////////////////////////////// 1474 case ICACHE_XTN_CACHE_FLUSH_GO: 1475 { 1476 size_t 1477 size_t 1455 case ICACHE_XTN_CACHE_FLUSH_GO: // Switch slot state to ZOMBI for an XTN flush 1456 { 1457 size_t way = r_icache_miss_way.read(); 1458 size_t set = r_icache_miss_set.read(); 1478 1459 1479 1460 #ifdef INSTRUMENTATION 1480 m_cpt_icache_dir_write++;1481 #endif 1482 1483 r_icache.write_dir( 1484 1485 CACHE_SLOT_STATE_ZOMBI);1486 1487 if ( 1488 (m_icache_sets*m_icache_ways - 1) 1461 m_cpt_icache_dir_write++; 1462 #endif 1463 1464 r_icache.write_dir(way, 1465 set, 1466 CACHE_SLOT_STATE_ZOMBI); 1467 1468 if (r_icache_flush_count.read() == 1469 (m_icache_sets*m_icache_ways - 1)) // last slot 1489 1470 { 1490 1471 r_dcache_xtn_req = false; 1491 m_drsp.valid 1492 r_icache_fsm 1472 m_drsp.valid = true; 1473 r_icache_fsm = ICACHE_IDLE; 1493 1474 } 1494 1475 else 1495 1476 { 1496 r_icache_fsm 1477 r_icache_fsm = ICACHE_XTN_CACHE_FLUSH; 1497 1478 } 1498 1479 break; … … 1500 1481 1501 1482 ////////////////////////// 1502 case ICACHE_XTN_TLB_INVAL: 1503 1483 case ICACHE_XTN_TLB_INVAL: // invalidate one TLB entry selected by the virtual address 1484 // stored in the r_dcache_save_wdata register 1504 1485 { 1505 1486 r_itlb.inval(r_dcache_save_wdata.read()); 1506 r_dcache_xtn_req 1507 r_icache_fsm 1487 r_dcache_xtn_req = false; 1488 r_icache_fsm = ICACHE_IDLE; 1508 1489 break; 1509 1490 } … … 1518 1499 1519 1500 // read physical address in TLB when MMU activated 1520 if ( r_mmu_mode.read() & INS_TLB_MASK )// itlb activated1501 if (r_mmu_mode.read() & INS_TLB_MASK) // itlb activated 1521 1502 { 1522 1503 1523 1504 #ifdef INSTRUMENTATION 1524 m_cpt_ins_tlb_read++; 1525 #endif 1526 hit = r_itlb.translate(r_dcache_save_wdata.read(), 1527 &paddr); 1528 } 1529 else // itlb not activated 1530 { 1531 paddr = (paddr_t)r_dcache_save_wdata.read(); 1532 hit = true; 1533 } 1534 1535 if ( hit ) // continue the selective inval process 1536 { 1537 r_icache_vci_paddr = paddr; 1538 r_icache_fsm = ICACHE_XTN_CACHE_INVAL_PA; 1539 } 1540 else // miss : send a request to DCACHE FSM 1505 m_cpt_itlb_read++; 1506 #endif 1507 hit = r_itlb.translate(r_dcache_save_wdata.read(), &paddr); 1508 } 1509 else // itlb not activated 1510 { 1511 paddr = (paddr_t) r_dcache_save_wdata.read(); 1512 hit = true; 1513 } 1514 1515 if (hit) // continue the selective inval process 1516 { 1517 r_icache_vci_paddr = paddr; 1518 r_icache_fsm = ICACHE_XTN_CACHE_INVAL_PA; 1519 } 1520 else // miss : send a request to DCACHE FSM 1541 1521 { 1542 1522 1543 1523 #ifdef INSTRUMENTATION 1544 m_cpt_ins_tlb_miss++;1524 m_cpt_itlb_miss++; 1545 1525 #endif 1546 1526 r_icache_tlb_miss_req = true; … … 1555 1535 // with address stored in r_icache_vci_paddr register. 1556 1536 { 1557 int 1558 size_t 1559 size_t 1560 size_t 1537 int state; 1538 size_t way; 1539 size_t set; 1540 size_t word; 1561 1541 1562 1542 #ifdef INSTRUMENTATION 1563 m_cpt_icache_dir_read++;1543 m_cpt_icache_dir_read++; 1564 1544 #endif 1565 1545 r_icache.read_dir(r_icache_vci_paddr.read(), … … 1569 1549 &word); 1570 1550 1571 if ( state == CACHE_SLOT_STATE_VALID_CC )// inval to be done1551 if (state == CACHE_SLOT_STATE_VALID_CC) // inval to be done 1572 1552 { 1573 1553 r_icache_miss_way = way; … … 1575 1555 r_icache_fsm = ICACHE_XTN_CACHE_INVAL_GO; 1576 1556 } 1577 else 1557 else // miss : acknowlege the XTN request and return 1578 1558 { 1579 1559 r_dcache_xtn_req = false; … … 1585 1565 case ICACHE_XTN_CACHE_INVAL_GO: // Switch slot to ZOMBI state for an XTN inval 1586 1566 { 1587 if ( not r_icache_cc_send_req.read()) // blocked until previous cc_send request not sent1567 if (not r_icache_cc_send_req.read()) // blocked until previous cc_send request not sent 1588 1568 { 1589 1569 1590 1570 #ifdef INSTRUMENTATION 1591 m_cpt_icache_dir_write++;1592 #endif 1593 r_icache.write_dir( 1594 1595 CACHE_SLOT_STATE_ZOMBI);1571 m_cpt_icache_dir_write++; 1572 #endif 1573 r_icache.write_dir(r_icache_miss_way.read(), 1574 r_icache_miss_set.read(), 1575 CACHE_SLOT_STATE_ZOMBI); 1596 1576 1597 1577 // request cleanup 1598 1578 r_icache_cc_send_req = true; 1599 r_icache_cc_send_nline = r_icache_vci_paddr.read() / (m_icache_words <<2);1579 r_icache_cc_send_nline = r_icache_vci_paddr.read() / (m_icache_words << 2); 1600 1580 r_icache_cc_send_way = r_icache_miss_way.read(); 1601 1581 r_icache_cc_send_type = CC_TYPE_CLEANUP; 1602 1582 1603 1583 // acknowledge the XTN request and return 1604 r_dcache_xtn_req 1605 r_icache_fsm 1584 r_dcache_xtn_req = false; 1585 r_icache_fsm = ICACHE_IDLE; 1606 1586 } 1607 1587 break; … … 1609 1589 //////////////////////// 1610 1590 case ICACHE_MISS_SELECT: // Try to select a slot in associative set, 1611 // if previous cleanup has been sent.1612 1591 // Waiting in this state if no slot available. 1613 // Set the r_icache_cleanup_req flip-flop 1614 // and the r_icache_miss_clack flip-flop, 1592 // If a victim slot has been choosen and the r_icache_cc_send_req is false, 1593 // we send the cleanup request in this state. 1594 // If not, a r_icache_cleanup_victim_req flip-flop is 1595 // utilized for saving this cleanup request, and it will be sent later 1596 // in state ICACHE_MISS_WAIT or ICACHE_MISS_UPDT_DIR. 1597 // The r_icache_miss_clack flip-flop is set 1615 1598 // when a cleanup is required 1616 1599 { … … 1618 1601 1619 1602 // coherence clack interrupt 1620 if ( r_icache_clack_req.read())1603 if (r_icache_clack_req.read()) 1621 1604 { 1622 1605 r_icache_fsm = ICACHE_CC_CHECK; … … 1626 1609 1627 1610 // coherence interrupt 1628 if ( 1611 if (r_cc_receive_icache_req.read() and not r_icache_cc_send_req.read()) 1629 1612 { 1630 1613 r_icache_fsm = ICACHE_CC_CHECK; … … 1634 1617 1635 1618 1636 bool 1637 bool 1638 size_t 1639 size_t 1640 paddr_t 1619 bool found; 1620 bool cleanup; 1621 size_t way; 1622 size_t set; 1623 paddr_t victim; 1641 1624 1642 1625 #ifdef INSTRUMENTATION 1643 m_cpt_icache_dir_read++;1626 m_cpt_icache_dir_read++; 1644 1627 #endif 1645 1628 r_icache.read_select(r_icache_vci_paddr.read(), … … 1648 1631 &set, 1649 1632 &found, 1650 &cleanup 1651 if ( found)1652 { 1653 r_icache_miss_way 1654 r_icache_miss_set 1655 1656 if ( cleanup)1657 { 1658 if ( not r_icache_cc_send_req.read())1659 { 1660 r_icache_cc_send_req 1661 r_icache_cc_send_nline 1662 r_icache_cc_send_way 1663 r_icache_cc_send_type 1633 &cleanup); 1634 if (found) 1635 { 1636 r_icache_miss_way = way; 1637 r_icache_miss_set = set; 1638 1639 if (cleanup) 1640 { 1641 if (not r_icache_cc_send_req.read()) 1642 { 1643 r_icache_cc_send_req = true; 1644 r_icache_cc_send_nline = victim; 1645 r_icache_cc_send_way = way; 1646 r_icache_cc_send_type = CC_TYPE_CLEANUP; 1664 1647 } 1665 1648 else … … 1669 1652 } 1670 1653 1671 r_icache_miss_clack 1672 r_icache_fsm 1654 r_icache_miss_clack = true; 1655 r_icache_fsm = ICACHE_MISS_CLEAN; 1673 1656 } 1674 1657 else 1675 1658 { 1676 r_icache_fsm 1659 r_icache_fsm = ICACHE_MISS_WAIT; 1677 1660 } 1678 1661 1679 1662 #if DEBUG_ICACHE 1680 if ( m_debug_activated)1681 {1682 std::cout << " <PROC " << name()1683 << " ICACHE_MISS_SELECT> Select a slot:" << std::dec1684 << " / WAY = " << way1685 << " / SET = " << set;1686 if (cleanup) std::cout << " / VICTIM = " << std::hex << victim << std::endl;1687 else std::cout << std::endl;1688 }1663 if (m_debug_activated) 1664 { 1665 std::cout << " <PROC " << name() 1666 << " ICACHE_MISS_SELECT> Select a slot:" << std::dec 1667 << " / WAY = " << way 1668 << " / SET = " << set; 1669 if (cleanup) std::cout << " / VICTIM = " << std::hex << victim << std::endl; 1670 else std::cout << std::endl; 1671 } 1689 1672 #endif 1690 1673 } … … 1692 1675 } 1693 1676 /////////////////////// 1694 case ICACHE_MISS_CLEAN: 1677 case ICACHE_MISS_CLEAN: // switch the slot to zombi state 1695 1678 { 1696 1679 if (m_ireq.valid) m_cost_ins_miss_frz++; 1697 1680 1698 1681 #ifdef INSTRUMENTATION 1699 m_cpt_icache_dir_write++;1700 #endif 1701 r_icache.write_dir( 1702 1703 1682 m_cpt_icache_dir_write++; 1683 #endif 1684 r_icache.write_dir(r_icache_miss_way.read(), 1685 r_icache_miss_set.read(), 1686 CACHE_SLOT_STATE_ZOMBI); 1704 1687 #if DEBUG_ICACHE 1705 if ( m_debug_activated)1706 {1707 std::cout << " <PROC " << name()1708 << " ICACHE_MISS_CLEAN> Switch to ZOMBI state" << std::dec1709 << " / WAY = " << r_icache_miss_way.read()1710 << " / SET = " << r_icache_miss_set.read() << std::endl;1711 }1688 if (m_debug_activated) 1689 { 1690 std::cout << " <PROC " << name() 1691 << " ICACHE_MISS_CLEAN> Switch to ZOMBI state" << std::dec 1692 << " / WAY = " << r_icache_miss_way.read() 1693 << " / SET = " << r_icache_miss_set.read() << std::endl; 1694 } 1712 1695 #endif 1713 1696 … … 1716 1699 } 1717 1700 ////////////////////// 1718 case ICACHE_MISS_WAIT: 1701 case ICACHE_MISS_WAIT: // waiting response from VCI_RSP FSM 1719 1702 { 1720 1703 if (m_ireq.valid) m_cost_ins_miss_frz++; 1721 1704 1722 if ( r_icache_cleanup_victim_req.read() and not r_icache_cc_send_req.read() ) 1705 // send cleanup victim request 1706 if (r_icache_cleanup_victim_req.read() and not r_icache_cc_send_req.read()) 1723 1707 { 1724 1708 r_icache_cc_send_req = true; … … 1730 1714 1731 1715 // coherence clack interrupt 1732 if ( r_icache_clack_req.read())1716 if (r_icache_clack_req.read()) 1733 1717 { 1734 1718 r_icache_fsm = ICACHE_CC_CHECK; … … 1738 1722 1739 1723 // coherence interrupt 1740 if ( r_cc_receive_icache_req.read() and not r_icache_cc_send_req.read() and not r_icache_cleanup_victim_req.read())1724 if (r_cc_receive_icache_req.read() and not r_icache_cc_send_req.read() and not r_icache_cleanup_victim_req.read()) 1741 1725 { 1742 1726 r_icache_fsm = ICACHE_CC_CHECK; … … 1745 1729 } 1746 1730 1747 if ( r_vci_rsp_ins_error.read()) // bus error1731 if (r_vci_rsp_ins_error.read()) // bus error 1748 1732 { 1749 1733 r_mmu_ietr = MMU_READ_DATA_ILLEGAL_ACCESS; … … 1754 1738 r_icache_fsm = ICACHE_IDLE; 1755 1739 } 1756 else if ( r_vci_rsp_fifo_icache.rok()) // response available1740 else if (r_vci_rsp_fifo_icache.rok()) // response available 1757 1741 { 1758 1742 r_icache_miss_word = 0; … … 1762 1746 } 1763 1747 /////////////////////////// 1764 case ICACHE_MISS_DATA_UPDT: 1765 { 1766 if ( m_ireq.valid) m_cost_ins_miss_frz++;1767 1768 if ( r_vci_rsp_fifo_icache.rok() )// response available1748 case ICACHE_MISS_DATA_UPDT: // update the cache (one word per cycle) 1749 { 1750 if (m_ireq.valid) m_cost_ins_miss_frz++; 1751 1752 if (r_vci_rsp_fifo_icache.rok()) // response available 1769 1753 { 1770 1754 1771 1755 #ifdef INSTRUMENTATION 1772 m_cpt_icache_data_write++;1773 #endif 1774 r_icache.write( 1775 1776 1777 r_vci_rsp_fifo_icache.read());1756 m_cpt_icache_data_write++; 1757 #endif 1758 r_icache.write(r_icache_miss_way.read(), 1759 r_icache_miss_set.read(), 1760 r_icache_miss_word.read(), 1761 r_vci_rsp_fifo_icache.read()); 1778 1762 #if DEBUG_ICACHE 1779 if ( m_debug_activated)1780 {1781 std::cout << " <PROC " << name()1782 << " ICACHE_MISS_DATA_UPDT> Write one word:"1783 << " WDATA = " << std::hex << r_vci_rsp_fifo_icache.read()1784 << " WAY = " << r_icache_miss_way.read()1785 << " SET = " << r_icache_miss_set.read()1786 << " WORD = " << r_icache_miss_word.read() << std::endl;1787 }1763 if (m_debug_activated) 1764 { 1765 std::cout << " <PROC " << name() 1766 << " ICACHE_MISS_DATA_UPDT> Write one word:" 1767 << " WDATA = " << std::hex << r_vci_rsp_fifo_icache.read() 1768 << " WAY = " << r_icache_miss_way.read() 1769 << " SET = " << r_icache_miss_set.read() 1770 << " WORD = " << r_icache_miss_word.read() << std::endl; 1771 } 1788 1772 #endif 1789 1773 vci_rsp_fifo_icache_get = true; 1790 1774 r_icache_miss_word = r_icache_miss_word.read() + 1; 1791 1775 1792 if ( r_icache_miss_word.read() == m_icache_words-1 )// last word1776 if (r_icache_miss_word.read() == m_icache_words - 1) // last word 1793 1777 { 1794 1778 r_icache_fsm = ICACHE_MISS_DIR_UPDT; … … 1806 1790 // to ZOMBI state, and send a cleanup request. 1807 1791 { 1808 if ( m_ireq.valid) m_cost_ins_miss_frz++;1792 if (m_ireq.valid) m_cost_ins_miss_frz++; 1809 1793 1810 1794 // send cleanup victim request 1811 if ( r_icache_cleanup_victim_req.read() and not r_icache_cc_send_req.read())1795 if (r_icache_cleanup_victim_req.read() and not r_icache_cc_send_req.read()) 1812 1796 { 1813 1797 r_icache_cc_send_req = true; … … 1819 1803 1820 1804 // coherence clack interrupt 1821 if ( r_icache_clack_req.read())1805 if (r_icache_clack_req.read()) 1822 1806 { 1823 1807 r_icache_fsm = ICACHE_CC_CHECK; … … 1827 1811 1828 1812 // coherence interrupt 1829 if ( r_cc_receive_icache_req.read() and not r_icache_cc_send_req.read() and not r_icache_cleanup_victim_req.read())1813 if (r_cc_receive_icache_req.read() and not r_icache_cc_send_req.read() and not r_icache_cleanup_victim_req.read()) 1830 1814 { 1831 1815 r_icache_fsm = ICACHE_CC_CHECK; … … 1834 1818 } 1835 1819 1836 if ( not r_icache_miss_clack.read()) // waiting cleanup acknowledge for victim line1837 { 1838 if ( r_icache_miss_inval )// Switch slot to ZOMBI state, and new cleanup1839 { 1840 if ( not r_icache_cc_send_req.read())1820 if (not r_icache_miss_clack.read()) // waiting cleanup acknowledge for victim line 1821 { 1822 if (r_icache_miss_inval) // Switch slot to ZOMBI state, and new cleanup 1823 { 1824 if (not r_icache_cc_send_req.read()) 1841 1825 { 1842 1826 r_icache_miss_inval = false; 1843 1827 // request cleanup 1844 1828 r_icache_cc_send_req = true; 1845 r_icache_cc_send_nline = r_icache_vci_paddr.read() / (m_icache_words <<2);1829 r_icache_cc_send_nline = r_icache_vci_paddr.read() / (m_icache_words << 2); 1846 1830 r_icache_cc_send_way = r_icache_miss_way.read(); 1847 1831 r_icache_cc_send_type = CC_TYPE_CLEANUP; 1848 1832 1849 1833 #ifdef INSTRUMENTATION 1850 m_cpt_icache_dir_write++;1851 #endif 1852 r_icache.write_dir( 1853 1854 1855 CACHE_SLOT_STATE_ZOMBI);1834 m_cpt_icache_dir_write++; 1835 #endif 1836 r_icache.write_dir(r_icache_vci_paddr.read(), 1837 r_icache_miss_way.read(), 1838 r_icache_miss_set.read(), 1839 CACHE_SLOT_STATE_ZOMBI); 1856 1840 #if DEBUG_ICACHE 1857 if ( m_debug_activated)1858 {1859 std::cout << " <PROC " << name()1860 << " ICACHE_MISS_DIR_UPDT> Switch cache slot to ZOMBI state"1861 << " PADDR = " << std::hex << r_icache_vci_paddr.read()1862 << " WAY = " << std::dec << r_icache_miss_way.read()1863 << " SET = " << r_icache_miss_set.read() << std::endl;1864 }1841 if (m_debug_activated) 1842 { 1843 std::cout << " <PROC " << name() 1844 << " ICACHE_MISS_DIR_UPDT> Switch cache slot to ZOMBI state" 1845 << " PADDR = " << std::hex << r_icache_vci_paddr.read() 1846 << " WAY = " << std::dec << r_icache_miss_way.read() 1847 << " SET = " << r_icache_miss_set.read() << std::endl; 1848 } 1865 1849 #endif 1866 1850 } … … 1868 1852 break; 1869 1853 } 1870 else 1854 else // Switch slot to VALID state 1871 1855 { 1872 1856 1873 1857 #ifdef INSTRUMENTATION 1874 m_cpt_icache_dir_write++;1875 #endif 1876 r_icache.write_dir( 1877 1878 1879 CACHE_SLOT_STATE_VALID_CC);1858 m_cpt_icache_dir_write++; 1859 #endif 1860 r_icache.write_dir(r_icache_vci_paddr.read(), 1861 r_icache_miss_way.read(), 1862 r_icache_miss_set.read(), 1863 CACHE_SLOT_STATE_VALID_CC); 1880 1864 #if DEBUG_ICACHE 1881 if ( m_debug_activated)1882 {1883 std::cout << " <PROC " << name()1884 << " ICACHE_MISS_DIR_UPDT> Switch cache slot to VALID state"1885 << " PADDR = " << std::hex << r_icache_vci_paddr.read()1886 << " WAY = " << std::dec << r_icache_miss_way.read()1887 << " SET = " << r_icache_miss_set.read() << std::endl;1888 }1865 if (m_debug_activated) 1866 { 1867 std::cout << " <PROC " << name() 1868 << " ICACHE_MISS_DIR_UPDT> Switch cache slot to VALID state" 1869 << " PADDR = " << std::hex << r_icache_vci_paddr.read() 1870 << " WAY = " << std::dec << r_icache_miss_way.read() 1871 << " SET = " << r_icache_miss_set.read() << std::endl; 1872 } 1889 1873 #endif 1890 1874 } … … 1895 1879 } 1896 1880 //////////////////// 1897 case ICACHE_UNC_WAIT: 1881 case ICACHE_UNC_WAIT: // waiting a response to an uncacheable read from VCI_RSP FSM 1898 1882 { 1899 1883 // coherence clack interrupt 1900 if ( r_icache_clack_req.read())1901 { 1902 r_icache_fsm = ICACHE_CC_CHECK;1884 if (r_icache_clack_req.read()) 1885 { 1886 r_icache_fsm = ICACHE_CC_CHECK; 1903 1887 r_icache_fsm_save = r_icache_fsm.read(); 1904 1888 break; … … 1906 1890 1907 1891 // coherence interrupt 1908 if ( 1909 { 1910 r_icache_fsm = ICACHE_CC_CHECK;1892 if (r_cc_receive_icache_req.read() and not r_icache_cc_send_req.read()) 1893 { 1894 r_icache_fsm = ICACHE_CC_CHECK; 1911 1895 r_icache_fsm_save = r_icache_fsm.read(); 1912 1896 break; 1913 1897 } 1914 1898 1915 if ( r_vci_rsp_ins_error.read()) // bus error1899 if (r_vci_rsp_ins_error.read()) // bus error 1916 1900 { 1917 1901 r_mmu_ietr = MMU_READ_DATA_ILLEGAL_ACCESS; … … 1922 1906 r_icache_fsm = ICACHE_IDLE; 1923 1907 } 1924 else if (r_vci_rsp_fifo_icache.rok() 1908 else if (r_vci_rsp_fifo_icache.rok()) // instruction available 1925 1909 { 1926 1910 vci_rsp_fifo_icache_get = true; 1927 1911 r_icache_fsm = ICACHE_IDLE; 1928 if ( 1929 (m_ireq.addr == r_icache_vaddr_save.read()) 1912 if (m_ireq.valid and 1913 (m_ireq.addr == r_icache_vaddr_save.read())) // request unmodified 1930 1914 { 1931 1915 m_irsp.valid = true; … … 1936 1920 } 1937 1921 ///////////////////// 1938 case ICACHE_CC_CHECK: 1939 1940 1941 1942 1943 { 1944 paddr_t 1945 paddr_t mask = ~((m_icache_words<<2)-1);1922 case ICACHE_CC_CHECK: // This state is the entry point of a sub-fsm 1923 // handling coherence requests. 1924 // if there is a matching pending miss, it is 1925 // signaled in the r_icache_miss_inval flip-flop. 1926 // The return state is defined in r_icache_fsm_save. 1927 { 1928 paddr_t paddr = r_cc_receive_icache_nline.read() * m_icache_words * 4; 1929 paddr_t mask = ~((m_icache_words << 2) - 1); 1946 1930 1947 1931 // CLACK handler … … 1949 1933 // and reset r_icache_miss_clack if the cleanup ack 1950 1934 // is matching a pending miss. 1951 if ( r_icache_clack_req.read())1952 { 1953 1954 if ( m_ireq.valid) m_cost_ins_miss_frz++;1935 if (r_icache_clack_req.read()) 1936 { 1937 1938 if (m_ireq.valid) m_cost_ins_miss_frz++; 1955 1939 1956 1940 #ifdef INSTRUMENTATION 1957 m_cpt_icache_dir_write++;1958 #endif 1959 r_icache.write_dir( 1960 1961 1962 1963 1964 if ( 1965 (r_icache_miss_way.read() == r_icache_clack_way.read()) 1941 m_cpt_icache_dir_write++; 1942 #endif 1943 r_icache.write_dir(0, 1944 r_icache_clack_way.read(), 1945 r_icache_clack_set.read(), 1946 CACHE_SLOT_STATE_EMPTY); 1947 1948 if ((r_icache_miss_set.read() == r_icache_clack_set.read()) and 1949 (r_icache_miss_way.read() == r_icache_clack_way.read())) 1966 1950 { 1967 1951 r_icache_miss_clack = false; … … 1974 1958 1975 1959 #if DEBUG_ICACHE 1976 if ( m_debug_activated)1977 {1978 std::cout << " <PROC " << name()1979 << " ICACHE_CC_CHECK> CC_TYPE_CLACK slot returns to empty state"1980 << " set = " << r_icache_clack_set.read()1981 << " / way = " << r_icache_clack_way.read() << std::endl;1982 }1960 if (m_debug_activated) 1961 { 1962 std::cout << " <PROC " << name() 1963 << " ICACHE_CC_CHECK> CC_TYPE_CLACK slot returns to empty state" 1964 << " set = " << r_icache_clack_set.read() 1965 << " / way = " << r_icache_clack_way.read() << std::endl; 1966 } 1983 1967 #endif 1984 1968 … … 1990 1974 // because the CLACK access the directory but the MISS match dont. 1991 1975 if (r_cc_receive_icache_req.read() and 1992 ((r_icache_fsm_save.read() == ICACHE_MISS_SELECT 1993 (r_icache_fsm_save.read() == ICACHE_MISS_WAIT 1976 ((r_icache_fsm_save.read() == ICACHE_MISS_SELECT) or 1977 (r_icache_fsm_save.read() == ICACHE_MISS_WAIT) or 1994 1978 (r_icache_fsm_save.read() == ICACHE_MISS_DIR_UPDT)) and 1995 ((r_icache_vci_paddr.read() & mask) == (paddr & mask)) 1979 ((r_icache_vci_paddr.read() & mask) == (paddr & mask))) // matching 1996 1980 { 1997 1981 // signaling the matching 1998 r_icache_miss_inval 1982 r_icache_miss_inval = true; 1999 1983 2000 1984 // in case of update, go to CC_UPDT … … 2002 1986 if (r_cc_receive_icache_type.read() == CC_TYPE_UPDT) 2003 1987 { 2004 r_icache_fsm 2005 r_icache_cc_word 1988 r_icache_fsm = ICACHE_CC_UPDT; 1989 r_icache_cc_word = r_cc_receive_word_idx.read(); 2006 1990 2007 1991 // just pop the fifo , don't write in icache … … 2012 1996 { 2013 1997 r_cc_receive_icache_req = false; 2014 r_icache_fsm 1998 r_icache_fsm = r_icache_fsm_save.read(); 2015 1999 } 2016 2000 #if DEBUG_ICACHE 2017 if ( m_debug_activated)2018 {2019 std::cout << " <PROC " << name()2020 << " ICACHE_CC_CHECK> Coherence request matching a pending miss:"2021 << " PADDR = " << std::hex << paddr << std::endl;2022 }2023 #endif 2024 } 2025 2026 assert (not r_icache_cc_send_req.read() and "CC_SEND must be available in ICACHE_CC_CHECK");2001 if (m_debug_activated) 2002 { 2003 std::cout << " <PROC " << name() 2004 << " ICACHE_CC_CHECK> Coherence request matching a pending miss:" 2005 << " PADDR = " << std::hex << paddr << std::endl; 2006 } 2007 #endif 2008 } 2009 2010 assert(not r_icache_cc_send_req.read() and "CC_SEND must be available in ICACHE_CC_CHECK"); 2027 2011 2028 2012 // CC request handler 2029 2013 2030 int 2031 size_t 2032 size_t 2033 size_t 2014 int state = 0; 2015 size_t way = 0; 2016 size_t set = 0; 2017 size_t word = 0; 2034 2018 2035 2019 #ifdef INSTRUMENTATION 2036 m_cpt_icache_dir_read++;2020 m_cpt_icache_dir_read++; 2037 2021 #endif 2038 2022 r_icache.read_dir(paddr, … … 2045 2029 r_icache_cc_set = set; 2046 2030 2047 if ( 2031 if (state == CACHE_SLOT_STATE_VALID_CC) // hit 2048 2032 { 2049 2033 // need to update the cache state … … 2051 2035 { 2052 2036 r_icache_cc_need_write = true; 2053 r_icache_fsm 2054 r_icache_cc_word 2055 } 2056 else if ( r_cc_receive_icache_type.read() == CC_TYPE_INVAL) // hit inval2057 { 2058 r_icache_fsm 2037 r_icache_fsm = ICACHE_CC_UPDT; 2038 r_icache_cc_word = r_cc_receive_word_idx.read(); 2039 } 2040 else if (r_cc_receive_icache_type.read() == CC_TYPE_INVAL) // hit inval 2041 { 2042 r_icache_fsm = ICACHE_CC_INVAL; 2059 2043 } 2060 2044 } … … 2062 2046 { 2063 2047 // multicast acknowledgement required in case of update 2064 if (r_cc_receive_icache_type.read() == CC_TYPE_UPDT)2065 { 2066 r_icache_fsm 2067 r_icache_cc_word 2048 if (r_cc_receive_icache_type.read() == CC_TYPE_UPDT) 2049 { 2050 r_icache_fsm = ICACHE_CC_UPDT; 2051 r_icache_cc_word = r_cc_receive_word_idx.read(); 2068 2052 2069 2053 // just pop the fifo , don't write in icache … … 2073 2057 { 2074 2058 r_cc_receive_icache_req = false; 2075 r_icache_fsm 2059 r_icache_fsm = r_icache_fsm_save.read(); 2076 2060 } 2077 2061 } 2078 2062 #if DEBUG_ICACHE 2079 if ( m_debug_activated ) 2080 { 2081 std::cout << " <PROC " << name() 2082 << " ICACHE_CC_CHECK> Coherence request received:" 2083 << " PADDR = " << std::hex << paddr 2084 << " / TYPE = " << std::dec << r_cc_receive_dcache_type.read() 2085 << " / HIT = " << ((state == CACHE_SLOT_STATE_VALID_CC) or (state == CACHE_SLOT_STATE_VALID_NCC)) << std::endl; 2086 } 2087 #endif 2088 2063 if (m_debug_activated) 2064 { 2065 std::cout << " <PROC " << name() 2066 << " ICACHE_CC_CHECK> Coherence request received:" 2067 << " PADDR = " << std::hex << paddr 2068 << " / TYPE = " << std::dec << r_cc_receive_dcache_type.read() 2069 << " / HIT = " << ((state == CACHE_SLOT_STATE_VALID_CC) or (state == CACHE_SLOT_STATE_VALID_NCC)) << std::endl; 2070 } 2071 #endif 2089 2072 break; 2090 2073 } 2091 2074 ///////////////////// 2092 case ICACHE_CC_INVAL: 2093 { 2094 assert (not r_icache_cc_send_req.read() &&2095 2096 2075 case ICACHE_CC_INVAL: // hit inval : switch slot to ZOMBI state 2076 { 2077 assert(not r_icache_cc_send_req.read() and 2078 "ERROR in ICACHE_CC_INVAL: the r_icache_cc_send_req " 2079 "must not be set"); 2097 2080 2098 2081 #ifdef INSTRUMENTATION 2099 m_cpt_icache_dir_read++;2082 m_cpt_icache_dir_read++; 2100 2083 #endif 2101 2084 2102 2085 // Switch slot state to ZOMBI and send CLEANUP command 2103 r_icache.write_dir( 2104 2105 CACHE_SLOT_STATE_ZOMBI);2086 r_icache.write_dir(r_icache_cc_way.read(), 2087 r_icache_cc_set.read(), 2088 CACHE_SLOT_STATE_ZOMBI); 2106 2089 2107 2090 // coherence request completed … … 2111 2094 r_icache_cc_send_type = CC_TYPE_CLEANUP; 2112 2095 2113 r_icache_fsm 2096 r_icache_fsm = r_icache_fsm_save.read(); 2114 2097 2115 2098 #if DEBUG_ICACHE 2116 if ( m_debug_activated)2117 {2118 std::cout << " <PROC " << name()2119 << " ICACHE_CC_INVAL> slot returns to ZOMBI state"2120 << " set = " << r_icache_cc_set.read()2121 << " / way = " << r_icache_cc_way.read() << std::endl;2122 }2099 if (m_debug_activated) 2100 { 2101 std::cout << " <PROC " << name() 2102 << " ICACHE_CC_INVAL> slot returns to ZOMBI state" 2103 << " set = " << r_icache_cc_set.read() 2104 << " / way = " << r_icache_cc_way.read() << std::endl; 2105 } 2123 2106 #endif 2124 2107 … … 2126 2109 } 2127 2110 //////////////////// 2128 case ICACHE_CC_UPDT: 2129 { 2130 assert (not r_icache_cc_send_req.read() &&2131 2132 2133 2134 if ( not r_cc_receive_updt_fifo_be.rok()) break;2135 2136 2137 size_t word= r_icache_cc_word.read();2138 size_t way= r_icache_cc_way.read();2139 size_t set= r_icache_cc_set.read();2111 case ICACHE_CC_UPDT: // hit update : write one word per cycle 2112 { 2113 assert(not r_icache_cc_send_req.read() and 2114 "ERROR in ICACHE_CC_UPDT: the r_icache_cc_send_req " 2115 "must not be set"); 2116 2117 if (not r_cc_receive_updt_fifo_be.rok()) break; 2118 2119 2120 size_t word = r_icache_cc_word.read(); 2121 size_t way = r_icache_cc_way.read(); 2122 size_t set = r_icache_cc_set.read(); 2140 2123 2141 2124 if (r_icache_cc_need_write.read()) 2142 2125 { 2143 r_icache.write( 2144 2145 2146 2147 r_cc_receive_updt_fifo_be.read());2148 2149 r_icache_cc_word = word +1;2126 r_icache.write(way, 2127 set, 2128 word, 2129 r_cc_receive_updt_fifo_data.read(), 2130 r_cc_receive_updt_fifo_be.read()); 2131 2132 r_icache_cc_word = word + 1; 2150 2133 2151 2134 #ifdef INSTRUMENTATION 2152 m_cpt_icache_data_write++;2135 m_cpt_icache_data_write++; 2153 2136 #endif 2154 2137 2155 2138 #if DEBUG_ICACHE 2156 if ( m_debug_activated)2157 {2158 std::cout << " <PROC " << name()2159 << " ICACHE_CC_UPDT> Write one word "2160 << " set = " << r_icache_cc_set.read()2161 << " / way = " << r_icache_cc_way.read()2162 << " / word = " << r_icache_cc_word.read() << std::endl;2163 }2164 #endif 2165 } 2166 2167 if ( r_cc_receive_updt_fifo_eop.read() )// last word2139 if (m_debug_activated) 2140 { 2141 std::cout << " <PROC " << name() 2142 << " ICACHE_CC_UPDT> Write one word " 2143 << " set = " << r_icache_cc_set.read() 2144 << " / way = " << r_icache_cc_way.read() 2145 << " / word = " << r_icache_cc_word.read() << std::endl; 2146 } 2147 #endif 2148 } 2149 2150 if (r_cc_receive_updt_fifo_eop.read()) // last word 2168 2151 { 2169 2152 // no need to write in the cache anymore 2170 r_icache_cc_need_write 2153 r_icache_cc_need_write = false; 2171 2154 2172 2155 // coherence request completed 2173 r_cc_receive_icache_req 2156 r_cc_receive_icache_req = false; 2174 2157 2175 2158 // request multicast acknowledgement … … 2179 2162 r_icache_cc_send_type = CC_TYPE_MULTI_ACK; 2180 2163 2181 r_icache_fsm 2164 r_icache_fsm = r_icache_fsm_save.read(); 2182 2165 } 2183 2166 //consume fifo if not eop 2184 cc_receive_updt_fifo_get 2167 cc_receive_updt_fifo_get = true; 2185 2168 2186 2169 break; … … 2243 2226 // This component implement a strong order between non cacheable access 2244 2227 // (read or write) : A new non cacheable VCI transaction starts only when 2245 // the previous non cacheable transaction is completed. Both cacheable and 2246 // non cacheable transactions use the write buffer, but the DCACHE FSM registers 2247 // a non cacheable write transaction posted in the write buffer by setting the 2248 // r_dcache_pending_unc_write flip_flop. All other non cacheable requests 2249 // are stalled until this flip-flop is reset by the VCI_RSP_FSM (when the 2250 // pending non cacheable write transaction completes). 2228 // the previous non cacheable transaction is completed. After send the VCI 2229 // transaction, the DCACHE FSM wait for the respone in the DCACHE_UNC_WAIT state. 2230 // So the processor is blocked until the respone arrives in CACHE L1. 2251 2231 // 2252 2232 // 6/ Error handling: 2253 2233 // When the MMU is not activated, Read Bus Errors are synchronous events, 2254 // but Write Bus Errors are asynchronous events (processor is not frozen). 2255 // - If a Read Bus Error is detected, the VCI_RSP FSM sets the 2234 // Some Write Bus Errors are synchronous events when the request is a non cacheable access 2235 // but some Write Bus Errors are asynchronous events when the request is cacheable access 2236 // (processor is not frozen). 2237 // - If a Read Bus Error or a Non Cacheable Write Bus Error is detected, the VCI_RSP FSM sets the 2256 2238 // r_vci_rsp_data_error flip-flop, without writing any data in the 2257 2239 // r_vci_rsp_fifo_dcache FIFO, and the synchronous error is signaled 2258 2240 // by the DCACHE FSM. 2259 // - If a Write Bus Error is detected, the VCI_RSP FSMsignals2260 // 2241 // - If a Cacheable Write Bus Error is detected, the VCI_RSP_FSM signals 2242 // the asynchronous error using the setWriteBerr() method. 2261 2243 // When the MMU is activated bus error are rare events, as the MMU 2262 2244 // checks the physical address before the VCI transaction starts. … … 2268 2250 m_drsp.rdata = 0; 2269 2251 2270 switch ( r_dcache_fsm.read())2252 switch (r_dcache_fsm.read()) 2271 2253 { 2272 2254 case DCACHE_IDLE: // There are 10 conditions to exit the IDLE state : … … 2278 2260 // 6) Dirty bit update (processor) => DCACHE_DIRTY_GET_PTE 2279 2261 // 7) Cacheable read miss (processor) => DCACHE_MISS_SELECT 2280 // 8) Uncacheable read (processor)=> DCACHE_UNC_WAIT2262 // 8) Uncacheable read/write (processor)=> DCACHE_UNC_WAIT 2281 2263 // 9) LL access (processor) => DCACHE_LL_WAIT 2282 2264 // 10) SC access (processor) => DCACHE_SC_WAIT … … 2305 2287 // updt_request, wbuf_request, wbuf_write_miss. 2306 2288 { 2307 paddr_t paddr; // physical address2308 pte_info_t 2309 size_t 2310 size_t 2311 paddr_t 2312 size_t 2313 size_t 2314 size_t 2315 uint32_t 2316 bool 2317 int 2318 2319 bool tlb_inval_required = false;// request TLB inval after cache update2320 bool wbuf_write_miss = false;// miss a WBUF write request2321 bool updt_request = false;// request DCACHE update in P1 stage2322 bool wbuf_request = false;// request WBUF write in P1 stage2323 2324 // physical address computation : systematic DTLB access (if activated)2289 paddr_t paddr; 2290 pte_info_t tlb_flags; 2291 size_t tlb_way; 2292 size_t tlb_set; 2293 paddr_t tlb_nline = 0; 2294 size_t cache_way; 2295 size_t cache_set; 2296 size_t cache_word; 2297 uint32_t cache_rdata = 0; 2298 bool tlb_hit = false; 2299 int cache_state = CACHE_SLOT_STATE_EMPTY; 2300 2301 bool tlb_inval_required = false; // request TLB inval after cache update 2302 bool wbuf_write_miss = false; // miss a WBUF write request 2303 bool updt_request = false; // request DCACHE update in P1 stage 2304 bool wbuf_request = false; // request WBUF write in P1 stage 2305 2306 // physical address computation : systematic DTLB access if activated 2325 2307 paddr = (paddr_t) m_dreq.addr; 2326 if ( m_dreq.valid)2327 { 2328 if ( r_mmu_mode.read() & DATA_TLB_MASK) // DTLB activated2329 { 2330 tlb_hit = r_dtlb.translate( 2331 2332 2333 2334 2335 &tlb_set);2308 if (m_dreq.valid) 2309 { 2310 if (r_mmu_mode.read() & DATA_TLB_MASK) // DTLB activated 2311 { 2312 tlb_hit = r_dtlb.translate(m_dreq.addr, 2313 &paddr, 2314 &tlb_flags, 2315 &tlb_nline, 2316 &tlb_way, 2317 &tlb_set); 2336 2318 #ifdef INSTRUMENTATION 2337 m_cpt_data_tlb_read++;2338 #endif 2339 } 2340 else 2319 m_cpt_dtlb_read++; 2320 #endif 2321 } 2322 else // identity mapping 2341 2323 { 2342 2324 // we take into account the paddr extension 2343 2325 if (vci_param::N > 32) 2344 paddr = paddr | ((paddr_t) (r_dcache_paddr_ext.read()) << 32);2326 paddr = paddr | ((paddr_t) (r_dcache_paddr_ext.read()) << 32); 2345 2327 } 2346 2328 } // end physical address computation 2347 2329 2348 2330 // systematic DCACHE access depending on r_dcache_updt_req (if activated) 2349 if ( 2350 { 2351 2352 if ( m_dreq.valid and r_dcache_updt_req.read()) // read DIR and write DATA2353 { 2354 r_dcache.read_dir( 2355 2356 2357 2358 &cache_word);2359 2360 r_dcache.write( 2361 2362 2363 2364 r_dcache_save_be.read());2331 if (r_mmu_mode.read() & DATA_CACHE_MASK) 2332 { 2333 2334 if (m_dreq.valid and r_dcache_updt_req.read()) // read DIR and write DATA 2335 { 2336 r_dcache.read_dir(paddr, 2337 &cache_state, 2338 &cache_way, 2339 &cache_set, 2340 &cache_word); 2341 2342 r_dcache.write(r_dcache_save_cache_way.read(), 2343 r_dcache_save_cache_set.read(), 2344 r_dcache_save_cache_word.read(), 2345 r_dcache_save_wdata.read(), 2346 r_dcache_save_be.read()); 2365 2347 #ifdef INSTRUMENTATION 2366 m_cpt_dcache_dir_read++;2367 m_cpt_dcache_data_write++;2368 #endif 2369 } 2370 else if ( m_dreq.valid and not r_dcache_updt_req.read()) // read DIR and DATA2371 { 2372 r_dcache.read( 2373 2374 2375 2376 2377 &cache_state);2348 m_cpt_dcache_dir_read++; 2349 m_cpt_dcache_data_write++; 2350 #endif 2351 } 2352 else if (m_dreq.valid and not r_dcache_updt_req.read()) // read DIR and DATA 2353 { 2354 r_dcache.read(paddr, 2355 &cache_rdata, 2356 &cache_way, 2357 &cache_set, 2358 &cache_word, 2359 &cache_state); 2378 2360 2379 2361 #ifdef INSTRUMENTATION 2380 m_cpt_dcache_dir_read++;2381 m_cpt_dcache_data_read++;2382 #endif 2383 } 2384 else if ( not m_dreq.valid and r_dcache_updt_req.read()) // write DATA2385 { 2386 r_dcache.write( 2387 2388 2389 2390 r_dcache_save_be.read());2362 m_cpt_dcache_dir_read++; 2363 m_cpt_dcache_data_read++; 2364 #endif 2365 } 2366 else if (not m_dreq.valid and r_dcache_updt_req.read()) // write DATA 2367 { 2368 r_dcache.write(r_dcache_save_cache_way.read(), 2369 r_dcache_save_cache_set.read(), 2370 r_dcache_save_cache_word.read(), 2371 r_dcache_save_wdata.read(), 2372 r_dcache_save_be.read()); 2391 2373 #ifdef INSTRUMENTATION 2392 m_cpt_dcache_data_write++;2374 m_cpt_dcache_data_write++; 2393 2375 #endif 2394 2376 } … … 2396 2378 2397 2379 // DCACHE update in P1 stage can require ITLB / DTLB inval or flush 2398 if ( r_dcache_updt_req.read())2380 if (r_dcache_updt_req.read()) 2399 2381 { 2400 2382 size_t way = r_dcache_save_cache_way.read(); 2401 2383 size_t set = r_dcache_save_cache_set.read(); 2402 2384 2403 if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_IN_TLB ) 2404 { 2405 tlb_inval_required = true; 2406 r_dcache_tlb_inval_set = 0; 2407 r_dcache_tlb_inval_line = r_dcache_save_paddr.read()>> 2408 (uint32_log2(m_dcache_words<<2)); 2409 2410 r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_DIRTY; 2411 } 2412 else if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_CONTAINS_PTD ) 2385 if (r_dcache_content_state[way * m_dcache_sets + set] == LINE_CACHE_IN_TLB) 2386 { 2387 tlb_inval_required = true; 2388 r_dcache_tlb_inval_set = 0; 2389 r_dcache_tlb_inval_line = r_dcache_save_paddr.read() >> 2390 (uint32_log2(m_dcache_words << 2)); 2391 r_dcache_content_state[way * m_dcache_sets + set] = LINE_CACHE_DATA_DIRTY; 2392 } 2393 else if (r_dcache_content_state[way * m_dcache_sets + set] == LINE_CACHE_CONTAINS_PTD) 2413 2394 { 2414 2395 r_itlb.reset(); 2415 2396 r_dtlb.reset(); 2416 2417 r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_DIRTY; 2397 r_dcache_content_state[way * m_dcache_sets + set] = LINE_CACHE_DATA_DIRTY; 2418 2398 } 2419 2399 2420 2400 #if DEBUG_DCACHE 2421 if ( m_debug_activated ) 2422 std::cout << " <PROC " << name() << " DCACHE_IDLE>" 2423 << " Cache update in P1 stage" << std::dec 2424 << " / WAY = " << r_dcache_save_cache_way.read() 2425 << " / SET = " << r_dcache_save_cache_set.read() 2426 << " / WORD = " << r_dcache_save_cache_word.read() << std::hex 2427 << " / WDATA = " << r_dcache_save_wdata.read() 2428 << " / BE = " << r_dcache_save_be.read() << std::endl; 2401 if (m_debug_activated) 2402 { 2403 std::cout << " <PROC " << name() << " DCACHE_IDLE>" 2404 << " Cache update in P1 stage" << std::dec 2405 << " / WAY = " << r_dcache_save_cache_way.read() 2406 << " / SET = " << r_dcache_save_cache_set.read() 2407 << " / WORD = " << r_dcache_save_cache_word.read() << std::hex 2408 << " / WDATA = " << r_dcache_save_wdata.read() 2409 << " / BE = " << r_dcache_save_be.read() << std::endl; 2410 } 2429 2411 #endif 2430 2412 } // end test TLB inval … … 2433 2415 // Miss if the write request is non cacheable, and there is a pending 2434 2416 // non cacheable write, or if the write buffer is full. 2435 if ( r_dcache_wbuf_req.read() ) 2436 { 2437 bool wok = r_wbuf.write( r_dcache_save_paddr.read(), 2438 r_dcache_save_be.read(), 2439 r_dcache_save_wdata.read(), 2440 true ); 2441 /*#ifdef INSTRUMENTATION 2442 m_cpt_wbuf_write++; 2443 #endif*/ 2444 2445 if ( not wok ) // miss if write buffer full 2417 if (r_dcache_wbuf_req.read()) 2418 { 2419 bool wok = r_wbuf.write(r_dcache_save_paddr.read(), 2420 r_dcache_save_be.read(), 2421 r_dcache_save_wdata.read(), 2422 true); 2423 #ifdef INSTRUMENTATION 2424 m_cpt_wbuf_write++; 2425 #endif 2426 if (not wok) // miss if write buffer full 2446 2427 { 2447 2428 wbuf_write_miss = true; 2448 2429 } 2449 2430 } // end WBUF update 2450 2431 … … 2453 2434 2454 2435 // itlb/dtlb invalidation self-request 2455 if ( tlb_inval_required)2436 if (tlb_inval_required) 2456 2437 { 2457 2438 r_dcache_fsm_scan_save = r_dcache_fsm.read(); … … 2460 2441 2461 2442 // coherence clack request (from DSPIN CLACK) 2462 else if ( r_dcache_clack_req.read())2443 else if (r_dcache_clack_req.read()) 2463 2444 { 2464 2445 r_dcache_fsm = DCACHE_CC_CHECK; … … 2466 2447 } 2467 2448 // coherence request (from CC_RECEIVE FSM) 2468 else if ( 2449 else if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 2469 2450 { 2470 2451 r_dcache_fsm = DCACHE_CC_CHECK; … … 2475 2456 // we don't take the processor request, and registers 2476 2457 // are frozen in case of wbuf_write_miss 2477 else if ( m_dreq.valid and not wbuf_write_miss)2458 else if (m_dreq.valid and not wbuf_write_miss) 2478 2459 { 2479 2460 // register processor request and DCACHE response … … 2491 2472 if (m_dreq.type == iss_t::XTN_READ) 2492 2473 { 2493 int xtn_opcode = (int)m_dreq.addr /4;2474 int xtn_opcode = (int)m_dreq.addr / 4; 2494 2475 2495 2476 // checking processor mode: … … 2505 2486 else 2506 2487 { 2507 switch ( xtn_opcode)2488 switch (xtn_opcode) 2508 2489 { 2509 2490 case iss_t::XTN_INS_ERROR_TYPE: … … 2580 2561 2581 2562 default: 2582 r_mmu_detr = MMU_READ_UNDEFINED_XTN;2563 r_mmu_detr = MMU_READ_UNDEFINED_XTN; 2583 2564 r_mmu_dbvar = m_dreq.addr; 2584 2565 m_drsp.valid = true; … … 2598 2579 else if (m_dreq.type == iss_t::XTN_WRITE) 2599 2580 { 2600 int xtn_opcode = (int) m_dreq.addr/4;2581 int xtn_opcode = (int) m_dreq.addr / 4; 2601 2582 r_dcache_xtn_opcode = xtn_opcode; 2602 2583 2603 2584 // checking processor mode: 2604 if ( (m_dreq.mode== iss_t::MODE_USER) &&2605 2606 2607 2608 2609 (xtn_opcode != iss_t::XTN_ICACHE_FLUSH))2585 if ((m_dreq.mode == iss_t::MODE_USER) && 2586 (xtn_opcode != iss_t::XTN_SYNC) && 2587 (xtn_opcode != iss_t::XTN_DCACHE_INVAL) && 2588 (xtn_opcode != iss_t::XTN_DCACHE_FLUSH) && 2589 (xtn_opcode != iss_t::XTN_ICACHE_INVAL) && 2590 (xtn_opcode != iss_t::XTN_ICACHE_FLUSH)) 2610 2591 { 2611 2592 r_mmu_detr = MMU_WRITE_PRIVILEGE_VIOLATION; … … 2618 2599 else 2619 2600 { 2620 switch ( xtn_opcode)2601 switch (xtn_opcode) 2621 2602 { 2622 case iss_t::XTN_PTPR: 2603 case iss_t::XTN_PTPR: // itlb & dtlb must be flushed 2623 2604 r_dcache_xtn_req = true; 2624 2605 r_dcache_fsm = DCACHE_XTN_SWITCH; 2625 2606 break; 2626 2607 2627 case iss_t::XTN_TLB_MODE: 2628 r_mmu_mode 2629 m_drsp.valid 2630 r_dcache_fsm 2608 case iss_t::XTN_TLB_MODE: // no cache or tlb access 2609 r_mmu_mode = m_dreq.wdata; 2610 m_drsp.valid = true; 2611 r_dcache_fsm = DCACHE_IDLE; 2631 2612 break; 2632 2613 2633 case iss_t::XTN_DTLB_INVAL: 2634 r_dcache_fsm 2614 case iss_t::XTN_DTLB_INVAL: // dtlb access 2615 r_dcache_fsm = DCACHE_XTN_DT_INVAL; 2635 2616 break; 2636 2617 2637 case iss_t::XTN_ITLB_INVAL: 2618 case iss_t::XTN_ITLB_INVAL: // itlb access 2638 2619 r_dcache_xtn_req = true; 2639 2620 r_dcache_fsm = DCACHE_XTN_IT_INVAL; 2640 2621 break; 2641 2622 2642 case iss_t::XTN_DCACHE_INVAL: 2643 r_dcache_fsm 2623 case iss_t::XTN_DCACHE_INVAL: // dcache, dtlb & itlb access 2624 r_dcache_fsm = DCACHE_XTN_DC_INVAL_VA; 2644 2625 break; 2645 2626 2646 case iss_t::XTN_MMU_DCACHE_PA_INV: 2647 r_dcache_fsm 2627 case iss_t::XTN_MMU_DCACHE_PA_INV: // dcache, dtlb & itlb access 2628 r_dcache_fsm = DCACHE_XTN_DC_INVAL_PA; 2648 2629 if (sizeof(paddr_t) <= 32) 2649 2630 { … … 2659 2640 break; 2660 2641 2661 case iss_t::XTN_DCACHE_FLUSH: 2642 case iss_t::XTN_DCACHE_FLUSH: // itlb and dtlb must be reset 2662 2643 r_dcache_flush_count = 0; 2663 r_dcache_fsm = DCACHE_XTN_DC_FLUSH;2644 r_dcache_fsm = DCACHE_XTN_DC_FLUSH; 2664 2645 break; 2665 2646 2666 case iss_t::XTN_ICACHE_INVAL: 2647 case iss_t::XTN_ICACHE_INVAL: // icache and itlb access 2667 2648 r_dcache_xtn_req = true; 2668 2649 r_dcache_fsm = DCACHE_XTN_IC_INVAL_VA; 2669 2650 break; 2670 2651 2671 case iss_t::XTN_MMU_ICACHE_PA_INV: 2652 case iss_t::XTN_MMU_ICACHE_PA_INV: // icache access 2672 2653 r_dcache_xtn_req = true; 2673 2654 r_dcache_fsm = DCACHE_XTN_IC_INVAL_PA; 2674 2655 break; 2675 2656 2676 case iss_t::XTN_ICACHE_FLUSH: 2657 case iss_t::XTN_ICACHE_FLUSH: // icache access 2677 2658 r_dcache_xtn_req = true; 2678 2659 r_dcache_fsm = DCACHE_XTN_IC_FLUSH; 2679 2660 break; 2680 2661 2681 case iss_t::XTN_SYNC: 2682 r_dcache_fsm 2662 case iss_t::XTN_SYNC: // wait until write buffer empty 2663 r_dcache_fsm = DCACHE_XTN_SYNC; 2683 2664 break; 2684 2665 2685 case iss_t::XTN_MMU_WORD_LO: 2686 r_mmu_word_lo 2687 m_drsp.valid 2688 r_dcache_fsm 2666 case iss_t::XTN_MMU_WORD_LO: // no cache or tlb access 2667 r_mmu_word_lo = m_dreq.wdata; 2668 m_drsp.valid = true; 2669 r_dcache_fsm = DCACHE_IDLE; 2689 2670 break; 2690 2671 2691 case iss_t::XTN_MMU_WORD_HI: 2692 r_mmu_word_hi 2693 m_drsp.valid 2694 r_dcache_fsm 2672 case iss_t::XTN_MMU_WORD_HI: // no cache or tlb access 2673 r_mmu_word_hi = m_dreq.wdata; 2674 m_drsp.valid = true; 2675 r_dcache_fsm = DCACHE_IDLE; 2695 2676 break; 2696 2677 2697 case iss_t::XTN_MMU_LL_RESET: 2678 case iss_t::XTN_MMU_LL_RESET: // no cache or tlb access 2698 2679 r_dcache_llsc_valid = false; 2699 m_drsp.valid = true;2700 r_dcache_fsm = DCACHE_IDLE;2680 m_drsp.valid = true; 2681 r_dcache_fsm = DCACHE_IDLE; 2701 2682 break; 2702 2683 2703 case iss_t::XTN_DATA_PADDR_EXT: 2684 case iss_t::XTN_DATA_PADDR_EXT: // no cache or tlb access 2704 2685 r_dcache_paddr_ext = m_dreq.wdata; 2705 2686 m_drsp.valid = true; … … 2707 2688 break; 2708 2689 2709 case iss_t::XTN_INST_PADDR_EXT: 2690 case iss_t::XTN_INST_PADDR_EXT: // no cache or tlb access 2710 2691 r_dcache_xtn_req = true; 2711 2692 r_dcache_fsm = DCACHE_XTN_IC_PADDR_EXT; 2712 2693 break; 2713 2694 2714 case iss_t::XTN_ICACHE_PREFETCH: 2715 case iss_t::XTN_DCACHE_PREFETCH: 2716 m_drsp.valid 2717 r_dcache_fsm 2695 case iss_t::XTN_ICACHE_PREFETCH: // not implemented : no action 2696 case iss_t::XTN_DCACHE_PREFETCH: // not implemented : no action 2697 m_drsp.valid = true; 2698 r_dcache_fsm = DCACHE_IDLE; 2718 2699 break; 2719 2700 … … 2739 2720 else 2740 2721 { 2741 bool 2742 bool 2743 2744 if ( not (r_mmu_mode.read() & DATA_TLB_MASK) )// dtlb not activated2745 { 2746 valid_req 2747 2748 if ( not (r_mmu_mode.read() & DATA_CACHE_MASK)) cacheable = false;2722 bool valid_req; 2723 bool cacheable; 2724 2725 if (not (r_mmu_mode.read() & DATA_TLB_MASK)) // dtlb not activated 2726 { 2727 valid_req = true; 2728 2729 if (not (r_mmu_mode.read() & DATA_CACHE_MASK)) cacheable = false; 2749 2730 else cacheable = m_cacheability_table[(uint64_t)m_dreq.addr]; 2750 2731 } 2751 else 2752 { 2753 if ( tlb_hit )// tlb hit2732 else // dtlb activated 2733 { 2734 if (tlb_hit) // tlb hit 2754 2735 { 2755 2736 // cacheability 2756 if ( not (r_mmu_mode.read() & DATA_CACHE_MASK)) cacheable = false;2737 if (not (r_mmu_mode.read() & DATA_CACHE_MASK)) cacheable = false; 2757 2738 else cacheable = tlb_flags.c; 2739 2758 2740 // access rights checking 2759 if ( 2741 if (not tlb_flags.u and (m_dreq.mode == iss_t::MODE_USER)) 2760 2742 { 2761 if ( 2762 (m_dreq.type == iss_t::DATA_LL))2743 if ((m_dreq.type == iss_t::DATA_READ) or 2744 (m_dreq.type == iss_t::DATA_LL)) 2763 2745 { 2764 2746 r_mmu_detr = MMU_READ_PRIVILEGE_VIOLATION; … … 2774 2756 m_drsp.rdata = 0; 2775 2757 #if DEBUG_DCACHE 2776 if ( m_debug_activated ) 2777 std::cout << " <PROC " << name() << " DCACHE_IDLE>" 2778 << " HIT in dtlb, but privilege violation" << std::endl; 2758 if (m_debug_activated) 2759 { 2760 std::cout << " <PROC " << name() << " DCACHE_IDLE>" 2761 << " HIT in dtlb, but privilege violation" << std::endl; 2762 } 2779 2763 #endif 2780 2764 } 2781 else if ( 2765 else if (not tlb_flags.w and 2782 2766 ((m_dreq.type == iss_t::DATA_WRITE) or 2783 (m_dreq.type == iss_t::DATA_SC)) 2767 (m_dreq.type == iss_t::DATA_SC))) 2784 2768 { 2785 2769 r_mmu_detr = MMU_WRITE_ACCES_VIOLATION; … … 2790 2774 m_drsp.rdata = 0; 2791 2775 #if DEBUG_DCACHE 2792 if ( m_debug_activated ) 2793 std::cout << " <PROC " << name() << " DCACHE_IDLE>" 2794 << " HIT in dtlb, but writable violation" << std::endl; 2776 if (m_debug_activated) 2777 { 2778 std::cout << " <PROC " << name() << " DCACHE_IDLE>" 2779 << " HIT in dtlb, but writable violation" << std::endl; 2780 } 2795 2781 #endif 2796 2782 } 2797 2783 else 2798 2784 { 2799 valid_req 2785 valid_req = true; 2800 2786 } 2801 2787 } 2802 else 2788 else // tlb miss 2803 2789 { 2804 valid_req 2805 r_dcache_tlb_vaddr 2806 r_dcache_tlb_ins 2807 r_dcache_fsm 2790 valid_req = false; 2791 r_dcache_tlb_vaddr = m_dreq.addr; 2792 r_dcache_tlb_ins = false; 2793 r_dcache_fsm = DCACHE_TLB_MISS; 2808 2794 } 2809 2795 } // end DTLB activated 2810 2796 2811 if ( valid_req )// processor request is valid (after MMU check)2797 if (valid_req) // processor request is valid (after MMU check) 2812 2798 { 2813 2799 // READ request … … 2815 2801 // We request a VCI transaction to CMD FSM if miss or uncachable 2816 2802 2817 if ( 2818 and not r_dcache_updt_req.read() 2803 if (((m_dreq.type == iss_t::DATA_READ)) 2804 and not r_dcache_updt_req.read()) 2819 2805 { 2820 if ( cacheable )// cacheable read2806 if (cacheable) // cacheable read 2821 2807 { 2822 if ( cache_state == CACHE_SLOT_STATE_EMPTY) // cache miss2808 if (cache_state == CACHE_SLOT_STATE_EMPTY) // cache miss 2823 2809 { 2824 2810 #ifdef INSTRUMENTATION 2825 m_cpt_data_miss++;2811 m_cpt_dcache_miss++; 2826 2812 #endif 2827 2813 // request a VCI DMISS transaction … … 2831 2817 r_dcache_fsm = DCACHE_MISS_SELECT; 2832 2818 #if DEBUG_DCACHE 2833 if ( m_debug_activated ) 2834 std::cout << " <PROC " << name() << " DCACHE_IDLE>" 2835 << " READ MISS in dcache" 2836 << " / PADDR = " << std::hex << paddr << std::endl; 2819 if (m_debug_activated) 2820 { 2821 std::cout << " <PROC " << name() << " DCACHE_IDLE>" 2822 << " READ MISS in dcache" 2823 << " / PADDR = " << std::hex << paddr << std::endl; 2824 } 2837 2825 #endif 2838 2826 } 2839 else if (cache_state == CACHE_SLOT_STATE_ZOMBI 2827 else if (cache_state == CACHE_SLOT_STATE_ZOMBI) // pending cleanup 2840 2828 { 2841 2829 // stalled until cleanup is acknowledged 2842 2830 r_dcache_fsm = DCACHE_IDLE; 2843 2831 #if DEBUG_DCACHE 2844 if ( m_debug_activated ) 2845 std::cout << " <PROC " << name() << " DCACHE_IDLE>" 2846 << " Pending cleanup, stalled until cleanup acknowledge" 2847 << " / PADDR = " << std::hex << paddr << std::endl; 2832 if (m_debug_activated) 2833 { 2834 std::cout << " <PROC " << name() << " DCACHE_IDLE>" 2835 << " Pending cleanup, stalled until cleanup acknowledge" 2836 << " / PADDR = " << std::hex << paddr << std::endl; 2837 } 2848 2838 #endif 2849 2839 } … … 2851 2841 { 2852 2842 #ifdef INSTRUMENTATION 2853 m_cpt_data_read++;2843 m_cpt_data_read++; 2854 2844 #endif 2855 2845 // returns data to processor 2856 m_drsp.valid 2857 m_drsp.error 2858 m_drsp.rdata 2846 m_drsp.valid = true; 2847 m_drsp.error = false; 2848 m_drsp.rdata = cache_rdata; 2859 2849 #if DEBUG_DCACHE 2860 if ( m_debug_activated ) 2861 std::cout << " <PROC " << name() << " DCACHE_IDLE>" 2862 << " READ HIT in dcache" 2863 << " : PADDR = " << std::hex << paddr 2864 << " / DATA = " << std::hex << cache_rdata << std::dec << std::endl; 2850 if (m_debug_activated) 2851 { 2852 std::cout << " <PROC " << name() << " DCACHE_IDLE>" 2853 << " READ HIT in dcache" 2854 << " : PADDR = " << std::hex << paddr 2855 << " / DATA = " << std::hex << cache_rdata << std::dec << std::endl; 2856 } 2865 2857 #endif 2866 2858 } 2867 2859 } 2868 else 2860 else // uncacheable read 2869 2861 { 2870 r_dcache_vci_paddr 2871 r_dcache_vci_unc_be 2872 r_dcache_vci_unc_write 2873 r_dcache_vci_unc_req 2874 r_dcache_fsm 2862 r_dcache_vci_paddr = paddr; 2863 r_dcache_vci_unc_be = m_dreq.be; 2864 r_dcache_vci_unc_write = false; 2865 r_dcache_vci_unc_req = true; 2866 r_dcache_fsm = DCACHE_UNC_WAIT; 2875 2867 #if DEBUG_DCACHE 2876 if ( m_debug_activated ) 2877 std::cout << " <PROC " << name() << " DCACHE_IDLE>" 2878 << " READ UNCACHEABLE in dcache" 2879 << " / PADDR = " << std::hex << paddr << std::endl; 2868 if (m_debug_activated) 2869 { 2870 std::cout << " <PROC " << name() << " DCACHE_IDLE>" 2871 << " READ UNCACHEABLE in dcache" 2872 << " / PADDR = " << std::hex << paddr << std::endl; 2873 } 2880 2874 #endif 2881 2875 } … … 2908 2902 // physical address) are registered in r_dcache_save registers, 2909 2903 // and the write will be done in the P1 pipeline stage. 2910 else if ( m_dreq.type == iss_t::DATA_WRITE)2904 else if (m_dreq.type == iss_t::DATA_WRITE) 2911 2905 { 2912 if ( (r_mmu_mode.read() & DATA_TLB_MASK)2913 and not tlb_flags.d )// Dirty bit must be set2906 if ((r_mmu_mode.read() & DATA_TLB_MASK) 2907 and not tlb_flags.d) // Dirty bit must be set 2914 2908 { 2915 2909 // The PTE physical address is obtained from the nline value (dtlb), 2916 2910 // and from the virtual address (word index) 2917 if ( tlb_flags.b )// PTE12911 if (tlb_flags.b) // PTE1 2918 2912 { 2919 r_dcache_dirty_paddr = (paddr_t) (tlb_nline*(m_dcache_words<<2)) |2920 (paddr_t) ((m_dreq.addr>>19) & 0x3c);2913 r_dcache_dirty_paddr = (paddr_t) (tlb_nline * (m_dcache_words << 2)) | 2914 (paddr_t) ((m_dreq.addr >> 19) & 0x3c); 2921 2915 } 2922 else 2916 else // PTE2 2923 2917 { 2924 r_dcache_dirty_paddr = (paddr_t) (tlb_nline*(m_dcache_words<<2)) |2925 (paddr_t) ((m_dreq.addr>>9) & 0x38);2918 r_dcache_dirty_paddr = (paddr_t) (tlb_nline * (m_dcache_words << 2)) | 2919 (paddr_t) ((m_dreq.addr >> 9) & 0x38); 2926 2920 } 2927 r_dcache_fsm 2921 r_dcache_fsm = DCACHE_DIRTY_GET_PTE; 2928 2922 } 2929 else 2923 else // Write request accepted 2930 2924 { 2931 2925 #ifdef INSTRUMENTATION 2932 m_cpt_data_write++;2926 m_cpt_data_write++; 2933 2927 #endif 2934 2928 // cleaning llsc buffer if address matching 2935 if ( paddr == r_dcache_llsc_paddr.read())2929 if (paddr == r_dcache_llsc_paddr.read()) 2936 2930 r_dcache_llsc_valid = false; 2937 2931 2938 if (not cacheable) 2932 if (not cacheable) // uncacheable write 2939 2933 { 2940 r_dcache_vci_paddr 2941 r_dcache_vci_wdata 2942 r_dcache_vci_unc_write 2943 r_dcache_vci_unc_be 2944 r_dcache_vci_unc_req 2945 r_dcache_fsm 2934 r_dcache_vci_paddr = paddr; 2935 r_dcache_vci_wdata = m_dreq.wdata; 2936 r_dcache_vci_unc_write = true; 2937 r_dcache_vci_unc_be = m_dreq.be; 2938 r_dcache_vci_unc_req = true; 2939 r_dcache_fsm = DCACHE_UNC_WAIT; 2946 2940 } 2947 2941 // activating P1 stage 2948 else if( (cache_state != CACHE_SLOT_STATE_ZOMBI) && (cache_state != CACHE_SLOT_STATE_EMPTY) ) 2942 else if ((cache_state != CACHE_SLOT_STATE_ZOMBI) and 2943 (cache_state != CACHE_SLOT_STATE_EMPTY)) 2949 2944 { 2950 wbuf_request = (cache_state == CACHE_SLOT_STATE_VALID_CC); //write to L2 only if CC2945 wbuf_request = (cache_state == CACHE_SLOT_STATE_VALID_CC); 2951 2946 updt_request = true; 2952 2947 m_drsp.valid = true; 2953 if ( cache_state == CACHE_SLOT_STATE_VALID_NCC)2948 if (cache_state == CACHE_SLOT_STATE_VALID_NCC) 2954 2949 { 2955 if ( r_dcache_content_state[cache_way*m_dcache_sets+cache_set] == LINE_CACHE_DATA_NOT_DIRTY)2950 if (r_dcache_content_state[cache_way * m_dcache_sets + cache_set] == LINE_CACHE_DATA_NOT_DIRTY) 2956 2951 { 2957 r_dcache_content_state[cache_way *m_dcache_sets+cache_set] = LINE_CACHE_DATA_DIRTY;2952 r_dcache_content_state[cache_way * m_dcache_sets + cache_set] = LINE_CACHE_DATA_DIRTY; 2958 2953 } 2959 // dirty bit with word granularity (only for stats)2960 r_dcache_dirty_word[(cache_way *m_dcache_sets +cache_set)*m_dcache_words+cache_word] = 1;2954 // dirty bit with word granularity (only for stats) 2955 r_dcache_dirty_word[(cache_way * m_dcache_sets + cache_set) * m_dcache_words + cache_word] = 1; 2961 2956 m_cpt_data_write_back ++; 2962 2957 } … … 2971 2966 // cleanup and therefore overwrite the new value of 2972 2967 // writing that is more current than the data 2973 // contained in the cleanup 2968 // contained in the cleanup. 2974 2969 // TODO : MAYBE NEED TO OPTIMIZE 2975 else if ( cache_state == CACHE_SLOT_STATE_ZOMBI)2970 else if (cache_state == CACHE_SLOT_STATE_ZOMBI) 2976 2971 { 2977 2972 m_drsp.valid = false; 2978 2973 r_dcache_fsm = DCACHE_IDLE; 2979 2974 // STAT : WRITE ON ZOMBI NCC LINE 2980 if (r_dcache_zombi_ncc[cache_way *m_dcache_sets+cache_set] == true)2975 if (r_dcache_zombi_ncc[cache_way * m_dcache_sets + cache_set] == true) 2981 2976 { 2982 2977 m_cpt_data_write_on_zombi_ncc++; 2983 2978 } 2984 2985 2979 m_cpt_data_write_on_zombi++; 2986 2980 } … … 2994 2988 } 2995 2989 #if DEBUG_DCACHE 2996 if ( m_debug_activated ) 2997 std::cout << " <PROC " << name() << " DCACHE_IDLE>" 2998 << " WRITE REQ " 2999 << " / wbuf_request = " << wbuf_request 3000 << " / updt_request = " << updt_request 3001 << " / cache_state = " << cache_state 3002 << " / PADDR = " << std::hex << paddr << std::endl; 3003 #endif 3004 2990 if (m_debug_activated) 2991 { 2992 std::cout << " <PROC " << name() << " DCACHE_IDLE>" 2993 << " WRITE REQ " 2994 << " / wbuf_request = " << wbuf_request 2995 << " / updt_request = " << updt_request 2996 << " / cache_state = " << cache_state 2997 << " / PADDR = " << std::hex << paddr << std::dec << std::endl; 2998 } 2999 #endif 3005 3000 } // end WRITE 3006 3001 … … 3015 3010 // We don't check a possible write hit in dcache, as the cache update 3016 3011 // is done by the coherence transaction induced by the SC... 3017 else if ( m_dreq.type == iss_t::DATA_SC)3012 else if (m_dreq.type == iss_t::DATA_SC) 3018 3013 { 3019 if ( (r_mmu_mode.read() & DATA_TLB_MASK)3020 and not tlb_flags.d )// Dirty bit must be set3014 if ((r_mmu_mode.read() & DATA_TLB_MASK) 3015 and not tlb_flags.d) // Dirty bit must be set 3021 3016 { 3022 3017 // The PTE physical address is obtained from the nline value (dtlb), 3023 3018 // and the word index (virtual address) 3024 if ( tlb_flags.b )// PTE13019 if (tlb_flags.b) // PTE1 3025 3020 { 3026 r_dcache_dirty_paddr = (paddr_t) (tlb_nline*(m_dcache_words<<2)) |3027 (paddr_t) ((m_dreq.addr>>19) & 0x3c);3021 r_dcache_dirty_paddr = (paddr_t) (tlb_nline * (m_dcache_words << 2)) | 3022 (paddr_t) ((m_dreq.addr >> 19) & 0x3c); 3028 3023 } 3029 else 3024 else // PTE2 3030 3025 { 3031 r_dcache_dirty_paddr = (paddr_t) (tlb_nline*(m_dcache_words<<2)) |3032 (paddr_t) ((m_dreq.addr>>9) & 0x38);3026 r_dcache_dirty_paddr = (paddr_t) (tlb_nline * (m_dcache_words << 2)) | 3027 (paddr_t) ((m_dreq.addr >> 9) & 0x38); 3033 3028 } 3034 r_dcache_fsm 3029 r_dcache_fsm = DCACHE_DIRTY_GET_PTE; 3035 3030 m_drsp.valid = false; 3036 3031 m_drsp.error = false; 3037 3032 m_drsp.rdata = 0; 3038 3033 } 3039 else 3034 else // SC request accepted 3040 3035 { 3041 3036 #ifdef INSTRUMENTATION 3042 m_cpt_data_sc++;3037 m_cpt_data_sc++; 3043 3038 #endif 3044 3039 // checking local success 3045 if (r_dcache_llsc_valid.read() and3046 (r_dcache_llsc_paddr.read() == paddr) )// local success3040 if (r_dcache_llsc_valid.read() and 3041 (r_dcache_llsc_paddr.read() == paddr)) // local success 3047 3042 { 3048 3043 // request an SC CMD and go to DCACHE_SC_WAIT state … … 3052 3047 r_dcache_fsm = DCACHE_SC_WAIT; 3053 3048 } 3054 else 3049 else // local fail 3055 3050 { 3056 3051 m_drsp.valid = true; … … 3065 3060 3066 3061 // itlb miss request 3067 else if ( r_icache_tlb_miss_req.read() and not wbuf_write_miss)3062 else if (r_icache_tlb_miss_req.read() and not wbuf_write_miss) 3068 3063 { 3069 3064 r_dcache_tlb_ins = true; … … 3091 3086 // r_mmu_ins_* or r_mmu_data* error reporting registers. 3092 3087 { 3093 uint32_t 3094 bool 3095 paddr_t 3088 uint32_t ptba = 0; 3089 bool bypass; 3090 paddr_t pte_paddr; 3096 3091 3097 3092 // evaluate bypass in order to skip first level page table access 3098 if ( r_dcache_tlb_ins.read() )// itlb miss3093 if (r_dcache_tlb_ins.read()) // itlb miss 3099 3094 { 3100 3095 bypass = r_itlb.get_bypass(r_dcache_tlb_vaddr.read(), &ptba); 3101 3096 } 3102 else 3097 else // dtlb miss 3103 3098 { 3104 3099 bypass = r_dtlb.get_bypass(r_dcache_tlb_vaddr.read(), &ptba); 3105 3100 } 3106 3101 3107 if ( not bypass )// Try to read PTE1/PTD1 in dcache3108 { 3109 pte_paddr = (((paddr_t) r_mmu_ptpr.read()) << (INDEX1_NBITS+2)) |3110 ((((paddr_t)r_dcache_tlb_vaddr.read()) >> PAGE_M_NBITS) << 2);3102 if (not bypass) // Try to read PTE1/PTD1 in dcache 3103 { 3104 pte_paddr = (((paddr_t) r_mmu_ptpr.read()) << (INDEX1_NBITS + 2)) | 3105 ((((paddr_t) r_dcache_tlb_vaddr.read()) >> PAGE_M_NBITS) << 2); 3111 3106 r_dcache_tlb_paddr = pte_paddr; 3112 3107 r_dcache_fsm = DCACHE_TLB_PTE1_GET; 3113 3108 } 3114 else 3115 { 3116 pte_paddr = (paddr_t) ptba << PAGE_K_NBITS |3117 (paddr_t) (r_dcache_tlb_vaddr.read()&PTD_ID2_MASK)>>(PAGE_K_NBITS-3);3109 else // Try to read PTE2 in dcache 3110 { 3111 pte_paddr = (paddr_t) ptba << PAGE_K_NBITS | 3112 (paddr_t) (r_dcache_tlb_vaddr.read() & PTD_ID2_MASK) >> (PAGE_K_NBITS - 3); 3118 3113 r_dcache_tlb_paddr = pte_paddr; 3119 3114 r_dcache_fsm = DCACHE_TLB_PTE2_GET; … … 3121 3116 3122 3117 #if DEBUG_DCACHE 3123 if ( m_debug_activated)3124 {3125 if ( r_dcache_tlb_ins.read())3126 std::cout << " <PROC " << name() << " DCACHE_TLB_MISS> ITLB miss";3127 else3128 std::cout << " <PROC " << name() << " DCACHE_TLB_MISS> DTLB miss";3129 std::cout << " / VADDR = " << std::hex << r_dcache_tlb_vaddr.read()3130 << " / ptpr = " << (((paddr_t)r_mmu_ptpr.read()) << (INDEX1_NBITS+2))3131 << " / BYPASS = " << bypass3132 << " / PTE_ADR = " << pte_paddr << std::endl;3133 }3118 if (m_debug_activated) 3119 { 3120 if (r_dcache_tlb_ins.read()) 3121 std::cout << " <PROC " << name() << " DCACHE_TLB_MISS> ITLB miss"; 3122 else 3123 std::cout << " <PROC " << name() << " DCACHE_TLB_MISS> DTLB miss"; 3124 std::cout << " / VADDR = " << std::hex << r_dcache_tlb_vaddr.read() 3125 << " / ptpr = " << (((paddr_t) r_mmu_ptpr.read()) << (INDEX1_NBITS + 2)) 3126 << " / BYPASS = " << bypass 3127 << " / PTE_ADR = " << pte_paddr << std::endl; 3128 } 3134 3129 #endif 3135 3130 … … 3137 3132 } 3138 3133 ///////////////////////// 3139 case DCACHE_TLB_PTE1_GET: 3134 case DCACHE_TLB_PTE1_GET: // try to read a PT1 entry in dcache 3140 3135 { 3141 3136 // coherence clack request (from DSPIN CLACK) 3142 if ( r_dcache_clack_req.read())3137 if (r_dcache_clack_req.read()) 3143 3138 { 3144 3139 r_dcache_fsm = DCACHE_CC_CHECK; … … 3148 3143 3149 3144 // coherence request (from CC_RECEIVE FSM) 3150 if ( 3145 if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 3151 3146 { 3152 3147 r_dcache_fsm = DCACHE_CC_CHECK; … … 3155 3150 } 3156 3151 3157 uint32_t entry; 3158 size_t way; 3159 size_t set; 3160 size_t word; 3161 int cache_state; 3162 r_dcache.read( r_dcache_tlb_paddr.read(), 3163 &entry, 3164 &way, 3165 &set, 3166 &word, 3167 &cache_state ); 3168 3152 uint32_t entry; 3153 size_t way; 3154 size_t set; 3155 size_t word; 3156 int cache_state; 3157 r_dcache.read(r_dcache_tlb_paddr.read(), 3158 &entry, 3159 &way, 3160 &set, 3161 &word, 3162 &cache_state); 3169 3163 #ifdef INSTRUMENTATION 3170 m_cpt_dcache_data_read++;3171 m_cpt_dcache_dir_read++;3172 #endif 3173 3174 if (( cache_state == CACHE_SLOT_STATE_VALID_NCC ) or ( cache_state == CACHE_SLOT_STATE_VALID_CC))3175 { 3176 if ( not (entry & PTE_V_MASK)) // unmapped3177 { 3178 if ( r_dcache_tlb_ins.read())3164 m_cpt_dcache_data_read++; 3165 m_cpt_dcache_dir_read++; 3166 #endif 3167 if ((cache_state == CACHE_SLOT_STATE_VALID_NCC) or 3168 (cache_state == CACHE_SLOT_STATE_VALID_CC)) 3169 { 3170 if (not (entry & PTE_V_MASK)) // unmapped 3171 { 3172 if (r_dcache_tlb_ins.read()) 3179 3173 { 3180 3174 r_mmu_ietr = MMU_READ_PT1_UNMAPPED; … … 3185 3179 else 3186 3180 { 3187 r_mmu_detr 3188 r_mmu_dbvar 3189 m_drsp.valid 3190 m_drsp.error 3191 } 3192 r_dcache_fsm 3181 r_mmu_detr = MMU_READ_PT1_UNMAPPED; 3182 r_mmu_dbvar = r_dcache_tlb_vaddr.read(); 3183 m_drsp.valid = true; 3184 m_drsp.error = true; 3185 } 3186 r_dcache_fsm = DCACHE_IDLE; 3193 3187 3194 3188 #if DEBUG_DCACHE 3195 if ( m_debug_activated)3196 {3197 std::cout << " <PROC " << name()3198 << " DCACHE_TLB_PTE1_GET> HIT in dcache, but unmapped"3199 << std::hex << " / paddr = " << r_dcache_tlb_paddr.read()3200 << std::dec << " / way = " << way3201 << std::dec << " / set = " << set3202 << std::dec << " / word = " << word3203 << std::hex << " / PTE1 = " << entry << std::endl;3204 }3205 #endif 3206 3207 } 3208 else if ( entry & PTE_T_MASK )// PTD : me must access PT23189 if (m_debug_activated) 3190 { 3191 std::cout << " <PROC " << name() 3192 << " DCACHE_TLB_PTE1_GET> HIT in dcache, but unmapped" 3193 << std::hex << " / paddr = " << r_dcache_tlb_paddr.read() 3194 << std::dec << " / way = " << way 3195 << std::dec << " / set = " << set 3196 << std::dec << " / word = " << word 3197 << std::hex << " / PTE1 = " << entry << std::endl; 3198 } 3199 #endif 3200 3201 } 3202 else if (entry & PTE_T_MASK) // PTD : me must access PT2 3209 3203 { 3210 3204 // mark the cache line ac containing a PTD 3211 r_dcache_content_state[way *m_dcache_sets+set] = LINE_CACHE_CONTAINS_PTD;3205 r_dcache_content_state[way * m_dcache_sets + set] = LINE_CACHE_CONTAINS_PTD; 3212 3206 3213 3207 // register bypass 3214 if ( r_dcache_tlb_ins.read() )// itlb3208 if (r_dcache_tlb_ins.read()) // itlb 3215 3209 { 3216 3210 r_itlb.set_bypass(r_dcache_tlb_vaddr.read(), 3217 entry & ((1 << (m_paddr_nbits -PAGE_K_NBITS)) - 1),3218 r_dcache_tlb_paddr.read() / (m_icache_words <<2));3219 } 3220 else 3211 entry & ((1 << (m_paddr_nbits - PAGE_K_NBITS)) - 1), 3212 r_dcache_tlb_paddr.read() / (m_icache_words << 2)); 3213 } 3214 else // dtlb 3221 3215 { 3222 3216 r_dtlb.set_bypass(r_dcache_tlb_vaddr.read(), 3223 entry & ((1 << (m_paddr_nbits -PAGE_K_NBITS)) - 1),3224 r_dcache_tlb_paddr.read() / (m_dcache_words <<2));3217 entry & ((1 << (m_paddr_nbits - PAGE_K_NBITS)) - 1), 3218 r_dcache_tlb_paddr.read() / (m_dcache_words << 2)); 3225 3219 } 3226 3220 r_dcache_tlb_paddr = 3227 (paddr_t) (entry & ((1<<(m_paddr_nbits-PAGE_K_NBITS))-1)) << PAGE_K_NBITS |3228 (paddr_t) (((r_dcache_tlb_vaddr.read() & PTD_ID2_MASK) >> PAGE_K_NBITS) << 3);3229 r_dcache_fsm 3221 (paddr_t) (entry & ((1 << (m_paddr_nbits - PAGE_K_NBITS)) - 1)) << PAGE_K_NBITS | 3222 (paddr_t) (((r_dcache_tlb_vaddr.read() & PTD_ID2_MASK) >> PAGE_K_NBITS) << 3); 3223 r_dcache_fsm = DCACHE_TLB_PTE2_GET; 3230 3224 3231 3225 #if DEBUG_DCACHE 3232 if ( m_debug_activated)3233 {3234 std::cout << " <PROC " << name()3235 << " DCACHE_TLB_PTE1_GET> HIT in dcache"3236 << std::hex << " / paddr = " << r_dcache_tlb_paddr.read()3237 << std::dec << " / way = " << way3238 << std::dec << " / set = " << set3239 << std::dec << " / word = " << word3240 << std::hex << " / PTD = " << entry << std::endl;3241 }3242 #endif 3243 } 3244 else 3245 { 3246 r_dcache_content_state[m_ icache_sets*way+set] = LINE_CACHE_IN_TLB;3226 if (m_debug_activated) 3227 { 3228 std::cout << " <PROC " << name() 3229 << " DCACHE_TLB_PTE1_GET> HIT in dcache" 3230 << std::hex << " / paddr = " << r_dcache_tlb_paddr.read() 3231 << std::dec << " / way = " << way 3232 << std::dec << " / set = " << set 3233 << std::dec << " / word = " << word 3234 << std::hex << " / PTD = " << entry << std::endl; 3235 } 3236 #endif 3237 } 3238 else // PTE1 : we must update the TLB 3239 { 3240 r_dcache_content_state[m_dcache_sets * way + set] = LINE_CACHE_IN_TLB; 3247 3241 r_dcache_tlb_pte_flags = entry; 3248 3242 r_dcache_fsm = DCACHE_TLB_PTE1_SELECT; 3249 3243 3250 r_cas_islocal = (cache_state == CACHE_SLOT_STATE_VALID_NCC); //do not check L2 if NCC: the CAS is necessarily a success3244 r_cas_islocal = (cache_state == CACHE_SLOT_STATE_VALID_NCC); // do not check L2 if NCC: the CAS is necessarily a success 3251 3245 r_cas_local_way = way; 3252 3246 r_cas_local_set = set; … … 3254 3248 3255 3249 #if DEBUG_DCACHE 3256 if ( m_debug_activated)3257 {3258 std::cout << " <PROC " << name()3259 << " DCACHE_TLB_PTE1_GET> HIT in dcache"3260 << std::hex << " / paddr = " << r_dcache_tlb_paddr.read()3261 << std::dec << " / way = " << way3262 << std::dec << " / set = " << set3263 << std::dec << " / word = " << word3264 << std::hex << " / PTE1 = " << entry << std::endl;3265 }3266 #endif 3267 } 3268 } 3269 else if ( cache_state == CACHE_SLOT_STATE_ZOMBI) // pending cleanup3250 if (m_debug_activated) 3251 { 3252 std::cout << " <PROC " << name() 3253 << " DCACHE_TLB_PTE1_GET> HIT in dcache" 3254 << std::hex << " / paddr = " << r_dcache_tlb_paddr.read() 3255 << std::dec << " / way = " << way 3256 << std::dec << " / set = " << set 3257 << std::dec << " / word = " << word 3258 << std::hex << " / PTE1 = " << entry << std::endl; 3259 } 3260 #endif 3261 } 3262 } 3263 else if (cache_state == CACHE_SLOT_STATE_ZOMBI) // pending cleanup 3270 3264 { 3271 3265 // stalled until cleanup is acknowledged 3272 r_dcache_fsm 3273 } 3274 else 3275 { 3276 r_dcache_vci_miss_req 3277 r_dcache_vci_paddr 3278 r_dcache_save_paddr 3279 r_dcache_miss_type 3280 r_dcache_fsm 3266 r_dcache_fsm = DCACHE_TLB_PTE1_GET; 3267 } 3268 else // we must load the missing cache line in dcache 3269 { 3270 r_dcache_vci_miss_req = true; 3271 r_dcache_vci_paddr = r_dcache_tlb_paddr.read(); 3272 r_dcache_save_paddr = r_dcache_tlb_paddr.read(); 3273 r_dcache_miss_type = PTE1_MISS; 3274 r_dcache_fsm = DCACHE_MISS_SELECT; 3281 3275 3282 3276 #if DEBUG_DCACHE 3283 if ( m_debug_activated)3284 {3285 std::cout << " <PROC " << name()3286 << " DCACHE_TLB_PTE1_GET> MISS in dcache:"3287 << " PTE1 address = " << std::hex << r_dcache_tlb_paddr.read() << std::endl;3288 }3277 if (m_debug_activated) 3278 { 3279 std::cout << " <PROC " << name() 3280 << " DCACHE_TLB_PTE1_GET> MISS in dcache:" 3281 << " PTE1 address = " << std::hex << r_dcache_tlb_paddr.read() << std::endl; 3282 } 3289 3283 #endif 3290 3284 } … … 3292 3286 } 3293 3287 //////////////////////////// 3294 case DCACHE_TLB_PTE1_SELECT: 3288 case DCACHE_TLB_PTE1_SELECT: // select a slot for PTE1 3295 3289 { 3296 3290 size_t way; 3297 3291 size_t set; 3298 3292 3299 if ( r_dcache_tlb_ins.read())3300 { 3301 r_itlb.select( 3302 3303 3304 &set);3293 if (r_dcache_tlb_ins.read()) 3294 { 3295 r_itlb.select(r_dcache_tlb_vaddr.read(), 3296 true, // PTE1 3297 &way, 3298 &set); 3305 3299 #ifdef INSTRUMENTATION 3306 m_cpt_ins_tlb_read++;3300 m_cpt_itlb_read++; 3307 3301 #endif 3308 3302 } 3309 3303 else 3310 3304 { 3311 r_dtlb.select( 3312 3313 3314 &set);3305 r_dtlb.select(r_dcache_tlb_vaddr.read(), 3306 true, // PTE1 3307 &way, 3308 &set); 3315 3309 #ifdef INSTRUMENTATION 3316 m_cpt_data_tlb_read++;3310 m_cpt_dtlb_read++; 3317 3311 #endif 3318 3312 } … … 3322 3316 3323 3317 #if DEBUG_DCACHE 3324 if ( m_debug_activated)3325 {3326 if ( r_dcache_tlb_ins.read())3327 std::cout << " <PROC " << name()3328 << " DCACHE_TLB_PTE1_SELECT> Select a slot in ITLB:";3329 else3330 std::cout << " <PROC " << name()3331 << ".DCACHE_TLB_PTE1_SELECT> Select a slot in DTLB:";3332 std::cout << " way = " << std::dec << way3333 3334 }3318 if (m_debug_activated) 3319 { 3320 if (r_dcache_tlb_ins.read()) 3321 std::cout << " <PROC " << name() 3322 << " DCACHE_TLB_PTE1_SELECT> Select a slot in ITLB:"; 3323 else 3324 std::cout << " <PROC " << name() 3325 << ".DCACHE_TLB_PTE1_SELECT> Select a slot in DTLB:"; 3326 std::cout << " way = " << std::dec << way 3327 << " / set = " << set << std::endl; 3328 } 3335 3329 #endif 3336 3330 break; … … 3343 3337 // the coherence mechanism. 3344 3338 { 3345 paddr_t nline = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words)+2);3346 uint32_t pte= r_dcache_tlb_pte_flags.read();3347 bool 3348 bool 3339 paddr_t nline = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words) + 2); 3340 uint32_t pte = r_dcache_tlb_pte_flags.read(); 3341 bool pt_updt = false; 3342 bool local = true; 3349 3343 3350 3344 // We should compute the access locality: … … 3355 3349 // As long as this computation is not done, all access are local. 3356 3350 3357 if ( local )// local access3358 { 3359 if ( not ((pte & PTE_L_MASK) == PTE_L_MASK)) // we must set the L bit3351 if (local) // local access 3352 { 3353 if (not ((pte & PTE_L_MASK) == PTE_L_MASK)) // we must set the L bit 3360 3354 { 3361 3355 pt_updt = true; 3362 r_dcache_vci_cas_old 3363 r_dcache_vci_cas_new 3356 r_dcache_vci_cas_old = pte; 3357 r_dcache_vci_cas_new = pte | PTE_L_MASK; 3364 3358 pte = pte | PTE_L_MASK; 3365 3359 r_dcache_tlb_pte_flags = pte; 3366 3360 } 3367 3361 } 3368 else 3369 { 3370 if ( not ((pte & PTE_R_MASK) == PTE_R_MASK)) // we must set the R bit3362 else // remote access 3363 { 3364 if (not ((pte & PTE_R_MASK) == PTE_R_MASK)) // we must set the R bit 3371 3365 { 3372 3366 pt_updt = true; 3373 r_dcache_vci_cas_old 3374 r_dcache_vci_cas_new 3367 r_dcache_vci_cas_old = pte; 3368 r_dcache_vci_cas_new = pte | PTE_R_MASK; 3375 3369 pte = pte | PTE_R_MASK; 3376 3370 r_dcache_tlb_pte_flags = pte; … … 3378 3372 } 3379 3373 3380 if ( not pt_updt )// update TLB and return3381 { 3382 if ( r_dcache_tlb_ins.read())3383 { 3384 r_itlb.write( true,// 2M page3385 3386 0,// argument unused for a PTE13387 3388 3389 3390 nline);3374 if (not pt_updt) // update TLB and return 3375 { 3376 if (r_dcache_tlb_ins.read()) 3377 { 3378 r_itlb.write(true, // 2M page 3379 pte, 3380 0, // argument unused for a PTE1 3381 r_dcache_tlb_vaddr.read(), 3382 r_dcache_tlb_way.read(), 3383 r_dcache_tlb_set.read(), 3384 nline); 3391 3385 #ifdef INSTRUMENTATION 3392 m_cpt_ins_tlb_update_acc++;3386 m_cpt_itlb_write++; 3393 3387 #endif 3394 3388 3395 3389 #if DEBUG_DCACHE 3396 if ( m_debug_activated)3397 {3398 std::cout << " <PROC " << name()3399 << " DCACHE_TLB_PTE1_UPDT> write PTE1 in ITLB"3400 << " / set = " << std::dec << r_dcache_tlb_set.read()3401 << " / way = " << r_dcache_tlb_way.read() << std::endl;3402 r_itlb.printTrace();3403 }3390 if (m_debug_activated) 3391 { 3392 std::cout << " <PROC " << name() 3393 << " DCACHE_TLB_PTE1_UPDT> write PTE1 in ITLB" 3394 << " / set = " << std::dec << r_dcache_tlb_set.read() 3395 << " / way = " << r_dcache_tlb_way.read() << std::endl; 3396 r_itlb.printTrace(); 3397 } 3404 3398 #endif 3405 3399 } 3406 3400 else 3407 3401 { 3408 r_dtlb.write( true,// 2M page3409 3410 0,// argument unused for a PTE13411 3412 3413 3414 nline);3402 r_dtlb.write(true, // 2M page 3403 pte, 3404 0, // argument unused for a PTE1 3405 r_dcache_tlb_vaddr.read(), 3406 r_dcache_tlb_way.read(), 3407 r_dcache_tlb_set.read(), 3408 nline); 3415 3409 #ifdef INSTRUMENTATION 3416 m_cpt_data_tlb_update_acc++;3410 m_cpt_dtlb_write++; 3417 3411 #endif 3418 3412 3419 3413 #if DEBUG_DCACHE 3420 if ( m_debug_activated)3421 {3422 std::cout << " <PROC " << name()3423 << " DCACHE_TLB_PTE1_UPDT> write PTE1 in DTLB"3424 << " / set = " << std::dec << r_dcache_tlb_set.read()3425 << " / way = " << r_dcache_tlb_way.read() << std::endl;3426 r_dtlb.printTrace();3427 }3414 if (m_debug_activated) 3415 { 3416 std::cout << " <PROC " << name() 3417 << " DCACHE_TLB_PTE1_UPDT> write PTE1 in DTLB" 3418 << " / set = " << std::dec << r_dcache_tlb_set.read() 3419 << " / way = " << r_dcache_tlb_way.read() << std::endl; 3420 r_dtlb.printTrace(); 3421 } 3428 3422 #endif 3429 3423 } … … 3435 3429 3436 3430 #if DEBUG_DCACHE 3437 if ( m_debug_activated)3438 {3439 std::cout << " <PROC " << name()3440 << " DCACHE_TLB_PTE1_UPDT> L/R bit update required"3441 << std::endl;3442 }3431 if (m_debug_activated) 3432 { 3433 std::cout << " <PROC " << name() 3434 << " DCACHE_TLB_PTE1_UPDT> L/R bit update required" 3435 << std::endl; 3436 } 3443 3437 #endif 3444 3438 } … … 3446 3440 } 3447 3441 ///////////////////////// 3448 case DCACHE_TLB_PTE2_GET: 3442 case DCACHE_TLB_PTE2_GET: // Try to get a PTE2 (64 bits) in the dcache 3449 3443 { 3450 3444 // coherence clack request (from DSPIN CLACK) 3451 if ( r_dcache_clack_req.read())3445 if (r_dcache_clack_req.read()) 3452 3446 { 3453 3447 r_dcache_fsm = DCACHE_CC_CHECK; … … 3457 3451 3458 3452 // coherence request (from CC_RECEIVE FSM) 3459 if ( 3453 if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 3460 3454 { 3461 3455 r_dcache_fsm = DCACHE_CC_CHECK; … … 3464 3458 } 3465 3459 3466 uint32_t pte_flags= 0;3467 uint32_t pte_ppn= 0;3468 size_t way= 0;3469 size_t set= 0;3470 size_t word= 0;3471 int cache_state= 0;3472 3473 r_dcache.read( 3474 3475 3476 3477 3478 3479 &cache_state);3460 uint32_t pte_flags = 0; 3461 uint32_t pte_ppn = 0; 3462 size_t way = 0; 3463 size_t set = 0; 3464 size_t word = 0; 3465 int cache_state = 0; 3466 3467 r_dcache.read(r_dcache_tlb_paddr.read(), 3468 &pte_flags, 3469 &pte_ppn, 3470 &way, 3471 &set, 3472 &word, 3473 &cache_state); 3480 3474 #ifdef INSTRUMENTATION 3481 m_cpt_dcache_data_read++; 3482 m_cpt_dcache_dir_read++; 3483 #endif 3484 if ((cache_state == CACHE_SLOT_STATE_VALID_CC) or (cache_state == CACHE_SLOT_STATE_VALID_NCC)) 3485 { 3486 if ( not (pte_flags & PTE_V_MASK) ) // unmapped 3487 { 3488 if ( r_dcache_tlb_ins.read() ) 3475 m_cpt_dcache_data_read++; 3476 m_cpt_dcache_dir_read++; 3477 #endif 3478 if ((cache_state == CACHE_SLOT_STATE_VALID_CC) or 3479 (cache_state == CACHE_SLOT_STATE_VALID_NCC)) 3480 { 3481 if (not (pte_flags & PTE_V_MASK)) // unmapped 3482 { 3483 if (r_dcache_tlb_ins.read()) 3489 3484 { 3490 3485 r_mmu_ietr = MMU_READ_PT2_UNMAPPED; … … 3495 3490 else 3496 3491 { 3497 r_mmu_detr 3498 r_mmu_dbvar 3499 m_drsp.valid 3500 m_drsp.error 3501 } 3502 r_dcache_fsm 3492 r_mmu_detr = MMU_READ_PT2_UNMAPPED; 3493 r_mmu_dbvar = r_dcache_tlb_vaddr.read(); 3494 m_drsp.valid = true; 3495 m_drsp.error = true; 3496 } 3497 r_dcache_fsm = DCACHE_IDLE; 3503 3498 3504 3499 #if DEBUG_DCACHE 3505 if ( m_debug_activated)3506 {3507 std::cout << " <PROC " << name()3508 << " DCACHE_TLB_PTE2_GET> HIT in dcache, but PTE unmapped"3509 << " PTE_FLAGS = " << std::hex << pte_flags3510 << " PTE_PPN = " << std::hex << pte_ppn << std::endl;3511 }3512 #endif 3513 } 3514 else 3515 { 3516 r_dcache_content_state[m_dcache_sets *way+set] = LINE_CACHE_IN_TLB;3500 if (m_debug_activated) 3501 { 3502 std::cout << " <PROC " << name() 3503 << " DCACHE_TLB_PTE2_GET> HIT in dcache, but PTE unmapped" 3504 << " PTE_FLAGS = " << std::hex << pte_flags 3505 << " PTE_PPN = " << std::hex << pte_ppn << std::endl; 3506 } 3507 #endif 3508 } 3509 else // mapped : we must update the TLB 3510 { 3511 r_dcache_content_state[m_dcache_sets * way + set] = LINE_CACHE_IN_TLB; 3517 3512 r_dcache_tlb_pte_flags = pte_flags; 3518 3513 r_dcache_tlb_pte_ppn = pte_ppn; 3519 3514 r_dcache_fsm = DCACHE_TLB_PTE2_SELECT; 3520 3515 3521 r_cas_islocal = (cache_state == CACHE_SLOT_STATE_VALID_NCC); //do not check L2 if NCC: the CAS is necessarily a success3516 r_cas_islocal = (cache_state == CACHE_SLOT_STATE_VALID_NCC); // do not check L2 if NCC: the CAS is necessarily a success 3522 3517 r_cas_local_way = way; 3523 3518 r_cas_local_set = set; … … 3525 3520 3526 3521 #if DEBUG_DCACHE 3527 if ( m_debug_activated)3528 {3529 std::cout << " <PROC " << name()3530 << " DCACHE_TLB_PTE2_GET> HIT in dcache:"3531 << " PTE_FLAGS = " << std::hex << pte_flags3532 << " PTE_PPN = " << std::hex << pte_ppn << std::endl;3533 }3522 if (m_debug_activated) 3523 { 3524 std::cout << " <PROC " << name() 3525 << " DCACHE_TLB_PTE2_GET> HIT in dcache:" 3526 << " PTE_FLAGS = " << std::hex << pte_flags 3527 << " PTE_PPN = " << std::hex << pte_ppn << std::endl; 3528 } 3534 3529 #endif 3535 3530 } 3536 3531 } 3537 else if ( cache_state == CACHE_SLOT_STATE_ZOMBI) // pending cleanup3532 else if (cache_state == CACHE_SLOT_STATE_ZOMBI) // pending cleanup 3538 3533 { 3539 3534 // stalled until cleanup is acknowledged … … 3541 3536 3542 3537 #if DEBUG_DCACHE 3543 if ( m_debug_activated)3544 {3545 std::cout << " <PROC " << name()3546 << " DCACHE_TLB_PTE2_GET> ZOMBI in dcache: waiting cleanup ack"3547 << std::endl;3548 }3538 if (m_debug_activated) 3539 { 3540 std::cout << " <PROC " << name() 3541 << " DCACHE_TLB_PTE2_GET> ZOMBI in dcache: waiting cleanup ack" 3542 << std::endl; 3543 } 3549 3544 #endif 3550 3545 } … … 3558 3553 3559 3554 #if DEBUG_DCACHE 3560 if ( m_debug_activated)3561 {3562 std::cout << " <PROC " << name()3563 << " DCACHE_TLB_PTE2_GET> MISS in dcache:"3564 << " PTE address = " << std::hex << r_dcache_tlb_paddr.read() << std::endl;3565 }3555 if (m_debug_activated) 3556 { 3557 std::cout << " <PROC " << name() 3558 << " DCACHE_TLB_PTE2_GET> MISS in dcache:" 3559 << " PTE address = " << std::hex << r_dcache_tlb_paddr.read() << std::endl; 3560 } 3566 3561 #endif 3567 3562 } … … 3574 3569 size_t set; 3575 3570 3576 if ( r_dcache_tlb_ins.read())3577 { 3578 r_itlb.select( 3579 false,// PTE23580 3581 &set);3571 if (r_dcache_tlb_ins.read()) 3572 { 3573 r_itlb.select(r_dcache_tlb_vaddr.read(), 3574 false, // PTE2 3575 &way, 3576 &set); 3582 3577 #ifdef INSTRUMENTATION 3583 m_cpt_ins_tlb_read++;3578 m_cpt_itlb_read++; 3584 3579 #endif 3585 3580 } 3586 3581 else 3587 3582 { 3588 r_dtlb.select( 3589 false,// PTE23590 3591 &set);3583 r_dtlb.select(r_dcache_tlb_vaddr.read(), 3584 false, // PTE2 3585 &way, 3586 &set); 3592 3587 #ifdef INSTRUMENTATION 3593 m_cpt_data_tlb_read++;3588 m_cpt_dtlb_read++; 3594 3589 #endif 3595 3590 } 3596 3591 3597 3592 #if DEBUG_DCACHE 3598 if ( m_debug_activated)3599 {3600 if ( r_dcache_tlb_ins.read())3601 std::cout << " <PROC " << name()3602 << " DCACHE_TLB_PTE2_SELECT> Select a slot in ITLB:";3603 else3604 std::cout << " <PROC " << name()3605 << " DCACHE_TLB_PTE2_SELECT> Select a slot in DTLB:";3606 std::cout << " way = " << std::dec << way3607 3608 }3593 if (m_debug_activated) 3594 { 3595 if (r_dcache_tlb_ins.read()) 3596 std::cout << " <PROC " << name() 3597 << " DCACHE_TLB_PTE2_SELECT> Select a slot in ITLB:"; 3598 else 3599 std::cout << " <PROC " << name() 3600 << " DCACHE_TLB_PTE2_SELECT> Select a slot in DTLB:"; 3601 std::cout << " way = " << std::dec << way 3602 << " / set = " << set << std::endl; 3603 } 3609 3604 #endif 3610 3605 r_dcache_tlb_way = way; … … 3620 3615 // the coherence mechanism. 3621 3616 { 3622 paddr_t nline = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words)+2);3623 uint32_t 3624 uint32_t 3625 bool 3626 bool 3617 paddr_t nline = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words) + 2); 3618 uint32_t pte_flags = r_dcache_tlb_pte_flags.read(); 3619 uint32_t pte_ppn = r_dcache_tlb_pte_ppn.read(); 3620 bool pt_updt = false; 3621 bool local = true; 3627 3622 3628 3623 // We should compute the access locality: … … 3633 3628 // As long as this computation is not done, all access are local. 3634 3629 3635 if ( local )// local access3636 { 3637 if ( not ((pte_flags & PTE_L_MASK) == PTE_L_MASK)) // we must set the L bit3630 if (local) // local access 3631 { 3632 if (not ((pte_flags & PTE_L_MASK) == PTE_L_MASK)) // we must set the L bit 3638 3633 { 3639 3634 pt_updt = true; … … 3646 3641 else // remote access 3647 3642 { 3648 if ( not ((pte_flags & PTE_R_MASK) == PTE_R_MASK)) // we must set the R bit3643 if (not ((pte_flags & PTE_R_MASK) == PTE_R_MASK)) // we must set the R bit 3649 3644 { 3650 3645 pt_updt = true; … … 3656 3651 } 3657 3652 3658 if ( not pt_updt )// update TLB3659 { 3660 if ( r_dcache_tlb_ins.read())3661 { 3662 r_itlb.write( false,// 4K page3663 3664 3665 3666 3667 3668 nline);3653 if (not pt_updt) // update TLB 3654 { 3655 if (r_dcache_tlb_ins.read()) 3656 { 3657 r_itlb.write(false, // 4K page 3658 pte_flags, 3659 pte_ppn, 3660 r_dcache_tlb_vaddr.read(), 3661 r_dcache_tlb_way.read(), 3662 r_dcache_tlb_set.read(), 3663 nline); 3669 3664 #ifdef INSTRUMENTATION 3670 m_cpt_ins_tlb_update_acc++;3665 m_cpt_itlb_write++; 3671 3666 #endif 3672 3667 3673 3668 #if DEBUG_DCACHE 3674 if ( m_debug_activated)3675 {3676 std::cout << " <PROC " << name()3677 << " DCACHE_TLB_PTE2_UPDT> write PTE2 in ITLB"3678 << " / set = " << std::dec << r_dcache_tlb_set.read()3679 << " / way = " << r_dcache_tlb_way.read() << std::endl;3680 r_itlb.printTrace();3681 }3669 if (m_debug_activated) 3670 { 3671 std::cout << " <PROC " << name() 3672 << " DCACHE_TLB_PTE2_UPDT> write PTE2 in ITLB" 3673 << " / set = " << std::dec << r_dcache_tlb_set.read() 3674 << " / way = " << r_dcache_tlb_way.read() << std::endl; 3675 r_itlb.printTrace(); 3676 } 3682 3677 #endif 3683 3678 } 3684 3679 else 3685 3680 { 3686 r_dtlb.write( false,// 4K page3687 3688 3689 3690 3691 3692 nline);3681 r_dtlb.write(false, // 4K page 3682 pte_flags, 3683 pte_ppn, 3684 r_dcache_tlb_vaddr.read(), 3685 r_dcache_tlb_way.read(), 3686 r_dcache_tlb_set.read(), 3687 nline); 3693 3688 #ifdef INSTRUMENTATION 3694 m_cpt_data_tlb_update_acc++;3689 m_cpt_dtlb_write++; 3695 3690 #endif 3696 3691 3697 3692 #if DEBUG_DCACHE 3698 if ( m_debug_activated)3699 {3700 std::cout << " <PROC " << name()3701 << " DCACHE_TLB_PTE2_UPDT> write PTE2 in DTLB"3702 << " / set = " << std::dec << r_dcache_tlb_set.read()3703 << " / way = " << r_dcache_tlb_way.read() << std::endl;3704 r_dtlb.printTrace();3705 }3693 if (m_debug_activated) 3694 { 3695 std::cout << " <PROC " << name() 3696 << " DCACHE_TLB_PTE2_UPDT> write PTE2 in DTLB" 3697 << " / set = " << std::dec << r_dcache_tlb_set.read() 3698 << " / way = " << r_dcache_tlb_way.read() << std::endl; 3699 r_dtlb.printTrace(); 3700 } 3706 3701 #endif 3707 3702 … … 3714 3709 3715 3710 #if DEBUG_DCACHE 3716 if ( m_debug_activated)3717 {3718 std::cout << " <PROC " << name()3719 << " DCACHE_TLB_PTE2_UPDT> L/R bit update required" << std::endl;3720 }3711 if (m_debug_activated) 3712 { 3713 std::cout << " <PROC " << name() 3714 << " DCACHE_TLB_PTE2_UPDT> L/R bit update required" << std::endl; 3715 } 3721 3716 #endif 3722 3717 } … … 3729 3724 uint32_t set = r_cas_local_set.read(); 3730 3725 uint32_t word = r_cas_local_word.read(); 3731 paddr_t nline = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words) +2);3726 paddr_t nline = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words) + 2); 3732 3727 #if DEBUG_DCACHE 3733 if ( m_debug_activated)3734 {3735 std::cout << " <PROC " << name()3736 << " DCACHE_TLB_LR_UPDT> Update dcache: (L/R) bit" << std::endl;3737 }3728 if (m_debug_activated) 3729 { 3730 std::cout << " <PROC " << name() 3731 << " DCACHE_TLB_LR_UPDT> Update dcache: (L/R) bit" << std::endl; 3732 } 3738 3733 #endif 3739 3734 … … 3744 3739 word, 3745 3740 r_dcache_vci_cas_new.read()); 3746 //compteur dirty 3747 r_dcache_dirty_word[(way*m_dcache_sets +set)*m_dcache_words+word] = 1; 3748 3749 if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_IN_TLB ) 3750 { 3751 r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_DIRTY; 3752 r_dcache_tlb_inval_line = nline; 3753 r_dcache_tlb_inval_set = 0; 3754 r_dcache_fsm_scan_save = DCACHE_TLB_RETURN; 3755 r_dcache_fsm = DCACHE_INVAL_TLB_SCAN; 3741 3742 // stats dirty words 3743 r_dcache_dirty_word[(way * m_dcache_sets + set) * m_dcache_words + word] = 1; 3744 3745 if (r_dcache_content_state[way * m_dcache_sets + set] == LINE_CACHE_IN_TLB) 3746 { 3747 r_dcache_content_state[way * m_dcache_sets + set] = LINE_CACHE_DATA_DIRTY; 3748 r_dcache_tlb_inval_line = nline; 3749 r_dcache_tlb_inval_set = 0; 3750 r_dcache_fsm_scan_save = DCACHE_TLB_RETURN; 3751 r_dcache_fsm = DCACHE_INVAL_TLB_SCAN; 3756 3752 break; 3757 3753 } 3758 3754 3759 if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_CONTAINS_PTD)3755 if (r_dcache_content_state[way * m_dcache_sets + set] == LINE_CACHE_CONTAINS_PTD) 3760 3756 { 3761 3757 r_itlb.reset(); … … 3764 3760 3765 3761 #if DEBUG_DCACHE 3766 if ( m_debug_activated)3762 if (m_debug_activated) 3767 3763 { 3768 3764 std::cout << " <PROC " << name() … … 3777 3773 { 3778 3774 // r_dcache_vci_cas_old & r_dcache_vci_cas_new registers are already set 3779 r_dcache_vci_paddr = r_dcache_tlb_paddr.read();3775 r_dcache_vci_paddr = r_dcache_tlb_paddr.read(); 3780 3776 3781 3777 // checking llsc reservation buffer 3782 if ( r_dcache_llsc_paddr.read() == r_dcache_tlb_paddr.read())3778 if (r_dcache_llsc_paddr.read() == r_dcache_tlb_paddr.read()) 3783 3779 r_dcache_llsc_valid = false; 3784 3780 … … 3800 3796 { 3801 3797 // coherence clack request (from DSPIN CLACK) 3802 if ( r_dcache_clack_req.read())3798 if (r_dcache_clack_req.read()) 3803 3799 { 3804 3800 r_dcache_fsm = DCACHE_CC_CHECK; … … 3808 3804 3809 3805 // coherence request (from CC_RECEIVE FSM) 3810 if ( 3806 if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 3811 3807 { 3812 3808 r_dcache_fsm = DCACHE_CC_CHECK; … … 3815 3811 } 3816 3812 3817 if ( r_vci_rsp_data_error.read() )// bus error3813 if (r_vci_rsp_data_error.read()) // bus error 3818 3814 { 3819 3815 std::cout << "BUS ERROR in DCACHE_TLB_LR_WAIT state" << std::endl; … … 3821 3817 exit(0); 3822 3818 } 3823 else if ( r_vci_rsp_fifo_dcache.rok()) // response available3819 else if (r_vci_rsp_fifo_dcache.rok()) // response available 3824 3820 { 3825 3821 #if DEBUG_DCACHE 3826 if ( m_debug_activated)3827 {3828 std::cout << " <PROC " << name()3829 << " DCACHE_TLB_LR_WAIT> SC response received" << std::endl;3830 }3822 if (m_debug_activated) 3823 { 3824 std::cout << " <PROC " << name() 3825 << " DCACHE_TLB_LR_WAIT> SC response received" << std::endl; 3826 } 3831 3827 #endif 3832 3828 vci_rsp_fifo_dcache_get = true; 3833 r_dcache_fsm 3829 r_dcache_fsm = DCACHE_TLB_RETURN; 3834 3830 } 3835 3831 break; 3836 3832 } 3837 3833 /////////////////////// 3838 case DCACHE_TLB_RETURN: 3834 case DCACHE_TLB_RETURN: // return to caller depending on tlb miss type 3839 3835 { 3840 3836 #if DEBUG_DCACHE 3841 if ( m_debug_activated)3842 {3843 std::cout << " <PROC " << name()3844 << " DCACHE_TLB_RETURN> TLB MISS completed" << std::endl;3845 }3846 #endif 3847 if ( r_dcache_tlb_ins.read()) r_icache_tlb_miss_req = false;3837 if (m_debug_activated) 3838 { 3839 std::cout << " <PROC " << name() 3840 << " DCACHE_TLB_RETURN> TLB MISS completed" << std::endl; 3841 } 3842 #endif 3843 if (r_dcache_tlb_ins.read()) r_icache_tlb_miss_req = false; 3848 3844 r_dcache_fsm = DCACHE_IDLE; 3849 3845 break; … … 3854 3850 // Caution : the itlb miss requests must be taken 3855 3851 // to avoid dead-lock in case of simultaneous ITLB miss 3852 // Caution : the clack and cc requests must be taken 3853 // to avoid dead-lock 3856 3854 { 3857 3855 // coherence clack request (from DSPIN CLACK) 3858 if ( r_dcache_clack_req.read())3856 if (r_dcache_clack_req.read()) 3859 3857 { 3860 3858 r_dcache_fsm = DCACHE_CC_CHECK; … … 3864 3862 3865 3863 // coherence request (from CC_RECEIVE FSM) 3866 if ( 3864 if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 3867 3865 { 3868 3866 r_dcache_fsm = DCACHE_CC_CHECK; … … 3872 3870 3873 3871 // itlb miss request 3874 if ( r_icache_tlb_miss_req.read())3875 { 3876 r_dcache_tlb_ins 3877 r_dcache_tlb_vaddr 3878 r_dcache_fsm 3879 break; 3880 } 3881 3882 if ( not r_dcache_xtn_req.read())3872 if (r_icache_tlb_miss_req.read()) 3873 { 3874 r_dcache_tlb_ins = true; 3875 r_dcache_tlb_vaddr = r_icache_vaddr_save.read(); 3876 r_dcache_fsm = DCACHE_TLB_MISS; 3877 break; 3878 } 3879 3880 if (not r_dcache_xtn_req.read()) 3883 3881 { 3884 3882 r_dtlb.flush(); … … 3890 3888 } 3891 3889 ///////////////////// 3892 case DCACHE_XTN_SYNC: 3893 3894 3890 case DCACHE_XTN_SYNC: // waiting until write buffer empty 3891 // The coherence request must be taken 3892 // as there is a risk of dead-lock 3895 3893 { 3896 3894 // coherence clack request (from DSPIN CLACK) 3897 if ( r_dcache_clack_req.read())3895 if (r_dcache_clack_req.read()) 3898 3896 { 3899 3897 r_dcache_fsm = DCACHE_CC_CHECK; … … 3903 3901 3904 3902 // coherence request (from CC_RECEIVE FSM) 3905 if ( 3903 if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 3906 3904 { 3907 3905 r_dcache_fsm = DCACHE_CC_CHECK; … … 3910 3908 } 3911 3909 3912 if ( r_wbuf.empty())3913 { 3914 m_drsp.valid 3910 if (r_wbuf.empty()) 3911 { 3912 m_drsp.valid = true; 3915 3913 r_dcache_fsm = DCACHE_IDLE; 3916 3914 } … … 3926 3924 { 3927 3925 // coherence clack request (from DSPIN CLACK) 3928 if ( r_dcache_clack_req.read())3926 if (r_dcache_clack_req.read()) 3929 3927 { 3930 3928 r_dcache_fsm = DCACHE_CC_CHECK; … … 3934 3932 3935 3933 // coherence request (from CC_RECEIVE FSM) 3936 if ( 3934 if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 3937 3935 { 3938 3936 r_dcache_fsm = DCACHE_CC_CHECK; … … 3942 3940 3943 3941 // itlb miss request 3944 if ( r_icache_tlb_miss_req.read())3945 { 3946 r_dcache_tlb_ins 3947 r_dcache_tlb_vaddr 3948 r_dcache_fsm 3942 if (r_icache_tlb_miss_req.read()) 3943 { 3944 r_dcache_tlb_ins = true; 3945 r_dcache_tlb_vaddr = r_icache_vaddr_save.read(); 3946 r_dcache_fsm = DCACHE_TLB_MISS; 3949 3947 break; 3950 3948 } 3951 3949 3952 3950 // test if XTN request to icache completed 3953 if ( not r_dcache_xtn_req.read())3951 if (not r_dcache_xtn_req.read()) 3954 3952 { 3955 3953 r_dcache_fsm = DCACHE_IDLE; … … 3969 3967 { 3970 3968 // coherence clack request (from DSPIN CLACK) 3971 if ( r_dcache_clack_req.read())3969 if (r_dcache_clack_req.read()) 3972 3970 { 3973 3971 r_dcache_fsm = DCACHE_CC_CHECK; … … 3977 3975 3978 3976 // coherence request (from CC_RECEIVE FSM) 3979 if ( 3977 if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 3980 3978 { 3981 3979 r_dcache_fsm = DCACHE_CC_CHECK; … … 3984 3982 } 3985 3983 3986 if ( not r_dcache_cc_send_req.read()) // blocked until previous cc_send request is sent3987 { 3988 int 3989 paddr_t 3990 size_t 3991 size_t 3984 if (not r_dcache_cc_send_req.read()) // blocked until previous cc_send request is sent 3985 { 3986 int state; 3987 paddr_t tag; 3988 size_t way = r_dcache_flush_count.read()/m_dcache_sets; 3989 size_t set = r_dcache_flush_count.read()%m_dcache_sets; 3992 3990 3993 3991 #ifdef INSTRUMENTATION 3994 m_cpt_dcache_dir_read++;3995 #endif 3996 r_dcache.read_dir( 3997 3998 3999 &state);4000 4001 if ( state == CACHE_SLOT_STATE_VALID_CC )// inval required3992 m_cpt_dcache_dir_read++; 3993 #endif 3994 r_dcache.read_dir(way, 3995 set, 3996 &tag, 3997 &state); 3998 3999 if (state == CACHE_SLOT_STATE_VALID_CC) // inval required 4002 4000 { 4003 4001 // request cleanup … … 4008 4006 4009 4007 // goes to DCACHE_XTN_DC_FLUSH_GO to inval directory 4010 r_dcache_miss_way = way; 4011 r_dcache_miss_set = set; 4008 r_dcache_miss_way = way; 4009 r_dcache_miss_set = set; 4010 r_dcache_fsm = DCACHE_XTN_DC_FLUSH_GO; 4012 4011 r_dcache_cc_cleanup_line_ncc = false; 4013 4012 r_dcache_cc_cleanup_updt_data = false; 4014 r_dcache_fsm = DCACHE_XTN_DC_FLUSH_GO; 4015 } 4016 else if ( state == CACHE_SLOT_STATE_VALID_NCC) 4013 } 4014 else if (state == CACHE_SLOT_STATE_VALID_NCC) 4017 4015 { 4018 4016 // request cleanup … … 4023 4021 4024 4022 // goes to DCACHE_XTN_DC_FLUSH_GO to inval directory 4025 r_dcache_miss_way 4026 r_dcache_miss_set 4023 r_dcache_miss_way = way; 4024 r_dcache_miss_set = set; 4027 4025 r_dcache_cc_cleanup_line_ncc = true; 4028 4026 4029 if (r_dcache_content_state[m_dcache_sets *way+set] != LINE_CACHE_DATA_NOT_DIRTY)//Must send data in the cleanup4027 if (r_dcache_content_state[m_dcache_sets * way + set] != LINE_CACHE_DATA_NOT_DIRTY) // Must send data in the cleanup 4030 4028 { 4031 4029 r_dcache_xtn_flush_addr_data = (tag * m_dcache_sets + set) * m_dcache_words * 4; 4032 4030 r_dcache_xtn_flush_data_cpt = 0; 4033 4031 r_dcache_cc_cleanup_updt_data = true; 4034 for (size_t w = 0; w < m_dcache_words; w++)4032 for (size_t w = 0; w < m_dcache_words; w++) 4035 4033 { 4036 m_cpt_cleanup_data_dirty_word += r_dcache_dirty_word[(m_dcache_sets *way+set)*m_dcache_words + w];4034 m_cpt_cleanup_data_dirty_word += r_dcache_dirty_word[(m_dcache_sets * way + set) * m_dcache_words + w]; 4037 4035 } 4038 r_dcache_fsm 4036 r_dcache_fsm = DCACHE_XTN_DC_FLUSH_DATA; 4039 4037 } 4040 4038 else 4041 4039 { 4042 4040 r_dcache_cc_cleanup_updt_data = false; 4043 r_dcache_fsm 4044 } 4045 } 4046 else if ( 4047 (m_dcache_sets *m_dcache_ways - 1)) // last slot4041 r_dcache_fsm = DCACHE_XTN_DC_FLUSH_GO; 4042 } 4043 } 4044 else if (r_dcache_flush_count.read() == 4045 (m_dcache_sets * m_dcache_ways - 1)) // last slot 4048 4046 { 4049 4047 r_dtlb.reset(); … … 4054 4052 4055 4053 // saturation counter 4056 if ( r_dcache_flush_count.read() < (m_dcache_sets*m_dcache_ways - 1))4054 if (r_dcache_flush_count.read() < (m_dcache_sets * m_dcache_ways - 1)) 4057 4055 r_dcache_flush_count = r_dcache_flush_count.read() + 1; 4058 4056 } 4059 4057 break; 4060 4058 } 4061 4062 4059 //////////////////////////// 4063 4060 case DCACHE_XTN_DC_FLUSH_DATA: 4064 4061 { 4065 4062 uint32_t rdata; 4066 size_t 4067 size_t 4068 size_t 4063 size_t way; 4064 size_t set; 4065 size_t word; 4069 4066 4070 4067 r_dcache.read_neutral(r_dcache_xtn_flush_addr_data.read(), … … 4073 4070 &set, 4074 4071 &word); 4075 if(r_cc_send_data_fifo.wok()) 4072 4073 if (r_cc_send_data_fifo.wok()) 4076 4074 { 4077 4075 r_dcache_xtn_flush_addr_data = r_dcache_xtn_flush_addr_data.read() + 4; 4078 4076 4079 cleanup_data_updt_fifo_dcache_put 4080 cleanup_data_updt_fifo_dcache_data 4077 cleanup_data_updt_fifo_dcache_put = true; 4078 cleanup_data_updt_fifo_dcache_data = rdata; 4081 4079 4082 4080 r_dcache_xtn_flush_data_cpt = r_dcache_xtn_flush_data_cpt + 1; 4083 if (r_dcache_xtn_flush_data_cpt.read() == (m_dcache_words - 1))4081 if (r_dcache_xtn_flush_data_cpt.read() == (m_dcache_words - 1)) 4084 4082 { 4085 4083 r_dcache_xtn_flush_data_cpt = 0; … … 4089 4087 break; 4090 4088 } 4091 4092 4089 //////////////////////////// 4093 4090 case DCACHE_XTN_DC_FLUSH_GO: // Switch the cache slot to ZOMBI state … … 4098 4095 size_t set = r_dcache_miss_set.read(); 4099 4096 4100 r_dcache_content_state[m_dcache_sets *way+set] = LINE_CACHE_DATA_DIRTY;4097 r_dcache_content_state[m_dcache_sets * way + set] = LINE_CACHE_DATA_DIRTY; 4101 4098 4102 4099 #ifdef INSTRUMENTATION 4103 m_cpt_dcache_dir_write++; 4104 #endif 4105 4106 4107 4108 r_dcache.write_dir( way, 4109 set, 4110 CACHE_SLOT_STATE_ZOMBI ); 4111 4112 if ( r_dcache_flush_count.read() == 4113 (m_dcache_sets*m_dcache_ways - 1) ) // last slot 4100 m_cpt_dcache_dir_write++; 4101 #endif 4102 r_dcache.write_dir(way, 4103 set, 4104 CACHE_SLOT_STATE_ZOMBI); 4105 4106 if (r_dcache_flush_count.read() == 4107 (m_dcache_sets * m_dcache_ways - 1)) // last slot 4114 4108 { 4115 4109 r_dtlb.reset(); … … 4125 4119 } 4126 4120 ///////////////////////// 4127 case DCACHE_XTN_DT_INVAL: 4121 case DCACHE_XTN_DT_INVAL: // handling processor XTN_DTLB_INVAL request 4128 4122 { 4129 4123 r_dtlb.inval(r_dcache_save_wdata.read()); 4130 r_dcache_fsm 4131 m_drsp.valid 4124 r_dcache_fsm = DCACHE_IDLE; 4125 m_drsp.valid = true; 4132 4126 break; 4133 4127 } … … 4138 4132 { 4139 4133 paddr_t paddr; 4140 bool 4141 4142 if ( r_mmu_mode.read() & DATA_TLB_MASK )// dtlb activated4134 bool hit; 4135 4136 if (r_mmu_mode.read() & DATA_TLB_MASK) // dtlb activated 4143 4137 { 4144 4138 4145 4139 #ifdef INSTRUMENTATION 4146 m_cpt_data_tlb_read++;4147 #endif 4148 hit = r_dtlb.translate( 4149 &paddr);4150 } 4151 else 4140 m_cpt_dtlb_read++; 4141 #endif 4142 hit = r_dtlb.translate(r_dcache_save_wdata.read(), 4143 &paddr); 4144 } 4145 else // dtlb not activated 4152 4146 { 4153 4147 paddr = (paddr_t)r_dcache_save_wdata.read(); 4154 4148 if (vci_param::N > 32) 4155 4149 paddr = paddr | ((paddr_t)(r_dcache_paddr_ext.read()) << 32); 4156 hit 4157 } 4158 4159 if ( hit )// tlb hit4150 hit = true; 4151 } 4152 4153 if (hit) // tlb hit 4160 4154 { 4161 4155 r_dcache_save_paddr = paddr; 4162 r_dcache_fsm 4163 } 4164 else 4156 r_dcache_fsm = DCACHE_XTN_DC_INVAL_PA; 4157 } 4158 else // tlb miss 4165 4159 { 4166 4160 4167 4161 #ifdef INSTRUMENTATION 4168 m_cpt_data_tlb_miss++;4169 #endif 4170 r_dcache_tlb_ins = false;// dtlb4171 r_dcache_tlb_vaddr 4172 r_dcache_fsm 4162 m_cpt_dtlb_miss++; 4163 #endif 4164 r_dcache_tlb_ins = false; // dtlb 4165 r_dcache_tlb_vaddr = r_dcache_save_wdata.read(); 4166 r_dcache_fsm = DCACHE_TLB_MISS; 4173 4167 } 4174 4168 4175 4169 #if DEBUG_DCACHE 4176 if ( m_debug_activated)4177 {4178 std::cout << " <PROC " << name()4179 << " DCACHE_XTN_DC_INVAL_VA> Compute physical address" << std::hex4180 << " / VADDR = " << r_dcache_save_wdata.read()4181 << " / PADDR = " << paddr << std::endl;4182 }4170 if (m_debug_activated) 4171 { 4172 std::cout << " <PROC " << name() 4173 << " DCACHE_XTN_DC_INVAL_VA> Compute physical address" << std::hex 4174 << " / VADDR = " << r_dcache_save_wdata.read() 4175 << " / PADDR = " << paddr << std::endl; 4176 } 4183 4177 #endif 4184 4178 … … 4190 4184 // In this state we read dcache. 4191 4185 { 4192 size_t 4193 size_t 4194 size_t 4195 int 4186 size_t way; 4187 size_t set; 4188 size_t word; 4189 int state; 4196 4190 4197 4191 #ifdef INSTRUMENTATION 4198 m_cpt_dcache_dir_read++; 4199 #endif 4200 r_dcache.read_dir( r_dcache_save_paddr.read(), 4201 &state, 4202 &way, 4203 &set, 4204 &word ); 4205 4206 if ((state == CACHE_SLOT_STATE_VALID_CC) or (state == CACHE_SLOT_STATE_VALID_NCC)) // inval to be done 4192 m_cpt_dcache_dir_read++; 4193 #endif 4194 r_dcache.read_dir(r_dcache_save_paddr.read(), 4195 &state, 4196 &way, 4197 &set, 4198 &word); 4199 4200 if ((state == CACHE_SLOT_STATE_VALID_CC) or 4201 (state == CACHE_SLOT_STATE_VALID_NCC)) // inval to be done 4207 4202 { 4208 4203 r_dcache_xtn_way = way; 4209 4204 r_dcache_xtn_set = set; 4210 4205 r_dcache_xtn_state = state; 4211 r_dcache_xtn_data_addr = r_dcache_save_paddr.read()&~0x3F; 4212 4213 if( (state == CACHE_SLOT_STATE_VALID_NCC) and (r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_DATA_NOT_DIRTY) ) 4206 r_dcache_xtn_data_addr = r_dcache_save_paddr.read() & ~0x3F; 4207 4208 if ((state == CACHE_SLOT_STATE_VALID_NCC) and 4209 (r_dcache_content_state[way * m_dcache_sets + set] == LINE_CACHE_DATA_NOT_DIRTY)) 4214 4210 { 4215 4211 m_cpt_cleanup_data_not_dirty ++; 4216 4212 } 4217 4213 r_dcache_fsm = DCACHE_XTN_DC_INVAL_GO; 4218 4219 } 4220 else // miss : nothing to do 4221 { 4222 r_dcache_fsm = DCACHE_IDLE; 4223 m_drsp.valid = true; 4214 } 4215 else // miss : nothing to do 4216 { 4217 r_dcache_fsm = DCACHE_IDLE; 4218 m_drsp.valid = true; 4224 4219 } 4225 4220 4226 4221 #if DEBUG_DCACHE 4227 if ( m_debug_activated ) 4228 { 4229 std::cout << " <PROC " << name() 4230 << " DCACHE_XTN_DC_INVAL_PA> Test hit in dcache" << std::hex 4231 << " / PADDR = " << r_dcache_save_paddr.read() << std::dec 4232 << " / HIT = " << ((state == CACHE_SLOT_STATE_VALID_CC) or (state == CACHE_SLOT_STATE_VALID_NCC)) 4233 << " / SET = " << set 4234 << " / WAY = " << way << std::endl; 4235 //r_dcache.printTrace(); 4236 } 4222 if (m_debug_activated) 4223 { 4224 std::cout << " <PROC " << name() 4225 << " DCACHE_XTN_DC_INVAL_PA> Test hit in dcache" << std::hex 4226 << " / PADDR = " << r_dcache_save_paddr.read() << std::dec 4227 << " / HIT = " << ((state == CACHE_SLOT_STATE_VALID_CC) or (state == CACHE_SLOT_STATE_VALID_NCC)) 4228 << " / SET = " << set 4229 << " / WAY = " << way << std::endl; 4230 } 4237 4231 #endif 4238 4232 break; … … 4243 4237 // Test if itlb or dtlb inval is required 4244 4238 { 4245 if ( not r_dcache_cc_send_req.read()) // blocked until previous cc_send request is sent4246 { 4247 int state= r_dcache_xtn_state.read();4248 size_t way= r_dcache_xtn_way.read();4249 size_t set= r_dcache_xtn_set.read();4250 paddr_t nline = r_dcache_save_paddr.read() / (m_dcache_words<<2);4239 if (not r_dcache_cc_send_req.read()) // blocked until previous cc_send request is sent 4240 { 4241 int state = r_dcache_xtn_state.read(); 4242 size_t way = r_dcache_xtn_way.read(); 4243 size_t set = r_dcache_xtn_set.read(); 4244 paddr_t nline = r_dcache_save_paddr.read() / (m_dcache_words << 2); 4251 4245 4252 4246 #ifdef INSTRUMENTATION 4253 m_cpt_dcache_dir_write++;4254 #endif 4255 4256 if ((state == CACHE_SLOT_STATE_VALID_CC) or (state == CACHE_SLOT_STATE_VALID_NCC))// request cleanup4247 m_cpt_dcache_dir_write++; 4248 #endif 4249 if ((state == CACHE_SLOT_STATE_VALID_CC) or 4250 (state == CACHE_SLOT_STATE_VALID_NCC)) // request cleanup 4257 4251 { 4258 4252 r_dcache_cc_send_req = true; … … 4263 4257 { 4264 4258 r_dcache_cc_cleanup_line_ncc = false; 4265 r_dcache.write_dir( 4266 set,4267 CACHE_SLOT_STATE_ZOMBI);4259 r_dcache.write_dir(way, 4260 set, 4261 CACHE_SLOT_STATE_ZOMBI); 4268 4262 } 4269 4263 else 4270 4264 { 4271 4265 r_dcache_cc_cleanup_line_ncc = true; 4272 if ((r_dcache_content_state[way *m_dcache_sets+set] != LINE_CACHE_DATA_NOT_DIRTY)) //must send data4266 if ((r_dcache_content_state[way * m_dcache_sets + set] != LINE_CACHE_DATA_NOT_DIRTY)) //must send data 4273 4267 { 4274 4268 r_dcache_cc_cleanup_updt_data = true; 4275 for (size_t w = 0; w < m_dcache_words; w++)4269 for (size_t w = 0; w < m_dcache_words; w++) 4276 4270 { 4277 m_cpt_cleanup_data_dirty_word += r_dcache_dirty_word[(m_dcache_sets *way+set)*m_dcache_words + w];4271 m_cpt_cleanup_data_dirty_word += r_dcache_dirty_word[(m_dcache_sets * way + set) * m_dcache_words + w]; 4278 4272 } 4279 4273 r_dcache_fsm = DCACHE_XTN_DC_INVAL_DATA; … … 4283 4277 { 4284 4278 r_dcache_cc_cleanup_updt_data = false; 4285 r_dcache.write_dir( 4286 4287 CACHE_SLOT_STATE_ZOMBI);4279 r_dcache.write_dir(way, 4280 set, 4281 CACHE_SLOT_STATE_ZOMBI); 4288 4282 } 4289 if( (state == CACHE_SLOT_STATE_VALID_NCC) and (r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_DATA_NOT_DIRTY) ) 4283 if ((state == CACHE_SLOT_STATE_VALID_NCC) and 4284 (r_dcache_content_state[way * m_dcache_sets + set] == LINE_CACHE_DATA_NOT_DIRTY)) 4285 { 4290 4286 m_cpt_cleanup_data_not_dirty ++; 4287 } 4291 4288 } 4292 4289 } 4293 4290 4294 4291 // possible itlb & dtlb invalidate 4295 if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_IN_TLB)4292 if (r_dcache_content_state[way * m_dcache_sets + set] == LINE_CACHE_IN_TLB) 4296 4293 { 4297 4294 r_dcache_tlb_inval_line = nline; … … 4299 4296 r_dcache_fsm_scan_save = DCACHE_XTN_DC_INVAL_END; 4300 4297 r_dcache_fsm = DCACHE_INVAL_TLB_SCAN; 4301 r_dcache_content_state[way *m_dcache_sets+set] = LINE_CACHE_DATA_DIRTY;4302 } 4303 else if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_CONTAINS_PTD)4298 r_dcache_content_state[way * m_dcache_sets + set] = LINE_CACHE_DATA_DIRTY; 4299 } 4300 else if (r_dcache_content_state[way * m_dcache_sets + set] == LINE_CACHE_CONTAINS_PTD) 4304 4301 { 4305 4302 r_itlb.reset(); 4306 4303 r_dtlb.reset(); 4307 r_dcache_content_state[way *m_dcache_sets+set] = LINE_CACHE_DATA_DIRTY;4304 r_dcache_content_state[way * m_dcache_sets + set] = LINE_CACHE_DATA_DIRTY; 4308 4305 r_dcache_fsm = DCACHE_IDLE; 4309 4306 m_drsp.valid = true; … … 4316 4313 4317 4314 #if DEBUG_DCACHE 4318 if ( m_debug_activated)4319 {4320 std::cout << " <PROC " << name()4321 << " DCACHE_XTN_DC_INVAL_GO> Actual dcache inval" << std::hex4322 << " / PADDR = " << r_dcache_save_paddr.read() << std::endl;4323 }4315 if (m_debug_activated) 4316 { 4317 std::cout << " <PROC " << name() 4318 << " DCACHE_XTN_DC_INVAL_GO> Actual dcache inval" << std::hex 4319 << " / PADDR = " << r_dcache_save_paddr.read() << std::endl; 4320 } 4324 4321 #endif 4325 4322 } 4326 4323 break; 4327 4324 } 4328 4329 /*RWT*/4330 4325 ////////////////////////////// 4331 4326 case DCACHE_XTN_DC_INVAL_DATA: 4332 4327 { 4333 4334 4328 uint32_t rdata; 4335 size_t 4336 size_t 4337 size_t 4329 size_t way = 0; // To avoid gcc warning 4330 size_t set = 0; // To avoid gcc warning 4331 size_t word; 4338 4332 r_dcache.read_neutral(r_dcache_xtn_data_addr.read(), 4339 4333 &rdata, … … 4341 4335 &set, 4342 4336 &word); 4343 if (r_cc_send_data_fifo.wok())4337 if (r_cc_send_data_fifo.wok()) 4344 4338 { 4345 4339 r_dcache_xtn_data_addr = r_dcache_xtn_data_addr.read() + 4; 4346 4340 4347 cleanup_data_updt_fifo_dcache_put 4348 cleanup_data_updt_fifo_dcache_data 4341 cleanup_data_updt_fifo_dcache_put = true; 4342 cleanup_data_updt_fifo_dcache_data = rdata; 4349 4343 4350 4344 r_dcache_xtn_data_cpt = r_dcache_xtn_data_cpt.read() + 1; 4351 if (r_dcache_xtn_data_cpt.read() == (m_dcache_words - 1))4345 if (r_dcache_xtn_data_cpt.read() == (m_dcache_words - 1)) 4352 4346 { 4353 4347 r_dcache_xtn_state = CACHE_SLOT_STATE_ZOMBI; 4354 4348 r_dcache_xtn_data_cpt = 0; 4355 4349 r_dcache_fsm = DCACHE_XTN_DC_INVAL_GO; 4356 r_dcache.write_dir( 4357 4358 CACHE_SLOT_STATE_ZOMBI);4350 r_dcache.write_dir(way, 4351 set, 4352 CACHE_SLOT_STATE_ZOMBI); 4359 4353 } 4360 4354 } 4361 4355 break; 4362 4356 } 4363 4364 4357 ////////////////////////////// 4365 case DCACHE_XTN_DC_INVAL_END: 4358 case DCACHE_XTN_DC_INVAL_END: // send response to processor XTN request 4366 4359 { 4367 4360 r_dcache_fsm = DCACHE_IDLE; … … 4377 4370 // when a cleanup is required 4378 4371 { 4379 if ( 4372 if (m_dreq.valid) m_cost_data_miss_frz++; 4380 4373 4381 4374 // coherence clack request (from DSPIN CLACK) 4382 if ( r_dcache_clack_req.read())4375 if (r_dcache_clack_req.read()) 4383 4376 { 4384 4377 r_dcache_fsm = DCACHE_CC_CHECK; … … 4388 4381 4389 4382 // coherence request (from CC_RECEIVE FSM) 4390 if ( 4383 if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 4391 4384 { 4392 4385 r_dcache_fsm = DCACHE_CC_CHECK; … … 4395 4388 } 4396 4389 4397 4398 4399 4400 4401 4402 4403 4404 4390 bool found = false; 4391 bool cleanup = false; 4392 size_t way = 0; 4393 size_t set = 0; 4394 paddr_t victim = 0; 4395 int state; 4396 bool s_cleanup_updt_data = false; 4397 bool s_cleanup_line_ncc = false; 4405 4398 4406 4399 #ifdef INSTRUMENTATION 4407 m_cpt_dcache_dir_read++; 4408 #endif 4409 r_dcache.read_select( r_dcache_save_paddr.read(), 4410 &victim, 4411 &way, 4412 &set, 4413 &found, 4414 &cleanup ); 4415 state = r_dcache.get_cache_state(way,set); 4416 4417 if ( found ) 4418 { 4419 r_dcache_miss_way = way; 4420 r_dcache_miss_set = set; 4421 4422 if ( cleanup ) 4423 { 4424 r_dcache_miss_clack = true; 4425 r_dcache_fsm = DCACHE_MISS_CLEAN; 4426 if( (state == CACHE_SLOT_STATE_VALID_NCC) ) 4400 m_cpt_dcache_dir_read++; 4401 #endif 4402 r_dcache.read_select(r_dcache_save_paddr.read(), 4403 &victim, 4404 &way, 4405 &set, 4406 &found, 4407 &cleanup); 4408 state = r_dcache.get_cache_state(way, set); 4409 4410 if (found) 4411 { 4412 r_dcache_miss_way = way; 4413 r_dcache_miss_set = set; 4414 4415 if (cleanup) 4416 { 4417 r_dcache_miss_clack = true; 4418 r_dcache_fsm = DCACHE_MISS_CLEAN; 4419 4420 if ((state == CACHE_SLOT_STATE_VALID_NCC)) 4421 { 4422 s_cleanup_line_ncc = true; 4423 r_dcache_miss_data_addr = (victim * m_dcache_words) * 4; 4424 if ((r_dcache_content_state[way * m_dcache_sets + set] != LINE_CACHE_DATA_NOT_DIRTY)) // must send data 4427 4425 { 4428 s_cleanup_line_ncc = true; 4429 r_dcache_miss_data_addr = (victim*m_dcache_words)*4; 4430 if ((r_dcache_content_state[way*m_dcache_sets+set] != LINE_CACHE_DATA_NOT_DIRTY))//must send data 4426 s_cleanup_updt_data = true; 4427 for (size_t w = 0; w < m_dcache_words; w++) 4431 4428 { 4432 s_cleanup_updt_data = true; 4433 for (size_t w = 0; w< m_dcache_words; w++) 4434 { 4435 m_cpt_cleanup_data_dirty_word += r_dcache_dirty_word[(m_dcache_sets*way+set)*m_dcache_words + w]; 4436 } 4437 r_dcache_fsm = DCACHE_MISS_DATA; 4429 m_cpt_cleanup_data_dirty_word += r_dcache_dirty_word[(m_dcache_sets * way + set) * m_dcache_words + w]; 4438 4430 } 4439 else 4440 { 4441 s_cleanup_updt_data = false; 4442 } 4443 4444 if (r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_DATA_NOT_DIRTY) 4445 m_cpt_cleanup_data_not_dirty ++; 4431 r_dcache_fsm = DCACHE_MISS_DATA; 4446 4432 } 4447 4433 else 4448 4434 { 4449 s_cleanup_line_ncc = false;4450 4435 s_cleanup_updt_data = false; 4451 4436 } 4452 4437 4453 if( not r_dcache_cc_send_req.read() ) 4454 { 4455 // request cleanup 4456 r_dcache_cc_send_req = true; 4457 r_dcache_cc_send_nline = victim; 4458 r_dcache_cc_send_way = way; 4459 r_dcache_cc_send_type = CC_TYPE_CLEANUP; 4460 r_dcache_cc_cleanup_updt_data = s_cleanup_updt_data; 4461 r_dcache_cc_cleanup_line_ncc = s_cleanup_line_ncc; 4462 } 4463 else 4464 { 4465 r_dcache_cleanup_victim_nline = victim; 4466 r_dcache_cleanup_victim_req = true; 4467 r_dcache_cleanup_victim_updt_data = s_cleanup_updt_data; 4468 r_dcache_cleanup_victim_line_ncc = s_cleanup_line_ncc; 4469 } 4438 if (r_dcache_content_state[way * m_dcache_sets + set] == LINE_CACHE_DATA_NOT_DIRTY) 4439 m_cpt_cleanup_data_not_dirty ++; 4470 4440 } 4471 4441 else 4472 4442 { 4473 r_dcache_fsm = DCACHE_MISS_WAIT; 4474 } 4443 s_cleanup_line_ncc = false; 4444 s_cleanup_updt_data = false; 4445 } 4446 4447 if (not r_dcache_cc_send_req.read()) 4448 { 4449 // request cleanup 4450 r_dcache_cc_send_req = true; 4451 r_dcache_cc_send_nline = victim; 4452 r_dcache_cc_send_way = way; 4453 r_dcache_cc_send_type = CC_TYPE_CLEANUP; 4454 r_dcache_cc_cleanup_updt_data = s_cleanup_updt_data; 4455 r_dcache_cc_cleanup_line_ncc = s_cleanup_line_ncc; 4456 } 4457 else 4458 { 4459 r_dcache_cleanup_victim_nline = victim; 4460 r_dcache_cleanup_victim_req = true; 4461 r_dcache_cleanup_victim_updt_data = s_cleanup_updt_data; 4462 r_dcache_cleanup_victim_line_ncc = s_cleanup_line_ncc; 4463 } 4464 } 4465 else 4466 { 4467 r_dcache_fsm = DCACHE_MISS_WAIT; 4468 } 4475 4469 4476 4470 #if DEBUG_DCACHE 4477 if ( m_debug_activated)4478 {4479 std::cout << " <PROC " << name()4480 << " DCACHE_MISS_SELECT> Select a slot:" << std::dec4481 << " / WAY = " << way4482 << " / SET = " << set4483 << " / PADDR = " << std::hex << r_dcache_save_paddr.read();4484 if(cleanup) std::cout << " / VICTIM = " << (victim*m_dcache_words*4)<< std::endl;4485 else std::cout<< std::endl;4486 }4487 #endif 4488 4471 if (m_debug_activated) 4472 { 4473 std::cout << " <PROC " << name() 4474 << " DCACHE_MISS_SELECT> Select a slot:" << std::dec 4475 << " / WAY = " << way 4476 << " / SET = " << set 4477 << " / PADDR = " << std::hex << r_dcache_save_paddr.read(); 4478 if (cleanup) std::cout << " / VICTIM = " << (victim * m_dcache_words * 4) << std::dec << std::endl; 4479 else std::cout << std::dec << std::endl; 4480 } 4481 #endif 4482 } // end found 4489 4483 break; 4490 4484 } … … 4497 4491 size_t word; 4498 4492 4499 if ( r_dcache_cleanup_victim_req.read() and not r_dcache_cc_send_req.read())4493 if (r_dcache_cleanup_victim_req.read() and not r_dcache_cc_send_req.read()) 4500 4494 { 4501 4495 r_dcache_cc_send_req = true; … … 4513 4507 &set, 4514 4508 &word); 4515 if (r_cc_send_data_fifo.wok())4509 if (r_cc_send_data_fifo.wok()) 4516 4510 { 4517 4511 r_dcache_miss_data_addr = r_dcache_miss_data_addr.read() + 4; 4518 4512 4519 cleanup_data_updt_fifo_dcache_put 4520 cleanup_data_updt_fifo_dcache_data 4513 cleanup_data_updt_fifo_dcache_put = true; 4514 cleanup_data_updt_fifo_dcache_data = rdata; 4521 4515 4522 4516 r_dcache_miss_data_cpt = r_dcache_miss_data_cpt.read() + 1; 4523 if (r_dcache_miss_data_cpt.read() == m_dcache_words-1)4517 if (r_dcache_miss_data_cpt.read() == (m_dcache_words - 1)) 4524 4518 { 4525 4519 r_dcache_miss_data_cpt = 0; … … 4534 4528 // and possibly request itlb or dtlb invalidate 4535 4529 { 4536 if ( 4537 4538 size_t way= r_dcache_miss_way.read();4539 size_t set= r_dcache_miss_set.read();4530 if (m_dreq.valid) m_cost_data_miss_frz++; 4531 4532 size_t way = r_dcache_miss_way.read(); 4533 size_t set = r_dcache_miss_set.read(); 4540 4534 4541 4535 #ifdef INSTRUMENTATION 4542 m_cpt_dcache_dir_read++;4543 #endif 4544 r_dcache.write_dir( 4545 4546 CACHE_SLOT_STATE_ZOMBI);4536 m_cpt_dcache_dir_read++; 4537 #endif 4538 r_dcache.write_dir(way, 4539 set, 4540 CACHE_SLOT_STATE_ZOMBI); 4547 4541 #if DEBUG_DCACHE 4548 if ( m_debug_activated)4549 {4550 std::cout << " <PROC " << name()4551 << " DCACHE_MISS_CLEAN> Switch to ZOMBI state" << std::dec4552 << " / way = " << way4553 << " / set = " << set << std::endl;4554 }4542 if (m_debug_activated) 4543 { 4544 std::cout << " <PROC " << name() 4545 << " DCACHE_MISS_CLEAN> Switch to ZOMBI state" << std::dec 4546 << " / way = " << way 4547 << " / set = " << set << std::endl; 4548 } 4555 4549 #endif 4556 4550 // if selective itlb & dtlb invalidate are required 4557 4551 // the miss response is not handled before invalidate completed 4558 if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_IN_TLB)4559 { 4560 r_dcache_content_state[way *m_dcache_sets+set] = LINE_CACHE_DATA_DIRTY;4561 if( not r_dcache_cleanup_victim_req.read() ) 4562 {4552 if (r_dcache_content_state[way * m_dcache_sets + set] == LINE_CACHE_IN_TLB) 4553 { 4554 r_dcache_content_state[way * m_dcache_sets + set] = LINE_CACHE_DATA_DIRTY; 4555 4556 if (not r_dcache_cleanup_victim_req.read()) 4563 4557 r_dcache_tlb_inval_line = r_dcache_cc_send_nline.read(); 4564 }4565 4558 else 4566 {4567 4559 r_dcache_tlb_inval_line = r_dcache_cleanup_victim_nline.read(); 4568 } 4569 r_dcache_tlb_inval_set 4570 r_dcache_fsm_scan_save 4571 r_dcache_fsm 4572 } 4573 else if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_CONTAINS_PTD)4560 4561 r_dcache_tlb_inval_set = 0; 4562 r_dcache_fsm_scan_save = DCACHE_MISS_WAIT; 4563 r_dcache_fsm = DCACHE_INVAL_TLB_SCAN; 4564 } 4565 else if (r_dcache_content_state[way * m_dcache_sets + set] == LINE_CACHE_CONTAINS_PTD) 4574 4566 { 4575 4567 r_itlb.reset(); 4576 4568 r_dtlb.reset(); 4577 r_dcache_content_state[way *m_dcache_sets+set] = LINE_CACHE_DATA_DIRTY;4569 r_dcache_content_state[way * m_dcache_sets + set] = LINE_CACHE_DATA_DIRTY; 4578 4570 r_dcache_fsm = DCACHE_MISS_WAIT; 4579 4571 } … … 4589 4581 // There is 5 types of error depending on the requester 4590 4582 { 4591 if ( m_dreq.valid) m_cost_data_miss_frz++; 4592 4593 if( r_dcache_cleanup_victim_req.read() and not r_dcache_cc_send_req.read() ) 4594 { 4595 r_dcache_cc_send_req = true; 4596 r_dcache_cc_send_type = CC_TYPE_CLEANUP; 4597 r_dcache_cc_send_nline = r_dcache_cleanup_victim_nline.read(); 4583 if (m_dreq.valid) m_cost_data_miss_frz++; 4584 4585 // send cleanup victim request 4586 if (r_dcache_cleanup_victim_req.read() and not r_dcache_cc_send_req.read()) 4587 { 4588 r_dcache_cc_send_req = true; 4589 r_dcache_cc_send_nline = r_dcache_cleanup_victim_nline.read(); 4590 r_dcache_cc_send_way = r_dcache_miss_way.read(); 4591 r_dcache_cc_send_type = CC_TYPE_CLEANUP; 4598 4592 r_dcache_cleanup_victim_req = false; 4599 4593 r_dcache_cc_cleanup_updt_data = r_dcache_cleanup_victim_updt_data.read(); 4600 r_dcache_cc_cleanup_line_ncc = r_dcache_cleanup_victim_line_ncc.read(); 4601 r_dcache_cc_send_way = r_dcache_miss_way; 4594 r_dcache_cc_cleanup_line_ncc = r_dcache_cleanup_victim_line_ncc.read(); 4602 4595 } 4603 4596 4604 4597 // coherence clack request (from DSPIN CLACK) 4605 if ( r_dcache_clack_req.read())4598 if (r_dcache_clack_req.read()) 4606 4599 { 4607 4600 r_dcache_fsm = DCACHE_CC_CHECK; … … 4611 4604 4612 4605 // coherence request (from CC_RECEIVE FSM) 4613 if ( r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read() and not r_dcache_cleanup_victim_req.read() ) 4606 if (r_cc_receive_dcache_req.read() and 4607 not r_dcache_cc_send_req.read() and 4608 not r_dcache_cleanup_victim_req.read()) 4614 4609 { 4615 4610 r_dcache_fsm = DCACHE_CC_CHECK; … … 4618 4613 } 4619 4614 4620 if ( r_vci_rsp_data_error.read() )// bus error4621 { 4622 switch ( r_dcache_miss_type.read())4615 if (r_vci_rsp_data_error.read()) // bus error 4616 { 4617 switch (r_dcache_miss_type.read()) 4623 4618 { 4624 4619 case PROC_MISS: 4625 4620 { 4626 r_mmu_detr 4627 r_mmu_dbvar 4628 m_drsp.valid 4629 m_drsp.error 4630 r_dcache_fsm 4621 r_mmu_detr = MMU_READ_DATA_ILLEGAL_ACCESS; 4622 r_mmu_dbvar = r_dcache_save_vaddr.read(); 4623 m_drsp.valid = true; 4624 m_drsp.error = true; 4625 r_dcache_fsm = DCACHE_IDLE; 4631 4626 break; 4632 4627 } 4633 4628 case PTE1_MISS: 4634 4629 { 4635 if ( r_dcache_tlb_ins.read())4630 if (r_dcache_tlb_ins.read()) 4636 4631 { 4637 r_mmu_ietr 4638 r_mmu_ibvar 4639 r_icache_tlb_miss_req 4640 r_icache_tlb_rsp_error 4632 r_mmu_ietr = MMU_READ_PT1_ILLEGAL_ACCESS; 4633 r_mmu_ibvar = r_dcache_tlb_vaddr.read(); 4634 r_icache_tlb_miss_req = false; 4635 r_icache_tlb_rsp_error = true; 4641 4636 } 4642 4637 else 4643 4638 { 4644 r_mmu_detr 4645 r_mmu_dbvar 4646 m_drsp.valid 4647 m_drsp.error 4639 r_mmu_detr = MMU_READ_PT1_ILLEGAL_ACCESS; 4640 r_mmu_dbvar = r_dcache_tlb_vaddr.read(); 4641 m_drsp.valid = true; 4642 m_drsp.error = true; 4648 4643 } 4649 r_dcache_fsm 4644 r_dcache_fsm = DCACHE_IDLE; 4650 4645 break; 4651 4646 } 4652 4647 case PTE2_MISS: 4653 4648 { 4654 if ( r_dcache_tlb_ins.read())4649 if (r_dcache_tlb_ins.read()) 4655 4650 { 4656 r_mmu_ietr 4657 r_mmu_ibvar 4658 r_icache_tlb_miss_req 4659 r_icache_tlb_rsp_error 4651 r_mmu_ietr = MMU_READ_PT2_ILLEGAL_ACCESS; 4652 r_mmu_ibvar = r_dcache_tlb_vaddr.read(); 4653 r_icache_tlb_miss_req = false; 4654 r_icache_tlb_rsp_error = true; 4660 4655 } 4661 4656 else 4662 4657 { 4663 r_mmu_detr 4664 r_mmu_dbvar 4665 m_drsp.valid 4666 m_drsp.error 4658 r_mmu_detr = MMU_READ_PT2_ILLEGAL_ACCESS; 4659 r_mmu_dbvar = r_dcache_tlb_vaddr.read(); 4660 m_drsp.valid = true; 4661 m_drsp.error = true; 4667 4662 } 4668 r_dcache_fsm 4663 r_dcache_fsm = DCACHE_IDLE; 4669 4664 break; 4670 4665 } … … 4672 4667 r_vci_rsp_data_error = false; 4673 4668 } 4674 else if ( r_vci_rsp_fifo_dcache.rok() )// valid response available4669 else if (r_vci_rsp_fifo_dcache.rok()) // valid response available 4675 4670 { 4676 4671 r_dcache_miss_word = 0; … … 4680 4675 } 4681 4676 ////////////////////////// 4682 case DCACHE_MISS_DATA_UPDT: 4683 { 4684 if ( 4685 4686 if ( r_vci_rsp_fifo_dcache.rok() && r_vci_rsp_fifo_rpktid.rok())// one word available4677 case DCACHE_MISS_DATA_UPDT: // update the dcache (one word per cycle) 4678 { 4679 if (m_dreq.valid) m_cost_data_miss_frz++; 4680 4681 if (r_vci_rsp_fifo_dcache.rok() and r_vci_rsp_fifo_rpktid.rok()) // one word available 4687 4682 { 4688 4683 #ifdef INSTRUMENTATION 4689 m_cpt_dcache_data_write++;4690 #endif 4691 r_dcache.write(r_dcache_miss_way.read(),4692 4693 4694 r_vci_rsp_fifo_dcache.read());4684 m_cpt_dcache_data_write++; 4685 #endif 4686 r_dcache.write(r_dcache_miss_way.read(), 4687 r_dcache_miss_set.read(), 4688 r_dcache_miss_word.read(), 4689 r_vci_rsp_fifo_dcache.read()); 4695 4690 #if DEBUG_DCACHE 4696 if ( m_debug_activated)4697 {4698 std::cout << " <PROC " << name()4699 << " DCACHE_MISS_DATA_UPDT> Write one word:"4700 << " / DATA = " << std::hex << r_vci_rsp_fifo_dcache.read()4701 << " / WAY = " << std::dec << r_dcache_miss_way.read()4702 << " / SET = " << r_dcache_miss_set.read()4703 << " / WORD = " << r_dcache_miss_word.read() << std::endl;4704 }4691 if (m_debug_activated) 4692 { 4693 std::cout << " <PROC " << name() 4694 << " DCACHE_MISS_DATA_UPDT> Write one word:" 4695 << " / DATA = " << std::hex << r_vci_rsp_fifo_dcache.read() 4696 << " / WAY = " << std::dec << r_dcache_miss_way.read() 4697 << " / SET = " << r_dcache_miss_set.read() 4698 << " / WORD = " << r_dcache_miss_word.read() << std::endl; 4699 } 4705 4700 #endif 4706 4701 vci_rsp_fifo_dcache_get = true; 4707 4702 4708 r_dcache_read_state = !r_vci_rsp_fifo_rpktid.read();//deduce the state (CC or NCC) from msb of pktid4703 r_dcache_read_state = not r_vci_rsp_fifo_rpktid.read(); //deduce the state (CC or NCC) from msb of pktid 4709 4704 vci_rsp_fifo_rpktid_get = true; 4710 4705 4711 4712 4706 r_dcache_miss_word = r_dcache_miss_word.read() + 1; 4713 4707 4714 if ( r_dcache_miss_word.read() == (m_dcache_words-1)) // last word4708 if (r_dcache_miss_word.read() == (m_dcache_words - 1)) // last word 4715 4709 { 4716 4710 r_dcache_fsm = DCACHE_MISS_DIR_UPDT; … … 4728 4722 // to ZOMBI state, and send a cleanup request. 4729 4723 { 4730 if ( m_dreq.valid) m_cost_data_miss_frz++; 4731 4732 if( r_dcache_cleanup_victim_req.read() and not r_dcache_cc_send_req.read() ) 4733 { 4734 r_dcache_cc_send_req = true; 4735 r_dcache_cc_send_type = CC_TYPE_CLEANUP; 4736 r_dcache_cc_send_nline = r_dcache_cleanup_victim_nline.read(); 4724 if (m_dreq.valid) m_cost_data_miss_frz++; 4725 4726 // send cleanup victim request 4727 if (r_dcache_cleanup_victim_req.read() and not r_dcache_cc_send_req.read()) 4728 { 4729 r_dcache_cc_send_req = true; 4730 r_dcache_cc_send_nline = r_dcache_cleanup_victim_nline.read(); 4731 r_dcache_cc_send_way = r_dcache_miss_way.read(); 4732 r_dcache_cc_send_type = CC_TYPE_CLEANUP; 4737 4733 r_dcache_cleanup_victim_req = false; 4738 4734 r_dcache_cc_cleanup_updt_data = r_dcache_cleanup_victim_updt_data.read(); 4739 r_dcache_cc_cleanup_line_ncc = r_dcache_cleanup_victim_line_ncc.read(); 4740 r_dcache_cc_send_way = r_dcache_miss_way; 4735 r_dcache_cc_cleanup_line_ncc = r_dcache_cleanup_victim_line_ncc.read(); 4741 4736 } 4742 4737 4743 4738 // coherence clack request (from DSPIN CLACK) 4744 if ( r_dcache_clack_req.read())4739 if (r_dcache_clack_req.read()) 4745 4740 { 4746 4741 r_dcache_fsm = DCACHE_CC_CHECK; … … 4750 4745 4751 4746 // coherence request (from CC_RECEIVE FSM) 4752 if ( r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read() and not r_dcache_cleanup_victim_req.read() ) 4747 if (r_cc_receive_dcache_req.read() and 4748 not r_dcache_cc_send_req.read() and 4749 not r_dcache_cleanup_victim_req.read()) 4753 4750 { 4754 4751 r_dcache_fsm = DCACHE_CC_CHECK; … … 4757 4754 } 4758 4755 4759 if ( not r_dcache_miss_clack.read()) // waiting cleanup acknowledge4760 { 4761 if ( r_dcache_miss_inval.read()) // switch slot to ZOMBI state, and new cleanup4762 { 4763 if ( not r_dcache_cc_send_req.read()) // blocked until previous request sent4764 { 4765 r_dcache_miss_inval 4756 if (not r_dcache_miss_clack.read()) // waiting cleanup acknowledge 4757 { 4758 if (r_dcache_miss_inval.read()) // switch slot to ZOMBI state, and new cleanup 4759 { 4760 if (not r_dcache_cc_send_req.read()) // blocked until previous request sent 4761 { 4762 r_dcache_miss_inval = false; 4766 4763 // request cleanup 4767 4764 r_dcache_cc_send_req = true; 4768 r_dcache_cc_send_nline = r_dcache_save_paddr.read() /(m_dcache_words<<2);4765 r_dcache_cc_send_nline = r_dcache_save_paddr.read() / (m_dcache_words << 2); 4769 4766 r_dcache_cc_send_way = r_dcache_miss_way.read(); 4770 4767 r_dcache_cc_send_type = CC_TYPE_CLEANUP; 4771 r_dcache_cc_cleanup_updt_data = false; // the line is evicted at the very moment it arives, so it is not dirty4772 r_dcache_cc_cleanup_line_ncc = !r_dcache_read_state.read();4768 r_dcache_cc_cleanup_updt_data = false; // the line is evicted at the very moment it arives, so it is not dirty 4769 r_dcache_cc_cleanup_line_ncc = !r_dcache_read_state.read(); 4773 4770 4774 4771 #ifdef INSTRUMENTATION 4775 m_cpt_dcache_dir_write++;4772 m_cpt_dcache_dir_write++; 4776 4773 #endif 4777 4774 r_dcache.write_dir( r_dcache_save_paddr.read(), … … 4780 4777 CACHE_SLOT_STATE_ZOMBI ); 4781 4778 #if DEBUG_DCACHE 4782 if ( m_debug_activated)4783 std::cout << " <PROC " << name()4784 << " DCACHE_MISS_DIR_UPDT> Switch slot to ZOMBI state"4785 << " PADDR = " << std::hex << r_dcache_save_paddr.read()4786 << " / WAY = " << std::dec << r_dcache_miss_way.read()4787 << " / SET = " << r_dcache_miss_set.read() << std::endl;4779 if (m_debug_activated) 4780 std::cout << " <PROC " << name() 4781 << " DCACHE_MISS_DIR_UPDT> Switch slot to ZOMBI state" 4782 << " PADDR = " << std::hex << r_dcache_save_paddr.read() 4783 << " / WAY = " << std::dec << r_dcache_miss_way.read() 4784 << " / SET = " << r_dcache_miss_set.read() << std::endl; 4788 4785 #endif 4789 4786 } … … 4795 4792 4796 4793 #ifdef INSTRUMENTATION 4797 m_cpt_dcache_dir_write++; 4798 #endif 4799 4794 m_cpt_dcache_dir_write++; 4795 #endif 4800 4796 size_t way = r_dcache_miss_way.read(); 4801 4797 size_t set = r_dcache_miss_set.read(); 4802 4798 if (r_dcache_read_state.read()) 4803 4799 { 4804 r_dcache.write_dir( r_dcache_save_paddr.read(), 4805 r_dcache_miss_way.read(), 4806 r_dcache_miss_set.read(), 4807 CACHE_SLOT_STATE_VALID_CC ); 4808 4809 r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY; 4810 4800 r_dcache.write_dir(r_dcache_save_paddr.read(), 4801 r_dcache_miss_way.read(), 4802 r_dcache_miss_set.read(), 4803 CACHE_SLOT_STATE_VALID_CC); 4804 4805 r_dcache_content_state[way * m_dcache_sets + set] = LINE_CACHE_DATA_NOT_DIRTY; 4811 4806 } 4812 4807 else 4813 4808 { 4814 r_dcache.write_dir( 4815 4816 4817 CACHE_SLOT_STATE_VALID_NCC);4818 r_dcache_content_state[way *m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY;4819 for (size_t word = 0; word < m_dcache_words; word++)4809 r_dcache.write_dir(r_dcache_save_paddr.read(), 4810 r_dcache_miss_way.read(), 4811 r_dcache_miss_set.read(), 4812 CACHE_SLOT_STATE_VALID_NCC); 4813 r_dcache_content_state[way * m_dcache_sets + set] = LINE_CACHE_DATA_NOT_DIRTY; 4814 for (size_t word = 0; word < m_dcache_words; word++) 4820 4815 { 4821 r_dcache_dirty_word[(way *m_dcache_sets +set)*m_dcache_words+word] = 0;4816 r_dcache_dirty_word[(way * m_dcache_sets + set) * m_dcache_words + word] = 0; 4822 4817 } 4823 4818 4824 4819 // STAT : WRITE ON ZOMBI NCC LINE 4825 r_dcache_zombi_ncc[r_dcache_miss_way.read() *m_dcache_sets+r_dcache_miss_set.read()] = true;4820 r_dcache_zombi_ncc[r_dcache_miss_way.read() * m_dcache_sets + r_dcache_miss_set.read()] = true; 4826 4821 } 4827 4822 4828 4823 #if DEBUG_DCACHE 4829 if ( m_debug_activated)4830 std::cout << " <PROC " << name()4831 << " DCACHE_MISS_DIR_UPDT> Switch slot to VALID state"4832 << " PADDR = " << std::hex << r_dcache_save_paddr.read()4833 << " / WAY = " << std::dec << r_dcache_miss_way.read()4834 << " / SET = " << r_dcache_miss_set.read() << std::endl;4824 if (m_debug_activated) 4825 std::cout << " <PROC " << name() 4826 << " DCACHE_MISS_DIR_UPDT> Switch slot to VALID state" 4827 << " PADDR = " << std::hex << r_dcache_save_paddr.read() 4828 << " / WAY = " << std::dec << r_dcache_miss_way.read() 4829 << " / SET = " << r_dcache_miss_set.read() << std::endl; 4835 4830 #endif 4836 4831 } … … 4842 4837 } 4843 4838 ///////////////////// 4844 case DCACHE_UNC_WAIT: // waiting a response to an uncacheable read 4839 case DCACHE_UNC_WAIT: // waiting a response to an uncacheable read/write 4845 4840 { 4846 4841 // coherence clack request (from DSPIN CLACK) 4847 if ( r_dcache_clack_req.read())4842 if (r_dcache_clack_req.read()) 4848 4843 { 4849 4844 r_dcache_fsm = DCACHE_CC_CHECK; … … 4853 4848 4854 4849 // coherence request (from CC_RECEIVE FSM) 4855 if ( 4850 if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 4856 4851 { 4857 4852 r_dcache_fsm = DCACHE_CC_CHECK; … … 4860 4855 } 4861 4856 4862 if ( r_vci_rsp_data_error.read() )// bus error4863 { 4864 if (r_dcache_vci_unc_write.read())4865 r_mmu_detr 4857 if (r_vci_rsp_data_error.read()) // bus error 4858 { 4859 if (r_dcache_vci_unc_write.read()) 4860 r_mmu_detr = MMU_WRITE_DATA_ILLEGAL_ACCESS; 4866 4861 else 4867 r_mmu_detr = MMU_READ_DATA_ILLEGAL_ACCESS; 4862 r_mmu_detr = MMU_READ_DATA_ILLEGAL_ACCESS; 4863 4868 4864 r_mmu_dbvar = m_dreq.addr; 4869 4865 r_vci_rsp_data_error = false; … … 4873 4869 break; 4874 4870 } 4875 else if ( r_vci_rsp_fifo_dcache.rok()) // data available4871 else if (r_vci_rsp_fifo_dcache.rok()) // data available 4876 4872 { 4877 4873 // consume data … … 4880 4876 4881 4877 // acknowledge the processor request if it has not been modified 4882 if ( m_dreq.valid and (m_dreq.addr == r_dcache_save_vaddr.read()))4883 { 4884 m_drsp.valid 4885 m_drsp.error 4886 m_drsp.rdata 4878 if (m_dreq.valid and (m_dreq.addr == r_dcache_save_vaddr.read())) 4879 { 4880 m_drsp.valid = true; 4881 m_drsp.error = false; 4882 m_drsp.rdata = r_vci_rsp_fifo_dcache.read(); 4887 4883 } 4888 4884 } … … 4893 4889 { 4894 4890 // coherence clack request (from DSPIN CLACK) 4895 if ( r_dcache_clack_req.read())4891 if (r_dcache_clack_req.read()) 4896 4892 { 4897 4893 r_dcache_fsm = DCACHE_CC_CHECK; … … 4901 4897 4902 4898 // coherence request (from CC_RECEIVE FSM) 4903 if ( 4899 if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 4904 4900 { 4905 4901 r_dcache_fsm = DCACHE_CC_CHECK; … … 4908 4904 } 4909 4905 4910 if ( r_vci_rsp_data_error.read() )// bus error4906 if (r_vci_rsp_data_error.read()) // bus error 4911 4907 { 4912 4908 r_mmu_detr = MMU_READ_DATA_ILLEGAL_ACCESS; … … 4918 4914 break; 4919 4915 } 4920 else if ( r_vci_rsp_fifo_dcache.rok()) // data available4916 else if (r_vci_rsp_fifo_dcache.rok()) // data available 4921 4917 { 4922 4918 // consume data 4923 4919 vci_rsp_fifo_dcache_get = true; 4924 4920 4925 if (r_dcache_ll_rsp_count.read() == 0) // first flit4921 if (r_dcache_ll_rsp_count.read() == 0) // first flit 4926 4922 { 4927 4923 // set key value in llsc reservation buffer 4928 4924 r_dcache_llsc_key = r_vci_rsp_fifo_dcache.read(); 4929 r_dcache_ll_rsp_count = r_dcache_ll_rsp_count.read() + 1 4925 r_dcache_ll_rsp_count = r_dcache_ll_rsp_count.read() + 1; 4930 4926 } 4931 4927 else // last flit 4932 4928 { 4933 4929 // acknowledge the processor request if it has not been modified 4934 if ( m_dreq.valid and (m_dreq.addr == r_dcache_save_vaddr.read()))4935 { 4936 m_drsp.valid 4937 m_drsp.error 4938 m_drsp.rdata 4930 if (m_dreq.valid and (m_dreq.addr == r_dcache_save_vaddr.read())) 4931 { 4932 m_drsp.valid = true; 4933 m_drsp.error = false; 4934 m_drsp.rdata = r_vci_rsp_fifo_dcache.read(); 4939 4935 } 4940 4936 r_dcache_fsm = DCACHE_IDLE; … … 4944 4940 } 4945 4941 //////////////////// 4946 case DCACHE_SC_WAIT: 4942 case DCACHE_SC_WAIT: // waiting VCI response to a SC transaction 4947 4943 { 4948 4944 // coherence clack request (from DSPIN CLACK) 4949 if ( r_dcache_clack_req.read())4945 if (r_dcache_clack_req.read()) 4950 4946 { 4951 4947 r_dcache_fsm = DCACHE_CC_CHECK; … … 4955 4951 4956 4952 // coherence request (from CC_RECEIVE FSM) 4957 if ( 4953 if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 4958 4954 { 4959 4955 r_dcache_fsm = DCACHE_CC_CHECK; … … 4962 4958 } 4963 4959 4964 if ( r_vci_rsp_data_error.read() )// bus error4960 if (r_vci_rsp_data_error.read()) // bus error 4965 4961 { 4966 4962 r_mmu_detr = MMU_READ_DATA_ILLEGAL_ACCESS; … … 4972 4968 break; 4973 4969 } 4974 else if ( r_vci_rsp_fifo_dcache.rok()) // response available4970 else if (r_vci_rsp_fifo_dcache.rok()) // response available 4975 4971 { 4976 4972 // consume response … … 4983 4979 } 4984 4980 ////////////////////////// 4985 case DCACHE_DIRTY_GET_PTE: 4986 4987 4988 4989 4981 case DCACHE_DIRTY_GET_PTE: // This sub_fsm set the PTE Dirty bit in memory 4982 // before handling a processor WRITE or SC request 4983 // Input argument is r_dcache_dirty_paddr 4984 // In this first state, we get PTE value in dcache 4985 // and post a CAS request to CMD FSM 4990 4986 { 4991 4987 // get PTE in dcache … … 4997 4993 4998 4994 #ifdef INSTRUMENTATION 4999 m_cpt_dcache_data_read++;5000 m_cpt_dcache_dir_read++;5001 #endif 5002 r_dcache.read( 5003 5004 5005 5006 5007 &state);5008 5009 assert( 4995 m_cpt_dcache_data_read++; 4996 m_cpt_dcache_dir_read++; 4997 #endif 4998 r_dcache.read(r_dcache_dirty_paddr.read(), 4999 &pte, 5000 &way, 5001 &set, 5002 &word, 5003 &state); 5004 5005 assert((state == CACHE_SLOT_STATE_VALID_CC or state == CACHE_SLOT_STATE_VALID_NCC) and 5010 5006 "error in DCACHE_DIRTY_TLB_SET: the PTE should be in dcache" ); 5011 5007 5012 5008 // request CAS transaction to CMD_FSM 5013 r_dcache_dirty_way 5014 r_dcache_dirty_set 5009 r_dcache_dirty_way = way; 5010 r_dcache_dirty_set = set; 5015 5011 5016 5012 // check llsc reservation buffer 5017 if (r_dcache_llsc_paddr.read() == r_dcache_dirty_paddr.read() 5013 if (r_dcache_llsc_paddr.read() == r_dcache_dirty_paddr.read()) 5018 5014 r_dcache_llsc_valid = false; 5019 5015 … … 5029 5025 else 5030 5026 { 5031 r_cas_islocal = true; 5032 r_cas_local_way = way; 5033 r_cas_local_set = set; 5034 r_cas_local_word = word; 5027 r_cas_local_way = way; 5028 r_cas_local_set = set; 5029 r_cas_local_word = word; 5035 5030 r_dcache_vci_cas_new = pte | PTE_D_MASK; 5036 }5037 5038 5039 r_dcache_fsm= DCACHE_DIRTY_WAIT;5031 r_cas_islocal = true; 5032 } 5033 5034 r_dcache_fsm = DCACHE_DIRTY_WAIT; 5040 5035 5041 5036 #if DEBUG_DCACHE 5042 if ( m_debug_activated)5043 {5044 std::cout << " <PROC " << name()5045 << " DCACHE_DIRTY_GET_PTE> CAS request" << std::hex5046 << " / PTE_PADDR = " << r_dcache_dirty_paddr.read()5047 << " / PTE_VALUE = " << pte << std::dec5048 << " / SET = " << set5049 << " / WAY = " << way << std::endl;5050 }5037 if (m_debug_activated) 5038 { 5039 std::cout << " <PROC " << name() 5040 << " DCACHE_DIRTY_GET_PTE> CAS request" << std::hex 5041 << " / PTE_PADDR = " << r_dcache_dirty_paddr.read() 5042 << " / PTE_VALUE = " << pte << std::dec 5043 << " / SET = " << set 5044 << " / WAY = " << way << std::endl; 5045 } 5051 5046 #endif 5052 5047 break; 5053 5048 } 5054 5049 /////////////////////// 5055 case DCACHE_DIRTY_WAIT: 5056 5057 5058 5059 5060 5050 case DCACHE_DIRTY_WAIT: // wait completion of CAS for PTE Dirty bit, 5051 // and return to IDLE state when response is received. 5052 // we don't care if the CAS is a failure: 5053 // - if the CAS is a success, the coherence mechanism 5054 // updates the local copy. 5055 // - if the CAS is a failure, we just retry the write. 5061 5056 { 5062 5057 uint32_t way = r_cas_local_way.read(); … … 5066 5061 5067 5062 // coherence clack request (from DSPIN CLACK) 5068 if ( r_dcache_clack_req.read())5063 if (r_dcache_clack_req.read()) 5069 5064 { 5070 5065 r_dcache_fsm = DCACHE_CC_CHECK; … … 5074 5069 5075 5070 // coherence request (from CC_RECEIVE FSM) 5076 if ( 5071 if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read()) 5077 5072 { 5078 5073 r_dcache_fsm = DCACHE_CC_CHECK; … … 5081 5076 } 5082 5077 5083 if ( !r_cas_islocal.read())5084 { 5085 if ( r_vci_rsp_data_error.read()) // bus error5078 if (not r_cas_islocal.read()) 5079 { 5080 if (r_vci_rsp_data_error.read()) // bus error 5086 5081 { 5087 5082 std::cout << "BUS ERROR in DCACHE_DIRTY_WAIT state" << std::endl; … … 5089 5084 exit(0); 5090 5085 } 5091 else if ( r_vci_rsp_fifo_dcache.rok()) // response available5086 else if (r_vci_rsp_fifo_dcache.rok()) // response available 5092 5087 { 5093 5088 vci_rsp_fifo_dcache_get = true; 5094 r_dcache_fsm 5089 r_dcache_fsm = DCACHE_IDLE; 5095 5090 #if DEBUG_DCACHE 5096 if ( m_debug_activated)5097 {5098 std::cout << " <PROC " << name()5099 << " DCACHE_DIRTY_WAIT> CAS completed" << std::endl;5100 }5091 if (m_debug_activated) 5092 { 5093 std::cout << " <PROC " << name() 5094 << " DCACHE_DIRTY_WAIT> CAS completed" << std::endl; 5095 } 5101 5096 #endif 5102 5097 } … … 5109 5104 r_dcache_vci_cas_new.read()); 5110 5105 5111 if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_IN_TLB)5112 { 5113 r_dcache_content_state[way *m_dcache_sets+set] = LINE_CACHE_DATA_DIRTY;5106 if (r_dcache_content_state[way * m_dcache_sets + set] == LINE_CACHE_IN_TLB) 5107 { 5108 r_dcache_content_state[way * m_dcache_sets + set] = LINE_CACHE_DATA_DIRTY; 5114 5109 r_dcache_tlb_inval_line = nline; 5115 5110 r_dcache_tlb_inval_set = 0; … … 5119 5114 } 5120 5115 5121 if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_CONTAINS_PTD)5116 if (r_dcache_content_state[way * m_dcache_sets + set] == LINE_CACHE_CONTAINS_PTD) 5122 5117 { 5123 5118 r_itlb.reset(); 5124 5119 r_dtlb.reset(); 5125 r_dcache_content_state[way *m_dcache_sets+set] = LINE_CACHE_DATA_DIRTY;5120 r_dcache_content_state[way * m_dcache_sets + set] = LINE_CACHE_DATA_DIRTY; 5126 5121 5127 5122 #if DEBUG_DCACHE 5128 if ( m_debug_activated)5123 if (m_debug_activated) 5129 5124 { 5130 5125 std::cout << " <PROC " << name() … … 5133 5128 #endif 5134 5129 } 5135 r_dcache_fsm 5130 r_dcache_fsm = DCACHE_IDLE; 5136 5131 } 5137 5132 break; … … 5146 5141 // The return state is defined in r_dcache_fsm_cc_save 5147 5142 { 5148 paddr_t paddr = r_cc_receive_dcache_nline.read() * m_dcache_words * 4; 5149 paddr_t mask = ~((m_dcache_words<<2)-1); 5150 5151 //#if DEBUG_DCACHE 5152 //if ( m_debug_activated ) 5153 //{ 5154 // std::cout << " <PROC " << name() << std::hex 5155 // << " DCACHE_CC_CHECK> paddr = " << paddr 5156 // << " r_dcache_vci_paddr = " << r_dcache_vci_paddr.read() 5157 // << " mask = " << mask 5158 // << " (r_dcache_fsm_cc_save == DCACHE_MISS_WAIT) = " 5159 // << (r_dcache_fsm_cc_save == DCACHE_MISS_WAIT) 5160 // << " (r_dcache_fsm_cc_save == DCACHE_MISS_DIR_UPDT) = " 5161 // << (r_dcache_fsm_cc_save == DCACHE_MISS_DIR_UPDT) 5162 // << " ((r_dcache_vci_paddr.read() & mask) == (paddr & mask)) = " 5163 // << ((r_dcache_vci_paddr.read() & mask) == (paddr & mask)) 5164 // << std::dec <<std::endl; 5165 //} 5166 //#endif 5143 paddr_t paddr = r_cc_receive_dcache_nline.read() * m_dcache_words * 4; 5144 paddr_t mask = ~((m_dcache_words << 2) - 1); 5145 5167 5146 // CLACK handler 5168 5147 // We switch the directory slot to EMPTY state and reset 5169 5148 // r_dcache_miss_clack if the cleanup ack is matching a pending miss. 5170 if ( r_dcache_clack_req.read())5171 { 5172 if ( m_dreq.valid) m_cost_data_miss_frz++;5149 if (r_dcache_clack_req.read()) 5150 { 5151 if (m_dreq.valid) m_cost_data_miss_frz++; 5173 5152 5174 5153 #ifdef INSTRUMENTATION 5175 m_cpt_dcache_dir_write++;5176 #endif 5177 r_dcache.write_dir( 5178 5179 5180 5154 m_cpt_dcache_dir_write++; 5155 #endif 5156 r_dcache.write_dir(0, 5157 r_dcache_clack_way.read(), 5158 r_dcache_clack_set.read(), 5159 CACHE_SLOT_STATE_EMPTY); 5181 5160 5182 5161 // STAT : WRITE ON ZOMBI NCC LINE 5183 r_dcache_zombi_ncc[r_dcache_clack_way.read() *m_dcache_sets+r_dcache_clack_set.read()] = false;5184 5185 if ( 5186 (r_dcache_miss_way.read() == r_dcache_clack_way.read()))5162 r_dcache_zombi_ncc[r_dcache_clack_way.read() * m_dcache_sets + r_dcache_clack_set.read()] = false; 5163 5164 if ((r_dcache_miss_set.read() == r_dcache_clack_set.read()) and 5165 (r_dcache_miss_way.read() == r_dcache_clack_way.read())) 5187 5166 { 5188 5167 r_dcache_miss_clack = false; … … 5195 5174 5196 5175 #if DEBUG_DCACHE 5197 if ( m_debug_activated ) 5198 { 5199 std::cout << " <PROC " << name() 5200 << " DCACHE_CC_CHECK> CC_TYPE_CLACK Switch slot to EMPTY state" 5201 << " set = " << r_dcache_clack_set.read() 5202 << " / way = " << r_dcache_clack_way.read() << std::endl; 5203 } 5204 #endif 5205 break; 5206 } 5207 5176 if (m_debug_activated) 5177 { 5178 std::cout << " <PROC " << name() 5179 << " DCACHE_CC_CHECK> CLACK for PADDR " << std::hex << paddr 5180 << " Switch slot to EMPTY state : " 5181 << " set = " << std::dec << r_dcache_clack_set.read() 5182 << " / way = " << r_dcache_clack_way.read() << std::endl; 5183 } 5184 #endif 5185 break; 5186 } 5187 5188 assert(not r_dcache_cc_send_req.read() and 5189 "CC_SEND must be available in DCACHE_CC_CHECK"); 5208 5190 5209 5191 // Match between MISS address and CC address … … 5211 5193 // because the CLACK access the directory but the MISS match dont. 5212 5194 if (r_cc_receive_dcache_req.read() and 5213 ((r_dcache_fsm_cc_save == DCACHE_MISS_SELECT 5214 (r_dcache_fsm_cc_save == DCACHE_MISS_WAIT 5195 ((r_dcache_fsm_cc_save == DCACHE_MISS_SELECT) or 5196 (r_dcache_fsm_cc_save == DCACHE_MISS_WAIT) or 5215 5197 (r_dcache_fsm_cc_save == DCACHE_MISS_DIR_UPDT)) and 5216 5198 ((r_dcache_vci_paddr.read() & mask) == (paddr & mask))) // matching … … 5223 5205 if (r_cc_receive_dcache_type.read() == CC_TYPE_UPDT) 5224 5206 { 5225 r_dcache_fsm 5226 r_dcache_cc_word 5207 r_dcache_fsm = DCACHE_CC_UPDT; 5208 r_dcache_cc_word = r_cc_receive_word_idx.read(); 5227 5209 5228 5210 // just pop the fifo , don't write in icache … … 5237 5219 5238 5220 #if DEBUG_DCACHE 5239 if ( m_debug_activated ) 5240 { 5241 std::cout << " <PROC " << name() 5242 << " DCACHE_CC_CHECK> Coherence request matching a pending miss:" 5243 << " PADDR = " << std::hex << paddr << std::endl; 5244 } 5245 #endif 5246 } 5247 5248 5249 assert ( not r_dcache_cc_send_req.read() and "CC_SEND must be available in DCACHE_CC_CHECK" ); 5221 if (m_debug_activated) 5222 { 5223 std::cout << " <PROC " << name() 5224 << " DCACHE_CC_CHECK> Coherence request matching a pending miss:" 5225 << " PADDR = " << std::hex << paddr << std::endl; 5226 } 5227 #endif 5228 } 5250 5229 5251 5230 // CC request handler … … 5257 5236 5258 5237 #ifdef INSTRUMENTATION 5259 m_cpt_dcache_dir_read++;5260 #endif 5261 r_dcache.read_dir( 5262 5263 5264 5265 &word); // unused5238 m_cpt_dcache_dir_read++; 5239 #endif 5240 r_dcache.read_dir(paddr, 5241 &state, 5242 &way, 5243 &set, 5244 &word); // unused 5266 5245 5267 5246 r_dcache_cc_state = state; … … 5269 5248 r_dcache_cc_set = set; 5270 5249 5271 if ((state == CACHE_SLOT_STATE_VALID_CC) or (state == CACHE_SLOT_STATE_VALID_NCC)) // hit 5250 if ((state == CACHE_SLOT_STATE_VALID_CC) or 5251 (state == CACHE_SLOT_STATE_VALID_NCC)) // hit 5272 5252 { 5273 5253 // need to update the cache state … … 5276 5256 if (r_cc_receive_dcache_type.read() == CC_TYPE_UPDT) // hit update 5277 5257 { 5278 r_dcache_fsm 5279 r_dcache_cc_word 5258 r_dcache_fsm = DCACHE_CC_UPDT; 5259 r_dcache_cc_word = r_cc_receive_word_idx.read(); 5280 5260 } 5281 5261 else if (r_cc_receive_dcache_type.read() == CC_TYPE_INVAL) // hit inval … … 5283 5263 if (state == CACHE_SLOT_STATE_VALID_NCC) 5284 5264 { 5285 r_dcache_cc_inval_addr = (paddr & ~0x3F);5265 r_dcache_cc_inval_addr = (paddr & ~0x3F); 5286 5266 r_dcache_cc_inval_data_cpt = 0; 5287 5267 } 5288 r_dcache_fsm 5289 r_dcache_dirty_save 5268 r_dcache_fsm = DCACHE_CC_INVAL; 5269 r_dcache_dirty_save = false; 5290 5270 } 5291 5271 } … … 5293 5273 { 5294 5274 // multicast acknowledgement required in case of update 5295 if (r_cc_receive_dcache_type.read() == CC_TYPE_UPDT)5296 { 5297 r_dcache_fsm 5298 r_dcache_cc_word 5275 if (r_cc_receive_dcache_type.read() == CC_TYPE_UPDT) 5276 { 5277 r_dcache_fsm = DCACHE_CC_UPDT; 5278 r_dcache_cc_word = r_cc_receive_word_idx.read(); 5299 5279 5300 5280 // just pop the fifo , don't write in icache … … 5309 5289 5310 5290 #if DEBUG_DCACHE 5311 if ( m_debug_activated)5312 {5313 std::cout << " <PROC " << name()5314 << " DCACHE_CC_CHECK> Coherence request received:"5315 << " PADDR = " << std::hex << paddr5316 << " / TYPE = " << std::dec << r_cc_receive_dcache_type.read()5317 << " / HIT = " << ((state == CACHE_SLOT_STATE_VALID_CC) or (state == CACHE_SLOT_STATE_VALID_NCC)) << std::endl;5318 }5291 if (m_debug_activated) 5292 { 5293 std::cout << " <PROC " << name() 5294 << " DCACHE_CC_CHECK> Coherence request received:" 5295 << " PADDR = " << std::hex << paddr 5296 << " / TYPE = " << std::dec << r_cc_receive_dcache_type.read() 5297 << " / HIT = " << ((state == CACHE_SLOT_STATE_VALID_CC) or (state == CACHE_SLOT_STATE_VALID_NCC)) << std::endl; 5298 } 5319 5299 #endif 5320 5300 5321 5301 break; 5322 5302 } 5323 5324 5303 ///////////////////// 5325 5304 case DCACHE_CC_INVAL: // hit inval: switch slot to ZOMBI state and send a … … 5327 5306 // TLBs 5328 5307 { 5329 size_t way 5330 size_t set 5331 int 5332 bool 5308 size_t way = r_dcache_cc_way.read(); 5309 size_t set = r_dcache_cc_set.read(); 5310 int cache_state = r_dcache_cc_state.read(); 5311 bool dirty_save = false; 5333 5312 5334 5313 if (r_dcache_cc_need_write.read()) 5335 5314 { 5336 if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_IN_TLB)5337 { 5338 r_dcache_content_state[way *m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY;//need to remember it was dirty for cleanup5315 if (r_dcache_content_state[way * m_dcache_sets + set] == LINE_CACHE_IN_TLB) 5316 { 5317 r_dcache_content_state[way * m_dcache_sets + set] = LINE_CACHE_DATA_NOT_DIRTY; //need to remember it was dirty for cleanup 5339 5318 dirty_save = true; 5340 5319 r_dcache_dirty_save = true; 5341 r_dcache_tlb_inval_line 5342 r_dcache_tlb_inval_set 5343 r_dcache_fsm_scan_save 5344 r_dcache_fsm 5320 r_dcache_tlb_inval_line = r_cc_receive_dcache_nline.read(); 5321 r_dcache_tlb_inval_set = 0; 5322 r_dcache_fsm_scan_save = r_dcache_fsm.read(); 5323 r_dcache_fsm = DCACHE_INVAL_TLB_SCAN; 5345 5324 break; 5346 5325 } 5347 5326 else 5348 5327 { 5349 if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_CONTAINS_PTD)5328 if (r_dcache_content_state[way * m_dcache_sets + set] == LINE_CACHE_CONTAINS_PTD) 5350 5329 { 5351 5330 r_itlb.reset(); 5352 5331 r_dtlb.reset(); 5353 r_dcache_content_state[way *m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY;5332 r_dcache_content_state[way * m_dcache_sets + set] = LINE_CACHE_DATA_NOT_DIRTY; 5354 5333 dirty_save = true; 5355 5334 r_dcache_dirty_save = true; 5356 5335 #if DEBUG_DCACHE 5357 if ( m_debug_activated)5358 {5359 std::cout << " <PROC " << name()5360 << " DCACHE_CC_INVAL> Flush DTLB & ITLB" << std::endl;5361 }5336 if (m_debug_activated) 5337 { 5338 std::cout << " <PROC " << name() 5339 << " DCACHE_CC_INVAL> Flush DTLB & ITLB" << std::endl; 5340 } 5362 5341 #endif 5363 5342 } … … 5365 5344 // If the type of inval request from Memcache is configuration 5366 5345 // (software), we send a classic CLEANUP 5367 if (cache_state == CACHE_SLOT_STATE_VALID_CC or r_cc_receive_dcache_inval_is_config.read())5368 {5369 r_dcache.write_dir( way,5370 set,5371 CACHE_SLOT_STATE_ZOMBI );5372 }5373 5346 if (cache_state == CACHE_SLOT_STATE_VALID_CC or 5347 r_cc_receive_dcache_inval_is_config.read()) 5348 { 5349 r_dcache.write_dir(way, 5350 set, 5351 CACHE_SLOT_STATE_ZOMBI); 5352 } 5374 5353 r_dcache_cc_need_write = false; 5375 5354 } 5376 5355 } 5377 assert (not r_dcache_cc_send_req.read() &&5378 5379 5356 assert(not r_dcache_cc_send_req.read() and 5357 "ERROR in DCACHE_CC_INVAL: the r_dcache_cc_send_req " 5358 "must not be set"); 5380 5359 // coherence request completed 5381 5360 r_cc_receive_dcache_req = false; … … 5386 5365 r_dcache_cc_send_type = CC_TYPE_CLEANUP; 5387 5366 5388 if (cache_state == CACHE_SLOT_STATE_VALID_NCC and not r_cc_receive_dcache_inval_is_config.read()) 5367 if (cache_state == CACHE_SLOT_STATE_VALID_NCC and 5368 not r_cc_receive_dcache_inval_is_config.read()) 5389 5369 { 5390 5370 r_dcache_cc_cleanup_line_ncc = true; 5391 if ((r_dcache_content_state[way*m_dcache_sets+set] != LINE_CACHE_DATA_NOT_DIRTY) or r_dcache_dirty_save.read() or dirty_save) //must send data 5371 if ((r_dcache_content_state[way * m_dcache_sets + set] != LINE_CACHE_DATA_NOT_DIRTY) or 5372 r_dcache_dirty_save.read() or 5373 dirty_save) //must send data 5392 5374 { 5393 5375 r_dcache_cc_cleanup_updt_data = true; 5394 for (size_t w = 0; w < m_dcache_words; w++)5395 { 5396 m_cpt_cleanup_data_dirty_word += r_dcache_dirty_word[(m_dcache_sets *way+set)*m_dcache_words + w];5397 } 5398 5399 r_dcache_fsm 5376 for (size_t w = 0; w < m_dcache_words; w++) 5377 { 5378 m_cpt_cleanup_data_dirty_word += r_dcache_dirty_word[(m_dcache_sets * way + set) * m_dcache_words + w]; 5379 } 5380 5381 r_dcache_fsm = DCACHE_CC_INVAL_DATA; 5400 5382 } 5401 5383 else 5402 5384 { 5403 r_dcache.write_dir( 5404 5405 CACHE_SLOT_STATE_ZOMBI);5385 r_dcache.write_dir(way, 5386 set, 5387 CACHE_SLOT_STATE_ZOMBI); 5406 5388 5407 5389 r_dcache_cc_cleanup_updt_data = false; … … 5417 5399 break; 5418 5400 } 5419 5420 5401 ///////////////////// 5421 5402 case DCACHE_CC_INVAL_DATA: … … 5423 5404 5424 5405 uint32_t rdata; 5425 size_t 5426 size_t 5427 size_t 5406 size_t way = 0; // to avoid gcc warning 5407 size_t set = 0; // to avoid gcc warning 5408 size_t word; 5428 5409 r_dcache.read_neutral(r_dcache_cc_inval_addr.read(), 5429 5410 &rdata, … … 5431 5412 &set, 5432 5413 &word); 5433 if (r_cc_send_data_fifo.wok())5414 if (r_cc_send_data_fifo.wok()) 5434 5415 { 5435 5416 r_dcache_cc_inval_addr = r_dcache_cc_inval_addr.read() + 4; 5436 5417 5437 cleanup_data_updt_fifo_dcache_put 5438 cleanup_data_updt_fifo_dcache_data 5418 cleanup_data_updt_fifo_dcache_put = true; 5419 cleanup_data_updt_fifo_dcache_data = rdata; 5439 5420 5440 5421 r_dcache_cc_inval_data_cpt = r_dcache_cc_inval_data_cpt.read() + 1; 5441 if (r_dcache_cc_inval_data_cpt.read() == (m_dcache_words - 1))5422 if (r_dcache_cc_inval_data_cpt.read() == (m_dcache_words - 1)) 5442 5423 { 5443 5424 r_dcache_cc_inval_data_cpt = 0; 5444 r_dcache_fsm 5425 r_dcache_fsm = r_dcache_fsm_cc_save.read(); 5445 5426 r_dcache.write_dir(way, 5446 5427 set, 5447 CACHE_SLOT_STATE_ZOMBI 5428 CACHE_SLOT_STATE_ZOMBI); 5448 5429 } 5449 5430 } … … 5451 5432 } 5452 5433 /////////////////// 5453 case DCACHE_CC_UPDT: 5454 5455 { 5456 size_t word 5457 size_t way 5458 size_t set 5459 5460 5461 5462 if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_IN_TLB)5463 5464 r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY;5465 r_dcache_tlb_inval_line= r_cc_receive_dcache_nline.read();5466 r_dcache_tlb_inval_set= 0;5467 r_dcache_fsm_scan_save= r_dcache_fsm.read();5468 r_dcache_fsm= DCACHE_INVAL_TLB_SCAN;5469 5470 5471 if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_CONTAINS_PTD)5472 5473 5474 5475 r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY;5434 case DCACHE_CC_UPDT: // hit update: write one word per cycle, 5435 // after possible invalidation of copies in TLBs 5436 { 5437 size_t word = r_dcache_cc_word.read(); 5438 size_t way = r_dcache_cc_way.read(); 5439 size_t set = r_dcache_cc_set.read(); 5440 5441 if (r_dcache_cc_need_write.read()) 5442 { 5443 if (r_dcache_content_state[way * m_dcache_sets + set] == LINE_CACHE_IN_TLB) 5444 { 5445 r_dcache_content_state[way * m_dcache_sets + set] = LINE_CACHE_DATA_NOT_DIRTY; 5446 r_dcache_tlb_inval_line = r_cc_receive_dcache_nline.read(); 5447 r_dcache_tlb_inval_set = 0; 5448 r_dcache_fsm_scan_save = r_dcache_fsm.read(); 5449 r_dcache_fsm = DCACHE_INVAL_TLB_SCAN; 5450 break; 5451 } 5452 if (r_dcache_content_state[way * m_dcache_sets + set] == LINE_CACHE_CONTAINS_PTD) 5453 { 5454 r_itlb.reset(); 5455 r_dtlb.reset(); 5456 r_dcache_content_state[way * m_dcache_sets + set] = LINE_CACHE_DATA_NOT_DIRTY; 5476 5457 5477 5458 #if DEBUG_DCACHE 5478 if ( m_debug_activated)5479 {5480 std::cout << " <PROC " << name()5481 << " DCACHE_CC_UPDT> Flush DTLB & ITLB" << std::endl;5482 }5483 #endif 5484 5485 5486 assert(not r_dcache_cc_send_req.read() &&5487 5488 5489 5490 if ( not r_cc_receive_updt_fifo_be.rok()) break;5459 if (m_debug_activated) 5460 { 5461 std::cout << " <PROC " << name() 5462 << " DCACHE_CC_UPDT> Flush DTLB & ITLB" << std::endl; 5463 } 5464 #endif 5465 } 5466 5467 assert(not r_dcache_cc_send_req.read() && 5468 "ERROR in DCACHE_CC_INVAL: the r_dcache_cc_send_req " 5469 "must not be set"); 5470 5471 if (not r_cc_receive_updt_fifo_be.rok()) break; 5491 5472 5492 5473 #ifdef INSTRUMENTATION 5493 m_cpt_dcache_data_write++;5494 #endif 5495 r_dcache.write( 5496 5497 5498 5499 r_cc_receive_updt_fifo_be.read());5474 m_cpt_dcache_data_write++; 5475 #endif 5476 r_dcache.write(way, 5477 set, 5478 word, 5479 r_cc_receive_updt_fifo_data.read(), 5480 r_cc_receive_updt_fifo_be.read()); 5500 5481 5501 5482 r_dcache_cc_word = word + 1; 5502 5483 5503 5484 #if DEBUG_DCACHE 5504 if ( m_debug_activated)5505 {5506 std::cout << " <PROC " << name()5507 << " DCACHE_CC_UPDT> Write one word" << std::dec5508 << " / WAY = " << way5509 << " / SET = " << set5510 << " / WORD = " << word5511 << " / VALUE = " << std::hex << r_cc_receive_updt_fifo_data.read() << std::endl;5512 }5513 #endif 5514 } 5515 5516 if ( not r_cc_receive_updt_fifo_be.rok()) break;5517 5518 if ( r_cc_receive_updt_fifo_eop.read()) // last word5485 if (m_debug_activated) 5486 { 5487 std::cout << " <PROC " << name() 5488 << " DCACHE_CC_UPDT> Write one word" << std::dec 5489 << " / WAY = " << way 5490 << " / SET = " << set 5491 << " / WORD = " << word 5492 << " / VALUE = " << std::hex << r_cc_receive_updt_fifo_data.read() << std::endl; 5493 } 5494 #endif 5495 } 5496 5497 if (not r_cc_receive_updt_fifo_be.rok()) break; 5498 5499 if (r_cc_receive_updt_fifo_eop.read()) // last word 5519 5500 { 5520 5501 // no need to write in the cache anymore … … 5528 5509 r_dcache_cc_send_updt_tab_idx = r_cc_receive_dcache_updt_tab_idx.read(); 5529 5510 r_dcache_cc_send_type = CC_TYPE_MULTI_ACK; 5530 5531 5511 r_dcache_fsm = r_dcache_fsm_cc_save.read(); 5532 5512 } … … 5538 5518 } 5539 5519 /////////////////////////// 5540 case DCACHE_INVAL_TLB_SCAN: 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5520 case DCACHE_INVAL_TLB_SCAN: // Scan sequencially all sets for both ITLB & DTLB 5521 // It makes assumption: m_itlb_sets == m_dtlb_sets 5522 // All ways are handled in parallel. 5523 // We enter this state when a DCACHE line is modified, 5524 // and there is a copy in itlb or dtlb. 5525 // It can be caused by: 5526 // - a coherence inval or updt transaction, 5527 // - a line inval caused by a cache miss 5528 // - a processor XTN inval request, 5529 // - a WRITE hit, 5530 // - a Dirty bit update 5531 // Input arguments are: 5532 // - r_dcache_tlb_inval_line 5533 // - r_dcache_tlb_inval_set 5534 // - r_dcache_fsm_scan_save 5555 5535 { 5556 5536 paddr_t line = r_dcache_tlb_inval_line.read(); 5557 size_t set= r_dcache_tlb_inval_set.read();5558 size_t 5559 bool 5560 5561 for ( way = 0 ; way < m_itlb_ways ; way++)5562 { 5563 ok = r_itlb.inval( line, way, set);5537 size_t set = r_dcache_tlb_inval_set.read(); 5538 size_t way; 5539 bool ok; 5540 5541 for (way = 0; way < m_itlb_ways; way++) 5542 { 5543 ok = r_itlb.inval(line, way, set); 5564 5544 5565 5545 #if DEBUG_DCACHE 5566 if ( m_debug_activated and ok)5567 {5568 std::cout << " <PROC " << name()5569 << ".DCACHE_INVAL_TLB_SCAN> Invalidate ITLB entry:" << std::hex5570 << " line = " << line << std::dec5571 << " / set = " << set5572 << " / way = " << way << std::endl;5573 }5574 #endif 5575 } 5576 5577 for ( way = 0 ; way < m_dtlb_ways ; way++)5578 { 5579 ok = r_dtlb.inval( line, way, set);5546 if (m_debug_activated and ok) 5547 { 5548 std::cout << " <PROC " << name() 5549 << ".DCACHE_INVAL_TLB_SCAN> Invalidate ITLB entry:" << std::hex 5550 << " line = " << line << std::dec 5551 << " / set = " << set 5552 << " / way = " << way << std::endl; 5553 } 5554 #endif 5555 } 5556 5557 for (way = 0; way < m_dtlb_ways; way++) 5558 { 5559 ok = r_dtlb.inval(line, way, set); 5580 5560 5581 5561 #if DEBUG_DCACHE 5582 if ( m_debug_activated and ok ) 5583 std::cout << " <PROC " << name() << " DCACHE_INVAL_TLB_SCAN>" 5584 << " Invalidate DTLB entry" << std::hex 5585 << " / line = " << line << std::dec 5586 << " / set = " << set 5587 << " / way = " << way << std::endl; 5562 if (m_debug_activated and ok) 5563 { 5564 std::cout << " <PROC " << name() << " DCACHE_INVAL_TLB_SCAN>" 5565 << " Invalidate DTLB entry" << std::hex 5566 << " / line = " << line << std::dec 5567 << " / set = " << set 5568 << " / way = " << way << std::endl; 5569 } 5588 5570 #endif 5589 5571 } 5590 5572 5591 5573 // return to the calling state when TLB inval completed 5592 if ( r_dcache_tlb_inval_set.read() == (m_dtlb_sets-1))5574 if (r_dcache_tlb_inval_set.read() == (m_dtlb_sets - 1)) 5593 5575 { 5594 5576 r_dcache_fsm = r_dcache_fsm_scan_save.read(); … … 5609 5591 // The simulation exit if the number of consecutive frozen cycles 5610 5592 // is larger than the m_max_frozen_cycles (constructor parameter) 5611 if ( (m_ireq.valid and not m_irsp.valid) or (m_dreq.valid and not m_drsp.valid))5612 { 5613 m_cpt_frz_cycles++; 5614 m_cpt_stop_simulation++; 5615 if ( m_cpt_stop_simulation > m_max_frozen_cycles)5593 if ((m_ireq.valid and not m_irsp.valid) or (m_dreq.valid and not m_drsp.valid)) 5594 { 5595 m_cpt_frz_cycles++; // used for instrumentation 5596 m_cpt_stop_simulation++; // used for debug 5597 if (m_cpt_stop_simulation > m_max_frozen_cycles) 5616 5598 { 5617 5599 std::cout << std::dec << "ERROR in CC_VCACHE_WRAPPER " << name() << std::endl … … 5630 5612 /////////// execute one iss cycle ///////////////////////////////// 5631 5613 { 5632 uint32_t it = 0;5633 for (size_t i=0; i<(size_t)iss_t::n_irq; i++) if(p_irq[i].read()) it |= (1<<i);5634 r_iss.executeNCycles(1, m_irsp, m_drsp, it);5614 uint32_t it = 0; 5615 for (size_t i = 0; i < (size_t) iss_t::n_irq; i++) if (p_irq[i].read()) it |= (1 << i); 5616 r_iss.executeNCycles(1, m_irsp, m_drsp, it); 5635 5617 } 5636 5618 … … 5676 5658 5677 5659 5678 switch ( r_vci_cmd_fsm.read())5660 switch (r_vci_cmd_fsm.read()) 5679 5661 { 5680 5662 ////////////// … … 5688 5670 // using the r_vci_cmd_imiss_prio flip-flop. 5689 5671 5690 size_t 5691 size_t 5672 size_t wbuf_min; 5673 size_t wbuf_max; 5692 5674 5693 5675 bool dcache_miss_req = r_dcache_vci_miss_req.read() and 5694 ( not r_icache_miss_req.read() or not r_vci_cmd_imiss_prio.read());5695 5696 bool dcache_ll_req 5697 ( not r_icache_miss_req.read() or not r_vci_cmd_imiss_prio.read());5698 5699 bool dcache_sc_req 5700 ( not r_icache_miss_req.read() or not r_vci_cmd_imiss_prio.read());5701 5702 bool dcache_cas_req 5703 ( not r_icache_miss_req.read() or not r_vci_cmd_imiss_prio.read());5676 (not r_icache_miss_req.read() or not r_vci_cmd_imiss_prio.read()); 5677 5678 bool dcache_ll_req = r_dcache_vci_ll_req.read() and 5679 (not r_icache_miss_req.read() or not r_vci_cmd_imiss_prio.read()); 5680 5681 bool dcache_sc_req = r_dcache_vci_sc_req.read() and 5682 (not r_icache_miss_req.read() or not r_vci_cmd_imiss_prio.read()); 5683 5684 bool dcache_cas_req = r_dcache_vci_cas_req.read() and 5685 (not r_icache_miss_req.read() or not r_vci_cmd_imiss_prio.read()); 5704 5686 5705 5687 bool icache_miss_req = r_icache_miss_req.read() and 5706 ( 5707 5708 5709 r_dcache_vci_sc_req.read())5710 or r_vci_cmd_imiss_prio.read());5688 (not (r_dcache_vci_miss_req.read() or 5689 r_dcache_vci_ll_req.read() or 5690 r_dcache_vci_cas_req.read() or 5691 r_dcache_vci_sc_req.read()) or 5692 r_vci_cmd_imiss_prio.read()); 5711 5693 5712 5694 // 1 - Data unc write 5713 if ( 5695 if (r_dcache_vci_unc_req.read() and r_dcache_vci_unc_write.read()) 5714 5696 { 5715 5697 r_vci_cmd_fsm = CMD_DATA_UNC_WRITE; 5716 5698 r_dcache_vci_unc_req = false; 5717 // m_cpt_dunc_transaction++;5718 5699 } 5719 5700 // 2 data read miss 5720 else if ( dcache_miss_req and r_wbuf.miss(r_dcache_vci_paddr.read()))5701 else if (dcache_miss_req and r_wbuf.miss(r_dcache_vci_paddr.read())) 5721 5702 { 5722 5703 r_vci_cmd_fsm = CMD_DATA_MISS; 5723 5704 r_dcache_vci_miss_req = false; 5724 5705 r_vci_cmd_imiss_prio = true; 5725 m_cpt_dmiss_transaction++;5726 5706 } 5727 5707 // 3 - Data Read Uncachable 5728 else if ( r_dcache_vci_unc_req.read() and not r_dcache_vci_unc_write.read())5708 else if (r_dcache_vci_unc_req.read() and not r_dcache_vci_unc_write.read()) 5729 5709 { 5730 5710 r_vci_cmd_fsm = CMD_DATA_UNC_READ; 5731 5711 r_dcache_vci_unc_req = false; 5732 m_cpt_dunc_transaction++;5733 5712 } 5734 5713 // 4 - Data Linked Load 5735 else if ( 5714 else if (dcache_ll_req and r_wbuf.miss(r_dcache_vci_paddr.read())) 5736 5715 { 5737 5716 r_vci_cmd_fsm = CMD_DATA_LL; 5738 5717 r_dcache_vci_ll_req = false; 5739 5718 r_vci_cmd_imiss_prio = true; 5740 m_cpt_ll_transaction++;5741 5719 } 5742 5720 // 5 - Instruction Miss 5743 else if ( icache_miss_req and r_wbuf.miss(r_icache_vci_paddr.read()))5721 else if (icache_miss_req and r_wbuf.miss(r_icache_vci_paddr.read())) 5744 5722 { 5745 5723 r_vci_cmd_fsm = CMD_INS_MISS; 5746 5724 r_icache_miss_req = false; 5747 5725 r_vci_cmd_imiss_prio = false; 5748 m_cpt_imiss_transaction++;5749 5726 } 5750 5727 // 6 - Instruction Uncachable 5751 else if ( r_icache_unc_req.read() ) 5752 { 5753 r_vci_cmd_fsm = CMD_INS_UNC; 5754 r_icache_unc_req = false; 5755 //m_cpt_iunc_transaction++; 5728 else if (r_icache_unc_req.read()) 5729 { 5730 r_vci_cmd_fsm = CMD_INS_UNC; 5731 r_icache_unc_req = false; 5756 5732 } 5757 5733 // 7 - Data Write 5758 else if ( r_wbuf.rok(&wbuf_min, &wbuf_max))5759 { 5760 r_vci_cmd_fsm 5761 r_vci_cmd_cpt 5762 r_vci_cmd_min 5763 r_vci_cmd_max 5734 else if (r_wbuf.rok(&wbuf_min, &wbuf_max)) 5735 { 5736 r_vci_cmd_fsm = CMD_DATA_WRITE; 5737 r_vci_cmd_cpt = wbuf_min; 5738 r_vci_cmd_min = wbuf_min; 5739 r_vci_cmd_max = wbuf_max; 5764 5740 m_cpt_write_transaction++; 5765 m_length_write_transaction += (wbuf_max -wbuf_min+1);5741 m_length_write_transaction += (wbuf_max - wbuf_min + 1); 5766 5742 } 5767 5743 // 8 - Data Store Conditionnal 5768 else if ( dcache_sc_req and r_wbuf.miss(r_dcache_vci_paddr.read()) ) 5769 { 5770 r_vci_cmd_fsm = CMD_DATA_SC; 5771 r_dcache_vci_sc_req = false; 5772 r_vci_cmd_imiss_prio = true; 5773 r_vci_cmd_cpt = 0; 5774 //m_cpt_sc_transaction++; 5744 else if (dcache_sc_req and r_wbuf.miss(r_dcache_vci_paddr.read())) 5745 { 5746 r_vci_cmd_fsm = CMD_DATA_SC; 5747 r_dcache_vci_sc_req = false; 5748 r_vci_cmd_imiss_prio = true; 5749 r_vci_cmd_cpt = 0; 5775 5750 } 5776 5751 // 9 - Compare And Swap 5777 else if ( dcache_cas_req and r_wbuf.miss(r_dcache_vci_paddr.read()) ) 5778 { 5779 r_vci_cmd_fsm = CMD_DATA_CAS; 5780 r_dcache_vci_cas_req = false; 5781 r_vci_cmd_imiss_prio = true; 5782 r_vci_cmd_cpt = 0; 5783 //m_cpt_cas_transaction++; 5752 else if (dcache_cas_req and r_wbuf.miss(r_dcache_vci_paddr.read())) 5753 { 5754 r_vci_cmd_fsm = CMD_DATA_CAS; 5755 r_dcache_vci_cas_req = false; 5756 r_vci_cmd_imiss_prio = true; 5757 r_vci_cmd_cpt = 0; 5784 5758 } 5785 5759 5786 5760 #if DEBUG_CMD 5787 if ( m_debug_activated)5788 {5789 std::cout << " <PROC " << name() << " CMD_IDLE>"5790 << " / dmiss_req = " << dcache_miss_req5791 << " / imiss_req = " << icache_miss_req5792 << std::endl;5793 }5761 if (m_debug_activated) 5762 { 5763 std::cout << " <PROC " << name() << " CMD_IDLE>" 5764 << " / dmiss_req = " << dcache_miss_req 5765 << " / imiss_req = " << icache_miss_req 5766 << std::endl; 5767 } 5794 5768 #endif 5795 5769 break; … … 5798 5772 case CMD_DATA_WRITE: 5799 5773 { 5800 if ( p_vci.cmdack.read())5774 if (p_vci.cmdack.read()) 5801 5775 { 5802 5776 r_vci_cmd_cpt = r_vci_cmd_cpt + 1; 5803 5777 if (r_vci_cmd_cpt == r_vci_cmd_max) // last flit sent 5804 5778 { 5805 r_vci_cmd_fsm = CMD_IDLE 5806 r_wbuf.sent() 5779 r_vci_cmd_fsm = CMD_IDLE; 5780 r_wbuf.sent(); 5807 5781 } 5808 5782 } … … 5814 5788 { 5815 5789 // The CAS and SC VCI commands contain two flits 5816 if ( p_vci.cmdack.read())5790 if (p_vci.cmdack.read()) 5817 5791 { 5818 5792 r_vci_cmd_cpt = r_vci_cmd_cpt + 1; … … 5830 5804 { 5831 5805 // all read VCI commands contain one single flit 5832 if ( p_vci.cmdack.read()) {5806 if (p_vci.cmdack.read()) { 5833 5807 r_vci_cmd_fsm = CMD_IDLE; 5834 5808 } … … 5865 5839 ////////////////////////////////////////////////////////////////////////// 5866 5840 5867 switch ( r_vci_rsp_fsm.read())5841 switch (r_vci_rsp_fsm.read()) 5868 5842 { 5869 5843 ////////////// 5870 5844 case RSP_IDLE: 5871 5845 { 5872 if ( p_vci.rspval.read())5846 if (p_vci.rspval.read()) 5873 5847 { 5874 5848 r_vci_rsp_cpt = 0; 5875 if (r_dcache_vci_paddr.read() == 0x1f624) std::cout << "Tansaction on barrier, pktid = " << p_vci.rpktid.read() << std::endl; 5876 if ( (p_vci.rpktid.read() & 0x7) == TYPE_DATA_UNC)5849 5850 if ((p_vci.rpktid.read() & 0x7) == TYPE_DATA_UNC) 5877 5851 { 5878 5852 r_vci_rsp_fsm = RSP_DATA_UNC; 5879 5853 } 5880 else if ( (p_vci.rpktid.read() & 0x7) == TYPE_READ_DATA_MISS)5854 else if ((p_vci.rpktid.read() & 0x7) == TYPE_READ_DATA_MISS) 5881 5855 { 5882 5856 r_vci_rsp_fsm = RSP_DATA_MISS; 5883 5857 } 5884 else if ( (p_vci.rpktid.read() & 0x7) == TYPE_READ_INS_UNC)5858 else if ((p_vci.rpktid.read() & 0x7) == TYPE_READ_INS_UNC) 5885 5859 { 5886 5860 r_vci_rsp_fsm = RSP_INS_UNC; 5887 5861 } 5888 else if ( (p_vci.rpktid.read() & 0x7) == TYPE_READ_INS_MISS)5862 else if ((p_vci.rpktid.read() & 0x7) == TYPE_READ_INS_MISS) 5889 5863 { 5890 5864 r_vci_rsp_fsm = RSP_INS_MISS; 5891 5865 } 5892 else if ( (p_vci.rpktid.read() & 0x7) == TYPE_WRITE)5866 else if ((p_vci.rpktid.read() & 0x7) == TYPE_WRITE) 5893 5867 { 5894 5868 r_vci_rsp_fsm = RSP_DATA_WRITE; 5895 5869 } 5896 else if ( (p_vci.rpktid.read() & 0x7) == TYPE_CAS)5870 else if ((p_vci.rpktid.read() & 0x7) == TYPE_CAS) 5897 5871 { 5898 5872 r_vci_rsp_fsm = RSP_DATA_UNC; 5899 5873 } 5900 else if ( (p_vci.rpktid.read() & 0x7) == TYPE_LL)5874 else if ((p_vci.rpktid.read() & 0x7) == TYPE_LL) 5901 5875 { 5902 5876 r_vci_rsp_fsm = RSP_DATA_LL; 5903 5877 } 5904 else if ( (p_vci.rpktid.read() & 0x7) == TYPE_SC)5878 else if ((p_vci.rpktid.read() & 0x7) == TYPE_SC) 5905 5879 { 5906 5880 r_vci_rsp_fsm = RSP_DATA_UNC; … … 5916 5890 case RSP_INS_MISS: 5917 5891 { 5918 if ( p_vci.rspval.read())5919 { 5920 if ( (p_vci.rerror.read()&0x1) != 0) // error reported5892 if (p_vci.rspval.read()) 5893 { 5894 if ((p_vci.rerror.read() & 0x1) != 0) // error reported 5921 5895 { 5922 5896 r_vci_rsp_ins_error = true; 5923 if ( p_vci.reop.read()) r_vci_rsp_fsm = RSP_IDLE;5897 if (p_vci.reop.read()) r_vci_rsp_fsm = RSP_IDLE; 5924 5898 } 5925 5899 else // no error reported 5926 5900 { 5927 if ( r_vci_rsp_fifo_icache.wok())5901 if (r_vci_rsp_fifo_icache.wok()) 5928 5902 { 5929 if ( r_vci_rsp_cpt.read() >= m_icache_words)5903 if (r_vci_rsp_cpt.read() >= m_icache_words) 5930 5904 { 5931 5905 std::cout << "ERROR in VCI_CC_VCACHE " << name() … … 5934 5908 exit(0); 5935 5909 } 5936 r_vci_rsp_cpt 5937 vci_rsp_fifo_icache_put 5938 vci_rsp_fifo_icache_data 5939 if ( p_vci.reop.read())5910 r_vci_rsp_cpt = r_vci_rsp_cpt.read() + 1; 5911 vci_rsp_fifo_icache_put = true, 5912 vci_rsp_fifo_icache_data = p_vci.rdata.read(); 5913 if (p_vci.reop.read()) 5940 5914 { 5941 if ( r_vci_rsp_cpt.read() != (m_icache_words - 1))5915 if (r_vci_rsp_cpt.read() != (m_icache_words - 1)) 5942 5916 { 5943 5917 std::cout << "ERROR in VCI_CC_VCACHE " << name() … … 5946 5920 exit(0); 5947 5921 } 5948 r_vci_rsp_fsm 5922 r_vci_rsp_fsm = RSP_IDLE; 5949 5923 } 5950 5924 } … … 5956 5930 case RSP_INS_UNC: 5957 5931 { 5958 if (p_vci.rspval.read() 5959 { 5960 assert( 5932 if (p_vci.rspval.read()) 5933 { 5934 assert(p_vci.reop.read() and 5961 5935 "illegal VCI response packet for uncachable instruction"); 5962 5936 5963 if ( (p_vci.rerror.read()&0x1) != 0) // error reported5937 if ((p_vci.rerror.read() & 0x1) != 0) // error reported 5964 5938 { 5965 5939 r_vci_rsp_ins_error = true; … … 5968 5942 else // no error reported 5969 5943 { 5970 if ( 5944 if (r_vci_rsp_fifo_icache.wok()) 5971 5945 { 5972 vci_rsp_fifo_icache_put 5973 vci_rsp_fifo_icache_data 5946 vci_rsp_fifo_icache_put = true; 5947 vci_rsp_fifo_icache_data = p_vci.rdata.read(); 5974 5948 r_vci_rsp_fsm = RSP_IDLE; 5975 5949 } … … 5981 5955 case RSP_DATA_MISS: 5982 5956 { 5983 if ( p_vci.rspval.read())5984 { 5985 if ( (p_vci.rerror.read()&0x1) != 0) // error reported5957 if (p_vci.rspval.read()) 5958 { 5959 if ((p_vci.rerror.read() & 0x1) != 0) // error reported 5986 5960 { 5987 5961 r_vci_rsp_data_error = true; 5988 if ( p_vci.reop.read()) r_vci_rsp_fsm = RSP_IDLE;5962 if (p_vci.reop.read()) r_vci_rsp_fsm = RSP_IDLE; 5989 5963 } 5990 5964 else // no error reported 5991 5965 { 5992 5993 5994 if ( r_vci_rsp_fifo_dcache.wok() && r_vci_rsp_fifo_rpktid.wok()) 5966 if (r_vci_rsp_fifo_dcache.wok() and r_vci_rsp_fifo_rpktid.wok()) 5995 5967 { 5996 assert( 5968 assert((r_vci_rsp_cpt.read() < m_dcache_words) and 5997 5969 "The VCI response packet for data miss is too long"); 5998 5970 5999 r_vci_rsp_cpt 6000 vci_rsp_fifo_dcache_put 6001 vci_rsp_fifo_dcache_data 6002 vci_rsp_fifo_rpktid = (p_vci.rpktid.read() == 0x9);//RWT: interpretation of pktid for state (NCC or CC)6003 vci_rsp_fifo_rpktid_put = true;//RWT6004 6005 if ( p_vci.reop.read())5971 r_vci_rsp_cpt = r_vci_rsp_cpt.read() + 1; 5972 vci_rsp_fifo_dcache_put = true, 5973 vci_rsp_fifo_dcache_data = p_vci.rdata.read(); 5974 vci_rsp_fifo_rpktid = (p_vci.rpktid.read() == 0x9); //RWT: interpretation of pktid for state (NCC or CC) 5975 vci_rsp_fifo_rpktid_put = true; //RWT 5976 5977 if (p_vci.reop.read()) 6006 5978 { 6007 if (r_vci_rsp_cpt.read() != m_dcache_words - 1) std::cout << "assert on proc " << name() << std::endl; 6008 assert( (r_vci_rsp_cpt.read() == m_dcache_words - 1) and 5979 assert((r_vci_rsp_cpt.read() == m_dcache_words - 1) and 6009 5980 "The VCI response packet for data miss is too short"); 6010 5981 6011 r_vci_rsp_fsm 5982 r_vci_rsp_fsm = RSP_IDLE; 6012 5983 } 6013 5984 } … … 6019 5990 case RSP_DATA_UNC: 6020 5991 { 6021 if (p_vci.rspval.read() 6022 { 6023 assert( 5992 if (p_vci.rspval.read()) 5993 { 5994 assert(p_vci.reop.read() and 6024 5995 "illegal VCI response packet for uncachable read data"); 6025 5996 6026 if ( (p_vci.rerror.read()&0x1) != 0) // error reported5997 if ((p_vci.rerror.read() & 0x1) != 0) // error reported 6027 5998 { 6028 5999 r_vci_rsp_data_error = true; 6029 6000 r_vci_rsp_fsm = RSP_IDLE; 6030 6001 } 6031 else 6032 { 6033 if ( 6002 else // no error reported 6003 { 6004 if (r_vci_rsp_fifo_dcache.wok()) 6034 6005 { 6035 vci_rsp_fifo_dcache_put 6036 vci_rsp_fifo_dcache_data 6006 vci_rsp_fifo_dcache_put = true; 6007 vci_rsp_fifo_dcache_data = p_vci.rdata.read(); 6037 6008 r_vci_rsp_fsm = RSP_IDLE; 6038 6009 } … … 6044 6015 case RSP_DATA_LL: 6045 6016 { 6046 if ( p_vci.rspval.read())6047 { 6048 if ( (p_vci.rerror.read()&0x1) != 0) // error reported6017 if (p_vci.rspval.read()) 6018 { 6019 if ((p_vci.rerror.read() & 0x1) != 0) // error reported 6049 6020 { 6050 6021 r_vci_rsp_data_error = true; … … 6054 6025 if (r_vci_rsp_cpt.read() == 0) //first flit 6055 6026 { 6056 if (r_vci_rsp_fifo_dcache.wok())6027 if (r_vci_rsp_fifo_dcache.wok()) 6057 6028 { 6058 6029 assert(!p_vci.reop.read() && … … 6066 6037 else // last flit 6067 6038 { 6068 if (r_vci_rsp_fifo_dcache.wok())6039 if (r_vci_rsp_fifo_dcache.wok()) 6069 6040 { 6070 6041 assert(p_vci.reop.read() && … … 6084 6055 if (p_vci.rspval.read()) 6085 6056 { 6086 assert( 6057 assert(p_vci.reop.read() and 6087 6058 "a VCI response packet must contain one flit for a write transaction"); 6088 6059 6089 6060 r_vci_rsp_fsm = RSP_IDLE; 6090 uint32_t 6061 uint32_t wbuf_index = p_vci.rtrdid.read(); 6091 6062 r_wbuf.completed(wbuf_index); 6092 if ( (p_vci.rerror.read()&0x1) != 0) r_iss.setWriteBerr();6063 if ((p_vci.rerror.read() & 0x1) != 0) r_iss.setWriteBerr(); 6093 6064 } 6094 6065 break; … … 6103 6074 // soon as the request has been sent. 6104 6075 ///////////////////////////////////////////////////////////////////////////////////// 6105 switch ( r_cc_send_fsm.read())6076 switch (r_cc_send_fsm.read()) 6106 6077 { 6107 6078 /////////////////////////// … … 6115 6086 /////////////////////////////////////////////////////// 6116 6087 bool update_last_client = r_cc_send_last_client.read(); 6117 if ( r_cc_send_last_client.read() == 0) // last client was dcache6088 if (r_cc_send_last_client.read() == 0) // last client was dcache 6118 6089 { 6119 6090 if (r_icache_cc_send_req.read()) // request from icache … … 6131 6102 { 6132 6103 // the new client is dcache and has a cleanup request 6133 if ((update_last_client == 0) and6134 6104 if ((update_last_client == 0) and 6105 (r_dcache_cc_send_type.read() == CC_TYPE_CLEANUP)) 6135 6106 r_cc_send_fsm = CC_SEND_CLEANUP_1; 6136 6107 // the new client is dcache and has a multi acknowledgement request 6137 else if ( 6138 6108 else if ((update_last_client == 0) and 6109 (r_dcache_cc_send_type.read() == CC_TYPE_MULTI_ACK)) 6139 6110 r_cc_send_fsm = CC_SEND_MULTI_ACK; 6140 6111 // the new client is icache and has a cleanup request 6141 else if ( 6142 6112 else if ((update_last_client == 1) and 6113 (r_icache_cc_send_type.read() == CC_TYPE_CLEANUP)) 6143 6114 r_cc_send_fsm = CC_SEND_CLEANUP_1; 6144 6115 // the new client is icache and has a multi acknowledgement request 6145 else if ( 6116 else if ((update_last_client == 1) and 6146 6117 (r_icache_cc_send_type.read() == CC_TYPE_MULTI_ACK)) 6147 6118 r_cc_send_fsm = CC_SEND_MULTI_ACK; … … 6165 6136 { 6166 6137 6167 if(r_dcache_cc_cleanup_updt_data.read() and (r_cc_send_last_client.read() == 0))//dcache request with data 6138 if (r_dcache_cc_cleanup_updt_data.read() and 6139 (r_cc_send_last_client.read() == 0)) //dcache request with data 6168 6140 { 6169 6141 r_cc_send_fsm = CC_SEND_CLEANUP_DATA_UPDT; … … 6190 6162 if (p_dspin_p2m.read.read()) 6191 6163 { 6192 if (r_cc_send_data_fifo.rok())6164 if (r_cc_send_data_fifo.rok()) 6193 6165 { 6194 6166 m_cpt_data_cleanup++; 6195 6167 cleanup_data_updt_fifo_dcache_get = true; 6196 6168 r_cc_send_cpt_word = r_cc_send_cpt_word.read() + 1; 6197 if (r_cc_send_cpt_word.read() == m_dcache_words -1)6169 if (r_cc_send_cpt_word.read() == m_dcache_words - 1) 6198 6170 { 6199 6171 r_dcache_cc_send_req = false; … … 6210 6182 { 6211 6183 // wait for the flit to be consumed 6212 if (p_dspin_p2m.read.read())6213 { 6214 if (r_cc_send_last_client.read() == 0) // dcache active request6184 if (p_dspin_p2m.read.read()) 6185 { 6186 if (r_cc_send_last_client.read() == 0) // dcache active request 6215 6187 r_dcache_cc_send_req = false; // reset dcache request 6216 6188 else // icache active request … … 6233 6205 // - CC_BROADCAST : Broadcast invalidate request (both DCACHE & ICACHE) 6234 6206 ////////////////////////////////////////////////////////////////////////////// 6235 switch ( r_cc_receive_fsm.read())6207 switch (r_cc_receive_fsm.read()) 6236 6208 { 6237 6209 ///////////////////// … … 6247 6219 DspinRwtParam::M2P_TYPE); 6248 6220 // test for a broadcast 6249 if (DspinRwtParam::dspin_get(receive_data, DspinRwtParam::M2P_BC))6221 if (DspinRwtParam::dspin_get(receive_data, DspinRwtParam::M2P_BC)) 6250 6222 { 6251 6223 r_cc_receive_fsm = CC_RECEIVE_BRDCAST_HEADER; … … 6294 6266 // request dcache to handle the BROADCAST 6295 6267 r_cc_receive_dcache_req = true; 6296 r_cc_receive_dcache_nline 6268 r_cc_receive_dcache_nline = DspinRwtParam::dspin_get(receive_data, 6297 6269 DspinRwtParam::BROADCAST_NLINE); 6298 6270 r_cc_receive_dcache_type = CC_TYPE_INVAL; 6299 6271 // request icache to handle the BROADCAST 6300 6272 r_cc_receive_icache_req = true; 6301 r_cc_receive_icache_nline 6273 r_cc_receive_icache_nline = DspinRwtParam::dspin_get(receive_data, 6302 6274 DspinRwtParam::BROADCAST_NLINE); 6303 6275 r_cc_receive_icache_type = CC_TYPE_INVAL; … … 6333 6305 uint64_t receive_data = p_dspin_m2p.data.read(); 6334 6306 // for data INVAL, wait for dcache to take the request 6335 if (p_dspin_m2p.write.read() 6336 not r_cc_receive_dcache_req.read() 6307 if (p_dspin_m2p.write.read() and 6308 not r_cc_receive_dcache_req.read()) 6337 6309 { 6338 6310 // request dcache to handle the INVAL 6339 6311 r_cc_receive_dcache_req = true; 6340 r_cc_receive_dcache_nline = DspinRwtParam::dspin_get(receive_data, DspinRwtParam::MULTI_INVAL_NLINE);6312 r_cc_receive_dcache_nline = DspinRwtParam::dspin_get(receive_data, DspinRwtParam::MULTI_INVAL_NLINE); 6341 6313 r_cc_receive_dcache_type = CC_TYPE_INVAL; 6342 6314 // get back to idle state … … 6352 6324 uint64_t receive_data = p_dspin_m2p.data.read(); 6353 6325 // for ins INVAL, wait for icache to take the request 6354 if (p_dspin_m2p.write.read() 6355 not r_cc_receive_icache_req.read() 6326 if (p_dspin_m2p.write.read() and 6327 not r_cc_receive_icache_req.read()) 6356 6328 { 6357 6329 // request icache to handle the INVAL 6358 6330 r_cc_receive_icache_req = true; 6359 r_cc_receive_icache_nline = DspinRwtParam::dspin_get(receive_data, DspinRwtParam::MULTI_INVAL_NLINE);6331 r_cc_receive_icache_nline = DspinRwtParam::dspin_get(receive_data, DspinRwtParam::MULTI_INVAL_NLINE); 6360 6332 r_cc_receive_icache_type = CC_TYPE_INVAL; 6361 6333 // get back to idle state … … 6374 6346 if (not r_cc_receive_dcache_req.read()) 6375 6347 { 6376 r_cc_receive_dcache_updt_tab_idx = DspinRwtParam::dspin_get(receive_data,DspinRwtParam::MULTI_UPDT_UPDT_INDEX);6348 r_cc_receive_dcache_updt_tab_idx = DspinRwtParam::dspin_get(receive_data, DspinRwtParam::MULTI_UPDT_UPDT_INDEX); 6377 6349 r_cc_receive_fsm = CC_RECEIVE_DATA_UPDT_NLINE; 6378 6350 break; … … 6389 6361 if (not r_cc_receive_icache_req.read()) 6390 6362 { 6391 r_cc_receive_icache_updt_tab_idx = DspinRwtParam::dspin_get(receive_data,DspinRwtParam::MULTI_UPDT_UPDT_INDEX);6363 r_cc_receive_icache_updt_tab_idx = DspinRwtParam::dspin_get(receive_data, DspinRwtParam::MULTI_UPDT_UPDT_INDEX); 6392 6364 r_cc_receive_fsm = CC_RECEIVE_INS_UPDT_NLINE; 6393 6365 break; … … 6403 6375 // for data INVAL, wait for dcache to take the request and fifo to 6404 6376 // be empty 6405 if ( 6406 p_dspin_m2p.write.read() 6407 { 6408 r_cc_receive_dcache_req = true;6409 r_cc_receive_dcache_nline = DspinRwtParam::dspin_get(receive_data,DspinRwtParam::MULTI_UPDT_NLINE);6410 r_cc_receive_word_idx = DspinRwtParam::dspin_get(receive_data,DspinRwtParam::MULTI_UPDT_WORD_INDEX);6411 r_cc_receive_dcache_type = CC_TYPE_UPDT;6377 if (r_cc_receive_updt_fifo_be.empty() and 6378 p_dspin_m2p.write.read()) 6379 { 6380 r_cc_receive_dcache_req = true; 6381 r_cc_receive_dcache_nline = DspinRwtParam::dspin_get(receive_data, DspinRwtParam::MULTI_UPDT_NLINE); 6382 r_cc_receive_word_idx = DspinRwtParam::dspin_get(receive_data, DspinRwtParam::MULTI_UPDT_WORD_INDEX); 6383 r_cc_receive_dcache_type = CC_TYPE_UPDT; 6412 6384 // get back to idle state 6413 6385 r_cc_receive_fsm = CC_RECEIVE_DATA_UPDT_DATA; … … 6423 6395 // for ins INVAL, wait for icache to take the request and fifo to be 6424 6396 // empty 6425 if ( 6426 p_dspin_m2p.write.read() 6427 { 6428 r_cc_receive_icache_req = true;6429 r_cc_receive_icache_nline = DspinRwtParam::dspin_get(receive_data,DspinRwtParam::MULTI_UPDT_NLINE);6430 r_cc_receive_word_idx = DspinRwtParam::dspin_get(receive_data,DspinRwtParam::MULTI_UPDT_WORD_INDEX);6431 r_cc_receive_icache_type = CC_TYPE_UPDT;6397 if (r_cc_receive_updt_fifo_be.empty() and 6398 p_dspin_m2p.write.read()) 6399 { 6400 r_cc_receive_icache_req = true; 6401 r_cc_receive_icache_nline = DspinRwtParam::dspin_get(receive_data, DspinRwtParam::MULTI_UPDT_NLINE); 6402 r_cc_receive_word_idx = DspinRwtParam::dspin_get(receive_data, DspinRwtParam::MULTI_UPDT_WORD_INDEX); 6403 r_cc_receive_icache_type = CC_TYPE_UPDT; 6432 6404 // get back to idle state 6433 6405 r_cc_receive_fsm = CC_RECEIVE_INS_UPDT_DATA; … … 6444 6416 uint64_t receive_data = p_dspin_m2p.data.read(); 6445 6417 bool receive_eop = p_dspin_m2p.eop.read(); 6446 cc_receive_updt_fifo_be = DspinRwtParam::dspin_get(receive_data, DspinRwtParam::MULTI_UPDT_BE);6447 cc_receive_updt_fifo_data = DspinRwtParam::dspin_get(receive_data, DspinRwtParam::MULTI_UPDT_DATA);6418 cc_receive_updt_fifo_be = DspinRwtParam::dspin_get(receive_data, DspinRwtParam::MULTI_UPDT_BE); 6419 cc_receive_updt_fifo_data = DspinRwtParam::dspin_get(receive_data, DspinRwtParam::MULTI_UPDT_DATA); 6448 6420 cc_receive_updt_fifo_eop = receive_eop; 6449 6421 cc_receive_updt_fifo_put = true; 6450 if ( receive_eop) r_cc_receive_fsm = CC_RECEIVE_IDLE;6422 if (receive_eop) r_cc_receive_fsm = CC_RECEIVE_IDLE; 6451 6423 } 6452 6424 break; … … 6460 6432 uint64_t receive_data = p_dspin_m2p.data.read(); 6461 6433 bool receive_eop = p_dspin_m2p.eop.read(); 6462 cc_receive_updt_fifo_be = DspinRwtParam::dspin_get(receive_data, DspinRwtParam::MULTI_UPDT_BE);6463 cc_receive_updt_fifo_data = DspinRwtParam::dspin_get(receive_data, DspinRwtParam::MULTI_UPDT_DATA);6434 cc_receive_updt_fifo_be = DspinRwtParam::dspin_get(receive_data, DspinRwtParam::MULTI_UPDT_BE); 6435 cc_receive_updt_fifo_data = DspinRwtParam::dspin_get(receive_data, DspinRwtParam::MULTI_UPDT_DATA); 6464 6436 cc_receive_updt_fifo_eop = receive_eop; 6465 6437 cc_receive_updt_fifo_put = true; 6466 if ( receive_eop) r_cc_receive_fsm = CC_RECEIVE_IDLE;6438 if (receive_eop) r_cc_receive_fsm = CC_RECEIVE_IDLE; 6467 6439 } 6468 6440 break; … … 6474 6446 6475 6447 uint64_t clack_type = DspinRwtParam::dspin_get(r_dspin_clack_flit.read(), 6476 6477 6478 size_t clack_way 6479 6480 6481 size_t clack_set 6482 6483 6484 bool dspin_clack_get 6448 DspinRwtParam::CLACK_TYPE); 6449 6450 size_t clack_way = DspinRwtParam::dspin_get(r_dspin_clack_flit.read(), 6451 DspinRwtParam::CLACK_WAY); 6452 6453 size_t clack_set = DspinRwtParam::dspin_get(r_dspin_clack_flit.read(), 6454 DspinRwtParam::CLACK_SET); 6455 6456 bool dspin_clack_get = false; 6485 6457 bool dcache_clack_request = (clack_type == DspinRwtParam::TYPE_CLACK_DATA); 6486 6458 bool icache_clack_request = (clack_type == DspinRwtParam::TYPE_CLACK_INST); … … 6489 6461 { 6490 6462 // CLACK DATA: Send request to DCACHE FSM 6491 if (dcache_clack_request and not r_dcache_clack_req.read()){ 6463 if (dcache_clack_request and not r_dcache_clack_req.read()) 6464 { 6492 6465 r_dcache_clack_req = true; 6493 r_dcache_clack_way = clack_way & ((1ULL <<(uint32_log2(m_dcache_ways)))-1);6494 r_dcache_clack_set = clack_set & ((1ULL <<(uint32_log2(m_dcache_sets)))-1);6466 r_dcache_clack_way = clack_way & ((1ULL << (uint32_log2(m_dcache_ways))) - 1); 6467 r_dcache_clack_set = clack_set & ((1ULL << (uint32_log2(m_dcache_sets))) - 1); 6495 6468 dspin_clack_get = true; 6496 6469 } 6497 6470 6498 6471 // CLACK INST: Send request to ICACHE FSM 6499 else if (icache_clack_request and not r_icache_clack_req.read()){ 6472 else if (icache_clack_request and not r_icache_clack_req.read()) 6473 { 6500 6474 r_icache_clack_req = true; 6501 6475 r_icache_clack_way = clack_way & ((1ULL<<(uint32_log2(m_dcache_ways)))-1); … … 6555 6529 6556 6530 bool is_sc_or_cas = (r_vci_cmd_fsm.read() == CMD_DATA_CAS) or 6557 (r_vci_cmd_fsm.read() == CMD_DATA_SC 6531 (r_vci_cmd_fsm.read() == CMD_DATA_SC); 6558 6532 6559 6533 p_vci.pktid = 0; … … 6565 6539 p_vci.cfixed = false; 6566 6540 6567 if ( m_monitor_ok) {6568 if ( 6541 if (m_monitor_ok) { 6542 if (p_vci.cmdack.read() == true and p_vci.cmdval == true) { 6569 6543 if (((p_vci.address.read()) >= m_monitor_base) and 6570 ((p_vci.address.read()) < m_monitor_base + m_monitor_length) 6544 ((p_vci.address.read()) < m_monitor_base + m_monitor_length)) { 6571 6545 std::cout << "CC_VCACHE Monitor " << name() << std::hex 6572 6546 << " Access type = " << vci_cmd_type_str[p_vci.cmd.read()] … … 6574 6548 << " : address = " << p_vci.address.read() 6575 6549 << " / be = " << p_vci.be.read(); 6576 if ( p_vci.cmd.read() == vci_param::CMD_WRITE) {6550 if (p_vci.cmd.read() == vci_param::CMD_WRITE) { 6577 6551 std::cout << " / data = " << p_vci.wdata.read(); 6578 6552 } … … 6582 6556 } 6583 6557 6584 switch ( r_vci_cmd_fsm.read()) {6558 switch (r_vci_cmd_fsm.read()) { 6585 6559 6586 6560 case CMD_IDLE: … … 6683 6657 p_vci.cmdval = true; 6684 6658 p_vci.address = r_dcache_vci_paddr.read() & ~0x3; 6685 if ( r_vci_cmd_cpt.read() == 0) p_vci.wdata = r_dcache_llsc_key.read();6686 else 6659 if (r_vci_cmd_cpt.read() == 0) p_vci.wdata = r_dcache_llsc_key.read(); 6660 else p_vci.wdata = r_dcache_vci_sc_data.read(); 6687 6661 p_vci.be = 0xF; 6688 6662 p_vci.trdid = 0; … … 6696 6670 p_vci.cmdval = true; 6697 6671 p_vci.address = r_dcache_vci_paddr.read() & ~0x3; 6698 if ( r_vci_cmd_cpt.read() == 0) p_vci.wdata = r_dcache_vci_cas_old.read();6699 else 6672 if (r_vci_cmd_cpt.read() == 0) p_vci.wdata = r_dcache_vci_cas_old.read(); 6673 else p_vci.wdata = r_dcache_vci_cas_new.read(); 6700 6674 p_vci.be = 0xF; 6701 6675 p_vci.trdid = 0; … … 6710 6684 // it depends on the VCI_RSP FSM 6711 6685 6712 switch (r_vci_rsp_fsm.read() 6686 switch (r_vci_rsp_fsm.read()) 6713 6687 { 6714 6688 case RSP_DATA_WRITE : p_vci.rspack = true; break; … … 6726 6700 6727 6701 uint64_t dspin_send_data = 0; 6728 switch ( r_cc_send_fsm.read())6702 switch (r_cc_send_fsm.read()) 6729 6703 { 6730 6704 ////////////////// … … 6739 6713 // initialize dspin send data 6740 6714 DspinRwtParam::dspin_set(dspin_send_data, 6741 6742 6715 m_cc_global_id, 6716 DspinRwtParam::CLEANUP_SRCID); 6743 6717 DspinRwtParam::dspin_set(dspin_send_data, 6744 6745 6746 6747 if (r_cc_send_last_client.read() == 0) // dcache active request6718 0, 6719 DspinRwtParam::P2M_BC); 6720 6721 if (r_cc_send_last_client.read() == 0) // dcache active request 6748 6722 { 6749 6723 uint64_t dest = (uint64_t) r_dcache_cc_send_nline.read() 6750 6724 >> (m_nline_width - m_x_width - m_y_width) 6751 6725 << (DspinRwtParam::GLOBALID_WIDTH - m_x_width - m_y_width); 6726 6752 6727 DspinRwtParam::dspin_set(dspin_send_data, 6753 6754 6728 dest, 6729 DspinRwtParam::CLEANUP_DEST); 6755 6730 6756 6731 DspinRwtParam::dspin_set(dspin_send_data, 6757 (r_dcache_cc_send_nline.read() & 0x300000000ULL)>>32,6758 6732 (r_dcache_cc_send_nline.read() & 0x300000000ULL) >> 32, 6733 DspinRwtParam::CLEANUP_NLINE_MSB); 6759 6734 6760 6735 DspinRwtParam::dspin_set(dspin_send_data, 6761 6762 6736 r_dcache_cc_send_way.read(), 6737 DspinRwtParam::CLEANUP_WAY_INDEX); 6763 6738 6764 6739 DspinRwtParam::dspin_set(dspin_send_data, 6765 6766 6740 DspinRwtParam::TYPE_CLEANUP_DATA, 6741 DspinRwtParam::P2M_TYPE); 6767 6742 6768 6743 DspinRwtParam::dspin_set(dspin_send_data, 6769 6770 6744 (r_dcache_cc_cleanup_line_ncc.read() and (r_cc_send_last_client.read() == 0)), 6745 DspinRwtParam::CLEANUP_NCC); 6771 6746 } 6772 6747 else // icache active request … … 6777 6752 6778 6753 DspinRwtParam::dspin_set(dspin_send_data, 6779 6780 6754 dest, 6755 DspinRwtParam::CLEANUP_DEST); 6781 6756 6782 6757 DspinRwtParam::dspin_set(dspin_send_data, 6783 (r_icache_cc_send_nline.read() & 0x300000000ULL)>>32,6784 6758 (r_icache_cc_send_nline.read() & 0x300000000ULL) >> 32, 6759 DspinRwtParam::CLEANUP_NLINE_MSB); 6785 6760 6786 6761 DspinRwtParam::dspin_set(dspin_send_data, 6787 6788 6762 r_icache_cc_send_way.read(), 6763 DspinRwtParam::CLEANUP_WAY_INDEX); 6789 6764 6790 6765 DspinRwtParam::dspin_set(dspin_send_data, 6791 6792 6766 DspinRwtParam::TYPE_CLEANUP_INST, 6767 DspinRwtParam::P2M_TYPE); 6793 6768 6794 6769 DspinRwtParam::dspin_set(dspin_send_data, 6795 6796 6770 0, 6771 DspinRwtParam::CLEANUP_NCC); 6797 6772 6798 6773 … … 6808 6783 { 6809 6784 // initialize dspin send data 6810 if (r_cc_send_last_client.read() == 0) // dcache active request6785 if (r_cc_send_last_client.read() == 0) // dcache active request 6811 6786 { 6812 6787 DspinRwtParam::dspin_set(dspin_send_data, 6813 6814 6788 r_dcache_cc_send_nline.read() & 0xFFFFFFFFULL, 6789 DspinRwtParam::CLEANUP_NLINE_LSB); 6815 6790 } 6816 6791 else // icache active request 6817 6792 { 6818 6793 DspinRwtParam::dspin_set(dspin_send_data, 6819 6820 6794 r_icache_cc_send_nline.read() & 0xFFFFFFFFULL, 6795 DspinRwtParam::CLEANUP_NLINE_LSB); 6821 6796 } 6822 6797 // send flit 6823 6798 p_dspin_p2m.data = dspin_send_data; 6824 6799 p_dspin_p2m.write = true; 6825 p_dspin_p2m.eop = ! 6800 p_dspin_p2m.eop = !(r_dcache_cc_cleanup_updt_data.read() and (r_cc_send_last_client.read() == 0)); 6826 6801 break; 6827 6802 } … … 6831 6806 6832 6807 DspinRwtParam::dspin_set(dspin_send_data, 6833 6834 6835 6836 p_dspin_p2m.data = dspin_send_data;6808 r_cc_send_data_fifo.read(), 6809 DspinRwtParam::CLEANUP_DATA_UPDT); 6810 6811 p_dspin_p2m.data = dspin_send_data; 6837 6812 p_dspin_p2m.write = true; 6838 p_dspin_p2m.eop = (r_cc_send_cpt_word.read() == m_dcache_words-1);6813 p_dspin_p2m.eop = (r_cc_send_cpt_word.read() == m_dcache_words - 1); 6839 6814 break; 6840 6815 } … … 6844 6819 // initialize dspin send data 6845 6820 DspinRwtParam::dspin_set(dspin_send_data, 6846 6847 6821 0, 6822 DspinRwtParam::P2M_BC); 6848 6823 DspinRwtParam::dspin_set(dspin_send_data, 6849 6850 6851 6852 if (r_cc_send_last_client.read() == 0) // dcache active request6824 DspinRwtParam::TYPE_MULTI_ACK, 6825 DspinRwtParam::P2M_TYPE); 6826 6827 if (r_cc_send_last_client.read() == 0) // dcache active request 6853 6828 { 6854 6829 uint64_t dest = (uint64_t) r_dcache_cc_send_nline.read() … … 6857 6832 6858 6833 DspinRwtParam::dspin_set(dspin_send_data, 6859 6860 6834 dest, 6835 DspinRwtParam::MULTI_ACK_DEST); 6861 6836 6862 6837 DspinRwtParam::dspin_set(dspin_send_data, 6863 6864 6838 r_dcache_cc_send_updt_tab_idx.read(), 6839 DspinRwtParam::MULTI_ACK_UPDT_INDEX); 6865 6840 } 6866 6841 else // icache active request … … 6872 6847 6873 6848 DspinRwtParam::dspin_set(dspin_send_data, 6874 6875 6849 dest, 6850 DspinRwtParam::MULTI_ACK_DEST); 6876 6851 6877 6852 DspinRwtParam::dspin_set(dspin_send_data, 6878 6879 6853 r_icache_cc_send_updt_tab_idx.read(), 6854 DspinRwtParam::MULTI_ACK_UPDT_INDEX); 6880 6855 } 6881 6856 // send flit … … 6890 6865 // Receive coherence packets 6891 6866 // It depends on the CC_RECEIVE FSM 6892 switch ( r_cc_receive_fsm.read())6867 switch (r_cc_receive_fsm.read()) 6893 6868 { 6894 6869 ///////////////////// … … 6946 6921 case CC_RECEIVE_INS_UPDT_HEADER: 6947 6922 { 6948 if ( 6923 if (not r_cc_receive_icache_req.read()) 6949 6924 p_dspin_m2p.read = true; 6950 6925 else … … 6956 6931 case CC_RECEIVE_INS_UPDT_NLINE: 6957 6932 { 6958 if (r_cc_receive_updt_fifo_be.empty())6933 if (r_cc_receive_updt_fifo_be.empty()) 6959 6934 p_dspin_m2p.read = true; 6960 6935 else … … 6976 6951 6977 6952 int clack_type = DspinRwtParam::dspin_get(r_dspin_clack_flit.read(), 6978 6953 DspinRwtParam::CLACK_TYPE); 6979 6954 6980 6955 bool dspin_clack_get = false; … … 7007 6982 // This version of monitor print both Read and Write request 7008 6983 { 7009 m_monitor_ok 7010 m_monitor_base 7011 m_monitor_length 6984 m_monitor_ok = true; 6985 m_monitor_base = base; 6986 m_monitor_length = length; 7012 6987 } 7013 6988 7014 6989 tmpl(void)::stop_monitor() 7015 6990 { 7016 m_monitor_ok 6991 m_monitor_ok = false; 7017 6992 } 7018 6993
Note: See TracChangeset
for help on using the changeset viewer.