Index: /trunk/communication/dspin_dhccp_param/caba/source/include/dspin_dhccp_param.h
===================================================================
--- /trunk/communication/dspin_dhccp_param/caba/source/include/dspin_dhccp_param.h	(revision 467)
+++ /trunk/communication/dspin_dhccp_param/caba/source/include/dspin_dhccp_param.h	(revision 468)
@@ -61,14 +61,5 @@
 
 /*
- * Memory Cache to L1 cache command packets
- *
- * CLEANUP ACKNOWLEDGEMENT
- *
- * flit 1
- * ----------------------------------------------------------------------------------------------
- * EOP:1 | DEST(14 bits) | X(3 bits) | SET_INDEX(16 bits) | WAY_INDEX(2 bits) | TYPE:0b10X | BC:0
- * ----------------------------------------------------------------------------------------------
- *                                                                            | X: 0 DATA  |
- *                                                                            |    1 INST  |
+ * M2P command packets
  *
  * MULTICAST UPDATE
@@ -76,5 +67,5 @@
  * flit 1
  * ----------------------------------------------------------------------------------------------
- * EOP:0 | DEST(14 bits) | X(3 bits) | MEMC_ID(14 bits) | UPDT_INDEX(4 bits) | TYPE:0b00X  | BC:0
+ * EOP:0 | DEST(14 bits) | X(4 bits) | MEMC_ID(14 bits) | UPDT_INDEX(4 bits) | TYPE:0b0X   | BC:0
  * ----------------------------------------------------------------------------------------------
  *                                                                           | X: 0 DATA   |
@@ -99,5 +90,5 @@
  * flit 1
  * ----------------------------------------------------------------------------------------------
- * EOP:0 | DEST(14 bits) | X(3 bits) | MEMC_ID(14 bits) | UPDT_INDEX(4 bits) | TYPE:0b01X | BC:0
+ * EOP:0 | DEST(14 bits) | X(4 bits) | MEMC_ID(14 bits) | UPDT_INDEX(4 bits) | TYPE:0b1X  | BC:0
  * ----------------------------------------------------------------------------------------------
  *                                                                           | X: 0 DATA  |
@@ -120,4 +111,18 @@
  * EOP:1 |        X(5 bits)       |                                              NLINE (34 bits)
  * ----------------------------------------------------------------------------------------------
+ *
+ * M2P clack commands
+ *
+ * CLEANUP ACKNOWLEDGEMENT
+ *
+ * flit 1
+ * ----------------------------------------------------------------------------------------------
+ * EOP:1 | DEST(14 bits) | X(5 bits) | SET_INDEX(16 bits) | WAY_INDEX(2 bits) | TYPE:0bX   | BC:0
+ * ----------------------------------------------------------------------------------------------
+ *                                                                            | X: 0 CLACK |
+ *                                                                            |      DATA  |
+ *                                                                            |    1 CLACK |
+ *                                                                            |      INST  |
+ *
  */
 
@@ -135,6 +140,7 @@
   public:
 
-    static const uint8_t  from_memc_flit_width         = 40;
-    static const uint8_t  from_l1_flit_width           = 33;
+    static const uint8_t  m2p_flit_width               = 40;
+    static const uint8_t  p2m_flit_width               = 33;
+    static const uint8_t  clack_flit_width             = 40;
 
     static const uint8_t  UPDT_INDEX_WIDTH             = 4;
@@ -148,13 +154,14 @@
     static const uint8_t  WAY_INDEX_WIDTH              = 2;
     static const uint8_t  BROADCAST_BOX_WIDTH          = 20;
-    static const uint8_t  MC_TYPE_WIDTH                = 3;
-    static const uint8_t  L1_TYPE_WIDTH                = 2;
-
-    static const uint8_t  FROM_L1_TYPE_SHIFT           = 1;
-    static const uint64_t FROM_L1_TYPE_MASK            = ((1ULL<<L1_TYPE_WIDTH)-1);
-    static const uint8_t  FROM_L1_EOP_SHIFT            = 32;
-    static const uint64_t FROM_L1_EOP_MASK             = 1;
-    static const uint8_t  FROM_L1_BC_SHIFT             = 0;
-    static const uint64_t FROM_L1_BC_MASK              = 1;
+    static const uint8_t  M2P_TYPE_WIDTH               = 2;
+    static const uint8_t  P2M_TYPE_WIDTH               = 2;
+    static const uint8_t  CLACK_TYPE_WIDTH             = 1;
+
+    static const uint8_t  P2M_TYPE_SHIFT               = 1;
+    static const uint64_t P2M_TYPE_MASK                = ((1ULL<<P2M_TYPE_WIDTH)-1);
+    static const uint8_t  P2M_EOP_SHIFT                = 32;
+    static const uint64_t P2M_EOP_MASK                 = 1;
+    static const uint8_t  P2M_BC_SHIFT                 = 0;
+    static const uint64_t P2M_BC_MASK                  = 1;
 
     static const uint8_t  CLEANUP_DEST_SHIFT           = 22;
@@ -174,10 +181,10 @@
     static const uint64_t MULTI_ACK_UPDT_INDEX_MASK    = ((1ULL<<UPDT_INDEX_WIDTH)-1);
 
-    static const uint8_t  FROM_MC_TYPE_SHIFT           = 1;
-    static const uint64_t FROM_MC_TYPE_MASK            = ((1ULL<<MC_TYPE_WIDTH)-1);
-    static const uint8_t  FROM_MC_EOP_SHIFT            = 39;
-    static const uint64_t FROM_MC_EOP_MASK             = 1;
-    static const uint8_t  FROM_MC_BC_SHIFT             = 0;
-    static const uint64_t FROM_MC_BC_MASK              = 1;
+    static const uint8_t  M2P_TYPE_SHIFT               = 1;
+    static const uint64_t M2P_TYPE_MASK                = ((1ULL<<M2P_TYPE_WIDTH)-1);
+    static const uint8_t  M2P_EOP_SHIFT                = 39;
+    static const uint64_t M2P_EOP_MASK                 = 1;
+    static const uint8_t  M2P_BC_SHIFT                 = 0;
+    static const uint64_t M2P_BC_MASK                  = 1;
 
     static const uint8_t  MULTI_INVAL_DEST_SHIFT       = 25;
@@ -205,11 +212,4 @@
     static const uint64_t MULTI_UPDT_DATA_MASK         = ((1ULL<<DATA_WIDTH)-1);
 
-    static const uint8_t  CLEANUP_ACK_DEST_SHIFT       = MULTI_INVAL_DEST_SHIFT;
-    static const uint64_t CLEANUP_ACK_DEST_MASK        = MULTI_INVAL_DEST_MASK;
-    static const uint8_t  CLEANUP_ACK_SET_SHIFT        = 6;
-    static const uint64_t CLEANUP_ACK_SET_MASK         = ((1ULL<<SET_INDEX_WIDTH)-1);
-    static const uint8_t  CLEANUP_ACK_WAY_SHIFT        = 4;
-    static const uint64_t CLEANUP_ACK_WAY_MASK         = ((1ULL<<WAY_INDEX_WIDTH)-1);
-
     static const uint8_t  BROADCAST_BOX_SHIFT          = 19;
     static const uint64_t BROADCAST_BOX_MASK           = ((1ULL<<BROADCAST_BOX_WIDTH)-1);
@@ -219,6 +219,19 @@
     static const uint64_t BROADCAST_NLINE_MASK         = MULTI_INVAL_NLINE_MASK;
 
+    static const uint8_t  CLACK_TYPE_SHIFT             = 1;
+    static const uint64_t CLACK_TYPE_MASK              = ((1ULL<<CLACK_TYPE_WIDTH)-1);
+    static const uint8_t  CLACK_EOP_SHIFT              = 39;
+    static const uint64_t CLACK_EOP_MASK               = 1;
+    static const uint8_t  CLACK_BC_SHIFT               = 0;
+    static const uint64_t CLACK_BC_MASK                = 1;
+    static const uint8_t  CLACK_DEST_SHIFT             = 25;
+    static const uint64_t CLACK_DEST_MASK              = ((1ULL<<SRCID_WIDTH)-1);
+    static const uint8_t  CLACK_SET_SHIFT              = 6;
+    static const uint64_t CLACK_SET_MASK               = ((1ULL<<SET_INDEX_WIDTH)-1);
+    static const uint8_t  CLACK_WAY_SHIFT              = 4;
+    static const uint64_t CLACK_WAY_MASK               = ((1ULL<<WAY_INDEX_WIDTH)-1);
+
     /*
-     * L1 cache to Memory Cache command types
+     * P2M command types
      */
     enum
@@ -231,5 +244,5 @@
 
     /*
-     * Memory Cache to L1 cache command types
+     * M2P command types
      */
     enum
@@ -240,15 +253,22 @@
       TYPE_MULTI_INVAL      = 2,
       TYPE_MULTI_INVAL_DATA = TYPE_MULTI_INVAL,
-      TYPE_MULTI_INVAL_INST = 3,
-      TYPE_CLEANUP_ACK      = 4,
-      TYPE_CLEANUP_ACK_DATA = TYPE_CLEANUP_ACK,
-      TYPE_CLEANUP_ACK_INST = 5
+      TYPE_MULTI_INVAL_INST = 3
     };
 
