Index: branches/ODCCP/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 434)
+++ branches/ODCCP/modules/vci_cc_vcache_wrapper/caba/source/src/vci_cc_vcache_wrapper.cpp	(revision 460)
@@ -32,7 +32,10 @@
 #include "../include/vci_cc_vcache_wrapper.h"
 
-#define DEBUG_DCACHE		1
-#define DEBUG_ICACHE		1
-#define DEBUG_CMD   		0
+#define DEBUG_DCACHE		  1
+#define DEBUG_ICACHE		  1
+#define DEBUG_CLEANUP		  1
+#define INSTRUMENTATION       1
+#define FETCH_ON_WRITE_ENABLE 1
+#define DEBUG_CMD   		  0
 
 namespace soclib {
@@ -89,4 +92,5 @@
         "DCACHE_XTN_IT_INVAL",
         "DCACHE_XTN_DC_FLUSH",
+        "DCACHE_XTN_DC_FLUSH_DATA",
         "DCACHE_XTN_DC_FLUSH_GO",
         "DCACHE_XTN_DC_INVAL_VA",
@@ -94,4 +98,5 @@
         "DCACHE_XTN_DC_INVAL_END",
         "DCACHE_XTN_DC_INVAL_GO",
+        "DCACHE_XTN_DC_INVAL_DATA",
         "DCACHE_XTN_DT_INVAL",
 
@@ -101,4 +106,5 @@
         "DCACHE_MISS_SELECT",
         "DCACHE_MISS_CLEAN",
+        "DCACHE_MISS_DATA",
         "DCACHE_MISS_WAIT",
         "DCACHE_MISS_DATA_UPDT",
@@ -110,4 +116,5 @@
 
         "DCACHE_CC_CHECK",
+        "DCACHE_CC_INVAL_DATA",
         "DCACHE_CC_INVAL",
         "DCACHE_CC_UPDT",
@@ -174,4 +181,5 @@
         "CC_SEND_CLEANUP_1",
         "CC_SEND_CLEANUP_2",
+        "CC_SEND_CLEANUP_DATA_UPDT",
         "CC_SEND_MULTI_ACK",
     };
@@ -353,4 +361,6 @@
       r_dcache_cc_send_way("r_dcache_cc_send_way"),
       r_dcache_cc_send_updt_tab_idx("r_dcache_cc_send_updt_tab_idx"),
+      
+      r_cc_send_data_fifo("r_cc_send_data_fifo", 2),  // ODCCP
 
       r_vci_cmd_fsm("r_vci_cmd_fsm"),
@@ -423,6 +433,11 @@
     r_mmu_release = (uint32_t)(1 << 16) | 0x1;
 
-    r_dcache_in_tlb       = new bool[dcache_ways*dcache_sets];
-    r_dcache_contains_ptd = new bool[dcache_ways*dcache_sets];
+    ////////////////////MODIFIED///////////////////////////////
+    //r_dcache_in_tlb        = new bool[dcache_ways*dcache_sets];
+    //r_dcache_contains_ptd  = new bool[dcache_ways*dcache_sets];
+    dirty_stats            = new bool [dcache_ways*dcache_sets*dcache_words];
+    r_dcache_content_state = new int [dcache_ways*dcache_sets];
+    ///////////////////////////////////////////////////////////
+
 
     SC_METHOD(transition);
@@ -449,6 +464,10 @@
 /////////////////////////////////////
 {
-    delete [] r_dcache_in_tlb;
-    delete [] r_dcache_contains_ptd;
+    ////////////MODIFIED/////////////
+    //delete [] r_dcache_in_tlb;
+    //delete [] r_dcache_contains_ptd;
+    delete [] dirty_stats;
+    delete [] r_dcache_content_state;
+    /////////////////////////////////
 }
 
@@ -479,4 +498,6 @@
     std::cout << "  " << m_drsp << std::endl;
 
+    std::cout << r_iss << std::endl;
+
     std::cout << "  " << icache_fsm_state_str[r_icache_fsm.read()]
               << " | " << dcache_fsm_state_str[r_dcache_fsm.read()]
@@ -561,5 +582,5 @@
 }
 
