Index: branches/ODCCP/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp
===================================================================
--- trunk/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp	(revision 449)
+++ branches/ODCCP/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp	(revision 460)
@@ -217,8 +217,10 @@
   "IXR_CMD_CAS_IDLE",
   "IXR_CMD_XRAM_IDLE",
+  "IXR_CMD_CLEANUP_IDLE",
   "IXR_CMD_READ",
   "IXR_CMD_WRITE",
   "IXR_CMD_CAS",
-  "IXR_CMD_XRAM"
+  "IXR_CMD_XRAM",
+  "IXR_CMD_CLEANUP_DATA"
 };
 const char *cas_fsm_str[] =
@@ -250,4 +252,5 @@
   "CLEANUP_IDLE",
   "CLEANUP_GET_NLINE",
+  "CLEANUP_GET_DATA",
   "CLEANUP_DIR_REQ",
   "CLEANUP_DIR_LOCK",
@@ -263,4 +266,6 @@
   "CLEANUP_WRITE_RSP",
   "CLEANUP_CONFIG_ACK",
+  "CLEANUP_IXR_REQ",
+  "CLEANUP_WAIT",
   "CLEANUP_SEND_CLACK"
 };
@@ -280,5 +285,6 @@
   "ALLOC_TRT_CAS",
   "ALLOC_TRT_XRAM_RSP",
-  "ALLOC_TRT_IXR_RSP"
+  "ALLOC_TRT_IXR_RSP",
+  "ALLOC_TRT_CLEANUP"
 };
 const char *alloc_upt_fsm_str[] =
@@ -333,4 +339,6 @@
   : soclib::caba::BaseModule(name),
 
+    m_monitor_ok(false),
+    
     p_clk( "p_clk" ),
     p_resetn( "p_resetn" ),
@@ -496,4 +504,5 @@
     // Allocation for IXR_RSP FSM
     r_ixr_rsp_to_xram_rsp_rok  = new sc_signal<bool>[m_trt_lines];
+    //r_ixr_rsp_to_xram_rsp_no_coherent  = new sc_signal<bool>[m_trt_lines];
 
     // Allocation for XRAM_RSP FSM
@@ -517,4 +526,8 @@
     r_cas_data                 = new sc_signal<data_t>[nwords];
     r_cas_rdata                = new sc_signal<data_t>[2];
+
+    // Allocation for ODCCP
+    r_cleanup_data             = new sc_signal<data_t>[nwords];
+    r_cleanup_to_ixr_cmd_data  = new sc_signal<data_t>[nwords];
 
     // Allocation for debug
@@ -631,4 +644,62 @@
 
 /////////////////////////////////////////
+tmpl(void) ::clear_stats()
+/////////////////////////////////////////
+{
+    m_cpt_cycles                  = 0;
+    m_cpt_read                    = 0;
+    m_cpt_read_miss               = 0;
+    m_cpt_write                   = 0;
+    m_cpt_write_miss              = 0;
+    m_cpt_write_cells             = 0;
+    m_cpt_write_dirty             = 0;
+    m_cpt_update                  = 0;
+    m_cpt_update_mult             = 0;
+    m_cpt_inval_brdcast           = 0;
+    m_cpt_inval                   = 0;
+    m_cpt_inval_mult              = 0;
+    m_cpt_cleanup                 = 0;
+    m_cpt_cleanup_data            = 0;
+    m_cpt_ll                      = 0;
+    m_cpt_sc                      = 0;
+    m_cpt_cas                     = 0;
+    m_cpt_trt_full                = 0;
+    m_cpt_trt_rb                  = 0;
+    m_cpt_dir_unused              = 0;
+    m_cpt_upt_unused              = 0;
+    m_cpt_heap_unused             = 0;
+    m_cpt_trt_unused              = 0;
+    m_cpt_read_fsm_n_dir_lock     = 0;
+    m_cpt_read_fsm_dir_lock       = 0;
+    m_cpt_read_fsm_dir_used       = 0;
+    m_cpt_read_fsm_trt_lock       = 0;
+    m_cpt_read_fsm_heap_lock      = 0;
+    m_cpt_write_fsm_dir_lock      = 0;
+    m_cpt_write_fsm_n_dir_lock    = 0;
+    m_cpt_write_fsm_upt_lock      = 0;
+    m_cpt_write_fsm_heap_lock     = 0;
+    m_cpt_write_fsm_dir_used      = 0;
+    m_cpt_write_fsm_trt_lock      = 0;
+    m_cpt_cas_fsm_n_dir_lock      = 0;
+    m_cpt_cas_fsm_dir_lock        = 0;
+    m_cpt_cas_fsm_upt_lock        = 0;
+    m_cpt_cas_fsm_heap_lock       = 0;
+    m_cpt_cas_fsm_trt_lock        = 0;
+    m_cpt_cas_fsm_dir_used        = 0;
+    m_cpt_xram_rsp_fsm_n_dir_lock = 0;
+    m_cpt_xram_rsp_fsm_dir_lock   = 0;
+    m_cpt_xram_rsp_fsm_trt_lock   = 0;
+    m_cpt_xram_rsp_fsm_upt_lock   = 0;
+    m_cpt_xram_rsp_fsm_heap_lock  = 0;
+    m_cpt_xram_rsp_fsm_dir_used   = 0;
+    m_cpt_cleanup_fsm_dir_lock    = 0;
+    m_cpt_cleanup_fsm_n_dir_lock  = 0;
+    m_cpt_cleanup_fsm_heap_lock   = 0;
+    m_cpt_cleanup_fsm_upt_lock    = 0;
+    m_cpt_cleanup_fsm_dir_used    = 0;
+    m_cpt_ixr_fsm_trt_lock        = 0;
+    m_cpt_multi_ack_fsm_upt_lock  = 0;
+}
+/////////////////////////////////////////
 tmpl(void) ::print_stats()
 /////////////////////////////////////////
@@ -637,24 +708,75 @@
   std::cout
       << "MEM_CACHE " << name() << " / Time = " << m_cpt_cycles << std::endl
