Changeset 827 for branches/RWT/modules/vci_cc_vcache_wrapper/caba/source
- Timestamp:
- Oct 1, 2014, 5:44:55 PM (10 years ago)
- Location:
- branches/RWT/modules/vci_cc_vcache_wrapper/caba/source
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/RWT/modules/vci_cc_vcache_wrapper/caba/source/include/vci_cc_vcache_wrapper.h
r824 r827 35 35 #include <inttypes.h> 36 36 #include <systemc> 37 38 37 #include "caba_base_module.h" 39 38 #include "multi_write_buffer.h" … … 307 306 soclib::common::AddressDecodingTable<uint64_t, bool> m_cacheability_table; 308 307 309 const size_t 310 const size_t 311 const size_t 312 const size_t 313 const size_t 314 const size_t 315 const size_t 316 const size_t 317 const size_t 318 const paddr_t 319 const size_t 320 const size_t 321 const size_t 322 const paddr_t 323 const size_t 324 const size_t 325 const size_t 326 const size_t 327 const uint32_t 328 const size_t 329 uint32_t 330 bool 331 332 uint32_t 333 uint32_t 308 const size_t m_srcid; 309 const size_t m_cc_global_id; 310 const size_t m_nline_width; 311 const size_t m_itlb_ways; 312 const size_t m_itlb_sets; 313 const size_t m_dtlb_ways; 314 const size_t m_dtlb_sets; 315 const size_t m_icache_ways; 316 const size_t m_icache_sets; 317 const paddr_t m_icache_yzmask; 318 const size_t m_icache_words; 319 const size_t m_dcache_ways; 320 const size_t m_dcache_sets; 321 const paddr_t m_dcache_yzmask; 322 const size_t m_dcache_words; 323 const size_t m_x_width; 324 const size_t m_y_width; 325 const size_t m_proc_id; 326 const uint32_t m_max_frozen_cycles; 327 const size_t m_paddr_nbits; 328 uint32_t m_debug_start_cycle; 329 bool m_debug_ok; 330 331 uint32_t m_dcache_paddr_ext_reset; 332 uint32_t m_icache_paddr_ext_reset; 334 333 335 334 //////////////////////////////////////// … … 344 343 // debug variables 345 344 ///////////////////////////////////////////// 346 bool 347 bool 348 bool 345 bool m_debug_previous_i_hit; 346 bool m_debug_previous_d_hit; 347 bool m_debug_activated; 349 348 350 349 /////////////////////////////// 351 350 // Software visible REGISTERS 352 351 /////////////////////////////// 353 sc_signal<uint32_t> r_mmu_ptpr;// page table pointer register354 sc_signal<uint32_t> r_mmu_mode;// mmu mode register355 sc_signal<uint32_t> r_mmu_word_lo;// mmu misc data low356 sc_signal<uint32_t> r_mmu_word_hi;// mmu misc data hight357 sc_signal<uint32_t> r_mmu_ibvar;// mmu bad instruction address358 sc_signal<uint32_t> r_mmu_dbvar;// mmu bad data address359 sc_signal<uint32_t> r_mmu_ietr;// mmu instruction error type360 sc_signal<uint32_t> r_mmu_detr;// mmu data error type361 uint32_t r_mmu_params;// read-only362 uint32_t r_mmu_release;// read_only352 sc_signal<uint32_t> r_mmu_ptpr; // page table pointer register 353 sc_signal<uint32_t> r_mmu_mode; // mmu mode register 354 sc_signal<uint32_t> r_mmu_word_lo; // mmu misc data low 355 sc_signal<uint32_t> r_mmu_word_hi; // mmu misc data hight 356 sc_signal<uint32_t> r_mmu_ibvar; // mmu bad instruction address 357 sc_signal<uint32_t> r_mmu_dbvar; // mmu bad data address 358 sc_signal<uint32_t> r_mmu_ietr; // mmu instruction error type 359 sc_signal<uint32_t> r_mmu_detr; // mmu data error type 360 uint32_t r_mmu_params; // read-only 361 uint32_t r_mmu_release; // read_only 363 362 364 363 … … 366 365 // ICACHE FSM REGISTERS 367 366 ////////////////////////////// 368 sc_signal<int> r_icache_fsm;// state register369 sc_signal<int> r_icache_fsm_save;// return state for coherence op370 sc_signal<paddr_t> r_icache_vci_paddr;// physical address371 sc_signal<uint32_t> r_icache_vaddr_save;// virtual address from processor367 sc_signal<int> r_icache_fsm; // state register 368 sc_signal<int> r_icache_fsm_save; // return state for coherence op 369 sc_signal<paddr_t> r_icache_vci_paddr; // physical address 370 sc_signal<uint32_t> r_icache_vaddr_save; // virtual address from processor 372 371 373 372 // icache miss handling 374 sc_signal<size_t> r_icache_miss_way;// selected way for cache update375 sc_signal<size_t> r_icache_miss_set;// selected set for cache update376 sc_signal<size_t> r_icache_miss_word;// word index ( cache update)377 sc_signal<bool> r_icache_miss_inval;// coherence request matching a miss378 sc_signal<bool> r_icache_miss_clack;// waiting for a cleanup acknowledge373 sc_signal<size_t> r_icache_miss_way; // selected way for cache update 374 sc_signal<size_t> r_icache_miss_set; // selected set for cache update 375 sc_signal<size_t> r_icache_miss_word; // word index ( cache update) 376 sc_signal<bool> r_icache_miss_inval; // coherence request matching a miss 377 sc_signal<bool> r_icache_miss_clack; // waiting for a cleanup acknowledge 379 378 380 379 // coherence request handling 381 sc_signal<size_t> r_icache_cc_way;// selected way for cc update/inval382 sc_signal<size_t> r_icache_cc_set;// selected set for cc update/inval383 sc_signal<size_t> r_icache_cc_word;// word counter for cc update384 sc_signal<bool> r_icache_cc_need_write;// activate the cache for writing380 sc_signal<size_t> r_icache_cc_way; // selected way for cc update/inval 381 sc_signal<size_t> r_icache_cc_set; // selected set for cc update/inval 382 sc_signal<size_t> r_icache_cc_word; // word counter for cc update 383 sc_signal<bool> r_icache_cc_need_write; // activate the cache for writing 385 384 386 385 // coherence clack handling 387 sc_signal<bool> r_icache_clack_req;// clack request388 sc_signal<size_t> r_icache_clack_way;// clack way389 sc_signal<size_t> r_icache_clack_set;// clack set386 sc_signal<bool> r_icache_clack_req; // clack request 387 sc_signal<size_t> r_icache_clack_way; // clack way 388 sc_signal<size_t> r_icache_clack_set; // clack set 390 389 391 390 // icache flush handling 392 sc_signal<size_t> r_icache_flush_count;// slot counter used for cache flush391 sc_signal<size_t> r_icache_flush_count; // slot counter used for cache flush 393 392 394 393 // communication between ICACHE FSM and VCI_CMD FSM 395 sc_signal<bool> r_icache_miss_req;// cached read miss396 sc_signal<bool> r_icache_unc_req;// uncached read miss394 sc_signal<bool> r_icache_miss_req; // cached read miss 395 sc_signal<bool> r_icache_unc_req; // uncached read miss 397 396 398 397 // communication between ICACHE FSM and DCACHE FSM 399 sc_signal<bool> r_icache_tlb_miss_req;// (set icache/reset dcache)400 sc_signal<bool> r_icache_tlb_rsp_error;// tlb miss response error398 sc_signal<bool> r_icache_tlb_miss_req; // (set icache/reset dcache) 399 sc_signal<bool> r_icache_tlb_rsp_error; // tlb miss response error 401 400 402 401 // Flip-Flop in ICACHE FSM for saving the cleanup victim request 403 sc_signal<bool> 404 sc_signal<paddr_t> 402 sc_signal<bool> r_icache_cleanup_victim_req; 403 sc_signal<paddr_t> r_icache_cleanup_victim_nline; 405 404 406 405 // communication between ICACHE FSM and CC_SEND FSM 407 sc_signal<bool> r_icache_cc_send_req;// ICACHE cc_send request408 sc_signal<int> r_icache_cc_send_type;// ICACHE cc_send request type409 sc_signal<paddr_t> r_icache_cc_send_nline;// ICACHE cc_send nline410 sc_signal<size_t> r_icache_cc_send_way;// ICACHE cc_send way411 sc_signal<size_t> r_icache_cc_send_updt_tab_idx;// ICACHE cc_send update table index406 sc_signal<bool> r_icache_cc_send_req; // ICACHE cc_send request 407 sc_signal<int> r_icache_cc_send_type; // ICACHE cc_send request type 408 sc_signal<paddr_t> r_icache_cc_send_nline; // ICACHE cc_send nline 409 sc_signal<size_t> r_icache_cc_send_way; // ICACHE cc_send way 410 sc_signal<size_t> r_icache_cc_send_updt_tab_idx; // ICACHE cc_send update table index 412 411 413 412 // Physical address extension for data access 414 sc_signal<uint32_t> r_icache_paddr_ext;// CP2 register (if vci_address > 32)413 sc_signal<uint32_t> r_icache_paddr_ext; // CP2 register (if vci_address > 32) 415 414 416 415 /////////////////////////////// 417 416 // DCACHE FSM REGISTERS 418 417 /////////////////////////////// 419 sc_signal<int> r_dcache_fsm;// state register420 sc_signal<int> r_dcache_fsm_cc_save;// return state for coherence op421 sc_signal<int> r_dcache_fsm_scan_save;// return state for tlb scan op418 sc_signal<int> r_dcache_fsm; // state register 419 sc_signal<int> r_dcache_fsm_cc_save; // return state for coherence op 420 sc_signal<int> r_dcache_fsm_scan_save; // return state for tlb scan op 422 421 // registers written in P0 stage (used in P1 stage) 423 sc_signal<bool> r_dcache_wbuf_req;// WBUF must be written in P1 stage424 sc_signal<bool> r_dcache_updt_req;// DCACHE must be updated in P1 stage425 sc_signal<uint32_t> r_dcache_save_vaddr;// virtual address (from proc)426 sc_signal<uint32_t> r_dcache_save_wdata;// write data (from proc)427 sc_signal<uint32_t> r_dcache_save_be;// byte enable (from proc)428 sc_signal<paddr_t> r_dcache_save_paddr;// physical address429 sc_signal<size_t> r_dcache_save_cache_way;// selected way (from dcache)430 sc_signal<size_t> r_dcache_save_cache_set;// selected set (from dcache)431 sc_signal<size_t> r_dcache_save_cache_word;// selected word (from dcache)422 sc_signal<bool> r_dcache_wbuf_req; // WBUF must be written in P1 stage 423 sc_signal<bool> r_dcache_updt_req; // DCACHE must be updated in P1 stage 424 sc_signal<uint32_t> r_dcache_save_vaddr; // virtual address (from proc) 425 sc_signal<uint32_t> r_dcache_save_wdata; // write data (from proc) 426 sc_signal<uint32_t> r_dcache_save_be; // byte enable (from proc) 427 sc_signal<paddr_t> r_dcache_save_paddr; // physical address 428 sc_signal<size_t> r_dcache_save_cache_way; // selected way (from dcache) 429 sc_signal<size_t> r_dcache_save_cache_set; // selected set (from dcache) 430 sc_signal<size_t> r_dcache_save_cache_word; // selected word (from dcache) 432 431 // registers used by the Dirty bit sub-fsm 433 sc_signal<paddr_t> r_dcache_dirty_paddr;// PTE physical address434 sc_signal<size_t> r_dcache_dirty_way;// way to invalidate in dcache435 sc_signal<size_t> r_dcache_dirty_set;// set to invalidate in dcache432 sc_signal<paddr_t> r_dcache_dirty_paddr; // PTE physical address 433 sc_signal<size_t> r_dcache_dirty_way; // way to invalidate in dcache 434 sc_signal<size_t> r_dcache_dirty_set; // set to invalidate in dcache 436 435 437 436 // communication between DCACHE FSM and VCI_CMD FSM 438 sc_signal<paddr_t> r_dcache_vci_paddr;// physical address for VCI command439 sc_signal<uint32_t> r_dcache_vci_wdata;// write unc data for VCI command440 sc_signal<bool> r_dcache_vci_miss_req;// read miss request441 sc_signal<bool> r_dcache_vci_unc_req;// uncacheable request (read/write)442 sc_signal<uint32_t> r_dcache_vci_unc_be;// uncacheable byte enable443 sc_signal<uint32_t> r_dcache_vci_unc_write;// uncacheable data write request444 sc_signal<bool> r_dcache_vci_cas_req;// atomic write request CAS445 sc_signal<uint32_t> r_dcache_vci_cas_old;// previous data value for a CAS446 sc_signal<uint32_t> r_dcache_vci_cas_new;// new data value for a CAS447 sc_signal<bool> r_dcache_vci_ll_req;// atomic read request LL448 sc_signal<bool> r_dcache_vci_sc_req;// atomic write request SC449 sc_signal<uint32_t> r_dcache_vci_sc_data;// SC data (command)437 sc_signal<paddr_t> r_dcache_vci_paddr; // physical address for VCI command 438 sc_signal<uint32_t> r_dcache_vci_wdata; // write unc data for VCI command 439 sc_signal<bool> r_dcache_vci_miss_req; // read miss request 440 sc_signal<bool> r_dcache_vci_unc_req; // uncacheable request (read/write) 441 sc_signal<uint32_t> r_dcache_vci_unc_be; // uncacheable byte enable 442 sc_signal<uint32_t> r_dcache_vci_unc_write; // uncacheable data write request 443 sc_signal<bool> r_dcache_vci_cas_req; // atomic write request CAS 444 sc_signal<uint32_t> r_dcache_vci_cas_old; // previous data value for a CAS 445 sc_signal<uint32_t> r_dcache_vci_cas_new; // new data value for a CAS 446 sc_signal<bool> r_dcache_vci_ll_req; // atomic read request LL 447 sc_signal<bool> r_dcache_vci_sc_req; // atomic write request SC 448 sc_signal<uint32_t> r_dcache_vci_sc_data; // SC data (command) 450 449 451 450 //RWT: local cas 452 sc_signal<bool> 453 sc_signal<size_t> 454 sc_signal<size_t> 455 sc_signal<size_t> 451 sc_signal<bool> r_cas_islocal; 452 sc_signal<size_t> r_cas_local_way; 453 sc_signal<size_t> r_cas_local_set; 454 sc_signal<size_t> r_cas_local_word; 456 455 457 456 // register used for XTN inval 458 sc_signal<size_t> r_dcache_xtn_way;// selected way (from dcache)459 sc_signal<size_t> r_dcache_xtn_set;// selected set (from dcache)457 sc_signal<size_t> r_dcache_xtn_way; // selected way (from dcache) 458 sc_signal<size_t> r_dcache_xtn_set; // selected set (from dcache) 460 459 461 460 // handling dcache miss 462 sc_signal<int> r_dcache_miss_type;// depending on the requester463 sc_signal<size_t> r_dcache_miss_word;// word index for cache update464 sc_signal<size_t> r_dcache_miss_way;// selected way for cache update465 sc_signal<size_t> r_dcache_miss_set;// selected set for cache update466 sc_signal<bool> r_dcache_miss_inval;// coherence request matching a miss467 sc_signal<bool> r_dcache_miss_clack;// waiting for a cleanup acknowledge461 sc_signal<int> r_dcache_miss_type; // depending on the requester 462 sc_signal<size_t> r_dcache_miss_word; // word index for cache update 463 sc_signal<size_t> r_dcache_miss_way; // selected way for cache update 464 sc_signal<size_t> r_dcache_miss_set; // selected set for cache update 465 sc_signal<bool> r_dcache_miss_inval; // coherence request matching a miss 466 sc_signal<bool> r_dcache_miss_clack; // waiting for a cleanup acknowledge 468 467 469 468 // handling coherence requests 470 sc_signal<size_t> r_dcache_cc_way;// selected way for cc update/inval471 sc_signal<size_t> r_dcache_cc_set;// selected set for cc update/inval472 sc_signal<int> r_dcache_cc_state;// state of selected cache slot473 sc_signal<size_t> r_dcache_cc_word;// word counter for cc update474 sc_signal<bool> r_dcache_cc_need_write;// activate the cache for writing475 sc_signal<paddr_t> r_dcache_cc_inval_addr;// address for a cleanup transaction476 sc_signal<uint32_t> 469 sc_signal<size_t> r_dcache_cc_way; // selected way for cc update/inval 470 sc_signal<size_t> r_dcache_cc_set; // selected set for cc update/inval 471 sc_signal<int> r_dcache_cc_state; // state of selected cache slot 472 sc_signal<size_t> r_dcache_cc_word; // word counter for cc update 473 sc_signal<bool> r_dcache_cc_need_write; // activate the cache for writing 474 sc_signal<paddr_t> r_dcache_cc_inval_addr; // address for a cleanup transaction 475 sc_signal<uint32_t> r_dcache_cc_inval_data_cpt; 477 476 478 477 // coherence clack handling 479 sc_signal<bool> r_dcache_clack_req;// clack request480 sc_signal<size_t> r_dcache_clack_way;// clack way481 sc_signal<size_t> r_dcache_clack_set;// clack set478 sc_signal<bool> r_dcache_clack_req; // clack request 479 sc_signal<size_t> r_dcache_clack_way; // clack way 480 sc_signal<size_t> r_dcache_clack_set; // clack set 482 481 483 482 // dcache flush handling 484 sc_signal<size_t> r_dcache_flush_count;// slot counter used for cache flush483 sc_signal<size_t> r_dcache_flush_count; // slot counter used for cache flush 485 484 486 485 // ll response handling 487 sc_signal<size_t> r_dcache_ll_rsp_count;// flit counter used for ll rsp486 sc_signal<size_t> r_dcache_ll_rsp_count; // flit counter used for ll rsp 488 487 489 488 // used by the TLB miss sub-fsm 490 sc_signal<uint32_t> r_dcache_tlb_vaddr;// virtual address for a tlb miss491 sc_signal<bool> r_dcache_tlb_ins;// target tlb (itlb if true)492 sc_signal<paddr_t> r_dcache_tlb_paddr;// physical address of pte493 sc_signal<uint32_t> r_dcache_tlb_pte_flags;// pte1 or first word of pte2494 sc_signal<uint32_t> r_dcache_tlb_pte_ppn;// second word of pte2495 sc_signal<size_t> r_dcache_tlb_cache_way;// selected way in dcache496 sc_signal<size_t> r_dcache_tlb_cache_set;// selected set in dcache497 sc_signal<size_t> r_dcache_tlb_cache_word;// selected word in dcache498 sc_signal<size_t> r_dcache_tlb_way;// selected way in tlb499 sc_signal<size_t> r_dcache_tlb_set;// selected set in tlb489 sc_signal<uint32_t> r_dcache_tlb_vaddr; // virtual address for a tlb miss 490 sc_signal<bool> r_dcache_tlb_ins; // target tlb (itlb if true) 491 sc_signal<paddr_t> r_dcache_tlb_paddr; // physical address of pte 492 sc_signal<uint32_t> r_dcache_tlb_pte_flags; // pte1 or first word of pte2 493 sc_signal<uint32_t> r_dcache_tlb_pte_ppn; // second word of pte2 494 sc_signal<size_t> r_dcache_tlb_cache_way; // selected way in dcache 495 sc_signal<size_t> r_dcache_tlb_cache_set; // selected set in dcache 496 sc_signal<size_t> r_dcache_tlb_cache_word; // selected word in dcache 497 sc_signal<size_t> r_dcache_tlb_way; // selected way in tlb 498 sc_signal<size_t> r_dcache_tlb_set; // selected set in tlb 500 499 501 500 // ITLB and DTLB invalidation 502 sc_signal<paddr_t> r_dcache_tlb_inval_line;// line index503 sc_signal<size_t> r_dcache_tlb_inval_set;// tlb set counter501 sc_signal<paddr_t> r_dcache_tlb_inval_line; // line index 502 sc_signal<size_t> r_dcache_tlb_inval_set; // tlb set counter 504 503 505 504 // communication between DCACHE FSM and ICACHE FSM 506 sc_signal<bool> r_dcache_xtn_req;// xtn request (caused by processor)507 sc_signal<int> r_dcache_xtn_opcode;// xtn request type505 sc_signal<bool> r_dcache_xtn_req; // xtn request (caused by processor) 506 sc_signal<int> r_dcache_xtn_opcode; // xtn request type 508 507 509 508 // Filp-Flop in DCACHE FSM for saving the cleanup victim request 510 sc_signal<bool> 511 sc_signal<bool> 512 sc_signal<bool> 513 sc_signal<paddr_t> 509 sc_signal<bool> r_dcache_cleanup_victim_req; 510 sc_signal<bool> r_dcache_cleanup_victim_line_ncc; 511 sc_signal<bool> r_dcache_cleanup_victim_updt_data; 512 sc_signal<paddr_t> r_dcache_cleanup_victim_nline; 514 513 515 514 // communication between DCACHE FSM and CC_SEND FSM 516 sc_signal<bool> r_dcache_cc_send_req;// DCACHE cc_send request517 sc_signal<int> r_dcache_cc_send_type;// DCACHE cc_send request type518 sc_signal<paddr_t> r_dcache_cc_send_nline;// DCACHE cc_send nline519 sc_signal<size_t> r_dcache_cc_send_way;// DCACHE cc_send way520 sc_signal<size_t> r_dcache_cc_send_updt_tab_idx;// DCACHE cc_send update table index515 sc_signal<bool> r_dcache_cc_send_req; // DCACHE cc_send request 516 sc_signal<int> r_dcache_cc_send_type; // DCACHE cc_send request type 517 sc_signal<paddr_t> r_dcache_cc_send_nline; // DCACHE cc_send nline 518 sc_signal<size_t> r_dcache_cc_send_way; // DCACHE cc_send way 519 sc_signal<size_t> r_dcache_cc_send_updt_tab_idx; // DCACHE cc_send update table index 521 520 522 521 // special registers for RWT 523 sc_signal<bool> r_dcache_cc_cleanup_updt_data; // Register for cleanup with data (wb updt) 524 sc_signal<bool> r_dcache_cc_cleanup_line_ncc; // Register for cleanup with data (wb updt) 525 sc_signal<bool> r_dcache_miss_victim_no_coherence; // Register for victim in no coherence mode 526 sc_signal<bool> r_dcache_line_no_coherence; // Register for line current in no coherence mode 527 sc_signal<bool> r_dcache_dirty_save; 528 sc_signal<uint32_t> r_cc_send_cpt_word; 529 sc_signal<uint32_t> r_dcache_miss_data_cpt; 530 sc_signal<paddr_t> r_dcache_miss_data_addr; 531 sc_signal<uint32_t> r_dcache_xtn_flush_data_cpt; 532 sc_signal<paddr_t> r_dcache_xtn_flush_addr_data; 533 sc_signal<int> r_dcache_xtn_state; 534 sc_signal<paddr_t> r_dcache_xtn_data_addr; 535 sc_signal<uint32_t> r_dcache_xtn_data_cpt; 536 sc_signal<bool> r_dcache_read_state; 522 sc_signal<bool> r_dcache_cc_cleanup_updt_data; // Register for cleanup with data (wb updt) 523 sc_signal<bool> r_dcache_cc_cleanup_line_ncc; // Register for cleanup with data (wb updt) 524 sc_signal<bool> r_dcache_dirty_save; 525 sc_signal<uint32_t> r_cc_send_cpt_word; 526 sc_signal<uint32_t> r_dcache_miss_data_cpt; 527 sc_signal<paddr_t> r_dcache_miss_data_addr; 528 sc_signal<uint32_t> r_dcache_xtn_flush_data_cpt; 529 sc_signal<paddr_t> r_dcache_xtn_flush_addr_data; 530 sc_signal<int> r_dcache_xtn_state; 531 sc_signal<paddr_t> r_dcache_xtn_data_addr; 532 sc_signal<uint32_t> r_dcache_xtn_data_cpt; 533 sc_signal<bool> r_dcache_read_state; 537 534 538 535 // dcache directory extension 539 int 536 int *r_dcache_content_state; // content state of one cache line 540 537 // Stats 541 int 542 bool 538 int *r_dcache_dirty_word; // use for compute number of words dirty per cleanup_data 539 bool *r_dcache_zombi_ncc; // use for compute number of blocked write on ncc zombi line 543 540 ////////////////////////////////////////////////////////////////////////////////////// 544 541 545 542 /////////////////////////////////// 546 543 // Physical address extension for data access 547 sc_signal<uint32_t> r_dcache_paddr_ext;// CP2 register (if vci_address > 32)544 sc_signal<uint32_t> r_dcache_paddr_ext; // CP2 register (if vci_address > 32) 548 545 549 546 /////////////////////////////////// 550 547 // VCI_CMD FSM REGISTERS 551 548 /////////////////////////////////// 552 sc_signal<int> 553 sc_signal<size_t> r_vci_cmd_min;// used for write bursts554 sc_signal<size_t> r_vci_cmd_max;// used for write bursts555 sc_signal<size_t> r_vci_cmd_cpt;// used for write bursts556 sc_signal<bool> r_vci_cmd_imiss_prio;// round-robin between imiss & dmiss549 sc_signal<int> r_vci_cmd_fsm; 550 sc_signal<size_t> r_vci_cmd_min; // used for write bursts 551 sc_signal<size_t> r_vci_cmd_max; // used for write bursts 552 sc_signal<size_t> r_vci_cmd_cpt; // used for write bursts 553 sc_signal<bool> r_vci_cmd_imiss_prio; // round-robin between imiss & dmiss 557 554 558 555 /////////////////////////////////// 559 556 // VCI_RSP FSM REGISTERS 560 557 /////////////////////////////////// 561 sc_signal<int> 562 sc_signal<size_t> 563 sc_signal<bool> 564 sc_signal<bool> 565 GenericFifo<uint32_t> r_vci_rsp_fifo_icache;// response FIFO to ICACHE FSM566 GenericFifo<uint32_t> r_vci_rsp_fifo_dcache;// response FIFO to DCACHE FSM558 sc_signal<int> r_vci_rsp_fsm; 559 sc_signal<size_t> r_vci_rsp_cpt; 560 sc_signal<bool> r_vci_rsp_ins_error; 561 sc_signal<bool> r_vci_rsp_data_error; 562 GenericFifo<uint32_t> r_vci_rsp_fifo_icache; // response FIFO to ICACHE FSM 563 GenericFifo<uint32_t> r_vci_rsp_fifo_dcache; // response FIFO to DCACHE FSM 567 564 568 565 569 566 //RWT 570 GenericFifo<bool> 571 GenericFifo<uint32_t> 567 GenericFifo<bool> r_vci_rsp_fifo_rpktid; 568 GenericFifo<uint32_t> r_cc_send_data_fifo; 572 569 573 570 /////////////////////////////////// 574 571 // CC_SEND FSM REGISTER 575 572 /////////////////////////////////// 576 sc_signal<int> r_cc_send_fsm;// state register577 sc_signal<bool> r_cc_send_last_client;// 0 dcache / 1 icache573 sc_signal<int> r_cc_send_fsm; // state register 574 sc_signal<bool> r_cc_send_last_client; // 0 dcache / 1 icache 578 575 579 576 /////////////////////////////////// 580 577 // CC_RECEIVE FSM REGISTER 581 578 /////////////////////////////////// 582 sc_signal<int> r_cc_receive_fsm;// state register583 sc_signal<bool> r_cc_receive_data_ins;// request to : 0 dcache / 1 icache579 sc_signal<int> r_cc_receive_fsm; // state register 580 sc_signal<bool> r_cc_receive_data_ins; // request to : 0 dcache / 1 icache 584 581 585 582 // communication between CC_RECEIVE FSM and ICACHE/DCACHE FSM 586 sc_signal<size_t> r_cc_receive_word_idx;// word index587 GenericFifo<uint32_t> 588 GenericFifo<uint32_t> 589 GenericFifo<bool> 583 sc_signal<size_t> r_cc_receive_word_idx; // word index 584 GenericFifo<uint32_t> r_cc_receive_updt_fifo_be; 585 GenericFifo<uint32_t> r_cc_receive_updt_fifo_data; 586 GenericFifo<bool> r_cc_receive_updt_fifo_eop; 590 587 591 588 // communication between CC_RECEIVE FSM and ICACHE FSM 592 sc_signal<bool> r_cc_receive_icache_req;// cc_receive to icache request593 sc_signal<int> r_cc_receive_icache_type;// cc_receive type of request594 sc_signal<size_t> r_cc_receive_icache_way;// cc_receive to icache way595 sc_signal<size_t> r_cc_receive_icache_set;// cc_receive to icache set596 sc_signal<size_t> r_cc_receive_icache_updt_tab_idx;// cc_receive update table index597 sc_signal<paddr_t> r_cc_receive_icache_nline;// cache line physical address589 sc_signal<bool> r_cc_receive_icache_req; // cc_receive to icache request 590 sc_signal<int> r_cc_receive_icache_type; // cc_receive type of request 591 sc_signal<size_t> r_cc_receive_icache_way; // cc_receive to icache way 592 sc_signal<size_t> r_cc_receive_icache_set; // cc_receive to icache set 593 sc_signal<size_t> r_cc_receive_icache_updt_tab_idx; // cc_receive update table index 594 sc_signal<paddr_t> r_cc_receive_icache_nline; // cache line physical address 598 595 599 596 // communication between CC_RECEIVE FSM and DCACHE FSM 600 sc_signal<bool> r_cc_receive_dcache_req;// cc_receive to dcache request601 sc_signal<int> r_cc_receive_dcache_type;// cc_receive type of request602 sc_signal<size_t> r_cc_receive_dcache_way;// cc_receive to dcache way603 sc_signal<size_t> r_cc_receive_dcache_set;// cc_receive to dcache set604 sc_signal<size_t> r_cc_receive_dcache_updt_tab_idx;// cc_receive update table index605 sc_signal<paddr_t> r_cc_receive_dcache_nline;// cache line physical address606 sc_signal<bool> r_cc_receive_dcache_inval_is_config;// inval from memcache is config597 sc_signal<bool> r_cc_receive_dcache_req; // cc_receive to dcache request 598 sc_signal<int> r_cc_receive_dcache_type; // cc_receive type of request 599 sc_signal<size_t> r_cc_receive_dcache_way; // cc_receive to dcache way 600 sc_signal<size_t> r_cc_receive_dcache_set; // cc_receive to dcache set 601 sc_signal<size_t> r_cc_receive_dcache_updt_tab_idx; // cc_receive update table index 602 sc_signal<paddr_t> r_cc_receive_dcache_nline; // cache line physical address 603 sc_signal<bool> r_cc_receive_dcache_inval_is_config; // inval from memcache is config 607 604 608 605 /////////////////////////////////// 609 606 // DSPIN CLACK INTERFACE REGISTER 610 607 /////////////////////////////////// 611 sc_signal<bool> 612 sc_signal<uint64_t> 608 sc_signal<bool> r_dspin_clack_req; 609 sc_signal<uint64_t> r_dspin_clack_flit; 613 610 614 611 ////////////////////////////////////////////////////////////////// … … 616 613 ////////////////////////////////////////////////////////////////// 617 614 618 iss_t 619 MultiWriteBuffer<paddr_t> 620 GenericCache<paddr_t> 621 GenericCache<paddr_t> 622 GenericTlb<paddr_t> 623 GenericTlb<paddr_t> 615 iss_t r_iss; 616 MultiWriteBuffer<paddr_t> r_wbuf; 617 GenericCache<paddr_t> r_icache; 618 GenericCache<paddr_t> r_dcache; 619 GenericTlb<paddr_t> r_itlb; 620 GenericTlb<paddr_t> r_dtlb; 624 621 625 622 ////////////////////////////////////////////////////////////////// … … 627 624 ////////////////////////////////////////////////////////////////// 628 625 629 sc_signal<paddr_t> r_dcache_llsc_paddr; 630 sc_signal<uint32_t> r_dcache_llsc_key; 631 sc_signal<uint32_t> r_dcache_llsc_count; 632 sc_signal<bool> r_dcache_llsc_valid; 633 634 635 sc_signal<bool> r_cache_frozen; 626 sc_signal<paddr_t> r_dcache_llsc_paddr; 627 sc_signal<uint32_t> r_dcache_llsc_key; 628 sc_signal<uint32_t> r_dcache_llsc_count; 629 sc_signal<bool> r_dcache_llsc_valid; 636 630 637 631 //////////////////////////////// 638 632 // Activity counters 639 633 //////////////////////////////// 640 uint32_t m_cpt_dcache_data_read; 641 uint32_t m_cpt_dcache_data_write; 642 uint32_t m_cpt_dcache_dir_read; 643 uint32_t m_cpt_dcache_dir_write; 644 645 uint32_t m_cpt_icache_data_read; 646 uint32_t m_cpt_icache_data_write; 647 uint32_t m_cpt_icache_dir_read; 648 uint32_t m_cpt_icache_dir_write; 649 650 uint32_t m_cpt_frz_cycles; 651 uint32_t m_cpt_total_cycles; 634 uint32_t m_cpt_dcache_data_read; // DCACHE DATA READ 635 uint32_t m_cpt_dcache_data_write; // DCACHE DATA WRITE 636 uint32_t m_cpt_dcache_dir_read; // DCACHE DIR READ 637 uint32_t m_cpt_dcache_dir_write; // DCACHE DIR WRITE 638 639 uint32_t m_cpt_icache_data_read; // ICACHE DATA READ 640 uint32_t m_cpt_icache_data_write; // ICACHE DATA WRITE 641 uint32_t m_cpt_icache_dir_read; // ICACHE DIR READ 642 uint32_t m_cpt_icache_dir_write; // ICACHE DIR WRITE 643 644 uint32_t m_cpt_frz_cycles; // number of cycles where the cpu is frozen 645 uint32_t m_cpt_total_cycles; // total number of cycles 652 646 653 647 // Cache activity counters 654 uint32_t m_cpt_data_read; 655 uint32_t m_cpt_data_write; 648 uint32_t m_cpt_data_read; // total number of read data 649 uint32_t m_cpt_data_write; // total number of write data 656 650 uint32_t m_cpt_data_write_back; 651 uint32_t m_cpt_data_write_miss; // number of total write miss 652 uint32_t m_cpt_data_write_on_zombi; // number of frozen cycles related to blocked write on ZOMBI line 653 uint32_t m_cpt_data_write_on_zombi_ncc; // number of frozen cycles related to blocked write on NCC ZOMBI line 657 654 uint32_t m_cpt_data_cleanup; 658 655 uint32_t m_cpt_data_sc; 659 uint32_t m_cpt_data_miss; // number of read miss 660 uint32_t m_cpt_ins_miss; // number of instruction miss 661 uint32_t m_cpt_unc_read; // number of read uncached 662 uint32_t m_cpt_write_cached; // number of cached write 663 uint32_t m_cpt_ins_read; // number of instruction read 664 uint32_t m_cpt_ins_spc_miss; // number of speculative instruction miss 665 666 uint32_t m_cost_write_frz; // number of frozen cycles related to write buffer 667 uint32_t m_cost_data_miss_frz; // number of frozen cycles related to data miss 668 uint32_t m_cost_unc_read_frz; // number of frozen cycles related to uncached read 669 uint32_t m_cost_ins_miss_frz; // number of frozen cycles related to ins miss 670 671 uint32_t m_cpt_imiss_transaction; // number of VCI instruction miss transactions 672 uint32_t m_cpt_dmiss_transaction; // number of VCI data miss transactions 673 uint32_t m_cpt_unc_transaction; // number of VCI uncached read transactions 674 uint32_t m_cpt_dunc_transaction; // number of VCI uncached read transactions 675 uint32_t m_cpt_ll_transaction; // number of VCI uncached read transactions 676 uint32_t m_cpt_write_transaction; // number of VCI write transactions 677 uint32_t m_cpt_icache_unc_transaction; 678 679 uint32_t m_cost_imiss_transaction; // cumulated duration for VCI IMISS transactions 680 uint32_t m_cost_dmiss_transaction; // cumulated duration for VCI DMISS transactions 681 uint32_t m_cost_unc_transaction; // cumulated duration for VCI UNC transactions 682 uint32_t m_cost_write_transaction; // cumulated duration for VCI WRITE transactions 683 uint32_t m_cost_icache_unc_transaction; // cumulated duration for VCI IUNC transactions 684 uint32_t m_length_write_transaction; // cumulated length for VCI WRITE transactions 656 uint32_t m_cpt_dcache_miss; // number of read miss 657 uint32_t m_cpt_icache_miss; // number of instruction miss 658 uint32_t m_cpt_ins_read; // number of instruction read 659 660 uint32_t m_cost_data_miss_frz; // number of frozen cycles related to data miss 661 uint32_t m_cost_ins_miss_frz; // number of frozen cycles related to ins miss 662 663 uint32_t m_cpt_write_transaction; // number of VCI write transactions 664 uint32_t m_length_write_transaction; // cumulated length for VCI WRITE transactions 685 665 686 666 // TLB activity counters 687 uint32_t m_cpt_ins_tlb_read; // number of instruction tlb read 688 uint32_t m_cpt_ins_tlb_miss; // number of instruction tlb miss 689 uint32_t m_cpt_ins_tlb_update_acc; // number of instruction tlb update 690 uint32_t m_cpt_ins_tlb_occup_cache; // number of instruction tlb occupy data cache line 691 uint32_t m_cpt_ins_tlb_hit_dcache; // number of instruction tlb hit in data cache 692 693 uint32_t m_cpt_data_tlb_read; // number of data tlb read 694 uint32_t m_cpt_data_tlb_miss; // number of data tlb miss 695 uint32_t m_cpt_data_tlb_update_acc; // number of data tlb update 696 uint32_t m_cpt_data_tlb_update_dirty; // number of data tlb update dirty 697 uint32_t m_cpt_data_tlb_hit_dcache; // number of data tlb hit in data cache 698 uint32_t m_cpt_data_tlb_occup_cache; // number of data tlb occupy data cache line 667 uint32_t m_cpt_itlb_read; // number of instruction tlb read 668 uint32_t m_cpt_itlb_miss; // number of instruction tlb miss 669 uint32_t m_cpt_itlb_write; // number of instruction tlb update 670 671 uint32_t m_cpt_dtlb_read; // number of data tlb read 672 uint32_t m_cpt_dtlb_miss; // number of data tlb miss 673 uint32_t m_cpt_dtlb_write; // number of data tlb update 674 675 uint32_t m_cost_ins_tlb_miss_frz; // number of frozen cycles related to instruction tlb miss 676 677 // coherence activity counters 678 uint32_t m_cpt_cleanup_data_not_dirty; // number of total cleanup data without extra data flits 679 uint32_t m_cpt_cleanup_data_dirty_word; // number of total words dirty in cleanup data 680 681 682 683 // counters NOT implemented 684 uint32_t m_cost_write_frz; // number of frozen cycles related to write buffer 685 uint32_t m_cost_unc_read_frz; // number of frozen cycles related to uncached read 686 uint32_t m_cpt_imiss_transaction; // number of VCI instruction miss transactions 687 uint32_t m_cpt_dmiss_transaction; // number of VCI data miss transactions 688 uint32_t m_cpt_unc_transaction; // number of VCI uncached read transactions 689 uint32_t m_cost_imiss_transaction; // cumulated duration for VCI IMISS transactions 690 uint32_t m_cost_dmiss_transaction; // cumulated duration for VCI DMISS transactions 691 uint32_t m_cost_unc_transaction; // cumulated duration for VCI UNC transactions 692 uint32_t m_cost_write_transaction; // cumulated duration for VCI WRITE transactions 693 uint32_t m_cpt_data_tlb_update_dirty; // number of data tlb update dirty 694 uint32_t m_cpt_ins_tlb_hit_dcache; // number of instruction tlb hit in data cache 695 uint32_t m_cpt_data_tlb_hit_dcache; // number of data tlb hit in data cache 696 uint32_t m_cost_data_tlb_miss_frz; // number of frozen cycles related to data tlb miss 697 uint32_t m_cost_ins_tlb_update_acc_frz; // number of frozen cycles related to instruction tlb update acc 698 uint32_t m_cost_data_tlb_update_acc_frz; // number of frozen cycles related to data tlb update acc 699 uint32_t m_cost_data_tlb_update_dirty_frz; // number of frozen cycles related to data tlb update dirty 700 uint32_t m_cpt_itlbmiss_transaction; // number of itlb miss transactions 701 uint32_t m_cpt_dtlbmiss_transaction; // number of dtlb miss transactions 702 uint32_t m_cost_itlbmiss_transaction; // cumulated duration for VCI instruction TLB miss transactions 703 uint32_t m_cost_dtlbmiss_transaction; // cumulated duration for VCI data TLB miss transactions 704 uint32_t m_cpt_cc_broadcast; // number of coherence broadcast commands 705 uint32_t m_cost_updt_data_frz; // number of frozen cycles related to coherence update data packets 706 uint32_t m_cost_inval_ins_frz; // number of frozen cycles related to coherence inval instruction packets 707 uint32_t m_cost_inval_data_frz; // number of frozen cycles related to coherence inval data packets 708 uint32_t m_cost_broadcast_frz; // number of frozen cycles related to coherence broadcast packets 709 uint32_t m_cpt_cc_cleanup_data; // number of coherence cleanup packets 710 uint32_t m_cpt_cc_cleanup_ins; // number of coherence cleanup packets 711 uint32_t m_cpt_dunc_transaction; // number of VCI uncached read transactions 712 uint32_t m_cpt_ll_transaction; // number of VCI uncached read transactions 713 uint32_t m_cpt_cc_update_dcache; // number of coherence update data commands 714 uint32_t m_cpt_cc_inval_icache; // number of coherence inval instruction commands 715 uint32_t m_cpt_cc_inval_dcache; // number of coherence inval data commands 716 uint32_t m_cpt_unc_read; // number of read uncached 717 uint32_t m_cpt_write_cached; // number of cached write 699 718 uint32_t m_cpt_tlb_occup_dcache; 700 719 701 uint32_t m_cost_ins_tlb_miss_frz; // number of frozen cycles related to instruction tlb miss702 uint32_t m_cost_data_tlb_miss_frz; // number of frozen cycles related to data tlb miss703 uint32_t m_cost_ins_tlb_update_acc_frz; // number of frozen cycles related to instruction tlb update acc704 uint32_t m_cost_data_tlb_update_acc_frz; // number of frozen cycles related to data tlb update acc705 uint32_t m_cost_data_tlb_update_dirty_frz; // number of frozen cycles related to data tlb update dirty706 uint32_t m_cost_ins_tlb_occup_cache_frz; // number of frozen cycles related to instruction tlb miss operate in dcache707 uint32_t m_cost_data_tlb_occup_cache_frz; // number of frozen cycles related to data tlb miss operate in dcache708 709 uint32_t m_cpt_itlbmiss_transaction; // number of itlb miss transactions710 uint32_t m_cpt_itlb_ll_transaction; // number of itlb ll acc transactions711 uint32_t m_cpt_itlb_sc_transaction; // number of itlb sc acc transactions712 uint32_t m_cpt_dtlbmiss_transaction; // number of dtlb miss transactions713 uint32_t m_cpt_dtlb_ll_transaction; // number of dtlb ll acc transactions714 uint32_t m_cpt_dtlb_sc_transaction; // number of dtlb sc acc transactions715 uint32_t m_cpt_dtlb_ll_dirty_transaction; // number of dtlb ll dirty transactions716 uint32_t m_cpt_dtlb_sc_dirty_transaction; // number of dtlb sc dirty transactions717 718 uint32_t m_cost_itlbmiss_transaction; // cumulated duration for VCI instruction TLB miss transactions719 uint32_t m_cost_itlb_ll_transaction; // cumulated duration for VCI instruction TLB ll acc transactions720 uint32_t m_cost_itlb_sc_transaction; // cumulated duration for VCI instruction TLB sc acc transactions721 uint32_t m_cost_dtlbmiss_transaction; // cumulated duration for VCI data TLB miss transactions722 uint32_t m_cost_dtlb_ll_transaction; // cumulated duration for VCI data TLB ll acc transactions723 uint32_t m_cost_dtlb_sc_transaction; // cumulated duration for VCI data TLB sc acc transactions724 uint32_t m_cost_dtlb_ll_dirty_transaction; // cumulated duration for VCI data TLB ll dirty transactions725 uint32_t m_cost_dtlb_sc_dirty_transaction; // cumulated duration for VCI data TLB sc dirty transactions726 727 // coherence activity counters728 uint32_t m_cpt_cc_update_icache; // number of coherence update instruction commands729 uint32_t m_cpt_cc_update_dcache; // number of coherence update data commands730 uint32_t m_cpt_cc_inval_icache; // number of coherence inval instruction commands731 uint32_t m_cpt_cc_inval_dcache; // number of coherence inval data commands732 uint32_t m_cpt_cc_broadcast; // number of coherence broadcast commands733 734 uint32_t m_cost_updt_data_frz; // number of frozen cycles related to coherence update data packets735 uint32_t m_cost_inval_ins_frz; // number of frozen cycles related to coherence inval instruction packets736 uint32_t m_cost_inval_data_frz; // number of frozen cycles related to coherence inval data packets737 uint32_t m_cost_broadcast_frz; // number of frozen cycles related to coherence broadcast packets738 739 uint32_t m_cpt_cc_cleanup_ins; // number of coherence cleanup packets740 uint32_t m_cpt_cc_cleanup_data; // number of coherence cleanup packets741 uint32_t m_cpt_cleanup_data_not_dirty; // number of total cleanup data without extra data flits742 uint32_t m_cpt_cleanup_data_dirty_word; // number of total words dirty in cleanup data743 uint32_t m_cpt_data_write_miss; // number of total write miss744 uint32_t m_cpt_data_write_on_zombi; // number of frozen cycles related to blocked write on line NCC/CC ZOMBI745 uint32_t m_cpt_data_write_on_zombi_ncc; // number of frozen cycles related to blocked write on line NCC ZOMBI746 747 uint32_t m_cpt_icleanup_transaction; // number of instruction cleanup transactions748 uint32_t m_cpt_dcleanup_transaction; // number of instructinumber of data cleanup transactions749 uint32_t m_cost_icleanup_transaction; // cumulated duration for VCI instruction cleanup transactions750 uint32_t m_cost_dcleanup_transaction; // cumulated duration for VCI data cleanup transactions751 752 uint32_t m_cost_ins_tlb_inval_frz; // number of frozen cycles related to checking ins tlb invalidate753 uint32_t m_cpt_ins_tlb_inval; // number of ins tlb invalidate754 755 uint32_t m_cost_data_tlb_inval_frz; // number of frozen cycles related to checking data tlb invalidate756 uint32_t m_cpt_data_tlb_inval; // number of data tlb invalidate757 720 758 721 // FSM activity counters … … 764 727 uint32_t m_cpt_fsm_cc_send [64]; 765 728 766 uint32_t m_cpt_stop_simulation; 767 bool m_monitor_ok; 729 uint32_t m_cpt_stop_simulation; // used to stop simulation if frozen 730 bool m_monitor_ok; // used to debug cache output 768 731 uint32_t m_monitor_base; 769 732 uint32_t m_monitor_length; … … 774 737 public: 775 738 VciCcVCacheWrapper( 776 sc_module_name 777 const int 778 const soclib::common::MappingTable 779 const soclib::common::IntTab 780 const size_t 781 const size_t 782 const size_t 783 const size_t 784 const size_t 785 const size_t 786 const size_t 787 const size_t 788 const size_t 789 const size_t 790 const size_t 791 const size_t 792 const size_t 793 const size_t 794 const size_t 795 const uint32_t 796 const uint32_t 797 const bool 739 sc_module_name name, 740 const int proc_id, 741 const soclib::common::MappingTable &mtd, 742 const soclib::common::IntTab &srcid, 743 const size_t cc_global_id, 744 const size_t itlb_ways, 745 const size_t itlb_sets, 746 const size_t dtlb_ways, 747 const size_t dtlb_sets, 748 const size_t icache_ways, 749 const size_t icache_sets, 750 const size_t icache_words, 751 const size_t dcache_ways, 752 const size_t dcache_sets, 753 const size_t dcache_words, 754 const size_t wbuf_nlines, 755 const size_t wbuf_nwords, 756 const size_t x_width, 757 const size_t y_width, 758 const uint32_t max_frozen_cycles, 759 const uint32_t debug_start_cycle, 760 const bool debug_ok ); 798 761 799 762 ~VciCcVCacheWrapper(); -
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"