-/*
+
 ////////////////////////
 tmpl(void)::print_stats()
@@ -568,45 +589,54 @@
     float run_cycles = (float)(m_cpt_total_cycles - m_cpt_frz_cycles);
     std::cout << name() << std::endl
-        << "- CPI                    = " << (float)m_cpt_total_cycles/run_cycles << std::endl
-        << "- READ RATE              = " << (float)m_cpt_read/run_cycles << std::endl
-        << "- WRITE RATE             = " << (float)m_cpt_write/run_cycles << std::endl
-        << "- IMISS_RATE             = " << (float)m_cpt_ins_miss/m_cpt_ins_read << std::endl
-        << "- DMISS RATE             = " << (float)m_cpt_data_miss/(m_cpt_read-m_cpt_unc_read) << std::endl
-        << "- INS MISS COST          = " << (float)m_cost_ins_miss_frz/m_cpt_ins_miss << std::endl
-        << "- DATA MISS COST         = " << (float)m_cost_data_miss_frz/m_cpt_data_miss << std::endl
-        << "- WRITE COST             = " << (float)m_cost_write_frz/m_cpt_write << std::endl
-        << "- UNC COST               = " << (float)m_cost_unc_read_frz/m_cpt_unc_read << std::endl
-        << "- UNCACHED READ RATE     = " << (float)m_cpt_unc_read/m_cpt_read << std::endl
-        << "- CACHED WRITE RATE      = " << (float)m_cpt_write_cached/m_cpt_write << std::endl
-        << "- INS TLB MISS RATE      = " << (float)m_cpt_ins_tlb_miss/m_cpt_ins_tlb_read << std::endl
-        << "- DATA TLB MISS RATE     = " << (float)m_cpt_data_tlb_miss/m_cpt_data_tlb_read << std::endl
-        << "- ITLB MISS COST         = " << (float)m_cost_ins_tlb_miss_frz/m_cpt_ins_tlb_miss << std::endl
-        << "- DTLB MISS COST         = " << (float)m_cost_data_tlb_miss_frz/m_cpt_data_tlb_miss << std::endl
-        << "- ITLB UPDATE ACC COST   = " << (float)m_cost_ins_tlb_update_acc_frz/m_cpt_ins_tlb_update_acc << std::endl
-        << "- DTLB UPDATE ACC COST   = " << (float)m_cost_data_tlb_update_acc_frz/m_cpt_data_tlb_update_acc << std::endl
-        << "- DTLB UPDATE DIRTY COST = " << (float)m_cost_data_tlb_update_dirty_frz/m_cpt_data_tlb_update_dirty << std::endl
-        << "- ITLB HIT IN DCACHE RATE= " << (float)m_cpt_ins_tlb_hit_dcache/m_cpt_ins_tlb_miss << std::endl
-        << "- DTLB HIT IN DCACHE RATE= " << (float)m_cpt_data_tlb_hit_dcache/m_cpt_data_tlb_miss << std::endl
-        << "- DCACHE FROZEN BY ITLB  = " << (float)m_cost_ins_tlb_occup_cache_frz/m_cpt_dcache_frz_cycles << std::endl
-        << "- DCACHE FOR TLB %       = " << (float)m_cpt_tlb_occup_dcache/(m_dcache_ways*m_dcache_sets) << std::endl
-        << "- NB CC BROADCAST        = " << m_cpt_cc_broadcast << std::endl
-        << "- NB CC UPDATE DATA      = " << m_cpt_cc_update_data << std::endl
-        << "- NB CC INVAL DATA       = " << m_cpt_cc_inval_data << std::endl
-        << "- NB CC INVAL INS        = " << m_cpt_cc_inval_ins << std::endl
-        << "- CC BROADCAST COST      = " << (float)m_cost_broadcast_frz/m_cpt_cc_broadcast << std::endl
-        << "- CC UPDATE DATA COST    = " << (float)m_cost_updt_data_frz/m_cpt_cc_update_data << std::endl
-        << "- CC INVAL DATA COST     = " << (float)m_cost_inval_data_frz/m_cpt_cc_inval_data << std::endl
-        << "- CC INVAL INS COST      = " << (float)m_cost_inval_ins_frz/m_cpt_cc_inval_ins << std::endl
-        << "- NB CC CLEANUP DATA     = " << m_cpt_cc_cleanup_data << std::endl
-        << "- NB CC CLEANUP INS      = " << m_cpt_cc_cleanup_ins << std::endl
-        << "- IMISS TRANSACTION      = " << (float)m_cost_imiss_transaction/m_cpt_imiss_transaction << std::endl
-        << "- DMISS TRANSACTION      = " << (float)m_cost_dmiss_transaction/m_cpt_dmiss_transaction << std::endl
-        << "- UNC TRANSACTION        = " << (float)m_cost_unc_transaction/m_cpt_unc_transaction << std::endl
-        << "- WRITE TRANSACTION      = " << (float)m_cost_write_transaction/m_cpt_write_transaction << std::endl
-        << "- WRITE LENGTH           = " << (float)m_length_write_transaction/m_cpt_write_transaction << std::endl
-        << "- ITLB MISS TRANSACTION  = " << (float)m_cost_itlbmiss_transaction/m_cpt_itlbmiss_transaction << std::endl
-        << "- DTLB MISS TRANSACTION  = " << (float)m_cost_dtlbmiss_transaction/m_cpt_dtlbmiss_transaction << std::endl;
+        << "- CPI                     = " << (float)m_cpt_total_cycles/run_cycles << std::endl
+        << "- READ RATE               = " << (float)m_cpt_data_read/run_cycles << std::endl
+        << "- WRITE RATE              = " << (float)m_cpt_data_write/run_cycles << std::endl
+        << "- IMISS_RATE              = " << (float)m_cpt_ins_miss/m_cpt_ins_read << std::endl
+        << "- DMISS RATE              = " << (float)m_cpt_data_miss/(m_cpt_data_read-m_cpt_unc_read) << std::endl
+        << "- INS MISS COST           = " << (float)m_cost_ins_miss_frz/m_cpt_ins_miss << std::endl
+        << "- DATA MISS COST          = " << (float)m_cost_data_miss_frz/m_cpt_data_miss << std::endl
+        << "- WRITE COST              = " << (float)m_cost_write_frz/m_cpt_data_write << std::endl
+        << "- UNC COST                = " << (float)m_cost_unc_read_frz/m_cpt_unc_read << std::endl
+        << "- UNCACHED READ RATE      = " << (float)m_cpt_unc_read/m_cpt_data_read << std::endl
+        << "- CACHED WRITE RATE       = " << (float)m_cpt_write_cached/m_cpt_data_write << std::endl
+        << "- INS TLB MISS RATE       = " << (float)m_cpt_ins_tlb_miss/m_cpt_ins_tlb_read << std::endl
+        << "- DATA TLB MISS RATE      = " << (float)m_cpt_data_tlb_miss/m_cpt_data_tlb_read << std::endl
+        << "- ITLB MISS COST          = " << (float)m_cost_ins_tlb_miss_frz/m_cpt_ins_tlb_miss << std::endl
+        << "- DTLB MISS COST          = " << (float)m_cost_data_tlb_miss_frz/m_cpt_data_tlb_miss << std::endl
+        << "- ITLB UPDATE ACC COST    = " << (float)m_cost_ins_tlb_update_acc_frz/m_cpt_ins_tlb_update_acc << std::endl
+        << "- DTLB UPDATE ACC COST    = " << (float)m_cost_data_tlb_update_acc_frz/m_cpt_data_tlb_update_acc << std::endl
+        << "- DTLB UPDATE DIRTY COST  = " << (float)m_cost_data_tlb_update_dirty_frz/m_cpt_data_tlb_update_dirty << std::endl
+        << "- ITLB HIT IN DCACHE RATE = " << (float)m_cpt_ins_tlb_hit_dcache/m_cpt_ins_tlb_miss << std::endl
+        << "- DTLB HIT IN DCACHE RATE = " << (float)m_cpt_data_tlb_hit_dcache/m_cpt_data_tlb_miss << std::endl
+        //<< "- DCACHE FROZEN BY ITLB   = " << (float)m_cost_ins_tlb_occup_cache_frz/m_cpt_dcache_frz_cycles << std::endl
+        << "- DCACHE FOR TLB %        = " << (float)m_cpt_tlb_occup_dcache/(m_dcache_ways*m_dcache_sets) << std::endl
+        << "- NB CC BROADCAST         = " << m_cpt_cc_broadcast << std::endl
+        << "- NB CC UPDATE DATA       = " << m_cpt_cc_update_dcache << std::endl
+        << "- NB CC INVAL DATA        = " << m_cpt_cc_inval_dcache << std::endl
+        << "- NB CC INVAL INS         = " << m_cpt_cc_inval_icache << std::endl
+        << "- CC BROADCAST COST       = " << (float)m_cost_broadcast_frz/m_cpt_cc_broadcast << std::endl
+        << "- CC UPDATE DATA COST     = " << (float)m_cost_updt_data_frz/m_cpt_cc_update_dcache << std::endl
+        << "- CC INVAL DATA COST      = " << (float)m_cost_inval_data_frz/m_cpt_cc_inval_dcache << std::endl
+        << "- CC INVAL INS COST       = " << (float)m_cost_inval_ins_frz/m_cpt_cc_inval_icache << std::endl
+        << "- NB CC CLEANUP DATA      = " << m_cpt_cc_cleanup_data << std::endl
+        << "- NB CC CLEANUP INS       = " << m_cpt_cc_cleanup_ins << std::endl
+        << "- IMISS TRANSACTION       = " << (float)m_cost_imiss_transaction/m_cpt_imiss_transaction << std::endl
+        << "- DMISS TRANSACTION       = " << (float)m_cost_dmiss_transaction/m_cpt_dmiss_transaction << std::endl
+        << "- UNC TRANSACTION         = " << (float)m_cost_unc_transaction/m_cpt_unc_transaction << std::endl
+        << "- WRITE TRANSACTION       = " << (float)m_cost_write_transaction/m_cpt_write_transaction << std::endl
+        << "- NB WRITE TRANSACTION    = " << m_cpt_write_transaction << std::endl
+        << "- NB WRITE WORDS VCI      = " << m_length_write_transaction << std::endl
+        << "- NB WRITE PROC           = " << m_cpt_data_write << std::endl
+        << "- NB WRITE NCC PROC       = " << m_cpt_data_write_back << std::endl
+        << "- NB WRITE NCC COHERENCE  = " << m_cpt_data_cleanup << std::endl
+        << "- NB CLEANUP DATA DIRTY   = " << m_cpt_data_cleanup_dirty*16 << std::endl
+        << "- NB WORDS DIRTY          = " << m_cpt_words_dirty << std::endl
+        << "- NB WRITE MISS NCC       = " << m_cpt_data_write_miss_ncc << std::endl
+        << "- NB DATA SC              = " << m_cpt_data_sc << std::endl
+        << "- WRITE LENGTH            = " << (float)m_length_write_transaction/m_cpt_write_transaction << std::endl
+        << "- ITLB MISS TRANSACTION   = " << (float)m_cost_itlbmiss_transaction/m_cpt_itlbmiss_transaction << std::endl
+        << "- DTLB MISS TRANSACTION   = " << (float)m_cost_dtlbmiss_transaction/m_cpt_dtlbmiss_transaction << std::endl;
 }
-
+/*
 ////////////////////////
 tmpl(void)::clear_stats()
@@ -733,6 +763,12 @@
         for (size_t i=0 ; i< m_dcache_ways*m_dcache_sets ; i++)
         {
-            r_dcache_in_tlb[i]       = false;
-            r_dcache_contains_ptd[i] = false;
+            // MODIFIED
+            //r_dcache_in_tlb[i]        = false;
+            //r_dcache_contains_ptd[i]  = false;
+            r_dcache_content_state[i] = LINE_CACHE_DATA_NOT_DIRTY;
+        }
+        for (size_t i=0; i<m_dcache_ways*m_dcache_sets*m_dcache_words; i++)
+        {
+            dirty_stats[i] = false;
         }
 
@@ -740,4 +776,5 @@
         r_vci_rsp_fifo_icache.init();
         r_vci_rsp_fifo_dcache.init();
+        r_cc_send_data_fifo.init();
 
         // ICACHE & DCACHE activated
@@ -799,95 +836,112 @@
         m_debug_activated	       = false;
 
+        // SPECIAL REGISTERS ODCCP
+        r_dcache_cc_cleanup_updt_data        = false;
+        r_dcache_miss_victim_no_coherence    = false;
+        r_dcache_line_no_coherence           = false;
+        r_dcache_miss_no_coherent            = false;
+        r_vci_rsp_read_data_miss_no_coherent = false;
+        r_cc_send_cpt_word                   = 0;
+        r_dcache_miss_data_cpt               = 0;
+        r_dcache_miss_data_addr              = 0;
+
         // activity counters
-        m_cpt_dcache_data_read  = 0;
-        m_cpt_dcache_data_write = 0;
-        m_cpt_dcache_dir_read   = 0;
-        m_cpt_dcache_dir_write  = 0;
-        m_cpt_icache_data_read  = 0;
-        m_cpt_icache_data_write = 0;
-        m_cpt_icache_dir_read   = 0;
-        m_cpt_icache_dir_write  = 0;
-
-        m_cpt_frz_cycles        = 0;
-        m_cpt_total_cycles      = 0;
-        m_cpt_stop_simulation   = 0;
-
-        m_cpt_data_miss         = 0;
-        m_cpt_ins_miss          = 0;
-        m_cpt_unc_read          = 0;
-        m_cpt_write_cached      = 0;
-        m_cpt_ins_read          = 0;
-
-        m_cost_write_frz        = 0;
-        m_cost_data_miss_frz    = 0;
-        m_cost_unc_read_frz     = 0;
-        m_cost_ins_miss_frz     = 0;
-
-        m_cpt_imiss_transaction = 0;
-        m_cpt_dmiss_transaction = 0;
-        m_cpt_unc_transaction   = 0;
-        m_cpt_write_transaction = 0;
-        m_cpt_icache_unc_transaction = 0;
-
-        m_cost_imiss_transaction      = 0;
-        m_cost_dmiss_transaction      = 0;
-        m_cost_unc_transaction        = 0;
-        m_cost_write_transaction      = 0;
-        m_cost_icache_unc_transaction = 0;
-        m_length_write_transaction    = 0;
-
-        m_cpt_ins_tlb_read       = 0;
-        m_cpt_ins_tlb_miss       = 0;
-        m_cpt_ins_tlb_update_acc = 0;
-
-        m_cpt_data_tlb_read         = 0;
-        m_cpt_data_tlb_miss         = 0;
-        m_cpt_data_tlb_update_acc   = 0;
-        m_cpt_data_tlb_update_dirty = 0;
-        m_cpt_ins_tlb_hit_dcache    = 0;
-        m_cpt_data_tlb_hit_dcache   = 0;
-        m_cpt_ins_tlb_occup_cache   = 0;
-        m_cpt_data_tlb_occup_cache  = 0;
-
-        m_cost_ins_tlb_miss_frz          = 0;
-        m_cost_data_tlb_miss_frz         = 0;
-        m_cost_ins_tlb_update_acc_frz    = 0;
-        m_cost_data_tlb_update_acc_frz   = 0;
-        m_cost_data_tlb_update_dirty_frz = 0;
-        m_cost_ins_tlb_occup_cache_frz   = 0;
-        m_cost_data_tlb_occup_cache_frz  = 0;
-
-    	m_cpt_ins_tlb_inval       = 0;
-    	m_cpt_data_tlb_inval      = 0;
-    	m_cost_ins_tlb_inval_frz  = 0;
-    	m_cost_data_tlb_inval_frz = 0;
-
-        m_cpt_cc_broadcast   = 0;
-
-   	    m_cost_updt_data_frz  = 0;
-   	    m_cost_inval_ins_frz  = 0;
-   	    m_cost_inval_data_frz = 0;
-   	    m_cost_broadcast_frz  = 0;
-
-   	    m_cpt_cc_cleanup_data = 0;
-   	    m_cpt_cc_cleanup_ins  = 0;
-
-        m_cpt_itlbmiss_transaction      = 0;
-        m_cpt_itlb_ll_transaction       = 0;
-        m_cpt_itlb_sc_transaction       = 0;
-        m_cpt_dtlbmiss_transaction      = 0;
-        m_cpt_dtlb_ll_transaction       = 0;
-        m_cpt_dtlb_sc_transaction       = 0;
-        m_cpt_dtlb_ll_dirty_transaction = 0;
-        m_cpt_dtlb_sc_dirty_transaction = 0;
-
-        m_cost_itlbmiss_transaction      = 0;
-        m_cost_itlb_ll_transaction       = 0;
-        m_cost_itlb_sc_transaction       = 0;
-        m_cost_dtlbmiss_transaction      = 0;
-        m_cost_dtlb_ll_transaction       = 0;
-        m_cost_dtlb_sc_transaction       = 0;
-        m_cost_dtlb_ll_dirty_transaction = 0;
-        m_cost_dtlb_sc_dirty_transaction = 0;
+        m_cpt_dcache_data_read            = 0;
+        m_cpt_dcache_data_write           = 0;
+        m_cpt_dcache_dir_read             = 0;
+        m_cpt_dcache_dir_write            = 0;
+        m_cpt_icache_data_read            = 0;
+        m_cpt_icache_data_write           = 0;
+        m_cpt_icache_dir_read             = 0;
+        m_cpt_icache_dir_write            = 0;
+
+        m_cpt_frz_cycles                  = 0;
+        m_cpt_total_cycles                = 0;
+        m_cpt_stop_simulation             = 0;
+
+        m_cpt_data_miss                   = 0;
+        m_cpt_data_write                  = 0;
+        m_cpt_data_sc                     = 0;
+        m_cpt_data_write_back             = 0;
+        m_cpt_data_write_miss_ncc         = 0;
+        m_cpt_data_cleanup                = 0;
+        m_cpt_data_cleanup_dirty          = 0;
+        m_cpt_words_dirty                 = 0;
+        m_cpt_ins_miss                    = 0;
+        m_cpt_unc_read                    = 0;
+        m_cpt_write_cached                = 0;
+        m_cpt_ins_read                    = 0;
+
+        m_cost_write_frz                  = 0;
+        m_cost_data_miss_frz              = 0;
+        m_cost_unc_read_frz               = 0;
+        m_cost_ins_miss_frz               = 0;
+
+        m_cpt_imiss_transaction           = 0;
+        m_cpt_dmiss_transaction           = 0;
+        m_cpt_unc_transaction             = 0;
+        m_cpt_write_transaction           = 0;
+        m_cpt_icache_unc_transaction      = 0;
+
+        m_cost_imiss_transaction          = 0;
+        m_cost_dmiss_transaction          = 0;
+        m_cost_unc_transaction            = 0;
+        m_cost_write_transaction          = 0;
+        m_cost_icache_unc_transaction     = 0;
+        m_length_write_transaction        = 0;
+
+        m_cpt_ins_tlb_read                = 0;
+        m_cpt_ins_tlb_miss                = 0;
+        m_cpt_ins_tlb_update_acc          = 0;
+
+        m_cpt_data_tlb_read               = 0;
+        m_cpt_data_tlb_miss               = 0;
+        m_cpt_data_tlb_update_acc         = 0;
+        m_cpt_data_tlb_update_dirty       = 0;
+        m_cpt_ins_tlb_hit_dcache          = 0;
+        m_cpt_data_tlb_hit_dcache         = 0;
+        m_cpt_ins_tlb_occup_cache         = 0;
+        m_cpt_data_tlb_occup_cache        = 0;
+
+        m_cost_ins_tlb_miss_frz           = 0;
+        m_cost_data_tlb_miss_frz          = 0;
+        m_cost_ins_tlb_update_acc_frz     = 0;
+        m_cost_data_tlb_update_acc_frz    = 0;
+        m_cost_data_tlb_update_dirty_frz  = 0;
+        m_cost_ins_tlb_occup_cache_frz    = 0;
+        m_cost_data_tlb_occup_cache_frz   = 0;
+
+        m_cpt_ins_tlb_inval               = 0;
+        m_cpt_data_tlb_inval              = 0;
+        m_cost_ins_tlb_inval_frz          = 0;
+        m_cost_data_tlb_inval_frz         = 0;
+
+        m_cpt_cc_broadcast                = 0;
+
+        m_cost_updt_data_frz              = 0;
+        m_cost_inval_ins_frz              = 0;
+        m_cost_inval_data_frz             = 0;
+        m_cost_broadcast_frz              = 0;
+
+        m_cpt_cc_cleanup_data             = 0;
+        m_cpt_cc_cleanup_ins              = 0;
+
+        m_cpt_itlbmiss_transaction        = 0;
+        m_cpt_itlb_ll_transaction         = 0;
+        m_cpt_itlb_sc_transaction         = 0;
+        m_cpt_dtlbmiss_transaction        = 0;
+        m_cpt_dtlb_ll_transaction         = 0;
+        m_cpt_dtlb_sc_transaction         = 0;
+        m_cpt_dtlb_ll_dirty_transaction   = 0;
+        m_cpt_dtlb_sc_dirty_transaction   = 0;
+
+        m_cost_itlbmiss_transaction       = 0;
+        m_cost_itlb_ll_transaction        = 0;
+        m_cost_itlb_sc_transaction        = 0;
+        m_cost_dtlbmiss_transaction       = 0;
+        m_cost_dtlb_ll_transaction        = 0;
+        m_cost_dtlb_sc_transaction        = 0;
+        m_cost_dtlb_ll_dirty_transaction  = 0;
+        m_cost_dtlb_sc_dirty_transaction  = 0;
 /*
         m_cpt_dcache_frz_cycles = 0;
@@ -910,4 +964,8 @@
         return;
     }
+    /*ODDCP*/
+
+    /*std::cout << "r_dcache_cc_send_req = " << r_dcache_cc_send_req.read() << std::endl;
+    std::cout << "r_icache_cc_send_req = " << r_icache_cc_send_req.read() << std::endl;*/
 
     // Response FIFOs default values
