Index: branches/MESI/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp
===================================================================
--- branches/MESI/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp	(revision 676)
+++ branches/MESI/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp	(revision 677)
@@ -135,5 +135,5 @@
         "MULTI_ACK_HEAP_LOCK",
         "MULTI_ACK_HEAP_WRITE",
-        "MULTI_ACK_WAIT"
+        "MULTI_ACK_IVT_CHANGE"
     };
     const char *config_fsm_str[] =
@@ -1112,7 +1112,8 @@
             r_tgt_cmd_to_tgt_rsp_req = false;
 
+            r_read_to_cc_send_multi_req = false;
+            r_read_to_cc_send_brdcast_req = false;
             r_read_to_tgt_rsp_req = false;
             r_read_to_ixr_cmd_req = false;
-            r_read_to_cc_send_req = false;
             r_read_to_cleanup_req = false;
             r_read_to_multi_ack_req     = false;
@@ -2155,7 +2156,11 @@
                         if(not entry.count)
                         {
+                            r_multi_ack_fsm = MULTI_ACK_IVT_LOCK; 
                             r_multi_ack_miss_updt = false;
                         }
-                        r_multi_ack_fsm = MULTI_ACK_WAIT; 
+                        else
+                        {
+                            r_multi_ack_fsm = MULTI_ACK_IVT_CHANGE; 
+                        }
                     }
                     else if( not entry.count or match_ll) // The line has been already evicted from cache L1
@@ -2173,15 +2178,17 @@
                 }
                 /////////////
-            case MULTI_ACK_WAIT:   // release all locks and retry from beginning
-                {
-
+            case MULTI_ACK_IVT_CHANGE:   // release all locks and retry from beginning
+                {                  
+                    if(r_alloc_ivt_fsm.read() != ALLOC_IVT_MULTI_ACK)  break;
+                    
+                    m_ivt.change(r_multi_ack_ivt_index.read());
 #if DEBUG_MEMC_MULTI_ACK
                     if(m_debug)
                     {
                         std::cout << "  <MEMC " << name()
-                            << " MULTI_ACK_WAIT> Release all locks" << std::endl;
-                    }
-#endif
-                    r_multi_ack_fsm = MULTI_ACK_IVT_LOCK;
+                            << " MULTI_ACK_IVT_CHANGE> multi ack miss, count is 1, change ivt state" << std::endl;
+                    }
+#endif
+                    r_multi_ack_fsm = MULTI_ACK_IDLE;
                     break;
                 }
@@ -3234,6 +3241,6 @@
                             r_read_to_cc_send_brdcast_req   = not multi_req;
                             r_read_to_cc_send_nline         = nline;
-                            r_read_to_cc_send_srcid         = m_cmd_read_srcid_fifo.read();
-                            r_read_to_cc_send_is_shared     = r_read_state.read() == ENTRY_SHARED;
+                            //r_read_to_cc_send_srcid         = m_cmd_read_srcid_fifo.read();
+                            //r_read_to_cc_send_is_shared     = r_read_state.read() == ENTRY_SHARED;
 
                             if(r_read_need_block.read())
@@ -3442,5 +3449,5 @@
                                                            false,             // multi_inval  
                                                            true,              // it needs a read response
-                                                           true,              // acknowledge required
+                                                           false,              // acknowledge required
                                                            m_cmd_read_srcid_fifo.read(),
                                                            m_cmd_read_trdid_fifo.read(),
@@ -6635,4 +6642,5 @@
                             << " CLEANUP_LOCKED_IVT_LOCK> :"
                             << "/ is_updt =" << m_ivt.is_update(index)
+                            << "/ is_change =" << m_ivt.is_change(index)
                             << "/ match =" << match_inval
                             << "/ need rsp  =" << m_ivt.need_rsp(index)
@@ -6641,17 +6649,18 @@
 #endif
 
