Changeset 527 for trunk


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.
Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/generic_llsc_global_table/include/generic_llsc_global_table.h

    r524 r527  
    2828#define SOCLIB_GENERIC_LLSC_GLOBAL_TABLE_H
    2929
    30 #include <systemc>
    31 #include <arithmetics.h>
    3230#include <cassert>
    3331#include <cstring>
     
    3533#include <iostream>
    3634#include <iomanip>
     35#include <stdint.h>
    3736
    3837namespace soclib
     
    7069
    7170    uint32_t                    r_next_key        ; // value of the next key
    72     sc_dt::sc_uint<nb_slots>    r_block_mask      ; // mask for the slots blocks
    73     sc_dt::sc_uint<nb_slots>    r_last_counter    ; // mask for the slots blocks
     71    uint64_t                    r_block_mask      ; // mask for the slots blocks
     72    uint64_t                    r_last_counter    ; // mask for the slots blocks
    7473    size_t                      r_write_ptr       ; // index of next slot to replace
    7574    size_t                      r_last_empty      ; // index of last empty slot used
    7675
    77     uint32_t                    m_cpt_evic        ; // number of eviction in the table
    78     uint32_t                    m_cpt_ll          ; // number of ll accesses to the table
    79     uint32_t                    m_cpt_ll_update   ; // number of ll accesses to the table that trigger an update TODO check that
    80     uint32_t                    m_cpt_sc          ; // number of sc accesses to the table
    81     uint32_t                    m_cpt_sc_success  ; // number of sc accesses to the table that are successful
    82     uint32_t                    m_cpt_sw          ; // number of sw accesses to the table
     76    mutable uint32_t            m_cpt_evic        ; // number of eviction in the table
     77    mutable uint32_t            m_cpt_ll          ; // number of ll accesses to the table
     78    mutable uint32_t            m_cpt_ll_update   ; // number of ll accesses to the table that trigger an update TODO check that
     79    mutable uint32_t            m_cpt_sc          ; // number of sc accesses to the table
     80    mutable uint32_t            m_cpt_sc_success  ; // number of sc accesses to the table that are successful
     81    mutable uint32_t            m_cpt_check       ; // number of check accesses to the table
     82    mutable uint32_t            m_cpt_sw          ; // number of sw accesses to the table
    8383
    8484    ////////////////////////////////////////////////////////////////////////////
     
    121121    //  This is done by updating the value of r_write_ptr
    122122    {
    123         sc_dt::sc_uint<nb_slots> new_counter;
    124         sc_dt::sc_uint<nb_slots> xor_counter;
     123        uint64_t new_counter;
     124        uint64_t xor_counter;
    125125
    126126        new_counter = newCounter(r_block_mask, r_last_counter);
     
    129129        for (size_t i = nb_slots - 1; i >= 0; --i)
    130130        {
    131             if(xor_counter[i])
     131            if(xor_counter & (1 << i))
    132132            {
    133133                r_write_ptr = i;
     
    140140
    141141    ////////////////////////////////////////////////////////////////////////////
    142     inline sc_dt::sc_uint<nb_slots> newCounter(const sc_dt::sc_uint<nb_slots>& mask,
    143                                                const sc_dt::sc_uint<nb_slots>& counter)
     142    inline uint64_t newCounter(const uint64_t& mask,
     143                               const uint64_t& counter) const
    144144    // This function generates the new counter //TODO comment more
    145145    {
    146         //
    147146        return ((((~counter) & (counter << 1)) & mask) | (counter + 1));
    148147    }
     
    164163        {
    165164            case 12:
    166             r_block_mask = sc_dt::sc_uint<nb_slots>("0x000");
     165            r_block_mask = (uint64_t)0x000ULL;
    167166            break;
    168167            case 16 :
    169             r_block_mask = sc_dt::sc_uint<nb_slots>("0xA800");
     168            r_block_mask = (uint64_t)0xA800ULL;
    170169            break;
    171170            case 20 :
    172             r_block_mask = sc_dt::sc_uint<nb_slots>("0xD5500");
     171            r_block_mask = (uint64_t)0xD5500ULL;
    173172            break;
    174173            case 24 :
    175             r_block_mask = sc_dt::sc_uint<nb_slots>("0xDB5540");
     174            r_block_mask = (uint64_t)0xDB5540ULL;
    176175            break;
    177176            case 28 :
    178             r_block_mask = sc_dt::sc_uint<nb_slots>("0xEEDAAA0");
     177            r_block_mask = (uint64_t)0xEEDAAA0ULL;
    179178            break;
    180179            case 32 :
    181             r_block_mask = sc_dt::sc_uint<nb_slots>("0xF776D550");
     180            r_block_mask = (uint64_t)0xF776D550ULL;
    182181            break;
    183182            case 36 :
    184             r_block_mask = sc_dt::sc_uint<nb_slots>("0xFBDDDB550");
     183            r_block_mask = (uint64_t)0xFBDDDB550ULL;
    185184            break;
    186185            case 40 :
    187             r_block_mask = sc_dt::sc_uint<nb_slots>("0xFDF7BB6D50");
     186            r_block_mask = (uint64_t)0xFDF7BB6D50ULL;
    188187            break;
    189188            case 44 :
    190             r_block_mask = sc_dt::sc_uint<nb_slots>("0xFEFBDEEDAA8");
     189            r_block_mask = (uint64_t)0xFEFBDEEDAA8ULL;
    191190            break;
    192191            case 48 :
    193             r_block_mask = sc_dt::sc_uint<nb_slots>("0xFF7EFBDDDAA8");
     192            r_block_mask = (uint64_t)0xFF7EFBDDDAA8ULL;
    194193            break;
    195194            case 52 :
    196             r_block_mask = sc_dt::sc_uint<nb_slots>("0xFFBFBF7BBB6A8");
     195            r_block_mask = (uint64_t)0xFFBFBF7BBB6A8ULL;
    197196            break;
    198197            case 56 :
    199             r_block_mask = sc_dt::sc_uint<nb_slots>("0xFFDFEFDF7BB6A8");
     198            r_block_mask = (uint64_t)0xFFDFEFDF7BB6A8ULL;
    200199            break;
    201200            case 60 :
    202             r_block_mask = sc_dt::sc_uint<nb_slots>("0xFFF7FDFDF7BB6A8");
     201            r_block_mask = (uint64_t)0xFFF7FDFDF7BB6A8ULL;
    203202            break;
    204203            case 64 :
    205             r_block_mask = sc_dt::sc_uint<nb_slots>("0xFFFBFF7FBF7BB6A8");
     204            r_block_mask = (uint64_t)0xFFFBFF7FBF7BB6A8ULL;
    206205            break;
    207206            default:
     
    211210
    212211    ////////////////////////////////////////////////////////////////////////////
    213     inline int nextEmptySlot()
     212    inline int nextEmptySlot() const
    214213    //  This function returns :
    215214    //  - the position of the first next empty slot in the table
     
    218217    //  - -1 if the table is full
    219218    {
    220         size_t i = r_last_empty;
    221         do
    222         {
    223             // checking if current slot is empty
    224             if(!r_val[i])
    225             {
    226                 // updating last empty slot and returning its position
    227                 r_last_empty = i;
    228                 return i;
    229             }
    230             // selecting next slot
    231             i = (i+1) % nb_slots;
    232         }
    233         // stop if all slots have been tested
    234         while(i != r_last_empty);
    235 
    236         // the table is full
     219        uint64_t i;
     220        for(i = 0; i < nb_slots; i++)
     221        {
     222            if (!r_val[i]) return i;
     223        }
     224
    237225        return -1;
    238226    }
    239227
    240228    ////////////////////////////////////////////////////////////////////////////
    241     inline int hitAddr(const addr_t ad)
     229    inline int hitAddr(const addr_t ad) const
    242230    //  HIT on the address only
    243231    //  This function takes an addr_t ad
     
    259247
    260248    ////////////////////////////////////////////////////////////////////////////
    261     inline int hitAddrKey(const addr_t ad, const uint32_t key)
     249    inline int hitAddrKey(const addr_t ad, const uint32_t key) const
    262250    //  HIT on the address AND the on the signature
    263251    //  This function takes an addr_t ad and a uint32_t key
     
    291279        m_cpt_sc            = 0;
    292280        m_cpt_sc_success    = 0;
     281        m_cpt_check         = 0;
    293282        m_cpt_sw            = 0;
    294283    }
     
    301290    :   name(n)
    302291    {
    303         #define L2 soclib::common::uint32_log2
    304292        assert(nb_procs > 1);
    305         assert((int)nb_slots >= L2(nb_procs));
    306         #undef L2
    307293        init();
    308294        init_block_mask();
     
    362348        if (pos >= 0)
    363349        {
    364             if(r_key[pos] - r_next_key > life_span)
    365                 return r_key[pos];
     350            uint32_t absdiff = ( r_key[pos] > r_next_key) ?
     351                                 r_key[pos] - r_next_key  :
     352                                 r_next_key - r_key[pos];
     353
     354            if(absdiff < life_span) return r_key[pos];
     355
    366356            r_key[pos] = r_next_key;
    367357            upNextKey();
    368358            m_cpt_ll_update++;
     359
    369360            return r_key[pos];
    370361        }
     
    377368        if (pos == -1)
    378369        {
     370            //  update the victim slot for the next eviction
     371            updateVictimSlot();
     372
    379373            //  get the position of the evicted registration
    380374            pos = r_write_ptr;
    381             //  update the victim slot for the next eviction
    382             updateVictimSlot();
     375
    383376            // increment the eviction counter (for stats)
    384377            m_cpt_evic++;
     
    434427
    435428    ////////////////////////////////////////////////////////////////////////////
     429    inline bool check(const addr_t ad, const uint32_t key) const
     430    //  This method checks if there is a valid registration for the SC (ad &&
     431    //  key)
     432    //  The return value can be used to tell if the SC is atomic
     433    {
     434        // increment the check access counter (for stats)
     435        m_cpt_check++;
     436
     437        return (hitAddrKey(ad, key) >= 0);
     438    }
     439
     440    ////////////////////////////////////////////////////////////////////////////
    436441    /*
    437442    inline void sw(const addr_t ad)
     
    489494    inline void print_trace(std::ostream& out = std::cout)
    490495    {
    491         out <<  " ___________________________________" << std::endl
    492             <<  "| " << std::setw(33) << "generic_llsc_global_table" << " |" << std::endl
    493             <<  "| " << std::setw(33) << name << " |" << std::endl
    494             <<  " ===================================" << std::endl
    495             <<  "| "
    496             <<  std::setw(11) << "addr"   << " | "
    497             <<  std::setw(11) << "key"    << " | "
    498             <<  std::setw(5)  << "val"
    499             << " |" << std::endl
    500             <<  " -----------------------------------" << std::endl;
    501496        for ( size_t i = 0; i < nb_slots ; i++ )
    502497        {
    503             out << "| "
    504                 << std::showbase
    505                 << std::setw(11) << std::setfill('0')   << std::hex       << r_addr[i]    << " | "
     498            out << std::setw(3)   << std::setfill(' ') << std::dec << i
    506499                << std::noshowbase
    507                 << std::setw(11) << std::setfill('0')   << std::dec       << r_key[i]     << " | "
    508                 << std::setw(5)  << std::setfill(' ')   << std::boolalpha << r_val[i]     << " |" << std::endl ;
    509         }
    510         out <<  " -----------------------------------" << std::endl
    511             << std::noshowbase << std::dec << std::endl ;
     500                << " VLD_RX = "   << r_val[i]
     501                << std::uppercase
     502                << " ADR_RX = 0x" << std::setw(8) << std::setfill('0') << std::hex << (r_addr[i] >> 2)
     503                << " SGN_RX = 0x" << std::setw(8) << std::setfill('0') << std::hex << r_key[i]
     504                << std::endl;
     505        }
     506        out << "NEXT_SGN_RX = 0x" << std::setw(8) << std::setfill('0') << std::hex << r_next_key     << std::endl
     507            << "CNT_RX = 0x"      << std::setw(8) << std::setfill('0') << std::hex << r_last_counter << std::endl;
    512508    }
    513509
  • trunk/modules/vci_mem_cache/caba/source/include/vci_mem_cache.h

    r507 r527  
    702702      sc_signal<size_t>   r_write_upt_index;          // index in Update Table
    703703      sc_signal<bool>     r_write_sc_fail;            // sc command failed
    704       sc_signal<bool>     r_write_pending_sc;         // sc command pending
     704      sc_signal<data_t>   r_write_sc_key;             // sc command key
    705705
    706706      // Buffer between WRITE fsm and TGT_RSP fsm (acknowledge a write command from L1)
  • 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.