@@ -919,4 +977,9 @@
     bool       vci_rsp_fifo_dcache_put   = false;
     uint32_t   vci_rsp_fifo_dcache_data  = 0;
+
+    // FIFO for cleanup data updt
+    bool       cleanup_data_updt_fifo_dcache_get   = false;
+    bool       cleanup_data_updt_fifo_dcache_put   = false;
+    uint32_t   cleanup_data_updt_fifo_dcache_data  = 0;
 
     // updt fifo
@@ -928,10 +991,10 @@
 
 #ifdef INSTRUMENTATION
-    m_cpt_fsm_dcache  [r_dcache_fsm.read() ] ++;
-    m_cpt_fsm_icache  [r_icache_fsm.read() ] ++;
-    m_cpt_fsm_cmd     [r_vci_cmd_fsm.read()] ++;
-    m_cpt_fsm_rsp     [r_vci_rsp_fsm.read()] ++;
-    m_cpt_fsm_tgt     [r_tgt_fsm.read()    ] ++;
-    m_cpt_fsm_cleanup [r_cleanup_cmd_fsm.read()] ++;
+    m_cpt_fsm_dcache     [r_dcache_fsm.read()    ] ++;
+    m_cpt_fsm_icache     [r_icache_fsm.read()    ] ++;
+    m_cpt_fsm_cmd        [r_vci_cmd_fsm.read()   ] ++;
+    m_cpt_fsm_rsp        [r_vci_rsp_fsm.read()   ] ++;
+    m_cpt_fsm_cc_send    [r_cc_send_fsm.read()   ] ++;
+    m_cpt_fsm_cc_receive [r_cc_receive_fsm.read()] ++;
 #endif
 
@@ -1015,5 +1078,5 @@
     {
         // coherence interrupt
-        if ( r_cc_receive_icache_req.read() )
+        if ( r_cc_receive_icache_req.read())
         {
             r_icache_fsm = ICACHE_CC_CHECK;
@@ -1084,4 +1147,5 @@
 
             // We register processor request
+            ///*ODCCP*/ std::cout << "DEBUG IREQ.ADDR = " << std::hex << m_ireq.addr << std::dec << " | on " << name() << std::endl;
             r_icache_vaddr_save = m_ireq.addr;
 
@@ -1091,5 +1155,5 @@
 
 #ifdef INSTRUMENTATION
-m_cpt_itlb_read++;
+m_cpt_ins_tlb_read++;
 #endif
                 tlb_hit = r_itlb.translate( m_ireq.addr,
@@ -1166,5 +1230,5 @@
 
 #ifdef INSTRUMENTATION
-m_cpt_itlb_miss++;
+m_cpt_ins_tlb_miss++;
 #endif
                     r_icache_fsm          = ICACHE_TLB_WAIT;
@@ -1184,5 +1248,5 @@
 
 #ifdef INSTRUMENTATION
-m_cpt_icache_miss++;
+m_cpt_ins_miss++;
 #endif
                     // we request a VCI transaction
@@ -1309,5 +1373,5 @@
                                &state );
 
-            if ( state == CACHE_SLOT_STATE_VALID )    // inval required
+            if ( state == CACHE_SLOT_STATE_VALID_CC )    // inval required
             {
                 // request cleanup
@@ -1390,5 +1454,5 @@
 
 #ifdef INSTRUMENTATION
-m_cpt_itlb_read++;
+m_cpt_ins_tlb_read++;
 #endif
             hit = r_itlb.translate(r_dcache_save_wdata.read(),
@@ -1410,5 +1474,5 @@
 
 #ifdef INSTRUMENTATION
-m_cpt_itlb_miss++;
+m_cpt_ins_tlb_miss++;
 #endif
             r_icache_tlb_miss_req = true;
@@ -1437,5 +1501,5 @@
                           &word);
 
-        if ( state == CACHE_SLOT_STATE_VALID )	// inval to be done
+        if ( state == CACHE_SLOT_STATE_VALID_CC )	// inval to be done
         {
             r_icache_miss_way = way;
@@ -1696,5 +1760,5 @@
                                     r_icache_miss_way.read(),
                                     r_icache_miss_set.read(),
-                                    CACHE_SLOT_STATE_VALID );
+                                    CACHE_SLOT_STATE_VALID_CC );
 #if DEBUG_ICACHE
 if ( m_debug_activated )
@@ -1840,5 +1904,5 @@
             r_icache_cc_set = set;
 
-            if ( state == CACHE_SLOT_STATE_VALID)            // hit
+            if ( state == CACHE_SLOT_STATE_VALID_CC)            // hit
             {
                 // need to update the cache state
@@ -1885,5 +1949,5 @@
 {
     std::cout << "  <PROC " << name()
-              << " ICACHE_CC_INVAL> slot returns to empty state"
+              << " ICACHE_//CC_INVAL> slot returns to empty state"
               << " set = " << r_icache_cc_set.read()
               << " / way = " << r_icache_cc_way.read() << std::endl;
@@ -1894,14 +1958,14 @@
 m_cpt_icache_dir_read++;
 #endif
-        if (r_icache_cc_need_write.read())
-        {
-            r_icache.write_dir( 0,
-	                            r_icache_cc_way.read(),
-	                            r_icache_cc_set.read(),
-                                CACHE_SLOT_STATE_EMPTY );
-            // no need to write in the cache anymore
-            r_icache_cc_need_write = false;
-        }
-
+
+            if (r_icache_cc_need_write.read())
+            {
+                r_icache.write_dir( 0,
+                        r_icache_cc_way.read(),
+                        r_icache_cc_set.read(),
+                        CACHE_SLOT_STATE_EMPTY );
+                // no need to write in the cache anymore
+                r_icache_cc_need_write = false;
+            }
         // multicast acknowledgement
         // send a request to cc_send_fsm
@@ -2001,10 +2065,10 @@
 m_cpt_icache_dir_write++;
 #endif
-        if (r_icache_cc_need_write.read())
-        {
+       if (r_icache_cc_need_write.read())
+       {
             r_icache.write_dir( r_icache_cc_way.read(),
-	                            r_icache_cc_set.read(),
+                                r_icache_cc_set.read(),
                                 CACHE_SLOT_STATE_ZOMBI );
-            // no need to write in the cache anymore
+                // no need to write in the cache anymore
             r_icache_cc_need_write = false;
         }
@@ -2174,5 +2238,5 @@
                                             &tlb_set );
 #ifdef INSTRUMENTATION
-m_cpt_dtlb_read++;
+m_cpt_data_tlb_read++;
 #endif
             }
@@ -2239,6 +2303,5 @@
             size_t way = r_dcache_save_cache_way.read();
             size_t set = r_dcache_save_cache_set.read();
-
-            if ( r_dcache_in_tlb[way*m_dcache_sets+set] )
+            if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_IN_TLB )
             {
                 tlb_inval_required       = true;
@@ -2246,11 +2309,11 @@
 	            r_dcache_tlb_inval_line  = r_dcache_save_paddr.read()>>
                                            (uint32_log2(m_dcache_words<<2));
-	            r_dcache_in_tlb[way*m_dcache_sets+set] = false;
-            }
-            else if ( r_dcache_contains_ptd[way*m_dcache_sets+set] )
+                r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY;
+            }
+            else if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_CONTAINS_PTD )
             {
                 r_itlb.reset();
                 r_dtlb.reset();
-	            r_dcache_contains_ptd[way*m_dcache_sets+set] = false;
+                r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY;
             }
 
@@ -2283,7 +2346,7 @@
                                          r_dcache_save_wdata.read(),
                                          r_dcache_save_cacheable.read() );
