Changeset 291 for trunk/modules/vci_cc_vcache_wrapper_v4/caba
- Timestamp:
- Jan 28, 2013, 1:59:32 PM (12 years ago)
- Location:
- trunk/modules/vci_cc_vcache_wrapper_v4/caba
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/modules/vci_cc_vcache_wrapper_v4/caba/metadata/vci_cc_vcache_wrapper_v4.sd
r183 r291 16 16 Uses('caba:generic_fifo'), 17 17 Uses('caba:generic_cam'), 18 Uses('caba:generic_llsc_local_table'), 18 19 Uses('caba:generic_cache', 19 20 addr_t = parameter.StringExt('sc_dt::sc_uint<%d> ', -
trunk/modules/vci_cc_vcache_wrapper_v4/caba/source/include/vci_cc_vcache_wrapper_v4.h
r284 r291 37 37 #include "generic_cache.h" 38 38 #include "generic_cam.h" 39 #include "generic_llsc_local_table.h" 39 40 #include "vci_initiator.h" 40 41 #include "vci_target.h" … … 60 61 61 62 typedef typename vci_param::addr_t paddr_t; 63 typedef typename vci_param::data_t vci_data_t; 62 64 typedef typename vci_param::be_t vci_be_t; 63 65 typedef typename vci_param::srcid_t vci_srcid_t; … … 124 126 DCACHE_MISS_WAIT, 125 127 DCACHE_MISS_UPDT, 126 // handling processor unc and sc requests128 // handling processor unc, ll and sc requests 127 129 DCACHE_UNC_WAIT, 130 DCACHE_LL_WAIT, 128 131 DCACHE_SC_WAIT, 129 132 // handling coherence requests … … 142 145 CMD_DATA_UNC, 143 146 CMD_DATA_WRITE, 147 CMD_DATA_LL, 148 CMD_DATA_SC, 144 149 CMD_DATA_CAS, 145 150 }; … … 151 156 RSP_DATA_MISS, 152 157 RSP_DATA_UNC, 158 RSP_DATA_LL, 153 159 RSP_DATA_WRITE, 154 160 }; … … 400 406 sc_signal<bool> r_dcache_vci_unc_req; // uncacheable read request 401 407 sc_signal<bool> r_dcache_vci_unc_be; // uncacheable read byte enable 402 sc_signal<bool> r_dcache_vci_sc_req; // atomic write request (Compare & swap) 403 sc_signal<uint32_t> r_dcache_vci_sc_old; // previous data value for an atomic write 404 sc_signal<uint32_t> r_dcache_vci_sc_new; // new data value for an atomic write 408 sc_signal<bool> r_dcache_vci_cas_req; // atomic write request CAS 409 sc_signal<uint32_t> r_dcache_vci_cas_old; // previous data value for an atomic write CAS 410 sc_signal<uint32_t> r_dcache_vci_cas_new; // new data value for an atomic write CAS 411 sc_signal<bool> r_dcache_vci_ll_req; // atomic read request LL 412 sc_signal<bool> r_dcache_vci_sc_req; // atomic write request SC 413 sc_signal<vci_data_t> r_dcache_vci_sc_data; // SC data (command) 405 414 406 415 // register used for XTN inval … … 425 434 // dcache flush handling 426 435 sc_signal<size_t> r_dcache_flush_count; // slot counter used for cache flush 436 437 // ll rsp handling 438 sc_signal<size_t> r_dcache_ll_rsp_count; // flit counter used for ll rsp 439 440 // sc cmd handling 441 sc_signal<vci_data_t> r_sc_key; // SC key returned by local table 427 442 428 443 // used by the TLB miss sub-fsm … … 438 453 sc_signal<size_t> r_dcache_tlb_set; // selected set in tlb 439 454 440 // LL reservation handling441 sc_signal<bool> r_dcache_ll_valid; // valid LL reservation442 sc_signal<uint32_t> r_dcache_ll_data; // LL reserved data443 sc_signal<paddr_t> r_dcache_ll_vaddr; // LL reserved address444 445 455 // ITLB and DTLB invalidation 446 456 sc_signal<paddr_t> r_dcache_tlb_inval_line; // line index … … 517 527 GenericTlb<paddr_t> r_itlb; 518 528 GenericTlb<paddr_t> r_dtlb; 529 530 ////////////////////////////////////////////////////////////////// 531 // llsc local registration table 532 ////////////////////////////////////////////////////////////////// 533 534 #define LLSCLocalTable GenericLLSCLocalTable<8000, 1, paddr_t, vci_trdid_t, vci_data_t> 535 LLSCLocalTable r_llsc_table; // The llsc local registration table 536 537 typename LLSCLocalTable::in_t table_in ; // llsc local table input signals 538 typename LLSCLocalTable::out_t table_out ; // llsc local table output signals 539 540 #undef LLSCLocalTable 519 541 520 542 //////////////////////////////// -
trunk/modules/vci_cc_vcache_wrapper_v4/caba/source/src/vci_cc_vcache_wrapper_v4.cpp
r288 r291 97 97 98 98 "DCACHE_UNC_WAIT", 99 "DCACHE_LL_WAIT", 99 100 "DCACHE_SC_WAIT", 100 101 … … 112 113 "CMD_DATA_UNC", 113 114 "CMD_DATA_WRITE", 115 "CMD_DATA_LL", 116 "CMD_DATA_SC", 114 117 "CMD_DATA_CAS", 115 118 }; … … 120 123 "RSP_DATA_MISS", 121 124 "RSP_DATA_UNC", 125 "RSP_DATA_LL", 122 126 "RSP_DATA_WRITE", 123 127 }; … … 277 281 r_dcache_vci_unc_req("r_dcache_vci_unc_req"), 278 282 r_dcache_vci_unc_be("r_dcache_vci_unc_be"), 283 r_dcache_vci_cas_req("r_dcache_vci_cas_req"), 284 r_dcache_vci_cas_old("r_dcache_vci_cas_old"), 285 r_dcache_vci_cas_new("r_dcache_vci_cas_new"), 286 r_dcache_vci_ll_req("r_dcache_vci_ll_req"), 279 287 r_dcache_vci_sc_req("r_dcache_vci_sc_req"), 280 r_dcache_vci_sc_old("r_dcache_vci_sc_old"), 281 r_dcache_vci_sc_new("r_dcache_vci_sc_new"), 288 r_dcache_vci_sc_data("r_dcache_vci_sc_data"), 282 289 283 290 r_dcache_xtn_way("r_dcache_xtn_way"), … … 307 314 r_dcache_tlb_way("r_dcache_tlb_way"), 308 315 r_dcache_tlb_set("r_dcache_tlb_set"), 309 310 r_dcache_ll_valid("r_dcache_ll_valid"),311 r_dcache_ll_data("r_dcache_ll_data"),312 r_dcache_ll_vaddr("r_dcache_ll_vaddr"),313 316 314 317 r_dcache_tlb_inval_line("r_dcache_tlb_inval_line"), … … 666 669 ///////////////////////// 667 670 { 671 #define LLSCLocalTable GenericLLSCLocalTable<8000, 1, paddr_t, vci_trdid_t, vci_data_t> 668 672 if ( not p_resetn.read() ) 669 673 { … … 714 718 r_dcache_vci_miss_req = false; 715 719 r_dcache_vci_unc_req = false; 720 r_dcache_vci_cas_req = false; 721 r_dcache_vci_ll_req = false; 716 722 r_dcache_vci_sc_req = false; 717 723 718 724 // No uncacheable write pending 719 725 r_dcache_pending_unc_write = false; 720 721 // No LL reservation722 r_dcache_ll_valid = false;723 726 724 727 // No processor XTN request pending … … 854 857 for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_cmd_cleanup [i] = 0; 855 858 for (uint32_t i=0; i<32 ; ++i) m_cpt_fsm_rsp_cleanup [i] = 0; 859 860 // init the llsc local registration table 861 r_llsc_table.init(); 856 862 857 863 return; … … 1936 1942 // 4/ Atomic instructions LL/SC 1937 1943 // The LL/SC address can be cacheable or non cacheable. 1938 // The reservation registers (r_dcache_ll_valid, r_dcache_ll_vaddr and 1939 // r_dcache_ll_data are stored in the L1 cache controller, and not in the 1940 // memory controller. 1941 // - LL requests from the processor are transmitted as standard VCI 1942 // READ transactions (one word / one line, depending on the cacheability). 1944 // The llsc_local_table holds a registration for an active LL/SC 1945 // operation (with an address, a registration key, an aging counter and a 1946 // valid bit). 1947 // - LL requests from the processor are transmitted as a one flit VCI 1948 // CMD_LOCKED_READ transaction with TYPE_LL as PKTID value. PLEN must 1949 // be 8 as the response is 2 flits long (data and registration key) 1943 1950 // - SC requests from the processor are systematically transmitted to the 1944 // memory cache as Compare&swap requests (both the data value stored in the 1945 // r_dcache_ll_data register and the new value). 1951 // memory cache as 2 flits VCI CMD_NOP (or CMD_STORE_COND) 1952 // transactions, with TYPE_SC as PKTID value (the first flit contains 1953 // the registration key, the second flit contains the data to write in 1954 // case of success). 1946 1955 // The cache is not updated, as this is done in case of success by the 1947 1956 // coherence transaction. … … 1974 1983 m_drsp.error = false; 1975 1984 m_drsp.rdata = 0; 1985 1986 // keep track of the local llsc table access and perform a NOP access if 1987 // necessary at the end of the DCACHE transition function 1988 bool llsc_local_table_access_done = false; 1976 1989 1977 1990 switch ( r_dcache_fsm.read() ) 1978 1991 { 1979 case DCACHE_IDLE: // There is 8conditions to exit the IDLE state :1992 case DCACHE_IDLE: // There are 9 conditions to exit the IDLE state : 1980 1993 // 1) Dirty bit update (processor) => DCACHE_DIRTY_GET_PTE 1981 1994 // 2) Coherence request (TGT FSM) => DCACHE_CC_CHECK … … 1985 1998 // 6) Cacheable read miss (processor) => DCACHE_MISS_VICTIM 1986 1999 // 7) Uncacheable read (processor) => DCACHE_UNC_WAIT 1987 // 8) SC access (processor) => DCACHE_SC_WAIT 2000 // 8) LL access (processor) => DCACHE_LL_WAIT 2001 // 9) SC access (processor) => DCACHE_SC_WAIT 1988 2002 // 1989 2003 // The dtlb is unconditionally accessed to translate the … … 2150 2164 // dtlb miss. If dtlb is OK, It enters the three stage pipe-line (fully 2151 2165 // handled by the IDLE state), and the processor request is acknowledged. 2152 // 2) A processor READ or LLrequest generate a simultaneouss access to2166 // 2) A processor READ request generate a simultaneouss access to 2153 2167 // both dcache data and dcache directoty, using speculative PPN, but 2154 2168 // is delayed if the write pipe-line is not empty. 2155 2169 // In case of miss, we wait the VCI response in DCACHE_UNC_WAIT or 2156 2170 // DCACHE_MISS_WAIT states. 2157 // 3) A processor SC request is delayed until the write pipe-line is empty. 2171 // 3) A processor LL request generate a VCI LL transaction. We wait for 2172 // the response in DCACHE_LL_WAIT state. 2173 // 4) A processor SC request is delayed until the write pipe-line is empty. 2158 2174 // A VCI SC transaction is launched, and we wait the VCI response in 2159 2175 // DCACHE_SC_WAIT state. It can be completed by a "long write" if the … … 2535 2551 r_dcache_p0_cacheable = cacheable; 2536 2552 2537 // READ or LLrequest2553 // READ request 2538 2554 // The read requests are taken only if the write pipe-line is empty. 2539 2555 // If dcache hit, dtlb hit, and speculative PPN OK, data in one cycle. … … 2541 2557 // If dcache miss, we go to DCACHE_MISS_VICTIM state. 2542 2558 // If uncacheable, we go to DCACHE_UNC_WAIT state. 2543 // In case of LL, the LL registration is done when the data is returned: 2544 // in DCACHE_IDLE if cacheable / in DCACHE_UNC_WAIT if uncacheable 2545 if ( ((m_dreq.type == iss_t::DATA_READ) or (m_dreq.type == iss_t::DATA_LL)) 2559 if ( ((m_dreq.type == iss_t::DATA_READ)) 2546 2560 and not r_dcache_p0_valid.read() and not r_dcache_p1_valid.read() ) 2547 2561 { … … 2581 2595 m_drsp.valid = true; 2582 2596 m_drsp.rdata = cache_rdata; 2583 2584 // makes reservation in case of LL2585 if ( m_dreq.type == iss_t::DATA_LL )2586 {2587 r_dcache_ll_valid = true;2588 r_dcache_ll_vaddr = m_dreq.addr;2589 r_dcache_ll_data = cache_rdata;2590 }2591 2597 #if DEBUG_DCACHE 2592 2598 if ( m_debug_dcache_fsm ) … … 2606 2612 2607 2613 r_dcache_p0_valid = false; 2608 } // end READ or LL 2614 } // end READ 2615 2616 // LL request 2617 // The LL requests are taken only if the write pipe-line is empty. 2618 // We request an LL transaction to CMD FSM and go to 2619 // DCACHE_LL_WAIT state, that will return the response to 2620 // the processor. 2621 else if ( ((m_dreq.type == iss_t::DATA_LL)) 2622 and not r_dcache_p0_valid.read() and not r_dcache_p1_valid.read() ) 2623 { 2624 // prepare llsc local table access 2625 table_in.cmd = LLSCLocalTable::LL_CMD ; 2626 table_in.address = paddr; 2627 // access the table 2628 r_llsc_table.exec(table_in, table_out); 2629 llsc_local_table_access_done = true; 2630 // test if the table is done 2631 if(!table_out.done) 2632 { 2633 r_dcache_p0_valid = false; 2634 break; 2635 } 2636 // request an LL CMD and go to DCACHE_LL_WAIT state 2637 r_dcache_vci_ll_req = true; 2638 r_dcache_ll_rsp_count = 0; 2639 r_dcache_p0_valid = false; 2640 r_dcache_vci_paddr = paddr; 2641 r_dcache_fsm = DCACHE_LL_WAIT; 2642 }// end LL 2609 2643 2610 2644 // WRITE request: … … 2640 2674 m_cpt_data_write++; 2641 2675 #endif 2676 table_in.cmd = LLSCLocalTable::SW_CMD ; 2677 table_in.address = paddr; 2678 r_llsc_table.exec(table_in, table_out) ; 2679 llsc_local_table_access_done = true; 2680 if(!table_out.done) 2681 { 2682 r_dcache_p0_valid = false; 2683 break; 2684 } 2642 2685 m_drsp.valid = true; 2643 2686 m_drsp.rdata = 0; … … 2648 2691 // SC request: 2649 2692 // The SC requests are taken only if the write pipe-line is empty. 2650 // - if there is no valid registered LL, we just return rdata = 1 2651 // (atomic access failed) and the SC transaction is completed. 2652 // - if a valid LL reservation (with the same address) is registered, 2653 // we test if a DIRTY bit update is required. 2654 // If the TLB is activated and the PTE Dirty bit is not set, we stall 2655 // the processor and set the Dirty bit before handling the write request. 2656 // If we don't need to set the Dirty bit, we request a SC transaction 2657 // to CMD FSM and go to DCACHE_SC_WAIT state, that will return 2658 // the response to the processor. 2659 // We don't check a possible write hit in dcache, as the cache update 2660 // is done by the coherence transaction induced by the SC... 2693 // We test if a DIRTY bit update is required. 2694 // If the TLB is activated and the PTE Dirty bit is not set, we stall 2695 // the processor and set the Dirty bit before handling the write request. 2696 // If we don't need to set the Dirty bit, we request a SC transaction 2697 // to CMD FSM and go to DCACHE_SC_WAIT state, that will return 2698 // the response to the processor. 2699 // We don't check a possible write hit in dcache, as the cache update 2700 // is done by the coherence transaction induced by the SC... 2661 2701 else if ( ( m_dreq.type == iss_t::DATA_SC ) 2662 2702 and not r_dcache_p0_valid.read() and not r_dcache_p1_valid.read() ) 2663 2703 { 2664 if ( (r_dcache_ll_vaddr.read() != m_dreq.addr) 2665 or not r_dcache_ll_valid.read() ) // no valid registered LL 2666 { 2704 if ( (r_mmu_mode.read() & DATA_TLB_MASK ) 2705 and not tlb_flags.d ) // Dirty bit must be set 2706 { 2707 // The PTE physical address is obtained from the nline value (dtlb), 2708 // and the word index (virtual address) 2709 if ( tlb_flags.b ) // PTE1 2710 { 2711 r_dcache_dirty_paddr = (paddr_t)(tlb_nline*(m_dcache_words<<2)) | 2712 (paddr_t)((m_dreq.addr>>19) & 0x3c); 2713 } 2714 else // PTE2 2715 { 2716 r_dcache_dirty_paddr = (paddr_t)(tlb_nline*(m_dcache_words<<2)) | 2717 (paddr_t)((m_dreq.addr>>9) & 0x38); 2718 } 2719 r_dcache_fsm = DCACHE_DIRTY_GET_PTE; 2720 } 2721 else // SC request accepted 2722 { 2667 2723 #ifdef INSTRUMENTATION 2668 2724 m_cpt_data_sc++; 2669 2725 #endif 2670 m_drsp.valid = true;2671 m_drsp.rdata = 1;2672 r_dcache_ll_valid = false;2673 }2674 else // valid registered LL2675 {2676 if ( (r_mmu_mode.read() & DATA_TLB_MASK )2677 and not tlb_flags.d ) // Dirty bit must be set2726 // prepare llsc local table access 2727 table_in.cmd = LLSCLocalTable::SC_CMD ; 2728 table_in.address = paddr; 2729 // access the table 2730 r_llsc_table.exec(table_in, table_out) ; 2731 llsc_local_table_access_done = true; 2732 // test if the table is done 2733 if(!table_out.done) 2678 2734 { 2679 // The PTE physical address is obtained from the nline value (dtlb), 2680 // and the word index (virtual address) 2681 if ( tlb_flags.b ) // PTE1 2682 { 2683 r_dcache_dirty_paddr = (paddr_t)(tlb_nline*(m_dcache_words<<2)) | 2684 (paddr_t)((m_dreq.addr>>19) & 0x3c); 2685 } 2686 else // PTE2 2687 { 2688 r_dcache_dirty_paddr = (paddr_t)(tlb_nline*(m_dcache_words<<2)) | 2689 (paddr_t)((m_dreq.addr>>9) & 0x38); 2690 } 2691 r_dcache_fsm = DCACHE_DIRTY_GET_PTE; 2735 r_dcache_p0_valid = false; 2736 break; 2692 2737 } 2693 else // SC request accepted 2738 // test for a local fail 2739 if(table_out.hit) 2694 2740 { 2695 #ifdef INSTRUMENTATION 2696 m_cpt_data_sc++; 2697 #endif 2698 2699 r_dcache_vci_paddr = paddr; 2700 r_dcache_vci_sc_req = true; 2701 r_dcache_vci_sc_old = r_dcache_ll_data.read(); 2702 r_dcache_vci_sc_new = m_dreq.wdata; 2703 r_dcache_ll_valid = false; 2704 r_dcache_fsm = DCACHE_SC_WAIT; 2741 // request an SC CMD and go to DCACHE_SC_WAIT state 2742 r_sc_key = table_out.key; 2743 r_dcache_vci_paddr = paddr; 2744 r_dcache_vci_sc_req = true; 2745 r_dcache_vci_sc_data = m_dreq.wdata; 2746 r_dcache_fsm = DCACHE_SC_WAIT; 2747 } 2748 else // local fail 2749 { 2750 m_drsp.valid = true; 2751 m_drsp.rdata = 0x1; 2705 2752 } 2706 2753 } … … 2984 3031 { 2985 3032 pt_updt = true; 2986 r_dcache_vci_ sc_old = pte;2987 r_dcache_vci_ sc_new = pte | PTE_L_MASK;3033 r_dcache_vci_cas_old = pte; 3034 r_dcache_vci_cas_new = pte | PTE_L_MASK; 2988 3035 pte = pte | PTE_L_MASK; 2989 3036 r_dcache_tlb_pte_flags = pte; … … 2995 3042 { 2996 3043 pt_updt = true; 2997 r_dcache_vci_ sc_old = pte;2998 r_dcache_vci_ sc_new = pte | PTE_R_MASK;3044 r_dcache_vci_cas_old = pte; 3045 r_dcache_vci_cas_new = pte | PTE_R_MASK; 2999 3046 pte = pte | PTE_R_MASK; 3000 3047 r_dcache_tlb_pte_flags = pte; … … 3219 3266 { 3220 3267 pt_updt = true; 3221 r_dcache_vci_ sc_old = pte_flags;3222 r_dcache_vci_ sc_new = pte_flags | PTE_L_MASK;3268 r_dcache_vci_cas_old = pte_flags; 3269 r_dcache_vci_cas_new = pte_flags | PTE_L_MASK; 3223 3270 pte_flags = pte_flags | PTE_L_MASK; 3224 3271 r_dcache_tlb_pte_flags = pte_flags; … … 3230 3277 { 3231 3278 pt_updt = true; 3232 r_dcache_vci_ sc_old = pte_flags;3233 r_dcache_vci_ sc_new = pte_flags | PTE_R_MASK;3279 r_dcache_vci_cas_old = pte_flags; 3280 r_dcache_vci_cas_new = pte_flags | PTE_R_MASK; 3234 3281 pte_flags = pte_flags | PTE_R_MASK; 3235 3282 r_dcache_tlb_pte_flags = pte_flags; … … 3311 3358 } 3312 3359 #endif 3313 // r_dcache_vci_sc_old & r_dcache_vci_sc_new registers are already set 3314 r_dcache_vci_paddr = r_dcache_tlb_paddr.read(); 3315 r_dcache_vci_sc_req = true; 3360 // r_dcache_vci_cas_old & r_dcache_vci_cas_new registers are already set 3361 r_dcache_vci_paddr = r_dcache_tlb_paddr.read(); 3362 // prepare llsc local table access 3363 table_in.cmd = LLSCLocalTable::SW_CMD; 3364 table_in.address = r_dcache_tlb_paddr.read(); 3365 // access the table 3366 r_llsc_table.exec(table_in, table_out); 3367 llsc_local_table_access_done = true; 3368 // test if the table is done 3369 if(!table_out.done) 3370 break; 3371 // request a CAS CMD and go to DCACHE_TLB_LR_WAIT state 3372 r_dcache_vci_cas_req = true; 3316 3373 r_dcache_fsm = DCACHE_TLB_LR_WAIT; 3317 3374 break; … … 3921 3978 r_mmu_dbvar = m_dreq.addr; 3922 3979 r_vci_rsp_data_error = false; 3923 m_drsp.error 3924 m_drsp.valid 3980 m_drsp.error = true; 3981 m_drsp.valid = true; 3925 3982 r_dcache_fsm = DCACHE_IDLE; 3926 3983 break; … … 3935 3992 if ( m_dreq.valid and (m_dreq.addr == r_dcache_p0_vaddr.read()) ) 3936 3993 { 3937 m_drsp.valid = true; 3938 m_drsp.rdata = r_vci_rsp_fifo_dcache.read(); 3939 3940 // makes reservation in case of LL 3941 if ( m_dreq.type == iss_t::DATA_LL ) 3942 { 3943 r_dcache_ll_valid = true; 3944 r_dcache_ll_data = r_vci_rsp_fifo_dcache.read(); 3945 r_dcache_ll_vaddr = m_dreq.addr; 3946 } 3994 m_drsp.valid = true; 3995 m_drsp.rdata = r_vci_rsp_fifo_dcache.read(); 3947 3996 } 3948 3997 } 3949 3998 break; 3950 3999 } 3951 //////////////////// 3952 case DCACHE_ SC_WAIT: // waiting VCI response after a processor SC request4000 ///////////////////// 4001 case DCACHE_LL_WAIT: 3953 4002 { 3954 4003 // external coherence request … … 3960 4009 } 3961 4010 3962 if ( r_vci_rsp_data_error.read() ) 4011 if ( r_vci_rsp_data_error.read() ) // bus error 3963 4012 { 3964 4013 r_mmu_detr = MMU_READ_DATA_ILLEGAL_ACCESS; … … 3970 4019 break; 3971 4020 } 3972 else if ( r_vci_rsp_fifo_dcache.rok() ) // response available 3973 { 3974 vci_rsp_fifo_dcache_get = true; 3975 m_drsp.valid = true; 4021 else if ( r_vci_rsp_fifo_dcache.rok() ) // data available 4022 { 4023 // consume data 4024 vci_rsp_fifo_dcache_get = true; 4025 if(r_dcache_ll_rsp_count.read() == 0) //first flit 4026 { 4027 //access table 4028 table_in.cmd = LLSCLocalTable::LL_RSP ; 4029 table_in.index = 0;//p_vci_ini_d.rtrdid.read() ; // TODO use this ? 4030 table_in.key = r_vci_rsp_fifo_dcache.read(); 4031 r_llsc_table.exec(table_in, table_out); 4032 llsc_local_table_access_done = true; 4033 r_dcache_ll_rsp_count = r_dcache_ll_rsp_count.read() + 1 ; 4034 } 4035 else //last flit 4036 { 4037 // acknowledge the processor request if it has not been modified 4038 if ( m_dreq.valid and (m_dreq.addr == r_dcache_p0_vaddr.read()) ) 4039 { 4040 m_drsp.valid = true; 4041 m_drsp.rdata = r_vci_rsp_fifo_dcache.read(); 4042 } 4043 r_dcache_fsm = DCACHE_IDLE; 4044 } 4045 } 4046 break; 4047 } 4048 //////////////////// 4049 case DCACHE_SC_WAIT: // waiting VCI response after a processor SC request 4050 { 4051 // external coherence request 4052 if ( r_tgt_dcache_req.read() ) 4053 { 4054 r_dcache_fsm_cc_save = r_dcache_fsm; 4055 r_dcache_fsm = DCACHE_CC_CHECK; 4056 break; 4057 } 4058 4059 if ( r_vci_rsp_data_error.read() ) // bus error 4060 { 4061 r_mmu_detr = MMU_READ_DATA_ILLEGAL_ACCESS; 4062 r_mmu_dbvar = m_dreq.addr; 4063 r_vci_rsp_data_error = false; 4064 m_drsp.error = true; 4065 m_drsp.valid = true; 4066 r_dcache_fsm = DCACHE_IDLE; 4067 break; 4068 } 4069 else if ( r_vci_rsp_fifo_dcache.rok() ) // response available 4070 { 4071 // consume response 4072 vci_rsp_fifo_dcache_get = true; 4073 m_drsp.valid = true; 3976 4074 m_drsp.rdata = r_vci_rsp_fifo_dcache.read(); 3977 4075 r_dcache_fsm = DCACHE_IDLE; 3978 }4076 } 3979 4077 break; 3980 4078 } … … 4002 4100 assert( hit and "error in DCACHE_DIRTY_TLB_SET: the PTE should be in dcache" ); 4003 4101 4004 // request sctransaction to CMD_FSM4102 // request CAS transaction to CMD_FSM 4005 4103 r_dcache_dirty_way = way; 4006 4104 r_dcache_dirty_set = set; 4007 r_dcache_vci_sc_req = true; 4105 // prepare llsc local table access 4106 table_in.cmd = LLSCLocalTable::SW_CMD; 4107 table_in.address = r_dcache_dirty_paddr.read(); 4108 // access the table 4109 r_llsc_table.exec(table_in, table_out); 4110 llsc_local_table_access_done = true; 4111 // test if the table is done 4112 if(!table_out.done) 4113 break; 4114 // request a CAS CMD and go to DCACHE_DIRTY_WAIT state 4115 r_dcache_vci_cas_req = true; 4008 4116 r_dcache_vci_paddr = r_dcache_dirty_paddr.read(); 4009 r_dcache_vci_ sc_old = pte;4010 r_dcache_vci_ sc_new = pte | PTE_D_MASK;4117 r_dcache_vci_cas_old = pte; 4118 r_dcache_vci_cas_new = pte | PTE_D_MASK; 4011 4119 r_dcache_fsm = DCACHE_DIRTY_WAIT; 4012 4120 … … 4041 4149 if ( r_vci_rsp_data_error.read() ) // bus error 4042 4150 { 4043 std::cout << "BUS ERROR in DCACHE_DIRTY_ SC_WAIT state" << std::endl;4151 std::cout << "BUS ERROR in DCACHE_DIRTY_WAIT state" << std::endl; 4044 4152 std::cout << "This should not happen in this state" << std::endl; 4045 4153 exit(0); … … 4053 4161 if ( m_debug_dcache_fsm ) 4054 4162 { 4055 std::cout << " <PROC " << name() << ".DCACHE_DIRTY_ SC_WAIT> SC completed" << std::endl;4163 std::cout << " <PROC " << name() << ".DCACHE_DIRTY_WAIT> SC completed" << std::endl; 4056 4164 } 4057 4165 #endif … … 4303 4411 } 4304 4412 } // end switch r_dcache_fsm 4413 // perform a NOP access the the local llsc table if necessary 4414 if(llsc_local_table_access_done == false) 4415 { 4416 table_in.cmd = LLSCLocalTable::NOP; 4417 r_llsc_table.exec(table_in, table_out); 4418 } 4305 4419 4306 4420 ///////////////// wbuf update ////////////////////////////////////////////////////// … … 4347 4461 // - r_dcache_vci_miss_req (reset) 4348 4462 // - r_dcache_vci_unc_req (reset) 4349 // - r_dcache_vci_sc_req (reset) 4463 // - r_dcache_vci_ll_req (reset) 4464 // - r_dcache_vci_sc_req (reset in case of local sc fail) 4465 // - r_dcache_vci_cas_req (reset) 4350 4466 // 4351 4467 // This FSM handles requests from both the DCACHE FSM & the ICACHE FSM. 4352 // There is 6request types, with the following priorities :4468 // There are 8 request types, with the following priorities : 4353 4469 // 1 - Data Read Miss : r_dcache_vci_miss_req and miss in the write buffer 4354 4470 // 2 - Data Read Uncachable : r_dcache_vci_unc_req … … 4356 4472 // 4 - Instruction Uncachable : r_icache_unc_req 4357 4473 // 5 - Data Write : r_wbuf.rok() 4358 // 6 - Data Store Conditionnal: r_dcache_vci_sc_req 4474 // 6 - Data Linked Load : r_dcache_vci_ll_req 4475 // 7 - Data Store Conditionnal: r_dcache_vci_sc_req 4476 // 8 - Compare And Swap : r_dcache_vci_cas_req 4359 4477 // 4360 4478 // As we want to support several simultaneous VCI transactions, the VCI_CMD_FSM … … 4430 4548 // m_length_write_transaction += (wbuf_max-wbuf_min+1); 4431 4549 } 4432 // 6 - Data Store Conditionnal 4550 // 6 - Data Linked Load 4551 // must check that all write transaction are completed 4552 else if ( r_dcache_vci_ll_req.read() && r_wbuf.miss(r_dcache_vci_paddr.read())) 4553 { 4554 r_dcache_vci_ll_req = false; 4555 r_vci_cmd_fsm = CMD_DATA_LL; 4556 // r_vci_cmd_cpt = 0; 4557 // m_cpt_sc_transaction++; 4558 } 4559 // 7 - Data Store Conditionnal 4560 // should check that all write transaction are completed ? 4433 4561 else if ( r_dcache_vci_sc_req.read() ) 4434 4562 { 4435 r_vci_cmd_fsm = CMD_DATA_CAS;4436 4563 r_dcache_vci_sc_req = false; 4437 r_vci_cmd_cpt = 0; 4438 // m_cpt_sc_transaction++; 4564 r_vci_cmd_cpt = 0; 4565 r_vci_cmd_fsm = CMD_DATA_SC; 4566 // m_cpt_sc_transaction++; 4567 } 4568 // 8 - Compare And Swap 4569 // should check that all write transaction are completed ? 4570 else if ( r_dcache_vci_cas_req.read() ) 4571 { 4572 r_vci_cmd_fsm = CMD_DATA_CAS; 4573 r_dcache_vci_cas_req = false; 4574 r_vci_cmd_cpt = 0; 4575 // m_cpt_sc_transaction++; 4439 4576 } 4440 4577 break; … … 4456 4593 } 4457 4594 ///////////////// 4595 case CMD_DATA_SC: 4458 4596 case CMD_DATA_CAS: 4459 4597 { 4460 // The SC VCI command containstwo flits4598 // The CAS and SC VCI commands contain two flits 4461 4599 if ( p_vci_ini_d.cmdack.read() ) 4462 4600 { … … 4471 4609 case CMD_DATA_MISS: 4472 4610 case CMD_DATA_UNC: 4611 case CMD_DATA_LL: 4473 4612 { 4474 4613 // all read VCI commands contain one single flit … … 4487 4626 // - r_vci_rsp_ins_error (set) 4488 4627 // - r_vci_rsp_cpt 4628 // - r_dcache_vci_sc_req (reset when SC response recieved) 4489 4629 // 4490 4630 // As the VCI_RSP and VCI_CMD are fully desynchronized to support several … … 4540 4680 else if ( (p_vci_ini_d.rpktid.read() & 0x7) == TYPE_LL ) 4541 4681 { 4542 assert(false and "TODO ! LL NOT IMPLEMENTED YET"); //TODO 4543 //r_vci_rsp_fsm = RSP_DATA_UNC; 4682 r_vci_rsp_fsm = RSP_DATA_LL; 4544 4683 } 4545 4684 else if ( (p_vci_ini_d.rpktid.read() & 0x7) == TYPE_SC ) 4546 4685 { 4547 assert(false and "TODO ! SC NOT IMPLEMENTED YET"); //TODO 4548 //r_vci_rsp_fsm = RSP_DATA_UNC; 4686 r_vci_rsp_fsm = RSP_DATA_UNC; 4549 4687 } 4550 4688 else … … 4670 4808 } 4671 4809 //////////////////// 4810 case RSP_DATA_LL: 4811 { 4812 if ( p_vci_ini_d.rspval.read() ) 4813 { 4814 if ( (p_vci_ini_d.rerror.read()&0x1) != 0 ) // error reported 4815 { 4816 r_vci_rsp_data_error = true; 4817 r_vci_rsp_fsm = RSP_IDLE; 4818 } 4819 if (r_vci_rsp_cpt.read() == 0) //first flit 4820 { 4821 if(r_vci_rsp_fifo_dcache.wok()) 4822 { 4823 assert(!p_vci_ini_d.reop.read() && 4824 "illegal VCI response packet for LL"); 4825 vci_rsp_fifo_dcache_put = true; 4826 vci_rsp_fifo_dcache_data = p_vci_ini_d.rdata.read(); 4827 r_vci_rsp_cpt = r_vci_rsp_cpt.read() + 1; 4828 } 4829 break; 4830 } 4831 else // last flit 4832 { 4833 if(r_vci_rsp_fifo_dcache.wok()) 4834 { 4835 assert(p_vci_ini_d.reop.read() && 4836 "illegal VCI response packet for LL"); 4837 vci_rsp_fifo_dcache_put = true; 4838 vci_rsp_fifo_dcache_data = p_vci_ini_d.rdata.read(); 4839 r_vci_rsp_fsm = RSP_IDLE; 4840 } 4841 break; 4842 } 4843 } 4844 break; 4845 } 4846 //////////////////// 4672 4847 case RSP_DATA_WRITE: 4673 4848 { … … 4678 4853 4679 4854 r_vci_rsp_fsm = RSP_IDLE; 4680 uint32_t wbuf_index = p_vci_ini_d.rtrdid.read() - (1<<(vci_param::T-1));4855 uint32_t wbuf_index = p_vci_ini_d.rtrdid.read(); 4681 4856 bool cacheable = r_wbuf.completed(wbuf_index); 4682 4857 if ( not cacheable ) r_dcache_pending_unc_write = false; … … 4814 4989 vci_rsp_fifo_dcache_put, 4815 4990 vci_rsp_fifo_dcache_data); 4991 4992 #undef LLSCLocalTable 4816 4993 } // end transition() 4817 4994 … … 4951 5128 p_vci_ini_d.wdata = r_wbuf.getData(r_vci_cmd_cpt.read()); 4952 5129 p_vci_ini_d.be = r_wbuf.getBe(r_vci_cmd_cpt.read()); 4953 p_vci_ini_d.trdid = r_wbuf.getIndex() + (1<<(vci_param::T-1));5130 p_vci_ini_d.trdid = r_wbuf.getIndex(); 4954 5131 p_vci_ini_d.pktid = TYPE_WRITE; 4955 5132 p_vci_ini_d.plen = (r_vci_cmd_max.read() - r_vci_cmd_min.read() + 1) << 2; … … 4958 5135 break; 4959 5136 5137 case CMD_DATA_LL: 5138 p_vci_ini_d.cmdval = true; 5139 p_vci_ini_d.address = r_dcache_vci_paddr.read() & ~0x3; 5140 p_vci_ini_d.wdata = 0; 5141 p_vci_ini_d.be = 0xF; 5142 p_vci_ini_d.trdid = 0; //TODO local table index 5143 p_vci_ini_d.pktid = TYPE_LL; 5144 p_vci_ini_d.plen = 8; 5145 p_vci_ini_d.cmd = vci_param::CMD_LOCKED_READ; 5146 p_vci_ini_d.eop = true; 5147 break; 5148 5149 case CMD_DATA_SC: 5150 p_vci_ini_d.cmdval = true; 5151 p_vci_ini_d.address = r_dcache_vci_paddr.read() & ~0x3; 5152 if ( r_vci_cmd_cpt.read() == 0 ) p_vci_ini_d.wdata = r_sc_key.read(); 5153 else p_vci_ini_d.wdata = r_dcache_vci_sc_data.read(); 5154 p_vci_ini_d.be = 0xF; 5155 p_vci_ini_d.trdid = 0; 5156 p_vci_ini_d.pktid = TYPE_SC; 5157 p_vci_ini_d.plen = 8; 5158 p_vci_ini_d.cmd = vci_param::CMD_NOP; 5159 p_vci_ini_d.eop = (r_vci_cmd_cpt.read() == 1); 5160 break; 5161 4960 5162 case CMD_DATA_CAS: 4961 5163 p_vci_ini_d.cmdval = true; 4962 5164 p_vci_ini_d.address = r_dcache_vci_paddr.read() & ~0x3; 4963 if ( r_vci_cmd_cpt.read() == 0 ) p_vci_ini_d.wdata = r_dcache_vci_ sc_old.read();4964 else p_vci_ini_d.wdata = r_dcache_vci_ sc_new.read();5165 if ( r_vci_cmd_cpt.read() == 0 ) p_vci_ini_d.wdata = r_dcache_vci_cas_old.read(); 5166 else p_vci_ini_d.wdata = r_dcache_vci_cas_new.read(); 4965 5167 p_vci_ini_d.be = 0xF; 4966 5168 p_vci_ini_d.trdid = 0; … … 4983 5185 case RSP_DATA_MISS : p_vci_ini_d.rspack = r_vci_rsp_fifo_dcache.wok(); break; 4984 5186 case RSP_DATA_UNC : p_vci_ini_d.rspack = r_vci_rsp_fifo_dcache.wok(); break; 5187 case RSP_DATA_LL : p_vci_ini_d.rspack = r_vci_rsp_fifo_dcache.wok(); break; 4985 5188 case RSP_IDLE : p_vci_ini_d.rspack = false; break; 4986 5189 } // end switch r_vci_rsp_fsm … … 5051 5254 5052 5255 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062
Note: See TracChangeset
for help on using the changeset viewer.