Ignore:
Timestamp:
Sep 18, 2013, 1:44:37 PM (11 years ago)
Author:
cfuguet
Message:

Bugfix in vci_mem_cache and generic_llsc_global_table:

  • The Store Conditional commmand was not performed atomically in some special cases. To solve this, a new operation has been introduced in the LL/SC table (check operation) which allows

to check if a SC operation is atomic or not without erasing the

reservation on the LL/SC table.

The reservation on the LL/SC table will be erased once the SC
command is completely treated:

  • A GET request has been inserted on the TRT when MISS.
  • An UPDATE request has been inserted on the UPT when MULTI

UPDATE needed.

  • An INVAL request has been inserted on the IVT when BROADCAST INVALIDATE needed.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp

    r524 r527  
    26542654            case WRITE_IDLE:  // copy first word of a write burst in local buffer
    26552655                {
    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                    }
    26862695
    26872696#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
    26952703                    break;
    26962704                }
     
    26982706            case WRITE_NEXT:  // copy next word of a write burst in local buffer
    26992707                {
    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;
    27022736
    27032737#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
    27252743                    break;
    27262744                }
    27272745                ///////////////////
    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
    27592767#define L2 soclib::common::uint32_log2
    2760                             addr_t min = r_write_address.read();
    2761                             addr_t max = r_write_address.read() +
    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));
    27632771#undef L2
    27642772
    2765                             m_llsc_table.sw(min, max);
    2766 
    2767                             r_write_fsm = WRITE_DIR_LOCK;
    2768                         }
     2773                        m_llsc_table.sw(min, max);
     2774
     2775                        r_write_fsm = WRITE_DIR_LOCK;
     2776                    }
    27692777
    27702778#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
    27762783                    break;
    27772784                }
     
    27982805
    27992806                        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;
    28012808                    }
    28022809                    else  // miss
     
    28512858                    // no_update is true when there is no need for coherence transaction
    28522859                    bool no_update = ( (r_write_count.read() == 0) or
    2853                             (owner and (r_write_count.read() ==1) and
    2854                              (r_write_pktid.read() != TYPE_SC)));
     2860                            (owner and (r_write_count.read() == 1) and
     2861                             ((r_write_pktid.read() & 0x7) != TYPE_SC)));
    28552862
    28562863                    // write data in the cache if no coherence transaction
    28572864                    if (no_update)
    28582865                    {
     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
    28592873                        for(size_t word=0 ; word<m_words ; word++)
    28602874                        {
     
    28672881                    }
    28682882
    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))
    28702884                    {
    28712885                        r_write_count = r_write_count.read() - 1;
     
    29362950                        if (wok )       // write data in cache
    29372951                        {
     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
    29382959                            for(size_t word=0 ; word<m_words ; word++)
    29392960                            {
     
    29993020                    size_t min = r_write_word_index.read();
    30003021                    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];
    30023023
    30033024                    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())
    30053027                    {
    30063028                        // put the first srcid in the fifo
     
    30603082                    // put the next srcid in the fifo
    30613083                    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)
    30633086                    {
    30643087                        dec_upt_counter                = false;
     
    31403163                // a new request in the write FIFO
    31413164                {
    3142                     if (!r_write_to_tgt_rsp_req.read())
     3165                    if (not r_write_to_tgt_rsp_req.read())
    31433166                    {
    31443167                        // post the request to TGT_RSP_FSM
     
    31503173
    31513174                        // 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
    31533180                        {
    31543181                            // consume a word in the FIFO & write it in the local buffer
     
    31583185                            r_write_address     = (addr_t) (m_cmd_write_addr_fifo.read());
    31593186                            r_write_word_index  = index;
    3160                             r_write_word_count  = 1;
     3187                            r_write_word_count  = 0;
    31613188                            r_write_data[index] = m_cmd_write_data_fifo.read();
    31623189                            r_write_srcid       = m_cmd_write_srcid_fifo.read();
    31633190                            r_write_trdid       = m_cmd_write_trdid_fifo.read();
    31643191                            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                            }
    31663202
    31673203                            // initialize the be field for all words
     
    31693205                            {
    31703206                                if (word == index) r_write_be[word] = m_cmd_write_be_fifo.read();
    3171                                 else                 r_write_be[word] = 0x0;
     3207                                else               r_write_be[word] = 0x0;
    31723208                            }
    31733209
    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())
    31753211                            {
    31763212                                r_write_fsm = WRITE_DIR_REQ;
     
    31803216                                r_write_fsm = WRITE_NEXT;
    31813217                            }
    3182                         }
    3183                         else
    3184                         {
    3185                             r_write_fsm = WRITE_IDLE;
    31863218                        }
    31873219
     
    32213253                        bool    wok       = not m_trt.full(wok_index);
    32223254
    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)
    32243272                        {
    32253273                            r_write_trt_index = hit_index;
    32263274                            r_write_fsm       = WRITE_MISS_TRT_DATA;
    32273275                            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)
    32303281                        {
    32313282                            r_write_trt_index = wok_index;
    32323283                            r_write_fsm       = WRITE_MISS_TRT_SET;
    32333284                            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");
    32403289                    }
    32413290                    break;
     
    34773526
    34783527                    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                    }
    34793534
    34803535#if DEBUG_MEMC_WRITE
     
    62846339                {
    62856340                    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())
    62876342                    {
    62886343                        write_to_cc_send_fifo_get = true;
     
    83068361
    83078362                    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());
    83098364                    p_dspin_m2p.data  = flit;
    83108365
Note: See TracChangeset for help on using the changeset viewer.