-#ifdef INSTRUMENTATION
+/*#ifdef INSTRUMENTATION
 m_cpt_wbuf_write++;
-#endif
+#endif*/
                 if ( not wok ) // miss if write buffer full
                 {
@@ -2588,5 +2651,4 @@
                         if ( not (r_mmu_mode.read() & DATA_CACHE_MASK) ) cacheable = false;
                         else cacheable = tlb_flags.c;
-
                         // access rights checking
                         if ( not tlb_flags.u and (m_dreq.mode == iss_t::MODE_USER))
@@ -2658,17 +2720,34 @@
                             {
 #ifdef INSTRUMENTATION
-m_cpt_dcache_miss++;
-#endif
-                                // request a VCI DMISS transaction
+m_cpt_data_miss++;
+#endif
                                 r_dcache_vci_paddr    = paddr;
                                 r_dcache_vci_miss_req = true;
                                 r_dcache_miss_type    = PROC_MISS;
                                 r_dcache_fsm          = DCACHE_MISS_SELECT;
+                               
+                                /*ODCCP*/ // if tlb's flag cc egal 0 that means line is no coherent 
+                                bool ncc = ((tlb_flags.cc == 0) and (r_mmu_mode.read() & DATA_TLB_MASK));
+
+                                if(ncc)
+                                {
+                                    r_dcache_miss_no_coherent = true;
 #if DEBUG_DCACHE
 if ( m_debug_activated )
 std::cout << "  <PROC " << name() << " DCACHE_IDLE>"
-          << " READ MISS in dcache" 
+          << " READ MISS NCC in dcache" 
           << " / PADDR = " << std::hex << paddr << std::endl;
 #endif
+                                }
+                                else
+                                {
+                                    r_dcache_miss_no_coherent = false;
+#if DEBUG_DCACHE
+if ( m_debug_activated )
+std::cout << "  <PROC " << name() << " DCACHE_IDLE>"
+          << " READ MISS CC in dcache" 
+          << " / PADDR = " << std::hex << paddr << std::endl;
+#endif
+                                }
                             }
                             else if (cache_state == CACHE_SLOT_STATE_ZOMBI ) // pending cleanup
@@ -2765,4 +2844,7 @@
 m_cpt_data_write++;
 #endif
+                            // check if line is ncc or cc.
+                            bool ncc = ((tlb_flags.cc == 0) and (r_mmu_mode.read() & DATA_TLB_MASK));
+
                             // cleaning llsc buffer if address matching
                             if ( paddr == r_dcache_llsc_paddr.read() )
@@ -2770,9 +2852,78 @@
 
                             // response to processor
-                            m_drsp.valid        = true;
-
                             // activating P1 stage
-                            wbuf_request = true;
-                            updt_request = (cache_state == CACHE_SLOT_STATE_VALID);
+                            if( (cache_state != CACHE_SLOT_STATE_ZOMBI) && (cache_state != CACHE_SLOT_STATE_EMPTY) && (cacheable) )
+                            {
+                                m_drsp.valid        = true;
+                                
+                                /*ODCCP*/ // if ncc we write locally the new data
+                                if (ncc)  
+                                {   
+#if DEBUG_DCACHE
+if ( m_debug_activated )
+{
+    std::cout << "  <PROC " << name()
+              << " DCACHE_IDLE> WRITE HIT NCC in dcache" 
+              << " : PADDR = " << std::hex << paddr << std::endl;
+}
+#endif
+                                    m_cpt_data_write_back++;
+                                    wbuf_request = false;
+                                    r_dcache_content_state[cache_way*m_dcache_sets+cache_set] = LINE_CACHE_DATA_DIRTY;
+
+                                    /*STATS DIRTY*/
+                                    dirty_stats[(cache_way * m_dcache_sets + cache_set) * m_dcache_words + cache_word] = true;
+                                    
+                                    updt_request = (cache_state == CACHE_SLOT_STATE_VALID_NCC) or (cache_state == CACHE_SLOT_STATE_VALID_CC);
+
+                                }
+                                else
+                                {
+                                    assert((cache_state != CACHE_SLOT_STATE_VALID_NCC) and "ODCCP/RWT : IMPOSSIBLE STATE NCC HERE !");
+                                    wbuf_request = true;
+                                    updt_request = (cache_state == CACHE_SLOT_STATE_VALID_CC)or(cache_state == CACHE_SLOT_STATE_VALID_NCC);
+                                }
+                            }
+                            /*ODCCP We stall proc when Write NCC on line ZOMBI until line becomes not ZOMBI*/
+                            else if( (cache_state == CACHE_SLOT_STATE_ZOMBI) && (ncc) && (cacheable) )
+                            {
+#if DEBUG_DCACHE
+if ( m_debug_activated )
+{
+    std::cout << "  <PROC " << name()
+              << " DCACHE_IDLE> WRITE NCC on ZOMBI line in dcache" 
+              << " : PADDR = " << std::hex << paddr << std::endl;
+}
+#endif
+                                m_drsp.valid   = false;
+                                r_dcache_fsm   = DCACHE_IDLE;
+                            }
+#if FETCH_ON_WRITE_ENABLE
+                            /*ODCCP*/ // IF Fetch-on-Write is enabled, when a write NCC miss cache L1 fetch the missing line before writting it.
+                            else if( (cache_state == CACHE_SLOT_STATE_EMPTY) && (ncc) && (cacheable) )
+                            {
+#if DEBUG_DCACHE
+if ( m_debug_activated )
+{
+    std::cout << "  <PROC " << name()
+              << " DCACHE_IDLE> WRITE MISS NCC in dcache" 
+              << " : PADDR = " << std::hex << paddr << std::endl;
+}
+#endif
+                                // request a VCI DMISS transaction
+                                r_dcache_vci_paddr    = paddr;
+                                r_dcache_vci_miss_req = true;
+                                r_dcache_miss_type    = PROC_MISS;
+                                r_dcache_fsm          = DCACHE_MISS_SELECT;
+                                m_cpt_data_write_miss_ncc++;
+                                r_dcache_miss_no_coherent = true;
+                            }
+#endif
+                            else
+                            {
+                                m_drsp.valid = true;
+                                wbuf_request = true;
+                                updt_request = (cache_state == CACHE_SLOT_STATE_VALID_CC)or(cache_state == CACHE_SLOT_STATE_VALID_NCC);
+                            }
                         }
                     } // end WRITE
@@ -2867,4 +3018,6 @@
         bool		bypass;
         paddr_t		pte_paddr;
+        
+        //r_dcache.printTrace();
 
         // evaluate bypass in order to skip first level page table access
@@ -2877,9 +3030,10 @@
             bypass = r_dtlb.get_bypass(r_dcache_tlb_vaddr.read(), &ptba);
         }
-
+        
+        
         if ( not bypass )     // Try to read PTE1/PTD1 in dcache
         {
             pte_paddr = (((paddr_t)r_mmu_ptpr.read()) << (INDEX1_NBITS+2)) |
-                        ((((paddr_t)r_dcache_tlb_vaddr.read()) >> PAGE_M_NBITS) << 2);
+                ((((paddr_t)r_dcache_tlb_vaddr.read()) >> PAGE_M_NBITS) << 2);
             r_dcache_tlb_paddr = pte_paddr;
             r_dcache_fsm       = DCACHE_TLB_PTE1_GET;
@@ -2888,5 +3042,5 @@
         {
             pte_paddr = (paddr_t)ptba << PAGE_K_NBITS |
-                        (paddr_t)(r_dcache_tlb_vaddr.read()&PTD_ID2_MASK)>>(PAGE_K_NBITS-3);
+                (paddr_t)(r_dcache_tlb_vaddr.read()&PTD_ID2_MASK)>>(PAGE_K_NBITS-3);
             r_dcache_tlb_paddr = pte_paddr;
             r_dcache_fsm       = DCACHE_TLB_PTE2_GET;
@@ -2903,4 +3057,5 @@
               << " / ptpr  = " << (((paddr_t)r_mmu_ptpr.read()) << (INDEX1_NBITS+2))
               << " / BYPASS = " << bypass
+              << " / PTBA = " << ptba
               << " / PTE_ADR = " << pte_paddr << std::endl;
 }
@@ -2935,5 +3090,7 @@
 m_cpt_dcache_dir_read++;
 #endif
-        if ( cache_state == CACHE_SLOT_STATE_VALID )   // hit in dcache
+        /*ODCCP*/
+        assert((cache_state != CACHE_SLOT_STATE_VALID_NCC) and "DCACHE_TLB_PTE1_GET : IMPOSSIBLE NCC HERE");
+        if ( cache_state == CACHE_SLOT_STATE_VALID_CC )   // hit in dcache
         {
             if ( not (entry & PTE_V_MASK) )	// unmapped
@@ -2972,5 +3129,5 @@
             {
                 // mark the cache line ac containing a PTD
-                r_dcache_contains_ptd[m_dcache_sets*way+set] = true;
+                r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_CONTAINS_PTD;
 
                 // register bypass
@@ -3007,5 +3164,5 @@
             else			//  PTE1 :  we must update the TLB
             {
-                r_dcache_in_tlb[m_icache_sets*way+set] = true;
+                r_dcache_content_state[m_icache_sets*way+set] = LINE_CACHE_IN_TLB;
                 r_dcache_tlb_pte_flags  = entry;
                 r_dcache_tlb_cache_way  = way;
@@ -3065,5 +3222,5 @@
                            &set );
 #ifdef INSTRUMENTATION
-m_cpt_itlb_read++;
+m_cpt_ins_tlb_read++;
 #endif
         }
@@ -3075,5 +3232,5 @@
                            &set );
 #ifdef INSTRUMENTATION
-m_cpt_dtlb_read++;
+m_cpt_data_tlb_read++;
 #endif
         }
@@ -3151,5 +3308,5 @@
                               nline );
 #ifdef INSTRUMENTATION
-m_cpt_itlb_write++;
+m_cpt_ins_tlb_update_acc++;
 #endif
 
@@ -3175,5 +3332,5 @@
                               nline );
 #ifdef INSTRUMENTATION
-m_cpt_dtlb_write++;
+m_cpt_data_tlb_update_acc++;
 #endif
 
@@ -3218,5 +3375,5 @@
 
         uint32_t 	pte_flags;
-        uint32_t 	pte_ppn;
+        uint32_t 	pte_ppn=0;
         size_t   	way;
         size_t   	set;
@@ -3235,5 +3392,7 @@
 m_cpt_dcache_dir_read++;
 #endif
-        if ( cache_state == CACHE_SLOT_STATE_VALID )   // hit in dcache
+        /*ODCCP*/
+        assert((cache_state != CACHE_SLOT_STATE_VALID_NCC) and "DCACHE_TLB_PTE2_GET : IMPOSSIBLE NCC HERE");
+        if (cache_state == CACHE_SLOT_STATE_VALID_CC)    // hit in dcache
         {
             if ( not (pte_flags & PTE_V_MASK) )	// unmapped
@@ -3267,5 +3426,5 @@
             else				// mapped : we must update the TLB
             {
-                r_dcache_in_tlb[m_dcache_sets*way+set] = true;
+                r_dcache_content_state[m_dcache_sets*way+set] = LINE_CACHE_IN_TLB;
                 r_dcache_tlb_pte_flags  = pte_flags;
                 r_dcache_tlb_pte_ppn    = pte_ppn;
@@ -3332,5 +3491,5 @@
                            &set );
 #ifdef INSTRUMENTATION
-m_cpt_itlb_read++;
+m_cpt_ins_tlb_read++;
 #endif
         }