+    /*
+     * CLACK command types
+     */
+    enum
+    {
+      TYPE_CLACK      = 0,
+      TYPE_CLACK_DATA = TYPE_CLACK,
+      TYPE_CLACK_INST = 1
+    };
+
     enum flit_field_e
     {
-      FROM_L1_TYPE,
-      FROM_L1_EOP,
-      FROM_L1_BC,
+      P2M_TYPE,
+      P2M_EOP,
+      P2M_BC,
 
       CLEANUP_DEST,
@@ -261,7 +281,7 @@
       MULTI_ACK_UPDT_INDEX,
 
-      FROM_MC_TYPE,
-      FROM_MC_EOP,
-      FROM_MC_BC,
+      M2P_TYPE,
+      M2P_EOP,
+      M2P_BC,
 
       MULTI_INVAL_DEST,
@@ -278,7 +298,9 @@
       MULTI_UPDT_DATA,
 
-      CLEANUP_ACK_DEST,
-      CLEANUP_ACK_SET,
-      CLEANUP_ACK_WAY,
+      CLACK_TYPE,
+
+      CLACK_DEST,
+      CLACK_SET,
+      CLACK_WAY,
 
       BROADCAST_BOX,
@@ -291,7 +313,7 @@
       switch(field)
       {
-        GET_FIELD(flit,FROM_L1_TYPE);
-        GET_FIELD(flit,FROM_L1_EOP);
-        GET_FIELD(flit,FROM_L1_BC);
+        GET_FIELD(flit,P2M_TYPE);
+        GET_FIELD(flit,P2M_EOP);
+        GET_FIELD(flit,P2M_BC);
         GET_FIELD(flit,CLEANUP_DEST);
         GET_FIELD(flit,CLEANUP_SRCID);
@@ -301,7 +323,7 @@
         GET_FIELD(flit,MULTI_ACK_DEST);
         GET_FIELD(flit,MULTI_ACK_UPDT_INDEX);
-        GET_FIELD(flit,FROM_MC_TYPE);
-        GET_FIELD(flit,FROM_MC_EOP);
-        GET_FIELD(flit,FROM_MC_BC);
+        GET_FIELD(flit,M2P_TYPE);
+        GET_FIELD(flit,M2P_EOP);
+        GET_FIELD(flit,M2P_BC);
         GET_FIELD(flit,MULTI_INVAL_DEST);
         GET_FIELD(flit,MULTI_INVAL_SRCID);
@@ -315,7 +337,8 @@
         GET_FIELD(flit,MULTI_UPDT_BE);
         GET_FIELD(flit,MULTI_UPDT_DATA);
-        GET_FIELD(flit,CLEANUP_ACK_DEST);
-        GET_FIELD(flit,CLEANUP_ACK_SET);
-        GET_FIELD(flit,CLEANUP_ACK_WAY);
+        GET_FIELD(flit,CLACK_TYPE);
+        GET_FIELD(flit,CLACK_DEST);
+        GET_FIELD(flit,CLACK_SET);
+        GET_FIELD(flit,CLACK_WAY);
         GET_FIELD(flit,BROADCAST_BOX);
         GET_FIELD(flit,BROADCAST_SRCID);
@@ -330,7 +353,7 @@
       switch(field)
       {
-        SET_FIELD(flit,value,FROM_L1_TYPE);
-        SET_FIELD(flit,value,FROM_L1_EOP);
-        SET_FIELD(flit,value,FROM_L1_BC);
+        SET_FIELD(flit,value,P2M_TYPE);
+        SET_FIELD(flit,value,P2M_EOP);
+        SET_FIELD(flit,value,P2M_BC);
         SET_FIELD(flit,value,CLEANUP_DEST);
         SET_FIELD(flit,value,CLEANUP_SRCID);
@@ -340,7 +363,7 @@
         SET_FIELD(flit,value,MULTI_ACK_DEST);
         SET_FIELD(flit,value,MULTI_ACK_UPDT_INDEX);
-        SET_FIELD(flit,value,FROM_MC_TYPE);
-        SET_FIELD(flit,value,FROM_MC_EOP);
-        SET_FIELD(flit,value,FROM_MC_BC);
+        SET_FIELD(flit,value,M2P_TYPE);
+        SET_FIELD(flit,value,M2P_EOP);
+        SET_FIELD(flit,value,M2P_BC);
         SET_FIELD(flit,value,MULTI_INVAL_DEST);
         SET_FIELD(flit,value,MULTI_INVAL_SRCID);
@@ -354,7 +377,8 @@
         SET_FIELD(flit,value,MULTI_UPDT_BE);
         SET_FIELD(flit,value,MULTI_UPDT_DATA);
-        SET_FIELD(flit,value,CLEANUP_ACK_DEST);
-        SET_FIELD(flit,value,CLEANUP_ACK_SET);
-        SET_FIELD(flit,value,CLEANUP_ACK_WAY);
+        SET_FIELD(flit,value,CLACK_TYPE);
+        SET_FIELD(flit,value,CLACK_DEST);
+        SET_FIELD(flit,value,CLACK_SET);
+        SET_FIELD(flit,value,CLACK_WAY);
         SET_FIELD(flit,value,BROADCAST_BOX);
         SET_FIELD(flit,value,BROADCAST_SRCID);
Index: /trunk/modules/vci_cc_vcache_wrapper/caba/metadata/vci_cc_vcache_wrapper.sd
===================================================================
--- /trunk/modules/vci_cc_vcache_wrapper/caba/metadata/vci_cc_vcache_wrapper.sd	(revision 467)
+++ /trunk/modules/vci_cc_vcache_wrapper/caba/metadata/vci_cc_vcache_wrapper.sd	(revision 468)
@@ -37,8 +37,10 @@
 	    ports = [
             Port('caba:vci_initiator', 'p_vci'),
-            Port('caba:dspin_input', 'p_dspin_in', 
+            Port('caba:dspin_input', 'p_dspin_m2p', 
                   dspin_data_size = parameter.Reference('dspin_in_width')),
-            Port('caba:dspin_output', 'p_dspin_out', 
+            Port('caba:dspin_output', 'p_dspin_p2m', 
                   dspin_data_size = parameter.Reference('dspin_out_width')),
+            Port('caba:dspin_input', 'p_dspin_clack', 
+                  dspin_data_size = parameter.Reference('dspin_in_width')),
 	        Port('caba:bit_in','p_irq', parameter.Constant('n_irq')),
 	        Port('caba:bit_in', 'p_resetn', auto = 'resetn'),
Index: /trunk/modules/vci_cc_vcache_wrapper/caba/source/include/vci_cc_vcache_wrapper.h
===================================================================
--- /trunk/modules/vci_cc_vcache_wrapper/caba/source/include/vci_cc_vcache_wrapper.h	(revision 467)
+++ /trunk/modules/vci_cc_vcache_wrapper/caba/source/include/vci_cc_vcache_wrapper.h	(revision 468)
@@ -89,8 +89,6 @@
         // handling coherence requests
         ICACHE_CC_CHECK,
+        ICACHE_CC_UPDT,
         ICACHE_CC_INVAL,
-        ICACHE_CC_UPDT,
-        ICACHE_CC_BROADCAST,
-        ICACHE_CC_SEND_WAIT,
     };
 
@@ -138,8 +136,6 @@
         // handling coherence requests
         DCACHE_CC_CHECK,
+        DCACHE_CC_UPDT,
         DCACHE_CC_INVAL,
-        DCACHE_CC_UPDT,
-        DCACHE_CC_BROADCAST,
-        DCACHE_CC_SEND_WAIT,
         // handling TLB inval (after a coherence or XTN request)
         DCACHE_INVAL_TLB_SCAN,
@@ -173,12 +169,16 @@
     {
         CC_RECEIVE_IDLE,
-        CC_RECEIVE_CLACK,
         CC_RECEIVE_BRDCAST_HEADER,
         CC_RECEIVE_BRDCAST_NLINE,
-        CC_RECEIVE_INVAL_HEADER,
-        CC_RECEIVE_INVAL_NLINE,
-        CC_RECEIVE_UPDT_HEADER,
-        CC_RECEIVE_UPDT_NLINE,
-        CC_RECEIVE_UPDT_DATA,
+        CC_RECEIVE_INS_INVAL_HEADER,
+        CC_RECEIVE_INS_INVAL_NLINE,
+        CC_RECEIVE_INS_UPDT_HEADER,
+        CC_RECEIVE_INS_UPDT_NLINE,
+        CC_RECEIVE_INS_UPDT_DATA,
+        CC_RECEIVE_DATA_INVAL_HEADER,
+        CC_RECEIVE_DATA_INVAL_NLINE,
+        CC_RECEIVE_DATA_UPDT_HEADER,
+        CC_RECEIVE_DATA_UPDT_NLINE,
+        CC_RECEIVE_DATA_UPDT_DATA,
     };
 
@@ -285,10 +285,11 @@
 
 public:
-    sc_in<bool>                                 p_clk;
-    sc_in<bool>                                 p_resetn;
-    sc_in<bool>                                 p_irq[iss_t::n_irq];
-    soclib::caba::VciInitiator<vci_param>       p_vci;
-    soclib::caba::DspinInput <dspin_in_width>   p_dspin_in;
-    soclib::caba::DspinOutput<dspin_out_width>  p_dspin_out;
+    sc_in<bool>                                p_clk;
+    sc_in<bool>                                p_resetn;
+    sc_in<bool>                                p_irq[iss_t::n_irq];
+    soclib::caba::VciInitiator<vci_param>      p_vci;
+    soclib::caba::DspinInput<dspin_in_width>   p_dspin_m2p;
+    soclib::caba::DspinOutput<dspin_out_width> p_dspin_p2m;
+    soclib::caba::DspinInput<dspin_in_width>   p_dspin_clack;
 
 private:
@@ -371,4 +372,9 @@
     sc_signal<bool>         r_icache_cc_need_write;     // activate the cache for writing
 
+    // coherence clack handling
+    sc_signal<bool>         r_icache_clack_req;         // clack request
+    sc_signal<size_t>       r_icache_clack_way;		    // clack way
+    sc_signal<size_t>       r_icache_clack_set;		    // clack set
+
     // icache flush handling
     sc_signal<size_t>       r_icache_flush_count;	    // slot counter used for cache flush
@@ -444,4 +450,9 @@
     sc_signal<bool>         r_dcache_cc_need_write;     // activate the cache for writing
 
+    // coherence clack handling
+    sc_signal<bool>         r_dcache_clack_req;         // clack request
+    sc_signal<size_t>       r_dcache_clack_way;		    // clack way
+    sc_signal<size_t>       r_dcache_clack_set;		    // clack set
+
     // dcache flush handling
     sc_signal<size_t>       r_dcache_flush_count;	    // slot counter used for cache flush
@@ -537,4 +548,10 @@
     sc_signal<paddr_t>      r_cc_receive_dcache_nline;	    // cache line physical address
 
+    ///////////////////////////////////
+    //  DSPIN CLACK INTERFACE REGISTER
+    ///////////////////////////////////
+    sc_signal<bool>         r_dspin_clack_req;
+    sc_signal<uint64_t>     r_dspin_clack_flit;
+    
     //////////////////////////////////////////////////////////////////
     // processor, write buffer, caches , TLBs
Index: /trunk/modules/vci_cc_vcache_wrapper/caba/source/src/vci_cc_vcache_wrapper.cpp
===================================================================
--- /trunk/modules/vci_cc_vcache_wrapper/caba/source/src/vci_cc_vcache_wrapper.cpp	(revision 467)
+++ /trunk/modules/vci_cc_vcache_wrapper/caba/source/src/vci_cc_vcache_wrapper.cpp	(revision 468)
@@ -62,8 +62,6 @@
 
         "ICACHE_CC_CHECK",
+        "ICACHE_CC_UPDT",
         "ICACHE_CC_INVAL",
-        "ICACHE_CC_UPDT",
-        "ICACHE_CC_BROADCAST",
-        "ICACHE_CC_SEND_WAIT",
     };
 
@@ -110,8 +108,6 @@
 
         "DCACHE_CC_CHECK",
+        "DCACHE_CC_UPDT",
         "DCACHE_CC_INVAL",
-        "DCACHE_CC_UPDT",
-        "DCACHE_CC_BROADCAST",
-        "DCACHE_CC_SEND_WAIT",
 
         "DCACHE_INVAL_TLB_SCAN",
@@ -160,12 +156,16 @@
 const char *cc_receive_fsm_state_str[] = {
         "CC_RECEIVE_IDLE",
-        "CC_RECEIVE_CLACK",
         "CC_RECEIVE_BRDCAST_HEADER",
         "CC_RECEIVE_BRDCAST_NLINE",
-        "CC_RECEIVE_INVAL_HEADER",
-        "CC_RECEIVE_INVAL_NLINE",
-        "CC_RECEIVE_UPDT_HEADER",
-        "CC_RECEIVE_UPDT_NLINE",
-        "CC_RECEIVE_UPDT_DATA",
+        "CC_RECEIVE_INS_INVAL_HEADER",
+        "CC_RECEIVE_INS_INVAL_NLINE",
+        "CC_RECEIVE_INS_UPDT_HEADER",
+        "CC_RECEIVE_INS_UPDT_NLINE",
+        "CC_RECEIVE_INS_UPDT_DATA",
+        "CC_RECEIVE_DATA_INVAL_HEADER",
+        "CC_RECEIVE_DATA_INVAL_NLINE",
+        "CC_RECEIVE_DATA_UPDT_HEADER",
+        "CC_RECEIVE_DATA_UPDT_NLINE",
+        "CC_RECEIVE_DATA_UPDT_DATA",
     };
 
@@ -216,6 +216,7 @@
       p_resetn("p_resetn"),
       p_vci("p_vci"),
-      p_dspin_in("p_dspin_in"),
-      p_dspin_out("p_dspin_out"),
+      p_dspin_m2p("p_dspin_m2p"),
+      p_dspin_p2m("p_dspin_p2m"),
+      p_dspin_clack("p_dspin_clack"),
 
       m_cacheability_table( mtd.getCacheabilityTable() ),
@@ -755,4 +756,6 @@
         r_icache_cc_send_req       = false;
 
+        r_icache_clack_req         = false;
+
         // No pending write in pipeline
         r_dcache_wbuf_req          = false;
@@ -775,4 +778,6 @@
         r_dcache_cc_send_req       = false;
 
+        r_dcache_clack_req         = false;
+
         // No request from CC_RECEIVE FSM to ICACHE/DCACHE FSMs
         r_cc_receive_icache_req    = false;
@@ -789,4 +794,6 @@
         r_icache_miss_inval        = false;
         r_dcache_miss_inval        = false;
+
+        r_dspin_clack_req          = false;
 
         // No signalisation  of errors
@@ -1014,4 +1021,12 @@
                         // 5/ uncacheable read miss                     => ICACHE_UNC_REQ
     {
+        // coherence clack interrupt
+        if ( r_icache_clack_req.read() )
+        {
+            r_icache_fsm = ICACHE_CC_CHECK;
+            r_icache_fsm_save = r_icache_fsm.read();
+            break;
+        }
+
         // coherence interrupt
         if ( r_cc_receive_icache_req.read() )
@@ -1242,4 +1257,12 @@
                             // external coherence request are accepted in this state.
     {
+        // coherence clack interrupt
+        if ( r_icache_clack_req.read() )
+        {
+            r_icache_fsm = ICACHE_CC_CHECK;
+            r_icache_fsm_save = r_icache_fsm.read();
+            break;
+        }
+
         // coherence interrupt
         if ( r_cc_receive_icache_req.read() )
@@ -1286,4 +1309,12 @@
                        		        // A cleanup request is generated for each valid line
     {
+        // coherence clack interrupt
+        if ( r_icache_clack_req.read() )
+        {
+            r_icache_fsm = ICACHE_CC_CHECK;
+            r_icache_fsm_save = r_icache_fsm.read();
+            break;
+        }
+
         // coherence request (from CC_RECEIVE FSM)
         if ( r_cc_receive_icache_req.read() )
@@ -1484,4 +1515,12 @@
     {
         if (m_ireq.valid) m_cost_ins_miss_frz++;
+
+        // coherence clack interrupt
+        if ( r_icache_clack_req.read() )
+        {
+            r_icache_fsm = ICACHE_CC_CHECK;
+            r_icache_fsm_save = r_icache_fsm.read();
+            break;
+        }
 
         // coherence interrupt
@@ -1574,4 +1613,12 @@
         if (m_ireq.valid) m_cost_ins_miss_frz++;
 
+        // coherence clack interrupt
+        if ( r_icache_clack_req.read() )
+        {
+            r_icache_fsm = ICACHE_CC_CHECK;
+            r_icache_fsm_save = r_icache_fsm.read();
+            break;
+        }
+
         // coherence interrupt
         if ( r_cc_receive_icache_req.read() )
@@ -1645,4 +1692,12 @@
         if ( m_ireq.valid ) m_cost_ins_miss_frz++;
 
+        // coherence clack interrupt
+        if ( r_icache_clack_req.read() )
+        {
+            r_icache_fsm = ICACHE_CC_CHECK;
+            r_icache_fsm_save = r_icache_fsm.read();
+            break;
+        }
+
         // coherence interrupt
         if ( r_cc_receive_icache_req.read() )
@@ -1716,4 +1771,12 @@
     case ICACHE_UNC_WAIT:	// waiting a response to an uncacheable read from VCI_RSP FSM
     {
+        // coherence clack interrupt
+        if ( r_icache_clack_req.read() )
+        {
+            r_icache_fsm = ICACHE_CC_CHECK;
+            r_icache_fsm_save = r_icache_fsm.read();
+            break;
+        }
+
         // coherence interrupt
         if ( r_cc_receive_icache_req.read() )
@@ -1756,41 +1819,13 @@
         paddr_t  mask  = ~((m_icache_words<<2)-1);
 
-        if (r_cc_receive_icache_type.read() == CC_TYPE_CLACK)
-                           	// We switch the directory slot to EMPTY state
-                            // and reset r_icache_miss_clack if the cleanup ack
-                            // is matching a pending miss
-        {
-
-            if ( m_ireq.valid ) m_cost_ins_miss_frz++;
-
-#ifdef INSTRUMENTATION
-m_cpt_icache_dir_write++;
-#endif
-            r_icache.write_dir( 0,
-                                r_cc_receive_icache_way.read(),
-                                r_cc_receive_icache_set.read(),
-                                CACHE_SLOT_STATE_EMPTY);
-
-            if ( (r_icache_miss_set.read() == r_cc_receive_icache_set.read()) and
-                 (r_icache_miss_way.read() == r_cc_receive_icache_way.read()) )
-                    r_icache_miss_clack = false;
-
-            r_icache_fsm = r_icache_fsm_save.read() ;
-            r_cc_receive_icache_req = false;
-
-#if DEBUG_ICACHE
-if ( m_debug_activated )
-{
-    std::cout << "  <PROC " << name()
-    << " ICACHE_CC_CHECK>  CC_TYPE_CLACK slot returns to empty state"
-    << " set = " << r_cc_receive_icache_set.read()
-    << " / way = " << r_cc_receive_icache_way.read() << std::endl;
-}
-#endif
-        }
-        else if( ((r_icache_fsm_save.read() == ICACHE_MISS_SELECT) or
-                 (r_icache_fsm_save.read() == ICACHE_MISS_WAIT) or
-                 (r_icache_fsm_save.read() == ICACHE_MISS_DIR_UPDT)) and
-                 ((r_icache_vci_paddr.read() & mask) == (paddr & mask)) ) // matching
+
+        // Match between MISS address and CC address
+        // note: In the same cycle we can handle a CLACK and a MISS match
+        // because the CLACK access the directory but the MISS match dont.
+        if (r_cc_receive_icache_req.read() and
+          ((r_icache_fsm_save.read() == ICACHE_MISS_SELECT  )  or
+           (r_icache_fsm_save.read() == ICACHE_MISS_WAIT    )  or
+           (r_icache_fsm_save.read() == ICACHE_MISS_DIR_UPDT)) and
+          ((r_icache_vci_paddr.read() & mask) == (paddr & mask)) ) // matching
         {
             // signaling the matching
@@ -1803,4 +1838,5 @@
                 r_icache_fsm        = ICACHE_CC_UPDT;
                 r_icache_cc_word    = r_cc_receive_word_idx.read();
+
                 // just pop the fifo , don't write in icache
                 r_icache_cc_need_write = false;
@@ -1821,63 +1857,33 @@
 #endif
         }
-        else  								                            // no match
-        {
-            int	        state = 0;
-            size_t 	    way = 0;
-            size_t 	    set = 0;
-            size_t 	    word = 0;
+
+        // CLACK handler
+        // We switch the directory slot to EMPTY state
+        // and reset r_icache_miss_clack if the cleanup ack
+        // is matching a pending miss.
+        if ( r_icache_clack_req.read() )
+        {
+
+            if ( m_ireq.valid ) m_cost_ins_miss_frz++;
 
 #ifdef INSTRUMENTATION
-m_cpt_icache_dir_read++;
-#endif
-            r_icache.read_dir(paddr,
-                              &state,
-                              &way,
-                              &set,
-                              &word);
-
-            r_icache_cc_way = way;
-            r_icache_cc_set = set;
-
-            if ( state == CACHE_SLOT_STATE_VALID)            // hit
-            {
-                // need to update the cache state
-                r_icache_cc_need_write = true;
-                if (r_cc_receive_icache_type.read() == CC_TYPE_UPDT)  // hit update
-                {
-                    r_icache_fsm          = ICACHE_CC_UPDT;
-                    r_icache_cc_word      = r_cc_receive_word_idx.read();
-                }
-                else if (r_cc_receive_icache_type.read() == CC_TYPE_INVAL)   // hit inval
-                {
-                    r_icache_fsm          = ICACHE_CC_INVAL;
-                }
-                else if (r_cc_receive_icache_type.read() == CC_TYPE_BRDCAST)  // hit broadcast
-                {
-                    r_icache_fsm          = ICACHE_CC_BROADCAST;
-                }
-            }
-            else                                      // miss
-            {
-                // multicast acknowledgement required in case of update
-                if(r_cc_receive_icache_type.read() == CC_TYPE_UPDT)
-                {
-                    r_icache_fsm          = ICACHE_CC_UPDT;
-                    r_icache_cc_word      = r_cc_receive_word_idx.read();
-                    // just pop the fifo , don't write in icache
-                    r_icache_cc_need_write = false;
-                }
-                else // No response needed
-                {
-                    r_cc_receive_icache_req = false;
-                    r_icache_fsm          = r_icache_fsm_save.read();
-                }
-            }
-        }
-        break;
-    }
-    /////////////////////
-    case ICACHE_CC_INVAL:  	// hit inval : switch slot to EMPTY state
-    {
+m_cpt_icache_dir_write++;
+#endif
+            r_icache.write_dir( 0,
+                                r_icache_clack_way.read(),
+                                r_icache_clack_set.read(),
+                                CACHE_SLOT_STATE_EMPTY);
+
+            if ( (r_icache_miss_set.read() == r_icache_clack_set.read()) and
+                 (r_icache_miss_way.read() == r_icache_clack_way.read()) )
+            {
+                r_icache_miss_clack = false;
+            }
+
+            r_icache_clack_req = false;
+
+            // return to cc_save state if no pending CC request
+            if ( not r_cc_receive_icache_req.read() )
+                r_icache_fsm = r_icache_fsm_save.read();
 
 #if DEBUG_ICACHE
@@ -1885,38 +1891,105 @@
 {
     std::cout << "  <PROC " << name()
-              << " ICACHE_CC_INVAL> slot returns to empty state"
-              << " set = " << r_icache_cc_set.read()
-              << " / way = " << r_icache_cc_way.read() << std::endl;
+        << " ICACHE_CC_CHECK>  CC_TYPE_CLACK slot returns to empty state"
+        << " set = " << r_icache_clack_set.read()
+        << " / way = " << r_icache_clack_way.read() << std::endl;
 }
 #endif
+
+            break;
+        }
+
+        // wait if pending request to CC_SEND. This way if there are pending
+        // CLACK they can be treated in this state and then a deadlock
+        // situation is avoided
+        if ( r_icache_cc_send_req.read() ) break;
+
+        // CC request handler
+
+        int	        state = 0;
+        size_t 	    way = 0;
+        size_t 	    set = 0;
+        size_t 	    word = 0;
 
 #ifdef INSTRUMENTATION
 m_cpt_icache_dir_read++;
 #endif
-        if (r_icache_cc_need_write.read())
-        {
-            r_icache.write_dir( 0,
-	                            r_icache_cc_way.read(),
-	                            r_icache_cc_set.read(),
-                                CACHE_SLOT_STATE_EMPTY );
-            // no need to write in the cache anymore
-            r_icache_cc_need_write = false;
-        }
-
-        // multicast acknowledgement
-        // send a request to cc_send_fsm
-        if(not r_icache_cc_send_req.read()) // cc_send is available
-        {
-            // coherence request completed
-            r_cc_receive_icache_req = false;
-            // request multicast acknowledgement
-            r_icache_cc_send_req = true;
-            r_icache_cc_send_nline = r_cc_receive_icache_nline.read();
-            r_icache_cc_send_updt_tab_idx = r_cc_receive_icache_updt_tab_idx.read();
-            r_icache_cc_send_type = CC_TYPE_MULTI_ACK;
-
-            r_icache_fsm          = r_icache_fsm_save.read();
-        }
-        //else wait for previous cc_send request to be sent
+        r_icache.read_dir(paddr,
+                          &state,
+                          &way,
+                          &set,
+                          &word);
+
+        r_icache_cc_way = way;
+        r_icache_cc_set = set;
+
+        if ( state == CACHE_SLOT_STATE_VALID)            // hit
+        {
+            // need to update the cache state
+            if (r_cc_receive_icache_type.read() == CC_TYPE_UPDT)  // hit update
+            {
+                r_icache_cc_need_write = true;
+                r_icache_fsm           = ICACHE_CC_UPDT;
+                r_icache_cc_word       = r_cc_receive_word_idx.read();
+            }
+            else if ( r_cc_receive_icache_type.read() == CC_TYPE_INVAL ) // hit inval
+            {
+                r_icache_fsm           = ICACHE_CC_INVAL;
+            }
+        }
+        else                                      // miss
+        {
+            // multicast acknowledgement required in case of update
+            if(r_cc_receive_icache_type.read() == CC_TYPE_UPDT)
+            {
+                r_icache_fsm           = ICACHE_CC_UPDT;
+                r_icache_cc_word       = r_cc_receive_word_idx.read();
+
+                // just pop the fifo , don't write in icache
+                r_icache_cc_need_write = false;
+            }
+            else // No response needed
+            {
+                r_cc_receive_icache_req = false;
+                r_icache_fsm            = r_icache_fsm_save.read();
+            }
+        }
+        break;
+    }
+    /////////////////////
+    case ICACHE_CC_INVAL:  	// hit inval : switch slot to ZOMBI state
+    {
+        assert (not r_icache_cc_send_req.read() &&
+                "ERROR in ICACHE_CC_INVAL: the r_icache_cc_send_req "
+                "must not be set");
+
+#ifdef INSTRUMENTATION
+m_cpt_icache_dir_read++;
+#endif
+
+        // Switch slot state to ZOMBI and send CLEANUP command 
+        r_icache.write_dir( 0,
+                            r_icache_cc_way.read(),
+                            r_icache_cc_set.read(),
+                            CACHE_SLOT_STATE_ZOMBI );
+
+        // coherence request completed
+        r_icache_cc_send_req   = true;
+        r_icache_cc_send_nline = r_cc_receive_icache_nline.read();
+        r_icache_cc_send_way   = r_icache_cc_way.read();
+        r_icache_cc_send_type  = CC_TYPE_CLEANUP;
+
+        r_icache_fsm           = r_icache_fsm_save.read();
+
+#if DEBUG_ICACHE
+if ( m_debug_activated )
+{
+std::cout << "  <PROC " << name()
+          << " ICACHE_CC_INVAL> slot returns to ZOMBI state"
+          << " set = " << r_icache_cc_set.read()
+          << " / way = " << r_icache_cc_way.read() << std::endl;
+}
+#endif
+
         break;
     }
@@ -1924,4 +1997,28 @@
     case ICACHE_CC_UPDT:	// hit update : write one word per cycle
     {
+        assert (not r_icache_cc_send_req.read() &&
+                "ERROR in ICACHE_CC_UPDT: the r_icache_cc_send_req "
+                "must not be set");
+
+        if ( not r_cc_receive_updt_fifo_be.rok() ) break;
+
+
+        size_t  word  = r_icache_cc_word.read();
+        size_t  way   = r_icache_cc_way.read();
+        size_t  set   = r_icache_cc_set.read();
+
+        if (r_icache_cc_need_write.read())
+        {
+            r_icache.write( way,
+                            set,
+                            word,
+                            r_cc_receive_updt_fifo_data.read(),
+                            r_cc_receive_updt_fifo_be.read() );
+
+            r_icache_cc_word = word+1;
+
+#ifdef INSTRUMENTATION
+m_cpt_icache_data_write++;
+#endif
 
 #if DEBUG_ICACHE
@@ -1935,96 +2032,28 @@
 }
 #endif
-
-#ifdef INSTRUMENTATION
-m_cpt_icache_data_write++;
-#endif
-        size_t  word  = r_icache_cc_word.read();
-        size_t  way   = r_icache_cc_way.read();
-        size_t  set   = r_icache_cc_set.read();
-
-        if (r_cc_receive_updt_fifo_be.rok())
-        {
-            if (r_icache_cc_need_write.read())
-            {
-                r_icache.write( way,
-                                set,
-                                word,
-                                r_cc_receive_updt_fifo_data.read(),
-                                r_cc_receive_updt_fifo_be.read() );
-
-                r_icache_cc_word = word+1;
-            }
-            if ( r_cc_receive_updt_fifo_eop.read() )	// last word
-            {
-                // no need to write in the cache anymore
-                r_icache_cc_need_write = false;
-                // wait to send a request to cc_send_fsm
-                if(not r_icache_cc_send_req.read()) // cc_send is available
-                {
-                    //consume last flit
-                    cc_receive_updt_fifo_get  = true;
-                    // coherence request completed
-                    r_cc_receive_icache_req = false;
-                    // request multicast acknowledgement
-                    r_icache_cc_send_req = true;
-                    r_icache_cc_send_nline = r_cc_receive_icache_nline.read();
-                    r_icache_cc_send_updt_tab_idx = r_cc_receive_icache_updt_tab_idx.read();
-                    r_icache_cc_send_type = CC_TYPE_MULTI_ACK;
-
-                    r_icache_fsm          = r_icache_fsm_save.read();
-                }
-            }
-            else
-            {
-                //consume fifo if not eop
-                cc_receive_updt_fifo_get  = true;
-            }
-        }
+        }
+
+        if ( r_cc_receive_updt_fifo_eop.read() )	// last word
+        {
+            // no need to write in the cache anymore
+            r_icache_cc_need_write        = false;
+
+            // coherence request completed
+            r_cc_receive_icache_req       = false;
+
+            // request multicast acknowledgement
+            r_icache_cc_send_req          = true;
+            r_icache_cc_send_nline        = r_cc_receive_icache_nline.read();
+            r_icache_cc_send_updt_tab_idx = r_cc_receive_icache_updt_tab_idx.read();
+            r_icache_cc_send_type         = CC_TYPE_MULTI_ACK;
+
+            r_icache_fsm                  = r_icache_fsm_save.read();
+        }
+        //consume fifo if not eop
+        cc_receive_updt_fifo_get  = true;
+
         break;
     }
-    /////////////////////////
-    case ICACHE_CC_BROADCAST:  // hit broadcast : switch slot to ZOMBI state
-                               // and request a cleanup
-    {
-
-#if DEBUG_ICACHE
-if ( m_debug_activated )
-{
-    std::cout << "  <PROC " << name()
-              << " ICACHE_CC_BROADCAST > Slot goes to zombi state "
-              << " set = " << r_icache_cc_set.read()
-              << " / way = " << r_icache_cc_way.read() << std::endl;
-}
-#endif
-
-#ifdef INSTRUMENTATION
-m_cpt_icache_dir_write++;
-#endif
-        if (r_icache_cc_need_write.read())
-        {
-            r_icache.write_dir( r_icache_cc_way.read(),
-	                            r_icache_cc_set.read(),
-                                CACHE_SLOT_STATE_ZOMBI );
-            // no need to write in the cache anymore
-            r_icache_cc_need_write = false;
-        }
-
-        // cleanup
-        // send a request to cc_send_fsm
-        if(not r_icache_cc_send_req.read()) // cc_send is available
-        {
-            // coherence request completed
-            r_cc_receive_icache_req = false;
-            // request cleanup
-            r_icache_cc_send_req = true;
-            r_icache_cc_send_nline = r_cc_receive_icache_nline.read();
-            r_icache_cc_send_way   = r_icache_cc_way.read();
-            r_icache_cc_send_type  = CC_TYPE_CLEANUP;
-
-            r_icache_fsm          = r_icache_fsm_save.read();
-        }
-        //else wait for previous cc_send request to be sent
-        break;
-    }
+
     } // end switch r_icache_fsm
 
@@ -2308,4 +2337,10 @@
         }
 
+        // coherence clack request (from DSPIN CLACK)
+        else if ( r_dcache_clack_req.read() )
+        {
+            r_dcache_fsm = DCACHE_CC_CHECK;
+            r_dcache_fsm_cc_save = r_dcache_fsm.read();
+        }
         // coherence request (from CC_RECEIVE FSM)
         else if ( r_cc_receive_dcache_req.read() )
@@ -2912,4 +2947,12 @@
     case DCACHE_TLB_PTE1_GET:	// try to read a PT1 entry in dcache
     {
+        // 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() )
@@ -3209,4 +3252,12 @@
     case DCACHE_TLB_PTE2_GET:	// Try to get a PTE2 (64 bits) in the dcache
     {
+        // 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() )
@@ -3506,4 +3557,12 @@
 
     {
+        // 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() )
@@ -3577,4 +3636,12 @@
                                 // as there is a risk of dead-lock
     {
+        // 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() )
@@ -3582,4 +3649,5 @@
             r_dcache_fsm = DCACHE_CC_CHECK;
             r_dcache_fsm_cc_save = r_dcache_fsm.read();
+            break;
         }
 
@@ -3598,4 +3666,12 @@
                                     // and because it can exist a 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() )
@@ -3633,4 +3709,12 @@
                                 // returns to IDLE and flush TLBs when last slot
     {
+        // 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() )
@@ -3893,4 +3977,12 @@
     {
         if ( m_dreq.valid) m_cost_data_miss_frz++;
+
+        // 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)
@@ -4009,4 +4101,12 @@
     {
         if ( m_dreq.valid) m_cost_data_miss_frz++;
+
+        // 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)
@@ -4125,4 +4225,12 @@
         if ( m_dreq.valid) m_cost_data_miss_frz++;
 
+        // 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() )
@@ -4199,4 +4307,12 @@
     case DCACHE_UNC_WAIT:  // waiting a response to an uncacheable read
     {
+        // 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() )
@@ -4236,4 +4352,12 @@
     case DCACHE_LL_WAIT:    // waiting VCI response to a LL transaction
     {
+        // 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() )
@@ -4282,4 +4406,12 @@
     case DCACHE_SC_WAIT:	// waiting VCI response to a SC transaction
     {
+        // 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() )
@@ -4321,5 +4453,5 @@
         size_t   way;
         size_t   set;
-        size_t   word;	// unused
+        size_t   word; // unused
         int      state;
 
@@ -4374,4 +4506,12 @@
                                     // - if the CAS is a failure, we just retry the write.
     {
+        // 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() )
@@ -4382,5 +4522,5 @@
         }
 
-        if ( r_vci_rsp_data_error.read() )	// bus error
+        if ( r_vci_rsp_data_error.read() )      // bus error
         {
             std::cout << "BUS ERROR in DCACHE_DIRTY_WAIT state" << std::endl;
@@ -4388,5 +4528,5 @@
             exit(0);
         }
-        else if ( r_vci_rsp_fifo_dcache.rok() )	// response available
+        else if ( r_vci_rsp_fifo_dcache.rok() ) // response available
         {
             vci_rsp_fifo_dcache_get = true;
@@ -4432,40 +4572,13 @@
 #endif
 
-        if (r_cc_receive_dcache_type.read() == CC_TYPE_CLACK)
-                            // We switch the directory slot to EMPTY state
-                            // and reset r_icache_miss_clack if the cleanup ack
-                            // is matching a pending miss.
-        {
-
-            if ( m_dreq.valid ) m_cost_data_miss_frz++;
-
-#ifdef INSTRUMENTATION
-m_cpt_dcache_dir_write++;
-#endif
-            r_dcache.write_dir( 0,
-                                r_cc_receive_dcache_way.read(),
-                                r_cc_receive_dcache_set.read(),
-                                CACHE_SLOT_STATE_EMPTY);
-
-            if ( (r_dcache_miss_set.read() == r_cc_receive_dcache_set.read()) and
-                 (r_dcache_miss_way.read() == r_cc_receive_dcache_way.read()) )
-                  r_dcache_miss_clack = false;
-
-            r_dcache_fsm = r_dcache_fsm_cc_save.read() ;
-            r_cc_receive_dcache_req = false;
-#if DEBUG_DCACHE
-if ( m_debug_activated )
-{
-    std::cout << "  <PROC " << name()
-              << " DCACHE_CC_CHECK> CC_TYPE_CLACK Switch slot to EMPTY state"
-              << " set = " << r_cc_receive_dcache_set.read()
-              << " / way = " << r_cc_receive_dcache_way.read() << std::endl;
-}
-#endif
-        }
-        else if( ((r_dcache_fsm_cc_save == DCACHE_MISS_SELECT) or
-                  (r_dcache_fsm_cc_save == DCACHE_MISS_WAIT) or
-                  (r_dcache_fsm_cc_save == DCACHE_MISS_DIR_UPDT)) and
-                  ((r_dcache_vci_paddr.read() & mask) == (paddr & mask)) ) // matching
+        
+        // Match between MISS address and CC address
+        // note: In the same cycle we can handle a CLACK and a MISS match
+        // because the CLACK access the directory but the MISS match dont.
+        if (r_cc_receive_dcache_req.read() and 
+          ((r_dcache_fsm_cc_save == DCACHE_MISS_SELECT  )  or
+           (r_dcache_fsm_cc_save == DCACHE_MISS_WAIT    )  or
+           (r_dcache_fsm_cc_save == DCACHE_MISS_DIR_UPDT)) and
+          ((r_dcache_vci_paddr.read() & mask) == (paddr & mask))) // matching
         {
             // signaling matching
@@ -4478,4 +4591,5 @@
                 r_dcache_fsm        = DCACHE_CC_UPDT;
                 r_dcache_cc_word    = r_cc_receive_word_idx.read();
+
                 // just pop the fifo , don't write in icache
                 r_dcache_cc_need_write = false;
@@ -4485,5 +4599,5 @@
             {
                 r_cc_receive_dcache_req = false;
-                r_dcache_fsm          = r_dcache_fsm_cc_save.read();
+                r_dcache_fsm            = r_dcache_fsm_cc_save.read();
             }
 
@@ -4496,59 +4610,102 @@
 }
 #endif
-
-        }
-        else                                                    // no match
-	    {
-            int        state = 0;
-            size_t 	   way = 0;
-            size_t 	   set = 0;
-            size_t	   word = 0;
+        }
+
+        // CLACK handler
+        // We switch the directory slot to EMPTY state and reset
+        // r_dcache_miss_clack if the cleanup ack is matching a pending miss.
+        if ( r_dcache_clack_req.read() )
+        {
+            if ( m_dreq.valid ) m_cost_data_miss_frz++;
+
+#ifdef INSTRUMENTATION
+m_cpt_dcache_dir_write++;
+#endif
+            r_dcache.write_dir( 0,
+                                r_dcache_clack_way.read(),
+                                r_dcache_clack_set.read(),
+                                CACHE_SLOT_STATE_EMPTY);
+
+            if ( (r_dcache_miss_set.read() == r_dcache_clack_set.read()) and
+                 (r_dcache_miss_way.read() == r_dcache_clack_way.read()) )
+            {
+                  r_dcache_miss_clack = false;
+            }
+
+            r_dcache_clack_req = false;
+
+            // return to cc_save state if no pending CC request
+            if ( not r_cc_receive_dcache_req.read() )
+            {
+                r_dcache_fsm = r_dcache_fsm_cc_save.read() ;
+            }
+
+#if DEBUG_DCACHE
+if ( m_debug_activated )
+{
+    std::cout << "  <PROC " << name()
+              << " DCACHE_CC_CHECK> CC_TYPE_CLACK Switch slot to EMPTY state"
+              << " set = " << r_dcache_clack_set.read()
+              << " / way = " << r_dcache_clack_way.read() << std::endl;
+}
+#endif
+            break;
+        }
+
+        // wait if pending request to CC_SEND. This way if there are pending
+        // CLACK they can be treated in this state and then a deadlock
+        // situation is avoided
+        if ( r_dcache_cc_send_req.read() ) break;
+
+        // CC request handler
+       
+        int    state = 0;
+        size_t way   = 0;
+        size_t set   = 0;
+        size_t word  = 0;
 
 #ifdef INSTRUMENTATION
 m_cpt_dcache_dir_read++;
 #endif
-            r_dcache.read_dir( paddr,
-                               &state,
-                               &way,
-                               &set,
-                               &word );	// unused
-
-            r_dcache_cc_way = way;
-            r_dcache_cc_set = set;
-
-            if ( state == CACHE_SLOT_STATE_VALID)            // hit
-            {
-                // need to update the cache state
+        r_dcache.read_dir( paddr,
+                           &state,
+                           &way,
+                           &set,
+                           &word ); // unused
+
+        r_dcache_cc_way = way;
+        r_dcache_cc_set = set;
+
+        if ( state == CACHE_SLOT_STATE_VALID) // hit
+        {
+            // need to update the cache state
+            if (r_cc_receive_dcache_type.read() == CC_TYPE_UPDT) // hit update
+            {
                 r_dcache_cc_need_write = true;
-                if (r_cc_receive_dcache_type.read() == CC_TYPE_UPDT)  // hit update
-                {
-                    r_dcache_fsm          = DCACHE_CC_UPDT;
-                    r_dcache_cc_word      = r_cc_receive_word_idx.read();
-                }
-                else if (r_cc_receive_dcache_type.read() == CC_TYPE_INVAL)   // hit inval
-                {
-                    r_dcache_fsm          = DCACHE_CC_INVAL;
-                }
-                else if ( r_cc_receive_dcache_type.read() == CC_TYPE_BRDCAST)  // hit broadcast
-                {
-                    r_dcache_fsm          = DCACHE_CC_BROADCAST;
-                }
-            }
-            else                                      // miss
-            {
-                // multicast acknowledgement required in case of update
-                if(r_cc_receive_dcache_type.read() == CC_TYPE_UPDT)
-                {
-                    r_dcache_fsm          = DCACHE_CC_UPDT;
-                    r_dcache_cc_word      = r_cc_receive_word_idx.read();
-                    // just pop the fifo , don't write in icache
-                    r_dcache_cc_need_write = false;
-                }
-                else // No response needed
-                {
-                    r_cc_receive_dcache_req = false;
-                    r_dcache_fsm          = r_dcache_fsm_cc_save.read();
-                }
-            }
+                r_dcache_fsm           = DCACHE_CC_UPDT;
+                r_dcache_cc_word       = r_cc_receive_word_idx.read();
+            }
+            else if ( r_cc_receive_dcache_type.read() == CC_TYPE_INVAL ) // hit inval
+            {
+                r_dcache_fsm           = DCACHE_CC_INVAL;
+            }
+        }
+        else                                  // miss
+        {
+            // multicast acknowledgement required in case of update
+            if(r_cc_receive_dcache_type.read() == CC_TYPE_UPDT)
+            {
+                r_dcache_fsm           = DCACHE_CC_UPDT;
+                r_dcache_cc_word       = r_cc_receive_word_idx.read();
+
+                // just pop the fifo , don't write in icache
+                r_dcache_cc_need_write = false;
+            }
+            else // No response needed
+            {
+                r_cc_receive_dcache_req = false;
+                r_dcache_fsm            = r_dcache_fsm_cc_save.read();
+            }
+        }
 
 #if DEBUG_DCACHE
@@ -4562,32 +4719,30 @@
 }
 #endif
-        }
+
         break;
     }
     /////////////////////
-    case DCACHE_CC_INVAL:   	// hit inval: switch slot to EMPTY state,
-                                // after possible invalidation of copies in TLBs
-    {
-        size_t	 way    = r_dcache_cc_way.read();
-        size_t	 set    = r_dcache_cc_set.read();
-
-        if (r_dcache_cc_need_write.read())
-        {
-            if ( r_dcache_in_tlb[way*m_dcache_sets+set] ) 			// selective TLB inval
-            {
-                r_dcache_in_tlb[way*m_dcache_sets+set] = false;
-                r_dcache_tlb_inval_line  = r_cc_receive_dcache_nline.read();
-                r_dcache_tlb_inval_set   = 0;
-                r_dcache_fsm_scan_save   = r_dcache_fsm.read();
-                r_dcache_fsm             = DCACHE_INVAL_TLB_SCAN;
-                break;
-            }
-            else
-            {
-                if ( r_dcache_contains_ptd[way*m_dcache_sets+set] ) 	// TLB flush
-                {
-                    r_itlb.reset();
-                    r_dtlb.reset();
-                    r_dcache_contains_ptd[way*m_dcache_sets+set] = false;
+    case DCACHE_CC_INVAL: // hit inval: switch slot to ZOMBI state and send a
+                          // CLEANUP after possible invalidation of copies in
+                          // TLBs
+    {
+        size_t way    = r_dcache_cc_way.read();
+        size_t set    = r_dcache_cc_set.read();
+
+        if ( r_dcache_in_tlb[way*m_dcache_sets+set] )       // selective TLB inval
+        {
+            r_dcache_in_tlb[way*m_dcache_sets+set] = false;
+            r_dcache_tlb_inval_line  = r_cc_receive_dcache_nline.read();
+            r_dcache_tlb_inval_set   = 0;
+            r_dcache_fsm_scan_save   = r_dcache_fsm.read();
+            r_dcache_fsm             = DCACHE_INVAL_TLB_SCAN;
+            break;
+        }
+
+        if ( r_dcache_contains_ptd[way*m_dcache_sets+set] ) // TLB flush
+        {
+            r_itlb.reset();
+            r_dtlb.reset();
+            r_dcache_contains_ptd[way*m_dcache_sets+set] = false;
 
 #if DEBUG_DCACHE
@@ -4598,12 +4753,23 @@
 }
 #endif
-                }
-
-                r_dcache.write_dir( 0,
-                                    way,
-                                    set,
-                                    CACHE_SLOT_STATE_EMPTY );
-
-                r_dcache_cc_need_write = false;
+        }
+
+        assert (not r_dcache_cc_send_req.read() &&
+                "ERROR in DCACHE_CC_INVAL: the r_dcache_cc_send_req "
+                "must not be set");
+
+        // Switch slot state to ZOMBI and send CLEANUP command 
+        r_dcache.write_dir( 0,
+                            way,
+                            set,
+                            CACHE_SLOT_STATE_ZOMBI );
+
+        // coherence request completed
+        r_cc_receive_dcache_req = false;
+        r_dcache_cc_send_req    = true;
+        r_dcache_cc_send_nline  = r_cc_receive_dcache_nline.read();
+        r_dcache_cc_send_way    = r_dcache_cc_way.read();
+        r_dcache_cc_send_type   = CC_TYPE_CLEANUP;
+        r_dcache_fsm            = r_dcache_fsm_cc_save.read();
 
 #if DEBUG_DCACHE
@@ -4611,55 +4777,35 @@
 {
     std::cout << "  <PROC " << name()
-              << " DCACHE_CC_INVAL> Switch slot to EMPTY state:" << std::dec
-              << " / WAY = " << way
-              << " / SET = " << set << std::endl;
+        << " DCACHE_CC_INVAL> Switch slot to EMPTY state:" << std::dec
+        << " / WAY = " << way
+        << " / SET = " << set << std::endl;
 }
 #endif
-            }
-        }
-        // multicast acknowledgement
-        // send a request to cc_send_fsm
-        if(not r_dcache_cc_send_req.read()) // cc_send is available
-        {
-            // coherence request completed
-            r_cc_receive_dcache_req = false;
-            // request multicast acknowledgement
-            r_dcache_cc_send_req = true;
-            r_dcache_cc_send_nline = r_cc_receive_dcache_nline.read();
-            r_dcache_cc_send_updt_tab_idx = r_cc_receive_dcache_updt_tab_idx.read();
-            r_dcache_cc_send_type = CC_TYPE_MULTI_ACK;
-
-            r_dcache_fsm          = r_dcache_fsm_cc_save.read();
-        }
-        //else wait for previous cc_send request to be sent
         break;
     }
     ///////////////////
-    case DCACHE_CC_UPDT:    	// hit update: write one word per cycle,
+    case DCACHE_CC_UPDT:        // hit update: write one word per cycle,
                                 // after possible invalidation of copies in TLBs
     {
-        size_t	 word       = r_dcache_cc_word.read();
-        size_t	 way        = r_dcache_cc_way.read();
-        size_t	 set        = r_dcache_cc_set.read();
-
-        if (r_cc_receive_updt_fifo_be.rok())
-        {
-            if (r_dcache_cc_need_write.read())
-            {
-                if ( r_dcache_in_tlb[way*m_dcache_sets+set] ) 			// selective TLB inval
-                {
-                    r_dcache_in_tlb[way*m_dcache_sets+set] = false;
-                    r_dcache_tlb_inval_line  = r_cc_receive_dcache_nline.read();
-                    r_dcache_tlb_inval_set   = 0;
-                    r_dcache_fsm_scan_save   = r_dcache_fsm.read();
-                    r_dcache_fsm             = DCACHE_INVAL_TLB_SCAN;
-                    break;
-                }
-
-                if ( r_dcache_contains_ptd[way*m_dcache_sets+set] ) 	// TLB flush
-                {
-                    r_itlb.reset();
-                    r_dtlb.reset();
-                    r_dcache_contains_ptd[way*m_dcache_sets+set] = false;
+        size_t word       = r_dcache_cc_word.read();
+        size_t way        = r_dcache_cc_way.read();
+        size_t set        = r_dcache_cc_set.read();
+
+        if ( r_dcache_in_tlb[way*m_dcache_sets+set] )       // selective TLB inval
+        {
+            r_dcache_in_tlb[way*m_dcache_sets+set] = false;
+            r_dcache_tlb_inval_line = r_cc_receive_dcache_nline.read();
+            r_dcache_tlb_inval_set  = 0;
+            r_dcache_fsm_scan_save  = r_dcache_fsm.read();
+            r_dcache_fsm            = DCACHE_INVAL_TLB_SCAN;
+
+            break;
+        }
+
+        if ( r_dcache_contains_ptd[way*m_dcache_sets+set] ) // TLB flush
+        {
+            r_itlb.reset();
+            r_dtlb.reset();
+            r_dcache_contains_ptd[way*m_dcache_sets+set] = false;
 
 #if DEBUG_DCACHE
@@ -4670,16 +4816,25 @@
 }
 #endif
-                }
-
+        }
+
+        assert (not r_dcache_cc_send_req.read() &&
+                "ERROR in DCACHE_CC_INVAL: the r_dcache_cc_send_req "
+                "must not be set");
+        
+        if ( not r_cc_receive_updt_fifo_be.rok() ) break;
+
+        if (r_dcache_cc_need_write.read())
+        {
+        
 #ifdef INSTRUMENTATION
 m_cpt_dcache_data_write++;
 #endif
-                r_dcache.write( way,
-                                set,
-                                word,
-                                r_cc_receive_updt_fifo_data.read(),
-                                r_cc_receive_updt_fifo_be.read() );
-
-                r_dcache_cc_word = word + 1;
+            r_dcache.write( way,
+                            set,
+                            word,
+                            r_cc_receive_updt_fifo_data.read(),
+                            r_cc_receive_updt_fifo_be.read() );
+
+            r_dcache_cc_word = word + 1;
 
 #if DEBUG_DCACHE
@@ -4694,109 +4849,26 @@
 }
 #endif
-            }
-
-            if ( r_cc_receive_updt_fifo_eop.read() )	// last word
-            {
-                // no need to write in the cache anymore
-                r_dcache_cc_need_write = false;
-
-                // wait to send a request to cc_send_fsm
-                if(not r_dcache_cc_send_req.read())
-                // cc_send is available
-                {
-                    //consume last fifo flit if eop and request to cc_send possible
-                    cc_receive_updt_fifo_get  = true;
-
-                    // coherence request completed
-                    r_cc_receive_dcache_req = false;
-
-                    // request multicast acknowledgement
-                    r_dcache_cc_send_req = true;
-                    r_dcache_cc_send_nline = r_cc_receive_dcache_nline.read();
-                    r_dcache_cc_send_updt_tab_idx = r_cc_receive_dcache_updt_tab_idx.read();
-                    r_dcache_cc_send_type = CC_TYPE_MULTI_ACK;
-
-                    r_dcache_fsm          = r_dcache_fsm_cc_save.read();
-                }
-            }
-            else
-            {
-                //consume fifo if not eop
-                cc_receive_updt_fifo_get  = true;
-            }
-        }
-        break;
-    }
-    /////////////////////////
-    case DCACHE_CC_BROADCAST:   // hit broadcast : switch state to ZOMBI state
-                                // and request a cleanup, after possible
-                                // invalidation of copies in TLBs
-    {
-        size_t	 way   = r_dcache_cc_way.read();
-        size_t	 set   = r_dcache_cc_set.read();
-        paddr_t  nline = r_cc_receive_dcache_nline.read();
-
-        if (r_dcache_cc_need_write.read())
-        {
-            if ( r_dcache_in_tlb[way*m_dcache_sets+set] ) 			// selective TLB inval
-            {
-                r_dcache_in_tlb[way*m_dcache_sets+set] = false;
-                r_dcache_tlb_inval_line  = nline;
-                r_dcache_tlb_inval_set   = 0;
-                r_dcache_fsm_scan_save   = r_dcache_fsm.read();
-                r_dcache_fsm             = DCACHE_INVAL_TLB_SCAN;
-                break;
-            }
-            else
-            {
-                if ( r_dcache_contains_ptd[way*m_dcache_sets+set] ) 	// TLB flush
-                {
-                    r_itlb.reset();
-                    r_dtlb.reset();
-                    r_dcache_contains_ptd[way*m_dcache_sets+set] = false;
-
-#if DEBUG_DCACHE
-if ( m_debug_activated )
-{
-    std::cout << "  <PROC " << name()
-              << " DCACHE_CC_BROADCAST> Flush DTLB & ITLB" << std::endl;
-}
-#endif
-                }
-
-#ifdef INSTRUMENTATION
-m_cpt_dcache_dir_write++;
-#endif
-                r_dcache.write_dir( way,
-                                    set,
-                                    CACHE_SLOT_STATE_ZOMBI );
-
-                r_dcache_cc_need_write = false;
-#if DEBUG_DCACHE
-if ( m_debug_activated )
-{
-    std::cout << "  <PROC " << name()
-              << " DCACHE_CC_BROADCAST > Slot goes to ZOMBI state "
-              << " SET = " << set
-              << " / WAY = " << way << std::endl;
-}
-#endif
-            }
-        }
-        // cleanup
-        // send a request to cc_send_fsm
-        if(not r_dcache_cc_send_req.read()) // cc_send is available
-        {
+        }
+
+        if ( r_cc_receive_updt_fifo_eop.read() )  // last word
+        {
+            // no need to write in the cache anymore
+            r_dcache_cc_need_write = false;
+
             // coherence request completed
             r_cc_receive_dcache_req = false;
-            // request cleanup
-            r_dcache_cc_send_req = true;
-            r_dcache_cc_send_nline = r_cc_receive_dcache_nline.read();
-            r_dcache_cc_send_way   = r_dcache_cc_way.read();
-            r_dcache_cc_send_type  = CC_TYPE_CLEANUP;
-
-            r_dcache_fsm          = r_dcache_fsm_cc_save.read();
-        }
-        //else wait for previous cc_send request to be sent
+
+            // request multicast acknowledgement
+            r_dcache_cc_send_req          = true;
+            r_dcache_cc_send_nline        = r_cc_receive_dcache_nline.read();
+            r_dcache_cc_send_updt_tab_idx = r_cc_receive_dcache_updt_tab_idx.read();
+            r_dcache_cc_send_type         = CC_TYPE_MULTI_ACK;
+
+            r_dcache_fsm                  = r_dcache_fsm_cc_save.read();
+        }
+
+        //consume fifo if not eop
+        cc_receive_updt_fifo_get  = true;
+
         break;
     }
@@ -5389,5 +5461,5 @@
         {
             // wait for the first flit to be consumed
-            if (p_dspin_out.read.read())
+            if (p_dspin_p2m.read.read())
                 r_cc_send_fsm = CC_SEND_CLEANUP_2;
 
@@ -5398,5 +5470,5 @@
         {
             // wait for the second flit to be consumed
-            if (p_dspin_out.read.read())
+            if (p_dspin_p2m.read.read())
             {
                 if (r_cc_send_last_client.read() == 0) // dcache active request
@@ -5414,5 +5486,5 @@
         {
             // wait for the flit to be consumed
-            if(p_dspin_out.read.read())
+            if(p_dspin_p2m.read.read())
             {
                 if(r_cc_send_last_client.read() == 0) // dcache active request
@@ -5428,7 +5500,7 @@
 
     ///////////////////////////////////////////////////////////////////////////////
-    //   C_RECEIVE  FSM
+    //  CC_RECEIVE  FSM
     // This FSM receive all coherence packets on a DSPIN40 port.
-    // There is 7 packet types:
+    // There is 5 packet types:
     // - CC_DATA_INVAL : DCACHE invalidate request
     // - CC_DATA_UPDT  : DCACHE update request (multi-words)
@@ -5436,6 +5508,4 @@
     // - CC_INST_UPDT  : ICACHE update request (multi-words)
     // - CC_BROADCAST  : Broadcast invalidate request (both DCACHE & ICACHE)
-    // - CC_DATA_CLACK : DCACHE cleanup acknowledge
-    // - CC_INST_CLACK : ICACHE cleanup acknowledge
     //////////////////////////////////////////////////////////////////////////////
     switch( r_cc_receive_fsm.read() )
@@ -5445,79 +5515,35 @@
         {
             // a coherence request has arrived
-            if (p_dspin_in.write.read())
+            if (p_dspin_m2p.write.read())
             {
                 // initialize dspin received data
-                uint64_t receive_data = p_dspin_in.data.read();
+                uint64_t receive_data = p_dspin_m2p.data.read();
                 // initialize coherence packet type
                 uint64_t receive_type = DspinDhccpParam::dspin_get(receive_data,
-                                            DspinDhccpParam::FROM_MC_TYPE);
-                // initialize data/ins flip_flop (0 data / 1 ins)
-                r_cc_receive_data_ins = (bool)(receive_type & 0x1);
+                                            DspinDhccpParam::M2P_TYPE);
                 // test for a broadcast
-                if (DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::FROM_MC_BC))
+                if (DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::M2P_BC))
                 {
                     r_cc_receive_fsm = CC_RECEIVE_BRDCAST_HEADER;
                 }
-                // test for a CLACK
-                else if ((receive_type == DspinDhccpParam::TYPE_CLEANUP_ACK_DATA) or
-                         (receive_type == DspinDhccpParam::TYPE_CLEANUP_ACK_INST))
+                // test for a multi updt
+                else if (receive_type == DspinDhccpParam::TYPE_MULTI_UPDT_DATA) 
                 {
-                    r_cc_receive_fsm = CC_RECEIVE_CLACK;
+                    r_cc_receive_fsm = CC_RECEIVE_DATA_UPDT_HEADER;
                 }
-                // test for a multi updt
-                else if ((receive_type == DspinDhccpParam::TYPE_MULTI_UPDT_DATA) or
-                         (receive_type == DspinDhccpParam::TYPE_MULTI_UPDT_INST))
+                else if (receive_type == DspinDhccpParam::TYPE_MULTI_UPDT_INST)
                 {
-                    r_cc_receive_fsm = CC_RECEIVE_UPDT_HEADER;
+                    r_cc_receive_fsm = CC_RECEIVE_INS_UPDT_HEADER;
                 }
                 // test for a multi inval
+                else if (receive_type == DspinDhccpParam::TYPE_MULTI_INVAL_DATA)
+                {
+                    r_cc_receive_fsm = CC_RECEIVE_DATA_INVAL_HEADER;
+                }
                 else
                 {
-                    r_cc_receive_fsm = CC_RECEIVE_INVAL_HEADER;
+                    r_cc_receive_fsm = CC_RECEIVE_INS_INVAL_HEADER;
                 }
             }
-            break;
-        }
-        //////////////////////
-        case CC_RECEIVE_CLACK:
-        {
-            // initialize dspin received data
-            uint64_t receive_data = p_dspin_in.data.read();
-
-            // for data CLACK, wait for dcache to take the request
-            if ((r_cc_receive_data_ins.read() == 0) and 
-                   not (r_cc_receive_dcache_req.read()))
-            {
-                // request dcache to handle the CLACK
-                r_cc_receive_dcache_req  = true;
-                r_cc_receive_dcache_set  = DspinDhccpParam::dspin_get(receive_data,
-                                           DspinDhccpParam::CLEANUP_ACK_SET) & 
-                                           ((1ULL<<(uint32_log2(m_dcache_sets)))-1);
-                r_cc_receive_dcache_way  = DspinDhccpParam::dspin_get(receive_data,
-                                           DspinDhccpParam::CLEANUP_ACK_WAY) & 
-                                           ((1ULL<<(uint32_log2(m_dcache_ways)))-1);
-                r_cc_receive_dcache_type = CC_TYPE_CLACK;
-                // get back to idle state
-                r_cc_receive_fsm = CC_RECEIVE_IDLE;
-                break;
-            }
-            // for ins CLACK, wait for icache to take the request
-            if ((r_cc_receive_data_ins.read() == 1) and 
-                   not (r_cc_receive_icache_req.read()))
-            {
-                // request icache to handle the CLACK
-                r_cc_receive_icache_req  = true;
-                r_cc_receive_icache_set  = DspinDhccpParam::dspin_get(receive_data,
-                                           DspinDhccpParam::CLEANUP_ACK_SET) & 
-                                           ((1ULL<<(uint32_log2(m_icache_sets)))-1);
-                r_cc_receive_icache_way  = DspinDhccpParam::dspin_get(receive_data,
-                                           DspinDhccpParam::CLEANUP_ACK_WAY) & 
-                                           ((1ULL<<(uint32_log2(m_icache_ways)))-1);
-                r_cc_receive_icache_type = CC_TYPE_CLACK;
-                // get back to idle state
-                r_cc_receive_fsm = CC_RECEIVE_IDLE;
-                break;
-            }
-            // keep waiting for the correct cache to accept the request
             break;
         }
@@ -5533,5 +5559,5 @@
         {
             // initialize dspin received data
-            uint64_t receive_data = p_dspin_in.data.read();
+            uint64_t receive_data = p_dspin_m2p.data.read();
             // wait for both dcache and icache to take the request
             // TODO maybe we need to wait for both only to leave the state, but
@@ -5540,16 +5566,16 @@
             if (not (r_cc_receive_icache_req.read()) and 
                 not (r_cc_receive_dcache_req.read()) and 
-                (p_dspin_in.write.read()))
+                (p_dspin_m2p.write.read()))
             {
                 // request dcache to handle the BROADCAST
-                r_cc_receive_dcache_req  = true;
+                r_cc_receive_dcache_req = true;
                 r_cc_receive_dcache_nline  = DspinDhccpParam::dspin_get(receive_data,
                                              DspinDhccpParam::BROADCAST_NLINE);
-                r_cc_receive_dcache_type = CC_TYPE_BRDCAST;
+                r_cc_receive_dcache_type = CC_TYPE_INVAL;
                 // request icache to handle the BROADCAST
-                r_cc_receive_icache_req  = true;
+                r_cc_receive_icache_req = true;
                 r_cc_receive_icache_nline  = DspinDhccpParam::dspin_get(receive_data,
                                              DspinDhccpParam::BROADCAST_NLINE);
-                r_cc_receive_icache_type = CC_TYPE_BRDCAST;
+                r_cc_receive_icache_type = CC_TYPE_INVAL;
                 // get back to idle state
                 r_cc_receive_fsm = CC_RECEIVE_IDLE;
@@ -5560,42 +5586,28 @@
         }
         /////////////////////////////
-        case CC_RECEIVE_INVAL_HEADER:
+        case CC_RECEIVE_DATA_INVAL_HEADER:
         {
             // sample updt tab index in the HEADER, then skip to second flit
-            uint64_t receive_data = p_dspin_in.data.read();
+            r_cc_receive_fsm = CC_RECEIVE_DATA_INVAL_NLINE;
+            break;
+        }
+        /////////////////////////////
+        case CC_RECEIVE_INS_INVAL_HEADER:
+        {
+            // sample updt tab index in the HEADER, then skip to second flit
+            r_cc_receive_fsm = CC_RECEIVE_INS_INVAL_NLINE;
+            break;
+        }
+        ////////////////////////////
+        case CC_RECEIVE_DATA_INVAL_NLINE:
+        {
+            // sample nline in the second flit
+            uint64_t receive_data = p_dspin_m2p.data.read();
             // for data INVAL, wait for dcache to take the request
-            if ((r_cc_receive_data_ins.read() == 0) and 
-                 not (r_cc_receive_dcache_req.read()))
-            {
-                r_cc_receive_dcache_updt_tab_idx = DspinDhccpParam::dspin_get(receive_data,
-                                                   DspinDhccpParam::MULTI_INVAL_UPDT_INDEX);
-                r_cc_receive_fsm = CC_RECEIVE_INVAL_NLINE;
-                break;
-            }
-            // for ins INVAL, wait for icache to take the request
-            if ((r_cc_receive_data_ins.read() == 1) and 
-                 not (r_cc_receive_icache_req.read()))
-            {
-                r_cc_receive_icache_updt_tab_idx = DspinDhccpParam::dspin_get(receive_data,
-                                                   DspinDhccpParam::MULTI_INVAL_UPDT_INDEX);
-                r_cc_receive_fsm = CC_RECEIVE_INVAL_NLINE;
-                break;
-            }
-            // keep waiting for the correct cache to accept the request
-            break;
-        }
-        ////////////////////////////
-        case CC_RECEIVE_INVAL_NLINE:
-        {
-            // sample nline in the second flit
-            uint64_t receive_data = p_dspin_in.data.read();
-            // for data INVAL, wait for dcache to take the request
-            if ( (r_cc_receive_data_ins.read() == 0) and 
-                 not (r_cc_receive_dcache_req.read()) and 
-                 (p_dspin_in.write.read()) )
+            if (p_dspin_m2p.write.read() and not r_cc_receive_dcache_req.read())
             {
                 // request dcache to handle the INVAL
-                r_cc_receive_dcache_req  = true;
-                r_cc_receive_dcache_nline  = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_INVAL_NLINE);
+                r_cc_receive_dcache_req = true;
+                r_cc_receive_dcache_nline = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_INVAL_NLINE);
                 r_cc_receive_dcache_type = CC_TYPE_INVAL;
                 // get back to idle state
@@ -5603,10 +5615,17 @@
                 break;
             }
+            break;
+        }
+        //////////////////////////////
+        case CC_RECEIVE_INS_INVAL_NLINE:
+        {
+            // sample nline in the second flit
+            uint64_t receive_data = p_dspin_m2p.data.read();
             // for ins INVAL, wait for icache to take the request
-            if ((r_cc_receive_data_ins.read() == 1) and not (r_cc_receive_icache_req.read()) and (p_dspin_in.write.read()))
+            if (p_dspin_m2p.write.read() and not r_cc_receive_icache_req.read())
             {
                 // request icache to handle the INVAL
-                r_cc_receive_icache_req  = true;
-                r_cc_receive_icache_nline  = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_INVAL_NLINE);
+                r_cc_receive_icache_req = true;
+                r_cc_receive_icache_nline = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_INVAL_NLINE);
                 r_cc_receive_icache_type = CC_TYPE_INVAL;
                 // get back to idle state
@@ -5614,26 +5633,32 @@
                 break;
             }
-            // we should never get there
-            assert ( false && "ERROR in CC_VCACHE : CC_RECEIVE_INVAL_NLINE\n");
+            break;
         }
         ////////////////////////////
-        case CC_RECEIVE_UPDT_HEADER:
+        case CC_RECEIVE_DATA_UPDT_HEADER:
         {
             // sample updt tab index in the HEADER, than skip to second flit
-            uint64_t receive_data = p_dspin_in.data.read();
+            uint64_t receive_data = p_dspin_m2p.data.read();
             // for data INVAL, wait for dcache to take the request and fifo to
             // be empty
-            if ((r_cc_receive_data_ins.read() == 0) and not r_cc_receive_dcache_req.read() and r_cc_receive_updt_fifo_be.empty())
+            if (not r_cc_receive_dcache_req.read())
             {
                 r_cc_receive_dcache_updt_tab_idx  = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_UPDT_INDEX);
-                r_cc_receive_fsm = CC_RECEIVE_UPDT_NLINE;
+                r_cc_receive_fsm = CC_RECEIVE_DATA_UPDT_NLINE;
                 break;
             }
+            break;
+        }
+        ////////////////////////////
+        case CC_RECEIVE_INS_UPDT_HEADER:
+        {
+            // sample updt tab index in the HEADER, than skip to second flit
+            uint64_t receive_data = p_dspin_m2p.data.read();
             // for ins INVAL, wait for icache to take the request and fifo to be
             // empty
-            if ((r_cc_receive_data_ins.read() == 1) and not r_cc_receive_icache_req.read() and r_cc_receive_updt_fifo_be.empty())
+            if (not r_cc_receive_icache_req.read())
             {
                 r_cc_receive_icache_updt_tab_idx  = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_UPDT_INDEX);
-                r_cc_receive_fsm = CC_RECEIVE_UPDT_NLINE;
+                r_cc_receive_fsm = CC_RECEIVE_INS_UPDT_NLINE;
                 break;
             }
@@ -5642,53 +5667,51 @@
         }
         ///////////////////////////
-        case CC_RECEIVE_UPDT_NLINE:
+        case CC_RECEIVE_DATA_UPDT_NLINE:
         {
             // sample nline and word index in the second flit
-            uint64_t receive_data = p_dspin_in.data.read();
+            uint64_t receive_data = p_dspin_m2p.data.read();
             // for data INVAL, wait for dcache to take the request and fifo to
             // be empty
-            if ( (r_cc_receive_data_ins.read() == 0) and 
-                 not (r_cc_receive_dcache_req.read()) and 
-                 r_cc_receive_updt_fifo_be.empty() and 
-                 (p_dspin_in.write.read()) )
-            {
+            if ( r_cc_receive_updt_fifo_be.empty() and 
+                 p_dspin_m2p.write.read() )
+            {
+                r_cc_receive_dcache_req = true;
                 r_cc_receive_dcache_nline  = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_NLINE);
                 r_cc_receive_word_idx  = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_WORD_INDEX);
                 r_cc_receive_dcache_type = CC_TYPE_UPDT;
                 // get back to idle state
-                r_cc_receive_fsm = CC_RECEIVE_UPDT_DATA;
+                r_cc_receive_fsm = CC_RECEIVE_DATA_UPDT_DATA;
                 break;
             }
+            break;
+        }
+        ////////////////////////////
+        case CC_RECEIVE_INS_UPDT_NLINE:
+        {
+            // sample nline and word index in the second flit
+            uint64_t receive_data = p_dspin_m2p.data.read();
             // for ins INVAL, wait for icache to take the request and fifo to be
             // empty
-            if ( (r_cc_receive_data_ins.read() == 1) and 
-                 not (r_cc_receive_icache_req.read()) and 
-                 r_cc_receive_updt_fifo_be.empty() and 
-                 (p_dspin_in.write.read()))
-            {
+            if ( r_cc_receive_updt_fifo_be.empty() and 
+                 p_dspin_m2p.write.read() )
+            {
+                r_cc_receive_icache_req = true;
                 r_cc_receive_icache_nline  = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_NLINE);
                 r_cc_receive_word_idx  = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_WORD_INDEX);
                 r_cc_receive_icache_type = CC_TYPE_UPDT;
                 // get back to idle state
-                r_cc_receive_fsm = CC_RECEIVE_UPDT_DATA;
+                r_cc_receive_fsm = CC_RECEIVE_INS_UPDT_DATA;
                 break;
             }
-            // we should never get there
-            assert ( false && "ERROR in CC_VCACHE : CC_RECEIVE_UPDT_NLINE \n");
             break;
         }
         //////////////////////////
-        case CC_RECEIVE_UPDT_DATA:
-        {
-            if ((r_cc_receive_data_ins.read() == 0) and not (r_cc_receive_dcache_req.read()) and (p_dspin_in.write.read()))
-                r_cc_receive_dcache_req = true;
-            if ((r_cc_receive_data_ins.read() == 1) and not (r_cc_receive_icache_req.read()) and (p_dspin_in.write.read()))
-                r_cc_receive_icache_req = true;
-
+        case CC_RECEIVE_DATA_UPDT_DATA:
+        {
             // wait for the fifo
-            if (r_cc_receive_updt_fifo_be.wok() and (p_dspin_in.write.read()))
-            {
-                uint64_t receive_data = p_dspin_in.data.read();
-                bool     receive_eop  = p_dspin_in.eop.read();
+            if (r_cc_receive_updt_fifo_be.wok() and (p_dspin_m2p.write.read()))
+            {
+                uint64_t receive_data = p_dspin_m2p.data.read();
+                bool     receive_eop  = p_dspin_m2p.eop.read();
                 cc_receive_updt_fifo_be   = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_BE);
                 cc_receive_updt_fifo_data = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_DATA);
@@ -5699,5 +5722,66 @@
             break;
         }
+        //////////////////////////
+        case CC_RECEIVE_INS_UPDT_DATA:
+        {
+            // wait for the fifo
+            if (r_cc_receive_updt_fifo_be.wok() and (p_dspin_m2p.write.read()))
+            {
+                uint64_t receive_data = p_dspin_m2p.data.read();
+                bool     receive_eop  = p_dspin_m2p.eop.read();
+                cc_receive_updt_fifo_be   = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_BE);
+                cc_receive_updt_fifo_data = DspinDhccpParam::dspin_get(receive_data,DspinDhccpParam::MULTI_UPDT_DATA);
+                cc_receive_updt_fifo_eop  = receive_eop;
+                cc_receive_updt_fifo_put  = true;
+                if ( receive_eop ) r_cc_receive_fsm = CC_RECEIVE_IDLE;
+            }
+            break;
+        }
+
     } // end switch CC_RECEIVE FSM
+
+    ///////////////// DSPIN CLACK interface ///////////////
+    
+    uint64_t clack_type = DspinDhccpParam::dspin_get(r_dspin_clack_flit.read(),
+                                                     DspinDhccpParam::CLACK_TYPE);
+
+    size_t clack_way  = DspinDhccpParam::dspin_get(r_dspin_clack_flit.read(),
+                                                   DspinDhccpParam::CLACK_WAY);
+
+    size_t clack_set  = DspinDhccpParam::dspin_get(r_dspin_clack_flit.read(),
+                                                   DspinDhccpParam::CLACK_SET);
+
+    bool dspin_clack_get      = false;
+    bool dcache_clack_request = (clack_type == DspinDhccpParam::TYPE_CLACK_DATA);
+    bool icache_clack_request = (clack_type == DspinDhccpParam::TYPE_CLACK_INST);
+
+    if (r_dspin_clack_req.read())
+    {
+        // CLACK DATA: Send request to DCACHE FSM
+        if (dcache_clack_request and not r_dcache_clack_req.read()){
+            r_dcache_clack_req = true;
+            r_dcache_clack_way = clack_way & ((1ULL<<(uint32_log2(m_dcache_ways)))-1);
+            r_dcache_clack_set = clack_set & ((1ULL<<(uint32_log2(m_dcache_sets)))-1);
+            dspin_clack_get    = true;
+        }
+
+        // CLACK INST: Send request to ICACHE FSM
+        else if (icache_clack_request and not r_icache_clack_req.read()){
+            r_icache_clack_req = true;
+            r_icache_clack_way = clack_way & ((1ULL<<(uint32_log2(m_dcache_ways)))-1);
+            r_icache_clack_set = clack_set & ((1ULL<<(uint32_log2(m_icache_sets)))-1);
+            dspin_clack_get    = true;
+        }
+    }
+    else
+    {
+        dspin_clack_get = true;
+    }
+
+    if (dspin_clack_get)
+    {
+        r_dspin_clack_req  = p_dspin_clack.write.read();
+        r_dspin_clack_flit = p_dspin_clack.data.read();
+    }
 
     ///////////////// Response FIFOs update  //////////////////////
@@ -5897,5 +5981,5 @@
         case CC_SEND_IDLE:
         {
-            p_dspin_out.write = false;
+            p_dspin_p2m.write = false;
             break;
         }
@@ -5906,5 +5990,5 @@
 //            DspinDhccpParam::dspin_set(dspin_send_data,
 //                                       0,
-//                                       DspinDhccpParam::FROM_L1_EOP);
+//                                       DspinDhccpParam::P2M_EOP);
             DspinDhccpParam::dspin_set(dspin_send_data,
                                        m_cc_global_id,
@@ -5912,5 +5996,5 @@
             DspinDhccpParam::dspin_set(dspin_send_data,
                                        0,
-                                       DspinDhccpParam::FROM_L1_BC);
+                                       DspinDhccpParam::P2M_BC);
 
             if(r_cc_send_last_client.read() == 0) // dcache active request
@@ -5934,5 +6018,5 @@
                 DspinDhccpParam::dspin_set(dspin_send_data,
                                            DspinDhccpParam::TYPE_CLEANUP_DATA,
-                                           DspinDhccpParam::FROM_L1_TYPE);
+                                           DspinDhccpParam::P2M_TYPE);
             }
             else                                // icache active request