-      << "- READ RATE            = " << (double) m_cpt_read/m_cpt_cycles << std::endl
-      << "- READ TOTAL           = " << m_cpt_read << std::endl
-      << "- READ MISS RATE       = " << (double) m_cpt_read_miss/m_cpt_read << std::endl
-      << "- WRITE RATE           = " << (double) m_cpt_write/m_cpt_cycles << std::endl
-      << "- WRITE TOTAL          = " << m_cpt_write << std::endl
-      << "- WRITE MISS RATE      = " << (double) m_cpt_write_miss/m_cpt_write << std::endl
-      << "- WRITE BURST LENGTH   = " << (double) m_cpt_write_cells/m_cpt_write << std::endl
-      << "- WRITE BURST TOTAL    = " << m_cpt_write_cells << std::endl
-      << "- REQUESTS TRT FULL    = " << m_cpt_trt_full << std::endl
-      << "- READ TRT BLOKED HIT  = " << m_cpt_trt_rb << std::endl
-      << "- UPDATE RATE          = " << (double) m_cpt_update/m_cpt_cycles << std::endl
-      << "- UPDATE ARITY         = " << (double) m_cpt_update_mult/m_cpt_update << std::endl
-      << "- INVAL MULTICAST RATE = " << (double)(m_cpt_inval-m_cpt_inval_brdcast) /m_cpt_cycles << std::endl
-      << "- INVAL MULTICAST ARITY= " << (double) m_cpt_inval_mult/ (m_cpt_inval-m_cpt_inval_brdcast) << std::endl
-      << "- INVAL BROADCAST RATE = " << (double) m_cpt_inval_brdcast/m_cpt_cycles << std::endl
-      << "- SAVE DIRTY RATE      = " << (double) m_cpt_write_dirty/m_cpt_cycles << std::endl
-      << "- CLEANUP RATE         = " << (double) m_cpt_cleanup/m_cpt_cycles << std::endl
-      << "- LL RATE              = " << (double) m_cpt_ll/m_cpt_cycles << std::endl
-      << "- SC RATE              = " << (double) m_cpt_sc/m_cpt_cycles << std::endl
-      << "- CAS RATE             = " << (double) m_cpt_cas/m_cpt_cycles << std::endl;
+      << "- READ RATE                              = " << (double) m_cpt_read/m_cpt_cycles << std::endl
+      << "- READ TOTAL                             = " << m_cpt_read << std::endl
+      << "- READ MISS RATE                         = " << (double) m_cpt_read_miss/m_cpt_read << std::endl
+      << "- WRITE RATE                             = " << (double) m_cpt_write/m_cpt_cycles << std::endl
+      << "- WRITE TOTAL                            = " << m_cpt_write << std::endl
+      << "- WRITE MISS RATE                        = " << (double) m_cpt_write_miss/m_cpt_write << std::endl
+      << "- WRITE BURST LENGTH                     = " << (double) m_cpt_write_cells/m_cpt_write << std::endl
+      << "- WRITE BURST TOTAL                      = " << m_cpt_write_cells << std::endl
+      << "- REQUESTS TRT FULL                      = " << m_cpt_trt_full << std::endl
+      << "- READ TRT BLOKED HIT                    = " << m_cpt_trt_rb << std::endl
+      << "- UPDATE RATE                            = " << (double) m_cpt_update/m_cpt_cycles << std::endl
+      << "- UPDATE ARITY                           = " << (double) m_cpt_update_mult/m_cpt_update << std::endl
+      << "- INVAL MULTICAST RATE                   = " << (double)(m_cpt_inval-m_cpt_inval_brdcast) /m_cpt_cycles << std::endl
+      << "- INVAL MULTICAST ARITY                  = " << (double) m_cpt_inval_mult/ (m_cpt_inval-m_cpt_inval_brdcast) << std::endl
+      << "- INVAL BROADCAST RATE                   = " << (double) m_cpt_inval_brdcast/m_cpt_cycles << std::endl
+      << "- SAVE DIRTY RATE                        = " << (double) m_cpt_write_dirty/m_cpt_cycles << std::endl
+      << "- CLEANUP RATE                           = " << (double) m_cpt_cleanup/m_cpt_cycles << std::endl
+      << "- CLEANUP TOTAL                          = " << (double) m_cpt_cleanup << std::endl
+      << "- CLEANUP WITH DATA RATE                 = " << (double) m_cpt_cleanup_data/m_cpt_cycles << std::endl
+      << "- CLEANUP WITH DATA TOTAL                = " << (double) m_cpt_cleanup_data << std::endl
+      << "- LL RATE                                = " << (double) m_cpt_ll/m_cpt_cycles << std::endl
+      << "- SC RATE                                = " << (double) m_cpt_sc/m_cpt_cycles << std::endl
+      << "- CAS RATE                               = " << (double) m_cpt_cas/m_cpt_cycles << std::endl << std::endl;
+
+     /* << "- WAIT DIR LOCK in READ_FSM              = " << (double) m_cpt_read_fsm_dir_lock/m_cpt_read_fsm_n_dir_lock << std::endl
+      << "- NB CYCLES IN DIR LOCK in READ_FSM      = " << (double) m_cpt_read_fsm_dir_used/m_cpt_read_fsm_n_dir_lock << std::endl
+      << "- WAIT DIR LOCK in WRITE_FSM             = " << (double) m_cpt_write_fsm_dir_lock/m_cpt_write_fsm_n_dir_lock << std::endl
+      << "- NB CYCLES IN DIR LOCK in WRITE_FSM     = " << (double) m_cpt_write_fsm_dir_used/m_cpt_write_fsm_n_dir_lock << std::endl
+      << "- WAIT DIR LOCK in XRAM_FSM              = " << (double) m_cpt_xram_rsp_fsm_dir_lock/m_cpt_xram_rsp_fsm_n_dir_lock << std::endl
+      << "- NB CYCLES IN DIR LOCK in XRAM_FSM      = " << (double) m_cpt_xram_rsp_fsm_dir_used/m_cpt_xram_rsp_fsm_n_dir_lock << std::endl
+      << "- WAIT DIR LOCK in CLEANUP_FSM           = " << (double) m_cpt_cleanup_fsm_dir_lock/m_cpt_cleanup_fsm_n_dir_lock << std::endl
+      << "- NB CYCLES IN DIR LOCK in CLEANUP_FSM   = " << (double) m_cpt_cleanup_fsm_dir_used/m_cpt_cleanup_fsm_n_dir_lock << std::endl
+      << "- WAIT DIR LOCK in CAS_FSM               = " << (double) m_cpt_cas_fsm_dir_lock/m_cpt_cas_fsm_n_dir_lock << std::endl
+      << "- NB CYCLES IN LOCK in CAS_FSM           = " << (double) m_cpt_cas_fsm_dir_used/m_cpt_cas_fsm_n_dir_lock << std::endl
+      << "- DIR UNUSED RATE                        = " << (double) m_cpt_dir_unused/m_cpt_cycles << std::endl << std::endl
+      
+      << "- WAIT TRT LOCK in READ_FSM              = " << (double) m_cpt_read_fsm_trt_lock/m_cpt_read_fsm_n_trt_lock << std::endl
+      << "- NB CYCLES IN TRT LOCK in READ_FSM      = " << (double) m_cpt_read_fsm_trt_used/m_cpt_read_fsm_n_trt_lock << std::endl
+      << "- WAIT TRT LOCK in WRITE_FSM             = " << (double) m_cpt_write_fsm_trt_lock/m_cpt_write_fsm_n_trt_lock << std::endl
+      << "- NB CYCLES IN TRT LOCK in WRITE_FSM     = " << (double) m_cpt_write_fsm_trt_used/m_cpt_write_fsm_n_trt_lock << std::endl
+      << "- WAIT TRT LOCK in CAS_FSM               = " << (double) m_cpt_cas_fsm_trt_lock/m_cpt_cas_fsm_n_trt_lock << std::endl
+      << "- NB CYCLES IN TRT LOCK in CAS_FSM       = " << (double) m_cpt_cas_fsm_trt_used/m_cpt_cas_fsm_n_trt_lock << std::endl
+      << "- WAIT TRT LOCK in XRAM_FSM              = " << (double) m_cpt_xram_rsp_fsm_trt_lock/m_cpt_xram_rsp_fsm_n_trt_lock << std::endl
+      << "- NB CYCLES IN TRT LOCK in XRAM_FSM      = " << (double) m_cpt_xram_rsp_fsm_trt_used/m_cpt_xram_rsp_fsm_n_trt_lock << std::endl
+      << "- WAIT TRT LOCK in IXR_FSM               = " << (double) m_cpt_ixr_fsm_trt_lock/m_cpt_ixr_fsm_n_trt_lock << std::endl
+      << "- NB CYCLES IN TRT LOCK in IXR_FSM       = " << (double) m_cpt_ixr_fsm_trt_used/m_cpt_ixr_fsm_n_trt_lock << std::endl
+      << "- TRT UNUSED RATE                        = " << (double) m_cpt_trt_unused/m_cpt_cycles << std::endl << std::endl
+      
+      << "- WAIT UPT LOCK in WRITE_FSM             = " << (double) m_cpt_write_fsm_upt_lock/m_cpt_write_fsm_n_upt_lock << std::endl
+      << "- NB CYCLES IN UPT LOCK in WRITE_FSM     = " << (double) m_cpt_write_fsm_upt_used/m_cpt_write_fsm_n_upt_lock << std::endl
+      << "- WAIT UPT LOCK in XRAM_FSM              = " << (double) m_cpt_xram_rsp_fsm_upt_lock/m_cpt_xram_rsp_fsm_n_upt_lock << std::endl
+      << "- NB CYCLES IN UPT LOCK in XRAM_FSM      = " << (double) m_cpt_xram_rsp_fsm_upt_used/m_cpt_xram_rsp_fsm_n_upt_lock << std::endl
+      << "- WAIT UPT LOCK in MULTIACK_FSM          = " << (double) m_cpt_multi_ack_fsm_upt_lock/m_cpt_multi_ack_fsm_n_upt_lock << std::endl
+      << "- NB CYCLES IN UPT LOCK in MULTIACK_FSM  = " << (double) m_cpt_multi_ack_fsm_upt_used/m_cpt_multi_ack_fsm_n_upt_lock << std::endl
+      << "- WAIT UPT LOCK in CLEANUP_FSM           = " << (double) m_cpt_cleanup_fsm_upt_lock/m_cpt_cleanup_fsm_n_upt_lock << std::endl
+      << "- NB CYCLES IN UPT LOCK in CLEANUP_FSM   = " << (double) m_cpt_cleanup_fsm_upt_used/m_cpt_cleanup_fsm_n_upt_lock << std::endl
+      << "- WAIT UPT LOCK in CAS_FSM               = " << (double) m_cpt_cas_fsm_upt_lock/m_cpt_cas_fsm_n_upt_lock << std::endl
+      << "- NB CYCLES IN UPT LOCK in CAS_FSM       = " << (double) m_cpt_cas_fsm_upt_used/m_cpt_cas_fsm_n_upt_lock << std::endl
+      << "- UPT UNUSED RATE                        = " << (double) m_cpt_upt_unused/m_cpt_cycles << std::endl << std::endl
+      
+      << "- WAIT HEAP LOCK in READ_FSM             = " << (double) m_cpt_read_fsm_heap_lock/m_cpt_read_fsm_n_heap_lock << std::endl
+      << "- NB CYCLES IN HEAP LOCK in READ_FSM     = " << (double) m_cpt_read_fsm_heap_used/m_cpt_read_fsm_n_heap_lock << std::endl
+      << "- WAIT HEAP LOCK in WRITE_FSM            = " << (double) m_cpt_write_fsm_heap_lock/m_cpt_write_fsm_n_heap_lock << std::endl
+      << "- NB CYCLES IN HEAP LOCK in WRITE_FSM    = " << (double) m_cpt_write_fsm_heap_used/m_cpt_write_fsm_n_heap_lock << std::endl
+      << "- WAIT HEAP LOCK in XRAM_FSM             = " << (double) m_cpt_xram_rsp_fsm_heap_lock/m_cpt_xram_rsp_fsm_n_heap_lock << std::endl
+      << "- NB CYCLES IN HEAP LOCK in XRAM_FSM     = " << (double) m_cpt_xram_rsp_fsm_heap_used/m_cpt_xram_rsp_fsm_n_heap_lock << std::endl
+      << "- WAIT HEAP LOCK in CLEANUP_FSM          = " << (double) m_cpt_cleanup_fsm_heap_lock/m_cpt_cleanup_fsm_n_heap_lock << std::endl
+      << "- NB CYCLES IN HEAP LOCK in CLEANUP_FSM  = " << (double) m_cpt_cleanup_fsm_heap_used/m_cpt_cleanup_fsm_n_heap_lock << std::endl
+      << "- WAIT HEAP LOCK in CAS_FSM              = " << (double) m_cpt_cas_fsm_heap_lock/m_cpt_cas_fsm_n_heap_lock << std::endl
+      << "- NB CYCLES IN HEAP LOCK in CAS_FSM      = " << (double) m_cpt_cas_fsm_heap_used/m_cpt_cas_fsm_n_heap_lock << std::endl
+      << "- HEAP UNUSED RATE                       = " << (double) m_cpt_heap_unused/m_cpt_cycles << std::endl;*/
 }
 