@@ -3342,5 +3501,5 @@
                            &set );
 #ifdef INSTRUMENTATION
-m_cpt_dtlb_read++;
+m_cpt_data_tlb_read++;
 #endif
         }
@@ -3419,5 +3578,5 @@
                               nline );
 #ifdef INSTRUMENTATION
-m_cpt_itlb_write++;
+m_cpt_ins_tlb_update_acc++;
 #endif
 
@@ -3443,5 +3602,5 @@
                               nline );
 #ifdef INSTRUMENTATION
-m_cpt_dtlb_write++;
+m_cpt_data_tlb_update_acc++;
 #endif
 
@@ -3656,5 +3815,5 @@
                                &state );
 
-            if ( state == CACHE_SLOT_STATE_VALID )         // inval required
+            if ( state == CACHE_SLOT_STATE_VALID_CC )         // inval required
             {
                 // request cleanup
@@ -3667,5 +3826,40 @@
                 r_dcache_miss_way     = way;
                 r_dcache_miss_set     = set;
+                r_dcache_cleanup_ncc  = false;
+                r_dcache_cc_cleanup_updt_data = false;
                 r_dcache_fsm          = DCACHE_XTN_DC_FLUSH_GO;
+            }
+            else if ( state == CACHE_SLOT_STATE_VALID_NCC )
+            {
+                // request cleanup
+                r_dcache_cc_send_req   = true;
+                r_dcache_cc_send_nline = tag * m_dcache_sets + set;
+                r_dcache_cc_send_way   = way;
+                r_dcache_cc_send_type  = CC_TYPE_CLEANUP;
+
+                // goes to DCACHE_XTN_DC_FLUSH_GO to inval directory
+                r_dcache_miss_way     = way;
+                r_dcache_miss_set     = set;
+                r_dcache_cleanup_ncc  = true;
+                
+                if (r_dcache_content_state[m_dcache_sets*way+set] == LINE_CACHE_DATA_NOT_DIRTY)
+                {
+                    r_dcache_cc_cleanup_updt_data = false;
+                    r_dcache_fsm          = DCACHE_XTN_DC_FLUSH_GO;
+                }
+                else // if line is dirty we save the data values for send into cleanup data
+                {
+                    r_dcache_xtn_flush_addr_data = (tag * m_dcache_sets + set) * m_dcache_words * 4;
+                    r_dcache_xtn_flush_data_cpt = 0;
+                    r_dcache_cc_cleanup_updt_data = true;
+                    r_dcache_fsm          = DCACHE_XTN_DC_FLUSH_DATA;
+                    
+                    /*STATS DIRTY*/
+                    for (size_t w = 0; w < m_dcache_words; w++)
+                    {
+                       if(dirty_stats[(way * m_dcache_sets + set) * m_dcache_words + w] == true)
+                           m_cpt_words_dirty++;
+                    }
+                }
             }
             else if ( r_dcache_flush_count.read() ==
@@ -3685,4 +3879,35 @@
     }
     ////////////////////////////
+    case DCACHE_XTN_DC_FLUSH_DATA: /*ODCCP*/ // In this state we save data values into cc_send_data_fifo for
+                                             // send cleanup with data
+    {
+        uint32_t rdata;
+        size_t   way;
+        size_t   set;
+        size_t   word;
+        r_dcache.read_neutral(r_dcache_xtn_flush_addr_data.read(),
+                              &rdata,
+                              &way,
+                              &set,
+                              &word);
+        if(r_cc_send_data_fifo.wok())
+        {
+            r_dcache_xtn_flush_addr_data = r_dcache_xtn_flush_addr_data.read() + 4;
+
+            cleanup_data_updt_fifo_dcache_get   = false;
+            cleanup_data_updt_fifo_dcache_put   = true;
+            cleanup_data_updt_fifo_dcache_data  = rdata;
+
+            r_dcache_xtn_flush_data_cpt = r_dcache_xtn_flush_data_cpt + 1;
+            if(r_dcache_xtn_flush_data_cpt.read() == (m_dcache_words - 1))
+            {
+                r_dcache_xtn_flush_data_cpt = 0;
+                r_dcache_fsm = DCACHE_XTN_DC_FLUSH_GO;
+            }
+        }
+        break;
+
+    }
+    ////////////////////////////
     case DCACHE_XTN_DC_FLUSH_GO:    // Switch the cache slot to ZOMBI state
                                     // and reset directory extension.
@@ -3692,6 +3917,5 @@
         size_t set = r_dcache_miss_set.read();
 
-        r_dcache_in_tlb[m_dcache_sets*way+set]       = false;
-        r_dcache_contains_ptd[m_dcache_sets*way+set] = false;
+        r_dcache_content_state[m_dcache_sets*way+set]  = LINE_CACHE_DATA_NOT_DIRTY;
 
 #ifdef INSTRUMENTATION
@@ -3736,5 +3960,5 @@
 
 #ifdef INSTRUMENTATION
-m_cpt_dtlb_read++;
+m_cpt_data_tlb_read++;
 #endif
             hit = r_dtlb.translate( r_dcache_save_wdata.read(),
@@ -3756,5 +3980,5 @@
 
 #ifdef INSTRUMENTATION
-m_cpt_dtlb_miss++;
+m_cpt_data_tlb_miss++;
 #endif
             r_dcache_tlb_ins    = false;		// dtlb
@@ -3793,10 +4017,13 @@
                            &set,
                            &word );
-
-        if ( state == CACHE_SLOT_STATE_VALID )	// inval to be done
-        {
-            r_dcache_xtn_way = way;
-            r_dcache_xtn_set = set;
-            r_dcache_fsm      = DCACHE_XTN_DC_INVAL_GO;
+        /*ODCCP*/
+        if ((state == CACHE_SLOT_STATE_VALID_CC) or (state == CACHE_SLOT_STATE_VALID_NCC))	// inval to be done
+        {
+            r_dcache_xtn_way       = way;
+            r_dcache_xtn_set       = set;
+            r_dcache_xtn_state     = state;
+            r_dcache_xtn_data_addr = r_dcache_save_paddr.read()&~0x3F;
+            r_dcache_fsm           = DCACHE_XTN_DC_INVAL_GO;
+            
         }
         else		// miss : nothing to do
@@ -3812,7 +4039,8 @@
               << " DCACHE_XTN_DC_INVAL_PA> Test hit in dcache" << std::hex
               << " / PADDR = " << r_dcache_save_paddr.read() << std::dec
-              << " / HIT = " << (state == CACHE_SLOT_STATE_VALID)
+              << " / HIT = " << ((state == CACHE_SLOT_STATE_VALID_CC) or (state == CACHE_SLOT_STATE_VALID_NCC))
               << " / SET = " << set
               << " / WAY = " << way << std::endl;
+    //r_dcache.printTrace();
 }
 #endif
@@ -3826,4 +4054,5 @@
         if ( not r_dcache_cc_send_req.read() ) // blocked until previous cc_send request is sent
         {
+            int     state      = r_dcache_xtn_state.read();
             size_t	way        = r_dcache_xtn_way.read();
             size_t	set        = r_dcache_xtn_set.read();
@@ -3833,7 +4062,10 @@
 m_cpt_dcache_dir_write++;
 #endif
-            r_dcache.write_dir( way,
-                                set,
-                                CACHE_SLOT_STATE_ZOMBI );
+            if(state == CACHE_SLOT_STATE_VALID_CC)
+            {
+                r_dcache.write_dir( way,
+                                    set,
+                                    CACHE_SLOT_STATE_ZOMBI );
+            }
 
             // request cleanup
@@ -3842,7 +4074,37 @@
             r_dcache_cc_send_way   = way;
             r_dcache_cc_send_type  = CC_TYPE_CLEANUP;
+            r_dcache_cleanup_ncc   = false;
+
+            /*ODCCP*/
+            if( (state == CACHE_SLOT_STATE_VALID_NCC) /*and (r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_DATA_DIRTY)*/ )
+            {
+                r_dcache_cleanup_ncc   = true;
+                /*ODCCP*/ // If line is dirty we read data values for send cleanup with data
+                if (r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_DATA_DIRTY)
+                {
+                    r_dcache_cc_cleanup_updt_data = true;
+                    r_dcache_fsm = DCACHE_XTN_DC_INVAL_DATA;
+                    m_cpt_data_cleanup_dirty ++;
+                    
+                    /*STATS DIRTY*/
+                    for (size_t w = 0; w < m_dcache_words; w++)
+                    {
+                       if(dirty_stats[(way * m_dcache_sets + set) * m_dcache_words + w] == true)
+                           m_cpt_words_dirty++;
+                    }
+                }
+                else
+                {
+                    r_dcache.write_dir( way,
+                                        set,
+                                        CACHE_SLOT_STATE_ZOMBI );
+                    r_dcache_cc_cleanup_updt_data = false;
+                    r_dcache_fsm = DCACHE_IDLE;
+                    m_drsp.valid = true;
+                }
+            }
 
             // possible itlb & dtlb invalidate
-            if ( r_dcache_in_tlb[way*m_dcache_sets+set] )
+            else if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_IN_TLB )
             {
                 r_dcache_tlb_inval_line = nline;
@@ -3850,11 +4112,11 @@
                 r_dcache_fsm_scan_save  = DCACHE_XTN_DC_INVAL_END;
                 r_dcache_fsm            = DCACHE_INVAL_TLB_SCAN;
-                r_dcache_in_tlb[way*m_dcache_sets+set] = false;
-            }
-            else if ( r_dcache_contains_ptd[way*m_dcache_sets+set] )
+                r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY;
+            }
+            else if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_CONTAINS_PTD)
             {
                 r_itlb.reset();
                 r_dtlb.reset();
-                r_dcache_contains_ptd[way*m_dcache_sets+set] = false;
+                r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY;
                 r_dcache_fsm = DCACHE_IDLE;
                 m_drsp.valid = true;
@@ -3877,4 +4139,42 @@
         break;
     }
+
+    /*ODCCP*/
+    //////////////////////////////
+    case DCACHE_XTN_DC_INVAL_DATA:  	
+    {
+
+        uint32_t rdata;
+        size_t   way;
+        size_t   set;
+        size_t   word;
+        r_dcache.read_neutral(r_dcache_xtn_data_addr.read(),
+                              &rdata,
+                              &way,
+                              &set,
+                              &word);
+        if(r_cc_send_data_fifo.wok())
+        {
+            r_dcache_xtn_data_addr = r_dcache_xtn_data_addr.read() + 4;
+
+            cleanup_data_updt_fifo_dcache_get   = false;
+            cleanup_data_updt_fifo_dcache_put   = true;
+            cleanup_data_updt_fifo_dcache_data  = rdata;
+
+            r_dcache_xtn_data_cpt = r_dcache_xtn_data_cpt.read() + 1;
+            /*ODCCP*/ // after read the last word we set the line as ZOMBI
+            if(r_dcache_xtn_data_cpt.read() == (m_dcache_words - 1))
+            {
+                r_dcache_xtn_data_cpt = 0;
+                r_dcache_fsm = DCACHE_IDLE;
+                r_dcache.write_dir( way,
+                                    set,
+                                    CACHE_SLOT_STATE_ZOMBI );
+                m_drsp.valid = true;
+            }
+        }
+        break;
+    }
+
     //////////////////////////////
     case DCACHE_XTN_DC_INVAL_END:  	// send response to processor XTN request