@@ -5956,10 +6040,10 @@
                 DspinDhccpParam::dspin_set(dspin_send_data,
                                            DspinDhccpParam::TYPE_CLEANUP_INST,
-                                           DspinDhccpParam::FROM_L1_TYPE);
+                                           DspinDhccpParam::P2M_TYPE);
             }
             // send flit
-            p_dspin_out.data  = dspin_send_data;
-            p_dspin_out.write = true;
-            p_dspin_out.eop   = false;
+            p_dspin_p2m.data  = dspin_send_data;
+            p_dspin_p2m.write = true;
+            p_dspin_p2m.eop   = false;
             break;
         }
@@ -5970,5 +6054,5 @@
 //            DspinDhccpParam::dspin_set(dspin_send_data,
 //                                       1,
-//                                       DspinDhccpParam::FROM_L1_EOP);
+//                                       DspinDhccpParam::P2M_EOP);
 
             if(r_cc_send_last_client.read() == 0) // dcache active request
@@ -5985,7 +6069,7 @@
             }
             // send flit
-            p_dspin_out.data  = dspin_send_data;
-            p_dspin_out.write = true;
-            p_dspin_out.eop   = true;
+            p_dspin_p2m.data  = dspin_send_data;
+            p_dspin_p2m.write = true;
+            p_dspin_p2m.eop   = true;
             break;
         }
@@ -5996,11 +6080,11 @@
 //            DspinDhccpParam::dspin_set(dspin_send_data,
 //                                       1,
-//                                       DspinDhccpParam::FROM_L1_EOP);
+//                                       DspinDhccpParam::P2M_EOP);
             DspinDhccpParam::dspin_set(dspin_send_data,
                                        0,
-                                       DspinDhccpParam::FROM_L1_BC);
+                                       DspinDhccpParam::P2M_BC);
             DspinDhccpParam::dspin_set(dspin_send_data,
                                        DspinDhccpParam::TYPE_MULTI_ACK,
-                                       DspinDhccpParam::FROM_L1_TYPE);
+                                       DspinDhccpParam::P2M_TYPE);
 
             if(r_cc_send_last_client.read() == 0) // dcache active request
@@ -6034,7 +6118,7 @@
             }
             // send flit
-            p_dspin_out.data  = dspin_send_data;
-            p_dspin_out.write = true;
-            p_dspin_out.eop   = true;
+            p_dspin_p2m.data  = dspin_send_data;
+            p_dspin_p2m.write = true;
+            p_dspin_p2m.eop   = true;
 
             break;
@@ -6044,5 +6128,4 @@
     // Receive coherence packets
     // It depends on the CC_RECEIVE FSM 
-
     switch( r_cc_receive_fsm.read() )
     {
@@ -6050,15 +6133,5 @@
         case CC_RECEIVE_IDLE:
         {
-            p_dspin_in.read = false;
-            break;
-        }
-        //////////////////////
-        case CC_RECEIVE_CLACK:
-        {
-            if (((r_cc_receive_data_ins.read() == 0) and not (r_cc_receive_dcache_req.read())) or
-                ((r_cc_receive_data_ins.read() == 1) and not (r_cc_receive_icache_req.read())))
-                p_dspin_in.read = true;
-            else
-                p_dspin_in.read = false;
+            p_dspin_m2p.read = false;
             break;
         }
@@ -6066,5 +6139,5 @@
         case CC_RECEIVE_BRDCAST_HEADER:
         {
-            p_dspin_in.read = true;
+            p_dspin_m2p.read = true;
             break;
         }
@@ -6076,66 +6149,95 @@
             // flip_flop to check that ?
             if (not (r_cc_receive_icache_req.read()) and not (r_cc_receive_dcache_req.read()))
-                p_dspin_in.read = true;
+                p_dspin_m2p.read = true;
             else
-                p_dspin_in.read = false;
+                p_dspin_m2p.read = false;
             break;
         }
         /////////////////////////////
