Index: branches/MESI/modules/vci_cc_vcache_wrapper/caba/source/src/vci_cc_vcache_wrapper.cpp
===================================================================
--- branches/MESI/modules/vci_cc_vcache_wrapper/caba/source/src/vci_cc_vcache_wrapper.cpp	(revision 674)
+++ branches/MESI/modules/vci_cc_vcache_wrapper/caba/source/src/vci_cc_vcache_wrapper.cpp	(revision 675)
@@ -106,4 +106,5 @@
         "DCACHE_MISS_DATA_UPDT",
         "DCACHE_MISS_DIR_UPDT",
+        "DCACHE_MISS_BACKOFF",
 
         "DCACHE_UNC_WAIT",
@@ -385,5 +386,5 @@
       r_vci_rsp_data_error("r_vci_rsp_data_error"),
       r_vci_rsp_fifo_icache("r_vci_rsp_fifo_icache", 2),	// 2 words depth
-      r_vci_rsp_fifo_dcache("r_vci_rsp_fifo_dcache", 2),	// 2 words depth
+      r_vci_rsp_fifo_dcache("r_vci_rsp_fifo_dcache", 16),	// 2 words depth
 //      r_vci_rsp_fifo_rpktid("r_vci_rsp_fifo_rpktid", 2),    // 2 words depth
       r_cc_send_data_fifo("r_cc_send_data_fifo", 16),
@@ -872,4 +873,6 @@
         r_dcache_xtn_flush_data_cpt = 0;
         r_dcache_cc_inval_data_cpt = 0;
+        r_dcache_count_backoff = 0;
+        r_dcache_count_begin = 0;
 
         r_dcache_cleanup_victim_req = false;
