Index: trunk/modules/vci_cc_vcache_wrapper/caba/source/src/vci_cc_vcache_wrapper.cpp
===================================================================
--- trunk/modules/vci_cc_vcache_wrapper/caba/source/src/vci_cc_vcache_wrapper.cpp	(revision 484)
+++ trunk/modules/vci_cc_vcache_wrapper/caba/source/src/vci_cc_vcache_wrapper.cpp	(revision 487)
@@ -277,4 +277,7 @@
       r_icache_tlb_rsp_error("r_icache_tlb_rsp_error"),
 
+      r_icache_cleanup_victim_req("r_icache_cleanup_victim_req"),
+      r_icache_cleanup_victim_nline("r_icache_cleanup_victim_nline"),
+
       r_icache_cc_send_req("r_icache_cc_send_req"),
       r_icache_cc_send_type("r_icache_cc_send_type"),
@@ -349,4 +352,7 @@
       r_dcache_xtn_opcode("r_dcache_xtn_opcode"),
 
+      r_dcache_cleanup_victim_req("r_dcache_cleanup_victim_req"),
+      r_dcache_cleanup_victim_nline("r_dcache_cleanup_victim_nline"),
+    
       r_dcache_cc_send_req("r_dcache_cc_send_req"),
       r_dcache_cc_send_type("r_dcache_cc_send_type"),
@@ -755,4 +761,5 @@
         // No request from ICACHE_FSM to CC_SEND FSM
         r_icache_cc_send_req       = false;
+        r_icache_cleanup_victim_req = false;
 
         r_icache_clack_req         = false;
@@ -777,4 +784,5 @@
         // No request from DCACHE FSM to CC_SEND FSM
         r_dcache_cc_send_req       = false;
+        r_dcache_cleanup_victim_req = false;
 
         r_dcache_clack_req         = false;
@@ -1508,8 +1516,11 @@
     ////////////////////////
     case ICACHE_MISS_SELECT:       // Try to select a slot in associative set,
-                                   // if previous cleanup has been sent.
                                    // Waiting in this state if no slot available.
-                                   // Set the r_icache_cleanup_req flip-flop
-                                   // and the r_icache_miss_clack flip-flop,
+                                   // If a victim slot has been choosen and the r_icache_cc_send_req is false, 
+                                   // we send the cleanup request in this state. 
+                                   // If not, a r_icache_cleanup_victim_req flip-flop is
+                                   // utilized for saving this cleanup request, and it will be sent later
+                                   // in state ICACHE_MISS_WAIT or ICACHE_MISS_UPDT_DIR. 
+                                   // The r_icache_miss_clack flip-flop is set
                                    // when a cleanup is required
     {
@@ -1532,40 +1543,51 @@
         }
 
-        if ( not r_icache_cc_send_req.read() ) // wait for previous cc_send request to be sent
-        {
-            bool        found;
-            bool        cleanup;
-            size_t  	way;
-            size_t  	set;
-            paddr_t 	victim;
+
+        bool        found;
+        bool        cleanup;
+        size_t  	way;
+        size_t  	set;
+        paddr_t 	victim;
 
 #ifdef INSTRUMENTATION
 m_cpt_icache_dir_read++;
 #endif
-            r_icache.read_select(r_icache_vci_paddr.read(),
-                                 &victim,
-                                 &way,
-                                 &set,
-                                 &found,
-                                 &cleanup );
-            if ( found )
-            {
-                r_icache_miss_way     = way;
-                r_icache_miss_set     = set;
-
-                if ( cleanup )
+        r_icache.read_select(r_icache_vci_paddr.read(),
+                             &victim,
+                             &way,
+                             &set,
+                             &found,
+                             &cleanup );
+        if ( not found )
+        {
+            break;
+        }
+        else
+        {
+            r_icache_miss_way     = way;
+            r_icache_miss_set     = set;
+
+            if ( cleanup )
+            {
+                if ( not r_icache_cc_send_req.read() )
                 {
-                    r_icache_fsm           = ICACHE_MISS_CLEAN;
-                    r_icache_miss_clack    = true;
-                    // request cleanup
-                    r_icache_cc_send_req   = true;
-                    r_icache_cc_send_nline = victim;
-                    r_icache_cc_send_way   = way;
-                    r_icache_cc_send_type  = CC_TYPE_CLEANUP;
+                    r_icache_cc_send_req    = true;
+                    r_icache_cc_send_nline  = victim;
+                    r_icache_cc_send_way    = way;
+                    r_icache_cc_send_type   = CC_TYPE_CLEANUP;    
                 }
                 else
                 {
-                    r_icache_fsm          = ICACHE_MISS_WAIT;
+                    r_icache_cleanup_victim_req   = true;
+                    r_icache_cleanup_victim_nline = victim;
                 }
+
+                r_icache_miss_clack           = true;
+                r_icache_fsm                  = ICACHE_MISS_CLEAN;
+            }
+            else
+            {
+                r_icache_fsm          = ICACHE_MISS_WAIT;
+            }
 
 #if DEBUG_ICACHE
@@ -1580,5 +1602,4 @@
 }
 #endif
-            }
         }
         break;
