Index: branches/ODCCP/modules/vci_cc_vcache_wrapper/caba/source/src/vci_cc_vcache_wrapper.cpp
===================================================================
--- branches/ODCCP/modules/vci_cc_vcache_wrapper/caba/source/src/vci_cc_vcache_wrapper.cpp	(revision 543)
+++ branches/ODCCP/modules/vci_cc_vcache_wrapper/caba/source/src/vci_cc_vcache_wrapper.cpp	(revision 544)
@@ -3826,4 +3826,20 @@
                                 // to avoid dead-lock in case of simultaneous ITLB miss
     {
+        // coherence clack request (from DSPIN CLACK)
+        if ( r_dcache_clack_req.read() )
+        {
+            r_dcache_fsm = DCACHE_CC_CHECK;
+            r_dcache_fsm_cc_save = r_dcache_fsm.read();
+            break;
+        }
+
+        // coherence request (from CC_RECEIVE FSM)
+        if ( r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read())
+        {
+            r_dcache_fsm = DCACHE_CC_CHECK;
+            r_dcache_fsm_cc_save = r_dcache_fsm.read();
+            break;
+        }
+
         // itlb miss request
         if ( r_icache_tlb_miss_req.read() )
@@ -4539,5 +4555,8 @@
         {
             r_dcache_content_state[way*m_dcache_sets+set] = LINE_CACHE_DATA_NOT_DIRTY;
-            r_dcache_tlb_inval_line  = r_dcache_cc_send_nline;
+            if( not r_dcache_cleanup_victim_req.read() )
+                r_dcache_tlb_inval_line  = r_dcache_cc_send_nline;
+            else
+                r_dcache_tlb_inval_line  = r_dcache_cleanup_victim_nline.read();
             r_dcache_tlb_inval_set   = 0;
             r_dcache_fsm_scan_save   = DCACHE_MISS_WAIT;
Index: branches/ODCCP/modules/vci_mem_cache/caba/source/include/mem_cache_directory.h
===================================================================
--- branches/ODCCP/modules/vci_mem_cache/caba/source/include/mem_cache_directory.h	(revision 543)
+++ branches/ODCCP/modules/vci_mem_cache/caba/source/include/mem_cache_directory.h	(revision 544)
@@ -235,17 +235,22 @@
 
       bool hit       = false;
-      for ( size_t i=0 ; i<m_ways ; i++ ) {
+        for ( size_t i=0 ; i<m_ways ; i++ ) 
+        {
         bool equal = ( m_dir_tab[set][i].tag == tag );
         bool valid = m_dir_tab[set][i].valid;
         hit = equal && valid;
-        if ( hit ) {			
+            if ( hit ) 
+            {			
           way = i;
           break;
         } 
       }
-      if ( hit ) {
+        if ( hit ) 
+        {
         m_lru_tab[set][way].recent = true;
         return DirectoryEntry(m_dir_tab[set][way]);
-      } else {
+        } 
+        else 
+        {
         return DirectoryEntry();
       }
Index: branches/ODCCP/modules/vci_mem_cache/caba/source/include/vci_mem_cache.h
===================================================================
--- branches/ODCCP/modules/vci_mem_cache/caba/source/include/vci_mem_cache.h	(revision 543)
+++ branches/ODCCP/modules/vci_mem_cache/caba/source/include/vci_mem_cache.h	(revision 544)
@@ -80,8 +80,8 @@
       {
         TGT_CMD_IDLE,
-        TGT_CMD_ERROR,
         TGT_CMD_READ,
         TGT_CMD_WRITE,
         TGT_CMD_CAS,
+        TGT_CMD_ERROR,
         TGT_CMD_CONFIG
       };
@@ -90,6 +90,4 @@
       enum tgt_rsp_fsm_state_e
       {
-        TGT_RSP_CONFIG_IDLE,
-        TGT_RSP_TGT_CMD_IDLE,
         TGT_RSP_READ_IDLE,
         TGT_RSP_WRITE_IDLE,
@@ -98,6 +96,6 @@
         TGT_RSP_MULTI_ACK_IDLE,
         TGT_RSP_CLEANUP_IDLE,
-        TGT_RSP_CONFIG,
-        TGT_RSP_TGT_CMD,
+        TGT_RSP_CONFIG_IDLE,
+        TGT_RSP_TGT_CMD_IDLE,
         TGT_RSP_READ,
         TGT_RSP_WRITE,
@@ -105,5 +103,7 @@
         TGT_RSP_XRAM,
         TGT_RSP_MULTI_ACK,
-        TGT_RSP_CLEANUP
+        TGT_RSP_CLEANUP,
+        TGT_RSP_CONFIG,
+        TGT_RSP_TGT_CMD
       };
 
@@ -120,12 +120,8 @@
       enum cc_send_fsm_state_e
       {
-        CC_SEND_CONFIG_IDLE,
         CC_SEND_XRAM_RSP_IDLE,
         CC_SEND_WRITE_IDLE,
         CC_SEND_CAS_IDLE,
-        CC_SEND_CONFIG_INVAL_HEADER,
-        CC_SEND_CONFIG_INVAL_NLINE,
-        CC_SEND_CONFIG_BRDCAST_HEADER,
-        CC_SEND_CONFIG_BRDCAST_NLINE,
+        CC_SEND_CONFIG_IDLE,
         CC_SEND_XRAM_RSP_BRDCAST_HEADER,
         CC_SEND_XRAM_RSP_BRDCAST_NLINE,
@@ -142,5 +138,9 @@
         CC_SEND_CAS_UPDT_NLINE,
         CC_SEND_CAS_UPDT_DATA,
-        CC_SEND_CAS_UPDT_DATA_HIGH
+        CC_SEND_CAS_UPDT_DATA_HIGH,
+        CC_SEND_CONFIG_INVAL_HEADER,
+        CC_SEND_CONFIG_INVAL_NLINE,
+        CC_SEND_CONFIG_BRDCAST_HEADER,
+        CC_SEND_CONFIG_BRDCAST_NLINE
       };
 
@@ -324,10 +324,10 @@
       {
         ALLOC_DIR_RESET,
-        ALLOC_DIR_CONFIG,
         ALLOC_DIR_READ,
         ALLOC_DIR_WRITE,
         ALLOC_DIR_CAS,
         ALLOC_DIR_CLEANUP,
-        ALLOC_DIR_XRAM_RSP
+        ALLOC_DIR_XRAM_RSP,
+        ALLOC_DIR_CONFIG
       };
 
@@ -414,20 +414,49 @@
       uint32_t     m_cpt_cycles;        // Counter of cycles
 
-      uint32_t     m_cpt_read;          // Number of READ transactions
+      // Counters accessible in software (not yet but eventually)
+      uint32_t     m_cpt_read_local;     // Number of local READ transactions
       uint32_t     m_cpt_read_remote;   // number of remote READ transactions
-      uint32_t     m_cpt_read_flits;    // number of flits for READs
       uint32_t     m_cpt_read_cost;     // Number of (flits * distance) for READs
 
-      uint32_t     m_cpt_read_miss;     // Number of MISS READ
-
-      uint32_t     m_cpt_write;         // Number of WRITE transactions
+      uint32_t     m_cpt_write_local;    // Number of local WRITE transactions
       uint32_t     m_cpt_write_remote;  // number of remote WRITE transactions
-      uint32_t     m_cpt_write_flits;   // number of flits for WRITEs
+      uint32_t     m_cpt_write_flits_local;  // number of flits for local WRITEs
+      uint32_t     m_cpt_write_flits_remote; // number of flits for remote WRITEs
       uint32_t     m_cpt_write_cost;    // Number of (flits * distance) for WRITEs
 
+      uint32_t     m_cpt_ll_local;       // Number of local LL transactions
+      uint32_t     m_cpt_ll_remote;      // number of remote LL transactions
+      uint32_t     m_cpt_ll_cost;        // Number of (flits * distance) for LLs
+
+      uint32_t     m_cpt_sc_local;       // Number of local SC transactions
+      uint32_t     m_cpt_sc_remote;      // number of remote SC transactions
+      uint32_t     m_cpt_sc_cost;        // Number of (flits * distance) for SCs
+
+      uint32_t     m_cpt_cas_local;      // Number of local SC transactions
+      uint32_t     m_cpt_cas_remote;     // number of remote SC transactions
+      uint32_t     m_cpt_cas_cost;       // Number of (flits * distance) for SCs
+
+      uint32_t     m_cpt_update;         // Number of requests causing an UPDATE
+      uint32_t     m_cpt_update_local;   // Number of local UPDATE transactions
+      uint32_t     m_cpt_update_remote;  // Number of remote UPDATE transactions
+      uint32_t     m_cpt_update_cost;    // Number of (flits * distance) for UPDT
+
+      uint32_t     m_cpt_m_inval;        // Number of requests causing M_INV
+      uint32_t     m_cpt_m_inval_local;  // Number of local M_INV transactions
+      uint32_t     m_cpt_m_inval_remote; // Number of remote M_INV transactions
+      uint32_t     m_cpt_m_inval_cost;   // Number of (flits * distance) for M_INV
+
+      uint32_t     m_cpt_br_inval;       // Number of BROADCAST INVAL
+
+      uint32_t     m_cpt_cleanup_local;  // Number of local CLEANUP transactions
+      uint32_t     m_cpt_cleanup_remote; // Number of remote CLEANUP transactions
+      uint32_t     m_cpt_cleanup_cost;   // Number of (flits * distance) for CLEANUPs
+
+      // Counters not accessible by software
+      uint32_t     m_cpt_read_miss;      // Number of MISS READ
       uint32_t     m_cpt_write_miss;    // Number of MISS WRITE
-      uint32_t     m_cpt_write_cells;   // Cumulated length for WRITE transactions
       uint32_t     m_cpt_write_dirty;   // Cumulated length for WRITE transactions
-      uint32_t     m_cpt_update;        // Number of UPDATE transactions
+      uint32_t     m_cpt_write_broadcast;// Number of BROADCAST INVAL because write
+
       uint32_t     m_cpt_trt_rb;        // Read blocked by a hit in trt
       uint32_t     m_cpt_trt_full;      // Transaction blocked due to a full trt
@@ -441,5 +470,4 @@
       uint32_t     m_cpt_sc;            // Number of SC transactions
       uint32_t     m_cpt_cas;           // Number of CAS transactions
-      
       uint32_t     m_cpt_read_fsm_dir_lock;        // wait DIR LOCK
       uint32_t     m_cpt_read_fsm_n_dir_lock;      // NB DIR LOCK
@@ -520,13 +548,8 @@
       uint32_t     m_cpt_heap_unused;            // NB cycles HEAP LOCK unused
 
-      uint32_t     m_cpt_cleanup_cost;  // Number of (flits * distance) for CLEANUPs
-
       uint32_t     m_cpt_update_flits;  // Number of flits for UPDATEs
-      uint32_t     m_cpt_update_cost;   // Number of (flits * distance) for UPDATEs
-
       uint32_t     m_cpt_inval_cost;    // Number of (flits * distance) for INVALs
 
       uint32_t     m_cpt_get;
-
       uint32_t     m_cpt_put;
 
@@ -546,4 +569,25 @@
       soclib::caba::DspinOutput<dspin_out_width>  p_dspin_clack;
 
+#if MONITOR_MEMCACHE_FSM == 1
+      sc_out<int> p_read_fsm; 
+      sc_out<int> p_write_fsm; 
+      sc_out<int> p_xram_rsp_fsm; 
+      sc_out<int> p_cas_fsm; 
+      sc_out<int> p_cleanup_fsm; 
+      sc_out<int> p_config_fsm; 
+      sc_out<int> p_alloc_heap_fsm; 
+      sc_out<int> p_alloc_dir_fsm; 
+      sc_out<int> p_alloc_trt_fsm; 
+      sc_out<int> p_alloc_upt_fsm; 
+      sc_out<int> p_alloc_ivt_fsm; 
+      sc_out<int> p_tgt_cmd_fsm; 
+      sc_out<int> p_tgt_rsp_fsm; 
+      sc_out<int> p_ixr_cmd_fsm; 
+      sc_out<int> p_ixr_rsp_fsm; 
+      sc_out<int> p_cc_send_fsm; 
+      sc_out<int> p_cc_receive_fsm; 
+      sc_out<int> p_multi_ack_fsm; 
+#endif
+
       VciMemCache(
           sc_module_name name,                                // Instance Name
@@ -553,4 +597,6 @@
           const soclib::common::IntTab       &tgtid_d,        // global index INT network
           const size_t                       cc_global_id,    // global index CC network
+          const size_t                       x_width,         // X width in platform
+          const size_t                       y_width,         // Y width in platform
           const size_t                       nways,           // Number of ways per set
           const size_t                       nsets,           // Number of sets
@@ -566,6 +612,5 @@
       ~VciMemCache();
 
-      void clear_stats();
-      void print_stats();
+      void print_stats(bool activity_counters, bool stats);
       void print_trace();
       void cache_monitor(addr_t addr);
@@ -578,4 +623,6 @@
       void genMoore();
       void check_monitor(addr_t addr, data_t data, bool read);
+      uint32_t req_distance(uint32_t req_srcid);
+      bool is_local_req(uint32_t req_srcid);
 
       // Component attributes
@@ -591,4 +638,6 @@
       const size_t                       m_words;            // Number of words in a line
       const size_t                       m_cc_global_id;     // global_index on cc network
+      const size_t                       m_xwidth;           // number of x bits in platform
+      const size_t                       m_ywidth;           // number of y bits in platform
       size_t                             m_debug_start_cycle;
       bool                               m_debug_ok;
@@ -665,7 +714,4 @@
 
       sc_signal<int>         r_tgt_cmd_fsm;
-      sc_signal<size_t>      r_tgt_cmd_srcid;           // srcid for response to config
-      sc_signal<size_t>      r_tgt_cmd_trdid;           // trdid for response to config
-      sc_signal<size_t>      r_tgt_cmd_pktid;           // pktid for response to config
 
       ///////////////////////////////////////////////////////
@@ -696,5 +742,4 @@
       sc_signal<bool>     r_config_to_ixr_cmd_req;    // valid request
       sc_signal<size_t>   r_config_to_ixr_cmd_index;  // TRT index
-
 
       // Buffer between CONFIG fsm and TGT_RSP fsm (send a done response to L1 cache)
@@ -776,5 +821,6 @@
       sc_signal<size_t>   r_write_upt_index;          // index in Update Table
       sc_signal<bool>     r_write_sc_fail;            // sc command failed
-      sc_signal<bool>     r_write_pending_sc;         // sc command pending
+      sc_signal<data_t>   r_write_sc_key;             // sc command key
+      sc_signal<bool>     r_write_bc_data_we;         // Write enable for data buffer
 
       // Buffer between WRITE fsm and TGT_RSP fsm (acknowledge a write command from L1)
@@ -787,5 +833,4 @@
       // Buffer between WRITE fsm and IXR_CMD fsm 
       sc_signal<bool>     r_write_to_ixr_cmd_req;     // valid request
-      sc_signal<bool>     r_write_to_ixr_cmd_put;     // request type (GET/PUT)
       sc_signal<size_t>   r_write_to_ixr_cmd_index;   // TRT index 
 
@@ -891,5 +936,4 @@
       // Buffer between CAS fsm and IXR_CMD fsm 
       sc_signal<bool>     r_cas_to_ixr_cmd_req;   // valid request
-      sc_signal<bool>     r_cas_to_ixr_cmd_put;   // request type (GET/PUT)
       sc_signal<size_t>   r_cas_to_ixr_cmd_index; // TRT index 
 
Index: branches/ODCCP/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp
===================================================================
--- branches/ODCCP/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp	(revision 543)
+++ branches/ODCCP/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp	(revision 544)
@@ -64,14 +64,12 @@
     {
         "TGT_CMD_IDLE",
-        "TGT_CMD_ERROR",
         "TGT_CMD_READ",
         "TGT_CMD_WRITE",
         "TGT_CMD_CAS",
+        "TGT_CMD_ERROR",
         "TGT_CMD_CONFIG"
     };
     const char *tgt_rsp_fsm_str[] =
     {
-        "TGT_RSP_CONFIG_IDLE",
-        "TGT_RSP_TGT_CMD_IDLE",
         "TGT_RSP_READ_IDLE",
         "TGT_RSP_WRITE_IDLE",
@@ -80,6 +78,6 @@
         "TGT_RSP_MULTI_ACK_IDLE",
         "TGT_RSP_CLEANUP_IDLE",
-        "TGT_RSP_CONFIG",
-        "TGT_RSP_TGT_CMD",
+        "TGT_RSP_CONFIG_IDLE",
+        "TGT_RSP_TGT_CMD_IDLE",
         "TGT_RSP_READ",
         "TGT_RSP_WRITE",
@@ -87,5 +85,7 @@
         "TGT_RSP_XRAM",
         "TGT_RSP_MULTI_ACK",
-        "TGT_RSP_CLEANUP"
+        "TGT_RSP_CLEANUP",
+        "TGT_RSP_CONFIG",
+        "TGT_RSP_TGT_CMD"
     };
     const char *cc_receive_fsm_str[] =
@@ -98,12 +98,8 @@
     const char *cc_send_fsm_str[] =
     {
-        "CC_SEND_CONFIG_IDLE",
         "CC_SEND_XRAM_RSP_IDLE",
         "CC_SEND_WRITE_IDLE",
         "CC_SEND_CAS_IDLE",
-        "CC_SEND_CONFIG_INVAL_HEADER",
-        "CC_SEND_CONFIG_INVAL_NLINE",
-        "CC_SEND_CONFIG_BRDCAST_HEADER",
-        "CC_SEND_CONFIG_BRDCAST_NLINE",
+        "CC_SEND_CONFIG_IDLE",
         "CC_SEND_XRAM_RSP_BRDCAST_HEADER",
         "CC_SEND_XRAM_RSP_BRDCAST_NLINE",
@@ -120,5 +116,9 @@
         "CC_SEND_CAS_UPDT_NLINE",
         "CC_SEND_CAS_UPDT_DATA",
-        "CC_SEND_CAS_UPDT_DATA_HIGH"
+        "CC_SEND_CAS_UPDT_DATA_HIGH",
+        "CC_SEND_CONFIG_INVAL_HEADER",
+        "CC_SEND_CONFIG_INVAL_NLINE",
+        "CC_SEND_CONFIG_BRDCAST_HEADER",
+        "CC_SEND_CONFIG_BRDCAST_NLINE"
     };
     const char *multi_ack_fsm_str[] =
@@ -282,10 +282,10 @@
     {
         "ALLOC_DIR_RESET",
-        "ALLOC_DIR_CONFIG",
         "ALLOC_DIR_READ",
         "ALLOC_DIR_WRITE",
         "ALLOC_DIR_CAS",
         "ALLOC_DIR_CLEANUP",
-        "ALLOC_DIR_XRAM_RSP"
+        "ALLOC_DIR_XRAM_RSP",
+        "ALLOC_DIR_CONFIG"
     };
     const char *alloc_trt_fsm_str[] =
@@ -345,4 +345,6 @@
             const IntTab        &tgtid_d,          // global index on direct network
             const size_t        cc_global_id,      // global index on cc network
+            const size_t        x_width,           // number of x bits in platform
+            const size_t        y_width,           // number of x bits in platform
             const size_t        nways,             // number of ways per set
             const size_t        nsets,             // number of associative sets
@@ -377,4 +379,6 @@
         m_words( nwords ),
         m_cc_global_id( cc_global_id ),
+        m_xwidth(x_width),
+        m_ywidth(y_width),
         m_debug_start_cycle( debug_start_cycle ),
         m_debug_ok( debug_ok ),
@@ -470,4 +474,25 @@
         r_alloc_heap_fsm("r_alloc_heap_fsm"),
         r_alloc_heap_reset_cpt("r_alloc_heap_reset_cpt")
+#if MONITOR_MEMCACHE_FSM == 1
+        ,
+        p_read_fsm("p_read_fsm"), 
+        p_write_fsm("p_write_fsm"), 
+        p_xram_rsp_fsm("p_xram_rsp_fsm"), 
+        p_cas_fsm("p_cas_fsm"), 
+        p_cleanup_fsm("p_cleanup_fsm"), 
+        p_config_fsm("p_config_fsm"), 
+        p_alloc_heap_fsm("p_alloc_heap_fsm"), 
+        p_alloc_dir_fsm("p_alloc_dir_fsm"), 
+        p_alloc_trt_fsm("p_alloc_trt_fsm"), 
+        p_alloc_upt_fsm("p_alloc_upt_fsm"), 
+        p_alloc_ivt_fsm("p_alloc_ivt_fsm"), 
+        p_tgt_cmd_fsm("p_tgt_cmd_fsm"), 
+        p_tgt_rsp_fsm("p_tgt_rsp_fsm"), 
+        p_ixr_cmd_fsm("p_ixr_cmd_fsm"), 
+        p_ixr_rsp_fsm("p_ixr_rsp_fsm"), 
+        p_cc_send_fsm("p_cc_send_fsm"), 
+        p_cc_receive_fsm("p_cc_receive_fsm"),
+        p_multi_ack_fsm("p_multi_ack_fsm")
+#endif
         {
             std::cout << "  - Building VciMemCache : " << name << std::endl;
@@ -623,4 +648,27 @@
     }
 
+    
+    /////////////////////////////////////////////////////
+    tmpl(uint32_t)::req_distance(uint32_t req_srcid)
+    /////////////////////////////////////////////////////
+    {
+        const uint32_t srcid_width = vci_param_int::S;
+        uint8_t self_x_srcid = m_cc_global_id >> (srcid_width - m_xwidth);
+        uint8_t self_y_srcid = (m_cc_global_id >> (srcid_width - m_ywidth)) & ((1 << m_xwidth) - 1);
+
+        uint8_t x_srcid = req_srcid >> (srcid_width - m_xwidth);
+        uint8_t y_srcid = (req_srcid >> (srcid_width - m_ywidth - m_xwidth)) & ((1 << m_xwidth) - 1);
+        return abs(self_x_srcid - x_srcid) + abs(self_y_srcid - y_srcid);
+    }
+
+
+    /////////////////////////////////////////////////////
+    tmpl(bool)::is_local_req(uint32_t req_srcid)
+    /////////////////////////////////////////////////////
+    {
+        return req_distance(req_srcid) == 0;
+    }
+
+
     //////////////////////////////////////////////////
     tmpl(void) ::print_trace()
@@ -648,141 +696,119 @@
     }
 
+
     /////////////////////////////////////////
-    tmpl(void) ::clear_stats()
-        /////////////////////////////////////////
+    tmpl(void)::print_stats(bool activity_counters = true, bool stats = true)
     {
-        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_ivt_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;
+        std::cout << "**********************************" << std::dec << std::endl;
+        std::cout << "*** MEM_CACHE " << name() << std::endl;
+        std::cout << "**********************************" << std::dec << std::endl;
+        if (activity_counters) {
+        std::cout << "----------------------------------" << std::dec << std::endl;
+            std::cout << "---     Activity Counters      ---" << std::dec << std::endl;
+            std::cout << "----------------------------------" << std::dec << std::endl;
+        std::cout
+                << "[001] NUMBER OF CYCLES          = " << m_cpt_cycles << std::endl
+                << std::endl
+                << "[002] LOCAL READ                = " << m_cpt_read_local << std::endl
+                << "[003] REMOTE READ               = " << m_cpt_read_remote << std::endl
+                << "[004] READ COST (FLITS * DIST)  = " << m_cpt_read_cost << std::endl
+                << std::endl
+                << "[005] LOCAL WRITE               = " << m_cpt_write_local << std::endl
+                << "[006] REMOTE WRITE              = " << m_cpt_write_remote << std::endl
+                << "[007] WRITE FLITS LOCAL         = " << m_cpt_write_flits_local << std::endl
+                << "[008] WRITE FLITS REMOTE        = " << m_cpt_write_flits_remote << std::endl
+                << "[009] WRITE COST (FLITS * DIST) = " << m_cpt_write_cost << std::endl
+                << std::endl
+                << "[010] LOCAL LL                  = " << m_cpt_ll_local << std::endl
+                << "[011] REMOTE LL                 = " << m_cpt_ll_remote << std::endl
+                << "[012] LL COST (FLITS * DIST)    = " << m_cpt_ll_cost << std::endl
+                << std::endl
+                << "[013] LOCAL SC                  = " << m_cpt_sc_local << std::endl
+                << "[014] REMOTE SC                 = " << m_cpt_sc_remote << std::endl
+                << "[015] SC COST (FLITS * DIST)    = " << m_cpt_sc_cost << std::endl
+                << std::endl
+                << "[016] LOCAL CAS                 = " << m_cpt_cas_local << std::endl
+                << "[017] REMOTE CAS                = " << m_cpt_cas_remote << std::endl
+                << "[018] CAS COST (FLITS * DIST)   = " << m_cpt_cas_cost << std::endl
+                << std::endl
+                << "[019] REQUESTS TRIG. UPDATE     = " << m_cpt_update << std::endl
+                << "[020] LOCAL UPDATE              = " << m_cpt_update_local << std::endl
+                << "[021] REMOTE UPDATE             = " << m_cpt_update_remote << std::endl
+                << "[022] UPDT COST (FLITS * DIST)  = " << m_cpt_update_cost << std::endl
+                << std::endl
+                << "[023] REQUESTS TRIG. M_INV      = " << m_cpt_m_inval << std::endl
+                << "[024] LOCAL M_INV               = " << m_cpt_m_inval_local << std::endl
+                << "[025] REMOTE M_INV              = " << m_cpt_m_inval_remote << std::endl
+                << "[026] M_INV COST (FLITS * DIST) = " << m_cpt_m_inval_cost << std::endl
+                << std::endl
+                << "[027] BROADCAT INVAL            = " << m_cpt_br_inval << std::endl
+                << std::endl
+                << "[028] LOCAL CLEANUP             = " << m_cpt_cleanup_local << std::endl
+                << "[029] REMOTE CLEANUP            = " << m_cpt_cleanup_remote << std::endl
+                << "[030] CLNUP COST (FLITS * DIST) = " << m_cpt_cleanup_cost << std::endl
+                << std::endl
+                << std::endl
+                << "[031] READ MISS                 = " << m_cpt_read_miss << std::endl
+                << "[032] WRITE MISS                = " << m_cpt_write_miss << std::endl
+                << "[033] WRITE DIRTY               = " << m_cpt_write_dirty << std::endl
+                << "[034] RD BLOCKED BY HIT IN TRT  = " << m_cpt_trt_rb << std::endl
+                << "[035] TRANS BLOCKED BY FULL TRT = " << m_cpt_trt_full << std::endl
+                << "[036] PUT (UNIMPLEMENTED)       = " << m_cpt_put << std::endl
+                << "[037] GET (UNIMPLEMENTED)       = " << m_cpt_get << std::endl
+                << "[038] WRITE BROADCAST           = " << m_cpt_write_broadcast << std::endl
+                << std::endl;
     }
-    /////////////////////////////////////////
-    tmpl(void) ::print_stats()
-        /////////////////////////////////////////
-    {
-        std::cout << "----------------------------------" << std::dec << std::endl;
-        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
-            << "- 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
-           << "- IVT UNUSED RATE                        = " << (double) m_cpt_ivt_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;*/
+
+        if (stats) {
+            std::cout << "----------------------------------" << std::dec << std::endl;
+            std::cout << "---      Calculated Stats      ---" << std::dec << std::endl;
+            std::cout << "----------------------------------" << std::dec << std::endl;
+            std::cout
+                << "[100] READ TOTAL            = " << m_cpt_read_local + m_cpt_read_remote << std::endl
+                << "[101] READ RATE             = " << (double) (m_cpt_read_local + m_cpt_read_remote) / m_cpt_cycles << std::endl
+                << "[102] LOCAL READ RATE       = " << (double) m_cpt_read_local / m_cpt_cycles << std::endl
+                << "[103] REMOTE READ RATE      = " << (double) m_cpt_read_remote / m_cpt_cycles << std::endl
+                << "[104] READ MISS RATE        = " << (double) m_cpt_read_miss / (m_cpt_read_local + m_cpt_read_remote) << std::endl
+                << std::endl
+                << "[105] WRITE TOTAL           = " << m_cpt_write_local + m_cpt_write_remote << std::endl
+                << "[106] WRITE RATE            = " << (double) (m_cpt_write_local + m_cpt_write_remote) / m_cpt_cycles << std::endl
+                << "[107] LOCAL WRITE RATE      = " << (double) m_cpt_write_local / m_cpt_cycles << std::endl
+                << "[108] REMOTE WRITE RATE     = " << (double) m_cpt_write_remote / m_cpt_cycles << std::endl
+                << "[109] WRITE MISS RATE       = " << (double) m_cpt_write_miss / (m_cpt_write_local + m_cpt_write_remote) << std::endl
+                << "[110] WRITE BURST TOTAL     = " << m_cpt_write_flits_local + m_cpt_write_flits_remote << std::endl
+                << "[111] WRITE BURST AVERAGE   = " << (double) (m_cpt_write_flits_local + m_cpt_write_flits_remote) / (m_cpt_write_local + m_cpt_write_remote) << std::endl
+                << "[112] LOCAL WRITE BURST AV. = " << (double) m_cpt_write_flits_local / (m_cpt_write_local + m_cpt_write_remote) << std::endl
+                << "[113] REMOTE WRITE BURST AV = " << (double) m_cpt_write_flits_remote / (m_cpt_write_local + m_cpt_write_remote) << std::endl
+                << std::endl
+                << "[114] UPDATE RATE                = " << (double) m_cpt_update / m_cpt_cycles << std::endl
+                << "[115] AV. UPDATE PER UP REQ      = " << (double) (m_cpt_update_local + m_cpt_update_remote) / m_cpt_update << std::endl
+                << "[116] AV. LOC UPDT PER UP REQ    = " << (double) m_cpt_update_local / m_cpt_update << std::endl
+                << "[117] AV. REMOTE UPDT PER UP REQ = " << (double) m_cpt_update_remote / m_cpt_update << std::endl
+                << std::endl
+                << "[118] INVAL MULTICAST RATE  = " << (double) m_cpt_m_inval / m_cpt_cycles << std::endl
+                << "[119] AVE. INVAL PER M_INV  = " << (double) (m_cpt_m_inval_local + m_cpt_m_inval_remote) / m_cpt_m_inval << std::endl
+                << "[120] AV. LOC INV PER M_INV = " << (double) m_cpt_m_inval_local / m_cpt_m_inval << std::endl
+                << "[121] AV. REM INV PER M_INV = " << (double) m_cpt_m_inval_remote / m_cpt_m_inval << std::endl
+                << std::endl
+                << "[122] INVAL BROADCAST RATE  = " << (double) m_cpt_br_inval / m_cpt_cycles << std::endl
+                << "[123] WRITE DIRTY RATE      = " << (double) m_cpt_write_dirty / m_cpt_cycles << std::endl
+                << std::endl
+                << "[124] CLEANUP RATE          = " << (double) (m_cpt_cleanup_local + m_cpt_cleanup_remote) / m_cpt_cycles << std::endl
+                << "[125] LOCAL CLEANUP RATE    = " << (double) m_cpt_cleanup_local / m_cpt_cycles << std::endl
+                << "[126] REMOTE CLEANUP RATE   = " << (double) m_cpt_cleanup_remote / m_cpt_cycles << std::endl
+                << "[127] LL RATE               = " << (double) (m_cpt_ll_local + m_cpt_ll_remote) / m_cpt_cycles << std::endl
+                << "[128] LOCAL LL RATE         = " << (double) m_cpt_ll_local / m_cpt_cycles << std::endl
+                << "[129] REMOTE LL RATE        = " << (double) m_cpt_ll_remote / m_cpt_cycles << std::endl
+                << "[130] SC RATE               = " << (double) (m_cpt_sc_local + m_cpt_sc_remote) / m_cpt_cycles << std::endl
+                << "[131] LOCAL SC RATE         = " << (double) m_cpt_sc_local / m_cpt_cycles << std::endl
+                << "[132] REMOTE SC RATE        = " << (double) m_cpt_sc_remote / m_cpt_cycles << std::endl
+                << "[133] CAS RATE              = " << (double) (m_cpt_cas_local + m_cpt_cas_remote) / m_cpt_cycles << std::endl
+                << "[134] LOCAL CAS RATE        = " << (double) m_cpt_cas_local / m_cpt_cycles << std::endl
+                << "[135] REMOTE CAS RATE       = " << (double) m_cpt_cas_remote / m_cpt_cycles << std::endl
+                << std::endl
+                << std::endl;
+        }
     }
+
 
     /////////////////////////////////
@@ -790,7 +816,7 @@
         /////////////////////////////////
     {
+        delete [] m_seg;
+
         delete [] r_ixr_rsp_to_xram_rsp_rok;
-        //delete [] r_ixr_rsp_to_xram_rsp_no_coherent;
-
         delete [] r_xram_rsp_victim_data;
         delete [] r_xram_rsp_to_tgt_rsp_data;
@@ -802,8 +828,17 @@
         delete [] r_write_be;
         delete [] r_write_to_cc_send_data;
+        delete [] r_write_to_cc_send_be;
 
         delete [] r_cleanup_data;
-        delete [] r_ixr_cmd_data;
         delete [] r_cleanup_to_ixr_cmd_data;
+
+        delete [] r_cas_data;
+        delete [] r_cas_rdata;
+
+        delete [] r_ixr_cmd_wdata;
+        delete [] m_debug_previous_data;
+        delete [] m_debug_data;
+
+        print_stats();
     }
 
@@ -821,5 +856,5 @@
             r_tgt_cmd_fsm    = TGT_CMD_IDLE;
             r_config_fsm     = CONFIG_IDLE;
-            r_tgt_rsp_fsm    = TGT_RSP_TGT_CMD_IDLE;
+            r_tgt_rsp_fsm    = TGT_RSP_READ_IDLE;
             r_cc_send_fsm    = CC_SEND_XRAM_RSP_IDLE;
             r_cc_receive_fsm = CC_RECEIVE_IDLE;
@@ -833,5 +868,5 @@
             r_alloc_trt_fsm  = ALLOC_TRT_READ;
             r_alloc_upt_fsm  = ALLOC_UPT_WRITE;
-            r_alloc_ivt_fsm  = ALLOC_IVT_XRAM_RSP;
+            r_alloc_ivt_fsm  = ALLOC_IVT_WRITE;
             r_ixr_rsp_fsm    = IXR_RSP_IDLE;
             r_xram_rsp_fsm   = XRAM_RSP_IDLE;
@@ -951,9 +986,36 @@
             // Activity counters
             m_cpt_cycles                  = 0;
-            m_cpt_read                    = 0;
+            m_cpt_read_local         = 0;
+            m_cpt_read_remote        = 0;
+            m_cpt_read_cost          = 0;
+            m_cpt_write_local        = 0;
+            m_cpt_write_remote       = 0;
+            m_cpt_write_flits_local  = 0;
+            m_cpt_write_flits_remote = 0;
+            m_cpt_write_cost         = 0;
+            m_cpt_ll_local           = 0;
+            m_cpt_ll_remote          = 0;
+            m_cpt_ll_cost            = 0;
+            m_cpt_sc_local           = 0;
+            m_cpt_sc_remote          = 0;
+            m_cpt_sc_cost            = 0;
+            m_cpt_cas_local          = 0;
+            m_cpt_cas_remote         = 0;
+            m_cpt_cas_cost           = 0;
+            m_cpt_update             = 0;
+            m_cpt_update_local       = 0;
+            m_cpt_update_remote      = 0;
+            m_cpt_update_cost        = 0;
+            m_cpt_m_inval            = 0;
+            m_cpt_m_inval_local      = 0;
+            m_cpt_m_inval_remote     = 0;
+            m_cpt_m_inval_cost       = 0;
+            m_cpt_br_inval           = 0;
+            m_cpt_cleanup_local      = 0;
+            m_cpt_cleanup_remote     = 0;
+            m_cpt_cleanup_cost       = 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;
@@ -967,6 +1029,9 @@
             m_cpt_sc                      = 0;
             m_cpt_cas                     = 0;
+            m_cpt_write_broadcast         = 0;
+            m_cpt_trt_rb                  = 0;
             m_cpt_trt_full                = 0;
-            m_cpt_trt_rb                  = 0;
+            m_cpt_get                     = 0;
+            m_cpt_put                     = 0;
             m_cpt_dir_unused              = 0;
             m_cpt_ivt_unused              = 0;
@@ -1092,5 +1157,4 @@
         ////////////////////////////////////////////////////////////////////////////////////
 
-        //std::cout << std::endl << "tgt_cmd_fsm" << std::endl;
 
         switch(r_tgt_cmd_fsm.read())
@@ -1114,12 +1178,7 @@
                     bool        config   = false;
 
-                    // register arguments for response (segmentation violation or config)
-                    r_tgt_cmd_to_tgt_rsp_srcid = p_vci_tgt.srcid.read();
-                    r_tgt_cmd_to_tgt_rsp_trdid = p_vci_tgt.trdid.read();
-                    r_tgt_cmd_to_tgt_rsp_pktid = p_vci_tgt.pktid.read();
-
-                    for(size_t seg_id = 0 ; (seg_id < m_nseg) and not found ; seg_id++)
-                    {
-                        if( m_seg[seg_id]->contains(address) and
+                    for (size_t seg_id = 0; (seg_id < m_nseg) && !found; seg_id++)
+                    {
+                        if (m_seg[seg_id]->contains(address) &&
                                 m_seg[seg_id]->contains(address + plen - vci_param_int::B) )
                         {
@@ -1129,5 +1188,5 @@
                     }
 
-                    if ( not found )                /////////// out of segment error
+                    if (!found)                /////////// out of segment error
                     {
                         r_tgt_cmd_fsm   = TGT_CMD_ERROR;
@@ -1135,5 +1194,5 @@
                     else if ( config )              /////////// configuration command
                     {
-                        if ( not p_vci_tgt.eop.read() ) r_tgt_cmd_fsm = TGT_CMD_ERROR;
+                        if (!p_vci_tgt.eop.read()) r_tgt_cmd_fsm = TGT_CMD_ERROR;
                         else                            r_tgt_cmd_fsm = TGT_CMD_CONFIG;
                     }
@@ -1202,4 +1261,7 @@
                 if ( p_vci_tgt.cmdval and p_vci_tgt.eop )
                 {
+                    r_tgt_cmd_to_tgt_rsp_srcid = p_vci_tgt.srcid.read();
+                    r_tgt_cmd_to_tgt_rsp_trdid = p_vci_tgt.trdid.read();
+                    r_tgt_cmd_to_tgt_rsp_pktid = p_vci_tgt.pktid.read();
                     r_tgt_cmd_to_tgt_rsp_req   = true;
                     r_tgt_cmd_to_tgt_rsp_error = 1;
@@ -1239,14 +1301,7 @@
                         error            = 0;
                         r_config_lock    = true;
-                        if ( rdata == 0 )
-                        {
-                            r_tgt_cmd_srcid = p_vci_tgt.srcid.read();
-                            r_tgt_cmd_trdid = p_vci_tgt.trdid.read();
-                            r_tgt_cmd_pktid = p_vci_tgt.pktid.read();
-                        }
-                    }
+                        }
                     else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)  // release lock
-                            and (cell == MEMC_LOCK)
-                            and (p_vci_tgt.srcid.read() == r_tgt_cmd_srcid.read()) )
+                            and (cell == MEMC_LOCK) )
                     {
                         need_rsp         = true;
@@ -1255,6 +1310,5 @@
                     }
                     else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set addr_lo
-                            and (cell == MEMC_ADDR_LO)
-                            and (p_vci_tgt.srcid.read() == r_tgt_cmd_srcid.read()) )
+                            and (cell == MEMC_ADDR_LO) )
                     {
                         assert( ((wdata % (m_words*vci_param_int::B)) == 0) and
@@ -1264,9 +1318,8 @@
                         error            = 0;
                         r_config_address = (r_config_address.read() & 0xFFFFFFFF00000000LL) |
-                            (addr_t)p_vci_tgt.wdata.read();
+                            ((addr_t)wdata);
                     }
                     else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set addr_hi
-                            and (cell == MEMC_ADDR_HI)
-                            and (p_vci_tgt.srcid.read() == r_tgt_cmd_srcid.read()) )
+                            and (cell == MEMC_ADDR_HI) )
 
                     {
@@ -1274,24 +1327,22 @@
                         error            = 0;
                         r_config_address = (r_config_address.read() & 0x00000000FFFFFFFFLL) |
-                            ((addr_t)p_vci_tgt.wdata.read())<<32;
+                            (((addr_t) wdata) << 32);
                     }
                     else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set buf_lines
-                            and (cell == MEMC_BUF_LENGTH)
-                            and (p_vci_tgt.srcid.read() == r_tgt_cmd_srcid.read()) )
+                            and (cell == MEMC_BUF_LENGTH) )
                     {
                         need_rsp         = true;
                         error            = 0;
-                        size_t lines = (size_t)(p_vci_tgt.wdata.read()/(m_words<<2));
-                        if ( r_config_address.read()%(m_words*4) ) lines++;
+                        size_t lines = wdata/(m_words<<2);
+                        if ( wdata%(m_words<<2) ) lines++;
                         r_config_cmd_lines  = lines;
                         r_config_rsp_lines  = lines;
                     }
                     else if ( (p_vci_tgt.cmd.read() == vci_param_int::CMD_WRITE)   // set cmd type
-                            and (cell == MEMC_CMD_TYPE)
-                            and (p_vci_tgt.srcid.read() == r_tgt_cmd_srcid.read()) )
+                            and (cell == MEMC_CMD_TYPE) )
                     {
                         need_rsp         = false;
                         error            = 0;
-                        r_config_cmd     = p_vci_tgt.wdata.read();
+                        r_config_cmd     = wdata;
 
                         // prepare delayed response from CONFIG FSM
@@ -1311,4 +1362,7 @@
                         if ( r_tgt_cmd_to_tgt_rsp_req.read() ) break;
 
+                        r_tgt_cmd_to_tgt_rsp_srcid = p_vci_tgt.srcid.read();
+                        r_tgt_cmd_to_tgt_rsp_trdid = p_vci_tgt.trdid.read();
+                        r_tgt_cmd_to_tgt_rsp_pktid = p_vci_tgt.pktid.read();
                         r_tgt_cmd_to_tgt_rsp_req   = true;
                         r_tgt_cmd_to_tgt_rsp_error = error;
@@ -1371,6 +1425,16 @@
 #endif
                     cmd_read_fifo_put = true;
-                    if(p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ) m_cpt_ll++;
-                    else                                                       m_cpt_read++;
+                    // <Activity counters>
+                    if (p_vci_tgt.cmd.read() == vci_param_int::CMD_LOCKED_READ) {
+                        if (is_local_req(p_vci_tgt.srcid.read())) m_cpt_ll_local++;
+                        else                                      m_cpt_ll_remote++;
+                        m_cpt_ll_cost += req_distance(p_vci_tgt.srcid.read()); // LL on a single word
+                    }
+                    else {
+                        if (is_local_req(p_vci_tgt.srcid.read())) m_cpt_read_local++;
+                        else                                      m_cpt_read_remote++;
+                        m_cpt_read_cost += m_words * req_distance(p_vci_tgt.srcid.read());
+                    }
+                    // </Activity counters>
                     r_tgt_cmd_fsm = TGT_CMD_IDLE;
                 }