@@ -2295,4 +2298,12 @@
         {
 
+//#if 1
+//            // @@@ DO NOT COMMIT: ALMOS KILLING SIMU PURPOSE
+//            if (m_dreq.addr == 0x0 && m_dreq.wdata == 0xDEADDEAD) {
+//                std::cout << "*** Ecriture Ã  l'adresse 0 pour fin de simulation ***" << std::endl;
+//                raise(SIGINT);
+//            }
+//#endif
+
             if ( r_mmu_mode.read() & DATA_TLB_MASK )  // DTLB activated
             {
@@ -2439,5 +2450,5 @@
         }
         // coherence request (from CC_RECEIVE FSM)
-        else if ( r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read() and not r_dcache_miss_updt.read())
+        else if ( r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read())
         {
             r_dcache_fsm = DCACHE_CC_CHECK;
@@ -2449,5 +2460,4 @@
         else if ( m_dreq.valid )
         {
-            r_dcache_miss_updt = false;
             // register processor request and DCACHE response
             r_dcache_save_vaddr      = m_dreq.addr;
@@ -3121,5 +3131,5 @@
 
         // coherence request (from CC_RECEIVE FSM)
-        if ( r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read() and not r_dcache_miss_updt.read())
+        if ( r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read())
         {
             r_dcache_fsm = DCACHE_CC_CHECK;
@@ -3128,5 +3138,4 @@
         }
 
-        r_dcache_miss_updt = false;
         uint32_t 	entry;
         size_t		way;
@@ -3437,5 +3446,5 @@
 
         // coherence request (from CC_RECEIVE FSM)
-        if ( r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read() and not r_dcache_miss_updt.read())
+        if ( r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read())
         {
             r_dcache_fsm = DCACHE_CC_CHECK;
@@ -3444,5 +3453,4 @@
         }
         
-        r_dcache_miss_updt = false;
         uint32_t 	pte_flags     = 0;
         uint32_t 	pte_ppn       = 0;
@@ -4747,5 +4755,5 @@
 
         // coherence request (from CC_RECEIVE FSM)
-        if ( r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read() and not r_dcache_cleanup_victim_req.read() and not r_dcache_miss_updt.read())
+        if ( r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read() and not r_dcache_cleanup_victim_req.read() and not r_dcache_miss_inval.read() and not r_dcache_miss_updt.read())
         {
             r_dcache_fsm = DCACHE_CC_CHECK;
@@ -4754,26 +4762,25 @@
         }
 
-        if ( not r_dcache_miss_clack.read() )  // waiting cleanup acknowledge
+        if ( not r_dcache_miss_clack.read() and not r_dcache_cc_send_req.read())  // waiting cleanup acknowledge
         {
             if ( r_dcache_miss_inval.read() ) // switch slot to ZOMBI state, and new cleanup
             {
-                if ( not r_dcache_cc_send_req.read() ) // blocked until previous request sent
-                {
-                    r_dcache_miss_inval         = false;
-                    // request cleanup
-                    r_dcache_cc_send_req        = true;
-                    r_dcache_cc_send_nline      = r_dcache_save_paddr.read()/(m_dcache_words<<2);
-                    r_dcache_cc_send_way        = r_dcache_miss_way.read();
-                    r_dcache_cc_send_type       = CC_TYPE_CLEANUP;
-                    r_dcache_cc_line_dirty      = false;   // in case of miss inval, the cleanup is not with data.
-                    r_dcache_cc_line_no_shared  = r_dcache_rsp_state.read(); // the miss read rsp contents the state of this line 
+                r_dcache_miss_inval         = false;
+                // request cleanup
+                r_dcache_cc_send_req        = true;
+                r_dcache_cc_send_nline      = r_dcache_save_paddr.read()/(m_dcache_words<<2);
+                r_dcache_cc_send_way        = r_dcache_miss_way.read();
+                r_dcache_cc_send_type       = CC_TYPE_CLEANUP;
+                r_dcache_cc_line_dirty      = false;   // in case of miss inval, the cleanup is not with data.
+                r_dcache_cc_line_no_shared  = r_dcache_rsp_state.read(); // the miss read rsp contents the state of this line 
 
 #ifdef INSTRUMENTATION
 m_cpt_dcache_dir_write++;
 #endif
-                    r_dcache.write_dir( r_dcache_save_paddr.read(),
-                                        r_dcache_miss_way.read(),
-                                        r_dcache_miss_set.read(),
-                                        CACHE_SLOT_STATE_ZOMBI );
+                r_dcache.write_dir( r_dcache_save_paddr.read(),
+                                    r_dcache_miss_way.read(),
+                                    r_dcache_miss_set.read(),
+                                    CACHE_SLOT_STATE_ZOMBI );
+
 #if DEBUG_DCACHE
 if ( m_debug_activated )
@@ -4784,7 +4791,26 @@
           << " / SET = "   << r_dcache_miss_set.read() << std::endl;
 #endif
+
+                if( not r_dcache_miss_updt.read())
+                {
+                    r_dcache_fsm                = DCACHE_MISS_BACKOFF;
+                    r_dcache_count_backoff      = r_dcache_count_backoff.read() + 1;
+                    r_dcache_count_begin        = 0;                    
                 }
-                else
-                    break;
+                break;
+            }
+            else if( r_dcache_miss_updt.read())
+            {
+                r_dcache_miss_updt              = false;
+                r_cc_receive_dcache_req         = false;
+                r_dcache_cc_send_req            = true;
+                r_dcache_cc_send_multi_ack_miss = true;
+                r_dcache_cc_send_nline          = r_cc_receive_dcache_nline.read();
+                r_dcache_cc_send_updt_tab_idx   = r_cc_receive_dcache_updt_tab_idx.read();
+                r_dcache_cc_send_type           = CC_TYPE_MULTI_ACK;
+
+                r_dcache_fsm                    = DCACHE_MISS_BACKOFF;
+                r_dcache_count_backoff          = r_dcache_count_backoff.read() + 1;
+                r_dcache_count_begin            = 0;   
             }
             else                              // switch slot to VALID state
@@ -4794,5 +4820,5 @@
 m_cpt_dcache_dir_write++;
 #endif
-
+                r_dcache_count_backoff  = 0;
                 size_t way = r_dcache_miss_way.read();
                 size_t set = r_dcache_miss_set.read();
@@ -4822,12 +4848,32 @@
 #endif
                 // reset directory extension
-
-            }
+               if      (r_dcache_miss_type.read()==PTE1_MISS) r_dcache_fsm = DCACHE_TLB_PTE1_GET;
+               else if (r_dcache_miss_type.read()==PTE2_MISS) r_dcache_fsm = DCACHE_TLB_PTE2_GET;
+               else                                           r_dcache_fsm = DCACHE_IDLE;
+            }
+        }
+        break;
+    }
+    /////////////////////
+    case DCACHE_MISS_BACKOFF:
+    {
+        size_t count_max = r_dcache_count_backoff.read() << 4;
+        r_dcache_count_begin = r_dcache_count_begin.read() + 1;
+        if(r_dcache_count_begin.read() == count_max)
+        {
             if      (r_dcache_miss_type.read()==PTE1_MISS) r_dcache_fsm = DCACHE_TLB_PTE1_GET;
             else if (r_dcache_miss_type.read()==PTE2_MISS) r_dcache_fsm = DCACHE_TLB_PTE2_GET;
             else                                           r_dcache_fsm = DCACHE_IDLE;
         }
-        break;
-    }
+        break; 
+#if DEBUG_DCACHE
+if ( m_debug_activated )
+std::cout << "  <PROC " << name()
+          << " DCACHE_MISS_BACKOFF> operation back off"
+          << std::endl;
+#endif
+ 
+    }
+
     /////////////////////
     case DCACHE_UNC_WAIT:  // waiting a response to an uncacheable read