@@ -664,4 +786,5 @@
 {
   delete [] r_ixr_rsp_to_xram_rsp_rok;
+  //delete [] r_ixr_rsp_to_xram_rsp_no_coherent;
 
   delete [] r_xram_rsp_victim_data;
@@ -675,4 +798,7 @@
   delete [] r_write_be;
   delete [] r_write_to_cc_send_data;
+
+  delete [] r_cleanup_data;
+  delete [] r_cleanup_to_ixr_cmd_data;
 }
 
@@ -788,4 +914,5 @@
     {
       r_ixr_rsp_to_xram_rsp_rok[i] = false;
+      //r_ixr_rsp_to_xram_rsp_no_coherent[i] = false;
     }
 
@@ -808,23 +935,77 @@
     r_tgt_rsp_key_sent  = false;
 
+    // ODCCP
+    r_cleanup_data_index       = 0;
+    r_cleanup_trdid            = 0;
+    r_cleanup_pktid            = 0;
+    r_cleanup_contains_data    = false;
+    r_cleanup_to_ixr_cmd_req   = false;
+    r_cleanup_to_ixr_cmd_l1_dirty_ncc = false;
+    r_xram_rsp_to_ixr_cmd_inval_ncc_pending = false;
+    r_cleanup_to_ixr_cmd_srcid = 0;
+    r_cleanup_to_ixr_cmd_trdid = 0;
+    r_cleanup_to_ixr_cmd_pktid = 0;
+    r_cleanup_to_ixr_cmd_nline = 0;
+    for (size_t word = 0; word < m_words; word ++)
+    {
+      r_cleanup_to_ixr_cmd_data[word] = 0;
+      r_cleanup_data[word] = 0;
+    }
+
+
     // Activity counters
-    m_cpt_cycles        = 0;
-    m_cpt_read          = 0;
-    m_cpt_read_miss     = 0;
-    m_cpt_write         = 0;
-    m_cpt_write_miss    = 0;
-    m_cpt_write_cells   = 0;
-    m_cpt_write_dirty   = 0;
-    m_cpt_update        = 0;
-    m_cpt_update_mult   = 0;
-    m_cpt_inval_brdcast = 0;
-    m_cpt_inval         = 0;
-    m_cpt_inval_mult    = 0;
-    m_cpt_cleanup       = 0;
-    m_cpt_ll            = 0;
-    m_cpt_sc            = 0;
-    m_cpt_cas           = 0;
-    m_cpt_trt_full      = 0;
-    m_cpt_trt_rb        = 0;
+    m_cpt_cycles                  = 0;
+    m_cpt_read                    = 0;
+    m_cpt_read_miss               = 0;
+    m_cpt_write                   = 0;
+    m_cpt_write_miss              = 0;
+    m_cpt_write_cells             = 0;
+    m_cpt_write_dirty             = 0;
+    m_cpt_update                  = 0;
+    m_cpt_update_mult             = 0;
+    m_cpt_inval_brdcast           = 0;
+    m_cpt_inval                   = 0;
+    m_cpt_inval_mult              = 0;
+    m_cpt_cleanup                 = 0;
+    m_cpt_cleanup_data            = 0;
+    m_cpt_ll                      = 0;
+    m_cpt_sc                      = 0;
+    m_cpt_cas                     = 0;
+    m_cpt_trt_full                = 0;
+    m_cpt_trt_rb                  = 0;
+    m_cpt_dir_unused              = 0;
+    m_cpt_upt_unused              = 0;
+    m_cpt_heap_unused             = 0;
+    m_cpt_trt_unused              = 0;
+    m_cpt_read_fsm_n_dir_lock     = 0;
+    m_cpt_read_fsm_dir_lock       = 0;
+    m_cpt_read_fsm_dir_used       = 0;
+    m_cpt_read_fsm_trt_lock       = 0;
+    m_cpt_read_fsm_heap_lock      = 0;
+    m_cpt_write_fsm_dir_lock      = 0;
+    m_cpt_write_fsm_n_dir_lock    = 0;
+    m_cpt_write_fsm_upt_lock      = 0;
+    m_cpt_write_fsm_heap_lock     = 0;
+    m_cpt_write_fsm_dir_used      = 0;
+    m_cpt_write_fsm_trt_lock      = 0;
+    m_cpt_cas_fsm_n_dir_lock      = 0;
+    m_cpt_cas_fsm_dir_lock        = 0;
+    m_cpt_cas_fsm_upt_lock        = 0;
+    m_cpt_cas_fsm_heap_lock       = 0;
+    m_cpt_cas_fsm_trt_lock        = 0;
+    m_cpt_cas_fsm_dir_used        = 0;
+    m_cpt_xram_rsp_fsm_n_dir_lock = 0;
+    m_cpt_xram_rsp_fsm_dir_lock   = 0;
+    m_cpt_xram_rsp_fsm_trt_lock   = 0;
+    m_cpt_xram_rsp_fsm_upt_lock   = 0;
+    m_cpt_xram_rsp_fsm_heap_lock  = 0;
+    m_cpt_xram_rsp_fsm_dir_used   = 0;
+    m_cpt_cleanup_fsm_dir_lock    = 0;
+    m_cpt_cleanup_fsm_n_dir_lock  = 0;
+    m_cpt_cleanup_fsm_heap_lock   = 0;
+    m_cpt_cleanup_fsm_upt_lock    = 0;
+    m_cpt_cleanup_fsm_dir_used    = 0;
+    m_cpt_ixr_fsm_trt_lock        = 0;
+    m_cpt_multi_ack_fsm_upt_lock  = 0;
 
     return;
@@ -1319,10 +1500,12 @@
     case MULTI_ACK_UPT_LOCK:
     {
+        m_cpt_multi_ack_fsm_upt_lock++;
         // get lock to the UPDATE table
-        if(r_alloc_upt_fsm.read() != ALLOC_UPT_MULTI_ACK) break;
+        if(r_alloc_upt_fsm.read() != ALLOC_UPT_MULTI_ACK)  break;
 
         // decrement the number of expected responses
         size_t count = 0;
         bool valid   = m_upt.decrement(r_multi_ack_upt_index.read(), count);
+
 
         if(not valid)
@@ -1349,4 +1532,5 @@
           << " entry = "       << r_multi_ack_upt_index.read()
           << " / rsp_count = " << std::dec << count << std::endl;
+        m_cpt_multi_ack_fsm_n_upt_lock++;
 #endif
         break;
@@ -1874,4 +2058,5 @@
       {
         r_read_fsm = READ_DIR_LOCK;
+        m_cpt_read_fsm_n_dir_lock++;
       }
 
@@ -1880,4 +2065,7 @@
 std::cout << "  <MEMC " << name() << " READ_DIR_REQ> Requesting DIR lock " << std::endl;
 #endif
+
+      m_cpt_read_fsm_dir_lock++;
+
       break;
     }
@@ -1981,43 +2169,51 @@
             if(m_monitor_ok) check_monitor( m_cmd_read_addr_fifo.read(), r_read_data[0], true);
 