@@ -3909,4 +4209,5 @@
             size_t   set = 0;
             paddr_t  victim = 0;
+            int state;
 
 #ifdef INSTRUMENTATION
@@ -3919,5 +4220,5 @@
                                   &found,
                                   &cleanup );
-
+            state = r_dcache.get_cache_state(way,set);
             if ( found )
             {
@@ -3934,4 +4235,34 @@
                     r_dcache_cc_send_way   = way;
                     r_dcache_cc_send_type  = CC_TYPE_CLEANUP;
+                    
+                    if( (state == CACHE_SLOT_STATE_VALID_NCC) )
+                    {
+                        r_dcache_cleanup_ncc = true;
+                        
+                        /*ODCCP*/ // if line is dirty we must save the data values
+                        if (r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_DATA_DIRTY)
+                        {
+                            r_dcache_cc_cleanup_updt_data = true;
+                            r_dcache_miss_data_addr = (victim*m_dcache_words)*4;
+                            r_dcache_fsm = DCACHE_MISS_DATA;
+                            m_cpt_data_cleanup_dirty ++;
+                            
+                            /*STATS DIRTY*/
+                            for (size_t w = 0; w < m_dcache_words; w++)
+                            {
+                                if(dirty_stats[(way * m_dcache_sets + set) * m_dcache_words + w] == true)
+                                    m_cpt_words_dirty++;
+                            }
+                        }
+                        else
+                        {
+                            r_dcache_cc_cleanup_updt_data = false;
+                        }
+                    } 
+                    else
+                    {
+                        r_dcache_cc_cleanup_updt_data = false;
+                        r_dcache_cleanup_ncc = false;
+                    }
                 }
                 else
@@ -3957,4 +4288,34 @@
     }
     ///////////////////////
+    case DCACHE_MISS_DATA:
+    {
+        uint32_t rdata;
+        size_t way;
+        size_t set;
+        size_t word;
+
+        r_dcache.read_neutral(r_dcache_miss_data_addr,
+                              &rdata,
+                              &way,
+                              &set,
+                              &word);
+        if(r_cc_send_data_fifo.wok())
+        {
+            r_dcache_miss_data_addr = r_dcache_miss_data_addr.read() + 4;
+
+            cleanup_data_updt_fifo_dcache_get   = false;
+            cleanup_data_updt_fifo_dcache_put   = true;
+            cleanup_data_updt_fifo_dcache_data  = rdata;
+
+            r_dcache_miss_data_cpt = r_dcache_miss_data_cpt.read() + 1;
+            if (r_dcache_miss_data_cpt.read() == m_dcache_words-1 )
+            {
+                r_dcache_miss_data_cpt = 0;
+                r_dcache_fsm = DCACHE_MISS_CLEAN;
+            }
+        }
+        break;
+    }
+    ///////////////////////
     case DCACHE_MISS_CLEAN:		// switch the slot to ZOMBI state
                                 // and possibly request itlb or dtlb invalidate
@@ -3982,7 +4343,7 @@
         // if selective itlb & dtlb invalidate are required
         // the miss response is not handled before invalidate completed
-        if ( r_dcache_in_tlb[way*m_dcache_sets+set] )
-        {
-            r_dcache_in_tlb[way*m_dcache_sets+set] = false;
+        if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_IN_TLB )
+        {
+            r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY;
             r_dcache_tlb_inval_line  = r_dcache_cc_send_nline;
             r_dcache_tlb_inval_set   = 0;
@@ -3990,9 +4351,9 @@
             r_dcache_fsm             = DCACHE_INVAL_TLB_SCAN;
         }
-        else if ( r_dcache_contains_ptd[way*m_dcache_sets+set] )
+        else if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_CONTAINS_PTD )
         {
             r_itlb.reset();
             r_dtlb.reset();
-            r_dcache_contains_ptd[way*m_dcache_sets+set] = false;
+            r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY;
             r_dcache_fsm = DCACHE_MISS_WAIT;
         }
@@ -4145,4 +4506,15 @@
                     r_dcache_cc_send_way   = r_dcache_miss_way.read();
                     r_dcache_cc_send_type  = CC_TYPE_CLEANUP;
+                    
+                    if (r_vci_rsp_read_data_miss_no_coherent.read() == true)
+                    {
+                        r_dcache_cleanup_ncc   = true;
+                        r_dcache_cc_cleanup_updt_data = false;
+                    }
+                    else
+                    {
+                        r_dcache_cleanup_ncc = false;
+                        r_dcache_cc_cleanup_updt_data = false;
+                    }
 
 #ifdef INSTRUMENTATION
@@ -4171,22 +4543,43 @@
 m_cpt_dcache_dir_write++;
 #endif
-                r_dcache.write_dir( r_dcache_save_paddr.read(),
-                                    r_dcache_miss_way.read(),
-                                    r_dcache_miss_set.read(),
-                                    CACHE_SLOT_STATE_VALID );
-
+                size_t way = r_dcache_miss_way.read();
+                size_t set = r_dcache_miss_set.read();
+
+                /*ODCCP*/ // if the read miss is on line NCC we set the state's line as VALID_NCC    
+                if (r_vci_rsp_read_data_miss_no_coherent.read() == true)
+                {
+                    r_dcache.write_dir( r_dcache_save_paddr.read(),
+                                        r_dcache_miss_way.read(),
+                                        r_dcache_miss_set.read(),
+                                        CACHE_SLOT_STATE_VALID_NCC );
+                    r_vci_rsp_read_data_miss_no_coherent = false;
 #if DEBUG_DCACHE
 if ( m_debug_activated )
 std::cout << "  <PROC " << name()
-          << " DCACHE_MISS_DIR_UPDT> Switch slot to VALID state"
+          << " DCACHE_MISS_DIR_UPDT> Switch slot to VALID_NCC state"
           << " PADDR = " << std::hex << r_dcache_save_paddr.read()
           << " / WAY = "   << std::dec << r_dcache_miss_way.read()
           << " / SET = "   << r_dcache_miss_set.read() << std::endl;
 #endif
+                }
+                else
+                {
+                    r_dcache.write_dir( r_dcache_save_paddr.read(),
+                                        r_dcache_miss_way.read(),
+                                        r_dcache_miss_set.read(),
+                                        CACHE_SLOT_STATE_VALID_CC );
+#if DEBUG_DCACHE
+if ( m_debug_activated )
+std::cout << "  <PROC " << name()
+          << " DCACHE_MISS_DIR_UPDT> Switch slot to VALID_CC state"
+          << " PADDR = " << std::hex << r_dcache_save_paddr.read()
+          << " / WAY = "   << std::dec << r_dcache_miss_way.read()
+          << " / SET = "   << r_dcache_miss_set.read() << std::endl;
+#endif
+                }
                 // reset directory extension
-                size_t way = r_dcache_miss_way.read();
-                size_t set = r_dcache_miss_set.read();
-                r_dcache_in_tlb[way*m_dcache_sets+set] = false;
-                r_dcache_contains_ptd[way*m_dcache_sets+set] = false;
+                /*ODCCP*/ // We set the new line as not dirty
+                r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY;
+
             }
             if      (r_dcache_miss_type.read()==PTE1_MISS) r_dcache_fsm = DCACHE_TLB_PTE1_GET;
@@ -4335,5 +4728,5 @@
                        &state );
 
-        assert( (state == CACHE_SLOT_STATE_VALID) and
+        assert( (state == CACHE_SLOT_STATE_VALID_CC) and
         "error in DCACHE_DIRTY_TLB_SET: the PTE should be in dcache" );
 
@@ -4447,5 +4840,12 @@
                                 r_cc_receive_dcache_set.read(),
                                 CACHE_SLOT_STATE_EMPTY);
-
+            
+            /*STATS DIRTY*/
+            for (size_t word = 0; word < m_dcache_words; word++)
+            {
+                dirty_stats[(r_cc_receive_dcache_way * m_dcache_sets + r_cc_receive_dcache_set) * m_dcache_words + word] = false;
+            }
+
+            
             if ( (r_dcache_miss_set.read() == r_cc_receive_dcache_set.read()) and
                  (r_dcache_miss_way.read() == r_cc_receive_dcache_way.read()) )
@@ -4516,11 +4916,17 @@
             r_dcache_cc_way = way;
             r_dcache_cc_set = set;
