Index: trunk/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp
===================================================================
--- trunk/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp	(revision 581)
+++ trunk/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp	(revision 582)
@@ -888,6 +888,6 @@
             m_cmd_cas_eop_fifo.init()   ;
 
-            r_config_cmd  = MEMC_CMD_NOP;
-            r_config_lock = false;
+            r_config_cmd       = MEMC_CMD_NOP;
+            r_config_lock      = false;
 
             m_config_to_cc_send_inst_fifo.init();
@@ -1014,4 +1014,8 @@
         size_t xram_rsp_to_cc_send_fifo_srcid = 0;
 
+        bool   config_rsp_lines_incr          = false;
+        bool   config_rsp_lines_cleanup_decr  = false;
+        bool   config_rsp_lines_ixr_rsp_decr  = false;
+ 
         bool   config_to_cc_send_fifo_put   = false;
         bool   config_to_cc_send_fifo_get   = false;
@@ -1254,5 +1258,5 @@
                         if (wdata % (m_words << 2)) lines++;
                         r_config_cmd_lines = lines;
-                        r_config_rsp_lines = lines;
+                        r_config_rsp_lines = 0;
                     }
                     else if ((p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set cmd type
@@ -1621,5 +1625,11 @@
         // the command for line (n+1). It decrements the r_config_cmd_lines counter until 
         // the last request has been registered in TRT (for a SYNC), or in IVT (for an INVAL).
-        // 
+        // The r_config_rsp_lines counter contains the number of expected responses from
+        // CLEANUP FSM (inval) or from IXR_RSP FSM (sync). This register is incremented by
+        // the CONFIG FSM (each time a transaction is requested), and decremented by the
+        // CLEANUP or IXR_RSP FSMs(each time a response is received. As this register can
+        // be concurently accessed by those three FSMs, it is implemented as an [incr/decr]
+        // counter.
+        //
         // - INVAL request:
         //   For each line, it access to the DIR. 
@@ -1660,482 +1670,483 @@
             /////////////////
             case CONFIG_IDLE:  // waiting a config request 
-                {
-                    if (r_config_cmd.read() != MEMC_CMD_NOP )  
-                    {
-                        r_config_fsm    = CONFIG_LOOP;
+            {
+                if (r_config_cmd.read() != MEMC_CMD_NOP )  
+                {
+                    r_config_fsm    = CONFIG_LOOP;
 
 #if DEBUG_MEMC_CONFIG
-                        if (m_debug)
-                            std::cout << "  <MEMC " << name() << " CONFIG_IDLE> Config Request received" 
-                                << " / address = " << std::hex << r_config_address.read()
-                                << " / lines = " << std::dec << r_config_cmd_lines.read()
-                                << " / type = " << r_config_cmd.read() << std::endl;
-#endif
-                    }
-                    break;
-                }
-                /////////////////
+if (m_debug)
+std::cout << "  <MEMC " << name() << " CONFIG_IDLE> Config Request received" 
+          << " / address = " << std::hex << r_config_address.read()
+          << " / lines = " << std::dec << r_config_cmd_lines.read()
+          << " / type = " << r_config_cmd.read() << std::endl;
+#endif
+                }
+                break;
+            }
+            /////////////////
             case CONFIG_LOOP:   // test if last line to be handled
-                {
-                    if (r_config_cmd_lines.read() == 0 )
-                    {
-                        r_config_cmd = MEMC_CMD_NOP;
-                        r_config_fsm = CONFIG_WAIT;
+            {
+                if (r_config_cmd_lines.read() == 0 )
+                {
+                    r_config_cmd = MEMC_CMD_NOP;
+                    r_config_fsm = CONFIG_WAIT;
+                }
+                else
+                {
+                    r_config_fsm = CONFIG_DIR_REQ;
+                }
+
+#if DEBUG_MEMC_CONFIG
+if (m_debug)
+std::cout << "  <MEMC " << name() << " CONFIG_LOOP>" 
+          << " / address = " << std::hex << r_config_address.read()    
+          << " / lines not handled = " << std::dec << r_config_cmd_lines.read() 
+          << " / command = " << r_config_cmd.read() << std::endl;
+#endif
+                break;
+            }
+            /////////////////
+            case CONFIG_WAIT:   // wait completion (last response) 
+            {
+                if (r_config_rsp_lines.read() == 0 )  // last response received
+                {
+                    r_config_fsm = CONFIG_RSP;
+                }
+
+#if DEBUG_MEMC_CONFIG
+if (m_debug)
+std::cout << "  <MEMC " << name() << " CONFIG_WAIT>" 
+          << " / lines to do = " << std::dec << r_config_rsp_lines.read() << std::endl;
+#endif
+                break;
+            }
+            ////////////////
+            case CONFIG_RSP:  // request TGT_RSP FSM to return response 
+            {
+                if (not r_config_to_tgt_rsp_req.read())
+                {
+                    r_config_to_tgt_rsp_srcid  = r_config_srcid.read();
+                    r_config_to_tgt_rsp_trdid  = r_config_trdid.read();
+                    r_config_to_tgt_rsp_pktid  = r_config_pktid.read();
+                    r_config_to_tgt_rsp_error  = false;
+                    r_config_to_tgt_rsp_req    = true;
+                    r_config_fsm               = CONFIG_IDLE;
+
+#if DEBUG_MEMC_CONFIG
+if (m_debug)
+std::cout << "  <MEMC " << name() << " CONFIG_RSP> Request TGT_RSP FSM to send response:"
+          << " error = " << r_config_to_tgt_rsp_error.read()
+          << " / rsrcid = " << std::hex << r_config_srcid.read()
+          << " / rtrdid = " << std::hex << r_config_trdid.read()
+          << " / rpktid = " << std::hex << r_config_pktid.read() << std::endl;
+#endif
+                }
+                break;
+            }
+            ////////////////////
+            case CONFIG_DIR_REQ:  // Request directory lock
+            {
+                if (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG )
+                {
+                    r_config_fsm = CONFIG_DIR_ACCESS;
+                }
+
+#if DEBUG_MEMC_CONFIG
+if (m_debug)
+std::cout << "  <MEMC " << name() << " CONFIG_DIR_REQ>"
+          << " Request DIR access" << std::endl;
+#endif
+                break;
+            }
+            ///////////////////////
+            case CONFIG_DIR_ACCESS:   // Access directory and decode config command
+            {
+                assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
+                "MEMC ERROR in CONFIG_DIR_ACCESS state: bad DIR allocation");
+
+                size_t way = 0;
+                DirectoryEntry entry = m_cache_directory.read(r_config_address.read(), way);
+
+                r_config_dir_way        = way;
+                r_config_dir_copy_inst  = entry.owner.inst;
+                r_config_dir_copy_srcid = entry.owner.srcid;
+                r_config_dir_is_cnt     = entry.is_cnt;
+                r_config_dir_lock       = entry.lock;
+                r_config_dir_count      = entry.count;
+                r_config_dir_ptr        = entry.ptr;
+
+                if (entry.valid and                            // hit & inval command
+                   (r_config_cmd.read() == MEMC_CMD_INVAL)) 
+                {
+                    r_config_fsm       = CONFIG_IVT_LOCK;
+                }
+                else if (entry.valid and                       // hit & sync command
+                         entry.dirty and
+                         (r_config_cmd.read() == MEMC_CMD_SYNC))
+                { 
+                    r_config_fsm       = CONFIG_TRT_LOCK;
+                }
+                else                                            // miss : return to LOOP 
+                {
+                    r_config_cmd_lines = r_config_cmd_lines.read() - 1;
+                    r_config_address   = r_config_address.read() + (m_words<<2);
+                    r_config_fsm       = CONFIG_LOOP;
+                }
+
+#if DEBUG_MEMC_CONFIG
+if (m_debug)
+std::cout << "  <MEMC " << name() << " CONFIG_DIR_ACCESS> Accessing directory: "
+          << " address = " << std::hex << r_config_address.read()
+          << " / hit = " << std::dec << entry.valid
+          << " / dirty = " << entry.dirty
+          << " / count = " << entry.count
+          << " / is_cnt = " << entry.is_cnt << std::endl;
+#endif
+                break;
+            }
+            /////////////////////
+            case CONFIG_TRT_LOCK:      // enter this state in case of SYNC command
+                                       // to a dirty cache line 
+                                       // keep DIR lock, and try to get TRT lock
+                                       // return to LOOP state if TRT full
+                                       // reset dirty bit in DIR and register a PUT
+                                       // transaction in TRT if not full.
+            {
+                assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
+                "MEMC ERROR in CONFIG_TRT_LOCK state: bad DIR allocation");
+
+                if (r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG )
+                {
+                    size_t index = 0;
+                    bool   wok   = not m_trt.full(index);
+
+                    if (not wok )
+                    {
+                        r_config_fsm = CONFIG_LOOP;
                     }
                     else
                     {
-                        r_config_fsm = CONFIG_DIR_REQ;
+                        size_t          way = r_config_dir_way.read();
+                        size_t          set = m_y[r_config_address.read()];
+
+                        // reset dirty bit in DIR
+                        DirectoryEntry  entry;
+                        entry.valid       = true;
+                        entry.dirty       = false;
+                        entry.tag         = m_z[r_config_address.read()];
+                        entry.is_cnt      = r_config_dir_is_cnt.read();
+                        entry.lock        = r_config_dir_lock.read();
+                        entry.ptr         = r_config_dir_ptr.read();
+                        entry.count       = r_config_dir_count.read();
+                        entry.owner.inst  = r_config_dir_copy_inst.read();
+                        entry.owner.srcid = r_config_dir_copy_srcid.read();
+                        m_cache_directory.write( set, way, entry );
+
+                        r_config_trt_index = index;
+                        r_config_fsm       = CONFIG_TRT_SET;
                     }
 
 #if DEBUG_MEMC_CONFIG
-                    if (m_debug)
-                        std::cout << "  <MEMC " << name() << " CONFIG_LOOP>" 
-                            << " / address = " << std::hex << r_config_address.read()    
-                            << " / lines not handled = " << std::dec << r_config_cmd_lines.read() 
-                            << " / command = " << r_config_cmd.read() << std::endl;
-#endif
-                    break;
-                }
-                /////////////////
-            case CONFIG_WAIT:   // wait completion (last response) 
-                {
-                    if (r_config_rsp_lines.read() == 0 )  // last response received
-                    {
-                        r_config_fsm = CONFIG_RSP;
-                    }
+if (m_debug)
+std::cout << "  <MEMC " << name() << " CONFIG_TRT_LOCK> Access TRT: "
+          << " wok = " << std::dec << wok
+          << " index = " << index << std::endl;
+#endif
+                }
+                break;
+            }
+            ////////////////////
+            case CONFIG_TRT_SET:       // read data in cache
+            // and post a PUT request in TRT
+            {
+                assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
+                "MEMC ERROR in CONFIG_TRT_SET state: bad DIR allocation");
+
+                assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG) and
+                "MEMC ERROR in CONFIG_TRT_SET state: bad TRT allocation");
+
+                // read data into cache
+                size_t              way = r_config_dir_way.read();
+                size_t              set = m_y[r_config_address.read()];
+                std::vector<data_t> data_vector;
+                data_vector.clear();
+                for(size_t word=0; word<m_words; word++) 
+                {
+                    uint32_t data = m_cache_data.read( way, set, word );
+                    data_vector.push_back( data );
+                }
+
+                // post the PUT request in TRT
+                m_trt.set( r_config_trt_index.read(),
+                           false,                               // PUT transaction
+                           m_nline[r_config_address.read()],    // line index
+                           0,                                   // srcid:       unused
+                           0,                                   // trdid:       unused
+                           0,                                   // pktid:       unused
+                           false,                               // not proc_read
+                           0,                                   // read_length: unused
+                           0,                                   // word_index:  unused
+                           std::vector<be_t>(m_words,0xF),      // byte-enable: unused 
+                           data_vector,                         // data to be written
+                           0,                                   // ll_key:      unused
+                           true );                              // requested by config FSM
+                config_rsp_lines_incr = true;
+                r_config_fsm          = CONFIG_PUT_REQ;
 
 #if DEBUG_MEMC_CONFIG
