Ignore:
Timestamp:
Aug 9, 2013, 11:00:05 AM (10 years ago)
Author:
alain
Message:

Implement both the SYNC and INVAL configuration commands.
Uses the TRT to transmit the cache line to XRAM in cPUT transactions.
Improve the debug.

File:
1 edited

Legend:

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

    r483 r489  
    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
     
    124124  "MULTI_ACK_UPT_LOCK",
    125125  "MULTI_ACK_UPT_CLEAR",
    126   "MULTI_ACK_WRITE_RSP",
    127   "MULTI_ACK_CONFIG_ACK"
     126  "MULTI_ACK_WRITE_RSP"
    128127};
    129128const char *config_fsm_str[] =
     
    131130  "CONFIG_IDLE",
    132131  "CONFIG_LOOP",
     132  "CONFIG_WAIT",
    133133  "CONFIG_RSP",
    134134  "CONFIG_DIR_REQ",
    135135  "CONFIG_DIR_ACCESS",
    136   "CONFIG_DIR_IVT_LOCK",
     136  "CONFIG_IVT_LOCK",
    137137  "CONFIG_BC_SEND",
    138   "CONFIG_BC_WAIT",
    139   "CONFIG_INV_SEND",
     138  "CONFIG_INVAL_SEND",
    140139  "CONFIG_HEAP_REQ",
    141140  "CONFIG_HEAP_SCAN",
    142141  "CONFIG_HEAP_LAST",
    143   "CONFIG_INV_WAIT"
     142  "CONFIG_TRT_LOCK",
     143  "CONFIG_TRT_SET",
     144  "CONFIG_PUT_REQ"
    144145};
    145146const char *read_fsm_str[] =
     
    165166  "WRITE_DIR_REQ",
    166167  "WRITE_DIR_LOCK",
    167   "WRITE_DIR_READ",
    168168  "WRITE_DIR_HIT",
    169169  "WRITE_UPT_LOCK",
     
    177177  "WRITE_MISS_TRT_SET",
    178178  "WRITE_MISS_XRAM_REQ",
     179  "WRITE_BC_DIR_READ",
    179180  "WRITE_BC_TRT_LOCK",
    180181  "WRITE_BC_IVT_LOCK",
     
    187188{
    188189  "IXR_RSP_IDLE",
    189   "IXR_RSP_ACK",
    190190  "IXR_RSP_TRT_ERASE",
    191191  "IXR_RSP_TRT_READ"
     
    199199  "XRAM_RSP_DIR_UPDT",
    200200  "XRAM_RSP_DIR_RSP",
    201   "XRAM_RSP_INVAL_LOCK",
     201  "XRAM_RSP_IVT_LOCK",
    202202  "XRAM_RSP_INVAL_WAIT",
    203203  "XRAM_RSP_INVAL",
     
    215215  "IXR_CMD_CAS_IDLE",
    216216  "IXR_CMD_XRAM_IDLE",
    217   "IXR_CMD_READ",
    218   "IXR_CMD_WRITE",
    219   "IXR_CMD_CAS",
    220   "IXR_CMD_XRAM"
     217  "IXR_CMD_CONFIG_IDLE",
     218  "IXR_CMD_READ_TRT",
     219  "IXR_CMD_WRITE_TRT",
     220  "IXR_CMD_CAS_TRT",
     221  "IXR_CMD_XRAM_TRT",
     222  "IXR_CMD_CONFIG_TRT",
     223  "IXR_CMD_READ_SEND",
     224  "IXR_CMD_WRITE_SEND",
     225  "IXR_CMD_CAS_SEND",
     226  "IXR_CMD_XRAM_SEND",
     227  "IXR_CMD_CONFIG_SEND"
    221228};
    222229const char *cas_fsm_str[] =
     
    260267  "CLEANUP_IVT_CLEAR",
    261268  "CLEANUP_WRITE_RSP",
    262   "CLEANUP_CONFIG_ACK",
    263269  "CLEANUP_SEND_CLACK"
    264270};
     
    279285  "ALLOC_TRT_CAS",
    280286  "ALLOC_TRT_XRAM_RSP",
    281   "ALLOC_TRT_IXR_RSP"
     287  "ALLOC_TRT_IXR_RSP",
     288  "ALLOC_TRT_CONFIG",
     289  "ALLOC_TRT_IXR_CMD"
    282290};
    283291const char *alloc_upt_fsm_str[] =
     
    380388    m_broadcast_boundaries(0x7C1F),
    381389
    382     r_tgt_cmd_fsm("r_tgt_cmd_fsm"),
    383390
    384391    //  FIFOs
     
    407414    m_cc_receive_to_multi_ack_fifo("m_cc_receive_to_multi_ack_fifo", 4),
    408415
     416    r_tgt_cmd_fsm("r_tgt_cmd_fsm"),
     417
    409418    r_config_fsm( "r_config_fsm" ),
    410419
     
    418427    m_write_to_cc_send_inst_fifo("m_write_to_cc_send_inst_fifo",8),
    419428    m_write_to_cc_send_srcid_fifo("m_write_to_cc_send_srcid_fifo",8),
    420 #if L1_MULTI_CACHE
    421     m_write_to_cc_send_cache_id_fifo("m_write_to_cc_send_cache_id_fifo",8),
    422 #endif
    423429
    424430    r_multi_ack_fsm("r_multi_ack_fsm"),
     
    430436    m_cas_to_cc_send_inst_fifo("m_cas_to_cc_send_inst_fifo",8),
    431437    m_cas_to_cc_send_srcid_fifo("m_cas_to_cc_send_srcid_fifo",8),
    432 #if L1_MULTI_CACHE
    433     m_cas_to_cc_send_cache_id_fifo("m_cas_to_cc_send_cache_id_fifo",8),
    434 #endif
    435438
    436439    r_ixr_rsp_fsm("r_ixr_rsp_fsm"),
     
    439442    m_xram_rsp_to_cc_send_inst_fifo("m_xram_rsp_to_cc_send_inst_fifo",8),
    440443    m_xram_rsp_to_cc_send_srcid_fifo("m_xram_rsp_to_cc_send_srcid_fifo",8),
    441 #if L1_MULTI_CACHE
    442     m_xram_rsp_to_cc_send_cache_id_fifo("m_xram_rsp_to_cc_send_cache_id_fifo",8),
    443 #endif
    444444
    445445    r_ixr_cmd_fsm("r_ixr_cmd_fsm"),
     
    509509    r_xram_rsp_victim_data     = new sc_signal<data_t>[nwords];
    510510    r_xram_rsp_to_tgt_rsp_data = new sc_signal<data_t>[nwords];
    511     r_xram_rsp_to_ixr_cmd_data = new sc_signal<data_t>[nwords];
    512511
    513512    // Allocation for READ FSM
     
    520519    r_write_to_cc_send_data    = new sc_signal<data_t>[nwords];
    521520    r_write_to_cc_send_be      = new sc_signal<be_t>[nwords];
    522     r_write_to_ixr_cmd_data    = new sc_signal<data_t>[nwords];
    523521
    524522    // Allocation for CAS FSM
    525     r_cas_to_ixr_cmd_data      = new sc_signal<data_t>[nwords];
    526523    r_cas_data                 = new sc_signal<data_t>[nwords];
    527524    r_cas_rdata                = new sc_signal<data_t>[2];
    528525
     526    // Allocation for IXR_CMD FSM
     527    r_ixr_cmd_wdata            = new sc_signal<data_t>[nwords];
     528
    529529    // Allocation for debug
    530     m_debug_previous_data      = new sc_signal<data_t>[nwords];
    531     m_debug_data               = new sc_signal<data_t>[nwords];
     530    m_debug_previous_data      = new data_t[nwords];
     531    m_debug_data               = new data_t[nwords];
    532532
    533533    SC_METHOD(transition);
     
    540540} // end constructor
    541541
    542 ///////////////////////////////////////////////////////////////////////
    543 tmpl(void) ::start_monitor(addr_t addr, addr_t length)
    544 ///////////////////////////////////////////////////////////////////////
    545 {
    546   m_monitor_ok        = true;
    547   m_monitor_base      = addr;
    548   m_monitor_length    = length;
    549 }
    550 
    551 ///////////////////////////////////////////////////////////////////////
    552 tmpl(void) ::stop_monitor()
    553 ///////////////////////////////////////////////////////////////////////
    554 {
    555   m_monitor_ok        = false;
    556 }
    557 
    558 ////////////////////////////////////////////////
    559 tmpl(void) ::check_monitor( addr_t      addr,
    560                             data_t      data,
    561                             bool        read )
    562 ////////////////////////////////////////////////
    563 {
    564   if((addr >= m_monitor_base) and
    565       (addr < m_monitor_base + m_monitor_length))
    566   {
    567     if ( read ) std::cout << " Monitor MEMC Read ";
    568     else        std::cout << " Monitor MEMC Write";
    569     std::cout << " / Address = " << std::hex << addr
    570               << " / Data = " << data
    571               << " at cycle " << std::dec << m_cpt_cycles << std::endl;
    572   }
    573 }
    574542
    575543/////////////////////////////////////////////////////
     
    581549    DirectoryEntry entry = m_cache_directory.read_neutral(addr, &way, &set );
    582550
     551    // read data and compute data_change
    583552    bool data_change = false;
    584 
    585553    if ( entry.valid )
    586554    {
    587         m_cache_data.read_line( way, set, m_debug_data );
    588 
    589         for ( size_t i = 0 ; i<m_words ; i++ )
    590         {
    591             if ( m_debug_previous_valid and
    592                  (m_debug_data[i].read() != m_debug_previous_data[i].read()) )
    593                  data_change = true;
    594             m_debug_previous_data[i] = m_debug_data[i].read();
     555        for ( size_t word = 0 ; word<m_words ; word++ )
     556        {
     557            m_debug_data[word] = m_cache_data.read(way, set, word);
     558            if ( m_debug_previous_valid and
     559                 (m_debug_data[word] != m_debug_previous_data[word]) )
     560            {
     561                data_change = true;
     562            }
    595563        }
    596564    }
    597565   
     566    // print values if any change
    598567    if ( (entry.valid != m_debug_previous_valid) or
    599568         (entry.valid and (entry.count != m_debug_previous_count)) or
     
    603572                  << " at cycle " << std::dec << m_cpt_cycles
    604573                  << " for address " << std::hex << addr
    605                   << " / HIT = " << std::dec << entry.valid
     574                  << " / VAL = " << std::dec << entry.valid
    606575                  << " / WAY = " << way
    607576                  << " / COUNT = " << entry.count
    608577                  << " / DIRTY = " << entry.dirty
    609                   << " / DATA_CHANGE = " << entry.count
     578                  << " / DATA_CHANGE = " << data_change
    610579                  << std::endl;
    611     }
     580        std::cout << std::hex << "     /0:" << m_debug_data[0]
     581                  << "/1:" << m_debug_data[1]
     582                  << "/2:" << m_debug_data[2]
     583                  << "/3:" << m_debug_data[3]
     584                  << "/4:" << m_debug_data[4]
     585                  << "/5:" << m_debug_data[5]
     586                  << "/6:" << m_debug_data[6]
     587                  << "/7:" << m_debug_data[7]
     588                  << "/8:" << m_debug_data[8]
     589                  << "/9:" << m_debug_data[9]
     590                  << "/A:" << m_debug_data[10]
     591                  << "/B:" << m_debug_data[11]
     592                  << "/C:" << m_debug_data[12]
     593                  << "/D:" << m_debug_data[13]
     594                  << "/E:" << m_debug_data[14]
     595                  << "/F:" << m_debug_data[15]
     596                  << std::endl;
     597    }
     598
     599    // register values
    612600    m_debug_previous_count = entry.count;
    613601    m_debug_previous_valid = entry.valid;
    614602    m_debug_previous_dirty = entry.dirty;
     603    for( size_t word=0 ; word<m_words ; word++ )
     604        m_debug_previous_data[word] = m_debug_data[word];
    615605}
    616606
     
    677667  delete [] r_xram_rsp_victim_data;
    678668  delete [] r_xram_rsp_to_tgt_rsp_data;
    679   delete [] r_xram_rsp_to_ixr_cmd_data;
    680669
    681670  delete [] r_read_data;
     
    755744    m_config_to_cc_send_inst_fifo.init();
    756745    m_config_to_cc_send_srcid_fifo.init();
    757 #if L1_MULTI_CACHE
    758     m_config_to_cc_send_cache_id_fifo.init();
    759 #endif
    760746
    761747    r_tgt_cmd_to_tgt_rsp_req = false;
     
    772758    m_write_to_cc_send_inst_fifo.init();
    773759    m_write_to_cc_send_srcid_fifo.init();
    774 #if L1_MULTI_CACHE
    775     m_write_to_cc_send_cache_id_fifo.init();
    776 #endif
    777760
    778761    r_cleanup_to_tgt_rsp_req      = false;
     
    780763    m_cc_receive_to_cleanup_fifo.init();
    781764
    782     r_multi_ack_to_tgt_rsp_req     = false;
     765    r_multi_ack_to_tgt_rsp_req    = false;
    783766
    784767    m_cc_receive_to_multi_ack_fifo.init();
     
    788771    r_cas_lfsr                    = -1   ;
    789772    r_cas_to_ixr_cmd_req          = false;
    790     r_cas_to_cc_send_multi_req   = false;
    791     r_cas_to_cc_send_brdcast_req = false;
     773    r_cas_to_cc_send_multi_req    = false;
     774    r_cas_to_cc_send_brdcast_req  = false;
    792775
    793776    m_cas_to_cc_send_inst_fifo.init();
    794777    m_cas_to_cc_send_srcid_fifo.init();
    795 #if L1_MULTI_CACHE
    796     m_cas_to_cc_send_cache_id_fifo.init();
    797 #endif
    798778
    799779    for(size_t i=0; i<m_trt_lines ; i++)
     
    810790    m_xram_rsp_to_cc_send_inst_fifo.init();
    811791    m_xram_rsp_to_cc_send_srcid_fifo.init();
    812 #if L1_MULTI_CACHE
    813     m_xram_rsp_to_cc_send_cache_id_fifo.init();
    814 #endif
    815 
    816     r_ixr_cmd_cpt          = 0;
     792
    817793    r_alloc_dir_reset_cpt  = 0;
    818794    r_alloc_heap_reset_cpt = 0;
     
    863839  size_t  write_to_cc_send_fifo_srcid = 0;
    864840
    865 #if L1_MULTI_CACHE
    866   size_t  write_to_cc_send_fifo_cache_id = 0;
    867 #endif
    868 
    869841  bool    xram_rsp_to_cc_send_fifo_put   = false;
    870842  bool    xram_rsp_to_cc_send_fifo_get   = false;
     
    872844  size_t  xram_rsp_to_cc_send_fifo_srcid = 0;
    873845
    874 #if L1_MULTI_CACHE
    875   size_t  xram_rsp_to_cc_send_fifo_cache_id = 0;
    876 #endif
    877 
    878846  bool    config_to_cc_send_fifo_put   = false;
    879847  bool    config_to_cc_send_fifo_get   = false;
     
    885853  bool    cas_to_cc_send_fifo_inst  = false;
    886854  size_t  cas_to_cc_send_fifo_srcid = 0;
    887 
    888 #if L1_MULTI_CACHE
    889   size_t  cas_to_cc_send_fifo_cache_id = 0;
    890 #endif
    891855
    892856  m_debug = (m_cpt_cycles > m_debug_start_cycle) and m_debug_ok;
     
    939903  // - For MEMC_CMD_TYPE, the response is delayed until the operation is completed.
    940904  ////////////////////////////////////////////////////////////////////////////////////
     905
     906//std::cout << std::endl << "tgt_cmd_fsm" << std::endl;
    941907
    942908  switch(r_tgt_cmd_fsm.read())
     
    10421008    case TGT_CMD_ERROR:  // response error must be sent
    10431009
    1044     // wait if pending TGT_CMD request to TGT_RSP FSM
     1010    // wait if pending request
    10451011    if(r_tgt_cmd_to_tgt_rsp_req.read()) break;
    10461012
     
    10761042        size_t   error; 
    10771043        uint32_t rdata = 0;         // default value
     1044        uint32_t wdata = p_vci_tgt.wdata.read();
    10781045
    10791046        if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_READ)         // get lock
     
    10841051            error            = 0;
    10851052            r_config_lock    = true;
     1053            if ( rdata == 0 )
     1054            {
     1055                r_tgt_cmd_srcid = p_vci_tgt.srcid.read();
     1056                r_tgt_cmd_trdid = p_vci_tgt.trdid.read();
     1057                r_tgt_cmd_pktid = p_vci_tgt.pktid.read();
     1058            }
    10861059        }
    10871060        else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)  // release lock
    1088                    and (cell == MEMC_LOCK) )
     1061                   and (cell == MEMC_LOCK)
     1062                   and (p_vci_tgt.srcid.read() == r_tgt_cmd_srcid.read()) )
    10891063        {
    10901064            need_rsp         = true;
     
    10931067        }
    10941068        else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set addr_lo
    1095                    and (cell == MEMC_ADDR_LO) )
    1096         {
     1069                   and (cell == MEMC_ADDR_LO)
     1070                   and (p_vci_tgt.srcid.read() == r_tgt_cmd_srcid.read()) )
     1071        {
     1072            assert( ((wdata % (m_words*vci_param_int::B)) == 0) and
     1073            "VCI_MEM_CACHE CONFIG ERROR: The buffer must be aligned on a cache line");
     1074
    10971075            need_rsp         = true;
    10981076            error            = 0;
     
    11011079        }
    11021080        else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set addr_hi
    1103                    and (cell == MEMC_ADDR_HI) )
     1081                   and (cell == MEMC_ADDR_HI)
     1082                   and (p_vci_tgt.srcid.read() == r_tgt_cmd_srcid.read()) )
     1083
    11041084        {
    11051085            need_rsp         = true;
     
    11091089        }
    11101090        else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set buf_lines
    1111                    and (cell == MEMC_BUF_LENGTH) )
     1091                   and (cell == MEMC_BUF_LENGTH)
     1092                   and (p_vci_tgt.srcid.read() == r_tgt_cmd_srcid.read()) )
    11121093        {
    11131094            need_rsp         = true;
    11141095            error            = 0;
    11151096            size_t lines = (size_t)(p_vci_tgt.wdata.read()/(m_words<<2));
    1116             if ( r_config_address.read()/(m_words*vci_param_int::B) ) lines++;
    1117             r_config_nlines  = lines;
     1097            if ( r_config_address.read()%(m_words*4) ) lines++;
     1098            r_config_cmd_lines  = lines;
     1099            r_config_rsp_lines  = lines;
    11181100        }
    11191101        else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set cmd type
    1120                    and (cell == MEMC_CMD_TYPE) )
     1102                   and (cell == MEMC_CMD_TYPE)
     1103                   and (p_vci_tgt.srcid.read() == r_tgt_cmd_srcid.read()) )
    11211104        {
    11221105            need_rsp         = false;
    11231106            error            = 0;
    11241107            r_config_cmd     = p_vci_tgt.wdata.read();
     1108
     1109            // prepare delayed response from CONFIG FSM
    11251110            r_config_srcid   = p_vci_tgt.srcid.read();
    11261111            r_config_trdid   = p_vci_tgt.trdid.read();
     
    11531138          << " address = " << std::hex << p_vci_tgt.address.read()
    11541139          << " / wdata = " << p_vci_tgt.wdata.read()
     1140          << " / need_rsp = " << need_rsp
    11551141          << " / error = " << error << std::endl;
    11561142#endif
     
    12561242  //    MULTI_ACK FSM
    12571243  /////////////////////////////////////////////////////////////////////////
    1258   // This FSM controls the response to the multicast update or multicast
    1259   // inval coherence requests sent by the memory cache to the L1 caches and
    1260   // update the UPT.
     1244  // This FSM controls the response to the multicast update requests sent
     1245  // by the memory cache to the L1 caches and update the UPT.
    12611246  //
    12621247  // - The FSM decrements the proper entry in UPT,
     
    12641249  // - If required, it sends a request to the TGT_RSP FSM to complete
    12651250  //   a pending  write transaction.
    1266   // - If required, it sends an acknowledge to the CONFIG FSM to signal
    1267   //   completion of a line inval.
    12681251  //
    12691252  // All those multi-ack packets are one flit packet.
    1270   // The index in the UPT is defined in the UPDTID field.
     1253  // The index in the UPT is defined in the TRDID field.
    12711254  ////////////////////////////////////////////////////////////////////////
     1255
     1256//std::cout << std::endl << "multi_ack_fsm" << std::endl;
    12721257
    12731258  switch(r_multi_ack_fsm.read())
     
    13811366        r_multi_ack_nline = m_upt.nline(r_multi_ack_upt_index.read());
    13821367        bool need_rsp     = m_upt.need_rsp(r_multi_ack_upt_index.read());
    1383         bool need_ack     = m_upt.need_ack(r_multi_ack_upt_index.read());
    13841368
    13851369        // clear the UPT entry
     
    13871371
    13881372        if      ( need_rsp ) r_multi_ack_fsm = MULTI_ACK_WRITE_RSP;
    1389         else if ( need_ack ) r_multi_ack_fsm = MULTI_ACK_CONFIG_ACK;
    13901373        else                 r_multi_ack_fsm = MULTI_ACK_IDLE;
    13911374
     
    14181401        break;
    14191402    }
    1420     //////////////////////////
    1421     case MULTI_ACK_CONFIG_ACK:    // Signals multi-inval completion to CONFIG FSM
    1422                                   // Wait if pending request
    1423     {
    1424         if ( r_multi_ack_to_config_ack.read() ) break;
    1425 
    1426         r_multi_ack_to_config_ack   = true;
    1427         r_multi_ack_fsm              = MULTI_ACK_IDLE;
    1428 
    1429 #if DEBUG_MEMC_MULTI_ACK
    1430 if(m_debug)
    1431 std::cout << "  <MEMC " << name() << " MULTI_ACK_CONFIG_ACK>"
    1432           << " Signals inval completion to CONFIG FSM" << std::endl;
    1433 #endif
    1434         break;
    1435     }
    14361403  } // end switch r_multi_ack_fsm
    14371404
     
    14411408  // The CONFIG FSM handles the VCI configuration requests (INVAL & SYNC).
    14421409  // The target buffer can have any size, and there is one single command for
    1443   // all cache lines covered by the target buffer.
    1444   // An INVAL or SYNC configuration request is defined by the followinf registers:
    1445   // - bool      r_config_cmd        : INVAL / SYNC / NOP)
     1410  // all cache lines covered by the target buffer.
     1411  //
     1412  // An INVAL or SYNC configuration operation is defined by the following registers:
     1413  // - bool      r_config_cmd        : INVAL / SYNC / NOP
    14461414  // - uint64_t  r_config_address    : buffer base address
    1447   // - uint32_t  r_config_nlines     : number of lines covering buffer
     1415  // - uint32_t  r_config_cmd_lines  : number of lines to be handled
     1416  // - uint32_t  r_config_rsp_lines  : number of lines not completed
    14481417  //
    14491418  // For both INVAL and SYNC commands, the CONFIG FSM contains the loop handling
    1450   // all cache lines covered by the target buffer.
    1451   //
     1419  // all cache lines covered by the buffer. The various lines of a given buffer
     1420  // can be pipelined: the CONFIG FSM does not wait the response for line (n) to send
     1421  // the command for line (n+1). It decrements the r_config_cmd_lines counter until
     1422  // the last request has been registered in TRT (for a SYNC), or in IVT (for an INVAL).
     1423  //
    14521424  // - INVAL request:
    1453   //   For each line, it access to the DIR array.
     1425  //   For each line, it access to the DIR.
    14541426  //   In case of miss, it does nothing, and a response is requested to TGT_RSP FSM.
    14551427  //   In case of hit, with no copies in L1 caches, the line is invalidated and
    14561428  //   a response is requested to TGT_RSP FSM.
    14571429  //   If there is copies, a multi-inval, or a broadcast-inval coherence transaction
    1458   //   is launched and registered in UPT. The multi-inval transaction is signaled
    1459   //   by the r_multi_ack_to config_ack or r_cleanup_to_config_ack flip-flops.
    1460   //   The config inval response is sent only when the last line has been invalidated.
    1461   //
     1430  //   is launched and registered in UPT. The multi-inval transaction completion
     1431  //   is signaled by the CLEANUP FSM by decrementing the r_config_rsp_lines counter.
     1432  //   The CONFIG INVAL response is sent only when the last line has been invalidated.
     1433  //   TODO : The target buffer address must be aligned on a cache line boundary.
     1434  //   This constraint can be released, but it requires to make 2 PUT transactions
     1435  //   for the first and the last line...
     1436  //
    14621437  // - SYNC request:
    1463   //
    1464   //  ...  Not implemented yet ...
     1438  //   For each line, it access to the DIR.
     1439  //   In case of miss, it does nothing, and a response is requested to TGT_RSP FSM.
     1440  //   In case of hit, a PUT transaction is registered in TRT and a request is sent
     1441  //   to IXR_CMD FSM. The IXR_RSP FSM decrements the r_config_rsp_lines counter
     1442  //   when a PUT response is received.
     1443  //   The CONFIG SYNC response is sent only when the last PUT response is received.
    14651444  //
    14661445  // From the software point of view, a configuration request is a sequence
    1467   // of 6 atomic accesses in an uncached segment:
     1446  // of 6 atomic accesses in an uncached segment. A dedicated lock is used
     1447  // to handle only one configuration command at a given time:
    14681448  // - Read  MEMC_LOCK       : Get the lock
    14691449  // - Write MEMC_ADDR_LO    : Set the buffer address LSB
     
    14741454  ////////////////////////////////////////////////////////////////////////////////////
    14751455
     1456//std::cout << std::endl << "config_fsm" << std::endl;
     1457
    14761458  switch( r_config_fsm.read() )
    14771459  {
     
    14861468if(m_debug)
    14871469std::cout << "  <MEMC " << name() << " CONFIG_IDLE> Config Request received"
    1488           << " address = " << std::hex << r_config_address.read()
    1489           << " / nlines = " << std::dec << r_config_nlines.read()
     1470          << " / address = " << std::hex << r_config_address.read()
     1471          << " / lines = " << std::dec << r_config_cmd_lines.read()
    14901472          << " / type = " << r_config_cmd.read() << std::endl;
    14911473#endif
     
    14941476      }
    14951477      /////////////////
    1496       case CONFIG_LOOP:   // test last line
    1497       {
    1498           if ( r_config_nlines.read() == 0 )
     1478      case CONFIG_LOOP:   // test if last line to be handled
     1479      {
     1480          if ( r_config_cmd_lines.read() == 0 )
    14991481          {
    15001482              r_config_cmd = MEMC_CMD_NOP;
    1501               r_config_fsm = CONFIG_RSP;
     1483              r_config_fsm = CONFIG_WAIT;
    15021484          }
    15031485          else
     
    15091491if(m_debug)
    15101492std::cout << "  <MEMC " << name() << " CONFIG_LOOP>"
    1511           << " address = " << std::hex << r_config_address.read()   
    1512           << " / nlines = " << std::dec << r_config_nlines.read()
     1493          << " / address = " << std::hex << r_config_address.read()   
     1494          << " / lines not handled = " << std::dec << r_config_cmd_lines.read()
    15131495          << " / command = " << r_config_cmd.read() << std::endl;
    15141496#endif
    15151497          break;
     1498      }
     1499      /////////////////
     1500      case CONFIG_WAIT:   // wait completion (last response)
     1501      {
     1502          if ( r_config_rsp_lines.read() == 0 )  // last response received
     1503          {
     1504              r_config_fsm = CONFIG_RSP;
     1505          }
     1506
     1507#if DEBUG_MEMC_CONFIG
     1508if(m_debug)
     1509std::cout << "  <MEMC " << name() << " CONFIG_WAIT>"
     1510          << " / lines to do = " << std::dec << r_config_rsp_lines.read() << std::endl;
     1511#endif
     1512          break;
     1513      }
     1514      ////////////////
     1515      case CONFIG_RSP:  // request TGT_RSP FSM to return response
     1516      {
     1517          if ( not r_config_to_tgt_rsp_req.read() )
     1518          {
     1519              r_config_to_tgt_rsp_srcid  = r_config_srcid.read();
     1520              r_config_to_tgt_rsp_trdid  = r_config_trdid.read();
     1521              r_config_to_tgt_rsp_pktid  = r_config_pktid.read();
     1522              r_config_to_tgt_rsp_error  = false;
     1523              r_config_to_tgt_rsp_req    = true;
     1524              r_config_fsm               = CONFIG_IDLE;
     1525
     1526#if DEBUG_MEMC_CONFIG
     1527if(m_debug)
     1528std::cout << "  <MEMC " << name() << " CONFIG_RSP> Request TGT_RSP FSM to return response:"
     1529          << " error = " << r_config_to_tgt_rsp_error.read()
     1530          << " / rsrcid = " << std::hex << r_config_srcid.read()
     1531          << " / rtrdid = " << std::hex << r_config_trdid.read()
     1532          << " / rpktid = " << std::hex << r_config_pktid.read() << std::endl;
     1533#endif
     1534          }
     1535          break;
     1536
    15161537      }
    15171538      ////////////////////
     
    15331554      case CONFIG_DIR_ACCESS:   // Access directory and decode config command
    15341555      {
     1556          assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
     1557          "MEMC ERROR in CONFIG_DIR_ACCESS state: bad DIR allocation");
     1558
    15351559          size_t way = 0;
    15361560          DirectoryEntry entry = m_cache_directory.read(r_config_address.read(), way);
     
    15431567              r_config_dir_copy_srcid = entry.owner.srcid;
    15441568              r_config_dir_is_cnt     = entry.is_cnt;
     1569              r_config_dir_lock       = entry.lock;
    15451570              r_config_dir_count      = entry.count;
    1546               r_config_dir_next_ptr   = entry.ptr;
    1547 
    1548               r_config_fsm    = CONFIG_DIR_IVT_LOCK;
     1571              r_config_dir_ptr        = entry.ptr;
     1572
     1573              r_config_fsm    = CONFIG_IVT_LOCK;
    15491574          }
    15501575          else if ( entry.valid and                       // hit & sync command
     
    15521577                    (r_config_cmd.read() == MEMC_CMD_SYNC) )
    15531578          {
    1554               std::cout << "VCI_MEM_CACHE ERROR: "
    1555                         << "SYNC config request not implemented yet" << std::endl;
    1556               exit(0);
     1579              r_config_fsm  = CONFIG_TRT_LOCK;
    15571580          }
    1558           else                                            // return to LOOP
     1581          else                                            // miss : return to LOOP
    15591582          {
    1560               r_config_nlines  = r_config_nlines.read() - 1;
    1561               r_config_address = r_config_address.read() + (m_words<<2);
    1562               r_config_fsm     = CONFIG_LOOP;
     1583              r_config_cmd_lines = r_config_cmd_lines.read() - 1;
     1584              r_config_rsp_lines = r_config_rsp_lines.read() - 1;
     1585              r_config_cmd_lines = r_config_cmd_lines.read() - 1;
     1586              r_config_address   = r_config_address.read() + (m_words<<2);
     1587              r_config_fsm       = CONFIG_LOOP;
    15631588          }
    15641589
     
    15741599          break;
    15751600      }
    1576       /////////////////////////
    1577       case CONFIG_DIR_IVT_LOCK:  // enter this state in case of INVAL command
    1578                                  // Try to get both DIR & IVT locks, and return
    1579                                  // to LOOP state if IVT full.
    1580                                  // Register inval in IVT, and invalidate the
    1581                                  // directory if IVT not full.
    1582       {
     1601      /////////////////////
     1602      case CONFIG_TRT_LOCK:      // enter this state in case of SYNC command
     1603                                 // to a dirty cache line
     1604                                 // keep DIR lock, and try to get TRT lock
     1605                                 // return to LOOP state if TRT full
     1606                                 // reset dirty bit in DIR and register a PUT
     1607                                 // trabsaction in TRT if not full.
     1608      {
     1609          assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
     1610          "MEMC ERROR in CONFIG_TRT_LOCK state: bad DIR allocation");
     1611
     1612          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG )
     1613          {
     1614              size_t index = 0;
     1615              bool   wok   = not m_trt.full(index);
     1616
     1617              if ( not wok )
     1618              {
     1619                  r_config_fsm = CONFIG_LOOP;
     1620              }
     1621              else
     1622              {
     1623                  size_t          way = r_config_dir_way.read();
     1624                  size_t          set = m_y[r_config_address.read()];
     1625
     1626                  // reset dirty bit in DIR
     1627                  DirectoryEntry  entry;
     1628                  entry.valid       = true;
     1629                  entry.dirty       = false;
     1630                  entry.tag         = m_z[r_config_address.read()];
     1631                  entry.is_cnt      = r_config_dir_is_cnt.read();
     1632                  entry.lock        = r_config_dir_lock.read();
     1633                  entry.ptr         = r_config_dir_ptr.read();
     1634                  entry.count       = r_config_dir_count.read();
     1635                  entry.owner.inst  = r_config_dir_copy_inst.read();
     1636                  entry.owner.srcid = r_config_dir_copy_srcid.read();
     1637                  m_cache_directory.write( set,
     1638                                           way,
     1639                                           entry );
     1640
     1641                  r_config_trt_index = index;
     1642                  r_config_fsm       = CONFIG_TRT_SET;
     1643              }
     1644
     1645#if DEBUG_MEMC_CONFIG
     1646if(m_debug)
     1647std::cout << "  <MEMC " << name() << " CONFIG_TRT_LOCK> Access TRT: "
     1648          << " wok = " << std::dec << wok
     1649          << " index = " << index << std::endl;
     1650#endif
     1651          }
     1652          break;
     1653      }
     1654      ////////////////////
     1655      case CONFIG_TRT_SET:       // read data in cache
     1656                                 // and post a PUT request in TRT
     1657      {
     1658          assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
     1659          "MEMC ERROR in CONFIG_TRT_SET state: bad DIR allocation");
     1660
     1661          assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG) and
     1662          "MEMC ERROR in CONFIG_TRT_SET state: bad TRT allocation");
     1663
     1664          // read data into cache
     1665          size_t          way = r_config_dir_way.read();
     1666          size_t          set = m_y[r_config_address.read()];
     1667
     1668          sc_signal<data_t> config_data[16];
     1669          m_cache_data.read_line( way,
     1670                                  set,
     1671                                  config_data );
     1672           
     1673          // post a PUT request in TRT
     1674          std::vector<data_t> data_vector;
     1675          data_vector.clear();
     1676          for(size_t i=0; i<m_words; i++) data_vector.push_back(config_data[i].read());
     1677          m_trt.set( r_config_trt_index.read(),
     1678                     false,                               // PUT
     1679                     m_nline[r_config_address.read()],    // nline
     1680                     0,                                   // srcid:       unused
     1681                     0,                                   // trdid:       unused
     1682                     0,                                   // pktid:       unused
     1683                     false,                               // not proc_read
     1684                     0,                                   // read_length: unused
     1685                     0,                                   // word_index:  unused
     1686                     std::vector<be_t>(m_words,0xF),                         
     1687                     data_vector);
     1688
     1689#if DEBUG_MEMC_CONFIG
     1690if(m_debug)
     1691std::cout << "  <MEMC " << name() << " CONFIG_TRT_SET> PUT request in TRT:"
     1692          << " address = " << std::hex << r_config_address.read()
     1693          << " index = " << std::dec << r_config_trt_index.read() << std::endl;
     1694#endif
     1695          break;
     1696      }
     1697      ////////////////////
     1698      case CONFIG_PUT_REQ:       // PUT request to IXR_CMD_FSM
     1699      {
     1700          if ( not r_config_to_ixr_cmd_req.read() )
     1701          {
     1702              r_config_to_ixr_cmd_req   = true;
     1703              r_config_to_ixr_cmd_index = r_config_trt_index.read();
     1704
     1705              // prepare next iteration
     1706              r_config_cmd_lines              = r_config_cmd_lines.read() - 1;
     1707              r_config_address                = r_config_address.read() + (m_words<<2);
     1708              r_config_fsm                    = CONFIG_LOOP;
     1709
     1710#if DEBUG_MEMC_CONFIG
     1711if(m_debug)
     1712std::cout << "  <MEMC " << name() << " CONFIG_PUT_REQ> PUT request to IXR_CMD_FSM"
     1713          << " / address = " << std::hex << r_config_address.read() << std::endl;
     1714#endif
     1715          }
     1716          break;
     1717      }
     1718      /////////////////////
     1719      case CONFIG_IVT_LOCK:  // enter this state in case of INVAL command
     1720                             // Keep DIR lock and Try to get IVT lock.
     1721                             // Return to LOOP state if IVT full.
     1722                             // Register inval in IVT, and invalidate the
     1723                             // directory if IVT not full.
     1724      {
     1725          assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
     1726          "MEMC ERROR in CONFIG_IVT_LOCK state: bad DIR allocation");
     1727
    15831728          if ( r_alloc_ivt_fsm.read() == ALLOC_IVT_CONFIG )
    15841729          {
     
    15891734              {
    15901735                  m_cache_directory.inval( way, set );
    1591                   r_config_nlines  = r_config_nlines.read() - 1;
    1592                   r_config_address = r_config_address.read() + (m_words<<2);
    1593                   r_config_fsm     = CONFIG_LOOP;
     1736                  r_config_cmd_lines  = r_config_cmd_lines.read() - 1;
     1737                  r_config_rsp_lines  = r_config_rsp_lines.read() - 1;
     1738                  r_config_address    = r_config_address.read() + (m_words<<2);
     1739                  r_config_fsm        = CONFIG_LOOP;
    15941740
    15951741#if DEBUG_MEMC_CONFIG
    15961742if(m_debug)
    1597 std::cout << "  <MEMC " << name() << " CONFIG_DIR_IVT_LOCK>"
     1743std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
    15981744          << " No copies in L1 : inval DIR entry"  << std::endl;
    15991745#endif
     
    16261772                      r_config_ivt_index = index;
    16271773                      if ( broadcast )  r_config_fsm = CONFIG_BC_SEND;
    1628                       else              r_config_fsm = CONFIG_INV_SEND;
     1774                      else              r_config_fsm = CONFIG_INVAL_SEND;
    16291775
    16301776#if DEBUG_MEMC_CONFIG
    16311777if(m_debug)
    1632 std::cout << "  <MEMC " << name() << " CONFIG_DIR_IVT_LOCK>"
     1778std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
    16331779          << " Inval DIR entry and register inval in IVT"
    1634           << " : index = " << std::dec << index
     1780          << " / index = " << std::dec << index
    16351781          << " / broadcast = " << broadcast << std::endl;
    16361782#endif
     
    16421788#if DEBUG_MEMC_CONFIG
    16431789if(m_debug)
    1644 std::cout << "  <MEMC " << name() << " CONFIG_DIR_IVT_LOCK>"
     1790std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
    16451791          << " IVT full : release DIR & IVT locks and retry" << std::endl;
    16461792#endif
     
    16561802              not r_config_to_cc_send_brdcast_req.read() )
    16571803          {
     1804              // post bc inval request
    16581805              r_config_to_cc_send_multi_req   = false;
    16591806              r_config_to_cc_send_brdcast_req = true;
    16601807              r_config_to_cc_send_trdid       = r_config_ivt_index.read();
    16611808              r_config_to_cc_send_nline       = m_nline[(addr_t)(r_config_address.read())];
    1662               r_cleanup_to_config_ack         = false;
    1663               r_config_fsm                    = CONFIG_BC_WAIT;
     1809
     1810              // prepare next iteration
     1811              r_config_cmd_lines              = r_config_cmd_lines.read() - 1;
     1812              r_config_address                = r_config_address.read() + (m_words<<2);
     1813              r_config_fsm                    = CONFIG_LOOP;
    16641814
    16651815#if DEBUG_MEMC_CONFIG
     
    16721822          break;
    16731823      }
    1674       ////////////////////
    1675       case CONFIG_BC_WAIT:      // wait broadcast completion to return to LOOP
    1676       {
    1677           if ( r_cleanup_to_config_ack.read() )
    1678           {
    1679               r_config_fsm     = CONFIG_LOOP;
    1680               r_config_nlines  = r_config_nlines.read() - 1;
    1681               r_config_address = r_config_address.read() + (m_words<<2);
    1682           }
    1683 
    1684 #if DEBUG_MEMC_CONFIG
    1685 if(m_debug)
    1686 std::cout << "  <MEMC " << name() << " CONFIG_BC_WAIT> Waiting BC completion "
    1687           << " done = " << r_cleanup_to_config_ack.read()
    1688           << std::endl;
    1689 #endif
    1690           break;
    1691       }
    1692       /////////////////////
    1693       case CONFIG_INV_SEND:    // Post a multi inval request to CC_SEND FSM
     1824      ///////////////////////
     1825      case CONFIG_INVAL_SEND:    // Post a multi inval request to CC_SEND FSM
    16941826      {
    16951827          if( not r_config_to_cc_send_multi_req.read() and
    16961828              not r_config_to_cc_send_brdcast_req.read() )
    16971829          {
     1830              // post multi inval request
    16981831              r_config_to_cc_send_multi_req   = true;
    16991832              r_config_to_cc_send_brdcast_req = false;
    17001833              r_config_to_cc_send_trdid       = r_config_ivt_index.read();
    17011834              r_config_to_cc_send_nline       = m_nline[(addr_t)(r_config_address.read())];
    1702               r_multi_ack_to_config_ack       = false;
    1703 
     1835
     1836              // post data into FIFO
    17041837              config_to_cc_send_fifo_srcid    = r_config_dir_copy_srcid.read();
    17051838              config_to_cc_send_fifo_inst     = r_config_dir_copy_inst.read();
    17061839              config_to_cc_send_fifo_put      = true;
    17071840
    1708               if ( r_config_dir_count.read() == 1 )  r_config_fsm = CONFIG_INV_WAIT;
    1709               else                                   r_config_fsm = CONFIG_HEAP_REQ;
     1841              if ( r_config_dir_count.read() == 1 )  // one copy
     1842              {
     1843                  // prepare next iteration
     1844                  r_config_cmd_lines          = r_config_cmd_lines.read() - 1;
     1845                  r_config_address            = r_config_address.read() + (m_words<<2);
     1846                  r_config_fsm                = CONFIG_LOOP;
     1847              }
     1848              else                                   // several copies
     1849              {
     1850                  r_config_fsm = CONFIG_HEAP_REQ;
     1851              }
    17101852
    17111853#if DEBUG_MEMC_CONFIG
    17121854if(m_debug)
    1713 std::cout << "  <MEMC " << name() << " CONFIG_INV_SEND>"
     1855std::cout << "  <MEMC " << name() << " CONFIG_INVAL_SEND>"
    17141856          << " Post multi inval request to CC_SEND FSM"
    17151857          << " / address = " << std::hex << r_config_address.read()
     
    17261868          {
    17271869              r_config_fsm       = CONFIG_HEAP_SCAN;
    1728               r_config_heap_next = r_config_dir_next_ptr.read();
     1870              r_config_heap_next = r_config_dir_ptr.read();
    17291871          }
    17301872
     
    17731915          if ( m_heap.is_full() )
    17741916          {
    1775               last_entry.next = r_config_dir_next_ptr.read();
     1917              last_entry.next = r_config_dir_ptr.read();
    17761918              m_heap.unset_full();
    17771919          }
     
    17811923          }
    17821924
    1783           m_heap.write_free_ptr( r_config_dir_next_ptr.read() );
     1925          m_heap.write_free_ptr( r_config_dir_ptr.read() );
    17841926          m_heap.write( r_config_heap_next.read(), last_entry );
    1785           r_config_fsm = CONFIG_INV_WAIT;
     1927
     1928          // prepare next iteration
     1929          r_config_cmd_lines          = r_config_cmd_lines.read() - 1;
     1930          r_config_address            = r_config_address.read() + (m_words<<2);
     1931          r_config_fsm                = CONFIG_LOOP;
    17861932
    17871933#if DEBUG_MEMC_CONFIG
     
    17911937#endif
    17921938          break;
    1793       }
    1794       /////////////////////
    1795       case CONFIG_INV_WAIT:      // wait inval completion to return to LOOP
    1796       {
    1797           if ( r_multi_ack_to_config_ack.read() )
    1798           {
    1799               r_config_fsm     = CONFIG_LOOP;
    1800               r_config_nlines  = r_config_nlines.read() - 1;
    1801               r_config_address = r_config_address.read() + (m_words<<2);
    1802           }
    1803 
    1804 #if DEBUG_MEMC_CONFIG
    1805 if(m_debug)
    1806 std::cout << "  <MEMC " << name() << " CONFIG_INV_WAIT> Waiting inval completion "
    1807           << " done = " << r_multi_ack_to_config_ack.read()
    1808           << std::endl;
    1809 #endif
    1810           break;
    1811       }
    1812 
    1813       ////////////////
    1814       case CONFIG_RSP:  // request TGT_RSP FSM to return response
    1815       {
    1816           if ( not r_config_to_tgt_rsp_req.read() )
    1817           {
    1818               r_config_to_tgt_rsp_srcid  = r_config_srcid.read();
    1819               r_config_to_tgt_rsp_trdid  = r_config_trdid.read();
    1820               r_config_to_tgt_rsp_pktid  = r_config_pktid.read();
    1821               r_config_to_tgt_rsp_error  = false;
    1822               r_config_to_tgt_rsp_req    = true;
    1823               r_config_fsm               = CONFIG_IDLE;
    1824 
    1825 #if DEBUG_MEMC_CONFIG
    1826 if(m_debug)
    1827 std::cout << "  <MEMC " << name() << " CONFIG_RSP> Request TGT_RSP FSM to return response:"
    1828           << " error = " << r_config_to_tgt_rsp_error.read()
    1829           << " / rsrcid = " << std::hex << r_config_srcid.read() << std::endl;
    1830 #endif
    1831           }
    1832           break;
    1833 
    18341939      }
    18351940  }  // end switch r_config_fsm
     
    18581963  ////////////////////////////////////////////////////////////////////////////////////
    18591964
     1965//std::cout << std::endl << "read_fsm" << std::endl;
     1966
    18601967  switch(r_read_fsm.read())
    18611968  {
     
    18631970    case READ_IDLE:  // waiting a read request
    18641971    {
    1865       if(m_cmd_read_addr_fifo.rok())
    1866       {
     1972        if(m_cmd_read_addr_fifo.rok())
     1973        {
    18671974
    18681975#if DEBUG_MEMC_READ
    1869         if(m_debug)
    1870           std::cout << "  <MEMC " << name() << " READ_IDLE> Read request"
    1871             << " : address = " << std::hex << m_cmd_read_addr_fifo.read()
    1872             << " / srcid = " << m_cmd_read_srcid_fifo.read()
    1873             << " / trdid = " << m_cmd_read_trdid_fifo.read()
    1874             << " / pktid = " << m_cmd_read_pktid_fifo.read()
    1875             << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
    1876 #endif
    1877         r_read_fsm = READ_DIR_REQ;
    1878       }
    1879       break;
    1880     }
    1881 
     1976if(m_debug)
     1977std::cout << "  <MEMC " << name() << " READ_IDLE> Read request"
     1978          << " : address = " << std::hex << m_cmd_read_addr_fifo.read()
     1979          << " / srcid = " << m_cmd_read_srcid_fifo.read()
     1980          << " / trdid = " << m_cmd_read_trdid_fifo.read()
     1981          << " / pktid = " << m_cmd_read_pktid_fifo.read()
     1982          << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
     1983#endif
     1984            r_read_fsm = READ_DIR_REQ;
     1985        }
     1986        break;
     1987    }
    18821988    //////////////////
    18831989    case READ_DIR_REQ:  // Get the lock to the directory
    18841990    {
    1885       if(r_alloc_dir_fsm.read() == ALLOC_DIR_READ)
    1886       {
    1887         r_read_fsm = READ_DIR_LOCK;
    1888       }
     1991        if(r_alloc_dir_fsm.read() == ALLOC_DIR_READ)
     1992        {
     1993            r_read_fsm = READ_DIR_LOCK;
     1994        }
    18891995
    18901996#if DEBUG_MEMC_READ
     
    18921998std::cout << "  <MEMC " << name() << " READ_DIR_REQ> Requesting DIR lock " << std::endl;
    18931999#endif
    1894       break;
     2000        break;
    18952001    }
    18962002
     
    18982004    case READ_DIR_LOCK:  // check directory for hit / miss
    18992005    {
    1900       if(r_alloc_dir_fsm.read() == ALLOC_DIR_READ)
    1901       {
     2006        assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_READ) and
     2007        "MEMC ERROR in READ_DIR_LOCK state: Bad DIR allocation");
     2008
    19022009        size_t way = 0;
    1903         DirectoryEntry entry =
    1904           m_cache_directory.read(m_cmd_read_addr_fifo.read(), way);
     2010        DirectoryEntry entry = m_cache_directory.read(m_cmd_read_addr_fifo.read(), way);
     2011
    19052012        // access the global table ONLY when we have an LL cmd
    19062013        if((m_cmd_read_pktid_fifo.read() & 0x7) == TYPE_LL)   
    19072014        {
    1908           r_read_ll_key   = m_llsc_table.ll(m_cmd_read_addr_fifo.read());
     2015            r_read_ll_key   = m_llsc_table.ll(m_cmd_read_addr_fifo.read());
    19092016        }
    19102017        r_read_is_cnt     = entry.is_cnt;
     
    19152022        r_read_count      = entry.count;
    19162023        r_read_copy       = entry.owner.srcid;
    1917 
    1918 #if L1_MULTI_CACHE
    1919         r_read_copy_cache = entry.owner.cache_id;
    1920 #endif
    19212024        r_read_copy_inst  = entry.owner.inst;
    19222025        r_read_ptr        = entry.ptr; // pointer to the heap
     
    19282031        if(entry.valid)    // hit
    19292032        {
    1930           // test if we need to register a new copy in the heap
    1931           if(entry.is_cnt or (entry.count == 0) or !cached_read)
    1932           {
    1933             r_read_fsm = READ_DIR_HIT;
    1934           }
    1935           else
    1936           {
    1937             r_read_fsm = READ_HEAP_REQ;
    1938           }
     2033            // test if we need to register a new copy in the heap
     2034            if(entry.is_cnt or (entry.count == 0) or !cached_read)
     2035            {
     2036                r_read_fsm = READ_DIR_HIT;
     2037            }
     2038            else
     2039            {
     2040                r_read_fsm = READ_HEAP_REQ;
     2041            }
    19392042        }
    19402043        else      // miss
    19412044        {
    1942           r_read_fsm = READ_TRT_LOCK;
     2045            r_read_fsm = READ_TRT_LOCK;
    19432046        }
    19442047
     
    19552058}
    19562059#endif
    1957       }
    1958       else
    1959       {
    1960         std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_DIR_LOCK state"
    1961                   << "Bad DIR allocation"   << std::endl;
    1962         exit(0);
    1963       }
    1964       break;
    1965     }
    1966 
     2060        break;
     2061    }
    19672062    //////////////////
    19682063    case READ_DIR_HIT:    //  read data in cache & update the directory
     
    19732068
    19742069    {
    1975       if(r_alloc_dir_fsm.read() == ALLOC_DIR_READ)
    1976       {
     2070        assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_READ) and
     2071        "MEMC ERROR in READ_DIR_HIT state: Bad DIR allocation");
     2072
    19772073        // check if this is an instruction read, this means pktid is either
    19782074        // TYPE_READ_INS_UNC   0bX010 with TSAR encoding
     
    19912087        m_cache_data.read_line(way, set, r_read_data);
    19922088
    1993         if(m_monitor_ok) check_monitor( m_cmd_read_addr_fifo.read(), r_read_data[0], true);
    1994 
    19952089        // update the cache directory
    19962090        DirectoryEntry entry;
     
    20042098        if(cached_read)   // Cached read => we must update the copies
    20052099        {
    2006           if(!is_cnt)  // Not counter mode
    2007           {
    2008             entry.owner.srcid    = m_cmd_read_srcid_fifo.read();
    2009 #if L1_MULTI_CACHE
    2010             entry.owner.cache_id = m_cmd_read_pktid_fifo.read();
    2011 #endif
    2012             entry.owner.inst     = inst_read;
    2013             entry.count          = r_read_count.read() + 1;
    2014           }
    2015           else  // Counter mode
    2016           {
    2017             entry.owner.srcid    = 0;
    2018 #if L1_MULTI_CACHE
    2019             entry.owner.cache_id = 0;
    2020 #endif
    2021             entry.owner.inst     = false;
    2022             entry.count          = r_read_count.read() + 1;
    2023           }
     2100            if(!is_cnt)  // Not counter mode
     2101            {
     2102                entry.owner.srcid    = m_cmd_read_srcid_fifo.read();
     2103                entry.owner.inst     = inst_read;
     2104                entry.count          = r_read_count.read() + 1;
     2105            }
     2106            else  // Counter mode
     2107            {
     2108                entry.owner.srcid    = 0;
     2109                entry.owner.inst     = false;
     2110                entry.count          = r_read_count.read() + 1;
     2111            }
    20242112        }
    20252113        else            // Uncached read
    20262114        {
    2027           entry.owner.srcid     = r_read_copy.read();
    2028 #if L1_MULTI_CACHE
    2029           entry.owner.cache_id  = r_read_copy_cache.read();
    2030 #endif
    2031           entry.owner.inst      = r_read_copy_inst.read();
    2032           entry.count           = r_read_count.read();
     2115            entry.owner.srcid     = r_read_copy.read();
     2116            entry.owner.inst      = r_read_copy_inst.read();
     2117            entry.count           = r_read_count.read();
    20332118        }
    20342119
    20352120#if DEBUG_MEMC_READ
    2036         if(m_debug)
    2037           std::cout << "  <MEMC " << name() << " READ_DIR_HIT> Update directory entry:"
    2038             << " addr = " << std::hex << m_cmd_read_addr_fifo.read()
    2039             << " / set = " << std::dec << set
    2040             << " / way = " << way
    2041             << " / owner_id = " << std::hex << entry.owner.srcid
    2042             << " / owner_ins = " << std::dec << entry.owner.inst
    2043             << " / count = " << entry.count
    2044             << " / is_cnt = " << entry.is_cnt << std::endl;
    2045 #endif
    2046 
     2121if(m_debug)
     2122std::cout << "  <MEMC " << name() << " READ_DIR_HIT> Update directory entry:"
     2123          << " addr = " << std::hex << m_cmd_read_addr_fifo.read()
     2124          << " / set = " << std::dec << set
     2125          << " / way = " << way
     2126          << " / owner_id = " << std::hex << entry.owner.srcid
     2127          << " / owner_ins = " << std::dec << entry.owner.inst
     2128          << " / count = " << entry.count
     2129          << " / is_cnt = " << entry.is_cnt << std::endl;
     2130#endif
    20472131        m_cache_directory.write(set, way, entry);
    20482132        r_read_fsm    = READ_RSP;
    2049       }
    2050       break;
     2133        break;
    20512134    }
    20522135    ///////////////////
     
    20802163
    20812164        m_cache_data.read_line(way, set, r_read_data);
    2082 
    2083         if(m_monitor_ok) check_monitor( m_cmd_read_addr_fifo.read(), r_read_data[0], true);
    20842165
    20852166        // update the cache directory
     
    20952176        {
    20962177          entry.owner.srcid    = r_read_copy.read();
    2097 #if L1_MULTI_CACHE
    2098           entry.owner.cache_id = r_read_copy_cache.read();
    2099 #endif
    21002178          entry.owner.inst     = r_read_copy_inst.read();
    21012179          entry.ptr            = m_heap.next_free_ptr();   // set pointer on the heap
     
    21042182        {
    21052183          entry.owner.srcid    = 0;
    2106 #if L1_MULTI_CACHE
    2107           entry.owner.cache_id = 0;
    2108 #endif
    21092184          entry.owner.inst     = false;
    21102185          entry.ptr            = 0;
     
    21722247        HeapEntry heap_entry;
    21732248        heap_entry.owner.srcid    = m_cmd_read_srcid_fifo.read();
    2174 #if L1_MULTI_CACHE
    2175         heap_entry.owner.cache_id = m_cmd_read_pktid_fifo.read();
    2176 #endif
    21772249        heap_entry.owner.inst     = ((m_cmd_read_pktid_fifo.read() & 0x2) != 0);
    21782250
     
    22382310        HeapEntry last_entry;
    22392311        last_entry.owner.srcid    = 0;
    2240 #if L1_MULTI_CACHE
    2241         last_entry.owner.cache_id = 0;
    2242 #endif
    22432312        last_entry.owner.inst     = false;
    22442313
     
    22662335    case READ_RSP:    //  request the TGT_RSP FSM to return data
    22672336    {
    2268       if(!r_read_to_tgt_rsp_req)
    2269       {
    2270         for(size_t i=0 ; i<m_words ; i++)  r_read_to_tgt_rsp_data[i] = r_read_data[i];
    2271         r_read_to_tgt_rsp_word   = m_x[(addr_t) m_cmd_read_addr_fifo.read()];
    2272         r_read_to_tgt_rsp_length = m_cmd_read_length_fifo.read();
    2273         r_read_to_tgt_rsp_srcid  = m_cmd_read_srcid_fifo.read();
    2274         r_read_to_tgt_rsp_trdid  = m_cmd_read_trdid_fifo.read();
    2275         r_read_to_tgt_rsp_pktid  = m_cmd_read_pktid_fifo.read();
    2276         r_read_to_tgt_rsp_ll_key = r_read_ll_key.read();
    2277         cmd_read_fifo_get        = true;
    2278         r_read_to_tgt_rsp_req    = true;
    2279         r_read_fsm               = READ_IDLE;
     2337        if(!r_read_to_tgt_rsp_req)
     2338        {
     2339            for(size_t i=0 ; i<m_words ; i++)  r_read_to_tgt_rsp_data[i] = r_read_data[i];
     2340            r_read_to_tgt_rsp_word   = m_x[(addr_t) m_cmd_read_addr_fifo.read()];
     2341            r_read_to_tgt_rsp_length = m_cmd_read_length_fifo.read();
     2342            r_read_to_tgt_rsp_srcid  = m_cmd_read_srcid_fifo.read();
     2343            r_read_to_tgt_rsp_trdid  = m_cmd_read_trdid_fifo.read();
     2344            r_read_to_tgt_rsp_pktid  = m_cmd_read_pktid_fifo.read();
     2345            r_read_to_tgt_rsp_ll_key = r_read_ll_key.read();
     2346            cmd_read_fifo_get        = true;
     2347            r_read_to_tgt_rsp_req    = true;
     2348            r_read_fsm               = READ_IDLE;
    22802349
    22812350#if DEBUG_MEMC_READ
     
    22862355          << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
    22872356#endif
    2288       }
    2289       break;
     2357        }
     2358        break;
    22902359    }
    22912360    ///////////////////
    22922361    case READ_TRT_LOCK: // read miss : check the Transaction Table
    22932362    {
    2294       if(r_alloc_trt_fsm.read() == ALLOC_TRT_READ)
    2295       {
    2296         size_t      index     = 0;
    2297         addr_t      addr      = (addr_t) m_cmd_read_addr_fifo.read();
    2298         bool        hit_read  = m_trt.hit_read(m_nline[addr], index);
    2299         bool        hit_write = m_trt.hit_write(m_nline[addr]);
    2300         bool        wok       = !m_trt.full(index);
    2301 
    2302         if(hit_read or !wok or hit_write)    // missing line already requested or no space
    2303         {
    2304           if(!wok)      m_cpt_trt_full++;
    2305           if(hit_read or hit_write)   m_cpt_trt_rb++;
    2306           r_read_fsm = READ_IDLE;
    2307         }
    2308         else                  // missing line is requested to the XRAM
    2309         {
    2310           m_cpt_read_miss++;
    2311           r_read_trt_index = index;
    2312           r_read_fsm       = READ_TRT_SET;
    2313         }
     2363        if(r_alloc_trt_fsm.read() == ALLOC_TRT_READ)
     2364        {
     2365            size_t      index     = 0;
     2366            addr_t      addr      = (addr_t) m_cmd_read_addr_fifo.read();
     2367            bool        hit_read  = m_trt.hit_read(m_nline[addr], index);
     2368            bool        hit_write = m_trt.hit_write(m_nline[addr]);
     2369            bool        wok       = not m_trt.full(index);
     2370
     2371            if(hit_read or !wok or hit_write)    // line already requested or no space
     2372            {
     2373                if(!wok)                    m_cpt_trt_full++;
     2374                if(hit_read or hit_write)   m_cpt_trt_rb++;
     2375                r_read_fsm = READ_IDLE;
     2376            }
     2377            else                  // missing line is requested to the XRAM
     2378            {
     2379                m_cpt_read_miss++;
     2380                r_read_trt_index = index;
     2381                r_read_fsm       = READ_TRT_SET;
     2382            }
    23142383
    23152384#if DEBUG_MEMC_READ
     
    23202389          << " / full = " << !wok << std::endl;
    23212390#endif
    2322       }
    2323       break;
    2324     }
    2325 
     2391        }
     2392        break;
     2393    }
    23262394    //////////////////
    23272395    case READ_TRT_SET:      // register get transaction in TRT
    23282396    {
    2329       if(r_alloc_trt_fsm.read() == ALLOC_TRT_READ)
    2330       {
    2331         m_trt.set(r_read_trt_index.read(),
    2332                               true,
    2333                               m_nline[(addr_t)(m_cmd_read_addr_fifo.read())],
    2334                               m_cmd_read_srcid_fifo.read(),
    2335                               m_cmd_read_trdid_fifo.read(),
    2336                               m_cmd_read_pktid_fifo.read(),
    2337                               true,
    2338                               m_cmd_read_length_fifo.read(),
    2339                               m_x[(addr_t)(m_cmd_read_addr_fifo.read())],
    2340                               std::vector<be_t> (m_words,0),
    2341                               std::vector<data_t> (m_words,0),
    2342                               r_read_ll_key.read());
     2397        if(r_alloc_trt_fsm.read() == ALLOC_TRT_READ)
     2398        {
     2399            m_trt.set( r_read_trt_index.read(),
     2400                       true,      // GET
     2401                       m_nline[(addr_t)(m_cmd_read_addr_fifo.read())],
     2402                       m_cmd_read_srcid_fifo.read(),
     2403                       m_cmd_read_trdid_fifo.read(),
     2404                       m_cmd_read_pktid_fifo.read(),
     2405                       true,      // proc read
     2406                       m_cmd_read_length_fifo.read(),
     2407                       m_x[(addr_t)(m_cmd_read_addr_fifo.read())],
     2408                       std::vector<be_t> (m_words,0),
     2409                       std::vector<data_t> (m_words,0),
     2410                       r_read_ll_key.read() );
    23432411#if DEBUG_MEMC_READ
    23442412if(m_debug)
    2345 std::cout << "  <MEMC " << name() << " READ_TRT_SET> Write in Transaction Table:"
     2413std::cout << "  <MEMC " << name() << " READ_TRT_SET> Set a GET in TRT:"
    23462414          << " address = " << std::hex << m_cmd_read_addr_fifo.read()
    23472415          << " / srcid = " << std::hex << m_cmd_read_srcid_fifo.read() << std::endl;
    23482416#endif
    2349         r_read_fsm = READ_TRT_REQ;
    2350       }
    2351       break;
     2417            r_read_fsm = READ_TRT_REQ;
     2418        }
     2419        break;
    23522420    }
    23532421
     
    23552423    case READ_TRT_REQ:   // consume the read request in FIFO and send it to IXR_CMD_FSM
    23562424    {
    2357       if(not r_read_to_ixr_cmd_req)
    2358       {
    2359         cmd_read_fifo_get       = true;
    2360         r_read_to_ixr_cmd_req   = true;
    2361         r_read_to_ixr_cmd_nline = m_nline[(addr_t)(m_cmd_read_addr_fifo.read())];
    2362         r_read_to_ixr_cmd_trdid = r_read_trt_index.read();
    2363         r_read_fsm              = READ_IDLE;
     2425        if(not r_read_to_ixr_cmd_req)
     2426        {
     2427            cmd_read_fifo_get       = true;
     2428            r_read_to_ixr_cmd_req   = true;
     2429            r_read_to_ixr_cmd_index = r_read_trt_index.read();
     2430            r_read_fsm              = READ_IDLE;
    23642431
    23652432#if DEBUG_MEMC_READ
     
    23682435          << std::hex << m_cmd_read_addr_fifo.read() << std::endl;
    23692436#endif
    2370       }
    2371       break;
     2437        }
     2438        break;
    23722439    }
    23732440  } // end switch read_fsm
     
    23872454  //   If the data is cached by other processors, a coherence transaction must
    23882455  //   be launched (sc requests always require a coherence transaction):
    2389   //   It is a multicast update if the line is not in counter mode, and the processor
     2456  //   It is a multicast update if the line is not in counter mode: the processor
    23902457  //   takes the lock protecting the Update Table (UPT) to register this transaction.
    2391   //   It is a broadcast invalidate if the line is in counter mode.
    23922458  //   If the UPT is full, it releases the lock(s) and retry. Then, it sends
    23932459  //   a multi-update request to all owners of the line (but the writer),
     
    23952461  //   does not respond to the writing processor, as this response will be sent by
    23962462  //   the MULTI_ACK FSM when all update responses have been received.
     2463  //   It is a broadcast invalidate if the line is in counter mode: The line
     2464  //   should be erased in memory cache, and written in XRAM with a PUT transaction,
     2465  //   after registration in TRT.
    23972466  //
    23982467  // - In case of MISS, the WRITE FSM takes the lock protecting the transaction
    23992468  //   table (TRT). If a read transaction to the XRAM for this line already exists,
    24002469  //   it writes in the TRT (write buffer). Otherwise, if a TRT entry is free,
    2401   //   the WRITE FSM register a new transaction in TRT, and sends a read line request
     2470  //   the WRITE FSM register a new transaction in TRT, and sends a GET request
    24022471  //   to the XRAM. If the TRT is full, it releases the lock, and waits.
    24032472  //   Finally, the WRITE FSM returns an aknowledge response to the writing processor.
    24042473  /////////////////////////////////////////////////////////////////////////////////////
     2474
     2475//std::cout << std::endl << "write_fsm" << std::endl;
    24052476
    24062477  switch(r_write_fsm.read())
     
    24092480    case WRITE_IDLE:  // copy first word of a write burst in local buffer
    24102481    {
    2411       if(m_cmd_write_addr_fifo.rok())
    2412       {
    2413         if((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC)
    2414           m_cpt_sc++;
    2415         else
    2416         {
    2417           m_cpt_write++;
    2418           m_cpt_write_cells++;
    2419         }
    2420 
    2421         // consume a word in the FIFO & write it in the local buffer
    2422         cmd_write_fifo_get  = true;
    2423         size_t index        = m_x[(addr_t)(m_cmd_write_addr_fifo.read())];
    2424 
    2425         r_write_address     = (addr_t)(m_cmd_write_addr_fifo.read());
    2426         r_write_word_index  = index;
    2427         r_write_word_count  = 1;
    2428         r_write_data[index] = m_cmd_write_data_fifo.read();
    2429         r_write_srcid       = m_cmd_write_srcid_fifo.read();
    2430         r_write_trdid       = m_cmd_write_trdid_fifo.read();
    2431         r_write_pktid       = m_cmd_write_pktid_fifo.read();
    2432         r_write_pending_sc  = false;
    2433 
    2434         // initialize the be field for all words
    2435         for(size_t word=0 ; word<m_words ; word++)
    2436         {
    2437           if(word == index) r_write_be[word] = m_cmd_write_be_fifo.read();
    2438           else              r_write_be[word] = 0x0;
    2439         }
    2440 
    2441         if (m_cmd_write_eop_fifo.read() or ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC))
    2442         {
    2443           r_write_fsm = WRITE_DIR_REQ;
    2444         }
    2445         else
    2446         {
    2447           r_write_fsm = WRITE_NEXT;
    2448         }
     2482        if(m_cmd_write_addr_fifo.rok())
     2483        {
     2484            if((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC)
     2485            {
     2486                m_cpt_sc++;
     2487            }
     2488            else
     2489            {
     2490                m_cpt_write++;
     2491                m_cpt_write_cells++;
     2492            }
     2493
     2494            // consume a word in the FIFO & write it in the local buffer
     2495            cmd_write_fifo_get  = true;
     2496            size_t index        = m_x[(addr_t)(m_cmd_write_addr_fifo.read())];
     2497
     2498            r_write_address     = (addr_t)(m_cmd_write_addr_fifo.read());
     2499            r_write_word_index  = index;
     2500            r_write_word_count  = 1;
     2501            r_write_data[index] = m_cmd_write_data_fifo.read();
     2502            r_write_srcid       = m_cmd_write_srcid_fifo.read();
     2503            r_write_trdid       = m_cmd_write_trdid_fifo.read();
     2504            r_write_pktid       = m_cmd_write_pktid_fifo.read();
     2505            r_write_pending_sc  = false;
     2506
     2507            // initialize the be field for all words
     2508            for(size_t word=0 ; word<m_words ; word++)
     2509            {
     2510                if(word == index) r_write_be[word] = m_cmd_write_be_fifo.read();
     2511                else              r_write_be[word] = 0x0;
     2512            }
     2513
     2514            if (m_cmd_write_eop_fifo.read() or ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC))
     2515            {
     2516                r_write_fsm = WRITE_DIR_REQ;
     2517            }
     2518            else
     2519            {
     2520                r_write_fsm = WRITE_NEXT;
     2521            }
    24492522
    24502523#if DEBUG_MEMC_WRITE
     
    24552528          << " / data = " << m_cmd_write_data_fifo.read() << std::endl;
    24562529#endif
    2457       }
    2458       break;
    2459     }
    2460 
     2530        }
     2531        break;
     2532    }
    24612533    ////////////////
    24622534    case WRITE_NEXT:  // copy next word of a write burst in local buffer
    24632535    {
    2464       if(m_cmd_write_addr_fifo.rok())
    2465       {
     2536        if(m_cmd_write_addr_fifo.rok())
     2537        {
    24662538
    24672539#if DEBUG_MEMC_WRITE
     
    24712543          << std::endl;
    24722544#endif
    2473         m_cpt_write_cells++;
    2474 
    2475         // check that the next word is in the same cache line
    2476         if((m_nline[(addr_t)(r_write_address.read())]       !=
    2477             m_nline[(addr_t)(m_cmd_write_addr_fifo.read())]))
    2478         {
    2479           std::cout << "VCI_MEM_CACHE ERROR " << name() << " WRITE_NEXT state" << std::endl
    2480                     << "all words in a write burst must be in same cache line" << std::endl;
    2481 
    2482           exit(0);
    2483         }
    2484 
    2485         // consume a word in the FIFO & write it in the local buffer
    2486         cmd_write_fifo_get  = true;
    2487         size_t index        = r_write_word_index.read() + r_write_word_count.read();
    2488 
    2489         r_write_be[index]   = m_cmd_write_be_fifo.read();
    2490         r_write_data[index] = m_cmd_write_data_fifo.read();
    2491         r_write_word_count  = r_write_word_count.read() + 1;
    2492 
    2493         if(m_cmd_write_eop_fifo.read())
    2494         {
    2495           r_write_fsm = WRITE_DIR_REQ;
    2496         }
    2497       }
    2498       break;
    2499     }
    2500 
    2501     ////////////////////
    2502     case WRITE_DIR_REQ:
    2503     {
    2504       // Get the lock to the directory
    2505       // and access the llsc_global_table
    2506       if(r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE)
    2507       {
    2508         ///////////////////////////////////////////////////////////////////////
    2509         // SC command treatment
    2510         // We test the r_write_pending_sc register to know if we are returning
    2511         // from the WAIT state.
    2512         // In this case, the SC has already succeed and we cannot consume
    2513         // another time from the FIFO. Also, we don't have to test another
    2514         // time if the SC has succeed
    2515         if(((r_write_pktid.read() & 0x7) == TYPE_SC) and not r_write_pending_sc.read())
    2516         {
    2517           if(not m_cmd_write_addr_fifo.rok()) break;
    2518 
    2519           assert(m_cmd_write_eop_fifo.read() and
    2520                  "Error in VCI_MEM_CACHE : "
    2521                  "invalid packet format for SC command");
    2522 
    2523           size_t index    = r_write_word_index.read();
    2524           bool sc_success = m_llsc_table.sc(r_write_address.read()    ,
     2545            m_cpt_write_cells++;
     2546
     2547            // check that the next word is in the same cache line
     2548            assert( (m_nline[(addr_t)(r_write_address.read())] ==
     2549                     m_nline[(addr_t)(m_cmd_write_addr_fifo.read())]) and
     2550            "MEMC ERROR in WRITE_NEXT state: Illegal write burst");
     2551
     2552            // consume a word in the FIFO & write it in the local buffer
     2553            cmd_write_fifo_get  = true;
     2554            size_t index        = r_write_word_index.read() + r_write_word_count.read();
     2555
     2556            r_write_be[index]   = m_cmd_write_be_fifo.read();
     2557            r_write_data[index] = m_cmd_write_data_fifo.read();
     2558            r_write_word_count  = r_write_word_count.read() + 1;
     2559
     2560            if(m_cmd_write_eop_fifo.read()) r_write_fsm = WRITE_DIR_REQ;
     2561        }
     2562        break;
     2563    }
     2564    ///////////////////
     2565    case WRITE_DIR_REQ:    // Get the lock to the directory
     2566                           // and access the llsc_global_table
     2567    {
     2568        if( r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE )
     2569        {
     2570            if(((r_write_pktid.read() & 0x7) == TYPE_SC) and not r_write_pending_sc.read())
     2571            {
     2572                // We enter here if it is a new SC command
     2573                // If r_write_pending_sc is set the SC is not new and has already been tested
     2574
     2575                if(not m_cmd_write_addr_fifo.rok()) break;
     2576
     2577                assert( m_cmd_write_eop_fifo.read() and
     2578                "MEMC ERROR in WRITE_DIR_REQ state: invalid packet format for SC command");
     2579
     2580                size_t index    = r_write_word_index.read();
     2581                bool sc_success = m_llsc_table.sc(r_write_address.read()    ,
    25252582                                            r_write_data[index].read());
    25262583
    2527           // consume a word in the FIFO & write it in the local buffer
    2528           cmd_write_fifo_get  = true;
    2529           r_write_data[index] = m_cmd_write_data_fifo.read();
    2530           r_write_sc_fail     = not sc_success;
    2531           r_write_pending_sc  = true;
    2532 
    2533           if(not sc_success) r_write_fsm = WRITE_RSP;
    2534           else               r_write_fsm = WRITE_DIR_LOCK;
    2535 
    2536           break;
    2537         }
    2538 
    2539         ///////////////////////////////////////////////////////////////////////
    2540         // WRITE command treatment or SC command returning from the WAIT state
    2541         // In the second case, we must access the LL/SC global table to
    2542         // erase any possible new reservation when we release the lock on the
    2543         // directory
    2544         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());
    2545 
    2546         r_write_fsm = WRITE_DIR_LOCK;
    2547       }
     2584                // consume a word in the FIFO & write it in the local buffer
     2585                cmd_write_fifo_get  = true;
     2586                r_write_data[index] = m_cmd_write_data_fifo.read();
     2587                r_write_sc_fail     = not sc_success;
     2588                r_write_pending_sc  = true;
     2589
     2590                if(not sc_success) r_write_fsm = WRITE_RSP;
     2591                else               r_write_fsm = WRITE_DIR_LOCK;
     2592            }
     2593            else
     2594            {
     2595                // We enter here if it is a SW command or an already tested SC command
     2596
     2597                m_llsc_table.sw( m_nline[(addr_t)r_write_address.read()],
     2598                                 r_write_word_index.read(),
     2599                                 r_write_word_index.read() + r_write_word_count.read() );
     2600
     2601                r_write_fsm = WRITE_DIR_LOCK;
     2602            }
    25482603
    25492604#if DEBUG_MEMC_WRITE
     
    25522607          << std::endl;
    25532608#endif
    2554 
    2555       break;
    2556     }
    2557 
     2609        }
     2610        break;
     2611    }
    25582612    ////////////////////
    25592613    case WRITE_DIR_LOCK:     // access directory to check hit/miss
    25602614    {
    2561       if(r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE)
    2562       {
     2615        assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
     2616        "MEMC ERROR in ALLOC_DIR_LOCK state: Bad DIR allocation");
     2617
    25632618        size_t  way = 0;
    25642619        DirectoryEntry entry(m_cache_directory.read(r_write_address.read(), way));
     
    25662621        if(entry.valid)    // hit
    25672622        {
    2568           // copy directory entry in local buffer in case of hit
    2569           r_write_is_cnt     = entry.is_cnt;
    2570           r_write_lock       = entry.lock;
    2571           r_write_tag        = entry.tag;
    2572           r_write_copy       = entry.owner.srcid;
    2573 #if L1_MULTI_CACHE
    2574           r_write_copy_cache = entry.owner.cache_id;
    2575 #endif
    2576           r_write_copy_inst  = entry.owner.inst;
    2577           r_write_count      = entry.count;
    2578           r_write_ptr        = entry.ptr;
    2579           r_write_way        = way;
    2580 
    2581           if(entry.is_cnt and entry.count)
    2582           {
    2583             r_write_fsm = WRITE_DIR_READ;
    2584           }
    2585           else
    2586           {
    2587             r_write_fsm = WRITE_DIR_HIT;
    2588           }
     2623            // copy directory entry in local buffer in case of hit
     2624            r_write_is_cnt     = entry.is_cnt;
     2625            r_write_lock       = entry.lock;
     2626            r_write_tag        = entry.tag;
     2627            r_write_copy       = entry.owner.srcid;
     2628            r_write_copy_inst  = entry.owner.inst;
     2629            r_write_count      = entry.count;
     2630            r_write_ptr        = entry.ptr;
     2631            r_write_way        = way;
     2632
     2633            if(entry.is_cnt and entry.count) r_write_fsm = WRITE_BC_DIR_READ;
     2634            else                             r_write_fsm = WRITE_DIR_HIT;
    25892635        }
    25902636        else  // miss
    25912637        {
    2592           r_write_fsm = WRITE_MISS_TRT_LOCK;
     2638            r_write_fsm = WRITE_MISS_TRT_LOCK;
    25932639        }
    25942640
     
    26072653}
    26082654#endif
    2609       }
    2610       else
    2611       {
    2612         std::cout << "VCI_MEM_CACHE ERROR " << name()
    2613                   << " WRITE_DIR_LOCK state"        << std::endl
    2614                   << "bad DIR allocation"           << std::endl;
    2615 
    2616         exit(0);
    2617       }
    2618       break;
    2619     }
    2620     ////////////////////
    2621     case WRITE_DIR_READ:  // read the cache and complete the buffer when be!=0xF
    2622     {
    2623       // update local buffer
    2624       size_t set  = m_y[(addr_t)(r_write_address.read())];
    2625       size_t way  = r_write_way.read();
    2626       for(size_t word=0 ; word<m_words ; word++)
    2627       {
    2628         data_t mask = 0;
    2629         if(r_write_be[word].read() & 0x1) mask = mask | 0x000000FF;
    2630         if(r_write_be[word].read() & 0x2) mask = mask | 0x0000FF00;
    2631         if(r_write_be[word].read() & 0x4) mask = mask | 0x00FF0000;
    2632         if(r_write_be[word].read() & 0x8) mask = mask | 0xFF000000;
    2633 
    2634         // complete only if mask is not null (for energy consumption)
    2635         r_write_data[word]  = (r_write_data[word].read() & mask) |
    2636                               (m_cache_data.read(way, set, word) & ~mask);
    2637 
    2638       } // end for
    2639 
    2640       // test if a coherence broadcast is required
    2641       r_write_fsm = WRITE_BC_TRT_LOCK;
    2642 
    2643 #if DEBUG_MEMC_WRITE
    2644 if(m_debug)
    2645 std::cout << "  <MEMC " << name() << " WRITE_DIR_READ>"
    2646           << " Read the cache to complete local buffer" << std::endl;
    2647 #endif
    2648       break;
    2649     }
    2650 
     2655        break;
     2656    }
    26512657    ///////////////////
    2652     case WRITE_DIR_HIT:
    2653     {
    2654       // update the cache directory
    2655       // update directory with Dirty bit
    2656       DirectoryEntry entry;
    2657       entry.valid          = true;
    2658       entry.dirty          = true;
    2659       entry.tag            = r_write_tag.read();
    2660       entry.is_cnt         = r_write_is_cnt.read();
    2661       entry.lock           = r_write_lock.read();
    2662       entry.owner.srcid    = r_write_copy.read();
    2663 #if L1_MULTI_CACHE
    2664       entry.owner.cache_id = r_write_copy_cache.read();
    2665 #endif
    2666       entry.owner.inst     = r_write_copy_inst.read();
    2667       entry.count          = r_write_count.read();
    2668       entry.ptr            = r_write_ptr.read();
    2669 
    2670       size_t set           = m_y[(addr_t)(r_write_address.read())];
    2671       size_t way           = r_write_way.read();
    2672 
    2673       // update directory
    2674       m_cache_directory.write(set, way, entry);
    2675 
    2676       // owner is true when the  the first registered copy is the writer itself
    2677       bool owner = (((r_write_copy.read() == r_write_srcid.read())
    2678 #if L1_MULTI_CACHE
    2679                      and(r_write_copy_cache.read() ==r_write_pktid.read())
    2680 #endif
    2681                     ) and not r_write_copy_inst.read());
    2682 
    2683       // no_update is true when there is no need for coherence transaction
    2684       // (tests for sc requests)
    2685       bool no_update = ( (r_write_count.read() == 0) or
     2658    case WRITE_DIR_HIT:    // update the cache directory with Dirty bit
     2659                           // and update data cache
     2660    {
     2661        assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
     2662        "MEMC ERROR in ALLOC_DIR_HIT state: Bad DIR allocation");
     2663
     2664        DirectoryEntry entry;
     2665        entry.valid          = true;
     2666        entry.dirty          = true;
     2667        entry.tag            = r_write_tag.read();
     2668        entry.is_cnt         = r_write_is_cnt.read();
     2669        entry.lock           = r_write_lock.read();
     2670        entry.owner.srcid    = r_write_copy.read();
     2671        entry.owner.inst     = r_write_copy_inst.read();
     2672        entry.count          = r_write_count.read();
     2673        entry.ptr            = r_write_ptr.read();
     2674
     2675        size_t set           = m_y[(addr_t)(r_write_address.read())];
     2676        size_t way           = r_write_way.read();
     2677
     2678        // update directory
     2679        m_cache_directory.write(set, way, entry);
     2680
     2681        // owner is true when the  the first registered copy is the writer itself
     2682        bool owner = ( (r_write_copy.read() == r_write_srcid.read())
     2683                     and not r_write_copy_inst.read() );
     2684
     2685        // no_update is true when there is no need for coherence transaction
     2686        bool no_update = ( (r_write_count.read() == 0) or
    26862687                         (owner and (r_write_count.read() ==1) and
    26872688                         (r_write_pktid.read() != TYPE_SC)));
    26882689
    2689       // write data in the cache if no coherence transaction
    2690       if(no_update)
    2691       {
    2692         for(size_t word=0 ; word<m_words ; word++)
    2693         {
    2694           m_cache_data.write(way, set, word, r_write_data[word].read(), r_write_be[word].read());
    2695 
    2696           if(m_monitor_ok)
    2697           {
    2698             addr_t address = (r_write_address.read() & ~(addr_t) 0x3F) | word<<2;
    2699             check_monitor( address, r_write_data[word].read(), false);
    2700           }
    2701         }
    2702       }
    2703 
    2704       if(owner and not no_update and(r_write_pktid.read() != TYPE_SC))
    2705       {
    2706         r_write_count = r_write_count.read() - 1;
    2707       }
    2708 
    2709       if(no_update)
    2710       // Write transaction completed
    2711       {
    2712         r_write_fsm = WRITE_RSP;
    2713       }
    2714       else
    2715       // coherence update required
    2716       {
    2717         if(!r_write_to_cc_send_multi_req.read() and
    2718            !r_write_to_cc_send_brdcast_req.read())
    2719         {
    2720           r_write_fsm = WRITE_UPT_LOCK;
    2721         }
    2722         else
    2723         {
    2724           r_write_fsm = WRITE_WAIT;
    2725         }
    2726       }
     2690        // write data in the cache if no coherence transaction
     2691        if(no_update)
     2692        {
     2693            for(size_t word=0 ; word<m_words ; word++)
     2694            {
     2695                m_cache_data.write( way,
     2696                                    set,
     2697                                    word,
     2698                                    r_write_data[word].read(),
     2699                                    r_write_be[word].read());
     2700            }
     2701        }
     2702
     2703        if(owner and not no_update and(r_write_pktid.read() != TYPE_SC))
     2704        {
     2705            r_write_count = r_write_count.read() - 1;
     2706        }
     2707
     2708        if(no_update)     // Write transaction completed
     2709        {
     2710            r_write_fsm = WRITE_RSP;
     2711        }
     2712        else              // coherence update required
     2713        {
     2714            if(!r_write_to_cc_send_multi_req.read() and
     2715               !r_write_to_cc_send_brdcast_req.read())
     2716            {
     2717                r_write_fsm = WRITE_UPT_LOCK;
     2718            }
     2719            else
     2720            {
     2721                r_write_fsm = WRITE_WAIT;
     2722            }
     2723        }
    27272724
    27282725#if DEBUG_MEMC_WRITE
    27292726if(m_debug)
    27302727{
    2731     if(no_update)
    2732     {
    2733         std::cout << "  <MEMC " << name()
    2734                   << " WRITE_DIR_HIT> Write into cache / No coherence transaction"
    2735                   << std::endl;
    2736     }
    2737     else
    2738     {
    2739         std::cout << "  <MEMC " << name() << " WRITE_DIR_HIT> Coherence update required:"
    2740                   << " is_cnt = " << r_write_is_cnt.read()
    2741                   << " nb_copies = " << std::dec << r_write_count.read() << std::endl;
    2742         if(owner) std::cout << "       ... but the first copy is the writer" << std::endl;
    2743     }
     2728if(no_update)
     2729{
     2730std::cout << "  <MEMC " << name()
     2731          << " WRITE_DIR_HIT> Write into cache / No coherence transaction" << std::endl;
    27442732}
    2745 #endif
    2746       break;
     2733else
     2734{
     2735std::cout << "  <MEMC " << name() << " WRITE_DIR_HIT> Coherence update required:"
     2736          << " is_cnt = " << r_write_is_cnt.read()
     2737          << " nb_copies = " << std::dec << r_write_count.read() << std::endl;
     2738if(owner) std::cout << "       ... but the first copy is the writer" << std::endl;
     2739}
     2740}
     2741#endif
     2742        break;
    27472743    }
    27482744    ////////////////////
    27492745    case WRITE_UPT_LOCK:  // Try to register the update request in UPT
    27502746    {
    2751       if(r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE)
    2752       {
    2753         bool        wok        = false;
    2754         size_t      index      = 0;
    2755         size_t      srcid      = r_write_srcid.read();
    2756         size_t      trdid      = r_write_trdid.read();
    2757         size_t      pktid      = r_write_pktid.read();
    2758         addr_t      nline      = m_nline[(addr_t)(r_write_address.read())];
    2759         size_t      nb_copies  = r_write_count.read();
    2760         size_t      set        = m_y[(addr_t)(r_write_address.read())];
    2761         size_t      way        = r_write_way.read();
    2762 
    2763         wok = m_upt.set(true,  // it's an update transaction
    2764                         false, // it's not a broadcast
    2765                         true,  // response required
    2766                         false, // no acknowledge required
    2767                         srcid,   
    2768                         trdid,
    2769                         pktid,
    2770                         nline,
    2771                         nb_copies,
    2772                         index);
    2773         if(wok)       // write data in cache
    2774         {
    2775           for(size_t word=0 ; word<m_words ; word++)
    2776           {
    2777             m_cache_data.write(way,
    2778                                set,
    2779                                word,
    2780                                r_write_data[word].read(),
    2781                                r_write_be[word].read());
    2782 
    2783             if(m_monitor_ok)
     2747        if(r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE)
     2748        {
     2749            bool        wok        = false;
     2750            size_t      index      = 0;
     2751            size_t      srcid      = r_write_srcid.read();
     2752            size_t      trdid      = r_write_trdid.read();
     2753            size_t      pktid      = r_write_pktid.read();
     2754            addr_t      nline      = m_nline[(addr_t)(r_write_address.read())];
     2755            size_t      nb_copies  = r_write_count.read();
     2756            size_t      set        = m_y[(addr_t)(r_write_address.read())];
     2757            size_t      way        = r_write_way.read();
     2758
     2759            wok = m_upt.set( true,  // it's an update transaction
     2760                             false, // it's not a broadcast
     2761                             true,  // response required
     2762                             false, // no acknowledge required
     2763                             srcid,   
     2764                             trdid,
     2765                             pktid,
     2766                             nline,
     2767                             nb_copies,
     2768                             index);
     2769
     2770            if( wok )       // write data in cache
    27842771            {
    2785               addr_t address = (r_write_address.read() & ~(addr_t) 0x3F) | word<<2;
    2786               check_monitor( address, r_write_data[word].read(), false);
     2772                for(size_t word=0 ; word<m_words ; word++)
     2773                {
     2774                    m_cache_data.write( way,
     2775                                        set,
     2776                                        word,
     2777                                        r_write_data[word].read(),
     2778                                        r_write_be[word].read());
     2779                }
    27872780            }
    2788           }
    2789         }
    27902781
    27912782#if DEBUG_MEMC_WRITE
    2792 if(m_debug)
     2783if(m_debug and wok)
    27932784{
    2794     if(wok)
    2795     {
    2796         std::cout << "  <MEMC " << name()
    2797                   << " WRITE_UPT_LOCK> Register the multicast update in UPT / "
    2798                   << " nb_copies = " << r_write_count.read() << std::endl;
    2799     }
     2785std::cout << "  <MEMC " << name()
     2786          << " WRITE_UPT_LOCK> Register the multicast update in UPT / "
     2787          << " nb_copies = " << r_write_count.read() << std::endl;
    28002788}
    28012789#endif
    2802         r_write_upt_index = index;
    2803         // releases the lock protecting UPT and the DIR if no entry...
    2804         if(wok) r_write_fsm = WRITE_UPT_HEAP_LOCK;
    2805         else    r_write_fsm = WRITE_WAIT;
    2806       }
    2807       break;
     2790            r_write_upt_index = index;
     2791            // releases the lock protecting UPT and the DIR if no entry...
     2792            if(wok) r_write_fsm = WRITE_UPT_HEAP_LOCK;
     2793            else    r_write_fsm = WRITE_WAIT;
     2794        }
     2795        break;
    28082796    }
    28092797
     
    28472835      for(size_t i=min ; i<max ; i++) r_write_to_cc_send_data[i] = r_write_data[i];
    28482836
    2849       if((r_write_copy.read() != r_write_srcid.read()) or(r_write_pktid.read() == TYPE_SC) or
    2850 #if L1_MULTI_CACHE
    2851           (r_write_copy_cache.read() != r_write_pktid.read()) or
    2852 #endif
    2853           r_write_copy_inst.read())
     2837      if( (r_write_copy.read() != r_write_srcid.read()) or
     2838          (r_write_pktid.read() == TYPE_SC) or r_write_copy_inst.read())
    28542839      {
    28552840        // put the first srcid in the fifo
     
    28572842        write_to_cc_send_fifo_inst    = r_write_copy_inst.read();
    28582843        write_to_cc_send_fifo_srcid   = r_write_copy.read();
    2859 #if L1_MULTI_CACHE
    2860         write_to_cc_send_fifo_cache_id= r_write_copy_cache.read();
    2861 #endif
    28622844        if(r_write_count.read() == 1)
    28632845        {
     
    29102892      bool dec_upt_counter;
    29112893
    2912       if(((entry.owner.srcid != r_write_srcid.read()) or (r_write_pktid.read() == TYPE_SC)) or
    2913 #if L1_MULTI_CACHE
    2914           (entry.owner.cache_id != r_write_pktid.read()) or
    2915 #endif
    2916           entry.owner.inst)             // put the next srcid in the fifo
     2894      // put the next srcid in the fifo
     2895      if( (entry.owner.srcid != r_write_srcid.read()) or
     2896          (r_write_pktid.read() == TYPE_SC) or entry.owner.inst)   
    29172897      {
    29182898        dec_upt_counter                = false;
     
    29202900        write_to_cc_send_fifo_inst     = entry.owner.inst;
    29212901        write_to_cc_send_fifo_srcid    = entry.owner.srcid;
    2922 #if L1_MULTI_CACHE
    2923         write_to_cc_send_fifo_cache_id = entry.owner.cache_id;
    2924 #endif
    29252902
    29262903#if DEBUG_MEMC_WRITE
     
    29922969
    29932970    ///////////////
    2994     case WRITE_RSP:
    2995     {
    2996       // Post a request to TGT_RSP FSM to acknowledge the write
    2997       // In order to increase the Write requests throughput,
    2998       // we don't wait to return in the IDLE state to consume
    2999       // a new request in the write FIFO
    3000 
     2971    case WRITE_RSP:  // Post a request to TGT_RSP FSM to acknowledge the write
     2972                     // In order to increase the Write requests throughput,
     2973                     // we don't wait to return in the IDLE state to consume
     2974                     // a new request in the write FIFO
     2975    {
    30012976      if(!r_write_to_tgt_rsp_req.read())
    30022977      {
     
    30863061        bool    hit_read  = m_trt.hit_read(m_nline[addr], hit_index);
    30873062        bool    hit_write = m_trt.hit_write(m_nline[addr]);
    3088         bool    wok       = !m_trt.full(wok_index);
     3063        bool    wok       = not m_trt.full(wok_index);
    30893064
    30903065        if(hit_read)      // register the modified data in TRT
     
    31703145          data_vector.push_back(r_write_data[i]);
    31713146        }
    3172         m_trt.write_data_mask(r_write_trt_index.read(),
    3173                                           be_vector,
    3174                                           data_vector);
     3147        m_trt.write_data_mask( r_write_trt_index.read(),
     3148                               be_vector,
     3149                               data_vector );
    31753150        r_write_fsm = WRITE_RSP;
    31763151
     
    31823157      break;
    31833158    }
    3184 
    31853159    /////////////////////////
    31863160    case WRITE_MISS_XRAM_REQ: // send a GET request to IXR_CMD FSM
    31873161    {
    3188       if(!r_write_to_ixr_cmd_req)
     3162      if( not r_write_to_ixr_cmd_req.read() )
    31893163      {
    31903164        r_write_to_ixr_cmd_req   = true;
    3191         r_write_to_ixr_cmd_write = false;
    3192         r_write_to_ixr_cmd_nline = m_nline[(addr_t)(r_write_address.read())];
    3193         r_write_to_ixr_cmd_trdid = r_write_trt_index.read();
     3165        r_write_to_ixr_cmd_put   = false;
     3166        r_write_to_ixr_cmd_index = r_write_trt_index.read();
    31943167        r_write_fsm              = WRITE_RSP;
    31953168
     
    32013174      break;
    32023175    }
    3203 
    32043176    ///////////////////////
    3205     case WRITE_BC_TRT_LOCK:     // Check TRT not full
    3206     {
    3207       if(r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE)
    3208       {
    3209         size_t wok_index = 0;
    3210         bool wok = !m_trt.full(wok_index);
    3211         if(wok)       // set a new entry in TRT
    3212         {
    3213           r_write_trt_index = wok_index;
    3214           r_write_fsm       = WRITE_BC_IVT_LOCK;
    3215         }
    3216         else  // wait an empty entry in TRT
    3217         {
    3218           r_write_fsm       = WRITE_WAIT;
    3219         }
     3177    case WRITE_BC_DIR_READ:  // enter this state if a broadcast-inval is required
     3178                             // the cache line must be erased in mem-cache, and written
     3179                             // into XRAM. we read the cache and complete the buffer
     3180    {
     3181        assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
     3182        "MEMC ERROR in WRITE_BC_DIR_READ state: Bad DIR allocation");
     3183 
     3184        // update local buffer
     3185        size_t set  = m_y[(addr_t)(r_write_address.read())];
     3186        size_t way  = r_write_way.read();
     3187        for(size_t word=0 ; word<m_words ; word++)
     3188        {
     3189            data_t mask = 0;
     3190            if(r_write_be[word].read() & 0x1) mask = mask | 0x000000FF;
     3191            if(r_write_be[word].read() & 0x2) mask = mask | 0x0000FF00;
     3192            if(r_write_be[word].read() & 0x4) mask = mask | 0x00FF0000;
     3193            if(r_write_be[word].read() & 0x8) mask = mask | 0xFF000000;
     3194
     3195            // complete only if mask is not null (for energy consumption)
     3196            r_write_data[word]  = (r_write_data[word].read() & mask) |
     3197                                  (m_cache_data.read(way, set, word) & ~mask);
     3198        } // end for
     3199
     3200        r_write_fsm = WRITE_BC_TRT_LOCK;
     3201
     3202#if DEBUG_MEMC_WRITE
     3203if(m_debug)
     3204std::cout << "  <MEMC " << name() << " WRITE_BC_DIR_READ>"
     3205          << " Read the cache to complete local buffer" << std::endl;
     3206#endif
     3207        break;
     3208    }
     3209    ///////////////////////
     3210    case WRITE_BC_TRT_LOCK:     // get TRT lock to check TRT not full
     3211    {
     3212        assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
     3213        "MEMC ERROR in WRITE_BC_TRT_LOCK state: Bad DIR allocation");
     3214 
     3215        if(r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE)
     3216        {
     3217            size_t wok_index = 0;
     3218            bool wok = not m_trt.full(wok_index);
     3219            if( wok )       
     3220            {
     3221                r_write_trt_index = wok_index;
     3222                r_write_fsm       = WRITE_BC_IVT_LOCK;
     3223            }
     3224            else  // wait an empty slot in TRT
     3225            {
     3226                r_write_fsm       = WRITE_WAIT;
     3227            }
    32203228
    32213229#if DEBUG_MEMC_WRITE
     
    32243232          << " : wok = " << wok << " / index = " << wok_index << std::endl;
    32253233#endif
    3226       }
    3227       break;
    3228     }
    3229 
     3234        }
     3235        break;
     3236    }
    32303237    //////////////////////
    3231     case WRITE_BC_IVT_LOCK:      // register BC transaction in IVT
    3232     {
    3233       if(r_alloc_ivt_fsm.read() == ALLOC_IVT_WRITE)
    3234       {
    3235         bool        wok       = false;
    3236         size_t      index     = 0;
    3237         size_t      srcid     = r_write_srcid.read();
    3238         size_t      trdid     = r_write_trdid.read();
    3239         size_t      pktid     = r_write_pktid.read();
    3240         addr_t      nline     = m_nline[(addr_t)(r_write_address.read())];
    3241         size_t      nb_copies = r_write_count.read();
    3242 
    3243         wok = m_ivt.set(false,  // it's an inval transaction
    3244                         true,   // it's a broadcast
    3245                         true,   // response required
    3246                         false,  // no acknowledge required
    3247                         srcid,
    3248                         trdid,
    3249                         pktid,
    3250                         nline,
    3251                         nb_copies,
    3252                         index);
    3253 
     3238    case WRITE_BC_IVT_LOCK:      // get IVT lock and register BC transaction in IVT
     3239    {
     3240        assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
     3241        "MEMC ERROR in WRITE_BC_IVT_LOCK state: Bad DIR allocation");
     3242 
     3243        assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE) and
     3244        "MEMC ERROR in WRITE_BC_IVT_LOCK state: Bad TRT allocation");
     3245 
     3246        if(r_alloc_ivt_fsm.read() == ALLOC_IVT_WRITE)
     3247        {
     3248            bool        wok       = false;
     3249            size_t      index     = 0;
     3250            size_t      srcid     = r_write_srcid.read();
     3251            size_t      trdid     = r_write_trdid.read();
     3252            size_t      pktid     = r_write_pktid.read();
     3253            addr_t      nline     = m_nline[(addr_t)(r_write_address.read())];
     3254            size_t      nb_copies = r_write_count.read();
     3255
     3256            wok = m_ivt.set(false,  // it's an inval transaction
     3257                            true,   // it's a broadcast
     3258                            true,   // response required
     3259                            false,  // no acknowledge required
     3260                            srcid,
     3261                            trdid,
     3262                            pktid,
     3263                            nline,
     3264                            nb_copies,
     3265                            index);
    32543266#if DEBUG_MEMC_WRITE
    32553267if( m_debug and wok )
     
    32573269          << " / nb_copies = " << r_write_count.read() << std::endl;
    32583270#endif
    3259         r_write_upt_index = index;
    3260 
    3261         if(wok) r_write_fsm = WRITE_BC_DIR_INVAL;
    3262         else    r_write_fsm = WRITE_WAIT;
    3263       }
    3264       break;
    3265     }
    3266 
     3271            r_write_upt_index = index;
     3272
     3273            if( wok ) r_write_fsm = WRITE_BC_DIR_INVAL;
     3274            else      r_write_fsm = WRITE_WAIT;
     3275        }
     3276        break;
     3277    }
    32673278    ////////////////////////
    3268     case WRITE_BC_DIR_INVAL:
    3269     {
    3270       // Register a put transaction to XRAM in TRT
    3271       // and invalidate the line in directory
    3272       if((r_alloc_trt_fsm.read() != ALLOC_TRT_WRITE) or
    3273          (r_alloc_ivt_fsm.read() != ALLOC_IVT_WRITE) or
    3274          (r_alloc_dir_fsm.read() != ALLOC_DIR_WRITE))
    3275       {
    3276         std::cout << "VCI_MEM_CACHE ERROR " << name() << " WRITE_BC_DIR_INVAL state" << std::endl;
    3277         std::cout << "bad TRT, DIR, or IVT allocation" << std::endl;
    3278         exit(0);
    3279       }
    3280 
    3281       // register a write request to XRAM in TRT
    3282       m_trt.set(r_write_trt_index.read(),
    3283                             false,    // write request to XRAM
    3284                             m_nline[(addr_t)(r_write_address.read())],
    3285                             0,
    3286                             0,
    3287                             0,
    3288                             false,    // not a processor read
    3289                             0,        // not a single word
    3290                             0,            // word index
    3291                             std::vector<be_t> (m_words,0),
    3292                             std::vector<data_t> (m_words,0));
    3293 
    3294       // invalidate directory entry
    3295       DirectoryEntry entry;
    3296       entry.valid         = false;
    3297       entry.dirty         = false;
    3298       entry.tag         = 0;
    3299       entry.is_cnt        = false;
    3300       entry.lock          = false;
    3301       entry.owner.srcid   = 0;
    3302 #if L1_MULTI_CACHE
    3303       entry.owner.cache_id= 0;
    3304 #endif
    3305       entry.owner.inst    = false;
    3306       entry.ptr           = 0;
    3307       entry.count         = 0;
    3308       size_t set          = m_y[(addr_t)(r_write_address.read())];
    3309       size_t way          = r_write_way.read();
    3310 
    3311       m_cache_directory.write(set, way, entry);
     3279    case WRITE_BC_DIR_INVAL:    // Register a put transaction in TRT
     3280                                // and invalidate the line in directory
     3281    {
     3282        assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
     3283        "MEMC ERROR in WRITE_BC_DIR_INVAL state: Bad DIR allocation");
     3284 
     3285        assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE) and
     3286        "MEMC ERROR in WRITE_BC_DIR_INVAL state: Bad TRT allocation");
     3287 
     3288        assert( (r_alloc_ivt_fsm.read() == ALLOC_IVT_WRITE) and
     3289        "MEMC ERROR in WRITE_BC_DIR_INVAL state: Bad IVT allocation");
     3290 
     3291        // register PUT request in TRT
     3292        std::vector<data_t> data_vector;
     3293        data_vector.clear();
     3294        for(size_t i=0; i<m_words; i++) data_vector.push_back(r_write_data[i].read());
     3295        m_trt.set( r_write_trt_index.read(),
     3296                   false,             // PUT request
     3297                   m_nline[(addr_t)(r_write_address.read())],
     3298                   0,                 // unused
     3299                   0,                 // unused
     3300                   0,                 // unused
     3301                   false,             // not a processor read
     3302                   0,                 // unused
     3303                   0,                 // unused
     3304                   std::vector<be_t> (m_words,0),
     3305                   data_vector );
     3306
     3307        // invalidate directory entry
     3308        DirectoryEntry entry;
     3309        entry.valid         = false;
     3310        entry.dirty         = false;
     3311        entry.tag           = 0;
     3312        entry.is_cnt        = false;
     3313        entry.lock          = false;
     3314        entry.owner.srcid   = 0;
     3315        entry.owner.inst    = false;
     3316        entry.ptr           = 0;
     3317        entry.count         = 0;
     3318        size_t set          = m_y[(addr_t)(r_write_address.read())];
     3319        size_t way          = r_write_way.read();
     3320
     3321        m_cache_directory.write(set, way, entry);
    33123322
    33133323#if DEBUG_MEMC_WRITE
    33143324if(m_debug)
    3315 std::cout << "  <MEMC " << name() << " WRITE_BC_DIR_INVAL> Invalidate the directory entry: @ = "
    3316           << r_write_address.read() << " / register the put transaction in TRT:" << std::endl;
    3317 #endif
    3318       r_write_fsm = WRITE_BC_CC_SEND;
    3319       break;
     3325std::cout << "  <MEMC " << name() << " WRITE_BC_DIR_INVAL> Inval DIR and register in TRT:"
     3326          << " address = " << r_write_address.read() << std::endl;
     3327#endif
     3328        r_write_fsm = WRITE_BC_CC_SEND;
     3329        break;
    33203330    }
    33213331
     
    33233333    case WRITE_BC_CC_SEND:    // Post a coherence broadcast request to CC_SEND FSM
    33243334    {
    3325       if(!r_write_to_cc_send_multi_req.read() and !r_write_to_cc_send_brdcast_req.read())
    3326       {
    3327         r_write_to_cc_send_multi_req   = false;
    3328         r_write_to_cc_send_brdcast_req = true;
    3329         r_write_to_cc_send_trdid       = r_write_upt_index.read();
    3330         r_write_to_cc_send_nline       = m_nline[(addr_t)(r_write_address.read())];
    3331         r_write_to_cc_send_index       = 0;
    3332         r_write_to_cc_send_count       = 0;
    3333 
    3334         for(size_t i=0; i<m_words ; i++)
    3335         {
    3336           r_write_to_cc_send_be[i]=0;
    3337           r_write_to_cc_send_data[i] = 0;
    3338         }
    3339         r_write_fsm = WRITE_BC_XRAM_REQ;
     3335        if(!r_write_to_cc_send_multi_req.read() and !r_write_to_cc_send_brdcast_req.read())
     3336        {
     3337            r_write_to_cc_send_multi_req   = false;
     3338            r_write_to_cc_send_brdcast_req = true;
     3339            r_write_to_cc_send_trdid       = r_write_upt_index.read();
     3340            r_write_to_cc_send_nline       = m_nline[(addr_t)(r_write_address.read())];
     3341            r_write_to_cc_send_index       = 0;
     3342            r_write_to_cc_send_count       = 0;
     3343
     3344            for(size_t i=0; i<m_words ; i++)  // à quoi sert ce for? (AG)
     3345            {
     3346                r_write_to_cc_send_be[i]=0;
     3347                r_write_to_cc_send_data[i] = 0;
     3348            }
     3349            r_write_fsm = WRITE_BC_XRAM_REQ;
    33403350
    33413351#if DEBUG_MEMC_WRITE
     
    33443354          << " WRITE_BC_CC_SEND> Post a broadcast request to CC_SEND FSM" << std::endl;
    33453355#endif
    3346       }
    3347       break;
     3356        }
     3357        break;
    33483358    }
    33493359
    33503360    ///////////////////////
    3351     case WRITE_BC_XRAM_REQ:   // Post a put request to IXR_CMD FSM
    3352     {
    3353       if(!r_write_to_ixr_cmd_req)
    3354       {
    3355         r_write_to_ixr_cmd_req     = true;
    3356         r_write_to_ixr_cmd_write   = true;
    3357         r_write_to_ixr_cmd_nline   = m_nline[(addr_t)(r_write_address.read())];
    3358         r_write_to_ixr_cmd_trdid   = r_write_trt_index.read();
    3359 
    3360         for(size_t i=0; i<m_words; i++) r_write_to_ixr_cmd_data[i] = r_write_data[i];
    3361 
    3362         r_write_fsm = WRITE_IDLE;
     3361    case WRITE_BC_XRAM_REQ:   // Post a PUT request to IXR_CMD FSM
     3362    {
     3363        if( not r_write_to_ixr_cmd_req.read() )
     3364        {
     3365            r_write_to_ixr_cmd_req     = true;
     3366            r_write_to_ixr_cmd_put     = true;
     3367            r_write_to_ixr_cmd_index   = r_write_trt_index.read();
     3368            r_write_fsm = WRITE_IDLE;
    33633369
    33643370#if DEBUG_MEMC_WRITE
     
    33673373          << " WRITE_BC_XRAM_REQ> Post a put request to IXR_CMD FSM" << std::endl;
    33683374#endif
    3369       }
    3370       break;
     3375        }
     3376        break;
    33713377    }
    33723378  } // end switch r_write_fsm
     
    33763382  ///////////////////////////////////////////////////////////////////////
    33773383  // The IXR_CMD fsm controls the command packets to the XRAM :
    3378   // It handles requests from the READ, WRITE, CAS, XRAM_RSP FSMs
    3379   // with a round-robin priority.
     3384  // It handles requests from 5 FSMs with a round-robin priority:
     3385  //  READ > WRITE > CAS > XRAM_RSP > CONFIG
    33803386  //
    3381   // - It sends a single flit VCI read request to the XRAM in case of MISS
    3382   // posted by the READ, WRITE or CAS FSMs : the TRDID field contains
    3383   // the Transaction Tab index.
    3384   // The VCI response is a multi-flit packet : the N cells contain
    3385   // the N data words.
     3387  // - It sends a single flit VCI read to the XRAM in case of
     3388  //   GET request posted by the READ, WRITE or CAS FSMs.
     3389  // - It sends a multi-flit VCI write in case of PUT request posted by
     3390  //   the XRAM_RSP, WRITE, CAS, or CONFIG FSMs.
    33863391  //
    3387   // - It sends a multi-flit VCI write when the XRAM_RSP FSM, WRITE FSM
    3388   // or CAS FSM request to save a dirty line to the XRAM.
    3389   // The VCI response is a single flit packet.
     3392  // For each client, there is three steps:
     3393  // - IXR_CMD_*_IDLE : round-robin allocation to a client
     3394  // - IXR_CMD_*_TRT  : access to TRT for address and data
     3395  // - IXR_CMD_*_SEND : send the PUT or GET VCI command
     3396  //
     3397  // The address and data to be written (for a PUT) are stored in TRT.
     3398  // The trdid field contains always the TRT entry index.
    33903399  ////////////////////////////////////////////////////////////////////////
     3400
     3401//std::cout << std::endl << "ixr_cmd_fsm" << std::endl;
    33913402
    33923403  switch(r_ixr_cmd_fsm.read())
    33933404  {
    3394     ////////////////////////
     3405    ///////////////////////
    33953406    case IXR_CMD_READ_IDLE:
    33963407    {
    3397       if     (r_write_to_ixr_cmd_req)    r_ixr_cmd_fsm = IXR_CMD_WRITE;
    3398       else if(r_cas_to_ixr_cmd_req)      r_ixr_cmd_fsm = IXR_CMD_CAS;
    3399       else if(r_xram_rsp_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_XRAM;
    3400       else if(r_read_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_READ;
     3408      if     (r_write_to_ixr_cmd_req)      r_ixr_cmd_fsm = IXR_CMD_WRITE_TRT;
     3409      else if(r_cas_to_ixr_cmd_req)        r_ixr_cmd_fsm = IXR_CMD_CAS_TRT;
     3410      else if(r_xram_rsp_to_ixr_cmd_req)   r_ixr_cmd_fsm = IXR_CMD_XRAM_TRT;
     3411      else if(r_config_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_CONFIG_TRT;
     3412      else if(r_read_to_ixr_cmd_req)       r_ixr_cmd_fsm = IXR_CMD_READ_TRT;
    34013413      break;
    34023414    }
     
    34043416    case IXR_CMD_WRITE_IDLE:
    34053417    {
    3406       if     (r_cas_to_ixr_cmd_req)      r_ixr_cmd_fsm = IXR_CMD_CAS;
    3407       else if(r_xram_rsp_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_XRAM;
    3408       else if(r_read_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_READ;
    3409       else if(r_write_to_ixr_cmd_req)    r_ixr_cmd_fsm = IXR_CMD_WRITE;
     3418      if     (r_cas_to_ixr_cmd_req)        r_ixr_cmd_fsm = IXR_CMD_CAS_TRT;
     3419      else if(r_xram_rsp_to_ixr_cmd_req)   r_ixr_cmd_fsm = IXR_CMD_XRAM_TRT;
     3420      else if(r_config_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_CONFIG_TRT;
     3421      else if(r_read_to_ixr_cmd_req)       r_ixr_cmd_fsm = IXR_CMD_READ_TRT;
     3422      else if(r_write_to_ixr_cmd_req)      r_ixr_cmd_fsm = IXR_CMD_WRITE_TRT;
    34103423      break;
    34113424    }
     3425    //////////////////////
     3426    case IXR_CMD_CAS_IDLE:
     3427    {
     3428      if     (r_xram_rsp_to_ixr_cmd_req)   r_ixr_cmd_fsm = IXR_CMD_XRAM_TRT;
     3429      else if(r_config_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_CONFIG_TRT;
     3430      else if(r_read_to_ixr_cmd_req)       r_ixr_cmd_fsm = IXR_CMD_READ_TRT;
     3431      else if(r_write_to_ixr_cmd_req)      r_ixr_cmd_fsm = IXR_CMD_WRITE_TRT;
     3432      else if(r_cas_to_ixr_cmd_req)        r_ixr_cmd_fsm = IXR_CMD_CAS_TRT;
     3433      break;
     3434    }
     3435    ///////////////////////
     3436    case IXR_CMD_XRAM_IDLE:
     3437    {
     3438      if     (r_config_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_CONFIG_TRT;
     3439      else if(r_read_to_ixr_cmd_req)       r_ixr_cmd_fsm = IXR_CMD_READ_TRT;
     3440      else if(r_write_to_ixr_cmd_req)      r_ixr_cmd_fsm = IXR_CMD_WRITE_TRT;
     3441      else if(r_cas_to_ixr_cmd_req)        r_ixr_cmd_fsm = IXR_CMD_CAS_TRT;
     3442      else if(r_xram_rsp_to_ixr_cmd_req)   r_ixr_cmd_fsm = IXR_CMD_XRAM_TRT;
     3443      break;
     3444    }
     3445    /////////////////////////
     3446    case IXR_CMD_CONFIG_IDLE:
     3447    {
     3448      if     (r_read_to_ixr_cmd_req)       r_ixr_cmd_fsm = IXR_CMD_READ_TRT;
     3449      else if(r_write_to_ixr_cmd_req)      r_ixr_cmd_fsm = IXR_CMD_WRITE_TRT;
     3450      else if(r_cas_to_ixr_cmd_req)        r_ixr_cmd_fsm = IXR_CMD_CAS_TRT;
     3451      else if(r_xram_rsp_to_ixr_cmd_req)   r_ixr_cmd_fsm = IXR_CMD_XRAM_TRT;
     3452      else if(r_config_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_CONFIG_TRT;
     3453      break;
     3454    }
     3455
     3456    //////////////////////
     3457    case IXR_CMD_READ_TRT:       // access TRT for a GET
     3458    {
     3459        if ( r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_CMD )
     3460        {
     3461            TransactionTabEntry entry = m_trt.read( r_read_to_ixr_cmd_index.read() );
     3462            r_ixr_cmd_address = entry.nline * (m_words<<2);
     3463            r_ixr_cmd_trdid   = r_read_to_ixr_cmd_index.read();
     3464            r_ixr_cmd_get     = true;
     3465            r_ixr_cmd_word    = 0;
     3466            r_ixr_cmd_fsm     = IXR_CMD_READ_SEND;
     3467            for( size_t i=0 ; i<m_words ; i++ ) r_ixr_cmd_wdata[i] = entry.wdata[i];
     3468
     3469#if DEBUG_MEMC_IXR_CMD
     3470if(m_debug)
     3471std::cout << "  <MEMC " << name() << " IXR_CMD_READ_TRT> TRT access"
     3472          << " index = " << std::dec << r_read_to_ixr_cmd_index.read()
     3473          << " / address = " << std::hex << (entry.nline*(m_words<<2)) << std::endl;
     3474#endif
     3475        }
     3476        break;
     3477    }
     3478    ///////////////////////
     3479    case IXR_CMD_WRITE_TRT:       // access TRT for a PUT or a GET
     3480    {
     3481        if ( r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_CMD )
     3482        {
     3483            TransactionTabEntry entry = m_trt.read( r_write_to_ixr_cmd_index.read() );
     3484            r_ixr_cmd_address = entry.nline * (m_words<<2);
     3485            r_ixr_cmd_trdid   = r_write_to_ixr_cmd_index.read();
     3486            r_ixr_cmd_get     = entry.xram_read;
     3487            r_ixr_cmd_word    = 0;
     3488            r_ixr_cmd_fsm     = IXR_CMD_WRITE_SEND;
     3489            for( size_t i=0 ; i<m_words ; i++ ) r_ixr_cmd_wdata[i] = entry.wdata[i];
     3490
     3491#if DEBUG_MEMC_IXR_CMD
     3492if(m_debug)
     3493std::cout << "  <MEMC " << name() << " IXR_CMD_WRITE_TRT> TRT access"
     3494          << " index = " << std::dec << r_write_to_ixr_cmd_index.read()
     3495          << " / address = " << std::hex << (entry.nline*(m_words<<2)) << std::endl;
     3496#endif
     3497        }
     3498        break;
     3499    }
     3500    /////////////////////
     3501    case IXR_CMD_CAS_TRT:       // access TRT for a PUT or a GET
     3502    {
     3503        if ( r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_CMD )
     3504        {
     3505            TransactionTabEntry entry = m_trt.read( r_cas_to_ixr_cmd_index.read() );
     3506            r_ixr_cmd_address = entry.nline * (m_words<<2);
     3507            r_ixr_cmd_trdid   = r_cas_to_ixr_cmd_index.read();
     3508            r_ixr_cmd_get     = entry.xram_read;
     3509            r_ixr_cmd_word    = 0;
     3510            r_ixr_cmd_fsm     = IXR_CMD_CAS_SEND;
     3511            for( size_t i=0 ; i<m_words ; i++ ) r_ixr_cmd_wdata[i] = entry.wdata[i];
     3512
     3513#if DEBUG_MEMC_IXR_CMD
     3514if(m_debug)
     3515std::cout << "  <MEMC " << name() << " IXR_CMD_CAS_TRT> TRT access"
     3516          << " index = " << std::dec << r_cas_to_ixr_cmd_index.read()
     3517          << " / address = " << std::hex << (entry.nline*(m_words<<2)) << std::endl;
     3518#endif
     3519        }
     3520        break;
     3521    }
     3522    //////////////////////
     3523    case IXR_CMD_XRAM_TRT:       // access TRT for a PUT
     3524    {
     3525        if ( r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_CMD )
     3526        {
     3527            TransactionTabEntry entry = m_trt.read( r_xram_rsp_to_ixr_cmd_index.read() );
     3528            r_ixr_cmd_address = entry.nline * (m_words<<2);
     3529            r_ixr_cmd_trdid   = r_xram_rsp_to_ixr_cmd_index.read();
     3530            r_ixr_cmd_get     = false;
     3531            r_ixr_cmd_word    = 0;
     3532            r_ixr_cmd_fsm     = IXR_CMD_XRAM_SEND;
     3533            for( size_t i=0 ; i<m_words ; i++ ) r_ixr_cmd_wdata[i] = entry.wdata[i];
     3534
     3535#if DEBUG_MEMC_IXR_CMD
     3536if(m_debug)
     3537std::cout << "  <MEMC " << name() << " IXR_CMD_XRAM_TRT> TRT access"
     3538          << " index = " << std::dec << r_xram_rsp_to_ixr_cmd_index.read()
     3539          << " / address = " << std::hex << (entry.nline*(m_words<<2)) << std::endl;
     3540#endif
     3541        }
     3542        break;
     3543    }
    34123544    ////////////////////////
    3413     case IXR_CMD_CAS_IDLE:
    3414     {
    3415       if     (r_xram_rsp_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_XRAM;
    3416       else if(r_read_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_READ;
    3417       else if(r_write_to_ixr_cmd_req)    r_ixr_cmd_fsm = IXR_CMD_WRITE;
    3418       else if(r_cas_to_ixr_cmd_req)      r_ixr_cmd_fsm = IXR_CMD_CAS;
    3419       break;
     3545    case IXR_CMD_CONFIG_TRT:       // access TRT for a PUT
     3546    {
     3547        if ( r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_CMD )
     3548        {
     3549            TransactionTabEntry entry = m_trt.read( r_config_to_ixr_cmd_index.read() );
     3550            r_ixr_cmd_address = entry.nline * (m_words<<2);
     3551            r_ixr_cmd_trdid   = r_config_to_ixr_cmd_index.read();
     3552            r_ixr_cmd_get     = false;
     3553            r_ixr_cmd_word    = 0;
     3554            r_ixr_cmd_fsm     = IXR_CMD_CONFIG_SEND;
     3555            for( size_t i=0 ; i<m_words ; i++ ) r_ixr_cmd_wdata[i] = entry.wdata[i];
     3556
     3557#if DEBUG_MEMC_IXR_CMD
     3558if(m_debug)
     3559std::cout << "  <MEMC " << name() << " IXR_CMD_CONFIG_TRT> TRT access"
     3560          << " index = " << std::dec << r_config_to_ixr_cmd_index.read()
     3561          << " / address = " << std::hex << (entry.nline*(m_words<<2)) << std::endl;
     3562#endif
     3563        }
     3564        break;
     3565    }
     3566
     3567    ///////////////////////
     3568    case IXR_CMD_READ_SEND:      // send a get from READ FSM
     3569    {
     3570        if(p_vci_ixr.cmdack)
     3571        {
     3572            r_ixr_cmd_fsm         = IXR_CMD_READ_IDLE;
     3573            r_read_to_ixr_cmd_req = false;
     3574
     3575#if DEBUG_MEMC_IXR_CMD
     3576if(m_debug)
     3577std::cout << "  <MEMC " << name() << " IXR_CMD_READ_SEND> GET request:" << std::hex
     3578          << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2) << std::endl;
     3579#endif
     3580        }
     3581        break;
    34203582    }
    34213583    ////////////////////////
    3422     case IXR_CMD_XRAM_IDLE:
    3423     {
    3424       if     (r_read_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_READ;
    3425       else if(r_write_to_ixr_cmd_req)    r_ixr_cmd_fsm = IXR_CMD_WRITE;
    3426       else if(r_cas_to_ixr_cmd_req)      r_ixr_cmd_fsm = IXR_CMD_CAS;
    3427       else if(r_xram_rsp_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_XRAM;
    3428       break;
    3429     }
    3430     //////////////////       // send a get from READ FSM
    3431     case IXR_CMD_READ:
    3432     {
    3433       if(p_vci_ixr.cmdack)
    3434       {
    3435         r_ixr_cmd_fsm = IXR_CMD_READ_IDLE;
    3436         r_read_to_ixr_cmd_req = false;
     3584    case IXR_CMD_WRITE_SEND:     // send a put or get from WRITE FSM
     3585    {
     3586        if(p_vci_ixr.cmdack)
     3587        {
     3588            if(r_write_to_ixr_cmd_put.read())   // PUT
     3589            {
     3590                if(r_ixr_cmd_word.read() == (m_words - 2))
     3591                {
     3592                    r_ixr_cmd_fsm          = IXR_CMD_WRITE_IDLE;
     3593                    r_write_to_ixr_cmd_req = false;
     3594                }
     3595                else
     3596                {
     3597                    r_ixr_cmd_word = r_ixr_cmd_word.read() + 2;
     3598                }
    34373599
    34383600#if DEBUG_MEMC_IXR_CMD
    34393601if(m_debug)
    3440 std::cout << "  <MEMC " << name() << " IXR_CMD_READ>"
    3441           << " Send a get request to xram / address = " << std::hex
    3442           << (addr_t)(r_read_to_ixr_cmd_nline.read()*m_words*4) << std::endl;
    3443 #endif
    3444       }
    3445       break;
    3446     }
    3447     ///////////////////
    3448     case IXR_CMD_WRITE:     // send a put or get from WRITE FSM
    3449     {
    3450       if(p_vci_ixr.cmdack)
    3451       {
    3452         if(r_write_to_ixr_cmd_write.read())   // PUT
    3453         {
    3454           if(r_ixr_cmd_cpt.read() == (m_words - 2))
    3455           {
    3456             r_ixr_cmd_cpt = 0;
    3457             r_ixr_cmd_fsm = IXR_CMD_WRITE_IDLE;
    3458             r_write_to_ixr_cmd_req = false;
    3459           }
    3460           else
    3461           {
    3462             r_ixr_cmd_cpt = r_ixr_cmd_cpt + 2;
    3463           }
     3602std::cout << "  <MEMC " << name() << " IXR_CMD_WRITE_SEND> PUT request:" << std::hex
     3603          << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2) << std::endl;
     3604#endif
     3605            }
     3606            else                                  // GET
     3607            {
     3608                r_ixr_cmd_fsm          = IXR_CMD_WRITE_IDLE;
     3609                r_write_to_ixr_cmd_req = false;
    34643610
    34653611#if DEBUG_MEMC_IXR_CMD
    34663612if(m_debug)
    3467 std::cout << "  <MEMC " << name() << " IXR_CMD_WRITE>"
    3468           << " Send a put request to xram / address = " << std::hex
    3469           << (addr_t)((r_write_to_ixr_cmd_nline.read() * m_words +
    3470                       r_ixr_cmd_cpt.read()) * 4 ) << std::endl;
    3471 #endif
    3472         }
    3473         else                                  // GET
    3474         {
    3475           r_ixr_cmd_fsm = IXR_CMD_WRITE_IDLE;
    3476           r_write_to_ixr_cmd_req = false;
     3613std::cout << "  <MEMC " << name() << " IXR_CMD_WRITE_SEND> GET request:" << std::hex
     3614          << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2) << std::endl;
     3615#endif
     3616            }
     3617        }
     3618        break;
     3619    }
     3620    //////////////////////
     3621    case IXR_CMD_CAS_SEND:      // send a put or get command from CAS FSM
     3622    {
     3623        if(p_vci_ixr.cmdack)
     3624        {
     3625            if(r_cas_to_ixr_cmd_put.read()) // PUT
     3626            {
     3627                if(r_ixr_cmd_word.read() == (m_words - 2))
     3628                {
     3629                    r_ixr_cmd_fsm        = IXR_CMD_CAS_IDLE;
     3630                    r_cas_to_ixr_cmd_req = false;
     3631                }
     3632                else
     3633                {
     3634                    r_ixr_cmd_word = r_ixr_cmd_word.read() + 2;
     3635                }
    34773636
    34783637#if DEBUG_MEMC_IXR_CMD
    34793638if(m_debug)
    3480 std::cout << "  <MEMC " << name() << " IXR_CMD_WRITE>"
    3481           << " Send a get request to xram / address = " << std::hex
    3482           << (addr_t)(r_write_to_ixr_cmd_nline.read()*m_words*4) << std::endl;
    3483 #endif
    3484         }
    3485       }
    3486       break;
    3487     }
    3488     /////////////////
    3489     case IXR_CMD_CAS:      // send a put or get command from CAS FSM
    3490     {
    3491       if(p_vci_ixr.cmdack)
    3492       {
    3493         if(r_cas_to_ixr_cmd_write.read()) // PUT
    3494         {
    3495           if(r_ixr_cmd_cpt.read() == (m_words - 2))
    3496           {
    3497             r_ixr_cmd_cpt = 0;
    3498             r_ixr_cmd_fsm = IXR_CMD_CAS_IDLE;
    3499             r_cas_to_ixr_cmd_req = false;
    3500           }
    3501           else
    3502           {
    3503             r_ixr_cmd_cpt = r_ixr_cmd_cpt + 2;
    3504           }
     3639std::cout << "  <MEMC " << name() << " IXR_CMD_CAS_SEND> PUT request:" << std::hex
     3640          << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2) << std::endl;
     3641#endif
     3642            }
     3643            else                            // GET
     3644            {
     3645                r_ixr_cmd_fsm        = IXR_CMD_CAS_IDLE;
     3646                r_cas_to_ixr_cmd_req = false;
    35053647
    35063648#if DEBUG_MEMC_IXR_CMD
    35073649if(m_debug)
    3508 std::cout << "  <MEMC " << name() << " IXR_CMD_CAS>"
    3509           << " Send a put request to xram / address = " << std::hex
    3510           << (addr_t)( (r_cas_to_ixr_cmd_nline.read() * m_words +
    3511                       r_ixr_cmd_cpt.read()) * 4 ) << std::endl;
    3512 #endif
    3513         }
    3514         else                            // GET
    3515         {
    3516           r_ixr_cmd_fsm = IXR_CMD_CAS_IDLE;
    3517           r_cas_to_ixr_cmd_req = false;
     3650std::cout << "  <MEMC " << name() << " IXR_CMD_CAS_SEND> GET request:" << std::hex
     3651          << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2) << std::endl;
     3652#endif
     3653            }
     3654        }
     3655        break;
     3656    }
     3657    ///////////////////////
     3658    case IXR_CMD_XRAM_SEND:     // send a put from XRAM_RSP FSM
     3659    {
     3660        if(p_vci_ixr.cmdack)
     3661        {
     3662            if(r_ixr_cmd_word.read() == (m_words - 2))
     3663            {
     3664                r_ixr_cmd_fsm = IXR_CMD_XRAM_IDLE;
     3665                r_xram_rsp_to_ixr_cmd_req = false;
     3666            }
     3667            else
     3668            {
     3669                r_ixr_cmd_word = r_ixr_cmd_word.read() + 2;
     3670            }
    35183671
    35193672#if DEBUG_MEMC_IXR_CMD
    35203673if(m_debug)
    3521 std::cout << "  <MEMC " << name() << " IXR_CMD_CAS>"
    3522           << " Send a get request to xram / address = " << std::hex
    3523           << (addr_t)(r_cas_to_ixr_cmd_nline.read()*m_words*4) << std::endl;
    3524 #endif
    3525         }
    3526       }
    3527       break;
    3528     }
    3529     //////////////////
    3530     case IXR_CMD_XRAM:     // send a put from XRAM_RSP FSM
    3531     {
    3532       if(p_vci_ixr.cmdack)
    3533       {
    3534         if(r_ixr_cmd_cpt.read() == (m_words - 2))
    3535         {
    3536           r_ixr_cmd_cpt = 0;
    3537           r_ixr_cmd_fsm = IXR_CMD_XRAM_IDLE;
    3538           r_xram_rsp_to_ixr_cmd_req = false;
    3539         }
    3540         else
    3541         {
    3542           r_ixr_cmd_cpt = r_ixr_cmd_cpt + 2;
    3543         }
     3674std::cout << "  <MEMC " << name() << " IXR_CMD_XRAM_SEND> PUT request:" << std::hex
     3675          << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2) << std::endl;
     3676#endif
     3677        }
     3678        break;
     3679    }
     3680    /////////////////////////
     3681    case IXR_CMD_CONFIG_SEND:     // send a put from CONFIG FSM
     3682    {
     3683        if(p_vci_ixr.cmdack)
     3684        {
     3685            if(r_ixr_cmd_word.read() == (m_words - 2))
     3686            {
     3687                r_ixr_cmd_fsm = IXR_CMD_CONFIG_IDLE;
     3688                r_config_to_ixr_cmd_req = false;
     3689            }
     3690            else
     3691            {
     3692                r_ixr_cmd_word = r_ixr_cmd_word.read() + 2;
     3693            }
    35443694
    35453695#if DEBUG_MEMC_IXR_CMD
    35463696if(m_debug)
    3547 std::cout << "  <MEMC " << name() << " IXR_CMD_XRAM>"
    3548           << " Send a put request to xram / address = " << std::hex
    3549           << (addr_t)( (r_xram_rsp_to_ixr_cmd_nline.read() * m_words +
    3550                        r_ixr_cmd_cpt.read()) * 4 ) << std::endl;
    3551 #endif
    3552       }
    3553       break;
    3554     }
    3555 
     3697std::cout << "  <MEMC " << name() << " IXR_CMD_CONFIG_SEND> PUT request:" << std::hex
     3698          << " address = " << r_ixr_cmd_address.read() + (r_ixr_cmd_word.read()<<2) << std::endl;
     3699#endif
     3700        }
     3701        break;
     3702    }
    35563703  } // end switch r_ixr_cmd_fsm
    35573704
     
    35603707  ////////////////////////////////////////////////////////////////////////////
    35613708  // The IXR_RSP FSM receives the response packets from the XRAM,
    3562   // for both put transaction, and get transaction.
     3709  // for both PUT transaction, and GET transaction.
    35633710  //
    3564   // - A response to a put request is a single-cell VCI packet.
    3565   // The Transaction Tab index is contained in the RTRDID field.
     3711  // - A response to a PUT request is a single-cell VCI packet.
     3712  // The TRT index is contained in the RTRDID field.
    35663713  // The FSM takes the lock protecting the TRT, and the corresponding
    3567   // entry is erased.
     3714  // entry is erased. If an acknowledge was required (in case of software SYNC)
     3715  // the r_config_rsp_lines counter is decremented. 
    35683716  //
    3569   // - A response to a get request is a multi-cell VCI packet.
    3570   // The Transaction Tab index is contained in the RTRDID field.
     3717  // - A response to a GET request is a multi-cell VCI packet.
     3718  // The TRT index is contained in the RTRDID field.
    35713719  // The N cells contain the N words of the cache line in the RDATA field.
    35723720  // The FSM takes the lock protecting the TRT to store the line in the TRT
    35733721  // (taking into account the write requests already stored in the TRT).
    3574   // When the line is completely written, the corresponding rok signal is set.
     3722  // When the line is completely written, the r_ixr_rsp_to_xram_rsp_rok[index] 
     3723  // signal is set to inform the XRAM_RSP FSM.
    35753724  ///////////////////////////////////////////////////////////////////////////////
     3725
     3726//std::cout << std::endl << "ixr_rsp_fsm" << std::endl;
    35763727
    35773728  switch(r_ixr_rsp_fsm.read())
    35783729  {
    3579     //////////////////
    3580     case IXR_RSP_IDLE:  // test transaction type: PUT/GET
    3581     {
    3582       if(p_vci_ixr.rspval.read())
    3583       {
    3584         r_ixr_rsp_cpt   = 0;
    3585         r_ixr_rsp_trt_index = p_vci_ixr.rtrdid.read();
    3586         if(p_vci_ixr.reop.read() and !(p_vci_ixr.rerror.read() &0x1))   // PUT transaction
    3587         {
    3588           r_ixr_rsp_fsm = IXR_RSP_ACK;
     3730      //////////////////
     3731      case IXR_RSP_IDLE:  // test transaction type: PUT/GET
     3732      {
     3733          if(p_vci_ixr.rspval.read())
     3734          {
     3735              r_ixr_rsp_cpt       = 0;
     3736              r_ixr_rsp_trt_index = p_vci_ixr.rtrdid.read();
     3737
     3738              assert( ((p_vci_ixr.rerror.read() & 0x1) == 0) and
     3739              "MEMC ERROR in IXR_RSP state: XRAM response error !");
     3740
     3741              if(p_vci_ixr.reop.read())   // PUT
     3742              {
     3743                  r_ixr_rsp_fsm = IXR_RSP_TRT_ERASE;
    35893744
    35903745#if DEBUG_MEMC_IXR_RSP
     
    35933748          << " IXR_RSP_IDLE> Response from XRAM to a put transaction" << std::endl;
    35943749#endif
    3595         }
    3596         else                                                         // GET transaction
    3597         {
    3598           r_ixr_rsp_fsm = IXR_RSP_TRT_READ;
     3750              }
     3751              else                       // GET
     3752              {
     3753                  r_ixr_rsp_fsm = IXR_RSP_TRT_READ;
    35993754
    36003755#if DEBUG_MEMC_IXR_RSP
     
    36033758          << " IXR_RSP_IDLE> Response from XRAM to a get transaction" << std::endl;
    36043759#endif
    3605         }
    3606       }
    3607       break;
    3608     }
    3609     /////////////////
    3610     case IXR_RSP_ACK:        // Aknowledge the VCI response for a PUT
    3611     {
    3612       if(p_vci_ixr.rspval.read()) r_ixr_rsp_fsm = IXR_RSP_TRT_ERASE;
    3613 
    3614 #if DEBUG_MEMC_IXR_RSP
    3615 if(m_debug)
    3616 std::cout << "  <MEMC " << name() << " IXR_RSP_ACK>" << std::endl;
    3617 #endif
    3618       break;
    3619     }
    3620     ////////////////////////
    3621     case IXR_RSP_TRT_ERASE:   // erase the entry in the TRT
    3622     {
    3623       if(r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP)
    3624       {
    3625         m_trt.erase(r_ixr_rsp_trt_index.read());
    3626         r_ixr_rsp_fsm = IXR_RSP_IDLE;
     3760              }
     3761          }
     3762          break;
     3763      }
     3764      ////////////////////////
     3765      case IXR_RSP_TRT_ERASE:   // erase the entry in the TRT
     3766                                // decrease the line counter if config request
     3767      {
     3768          if(r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP)
     3769          {
     3770              size_t  index = r_ixr_rsp_trt_index.read();
     3771              if (m_trt.is_config(index) ) r_config_rsp_lines = r_config_rsp_lines.read() - 1;
     3772              m_trt.erase(index);
     3773              r_ixr_rsp_fsm = IXR_RSP_IDLE;
    36273774
    36283775#if DEBUG_MEMC_IXR_RSP
     
    36313778          << r_ixr_rsp_trt_index.read() << std::endl;
    36323779#endif
    3633       }
    3634       break;
    3635     }
    3636     //////////////////////
    3637     case IXR_RSP_TRT_READ:    // write a 64 bits data in the TRT
    3638     {
    3639       if((r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP) and  p_vci_ixr.rspval)
    3640       {
    3641         size_t      index    = r_ixr_rsp_trt_index.read();
    3642         bool        eop      = p_vci_ixr.reop.read();
    3643         wide_data_t data     = p_vci_ixr.rdata.read();
    3644         bool        error    = ((p_vci_ixr.rerror.read() & 0x1) == 1);
    3645 
    3646         assert(((eop == (r_ixr_rsp_cpt.read() == (m_words-2))) or p_vci_ixr.rerror.read())
    3647                and "Error in VCI_MEM_CACHE : invalid length for a response from XRAM");
    3648 
    3649         m_trt.write_rsp( index,
    3650                          r_ixr_rsp_cpt.read(),
    3651                          data,
    3652                          error);
    3653 
    3654         r_ixr_rsp_cpt = r_ixr_rsp_cpt.read() + 2;
    3655 
    3656         if(eop)
    3657         {
    3658           r_ixr_rsp_to_xram_rsp_rok[r_ixr_rsp_trt_index.read()]=true;
    3659           r_ixr_rsp_fsm = IXR_RSP_IDLE;
    3660         }
     3780          }
     3781          break;
     3782      }
     3783      //////////////////////
     3784      case IXR_RSP_TRT_READ:    // write a 64 bits data word in TRT
     3785      {
     3786          if((r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP) and  p_vci_ixr.rspval)
     3787          {
     3788              size_t      index    = r_ixr_rsp_trt_index.read();
     3789              size_t      word     = r_ixr_rsp_cpt.read();
     3790              bool        eop      = p_vci_ixr.reop.read();
     3791              wide_data_t data     = p_vci_ixr.rdata.read();
     3792              bool        error    = ((p_vci_ixr.rerror.read() & 0x1) == 1);
     3793
     3794              assert(((eop == (word == (m_words-2))) or error) and
     3795              "MEMC ERROR in IXR_RSP_TRT_READ state : invalid response from XRAM");
     3796
     3797              m_trt.write_rsp( index,
     3798                               word,
     3799                               data );
     3800
     3801              r_ixr_rsp_cpt = word + 2;
     3802
     3803              if( eop )
     3804              {
     3805                  r_ixr_rsp_to_xram_rsp_rok[r_ixr_rsp_trt_index.read()] = true;
     3806                  r_ixr_rsp_fsm = IXR_RSP_IDLE;
     3807              }
    36613808
    36623809#if DEBUG_MEMC_IXR_RSP
    36633810if(m_debug)
    3664 std::cout << "  <MEMC " << name() << " IXR_RSP_TRT_READ> Writing a word in TRT : "
     3811std::cout << "  <MEMC " << name() << " IXR_RSP_TRT_READ> Writing 2 words in TRT : "
    36653812          << " index = " << std::dec << index
    3666           << " / word = " << r_ixr_rsp_cpt.read()
     3813          << " / word = " << word
    36673814          << " / data = " << std::hex << data << std::endl;
    36683815#endif
    3669       }
    3670       break;
    3671     }
     3816          }
     3817          break;
     3818      }
    36723819  } // end swich r_ixr_rsp_fsm
    36733820
     
    36753822  //                XRAM_RSP FSM
    36763823  ////////////////////////////////////////////////////////////////////////////
    3677   // The XRAM_RSP FSM handles the incoming cache lines from the XRAM.
     3824  // The XRAM_RSP FSM handles the incoming cache lines after an XRAM GET.
    36783825  // The cache line has been written in the TRT by the IXR_CMD_FSM.
    36793826  // As the IXR_RSP FSM and the XRAM_RSP FSM are running in parallel,
    3680   // there is as many flip-flops r_ixr_rsp_to_xram_rsp_rok[i]
    3681   // as the number of entries in the TRT, that are handled with
    3682   // a round-robin priority...
     3827  // there is as many flip-flops r_ixr_rsp_to_xram_rsp_rok[i] as the number
     3828  // of entries in the TRT, that are handled with a round-robin priority...
    36833829  //
    3684   // When a response is available, the corresponding TRT entry
    3685   // is copied in a local buffer to be written in the cache.
    3686   // The FSM takes the lock protecting the TRT, and the lock protecting the DIR.
    3687   // It selects a cache slot and writes the line in the cache.
     3830  // The FSM takes the lock protecting TRT, and the lock protecting DIR.
     3831  // The selected TRT entry is copied in the local buffer r_xram_rsp_trt_buf.
     3832  // It selects a cache slot and save the victim line in another local buffer
     3833  // r_xram_rsp_victim_***.
     3834  // It writes the line extracted from TRT in the cache.
    36883835  // If it was a read MISS, the XRAM_RSP FSM send a request to the TGT_RSP
    36893836  // FSM to return the cache line to the registered processor.
     
    36953842  ///////////////////////////////////////////////////////////////////////////////
    36963843
     3844//std::cout << std::endl << "xram_rsp_fsm" << std::endl;
     3845
    36973846  switch(r_xram_rsp_fsm.read())
    36983847  {
     
    37003849    case XRAM_RSP_IDLE: // scan the XRAM responses / select a TRT index (round robin)
    37013850    {
    3702       size_t ptr   = r_xram_rsp_trt_index.read();
    3703       size_t lines = m_trt_lines;
    3704       for(size_t i=0 ; i<lines ; i++)
    3705       {
    3706         size_t index = (i+ptr+1) %lines;
    3707         if(r_ixr_rsp_to_xram_rsp_rok[index])
    3708         {
    3709           r_xram_rsp_trt_index             = index;
    3710           r_ixr_rsp_to_xram_rsp_rok[index] = false;
    3711           r_xram_rsp_fsm                   = XRAM_RSP_DIR_LOCK;
     3851        size_t old   = r_xram_rsp_trt_index.read();
     3852        size_t lines = m_trt_lines;
     3853        for(size_t i=0 ; i<lines ; i++)
     3854        {
     3855            size_t index = (i+old+1) %lines;
     3856            if(r_ixr_rsp_to_xram_rsp_rok[index])
     3857            {
     3858                r_xram_rsp_trt_index             = index;
     3859                r_ixr_rsp_to_xram_rsp_rok[index] = false;
     3860                r_xram_rsp_fsm                   = XRAM_RSP_DIR_LOCK;
    37123861
    37133862#if DEBUG_MEMC_XRAM_RSP
     
    37173866          << " index = " << std::dec << index << std::endl;
    37183867#endif
    3719           break;
    3720         }
    3721       }
    3722       break;
     3868                break;
     3869            }
     3870        }
     3871        break;
    37233872    }
    37243873    ///////////////////////
     
    37263875                            // Copy the TRT entry in a local buffer
    37273876    {
    3728       if((r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP) and
    3729           (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP))
    3730       {
    3731         // copy the TRT entry in the r_xram_rsp_trt_buf local buffer
    3732         size_t  index = r_xram_rsp_trt_index.read();
    3733         r_xram_rsp_trt_buf.copy( m_trt.read(index) );
    3734 
    3735         r_xram_rsp_fsm = XRAM_RSP_TRT_COPY;
     3877        if( (r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP) and
     3878            (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP) )
     3879        {
     3880            // copy the TRT entry in the r_xram_rsp_trt_buf local buffer
     3881            size_t  index = r_xram_rsp_trt_index.read();
     3882            r_xram_rsp_trt_buf.copy( m_trt.read(index) );
     3883            r_xram_rsp_fsm = XRAM_RSP_TRT_COPY;
    37363884
    37373885#if DEBUG_MEMC_XRAM_RSP
     
    37403888          << " Get access to DIR and TRT" << std::endl;
    37413889#endif
    3742       }
    3743       break;
     3890        }
     3891        break;
    37443892    }
    37453893    ///////////////////////
     
    37473895                            // and copy it in a local buffer
    37483896    {
    3749       if ( (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP) and
    3750            (r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP) )
    3751       {
     3897        assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP) and
     3898        "MEMC ERROR in XRAM_RSP_TRT_COPY state: Bad DIR allocation");
     3899
     3900        assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP) and
     3901        "MEMC ERROR in XRAM_RSP_TRT_COPY state: Bad TRT allocation");
     3902
    37523903        // selects & extracts a victim line from cache
    37533904        size_t way = 0;
     
    37583909        bool inval = (victim.count and victim.valid) ;
    37593910
    3760         // copy the victim line in a local buffer
     3911        // copy the victim line in a local buffer (both data dir)
    37613912        m_cache_data.read_line(way, set, r_xram_rsp_victim_data);
    37623913
    37633914        r_xram_rsp_victim_copy      = victim.owner.srcid;
    3764 
    3765 #if L1_MULTI_CACHE
    3766         r_xram_rsp_victim_copy_cache= victim.owner.cache_id;
    3767 #endif
    37683915        r_xram_rsp_victim_copy_inst = victim.owner.inst;
    37693916        r_xram_rsp_victim_count     = victim.count;
     
    37763923        r_xram_rsp_victim_dirty     = victim.dirty;
    37773924
    3778         if(!r_xram_rsp_trt_buf.rerror)
    3779         {
    3780           r_xram_rsp_fsm = XRAM_RSP_INVAL_LOCK;
    3781         }
    3782         else
    3783         {
    3784           r_xram_rsp_fsm = XRAM_RSP_ERROR_ERASE;
    3785         }
     3925        if( not r_xram_rsp_trt_buf.rerror ) r_xram_rsp_fsm = XRAM_RSP_IVT_LOCK;
     3926        else                                r_xram_rsp_fsm = XRAM_RSP_ERROR_ERASE;
    37863927
    37873928#if DEBUG_MEMC_XRAM_RSP
    37883929if(m_debug)
    37893930std::cout << "  <MEMC " << name() << " XRAM_RSP_TRT_COPY>"
    3790           << " Select a slot: "
     3931          << " Select a victim slot: "
    37913932          << " way = " << std::dec << way
    37923933          << " / set = " << set
    37933934          << " / inval_required = " << inval << std::endl;
    37943935#endif
    3795       }
    3796       else
    3797       {
    3798         std::cout << "VCI_MEM_CACHE ERROR " << name() << " XRAM_RSP_TRT_COPY"
    3799                   << " bad TRT or DIR allocation" << std::endl;
    3800         exit(0);
    3801       }
    3802       break;
    3803     }
    3804     /////////////////////////
    3805     case XRAM_RSP_INVAL_LOCK: // Take the IVT lock to check a possible pending inval
    3806     {
    3807       if(r_alloc_ivt_fsm == ALLOC_IVT_XRAM_RSP)
    3808       {
    3809         size_t index = 0;
    3810         if(m_ivt.search_inval(r_xram_rsp_trt_buf.nline, index))  // pending inval
    3811         {
    3812           r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT;
     3936        break;
     3937    }
     3938    ///////////////////////
     3939    case XRAM_RSP_IVT_LOCK:   // Keep DIR and TRT locks and take the IVT lock
     3940                              // to check a possible pending inval
     3941    {
     3942        assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP) and
     3943        "MEMC ERROR in XRAM_RSP_IVT_LOCK state: Bad DIR allocation");
     3944
     3945        assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP) and
     3946        "MEMC ERROR in XRAM_RSP_IVT_LOCK state: Bad TRT allocation");
     3947
     3948        if(r_alloc_ivt_fsm == ALLOC_IVT_XRAM_RSP)
     3949        {
     3950            size_t index = 0;
     3951            if(m_ivt.search_inval(r_xram_rsp_trt_buf.nline, index))  // pending inval
     3952            {
     3953                r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT;
    38133954
    38143955#if DEBUG_MEMC_XRAM_RSP
    38153956if(m_debug)
    3816 std::cout << "  <MEMC " << name() << " XRAM_RSP_INVAL_LOCK>"
     3957std::cout << "  <MEMC " << name() << " XRAM_RSP_IVT_LOCK>"
    38173958          << " Get acces to IVT, but line invalidation registered"
    3818           << " / nline = " << std::hex << r_xram_rsp_trt_buf.nline
     3959          << " / address = " << std::hex << r_xram_rsp_trt_buf.nline*m_words*4
    38193960          << " / index = " << std::dec << index << std::endl;
    38203961#endif
    38213962
    3822         }
    3823         else if(m_ivt.is_full() and r_xram_rsp_victim_inval.read()) // IVT full
    3824         {
    3825           r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT;
     3963            }
     3964            else if(m_ivt.is_full() and r_xram_rsp_victim_inval.read()) // IVT full
     3965            {
     3966                r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT;
    38263967
    38273968#if DEBUG_MEMC_XRAM_RSP
    38283969if(m_debug)
    3829 std::cout << "  <MEMC " << name() << " XRAM_RSP_INVAL_LOCK>"
     3970std::cout << "  <MEMC " << name() << " XRAM_RSP_IVT_LOCK>"
    38303971          << " Get acces to IVT, but inval required and IVT full" << std::endl;
    38313972#endif
    3832         }
    3833         else
    3834         {
    3835           r_xram_rsp_fsm = XRAM_RSP_DIR_UPDT;
     3973            }
     3974            else
     3975            {
     3976                r_xram_rsp_fsm = XRAM_RSP_DIR_UPDT;
    38363977
    38373978#if DEBUG_MEMC_XRAM_RSP
    38383979if(m_debug)
    3839 std::cout << "  <MEMC " << name() << " XRAM_RSP_INVAL_LOCK>"
    3840           << " Get acces to IVT" << std::endl;
    3841 #endif
    3842         }
    3843       }
    3844       break;
     3980std::cout << "  <MEMC " << name() << " XRAM_RSP_IVT_LOCK>"
     3981          << " Get acces to IVT / no pending inval request" << std::endl;
     3982#endif
     3983            }
     3984        }
     3985        break;
    38453986    }
    38463987    /////////////////////////
     
    38533994          << " Release all locks and retry" << std::endl;
    38543995#endif
    3855       r_xram_rsp_fsm = XRAM_RSP_DIR_LOCK;
    3856       break;
     3996        r_xram_rsp_fsm = XRAM_RSP_DIR_LOCK;
     3997        break;
    38573998    }
    38583999    ///////////////////////
    3859     case XRAM_RSP_DIR_UPDT:   // updates the cache (both data & directory)
    3860                               // and possibly set an inval request in IVT
    3861     {
    3862       // check if this is an instruction read, this means pktid is either
    3863       // TYPE_READ_INS_UNC   0bX010 with TSAR encoding
    3864       // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
    3865       bool inst_read = (r_xram_rsp_trt_buf.pktid & 0x2) and r_xram_rsp_trt_buf.proc_read;
    3866 
    3867       // check if this is a cached read, this means pktid is either
    3868       // TYPE_READ_DATA_MISS 0bX001 with TSAR encoding
    3869       // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
    3870       bool cached_read = (r_xram_rsp_trt_buf.pktid & 0x1) and r_xram_rsp_trt_buf.proc_read;
    3871 
    3872       bool dirty = false;
    3873 
    3874       // update cache data
    3875       size_t set   = r_xram_rsp_victim_set.read();
    3876       size_t way   = r_xram_rsp_victim_way.read();
    3877       for(size_t word=0; word<m_words ; word++)
    3878       {
    3879         m_cache_data.write(way, set, word, r_xram_rsp_trt_buf.wdata[word]);
    3880 
    3881         dirty = dirty or (r_xram_rsp_trt_buf.wdata_be[word] != 0);
    3882 
    3883         if(m_monitor_ok)
    3884         {
    3885           addr_t address = r_xram_rsp_trt_buf.nline<<6 | word<<2;
    3886           check_monitor( address, r_xram_rsp_trt_buf.wdata[word], false);
    3887         }
    3888       }
    3889 
    3890       // update cache directory
    3891       DirectoryEntry entry;
    3892       entry.valid   = true;
    3893       entry.is_cnt  = false;
    3894       entry.lock    = false;
    3895       entry.dirty   = dirty;
    3896       entry.tag     = r_xram_rsp_trt_buf.nline / m_sets;
    3897       entry.ptr     = 0;
    3898       if(cached_read)
    3899       {
    3900         entry.owner.srcid   = r_xram_rsp_trt_buf.srcid;
    3901 #if L1_MULTI_CACHE
    3902         entry.owner.cache_id= r_xram_rsp_trt_buf.pktid;
    3903 #endif
    3904         entry.owner.inst    = inst_read;
    3905         entry.count         = 1;
    3906       }
    3907       else
    3908       {
    3909         entry.owner.srcid    = 0;
    3910 #if L1_MULTI_CACHE
    3911         entry.owner.cache_id = 0;
    3912 #endif
    3913         entry.owner.inst     = 0;
    3914         entry.count          = 0;
    3915       }
    3916       m_cache_directory.write(set, way, entry);
    3917 
    3918       // request an invalidattion request in IVT for victim line
    3919       if(r_xram_rsp_victim_inval.read())
    3920       {
    3921         bool   broadcast    = r_xram_rsp_victim_is_cnt.read();
    3922         size_t index        = 0;
    3923         size_t count_copies = r_xram_rsp_victim_count.read();
    3924 
    3925         bool   wok = m_ivt.set(false,      // it's an inval transaction
    3926                                broadcast,  // set broadcast bit
    3927                                false,      // no response required
    3928                                false,      // no acknowledge required
    3929                                0,          // srcid
    3930                                0,          // trdid
    3931                                0,          // pktid
    3932                                r_xram_rsp_victim_nline.read(),
    3933                                count_copies,
    3934                                index);
    3935 
    3936         r_xram_rsp_ivt_index = index;
    3937 
    3938         if(!wok)
    3939         {
    3940           std::cout << "VCI_MEM_CACHE ERROR " << name() << " XRAM_RSP_DIR_UPDT"
    3941                     << " invalidate_tab entry free but write unsuccessful" << std::endl;
    3942           exit(0);
    3943         }
    3944       }
     4000    case XRAM_RSP_DIR_UPDT:   // updates the cache (both data & directory),
     4001                              // erases the TRT entry if victim not dirty,
     4002                              // and set inval request in IVT if required
     4003    {
     4004        assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP) and
     4005        "MEMC ERROR in XRAM_RSP_DIR_UPDT state: Bad DIR allocation");
     4006
     4007        assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP) and
     4008        "MEMC ERROR in XRAM_RSP_DIR_UPDT state: Bad TRT allocation");
     4009
     4010        assert( (r_alloc_ivt_fsm.read() == ALLOC_IVT_XRAM_RSP) and
     4011        "MEMC ERROR in XRAM_RSP_DIR_UPDT state: Bad IVT allocation");
     4012
     4013        // check if this is an instruction read, this means pktid is either
     4014        // TYPE_READ_INS_UNC   0bX010 with TSAR encoding
     4015        // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
     4016        bool inst_read = (r_xram_rsp_trt_buf.pktid & 0x2) and r_xram_rsp_trt_buf.proc_read;
     4017
     4018        // check if this is a cached read, this means pktid is either
     4019        // TYPE_READ_DATA_MISS 0bX001 with TSAR encoding
     4020        // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
     4021        bool cached_read = (r_xram_rsp_trt_buf.pktid & 0x1) and r_xram_rsp_trt_buf.proc_read;
     4022
     4023        bool dirty = false;
     4024
     4025        // update cache data
     4026        size_t set   = r_xram_rsp_victim_set.read();
     4027        size_t way   = r_xram_rsp_victim_way.read();
     4028
     4029        for(size_t word=0; word<m_words ; word++)
     4030        {
     4031            m_cache_data.write(way, set, word, r_xram_rsp_trt_buf.wdata[word]);
     4032            dirty = dirty or (r_xram_rsp_trt_buf.wdata_be[word] != 0);
     4033        }
     4034
     4035        // update cache directory
     4036        DirectoryEntry entry;
     4037        entry.valid   = true;
     4038        entry.is_cnt  = false;
     4039        entry.lock    = false;
     4040        entry.dirty   = dirty;
     4041        entry.tag     = r_xram_rsp_trt_buf.nline / m_sets;
     4042        entry.ptr     = 0;
     4043        if(cached_read)
     4044        {
     4045            entry.owner.srcid   = r_xram_rsp_trt_buf.srcid;
     4046            entry.owner.inst    = inst_read;
     4047            entry.count         = 1;
     4048        }
     4049        else
     4050        {
     4051            entry.owner.srcid    = 0;
     4052            entry.owner.inst     = 0;
     4053            entry.count          = 0;
     4054        }
     4055        m_cache_directory.write(set, way, entry);
     4056
     4057        // register invalid request in IVT for victim line if required
     4058        if(r_xram_rsp_victim_inval.read())
     4059        {
     4060            bool   broadcast    = r_xram_rsp_victim_is_cnt.read();
     4061            size_t index        = 0;
     4062            size_t count_copies = r_xram_rsp_victim_count.read();
     4063
     4064            bool   wok = m_ivt.set(false,      // it's an inval transaction
     4065                                   broadcast,  // set broadcast bit
     4066                                   false,      // no response required
     4067                                   false,      // no acknowledge required
     4068                                   0,          // srcid
     4069                                   0,          // trdid
     4070                                   0,          // pktid
     4071                                   r_xram_rsp_victim_nline.read(),
     4072                                   count_copies,
     4073                                   index);
     4074
     4075            r_xram_rsp_ivt_index = index;
     4076
     4077            assert( wok and
     4078            "MEMC ERROR in XRAM_RSP_DIR_UPDT state: IVT should not be full");
     4079        }
    39454080
    39464081#if DEBUG_MEMC_XRAM_RSP
     
    39564091          << " / is_cnt = " << entry.is_cnt << std::endl;
    39574092if(r_xram_rsp_victim_inval.read())
    3958 std::cout << "                           Invalidation request for victim line "
    3959           << std::hex << r_xram_rsp_victim_nline.read()
     4093std::cout << "                           Invalidation request for address "
     4094          << std::hex << r_xram_rsp_victim_nline.read()*m_words*4
    39604095          << " / broadcast = " << r_xram_rsp_victim_is_cnt.read() << std::endl;
    39614096}
    39624097#endif
    39634098
    3964       // If the victim is not dirty, we don't need another XRAM put transaction,
    3965       // and we can erase the TRT entry
    3966       if(!r_xram_rsp_victim_dirty.read())  m_trt.erase(r_xram_rsp_trt_index.read());
    3967 
    3968       // Next state
    3969       if(r_xram_rsp_victim_dirty.read())       r_xram_rsp_fsm = XRAM_RSP_TRT_DIRTY;
    3970       else if(r_xram_rsp_trt_buf.proc_read)    r_xram_rsp_fsm = XRAM_RSP_DIR_RSP;
    3971       else if(r_xram_rsp_victim_inval.read())  r_xram_rsp_fsm = XRAM_RSP_INVAL;
    3972       else                                     r_xram_rsp_fsm = XRAM_RSP_IDLE;
    3973       break;
     4099        // If the victim is not dirty, we don't need to reuse the TRT entry for
     4100        // another PUT transaction, and we can erase the TRT entry
     4101        if( not r_xram_rsp_victim_dirty.read() )
     4102        {
     4103            m_trt.erase(r_xram_rsp_trt_index.read());
     4104        }
     4105
     4106        // Next state
     4107        if(r_xram_rsp_victim_dirty.read())       r_xram_rsp_fsm = XRAM_RSP_TRT_DIRTY;
     4108        else if(r_xram_rsp_trt_buf.proc_read)    r_xram_rsp_fsm = XRAM_RSP_DIR_RSP;
     4109        else if(r_xram_rsp_victim_inval.read())  r_xram_rsp_fsm = XRAM_RSP_INVAL;
     4110        else                                     r_xram_rsp_fsm = XRAM_RSP_IDLE;
     4111        break;
    39744112    }
    39754113    ////////////////////////
    39764114    case XRAM_RSP_TRT_DIRTY:  // set the TRT entry (PUT to XRAM) if the victim is dirty
    39774115    {
    3978       if(r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP)
    3979       {
    3980         m_trt.set(r_xram_rsp_trt_index.read(),
    3981                               false,       // write to XRAM
    3982                               r_xram_rsp_victim_nline.read(),  // line index
    3983                               0,
    3984                               0,
    3985                               0,
    3986                               false,
    3987                               0,
    3988                               0,
    3989                               std::vector<be_t> (m_words,0),
    3990                               std::vector<data_t> (m_words,0));
     4116        if(r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP)
     4117        {
     4118            std::vector<data_t> data_vector;
     4119            data_vector.clear();
     4120            for(size_t i=0; i<m_words; i++)
     4121            {
     4122                data_vector.push_back(r_xram_rsp_victim_data[i].read());
     4123            }
     4124            m_trt.set( r_xram_rsp_trt_index.read(),
     4125                       false,                             // PUT
     4126                       r_xram_rsp_victim_nline.read(),    // line index
     4127                       0,                                 // unused
     4128                       0,                                 // unused
     4129                       0,                                 // unused
     4130                       false,                             // not proc_read
     4131                       0,                                 // unused
     4132                       0,                                 // unused
     4133                       std::vector<be_t>(m_words,0xF),                         
     4134                       data_vector);
    39914135
    39924136#if DEBUG_MEMC_XRAM_RSP
     
    39944138std::cout << "  <MEMC " << name() << " XRAM_RSP_TRT_DIRTY>"
    39954139          << " Set TRT entry for the put transaction"
    3996           << " / dirty victim line = " << r_xram_rsp_victim_nline.read() << std::endl;
    3997 #endif
    3998         if(r_xram_rsp_trt_buf.proc_read)         r_xram_rsp_fsm = XRAM_RSP_DIR_RSP;
    3999         else if(r_xram_rsp_victim_inval.read())  r_xram_rsp_fsm = XRAM_RSP_INVAL;
    4000         else                                     r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
    4001       }
    4002       break;
     4140          << " / address = " << (r_xram_rsp_victim_nline.read()*m_words*4) << std::endl;
     4141#endif
     4142            if(r_xram_rsp_trt_buf.proc_read)         r_xram_rsp_fsm = XRAM_RSP_DIR_RSP;
     4143            else if(r_xram_rsp_victim_inval.read())  r_xram_rsp_fsm = XRAM_RSP_INVAL;
     4144            else                                     r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
     4145        }
     4146        break;
    40034147    }
    40044148    //////////////////////
    40054149    case XRAM_RSP_DIR_RSP:     // Request a response to TGT_RSP FSM
    40064150    {
    4007       if(!r_xram_rsp_to_tgt_rsp_req.read())
    4008       {
    4009         r_xram_rsp_to_tgt_rsp_srcid = r_xram_rsp_trt_buf.srcid;
    4010         r_xram_rsp_to_tgt_rsp_trdid = r_xram_rsp_trt_buf.trdid;
    4011         r_xram_rsp_to_tgt_rsp_pktid = r_xram_rsp_trt_buf.pktid;
    4012         for(size_t i=0; i < m_words; i++)
    4013         {
    4014             r_xram_rsp_to_tgt_rsp_data[i] = r_xram_rsp_trt_buf.wdata[i];
    4015         }
    4016         r_xram_rsp_to_tgt_rsp_word   = r_xram_rsp_trt_buf.word_index;
    4017         r_xram_rsp_to_tgt_rsp_length = r_xram_rsp_trt_buf.read_length;
    4018         r_xram_rsp_to_tgt_rsp_ll_key = r_xram_rsp_trt_buf.ll_key;
    4019         r_xram_rsp_to_tgt_rsp_rerror = false;
    4020         r_xram_rsp_to_tgt_rsp_req    = true;
    4021 
    4022         if(r_xram_rsp_victim_inval)      r_xram_rsp_fsm = XRAM_RSP_INVAL;
    4023         else if(r_xram_rsp_victim_dirty) r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
    4024         else                             r_xram_rsp_fsm = XRAM_RSP_IDLE;
     4151        if ( not r_xram_rsp_to_tgt_rsp_req.read() )
     4152        {
     4153            r_xram_rsp_to_tgt_rsp_srcid = r_xram_rsp_trt_buf.srcid;
     4154            r_xram_rsp_to_tgt_rsp_trdid = r_xram_rsp_trt_buf.trdid;
     4155            r_xram_rsp_to_tgt_rsp_pktid = r_xram_rsp_trt_buf.pktid;
     4156            for(size_t i=0; i < m_words; i++)
     4157            {
     4158                r_xram_rsp_to_tgt_rsp_data[i] = r_xram_rsp_trt_buf.wdata[i];
     4159            }
     4160            r_xram_rsp_to_tgt_rsp_word   = r_xram_rsp_trt_buf.word_index;
     4161            r_xram_rsp_to_tgt_rsp_length = r_xram_rsp_trt_buf.read_length;
     4162            r_xram_rsp_to_tgt_rsp_ll_key = r_xram_rsp_trt_buf.ll_key;
     4163            r_xram_rsp_to_tgt_rsp_rerror = false;
     4164            r_xram_rsp_to_tgt_rsp_req    = true;
     4165
     4166            if(r_xram_rsp_victim_inval.read())      r_xram_rsp_fsm = XRAM_RSP_INVAL;
     4167            else if(r_xram_rsp_victim_dirty.read()) r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
     4168            else                                    r_xram_rsp_fsm = XRAM_RSP_IDLE;
    40254169
    40264170#if DEBUG_MEMC_XRAM_RSP
     
    40324176          << " / nwords = " << std::dec << r_xram_rsp_trt_buf.read_length << std::endl;
    40334177#endif
    4034       }
    4035       break;
     4178        }
     4179        break;
    40364180    }
    40374181    ////////////////////
     
    40514195        xram_rsp_to_cc_send_fifo_srcid     = r_xram_rsp_victim_copy.read();
    40524196        xram_rsp_to_cc_send_fifo_inst      = r_xram_rsp_victim_copy_inst.read();
    4053 #if L1_MULTI_CACHE
    4054         xram_rsp_to_cc_send_fifo_cache_id  = r_xram_rsp_victim_copy_cache.read();
    4055 #endif
    40564197        xram_rsp_to_cc_send_fifo_put       = multi_req;
    4057         r_xram_rsp_next_ptr                 = r_xram_rsp_victim_ptr.read();
     4198        r_xram_rsp_next_ptr                = r_xram_rsp_victim_ptr.read();
    40584199
    40594200        if(r_xram_rsp_victim_dirty)  r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
     
    40654206std::cout << "  <MEMC " << name() << " XRAM_RSP_INVAL>"
    40664207          << " Send an inval request to CC_SEND FSM"
    4067           << " / victim line = " << r_xram_rsp_victim_nline.read() << std::endl;
     4208          << " / address = " << r_xram_rsp_victim_nline.read()*m_words*4 << std::endl;
    40684209#endif
    40694210      }
     
    40734214    case XRAM_RSP_WRITE_DIRTY:  // send a write request to IXR_CMD FSM
    40744215    {
    4075       if(!r_xram_rsp_to_ixr_cmd_req.read())
    4076       {
    4077         r_xram_rsp_to_ixr_cmd_req = true;
    4078         r_xram_rsp_to_ixr_cmd_nline = r_xram_rsp_victim_nline.read();
    4079         r_xram_rsp_to_ixr_cmd_trdid = r_xram_rsp_trt_index.read();
    4080         for(size_t i=0; i<m_words ; i++)
    4081         {
    4082             r_xram_rsp_to_ixr_cmd_data[i] = r_xram_rsp_victim_data[i];
    4083         }
    4084         m_cpt_write_dirty++;
    4085 
    4086         bool multi_req = !r_xram_rsp_victim_is_cnt.read() and r_xram_rsp_victim_inval.read();
    4087         bool not_last_multi_req = multi_req and (r_xram_rsp_victim_count.read() != 1);
    4088 
    4089         if(not_last_multi_req)   r_xram_rsp_fsm = XRAM_RSP_HEAP_REQ;
    4090         else                     r_xram_rsp_fsm = XRAM_RSP_IDLE;
     4216        if ( not r_xram_rsp_to_ixr_cmd_req.read() )
     4217        {
     4218            r_xram_rsp_to_ixr_cmd_req = true;
     4219            r_xram_rsp_to_ixr_cmd_index = r_xram_rsp_trt_index.read();
     4220
     4221            m_cpt_write_dirty++;
     4222
     4223            bool multi_req = not r_xram_rsp_victim_is_cnt.read() and
     4224                             r_xram_rsp_victim_inval.read();
     4225            bool not_last_multi_req = multi_req and (r_xram_rsp_victim_count.read() != 1);
     4226
     4227            if(not_last_multi_req)   r_xram_rsp_fsm = XRAM_RSP_HEAP_REQ;
     4228            else                     r_xram_rsp_fsm = XRAM_RSP_IDLE;
    40914229
    40924230#if DEBUG_MEMC_XRAM_RSP
     
    40944232std::cout << "  <MEMC " << name() << " XRAM_RSP_WRITE_DIRTY>"
    40954233          << " Send the put request to IXR_CMD FSM"
    4096           << " / victim line = " << r_xram_rsp_victim_nline.read() << std::endl;
    4097 #endif
    4098       }
    4099       break;
     4234          << " / address = " << r_xram_rsp_victim_nline.read()*m_words*4 << std::endl;
     4235#endif
     4236        }
     4237        break;
    41004238    }
    41014239    /////////////////////////
    41024240    case XRAM_RSP_HEAP_REQ:    // Get the lock to the HEAP
    41034241    {
    4104       if(r_alloc_heap_fsm.read() == ALLOC_HEAP_XRAM_RSP)
    4105       {
    4106         r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE;
    4107       }
     4242        if(r_alloc_heap_fsm.read() == ALLOC_HEAP_XRAM_RSP)
     4243        {
     4244            r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE;
     4245        }
    41084246
    41094247#if DEBUG_MEMC_XRAM_RSP
     
    41124250          << " Requesting HEAP lock" << std::endl;
    41134251#endif
    4114       break;
     4252        break;
    41154253    }
    41164254    /////////////////////////
     
    41224260
    41234261        xram_rsp_to_cc_send_fifo_srcid    = entry.owner.srcid;
    4124 #if L1_MULTI_CACHE
    4125         xram_rsp_to_cc_send_fifo_cache_id = entry.owner.cache_id;
    4126 #endif
    41274262        xram_rsp_to_cc_send_fifo_inst  = entry.owner.inst;
    41284263        xram_rsp_to_cc_send_fifo_put   = true;
     
    41684303      HeapEntry last_entry;
    41694304      last_entry.owner.srcid    = 0;
    4170 #if L1_MULTI_CACHE
    4171       last_entry.owner.cache_id = 0;
    4172 #endif
    41734305      last_entry.owner.inst     = false;
    41744306      if(m_heap.is_full())
     
    41944326      break;
    41954327    }
    4196     // ///////////////////////
     4328    //////////////////////////
    41974329    case XRAM_RSP_ERROR_ERASE:  // erase TRT entry in case of error
    41984330    {
     
    42474379  ////////////////////////////////////////////////////////////////////////////////////
    42484380
     4381//std::cout << std::endl << "cleanup_fsm" << std::endl;
     4382
    42494383  switch(r_cleanup_fsm.read())
    42504384  {
    4251     //////////////////
    4252     case CLEANUP_IDLE:     // Get first DSPIN flit of the CLEANUP command
    4253     {
    4254       if(not m_cc_receive_to_cleanup_fifo.rok()) break;
    4255 
    4256       uint64_t flit = m_cc_receive_to_cleanup_fifo.read();
    4257 
    4258       uint32_t srcid =
    4259         DspinDhccpParam::dspin_get(
    4260             flit,
    4261             DspinDhccpParam::CLEANUP_SRCID);
    4262 
    4263       uint8_t type =
    4264         DspinDhccpParam::dspin_get(
    4265             flit,
    4266             DspinDhccpParam::P2M_TYPE);
    4267 
    4268       r_cleanup_way_index =
    4269         DspinDhccpParam::dspin_get(
    4270             flit,
    4271             DspinDhccpParam::CLEANUP_WAY_INDEX);
    4272 
    4273       r_cleanup_nline =
    4274         DspinDhccpParam::dspin_get(
    4275             flit,
    4276             DspinDhccpParam::CLEANUP_NLINE_MSB) << 32;
    4277 
    4278       r_cleanup_inst  = (type == DspinDhccpParam::TYPE_CLEANUP_INST);
    4279       r_cleanup_srcid = srcid;
    4280 
    4281       if(srcid >= m_initiators)
    4282       {
    4283         std::cout
    4284             << "VCI_MEM_CACHE ERROR " << name()
    4285             << " CLEANUP_IDLE state"  << std::endl
    4286             << "illegal srcid for cleanup request" << std::endl;
    4287 
    4288         exit(0);
    4289       }
    4290 
    4291       m_cpt_cleanup++;
    4292       cc_receive_to_cleanup_fifo_get = true;
    4293       r_cleanup_fsm                  = CLEANUP_GET_NLINE;
     4385      //////////////////
     4386      case CLEANUP_IDLE:     // Get first DSPIN flit of the CLEANUP command
     4387      {
     4388          if(not m_cc_receive_to_cleanup_fifo.rok()) break;
     4389
     4390          uint64_t flit = m_cc_receive_to_cleanup_fifo.read();
     4391
     4392          uint32_t srcid = DspinDhccpParam::dspin_get( flit,
     4393                           DspinDhccpParam::CLEANUP_SRCID);
     4394
     4395          uint8_t type = DspinDhccpParam::dspin_get( flit,
     4396                         DspinDhccpParam::P2M_TYPE);
     4397
     4398          r_cleanup_way_index = DspinDhccpParam::dspin_get( flit,
     4399                                DspinDhccpParam::CLEANUP_WAY_INDEX);
     4400
     4401          r_cleanup_nline = DspinDhccpParam::dspin_get( flit,
     4402                            DspinDhccpParam::CLEANUP_NLINE_MSB) << 32;
     4403
     4404          r_cleanup_inst  = (type == DspinDhccpParam::TYPE_CLEANUP_INST);
     4405          r_cleanup_srcid = srcid;
     4406
     4407          assert( (srcid < m_initiators) and
     4408          "MEMC ERROR in CLEANUP_IDLE state : illegal SRCID value");
     4409
     4410          m_cpt_cleanup++;
     4411          cc_receive_to_cleanup_fifo_get = true;
     4412          r_cleanup_fsm                  = CLEANUP_GET_NLINE;
    42944413
    42954414#if DEBUG_MEMC_CLEANUP
     
    42974416std::cout << "  <MEMC "         << name()
    42984417          << " CLEANUP_IDLE> Cleanup request:" << std::hex
    4299           << " / owner_id = "   << srcid
     4418          << " owner_id = "   << srcid
    43004419          << " / owner_ins = "  << (type == DspinDhccpParam::TYPE_CLEANUP_INST) << std::endl;
    43014420#endif
    4302       break;
    4303     }
    4304 
    4305     ///////////////////////
    4306     case CLEANUP_GET_NLINE:  // GET second DSPIN flit of the cleanup command
    4307     {
    4308       if(not m_cc_receive_to_cleanup_fifo.rok()) break;
    4309 
    4310       uint64_t flit = m_cc_receive_to_cleanup_fifo.read();
    4311 
    4312       addr_t nline = r_cleanup_nline.read() |
    4313         DspinDhccpParam::dspin_get(flit, DspinDhccpParam::CLEANUP_NLINE_LSB);
    4314 
    4315       cc_receive_to_cleanup_fifo_get = true;
    4316       r_cleanup_nline                = nline;
    4317       r_cleanup_fsm                  = CLEANUP_DIR_REQ;
     4421          break;
     4422      }
     4423      ///////////////////////
     4424      case CLEANUP_GET_NLINE:  // GET second DSPIN flit of the cleanup command
     4425      {
     4426          if(not m_cc_receive_to_cleanup_fifo.rok()) break;
     4427
     4428          uint64_t flit = m_cc_receive_to_cleanup_fifo.read();
     4429
     4430          addr_t nline = r_cleanup_nline.read() |
     4431              DspinDhccpParam::dspin_get(flit, DspinDhccpParam::CLEANUP_NLINE_LSB);
     4432
     4433          cc_receive_to_cleanup_fifo_get = true;
     4434          r_cleanup_nline                = nline;
     4435          r_cleanup_fsm                  = CLEANUP_DIR_REQ;
    43184436
    43194437#if DEBUG_MEMC_CLEANUP
     
    43214439std::cout << "  <MEMC "         << name()
    43224440          << " CLEANUP_GET_NLINE> Cleanup request:"
    4323           << " / address = " << std::hex << nline * m_words * 4 << std::endl;
    4324 #endif
    4325       break;
    4326     }
    4327 
    4328     /////////////////////
    4329     case CLEANUP_DIR_REQ:   // Get the lock to the directory
    4330     {
    4331       if(r_alloc_dir_fsm.read() != ALLOC_DIR_CLEANUP) break;
    4332 
    4333       r_cleanup_fsm = CLEANUP_DIR_LOCK;
     4441          << " address = " << std::hex << nline * m_words * 4 << std::endl;
     4442#endif
     4443          break;
     4444      }
     4445      /////////////////////
     4446      case CLEANUP_DIR_REQ:   // Get the lock to the directory
     4447      {
     4448          if(r_alloc_dir_fsm.read() != ALLOC_DIR_CLEANUP) break;
     4449
     4450          r_cleanup_fsm = CLEANUP_DIR_LOCK;
    43344451
    43354452#if DEBUG_MEMC_CLEANUP
     
    43374454std::cout << "  <MEMC " << name() << " CLEANUP_DIR_REQ> Requesting DIR lock" << std::endl;
    43384455#endif
    4339       break;
    4340     }
    4341 
    4342     //////////////////////
    4343     case CLEANUP_DIR_LOCK:
    4344     {
    4345       // test directory status
    4346       if(r_alloc_dir_fsm.read() != ALLOC_DIR_CLEANUP)
    4347       {
    4348         std::cout
    4349             << "VCI_MEM_CACHE ERROR " << name()
    4350             << " CLEANUP_DIR_LOCK state"
    4351             << " bad DIR allocation" << std::endl;
    4352 
    4353         exit(0);
    4354       }
    4355 
    4356       // Read the directory
    4357       size_t way = 0;
    4358       addr_t cleanup_address = r_cleanup_nline.read() * m_words * 4;
    4359 
    4360       DirectoryEntry entry   = m_cache_directory.read(cleanup_address , way);
    4361       r_cleanup_is_cnt       = entry.is_cnt;
    4362       r_cleanup_dirty        = entry.dirty;
    4363       r_cleanup_tag          = entry.tag;
    4364       r_cleanup_lock         = entry.lock;
    4365       r_cleanup_way          = way;
    4366       r_cleanup_count        = entry.count;
    4367       r_cleanup_ptr          = entry.ptr;
    4368       r_cleanup_copy         = entry.owner.srcid;
    4369       r_cleanup_copy_inst    = entry.owner.inst;
    4370 #if L1_MULTI_CACHE
    4371       r_cleanup_copy_cache   = entry.owner.cache_id;
    4372 #endif
    4373 
    4374       if(entry.valid)      // hit : the copy must be cleared
    4375       {
    4376         assert(
    4377             (entry.count > 0) and
    4378             "VCI MEM CACHE ERROR: "
    4379             "In CLEANUP_DIR_LOCK, CLEANUP command on a valid entry "
    4380             "with no copies");
    4381 
    4382         // no access to the heap
    4383         if((entry.count == 1) or (entry.is_cnt))
    4384         {
    4385           r_cleanup_fsm = CLEANUP_DIR_WRITE;
    4386         }
    4387         // access to the heap
    4388         else
    4389         {
    4390           r_cleanup_fsm = CLEANUP_HEAP_REQ;
    4391         }
    4392       }
    4393       else                // miss : check UPT for a pending invalidation transaction
    4394       {
    4395         r_cleanup_fsm = CLEANUP_IVT_LOCK;
    4396       }
     4456          break;
     4457      }
     4458      //////////////////////
     4459      case CLEANUP_DIR_LOCK:    // test directory status
     4460      {
     4461          assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CLEANUP) and
     4462          "MEMC ERROR in CLEANUP_DIR_LOCK: bad DIR allocation");
     4463
     4464          // Read the directory
     4465          size_t way = 0;
     4466          addr_t cleanup_address = r_cleanup_nline.read() * m_words * 4;
     4467          DirectoryEntry entry   = m_cache_directory.read(cleanup_address , way);
     4468          r_cleanup_is_cnt       = entry.is_cnt;
     4469          r_cleanup_dirty        = entry.dirty;
     4470          r_cleanup_tag          = entry.tag;
     4471          r_cleanup_lock         = entry.lock;
     4472          r_cleanup_way          = way;
     4473          r_cleanup_count        = entry.count;
     4474          r_cleanup_ptr          = entry.ptr;
     4475          r_cleanup_copy         = entry.owner.srcid;
     4476          r_cleanup_copy_inst    = entry.owner.inst;
     4477
     4478          if(entry.valid)      // hit : the copy must be cleared
     4479          {
     4480              assert( (entry.count > 0) and
     4481              "MEMC ERROR in CLEANUP_DIR_LOCK state, CLEANUP on valid entry with no copies");
     4482
     4483              if((entry.count == 1) or (entry.is_cnt))   // no access to the heap
     4484              {
     4485                  r_cleanup_fsm = CLEANUP_DIR_WRITE;
     4486              }
     4487              else                                       // access to the heap
     4488              {
     4489                  r_cleanup_fsm = CLEANUP_HEAP_REQ;
     4490              }
     4491          }
     4492          else                // miss : check IVT for a pending inval
     4493          {
     4494              r_cleanup_fsm = CLEANUP_IVT_LOCK;
     4495          }
    43974496
    43984497#if DEBUG_MEMC_CLEANUP
    4399       if(m_debug)
    4400       {
    4401         std::cout
    4402             << "  <MEMC " << name()
    4403             << " CLEANUP_DIR_LOCK> Test directory status: "
    4404             << std::hex
    4405             << " line = "         << cleanup_address
    4406             << " / hit = "        << entry.valid
    4407             << " / dir_id = "     << entry.owner.srcid
    4408             << " / dir_ins = "    << entry.owner.inst
    4409             << " / search_id = "  << r_cleanup_srcid.read()
    4410             << " / search_ins = " << r_cleanup_inst.read()
    4411             << " / count = "      << entry.count
    4412             << " / is_cnt = "     << entry.is_cnt
    4413             << std::endl;
    4414       }
    4415 #endif
    4416       break;
    4417     }
    4418 
    4419     ///////////////////////
    4420     case CLEANUP_DIR_WRITE:
    4421     {
    4422       // Update the directory entry without heap access
    4423       if(r_alloc_dir_fsm.read() != ALLOC_DIR_CLEANUP)
    4424       {
    4425         std::cout
    4426             << "VCI_MEM_CACHE ERROR " << name()
    4427             << " CLEANUP_DIR_WRITE state"
    4428             << " bad DIR allocation" << std::endl;
    4429 
    4430         exit(0);
    4431       }
    4432 
    4433       size_t way         = r_cleanup_way.read();
    4434       size_t set         = m_y[(addr_t)(r_cleanup_nline.read()*m_words*4)];
    4435       bool   match_srcid = (r_cleanup_copy.read() == r_cleanup_srcid.read());
    4436 
    4437 #if L1_MULTI_CACHE
    4438       match_srcid       &= (r_cleanup_copy_cache.read() == r_cleanup_pktid.read());
    4439 #endif
    4440 
    4441       bool   match_inst  = (r_cleanup_copy_inst.read() == r_cleanup_inst.read());
    4442       bool   match       = match_srcid and match_inst;
    4443 
    4444       if(not r_cleanup_is_cnt.read() and not match)
    4445       {
    4446         std::cout
    4447             << "VCI_MEM_CACHE ERROR : Cleanup request on a valid"
    4448             << "entry using linked list mode with no corresponding"
    4449             << "directory or heap entry"
    4450             << std::endl;
    4451 
    4452         exit(1);
    4453       }
    4454 
    4455       // update the cache directory (for the copies)
    4456       DirectoryEntry entry;
    4457       entry.valid       = true;
    4458       entry.is_cnt      = r_cleanup_is_cnt.read();
    4459       entry.dirty       = r_cleanup_dirty.read();
    4460       entry.tag         = r_cleanup_tag.read();
    4461       entry.lock        = r_cleanup_lock.read();
    4462       entry.ptr         = r_cleanup_ptr.read();
    4463       entry.count       = r_cleanup_count.read() - 1;
    4464       entry.owner.srcid = 0;
    4465       entry.owner.inst  = 0;
    4466 
    4467 #if L1_MULTI_CACHE
    4468       entry.owner.cache_id = 0;
    4469 #endif
    4470 
    4471       m_cache_directory.write(set, way, entry);
    4472 
    4473       r_cleanup_fsm = CLEANUP_SEND_CLACK;
     4498if(m_debug)
     4499std::cout << "  <MEMC " << name()
     4500          << " CLEANUP_DIR_LOCK> Test directory status: "
     4501          << std::hex << " address = " << cleanup_address
     4502          << " / hit = "        << entry.valid
     4503          << " / dir_id = "     << entry.owner.srcid
     4504          << " / dir_ins = "    << entry.owner.inst
     4505          << " / search_id = "  << r_cleanup_srcid.read()
     4506          << " / search_ins = " << r_cleanup_inst.read()
     4507          << " / count = "      << entry.count
     4508          << " / is_cnt = "     << entry.is_cnt << std::endl;
     4509#endif
     4510          break;
     4511      }
     4512      ///////////////////////
     4513      case CLEANUP_DIR_WRITE:      // Update the directory entry without heap access
     4514      {
     4515          assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CLEANUP) and
     4516          "MEMC ERROR in CLEANUP_DIR_LOCK: bad DIR allocation");
     4517
     4518          size_t way         = r_cleanup_way.read();
     4519          size_t set         = m_y[(addr_t)(r_cleanup_nline.read()*m_words*4)];
     4520          bool   match_srcid = (r_cleanup_copy.read() == r_cleanup_srcid.read());
     4521          bool   match_inst  = (r_cleanup_copy_inst.read() == r_cleanup_inst.read());
     4522          bool   match       = match_srcid and match_inst;
     4523
     4524          assert( (r_cleanup_is_cnt.read() or match) and
     4525          "MEMC ERROR in CLEANUP_DIR_LOCK: illegal CLEANUP on valid entry");
     4526
     4527          // update the cache directory (for the copies)
     4528          DirectoryEntry entry;
     4529          entry.valid       = true;
     4530          entry.is_cnt      = r_cleanup_is_cnt.read();
     4531          entry.dirty       = r_cleanup_dirty.read();
     4532          entry.tag         = r_cleanup_tag.read();
     4533          entry.lock        = r_cleanup_lock.read();
     4534          entry.ptr         = r_cleanup_ptr.read();
     4535          entry.count       = r_cleanup_count.read() - 1;
     4536          entry.owner.srcid = 0;
     4537          entry.owner.inst  = 0;
     4538
     4539          m_cache_directory.write(set, way, entry);
     4540
     4541          r_cleanup_fsm = CLEANUP_SEND_CLACK;
    44744542
    44754543#if DEBUG_MEMC_CLEANUP
    4476       if(m_debug)
    4477       {
    4478         std::cout
    4479             << "  <MEMC " << name()
    4480             << " CLEANUP_DIR_WRITE> Update directory:"
    4481             << std::hex
    4482             << " address = "   << r_cleanup_nline.read() * m_words * 4
    4483             << " / dir_id = "  << entry.owner.srcid
    4484             << " / dir_ins = " << entry.owner.inst
    4485             << " / count = "   << entry.count
    4486             << " / is_cnt = "  << entry.is_cnt
    4487             << std::endl;
    4488       }
    4489 #endif
    4490 
    4491       break;
    4492     }
    4493 
    4494     //////////////////////
    4495     case CLEANUP_HEAP_REQ:
    4496     {
    4497       // get the lock to the HEAP directory
    4498       if(r_alloc_heap_fsm.read() != ALLOC_HEAP_CLEANUP) break;
    4499 
    4500       r_cleanup_fsm = CLEANUP_HEAP_LOCK;
     4544if(m_debug)
     4545std::cout << "  <MEMC " << name()
     4546          << " CLEANUP_DIR_WRITE> Update directory:"
     4547          << std::hex << " address = "   << r_cleanup_nline.read() * m_words * 4
     4548          << " / dir_id = "  << entry.owner.srcid
     4549          << " / dir_ins = " << entry.owner.inst
     4550          << " / count = "   << entry.count
     4551          << " / is_cnt = "  << entry.is_cnt << std::endl;
     4552#endif
     4553
     4554          break;
     4555      }
     4556      //////////////////////
     4557      case CLEANUP_HEAP_REQ:         // get the lock to the HEAP directory
     4558      {
     4559          if(r_alloc_heap_fsm.read() != ALLOC_HEAP_CLEANUP) break;
     4560
     4561          r_cleanup_fsm = CLEANUP_HEAP_LOCK;
    45014562
    45024563#if DEBUG_MEMC_CLEANUP
    4503       if(m_debug)
    4504       {
    4505         std::cout
    4506             << "  <MEMC " << name()
    4507             << " CLEANUP_HEAP_REQ> HEAP lock acquired "
    4508             << std::endl;
    4509       }
    4510 #endif
    4511       break;
    4512     }
    4513 
    4514     //////////////////////
    4515     case CLEANUP_HEAP_LOCK:
    4516     {
    4517       // two cases are handled in this state :
    4518       // 1. the matching copy is directly in the directory
    4519       // 2. the matching copy is the first copy in the heap
    4520       if(r_alloc_heap_fsm.read() != ALLOC_HEAP_CLEANUP)
    4521       {
    4522         std::cout
    4523             << "VCI_MEM_CACHE ERROR " << name()
    4524             << " CLEANUP_HEAP_LOCK state"
    4525             << " bad HEAP allocation" << std::endl;
    4526 
    4527         exit(0);
    4528       }
    4529 
    4530       size_t way            = r_cleanup_way.read();
    4531       size_t set            = m_y[(addr_t)(r_cleanup_nline.read() *m_words*4)];
    4532 
    4533       HeapEntry heap_entry  = m_heap.read(r_cleanup_ptr.read());
    4534       bool last             = (heap_entry.next == r_cleanup_ptr.read());
    4535 
    4536       // match_dir computation
    4537       bool match_dir_srcid  = (r_cleanup_copy.read()      == r_cleanup_srcid.read());
    4538       bool match_dir_inst   = (r_cleanup_copy_inst.read() == r_cleanup_inst.read());
    4539       bool match_dir        = match_dir_srcid  and match_dir_inst;
    4540 
    4541       // match_heap computation
    4542       bool match_heap_srcid = (heap_entry.owner.srcid == r_cleanup_srcid.read());
    4543       bool match_heap_inst  = (heap_entry.owner.inst  == r_cleanup_inst.read());
    4544       bool match_heap       = match_heap_srcid and match_heap_inst;
    4545 
    4546       r_cleanup_prev_ptr    = r_cleanup_ptr.read();
    4547       r_cleanup_prev_srcid  = heap_entry.owner.srcid;
    4548       r_cleanup_prev_inst   = heap_entry.owner.inst;
    4549 
    4550 #if L1_MULTI_CACHE
    4551       match_dir  = match_dir  and(r_cleanup_copy_cache.read() == r_cleanup_pktid.read());
    4552       match_heap = match_heap and(heap_entry.owner.cache_id   == r_cleanup_pktid.read());
    4553       r_cleanup_prev_cache_id = heap_entry.owner.cache_id;
    4554 #endif
    4555 
    4556       if(not match_dir and not match_heap and last)
    4557       {
    4558         std::cout
    4559             << "VCI_MEM_CACHE ERROR " << name()
    4560             << " CLEANUP_HEAP_LOCK state"
    4561             << " hit but copy not found"
    4562             << std::endl;
    4563 /**/
    4564         std::cout
    4565           << "r_cleanup_srcid = " << r_cleanup_srcid.read()
    4566           << " / r_cleanup_inst = " << r_cleanup_inst.read() << std::endl
    4567           << "r_cleanup_copy = " << r_cleanup_copy.read()
    4568           << " / r_cleanup_copy_inst = " << r_cleanup_copy_inst.read() << std::endl
    4569           << "heap_entry.owner.srcid = " << heap_entry.owner.srcid
    4570           << " / heap_entry.owner.inst = " << heap_entry.owner.inst << std::endl;
    4571 /**/
    4572         exit(0);
    4573       }
    4574 
    4575       if(match_dir and match_heap)
    4576       {
    4577         std::cout
    4578             << "VCI_MEM_CACHE ERROR " << name()
    4579             << " CLEANUP_HEAP_LOCK state"
    4580             << " two copies matching the cleanup owner id"
    4581             << std::endl;
    4582 /**/
    4583         std::cout
    4584           << "r_cleanup_srcid = " << r_cleanup_srcid.read()
    4585           << " / r_cleanup_inst = " << r_cleanup_inst.read() << std::endl
    4586           << "r_cleanup_copy = " << r_cleanup_copy.read()
    4587           << " / r_cleanup_copy_inst = " << r_cleanup_copy_inst.read() << std::endl
    4588           << "heap_entry.owner.srcid = " << heap_entry.owner.srcid
    4589           << " / heap_entry.owner.inst = " << heap_entry.owner.inst << std::endl;
    4590 /**/
    4591 
    4592         exit(0);
    4593       }
    4594 
    4595       DirectoryEntry dir_entry;
    4596       dir_entry.valid          = true;
    4597       dir_entry.is_cnt         = r_cleanup_is_cnt.read();
    4598       dir_entry.dirty          = r_cleanup_dirty.read();
    4599       dir_entry.tag            = r_cleanup_tag.read();
    4600       dir_entry.lock           = r_cleanup_lock.read();
    4601       dir_entry.count          = r_cleanup_count.read()-1;
    4602 
    4603       // the matching copy is registered in the directory and
    4604       // it must be replaced by the first copy registered in
    4605       // the heap. The corresponding entry must be freed
    4606       if(match_dir)
    4607       {
    4608         dir_entry.ptr            = heap_entry.next;
    4609         dir_entry.owner.srcid    = heap_entry.owner.srcid;
    4610         dir_entry.owner.inst     = heap_entry.owner.inst;
    4611 
    4612 #if L1_MULTI_CACHE
    4613         dir_entry.owner.cache_id = heap_entry.owner.cache_id;
    4614 #endif
    4615 
    4616         r_cleanup_next_ptr       = r_cleanup_ptr.read();
    4617         r_cleanup_fsm            = CLEANUP_HEAP_FREE;
    4618       }
    4619 
    4620       // the matching copy is the first copy in the heap
    4621       // It must be freed and the copy registered in directory
    4622       // must point to the next copy in heap
    4623       else if(match_heap)
    4624       {
    4625         dir_entry.ptr            = heap_entry.next;
    4626         dir_entry.owner.srcid    = r_cleanup_copy.read();
    4627         dir_entry.owner.inst     = r_cleanup_copy_inst.read();
    4628 
    4629 #if L1_MULTI_CACHE
    4630         dir_entry.owner.cache_id = r_cleanup_copy_cache.read();
    4631 #endif
    4632 
    4633         r_cleanup_next_ptr       = r_cleanup_ptr.read();
    4634         r_cleanup_fsm            = CLEANUP_HEAP_FREE;
    4635       }
    4636 
    4637       // The matching copy is in the heap, but is not the first copy
    4638       // The directory entry must be modified to decrement count
    4639       else
    4640       {
    4641         dir_entry.ptr            = r_cleanup_ptr.read();
    4642         dir_entry.owner.srcid    = r_cleanup_copy.read();
    4643         dir_entry.owner.inst     = r_cleanup_copy_inst.read();
    4644 
    4645 #if L1_MULTI_CACHE
    4646         dir_entry.owner.cache_id = r_cleanup_copy_cache.read();
    4647 #endif
    4648 
    4649         r_cleanup_next_ptr       = heap_entry.next;
    4650         r_cleanup_fsm            = CLEANUP_HEAP_SEARCH;
    4651       }
    4652 
    4653       m_cache_directory.write(set,way,dir_entry);
     4564if(m_debug)
     4565std::cout << "  <MEMC " << name()
     4566          << " CLEANUP_HEAP_REQ> HEAP lock acquired " << std::endl;
     4567#endif
     4568          break;
     4569      }
     4570      //////////////////////
     4571      case CLEANUP_HEAP_LOCK:      // two cases are handled in this state :
     4572                                 // 1. the matching copy is directly in the directory
     4573                                 // 2. the matching copy is the first copy in the heap
     4574      {
     4575          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP) and
     4576          "MEMC ERROR in CLEANUP_HEAP_LOCK state: bad HEAP allocation");
     4577
     4578          size_t way            = r_cleanup_way.read();
     4579          size_t set            = m_y[(addr_t)(r_cleanup_nline.read() *m_words*4)];
     4580
     4581          HeapEntry heap_entry  = m_heap.read(r_cleanup_ptr.read());
     4582          bool last             = (heap_entry.next == r_cleanup_ptr.read());
     4583
     4584          // match_dir computation
     4585          bool match_dir_srcid  = (r_cleanup_copy.read()      == r_cleanup_srcid.read());
     4586          bool match_dir_inst   = (r_cleanup_copy_inst.read() == r_cleanup_inst.read());
     4587          bool match_dir        = match_dir_srcid  and match_dir_inst;
     4588
     4589          // match_heap computation
     4590          bool match_heap_srcid = (heap_entry.owner.srcid == r_cleanup_srcid.read());
     4591          bool match_heap_inst  = (heap_entry.owner.inst  == r_cleanup_inst.read());
     4592          bool match_heap       = match_heap_srcid and match_heap_inst;
     4593
     4594          r_cleanup_prev_ptr    = r_cleanup_ptr.read();
     4595          r_cleanup_prev_srcid  = heap_entry.owner.srcid;
     4596          r_cleanup_prev_inst   = heap_entry.owner.inst;
     4597
     4598          assert( (not last or match_dir or match_heap) and
     4599          "MEMC ERROR in CLEANUP_HEAP_LOCK state: hit but no copy found");
     4600
     4601          assert( (not match_dir or not match_heap) and
     4602          "MEMC ERROR in CLEANUP_HEAP_LOCK state: two matching copies found");
     4603
     4604          DirectoryEntry dir_entry;
     4605          dir_entry.valid          = true;
     4606          dir_entry.is_cnt         = r_cleanup_is_cnt.read();
     4607          dir_entry.dirty          = r_cleanup_dirty.read();
     4608          dir_entry.tag            = r_cleanup_tag.read();
     4609          dir_entry.lock           = r_cleanup_lock.read();
     4610          dir_entry.count          = r_cleanup_count.read()-1;
     4611
     4612          // the matching copy is registered in the directory and
     4613          // it must be replaced by the first copy registered in
     4614          // the heap. The corresponding entry must be freed
     4615          if(match_dir)
     4616          {
     4617              dir_entry.ptr            = heap_entry.next;
     4618              dir_entry.owner.srcid    = heap_entry.owner.srcid;
     4619              dir_entry.owner.inst     = heap_entry.owner.inst;
     4620              r_cleanup_next_ptr       = r_cleanup_ptr.read();
     4621              r_cleanup_fsm            = CLEANUP_HEAP_FREE;
     4622          }
     4623
     4624          // the matching copy is the first copy in the heap
     4625          // It must be freed and the copy registered in directory
     4626          // must point to the next copy in heap
     4627          else if(match_heap)
     4628          {
     4629              dir_entry.ptr            = heap_entry.next;
     4630              dir_entry.owner.srcid    = r_cleanup_copy.read();
     4631              dir_entry.owner.inst     = r_cleanup_copy_inst.read();
     4632              r_cleanup_next_ptr       = r_cleanup_ptr.read();
     4633              r_cleanup_fsm            = CLEANUP_HEAP_FREE;
     4634          }
     4635
     4636          // The matching copy is in the heap, but is not the first copy
     4637          // The directory entry must be modified to decrement count
     4638          else
     4639          {
     4640              dir_entry.ptr            = r_cleanup_ptr.read();
     4641              dir_entry.owner.srcid    = r_cleanup_copy.read();
     4642              dir_entry.owner.inst     = r_cleanup_copy_inst.read();
     4643              r_cleanup_next_ptr       = heap_entry.next;
     4644              r_cleanup_fsm            = CLEANUP_HEAP_SEARCH;
     4645          }
     4646
     4647          m_cache_directory.write(set,way,dir_entry);
    46544648
    46554649#if DEBUG_MEMC_CLEANUP
    4656       if(m_debug)
    4657       {
    4658         std::cout
    4659             << "  <MEMC " << name()
    4660             << " CLEANUP_HEAP_LOCK> Checks matching:"
    4661             << " address = "      << r_cleanup_nline.read() * m_words * 4
    4662             << " / dir_id = "     << r_cleanup_copy.read()
    4663             << " / dir_ins = "    << r_cleanup_copy_inst.read()
    4664             << " / heap_id = "    << heap_entry.owner.srcid
    4665             << " / heap_ins = "   << heap_entry.owner.inst
    4666             << " / search_id = "  << r_cleanup_srcid.read()
    4667             << " / search_ins = " << r_cleanup_inst.read()
    4668             << std::endl;
    4669       }
    4670 #endif
    4671       break;
    4672     }
    4673 
    4674     ////////////////////////
    4675     case CLEANUP_HEAP_SEARCH:
    4676     {
    4677       // This state is handling the case where the copy
    4678       // is in the heap, but is not the first in the linked list
    4679       if(r_alloc_heap_fsm.read() != ALLOC_HEAP_CLEANUP)
    4680       {
    4681         std::cout
    4682             << "VCI_MEM_CACHE ERROR " << name()
    4683             << " CLEANUP_HEAP_SEARCH state"
    4684             << " bad HEAP allocation" << std::endl;
    4685 
    4686         exit(0);
    4687       }
    4688 
    4689       HeapEntry heap_entry  = m_heap.read(r_cleanup_next_ptr.read());
    4690 
    4691       bool last             = (heap_entry.next        == r_cleanup_next_ptr.read());
    4692       bool match_heap_srcid = (heap_entry.owner.srcid == r_cleanup_srcid.read());
    4693       bool match_heap_inst  = (heap_entry.owner.inst  == r_cleanup_inst.read());
    4694       bool match_heap       = match_heap_srcid and match_heap_inst;
    4695 
    4696 #if L1_MULTI_CACHE
    4697       match_heap = match_heap and(heap_entry.owner.cache_id == r_cleanup_pktid.read());
    4698 #endif
    4699 
    4700       if(not match_heap and last)
    4701       {
    4702         std::cout
    4703             << "VCI_MEM_CACHE_ERROR " << name()
    4704             << " CLEANUP_HEAP_SEARCH state"
    4705             << " cleanup on valid line but copy not found"
    4706             << std::endl;
    4707 
    4708         exit(0);
    4709       }
    4710 
    4711       // the matching copy must be removed
    4712       if(match_heap)
    4713       {
    4714         // re-use ressources
    4715         r_cleanup_ptr = heap_entry.next;
    4716         r_cleanup_fsm = CLEANUP_HEAP_CLEAN;
    4717       }
    4718       // test the next in the linked list
    4719       else
    4720       {
    4721         r_cleanup_prev_ptr      = r_cleanup_next_ptr.read();
    4722         r_cleanup_prev_srcid    = heap_entry.owner.srcid;
    4723         r_cleanup_prev_inst     = heap_entry.owner.inst;
    4724         r_cleanup_next_ptr      = heap_entry.next;
    4725 
    4726         r_cleanup_fsm           = CLEANUP_HEAP_SEARCH;
    4727 
    4728 #if L1_MULTI_CACHE
    4729         r_cleanup_prev_cache_id = heap_entry.owner.cache_id;
    4730 #endif
    4731       }
     4650if(m_debug)
     4651std::cout << "  <MEMC " << name()
     4652          << " CLEANUP_HEAP_LOCK> Checks matching:"
     4653          << " address = "      << r_cleanup_nline.read() * m_words * 4
     4654          << " / dir_id = "     << r_cleanup_copy.read()
     4655          << " / dir_ins = "    << r_cleanup_copy_inst.read()
     4656          << " / heap_id = "    << heap_entry.owner.srcid
     4657          << " / heap_ins = "   << heap_entry.owner.inst
     4658          << " / search_id = "  << r_cleanup_srcid.read()
     4659          << " / search_ins = " << r_cleanup_inst.read() << std::endl;
     4660#endif
     4661          break;
     4662      }
     4663      ////////////////////////
     4664      case CLEANUP_HEAP_SEARCH:     // This state is handling the case where the copy
     4665                                    // is in the heap, but not the first in linked list
     4666      {
     4667          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP) and
     4668          "MEMC ERROR in CLEANUP_HEAP_LOCK state: bad HEAP allocation");
     4669
     4670          HeapEntry heap_entry  = m_heap.read(r_cleanup_next_ptr.read());
     4671
     4672          bool last             = (heap_entry.next        == r_cleanup_next_ptr.read());
     4673          bool match_heap_srcid = (heap_entry.owner.srcid == r_cleanup_srcid.read());
     4674          bool match_heap_inst  = (heap_entry.owner.inst  == r_cleanup_inst.read());
     4675          bool match_heap       = match_heap_srcid and match_heap_inst;
     4676
     4677          assert( (not last or match_heap) and
     4678          "MEMC ERROR in CLEANUP_HEAP_SEARCH state: no copy found");
     4679
     4680          // the matching copy must be removed
     4681          if(match_heap)
     4682          {
     4683              // re-use ressources
     4684              r_cleanup_ptr = heap_entry.next;
     4685              r_cleanup_fsm = CLEANUP_HEAP_CLEAN;
     4686          }
     4687          // test the next in the linked list
     4688          else
     4689          {
     4690              r_cleanup_prev_ptr      = r_cleanup_next_ptr.read();
     4691              r_cleanup_prev_srcid    = heap_entry.owner.srcid;
     4692              r_cleanup_prev_inst     = heap_entry.owner.inst;
     4693              r_cleanup_next_ptr      = heap_entry.next;
     4694              r_cleanup_fsm           = CLEANUP_HEAP_SEARCH;
     4695          }
    47324696
    47334697#if DEBUG_MEMC_CLEANUP
    4734       if(m_debug)
    4735       {
     4698if(m_debug)
     4699{
    47364700        if(not match_heap)
    47374701        {
     
    47484712              << std::endl;
    47494713        }
    4750 
    47514714        std::cout
    47524715            << " address = "      << r_cleanup_nline.read() * m_words * 4
     
    47574720            << " / last = "       << last
    47584721            << std::endl;
    4759       }
    4760 #endif
    4761       break;
    4762     }
    4763     ////////////////////////
    4764     case CLEANUP_HEAP_CLEAN:    // remove a copy in the linked list
    4765     {
    4766       if(r_alloc_heap_fsm.read() != ALLOC_HEAP_CLEANUP)
    4767       {
    4768         std::cout
    4769             << "VCI_MEM_CACHE ERROR " << name()
    4770             << " CLEANUP_HEAP_CLEAN state"
    4771             << "Bad HEAP allocation"  << std::endl;
    4772 
    4773         exit(0);
    4774       }
    4775 
    4776       HeapEntry heap_entry;
    4777       heap_entry.owner.srcid    = r_cleanup_prev_srcid.read();
    4778       heap_entry.owner.inst     = r_cleanup_prev_inst.read();
    4779 
    4780 #if L1_MULTI_CACHE
    4781       heap_entry.owner.cache_id = r_cleanup_prev_cache_id.read();
    4782 #endif
    4783 
    4784       bool last = (r_cleanup_next_ptr.read() == r_cleanup_ptr.read());
    4785 
    4786       // this is the last entry of the list of copies
    4787       if(last)
    4788       {
    4789         heap_entry.next = r_cleanup_prev_ptr.read();
    4790       }
    4791       // this is not the last entry
    4792       else
    4793       {
    4794         heap_entry.next = r_cleanup_ptr.read();
    4795       }
    4796 
    4797       m_heap.write(r_cleanup_prev_ptr.read(), heap_entry);
    4798 
    4799       r_cleanup_fsm = CLEANUP_HEAP_FREE;
     4722}
     4723#endif
     4724          break;
     4725      }
     4726      ////////////////////////
     4727      case CLEANUP_HEAP_CLEAN:    // remove a copy in the linked list
     4728      {
     4729          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP) and
     4730          "MEMC ERROR in CLEANUP_HEAP_LOCK state: bad HEAP allocation");
     4731
     4732          HeapEntry heap_entry;
     4733          heap_entry.owner.srcid    = r_cleanup_prev_srcid.read();
     4734          heap_entry.owner.inst     = r_cleanup_prev_inst.read();
     4735          bool last = (r_cleanup_next_ptr.read() == r_cleanup_ptr.read());
     4736
     4737          if (last)     // this is the last entry of the list of copies
     4738          {
     4739              heap_entry.next = r_cleanup_prev_ptr.read();
     4740          }
     4741          else          // this is not the last entry
     4742          {
     4743              heap_entry.next = r_cleanup_ptr.read();
     4744          }
     4745
     4746          m_heap.write(r_cleanup_prev_ptr.read(), heap_entry);
     4747
     4748          r_cleanup_fsm = CLEANUP_HEAP_FREE;
    48004749
    48014750#if DEBUG_MEMC_CLEANUP
     
    48044753          << " Remove the copy in the linked list" << std::endl;
    48054754#endif
    4806       break;
    4807     }
    4808     ///////////////////////
    4809     case CLEANUP_HEAP_FREE:   // The heap entry pointed by r_cleanup_next_ptr is freed
    4810                               // and becomes the head of the list of free entries
    4811     {
    4812       if(r_alloc_heap_fsm.read() != ALLOC_HEAP_CLEANUP)
    4813       {
    4814         std::cout
    4815             << "VCI_MEM_CACHE ERROR " << name()
    4816             << " CLEANUP_HEAP_CLEAN state" << std::endl
    4817             << "Bad HEAP allocation" << std::endl;
    4818 
    4819         exit(0);
    4820       }
    4821 
    4822       HeapEntry heap_entry;
    4823       heap_entry.owner.srcid    = 0;
    4824       heap_entry.owner.inst     = false;
    4825 
    4826 #if L1_MULTI_CACHE
    4827       heap_entry.owner.cache_id = 0;
    4828 #endif
    4829 
    4830       if(m_heap.is_full())
    4831       {
    4832         heap_entry.next = r_cleanup_next_ptr.read();
    4833       }
    4834       else
    4835       {
    4836         heap_entry.next = m_heap.next_free_ptr();
    4837       }
    4838 
    4839       m_heap.write(r_cleanup_next_ptr.read(),heap_entry);
    4840       m_heap.write_free_ptr(r_cleanup_next_ptr.read());
    4841       m_heap.unset_full();
    4842 
    4843       r_cleanup_fsm = CLEANUP_SEND_CLACK;
     4755          break;
     4756      }
     4757      ///////////////////////
     4758      case CLEANUP_HEAP_FREE:   // The heap entry pointed by r_cleanup_next_ptr is freed
     4759                                // and becomes the head of the list of free entries
     4760      {
     4761          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP) and
     4762          "MEMC ERROR in CLEANUP_HEAP_LOCK state: bad HEAP allocation");
     4763
     4764          HeapEntry heap_entry;
     4765          heap_entry.owner.srcid    = 0;
     4766          heap_entry.owner.inst     = false;
     4767
     4768          if(m_heap.is_full())
     4769          {
     4770              heap_entry.next = r_cleanup_next_ptr.read();
     4771          }
     4772          else
     4773          {
     4774              heap_entry.next = m_heap.next_free_ptr();
     4775          }
     4776
     4777          m_heap.write(r_cleanup_next_ptr.read(),heap_entry);
     4778          m_heap.write_free_ptr(r_cleanup_next_ptr.read());
     4779          m_heap.unset_full();
     4780
     4781          r_cleanup_fsm = CLEANUP_SEND_CLACK;
    48444782
    48454783#if DEBUG_MEMC_CLEANUP
     
    48484786          << " Update the list of free entries" << std::endl;
    48494787#endif
     4788          break;
     4789      }
     4790      //////////////////////
     4791      case CLEANUP_IVT_LOCK:   // get the lock protecting the IVT to search a pending
     4792                               // invalidate transaction matching the cleanup
     4793      {
     4794          if(r_alloc_ivt_fsm.read() != ALLOC_IVT_CLEANUP) break;
     4795
     4796          size_t index = 0;
     4797          bool   match_inval;
     4798
     4799          match_inval = m_ivt.search_inval(r_cleanup_nline.read(), index);
     4800
     4801          if ( not match_inval )     // no pending inval in IVT
     4802          {
     4803              r_cleanup_fsm = CLEANUP_SEND_CLACK;
     4804
     4805#if DEBUG_MEMC_CLEANUP
     4806if(m_debug)
     4807std::cout << "  <MEMC " << name() << " CLEANUP_IVT_LOCK>"
     4808          << " Unexpected cleanup with no corresponding IVT entry:"
     4809          << " address = " << std::hex << (r_cleanup_nline.read()*4*m_words) << std::endl;
     4810#endif
     4811          }
     4812          else                     // pending inval in IVT
     4813          {
     4814              r_cleanup_write_srcid = m_ivt.srcid(index);
     4815              r_cleanup_write_trdid = m_ivt.trdid(index);
     4816              r_cleanup_write_pktid = m_ivt.pktid(index);
     4817              r_cleanup_need_rsp    = m_ivt.need_rsp(index);
     4818              r_cleanup_need_ack    = m_ivt.need_ack(index);
     4819              r_cleanup_index       = index;
     4820              r_cleanup_fsm         = CLEANUP_IVT_DECREMENT;
     4821
     4822#if DEBUG_MEMC_CLEANUP
     4823if(m_debug)
     4824std::cout << "  <MEMC " << name() << " CLEANUP_IVT_LOCK>"
     4825          << " Cleanup matching pending invalidate transaction on IVT:"
     4826          << " address = " << std::hex << (r_cleanup_nline.read()*m_words*4)
     4827          << " / ivt_entry = " << index << std::endl;
     4828#endif
     4829          }
    48504830      break;
    4851     }
    4852     //////////////////////
    4853     case CLEANUP_IVT_LOCK:   // get the lock protecting the IVT to search a pending
    4854                              // invalidate transaction matching the cleanup
    4855     {
    4856       if(r_alloc_ivt_fsm.read() != ALLOC_IVT_CLEANUP) break;
    4857 
    4858       size_t index = 0;
    4859       bool   match_inval;
    4860 
    4861       match_inval = m_ivt.search_inval(r_cleanup_nline.read(), index);
    4862 
    4863       if ( not match_inval )     // no pending inval
    4864       {
    4865           r_cleanup_fsm = CLEANUP_SEND_CLACK;
    4866 
    4867 #if DEBUG_MEMC_CLEANUP
    4868 if(m_debug)
    4869 std::cout << "  <MEMC " << name()
    4870           << " CLEANUP_IVT_LOCK> Unexpected cleanup"
    4871           << " with no corresponding IVT entry:"
    4872           << " address = " << std::hex
    4873           << (r_cleanup_nline.read() *4*m_words)
    4874           << std::endl;
    4875 #endif
    4876           break;
    4877       }
    4878 
    4879       // pending inval
    4880       r_cleanup_write_srcid = m_ivt.srcid(index);
    4881       r_cleanup_write_trdid = m_ivt.trdid(index);
    4882       r_cleanup_write_pktid = m_ivt.pktid(index);
    4883       r_cleanup_need_rsp    = m_ivt.need_rsp(index);
    4884       r_cleanup_need_ack    = m_ivt.need_ack(index);
    4885       r_cleanup_index       = index;
    4886 
    4887       r_cleanup_fsm         = CLEANUP_IVT_DECREMENT;
    4888 
    4889 #if DEBUG_MEMC_CLEANUP
    4890 if(m_debug)
    4891 std::cout << "  <MEMC " << name()
    4892           << " CLEANUP_IVT_LOCK> Cleanup matching pending"
    4893           << " invalidate transaction on IVT:"
    4894           << " address = " << std::hex << r_cleanup_nline.read() * m_words * 4
    4895           << " / ivt_entry = " << index << std::endl;
    4896 #endif
    4897       break;
    4898     }
    4899     ///////////////////////////
    4900     case CLEANUP_IVT_DECREMENT: // decrement response counter in IVT matching entry
    4901     {
    4902       if(r_alloc_ivt_fsm.read() != ALLOC_IVT_CLEANUP)
    4903       {
    4904         std::cout
    4905             << "VCI_MEM_CACHE ERROR "         << name()
    4906             << " CLEANUP_IVT_DECREMENT state" << std::endl
    4907             << "Bad IVT allocation"
    4908             << std::endl;
    4909 
    4910         exit(0);
    4911       }
    4912 
    4913       size_t count = 0;
    4914       m_ivt.decrement(r_cleanup_index.read(), count);
    4915 
    4916       if(count == 0)   // multi inval transaction completed
    4917       {
    4918         r_cleanup_fsm = CLEANUP_IVT_CLEAR;
    4919       }
    4920       else             // multi inval transaction not completed
    4921       {
    4922         r_cleanup_fsm = CLEANUP_SEND_CLACK ;
    4923       }
     4831      }
     4832      ///////////////////////////
     4833      case CLEANUP_IVT_DECREMENT: // decrement response counter in IVT matching entry
     4834                                  // and test if last
     4835      {
     4836          assert( (r_alloc_ivt_fsm.read() == ALLOC_IVT_CLEANUP) and
     4837          "MEMC ERROR in CLEANUP_IVT_DECREMENT state: Bad IVT allocation");
     4838
     4839          size_t count = 0;
     4840          m_ivt.decrement(r_cleanup_index.read(), count);
     4841
     4842          if(count == 0)  r_cleanup_fsm = CLEANUP_IVT_CLEAR;
     4843          else            r_cleanup_fsm = CLEANUP_SEND_CLACK ;
    49244844
    49254845#if DEBUG_MEMC_CLEANUP
     
    49274847std::cout << "  <MEMC " << name() << " CLEANUP_IVT_DECREMENT>"
    49284848          << " Decrement response counter in IVT:"
    4929             << " IVT_index = " << r_cleanup_index.read()
    4930             << " / rsp_count = " << count << std::endl;
    4931 #endif
    4932       break;
    4933     }
    4934     ///////////////////////
    4935     case CLEANUP_IVT_CLEAR:    // Clear IVT entry
    4936     {
    4937       if(r_alloc_ivt_fsm.read() != ALLOC_IVT_CLEANUP)
    4938       {
    4939         std::cout
    4940             << "VCI_MEM_CACHE ERROR "     << name()
    4941             << " CLEANUP_IVT_CLEAR state" << std::endl
    4942             << "Bad IVT allocation"
    4943             << std::endl;
    4944 
    4945         exit(0);
    4946       }
    4947 
    4948       m_ivt.clear(r_cleanup_index.read());
    4949 
    4950       if      ( r_cleanup_need_rsp.read() ) r_cleanup_fsm = CLEANUP_WRITE_RSP;
    4951       else if ( r_cleanup_need_ack.read() ) r_cleanup_fsm = CLEANUP_CONFIG_ACK;
    4952       else                                  r_cleanup_fsm = CLEANUP_SEND_CLACK;
     4849          << " IVT_index = " << r_cleanup_index.read()
     4850          << " / rsp_count = " << count << std::endl;
     4851#endif
     4852          break;
     4853      }
     4854      ///////////////////////
     4855      case CLEANUP_IVT_CLEAR:    // Clear IVT entry
     4856                                 // Acknowledge CONFIG FSM if required
     4857      {
     4858          assert( (r_alloc_ivt_fsm.read() == ALLOC_IVT_CLEANUP) and
     4859          "MEMC ERROR in CLEANUP_IVT_CLEAR state : bad IVT allocation");
     4860
     4861          m_ivt.clear(r_cleanup_index.read());
     4862
     4863          if ( r_cleanup_need_ack.read() )
     4864          {
     4865              assert( (r_config_rsp_lines.read() > 0) and
     4866              "MEMC ERROR in CLEANUP_IVT_CLEAR state");
     4867   
     4868              r_config_rsp_lines = r_config_rsp_lines.read() - 1;
     4869          }
     4870
     4871          if ( r_cleanup_need_rsp.read() ) r_cleanup_fsm = CLEANUP_WRITE_RSP;
     4872          else                             r_cleanup_fsm = CLEANUP_SEND_CLACK;
    49534873
    49544874#if DEBUG_MEMC_CLEANUP
     
    49584878          << " IVT_index = " << r_cleanup_index.read() << std::endl;
    49594879#endif
    4960       break;
    4961     }
    4962     ///////////////////////
    4963     case CLEANUP_WRITE_RSP:    // response to a previous write on the direct network
     4880          break;
     4881      }
     4882      ///////////////////////
     4883      case CLEANUP_WRITE_RSP:    // response to a previous write on the direct network
    49644884                               // wait if pending request to the TGT_RSP FSM
    4965     {
    4966       if(r_cleanup_to_tgt_rsp_req.read()) break;
    4967 
    4968       // no pending request
    4969       r_cleanup_to_tgt_rsp_req     = true;
    4970       r_cleanup_to_tgt_rsp_srcid   = r_cleanup_write_srcid.read();
    4971       r_cleanup_to_tgt_rsp_trdid   = r_cleanup_write_trdid.read();
    4972       r_cleanup_to_tgt_rsp_pktid   = r_cleanup_write_pktid.read();
    4973 
    4974       r_cleanup_fsm                = CLEANUP_SEND_CLACK;
     4885      {
     4886          if(r_cleanup_to_tgt_rsp_req.read()) break;
     4887
     4888          // no pending request
     4889          r_cleanup_to_tgt_rsp_req     = true;
     4890          r_cleanup_to_tgt_rsp_srcid   = r_cleanup_write_srcid.read();
     4891          r_cleanup_to_tgt_rsp_trdid   = r_cleanup_write_trdid.read();
     4892          r_cleanup_to_tgt_rsp_pktid   = r_cleanup_write_pktid.read();
     4893          r_cleanup_fsm                = CLEANUP_SEND_CLACK;
    49754894
    49764895#if DEBUG_MEMC_CLEANUP
     
    49824901          << " / rpktid = " << r_cleanup_write_pktid.read() << std::endl;
    49834902#endif
    4984       break;
    4985     }
    4986     ////////////////////////
    4987     case CLEANUP_CONFIG_ACK:   // signals inval completion to CONFIG FSM
    4988                                // wait if pending request
    4989     {
    4990       if ( r_cleanup_to_config_ack.read() ) break;
    4991 
    4992       r_cleanup_to_config_ack      = true;
    4993       r_cleanup_fsm                = CLEANUP_SEND_CLACK;
    4994 
    4995 #if DEBUG_MEMC_CLEANUP
    4996 if(m_debug)
    4997 std::cout << "  <MEMC " << name() << " CLEANUP_CONFIG_ACK>"
    4998           << " Acknowledge broacast inval completion" << std::endl;
    4999 #endif
    5000       break;
    5001     }
    5002     ////////////////////////
    5003     case CLEANUP_SEND_CLACK:  // acknowledgement to a cleanup command
    5004                               // on the coherence CLACK network.
    5005     {
    5006       if(not p_dspin_clack.read) break;
    5007 
    5008       r_cleanup_fsm = CLEANUP_IDLE;
     4903          break;
     4904      }
     4905      ////////////////////////
     4906      case CLEANUP_SEND_CLACK:  // acknowledgement to a cleanup command
     4907                                // on the coherence CLACK network.
     4908      {
     4909          if(not p_dspin_clack.read) break;
     4910
     4911          r_cleanup_fsm = CLEANUP_IDLE;
    50094912
    50104913#if DEBUG_MEMC_CLEANUP
     
    50124915std::cout << "  <MEMC " << name()
    50134916          << " CLEANUP_SEND_CLACK> Send the response to a cleanup request:"
    5014           << " nline = "   << std::hex << r_cleanup_nline.read()
     4917          << " address = "   << std::hex << r_cleanup_nline.read()*m_words*4
    50154918          << " / way = "   << std::dec << r_cleanup_way.read()
    50164919          << " / srcid = " << std::dec << r_cleanup_srcid.read()
    50174920          << std::endl;
    50184921#endif
    5019       break;
    5020     }
     4922          break;
     4923      }
    50214924  } // end switch cleanup fsm
    50224925
     
    50244927  //    CAS FSM
    50254928  ////////////////////////////////////////////////////////////////////////////////////
    5026   // The CAS FSM handles the CAS (Store Conditionnal) atomic commands,
    5027   // that are handled as "compare-and-swap instructions.
     4929  // The CAS FSM handles the CAS (Compare And Swap) atomic commands.
    50284930  //
    50294931  // This command contains two or four flits:
    50304932  // - In case of 32 bits atomic access, the first flit contains the value read
    5031   // by a previous LL instruction, the second flit contains the value to be writen.
     4933  // by a previous READ instruction, the second flit contains the value to be writen.
    50324934  // - In case of 64 bits atomic access, the 2 first flits contains the value read
    5033   // by a previous LL instruction, the 2 next flits contains the value to be writen.
     4935  // by a previous READ instruction, the 2 next flits contains the value to be writen.
    50344936  //
    50354937  // The target address is cachable. If it is replicated in other L1 caches
     
    50384940  // It access the directory to check hit / miss.
    50394941  // - In case of miss, the CAS FSM must register a GET transaction in TRT.
    5040   // If a read transaction to the XRAM for this line already exists,
    5041   // or if the transaction table is full, it goes to the WAIT state
    5042   // to release the locks and try again. When the GET transaction has been
    5043   // launched, it goes to the WAIT state and try again.
    5044   // The CAS request is not consumed in the FIFO until a HIT is obtained.
     4942  //   If a read transaction to the XRAM for this line already exists,
     4943  //   or if the transaction table is full, it goes to the WAIT state
     4944  //   to release the locks and try again. When the GET transaction has been
     4945  //   launched, it goes to the WAIT state and try again.
     4946  //   The CAS request is not consumed in the FIFO until a HIT is obtained.
    50454947  // - In case of hit...
    50464948  ///////////////////////////////////////////////////////////////////////////////////
    50474949
     4950//std::cout << std::endl << "cas_fsm" << std::endl;
     4951
    50484952  switch(r_cas_fsm.read())
    50494953  {
    5050       /////////////
     4954    ////////////
    50514955    case CAS_IDLE:     // fill the local rdata buffers
    50524956    {
    5053       if(m_cmd_cas_addr_fifo.rok())
    5054       {
     4957        if (m_cmd_cas_addr_fifo.rok() )
     4958        {
    50554959
    50564960#if DEBUG_MEMC_CAS
    5057         if(m_debug)
    5058         {
    5059           std::cout << "  <MEMC " << name() << " CAS_IDLE> CAS command: " << std::hex
    5060                     << " srcid = " <<  std::dec << m_cmd_cas_srcid_fifo.read()
    5061                     << " addr = " << std::hex << m_cmd_cas_addr_fifo.read()
    5062                     << " wdata = " << m_cmd_cas_wdata_fifo.read()
    5063                     << " eop = " << std::dec << m_cmd_cas_eop_fifo.read()
    5064                     << " cpt  = " << std::dec << r_cas_cpt.read() << std::endl;
    5065         }
    5066 #endif
    5067         if(m_cmd_cas_eop_fifo.read())
    5068         {
    5069           m_cpt_cas++;
    5070           r_cas_fsm = CAS_DIR_REQ;
    5071         }
    5072         else  // we keep the last word in the FIFO
    5073         {
    5074           cmd_cas_fifo_get = true;
    5075         }
    5076         // We fill the two buffers
    5077         if(r_cas_cpt.read() < 2)    // 32 bits access
    5078           r_cas_rdata[r_cas_cpt.read()] = m_cmd_cas_wdata_fifo.read();
    5079 
    5080         if((r_cas_cpt.read() == 1) and m_cmd_cas_eop_fifo.read())
    5081           r_cas_wdata = m_cmd_cas_wdata_fifo.read();
    5082 
    5083         if(r_cas_cpt.read() >3)  // more than 4 flits...
    5084         {
    5085           std::cout << "VCI_MEM_CACHE ERROR in CAS_IDLE state : illegal CAS command"
    5086                     << std::endl;
    5087           exit(0);
    5088         }
    5089 
    5090         if(r_cas_cpt.read() ==2)
    5091           r_cas_wdata = m_cmd_cas_wdata_fifo.read();
    5092 
    5093         r_cas_cpt = r_cas_cpt.read() +1;
    5094       }
    5095       break;
    5096     }
    5097 
     4961if(m_debug)
     4962std::cout << "  <MEMC " << name() << " CAS_IDLE> CAS command: " << std::hex
     4963          << " srcid = " <<  std::dec << m_cmd_cas_srcid_fifo.read()
     4964          << " addr = " << std::hex << m_cmd_cas_addr_fifo.read()
     4965          << " wdata = " << m_cmd_cas_wdata_fifo.read()
     4966          << " eop = " << std::dec << m_cmd_cas_eop_fifo.read()
     4967          << " cpt  = " << std::dec << r_cas_cpt.read() << std::endl;
     4968#endif
     4969            if(m_cmd_cas_eop_fifo.read())
     4970            {
     4971                m_cpt_cas++;
     4972                r_cas_fsm = CAS_DIR_REQ;
     4973            }
     4974            else  // we keep the last word in the FIFO
     4975            {
     4976                cmd_cas_fifo_get = true;
     4977            }
     4978
     4979            // We fill the two buffers
     4980            if(r_cas_cpt.read() < 2)    // 32 bits access
     4981                r_cas_rdata[r_cas_cpt.read()] = m_cmd_cas_wdata_fifo.read();
     4982
     4983            if((r_cas_cpt.read() == 1) and m_cmd_cas_eop_fifo.read())
     4984                r_cas_wdata = m_cmd_cas_wdata_fifo.read();
     4985
     4986            assert( (r_cas_cpt.read() <= 3) and  // no more than 4 flits...
     4987            "MEMC ERROR in CAS_IDLE state: illegal CAS command");
     4988
     4989            if(r_cas_cpt.read() ==2)
     4990                r_cas_wdata = m_cmd_cas_wdata_fifo.read();
     4991
     4992            r_cas_cpt = r_cas_cpt.read() +1;
     4993        }
     4994        break;
     4995    }
    50984996    /////////////////
    50994997    case CAS_DIR_REQ:
    51004998    {
    5101       if(r_alloc_dir_fsm.read() == ALLOC_DIR_CAS)
    5102       {
    5103         r_cas_fsm = CAS_DIR_LOCK;
    5104       }
     4999        if(r_alloc_dir_fsm.read() == ALLOC_DIR_CAS)
     5000        {
     5001            r_cas_fsm = CAS_DIR_LOCK;
     5002        }
    51055003
    51065004#if DEBUG_MEMC_CAS
    5107       if(m_debug)
    5108       {
    5109         std::cout
    5110             << "  <MEMC " << name() << " CAS_DIR_REQ> Requesting DIR lock "
    5111             << std::endl;
    5112       }
    5113 #endif
    5114       break;
    5115     }
    5116 
     5005if(m_debug)
     5006std::cout << "  <MEMC " << name() << " CAS_DIR_REQ> Requesting DIR lock " << std::endl;
     5007#endif
     5008        break;
     5009    }
    51175010    /////////////////
    51185011    case CAS_DIR_LOCK:  // Read the directory
    51195012    {
    5120       if(r_alloc_dir_fsm.read() == ALLOC_DIR_CAS)
    5121       {
     5013        assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CAS) and
     5014        "MEMC ERROR in CAS_DIR_LOCK: Bad DIR allocation");
     5015
    51225016        size_t way = 0;
    51235017        DirectoryEntry entry(m_cache_directory.read(m_cmd_cas_addr_fifo.read(), way));
     
    51285022        r_cas_way        = way;
    51295023        r_cas_copy       = entry.owner.srcid;
    5130 #if L1_MULTI_CACHE
    5131         r_cas_copy_cache = entry.owner.cache_id;
    5132 #endif
    51335024        r_cas_copy_inst  = entry.owner.inst;
    51345025        r_cas_ptr        = entry.ptr;
     
    51395030
    51405031#if DEBUG_MEMC_CAS
    5141         if(m_debug)
    5142         {
    5143           std::cout << "  <MEMC " << name() << " CAS_DIR_LOCK> Directory acces"
    5144                     << " / address = " << std::hex << m_cmd_cas_addr_fifo.read()
    5145                     << " / hit = " << std::dec << entry.valid
    5146                     << " / count = " << entry.count
    5147                     << " / is_cnt = " << entry.is_cnt << std::endl;
    5148         }
    5149 #endif
    5150       }
    5151       else
    5152       {
    5153         std::cout
    5154             << "VCI_MEM_CACHE ERROR " << name()
    5155             << " CAS_DIR_LOCK state" << std::endl
    5156             << "Bad DIR allocation"   << std::endl;
    5157 
    5158         exit(0);
    5159       }
    5160 
    5161       break;
     5032if(m_debug)
     5033std::cout << "  <MEMC " << name() << " CAS_DIR_LOCK> Directory acces"
     5034          << " / address = " << std::hex << m_cmd_cas_addr_fifo.read()
     5035          << " / hit = " << std::dec << entry.valid
     5036          << " / count = " << entry.count
     5037          << " / is_cnt = " << entry.is_cnt << std::endl;
     5038#endif
     5039
     5040        break;
    51625041    }
    51635042    /////////////////////
     
    51655044                            // and check data change in cache
    51665045    {
    5167       size_t way  = r_cas_way.read();
    5168       size_t set  = m_y[(addr_t)(m_cmd_cas_addr_fifo.read())];
    5169 
    5170       // update directory (lock & dirty bits)
    5171       DirectoryEntry entry;
    5172       entry.valid          = true;
    5173       entry.is_cnt         = r_cas_is_cnt.read();
    5174       entry.dirty          = true;
    5175       entry.lock           = true;
    5176       entry.tag            = r_cas_tag.read();
    5177       entry.owner.srcid    = r_cas_copy.read();
    5178 #if L1_MULTI_CACHE
    5179       entry.owner.cache_id = r_cas_copy_cache.read();
    5180 #endif
    5181       entry.owner.inst     = r_cas_copy_inst.read();
    5182       entry.count          = r_cas_count.read();
    5183       entry.ptr            = r_cas_ptr.read();
    5184 
    5185       m_cache_directory.write(set, way, entry);
    5186 
    5187       // Stored data from cache in buffer to do the comparison in next state
    5188       m_cache_data.read_line(way, set, r_cas_data);
    5189 
    5190       r_cas_fsm = CAS_DIR_HIT_COMPARE;
     5046        assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CAS) and
     5047        "MEMC ERROR in CAS_DIR_HIT_READ: Bad DIR allocation");
     5048
     5049        size_t way  = r_cas_way.read();
     5050        size_t set  = m_y[(addr_t)(m_cmd_cas_addr_fifo.read())];
     5051
     5052        // update directory (lock & dirty bits)
     5053        DirectoryEntry entry;
     5054        entry.valid          = true;
     5055        entry.is_cnt         = r_cas_is_cnt.read();
     5056        entry.dirty          = true;
     5057        entry.lock           = true;
     5058        entry.tag            = r_cas_tag.read();
     5059        entry.owner.srcid    = r_cas_copy.read();
     5060        entry.owner.inst     = r_cas_copy_inst.read();
     5061        entry.count          = r_cas_count.read();
     5062        entry.ptr            = r_cas_ptr.read();
     5063
     5064        m_cache_directory.write(set, way, entry);
     5065
     5066        // Store data from cache in buffer to do the comparison in next state
     5067        m_cache_data.read_line(way, set, r_cas_data);
     5068
     5069        r_cas_fsm = CAS_DIR_HIT_COMPARE;
    51915070
    51925071#if DEBUG_MEMC_CAS
     
    51955074          << " cache and store it in buffer" << std::endl;
    51965075#endif
    5197       break;
    5198     }
    5199 
     5076        break;
     5077    }
     5078    ////////////////////////
    52005079    case CAS_DIR_HIT_COMPARE:
    52015080    {
    5202       size_t word = m_x[(addr_t)(m_cmd_cas_addr_fifo.read())];
    5203 
    5204       // Read data in buffer & check data change
     5081        size_t word = m_x[(addr_t)(m_cmd_cas_addr_fifo.read())];
     5082
     5083        // check data change
    52055084      bool ok = (r_cas_rdata[0].read() == r_cas_data[word].read());
    52065085
     
    52125091      r_cas_lfsr = (r_cas_lfsr >> 1) ^ ((- (r_cas_lfsr & 1)) & 0xd0000001);
    52135092
    5214       // cas success
    5215       if(ok and not forced_fail)
    5216       {
    5217         r_cas_fsm = CAS_DIR_HIT_WRITE;
    5218       }
    5219       // cas failure
    5220       else
    5221       {
    5222         r_cas_fsm = CAS_RSP_FAIL;
    5223       }
     5093      if(ok and not forced_fail) r_cas_fsm = CAS_DIR_HIT_WRITE;
     5094      else                       r_cas_fsm = CAS_RSP_FAIL;
    52245095
    52255096#if DEBUG_MEMC_CAS
    52265097if(m_debug)
    5227 std::cout << "  <MEMC " << name() << " CAS_DIR_HIT_COMPARE> Compare the old"
    5228           << " and the new data"
    5229           << " / expected value = " << r_cas_rdata[0].read()
    5230           << " / actual value = "   << r_cas_data[word].read()
    5231           << " / forced_fail = "    << forced_fail << std::endl;
     5098std::cout << "  <MEMC " << name() << " CAS_DIR_HIT_COMPARE> Compare old and new data"
     5099          << " / expected value = " << std::hex << r_cas_rdata[0].read()
     5100          << " / actual value = "   << std::hex << r_cas_data[word].read()
     5101          << " / forced_fail = "    << std::dec << forced_fail << std::endl;
    52325102#endif
    52335103      break;
     
    52355105    //////////////////////
    52365106    case CAS_DIR_HIT_WRITE:    // test if a CC transaction is required
    5237       // write data in cache if no CC request
    5238     {
    5239       // The CAS is a success => sw access to the llsc_global_table
    5240       m_llsc_table.sw(m_nline[(addr_t)m_cmd_cas_addr_fifo.read()],m_x[(addr_t)(m_cmd_cas_addr_fifo.read())],m_x[(addr_t)(m_cmd_cas_addr_fifo.read())]);
    5241 
    5242       // test coherence request
    5243       if(r_cas_count.read())   // replicated line
    5244       {
    5245         if(r_cas_is_cnt.read())
    5246         {
    5247           r_cas_fsm = CAS_BC_TRT_LOCK;    // broadcast invalidate required
    5248         }
    5249         else if(!r_cas_to_cc_send_multi_req.read() and
    5250                 !r_cas_to_cc_send_brdcast_req.read())
    5251         {
    5252           r_cas_fsm = CAS_UPT_LOCK;       // multi update required
    5253         }
    5254         else
    5255         {
    5256           r_cas_fsm = CAS_WAIT;
    5257         }
    5258       }
    5259       else                    // no copies
    5260       {
    5261         size_t way  = r_cas_way.read();
    5262         size_t set  = m_y[(addr_t)(m_cmd_cas_addr_fifo.read())];
    5263         size_t word = m_x[(addr_t)(m_cmd_cas_addr_fifo.read())];
    5264 
    5265         // cache update
    5266         m_cache_data.write(way, set, word, r_cas_wdata.read());
    5267         if(r_cas_cpt.read() == 4)
    5268           m_cache_data.write(way, set, word+1, m_cmd_cas_wdata_fifo.read());
    5269 
    5270         r_cas_fsm = CAS_RSP_SUCCESS;
    5271 
    5272         // monitor
    5273         if(m_monitor_ok)
    5274         {
    5275           addr_t address = m_cmd_cas_addr_fifo.read();
    5276           check_monitor( address, r_cas_wdata.read(), false);
    5277 
    5278           if(r_cas_cpt.read() == 4)
    5279             check_monitor( address+4, m_cmd_cas_wdata_fifo.read(), false);
    5280         }
     5107                               // write data in cache if no CC request
     5108    {
     5109        assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CAS) and
     5110        "MEMC ERROR in CAS_DIR_HIT_WRITE: Bad DIR allocation");
     5111
     5112        // The CAS is a success => sw access to the llsc_global_table
     5113        m_llsc_table.sw( m_nline[(addr_t)m_cmd_cas_addr_fifo.read()],
     5114                         m_x[(addr_t)(m_cmd_cas_addr_fifo.read())],
     5115                         m_x[(addr_t)(m_cmd_cas_addr_fifo.read())] );
     5116
     5117        // test coherence request
     5118        if(r_cas_count.read())   // replicated line
     5119        {
     5120</