@@ -1620,7 +1641,17 @@
             break;
         }
+        
+        // send cleanup victim request
+        if ( r_icache_cleanup_victim_req.read() and not r_icache_cc_send_req.read() )
+        {
+            r_icache_cc_send_req        = true;
+            r_icache_cc_send_nline      = r_icache_cleanup_victim_nline;
+            r_icache_cc_send_way        = r_icache_miss_way;
+            r_icache_cc_send_type       = CC_TYPE_CLEANUP; 
+            r_icache_cleanup_victim_req = false;
+        }   
 
         // coherence interrupt
-        if ( r_cc_receive_icache_req.read() and not r_icache_cc_send_req.read())
+        if ( r_cc_receive_icache_req.read() and not r_icache_cc_send_req.read() and not r_icache_cleanup_victim_req.read() )
         {
             r_icache_fsm = ICACHE_CC_CHECK;
@@ -1700,6 +1731,16 @@
         }
 
+        // send cleanup victim request
+        if ( r_icache_cleanup_victim_req.read() and not r_icache_cc_send_req.read() )
+        {
+            r_icache_cc_send_req        = true;
+            r_icache_cc_send_nline      = r_icache_cleanup_victim_nline;
+            r_icache_cc_send_way        = r_icache_miss_way;
+            r_icache_cc_send_type       = CC_TYPE_CLEANUP; 
+            r_icache_cleanup_victim_req = false;
+        }   
+
         // coherence interrupt
-        if ( r_cc_receive_icache_req.read() and not r_icache_cc_send_req.read())
+        if ( r_cc_receive_icache_req.read() and not r_icache_cc_send_req.read() and not r_icache_cleanup_victim_req.read() )
         {
             r_icache_fsm = ICACHE_CC_CHECK;
@@ -1860,7 +1901,7 @@
         }
 
+        assert ( not r_icache_cc_send_req.read() and "CC_SEND must be available in ICACHE_CC_CHECK");
+
         // Match between MISS address and CC address
-        // note: In the same cycle we can handle a CLACK and a MISS match
-        // because the CLACK access the directory but the MISS match dont.
         if (r_cc_receive_icache_req.read() and
           ((r_icache_fsm_save.read() == ICACHE_MISS_SELECT  )  or
@@ -1897,6 +1938,4 @@
 #endif
         }
-
-        assert ( not r_icache_cc_send_req.read() and "CC_SEND must be available in ICACHE_CC_CHECK");
 
         // CC request handler
@@ -3823,4 +3862,6 @@
         {
             paddr = (paddr_t)r_dcache_save_wdata.read();
+            if (vci_param::N > 32) 
+                paddr = paddr | ((paddr_t)(r_dcache_paddr_ext.read()) << 32);
             hit   = true;
         }
@@ -3964,10 +4005,13 @@
     }
     ////////////////////////
-    case DCACHE_MISS_SELECT:   // Try to select a slot in associative set
-                               // if previous cleanup has been sent.
-                               // Waiting in this state if no slot available
-                               // Set the r_dcache_cleanup_req flip-flop
-                               // and the r_dcache_miss_clack flip-flop
-                               // when a cleanup is required
+    case DCACHE_MISS_SELECT:       // Try to select a slot in associative set,
+                                   // Waiting in this state if no slot available.
+                                   // If a victim slot has been choosen and the r_icache_cc_send_req is false, 
+                                   // we send the cleanup request in this state. 
+                                   // If not, a r_icache_cleanup_victim_req flip-flop is
+                                   // utilized for saving this cleanup request, and it will be sent later
+                                   // in state ICACHE_MISS_WAIT or ICACHE_MISS_UPDT_DIR. 
+                                   // The r_icache_miss_clack flip-flop is set
+                                   // when a cleanup is required
     {
         if ( m_dreq.valid) m_cost_data_miss_frz++;
@@ -3989,41 +4033,52 @@
         }
 