-        case CC_RECEIVE_INVAL_HEADER:
-        {
-            if (((r_cc_receive_data_ins.read() == 0) and not (r_cc_receive_dcache_req.read())) or
-                ((r_cc_receive_data_ins.read() == 1) and not (r_cc_receive_icache_req.read())))
-                p_dspin_in.read = true;
+        case CC_RECEIVE_DATA_INVAL_HEADER:
+        case CC_RECEIVE_INS_INVAL_HEADER:
+        {
+            p_dspin_m2p.read = true;
+            break;
+        }
+        ////////////////////////////
+        case CC_RECEIVE_DATA_INVAL_NLINE:
+        {
+            p_dspin_m2p.read = not r_cc_receive_dcache_req.read();
+            break;
+        }
+        case CC_RECEIVE_INS_INVAL_NLINE:
+        {
+            p_dspin_m2p.read = not r_cc_receive_icache_req.read();
+            break;
+        }
+        ///////////////////////////
+        case CC_RECEIVE_DATA_UPDT_HEADER:
+        {
+            if (not r_cc_receive_dcache_req.read())
+                p_dspin_m2p.read = true;
             else
-                p_dspin_in.read = false;
+                p_dspin_m2p.read = false;
             break;
         }
         ////////////////////////////
-        case CC_RECEIVE_INVAL_NLINE:
-        {
-            p_dspin_in.read = true;
-            break;
-        }
-        ////////////////////////////
-        case CC_RECEIVE_UPDT_HEADER:
-        {
-            if (((r_cc_receive_data_ins.read() == 0) and
-                not r_cc_receive_dcache_req.read() and
-                r_cc_receive_updt_fifo_be.empty())
-                or
-                (((r_cc_receive_data_ins.read() == 1) and
-                not r_cc_receive_icache_req.read()) and
-                r_cc_receive_updt_fifo_be.empty()))
-                p_dspin_in.read = true;
+        case CC_RECEIVE_INS_UPDT_HEADER:
+        {
+            if ( not r_cc_receive_icache_req.read()) 
+                p_dspin_m2p.read = true;
             else
-                p_dspin_in.read = false;
+                p_dspin_m2p.read = false;
             break;
         }
         ///////////////////////////
-        case CC_RECEIVE_UPDT_NLINE:
-        {
-            if (((r_cc_receive_data_ins.read() == 0) and
-                not (r_cc_receive_dcache_req.read()) and
-                r_cc_receive_updt_fifo_be.empty())
-                or
-                ((r_cc_receive_data_ins.read() == 1) and
-                not (r_cc_receive_icache_req.read()) and
-                r_cc_receive_updt_fifo_be.empty()))
-                p_dspin_in.read = true;
+        case CC_RECEIVE_DATA_UPDT_NLINE:
+        case CC_RECEIVE_INS_UPDT_NLINE:
+        {
+            if(r_cc_receive_updt_fifo_be.empty())
+                p_dspin_m2p.read = true;
             else
-                p_dspin_in.read = false;
-            break;
-        }
-        //////////////////////////
-        case CC_RECEIVE_UPDT_DATA:
+                p_dspin_m2p.read = false;
+            break;
+        }
+        ///////////////////////////
+        case CC_RECEIVE_DATA_UPDT_DATA:
+        case CC_RECEIVE_INS_UPDT_DATA:
         {
             if (r_cc_receive_updt_fifo_be.wok())
-                p_dspin_in.read = true;
+                p_dspin_m2p.read = true;
             else
-                p_dspin_in.read = false;
+                p_dspin_m2p.read = false;
             break;
         }
     } // end switch CC_RECEIVE FSM
 
+
+    int clack_type = DspinDhccpParam::dspin_get(r_dspin_clack_flit.read(),
+                                                DspinDhccpParam::CLACK_TYPE);
+
+    bool dspin_clack_get      = false;
+    bool dcache_clack_request = (clack_type == DspinDhccpParam::TYPE_CLACK_DATA);
+    bool icache_clack_request = (clack_type == DspinDhccpParam::TYPE_CLACK_INST);
+
+    if (r_dspin_clack_req.read())
+    {
+        // CLACK DATA: wait if pending request to DCACHE FSM
+        if (dcache_clack_request and not r_dcache_clack_req.read())
+        {
+            dspin_clack_get = true;
+        }
+
+        // CLACK INST: wait if pending request to ICACHE FSM
+        else if (icache_clack_request and not r_icache_clack_req.read())
+        {
+            dspin_clack_get = true;
+        }
+    }
+    else
+    {
+        dspin_clack_get = true;
+    }
+
+    p_dspin_clack.read = dspin_clack_get; 
 } // end genMoore
 
Index: /trunk/modules/vci_mem_cache/caba/metadata/vci_mem_cache.sd
===================================================================
--- /trunk/modules/vci_mem_cache/caba/metadata/vci_mem_cache.sd	(revision 467)
+++ /trunk/modules/vci_mem_cache/caba/metadata/vci_mem_cache.sd	(revision 468)
@@ -49,9 +49,13 @@
             Port('caba:vci_initiator', 'p_vci_ixr'),
             Port('caba:dspin_input',
-                'p_dspin_in',
+                'p_dspin_p2m',
                 dspin_data_size = parameter.Reference('dspin_in_width')
             ),
             Port('caba:dspin_output',
-                'p_dspin_out',
+                'p_dspin_m2p',
+                dspin_data_size = parameter.Reference('dspin_out_width')
+            ),
+            Port('caba:dspin_output',
+                'p_dspin_clack',
                 dspin_data_size = parameter.Reference('dspin_out_width')
             ),
Index: /trunk/modules/vci_mem_cache/caba/source/include/vci_mem_cache.h
===================================================================
--- /trunk/modules/vci_mem_cache/caba/source/include/vci_mem_cache.h	(revision 467)
+++ /trunk/modules/vci_mem_cache/caba/source/include/vci_mem_cache.h	(revision 468)
@@ -54,4 +54,5 @@
 #define TRT_ENTRIES      4      // Number of entries in TRT
 #define UPT_ENTRIES      4      // Number of entries in UPT
+#define IVT_ENTRIES      4      // Number of entries in IVT
 #define HEAP_ENTRIES     1024   // Number of entries in HEAP
 
@@ -122,10 +123,8 @@
         CC_SEND_WRITE_IDLE,
         CC_SEND_CAS_IDLE,
-        CC_SEND_CLEANUP_IDLE,
         CC_SEND_CONFIG_INVAL_HEADER,
         CC_SEND_CONFIG_INVAL_NLINE,
         CC_SEND_CONFIG_BRDCAST_HEADER,
         CC_SEND_CONFIG_BRDCAST_NLINE,
-        CC_SEND_CLEANUP_ACK,
         CC_SEND_XRAM_RSP_BRDCAST_HEADER,
         CC_SEND_XRAM_RSP_BRDCAST_NLINE,
@@ -163,5 +162,5 @@
         CONFIG_DIR_REQ,
         CONFIG_DIR_ACCESS,
-        CONFIG_DIR_UPT_LOCK,
+        CONFIG_DIR_IVT_LOCK,
         CONFIG_BC_SEND,
         CONFIG_BC_WAIT,
@@ -211,5 +210,5 @@
         WRITE_MISS_XRAM_REQ,
         WRITE_BC_TRT_LOCK,
-        WRITE_BC_UPT_LOCK,
+        WRITE_BC_IVT_LOCK,
         WRITE_BC_DIR_INVAL,
         WRITE_BC_CC_SEND,
@@ -274,5 +273,5 @@
         CAS_UPT_NEXT,
         CAS_BC_TRT_LOCK,
-        CAS_BC_UPT_LOCK,
+        CAS_BC_IVT_LOCK,
         CAS_BC_DIR_INVAL,
         CAS_BC_CC_SEND,
@@ -299,7 +298,7 @@
         CLEANUP_HEAP_CLEAN,
         CLEANUP_HEAP_FREE,
-        CLEANUP_UPT_LOCK,
-        CLEANUP_UPT_DECREMENT,
-        CLEANUP_UPT_CLEAR,
+        CLEANUP_IVT_LOCK,
+        CLEANUP_IVT_DECREMENT,
+        CLEANUP_IVT_CLEAR,
         CLEANUP_WRITE_RSP,
         CLEANUP_CONFIG_ACK,
@@ -332,10 +331,17 @@
       enum alloc_upt_fsm_state_e
       {
-        ALLOC_UPT_CONFIG,
         ALLOC_UPT_WRITE,
-        ALLOC_UPT_XRAM_RSP,
-        ALLOC_UPT_MULTI_ACK,
-        ALLOC_UPT_CLEANUP,
-        ALLOC_UPT_CAS
+        ALLOC_UPT_CAS,
+        ALLOC_UPT_MULTI_ACK
+      };
+
+      /* States of the ALLOC_IVT fsm */
+      enum alloc_ivt_fsm_state_e
+      {
+        ALLOC_IVT_WRITE,
+        ALLOC_IVT_XRAM_RSP,
+        ALLOC_IVT_CLEANUP,
+        ALLOC_IVT_CAS,
+        ALLOC_IVT_CONFIG
       };
 
@@ -451,6 +457,7 @@
       soclib::caba::VciTarget<vci_param_int>      p_vci_tgt;
       soclib::caba::VciInitiator<vci_param_ext>   p_vci_ixr;
-      soclib::caba::DspinInput<dspin_in_width>    p_dspin_in;
-      soclib::caba::DspinOutput<dspin_out_width>  p_dspin_out;
+      soclib::caba::DspinInput<dspin_in_width>    p_dspin_p2m;
+      soclib::caba::DspinOutput<dspin_out_width>  p_dspin_m2p;
+      soclib::caba::DspinOutput<dspin_out_width>  p_dspin_clack;
 
       VciMemCache(
@@ -468,4 +475,5 @@
           const size_t                       trt_lines=TRT_ENTRIES, 
           const size_t                       upt_lines=UPT_ENTRIES,     
+          const size_t                       ivt_lines=IVT_ENTRIES,     
           const size_t                       debug_start_cycle=0,
           const bool                         debug_ok=false );
@@ -502,5 +510,6 @@
       TransactionTab                     m_trt;              // xram transaction table
       uint32_t                           m_upt_lines;
-      UpdateTab                          m_upt;              // pending update & invalidate
+      UpdateTab                          m_upt;              // pending update
+      UpdateTab                          m_ivt;              // pending invalidate
       CacheDirectory                     m_cache_directory;  // data cache directory
       CacheData                          m_cache_data;       // data array[set][way][word]
@@ -591,5 +600,5 @@
       sc_signal<size_t>   r_config_heap_next;      // current pointer to scan HEAP
 
-      sc_signal<size_t>   r_config_upt_index;  // UPT index
+      sc_signal<size_t>   r_config_ivt_index;      // IVT index
 
       // Buffer between CONFIG fsm and TGT_RSP fsm (send a done response to L1 cache)
@@ -780,11 +789,4 @@
       sc_signal<size_t>   r_cleanup_to_tgt_rsp_pktid; // transaction pktid
 
-      // Buffer between CLEANUP fsm and CC_SEND fsm (acknowledge a cleanup command from L1)
-      sc_signal<bool>     r_cleanup_to_cc_send_req;       // valid request
-      sc_signal<size_t>   r_cleanup_to_cc_send_srcid;     // L1 srcid
-      sc_signal<size_t>   r_cleanup_to_cc_send_set_index; // L1 set index
-      sc_signal<size_t>   r_cleanup_to_cc_send_way_index; // L1 way index
-      sc_signal<bool>     r_cleanup_to_cc_send_inst;      // Instruction Cleanup Ack
-
       ///////////////////////////////////////////////////////
       // Registers controlled by CAS fsm
@@ -872,5 +874,5 @@
       sc_signal<size_t>   r_xram_rsp_victim_ptr;        // victim line pointer to the heap
       sc_signal<data_t> * r_xram_rsp_victim_data;       // victim line data
-      sc_signal<size_t>   r_xram_rsp_upt_index;         // UPT entry index
+      sc_signal<size_t>   r_xram_rsp_ivt_index;         // IVT entry index
       sc_signal<size_t>   r_xram_rsp_next_ptr;          // Next pointer to the heap
 
@@ -953,4 +955,10 @@
 
       ////////////////////////////////////////////////////
+      // Registers controlled by ALLOC_IVT fsm
+      ////////////////////////////////////////////////////
+
+      sc_signal<int>      r_alloc_ivt_fsm;
+
+      ////////////////////////////////////////////////////
       // Registers controlled by ALLOC_HEAP fsm
       ////////////////////////////////////////////////////
Index: /trunk/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp
===================================================================
--- /trunk/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp	(revision 467)
+++ /trunk/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp	(revision 468)
@@ -99,10 +99,8 @@
   "CC_SEND_WRITE_IDLE",
   "CC_SEND_CAS_IDLE",
-  "CC_SEND_CLEANUP_IDLE",
   "CC_SEND_CONFIG_INVAL_HEADER",
   "CC_SEND_CONFIG_INVAL_NLINE",
   "CC_SEND_CONFIG_BRDCAST_HEADER",
   "CC_SEND_CONFIG_BRDCAST_NLINE",
-  "CC_SEND_CLEANUP_ACK",
   "CC_SEND_XRAM_RSP_BRDCAST_HEADER",
   "CC_SEND_XRAM_RSP_BRDCAST_NLINE",
@@ -136,5 +134,5 @@
   "CONFIG_DIR_REQ",
   "CONFIG_DIR_ACCESS",
-  "CONFIG_DIR_UPT_LOCK",
+  "CONFIG_DIR_IVT_LOCK",
   "CONFIG_BC_SEND",
   "CONFIG_BC_WAIT",
@@ -180,5 +178,5 @@
   "WRITE_MISS_XRAM_REQ",
   "WRITE_BC_TRT_LOCK",
-  "WRITE_BC_UPT_LOCK",
+  "WRITE_BC_IVT_LOCK",
   "WRITE_BC_DIR_INVAL",
   "WRITE_BC_CC_SEND",
@@ -235,5 +233,5 @@
   "CAS_UPT_NEXT",
   "CAS_BC_TRT_LOCK",
-  "CAS_BC_UPT_LOCK",
+  "CAS_BC_IVT_LOCK",
   "CAS_BC_DIR_INVAL",
   "CAS_BC_CC_SEND",
@@ -258,7 +256,7 @@
   "CLEANUP_HEAP_CLEAN",
   "CLEANUP_HEAP_FREE",
-  "CLEANUP_UPT_LOCK",
-  "CLEANUP_UPT_DECREMENT",
-  "CLEANUP_UPT_CLEAR",
+  "CLEANUP_IVT_LOCK",
+  "CLEANUP_IVT_DECREMENT",
+  "CLEANUP_IVT_CLEAR",
   "CLEANUP_WRITE_RSP",
   "CLEANUP_CONFIG_ACK",
@@ -268,4 +266,5 @@
 {
   "ALLOC_DIR_RESET",
+  "ALLOC_DIR_CONFIG",
   "ALLOC_DIR_READ",
   "ALLOC_DIR_WRITE",
@@ -285,8 +284,14 @@
 {
   "ALLOC_UPT_WRITE",
-  "ALLOC_UPT_XRAM_RSP",
-  "ALLOC_UPT_MULTI_ACK",
-  "ALLOC_UPT_CLEANUP",
-  "ALLOC_UPT_CAS"
+  "ALLOC_UPT_CAS",
+  "ALLOC_UPT_MULTI_ACK"
+};
+const char *alloc_ivt_fsm_str[] =
+{
+  "ALLOC_IVT_WRITE",
+  "ALLOC_IVT_XRAM_RSP",
+  "ALLOC_IVT_CLEANUP",
+  "ALLOC_IVT_CAS",
+  "ALLOC_IVT_CONFIG"
 };
 const char *alloc_heap_fsm_str[] =
@@ -328,4 +333,5 @@
   const size_t        trt_lines,         // number of TRT entries
   const size_t        upt_lines,         // number of UPT entries
+  const size_t        ivt_lines,         // number of IVT entries
   const size_t        debug_start_cycle,
   const bool          debug_ok)
@@ -337,6 +343,7 @@
     p_vci_tgt( "p_vci_tgt" ),
     p_vci_ixr( "p_vci_ixr" ),
-    p_dspin_in( "p_dspin_in" ),
-    p_dspin_out( "p_dspin_out" ),
+    p_dspin_p2m( "p_dspin_p2m" ),
+    p_dspin_m2p( "p_dspin_m2p" ),
+    p_dspin_clack( "p_dspin_clack" ),
 
     m_seglist( mtp.getSegmentList(tgtid_d) ),
@@ -355,4 +362,5 @@
     m_upt_lines(upt_lines),
     m_upt(upt_lines),
+    m_ivt(ivt_lines),
     m_cache_directory(nways, nsets, nwords, vci_param_int::N),
     m_cache_data(nways, nsets, nwords),
@@ -446,4 +454,5 @@
     r_alloc_trt_fsm("r_alloc_trt_fsm"),
     r_alloc_upt_fsm("r_alloc_upt_fsm"),
+    r_alloc_ivt_fsm("r_alloc_ivt_fsm"),
     r_alloc_heap_fsm("r_alloc_heap_fsm"),
     r_alloc_heap_reset_cpt("r_alloc_heap_reset_cpt")
@@ -623,8 +632,9 @@
             << " | " << ixr_cmd_fsm_str[r_ixr_cmd_fsm.read()]
             << " | " << ixr_rsp_fsm_str[r_ixr_rsp_fsm.read()]
-            << " | " << xram_rsp_fsm_str[r_xram_rsp_fsm] << std::endl;
+            << " | " << xram_rsp_fsm_str[r_xram_rsp_fsm.read()] << std::endl;
   std::cout << "  "  << alloc_dir_fsm_str[r_alloc_dir_fsm.read()]
             << " | " << alloc_trt_fsm_str[r_alloc_trt_fsm.read()]
             << " | " << alloc_upt_fsm_str[r_alloc_upt_fsm.read()]
+            << " | " << alloc_ivt_fsm_str[r_alloc_ivt_fsm.read()]
             << " | " << alloc_heap_fsm_str[r_alloc_heap_fsm.read()] << std::endl;
 }
@@ -702,4 +712,5 @@
     r_alloc_trt_fsm  = ALLOC_TRT_READ;
     r_alloc_upt_fsm  = ALLOC_UPT_WRITE;
+    r_alloc_ivt_fsm  = ALLOC_IVT_XRAM_RSP;
     r_ixr_rsp_fsm    = IXR_RSP_IDLE;
     r_xram_rsp_fsm   = XRAM_RSP_IDLE;
@@ -714,4 +725,5 @@
     m_trt.init();
     m_upt.init();
+    m_ivt.init();
     m_llsc_table.init();
 
@@ -1534,5 +1546,5 @@
               r_config_dir_next_ptr   = entry.ptr;
 
-              r_config_fsm    = CONFIG_DIR_UPT_LOCK;
+              r_config_fsm    = CONFIG_DIR_IVT_LOCK;
           }
           else if ( entry.valid and                       // hit & sync command
@@ -1563,11 +1575,11 @@
       }
       /////////////////////////