-            // update the cache directory
-            DirectoryEntry entry;
-            entry.valid   = true;
-            entry.is_cnt  = is_cnt;
-            entry.dirty   = r_read_dirty.read();
-            entry.tag     = r_read_tag.read();
-            entry.lock    = r_read_lock.read();
-            entry.ptr     = r_read_ptr.read();
-
-            if(cached_read)   // Cached read => we must update the copies
-            {
-                if(!is_cnt)  // Not counter mode
-                {
-                    entry.owner.srcid    = m_cmd_read_srcid_fifo.read();
+        // update the cache directory
+        DirectoryEntry entry;
+        entry.valid    = true;
+        entry.is_cnt   = is_cnt;
+        entry.dirty    = r_read_dirty.read();
+        entry.tag      = r_read_tag.read();
+        entry.lock     = r_read_lock.read();
+        entry.ptr      = r_read_ptr.read();
+
+        /*ODCCP*/ // if pktid = 0x9 that means read on no coherent line
+        if(m_cmd_read_pktid_fifo.read() == 0x9){
+          entry.coherent = false;
+        }
+        else{
+          entry.coherent = true;
+        }
+        
+        if(cached_read)   // Cached read => we must update the copies
+        {
+          if(!is_cnt)  // Not counter mode
+          {
+            entry.owner.srcid    = m_cmd_read_srcid_fifo.read();
 #if L1_MULTI_CACHE
-                    entry.owner.cache_id = m_cmd_read_pktid_fifo.read();
-#endif
-                    entry.owner.inst     = inst_read;
-                    entry.count          = r_read_count.read() + 1;
-                }
-                else  // Counter mode
-                {
-                    entry.owner.srcid    = 0;
+            entry.owner.cache_id = m_cmd_read_pktid_fifo.read();
+#endif
+            entry.owner.inst     = inst_read;
+            entry.count          = r_read_count.read() + 1;
+          }
+          else  // Counter mode
+          {
+            entry.owner.srcid    = 0;
 #if L1_MULTI_CACHE
-                    entry.owner.cache_id = 0;
-#endif
-                    entry.owner.inst     = false;
-                    entry.count          = r_read_count.read() + 1;
-                }
-            }
-            else            // Uncached read
-            {
-                entry.owner.srcid     = r_read_copy.read();
+            entry.owner.cache_id = 0;
+#endif
+            entry.owner.inst     = false;
+            entry.count          = r_read_count.read() + 1;
+          }
+        }
+        else            // Uncached read
+        {
+          entry.owner.srcid     = r_read_copy.read();
 #if L1_MULTI_CACHE
-                entry.owner.cache_id  = r_read_copy_cache.read();
-#endif
-                entry.owner.inst      = r_read_copy_inst.read();
-                entry.count           = r_read_count.read();
-            }
+          entry.owner.cache_id  = r_read_copy_cache.read();
+#endif
+          entry.owner.inst      = r_read_copy_inst.read();
+          entry.count           = r_read_count.read();
+        }
 
 #if DEBUG_MEMC_READ
@@ -2033,8 +2229,16 @@
 #endif
 
-            m_cache_directory.write(set, way, entry);
-            r_read_fsm    = READ_RSP;
-        }
-        break;
+          if(m_monitor_ok)
+          {
+            char buf[80];
+            snprintf(buf, 80, "READ_DIR_HIT srcid %d, ins %d",
+                     (int)m_cmd_read_srcid_fifo.read(),
+                     (int)((m_cmd_read_pktid_fifo.read()&0x2)!=0));
+            check_monitor(m_cmd_read_addr_fifo.read(), r_read_data[0], true);
+          }
+        m_cache_directory.write(set, way, entry);
+        r_read_fsm    = READ_RSP;
+      }
+      break;
     }
     ///////////////////
@@ -2044,4 +2248,5 @@
       {
         r_read_fsm = READ_HEAP_LOCK;
+        m_cpt_read_fsm_n_heap_lock++;
       }
 
@@ -2051,4 +2256,7 @@
           << " Requesting HEAP lock " << std::endl;
 #endif
+
+      m_cpt_read_fsm_heap_lock++;
+
       break;
     }
@@ -2283,7 +2491,8 @@
       {
         size_t      index     = 0;
+        size_t      index_write = 0;
         addr_t      addr      = (addr_t) m_cmd_read_addr_fifo.read();
         bool        hit_read  = m_trt.hit_read(m_nline[addr], index);
-        bool        hit_write = m_trt.hit_write(m_nline[addr]);
+        bool        hit_write = m_trt.hit_write(m_nline[addr], &index_write);
         bool        wok       = !m_trt.full(index);
 
@@ -2306,7 +2515,12 @@
           << " hit_read = " << hit_read
           << " / hit_write = " << hit_write
+          << " / Index = " << index_write
           << " / full = " << !wok << std::endl;
-#endif
-      }
+        m_cpt_read_fsm_n_trt_lock++;
+#endif
+      }
+
+      m_cpt_read_fsm_trt_lock++;
+
       break;
     }
@@ -2533,4 +2747,5 @@
 
         r_write_fsm = WRITE_DIR_LOCK;
+        m_cpt_write_fsm_n_dir_lock++;
       }
 
@@ -2540,4 +2755,6 @@
           << std::endl;
 #endif
+
+      m_cpt_write_fsm_dir_lock++;
 
       break;
@@ -2792,5 +3009,9 @@
         if(wok) r_write_fsm = WRITE_UPT_HEAP_LOCK;
         else    r_write_fsm = WRITE_WAIT;
-      }
+        m_cpt_write_fsm_n_upt_lock++;
+      }
+
+      m_cpt_write_fsm_upt_lock++;
+
       break;
     }
@@ -2808,5 +3029,9 @@
 #endif
         r_write_fsm = WRITE_UPT_REQ;
-      }
+        m_cpt_write_fsm_n_heap_lock++;
+      }
+
+      m_cpt_write_fsm_heap_lock++;
+
       break;
     }
@@ -3093,5 +3318,9 @@
           m_cpt_trt_full++;
         }
-      }
+        m_cpt_write_fsm_n_trt_lock++;
+      }
+
+      m_cpt_write_fsm_trt_lock++;
+
       break;
     }
@@ -3212,5 +3441,9 @@
           << " : wok = " << wok << " / index = " << wok_index << std::endl;
 #endif
-      }
+        m_cpt_write_fsm_n_trt_lock++;
+      }
+
+      m_cpt_write_fsm_trt_lock++;
+
       break;
     }
@@ -3239,5 +3472,4 @@
                         nb_copies,
                         index);
-
 #if DEBUG_MEMC_WRITE
 if( m_debug and wok )
@@ -3249,5 +3481,9 @@
         if(wok) r_write_fsm = WRITE_BC_DIR_INVAL;
         else       r_write_fsm = WRITE_WAIT;
-      }
+        m_cpt_write_fsm_n_upt_lock++;
+      }
+
+      m_cpt_write_fsm_upt_lock++;
+
       break;
     }
@@ -3382,38 +3618,42 @@
     ////////////////////////
     case IXR_CMD_READ_IDLE:
-    {
       if     (r_write_to_ixr_cmd_req)    r_ixr_cmd_fsm = IXR_CMD_WRITE;
       else if(r_cas_to_ixr_cmd_req)      r_ixr_cmd_fsm = IXR_CMD_CAS;
       else if(r_xram_rsp_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_XRAM;
+      else if(r_cleanup_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_CLEANUP_DATA;
       else if(r_read_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_READ;
       break;
-    }
     ////////////////////////
     case IXR_CMD_WRITE_IDLE:
-    {
-      if     (r_cas_to_ixr_cmd_req)      r_ixr_cmd_fsm = IXR_CMD_CAS;
+      if(r_cas_to_ixr_cmd_req)           r_ixr_cmd_fsm = IXR_CMD_CAS;
       else if(r_xram_rsp_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_XRAM;
+      else if(r_cleanup_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_CLEANUP_DATA;
       else if(r_read_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_READ;
       else if(r_write_to_ixr_cmd_req)    r_ixr_cmd_fsm = IXR_CMD_WRITE;
       break;
-    }
     ////////////////////////
     case IXR_CMD_CAS_IDLE:
-    {
-      if     (r_xram_rsp_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_XRAM;
+      if(r_xram_rsp_to_ixr_cmd_req)      r_ixr_cmd_fsm = IXR_CMD_XRAM;
+      else if(r_cleanup_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_CLEANUP_DATA;
       else if(r_read_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_READ;
       else if(r_write_to_ixr_cmd_req)    r_ixr_cmd_fsm = IXR_CMD_WRITE;
       else if(r_cas_to_ixr_cmd_req)      r_ixr_cmd_fsm = IXR_CMD_CAS;
       break;
-    }
     ////////////////////////
     case IXR_CMD_XRAM_IDLE:
-    {
-      if     (r_read_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_READ;
-      else if(r_write_to_ixr_cmd_req)    r_ixr_cmd_fsm = IXR_CMD_WRITE;
+      if(r_cleanup_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_CLEANUP_DATA;
+      else if(r_read_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_READ;
+      else if(r_write_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_WRITE;
       else if(r_cas_to_ixr_cmd_req)      r_ixr_cmd_fsm = IXR_CMD_CAS;
       else if(r_xram_rsp_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_XRAM;
       break;
-    }
+      ////////////////////////
+    case IXR_CMD_CLEANUP_IDLE:
+      if(r_read_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_READ;
+      else if(r_write_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_WRITE;
+      else if(r_cas_to_ixr_cmd_req)      r_ixr_cmd_fsm = IXR_CMD_CAS;
+      else if(r_xram_rsp_to_ixr_cmd_req) r_ixr_cmd_fsm = IXR_CMD_XRAM;
+      else if(r_cleanup_to_ixr_cmd_req)     r_ixr_cmd_fsm = IXR_CMD_CLEANUP_DATA;
+      break;      
     //////////////////       // send a get from READ FSM
     case IXR_CMD_READ:
@@ -3541,4 +3781,29 @@
       break;
     }
+
+      ////////////////////////
+    case IXR_CMD_CLEANUP_DATA:     // send a put command to XRAM
+      if(p_vci_ixr.cmdack)
+      {
+        if(r_ixr_cmd_cpt.read() == (m_words - 2))
+        {
+          r_ixr_cmd_cpt = 0;
+          r_ixr_cmd_fsm = IXR_CMD_CLEANUP_IDLE;
+          r_cleanup_to_ixr_cmd_req = false;
+          r_xram_rsp_to_ixr_cmd_inval_ncc_pending = false;
+        }
+        else
+        {
+          r_ixr_cmd_cpt = r_ixr_cmd_cpt.read() + 2;
+        }
+
+#if DEBUG_MEMC_IXR_CMD
+        if(m_debug)
+        {
+          std::cout << "  <MEMC " << name() << ".IXR_CMD_CLEANUP_DATA> Send a put request to xram" << std::endl;
+        }
+#endif
+      }
+      break;
 
   } // end switch r_ixr_cmd_fsm
@@ -3619,5 +3884,9 @@
           << r_ixr_rsp_trt_index.read() << std::endl;
 #endif
-      }
+      m_cpt_ixr_fsm_n_trt_lock++;
+      }
+
+      m_cpt_ixr_fsm_trt_lock++;
+
       break;
     }
@@ -3645,4 +3914,8 @@
         {
           r_ixr_rsp_to_xram_rsp_rok[r_ixr_rsp_trt_index.read()]=true;
+          /*if(p_vci_ixr.rpktid.read()&0xF == 0x9)
+            r_ixr_rsp_to_xram_rsp_no_coherent[r_ixr_rsp_trt_index.read()] = true;
+          else
+            r_ixr_rsp_to_xram_rsp_no_coherent[r_ixr_rsp_trt_index.read()] = false;*/
           r_ixr_rsp_fsm = IXR_RSP_IDLE;
         }
@@ -3655,5 +3928,7 @@
           << " / data = " << std::hex << data << std::endl;
 #endif
-      }
+      m_cpt_ixr_fsm_n_trt_lock++;
+      }
+      m_cpt_ixr_fsm_trt_lock++;
       break;
     }
@@ -3728,5 +4003,9 @@
           << " Get access to DIR and TRT" << std::endl;
 #endif
-      }
+        m_cpt_xram_rsp_fsm_n_dir_lock++;
+        m_cpt_xram_rsp_fsm_n_trt_lock++;
+      }
+      m_cpt_xram_rsp_fsm_dir_lock++;
+      m_cpt_xram_rsp_fsm_trt_lock++;
       break;
     }
@@ -3754,4 +4033,6 @@
         r_xram_rsp_victim_copy_cache= victim.owner.cache_id;
 #endif
+        
+        r_xram_rsp_victim_coherent  = victim.coherent;
         r_xram_rsp_victim_copy_inst = victim.owner.inst;
         r_xram_rsp_victim_count     = victim.count;
@@ -3764,7 +4045,16 @@
         r_xram_rsp_victim_dirty     = victim.dirty;
 
+
         if(!r_xram_rsp_trt_buf.rerror)
         {
-          r_xram_rsp_fsm = XRAM_RSP_INVAL_LOCK;
+          /*ODCCP*/ //if victim is no coherent and there is an inval no coherent pending we wait
+          if(!victim.coherent and r_xram_rsp_to_ixr_cmd_inval_ncc_pending.read())
+          {
+            r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT;
+          }
+          else
+          {
+            r_xram_rsp_fsm = XRAM_RSP_INVAL_LOCK;
+          }
         }
         else
@@ -3829,5 +4119,9 @@
 #endif
         }
-      }
+        m_cpt_xram_rsp_fsm_n_upt_lock++;
+      }
+
+      m_cpt_xram_rsp_fsm_upt_lock++;
+
       break;
     }
@@ -3892,4 +4186,5 @@
         entry.owner.inst    = inst_read;
         entry.count         = 1;
+
       }
       else
@@ -3902,4 +4197,13 @@
         entry.count          = 0;
       }
+
+      /*ODCCP*/ //if pktid = 0x9 that means line no coherent
+      if(r_xram_rsp_trt_buf.pktid == 0x9){
+        entry.coherent = false;
+      }
+      else{
+        entry.coherent = true;
+      }
+
       m_cache_directory.write(set, way, entry);
 
@@ -3950,10 +4254,10 @@
 #endif
 
-      // If the victim is not dirty, we don't need another XRAM put transaction,
+      // If the victim is not dirty and coherent or victim's count egal 0 , we don't need another XRAM put transaction,
       // and we can erase the TRT entry
-      if(!r_xram_rsp_victim_dirty.read())  m_trt.erase(r_xram_rsp_trt_index.read());
+      if(!r_xram_rsp_victim_dirty.read() and (r_xram_rsp_victim_coherent.read() or (r_xram_rsp_victim_count.read() == 0)))  m_trt.erase(r_xram_rsp_trt_index.read());
 
       // Next state
-      if(r_xram_rsp_victim_dirty.read())       r_xram_rsp_fsm = XRAM_RSP_TRT_DIRTY;
+      if(r_xram_rsp_victim_dirty.read() or (!r_xram_rsp_victim_coherent.read() and (r_xram_rsp_victim_count.read() == 1)))       r_xram_rsp_fsm = XRAM_RSP_TRT_DIRTY;
       else if(r_xram_rsp_trt_buf.proc_read)    r_xram_rsp_fsm = XRAM_RSP_DIR_RSP;
       else if(r_xram_rsp_victim_inval.read())  r_xram_rsp_fsm = XRAM_RSP_INVAL;
@@ -3987,5 +4291,9 @@
         else if(r_xram_rsp_victim_inval.read())  r_xram_rsp_fsm = XRAM_RSP_INVAL;
         else                                     r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
-      }
+        m_cpt_xram_rsp_fsm_n_trt_lock++;
+      }
+
+      m_cpt_xram_rsp_fsm_trt_lock++;
+
       break;
     }
@@ -4009,5 +4317,5 @@
 
         if(r_xram_rsp_victim_inval)      r_xram_rsp_fsm = XRAM_RSP_INVAL;
-        else if(r_xram_rsp_victim_dirty) r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
+        else if(r_xram_rsp_victim_dirty or (!r_xram_rsp_victim_coherent.read() and (r_xram_rsp_victim_count.read() == 1))) r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
         else                             r_xram_rsp_fsm = XRAM_RSP_IDLE;
 
@@ -4045,5 +4353,5 @@
         r_xram_rsp_next_ptr                 = r_xram_rsp_victim_ptr.read();
 
-        if(r_xram_rsp_victim_dirty)  r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
+        if(r_xram_rsp_victim_dirty or (!r_xram_rsp_victim_coherent.read() and (r_xram_rsp_victim_count.read() == 1)))  r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
         else if(not_last_multi_req)  r_xram_rsp_fsm = XRAM_RSP_HEAP_REQ;
         else                         r_xram_rsp_fsm = XRAM_RSP_IDLE;