@@ -1394,5 +1458,29 @@
 #endif
                     cmd_write_fifo_put = true;
-                    if(p_vci_tgt.eop)  r_tgt_cmd_fsm = TGT_CMD_IDLE;
+                    // <Activity counters>
+                    if (p_vci_tgt.cmd.read() == vci_param_int::CMD_NOP) {
+                        m_cpt_sc_cost += req_distance(p_vci_tgt.srcid.read());
+                }
+                    else {
+                        if (is_local_req(p_vci_tgt.srcid.read())) m_cpt_write_flits_local++;
+                        else                                      m_cpt_write_flits_remote++;
+                        m_cpt_write_cost += req_distance(p_vci_tgt.srcid.read());
+                    }
+                    // </Activity counters>
+
+                    if (p_vci_tgt.eop) {
+                        // <Activity counters>
+                        if (p_vci_tgt.cmd.read() == vci_param_int::CMD_NOP) {
+                            if (is_local_req(p_vci_tgt.srcid.read())) m_cpt_sc_local++;
+                            else                                      m_cpt_sc_remote++;
+
+                        }
+                        else {
+                            if (is_local_req(p_vci_tgt.srcid.read())) m_cpt_write_local++;
+                            else                                      m_cpt_write_remote++;
+                        }
+                        // </Activity counters>
+                        r_tgt_cmd_fsm = TGT_CMD_IDLE;
+                    }
                 }
                 break;