-                        r_cleanup_locked_srcid    = m_ivt.srcid(index);
-                        r_cleanup_locked_trdid    = m_ivt.trdid(index);
-                        r_cleanup_locked_pktid    = m_ivt.pktid(index);
-                        r_cleanup_locked_index    = index;
-                        r_cleanup_locked_is_updt  = m_ivt.is_update(index);
-
-                        if( not m_ivt.is_update(index))
-                        {
-                           r_cleanup_fsm = CLEANUP_LOCKED_IVT_DECREMENT;
+                        r_cleanup_locked_srcid      = m_ivt.srcid(index);
+                        r_cleanup_locked_trdid      = m_ivt.trdid(index);
+                        r_cleanup_locked_pktid      = m_ivt.pktid(index);
+                        r_cleanup_locked_index      = index;
+                        r_cleanup_locked_is_updt    = m_ivt.is_update(index);
+                        r_cleanup_locked_is_change  = m_ivt.is_change(index);
+
+                        if( m_ivt.is_update(index) and not m_ivt.is_change(index))
+                        {
+                            r_cleanup_fsm = CLEANUP_LOCKED_IVT_CLEAR;
                         }
                         else
                         {
-                            r_cleanup_fsm = CLEANUP_LOCKED_IVT_CLEAR;
+                            r_cleanup_fsm = CLEANUP_LOCKED_IVT_DECREMENT;
                         }
 
@@ -6705,8 +6714,10 @@
                     size_t match_cas_multi_inval = r_cas_to_cleanup_req.read() and
                                                   (r_cas_to_cleanup_nline.read() == r_cleanup_nline.read()); 
+
+                    bool match_ll = ((r_cleanup_locked_pktid.read() & 0x07) == TYPE_LL);
                     DirectoryEntry  entry;
                     entry.is_cnt        = false;
                     entry.lock          = r_cleanup_lock.read();
-                    entry.dirty         = r_cleanup_dirty.read();
+                    entry.dirty         = r_cleanup_dirty.read() or r_cleanup_contains_data.read();
                     entry.tag           = r_cleanup_tag.read();
                     entry.ptr           = r_cleanup_ptr.read();
@@ -6728,6 +6739,7 @@
                     }
 
-                    if(r_cleanup_locked_is_updt.read()) //cleanup req cross with multi ack rsp. here, just decrements the count and remains the state.
-                    {
+                    if(r_cleanup_locked_is_updt.read() and not r_cleanup_locked_is_change.read()) //cleanup req cross with multi ack rsp. here, just decrements the count and remains the state.
+                    {
+                        assert(r_cleanup_count.read() == 1 && " only one copy when cleanup fsm receives a req for is_updt command");
                         entry.state         = r_cleanup_state.read();  //cross with cc updt cmd, don't modify the state
                         entry.count         = 0;
@@ -6735,4 +6747,30 @@
                         entry.owner.inst    = 0;
                         r_cleanup_fsm       = CLEANUP_SEND_CLACK;
+                    }
+                    else if(r_cleanup_locked_is_updt.read() and r_cleanup_locked_is_change.read())
+                    {
+                        entry.state = ENTRY_SHARED;
+                        if(match_ll)
+                        {
+                            entry.count       = 0;
+                            entry.owner.srcid = 0;
+                        }
+                        else
+                        {
+                            entry.count       = 1;
+                            entry.owner.srcid = r_cleanup_locked_srcid.read();
+                        }
+
+                        if((r_cleanup_locked_pktid.read() & 0x7) == 0x03) 
+                        {
+                            entry.owner.inst = true;
+                        }
+                        else
+                        {
+                            entry.owner.inst = false;
+                        }
+
+                        r_cleanup_fsm       = CLEANUP_LOCKED_RSP;
+                        m_ivt.clear(r_cleanup_locked_index.read());
                     }
                     else // cas, getm, one copy updated in dir
@@ -6781,7 +6819,23 @@
                     r_cleanup_to_tgt_rsp_nline   = r_cleanup_nline.read();
                     
-                    r_cleanup_to_tgt_rsp_pktid   = 0x8 + r_cleanup_locked_pktid.read(); // there is not a brdcast for cas operation. in cache L1, the line can be in M state
-                    
-                    if(r_read_to_cleanup_req.read() and (r_read_to_cleanup_nline.read() == r_cleanup_nline.read())) // rsp for LL or pheriph
+                    if(r_cleanup_locked_is_change.read() and r_cleanup_locked_is_updt.read())
+                    {
+                        r_cleanup_to_tgt_rsp_pktid   = r_cleanup_locked_pktid.read(); // rsp for is_updt in shared state
+                    }
+                    else
+                    {
+
+                        r_cleanup_to_tgt_rsp_pktid   = 0x8 + r_cleanup_locked_pktid.read(); // there is not a brdcast for cas operation. in cache L1, the line can be in M state
+                    }
+
+                    if(r_read_to_multi_ack_req.read() and (r_read_to_multi_ack_nline.read() == r_cleanup_nline.read()) and // rsp for LL or pheriph
+                      (r_cleanup_locked_is_change.read() and r_cleanup_locked_is_updt.read()))
+                    {
+                        r_cleanup_to_tgt_rsp_ll_key     = r_read_to_multi_ack_ll_key.read(); 
+                        r_cleanup_to_tgt_rsp_length     = r_read_to_multi_ack_length.read();
+                        r_cleanup_to_tgt_rsp_first_word = r_read_to_multi_ack_first_word.read();
+                        r_read_to_multi_ack_req           = false;
+                    } 
+                    else if(r_read_to_cleanup_req.read() and (r_read_to_cleanup_nline.read() == r_cleanup_nline.read())) // rsp for LL or pheriph
                     {
                         r_cleanup_to_tgt_rsp_ll_key     = r_read_to_cleanup_ll_key.read(); 
@@ -6820,8 +6874,8 @@
                             << " <MEMC " << name()
                             << " CLEANUP_LOCKED_RSP>"
-                            << "type rsp =" << r_cleanup_locked_pktid.read()
-                            << "r_read_to_cleanup_req  =" << r_read_to_cleanup_req.read()
-                            << "r_read_to_cleanup_length  =" << r_read_to_cleanup_length.read()
-                            << "r_read_to_cleanup_first_word  =" << r_read_to_cleanup_first_word.read()
+                            << " type rsp =" << r_cleanup_locked_pktid.read()
+                            << " r_read_to_cleanup_req  =" << r_read_to_cleanup_req.read()
+                            << " r_read_to_cleanup_length  =" << r_read_to_cleanup_length.read()
+                            << " r_read_to_cleanup_first_word  =" << r_read_to_cleanup_first_word.read()
                             << std::endl;
                     }
@@ -7267,8 +7321,8 @@
                             }
                             //std::cout << "cleanup with a non coherent ligne in trt index = " << index << std::endl;
