Index: branches/MESI/modules/vci_mem_cache/caba/source/include/update_tab.h
===================================================================
--- branches/MESI/modules/vci_mem_cache/caba/source/include/update_tab.h	(revision 676)
+++ branches/MESI/modules/vci_mem_cache/caba/source/include/update_tab.h	(revision 677)
@@ -27,17 +27,19 @@
   addr_t	nline;	    // The identifier of the cache line
   size_t 	count;      // The number of acknowledge responses to receive
+  bool      is_change;  // multi ack miss req sends this bit to 1
 
   UpdateTabEntry()
   {
-    valid	= false;
-    update  = false;
-    brdcast = false;
-    rsp     = false;
-    ack     = false;
-    srcid	= 0;
-    trdid	= 0;
-    pktid	= 0;
-    nline	= 0;
-    count	= 0;
+    valid	    = false;
+    update      = false;
+    brdcast     = false;
+    rsp         = false;
+    ack         = false;
+    srcid	    = 0;
+    trdid	    = 0;
+    pktid	    = 0;
+    nline	    = 0;
+    count	    = 0;
+    is_change   = 0;
   }
 
@@ -51,30 +53,33 @@
                  size_t i_pktid, 
                  addr_t i_nline,
-                 size_t i_count) 
-  {
-    valid	= i_valid;
-    update	= i_update;
-    brdcast = i_brdcast;
-    rsp     = i_rsp;
-    ack     = i_ack;
-    srcid	= i_srcid;
-    trdid	= i_trdid;
-    pktid	= i_pktid;
-    nline	= i_nline;
-    count	= i_count;
+                 size_t i_count,
+                 size_t i_is_change) 
+  {
+    valid	    = i_valid;
+    update	    = i_update;
+    brdcast     = i_brdcast;
+    rsp         = i_rsp;
+    ack         = i_ack;
+    srcid	    = i_srcid;
+    trdid	    = i_trdid;
+    pktid	    = i_pktid;
+    nline	    = i_nline;
+    count	    = i_count;
+    is_change   = i_is_change;
   }
 
   UpdateTabEntry(const UpdateTabEntry &source)
   {
-    valid   = source.valid;
-    update  = source.update;
-    brdcast = source.brdcast;
-    rsp     = source.rsp;
-    ack     = source.ack;
-    srcid   = source.srcid;
-    trdid   = source.trdid;
-    pktid   = source.pktid;
-    nline   = source.nline;
-    count   = source.count;
+    valid       = source.valid;
+    update      = source.update;
+    brdcast     = source.brdcast;
+    rsp         = source.rsp;
+    ack         = source.ack;
+    srcid       = source.srcid;
+    trdid       = source.trdid;
+    pktid       = source.pktid;
+    nline       = source.nline;
+    count       = source.count;
+    is_change   = source.is_change;
   }
 
@@ -84,14 +89,15 @@
   void init()
   {
-    valid  = false;
-    update = false;
-    brdcast= false;
-    rsp    = false;
-    ack    = false;
-    srcid  = 0;
-    trdid  = 0;
-    pktid  = 0;
-    nline  = 0;
-    count  = 0;
+    valid       = false;
+    update      = false;
+    brdcast     = false;
+    rsp         = false;
+    ack         = false;
+    srcid       = 0;
+    trdid       = 0;
+    pktid       = 0;
+    nline       = 0;
+    count       = 0;
+    is_change   = 0;
   }
 
@@ -103,14 +109,15 @@
   void copy(const UpdateTabEntry &source)
   {
-    valid  = source.valid;
-    update = source.update;
-    brdcast= source.brdcast;
-    rsp    = source.rsp;
-    ack    = source.ack  ;
-    srcid  = source.srcid;
-    trdid  = source.trdid;
-    pktid  = source.pktid;
-    nline  = source.nline;
-    count  = source.count;
+    valid       = source.valid;
+    update      = source.update;
+    brdcast     = source.brdcast;
+    rsp         = source.rsp;
+    ack         = source.ack;
+    srcid       = source.srcid;
+    trdid       = source.trdid;
+    pktid       = source.pktid;
+    nline       = source.nline;
+    count       = source.count;
+    is_change   = source.is_change;
   }
 
@@ -220,5 +227,6 @@
            const addr_t nline,
            const size_t count,
-           size_t       &index)
+           size_t       &index,
+           const bool   is_change=false)
   {
     for ( size_t i=0 ; i<size_tab ; i++ ) 
@@ -236,4 +244,5 @@
         tab[i].nline		= (addr_t) nline;
         tab[i].count		= (size_t) count;
+        tab[i].is_change    = is_change;
         index			    = i;
         return true;
@@ -452,4 +461,15 @@
   }
 
+  void change(const size_t index)
+  {
+    assert(index<size_tab && "Bad Update Tab Entry");
+    tab[index].is_change = true;
+  }
+
+  size_t is_change(const size_t index)
+  {
+    assert(index<size_tab && "Bad Update Tab Entry");
+    return tab[index].is_change;
+  }
 };
 
Index: branches/MESI/modules/vci_mem_cache/caba/source/include/vci_mem_cache.h
===================================================================
--- branches/MESI/modules/vci_mem_cache/caba/source/include/vci_mem_cache.h	(revision 676)
+++ branches/MESI/modules/vci_mem_cache/caba/source/include/vci_mem_cache.h	(revision 677)
@@ -161,5 +161,5 @@
         MULTI_ACK_HEAP_LOCK,
         MULTI_ACK_HEAP_WRITE,
-        MULTI_ACK_WAIT
+        MULTI_ACK_IVT_CHANGE
       };
 
@@ -1024,4 +1024,5 @@
       sc_signal<size_t>   r_cleanup_locked_index;   // ivt index
       sc_signal<bool>     r_cleanup_locked_is_updt; 
+      sc_signal<bool>     r_cleanup_locked_is_change; 
 
       sc_signal<size_t>   r_cleanup_miss_srcid;   // srcid of write rsp
@@ -1029,5 +1030,4 @@
       sc_signal<size_t>   r_cleanup_miss_pktid;   // pktid of write rsp
       sc_signal<size_t>   r_cleanup_miss_index;   // ivt index
-      sc_signal<bool>     r_cleanup_miss_is_updt; 
       sc_signal<bool>     r_cleanup_miss_need_rsp;      // write response required
       sc_signal<bool>     r_cleanup_miss_need_ack;      // config acknowledge required
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,
