Index: /branches/v5/modules/vci_cc_vcache_wrapper/caba/source/src/vci_cc_vcache_wrapper.cpp
===================================================================
--- /branches/v5/modules/vci_cc_vcache_wrapper/caba/source/src/vci_cc_vcache_wrapper.cpp	(revision 460)
+++ /branches/v5/modules/vci_cc_vcache_wrapper/caba/source/src/vci_cc_vcache_wrapper.cpp	(revision 461)
@@ -1819,8 +1819,9 @@
         paddr_t  mask  = ~((m_icache_words<<2)-1);
 
+        // CLACK handler
+        // We switch the directory slot to EMPTY state
+        // and reset r_icache_miss_clack if the cleanup ack
+        // is matching a pending miss.
         if ( r_icache_clack_req.read() )
-                           	// We switch the directory slot to EMPTY state
-                            // and reset r_icache_miss_clack if the cleanup ack
-                            // is matching a pending miss
         {
 
@@ -1837,7 +1838,13 @@
             if ( (r_icache_miss_set.read() == r_icache_clack_set.read()) and
                  (r_icache_miss_way.read() == r_icache_clack_way.read()) )
-                    r_icache_miss_clack = false;
+            {
+                r_icache_miss_clack = false;
+            }
 
             r_icache_clack_req = false;
+
+            // return to cc_save state if no pending CC request
+            if ( not r_cc_receive_icache_req.read() )
+                r_icache_fsm = r_icache_fsm_save.read();
 
 #if DEBUG_ICACHE
@@ -1845,22 +1852,19 @@
 {
     std::cout << "  <PROC " << name()
-    << " ICACHE_CC_CHECK>  CC_TYPE_CLACK slot returns to empty state"
-    << " set = " << r_icache_clack_set.read()
-    << " / way = " << r_icache_clack_way.read() << std::endl;
+        << " ICACHE_CC_CHECK>  CC_TYPE_CLACK slot returns to empty state"
+        << " set = " << r_icache_clack_set.read()
+        << " / way = " << r_icache_clack_way.read() << std::endl;
 }
 #endif
-            // we should handle the clack request first, 
-            // if the cc request is arrived simultaneously, 
-            // we stay here in next cycle for treating the cc request. 
-            if ( not r_cc_receive_icache_req.read() )
-                r_icache_fsm          = r_icache_fsm_save.read();
-
-            break;
-       }
-        else if( r_cc_receive_icache_req.read() and
-                 ((r_icache_fsm_save.read() == ICACHE_MISS_SELECT) or
-                 (r_icache_fsm_save.read() == ICACHE_MISS_WAIT) or
-                 (r_icache_fsm_save.read() == ICACHE_MISS_DIR_UPDT)) and
-                 ((r_icache_vci_paddr.read() & mask) == (paddr & mask)) ) // matching
+
+            break;
+        }
+
+        // Match between MISS address and CC address
+        if (r_cc_receive_icache_req.read() and
+          ((r_icache_fsm_save.read() == ICACHE_MISS_SELECT  )  or
+           (r_icache_fsm_save.read() == ICACHE_MISS_WAIT    )  or
+           (r_icache_fsm_save.read() == ICACHE_MISS_DIR_UPDT)) and
+          ((r_icache_vci_paddr.read() & mask) == (paddr & mask)) ) // matching
         {
             // signaling the matching
@@ -1873,4 +1877,5 @@
                 r_icache_fsm        = ICACHE_CC_UPDT;
                 r_icache_cc_word    = r_cc_receive_word_idx.read();
+
                 // just pop the fifo , don't write in icache
                 r_icache_cc_need_write = false;
@@ -1890,53 +1895,55 @@
 }
 #endif
-        }
-        else  								                            // no match
-        {
-            int	        state = 0;
-            size_t 	    way = 0;
-            size_t 	    set = 0;
-            size_t 	    word = 0;
+            break;
+        }
+
+        // CC request handler
+
+        int	        state = 0;
+        size_t 	    way = 0;
+        size_t 	    set = 0;
+        size_t 	    word = 0;
 
 #ifdef INSTRUMENTATION
 m_cpt_icache_dir_read++;
 #endif
