Index: branches/reconfiguration/modules/vci_cc_vcache_wrapper/caba/source/include/vci_cc_vcache_wrapper.h
===================================================================
--- branches/reconfiguration/modules/vci_cc_vcache_wrapper/caba/source/include/vci_cc_vcache_wrapper.h	(revision 905)
+++ branches/reconfiguration/modules/vci_cc_vcache_wrapper/caba/source/include/vci_cc_vcache_wrapper.h	(revision 919)
@@ -123,4 +123,5 @@
         DCACHE_XTN_DC_INVAL_GO,
         DCACHE_XTN_DT_INVAL,
+        DCACHE_XTN_CC_TEST,
         //handling dirty bit update
         DCACHE_DIRTY_GET_PTE,
@@ -184,4 +185,6 @@
         CC_RECEIVE_INS_UPDT_DATA,
         CC_RECEIVE_DATA_UPDT_DATA,
+        CC_RECEIVE_TEST_HEADER,
+        CC_RECEIVE_TEST_SIGNATURE,
     };
 
@@ -192,4 +195,14 @@
         CC_SEND_CLEANUP_2,
         CC_SEND_MULTI_ACK,
+        CC_SEND_TEST_HEADER,
+        CC_SEND_TEST_SIGNATURE,
+    };
+
+    enum cc_test_fsm_state_e
+    {
+        CC_TEST_IDLE,
+        CC_TEST_P2M_REQ,
+        CC_TEST_P2M_WAIT,
+        CC_TEST_ACK_WAIT,
     };
 
@@ -279,6 +292,10 @@
 
     // this enumeration type extends the ExternalAcessTypes defined in iss2.h
+    // XTN_CC_TEST:
+    //    When XTN_WRITE: triggers the CC_TEST. The target MEMC is in dreq.wdata
+    //    When XTN_READ: returns the CC_TEST result
     enum xtn_cop2_extension_e {
         XTN_WDT_MAX = 26,              // Read & Write the watchdog timer threshold
+        XTN_CC_TEST = 27,              // Trigger coherence network test
     };
 
@@ -516,4 +533,8 @@
     sc_signal<uint32_t>     r_dcache_paddr_ext;             // CP2 register (if vci_address > 32)
 
+    // communication between DCACHE FSM and CC_TEST FSM
+    sc_signal<bool>         r_dcache_to_cc_test_req;
+    sc_signal<uint32_t>     r_dcache_to_cc_test_dest;
+
     ///////////////////////////////////
     // VCI_CMD FSM REGISTERS
@@ -574,4 +595,22 @@
     sc_signal<bool>         r_dspin_clack_req;
     sc_signal<uint64_t>     r_dspin_clack_flit;
+    sc_signal<bool>         r_dspin_clack_test;
+
+    ///////////////////////////////////
+    //  CC_TEST FSM REGISTER
+    ///////////////////////////////////
+    enum cc_test_result_e
+    {
+        CC_TEST_SUCCESS = 0,
+        CC_TEST_FAILURE = 1,
+    };
+
+    sc_signal<int>          r_cc_test_fsm;
+    sc_signal<bool>         r_cc_test_to_cc_send_req;
+    sc_signal<bool>         r_cc_test_m2p_req;
+    sc_signal<uint64_t>     r_cc_test_m2p_sign;
+    sc_signal<bool>         r_cc_test_clack_req;
+    sc_signal<uint64_t>     r_cc_test_clack_sign;
+    sc_signal<int>          r_cc_test_to_dcache_result;
 
     //////////////////////////////////////////////////////////////////
Index: branches/reconfiguration/modules/vci_cc_vcache_wrapper/caba/source/src/vci_cc_vcache_wrapper.cpp
===================================================================
--- branches/reconfiguration/modules/vci_cc_vcache_wrapper/caba/source/src/vci_cc_vcache_wrapper.cpp	(revision 905)
+++ branches/reconfiguration/modules/vci_cc_vcache_wrapper/caba/source/src/vci_cc_vcache_wrapper.cpp	(revision 919)
@@ -96,4 +96,5 @@
         "DCACHE_XTN_DC_INVAL_GO",
         "DCACHE_XTN_DT_INVAL",
