- Timestamp:
- Sep 18, 2013, 1:44:37 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp
r524 r527 2654 2654 case WRITE_IDLE: // copy first word of a write burst in local buffer 2655 2655 { 2656 if (m_cmd_write_addr_fifo.rok()) 2657 { 2658 // consume a word in the FIFO & write it in the local buffer 2659 cmd_write_fifo_get = true; 2660 size_t index = m_x[(addr_t)(m_cmd_write_addr_fifo.read())]; 2661 2662 r_write_address = (addr_t)(m_cmd_write_addr_fifo.read()); 2663 r_write_word_index = index; 2664 r_write_word_count = 1; 2665 r_write_data[index] = m_cmd_write_data_fifo.read(); 2666 r_write_srcid = m_cmd_write_srcid_fifo.read(); 2667 r_write_trdid = m_cmd_write_trdid_fifo.read(); 2668 r_write_pktid = m_cmd_write_pktid_fifo.read(); 2669 r_write_pending_sc = false; 2670 2671 // initialize the be field for all words 2672 for(size_t word=0 ; word<m_words ; word++) 2673 { 2674 if (word == index) r_write_be[word] = m_cmd_write_be_fifo.read(); 2675 else r_write_be[word] = 0x0; 2676 } 2677 2678 if (m_cmd_write_eop_fifo.read() or ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC)) 2679 { 2680 r_write_fsm = WRITE_DIR_REQ; 2681 } 2682 else 2683 { 2684 r_write_fsm = WRITE_NEXT; 2685 } 2656 if (not m_cmd_write_addr_fifo.rok()) break; 2657 2658 // consume a word in the FIFO & write it in the local buffer 2659 cmd_write_fifo_get = true; 2660 size_t index = m_x[(addr_t)(m_cmd_write_addr_fifo.read())]; 2661 2662 r_write_address = (addr_t)(m_cmd_write_addr_fifo.read()); 2663 r_write_word_index = index; 2664 r_write_word_count = 0; 2665 r_write_data[index] = m_cmd_write_data_fifo.read(); 2666 r_write_srcid = m_cmd_write_srcid_fifo.read(); 2667 r_write_trdid = m_cmd_write_trdid_fifo.read(); 2668 r_write_pktid = m_cmd_write_pktid_fifo.read(); 2669 2670 // if SC command, get the SC key 2671 if ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC) 2672 { 2673 assert( not m_cmd_write_eop_fifo.read() && 2674 "MEMC ERROR in WRITE_IDLE state: " 2675 "invalid packet format for SC command"); 2676 2677 r_write_sc_key = m_cmd_write_data_fifo.read(); 2678 } 2679 2680 // initialize the be field for all words 2681 for(size_t word=0 ; word<m_words ; word++) 2682 { 2683 if (word == index) r_write_be[word] = m_cmd_write_be_fifo.read(); 2684 else r_write_be[word] = 0x0; 2685 } 2686 2687 if (m_cmd_write_eop_fifo.read()) 2688 { 2689 r_write_fsm = WRITE_DIR_REQ; 2690 } 2691 else 2692 { 2693 r_write_fsm = WRITE_NEXT; 2694 } 2686 2695 2687 2696 #if DEBUG_MEMC_WRITE 2688 if (m_debug) 2689 std::cout << " <MEMC " << name() << " WRITE_IDLE> Write request " 2690 << " srcid = " << std::hex << m_cmd_write_srcid_fifo.read() 2691 << " / address = " << std::hex << m_cmd_write_addr_fifo.read() 2692 << " / data = " << m_cmd_write_data_fifo.read() << std::endl; 2693 #endif 2694 } 2697 if (m_debug) 2698 std::cout << " <MEMC " << name() << " WRITE_IDLE> Write request " 2699 << " srcid = " << std::hex << m_cmd_write_srcid_fifo.read() 2700 << " / address = " << std::hex << m_cmd_write_addr_fifo.read() 2701 << " / data = " << m_cmd_write_data_fifo.read() << std::endl; 2702 #endif 2695 2703 break; 2696 2704 } … … 2698 2706 case WRITE_NEXT: // copy next word of a write burst in local buffer 2699 2707 { 2700 if (m_cmd_write_addr_fifo.rok()) 2701 { 2708 if (not m_cmd_write_addr_fifo.rok()) break; 2709 2710 // check that the next word is in the same cache line 2711 assert((m_nline[(addr_t)(r_write_address.read())] == 2712 m_nline[(addr_t)(m_cmd_write_addr_fifo.read())]) && 2713 "MEMC ERROR in WRITE_NEXT state: Illegal write burst"); 2714 2715 size_t index = m_x[(addr_t)(m_cmd_write_addr_fifo.read())]; 2716 bool is_sc = ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC); 2717 2718 // check that SC command has constant address 2719 assert( not is_sc or (index == r_write_word_index) && 2720 "MEMC ERROR in WRITE_NEXT state: " 2721 "the address must be constant on a SC command"); 2722 2723 // check that SC command has two flits 2724 assert( not is_sc or m_cmd_write_eop_fifo.read() && 2725 "MEMC ERROR in WRITE_NEXT state: " 2726 "invalid packet format for SC command"); 2727 2728 // consume a word in the FIFO & write it in the local buffer 2729 cmd_write_fifo_get = true; 2730 2731 r_write_be[index] = m_cmd_write_be_fifo.read(); 2732 r_write_data[index] = m_cmd_write_data_fifo.read(); 2733 r_write_word_count = r_write_word_count.read() + 1; 2734 2735 if (m_cmd_write_eop_fifo.read()) r_write_fsm = WRITE_DIR_REQ; 2702 2736 2703 2737 #if DEBUG_MEMC_WRITE 2704 if (m_debug) 2705 std::cout << " <MEMC " << name() 2706 << " WRITE_NEXT> Write another word in local buffer" 2707 << std::endl; 2708 #endif 2709 2710 // check that the next word is in the same cache line 2711 assert((m_nline[(addr_t)(r_write_address.read())] == 2712 m_nline[(addr_t)(m_cmd_write_addr_fifo.read())]) and 2713 "MEMC ERROR in WRITE_NEXT state: Illegal write burst"); 2714 2715 // consume a word in the FIFO & write it in the local buffer 2716 cmd_write_fifo_get = true; 2717 size_t index = r_write_word_index.read() + r_write_word_count.read(); 2718 2719 r_write_be[index] = m_cmd_write_be_fifo.read(); 2720 r_write_data[index] = m_cmd_write_data_fifo.read(); 2721 r_write_word_count = r_write_word_count.read() + 1; 2722 2723 if (m_cmd_write_eop_fifo.read()) r_write_fsm = WRITE_DIR_REQ; 2724 } 2738 if (m_debug) 2739 std::cout << " <MEMC " << name() 2740 << " WRITE_NEXT> Write another word in local buffer" 2741 << std::endl; 2742 #endif 2725 2743 break; 2726 2744 } 2727 2745 /////////////////// 2728 case WRITE_DIR_REQ: // Get the lock to the directory 2729 // and access the llsc_global_table 2730 { 2731 if (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE ) 2732 { 2733 if (((r_write_pktid.read() & 0x7) == TYPE_SC) and not r_write_pending_sc.read()) 2734 { 2735 // We enter here if it is a new SC command 2736 // If r_write_pending_sc is set the SC is not new and has already been tested 2737 2738 if (not m_cmd_write_addr_fifo.rok()) break; 2739 2740 assert( m_cmd_write_eop_fifo.read() and 2741 "MEMC ERROR in WRITE_DIR_REQ state: invalid packet format for SC command"); 2742 2743 size_t index = r_write_word_index.read(); 2744 bool sc_success = m_llsc_table.sc(r_write_address.read(), 2745 r_write_data[index].read()); 2746 2747 // consume a word in the FIFO & write it in the local buffer 2748 cmd_write_fifo_get = true; 2749 r_write_data[index] = m_cmd_write_data_fifo.read(); 2750 r_write_sc_fail = not sc_success; 2751 r_write_pending_sc = true; 2752 2753 if (not sc_success) r_write_fsm = WRITE_RSP; 2754 else r_write_fsm = WRITE_DIR_LOCK; 2755 } 2756 else 2757 { 2758 // We enter here if it is a SW command or an already tested SC command 2746 case WRITE_DIR_REQ: // Get the lock to the directory 2747 // and access the llsc_global_table 2748 { 2749 if (r_alloc_dir_fsm.read() != ALLOC_DIR_WRITE ) break; 2750 2751 if ((r_write_pktid.read() & 0x7) == TYPE_SC) 2752 { 2753 // test address and key match of the SC command on the 2754 // LL/SC table without removing reservation. The reservation 2755 // will be erased after in this FSM. 2756 bool sc_success = m_llsc_table.check(r_write_address.read(), 2757 r_write_sc_key.read()); 2758 2759 r_write_sc_fail = not sc_success; 2760 2761 if (not sc_success) r_write_fsm = WRITE_RSP; 2762 else r_write_fsm = WRITE_DIR_LOCK; 2763 } 2764 else 2765 { 2766 // write burst 2759 2767 #define L2 soclib::common::uint32_log2 2760 2761 2762 ((r_write_word_count.read()-1) << L2(vci_param_int::B));2768 addr_t min = r_write_address.read(); 2769 addr_t max = r_write_address.read() + 2770 (r_write_word_count.read() << L2(vci_param_int::B)); 2763 2771 #undef L2 2764 2772 2765 2766 2767 2768 2773 m_llsc_table.sw(min, max); 2774 2775 r_write_fsm = WRITE_DIR_LOCK; 2776 } 2769 2777 2770 2778 #if DEBUG_MEMC_WRITE 2771 if (m_debug) 2772 std::cout << " <MEMC " << name() << " WRITE_DIR_REQ> Requesting DIR lock " 2773 << std::endl; 2774 #endif 2775 } 2779 if (m_debug) 2780 std::cout << " <MEMC " << name() << " WRITE_DIR_REQ> Requesting DIR lock " 2781 << std::endl; 2782 #endif 2776 2783 break; 2777 2784 } … … 2798 2805 2799 2806 if (entry.is_cnt and entry.count) r_write_fsm = WRITE_BC_DIR_READ; 2800 else r_write_fsm = WRITE_DIR_HIT;2807 else r_write_fsm = WRITE_DIR_HIT; 2801 2808 } 2802 2809 else // miss … … 2851 2858 // no_update is true when there is no need for coherence transaction 2852 2859 bool no_update = ( (r_write_count.read() == 0) or 2853 (owner and (r_write_count.read() == 1) and2854 ( r_write_pktid.read() != TYPE_SC)));2860 (owner and (r_write_count.read() == 1) and 2861 ((r_write_pktid.read() & 0x7) != TYPE_SC))); 2855 2862 2856 2863 // write data in the cache if no coherence transaction 2857 2864 if (no_update) 2858 2865 { 2866 // SC command but zero copies 2867 if ((r_write_pktid.read() & 0x7) == TYPE_SC) 2868 { 2869 m_llsc_table.sc(r_write_address.read(), 2870 r_write_sc_key.read()); 2871 } 2872 2859 2873 for(size_t word=0 ; word<m_words ; word++) 2860 2874 { … … 2867 2881 } 2868 2882 2869 if (owner and not no_update and (r_write_pktid.read() != TYPE_SC))2883 if (owner and not no_update and ((r_write_pktid.read() & 0x7) != TYPE_SC)) 2870 2884 { 2871 2885 r_write_count = r_write_count.read() - 1; … … 2936 2950 if (wok ) // write data in cache 2937 2951 { 2952 2953 if ((r_write_pktid.read() & 0x7) == TYPE_SC) 2954 { 2955 m_llsc_table.sc(r_write_address.read(), 2956 r_write_sc_key.read()); 2957 } 2958 2938 2959 for(size_t word=0 ; word<m_words ; word++) 2939 2960 { … … 2999 3020 size_t min = r_write_word_index.read(); 3000 3021 size_t max = r_write_word_index.read() + r_write_word_count.read(); 3001 for(size_t i=min ; i< max ; i++) r_write_to_cc_send_data[i] = r_write_data[i];3022 for(size_t i=min ; i<=max ; i++) r_write_to_cc_send_data[i] = r_write_data[i]; 3002 3023 3003 3024 if ((r_write_copy.read() != r_write_srcid.read()) or 3004 (r_write_pktid.read() == TYPE_SC) or r_write_copy_inst.read()) 3025 ((r_write_pktid.read() & 0x7) == TYPE_SC) or 3026 r_write_copy_inst.read()) 3005 3027 { 3006 3028 // put the first srcid in the fifo … … 3060 3082 // put the next srcid in the fifo 3061 3083 if ((entry.owner.srcid != r_write_srcid.read()) or 3062 (r_write_pktid.read() == TYPE_SC) or entry.owner.inst) 3084 ((r_write_pktid.read() & 0x7) == TYPE_SC) or 3085 entry.owner.inst) 3063 3086 { 3064 3087 dec_upt_counter = false; … … 3140 3163 // a new request in the write FIFO 3141 3164 { 3142 if ( !r_write_to_tgt_rsp_req.read())3165 if (not r_write_to_tgt_rsp_req.read()) 3143 3166 { 3144 3167 // post the request to TGT_RSP_FSM … … 3150 3173 3151 3174 // try to get a new write request from the FIFO 3152 if (m_cmd_write_addr_fifo.rok()) 3175 if (not m_cmd_write_addr_fifo.rok()) 3176 { 3177 r_write_fsm = WRITE_IDLE; 3178 } 3179 else 3153 3180 { 3154 3181 // consume a word in the FIFO & write it in the local buffer … … 3158 3185 r_write_address = (addr_t) (m_cmd_write_addr_fifo.read()); 3159 3186 r_write_word_index = index; 3160 r_write_word_count = 1;3187 r_write_word_count = 0; 3161 3188 r_write_data[index] = m_cmd_write_data_fifo.read(); 3162 3189 r_write_srcid = m_cmd_write_srcid_fifo.read(); 3163 3190 r_write_trdid = m_cmd_write_trdid_fifo.read(); 3164 3191 r_write_pktid = m_cmd_write_pktid_fifo.read(); 3165 r_write_pending_sc = false; 3192 3193 // if SC command, get the SC key 3194 if ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC) 3195 { 3196 assert( not m_cmd_write_eop_fifo.read() && 3197 "MEMC ERROR in WRITE_RSP state: " 3198 "invalid packet format for SC command"); 3199 3200 r_write_sc_key = m_cmd_write_data_fifo.read(); 3201 } 3166 3202 3167 3203 // initialize the be field for all words … … 3169 3205 { 3170 3206 if (word == index) r_write_be[word] = m_cmd_write_be_fifo.read(); 3171 else 3207 else r_write_be[word] = 0x0; 3172 3208 } 3173 3209 3174 if (m_cmd_write_eop_fifo.read() or ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC))3210 if (m_cmd_write_eop_fifo.read()) 3175 3211 { 3176 3212 r_write_fsm = WRITE_DIR_REQ; … … 3180 3216 r_write_fsm = WRITE_NEXT; 3181 3217 } 3182 }3183 else3184 {3185 r_write_fsm = WRITE_IDLE;3186 3218 } 3187 3219 … … 3221 3253 bool wok = not m_trt.full(wok_index); 3222 3254 3223 if (hit_read) // register the modified data in TRT 3255 // wait an empty entry in TRT 3256 if(not hit_read and (not wok or hit_write)) 3257 { 3258 r_write_fsm = WRITE_WAIT; 3259 m_cpt_trt_full++; 3260 3261 break; 3262 } 3263 3264 if ((r_write_pktid.read() & 0x7) == TYPE_SC) 3265 { 3266 m_llsc_table.sc(r_write_address.read(), 3267 r_write_sc_key.read()); 3268 } 3269 3270 // register the modified data in TRT 3271 if (hit_read) 3224 3272 { 3225 3273 r_write_trt_index = hit_index; 3226 3274 r_write_fsm = WRITE_MISS_TRT_DATA; 3227 3275 m_cpt_write_miss++; 3228 } 3229 else if (wok and !hit_write) // set a new entry in TRT 3276 break; 3277 } 3278 3279 // set a new entry in TRT 3280 if (wok and not hit_write) 3230 3281 { 3231 3282 r_write_trt_index = wok_index; 3232 3283 r_write_fsm = WRITE_MISS_TRT_SET; 3233 3284 m_cpt_write_miss++; 3234 } 3235 else // wait an empty entry in TRT 3236 { 3237 r_write_fsm = WRITE_WAIT; 3238 m_cpt_trt_full++; 3239 } 3285 break; 3286 } 3287 3288 assert(false && "VCI_MEM_CACHE ERROR: this part must not be reached"); 3240 3289 } 3241 3290 break; … … 3477 3526 3478 3527 m_cache_directory.write(set, way, entry); 3528 3529 if ((r_write_pktid.read() & 0x7) == TYPE_SC) 3530 { 3531 m_llsc_table.sc(r_write_address.read(), 3532 r_write_sc_key.read()); 3533 } 3479 3534 3480 3535 #if DEBUG_MEMC_WRITE … … 6284 6339 { 6285 6340 if (not p_dspin_m2p.read) break; 6286 if (r_cc_send_cpt.read() == (r_write_to_cc_send_count.read() - 1))6341 if (r_cc_send_cpt.read() == r_write_to_cc_send_count.read()) 6287 6342 { 6288 6343 write_to_cc_send_fifo_get = true; … … 8306 8361 8307 8362 p_dspin_m2p.write = true; 8308 p_dspin_m2p.eop = (r_cc_send_cpt.read() == (r_write_to_cc_send_count.read()-1));8363 p_dspin_m2p.eop = (r_cc_send_cpt.read() == r_write_to_cc_send_count.read()); 8309 8364 p_dspin_m2p.data = flit; 8310 8365
Note: See TracChangeset
for help on using the changeset viewer.