Ignore:
Timestamp:
Aug 20, 2013, 2:13:08 PM (11 years ago)
Author:
devigne
Message:

Merge with the lastest version of trunk

Location:
branches/ODCCP/modules/vci_mem_cache
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/ODCCP/modules/vci_mem_cache

  • branches/ODCCP/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp

    r492 r494  
    4545#define DEBUG_MEMC_WRITE     1 // detailed trace of WRITE FSM
    4646#define DEBUG_MEMC_CAS       1 // detailed trace of CAS FSM
    47 #define DEBUG_MEMC_IXR_CMD   1 // detailed trace of IXR_RSP FSM
     47#define DEBUG_MEMC_IXR_CMD   1 // detailed trace of IXR_CMD FSM
    4848#define DEBUG_MEMC_IXR_RSP   1 // detailed trace of IXR_RSP FSM
    4949#define DEBUG_MEMC_XRAM_RSP  1 // detailed trace of XRAM_RSP FSM
     
    127127  "MULTI_ACK_UPT_LOCK",
    128128  "MULTI_ACK_UPT_CLEAR",
    129   "MULTI_ACK_WRITE_RSP",
    130   "MULTI_ACK_CONFIG_ACK"
     129  "MULTI_ACK_WRITE_RSP"
    131130};
    132131const char *config_fsm_str[] =
     
    134133  "CONFIG_IDLE",
    135134  "CONFIG_LOOP",
     135  "CONFIG_WAIT",
    136136  "CONFIG_RSP",
    137137  "CONFIG_DIR_REQ",
    138138  "CONFIG_DIR_ACCESS",
    139   "CONFIG_DIR_IVT_LOCK",
     139  "CONFIG_IVT_LOCK",
    140140  "CONFIG_BC_SEND",
    141   "CONFIG_BC_WAIT",
    142   "CONFIG_INV_SEND",
     141  "CONFIG_INVAL_SEND",
    143142  "CONFIG_HEAP_REQ",
    144143  "CONFIG_HEAP_SCAN",
    145144  "CONFIG_HEAP_LAST",
    146   "CONFIG_INV_WAIT"
     145  "CONFIG_TRT_LOCK",
     146  "CONFIG_TRT_SET",
     147  "CONFIG_PUT_REQ"
    147148};
    148149const char *read_fsm_str[] =
     
    168169  "WRITE_DIR_REQ",
    169170  "WRITE_DIR_LOCK",
    170   "WRITE_DIR_READ",
    171171  "WRITE_DIR_HIT",
    172172  "WRITE_UPT_LOCK",
     
    180180  "WRITE_MISS_TRT_SET",
    181181  "WRITE_MISS_XRAM_REQ",
     182  "WRITE_BC_DIR_READ",
    182183  "WRITE_BC_TRT_LOCK",
    183184  "WRITE_BC_IVT_LOCK",
     
    202203  "XRAM_RSP_DIR_UPDT",
    203204  "XRAM_RSP_DIR_RSP",
    204   "XRAM_RSP_INVAL_LOCK",
     205  "XRAM_RSP_IVT_LOCK",
    205206  "XRAM_RSP_INVAL_WAIT",
    206207  "XRAM_RSP_INVAL",
     
    219220  "IXR_CMD_XRAM_IDLE",
    220221  "IXR_CMD_CLEANUP_IDLE",
    221   "IXR_CMD_TRT_LOCK",
    222   "IXR_CMD_READ",
    223   "IXR_CMD_WRITE",
    224   "IXR_CMD_CAS",
    225   "IXR_CMD_XRAM",
    226   "IXR_CMD_CLEANUP_DATA"
     222  "IXR_CMD_CONFIG_IDLE",
     223  "IXR_CMD_READ_TRT",
     224  "IXR_CMD_WRITE_TRT",
     225  "IXR_CMD_CAS_TRT",
     226  "IXR_CMD_XRAM_TRT",
     227  "IXR_CMD_CLEANUP_TRT",
     228  "IXR_CMD_CONFIG_TRT",
     229  "IXR_CMD_READ_SEND",
     230  "IXR_CMD_WRITE_SEND",
     231  "IXR_CMD_CAS_SEND",
     232  "IXR_CMD_XRAM_SEND",
     233  "IXR_CMD_CLEANUP_DATA_SEND",
     234  "IXR_CMD_CONFIG_SEND"
    227235};
    228236const char *cas_fsm_str[] =
     
    267275  "CLEANUP_IVT_CLEAR",
    268276  "CLEANUP_WRITE_RSP",
    269   "CLEANUP_CONFIG_ACK",
    270277  "CLEANUP_IXR_REQ",
    271278  "CLEANUP_WAIT",
     
    290297  "ALLOC_TRT_IXR_RSP",
    291298  "ALLOC_TRT_CLEANUP",
    292   "ALLOC_TRT_IXR_CMD"
     299  "ALLOC_TRT_IXR_CMD",
     300  "ALLOC_TRT_CONFIG"
    293301};
    294302const char *alloc_upt_fsm_str[] =
    295303{
    296   "ALLOC_UPT_CONFIG",
    297304  "ALLOC_UPT_WRITE",
    298305  "ALLOC_UPT_CAS",
     
    351358  : soclib::caba::BaseModule(name),
    352359
    353     m_monitor_ok(false),
     360    //m_monitor_ok(false),
    354361   
    355362    p_clk( "p_clk" ),
     
    394401    m_broadcast_boundaries(0x7C1F),
    395402
    396     r_tgt_cmd_fsm("r_tgt_cmd_fsm"),
    397403
    398404    //  FIFOs
     
    421427    m_cc_receive_to_multi_ack_fifo("m_cc_receive_to_multi_ack_fifo", 4),
    422428
     429    r_tgt_cmd_fsm("r_tgt_cmd_fsm"),
     430
    423431    r_config_fsm( "r_config_fsm" ),
    424432
     
    432440    m_write_to_cc_send_inst_fifo("m_write_to_cc_send_inst_fifo",8),
    433441    m_write_to_cc_send_srcid_fifo("m_write_to_cc_send_srcid_fifo",8),
    434 #if L1_MULTI_CACHE
    435     m_write_to_cc_send_cache_id_fifo("m_write_to_cc_send_cache_id_fifo",8),
    436 #endif
    437442
    438443    r_multi_ack_fsm("r_multi_ack_fsm"),
     
    444449    m_cas_to_cc_send_inst_fifo("m_cas_to_cc_send_inst_fifo",8),
    445450    m_cas_to_cc_send_srcid_fifo("m_cas_to_cc_send_srcid_fifo",8),
    446 #if L1_MULTI_CACHE
    447     m_cas_to_cc_send_cache_id_fifo("m_cas_to_cc_send_cache_id_fifo",8),
    448 #endif
    449451
    450452    r_ixr_rsp_fsm("r_ixr_rsp_fsm"),
     
    453455    m_xram_rsp_to_cc_send_inst_fifo("m_xram_rsp_to_cc_send_inst_fifo",8),
    454456    m_xram_rsp_to_cc_send_srcid_fifo("m_xram_rsp_to_cc_send_srcid_fifo",8),
    455 #if L1_MULTI_CACHE
    456     m_xram_rsp_to_cc_send_cache_id_fifo("m_xram_rsp_to_cc_send_cache_id_fifo",8),
    457 #endif
    458457
    459458    r_ixr_cmd_fsm("r_ixr_cmd_fsm"),
     
    524523    r_xram_rsp_victim_data     = new sc_signal<data_t>[nwords];
    525524    r_xram_rsp_to_tgt_rsp_data = new sc_signal<data_t>[nwords];
    526     r_xram_rsp_to_ixr_cmd_data = new sc_signal<data_t>[nwords];
    527525
    528526    // Allocation for READ FSM
     
    535533    r_write_to_cc_send_data    = new sc_signal<data_t>[nwords];
    536534    r_write_to_cc_send_be      = new sc_signal<be_t>[nwords];
    537     r_write_to_ixr_cmd_data    = new sc_signal<data_t>[nwords];
    538535
    539536    // Allocation for CAS FSM
    540     r_cas_to_ixr_cmd_data      = new sc_signal<data_t>[nwords];
    541537    r_cas_data                 = new sc_signal<data_t>[nwords];
    542538    r_cas_rdata                = new sc_signal<data_t>[2];
     
    544540    // Allocation for ODCCP
    545541    r_cleanup_data             = new sc_signal<data_t>[nwords];
    546     r_ixr_cmd_data             = new sc_signal<data_t>[nwords];
    547542    r_cleanup_to_ixr_cmd_data  = new sc_signal<data_t>[nwords];
    548543
     544    // Allocation for IXR_CMD FSM
     545    r_ixr_cmd_wdata            = new sc_signal<data_t>[nwords];
     546
    549547    // Allocation for debug
    550     m_debug_previous_data      = new sc_signal<data_t>[nwords];
    551     m_debug_data               = new sc_signal<data_t>[nwords];
     548    m_debug_previous_data      = new data_t[nwords];
     549    m_debug_data               = new data_t[nwords];
    552550
    553551    SC_METHOD(transition);
     
    560558} // end constructor
    561559
    562 ///////////////////////////////////////////////////////////////////////
    563 tmpl(void) ::start_monitor(addr_t addr, addr_t length)
    564 ///////////////////////////////////////////////////////////////////////
    565 {
    566   m_monitor_ok        = true;
    567   m_monitor_base      = addr;
    568   m_monitor_length    = length;
    569 }
    570 
    571 ///////////////////////////////////////////////////////////////////////
    572 tmpl(void) ::stop_monitor()
    573 ///////////////////////////////////////////////////////////////////////
    574 {
    575   m_monitor_ok        = false;
    576 }
    577 
    578 ////////////////////////////////////////////////
    579 tmpl(void) ::check_monitor( addr_t      addr,
    580                             data_t      data,
    581                             bool        read )
    582 ////////////////////////////////////////////////
    583 {
    584   if((addr >= m_monitor_base) and
    585       (addr < m_monitor_base + m_monitor_length))
    586   {
    587     if ( read ) std::cout << " Monitor MEMC Read ";
    588     else        std::cout << " Monitor MEMC Write";
    589     std::cout << " / Address = " << std::hex << addr
    590               << " / Data = " << data
    591               << " at cycle " << std::dec << m_cpt_cycles << std::endl;
    592   }
    593 }
    594560
    595561/////////////////////////////////////////////////////
     
    601567    DirectoryEntry entry = m_cache_directory.read_neutral(addr, &way, &set );
    602568
     569    // read data and compute data_change
    603570    bool data_change = false;
    604 
    605571    if ( entry.valid )
    606572    {
    607         m_cache_data.read_line( way, set, m_debug_data );
    608 
    609         for ( size_t i = 0 ; i<m_words ; i++ )
    610         {
    611             if ( m_debug_previous_valid and
    612                  (m_debug_data[i].read() != m_debug_previous_data[i].read()) )
    613                  data_change = true;
    614             m_debug_previous_data[i] = m_debug_data[i].read();
     573        for ( size_t word = 0 ; word<m_words ; word++ )
     574        {
     575            m_debug_data[word] = m_cache_data.read(way, set, word);
     576            if ( m_debug_previous_valid and
     577                 (m_debug_data[word] != m_debug_previous_data[word]) )
     578            {
     579                data_change = true;
     580            }
    615581        }
    616582    }
    617583   
     584    // print values if any change
    618585    if ( (entry.valid != m_debug_previous_valid) or
    619586         (entry.valid and (entry.count != m_debug_previous_count)) or
     
    623590                  << " at cycle " << std::dec << m_cpt_cycles
    624591                  << " for address " << std::hex << addr
    625                   << " / HIT = " << std::dec << entry.valid
     592                  << " / VAL = " << std::dec << entry.valid
    626593                  << " / WAY = " << way
    627594                  << " / COUNT = " << entry.count
    628595                  << " / DIRTY = " << entry.dirty
    629                   << " / DATA_CHANGE = " << entry.count
     596                  << " / DATA_CHANGE = " << data_change
    630597                  << std::endl;
    631     }
     598        std::cout << std::hex << "     /0:" << m_debug_data[0]
     599                  << "/1:" << m_debug_data[1]
     600                  << "/2:" << m_debug_data[2]
     601                  << "/3:" << m_debug_data[3]
     602                  << "/4:" << m_debug_data[4]
     603                  << "/5:" << m_debug_data[5]
     604                  << "/6:" << m_debug_data[6]
     605                  << "/7:" << m_debug_data[7]
     606                  << "/8:" << m_debug_data[8]
     607                  << "/9:" << m_debug_data[9]
     608                  << "/A:" << m_debug_data[10]
     609                  << "/B:" << m_debug_data[11]
     610                  << "/C:" << m_debug_data[12]
     611                  << "/D:" << m_debug_data[13]
     612                  << "/E:" << m_debug_data[14]
     613                  << "/F:" << m_debug_data[15]
     614                  << std::endl;
     615    }
     616
     617    // register values
    632618    m_debug_previous_count = entry.count;
    633619    m_debug_previous_valid = entry.valid;
    634620    m_debug_previous_dirty = entry.dirty;
     621    for( size_t word=0 ; word<m_words ; word++ )
     622        m_debug_previous_data[word] = m_debug_data[word];
    635623}
    636624
     
    807795  delete [] r_xram_rsp_victim_data;
    808796  delete [] r_xram_rsp_to_tgt_rsp_data;
    809   delete [] r_xram_rsp_to_ixr_cmd_data;
    810797
    811798  delete [] r_read_data;
     
    889876    m_config_to_cc_send_inst_fifo.init();
    890877    m_config_to_cc_send_srcid_fifo.init();
    891 #if L1_MULTI_CACHE
    892     m_config_to_cc_send_cache_id_fifo.init();
    893 #endif
    894878
    895879    r_tgt_cmd_to_tgt_rsp_req = false;
     
    906890    m_write_to_cc_send_inst_fifo.init();
    907891    m_write_to_cc_send_srcid_fifo.init();
    908 #if L1_MULTI_CACHE
    909     m_write_to_cc_send_cache_id_fifo.init();
    910 #endif
    911892
    912893    r_cleanup_to_tgt_rsp_req      = false;
     
    914895    m_cc_receive_to_cleanup_fifo.init();
    915896
    916     r_multi_ack_to_tgt_rsp_req     = false;
     897    r_multi_ack_to_tgt_rsp_req    = false;
    917898
    918899    m_cc_receive_to_multi_ack_fifo.init();
     
    922903    r_cas_lfsr                    = -1   ;
    923904    r_cas_to_ixr_cmd_req          = false;
    924     r_cas_to_cc_send_multi_req   = false;
    925     r_cas_to_cc_send_brdcast_req = false;
     905    r_cas_to_cc_send_multi_req    = false;
     906    r_cas_to_cc_send_brdcast_req  = false;
    926907
    927908    m_cas_to_cc_send_inst_fifo.init();
    928909    m_cas_to_cc_send_srcid_fifo.init();
    929 #if L1_MULTI_CACHE
    930     m_cas_to_cc_send_cache_id_fifo.init();
    931 #endif
    932910
    933911    for(size_t i=0; i<m_trt_lines ; i++)
     
    945923    m_xram_rsp_to_cc_send_inst_fifo.init();
    946924    m_xram_rsp_to_cc_send_srcid_fifo.init();
    947 #if L1_MULTI_CACHE
    948     m_xram_rsp_to_cc_send_cache_id_fifo.init();
    949 #endif
    950 
    951     r_ixr_cmd_cpt          = 0;
     925
    952926    r_alloc_dir_reset_cpt  = 0;
    953927    r_alloc_heap_reset_cpt = 0;
     
    964938    //r_xram_rsp_to_ixr_cmd_inval_ncc_pending = false;
    965939    r_cleanup_to_ixr_cmd_srcid = 0;
    966     r_cleanup_to_ixr_cmd_trdid = 0;
     940    r_cleanup_to_ixr_cmd_index = 0;
    967941    r_cleanup_to_ixr_cmd_pktid = 0;
    968942    r_cleanup_to_ixr_cmd_nline = 0;
     
    971945      r_cleanup_to_ixr_cmd_data[word] = 0;
    972946      r_cleanup_data[word] = 0;
    973       r_ixr_cmd_data[word] = 0;
     947      r_ixr_cmd_wdata[word] = 0;
    974948    }
    975949
     
    10531027  size_t  write_to_cc_send_fifo_srcid = 0;
    10541028
    1055 #if L1_MULTI_CACHE
    1056   size_t  write_to_cc_send_fifo_cache_id = 0;
    1057 #endif
    1058 
    10591029  bool    xram_rsp_to_cc_send_fifo_put   = false;
    10601030  bool    xram_rsp_to_cc_send_fifo_get   = false;
     
    10621032  size_t  xram_rsp_to_cc_send_fifo_srcid = 0;
    10631033
    1064 #if L1_MULTI_CACHE
    1065   size_t  xram_rsp_to_cc_send_fifo_cache_id = 0;
    1066 #endif
    1067 
    10681034  bool    config_to_cc_send_fifo_put   = false;
    10691035  bool    config_to_cc_send_fifo_get   = false;
     
    10751041  bool    cas_to_cc_send_fifo_inst  = false;
    10761042  size_t  cas_to_cc_send_fifo_srcid = 0;
    1077 
    1078 #if L1_MULTI_CACHE
    1079   size_t  cas_to_cc_send_fifo_cache_id = 0;
    1080 #endif
    10811043
    10821044  m_debug = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
     
    11291091  // - For MEMC_CMD_TYPE, the response is delayed until the operation is completed.
    11301092  ////////////////////////////////////////////////////////////////////////////////////
     1093
     1094//std::cout << std::endl << "tgt_cmd_fsm" << std::endl;
    11311095
    11321096  switch(r_tgt_cmd_fsm.read())
     
    12321196    case TGT_CMD_ERROR:  // response error must be sent
    12331197
    1234     // wait if pending TGT_CMD request to TGT_RSP FSM
     1198    // wait if pending request
    12351199    if(r_tgt_cmd_to_tgt_rsp_req.read()) break;
    12361200
     
    12661230        size_t   error; 
    12671231        uint32_t rdata = 0;         // default value
     1232        uint32_t wdata = p_vci_tgt.wdata.read();
    12681233
    12691234        if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_READ)         // get lock
     
    12741239            error            = 0;
    12751240            r_config_lock    = true;
     1241            if ( rdata == 0 )
     1242            {
     1243                r_tgt_cmd_srcid = p_vci_tgt.srcid.read();
     1244                r_tgt_cmd_trdid = p_vci_tgt.trdid.read();
     1245                r_tgt_cmd_pktid = p_vci_tgt.pktid.read();
     1246            }
    12761247        }
    12771248        else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)  // release lock
    1278                    and (cell == MEMC_LOCK) )
     1249                   and (cell == MEMC_LOCK)
     1250                   and (p_vci_tgt.srcid.read() == r_tgt_cmd_srcid.read()) )
    12791251        {
    12801252            need_rsp         = true;
     
    12831255        }
    12841256        else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set addr_lo
    1285                    and (cell == MEMC_ADDR_LO) )
    1286         {
     1257                   and (cell == MEMC_ADDR_LO)
     1258                   and (p_vci_tgt.srcid.read() == r_tgt_cmd_srcid.read()) )
     1259        {
     1260            assert( ((wdata % (m_words*vci_param_int::B)) == 0) and
     1261            "VCI_MEM_CACHE CONFIG ERROR: The buffer must be aligned on a cache line");
     1262
    12871263            need_rsp         = true;
    12881264            error            = 0;
     
    12911267        }
    12921268        else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set addr_hi
    1293                    and (cell == MEMC_ADDR_HI) )
     1269                   and (cell == MEMC_ADDR_HI)
     1270                   and (p_vci_tgt.srcid.read() == r_tgt_cmd_srcid.read()) )
     1271
    12941272        {
    12951273            need_rsp         = true;
     
    12991277        }
    13001278        else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set buf_lines
    1301                    and (cell == MEMC_BUF_LENGTH) )
     1279                   and (cell == MEMC_BUF_LENGTH)
     1280                   and (p_vci_tgt.srcid.read() == r_tgt_cmd_srcid.read()) )
    13021281        {
    13031282            need_rsp         = true;
    13041283            error            = 0;
    13051284            size_t lines = (size_t)(p_vci_tgt.wdata.read()/(m_words<<2));
    1306             if ( r_config_address.read()/(m_words*vci_param_int::B) ) lines++;
    1307             r_config_nlines  = lines;
     1285            if ( r_config_address.read()%(m_words*4) ) lines++;
     1286            r_config_cmd_lines  = lines;
     1287            r_config_rsp_lines  = lines;
    13081288        }
    13091289        else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set cmd type
    1310                    and (cell == MEMC_CMD_TYPE) )
     1290                   and (cell == MEMC_CMD_TYPE)
     1291                   and (p_vci_tgt.srcid.read() == r_tgt_cmd_srcid.read()) )
    13111292        {
    13121293            need_rsp         = false;
    13131294            error            = 0;
    13141295            r_config_cmd     = p_vci_tgt.wdata.read();
     1296
     1297            // prepare delayed response from CONFIG FSM
    13151298            r_config_srcid   = p_vci_tgt.srcid.read();
    13161299            r_config_trdid   = p_vci_tgt.trdid.read();
     
    13431326          << " address = " << std::hex << p_vci_tgt.address.read()
    13441327          << " / wdata = " << p_vci_tgt.wdata.read()
     1328          << " / need_rsp = " << need_rsp
    13451329          << " / error = " << error << std::endl;
    13461330#endif
     
    14461430  //    MULTI_ACK FSM
    14471431  /////////////////////////////////////////////////////////////////////////
    1448   // This FSM controls the response to the multicast update or multicast
    1449   // inval coherence requests sent by the memory cache to the L1 caches and
    1450   // update the UPT.
     1432  // This FSM controls the response to the multicast update requests sent
     1433  // by the memory cache to the L1 caches and update the UPT.
    14511434  //
    14521435  // - The FSM decrements the proper entry in UPT,
     
    14541437  // - If required, it sends a request to the TGT_RSP FSM to complete
    14551438  //   a pending  write transaction.
    1456   // - If required, it sends an acknowledge to the CONFIG FSM to signal
    1457   //   completion of a line inval.
    14581439  //
    14591440  // All those multi-ack packets are one flit packet.
    1460   // The index in the UPT is defined in the UPDTID field.
     1441  // The index in the UPT is defined in the TRDID field.
    14611442  ////////////////////////////////////////////////////////////////////////
     1443
     1444//std::cout << std::endl << "multi_ack_fsm" << std::endl;
    14621445
    14631446  switch(r_multi_ack_fsm.read())
     
    15741557        r_multi_ack_nline = m_upt.nline(r_multi_ack_upt_index.read());
    15751558        bool need_rsp     = m_upt.need_rsp(r_multi_ack_upt_index.read());
    1576         bool need_ack     = m_upt.need_ack(r_multi_ack_upt_index.read());
    15771559
    15781560        // clear the UPT entry
     
    15801562
    15811563        if      ( need_rsp ) r_multi_ack_fsm = MULTI_ACK_WRITE_RSP;
    1582         else if ( need_ack ) r_multi_ack_fsm = MULTI_ACK_CONFIG_ACK;
    15831564        else                 r_multi_ack_fsm = MULTI_ACK_IDLE;
    15841565
     
    16111592        break;
    16121593    }
    1613     //////////////////////////
    1614     case MULTI_ACK_CONFIG_ACK:    // Signals multi-inval completion to CONFIG FSM
    1615                                   // Wait if pending request
    1616     {
    1617         if ( r_multi_ack_to_config_ack.read() ) break;
    1618 
    1619         r_multi_ack_to_config_ack   = true;
    1620         r_multi_ack_fsm              = MULTI_ACK_IDLE;
    1621 
    1622 #if DEBUG_MEMC_MULTI_ACK
    1623 if(m_debug)
    1624 std::cout << "  <MEMC " << name() << " MULTI_ACK_CONFIG_ACK>"
    1625           << " Signals inval completion to CONFIG FSM" << std::endl;
    1626 #endif
    1627         break;
    1628     }
    16291594  } // end switch r_multi_ack_fsm
    16301595
     
    16341599  // The CONFIG FSM handles the VCI configuration requests (INVAL & SYNC).
    16351600  // The target buffer can have any size, and there is one single command for
    1636   // all cache lines covered by the target buffer.
    1637   // An INVAL or SYNC configuration request is defined by the followinf registers:
    1638   // - bool      r_config_cmd        : INVAL / SYNC / NOP)
     1601  // all cache lines covered by the target buffer.
     1602  //
     1603  // An INVAL or SYNC configuration operation is defined by the following registers:
     1604  // - bool      r_config_cmd        : INVAL / SYNC / NOP
    16391605  // - uint64_t  r_config_address    : buffer base address
    1640   // - uint32_t  r_config_nlines     : number of lines covering buffer
     1606  // - uint32_t  r_config_cmd_lines  : number of lines to be handled
     1607  // - uint32_t  r_config_rsp_lines  : number of lines not completed
    16411608  //
    16421609  // For both INVAL and SYNC commands, the CONFIG FSM contains the loop handling
    1643   // all cache lines covered by the target buffer.
    1644   //
     1610  // all cache lines covered by the buffer. The various lines of a given buffer
     1611  // can be pipelined: the CONFIG FSM does not wait the response for line (n) to send
     1612  // the command for line (n+1). It decrements the r_config_cmd_lines counter until
     1613  // the last request has been registered in TRT (for a SYNC), or in IVT (for an INVAL).
     1614  //
    16451615  // - INVAL request:
    1646   //   For each line, it access to the DIR array.
     1616  //   For each line, it access to the DIR.
    16471617  //   In case of miss, it does nothing, and a response is requested to TGT_RSP FSM.
    16481618  //   In case of hit, with no copies in L1 caches, the line is invalidated and
    16491619  //   a response is requested to TGT_RSP FSM.
    16501620  //   If there is copies, a multi-inval, or a broadcast-inval coherence transaction
    1651   //   is launched and registered in UPT. The multi-inval transaction is signaled
    1652   //   by the r_multi_ack_to config_ack or r_cleanup_to_config_ack flip-flops.
    1653   //   The config inval response is sent only when the last line has been invalidated.
    1654   //
     1621  //   is launched and registered in UPT. The multi-inval transaction completion
     1622  //   is signaled by the CLEANUP FSM by decrementing the r_config_rsp_lines counter.
     1623  //   The CONFIG INVAL response is sent only when the last line has been invalidated.
     1624  //   TODO : The target buffer address must be aligned on a cache line boundary.
     1625  //   This constraint can be released, but it requires to make 2 PUT transactions
     1626  //   for the first and the last line...
     1627  //
    16551628  // - SYNC request:
    1656   //
    1657   //  ...  Not implemented yet ...
     1629  //   For each line, it access to the DIR.
     1630  //   In case of miss, it does nothing, and a response is requested to TGT_RSP FSM.
     1631  //   In case of hit, a PUT transaction is registered in TRT and a request is sent
     1632  //   to IXR_CMD FSM. The IXR_RSP FSM decrements the r_config_rsp_lines counter
     1633  //   when a PUT response is received.
     1634  //   The CONFIG SYNC response is sent only when the last PUT response is received.
    16581635  //
    16591636  // From the software point of view, a configuration request is a sequence
    1660   // of 6 atomic accesses in an uncached segment:
     1637  // of 6 atomic accesses in an uncached segment. A dedicated lock is used
     1638  // to handle only one configuration command at a given time:
    16611639  // - Read  MEMC_LOCK       : Get the lock
    16621640  // - Write MEMC_ADDR_LO    : Set the buffer address LSB
     
    16671645  ////////////////////////////////////////////////////////////////////////////////////
    16681646
     1647//std::cout << std::endl << "config_fsm" << std::endl;
     1648
    16691649  switch( r_config_fsm.read() )
    16701650  {
     
    16791659if(m_debug)
    16801660std::cout << "  <MEMC " << name() << " CONFIG_IDLE> Config Request received"
    1681           << " address = " << std::hex << r_config_address.read()
    1682           << " / nlines = " << std::dec << r_config_nlines.read()
     1661          << " / address = " << std::hex << r_config_address.read()
     1662          << " / lines = " << std::dec << r_config_cmd_lines.read()
    16831663          << " / type = " << r_config_cmd.read() << std::endl;
    16841664#endif
     
    16871667      }
    16881668      /////////////////
    1689       case CONFIG_LOOP:   // test last line
    1690       {
    1691           if ( r_config_nlines.read() == 0 )
     1669      case CONFIG_LOOP:   // test if last line to be handled
     1670      {
     1671          if ( r_config_cmd_lines.read() == 0 )
    16921672          {
    16931673              r_config_cmd = MEMC_CMD_NOP;
    1694               r_config_fsm = CONFIG_RSP;
     1674              r_config_fsm = CONFIG_WAIT;
    16951675          }
    16961676          else
     
    17021682if(m_debug)
    17031683std::cout << "  <MEMC " << name() << " CONFIG_LOOP>"
    1704           << " address = " << std::hex << r_config_address.read()   
    1705           << " / nlines = " << std::dec << r_config_nlines.read()
     1684          << " / address = " << std::hex << r_config_address.read()   
     1685          << " / lines not handled = " << std::dec << r_config_cmd_lines.read()
    17061686          << " / command = " << r_config_cmd.read() << std::endl;
    17071687#endif
    17081688          break;
     1689      }
     1690      /////////////////
     1691      case CONFIG_WAIT:   // wait completion (last response)
     1692      {
     1693          if ( r_config_rsp_lines.read() == 0 )  // last response received
     1694          {
     1695              r_config_fsm = CONFIG_RSP;
     1696          }
     1697
     1698#if DEBUG_MEMC_CONFIG
     1699if(m_debug)
     1700std::cout << "  <MEMC " << name() << " CONFIG_WAIT>"
     1701          << " / lines to do = " << std::dec << r_config_rsp_lines.read() << std::endl;
     1702#endif
     1703          break;
     1704      }
     1705      ////////////////
     1706      case CONFIG_RSP:  // request TGT_RSP FSM to return response
     1707      {
     1708          if ( not r_config_to_tgt_rsp_req.read() )
     1709          {
     1710              r_config_to_tgt_rsp_srcid  = r_config_srcid.read();
     1711              r_config_to_tgt_rsp_trdid  = r_config_trdid.read();
     1712              r_config_to_tgt_rsp_pktid  = r_config_pktid.read();
     1713              r_config_to_tgt_rsp_error  = false;
     1714              r_config_to_tgt_rsp_req    = true;
     1715              r_config_fsm               = CONFIG_IDLE;
     1716
     1717#if DEBUG_MEMC_CONFIG
     1718if(m_debug)
     1719std::cout << "  <MEMC " << name() << " CONFIG_RSP> Request TGT_RSP FSM to return response:"
     1720          << " error = " << r_config_to_tgt_rsp_error.read()
     1721          << " / rsrcid = " << std::hex << r_config_srcid.read()
     1722          << " / rtrdid = " << std::hex << r_config_trdid.read()
     1723          << " / rpktid = " << std::hex << r_config_pktid.read() << std::endl;
     1724#endif
     1725          }
     1726          break;
     1727
    17091728      }
    17101729      ////////////////////
     
    17261745      case CONFIG_DIR_ACCESS:   // Access directory and decode config command
    17271746      {
     1747          assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
     1748          "MEMC ERROR in CONFIG_DIR_ACCESS state: bad DIR allocation");
     1749
    17281750          size_t way = 0;
    17291751          DirectoryEntry entry = m_cache_directory.read(r_config_address.read(), way);
     
    17361758              r_config_dir_copy_srcid = entry.owner.srcid;
    17371759              r_config_dir_is_cnt     = entry.is_cnt;
     1760              r_config_dir_lock       = entry.lock;
    17381761              r_config_dir_count      = entry.count;
    1739               r_config_dir_next_ptr   = entry.ptr;
    1740 
    1741               r_config_fsm    = CONFIG_DIR_IVT_LOCK;
     1762              r_config_dir_ptr        = entry.ptr;
     1763
     1764              r_config_fsm    = CONFIG_IVT_LOCK;
    17421765          }
    17431766          else if ( entry.valid and                       // hit & sync command
     
    17451768                    (r_config_cmd.read() == MEMC_CMD_SYNC) )
    17461769          {
    1747               std::cout << "VCI_MEM_CACHE ERROR: "
    1748                         << "SYNC config request not implemented yet" << std::endl;
    1749               exit(0);
     1770              r_config_fsm  = CONFIG_TRT_LOCK;
    17501771          }
    1751           else                                            // return to LOOP
     1772          else                                            // miss : return to LOOP
    17521773          {
    1753               r_config_nlines  = r_config_nlines.read() - 1;
    1754               r_config_address = r_config_address.read() + (m_words<<2);
    1755               r_config_fsm     = CONFIG_LOOP;
     1774              r_config_cmd_lines = r_config_cmd_lines.read() - 1;
     1775              r_config_rsp_lines = r_config_rsp_lines.read() - 1;
     1776              r_config_cmd_lines = r_config_cmd_lines.read() - 1;
     1777              r_config_address   = r_config_address.read() + (m_words<<2);
     1778              r_config_fsm       = CONFIG_LOOP;
    17561779          }
    17571780
     
    17671790          break;
    17681791      }
    1769       /////////////////////////
    1770       case CONFIG_DIR_IVT_LOCK:  // enter this state in case of INVAL command
    1771                                  // Try to get both DIR & IVT locks, and return
    1772                                  // to LOOP state if IVT full.
    1773                                  // Register inval in IVT, and invalidate the
    1774                                  // directory if IVT not full.
    1775       {
     1792      /////////////////////
     1793      case CONFIG_TRT_LOCK:      // enter this state in case of SYNC command
     1794                                 // to a dirty cache line
     1795                                 // keep DIR lock, and try to get TRT lock
     1796                                 // return to LOOP state if TRT full
     1797                                 // reset dirty bit in DIR and register a PUT
     1798                                 // trabsaction in TRT if not full.
     1799      {
     1800          assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
     1801          "MEMC ERROR in CONFIG_TRT_LOCK state: bad DIR allocation");
     1802
     1803          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG )
     1804          {
     1805              size_t index = 0;
     1806              bool   wok   = not m_trt.full(index);
     1807
     1808              if ( not wok )
     1809              {
     1810                  r_config_fsm = CONFIG_LOOP;
     1811              }
     1812              else
     1813              {
     1814                  size_t          way = r_config_dir_way.read();
     1815                  size_t          set = m_y[r_config_address.read()];
     1816
     1817                  // reset dirty bit in DIR
     1818                  DirectoryEntry  entry;
     1819                  entry.valid       = true;
     1820                  entry.dirty       = false;
     1821                  entry.tag         = m_z[r_config_address.read()];
     1822                  entry.is_cnt      = r_config_dir_is_cnt.read();
     1823                  entry.lock        = r_config_dir_lock.read();
     1824                  entry.ptr         = r_config_dir_ptr.read();
     1825                  entry.count       = r_config_dir_count.read();
     1826                  entry.owner.inst  = r_config_dir_copy_inst.read();
     1827                  entry.owner.srcid = r_config_dir_copy_srcid.read();
     1828                  m_cache_directory.write( set,
     1829                                           way,
     1830                                           entry );
     1831
     1832                  r_config_trt_index = index;
     1833                  r_config_fsm       = CONFIG_TRT_SET;
     1834              }
     1835
     1836#if DEBUG_MEMC_CONFIG
     1837if(m_debug)
     1838std::cout << "  <MEMC " << name() << " CONFIG_TRT_LOCK> Access TRT: "
     1839          << " wok = " << std::dec << wok
     1840          << " index = " << index << std::endl;
     1841#endif
     1842          }
     1843          break;
     1844      }
     1845      ////////////////////
     1846      case CONFIG_TRT_SET:       // read data in cache
     1847                                 // and post a PUT request in TRT
     1848      {
     1849          assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
     1850          "MEMC ERROR in CONFIG_TRT_SET state: bad DIR allocation");
     1851
     1852          assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG) and
     1853          "MEMC ERROR in CONFIG_TRT_SET state: bad TRT allocation");
     1854
     1855          // read data into cache
     1856          size_t          way = r_config_dir_way.read();
     1857          size_t          set = m_y[r_config_address.read()];
     1858
     1859          sc_signal<data_t> config_data[16];
     1860          m_cache_data.read_line( way,
     1861                                  set,
     1862                                  config_data );
     1863           
     1864          // post a PUT request in TRT
     1865          std::vector<data_t> data_vector;
     1866          data_vector.clear();
     1867          for(size_t i=0; i<m_words; i++) data_vector.push_back(config_data[i].read());
     1868          m_trt.set( r_config_trt_index.read(),
     1869                     false,                               // PUT
     1870                     m_nline[r_config_address.read()],    // nline
     1871                     0,                                   // srcid:       unused
     1872                     0,                                   // trdid:       unused
     1873                     0,                                   // pktid:       unused
     1874                     false,                               // not proc_read
     1875                     0,                                   // read_length: unused
     1876                     0,                                   // word_index:  unused
     1877                     std::vector<be_t>(m_words,0xF),                         
     1878                     data_vector);
     1879
     1880#if DEBUG_MEMC_CONFIG
     1881if(m_debug)
     1882std::cout << "  <MEMC " << name() << " CONFIG_TRT_SET> PUT request in TRT:"
     1883          << " address = " << std::hex << r_config_address.read()
     1884          << " index = " << std::dec << r_config_trt_index.read() << std::endl;
     1885#endif
     1886          break;
     1887      }
     1888      ////////////////////
     1889      case CONFIG_PUT_REQ:       // PUT request to IXR_CMD_FSM
     1890      {
     1891          if ( not r_config_to_ixr_cmd_req.read() )
     1892          {
     1893              r_config_to_ixr_cmd_req   = true;
     1894              r_config_to_ixr_cmd_index = r_config_trt_index.read();
     1895
     1896              // prepare next iteration
     1897              r_config_cmd_lines              = r_config_cmd_lines.read() - 1;
     1898              r_config_address                = r_config_address.read() + (m_words<<2);
     1899              r_config_fsm                    = CONFIG_LOOP;
     1900
     1901#if DEBUG_MEMC_CONFIG
     1902if(m_debug)
     1903std::cout << "  <MEMC " << name() << " CONFIG_PUT_REQ> PUT request to IXR_CMD_FSM"
     1904          << " / address = " << std::hex << r_config_address.read() << std::endl;
     1905#endif
     1906          }
     1907          break;
     1908      }
     1909      /////////////////////
     1910      case CONFIG_IVT_LOCK:  // enter this state in case of INVAL command
     1911                             // Keep DIR lock and Try to get IVT lock.
     1912                             // Return to LOOP state if IVT full.
     1913                             // Register inval in IVT, and invalidate the
     1914                             // directory if IVT not full.
     1915      {
     1916          assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
     1917          "MEMC ERROR in CONFIG_IVT_LOCK state: bad DIR allocation");
     1918
    17761919          if ( r_alloc_ivt_fsm.read() == ALLOC_IVT_CONFIG )
    17771920          {
     
    17821925              {
    17831926                  m_cache_directory.inval( way, set );
    1784                   r_config_nlines  = r_config_nlines.read() - 1;
    1785                   r_config_address = r_config_address.read() + (m_words<<2);
    1786                   r_config_fsm     = CONFIG_LOOP;
     1927                  r_config_cmd_lines  = r_config_cmd_lines.read() - 1;
     1928                  r_config_rsp_lines  = r_config_rsp_lines.read() - 1;
     1929                  r_config_address    = r_config_address.read() + (m_words<<2);
     1930                  r_config_fsm        = CONFIG_LOOP;
    17871931
    17881932#if DEBUG_MEMC_CONFIG
    17891933if(m_debug)
    1790 std::cout << "  <MEMC " << name() << " CONFIG_DIR_IVT_LOCK>"
     1934std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
    17911935          << " No copies in L1 : inval DIR entry"  << std::endl;
    17921936#endif
     
    18191963                      r_config_ivt_index = index;
    18201964                      if ( broadcast )  r_config_fsm = CONFIG_BC_SEND;
    1821                       else              r_config_fsm = CONFIG_INV_SEND;
     1965                      else              r_config_fsm = CONFIG_INVAL_SEND;
    18221966
    18231967#if DEBUG_MEMC_CONFIG
    18241968if(m_debug)
    1825 std::cout << "  <MEMC " << name() << " CONFIG_DIR_IVT_LOCK>"
     1969std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
    18261970          << " Inval DIR entry and register inval in IVT"
    1827           << " : index = " << std::dec << index
     1971          << " / index = " << std::dec << index
    18281972          << " / broadcast = " << broadcast << std::endl;
    18291973#endif
     
    18351979#if DEBUG_MEMC_CONFIG
    18361980if(m_debug)
    1837 std::cout << "  <MEMC " << name() << " CONFIG_DIR_IVT_LOCK>"
     1981std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
    18381982          << " IVT full : release DIR & IVT locks and retry" << std::endl;
    18391983#endif
     
    18491993              not r_config_to_cc_send_brdcast_req.read() )
    18501994          {
     1995              // post bc inval request
    18511996              r_config_to_cc_send_multi_req   = false;
    18521997              r_config_to_cc_send_brdcast_req = true;
    18531998              r_config_to_cc_send_trdid       = r_config_ivt_index.read();
    18541999              r_config_to_cc_send_nline       = m_nline[(addr_t)(r_config_address.read())];
    1855               r_cleanup_to_config_ack         = false;
    1856               r_config_fsm                    = CONFIG_BC_WAIT;
     2000
     2001              // prepare next iteration
     2002              r_config_cmd_lines              = r_config_cmd_lines.read() - 1;
     2003              r_config_address                = r_config_address.read() + (m_words<<2);
     2004              r_config_fsm                    = CONFIG_LOOP;
    18572005
    18582006#if DEBUG_MEMC_CONFIG
     
    18652013          break;
    18662014      }
    1867       ////////////////////
    1868       case CONFIG_BC_WAIT:      // wait broadcast completion to return to LOOP
    1869       {
    1870           if ( r_cleanup_to_config_ack.read() )
    1871           {
    1872               r_config_fsm     = CONFIG_LOOP;
    1873               r_config_nlines  = r_config_nlines.read() - 1;
    1874               r_config_address = r_config_address.read() + (m_words<<2);
    1875           }
    1876 
    1877 #if DEBUG_MEMC_CONFIG
    1878 if(m_debug)
    1879 std::cout << "  <MEMC " << name() << " CONFIG_BC_WAIT> Waiting BC completion "
    1880           << " done = " << r_cleanup_to_config_ack.read()
    1881           << std::endl;
    1882 #endif
    1883           break;
    1884       }
    1885       /////////////////////
    1886       case CONFIG_INV_SEND:    // Post a multi inval request to CC_SEND FSM
     2015      ///////////////////////
     2016      case CONFIG_INVAL_SEND:    // Post a multi inval request to CC_SEND FSM
    18872017      {
    18882018          if( not r_config_to_cc_send_multi_req.read() and
    18892019              not r_config_to_cc_send_brdcast_req.read() )
    18902020          {
     2021              // post multi inval request
    18912022              r_config_to_cc_send_multi_req   = true;
    18922023              r_config_to_cc_send_brdcast_req = false;
    18932024              r_config_to_cc_send_trdid       = r_config_ivt_index.read();
    18942025              r_config_to_cc_send_nline       = m_nline[(addr_t)(r_config_address.read())];
    1895               r_multi_ack_to_config_ack       = false;
    1896 
     2026
     2027              // post data into FIFO
    18972028              config_to_cc_send_fifo_srcid    = r_config_dir_copy_srcid.read();
    18982029              config_to_cc_send_fifo_inst     = r_config_dir_copy_inst.read();
    18992030              config_to_cc_send_fifo_put      = true;
    19002031
    1901               if ( r_config_dir_count.read() == 1 )  r_config_fsm = CONFIG_INV_WAIT;
    1902               else                                   r_config_fsm = CONFIG_HEAP_REQ;
     2032              if ( r_config_dir_count.read() == 1 )  // one copy
     2033              {
     2034                  // prepare next iteration
     2035                  r_config_cmd_lines          = r_config_cmd_lines.read() - 1;
     2036                  r_config_address            = r_config_address.read() + (m_words<<2);
     2037                  r_config_fsm                = CONFIG_LOOP;
     2038              }
     2039              else                                   // several copies
     2040              {
     2041                  r_config_fsm = CONFIG_HEAP_REQ;
     2042              }
    19032043
    19042044#if DEBUG_MEMC_CONFIG
    19052045if(m_debug)
    1906 std::cout << "  <MEMC " << name() << " CONFIG_INV_SEND>"
     2046std::cout << "  <MEMC " << name() << " CONFIG_INVAL_SEND>"
    19072047          << " Post multi inval request to CC_SEND FSM"
    19082048          << " / address = " << std::hex << r_config_address.read()
     
    19192059          {
    19202060              r_config_fsm       = CONFIG_HEAP_SCAN;
    1921               r_config_heap_next = r_config_dir_next_ptr.read();
     2061              r_config_heap_next = r_config_dir_ptr.read();
    19222062          }
    19232063
     
    19662106          if ( m_heap.is_full() )
    19672107          {
    1968               last_entry.next = r_config_dir_next_ptr.read();
     2108              last_entry.next = r_config_dir_ptr.read();
    19692109              m_heap.unset_full();
    19702110          }
     
    19742114          }
    19752115
    1976           m_heap.write_free_ptr( r_config_dir_next_ptr.read() );
     2116          m_heap.write_free_ptr( r_config_dir_ptr.read() );
    19772117          m_heap.write( r_config_heap_next.read(), last_entry );
    1978           r_config_fsm = CONFIG_INV_WAIT;
     2118
     2119          // prepare next iteration
     2120          r_config_cmd_lines          = r_config_cmd_lines.read() - 1;
     2121          r_config_address            = r_config_address.read() + (m_words<<2);
     2122          r_config_fsm                = CONFIG_LOOP;
    19792123
    19802124#if DEBUG_MEMC_CONFIG
     
    19842128#endif
    19852129          break;
    1986       }
    1987       /////////////////////
    1988       case CONFIG_INV_WAIT:      // wait inval completion to return to LOOP
    1989       {
    1990           if ( r_multi_ack_to_config_ack.read() )
    1991           {
    1992               r_config_fsm     = CONFIG_LOOP;
    1993               r_config_nlines  = r_config_nlines.read() - 1;
    1994               r_config_address = r_config_address.read() + (m_words<<2);
    1995           }
    1996 
    1997 #if DEBUG_MEMC_CONFIG
    1998 if(m_debug)
    1999 std::cout << "  <MEMC " << name() << " CONFIG_INV_WAIT> Waiting inval completion "
    2000           << " done = " << r_multi_ack_to_config_ack.read()
    2001           << std::endl;
    2002 #endif
    2003           break;
    2004       }
    2005 
    2006       ////////////////
    2007       case CONFIG_RSP:  // request TGT_RSP FSM to return response
    2008       {
    2009           if ( not r_config_to_tgt_rsp_req.read() )
    2010           {
    2011               r_config_to_tgt_rsp_srcid  = r_config_srcid.read();
    2012               r_config_to_tgt_rsp_trdid  = r_config_trdid.read();
    2013               r_config_to_tgt_rsp_pktid  = r_config_pktid.read();
    2014               r_config_to_tgt_rsp_error  = false;
    2015               r_config_to_tgt_rsp_req    = true;
    2016               r_config_fsm               = CONFIG_IDLE;
    2017 
    2018 #if DEBUG_MEMC_CONFIG
    2019 if(m_debug)
    2020 std::cout << "  <MEMC " << name() << " CONFIG_RSP> Request TGT_RSP FSM to return response:"
    2021           << " error = " << r_config_to_tgt_rsp_error.read()
    2022           << " / rsrcid = " << std::hex << r_config_srcid.read() << std::endl;
    2023 #endif
    2024           }
    2025           break;
    2026 
    20272130      }
    20282131  }  // end switch r_config_fsm
     
    20512154  ////////////////////////////////////////////////////////////////////////////////////
    20522155
     2156//std::cout << std::endl << "read_fsm" << std::endl;
     2157
    20532158  switch(r_read_fsm.read())
    20542159  {
     
    20562161    case READ_IDLE:  // waiting a read request
    20572162    {
    2058       if(m_cmd_read_addr_fifo.rok())
    2059       {
     2163        if(m_cmd_read_addr_fifo.rok())
     2164        {
    20602165
    20612166#if DEBUG_MEMC_READ
    2062         if(m_debug)
    2063           std::cout << "  <MEMC " << name() << " READ_IDLE> Read request"
    2064             << " : address = " << std::hex << m_cmd_read_addr_fifo.read()
    2065             << " / srcid = " << m_cmd_read_srcid_fifo.read()
    2066             << " / trdid = " << m_cmd_read_trdid_fifo.read()
    2067             << " / pktid = " << m_cmd_read_pktid_fifo.read()
    2068             << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
    2069 #endif
    2070         r_read_fsm = READ_DIR_REQ;
    2071       }
    2072       break;
    2073     }
    2074 
     2167if(m_debug)
     2168std::cout << "  <MEMC " << name() << " READ_IDLE> Read request"
     2169          << " : address = " << std::hex << m_cmd_read_addr_fifo.read()
     2170          << " / srcid = " << m_cmd_read_srcid_fifo.read()
     2171          << " / trdid = " << m_cmd_read_trdid_fifo.read()
     2172          << " / pktid = " << m_cmd_read_pktid_fifo.read()
     2173          << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
     2174#endif
     2175            r_read_fsm = READ_DIR_REQ;
     2176        }
     2177        break;
     2178    }
    20752179    //////////////////
    20762180    case READ_DIR_REQ:  // Get the lock to the directory
     
    20952199    case READ_DIR_LOCK:  // check directory for hit / miss
    20962200    {
    2097       if(r_alloc_dir_fsm.read() == ALLOC_DIR_READ)
    2098       {
     2201        assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_READ) and
     2202        "MEMC ERROR in READ_DIR_LOCK state: Bad DIR allocation");
     2203
    20992204        size_t way = 0;
    2100         DirectoryEntry entry =
    2101           m_cache_directory.read(m_cmd_read_addr_fifo.read(), way);
     2205        DirectoryEntry entry = m_cache_directory.read(m_cmd_read_addr_fifo.read(), way);
     2206
    21022207        // access the global table ONLY when we have an LL cmd
    21032208        if((m_cmd_read_pktid_fifo.read() & 0x7) == TYPE_LL)   
    21042209        {
    2105           r_read_ll_key   = m_llsc_table.ll(m_cmd_read_addr_fifo.read());
     2210            r_read_ll_key   = m_llsc_table.ll(m_cmd_read_addr_fifo.read());
    21062211        }
    21072212        r_read_is_cnt     = entry.is_cnt;
     
    21122217        r_read_count      = entry.count;
    21132218        r_read_copy       = entry.owner.srcid;
    2114 
    2115 #if L1_MULTI_CACHE
    2116         r_read_copy_cache = entry.owner.cache_id;
    2117 #endif
    21182219        r_read_copy_inst  = entry.owner.inst;
    21192220        r_read_ptr        = entry.ptr; // pointer to the heap
     
    21252226        if(entry.valid)    // hit
    21262227        {
    2127           // test if we need to register a new copy in the heap
    2128           if(entry.is_cnt or (entry.count == 0) or !cached_read)
    2129           {
    2130             r_read_fsm = READ_DIR_HIT;
    2131           }
    2132           else
    2133           {
    2134             r_read_fsm = READ_HEAP_REQ;
    2135           }
     2228            // test if we need to register a new copy in the heap
     2229            if(entry.is_cnt or (entry.count == 0) or !cached_read)
     2230            {
     2231                r_read_fsm = READ_DIR_HIT;
     2232            }
     2233            else
     2234            {
     2235                r_read_fsm = READ_HEAP_REQ;
     2236            }
    21362237        }
    21372238        else      // miss
    21382239        {
    2139           r_read_fsm = READ_TRT_LOCK;
     2240            r_read_fsm = READ_TRT_LOCK;
    21402241        }
    21412242
     
    21522253}
    21532254#endif
    2154       }
    2155       else
    2156       {
    2157         std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_DIR_LOCK state"
    2158                   << "Bad DIR allocation"   << std::endl;
    2159         exit(0);
    2160       }
    2161       break;
    2162     }
    2163 
     2255        break;
     2256    }
    21642257    //////////////////
    21652258    case READ_DIR_HIT:    //  read data in cache & update the directory
     
    21702263
    21712264    {
    2172       if(r_alloc_dir_fsm.read() == ALLOC_DIR_READ)
    2173       {
     2265        assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_READ) and
     2266        "MEMC ERROR in READ_DIR_HIT state: Bad DIR allocation");
     2267
    21742268        // check if this is an instruction read, this means pktid is either
    21752269        // TYPE_READ_INS_UNC   0bX010 with TSAR encoding
     
    21882282        m_cache_data.read_line(way, set, r_read_data);
    21892283
    2190         if(m_monitor_ok) check_monitor( m_cmd_read_addr_fifo.read(), r_read_data[0], true);
    2191 
    21922284        // update the cache directory
    21932285        DirectoryEntry entry;
     
    22092301        if(cached_read)   // Cached read => we must update the copies
    22102302        {
    2211           if(!is_cnt)  // Not counter mode
    2212           {
    2213             entry.owner.srcid    = m_cmd_read_srcid_fifo.read();
    2214 #if L1_MULTI_CACHE
    2215             entry.owner.cache_id = m_cmd_read_pktid_fifo.read();
    2216 #endif
    2217             entry.owner.inst     = inst_read;
    2218             entry.count          = r_read_count.read() + 1;
    2219           }
    2220           else  // Counter mode
    2221           {
    2222             entry.owner.srcid    = 0;
    2223 #if L1_MULTI_CACHE
    2224             entry.owner.cache_id = 0;
    2225 #endif
    2226             entry.owner.inst     = false;
    2227             entry.count          = r_read_count.read() + 1;
    2228           }
     2303            if(!is_cnt)  // Not counter mode
     2304            {
     2305                entry.owner.srcid    = m_cmd_read_srcid_fifo.read();
     2306                entry.owner.inst     = inst_read;
     2307                entry.count          = r_read_count.read() + 1;
     2308            }
     2309            else  // Counter mode
     2310            {
     2311                entry.owner.srcid    = 0;
     2312                entry.owner.inst     = false;
     2313                entry.count          = r_read_count.read() + 1;
     2314            }
    22292315        }
    22302316        else            // Uncached read
    22312317        {
    2232           entry.owner.srcid     = r_read_copy.read();
    2233 #if L1_MULTI_CACHE
    2234           entry.owner.cache_id  = r_read_copy_cache.read();
    2235 #endif
    2236           entry.owner.inst      = r_read_copy_inst.read();
    2237           entry.count           = r_read_count.read();
     2318            entry.owner.srcid     = r_read_copy.read();
     2319            entry.owner.inst      = r_read_copy_inst.read();
     2320            entry.count           = r_read_count.read();
    22382321        }
    22392322
    22402323#if DEBUG_MEMC_READ
    2241         if(m_debug)
    2242           std::cout << "  <MEMC " << name() << " READ_DIR_HIT> Update directory entry:"
    2243             << " addr = " << std::hex << m_cmd_read_addr_fifo.read()
    2244             << " / set = " << std::dec << set
    2245             << " / way = " << way
    2246             << " / owner_id = " << std::hex << entry.owner.srcid
    2247             << " / owner_ins = " << std::dec << entry.owner.inst
    2248             << " / count = " << entry.count
    2249             << " / is_cnt = " << entry.is_cnt << std::endl;
    2250 #endif
    2251 
    2252           if(m_monitor_ok)
     2324if(m_debug)
     2325std::cout << "  <MEMC " << name() << " READ_DIR_HIT> Update directory entry:"
     2326          << " addr = " << std::hex << m_cmd_read_addr_fifo.read()
     2327          << " / set = " << std::dec << set
     2328          << " / way = " << way
     2329          << " / owner_id = " << std::hex << entry.owner.srcid
     2330          << " / owner_ins = " << std::dec << entry.owner.inst
     2331          << " / count = " << entry.count
     2332          << " / is_cnt = " << entry.is_cnt << std::endl;
     2333#endif
     2334          /*if(m_monitor_ok)
    22532335          {
    22542336            char buf[80];
     
    22572339                     (int)((m_cmd_read_pktid_fifo.read()&0x2)!=0));
    22582340            check_monitor(m_cmd_read_addr_fifo.read(), r_read_data[0], true);
    2259           }
     2341          }*/
    22602342        m_cache_directory.write(set, way, entry);
    22612343        r_read_fsm    = READ_RSP;
    2262       }
    2263       break;
     2344        break;
    22642345    }
    22652346    ///////////////////
     
    22972378
    22982379        m_cache_data.read_line(way, set, r_read_data);
    2299 
    2300         if(m_monitor_ok) check_monitor( m_cmd_read_addr_fifo.read(), r_read_data[0], true);
    23012380
    23022381        // update the cache directory
     
    23122391        {
    23132392          entry.owner.srcid    = r_read_copy.read();
    2314 #if L1_MULTI_CACHE
    2315           entry.owner.cache_id = r_read_copy_cache.read();
    2316 #endif
    23172393          entry.owner.inst     = r_read_copy_inst.read();
    23182394          entry.ptr            = m_heap.next_free_ptr();   // set pointer on the heap
     
    23212397        {
    23222398          entry.owner.srcid    = 0;
    2323 #if L1_MULTI_CACHE
    2324           entry.owner.cache_id = 0;
    2325 #endif
    23262399          entry.owner.inst     = false;
    23272400          entry.ptr            = 0;
     
    23892462        HeapEntry heap_entry;
    23902463        heap_entry.owner.srcid    = m_cmd_read_srcid_fifo.read();
    2391 #if L1_MULTI_CACHE
    2392         heap_entry.owner.cache_id = m_cmd_read_pktid_fifo.read();
    2393 #endif
    23942464        heap_entry.owner.inst     = ((m_cmd_read_pktid_fifo.read() & 0x2) != 0);
    23952465
     
    24552525        HeapEntry last_entry;
    24562526        last_entry.owner.srcid    = 0;
    2457 #if L1_MULTI_CACHE
    2458         last_entry.owner.cache_id = 0;
    2459 #endif
    24602527        last_entry.owner.inst     = false;
    24612528
     
    24832550    case READ_RSP:    //  request the TGT_RSP FSM to return data
    24842551    {
    2485       if(!r_read_to_tgt_rsp_req)
    2486       {
    2487         for(size_t i=0 ; i<m_words ; i++)  r_read_to_tgt_rsp_data[i] = r_read_data[i];
    2488         r_read_to_tgt_rsp_word   = m_x[(addr_t) m_cmd_read_addr_fifo.read()];
    2489         r_read_to_tgt_rsp_length = m_cmd_read_length_fifo.read();
    2490         r_read_to_tgt_rsp_srcid  = m_cmd_read_srcid_fifo.read();
    2491         r_read_to_tgt_rsp_trdid  = m_cmd_read_trdid_fifo.read();
    2492         r_read_to_tgt_rsp_pktid  = m_cmd_read_pktid_fifo.read();
    2493         r_read_to_tgt_rsp_ll_key = r_read_ll_key.read();
    2494         cmd_read_fifo_get        = true;
    2495         r_read_to_tgt_rsp_req    = true;
    2496         r_read_fsm               = READ_IDLE;
     2552        if(!r_read_to_tgt_rsp_req)
     2553        {
     2554            for(size_t i=0 ; i<m_words ; i++)  r_read_to_tgt_rsp_data[i] = r_read_data[i];
     2555            r_read_to_tgt_rsp_word   = m_x[(addr_t) m_cmd_read_addr_fifo.read()];
     2556            r_read_to_tgt_rsp_length = m_cmd_read_length_fifo.read();
     2557            r_read_to_tgt_rsp_srcid  = m_cmd_read_srcid_fifo.read();
     2558            r_read_to_tgt_rsp_trdid  = m_cmd_read_trdid_fifo.read();
     2559            r_read_to_tgt_rsp_pktid  = m_cmd_read_pktid_fifo.read();
     2560            r_read_to_tgt_rsp_ll_key = r_read_ll_key.read();
     2561            cmd_read_fifo_get        = true;
     2562            r_read_to_tgt_rsp_req    = true;
     2563            r_read_fsm               = READ_IDLE;
    24972564
    24982565#if DEBUG_MEMC_READ
     
    25032570          << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
    25042571#endif
    2505       }
    2506       break;
     2572        }
     2573        break;
    25072574    }
    25082575    ///////////////////
     
    25252592        if(hit_read or !wok or hit_write)    // missing line already requested or no space
    25262593        {
    2527           if(!wok)      m_cpt_trt_full++;
     2594          if(!wok)                    m_cpt_trt_full++;
    25282595          if(hit_read or hit_write)   m_cpt_trt_rb++;
    25292596          r_read_fsm = READ_IDLE;
     
    25512618      break;
    25522619    }
    2553 
    25542620    //////////////////
    25552621    case READ_TRT_SET:      // register get transaction in TRT
    25562622    {
    2557       if(r_alloc_trt_fsm.read() == ALLOC_TRT_READ)
    2558       {
    2559         m_trt.set(r_read_trt_index.read(),
    2560                               true,
    2561                               m_nline[(addr_t)(m_cmd_read_addr_fifo.read())],
    2562                               m_cmd_read_srcid_fifo.read(),
    2563                               m_cmd_read_trdid_fifo.read(),
    2564                               m_cmd_read_pktid_fifo.read(),
    2565                               true,
    2566                               m_cmd_read_length_fifo.read(),
    2567                               m_x[(addr_t)(m_cmd_read_addr_fifo.read())],
    2568                               std::vector<be_t> (m_words,0),
    2569                               std::vector<data_t> (m_words,0),
    2570                               r_read_ll_key.read());
     2623        if(r_alloc_trt_fsm.read() == ALLOC_TRT_READ)
     2624        {
     2625            m_trt.set( r_read_trt_index.read(),
     2626                       true,      // GET
     2627                       m_nline[(addr_t)(m_cmd_read_addr_fifo.read())],
     2628                       m_cmd_read_srcid_fifo.read(),
     2629                       m_cmd_read_trdid_fifo.read(),
     2630                       m_cmd_read_pktid_fifo.read(),
     2631                       true,      // proc read
     2632                       m_cmd_read_length_fifo.read(),
     2633                       m_x[(addr_t)(m_cmd_read_addr_fifo.read())],
     2634                       std::vector<be_t> (m_words,0),
     2635                       std::vector<data_t> (m_words,0),
     2636                       r_read_ll_key.read() );
    25712637#if DEBUG_MEMC_READ
    25722638if(m_debug)
    2573 std::cout << "  <MEMC " << name() << " READ_TRT_SET> Write in Transaction Table:"
     2639std::cout << "  <MEMC " << name() << " READ_TRT_SET> Set a GET in TRT:"
    25742640          << " address = " << std::hex << m_cmd_read_addr_fifo.read()
    25752641          << " / srcid = " << std::hex << m_cmd_read_srcid_fifo.read() << std::endl;
    25762642#endif
    2577         r_read_fsm = READ_TRT_REQ;
    2578       }
    2579       break;
     2643            r_read_fsm = READ_TRT_REQ;
     2644        }
     2645        break;
    25802646    }
    25812647
     
    25832649    case READ_TRT_REQ:   // consume the read request in FIFO and send it to IXR_CMD_FSM
    25842650    {
    2585       if(not r_read_to_ixr_cmd_req)
    2586       {
    2587         cmd_read_fifo_get       = true;
    2588         r_read_to_ixr_cmd_req   = true;
    2589         r_read_to_ixr_cmd_nline = m_nline[(addr_t)(m_cmd_read_addr_fifo.read())];
    2590         r_read_to_ixr_cmd_trdid = r_read_trt_index.read();
    2591         r_read_fsm              = READ_IDLE;
     2651        if(not r_read_to_ixr_cmd_req)
     2652        {
     2653            cmd_read_fifo_get       = true;
     2654            r_read_to_ixr_cmd_req   = true;
     2655            r_read_to_ixr_cmd_index = r_read_trt_index.read();
     2656            r_read_fsm              = READ_IDLE;
    25922657
    25932658#if DEBUG_MEMC_READ
     
    25962661          << std::hex << m_cmd_read_addr_fifo.read() << std::endl;
    25972662#endif
    2598       }
    2599       break;
     2663        }
     2664        break;
    26002665    }
    26012666  } // end switch read_fsm
     
    26152680  //   If the data is cached by other processors, a coherence transaction must
    26162681  //   be launched (sc requests always require a coherence transaction):
    2617   //   It is a multicast update if the line is not in counter mode, and the processor
     2682  //   It is a multicast update if the line is not in counter mode: the processor
    26182683  //   takes the lock protecting the Update Table (UPT) to register this transaction.
    2619   //   It is a broadcast invalidate if the line is in counter mode.
    26202684  //   If the UPT is full, it releases the lock(s) and retry. Then, it sends
    26212685  //   a multi-update request to all owners of the line (but the writer),
     
    26232687  //   does not respond to the writing processor, as this response will be sent by
    26242688  //   the MULTI_ACK FSM when all update responses have been received.
     2689  //   It is a broadcast invalidate if the line is in counter mode: The line
     2690  //   should be erased in memory cache, and written in XRAM with a PUT transaction,
     2691  //   after registration in TRT.
    26252692  //
    26262693  // - In case of MISS, the WRITE FSM takes the lock protecting the transaction
    26272694  //   table (TRT). If a read transaction to the XRAM for this line already exists,
    26282695  //   it writes in the TRT (write buffer). Otherwise, if a TRT entry is free,
    2629   //   the WRITE FSM register a new transaction in TRT, and sends a read line request
     2696  //   the WRITE FSM register a new transaction in TRT, and sends a GET request
    26302697  //   to the XRAM. If the TRT is full, it releases the lock, and waits.
    26312698  //   Finally, the WRITE FSM returns an aknowledge response to the writing processor.
    26322699  /////////////////////////////////////////////////////////////////////////////////////
     2700
     2701//std::cout << std::endl << "write_fsm" << std::endl;
    26332702
    26342703  switch(r_write_fsm.read())
     
    26372706    case WRITE_IDLE:  // copy first word of a write burst in local buffer
    26382707    {
    2639       if(m_cmd_write_addr_fifo.rok())
    2640       {
    2641         if((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC)
    2642           m_cpt_sc++;
    2643         else
    2644         {
    2645           m_cpt_write++;
    2646           m_cpt_write_cells++;
    2647         }
    2648 
    2649         // consume a word in the FIFO & write it in the local buffer
    2650         cmd_write_fifo_get  = true;
    2651         size_t index        = m_x[(addr_t)(m_cmd_write_addr_fifo.read())];
    2652 
    2653         r_write_address     = (addr_t)(m_cmd_write_addr_fifo.read());
    2654         r_write_word_index  = index;
    2655         r_write_word_count  = 1;
    2656         r_write_data[index] = m_cmd_write_data_fifo.read();
    2657         r_write_srcid       = m_cmd_write_srcid_fifo.read();
    2658         r_write_trdid       = m_cmd_write_trdid_fifo.read();
    2659         r_write_pktid       = m_cmd_write_pktid_fifo.read();
    2660         r_write_pending_sc  = false;
    2661 
    2662         // initialize the be field for all words
    2663         for(size_t word=0 ; word<m_words ; word++)
    2664         {
    2665           if(word == index) r_write_be[word] = m_cmd_write_be_fifo.read();
    2666           else              r_write_be[word] = 0x0;
    2667         }
    2668 
    2669         if (m_cmd_write_eop_fifo.read() or ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC))
    2670         {
    2671           r_write_fsm = WRITE_DIR_REQ;
    2672         }
    2673         else
    2674         {
    2675           r_write_fsm = WRITE_NEXT;
    2676         }
     2708        if(m_cmd_write_addr_fifo.rok())
     2709        {
     2710            if((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC)
     2711            {
     2712                m_cpt_sc++;
     2713            }
     2714            else
     2715            {
     2716                m_cpt_write++;
     2717                m_cpt_write_cells++;
     2718            }
     2719
     2720            // consume a word in the FIFO & write it in the local buffer
     2721            cmd_write_fifo_get  = true;
     2722            size_t index        = m_x[(addr_t)(m_cmd_write_addr_fifo.read())];
     2723
     2724            r_write_address     = (addr_t)(m_cmd_write_addr_fifo.read());
     2725            r_write_word_index  = index;
     2726            r_write_word_count  = 1;
     2727            r_write_data[index] = m_cmd_write_data_fifo.read();
     2728            r_write_srcid       = m_cmd_write_srcid_fifo.read();
     2729            r_write_trdid       = m_cmd_write_trdid_fifo.read();
     2730            r_write_pktid       = m_cmd_write_pktid_fifo.read();
     2731            r_write_pending_sc  = false;
     2732
     2733            // initialize the be field for all words
     2734            for(size_t word=0 ; word<m_words ; word++)
     2735            {
     2736                if(word == index) r_write_be[word] = m_cmd_write_be_fifo.read();
     2737                else              r_write_be[word] = 0x0;
     2738            }
     2739
     2740            if (m_cmd_write_eop_fifo.read() or ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC))
     2741            {
     2742                r_write_fsm = WRITE_DIR_REQ;
     2743            }
     2744            else
     2745            {
     2746                r_write_fsm = WRITE_NEXT;
     2747            }
    26772748
    26782749#if DEBUG_MEMC_WRITE
     
    26832754          << " / data = " << m_cmd_write_data_fifo.read() << std::endl;
    26842755#endif
    2685       }
    2686       break;
    2687     }
    2688 
     2756        }
     2757        break;
     2758    }
    26892759    ////////////////
    26902760    case WRITE_NEXT:  // copy next word of a write burst in local buffer
    26912761    {
    2692       if(m_cmd_write_addr_fifo.rok())
    2693       {
     2762        if(m_cmd_write_addr_fifo.rok())
     2763        {
    26942764
    26952765#if DEBUG_MEMC_WRITE
     
    26992769          << std::endl;
    27002770#endif
    2701         m_cpt_write_cells++;
    2702 
    2703         // check that the next word is in the same cache line
    2704         if((m_nline[(addr_t)(r_write_address.read())]       !=
    2705             m_nline[(addr_t)(m_cmd_write_addr_fifo.read())]))
    2706         {
    2707           std::cout << "VCI_MEM_CACHE ERROR " << name() << " WRITE_NEXT state" << std::endl
    2708                     << "all words in a write burst must be in same cache line" << std::endl;
    2709 
    2710           exit(0);
    2711         }
    2712 
    2713         // consume a word in the FIFO & write it in the local buffer
    2714         cmd_write_fifo_get  = true;
    2715         size_t index        = r_write_word_index.read() + r_write_word_count.read();
    2716 
    2717         r_write_be[index]   = m_cmd_write_be_fifo.read();
    2718         r_write_data[index] = m_cmd_write_data_fifo.read();
    2719         r_write_word_count  = r_write_word_count.read() + 1;
    2720 
    2721         if(m_cmd_write_eop_fifo.read())
    2722         {
    2723           r_write_fsm = WRITE_DIR_REQ;
    2724         }
    2725       }
    2726       break;
    2727     }
    2728 
    2729     ////////////////////
    2730     case WRITE_DIR_REQ:
    2731     {
    2732       // Get the lock to the directory
    2733       // and access the llsc_global_table
    2734       if(r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE)
    2735       {
    2736         ///////////////////////////////////////////////////////////////////////
    2737         // SC command treatment
    2738         // We test the r_write_pending_sc register to know if we are returning
    2739         // from the WAIT state.
    2740         // In this case, the SC has already succeed and we cannot consume
    2741         // another time from the FIFO. Also, we don't have to test another
    2742         // time if the SC has succeed
    2743         if(((r_write_pktid.read() & 0x7) == TYPE_SC) and not r_write_pending_sc.read())
    2744         {
    2745           if(not m_cmd_write_addr_fifo.rok()) break;
    2746 
    2747           assert(m_cmd_write_eop_fifo.read() and
    2748                  "Error in VCI_MEM_CACHE : "
    2749                  "invalid packet format for SC command");
    2750 
    2751           size_t index    = r_write_word_index.read();
    2752           bool sc_success = m_llsc_table.sc(r_write_address.read()    ,
     2771            m_cpt_write_cells++;
     2772
     2773            // check that the next word is in the same cache line
     2774            assert( (m_nline[(addr_t)(r_write_address.read())] ==
     2775                     m_nline[(addr_t)(m_cmd_write_addr_fifo.read())]) and
     2776            "MEMC ERROR in WRITE_NEXT state: Illegal write burst");
     2777
     2778            // consume a word in the FIFO & write it in the local buffer
     2779            cmd_write_fifo_get  = true;
     2780            size_t index        = r_write_word_index.read() + r_write_word_count.read();
     2781
     2782            r_write_be[index]   = m_cmd_write_be_fifo.read();
     2783            r_write_data[index] = m_cmd_write_data_fifo.read();
     2784            r_write_word_count  = r_write_word_count.read() + 1;
     2785
     2786            if(m_cmd_write_eop_fifo.read()) r_write_fsm = WRITE_DIR_REQ;
     2787        }
     2788        break;
     2789    }
     2790    ///////////////////
     2791    case WRITE_DIR_REQ:    // Get the lock to the directory
     2792                           // and access the llsc_global_table
     2793    {
     2794        if( r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE )
     2795        {
     2796            if(((r_write_pktid.read() & 0x7) == TYPE_SC) and not r_write_pending_sc.read())
     2797            {
     2798                // We enter here if it is a new SC command
     2799                // If r_write_pending_sc is set the SC is not new and has already been tested
     2800
     2801                if(not m_cmd_write_addr_fifo.rok()) break;
     2802
     2803                assert( m_cmd_write_eop_fifo.read() and
     2804                "MEMC ERROR in WRITE_DIR_REQ state: invalid packet format for SC command");
     2805
     2806                size_t index    = r_write_word_index.read();
     2807                bool sc_success = m_llsc_table.sc(r_write_address.read()    ,
    27532808                                            r_write_data[index].read());
    27542809
    2755           // consume a word in the FIFO & write it in the local buffer
    2756           cmd_write_fifo_get  = true;
    2757           r_write_data[index] = m_cmd_write_data_fifo.read();
    2758           r_write_sc_fail     = not sc_success;
    2759           r_write_pending_sc  = true;
    2760 
    2761           if(not sc_success) r_write_fsm = WRITE_RSP;
    2762           else               r_write_fsm = WRITE_DIR_LOCK;
    2763 
    2764           break;
    2765         }
    2766 
    2767         ///////////////////////////////////////////////////////////////////////
    2768         // WRITE command treatment or SC command returning from the WAIT state
    2769         // In the second case, we must access the LL/SC global table to
    2770         // erase any possible new reservation when we release the lock on the
    2771         // directory
    2772         m_llsc_table.sw(m_nline[(addr_t)r_write_address.read()],r_write_word_index.read(),r_write_word_index.read()+r_write_word_count.read());
    2773 
    2774         r_write_fsm = WRITE_DIR_LOCK;
    2775         m_cpt_write_fsm_n_dir_lock++;
     2810                // consume a word in the FIFO & write it in the local buffer
     2811                cmd_write_fifo_get  = true;
     2812                r_write_data[index] = m_cmd_write_data_fifo.read();
     2813                r_write_sc_fail     = not sc_success;
     2814                r_write_pending_sc  = true;
     2815
     2816                if(not sc_success) r_write_fsm = WRITE_RSP;
     2817                else               r_write_fsm = WRITE_DIR_LOCK;
     2818            }
     2819            else
     2820            {
     2821                // We enter here if it is a SW command or an already tested SC command
     2822
     2823                m_llsc_table.sw( m_nline[(addr_t)r_write_address.read()],
     2824                                 r_write_word_index.read(),
     2825                                 r_write_word_index.read() + r_write_word_count.read() );
     2826
     2827                r_write_fsm = WRITE_DIR_LOCK;
     2828            }
    27762829      }
    27772830
     
    27812834          << std::endl;
    27822835#endif
    2783 
    2784       m_cpt_write_fsm_dir_lock++;
    2785 
    27862836      break;
    27872837    }
    2788 
    27892838    ////////////////////
    27902839    case WRITE_DIR_LOCK:     // access directory to check hit/miss
    27912840    {
    2792       if(r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE)
    2793       {
     2841        assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
     2842        "MEMC ERROR in ALLOC_DIR_LOCK state: Bad DIR allocation");
     2843
    27942844        size_t  way = 0;
    27952845        DirectoryEntry entry(m_cache_directory.read(r_write_address.read(), way));
     
    27972847        if(entry.valid)    // hit
    27982848        {
    2799           // copy directory entry in local buffer in case of hit
    2800           r_write_is_cnt     = entry.is_cnt;
    2801           r_write_lock       = entry.lock;
    2802           r_write_tag        = entry.tag;
    2803           r_write_copy       = entry.owner.srcid;
    2804 #if L1_MULTI_CACHE
    2805           r_write_copy_cache = entry.owner.cache_id;
    2806 #endif
    2807           r_write_copy_inst  = entry.owner.inst;
    2808           r_write_count      = entry.count;
    2809           r_write_ptr        = entry.ptr;
    2810           r_write_way        = way;
    2811 
    2812           if(entry.is_cnt and entry.count)
    2813           {
    2814             r_write_fsm = WRITE_DIR_READ;
    2815           }
    2816           else
    2817           {
    2818             r_write_fsm = WRITE_DIR_HIT;
    2819           }
     2849            // copy directory entry in local buffer in case of hit
     2850            r_write_is_cnt     = entry.is_cnt;
     2851            r_write_lock       = entry.lock;
     2852            r_write_tag        = entry.tag;
     2853            r_write_copy       = entry.owner.srcid;
     2854            r_write_copy_inst  = entry.owner.inst;
     2855            r_write_count      = entry.count;
     2856            r_write_ptr        = entry.ptr;
     2857            r_write_way        = way;
     2858
     2859            if(entry.is_cnt and entry.count) r_write_fsm = WRITE_BC_DIR_READ;
     2860            else                             r_write_fsm = WRITE_DIR_HIT;
    28202861        }
    28212862        else  // miss
    28222863        {
    2823           r_write_fsm = WRITE_MISS_TRT_LOCK;
     2864            r_write_fsm = WRITE_MISS_TRT_LOCK;
    28242865        }
    28252866
     
    28382879}
    28392880#endif
    2840       }
    2841       else
    2842       {
    2843         std::cout << "VCI_MEM_CACHE ERROR " << name()
    2844                   << " WRITE_DIR_LOCK state"        << std::endl
    2845                   << "bad DIR allocation"           << std::endl;
    2846 
    2847         exit(0);
    2848       }
    2849       break;
    2850     }
    2851     ////////////////////
    2852     case WRITE_DIR_READ:  // read the cache and complete the buffer when be!=0xF
    2853     {
    2854       // update local buffer
    2855       size_t set  = m_y[(addr_t)(r_write_address.read())];
    2856       size_t way  = r_write_way.read();
    2857       for(size_t word=0 ; word<m_words ; word++)
    2858       {
    2859         data_t mask = 0;
    2860         if(r_write_be[word].read() & 0x1) mask = mask | 0x000000FF;
    2861         if(r_write_be[word].read() & 0x2) mask = mask | 0x0000FF00;
    2862         if(r_write_be[word].read() & 0x4) mask = mask | 0x00FF0000;
    2863         if(r_write_be[word].read() & 0x8) mask = mask | 0xFF000000;
    2864 
    2865         // complete only if mask is not null (for energy consumption)
    2866         r_write_data[word]  = (r_write_data[word].read() & mask) |
    2867                               (m_cache_data.read(way, set, word) & ~mask);
    2868 
    2869       } // end for
    2870 
    2871       // test if a coherence broadcast is required
    2872       r_write_fsm = WRITE_BC_TRT_LOCK;
    2873 
    2874 #if DEBUG_MEMC_WRITE
    2875 if(m_debug)
    2876 std::cout << "  <MEMC " << name() << " WRITE_DIR_READ>"
    2877           << " Read the cache to complete local buffer" << std::endl;
    2878 #endif
    2879       break;
    2880     }
    2881 
     2881        break;
     2882    }
    28822883    ///////////////////
    2883     case WRITE_DIR_HIT:
    2884     {
    2885       // update the cache directory
    2886       // update directory with Dirty bit
    2887       DirectoryEntry entry;
    2888       entry.valid          = true;
    2889       entry.dirty          = true;
    2890       entry.tag            = r_write_tag.read();
    2891       entry.is_cnt         = r_write_is_cnt.read();
    2892       entry.lock           = r_write_lock.read();
    2893       entry.owner.srcid    = r_write_copy.read();
    2894 #if L1_MULTI_CACHE
    2895       entry.owner.cache_id = r_write_copy_cache.read();
    2896 #endif
    2897       entry.owner.inst     = r_write_copy_inst.read();
    2898       entry.count          = r_write_count.read();
    2899       entry.ptr            = r_write_ptr.read();
    2900 
    2901       size_t set           = m_y[(addr_t)(r_write_address.read())];
    2902       size_t way           = r_write_way.read();
    2903 
    2904       // update directory
    2905       m_cache_directory.write(set, way, entry);
    2906 
    2907       // owner is true when the  the first registered copy is the writer itself
    2908       bool owner = (((r_write_copy.read() == r_write_srcid.read())
    2909 #if L1_MULTI_CACHE
    2910                      and(r_write_copy_cache.read() ==r_write_pktid.read())
    2911 #endif
    2912                     ) and not r_write_copy_inst.read());
    2913 
    2914       // no_update is true when there is no need for coherence transaction
    2915       // (tests for sc requests)
    2916       bool no_update = ( (r_write_count.read() == 0) or
     2884    case WRITE_DIR_HIT:    // update the cache directory with Dirty bit
     2885                           // and update data cache
     2886    {
     2887        assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
     2888        "MEMC ERROR in ALLOC_DIR_HIT state: Bad DIR allocation");
     2889
     2890        DirectoryEntry entry;
     2891        entry.valid          = true;
     2892        entry.dirty          = true;
     2893        entry.tag            = r_write_tag.read();
     2894        entry.is_cnt         = r_write_is_cnt.read();
     2895        entry.lock           = r_write_lock.read();
     2896        entry.owner.srcid    = r_write_copy.read();
     2897        entry.owner.inst     = r_write_copy_inst.read();
     2898        entry.count          = r_write_count.read();
     2899        entry.ptr            = r_write_ptr.read();
     2900
     2901        size_t set           = m_y[(addr_t)(r_write_address.read())];
     2902        size_t way           = r_write_way.read();
     2903
     2904        // update directory
     2905        m_cache_directory.write(set, way, entry);
     2906
     2907        // owner is true when the  the first registered copy is the writer itself
     2908        bool owner = ( (r_write_copy.read() == r_write_srcid.read())
     2909                     and not r_write_copy_inst.read() );
     2910
     2911        // no_update is true when there is no need for coherence transaction
     2912        bool no_update = ( (r_write_count.read() == 0) or
    29172913                         (owner and (r_write_count.read() ==1) and
    29182914                         (r_write_pktid.read() != TYPE_SC)));
    29192915
    2920       // write data in the cache if no coherence transaction
    2921       if(no_update)
    2922       {
    2923         for(size_t word=0 ; word<m_words ; word++)
    2924         {
    2925           m_cache_data.write(way, set, word, r_write_data[word].read(), r_write_be[word].read());
    2926 
    2927           if(m_monitor_ok)
    2928           {
    2929             addr_t address = (r_write_address.read() & ~(addr_t) 0x3F) | word<<2;
    2930             check_monitor( address, r_write_data[word].read(), false);
    2931           }
    2932         }
    2933       }
    2934 
    2935       if(owner and not no_update and(r_write_pktid.read() != TYPE_SC))
    2936       {
    2937         r_write_count = r_write_count.read() - 1;
    2938       }
    2939 
    2940       if(no_update)
    2941       // Write transaction completed
    2942       {
    2943         r_write_fsm = WRITE_RSP;
    2944       }
    2945       else
    2946       // coherence update required
    2947       {
    2948         if(!r_write_to_cc_send_multi_req.read() and
    2949            !r_write_to_cc_send_brdcast_req.read())
    2950         {
    2951           r_write_fsm = WRITE_UPT_LOCK;
    2952         }
    2953         else
    2954         {
    2955           r_write_fsm = WRITE_WAIT;
    2956         }
    2957       }
     2916        // write data in the cache if no coherence transaction
     2917        if(no_update)
     2918        {
     2919            for(size_t word=0 ; word<m_words ; word++)
     2920            {
     2921                m_cache_data.write( way,
     2922                                    set,
     2923                                    word,
     2924                                    r_write_data[word].read(),
     2925                                    r_write_be[word].read());
     2926            }
     2927        }
     2928
     2929        if(owner and not no_update and(r_write_pktid.read() != TYPE_SC))
     2930        {
     2931            r_write_count = r_write_count.read() - 1;
     2932        }
     2933
     2934        if(no_update)     // Write transaction completed
     2935        {
     2936            r_write_fsm = WRITE_RSP;
     2937        }
     2938        else              // coherence update required
     2939        {
     2940            if(!r_write_to_cc_send_multi_req.read() and
     2941               !r_write_to_cc_send_brdcast_req.read())
     2942            {
     2943                r_write_fsm = WRITE_UPT_LOCK;
     2944            }
     2945            else
     2946            {
     2947                r_write_fsm = WRITE_WAIT;
     2948            }
     2949        }
    29582950
    29592951#if DEBUG_MEMC_WRITE
    29602952if(m_debug)
    29612953{
    2962     if(no_update)
    2963     {
    2964         std::cout << "  <MEMC " << name()
    2965                   << " WRITE_DIR_HIT> Write into cache / No coherence transaction"
    2966                   << std::endl;
    2967     }
    2968     else
    2969     {
    2970         std::cout << "  <MEMC " << name() << " WRITE_DIR_HIT> Coherence update required:"
    2971                   << " is_cnt = " << r_write_is_cnt.read()
    2972                   << " nb_copies = " << std::dec << r_write_count.read() << std::endl;
    2973         if(owner) std::cout << "       ... but the first copy is the writer" << std::endl;
    2974     }
     2954if(no_update)
     2955{
     2956std::cout << "  <MEMC " << name()
     2957          << " WRITE_DIR_HIT> Write into cache / No coherence transaction" << std::endl;
    29752958}
    2976 #endif
    2977       break;
     2959else
     2960{
     2961std::cout << "  <MEMC " << name() << " WRITE_DIR_HIT> Coherence update required:"
     2962          << " is_cnt = " << r_write_is_cnt.read()
     2963          << " nb_copies = " << std::dec << r_write_count.read() << std::endl;
     2964if(owner) std::cout << "       ... but the first copy is the writer" << std::endl;
     2965}
     2966}
     2967#endif
     2968        break;
    29782969    }
    29792970    ////////////////////
    29802971    case WRITE_UPT_LOCK:  // Try to register the update request in UPT
    29812972    {
    2982       if(r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE)
    2983       {
    2984         bool        wok        = false;
    2985         size_t      index      = 0;
    2986         size_t      srcid      = r_write_srcid.read();
    2987         size_t      trdid      = r_write_trdid.read();
    2988         size_t      pktid      = r_write_pktid.read();
    2989         addr_t      nline      = m_nline[(addr_t)(r_write_address.read())];
    2990         size_t      nb_copies  = r_write_count.read();
    2991         size_t      set        = m_y[(addr_t)(r_write_address.read())];
    2992         size_t      way        = r_write_way.read();
    2993 
    2994         wok = m_upt.set(true,  // it's an update transaction
    2995                         false, // it's not a broadcast
    2996                         true,  // response required
    2997                         false, // no acknowledge required
    2998                         srcid,   
    2999                         trdid,
    3000                         pktid,
    3001                         nline,
    3002                         nb_copies,
    3003                         index);
    3004         if(wok)       // write data in cache
    3005         {
    3006           for(size_t word=0 ; word<m_words ; word++)
    3007           {
    3008             m_cache_data.write(way,
    3009                                set,
    3010                                word,
    3011                                r_write_data[word].read(),
    3012                                r_write_be[word].read());
    3013 
    3014             if(m_monitor_ok)
     2973        if(r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE)
     2974        {
     2975            bool        wok        = false;
     2976            size_t      index      = 0;
     2977            size_t      srcid      = r_write_srcid.read();
     2978            size_t      trdid      = r_write_trdid.read();
     2979            size_t      pktid      = r_write_pktid.read();
     2980            addr_t      nline      = m_nline[(addr_t)(r_write_address.read())];
     2981            size_t      nb_copies  = r_write_count.read();
     2982            size_t      set        = m_y[(addr_t)(r_write_address.read())];
     2983            size_t      way        = r_write_way.read();
     2984
     2985            wok = m_upt.set( true,  // it's an update transaction
     2986                             false, // it's not a broadcast
     2987                             true,  // response required
     2988                             false, // no acknowledge required
     2989                             srcid,   
     2990                             trdid,
     2991                             pktid,
     2992                             nline,
     2993                             nb_copies,
     2994                             index);
     2995
     2996            if( wok )       // write data in cache
    30152997            {
    3016               addr_t address = (r_write_address.read() & ~(addr_t) 0x3F) | word<<2;
    3017               check_monitor( address, r_write_data[word].read(), false);
     2998                for(size_t word=0 ; word<m_words ; word++)
     2999                {
     3000                    m_cache_data.write( way,
     3001                                        set,
     3002                                        word,
     3003                                        r_write_data[word].read(),
     3004                                        r_write_be[word].read());
     3005                }
    30183006            }
    3019           }
    3020         }
    30213007
    30223008#if DEBUG_MEMC_WRITE
    3023 if(m_debug)
     3009if(m_debug and wok)
    30243010{
    3025     if(wok)
    3026     {
    3027         std::cout << "  <MEMC " << name()
    3028                   << " WRITE_UPT_LOCK> Register the multicast update in UPT / "
    3029                   << " nb_copies = " << r_write_count.read() << std::endl;
    3030     }
     3011std::cout << "  <MEMC " << name()
     3012          << " WRITE_UPT_LOCK> Register the multicast update in UPT / "
     3013          << " nb_copies = " << r_write_count.read() << std::endl;
    30313014}
    30323015#endif
    3033         r_write_upt_index = index;
    3034         //  releases the lock protecting UPT and the DIR if no entry...
    3035         if(wok) r_write_fsm = WRITE_UPT_HEAP_LOCK;
    3036         else    r_write_fsm = WRITE_WAIT;
    3037         m_cpt_write_fsm_n_upt_lock++;
    3038       }
    3039 
    3040       m_cpt_write_fsm_upt_lock++;
    3041 
    3042       break;
     3016            r_write_upt_index = index;
     3017            // releases the lock protecting UPT and the DIR if no entry...
     3018            if(wok) r_write_fsm = WRITE_UPT_HEAP_LOCK;
     3019            else    r_write_fsm = WRITE_WAIT;
     3020        }
     3021        break;
    30433022    }
    30443023
     
    30863065      for(size_t i=min ; i<max ; i++) r_write_to_cc_send_data[i] = r_write_data[i];
    30873066
    3088       if((r_write_copy.read() != r_write_srcid.read()) or(r_write_pktid.read() == TYPE_SC) or
    3089 #if L1_MULTI_CACHE
    3090           (r_write_copy_cache.read() != r_write_pktid.read()) or
    3091 #endif
    3092           r_write_copy_inst.read())
     3067      if( (r_write_copy.read() != r_write_srcid.read()) or
     3068          (r_write_pktid.read() == TYPE_SC) or r_write_copy_inst.read())
    30933069      {
    30943070        // put the first srcid in the fifo
     
    30963072        write_to_cc_send_fifo_inst    = r_write_copy_inst.read();
    30973073        write_to_cc_send_fifo_srcid   = r_write_copy.read();
    3098 #if L1_MULTI_CACHE
    3099         write_to_cc_send_fifo_cache_id= r_write_copy_cache.read();
    3100 #endif
    31013074        if(r_write_count.read() == 1)
    31023075        {
     
    31493122      bool dec_upt_counter;
    31503123
    3151       if(((entry.owner.srcid != r_write_srcid.read()) or (r_write_pktid.read() == TYPE_SC)) or
    3152 #if L1_MULTI_CACHE
    3153           (entry.owner.cache_id != r_write_pktid.read()) or
    3154 #endif
    3155           entry.owner.inst)             // put the next srcid in the fifo
     3124      // put the next srcid in the fifo
     3125      if( (entry.owner.srcid != r_write_srcid.read()) or
     3126          (r_write_pktid.read() == TYPE_SC) or entry.owner.inst)   
    31563127      {
    31573128        dec_upt_counter                = false;
     
    31593130        write_to_cc_send_fifo_inst     = entry.owner.inst;
    31603131        write_to_cc_send_fifo_srcid    = entry.owner.srcid;
    3161 #if L1_MULTI_CACHE
    3162         write_to_cc_send_fifo_cache_id = entry.owner.cache_id;
    3163 #endif
    31643132
    31653133#if DEBUG_MEMC_WRITE
     
    32313199
    32323200    ///////////////
    3233     case WRITE_RSP:
    3234     {
    3235       // Post a request to TGT_RSP FSM to acknowledge the write
    3236       // In order to increase the Write requests throughput,
    3237       // we don't wait to return in the IDLE state to consume
    3238       // a new request in the write FIFO
    3239 
     3201    case WRITE_RSP:  // Post a request to TGT_RSP FSM to acknowledge the write
     3202                     // In order to increase the Write requests throughput,
     3203                     // we don't wait to return in the IDLE state to consume
     3204                     // a new request in the write FIFO
     3205    {
    32403206      if(!r_write_to_tgt_rsp_req.read())
    32413207      {
     
    33303296        bool    hit_write = m_trt.hit_write(m_nline[addr]);
    33313297#endif
    3332         bool    wok       = !m_trt.full(wok_index);
     3298        bool    wok       = not m_trt.full(wok_index);
    33333299
    33343300        if(hit_read)      // register the modified data in TRT
     
    34183384          data_vector.push_back(r_write_data[i]);
    34193385        }
    3420         m_trt.write_data_mask(r_write_trt_index.read(),
    3421                                           be_vector,
    3422                                           data_vector);
     3386        m_trt.write_data_mask( r_write_trt_index.read(),
     3387                               be_vector,
     3388                               data_vector );
    34233389        r_write_fsm = WRITE_RSP;
    34243390
     
    34303396      break;
    34313397    }
    3432 
    34333398    /////////////////////////
    34343399    case WRITE_MISS_XRAM_REQ: // send a GET request to IXR_CMD FSM
    34353400    {
    3436       if(!r_write_to_ixr_cmd_req)
     3401      if( not r_write_to_ixr_cmd_req.read() )
    34373402      {
    34383403        r_write_to_ixr_cmd_req   = true;
    3439         r_write_to_ixr_cmd_write = false;
    3440         r_write_to_ixr_cmd_nline = m_nline[(addr_t)(r_write_address.read())];
    3441         r_write_to_ixr_cmd_trdid = r_write_trt_index.read();
     3404        r_write_to_ixr_cmd_put   = false;
     3405        r_write_to_ixr_cmd_index = r_write_trt_index.read();
    34423406        r_write_fsm              = WRITE_RSP;
    34433407
     
    34493413      break;
    34503414    }
    3451 
    34523415    ///////////////////////
    3453     case WRITE_BC_TRT_LOCK:     // Check TRT not full
    3454     {
    3455       if(r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE)
    3456       {
    3457         size_t wok_index = 0;
    3458         bool wok = !m_trt.full(wok_index);
    3459         if(wok)       // set a new entry in TRT
    3460         {
    3461           r_write_trt_index = wok_index;
    3462           r_write_fsm       = WRITE_BC_IVT_LOCK;
    3463         }
    3464         else  // wait an empty entry in TRT
    3465         {
    3466           r_write_fsm       = WRITE_WAIT;
    3467         }
     3416    case WRITE_BC_DIR_READ:  // enter this state if a broadcast-inval is required
     3417                             // the cache line must be erased in mem-cache, and written
     3418                             // into XRAM. we read the cache and complete the buffer
     3419    {
     3420        assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
     3421        "MEMC ERROR in WRITE_BC_DIR_READ state: Bad DIR allocation");
     3422 
     3423        // update local buffer
     3424        size_t set  = m_y[(addr_t)(r_write_address.read())];
     3425        size_t way  = r_write_way.read();
     3426        for(size_t word=0 ; word<m_words ; word++)
     3427        {
     3428            data_t mask = 0;
     3429            if(r_write_be[word].read() & 0x1) mask = mask | 0x000000FF;
     3430            if(r_write_be[word].read() & 0x2) mask = mask | 0x0000FF00;
     3431            if(r_write_be[word].read() & 0x4) mask = mask | 0x00FF0000;
     3432            if(r_write_be[word].read() & 0x8) mask = mask | 0xFF000000;
     3433
     3434            // complete only if mask is not null (for energy consumption)
     3435            r_write_data[word]  = (r_write_data[word].read() & mask) |
     3436                                  (m_cache_data.read(way, set, word) & ~mask);
     3437        } // end for
     3438
     3439        r_write_fsm = WRITE_BC_TRT_LOCK;
     3440
     3441#if DEBUG_MEMC_WRITE
     3442if(m_debug)
     3443std::cout << "  <MEMC " << name() << " WRITE_BC_DIR_READ>"
     3444          << " Read the cache to complete local buffer" << std::endl;
     3445#endif
     3446        break;
     3447    }
     3448    ///////////////////////
     3449    case WRITE_BC_TRT_LOCK:     // get TRT lock to check TRT not full
     3450    {
     3451        assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
     3452        "MEMC ERROR in WRITE_BC_TRT_LOCK state: Bad DIR allocation");
     3453 
     3454        if(r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE)
     3455        {
     3456            size_t wok_index = 0;
     3457            bool wok = not m_trt.full(wok_index);
     3458            if( wok )       
     3459            {
     3460                r_write_trt_index = wok_index;
     3461                r_write_fsm       = WRITE_BC_IVT_LOCK;
     3462            }
     3463            else  // wait an empty slot in TRT
     3464            {
     3465                r_write_fsm       = WRITE_WAIT;
     3466            }
    34683467
    34693468#if DEBUG_MEMC_WRITE
     
    34793478      break;
    34803479    }
    3481 
    34823480    //////////////////////
    3483     case WRITE_BC_IVT_LOCK:      // register BC transaction in IVT
    3484     {
    3485       if(r_alloc_ivt_fsm.read() == ALLOC_IVT_WRITE)
    3486       {
    3487         bool        wok       = false;
    3488         size_t      index     = 0;
    3489         size_t      srcid     = r_write_srcid.read();
    3490         size_t      trdid     = r_write_trdid.read();
    3491         size_t      pktid     = r_write_pktid.read();
    3492         addr_t      nline     = m_nline[(addr_t)(r_write_address.read())];
    3493         size_t      nb_copies = r_write_count.read();
    3494 
    3495         wok = m_ivt.set(false,  // it's an inval transaction
    3496                         true,   // it's a broadcast
    3497                         true,   // response required
    3498                         false,  // no acknowledge required
    3499                         srcid,
    3500                         trdid,
    3501                         pktid,
    3502                         nline,
    3503                         nb_copies,
    3504                         index);
     3481    case WRITE_BC_IVT_LOCK:      // get IVT lock and register BC transaction in IVT
     3482    {
     3483        assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
     3484        "MEMC ERROR in WRITE_BC_IVT_LOCK state: Bad DIR allocation");
     3485 
     3486        assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE) and
     3487        "MEMC ERROR in WRITE_BC_IVT_LOCK state: Bad TRT allocation");
     3488 
     3489        if(r_alloc_ivt_fsm.read() == ALLOC_IVT_WRITE)
     3490        {
     3491            bool        wok       = false;
     3492            size_t      index     = 0;
     3493            size_t      srcid     = r_write_srcid.read();
     3494            size_t      trdid     = r_write_trdid.read();
     3495            size_t      pktid     = r_write_pktid.read();
     3496            addr_t      nline     = m_nline[(addr_t)(r_write_address.read())];
     3497            size_t      nb_copies = r_write_count.read();
     3498
     3499            wok = m_ivt.set(false,  // it's an inval transaction
     3500                            true,   // it's a broadcast
     3501                            true,   // response required
     3502                            false,  // no acknowledge required
     3503                            srcid,
     3504                            trdid,
     3505                            pktid,
     3506                            nline,
     3507                            nb_copies,
     3508                            index);
    35053509#if DEBUG_MEMC_WRITE
    35063510if( m_debug and wok )
     
    35083512          << " / nb_copies = " << r_write_count.read() << std::endl;
    35093513#endif
    3510         r_write_upt_index = index;
    3511 
    3512         if(wok) r_write_fsm = WRITE_BC_DIR_INVAL;
    3513         else    r_write_fsm = WRITE_WAIT;
    3514         m_cpt_write_fsm_n_upt_lock++;
    3515       }
    3516 
    3517       m_cpt_write_fsm_upt_lock++;
    3518 
    3519       break;
    3520     }
    3521 
     3514            r_write_upt_index = index;
     3515
     3516            if( wok ) r_write_fsm = WRITE_BC_DIR_INVAL;
     3517            else      r_write_fsm = WRITE_WAIT;
     3518        }
     3519        break;
     3520    }
    35223521    ////////////////////////
    3523     case WRITE_BC_DIR_INVAL:
    3524     {
    3525       // Register a put transaction to XRAM in TRT
    3526       // and invalidate the line in directory
    3527       if((r_alloc_trt_fsm.read() != ALLOC_TRT_WRITE) or
    3528          (r_alloc_ivt_fsm.read() != ALLOC_IVT_WRITE) or
    3529          (r_alloc_dir_fsm.read() != ALLOC_DIR_WRITE))
    3530       {
    3531         std::cout << "VCI_MEM_CACHE ERROR " << name() << " WRITE_BC_DIR_INVAL state" << std::endl;
    3532         std::cout << "bad TRT, DIR, or IVT allocation" << std::endl;
    3533         exit(0);
    3534       }
    3535 
    3536       // register a write request to XRAM in TRT
    3537       m_trt.set(r_write_trt_index.read(),
    3538                             false,    // write request to XRAM
    3539                             m_nline[(addr_t)(r_write_address.read())],
    3540                             0,
    3541                             0,
    3542                             0,
    3543                             false,    // not a processor read
    3544                             0,        // not a single word
    3545                             0,            // word index
    3546                             std::vector<be_t> (m_words,0),
    3547                             std::vector<data_t> (m_words,0));
    3548 
    3549       // invalidate directory entry
    3550       DirectoryEntry entry;
    3551       entry.valid         = false;
    3552       entry.dirty         = false;
    3553       entry.tag         = 0;
    3554       entry.is_cnt        = false;
    3555       entry.lock          = false;
    3556       entry.owner.srcid   = 0;
    3557 #if L1_MULTI_CACHE
    3558       entry.owner.cache_id= 0;
    3559 #endif
    3560       entry.owner.inst    = false;
    3561       entry.ptr           = 0;
    3562       entry.count         = 0;
    3563       size_t set          = m_y[(addr_t)(r_write_address.read())];
    3564       size_t way          = r_write_way.read();
    3565 
    3566       m_cache_directory.write(set, way, entry);
     3522    case WRITE_BC_DIR_INVAL:    // Register a put transaction in TRT
     3523                                // and invalidate the line in directory
     3524    {
     3525        assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
     3526        "MEMC ERROR in WRITE_BC_DIR_INVAL state: Bad DIR allocation");
     3527 
     3528        assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE) and
     3529        "MEMC ERROR in WRITE_BC_DIR_INVAL state: Bad TRT allocation");
     3530 
     3531        assert( (r_alloc_ivt_fsm.read() == ALLOC_IVT_WRITE) and
     3532        "MEMC ERROR in WRITE_BC_DIR_INVAL state: Bad IVT allocation");
     3533 
     3534        // register PUT request in TRT
     3535        std::vector<data_t> data_vector;
     3536        data_vector.clear();
     3537        for(size_t i=0; i<m_words; i++) data_vector.push_back(r_write_data[i].read());
     3538        m_trt.set( r_write_trt_index.read(),
     3539                   false,             // PUT request
     3540                   m_nline[(addr_t)(r_write_address.read())],
     3541                   0,                 // unused
     3542                   0,                 // unused
     3543                   0,                 // unused
     3544                   false,             // not a processor read
     3545                   0,                 // unused
     3546                   0,                 // unused
     3547                   std::vector<be_t> (m_words,0),
     3548                   data_vector );
     3549
     3550        // invalidate directory entry
     3551        DirectoryEntry entry;
     3552        entry.valid         = false;
     3553        entry.dirty         = false;
     3554        entry.tag           = 0;
     3555        entry.is_cnt        = false;
     3556        entry.lock          = false;
     3557        entry.owner.srcid   = 0;
     3558        entry.owner.inst    = false;
     3559        entry.ptr           = 0;
     3560        entry.count         = 0;
     3561        size_t set          = m_y[(addr_t)(r_write_address.read())];
     3562        size_t way          = r_write_way.read();
     3563
     3564        m_cache_directory.write(set, way, entry);
    35673565
    35683566#if DEBUG_MEMC_WRITE
    35693567if(m_debug)
    3570 std::cout << "  <MEMC " << name() << " WRITE_BC_DIR_INVAL> Invalidate the directory entry: @ = "
    3571           << r_write_address.read() << " / register the put transaction in TRT:" << std::endl;
    3572 #endif
    3573       r_write_fsm = WRITE_BC_CC_SEND;
    3574       break;
     3568std::cout << "  <MEMC " << name() << " WRITE_BC_DIR_INVAL> Inval DIR and register in TRT:"
     3569          << " address = " << r_write_address.read() << std::endl;
     3570#endif
     3571        r_write_fsm = WRITE_BC_CC_SEND;
     3572        break;
    35753573    }
    35763574
     
    35783576    case WRITE_BC_CC_SEND:    // Post a coherence broadcast request to CC_SEND FSM
    35793577    {
    3580       if(!r_write_to_cc_send_multi_req.read() and !r_write_to_cc_send_brdcast_req.read())
    3581       {
    3582         r_write_to_cc_send_multi_req   = false;
    3583         r_write_to_cc_send_brdcast_req = true;
    3584         r_write_to_cc_send_trdid       = r_write_upt_index.read();
    3585         r_write_to_cc_send_nline       = m_nline[(addr_t)(r_write_address.read())];
    3586         r_write_to_cc_send_index       = 0;
    3587         r_write_to_cc_send_count       = 0;
    3588 
    3589         for(size_t i=0; i<m_words ; i++)
    3590         {
    3591           r_write_to_cc_send_be[i]=0;
    3592           r_write_to_cc_send_data[i] = 0;
    3593         }
    3594         r_write_fsm = WRITE_BC_XRAM_REQ;
     3578        if(!r_write_to_cc_send_multi_req.read() and !r_write_to_cc_send_brdcast_req.read())
     3579        {
     3580            r_write_to_cc_send_multi_req   = false;
     3581            r_write_to_cc_send_brdcast_req = true;
     3582            r_write_to_cc_send_trdid       = r_write_upt_index.read();
     3583            r_write_to_cc_send_nline       = m_nline[(addr_t)(r_write_address.read())];
     3584            r_write_to_cc_send_index       = 0;
     3585            r_write_to_cc_send_count       = 0;
     3586
     3587            for(size_t i=0; i<m_words ; i++)  // à quoi sert ce for? (AG)
     3588            {
     3589                r_write_to_cc_send_be[i]=0;
     3590                r_write_to_cc_send_data[i] = 0;
     3591            }
     3592            r_write_fsm = WRITE_BC_XRAM_REQ;
    35953593
    35963594#if DEBUG_MEMC_WRITE
     
    35993597          << " WRITE_BC_CC_SEND> Post a broadcast request to CC_SEND FSM" << std::endl;
    36003598#endif
    3601       }
    3602       break;
     3599        }
     3600        break;
    36033601    }
    36043602
    36053603    ///////////////////////
    3606     case WRITE_BC_XRAM_REQ:   // Post a put request to IXR_CMD FSM
    3607     {
    3608       if(!r_write_to_ixr_cmd_req)
    3609       {
    3610         r_write_to_ixr_cmd_req     = true;
    3611         r_write_to_ixr_cmd_write   = true;
    3612         r_write_to_ixr_cmd_nline   = m_nline[(addr_t)(r_write_address.read())];
    3613         r_write_to_ixr_cmd_trdid   = r_write_trt_index.read();
    3614 
    3615         for(size_t i=0; i<m_words; i++) r_write_to_ixr_cmd_data[i] = r_write_data[i];
    3616 
    3617         r_write_fsm = WRITE_IDLE;
     3604    case WRITE_BC_XRAM_REQ:   // Post a PUT request to IXR_CMD FSM
     3605    {
     3606        if( not r_write_to_ixr_cmd_req.read() )
     3607        {
     3608            r_write_to_ixr_cmd_req     = true;
     3609            r_write_to_ixr_cmd_put     = true;
     3610            r_write_to_ixr_cmd_index   = r_write_trt_index.read();
     3611            r_write_fsm = WRITE_IDLE;
    36183612
    36193613#if DEBUG_MEMC_WRITE
     
    36223616          << " WRITE_BC_XRAM_REQ> Post a put request to IXR_CMD FSM" << std::endl;
    36233617#endif
    3624       }
    3625       break;
     3618        }
     3619        break;
    36263620    }
    36273621  } // end switch r_write_fsm
     
    36313625  ///////////////////////////////////////////////////////////////////////
    36323626  // The IXR_CMD fsm controls the command packets to the XRAM :
    3633   // It handles requests from the READ, WRITE, CAS, XRAM_RSP FSMs
    3634   // with a round-robin priority.
     3627  // It handles requests from 5 FSMs with a round-robin priority:
     3628  //  READ > WRITE > CAS > XRAM_RSP > CONFIG
    36353629  //
    3636   // - It sends a single flit VCI read request to the XRAM in case of MISS
    3637   // posted by the READ, WRITE or CAS FSMs : the TRDID field contains
    3638   // the Transaction Tab index.
    3639   // The VCI response is a multi-flit packet : the N cells contain
    3640   // the N data words.
     3630  // - It sends a single flit VCI read to the XRAM in case of
     3631  //   GET request posted by the READ, WRITE or CAS FSMs.
     3632  // - It sends a multi-flit VCI write in case of PUT request posted by
     3633  //   the XRAM_RSP, WRITE, CAS, or CONFIG FSMs.
    36413634  //
    3642   // - It sends a multi-flit VCI write when the XRAM_RSP FSM, WRITE FSM
    3643   // or CAS FSM request to save a dirty line to the XRAM.
    3644   // The VCI response is a single flit packet.
     3635  // For each client, there is three steps:
     3636  // - IXR_CMD_*_IDLE : round-robin allocation to a client
     3637  // - IXR_CMD_*_TRT  : access to TRT for address and data
     3638  // - IXR_CMD_*_SEND : send the PUT or GET VCI command
     3639  //
     3640  // The address and data to be written (for a PUT) are stored in TRT.
     3641  // The trdid field contains always the TRT entry index.
    36453642  ////////////////////////////////////////////////////////////////////////
     3643
     3644//std::cout << std::endl << "ixr_cmd_fsm" << std::endl;
    36463645
    36473646  switch(r_ixr_cmd_fsm.read())
    36483647  {
    3649     ////////////////////////
     3648    ///////////////////////
    36503649    case IXR_CMD_READ_IDLE:
    3651       if     (r_write_to_ixr_cmd_req)    r_ixr_cmd_fsm = IXR_CMD_WRITE;
    3652       else if(r_cas_to_ixr_cmd_req)      r_ixr_cmd_fsm = IXR_CMD_CAS;
    3653       else if(r_xram_rsp_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_XRAM;
     3650      if     (r_write_to_ixr_cmd_req.read())      r_ixr_cmd_fsm = IXR_CMD_WRITE_TRT;
     3651      else if(r_cas_to_ixr_cmd_req.read())        r_ixr_cmd_fsm = IXR_CMD_CAS_TRT;
     3652      else if(r_xram_rsp_to_ixr_cmd_req.read())   r_ixr_cmd_fsm = IXR_CMD_XRAM_TRT;
    36543653#if ODCCP_NON_INCLUSIVE
    3655       else if(r_cleanup_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_CLEANUP_DATA;
     3654      else if(r_cleanup_to_ixr_cmd_req.read())
     3655      {
     3656        r_ixr_cmd_fsm = IXR_CMD_CLEANUP_DATA_SEND;
     3657        r_ixr_cmd_word = 0;
     3658      }
    36563659#else
    3657       else if(r_cleanup_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_TRT_LOCK;
    3658 #endif
    3659       else if(r_read_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_READ;
     3660      else if(r_cleanup_to_ixr_cmd_req.read())     r_ixr_cmd_fsm = IXR_CMD_CLEANUP_TRT;
     3661#endif
     3662      else if(r_config_to_ixr_cmd_req.read())     r_ixr_cmd_fsm = IXR_CMD_CONFIG_TRT;
     3663      else if(r_read_to_ixr_cmd_req.read())       r_ixr_cmd_fsm = IXR_CMD_READ_TRT;
    36603664      break;
    36613665    ////////////////////////
    36623666    case IXR_CMD_WRITE_IDLE:
    3663       if(r_cas_to_ixr_cmd_req)           r_ixr_cmd_fsm = IXR_CMD_CAS;
    3664       else if(r_xram_rsp_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_XRAM;
     3667      if     (r_cas_to_ixr_cmd_req.read())        r_ixr_cmd_fsm = IXR_CMD_CAS_TRT;
     3668      else if(r_xram_rsp_to_ixr_cmd_req.read())   r_ixr_cmd_fsm = IXR_CMD_XRAM_TRT;
    36653669#if ODCCP_NON_INCLUSIVE
    3666       else if(r_cleanup_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_CLEANUP_DATA;
     3670      else if(r_cleanup_to_ixr_cmd_req.read())
     3671      {
     3672        r_ixr_cmd_fsm = IXR_CMD_CLEANUP_DATA_SEND;
     3673        r_ixr_cmd_word = 0;
     3674      }
    36673675#else
    3668       else if(r_cleanup_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_TRT_LOCK;
    3669 #endif
    3670       else if(r_read_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_READ;
    3671       else if(r_write_to_ixr_cmd_req)    r_ixr_cmd_fsm = IXR_CMD_WRITE;
     3676      else if(r_cleanup_to_ixr_cmd_req)           r_ixr_cmd_fsm = IXR_CMD_CLEANUP_TRT;
     3677#endif
     3678      else if(r_config_to_ixr_cmd_req.read())     r_ixr_cmd_fsm = IXR_CMD_CONFIG_TRT;
     3679      else if(r_read_to_ixr_cmd_req.read())       r_ixr_cmd_fsm = IXR_CMD_READ_TRT;
     3680      else if(r_write_to_ixr_cmd_req.read())      r_ixr_cmd_fsm = IXR_CMD_WRITE_TRT;
    36723681      break;
    3673     ////////////////////////
     3682    //////////////////////
    36743683    case IXR_CMD_CAS_IDLE:
    3675       if(r_xram_rsp_to_ixr_cmd_req)      r_ixr_cmd_fsm = IXR_CMD_XRAM;
     3684      if     (r_xram_rsp_to_ixr_cmd_req.read())   r_ixr_cmd_fsm = IXR_CMD_XRAM_TRT;
    36763685#if ODCCP_NON_INCLUSIVE
    3677       else if(r_cleanup_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_CLEANUP_DATA;
     3686      else if(r_cleanup_to_ixr_cmd_req.read())
     3687      {
     3688        r_ixr_cmd_fsm = IXR_CMD_CLEANUP_DATA_SEND;
     3689        r_ixr_cmd_word = 0;
     3690      }
    36783691#else
    3679       else if(r_cleanup_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_TRT_LOCK;
    3680 #endif
    3681       else if(r_read_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_READ;
    3682       else if(r_write_to_ixr_cmd_req)    r_ixr_cmd_fsm = IXR_CMD_WRITE;
    3683       else if(r_cas_to_ixr_cmd_req)      r_ixr_cmd_fsm = IXR_CMD_CAS;
     3692      else if(r_cleanup_to_ixr_cmd_req)           r_ixr_cmd_fsm = IXR_CMD_CLEANUP_TRT;
     3693#endif
     3694      else if(r_config_to_ixr_cmd_req.read())     r_ixr_cmd_fsm = IXR_CMD_CONFIG_TRT;
     3695      else if(r_read_to_ixr_cmd_req.read())       r_ixr_cmd_fsm = IXR_CMD_READ_TRT;
     3696      else if(r_write_to_ixr_cmd_req.read())      r_ixr_cmd_fsm = IXR_CMD_WRITE_TRT;
     3697      else if(r_cas_to_ixr_cmd_req.read())        r_ixr_cmd_fsm = IXR_CMD_CAS_TRT;
    36843698      break;
    3685     ////////////////////////
     3699    ///////////////////////
    36863700    case IXR_CMD_XRAM_IDLE:
    36873701#if ODCCP_NON_INCLUSIVE
    3688       if(r_cleanup_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_CLEANUP_DATA;
     3702      if(r_cleanup_to_ixr_cmd_req.read())
     3703      {
     3704        r_ixr_cmd_fsm = IXR_CMD_CLEANUP_DATA_SEND;
     3705        r_ixr_cmd_word = 0;
     3706      }
    36893707#else
    3690       if(r_cleanup_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_TRT_LOCK;
    3691 #endif
    3692       else if(r_read_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_READ;
    3693       else if(r_write_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_WRITE;
    3694       else if(r_cas_to_ixr_cmd_req)      r_ixr_cmd_fsm = IXR_CMD_CAS;
    3695       else if(r_xram_rsp_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_XRAM;
     3708      if(r_cleanup_to_ixr_cmd_req)                r_ixr_cmd_fsm = IXR_CMD_CLEANUP_TRT;
     3709#endif
     3710      else if(r_config_to_ixr_cmd_req.read())     r_ixr_cmd_fsm = IXR_CMD_CONFIG_TRT;
     3711      else if(r_read_to_ixr_cmd_req.read())       r_ixr_cmd_fsm = IXR_CMD_READ_TRT;
     3712      else if(r_write_to_ixr_cmd_req.read())      r_ixr_cmd_fsm = IXR_CMD_WRITE_TRT;
     3713      else if(r_cas_to_ixr_cmd_req.read())        r_ixr_cmd_fsm = IXR_CMD_CAS_TRT;
     3714      else if(r_xram_rsp_to_ixr_cmd_req.read())   r_ixr_cmd_fsm = IXR_CMD_XRAM_TRT;
    36963715      break;
    36973716      ////////////////////////
    36983717    case IXR_CMD_CLEANUP_IDLE:
    3699       if(r_read_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_READ;
    3700       else if(r_write_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_WRITE;
    3701       else if(r_cas_to_ixr_cmd_req)      r_ixr_cmd_fsm = IXR_CMD_CAS;
    3702       else if(r_xram_rsp_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_XRAM;
     3718      if(r_config_to_ixr_cmd_req.read())          r_ixr_cmd_fsm = IXR_CMD_CONFIG_TRT;
     3719      else if(r_read_to_ixr_cmd_req.read())       r_ixr_cmd_fsm = IXR_CMD_READ_TRT;
     3720      else if(r_write_to_ixr_cmd_req.read())      r_ixr_cmd_fsm = IXR_CMD_WRITE_TRT;
     3721      else if(r_cas_to_ixr_cmd_req.read())        r_ixr_cmd_fsm = IXR_CMD_CAS_TRT;
     3722      else if(r_xram_rsp_to_ixr_cmd_req.read())   r_ixr_cmd_fsm = IXR_CMD_XRAM_TRT;
    37033723#if ODCCP_NON_INCLUSIVE
    3704       else if(r_cleanup_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_CLEANUP_DATA;
     3724      else if(r_cleanup_to_ixr_cmd_req.read())
     3725      {
     3726        r_ixr_cmd_fsm = IXR_CMD_CLEANUP_DATA_SEND;
     3727        r_ixr_cmd_word = 0;
     3728      }
    37053729#else
    3706       else if(r_cleanup_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_TRT_LOCK;
     3730      else if(r_cleanup_to_ixr_cmd_req.read())    r_ixr_cmd_fsm = IXR_CMD_CLEANUP_TRT;
    37073731#endif
    37083732      break;     
    3709 
     3733    /////////////////////////
     3734    case IXR_CMD_CONFIG_IDLE:
     3735      if     (r_read_to_ixr_cmd_req.read())       r_ixr_cmd_fsm = IXR_CMD_READ_TRT;
     3736      else if(r_write_to_ixr_cmd_req.read())      r_ixr_cmd_fsm = IXR_CMD_WRITE_TRT;
     3737      else if(r_cas_to_ixr_cmd_req.read())        r_ixr_cmd_fsm = IXR_CMD_CAS_TRT;
     3738      else if(r_xram_rsp_to_ixr_cmd_req.read())   r_ixr_cmd_fsm = IXR_CMD_XRAM_TRT;
     3739#if ODCCP_NON_INCLUSIVE
     3740      else if(r_cleanup_to_ixr_cmd_req.read())
     3741      {
     3742        r_ixr_cmd_fsm = IXR_CMD_CLEANUP_DATA_SEND;
     3743        r_ixr_cmd_word = 0;
     3744      }
     3745#else
     3746      else if(r_cleanup_to_ixr_cmd_req.read())    r_ixr_cmd_fsm = IXR_CMD_CLEANUP_TRT;
     3747#endif
     3748      else if(r_config_to_ixr_cmd_req.read())     r_ixr_cmd_fsm = IXR_CMD_CONFIG_TRT;
     3749      break;
     3750
     3751
     3752    //////////////////////
     3753    case IXR_CMD_READ_TRT:       // access TRT for a GET
     3754    {
     3755        if ( r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_CMD )
     3756        {
     3757            TransactionTabEntry entry = m_trt.read( r_read_to_ixr_cmd_index.read() );
     3758            r_ixr_cmd_address = entry.nline * (m_words<<2);
     3759            r_ixr_cmd_trdid   = r_read_to_ixr_cmd_index.read();
     3760            r_ixr_cmd_get     = true;
     3761            r_ixr_cmd_word    = 0;
     3762            r_ixr_cmd_fsm     = IXR_CMD_READ_SEND;
     3763            for( size_t i=0 ; i<m_words ; i++ ) r_ixr_cmd_wdata[i] = entry.wdata[i];
     3764
     3765#if DEBUG_MEMC_IXR_CMD
     3766if(m_debug)
     3767std::cout << "  <MEMC " << name() << " IXR_CMD_READ_TRT> TRT access"
     3768          << " index = " << std::dec << r_read_to_ixr_cmd_index.read()
     3769          << " / address = " << std::hex << (entry.nline*(m_words<<2)) << std::endl;
     3770#endif
     3771        }
     3772        break;
     3773    }
     3774    ///////////////////////
     3775    case IXR_CMD_WRITE_TRT:       // access TRT for a PUT or a GET
     3776    {
     3777        if ( r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_CMD )
     3778        {
     3779            TransactionTabEntry entry = m_trt.read( r_write_to_ixr_cmd_index.read() );
     3780            r_ixr_cmd_address = entry.nline * (m_words<<2);
     3781            r_ixr_cmd_trdid   = r_write_to_ixr_cmd_index.read();
     3782            r_ixr_cmd_get     = entry.xram_read;
     3783            r_ixr_cmd_word    = 0;
     3784            r_ixr_cmd_fsm     = IXR_CMD_WRITE_SEND;
     3785            for( size_t i=0 ; i<m_words ; i++ ) r_ixr_cmd_wdata[i] = entry.wdata[i];
     3786
     3787#if DEBUG_MEMC_IXR_CMD
     3788if(m_debug)
     3789std::cout << "  <MEMC " << name() << " IXR_CMD_WRITE_TRT> TRT access"
     3790          << " index = " << std::dec << r_write_to_ixr_cmd_index.read()
     3791          << " / address = " << std::hex << (entry.nline*(m_words<<2)) << std::endl;
     3792#endif
     3793        }
     3794        break;
     3795    }
    37103796    /////////////////////
    3711     case IXR_CMD_TRT_LOCK:
    3712     {
    3713         TransactionTabEntry entry;
    3714        
    3715         if(r_alloc_trt_fsm.read() != ALLOC_TRT_IXR_CMD) break;
    3716         entry.copy( m_trt.read(r_cleanup_to_ixr_cmd_trdid.read()));
    3717         for(size_t i=0; i < m_words; i++)
    3718         {
    3719           r_ixr_cmd_data[i] = entry.wdata[i];
    3720         }
    3721 
    3722         r_ixr_cmd_fsm = IXR_CMD_CLEANUP_DATA;
    3723         break;
    3724     }
    3725 
    3726     //////////////////       // send a get from READ FSM
    3727     case IXR_CMD_READ:
    3728     {
    3729       if(p_vci_ixr.cmdack)
    3730       {
    3731         r_ixr_cmd_fsm = IXR_CMD_READ_IDLE;
    3732         r_read_to_ixr_cmd_req = false;
     3797    case IXR_CMD_CAS_TRT:       // access TRT for a PUT or a GET
     3798    {
     3799        if ( r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_CMD )
     3800        {
     3801            TransactionTabEntry entry = m_trt.read( r_cas_to_ixr_cmd_index.read() );
     3802            r_ixr_cmd_address = entry.nline * (m_words<<2);
     3803            r_ixr_cmd_trdid   = r_cas_to_ixr_cmd_index.read();
     3804            r_ixr_cmd_get     = entry.xram_read;
     3805            r_ixr_cmd_word    = 0;
     3806            r_ixr_cmd_fsm     = IXR_CMD_CAS_SEND;
     3807            for( size_t i=0 ; i<m_words ; i++ ) r_ixr_cmd_wdata[i] = entry.wdata[i];
    37333808
    37343809#if DEBUG_MEMC_IXR_CMD
    37353810if(m_debug)
    3736 std::cout << "  <MEMC " << name() << " IXR_CMD_READ>"
    3737           << " Send a get request to xram / address = " << std::hex
    3738           << (addr_t)(r_read_to_ixr_cmd_nline.read()*m_words*4) << std::endl;
    3739 #endif
    3740       }
    3741       break;
    3742     }
    3743     ///////////////////
    3744     case IXR_CMD_WRITE:     // send a put or get from WRITE FSM
    3745     {
    3746       if(p_vci_ixr.cmdack)
    3747       {
    3748         if(r_write_to_ixr_cmd_write.read())   // PUT
    3749         {
    3750           if(r_ixr_cmd_cpt.read() == (m_words - 2))
    3751           {
    3752             r_ixr_cmd_cpt = 0;
    3753             r_ixr_cmd_fsm = IXR_CMD_WRITE_IDLE;
    3754             r_write_to_ixr_cmd_req = false;
    3755           }
    3756           else
    3757           {
    3758             r_ixr_cmd_cpt = r_ixr_cmd_cpt + 2;
    3759           }
     3811std::cout << "  <MEMC " << name() << " IXR_CMD_CAS_TRT> TRT access"
     3812          << " index = " << std::dec << r_cas_to_ixr_cmd_index.read()
     3813          << " / address = " << std::hex << (entry.nline*(m_words<<2)) << std::endl;
     3814#endif
     3815        }
     3816        break;
     3817    }
     3818    //////////////////////
     3819    case IXR_CMD_XRAM_TRT:       // access TRT for a PUT
     3820    {
     3821        if ( r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_CMD )
     3822        {
     3823            TransactionTabEntry entry = m_trt.read( r_xram_rsp_to_ixr_cmd_index.read() );
     3824            r_ixr_cmd_address = entry.nline * (m_words<<2);
     3825            r_ixr_cmd_trdid   = r_xram_rsp_to_ixr_cmd_index.read();
     3826            r_ixr_cmd_get     = false;
     3827            r_ixr_cmd_word    = 0;
     3828            r_ixr_cmd_fsm     = IXR_CMD_XRAM_SEND;
     3829            for( size_t i=0 ; i<m_words ; i++ ) r_ixr_cmd_wdata[i] = entry.wdata[i];
    37603830
    37613831#if DEBUG_MEMC_IXR_CMD
    37623832if(m_debug)
    3763 std::cout << "  <MEMC " << name() << " IXR_CMD_WRITE>"
    3764           << " Send a put request to xram / address = " << std::hex
    3765           << (addr_t)((r_write_to_ixr_cmd_nline.read() * m_words +
    3766                       r_ixr_cmd_cpt.read()) * 4 ) << std::endl;
    3767 #endif
    3768         }
    3769         else                                  // GET
    3770         {
    3771           r_ixr_cmd_fsm = IXR_CMD_WRITE_IDLE;
    3772           r_write_to_ixr_cmd_req = false;
     3833std::cout << "  <MEMC " << name() << " IXR_CMD_XRAM_TRT> TRT access"
     3834          << " index = " << std::dec << r_xram_rsp_to_ixr_cmd_index.read()
     3835          << " / address = " << std::hex << (entry.nline*(m_words<<2)) << std::endl;
     3836#endif
     3837        }
     3838        break;
     3839    }
     3840    //////////////////////
     3841    case IXR_CMD_CLEANUP_TRT:       // access TRT for a PUT
     3842    {
     3843        if ( r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_CMD )
     3844        {
     3845         
     3846            TransactionTabEntry entry = m_trt.read( r_cleanup_to_ixr_cmd_index.read() );
     3847            r_ixr_cmd_address = entry.nline * (m_words<<2);
     3848            r_ixr_cmd_trdid   = r_cleanup_to_ixr_cmd_index.read();
     3849            r_ixr_cmd_get     = false;
     3850            r_ixr_cmd_word    = 0;
     3851            r_ixr_cmd_fsm     = IXR_CMD_CLEANUP_DATA_SEND;
     3852            for( size_t i=0 ; i<m_words ; i++ ) r_ixr_cmd_wdata[i] = entry.wdata[i];
    37733853
    37743854#if DEBUG_MEMC_IXR_CMD
    37753855if(m_debug)
    3776 std::cout << "  <MEMC " << name() << " IXR_CMD_WRITE>"
    3777           << " Send a get request to xram / address = " << std::hex
    3778           << (addr_t)(r_write_to_ixr_cmd_nline.read()*m_words*4) << std::endl;
    3779 #endif
    3780         }
    3781       }
    3782       break;
    3783     }
    3784     /////////////////
    3785     case IXR_CMD_CAS:      // send a put or get command from CAS FSM
    3786     {
    3787       if(p_vci_ixr.cmdack)
    3788       {
    3789         if(r_cas_to_ixr_cmd_write.read()) // PUT
    3790         {
    3791           if(r_ixr_cmd_cpt.read() == (m_words - 2))
    3792           {
    3793             r_ixr_cmd_cpt = 0;
    3794             r_ixr_cmd_fsm = IXR_CMD_CAS_IDLE;
    3795             r_cas_to_ixr_cmd_req = false;
    3796           }
    3797           else
    3798           {
    3799             r_ixr_cmd_cpt = r_ixr_cmd_cpt + 2;
    3800           }
     3856std::cout << "  <MEMC " << name() << " IXR_CMD_CLEANUP_TRT> TRT access"
     3857          << " index = " << std::dec << r_cleanup_to_ixr_cmd_index.read()
     3858          << " / address = " << std::hex << (entry.nline*(m_words<<2)) << std::endl;
     3859#endif
     3860        }
     3861        break;
     3862    }
     3863    ////////////////////////
     3864    case IXR_CMD_CONFIG_TRT:       // access TRT for a PUT
     3865    {
     3866        if ( r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_CMD )
     3867        {
     3868            TransactionTabEntry entry = m_trt.read( r_config_to_ixr_cmd_index.read() );
     3869            r_ixr_cmd_address = entry.nline * (m_words<<2);
     3870            r_ixr_cmd_trdid   = r_config_to_ixr_cmd_index.read();
     3871            r_ixr_cmd_get     = false;
     3872            r_ixr_cmd_word    = 0;
     3873            r_ixr_cmd_fsm     = IXR_CMD_CONFIG_SEND;
     3874            for( size_t i=0 ; i<m_words ; i++ ) r_ixr_cmd_wdata[i] = entry.wdata[i];
    38013875
    38023876#if DEBUG_MEMC_IXR_CMD
    38033877if(m_debug)
    3804 std::cout << "  <MEMC " << name() << " IXR_CMD_CAS>"
    3805           << " Send a put request to xram / address = " << std::hex
    3806           << (addr_t)( (r_cas_to_ixr_cmd_nline.read() * m_words +
    3807                       r_ixr_cmd_cpt.read()) * 4 ) << std::endl;
    3808 #endif
    3809         }
    3810         else                            // GET
    3811         {
    3812           r_ixr_cmd_fsm = IXR_CMD_CAS_IDLE;
    3813           r_cas_to_ixr_cmd_req = false;
     3878std::cout << "  <MEMC " << name() << " IXR_CMD_CONFIG_TRT> TRT access"
     3879          << " index = " << std::dec << r_config_to_ixr_cmd_index.read()
     3880          << " / address = " << std::hex << (entry.nline*(m_words<<2)) << std::endl;
     3881#endif
     3882        }
     3883        break;
     3884    }
     3885
     3886    ///////////////////////
     3887    case IXR_CMD_READ_SEND:      // send a get from READ FSM
     3888    {
     3889        if(p_vci_ixr.cmdack)
     3890        {
     3891            r_ixr_cmd_fsm         = IXR_CMD_READ_IDLE;
     3892            r_read_to_ixr_cmd_req = false;
    38143893
    38153894#if DEBUG_MEMC_IXR_CMD
    38163895if(m_debug)
    3817 std::cout << "  <MEMC " << name() << " IXR_CMD_CAS>"
    3818           << " Send a get request to xram / address = " << std::hex
    3819           << (addr_t)(r_cas_to_ixr_cmd_nline.read()*m_words*4) << std::endl;
    3820 #endif
    3821         }
    3822       }
    3823       break;
    3824     }
    3825     //////////////////
    3826     case IXR_CMD_XRAM:     // send a put from XRAM_RSP FSM
    3827     {
    3828       if(p_vci_ixr.cmdack)
    3829       {
    3830         if(r_ixr_cmd_cpt.read() == (m_words - 2))
    3831         {
    3832           r_ixr_cmd_cpt = 0;
    3833           r_ixr_cmd_fsm = IXR_CMD_XRAM_IDLE;
    3834           r_xram_rsp_to_ixr_cmd_req = false;
    3835         }
    3836         else
    3837         {
    3838           r_ixr_cmd_cpt = r_ixr_cmd_cpt + 2;
    3839         }
     3896std::cout << "  <MEMC " << name() << " IXR_CMD_READ_SEND> GET request:" << std::hex
     3897          << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2) << std::endl;
     3898#endif
     3899        }
     3900        break;
     3901    }
     3902    ////////////////////////
     3903    case IXR_CMD_WRITE_SEND:     // send a put or get from WRITE FSM
     3904    {
     3905        if(p_vci_ixr.cmdack)
     3906        {
     3907            if(r_write_to_ixr_cmd_put.read())   // PUT
     3908            {
     3909                if(r_ixr_cmd_word.read() == (m_words - 2))
     3910                {
     3911                    r_ixr_cmd_fsm          = IXR_CMD_WRITE_IDLE;
     3912                    r_write_to_ixr_cmd_req = false;
     3913                }
     3914                else
     3915                {
     3916                    r_ixr_cmd_word = r_ixr_cmd_word.read() + 2;
     3917                }
    38403918
    38413919#if DEBUG_MEMC_IXR_CMD
    38423920if(m_debug)
    3843 std::cout << "  <MEMC " << name() << " IXR_CMD_XRAM>"
    3844           << " Send a put request to xram / address = " << std::hex
    3845           << (addr_t)( (r_xram_rsp_to_ixr_cmd_nline.read() * m_words +
    3846                        r_ixr_cmd_cpt.read()) * 4 ) << std::endl;
    3847 #endif
    3848       }
    3849       break;
     3921std::cout << "  <MEMC " << name() << " IXR_CMD_WRITE_SEND> PUT request:" << std::hex
     3922          << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2) << std::endl;
     3923#endif
     3924            }
     3925            else                                  // GET
     3926            {
     3927                r_ixr_cmd_fsm          = IXR_CMD_WRITE_IDLE;
     3928                r_write_to_ixr_cmd_req = false;
     3929
     3930#if DEBUG_MEMC_IXR_CMD
     3931if(m_debug)
     3932std::cout << "  <MEMC " << name() << " IXR_CMD_WRITE_SEND> GET request:" << std::hex
     3933          << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2) << std::endl;
     3934#endif
     3935            }
     3936        }
     3937        break;
     3938    }
     3939    //////////////////////
     3940    case IXR_CMD_CAS_SEND:      // send a put or get command from CAS FSM
     3941    {
     3942        if(p_vci_ixr.cmdack)
     3943        {
     3944            if(r_cas_to_ixr_cmd_put.read()) // PUT
     3945            {
     3946                if(r_ixr_cmd_word.read() == (m_words - 2))
     3947                {
     3948                    r_ixr_cmd_fsm        = IXR_CMD_CAS_IDLE;
     3949                    r_cas_to_ixr_cmd_req = false;
     3950                }
     3951                else
     3952                {
     3953                    r_ixr_cmd_word = r_ixr_cmd_word.read() + 2;
     3954                }
     3955
     3956#if DEBUG_MEMC_IXR_CMD
     3957if(m_debug)
     3958std::cout << "  <MEMC " << name() << " IXR_CMD_CAS_SEND> PUT request:" << std::hex
     3959          << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2) << std::endl;
     3960#endif
     3961            }
     3962            else                            // GET
     3963            {
     3964                r_ixr_cmd_fsm        = IXR_CMD_CAS_IDLE;
     3965                r_cas_to_ixr_cmd_req = false;
     3966
     3967#if DEBUG_MEMC_IXR_CMD
     3968if(m_debug)
     3969std::cout << "  <MEMC " << name() << " IXR_CMD_CAS_SEND> GET request:" << std::hex
     3970          << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2) << std::endl;
     3971#endif
     3972            }
     3973        }
     3974        break;
     3975    }
     3976    ///////////////////////
     3977    case IXR_CMD_XRAM_SEND:     // send a put from XRAM_RSP FSM
     3978    {
     3979        if(p_vci_ixr.cmdack.read())
     3980        {
     3981            if(r_ixr_cmd_word.read() == (m_words - 2))
     3982            {
     3983                r_ixr_cmd_fsm = IXR_CMD_XRAM_IDLE;
     3984                r_xram_rsp_to_ixr_cmd_req = false;
     3985            }
     3986            else
     3987            {
     3988                r_ixr_cmd_word = r_ixr_cmd_word.read() + 2;
     3989            }
     3990#if DEBUG_MEMC_IXR_CMD
     3991if(m_debug)
     3992std::cout << "  <MEMC " << name() << " IXR_CMD_XRAM_SEND> PUT request:" << std::hex
     3993          << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2) << std::endl;
     3994#endif
     3995        }
     3996        break;
    38503997    }
    38513998
    38523999      ////////////////////////
    3853     case IXR_CMD_CLEANUP_DATA:     // send a put command to XRAM
    3854       if(p_vci_ixr.cmdack)
    3855       {
    3856         if(r_ixr_cmd_cpt.read() == (m_words - 2))
    3857         {
    3858           r_ixr_cmd_cpt = 0;
     4000    case IXR_CMD_CLEANUP_DATA_SEND:     // send a put command to XRAM
     4001    {
     4002      if(p_vci_ixr.cmdack.read())
     4003      {
     4004        /*ODCCP*/ //std::cout << "IXR_CMD_CLEANUP_DATA_SEND STATE at cycle : " << std::dec << m_cpt_cycles << std::endl;
     4005        if(r_ixr_cmd_word.read() == (m_words - 2))
     4006        {
     4007          /*ODCCP*/ //std::cout << "IXR_CMD_CLEANUP_DATA_SEND GO TO IXR_CMD_CLEANUP_IDLE" << std::endl;
    38594008          r_ixr_cmd_fsm = IXR_CMD_CLEANUP_IDLE;
    38604009          r_cleanup_to_ixr_cmd_req = false;
     4010          //r_ixr_cmd_word = 0;
    38614011          //r_xram_rsp_to_ixr_cmd_inval_ncc_pending = false;
    38624012        }
    38634013        else
    38644014        {
    3865           r_ixr_cmd_cpt = r_ixr_cmd_cpt.read() + 2;
     4015          r_ixr_cmd_word = r_ixr_cmd_word.read() + 2;
    38664016        }
    38674017
     
    38694019        if(m_debug)
    38704020        {
    3871           std::cout << "  <MEMC " << name() << ".IXR_CMD_CLEANUP_DATA> Send a put request to xram" << std::endl;
     4021          std::cout << "  <MEMC " << name() << ".IXR_CMD_CLEANUP_DATA_SEND> Send a put request to xram" << std::endl;
    38724022        }
    38734023#endif
    38744024      }
    38754025      break;
    3876 
     4026    }
     4027
     4028    /////////////////////////
     4029    case IXR_CMD_CONFIG_SEND:     // send a put from CONFIG FSM
     4030    {
     4031        if(p_vci_ixr.cmdack.read())
     4032        {
     4033            if(r_ixr_cmd_word.read() == (m_words - 2))
     4034            {
     4035                r_ixr_cmd_fsm = IXR_CMD_CONFIG_IDLE;
     4036                r_config_to_ixr_cmd_req = false;
     4037            }
     4038            else
     4039            {
     4040                r_ixr_cmd_word = r_ixr_cmd_word.read() + 2;
     4041            }
     4042
     4043#if DEBUG_MEMC_IXR_CMD
     4044if(m_debug)
     4045std::cout << "  <MEMC " << name() << " IXR_CMD_CONFIG_SEND> PUT request:" << std::hex
     4046          << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2) << std::endl;
     4047#endif
     4048        }
     4049        break;
     4050    }
    38774051  } // end switch r_ixr_cmd_fsm
    38784052
     
    38814055  ////////////////////////////////////////////////////////////////////////////
    38824056  // The IXR_RSP FSM receives the response packets from the XRAM,
    3883   // for both put transaction, and get transaction.
     4057  // for both PUT transaction, and GET transaction.
    38844058  //
    3885   // - A response to a put request is a single-cell VCI packet.
    3886   // The Transaction Tab index is contained in the RTRDID field.
     4059  // - A response to a PUT request is a single-cell VCI packet.
     4060  // The TRT index is contained in the RTRDID field.
    38874061  // The FSM takes the lock protecting the TRT, and the corresponding
    3888   // entry is erased.
     4062  // entry is erased. If an acknowledge was required (in case of software SYNC)
     4063  // the r_config_rsp_lines counter is decremented. 
    38894064  //
    3890   // - A response to a get request is a multi-cell VCI packet.
    3891   // The Transaction Tab index is contained in the RTRDID field.
     4065  // - A response to a GET request is a multi-cell VCI packet.
     4066  // The TRT index is contained in the RTRDID field.
    38924067  // The N cells contain the N words of the cache line in the RDATA field.
    38934068  // The FSM takes the lock protecting the TRT to store the line in the TRT
    38944069  // (taking into account the write requests already stored in the TRT).
    3895   // When the line is completely written, the corresponding rok signal is set.
     4070  // When the line is completely written, the r_ixr_rsp_to_xram_rsp_rok[index] 
     4071  // signal is set to inform the XRAM_RSP FSM.
    38964072  ///////////////////////////////////////////////////////////////////////////////
     4073
     4074//std::cout << std::endl << "ixr_rsp_fsm" << std::endl;
    38974075
    38984076  switch(r_ixr_rsp_fsm.read())
    38994077  {
    3900     //////////////////
    3901     case IXR_RSP_IDLE:  // test transaction type: PUT/GET
    3902     {
    3903       if(p_vci_ixr.rspval.read())
    3904       {
    3905         r_ixr_rsp_cpt   = 0;
    3906         r_ixr_rsp_trt_index = p_vci_ixr.rtrdid.read();
    3907         if(p_vci_ixr.reop.read() and !(p_vci_ixr.rerror.read() &0x1))   // PUT transaction
    3908         {
    3909           r_ixr_rsp_fsm = IXR_RSP_ACK;
     4078      //////////////////
     4079      case IXR_RSP_IDLE:  // test transaction type: PUT/GET
     4080      {
     4081          if(p_vci_ixr.rspval.read())
     4082          {
     4083              r_ixr_rsp_cpt       = 0;
     4084              r_ixr_rsp_trt_index = p_vci_ixr.rtrdid.read();
     4085
     4086              assert( ((p_vci_ixr.rerror.read() & 0x1) == 0) and
     4087              "MEMC ERROR in IXR_RSP state: XRAM response error !");
     4088
     4089              if(p_vci_ixr.reop.read())   // PUT
     4090              {
     4091#if ODCCP_NON_INCLUSIVE
     4092                  if (p_vci_ixr.rtrdid.read() == m_trt_lines)
     4093                    r_ixr_rsp_fsm = IXR_RSP_ACK;
     4094                  else
     4095                    r_ixr_rsp_fsm = IXR_RSP_TRT_ERASE;
     4096#else
     4097                  r_ixr_rsp_fsm = IXR_RSP_TRT_ERASE;
     4098#endif
    39104099
    39114100#if DEBUG_MEMC_IXR_RSP
     
    39144103          << " IXR_RSP_IDLE> Response from XRAM to a put transaction" << std::endl;
    39154104#endif
    3916         }
    3917         else                                                         // GET transaction
    3918         {
    3919           r_ixr_rsp_fsm = IXR_RSP_TRT_READ;
     4105              }
     4106              else                       // GET
     4107              {
     4108                  r_ixr_rsp_fsm = IXR_RSP_TRT_READ;
    39204109
    39214110#if DEBUG_MEMC_IXR_RSP
     
    39244113          << " IXR_RSP_IDLE> Response from XRAM to a get transaction" << std::endl;
    39254114#endif
    3926         }
    3927       }
    3928       break;
    3929     }
    3930     /////////////////
    3931     case IXR_RSP_ACK:        // Aknowledge the VCI response for a PUT
    3932     {
    3933 #if ODCCP_NON_INCLUSIVE
    3934       if(p_vci_ixr.rspval.read())
    3935       {
    3936         if (r_ixr_rsp_trt_index.read() == m_trt_lines)
    3937           r_ixr_rsp_fsm = IXR_RSP_IDLE;
    3938         else
    3939           r_ixr_rsp_fsm = IXR_RSP_TRT_ERASE;
    3940       }
    3941 #else
    3942       if(p_vci_ixr.rspval.read()) r_ixr_rsp_fsm = IXR_RSP_TRT_ERASE;
    3943 #endif
    3944 
    3945 #if DEBUG_MEMC_IXR_RSP
    3946 if(m_debug)
    3947 std::cout << "  <MEMC " << name() << " IXR_RSP_ACK>" << std::endl;
    3948 #endif
    3949       break;
    3950     }
    3951     ////////////////////////
    3952     case IXR_RSP_TRT_ERASE:   // erase the entry in the TRT
    3953     {
    3954       if(r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP)
    3955       {
    3956         m_trt.erase(r_ixr_rsp_trt_index.read());
     4115              }
     4116          }
     4117          break;
     4118      }
     4119      ////////////////////////
     4120      case IXR_RSP_ACK:     // Acknowledge PUT transaction
     4121      {
    39574122        r_ixr_rsp_fsm = IXR_RSP_IDLE;
     4123        break;
     4124      }
     4125      ////////////////////////
     4126      case IXR_RSP_TRT_ERASE:   // erase the entry in the TRT
     4127                                // decrease the line counter if config request
     4128      {
     4129          if(r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP)
     4130          {
     4131              size_t  index = r_ixr_rsp_trt_index.read();
     4132              if (m_trt.is_config(index) ) r_config_rsp_lines = r_config_rsp_lines.read() - 1;
     4133              m_trt.erase(index);
     4134              r_ixr_rsp_fsm = IXR_RSP_IDLE;
    39584135
    39594136#if DEBUG_MEMC_IXR_RSP
     
    39624139          << r_ixr_rsp_trt_index.read() << std::endl;
    39634140#endif
    3964       m_cpt_ixr_fsm_n_trt_lock++;
    3965       }
    3966 
    3967       m_cpt_ixr_fsm_trt_lock++;
    3968 
    3969       break;
    3970     }
    3971     //////////////////////
    3972     case IXR_RSP_TRT_READ:    // write a 64 bits data in the TRT
    3973     {
    3974       if((r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP) and  p_vci_ixr.rspval)
    3975       {
    3976         size_t      index    = r_ixr_rsp_trt_index.read();
    3977         bool        eop      = p_vci_ixr.reop.read();
    3978         wide_data_t data     = p_vci_ixr.rdata.read();
    3979         bool        error    = ((p_vci_ixr.rerror.read() & 0x1) == 1);
    3980 
    3981         assert(((eop == (r_ixr_rsp_cpt.read() == (m_words-2))) or p_vci_ixr.rerror.read())
    3982                and "Error in VCI_MEM_CACHE : invalid length for a response from XRAM");
    3983 
    3984         m_trt.write_rsp( index,
    3985                          r_ixr_rsp_cpt.read(),
    3986                          data,
    3987                          error);
    3988 
    3989         r_ixr_rsp_cpt = r_ixr_rsp_cpt.read() + 2;
    3990 
    3991         if(eop)
    3992         {
    3993           r_ixr_rsp_to_xram_rsp_rok[r_ixr_rsp_trt_index.read()]=true;
    3994           /*if(p_vci_ixr.rpktid.read()&0xF == 0x9)
    3995             r_ixr_rsp_to_xram_rsp_no_coherent[r_ixr_rsp_trt_index.read()] = true;
    3996           else
    3997             r_ixr_rsp_to_xram_rsp_no_coherent[r_ixr_rsp_trt_index.read()] = false;*/
    3998           r_ixr_rsp_fsm = IXR_RSP_IDLE;
    3999         }
     4141          }
     4142          break;
     4143      }
     4144      //////////////////////
     4145      case IXR_RSP_TRT_READ:    // write a 64 bits data word in TRT
     4146      {
     4147          if((r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP) and  p_vci_ixr.rspval)
     4148          {
     4149              size_t      index    = r_ixr_rsp_trt_index.read();
     4150              size_t      word     = r_ixr_rsp_cpt.read();
     4151              bool        eop      = p_vci_ixr.reop.read();
     4152              wide_data_t data     = p_vci_ixr.rdata.read();
     4153              bool        error    = ((p_vci_ixr.rerror.read() & 0x1) == 1);
     4154
     4155              assert(((eop == (word == (m_words-2))) or error) and
     4156              "MEMC ERROR in IXR_RSP_TRT_READ state : invalid response from XRAM");
     4157
     4158              m_trt.write_rsp( index,
     4159                               word,
     4160                               data );
     4161
     4162              r_ixr_rsp_cpt = word + 2;
     4163
     4164              if(eop)
     4165              {
     4166                r_ixr_rsp_to_xram_rsp_rok[r_ixr_rsp_trt_index.read()]=true;
     4167                /*if(p_vci_ixr.rpktid.read()&0xF == 0x9)
     4168                  r_ixr_rsp_to_xram_rsp_no_coherent[r_ixr_rsp_trt_index.read()] = true;
     4169                  else
     4170                  r_ixr_rsp_to_xram_rsp_no_coherent[r_ixr_rsp_trt_index.read()] = false;*/
     4171                r_ixr_rsp_fsm = IXR_RSP_IDLE;
     4172              }
    40004173
    40014174#if DEBUG_MEMC_IXR_RSP
    40024175if(m_debug)
    4003 std::cout << "  <MEMC " << name() << " IXR_RSP_TRT_READ> Writing a word in TRT : "
     4176std::cout << "  <MEMC " << name() << " IXR_RSP_TRT_READ> Writing 2 words in TRT : "
    40044177          << " index = " << std::dec << index
    4005           << " / word = " << r_ixr_rsp_cpt.read()
     4178          << " / word = " << word
    40064179          << " / data = " << std::hex << data << std::endl;
    40074180#endif
    4008       m_cpt_ixr_fsm_n_trt_lock++;
    4009       }
    4010       m_cpt_ixr_fsm_trt_lock++;
    4011       break;
    4012     }
     4181          }
     4182          break;
     4183      }
    40134184  } // end swich r_ixr_rsp_fsm
    40144185
     
    40164187  //                XRAM_RSP FSM
    40174188  ////////////////////////////////////////////////////////////////////////////
    4018   // The XRAM_RSP FSM handles the incoming cache lines from the XRAM.
     4189  // The XRAM_RSP FSM handles the incoming cache lines after an XRAM GET.
    40194190  // The cache line has been written in the TRT by the IXR_CMD_FSM.
    40204191  // As the IXR_RSP FSM and the XRAM_RSP FSM are running in parallel,
    4021   // there is as many flip-flops r_ixr_rsp_to_xram_rsp_rok[i]
    4022   // as the number of entries in the TRT, that are handled with
    4023   // a round-robin priority...
     4192  // there is as many flip-flops r_ixr_rsp_to_xram_rsp_rok[i] as the number
     4193  // of entries in the TRT, that are handled with a round-robin priority...
    40244194  //
    4025   // When a response is available, the corresponding TRT entry
    4026   // is copied in a local buffer to be written in the cache.
    4027   // The FSM takes the lock protecting the TRT, and the lock protecting the DIR.
    4028   // It selects a cache slot and writes the line in the cache.
     4195  // The FSM takes the lock protecting TRT, and the lock protecting DIR.
     4196  // The selected TRT entry is copied in the local buffer r_xram_rsp_trt_buf.
     4197  // It selects a cache slot and save the victim line in another local buffer
     4198  // r_xram_rsp_victim_***.
     4199  // It writes the line extracted from TRT in the cache.
    40294200  // If it was a read MISS, the XRAM_RSP FSM send a request to the TGT_RSP
    40304201  // FSM to return the cache line to the registered processor.
     
    40364207  ///////////////////////////////////////////////////////////////////////////////
    40374208
     4209//std::cout << std::endl << "xram_rsp_fsm" << std::endl;
     4210
    40384211  switch(r_xram_rsp_fsm.read())
    40394212  {
     
    40414214    case XRAM_RSP_IDLE: // scan the XRAM responses / select a TRT index (round robin)
    40424215    {
    4043       size_t ptr   = r_xram_rsp_trt_index.read();
    4044       size_t lines = m_trt_lines;
    4045      
    4046       for(size_t i=0 ; i<lines ; i++)
    4047       {
    4048         size_t index = (i+ptr+1) %lines;
    4049         if(r_ixr_rsp_to_xram_rsp_rok[index])
    4050         {
    4051           r_xram_rsp_trt_index             = index;
    4052           r_ixr_rsp_to_xram_rsp_rok[index] = false;
    4053           r_xram_rsp_fsm                   = XRAM_RSP_DIR_LOCK;
     4216        size_t old   = r_xram_rsp_trt_index.read();
     4217        size_t lines = m_trt_lines;
     4218        for(size_t i=0 ; i<lines ; i++)
     4219        {
     4220            size_t index = (i+old+1) %lines;
     4221            if(r_ixr_rsp_to_xram_rsp_rok[index])
     4222            {
     4223                r_xram_rsp_trt_index             = index;
     4224                r_ixr_rsp_to_xram_rsp_rok[index] = false;
     4225                r_xram_rsp_fsm                   = XRAM_RSP_DIR_LOCK;
    40544226
    40554227#if DEBUG_MEMC_XRAM_RSP
     
    40594231          << " index = " << std::dec << index << std::endl;
    40604232#endif
    4061           break;
    4062         }
    4063       }
    4064       break;
     4233                break;
     4234            }
     4235        }
     4236        break;
    40654237    }
    40664238    ///////////////////////
     
    40684240                            // Copy the TRT entry in a local buffer
    40694241    {
    4070       if((r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP) and
    4071           (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP))
    4072       {
    4073         // copy the TRT entry in the r_xram_rsp_trt_buf local buffer
    4074         size_t  index = r_xram_rsp_trt_index.read();
    4075         r_xram_rsp_trt_buf.copy( m_trt.read(index) );
    4076 
    4077         r_xram_rsp_fsm = XRAM_RSP_TRT_COPY;
     4242        if( (r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP) and
     4243            (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP) )
     4244        {
     4245            // copy the TRT entry in the r_xram_rsp_trt_buf local buffer
     4246            size_t  index = r_xram_rsp_trt_index.read();
     4247            r_xram_rsp_trt_buf.copy( m_trt.read(index) );
     4248            r_xram_rsp_fsm = XRAM_RSP_TRT_COPY;
    40784249
    40794250#if DEBUG_MEMC_XRAM_RSP
     
    40824253          << " Get access to DIR and TRT" << std::endl;
    40834254#endif
    4084         m_cpt_xram_rsp_fsm_n_dir_lock++;
    4085         m_cpt_xram_rsp_fsm_n_trt_lock++;
    4086       }
    4087       m_cpt_xram_rsp_fsm_dir_lock++;
    4088       m_cpt_xram_rsp_fsm_trt_lock++;
    4089       break;
     4255        }
     4256        break;
    40904257    }
    40914258    ///////////////////////
     
    40934260                            // and copy it in a local buffer
    40944261    {
    4095       if ( (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP) and
    4096            (r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP) )
    4097       {
     4262        assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP) and
     4263        "MEMC ERROR in XRAM_RSP_TRT_COPY state: Bad DIR allocation");
     4264
     4265        assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP) and
     4266        "MEMC ERROR in XRAM_RSP_TRT_COPY state: Bad TRT allocation");
     4267
    40984268        // selects & extracts a victim line from cache
    40994269        size_t way = 0;
     
    41084278#endif
    41094279
    4110         // copy the victim line in a local buffer
     4280        // copy the victim line in a local buffer (both data dir)
    41114281        m_cache_data.read_line(way, set, r_xram_rsp_victim_data);
    41124282
    41134283        r_xram_rsp_victim_copy      = victim.owner.srcid;
    4114 
    4115 #if L1_MULTI_CACHE
    4116         r_xram_rsp_victim_copy_cache= victim.owner.cache_id;
    4117 #endif
    41184284       
    41194285        r_xram_rsp_victim_coherent  = victim.coherent;
     
    41284294        r_xram_rsp_victim_dirty     = victim.dirty;
    41294295
    4130 
    4131         if(!r_xram_rsp_trt_buf.rerror)
    4132         {
    4133 #if ODCCP_NON_INCLUSIVE
    4134           r_xram_rsp_fsm = XRAM_RSP_INVAL_LOCK;
    4135 #else
    4136           /*ODCCP*/ //if victim is no coherent and there is an inval no coherent pending we wait
    4137           /*if(!victim.coherent and r_xram_rsp_to_ixr_cmd_inval_ncc_pending.read())
    4138           {
    4139             r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT;
    4140           }
    4141           else
    4142           {*/
    4143             r_xram_rsp_fsm = XRAM_RSP_INVAL_LOCK;
    4144          //}
    4145 #endif
    4146         }
    4147         else
    4148         {
    4149           r_xram_rsp_fsm = XRAM_RSP_ERROR_ERASE;
    4150         }
     4296        if( not r_xram_rsp_trt_buf.rerror ) r_xram_rsp_fsm = XRAM_RSP_IVT_LOCK;
     4297        else                                r_xram_rsp_fsm = XRAM_RSP_ERROR_ERASE;
    41514298
    41524299#if DEBUG_MEMC_XRAM_RSP
    41534300if(m_debug)
    41544301std::cout << "  <MEMC " << name() << " XRAM_RSP_TRT_COPY>"
    4155           << " Select a slot: "
     4302          << " Select a victim slot: "
    41564303          << " way = " << std::dec << way
    41574304          << " / set = " << set
     
    41604307          << " / inval_required = " << inval << std::endl;
    41614308#endif
    4162       }
    4163       else
    4164       {
    4165         std::cout << "VCI_MEM_CACHE ERROR " << name() << " XRAM_RSP_TRT_COPY"
    4166                   << " bad TRT or DIR allocation" << std::endl;
    4167         exit(0);
    4168       }
    4169       break;
    4170     }
    4171     /////////////////////////
    4172     case XRAM_RSP_INVAL_LOCK: // Take the IVT lock to check a possible pending inval
    4173     {
    4174       if(r_alloc_ivt_fsm == ALLOC_IVT_XRAM_RSP)
    4175       {
    4176         size_t index = 0;
    4177         if(m_ivt.search_inval(r_xram_rsp_trt_buf.nline, index))  // pending inval
    4178         {
    4179           r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT;
     4309        break;
     4310    }
     4311    ///////////////////////
     4312    case XRAM_RSP_IVT_LOCK:   // Keep DIR and TRT locks and take the IVT lock
     4313                              // to check a possible pending inval
     4314    {
     4315        assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP) and
     4316        "MEMC ERROR in XRAM_RSP_IVT_LOCK state: Bad DIR allocation");
     4317
     4318        assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP) and
     4319        "MEMC ERROR in XRAM_RSP_IVT_LOCK state: Bad TRT allocation");
     4320
     4321        if(r_alloc_ivt_fsm == ALLOC_IVT_XRAM_RSP)
     4322        {
     4323            size_t index = 0;
     4324            if(m_ivt.search_inval(r_xram_rsp_trt_buf.nline, index))  // pending inval
     4325            {
     4326                r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT;
    41804327
    41814328#if DEBUG_MEMC_XRAM_RSP
    41824329if(m_debug)
    4183 std::cout << "  <MEMC " << name() << " XRAM_RSP_INVAL_LOCK>"
     4330std::cout << "  <MEMC " << name() << " XRAM_RSP_IVT_LOCK>"
    41844331          << " Get acces to IVT, but line invalidation registered"
    4185           << " / nline = " << std::hex << r_xram_rsp_trt_buf.nline
     4332          << " / address = " << std::hex << r_xram_rsp_trt_buf.nline*m_words*4
    41864333          << " / index = " << std::dec << index << std::endl;
    41874334#endif
    41884335
    4189         }
    4190         else if(m_ivt.is_full() and r_xram_rsp_victim_inval.read()) // IVT full
    4191         {
    4192           r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT;
     4336            }
     4337            else if(m_ivt.is_full() and r_xram_rsp_victim_inval.read()) // IVT full
     4338            {
     4339                r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT;
    41934340
    41944341#if DEBUG_MEMC_XRAM_RSP
    41954342if(m_debug)
    4196 std::cout << "  <MEMC " << name() << " XRAM_RSP_INVAL_LOCK>"
     4343std::cout << "  <MEMC " << name() << " XRAM_RSP_IVT_LOCK>"
    41974344          << " Get acces to IVT, but inval required and IVT full" << std::endl;
    41984345#endif
    4199         }
    4200         else
    4201         {
    4202           r_xram_rsp_fsm = XRAM_RSP_DIR_UPDT;
     4346            }
     4347            else
     4348            {
     4349                r_xram_rsp_fsm = XRAM_RSP_DIR_UPDT;
    42034350
    42044351#if DEBUG_MEMC_XRAM_RSP
    42054352if(m_debug)
    4206 std::cout << "  <MEMC " << name() << " XRAM_RSP_INVAL_LOCK>"
    4207           << " Get acces to IVT" << std::endl;
    4208 #endif
    4209         }
    4210         m_cpt_xram_rsp_fsm_n_upt_lock++;
    4211       }
    4212 
    4213       m_cpt_xram_rsp_fsm_upt_lock++;
    4214 
    4215       break;
     4353std::cout << "  <MEMC " << name() << " XRAM_RSP_IVT_LOCK>"
     4354          << " Get acces to IVT / no pending inval request" << std::endl;
     4355#endif
     4356            }
     4357        }
     4358        break;
    42164359    }
    42174360    /////////////////////////
     
    42244367          << " Release all locks and retry" << std::endl;
    42254368#endif
    4226       r_xram_rsp_fsm = XRAM_RSP_DIR_LOCK;
    4227       break;
     4369        r_xram_rsp_fsm = XRAM_RSP_DIR_LOCK;
     4370        break;
    42284371    }
    42294372    ///////////////////////
    4230     case XRAM_RSP_DIR_UPDT:   // updates the cache (both data & directory)
    4231                               // and possibly set an inval request in IVT
    4232     {
    4233       // check if this is an instruction read, this means pktid is either
    4234       // TYPE_READ_INS_UNC   0bX010 with TSAR encoding
    4235       // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
    4236       bool inst_read = (r_xram_rsp_trt_buf.pktid & 0x2) and r_xram_rsp_trt_buf.proc_read;
    4237 
    4238       // check if this is a cached read, this means pktid is either
    4239       // TYPE_READ_DATA_MISS 0bX001 with TSAR encoding
    4240       // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
    4241       bool cached_read = (r_xram_rsp_trt_buf.pktid & 0x1) and r_xram_rsp_trt_buf.proc_read;
    4242 
    4243       bool dirty = false;
    4244 
    4245       // update cache data
    4246       size_t set   = r_xram_rsp_victim_set.read();
    4247       size_t way   = r_xram_rsp_victim_way.read();
    4248       for(size_t word=0; word<m_words ; word++)
    4249       {
    4250         m_cache_data.write(way, set, word, r_xram_rsp_trt_buf.wdata[word]);
    4251 
    4252         dirty = dirty or (r_xram_rsp_trt_buf.wdata_be[word] != 0);
    4253 
    4254         if(m_monitor_ok)
    4255         {
    4256           addr_t address = r_xram_rsp_trt_buf.nline<<6 | word<<2;
    4257           check_monitor( address, r_xram_rsp_trt_buf.wdata[word], false);
    4258         }
    4259       }
     4373    case XRAM_RSP_DIR_UPDT:   // updates the cache (both data & directory),
     4374                              // erases the TRT entry if victim not dirty,
     4375                              // and set inval request in IVT if required
     4376    {
     4377        assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP) and
     4378        "MEMC ERROR in XRAM_RSP_DIR_UPDT state: Bad DIR allocation");
     4379
     4380        assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP) and
     4381        "MEMC ERROR in XRAM_RSP_DIR_UPDT state: Bad TRT allocation");
     4382
     4383        assert( (r_alloc_ivt_fsm.read() == ALLOC_IVT_XRAM_RSP) and
     4384        "MEMC ERROR in XRAM_RSP_DIR_UPDT state: Bad IVT allocation");
     4385
     4386        // check if this is an instruction read, this means pktid is either
     4387        // TYPE_READ_INS_UNC   0bX010 with TSAR encoding
     4388        // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
     4389        bool inst_read = (r_xram_rsp_trt_buf.pktid & 0x2) and r_xram_rsp_trt_buf.proc_read;
     4390
     4391        // check if this is a cached read, this means pktid is either
     4392        // TYPE_READ_DATA_MISS 0bX001 with TSAR encoding
     4393        // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
     4394        bool cached_read = (r_xram_rsp_trt_buf.pktid & 0x1) and r_xram_rsp_trt_buf.proc_read;
     4395
     4396        bool dirty = false;
     4397
     4398        // update cache data
     4399        size_t set   = r_xram_rsp_victim_set.read();
     4400        size_t way   = r_xram_rsp_victim_way.read();
     4401
     4402        for(size_t word=0; word<m_words ; word++)
     4403        {
     4404            m_cache_data.write(way, set, word, r_xram_rsp_trt_buf.wdata[word]);
     4405            dirty = dirty or (r_xram_rsp_trt_buf.wdata_be[word] != 0);
     4406        }
    42604407
    42614408      // update cache directory
     
    42974444      m_cache_directory.write(set, way, entry);
    42984445
    4299       // request an invalidation request in IVT for victim line
    4300       if(r_xram_rsp_victim_inval.read())
    4301       {
    4302         bool   broadcast    = r_xram_rsp_victim_is_cnt.read();
    4303         size_t index        = 0;
    4304         size_t count_copies = r_xram_rsp_victim_count.read();
     4446        // register invalid request in IVT for victim line if required
     4447        if(r_xram_rsp_victim_inval.read())
     4448        {
     4449            bool   broadcast    = r_xram_rsp_victim_is_cnt.read();
     4450            size_t index        = 0;
     4451            size_t count_copies = r_xram_rsp_victim_count.read();
    43054452       
    4306         bool   wok = m_ivt.set(false,      // it's an inval transaction
    4307                                broadcast,  // set broadcast bit
    4308                                false,      // no response required
    4309                                false,      // no acknowledge required
    4310                                0,          // srcid
    4311                                0,          // trdid
    4312                                0,          // pktid
    4313                                r_xram_rsp_victim_nline.read(),
    4314                                count_copies,
    4315                                index);
    4316 
    4317         r_xram_rsp_ivt_index = index;
    4318 
    4319         if(!wok)
    4320         {
    4321           std::cout << "VCI_MEM_CACHE ERROR " << name() << " XRAM_RSP_DIR_UPDT"
    4322                     << " invalidate_tab entry free but write unsuccessful" << std::endl;
    4323           exit(0);
    4324         }
    4325       }
     4453            bool   wok = m_ivt.set(false,      // it's an inval transaction
     4454                                   broadcast,  // set broadcast bit
     4455                                   false,      // no response required
     4456                                   false,      // no acknowledge required
     4457                                   0,          // srcid
     4458                                   0,          // trdid
     4459                                   0,          // pktid
     4460                                   r_xram_rsp_victim_nline.read(),
     4461                                   count_copies,
     4462                                   index);
     4463
     4464            r_xram_rsp_ivt_index = index;
     4465
     4466            assert( wok and
     4467            "MEMC ERROR in XRAM_RSP_DIR_UPDT state: IVT should not be full");
     4468        }
    43264469
    43274470#if DEBUG_MEMC_XRAM_RSP
     
    43374480          << " / is_cnt = " << entry.is_cnt << std::endl;
    43384481if(r_xram_rsp_victim_inval.read())
    4339 std::cout << "                           Invalidation request for victim line "
    4340           << std::hex << r_xram_rsp_victim_nline.read()
     4482std::cout << "                           Invalidation request for address "
     4483          << std::hex << r_xram_rsp_victim_nline.read()*m_words*4
    43414484          << " / broadcast = " << r_xram_rsp_victim_is_cnt.read() << std::endl;
    43424485}
     
    43674510    case XRAM_RSP_TRT_DIRTY:  // set the TRT entry (PUT to XRAM) if the victim is dirty
    43684511    {
    4369       if(r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP)
    4370       {
    4371         std::vector<data_t> data_vector;
    4372         data_vector.clear();
    4373        
    4374         for(size_t i=0; i<m_words; i++)
    4375         {
    4376           data_vector.push_back(r_xram_rsp_victim_data[i]);
    4377         }
    4378         /*m_trt.set(r_xram_rsp_trt_index.read(),
    4379                               false,       // write to XRAM
    4380                               r_xram_rsp_victim_nline.read(),  // line index
    4381                               0,
    4382                               0,
    4383                               0,
    4384                               false,
    4385                               0,
    4386                               0,
    4387                               std::vector<be_t> (m_words,0),
    4388                               std::vector<data_t> (m_words,0));*/
    4389        
    4390         m_trt.set(r_xram_rsp_trt_index.read(),
    4391                   false,       // write to XRAM
    4392                   r_xram_rsp_victim_nline.read(),  // line index
    4393                   0,
    4394                   0,
    4395                   0,
    4396                   false,
    4397                   0,
    4398                   0,
    4399                   std::vector<be_t> (m_words,0),
    4400                   data_vector);
     4512        if(r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP)
     4513        {
     4514            std::vector<data_t> data_vector;
     4515            data_vector.clear();
     4516            for(size_t i=0; i<m_words; i++)
     4517            {
     4518                data_vector.push_back(r_xram_rsp_victim_data[i].read());
     4519            }
     4520            m_trt.set( r_xram_rsp_trt_index.read(),
     4521                       false,                             // PUT
     4522                       r_xram_rsp_victim_nline.read(),    // line index
     4523                       0,                                 // unused
     4524                       0,                                 // unused
     4525                       0,                                 // unused
     4526                       false,                             // not proc_read
     4527                       0,                                 // unused
     4528                       0,                                 // unused
     4529                       std::vector<be_t>(m_words,0xF),                         
     4530                       data_vector);
    44014531
    44024532#if DEBUG_MEMC_XRAM_RSP
     
    44044534std::cout << "  <MEMC " << name() << " XRAM_RSP_TRT_DIRTY>"
    44054535          << " Set TRT entry for the put transaction"
    4406           << " / dirty victim line = " << r_xram_rsp_victim_nline.read() << std::endl;
    4407 #endif
    4408         if(r_xram_rsp_trt_buf.proc_read)         r_xram_rsp_fsm = XRAM_RSP_DIR_RSP;
    4409         else if(r_xram_rsp_victim_inval.read())  r_xram_rsp_fsm = XRAM_RSP_INVAL;
    4410         else                                     r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
    4411         m_cpt_xram_rsp_fsm_n_trt_lock++;
    4412       }
    4413 
    4414       m_cpt_xram_rsp_fsm_trt_lock++;
    4415 
    4416       break;
     4536          << " / address = " << (r_xram_rsp_victim_nline.read()*m_words*4) << std::endl;
     4537#endif
     4538            if(r_xram_rsp_trt_buf.proc_read)         r_xram_rsp_fsm = XRAM_RSP_DIR_RSP;
     4539            else if(r_xram_rsp_victim_inval.read())  r_xram_rsp_fsm = XRAM_RSP_INVAL;
     4540            else                                     r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
     4541        }
     4542        break;
    44174543    }
    44184544    //////////////////////
    44194545    case XRAM_RSP_DIR_RSP:     // Request a response to TGT_RSP FSM
    44204546    {
    4421       if(!r_xram_rsp_to_tgt_rsp_req.read())
    4422       {
    4423         r_xram_rsp_to_tgt_rsp_srcid = r_xram_rsp_trt_buf.srcid;
    4424         r_xram_rsp_to_tgt_rsp_trdid = r_xram_rsp_trt_buf.trdid;
    4425         r_xram_rsp_to_tgt_rsp_pktid = r_xram_rsp_trt_buf.pktid;
    4426         for(size_t i=0; i < m_words; i++)
    4427         {
    4428             r_xram_rsp_to_tgt_rsp_data[i] = r_xram_rsp_trt_buf.wdata[i];
    4429         }
    4430         r_xram_rsp_to_tgt_rsp_word   = r_xram_rsp_trt_buf.word_index;
    4431         r_xram_rsp_to_tgt_rsp_length = r_xram_rsp_trt_buf.read_length;
    4432         r_xram_rsp_to_tgt_rsp_ll_key = r_xram_rsp_trt_buf.ll_key;
    4433         r_xram_rsp_to_tgt_rsp_rerror = false;
    4434         r_xram_rsp_to_tgt_rsp_req    = true;
     4547        if ( not r_xram_rsp_to_tgt_rsp_req.read() )
     4548        {
     4549            r_xram_rsp_to_tgt_rsp_srcid = r_xram_rsp_trt_buf.srcid;
     4550            r_xram_rsp_to_tgt_rsp_trdid = r_xram_rsp_trt_buf.trdid;
     4551            r_xram_rsp_to_tgt_rsp_pktid = r_xram_rsp_trt_buf.pktid;
     4552            for(size_t i=0; i < m_words; i++)
     4553            {
     4554                r_xram_rsp_to_tgt_rsp_data[i] = r_xram_rsp_trt_buf.wdata[i];
     4555            }
     4556            r_xram_rsp_to_tgt_rsp_word   = r_xram_rsp_trt_buf.word_index;
     4557            r_xram_rsp_to_tgt_rsp_length = r_xram_rsp_trt_buf.read_length;
     4558            r_xram_rsp_to_tgt_rsp_ll_key = r_xram_rsp_trt_buf.ll_key;
     4559            r_xram_rsp_to_tgt_rsp_rerror = false;
     4560            r_xram_rsp_to_tgt_rsp_req    = true;
    44354561
    44364562#if ODCCP_NON_INCLUSIVE
     
    44544580          << " / nwords = " << std::dec << r_xram_rsp_trt_buf.read_length << std::endl;
    44554581#endif
    4456       }
    4457       break;
     4582        }
     4583        break;
    44584584    }
    44594585    ////////////////////
     
    44734599        xram_rsp_to_cc_send_fifo_srcid     = r_xram_rsp_victim_copy.read();
    44744600        xram_rsp_to_cc_send_fifo_inst      = r_xram_rsp_victim_copy_inst.read();
    4475 #if L1_MULTI_CACHE
    4476         xram_rsp_to_cc_send_fifo_cache_id  = r_xram_rsp_victim_copy_cache.read();
    4477 #endif
    44784601        xram_rsp_to_cc_send_fifo_put       = multi_req;
    4479         r_xram_rsp_next_ptr                 = r_xram_rsp_victim_ptr.read();
     4602        r_xram_rsp_next_ptr                = r_xram_rsp_victim_ptr.read();
    44804603
    44814604#if ODCCP_NON_INCLUSIVE
     
    44944617std::cout << "  <MEMC " << name() << " XRAM_RSP_INVAL>"
    44954618          << " Send an inval request to CC_SEND FSM"
    4496           << " / victim line = " << r_xram_rsp_victim_nline.read() << std::endl;
     4619          << " / address = " << r_xram_rsp_victim_nline.read()*m_words*4 << std::endl;
    44974620#endif
    44984621      }
     
    45064629
    45074630        r_xram_rsp_to_ixr_cmd_req = true;
    4508         r_xram_rsp_to_ixr_cmd_nline = r_xram_rsp_victim_nline.read();
    4509         r_xram_rsp_to_ixr_cmd_trdid = r_xram_rsp_trt_index.read();
    4510         for(size_t i=0; i<m_words ; i++)
    4511         {
    4512             r_xram_rsp_to_ixr_cmd_data[i] = r_xram_rsp_victim_data[i];
    4513         }
    4514         m_cpt_write_dirty++;
    4515 
     4631        //r_xram_rsp_to_ixr_cmd_nline = r_xram_rsp_victim_nline.read();
     4632        r_xram_rsp_to_ixr_cmd_index = r_xram_rsp_trt_index.read();
     4633        /*for(size_t i=0; i<m_words ; i++)
     4634        {
     4635          r_xram_rsp_to_ixr_cmd_data[i] = r_xram_rsp_victim_data[i];
     4636        }*/
    45164637#if (ODCCP_NON_INCLUSIVE == 0)
    45174638        // if victim is no coherent, we dont request a ixr command
     
    45254646#endif
    45264647
    4527         bool multi_req = !r_xram_rsp_victim_is_cnt.read() and r_xram_rsp_victim_inval.read();
     4648        m_cpt_write_dirty++;
     4649
     4650        bool multi_req = not r_xram_rsp_victim_is_cnt.read() and
     4651          r_xram_rsp_victim_inval.read();
    45284652        bool not_last_multi_req = multi_req and (r_xram_rsp_victim_count.read() != 1);
    45294653
     
    45354659std::cout << "  <MEMC " << name() << " XRAM_RSP_WRITE_DIRTY>"
    45364660          << " Send the put request to IXR_CMD FSM"
    4537           << " / victim line = " << r_xram_rsp_victim_nline.read() << std::endl;
    4538 #endif
    4539       }
    4540       break;
     4661          << " / address = " << r_xram_rsp_victim_nline.read()*m_words*4 << std::endl;
     4662#endif
     4663        }
     4664        break;
    45414665    }
    45424666    /////////////////////////
    45434667    case XRAM_RSP_HEAP_REQ:    // Get the lock to the HEAP
    45444668    {
    4545       if(r_alloc_heap_fsm.read() == ALLOC_HEAP_XRAM_RSP)
    4546       {
    4547         r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE;
    4548         m_cpt_xram_rsp_fsm_n_heap_lock++;
    4549       }
     4669        if(r_alloc_heap_fsm.read() == ALLOC_HEAP_XRAM_RSP)
     4670        {
     4671            r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE;
     4672        }
    45504673
    45514674#if DEBUG_MEMC_XRAM_RSP
     
    45544677          << " Requesting HEAP lock" << std::endl;
    45554678#endif
    4556 
    4557       m_cpt_xram_rsp_fsm_heap_lock++;
    4558 
    4559       break;
     4679        break;
    45604680    }
    45614681    /////////////////////////
     
    45674687
    45684688        xram_rsp_to_cc_send_fifo_srcid    = entry.owner.srcid;
    4569 #if L1_MULTI_CACHE
    4570         xram_rsp_to_cc_send_fifo_cache_id = entry.owner.cache_id;
    4571 #endif
    45724689        xram_rsp_to_cc_send_fifo_inst  = entry.owner.inst;
    45734690        xram_rsp_to_cc_send_fifo_put   = true;
     
    46134730      HeapEntry last_entry;
    46144731      last_entry.owner.srcid    = 0;
    4615 #if L1_MULTI_CACHE
    4616       last_entry.owner.cache_id = 0;
    4617 #endif
    46184732      last_entry.owner.inst     = false;
    46194733      if(m_heap.is_full())
     
    46394753      break;
    46404754    }
    4641     // ///////////////////////
     4755    //////////////////////////
    46424756    case XRAM_RSP_ERROR_ERASE:  // erase TRT entry in case of error
    46434757    {
     
    46924806  ////////////////////////////////////////////////////////////////////////////////////
    46934807
     4808//std::cout << std::endl << "cleanup_fsm" << std::endl;
     4809
    46944810  switch(r_cleanup_fsm.read())
    46954811  {
    4696     //////////////////
    4697     case CLEANUP_IDLE:     // Get first DSPIN flit of the CLEANUP command
    4698     {
    4699       if(not m_cc_receive_to_cleanup_fifo.rok()) break;
    4700 
    4701       uint64_t flit = m_cc_receive_to_cleanup_fifo.read();
    4702       uint32_t srcid =
    4703         DspinDhccpParam::dspin_get(
    4704             flit,
    4705             DspinDhccpParam::CLEANUP_SRCID);
    4706 
    4707       uint8_t type =
    4708         DspinDhccpParam::dspin_get(
    4709             flit,
    4710             DspinDhccpParam::P2M_TYPE);
    4711 
    4712       r_cleanup_way_index =
    4713         DspinDhccpParam::dspin_get(
    4714             flit,
    4715             DspinDhccpParam::CLEANUP_WAY_INDEX);
    4716 
    4717       r_cleanup_nline =
    4718         DspinDhccpParam::dspin_get(
    4719             flit,
    4720             DspinDhccpParam::CLEANUP_NLINE_MSB) << 32;
    4721 
    4722       /*ODCCP*/ // Cleanup on no coherent line if 1
    4723       r_cleanup_ncc =
    4724         DspinDhccpParam::dspin_get(
    4725             flit,
    4726             DspinDhccpParam::CLEANUP_NCC);
    4727 
    4728       r_cleanup_inst  = (type == DspinDhccpParam::TYPE_CLEANUP_INST);
    4729       r_cleanup_srcid = srcid;
    4730 
    4731       if(srcid >= m_initiators)
    4732       {
    4733         std::cout
    4734             << "VCI_MEM_CACHE ERROR " << name()
    4735             << " CLEANUP_IDLE state"  << std::endl
    4736             << "illegal srcid for cleanup request" << std::endl;
    4737 
    4738         exit(0);
    4739       }
    4740 
    4741       m_cpt_cleanup++;
    4742       cc_receive_to_cleanup_fifo_get = true;
    4743       r_cleanup_fsm                  = CLEANUP_GET_NLINE;
     4812      //////////////////
     4813      case CLEANUP_IDLE:     // Get first DSPIN flit of the CLEANUP command
     4814      {
     4815          if(not m_cc_receive_to_cleanup_fifo.rok()) break;
     4816
     4817          uint64_t flit = m_cc_receive_to_cleanup_fifo.read();
     4818          uint32_t srcid = DspinDhccpParam::dspin_get( flit,
     4819                           DspinDhccpParam::CLEANUP_SRCID);
     4820
     4821          uint8_t type = DspinDhccpParam::dspin_get( flit,
     4822                         DspinDhccpParam::P2M_TYPE);
     4823
     4824          r_cleanup_way_index = DspinDhccpParam::dspin_get( flit,
     4825                                DspinDhccpParam::CLEANUP_WAY_INDEX);
     4826
     4827          r_cleanup_nline = DspinDhccpParam::dspin_get( flit,
     4828                            DspinDhccpParam::CLEANUP_NLINE_MSB) << 32;
     4829
     4830          /*ODCCP*/ // Cleanup on no coherent line if 1
     4831          r_cleanup_ncc =
     4832            DspinDhccpParam::dspin_get(
     4833                flit,
     4834                DspinDhccpParam::CLEANUP_NCC);
     4835
     4836          r_cleanup_inst  = (type == DspinDhccpParam::TYPE_CLEANUP_INST);
     4837          r_cleanup_srcid = srcid;
     4838
     4839          assert( (srcid < m_initiators) and
     4840          "MEMC ERROR in CLEANUP_IDLE state : illegal SRCID value");
     4841
     4842          m_cpt_cleanup++;
     4843          cc_receive_to_cleanup_fifo_get = true;
     4844          r_cleanup_fsm                  = CLEANUP_GET_NLINE;
    47444845
    47454846#if DEBUG_MEMC_CLEANUP
     
    47474848std::cout << "  <MEMC "         << name()
    47484849          << " CLEANUP_IDLE> Cleanup request:" << std::hex
    4749           << " / owner_id = "   << srcid
     4850          << " owner_id = "   << srcid
    47504851          << " / owner_ins = "  << (type == DspinDhccpParam::TYPE_CLEANUP_INST) << std::endl;
    47514852#endif
    4752       break;
    4753     }
    4754 
    4755     ///////////////////////
    4756     case CLEANUP_GET_NLINE:  // GET second DSPIN flit of the cleanup command
    4757     {
    4758       if(not m_cc_receive_to_cleanup_fifo.rok()) break;
     4853          break;
     4854      }
     4855      ///////////////////////
     4856      case CLEANUP_GET_NLINE:  // GET second DSPIN flit of the cleanup command
     4857      {
     4858          if(not m_cc_receive_to_cleanup_fifo.rok()) break;
     4859
     4860          uint64_t flit = m_cc_receive_to_cleanup_fifo.read();
    47594861     
    47604862
    4761       uint64_t flit = m_cc_receive_to_cleanup_fifo.read();
    4762 
    4763       addr_t nline = r_cleanup_nline.read() |
    4764         DspinDhccpParam::dspin_get(flit, DspinDhccpParam::CLEANUP_NLINE_LSB);
     4863          addr_t nline = r_cleanup_nline.read() |
     4864              DspinDhccpParam::dspin_get(flit, DspinDhccpParam::CLEANUP_NLINE_LSB);
     4865
     4866          cc_receive_to_cleanup_fifo_get = true;
     4867          r_cleanup_nline                = nline;
     4868          r_cleanup_fsm                  = CLEANUP_DIR_REQ;
    47654869     
    47664870      bool eop = DspinDhccpParam::dspin_get(flit, DspinDhccpParam::P2M_EOP);
     
    47894893          << " / address = " << std::hex << nline * m_words * 4 << std::endl;
    47904894#endif
    4791       break;
    4792     }
    4793 
     4895          break;
     4896      }
     4897      /////////////////////
    47944898    /*ODCCP*/ // We save the cleanup's data into a buffer
    47954899    case CLEANUP_GET_DATA :
     
    48184922    case CLEANUP_DIR_REQ:   // Get the lock to the directory
    48194923    {
    4820       m_cpt_cleanup_fsm_dir_lock++;
    48214924      // Get the lock to the directory
    48224925      if(r_alloc_dir_fsm.read() != ALLOC_DIR_CLEANUP) break;
    4823 
    4824       r_cleanup_fsm = CLEANUP_DIR_LOCK;
     4926          r_cleanup_fsm = CLEANUP_DIR_LOCK;
    48254927
    48264928#if DEBUG_MEMC_CLEANUP
     
    48284930std::cout << "  <MEMC " << name() << " CLEANUP_DIR_REQ> Requesting DIR lock" << std::endl;
    48294931#endif
    4830 
    4831       m_cpt_cleanup_fsm_n_dir_lock++;
     4932          break;
     4933      }
     4934      //////////////////////
     4935      case CLEANUP_DIR_LOCK:    // test directory status
     4936      {
     4937          assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CLEANUP) and
     4938          "MEMC ERROR in CLEANUP_DIR_LOCK: bad DIR allocation");
     4939
     4940          // Read the directory
     4941          size_t way = 0;
     4942          addr_t cleanup_address = r_cleanup_nline.read() * m_words * 4;
     4943          DirectoryEntry entry   = m_cache_directory.read(cleanup_address , way);
     4944          r_cleanup_is_cnt       = entry.is_cnt;
     4945          r_cleanup_dirty        = entry.dirty;
     4946          r_cleanup_tag          = entry.tag;
     4947          r_cleanup_lock         = entry.lock;
     4948          r_cleanup_way          = way;
     4949          r_cleanup_count        = entry.count;
     4950          r_cleanup_ptr          = entry.ptr;
     4951          r_cleanup_copy         = entry.owner.srcid;
     4952          r_cleanup_copy_inst    = entry.owner.inst;
     4953          if(entry.valid)      // hit : the copy must be cleared
     4954          {
     4955              assert( (entry.count > 0) and
     4956              "MEMC ERROR in CLEANUP_DIR_LOCK state, CLEANUP on valid entry with no copies");
     4957
     4958              if((entry.count == 1) or (entry.is_cnt))   // no access to the heap
     4959              {
     4960                  r_cleanup_fsm = CLEANUP_DIR_WRITE;
     4961              }
     4962              else                                       // access to the heap
     4963              {
     4964                  r_cleanup_fsm = CLEANUP_HEAP_REQ;
     4965              }
     4966          }
     4967          else                // miss : check IVT for a pending inval
     4968          {
     4969              r_cleanup_fsm = CLEANUP_IVT_LOCK;
     4970          }
     4971
     4972#if DEBUG_MEMC_CLEANUP
     4973if(m_debug)
     4974std::cout << "  <MEMC " << name()
     4975          << " CLEANUP_DIR_LOCK> Test directory status: "
     4976          << std::hex << " address = " << cleanup_address
     4977          << " / hit = "        << entry.valid
     4978          << " / dir_id = "     << entry.owner.srcid
     4979          << " / dir_ins = "    << entry.owner.inst
     4980          << " / search_id = "  << r_cleanup_srcid.read()
     4981          << " / search_ins = " << r_cleanup_inst.read()
     4982          << " / count = "      << entry.count
     4983          << " / is_cnt = "     << entry.is_cnt << std::endl;
     4984#endif
     4985          break;
     4986      }
     4987      ///////////////////////
     4988      case CLEANUP_DIR_WRITE:      // Update the directory entry without heap access
     4989      {
     4990          assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CLEANUP) and
     4991          "MEMC ERROR in CLEANUP_DIR_LOCK: bad DIR allocation");
     4992
     4993          size_t way         = r_cleanup_way.read();
     4994          size_t set         = m_y[(addr_t)(r_cleanup_nline.read()*m_words*4)];
     4995          bool   match_srcid = (r_cleanup_copy.read() == r_cleanup_srcid.read());
     4996          bool   match_inst  = (r_cleanup_copy_inst.read() == r_cleanup_inst.read());
     4997          bool   match       = match_srcid and match_inst;
     4998
     4999          assert( (r_cleanup_is_cnt.read() or match) and
     5000          "MEMC ERROR in CLEANUP_DIR_LOCK: illegal CLEANUP on valid entry");
     5001
     5002          // update the cache directory (for the copies)
     5003          DirectoryEntry entry;
     5004          entry.valid       = true;
     5005          entry.is_cnt      = r_cleanup_is_cnt.read();
     5006          entry.dirty       = r_cleanup_dirty.read() or r_cleanup_contains_data.read();
     5007          entry.tag         = r_cleanup_tag.read();
     5008          entry.lock        = r_cleanup_lock.read();
     5009          entry.ptr         = r_cleanup_ptr.read();
     5010          entry.count       = r_cleanup_count.read() - 1;
     5011          entry.owner.srcid = 0;
     5012          entry.owner.inst  = 0;
     5013          /*ODCCP*/ // if cleanup contains data we update the cache data
     5014          if (r_cleanup_contains_data.read())
     5015          {
     5016            for (size_t word = 0; word < m_words; word ++)
     5017            {
     5018              m_cache_data.write(way, set, word, r_cleanup_data[word].read(), 0xF);
     5019            }
     5020          }
     5021
     5022
     5023          m_cache_directory.write(set, way, entry);
     5024
     5025          r_cleanup_fsm = CLEANUP_SEND_CLACK;
     5026
     5027#if DEBUG_MEMC_CLEANUP
     5028if(m_debug)
     5029std::cout << "  <MEMC " << name()
     5030          << " CLEANUP_DIR_WRITE> Update directory:"
     5031          << std::hex << " address = "   << r_cleanup_nline.read() * m_words * 4
     5032          << " / dir_id = "  << entry.owner.srcid
     5033          << " / dir_ins = " << entry.owner.inst
     5034          << " / count = "   << entry.count
     5035          << " / is_cnt = "  << entry.is_cnt << std::endl;
     5036#endif
    48325037
    48335038      break;
    48345039    }
    48355040
    4836     //////////////////////
    4837     case CLEANUP_DIR_LOCK:
    4838     {
    4839       // test directory status
    4840       if(r_alloc_dir_fsm.read() != ALLOC_DIR_CLEANUP)
    4841       {
    4842         std::cout
    4843             << "VCI_MEM_CACHE ERROR " << name()
    4844             << " CLEANUP_DIR_LOCK state"
    4845             << " bad DIR allocation" << std::endl;
    4846 
    4847         exit(0);
    4848       }
    4849       // Read the directory
    4850       size_t way = 0;
    4851       addr_t cleanup_address = r_cleanup_nline.read() * m_words * 4;
    4852 
    4853       DirectoryEntry entry   = m_cache_directory.read(cleanup_address , way);
    4854       r_cleanup_is_cnt       = entry.is_cnt;
    4855       r_cleanup_dirty        = entry.dirty;
    4856       r_cleanup_tag          = entry.tag;
    4857       r_cleanup_lock         = entry.lock;
    4858       r_cleanup_way          = way;
    4859       r_cleanup_count        = entry.count;
    4860       r_cleanup_ptr          = entry.ptr;
    4861       r_cleanup_copy         = entry.owner.srcid;
    4862       r_cleanup_copy_inst    = entry.owner.inst;
    4863 #if L1_MULTI_CACHE
    4864       r_cleanup_copy_cache   = entry.owner.cache_id;
    4865 #endif
    4866 
    4867       if(entry.valid)      // hit : the copy must be cleared
    4868       {
    4869         if(entry.count < 1)
    4870         {
    4871           std::cout << "assert on line " << std::hex <<r_cleanup_nline.read() << " | at cycle " << std::dec <<m_cpt_cycles << std::endl;
    4872           std::cout << "cleanup with data ? " << r_cleanup_contains_data.read() << " | at cycle " << m_cpt_cycles << std::endl;
    4873           std::cout << "cleanup_address = " << std::hex << (r_cleanup_nline.read()*m_words*4) << std::dec << std::endl;
    4874           std::cout << "srcid = " << r_cleanup_srcid.read() << std::endl;
    4875           std::cout << "inst = " << r_cleanup_inst.read() << std::endl;
    4876           std::cout << "inst = " << r_cleanup_inst.read() << std::endl;
    4877         }
    4878         assert(
    4879             (entry.count > 0) and
    4880             "VCI MEM CACHE ERROR: "
    4881             "In CLEANUP_DIR_LOCK, CLEANUP command on a valid entry "
    4882             "with no copies");
    4883 
    4884         // no access to the heap
    4885         if((entry.count == 1) or (entry.is_cnt))
    4886         {
    4887           r_cleanup_fsm = CLEANUP_DIR_WRITE;
    4888         }
    4889         // access to the heap
    4890         else
    4891         {
    4892           r_cleanup_fsm = CLEANUP_HEAP_REQ;
    4893         }
    4894       }
    4895       else                // miss : check UPT for a pending invalidation transaction
    4896       {
    4897         r_cleanup_fsm = CLEANUP_IVT_LOCK;
    4898       }
     5041      //////////////////////
     5042      case CLEANUP_HEAP_REQ:         // get the lock to the HEAP directory
     5043      {
     5044          if(r_alloc_heap_fsm.read() != ALLOC_HEAP_CLEANUP) break;
     5045
     5046          r_cleanup_fsm = CLEANUP_HEAP_LOCK;
    48995047
    49005048#if DEBUG_MEMC_CLEANUP
    4901       if(m_debug)
    4902       {
    4903         std::cout
    4904             << "  <MEMC " << name()
    4905             << " CLEANUP_DIR_LOCK> Test directory status: "
    4906             << std::hex
    4907             << " line = "         << cleanup_address
    4908             << " / hit = "        << entry.valid
    4909             << " / dir_id = "     << entry.owner.srcid
    4910             << " / dir_ins = "    << entry.owner.inst
    4911             << " / search_id = "  << r_cleanup_srcid.read()
    4912             << " / search_ins = " << r_cleanup_inst.read()
    4913             << " / count = "      << entry.count
    4914             << " / is_cnt = "     << entry.is_cnt
    4915             << std::endl;
    4916       }
    4917 #endif
    4918       break;
    4919     }
    4920 
    4921     ///////////////////////
    4922     case CLEANUP_DIR_WRITE:
    4923     {
    4924       // Update the directory entry without heap access
    4925       if(r_alloc_dir_fsm.read() != ALLOC_DIR_CLEANUP)
    4926       {
    4927         std::cout
    4928             << "VCI_MEM_CACHE ERROR " << name()
    4929             << " CLEANUP_DIR_WRITE state"
    4930             << " bad DIR allocation" << std::endl;
    4931 
    4932         exit(0);
    4933       }
    4934 
    4935       size_t way         = r_cleanup_way.read();
    4936       size_t set         = m_y[(addr_t)(r_cleanup_nline.read()*m_words*4)];
    4937       bool   match_srcid = (r_cleanup_copy.read() == r_cleanup_srcid.read());
    4938 
    4939 #if L1_MULTI_CACHE
    4940       match_srcid       &= (r_cleanup_copy_cache.read() == r_cleanup_pktid.read());
    4941 #endif
    4942 
    4943       bool   match_inst  = (r_cleanup_copy_inst.read() == r_cleanup_inst.read());
    4944       bool   match       = match_srcid and match_inst;
    4945 
    4946       if(not r_cleanup_is_cnt.read() and not match)
    4947       {
    4948         std::cout
    4949             << "VCI_MEM_CACHE ERROR : Cleanup request on a valid"
    4950             << "entry using linked list mode with no corresponding"
    4951             << "directory or heap entry"
    4952             << std::endl;
    4953 
    4954         exit(1);
    4955       }
    4956 
    4957       // update the cache directory (for the copies)
    4958       DirectoryEntry entry;
    4959       entry.valid       = true;
    4960       entry.is_cnt      = r_cleanup_is_cnt.read();
    4961       entry.dirty       = r_cleanup_dirty.read() or r_cleanup_contains_data.read();
    4962       entry.tag         = r_cleanup_tag.read();
    4963       entry.lock        = r_cleanup_lock.read();
    4964       entry.ptr         = r_cleanup_ptr.read();
    4965       entry.count       = r_cleanup_count.read() - 1;
    4966       entry.owner.srcid = 0;
    4967       entry.owner.inst  = 0;
    4968 
    4969 #if L1_MULTI_CACHE
    4970       entry.owner.cache_id = 0;
    4971 #endif
    4972       /*ODCCP*/ // if cleanup contains data we update the cache data
    4973       if (r_cleanup_contains_data.read())
    4974       {
    4975         for (size_t word = 0; word < m_words; word ++)
    4976         {
    4977           m_cache_data.write(way, set, word, r_cleanup_data[word].read(), 0xF);
    4978         }
    4979       }
    4980 
    4981 
    4982       m_cache_directory.write(set, way, entry);
    4983 
    4984       r_cleanup_fsm = CLEANUP_SEND_CLACK;
     5049if(m_debug)
     5050std::cout << "  <MEMC " << name()
     5051          << " CLEANUP_HEAP_REQ> HEAP lock acquired " << std::endl;
     5052#endif
     5053          break;
     5054      }
     5055      //////////////////////
     5056      case CLEANUP_HEAP_LOCK:      // two cases are handled in this state :
     5057                                 // 1. the matching copy is directly in the directory
     5058                                 // 2. the matching copy is the first copy in the heap
     5059      {
     5060          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP) and
     5061          "MEMC ERROR in CLEANUP_HEAP_LOCK state: bad HEAP allocation");
     5062
     5063          size_t way            = r_cleanup_way.read();
     5064          size_t set            = m_y[(addr_t)(r_cleanup_nline.read() *m_words*4)];
     5065
     5066          HeapEntry heap_entry  = m_heap.read(r_cleanup_ptr.read());
     5067          bool last             = (heap_entry.next == r_cleanup_ptr.read());
     5068
     5069          // match_dir computation
     5070          bool match_dir_srcid  = (r_cleanup_copy.read()      == r_cleanup_srcid.read());
     5071          bool match_dir_inst   = (r_cleanup_copy_inst.read() == r_cleanup_inst.read());
     5072          bool match_dir        = match_dir_srcid  and match_dir_inst;
     5073
     5074          // match_heap computation
     5075          bool match_heap_srcid = (heap_entry.owner.srcid == r_cleanup_srcid.read());
     5076          bool match_heap_inst  = (heap_entry.owner.inst  == r_cleanup_inst.read());
     5077          bool match_heap       = match_heap_srcid and match_heap_inst;
     5078
     5079          r_cleanup_prev_ptr    = r_cleanup_ptr.read();
     5080          r_cleanup_prev_srcid  = heap_entry.owner.srcid;
     5081          r_cleanup_prev_inst   = heap_entry.owner.inst;
     5082
     5083          assert( (not last or match_dir or match_heap) and
     5084          "MEMC ERROR in CLEANUP_HEAP_LOCK state: hit but no copy found");
     5085
     5086          assert( (not match_dir or not match_heap) and
     5087          "MEMC ERROR in CLEANUP_HEAP_LOCK state: two matching copies found");
     5088
     5089          DirectoryEntry dir_entry;
     5090          dir_entry.valid          = true;
     5091          dir_entry.is_cnt         = r_cleanup_is_cnt.read();
     5092          dir_entry.dirty          = r_cleanup_dirty.read();
     5093          dir_entry.tag            = r_cleanup_tag.read();
     5094          dir_entry.lock           = r_cleanup_lock.read();
     5095          dir_entry.count          = r_cleanup_count.read()-1;
     5096
     5097          // the matching copy is registered in the directory and
     5098          // it must be replaced by the first copy registered in
     5099          // the heap. The corresponding entry must be freed
     5100          if(match_dir)
     5101          {
     5102              dir_entry.ptr            = heap_entry.next;
     5103              dir_entry.owner.srcid    = heap_entry.owner.srcid;
     5104              dir_entry.owner.inst     = heap_entry.owner.inst;
     5105              r_cleanup_next_ptr       = r_cleanup_ptr.read();
     5106              r_cleanup_fsm            = CLEANUP_HEAP_FREE;
     5107          }
     5108
     5109          // the matching copy is the first copy in the heap
     5110          // It must be freed and the copy registered in directory
     5111          // must point to the next copy in heap
     5112          else if(match_heap)
     5113          {
     5114              dir_entry.ptr            = heap_entry.next;
     5115              dir_entry.owner.srcid    = r_cleanup_copy.read();
     5116              dir_entry.owner.inst     = r_cleanup_copy_inst.read();
     5117              r_cleanup_next_ptr       = r_cleanup_ptr.read();
     5118              r_cleanup_fsm            = CLEANUP_HEAP_FREE;
     5119          }
     5120
     5121          // The matching copy is in the heap, but is not the first copy
     5122          // The directory entry must be modified to decrement count
     5123          else
     5124          {
     5125              dir_entry.ptr            = r_cleanup_ptr.read();
     5126              dir_entry.owner.srcid    = r_cleanup_copy.read();
     5127              dir_entry.owner.inst     = r_cleanup_copy_inst.read();
     5128              r_cleanup_next_ptr       = heap_entry.next;
     5129              r_cleanup_fsm            = CLEANUP_HEAP_SEARCH;
     5130          }
     5131
     5132          m_cache_directory.write(set,way,dir_entry);
    49855133
    49865134#if DEBUG_MEMC_CLEANUP
    4987       if(m_debug)
    4988       {
    4989         std::cout
    4990             << "  <MEMC " << name()
    4991             << " CLEANUP_DIR_WRITE> Update directory:"
    4992             << std::hex
    4993             << " address = "   << r_cleanup_nline.read() * m_words * 4
    4994             << " / dir_id = "  << entry.owner.srcid
    4995             << " / dir_ins = " << entry.owner.inst
    4996             << " / count = "   << entry.count
    4997             << " / is_cnt = "  << entry.is_cnt
    4998             << std::endl;
    4999       }
    5000 #endif
    5001 
    5002       break;
    5003     }
    5004 
    5005     //////////////////////
    5006     case CLEANUP_HEAP_REQ:
    5007     {
    5008       // get the lock to the HEAP directory
    5009       m_cpt_cleanup_fsm_heap_lock++;
    5010       if(r_alloc_heap_fsm.read() != ALLOC_HEAP_CLEANUP) break;
    5011 
    5012       r_cleanup_fsm = CLEANUP_HEAP_LOCK;
     5135if(m_debug)
     5136std::cout << "  <MEMC " << name()
     5137          << " CLEANUP_HEAP_LOCK> Checks matching:"
     5138          << " address = "      << r_cleanup_nline.read() * m_words * 4
     5139          << " / dir_id = "     << r_cleanup_copy.read()
     5140          << " / dir_ins = "    << r_cleanup_copy_inst.read()
     5141          << " / heap_id = "    << heap_entry.owner.srcid
     5142          << " / heap_ins = "   << heap_entry.owner.inst
     5143          << " / search_id = "  << r_cleanup_srcid.read()
     5144          << " / search_ins = " << r_cleanup_inst.read() << std::endl;
     5145#endif
     5146          break;
     5147      }
     5148      ////////////////////////
     5149      case CLEANUP_HEAP_SEARCH:     // This state is handling the case where the copy
     5150                                    // is in the heap, but not the first in linked list
     5151      {
     5152          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP) and
     5153          "MEMC ERROR in CLEANUP_HEAP_LOCK state: bad HEAP allocation");
     5154
     5155          HeapEntry heap_entry  = m_heap.read(r_cleanup_next_ptr.read());
     5156
     5157          bool last             = (heap_entry.next        == r_cleanup_next_ptr.read());
     5158          bool match_heap_srcid = (heap_entry.owner.srcid == r_cleanup_srcid.read());
     5159          bool match_heap_inst  = (heap_entry.owner.inst  == r_cleanup_inst.read());
     5160          bool match_heap       = match_heap_srcid and match_heap_inst;
     5161
     5162          assert( (not last or match_heap) and
     5163          "MEMC ERROR in CLEANUP_HEAP_SEARCH state: no copy found");
     5164
     5165          // the matching copy must be removed
     5166          if(match_heap)
     5167          {
     5168              // re-use ressources
     5169              r_cleanup_ptr = heap_entry.next;
     5170              r_cleanup_fsm = CLEANUP_HEAP_CLEAN;
     5171          }
     5172          // test the next in the linked list
     5173          else
     5174          {
     5175              r_cleanup_prev_ptr      = r_cleanup_next_ptr.read();
     5176              r_cleanup_prev_srcid    = heap_entry.owner.srcid;
     5177              r_cleanup_prev_inst     = heap_entry.owner.inst;
     5178              r_cleanup_next_ptr      = heap_entry.next;
     5179              r_cleanup_fsm           = CLEANUP_HEAP_SEARCH;
     5180          }
    50135181
    50145182#if DEBUG_MEMC_CLEANUP
    5015       if(m_debug)
    5016       {
    5017         std::cout
    5018             << "  <MEMC " << name()
    5019             << " CLEANUP_HEAP_REQ> HEAP lock acquired "
    5020             << std::endl;
    5021       }
    5022 #endif
    5023       m_cpt_cleanup_fsm_n_heap_lock++;
    5024       break;
    5025     }
    5026 
    5027     //////////////////////
    5028     case CLEANUP_HEAP_LOCK:
    5029     {
    5030       // two cases are handled in this state :
    5031       // 1. the matching copy is directly in the directory
    5032       // 2. the matching copy is the first copy in the heap
    5033       if(r_alloc_heap_fsm.read() != ALLOC_HEAP_CLEANUP)
    5034       {
    5035         std::cout
    5036             << "VCI_MEM_CACHE ERROR " << name()
    5037             << " CLEANUP_HEAP_LOCK state"
    5038             << " bad HEAP allocation" << std::endl;
    5039 
    5040         exit(0);
    5041       }
    5042 
    5043       size_t way            = r_cleanup_way.read();
    5044       size_t set            = m_y[(addr_t)(r_cleanup_nline.read() *m_words*4)];
    5045 
    5046       HeapEntry heap_entry  = m_heap.read(r_cleanup_ptr.read());
    5047       bool last             = (heap_entry.next == r_cleanup_ptr.read());
    5048 
    5049       // match_dir computation
    5050       bool match_dir_srcid  = (r_cleanup_copy.read()      == r_cleanup_srcid.read());
    5051       bool match_dir_inst   = (r_cleanup_copy_inst.read() == r_cleanup_inst.read());
    5052       bool match_dir        = match_dir_srcid  and match_dir_inst;
    5053 
    5054       // match_heap computation
    5055       bool match_heap_srcid = (heap_entry.owner.srcid == r_cleanup_srcid.read());
    5056       bool match_heap_inst  = (heap_entry.owner.inst  == r_cleanup_inst.read());
    5057       bool match_heap       = match_heap_srcid and match_heap_inst;
    5058 
    5059       r_cleanup_prev_ptr    = r_cleanup_ptr.read();
    5060       r_cleanup_prev_srcid  = heap_entry.owner.srcid;
    5061       r_cleanup_prev_inst   = heap_entry.owner.inst;
    5062 
    5063 #if L1_MULTI_CACHE
    5064       match_dir  = match_dir  and(r_cleanup_copy_cache.read() == r_cleanup_pktid.read());
    5065       match_heap = match_heap and(heap_entry.owner.cache_id   == r_cleanup_pktid.read());
    5066       r_cleanup_prev_cache_id = heap_entry.owner.cache_id;
    5067 #endif
    5068 
    5069       if(not match_dir and not match_heap and last)
    5070       {
    5071         std::cout
    5072             << "VCI_MEM_CACHE ERROR " << name()
    5073             << " CLEANUP_HEAP_LOCK state"
    5074             << " hit but copy not found"
    5075             << std::endl;
    5076 /**/
    5077         std::cout
    5078           << "r_cleanup_srcid = " << r_cleanup_srcid.read()
    5079           << " / r_cleanup_inst = " << r_cleanup_inst.read() << std::endl
    5080           << "r_cleanup_copy = " << r_cleanup_copy.read()
    5081           << " / r_cleanup_copy_inst = " << r_cleanup_copy_inst.read() << std::endl
    5082           << "heap_entry.owner.srcid = " << heap_entry.owner.srcid
    5083           << " / heap_entry.owner.inst = " << heap_entry.owner.inst << std::endl;
    5084 /**/
    5085         exit(0);
    5086       }
    5087 
    5088       if(match_dir and match_heap)
    5089       {
    5090         std::cout
    5091             << "VCI_MEM_CACHE ERROR " << name()
    5092             << " CLEANUP_HEAP_LOCK state"
    5093             << " two copies matching the cleanup owner id"
    5094             << std::endl;
    5095 /**/
    5096         std::cout
    5097           << "r_cleanup_srcid = " << r_cleanup_srcid.read()
    5098           << " / r_cleanup_inst = " << r_cleanup_inst.read() << std::endl
    5099           << "r_cleanup_copy = " << r_cleanup_copy.read()
    5100           << " / r_cleanup_copy_inst = " << r_cleanup_copy_inst.read() << std::endl
    5101           << "heap_entry.owner.srcid = " << heap_entry.owner.srcid
    5102           << " / heap_entry.owner.inst = " << heap_entry.owner.inst << std::endl
    5103           << " / addr = " << std::hex << (r_cleanup_nline.read() *m_words*4) << std::dec << std::endl;
    5104 /**/
    5105 
    5106         exit(0);
    5107       }
    5108 
    5109       DirectoryEntry dir_entry;
    5110       dir_entry.valid          = true;
    5111       dir_entry.is_cnt         = r_cleanup_is_cnt.read();
    5112       dir_entry.dirty          = r_cleanup_dirty.read();
    5113       dir_entry.tag            = r_cleanup_tag.read();
    5114       dir_entry.lock           = r_cleanup_lock.read();
    5115       dir_entry.count          = r_cleanup_count.read()-1;
    5116 
    5117       // the matching copy is registered in the directory and
    5118       // it must be replaced by the first copy registered in
    5119       // the heap. The corresponding entry must be freed
    5120       if(match_dir)
    5121       {
    5122         dir_entry.ptr            = heap_entry.next;
    5123         dir_entry.owner.srcid    = heap_entry.owner.srcid;
    5124         dir_entry.owner.inst     = heap_entry.owner.inst;
    5125 
    5126 #if L1_MULTI_CACHE
    5127         dir_entry.owner.cache_id = heap_entry.owner.cache_id;
    5128 #endif
    5129 
    5130         r_cleanup_next_ptr       = r_cleanup_ptr.read();
    5131         r_cleanup_fsm            = CLEANUP_HEAP_FREE;
    5132       }
    5133 
    5134       // the matching copy is the first copy in the heap
    5135       // It must be freed and the copy registered in directory
    5136       // must point to the next copy in heap
    5137       else if(match_heap)
    5138       {
    5139         dir_entry.ptr            = heap_entry.next;
    5140         dir_entry.owner.srcid    = r_cleanup_copy.read();
    5141         dir_entry.owner.inst     = r_cleanup_copy_inst.read();
    5142 
    5143 #if L1_MULTI_CACHE
    5144         dir_entry.owner.cache_id = r_cleanup_copy_cache.read();
    5145 #endif
    5146 
    5147         r_cleanup_next_ptr       = r_cleanup_ptr.read();
    5148         r_cleanup_fsm            = CLEANUP_HEAP_FREE;
    5149       }
    5150 
    5151       // The matching copy is in the heap, but is not the first copy
    5152       // The directory entry must be modified to decrement count
    5153       else
    5154       {
    5155         dir_entry.ptr            = r_cleanup_ptr.read();
    5156         dir_entry.owner.srcid    = r_cleanup_copy.read();
    5157         dir_entry.owner.inst     = r_cleanup_copy_inst.read();
    5158 
    5159 #if L1_MULTI_CACHE
    5160         dir_entry.owner.cache_id = r_cleanup_copy_cache.read();
    5161 #endif
    5162 
    5163         r_cleanup_next_ptr       = heap_entry.next;
    5164         r_cleanup_fsm            = CLEANUP_HEAP_SEARCH;
    5165       }
    5166 
    5167       m_cache_directory.write(set,way,dir_entry);
    5168 
    5169 #if DEBUG_MEMC_CLEANUP
    5170       if(m_debug)
    5171       {
    5172         std::cout
    5173             << "  <MEMC " << name()
    5174             << " CLEANUP_HEAP_LOCK> Checks matching:"
    5175             << " address = "      << r_cleanup_nline.read() * m_words * 4
    5176             << " / dir_id = "     << r_cleanup_copy.read()
    5177             << " / dir_ins = "    << r_cleanup_copy_inst.read()
    5178             << " / heap_id = "    << heap_entry.owner.srcid
    5179             << " / heap_ins = "   << heap_entry.owner.inst
    5180             << " / search_id = "  << r_cleanup_srcid.read()
    5181             << " / search_ins = " << r_cleanup_inst.read()
    5182             << std::endl;
    5183       }
    5184 #endif
    5185       break;
    5186     }
    5187 
    5188     ////////////////////////
    5189     case CLEANUP_HEAP_SEARCH:
    5190     {
    5191       // This state is handling the case where the copy
    5192       // is in the heap, but is not the first in the linked list
    5193       if(r_alloc_heap_fsm.read() != ALLOC_HEAP_CLEANUP)
    5194       {
    5195         std::cout
    5196             << "VCI_MEM_CACHE ERROR " << name()
    5197             << " CLEANUP_HEAP_SEARCH state"
    5198             << " bad HEAP allocation" << std::endl;
    5199 
    5200         exit(0);
    5201       }
    5202 
    5203       HeapEntry heap_entry  = m_heap.read(r_cleanup_next_ptr.read());
    5204 
    5205       bool last             = (heap_entry.next        == r_cleanup_next_ptr.read());
    5206       bool match_heap_srcid = (heap_entry.owner.srcid == r_cleanup_srcid.read());
    5207       bool match_heap_inst  = (heap_entry.owner.inst  == r_cleanup_inst.read());
    5208       bool match_heap       = match_heap_srcid and match_heap_inst;
    5209 
    5210 #if L1_MULTI_CACHE
    5211       match_heap = match_heap and(heap_entry.owner.cache_id == r_cleanup_pktid.read());
    5212 #endif
    5213 
    5214       if(not match_heap and last)
    5215       {
    5216         std::cout
    5217             << "VCI_MEM_CACHE_ERROR " << name()
    5218             << " CLEANUP_HEAP_SEARCH state"
    5219             << " cleanup on valid line but copy not found"
    5220             << std::endl;
    5221 
    5222         exit(0);
    5223       }
    5224 
    5225       // the matching copy must be removed
    5226       if(match_heap)
    5227       {
    5228         // re-use ressources
    5229         r_cleanup_ptr = heap_entry.next;
    5230         r_cleanup_fsm = CLEANUP_HEAP_CLEAN;
    5231       }
    5232       // test the next in the linked list
    5233       else
    5234       {
    5235         r_cleanup_prev_ptr      = r_cleanup_next_ptr.read();
    5236         r_cleanup_prev_srcid    = heap_entry.owner.srcid;
    5237         r_cleanup_prev_inst     = heap_entry.owner.inst;
    5238         r_cleanup_next_ptr      = heap_entry.next;
    5239 
    5240         r_cleanup_fsm           = CLEANUP_HEAP_SEARCH;
    5241 
    5242 #if L1_MULTI_CACHE
    5243         r_cleanup_prev_cache_id = heap_entry.owner.cache_id;
    5244 #endif
    5245       }
    5246 
    5247 #if DEBUG_MEMC_CLEANUP
    5248       if(m_debug)
    5249       {
     5183if(m_debug)
     5184{
    52505185        if(not match_heap)
    52515186        {
     
    52625197              << std::endl;
    52635198        }
    5264 
    52655199        std::cout
    52665200            << " address = "      << r_cleanup_nline.read() * m_words * 4
     
    52715205            << " / last = "       << last
    52725206            << std::endl;
    5273       }
    5274 #endif
    5275       break;
    5276     }
    5277     ////////////////////////
    5278     case CLEANUP_HEAP_CLEAN:    // remove a copy in the linked list
    5279     {
    5280       if(r_alloc_heap_fsm.read() != ALLOC_HEAP_CLEANUP)
    5281       {
    5282         std::cout
    5283             << "VCI_MEM_CACHE ERROR " << name()
    5284             << " CLEANUP_HEAP_CLEAN state"
    5285             << "Bad HEAP allocation"  << std::endl;
    5286 
    5287         exit(0);
    5288       }
    5289 
    5290       HeapEntry heap_entry;
    5291       heap_entry.owner.srcid    = r_cleanup_prev_srcid.read();
    5292       heap_entry.owner.inst     = r_cleanup_prev_inst.read();
    5293 
    5294 #if L1_MULTI_CACHE
    5295       heap_entry.owner.cache_id = r_cleanup_prev_cache_id.read();
    5296 #endif
    5297 
    5298       bool last = (r_cleanup_next_ptr.read() == r_cleanup_ptr.read());
    5299 
    5300       // this is the last entry of the list of copies
    5301       if(last)
    5302       {
    5303         heap_entry.next = r_cleanup_prev_ptr.read();
    5304       }
    5305       // this is not the last entry
    5306       else
    5307       {
    5308         heap_entry.next = r_cleanup_ptr.read();
    5309       }
    5310 
    5311       m_heap.write(r_cleanup_prev_ptr.read(), heap_entry);
    5312 
    5313       r_cleanup_fsm = CLEANUP_HEAP_FREE;
     5207}
     5208#endif
     5209          break;
     5210      }
     5211      ////////////////////////
     5212      case CLEANUP_HEAP_CLEAN:    // remove a copy in the linked list
     5213      {
     5214          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP) and
     5215          "MEMC ERROR in CLEANUP_HEAP_LOCK state: bad HEAP allocation");
     5216
     5217          HeapEntry heap_entry;
     5218          heap_entry.owner.srcid    = r_cleanup_prev_srcid.read();
     5219          heap_entry.owner.inst     = r_cleanup_prev_inst.read();
     5220          bool last = (r_cleanup_next_ptr.read() == r_cleanup_ptr.read());
     5221
     5222          if (last)     // this is the last entry of the list of copies
     5223          {
     5224              heap_entry.next = r_cleanup_prev_ptr.read();
     5225          }
     5226          else          // this is not the last entry
     5227          {
     5228              heap_entry.next = r_cleanup_ptr.read();
     5229          }
     5230
     5231          m_heap.write(r_cleanup_prev_ptr.read(), heap_entry);
     5232
     5233          r_cleanup_fsm = CLEANUP_HEAP_FREE;
    53145234
    53155235#if DEBUG_MEMC_CLEANUP
     
    53185238          << " Remove the copy in the linked list" << std::endl;
    53195239#endif
    5320       break;
    5321     }
    5322     ///////////////////////
    5323     case CLEANUP_HEAP_FREE:   // The heap entry pointed by r_cleanup_next_ptr is freed
    5324                               // and becomes the head of the list of free entries
    5325     {
    5326       if(r_alloc_heap_fsm.read() != ALLOC_HEAP_CLEANUP)
    5327       {
    5328         std::cout
    5329             << "VCI_MEM_CACHE ERROR " << name()
    5330             << " CLEANUP_HEAP_CLEAN state" << std::endl
    5331             << "Bad HEAP allocation" << std::endl;
    5332 
    5333         exit(0);
    5334       }
    5335 
    5336       HeapEntry heap_entry;
    5337       heap_entry.owner.srcid    = 0;
    5338       heap_entry.owner.inst     = false;
    5339 
    5340 #if L1_MULTI_CACHE
    5341       heap_entry.owner.cache_id = 0;
    5342 #endif
    5343 
    5344       if(m_heap.is_full())
    5345       {
    5346         heap_entry.next = r_cleanup_next_ptr.read();
    5347       }
    5348       else
    5349       {
    5350         heap_entry.next = m_heap.next_free_ptr();
    5351       }
    5352 
    5353       m_heap.write(r_cleanup_next_ptr.read(),heap_entry);
    5354       m_heap.write_free_ptr(r_cleanup_next_ptr.read());
    5355       m_heap.unset_full();
    5356 
    5357       r_cleanup_fsm = CLEANUP_SEND_CLACK;
     5240          break;
     5241      }
     5242      ///////////////////////
     5243      case CLEANUP_HEAP_FREE:   // The heap entry pointed by r_cleanup_next_ptr is freed
     5244                                // and becomes the head of the list of free entries
     5245      {
     5246          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP) and
     5247          "MEMC ERROR in CLEANUP_HEAP_LOCK state: bad HEAP allocation");
     5248
     5249          HeapEntry heap_entry;
     5250          heap_entry.owner.srcid    = 0;
     5251          heap_entry.owner.inst     = false;
     5252
     5253          if(m_heap.is_full())
     5254          {
     5255              heap_entry.next = r_cleanup_next_ptr.read();
     5256          }
     5257          else
     5258          {
     5259              heap_entry.next = m_heap.next_free_ptr();
     5260          }
     5261
     5262          m_heap.write(r_cleanup_next_ptr.read(),heap_entry);
     5263          m_heap.write_free_ptr(r_cleanup_next_ptr.read());
     5264          m_heap.unset_full();
     5265
     5266          r_cleanup_fsm = CLEANUP_SEND_CLACK;
    53585267
    53595268#if DEBUG_MEMC_CLEANUP
     
    53625271          << " Update the list of free entries" << std::endl;
    53635272#endif
    5364       break;
    5365     }
    5366     //////////////////////
    5367     case CLEANUP_IVT_LOCK:   // get the lock protecting the IVT to search a pending
    5368                              // invalidate transaction matching the cleanup
    5369     {
    5370       m_cpt_cleanup_fsm_upt_lock++;
    5371       if(r_alloc_ivt_fsm.read() != ALLOC_IVT_CLEANUP) break;
    5372 
    5373       size_t index = 0;
    5374       bool   match_inval;
    5375 
    5376       match_inval = m_ivt.search_inval(r_cleanup_nline.read(), index);
     5273          break;
     5274      }
     5275      //////////////////////
     5276      case CLEANUP_IVT_LOCK:   // get the lock protecting the IVT to search a pending
     5277                               // invalidate transaction matching the cleanup
     5278      {
     5279          if(r_alloc_ivt_fsm.read() != ALLOC_IVT_CLEANUP) break;
     5280
     5281          size_t index = 0;
     5282          bool   match_inval;
     5283
     5284          match_inval = m_ivt.search_inval(r_cleanup_nline.read(), index);
    53775285
    53785286      if ( not match_inval )     // no pending inval
     
    53905298#if DEBUG_MEMC_CLEANUP
    53915299if(m_debug)
    5392 std::cout << "  <MEMC " << name()
    5393           << " CLEANUP_IVT_LOCK> Unexpected cleanup"
    5394           << " with no corresponding IVT entry:"
    5395           << " address = " << std::hex
    5396           << (r_cleanup_nline.read() *4*m_words)
    5397           << std::endl;
    5398 #endif
    5399       m_cpt_cleanup_fsm_n_upt_lock++;
    5400         break;
    5401       }
    5402 
    5403       // pending inval
    5404       r_cleanup_write_srcid = m_ivt.srcid(index);
    5405       r_cleanup_write_trdid = m_ivt.trdid(index);
    5406       r_cleanup_write_pktid = m_ivt.pktid(index);
    5407       r_cleanup_need_rsp    = m_ivt.need_rsp(index);
    5408       r_cleanup_need_ack    = m_ivt.need_ack(index);
    5409       r_cleanup_index       = index;
    5410 
    5411       r_cleanup_fsm         = CLEANUP_IVT_DECREMENT;
     5300std::cout << "  <MEMC " << name() << " CLEANUP_IVT_LOCK>"
     5301          << " Unexpected cleanup with no corresponding IVT entry:"
     5302          << " address = " << std::hex << (r_cleanup_nline.read()*4*m_words) << std::endl;
     5303#endif
     5304        break;
     5305      }
     5306      else                     // pending inval in IVT
     5307      {
     5308        r_cleanup_write_srcid = m_ivt.srcid(index);
     5309        r_cleanup_write_trdid = m_ivt.trdid(index);
     5310        r_cleanup_write_pktid = m_ivt.pktid(index);
     5311        r_cleanup_need_rsp    = m_ivt.need_rsp(index);
     5312        r_cleanup_need_ack    = m_ivt.need_ack(index);
     5313        r_cleanup_index       = index;
     5314        r_cleanup_fsm         = CLEANUP_IVT_DECREMENT;
    54125315
    54135316#if DEBUG_MEMC_CLEANUP
    5414 if(m_debug)
    5415 std::cout << "  <MEMC " << name()
    5416           << " CLEANUP_IVT_LOCK> Cleanup matching pending"
    5417           << " invalidate transaction on IVT:"
    5418           << " address = " << std::hex << r_cleanup_nline.read() * m_words * 4
    5419           << " / ivt_entry = " << index << std::endl;
    5420 #endif
     5317        if(m_debug)
     5318          std::cout << "  <MEMC " << name() << " CLEANUP_IVT_LOCK>"
     5319            << " Cleanup matching pending invalidate transaction on IVT:"
     5320            << " address = " << std::hex << (r_cleanup_nline.read()*m_words*4)
     5321            << " / ivt_entry = " << index << std::endl;
     5322#endif
     5323      }
    54215324      break;
    5422     }
    5423     ///////////////////////////
    5424     case CLEANUP_IVT_DECREMENT: // decrement response counter in IVT matching entry
    5425     {
    5426       if(r_alloc_ivt_fsm.read() != ALLOC_IVT_CLEANUP)
    5427       {
    5428         std::cout
    5429             << "VCI_MEM_CACHE ERROR "         << name()
    5430             << " CLEANUP_IVT_DECREMENT state" << std::endl
    5431             << "Bad IVT allocation"
    5432             << std::endl;
    5433 
    5434         exit(0);
    5435       }
    5436 
    5437       size_t count = 0;
    5438       m_ivt.decrement(r_cleanup_index.read(), count);
    5439 
    5440       if(count == 0)   // multi inval transaction completed
    5441       {
    5442         r_cleanup_fsm = CLEANUP_IVT_CLEAR;
    5443       }
    5444       else             // multi inval transaction not completed
    5445       {
    5446         /*ODCCP*/ // If cleanup is on no coherent line we go to CLEANUP_IXR_REQ
    5447         if (r_cleanup_ncc.read())
    5448         {
    5449           r_cleanup_fsm = CLEANUP_IXR_REQ;
    5450         }
    5451         else
    5452         {
    5453           r_cleanup_fsm = CLEANUP_SEND_CLACK;
    5454         }
    5455       }
     5325      }
     5326      ///////////////////////////
     5327      case CLEANUP_IVT_DECREMENT: // decrement response counter in IVT matching entry
     5328                                  // and test if last
     5329      {
     5330          assert( (r_alloc_ivt_fsm.read() == ALLOC_IVT_CLEANUP) and
     5331          "MEMC ERROR in CLEANUP_IVT_DECREMENT state: Bad IVT allocation");
     5332
     5333          size_t count = 0;
     5334          m_ivt.decrement(r_cleanup_index.read(), count);
     5335
     5336          if(count == 0)   // multi inval transaction completed
     5337          {
     5338            r_cleanup_fsm = CLEANUP_IVT_CLEAR;
     5339          }
     5340          else             // multi inval transaction not completed
     5341          {
     5342            /*ODCCP*/ // If cleanup is on no coherent line we go to CLEANUP_IXR_REQ
     5343            if (r_cleanup_ncc.read())
     5344            {
     5345              r_cleanup_fsm = CLEANUP_IXR_REQ;
     5346            }
     5347            else
     5348            {
     5349              r_cleanup_fsm = CLEANUP_SEND_CLACK;
     5350            }
     5351          }
    54565352
    54575353#if DEBUG_MEMC_CLEANUP
     
    54595355std::cout << "  <MEMC " << name() << " CLEANUP_IVT_DECREMENT>"
    54605356          << " Decrement response counter in IVT:"
    5461             << " IVT_index = " << r_cleanup_index.read()
    5462             << " / rsp_count = " << count << std::endl;
    5463 #endif
    5464       break;
    5465     }
    5466     ///////////////////////
    5467     case CLEANUP_IVT_CLEAR:    // Clear IVT entry
    5468     {
    5469       if(r_alloc_ivt_fsm.read() != ALLOC_IVT_CLEANUP)
    5470       {
    5471         std::cout
    5472             << "VCI_MEM_CACHE ERROR "     << name()
    5473             << " CLEANUP_IVT_CLEAR state" << std::endl
    5474             << "Bad IVT allocation"
    5475             << std::endl;
    5476 
    5477         exit(0);
    5478       }
    5479 
    5480       m_ivt.clear(r_cleanup_index.read());
     5357          << " IVT_index = " << r_cleanup_index.read()
     5358          << " / rsp_count = " << count << std::endl;
     5359#endif
     5360          break;
     5361      }
     5362      ///////////////////////
     5363      case CLEANUP_IVT_CLEAR:    // Clear IVT entry
     5364                                 // Acknowledge CONFIG FSM if required
     5365      {
     5366          assert( (r_alloc_ivt_fsm.read() == ALLOC_IVT_CLEANUP) and
     5367          "MEMC ERROR in CLEANUP_IVT_CLEAR state : bad IVT allocation");
     5368
     5369          m_ivt.clear(r_cleanup_index.read());
     5370
     5371          if ( r_cleanup_need_ack.read() )
     5372          {
     5373              assert( (r_config_rsp_lines.read() > 0) and
     5374              "MEMC ERROR in CLEANUP_IVT_CLEAR state");
     5375   
     5376              r_config_rsp_lines = r_config_rsp_lines.read() - 1;
     5377          }
    54815378
    54825379      if      ( r_cleanup_need_rsp.read() ) r_cleanup_fsm = CLEANUP_WRITE_RSP;
    5483       else if ( r_cleanup_need_ack.read() ) r_cleanup_fsm = CLEANUP_CONFIG_ACK;
    54845380      else if ( r_cleanup_ncc.read()      ) r_cleanup_fsm = CLEANUP_IXR_REQ;
    54855381      else                                  r_cleanup_fsm = CLEANUP_SEND_CLACK;
     
    54915387          << " IVT_index = " << r_cleanup_index.read() << std::endl;
    54925388#endif
    5493       break;
    5494     }
    5495     ///////////////////////
    5496     case CLEANUP_WRITE_RSP:    // response to a previous write on the direct network
     5389          break;
     5390      }
     5391      ///////////////////////
     5392      case CLEANUP_WRITE_RSP:    // response to a previous write on the direct network
    54975393                               // wait if pending request to the TGT_RSP FSM
    5498     {
    5499       if(r_cleanup_to_tgt_rsp_req.read()) break;
    5500 
    5501       // no pending request
    5502       r_cleanup_to_tgt_rsp_req     = true;
    5503       r_cleanup_to_tgt_rsp_srcid   = r_cleanup_write_srcid.read();
    5504       r_cleanup_to_tgt_rsp_trdid   = r_cleanup_write_trdid.read();
    5505       r_cleanup_to_tgt_rsp_pktid   = r_cleanup_write_pktid.read();
    5506 
    5507       /*ODCCP*/ // If cleanup is on no coherent line we go to CLEANUP_IXR_REQ
    5508       if (r_cleanup_ncc.read())
    5509       {
    5510         r_cleanup_fsm = CLEANUP_IXR_REQ;
    5511       }
    5512       else
    5513       {
    5514         r_cleanup_fsm = CLEANUP_SEND_CLACK;
    5515       }
     5394      {
     5395          if(r_cleanup_to_tgt_rsp_req.read()) break;
     5396
     5397          // no pending request
     5398          r_cleanup_to_tgt_rsp_req     = true;
     5399          r_cleanup_to_tgt_rsp_srcid   = r_cleanup_write_srcid.read();
     5400          r_cleanup_to_tgt_rsp_trdid   = r_cleanup_write_trdid.read();
     5401          r_cleanup_to_tgt_rsp_pktid   = r_cleanup_write_pktid.read();
     5402
     5403          /*ODCCP*/ // If cleanup is on no coherent line we go to CLEANUP_IXR_REQ
     5404          if (r_cleanup_ncc.read())
     5405          {
     5406            r_cleanup_fsm = CLEANUP_IXR_REQ;
     5407          }
     5408          else
     5409          {
     5410            r_cleanup_fsm = CLEANUP_SEND_CLACK;
     5411          }
    55165412
    55175413#if DEBUG_MEMC_CLEANUP
     
    55235419          << " / rpktid = " << r_cleanup_write_pktid.read() << std::endl;
    55245420#endif
    5525       break;
    5526     }
    5527     ////////////////////////
    5528     case CLEANUP_CONFIG_ACK:   // signals inval completion to CONFIG FSM
    5529                                // wait if pending request
    5530     {
    5531       if ( r_cleanup_to_config_ack.read() ) break;
    5532       r_cleanup_to_config_ack      = true;
    5533       r_cleanup_fsm                = CLEANUP_SEND_CLACK;
    5534 
    5535 #if DEBUG_MEMC_CLEANUP
    5536 if(m_debug)
    5537 std::cout << "  <MEMC " << name() << " CLEANUP_CONFIG_ACK>"
    5538           << " Acknowledge broacast inval completion" << std::endl;
    5539 #endif
    5540       break;
    5541     }
     5421          break;
     5422      }
    55425423
    55435424    /*ODCCP*/
     
    55605441            r_cleanup_to_ixr_cmd_req          = r_cleanup_contains_data.read();
    55615442            r_cleanup_to_ixr_cmd_srcid        = r_cleanup_srcid.read();
    5562             r_cleanup_to_ixr_cmd_trdid        = m_trt_lines;
     5443            r_cleanup_to_ixr_cmd_index        = m_trt_lines;
    55635444            r_cleanup_to_ixr_cmd_pktid        = r_cleanup_pktid.read();
    55645445            r_cleanup_to_ixr_cmd_nline        = r_cleanup_nline.read();
     
    56045485          }
    56055486          r_cleanup_to_ixr_cmd_srcid        = r_cleanup_srcid.read();
    5606           r_cleanup_to_ixr_cmd_trdid        = index;
     5487          r_cleanup_to_ixr_cmd_index        = index;
    56075488          r_cleanup_to_ixr_cmd_pktid        = r_cleanup_pktid.read();
    56085489          r_cleanup_to_ixr_cmd_nline        = r_cleanup_nline.read();
     
    56525533std::cout << "  <MEMC " << name()
    56535534          << " CLEANUP_SEND_CLACK> Send the response to a cleanup request:"
    5654           << " nline = "   << std::hex << r_cleanup_nline.read()
     5535          << " address = "   << std::hex << r_cleanup_nline.read()*m_words*4
    56555536          << " / way = "   << std::dec << r_cleanup_way.read()
    56565537          << " / srcid = " << std::dec << r_cleanup_srcid.read()
    56575538          << std::endl;
    56585539#endif
    5659       break;
    5660     }
     5540          break;
     5541      }
    56615542  } // end switch cleanup fsm
    56625543
     
    56645545  //    CAS FSM
    56655546  ////////////////////////////////////////////////////////////////////////////////////
    5666   // The CAS FSM handles the CAS (Store Conditionnal) atomic commands,
    5667   // that are handled as "compare-and-swap instructions.
     5547  // The CAS FSM handles the CAS (Compare And Swap) atomic commands.
    56685548  //
    56695549  // This command contains two or four flits:
    56705550  // - In case of 32 bits atomic access, the first flit contains the value read
    5671   // by a previous LL instruction, the second flit contains the value to be writen.
     5551  // by a previous READ instruction, the second flit contains the value to be writen.
    56725552  // - In case of 64 bits atomic access, the 2 first flits contains the value read
    5673   // by a previous LL instruction, the 2 next flits contains the value to be writen.
     5553  // by a previous READ instruction, the 2 next flits contains the value to be writen.
    56745554  //
    56755555  // The target address is cachable. If it is replicated in other L1 caches
     
    56785558  // It access the directory to check hit / miss.
    56795559  // - In case of miss, the CAS FSM must register a GET transaction in TRT.
    5680   // If a read transaction to the XRAM for this line already exists,
    5681   // or if the transaction table is full, it goes to the WAIT state
    5682   // to release the locks and try again. When the GET transaction has been
    5683   // launched, it goes to the WAIT state and try again.
    5684   // The CAS request is not consumed in the FIFO until a HIT is obtained.
     5560  //   If a read transaction to the XRAM for this line already exists,
     5561  //   or if the transaction table is full, it goes to the WAIT state
     5562  //   to release the locks and try again. When the GET transaction has been
     5563  //   launched, it goes to the WAIT state and try again.
     5564  //   The CAS request is not consumed in the FIFO until a HIT is obtained.
    56855565  // - In case of hit...
    56865566  ///////////////////////////////////////////////////////////////////////////////////
    56875567
     5568//std::cout << std::endl << "cas_fsm" << std::endl;
     5569
    56885570  switch(r_cas_fsm.read())
    56895571  {
    5690       /////////////
     5572    ////////////
    56915573    case CAS_IDLE:     // fill the local rdata buffers
    56925574    {
    5693       if(m_cmd_cas_addr_fifo.rok())
    5694       {
     5575        if (m_cmd_cas_addr_fifo.rok() )
     5576        {
    56955577
    56965578#if DEBUG_MEMC_CAS
    5697         if(m_debug)
    5698         {
    5699           std::cout << "  <MEMC " << name() << " CAS_IDLE> CAS command: " << std::hex
    5700                     << " srcid = " <<  std::dec << m_cmd_cas_srcid_fifo.read()
    5701                     << " addr = " << std::hex << m_cmd_cas_addr_fifo.read()
    5702                     << " wdata = " << m_cmd_cas_wdata_fifo.read()
    5703                     << " eop = " << std::dec << m_cmd_cas_eop_fifo.read()
    5704                     << " cpt  = " << std::dec << r_cas_cpt.read() << std::endl;
    5705         }
    5706 #endif
    5707         if(m_cmd_cas_eop_fifo.read())
    5708         {
    5709           m_cpt_cas++;
    5710           r_cas_fsm = CAS_DIR_REQ;
    5711         }
    5712         else  // we keep the last word in the FIFO
    5713         {
    5714           cmd_cas_fifo_get = true;
    5715         }
    5716         // We fill the two buffers
    5717         if(r_cas_cpt.read() < 2)    // 32 bits access
    5718           r_cas_rdata[r_cas_cpt.read()] = m_cmd_cas_wdata_fifo.read();
    5719 
    5720         if((r_cas_cpt.read() == 1) and m_cmd_cas_eop_fifo.read())
    5721           r_cas_wdata = m_cmd_cas_wdata_fifo.read();
    5722 
    5723         if(r_cas_cpt.read() >3)  // more than 4 flits...
    5724         {
    5725           std::cout << "VCI_MEM_CACHE ERROR in CAS_IDLE state : illegal CAS command"
    5726                     << std::endl;
    5727           exit(0);
    5728         }
    5729 
    5730         if(r_cas_cpt.read() ==2)
    5731           r_cas_wdata = m_cmd_cas_wdata_fifo.read();
    5732 
    5733         r_cas_cpt = r_cas_cpt.read() +1;
    5734       }
    5735       break;
    5736     }
    5737 
     5579if(m_debug)
     5580std::cout << "  <MEMC " << name() << " CAS_IDLE> CAS command: " << std::hex
     5581          << " srcid = " <<  std::dec << m_cmd_cas_srcid_fifo.read()
     5582          << " addr = " << std::hex << m_cmd_cas_addr_fifo.read()
     5583          << " wdata = " << m_cmd_cas_wdata_fifo.read()
     5584          << " eop = " << std::dec << m_cmd_cas_eop_fifo.read()
     5585          << " cpt  = " << std::dec << r_cas_cpt.read() << std::endl;
     5586#endif
     5587            if(m_cmd_cas_eop_fifo.read())
     5588            {
     5589                m_cpt_cas++;
     5590                r_cas_fsm = CAS_DIR_REQ;
     5591            }
     5592            else  // we keep the last word in the FIFO
     5593            {
     5594                cmd_cas_fifo_get = true;
     5595            }
     5596
     5597            // We fill the two buffers
     5598            if(r_cas_cpt.read() < 2)    // 32 bits access
     5599                r_cas_rdata[r_cas_cpt.read()] = m_cmd_cas_wdata_fifo.read();
     5600
     5601            if((r_cas_cpt.read() == 1) and m_cmd_cas_eop_fifo.read())
     5602                r_cas_wdata = m_cmd_cas_wdata_fifo.read();
     5603
     5604            assert( (r_cas_cpt.read() <= 3) and  // no more than 4 flits...
     5605            "MEMC ERROR in CAS_IDLE state: illegal CAS command");
     5606
     5607            if(r_cas_cpt.read() ==2)
     5608                r_cas_wdata = m_cmd_cas_wdata_fifo.read();
     5609
     5610            r_cas_cpt = r_cas_cpt.read() +1;
     5611        }
     5612        break;
     5613    }
    57385614    /////////////////
    57395615    case CAS_DIR_REQ:
    57405616    {
    5741       if(r_alloc_dir_fsm.read() == ALLOC_DIR_CAS)
    5742       {
    5743         r_cas_fsm = CAS_DIR_LOCK;
    5744         m_cpt_cas_fsm_n_dir_lock++;
    5745       }
     5617        if(r_alloc_dir_fsm.read() == ALLOC_DIR_CAS)
     5618        {
     5619            r_cas_fsm = CAS_DIR_LOCK;
     5620        }