+        "DCACHE_XTN_CC_TEST",
 
         "DCACHE_DIRTY_GET_PTE",
@@ -172,4 +173,6 @@
         "CC_RECEIVE_DATA_UPDT_NLINE",
         "CC_RECEIVE_DATA_UPDT_DATA",
+        "CC_RECEIVE_TEST_HEADER",
+        "CC_RECEIVE_TEST_SIGNATURE",
     };
 
@@ -179,4 +182,13 @@
         "CC_SEND_CLEANUP_2",
         "CC_SEND_MULTI_ACK",
+        "CC_SEND_TEST_HEADER",
+        "CC_SEND_TEST_SIGNATURE",
+    };
+
+const char * cc_test_fsm_state_str[] = {
+        "CC_TEST_IDLE",
+        "CC_TEST_P2M_REQ",
+        "CC_TEST_P2M_WAIT",
+        "CC_TEST_ACK_WAIT",
     };
 }
@@ -371,4 +383,7 @@
       r_dcache_cc_send_updt_tab_idx("r_dcache_cc_send_updt_tab_idx"),
 
+      r_dcache_to_cc_test_req("r_dcache_to_cc_test_req"),
+      r_dcache_to_cc_test_dest("r_dcache_to_cc_test_dest"),
+
       r_vci_cmd_fsm("r_vci_cmd_fsm"),
       r_vci_cmd_min("r_vci_cmd_min"),
@@ -407,4 +422,12 @@
       r_cc_receive_dcache_updt_tab_idx("r_cc_receive_dcache_updt_tab_idx"),
       r_cc_receive_dcache_nline("r_cc_receive_dcache_nline"),
+
+      r_cc_test_fsm("r_cc_test_fsm"),
+      r_cc_test_to_cc_send_req("r_cc_test_to_cc_send_req"),
+      r_cc_test_m2p_req("r_cc_test_m2p_req"),
+      r_cc_test_m2p_sign("r_cc_test_m2p_sign"),
+      r_cc_test_clack_req("r_cc_test_clack_req"),
+      r_cc_test_clack_sign("r_cc_test_clack_sign"),
+      r_cc_test_to_dcache_result("r_cc_test_to_dcache_result"),
 
       r_iss(this->name(), proc_id),
@@ -503,4 +526,5 @@
               << " | " << cc_receive_fsm_state_str[r_cc_receive_fsm.read()]
               << " | " << cc_send_fsm_state_str[r_cc_send_fsm.read()]
+              << " | " << cc_test_fsm_state_str[r_cc_test_fsm.read()]
               << " | MMU = " << r_mmu_mode.read();
 
@@ -762,4 +786,5 @@
         r_cc_receive_fsm = CC_RECEIVE_IDLE;
         r_cc_send_fsm    = CC_SEND_IDLE;
+        r_cc_test_fsm    = CC_TEST_IDLE;
 
         // reset data physical address extension
@@ -837,4 +862,9 @@
 
         r_dspin_clack_req          = false;
+        r_dspin_clack_test         = false;
+
+        r_cc_test_to_cc_send_req   = false;
+        r_cc_test_m2p_req          = false;
+        r_cc_test_clack_req        = false;
 
         // No signalisation  of errors
@@ -2541,4 +2571,10 @@
                         break;
 
+                    case XTN_CC_TEST:
+                        m_drsp.rdata = r_cc_test_to_dcache_result.read();
+                        m_drsp.valid = true;
+                        m_drsp.error = false;
+                        break;
+
                     default:
                         r_mmu_detr   = MMU_READ_UNDEFINED_XTN;
@@ -2684,4 +2720,10 @@
                         m_drsp.valid = true;
                         r_dcache_fsm = DCACHE_IDLE;
+                        break;
+
+                    case XTN_CC_TEST:
+                        r_dcache_to_cc_test_dest = m_dreq.wdata;
+                        r_dcache_to_cc_test_req = true;
+                        r_dcache_fsm = DCACHE_XTN_CC_TEST;
                         break;
 
@@ -4121,4 +4163,44 @@
         r_dcache_fsm = DCACHE_IDLE;
         m_drsp.valid = true;