@@ -1422,5 +1510,12 @@
 #endif
                     cmd_cas_fifo_put = true;
-                    if(p_vci_tgt.eop) r_tgt_cmd_fsm = TGT_CMD_IDLE;
+                    if (p_vci_tgt.eop) {
+                        // <Activity counters>
+                        if (is_local_req(p_vci_tgt.srcid.read())) m_cpt_cas_local++;
+                        else                                      m_cpt_cas_remote++;
+                        m_cpt_cas_cost += req_distance(p_vci_tgt.srcid.read());
+                        // </Activity counters>
+                        r_tgt_cmd_fsm = TGT_CMD_IDLE;
+                }
                 }
                 break;
@@ -1751,15 +1846,15 @@
                     DirectoryEntry entry = m_cache_directory.read(r_config_address.read(), way);
 
-                    if ( entry.valid and                            // hit & inval command
-                            (r_config_cmd.read() == MEMC_CMD_INVAL) ) 
-                    {
-                        r_config_dir_way        = way;
-                        r_config_dir_copy_inst  = entry.owner.inst;
-                        r_config_dir_copy_srcid = entry.owner.srcid;
-                        r_config_dir_is_cnt     = entry.is_cnt;
-                        r_config_dir_lock       = entry.lock;
-                        r_config_dir_count      = entry.count;
-                        r_config_dir_ptr        = entry.ptr;
-
+                    r_config_dir_way        = way;
+                    r_config_dir_copy_inst  = entry.owner.inst;
+                    r_config_dir_copy_srcid = entry.owner.srcid;
+                    r_config_dir_is_cnt     = entry.is_cnt;
+                    r_config_dir_lock       = entry.lock;
+                    r_config_dir_count      = entry.count;
+                    r_config_dir_ptr        = entry.ptr;
+
+                    if (entry.valid and                            // hit & inval command
+                            (r_config_cmd.read() == MEMC_CMD_INVAL)) 
+                    {
                         r_config_fsm    = CONFIG_IVT_LOCK;
                     }
@@ -1774,5 +1869,4 @@
                         r_config_cmd_lines = r_config_cmd_lines.read() - 1;
                         r_config_rsp_lines = r_config_rsp_lines.read() - 1;
-                        r_config_cmd_lines = r_config_cmd_lines.read() - 1;
                         r_config_address   = r_config_address.read() + (m_words<<2);
                         r_config_fsm       = CONFIG_LOOP;
@@ -1826,7 +1920,5 @@
                             entry.owner.inst  = r_config_dir_copy_inst.read();
                             entry.owner.srcid = r_config_dir_copy_srcid.read();
-                            m_cache_directory.write( set, 
-                                    way, 
-                                    entry );
+                            m_cache_directory.write( set, way, entry );
 
                             r_config_trt_index = index;
@@ -1856,17 +1948,16 @@
                     size_t          way = r_config_dir_way.read();
                     size_t          set = m_y[r_config_address.read()];
-
-                    sc_signal<data_t> config_data[16];
-                    m_cache_data.read_line( way, 
-                            set, 
-                            config_data );
-
-                    // post a PUT request in TRT
                     std::vector<data_t> data_vector;
                     data_vector.clear();
-                    for(size_t i=0; i<m_words; i++) data_vector.push_back(config_data[i].read());
+                    for(size_t word=0; word<m_words; word++) 
+                    {
+                        uint32_t data = m_cache_data.read( way, set, word );
+                        data_vector.push_back( data );
+                    }
+
+                    // post the PUT request in TRT
                     m_trt.set( r_config_trt_index.read(),
-                            false,                               // PUT
-                            m_nline[r_config_address.read()],    // nline
+                            false,                               // PUT transaction
+                            m_nline[r_config_address.read()],    // line index
                             0,                                   // srcid:       unused
                             0,                                   // trdid:       unused
@@ -1875,6 +1966,9 @@
                             0,                                   // read_length: unused
                             0,                                   // word_index:  unused
-                            std::vector<be_t>(m_words,0xF),                         
-                            data_vector);
+                            std::vector<be_t>(m_words,0xF),      // byte-enable:     unused 
+                            data_vector,                         // data to be written
+                            0,                                   // ll_key:          unused
+                            true );                              // requested by config FSM
+                    r_config_fsm = CONFIG_PUT_REQ;
 
 #if DEBUG_MEMC_CONFIG