@@ -4061,6 +4369,7 @@
     case XRAM_RSP_WRITE_DIRTY:  // send a write request to IXR_CMD FSM
     {
-      if(!r_xram_rsp_to_ixr_cmd_req.read())
-      {
+      if((!r_xram_rsp_to_ixr_cmd_req.read()) and (!r_xram_rsp_to_ixr_cmd_inval_ncc_pending.read()))
+      {
+
         r_xram_rsp_to_ixr_cmd_req = true;
         r_xram_rsp_to_ixr_cmd_nline = r_xram_rsp_victim_nline.read();
@@ -4071,4 +4380,13 @@
         }
         m_cpt_write_dirty++;
+        
+        // if victim is no coherent, we dont request a ixr command
+        if( (!r_xram_rsp_victim_coherent.read()) and (r_xram_rsp_victim_count.read() == 1) )
+        {
+          r_xram_rsp_to_ixr_cmd_inval_ncc_pending = true; // inval no coherent pending
+          r_xram_rsp_to_ixr_cmd_req = false;
+          r_xram_rsp_fsm = XRAM_RSP_IDLE;
+          break;
+        }
 
         bool multi_req = !r_xram_rsp_victim_is_cnt.read() and r_xram_rsp_victim_inval.read();
@@ -4093,4 +4411,5 @@
       {
         r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE;
+        m_cpt_xram_rsp_fsm_n_heap_lock++;
       }
 
@@ -4100,4 +4419,7 @@
           << " Requesting HEAP lock" << std::endl;
 #endif
+
+      m_cpt_xram_rsp_fsm_heap_lock++;
+
       break;
     }
@@ -4243,5 +4565,4 @@
 
       uint64_t flit = m_cc_receive_to_cleanup_fifo.read();
-
       uint32_t srcid =
         DspinDhccpParam::dspin_get(
@@ -4264,4 +4585,10 @@
             DspinDhccpParam::CLEANUP_NLINE_MSB) << 32;
 
+      /*ODCCP*/ // Cleanup on no coherent line if 1
+      r_cleanup_ncc = 
+        DspinDhccpParam::dspin_get(
+            flit, 
+            DspinDhccpParam::CLEANUP_NCC);
+
       r_cleanup_inst  = (type == DspinDhccpParam::TYPE_CLEANUP_INST);
       r_cleanup_srcid = srcid;
@@ -4295,4 +4622,5 @@
     {
       if(not m_cc_receive_to_cleanup_fifo.rok()) break;
+      
 
       uint64_t flit = m_cc_receive_to_cleanup_fifo.read();
@@ -4300,8 +4628,22 @@
       addr_t nline = r_cleanup_nline.read() |
         DspinDhccpParam::dspin_get(flit, DspinDhccpParam::CLEANUP_NLINE_LSB);
+      
+      bool eop = DspinDhccpParam::dspin_get(flit, DspinDhccpParam::FROM_L1_EOP);
+      
+      /*ODCCP*/ // if not eop (more than 2 flits) there is a cleanup no coherent with data
+      if (!eop)
+      {
+        r_cleanup_contains_data = true; // this cleanup contains data
+        r_cleanup_fsm = CLEANUP_GET_DATA;
+        r_cleanup_data_index = 0;
+      }
+      else
+      {
+        r_cleanup_contains_data = false;
+        r_cleanup_fsm = CLEANUP_DIR_REQ;
+      }
 
       cc_receive_to_cleanup_fifo_get = true;
-      r_cleanup_nline                = nline;
-      r_cleanup_fsm                  = CLEANUP_DIR_REQ;
+      r_cleanup_nline               = nline;
 
 #if DEBUG_MEMC_CLEANUP
@@ -4314,7 +4656,32 @@
     }
 
+    /*ODCCP*/ // We save the cleanup's data into a buffer
+    case CLEANUP_GET_DATA :
+    {
+      if(not m_cc_receive_to_cleanup_fifo.rok()) break;
+      
+      assert (r_cleanup_data_index.read() < m_words and "MEM_CACHE in CLEANUP_GET_DATA : too much flits in cleanup data updt");
+
+      uint64_t flit = m_cc_receive_to_cleanup_fifo.read();
+
+      uint32_t data = 
+        DspinDhccpParam::dspin_get (flit, DspinDhccpParam::CLEANUP_DATA_UPDT);
+
+      r_cleanup_data[r_cleanup_data_index.read()] = data;
+      r_cleanup_data_index = r_cleanup_data_index.read() + 1;
+      cc_receive_to_cleanup_fifo_get = true;
+      m_cpt_cleanup_data++;
+
+      if (r_cleanup_data_index.read() == m_words - 1) // last flit
+      {
+        r_cleanup_fsm = CLEANUP_DIR_REQ;
+      }
+      break;
+    }
     /////////////////////
     case CLEANUP_DIR_REQ:   // Get the lock to the directory
     {
+      m_cpt_cleanup_fsm_dir_lock++;
+      // Get the lock to the directory
       if(r_alloc_dir_fsm.read() != ALLOC_DIR_CLEANUP) break;
 
@@ -4325,4 +4692,7 @@
 std::cout << "  <MEMC " << name() << " CLEANUP_DIR_REQ> Requesting DIR lock" << std::endl;
 #endif
+
+      m_cpt_cleanup_fsm_n_dir_lock++;
+
       break;
     }
@@ -4341,5 +4711,4 @@
         exit(0);
       }
-
       // Read the directory
       size_t way = 0;
@@ -4362,4 +4731,13 @@
       if(entry.valid)      // hit : the copy must be cleared
       {
+        if(entry.count < 1)
+        {
+          std::cout << "assert on line " << std::hex <<r_cleanup_nline.read() << " | at cycle " << std::dec <<m_cpt_cycles << std::endl;
+          std::cout << "cleanup with data ? " << r_cleanup_contains_data.read() << " | at cycle " << m_cpt_cycles << std::endl;
+          std::cout << "cleanup_address = " << std::hex << (r_cleanup_nline.read()*m_words*4) << std::dec << std::endl;
+          std::cout << "srcid = " << r_cleanup_srcid.read() << std::endl;
+          std::cout << "inst = " << r_cleanup_inst.read() << std::endl;
+          std::cout << "inst = " << r_cleanup_inst.read() << std::endl;
+        }
         assert(
             (entry.count > 0) and
@@ -4445,5 +4823,5 @@
       entry.valid       = true;
       entry.is_cnt      = r_cleanup_is_cnt.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.lock        = r_cleanup_lock.read();
@@ -4456,4 +4834,13 @@
       entry.owner.cache_id = 0;
 #endif
+      /*ODCCP*/ // if cleanup contains data we update the cache data
+      if (r_cleanup_contains_data.read())
+      {
+        for (size_t word = 0; word < m_words; word ++)
+        {
+          m_cache_data.write(way, set, word, r_cleanup_data[word].read(), 0xF);
+        }
+      }
+
 
       m_cache_directory.write(set, way, entry);
@@ -4484,4 +4871,5 @@
     {
       // get the lock to the HEAP directory
+      m_cpt_cleanup_fsm_heap_lock++;
       if(r_alloc_heap_fsm.read() != ALLOC_HEAP_CLEANUP) break;
 
@@ -4497,4 +4885,5 @@
       }
 #endif
+      m_cpt_cleanup_fsm_n_heap_lock++;
       break;
     }
@@ -4575,5 +4964,6 @@
           << " / r_cleanup_copy_inst = " << r_cleanup_copy_inst.read() << std::endl
           << "heap_entry.owner.srcid = " << heap_entry.owner.srcid
-          << " / heap_entry.owner.inst = " << heap_entry.owner.inst << std::endl;
+          << " / heap_entry.owner.inst = " << heap_entry.owner.inst << std::endl
+          << " / addr = " << std::hex << (r_cleanup_nline.read() *m_words*4) << std::dec << std::endl;
 /**/
 
@@ -4842,4 +5232,5 @@
                              // invalidate transaction matching the cleanup 
     {
+      m_cpt_cleanup_fsm_upt_lock++;
       if(r_alloc_upt_fsm.read() != ALLOC_UPT_CLEANUP) break;
 
@@ -4851,5 +5242,13 @@
       if ( not match_inval )     // no pending inval
       {
+        /*ODCCP*/ // If cleanup is on no coherent line we go to CLEANUP_IXR_REQ
+        if (r_cleanup_ncc.read())
+        {
+          r_cleanup_fsm = CLEANUP_IXR_REQ;
+        }
+        else
+        {
           r_cleanup_fsm = CLEANUP_SEND_CLACK;
+        }
 
 #if DEBUG_MEMC_CLEANUP
@@ -4862,5 +5261,6 @@
           << std::endl;
 #endif
-          break;
+      m_cpt_cleanup_fsm_n_upt_lock++;
+        break;
       }
 
@@ -4908,5 +5308,13 @@
       else             // multi inval transaction not completed
       {
-        r_cleanup_fsm = CLEANUP_SEND_CLACK ;
+        /*ODCCP*/ // If cleanup is on no coherent line we go to CLEANUP_IXR_REQ
+        if (r_cleanup_ncc.read())
+        {
+          r_cleanup_fsm = CLEANUP_IXR_REQ;
+        }
+        else
+        {
+          r_cleanup_fsm = CLEANUP_SEND_CLACK;
+        }
       }
 
@@ -4938,4 +5346,5 @@
       if      ( r_cleanup_need_rsp.read() ) r_cleanup_fsm = CLEANUP_WRITE_RSP;
       else if ( r_cleanup_need_ack.read() ) r_cleanup_fsm = CLEANUP_CONFIG_ACK;
+      else if ( r_cleanup_ncc.read()      ) r_cleanup_fsm = CLEANUP_IXR_REQ;
       else                                  r_cleanup_fsm = CLEANUP_SEND_CLACK;
 
@@ -4960,5 +5369,13 @@
       r_cleanup_to_tgt_rsp_pktid   = r_cleanup_write_pktid.read();
 
-      r_cleanup_fsm                = CLEANUP_SEND_CLACK;
+      /*ODCCP*/ // If cleanup is on no coherent line we go to CLEANUP_IXR_REQ
+      if (r_cleanup_ncc.read())
+      {
+        r_cleanup_fsm = CLEANUP_IXR_REQ;
+      }
+      else
+      {
+        r_cleanup_fsm = CLEANUP_SEND_CLACK;
+      }
 
 #if DEBUG_MEMC_CLEANUP
@@ -4977,5 +5394,4 @@
     {
       if ( r_cleanup_to_config_ack.read() ) break;
-
       r_cleanup_to_config_ack      = true;
       r_cleanup_fsm                = CLEANUP_SEND_CLACK;
@@ -4988,4 +5404,64 @@
       break;
     }
+
+    /*ODCCP*/ 
+    case CLEANUP_IXR_REQ:
+    {
+    
+      //Send a request to the ixr to write the data in the XRAM and set an entry in the TRT.
+      if (r_alloc_trt_fsm.read() == ALLOC_TRT_CLEANUP)
+      {
+        if(!r_cleanup_to_ixr_cmd_req.read())
+        {
+          size_t index = 0;
+          bool   hit   = m_trt.hit_write(r_cleanup_nline.read(), &index); // we save the index of the matching entry in TRT 
+          if (!hit)
+          {
+            std::cout << "assert on line " << r_cleanup_nline.read() << " | at cycle " << std::dec <<m_cpt_cycles << std::endl;
+            for (int i=0; i<4; i++) m_trt.print(i);
+          }
+          assert (hit and "CLEANUP_IXR_REQ found no matching entry in TRT");
+          
+          r_cleanup_to_ixr_cmd_req     = true;
+
+          for(size_t i = 0; i < m_words; i++){
+            r_cleanup_to_ixr_cmd_data[i]   = r_cleanup_data[i];
+          }
+
+          r_cleanup_to_ixr_cmd_srcid        = r_cleanup_srcid.read();
+          r_cleanup_to_ixr_cmd_trdid        = 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_l1_dirty_ncc = r_cleanup_contains_data.read();
+          r_cleanup_fsm = CLEANUP_SEND_CLACK;
+#if DEBUG_MEMC_CLEANUP
+      if(m_debug)
+      {
+        std::cout
+            << "  <MEMC " << name()
+            << " CLEANUP_IXR_REQ> Send a put request to the ixr:"
+            << " contains data ? = " << std::dec << r_cleanup_contains_data.read()
+            << " srcid = "           << std::dec << r_cleanup_srcid.read()
+            << " pktid = "           << std::dec << r_cleanup_pktid.read()
+            << " trdid = "           << std::dec << index
+            << " nline = "           << std::hex << r_cleanup_nline.read() << std::dec
+            << std::endl;
+      }
+#endif
+        }
+        else
+        {
+            r_cleanup_fsm = CLEANUP_WAIT;
+        }
+      }
+      break;
+    }
+
+    case CLEANUP_WAIT :
+    {
+      r_cleanup_fsm = CLEANUP_IXR_REQ;
+      break;
+    }
+
     ////////////////////////
     case CLEANUP_SEND_CLACK:    // acknowledgement to a cleanup command
@@ -5094,4 +5570,5 @@
       {
         r_cas_fsm = CAS_DIR_LOCK;
+        m_cpt_cas_fsm_n_dir_lock++;
       }
 
@@ -5104,4 +5581,7 @@
       }
 #endif
+
+      m_cpt_cas_fsm_dir_lock++;
+
       break;
     }