+        break;
+    }
+    //////////////////////////////
+    case DCACHE_XTN_CC_TEST:      // wait the CC_TEST to finish
+    {
+        // coherence clack request (from DSPIN CLACK)
+        if (r_dcache_clack_req.read())
+        {
+            r_dcache_fsm = DCACHE_CC_CHECK;
+            r_dcache_fsm_cc_save = r_dcache_fsm.read();
+            break;
+        }
+
+        // coherence request (from CC_RECEIVE FSM)
+        if (r_cc_receive_dcache_req.read() and not r_dcache_cc_send_req.read())
+        {
+            r_dcache_fsm = DCACHE_CC_CHECK;
+            r_dcache_fsm_cc_save = r_dcache_fsm.read();
+            break;
+        }
+
+        // wait the CC_TEST request to finish
+        // the test result is stored at the r_cc_test_to_dcache_result
+        if (not r_dcache_to_cc_test_req.read())
+        {
+            r_dcache_fsm = DCACHE_IDLE;
+            m_drsp.valid = true;
+
+#if DEBUG_DCACHE
+            if (m_debug_dcache_fsm)
+            {
+                std::cout << "  <PROC " << name()
+                    << " DCACHE_XTN_CC_TEST> CC_TEST finished:"
+                    << std::hex
+                    << " / DEST = " << r_dcache_to_cc_test_dest.read()
+                    << " / RESULt = " << r_cc_test_to_dcache_result.read()
+                    << std::dec << std::endl;
+            }
+#endif
+        }
         break;
     }
@@ -5681,4 +5763,13 @@
         {
             ///////////////////////////////////////////////////////
+            // Handle CC_TEST request                            //
+            ///////////////////////////////////////////////////////
+            if (r_cc_test_to_cc_send_req.read())
+            {
+                r_cc_send_fsm = CC_SEND_TEST_HEADER;
+                break;
+            }
+
+            ///////////////////////////////////////////////////////
             // handling round robin between icache and dcache :  //
             // we first check for the last client and listen for //
@@ -5761,4 +5852,29 @@
             break;
         }
+        ///////////////////////////
+        case CC_SEND_TEST_HEADER:
+        {
+            // the r_cc_test_to_cc_send_req can be reset by the CC_TEST FSM
+            // when there is a watchdog timeout
+            if (not r_cc_test_to_cc_send_req.read())
+            {
+                r_cc_send_fsm = CC_SEND_IDLE;
+                break;
+            }
+
+            if (not p_dspin_p2m.read.read()) break;
+            r_cc_send_fsm = CC_SEND_TEST_SIGNATURE;
+            break;
+        }
+        ///////////////////////////
+        case CC_SEND_TEST_SIGNATURE:
+        {
+            // the r_cc_test_to_cc_send_req can be reset by the CC_TEST FSM
+            // when there is a watchdog timeout
+            if (not p_dspin_p2m.read.read() and r_cc_test_to_cc_send_req.read()) break;
+            r_cc_test_to_cc_send_req = false;
+            r_cc_send_fsm = CC_SEND_IDLE;
+            break;
+        }
     } // end switch CC_SEND FSM
 
@@ -5772,4 +5888,5 @@
     // - CC_INST_UPDT  : ICACHE update request (multi-words)
     // - CC_BROADCAST  : Broadcast invalidate request (both DCACHE & ICACHE)
+    // - CC_TEST_M2P   : M2P coherence network test packet
     //////////////////////////////////////////////////////////////////////////////
     switch (r_cc_receive_fsm.read())
@@ -5783,4 +5900,12 @@
                 // initialize dspin received data
                 uint64_t receive_data = p_dspin_m2p.data.read();