@@ -1887,5 +1981,5 @@
                 }
                 ////////////////////
-            case CONFIG_PUT_REQ:       // PUT request to IXR_CMD_FSM
+            case CONFIG_PUT_REQ:       // post PUT request to IXR_CMD_FSM
                 {
                     if ( not r_config_to_ixr_cmd_req.read() )
@@ -1901,5 +1995,5 @@
 #if DEBUG_MEMC_CONFIG
                         if(m_debug)
-                            std::cout << "  <MEMC " << name() << " CONFIG_PUT_REQ> PUT request to IXR_CMD_FSM"
+                            std::cout << "  <MEMC " << name() << " CONFIG_PUT_REQ> post PUT request to IXR_CMD_FSM"
                                 << " / address = " << std::hex << r_config_address.read() << std::endl; 
 #endif
@@ -2706,15 +2800,5 @@
             case WRITE_IDLE:  // copy first word of a write burst in local buffer
                 {
-                    if(m_cmd_write_addr_fifo.rok())
-                    {
-                        if((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC)
-                        {
-                            m_cpt_sc++;
-                        }
-                        else
-                        { 
-                            m_cpt_write++;
-                            m_cpt_write_cells++;
-                        }
+                    if (not m_cmd_write_addr_fifo.rok()) break;
 
                         // consume a word in the FIFO & write it in the local buffer
@@ -2724,10 +2808,19 @@
                         r_write_address     = (addr_t)(m_cmd_write_addr_fifo.read());
                         r_write_word_index  = index;
-                        r_write_word_count  = 1;
+                    r_write_word_count  = 0;
                         r_write_data[index] = m_cmd_write_data_fifo.read();
                         r_write_srcid       = m_cmd_write_srcid_fifo.read();
                         r_write_trdid       = m_cmd_write_trdid_fifo.read();
                         r_write_pktid       = m_cmd_write_pktid_fifo.read();
-                        r_write_pending_sc  = false;
+
+                    // if SC command, get the SC key
+                    if ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC)
+                    {
+                        assert( not m_cmd_write_eop_fifo.read() &&
+                                "MEMC ERROR in WRITE_IDLE state: "
+                                "invalid packet format for SC command");
+
+                        r_write_sc_key = m_cmd_write_data_fifo.read();
+                    }
 
                         // initialize the be field for all words
@@ -2738,5 +2831,5 @@
                         }
 
-                        if (m_cmd_write_eop_fifo.read() or ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC))
+                    if (m_cmd_write_eop_fifo.read())
                         {
                             r_write_fsm = WRITE_DIR_REQ;
@@ -2754,5 +2847,4 @@
                                 << " / data = " << m_cmd_write_data_fifo.read() << std::endl;
 #endif
-                    }
                     break;
                 }