-                    if (m_debug)
-                        std::cout << "  <MEMC " << name() << " CONFIG_WAIT>" 
-                            << " / lines to do = " << std::dec << r_config_rsp_lines.read() << std::endl;
-#endif
-                    break;
-                }
-                ////////////////
-            case CONFIG_RSP:  // request TGT_RSP FSM to return response 
-                {
-                    if (not r_config_to_tgt_rsp_req.read())
-                    {
-                        r_config_to_tgt_rsp_srcid  = r_config_srcid.read();
-                        r_config_to_tgt_rsp_trdid  = r_config_trdid.read();
-                        r_config_to_tgt_rsp_pktid  = r_config_pktid.read();
-                        r_config_to_tgt_rsp_error  = false;
-                        r_config_to_tgt_rsp_req    = true;
-                        r_config_fsm               = CONFIG_IDLE;
+if (m_debug)
+std::cout << "  <MEMC " << name() << " CONFIG_TRT_SET> PUT request in TRT:"
+          << " address = " << std::hex << r_config_address.read()
+          << " index = " << std::dec << r_config_trt_index.read() << std::endl;
+#endif
+                break;
+            }
+            ////////////////////
+            case CONFIG_PUT_REQ:       // post PUT request to IXR_CMD_FSM
+            {
+                if (not r_config_to_ixr_cmd_req.read())
+                {
+                    r_config_to_ixr_cmd_req   = true;
+                    r_config_to_ixr_cmd_index = r_config_trt_index.read();
+
+                    // prepare next iteration
+                    r_config_cmd_lines        = r_config_cmd_lines.read() - 1;
+                    r_config_address          = r_config_address.read() + (m_words<<2);
+                    r_config_fsm              = CONFIG_LOOP;
 
 #if DEBUG_MEMC_CONFIG
-                        if (m_debug)
-                            std::cout << "  <MEMC " << name() << " CONFIG_RSP> Request TGT_RSP FSM to return response:"
-                                << " error = " << r_config_to_tgt_rsp_error.read()
-                                << " / rsrcid = " << std::hex << r_config_srcid.read()
-                                << " / rtrdid = " << std::hex << r_config_trdid.read()
-                                << " / rpktid = " << std::hex << r_config_pktid.read() << std::endl;
-#endif
-                    }
-                    break;
-
-                }
-                ////////////////////
-            case CONFIG_DIR_REQ:  // Request directory lock
-                {
-                    if (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG )
-                    {
-                        r_config_fsm = CONFIG_DIR_ACCESS;
-                    }
+if (m_debug)
+std::cout << "  <MEMC " << name() << " CONFIG_PUT_REQ> post PUT request to IXR_CMD_FSM"
+          << " / address = " << std::hex << r_config_address.read() << std::endl; 
+#endif
+                }
+                break;
+            }
+            /////////////////////
+            case CONFIG_IVT_LOCK:  // enter this state in case of INVAL command
+                                   // Keep DIR lock and Try to get IVT lock.
+                                   // Return to LOOP state if IVT full.
+                                   // Register inval in IVT, and invalidate the
+                                   // directory if IVT not full. 
+            {
+                assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
+                "MEMC ERROR in CONFIG_IVT_LOCK state: bad DIR allocation");
+
+                if (r_alloc_ivt_fsm.read() == ALLOC_IVT_CONFIG )
+                {
+                    size_t set        = m_y[(addr_t)(r_config_address.read())];
+                    size_t way        = r_config_dir_way.read();
+
+                    if (r_config_dir_count.read() == 0 )  // inval DIR and return to LOOP
+                    {
+                        m_cache_directory.inval( way, set );
+                        r_config_cmd_lines  = r_config_cmd_lines.read() - 1;
+                        r_config_address    = r_config_address.read() + (m_words<<2);
+                        r_config_fsm        = CONFIG_LOOP;
 
 #if DEBUG_MEMC_CONFIG
-                    if (m_debug)
-                        std::cout << "  <MEMC " << name() << " CONFIG_DIR_REQ>"
-                            << " Request DIR access" << std::endl;
-#endif
-                    break;
-                }
-                ///////////////////////
-            case CONFIG_DIR_ACCESS:   // Access directory and decode config command
-                {
-                    assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
-                            "MEMC ERROR in CONFIG_DIR_ACCESS state: bad DIR allocation");
-
-                    size_t way = 0;
-                    DirectoryEntry entry = m_cache_directory.read(r_config_address.read(), way);
-
-                    r_config_dir_way        = way;
-                    r_config_dir_copy_inst  = entry.owner.inst;
-                    r_config_dir_copy_srcid = entry.owner.srcid;
-                    r_config_dir_is_cnt     = entry.is_cnt;
-                    r_config_dir_lock       = entry.lock;
-                    r_config_dir_count      = entry.count;
-                    r_config_dir_ptr        = entry.ptr;
-
-                    if (entry.valid and                            // hit & inval command
-                            (r_config_cmd.read() == MEMC_CMD_INVAL)) 
-                    {
-                        r_config_fsm       = CONFIG_IVT_LOCK;
-                    }
-                    else if (entry.valid and                       // hit & sync command
-                            entry.dirty and
-                            (r_config_cmd.read() == MEMC_CMD_SYNC))
-                    { 
-                        r_config_fsm       = CONFIG_TRT_LOCK;
-                    }
-                    else                                            // miss : return to LOOP 
-                    {
-                        r_config_cmd_lines = r_config_cmd_lines.read() - 1;
-                        r_config_rsp_lines = r_config_rsp_lines.read() - 1;
-                        r_config_address   = r_config_address.read() + (m_words<<2);
-                        r_config_fsm       = CONFIG_LOOP;
-                    }
+if (m_debug)
+std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
+          << " No copies in L1 : inval DIR entry"  << std::endl;
+#endif
+                    }
+                    else    // try to register inval in IVT
+                    {
+                        bool        wok       = false;
+                        size_t      index     = 0;
+                        bool        broadcast = r_config_dir_is_cnt.read();
+                        size_t      srcid     = r_config_srcid.read();
+                        size_t      trdid     = r_config_trdid.read();
+                        size_t      pktid     = r_config_pktid.read();
+                        addr_t      nline     = m_nline[(addr_t)(r_config_address.read())];
+                        size_t      nb_copies = r_config_dir_count.read();
+
+                        wok = m_ivt.set( false,       // it's an inval transaction
+                                         broadcast,   
+                                         false,       // no response required
+                                         true,        // acknowledge required
+                                         srcid,
+                                         trdid,
+                                         pktid,
+                                         nline,
+                                         nb_copies,
+                                         index );
+
+                        if (wok )  // IVT success => inval DIR slot
+                        {
+                            m_cache_directory.inval( way, set );
+                            r_config_ivt_index    = index;
+                            config_rsp_lines_incr = true;
+                            if (broadcast )  r_config_fsm = CONFIG_BC_SEND;
+                            else             r_config_fsm = CONFIG_INVAL_SEND;
 
 #if DEBUG_MEMC_CONFIG
-                    if (m_debug)
-                        std::cout << "  <MEMC " << name() << " CONFIG_DIR_ACCESS> Accessing directory: "
-                            << " address = " << std::hex << r_config_address.read()
-                            << " / hit = " << std::dec << entry.valid
-                            << " / dirty = " << entry.dirty
-                            << " / count = " << entry.count
-                            << " / is_cnt = " << entry.is_cnt << std::endl;
-#endif
-                    break;
-                }
-                /////////////////////
-            case CONFIG_TRT_LOCK:      // enter this state in case of SYNC command
-                // to a dirty cache line 
-                // keep DIR lock, and try to get TRT lock
-                // return to LOOP state if TRT full
-                // reset dirty bit in DIR and register a PUT
-                // trabsaction in TRT if not full.
-                {
-                    assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
-                            "MEMC ERROR in CONFIG_TRT_LOCK state: bad DIR allocation");
-
-                    if (r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG )
-                    {
-                        size_t index = 0;
-                        bool   wok   = not m_trt.full(index);
-
-                        if (not wok )
+if (m_debug)
+std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
+          << " Inval DIR entry and register inval in IVT"
+          << " / index = " << std::dec << index
+          << " / broadcast = " << broadcast << std::endl;
+#endif
+                        }
+                        else       // IVT full => release both DIR and IVT locks
                         {
                             r_config_fsm = CONFIG_LOOP;
-                        }
-                        else
-                        {
-                            size_t          way = r_config_dir_way.read();
-                            size_t          set = m_y[r_config_address.read()];
-
-                            // reset dirty bit in DIR
-                            DirectoryEntry  entry;
-                            entry.valid       = true;
-                            entry.dirty       = false;
-                            entry.tag         = m_z[r_config_address.read()];
-                            entry.is_cnt      = r_config_dir_is_cnt.read();
-                            entry.lock        = r_config_dir_lock.read();
-                            entry.ptr         = r_config_dir_ptr.read();
-                            entry.count       = r_config_dir_count.read();
-                            entry.owner.inst  = r_config_dir_copy_inst.read();
-                            entry.owner.srcid = r_config_dir_copy_srcid.read();
-                            m_cache_directory.write( set, way, entry );
-
-                            r_config_trt_index = index;
-                            r_config_fsm       = CONFIG_TRT_SET;
-                        }
 
 #if DEBUG_MEMC_CONFIG
-                        if (m_debug)
-                            std::cout << "  <MEMC " << name() << " CONFIG_TRT_LOCK> Access TRT: "
-                                << " wok = " << std::dec << wok
-                                << " index = " << index << std::endl;
-#endif
-                    }
-                    break;
-                }
-                ////////////////////
-            case CONFIG_TRT_SET:       // read data in cache
-                // and post a PUT request in TRT
-                {
-                    assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
-                            "MEMC ERROR in CONFIG_TRT_SET state: bad DIR allocation");
-
-                    assert( (r_alloc_trt_fsm.read() == ALLOC_TRT_CONFIG) and
-                            "MEMC ERROR in CONFIG_TRT_SET state: bad TRT allocation");
-
-                    // read data into cache
-                    size_t              way = r_config_dir_way.read();
-                    size_t              set = m_y[r_config_address.read()];
-                    std::vector<data_t> data_vector;
-                    data_vector.clear();
-                    for(size_t word=0; word<m_words; word++) 
-                    {
-                        uint32_t data = m_cache_data.read( way, set, word );
-                        data_vector.push_back( data );
-                    }
-
-                    // post the PUT request in TRT
-                    m_trt.set( r_config_trt_index.read(),
-                            false,                               // PUT transaction
-                            m_nline[r_config_address.read()],    // line index
-                            0,                                   // srcid:           unused
-                            0,                                   // trdid:           unused
-                            0,                                   // pktid:           unused
-                            false,                               // not proc_read
-                            0,                                   // read_length:     unused
-                            0,                                   // word_index:      unused
-                            std::vector<be_t>(m_words,0xF),      // byte-enable:     unused 
-                            data_vector,                         // data to be written
-                            0,                                   // ll_key:          unused
-                            true );                              // requested by config FSM
-                    r_config_fsm = CONFIG_PUT_REQ;
+if (m_debug)
+std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
+          << " IVT full : release DIR & IVT locks and retry" << std::endl;
+#endif
+                        }
+                    }
+                }
+                break;
+            }
+            ////////////////////
+            case CONFIG_BC_SEND:    // Post a broadcast inval request to CC_SEND FSM
+            {
+                if (not r_config_to_cc_send_multi_req.read() and 
+                    not r_config_to_cc_send_brdcast_req.read())
+                {
+                    // post bc inval request
+                    r_config_to_cc_send_multi_req   = false;
+                    r_config_to_cc_send_brdcast_req = true;
+                    r_config_to_cc_send_trdid = r_config_ivt_index.read();
+                    r_config_to_cc_send_nline = m_nline[(addr_t)(r_config_address.read())];
+
+                    // prepare next iteration
+                    r_config_cmd_lines        = r_config_cmd_lines.read() - 1;
+                    r_config_address          = r_config_address.read() + (m_words << 2);
+                    r_config_fsm              = CONFIG_LOOP;
 
 #if DEBUG_MEMC_CONFIG
-                    if (m_debug)
-                        std::cout << "  <MEMC " << name() << " CONFIG_TRT_SET> PUT request in TRT:"
-                            << " address = " << std::hex << r_config_address.read()
-                            << " index = " << std::dec << r_config_trt_index.read() << std::endl;
-#endif
-                    break;
-                }
-                ////////////////////
-            case CONFIG_PUT_REQ:       // post PUT request to IXR_CMD_FSM
-                {
-                    if (not r_config_to_ixr_cmd_req.read())
-                    {
-                        r_config_to_ixr_cmd_req   = true;
-                        r_config_to_ixr_cmd_index = r_config_trt_index.read();
-
+if (m_debug)
+std::cout << "  <MEMC " << name() << " CONFIG_BC_SEND>"
+          << " Post a broadcast inval request to CC_SEND FSM" 
+          << " / address = " << r_config_address.read() <<std::endl;
+#endif
+                }
+                break;
+            }
+            ///////////////////////
+            case CONFIG_INVAL_SEND:    // Post a multi inval request to CC_SEND FSM
+            {
+                if (not r_config_to_cc_send_multi_req.read() and 
+                    not r_config_to_cc_send_brdcast_req.read())
+                {
+                    // post multi inval request
+                    r_config_to_cc_send_multi_req   = true;
+                    r_config_to_cc_send_brdcast_req = false;
+                    r_config_to_cc_send_trdid = r_config_ivt_index.read();
+                    r_config_to_cc_send_nline = m_nline[(addr_t)(r_config_address.read())];
+
+                    // post data into FIFO
+                    config_to_cc_send_fifo_srcid = r_config_dir_copy_srcid.read();
+                    config_to_cc_send_fifo_inst  = r_config_dir_copy_inst.read();
+                    config_to_cc_send_fifo_put   = true;
+
+                    if (r_config_dir_count.read() == 1 )  // one copy
+                    {
                         // prepare next iteration
-                        r_config_cmd_lines              = r_config_cmd_lines.read() - 1;
-                        r_config_address                = r_config_address.read() + (m_words<<2);
-                        r_config_fsm                    = CONFIG_LOOP;
+                        r_config_cmd_lines  = r_config_cmd_lines.read() - 1;
+                        r_config_address    = r_config_address.read() + (m_words << 2);
+                            r_config_fsm    = CONFIG_LOOP;
+                    }
+                    else                                   // several copies
+                    {
+                        r_config_fsm = CONFIG_HEAP_REQ;
+                    }
 
 #if DEBUG_MEMC_CONFIG
-                        if (m_debug)
-                            std::cout << "  <MEMC " << name() << " CONFIG_PUT_REQ> post PUT request to IXR_CMD_FSM"
-                                << " / address = " << std::hex << r_config_address.read() << std::endl; 
-#endif
-                    }
-                    break;
-                }
-                /////////////////////
-            case CONFIG_IVT_LOCK:  // enter this state in case of INVAL command
-                // Keep DIR lock and Try to get IVT lock.
-                // Return to LOOP state if IVT full.
-                // Register inval in IVT, and invalidate the
-                // directory if IVT not full. 
-                {
-                    assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CONFIG) and
-                            "MEMC ERROR in CONFIG_IVT_LOCK state: bad DIR allocation");
-
-                    if (r_alloc_ivt_fsm.read() == ALLOC_IVT_CONFIG )
-                    {
-                        size_t set        = m_y[(addr_t)(r_config_address.read())];
-                        size_t way        = r_config_dir_way.read();
-
-                        if (r_config_dir_count.read() == 0 )     // inval DIR and return to LOOP
-                        {
-                            m_cache_directory.inval( way, set );
-                            r_config_cmd_lines  = r_config_cmd_lines.read() - 1;
-                            r_config_rsp_lines  = r_config_rsp_lines.read() - 1;
-                            r_config_address    = r_config_address.read() + (m_words<<2);
-                            r_config_fsm        = CONFIG_LOOP;
+if (m_debug)
+std::cout << "  <MEMC " << name() << " CONFIG_INVAL_SEND>"
+          << " Post multi inval request to CC_SEND FSM" 
+          << " / address = " << std::hex << r_config_address.read() 
+          << " / copy = " << r_config_dir_copy_srcid.read() 
+          << " / inst = " << std::dec << r_config_dir_copy_inst.read() << std::endl;
+#endif
+                }
+                break;
+            }
+            /////////////////////
+            case CONFIG_HEAP_REQ:  // Try to get access to Heap
+            {
+                if (r_alloc_heap_fsm.read() == ALLOC_HEAP_CONFIG )
+                {
+                    r_config_fsm       = CONFIG_HEAP_SCAN;
+                    r_config_heap_next = r_config_dir_ptr.read();
+                }
 
 #if DEBUG_MEMC_CONFIG
-                            if (m_debug)
-                                std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
-                                    << " No copies in L1 : inval DIR entry"  << std::endl;
-#endif
-                        }
-                        else    // try to register inval in IVT
-                        {
-                            bool        wok       = false;
-                            size_t      index     = 0;
-                            bool        broadcast = r_config_dir_is_cnt.read();
-                            size_t      srcid     = r_config_srcid.read();
-                            size_t      trdid     = r_config_trdid.read();
-                            size_t      pktid     = r_config_pktid.read();
-                            addr_t      nline     = m_nline[(addr_t)(r_config_address.read())];
-                            size_t      nb_copies = r_config_dir_count.read();
-
-                            wok = m_ivt.set(false,       // it's an inval transaction
-                                    broadcast,   
-                                    false,       // no response required
-                                    true,        // acknowledge required
-                                    srcid,
-                                    trdid,
-                                    pktid,
-                                    nline,
-                                    nb_copies,
-                                    index);
-
-                            if (wok )  // IVT success => inval DIR slot
-                            {
-                                m_cache_directory.inval( way, set );
-                                r_config_ivt_index = index;
-                                if (broadcast )  r_config_fsm = CONFIG_BC_SEND;
-                                else              r_config_fsm = CONFIG_INVAL_SEND;
+if (m_debug)
+std::cout << "  <MEMC " << name() << " CONFIG_HEAP_REQ>"
+          << " Requesting HEAP lock" << std::endl;
+#endif
+                break;
+            }
+            //////////////////////
+            case CONFIG_HEAP_SCAN:      // scan HEAP and send inval to CC_SEND FSM
+            {
+                HeapEntry entry = m_heap.read( r_config_heap_next.read());
+                bool last_copy  = (entry.next == r_config_heap_next.read()); 
+
+                config_to_cc_send_fifo_srcid = entry.owner.srcid;
+                config_to_cc_send_fifo_inst  = entry.owner.inst;
+                // config_to_cc_send_fifo_last  = last_copy;
+                config_to_cc_send_fifo_put   = true;
+
+                if (m_config_to_cc_send_inst_fifo.wok()) // inval request accepted
+                {
+                    r_config_heap_next = entry.next;
+                    if (last_copy ) r_config_fsm = CONFIG_HEAP_LAST;
+                }
 
 #if DEBUG_MEMC_CONFIG
-                                if (m_debug)
-                                    std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
-                                        << " Inval DIR entry and register inval in IVT"
-                                        << " / index = " << std::dec << index
-                                        << " / broadcast = " << broadcast << std::endl;
-#endif
-                            }
-                            else       // IVT full => release both DIR and IVT locks
-                            {
-                                r_config_fsm = CONFIG_LOOP;
+if (m_debug)
+std::cout << "  <MEMC " << name() << " CONFIG_HEAP_SCAN>"
+          << " Post multi inval request to CC_SEND FSM" 
+          << " / address = " << std::hex << r_config_address.read() 
+          << " / copy = " << entry.owner.srcid 
+          << " / inst = " << std::dec << entry.owner.inst << std::endl;
+#endif
+                break;
+            }
+            //////////////////////
+            case CONFIG_HEAP_LAST:      // HEAP housekeeping
+            {
+                size_t free_pointer = m_heap.next_free_ptr();
+                HeapEntry last_entry;
+                last_entry.owner.srcid = 0;
+                last_entry.owner.inst  = false;
+
+                if (m_heap.is_full())
+                {
+                    last_entry.next = r_config_dir_ptr.read();
+                    m_heap.unset_full();
+                }
+                else
+                { 
+                   last_entry.next = free_pointer;
+                }
+
+                m_heap.write_free_ptr( r_config_dir_ptr.read());
+                m_heap.write( r_config_heap_next.read(), last_entry );
+
+                // prepare next iteration
+                r_config_cmd_lines          = r_config_cmd_lines.read() - 1;
+                r_config_address            = r_config_address.read() + (m_words<<2);
+                r_config_fsm                = CONFIG_LOOP;
 
 #if DEBUG_MEMC_CONFIG
-                                if (m_debug)
-                                    std::cout << "  <MEMC " << name() << " CONFIG_IVT_LOCK>"
-                                        << " IVT full : release DIR & IVT locks and retry" << std::endl;
-#endif
-                            }
-                        }
-                    }
-                    break;
-                }
-                ////////////////////
-            case CONFIG_BC_SEND:    // Post a broadcast inval request to CC_SEND FSM
-                {
-                    if (not r_config_to_cc_send_multi_req.read() and 
-                            not r_config_to_cc_send_brdcast_req.read())
-                    {
-                        // post bc inval request
-                        r_config_to_cc_send_multi_req   = false;
-                        r_config_to_cc_send_brdcast_req = true;
-                        r_config_to_cc_send_trdid       = r_config_ivt_index.read();
-                        r_config_to_cc_send_nline       = m_nline[(addr_t)(r_config_address.read())];
-
-                        // prepare next iteration
-                        r_config_cmd_lines              = r_config_cmd_lines.read() - 1;
-                        r_config_address                = r_config_address.read() + (m_words << 2);
-                        r_config_fsm                    = CONFIG_LOOP;
-
-#if DEBUG_MEMC_CONFIG
-                        if (m_debug)
-                            std::cout << "  <MEMC " << name() << " CONFIG_BC_SEND>"
-                                << " Post a broadcast inval request to CC_SEND FSM" 
-                                << " / address = " << r_config_address.read() <<std::endl;
-#endif
-                    }
-                    break;
-                }
-                ///////////////////////
-            case CONFIG_INVAL_SEND:    // Post a multi inval request to CC_SEND FSM
-                {
-                    if (not r_config_to_cc_send_multi_req.read() and 
-                            not r_config_to_cc_send_brdcast_req.read())
-                    {
-                        // post multi inval request
-                        r_config_to_cc_send_multi_req   = true;
-                        r_config_to_cc_send_brdcast_req = false;
-                        r_config_to_cc_send_trdid       = r_config_ivt_index.read();
-                        r_config_to_cc_send_nline       = m_nline[(addr_t) (r_config_address.read())];
-
-                        // post data into FIFO
-                        config_to_cc_send_fifo_srcid    = r_config_dir_copy_srcid.read();
-                        config_to_cc_send_fifo_inst     = r_config_dir_copy_inst.read();
-                        config_to_cc_send_fifo_put      = true;
-
-                        if (r_config_dir_count.read() == 1 )  // one copy
-                        {
-                            // prepare next iteration
-                            r_config_cmd_lines          = r_config_cmd_lines.read() - 1;
-                            r_config_address            = r_config_address.read() + (m_words << 2);
-                            r_config_fsm                = CONFIG_LOOP;
-                        }
-                        else                                   // several copies
-                        {
-                            r_config_fsm = CONFIG_HEAP_REQ;
-                        }
-
-#if DEBUG_MEMC_CONFIG
-                        if (m_debug)
-                            std::cout << "  <MEMC " << name() << " CONFIG_INVAL_SEND>"
-                                << " Post multi inval request to CC_SEND FSM" 
-                                << " / address = " << std::hex << r_config_address.read() 
-                                << " / copy = " << r_config_dir_copy_srcid.read() 
-                                << " / inst = " << std::dec << r_config_dir_copy_inst.read() << std::endl;
-#endif
-                    }
-                    break;
-                }
-                /////////////////////
-            case CONFIG_HEAP_REQ:  // Try to get access to Heap
-                {
-                    if (r_alloc_heap_fsm.read() == ALLOC_HEAP_CONFIG )
-                    {
-                        r_config_fsm       = CONFIG_HEAP_SCAN;
-                        r_config_heap_next = r_config_dir_ptr.read();
-                    }
-
-#if DEBUG_MEMC_CONFIG
-                    if (m_debug)
-                        std::cout << "  <MEMC " << name() << " CONFIG_HEAP_REQ>"
-                            << " Requesting HEAP lock" << std::endl;
-#endif
-                    break;
-                }
-                //////////////////////
-            case CONFIG_HEAP_SCAN:      // scan HEAP and send inval to CC_SEND FSM
-                {
-                    HeapEntry entry = m_heap.read( r_config_heap_next.read());
-                    bool last_copy  = (entry.next == r_config_heap_next.read()); 
-
-                    config_to_cc_send_fifo_srcid = entry.owner.srcid;
-                    config_to_cc_send_fifo_inst  = entry.owner.inst;
-                    // config_to_cc_send_fifo_last  = last_copy;
-                    config_to_cc_send_fifo_put   = true;
-
-                    if (m_config_to_cc_send_inst_fifo.wok()) // inval request accepted
-                    {
-                        r_config_heap_next = entry.next;
-                        if (last_copy ) r_config_fsm = CONFIG_HEAP_LAST;
-                    }
-
-#if DEBUG_MEMC_CONFIG
-                    if (m_debug)
-                        std::cout << "  <MEMC " << name() << " CONFIG_HEAP_SCAN>"
-                            << " Post multi inval request to CC_SEND FSM" 
-                            << " / address = " << std::hex << r_config_address.read() 
-                            << " / copy = " << entry.owner.srcid 
-                            << " / inst = " << std::dec << entry.owner.inst << std::endl;
-#endif
-                    break;
-                }
-                //////////////////////
-            case CONFIG_HEAP_LAST:      // HEAP housekeeping
-                {
-                    size_t free_pointer = m_heap.next_free_ptr();
-                    HeapEntry last_entry;
-                    last_entry.owner.srcid = 0;
-                    last_entry.owner.inst  = false;
-
-                    if (m_heap.is_full())
-                    {
-                        last_entry.next = r_config_dir_ptr.read();
-                        m_heap.unset_full();
-                    }
-                    else
-                    { 
-                        last_entry.next = free_pointer;
-                    }
-
-                    m_heap.write_free_ptr( r_config_dir_ptr.read());
-                    m_heap.write( r_config_heap_next.read(), last_entry );
-
-                    // prepare next iteration
-                    r_config_cmd_lines          = r_config_cmd_lines.read() - 1;
-                    r_config_address            = r_config_address.read() + (m_words<<2);
-                    r_config_fsm                = CONFIG_LOOP;
-
-#if DEBUG_MEMC_CONFIG
-                    if (m_debug)
-                        std::cout << "  <MEMC " << name() << " CONFIG_HEAP_LAST>"
-                            << " Heap housekeeping" << std::endl;
-#endif
-                    break;
-                }
+if (m_debug)
+std::cout << "  <MEMC " << name() << " CONFIG_HEAP_LAST>"
+          << " Heap housekeeping" << std::endl;
+#endif
+                break;
+            }
         }  // end switch r_config_fsm