+
+                // coherence test packet (CC_TEST_M2P)
+                if (DspinDhccpParam::dspin_get(receive_data, DspinDhccpParam::TEST_M2P_TEST))
+                {
+                    r_cc_receive_fsm = CC_RECEIVE_TEST_HEADER;
+                    break;
+                }
+
                 // initialize coherence packet type
                 uint64_t receive_type = DspinDhccpParam::dspin_get(receive_data,
@@ -5825,7 +5950,4 @@
             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
-            // not to actually post a request to an available cache => need a
-            // flip_flop to check that ?
             if (not (r_cc_receive_icache_req.read()) and
                 not (r_cc_receive_dcache_req.read()) and
@@ -6004,4 +6126,27 @@
             break;
         }
+        //////////////////////////
+        case CC_RECEIVE_TEST_HEADER:
+        {
+            if (not p_dspin_m2p.write.read()) break;
+
+            typedef DspinDhccpParam DDP;
+            uint64_t header = p_dspin_m2p.data.read();
+            uint64_t dest = DDP::dspin_get(header, DDP::TEST_M2P_DEST);
+            assert((size_t)dest == m_cc_global_id);
+
+            r_cc_receive_fsm = CC_RECEIVE_TEST_SIGNATURE;
+            break;
+        }
+        //////////////////////////
+        case CC_RECEIVE_TEST_SIGNATURE:
+        {
+            if (not p_dspin_m2p.write.read()) break;
+            assert(not r_cc_test_m2p_req.read());
+            r_cc_test_m2p_req = true;
+            r_cc_test_m2p_sign = p_dspin_m2p.data.read();
+            r_cc_receive_fsm = CC_RECEIVE_IDLE;
+            break;
+        }
 
     } // end switch CC_RECEIVE FSM
@@ -6017,4 +6162,7 @@
     size_t clack_set = DspinDhccpParam::dspin_get(r_dspin_clack_flit.read(),
                                                    DspinDhccpParam::CLACK_SET);
+
+    size_t clack_test = DspinDhccpParam::dspin_get(r_dspin_clack_flit.read(),
+                                                   DspinDhccpParam::TEST_CLACK_TEST);
 
     bool dspin_clack_get = false;