@@ -5347,5 +5827,9 @@
           << " / count = " << nb_copies << std::endl;
 #endif
-      }
+        m_cpt_cas_fsm_n_upt_lock++;
+      }
+
+      m_cpt_cas_fsm_upt_lock++;
+
       break;
     }
@@ -5378,5 +5862,9 @@
 #endif
         r_cas_fsm = CAS_UPT_REQ;
-      }
+        m_cpt_cas_fsm_n_heap_lock++;
+      }
+
+      m_cpt_cas_fsm_heap_lock++;
+
       break;
     }
@@ -5518,5 +6006,9 @@
           r_cas_fsm = CAS_WAIT;
         }
-      }
+        m_cpt_cas_fsm_n_trt_lock++;
+      }
+
+      m_cpt_cas_fsm_trt_lock++;
+
       break;
     }
@@ -5583,5 +6075,9 @@
           r_cas_fsm = CAS_WAIT;
         }
-      }
+        m_cpt_cas_fsm_n_upt_lock++;
+      }
+
+      m_cpt_cas_fsm_upt_lock++;
+
       break;
     }
@@ -5761,5 +6257,9 @@
           r_cas_fsm       = CAS_MISS_TRT_SET;
         }
-      }
+        m_cpt_cas_fsm_n_trt_lock++;
+      }
+
+      m_cpt_cas_fsm_trt_lock++;
+
       break;
     }
@@ -6531,15 +7031,16 @@
     case CC_RECEIVE_CLEANUP_EOP:
       {
-        // write second CLEANUP flit in CC_RECEIVE to CLEANUP fifo
+        // write second CLEANUP flit in CC_RECEIVE to CLEANUP fifo or more in case of cleanup data (ODCCP)
 
         if(not p_dspin_in.write or not m_cc_receive_to_cleanup_fifo.wok())
           break;
 
-        assert(p_dspin_in.eop.read() and
+        /*assert(p_dspin_in.eop.read() and
             "VCI_MEM_CACHE ERROR in CC_RECEIVE : "
-            "CLEANUP command must have two flits");
+            "CLEANUP command must have two flits");*/
 
         cc_receive_to_cleanup_fifo_put = true;
-        r_cc_receive_fsm               = CC_RECEIVE_IDLE;
+        if(p_dspin_in.eop.read())
+          r_cc_receive_fsm               = CC_RECEIVE_IDLE;
 
         break;
@@ -7020,8 +7521,11 @@
                 (r_cas_fsm.read() == CAS_BC_UPT_LOCK))
           r_alloc_upt_fsm = ALLOC_UPT_CAS;
-
         else if(r_config_fsm.read() == CONFIG_DIR_UPT_LOCK) 
           r_alloc_upt_fsm = ALLOC_UPT_CONFIG;
-      }
+        else
+          m_cpt_upt_unused++;
+      }
+      else
+        m_cpt_multi_ack_fsm_upt_used++;
       break;
 
@@ -7046,5 +7550,10 @@
         else if(r_multi_ack_fsm.read() == MULTI_ACK_UPT_LOCK)
           r_alloc_upt_fsm = ALLOC_UPT_MULTI_ACK;
-      }
+
+        else
+          m_cpt_upt_unused++;
+      }
+      else
+        m_cpt_write_fsm_upt_used++;
       break;
 
@@ -7069,5 +7578,10 @@
                 (r_write_fsm.read() == WRITE_BC_UPT_LOCK))
           r_alloc_upt_fsm = ALLOC_UPT_WRITE;
-      }
+
+        else
+          m_cpt_upt_unused++;
+      }
+      else
+        m_cpt_xram_rsp_fsm_upt_used++;
       break;
 
@@ -7093,5 +7607,10 @@
         else if(r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)
           r_alloc_upt_fsm = ALLOC_UPT_XRAM_RSP;
-      }
+
+        else
+          m_cpt_upt_unused++;
+      }
+      else
+        m_cpt_cleanup_fsm_upt_used++;
       break;
 
@@ -7116,5 +7635,10 @@
         else if(r_cleanup_fsm.read() == CLEANUP_UPT_LOCK)
           r_alloc_upt_fsm = ALLOC_UPT_CLEANUP;
-      }
+
+        else
+          m_cpt_upt_unused++;
+      }
+      else
+        m_cpt_cas_fsm_upt_used++;
       break;
 
@@ -7189,9 +7713,14 @@
         else if(r_xram_rsp_fsm.read() == XRAM_RSP_DIR_LOCK)
           r_alloc_dir_fsm = ALLOC_DIR_XRAM_RSP;
-
+        
         else if(r_config_fsm.read() == CONFIG_DIR_REQ)
           r_alloc_dir_fsm = ALLOC_DIR_CONFIG;
-    }
-    break;
+        
+        else
+          m_cpt_dir_unused++;
+      }
+      else
+        m_cpt_read_fsm_dir_used++;
+      break;
 
     /////////////////////
@@ -7227,6 +7756,11 @@
         else if(r_read_fsm.read() == READ_DIR_REQ)
           r_alloc_dir_fsm = ALLOC_DIR_READ;
-    }
-    break;
+        
+        else
+          m_cpt_dir_unused++;
+      }
+      else
+        m_cpt_write_fsm_dir_used++;
+      break;
 
     ///////////////////
@@ -7263,5 +7797,10 @@
         else if(r_write_fsm.read() == WRITE_DIR_REQ)
           r_alloc_dir_fsm = ALLOC_DIR_WRITE;
-    }
+        
+        else
+          m_cpt_dir_unused++;
+      }
+      else
+        m_cpt_cas_fsm_dir_used++;
       break;
 
@@ -7287,6 +7826,11 @@
         else if(r_cas_fsm.read() == CAS_DIR_REQ)
           r_alloc_dir_fsm = ALLOC_DIR_CAS;
-    }
-    break;
+
+        else
+          m_cpt_dir_unused++;
+      }
+      else
+        m_cpt_cleanup_fsm_dir_used++;
+      break;
 
     ////////////////////////
@@ -7310,6 +7854,11 @@
         else if(r_cleanup_fsm.read() == CLEANUP_DIR_REQ)
           r_alloc_dir_fsm = ALLOC_DIR_CLEANUP;
-    }
-    break;
+
+        else
+          m_cpt_dir_unused++;
+      }
+      else
+        m_cpt_xram_rsp_fsm_dir_used++;
+      break;
 
   } // end switch alloc_dir_fsm
@@ -7345,5 +7894,13 @@
                 (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ))
           r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP;
-      }
+
+        else if (r_cleanup_fsm.read() == CLEANUP_IXR_REQ)
+          r_alloc_trt_fsm = ALLOC_TRT_CLEANUP;
+
+        else
+          m_cpt_trt_unused++;
+      }
+      else
+        m_cpt_read_fsm_trt_used++;
       break;
 