@@ -2760,30 +2852,45 @@
             case WRITE_NEXT:  // copy next word of a write burst in local buffer
                 {
-                    if(m_cmd_write_addr_fifo.rok())
-                    {
-
-#if DEBUG_MEMC_WRITE
-                        if(m_debug)
-                            std::cout << "  <MEMC " << name()
-                                << " WRITE_NEXT> Write another word in local buffer"
-                                << std::endl;
-#endif
-                        m_cpt_write_cells++;
+                    if (not m_cmd_write_addr_fifo.rok()) break;
 
                         // check that the next word is in the same cache line
                         assert( (m_nline[(addr_t)(r_write_address.read())] == 
-                                    m_nline[(addr_t)(m_cmd_write_addr_fifo.read())]) and
+                            m_nline[(addr_t)(m_cmd_write_addr_fifo.read())]) &&
                                 "MEMC ERROR in WRITE_NEXT state: Illegal write burst");
+
+                    size_t index = m_x[(addr_t)(m_cmd_write_addr_fifo.read())];
+                    bool   is_sc = ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC);
+
+                    // check that SC command has constant address
+                    assert((not is_sc or (index == r_write_word_index)) &&
+                            "MEMC ERROR in WRITE_NEXT state: "
+                            "the address must be constant on a SC command");
+
+                    // check that SC command has two flits
+                    assert((not is_sc or m_cmd_write_eop_fifo.read()) &&
+                            "MEMC ERROR in WRITE_NEXT state: "
+                            "invalid packet format for SC command");
 
                         // consume a word in the FIFO & write it in the local buffer
                         cmd_write_fifo_get  = true;
-                        size_t index        = r_write_word_index.read() + r_write_word_count.read();
 
                         r_write_be[index]   = m_cmd_write_be_fifo.read();
                         r_write_data[index] = m_cmd_write_data_fifo.read();
+
+                    // the first flit of a SC command is the reservation key and
+                    // therefore it must not be counted as a data to write
+                    if (not is_sc)
+                    {
                         r_write_word_count  = r_write_word_count.read() + 1;
+                    }
 
                         if(m_cmd_write_eop_fifo.read()) r_write_fsm = WRITE_DIR_REQ;
-                    }
+
+#if DEBUG_MEMC_WRITE
+                    if (m_debug)
+                        std::cout << "  <MEMC " << name()
+                            << " WRITE_NEXT> Write another word in local buffer"
+                            << std::endl;
+#endif
                     break;
                 }