-            r_icache.read_dir(paddr,
-                              &state,
-                              &way,
-                              &set,
-                              &word);
-
-            r_icache_cc_way = way;
-            r_icache_cc_set = set;
-
-            if ( state == CACHE_SLOT_STATE_VALID)            // hit
-            {
-                // need to update the cache state
-                if (r_cc_receive_icache_type.read() == CC_TYPE_UPDT)  // hit update
-                {
-                    r_icache_cc_need_write = true;
-                    r_icache_fsm          = ICACHE_CC_UPDT;
-                    r_icache_cc_word      = r_cc_receive_word_idx.read();
-                }
-                else if ( r_cc_receive_icache_type.read() == CC_TYPE_INVAL ) // hit inval
-                {
-                    r_icache_fsm          = ICACHE_CC_INVAL;
-                }
-            }
-            else                                      // miss
-            {
-                // multicast acknowledgement required in case of update
-                if(r_cc_receive_icache_type.read() == CC_TYPE_UPDT)
-                {
-                    r_icache_fsm          = ICACHE_CC_UPDT;
-                    r_icache_cc_word      = r_cc_receive_word_idx.read();
-                    // just pop the fifo , don't write in icache
-                    r_icache_cc_need_write = false;
-                }
-                else // No response needed
-                {
-                    r_cc_receive_icache_req = false;
-                    r_icache_fsm          = r_icache_fsm_save.read();
-                }
+        r_icache.read_dir(paddr,
+                          &state,
+                          &way,
+                          &set,
+                          &word);
+
+        r_icache_cc_way = way;
+        r_icache_cc_set = set;
+
+        if ( state == CACHE_SLOT_STATE_VALID)            // hit
+        {
+            // need to update the cache state
+            if (r_cc_receive_icache_type.read() == CC_TYPE_UPDT)  // hit update
+            {
+                r_icache_cc_need_write = true;
+                r_icache_fsm           = ICACHE_CC_UPDT;
+                r_icache_cc_word       = r_cc_receive_word_idx.read();
+            }
+            else if ( r_cc_receive_icache_type.read() == CC_TYPE_INVAL ) // hit inval
+            {
+                r_icache_fsm           = ICACHE_CC_INVAL;
+            }
+        }
+        else                                      // miss
+        {
+            // multicast acknowledgement required in case of update
+            if(r_cc_receive_icache_type.read() == CC_TYPE_UPDT)
+            {
+                r_icache_fsm           = ICACHE_CC_UPDT;
+                r_icache_cc_word       = r_cc_receive_word_idx.read();
+
+                // just pop the fifo , don't write in icache
+                r_icache_cc_need_write = false;
+            }
+            else // No response needed
+            {
+                r_cc_receive_icache_req = false;
+                r_icache_fsm            = r_icache_fsm_save.read();
             }
         }
@@ -1946,42 +1953,74 @@
     case ICACHE_CC_INVAL:  	// hit inval : switch slot to ZOMBI state
     {
+        // return to CC_CHECK if pending request to CC_SEND
+        // to handle possible pending CLACK and avoid deadlock
+        if (r_icache_cc_send_req.read())
+        {
+            r_icache_fsm = ICACHE_CC_CHECK;
+            break; 
+        } 
+
+#ifdef INSTRUMENTATION
+m_cpt_icache_dir_read++;
+#endif
+
+        // Switch slot state to ZOMBI and send CLEANUP command 
+        r_icache.write_dir( 0,
+                            r_icache_cc_way.read(),
+                            r_icache_cc_set.read(),
+                            CACHE_SLOT_STATE_ZOMBI );
+
+        // coherence request completed
+        r_icache_cc_send_req   = true;
+        r_icache_cc_send_nline = r_cc_receive_icache_nline.read();
+        r_icache_cc_send_way   = r_icache_cc_way.read();
+        r_icache_cc_send_type  = CC_TYPE_CLEANUP;
+
+        r_icache_fsm           = r_icache_fsm_save.read();
 
 #if DEBUG_ICACHE
 if ( m_debug_activated )
 {
-    std::cout << "  <PROC " << name()
-              << " ICACHE_CC_INVAL> slot returns to zombi state"
-              << " set = " << r_icache_cc_set.read()
-              << " / way = " << r_icache_cc_way.read() << std::endl;
+std::cout << "  <PROC " << name()
+          << " ICACHE_CC_INVAL> slot returns to ZOMBI state"
+          << " set = " << r_icache_cc_set.read()
+          << " / way = " << r_icache_cc_way.read() << std::endl;
 }
 #endif
 
-#ifdef INSTRUMENTATION
-m_cpt_icache_dir_read++;
-#endif
-        // send a cleanup request to cc_send_fsm
-        if(not r_icache_cc_send_req.read()) // cc_send is available
-        {
-            r_icache.write_dir( 0,
-	                            r_icache_cc_way.read(),
-	                            r_icache_cc_set.read(),
-                                CACHE_SLOT_STATE_ZOMBI );
-            // coherence request completed
-            r_icache_cc_send_req = true;
-            r_icache_cc_send_nline = r_cc_receive_icache_nline.read();
-            r_icache_cc_send_way   = r_icache_cc_way.read();
-            r_icache_cc_send_type  = CC_TYPE_CLEANUP;
-
-            r_icache_fsm          = r_icache_fsm_save.read();
-        }
-        //else go to CC_CHECK
-        else
-            r_icache_fsm          = ICACHE_CC_CHECK;
         break;
-        
     }
     ////////////////////
     case ICACHE_CC_UPDT:	// hit update : write one word per cycle
     {
+
+        // if pending request to CC_SEND or if the CC_UPDT data is not ready to
+        // handle possible pending CLACK and avoid deadlock
+        if ( r_icache_cc_send_req.read() )
+        {
+            r_icache_fsm = ICACHE_CC_CHECK;
+            break;
+        }
+
+        if ( not r_cc_receive_updt_fifo_be.rok() ) break;
+
+
+        size_t  word  = r_icache_cc_word.read();
+        size_t  way   = r_icache_cc_way.read();
+        size_t  set   = r_icache_cc_set.read();
+
+        if (r_icache_cc_need_write.read())
+        {
+            r_icache.write( way,
+                            set,
+                            word,
+                            r_cc_receive_updt_fifo_data.read(),
+                            r_cc_receive_updt_fifo_be.read() );
+
+            r_icache_cc_word = word+1;
+
+#ifdef INSTRUMENTATION
+m_cpt_icache_data_write++;
+#endif
 
 #if DEBUG_ICACHE
@@ -1995,43 +2034,24 @@
 }
 #endif
-
-#ifdef INSTRUMENTATION
-m_cpt_icache_data_write++;
-#endif
-        size_t  word  = r_icache_cc_word.read();
-        size_t  way   = r_icache_cc_way.read();
-        size_t  set   = r_icache_cc_set.read();
-
-        if( (not r_icache_cc_send_req.read()) and r_cc_receive_updt_fifo_be.rok() ) // cc_send is available
-        {
-            if (r_icache_cc_need_write.read())
-            {
-                r_icache.write( way,
-                                set,
-                                word,
-                                r_cc_receive_updt_fifo_data.read(),
-                                r_cc_receive_updt_fifo_be.read() );
-
-                r_icache_cc_word = word+1;
-            }
-            if ( r_cc_receive_updt_fifo_eop.read() )	// last word
-            {
-                // no need to write in the cache anymore
-                r_icache_cc_need_write = false;
-                // coherence request completed
-                r_cc_receive_icache_req = false;
-                // request multicast acknowledgement
-                r_icache_cc_send_req = true;
-                r_icache_cc_send_nline = r_cc_receive_icache_nline.read();
-                r_icache_cc_send_updt_tab_idx = r_cc_receive_icache_updt_tab_idx.read();
-                r_icache_cc_send_type = CC_TYPE_MULTI_ACK;
-
-                r_icache_fsm          = r_icache_fsm_save.read();
-            }
-            //consume fifo if not eop
-            cc_receive_updt_fifo_get  = true;
-        }
-        else
-            r_icache_fsm            = ICACHE_CC_CHECK;
+        }
+
+        if ( r_cc_receive_updt_fifo_eop.read() )	// last word
+        {
+            // no need to write in the cache anymore
+            r_icache_cc_need_write        = false;
+
+            // coherence request completed
+            r_cc_receive_icache_req       = false;
+
+            // request multicast acknowledgement
+            r_icache_cc_send_req          = true;
+            r_icache_cc_send_nline        = r_cc_receive_icache_nline.read();
+            r_icache_cc_send_updt_tab_idx = r_cc_receive_icache_updt_tab_idx.read();
+            r_icache_cc_send_type         = CC_TYPE_MULTI_ACK;
+
+            r_icache_fsm                  = r_icache_fsm_save.read();
+        }
+        //consume fifo if not eop
+        cc_receive_updt_fifo_get  = true;
 
         break;
@@ -4435,5 +4455,5 @@
         size_t   way;
         size_t   set;
-        size_t   word;	// unused
+        size_t   word; // unused
         int      state;
 
@@ -4504,5 +4524,5 @@
         }
 