-                            r_cleanup_to_ixr_cmd_srcid        = r_cleanup_srcid.read();
+                            //r_cleanup_to_ixr_cmd_srcid        = r_cleanup_srcid.read();
                             r_cleanup_to_ixr_cmd_index        = index;
-                            r_cleanup_to_ixr_cmd_pktid        = r_cleanup_pktid.read();
-                            r_cleanup_to_ixr_cmd_nline        = r_cleanup_nline.read();
+                            //r_cleanup_to_ixr_cmd_pktid        = r_cleanup_pktid.read();
+                            //r_cleanup_to_ixr_cmd_nline        = r_cleanup_nline.read();
                             //r_cleanup_to_ixr_cmd_l1_dirty_ncc = r_cleanup_contains_data.read();
                             r_cleanup_fsm = CLEANUP_SEND_CLACK;
@@ -9826,5 +9880,6 @@
                         r_alloc_ivt_fsm = ALLOC_IVT_CONFIG;
 
-                    else if (r_multi_ack_fsm.read() == MULTI_ACK_IVT_LOCK)
+                    else if ((r_multi_ack_fsm.read() == MULTI_ACK_IVT_LOCK) or
+                            (r_multi_ack_fsm.read() == MULTI_ACK_IVT_CHANGE))
                         r_alloc_ivt_fsm = ALLOC_IVT_MULTI_ACK;
 
@@ -9853,5 +9908,6 @@
                         r_alloc_ivt_fsm = ALLOC_IVT_CONFIG;
 
-                    else if (r_multi_ack_fsm.read() == MULTI_ACK_IVT_LOCK)
+                    else if ((r_multi_ack_fsm.read() == MULTI_ACK_IVT_LOCK) or
+                            (r_multi_ack_fsm.read() == MULTI_ACK_IVT_CHANGE))
                         r_alloc_ivt_fsm = ALLOC_IVT_MULTI_ACK;
 