@@ -2792,43 +2899,31 @@
                 // and access the llsc_global_table
                 {
-                    if( r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE )
-                    {
-                        if(((r_write_pktid.read() & 0x7) == TYPE_SC) and not r_write_pending_sc.read())
-                        {
-                            // We enter here if it is a new SC command
-                            // If r_write_pending_sc is set the SC is not new and has already been tested
-
-                            if(not m_cmd_write_addr_fifo.rok()) break;
-
-                            assert( m_cmd_write_eop_fifo.read() and
-                                    "MEMC ERROR in WRITE_DIR_REQ state: invalid packet format for SC command");
-
-                            size_t index    = r_write_word_index.read();
-                            bool sc_success = m_llsc_table.sc(r_write_address.read()    ,
-                                    r_write_data[index].read());
-
-                            // consume a word in the FIFO & write it in the local buffer
-                            cmd_write_fifo_get  = true;
-                            r_write_data[index] = m_cmd_write_data_fifo.read();
-                            r_write_sc_fail     = not sc_success;
-                            r_write_pending_sc  = true;
-
-                            if(not sc_success) r_write_fsm = WRITE_RSP;
-                            else               r_write_fsm = WRITE_DIR_LOCK;
-                        }
-                        else
-                        {
-                            // We enter here if it is a SW command or an already tested SC command 
-
+                    if (r_alloc_dir_fsm.read() != ALLOC_DIR_WRITE ) break;
+
+                    if ((r_write_pktid.read() & 0x7) == TYPE_SC)
+                    {
+                        // test address and key match of the SC command on the
+                        // LL/SC table without removing reservation. The reservation
+                        // will be erased after in this FSM. 
+                        bool sc_success = m_llsc_table.check(r_write_address.read(),
+                                r_write_sc_key.read());
+
+                        r_write_sc_fail     = not sc_success;
+
+                        if(not sc_success) r_write_fsm = WRITE_RSP;
+                        else               r_write_fsm = WRITE_DIR_LOCK;
+                    }
+                    else
+                    {
+                        // write burst 
 #define L2 soclib::common::uint32_log2
-                            addr_t min = r_write_address.read();
-                            addr_t max = r_write_address.read() +
-                                ((r_write_word_count.read()-1) << L2(vci_param_int::B));
+                        addr_t min = r_write_address.read();
+                        addr_t max = r_write_address.read() +
+                            (r_write_word_count.read() << L2(vci_param_int::B));
 #undef L2
 
-                            m_llsc_table.sw(min, max);
-
-                            r_write_fsm = WRITE_DIR_LOCK;
-                        }
+                        m_llsc_table.sw(min, max);
+
+                        r_write_fsm = WRITE_DIR_LOCK;
                     }
 
@@ -2916,9 +3011,16 @@
                     bool no_update = ( (r_write_count.read() == 0) or
                             (owner and (r_write_count.read() ==1) and 
-                             (r_write_pktid.read() != TYPE_SC)));
+                             ((r_write_pktid.read() & 0x7) != TYPE_SC)));
 
                     // write data in the cache if no coherence transaction
                     if(no_update)
                     {
+                        // SC command but zero copies 
+                        if ((r_write_pktid.read() & 0x7) == TYPE_SC)
+                        {
+                            m_llsc_table.sc(r_write_address.read(),
+                                            r_write_sc_key.read());
+                        }
+
                         for(size_t word=0 ; word<m_words ; word++)
                         {
@@ -2931,5 +3033,5 @@
                     }
 
-                    if(owner and not no_update and(r_write_pktid.read() != TYPE_SC))
+                    if (owner and not no_update and ((r_write_pktid.read() & 0x7) != TYPE_SC))
                     {
                         r_write_count = r_write_count.read() - 1;
@@ -3000,4 +3102,11 @@
                         if( wok )       // write data in cache
                         {
+                            
+                            if ((r_write_pktid.read() & 0x7) == TYPE_SC)
+                            {
+                                m_llsc_table.sc(r_write_address.read(),
+                                                r_write_sc_key.read());
+                            }
+
                             for(size_t word=0 ; word<m_words ; word++)
                             {
@@ -3067,8 +3176,9 @@
                     size_t min = r_write_word_index.read();
                     size_t max = r_write_word_index.read() + r_write_word_count.read();
-                    for(size_t i=min ; i<max ; i++) r_write_to_cc_send_data[i] = r_write_data[i];
+                    for(size_t i=min ; i<=max ; i++) r_write_to_cc_send_data[i] = r_write_data[i];
 
                     if( (r_write_copy.read() != r_write_srcid.read()) or
-                            (r_write_pktid.read() == TYPE_SC) or r_write_copy_inst.read())
+                       ((r_write_pktid.read() & 0x7) == TYPE_SC)      or
+                         r_write_copy_inst.read())
                     {
                         // put the first srcid in the fifo
@@ -3128,5 +3238,6 @@
                     // put the next srcid in the fifo
                     if( (entry.owner.srcid != r_write_srcid.read()) or 
-                            (r_write_pktid.read() == TYPE_SC) or entry.owner.inst)   
+                       ((r_write_pktid.read() & 0x7) == TYPE_SC)    or
+                         entry.owner.inst)
                     {
                         dec_upt_counter                = false;
@@ -3208,5 +3319,5 @@
                 // a new request in the write FIFO
                 {
-                    if(!r_write_to_tgt_rsp_req.read())
+                    if (not r_write_to_tgt_rsp_req.read())
                     {
                         // post the request to TGT_RSP_FSM
@@ -3218,14 +3329,10 @@
 
                         // try to get a new write request from the FIFO
-                        if(m_cmd_write_addr_fifo.rok())
-                        {
-                            if((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC)
-                                m_cpt_sc++;
+                        if (not m_cmd_write_addr_fifo.rok())
+                        {
+                            r_write_fsm = WRITE_IDLE;
+                        }
                             else
                             {
-                                m_cpt_write++;
-                                m_cpt_write_cells++;
-                            }
-
                             // consume a word in the FIFO & write it in the local buffer
                             cmd_write_fifo_get  = true;
@@ -3234,10 +3341,19 @@
                             r_write_address     = (addr_t)(m_cmd_write_addr_fifo.read());
                             r_write_word_index  = index;
-                            r_write_word_count  = 1;
+                            r_write_word_count  = 0;
                             r_write_data[index] = m_cmd_write_data_fifo.read();
                             r_write_srcid       = m_cmd_write_srcid_fifo.read();
                             r_write_trdid       = m_cmd_write_trdid_fifo.read();
                             r_write_pktid       = m_cmd_write_pktid_fifo.read();
-                            r_write_pending_sc  = false;
+
+                            // if SC command, get the SC key
+                            if ((m_cmd_write_pktid_fifo.read() & 0x7) == TYPE_SC)
+                            {
+                                assert( not m_cmd_write_eop_fifo.read() &&
+                                        "MEMC ERROR in WRITE_RSP state: "
+                                        "invalid packet format for SC command");
+
+                                r_write_sc_key = m_cmd_write_data_fifo.read();
+                            } 
 
                             // initialize the be field for all words
@@ -3248,5 +3364,5 @@
                             }
 
-                            if(m_cmd_write_eop_fifo.read() or ((m_cmd_write_pktid_fifo.read() & 0x7)  == TYPE_SC))
+                            if (m_cmd_write_eop_fifo.read())
                             {
                                 r_write_fsm = WRITE_DIR_REQ;
@@ -3256,8 +3372,4 @@
                                 r_write_fsm = WRITE_NEXT;
                             }
-                        }
-                        else
-                        {
-                            r_write_fsm = WRITE_IDLE;
                         }
 
@@ -3302,23 +3414,39 @@
                         bool    wok       = not m_trt.full(wok_index);
 
-                        if(hit_read)      // register the modified data in TRT
+                        // wait an empty entry in TRT
+                        if(not hit_read and (not wok or hit_write))
+                        {
+                            r_write_fsm       = WRITE_WAIT;
+                            m_cpt_trt_full++;
+
+                            break;
+                        }
+
+                        if ((r_write_pktid.read() & 0x7) == TYPE_SC)
+                        {
+                            m_llsc_table.sc(r_write_address.read(),
+                                            r_write_sc_key.read());
+                        }
+
+                        // register the modified data in TRT
+                        if (hit_read)
                         {
                             r_write_trt_index = hit_index;
                             r_write_fsm       = WRITE_MISS_TRT_DATA;
                             m_cpt_write_miss++;
-                        }
-                        else if(wok and !hit_write)      // set a new entry in TRT
+                            break;
+                        }
+
+                        // set a new entry in TRT
+                        if (wok and not hit_write)
                         {
                             r_write_trt_index = wok_index;
                             r_write_fsm       = WRITE_MISS_TRT_SET;
                             m_cpt_write_miss++;
-                        }
-                        else    // wait an empty entry in TRT
-                        {
-                            r_write_fsm       = WRITE_WAIT;
-                            m_cpt_trt_full++;
-                        }
-                        m_cpt_write_fsm_n_trt_lock++;
-                    }
+                            break;
+                        }
+
+                        assert(false && "VCI_MEM_CACHE ERROR: this part must not be reached");
+                        }
 
                     m_cpt_write_fsm_trt_lock++;
@@ -3406,5 +3534,4 @@
                     {
                         r_write_to_ixr_cmd_req   = true;
-                        r_write_to_ixr_cmd_put   = false;
                         r_write_to_ixr_cmd_index = r_write_trt_index.read();
                         r_write_fsm              = WRITE_RSP;
@@ -3412,5 +3539,7 @@
 #if DEBUG_MEMC_WRITE
                         if(m_debug)
-                            std::cout << "  <MEMC " << name() << " WRITE_MISS_XRAM_REQ> Post a GET request to the IXR_CMD FSM" << std::endl;
+                            std::cout << "  <MEMC " << name() 
+                                      << " WRITE_MISS_XRAM_REQ> Post a GET request to the"
+                                      << " IXR_CMD FSM" << std::endl;
 #endif
                     }
@@ -3420,10 +3549,34 @@
             case WRITE_BC_DIR_READ:  // enter this state if a broadcast-inval is required
                 // the cache line must be erased in mem-cache, and written
-                // into XRAM. we read the cache and complete the buffer
+                                     // into XRAM.
                 {
                     assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
                             "MEMC ERROR in WRITE_BC_DIR_READ state: Bad DIR allocation");
 
-                    // update local buffer
+                    m_cpt_write_broadcast++;
+
+                    // write enable signal for data buffer.
+                    r_write_bc_data_we = true;
+
+                    r_write_fsm = WRITE_BC_TRT_LOCK;
+
+#if DEBUG_MEMC_WRITE
+                    if (m_debug)
+                        std::cout << "  <MEMC " << name() << " WRITE_BC_DIR_READ>"
+                                  << " Read the cache to complete local buffer" << std::endl;
+#endif
+                    break;
+                }
+                ///////////////////////
+            case WRITE_BC_TRT_LOCK:     // get TRT lock to check TRT not full
+                {
+                    assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
+                            "MEMC ERROR in WRITE_BC_TRT_LOCK state: Bad DIR allocation");
+
+                    // We read the cache and complete the buffer. As the DATA cache uses a
+                    // synchronous RAM, the read DATA request has been performed in the
+                    // WRITE_BC_DIR_READ state but the data is available in this state.
+                    if (r_write_bc_data_we.read())
+                    {
                     size_t set  = m_y[(addr_t)(r_write_address.read())];
                     size_t way  = r_write_way.read();
@@ -3437,25 +3590,24 @@
 
                         // complete only if mask is not null (for energy consumption)
-                        r_write_data[word]  = (r_write_data[word].read() & mask) |
+                            r_write_data[word] =
+                                (r_write_data[word].read()         &  mask) |
                             (m_cache_data.read(way, set, word) & ~mask);
-                    } // end for
-
-                    r_write_fsm = WRITE_BC_TRT_LOCK;
-
+                        }
 #if DEBUG_MEMC_WRITE
                     if(m_debug)