+
+        
 
         ////////////////////////////////////////////////////////////////////////////////////
@@ -4045,8 +4056,15 @@
                 {
                     size_t  index = r_ixr_rsp_trt_index.read(); 
-                    if (m_trt.is_config(index)) 
-                        r_config_rsp_lines = r_config_rsp_lines.read() - 1;
-                    m_trt.erase(index);
-                    r_ixr_rsp_fsm = IXR_RSP_IDLE;
+                    if (m_trt.is_config(index))     // it's a config transaction
+                    {
+                        config_rsp_lines_ixr_rsp_decr = true;
+                        m_trt.erase(index);
+                        r_ixr_rsp_fsm = IXR_RSP_IDLE;
+                    }
+                    else                            // not a config transaction
+                    {
+                        m_trt.erase(index);
+                        r_ixr_rsp_fsm = IXR_RSP_IDLE;
+                    }
 
 #if DEBUG_MEMC_IXR_RSP
@@ -5147,9 +5165,9 @@
                                 "MEMC ERROR in CLEANUP_IVT_CLEAR state");
 
-                        r_config_rsp_lines = r_config_rsp_lines.read() - 1;
+                        config_rsp_lines_cleanup_decr = true;
                     }
 
                     if (r_cleanup_need_rsp.read()) r_cleanup_fsm = CLEANUP_WRITE_RSP;
-                    else                             r_cleanup_fsm = CLEANUP_SEND_CLACK;
+                    else                           r_cleanup_fsm = CLEANUP_SEND_CLACK;
 
 #if DEBUG_MEMC_CLEANUP
@@ -7890,4 +7908,19 @@
         m_cpt_cycles++;
 
+        ////////////////////////////////////////////////////////////////////////////////////
+        //            Update r_config_rsp_lines counter.
+        // The three sources of (increment / decrement) are CONFIG / CLEANUP / IXR_RSP FSMs
+        ////////////////////////////////////////////////////////////////////////////////////
+        if ( config_rsp_lines_incr and not 
+             (config_rsp_lines_cleanup_decr or config_rsp_lines_ixr_rsp_decr) )
+        {
+            r_config_rsp_lines = r_config_rsp_lines.read() + 1;
+        }
+        if ( not config_rsp_lines_incr and  
+             (config_rsp_lines_cleanup_decr or config_rsp_lines_ixr_rsp_decr) )
+        {
+            r_config_rsp_lines = r_config_rsp_lines.read() - 1;
+        }
+
     } // end transition()
 