@@ -9879,5 +9935,6 @@
                         r_alloc_ivt_fsm = ALLOC_IVT_CONFIG;
 
-                    else if (r_multi_ack_fsm.read() == MULTI_ACK_IVT_LOCK)
+                    else if ((r_multi_ack_fsm.read() == MULTI_ACK_IVT_LOCK) or
+                            (r_multi_ack_fsm.read() == MULTI_ACK_IVT_CHANGE))
                         r_alloc_ivt_fsm = ALLOC_IVT_MULTI_ACK;
 
@@ -9908,5 +9965,6 @@
                         r_alloc_ivt_fsm = ALLOC_IVT_CONFIG;
 
-                    else if (r_multi_ack_fsm.read() == MULTI_ACK_IVT_LOCK)
+                    else if ((r_multi_ack_fsm.read() == MULTI_ACK_IVT_LOCK) or
+                            (r_multi_ack_fsm.read() == MULTI_ACK_IVT_CHANGE))
                         r_alloc_ivt_fsm = ALLOC_IVT_MULTI_ACK;
 
@@ -9934,5 +9992,6 @@
                         r_alloc_ivt_fsm = ALLOC_IVT_CONFIG;
 
-                    else if (r_multi_ack_fsm.read() == MULTI_ACK_IVT_LOCK)
+                    else if ((r_multi_ack_fsm.read() == MULTI_ACK_IVT_LOCK) or
+                            (r_multi_ack_fsm.read() == MULTI_ACK_IVT_CHANGE))
                         r_alloc_ivt_fsm = ALLOC_IVT_MULTI_ACK;
 
@@ -9960,5 +10019,6 @@
                 if (r_config_fsm.read() != CONFIG_IVT_LOCK)
                 {
-                    if (r_multi_ack_fsm.read() == MULTI_ACK_IVT_LOCK)
+                    if ((r_multi_ack_fsm.read() == MULTI_ACK_IVT_LOCK) or
+                            (r_multi_ack_fsm.read() == MULTI_ACK_IVT_CHANGE))
                         r_alloc_ivt_fsm = ALLOC_IVT_MULTI_ACK;
 
@@ -9987,5 +10047,6 @@
                 //////////////////////////
             case ALLOC_IVT_MULTI_ACK:           // allocated to MULTI ACK FSM
-                if (r_multi_ack_fsm.read() != MULTI_ACK_IVT_LOCK)
+                if ((r_multi_ack_fsm.read() != MULTI_ACK_IVT_LOCK) and
+                    (r_multi_ack_fsm.read() != MULTI_ACK_IVT_CHANGE))
                 {
                     if ((r_write_fsm.read() == WRITE_INVAL_IVT_LOCK))
@@ -11517,5 +11578,5 @@
 
                     DspinDhccpParam::dspin_set( flit,
-                            m_cc_global_id + 0xff,
+                            m_cc_global_id,
                             DspinDhccpParam::BROADCAST_SRCID);
 
@@ -11539,5 +11600,5 @@
 
                     DspinDhccpParam::dspin_set( flit,
-                            m_cc_global_id + 0xff,
+                            m_cc_global_id,
                             DspinDhccpParam::BROADCAST_SRCID);
 
@@ -11558,11 +11619,11 @@
                             DspinDhccpParam::BROADCAST_BOX);
 
-                    DspinDhccpParam::dspin_set( flit,
-                            r_read_to_cc_send_srcid.read(),    // send the srcid itself which demands the request getM
-                            DspinDhccpParam::BROADCAST_SRCID);
-
-                    DspinDhccpParam::dspin_set( flit,
-                            r_read_to_cc_send_is_shared.read(),    // send the actuel line state in memcache
-                            DspinDhccpParam::BRDCAST_IS_SHARED);
+                   // DspinDhccpParam::dspin_set( flit,
+                   //         r_read_to_cc_send_srcid.read(),    // send the srcid itself which demands the request getM
+                   //         DspinDhccpParam::BROADCAST_SRCID);
+
+                   // DspinDhccpParam::dspin_set( flit,
+                   //         r_read_to_cc_send_is_shared.read(),    // send the actuel line state in memcache
+                   //         DspinDhccpParam::BRDCAST_IS_SHARED);
 
                     DspinDhccpParam::dspin_set( flit,
