Ignore:
Timestamp:
Jan 28, 2013, 1:59:32 PM (11 years ago)
Author:
joannou
Message:

Introducing new generic_llsc_local_table and generic_llsc_global_table components :
These two tables implement the new scalable LL/SC mechanism for TSAR.

  • generic_llsc_local_table, integrated in the vci_cc_vache_wrapper_v4 component. The table is accessed by the DCACHE_FSM. A two step registration (LL cmd/ LL rsp) sets a signature allocated by the global table for the pending LL/SC operation. An SC operation consumes the registration.
  • generic_llsc_global_table, integrated in the vci_mem_cache_v4 component. The table is accessed by the READ_FSM, WRITE_FSM, CAS_FSM, when accessing the directory. It generates a signature for LL registrations and performs SC operation by checking registration's valididty with that signature. SW operations simply invalidate a registrations.

N.B. :

  • The sizes of the tables are parameters, and are NOT a function of the architecture's size (scalable mechanism).
  • The LL are handled by the MEMCACHE in the READ_FSM.
  • The SC are handled by the MEMCACHE in the WRITE_FSM, and are no longer CAS emulated. CAS operation is now only performed by hardware mechanisms.
  • An extra field is added to the xram transaction table to save a pending LL's signature.
File:
1 edited

Legend:

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

    r290 r291  
    293293    m_cache_data( nways, nsets, nwords ),
    294294    m_heap( m_heap_size ),
     295    m_llsc_table(),
    295296
    296297#define L2 soclib::common::uint32_log2
     
    511512              << " | " << ixr_rsp_fsm_str[r_ixr_rsp_fsm]
    512513              << " | " << xram_rsp_fsm_str[r_xram_rsp_fsm] << std::endl;
     514
     515              //m_llsc_table.print_trace();
     516
    513517}
    514518
     
    860864          assert(((p_vci_tgt.pktid.read() & 0x7) == 0x6) &&
    861865            "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;
    864867        }
    865868        else if ( p_vci_tgt.cmd.read() == vci_param::CMD_NOP )
     
    874877            "The type specified in the pktid field is incompatible with the NOP CMD");
    875878
    876           if(p_vci_tgt.pktid.read() == TYPE_CAS)
     879          if((p_vci_tgt.pktid.read() & 0x7) == TYPE_CAS)
    877880            r_tgt_cmd_fsm = TGT_CMD_CAS;
    878881          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;
    881883        }
    882884        else
     
    892894    //////////////////
    893895    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 ))
    895899      {
    896900        std::cout
     
    907911          << std::endl;
    908912        std::cout
    909           << " read command packets must contain one single flit"
     913          << " read or ll command packets must contain one single flit"
    910914          << std::endl;
    911915        exit(0);
     
    927931#endif
    928932        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++;
    930937        r_tgt_cmd_fsm = TGT_CMD_IDLE;
    931938      }
     
    11391146  //    READ FSM
    11401147  ////////////////////////////////////////////////////////////////////////////////////
    1141   // The READ FSM controls the VCI read requests.
     1148  // The READ FSM controls the VCI read  and ll requests.
    11421149  // It takes the lock protecting the cache directory to check the cache line status:
    11431150  // - In case of HIT
     
    11741181            << " srcid = " << std::dec << m_cmd_read_srcid_fifo.read()
    11751182            << " / address = " << std::hex << m_cmd_read_addr_fifo.read()
     1183            << " / pktid = " << std::hex << m_cmd_read_pktid_fifo.read()
    11761184            << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
    11771185        }
     
    12111219        DirectoryEntry entry =
    12121220          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        }
    12141225        r_read_is_cnt     = entry.is_cnt;
    12151226        r_read_dirty      = entry.dirty;
     
    12561267            << " / count = " <<std::dec << entry.count
    12571268            << " / 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            }
    12581274        }
    12591275#endif
     
    16041620        r_read_to_tgt_rsp_trdid  = m_cmd_read_trdid_fifo.read();
    16051621        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;
    16091626
    16101627#if DEBUG_MEMC_READ
     
    16731690            m_x[(vci_addr_t)(m_cmd_read_addr_fifo.read())],
    16741691            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());
    16761694#if DEBUG_MEMC_READ
    16771695        if( m_debug_read_fsm )
     
    17181736  //    WRITE FSM
    17191737  ///////////////////////////////////////////////////////////////////////////////////
    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.
    17211739  // All addresses in a burst must be in the same cache line.
    17221740  // A complete write burst is consumed in the FIFO & copied to a local buffer.
     
    17281746  //   returned to the writing processor.
    17291747  //   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):
    17311749  //   It is a multicast update if the line is not in counter mode, and the processor
    17321750  //   takes the lock protecting the Update Table (UPT) to register this transaction.
     
    17531771      if ( m_cmd_write_addr_fifo.rok() )
    17541772      {
    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        }
    17571780
    17581781        // consume a word in the FIFO & write it in the local buffer
    17591782        cmd_write_fifo_get  = true;
     1783        r_write_pending_sc  = false;
    17601784        size_t index        = m_x[(vci_addr_t)(m_cmd_write_addr_fifo.read())];
    17611785
     
    17751799        }
    17761800
    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) )
    17781802        {
    17791803          r_write_fsm = WRITE_DIR_REQ;
     
    18241848        // consume a word in the FIFO & write it in the local buffer
    18251849        cmd_write_fifo_get  = true;
     1850        r_write_pending_sc  = false;
    18261851        size_t index        = r_write_word_index.read() + r_write_word_count.read();
    18271852
     
    18441869      if ( r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE )
    18451870      {
     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        }
    18461903        r_write_fsm = WRITE_DIR_LOCK;
    18471904      }
     
    19051962            << " count = " << entry.count
    19061963            << " 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;
    19071968        }
    19081969#endif
     
    19852046
    19862047      // 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)));
    19882050
    19892051      // write data in the cache if no coherence transaction
     
    20042066      }
    20052067
    2006       if ( owner and not no_update )
     2068      if ( owner and not no_update and (r_write_pktid.read() != TYPE_SC))
    20072069      {
    20082070        r_write_count = r_write_count.read() - 1;
     
    21272189    case WRITE_UPT_REQ:
    21282190    {
    2129       // prepare the coherence ransaction for the INIT_CMD FSM
     2191      // prepare the coherence transaction for the INIT_CMD FSM
    21302192      // and write the first copy in the FIFO
    21312193      // send the request if only one copy
     
    21462208        for (size_t i=min ; i<max ; i++) r_write_to_init_cmd_data[i] = r_write_data[i];
    21472209
    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
    21492211#if L1_MULTI_CACHE
    21502212            (r_write_copy_cache.read() != r_write_pktid.read()) or
     
    21592221          write_to_init_cmd_fifo_cache_id= r_write_copy_cache.read();
    21602222#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)) )
    21622224          {
    21632225            r_write_fsm = WRITE_IDLE;
     
    22072269      bool dec_upt_counter;
    22082270
    2209       if( (entry.owner.srcid != r_write_srcid.read()) or
     2271      if(((entry.owner.srcid != r_write_srcid.read()) || (r_write_pktid.read() == TYPE_SC)) or
    22102272#if L1_MULTI_CACHE
    22112273          (entry.owner.cache_id != r_write_pktid.read()) or
    22122274#endif
    2213           entry.owner.inst)               // put te next srcid in the fifo
     2275          entry.owner.inst)             // put the next srcid in the fifo
    22142276      {
    22152277        dec_upt_counter                 = false;
     
    22992361      {
    23002362        // 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();
    23052368
    23062369        // try to get a new write request from the FIFO
    23072370        if ( m_cmd_write_addr_fifo.rok() )
    23082371        {
    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          }
    23112379
    23122380          // consume a word in the FIFO & write it in the local buffer
    23132381          cmd_write_fifo_get  = true;
     2382          r_write_pending_sc  = false;
    23142383          size_t index        = m_x[(vci_addr_t)(m_cmd_write_addr_fifo.read())];
    23152384
     
    23292398          }
    23302399
    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) )
    23322401          {
    23332402            r_write_fsm = WRITE_DIR_REQ;
     
    31913260            entry.lock    = false;
    31923261            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;
    31943263            entry.ptr     = 0;
    31953264            if(cached_read)
     
    33053374                r_xram_rsp_to_tgt_rsp_word   = r_xram_rsp_trt_buf.word_index;
    33063375                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;
    33073377                r_xram_rsp_to_tgt_rsp_rerror = false;
    33083378                r_xram_rsp_to_tgt_rsp_req    = true;
     
    43714441        //////////////////////
    43724442        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
    43754448            // test coherence request
    43764449            if(r_cas_count.read())   // replicated line
     
    44224495              << " / value = " << r_cas_wdata.read()
    44234496              << " / count = " << r_cas_count.read() << std::endl;
     4497    std::cout << "  <MEMC " << name() << ".CAS_DIR_HIT_WRITE> global_llsc_table SW access" << std::endl;
    44244498}
    44254499#endif
     
    63836457      case TGT_RSP_READ:
    63846458        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();
    63866466        p_vci_tgt.rsrcid   = r_read_to_tgt_rsp_srcid.read();
    63876467        p_vci_tgt.rtrdid   = r_read_to_tgt_rsp_trdid.read();
     
    63916471        break;
    63926472      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            }*/
    63936477        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;
    63956482        p_vci_tgt.rsrcid   = r_write_to_tgt_rsp_srcid.read();
    63966483        p_vci_tgt.rtrdid   = r_write_to_tgt_rsp_trdid.read();
    63976484        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;
    63996487        p_vci_tgt.reop     = true;
    64006488        break;
     
    64196507      case TGT_RSP_XRAM:
    64206508        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();
    64226514        p_vci_tgt.rsrcid   = r_xram_rsp_to_tgt_rsp_srcid.read();
    64236515        p_vci_tgt.rtrdid   = r_xram_rsp_to_tgt_rsp_trdid.read();
     
    64306522      case TGT_RSP_INIT:
    64316523        p_vci_tgt.rspval   = true;
    6432         p_vci_tgt.rdata    = 0;
     6524        p_vci_tgt.rdata    = 0; // Can be a CAS or SC rsp
    64336525        p_vci_tgt.rsrcid   = r_init_rsp_to_tgt_rsp_srcid.read();
    64346526        p_vci_tgt.rtrdid   = r_init_rsp_to_tgt_rsp_trdid.read();
    64356527        p_vci_tgt.rpktid   = r_init_rsp_to_tgt_rsp_pktid.read();
    6436         p_vci_tgt.rerror   = 0; // Can be a CAS rsp
     6528        p_vci_tgt.rerror   = 0;
    64376529        p_vci_tgt.reop     = true;
    64386530        break;
Note: See TracChangeset for help on using the changeset viewer.