Changeset 799


Ignore:
Timestamp:
Sep 9, 2014, 6:40:02 PM (10 years ago)
Author:
meunier
Message:

Trunk:

  • Cosmetic in vci_mem_cache
File:
1 edited

Legend:

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

    r789 r799  
    330330
    331331    tmpl(/**/)::VciMemCache(
    332             sc_module_name      name,
    333             const MappingTable  &mtp,              // mapping table for direct network
    334             const MappingTable  &mtx,              // mapping table for external network
    335             const IntTab        &srcid_x,          // global index on external network
    336             const IntTab        &tgtid_d,          // global index on direct network
    337             const size_t        x_width,           // number of x bits in platform
    338             const size_t        y_width,           // number of x bits in platform
    339             const size_t        nways,             // number of ways per set
    340             const size_t        nsets,             // number of associative sets
    341             const size_t        nwords,            // number of words in cache line
    342             const size_t        max_copies,        // max number of copies in heap
    343             const size_t        heap_size,         // number of heap entries
    344             const size_t        trt_lines,         // number of TRT entries
    345             const size_t        upt_lines,         // number of UPT entries
    346             const size_t        ivt_lines,         // number of IVT entries
    347             const size_t        debug_start_cycle,
    348             const bool          debug_ok)
     332            sc_module_name     name,
     333            const MappingTable &mtp,       // mapping table for direct network
     334            const MappingTable &mtx,       // mapping table for external network
     335            const IntTab       &srcid_x,   // global index on external network
     336            const IntTab       &tgtid_d,   // global index on direct network
     337            const size_t       x_width,    // number of x bits in platform
     338            const size_t       y_width,    // number of x bits in platform
     339            const size_t       nways,      // number of ways per set
     340            const size_t       nsets,      // number of associative sets
     341            const size_t       nwords,     // number of words in cache line
     342            const size_t       max_copies, // max number of copies in heap
     343            const size_t       heap_size,  // number of heap entries
     344            const size_t       trt_lines,  // number of TRT entries
     345            const size_t       upt_lines,  // number of UPT entries
     346            const size_t       ivt_lines,  // number of IVT entries
     347            const size_t       debug_start_cycle,
     348            const bool         debug_ok)
    349349
    350350        : soclib::caba::BaseModule(name),
    351351
    352         p_clk( "p_clk" ),
    353         p_resetn( "p_resetn" ),
    354         p_irq ( "p_irq" ),
    355         p_vci_tgt( "p_vci_tgt" ),
    356         p_vci_ixr( "p_vci_ixr" ),
    357         p_dspin_p2m( "p_dspin_p2m" ),
    358         p_dspin_m2p( "p_dspin_m2p" ),
    359         p_dspin_clack( "p_dspin_clack" ),
     352        p_clk("p_clk"),
     353        p_resetn("p_resetn"),
     354        p_irq ("p_irq"),
     355        p_vci_tgt("p_vci_tgt"),
     356        p_vci_ixr("p_vci_ixr"),
     357        p_dspin_p2m("p_dspin_p2m"),
     358        p_dspin_m2p("p_dspin_m2p"),
     359        p_dspin_clack("p_dspin_clack"),
    360360
    361361        m_seglist(mtp.getSegmentList(tgtid_d)),
    362362        m_nseg(0),
    363         m_srcid_x( mtx.indexForId(srcid_x)),
     363        m_srcid_x(mtx.indexForId(srcid_x)),
    364364        m_initiators(1 << vci_param_int::S),
    365365        m_heap_size(heap_size),
     
    394394
    395395        // CONFIG interface
    396         m_config_addr_mask((1<<12)-1),
     396        m_config_addr_mask((1 << 12) - 1),
    397397
    398398        m_config_regr_width(7),
    399399        m_config_func_width(3),
    400         m_config_regr_idx_mask((1<<m_config_regr_width)-1),
    401         m_config_func_idx_mask((1<<m_config_func_width)-1),
     400        m_config_regr_idx_mask((1 << m_config_regr_width) - 1),
     401        m_config_func_idx_mask((1 << m_config_func_width) - 1),
    402402
    403403        //  FIFOs
     
    428428        r_tgt_cmd_fsm("r_tgt_cmd_fsm"),
    429429
    430         r_config_fsm( "r_config_fsm" ),
    431 
    432         m_config_to_cc_send_inst_fifo( "m_config_to_cc_send_inst_fifo", 8 ),
    433         m_config_to_cc_send_srcid_fifo( "m_config_to_cc_send_srcid_fifo", 8 ),
    434 
    435         r_read_fsm( "r_read_fsm" ),
    436 
    437         r_write_fsm( "r_write_fsm" ),
     430        r_config_fsm("r_config_fsm"),
     431
     432        m_config_to_cc_send_inst_fifo("m_config_to_cc_send_inst_fifo", 8),
     433        m_config_to_cc_send_srcid_fifo("m_config_to_cc_send_srcid_fifo", 8),
     434
     435        r_read_fsm("r_read_fsm"),
     436
     437        r_write_fsm("r_write_fsm"),
    438438
    439439        m_write_to_cc_send_inst_fifo("m_write_to_cc_send_inst_fifo",8),
     
    471471#if MONITOR_MEMCACHE_FSM == 1
    472472        ,
    473         p_read_fsm("p_read_fsm"), 
    474         p_write_fsm("p_write_fsm"), 
    475         p_xram_rsp_fsm("p_xram_rsp_fsm"), 
    476         p_cas_fsm("p_cas_fsm"), 
    477         p_cleanup_fsm("p_cleanup_fsm"), 
    478         p_config_fsm("p_config_fsm"), 
    479         p_alloc_heap_fsm("p_alloc_heap_fsm"), 
    480         p_alloc_dir_fsm("p_alloc_dir_fsm"), 
    481         p_alloc_trt_fsm("p_alloc_trt_fsm"), 
    482         p_alloc_upt_fsm("p_alloc_upt_fsm"), 
    483         p_alloc_ivt_fsm("p_alloc_ivt_fsm"), 
    484         p_tgt_cmd_fsm("p_tgt_cmd_fsm"), 
    485         p_tgt_rsp_fsm("p_tgt_rsp_fsm"), 
    486         p_ixr_cmd_fsm("p_ixr_cmd_fsm"), 
    487         p_ixr_rsp_fsm("p_ixr_rsp_fsm"), 
    488         p_cc_send_fsm("p_cc_send_fsm"), 
     473        p_read_fsm("p_read_fsm"),
     474        p_write_fsm("p_write_fsm"),
     475        p_xram_rsp_fsm("p_xram_rsp_fsm"),
     476        p_cas_fsm("p_cas_fsm"),
     477        p_cleanup_fsm("p_cleanup_fsm"),
     478        p_config_fsm("p_config_fsm"),
     479        p_alloc_heap_fsm("p_alloc_heap_fsm"),
     480        p_alloc_dir_fsm("p_alloc_dir_fsm"),
     481        p_alloc_trt_fsm("p_alloc_trt_fsm"),
     482        p_alloc_upt_fsm("p_alloc_upt_fsm"),
     483        p_alloc_ivt_fsm("p_alloc_ivt_fsm"),
     484        p_tgt_cmd_fsm("p_tgt_cmd_fsm"),
     485        p_tgt_rsp_fsm("p_tgt_rsp_fsm"),
     486        p_ixr_cmd_fsm("p_ixr_cmd_fsm"),
     487        p_ixr_rsp_fsm("p_ixr_rsp_fsm"),
     488        p_cc_send_fsm("p_cc_send_fsm"),
    489489        p_cc_receive_fsm("p_cc_receive_fsm"),
    490490        p_multi_ack_fsm("p_multi_ack_fsm")
     
    505505
    506506            // check internal and external data width
    507             assert( (vci_param_int::B == 4 ) and
     507            assert((vci_param_int::B == 4) and
    508508                    "MEMC ERROR : VCI internal data width must be 32 bits");
    509509
    510             assert( (vci_param_ext::B == 8) and
     510            assert((vci_param_ext::B == 8) and
    511511                    "MEMC ERROR : VCI external data width must be 64 bits");
    512512
    513513            // Check coherence between internal & external addresses
    514             assert( (vci_param_int::N == vci_param_ext::N) and
     514            assert((vci_param_int::N == vci_param_ext::N) and
    515515                    "MEMC ERROR : VCI internal & external addresses must have the same width");
    516516
     
    527527            }
    528528
    529             assert( (m_nseg > 0) and
     529            assert((m_nseg > 0) and
    530530                    "MEMC ERROR : At least one segment must be mapped to this component");
    531531
     
    534534            for (seg = m_seglist.begin(); seg != m_seglist.end(); seg++)
    535535            {
    536                 if (seg->special() ) m_seg_config = i;
     536                if (seg->special()) m_seg_config = i;
    537537                m_seg[i] = & (*seg);
    538538                i++;
     
    587587        size_t way  = 0;
    588588        size_t set  = 0;
    589         size_t word = ((size_t)addr & 0x3F) >> 2;
    590        
     589        size_t word = ((size_t) addr & 0x3F) >> 2;
     590
    591591        DirectoryEntry entry = m_cache_directory.read_neutral(addr, &way, &set);
    592592
     
    595595        if (entry.valid)
    596596        {
    597             if (single_word )
     597            if (single_word)
    598598            {
    599599                m_debug_data[word] = m_cache_data.read(way, set, word);
    600                 if ( m_debug_previous_valid and
    601                      (m_debug_data[word] != m_debug_previous_data[word]) )
     600                if (m_debug_previous_valid and
     601                     (m_debug_data[word] != m_debug_previous_data[word]))
    602602                {
    603603                    data_change = true;
     
    609609                {
    610610                    m_debug_data[wcur] = m_cache_data.read(way, set, wcur);
    611                     if ( m_debug_previous_valid and
    612                          (m_debug_data[wcur] != m_debug_previous_data[wcur]) )
     611                    if (m_debug_previous_valid and
     612                         (m_debug_data[wcur] != m_debug_previous_data[wcur]))
    613613                    {
    614614                        data_change = true;
     
    620620        // print values if any change
    621621        if ((entry.valid != m_debug_previous_valid) or
    622                 (entry.valid and (entry.count != m_debug_previous_count)) or
    623                 (entry.valid and (entry.dirty != m_debug_previous_dirty)) or data_change)
     622            (entry.valid and (entry.count != m_debug_previous_count)) or
     623            (entry.valid and (entry.dirty != m_debug_previous_dirty)) or data_change)
    624624        {
    625625            std::cout << "Monitor MEMC " << name()
     
    628628                      << " / VAL = " << std::dec << entry.valid
    629629                      << " / WAY = " << way
    630                       << " / COUNT = " << entry.count 
     630                      << " / COUNT = " << entry.count
    631631                      << " / DIRTY = " << entry.dirty
    632                       << " / DATA_CHANGE = " << data_change; 
    633             if ( single_word )
     632                      << " / DATA_CHANGE = " << data_change;
     633            if (single_word)
    634634            {
    635635                 std::cout << std::hex << " / value = " << m_debug_data[word] << std::endl;
     
    662662        m_debug_previous_valid = entry.valid;
    663663        m_debug_previous_dirty = entry.dirty;
    664         for (size_t wcur = 0; wcur < m_words; wcur++)
     664        for (size_t wcur = 0; wcur < m_words; wcur++)
     665        {
    665666            m_debug_previous_data[wcur] = m_debug_data[wcur];
     667        }
    666668    }
    667669
    668    
     670
    669671    /////////////////////////////////////////////////////
    670672    tmpl(uint32_t)::req_distance(uint32_t req_srcid)
     
    795797
    796798    //////////////////////////////////////////////////
    797     tmpl(void)::print_trace( size_t detailed )
     799    tmpl(void)::print_trace(size_t detailed)
    798800    //////////////////////////////////////////////////
    799801    {
     
    818820            << " | " << alloc_heap_fsm_str[r_alloc_heap_fsm.read()] << std::endl;
    819821
    820         if ( detailed ) m_trt.print(0);
     822        if (detailed) m_trt.print(0);
    821823    }
    822824
    823    
     825
    824826    /////////////////////////////////////////
    825827    tmpl(void)::reset_counters()
     
    866868        m_cpt_cleanup_remote     = 0;
    867869        m_cpt_cleanup_cost       = 0;
    868        
     870
    869871        m_cpt_read_miss          = 0;
    870872        m_cpt_write_miss         = 0;
     
    884886        std::cout << "*** MEM_CACHE " << name() << std::endl;
    885887        std::cout << "**********************************" << std::dec << std::endl;
    886         if (activity_counters) {
     888        if (activity_counters)
     889        {
    887890            std::cout << "----------------------------------" << std::dec << std::endl;
    888891            std::cout << "---     Activity Counters      ---" << std::dec << std::endl;
     
    992995
    993996    //////////////////////////////////
    994     tmpl(void) ::transition()
     997    tmpl(void)::transition()
    995998    //////////////////////////////////
    996999    {
     
    9981001
    9991002        // RESET
    1000         if (! p_resetn.read())
     1003        if (!p_resetn.read())
    10011004        {
    10021005
     
    10541057            m_cmd_cas_eop_fifo.init()   ;
    10551058
    1056             r_config_cmd       = MEMC_CMD_NOP;
    1057             r_config_lock      = false;
     1059            r_config_cmd  = MEMC_CMD_NOP;
     1060            r_config_lock = false;
    10581061
    10591062            m_config_to_cc_send_inst_fifo.init();
     
    11591162            m_cpt_write_miss         = 0;
    11601163            m_cpt_write_dirty        = 0;
    1161            
     1164
    11621165            m_cpt_trt_rb             = 0;
    11631166            m_cpt_trt_full           = 0;
     
    11961199        bool   config_rsp_lines_cleanup_decr  = false;
    11971200        bool   config_rsp_lines_ixr_rsp_decr  = false;
    1198  
     1201
    11991202        bool   config_to_cc_send_fifo_put   = false;
    12001203        bool   config_to_cc_send_fifo_get   = false;
     
    12531256        // The READ/WRITE commands accepted in the configuration segment are targeting
    12541257        // configuration or status registers. They must contain one single flit.
    1255         // - For almost all addressable registers, the response is returned immediately. 
     1258        // - For almost all addressable registers, the response is returned immediately.
    12561259        // - For MEMC_CMD_TYPE, the response is delayed until the operation is completed.
    12571260        ////////////////////////////////////////////////////////////////////////////////////
     
    12661269#if DEBUG_MEMC_TGT_CMD
    12671270                    if (m_debug)
     1271                    {
    12681272                        std::cout << "  <MEMC " << name()
    12691273                            << " TGT_CMD_IDLE> Receive command from srcid "
    12701274                            << std::hex << p_vci_tgt.srcid.read()
    12711275                            << " / address " << std::hex << p_vci_tgt.address.read() << std::endl;
     1276                    }
    12721277#endif
    12731278                    // checking segmentation violation
     
    12851290                    }
    12861291
    1287                     if (config)                     /////////// configuration command
     1292                    if (config)     /////////// configuration command
    12881293                    {
    12891294                        if (!p_vci_tgt.eop.read()) r_tgt_cmd_fsm = TGT_CMD_ERROR;
    12901295                        else                       r_tgt_cmd_fsm = TGT_CMD_CONFIG;
    12911296                    }
    1292                     else                            //////////// memory access
     1297                    else           //////////// memory access
    12931298                    {
    12941299                        if (p_vci_tgt.cmd.read() == vci_param_int::CMD_READ)
     
    13341339                                    "The type specified in the pktid field is incompatible with the NOP CMD");
    13351340
    1336                             if ((p_vci_tgt.pktid.read() & 0x7) == TYPE_CAS) r_tgt_cmd_fsm = TGT_CMD_CAS;
    1337                             else                                            r_tgt_cmd_fsm = TGT_CMD_WRITE;
     1341                            if ((p_vci_tgt.pktid.read() & 0x7) == TYPE_CAS)
     1342                            {
     1343                                r_tgt_cmd_fsm = TGT_CMD_CAS;
     1344                            }
     1345                            else
     1346                            {
     1347                                r_tgt_cmd_fsm = TGT_CMD_WRITE;
     1348                            }
    13381349                        }
    13391350                        else
     
    13631374#if DEBUG_MEMC_TGT_CMD
    13641375                    if (m_debug)
     1376                    {
    13651377                        std::cout << "  <MEMC " << name()
    13661378                            << " TGT_CMD_ERROR> Segmentation violation:"
     
    13701382                            << " / pktid = " << p_vci_tgt.pktid.read()
    13711383                            << " / plen = " << std::dec << p_vci_tgt.plen.read() << std::endl;
    1372 #endif
    1373 
     1384                    }
     1385#endif
    13741386                }
    13751387                break;
     
    13771389                ////////////////////
    13781390            case TGT_CMD_CONFIG:    // execute config request and return response
    1379                 {
    1380                     ///////////////////////////////////////////////////////////
    1381                     //  Decoding CONFIG interface commands                   //
    1382                     //                                                       //
    1383                     //  VCI ADDRESS                                          //
    1384                     //  ================================================     //
    1385                     //  GLOBAL | LOCAL | ... | FUNC_IDX | REGS_IDX | 00      //
    1386                     //   IDX   |  IDX  |     | (3 bits) | (7 bits) |         //
    1387                     //  ================================================     //
    1388                     //                                                       //
    1389                     //  For instrumentation : FUNC_IDX = 0b001               //
    1390                     //                                                       //
    1391                     //  REGS_IDX                                             //
    1392                     //  ============================================         //
    1393                     //       Z     |    Y      |    X     |   W              //
    1394                     //    (1 bit)  | (2 bits)  | (3 bits) | (1 bit)          //
    1395                     //  ============================================         //
    1396                     //                                                       //
    1397                     //  Z : DIRECT / COHERENCE                               //
    1398                     //  Y : SUBTYPE ( LOCAL, REMOTE, OTHER )                 //
    1399                     //  X : REGISTER INDEX                                   //
    1400                     //  W : HI / LO                                          //
    1401                     //                                                       //
    1402                     //  For configuration: FUNC_IDX = 0b000                  //
    1403                     //                                                       //
    1404                     //  REGS_IDX                                             //
    1405                     //  ============================================         //
    1406                     //             RESERVED             |    X     |         //
    1407                     //             (4 bits)             | (3 bits) |         //
    1408                     //  ============================================         //
    1409                     //                                                       //
    1410                     //  X : REGISTER INDEX                                   //
    1411                     //                                                       //
    1412                     //  For WRITE MISS error signaling: FUNC = 0x010         //
    1413                     //                                                       //
    1414                     //  REGS_IDX                                             //
    1415                     //  ============================================         //
    1416                     //             RESERVED             |    X     |         //
    1417                     //             (4 bits)             | (3 bits) |         //
    1418                     //  ============================================         //
    1419                     //                                                       //
    1420                     //  X : REGISTER INDEX                                   //
    1421                     //                                                       //
    1422                     ///////////////////////////////////////////////////////////
    1423 
    1424                     addr_t addr_lsb = p_vci_tgt.address.read() &
    1425                                       m_config_addr_mask;
    1426 
    1427                     addr_t cell = (addr_lsb / vci_param_int::B);
    1428 
    1429                     size_t regr = cell &
    1430                                   m_config_regr_idx_mask;
    1431 
    1432                     size_t func = (cell >> m_config_regr_width) &
    1433                                   m_config_func_idx_mask;
    1434 
    1435                     bool     need_rsp;
    1436                     int      error; 
    1437                     uint32_t rdata = 0;         // default value
    1438                     uint32_t wdata = p_vci_tgt.wdata.read();
    1439 
    1440                     switch(func)
    1441                     {
    1442                         // memory operation
    1443                         case MEMC_CONFIG:
     1391            {
     1392                ///////////////////////////////////////////////////////////
     1393                //  Decoding CONFIG interface commands                   //
     1394                //                                                       //
     1395                //  VCI ADDRESS                                          //
     1396                //  ================================================     //
     1397                //  GLOBAL | LOCAL | ... | FUNC_IDX | REGS_IDX | 00      //
     1398                //   IDX   |  IDX  |     | (3 bits) | (7 bits) |         //
     1399                //  ================================================     //
     1400                //                                                       //
     1401                //  For instrumentation : FUNC_IDX = 0b001               //
     1402                //                                                       //
     1403                //  REGS_IDX                                             //
     1404                //  ============================================         //
     1405                //       Z     |    Y      |    X     |   W              //
     1406                //    (1 bit)  | (2 bits)  | (3 bits) | (1 bit)          //
     1407                //  ============================================         //
     1408                //                                                       //
     1409                //  Z : DIRECT / COHERENCE                               //
     1410                //  Y : SUBTYPE (LOCAL, REMOTE, OTHER)                   //
     1411                //  X : REGISTER INDEX                                   //
     1412                //  W : HI / LO                                          //
     1413                //                                                       //
     1414                //  For configuration: FUNC_IDX = 0b000                  //
     1415                //                                                       //
     1416                //  REGS_IDX                                             //
     1417                //  ============================================         //
     1418                //             RESERVED             |    X     |         //
     1419                //             (4 bits)             | (3 bits) |         //
     1420                //  ============================================         //
     1421                //                                                       //
     1422                //  X : REGISTER INDEX                                   //
     1423                //                                                       //
     1424                //  For WRITE MISS error signaling: FUNC = 0x010         //
     1425                //                                                       //
     1426                //  REGS_IDX                                             //
     1427                //  ============================================         //
     1428                //             RESERVED             |    X     |         //
     1429                //             (4 bits)             | (3 bits) |         //
     1430                //  ============================================         //
     1431                //                                                       //
     1432                //  X : REGISTER INDEX                                   //
     1433                //                                                       //
     1434                ///////////////////////////////////////////////////////////
     1435
     1436                addr_t addr_lsb = p_vci_tgt.address.read() & m_config_addr_mask;
     1437
     1438                addr_t cell = (addr_lsb / vci_param_int::B);
     1439
     1440                size_t regr = cell & m_config_regr_idx_mask;
     1441
     1442                size_t func = (cell >> m_config_regr_width) & m_config_func_idx_mask;
     1443
     1444                bool     need_rsp;
     1445                int      error;
     1446                uint32_t rdata = 0; // default value
     1447                uint32_t wdata = p_vci_tgt.wdata.read();
     1448
     1449                switch (func)
     1450                {
     1451                    // memory operation
     1452                    case MEMC_CONFIG:
     1453                    {
     1454                        if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_READ) // get lock
     1455                                and (regr == MEMC_LOCK))
    14441456                        {
    1445                             if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_READ)         // get lock
    1446                                     and (regr == MEMC_LOCK))
    1447                             {
    1448                                 rdata            = (uint32_t) r_config_lock.read();
    1449                                 need_rsp         = true;
    1450                                 error            = 0;
    1451                                 r_config_lock    = true;
    1452                             }
    1453                             else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)  // release lock
    1454                                     and (regr == MEMC_LOCK))
    1455                             {
    1456                                 need_rsp      = true;
    1457                                 error         = 0;
    1458                                 r_config_lock = false;
    1459                             }
    1460                             else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set addr_lo
    1461                                     and (regr == MEMC_ADDR_LO))
    1462                             {
    1463                                 assert( ((wdata % (m_words * vci_param_int::B)) == 0) and
    1464                                         "VCI_MEM_CACHE CONFIG ERROR: The buffer must be aligned on a cache line");
    1465 
    1466                                 need_rsp         = true;
    1467                                 error            = 0;
    1468                                 r_config_address = (r_config_address.read() & 0xFFFFFFFF00000000LL) |
    1469                                     ((addr_t)wdata);
    1470                             }
    1471                             else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set addr_hi
    1472                                     and (regr == MEMC_ADDR_HI))
    1473 
    1474                             {
    1475                                 need_rsp         = true;
    1476                                 error            = 0;
    1477                                 r_config_address = (r_config_address.read() & 0x00000000FFFFFFFFLL) |
    1478                                     (((addr_t) wdata) << 32);
    1479                             }
    1480                             else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set buf_lines
    1481                                     and (regr == MEMC_BUF_LENGTH))
    1482                             {
    1483                                 need_rsp         = true;
    1484                                 error            = 0;
    1485                                 size_t lines     = wdata / (m_words << 2);
    1486                                 if (wdata % (m_words << 2)) lines++;
    1487                                 r_config_cmd_lines = lines;
    1488                                 r_config_rsp_lines = 0;
    1489                             }
    1490                             else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set cmd type
    1491                                     and (regr == MEMC_CMD_TYPE))
    1492                             {
    1493                                 need_rsp         = false;
    1494                                 error            = 0;
    1495                                 r_config_cmd     = wdata;
    1496 
    1497                                 // prepare delayed response from CONFIG FSM
    1498                                 r_config_srcid   = p_vci_tgt.srcid.read();
    1499                                 r_config_trdid   = p_vci_tgt.trdid.read();
    1500                                 r_config_pktid   = p_vci_tgt.pktid.read();
    1501                             }
    1502                             else
    1503                             {
    1504                                 need_rsp         = true;
    1505                                 error            = 1;
    1506                             }
    1507 
    1508                             break;
     1457                            rdata         = (uint32_t) r_config_lock.read();
     1458                            need_rsp      = true;
     1459                            error         = 0;
     1460                            r_config_lock = true;
    15091461                        }
    1510 
    1511                         // instrumentation registers
    1512                         case MEMC_INSTRM:
    1513                         {
    1514                             need_rsp = true;
    1515 
    1516                             if (p_vci_tgt.cmd.read() == vci_param_int::CMD_READ)
    1517                             {
    1518                                 error = read_instrumentation(regr, rdata);
    1519                             }
    1520                             else
    1521                             {
    1522                                 error = 1;
    1523                             }
    1524 
    1525                             break;
    1526                         }
    1527 
    1528                         // xram GET bus error registers
    1529                         case MEMC_RERROR:
     1462                        else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)  // release lock
     1463                                and (regr == MEMC_LOCK))
    15301464                        {
    15311465                            need_rsp = true;
    15321466                            error    = 0;
    1533 
    1534                             if (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)
    1535                             {
    1536                                 switch (regr)
    1537                                 {
    1538                                     case MEMC_RERROR_IRQ_ENABLE:
    1539                                         r_xram_rsp_rerror_irq_enable =
    1540                                             (p_vci_tgt.wdata.read() != 0);
    1541 
    1542                                         break;
    1543                                        
    1544                                     default:
    1545                                         error = 1;
    1546                                         break;
    1547                                 }
    1548                             }
    1549                             else if (p_vci_tgt.cmd.read() == vci_param_int::CMD_READ)
    1550                             {
    1551                                 switch (regr)
    1552                                 {
    1553                                     case MEMC_RERROR_SRCID:
    1554                                         rdata = (uint32_t)
    1555                                             r_xram_rsp_rerror_rsrcid.read();
    1556 
    1557                                         break;
    1558 
    1559                                     case MEMC_RERROR_ADDR_LO:
    1560                                         rdata = (uint32_t)
    1561                                             (r_xram_rsp_rerror_address.read()) &
    1562                                             ((1ULL<<32)-1);
    1563 
    1564                                         break;
    1565 
    1566                                     case MEMC_RERROR_ADDR_HI:
    1567                                         rdata = (uint32_t)
    1568                                             (r_xram_rsp_rerror_address.read() >> 32) &
    1569                                             ((1ULL<<32)-1);
    1570 
    1571                                         break;
    1572 
    1573                                     case MEMC_RERROR_IRQ_RESET:
    1574                                         if (not r_xram_rsp_rerror_irq.read()) break;
    1575 
    1576                                         r_xram_rsp_rerror_irq = false;
    1577 
    1578                                         break;
    1579 
    1580                                     case MEMC_RERROR_IRQ_ENABLE:
    1581                                         rdata = (uint32_t)
    1582                                             (r_xram_rsp_rerror_irq_enable.read()) ? 1 : 0;
    1583 
    1584                                         break;
    1585 
    1586                                     default:
    1587                                         error = 1;
    1588                                         break;
    1589                                 }
    1590                             }
    1591                             else
    1592                             {
    1593                                 error = 1;
    1594                             }
    1595 
    1596                             break;
     1467                            r_config_lock = false;
    15971468                        }
    1598 
    1599                         //unknown function
    1600                         default:
     1469                        else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set addr_lo
     1470                                and (regr == MEMC_ADDR_LO))
     1471                        {
     1472                            assert(((wdata % (m_words * vci_param_int::B)) == 0) and
     1473                                    "VCI_MEM_CACHE CONFIG ERROR: The buffer must be aligned on a cache line");
     1474
     1475                            need_rsp = true;
     1476                            error    = 0;
     1477                            r_config_address = (r_config_address.read() & 0xFFFFFFFF00000000LL) |
     1478                                ((addr_t)wdata);
     1479                        }
     1480                        else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set addr_hi
     1481                                and (regr == MEMC_ADDR_HI))
     1482
     1483                        {
     1484                            need_rsp = true;
     1485                            error    = 0;
     1486                            r_config_address = (r_config_address.read() & 0x00000000FFFFFFFFLL) |
     1487                                (((addr_t) wdata) << 32);
     1488                        }
     1489                        else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set buf_lines
     1490                                and (regr == MEMC_BUF_LENGTH))
     1491                        {
     1492                            need_rsp = true;
     1493                            error    = 0;
     1494                            size_t lines = wdata / (m_words << 2);
     1495                            if (wdata % (m_words << 2)) lines++;
     1496                            r_config_cmd_lines = lines;
     1497                            r_config_rsp_lines = 0;
     1498                        }
     1499                        else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set cmd type
     1500                                and (regr == MEMC_CMD_TYPE))
     1501                        {
     1502                            need_rsp     = false;
     1503                            error        = 0;
     1504                            r_config_cmd = wdata;
     1505
     1506                            // prepare delayed response from CONFIG FSM
     1507                            r_config_srcid = p_vci_tgt.srcid.read();
     1508                            r_config_trdid = p_vci_tgt.trdid.read();
     1509                            r_config_pktid = p_vci_tgt.pktid.read();
     1510                        }
     1511                        else
    16011512                        {
    16021513                            need_rsp = true;
    16031514                            error    = 1;
    1604 
    1605                             break;
    16061515                        }
    1607                     }
    1608 
    1609                     if (need_rsp)
    1610                     {
    1611                         // blocked if previous pending request to TGT_RSP FSM
    1612                         if (r_tgt_cmd_to_tgt_rsp_req.read()) break;
    1613 
    1614                         r_tgt_cmd_to_tgt_rsp_srcid = p_vci_tgt.srcid.read();
    1615                         r_tgt_cmd_to_tgt_rsp_trdid = p_vci_tgt.trdid.read();
    1616                         r_tgt_cmd_to_tgt_rsp_pktid = p_vci_tgt.pktid.read();
    1617                         r_tgt_cmd_to_tgt_rsp_req   = true;
    1618                         r_tgt_cmd_to_tgt_rsp_error = error;
    1619                         r_tgt_cmd_to_tgt_rsp_rdata = rdata;
    1620                     }
    1621 
    1622                     r_tgt_cmd_fsm = TGT_CMD_IDLE;
     1516
     1517                        break;
     1518                    }
     1519
     1520                    // instrumentation registers
     1521                    case MEMC_INSTRM:
     1522                    {
     1523                        need_rsp = true;
     1524
     1525                        if (p_vci_tgt.cmd.read() == vci_param_int::CMD_READ)
     1526                        {
     1527                            error = read_instrumentation(regr, rdata);
     1528                        }
     1529                        else
     1530                        {
     1531                            error = 1;
     1532                        }
     1533
     1534                        break;
     1535                    }
     1536
     1537                    // xram GET bus error registers
     1538                    case MEMC_RERROR:
     1539                    {
     1540                        need_rsp = true;
     1541                        error    = 0;
     1542
     1543                        if (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)
     1544                        {
     1545                            switch (regr)
     1546                            {
     1547                                case MEMC_RERROR_IRQ_ENABLE:
     1548                                    r_xram_rsp_rerror_irq_enable =
     1549                                        (p_vci_tgt.wdata.read() != 0);
     1550
     1551                                    break;
     1552
     1553                                default:
     1554                                    error = 1;
     1555                                    break;
     1556                            }
     1557                        }
     1558                        else if (p_vci_tgt.cmd.read() == vci_param_int::CMD_READ)
     1559                        {
     1560                            switch (regr)
     1561                            {
     1562                                case MEMC_RERROR_SRCID:
     1563                                    rdata = (uint32_t)
     1564                                        r_xram_rsp_rerror_rsrcid.read();
     1565                                    break;
     1566
     1567                                case MEMC_RERROR_ADDR_LO:
     1568                                    rdata = (uint32_t)
     1569                                        (r_xram_rsp_rerror_address.read()) & ((1ULL << 32) - 1);
     1570
     1571                                    break;
     1572
     1573                                case MEMC_RERROR_ADDR_HI:
     1574                                    rdata = (uint32_t)
     1575                                        (r_xram_rsp_rerror_address.read() >> 32) & ((1ULL << 32) - 1);
     1576                                    break;
     1577
     1578                                case MEMC_RERROR_IRQ_RESET:
     1579                                    if (not r_xram_rsp_rerror_irq.read()) break;
     1580                                    r_xram_rsp_rerror_irq = false;
     1581                                    break;
     1582
     1583                                case MEMC_RERROR_IRQ_ENABLE:
     1584                                    rdata = (uint32_t) (r_xram_rsp_rerror_irq_enable.read()) ? 1 : 0;
     1585                                    break;
     1586
     1587                                default:
     1588                                    error = 1;
     1589                                    break;
     1590                            }
     1591                        }
     1592                        else
     1593                        {
     1594                            error = 1;
     1595                        }
     1596
     1597                        break;
     1598                    }
     1599
     1600                    //unknown function
     1601                    default:
     1602                    {
     1603                        need_rsp = true;
     1604                        error = 1;
     1605                        break;
     1606                    }
     1607                }
     1608
     1609                if (need_rsp)
     1610                {
     1611                    // blocked if previous pending request to TGT_RSP FSM
     1612                    if (r_tgt_cmd_to_tgt_rsp_req.read()) break;
     1613
     1614                    r_tgt_cmd_to_tgt_rsp_srcid = p_vci_tgt.srcid.read();
     1615                    r_tgt_cmd_to_tgt_rsp_trdid = p_vci_tgt.trdid.read();
     1616                    r_tgt_cmd_to_tgt_rsp_pktid = p_vci_tgt.pktid.read();
     1617                    r_tgt_cmd_to_tgt_rsp_req   = true;
     1618                    r_tgt_cmd_to_tgt_rsp_error = error;
     1619                    r_tgt_cmd_to_tgt_rsp_rdata = rdata;
     1620                }
     1621
     1622                r_tgt_cmd_fsm = TGT_CMD_IDLE;
    16231623
    16241624#if DEBUG_MEMC_TGT_CMD
    1625                     if (m_debug)
    1626                         std::cout << "  <MEMC " << name() << " TGT_CMD_CONFIG> Configuration request:"
    1627                             << " address = " << std::hex << p_vci_tgt.address.read()
    1628                             << " / func = " << func
    1629                             << " / regr = " << regr
    1630                             << " / rdata = " << rdata
    1631                             << " / wdata = " << p_vci_tgt.wdata.read()
    1632                             << " / need_rsp = " << need_rsp
    1633                             << " / error = " << error << std::endl;
    1634 #endif
    1635                     break;
    1636                 }
    1637                 //////////////////
     1625                if (m_debug)
     1626                {
     1627                    std::cout << "  <MEMC " << name() << " TGT_CMD_CONFIG> Configuration request:"
     1628                        << " address = " << std::hex << p_vci_tgt.address.read()
     1629                        << " / func = " << func
     1630                        << " / regr = " << regr
     1631                        << " / rdata = " << rdata
     1632                        << " / wdata = " << p_vci_tgt.wdata.read()
     1633                        << " / need_rsp = " << need_rsp
     1634                        << " / error = " << error << std::endl;
     1635                }
     1636#endif
     1637                break;
     1638            }
     1639            //////////////////
    16381640            case TGT_CMD_READ:    // Push a read request into read fifo
    16391641
     
    16521654                        << " read command packet must contain one single flit" << std::endl;
    16531655                    exit(0);
    1654                 } 
     1656                }
    16551657                // check plen for LL
    1656                 if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ) and 
     1658                if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ) and
    16571659                        (p_vci_tgt.plen.read() != 8))
    16581660                {
     
    16671669#if DEBUG_MEMC_TGT_CMD
    16681670                    if (m_debug)
     1671                    {
    16691672                        std::cout << "  <MEMC " << name() << " TGT_CMD_READ> Push into read_fifo:"
    16701673                            << " address = " << std::hex << p_vci_tgt.address.read()
     
    16731676                            << " / pktid = " << p_vci_tgt.pktid.read()
    16741677                            << " / plen = " << std::dec << p_vci_tgt.plen.read() << std::endl;
     1678                    }
    16751679#endif
    16761680                    cmd_read_fifo_put = true;
    16771681                    // <Activity counters>
    1678                     if (p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ) {
     1682                    if (p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ)
     1683                    {
    16791684                        if (is_local_req(p_vci_tgt.srcid.read()))
    16801685                        {
     
    16891694                    }
    16901695                    else {
    1691                         if (is_local_req(p_vci_tgt.srcid.read())) 
     1696                        if (is_local_req(p_vci_tgt.srcid.read()))
    16921697                        {
    16931698                            m_cpt_read_local++;
    16941699                        }
    1695                         else 
     1700                        else
    16961701                        {
    16971702                            m_cpt_read_remote++;
     
    17121717#if DEBUG_MEMC_TGT_CMD
    17131718                    if (m_debug)
     1719                    {
    17141720                        std::cout << "  <MEMC " << name() << " TGT_CMD_WRITE> Push into write_fifo:"
    17151721                            << " address = " << std::hex << p_vci_tgt.address.read()
     
    17201726                            << " / be = " << p_vci_tgt.be.read()
    17211727                            << " / plen = " << std::dec << p_vci_tgt.plen.read() << std::endl;
     1728                    }
    17221729#endif
    17231730                    cmd_write_fifo_put = true;
    17241731                    // <Activity counters>
    1725                     if (p_vci_tgt.cmd.read() == vci_param_int::CMD_NOP) {
     1732                    if (p_vci_tgt.cmd.read() == vci_param_int::CMD_NOP)
     1733                    {
    17261734                        // (2 (CMD) + 1 (RSP)) flits VCI => 4 + (1 (success) || 2 (failure)) flits dspin
    17271735                        m_cpt_sc_cost += 5 * req_distance(p_vci_tgt.srcid.read());
    17281736                    }
    17291737                    else {
    1730                         if (is_local_req(p_vci_tgt.srcid.read())) 
     1738                        if (is_local_req(p_vci_tgt.srcid.read()))
    17311739                        {
    17321740                            m_cpt_write_flits_local++;
     
    17411749                    // </Activity counters>
    17421750
    1743                     if (p_vci_tgt.eop) {
     1751                    if (p_vci_tgt.eop)
     1752                    {
    17441753                        // <Activity counters>
    1745                         if (p_vci_tgt.cmd.read() == vci_param_int::CMD_NOP) {
     1754                        if (p_vci_tgt.cmd.read() == vci_param_int::CMD_NOP)
     1755                        {
    17461756                            if (is_local_req(p_vci_tgt.srcid.read()))
    17471757                            {
     
    17831793#if DEBUG_MEMC_TGT_CMD
    17841794                    if (m_debug)
     1795                    {
    17851796                        std::cout << "  <MEMC " << name() << " TGT_CMD_CAS> Pushing command into cmd_cas_fifo:"
    17861797                            << " address = " << std::hex << p_vci_tgt.address.read()
     
    17911802                            << " be = " << p_vci_tgt.be.read()
    17921803                            << " plen = " << std::dec << p_vci_tgt.plen.read() << std::endl;
     1804                    }
    17931805#endif
    17941806                    cmd_cas_fifo_put = true;
    1795                     if (p_vci_tgt.eop) {
     1807                    if (p_vci_tgt.eop)
     1808                    {
    17961809                        // <Activity counters>
    17971810                        if (is_local_req(p_vci_tgt.srcid.read()))
     
    17991812                            m_cpt_cas_local++;
    18001813                        }
    1801                         else             
     1814                        else
    18021815                        {
    18031816                            m_cpt_cas_remote++;
     
    18151828        //    MULTI_ACK FSM
    18161829        /////////////////////////////////////////////////////////////////////////
    1817         // This FSM controls the response to the multicast update requests sent 
     1830        // This FSM controls the response to the multicast update requests sent
    18181831        // by the memory cache to the L1 caches and update the UPT.
    18191832        //
     
    18271840        ////////////////////////////////////////////////////////////////////////
    18281841
    1829         //std::cout << std::endl << "multi_ack_fsm" << std::endl;
    1830 
    1831         switch(r_multi_ack_fsm.read())
     1842        switch (r_multi_ack_fsm.read())
    18321843        {
    18331844            ////////////////////
    18341845            case MULTI_ACK_IDLE:
    1835                 {
    1836                     bool multi_ack_fifo_rok = m_cc_receive_to_multi_ack_fifo.rok();
    1837 
    1838                     // No CC_RECEIVE FSM request and no WRITE FSM request
    1839                     if (not multi_ack_fifo_rok and not r_write_to_multi_ack_req.read())
    1840                         break;
    1841 
    1842                     uint8_t updt_index;
    1843 
    1844                     // handling WRITE FSM request to decrement update table response
    1845                     // counter if no CC_RECEIVE FSM request
    1846                     if (not multi_ack_fifo_rok)
    1847                     {
    1848                         updt_index               = r_write_to_multi_ack_upt_index.read();
    1849                         r_write_to_multi_ack_req = false;
    1850                     }
    1851                     // Handling CC_RECEIVE FSM request
     1846            {
     1847                bool multi_ack_fifo_rok = m_cc_receive_to_multi_ack_fifo.rok();
     1848
     1849                // No CC_RECEIVE FSM request and no WRITE FSM request
     1850                if (not multi_ack_fifo_rok and not r_write_to_multi_ack_req.read())
     1851                    break;
     1852
     1853                uint8_t updt_index;
     1854
     1855                // handling WRITE FSM request to decrement update table response
     1856                // counter if no CC_RECEIVE FSM request
     1857                if (not multi_ack_fifo_rok)
     1858                {
     1859                    updt_index               = r_write_to_multi_ack_upt_index.read();
     1860                    r_write_to_multi_ack_req = false;
     1861                }
     1862                // Handling CC_RECEIVE FSM request
     1863                else
     1864                {
     1865                    uint64_t flit = m_cc_receive_to_multi_ack_fifo.read();
     1866                    updt_index = DspinDhccpParam::dspin_get(flit,
     1867                            DspinDhccpParam::MULTI_ACK_UPDT_INDEX);
     1868
     1869                    cc_receive_to_multi_ack_fifo_get = true;
     1870                }
     1871
     1872                assert((updt_index < m_upt.size()) and
     1873                        "VCI_MEM_CACHE ERROR in MULTI_ACK_IDLE : "
     1874                        "index too large for UPT");
     1875
     1876                r_multi_ack_upt_index = updt_index;
     1877                r_multi_ack_fsm       = MULTI_ACK_UPT_LOCK;
     1878
     1879#if DEBUG_MEMC_MULTI_ACK
     1880                if (m_debug)
     1881                {
     1882                    if (multi_ack_fifo_rok)
     1883                    {
     1884                        std::cout << "  <MEMC " << name()
     1885                            << " MULTI_ACK_IDLE> Response for UPT entry "
     1886                            << (size_t) updt_index << std::endl;
     1887                    }
    18521888                    else
    18531889                    {
    1854                         uint64_t flit = m_cc_receive_to_multi_ack_fifo.read();
    1855                         updt_index    = DspinDhccpParam::dspin_get(flit,
    1856                                 DspinDhccpParam::MULTI_ACK_UPDT_INDEX);
    1857 
    1858                         cc_receive_to_multi_ack_fifo_get = true;
    1859                     }
    1860 
    1861                     assert((updt_index < m_upt.size()) and
    1862                             "VCI_MEM_CACHE ERROR in MULTI_ACK_IDLE : "
    1863                             "index too large for UPT");
    1864 
    1865                     r_multi_ack_upt_index = updt_index;
    1866                     r_multi_ack_fsm       = MULTI_ACK_UPT_LOCK;
     1890                        std::cout << "  <MEMC " << name()
     1891                            << " MULTI_ACK_IDLE> Write FSM request to decrement UPT entry "
     1892                            << updt_index << std::endl;
     1893                    }
     1894                }
     1895#endif
     1896                break;
     1897            }
     1898
     1899            ////////////////////////
     1900            case MULTI_ACK_UPT_LOCK:
     1901            {
     1902                // get lock to the UPDATE table
     1903                if (r_alloc_upt_fsm.read() != ALLOC_UPT_MULTI_ACK) break;
     1904
     1905                // decrement the number of expected responses
     1906                size_t count = 0;
     1907                bool valid = m_upt.decrement(r_multi_ack_upt_index.read(), count);
     1908
     1909                if (not valid)
     1910                {
     1911                    std::cout << "VCI_MEM_CACHE ERROR " << name()
     1912                        << " MULTI_ACK_UPT_LOCK state" << std::endl
     1913                        << "unsuccessful access to decrement the UPT" << std::endl;
     1914                    exit(0);
     1915                }
     1916
     1917                if (count == 0)
     1918                {
     1919                    r_multi_ack_fsm = MULTI_ACK_UPT_CLEAR;
     1920                }
     1921                else
     1922                {
     1923                    r_multi_ack_fsm = MULTI_ACK_IDLE;
     1924                }
    18671925
    18681926#if DEBUG_MEMC_MULTI_ACK
    1869                     if (m_debug)
    1870                     {
    1871                         if (multi_ack_fifo_rok)
    1872                         {
    1873                             std::cout << "  <MEMC " << name()
    1874                                 << " MULTI_ACK_IDLE> Response for UPT entry "
    1875                                 << (size_t)updt_index << std::endl;
    1876                         }
    1877                         else
    1878                         {
    1879                             std::cout << "  <MEMC " << name()
    1880                                 << " MULTI_ACK_IDLE> Write FSM request to decrement UPT entry "
    1881                                 << updt_index << std::endl;
    1882                         }
    1883                     }
    1884 #endif
    1885                     break;
    1886                 }
    1887 
    1888                 ////////////////////////
    1889             case MULTI_ACK_UPT_LOCK:
    1890                 {
    1891                     // get lock to the UPDATE table
    1892                     if (r_alloc_upt_fsm.read() != ALLOC_UPT_MULTI_ACK) break;
    1893 
    1894                     // decrement the number of expected responses
    1895                     size_t count = 0;
    1896                     bool valid   = m_upt.decrement(r_multi_ack_upt_index.read(), count);
    1897 
    1898                     if (not valid)
    1899                     {
    1900                         std::cout << "VCI_MEM_CACHE ERROR " << name()
    1901                             << " MULTI_ACK_UPT_LOCK state" << std::endl
    1902                             << "unsuccessful access to decrement the UPT" << std::endl;
    1903                         exit(0);
    1904                     }
    1905 
    1906                     if (count == 0)
    1907                     {
    1908                         r_multi_ack_fsm = MULTI_ACK_UPT_CLEAR;
    1909                     }
    1910                     else
    1911                     {
    1912                         r_multi_ack_fsm = MULTI_ACK_IDLE;
    1913                     }
     1927                if (m_debug)
     1928                {
     1929                    std::cout << "  <MEMC " << name()
     1930                        << " MULTI_ACK_UPT_LOCK> Decrement the responses counter for UPT:"
     1931                        << " entry = "       << r_multi_ack_upt_index.read()
     1932                        << " / rsp_count = " << std::dec << count << std::endl;
     1933                }
     1934#endif
     1935                break;
     1936            }
     1937
     1938            /////////////////////////
     1939            case MULTI_ACK_UPT_CLEAR:   // Clear UPT entry / Test if rsp or ack required
     1940            {
     1941                if (r_alloc_upt_fsm.read() != ALLOC_UPT_MULTI_ACK)
     1942                {
     1943                    std::cout << "VCI_MEM_CACHE ERROR " << name()
     1944                        << " MULTI_ACK_UPT_CLEAR state"
     1945                        << " bad UPT allocation" << std::endl;
     1946                    exit(0);
     1947                }
     1948
     1949                r_multi_ack_srcid = m_upt.srcid(r_multi_ack_upt_index.read());
     1950                r_multi_ack_trdid = m_upt.trdid(r_multi_ack_upt_index.read());
     1951                r_multi_ack_pktid = m_upt.pktid(r_multi_ack_upt_index.read());
     1952                r_multi_ack_nline = m_upt.nline(r_multi_ack_upt_index.read());
     1953                bool need_rsp     = m_upt.need_rsp(r_multi_ack_upt_index.read());
     1954
     1955                // clear the UPT entry
     1956                m_upt.clear(r_multi_ack_upt_index.read());
     1957
     1958                if (need_rsp) r_multi_ack_fsm = MULTI_ACK_WRITE_RSP;
     1959                else          r_multi_ack_fsm = MULTI_ACK_IDLE;
    19141960
    19151961#if DEBUG_MEMC_MULTI_ACK
    1916                     if (m_debug)
    1917                         std::cout << "  <MEMC " << name()
    1918                             << " MULTI_ACK_UPT_LOCK> Decrement the responses counter for UPT:"
    1919                             << " entry = "       << r_multi_ack_upt_index.read()
    1920                             << " / rsp_count = " << std::dec << count << std::endl;
    1921 #endif
    1922                     break;
    1923                 }
    1924 
    1925                 /////////////////////////
    1926             case MULTI_ACK_UPT_CLEAR:   // Clear UPT entry / Test if rsp or ack required
    1927                 {
    1928                     if (r_alloc_upt_fsm.read() != ALLOC_UPT_MULTI_ACK)
    1929                     {
    1930                         std::cout << "VCI_MEM_CACHE ERROR " << name()
    1931                             << " MULTI_ACK_UPT_CLEAR state"
    1932                             << " bad UPT allocation" << std::endl;
    1933                         exit(0);
    1934                     }
    1935 
    1936                     r_multi_ack_srcid = m_upt.srcid(r_multi_ack_upt_index.read());
    1937                     r_multi_ack_trdid = m_upt.trdid(r_multi_ack_upt_index.read());
    1938                     r_multi_ack_pktid = m_upt.pktid(r_multi_ack_upt_index.read());
    1939                     r_multi_ack_nline = m_upt.nline(r_multi_ack_upt_index.read());
    1940                     bool need_rsp     = m_upt.need_rsp(r_multi_ack_upt_index.read());
    1941 
    1942                     // clear the UPT entry
    1943                     m_upt.clear(r_multi_ack_upt_index.read());
    1944 
    1945                     if      ( need_rsp ) r_multi_ack_fsm = MULTI_ACK_WRITE_RSP;
    1946                     else                 r_multi_ack_fsm = MULTI_ACK_IDLE;
     1962                if (m_debug)
     1963                {
     1964                    std::cout <<  "  <MEMC " << name()
     1965                        << " MULTI_ACK_UPT_CLEAR> Clear UPT entry "
     1966                        << std::dec << r_multi_ack_upt_index.read() << std::endl;
     1967                }
     1968#endif
     1969                break;
     1970            }
     1971            /////////////////////////
     1972            case MULTI_ACK_WRITE_RSP:     // Post a response request to TGT_RSP FSM
     1973            // Wait if pending request
     1974            {
     1975                if (r_multi_ack_to_tgt_rsp_req.read()) break;
     1976
     1977                r_multi_ack_to_tgt_rsp_req   = true;
     1978                r_multi_ack_to_tgt_rsp_srcid = r_multi_ack_srcid.read();
     1979                r_multi_ack_to_tgt_rsp_trdid = r_multi_ack_trdid.read();
     1980                r_multi_ack_to_tgt_rsp_pktid = r_multi_ack_pktid.read();
     1981                r_multi_ack_fsm              = MULTI_ACK_IDLE;
    19471982
    19481983#if DEBUG_MEMC_MULTI_ACK
    1949                     if (m_debug)
    1950                         std::cout <<  "  <MEMC " << name()
    1951                             << " MULTI_ACK_UPT_CLEAR> Clear UPT entry "
    1952                             << std::dec << r_multi_ack_upt_index.read() << std::endl;
    1953 #endif
    1954                     break;
    1955                 }
    1956                 /////////////////////////
    1957             case MULTI_ACK_WRITE_RSP:     // Post a response request to TGT_RSP FSM
    1958                 // Wait if pending request
    1959                 {
    1960                     if (r_multi_ack_to_tgt_rsp_req.read()) break;
    1961 
    1962                     r_multi_ack_to_tgt_rsp_req   = true;
    1963                     r_multi_ack_to_tgt_rsp_srcid = r_multi_ack_srcid.read();
    1964                     r_multi_ack_to_tgt_rsp_trdid = r_multi_ack_trdid.read();
    1965                     r_multi_ack_to_tgt_rsp_pktid = r_multi_ack_pktid.read();
    1966                     r_multi_ack_fsm              = MULTI_ACK_IDLE;
    1967 
    1968 #if DEBUG_MEMC_MULTI_ACK
    1969                     if (m_debug)
    1970                         std::cout << "  <MEMC " << name() << " MULTI_ACK_WRITE_RSP>"
    1971                             << " Request TGT_RSP FSM to send a response to srcid "
    1972                             << std::hex << r_multi_ack_srcid.read() << std::endl;
    1973 #endif
    1974                     break;
    1975                 }
     1984                if (m_debug)
     1985                {
     1986                    std::cout << "  <MEMC " << name() << " MULTI_ACK_WRITE_RSP>"
     1987                        << " Request TGT_RSP FSM to send a response to srcid "
     1988                        << std::hex << r_multi_ack_srcid.read() << std::endl;
     1989                }
     1990#endif
     1991                break;
     1992            }
    19761993        } // end switch r_multi_ack_fsm
    19771994
     
    19892006        // - uint32_t  r_config_rsp_lines  : number of lines not completed
    19902007        //
    1991         // For both INVAL and SYNC commands, the CONFIG FSM contains the loop handling 
     2008        // For both INVAL and SYNC commands, the CONFIG FSM contains the loop handling
    19922009        // all cache lines covered by the buffer. The various lines of a given buffer
    19932010        // can be pipelined: the CONFIG FSM does not wait the response for line (n) to send
    1994         // the command for line (n+1). It decrements the r_config_cmd_lines counter until 
     2011        // the command for line (n+1). It decrements the r_config_cmd_lines counter until
    19952012        // the last request has been registered in TRT (for a SYNC), or in IVT (for an INVAL).
    19962013        // The r_config_rsp_lines counter contains the number of expected responses from
     
    20022019        //
    20032020        // - INVAL request:
    2004         //   For each line, it access to the DIR. 
    2005         //   In case of miss, it does nothing, and a response is requested to TGT_RSP FSM. 
     2021        //   For each line, it access to the DIR.
     2022        //   In case of miss, it does nothing, and a response is requested to TGT_RSP FSM.
    20062023        //   In case of hit, with no copies in L1 caches, the line is invalidated and
    20072024        //   a response is requested to TGT_RSP FSM.
     
    20142031        //   This constraint can be released, but it requires to make 2 PUT transactions
    20152032        //   for the first and the last line...
    2016         // 
     2033        //
    20172034        // - SYNC request:
    2018         //   For each line, it access to the DIR. 
    2019         //   In case of miss, it does nothing, and a response is requested to TGT_RSP FSM. 
     2035        //   For each line, it access to the DIR.
     2036        //   In case of miss, it does nothing, and a response is requested to TGT_RSP FSM.
    20202037        //   In case of hit, a PUT transaction is registered in TRT and a request is sent
    20212038        //   to IXR_CMD FSM. The IXR_RSP FSM decrements the r_config_rsp_lines counter
     
    20242041        //
    20252042        // From the software point of view, a configuration request is a sequence
    2026         // of 6 atomic accesses in an uncached segment. A dedicated lock is used 
     2043        // of 6 atomic accesses in an uncached segment. A dedicated lock is used
    20272044        // to handle only one configuration command at a given time:
    20282045        // - Read  MEMC_LOCK       : Get the lock
     
    20362053        //std::cout << std::endl << "config_fsm" << std::endl;
    20372054
    2038         switch( r_config_fsm.read())
     2055        switch (r_config_fsm.read())
    20392056        {
    20402057            /////////////////
    2041             case CONFIG_IDLE:  // waiting a config request 
    2042             {
    2043                 if (r_config_cmd.read() != MEMC_CMD_NOP ) 
    2044                 {
    2045                     r_config_fsm    = CONFIG_LOOP;
     2058            case CONFIG_IDLE:  // waiting a config request
     2059            {
     2060                if (r_config_cmd.read() != MEMC_CMD_NOP)
     2061                {
     2062                    r_config_fsm = CONFIG_LOOP;
    20462063
    20472064#if DEBUG_MEMC_CONFIG
    2048 if (m_debug)
    2049     std::cout << "  <MEMC " << name() << " CONFIG_IDLE> Config Request received"
    2050               << " / address = " << std::hex << r_config_address.read()
    2051               << " / lines = " << std::dec << r_config_cmd_lines.read()
    2052               << " / type = " << r_config_cmd.read() << std::endl;
     2065                    if (m_debug)
     2066                    {
     2067                        std::cout << "  <MEMC " << name() << " CONFIG_IDLE> Config Request received"
     2068                            << " / address = " << std::hex << r_config_address.read()
     2069                            << " / lines = " << std::dec << r_config_cmd_lines.read()
     2070                            << " / type = " << r_config_cmd.read() << std::endl;
     2071                    }
    20532072#endif
    20542073                }
     
    20582077            case CONFIG_LOOP:   // test if last line to be handled
    20592078            {
    2060                 if (r_config_cmd_lines.read() == 0 )
     2079                if (r_config_cmd_lines.read() == 0)
    20612080                {
    20622081                    r_config_cmd = MEMC_CMD_NOP;
     
    20692088
    20702089#if DEBUG_MEMC_CONFIG
    2071 if (m_debug)
    2072 std::cout << "  <MEMC " << name() << " CONFIG_LOOP>"
    2073           << " / address = " << std::hex << r_config_address.read()   
    2074           << " / lines not handled = " << std::dec << r_config_cmd_lines.read()
    2075           << " / command = " << r_config_cmd.read() << std::endl;
     2090                if (m_debug)
     2091                {
     2092                    std::cout << "  <MEMC " << name() << " CONFIG_LOOP>"
     2093                        << " / address = " << std::hex << r_config_address.read()
     2094                        << " / lines not handled = " << std::dec << r_config_cmd_lines.read()
     2095                        << " / command = " << r_config_cmd.read() << std::endl;
     2096                }
    20762097#endif
    20772098                break;
    20782099            }
    20792100            /////////////////
    2080             case CONFIG_WAIT:   // wait completion (last response) 
    2081             {
    2082                 if (r_config_rsp_lines.read() == 0 )  // last response received
     2101            case CONFIG_WAIT:   // wait completion (last response)
     2102            {
     2103                if (r_config_rsp_lines.read() == 0)  // last response received
    20832104                {
    20842105                    r_config_fsm = CONFIG_RSP;
     
    20862107
    20872108#if DEBUG_MEMC_CONFIG
    2088 if (m_debug)
    2089 std::cout << "  <MEMC " << name() << " CONFIG_WAIT>"
    2090           << " / lines to do = " << std::dec << r_config_rsp_lines.read() << std::endl;
     2109                if (m_debug)
     2110                {
     2111                    std::cout << "  <MEMC " << name() << " CONFIG_WAIT>"
     2112                        << " / lines to do = " << std::dec << r_config_rsp_lines.read() << std::endl;
     2113                }
    20912114#endif
    20922115                break;
    20932116            }
    20942117            ////////////////
    2095             case CONFIG_RSP:  // request TGT_RSP FSM to return response 
     2118            case CONFIG_RSP:  // request TGT_RSP FSM to return response
    20962119            {
    20972120                if (not r_config_to_tgt_rsp_req.read())
    20982121                {
    2099                     r_config_to_tgt_rsp_srcid  = r_config_srcid.read();
    2100                     r_config_to_tgt_rsp_trdid  = r_config_trdid.read();
    2101                     r_config_to_tgt_rsp_pktid  = r_config_pktid.read();
    2102                     r_config_to_tgt_rsp_error  = false;
    2103                     r_config_to_tgt_rsp_req    = true;
    2104                     r_config_fsm               = CONFIG_IDLE;
     2122                    r_config_to_tgt_rsp_srcid = r_config_srcid.read();
     2123                    r_config_to_tgt_rsp_trdid = r_config_trdid.read();
     2124                    r_config_to_tgt_rsp_pktid = r_config_pktid.read();
     2125                    r_config_to_tgt_rsp_error = false;
     2126                    r_config_to_tgt_rsp_req   = true;
     2127                    r_config_fsm              = CONFIG_IDLE;
    21052128
    21062129#if DEBUG_MEMC_CONFIG
    2107 if (m_debug)
    2108 std::cout << "  <MEMC " << name() << " CONFIG_RSP> Request TGT_RSP FSM to send response:"
    2109           << " error = " << r_config_to_tgt_rsp_error.read()
    2110           << " / rsrcid = " << std::hex << r_config_srcid.read()
    2111           << " / rtrdid = " << std::hex << r_config_trdid.read()
    2112           << " / rpktid = " << std::hex << r_config_pktid.read() << std::endl;
     2130                    if (m_debug)
     2131                    {
     2132                        std::cout << "  <MEMC " << name() << " CONFIG_RSP> Request TGT_RSP FSM to send response:"
     2133                            << " error = " << r_config_to_tgt_rsp_error.read()
     2134                            << " / rsrcid = " << std::hex << r_config_srcid.read()
     2135                            << " / rtrdid = " << std::hex << r_config_trdid.read()
     2136                            << " / rpktid = " << std::hex << r_config_pktid.read() << std::endl;
     2137                    }
    21132138#endif
    21142139                }
     
    21182143            case CONFIG_DIR_REQ:  // Request directory lock
    21192144            {
    2120                 if (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG )
     2145                if (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG)
    21212146                {
    21222147                    r_config_fsm = CONFIG_DIR_ACCESS;
     
    21242149
    21252150#if DEBUG_MEMC_CONFIG
    2126 if (m_debug)
    2127 std::cout << "  <MEMC " << name() << " CONFIG_DIR_REQ>"
    2128           << " Request DIR access" << std::endl;
     2151                if (m_debug)
     2152                {
     2153                    std::cout << "  <MEMC " << name() << " CONFIG_DIR_REQ>"
     2154                        << " Request DIR access" << std::endl;
     2155                }
    21292156#endif
    21302157                break;
     
    21332160            case CONFIG_DIR_ACCESS:   // Access directory and decode config command
    21342161            {
    2135                 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
     2162                assert((r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
    21362163                "MEMC ERROR in CONFIG_DIR_ACCESS state: bad DIR allocation");
    21372164
     
    21472174                r_config_dir_ptr        = entry.ptr;
    21482175
    2149                 if (entry.valid and                            // hit & inval command
    2150                    (r_config_cmd.read() == MEMC_CMD_INVAL)) 
    2151                 {
    2152                     r_config_fsm       = CONFIG_IVT_LOCK;
    2153                 }
    2154                 else if (entry.valid and                       // hit & sync command
     2176                if (entry.valid and   // hit & inval command
     2177                   (r_config_cmd.read() == MEMC_CMD_INVAL))
     2178                {
     2179                    r_config_fsm = CONFIG_IVT_LOCK;
     2180                }
     2181                else if (entry.valid and  // hit & sync command
    21552182                         entry.dirty and
    21562183                         (r_config_cmd.read() == MEMC_CMD_SYNC))
    2157                 { 
    2158                     r_config_fsm       = CONFIG_TRT_LOCK;
    2159                 }
    2160                 else                                            // miss : return to LOOP
     2184                {
     2185                    r_config_fsm = CONFIG_TRT_LOCK;
     2186                }
     2187                else    // miss : return to LOOP
    21612188                {
    21622189                    r_config_cmd_lines = r_config_cmd_lines.read() - 1;
    2163                     r_config_address   = r_config_address.read() + (m_words<<2);
     2190                    r_config_address   = r_config_address.read() + (m_words << 2);
    21642191                    r_config_fsm       = CONFIG_LOOP;
    21652192                }
    21662193
    21672194#if DEBUG_MEMC_CONFIG
    2168 if (m_debug)
    2169 std::cout << "  <MEMC " << name() << " CONFIG_DIR_ACCESS> Accessing directory: "
    2170           << " address = " << std::hex << r_config_address.read()
    2171           << " / hit = " << std::dec << entry.valid
    2172           << " / dirty = " << entry.dirty
    2173           << " / count = " << entry.count
    2174           << " / is_cnt = " << entry.is_cnt << std::endl;
     2195                if (m_debug)
     2196                {
     2197                    std::cout << "  <MEMC " << name() << " CONFIG_DIR_ACCESS> Accessing directory: "
     2198                        << " address = " << std::hex << r_config_address.read()
     2199                        << " / hit = " << std::dec << entry.valid
     2200                        << " / dirty = " << entry.dirty
     2201                        << " / count = " << entry.count
     2202                        << " / is_cnt = " << entry.is_cnt << std::endl;
     2203                }
    21752204#endif
    21762205                break;
     
    21782207            /////////////////////
    21792208            case CONFIG_TRT_LOCK:      // enter this state in case of SYNC command
    2180                                        // to a dirty cache line 
     2209                                       // to a dirty cache line
    21812210                                       // keep DIR lock, and try to get TRT lock
    21822211                                       // return to LOOP state if TRT full
     
    21842213                                       // transaction in TRT if not full.
    21852214            {
    2186                 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
     2215                assert((r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
    21872216                "MEMC ERROR in CONFIG_TRT_LOCK state: bad DIR allocation");
    21882217
    2189                 if (r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG )
     2218                if (r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG)
    21902219                {
    21912220                    size_t index = 0;
    2192                     bool   wok  = not m_trt.full(index);
    2193 
    2194                     if (not wok )
     2221                    bool wok = not m_trt.full(index);
     2222
     2223                    if (not wok)
    21952224                    {
    21962225                        r_config_fsm = CONFIG_LOOP;
     
    21982227                    else
    21992228                    {
    2200                         size_t          way = r_config_dir_way.read();
    2201                         size_t          set = m_y[r_config_address.read()];
     2229                        size_t way = r_config_dir_way.read();
     2230                        size_t set = m_y[r_config_address.read()];
    22022231
    22032232                        // reset dirty bit in DIR
     
    22122241                        entry.owner.inst  = r_config_dir_copy_inst.read();
    22132242                        entry.owner.srcid = r_config_dir_copy_srcid.read();
    2214                         m_cache_directory.write( set, way, entry );
     2243                        m_cache_directory.write(set, way, entry);
    22152244
    22162245                        r_config_trt_index = index;
     
    22192248
    22202249#if DEBUG_MEMC_CONFIG
    2221 if (m_debug)
    2222 std::cout << "  <MEMC " << name() << " CONFIG_TRT_LOCK> Access TRT: "
    2223           << " wok = " << std::dec << wok
    2224           << " index = " << index << std::endl;
     2250                    if (m_debug)
     2251                    {
     2252                        std::cout << "  <MEMC " << name() << " CONFIG_TRT_LOCK> Access TRT: "
     2253                            << " wok = " << std::dec << wok
     2254                            << " index = " << index << std::endl;
     2255                    }
    22252256#endif
    22262257                }
     
    22312262            // and post a PUT request in TRT
    22322263            {
    2233                 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
     2264                assert((r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
    22342265                "MEMC ERROR in CONFIG_TRT_SET state: bad DIR allocation");
    22352266
    2236                 assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG) and
     2267                assert((r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG) and
    22372268                "MEMC ERROR in CONFIG_TRT_SET state: bad TRT allocation");
    22382269
    22392270                // read data into cache
    2240                 size_t              way = r_config_dir_way.read();
    2241                 size_t              set = m_y[r_config_address.read()];
     2271                size_t way = r_config_dir_way.read();
     2272                size_t set = m_y[r_config_address.read()];
    22422273                std::vector<data_t> data_vector;
    22432274                data_vector.clear();
    2244                 for(size_t word=0; word<m_words; word++)
    2245                 {
    2246                     uint32_t data = m_cache_data.read( way, set, word );
    2247                     data_vector.push_back( data );
     2275                for (size_t word = 0; word < m_words; word++)
     2276                {
     2277                    uint32_t data = m_cache_data.read(way, set, word);
     2278                    data_vector.push_back(data);
    22482279                }
    22492280
    22502281                // post the PUT request in TRT
    2251                 m_trt.set( r_config_trt_index.read(),
    2252                            false,                               // PUT transaction
    2253                            m_nline[r_config_address.read()],    // line index
    2254                            0,                                   // srcid:       unused
    2255                            0,                                   // trdid:       unused
    2256                            0,                                   // pktid:       unused
    2257                            false,                               // not proc_read
    2258                            0,                                   // read_length: unused
    2259                            0,                                   // word_index:  unused
    2260                            std::vector<be_t>(m_words,0xF),      // byte-enable: unused
    2261                            data_vector,                         // data to be written
    2262                            0,                                   // ll_key:      unused
    2263                            true );                              // requested by config FSM
     2282                m_trt.set(r_config_trt_index.read(),
     2283                          false,                            // PUT transaction
     2284                          m_nline[r_config_address.read()], // line index
     2285                          0,                                // srcid:       unused
     2286                          0,                                // trdid:       unused
     2287                          0,                                // pktid:       unused
     2288                          false,                            // not proc_read
     2289                          0,                                // read_length: unused
     2290                          0,                                // word_index:  unused
     2291                          std::vector<be_t>(m_words, 0xF),  // byte-enable: unused
     2292                          data_vector,                      // data to be written
     2293                          0,                                // ll_key:      unused
     2294                          true);                            // requested by config FSM
    22642295                config_rsp_lines_incr = true;
    22652296                r_config_fsm          = CONFIG_PUT_REQ;
    22662297
    22672298#if DEBUG_MEMC_CONFIG
    2268 if (m_debug)
    2269 std::cout << "  <MEMC " << name() << " CONFIG_TRT_SET> PUT request in TRT:"
    2270           << " address = " << std::hex << r_config_address.read()
    2271           << " index = " << std::dec << r_config_trt_index.read() << std::endl;
     2299                if (m_debug)
     2300                {
     2301                    std::cout << "  <MEMC " << name() << " CONFIG_TRT_SET> PUT request in TRT:"
     2302                        << " address = " << std::hex << r_config_address.read()
     2303                        << " index = " << std::dec << r_config_trt_index.read() << std::endl;
     2304                }
    22722305#endif
    22732306                break;
     
    22822315
    22832316                    // prepare next iteration
    2284                     r_config_cmd_lines        = r_config_cmd_lines.read() - 1;
    2285                     r_config_address          = r_config_address.read() + (m_words<<2);
    2286                     r_config_fsm              = CONFIG_LOOP;
     2317                    r_config_cmd_lines = r_config_cmd_lines.read() - 1;
     2318                    r_config_address   = r_config_address.read() + (m_words << 2);
     2319                    r_config_fsm       = CONFIG_LOOP;
    22872320
    22882321#if DEBUG_MEMC_CONFIG
    2289 if (m_debug)
    2290 std::cout << "  <MEMC " << name() << " CONFIG_PUT_REQ> post PUT request to IXR_CMD_FSM"
    2291           << " / address = " << std::hex << r_config_address.read() << std::endl;
     2322                    if (m_debug)
     2323                    {
     2324                        std::cout << "  <MEMC " << name() << " CONFIG_PUT_REQ> post PUT request to IXR_CMD_FSM"
     2325                            << " / address = " << std::hex << r_config_address.read() << std::endl;
     2326                    }
    22922327#endif
    22932328                }
     
    22992334                                   // Return to LOOP state if IVT full.
    23002335                                   // Register inval in IVT, and invalidate the
    2301                                    // directory if IVT not full. 
    2302             {
    2303                 assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
     2336                                   // directory if IVT not full.
     2337            {
     2338                assert((r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
    23042339                "MEMC ERROR in CONFIG_IVT_LOCK state: bad DIR allocation");
    23052340
    2306                 if (r_alloc_ivt_fsm.read() == ALLOC_IVT_CONFIG )
    2307                 {
    2308                     size_t set        = m_y[(addr_t)(r_config_address.read())];
    2309                     size_t way        = r_config_dir_way.read();
    2310 
    2311                     if (r_config_dir_count.read() == 0 )  // inval DIR and return to LOOP
    2312                     {
    2313                         m_cache_directory.inval( way, set );
    2314                         r_config_cmd_lines  = r_config_cmd_lines.read() - 1;
    2315                         r_config_address    = r_config_address.read() + (m_words<<2);
    2316                         r_config_fsm        = CONFIG_LOOP;
     2341                if (r_alloc_ivt_fsm.read() == ALLOC_IVT_CONFIG)
     2342                {
     2343                    size_t set = m_y[(addr_t) (r_config_address.read())];
     2344                    size_t way = r_config_dir_way.read();
     2345
     2346                    if (r_config_dir_count.read() == 0)  // inval DIR and return to LOOP
     2347                    {
     2348                        m_cache_directory.inval(way, set);
     2349                        r_config_cmd_lines = r_config_cmd_lines.read() - 1;
     2350                        r_config_address   = r_config_address.read() + (m_words << 2);
     2351                        r_config_fsm       = CONFIG_LOOP;
    23172352
    23182353#if DEBUG_MEMC_CONFIG
    2319 if (m_debug)
    2320 std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
    2321           << " No copies in L1 : inval DIR entry"  << std::endl;
     2354                        if (m_debug)
     2355                        {
     2356                            std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
     2357                                << " No copies in L1 : inval DIR entry"  << std::endl;
     2358                        }
    23222359#endif
    23232360                    }
    23242361                    else    // try to register inval in IVT
    23252362                    {
    2326                         bool        wok       = false;
    2327                         size_t      index     = 0;
    2328                         bool        broadcast = r_config_dir_is_cnt.read();
    2329                         size_t      srcid     = r_config_srcid.read();
    2330                         size_t      trdid     = r_config_trdid.read();
    2331                         size_t      pktid     = r_config_pktid.read();
    2332                         addr_t      nline     = m_nline[(addr_t)(r_config_address.read())];
    2333                         size_t      nb_copies = r_config_dir_count.read();
    2334 
    2335                         wok = m_ivt.set( false,       // it's an inval transaction
    2336                                          broadcast,   
    2337                                          false,       // no response required
    2338                                          true,        // acknowledge required
    2339                                          srcid,
    2340                                          trdid,
    2341                                          pktid,
    2342                                          nline,
    2343                                          nb_copies,
    2344                                          index );
    2345 
    2346                         if (wok )  // IVT success => inval DIR slot
     2363                        bool   wok       = false;
     2364                        size_t index     = 0;
     2365                        bool   broadcast = r_config_dir_is_cnt.read();
     2366                        size_t srcid     = r_config_srcid.read();
     2367                        size_t trdid     = r_config_trdid.read();
     2368                        size_t pktid     = r_config_pktid.read();
     2369                        addr_t nline     = m_nline[(addr_t) (r_config_address.read())];
     2370                        size_t nb_copies = r_config_dir_count.read();
     2371
     2372                        wok = m_ivt.set(false,       // it's an inval transaction
     2373                                        broadcast,
     2374                                        false,       // no response required
     2375                                        true,        // acknowledge required
     2376                                        srcid,
     2377                                        trdid,
     2378                                        pktid,
     2379                                        nline,
     2380                                        nb_copies,
     2381                                        index);
     2382
     2383                        if (wok)  // IVT success => inval DIR slot
    23472384                        {
    2348                             m_cache_directory.inval( way, set );
    2349                             r_config_ivt_index    = index;
     2385                            m_cache_directory.inval(way, set);
     2386                            r_config_ivt_index = index;
    23502387                            config_rsp_lines_incr = true;
    2351                             if (broadcast )  r_config_fsm = CONFIG_BC_SEND;
    2352                             else             r_config_fsm = CONFIG_INVAL_SEND;
     2388                            if (broadcast)
     2389                            {
     2390                                r_config_fsm = CONFIG_BC_SEND;
     2391                            }
     2392                            else
     2393                            {
     2394                                r_config_fsm = CONFIG_INVAL_SEND;
     2395                            }
    23532396
    23542397#if DEBUG_MEMC_CONFIG
    2355 if (m_debug)
    2356 std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
    2357           << " Inval DIR entry and register inval in IVT"
    2358           << " / index = " << std::dec << index
    2359           << " / broadcast = " << broadcast << std::endl;
     2398                            if (m_debug)
     2399                            {
     2400                                std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
     2401                                    << " Inval DIR entry and register inval in IVT"
     2402                                    << " / index = " << std::dec << index
     2403                                    << " / broadcast = " << broadcast << std::endl;
     2404                            }
    23602405#endif
    23612406                        }
     
    23652410
    23662411#if DEBUG_MEMC_CONFIG
    2367 if (m_debug)
    2368 std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
    2369           << " IVT full : release DIR & IVT locks and retry" << std::endl;
     2412                            if (m_debug)
     2413                            {
     2414                                std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
     2415                                    << " IVT full : release DIR & IVT locks and retry" << std::endl;
     2416                            }
    23702417#endif
    23712418                        }
     
    23772424            case CONFIG_BC_SEND:    // Post a broadcast inval request to CC_SEND FSM
    23782425            {
    2379                 if (not r_config_to_cc_send_multi_req.read() and 
     2426                if (not r_config_to_cc_send_multi_req.read() and
    23802427                    not r_config_to_cc_send_brdcast_req.read())
    23812428                {
    23822429                    // post bc inval request
    2383                     r_config_to_cc_send_multi_req   = false;
     2430                    r_config_to_cc_send_multi_req = false;
    23842431                    r_config_to_cc_send_brdcast_req = true;
    23852432                    r_config_to_cc_send_trdid = r_config_ivt_index.read();
     
    23872434
    23882435                    // prepare next iteration
    2389                     r_config_cmd_lines        = r_config_cmd_lines.read() - 1;
    2390                     r_config_address          = r_config_address.read() + (m_words << 2);
    2391                     r_config_fsm              = CONFIG_LOOP;
     2436                    r_config_cmd_lines = r_config_cmd_lines.read() - 1;
     2437                    r_config_address   = r_config_address.read() + (m_words << 2);
     2438                    r_config_fsm       = CONFIG_LOOP;
    23922439
    23932440#if DEBUG_MEMC_CONFIG
    2394 if (m_debug)
    2395 std::cout << "  <MEMC " << name() << " CONFIG_BC_SEND>"
    2396           << " Post a broadcast inval request to CC_SEND FSM"
    2397           << " / address = " << r_config_address.read() <<std::endl;
     2441                    if (m_debug)
     2442                    {
     2443                        std::cout << "  <MEMC " << name() << " CONFIG_BC_SEND>"
     2444                            << " Post a broadcast inval request to CC_SEND FSM"
     2445                            << " / address = " << r_config_address.read() <<std::endl;
     2446                    }
    23982447#endif
    23992448                }
     
    24032452            case CONFIG_INVAL_SEND:    // Post a multi inval request to CC_SEND FSM
    24042453            {
    2405                 if (not r_config_to_cc_send_multi_req.read() and 
     2454                if (not r_config_to_cc_send_multi_req.read() and
    24062455                    not r_config_to_cc_send_brdcast_req.read())
    24072456                {
    24082457                    // post multi inval request
    2409                     r_config_to_cc_send_multi_req   = true;
     2458                    r_config_to_cc_send_multi_req = true;
    24102459                    r_config_to_cc_send_brdcast_req = false;
    24112460                    r_config_to_cc_send_trdid = r_config_ivt_index.read();
     
    24172466                    config_to_cc_send_fifo_put   = true;
    24182467
    2419                     if (r_config_dir_count.read() == 1 )  // one copy
     2468                    if (r_config_dir_count.read() == 1)  // one copy
    24202469                    {
    24212470                        // prepare next iteration
    2422                         r_config_cmd_lines  = r_config_cmd_lines.read() - 1;
    2423                         r_config_address    = r_config_address.read() + (m_words << 2);
    2424                             r_config_fsm    = CONFIG_LOOP;
     2471                        r_config_cmd_lines = r_config_cmd_lines.read() - 1;
     2472                        r_config_address = r_config_address.read() + (m_words << 2);
     2473                        r_config_fsm = CONFIG_LOOP;
    24252474                    }
    24262475                    else                                   // several copies
     
    24302479
    24312480#if DEBUG_MEMC_CONFIG
    2432 if (m_debug)
    2433 std::cout << "  <MEMC " << name() << " CONFIG_INVAL_SEND>"
    2434           << " Post multi inval request to CC_SEND FSM"
    2435           << " / address = " << std::hex << r_config_address.read()
    2436           << " / copy = " << r_config_dir_copy_srcid.read()
    2437           << " / inst = " << std::dec << r_config_dir_copy_inst.read() << std::endl;
     2481                    if (m_debug)
     2482                    {
     2483                        std::cout << "  <MEMC " << name() << " CONFIG_INVAL_SEND>"
     2484                            << " Post multi inval request to CC_SEND FSM"
     2485                            << " / address = " << std::hex << r_config_address.read()
     2486                            << " / copy = " << r_config_dir_copy_srcid.read()
     2487                            << " / inst = " << std::dec << r_config_dir_copy_inst.read() << std::endl;
     2488                    }
    24382489#endif
    24392490                }
     
    24432494            case CONFIG_HEAP_REQ:  // Try to get access to Heap
    24442495            {
    2445                 if (r_alloc_heap_fsm.read() == ALLOC_HEAP_CONFIG )
    2446                 {
    2447                     r_config_fsm       = CONFIG_HEAP_SCAN;
     2496                if (r_alloc_heap_fsm.read() == ALLOC_HEAP_CONFIG)
     2497                {
     2498                    r_config_fsm = CONFIG_HEAP_SCAN;
    24482499                    r_config_heap_next = r_config_dir_ptr.read();
    24492500                }
    24502501
    24512502#if DEBUG_MEMC_CONFIG
    2452 if (m_debug)
    2453 std::cout << "  <MEMC " << name() << " CONFIG_HEAP_REQ>"
    2454           << " Requesting HEAP lock" << std::endl;
     2503                if (m_debug)
     2504                {
     2505                    std::cout << "  <MEMC " << name() << " CONFIG_HEAP_REQ>"
     2506                        << " Requesting HEAP lock" << std::endl;
     2507                }
    24552508#endif
    24562509                break;
    24572510            }
    24582511            //////////////////////
    2459             case CONFIG_HEAP_SCAN:      // scan HEAP and send inval to CC_SEND FSM
    2460             {
    2461                 HeapEntry entry = m_heap.read( r_config_heap_next.read());
    2462                 bool last_copy  = (entry.next == r_config_heap_next.read());
     2512            case CONFIG_HEAP_SCAN: // scan HEAP and send inval to CC_SEND FSM
     2513            {
     2514                HeapEntry entry = m_heap.read(r_config_heap_next.read());
     2515                bool last_copy = (entry.next == r_config_heap_next.read());
    24632516
    24642517                config_to_cc_send_fifo_srcid = entry.owner.srcid;
    2465                 config_to_cc_send_fifo_inst  = entry.owner.inst;
    2466                 // config_to_cc_send_fifo_last  = last_copy;
    2467                 config_to_cc_send_fifo_put   = true;
     2518                config_to_cc_send_fifo_inst = entry.owner.inst;
     2519                config_to_cc_send_fifo_put = true;
    24682520
    24692521                if (m_config_to_cc_send_inst_fifo.wok()) // inval request accepted
    24702522                {
    24712523                    r_config_heap_next = entry.next;
    2472                     if (last_copy ) r_config_fsm = CONFIG_HEAP_LAST;
     2524                    if (last_copy) r_config_fsm = CONFIG_HEAP_LAST;
    24732525                }
    24742526
    24752527#if DEBUG_MEMC_CONFIG
    2476 if (m_debug)
    2477 std::cout << "  <MEMC " << name() << " CONFIG_HEAP_SCAN>"
    2478           << " Post multi inval request to CC_SEND FSM"
    2479           << " / address = " << std::hex << r_config_address.read()
    2480           << " / copy = " << entry.owner.srcid
    2481           << " / inst = " << std::dec << entry.owner.inst << std::endl;
     2528                if (m_debug)
     2529                {
     2530                    std::cout << "  <MEMC " << name() << " CONFIG_HEAP_SCAN>"
     2531                        << " Post multi inval request to CC_SEND FSM"
     2532                        << " / address = " << std::hex << r_config_address.read()
     2533                        << " / copy = " << entry.owner.srcid
     2534                        << " / inst = " << std::dec << entry.owner.inst << std::endl;
     2535                }
    24822536#endif
    24832537                break;
    24842538            }
    24852539            //////////////////////
    2486             case CONFIG_HEAP_LAST:      // HEAP housekeeping
     2540            case CONFIG_HEAP_LAST:  // HEAP housekeeping
    24872541            {
    24882542                size_t free_pointer = m_heap.next_free_ptr();
     
    24972551                }
    24982552                else
    2499                 { 
     2553                {
    25002554                   last_entry.next = free_pointer;
    25012555                }
    25022556
    2503                 m_heap.write_free_ptr( r_config_dir_ptr.read());
    2504                 m_heap.write( r_config_heap_next.read(), last_entry );
     2557                m_heap.write_free_ptr(r_config_dir_ptr.read());
     2558                m_heap.write(r_config_heap_next.read(), last_entry);
    25052559
    25062560                // prepare next iteration
    2507                 r_config_cmd_lines          = r_config_cmd_lines.read() - 1;
    2508                 r_config_address            = r_config_address.read() + (m_words<<2);
    2509                 r_config_fsm                = CONFIG_LOOP;
     2561                r_config_cmd_lines = r_config_cmd_lines.read() - 1;
     2562                r_config_address   = r_config_address.read() + (m_words << 2);
     2563                r_config_fsm       = CONFIG_LOOP;
    25102564
    25112565#if DEBUG_MEMC_CONFIG
    2512 if (m_debug)
    2513 std::cout << "  <MEMC " << name() << " CONFIG_HEAP_LAST>"
    2514           << " Heap housekeeping" << std::endl;
     2566                if (m_debug)
     2567                {
     2568                    std::cout << "  <MEMC " << name() << " CONFIG_HEAP_LAST>"
     2569                        << " Heap housekeeping" << std::endl;
     2570                }
    25152571#endif
    25162572                break;
     
    25182574        }  // end switch r_config_fsm
    25192575
    2520        
     2576
    25212577
    25222578        ////////////////////////////////////////////////////////////////////////////////////
     
    25492605            ///////////////
    25502606            case READ_IDLE:  // waiting a read request
    2551                 {
    2552                     if (m_cmd_read_addr_fifo.rok())
    2553                     {
    2554 
    2555 #if DEBUG_MEMC_READ
    2556                         if (m_debug)
    2557                             std::cout << "  <MEMC " << name() << " READ_IDLE> Read request"
    2558                                 << " : address = " << std::hex << m_cmd_read_addr_fifo.read()
    2559                                 << " / srcid = " << m_cmd_read_srcid_fifo.read()
    2560                                 << " / trdid = " << m_cmd_read_trdid_fifo.read()
    2561                                 << " / pktid = " << m_cmd_read_pktid_fifo.read()
    2562                                 << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
    2563 #endif
    2564                         r_read_fsm = READ_DIR_REQ;
    2565                     }
    2566                     break;
    2567                 }
    2568                 //////////////////
    2569             case READ_DIR_REQ:  // Get the lock to the directory
    2570                 {
    2571                     if (r_alloc_dir_fsm.read() == ALLOC_DIR_READ)
    2572                     {
    2573                         r_read_fsm = READ_DIR_LOCK;
    2574                     }
     2607            {
     2608                if (m_cmd_read_addr_fifo.rok())
     2609                {
    25752610
    25762611#if DEBUG_MEMC_READ
    25772612                    if (m_debug)
    2578                         std::cout << "  <MEMC " << name() << " READ_DIR_REQ> Requesting DIR lock " << std::endl;
    2579 #endif
    2580                     break;
    2581                 }
    2582 
    2583                 ///////////////////
     2613                    {
     2614                        std::cout << "  <MEMC " << name() << " READ_IDLE> Read request"
     2615                            << " : address = " << std::hex << m_cmd_read_addr_fifo.read()
     2616                            << " / srcid = " << m_cmd_read_srcid_fifo.read()
     2617                            << " / trdid = " << m_cmd_read_trdid_fifo.read()
     2618                            << " / pktid = " << m_cmd_read_pktid_fifo.read()
     2619                            << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
     2620                    }
     2621#endif
     2622                    r_read_fsm = READ_DIR_REQ;
     2623                }
     2624                break;
     2625            }
     2626            //////////////////
     2627            case READ_DIR_REQ:  // Get the lock to the directory
     2628            {
     2629                if (r_alloc_dir_fsm.read() == ALLOC_DIR_READ)
     2630                {
     2631                    r_read_fsm = READ_DIR_LOCK;
     2632                }
     2633
     2634#if DEBUG_MEMC_READ
     2635                if (m_debug)
     2636                {
     2637                    std::cout << "  <MEMC " << name() << " READ_DIR_REQ> Requesting DIR lock " << std::endl;
     2638                }
     2639#endif
     2640                break;
     2641            }
     2642
     2643            ///////////////////
    25842644            case READ_DIR_LOCK:  // check directory for hit / miss
    2585                 {
    2586                     assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_READ) and
    2587                             "MEMC ERROR in READ_DIR_LOCK state: Bad DIR allocation");
    2588 
    2589                     size_t way = 0;
    2590                     DirectoryEntry entry = m_cache_directory.read(m_cmd_read_addr_fifo.read(), way);
    2591 
    2592                     // access the global table ONLY when we have an LL cmd
    2593                     if ((m_cmd_read_pktid_fifo.read() & 0x7) == TYPE_LL)   
    2594                     {
    2595                         r_read_ll_key   = m_llsc_table.ll(m_cmd_read_addr_fifo.read());
    2596                     }
    2597                     r_read_is_cnt     = entry.is_cnt;
    2598                     r_read_dirty      = entry.dirty;
    2599                     r_read_lock       = entry.lock;
    2600                     r_read_tag        = entry.tag;
    2601                     r_read_way        = way;
    2602                     r_read_count      = entry.count;
    2603                     r_read_copy       = entry.owner.srcid;
    2604                     r_read_copy_inst  = entry.owner.inst;
    2605                     r_read_ptr        = entry.ptr; // pointer to the heap
    2606 
    2607                     // check if this is a cached read, this means pktid is either
    2608                     // TYPE_READ_DATA_MISS 0bX001 with TSAR encoding
    2609                     // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
    2610                     bool cached_read = (m_cmd_read_pktid_fifo.read() & 0x1);
    2611                     if (entry.valid)    // hit
    2612                     {
    2613                         // test if we need to register a new copy in the heap
    2614                         if (entry.is_cnt or (entry.count == 0) or !cached_read)
     2645            {
     2646                assert((r_alloc_dir_fsm.read() == ALLOC_DIR_READ) and
     2647                        "MEMC ERROR in READ_DIR_LOCK state: Bad DIR allocation");
     2648
     2649                size_t way = 0;
     2650                DirectoryEntry entry = m_cache_directory.read(m_cmd_read_addr_fifo.read(), way);
     2651
     2652                // access the global table ONLY when we have an LL cmd
     2653                if ((m_cmd_read_pktid_fifo.read() & 0x7) == TYPE_LL)
     2654                {
     2655                    r_read_ll_key   = m_llsc_table.ll(m_cmd_read_addr_fifo.read());
     2656                }
     2657                r_read_is_cnt    = entry.is_cnt;
     2658                r_read_dirty     = entry.dirty;
     2659                r_read_lock      = entry.lock;
     2660                r_read_tag       = entry.tag;
     2661                r_read_way       = way;
     2662                r_read_count     = entry.count;
     2663                r_read_copy      = entry.owner.srcid;
     2664                r_read_copy_inst = entry.owner.inst;
     2665                r_read_ptr       = entry.ptr; // pointer to the heap
     2666
     2667                // check if this is a cached read, this means pktid is either
     2668                // TYPE_READ_DATA_MISS 0bX001 with TSAR encoding
     2669                // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
     2670                bool cached_read = (m_cmd_read_pktid_fifo.read() & 0x1);
     2671                if (entry.valid)    // hit
     2672                {
     2673                    // test if we need to register a new copy in the heap
     2674                    if (entry.is_cnt or (entry.count == 0) or !cached_read)
     2675                    {
     2676                        r_read_fsm = READ_DIR_HIT;
     2677                    }
     2678                    else
     2679                    {
     2680                        r_read_fsm = READ_HEAP_REQ;
     2681                    }
     2682                }
     2683                else      // miss
     2684                {
     2685                    r_read_fsm = READ_TRT_LOCK;
     2686                }
     2687
     2688#if DEBUG_MEMC_READ
     2689                if (m_debug)
     2690                {
     2691                    std::cout << "  <MEMC " << name() << " READ_DIR_LOCK> Accessing directory: "
     2692                        << " address = " << std::hex << m_cmd_read_addr_fifo.read()
     2693                        << " / hit = " << std::dec << entry.valid
     2694                        << " / count = " <<std::dec << entry.count
     2695                        << " / is_cnt = " << entry.is_cnt;
     2696                    if ((m_cmd_read_pktid_fifo.read() & 0x7) == TYPE_LL)
     2697                    {
     2698                        std::cout << " / LL access" << std::endl;
     2699                    }
     2700                    else
     2701                    {
     2702                        std::cout << std::endl;
     2703                    }
     2704                }
     2705#endif
     2706                break;
     2707            }
     2708            //////////////////
     2709            case READ_DIR_HIT:    //  read data in cache & update the directory
     2710            //  we enter this state in 3 cases:
     2711            //  - the read request is uncachable
     2712            //  - the cache line is in counter mode
     2713            //  - the cache line is valid but not replicated
     2714            {
     2715                assert((r_alloc_dir_fsm.read() == ALLOC_DIR_READ) and
     2716                        "MEMC ERROR in READ_DIR_HIT state: Bad DIR allocation");
     2717
     2718                // check if this is an instruction read, this means pktid is either
     2719                // TYPE_READ_INS_UNC   0bX010 with TSAR encoding
     2720                // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
     2721                bool inst_read = ((m_cmd_read_pktid_fifo.read() & 0x2) != 0);
     2722                // check if this is a cached read, this means pktid is either
     2723                // TYPE_READ_DATA_MISS 0bX001 with TSAR encoding
     2724                // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
     2725                bool cached_read = (m_cmd_read_pktid_fifo.read() & 0x1);
     2726                bool is_cnt      = r_read_is_cnt.read();
     2727
     2728                // read data in the cache
     2729                size_t set = m_y[(addr_t)(m_cmd_read_addr_fifo.read())];
     2730                size_t way = r_read_way.read();
     2731
     2732                m_cache_data.read_line(way, set, r_read_data);
     2733
     2734                // update the cache directory
     2735                DirectoryEntry entry;
     2736                entry.valid  = true;
     2737                entry.is_cnt = is_cnt;
     2738                entry.dirty  = r_read_dirty.read();
     2739                entry.tag    = r_read_tag.read();
     2740                entry.lock   = r_read_lock.read();
     2741                entry.ptr    = r_read_ptr.read();
     2742
     2743                if (cached_read) // Cached read => we must update the copies
     2744                {
     2745                    if (!is_cnt)  // Not counter mode
     2746                    {
     2747                        entry.owner.srcid = m_cmd_read_srcid_fifo.read();
     2748                        entry.owner.inst  = inst_read;
     2749                        entry.count       = r_read_count.read() + 1;
     2750                    }
     2751                    else  // Counter mode
     2752                    {
     2753                        entry.owner.srcid = 0;
     2754                        entry.owner.inst  = false;
     2755                        entry.count       = r_read_count.read() + 1;
     2756                    }
     2757                }
     2758                else // Uncached read
     2759                {
     2760                    entry.owner.srcid = r_read_copy.read();
     2761                    entry.owner.inst  = r_read_copy_inst.read();
     2762                    entry.count       = r_read_count.read();
     2763                }
     2764
     2765#if DEBUG_MEMC_READ
     2766                if (m_debug)
     2767                {
     2768                    std::cout << "  <MEMC " << name() << " READ_DIR_HIT> Update directory entry:"
     2769                        << " addr = " << std::hex << m_cmd_read_addr_fifo.read()
     2770                        << " / set = " << std::dec << set
     2771                        << " / way = " << way
     2772                        << " / owner_id = " << std::hex << entry.owner.srcid
     2773                        << " / owner_ins = " << std::dec << entry.owner.inst
     2774                        << " / count = " << entry.count
     2775                        << " / is_cnt = " << entry.is_cnt << std::endl;
     2776                }
     2777#endif
     2778                m_cache_directory.write(set, way, entry);
     2779                r_read_fsm = READ_RSP;
     2780                break;
     2781            }
     2782            ///////////////////
     2783            case READ_HEAP_REQ:    // Get the lock to the HEAP directory
     2784            {
     2785                if (r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)
     2786                {
     2787                    r_read_fsm = READ_HEAP_LOCK;
     2788                }
     2789
     2790#if DEBUG_MEMC_READ
     2791                if (m_debug)
     2792                {
     2793                    std::cout << "  <MEMC " << name() << " READ_HEAP_REQ>"
     2794                        << " Requesting HEAP lock " << std::endl;
     2795                }
     2796#endif
     2797                break;
     2798            }
     2799
     2800            ////////////////////
     2801            case READ_HEAP_LOCK:   // read data in cache, update the directory
     2802            // and prepare the HEAP update
     2803            {
     2804                if (r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)
     2805                {
     2806                    // enter counter mode when we reach the limit of copies or the heap is full
     2807                    bool go_cnt = (r_read_count.read() >= m_max_copies) or m_heap.is_full();
     2808
     2809                    // read data in the cache
     2810                    size_t set = m_y[(addr_t) (m_cmd_read_addr_fifo.read())];
     2811                    size_t way = r_read_way.read();
     2812
     2813                    m_cache_data.read_line(way, set, r_read_data);
     2814
     2815                    // update the cache directory
     2816                    DirectoryEntry entry;
     2817                    entry.valid  = true;
     2818                    entry.is_cnt = go_cnt;
     2819                    entry.dirty  = r_read_dirty.read();
     2820                    entry.tag    = r_read_tag.read();
     2821                    entry.lock   = r_read_lock.read();
     2822                    entry.count  = r_read_count.read() + 1;
     2823
     2824                    if (not go_cnt) // Not entering counter mode
     2825                    {
     2826                        entry.owner.srcid = r_read_copy.read();
     2827                        entry.owner.inst  = r_read_copy_inst.read();
     2828                        entry.ptr         = m_heap.next_free_ptr();   // set pointer on the heap
     2829                    }
     2830                    else    // Entering Counter mode
     2831                    {
     2832                        entry.owner.srcid = 0;
     2833                        entry.owner.inst  = false;
     2834                        entry.ptr         = 0;
     2835                    }
     2836
     2837                    m_cache_directory.write(set, way, entry);
     2838
     2839                    // prepare the heap update (add an entry, or clear the linked list)
     2840                    if (not go_cnt)      // not switching to counter mode
     2841                    {
     2842                        // We test if the next free entry in the heap is the last
     2843                        HeapEntry heap_entry = m_heap.next_free_entry();
     2844                        r_read_next_ptr      = heap_entry.next;
     2845                        r_read_last_free     = (heap_entry.next == m_heap.next_free_ptr());
     2846
     2847                        r_read_fsm = READ_HEAP_WRITE; // add an entry in the HEAP
     2848                    }
     2849                    else // switching to counter mode
     2850                    {
     2851                        if (r_read_count.read() > 1) // heap must be cleared
    26152852                        {
    2616                             r_read_fsm = READ_DIR_HIT;
     2853                            HeapEntry next_entry = m_heap.read(r_read_ptr.read());
     2854                            r_read_next_ptr      = m_heap.next_free_ptr();
     2855                            m_heap.write_free_ptr(r_read_ptr.read());
     2856
     2857                            if (next_entry.next == r_read_ptr.read())    // last entry
     2858                            {
     2859                                r_read_fsm = READ_HEAP_LAST;    // erase the entry
     2860                            }
     2861                            else                                        // not the last entry
     2862                            {
     2863                                r_read_ptr = next_entry.next;
     2864                                r_read_fsm = READ_HEAP_ERASE;   // erase the list
     2865                            }
    26172866                        }
    2618                         else
     2867                        else  // the heap is not used / nothing to do
    26192868                        {
    2620                             r_read_fsm = READ_HEAP_REQ;
     2869                            r_read_fsm = READ_RSP;
    26212870                        }
    2622                     }
    2623                     else      // miss
    2624                     {
    2625                         r_read_fsm = READ_TRT_LOCK;
    26262871                    }
    26272872
     
    26292874                    if (m_debug)
    26302875                    {
    2631                         std::cout << "  <MEMC " << name() << " READ_DIR_LOCK> Accessing directory: "
    2632                             << " address = " << std::hex << m_cmd_read_addr_fifo.read()
    2633                             << " / hit = " << std::dec << entry.valid
    2634                             << " / count = " <<std::dec << entry.count
    2635                             << " / is_cnt = " << entry.is_cnt;
    2636                         if ((m_cmd_read_pktid_fifo.read() & 0x7) == TYPE_LL) std::cout << " / LL access" << std::endl;
    2637                         else                                                std::cout << std::endl;
    2638                     }
    2639 #endif
    2640                     break;
    2641                 }
    2642                 //////////////////
    2643             case READ_DIR_HIT:    //  read data in cache & update the directory
    2644                 //  we enter this state in 3 cases:
    2645                 //  - the read request is uncachable
    2646                 //  - the cache line is in counter mode
    2647                 //  - the cache line is valid but not replicated
    2648 
    2649                 {
    2650                     assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_READ) and
    2651                             "MEMC ERROR in READ_DIR_HIT state: Bad DIR allocation");
    2652 
    2653                     // check if this is an instruction read, this means pktid is either
    2654                     // TYPE_READ_INS_UNC   0bX010 with TSAR encoding
    2655                     // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
    2656                     bool inst_read    = ((m_cmd_read_pktid_fifo.read() & 0x2) != 0);
    2657                     // check if this is a cached read, this means pktid is either
    2658                     // TYPE_READ_DATA_MISS 0bX001 with TSAR encoding
    2659                     // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
    2660                     bool cached_read  = (m_cmd_read_pktid_fifo.read() & 0x1);
    2661                     bool is_cnt       = r_read_is_cnt.read();
    2662 
    2663                     // read data in the cache
    2664                     size_t set        = m_y[(addr_t)(m_cmd_read_addr_fifo.read())];
    2665                     size_t way        = r_read_way.read();
    2666 
    2667                     m_cache_data.read_line(way, set, r_read_data);
    2668 
    2669                     // update the cache directory
    2670                     DirectoryEntry entry;
    2671                     entry.valid   = true;
    2672                     entry.is_cnt  = is_cnt;
    2673                     entry.dirty   = r_read_dirty.read();
    2674                     entry.tag     = r_read_tag.read();
    2675                     entry.lock    = r_read_lock.read();
    2676                     entry.ptr     = r_read_ptr.read();
    2677 
    2678                     if (cached_read)   // Cached read => we must update the copies
    2679                     {
    2680                         if (!is_cnt)  // Not counter mode
    2681                         {
    2682                             entry.owner.srcid    = m_cmd_read_srcid_fifo.read();
    2683                             entry.owner.inst     = inst_read;
    2684                             entry.count          = r_read_count.read() + 1;
    2685                         }
    2686                         else  // Counter mode
    2687                         {
    2688                             entry.owner.srcid    = 0;
    2689                             entry.owner.inst     = false;
    2690                             entry.count          = r_read_count.read() + 1;
    2691                         }
    2692                     }
    2693                     else            // Uncached read
    2694                     {
    2695                         entry.owner.srcid     = r_read_copy.read();
    2696                         entry.owner.inst      = r_read_copy_inst.read();
    2697                         entry.count           = r_read_count.read();
    2698                     }
     2876                        std::cout << "  <MEMC " << name() << " READ_HEAP_LOCK> Update directory:"
     2877                            << " tag = " << std::hex << entry.tag
     2878                            << " set = " << std::dec << set
     2879                            << " way = " << way
     2880                            << " count = " << entry.count
     2881                            << " is_cnt = " << entry.is_cnt << std::endl;
     2882                    }
     2883#endif
     2884                }
     2885                else
     2886                {
     2887                    std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_LOCK"
     2888                        << "Bad HEAP allocation"   << std::endl;
     2889                    exit(0);
     2890                }
     2891                break;
     2892            }
     2893            /////////////////////
     2894            case READ_HEAP_WRITE:       // add an entry in the heap
     2895            {
     2896                if (r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)
     2897                {
     2898                    HeapEntry heap_entry;
     2899                    heap_entry.owner.srcid = m_cmd_read_srcid_fifo.read();
     2900                    heap_entry.owner.inst  = ((m_cmd_read_pktid_fifo.read() & 0x2) != 0);
     2901
     2902                    if (r_read_count.read() == 1)  // creation of a new linked list
     2903                    {
     2904                        heap_entry.next = m_heap.next_free_ptr();
     2905                    }
     2906                    else                         // head insertion in existing list
     2907                    {
     2908                        heap_entry.next = r_read_ptr.read();
     2909                    }
     2910                    m_heap.write_free_entry(heap_entry);
     2911                    m_heap.write_free_ptr(r_read_next_ptr.read());
     2912                    if (r_read_last_free.read())  {
     2913                        m_heap.set_full();
     2914                    }
     2915
     2916                    r_read_fsm = READ_RSP;
    26992917
    27002918#if DEBUG_MEMC_READ
    27012919                    if (m_debug)
    2702                         std::cout << "  <MEMC " << name() << " READ_DIR_HIT> Update directory entry:"
    2703                             << " addr = " << std::hex << m_cmd_read_addr_fifo.read()
    2704                             << " / set = " << std::dec << set
    2705                             << " / way = " << way
    2706                             << " / owner_id = " << std::hex << entry.owner.srcid
    2707                             << " / owner_ins = " << std::dec << entry.owner.inst
    2708                             << " / count = " << entry.count
    2709                             << " / is_cnt = " << entry.is_cnt << std::endl;
    2710 #endif
    2711                     m_cache_directory.write(set, way, entry);
    2712                     r_read_fsm    = READ_RSP;
    2713                     break;
    2714                 }
    2715                 ///////////////////
    2716             case READ_HEAP_REQ:    // Get the lock to the HEAP directory
    2717                 {
    2718                     if (r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)
    2719                     {
    2720                         r_read_fsm = READ_HEAP_LOCK;
    2721                     }
     2920                    {
     2921                        std::cout << "  <MEMC " << name() << " READ_HEAP_WRITE> Add an entry in the heap:"
     2922                            << " owner_id = " << std::hex << heap_entry.owner.srcid
     2923                            << " owner_ins = " << std::dec << heap_entry.owner.inst << std::endl;
     2924                    }
     2925#endif
     2926                }
     2927                else
     2928                {
     2929                    std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_WRITE"
     2930                        << "Bad HEAP allocation" << std::endl;
     2931                    exit(0);
     2932                }
     2933                break;
     2934            }
     2935            /////////////////////
     2936            case READ_HEAP_ERASE:
     2937            {
     2938                if (r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)
     2939                {
     2940                    HeapEntry next_entry = m_heap.read(r_read_ptr.read());
     2941                    if (next_entry.next == r_read_ptr.read())
     2942                    {
     2943                        r_read_fsm = READ_HEAP_LAST;
     2944                    }
     2945                    else
     2946                    {
     2947                        r_read_ptr = next_entry.next;
     2948                        r_read_fsm = READ_HEAP_ERASE;
     2949                    }
     2950                }
     2951                else
     2952                {
     2953                    std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_ERASE"
     2954                        << "Bad HEAP allocation" << std::endl;
     2955                    exit(0);
     2956                }
     2957                break;
     2958            }
     2959
     2960            ////////////////////
     2961            case READ_HEAP_LAST:
     2962            {
     2963                if (r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)
     2964                {
     2965                    HeapEntry last_entry;
     2966                    last_entry.owner.srcid = 0;
     2967                    last_entry.owner.inst  = false;
     2968
     2969                    if (m_heap.is_full())
     2970                    {
     2971                        last_entry.next = r_read_ptr.read();
     2972                        m_heap.unset_full();
     2973                    }
     2974                    else
     2975                    {
     2976                        last_entry.next = r_read_next_ptr.read();
     2977                    }
     2978                    m_heap.write(r_read_ptr.read(),last_entry);
     2979                    r_read_fsm = READ_RSP;
     2980                }
     2981                else
     2982                {
     2983                    std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_LAST"
     2984                        << "Bad HEAP allocation" << std::endl;
     2985                    exit(0);
     2986                }
     2987                break;
     2988            }
     2989            //////////////
     2990            case READ_RSP:    //  request the TGT_RSP FSM to return data
     2991            {
     2992                if (!r_read_to_tgt_rsp_req)
     2993                {
     2994                    for (size_t i = 0; i < m_words; i++)
     2995                    {
     2996                        r_read_to_tgt_rsp_data[i] = r_read_data[i];
     2997                    }
     2998                    r_read_to_tgt_rsp_word   = m_x[(addr_t) m_cmd_read_addr_fifo.read()];
     2999                    r_read_to_tgt_rsp_length = m_cmd_read_length_fifo.read();
     3000                    r_read_to_tgt_rsp_srcid  = m_cmd_read_srcid_fifo.read();
     3001                    r_read_to_tgt_rsp_trdid  = m_cmd_read_trdid_fifo.read();
     3002                    r_read_to_tgt_rsp_pktid  = m_cmd_read_pktid_fifo.read();
     3003                    r_read_to_tgt_rsp_ll_key = r_read_ll_key.read();
     3004                    cmd_read_fifo_get        = true;
     3005                    r_read_to_tgt_rsp_req    = true;
     3006                    r_read_fsm               = READ_IDLE;
    27223007
    27233008#if DEBUG_MEMC_READ
    27243009                    if (m_debug)
    2725                         std::cout << "  <MEMC " << name() << " READ_HEAP_REQ>"
    2726                             << " Requesting HEAP lock " << std::endl;
    2727 #endif
    2728                     break;
    2729                 }
    2730 
    2731                 ////////////////////
    2732             case READ_HEAP_LOCK:   // read data in cache, update the directory
    2733                 // and prepare the HEAP update
    2734                 {
    2735                     if (r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)
    2736                     {
    2737                         // enter counter mode when we reach the limit of copies or the heap is full
    2738                         bool go_cnt = (r_read_count.read() >= m_max_copies) or m_heap.is_full();
    2739 
    2740                         // read data in the cache
    2741                         size_t set = m_y[(addr_t)(m_cmd_read_addr_fifo.read())];
    2742                         size_t way = r_read_way.read();
    2743 
    2744                         m_cache_data.read_line(way, set, r_read_data);
    2745 
    2746                         // update the cache directory
    2747                         DirectoryEntry entry;
    2748                         entry.valid  = true;
    2749                         entry.is_cnt = go_cnt;
    2750                         entry.dirty  = r_read_dirty.read();
    2751                         entry.tag    = r_read_tag.read();
    2752                         entry.lock   = r_read_lock.read();
    2753                         entry.count  = r_read_count.read() + 1;
    2754 
    2755                         if (not go_cnt)         // Not entering counter mode
    2756                         {
    2757                             entry.owner.srcid    = r_read_copy.read();
    2758                             entry.owner.inst     = r_read_copy_inst.read();
    2759                             entry.ptr            = m_heap.next_free_ptr();   // set pointer on the heap
    2760                         }
    2761                         else                // Entering Counter mode
    2762                         {
    2763                             entry.owner.srcid    = 0;
    2764                             entry.owner.inst     = false;
    2765                             entry.ptr            = 0;
    2766                         }
    2767 
    2768                         m_cache_directory.write(set, way, entry);
    2769 
    2770                         // prepare the heap update (add an entry, or clear the linked list)
    2771                         if (not go_cnt)      // not switching to counter mode
    2772                         {
    2773                             // We test if the next free entry in the heap is the last
    2774                             HeapEntry heap_entry = m_heap.next_free_entry();
    2775                             r_read_next_ptr      = heap_entry.next;
    2776                             r_read_last_free     = (heap_entry.next == m_heap.next_free_ptr());
    2777 
    2778                             r_read_fsm           = READ_HEAP_WRITE; // add an entry in the HEAP
    2779                         }
    2780                         else            // switching to counter mode
    2781                         {
    2782                             if (r_read_count.read() >1)              // heap must be cleared
    2783                             {
    2784                                 HeapEntry next_entry = m_heap.read(r_read_ptr.read());
    2785                                 r_read_next_ptr      = m_heap.next_free_ptr();
    2786                                 m_heap.write_free_ptr(r_read_ptr.read());
    2787 
    2788                                 if (next_entry.next == r_read_ptr.read())    // last entry
    2789                                 {
    2790                                     r_read_fsm = READ_HEAP_LAST;    // erase the entry
    2791                                 }
    2792                                 else                                        // not the last entry
    2793                                 {
    2794                                     r_read_ptr = next_entry.next;
    2795                                     r_read_fsm = READ_HEAP_ERASE;   // erase the list
    2796                                 }
    2797                             }
    2798                             else  // the heap is not used / nothing to do
    2799                             {
    2800                                 r_read_fsm = READ_RSP;
    2801                             }
    2802                         }
     3010                    {
     3011                        std::cout << "  <MEMC " << name() << " READ_RSP> Request TGT_RSP FSM to return data:"
     3012                            << " rsrcid = " << std::hex << m_cmd_read_srcid_fifo.read()
     3013                            << " / address = " << std::hex << m_cmd_read_addr_fifo.read()
     3014                            << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
     3015                    }
     3016#endif
     3017                }
     3018                break;
     3019            }
     3020            ///////////////////
     3021            case READ_TRT_LOCK: // read miss : check the Transaction Table
     3022            {
     3023                if (r_alloc_trt_fsm.read() == ALLOC_TRT_READ)
     3024                {
     3025                    size_t index     = 0;
     3026                    addr_t addr      = (addr_t) m_cmd_read_addr_fifo.read();
     3027                    bool   hit_read  = m_trt.hit_read(m_nline[addr], index);
     3028                    bool   hit_write = m_trt.hit_write(m_nline[addr]);
     3029                    bool   wok       = not m_trt.full(index);
     3030
     3031                    if (hit_read or !wok or hit_write) // line already requested or no space
     3032                    {
     3033                        if (!wok)                  m_cpt_trt_full++;
     3034                        if (hit_read or hit_write) m_cpt_trt_rb++;
     3035                        r_read_fsm = READ_IDLE;
     3036                    }
     3037                    else // missing line is requested to the XRAM
     3038                    {
     3039                        m_cpt_read_miss++;
     3040                        r_read_trt_index = index;
     3041                        r_read_fsm       = READ_TRT_SET;
     3042                    }
    28033043
    28043044#if DEBUG_MEMC_READ
    2805                         if (m_debug)
    2806                             std::cout << "  <MEMC " << name() << " READ_HEAP_LOCK> Update directory:"
    2807                                 << " tag = " << std::hex << entry.tag
    2808                                 << " set = " << std::dec << set
    2809                                 << " way = " << way
    2810                                 << " count = " << entry.count
    2811                                 << " is_cnt = " << entry.is_cnt << std::endl;
    2812 #endif
    2813                     }
    2814                     else
    2815                     {
    2816                         std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_LOCK"
    2817                             << "Bad HEAP allocation"   << std::endl;
    2818                         exit(0);
    2819                     }
    2820                     break;
    2821                 }
    2822                 /////////////////////
    2823             case READ_HEAP_WRITE:       // add an entry in the heap
    2824                 {
    2825                     if (r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)
    2826                     {
    2827                         HeapEntry heap_entry;
    2828                         heap_entry.owner.srcid    = m_cmd_read_srcid_fifo.read();
    2829                         heap_entry.owner.inst     = ((m_cmd_read_pktid_fifo.read() & 0x2) != 0);
    2830 
    2831                         if (r_read_count.read() == 1)  // creation of a new linked list
    2832                         {
    2833                             heap_entry.next         = m_heap.next_free_ptr();
    2834                         }
    2835                         else                         // head insertion in existing list
    2836                         {
    2837                             heap_entry.next         = r_read_ptr.read();
    2838                         }
    2839                         m_heap.write_free_entry(heap_entry);
    2840                         m_heap.write_free_ptr(r_read_next_ptr.read());
    2841                         if (r_read_last_free.read())  m_heap.set_full();
    2842 
    2843                         r_read_fsm = READ_RSP;
    2844 
     3045                    if (m_debug)
     3046                    {
     3047                        std::cout << "  <MEMC " << name() << " READ_TRT_LOCK> Check TRT:"
     3048                            << " hit_read = " << hit_read
     3049                            << " / hit_write = " << hit_write
     3050                            << " / full = " << !wok << std::endl;
     3051                    }
     3052#endif
     3053                }
     3054                break;
     3055            }
     3056            //////////////////
     3057            case READ_TRT_SET: // register get transaction in TRT
     3058            {
     3059                if (r_alloc_trt_fsm.read() == ALLOC_TRT_READ)
     3060                {
     3061                    m_trt.set(r_read_trt_index.read(),
     3062                            true,      // GET
     3063                            m_nline[(addr_t) (m_cmd_read_addr_fifo.read())],
     3064                            m_cmd_read_srcid_fifo.read(),
     3065                            m_cmd_read_trdid_fifo.read(),
     3066                            m_cmd_read_pktid_fifo.read(),
     3067                            true,      // proc read
     3068                            m_cmd_read_length_fifo.read(),
     3069                            m_x[(addr_t) (m_cmd_read_addr_fifo.read())],
     3070                            std::vector<be_t> (m_words, 0),
     3071                            std::vector<data_t> (m_words, 0),
     3072                            r_read_ll_key.read());
    28453073#if DEBUG_MEMC_READ
    2846                         if (m_debug)
    2847                             std::cout << "  <MEMC " << name() << " READ_HEAP_WRITE> Add an entry in the heap:"
    2848                                 << " owner_id = " << std::hex << heap_entry.owner.srcid
    2849                                 << " owner_ins = " << std::dec << heap_entry.owner.inst << std::endl;
    2850 #endif
    2851                     }
    2852                     else
    2853                     {
    2854                         std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_WRITE"
    2855                             << "Bad HEAP allocation" << std::endl;
    2856                         exit(0);
    2857                     }
    2858                     break;
    2859                 }
    2860                 /////////////////////
    2861             case READ_HEAP_ERASE:
    2862                 {
    2863                     if (r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)
    2864                     {
    2865                         HeapEntry next_entry = m_heap.read(r_read_ptr.read());
    2866                         if (next_entry.next == r_read_ptr.read())
    2867                         {
    2868                             r_read_fsm = READ_HEAP_LAST;
    2869                         }
    2870                         else
    2871                         {
    2872                             r_read_ptr = next_entry.next;
    2873                             r_read_fsm = READ_HEAP_ERASE;
    2874                         }
    2875                     }
    2876                     else
    2877                     {
    2878                         std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_ERASE"
    2879                             << "Bad HEAP allocation" << std::endl;
    2880                         exit(0);
    2881                     }
    2882                     break;
    2883                 }
    2884 
    2885                 ////////////////////
    2886             case READ_HEAP_LAST:
    2887                 {
    2888                     if (r_alloc_heap_fsm.read() == ALLOC_HEAP_READ)
    2889                     {
    2890                         HeapEntry last_entry;
    2891                         last_entry.owner.srcid    = 0;
    2892                         last_entry.owner.inst     = false;
    2893 
    2894                         if (m_heap.is_full())
    2895                         {
    2896                             last_entry.next       = r_read_ptr.read();
    2897                             m_heap.unset_full();
    2898                         }
    2899                         else
    2900                         {
    2901                             last_entry.next       = r_read_next_ptr.read();
    2902                         }
    2903                         m_heap.write(r_read_ptr.read(),last_entry);
    2904                         r_read_fsm = READ_RSP;
    2905                     }
    2906                     else
    2907                     {
    2908                         std::cout << "VCI_MEM_CACHE ERROR " << name() << " READ_HEAP_LAST"
    2909                             << "Bad HEAP allocation" << std::endl;
    2910                         exit(0);
    2911                     }
    2912                     break;
    2913                 }
    2914                 //////////////
    2915             case READ_RSP:    //  request the TGT_RSP FSM to return data
    2916                 {
    2917                     if (!r_read_to_tgt_rsp_req)
    2918                     {
    2919                         for(size_t i=0 ; i<m_words ; i++)  r_read_to_tgt_rsp_data[i] = r_read_data[i];
    2920                         r_read_to_tgt_rsp_word   = m_x[(addr_t) m_cmd_read_addr_fifo.read()];
    2921                         r_read_to_tgt_rsp_length = m_cmd_read_length_fifo.read();
    2922                         r_read_to_tgt_rsp_srcid  = m_cmd_read_srcid_fifo.read();
    2923                         r_read_to_tgt_rsp_trdid  = m_cmd_read_trdid_fifo.read();
    2924                         r_read_to_tgt_rsp_pktid  = m_cmd_read_pktid_fifo.read();
    2925                         r_read_to_tgt_rsp_ll_key = r_read_ll_key.read();
    2926                         cmd_read_fifo_get        = true;
    2927                         r_read_to_tgt_rsp_req    = true;
    2928                         r_read_fsm               = READ_IDLE;
     3074                    if (m_debug)
     3075                    {
     3076                        std::cout << "  <MEMC " << name() << " READ_TRT_SET> Set a GET in TRT:"
     3077                            << " address = " << std::hex << m_cmd_read_addr_fifo.read()
     3078                            << " / srcid = " << std::hex << m_cmd_read_srcid_fifo.read() << std::endl;
     3079                    }
     3080#endif
     3081                    r_read_fsm = READ_TRT_REQ;
     3082                }
     3083                break;
     3084            }
     3085
     3086            //////////////////
     3087            case READ_TRT_REQ:   // consume the read request in FIFO and send it to IXR_CMD_FSM
     3088            {
     3089                if (not r_read_to_ixr_cmd_req)
     3090                {
     3091                    cmd_read_fifo_get       = true;
     3092                    r_read_to_ixr_cmd_req   = true;
     3093                    r_read_to_ixr_cmd_index = r_read_trt_index.read();
     3094                    r_read_fsm              = READ_IDLE;
    29293095
    29303096#if DEBUG_MEMC_READ
    2931                         if (m_debug)
    2932                             std::cout << "  <MEMC " << name() << " READ_RSP> Request TGT_RSP FSM to return data:"
    2933                                 << " rsrcid = " << std::hex << m_cmd_read_srcid_fifo.read()
    2934                                 << " / address = " << std::hex << m_cmd_read_addr_fifo.read()
    2935                                 << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
    2936 #endif
    2937                     }
    2938                     break;
    2939                 }
    2940                 ///////////////////
    2941             case READ_TRT_LOCK: // read miss : check the Transaction Table
    2942                 {
    2943                     if (r_alloc_trt_fsm.read() == ALLOC_TRT_READ)
    2944                     {
    2945                         size_t      index     = 0;
    2946                         addr_t      addr      = (addr_t) m_cmd_read_addr_fifo.read();
    2947                         bool        hit_read  = m_trt.hit_read(m_nline[addr], index);
    2948                         bool        hit_write = m_trt.hit_write(m_nline[addr]);
    2949                         bool        wok       = not m_trt.full(index);
    2950 
    2951                         if (hit_read or !wok or hit_write)    // line already requested or no space
    2952                         {
    2953                             if (!wok)                    m_cpt_trt_full++;
    2954                             if (hit_read or hit_write)   m_cpt_trt_rb++;
    2955                             r_read_fsm = READ_IDLE;
    2956                         }
    2957                         else                  // missing line is requested to the XRAM
    2958                         {
    2959                             m_cpt_read_miss++;
    2960                             r_read_trt_index = index;
    2961                             r_read_fsm       = READ_TRT_SET;
    2962                         }
    2963 
    2964 #if DEBUG_MEMC_READ
    2965                         if (m_debug)
    2966                             std::cout << "  <MEMC " << name() << " READ_TRT_LOCK> Check TRT:"
    2967                                 << " hit_read = " << hit_read
    2968                                 << " / hit_write = " << hit_write
    2969                                 << " / full = " << !wok << std::endl;
    2970 #endif
    2971                     }
    2972                     break;
    2973                 }
    2974                 //////////////////
    2975             case READ_TRT_SET:      // register get transaction in TRT
    2976                 {
    2977                     if (r_alloc_trt_fsm.read() == ALLOC_TRT_READ)
    2978                     {
    2979                         m_trt.set( r_read_trt_index.read(),
    2980                                 true,      // GET
    2981                                 m_nline[(addr_t)(m_cmd_read_addr_fifo.read())],
    2982                                 m_cmd_read_srcid_fifo.read(),
    2983                                 m_cmd_read_trdid_fifo.read(),
    2984                                 m_cmd_read_pktid_fifo.read(),
    2985                                 true,      // proc read
    2986                                 m_cmd_read_length_fifo.read(),
    2987                                 m_x[(addr_t)(m_cmd_read_addr_fifo.read())],
    2988                                 std::vector<be_t> (m_words,0),
    2989                                 std::vector<data_t> (m_words,0),
    2990                                 r_read_ll_key.read());
    2991 #if DEBUG_MEMC_READ
    2992                         if (m_debug)
    2993                             std::cout << "  <MEMC " << name() << " READ_TRT_SET> Set a GET in TRT:"
    2994                                 << " address = " << std::hex << m_cmd_read_addr_fifo.read()
    2995                                 << " / srcid = " << std::hex << m_cmd_read_srcid_fifo.read() << std::endl;
    2996 #endif
    2997                         r_read_fsm = READ_TRT_REQ;
    2998                     }
    2999                     break;
    3000                 }
    3001 
    3002                 //////////////////
    3003             case READ_TRT_REQ:   // consume the read request in FIFO and send it to IXR_CMD_FSM
    3004                 {
    3005                     if (not r_read_to_ixr_cmd_req)
    3006                     {
    3007                         cmd_read_fifo_get       = true;
    3008                         r_read_to_ixr_cmd_req   = true;
    3009                         r_read_to_ixr_cmd_index = r_read_trt_index.read();
    3010                         r_read_fsm              = READ_IDLE;
    3011 
    3012 #if DEBUG_MEMC_READ
    3013                         if (m_debug)
    3014                             std::cout << "  <MEMC " << name() << " READ_TRT_REQ> Request GET transaction for address "
    3015                                 << std::hex << m_cmd_read_addr_fifo.read() << std::endl;
    3016 #endif
    3017                     }
    3018                     break;
    3019                 }
     3097                    if (m_debug)
     3098                    {
     3099                        std::cout << "  <MEMC " << name() << " READ_TRT_REQ> Request GET transaction for address "
     3100                            << std::hex << m_cmd_read_addr_fifo.read() << std::endl;
     3101                    }
     3102#endif
     3103                }
     3104                break;
     3105            }
    30203106        } // end switch read_fsm
    30213107
     
    30533139        /////////////////////////////////////////////////////////////////////////////////////
    30543140
    3055         //std::cout << std::endl << "write_fsm" << std::endl;
    3056 
    3057         switch(r_write_fsm.read())
     3141        switch (r_write_fsm.read())
    30583142        {
    30593143            ////////////////
    30603144            case WRITE_IDLE:  // copy first word of a write burst in local buffer
    3061                 {
    3062                     if (not m_cmd_write_addr_fifo.rok()) break;
    3063 
    3064                     // consume a word in the FIFO & write it in the local buffer
    3065                     cmd_write_fifo_get  = true;
    3066                     size_t index        = m_x[(addr_t)(m_cmd_write_addr_fifo.read())];
    3067 
    3068                     r_write_address     = (addr_t)(m_cmd_write_addr_fifo.read());
    3069                     r_write_word_index  = index;
    3070                     r_write_word_count  = 0;
    3071                     r_write_data[index] = m_cmd_write_data_fifo.read();
    3072                     r_write_srcid       = m_cmd_write_srcid_fifo.read();
    3073                     r_write_trdid       = m_cmd_write_trdid_fifo.read();
    3074                     r_write_pktid       = m_cmd_write_pktid_fifo.read();
    3075 
    3076                     // if SC command, get the SC key
    3077                     if ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC)
    3078                     {
    3079                         assert( not m_cmd_write_eop_fifo.read() &&
    3080                                 "MEMC ERROR in WRITE_IDLE state: "
    3081                                 "invalid packet format for SC command");
    3082 
    3083                         r_write_sc_key = m_cmd_write_data_fifo.read();
    3084                     }
    3085 
    3086                     // initialize the be field for all words
    3087                     for(size_t word=0 ; word<m_words ; word++)
    3088                     {
    3089                         if (word == index) r_write_be[word] = m_cmd_write_be_fifo.read();
    3090                         else               r_write_be[word] = 0x0;
    3091                     }
    3092 
    3093                     if (m_cmd_write_eop_fifo.read())
    3094                     {
    3095                         r_write_fsm = WRITE_DIR_REQ;
    3096                     }
    3097                     else
    3098                     {
    3099                         r_write_fsm = WRITE_NEXT;
    3100                     }
     3145            {
     3146                if (not m_cmd_write_addr_fifo.rok()) break;
     3147
     3148                // consume a word in the FIFO & write it in the local buffer
     3149                cmd_write_fifo_get  = true;
     3150                size_t index        = m_x[(addr_t) (m_cmd_write_addr_fifo.read())];
     3151
     3152                r_write_address     = (addr_t) (m_cmd_write_addr_fifo.read());
     3153                r_write_word_index  = index;
     3154                r_write_word_count  = 0;
     3155                r_write_data[index] = m_cmd_write_data_fifo.read();
     3156                r_write_srcid       = m_cmd_write_srcid_fifo.read();
     3157                r_write_trdid       = m_cmd_write_trdid_fifo.read();
     3158                r_write_pktid       = m_cmd_write_pktid_fifo.read();
     3159
     3160                // if SC command, get the SC key
     3161                if ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC)
     3162                {
     3163                    assert(not m_cmd_write_eop_fifo.read() &&
     3164                            "MEMC ERROR in WRITE_IDLE state: "
     3165                            "invalid packet format for SC command");
     3166
     3167                    r_write_sc_key = m_cmd_write_data_fifo.read();
     3168                }
     3169
     3170                // initialize the be field for all words
     3171                for (size_t word = 0; word < m_words; word++)
     3172                {
     3173                    if (word == index) r_write_be[word] = m_cmd_write_be_fifo.read();
     3174                    else               r_write_be[word] = 0x0;
     3175                }
     3176
     3177                if (m_cmd_write_eop_fifo.read())
     3178                {
     3179                    r_write_fsm = WRITE_DIR_REQ;
     3180                }
     3181                else
     3182                {
     3183                    r_write_fsm = WRITE_NEXT;
     3184                }
    31013185
    31023186#if DEBUG_MEMC_WRITE
    3103                     if (m_debug)
    3104                         std::cout << "  <MEMC " << name() << " WRITE_IDLE> Write request "
    3105                             << " srcid = " << std::hex << m_cmd_write_srcid_fifo.read()
    3106                             << " / address = " << std::hex << m_cmd_write_addr_fifo.read()
    3107                             << " / data = " << m_cmd_write_data_fifo.read() << std::endl;
    3108 #endif
    3109                     break;
    3110                 }
    3111                 ////////////////
     3187                if (m_debug)
     3188                {
     3189                    std::cout << "  <MEMC " << name() << " WRITE_IDLE> Write request "
     3190                        << " srcid = " << std::hex << m_cmd_write_srcid_fifo.read()
     3191                        << " / address = " << std::hex << m_cmd_write_addr_fifo.read()
     3192                        << " / data = " << m_cmd_write_data_fifo.read() << std::endl;
     3193                }
     3194#endif
     3195                break;
     3196            }
     3197            ////////////////
    31123198            case WRITE_NEXT:  // copy next word of a write burst in local buffer
    3113                 {
    3114                     if (not m_cmd_write_addr_fifo.rok()) break;
    3115 
    3116                     // check that the next word is in the same cache line
    3117                     assert((m_nline[(addr_t)(r_write_address.read())] ==
     3199            {
     3200                if (not m_cmd_write_addr_fifo.rok()) break;
     3201
     3202                // check that the next word is in the same cache line
     3203                assert((m_nline[(addr_t)(r_write_address.read())] ==
    31183204                            m_nline[(addr_t)(m_cmd_write_addr_fifo.read())]) &&
    3119                             "MEMC ERROR in WRITE_NEXT state: Illegal write burst");
    3120 
    3121                     size_t index = m_x[(addr_t)(m_cmd_write_addr_fifo.read())];
    3122                     bool   is_sc = ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC);
    3123 
    3124                     // check that SC command has constant address
    3125                     assert((not is_sc or (index == r_write_word_index)) &&
    3126                             "MEMC ERROR in WRITE_NEXT state: "
    3127                             "the address must be constant on a SC command");
    3128 
    3129                     // check that SC command has two flits
    3130                     assert((not is_sc or m_cmd_write_eop_fifo.read()) &&
    3131                             "MEMC ERROR in WRITE_NEXT state: "
    3132                             "invalid packet format for SC command");
    3133 
    3134                     // consume a word in the FIFO & write it in the local buffer
    3135                     cmd_write_fifo_get  = true;
    3136 
    3137                     r_write_be[index]   = m_cmd_write_be_fifo.read();
    3138                     r_write_data[index] = m_cmd_write_data_fifo.read();
    3139 
    3140                     // the first flit of a SC command is the reservation key and
    3141                     // therefore it must not be counted as a data to write
    3142                     if (not is_sc)
    3143                     {
    3144                         r_write_word_count = r_write_word_count.read() + 1;
    3145                     }
    3146 
    3147                     if (m_cmd_write_eop_fifo.read()) r_write_fsm = WRITE_DIR_REQ;
     3205                        "MEMC ERROR in WRITE_NEXT state: Illegal write burst");
     3206
     3207                size_t index = m_x[(addr_t)(m_cmd_write_addr_fifo.read())];
     3208                bool   is_sc = ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC);
     3209
     3210                // check that SC command has constant address
     3211                assert((not is_sc or (index == r_write_word_index)) &&
     3212                        "MEMC ERROR in WRITE_NEXT state: "
     3213                        "the address must be constant on a SC command");
     3214
     3215                // check that SC command has two flits
     3216                assert((not is_sc or m_cmd_write_eop_fifo.read()) &&
     3217                        "MEMC ERROR in WRITE_NEXT state: "
     3218                        "invalid packet format for SC command");
     3219
     3220                // consume a word in the FIFO & write it in the local buffer
     3221                cmd_write_fifo_get  = true;
     3222
     3223                r_write_be[index]   = m_cmd_write_be_fifo.read();
     3224                r_write_data[index] = m_cmd_write_data_fifo.read();
     3225
     3226                // the first flit of a SC command is the reservation key and
     3227                // therefore it must not be counted as a data to write
     3228                if (not is_sc)
     3229                {
     3230                    r_write_word_count = r_write_word_count.read() + 1;
     3231                }
     3232
     3233                if (m_cmd_write_eop_fifo.read())
     3234                {
     3235                    r_write_fsm = WRITE_DIR_REQ;
     3236                }
    31483237
    31493238#if DEBUG_MEMC_WRITE
    3150                     if (m_debug)
    3151                         std::cout << "  <MEMC " << name()
    3152                             << " WRITE_NEXT> Write another word in local buffer"
    3153                             << std::endl;
    3154 #endif
    3155                     break;
    3156                 }
    3157                 ///////////////////
     3239                if (m_debug)
     3240                {
     3241                    std::cout << "  <MEMC " << name()
     3242                        << " WRITE_NEXT> Write another word in local buffer"
     3243                        << std::endl;
     3244                }
     3245#endif
     3246                break;
     3247            }
     3248            ///////////////////
    31583249            case WRITE_DIR_REQ: // Get the lock to the directory
    31593250                                // and access the llsc_global_table
    3160                 {
    3161                     if (r_alloc_dir_fsm.read() != ALLOC_DIR_WRITE ) break;
    3162 
     3251            {
     3252                if (r_alloc_dir_fsm.read() != ALLOC_DIR_WRITE) break;
     3253
     3254                if ((r_write_pktid.read() & 0x7) == TYPE_SC)
     3255                {
     3256                    // test address and key match of the SC command on the
     3257                    // LL/SC table without removing reservation. The reservation
     3258                    // will be erased after in this FSM.
     3259                    bool sc_success = m_llsc_table.check(r_write_address.read(),
     3260                            r_write_sc_key.read());
     3261
     3262                    r_write_sc_fail = not sc_success;
     3263
     3264                    if (not sc_success) r_write_fsm = WRITE_RSP;
     3265                    else                r_write_fsm = WRITE_DIR_LOCK;
     3266                }
     3267                else
     3268                {
     3269                    // write burst
     3270#define L2 soclib::common::uint32_log2
     3271                    addr_t min = r_write_address.read();
     3272                    addr_t max = r_write_address.read() +
     3273                        (r_write_word_count.read() << L2(vci_param_int::B));
     3274#undef L2
     3275
     3276                    m_llsc_table.sw(min, max);
     3277
     3278                    r_write_fsm = WRITE_DIR_LOCK;
     3279                }
     3280
     3281#if DEBUG_MEMC_WRITE
     3282                if (m_debug)
     3283                {
     3284                    std::cout << "  <MEMC " << name() << " WRITE_DIR_REQ> Requesting DIR lock "
     3285                        << std::endl;
     3286                }
     3287#endif
     3288                break;
     3289            }
     3290            ////////////////////
     3291            case WRITE_DIR_LOCK:     // access directory to check hit/miss
     3292            {
     3293                assert((r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
     3294                        "MEMC ERROR in ALLOC_DIR_LOCK state: Bad DIR allocation");
     3295
     3296                size_t way = 0;
     3297                DirectoryEntry entry(m_cache_directory.read(r_write_address.read(), way));
     3298
     3299                if (entry.valid)    // hit
     3300                {
     3301                    // copy directory entry in local buffer in case of hit
     3302                    r_write_is_cnt    = entry.is_cnt;
     3303                    r_write_lock      = entry.lock;
     3304                    r_write_tag       = entry.tag;
     3305                    r_write_copy      = entry.owner.srcid;
     3306                    r_write_copy_inst = entry.owner.inst;
     3307                    r_write_count     = entry.count;
     3308                    r_write_ptr       = entry.ptr;
     3309                    r_write_way       = way;
     3310
     3311                    if (entry.is_cnt and entry.count) r_write_fsm = WRITE_BC_DIR_READ;
     3312                    else                              r_write_fsm = WRITE_DIR_HIT;
     3313                }
     3314                else  // miss
     3315                {
     3316                    r_write_fsm = WRITE_MISS_TRT_LOCK;
     3317                }
     3318
     3319#if DEBUG_MEMC_WRITE
     3320                if (m_debug)
     3321                {
     3322                    std::cout << "  <MEMC " << name() << " WRITE_DIR_LOCK> Check the directory: "
     3323                        << " address = " << std::hex << r_write_address.read()
     3324                        << " / hit = " << std::dec << entry.valid
     3325                        << " / count = " << entry.count
     3326                        << " / is_cnt = " << entry.is_cnt ;
    31633327                    if ((r_write_pktid.read() & 0x7) == TYPE_SC)
    31643328                    {
    3165                         // test address and key match of the SC command on the
    3166                         // LL/SC table without removing reservation. The reservation
    3167                         // will be erased after in this FSM.
    3168                         bool sc_success = m_llsc_table.check(r_write_address.read(),
    3169                                                              r_write_sc_key.read());
    3170 
    3171                         r_write_sc_fail     = not sc_success;
    3172 
    3173                         if (not sc_success) r_write_fsm = WRITE_RSP;
    3174                         else                r_write_fsm = WRITE_DIR_LOCK;
     3329                        std::cout << " / SC access" << std::endl;
    31753330                    }
    31763331                    else
    31773332                    {
    3178                         // write burst
    3179 #define L2 soclib::common::uint32_log2
    3180                         addr_t min = r_write_address.read();
    3181                         addr_t max = r_write_address.read() +
    3182                                     (r_write_word_count.read() << L2(vci_param_int::B));
    3183 #undef L2
    3184 
    3185                         m_llsc_table.sw(min, max);
    3186 
    3187                         r_write_fsm = WRITE_DIR_LOCK;
    3188                     }
     3333                        std::cout << " / SW access" << std::endl;
     3334                    }
     3335                }
     3336#endif
     3337                break;
     3338            }
     3339            ///////////////////
     3340            case WRITE_DIR_HIT:    // update the cache directory with Dirty bit
     3341            // and update data cache
     3342            {
     3343                assert((r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
     3344                        "MEMC ERROR in ALLOC_DIR_HIT state: Bad DIR allocation");
     3345
     3346                DirectoryEntry entry;
     3347                entry.valid       = true;
     3348                entry.dirty       = true;
     3349                entry.tag         = r_write_tag.read();
     3350                entry.is_cnt      = r_write_is_cnt.read();
     3351                entry.lock        = r_write_lock.read();
     3352                entry.owner.srcid = r_write_copy.read();
     3353                entry.owner.inst  = r_write_copy_inst.read();
     3354                entry.count       = r_write_count.read();
     3355                entry.ptr         = r_write_ptr.read();
     3356
     3357                size_t set = m_y[(addr_t) (r_write_address.read())];
     3358                size_t way = r_write_way.read();
     3359
     3360                // update directory
     3361                m_cache_directory.write(set, way, entry);
     3362
     3363                // owner is true when the  the first registered copy is the writer itself
     3364                bool owner = ((r_write_copy.read() == r_write_srcid.read())
     3365                        and not r_write_copy_inst.read());
     3366
     3367                // no_update is true when there is no need for coherence transaction
     3368                bool no_update = ((r_write_count.read() == 0) or
     3369                        (owner and (r_write_count.read() == 1) and
     3370                         ((r_write_pktid.read() & 0x7) != TYPE_SC)));
     3371
     3372                // write data in the cache if no coherence transaction
     3373                if (no_update)
     3374                {
     3375                    // SC command but zero copies
     3376                    if ((r_write_pktid.read() & 0x7) == TYPE_SC)
     3377                    {
     3378                        m_llsc_table.sc(r_write_address.read(),
     3379                                r_write_sc_key.read());
     3380                    }
     3381
     3382                    for (size_t word = 0; word < m_words; word++)
     3383                    {
     3384                        m_cache_data.write(way,
     3385                                set,
     3386                                word,
     3387                                r_write_data[word].read(),
     3388                                r_write_be[word].read());
     3389                    }
     3390                }
     3391
     3392                if (owner and not no_update and ((r_write_pktid.read() & 0x7) != TYPE_SC))
     3393                {
     3394                    r_write_count = r_write_count.read() - 1;
     3395                }
     3396
     3397                if (no_update) // Write transaction completed
     3398                {
     3399                    r_write_fsm = WRITE_RSP;
     3400                }
     3401                else // coherence update required
     3402                {
     3403                    if (!r_write_to_cc_send_multi_req.read() and
     3404                            !r_write_to_cc_send_brdcast_req.read())
     3405                    {
     3406                        r_write_fsm = WRITE_UPT_LOCK;
     3407                    }
     3408                    else
     3409                    {
     3410                        r_write_fsm = WRITE_WAIT;
     3411                    }
     3412                }
    31893413
    31903414#if DEBUG_MEMC_WRITE
    3191                     if (m_debug)
    3192                         std::cout << "  <MEMC " << name() << " WRITE_DIR_REQ> Requesting DIR lock "
    3193                             << std::endl;
    3194 #endif
    3195                     break;
    3196                 }
    3197                 ////////////////////
    3198             case WRITE_DIR_LOCK:     // access directory to check hit/miss
    3199                 {
    3200                     assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
    3201                             "MEMC ERROR in ALLOC_DIR_LOCK state: Bad DIR allocation");
    3202 
    3203                     size_t  way = 0;
    3204                     DirectoryEntry entry(m_cache_directory.read(r_write_address.read(), way));
    3205 
    3206                     if (entry.valid)    // hit
    3207                     {
    3208                         // copy directory entry in local buffer in case of hit
    3209                         r_write_is_cnt     = entry.is_cnt;
    3210                         r_write_lock       = entry.lock;
    3211                         r_write_tag        = entry.tag;
    3212                         r_write_copy       = entry.owner.srcid;
    3213                         r_write_copy_inst  = entry.owner.inst;
    3214                         r_write_count      = entry.count;
    3215                         r_write_ptr        = entry.ptr;
    3216                         r_write_way        = way;
    3217 
    3218                         if (entry.is_cnt and entry.count) r_write_fsm = WRITE_BC_DIR_READ;
    3219                         else                              r_write_fsm = WRITE_DIR_HIT;
    3220                     }
    3221                     else  // miss
    3222                     {
    3223                         r_write_fsm = WRITE_MISS_TRT_LOCK;
    3224                     }
    3225 
    3226 #if DEBUG_MEMC_WRITE
    3227                     if (m_debug)
    3228                     {
    3229                         std::cout << "  <MEMC " << name() << " WRITE_DIR_LOCK> Check the directory: "
    3230                             << " address = " << std::hex << r_write_address.read()
    3231                             << " / hit = " << std::dec << entry.valid
    3232                             << " / count = " << entry.count
    3233                             << " / is_cnt = " << entry.is_cnt ;
    3234                         if ((r_write_pktid.read() & 0x7) == TYPE_SC)
    3235                             std::cout << " / SC access" << std::endl;
    3236                         else
    3237                             std::cout << " / SW access" << std::endl;
    3238                     }
    3239 #endif
    3240                     break;
    3241                 }
    3242                 ///////////////////
    3243             case WRITE_DIR_HIT:    // update the cache directory with Dirty bit
    3244                 // and update data cache
    3245                 {
    3246                     assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
    3247                             "MEMC ERROR in ALLOC_DIR_HIT state: Bad DIR allocation");
    3248 
    3249                     DirectoryEntry entry;
    3250                     entry.valid          = true;
    3251                     entry.dirty          = true;
    3252                     entry.tag            = r_write_tag.read();
    3253                     entry.is_cnt         = r_write_is_cnt.read();
    3254                     entry.lock           = r_write_lock.read();
    3255                     entry.owner.srcid    = r_write_copy.read();
    3256                     entry.owner.inst     = r_write_copy_inst.read();
    3257                     entry.count          = r_write_count.read();
    3258                     entry.ptr            = r_write_ptr.read();
    3259 
    3260                     size_t set           = m_y[(addr_t)(r_write_address.read())];
    3261                     size_t way           = r_write_way.read();
    3262 
    3263                     // update directory
    3264                     m_cache_directory.write(set, way, entry);
    3265 
    3266                     // owner is true when the  the first registered copy is the writer itself
    3267                     bool owner = ( (r_write_copy.read() == r_write_srcid.read())
    3268                             and not r_write_copy_inst.read());
    3269 
    3270                     // no_update is true when there is no need for coherence transaction
    3271                     bool no_update = ( (r_write_count.read() == 0) or
    3272                             (owner and (r_write_count.read() == 1) and
    3273                              ((r_write_pktid.read() & 0x7) != TYPE_SC)));
    3274 
    3275                     // write data in the cache if no coherence transaction
     3415                if (m_debug)
     3416                {
    32763417                    if (no_update)
    32773418                    {
    3278                         // SC command but zero copies
     3419                        std::cout << "  <MEMC " << name()
     3420                            << " WRITE_DIR_HIT> Write into cache / No coherence transaction" << std::endl;
     3421                    }
     3422                    else
     3423                    {
     3424                        std::cout << "  <MEMC " << name() << " WRITE_DIR_HIT> Coherence update required:"
     3425                            << " is_cnt = " << r_write_is_cnt.read()
     3426                            << " nb_copies = " << std::dec << r_write_count.read() << std::endl;
     3427                        if (owner)
     3428                        {
     3429                            std::cout << "       ... but the first copy is the writer" << std::endl;
     3430                        }
     3431                    }
     3432                }
     3433#endif
     3434                break;
     3435            }
     3436            ////////////////////
     3437            case WRITE_UPT_LOCK:  // Try to register the update request in UPT
     3438            {
     3439                if (r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE)
     3440                {
     3441                    bool   wok       = false;
     3442                    size_t index     = 0;
     3443                    size_t srcid     = r_write_srcid.read();
     3444                    size_t trdid     = r_write_trdid.read();
     3445                    size_t pktid     = r_write_pktid.read();
     3446                    addr_t nline     = m_nline[(addr_t) (r_write_address.read())];
     3447                    size_t nb_copies = r_write_count.read();
     3448                    size_t set       = m_y[(addr_t) (r_write_address.read())];
     3449                    size_t way       = r_write_way.read();
     3450
     3451                    wok = m_upt.set(true,  // it's an update transaction
     3452                            false, // it's not a broadcast
     3453                            true,  // response required
     3454                            false, // no acknowledge required
     3455                            srcid,
     3456                            trdid,
     3457                            pktid,
     3458                            nline,
     3459                            nb_copies,
     3460                            index);
     3461
     3462                    if (wok) // write data in cache
     3463                    {
    32793464                        if ((r_write_pktid.read() & 0x7) == TYPE_SC)
    32803465                        {
    32813466                            m_llsc_table.sc(r_write_address.read(),
    3282                                             r_write_sc_key.read());
     3467                                    r_write_sc_key.read());
    32833468                        }
    32843469
    3285                         for(size_t word=0 ; word<m_words ; word++)
     3470                        for (size_t word = 0; word < m_words; word++)
    32863471                        {
    3287                             m_cache_data.write( way,
    3288                                     set, 
    3289                                     word, 
    3290                                     r_write_data[word].read(), 
     3472                            m_cache_data.write(way,
     3473                                    set,
     3474                                    word,
     3475                                    r_write_data[word].read(),
    32913476                                    r_write_be[word].read());
    32923477                        }
    32933478                    }
    32943479
    3295                     if (owner and not no_update and ((r_write_pktid.read() & 0x7) != TYPE_SC))
    3296                     {
    3297                         r_write_count = r_write_count.read() - 1;
    3298                     }
    3299 
    3300                     if (no_update)     // Write transaction completed
    3301                     {
    3302                         r_write_fsm = WRITE_RSP;
    3303                     }
    3304                     else              // coherence update required
    3305                     {
    3306                         if (!r_write_to_cc_send_multi_req.read() and
    3307                                 !r_write_to_cc_send_brdcast_req.read())
     3480#if DEBUG_MEMC_WRITE
     3481                    if (m_debug and wok)
     3482                    {
     3483                        std::cout << "  <MEMC " << name()
     3484                            << " WRITE_UPT_LOCK> Register the multicast update in UPT / "
     3485                            << " nb_copies = " << r_write_count.read() << std::endl;
     3486                    }
     3487#endif
     3488                    r_write_upt_index = index;
     3489                    // releases the lock protecting UPT and the DIR if no entry...
     3490                    if (wok) r_write_fsm = WRITE_UPT_HEAP_LOCK;
     3491                    else     r_write_fsm = WRITE_WAIT;
     3492                }
     3493                break;
     3494            }
     3495
     3496            /////////////////////////
     3497            case WRITE_UPT_HEAP_LOCK:   // get access to heap
     3498            {
     3499                if (r_alloc_heap_fsm.read() == ALLOC_HEAP_WRITE)
     3500                {
     3501
     3502#if DEBUG_MEMC_WRITE
     3503                    if (m_debug)
     3504                    {
     3505                        std::cout << "  <MEMC " << name()
     3506                            << " WRITE_UPT_HEAP_LOCK> Get acces to the HEAP" << std::endl;
     3507                    }
     3508#endif
     3509                    r_write_fsm = WRITE_UPT_REQ;
     3510                }
     3511                break;
     3512            }
     3513
     3514            //////////////////
     3515            case WRITE_UPT_REQ:    // prepare the coherence transaction for the CC_SEND FSM
     3516            // and write the first copy in the FIFO
     3517            // send the request if only one copy
     3518            {
     3519                assert(not r_write_to_cc_send_multi_req.read() and
     3520                        not r_write_to_cc_send_brdcast_req.read() and
     3521                        "Error in VCI_MEM_CACHE : pending multicast or broadcast\n"
     3522                        "transaction in WRITE_UPT_REQ state");
     3523
     3524                r_write_to_cc_send_brdcast_req = false;
     3525                r_write_to_cc_send_trdid = r_write_upt_index.read();
     3526                r_write_to_cc_send_nline = m_nline[(addr_t)(r_write_address.read())];
     3527                r_write_to_cc_send_index = r_write_word_index.read();
     3528                r_write_to_cc_send_count = r_write_word_count.read();
     3529
     3530                for (size_t i = 0; i < m_words; i++)
     3531                {
     3532                    r_write_to_cc_send_be[i] = r_write_be[i].read();
     3533                }
     3534
     3535                size_t min = r_write_word_index.read();
     3536                size_t max = r_write_word_index.read() + r_write_word_count.read();
     3537                for (size_t i = min; i <= max; i++)
     3538                {
     3539                    r_write_to_cc_send_data[i] = r_write_data[i];
     3540                }
     3541
     3542                if ((r_write_copy.read() != r_write_srcid.read()) or
     3543                        ((r_write_pktid.read() & 0x7) == TYPE_SC) or
     3544                        r_write_copy_inst.read())
     3545                {
     3546                    // put the first srcid in the fifo
     3547                    write_to_cc_send_fifo_put   = true;
     3548                    write_to_cc_send_fifo_inst  = r_write_copy_inst.read();
     3549                    write_to_cc_send_fifo_srcid = r_write_copy.read();
     3550                    if (r_write_count.read() == 1)
     3551                    {
     3552                        r_write_fsm = WRITE_IDLE;
     3553                        r_write_to_cc_send_multi_req = true;
     3554                    }
     3555                    else
     3556                    {
     3557                        r_write_fsm = WRITE_UPT_NEXT;
     3558                        r_write_to_dec = false;
     3559
     3560                    }
     3561                }
     3562                else
     3563                {
     3564                    r_write_fsm = WRITE_UPT_NEXT;
     3565                    r_write_to_dec = false;
     3566                }
     3567
     3568#if DEBUG_MEMC_WRITE
     3569                if (m_debug)
     3570                {
     3571                    std::cout
     3572                        << "  <MEMC " << name()
     3573                        << " WRITE_UPT_REQ> Post first request to CC_SEND FSM"
     3574                        << " / srcid = " << std::dec << r_write_copy.read()
     3575                        << " / inst = "  << std::dec << r_write_copy_inst.read() << std::endl;
     3576
     3577                    if (r_write_count.read() == 1)
     3578                    {
     3579                        std::cout << "         ... and this is the last" << std::endl;
     3580                    }
     3581                }
     3582#endif
     3583                break;
     3584            }
     3585
     3586            ///////////////////
     3587            case WRITE_UPT_NEXT:
     3588            {
     3589                // continue the multi-update request to CC_SEND fsm
     3590                // when there is copies in the heap.
     3591                // if one copy in the heap is the writer itself
     3592                // the corresponding SRCID should not be written in the fifo,
     3593                // but the UPT counter must be decremented.
     3594                // As this decrement is done in the WRITE_UPT_DEC state,
     3595                // after the last copy has been found, the decrement request
     3596                // must be  registered in the r_write_to_dec flip-flop.
     3597
     3598                HeapEntry entry = m_heap.read(r_write_ptr.read());
     3599
     3600                bool dec_upt_counter;
     3601
     3602                // put the next srcid in the fifo
     3603                if ((entry.owner.srcid != r_write_srcid.read()) or
     3604                        ((r_write_pktid.read() & 0x7) == TYPE_SC) or
     3605                        entry.owner.inst)
     3606                {
     3607                    dec_upt_counter             = false;
     3608                    write_to_cc_send_fifo_put   = true;
     3609                    write_to_cc_send_fifo_inst  = entry.owner.inst;
     3610                    write_to_cc_send_fifo_srcid = entry.owner.srcid;
     3611
     3612#if DEBUG_MEMC_WRITE
     3613                    if (m_debug)
     3614                    {
     3615                        std::cout << "  <MEMC " << name() << " WRITE_UPT_NEXT> Post another request to CC_SEND FSM"
     3616                            << " / heap_index = " << std::dec << r_write_ptr.read()
     3617                            << " / srcid = " << std::dec << r_write_copy.read()
     3618                            << " / inst = "  << std::dec << r_write_copy_inst.read() << std::endl;
     3619                        if (entry.next == r_write_ptr.read())
    33083620                        {
    3309                             r_write_fsm = WRITE_UPT_LOCK;
     3621                            std::cout << "        ... and this is the last" << std::endl;
     3622                        }
     3623                    }
     3624#endif
     3625                }
     3626                else // the UPT counter must be decremented
     3627                {
     3628                    dec_upt_counter = true;
     3629#if DEBUG_MEMC_WRITE
     3630                    if (m_debug)
     3631                    {
     3632                        std::cout << "  <MEMC " << name() << " WRITE_UPT_NEXT> Skip one entry in heap matching the writer"
     3633                            << " / heap_index = " << std::dec << r_write_ptr.read()
     3634                            << " / srcid = " << std::dec << r_write_copy.read()
     3635                            << " / inst = "  << std::dec << r_write_copy_inst.read() << std::endl;
     3636                        if (entry.next == r_write_ptr.read())
     3637                        {
     3638                            std::cout << "        ... and this is the last" << std::endl;
     3639                        }
     3640                    }
     3641#endif
     3642                }
     3643
     3644                // register the possible UPT decrement request
     3645                r_write_to_dec = dec_upt_counter or r_write_to_dec.read();
     3646
     3647                if (not m_write_to_cc_send_inst_fifo.wok())
     3648                {
     3649                    std::cout << "*** VCI_MEM_CACHE ERROR " << name() << " WRITE_UPT_NEXT state" << std::endl
     3650                        << "The write_to_cc_send_fifo should not be full" << std::endl
     3651                        << "as the depth should be larger than the max number of copies" << std::endl;
     3652                    exit(0);
     3653                }
     3654
     3655                r_write_ptr = entry.next;
     3656
     3657                if (entry.next == r_write_ptr.read()) // last copy
     3658                {
     3659                    r_write_to_cc_send_multi_req = true;
     3660                    if (r_write_to_dec.read() or dec_upt_counter) r_write_fsm = WRITE_UPT_DEC;
     3661                    else                                          r_write_fsm = WRITE_IDLE;
     3662                }
     3663                break;
     3664            }
     3665
     3666            //////////////////
     3667            case WRITE_UPT_DEC:
     3668            {
     3669                // If the initial writer has a copy, it should not
     3670                // receive an update request, but the counter in the
     3671                // update table must be decremented by the MULTI_ACK FSM.
     3672
     3673                if (!r_write_to_multi_ack_req.read())
     3674                {
     3675                    r_write_to_multi_ack_req = true;
     3676                    r_write_to_multi_ack_upt_index = r_write_upt_index.read();
     3677                    r_write_fsm = WRITE_IDLE;
     3678                }
     3679                break;
     3680            }
     3681
     3682            ///////////////
     3683            case WRITE_RSP:  // Post a request to TGT_RSP FSM to acknowledge the write
     3684            // In order to increase the Write requests throughput,
     3685            // we don't wait to return in the IDLE state to consume
     3686            // a new request in the write FIFO
     3687            {
     3688                if (not r_write_to_tgt_rsp_req.read())
     3689                {
     3690                    // post the request to TGT_RSP_FSM
     3691                    r_write_to_tgt_rsp_req     = true;
     3692                    r_write_to_tgt_rsp_srcid   = r_write_srcid.read();
     3693                    r_write_to_tgt_rsp_trdid   = r_write_trdid.read();
     3694                    r_write_to_tgt_rsp_pktid   = r_write_pktid.read();
     3695                    r_write_to_tgt_rsp_sc_fail = r_write_sc_fail.read();
     3696
     3697                    // try to get a new write request from the FIFO
     3698                    if (not m_cmd_write_addr_fifo.rok())
     3699                    {
     3700                        r_write_fsm = WRITE_IDLE;
     3701                    }
     3702                    else
     3703                    {
     3704                        // consume a word in the FIFO & write it in the local buffer
     3705                        cmd_write_fifo_get  = true;
     3706                        size_t index        = m_x[(addr_t) (m_cmd_write_addr_fifo.read())];
     3707
     3708                        r_write_address     = (addr_t) (m_cmd_write_addr_fifo.read());
     3709                        r_write_word_index  = index;
     3710                        r_write_word_count  = 0;
     3711                        r_write_data[index] = m_cmd_write_data_fifo.read();
     3712                        r_write_srcid       = m_cmd_write_srcid_fifo.read();
     3713                        r_write_trdid       = m_cmd_write_trdid_fifo.read();
     3714                        r_write_pktid       = m_cmd_write_pktid_fifo.read();
     3715
     3716                        // if SC command, get the SC key
     3717                        if ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC)
     3718                        {
     3719                            assert(not m_cmd_write_eop_fifo.read() &&
     3720                                    "MEMC ERROR in WRITE_RSP state: "
     3721                                    "invalid packet format for SC command");
     3722
     3723                            r_write_sc_key = m_cmd_write_data_fifo.read();
     3724                        }
     3725
     3726                        // initialize the be field for all words
     3727                        for (size_t word = 0; word < m_words; word++)
     3728                        {
     3729                            if (word == index) r_write_be[word] = m_cmd_write_be_fifo.read();
     3730                            else               r_write_be[word] = 0x0;
     3731                        }
     3732
     3733                        if (m_cmd_write_eop_fifo.read())
     3734                        {
     3735                            r_write_fsm = WRITE_DIR_REQ;
    33103736                        }
    33113737                        else
    33123738                        {
    3313                             r_write_fsm = WRITE_WAIT;
     3739                            r_write_fsm = WRITE_NEXT;
    33143740                        }
    33153741                    }
     
    33183744                    if (m_debug)
    33193745                    {
    3320                         if (no_update)
     3746                        std::cout << "  <MEMC " << name() << " WRITE_RSP> Post a request to TGT_RSP FSM"
     3747                            << " : rsrcid = " << std::hex << r_write_srcid.read() << std::endl;
     3748                        if (m_cmd_write_addr_fifo.rok())
    33213749                        {
    3322                             std::cout << "  <MEMC " << name()
    3323                                 << " WRITE_DIR_HIT> Write into cache / No coherence transaction" << std::endl;
     3750                            std::cout << "                    New Write request: "
     3751                                << " srcid = " << std::hex << m_cmd_write_srcid_fifo.read()
     3752                                << " / address = " << m_cmd_write_addr_fifo.read()
     3753                                << " / data = " << m_cmd_write_data_fifo.read() << std::endl;
    33243754                        }
    3325                         else
    3326                         {
    3327                             std::cout << "  <MEMC " << name() << " WRITE_DIR_HIT> Coherence update required:"
    3328                                 << " is_cnt = " << r_write_is_cnt.read()
    3329                                 << " nb_copies = " << std::dec << r_write_count.read() << std::endl;
    3330                             if (owner) std::cout << "       ... but the first copy is the writer" << std::endl;
    3331                         }
    3332                     }
    3333 #endif
    3334                     break;
    3335                 }
    3336                 ////////////////////
    3337             case WRITE_UPT_LOCK:  // Try to register the update request in UPT
    3338                 {
    3339                     if (r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE)
    3340                     {
    3341                         bool        wok        = false;
    3342                         size_t      index      = 0;
    3343                         size_t      srcid      = r_write_srcid.read();
    3344                         size_t      trdid      = r_write_trdid.read();
    3345                         size_t      pktid      = r_write_pktid.read();
    3346                         addr_t      nline      = m_nline[(addr_t)(r_write_address.read())];
    3347                         size_t      nb_copies  = r_write_count.read();
    3348                         size_t      set        = m_y[(addr_t)(r_write_address.read())];
    3349                         size_t      way        = r_write_way.read();
    3350 
    3351                         wok = m_upt.set( true,  // it's an update transaction
    3352                                 false, // it's not a broadcast
    3353                                 true,  // response required
    3354                                 false, // no acknowledge required
    3355                                 srcid,   
    3356                                 trdid,
    3357                                 pktid,
    3358                                 nline,
    3359                                 nb_copies,
    3360                                 index);
    3361 
    3362                         if (wok )       // write data in cache
    3363                         {
    3364                            
    3365                             if ((r_write_pktid.read() & 0x7) == TYPE_SC)
    3366                             {
    3367                                 m_llsc_table.sc(r_write_address.read(),
    3368                                                 r_write_sc_key.read());
    3369                             }
    3370 
    3371                             for(size_t word=0 ; word<m_words ; word++)
    3372                             {
    3373                                 m_cache_data.write( way,
    3374                                         set,
    3375                                         word,
    3376                                         r_write_data[word].read(),
    3377                                         r_write_be[word].read());
    3378                             }
    3379                         }
    3380 
    3381 #if DEBUG_MEMC_WRITE
    3382                         if (m_debug and wok)
    3383                         {
    3384                             std::cout << "  <MEMC " << name()
    3385                                 << " WRITE_UPT_LOCK> Register the multicast update in UPT / "
    3386                                 << " nb_copies = " << r_write_count.read() << std::endl;
    3387                         }
    3388 #endif
    3389                         r_write_upt_index = index;
    3390                         // releases the lock protecting UPT and the DIR if no entry...
    3391                         if (wok) r_write_fsm = WRITE_UPT_HEAP_LOCK;
    3392                         else    r_write_fsm = WRITE_WAIT;
    3393                     }
    3394                     break;
    3395                 }
    3396 
    3397                 /////////////////////////
    3398             case WRITE_UPT_HEAP_LOCK:   // get access to heap
    3399                 {
    3400                     if (r_alloc_heap_fsm.read() == ALLOC_HEAP_WRITE)
    3401                     {
    3402 
    3403 #if DEBUG_MEMC_WRITE
    3404                         if (m_debug)
    3405                             std::cout << "  <MEMC " << name()
    3406                                 << " WRITE_UPT_HEAP_LOCK> Get acces to the HEAP" << std::endl;
    3407 #endif
    3408                         r_write_fsm = WRITE_UPT_REQ;
    3409                     }
    3410                     break;
    3411                 }
    3412 
    3413                 //////////////////
    3414             case WRITE_UPT_REQ:    // prepare the coherence transaction for the CC_SEND FSM
    3415                 // and write the first copy in the FIFO
    3416                 // send the request if only one copy
    3417                 {
    3418                     assert(not r_write_to_cc_send_multi_req.read()   and
    3419                             not r_write_to_cc_send_brdcast_req.read() and
    3420                             "Error in VCI_MEM_CACHE : pending multicast or broadcast\n"
    3421                             "transaction in WRITE_UPT_REQ state"
    3422                           );
    3423 
    3424                     r_write_to_cc_send_brdcast_req  = false;
    3425                     r_write_to_cc_send_trdid        = r_write_upt_index.read();
    3426                     r_write_to_cc_send_nline        = m_nline[(addr_t)(r_write_address.read())];
    3427                     r_write_to_cc_send_index        = r_write_word_index.read();
    3428                     r_write_to_cc_send_count        = r_write_word_count.read();
    3429 
    3430                     for(size_t i=0; i<m_words ; i++) r_write_to_cc_send_be[i]=r_write_be[i].read();
    3431 
    3432                     size_t min = r_write_word_index.read();
    3433                     size_t max = r_write_word_index.read() + r_write_word_count.read();
    3434                     for(size_t i=min ; i<=max ; i++) r_write_to_cc_send_data[i] = r_write_data[i];
    3435 
    3436                     if ((r_write_copy.read() != r_write_srcid.read()) or
    3437                        ((r_write_pktid.read() & 0x7) == TYPE_SC)      or
    3438                          r_write_copy_inst.read())
    3439                     {
    3440                         // put the first srcid in the fifo
    3441                         write_to_cc_send_fifo_put     = true;
    3442                         write_to_cc_send_fifo_inst    = r_write_copy_inst.read();
    3443                         write_to_cc_send_fifo_srcid   = r_write_copy.read();
    3444                         if (r_write_count.read() == 1)
    3445                         {
    3446                             r_write_fsm = WRITE_IDLE;
    3447                             r_write_to_cc_send_multi_req = true;
    3448                         }
    3449                         else
    3450                         {
    3451                             r_write_fsm = WRITE_UPT_NEXT;
    3452                             r_write_to_dec = false;
    3453 
    3454                         }
    3455                     }
    3456                     else
    3457                     {
    3458                         r_write_fsm = WRITE_UPT_NEXT;
    3459                         r_write_to_dec = false;
    3460                     }
     3755                    }
     3756#endif
     3757                }
     3758                break;
     3759            }
     3760
     3761            /////////////////////////
     3762            case WRITE_MISS_TRT_LOCK: // Miss : check Transaction Table
     3763            {
     3764                if (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE)
     3765                {
    34613766
    34623767#if DEBUG_MEMC_WRITE
    34633768                    if (m_debug)
    34643769                    {
    3465                         std::cout
    3466                             << "  <MEMC "    << name()
    3467                             << " WRITE_UPT_REQ> Post first request to CC_SEND FSM"
    3468                             << " / srcid = " << std::dec << r_write_copy.read()
    3469                             << " / inst = "  << std::dec << r_write_copy_inst.read() << std::endl;
    3470 
    3471                         if (r_write_count.read() == 1)
    3472                             std::cout << "         ... and this is the last" << std::endl;
    3473                     }
    3474 #endif
    3475                     break;
    3476                 }
    3477 
    3478                 ///////////////////
    3479             case WRITE_UPT_NEXT:
    3480                 {
    3481                     // continue the multi-update request to CC_SEND fsm
    3482                     // when there is copies in the heap.
    3483                     // if one copy in the heap is the writer itself
    3484                     // the corresponding SRCID should not be written in the fifo,
    3485                     // but the UPT counter must be decremented.
    3486                     // As this decrement is done in the WRITE_UPT_DEC state,
    3487                     // after the last copy has been found, the decrement request
    3488                     // must be  registered in the r_write_to_dec flip-flop.
    3489 
    3490                     HeapEntry entry = m_heap.read(r_write_ptr.read());
    3491 
    3492                     bool dec_upt_counter;
    3493 
    3494                     // put the next srcid in the fifo
    3495                     if ((entry.owner.srcid != r_write_srcid.read()) or
    3496                        ((r_write_pktid.read() & 0x7) == TYPE_SC)    or
    3497                          entry.owner.inst)
    3498                     {
    3499                         dec_upt_counter                = false;
    3500                         write_to_cc_send_fifo_put      = true;
    3501                         write_to_cc_send_fifo_inst     = entry.owner.inst;
    3502                         write_to_cc_send_fifo_srcid    = entry.owner.srcid;
     3770                        std::cout << "  <MEMC " << name() << " WRITE_MISS_TRT_LOCK> Check the TRT" << std::endl;
     3771                    }
     3772#endif
     3773                    size_t hit_index = 0;
     3774                    size_t wok_index = 0;
     3775                    addr_t addr = (addr_t) r_write_address.read();
     3776                    bool   hit_read  = m_trt.hit_read(m_nline[addr], hit_index);
     3777                    bool   hit_write = m_trt.hit_write(m_nline[addr]);
     3778                    bool   wok       = not m_trt.full(wok_index);
     3779
     3780                    // wait an empty entry in TRT
     3781                    if (not hit_read and (not wok or hit_write))
     3782                    {
     3783                        r_write_fsm = WRITE_WAIT;
     3784                        m_cpt_trt_full++;
     3785
     3786                        break;
     3787                    }
     3788
     3789                    if ((r_write_pktid.read() & 0x7) == TYPE_SC)
     3790                    {
     3791                        m_llsc_table.sc(r_write_address.read(),
     3792                                r_write_sc_key.read());
     3793                    }
     3794
     3795                    // register the modified data in TRT
     3796                    if (hit_read)
     3797                    {
     3798                        r_write_trt_index = hit_index;
     3799                        r_write_fsm       = WRITE_MISS_TRT_DATA;
     3800                        m_cpt_write_miss++;
     3801                        break;
     3802                    }
     3803
     3804                    // set a new entry in TRT
     3805                    if (wok and not hit_write)
     3806                    {
     3807                        r_write_trt_index = wok_index;
     3808                        r_write_fsm       = WRITE_MISS_TRT_SET;
     3809                        m_cpt_write_miss++;
     3810                        break;
     3811                    }
     3812
     3813                    assert(false && "VCI_MEM_CACHE ERROR: this part must not be reached");
     3814                }
     3815                break;
     3816            }
     3817
     3818            ////////////////
     3819            case WRITE_WAIT:  // release the locks protecting the shared ressources
     3820            {
    35033821
    35043822#if DEBUG_MEMC_WRITE
    3505                         if (m_debug)
    3506                         {
    3507                             std::cout << "  <MEMC " << name() << " WRITE_UPT_NEXT> Post another request to CC_SEND FSM"
    3508                                 << " / heap_index = " << std::dec << r_write_ptr.read()
    3509                                 << " / srcid = " << std::dec << r_write_copy.read()
    3510                                 << " / inst = "  << std::dec << r_write_copy_inst.read() << std::endl;
    3511                             if (entry.next == r_write_ptr.read())
    3512                                 std::cout << "        ... and this is the last" << std::endl;
    3513                         }
    3514 #endif
    3515                     }
    3516                     else                                // the UPT counter must be decremented
    3517                     {
    3518                         dec_upt_counter = true;
    3519 
    3520 #if DEBUG_MEMC_WRITE
    3521                         if (m_debug)
    3522                         {
    3523                             std::cout << "  <MEMC " << name() << " WRITE_UPT_NEXT> Skip one entry in heap matching the writer"
    3524                                 << " / heap_index = " << std::dec << r_write_ptr.read()
    3525                                 << " / srcid = " << std::dec << r_write_copy.read()
    3526                                 << " / inst = "  << std::dec << r_write_copy_inst.read() << std::endl;
    3527                             if (entry.next == r_write_ptr.read())
    3528                                 std::cout << "        ... and this is the last" << std::endl;
    3529                         }
    3530 #endif
    3531                     }
    3532 
    3533                     // register the possible UPT decrement request
    3534                     r_write_to_dec = dec_upt_counter or r_write_to_dec.read();
    3535 
    3536                     if (not m_write_to_cc_send_inst_fifo.wok())
    3537                     {
    3538                         std::cout << "VCI_MEM_CACHE ERROR " << name() << " WRITE_UPT_NEXT state" << std::endl
    3539                             << "The write_to_cc_send_fifo should not be full" << std::endl
    3540                             << "as the depth should be larger than the max number of copies" << std::endl;
    3541                         exit(0);
    3542                     }
    3543 
    3544                     r_write_ptr = entry.next;
    3545 
    3546                     if (entry.next == r_write_ptr.read())    // last copy
    3547                     {
    3548                         r_write_to_cc_send_multi_req = true;
    3549                         if (r_write_to_dec.read() or dec_upt_counter)  r_write_fsm = WRITE_UPT_DEC;
    3550                         else                                          r_write_fsm = WRITE_IDLE;
    3551                     }
    3552                     break;
    3553                 }
    3554 
    3555                 //////////////////
    3556             case WRITE_UPT_DEC:
    3557                 {
    3558                     // If the initial writer has a copy, it should not
    3559                     // receive an update request, but the counter in the
    3560                     // update table must be decremented by the MULTI_ACK FSM.
    3561 
    3562                     if (!r_write_to_multi_ack_req.read())
    3563                     {
    3564                         r_write_to_multi_ack_req = true;
    3565                         r_write_to_multi_ack_upt_index = r_write_upt_index.read();
    3566                         r_write_fsm = WRITE_IDLE;
    3567                     }
    3568                     break;
    3569                 }
    3570 
    3571                 ///////////////
    3572             case WRITE_RSP:  // Post a request to TGT_RSP FSM to acknowledge the write
    3573                 // In order to increase the Write requests throughput,
    3574                 // we don't wait to return in the IDLE state to consume
    3575                 // a new request in the write FIFO
    3576                 {
    3577                     if (not r_write_to_tgt_rsp_req.read())
    3578                     {
    3579                         // post the request to TGT_RSP_FSM
    3580                         r_write_to_tgt_rsp_req     = true;
    3581                         r_write_to_tgt_rsp_srcid   = r_write_srcid.read();
    3582                         r_write_to_tgt_rsp_trdid   = r_write_trdid.read();
    3583                         r_write_to_tgt_rsp_pktid   = r_write_pktid.read();
    3584                         r_write_to_tgt_rsp_sc_fail = r_write_sc_fail.read();
    3585 
    3586                         // try to get a new write request from the FIFO
    3587                         if (not m_cmd_write_addr_fifo.rok())
    3588                         {
    3589                             r_write_fsm = WRITE_IDLE;
    3590                         }
    3591                         else
    3592                         {
    3593                             // consume a word in the FIFO & write it in the local buffer
    3594                             cmd_write_fifo_get  = true;
    3595                             size_t index        = m_x[(addr_t) (m_cmd_write_addr_fifo.read())];
    3596 
    3597                             r_write_address     = (addr_t) (m_cmd_write_addr_fifo.read());
    3598                             r_write_word_index  = index;
    3599                             r_write_word_count  = 0;
    3600                             r_write_data[index] = m_cmd_write_data_fifo.read();
    3601                             r_write_srcid       = m_cmd_write_srcid_fifo.read();
    3602                             r_write_trdid       = m_cmd_write_trdid_fifo.read();
    3603                             r_write_pktid       = m_cmd_write_pktid_fifo.read();
    3604 
    3605                             // if SC command, get the SC key
    3606                             if ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC)
    3607                             {
    3608                                 assert( not m_cmd_write_eop_fifo.read() &&
    3609                                         "MEMC ERROR in WRITE_RSP state: "
    3610                                         "invalid packet format for SC command");
    3611 
    3612                                 r_write_sc_key = m_cmd_write_data_fifo.read();
    3613                             }
    3614 
    3615                             // initialize the be field for all words
    3616                             for(size_t word=0 ; word<m_words ; word++)
    3617                             {
    3618                                 if (word == index) r_write_be[word] = m_cmd_write_be_fifo.read();
    3619                                 else               r_write_be[word] = 0x0;
    3620                             }
    3621 
    3622                             if (m_cmd_write_eop_fifo.read())
    3623                             {
    3624                                 r_write_fsm = WRITE_DIR_REQ;
    3625                             }
    3626                             else
    3627                             {
    3628                                 r_write_fsm = WRITE_NEXT;
    3629                             }
    3630                         }
    3631 
    3632 #if DEBUG_MEMC_WRITE
    3633                         if (m_debug)
    3634                         {
    3635                             std::cout << "  <MEMC " << name() << " WRITE_RSP> Post a request to TGT_RSP FSM"
    3636                                 << " : rsrcid = " << std::hex << r_write_srcid.read() << std::endl;
    3637                             if (m_cmd_write_addr_fifo.rok())
    3638                             {
    3639                                 std::cout << "                    New Write request: "
    3640                                     << " srcid = " << std::hex << m_cmd_write_srcid_fifo.read()
    3641                                     << " / address = " << m_cmd_write_addr_fifo.read()
    3642                                     << " / data = " << m_cmd_write_data_fifo.read() << std::endl;
    3643                             }
    3644                         }
    3645 #endif
    3646                     }
    3647                     break;
    3648                 }
    3649 
    3650                 /////////////////////////
    3651             case WRITE_MISS_TRT_LOCK: // Miss : check Transaction Table
    3652                 {
    3653                     if (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE)
    3654                     {
    3655 
    3656 #if DEBUG_MEMC_WRITE
    3657                         if (m_debug)
    3658                             std::cout << "  <MEMC " << name() << " WRITE_MISS_TRT_LOCK> Check the TRT" << std::endl;
    3659 #endif
    3660                         size_t  hit_index = 0;
    3661                         size_t  wok_index = 0;
    3662                         addr_t  addr  = (addr_t) r_write_address.read();
    3663                         bool    hit_read  = m_trt.hit_read(m_nline[addr], hit_index);
    3664                         bool    hit_write = m_trt.hit_write(m_nline[addr]);
    3665                         bool    wok       = not m_trt.full(wok_index);
    3666 
    3667                         // wait an empty entry in TRT
    3668                         if(not hit_read and (not wok or hit_write))
    3669                         {
    3670                             r_write_fsm       = WRITE_WAIT;
    3671                             m_cpt_trt_full++;
    3672 
    3673                             break;
    3674                         }
    3675 
    3676                         if ((r_write_pktid.read() & 0x7) == TYPE_SC)
    3677                         {
    3678                             m_llsc_table.sc(r_write_address.read(),
    3679                                             r_write_sc_key.read());
    3680                         }
    3681 
    3682                         // register the modified data in TRT
    3683                         if (hit_read)
    3684                         {
    3685                             r_write_trt_index = hit_index;
    3686                             r_write_fsm       = WRITE_MISS_TRT_DATA;
    3687                             m_cpt_write_miss++;
    3688                             break;
    3689                         }
    3690 
    3691                         // set a new entry in TRT
    3692                         if (wok and not hit_write)
    3693                         {
    3694                             r_write_trt_index = wok_index;
    3695                             r_write_fsm       = WRITE_MISS_TRT_SET;
    3696                             m_cpt_write_miss++;
    3697                             break;
    3698                         }
    3699 
    3700                         assert(false && "VCI_MEM_CACHE ERROR: this part must not be reached");
    3701                     }
    3702                     break;
    3703                 }
    3704 
    3705                 ////////////////
    3706             case WRITE_WAIT:  // release the locks protecting the shared ressources
    3707                 {
     3823                if (m_debug)
     3824                {
     3825                    std::cout << "  <MEMC " << name() << " WRITE_WAIT> Releases the locks before retry" << std::endl;
     3826                }
     3827#endif
     3828                r_write_fsm = WRITE_DIR_REQ;
     3829                break;
     3830            }
     3831
     3832            ////////////////////////
     3833            case WRITE_MISS_TRT_SET:  // register a new transaction in TRT (Write Buffer)
     3834            {
     3835                if (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE)
     3836                {
     3837                    std::vector<be_t> be_vector;
     3838                    std::vector<data_t> data_vector;
     3839                    be_vector.clear();
     3840                    data_vector.clear();
     3841                    for (size_t i = 0; i < m_words; i++)
     3842                    {
     3843                        be_vector.push_back(r_write_be[i]);
     3844                        data_vector.push_back(r_write_data[i]);
     3845                    }
     3846                    m_trt.set(r_write_trt_index.read(),
     3847                            true,     // read request to XRAM
     3848                            m_nline[(addr_t)(r_write_address.read())],
     3849                            r_write_srcid.read(),
     3850                            r_write_trdid.read(),
     3851                            r_write_pktid.read(),
     3852                            false,      // not a processor read
     3853                            0,        // not a single word
     3854                            0,            // word index
     3855                            be_vector,
     3856                            data_vector);
     3857                    r_write_fsm = WRITE_MISS_XRAM_REQ;
    37083858
    37093859#if DEBUG_MEMC_WRITE
    37103860                    if (m_debug)
    3711                         std::cout << "  <MEMC " << name() << " WRITE_WAIT> Releases the locks before retry" << std::endl;
    3712 #endif
    3713                     r_write_fsm = WRITE_DIR_REQ;
    3714                     break;
    3715                 }
    3716 
    3717                 ////////////////////////
    3718             case WRITE_MISS_TRT_SET:  // register a new transaction in TRT (Write Buffer)
    3719                 {
    3720                     if (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE)
    3721                     {
    3722                         std::vector<be_t>   be_vector;
    3723                         std::vector<data_t> data_vector;
    3724                         be_vector.clear();
    3725                         data_vector.clear();
    3726                         for(size_t i=0; i<m_words; i++)
    3727                         {
    3728                             be_vector.push_back(r_write_be[i]);
    3729                             data_vector.push_back(r_write_data[i]);
    3730                         }
    3731                         m_trt.set(r_write_trt_index.read(),
    3732                                 true,     // read request to XRAM
    3733                                 m_nline[(addr_t)(r_write_address.read())],
    3734                                 r_write_srcid.read(),
    3735                                 r_write_trdid.read(),
    3736                                 r_write_pktid.read(),
    3737                                 false,      // not a processor read
    3738                                 0,        // not a single word
    3739                                 0,            // word index
    3740                                 be_vector,
    3741                                 data_vector);
    3742                         r_write_fsm = WRITE_MISS_XRAM_REQ;
     3861                    {
     3862                        std::cout << "  <MEMC " << name() << " WRITE_MISS_TRT_SET> Set a new entry in TRT" << std::endl;
     3863                    }
     3864#endif
     3865                }
     3866                break;
     3867            }
     3868
     3869            /////////////////////////
     3870            case WRITE_MISS_TRT_DATA: // update an entry in TRT (used as a Write Buffer)
     3871            {
     3872                if (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE)
     3873                {
     3874                    std::vector<be_t> be_vector;
     3875                    std::vector<data_t> data_vector;
     3876                    be_vector.clear();
     3877                    data_vector.clear();
     3878                    for (size_t i = 0; i < m_words; i++)
     3879                    {
     3880                        be_vector.push_back(r_write_be[i]);
     3881                        data_vector.push_back(r_write_data[i]);
     3882                    }
     3883                    m_trt.write_data_mask(r_write_trt_index.read(),
     3884                            be_vector,
     3885                            data_vector);
     3886                    r_write_fsm = WRITE_RSP;
    37433887
    37443888#if DEBUG_MEMC_WRITE
    3745                         if (m_debug)
    3746                             std::cout << "  <MEMC " << name() << " WRITE_MISS_TRT_SET> Set a new entry in TRT" << std::endl;
    3747 #endif
    3748                     }
    3749                     break;
    3750                 }
    3751 
    3752                 /////////////////////////
    3753             case WRITE_MISS_TRT_DATA: // update an entry in TRT (used as a Write Buffer)
    3754                 {
    3755                     if (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE)
    3756                     {
    3757                         std::vector<be_t> be_vector;
    3758                         std::vector<data_t> data_vector;
    3759                         be_vector.clear();
    3760                         data_vector.clear();
    3761                         for(size_t i=0; i<m_words; i++)
    3762                         {
    3763                             be_vector.push_back(r_write_be[i]);
    3764                             data_vector.push_back(r_write_data[i]);
    3765                         }
    3766                         m_trt.write_data_mask( r_write_trt_index.read(),
    3767                                 be_vector,
    3768                                 data_vector );
    3769                         r_write_fsm = WRITE_RSP;
     3889                    if (m_debug)
     3890                    {
     3891                        std::cout << "  <MEMC " << name() << " WRITE_MISS_TRT_DATA> Modify an existing entry in TRT" << std::endl;
     3892                    }
     3893#endif
     3894                }
     3895                break;
     3896            }
     3897            /////////////////////////
     3898            case WRITE_MISS_XRAM_REQ: // send a GET request to IXR_CMD FSM
     3899            {
     3900                if (not r_write_to_ixr_cmd_req.read())
     3901                {
     3902                    r_write_to_ixr_cmd_req   = true;
     3903                    r_write_to_ixr_cmd_index = r_write_trt_index.read();
     3904                    r_write_fsm              = WRITE_RSP;
    37703905
    37713906#if DEBUG_MEMC_WRITE
    3772                         if (m_debug)
    3773                             std::cout << "  <MEMC " << name() << " WRITE_MISS_TRT_DATA> Modify an existing entry in TRT" << std::endl;
    3774 #endif
    3775                     }
    3776                     break;
    3777                 }
    3778                 /////////////////////////
    3779             case WRITE_MISS_XRAM_REQ: // send a GET request to IXR_CMD FSM
    3780                 {
    3781                     if (not r_write_to_ixr_cmd_req.read())
    3782                     {
    3783                         r_write_to_ixr_cmd_req   = true;
    3784                         r_write_to_ixr_cmd_index = r_write_trt_index.read();
    3785                         r_write_fsm              = WRITE_RSP;
    3786 
    3787 #if DEBUG_MEMC_WRITE
    3788                         if (m_debug)
    3789                             std::cout << "  <MEMC " << name()
    3790                                       << " WRITE_MISS_XRAM_REQ> Post a GET request to the"
    3791                                       << " IXR_CMD FSM" << std::endl;
    3792 #endif
    3793                     }
    3794                     break;
    3795                 }
    3796                 ///////////////////////
     3907                    if (m_debug)
     3908                    {
     3909                        std::cout << "  <MEMC " << name()
     3910                            << " WRITE_MISS_XRAM_REQ> Post a GET request to the"
     3911                            << " IXR_CMD FSM" << std::endl;
     3912                    }
     3913#endif
     3914                }
     3915                break;
     3916            }
     3917            ///////////////////////
    37973918            case WRITE_BC_DIR_READ:  // enter this state if a broadcast-inval is required
    37983919                                     // the cache line must be erased in mem-cache, and written
    37993920                                     // into XRAM.
    3800                 {
    3801                     assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
    3802                             "MEMC ERROR in WRITE_BC_DIR_READ state: Bad DIR allocation");
    3803 
    3804                     // write enable signal for data buffer.
    3805                     r_write_bc_data_we = true;
    3806 
    3807                     r_write_fsm = WRITE_BC_TRT_LOCK;
    3808 
     3921            {
     3922                assert((r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
     3923                        "MEMC ERROR in WRITE_BC_DIR_READ state: Bad DIR allocation");
     3924
     3925                // write enable signal for data buffer.
     3926                r_write_bc_data_we = true;
     3927
     3928                r_write_fsm = WRITE_BC_TRT_LOCK;
     3929
     3930#if DEBUG_MEMC_WRITE
     3931                if (m_debug)
     3932                {
     3933                    std::cout << "  <MEMC " << name() << " WRITE_BC_DIR_READ>"
     3934                        << " Read the cache to complete local buffer" << std::endl;
     3935                }
     3936#endif
     3937                break;
     3938            }
     3939            ///////////////////////
     3940            case WRITE_BC_TRT_LOCK:     // get TRT lock to check TRT not full
     3941            {
     3942                assert((r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
     3943                        "MEMC ERROR in WRITE_BC_TRT_LOCK state: Bad DIR allocation");
     3944
     3945                // We read the cache and complete the buffer. As the DATA cache uses a
     3946                // synchronous RAM, the read DATA request has been performed in the
     3947                // WRITE_BC_DIR_READ state but the data is available in this state.
     3948                if (r_write_bc_data_we.read())
     3949                {
     3950                    size_t set = m_y[(addr_t) (r_write_address.read())];
     3951                    size_t way = r_write_way.read();
     3952                    for (size_t word = 0; word < m_words ; word++)
     3953                    {
     3954                        data_t mask = 0;
     3955                        if (r_write_be[word].read() & 0x1) mask = mask | 0x000000FF;
     3956                        if (r_write_be[word].read() & 0x2) mask = mask | 0x0000FF00;
     3957                        if (r_write_be[word].read() & 0x4) mask = mask | 0x00FF0000;
     3958                        if (r_write_be[word].read() & 0x8) mask = mask | 0xFF000000;
     3959
     3960                        // complete only if mask is not null (for energy consumption)
     3961                        r_write_data[word] =
     3962                            (r_write_data[word].read()         &  mask) |
     3963                            (m_cache_data.read(way, set, word) & ~mask);
     3964                    }
    38093965#if DEBUG_MEMC_WRITE
    38103966                    if (m_debug)
    3811                         std::cout << "  <MEMC " << name() << " WRITE_BC_DIR_READ>"
    3812                                   << " Read the cache to complete local buffer" << std::endl;
    3813 #endif
     3967                    {
     3968                        std::cout << "  <MEMC "  << name()
     3969                            << " WRITE_BC_TRT_LOCK> Complete data buffer" << std::endl;
     3970                    }
     3971#endif
     3972                }
     3973
     3974                if (r_alloc_trt_fsm.read() != ALLOC_TRT_WRITE)
     3975                {
     3976                    // if we loop in this state, the data does not need to be
     3977                    // rewritten (for energy consuption)
     3978                    r_write_bc_data_we = false;
    38143979                    break;
    38153980                }
    3816                 ///////////////////////
    3817             case WRITE_BC_TRT_LOCK:     // get TRT lock to check TRT not full
    3818                 {
    3819                     assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
    3820                             "MEMC ERROR in WRITE_BC_TRT_LOCK state: Bad DIR allocation");
    3821 
    3822                     // We read the cache and complete the buffer. As the DATA cache uses a
    3823                     // synchronous RAM, the read DATA request has been performed in the
    3824                     // WRITE_BC_DIR_READ state but the data is available in this state.
    3825                     if (r_write_bc_data_we.read())
    3826                     {
    3827                         size_t set  = m_y[(addr_t)(r_write_address.read())];
    3828                         size_t way  = r_write_way.read();
    3829                         for(size_t word=0 ; word<m_words ; word++)
    3830                         {
    3831                             data_t mask = 0;
    3832                             if (r_write_be[word].read() & 0x1) mask = mask | 0x000000FF;
    3833                             if (r_write_be[word].read() & 0x2) mask = mask | 0x0000FF00;
    3834                             if (r_write_be[word].read() & 0x4) mask = mask | 0x00FF0000;
    3835                             if (r_write_be[word].read() & 0x8) mask = mask | 0xFF000000;
    3836 
    3837                             // complete only if mask is not null (for energy consumption)
    3838                             r_write_data[word] =
    3839                                 (r_write_data[word].read()         &  mask) |
    3840                                 (m_cache_data.read(way, set, word) & ~mask);
    3841                         }
     3981
     3982                size_t wok_index = 0;
     3983                bool wok = not m_trt.full(wok_index);
     3984                if (wok)
     3985                {
     3986                    r_write_trt_index = wok_index;
     3987                    r_write_fsm       = WRITE_BC_IVT_LOCK;
     3988                }
     3989                else  // wait an empty slot in TRT
     3990                {
     3991                    r_write_fsm = WRITE_WAIT;
     3992                }
     3993
    38423994#if DEBUG_MEMC_WRITE
    3843                         if (m_debug)
    3844                             std::cout
    3845                                 << "  <MEMC "  << name()
    3846                                 << " WRITE_BC_TRT_LOCK> Complete data buffer" << std::endl;
    3847 #endif
    3848                     }
    3849 
    3850                     if (r_alloc_trt_fsm.read() != ALLOC_TRT_WRITE)
    3851                     {
    3852                         // if we loop in this state, the data does not need to be
    3853                         // rewritten (for energy consuption)
    3854                         r_write_bc_data_we = false;
    3855                         break;
    3856                     }
    3857 
    3858                     size_t wok_index = 0;
    3859                     bool wok = not m_trt.full(wok_index);
    3860                     if (wok )       
    3861                     {
    3862                         r_write_trt_index = wok_index;
    3863                         r_write_fsm       = WRITE_BC_IVT_LOCK;
    3864                     }
    3865                     else  // wait an empty slot in TRT
    3866                     {
    3867                         r_write_fsm       = WRITE_WAIT;
    3868                     }
     3995                if (m_debug)
     3996                {
     3997                    std::cout << "  <MEMC "  << name()
     3998                        << " WRITE_BC_TRT_LOCK> Check TRT : wok = " << wok
     3999                        << " / index = " << wok_index << std::endl;
     4000                }
     4001#endif
     4002                break;
     4003            }
     4004            //////////////////////
     4005            case WRITE_BC_IVT_LOCK:      // get IVT lock and register BC transaction in IVT
     4006            {
     4007                assert((r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
     4008                        "MEMC ERROR in WRITE_BC_IVT_LOCK state: Bad DIR allocation");
     4009
     4010                assert((r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE) and
     4011                        "MEMC ERROR in WRITE_BC_IVT_LOCK state: Bad TRT allocation");
     4012
     4013                if (r_alloc_ivt_fsm.read() == ALLOC_IVT_WRITE)
     4014                {
     4015                    bool   wok       = false;
     4016                    size_t index     = 0;
     4017                    size_t srcid     = r_write_srcid.read();
     4018                    size_t trdid     = r_write_trdid.read();
     4019                    size_t pktid     = r_write_pktid.read();
     4020                    addr_t nline     = m_nline[(addr_t) (r_write_address.read())];
     4021                    size_t nb_copies = r_write_count.read();
     4022
     4023                    wok = m_ivt.set(false,  // it's an inval transaction
     4024                            true,   // it's a broadcast
     4025                            true,   // response required
     4026                            false,  // no acknowledge required
     4027                            srcid,
     4028                            trdid,
     4029                            pktid,
     4030                            nline,
     4031                            nb_copies,
     4032                            index);
     4033#if DEBUG_MEMC_WRITE
     4034                    if (m_debug and wok)
     4035                    {
     4036                        std::cout << "  <MEMC " << name() << " WRITE_BC_IVT_LOCK> Register broadcast inval in IVT"
     4037                            << " / nb_copies = " << r_write_count.read() << std::endl;
     4038                    }
     4039#endif
     4040                    r_write_upt_index = index;
     4041
     4042                    if (wok) r_write_fsm = WRITE_BC_DIR_INVAL;
     4043                    else     r_write_fsm = WRITE_WAIT;
     4044                }
     4045                break;
     4046            }
     4047            ////////////////////////
     4048            case WRITE_BC_DIR_INVAL:    // Register a put transaction in TRT
     4049            // and invalidate the line in directory
     4050            {
     4051                assert((r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
     4052                        "MEMC ERROR in WRITE_BC_DIR_INVAL state: Bad DIR allocation");
     4053
     4054                assert((r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE) and
     4055                        "MEMC ERROR in WRITE_BC_DIR_INVAL state: Bad TRT allocation");
     4056
     4057                assert((r_alloc_ivt_fsm.read() == ALLOC_IVT_WRITE) and
     4058                        "MEMC ERROR in WRITE_BC_DIR_INVAL state: Bad IVT allocation");
     4059
     4060                // register PUT request in TRT
     4061                std::vector<data_t> data_vector;
     4062                data_vector.clear();
     4063                for (size_t i = 0; i < m_words; i++)
     4064                {
     4065                    data_vector.push_back(r_write_data[i].read());
     4066                }
     4067                m_trt.set(r_write_trt_index.read(),
     4068                        false,             // PUT request
     4069                        m_nline[(addr_t) (r_write_address.read())],
     4070                        0,                 // unused
     4071                        0,                 // unused
     4072                        0,                 // unused
     4073                        false,             // not a processor read
     4074                        0,                 // unused
     4075                        0,                 // unused
     4076                        std::vector<be_t> (m_words, 0),
     4077                        data_vector);
     4078
     4079                // invalidate directory entry
     4080                DirectoryEntry entry;
     4081                entry.valid       = false;
     4082                entry.dirty       = false;
     4083                entry.tag         = 0;
     4084                entry.is_cnt      = false;
     4085                entry.lock        = false;
     4086                entry.owner.srcid = 0;
     4087                entry.owner.inst  = false;
     4088                entry.ptr         = 0;
     4089                entry.count       = 0;
     4090                size_t set        = m_y[(addr_t) (r_write_address.read())];
     4091                size_t way        = r_write_way.read();
     4092
     4093                m_cache_directory.write(set, way, entry);
     4094
     4095                if ((r_write_pktid.read() & 0x7) == TYPE_SC)
     4096                {
     4097                    m_llsc_table.sc(r_write_address.read(), r_write_sc_key.read());
     4098                }
     4099
     4100#if DEBUG_MEMC_WRITE
     4101                if (m_debug)
     4102                {
     4103                    std::cout << "  <MEMC " << name() << " WRITE_BC_DIR_INVAL> Inval DIR and register in TRT:"
     4104                        << " address = " << std::hex << r_write_address.read() << std::endl;
     4105                }
     4106#endif
     4107                r_write_fsm = WRITE_BC_CC_SEND;
     4108                break;
     4109            }
     4110
     4111            //////////////////////
     4112            case WRITE_BC_CC_SEND:    // Post a coherence broadcast request to CC_SEND FSM
     4113            {
     4114                if (!r_write_to_cc_send_multi_req.read() and !r_write_to_cc_send_brdcast_req.read())
     4115                {
     4116                    r_write_to_cc_send_multi_req   = false;
     4117                    r_write_to_cc_send_brdcast_req = true;
     4118                    r_write_to_cc_send_trdid       = r_write_upt_index.read();
     4119                    r_write_to_cc_send_nline       = m_nline[(addr_t) (r_write_address.read())];
     4120                    r_write_to_cc_send_index       = 0;
     4121                    r_write_to_cc_send_count       = 0;
     4122
     4123                    for (size_t i = 0; i < m_words; i++)  // à quoi sert ce for? (AG)
     4124                    {
     4125                        r_write_to_cc_send_be[i] = 0;
     4126                        r_write_to_cc_send_data[i] = 0;
     4127                    }
     4128                    r_write_fsm = WRITE_BC_XRAM_REQ;
    38694129
    38704130#if DEBUG_MEMC_WRITE
    38714131                    if (m_debug)
    3872                         std::cout << "  <MEMC "  << name()
    3873                                   << " WRITE_BC_TRT_LOCK> Check TRT : wok = " << wok
    3874                                   << " / index = " << wok_index << std::endl;
    3875 #endif
    3876                     break;
    3877                 }
    3878                 //////////////////////
    3879             case WRITE_BC_IVT_LOCK:      // get IVT lock and register BC transaction in IVT
    3880                 {
    3881                     assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
    3882                             "MEMC ERROR in WRITE_BC_IVT_LOCK state: Bad DIR allocation");
    3883 
    3884                     assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE) and
    3885                             "MEMC ERROR in WRITE_BC_IVT_LOCK state: Bad TRT allocation");
    3886 
    3887                     if (r_alloc_ivt_fsm.read() == ALLOC_IVT_WRITE)
    3888                     {
    3889                         bool        wok       = false;
    3890                         size_t      index     = 0;
    3891                         size_t      srcid     = r_write_srcid.read();
    3892                   &nbs