-
-            if ( state == CACHE_SLOT_STATE_VALID)            // hit
+            /*ODCCP*/
+            if ((state == CACHE_SLOT_STATE_VALID_CC) or (state == CACHE_SLOT_STATE_VALID_NCC))             // hit
             {
                 // need to update the cache state
+                r_dcache_cleanup_ncc = false;
                 r_dcache_cc_need_write = true;
                 if (r_cc_receive_dcache_type.read() == CC_TYPE_UPDT)  // hit update
                 {
+                    /*ODCCP*/ // we can't receive a CC_UPDT on a NCC line
+                    if (state == CACHE_SLOT_STATE_VALID_NCC)
+                        std::cout << "DCACHE_CC_CHECK : IMPOSSIBLE NCC STATE FOR CC_UPDT at cycle " << m_cpt_total_cycles << std::endl;
+                    assert((state != CACHE_SLOT_STATE_VALID_NCC) and "DCACHE_CC_CHECK : IMPOSSIBLE NCC STATE FOR CC_UPDT");
+                    
                     r_dcache_fsm          = DCACHE_CC_UPDT;
                     r_dcache_cc_word      = r_cc_receive_word_idx.read();
@@ -4528,8 +4934,22 @@
                 else if (r_cc_receive_dcache_type.read() == CC_TYPE_INVAL)   // hit inval
                 {
-                    r_dcache_fsm          = DCACHE_CC_INVAL;
+                    if ( (state == CACHE_SLOT_STATE_VALID_NCC) )
+                    {
+                        if (r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_DATA_DIRTY)
+                            m_cpt_data_cleanup_dirty ++;
+                        r_dcache_cc_state           = state;
+                        r_dcache_cc_inval_addr      = (paddr &~0x3F);
+                        r_dcache_cc_inval_data_cpt  = 0;
+                    }
+                    else
+                    {
+                        r_dcache_cc_state           = state;
+                        r_dcache_cc_inval_addr      = (paddr &~0x3F);
+                    }
+                    r_dcache_fsm                = DCACHE_CC_INVAL;
                 }
                 else if ( r_cc_receive_dcache_type.read() == CC_TYPE_BRDCAST)  // hit broadcast
                 {
+                    assert((state != CACHE_SLOT_STATE_VALID_NCC) and "DCACHE_CC_CHECK : IMPOSSIBLE NCC STATE FOR CC_BROADCAST");
                     r_dcache_fsm          = DCACHE_CC_BROADCAST;
                 }
@@ -4559,7 +4979,48 @@
               << " PADDR = " << std::hex << paddr
               << " / TYPE = " << std::dec << r_cc_receive_dcache_type.read()
-              << " / HIT = " << (state == CACHE_SLOT_STATE_VALID) << std::endl;
+              << " / HIT = " << ((state == CACHE_SLOT_STATE_VALID_CC) or (state == CACHE_SLOT_STATE_VALID_NCC)) << std::endl;
 }
 #endif
+        }
+        break;
+    }
+    /////////////////////
+    case DCACHE_CC_INVAL_DATA:
+    {
+        uint32_t rdata;
+        size_t   way;
+        size_t   set;
+        size_t   word;
+        r_dcache.read_neutral(r_dcache_cc_inval_addr.read(),
+                              &rdata,
+                              &way,
+                              &set,
+                              &word);
+        if(r_cc_send_data_fifo.wok())
+        {
+            r_dcache_cc_inval_addr = r_dcache_cc_inval_addr.read() + 4;
+
+            cleanup_data_updt_fifo_dcache_get   = false;
+            cleanup_data_updt_fifo_dcache_put   = true;
+            cleanup_data_updt_fifo_dcache_data  = rdata;
+
+            r_dcache_cc_inval_data_cpt = r_dcache_cc_inval_data_cpt.read() + 1;
+            /*ODCCP*/ // After reading the last word we switch slot to ZOMBI state
+            if(r_dcache_cc_inval_data_cpt.read() == (m_dcache_words - 1))
+            {
+                r_dcache_fsm = r_dcache_fsm_cc_save.read();
+                r_dcache.write_dir( way,
+                                    set,
+                                    CACHE_SLOT_STATE_ZOMBI );
+#if DEBUG_DCACHE
+                if ( m_debug_activated )
+                {
+                    std::cout << "  <PROC " << name()
+                        << " DCACHE_CC_INVAL_DATA> Switch slot to ZOMBI state:" << std::dec
+                        << " / WAY = " << way
+                        << " / SET = " << set << std::endl;
+                }
+#endif
+            }
         }
         break;
@@ -4571,10 +5032,10 @@
         size_t	 way    = r_dcache_cc_way.read();
         size_t	 set    = r_dcache_cc_set.read();
-
+        int      state  = r_dcache_cc_state.read();
         if (r_dcache_cc_need_write.read())
         {
-            if ( r_dcache_in_tlb[way*m_dcache_sets+set] ) 			// selective TLB inval
-            {
-                r_dcache_in_tlb[way*m_dcache_sets+set] = false;
+            if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_IN_TLB )
+            {
+                r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY;
                 r_dcache_tlb_inval_line  = r_cc_receive_dcache_nline.read();
                 r_dcache_tlb_inval_set   = 0;
@@ -4585,50 +5046,86 @@
             else
             {
-                if ( r_dcache_contains_ptd[way*m_dcache_sets+set] ) 	// TLB flush
+                if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_CONTAINS_PTD )
                 {
                     r_itlb.reset();
                     r_dtlb.reset();
-                    r_dcache_contains_ptd[way*m_dcache_sets+set] = false;
+                    r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY;
 
 #if DEBUG_DCACHE
-if ( m_debug_activated )
-{
-    std::cout << "  <PROC " << name()
-              << " DCACHE_CC_INVAL> Flush DTLB & ITLB" << std::endl;
-}
-#endif
-                }
-
-                r_dcache.write_dir( 0,
-                                    way,
-                                    set,
-                                    CACHE_SLOT_STATE_EMPTY );
-
+                    if ( m_debug_activated )
+                    {
+                        std::cout << "  <PROC " << name()
+                            << " DCACHE_CC_INVAL> Flush DTLB & ITLB" << std::endl;
+                    }
+#endif
+                }
+
+                if ( state == CACHE_SLOT_STATE_VALID_CC )
+                {
+                    r_dcache.write_dir( 0,
+                            way,
+                            set,
+                            CACHE_SLOT_STATE_EMPTY );
+#if DEBUG_DCACHE
+                    if ( m_debug_activated )
+                    {
+                        std::cout << "  <PROC " << name()
+
+                            << " DCACHE_CC_INVAL> Switch slot to EMPTY state:" << std::dec
+                            << " / WAY = " << way
+                            << " / SET = " << set << std::endl;
+                    }
+#endif
+                }
                 r_dcache_cc_need_write = false;
 
-#if DEBUG_DCACHE
-if ( m_debug_activated )
-{
-    std::cout << "  <PROC " << name()
-              << " DCACHE_CC_INVAL> Switch slot to EMPTY state:" << std::dec
-              << " / WAY = " << way
-              << " / SET = " << set << std::endl;
-}
-#endif
-            }
-        }
+            }
+        }
+
         // multicast acknowledgement
         // send a request to cc_send_fsm
         if(not r_dcache_cc_send_req.read()) // cc_send is available
         {
+
             // 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();
+
+            
+            if ( (state == CACHE_SLOT_STATE_VALID_NCC) )
+            {
+                r_dcache_cleanup_ncc = true;
+                r_dcache_cc_send_type = CC_TYPE_CLEANUP;
+                r_dcache_cc_send_way = way;
+                
+                if (r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_DATA_DIRTY)
+                {
+                    r_dcache_cc_cleanup_updt_data = true;
+                    r_dcache_fsm = DCACHE_CC_INVAL_DATA;
+                    
+                    /*STATS DIRTY*/
+                    for (size_t w = 0; w < m_dcache_words; w++)
+                    {
+                       if(dirty_stats[(way * m_dcache_sets + set) * m_dcache_words + w] == true)
+                           m_cpt_words_dirty++;
+                    }
+                }
+                else
+                {
+                    r_dcache_cc_cleanup_updt_data = false;
+                    r_dcache.write_dir( way,
+                                        set,
+                                        CACHE_SLOT_STATE_ZOMBI );
+                    r_dcache_fsm = r_dcache_fsm_cc_save.read();
+                }
+            }
+            else
+            {
+                // request multicast acknowledgement
+                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();
+            }
         }
         //else wait for previous cc_send request to be sent
@@ -4647,7 +5144,8 @@
             if (r_dcache_cc_need_write.read())
             {
-                if ( r_dcache_in_tlb[way*m_dcache_sets+set] ) 			// selective TLB inval
-                {
-                    r_dcache_in_tlb[way*m_dcache_sets+set] = false;
+                // selective TLB inval
+                if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_IN_TLB )
+                {
+                    r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY;
                     r_dcache_tlb_inval_line  = r_cc_receive_dcache_nline.read();
                     r_dcache_tlb_inval_set   = 0;
@@ -4656,10 +5154,10 @@
                     break;
                 }
-
-                if ( r_dcache_contains_ptd[way*m_dcache_sets+set] ) 	// TLB flush
+                // TLB flush
+                if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_CONTAINS_PTD )
                 {
                     r_itlb.reset();
                     r_dtlb.reset();
-                    r_dcache_contains_ptd[way*m_dcache_sets+set] = false;
+                    r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY;
 
 #if DEBUG_DCACHE
@@ -4739,7 +5237,8 @@
         if (r_dcache_cc_need_write.read())
         {
-            if ( r_dcache_in_tlb[way*m_dcache_sets+set] ) 			// selective TLB inval
-            {
-                r_dcache_in_tlb[way*m_dcache_sets+set] = false;
+            // selective TLB inval
+            if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_IN_TLB )
+            {
+                r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY;
                 r_dcache_tlb_inval_line  = nline;
                 r_dcache_tlb_inval_set   = 0;
@@ -4750,35 +5249,36 @@
             else
             {
-                if ( r_dcache_contains_ptd[way*m_dcache_sets+set] ) 	// TLB flush
+            	// TLB flush
+                if ( r_dcache_content_state[way*m_dcache_sets+set] == LINE_CACHE_CONTAINS_PTD )
                 {
                     r_itlb.reset();
                     r_dtlb.reset();
-                    r_dcache_contains_ptd[way*m_dcache_sets+set] = false;
+                    r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY;
 
 #if DEBUG_DCACHE
-if ( m_debug_activated )
-{
-    std::cout << "  <PROC " << name()
-              << " DCACHE_CC_BROADCAST> Flush DTLB & ITLB" << std::endl;
-}
+                    if ( m_debug_activated )
+                    {
+                        std::cout << "  <PROC " << name()
+                            << " DCACHE_CC_BROADCAST> Flush DTLB & ITLB" << std::endl;
+                    }
 #endif
                 }
 
 #ifdef INSTRUMENTATION
-m_cpt_dcache_dir_write++;
+                m_cpt_dcache_dir_write++;
 #endif
                 r_dcache.write_dir( way,
-                                    set,
-                                    CACHE_SLOT_STATE_ZOMBI );
+                        set,
+                        CACHE_SLOT_STATE_ZOMBI );
 
                 r_dcache_cc_need_write = false;
 #if DEBUG_DCACHE
-if ( m_debug_activated )
-{
-    std::cout << "  <PROC " << name()
-              << " DCACHE_CC_BROADCAST > Slot goes to ZOMBI state "
-              << " SET = " << set
-              << " / WAY = " << way << std::endl;
-}
+                if ( m_debug_activated )
+                {
+                    std::cout << "  <PROC " << name()
+                        << " DCACHE_CC_BROADCAST > Slot goes to ZOMBI state "
+                        << " SET = " << set
+                        << " / WAY = " << way << std::endl;
+                }
 #endif
             }
@@ -4969,5 +5469,4 @@
                         r_dcache_vci_unc_req.read())
                      or r_vci_cmd_imiss_prio.read() );
-
             // 1 - Data Read Miss
             if ( dcache_miss_req and r_wbuf.miss(r_dcache_vci_paddr.read()) )
@@ -4976,5 +5475,5 @@
                 r_dcache_vci_miss_req = false;
                 r_vci_cmd_imiss_prio  = true;
-//                m_cpt_dmiss_transaction++;
+                m_cpt_dmiss_transaction++;
             }
             // 2 - Data Read Uncachable
@@ -4983,5 +5482,5 @@
                 r_vci_cmd_fsm        = CMD_DATA_UNC;
                 r_dcache_vci_unc_req = false;
-//                m_cpt_dunc_transaction++;
+                //m_cpt_dunc_transaction++;
             }
             // 3 - Data Linked Load
@@ -4990,5 +5489,5 @@
                 r_dcache_vci_ll_req = false;
                 r_vci_cmd_fsm       = CMD_DATA_LL;
-//              m_cpt_ll_transaction++;
+                //m_cpt_ll_transaction++;
             }
             // 4 - Instruction Miss
@@ -4998,5 +5497,5 @@
                 r_icache_miss_req    = false;
                 r_vci_cmd_imiss_prio = false;
-//                m_cpt_imiss_transaction++;
+                m_cpt_imiss_transaction++;
             }
             // 5 - Instruction Uncachable
@@ -5005,5 +5504,5 @@
                 r_vci_cmd_fsm       = CMD_INS_UNC;
                 r_icache_unc_req    = false;
-//                m_cpt_iunc_transaction++;
+                //m_cpt_iunc_transaction++;
             }
             // 6 - Data Write
@@ -5014,6 +5513,6 @@
                 r_vci_cmd_min       = wbuf_min;
                 r_vci_cmd_max       = wbuf_max;
-//                m_cpt_write_transaction++;
-//                m_length_write_transaction += (wbuf_max-wbuf_min+1);
+                m_cpt_write_transaction++;
+                m_length_write_transaction += (wbuf_max-wbuf_min+1);
             }
             // 7 - Data Store Conditionnal