-      case CONFIG_DIR_UPT_LOCK:  // enter this state in case of INVAL command
-                                 // Try to get both DIR & UPT locks, and return
-                                 // to LOOP state if UPT full.
-                                 // Register inval in UPT, and invalidate the
-                                 // directory if UPT not full. 
-      {
-          if ( r_alloc_upt_fsm.read() == ALLOC_UPT_CONFIG )
+      case CONFIG_DIR_IVT_LOCK:  // enter this state in case of INVAL command
+                                 // Try to get both DIR & IVT locks, and return
+                                 // to LOOP state if IVT full.
+                                 // Register inval in IVT, and invalidate the
+                                 // directory if IVT not full. 
+      {
+          if ( r_alloc_ivt_fsm.read() == ALLOC_IVT_CONFIG )
           {
               size_t set        = m_y[(addr_t)(r_config_address.read())];
@@ -1583,9 +1595,9 @@
 #if DEBUG_MEMC_CONFIG
 if(m_debug)
-std::cout << "  <MEMC " << name() << " CONFIG_DIR_UPT_LOCK>"
+std::cout << "  <MEMC " << name() << " CONFIG_DIR_IVT_LOCK>"
           << " No copies in L1 : inval DIR entry"  << std::endl;
 #endif
               }
-              else    // try to register inval in UPT
+              else    // try to register inval in IVT
               {
                   bool        wok       = false;
@@ -1598,5 +1610,5 @@
                   size_t      nb_copies = r_config_dir_count.read();
 
-                  wok = m_upt.set(false,       // it's an inval transaction
+                  wok = m_ivt.set(false,       // it's an inval transaction
                                   broadcast,   
                                   false,       // no response required
@@ -1609,8 +1621,8 @@
                                   index);
 
-                  if ( wok )  // UPT success => inval DIR slot
+                  if ( wok )  // IVT success => inval DIR slot
                   {
                       m_cache_directory.inval( way, set );
-                      r_config_upt_index = index;
+                      r_config_ivt_index = index;
                       if ( broadcast )  r_config_fsm = CONFIG_BC_SEND;
                       else              r_config_fsm = CONFIG_INV_SEND;
@@ -1618,11 +1630,11 @@
 #if DEBUG_MEMC_CONFIG
 if(m_debug)
-std::cout << "  <MEMC " << name() << " CONFIG_DIR_UPT_LOCK>"
-          << " Inval DIR entry and register inval in UPT"
+std::cout << "  <MEMC " << name() << " CONFIG_DIR_IVT_LOCK>"
+          << " Inval DIR entry and register inval in IVT"
           << " : index = " << std::dec << index
           << " / broadcast = " << broadcast << std::endl;
 #endif
                   }
-                  else       // UPT full => release both DIR and UPT locks
+                  else       // IVT full => release both DIR and IVT locks
                   {
                       r_config_fsm = CONFIG_LOOP;
@@ -1630,6 +1642,6 @@
 #if DEBUG_MEMC_CONFIG
 if(m_debug)
-std::cout << "  <MEMC " << name() << " CONFIG_DIR_UPT_LOCK>"
-          << " UPT full : release DIR & UPT locks and retry" << std::endl;
+std::cout << "  <MEMC " << name() << " CONFIG_DIR_IVT_LOCK>"
+          << " IVT full : release DIR & IVT locks and retry" << std::endl;
 #endif
                   }
@@ -1646,5 +1658,5 @@
               r_config_to_cc_send_multi_req   = false;
               r_config_to_cc_send_brdcast_req = true;
-              r_config_to_cc_send_trdid       = r_config_upt_index.read();
+              r_config_to_cc_send_trdid       = r_config_ivt_index.read();
               r_config_to_cc_send_nline       = m_nline[(addr_t)(r_config_address.read())];
               r_cleanup_to_config_ack         = false;
@@ -1686,5 +1698,5 @@
               r_config_to_cc_send_multi_req   = true;
               r_config_to_cc_send_brdcast_req = false;
-              r_config_to_cc_send_trdid       = r_config_upt_index.read();
+              r_config_to_cc_send_trdid       = r_config_ivt_index.read();
               r_config_to_cc_send_nline       = m_nline[(addr_t)(r_config_address.read())];
               r_multi_ack_to_config_ack       = false;
@@ -1848,18 +1860,18 @@
   switch(r_read_fsm.read())
   {
-      ///////////////
-      case READ_IDLE:  // waiting a read request
-      {
+    ///////////////
+    case READ_IDLE:  // waiting a read request
+    {
       if(m_cmd_read_addr_fifo.rok())
       {
 
 #if DEBUG_MEMC_READ
-if(m_debug)
-std::cout << "  <MEMC " << name() << " READ_IDLE> Read request"
-          << " : address = " << std::hex << m_cmd_read_addr_fifo.read()
-          << " / srcid = " << m_cmd_read_srcid_fifo.read()
-          << " / trdid = " << m_cmd_read_trdid_fifo.read()
-          << " / pktid = " << m_cmd_read_pktid_fifo.read()
-          << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
+        if(m_debug)
+          std::cout << "  <MEMC " << name() << " READ_IDLE> Read request"
+            << " : address = " << std::hex << m_cmd_read_addr_fifo.read()
+            << " / srcid = " << m_cmd_read_srcid_fifo.read()
+            << " / trdid = " << m_cmd_read_trdid_fifo.read()
+            << " / pktid = " << m_cmd_read_pktid_fifo.read()
+            << " / nwords = " << std::dec << m_cmd_read_length_fifo.read() << std::endl;
 #endif
         r_read_fsm = READ_DIR_REQ;
@@ -1961,80 +1973,80 @@
 
     {
-        if(r_alloc_dir_fsm.read() == ALLOC_DIR_READ)
-        {
-            // check if this is an instruction read, this means pktid is either
-            // TYPE_READ_INS_UNC   0bX010 with TSAR encoding
-            // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
-            bool inst_read    = ((m_cmd_read_pktid_fifo.read() & 0x2) != 0);
-            // check if this is a cached read, this means pktid is either
-            // TYPE_READ_DATA_MISS 0bX001 with TSAR encoding
-            // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
-            bool cached_read  = (m_cmd_read_pktid_fifo.read() & 0x1);
-            bool is_cnt       = r_read_is_cnt.read();
-
-            // read data in the cache
-            size_t set        = m_y[(addr_t)(m_cmd_read_addr_fifo.read())];
-            size_t way        = r_read_way.read();
-
-            m_cache_data.read_line(way, set, r_read_data);
-
-            if(m_monitor_ok) check_monitor( m_cmd_read_addr_fifo.read(), r_read_data[0], true);
-
-            // update the cache directory
-            DirectoryEntry entry;
-            entry.valid   = true;
-            entry.is_cnt  = is_cnt;
-            entry.dirty   = r_read_dirty.read();
-            entry.tag     = r_read_tag.read();
-            entry.lock    = r_read_lock.read();
-            entry.ptr     = r_read_ptr.read();
-
-            if(cached_read)   // Cached read => we must update the copies
-            {
-                if(!is_cnt)  // Not counter mode
-                {
-                    entry.owner.srcid    = m_cmd_read_srcid_fifo.read();
+      if(r_alloc_dir_fsm.read() == ALLOC_DIR_READ)
+      {
+        // check if this is an instruction read, this means pktid is either
+        // TYPE_READ_INS_UNC   0bX010 with TSAR encoding
+        // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
+        bool inst_read    = ((m_cmd_read_pktid_fifo.read() & 0x2) != 0);
+        // check if this is a cached read, this means pktid is either
+        // TYPE_READ_DATA_MISS 0bX001 with TSAR encoding
+        // TYPE_READ_INS_MISS  0bX011 with TSAR encoding
+        bool cached_read  = (m_cmd_read_pktid_fifo.read() & 0x1);
+        bool is_cnt       = r_read_is_cnt.read();
+
+        // read data in the cache
+        size_t set        = m_y[(addr_t)(m_cmd_read_addr_fifo.read())];
+        size_t way        = r_read_way.read();
+
+        m_cache_data.read_line(way, set, r_read_data);
+
+        if(m_monitor_ok) check_monitor( m_cmd_read_addr_fifo.read(), r_read_data[0], true);
+
+        // update the cache directory
+        DirectoryEntry entry;
+        entry.valid   = true;
+        entry.is_cnt  = is_cnt;
+        entry.dirty   = r_read_dirty.read();
+        entry.tag     = r_read_tag.read();
+        entry.lock    = r_read_lock.read();
+        entry.ptr     = r_read_ptr.read();
+
+        if(cached_read)   // Cached read => we must update the copies
+        {
+          if(!is_cnt)  // Not counter mode
+          {
+            entry.owner.srcid    = m_cmd_read_srcid_fifo.read();
 #if L1_MULTI_CACHE
-                    entry.owner.cache_id = m_cmd_read_pktid_fifo.read();
-#endif
-                    entry.owner.inst     = inst_read;
-                    entry.count          = r_read_count.read() + 1;
-                }
-                else  // Counter mode
-                {
-                    entry.owner.srcid    = 0;
+            entry.owner.cache_id = m_cmd_read_pktid_fifo.read();
+#endif
+            entry.owner.inst     = inst_read;
+            entry.count          = r_read_count.read() + 1;
+          }
+          else  // Counter mode
+          {
+            entry.owner.srcid    = 0;
 #if L1_MULTI_CACHE
-                    entry.owner.cache_id = 0;
-#endif
-                    entry.owner.inst     = false;
-                    entry.count          = r_read_count.read() + 1;
-                }
-            }
-            else            // Uncached read
-            {
-                entry.owner.srcid     = r_read_copy.read();
+            entry.owner.cache_id = 0;
+#endif
+            entry.owner.inst     = false;
+            entry.count          = r_read_count.read() + 1;
+          }
+        }
+        else            // Uncached read
+        {
+          entry.owner.srcid     = r_read_copy.read();
 #if L1_MULTI_CACHE
-                entry.owner.cache_id  = r_read_copy_cache.read();
-#endif
-                entry.owner.inst      = r_read_copy_inst.read();
-                entry.count           = r_read_count.read();
-            }
+          entry.owner.cache_id  = r_read_copy_cache.read();
+#endif
+          entry.owner.inst      = r_read_copy_inst.read();
+          entry.count           = r_read_count.read();
+        }
 
 #if DEBUG_MEMC_READ
-if(m_debug)
-std::cout << "  <MEMC " << name() << " READ_DIR_HIT> Update directory entry:"
-          << " addr = " << std::hex << m_cmd_read_addr_fifo.read()
-          << " / set = " << std::dec << set
-          << " / way = " << way
-          << " / owner_id = " << std::hex << entry.owner.srcid
-          << " / owner_ins = " << std::dec << entry.owner.inst
-          << " / count = " << entry.count
-          << " / is_cnt = " << entry.is_cnt << std::endl;
-#endif
-
-            m_cache_directory.write(set, way, entry);
-            r_read_fsm    = READ_RSP;
-        }
-        break;
+        if(m_debug)
+          std::cout << "  <MEMC " << name() << " READ_DIR_HIT> Update directory entry:"
+            << " addr = " << std::hex << m_cmd_read_addr_fifo.read()
+            << " / set = " << std::dec << set
+            << " / way = " << way
+            << " / owner_id = " << std::hex << entry.owner.srcid
+            << " / owner_ins = " << std::dec << entry.owner.inst
+            << " / count = " << entry.count
+            << " / is_cnt = " << entry.is_cnt << std::endl;
+#endif
+
+        m_cache_directory.write(set, way, entry);
+        r_read_fsm    = READ_RSP;
+      }
+      break;
     }
     ///////////////////
@@ -2750,7 +2762,7 @@
 
         wok = m_upt.set(true,  // it's an update transaction
-                        false,    // it's not a broadcast
-                        true,     // response required
-                        false,    // no acknowledge required
+                        false, // it's not a broadcast
+                        true,  // response required
+                        false, // no acknowledge required
                         srcid,    
                         trdid,
@@ -2904,5 +2916,5 @@
           entry.owner.inst)             // put the next srcid in the fifo
       {
-        dec_upt_counter                 = false;
+        dec_upt_counter                = false;
         write_to_cc_send_fifo_put      = true;
         write_to_cc_send_fifo_inst     = entry.owner.inst;
@@ -2957,5 +2969,5 @@
       {
         r_write_to_cc_send_multi_req = true;
-        if(r_write_to_dec.read() or dec_upt_counter)   r_write_fsm = WRITE_UPT_DEC;
+        if(r_write_to_dec.read() or dec_upt_counter)  r_write_fsm = WRITE_UPT_DEC;
         else                                          r_write_fsm = WRITE_IDLE;
       }
@@ -3200,5 +3212,5 @@
         {
           r_write_trt_index = wok_index;
-          r_write_fsm       = WRITE_BC_UPT_LOCK;
+          r_write_fsm       = WRITE_BC_IVT_LOCK;
         }
         else  // wait an empty entry in TRT
@@ -3217,7 +3229,7 @@
 
     //////////////////////
-    case WRITE_BC_UPT_LOCK:      // register BC transaction in UPT
-    {
-      if(r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE)
+    case WRITE_BC_IVT_LOCK:      // register BC transaction in IVT
+    {
+      if(r_alloc_ivt_fsm.read() == ALLOC_IVT_WRITE)
       {
         bool        wok       = false;
@@ -3229,8 +3241,8 @@
         size_t      nb_copies = r_write_count.read();
 
-        wok = m_upt.set(false,  // it's an inval transaction
-                        true,     // it's a broadcast
-                        true,     // response required
-                        false,    // no acknowledge required
+        wok = m_ivt.set(false,  // it's an inval transaction
+                        true,   // it's a broadcast
+                        true,   // response required
+                        false,  // no acknowledge required
                         srcid,
                         trdid,
@@ -3242,5 +3254,5 @@
 #if DEBUG_MEMC_WRITE
 if( m_debug and wok )
-std::cout << "  <MEMC " << name() << " WRITE_BC_UPT_LOCK> Register broadcast inval in UPT"
+std::cout << "  <MEMC " << name() << " WRITE_BC_IVT_LOCK> Register broadcast inval in IVT"
           << " / nb_copies = " << r_write_count.read() << std::endl;
 #endif
@@ -3248,5 +3260,5 @@
 
         if(wok) r_write_fsm = WRITE_BC_DIR_INVAL;
-        else       r_write_fsm = WRITE_WAIT;
+        else    r_write_fsm = WRITE_WAIT;
       }
       break;
@@ -3259,9 +3271,9 @@
       // and invalidate the line in directory
       if((r_alloc_trt_fsm.read() != ALLOC_TRT_WRITE) or
-          (r_alloc_upt_fsm.read() != ALLOC_UPT_WRITE) or
-          (r_alloc_dir_fsm.read() != ALLOC_DIR_WRITE))
+         (r_alloc_ivt_fsm.read() != ALLOC_IVT_WRITE) or
+         (r_alloc_dir_fsm.read() != ALLOC_DIR_WRITE))
       {
         std::cout << "VCI_MEM_CACHE ERROR " << name() << " WRITE_BC_DIR_INVAL state" << std::endl;
-        std::cout << "bad TRT, DIR, or UPT allocation" << std::endl;
+        std::cout << "bad TRT, DIR, or IVT allocation" << std::endl;
         exit(0);
       }
@@ -3791,10 +3803,10 @@
     }
     /////////////////////////
-    case XRAM_RSP_INVAL_LOCK: // Take the UPT lock to check a possible pending inval
-    {
-      if(r_alloc_upt_fsm == ALLOC_UPT_XRAM_RSP)
+    case XRAM_RSP_INVAL_LOCK: // Take the IVT lock to check a possible pending inval
+    {
+      if(r_alloc_ivt_fsm == ALLOC_IVT_XRAM_RSP)
       {
         size_t index = 0;
-        if(m_upt.search_inval(r_xram_rsp_trt_buf.nline, index))  // pending inval
+        if(m_ivt.search_inval(r_xram_rsp_trt_buf.nline, index))  // pending inval
         {
           r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT;
@@ -3803,5 +3815,5 @@
 if(m_debug)
 std::cout << "  <MEMC " << name() << " XRAM_RSP_INVAL_LOCK>"
-          << " Get acces to UPT, but line invalidation registered"
+          << " Get acces to IVT, but line invalidation registered"
           << " / nline = " << std::hex << r_xram_rsp_trt_buf.nline
           << " / index = " << std::dec << index << std::endl;
@@ -3809,5 +3821,5 @@
 
         }
-        else if(m_upt.is_full() and r_xram_rsp_victim_inval.read()) // UPT full
+        else if(m_ivt.is_full() and r_xram_rsp_victim_inval.read()) // IVT full
         {
           r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT;
@@ -3816,5 +3828,5 @@
 if(m_debug)
 std::cout << "  <MEMC " << name() << " XRAM_RSP_INVAL_LOCK>"
-          << " Get acces to UPT, but inval required and UPT full" << std::endl;
+          << " Get acces to IVT, but inval required and IVT full" << std::endl;
 #endif
         }
@@ -3826,5 +3838,5 @@
 if(m_debug)
 std::cout << "  <MEMC " << name() << " XRAM_RSP_INVAL_LOCK>"
-          << " Get acces to UPT" << std::endl;
+          << " Get acces to IVT" << std::endl;
 #endif
         }
@@ -3846,5 +3858,5 @@
     ///////////////////////
     case XRAM_RSP_DIR_UPDT:   // updates the cache (both data & directory)
-                              // and possibly set an inval request in UPT
+                              // and possibly set an inval request in IVT
     {
       // check if this is an instruction read, this means pktid is either
@@ -3904,5 +3916,5 @@
       m_cache_directory.write(set, way, entry);
 
-      // request an invalidattion request in UPT for victim line
+      // request an invalidattion request in IVT for victim line
       if(r_xram_rsp_victim_inval.read())
       {
@@ -3911,5 +3923,5 @@
         size_t count_copies = r_xram_rsp_victim_count.read();
 
-        bool   wok = m_upt.set(false,      // it's an inval transaction
+        bool   wok = m_ivt.set(false,      // it's an inval transaction
                                broadcast,  // set broadcast bit
                                false,      // no response required 
@@ -3922,10 +3934,10 @@
                                index);
 
-        r_xram_rsp_upt_index = index;
+        r_xram_rsp_ivt_index = index;
 
         if(!wok)
         {
           std::cout << "VCI_MEM_CACHE ERROR " << name() << " XRAM_RSP_DIR_UPDT"
-                    << " update_tab entry free but write unsuccessful" << std::endl;
+                    << " invalidate_tab entry free but write unsuccessful" << std::endl;
           exit(0);
         }
@@ -4036,5 +4048,5 @@
         r_xram_rsp_to_cc_send_brdcast_req  = r_xram_rsp_victim_is_cnt.read();
         r_xram_rsp_to_cc_send_nline        = r_xram_rsp_victim_nline.read();
-        r_xram_rsp_to_cc_send_trdid        = r_xram_rsp_upt_index;
+        r_xram_rsp_to_cc_send_trdid        = r_xram_rsp_ivt_index;
         xram_rsp_to_cc_send_fifo_srcid     = r_xram_rsp_victim_copy.read();
         xram_rsp_to_cc_send_fifo_inst      = r_xram_rsp_victim_copy_inst.read();
@@ -4252,5 +4264,5 @@
         DspinDhccpParam::dspin_get(
             flit,
-            DspinDhccpParam::FROM_L1_TYPE);
+            DspinDhccpParam::P2M_TYPE);
 
       r_cleanup_way_index =
@@ -4381,5 +4393,5 @@
       else                // miss : check UPT for a pending invalidation transaction
       {
-        r_cleanup_fsm = CLEANUP_UPT_LOCK;
+        r_cleanup_fsm = CLEANUP_IVT_LOCK;
       }
 
@@ -4839,13 +4851,13 @@
     }
     //////////////////////
-    case CLEANUP_UPT_LOCK:   // get the lock protecting the UPT to search a pending
+    case CLEANUP_IVT_LOCK:   // get the lock protecting the IVT to search a pending
                              // invalidate transaction matching the cleanup 
     {
-      if(r_alloc_upt_fsm.read() != ALLOC_UPT_CLEANUP) break;
+      if(r_alloc_ivt_fsm.read() != ALLOC_IVT_CLEANUP) break;
 
       size_t index = 0;
       bool   match_inval;
 
-      match_inval = m_upt.search_inval(r_cleanup_nline.read(), index);
+      match_inval = m_ivt.search_inval(r_cleanup_nline.read(), index);
 
       if ( not match_inval )     // no pending inval
@@ -4856,6 +4868,6 @@
 if(m_debug)
 std::cout << "  <MEMC " << name()
-          << " CLEANUP_UPT_LOCK> Unexpected cleanup"
-          << " with no corresponding UPT entry:"
+          << " CLEANUP_IVT_LOCK> Unexpected cleanup"
+          << " with no corresponding IVT entry:"
           << " address = " << std::hex
           << (r_cleanup_nline.read() *4*m_words)
@@ -4866,32 +4878,32 @@
 
       // pending inval
-      r_cleanup_write_srcid = m_upt.srcid(index);
-      r_cleanup_write_trdid = m_upt.trdid(index);
-      r_cleanup_write_pktid = m_upt.pktid(index);
-      r_cleanup_need_rsp    = m_upt.need_rsp(index);
-      r_cleanup_need_ack    = m_upt.need_ack(index);
+      r_cleanup_write_srcid = m_ivt.srcid(index);
+      r_cleanup_write_trdid = m_ivt.trdid(index);
+      r_cleanup_write_pktid = m_ivt.pktid(index);
+      r_cleanup_need_rsp    = m_ivt.need_rsp(index);
+      r_cleanup_need_ack    = m_ivt.need_ack(index);
       r_cleanup_index       = index;
 
-      r_cleanup_fsm         = CLEANUP_UPT_DECREMENT;
+      r_cleanup_fsm         = CLEANUP_IVT_DECREMENT;
 
 #if DEBUG_MEMC_CLEANUP
 if(m_debug)
 std::cout << "  <MEMC " << name()
-          << " CLEANUP_UPT_LOCK> Cleanup matching pending"
-          << " invalidate transaction on UPT:"
+          << " CLEANUP_IVT_LOCK> Cleanup matching pending"
+          << " invalidate transaction on IVT:"
           << " address = " << std::hex << r_cleanup_nline.read() * m_words * 4
-          << " / upt_entry = " << index << std::endl;
+          << " / ivt_entry = " << index << std::endl;
 #endif
       break;
     }
     ///////////////////////////
-    case CLEANUP_UPT_DECREMENT:   // decrement response counter in UPT matching entry
-    {
-      if(r_alloc_upt_fsm.read() != ALLOC_UPT_CLEANUP)
+    case CLEANUP_IVT_DECREMENT: // decrement response counter in IVT matching entry
+    {
+      if(r_alloc_ivt_fsm.read() != ALLOC_IVT_CLEANUP)
       {
         std::cout
             << "VCI_MEM_CACHE ERROR "         << name()
-            << " CLEANUP_UPT_DECREMENT state" << std::endl
-            << "Bad UPT allocation"
+            << " CLEANUP_IVT_DECREMENT state" << std::endl
+            << "Bad IVT allocation"
             << std::endl;
 
@@ -4900,9 +4912,9 @@
 
       size_t count = 0;
-      m_upt.decrement(r_cleanup_index.read(), count);
+      m_ivt.decrement(r_cleanup_index.read(), count);
 
       if(count == 0)   // multi inval transaction completed
       {
-        r_cleanup_fsm = CLEANUP_UPT_CLEAR;
+        r_cleanup_fsm = CLEANUP_IVT_CLEAR;
       }
       else             // multi inval transaction not completed
@@ -4913,7 +4925,7 @@
 #if DEBUG_MEMC_CLEANUP
 if(m_debug)
-std::cout << "  <MEMC " << name() << " CLEANUP_UPT_DECREMENT>"
-          << " Decrement response counter in UPT:"
-            << " UPT_index = " << r_cleanup_index.read()
+std::cout << "  <MEMC " << name() << " CLEANUP_IVT_DECREMENT>"
+          << " Decrement response counter in IVT:"
+            << " IVT_index = " << r_cleanup_index.read()
             << " / rsp_count = " << count << std::endl;
 #endif
@@ -4921,12 +4933,12 @@
     }
     ///////////////////////
-    case CLEANUP_UPT_CLEAR:    // Clear UPT entry 
-    {
-      if(r_alloc_upt_fsm.read() != ALLOC_UPT_CLEANUP)
+    case CLEANUP_IVT_CLEAR:    // Clear IVT entry 
+    {
+      if(r_alloc_ivt_fsm.read() != ALLOC_IVT_CLEANUP)
       {
         std::cout
             << "VCI_MEM_CACHE ERROR "     << name()
-            << " CLEANUP_UPT_CLEAR state" << std::endl
-            << "Bad UPT allocation"
+            << " CLEANUP_IVT_CLEAR state" << std::endl
+            << "Bad IVT allocation"
             << std::endl;
 
@@ -4934,5 +4946,5 @@
       }
 
-      m_upt.clear(r_cleanup_index.read());
+      m_ivt.clear(r_cleanup_index.read());
 
       if      ( r_cleanup_need_rsp.read() ) r_cleanup_fsm = CLEANUP_WRITE_RSP;
@@ -4943,6 +4955,6 @@
 if(m_debug)
 std::cout << "  <MEMC "      << name()
-          << " CLEANUP_UPT_CLEAR> Clear entry in UPT:"
-          << " UPT_index = " << r_cleanup_index.read() << std::endl;
+          << " CLEANUP_IVT_CLEAR> Clear entry in IVT:"
+          << " IVT_index = " << r_cleanup_index.read() << std::endl;
 #endif
       break;
@@ -4989,15 +5001,8 @@
     }
     ////////////////////////
-    case CLEANUP_SEND_CLACK:    // acknowledgement to a cleanup command
-                              // on the coherence network (request to the CC_SEND FSM).
-                              // wait if pending request to the CC_SEND FSM
-    {
-      if(r_cleanup_to_cc_send_req.read()) break;
-
-      r_cleanup_to_cc_send_req       = true;
-      r_cleanup_to_cc_send_set_index = r_cleanup_nline.read() & 0xFFFF;
-      r_cleanup_to_cc_send_way_index = r_cleanup_way_index.read();
-      r_cleanup_to_cc_send_srcid     = r_cleanup_srcid.read();
-      r_cleanup_to_cc_send_inst      = r_cleanup_inst.read();
+    case CLEANUP_SEND_CLACK:  // acknowledgement to a cleanup command
+                              // on the coherence CLACK network.
+    {
+      if(not p_dspin_clack.read) break;
 
       r_cleanup_fsm = CLEANUP_IDLE;
@@ -5007,5 +5012,8 @@
 std::cout << "  <MEMC " << name()
           << " CLEANUP_SEND_CLACK> Send the response to a cleanup request:"
-          << " srcid = " << std::dec << r_cleanup_srcid.read() << std::endl;
+          << " nline = "   << std::hex << r_cleanup_nline.read()
+          << " / way = "   << std::dec << r_cleanup_way.read()
+          << " / srcid = " << std::dec << r_cleanup_srcid.read() 
+          << std::endl;
 #endif
       break;
@@ -5242,5 +5250,5 @@
                 !r_cas_to_cc_send_brdcast_req.read())
         {
-          r_cas_fsm = CAS_UPT_LOCK;     // multi update required
+          r_cas_fsm = CAS_UPT_LOCK;       // multi update required
         }
         else
@@ -5507,5 +5515,5 @@
           {
             r_cas_trt_index = wok_index;
-            r_cas_fsm       = CAS_BC_UPT_LOCK;
+            r_cas_fsm       = CAS_BC_IVT_LOCK;
           }
           else
@@ -5522,8 +5530,8 @@
     }
     /////////////////////
-    case CAS_BC_UPT_LOCK:  // register a broadcast inval transaction in UPT
+    case CAS_BC_IVT_LOCK:  // register a broadcast inval transaction in IVT
                            // write data in cache in case of successful registration
     {
-      if(r_alloc_upt_fsm.read() == ALLOC_UPT_CAS)
+      if(r_alloc_ivt_fsm.read() == ALLOC_IVT_CAS)
       {
         bool        wok       = false;
@@ -5535,9 +5543,9 @@
         size_t      nb_copies = r_cas_count.read();
 
-        // register a broadcast inval transaction in UPT
-        wok = m_upt.set(false,  // it's an inval transaction
-                        true,    // it's a broadcast
-                        true,    // response required
-                        false,   // no acknowledge required
+        // register a broadcast inval transaction in IVT
+        wok = m_ivt.set(false,  // it's an inval transaction
+                        true,   // it's a broadcast
+                        true,   // response required
+                        false,  // no acknowledge required
                         srcid,
                         trdid,
@@ -5547,5 +5555,5 @@
                         index);
 
-        if(wok)     // UPT not full
+        if(wok)     // IVT not full
         {
           // cache update
@@ -5573,11 +5581,11 @@
 if(m_debug)
 std::cout << "  <MEMC " << name()
-          << " CAS_BC_UPT_LOCK> Register a broadcast inval transaction in UPT"
+          << " CAS_BC_IVT_LOCK> Register a broadcast inval transaction in IVT"
           << " / nline = " << std::hex << nline
           << " / count = " << std::dec << nb_copies
-          << " / upt_index = " << index << std::endl;
-#endif
-        }
-        else      //  releases the lock protecting UPT
+          << " / ivt_index = " << index << std::endl;
+#endif
+        }
+        else      //  releases the lock protecting IVT
         {
           r_cas_fsm = CAS_WAIT;
@@ -5590,6 +5598,6 @@
     {
       if((r_alloc_trt_fsm.read() == ALLOC_TRT_CAS) and
-          (r_alloc_upt_fsm.read() == ALLOC_UPT_CAS) and
-          (r_alloc_dir_fsm.read() == ALLOC_DIR_CAS))
+         (r_alloc_ivt_fsm.read() == ALLOC_IVT_CAS) and
+         (r_alloc_dir_fsm.read() == ALLOC_DIR_CAS))
       {
         // set TRT
@@ -5834,9 +5842,6 @@
   // network, used to update or invalidate cache lines in L1 caches.
   //
-  // This fsm is used also to acknowledge CLEANUP a command after request from
-  // the CLEANUP fsm.
-  //
-  // It implements a round-robin priority between the five possible client FSMs
-  //     XRAM_RSP > CAS > CLEANUP > WRITE > CONFIG 
+  // It implements a round-robin priority between the four possible client FSMs
+  //     XRAM_RSP > CAS > WRITE > CONFIG 
   //
   // Each FSM can request the next services:
@@ -5850,6 +5855,4 @@
   //   r_config_to_cc_send_brdcast_req : broadcast-inval
   //   
-  // - r_cleanup_to_cc_send_req : cleanup acknowledgement
-  //
   // An inval request is a double DSPIN flit command containing:
   // 1. the index of the line to be invalidated.
@@ -5894,10 +5897,4 @@
           break;
         }
-        // CLEANUP
-        if (r_cleanup_to_cc_send_req.read())
-        {
-          r_cc_send_fsm = CC_SEND_CLEANUP_ACK;
-          break;
-        }
         // WRITE
         if(m_write_to_cc_send_inst_fifo.rok() or
@@ -5973,10 +5970,4 @@
           break;
         }
-        // CLEANUP
-        if (r_cleanup_to_cc_send_req.read())
-        {
-          r_cc_send_fsm = CC_SEND_CLEANUP_ACK;
-          break;
-        }
         // WRITE
         if(m_write_to_cc_send_inst_fifo.rok() or
@@ -6012,10 +6003,4 @@
           break;
         }
-        // CLEANUP
-        if(r_cleanup_to_cc_send_req.read())
-        {
-          r_cc_send_fsm = CC_SEND_CLEANUP_ACK;
-          break;
-        }
         // WRITE
         if(m_write_to_cc_send_inst_fifo.rok() or
@@ -6065,9 +6050,4 @@
       case CC_SEND_CAS_IDLE:   // CLEANUP FSM has highest priority
       {
-        if(r_cleanup_to_cc_send_req.read())
-        {
-          r_cc_send_fsm = CC_SEND_CLEANUP_ACK;
-          break;
-        }
         if(m_write_to_cc_send_inst_fifo.rok() or
             r_write_to_cc_send_multi_req.read())
@@ -6124,70 +6104,4 @@
         break;
       }
-      //////////////////////////
-      case CC_SEND_CLEANUP_IDLE:   // WRITE FSM has highest priority
-      {
-        // WRITE
-        if(m_write_to_cc_send_inst_fifo.rok() or
-            r_write_to_cc_send_multi_req.read())
-        {
-          r_cc_send_fsm = CC_SEND_WRITE_UPDT_HEADER;
-          m_cpt_update++;
-          break;
-        }
-        if(r_write_to_cc_send_brdcast_req.read())
-        {
-          r_cc_send_fsm = CC_SEND_WRITE_BRDCAST_HEADER;
-          m_cpt_inval++;
-          break;
-        }
-        // CONFIG
-        if(r_config_to_cc_send_multi_req.read())
-        {
-          r_cc_send_fsm = CC_SEND_CONFIG_INVAL_HEADER;
-          m_cpt_inval++;
-          break;
-        }
-        if(r_config_to_cc_send_brdcast_req.read())
-        {
-          r_cc_send_fsm = CC_SEND_CONFIG_BRDCAST_HEADER;
-          m_cpt_inval++;
-          break;
-        }
-        // XRAM_RSP
-        if(m_xram_rsp_to_cc_send_inst_fifo.rok() or
-            r_xram_rsp_to_cc_send_multi_req.read())
-        {
-          r_cc_send_fsm = CC_SEND_XRAM_RSP_INVAL_HEADER;
-          m_cpt_inval++;
-          break;
-        }
-        if(r_xram_rsp_to_cc_send_brdcast_req.read())
-        {
-          r_cc_send_fsm = CC_SEND_XRAM_RSP_BRDCAST_HEADER;
-          m_cpt_inval++;
-          break;
-        }
-        // CAS
-        if(m_cas_to_cc_send_inst_fifo.rok() or
-            r_cas_to_cc_send_multi_req.read())
-        {
-          r_cc_send_fsm = CC_SEND_CAS_UPDT_HEADER;
-          m_cpt_update++;
-          break;
-        }
-        if(r_cas_to_cc_send_brdcast_req.read())
-        {
-          r_cc_send_fsm = CC_SEND_CAS_BRDCAST_HEADER;
-          m_cpt_inval++;
-          break;
-        }
-        // CLEANUP
-        if(r_cleanup_to_cc_send_req.read())
-        {
-          r_cc_send_fsm = CC_SEND_CLEANUP_ACK;
-          break;
-        }
-        break;
-      }
       /////////////////////////////////
       case CC_SEND_CONFIG_INVAL_HEADER:   // send first flit multi-inval (from CONFIG FSM)
@@ -6195,5 +6109,5 @@
         if(m_config_to_cc_send_inst_fifo.rok())
         {
-          if(not p_dspin_out.read) break;
+          if(not p_dspin_m2p.read) break;
           r_cc_send_fsm = CC_SEND_CONFIG_INVAL_NLINE;
           break;
@@ -6206,5 +6120,5 @@
       case CC_SEND_CONFIG_INVAL_NLINE:    // send second flit multi-inval (from CONFIG FSM)
       {
-        if(not p_dspin_out.read) break;
+        if(not p_dspin_m2p.read) break;
         m_cpt_inval_mult++;
         config_to_cc_send_fifo_get = true;
@@ -6222,5 +6136,5 @@
       case CC_SEND_CONFIG_BRDCAST_HEADER:   // send first flit BC-inval (from CONFIG FSM)
       {
-        if(not p_dspin_out.read) break;
+        if(not p_dspin_m2p.read) break;
         r_cc_send_fsm = CC_SEND_CONFIG_BRDCAST_NLINE;
         break;
@@ -6229,5 +6143,5 @@
       case CC_SEND_CONFIG_BRDCAST_NLINE:    // send second flit BC-inval (from CONFIG FSM)
       {
-        if(not p_dspin_out.read) break;
+        if(not p_dspin_m2p.read) break;
         m_cpt_inval_brdcast++;
         r_config_to_cc_send_brdcast_req = false;
@@ -6242,20 +6156,4 @@
         break;
       }
-      /////////////////////////
-      case CC_SEND_CLEANUP_ACK:   // send one flit for a cleanup acknowledgement 
-      {
-        if(not p_dspin_out.read) break;
-
-        r_cleanup_to_cc_send_req = false;
-        r_cc_send_fsm = CC_SEND_CLEANUP_IDLE;
-
-#if DEBUG_MEMC_CC_SEND
-if(m_debug)
-std::cout << "  <MEMC " << name()
-          << " CC_SEND_CLEANUP_ACK> Cleanup Ack for srcid "
-          << std::hex << r_cleanup_to_cc_send_srcid.read() << std::endl;
-#endif
-        break;
-      }
       ///////////////////////////////////
       case CC_SEND_XRAM_RSP_INVAL_HEADER:   // send first flit multi-inval (from XRAM_RSP FSM)
@@ -6263,5 +6161,5 @@
         if(m_xram_rsp_to_cc_send_inst_fifo.rok())
         {
-          if(not p_dspin_out.read) break;
+          if(not p_dspin_m2p.read) break;
           r_cc_send_fsm = CC_SEND_XRAM_RSP_INVAL_NLINE;
           break;
@@ -6274,5 +6172,5 @@
       case CC_SEND_XRAM_RSP_INVAL_NLINE:   // send second flit multi-inval (from XRAM_RSP FSM)
       {
-        if(not p_dspin_out.read) break;
+        if(not p_dspin_m2p.read) break;
         m_cpt_inval_mult++;
         xram_rsp_to_cc_send_fifo_get = true;
@@ -6282,5 +6180,5 @@
 if(m_debug)
 std::cout << "  <MEMC " << name()
-          << " CC_SEND_XRAM_RSP_INVAL_NLINE> BC-Inval for line "
+          << " CC_SEND_XRAM_RSP_INVAL_NLINE> Multicast-Inval for line "
           << std::hex << r_xram_rsp_to_cc_send_nline.read() << std::endl;
 #endif
@@ -6290,5 +6188,5 @@
       case CC_SEND_XRAM_RSP_BRDCAST_HEADER:  // send first flit broadcast-inval (from XRAM_RSP FSM)
       {
-        if(not p_dspin_out.read) break;
+        if(not p_dspin_m2p.read) break;
         r_cc_send_fsm = CC_SEND_XRAM_RSP_BRDCAST_NLINE;
         break;
@@ -6297,5 +6195,5 @@
       case CC_SEND_XRAM_RSP_BRDCAST_NLINE:   // send second flit broadcast-inval (from XRAM_RSP FSM)
       {
-        if(not p_dspin_out.read) break;
+        if(not p_dspin_m2p.read) break;
         m_cpt_inval_brdcast++;
         r_xram_rsp_to_cc_send_brdcast_req = false;
@@ -6313,5 +6211,5 @@
       case CC_SEND_WRITE_BRDCAST_HEADER:   // send first flit broadcast-inval (from WRITE FSM)
       {
-        if(not p_dspin_out.read) break;
+        if(not p_dspin_m2p.read) break;
         r_cc_send_fsm = CC_SEND_WRITE_BRDCAST_NLINE;
         break;
@@ -6320,5 +6218,5 @@
       case CC_SEND_WRITE_BRDCAST_NLINE:   // send second flit broadcast-inval (from WRITE FSM)
       {
-        if(not p_dspin_out.read) break;
+        if(not p_dspin_m2p.read) break;
 
         m_cpt_inval_brdcast++;
@@ -6340,5 +6238,5 @@
         if(m_write_to_cc_send_inst_fifo.rok())
         {
-          if(not p_dspin_out.read) break;
+          if(not p_dspin_m2p.read) break;
 
           r_cc_send_fsm = CC_SEND_WRITE_UPDT_NLINE;
@@ -6357,5 +6255,5 @@
       case CC_SEND_WRITE_UPDT_NLINE:   // send second flit for a multi-update (from WRITE FSM)
       {
-        if(not p_dspin_out.read) break;
+        if(not p_dspin_m2p.read) break;
         m_cpt_update_mult++;
 
@@ -6374,5 +6272,5 @@
       case CC_SEND_WRITE_UPDT_DATA:   // send N data flits for a multi-update (from WRITE FSM)
       {
-        if(not p_dspin_out.read) break;
+        if(not p_dspin_m2p.read) break;
         if(r_cc_send_cpt.read() == (r_write_to_cc_send_count.read()-1))
         {
@@ -6388,5 +6286,5 @@
       case CC_SEND_CAS_BRDCAST_HEADER:   // send first flit  broadcast-inval (from CAS FSM)
       {
-        if(not p_dspin_out.read) break;
+        if(not p_dspin_m2p.read) break;
         r_cc_send_fsm = CC_SEND_CAS_BRDCAST_NLINE;
         break;
@@ -6395,5 +6293,5 @@
       case CC_SEND_CAS_BRDCAST_NLINE:   // send second flit broadcast-inval (from CAS FSM)
       {
-        if(not p_dspin_out.read) break;
+        if(not p_dspin_m2p.read) break;
         m_cpt_inval_brdcast++;
 
@@ -6414,5 +6312,5 @@
         if(m_cas_to_cc_send_inst_fifo.rok())
         {
-          if(not p_dspin_out.read) break;
+          if(not p_dspin_m2p.read) break;
 
           r_cc_send_fsm = CC_SEND_CAS_UPDT_NLINE;
@@ -6432,5 +6330,5 @@
       case CC_SEND_CAS_UPDT_NLINE:   // send second flit for a multi-update (from CAS FSM)
       {
-        if(not p_dspin_out.read) break;
+        if(not p_dspin_m2p.read) break;
 
         m_cpt_update_mult++;
@@ -6450,5 +6348,5 @@
       case CC_SEND_CAS_UPDT_DATA:   // send first data for a multi-update (from CAS FSM)
       {
-        if(not p_dspin_out.read) break;
+        if(not p_dspin_m2p.read) break;
 
         if(r_cas_to_cc_send_is_long.read())
@@ -6465,5 +6363,5 @@
       case CC_SEND_CAS_UPDT_DATA_HIGH:   // send second data for a multi-update (from CAS FSM)
       {
-        if(not p_dspin_out.read) break;
+        if(not p_dspin_m2p.read) break;
         cas_to_cc_send_fifo_get = true;
         r_cc_send_fsm = CC_SEND_CAS_UPDT_HEADER;
@@ -6485,10 +6383,10 @@
     case CC_RECEIVE_IDLE:
       {
-        if(not p_dspin_in.write) break;
+        if(not p_dspin_p2m.write) break;
 
         uint8_t type =
           DspinDhccpParam::dspin_get(
-              p_dspin_in.data.read(),
-              DspinDhccpParam::FROM_L1_TYPE);
+              p_dspin_p2m.data.read(),
+              DspinDhccpParam::P2M_TYPE);
 
         if((type == DspinDhccpParam::TYPE_CLEANUP_DATA) or
@@ -6516,8 +6414,8 @@
         // write first CLEANUP flit in CC_RECEIVE to CLEANUP fifo
 
-        if(not p_dspin_in.write or not m_cc_receive_to_cleanup_fifo.wok())
+        if(not p_dspin_p2m.write or not m_cc_receive_to_cleanup_fifo.wok())
           break;
 
-        assert(not p_dspin_in.eop.read() and
+        assert(not p_dspin_p2m.eop.read() and
             "VCI_MEM_CACHE ERROR in CC_RECEIVE : "
             "CLEANUP command must have two flits");
@@ -6533,8 +6431,8 @@
         // write second CLEANUP flit in CC_RECEIVE to CLEANUP fifo
 
-        if(not p_dspin_in.write or not m_cc_receive_to_cleanup_fifo.wok())
+        if(not p_dspin_p2m.write or not m_cc_receive_to_cleanup_fifo.wok())
           break;
 
-        assert(p_dspin_in.eop.read() and
+        assert(p_dspin_p2m.eop.read() and
             "VCI_MEM_CACHE ERROR in CC_RECEIVE : "
             "CLEANUP command must have two flits");
@@ -6552,8 +6450,8 @@
 
         // wait for a WOK in the CC_RECEIVE to MULTI_ACK fifo
-        if(not p_dspin_in.write or not m_cc_receive_to_multi_ack_fifo.wok())
+        if(not p_dspin_p2m.write or not m_cc_receive_to_multi_ack_fifo.wok())
           break;
 
-        assert(p_dspin_in.eop.read() and
+        assert(p_dspin_p2m.eop.read() and
             "VCI_MEM_CACHE ERROR in CC_RECEIVE : "
             "MULTI_ACK command must have one flit");
@@ -6965,159 +6863,161 @@
   //    ALLOC_UPT FSM
   ////////////////////////////////////////////////////////////////////////////////////
-  // The ALLOC_UPT FSM allocates the access to the Update/Inval Table (UPT),
-  // with a round robin priority between six FSMs, with the following order:
-  //  CONFIG > MULTI_ACK > WRITE > XRAM_RSP > CLEANUP > CAS
-  // - The CONFIG FSM initiates an inval transaction and sets a new entry in UPT.
+  // The ALLOC_UPT FSM allocates the access to the Update Table (UPT),
+  // with a round robin priority between three FSMs, with the following order:
+  //  WRITE -> CAS -> MULTI_ACK
+  // - The WRITE FSM initiates update transaction and sets a new entry in UPT.
+  // - The CAS FSM does the same thing as the WRITE FSM.
   // - The MULTI_ACK FSM complete those trasactions and erase the UPT entry.
-  // - The WRITE FSM initiates update transaction and sets a new entry in UPT.
-  // - The XRAM_RSP FSM initiates an inval transactions and sets a new entry in UPT.
-  // - The CLEANUP  FSM decrement an entry in UPT.
-  // - The CAS FSM does the same thing as the WRITE FSM.
   // The resource is always allocated.
   /////////////////////////////////////////////////////////////////////////////////////
-
   switch(r_alloc_upt_fsm.read())
   {
-      //////////////////////
-      case ALLOC_UPT_CONFIG:   // allocated to CONFIG FSM
-      if (r_config_fsm.read() != CONFIG_DIR_UPT_LOCK)
-      {
-        if(r_multi_ack_fsm.read() == MULTI_ACK_UPT_LOCK)
-          r_alloc_upt_fsm = ALLOC_UPT_MULTI_ACK;
-               
-        else if((r_write_fsm.read() == WRITE_UPT_LOCK) or
-                (r_write_fsm.read() == WRITE_BC_UPT_LOCK))
-          r_alloc_upt_fsm = ALLOC_UPT_WRITE;
-
-        else if(r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)
-          r_alloc_upt_fsm = ALLOC_UPT_XRAM_RSP;
-
-        else if(r_cleanup_fsm.read() == CLEANUP_UPT_LOCK)
-          r_alloc_upt_fsm = ALLOC_UPT_CLEANUP;
-
-        else if((r_cas_fsm.read() == CAS_UPT_LOCK) or
-                (r_cas_fsm.read() == CAS_BC_UPT_LOCK))
-          r_alloc_upt_fsm = ALLOC_UPT_CAS;
-      }
-      break;
-
       /////////////////////////
-      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_write_fsm.read() == WRITE_UPT_LOCK) or
-            (r_write_fsm.read() == WRITE_BC_UPT_LOCK))
-          r_alloc_upt_fsm = ALLOC_UPT_WRITE;
-
-        else if(r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)
-          r_alloc_upt_fsm = ALLOC_UPT_XRAM_RSP;
-
-        else if(r_cleanup_fsm.read() == CLEANUP_UPT_LOCK)
-          r_alloc_upt_fsm = ALLOC_UPT_CLEANUP;
-
-        else if((r_cas_fsm.read() == CAS_UPT_LOCK) or
-                (r_cas_fsm.read() == CAS_BC_UPT_LOCK))
-          r_alloc_upt_fsm = ALLOC_UPT_CAS;
-
-        else if(r_config_fsm.read() == CONFIG_DIR_UPT_LOCK) 
-          r_alloc_upt_fsm = ALLOC_UPT_CONFIG;
-      }
-      break;
-
-      /////////////////////
-      case ALLOC_UPT_WRITE:   // allocated to WRITE FSM
-      if((r_write_fsm.read() != WRITE_UPT_LOCK) and
-          (r_write_fsm.read() != WRITE_BC_UPT_LOCK))
-      {
-        if(r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)
-          r_alloc_upt_fsm = ALLOC_UPT_XRAM_RSP;
-
-        else if(r_cleanup_fsm.read() == CLEANUP_UPT_LOCK)
-          r_alloc_upt_fsm = ALLOC_UPT_CLEANUP;
-
-        else if((r_cas_fsm.read() == CAS_UPT_LOCK) or
-                (r_cas_fsm.read() == CAS_BC_UPT_LOCK))
-          r_alloc_upt_fsm = ALLOC_UPT_CAS;
-
-        else if(r_config_fsm.read() == CONFIG_DIR_UPT_LOCK) 
-          r_alloc_upt_fsm = ALLOC_UPT_CONFIG;
-
-        else if(r_multi_ack_fsm.read() == MULTI_ACK_UPT_LOCK)
-          r_alloc_upt_fsm = ALLOC_UPT_MULTI_ACK;
-      }
-      break;
-
-      ////////////////////////
-      case ALLOC_UPT_XRAM_RSP:
-      if(r_xram_rsp_fsm.read() != XRAM_RSP_INVAL_LOCK)
-      {
-        if(r_cleanup_fsm.read() == CLEANUP_UPT_LOCK)
-          r_alloc_upt_fsm = ALLOC_UPT_CLEANUP;
-
-        else if((r_cas_fsm.read() == CAS_UPT_LOCK) or
-                (r_cas_fsm.read() == CAS_BC_UPT_LOCK))
-          r_alloc_upt_fsm = ALLOC_UPT_CAS;
-
-        else if(r_config_fsm.read() == CONFIG_DIR_UPT_LOCK) 
-          r_alloc_upt_fsm = ALLOC_UPT_CONFIG;
-
-        else if(r_multi_ack_fsm.read() == MULTI_ACK_UPT_LOCK)
-          r_alloc_upt_fsm = ALLOC_UPT_MULTI_ACK;
-
-        else if((r_write_fsm.read() == WRITE_UPT_LOCK)   or
-                (r_write_fsm.read() == WRITE_BC_UPT_LOCK))
-          r_alloc_upt_fsm = ALLOC_UPT_WRITE;
-      }
-      break;
-
+      case ALLOC_UPT_WRITE:         // allocated to WRITE FSM
+          if (r_write_fsm.read() != WRITE_UPT_LOCK)
+          {
+              if (r_cas_fsm.read() == CAS_UPT_LOCK)
+                  r_alloc_upt_fsm = ALLOC_UPT_CAS;
+
+              else if (r_multi_ack_fsm.read() == MULTI_ACK_UPT_LOCK)
+                  r_alloc_upt_fsm = ALLOC_UPT_MULTI_ACK;
+          }
+          break;
+
+      /////////////////////////
+      case ALLOC_UPT_CAS:           // allocated to CAS FSM
+          if (r_cas_fsm.read() != CAS_UPT_LOCK)
+          {
+              if (r_multi_ack_fsm.read() == MULTI_ACK_UPT_LOCK)
+                  r_alloc_upt_fsm = ALLOC_UPT_MULTI_ACK;
+
+              else if (r_write_fsm.read() == WRITE_UPT_LOCK)
+                  r_alloc_upt_fsm = ALLOC_UPT_WRITE;
+          }
+          break;
+
+      /////////////////////////
+      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_write_fsm.read() == WRITE_UPT_LOCK)
+                  r_alloc_upt_fsm = ALLOC_UPT_WRITE;
+
+              else if (r_cas_fsm.read() == CAS_UPT_LOCK)
+                  r_alloc_upt_fsm = ALLOC_UPT_CAS;
+          }
+          break;
+  } // end switch r_alloc_upt_fsm
+
+  ////////////////////////////////////////////////////////////////////////////////////
+  //    ALLOC_IVT FSM
+  ////////////////////////////////////////////////////////////////////////////////////
+  // The ALLOC_IVT FSM allocates the access to the Invalidate Table (IVT),
+  // with a round robin priority between five FSMs, with the following order:
+  //  WRITE -> XRAM_RSP -> CLEANUP -> CAS -> CONFIG
+  // - The WRITE FSM initiates broadcast invalidate transactions and sets a new entry
+  //   in IVT.
+  // - The CAS FSM does the same thing as the WRITE FSM.
+  // - The XRAM_RSP FSM initiates broadcast/multicast invalidate transaction and sets
+  //   a new entry in the IVT
+  // - The CONFIG FSM does the same thing as the XRAM_RSP FSM 
+  // - The CLEANUP FSM complete those trasactions and erase the IVT entry.
+  // The resource is always allocated.
+  /////////////////////////////////////////////////////////////////////////////////////
+  switch(r_alloc_ivt_fsm.read())
+  {
       //////////////////////////
-      case ALLOC_UPT_CLEANUP:
-      if((r_cleanup_fsm.read() != CLEANUP_UPT_LOCK     ) and
-         (r_cleanup_fsm.read() != CLEANUP_UPT_DECREMENT))
-      {
-        if((r_cas_fsm.read() == CAS_UPT_LOCK) or
-            (r_cas_fsm.read() == CAS_BC_UPT_LOCK))
-          r_alloc_upt_fsm = ALLOC_UPT_CAS;
-
-        else if(r_config_fsm.read() == CONFIG_DIR_UPT_LOCK) 
-          r_alloc_upt_fsm = ALLOC_UPT_CONFIG;
-
-        else if(r_multi_ack_fsm.read() == MULTI_ACK_UPT_LOCK)
-          r_alloc_upt_fsm = ALLOC_UPT_MULTI_ACK;
-
-        else if((r_write_fsm.read() == WRITE_UPT_LOCK) or
-                (r_write_fsm.read() == WRITE_BC_UPT_LOCK))
-          r_alloc_upt_fsm = ALLOC_UPT_WRITE;
-
-        else if(r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)
-          r_alloc_upt_fsm = ALLOC_UPT_XRAM_RSP;
-      }
-      break;
+      case ALLOC_IVT_WRITE:            // allocated to WRITE FSM
+          if (r_write_fsm.read() != WRITE_BC_IVT_LOCK)
+          {
+              if (r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)
+                  r_alloc_ivt_fsm = ALLOC_IVT_XRAM_RSP;
+
+              else if (r_cleanup_fsm.read() == CLEANUP_IVT_LOCK)
+                  r_alloc_ivt_fsm = ALLOC_IVT_CLEANUP;
+
+              else if (r_cas_fsm.read() == CAS_BC_IVT_LOCK)
+                  r_alloc_ivt_fsm = ALLOC_IVT_CAS;
+
+              else if (r_config_fsm.read() == CONFIG_DIR_IVT_LOCK)
+                  r_alloc_ivt_fsm = ALLOC_IVT_CONFIG;
+          }
+          break;
 
       //////////////////////////
-      case ALLOC_UPT_CAS:
-      if((r_cas_fsm.read() != CAS_UPT_LOCK) and
-          (r_cas_fsm.read() != CAS_BC_UPT_LOCK))
-      {
-        if(r_config_fsm.read() == CONFIG_DIR_UPT_LOCK) 
-          r_alloc_upt_fsm = ALLOC_UPT_CONFIG;
-
-        else if(r_multi_ack_fsm.read() == MULTI_ACK_UPT_LOCK)
-          r_alloc_upt_fsm = ALLOC_UPT_MULTI_ACK;
-
-        else if((r_write_fsm.read() == WRITE_UPT_LOCK) or
-                (r_write_fsm.read() == WRITE_BC_UPT_LOCK))
-          r_alloc_upt_fsm = ALLOC_UPT_WRITE;
-
-        else if(r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)
-          r_alloc_upt_fsm = ALLOC_UPT_XRAM_RSP;
-
-        else if(r_cleanup_fsm.read() == CLEANUP_UPT_LOCK)
-          r_alloc_upt_fsm = ALLOC_UPT_CLEANUP;
-      }
-      break;
-
-  } // end switch r_alloc_upt_fsm
+      case ALLOC_IVT_XRAM_RSP:         // allocated to XRAM_RSP FSM
+          if(r_xram_rsp_fsm.read() != XRAM_RSP_INVAL_LOCK)
+          {
+              if(r_cleanup_fsm.read() == CLEANUP_IVT_LOCK)
+                  r_alloc_ivt_fsm = ALLOC_IVT_CLEANUP;
+
+              else if (r_cas_fsm.read() == CAS_BC_IVT_LOCK)
+                  r_alloc_ivt_fsm = ALLOC_IVT_CAS;
+
+              else if (r_config_fsm.read() == CONFIG_DIR_IVT_LOCK)
+                  r_alloc_ivt_fsm = ALLOC_IVT_CONFIG;
+
+              else if (r_write_fsm.read() == WRITE_BC_IVT_LOCK)
+                  r_alloc_ivt_fsm = ALLOC_IVT_WRITE;
+          }
+          break;
+
+      //////////////////////////
+      case ALLOC_IVT_CLEANUP:          // allocated to CLEANUP FSM
+          if ((r_cleanup_fsm.read() != CLEANUP_IVT_LOCK     ) and
+              (r_cleanup_fsm.read() != CLEANUP_IVT_DECREMENT))
+          {
+              if (r_cas_fsm.read() == CAS_BC_IVT_LOCK)
+                  r_alloc_ivt_fsm = ALLOC_IVT_CAS;
+
+              else if (r_config_fsm.read() == CONFIG_DIR_IVT_LOCK)
+                  r_alloc_ivt_fsm = ALLOC_IVT_CONFIG;
+
+              else if (r_write_fsm.read() == WRITE_BC_IVT_LOCK)
+                  r_alloc_ivt_fsm = ALLOC_IVT_WRITE;
+
+              else if (r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)
+                  r_alloc_ivt_fsm = ALLOC_IVT_XRAM_RSP;
+          }
+          break;
+
+      //////////////////////////
+      case ALLOC_IVT_CAS:              // allocated to CAS FSM
+          if (r_cas_fsm.read() != CAS_BC_IVT_LOCK)
+          {
+              if (r_config_fsm.read() == CONFIG_DIR_IVT_LOCK)
+                  r_alloc_ivt_fsm = ALLOC_IVT_CONFIG;
+
+              else if (r_write_fsm.read() == WRITE_BC_IVT_LOCK)
+                  r_alloc_ivt_fsm = ALLOC_IVT_WRITE;
+
+              else if (r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)
+                  r_alloc_ivt_fsm = ALLOC_IVT_XRAM_RSP;
+
+              else if (r_cleanup_fsm.read() == CLEANUP_IVT_LOCK)
+                  r_alloc_ivt_fsm = ALLOC_IVT_CLEANUP;
+          }
+          break;
+
+      //////////////////////////
+      case ALLOC_IVT_CONFIG:           // allocated to CONFIG FSM
+          if (r_config_fsm.read() != CONFIG_DIR_IVT_LOCK)
+          {
+              if (r_write_fsm.read() == WRITE_BC_IVT_LOCK)
+                  r_alloc_ivt_fsm = ALLOC_IVT_WRITE;
+
+              else if (r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)
+                  r_alloc_ivt_fsm = ALLOC_IVT_XRAM_RSP;
+
+              else if (r_cleanup_fsm.read() == CLEANUP_IVT_LOCK)
+                  r_alloc_ivt_fsm = ALLOC_IVT_CLEANUP;
+
+              else if (r_cas_fsm.read() == CAS_BC_IVT_LOCK)
+                  r_alloc_ivt_fsm = ALLOC_IVT_CAS;
+          }
+          break;
+
+  } // end switch r_alloc_ivt_fsm
 
   ////////////////////////////////////////////////////////////////////////////////////
@@ -7149,5 +7049,5 @@
     if ( (r_config_fsm.read()    != CONFIG_DIR_REQ) and
          (r_config_fsm.read()    != CONFIG_DIR_ACCESS) and
-         (r_config_fsm.read()    != CONFIG_DIR_UPT_LOCK) )
+         (r_config_fsm.read()    != CONFIG_DIR_IVT_LOCK) )
     {
         if(r_read_fsm.read() == READ_DIR_REQ)
@@ -7202,5 +7102,5 @@
         (r_write_fsm.read()       != WRITE_DIR_HIT)  and
         (r_write_fsm.read()       != WRITE_BC_TRT_LOCK)  and
-        (r_write_fsm.read()       != WRITE_BC_UPT_LOCK)  and
+        (r_write_fsm.read()       != WRITE_BC_IVT_LOCK)  and
         (r_write_fsm.read()       != WRITE_MISS_TRT_LOCK)  and
         (r_write_fsm.read()       != WRITE_UPT_LOCK)  and
@@ -7238,5 +7138,5 @@
         (r_cas_fsm.read()         != CAS_DIR_HIT_WRITE)  and
         (r_cas_fsm.read()         != CAS_BC_TRT_LOCK)  and
-        (r_cas_fsm.read()         != CAS_BC_UPT_LOCK)  and
+        (r_cas_fsm.read()         != CAS_BC_IVT_LOCK)  and
         (r_cas_fsm.read()         != CAS_MISS_TRT_LOCK)  and
         (r_cas_fsm.read()         != CAS_UPT_LOCK)  and
@@ -7352,5 +7252,5 @@
       if((r_write_fsm.read() != WRITE_MISS_TRT_LOCK) and
           (r_write_fsm.read() != WRITE_BC_TRT_LOCK) and
-          (r_write_fsm.read() != WRITE_BC_UPT_LOCK))
+          (r_write_fsm.read() != WRITE_BC_IVT_LOCK))
       {
         if((r_cas_fsm.read() == CAS_MISS_TRT_LOCK) or
@@ -7375,5 +7275,5 @@
       if((r_cas_fsm.read() != CAS_MISS_TRT_LOCK) and
           (r_cas_fsm.read() != CAS_BC_TRT_LOCK) and
-          (r_cas_fsm.read() != CAS_BC_UPT_LOCK))
+          (r_cas_fsm.read() != CAS_BC_IVT_LOCK))
       {
         if((r_xram_rsp_fsm.read()  == XRAM_RSP_DIR_LOCK) and
@@ -7665,5 +7565,5 @@
   m_cc_receive_to_cleanup_fifo.update( cc_receive_to_cleanup_fifo_get,
                                        cc_receive_to_cleanup_fifo_put, 
-                                       p_dspin_in.data.read() );
+                                       p_dspin_p2m.data.read() );
 
   ////////////////////////////////////////////////////////////////////////////////////
@@ -7673,5 +7573,5 @@
   m_cc_receive_to_multi_ack_fifo.update( cc_receive_to_multi_ack_fifo_get,
                                          cc_receive_to_multi_ack_fifo_put, 
-                                         p_dspin_in.data.read() );
+                                         p_dspin_p2m.data.read() );
 
   ////////////////////////////////////////////////////////////////////////////////////
@@ -8015,10 +7915,10 @@
 
   ////////////////////////////////////////////////////////////////////
-  //  p_dspin_out port (CC_SEND FSM)
+  //  p_dspin_m2p port (CC_SEND FSM)
   ////////////////////////////////////////////////////////////////////
 
-  p_dspin_out.write = false;
-  p_dspin_out.eop   = false;
-  p_dspin_out.data  = 0;
+  p_dspin_m2p.write = false;
+  p_dspin_m2p.eop   = false;
+  p_dspin_m2p.data  = 0;
 
   switch(r_cc_send_fsm.read())
@@ -8029,5 +7929,4 @@
     case CC_SEND_WRITE_IDLE:
     case CC_SEND_CAS_IDLE:
-    case CC_SEND_CLEANUP_IDLE:
     {
         break;
@@ -8064,7 +7963,7 @@
         DspinDhccpParam::dspin_set( flit,
                                     multi_inval_type,
-                                    DspinDhccpParam::FROM_MC_TYPE);
-        p_dspin_out.write = true;
-        p_dspin_out.data  = flit;
+                                    DspinDhccpParam::M2P_TYPE);
+        p_dspin_m2p.write = true;
+        p_dspin_m2p.data  = flit;
         break;
     }
@@ -8076,54 +7975,9 @@
                                     r_config_to_cc_send_nline.read(),
                                     DspinDhccpParam::MULTI_INVAL_NLINE);
-        p_dspin_out.eop   = true;
-        p_dspin_out.write = true;
-        p_dspin_out.data  = flit;
+        p_dspin_m2p.eop   = true;
+        p_dspin_m2p.write = true;
+        p_dspin_m2p.data  = flit;
         break;
     }
-    ////////////////////////
-    case CC_SEND_CLEANUP_ACK:
-      {
-        uint8_t cleanup_ack_type;
-        if(r_cleanup_to_cc_send_inst.read())
-        {
-          cleanup_ack_type = DspinDhccpParam::TYPE_CLEANUP_ACK_INST;
-        }
-        else
-        {
-          cleanup_ack_type = DspinDhccpParam::TYPE_CLEANUP_ACK_DATA;
-        }
-
-        uint64_t flit = 0;
-        uint64_t dest =
-          r_cleanup_to_cc_send_srcid.read() <<
-          (DspinDhccpParam::SRCID_WIDTH - vci_param_int::S);
-
-        DspinDhccpParam::dspin_set(
-            flit,
-            dest,
-            DspinDhccpParam::CLEANUP_ACK_DEST);
-
-        DspinDhccpParam::dspin_set(
-            flit,
-            r_cleanup_to_cc_send_set_index.read(),
-            DspinDhccpParam::CLEANUP_ACK_SET);
-
-        DspinDhccpParam::dspin_set(
-            flit,
-            r_cleanup_to_cc_send_way_index.read(),
-            DspinDhccpParam::CLEANUP_ACK_WAY);
-
-        DspinDhccpParam::dspin_set(
-            flit,
-            cleanup_ack_type,
-            DspinDhccpParam::FROM_MC_TYPE);
-
-        p_dspin_out.eop   = true;
-        p_dspin_out.write = true;
-        p_dspin_out.data  = flit;
-
-        break;
-    }
-
     ///////////////////////////////////
     case CC_SEND_XRAM_RSP_INVAL_HEADER:
@@ -8159,7 +8013,7 @@
         DspinDhccpParam::dspin_set( flit,
                                     multi_inval_type,
-                                    DspinDhccpParam::FROM_MC_TYPE);
-        p_dspin_out.write = true;
-        p_dspin_out.data  = flit;
+                                    DspinDhccpParam::M2P_TYPE);
+        p_dspin_m2p.write = true;
+        p_dspin_m2p.data  = flit;
         break;
     }
@@ -8173,7 +8027,7 @@
                                     r_xram_rsp_to_cc_send_nline.read(),
                                     DspinDhccpParam::MULTI_INVAL_NLINE);
-        p_dspin_out.eop   = true;
-        p_dspin_out.write = true;
-        p_dspin_out.data  = flit;
+        p_dspin_m2p.eop   = true;
+        p_dspin_m2p.write = true;
+        p_dspin_m2p.data  = flit;
         break;
     }
@@ -8197,7 +8051,7 @@
         DspinDhccpParam::dspin_set( flit,
                                     1ULL,
-                                    DspinDhccpParam::FROM_MC_BC);
-        p_dspin_out.write = true;
-        p_dspin_out.data  = flit;
+                                    DspinDhccpParam::M2P_BC);
+        p_dspin_m2p.write = true;
+        p_dspin_m2p.data  = flit;
         break;
     }
@@ -8209,7 +8063,7 @@
                                     r_xram_rsp_to_cc_send_nline.read(),
                                     DspinDhccpParam::BROADCAST_NLINE);
-        p_dspin_out.write = true;
-        p_dspin_out.eop   = true;
-        p_dspin_out.data  = flit;
+        p_dspin_m2p.write = true;
+        p_dspin_m2p.eop   = true;
+        p_dspin_m2p.data  = flit;
         break;
     }
@@ -8221,7 +8075,7 @@
                                     r_config_to_cc_send_nline.read(),
                                     DspinDhccpParam::BROADCAST_NLINE);
-        p_dspin_out.write = true;
-        p_dspin_out.eop   = true;
-        p_dspin_out.data  = flit;
+        p_dspin_m2p.write = true;
+        p_dspin_m2p.eop   = true;
+        p_dspin_m2p.data  = flit;
         break;
     }
@@ -8233,7 +8087,7 @@
                                     r_write_to_cc_send_nline.read(),
                                     DspinDhccpParam::BROADCAST_NLINE);
-        p_dspin_out.write = true;
-        p_dspin_out.eop   = true;
-        p_dspin_out.data  = flit;
+        p_dspin_m2p.write = true;
+        p_dspin_m2p.eop   = true;
+        p_dspin_m2p.data  = flit;
         break;
     }
@@ -8245,7 +8099,7 @@
                                     r_cas_to_cc_send_nline.read(),
                                     DspinDhccpParam::BROADCAST_NLINE);
-        p_dspin_out.write = true;
-        p_dspin_out.eop   = true;
-        p_dspin_out.data  = flit;
+        p_dspin_m2p.write = true;
+        p_dspin_m2p.eop   = true;
+        p_dspin_m2p.data  = flit;
         break;
     }
@@ -8288,8 +8142,8 @@
             flit,
             multi_updt_type,
-            DspinDhccpParam::FROM_MC_TYPE);
-
-        p_dspin_out.write = true;
-        p_dspin_out.data  = flit;
+            DspinDhccpParam::M2P_TYPE);
+
+        p_dspin_m2p.write = true;
+        p_dspin_m2p.data  = flit;
 
         break;
@@ -8310,6 +8164,6 @@
             DspinDhccpParam::MULTI_UPDT_NLINE);
 
-        p_dspin_out.write = true;
-        p_dspin_out.data  = flit;
+        p_dspin_m2p.write = true;
+        p_dspin_m2p.data  = flit;
 
         break;
@@ -8337,7 +8191,7 @@
             DspinDhccpParam::MULTI_UPDT_DATA);
 
-        p_dspin_out.write = true;
-        p_dspin_out.eop   = (r_cc_send_cpt.read() == (r_write_to_cc_send_count.read()-1));
-        p_dspin_out.data  = flit;
+        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.data  = flit;
 
         break;
@@ -8381,8 +8235,8 @@
             flit,
             multi_updt_type,
-            DspinDhccpParam::FROM_MC_TYPE);
-
-        p_dspin_out.write = true;
-        p_dspin_out.data  = flit;
+            DspinDhccpParam::M2P_TYPE);
+
+        p_dspin_m2p.write = true;
+        p_dspin_m2p.data  = flit;
 
         break;
@@ -8403,6 +8257,6 @@
             DspinDhccpParam::MULTI_UPDT_NLINE);
 
-        p_dspin_out.write = true;
-        p_dspin_out.data  = flit;
+        p_dspin_m2p.write = true;
+        p_dspin_m2p.data  = flit;
 
         break;
@@ -8423,7 +8277,7 @@
             DspinDhccpParam::MULTI_UPDT_DATA);
 
-        p_dspin_out.write = true;
-        p_dspin_out.eop   = not r_cas_to_cc_send_is_long.read();
-        p_dspin_out.data  = flit;
+        p_dspin_m2p.write = true;
+        p_dspin_m2p.eop   = not r_cas_to_cc_send_is_long.read();
+        p_dspin_m2p.data  = flit;
 
         break;
@@ -8444,7 +8298,7 @@
             DspinDhccpParam::MULTI_UPDT_DATA);
 
-        p_dspin_out.write = true;
-        p_dspin_out.eop   = true;
-        p_dspin_out.data  = flit;
+        p_dspin_m2p.write = true;
+        p_dspin_m2p.eop   = true;
+        p_dspin_m2p.data  = flit;
 
         break;
@@ -8452,12 +8306,84 @@
   }
 
+  ////////////////////////////////////////////////////////////////////
+  //  p_dspin_clack port (CLEANUP FSM)
+  ////////////////////////////////////////////////////////////////////
+
+  switch(r_cleanup_fsm.read())
+  {
+    case CLEANUP_IDLE:
+    case CLEANUP_GET_NLINE:
+    case CLEANUP_DIR_REQ:
+    case CLEANUP_DIR_LOCK:
+    case CLEANUP_DIR_WRITE:
+    case CLEANUP_HEAP_REQ:
+    case CLEANUP_HEAP_LOCK:
+    case CLEANUP_HEAP_SEARCH:
+    case CLEANUP_HEAP_CLEAN:
+    case CLEANUP_HEAP_FREE:
+    case CLEANUP_IVT_LOCK:
+    case CLEANUP_IVT_DECREMENT:
+    case CLEANUP_IVT_CLEAR:
+    case CLEANUP_WRITE_RSP:
+    case CLEANUP_CONFIG_ACK:
+      p_dspin_clack.write = false;
+      p_dspin_clack.eop   = false;
+      p_dspin_clack.data  = 0;
+
+      break;
+
+    case CLEANUP_SEND_CLACK: 
+      {
+        uint8_t cleanup_ack_type;
+        if(r_cleanup_inst.read())
+        {
+          cleanup_ack_type = DspinDhccpParam::TYPE_CLACK_INST;
+        }
+        else
+        {
+          cleanup_ack_type = DspinDhccpParam::TYPE_CLACK_DATA;
+        }
+
+        uint64_t flit = 0;
+        uint64_t dest =
+          r_cleanup_srcid.read() <<
+          (DspinDhccpParam::SRCID_WIDTH - vci_param_int::S);
+
+        DspinDhccpParam::dspin_set(
+            flit,
+            dest,
+            DspinDhccpParam::CLACK_DEST);
+
+        DspinDhccpParam::dspin_set(
+            flit,
+            r_cleanup_nline.read() & 0xFFFF,
+            DspinDhccpParam::CLACK_SET);
+
+        DspinDhccpParam::dspin_set(
+            flit,
+            r_cleanup_way_index.read(),
+            DspinDhccpParam::CLACK_WAY);
+
+        DspinDhccpParam::dspin_set(
+            flit,
+            cleanup_ack_type,
+            DspinDhccpParam::CLACK_TYPE);
+
+        p_dspin_clack.eop   = true;
+        p_dspin_clack.write = true;
+        p_dspin_clack.data  = flit;
+      }
+      break;
+  }
+
   ///////////////////////////////////////////////////////////////////
-  //  p_dspin_in port (CC_RECEIVE FSM)
+  //  p_dspin_p2m port (CC_RECEIVE FSM)
   ///////////////////////////////////////////////////////////////////
-  p_dspin_in.read = false;
+  //
   switch(r_cc_receive_fsm.read())
   {
     case CC_RECEIVE_IDLE:
       {
+        p_dspin_p2m.read = false;
         break;
       }
@@ -8465,10 +8391,10 @@
     case CC_RECEIVE_CLEANUP_EOP:
       {
-        p_dspin_in.read = m_cc_receive_to_cleanup_fifo.wok();
+        p_dspin_p2m.read = m_cc_receive_to_cleanup_fifo.wok();
         break;
       }
     case CC_RECEIVE_MULTI_ACK:
       {
-        p_dspin_in.read = m_cc_receive_to_multi_ack_fifo.wok();
+        p_dspin_p2m.read = m_cc_receive_to_multi_ack_fifo.wok();
         break;
       }
Index: /trunk/platforms/tsar_generic_iob/top.cpp
===================================================================
--- /trunk/platforms/tsar_generic_iob/top.cpp	(revision 467)
+++ /trunk/platforms/tsar_generic_iob/top.cpp	(revision 468)
@@ -802,7 +802,7 @@
    // Horizontal inter-clusters INT network DSPIN 
    DspinSignals<dspin_int_cmd_width>*** signal_dspin_int_cmd_h_inc =
-      alloc_elems<DspinSignals<dspin_int_cmd_width> >("signal_dspin_int_cmd_h_inc", XMAX-1, YMAX, 2);
+      alloc_elems<DspinSignals<dspin_int_cmd_width> >("signal_dspin_int_cmd_h_inc", XMAX-1, YMAX, 3);
    DspinSignals<dspin_int_cmd_width>*** signal_dspin_int_cmd_h_dec =
-      alloc_elems<DspinSignals<dspin_int_cmd_width> >("signal_dspin_int_cmd_h_dec", XMAX-1, YMAX, 2);
+      alloc_elems<DspinSignals<dspin_int_cmd_width> >("signal_dspin_int_cmd_h_dec", XMAX-1, YMAX, 3);
    DspinSignals<dspin_int_rsp_width>*** signal_dspin_int_rsp_h_inc =
       alloc_elems<DspinSignals<dspin_int_rsp_width> >("signal_dspin_int_rsp_h_inc", XMAX-1, YMAX, 2);
@@ -812,7 +812,7 @@
    // Vertical inter-clusters INT network DSPIN
    DspinSignals<dspin_int_cmd_width>*** signal_dspin_int_cmd_v_inc =
-      alloc_elems<DspinSignals<dspin_int_cmd_width> >("signal_dspin_int_cmd_v_inc", XMAX, YMAX-1, 2);
+      alloc_elems<DspinSignals<dspin_int_cmd_width> >("signal_dspin_int_cmd_v_inc", XMAX, YMAX-1, 3);
    DspinSignals<dspin_int_cmd_width>*** signal_dspin_int_cmd_v_dec =
-      alloc_elems<DspinSignals<dspin_int_cmd_width> >("signal_dspin_int_cmd_v_dec", XMAX, YMAX-1, 2);
+      alloc_elems<DspinSignals<dspin_int_cmd_width> >("signal_dspin_int_cmd_v_dec", XMAX, YMAX-1, 3);
    DspinSignals<dspin_int_rsp_width>*** signal_dspin_int_rsp_v_inc =
       alloc_elems<DspinSignals<dspin_int_rsp_width> >("signal_dspin_int_rsp_v_inc", XMAX, YMAX-1, 2);
@@ -822,11 +822,11 @@
    // Mesh boundaries INT network DSPIN 
    DspinSignals<dspin_int_cmd_width>**** signal_dspin_false_int_cmd_in =
-      alloc_elems<DspinSignals<dspin_int_cmd_width> >("signal_dspin_false_int_cmd_in", XMAX, YMAX, 2, 4);
+      alloc_elems<DspinSignals<dspin_int_cmd_width> >("signal_dspin_false_int_cmd_in", XMAX, YMAX, 4, 3);
    DspinSignals<dspin_int_cmd_width>**** signal_dspin_false_int_cmd_out =
-      alloc_elems<DspinSignals<dspin_int_cmd_width> >("signal_dspin_false_int_cmd_out", XMAX, YMAX, 2, 4);
+      alloc_elems<DspinSignals<dspin_int_cmd_width> >("signal_dspin_false_int_cmd_out", XMAX, YMAX, 4, 3);
    DspinSignals<dspin_int_rsp_width>**** signal_dspin_false_int_rsp_in =
-      alloc_elems<DspinSignals<dspin_int_rsp_width> >("signal_dspin_false_int_rsp_in", XMAX, YMAX, 2, 4);
+      alloc_elems<DspinSignals<dspin_int_rsp_width> >("signal_dspin_false_int_rsp_in", XMAX, YMAX, 4, 2);
    DspinSignals<dspin_int_rsp_width>**** signal_dspin_false_int_rsp_out =
-      alloc_elems<DspinSignals<dspin_int_rsp_width> >("signal_dspin_false_int_rsp_out", XMAX, YMAX, 2, 4);
+      alloc_elems<DspinSignals<dspin_int_rsp_width> >("signal_dspin_false_int_rsp_out", XMAX, YMAX, 4, 2);
 
 
@@ -1152,14 +1152,18 @@
          for (size_t y = 0; y < YMAX; y++)
          {
+            for (size_t k = 0; k < 3; k++)
+            {
+               clusters[x][y]->p_dspin_int_cmd_out[EAST][k]      (signal_dspin_int_cmd_h_inc[x][y][k]);
+               clusters[x+1][y]->p_dspin_int_cmd_in[WEST][k]     (signal_dspin_int_cmd_h_inc[x][y][k]);
+               clusters[x][y]->p_dspin_int_cmd_in[EAST][k]       (signal_dspin_int_cmd_h_dec[x][y][k]);
+               clusters[x+1][y]->p_dspin_int_cmd_out[WEST][k]    (signal_dspin_int_cmd_h_dec[x][y][k]);
+            }
+
             for (size_t k = 0; k < 2; k++)
             {
-               clusters[x][y]->p_dspin_int_cmd_out[k][EAST]      (signal_dspin_int_cmd_h_inc[x][y][k]);
-               clusters[x+1][y]->p_dspin_int_cmd_in[k][WEST]     (signal_dspin_int_cmd_h_inc[x][y][k]);
-               clusters[x][y]->p_dspin_int_cmd_in[k][EAST]       (signal_dspin_int_cmd_h_dec[x][y][k]);
-               clusters[x+1][y]->p_dspin_int_cmd_out[k][WEST]    (signal_dspin_int_cmd_h_dec[x][y][k]);
-               clusters[x][y]->p_dspin_int_rsp_out[k][EAST]      (signal_dspin_int_rsp_h_inc[x][y][k]);
-               clusters[x+1][y]->p_dspin_int_rsp_in[k][WEST]     (signal_dspin_int_rsp_h_inc[x][y][k]);
-               clusters[x][y]->p_dspin_int_rsp_in[k][EAST]       (signal_dspin_int_rsp_h_dec[x][y][k]);
-               clusters[x+1][y]->p_dspin_int_rsp_out[k][WEST]    (signal_dspin_int_rsp_h_dec[x][y][k]);
+               clusters[x][y]->p_dspin_int_rsp_out[EAST][k]      (signal_dspin_int_rsp_h_inc[x][y][k]);
+               clusters[x+1][y]->p_dspin_int_rsp_in[WEST][k]     (signal_dspin_int_rsp_h_inc[x][y][k]);
+               clusters[x][y]->p_dspin_int_rsp_in[EAST][k]       (signal_dspin_int_rsp_h_dec[x][y][k]);
+               clusters[x+1][y]->p_dspin_int_rsp_out[WEST][k]    (signal_dspin_int_rsp_h_dec[x][y][k]);
             }
 
@@ -1185,14 +1189,18 @@
          for (size_t x = 0; x < XMAX; x++)
          {
+            for (size_t k = 0; k < 3; k++)
+            {
+               clusters[x][y]->p_dspin_int_cmd_out[NORTH][k]     (signal_dspin_int_cmd_v_inc[x][y][k]);
+               clusters[x][y+1]->p_dspin_int_cmd_in[SOUTH][k]    (signal_dspin_int_cmd_v_inc[x][y][k]);
+               clusters[x][y]->p_dspin_int_cmd_in[NORTH][k]      (signal_dspin_int_cmd_v_dec[x][y][k]);
+               clusters[x][y+1]->p_dspin_int_cmd_out[SOUTH][k]   (signal_dspin_int_cmd_v_dec[x][y][k]);
+            }
+
             for (size_t k = 0; k < 2; k++)
             {
-               clusters[x][y]->p_dspin_int_cmd_out[k][NORTH]     (signal_dspin_int_cmd_v_inc[x][y][k]);
-               clusters[x][y+1]->p_dspin_int_cmd_in[k][SOUTH]    (signal_dspin_int_cmd_v_inc[x][y][k]);
-               clusters[x][y]->p_dspin_int_cmd_in[k][NORTH]      (signal_dspin_int_cmd_v_dec[x][y][k]);
-               clusters[x][y+1]->p_dspin_int_cmd_out[k][SOUTH]   (signal_dspin_int_cmd_v_dec[x][y][k]);
-               clusters[x][y]->p_dspin_int_rsp_out[k][NORTH]     (signal_dspin_int_rsp_v_inc[x][y][k]);
-               clusters[x][y+1]->p_dspin_int_rsp_in[k][SOUTH]    (signal_dspin_int_rsp_v_inc[x][y][k]);
-               clusters[x][y]->p_dspin_int_rsp_in[k][NORTH]      (signal_dspin_int_rsp_v_dec[x][y][k]);
-               clusters[x][y+1]->p_dspin_int_rsp_out[k][SOUTH]   (signal_dspin_int_rsp_v_dec[x][y][k]);
+               clusters[x][y]->p_dspin_int_rsp_out[NORTH][k]     (signal_dspin_int_rsp_v_inc[x][y][k]);
+               clusters[x][y+1]->p_dspin_int_rsp_in[SOUTH][k]    (signal_dspin_int_rsp_v_inc[x][y][k]);
+               clusters[x][y]->p_dspin_int_rsp_in[NORTH][k]      (signal_dspin_int_rsp_v_dec[x][y][k]);
+               clusters[x][y+1]->p_dspin_int_rsp_out[SOUTH][k]   (signal_dspin_int_rsp_v_dec[x][y][k]);
             }
 
@@ -1214,15 +1222,18 @@
    for (size_t y = 0; y < YMAX; y++)
    {
+      for (size_t k = 0; k < 3; k++)
+      {
+         clusters[0][y]->p_dspin_int_cmd_in[WEST][k]          (signal_dspin_false_int_cmd_in[0][y][WEST][k]);
+         clusters[0][y]->p_dspin_int_cmd_out[WEST][k]         (signal_dspin_false_int_cmd_out[0][y][WEST][k]);
+         clusters[XMAX-1][y]->p_dspin_int_cmd_in[EAST][k]     (signal_dspin_false_int_cmd_in[XMAX-1][y][EAST][k]);
+         clusters[XMAX-1][y]->p_dspin_int_cmd_out[EAST][k]    (signal_dspin_false_int_cmd_out[XMAX-1][y][EAST][k]);
+      }
+
       for (size_t k = 0; k < 2; k++)
       {
-         clusters[0][y]->p_dspin_int_cmd_in[k][WEST]          (signal_dspin_false_int_cmd_in[0][y][k][WEST]);
-         clusters[0][y]->p_dspin_int_cmd_out[k][WEST]         (signal_dspin_false_int_cmd_out[0][y][k][WEST]);
-         clusters[0][y]->p_dspin_int_rsp_in[k][WEST]          (signal_dspin_false_int_rsp_in[0][y][k][WEST]);
-         clusters[0][y]->p_dspin_int_rsp_out[k][WEST]         (signal_dspin_false_int_rsp_out[0][y][k][WEST]);
-
-         clusters[XMAX-1][y]->p_dspin_int_cmd_in[k][EAST]     (signal_dspin_false_int_cmd_in[XMAX-1][y][k][EAST]);
-         clusters[XMAX-1][y]->p_dspin_int_cmd_out[k][EAST]    (signal_dspin_false_int_cmd_out[XMAX-1][y][k][EAST]);
-         clusters[XMAX-1][y]->p_dspin_int_rsp_in[k][EAST]     (signal_dspin_false_int_rsp_in[XMAX-1][y][k][EAST]);
-         clusters[XMAX-1][y]->p_dspin_int_rsp_out[k][EAST]    (signal_dspin_false_int_rsp_out[XMAX-1][y][k][EAST]);
+         clusters[0][y]->p_dspin_int_rsp_in[WEST][k]          (signal_dspin_false_int_rsp_in[0][y][WEST][k]);
+         clusters[0][y]->p_dspin_int_rsp_out[WEST][k]         (signal_dspin_false_int_rsp_out[0][y][WEST][k]);
+         clusters[XMAX-1][y]->p_dspin_int_rsp_in[EAST][k]     (signal_dspin_false_int_rsp_in[XMAX-1][y][EAST][k]);
+         clusters[XMAX-1][y]->p_dspin_int_rsp_out[EAST][k]    (signal_dspin_false_int_rsp_out[XMAX-1][y][EAST][k]);
       }
 
@@ -1243,15 +1254,18 @@
    for (size_t x = 0; x < XMAX; x++)
    {
+      for (size_t k = 0; k < 3; k++)
+      {
+         clusters[x][0]->p_dspin_int_cmd_in[SOUTH][k]         (signal_dspin_false_int_cmd_in[x][0][SOUTH][k]);
+         clusters[x][0]->p_dspin_int_cmd_out[SOUTH][k]        (signal_dspin_false_int_cmd_out[x][0][SOUTH][k]);
+         clusters[x][YMAX-1]->p_dspin_int_cmd_in[NORTH][k]    (signal_dspin_false_int_cmd_in[x][YMAX-1][NORTH][k]);
+         clusters[x][YMAX-1]->p_dspin_int_cmd_out[NORTH][k]   (signal_dspin_false_int_cmd_out[x][YMAX-1][NORTH][k]);
+      }
+
       for (size_t k = 0; k < 2; k++)
       {
-         clusters[x][0]->p_dspin_int_cmd_in[k][SOUTH]         (signal_dspin_false_int_cmd_in[x][0][k][SOUTH]);
-         clusters[x][0]->p_dspin_int_cmd_out[k][SOUTH]        (signal_dspin_false_int_cmd_out[x][0][k][SOUTH]);
-         clusters[x][0]->p_dspin_int_rsp_in[k][SOUTH]         (signal_dspin_false_int_rsp_in[x][0][k][SOUTH]);
-         clusters[x][0]->p_dspin_int_rsp_out[k][SOUTH]        (signal_dspin_false_int_rsp_out[x][0][k][SOUTH]);
-
-         clusters[x][YMAX-1]->p_dspin_int_cmd_in[k][NORTH]    (signal_dspin_false_int_cmd_in[x][YMAX-1][k][NORTH]);
-         clusters[x][YMAX-1]->p_dspin_int_cmd_out[k][NORTH]   (signal_dspin_false_int_cmd_out[x][YMAX-1][k][NORTH]);
-         clusters[x][YMAX-1]->p_dspin_int_rsp_in[k][NORTH]    (signal_dspin_false_int_rsp_in[x][YMAX-1][k][NORTH]);
-         clusters[x][YMAX-1]->p_dspin_int_rsp_out[k][NORTH]   (signal_dspin_false_int_rsp_out[x][YMAX-1][k][NORTH]);
+         clusters[x][0]->p_dspin_int_rsp_in[SOUTH][k]         (signal_dspin_false_int_rsp_in[x][0][SOUTH][k]);
+         clusters[x][0]->p_dspin_int_rsp_out[SOUTH][k]        (signal_dspin_false_int_rsp_out[x][0][SOUTH][k]);
+         clusters[x][YMAX-1]->p_dspin_int_rsp_in[NORTH][k]    (signal_dspin_false_int_rsp_in[x][YMAX-1][NORTH][k]);
+         clusters[x][YMAX-1]->p_dspin_int_rsp_out[NORTH][k]   (signal_dspin_false_int_rsp_out[x][YMAX-1][NORTH][k]);
       }
 
@@ -1283,15 +1297,18 @@
          for (size_t a = 0; a < 4; a++)
          {
+            for (size_t k = 0; k < 3; k++)
+            {
+               signal_dspin_false_int_cmd_in[x][y][a][k].write = false;
+               signal_dspin_false_int_cmd_in[x][y][a][k].read = true;
+               signal_dspin_false_int_cmd_out[x][y][a][k].write = false;
+               signal_dspin_false_int_cmd_out[x][y][a][k].read = true;
+            }
+
             for (size_t k = 0; k < 2; k++)
             {
-               signal_dspin_false_int_cmd_in[x][y][k][a].write = false;
-               signal_dspin_false_int_cmd_in[x][y][k][a].read = true;
-               signal_dspin_false_int_cmd_out[x][y][k][a].write = false;
-               signal_dspin_false_int_cmd_out[x][y][k][a].read = true;
-
-               signal_dspin_false_int_rsp_in[x][y][k][a].write = false;
-               signal_dspin_false_int_rsp_in[x][y][k][a].read = true;
-               signal_dspin_false_int_rsp_out[x][y][k][a].write = false;
-               signal_dspin_false_int_rsp_out[x][y][k][a].read = true;
+               signal_dspin_false_int_rsp_in[x][y][a][k].write = false;
+               signal_dspin_false_int_rsp_in[x][y][a][k].read = true;
+               signal_dspin_false_int_rsp_out[x][y][a][k].write = false;
+               signal_dspin_false_int_rsp_out[x][y][a][k].read = true;
             }
 
Index: /trunk/platforms/tsar_generic_iob/tsar_iob_cluster/caba/metadata/tsar_iob_cluster.sd
===================================================================
--- /trunk/platforms/tsar_generic_iob/tsar_iob_cluster/caba/metadata/tsar_iob_cluster.sd	(revision 467)
+++ /trunk/platforms/tsar_generic_iob/tsar_iob_cluster/caba/metadata/tsar_iob_cluster.sd	(revision 468)
@@ -108,20 +108,20 @@
 		Port('caba:clock_in', 'p_clk', auto = 'clock'),
 
-		Port('caba:dspin_output', 'p_int_cmd_out', [2, 4], 
+		Port('caba:dspin_output', 'p_int_cmd_out', [4, 3], 
               dspin_data_size = parameter.Reference('dspin_int_cmd_width')),
-		Port('caba:dspin_input', 'p_int_cmd_in', [2, 4], 
+		Port('caba:dspin_input', 'p_int_cmd_in', [4, 3], 
               dspin_data_size = parameter.Reference('dspin_int_cmd_width')),
-		Port('caba:dspin_output', 'p_int_rsp_out', [2, 4], 
+		Port('caba:dspin_output', 'p_int_rsp_out', [4, 2], 
               dspin_data_size = parameter.Reference('dspin_int_rsp_width')), 
-		Port('caba:dspin_input', 'p_int_rsp_in', [2, 4], 
+		Port('caba:dspin_input', 'p_int_rsp_in', [4, 2], 
               dspin_data_size = parameter.Reference('dspin_int_rsp_width')),
 
-		Port('caba:dspin_output', 'p_ext_cmd_out', [2, 4], 
+		Port('caba:dspin_output', 'p_ram_cmd_out', [4], 
               dspin_data_size = parameter.Reference('dspin_ram_cmd_width')),
-		Port('caba:dspin_input', 'p_ext_cmd_in', [2, 4], 
+		Port('caba:dspin_input', 'p_ram_cmd_in', [4], 
               dspin_data_size = parameter.Reference('dspin_ram_cmd_width')),
-		Port('caba:dspin_output', 'p_ext_rsp_out', [2, 4], 
+		Port('caba:dspin_output', 'p_ram_rsp_out', [4], 
               dspin_data_size = parameter.Reference('dspin_ram_rsp_width')), 
-		Port('caba:dspin_input', 'p_ext_rsp_in', [2, 4], 
+		Port('caba:dspin_input', 'p_ram_rsp_in', [4], 
               dspin_data_size = parameter.Reference('dspin_ram_rsp_width')),
 		],
Index: /trunk/platforms/tsar_generic_iob/tsar_iob_cluster/caba/source/include/tsar_iob_cluster.h
===================================================================
--- /trunk/platforms/tsar_generic_iob/tsar_iob_cluster/caba/source/include/tsar_iob_cluster.h	(revision 467)
+++ /trunk/platforms/tsar_generic_iob/tsar_iob_cluster/caba/source/include/tsar_iob_cluster.h	(revision 468)
@@ -77,4 +77,6 @@
 	DspinSignals<dspin_int_cmd_width>     signal_int_dspin_m2p_l2g_c;
 	DspinSignals<dspin_int_cmd_width>     signal_int_dspin_m2p_g2l_c; 
+	DspinSignals<dspin_int_cmd_width>     signal_int_dspin_clack_l2g_c;
+	DspinSignals<dspin_int_cmd_width>     signal_int_dspin_clack_g2l_c;
 	DspinSignals<dspin_int_rsp_width>     signal_int_dspin_rsp_l2g_d; 
 	DspinSignals<dspin_int_rsp_width>     signal_int_dspin_rsp_g2l_d; 
@@ -111,6 +113,8 @@
 	// Coherence DSPIN signals between DSPIN local crossbars and CC components 
 	DspinSignals<dspin_int_cmd_width>     signal_int_dspin_m2p_memc;
+	DspinSignals<dspin_int_cmd_width>     signal_int_dspin_clack_memc;
 	DspinSignals<dspin_int_rsp_width>     signal_int_dspin_p2m_memc;
 	DspinSignals<dspin_int_cmd_width>     signal_int_dspin_m2p_proc[8];
+	DspinSignals<dspin_int_cmd_width>     signal_int_dspin_clack_proc[8];
 	DspinSignals<dspin_int_rsp_width>     signal_int_dspin_p2m_proc[8];
 
@@ -179,4 +183,5 @@
     DspinLocalCrossbar<dspin_int_cmd_width>*          int_xbar_m2p_c;
     DspinLocalCrossbar<dspin_int_rsp_width>*          int_xbar_p2m_c;
+    DspinLocalCrossbar<dspin_int_cmd_width>*          int_xbar_clack_c;
 
     VirtualDspinRouter<dspin_int_cmd_width>*	      int_router_cmd;
Index: /trunk/platforms/tsar_generic_iob/tsar_iob_cluster/caba/source/src/tsar_iob_cluster.cpp
===================================================================
--- /trunk/platforms/tsar_generic_iob/tsar_iob_cluster/caba/source/src/tsar_iob_cluster.cpp	(revision 467)
+++ /trunk/platforms/tsar_generic_iob/tsar_iob_cluster/caba/source/src/tsar_iob_cluster.cpp	(revision 468)
@@ -89,8 +89,8 @@
 
     // Vectors of DSPIN ports for inter-cluster communications
-    p_dspin_int_cmd_in  = alloc_elems<DspinInput<dspin_int_cmd_width> >("p_int_cmd_in", 2, 4);
-    p_dspin_int_cmd_out = alloc_elems<DspinOutput<dspin_int_cmd_width> >("p_int_cmd_out", 2, 4);
-    p_dspin_int_rsp_in  = alloc_elems<DspinInput<dspin_int_rsp_width> >("p_int_rsp_in", 2, 4);
-    p_dspin_int_rsp_out = alloc_elems<DspinOutput<dspin_int_rsp_width> >("p_int_rsp_out", 2, 4);
+    p_dspin_int_cmd_in  = alloc_elems<DspinInput<dspin_int_cmd_width> >("p_int_cmd_in", 4, 3);
+    p_dspin_int_cmd_out = alloc_elems<DspinOutput<dspin_int_cmd_width> >("p_int_cmd_out", 4, 3);
+    p_dspin_int_rsp_in  = alloc_elems<DspinInput<dspin_int_rsp_width> >("p_int_rsp_in", 4, 2);
+    p_dspin_int_rsp_out = alloc_elems<DspinOutput<dspin_int_rsp_width> >("p_int_rsp_out", 4, 2);
 
     p_dspin_ram_cmd_in  = alloc_elems<DspinInput<dspin_ram_cmd_width> >("p_ext_cmd_in", 4);
@@ -171,4 +171,5 @@
                      8,                                  // TRANSACTION TABLE DEPTH
                      8,                                  // UPDATE TABLE DEPTH
+                     8,                                  // INVALIDATE TABLE DEPTH
                      debug_start_cycle,
                      memc_debug_ok );
@@ -303,4 +304,18 @@
                      false );                      // no broacast 
 
+    std::ostringstream s_int_xbar_clack_c;
+    s_int_xbar_clack_c << "int_xbar_clack_c_" << x_id << "_" << y_id;
+    int_xbar_clack_c = new DspinLocalCrossbar<dspin_int_cmd_width>(
+                     s_int_xbar_clack_c.str().c_str(),
+                     mt_int,                       // mapping table
+                     x_id, y_id,                   // cluster coordinates
+                     x_width, y_width, l_width,
+                     1,                            // number of local sources
+                     nb_procs,                     // number of local targets 
+                     1, 1,                         // fifo depths
+                     true,                         // CMD
+                     false,                        // don't use local routing table
+                     false);                       // broadcast
+
     //////////////  INT ROUTER(S)
     std::ostringstream s_int_router_cmd;
@@ -310,4 +325,5 @@
                      x_id,y_id,                    // coordinate in the mesh
                      x_width, y_width,             // x & y fields width
+                     3,                            // nb virtual channels
                      4,4);                         // input & output fifo depths
 
@@ -318,4 +334,5 @@
                      x_id,y_id,                    // coordinates in mesh
                      x_width, y_width,             // x & y fields width
+                     2,                            // nb virtual channels
                      4,4);                         // input & output fifo depths
 
@@ -459,25 +476,32 @@
     int_router_rsp->p_clk                        (this->p_clk);
     int_router_rsp->p_resetn                     (this->p_resetn);
-    for (int x = 0; x < 2; x++)
-    {
-        for(int y = 0; y < 4; y++)
+
+    for (int i = 0; i < 4; i++)
+    {
+        for(int k = 0; k < 3; k++)
         {
-            int_router_cmd->p_out[x][y]          (this->p_dspin_int_cmd_out[x][y]);
-            int_router_cmd->p_in[x][y]           (this->p_dspin_int_cmd_in[x][y]);
-            int_router_rsp->p_out[x][y]          (this->p_dspin_int_rsp_out[x][y]);
-            int_router_rsp->p_in[x][y]           (this->p_dspin_int_rsp_in[x][y]);
+            int_router_cmd->p_out[i][k]          (this->p_dspin_int_cmd_out[i][k]);
+            int_router_cmd->p_in[i][k]           (this->p_dspin_int_cmd_in[i][k]);
         }
+
+        for(int k = 0; k < 2; k++)
+        {
+            int_router_rsp->p_out[i][k]          (this->p_dspin_int_rsp_out[i][k]);
+            int_router_rsp->p_in[i][k]           (this->p_dspin_int_rsp_in[i][k]);
+        }
     }
 
     // local ports
-    int_router_cmd->p_out[0][4]                  (signal_int_dspin_cmd_g2l_d);
-    int_router_cmd->p_out[1][4]                  (signal_int_dspin_m2p_g2l_c);
-    int_router_cmd->p_in[0][4]                   (signal_int_dspin_cmd_l2g_d);
-    int_router_cmd->p_in[1][4]                   (signal_int_dspin_m2p_l2g_c);
+    int_router_cmd->p_out[4][0]                  (signal_int_dspin_cmd_g2l_d);
+    int_router_cmd->p_out[4][1]                  (signal_int_dspin_m2p_g2l_c);
+    int_router_cmd->p_out[4][2]                  (signal_int_dspin_clack_g2l_c);
+    int_router_cmd->p_in[4][0]                   (signal_int_dspin_cmd_l2g_d);
+    int_router_cmd->p_in[4][1]                   (signal_int_dspin_m2p_l2g_c);
+    int_router_cmd->p_in[4][2]                   (signal_int_dspin_clack_l2g_c);
     
-    int_router_rsp->p_out[0][4]                  (signal_int_dspin_rsp_g2l_d);
-    int_router_rsp->p_out[1][4]                  (signal_int_dspin_p2m_g2l_c);
-    int_router_rsp->p_in[0][4]                   (signal_int_dspin_rsp_l2g_d);
-    int_router_rsp->p_in[1][4]                   (signal_int_dspin_p2m_l2g_c);
+    int_router_rsp->p_out[4][0]                  (signal_int_dspin_rsp_g2l_d);
+    int_router_rsp->p_out[4][1]                  (signal_int_dspin_p2m_g2l_c);
+    int_router_rsp->p_in[4][0]                   (signal_int_dspin_rsp_l2g_d);
+    int_router_rsp->p_in[4][1]                   (signal_int_dspin_p2m_l2g_c);
 
     ///////////////////// CMD DSPIN  local crossbar direct
@@ -541,4 +565,13 @@
         int_xbar_p2m_c->p_local_in[p]            (signal_int_dspin_p2m_proc[p]);
 
+    ////////////////////// CLACK DSPIN local crossbar coherence
+    int_xbar_clack_c->p_clk                      (this->p_clk);
+    int_xbar_clack_c->p_resetn                   (this->p_resetn);
+    int_xbar_clack_c->p_global_out               (signal_int_dspin_clack_l2g_c);
+    int_xbar_clack_c->p_global_in                (signal_int_dspin_clack_g2l_c);
+    int_xbar_clack_c->p_local_in[0]              (signal_int_dspin_clack_memc);
+    for (size_t p = 0; p < nb_procs; p++)
+        int_xbar_clack_c->p_local_out[p]         (signal_int_dspin_clack_proc[p]);
+
     //////////////////////////////////// Processors
     for (size_t p = 0; p < nb_procs; p++)
@@ -547,6 +580,7 @@
         proc[p]->p_resetn                        (this->p_resetn);
         proc[p]->p_vci                           (signal_int_vci_ini_proc[p]);
-        proc[p]->p_dspin_in                      (signal_int_dspin_m2p_proc[p]);
-        proc[p]->p_dspin_out                     (signal_int_dspin_p2m_proc[p]);
+        proc[p]->p_dspin_m2p                     (signal_int_dspin_m2p_proc[p]);
+        proc[p]->p_dspin_p2m                     (signal_int_dspin_p2m_proc[p]);
+        proc[p]->p_dspin_clack                   (signal_int_dspin_clack_proc[p]);
         proc[p]->p_irq[0]                        (signal_proc_it[p]);
         for ( size_t j = 1 ; j < 6 ; j++)
@@ -563,10 +597,10 @@
 
     ///////////////////////////////////// XICU
-    xicu->p_clk                     	          (this->p_clk);
-    xicu->p_resetn                  	          (this->p_resetn);
-    xicu->p_vci                     	          (signal_int_vci_tgt_xicu);
+    xicu->p_clk                                  (this->p_clk);
+    xicu->p_resetn                               (this->p_resetn);
+    xicu->p_vci                                  (signal_int_vci_tgt_xicu);
     for ( size_t p=0 ; p<nb_procs ; p++)
     {
-        xicu->p_irq[p]              	          (signal_proc_it[p]);
+        xicu->p_irq[p]                           (signal_proc_it[p]);
     }
     for ( size_t i=0 ; i<4 ; i++)
@@ -590,10 +624,11 @@
 
     ///////////////////////////////////// MEMC
-    memc->p_clk                     	          (this->p_clk);
-    memc->p_resetn                  	          (this->p_resetn);
-    memc->p_vci_ixr                 	          (signal_ram_vci_ini_memc);
-    memc->p_vci_tgt                 	          (signal_int_vci_tgt_memc);
-    memc->p_dspin_in                             (signal_int_dspin_p2m_memc);
-    memc->p_dspin_out         	                (signal_int_dspin_m2p_memc);
+    memc->p_clk                                  (this->p_clk);
+    memc->p_resetn                               (this->p_resetn);
+    memc->p_vci_ixr                              (signal_ram_vci_ini_memc);
+    memc->p_vci_tgt                              (signal_int_vci_tgt_memc);
+    memc->p_dspin_p2m                            (signal_int_dspin_p2m_memc);
+    memc->p_dspin_m2p                            (signal_int_dspin_m2p_memc);
+    memc->p_dspin_clack                          (signal_int_dspin_clack_memc);
 
     // wrapper to INT network
@@ -612,7 +647,7 @@
 
     //////////////////////////////////// XRAM
-    xram->p_clk                     	          (this->p_clk);
-    xram->p_resetn                  	          (this->p_resetn);
-    xram->p_vci                 	                (signal_ram_vci_tgt_xram);
+    xram->p_clk                                  (this->p_clk);
+    xram->p_resetn                               (this->p_resetn);
+    xram->p_vci                                  (signal_ram_vci_tgt_xram);
 
     // wrapper to RAM network
@@ -624,8 +659,8 @@
 
     /////////////////////////////////// MDMA
-    mdma->p_clk                       	          (this->p_clk);
+    mdma->p_clk                                  (this->p_clk);
     mdma->p_resetn                               (this->p_resetn);
-    mdma->p_vci_target                	          (signal_int_vci_tgt_mdma);
-    mdma->p_vci_initiator             	          (signal_int_vci_ini_mdma);
+    mdma->p_vci_target                           (signal_int_vci_tgt_mdma);
+    mdma->p_vci_initiator                        (signal_int_vci_ini_mdma);
     for (size_t i=0 ; i<nb_dmas ; i++)
         mdma->p_irq[i]                           (signal_irq_mdma[i]);
Index: /trunk/platforms/tsar_generic_xbar/Makefile
===================================================================
--- /trunk/platforms/tsar_generic_xbar/Makefile	(revision 467)
+++ /trunk/platforms/tsar_generic_xbar/Makefile	(revision 468)
@@ -1,6 +1,6 @@
 simul.x: top.cpp top.desc
-	soclib-cc -j3 -P -p top.desc -I. -o simul.x
+	soclib-cc -t mysystemcass -j8 -P -p top.desc -I. -o simul.x
 
 clean:
 	soclib-cc -x -p top.desc -I.
-	rm -rf *.o *.x tty*
+	rm -rf *.o *.x term*
Index: /trunk/platforms/tsar_generic_xbar/soclib.conf
===================================================================
--- /trunk/platforms/tsar_generic_xbar/soclib.conf	(revision 467)
+++ /trunk/platforms/tsar_generic_xbar/soclib.conf	(revision 468)
@@ -1,2 +1,8 @@
+import os;
 
-config.addDescPath("/Users/alain/soc/tsar-trunk-svn-2013/")
+desc_path = os.environ['HOME'] + "/Workspace/repo/tsar/trunk"
+
+config.mylibsystemcass.cflags += ['-fpermissive']
+config.addDescPath(desc_path)
+
+# vim: filetype=python
Index: /trunk/platforms/tsar_generic_xbar/top.cpp
===================================================================
--- /trunk/platforms/tsar_generic_xbar/top.cpp	(revision 467)
+++ /trunk/platforms/tsar_generic_xbar/top.cpp	(revision 468)
@@ -151,5 +151,4 @@
 //////////////////////i/////////////////////////////////////
 
-
 #ifdef USE_ALMOS
 #include "almos/hard_config.h"
@@ -157,6 +156,6 @@
 #endif
 #ifdef USE_GIET
+#include "giet_vm/hard_config.h"
 #define PREFIX_OS "giet_vm/"
-#include "giet_vm/hard_config.h"
 #endif
 
@@ -190,5 +189,5 @@
 #ifdef USE_GIET
 #define BDEV_SECTOR_SIZE      512
-#define BDEV_IMAGE_NAME       "giet_vm/display/images.raw"
+#define BDEV_IMAGE_NAME       PREFIX_OS"display/images.raw"
 #endif
 #ifdef USE_ALMOS
@@ -196,5 +195,4 @@
 #define BDEV_IMAGE_NAME       PREFIX_OS"hdd-img.bin"
 #endif
-
 
 #define NIC_RX_NAME           PREFIX_OS"nic/rx_packets.txt"
@@ -212,10 +210,10 @@
 
 #ifdef USE_ALMOS
-#define soft_name PREFIX_OS"bootloader.bin",\
-                  PREFIX_OS"kernel-soclib.bin@0xbfc10000:D",\
-                  PREFIX_OS"arch-info.bib@0xBFC08000:D"
+#define soft_name       PREFIX_OS"bootloader.bin",\
+                        PREFIX_OS"kernel-soclib.bin@0xbfc10000:D",\
+                        PREFIX_OS"arch-info.bib@0xBFC08000:D"
 #endif
 #ifdef USE_GIET
-#define soft_pathname        PREFIX_OS"soft.elf"
+#define soft_pathname   PREFIX_OS"soft.elf"
 #endif
 
@@ -285,7 +283,7 @@
 
 #ifdef USE_GIET
-   char     soft_name[256]   = soft_pathname;          // pathname to binary code
-#endif
-   size_t   ncycles          = 1000000000;         // simulated cycles
+   char     soft_name[256]   = soft_pathname;      // pathname to binary code
+#endif
+   uint64_t ncycles          = 100000000000;       // simulated cycles
    char     disk_name[256]   = BDEV_IMAGE_NAME;    // pathname to the disk image
    char     nic_rx_name[256] = NIC_RX_NAME;        // pathname to the rx packets file
@@ -299,5 +297,5 @@
    uint32_t frozen_cycles    = MAX_FROZEN_CYCLES;  // monitoring frozen processor
    size_t   cluster_io_id    = 0;                  // index of cluster containing IOs
-   struct timeval t1,t2;
+   struct   timeval t1,t2;
    uint64_t ms1,ms2;
 
@@ -541,7 +539,7 @@
    // Horizontal inter-clusters DSPIN signals
    DspinSignals<dspin_cmd_width>*** signal_dspin_h_cmd_inc =
-      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_h_cmd_inc", XMAX-1, YMAX, 2);
+      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_h_cmd_inc", XMAX-1, YMAX, 3);
    DspinSignals<dspin_cmd_width>*** signal_dspin_h_cmd_dec =
-      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_h_cmd_dec", XMAX-1, YMAX, 2);
+      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_h_cmd_dec", XMAX-1, YMAX, 3);
    DspinSignals<dspin_rsp_width>*** signal_dspin_h_rsp_inc =
       alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_h_rsp_inc", XMAX-1, YMAX, 2);
@@ -551,7 +549,7 @@
    // Vertical inter-clusters DSPIN signals
    DspinSignals<dspin_cmd_width>*** signal_dspin_v_cmd_inc =
-      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_v_cmd_inc", XMAX, YMAX-1, 2);
+      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_v_cmd_inc", XMAX, YMAX-1, 3);
    DspinSignals<dspin_cmd_width>*** signal_dspin_v_cmd_dec =
-      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_v_cmd_dec", XMAX, YMAX-1, 2);
+      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_v_cmd_dec", XMAX, YMAX-1, 3);
    DspinSignals<dspin_rsp_width>*** signal_dspin_v_rsp_inc =
       alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_v_rsp_inc", XMAX, YMAX-1, 2);
@@ -561,11 +559,11 @@
    // Mesh boundaries DSPIN signals
    DspinSignals<dspin_cmd_width>**** signal_dspin_false_cmd_in =
-      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_false_cmd_in", XMAX, YMAX, 2, 4);
+      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_false_cmd_in" , XMAX, YMAX, 4, 3);
    DspinSignals<dspin_cmd_width>**** signal_dspin_false_cmd_out =
-      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_false_cmd_out", XMAX, YMAX, 2, 4);
+      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_false_cmd_out", XMAX, YMAX, 4, 3);
    DspinSignals<dspin_rsp_width>**** signal_dspin_false_rsp_in =
-      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_false_rsp_in", XMAX, YMAX, 2, 4);
+      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_false_rsp_in" , XMAX, YMAX, 4, 2);
    DspinSignals<dspin_rsp_width>**** signal_dspin_false_rsp_out =
-      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_false_rsp_out", XMAX, YMAX, 2, 4);
+      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_false_rsp_out", XMAX, YMAX, 4, 2);
 
 
@@ -680,9 +678,12 @@
       for (size_t x = 0; x < (XMAX-1); x++){
          for (size_t y = 0; y < YMAX; y++){
-            for (size_t k = 0; k < 2; k++){
+            for (size_t k = 0; k < 3; k++){
                clusters[x][y]->p_cmd_out[EAST][k]      (signal_dspin_h_cmd_inc[x][y][k]);
                clusters[x+1][y]->p_cmd_in[WEST][k]     (signal_dspin_h_cmd_inc[x][y][k]);
                clusters[x][y]->p_cmd_in[EAST][k]       (signal_dspin_h_cmd_dec[x][y][k]);
                clusters[x+1][y]->p_cmd_out[WEST][k]    (signal_dspin_h_cmd_dec[x][y][k]);
+            }
+
+            for (size_t k = 0; k < 2; k++){
                clusters[x][y]->p_rsp_out[EAST][k]      (signal_dspin_h_rsp_inc[x][y][k]);
                clusters[x+1][y]->p_rsp_in[WEST][k]     (signal_dspin_h_rsp_inc[x][y][k]);
@@ -699,9 +700,12 @@
       for (size_t y = 0; y < (YMAX-1); y++){
          for (size_t x = 0; x < XMAX; x++){
-            for (size_t k = 0; k < 2; k++){
+            for (size_t k = 0; k < 3; k++){
                clusters[x][y]->p_cmd_out[NORTH][k]     (signal_dspin_v_cmd_inc[x][y][k]);
                clusters[x][y+1]->p_cmd_in[SOUTH][k]    (signal_dspin_v_cmd_inc[x][y][k]);
                clusters[x][y]->p_cmd_in[NORTH][k]      (signal_dspin_v_cmd_dec[x][y][k]);
                clusters[x][y+1]->p_cmd_out[SOUTH][k]   (signal_dspin_v_cmd_dec[x][y][k]);
+            }
+
+            for (size_t k = 0; k < 2; k++){
                clusters[x][y]->p_rsp_out[NORTH][k]     (signal_dspin_v_rsp_inc[x][y][k]);
                clusters[x][y+1]->p_rsp_in[SOUTH][k]    (signal_dspin_v_rsp_inc[x][y][k]);
@@ -717,15 +721,18 @@
    for (size_t y = 0; y < YMAX; y++)
    {
+      for (size_t k = 0; k < 3; k++)
+      {
+         clusters[0][y]->p_cmd_in[WEST][k]        (signal_dspin_false_cmd_in[0][y][WEST][k]);
+         clusters[0][y]->p_cmd_out[WEST][k]       (signal_dspin_false_cmd_out[0][y][WEST][k]);
+         clusters[XMAX-1][y]->p_cmd_in[EAST][k]   (signal_dspin_false_cmd_in[XMAX-1][y][EAST][k]);
+         clusters[XMAX-1][y]->p_cmd_out[EAST][k]  (signal_dspin_false_cmd_out[XMAX-1][y][EAST][k]);
+      }
+
       for (size_t k = 0; k < 2; k++)
       {
-         clusters[0][y]->p_cmd_in[WEST][k]             (signal_dspin_false_cmd_in[0][y][k][WEST]);
-         clusters[0][y]->p_cmd_out[WEST][k]            (signal_dspin_false_cmd_out[0][y][k][WEST]);
-         clusters[0][y]->p_rsp_in[WEST][k]             (signal_dspin_false_rsp_in[0][y][k][WEST]);
-         clusters[0][y]->p_rsp_out[WEST][k]            (signal_dspin_false_rsp_out[0][y][k][WEST]);
-
-         clusters[XMAX-1][y]->p_cmd_in[EAST][k]   (signal_dspin_false_cmd_in[XMAX-1][y][k][EAST]);
-         clusters[XMAX-1][y]->p_cmd_out[EAST][k]  (signal_dspin_false_cmd_out[XMAX-1][y][k][EAST]);
-         clusters[XMAX-1][y]->p_rsp_in[EAST][k]   (signal_dspin_false_rsp_in[XMAX-1][y][k][EAST]);
-         clusters[XMAX-1][y]->p_rsp_out[EAST][k]  (signal_dspin_false_rsp_out[XMAX-1][y][k][EAST]);
+         clusters[0][y]->p_rsp_in[WEST][k]        (signal_dspin_false_rsp_in[0][y][WEST][k]);
+         clusters[0][y]->p_rsp_out[WEST][k]       (signal_dspin_false_rsp_out[0][y][WEST][k]);
+         clusters[XMAX-1][y]->p_rsp_in[EAST][k]   (signal_dspin_false_rsp_in[XMAX-1][y][EAST][k]);
+         clusters[XMAX-1][y]->p_rsp_out[EAST][k]  (signal_dspin_false_rsp_out[XMAX-1][y][EAST][k]);
       }
    }
@@ -734,15 +741,18 @@
    for (size_t x = 0; x < XMAX; x++)
    {
+      for (size_t k = 0; k < 3; k++)
+      {
+         clusters[x][0]->p_cmd_in[SOUTH][k]       (signal_dspin_false_cmd_in[x][0][SOUTH][k]);
+         clusters[x][0]->p_cmd_out[SOUTH][k]      (signal_dspin_false_cmd_out[x][0][SOUTH][k]);
+         clusters[x][YMAX-1]->p_cmd_in[NORTH][k]  (signal_dspin_false_cmd_in[x][YMAX-1][NORTH][k]);
+         clusters[x][YMAX-1]->p_cmd_out[NORTH][k] (signal_dspin_false_cmd_out[x][YMAX-1][NORTH][k]);
+      }
+
       for (size_t k = 0; k < 2; k++)
       {
-         clusters[x][0]->p_cmd_in[SOUTH][k]            (signal_dspin_false_cmd_in[x][0][k][SOUTH]);
-         clusters[x][0]->p_cmd_out[SOUTH][k]           (signal_dspin_false_cmd_out[x][0][k][SOUTH]);
-         clusters[x][0]->p_rsp_in[SOUTH][k]            (signal_dspin_false_rsp_in[x][0][k][SOUTH]);
-         clusters[x][0]->p_rsp_out[SOUTH][k]           (signal_dspin_false_rsp_out[x][0][k][SOUTH]);
-
-         clusters[x][YMAX-1]->p_cmd_in[NORTH][k]  (signal_dspin_false_cmd_in[x][YMAX-1][k][NORTH]);
-         clusters[x][YMAX-1]->p_cmd_out[NORTH][k] (signal_dspin_false_cmd_out[x][YMAX-1][k][NORTH]);
-         clusters[x][YMAX-1]->p_rsp_in[NORTH][k]  (signal_dspin_false_rsp_in[x][YMAX-1][k][NORTH]);
-         clusters[x][YMAX-1]->p_rsp_out[NORTH][k] (signal_dspin_false_rsp_out[x][YMAX-1][k][NORTH]);
+         clusters[x][0]->p_rsp_in[SOUTH][k]       (signal_dspin_false_rsp_in[x][0][SOUTH][k]);
+         clusters[x][0]->p_rsp_out[SOUTH][k]      (signal_dspin_false_rsp_out[x][0][SOUTH][k]);
+         clusters[x][YMAX-1]->p_rsp_in[NORTH][k]  (signal_dspin_false_rsp_in[x][YMAX-1][NORTH][k]);
+         clusters[x][YMAX-1]->p_rsp_out[NORTH][k] (signal_dspin_false_rsp_out[x][YMAX-1][NORTH][k]);
       }
    }
@@ -761,15 +771,17 @@
    for (size_t x = 0; x < XMAX ; x++){
       for (size_t y = 0; y < YMAX ; y++){
-         for (size_t k = 0; k < 2; k++){
-            for (size_t a = 0; a < 4; a++){
-               signal_dspin_false_cmd_in [x][y][k][a].write = false;
-               signal_dspin_false_cmd_in [x][y][k][a].read  = true;
-               signal_dspin_false_cmd_out[x][y][k][a].write = false;
-               signal_dspin_false_cmd_out[x][y][k][a].read  = true;
-
-               signal_dspin_false_rsp_in [x][y][k][a].write = false;
-               signal_dspin_false_rsp_in [x][y][k][a].read  = true;
-               signal_dspin_false_rsp_out[x][y][k][a].write = false;
-               signal_dspin_false_rsp_out[x][y][k][a].read  = true;
+         for (size_t a = 0; a < 4; a++){
+            for (size_t k = 0; k < 3; k++){
+               signal_dspin_false_cmd_in [x][y][a][k].write = false;
+               signal_dspin_false_cmd_in [x][y][a][k].read  = true;
+               signal_dspin_false_cmd_out[x][y][a][k].write = false;
+               signal_dspin_false_cmd_out[x][y][a][k].read  = true;
+            }
+
+            for (size_t k = 0; k < 2; k++){
+               signal_dspin_false_rsp_in [x][y][a][k].write = false;
+               signal_dspin_false_rsp_in [x][y][a][k].read  = true;
+               signal_dspin_false_rsp_out[x][y][a][k].write = false;
+               signal_dspin_false_rsp_out[x][y][a][k].read  = true;
             }
          }
@@ -786,5 +798,5 @@
    }
 
-   for (size_t n = 1; n < ncycles; n++)
+   for (uint64_t n = 1; n < ncycles; n++)
    {
       // Monitor a specific address for L1 & L2 caches
@@ -811,5 +823,4 @@
          }
       }
-
 
       if (debug_ok and (n > debug_from) and (n % debug_period == 0))
Index: /trunk/platforms/tsar_generic_xbar/tsar_xbar_cluster/caba/metadata/tsar_xbar_cluster.sd
===================================================================
--- /trunk/platforms/tsar_generic_xbar/tsar_xbar_cluster/caba/metadata/tsar_xbar_cluster.sd	(revision 467)
+++ /trunk/platforms/tsar_generic_xbar/tsar_xbar_cluster/caba/metadata/tsar_xbar_cluster.sd	(revision 468)
@@ -57,5 +57,5 @@
         Uses('caba:virtual_dspin_router', 
               flit_width      = parameter.Reference('dspin_rsp_width')),
-            
+
         Uses('caba:vci_multi_tty',
               cell_size       = parameter.Reference('vci_data_width_int')),
@@ -85,11 +85,11 @@
 		Port('caba:bit_in', 'p_resetn', auto = 'resetn'),
 		Port('caba:clock_in', 'p_clk', auto = 'clock'),
-		Port('caba:dspin_output', 'p_cmd_out', [2, 4], 
+		Port('caba:dspin_output', 'p_cmd_out', [4, 3], 
               dspin_data_size = parameter.Reference('dspin_cmd_width')),
-		Port('caba:dspin_input', 'p_cmd_in', [2, 4], 
+		Port('caba:dspin_input', 'p_cmd_in', [4, 3], 
               dspin_data_size = parameter.Reference('dspin_cmd_width')),
-		Port('caba:dspin_output', 'p_rsp_out', [2, 4], 
+		Port('caba:dspin_output', 'p_rsp_out', [4, 2], 
               dspin_data_size = parameter.Reference('dspin_rsp_width')), 
-		Port('caba:dspin_input', 'p_rsp_in', [2, 4], 
+		Port('caba:dspin_input', 'p_rsp_in', [4, 2], 
               dspin_data_size = parameter.Reference('dspin_rsp_width')),
 		],
Index: /trunk/platforms/tsar_generic_xbar/tsar_xbar_cluster/caba/source/include/tsar_xbar_cluster.h
===================================================================
--- /trunk/platforms/tsar_generic_xbar/tsar_xbar_cluster/caba/source/include/tsar_xbar_cluster.h	(revision 467)
+++ /trunk/platforms/tsar_generic_xbar/tsar_xbar_cluster/caba/source/include/tsar_xbar_cluster.h	(revision 468)
@@ -69,4 +69,6 @@
     DspinSignals<dspin_cmd_width>   signal_dspin_m2p_l2g_c;
     DspinSignals<dspin_cmd_width>   signal_dspin_m2p_g2l_c;
+    DspinSignals<dspin_cmd_width>   signal_dspin_clack_l2g_c;
+    DspinSignals<dspin_cmd_width>   signal_dspin_clack_g2l_c;
     DspinSignals<dspin_rsp_width>   signal_dspin_rsp_l2g_d;
     DspinSignals<dspin_rsp_width>   signal_dspin_rsp_g2l_d;
@@ -115,6 +117,8 @@
     // Coherence DSPIN signals to local crossbar
     DspinSignals<dspin_cmd_width>     signal_dspin_m2p_memc;
+    DspinSignals<dspin_cmd_width>     signal_dspin_clack_memc;
     DspinSignals<dspin_rsp_width>     signal_dspin_p2m_memc;
     DspinSignals<dspin_cmd_width>     signal_dspin_m2p_proc[8];
+    DspinSignals<dspin_cmd_width>     signal_dspin_clack_proc[8];
     DspinSignals<dspin_rsp_width>     signal_dspin_p2m_proc[8];
 
@@ -198,4 +202,5 @@
     DspinLocalCrossbar<dspin_cmd_width>*          xbar_m2p_c;
     DspinLocalCrossbar<dspin_rsp_width>*          xbar_p2m_c;
+    DspinLocalCrossbar<dspin_cmd_width>*          xbar_clack_c;
 
     VirtualDspinRouter<dspin_cmd_width>*          router_cmd;
Index: /trunk/platforms/tsar_generic_xbar/tsar_xbar_cluster/caba/source/src/tsar_xbar_cluster.cpp
===================================================================
--- /trunk/platforms/tsar_generic_xbar/tsar_xbar_cluster/caba/source/src/tsar_xbar_cluster.cpp	(revision 467)
+++ /trunk/platforms/tsar_generic_xbar/tsar_xbar_cluster/caba/source/src/tsar_xbar_cluster.cpp	(revision 468)
@@ -85,6 +85,6 @@
 {
     // Vectors of ports definition
-    p_cmd_in        = alloc_elems<DspinInput<dspin_cmd_width> >("p_cmd_in", 4, 2);
-    p_cmd_out       = alloc_elems<DspinOutput<dspin_cmd_width> >("p_cmd_out", 4, 2);
+    p_cmd_in        = alloc_elems<DspinInput<dspin_cmd_width> >("p_cmd_in", 4, 3);
+    p_cmd_out       = alloc_elems<DspinOutput<dspin_cmd_width> >("p_cmd_out", 4, 3);
     p_rsp_in        = alloc_elems<DspinInput<dspin_rsp_width> >("p_rsp_in", 4, 2);
     p_rsp_out       = alloc_elems<DspinOutput<dspin_rsp_width> >("p_rsp_out", 4, 2);
@@ -148,4 +148,5 @@
                      8,                                  // TRANSACTION TABLE DEPTH
                      8,                                  // UPDATE TABLE DEPTH
+                     8,                                  // INVALIDATE TABLE DEPTH
                      debug_start_cycle,
                      memc_debug_ok );
@@ -269,9 +270,22 @@
 
     /////////////////////////////////////////////////////////////////////////////
+    xbar_clack_c = new DspinLocalCrossbar<dspin_cmd_width>(
+                     "xbar_clack_c",
+                     mtd,                          // mapping table
+                     x_id, y_id,                   // cluster coordinates
+                     x_width, y_width, l_width,
+                     1,                            // number of local sources
+                     nb_procs,                     // number of local targets 
+                     1, 1,                         // fifo depths
+                     true,                         // CMD
+                     false,                        // don't use local routing table
+                     false);                       // broadcast
+
+    /////////////////////////////////////////////////////////////////////////////
     router_cmd = new VirtualDspinRouter<dspin_cmd_width>(
                      "router_cmd",
                      x_id,y_id,                    // coordinate in the mesh
                      x_width, y_width,             // x & y fields width
-                     2,                            // nb virtual channels
+                     3,                            // nb virtual channels
                      4,4);                         // input & output fifo depths
 
@@ -385,8 +399,12 @@
     for(int i = 0; i < 4; i++)
     {
-        for (int k = 0; k < 2; k++)
+        for (int k = 0; k < 3; k++)
         {
             router_cmd->p_out[i][k]          (this->p_cmd_out[i][k]);
             router_cmd->p_in[i][k]           (this->p_cmd_in[i][k]);
+        }
+
+        for (int k = 0; k < 2; k++)
+        {
             router_rsp->p_out[i][k]          (this->p_rsp_out[i][k]);
             router_rsp->p_in[i][k]           (this->p_rsp_in[i][k]);
@@ -396,6 +414,8 @@
     router_cmd->p_out[4][0]                  (signal_dspin_cmd_g2l_d);
     router_cmd->p_out[4][1]                  (signal_dspin_m2p_g2l_c);
+    router_cmd->p_out[4][2]                  (signal_dspin_clack_g2l_c);
     router_cmd->p_in[4][0]                   (signal_dspin_cmd_l2g_d);
     router_cmd->p_in[4][1]                   (signal_dspin_m2p_l2g_c);
+    router_cmd->p_in[4][2]                   (signal_dspin_clack_l2g_c);
 
     router_rsp->p_out[4][0]                  (signal_dspin_rsp_g2l_d);
@@ -403,4 +423,5 @@
     router_rsp->p_in[4][0]                   (signal_dspin_rsp_l2g_d);
     router_rsp->p_in[4][1]                   (signal_dspin_p2m_l2g_c);
+
 
     std::cout << "  - CMD & RSP routers connected" << std::endl;
@@ -473,4 +494,15 @@
     std::cout << "  - M2P Coherence crossbar connected" << std::endl;
 
+    ////////////////////// CLACK DSPIN local crossbar coherence
+    xbar_clack_c->p_clk                          (this->p_clk);
+    xbar_clack_c->p_resetn                       (this->p_resetn);
+    xbar_clack_c->p_global_out                   (signal_dspin_clack_l2g_c);
+    xbar_clack_c->p_global_in                    (signal_dspin_clack_g2l_c);
+    xbar_clack_c->p_local_in[0]                  (signal_dspin_clack_memc);
+    for (size_t p = 0; p < nb_procs; p++)
+        xbar_clack_c->p_local_out[p]               (signal_dspin_clack_proc[p]);
+
+    std::cout << "  - Clack Coherence crossbar connected" << std::endl;
+
     ////////////////////////// P2M DSPIN local crossbar coherence
     xbar_p2m_c->p_clk                            (this->p_clk);
@@ -491,6 +523,7 @@
         proc[p]->p_resetn                   (this->p_resetn);
         proc[p]->p_vci                      (signal_vci_ini_proc[p]);
-        proc[p]->p_dspin_in                 (signal_dspin_m2p_proc[p]);
-        proc[p]->p_dspin_out                (signal_dspin_p2m_proc[p]);
+        proc[p]->p_dspin_m2p                (signal_dspin_m2p_proc[p]);
+        proc[p]->p_dspin_p2m                (signal_dspin_p2m_proc[p]);
+        proc[p]->p_dspin_clack              (signal_dspin_clack_proc[p]);
         proc[p]->p_irq[0]                   (signal_proc_it[p]);
         for ( size_t j = 1 ; j < 6 ; j++)
@@ -549,6 +582,7 @@
     memc->p_vci_ixr                    (signal_vci_xram);
     memc->p_vci_tgt                    (signal_vci_tgt_memc);
-    memc->p_dspin_in                   (signal_dspin_p2m_memc);
-    memc->p_dspin_out                  (signal_dspin_m2p_memc);
+    memc->p_dspin_p2m                  (signal_dspin_p2m_memc);
+    memc->p_dspin_m2p                  (signal_dspin_m2p_memc);
+    memc->p_dspin_clack                (signal_dspin_clack_memc);
 
     // wrapper MEMC