-        if ( r_vci_rsp_data_error.read() )	// bus error
+        if ( r_vci_rsp_data_error.read() )      // bus error
         {
             std::cout << "BUS ERROR in DCACHE_DIRTY_WAIT state" << std::endl;
@@ -4510,5 +4530,5 @@
             exit(0);
         }
-        else if ( r_vci_rsp_fifo_dcache.rok() )	// response available
+        else if ( r_vci_rsp_fifo_dcache.rok() ) // response available
         {
             vci_rsp_fifo_dcache_get = true;
@@ -4554,10 +4574,10 @@
 #endif
 
+        // CLACK handler
+        // We switch the directory slot to EMPTY state
+        // and reset r_dcache_miss_clack if the cleanup ack
+        // is matching a pending miss.
         if ( r_dcache_clack_req.read() )
-                            // We switch the directory slot to EMPTY state
-                            // and reset r_icache_miss_clack if the cleanup ack
-                            // is matching a pending miss.
-        {
-
+        {
             if ( m_dreq.valid ) m_cost_data_miss_frz++;
 
@@ -4572,7 +4592,14 @@
             if ( (r_dcache_miss_set.read() == r_dcache_clack_set.read()) and
                  (r_dcache_miss_way.read() == r_dcache_clack_way.read()) )
+            {
                   r_dcache_miss_clack = false;
+            }
 
             r_dcache_clack_req = false;
+
+            // return to cc_save state if no pending CC request
+            if ( not r_cc_receive_dcache_req.read() )
+                r_dcache_fsm = r_dcache_fsm_cc_save.read() ;
+
 #if DEBUG_DCACHE
 if ( m_debug_activated )
@@ -4584,14 +4611,13 @@
 }
 #endif
-            if ( not r_cc_receive_dcache_req.read() )
-                r_dcache_fsm = r_dcache_fsm_cc_save.read() ;
-
-            break;
-        }
-        else if( r_cc_receive_dcache_req.read() and 
-                 ((r_dcache_fsm_cc_save == DCACHE_MISS_SELECT) or
-                 (r_dcache_fsm_cc_save == DCACHE_MISS_WAIT) or
-                 (r_dcache_fsm_cc_save == DCACHE_MISS_DIR_UPDT)) and
-                 ((r_dcache_vci_paddr.read() & mask) == (paddr & mask)) ) // matching
+            break;
+        }
+        
+        // Match between MISS address and CC address
+        if (r_cc_receive_dcache_req.read() and 
+          ((r_dcache_fsm_cc_save == DCACHE_MISS_SELECT  )  or
+           (r_dcache_fsm_cc_save == DCACHE_MISS_WAIT    )  or
+           (r_dcache_fsm_cc_save == DCACHE_MISS_DIR_UPDT)) and
+          ((r_dcache_vci_paddr.read() & mask) == (paddr & mask))) // matching
         {
             // signaling matching
@@ -4604,4 +4630,5 @@
                 r_dcache_fsm        = DCACHE_CC_UPDT;
                 r_dcache_cc_word    = r_cc_receive_word_idx.read();
+
                 // just pop the fifo , don't write in icache
                 r_dcache_cc_need_write = false;
@@ -4623,54 +4650,57 @@
 #endif
 
-        }
-        else                                                    // no match
-	    {
-            int        state = 0;
-            size_t 	   way = 0;
-            size_t 	   set = 0;
-            size_t	   word = 0;
+            break;
+        }
+
+        // CC request handler
+       
+        int    state = 0;
+        size_t way   = 0;
+        size_t set   = 0;
+        size_t word  = 0;
 
 #ifdef INSTRUMENTATION
 m_cpt_dcache_dir_read++;
 #endif