@@ -7365,8 +7922,16 @@
                 (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ))
           r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP;
+        
+        else if (r_cleanup_fsm.read() == CLEANUP_IXR_REQ)
+          r_alloc_trt_fsm = ALLOC_TRT_CLEANUP;
 
         else if(r_read_fsm.read() == READ_TRT_LOCK)
           r_alloc_trt_fsm = ALLOC_TRT_READ;
-      }
+
+        else
+          m_cpt_trt_unused++;
+      }
+      else
+        m_cpt_write_fsm_trt_used++;
       break;
 
@@ -7384,4 +7949,7 @@
                 (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ))
           r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP;
+        
+        else if (r_cleanup_fsm.read() == CLEANUP_IXR_REQ)
+          r_alloc_trt_fsm = ALLOC_TRT_CLEANUP;
 
         else if(r_read_fsm.read() == READ_TRT_LOCK)
@@ -7391,5 +7959,10 @@
                 (r_write_fsm.read() == WRITE_BC_TRT_LOCK))
           r_alloc_trt_fsm = ALLOC_TRT_WRITE;
-      }
+
+        else
+          m_cpt_trt_unused++;
+      }
+      else
+        m_cpt_cas_fsm_trt_used++;
       break;
 
@@ -7405,4 +7978,7 @@
             (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ))
           r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP;
+        
+        else if (r_cleanup_fsm.read() == CLEANUP_IXR_REQ)
+          r_alloc_trt_fsm = ALLOC_TRT_CLEANUP;
 
         else if(r_read_fsm.read() == READ_TRT_LOCK)
@@ -7416,5 +7992,10 @@
                 (r_cas_fsm.read() == CAS_BC_TRT_LOCK))
           r_alloc_trt_fsm = ALLOC_TRT_CAS;
-      }
+
+        else
+          m_cpt_trt_unused++;
+      }
+      else
+        m_cpt_xram_rsp_fsm_trt_used++;
       break;
 
@@ -7424,4 +8005,34 @@
           (r_ixr_rsp_fsm.read() != IXR_RSP_TRT_READ))
       {
+        
+        if (r_cleanup_fsm.read() == CLEANUP_IXR_REQ)
+          r_alloc_trt_fsm = ALLOC_TRT_CLEANUP;
+
+        else if(r_read_fsm.read() == READ_TRT_LOCK)
+          r_alloc_trt_fsm = ALLOC_TRT_READ;
+
+        else if((r_write_fsm.read() == WRITE_MISS_TRT_LOCK) ||
+                (r_write_fsm.read() == WRITE_BC_TRT_LOCK))
+          r_alloc_trt_fsm = ALLOC_TRT_WRITE;
+
+        else if((r_cas_fsm.read() == CAS_MISS_TRT_LOCK) ||
+                (r_cas_fsm.read() == CAS_BC_TRT_LOCK))
+          r_alloc_trt_fsm = ALLOC_TRT_CAS;
+
+        else if((r_xram_rsp_fsm.read()  == XRAM_RSP_DIR_LOCK) &&
+                (r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP))
+          r_alloc_trt_fsm = ALLOC_TRT_XRAM_RSP;
+
+        else
+          m_cpt_trt_unused++;
+      }
+      else
+        m_cpt_ixr_fsm_trt_used++;
+      break;
+
+      ////////////////////////
+    case ALLOC_TRT_CLEANUP:
+      if(r_ixr_rsp_fsm.read() != CLEANUP_IXR_REQ)
+      {
         if(r_read_fsm.read() == READ_TRT_LOCK)
           r_alloc_trt_fsm = ALLOC_TRT_READ;
@@ -7438,4 +8049,8 @@
                 (r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP))
           r_alloc_trt_fsm = ALLOC_TRT_XRAM_RSP;
+
+        else if((r_ixr_rsp_fsm.read() == IXR_RSP_TRT_ERASE) ||
+            (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ))
+          r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP;
       }
       break;
@@ -7488,5 +8103,9 @@
         else if(r_config_fsm.read() == CONFIG_HEAP_REQ)
           r_alloc_heap_fsm = ALLOC_HEAP_CONFIG;
-      }
+        else
+          m_cpt_heap_unused++;
+      }
+      else
+        m_cpt_read_fsm_heap_used++;
       break;
 
@@ -7511,5 +8130,10 @@
         else if(r_read_fsm.read() == READ_HEAP_REQ)
           r_alloc_heap_fsm = ALLOC_HEAP_READ;
-      }
+
+        else
+          m_cpt_heap_unused++;
+      }
+      else
+        m_cpt_write_fsm_heap_used++;
       break;
 
@@ -7534,5 +8158,10 @@
         else if(r_write_fsm.read() == WRITE_UPT_HEAP_LOCK)
           r_alloc_heap_fsm = ALLOC_HEAP_WRITE;
-      }
+
+        else
+          m_cpt_heap_unused++;
+      }
+      else
+        m_cpt_cas_fsm_heap_used++;
       break;
 
@@ -7558,5 +8187,10 @@
         else if(r_cas_fsm.read() == CAS_UPT_HEAP_LOCK)
           r_alloc_heap_fsm = ALLOC_HEAP_CAS;
-      }
+
+        else
+          m_cpt_heap_unused++;
+      }
+      else
+        m_cpt_cleanup_fsm_heap_used++;
       break;
 
@@ -7603,5 +8237,9 @@
         if(r_xram_rsp_fsm.read() == XRAM_RSP_HEAP_REQ)
           r_alloc_heap_fsm = ALLOC_HEAP_XRAM_RSP;
-      }
+        else
+          m_cpt_heap_unused++;
+      }
+      else
+        m_cpt_xram_rsp_fsm_heap_used++;
       break;
 
@@ -7663,8 +8301,28 @@
   ////////////////////////////////////////////////////////////////////////////////////
 
+/*
+  if(cc_receive_to_cleanup_fifo_put)
+  {
+    if(cc_receive_to_cleanup_fifo_get)
+    {
+      m_cc_receive_to_cleanup_fifo.put_and_get( ( (uint64_t)(p_dspin_in.eop.read() & 0x1 ) << 32 ) | p_dspin_in.data.read());
+    }
+    else // TODO PAS METTRE 32 en DUR !!!!
+    {
+      m_cc_receive_to_cleanup_fifo.simple_put( ( (uint64_t)(p_dspin_in.eop.read() & 0x1 ) << 32 ) | p_dspin_in.data.read());
+      //m_cc_receive_to_cleanup_fifo.simple_put(p_dspin_in.data.read());
+    }
+  }
+  else
+  {
+    if(cc_receive_to_cleanup_fifo_get)
+    {
+      m_cc_receive_to_cleanup_fifo.simple_get();
+    }
+  }
+*/
   m_cc_receive_to_cleanup_fifo.update( cc_receive_to_cleanup_fifo_get,
                                        cc_receive_to_cleanup_fifo_put, 
-                                       p_dspin_in.data.read() );
-
+                                       ( (uint64_t)(p_dspin_in.eop.read() & 0x1 ) << 32 ) | p_dspin_in.data.read() );
   ////////////////////////////////////////////////////////////////////////////////////
   //    CC_RECEIVE to MULTI_ACK FIFO
@@ -7814,4 +8472,26 @@
     p_vci_ixr.trdid     = r_xram_rsp_to_ixr_cmd_trdid.read();
     p_vci_ixr.eop       = (r_ixr_cmd_cpt == (m_words-2));
+  } 
+  /*ODCCP*/
+  else if (r_ixr_cmd_fsm.read() == IXR_CMD_CLEANUP_DATA)
+  {
+    p_vci_ixr.cmd     = vci_param_ext::CMD_WRITE;
+    p_vci_ixr.cmdval  = true;
+    p_vci_ixr.address = (addr_t)((r_cleanup_to_ixr_cmd_nline.read() * m_words + 
+                                    r_ixr_cmd_cpt.read()) * 4);
+    
+    if(r_cleanup_to_ixr_cmd_l1_dirty_ncc.read()) // if cleanup data contains data, we use cleanup_data buffer (cleanup dirty)
+    {
+      p_vci_ixr.wdata   = ((wide_data_t)(r_cleanup_to_ixr_cmd_data[r_ixr_cmd_cpt.read()].read()) | 
+          ((wide_data_t)(r_cleanup_to_ixr_cmd_data[r_ixr_cmd_cpt.read() + 1].read()) << 32));
+    }
+    else // if cleanup data doesnt contain data, we use xram_rsp_data buffer (cleanup not dirty)
+    {
+      p_vci_ixr.wdata   = ((wide_data_t)(r_xram_rsp_to_ixr_cmd_data[r_ixr_cmd_cpt.read()].read()) | 
+          ((wide_data_t)(r_xram_rsp_to_ixr_cmd_data[r_ixr_cmd_cpt.read() + 1].read()) << 32));
+    }
+
+    p_vci_ixr.trdid   = r_cleanup_to_ixr_cmd_trdid.read();
+    p_vci_ixr.eop     = (r_ixr_cmd_cpt == (m_words - 2));
   }
   else