@@ -5023,5 +5522,5 @@
                 r_vci_cmd_cpt  = 0;
                 r_vci_cmd_fsm  = CMD_DATA_SC;
-//              m_cpt_sc_transaction++;
+                //m_cpt_sc_transaction++;
             }
             // 8 - Compare And Swap
@@ -5031,5 +5530,5 @@
                 r_dcache_vci_cas_req = false;
                 r_vci_cmd_cpt        = 0;
-//              m_cpt_cas_transaction++;
+                //m_cpt_cas_transaction++;
             }
 
@@ -5074,5 +5573,4 @@
         case CMD_INS_MISS:
         case CMD_INS_UNC:
-        case CMD_DATA_MISS:
         case CMD_DATA_UNC:
         case CMD_DATA_LL:
@@ -5080,4 +5578,14 @@
             // all read VCI commands contain one single flit
             if ( p_vci.cmdack.read() ) {
+                r_vci_cmd_fsm = CMD_IDLE;
+            }
+            break;
+        }
+
+        case CMD_DATA_MISS:
+        {
+            // all read VCI commands contain one single flit
+            if ( p_vci.cmdack.read() ) {
+                r_dcache_miss_no_coherent = false;
                 r_vci_cmd_fsm = CMD_IDLE;
             }
@@ -5123,33 +5631,38 @@
             r_vci_rsp_cpt = 0;
 
-            if      ( (p_vci.rpktid.read() & 0x7) ==  TYPE_READ_DATA_UNC  )
+            if      ( (p_vci.rpktid.read() & 0xF) ==  TYPE_READ_DATA_UNC  )
             {
                 r_vci_rsp_fsm = RSP_DATA_UNC;
             }
-            else if ( (p_vci.rpktid.read() & 0x7) ==  TYPE_READ_DATA_MISS )
+            else if ( (p_vci.rpktid.read() & 0xF) ==  TYPE_READ_DATA_MISS )
             {
                 r_vci_rsp_fsm = RSP_DATA_MISS;
             }
-            else if ( (p_vci.rpktid.read() & 0x7) ==  TYPE_READ_INS_UNC   )
+            else if ( (p_vci.rpktid.read() & 0xF) ==  TYPE_READ_DATA_MISS_NO_COHERENT )
+            {
+                r_vci_rsp_read_data_miss_no_coherent = true;
+                r_vci_rsp_fsm = RSP_DATA_MISS;
+            }
+            else if ( (p_vci.rpktid.read() & 0xF) ==  TYPE_READ_INS_UNC   )
             {
                 r_vci_rsp_fsm = RSP_INS_UNC;
             }
-            else if ( (p_vci.rpktid.read() & 0x7) ==  TYPE_READ_INS_MISS  )
+            else if ( (p_vci.rpktid.read() & 0xF) ==  TYPE_READ_INS_MISS  )
             {
                 r_vci_rsp_fsm = RSP_INS_MISS;
             }
-            else if ( (p_vci.rpktid.read() & 0x7) ==  TYPE_WRITE          )
+            else if ( (p_vci.rpktid.read() & 0xF) ==  TYPE_WRITE          )
             {
                 r_vci_rsp_fsm = RSP_DATA_WRITE;
             }
-            else if ( (p_vci.rpktid.read() & 0x7) ==  TYPE_CAS            )
+            else if ( (p_vci.rpktid.read() & 0xF) ==  TYPE_CAS            )
             {
                 r_vci_rsp_fsm = RSP_DATA_UNC;
             }
-            else if ( (p_vci.rpktid.read() & 0x7) ==  TYPE_LL             )
+            else if ( (p_vci.rpktid.read() & 0xF) ==  TYPE_LL             )
             {
                 r_vci_rsp_fsm = RSP_DATA_LL;
             }
-            else if ( (p_vci.rpktid.read() & 0x7) == TYPE_SC             )
+            else if ( (p_vci.rpktid.read() & 0xF) == TYPE_SC             )
             {
                 r_vci_rsp_fsm = RSP_DATA_UNC;
@@ -5400,11 +5913,40 @@
             if (p_dspin_out.read.read())
             {
-                if (r_cc_send_last_client.read() == 0) // dcache active request
-                    r_dcache_cc_send_req = false; // reset dcache request
-                else // icache active request
-                    r_icache_cc_send_req = false; // reset icache request
-
-                // go back to idle state
-                r_cc_send_fsm = CC_SEND_IDLE;
+                /*ODCCP*/ // If there is a cleanup with data and dcache active request we send other flits contained data
+                if(r_dcache_cc_cleanup_updt_data.read() and (r_cc_send_last_client.read() == 0) )
+                {
+                    r_cc_send_fsm = CC_SEND_CLEANUP_DATA_UPDT;
+                }
+                else
+                {
+                    if (r_cc_send_last_client.read() == 0) // dcache active request
+                        r_dcache_cc_send_req = false; // reset dcache request
+                    else // icache active request
+                        r_icache_cc_send_req = false; // reset icache request
+                    // go back to idle state
+                    r_cc_send_fsm = CC_SEND_IDLE;
+                }
+            }
+            break;
+        }
+        ///////////////////////////
+        case CC_SEND_CLEANUP_DATA_UPDT: /*ODCCP*/ // we send the data values of line cache into [m_dcache_words] flits
+        {
+            if (p_dspin_out.read.read())
+            {
+                if(r_cc_send_data_fifo.rok())
+                {
+                    m_cpt_data_cleanup++;
+                    cleanup_data_updt_fifo_dcache_get = true;
+                    r_cc_send_cpt_word = r_cc_send_cpt_word.read() + 1;
+                    if (r_cc_send_cpt_word.read() == m_dcache_words-1)
+                    {
+                        /*ODCCP*/
+                        r_dcache_cc_send_req = false;
+                        r_dcache_cc_cleanup_updt_data = false;
+                        r_cc_send_cpt_word = 0;
+                        r_cc_send_fsm = CC_SEND_IDLE;
+                    }
+                }
             }
             break;
@@ -5487,12 +6029,12 @@
             // for data CLACK, wait for dcache to take the request
             if ((r_cc_receive_data_ins.read() == 0) and 
-                   not (r_cc_receive_dcache_req.read()))
+                    not r_cc_receive_dcache_req.read())
             {
                 // request dcache to handle the CLACK
                 r_cc_receive_dcache_req  = true;
-                r_cc_receive_dcache_set  = DspinDhccpParam::dspin_get(receive_data,
+                r_cc_receive_dcache_set  = DspinDhccpParam::dspin_get(receive_data, 
                                            DspinDhccpParam::CLEANUP_ACK_SET) & 
                                            ((1ULL<<(uint32_log2(m_dcache_sets)))-1);
-                r_cc_receive_dcache_way  = DspinDhccpParam::dspin_get(receive_data,
+                r_cc_receive_dcache_way  = DspinDhccpParam::dspin_get(receive_data, 
                                            DspinDhccpParam::CLEANUP_ACK_WAY) & 
                                            ((1ULL<<(uint32_log2(m_dcache_ways)))-1);
@@ -5710,4 +6252,8 @@
                                  vci_rsp_fifo_dcache_data);
 
+    r_cc_send_data_fifo.update(cleanup_data_updt_fifo_dcache_get,
+                               cleanup_data_updt_fifo_dcache_put,
+                               cleanup_data_updt_fifo_dcache_data);
+
     ///////////////// updt FIFO update  //////////////////////
     //TODO check this
@@ -5804,5 +6350,9 @@
         p_vci.be      = 0xF;
         p_vci.trdid   = 0;
-        p_vci.pktid   = TYPE_READ_DATA_MISS;
+        /*ODCCP*/ // If miss on no coherent line pktid = TYPE_READ_DATA_MISS_NO_COHERENT
+        if(r_dcache_miss_no_coherent.read() == true)
+            p_vci.pktid   = TYPE_READ_DATA_MISS_NO_COHERENT;
+        else
+            p_vci.pktid   = TYPE_READ_DATA_MISS;
         p_vci.plen    = m_dcache_words << 2;
         p_vci.cmd     = vci_param::CMD_READ;
@@ -5904,7 +6454,4 @@
         {
             // initialize dspin send data
-//            DspinDhccpParam::dspin_set(dspin_send_data,
-//                                       0,
-//                                       DspinDhccpParam::FROM_L1_EOP);
             DspinDhccpParam::dspin_set(dspin_send_data,
                                        m_cc_global_id,
@@ -5919,5 +6466,4 @@
                                 >> (m_nline_width - m_x_width - m_y_width) 
                                 << (DspinDhccpParam::GLOBALID_WIDTH - m_x_width - m_y_width);
- 
                 DspinDhccpParam::dspin_set(dspin_send_data,
                                            dest,
@@ -5935,4 +6481,18 @@
                                            DspinDhccpParam::TYPE_CLEANUP_DATA,
                                            DspinDhccpParam::FROM_L1_TYPE);
+                /*ODCCP*/ // If cleanup on NCC line we set the CLEANUP_NCC bit in cleanup flit
+                if (r_dcache_cleanup_ncc.read())                 
+                {
+                    DspinDhccpParam::dspin_set(dspin_send_data,
+                                               1,
+                                               DspinDhccpParam::CLEANUP_NCC);
+                }
+                else
+                {
+                    DspinDhccpParam::dspin_set(dspin_send_data,
+                                               0,
+                                               DspinDhccpParam::CLEANUP_NCC);
+                }
+
             }
             else                                // icache active request
@@ -5957,4 +6517,8 @@
                                            DspinDhccpParam::TYPE_CLEANUP_INST,
                                            DspinDhccpParam::FROM_L1_TYPE);
+                
+                DspinDhccpParam::dspin_set(dspin_send_data,
+                                           0,
+                                           DspinDhccpParam::CLEANUP_NCC);
             }
             // send flit
@@ -5968,7 +6532,13 @@
         {
             // initialize dspin send data
-//            DspinDhccpParam::dspin_set(dspin_send_data,
-//                                       1,
-//                                       DspinDhccpParam::FROM_L1_EOP);
+            /*ODCCP*/ // if cleanup contains data and dcache active request, there is other flits to send
+            if (r_dcache_cc_cleanup_updt_data.read() and not r_cc_send_last_client.read())
+            {
+                p_dspin_out.eop   = false;
+            }
+            else
+            {
+                p_dspin_out.eop   = true;
+            }
 
             if(r_cc_send_last_client.read() == 0) // dcache active request
@@ -5987,5 +6557,24 @@
             p_dspin_out.data  = dspin_send_data;
             p_dspin_out.write = true;
-            p_dspin_out.eop   = true;
+            break;
+        }
+        ///////////////////////
+        case CC_SEND_CLEANUP_DATA_UPDT:
+        {
+            if (r_cc_send_cpt_word.read() == m_dcache_words-1) /*ODCCP*/ // Last flit sent
+            {
+                p_dspin_out.eop   = true;
+            }
+            else
+            {
+                p_dspin_out.eop   = false;
+            }
+
+            DspinDhccpParam::dspin_set(dspin_send_data,
+                                       r_cc_send_data_fifo.read(),
+                                       DspinDhccpParam::CLEANUP_DATA_UPDT);
+            
+            p_dspin_out.data = dspin_send_data;
+            p_dspin_out.write = true;
             break;
         }