-            r_dcache.read_dir( paddr,
-                               &state,
-                               &way,
-                               &set,
-                               &word );	// unused
-
-            r_dcache_cc_way = way;
-            r_dcache_cc_set = set;
-
-            if ( state == CACHE_SLOT_STATE_VALID)            // hit
-            {
-                // need to update the cache state
-                if (r_cc_receive_dcache_type.read() == CC_TYPE_UPDT)  // hit update
-                {
-                    r_dcache_cc_need_write = true;
-                    r_dcache_fsm          = DCACHE_CC_UPDT;
-                    r_dcache_cc_word      = r_cc_receive_word_idx.read();
-                }
-                else if ( r_cc_receive_dcache_type.read() == CC_TYPE_INVAL )    // hit inval
-                {
-                    r_dcache_fsm          = DCACHE_CC_INVAL;
-                }
-            }
-            else                                      // miss
-            {
-                // multicast acknowledgement required in case of update
-                if(r_cc_receive_dcache_type.read() == CC_TYPE_UPDT)
-                {
-                    r_dcache_fsm          = DCACHE_CC_UPDT;
-                    r_dcache_cc_word      = r_cc_receive_word_idx.read();
-                    // just pop the fifo , don't write in icache
-                    r_dcache_cc_need_write = false;
-                }
-                else // No response needed
-                {
-                    r_cc_receive_dcache_req = false;
-                    r_dcache_fsm          = r_dcache_fsm_cc_save.read();
-                }
-            }
+        r_dcache.read_dir( paddr,
+                           &state,
+                           &way,
+                           &set,
+                           &word ); // unused
+
+        r_dcache_cc_way = way;
+        r_dcache_cc_set = set;
+
+        if ( state == CACHE_SLOT_STATE_VALID) // hit
+        {
+            // need to update the cache state
+            if (r_cc_receive_dcache_type.read() == CC_TYPE_UPDT) // hit update
+            {
+                r_dcache_cc_need_write = true;
+                r_dcache_fsm           = DCACHE_CC_UPDT;
+                r_dcache_cc_word       = r_cc_receive_word_idx.read();
+            }
+            else if ( r_cc_receive_dcache_type.read() == CC_TYPE_INVAL ) // hit inval
+            {
+                r_dcache_fsm           = DCACHE_CC_INVAL;
+            }
+        }
+        else                                  // miss
+        {
+            // multicast acknowledgement required in case of update
+            if(r_cc_receive_dcache_type.read() == CC_TYPE_UPDT)
+            {
+                r_dcache_fsm           = DCACHE_CC_UPDT;
+                r_dcache_cc_word       = r_cc_receive_word_idx.read();
+
+                // just pop the fifo , don't write in icache
+                r_dcache_cc_need_write = false;
+            }
+            else // No response needed
+            {
+                r_cc_receive_dcache_req = false;
+                r_dcache_fsm            = r_dcache_fsm_cc_save.read();
+            }
+        }
 
 #if DEBUG_DCACHE