-                        std::cout << "  <MEMC " << name() << " WRITE_BC_DIR_READ>"
-                            << " Read the cache to complete local buffer" << std::endl;
-#endif
-                    break;
-                }
-                ///////////////////////
-            case WRITE_BC_TRT_LOCK:     // get TRT lock to check TRT not full
-                {
-                    assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
-                            "MEMC ERROR in WRITE_BC_TRT_LOCK state: Bad DIR allocation");
-
-                    if(r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE)
-                    {
+                            std::cout 
+                                << "  <MEMC "  << name()
+                                << " WRITE_BC_TRT_LOCK> Complete data buffer" << std::endl;
+#endif
+                    }
+
+                    if (r_alloc_trt_fsm.read() != ALLOC_TRT_WRITE)
+                    {
+                        // if we loop in this state, the data does not need to be
+                        // rewritten (for energy consuption)
+                        r_write_bc_data_we = false;
+                    break;
+                }
+
                         size_t wok_index = 0;
                         bool wok = not m_trt.full(wok_index);
@@ -3472,10 +3624,8 @@
 #if DEBUG_MEMC_WRITE
                         if(m_debug)
-                            std::cout << "  <MEMC " << name() << " WRITE_BC_TRT_LOCK> Check TRT"
-                                << " : wok = " << wok << " / index = " << wok_index << std::endl;
-#endif
-                        m_cpt_write_fsm_n_trt_lock++;
-                    }
-
+                        std::cout << "  <MEMC "  << name()
+                                  << " WRITE_BC_TRT_LOCK> Check TRT : wok = " << wok
+                                  << " / index = " << wok_index << std::endl;
+#endif
                     m_cpt_write_fsm_trt_lock++;
 
@@ -3568,4 +3718,10 @@
                     m_cache_directory.write(set, way, entry);
 
+                    if ((r_write_pktid.read() & 0x7) == TYPE_SC)
+                    {
+                        m_llsc_table.sc(r_write_address.read(),
+                                        r_write_sc_key.read());
+                    }
+
 #if DEBUG_MEMC_WRITE
                     if(m_debug)
@@ -3611,5 +3767,4 @@
                     {
                         r_write_to_ixr_cmd_req     = true;
-                        r_write_to_ixr_cmd_put     = true;
                         r_write_to_ixr_cmd_index   = r_write_trt_index.read();
                         r_write_fsm = WRITE_IDLE;
@@ -3765,5 +3920,4 @@
                         r_ixr_cmd_word    = 0;
                         r_ixr_cmd_fsm     = IXR_CMD_READ_SEND;
-                        for( size_t i=0 ; i<m_words ; i++ ) r_ixr_cmd_wdata[i] = entry.wdata[i];
 
 #if DEBUG_MEMC_IXR_CMD
@@ -3787,5 +3941,10 @@
                         r_ixr_cmd_word    = 0;
                         r_ixr_cmd_fsm     = IXR_CMD_WRITE_SEND;
+
+                        // Read data from TRT if PUT transaction
+                        if (not entry.xram_read)
+                        {
                         for( size_t i=0 ; i<m_words ; i++ ) r_ixr_cmd_wdata[i] = entry.wdata[i];
+                        }
 
 #if DEBUG_MEMC_IXR_CMD
@@ -3809,5 +3968,10 @@
                         r_ixr_cmd_word    = 0;
                         r_ixr_cmd_fsm     = IXR_CMD_CAS_SEND;
+
+                        // Read data from TRT if PUT transaction
+                        if (not entry.xram_read)
+                        {
                         for( size_t i=0 ; i<m_words ; i++ ) r_ixr_cmd_wdata[i] = entry.wdata[i];
+                        }
 
 #if DEBUG_MEMC_IXR_CMD
@@ -3909,5 +4073,5 @@
                     if(p_vci_ixr.cmdack)
                     {
-                        if(r_write_to_ixr_cmd_put.read())   // PUT
+                        if (not r_ixr_cmd_get.read())   // PUT
                         {
                             if(r_ixr_cmd_word.read() == (m_words - 2))
@@ -3946,5 +4110,5 @@
                     if(p_vci_ixr.cmdack)
                     {
-                        if(r_cas_to_ixr_cmd_put.read()) // PUT
+                        if (not r_ixr_cmd_get.read()) // PUT
                         {
                             if(r_ixr_cmd_word.read() == (m_words - 2))
@@ -4291,5 +4455,5 @@
                     r_xram_rsp_victim_way       = way;
                     r_xram_rsp_victim_set       = set;
-                    r_xram_rsp_victim_nline     = victim.tag*m_sets + set;
+                    r_xram_rsp_victim_nline     = (addr_t)victim.tag*m_sets + set;
                     r_xram_rsp_victim_is_cnt    = victim.is_cnt;
                     r_xram_rsp_victim_inval     = inval ;
@@ -4808,6 +4972,4 @@
         ////////////////////////////////////////////////////////////////////////////////////
 
-        //std::cout << std::endl << "cleanup_fsm" << std::endl;
-
         switch(r_cleanup_fsm.read())
         {
@@ -4842,5 +5004,13 @@
                             "MEMC ERROR in CLEANUP_IDLE state : illegal SRCID value");
 
-                    m_cpt_cleanup++;
+                    // <Activity Counters>
+                    if (is_local_req(srcid)) {
+                        m_cpt_cleanup_local++;
+                    }
+                    else {
+                        m_cpt_cleanup_remote++;
+                        m_cpt_cleanup_cost += req_distance(srcid);
+                    }
+                    // </Activity Counters>
                     cc_receive_to_cleanup_fifo_get = true;
                     r_cleanup_fsm                  = CLEANUP_GET_NLINE;
@@ -5589,5 +5759,4 @@
                         if(m_cmd_cas_eop_fifo.read())
                         {
-                            m_cpt_cas++;
                             r_cas_fsm = CAS_DIR_REQ;
                         }
@@ -6135,5 +6304,4 @@
                     {
                         r_cas_to_ixr_cmd_req     = true;
-                        r_cas_to_ixr_cmd_put     = true;
                         r_cas_to_ixr_cmd_index   = r_cas_trt_index.read();
                         r_cas_fsm                = CAS_IDLE;
@@ -6272,5 +6440,4 @@
                     {
                         r_cas_to_ixr_cmd_req        = true;
-                        r_cas_to_ixr_cmd_put        = false;
                         r_cas_to_ixr_cmd_index      = r_cas_trt_index.read();
                         r_cas_fsm                   = CAS_WAIT;
@@ -6328,5 +6495,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_XRAM_RSP_INVAL_HEADER;
-                        m_cpt_inval++;
                         break;
                     }
@@ -6334,5 +6500,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_XRAM_RSP_BRDCAST_HEADER;
-                        m_cpt_inval++;
                         break;
                     }
@@ -6342,5 +6507,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_CAS_UPDT_HEADER;
-                        m_cpt_update++;
                         break;
                     }
@@ -6348,5 +6512,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_CAS_BRDCAST_HEADER;
-                        m_cpt_inval++;
                         break;
                     }
@@ -6356,5 +6519,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_WRITE_UPDT_HEADER;
-                        m_cpt_update++;
                         break;
                     }
@@ -6362,5 +6524,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_WRITE_BRDCAST_HEADER;
-                        m_cpt_inval++;
                         break;
                     }
@@ -6369,5 +6530,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_CONFIG_INVAL_HEADER;
-                        m_cpt_inval++;
                         break;
                     }
@@ -6375,5 +6535,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_CONFIG_BRDCAST_HEADER;
-                        m_cpt_inval++;
                         break;
                     }
@@ -6387,5 +6546,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_CONFIG_INVAL_HEADER;
-                        m_cpt_inval++;
                         break;
                     }
@@ -6393,5 +6551,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_CONFIG_BRDCAST_HEADER;
-                        m_cpt_inval++;
                         break;
                     }
@@ -6401,5 +6558,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_XRAM_RSP_INVAL_HEADER;
-                        m_cpt_inval++;
                         break;
                     }
@@ -6407,5 +6563,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_XRAM_RSP_BRDCAST_HEADER;
-                        m_cpt_inval++;
                         break;
                     }
@@ -6415,5 +6570,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_CAS_UPDT_HEADER;
-                        m_cpt_update++;
                         break;
                     }
@@ -6421,5 +6575,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_CAS_BRDCAST_HEADER;
-                        m_cpt_inval++;
                         break;
                     }
@@ -6429,5 +6582,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_WRITE_UPDT_HEADER;
-                        m_cpt_update++;
                         break;
                     }
@@ -6435,5 +6587,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_WRITE_BRDCAST_HEADER;
-                        m_cpt_inval++;
                         break;
                     }
@@ -6448,5 +6599,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_CAS_UPDT_HEADER;
-                        m_cpt_update++;
                         break;
                     }
@@ -6454,5 +6604,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_CAS_BRDCAST_HEADER;
-                        m_cpt_inval++;
                         break;
                     }
@@ -6462,5 +6611,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_WRITE_UPDT_HEADER;
-                        m_cpt_update++;
                         break;
                     }
@@ -6469,5 +6617,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_WRITE_BRDCAST_HEADER;
-                        m_cpt_inval++;
                         break;
                     }
@@ -6476,5 +6623,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_CONFIG_INVAL_HEADER;
-                        m_cpt_inval++;
                         break;
                     }
@@ -6482,5 +6628,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_CONFIG_BRDCAST_HEADER;
-                        m_cpt_inval++;
                         break;
                     }
@@ -6490,5 +6635,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_XRAM_RSP_INVAL_HEADER;
-                        m_cpt_inval++;
                         break;
                     }
@@ -6496,5 +6640,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_XRAM_RSP_BRDCAST_HEADER;
-                        m_cpt_inval++;
                         break;
                     }
@@ -6508,5 +6651,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_WRITE_UPDT_HEADER;
-                        m_cpt_update++;
                         break;
                     }
@@ -6514,5 +6656,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_WRITE_BRDCAST_HEADER;
-                        m_cpt_inval++;
                         break;
                     }
@@ -6521,5 +6662,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_CONFIG_INVAL_HEADER;
-                        m_cpt_inval++;
                         break;
                     }
@@ -6527,5 +6667,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_CONFIG_BRDCAST_HEADER;
-                        m_cpt_inval++;
                         break;
                     }
@@ -6534,5 +6673,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_XRAM_RSP_INVAL_HEADER;
-                        m_cpt_inval++;
                         break;
                     }