@@ -5245,29 +5291,19 @@
         {
 
-            if(r_cc_receive_dcache_type.read() == CC_TYPE_BRDCAST and r_dcache_read_for_modify.read() and 
-               r_cc_receive_dcache_srcid.read() == m_srcid and (r_dcache_miss_type.read() == PROC_MISS))
-            {
+            if(r_dcache_read_for_modify.read() and(r_dcache_miss_type.read() == PROC_MISS) and (r_cc_receive_dcache_type.read() != CC_TYPE_UPDT) and (state == CACHE_SLOT_STATE_SHARED))
+            {
+                r_dcache_fsm = DCACHE_CC_INVAL;
+            }
+            else if(r_cc_receive_dcache_type.read() == CC_TYPE_UPDT)
+            {
+                r_dcache_fsm                    = r_dcache_fsm_cc_save.read();
+                r_dcache_miss_updt              = true;
+                r_dcache_miss_inval             = true;
+            }
+            else
+            {
+                r_dcache_miss_inval     = true;
                 r_cc_receive_dcache_req = false;
                 r_dcache_fsm            = r_dcache_fsm_cc_save.read();
-            }
-            else if(r_cc_receive_dcache_type.read() == CC_TYPE_BRDCAST and 
-                    r_dcache_read_for_modify.read() and 
-                    r_cc_receive_dcache_srcid.read() != m_srcid and 
-                    (r_dcache_miss_type.read() == PROC_MISS) and 
-                    (state == CACHE_SLOT_STATE_SHARED))
-            {
-                r_dcache_fsm        = DCACHE_CC_INVAL;
-            }
-            else if(r_cc_receive_dcache_type.read() == CC_TYPE_INVAL and r_dcache_read_for_modify.read() and 
-                    (r_dcache_miss_type.read() == PROC_MISS) and
-                    (state == CACHE_SLOT_STATE_SHARED))
-            {
-                r_dcache_fsm        = DCACHE_CC_INVAL;
-            }
-            else
-            {
-                r_dcache_miss_inval = false;
-                r_dcache_miss_updt  = true;
-                r_dcache_fsm        = r_dcache_fsm_cc_save.read();
             }
             // signaling matching
@@ -5622,11 +5658,4 @@
     } // end switch r_dcache_fsm
 
-//if(r_dcache_miss_updt.read())
-//std::cout << "  <PROC " << name() 
-//          << " miss updt " << r_dcache_miss_updt.read() << std::endl;
-
-//std::cout << "  <PROC " << name() 
-//          << " get cache state " << r_dcache.get_cache_state(2,0) << std::endl;
-
     ///////////////// llsc update ///////////////////////////////////////////////////////
     if (r_dcache_llsc_valid.read()) r_dcache_llsc_count = r_dcache_llsc_count.read() - 1;
@@ -6267,4 +6296,11 @@
                 r_cc_receive_dcache_srcid = DspinDhccpParam::dspin_get(receive_data,
                                             DspinDhccpParam::BROADCAST_SRCID);
+
+                r_cc_receive_dcache_inval_is_config = DspinDhccpParam::dspin_get(receive_data,
+                                                      DspinDhccpParam::BRDCAST_IS_CONFIG);
+
+                r_cc_receive_dcache_is_shared = DspinDhccpParam::dspin_get(receive_data,
+                                            DspinDhccpParam::BRDCAST_IS_SHARED);
+
                 r_cc_receive_fsm          = CC_RECEIVE_BRDCAST_NLINE;
             }
@@ -6316,4 +6352,7 @@
                 r_cc_receive_dcache_inval_is_config = DspinDhccpParam::dspin_get(receive_data,
                                                       DspinDhccpParam::MULTI_INVAL_IS_CONFIG);
+
+                r_cc_receive_dcache_is_shared = DspinDhccpParam::dspin_get(receive_data,
+                                            DspinDhccpParam::MULTI_INVAL_IS_SHARED);
             }
             break;