-        if ( not r_dcache_cc_send_req.read() ) // blocked until previous cc_send request is sent
-        {
-            bool     found = false;
-            bool     cleanup = false;
-            size_t   way = 0;
-            size_t   set = 0;
-            paddr_t  victim = 0;
+        bool     found = false;
+        bool     cleanup = false;
+        size_t   way = 0;
+        size_t   set = 0;
+        paddr_t  victim = 0;
 
 #ifdef INSTRUMENTATION
 m_cpt_dcache_dir_read++;
 #endif
-            r_dcache.read_select( r_dcache_save_paddr.read(),
-                                  &victim,
-                                  &way,
-                                  &set,
-                                  &found,
-                                  &cleanup );
-
-            if ( found )
-            {
-                r_dcache_miss_way = way;
-                r_dcache_miss_set = set;
-
-                if ( cleanup )
+        r_dcache.read_select( r_dcache_save_paddr.read(),
+                              &victim,
+                              &way,
+                              &set,
+                              &found,
+                              &cleanup );
+
+        if (  not found )
+        {
+            break;
+        }
+        else
+        {
+            r_dcache_miss_way = way;
+            r_dcache_miss_set = set;
+
+            if ( cleanup )
+            {
+                if ( not r_dcache_cc_send_req.read() )
                 {
-                    r_dcache_miss_clack   = true;
-                    r_dcache_fsm          = DCACHE_MISS_CLEAN;
-                    // request cleanup
-                    r_dcache_cc_send_req   = true;
-                    r_dcache_cc_send_nline = victim;
-                    r_dcache_cc_send_way   = way;
-                    r_dcache_cc_send_type  = CC_TYPE_CLEANUP;
+                    r_dcache_cc_send_req    = true;
+                    r_dcache_cc_send_nline  = victim;
+                    r_dcache_cc_send_way    = way;
+                    r_dcache_cc_send_type   = CC_TYPE_CLEANUP;    
+
                 }
                 else
                 {
-                    r_dcache_fsm          = DCACHE_MISS_WAIT;
+                    r_dcache_cleanup_victim_req   = true;
+                    r_dcache_cleanup_victim_nline = victim;
                 }
+
+                r_dcache_miss_clack           = true;
+                r_dcache_fsm                  = DCACHE_MISS_CLEAN;
+            }
+            else
+            {
+                r_dcache_fsm          = DCACHE_MISS_WAIT;
+            }
 
 #if DEBUG_DCACHE
@@ -4039,6 +4094,5 @@
 }
 #endif
-            } // end found
-        }
+        } // end found
         break;
     }
@@ -4105,6 +4159,16 @@
         }
 
+        // send cleanup victim request
+        if ( r_dcache_cleanup_victim_req.read() and not r_dcache_cc_send_req.read() )
+        {
+            r_dcache_cc_send_req        = true;
+            r_dcache_cc_send_nline      = r_dcache_cleanup_victim_nline;
+            r_dcache_cc_send_way        = r_dcache_miss_way;
+            r_dcache_cc_send_type       = CC_TYPE_CLEANUP; 
+            r_dcache_cleanup_victim_req = false;
+        }   
+
         // coherence request (from CC_RECEIVE FSM)
-        if ( r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read())
+        if ( r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read() and not r_dcache_cleanup_victim_req.read())
         {
             r_dcache_fsm = DCACHE_CC_CHECK;
@@ -4228,6 +4292,16 @@
         }
 
+        // send cleanup victim request
+        if ( r_dcache_cleanup_victim_req.read() and not r_dcache_cc_send_req.read() )
+        {
+            r_dcache_cc_send_req        = true;
+            r_dcache_cc_send_nline      = r_dcache_cleanup_victim_nline;
+            r_dcache_cc_send_way        = r_dcache_miss_way;
+            r_dcache_cc_send_type       = CC_TYPE_CLEANUP; 
+            r_dcache_cleanup_victim_req = false;
+        }   
+
         // coherence request (from CC_RECEIVE FSM)
-        if ( r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read())
+        if ( r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read() and not r_dcache_cleanup_victim_req.read() )
         {
             r_dcache_fsm = DCACHE_CC_CHECK;
@@ -4604,8 +4678,7 @@
         }
 
-        
+        assert ( not r_dcache_cc_send_req.read() and "CC_SEND must be available in DCACHE_CC_CHECK" );
+
         // Match between MISS address and CC address
-        // note: In the same cycle we can handle a CLACK and a MISS match
-        // because the CLACK access the directory but the MISS match dont.
         if (r_cc_receive_dcache_req.read() and 
           ((r_dcache_fsm_cc_save == DCACHE_MISS_SELECT  )  or
@@ -4643,7 +4716,4 @@
 #endif
         }
-
-
-        assert ( not r_dcache_cc_send_req.read() and "CC_SEND must be available in DCACHE_CC_CHECK" );
 
         // CC request handler