@@ -6540,5 +6678,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_XRAM_RSP_BRDCAST_HEADER;
-                        m_cpt_inval++;
                         break;
                     }
@@ -6547,5 +6684,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_CAS_UPDT_HEADER;
-                        m_cpt_update++;
                         break;
                     }
@@ -6553,5 +6689,4 @@
                     {
                         r_cc_send_fsm = CC_SEND_CAS_BRDCAST_HEADER;
-                        m_cpt_inval++;
                         break;
                     }
@@ -6564,8 +6699,22 @@
                     {
                         if(not p_dspin_m2p.read) break;
+                        // <Activity Counters>
+                        if (is_local_req(m_config_to_cc_send_srcid_fifo.read()))
+                        {
+                            m_cpt_m_inval_local++;
+                        }
+                        else
+                        {
+                            m_cpt_m_inval_remote++;
+                            m_cpt_m_inval_cost += req_distance(m_config_to_cc_send_srcid_fifo.read());
+                        }
+                        // </Activity Counters>
                         r_cc_send_fsm = CC_SEND_CONFIG_INVAL_NLINE;
                         break;
                     }
                     if(r_config_to_cc_send_multi_req.read()) r_config_to_cc_send_multi_req = false;
+                    // <Activity Counters>
+                    m_cpt_m_inval++;
+                    // </Activity Counters>
                     r_cc_send_fsm = CC_SEND_CONFIG_IDLE;
                     break;
@@ -6575,5 +6724,4 @@
                 {
                     if(not p_dspin_m2p.read) break;
-                    m_cpt_inval_mult++;
                     config_to_cc_send_fifo_get = true;
                     r_cc_send_fsm = CC_SEND_CONFIG_INVAL_HEADER;
@@ -6598,5 +6746,7 @@
                 {
                     if(not p_dspin_m2p.read) break;
-                    m_cpt_inval_brdcast++;
+                    // <Activity Counters>
+                    m_cpt_br_inval++;
+                    // </Activity Counters>
                     r_config_to_cc_send_brdcast_req = false;
                     r_cc_send_fsm = CC_SEND_CONFIG_IDLE;
@@ -6616,8 +6766,22 @@
                     {
                         if(not p_dspin_m2p.read) break;
+                        // <Activity Counters>
+                        if (is_local_req(m_xram_rsp_to_cc_send_srcid_fifo.read()))
+                        {
+                            m_cpt_m_inval_local++;
+                        }
+                        else
+                        {
+                            m_cpt_m_inval_remote++;
+                            m_cpt_m_inval_cost += req_distance(m_xram_rsp_to_cc_send_srcid_fifo.read());
+                        }
+                        // </Activity Counters>
                         r_cc_send_fsm = CC_SEND_XRAM_RSP_INVAL_NLINE;
                         break;
                     }
                     if(r_xram_rsp_to_cc_send_multi_req.read()) r_xram_rsp_to_cc_send_multi_req = false;
+                    // <Activity Counters>
+                    m_cpt_m_inval++;
+                    // </Activity Counters>
                     r_cc_send_fsm = CC_SEND_XRAM_RSP_IDLE;
                     break;
@@ -6627,5 +6791,4 @@
                 {
                     if(not p_dspin_m2p.read) break;
-                    m_cpt_inval_mult++;
                     xram_rsp_to_cc_send_fifo_get = true;
                     r_cc_send_fsm = CC_SEND_XRAM_RSP_INVAL_HEADER;
@@ -6650,5 +6813,7 @@
                 {
                     if(not p_dspin_m2p.read) break;
-                    m_cpt_inval_brdcast++;
+                    // <Activity Counters>
+                    m_cpt_br_inval++;
+                    // </Activity Counters>
                     r_xram_rsp_to_cc_send_brdcast_req = false;
                     r_cc_send_fsm = CC_SEND_XRAM_RSP_IDLE;
@@ -6674,5 +6839,7 @@
                     if(not p_dspin_m2p.read) break;
 
-                    m_cpt_inval_brdcast++;
+                    // <Activity Counters>
+                    m_cpt_br_inval++;
+                    // </Activity Counters>
 
                     r_write_to_cc_send_brdcast_req = false;
@@ -6693,4 +6860,15 @@
                     {
                         if(not p_dspin_m2p.read) break;
+                        // <Activity Counters>
+                        if (is_local_req(m_write_to_cc_send_srcid_fifo.read()))
+                        {
+                            m_cpt_update_local++;
+                        }
+                        else
+                        {
+                            m_cpt_update_remote++;
+                            m_cpt_update_cost += req_distance(m_write_to_cc_send_srcid_fifo.read());
+                        }
+                        // </Activity Counters>
 
                         r_cc_send_fsm = CC_SEND_WRITE_UPDT_NLINE;
@@ -6703,4 +6881,7 @@
                     }
 
+                    // <Activity Counters>
+                    m_cpt_update++;
+                    // </Activity Counters>
                     r_cc_send_fsm = CC_SEND_WRITE_IDLE;
                     break;
@@ -6710,5 +6891,4 @@
                 {
                     if(not p_dspin_m2p.read) break;
-                    m_cpt_update_mult++;
 
                     r_cc_send_cpt = 0;
@@ -6727,5 +6907,5 @@
                 {
                     if(not p_dspin_m2p.read) break;
-                    if(r_cc_send_cpt.read() == (r_write_to_cc_send_count.read()-1))
+                    if (r_cc_send_cpt.read() == r_write_to_cc_send_count.read())
                     {
                         write_to_cc_send_fifo_get = true;
@@ -6748,5 +6928,7 @@
                 {
                     if(not p_dspin_m2p.read) break;
-                    m_cpt_inval_brdcast++;
+                    // <Activity Counters>
+                    m_cpt_br_inval++;
+                    // </Activity Counters>
 
                     r_cas_to_cc_send_brdcast_req = false;
@@ -6767,5 +6949,15 @@
                     {
                         if(not p_dspin_m2p.read) break;
-
+                        // <Activity Counters>
+                        if (is_local_req(m_cas_to_cc_send_srcid_fifo.read()))
+                        {
+                            m_cpt_update_local++;
+                        }
+                        else
+                        {
+                            m_cpt_update_remote++;
+                            m_cpt_update_cost += req_distance(m_cas_to_cc_send_srcid_fifo.read());
+                        }
+                        // </Activity Counters>
                         r_cc_send_fsm = CC_SEND_CAS_UPDT_NLINE;
                         break;
@@ -6778,4 +6970,7 @@
                     }
 
+                    // <Activity Counters>
+                    m_cpt_update++;
+                    // </Activity Counters>
                     r_cc_send_fsm = CC_SEND_CAS_IDLE;
                     break;
@@ -6785,7 +6980,4 @@
                 {
                     if(not p_dspin_m2p.read) break;
-
-                    m_cpt_update_mult++;
-
                     r_cc_send_cpt = 0;
                     r_cc_send_fsm = CC_SEND_CAS_UPDT_DATA;
@@ -7359,6 +7551,5 @@
                 /////////////////////////
             case ALLOC_UPT_MULTI_ACK:     // allocated to MULTI_ACK FSM
-                if ((r_multi_ack_fsm.read() != MULTI_ACK_UPT_LOCK ) and
-                        (r_multi_ack_fsm.read() != MULTI_ACK_UPT_CLEAR))
+                if (r_multi_ack_fsm.read() != MULTI_ACK_UPT_LOCK)
                 {
                     if (r_write_fsm.read() == WRITE_UPT_LOCK)
@@ -7814,5 +8005,5 @@
                         r_alloc_trt_fsm = ALLOC_TRT_IXR_CMD;
 
-                    if((r_xram_rsp_fsm.read()  == XRAM_RSP_DIR_LOCK) and
+                    else if ((r_xram_rsp_fsm.read()  == XRAM_RSP_DIR_LOCK) and
                             (r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP))
                         r_alloc_trt_fsm = ALLOC_TRT_XRAM_RSP;
@@ -8201,5 +8392,5 @@
                         r_alloc_heap_fsm = ALLOC_HEAP_CLEANUP;
 
-                    if(r_xram_rsp_fsm.read() == XRAM_RSP_HEAP_REQ)
+                    else if (r_xram_rsp_fsm.read() == XRAM_RSP_HEAP_REQ)
                         r_alloc_heap_fsm = ALLOC_HEAP_XRAM_RSP;
                     else
@@ -8353,4 +8544,25 @@
         /////////////////////////////
     {
+#if MONITOR_MEMCACHE_FSM == 1
+        p_read_fsm.write        (r_read_fsm.read()       );
+        p_write_fsm.write       (r_write_fsm.read()      );
+        p_xram_rsp_fsm.write    (r_xram_rsp_fsm.read()   );
+        p_cas_fsm.write         (r_cas_fsm.read()        );
+        p_cleanup_fsm.write     (r_cleanup_fsm.read()    );
+        p_config_fsm.write      (r_config_fsm.read()     );
+        p_alloc_heap_fsm.write  (r_alloc_heap_fsm.read() );
+        p_alloc_dir_fsm.write   (r_alloc_dir_fsm.read()  );
+        p_alloc_trt_fsm.write   (r_alloc_trt_fsm.read()  );
+        p_alloc_upt_fsm.write   (r_alloc_upt_fsm.read()  );
+        p_alloc_ivt_fsm.write   (r_alloc_ivt_fsm.read()  );
+        p_tgt_cmd_fsm.write     (r_tgt_cmd_fsm.read()    );
+        p_tgt_rsp_fsm.write     (r_tgt_rsp_fsm.read()    );
+        p_ixr_cmd_fsm.write     (r_ixr_cmd_fsm.read()    );
+        p_ixr_rsp_fsm.write     (r_ixr_rsp_fsm.read()    );
+        p_cc_send_fsm.write     (r_cc_send_fsm.read()    );
+        p_cc_receive_fsm.write  (r_cc_receive_fsm.read() );
+        p_multi_ack_fsm.write   (r_multi_ack_fsm.read()  );
+#endif
+
         ////////////////////////////////////////////////////////////
         // Command signals on the p_vci_ixr port
@@ -8898,5 +9110,5 @@
 
                     p_dspin_m2p.write = true;
-                    p_dspin_m2p.eop   = (r_cc_send_cpt.read() == (r_write_to_cc_send_count.read()-1));
+                    p_dspin_m2p.eop   = (r_cc_send_cpt.read() == r_write_to_cc_send_count.read());
                     p_dspin_m2p.data  = flit;
 
@@ -9039,5 +9251,5 @@
             DspinDhccpParam::dspin_set(
                     flit,
-                    r_cleanup_nline.read() & 0xFFFF,
+                    r_cleanup_nline.read(),
                     DspinDhccpParam::CLACK_SET);
 
@@ -9093,6 +9305,6 @@
 
 // Local Variables:
-// tab-width: 2
-// c-basic-offset: 2
+// tab-width: 4
+// c-basic-offset: 4
 // c-file-offsets:((innamespace . 0)(inline-open . 0))
 // indent-tabs-mode: nil
