Changeset 291
- Timestamp:
- Jan 28, 2013, 1:59:32 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 10 added
- 7 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 -
trunk/modules/vci_mem_cache_v4/caba/metadata/vci_mem_cache_v4.sd
r273 r291 24 24 Uses('common:mapping_table'), 25 25 Uses('caba:generic_fifo'), 26 Uses('caba:generic_llsc_global_table'), 26 27 ], 27 28 -
trunk/modules/vci_mem_cache_v4/caba/source/include/vci_mem_cache_v4.h
r289 r291 54 54 #include "mapping_table.h" 55 55 #include "int_tab.h" 56 #include "generic_llsc_global_table.h" 56 57 #include "mem_cache_directory_v4.h" 57 58 #include "xram_transaction_v4.h" … … 422 423 CacheData m_cache_data; // data array[set][way][word] 423 424 HeapDirectory m_heap; // heap for copies 425 GenericLLSCGlobalTable 426 < 427 32 , // desired number of slots 428 4096, // number of processors in the system 429 8000, // registratioçn life span (in # of LL operations) 430 typename vci_param::fast_addr_t // address type 431 > 432 m_llsc_table; // ll/sc global registration table 424 433 425 434 // adress masks … … 491 500 sc_signal<size_t> r_read_next_ptr; // Next entry to point to 492 501 sc_signal<bool> r_read_last_free; // Last free entry 502 sc_signal<typename vci_param::fast_addr_t> 503 r_read_ll_key; // LL key returned by the llsc_global_table 493 504 494 505 // Buffer between READ fsm and IXR_CMD fsm (ask a missing cache line to XRAM) … … 505 516 sc_signal<size_t> r_read_to_tgt_rsp_word; // first word of the response 506 517 sc_signal<size_t> r_read_to_tgt_rsp_length; // length of the response 518 sc_signal<typename vci_param::fast_addr_t> 519 r_read_to_tgt_rsp_ll_key; // LL key returned by the llsc_global_table 507 520 508 521 /////////////////////////////////////////////////////////////// … … 533 546 sc_signal<size_t> r_write_trt_index; // index in Transaction Table 534 547 sc_signal<size_t> r_write_upt_index; // index in Update Table 548 sc_signal<bool> r_write_sc_fail; // sc command failed 549 sc_signal<bool> r_write_pending_sc; // sc command pending in WRITE fsm 535 550 536 551 // Buffer between WRITE fsm and TGT_RSP fsm (acknowledge a write command from L1) 537 sc_signal<bool> r_write_to_tgt_rsp_req; // valid request 538 sc_signal<size_t> r_write_to_tgt_rsp_srcid; // transaction srcid 539 sc_signal<size_t> r_write_to_tgt_rsp_trdid; // transaction trdid 540 sc_signal<size_t> r_write_to_tgt_rsp_pktid; // transaction pktid 552 sc_signal<bool> r_write_to_tgt_rsp_req; // valid request 553 sc_signal<size_t> r_write_to_tgt_rsp_srcid; // transaction srcid 554 sc_signal<size_t> r_write_to_tgt_rsp_trdid; // transaction trdid 555 sc_signal<size_t> r_write_to_tgt_rsp_pktid; // transaction pktid 556 sc_signal<bool> r_write_to_tgt_rsp_sc_fail; // sc command failed 541 557 542 558 // Buffer between WRITE fsm and IXR_CMD fsm (ask a missing cache line to XRAM) … … 721 737 sc_signal<size_t> r_xram_rsp_to_tgt_rsp_length; // length of the response 722 738 sc_signal<bool> r_xram_rsp_to_tgt_rsp_rerror; // send error to requester 739 sc_signal<typename vci_param::fast_addr_t> 740 r_xram_rsp_to_tgt_rsp_ll_key; // LL key returned by the llsc_global_table 723 741 724 742 // Buffer between XRAM_RSP fsm and INIT_CMD fsm (Inval L1 Caches) -
trunk/modules/vci_mem_cache_v4/caba/source/include/xram_transaction_v4.h
r253 r291 32 32 std::vector<be_t> wdata_be; // be for each data in the write buffer 33 33 bool rerror; // error returned by xram 34 data_t ll_key; // LL key returned by the llsc_global_table 34 35 35 36 ///////////////////////////////////////////////////////////////////// … … 127 128 wdata.assign(source.wdata.begin(),source.wdata.end()); 128 129 rerror = source.rerror; 130 ll_key = source.ll_key; 129 131 } 130 132 … … 325 327 // - data : the data to write (in case of write) 326 328 // - data_be : the mask of the data to write (in case of write) 329 // - ll_key : the ll key (if any) returned by the llsc_global_table 327 330 ///////////////////////////////////////////////////////////////////// 328 331 void set(const size_t index, … … 336 339 const size_t word_index, 337 340 const std::vector<be_t> &data_be, 338 const std::vector<data_t> &data) 341 const std::vector<data_t> &data, 342 const data_t ll_key = 0) 339 343 { 340 344 assert( (index < size_tab) … … 354 358 tab[index].read_length = read_length; 355 359 tab[index].word_index = word_index; 360 tab[index].ll_key = ll_key; 356 361 for(size_t i=0; i<tab[index].wdata.size(); i++) 357 362 { -
trunk/modules/vci_mem_cache_v4/caba/source/src/vci_mem_cache_v4.cpp
r290 r291 293 293 m_cache_data( nways, nsets, nwords ), 294 294 m_heap( m_heap_size ), 295 m_llsc_table(), 295 296 296 297 #define L2 soclib::common::uint32_log2 … … 511 512 << " | " << ixr_rsp_fsm_str[r_ixr_rsp_fsm] 512 513 << " | " << xram_rsp_fsm_str[r_xram_rsp_fsm] << std::endl; 514 515 //m_llsc_table.print_trace(); 516 513 517 } 514 518 … … 860 864 assert(((p_vci_tgt.pktid.read() & 0x7) == 0x6) && 861 865 "The type specified in the pktid field is incompatible with the LL CMD"); 862 assert(false && "TODO : LL not implemented"); //TODO 863 //r_tgt_cmd_fsm = TGT_CMD_READ; 866 r_tgt_cmd_fsm = TGT_CMD_READ; 864 867 } 865 868 else if ( p_vci_tgt.cmd.read() == vci_param::CMD_NOP ) … … 874 877 "The type specified in the pktid field is incompatible with the NOP CMD"); 875 878 876 if( p_vci_tgt.pktid.read() == TYPE_CAS)879 if((p_vci_tgt.pktid.read() & 0x7) == TYPE_CAS) 877 880 r_tgt_cmd_fsm = TGT_CMD_CAS; 878 881 else // TYPE_SC 879 assert(false && "TODO : SC not implemented"); //TODO 880 //r_tgt_cmd_fsm = TGT_CMD_WRITE; 882 r_tgt_cmd_fsm = TGT_CMD_WRITE; 881 883 } 882 884 else … … 892 894 ////////////////// 893 895 case TGT_CMD_READ: 894 if ((m_x[(vci_addr_t)p_vci_tgt.address.read()]+(p_vci_tgt.plen.read()>>2)) > 16) 896 // This test checks that the read does not cross a cache line limit. 897 // It must not be taken into account when dealing with an LL CMD. 898 if (((m_x[(vci_addr_t)p_vci_tgt.address.read()]+(p_vci_tgt.plen.read()>>2)) > 16) && ( p_vci_tgt.cmd.read() != vci_param::CMD_LOCKED_READ )) 895 899 { 896 900 std::cout … … 907 911 << std::endl; 908 912 std::cout 909 << " read command packets must contain one single flit"913 << " read or ll command packets must contain one single flit" 910 914 << std::endl; 911 915 exit(0); … … 927 931 #endif 928 932 cmd_read_fifo_put = true; 929 m_cpt_read++; 933 if ( p_vci_tgt.cmd.read() == vci_param::CMD_LOCKED_READ ) 934 m_cpt_ll++; 935 else 936 m_cpt_read++; 930 937 r_tgt_cmd_fsm = TGT_CMD_IDLE; 931 938 } … … 1139 1146 // READ FSM 1140 1147 //////////////////////////////////////////////////////////////////////////////////// 1141 // The READ FSM controls the VCI read requests.1148 // The READ FSM controls the VCI read and ll requests. 1142 1149 // It takes the lock protecting the cache directory to check the cache line status: 1143 1150 // - In case of HIT … … 1174 1181 << " srcid = " << std::dec << m_cmd_read_srcid_fifo.read() 1175 1182 << " / address = " << std::hex << m_cmd_read_addr_fifo.read() 1183 << " / pktid = " << std::hex << m_cmd_read_pktid_fifo.read() 1176 1184 << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl; 1177 1185 } … … 1211 1219 DirectoryEntry entry = 1212 1220 m_cache_directory.read(m_cmd_read_addr_fifo.read(), way); 1213 1221 if((m_cmd_read_pktid_fifo.read() & 0x7) == TYPE_LL) // access the global table ONLY when we have an LL cmd 1222 { 1223 r_read_ll_key = m_llsc_table.ll(m_cmd_read_addr_fifo.read()); 1224 } 1214 1225 r_read_is_cnt = entry.is_cnt; 1215 1226 r_read_dirty = entry.dirty; … … 1256 1267 << " / count = " <<std::dec << entry.count 1257 1268 << " / is_cnt = " << entry.is_cnt << std::endl; 1269 if((m_cmd_read_pktid_fifo.read() & 0x7) == TYPE_LL) 1270 { 1271 std::cout 1272 << " <MEMC " << name() << ".READ_DIR_LOCK> global_llsc_table LL access" << std::endl; 1273 } 1258 1274 } 1259 1275 #endif … … 1604 1620 r_read_to_tgt_rsp_trdid = m_cmd_read_trdid_fifo.read(); 1605 1621 r_read_to_tgt_rsp_pktid = m_cmd_read_pktid_fifo.read(); 1606 cmd_read_fifo_get = true; 1607 r_read_to_tgt_rsp_req = true; 1608 r_read_fsm = READ_IDLE; 1622 r_read_to_tgt_rsp_ll_key = r_read_ll_key.read(); 1623 cmd_read_fifo_get = true; 1624 r_read_to_tgt_rsp_req = true; 1625 r_read_fsm = READ_IDLE; 1609 1626 1610 1627 #if DEBUG_MEMC_READ … … 1673 1690 m_x[(vci_addr_t)(m_cmd_read_addr_fifo.read())], 1674 1691 std::vector<be_t>(m_words,0), 1675 std::vector<data_t>(m_words,0)); 1692 std::vector<data_t>(m_words,0), 1693 r_read_ll_key.read()); 1676 1694 #if DEBUG_MEMC_READ 1677 1695 if( m_debug_read_fsm ) … … 1718 1736 // WRITE FSM 1719 1737 /////////////////////////////////////////////////////////////////////////////////// 1720 // The WRITE FSM handles the write bursts sent by the processors.1738 // The WRITE FSM handles the write bursts and sc requests sent by the processors. 1721 1739 // All addresses in a burst must be in the same cache line. 1722 1740 // A complete write burst is consumed in the FIFO & copied to a local buffer. … … 1728 1746 // returned to the writing processor. 1729 1747 // If the data is cached by other processors, a coherence transaction must 1730 // be launched :1748 // be launched (sc requests always require a coherence transaction): 1731 1749 // It is a multicast update if the line is not in counter mode, and the processor 1732 1750 // takes the lock protecting the Update Table (UPT) to register this transaction. … … 1753 1771 if ( m_cmd_write_addr_fifo.rok() ) 1754 1772 { 1755 m_cpt_write++; 1756 m_cpt_write_cells++; 1773 if((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC) 1774 m_cpt_sc++; 1775 else 1776 { 1777 m_cpt_write++; 1778 m_cpt_write_cells++; 1779 } 1757 1780 1758 1781 // consume a word in the FIFO & write it in the local buffer 1759 1782 cmd_write_fifo_get = true; 1783 r_write_pending_sc = false; 1760 1784 size_t index = m_x[(vci_addr_t)(m_cmd_write_addr_fifo.read())]; 1761 1785 … … 1775 1799 } 1776 1800 1777 if( m_cmd_write_eop_fifo.read() )1801 if( m_cmd_write_eop_fifo.read() || ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC) ) 1778 1802 { 1779 1803 r_write_fsm = WRITE_DIR_REQ; … … 1824 1848 // consume a word in the FIFO & write it in the local buffer 1825 1849 cmd_write_fifo_get = true; 1850 r_write_pending_sc = false; 1826 1851 size_t index = r_write_word_index.read() + r_write_word_count.read(); 1827 1852 … … 1844 1869 if ( r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE ) 1845 1870 { 1871 if(((r_write_pktid.read() & 0x7) == TYPE_SC) && not r_write_pending_sc.read()) // check for an SC command (and check that its second flit is not already consumed) 1872 { 1873 if ( m_cmd_write_addr_fifo.rok() ) 1874 { 1875 size_t index = m_x[(vci_addr_t)(r_write_address.read())]; 1876 bool sc_success = m_llsc_table.sc(r_write_address.read(),r_write_data[index].read()); 1877 r_write_sc_fail = !sc_success; 1878 1879 assert(m_cmd_write_eop_fifo.read() && "Error in VCI_MEM_CACHE : invalid packet format for SC command"); 1880 // consume a word in the FIFO & write it in the local buffer 1881 cmd_write_fifo_get = true; 1882 r_write_pending_sc = true; 1883 index = m_x[(vci_addr_t)(m_cmd_write_addr_fifo.read())]; 1884 1885 r_write_address = (addr_t)(m_cmd_write_addr_fifo.read()); 1886 r_write_word_index = index; 1887 r_write_word_count = 1; 1888 r_write_data[index] = m_cmd_write_data_fifo.read(); 1889 if (!sc_success) 1890 { 1891 r_write_fsm = WRITE_RSP; 1892 break; 1893 } 1894 } 1895 else break; 1896 } 1897 //else it is a TYPE_WRITE, need a simple sw access to the 1898 // llsc_global_table 1899 else 1900 { 1901 m_llsc_table.sw(r_write_address.read()); 1902 } 1846 1903 r_write_fsm = WRITE_DIR_LOCK; 1847 1904 } … … 1905 1962 << " count = " << entry.count 1906 1963 << " is_cnt = " << entry.is_cnt << std::endl; 1964 if((r_write_pktid.read() & 0x7) == TYPE_SC) 1965 std::cout << " <MEMC " << name() << ".WRITE_DIR_LOCK> global_llsc_table SC access" << std::endl; 1966 else 1967 std::cout << " <MEMC " << name() << ".WRITE_DIR_LOCK> global_llsc_table SW access" << std::endl; 1907 1968 } 1908 1969 #endif … … 1985 2046 1986 2047 // no_update is true when there is no need for coherence transaction 1987 bool no_update = (r_write_count.read()==0) || ( owner && (r_write_count.read()==1)); 2048 // (tests for sc requests) 2049 bool no_update = ((r_write_count.read()==0) || ( owner && (r_write_count.read()==1) && (r_write_pktid.read() != TYPE_SC))); 1988 2050 1989 2051 // write data in the cache if no coherence transaction … … 2004 2066 } 2005 2067 2006 if ( owner and not no_update )2068 if ( owner and not no_update and (r_write_pktid.read() != TYPE_SC)) 2007 2069 { 2008 2070 r_write_count = r_write_count.read() - 1; … … 2127 2189 case WRITE_UPT_REQ: 2128 2190 { 2129 // prepare the coherence ransaction for the INIT_CMD FSM2191 // prepare the coherence transaction for the INIT_CMD FSM 2130 2192 // and write the first copy in the FIFO 2131 2193 // send the request if only one copy … … 2146 2208 for (size_t i=min ; i<max ; i++) r_write_to_init_cmd_data[i] = r_write_data[i]; 2147 2209 2148 if( (r_write_copy.read() != r_write_srcid.read()) or 2210 if( (r_write_copy.read() != r_write_srcid.read()) or (r_write_pktid.read() == TYPE_SC) or 2149 2211 #if L1_MULTI_CACHE 2150 2212 (r_write_copy_cache.read() != r_write_pktid.read()) or … … 2159 2221 write_to_init_cmd_fifo_cache_id= r_write_copy_cache.read(); 2160 2222 #endif 2161 if(r_write_count.read() == 1 )2223 if(r_write_count.read() == 1 || ((r_write_count.read() == 0) && (r_write_pktid.read() == TYPE_SC)) ) 2162 2224 { 2163 2225 r_write_fsm = WRITE_IDLE; … … 2207 2269 bool dec_upt_counter; 2208 2270 2209 if( (entry.owner.srcid != r_write_srcid.read()) or2271 if(((entry.owner.srcid != r_write_srcid.read()) || (r_write_pktid.read() == TYPE_SC)) or 2210 2272 #if L1_MULTI_CACHE 2211 2273 (entry.owner.cache_id != r_write_pktid.read()) or 2212 2274 #endif 2213 entry.owner.inst) // put te next srcid in the fifo2275 entry.owner.inst) // put the next srcid in the fifo 2214 2276 { 2215 2277 dec_upt_counter = false; … … 2299 2361 { 2300 2362 // post the request to TGT_RSP_FSM 2301 r_write_to_tgt_rsp_req = true; 2302 r_write_to_tgt_rsp_srcid = r_write_srcid.read(); 2303 r_write_to_tgt_rsp_trdid = r_write_trdid.read(); 2304 r_write_to_tgt_rsp_pktid = r_write_pktid.read(); 2363 r_write_to_tgt_rsp_req = true; 2364 r_write_to_tgt_rsp_srcid = r_write_srcid.read(); 2365 r_write_to_tgt_rsp_trdid = r_write_trdid.read(); 2366 r_write_to_tgt_rsp_pktid = r_write_pktid.read(); 2367 r_write_to_tgt_rsp_sc_fail = r_write_sc_fail.read(); 2305 2368 2306 2369 // try to get a new write request from the FIFO 2307 2370 if ( m_cmd_write_addr_fifo.rok() ) 2308 2371 { 2309 m_cpt_write++; 2310 m_cpt_write_cells++; 2372 if((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC) 2373 m_cpt_sc++; 2374 else 2375 { 2376 m_cpt_write++; 2377 m_cpt_write_cells++; 2378 } 2311 2379 2312 2380 // consume a word in the FIFO & write it in the local buffer 2313 2381 cmd_write_fifo_get = true; 2382 r_write_pending_sc = false; 2314 2383 size_t index = m_x[(vci_addr_t)(m_cmd_write_addr_fifo.read())]; 2315 2384 … … 2329 2398 } 2330 2399 2331 if( m_cmd_write_eop_fifo.read() )2400 if( m_cmd_write_eop_fifo.read() || ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC) ) 2332 2401 { 2333 2402 r_write_fsm = WRITE_DIR_REQ; … … 3191 3260 entry.lock = false; 3192 3261 entry.dirty = dirty; 3193 entry.tag = r_xram_rsp_trt_buf.nline / m_sets;3262 entry.tag = r_xram_rsp_trt_buf.nline / m_sets; 3194 3263 entry.ptr = 0; 3195 3264 if(cached_read) … … 3305 3374 r_xram_rsp_to_tgt_rsp_word = r_xram_rsp_trt_buf.word_index; 3306 3375 r_xram_rsp_to_tgt_rsp_length = r_xram_rsp_trt_buf.read_length; 3376 r_xram_rsp_to_tgt_rsp_ll_key = r_xram_rsp_trt_buf.ll_key; 3307 3377 r_xram_rsp_to_tgt_rsp_rerror = false; 3308 3378 r_xram_rsp_to_tgt_rsp_req = true; … … 4371 4441 ////////////////////// 4372 4442 case CAS_DIR_HIT_WRITE: // test if a CC transaction is required 4373 // write data in cache if no CC request 4374 { 4443 // write data in cache if no CC request 4444 { 4445 // The CAS is a success => sw access to the llsc_global_table 4446 m_llsc_table.sw(m_cmd_cas_addr_fifo.read()); 4447 4375 4448 // test coherence request 4376 4449 if(r_cas_count.read()) // replicated line … … 4422 4495 << " / value = " << r_cas_wdata.read() 4423 4496 << " / count = " << r_cas_count.read() << std::endl; 4497 std::cout << " <MEMC " << name() << ".CAS_DIR_HIT_WRITE> global_llsc_table SW access" << std::endl; 4424 4498 } 4425 4499 #endif … … 6383 6457 case TGT_RSP_READ: 6384 6458 p_vci_tgt.rspval = true; 6385 p_vci_tgt.rdata = r_read_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read(); 6459 if( ((r_read_to_tgt_rsp_pktid.read() & 0x7) == TYPE_LL) 6460 && (r_tgt_rsp_cpt.read() == (r_read_to_tgt_rsp_word.read()+r_read_to_tgt_rsp_length-1)) ) 6461 p_vci_tgt.rdata = r_read_to_tgt_rsp_data[r_tgt_rsp_cpt.read()-1].read(); 6462 else if ((r_read_to_tgt_rsp_pktid.read() & 0x7) == TYPE_LL) 6463 p_vci_tgt.rdata = r_read_to_tgt_rsp_ll_key.read(); 6464 else 6465 p_vci_tgt.rdata = r_read_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read(); 6386 6466 p_vci_tgt.rsrcid = r_read_to_tgt_rsp_srcid.read(); 6387 6467 p_vci_tgt.rtrdid = r_read_to_tgt_rsp_trdid.read(); … … 6391 6471 break; 6392 6472 case TGT_RSP_WRITE: 6473 /*if( ((r_write_to_tgt_rsp_pktid.read() & 0x7) == TYPE_SC) ) 6474 { 6475 std::cout << "SC RSP / rsrcid = " << r_write_to_tgt_rsp_srcid.read() << " / rdata = " << r_write_to_tgt_rsp_sc_fail.read() << std::endl; 6476 }*/ 6393 6477 p_vci_tgt.rspval = true; 6394 p_vci_tgt.rdata = 0; 6478 if( ((r_write_to_tgt_rsp_pktid.read() & 0x7) == TYPE_SC) && r_write_to_tgt_rsp_sc_fail.read() ) 6479 p_vci_tgt.rdata = 1; 6480 else 6481 p_vci_tgt.rdata = 0; 6395 6482 p_vci_tgt.rsrcid = r_write_to_tgt_rsp_srcid.read(); 6396 6483 p_vci_tgt.rtrdid = r_write_to_tgt_rsp_trdid.read(); 6397 6484 p_vci_tgt.rpktid = r_write_to_tgt_rsp_pktid.read(); 6398 p_vci_tgt.rerror = 0x2 & ( (1 << vci_param::E) - 1); 6485 //p_vci_tgt.rerror = 0x2 & ( (1 << vci_param::E) - 1); 6486 p_vci_tgt.rerror = 0; 6399 6487 p_vci_tgt.reop = true; 6400 6488 break; … … 6419 6507 case TGT_RSP_XRAM: 6420 6508 p_vci_tgt.rspval = true; 6421 p_vci_tgt.rdata = r_xram_rsp_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read(); 6509 if( ((r_xram_rsp_to_tgt_rsp_pktid.read() & 0x7) == TYPE_LL) 6510 && (r_tgt_rsp_cpt.read() == (r_xram_rsp_to_tgt_rsp_word.read()+r_xram_rsp_to_tgt_rsp_length-1)) ) 6511 p_vci_tgt.rdata = r_xram_rsp_to_tgt_rsp_ll_key.read(); 6512 else 6513 p_vci_tgt.rdata = r_xram_rsp_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read(); 6422 6514 p_vci_tgt.rsrcid = r_xram_rsp_to_tgt_rsp_srcid.read(); 6423 6515 p_vci_tgt.rtrdid = r_xram_rsp_to_tgt_rsp_trdid.read(); … … 6430 6522 case TGT_RSP_INIT: 6431 6523 p_vci_tgt.rspval = true; 6432 p_vci_tgt.rdata = 0; 6524 p_vci_tgt.rdata = 0; // Can be a CAS or SC rsp 6433 6525 p_vci_tgt.rsrcid = r_init_rsp_to_tgt_rsp_srcid.read(); 6434 6526 p_vci_tgt.rtrdid = r_init_rsp_to_tgt_rsp_trdid.read(); 6435 6527 p_vci_tgt.rpktid = r_init_rsp_to_tgt_rsp_pktid.read(); 6436 p_vci_tgt.rerror = 0; // Can be a CAS rsp6528 p_vci_tgt.rerror = 0; 6437 6529 p_vci_tgt.reop = true; 6438 6530 break;
Note: See TracChangeset
for help on using the changeset viewer.