@@ -4684,15 +4714,16 @@
 }
 #endif
-        }
+
         break;
     }
     /////////////////////
-    case DCACHE_CC_INVAL:   	// hit inval: switch slot to EMPTY state,
-                                // after possible invalidation of copies in TLBs
-    {
-        size_t	 way    = r_dcache_cc_way.read();
-        size_t	 set    = r_dcache_cc_set.read();
-
-        if ( r_dcache_in_tlb[way*m_dcache_sets+set] ) 			// selective TLB inval
+    case DCACHE_CC_INVAL: // hit inval: switch slot to ZOMBI state and send a
+                          // CLEANUP after possible invalidation of copies in
+                          // TLBs
+    {
+        size_t way    = r_dcache_cc_way.read();
+        size_t set    = r_dcache_cc_set.read();
+
+        if ( r_dcache_in_tlb[way*m_dcache_sets+set] )       // selective TLB inval
         {
             r_dcache_in_tlb[way*m_dcache_sets+set] = false;
@@ -4704,5 +4735,5 @@
         }
 
-        if ( r_dcache_contains_ptd[way*m_dcache_sets+set] ) 	// TLB flush
+        if ( r_dcache_contains_ptd[way*m_dcache_sets+set] ) // TLB flush
         {
             r_itlb.reset();
@@ -4718,11 +4749,26 @@
 #endif
         }
-        
-        if ( not r_dcache_cc_send_req.read() ) // cc_send is available
-        {
-            r_dcache.write_dir( 0,
-                                way,
-                                set,
-                                CACHE_SLOT_STATE_ZOMBI );
+
+        // return to CC_CHECK if pending request to CC_SEND
+        // to handle possible pending CLACK and avoid deadlock
+        if ( r_dcache_cc_send_req.read() )
+        {
+            r_dcache_fsm = DCACHE_CC_CHECK;
+            break;
+        }
+
+        // Switch slot state to ZOMBI and send CLEANUP command 
+        r_dcache.write_dir( 0,
+                            way,
+                            set,
+                            CACHE_SLOT_STATE_ZOMBI );
+
+        // coherence request completed
+        r_cc_receive_dcache_req = false;
+        r_dcache_cc_send_req    = true;
+        r_dcache_cc_send_nline  = r_cc_receive_dcache_nline.read();
+        r_dcache_cc_send_way    = r_dcache_cc_way.read();
+        r_dcache_cc_send_type   = CC_TYPE_CLEANUP;
+        r_dcache_fsm            = r_dcache_fsm_cc_save.read();
 
 #if DEBUG_DCACHE
@@ -4730,43 +4776,31 @@
 {
     std::cout << "  <PROC " << name()
-              << " DCACHE_CC_INVAL> Switch slot to EMPTY state:" << std::dec
-              << " / WAY = " << way
-              << " / SET = " << set << std::endl;
+        << " DCACHE_CC_INVAL> Switch slot to EMPTY state:" << std::dec
+        << " / WAY = " << way
+        << " / SET = " << set << std::endl;
 }
 #endif
-            // coherence request completed
-            r_cc_receive_dcache_req = false;
-            r_dcache_cc_send_req = true;
-            r_dcache_cc_send_nline = r_cc_receive_dcache_nline.read();
-            r_dcache_cc_send_way   = r_dcache_cc_way.read();
-            r_dcache_cc_send_type  = CC_TYPE_CLEANUP;
-
-            r_dcache_fsm          = r_dcache_fsm_cc_save.read();
-        }
-        //else go to DCACHE_CC_CHECK 
-        else
-            r_dcache_fsm          = DCACHE_CC_CHECK;
-
         break;
     }
     ///////////////////
-    case DCACHE_CC_UPDT:    	// hit update: write one word per cycle,
+    case DCACHE_CC_UPDT:        // hit update: write one word per cycle,
                                 // after possible invalidation of copies in TLBs
     {
-        size_t	 word       = r_dcache_cc_word.read();
-        size_t	 way        = r_dcache_cc_way.read();
-        size_t	 set        = r_dcache_cc_set.read();
-
-        if ( r_dcache_in_tlb[way*m_dcache_sets+set] ) 			// selective TLB inval
+        size_t word       = r_dcache_cc_word.read();
+        size_t way        = r_dcache_cc_way.read();
+        size_t set        = r_dcache_cc_set.read();
+
+        if ( r_dcache_in_tlb[way*m_dcache_sets+set] )       // selective TLB inval
         {
             r_dcache_in_tlb[way*m_dcache_sets+set] = false;
-            r_dcache_tlb_inval_line  = r_cc_receive_dcache_nline.read();
-            r_dcache_tlb_inval_set   = 0;
-            r_dcache_fsm_scan_save   = r_dcache_fsm.read();
-            r_dcache_fsm             = DCACHE_INVAL_TLB_SCAN;
-            break;
-        }
-
-        if ( r_dcache_contains_ptd[way*m_dcache_sets+set] ) 	// TLB flush
+            r_dcache_tlb_inval_line = r_cc_receive_dcache_nline.read();
+            r_dcache_tlb_inval_set  = 0;
+            r_dcache_fsm_scan_save  = r_dcache_fsm.read();
+            r_dcache_fsm            = DCACHE_INVAL_TLB_SCAN;
+
+            break;
+        }
+
+        if ( r_dcache_contains_ptd[way*m_dcache_sets+set] ) // TLB flush
         {
             r_itlb.reset();
@@ -4783,19 +4817,27 @@
         }
 
-        if ( (not r_dcache_cc_send_req.read()) and r_cc_receive_updt_fifo_be.rok())
-        {
-            if (r_dcache_cc_need_write.read())
-            {
-            
+        // if pending request to CC_SEND or if the CC_UPDT data is not ready to
+        // handle possible pending CLACK and avoid deadlock
+        if ( r_dcache_cc_send_req.read() )
+        {
+            r_dcache_fsm = DCACHE_CC_CHECK;
+            break;
+        }
+        
+        if ( not r_cc_receive_updt_fifo_be.rok() ) break;
+
+        if (r_dcache_cc_need_write.read())
+        {
+        
 #ifdef INSTRUMENTATION
 m_cpt_dcache_data_write++;
 #endif
-                r_dcache.write( way,
-                                set,
-                                word,
-                                r_cc_receive_updt_fifo_data.read(),
-                                r_cc_receive_updt_fifo_be.read() );
-
-                r_dcache_cc_word = word + 1;
+            r_dcache.write( way,
+                            set,
+                            word,
+                            r_cc_receive_updt_fifo_data.read(),
+                            r_cc_receive_updt_fifo_be.read() );
+
+            r_dcache_cc_word = word + 1;
 
 #if DEBUG_DCACHE
@@ -4810,28 +4852,25 @@
 }
 #endif
-            }
-
-            if ( r_cc_receive_updt_fifo_eop.read() )	// last word
-            {
-                // no need to write in the cache anymore
-                r_dcache_cc_need_write = false;
-
-                // coherence request completed
-                r_cc_receive_dcache_req = false;
-
-                // request multicast acknowledgement
-                r_dcache_cc_send_req = 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          = r_dcache_fsm_cc_save.read();
-            }
-
-            //consume fifo if not eop
-            cc_receive_updt_fifo_get  = true;
-        }
-        else
-            r_dcache_fsm        = DCACHE_CC_CHECK;
+        }
+
+        if ( r_cc_receive_updt_fifo_eop.read() )  // last word
+        {
+            // no need to write in the cache anymore
+            r_dcache_cc_need_write = false;
+
+            // coherence request completed
+            r_cc_receive_dcache_req = false;
+
+            // request multicast acknowledgement
+            r_dcache_cc_send_req          = 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                  = r_dcache_fsm_cc_save.read();
+        }
+
+        //consume fifo if not eop
+        cc_receive_updt_fifo_get  = true;
 
         break;