@@ -6024,6 +6172,24 @@
     if (r_dspin_clack_req.read())
     {
+        // CLACK TEST first flit
+        if (clack_test and not r_dspin_clack_test.read())
+        {
+            r_dspin_clack_test = true;
+            dspin_clack_get = true;
+        }
+
+        // CLACK TEST second flit
+        else if (r_dspin_clack_test.read())
+        {
+            assert (not r_cc_test_clack_req.read());
+            r_cc_test_clack_req = true;
+            r_cc_test_clack_sign = r_dspin_clack_flit.read();
+
+            r_dspin_clack_test = false;
+            dspin_clack_get = true;
+        }
+
         // CLACK DATA: Send request to DCACHE FSM
-        if (dcache_clack_request and not r_dcache_clack_req.read())
+        else if (dcache_clack_request and not r_dcache_clack_req.read())
         {
             r_dcache_clack_req = true;
@@ -6053,4 +6219,55 @@
     }
 
+    ///////////////////////////////////////////////////////////////
+    // CC_TEST FSM
+    ///////////////////////////////////////////////////////////////
+
+    // TODO: implement the watchdog timer (reuse the same that for the DATA UNC
+    // requests?)
+    const bool watchdog_timeout = false;
+
+    switch(r_cc_test_fsm.read())
+    {
+        case CC_TEST_IDLE:
+            if (not r_dcache_to_cc_test_req.read()) break;
+            r_cc_test_to_dcache_result = CC_TEST_SUCCESS;
+            r_cc_test_fsm = CC_TEST_P2M_REQ;
+            break;
+
+        case CC_TEST_P2M_REQ:
+            assert (not r_cc_test_to_cc_send_req.read());
+            r_cc_test_to_cc_send_req = true;
+            r_cc_test_fsm = CC_TEST_P2M_WAIT;
+            break;
+
+        case CC_TEST_P2M_WAIT:
+            if (r_cc_test_to_cc_send_req.read())
+            {
+                if (not watchdog_timeout) break;
+                r_dcache_to_cc_test_req = false;
+                r_cc_test_to_cc_send_req = false;
+                r_cc_test_to_dcache_result = CC_TEST_FAILURE;
+                r_cc_test_fsm = CC_TEST_IDLE;
+                break;
+            }
+            assert (not r_cc_test_clack_req.read() and not r_cc_test_m2p_req.read());
+            r_cc_test_fsm = CC_TEST_ACK_WAIT;
+            break;
+
+        case CC_TEST_ACK_WAIT:
+            if (not r_cc_test_clack_req.read() or not r_cc_test_m2p_req.read())
+            {
+                if (not watchdog_timeout) break;
+                r_cc_test_to_dcache_result = CC_TEST_FAILURE;
+            }
+
+            // TODO: compare signatures from M2P and CLACK with the sent one
+            r_dcache_to_cc_test_req = false;
+            r_cc_test_clack_req = false;
+            r_cc_test_m2p_req = false;
+            r_cc_test_fsm = CC_TEST_IDLE;
+            break;
+    }
+
     ///////////////// Response FIFOs update  //////////////////////
     r_vci_rsp_fifo_icache.update(vci_rsp_fifo_icache_get,
@@ -6063,5 +6280,4 @@
 
     ///////////////// updt FIFO update  //////////////////////
-    //TODO check this
     r_cc_receive_updt_fifo_be.update(cc_receive_updt_fifo_get,
                                  cc_receive_updt_fifo_put,
@@ -6395,4 +6611,37 @@
             break;
         }
+        ///////////////////////
+        case CC_SEND_TEST_HEADER:
+        {
+            typedef DspinDhccpParam DDP;
+            uint64_t flit = 0;
+
+            uint64_t dest = (uint64_t)r_dcache_to_cc_test_dest.read()
+                            << (DspinDhccpParam::GLOBALID_WIDTH - m_x_width - m_y_width);
+
+            DDP::dspin_set(flit, DDP::TYPE_TEST, DDP::P2M_TYPE);
+            DDP::dspin_set(flit, dest, DDP::TEST_P2M_DEST);
+            DDP::dspin_set(flit, m_cc_global_id, DDP::TEST_P2M_SRCID);
+            DDP::dspin_set(flit, 1ULL, DDP::TEST_P2M_TEST);
+
+            p_dspin_p2m.data  = flit;
+            p_dspin_p2m.write = true;
+            p_dspin_p2m.eop   = false;
+            break;
+        }
+        ///////////////////////
+        case CC_SEND_TEST_SIGNATURE:
+        {
+            typedef DspinDhccpParam DDP;
+            uint64_t flit = 0;
+
+            DDP::dspin_set(flit, r_mmu_word_lo.read(), DDP::TEST_P2M_SIGNATURE);
+
+            p_dspin_p2m.data  = flit;
+            p_dspin_p2m.write = true;
+            p_dspin_p2m.eop   = true;
+            break;
+        }
+
     } // end switch CC_SEND FSM
 
@@ -6416,7 +6665,4 @@
         case CC_RECEIVE_BRDCAST_NLINE:
         {
-            // TODO maybe we need to wait for both only to leave the state, but
-            // not to actually post a request to an available cache => need a
-            // flip_flop to check that ?
             if (not (r_cc_receive_icache_req.read()) and not (r_cc_receive_dcache_req.read()))
                 p_dspin_m2p.read = true;
@@ -6481,4 +6727,16 @@
             break;
         }
+        ///////////////////////////////
+        case CC_RECEIVE_TEST_HEADER:
+        {
+            p_dspin_m2p.read = true;
+            break;
+        }
+        ///////////////////////////////
+        case CC_RECEIVE_TEST_SIGNATURE:
+        {
+            p_dspin_m2p.read = true;
+            break;
+        }
     } // end switch CC_RECEIVE FSM
 
@@ -6486,4 +6744,7 @@
     int clack_type = DspinDhccpParam::dspin_get(r_dspin_clack_flit.read(),
                                                 DspinDhccpParam::CLACK_TYPE);
+
+    size_t clack_test = DspinDhccpParam::dspin_get(r_dspin_clack_flit.read(),
+                                                   DspinDhccpParam::TEST_CLACK_TEST);
 
     bool dspin_clack_get = false;
@@ -6493,6 +6754,12 @@
     if (r_dspin_clack_req.read())
     {
+        // CLACK TEST
+        if (clack_test or r_dspin_clack_test.read())
+        {
+            dspin_clack_get = true;
+        }
+
         // CLACK DATA: wait if pending request to DCACHE FSM
-        if (dcache_clack_request and not r_dcache_clack_req.read())
+        else if (dcache_clack_request and not r_dcache_clack_req.read())
         {
             dspin_clack_get = true;
