Index: trunk/modules/vci_cc_xcache_wrapper_v4/caba/source/src/vci_cc_xcache_wrapper_v4.cpp
===================================================================
--- trunk/modules/vci_cc_xcache_wrapper_v4/caba/source/src/vci_cc_xcache_wrapper_v4.cpp	(revision 175)
+++ trunk/modules/vci_cc_xcache_wrapper_v4/caba/source/src/vci_cc_xcache_wrapper_v4.cpp	(revision 188)
@@ -1,3 +1,7 @@
 /* -*- c++ -*-
+ * File         : vci_cc_xcache_wrapper_v4.cpp
+ * Date         : 26/11/2011
+ * Copyright    : UPMC / LIP6
+ * Authors      : Alain Greiner 
  *
  * SOCLIB_LGPL_HEADER_BEGIN
@@ -21,85 +25,24 @@
  * SOCLIB_LGPL_HEADER_END
  *
- * Copyright (c) UPMC, Lip6, SoC
- *         Alain Greiner <alain.greiner@lip6.fr>, 2008
+ * Copyright (c) UPMC, Lip6
+ *         Alain Greiner <alain.greiner@lip6.fr>, 2011
  *
- * Maintainers: alain eric.guthmuller@polytechnique.edu nipo
+ * Maintainers: alain 
  */
 
-/////////////////////////////////////////////////////////////////////////////
-// History
-// - 25/04/2008
-//   The existing vci_xcache component has been extended to include 
-//   a VCI target port to support a directory based coherence protocol.
-//   Two types of packets can be send by the L2 cache to the L1 cache
-//   * INVALIDATE packets : length = 1
-//   * UPDATE packets : length = n + 2   
-//   The CLEANUP packets are sent by the L1 cache to the L2 cache, 
-//   to signal a replaced cache line.
-// - 12/08/2008
-//   The vci_cc_xcache_wrapper component instanciates directly the processsor 
-//   iss, in order to supress the processor/cache interface.
-//   According to the VCI advanced specification, this component uses one 
-//   word VCI CMD packets for MISS transactions, and accept one word VCI RSP
-//   packets for Write burst  transactions.
-//   The write buffer has been modified to use the WriteBuffer object. 
-//   A VCI write burst is constructed when two conditions are satisfied :
-//   The processor make strictly successive write requests, and they are
-//   in the same cache line. The write buffer performs re-ordering, to
-//   respect the contiguous addresses VCI constraint. In case of several
-//   WRITE_WORD requests in the same word, only the last request is conserved.
-//   In case of several WRITE_HALF or WRITE_WORD requests in the same word,
-//   the requests are merged in the same word. In case of uncached write
-//   requests, each request is transmited as a single VCI transaction.
-//   Both the data & instruction caches can be flushed in one single cycle.
-///////////////////////////////////////////////////////////////////////////////
-
-#include <iomanip>
-#include "arithmetics.h"
-#include "size.h"
 #include "../include/vci_cc_xcache_wrapper_v4.h"
-namespace soclib { 
-  namespace caba {
+
+#define DEBUG_GLOBAL		0
+#define DEBUG_DCACHE		0
+#define DEBUG_ICACHE		0
+
+#define DEBUG_START_CYCLE	0
+#define DEBUG_ID		    0
+
+namespace soclib { namespace caba {
+
     namespace {
-
-// =====[ DEBUG ]====================================
-
-#define ASSERT_VERBOSE
-#define ASSERT_NCYCLES m_cpt_total_cycles
-
-#include "debug.h"
-
-#if CC_XCACHE_WRAPPER_DEBUG
-# define PRINTF(msg...) PRINTF_COND(m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN,msg)
-#else
-# define PRINTF(msg...)
-#endif
-
-/////////////////////////////////////////////////////////////////////
-// Management of address stocked in icache/dcache/mwbuf in case
-// of multiple bank implementation 
-/////////////////////////////////////////////////////////////////////
-
-// =====[ MULTI_CACHE ]==============================
-
-#if (CC_XCACHE_WRAPPER_MULTI_CACHE==1)
-# define get_num_icache(     addr,num_cpu)   get_num_cache     (addr)          
-# define get_num_icache_only(addr,num_cpu)   get_num_cache_only(addr)          
-# define set_num_icache(     addr,num_cache) set_num_cache     (addr,num_cache)
-# define set_num_icache_only(addr,num_cache) set_num_cache_only(addr,num_cache)
-#elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2)
-# define get_num_icache(     addr,num_cpu)   num_cpu
-# define get_num_icache_only(addr,num_cpu)   num_cpu
-# define set_num_icache(     addr,num_cache) do  {} while (0)
-# define set_num_icache_only(addr,num_cache) addr
-#else
-#error "Invalid value to CC_XCACHE_WRAPPER_MULTI_CACHE"
-#endif
-# define get_num_dcache(     addr)           get_num_cache     (addr)          
-# define get_num_dcache_only(addr)           get_num_cache_only(addr)          
-# define set_num_dcache(     addr,num_cache) set_num_cache     (addr,num_cache)
-# define set_num_dcache_only(addr,num_cache) set_num_cache_only(addr,num_cache)
-
-      const char *dcache_fsm_state_str[] = {
+      const char *dcache_fsm_state_str[] = 
+      {
         "DCACHE_IDLE",
         "DCACHE_WRITE_UPDT",
@@ -108,13 +51,14 @@
         "DCACHE_MISS_UPDT",
         "DCACHE_UNC_WAIT",
-        "DCACHE_SC_WAIT",
         "DCACHE_INVAL",
+        "DCACHE_INVAL_GO",
         "DCACHE_SYNC",
         "DCACHE_ERROR",
         "DCACHE_CC_CHECK",
         "DCACHE_CC_INVAL",
-        "DCACHE_CC_CLEANUP",
+        "DCACHE_CC_UPDT",
       };
-      const char *icache_fsm_state_str[] = {
+      const char *icache_fsm_state_str[] = 
+      {
         "ICACHE_IDLE",
         "ICACHE_MISS_VICTIM",
@@ -123,9 +67,10 @@
         "ICACHE_UNC_WAIT",
         "ICACHE_ERROR",
-        "ICACHE_CC_CLEANUP",
         "ICACHE_CC_CHECK",
         "ICACHE_CC_INVAL",
+        "ICACHE_CC_UPDT",
       };
-      const char *cmd_fsm_state_str[] = {
+      const char *cmd_fsm_state_str[] = 
+      {
         "CMD_IDLE",
         "CMD_INS_MISS",
@@ -136,5 +81,6 @@
         "CMD_DATA_SC",
       };
-      const char *rsp_fsm_state_str[] = {
+      const char *rsp_fsm_state_str[] = 
+      {
         "RSP_IDLE",
         "RSP_INS_MISS",
@@ -145,5 +91,6 @@
         "RSP_DATA_SC",
       };
-      const char *tgt_fsm_state_str[] = {
+      const char *tgt_fsm_state_str[] = 
+      {
         "TGT_IDLE",
         "TGT_UPDT_WORD",
@@ -157,4403 +104,2584 @@
       };
 
-      const char *cleanup_fsm_state_str[] = {
-        "CLEANUP_IDLE",
-        "CLEANUP_REQ",
-        "CLEANUP_RSP_DCACHE",
-        "CLEANUP_RSP_ICACHE",
+      const char *cleanup_fsm_state_str[] = 
+      {
+        "CLEANUP_DATA_IDLE",
+        "CLEANUP_DATA_GO",
+        "CLEANUP_INS_IDLE",
+        "CLEANUP_INS_GO",
       };
     }
 
-    typedef long long unsigned int blob_t;
-
-#define tmpl(...)  template<typename vci_param, typename iss_t> __VA_ARGS__ VciCcXCacheWrapperV4<vci_param, iss_t>
-
-    using soclib::common::uint32_log2;
-
-    /////////////////////////////////
-    tmpl(/**/)::VciCcXCacheWrapperV4(
-                                     /////////////////////////////////
-                                     sc_module_name name,
-                                     int proc_id,
-                                     const soclib::common::MappingTable &mtp,
-                                     const soclib::common::MappingTable &mtc,
-                                     const soclib::common::IntTab &initiator_index_rw,
-                                     const soclib::common::IntTab &initiator_index_c,
-                                     const soclib::common::IntTab &target_index,
-                                     size_t nb_cpu,
-                                     size_t nb_dcache,
-                                     size_t icache_ways,
-                                     size_t icache_sets,
-                                     size_t icache_words,
-                                     size_t dcache_ways,
-                                     size_t dcache_sets,
-                                     size_t dcache_words,
-                                     size_t wbuf_nwords,
-                                     size_t wbuf_nlines
-                                     )
-               : 
-               soclib::caba::BaseModule(name),
-
-               p_clk       ("clk"),
-               p_resetn    ("resetn"),
-               p_vci_ini_rw("vci_ini_rw"),
-               p_vci_ini_c ("vci_ini_c"),
-               p_vci_tgt   ("vci_tgt"),
-
-               m_cacheability_table(mtp.getCacheabilityTable<vci_addr_t>()),
-               m_segment(mtc.getSegment(target_index)),
-               m_srcid_rw(mtp.indexForId(initiator_index_rw)),
-               m_srcid_c(mtc.indexForId(initiator_index_c)),
-
-               m_nb_cpu(nb_cpu),
-#if   (CC_XCACHE_WRAPPER_MULTI_CACHE==1)
-               m_nb_icache(nb_dcache),
-#elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2)
-               m_nb_icache(m_nb_cpu),
+#define tmpl(...) template<typename vci_param, typename iss_t> __VA_ARGS__ VciCcXCacheWrapperV4<vci_param, iss_t>
+
+using soclib::common::uint32_log2;
+
+/////////////////////////////////
+tmpl(/**/)::VciCcXCacheWrapperV4(
+    sc_module_name                      name,
+    int                                 proc_id,
+    const soclib::common::MappingTable  &mtp,
+    const soclib::common::MappingTable  &mtc,
+    const soclib::common::IntTab        &initiator_index_d,
+    const soclib::common::IntTab        &initiator_index_c,
+    const soclib::common::IntTab        &target_index_c,
+    size_t                              icache_ways,
+    size_t                              icache_sets,
+    size_t                              icache_words,
+    size_t                              dcache_ways,
+    size_t                              dcache_sets,
+    size_t                              dcache_words,
+    size_t                              wbuf_nwords,
+    size_t                              wbuf_nlines,
+    uint32_t				            max_frozen_cycles)
+     : 
+     soclib::caba::BaseModule(name),
+
+     p_clk       ("clk"),
+     p_resetn    ("resetn"),
+     p_vci_ini_d ("vci_ini_d"),
+     p_vci_ini_c ("vci_ini_c"),
+     p_vci_tgt_c ("vci_tgt_c"),
+
+     m_cacheability_table(mtp.getCacheabilityTable<vci_addr_t>()),
+     m_segment(mtc.getSegment(target_index_c)),
+     m_srcid_d(mtp.indexForId(initiator_index_d)),
+     m_srcid_c(mtc.indexForId(initiator_index_c)),
+
+     m_dcache_ways(dcache_ways),
+     m_icache_ways(icache_ways),
+
+     m_cache_words(icache_words),
+     m_cache_words_shift(uint32_log2(icache_words)+uint32_log2(sizeof(data_t))),
+     m_cache_yzmask((~0)<<m_cache_words_shift),
+
+     m_max_frozen_cycles(max_frozen_cycles),
+
+     r_icache_fsm("r_icache_fsm"),
+     r_icache_fsm_save("r_icache_fsm_save"),
+     r_icache_addr_save("r_icache_addr_save"),
+     r_icache_miss_req("r_icache_miss_req"),
+     r_icache_unc_req("r_icache_unc_req"),
+     r_icache_cleanup_req("r_icache_cleanup_req"),
+     r_icache_cleanup_line("r_icache_cleanup_line"),
+     r_icache_cleanup_way("r_icache_cleanup_way"),
+     r_icache_cleanup_set("r_icache_cleanup_set"),
+     r_icache_miss_inval("r_icache_miss_inval"),
+     r_icache_update_word("r_icache_update_word"),
+
+     r_dcache_fsm("r_dcache_fsm"),
+     r_dcache_fsm_save("r_dcache_fsm_save"),
+     r_dcache_addr_save("r_dcache_addr_save"),
+     r_dcache_wdata_save("r_dcache_wdata_save"),
+     r_dcache_be_save("r_dcache_be_save"),
+     r_dcache_way_save("r_dcache_way_save"),
+     r_dcache_set_save("r_dcache_set_save"),
+     r_dcache_word_save("r_dcache_word_save"),
+     r_dcache_cleanup_req("r_dcache_cleanup_req"),
+     r_dcache_cleanup_line("r_dcache_cleanup_line"),
+     r_dcache_cleanup_way("r_dcache_cleanup_way"),
+     r_dcache_cleanup_set("r_dcache_cleanup_set"),
+     r_dcache_miss_req("r_dcache_miss_req"),
+     r_dcache_unc_req("r_dcache_unc_req"),
+     r_dcache_sc_req("r_dcache_sc_req"),
+     r_dcache_miss_inval("r_dcache_miss_inval"),
+     r_dcache_update_word("r_dcache_update_word"),
+     r_dcache_ll_data("r_dcache_ll_data"),
+     r_dcache_ll_addr("r_dcache_ll_addr"),
+     r_dcache_ll_valid("r_dcache_ll_valid"),
+
+     r_vci_cmd_fsm("r_vci_cmd_fsm"),
+     r_vci_cmd_min("r_vci_cmd_min"),
+     r_vci_cmd_max("r_vci_cmd_max"),
+     r_vci_cmd_cpt("r_vci_cmd_cpt"),
+     r_vci_cmd_imiss_prio("r_vci_cmd_imiss_prio"),
+
+     r_vci_rsp_fsm("r_vci_rsp_fsm"),
+     r_vci_rsp_cpt("r_vci_rsp_cpt"),
+     r_vci_rsp_ins_error("r_vci_rsp_ins_error"),
+     r_vci_rsp_data_error("r_vci_rsp_data_error"),
+     r_vci_rsp_fifo_icache("r_vci_rsp_fifo_icache" ,2),     // two words depth
+     r_vci_rsp_fifo_dcache("r_vci_rsp_fifo_dcache" ,2),     // two words depth
+
+     r_tgt_fsm("r_tgt_fsm"),
+     r_tgt_icache_rsp("r_tgt_icache_rsp"),
+     r_tgt_dcache_rsp("r_tgt_dcache_rsp"),
+     r_tgt_addr("r_tgt_daddr"),
+     r_tgt_word_min("r_tgt_word_min"),
+     r_tgt_word_max("r_tgt_word_max"),
+     r_tgt_word_count("r_tgt_word_count"),
+     r_tgt_update("r_tgt_update"),
+     r_tgt_update_data("r_tgt_update_data"),
+     r_tgt_srcid("r_tgt_srcid"),
+     r_tgt_pktid("r_tgt_pktid"),
+     r_tgt_trdid("r_tgt_trdid"),
+     r_tgt_icache_req("r_tgt_icache_req"),
+     r_tgt_dcache_req("r_tgt_dcache_req"),
+
+     r_cleanup_fsm("r_cleanup_fsm"),
+     r_cleanup_trdid("r_cleanup_trdid"),
+     r_cleanup_buffer(16)                   // up to 16 simultaneous cleanup transactions
+{
+    assert( ((icache_words*vci_param::B) < (1<<vci_param::K)) and
+             "Need more PLEN bits.");
+
+    assert( (vci_param::T > 2) and ((1<<(vci_param::T-1)) >= (wbuf_nlines)) and
+             "Need more TRDID bits.");
+
+    assert( (icache_words == dcache_words) and
+             "icache_words must be equal at dcache_words.");
+
+    p_irq  = new sc_in<bool> [iss_t::n_irq];
+
+    r_iss     = new iss_t (this->name() , proc_id);
+    r_icache  = new GenericCache<vci_addr_t>("icache", icache_ways, icache_sets, icache_words);
+    r_dcache  = new GenericCache<vci_addr_t>("dcache", dcache_ways, dcache_sets, dcache_words);
+    r_wbuf    = new MultiWriteBuffer<vci_addr_t>("wbuf", wbuf_nwords, wbuf_nlines, dcache_words);
+                
+    r_tgt_buf = new sc_signal<data_t> [m_cache_words];
+    r_tgt_be  = new sc_signal<be_t>   [m_cache_words];
+
+    m_cpt_fsm_dcache  = new uint32_t [32];
+    m_cpt_fsm_icache  = new uint32_t [32];
+    m_cpt_fsm_cmd     = new uint32_t [32];
+    m_cpt_fsm_rsp     = new uint32_t [32];
+    m_cpt_fsm_tgt     = new uint32_t [32];
+    m_cpt_fsm_cleanup = new uint32_t [32];
+
+    SC_METHOD(transition);
+    dont_initialize();
+    sensitive << p_clk.pos();
+
+    SC_METHOD(genMoore);
+    dont_initialize();
+    sensitive << p_clk.neg();
+
+    typename iss_t::CacheInfo cache_info;
+    cache_info.has_mmu          = false;
+    cache_info.icache_line_size = icache_words*sizeof(data_t);
+    cache_info.icache_assoc     = icache_ways;
+    cache_info.icache_n_lines   = icache_sets;
+    cache_info.dcache_line_size = dcache_words*sizeof(data_t);
+    cache_info.dcache_assoc     = dcache_ways;
+    cache_info.dcache_n_lines   = dcache_sets;
+
+    r_iss->setCacheInfo(cache_info);
+    
+} // end constructor
+
+///////////////////////////////////
+tmpl(/**/)::~VciCcXCacheWrapperV4()
+{
+    delete r_icache ;
+    delete r_wbuf   ;
+    delete r_dcache ;
+    delete r_iss;
+    delete [] p_irq;
+    delete [] r_tgt_buf;
+    delete [] r_tgt_be;
+}
+
+////////////////////////
+tmpl(void)::print_cpi()
+{
+    std::cout << "CPU " << m_srcid_d << " : CPI = " 
+              << (float)m_cpt_total_cycles/(m_cpt_total_cycles - m_cpt_frz_cycles) 
+              << std::endl ;
+}
+
+/*
+
+////////////////////////////////////////////////////////
+tmpl(void)::print_stats(bool print_wbuf, bool print_fsm)
+{
+    std::cout << "------------------------------------" << std:: dec << std::endl;
+    std::cout << "CPU " << m_srcid_d << " / Time = " << m_cpt_total_cycles << std::endl;
+
+    float run_cycles = (float)(m_cpt_total_cycles - m_cpt_frz_cycles);
+
+    std::cout << "- CPI                            : " 
+              << (float)m_cpt_total_cycles/run_cycles << std::endl ;
+
+    std::cout << "- CACHABLE INSTRUCTIONS          : " 
+              << m_cpt_ins_cacheable << std::endl ;
+
+    std::cout << "- INSTRUCTION CACHE MISS RATE    : "
+              << (float)m_cpt_ins_miss*100.0/(float)m_cpt_ins_cacheable 
+              << " %" << std::endl ;
+
+    std::cout << "- NON CACHABLE INSTRUCTIONS      : " 
+              << m_cpt_ins_uncacheable << std::endl ;
+
+    std::cout << "- CACHABLE DATA READ             : " 
+              << m_cpt_data_read_cacheable << std::endl;
+
+    std::cout << "- DATA CACHE MISS RATE           : "
+              << (float)m_cpt_data_read_miss*100.0/(float)m_cpt_data_read_cacheable 
+              << " %" << std::endl;
+
+    std::cout << "- CACHABLE DATA WRITE            : " 
+              << m_cpt_data_write_cacheable << std::endl ;
+
+    std::cout << "- CACHED WRITE RATE              : "
+              << (float)m_cpt_data_write_hit*100.0/(float)m_cpt_data_write_cacheable 
+              << " %" << std::endl;
+
+    std::cout << "- NON CACHABLE DATA READ         : " 
+              << m_cpt_data_read_uncacheable << std::endl;
+
+    std::cout << "- NON CACHABLE DATA WRITE        : " 
+              << m_cpt_data_write_uncacheable << std::endl;
+
+    std::cout << "- WRITE RATE                     : " 
+              << (float)m_cpt_data_write_cacheable*100.0/(float)m_cpt_ins_cacheable
+              << " %" << std::endl;
+
+    std::cout << "- READ RATE                      : " 
+              << (float)m_cpt_data_read_cacheable*100.0/(float)m_cpt_ins_cacheable
+              << " %" << std::endl;
+
+    std::cout << "- AVERAGE INSTRUCTION MISS COST  : " 
+              << (float)m_cost_ins_miss_frz/(float)m_cpt_ins_miss << std::endl;
+
+    std::cout << "- AVERAGE DATA MISS COST         : " 
+              << (float)m_cost_data_miss_frz/m_cpt_data_read_miss << std::endl;
+
+    std::cout << "- AVERAGE WRITE COST             : " 
+              << (float)m_cost_write_frz/m_cpt_data_write_cacheable << std::endl;
+
+    std::cout << "- CC_UPDATE_ICACHE               : " 
+              << m_cpt_cc_update_icache  << std::endl;
+
+    std::cout << "- CC_UPDATE_DCACHE               : " 
+              << m_cpt_cc_update_dcache  << std::endl;
+
+    std::cout << "- CC_INVAL_ICACHE                : " 
+              << m_cpt_cc_inval_icache << std::endl;
+
+    std::cout << "- CC_INVAL_ICACHE                : " 
+              << m_cpt_cc_inval_icache << std::endl;
+
+    std::cout << "-CC_BROADCAST                    : " 
+              << m_cpt_cc_inval_broadcast << std::endl;
+
+//  this part is removed because soclib::common::size() not found ...
+
+    if (print_fsm)
+    {
+        std::cout << "- DCACHE FSM" << std::endl;
+        for (uint32_t i=0; i<soclib::common::size(dcache_fsm_state_str ); ++i)
+            std::cout << "  + "  << dcache_fsm_state_str[i] << " : "
+                      << m_cpt_fsm_dcache [i] << std::endl; 
+
+        std::cout << "- ICACHE FSM" << std::endl;
+        for (uint32_t i=0; i<soclib::common::size(icache_fsm_state_str ); ++i)
+            std::cout << "  + "  << icache_fsm_state_str[i] << " : "
+                      << m_cpt_fsm_icache [i] << std::endl; 
+
+        std::cout << "- CMD FSM" << std::endl;
+        for (uint32_t i=0; i<soclib::common::size(cmd_fsm_state_str ); ++i)
+            std::cout << "  + " << cmd_fsm_state_str[i] << " : " 
+                      << m_cpt_fsm_cmd [i] << std::endl;
+
+        std::cout << "- RSP FSM" << std::endl;
+        for (uint32_t i=0; i<soclib::common::size(rsp_fsm_state_str ); ++i)
+            std::cout << "  + " << rsp_fsm_state_str[i] << " : "
+                      << m_cpt_fsm_rsp [i] << std::endl;
+
+        std::cout << "- TGT FSM" << std::endl;
+        for (uint32_t i=0; i<soclib::common::size(tgt_fsm_state_str ); ++i)
+            std::cout << "  + "  << tgt_fsm_state_str[i] << " : " 
+                      << m_cpt_fsm_tgt [i] << std::endl;
+
+        std::cout << "- CLEANUP FSM" << std::endl;
+        for (uint32_t i=0; i<soclib::common::size(cleanup_fsm_state_str ); ++i)
+            std::cout << "  + "  << cleanup_fsm_state_str[i] << " : " 
+                      << m_cpt_fsm_cleanup [i] << std::endl;
+    }
+
+    if (print_wbuf) r_wbuf->printStatistics();
+}
+
+*/
+////////////////////////////////////
+tmpl(void)::print_trace(size_t mode)
+{
+    // b0 : write buffer print trace
+    // b1 : write buffer verbose
+    // b2 : dcache print trace
+    // b3 : icache print trace
+
+    typename iss_t::InstructionRequest  ireq;
+    typename iss_t::InstructionResponse irsp;
+    typename iss_t::DataRequest         dreq;
+    typename iss_t::DataResponse        drsp;
+
+    ireq.valid       = m_ireq_valid;
+    ireq.addr        = m_ireq_addr;
+    ireq.mode        = m_ireq_mode;
+
+    irsp.valid       = m_irsp_valid;
+    irsp.instruction = m_irsp_instruction;
+    irsp.error       = m_irsp_error;
+
+    dreq.valid       = m_dreq_valid;
+    dreq.addr        = m_dreq_addr;
+    dreq.mode        = m_dreq_mode;
+    dreq.type        = m_dreq_type;
+    dreq.wdata       = m_dreq_wdata;
+    dreq.be          = m_dreq_be;
+
+    drsp.valid       = m_drsp_valid;
+    drsp.rdata       = m_drsp_rdata;
+    drsp.error       = m_drsp_error;
+
+    std::cout << std::dec << "Proc " << name() << std::endl;
+
+    std::cout << "  " << ireq << std::endl;
+    std::cout << "  " << irsp << std::endl;
+    std::cout << "  " << dreq << std::endl;
+    std::cout << "  " << drsp << std::endl;
+ 
+    std::cout << "  " << icache_fsm_state_str[r_icache_fsm.read()]
+              << " | " << dcache_fsm_state_str[r_dcache_fsm.read()]
+              << " | " << cmd_fsm_state_str[r_vci_cmd_fsm.read()]
+              << " | " << rsp_fsm_state_str[r_vci_rsp_fsm.read()]
+              << " | " << tgt_fsm_state_str[r_tgt_fsm.read()]
+              << " | " << cleanup_fsm_state_str[r_cleanup_fsm.read()] << std::endl;
+
+    if(mode & 0x1)
+    {
+        std::cout << "  Write Buffer" << std::endl;
+        r_wbuf->printTrace((mode>>1)&1);
+    }
+    if(mode & 0x4)
+    {
+        std::cout << "  Data cache" << std::endl;
+        r_dcache->printTrace();
+    }
+    if(mode & 0x8)
+    {
+        std::cout << "  Instruction cache" << std::endl;
+        r_icache->printTrace();
+    }
+}
+
+//////////////////////////
+tmpl(void)::transition()
+//////////////////////////
+{
+    // Reset
+    if ( not p_resetn.read() ) 
+    {
+        // iss, write buffer & caches
+        r_iss->reset();
+        r_wbuf->reset();
+        r_dcache->reset();
+        r_icache->reset();
+        r_cleanup_buffer.reset();
+
+        // FSM states
+        r_icache_fsm                = ICACHE_IDLE;
+        r_dcache_fsm                = DCACHE_IDLE;
+        r_vci_cmd_fsm               = CMD_IDLE;
+        r_vci_rsp_fsm               = RSP_IDLE;
+        r_tgt_fsm                   = TGT_IDLE;
+        r_cleanup_fsm               = CLEANUP_DATA_IDLE;
+
+        // synchronisation flip-flops between TGT FSM and ICACHE/DCACHE FSMs
+        r_tgt_icache_req            = false;
+        r_tgt_dcache_req            = false;
+
+        // synchronisation flip-flops between ICACHE/DCACHE FSMs and CLEANUP FSM
+        r_icache_cleanup_req        = false;
+        r_dcache_cleanup_req        = false;
+
+        // synchronisation flip-flops between ICACHE FSMs and VCI FSMs
+        r_icache_miss_req           = false;
+        r_icache_unc_req            = false;
+        r_icache_miss_inval         = false;
+        r_vci_rsp_ins_error         = false;
+
+        // synchronisation flip-flops between DCACHE FSMs and VCI FSMs
+        r_dcache_miss_req           = false;
+        r_dcache_unc_req            = false;
+        r_dcache_sc_req             = false;
+        r_dcache_miss_inval         = false;
+        r_vci_rsp_data_error        = false;
+
+        // pending non cacheable write
+        r_dcache_pending_unc_write  = false;
+
+        // linked load reservation flip-flop
+        r_dcache_ll_valid           = false;
+
+        // uncacheable read buffers
+        r_icache_unc_valid          = false;
+        r_dcache_unc_valid          = false;
+
+        // response FIFOs 
+        r_vci_rsp_fifo_icache.init();
+        r_vci_rsp_fifo_dcache.init();
+      
+        // activity counters (consommation)
+        m_conso_dcache_data_read     = 0;
+        m_conso_dcache_data_write    = 0;
+        m_conso_dcache_dir_read      = 0;
+        m_conso_dcache_dir_write     = 0;
+
+        m_conso_icache_data_read     = 0;
+        m_conso_icache_data_write    = 0;
+        m_conso_icache_dir_read      = 0;
+        m_conso_icache_dir_write     = 0;
+
+        m_conso_wbuf_read            = 0;
+        m_conso_wbuf_write           = 0;
+
+        // coherence request counters
+        m_cpt_cc_update_icache       = 0;
+        m_cpt_cc_update_dcache       = 0;
+        m_cpt_cc_inval_icache        = 0;
+        m_cpt_cc_inval_dcache        = 0;
+        m_cpt_cc_inval_broadcast     = 0;
+
+        // CPI computation
+        m_cpt_frz_cycles             = 0;
+        m_cpt_total_cycles           = 0;
+        m_cpt_stop_simulation        = 0;
+
+        // number of executed instructions
+        m_cpt_ins_cacheable          = 0;
+        m_cpt_ins_uncacheable        = 0;
+        m_cpt_ins_miss               = 0;
+
+        // number of data requests
+        m_cpt_data_read_cacheable    = 0;
+        m_cpt_data_read_miss         = 0;
+        m_cpt_data_read_uncacheable  = 0;
+        m_cpt_data_write_cacheable   = 0;
+        m_cpt_data_write_uncacheable = 0;
+        m_cpt_data_write_hit         = 0;
+        m_cpt_data_ll                = 0;
+        m_cpt_data_sc                = 0;
+
+        // number of external register requests
+        m_cpt_xtn_dcache_inval       = 0;
+        m_cpt_xtn_sync               = 0;
+
+        // cumulated cost (frozen cycles) for write and miss
+        m_cost_write_frz             = 0;
+        m_cost_data_miss_frz         = 0;
+        m_cost_ins_miss_frz          = 0;
+
+        m_cpt_imiss_transaction      = 0;
+        m_cpt_dmiss_transaction      = 0;
+        m_cpt_iunc_transaction       = 0;
+        m_cpt_dunc_transaction       = 0;
+        m_cpt_write_transaction      = 0;
+        m_cpt_sc_transaction         = 0;
+
+        m_cost_imiss_transaction    = 0;
+        m_cost_dmiss_transaction    = 0;
+        m_cost_unc_transaction      = 0;
+        m_cost_write_transaction    = 0;
+        m_length_write_transaction  = 0;
+
+        for (uint32_t i=0; i<32 ; ++i) 
+            m_cpt_fsm_icache  [i]   = 0;
+        for (uint32_t i=0; i<32 ; ++i) 
+            m_cpt_fsm_dcache  [i]   = 0;
+        for (uint32_t i=0; i<32 ; ++i) 
+            m_cpt_fsm_cmd     [i]   = 0;
+        for (uint32_t i=0; i<32 ; ++i) 
+            m_cpt_fsm_rsp     [i]   = 0;
+        for (uint32_t i=0; i<32 ; ++i) 
+            m_cpt_fsm_tgt     [i]   = 0;
+        for (uint32_t i=0; i<32 ; ++i) 
+            m_cpt_fsm_cleanup [i]   = 0;
+
+        return; 
+    }
+
+    // Response FIFOs default values
+    bool     vci_rsp_fifo_icache_get       = false;
+    bool     vci_rsp_fifo_icache_put       = false;
+    data_t   vci_rsp_fifo_icache_data      = 0;
+
+    bool     vci_rsp_fifo_dcache_get       = false;
+    bool     vci_rsp_fifo_dcache_put       = false;
+    data_t   vci_rsp_fifo_dcache_data      = 0;
+
+    // FSMs activity
+    m_cpt_fsm_dcache  [r_dcache_fsm.read() ] ++;
+    m_cpt_fsm_icache  [r_icache_fsm.read() ] ++;
+    m_cpt_fsm_cmd     [r_vci_cmd_fsm.read()] ++;
+    m_cpt_fsm_rsp     [r_vci_rsp_fsm.read()] ++;
+    m_cpt_fsm_tgt     [r_tgt_fsm.read()    ] ++;
+    m_cpt_fsm_cleanup [r_cleanup_fsm.read()] ++;
+
+    m_cpt_total_cycles++;
+
+    //////////////////////////////////////////////////////////////////////////////
+    // The TGT_FSM receives the coherence requests.
+    // It controls the following ressources:
+    // - r_tgt_fsm
+    // - r_tgt_buf[nwords]
+    // - r_tgt_be[nwords]
+    // - r_tgt_update
+    // - r_tgt_word_min
+    // - r_tgt_word_max
+    // - r_tgt_word_count
+    // - r_tgt_addr
+    // - r_tgt_srcid
+    // - r_tgt_trdid
+    // - r_tgt_pktid
+    // - r_tgt_icache_req (set)
+    // - r_tgt_dcache_req (set)
+    //
+    // All VCI commands must be CMD_WRITE.
+    // - If the 2 LSB bits of the VCI address are 11, it is a broadcast request.
+    //   It is a multicast request otherwise.
+    // - For multicast requests, the ADDRESS[2] bit distinguishes DATA/INS
+    //   (0 for data / 1 for instruction), and the ADDRESS[3] bit distinguishes
+    //   INVAL/UPDATE (0 for invalidate / 1 for UPDATE).
+    //
+    // For all types of coherence resqests, the line index (i.e. the Z & Y fields) 
+    // is coded on 34 bits, and is contained in the WDATA and BE fields 
+    // of the first VCI flit.
+    // -  for a multicast invalidate or for a broadcast invalidate request
+    //    the VCI packet length is 1 word. 
+    // -  for an update request the VCI packet length is (n+2) words.
+    //    The WDATA field of the second VCI word contains the word index.
+    //    The WDATA field of the n following words contains the values.
+    // -  for all transaction types, the VCI response is one single word.
+    // In case of errors in the VCI command packet, the simulation
+    // is stopped with an error message.
+    //
+    // This FSM is NOT pipelined : It consumes a new request on the VCI port
+    // only when the previous request is completed.
+    //
+    // The VCI_TGT FSM stores the external request arguments in the
+    // IDLE, UPDT_WORD & UPDT_DATA states. It sets the r_tgt_icache_req 
+    // and/or the r_tgt_dcache_req flip-flops to signal the coherence request 
+    // to the ICACHE & DCACHE FSMs in the REQ_ICACHE, REQ_DCACHE & REQ_BROADCAST
+    // states. It waits the completion of the coherence request  by polling the
+    // r_tgt_*cache_req flip-flops in the RSP_ICACHE, RSP_DCACHE & RSP_BROADCAST
+    // states. These flip-flops are reset by the ICACHE_FSM and/or DCACHE_FSM. 
+    // These two FSMs signal if a VCI answer must be send by setting
+    // the r_tgt_icache_rsp and/or the r_tgt_dcache_rsp flip_flops.
+    ///////////////////////////////////////////////////////////////////////////////
+
+    switch( r_tgt_fsm.read() ) 
+    {
+        //////////////
+        case TGT_IDLE:
+        {
+            vci_addr_t tgt_addr; 
+            
+            if ( p_vci_tgt_c.cmdval.read() ) 
+            {
+                vci_addr_t address = p_vci_tgt_c.address.read();
+
+                if ( p_vci_tgt_c.cmd.read() != vci_param::CMD_WRITE) 
+                {
+                    std::cout << "error in component VCI_CC_XCACHE_WRAPPER " 
+                              << name() << std::endl;
+                    std::cout << "coherence request is not a write" 
+                              << std::endl;
+                    exit(0);
+                }
+
+                // address checking for multi-update or multi-invalidate 
+                if ( ((address&0x3) != 0x3) and (not m_segment.contains(address)) ) 
+                {
+                    std::cout << "error in component VCI_CC_XCACHE_WRAPPER "
+                              << name() << std::endl;
+                    std::cout << "out of segment coherence request"
+                              << std::endl;
+                    exit(0);
+                }
+            
+                // address of the target cache line = nline * m_cache_words * 4
+                tgt_addr  = (vci_addr_t)(((((uint64_t)p_vci_tgt_c.be.read() & 0x3) << 32) | 
+                                  (uint64_t)p_vci_tgt_c.wdata.read() ) << m_cache_words_shift);
+
+                r_tgt_srcid    	= p_vci_tgt_c.srcid.read();
+                r_tgt_trdid    	= p_vci_tgt_c.trdid.read();
+                r_tgt_pktid    	= p_vci_tgt_c.pktid.read();
+                r_tgt_addr 	= tgt_addr;             // target line (for *CACHE FSMs)
+                    
+                if ( (address&0x3) == 0x3 )   // broadcast invalidate 
+                {
+                    if ( not p_vci_tgt_c.eop.read() ) 
+                    {
+                        std::cout << "error in component VCI_CC_XCACHE_WRAPPER " 
+                                  << name() << std::endl;
+                        std::cout << "the BROADCAST INVALIDATE command length must be one word"
+                                  << std::endl;
+                        exit(0);
+                    }
+                    r_tgt_update = false; 
+                    r_tgt_fsm = TGT_REQ_BROADCAST;
+
+                    m_cpt_cc_inval_broadcast++ ;
+                }
+                else                    // multi-update or multi-invalidate
+                { 
+                    uint32_t cell = address - m_segment.baseAddress(); 
+                    if (cell == 0)                           // invalidate data
+                    {
+                        if ( not p_vci_tgt_c.eop.read() ) 
+                        {
+                            std::cout << "error in component VCI_CC_XCACHE_WRAPPER " 
+                                      << name() << std::endl;
+                            std::cout << "the MULTI-INVALIDATE command length must be one word"
+                                      << std::endl;
+                            exit(0);
+                        }
+                        r_tgt_update 		= false; 
+                        r_tgt_fsm 		= TGT_REQ_DCACHE;
+
+                        m_cpt_cc_inval_dcache++ ;
+                    } 
+                    else if (cell == 4)                     // invalidate instruction
+                    {                         
+                        if ( not p_vci_tgt_c.eop.read() ) 
+                        {
+                            std::cout << "error in component VCI_CC_VCACHE_WRAPPER " 
+                                      << name() << std::endl;
+                            std::cout << "the MULTI-INVALIDATE command length must be one word"
+                                      << std::endl;
+                            exit(0);
+                        }
+                        r_tgt_update 		= false; 
+                        r_tgt_fsm 		= TGT_REQ_ICACHE;
+
+                        m_cpt_cc_inval_icache++ ;
+                    } 
+                    else if (cell == 8)    			// update data 
+                    {                                
+                        if ( p_vci_tgt_c.eop.read() ) 
+                        {
+                            std::cout << "error in component VCI_CC_VCACHE_WRAPPER " 
+                                      << name() << std::endl;
+                            std::cout << "the MULTI-UPDATE command length must be N+2 words" 
+                                      << std::endl;
+                            exit(0);
+                        }
+                        r_tgt_update      	= true;
+                        r_tgt_update_data 	= true;
+                        r_tgt_fsm 		= TGT_UPDT_WORD;
+
+                        m_cpt_cc_update_dcache++;
+                    }
+                    else					// update instruction
+                    {
+
+
+                        if ( p_vci_tgt_c.eop.read() ) 
+                        {
+                            std::cout << "error in component VCI_CC_VCACHE_WRAPPER " 
+                                      << name() << std::endl;
+                            std::cout << "the MULTI-UPDATE command length must be N+2 words" 
+                                      << std::endl;
+                            exit(0);
+                        }
+                        r_tgt_update      	= true;
+                        r_tgt_update_data 	= false;
+                        r_tgt_fsm 		= TGT_UPDT_WORD;
+
+                        m_cpt_cc_update_icache++;
+                    }
+                } // end if multi
+            } // end if cmdval
+            break;
+        }
+        //////////////////
+        case TGT_UPDT_WORD:	 // first word index acquisition fo update requests
+
+        {
+            if (p_vci_tgt_c.cmdval.read()) 
+            {
+                if ( p_vci_tgt_c.eop.read() ) 
+                {
+                    std::cout << "error in component VCI_CC_XCACHE_WRAPPER " 
+                              << name() << std::endl;
+                    std::cout << "the MULTI-UPDATE command length must be N+2 words" 
+                              << std::endl;
+                    exit(0);
+                }
+
+                for ( size_t i=0 ; i<m_cache_words ; i++ ) r_tgt_be[i] = 0;
+
+                r_tgt_word_min   = p_vci_tgt_c.wdata.read();  // first modified word 
+                r_tgt_word_count = p_vci_tgt_c.wdata.read();  // initializes the word counter
+                r_tgt_fsm   = TGT_UPDT_DATA;
+            }
+            break;
+        }
+        ///////////////////
+        case TGT_UPDT_DATA:  // data acquisition for update requests
+        {
+            if (p_vci_tgt_c.cmdval.read()) 
+            {
+                size_t word = r_tgt_word_count.read();
+                if ( word >= m_cache_words ) 
+                {
+                    std::cout << "error in component VCI_CC_XCACHE_WRAPPER " 
+                              << name() << std::endl;
+                    std::cout << "the reveived MULTI-UPDATE command length is wrong" 
+                              << std::endl;
+                    exit(0);
+                }
+
+                r_tgt_buf[word] = p_vci_tgt_c.wdata.read();
+                r_tgt_be [word] = p_vci_tgt_c.be.read();
+
+                r_tgt_word_count = word + 1;
+                if (p_vci_tgt_c.eop.read())  // last word 
+                {
+                    r_tgt_word_max = word;          // last modified word 
+              	    if(r_tgt_update_data.read()) 	r_tgt_fsm = TGT_REQ_DCACHE;
+                    else 			        r_tgt_fsm = TGT_REQ_ICACHE;
+                }
+            }
+            break;
+        }
+        ///////////////////////
+        case TGT_REQ_BROADCAST: // set the requests (if no previous request pending)
+        {
+            if (not r_tgt_icache_req.read() and not r_tgt_dcache_req.read()) 
+            {
+                r_tgt_fsm = TGT_RSP_BROADCAST; 
+                r_tgt_icache_req = true;
+                r_tgt_dcache_req = true;
+            }
+            break;
+        }
+        ////////////////////
+        case TGT_REQ_ICACHE: // set the request (if no previous request pending)
+        {
+            if ( not r_tgt_icache_req.read() ) 
+            {
+                r_tgt_fsm = TGT_RSP_ICACHE; 
+                r_tgt_icache_req = true;
+            }
+            break;
+        }
+        ////////////////////
+        case TGT_REQ_DCACHE: // set the request (if no previous request pending)
+        {
+            if ( not r_tgt_dcache_req.read() ) 
+            {
+                r_tgt_fsm = TGT_RSP_DCACHE; 
+                r_tgt_dcache_req = true;
+            }
+            break;
+        }
+        ///////////////////////
+        case TGT_RSP_BROADCAST:  // waiting acknowlege from both dcache fsm and icache fsm
+                                 // no VCI response when the r_tgt_*cache_rsp flip_flop is false
+        {
+            if ( not r_tgt_icache_req.read() and not r_tgt_dcache_req.read() )
+            {
+                if ( r_tgt_icache_rsp.read() or r_tgt_dcache_rsp.read() )  // at least one response
+                {
+                    if ( p_vci_tgt_c.rspack.read())
+                    {
+                        // reset dcache first if activated
+                        if (r_tgt_dcache_rsp) 	r_tgt_dcache_rsp = false;
+                        else 		        r_tgt_icache_rsp = false;
+                    }
+                }
+                else
+                {
+                    r_tgt_fsm = TGT_IDLE;
+                }
+            }
+            break;
+        }
+        ////////////////////
+        case TGT_RSP_ICACHE:  // waiting acknowledge from the icache fsm
+        {
+            // no VCI response when the r_tgt_icache_rsp flip_flop is false
+            if ( not r_tgt_icache_req.read() and p_vci_tgt_c.rspack.read() )
+            {
+                r_tgt_fsm = TGT_IDLE;
+                r_tgt_icache_rsp = false; 
+            }
+            break;
+        }
+        ////////////////////
+        case TGT_RSP_DCACHE:  // waiting acknowledge from the dcache fsm
+        {
+            // no VCI response when the r_tgt_dcache_rsp flip_flop is false
+            if ( not r_tgt_dcache_req.read() and p_vci_tgt_c.rspack.read() )
+            {
+                r_tgt_fsm = TGT_IDLE;
+                r_tgt_dcache_rsp = false; 
+            }
+            break;
+        }
+    } // end switch TGT_FSM
+
+    /////////////////////////////////////////////////////////////////////
+    // Get data and instruction requests from processor
+    ///////////////////////////////////////////////////////////////////////
+
+    typename iss_t::InstructionRequest  ireq = ISS_IREQ_INITIALIZER;
+    typename iss_t::DataRequest         dreq = ISS_DREQ_INITIALIZER;
+
+    r_iss->getRequests(ireq, dreq);
+
+    ///////////////////////////////////////////////////////////////////////////////
+    // The ICACHE FSM controls the following ressources:
+    // - r_icache_fsm
+    // - r_icache_fsm_save
+    // - r_icache_addr_save
+    // - r_icache_miss_req (set)
+    // - r_icache_unc_req (set)
+    // - r_icache_cleanup_req (set)
+    // - r_icache_cleanup_line
+    // - r_icache_cleanup_set
+    // - r_icache_cleanup_way
+    // - r_icache_miss_inval
+    // - r_icache (instruction cache access)
+    // - r_vci_rsp_ins_error (reset)
+    // - r_tgt_icache_req (reset)
+    // - r_tgt_icache_rsp
+    // - ireq & irsp structures for communication with the processor
+    //
+    // 1/ Coherence requests (update or invalidate) have highest priority.
+    //    They are taken into account in IDLE, UNC_WAIT, and MISS_WAIT states.
+    //    In case of coherence request the ICACHE FSM goes to the CC_CHECK
+    //    state to test the cache hit, and then to the CC_INVAL or
+    //    CC_UPDATE states to execute the request. It reset the r_tgt_icache_req 
+    //    flip_flop to signal completion, writes in the r_tgt_icache_rsp
+    //    to allow the VCI response, and returns in the pre-empted state.
+    //    
+    // 2/ Processor requests are taken into account only in the IDLE state.
+    //    In case of miss, or in case of uncached instruction, the FSM 
+    //    writes the missing address line in the r_icache_addr_save register 
+    //    and sets the r_icache_miss_req or the r_icache_unc_req flip-flops.
+    //    These request flip-flops are reset by the VCI_RSP FSM
+    //    when the VCI transaction is completed.
+    //
+    // 3/ In case of uncacheable instruction, the VCI_RSP FSM writes the
+    //    requested instruction in the r_icache_unc_buf register, and
+    //    sets the r_icache_unc_valid flip_flop. This flip_flop is reset
+    //    by the ICACHE FSM.
+    //
+    // 4/ In case of bus error, the VCI_RSP FSM sets the r_vci_rsp_ins_error 
+    //    flip-flop, and does not write any data in the response FIFO.
+    //    The r_vci_rsp_ins_error flip-flop is reset by the ICACHE FSM.
+    ////////////////////////////////////////////////////////////////////////////////
+        
+    // The default value for irsp.valid is false
+    typename iss_t::InstructionResponse irsp = ISS_IRSP_INITIALIZER;
+
+    switch( r_icache_fsm.read() ) 
+    {
+        /////////////////
+        case ICACHE_IDLE:
+        {
+            if ( r_tgt_icache_req.read() )    // coherence request
+            {
+                r_icache_fsm = ICACHE_CC_CHECK;
+                r_icache_fsm_save = r_icache_fsm.read();
+                break;
+            } 
+            if ( ireq.valid )  // processor request
+            {
+                bool     cacheable = m_cacheability_table[ireq.addr];
+                vci_addr_t addr     = (vci_addr_t)ireq.addr;
+
+                if ( cacheable )	 // cacheable
+                {
+                    data_t   inst;
+                    bool     hit = r_icache->read(addr, &inst);
+                    m_conso_icache_dir_read++;
+                    m_conso_icache_data_read++;
+                    if ( !hit )     // cacheable miss
+                    {
+                        // in order to avoid a dead-lock with the mem_cache
+                        // (in case of simultaneous broadcast for example),
+                        // we check that the previous cleanup request is completed
+                        // and the ICACHE FSM is blocked in IDLE state until completion
+                        if ( not r_icache_cleanup_req.read() )
+                        {
+                            r_icache_fsm       = ICACHE_MISS_VICTIM;
+                            r_icache_miss_req  = true;
+                            r_icache_addr_save = addr;
+                            m_cpt_ins_miss++;
+                            m_cost_ins_miss_frz++;
+                        }
+                    }
+                    else            // cacheable hit
+                    {
+                        irsp.valid          = true;
+                        irsp.instruction    = inst;
+                        m_cpt_ins_cacheable++;
+                    }
+                } 
+                else 		    // non cacheable
+                {
+                    if ( r_icache_unc_valid.read() and (addr == r_icache_addr_save.read()) )
+                    {
+                        r_icache_unc_valid  = false;
+                        irsp.valid          = true;
+                        irsp.instruction    = r_icache_unc_buf.read();
+                        m_cpt_ins_uncacheable++;
+                    }
+                    else
+                    {
+                        r_icache_unc_valid  = false;
+                        r_icache_fsm       = ICACHE_UNC_WAIT;
+                        r_icache_unc_req   = true;
+                        r_icache_addr_save = addr;
+                    }
+                }
+            }
+            break;
+        }
+        ////////////////////////
+        case ICACHE_MISS_VICTIM:           // Selects (and invalidates) a victim line
+        {                                  // Set the r_icache_cleanup_req flip-flop 
+                                           // when the selected slot is not empty
+            m_cost_ins_miss_frz++;
+
+            size_t       way;
+            size_t       set;
+            vci_addr_t   victim;
+                        
+            r_icache_cleanup_req  = r_icache->victim_select( r_icache_addr_save.read(), 
+                                                             &victim, 
+                                                             &way, 
+                                                             &set );
+            r_icache_cleanup_line = victim;
+            r_icache_cleanup_way  = way;
+            r_icache_cleanup_set  = set;
+            r_icache_fsm = ICACHE_MISS_WAIT;
+            break;
+        }
+        //////////////////////
+        case ICACHE_MISS_WAIT:            // waiting the response to a miss request
+        {                                 // to test a bus error
+            m_cost_ins_miss_frz++;
+
+            if ( r_tgt_icache_req.read() )    // coherence request
+            {
+                r_icache_fsm      = ICACHE_CC_CHECK;
+                r_icache_fsm_save = r_icache_fsm.read();
+                break;
+            }
+
+            if ( r_vci_rsp_ins_error.read() ) 
+            {
+                r_icache_fsm = ICACHE_ERROR;
+            } 
+            else if ( r_vci_rsp_fifo_icache.rok() )
+            {
+                r_icache_update_word = 0;
+                r_icache_fsm = ICACHE_MISS_UPDT;
+            }
+            break;
+        }
+        //////////////////////
+        case ICACHE_MISS_UPDT:          // Update the cache (one word per cycle) 
+        {
+            m_cost_ins_miss_frz++;
+            if ( r_vci_rsp_fifo_icache.rok() )
+            {
+                size_t      word = r_icache_update_word.read();
+                vci_addr_t  addr = r_icache_addr_save.read();
+                size_t      way  = r_icache_cleanup_way.read();
+                size_t      set  = r_icache_cleanup_set.read();
+
+                m_conso_icache_data_write++;
+                // if the pending miss is cancelled by a matching coherence request
+                // we pop the FIFO, but we don't update the cache
+                if ( not r_icache_miss_inval.read() )
+                      r_icache->write( way, 
+                                       set, 
+                                       word, 
+                                       r_vci_rsp_fifo_icache.read() );
+
+                vci_rsp_fifo_icache_get = true;
+                r_icache_update_word = word+1;
+
+                // if last word, finish the update
+                if ( word == m_cache_words-1 )
+                {
+                    if ( not r_icache_miss_inval.read() )
+                    {
+                        m_conso_icache_dir_write++;
+                        r_icache->victim_update_tag(addr, way, set);
+                    }
+                    r_icache_miss_inval = false;
+                    r_icache_fsm = ICACHE_IDLE;
+                }
+            }
+            break;
+        }
+        /////////////////////
+        case ICACHE_UNC_WAIT:           // waiting the response to an uncached request
+        {
+            if ( r_tgt_icache_req.read() )   // coherence request
+            {
+                r_icache_fsm      = ICACHE_CC_CHECK;
+                r_icache_fsm_save = r_icache_fsm.read();
+                break;
+            }
+            if ( r_vci_rsp_ins_error ) 	
+            {
+                r_icache_fsm = ICACHE_ERROR;
+            }
+            else if ( r_vci_rsp_fifo_icache.rok() )
+            {
+                vci_rsp_fifo_icache_get = true;
+                r_icache_unc_buf        = r_vci_rsp_fifo_icache.read();
+                r_icache_unc_valid      = true;                
+                r_icache_fsm            = ICACHE_IDLE;
+            }
+            break;
+        }
+        //////////////////
+        case ICACHE_ERROR:
+        {
+            irsp.error          = true;
+            irsp.valid          = true;
+            r_icache_fsm        = ICACHE_IDLE;
+            r_vci_rsp_ins_error = false;
+            break;
+        }
+        /////////////////////
+        case ICACHE_CC_CHECK:   // check directory in case of coherence request
+        {
+            vci_addr_t 	addr = r_tgt_addr.read();
+            vci_addr_t 	mask = ~((m_cache_words<<2)-1);
+
+            if( (r_icache_fsm_save.read() == ICACHE_MISS_WAIT) and 
+                ((r_icache_addr_save.read() & mask) == (addr & mask))) 
+                // The coherence request matches a pending miss
+            {
+                r_icache_miss_inval = true;
+                r_tgt_icache_req    = false;
+                r_tgt_icache_rsp    = r_tgt_update.read();
+                r_icache_fsm        = r_icache_fsm_save.read();  
+            } 
+            else  // no match for a pending miss
+            {
+                size_t way;
+                size_t set;
+                size_t word;
+                bool   hit = r_icache->hit(addr, 
+                                           &way, 
+                                           &set, 
+                                           &word);
+                r_icache_cc_way = way;
+                r_icache_cc_set = set;
+
+                m_conso_icache_dir_read++;
+
+                if ( hit and r_tgt_update.read() )           // hit update
+                {
+                      r_icache_fsm         = ICACHE_CC_UPDT;
+                      r_icache_update_word = r_tgt_word_min.read();
+                } 
+                else if ( hit and not r_tgt_update.read() )  // hit inval
+                {
+                    r_icache_fsm = ICACHE_CC_INVAL;
+                } 
+                else  				                        // miss can happen
+                {
+                    r_tgt_icache_req = false;
+                    r_tgt_icache_rsp = r_tgt_update.read(); 
+                    r_icache_fsm     = r_icache_fsm_save.read();
+                }
+            }
+            break;
+        }
+        /////////////////////
+        case ICACHE_CC_INVAL:  
+        {                      
+              vci_addr_t nline; 
+              r_icache->inval( r_icache_cc_way.read(),
+                               r_icache_cc_way.read(),
+                               &nline );
+              r_tgt_icache_req = false;
+              r_tgt_icache_rsp = true;
+              r_icache_fsm     = r_icache_fsm_save.read();
+              break;
+        }    
+        /////////////////////
+        case ICACHE_CC_UPDT:
+        {                       
+            size_t  word = r_icache_update_word.read();
+            r_icache->write( r_icache_cc_way.read(),
+                             r_icache_cc_set.read(),
+                             word,
+                             r_tgt_buf[word].read(),
+                             r_tgt_be[word].read() );
+            r_icache_update_word = word+1;
+
+            if ( word == r_tgt_word_max.read() )  // last word
+            {
+                r_tgt_icache_req = false;
+                r_tgt_icache_rsp = true;
+                r_icache_fsm     = r_icache_fsm_save.read();
+            }
+            break;
+        }    
+    } // end switch r_icache_fsm
+
+    // save the IREQ and IRSP fields for the print_trace() function
+    m_ireq_valid        = ireq.valid;
+    m_ireq_addr         = ireq.addr;
+    m_ireq_mode         = ireq.mode;
+    
+    m_irsp_valid        = irsp.valid;
+    m_irsp_instruction  = irsp.instruction;
+    m_irsp_error        = irsp.error;
+
+    //////////////////////////////////////////////////////////////////////://///////////
+    // The DCACHE FSM controls the following ressources:
+    // - r_dcache_fsm
+    // - r_dcache_fsm_save
+    // - r_dcache (data cache access)
+    // - r_dcache_addr_save
+    // - r_dcache_wdata_save
+    // - r_dcache_be_save
+    // - r_dcache_way_save
+    // - r_dcache_set_save
+    // - r_dcache_word_save
+    // - r_dcache_miss_req (set)
+    // - r_dcache_unc_req (set)
+    // - r_dcache_sc_req (set)
+    // - r_dcache_cleanup_req (set)
+    // - r_vci_rsp_data_error (reset)
+    // - r_tgt_dcache_req (reset)
+    // - r_wbuf write
+    // - drsp structure 
+    //
+    // 1/ Coherence requests : 
+    //    There is a coherence request when the tgt_dcache_req flip-flop is set,
+    //    requesting a line invalidation or a line update. 
+    //    Coherence requests are taken into account in IDLE, UNC_WAIT, MISS_WAIT states, 
+    //    and have the highest priority.
+    //    The actions associated to the pre-empted state are not executed, the DCACHE FSM
+    //    goes to the CC_CHECK state to execute the requested action, and returns to the
+    //    pre-empted state.
+    //
+    // 2/ processor requests : 
+    //    Processor READ requests are taken into account in IDLE state only.
+    //    In order to support WRITE bursts, write requests are taken into account 
+    //    in the WRITE_UPDT state as well as in the IDLE state.
+    //    - The processor read requests cannot be satisfied if
+    //    there is a cached read miss, or an uncached read.
+    //    - The processor write requests cannot be satisfied when the write buffer is full.
+    //
+    // 3/ Atomic instructions LL/SC
+    //    The reservation registers (r_dcache_ll_valid, r_dcache_ll_addr and
+    //    r_dcache_ll_data are stored in the L1 cache controller, and not in the 
+    //    memory controller. 
+    //    - LL requests from the processor and are transmitted as standard 
+    //      VCI read transactions (one word / one line, depending on the cacheability).
+    //    - SC requests from the processor are systematically transmitted to the 
+    //      memory cache as compare&swap requests (both the data value stored in the
+    //      r_dcache_ll_data register and the new value). 
+    //    The LL/SC address can be cacheable or not cacheable.
+    //
+    // 4/ Non cacheable access
+    //    This component implement a strong order between non cacheable access
+    //    (read or write) : A new non cacheable VCI transaction starts only when
+    //    the previous non cacheable transaction is completed. Both cacheable and
+    //    non cacheable transactions use the write buffer, but the DCACHE FSM registers
+    //    a non cacheable write transaction posted in the write buffer by setting the
+    //    r_dcache_pending_unc_write flip_flop. All other non cacheable requests
+    //    are stalled until this flip-flop is reset by the VCI_RSP_FSM (when the 
+    //    pending non cacheable write transaction completes).
+    //
+    // 5/ Error handling :  Read Bus Errors are synchronous events, but
+    //    Write Bus Errors are asynchronous events (processor is not frozen).
+    //    - If a Read Bus Error is detected, the VCI_RSP FSM sets the
+    //      r_vci_rsp_data_error flip-flop, without writing any data in the
+    //      r_vci_rsp_fifo_dcache FIFO, and the synchronous error is signaled
+    //      by the DCACHE FSM.
+    //    - If a Write Bus Error is detected, the VCI_RSP FSM  signals
+    //      the asynchronous error using the setWriteBerr() method.
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    // The default value for drsp.valid is false
+    typename iss_t::DataResponse  drsp = ISS_DRSP_INITIALIZER;
+
+    switch ( r_dcache_fsm.read() ) 
+    {
+        /////////////////
+        case DCACHE_IDLE:       // waiting requests from processor
+        {
+            if ( r_tgt_dcache_req.read() )  // coherence request
+            { 
+                r_dcache_fsm      = DCACHE_CC_CHECK;
+                r_dcache_fsm_save = r_dcache_fsm.read();
+                break;
+            } 
+            if ( dreq.valid )  // processor request
+            {
+                bool     	cacheable      = m_cacheability_table[dreq.addr];
+                vci_addr_t	addr          = (vci_addr_t)dreq.addr;
+
+                switch( dreq.type ) 
+                {
+                    case iss_t::DATA_LL:
+                    case iss_t::DATA_READ:
+                    {
+                        if ( cacheable )	// cacheable read   
+                        {
+                            data_t   rdata;
+                            bool     hit = r_dcache->read(addr, &rdata);
+                            m_conso_dcache_dir_read++;
+                            m_conso_dcache_data_read++;
+                            if ( !hit )         // cacheable read miss
+                            {
+                                // in order to avoid a dead-lock with the mem_cache
+                                // (in case of simultaneous broadcast for example),
+                                // we check that the previous cleanup request is completed
+                                // if not the DCACHE_FSM is blocked in IDLE state until completion
+                                if ( not r_dcache_cleanup_req.read() )
+                                {
+                                    r_dcache_fsm       = DCACHE_MISS_VICTIM;
+                                    r_dcache_miss_req  = true;
+                                    r_dcache_addr_save = addr;
+                                    m_cpt_data_read_miss++;
+                                    m_cost_data_miss_frz++;
+                                }
+                            }
+                            else                // cacheable read hit
+                            {
+                                m_cpt_data_read_cacheable++;
+                                drsp.valid   = true;
+                                drsp.rdata   = rdata;
+
+                                // makes reservation in case of LL
+                                if( dreq.type == iss_t::DATA_LL )
+                                {
+                                    m_cpt_data_ll++;
+                                    r_dcache_ll_valid = true;
+                                    r_dcache_ll_data  = rdata;
+                                    r_dcache_ll_addr  = addr;
+                                }
+                            }
+                        }
+                        else            // non cacheable read   
+                        {
+                            // non cacheable accesses must be strongly ordered
+                            // A non cacheable read must be delayed if there is 
+                            // a pending uncacheable write in the write buffer 
+                            if ( not r_dcache_pending_unc_write.read() )
+                            {
+                                if ( r_dcache_unc_valid.read() and 			// hit
+                                           (addr == r_dcache_addr_save.read()) )
+                                {
+                                    r_dcache_unc_valid = false;
+                                    drsp.valid         = true;
+                                    drsp.rdata         = r_dcache_unc_buf.read();
+                                    m_cpt_data_read_uncacheable++;
+
+                                    // makes reservation in case of uncacheable LL
+                                    if( dreq.type == iss_t::DATA_LL )
+                                    {
+                                        m_cpt_data_ll++;
+                                        r_dcache_ll_valid = true;
+                                        r_dcache_ll_data  = r_dcache_unc_buf.read();
+                                        r_dcache_ll_addr  = addr;
+                                    }
+                                }
+                                else							// miss
+                                {
+                                    r_dcache_unc_valid = false;
+                                    r_dcache_unc_req   = true;
+                                    r_dcache_fsm       = DCACHE_UNC_WAIT;
+                                    r_dcache_addr_save = addr;
+                                }
+                            } // end if pending_unc_write
+                        }                        
+                        break;
+                    }
+                    case iss_t::DATA_SC:
+                    {
+                        // - if a previous LL (with the same address) is registered, 
+                        // we makes a SC transaction, that will store the response
+                        // in the r_dcache_unc_buf register (0 if success).
+                        // As for the non cacheable read, we must test the 
+                        // r_dcache_unc_valid flip-flop to detect the SC completion,
+                        // return the value stored in r_dcache_unc_buf, and invalidate
+                        // the LL reservation.
+                        // - if there is no registerd LL, we just stay in IDLE state 
+                        // and return 1 (atomic access failed)
+
+                        if( r_dcache_ll_valid.read() and (r_dcache_ll_addr.read() == addr))
+                        {
+                            if ( r_dcache_unc_valid.read() and 		// SC done
+                                    (addr == r_dcache_addr_save.read()) )
+                            {
+                                r_dcache_ll_valid  = false;
+                                r_dcache_unc_valid = false;
+                                drsp.valid         = true;
+                                drsp.rdata         = r_dcache_unc_buf.read();
+                                m_cpt_data_sc++;
+                            }
+                            else					// SC to be done
+                            {
+                                r_dcache_sc_req     = true;
+                                r_dcache_fsm        = DCACHE_UNC_WAIT;
+                                r_dcache_addr_save  = addr;
+                                r_dcache_wdata_save = dreq.wdata;
+                            }
+                        } 
+                        else 					// no registered LL
+                        {
+                            drsp.valid = true;
+                            drsp.rdata = 1; 
+                            r_dcache_ll_valid = false;
+                        }
+                        break;
+                    }
+                    case iss_t::XTN_READ:
+                    case iss_t::XTN_WRITE:
+                    {
+                        // only DCACHE INVALIDATE and SYNC requests are supported
+                        if ( dreq.addr>>2 == iss_t::XTN_DCACHE_INVAL ) 
+                        {
+                            m_cpt_xtn_dcache_inval++;
+                            r_dcache_fsm        = DCACHE_INVAL;
+                            r_dcache_wdata_save = dreq.wdata;
+                        } 
+                        else if ( dreq.addr>>2 == iss_t::XTN_SYNC )
+                        {
+                            m_cpt_xtn_sync++;
+                            // Test if write buffer is already empty
+                            if ( r_wbuf->empty() )
+                            {
+                                drsp.valid = true;
+                                r_dcache_fsm  = DCACHE_IDLE;
+                            }
+                            else
+                            {
+                                r_dcache_fsm  = DCACHE_SYNC;
+                            }
+                        }
+                        else
+                        {
+                            std::cout << "Warning in VCI_CC_XCACHE_WRAPPER " 
+                                      << name() << std::endl;
+                            std::cout << "Unsupported  external access : " 
+                                      << (dreq.addr>>2) << std::endl;
+                            drsp.valid = true;
+                            r_dcache_fsm  = DCACHE_IDLE;
+                        }
+                        break;
+                    }
+                    case iss_t::DATA_WRITE:
+                    {
+                        if ( cacheable )     // cacheable write
+                        {
+                            bool    hit;
+                            size_t  way		= 0;
+                            size_t  set		= 0;
+                            size_t  word	= 0;
+
+                            m_conso_dcache_dir_read++;
+                            hit = r_dcache->hit(addr, &way, &set, &word);
+                            m_conso_wbuf_write++;
+                            bool wok = r_wbuf->write(addr, dreq.be, dreq.wdata, cacheable);
+                            if ( wok )
+                            {
+                                m_cpt_data_write_cacheable++;
+                                drsp.valid = true;
+                                if (hit)    // cached write
+                                {
+                                    m_cpt_data_write_hit++;
+                                    r_dcache_fsm          = DCACHE_WRITE_UPDT; 
+                                    r_dcache_addr_save    = addr;
+                                    r_dcache_wdata_save   = dreq.wdata;
+                                    r_dcache_be_save      = dreq.be;
+                                    r_dcache_way_save     = way;
+                                    r_dcache_set_save     = set;
+                                    r_dcache_word_save    = word;
+                                }
+                                else	  // non cached
+                                {
+                                    r_dcache_fsm = DCACHE_IDLE;
+                                }
+                            }
+                            else  // write miss into write buffer
+                            {
+                                r_dcache_fsm = DCACHE_IDLE;
+                                m_cost_write_frz++;
+                            }
+                        }
+                        else                // non cacheable write 
+                        {
+                            // non cacheable accesses must be strongly ordered
+                            // A non cacahble write must be delayed if there is 
+                            // a pending uncacheable write in the write buffer 
+                            if ( not r_dcache_pending_unc_write.read() )
+                            {
+                                m_conso_wbuf_write++;
+                                bool wok = r_wbuf->write(addr, dreq.be, dreq.wdata, cacheable);
+                                if ( wok ) 
+                                {
+                                    m_cpt_data_write_uncacheable++;
+                                    drsp.valid = true;
+                                }
+                            }
+                            r_dcache_fsm = DCACHE_IDLE;
+                        }
+
+                        break;
+                    }
+                }   // end switch dreq.type
+            }   // end if dreq.valid
+            break;
+        }
+        ///////////////////////
+        case DCACHE_WRITE_UPDT:
+        {
+            // cache update (address, data & be from the previous cycle)
+            m_conso_dcache_data_write++;
+            r_dcache->write( r_dcache_way_save.read(),         
+                             r_dcache_set_save.read(),        
+                             r_dcache_word_save.read(),
+                             r_dcache_wdata_save.read(),  
+                             r_dcache_be_save.read() );  
+
+#if DEBUG_DCACHE
+if ( (m_cpt_total_cycles > DEBUG_START_CYCLE) and (m_srcid_d == DEBUG_ID) )
+{
+    std::cout << "  <PROC.DCACHE_WRITE_UPDT> Writing one word :" << std::hex
+              << " data = " << r_dcache_wdata_save.read()
+              << " / be = " << r_dcache_be_save.read()
+              << " / way = " << r_dcache_way_save.read()
+              << " / set = " << r_dcache_set_save.read()
+              << " / word = " << r_dcache_word_save.read() << std::endl;
+}
 #endif
-               m_nb_dcache(nb_dcache),
-               m_nb_cache((m_nb_dcache>m_nb_icache)?m_nb_dcache:m_nb_icache),
-               m_dcache_ways(dcache_ways),
-               m_dcache_words(dcache_words),
-               m_dcache_words_shift(uint32_log2(dcache_words)+uint32_log2(sizeof(data_t))),
-               m_dcache_yzmask((~0)<<m_dcache_words_shift),
-               m_icache_ways(icache_ways),
-               m_icache_words(icache_words),
-               m_icache_words_shift(uint32_log2(icache_words)+uint32_log2(sizeof(data_t))),
-               m_icache_yzmask((~0)<<m_icache_words_shift),
-               m_cache_words((dcache_words)?dcache_words:icache_words),
-
-               r_cpu_prior("r_cpu_prior"),
-
-               r_vci_cmd_fsm("r_vci_cmd_fsm"),
-               r_vci_cmd_min("r_vci_cmd_min"),
-               r_vci_cmd_max("r_vci_cmd_max"),
-               r_vci_cmd_cpt("r_vci_cmd_cpt"),
-               r_vci_cmd_dcache_prior("r_vci_cmd_dcache_prior"),
-               r_vci_cmd_num_icache_prior("r_vci_cmd_num_icache_prior"),
-               r_vci_cmd_num_dcache_prior("r_vci_cmd_num_dcache_prior"),
-               r_vci_cmd_num_cache("r_vci_cmd_num_cache"),
-
-               r_vci_rsp_fsm("r_vci_rsp_fsm"),
-               r_vci_rsp_cpt("r_vci_rsp_cpt"),
-               r_vci_rsp_num_cache("r_vci_rsp_num_cache"),
-
-               r_vci_rsp_fifo_icache_data      ("r_vci_rsp_fifo_icache_data"     ,2),
-               r_vci_rsp_fifo_icache_num_cache ("r_vci_rsp_fifo_icache_num_cache",2),
-               r_vci_rsp_fifo_dcache_data      ("r_vci_rsp_fifo_dcache_data"     ,2),
-               r_vci_rsp_fifo_dcache_num_cache ("r_vci_rsp_fifo_dcache_num_cache",2),
-
-               r_cache_word("r_cache_word"),
-
-               r_vci_tgt_fsm("r_vci_tgt_fsm"),
-               r_tgt_iaddr("r_tgt_iaddr"),
-               r_tgt_daddr("r_tgt_daddr"),
-               r_tgt_word("r_tgt_word"),
-               r_tgt_update("r_tgt_update"),
-               r_tgt_update_data("r_tgt_update_data"),
-               // r_tgt_brdcast("r_tgt_brdcast"),
-               r_tgt_srcid("r_tgt_srcid"),
-               r_tgt_pktid("r_tgt_pktid"),
-               r_tgt_trdid("r_tgt_trdid"),
-               // r_tgt_plen("r_tgt_plen"),
-               r_tgt_num_cache("r_tgt_num_cache"),
-
-               r_cleanup_fsm("r_cleanup_fsm"),
-               r_cleanup_num_cache("r_cleanup_num_cache"),
-               r_cleanup_icache("r_cleanup_icache"),
-
-               m_num_cache_LSB(uint32_log2(icache_words) + uint32_log2(sizeof(data_t))),
-               m_num_cache_MSB(uint32_log2(nb_dcache) + m_num_cache_LSB)
+
+            // possible write after write
+            if ( dreq.valid and (dreq.type == iss_t::DATA_WRITE) )
+            {
+                bool     cacheable = m_cacheability_table[dreq.addr];
+                vci_addr_t addr     = (vci_addr_t)dreq.addr;
+
+                if ( cacheable ) // cacheable write
+                {
+                    bool    hit;
+                    size_t  way  = 0;
+                    size_t  set  = 0;
+                    size_t  word = 0;
+
+                    m_conso_dcache_dir_read++;
+                    hit = r_dcache->hit(addr, &way, &set, &word);
+                    m_conso_wbuf_write++;
+                    bool wok = r_wbuf->write(addr, dreq.be, dreq.wdata, cacheable);
+                    if (wok)   
+                    {
+                        m_cpt_data_write_cacheable++;
+                        drsp.valid = true;
+                        if (hit)        // cached write
+                        {
+                            m_cpt_data_write_hit++;
+                            r_dcache_fsm          = DCACHE_WRITE_UPDT; 
+                            r_dcache_addr_save    = addr;
+                            r_dcache_wdata_save   = dreq.wdata;
+                            r_dcache_be_save      = dreq.be;
+                            r_dcache_way_save     = way;
+                            r_dcache_set_save     = set;
+                            r_dcache_word_save    = word;
+                        }
+                        else   // uncached write
+                        {
+                            r_dcache_fsm = DCACHE_IDLE;
+                        }
+                    }
+                    else   // write miss into write buffer
+                    {
+                        m_cost_write_frz++;
+                        r_dcache_fsm = DCACHE_IDLE;
+                    }
+                }
+                else  // non cacheable write
+                {
+                    // non cacheable accesses must be strongly ordered 
+                    // A non cacahble write must be delayed if there is 
+                    // a pending uncacheable write in the write buffer 
+                    if ( not r_dcache_pending_unc_write.read() )
+                    {
+                        m_conso_wbuf_write++;
+                        bool wok = r_wbuf->write(addr, dreq.be, dreq.wdata, cacheable);
+                        if ( wok ) 
+                        {
+                            m_cpt_data_write_uncacheable++;
+                            drsp.valid = true;
+                        }
+                    }
+                    r_dcache_fsm = DCACHE_IDLE;
+                }
+            }
+            else    // no valid write request
+            {
+                r_dcache_fsm = DCACHE_IDLE;
+            }
+            break;
+        }
+        ////////////////////////
+        case DCACHE_MISS_VICTIM:           // Selects (and invalidates) a victim line
+        {                                  // Set the r_dcache_cleanup_req flip-flop 
+                                           // when the selected slot is not empty
+            m_cost_data_miss_frz++;
+
+            size_t     way;
+            size_t     set;
+            vci_addr_t   addr = r_dcache_addr_save.read();
+            vci_addr_t   victim;
+                        
+            bool cleanup_requested = r_dcache->victim_select( addr, &victim, &way, &set );
+
+            r_dcache_cleanup_line = victim;
+            r_dcache_cleanup_way  = way;
+            r_dcache_cleanup_set  = set;
+            r_dcache_cleanup_req  = cleanup_requested;
+            r_dcache_fsm = DCACHE_MISS_WAIT;
+            break;
+        }
+        //////////////////////
+        case DCACHE_MISS_WAIT:          // Waiting the response to a miss request
+        {                               // to test a bus error
+            m_cost_data_miss_frz++;
+
+            if ( r_tgt_dcache_req.read() )    // coherence request
+            {
+                r_dcache_fsm      = DCACHE_CC_CHECK;
+                r_dcache_fsm_save = r_dcache_fsm.read();
+                break;
+            }
+
+            if ( r_vci_rsp_data_error.read() ) 
+            {
+                r_dcache_fsm = DCACHE_ERROR;
+            } 
+            else if ( r_vci_rsp_fifo_dcache.rok() )
+            {
+                r_dcache_update_word = 0;
+                r_dcache_fsm = DCACHE_MISS_UPDT;
+            }
+            break;
+        }
+        //////////////////////
+        case DCACHE_MISS_UPDT:      // Update the cache (one word per cycle)
+        {
+            m_cost_data_miss_frz++;
+
+            size_t       word = r_dcache_update_word.read();
+            vci_addr_t   addr = r_dcache_addr_save.read();
+            size_t       way  = r_dcache_cleanup_way.read();
+            size_t       set  = r_dcache_cleanup_set.read();
+                    
+            if ( r_vci_rsp_fifo_dcache.rok() )
+            {
+                if ( not r_dcache_miss_inval.read() )  // no matching coherence request
+                {
+                    m_conso_dcache_data_write++;
+                    r_dcache->write( way, 
+                                     set, 
+                                     word, 
+                                     r_vci_rsp_fifo_dcache.read() );
+
+                    if ( word == m_cache_words-1 )	// last word
+                    {
+                        m_conso_dcache_dir_write++;
+                        r_dcache->victim_update_tag(addr, way, set);
+                        r_dcache_fsm = DCACHE_IDLE;
+                    }
+                    vci_rsp_fifo_dcache_get = true;
+                    r_dcache_update_word = word+1;
+                }
+                else	// if there is a matching coherence request :
+                        // we pop the response FIFO, but we don't update the cache
+                        // when we receive the last word, we send a cleanup for the
+                        // missing line and return to the IDLE state
+                {
+                    if ( word < m_cache_words-1 ) 
+                    {
+                        vci_rsp_fifo_dcache_get = true;
+                        r_dcache_update_word = word+1;
+                    }
+                    else	// last word
+                    {
+                        if ( not r_dcache_cleanup_req )
+                        {
+                            vci_rsp_fifo_dcache_get = true;
+                            r_dcache_cleanup_req  = true;
+                            r_dcache_cleanup_line = r_dcache_addr_save.read() >> m_cache_words_shift;
+                            r_dcache_miss_inval    = false;
+                            r_dcache_fsm          = DCACHE_IDLE;
+                        }
+                    }
+                }
+
+#if DEBUG_DCACHE
+if ( (m_cpt_total_cycles > DEBUG_START_CYCLE) and (m_srcid_d == DEBUG_ID) )
+{
+    if ( r_dcache_miss_inval.read() )
     {
-      // Size of word is 32 bits
-      ASSERT((icache_words*vci_param::B) < (1<<vci_param::K),
-             "Need more PLEN bits.");
-
-      ASSERT((vci_param::T > 2) and ((1<<(vci_param::T-1)) >= (wbuf_nlines/m_nb_dcache)),
-             "Need more TRDID bits.");
-
-      ASSERT(uint32_log2(nb_dcache) <= (1<<vci_param::P),
-             "Need more PKTID bits.");
-                
-      ASSERT(IS_POW_OF_2(m_nb_dcache),
-             "nb_dcache must be a power of 2.");
-
-      ASSERT(IS_POW_OF_2(m_nb_cpu) and (m_nb_cpu <= m_nb_dcache) and (m_nb_cpu > 0),
-             "nb cpu must be a multiple of nb cache.");
-
-      ASSERT(IS_POW_OF_2(m_icache_ways) and (m_nb_icache <= m_icache_ways),
-             "nb icache ways must be a multiple of nb cache.");
-
-      ASSERT(IS_POW_OF_2(m_dcache_ways) and (m_nb_dcache <= m_dcache_ways),
-             "nb dcache ways must be a multiple of nb cache.");
-
-      ASSERT(icache_words == dcache_words,
-             "icache_words must be equal at dcache_words.");
-
-      ASSERT(IS_POW_OF_2(wbuf_nlines) and (m_nb_dcache <= wbuf_nlines),
-             "wbuf_nlines must be a multiple of nb cache.");
-
-      // FIXME : s'adapter à la taille des requêtes XTN_READ/XTN_WRITE, car le type est fournit dans le champs l'adresse
-      ASSERT((m_nb_dcache == 1) or (dcache_words >= 16),
-             "When multi cache is activated, need 4 bits (16 word) to the cache set .");
-
-      if (m_nb_cpu > 1)
-        ASSERT(CC_XCACHE_MULTI_CPU!=0,
-               "Macro CC_XCACHE_MULTI_CPU in wbuf must be set at 1.");
-
-      p_irq = new sc_in<bool> * [m_nb_cpu];
-      for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
-        p_irq [num_cpu] = new sc_in<bool> [iss_t::n_irq];
-
-      m_iss = new iss_t * [m_nb_cpu];
-      for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
-        {
-          std::ostringstream iss_name("");
-          iss_name << this->name() << "_" << num_cpu;
-
-          m_iss[num_cpu] = new iss_t (iss_name.str().c_str(), proc_id+num_cpu);
-        }
-                
-      r_icache_lock          = new sc_signal<uint32_t>[m_nb_icache];
-      r_dcache_lock          = new sc_signal<uint32_t>[m_nb_dcache];
-      r_dcache_sync          = new sc_signal<bool>    [m_nb_dcache];
-
-      r_icache_fsm           = new sc_signal<int>     [m_nb_icache];
-      r_icache_fsm_save      = new sc_signal<int>     [m_nb_icache];
-      r_icache_addr_save     = new sc_signal<addr_40> [m_nb_icache];
-      r_icache_miss_req      = new sc_signal<bool>    [m_nb_icache];
-      r_icache_miss_way      = new sc_signal<size_t>  [m_nb_icache];
-      r_icache_miss_set      = new sc_signal<size_t>  [m_nb_icache];
-      r_icache_unc_req       = new sc_signal<bool>    [m_nb_icache];
-      r_icache_cleanup_req   = new sc_signal<bool>    [m_nb_icache];
-      r_icache_cleanup_line  = new sc_signal<addr_40> [m_nb_icache];
-      r_icache_inval_rsp     = new sc_signal<bool>    [m_nb_icache];
-      r_icache_update_addr   = new sc_signal<size_t>  [m_nb_icache];
-      r_icache_buf_unc_valid = new sc_signal<bool>    [m_nb_icache];
-
-      r_dcache_fsm           = new sc_signal<int>     [m_nb_dcache];
-      r_dcache_fsm_save      = new sc_signal<int>     [m_nb_dcache];
-      r_dcache_addr_save     = new sc_signal<addr_40> [m_nb_dcache];
-      r_dcache_wdata_save    = new sc_signal<data_t>  [m_nb_dcache];
-      r_dcache_rdata_save    = new sc_signal<data_t>  [m_nb_dcache];
-      r_dcache_type_save     = new sc_signal<int>     [m_nb_dcache];
-      r_dcache_be_save       = new sc_signal<be_t>    [m_nb_dcache];
-      r_dcache_cached_save   = new sc_signal<bool>    [m_nb_dcache];
-      r_dcache_num_cpu_save  = new sc_signal<uint32_t>[m_nb_dcache];
-      r_dcache_cleanup_req   = new sc_signal<bool>    [m_nb_dcache];
-      r_dcache_cleanup_line  = new sc_signal<addr_40> [m_nb_dcache];
-      r_dcache_miss_req      = new sc_signal<bool>    [m_nb_dcache];
-      r_dcache_miss_way      = new sc_signal<size_t>  [m_nb_dcache];
-      r_dcache_miss_set      = new sc_signal<size_t>  [m_nb_dcache];
-      r_dcache_unc_req       = new sc_signal<bool>    [m_nb_dcache];
-      r_dcache_sc_req        = new sc_signal<bool>    [m_nb_dcache];
-      r_dcache_inval_rsp     = new sc_signal<bool>    [m_nb_dcache];
-      r_dcache_update_addr   = new sc_signal<size_t>  [m_nb_dcache];
-      r_dcache_previous_unc  = new sc_signal<bool>    [m_nb_dcache];
-
-      r_dcache_ll_data       = new sc_signal<data_t>   * [m_nb_dcache];
-      r_dcache_ll_addr       = new sc_signal<addr_40>  * [m_nb_dcache];
-      r_dcache_ll_valid      = new sc_signal<bool>     * [m_nb_dcache];
-      for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
-        {
-          r_dcache_ll_data    [num_cache] = new sc_signal<data_t>   [m_nb_cpu];
-          r_dcache_ll_addr    [num_cache] = new sc_signal<addr_40>  [m_nb_cpu];
-          r_dcache_ll_valid   [num_cache] = new sc_signal<bool>     [m_nb_cpu];
-        }
-
-      r_tgt_icache_req       = new sc_signal<bool>    [m_nb_icache];
-      r_tgt_icache_rsp       = new sc_signal<bool>    [m_nb_icache];
-      r_tgt_dcache_req       = new sc_signal<bool>    [m_nb_dcache];
-      r_tgt_dcache_rsp       = new sc_signal<bool>    [m_nb_dcache];
-
-      r_tgt_buf              = new data_t             [m_cache_words];
-      r_tgt_be               = new be_t               [m_cache_words];
-
-      r_vci_rsp_ins_error    = new sc_signal<bool>    [m_nb_icache];
-      r_vci_rsp_data_error   = new sc_signal<bool>    [m_nb_dcache];
-
-      ireq                   = new typename iss_t::InstructionRequest  [m_nb_icache];
-      irsp                   = new typename iss_t::InstructionResponse [m_nb_icache];
-      ireq_cached            = new bool                                [m_nb_icache];
-      ireq_num_cpu           = new uint32_t                            [m_nb_dcache];
-
-      dreq                   = new typename iss_t::DataRequest         [m_nb_dcache];
-      drsp                   = new typename iss_t::DataResponse        [m_nb_dcache];
-      dreq_cached            = new bool                                [m_nb_dcache];
-      dreq_num_cpu           = new uint32_t                            [m_nb_dcache];
-
-      m_cpt_icache_access         = new uint32_t [m_nb_icache];
-      m_cpt_dcache_access         = new uint32_t [m_nb_dcache];
-      m_cpt_icache_miss_victim_wait = new uint32_t [m_nb_icache];
-      m_cpt_dcache_miss_victim_wait = new uint32_t [m_nb_dcache];
-
-      m_cpt_dcache_store_after_store    = new uint32_t [m_nb_dcache];
-      m_cpt_dcache_hit_after_miss_read  = new uint32_t [m_nb_dcache];
-      m_cpt_dcache_hit_after_miss_write = new uint32_t [m_nb_dcache];
-               
-      m_cpt_fsm_dcache  = new uint32_t * [m_nb_dcache];
-      m_cpt_fsm_icache  = new uint32_t * [m_nb_icache];
-      for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
-        m_cpt_fsm_dcache[num_cache]  = new uint32_t [soclib::common::size(dcache_fsm_state_str )];
-      for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
-        m_cpt_fsm_icache[num_cache]  = new uint32_t [soclib::common::size(icache_fsm_state_str )];
-      m_cpt_fsm_cmd     = new uint32_t [soclib::common::size(cmd_fsm_state_str    )];
-      m_cpt_fsm_rsp     = new uint32_t [soclib::common::size(rsp_fsm_state_str    )];
-      m_cpt_fsm_tgt     = new uint32_t [soclib::common::size(tgt_fsm_state_str    )];
-      m_cpt_fsm_cleanup = new uint32_t [soclib::common::size(cleanup_fsm_state_str)];
-
-      m_cpt_frz_cycles  = new uint32_t [m_nb_cpu];
-      // r_icache_fsm("r_icache_fsm"),
-      // r_icache_fsm_save("r_icache_fsm_save"),
-      // r_icache_addr_save("r_icache_addr_save"),
-      // r_icache_miss_req("r_icache_miss_req"),
-      // r_icache_miss_way("r_icache_miss_way"),
-      // r_icache_miss_set("r_icache_miss_set"),
-      // r_icache_unc_req("r_icache_unc_req"),
-      // r_icache_cleanup_req("r_icache_cleanup_req"),
-      // r_icache_cleanup_line("r_icache_cleanup_line"),
-      // r_icache_inval_rsp("r_icache_inval_rsp"),
-      // r_icache_update_addr("r_icache_update_addr"),
-      // r_icache_buf_unc_valid("r_icache_buf_unc_valid"),
-
-      // r_dcache_fsm("r_dcache_fsm"),
-      // r_dcache_fsm_save("r_dcache_fsm_save"),
-      // r_dcache_addr_save("r_dcache_addr_save"),
-      // r_dcache_wdata_save("r_dcache_wdata_save"),
-      // r_dcache_rdata_save("r_dcache_rdata_save"),
-      // r_dcache_type_save("r_dcache_type_save"),
-      // r_dcache_be_save("r_dcache_be_save"),
-      // r_dcache_cached_save("r_dcache_cached_save"),
-      // r_dcache_cleanup_req("r_dcache_cleanup_req"),
-      // r_dcache_cleanup_line("r_dcache_cleanup_line"),
-      // r_dcache_miss_req("r_dcache_miss_req"),
-      // r_dcache_miss_way("r_dcache_miss_way"),
-      // r_dcache_miss_set("r_dcache_miss_set"),
-      // r_dcache_unc_req("r_dcache_unc_req"),
-      // r_dcache_sc_req("r_dcache_sc_req"),
-      // r_dcache_inval_rsp("r_dcache_inval_rsp"),
-      // r_dcache_update_addr("r_dcache_update_addr"),
-      // r_dcache_ll_data("r_dcache_ll_data"),
-      // r_dcache_ll_addr("r_dcache_ll_addr"),
-      // r_dcache_ll_valid("r_dcache_ll_valid"),
-      // r_dcache_previous_unc("r_dcache_previous_unc"),
-
-      // r_tgt_icache_req("r_tgt_icache_req"),
-      // r_tgt_icache_rsp("r_tgt_icache_rsp"),
-
-      // r_tgt_dcache_req("r_tgt_dcache_req"),
-      // r_tgt_dcache_rsp("r_tgt_dcache_rsp"),
-
-      // r_vci_rsp_ins_error("r_vci_rsp_ins_error"),
-      // r_vci_rsp_data_error("r_vci_rsp_data_error"),
-
-      size_t _icache_ways  = icache_ways /m_nb_icache;
-      size_t _icache_sets  = icache_sets ;
-      size_t _dcache_ways  = dcache_ways /m_nb_dcache;
-      size_t _dcache_sets  = dcache_sets ;
-      size_t _icache_words = icache_words;
-      size_t _dcache_words = dcache_words;
-
-      size_t _wbuf_nwords  = wbuf_nwords ;
-      size_t _wbuf_nlines  = wbuf_nlines /m_nb_dcache;
-
-      r_icache = new GenericCache<vci_addr_t>  * [m_nb_icache];
-      r_dcache = new GenericCache<vci_addr_t>  * [m_nb_dcache];
-      r_wbuf   = new MultiWriteBuffer<addr_40> * [m_nb_dcache];
-
-      for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
-        {
-          r_icache [num_cache] = new GenericCache<vci_addr_t>  ("icache", _icache_ways, _icache_sets, _icache_words);
-        }
-      for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
-        {
-          r_dcache [num_cache] = new GenericCache<vci_addr_t>  ("dcache", _dcache_ways, _dcache_sets, _dcache_words);
-          r_wbuf   [num_cache] = new MultiWriteBuffer<addr_40> ("r_wbuf", _wbuf_nwords, _wbuf_nlines, _dcache_words);
-        }
-
-      m_num_cache_LSB_mask = 0;
-      for (uint32_t i=0; i<m_num_cache_LSB; ++i)
-        {
-          m_num_cache_LSB_mask <<= 1;
-          m_num_cache_LSB_mask  |= 1;
-        }
-      m_num_cache_mask = 0;
-      for (uint32_t i=0; i<(m_num_cache_MSB-m_num_cache_LSB); ++i)
-        {
-          m_num_cache_mask <<= 1;
-          m_num_cache_mask  |= 1;
-        }
-
-      SC_METHOD(transition);
-      dont_initialize();
-      sensitive << p_clk.pos();
-
-      SC_METHOD(genMoore);
-      dont_initialize();
-      sensitive << p_clk.neg();
-
-      typename iss_t::CacheInfo cache_info;
-      cache_info.has_mmu          = false;
-      cache_info.icache_line_size = icache_words*sizeof(data_t);
-      cache_info.icache_assoc     = icache_ways;
-      cache_info.icache_n_lines   = icache_sets;
-      cache_info.dcache_line_size = dcache_words*sizeof(data_t);
-      cache_info.dcache_assoc     = dcache_ways;
-      cache_info.dcache_n_lines   = dcache_sets;
-
-      for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
-        m_iss[num_cpu]->setCacheInfo(cache_info);
-                
-#if CC_XCACHE_WRAPPER_STOP_SIMULATION
-      m_stop_simulation               = false;
-      m_stop_simulation_nb_frz_cycles = new uint32_t [m_nb_cpu];
-      for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
-        m_stop_simulation_nb_frz_cycles [num_cpu] = 0;
-#endif // CC_XCACHE_WRAPPER_STOP_SIMULATION
-
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-      generate_log_transaction_file_icache  = true;
-      generate_log_transaction_file_dcache  = true;
-      generate_log_transaction_file_cmd     = true;
-      generate_log_transaction_file_tgt     = true;
-      generate_log_transaction_file_cleanup = true;
-
-      log_transaction_file_icache = new std::ofstream [m_nb_cpu];
-      log_transaction_file_dcache = new std::ofstream [m_nb_cpu];
-      for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
-        {
-          {
-            std::ostringstream filename("");
-            filename << CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION_PATH << "/Transaction_icache-" << proc_id << "_" << num_cpu << ".log";
-            log_transaction_file_icache[num_cpu].open(filename.str().c_str() ,std::ios::out | std::ios::trunc);
-          }
-          {
-            std::ostringstream filename("");
-            filename << CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION_PATH << "/Transaction_dcache-" << proc_id << "_" << num_cpu << ".log";
-            log_transaction_file_dcache[num_cpu].open(filename.str().c_str() ,std::ios::out | std::ios::trunc);
-          }
-        }
-
-      {
-        std::ostringstream filename("");
-        filename << CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION_PATH << "/Transaction_cmd-" << proc_id << ".log";
-        log_transaction_file_cmd.open(filename.str().c_str() ,std::ios::out | std::ios::trunc);
-      }
-      {
-        std::ostringstream filename("");
-        filename << CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION_PATH << "/Transaction_tgt-" << proc_id << ".log";
-        log_transaction_file_tgt.open(filename.str().c_str() ,std::ios::out | std::ios::trunc);
-      }
-      {
-        std::ostringstream filename("");
-        filename << CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION_PATH << "/Transaction_cleanup-" << proc_id << ".log";
-        log_transaction_file_cleanup.open(filename.str().c_str() ,std::ios::out | std::ios::trunc);
-      }
+        if ( word < m_cache_words-1 ) 
+        {
+            std::cout << "  <PROC.DCACHE_MISS_UPDT> Matching coherence request:"
+                      << "  pop the FIFO, don't update the cache" << std::endl;
+        }
+        else
+        {
+            std::cout << "  <PROC.DCACHE_MISS_UPDT> Matching coherence request:"
+                      << " last word : send a cleanup request " << std::endl;
+        }
+    }
+    else
+    {
+        std::cout << "  <PROC.DCACHE_MISS_UPDT> Write one word:"
+                  << " address = " << addr 
+                  << " / data = " << r_vci_rsp_fifo_dcache.read()
+                  << " / way = " << way 
+                  << " / set = " << set
+                  << " / word = " << word << std::endl; 
+    }
+}
 #endif
-
-#if MWBUF_VHDL_TESTBENCH
-      simulation_started = false;
-
-      vhdl_testbench_mwbuf = new std::ofstream [m_nb_dcache];
-      for (uint32_t num_dcache=0; num_dcache<m_nb_dcache; ++num_dcache)
-        {
-          std::ostringstream filename("");
-          filename << "VHDL_testbench_mwbuf-" << proc_id << "_" << num_dcache << ".txt";
-          vhdl_testbench_mwbuf[num_dcache].open(filename.str().c_str() ,std::ios::out | std::ios::trunc);
-
-          vhdl_testbench_mwbuf[num_dcache] 
-            << _wbuf_nlines  << " "        // nb_lines      
-            << _wbuf_nwords  << " "        // nb_words      
-            << m_nb_cpu      << " "        // nb_cpu        
-            << 32            << " "        // size_data     
-            << 40            << " "        // size_addr     
-            << _dcache_words << std::endl; // cache_nb_words
-        }
-#endif
-    } // end constructor
-
-    ///////////////////////////////////
-    tmpl(/**/)::~VciCcXCacheWrapperV4()
-               ///////////////////////////////////
-    {
-#if MWBUF_VHDL_TESTBENCH
-      for (uint32_t num_dcache=0; num_dcache<m_nb_dcache; ++num_dcache)
-        vhdl_testbench_mwbuf[num_dcache].close();
-      delete [] vhdl_testbench_mwbuf;
-#endif
-
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-      for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
-        {
-          log_transaction_file_dcache[num_cpu].close();
-          log_transaction_file_icache[num_cpu].close();
-        }
-      delete [] log_transaction_file_dcache;
-      delete [] log_transaction_file_icache;
-
-      log_transaction_file_cmd    .close();
-      log_transaction_file_tgt    .close();
-      log_transaction_file_cleanup.close();
-#endif
-
-      delete [] m_stop_simulation_nb_frz_cycles;
-
-
-      delete [] r_icache_lock         ;
-      delete [] r_dcache_lock         ;
-      delete [] r_dcache_sync         ;
-
-      delete [] r_icache_fsm          ;
-      delete [] r_icache_fsm_save     ;
-      delete [] r_icache_addr_save    ;
-      delete [] r_icache_miss_req     ;
-      delete [] r_icache_miss_way     ;
-      delete [] r_icache_miss_set     ;
-      delete [] r_icache_unc_req      ;
-      delete [] r_icache_cleanup_req  ;
-      delete [] r_icache_cleanup_line ;
-      delete [] r_icache_inval_rsp    ;
-      delete [] r_icache_update_addr  ;
-      delete [] r_icache_buf_unc_valid;
-
-      delete [] r_dcache_fsm          ;
-      delete [] r_dcache_fsm_save     ;
-      delete [] r_dcache_addr_save    ;
-      delete [] r_dcache_wdata_save   ;
-      delete [] r_dcache_rdata_save   ;
-      delete [] r_dcache_type_save    ;
-      delete [] r_dcache_be_save      ;
-      delete [] r_dcache_cached_save  ;
-      delete [] r_dcache_cleanup_req  ;
-      delete [] r_dcache_cleanup_line ;
-      delete [] r_dcache_miss_req     ;
-      delete [] r_dcache_miss_way     ;
-      delete [] r_dcache_miss_set     ;
-      delete [] r_dcache_unc_req      ;
-      delete [] r_dcache_sc_req       ;
-      delete [] r_dcache_inval_rsp    ;
-      delete [] r_dcache_update_addr  ;
-      delete [] r_dcache_previous_unc ;
-
-      for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
-        {
-          delete [] r_dcache_ll_data    [num_cache];
-          delete [] r_dcache_ll_addr    [num_cache];
-          delete [] r_dcache_ll_valid   [num_cache];
-        }
-      delete [] r_dcache_num_cpu_save ;
-      delete [] r_dcache_ll_data      ;
-      delete [] r_dcache_ll_addr      ;
-      delete [] r_dcache_ll_valid     ;
-
-      delete [] r_tgt_icache_req      ;
-      delete [] r_tgt_icache_rsp      ;
-      delete [] r_tgt_dcache_req      ;
-      delete [] r_tgt_dcache_rsp      ;
-
-      delete [] r_tgt_be ;
-      delete [] r_tgt_buf;
-
-      delete [] r_vci_rsp_ins_error   ;
-      delete [] r_vci_rsp_data_error  ;
-
-      delete [] ireq           ;
-      delete [] irsp           ;
-      delete [] ireq_cached    ;
-      delete [] ireq_num_cpu   ;
-      delete [] dreq           ;
-      delete [] drsp           ;
-      delete [] dreq_cached    ;
-      delete [] dreq_num_cpu   ;
-
-      delete [] m_cpt_frz_cycles;
-
-      delete [] m_cpt_icache_access   ;
-      delete [] m_cpt_dcache_access   ;
-      delete [] m_cpt_icache_miss_victim_wait;
-      delete [] m_cpt_dcache_miss_victim_wait;
-      delete [] m_cpt_dcache_store_after_store;
-      delete [] m_cpt_dcache_hit_after_miss_read;
-      delete [] m_cpt_dcache_hit_after_miss_write;
-      for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
-        delete [] m_cpt_fsm_dcache [num_cache];
-      for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
-        delete [] m_cpt_fsm_icache [num_cache];
-        
-      delete [] m_cpt_fsm_dcache ;
-      delete [] m_cpt_fsm_icache ;
-      delete [] m_cpt_fsm_cmd    ;
-      delete [] m_cpt_fsm_rsp    ;
-      delete [] m_cpt_fsm_tgt    ;
-      delete [] m_cpt_fsm_cleanup;
-
-      for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
-        {
-          delete r_icache [num_cache];
-        }
-      for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
-        {
-          delete r_wbuf   [num_cache];
-          delete r_dcache [num_cache];
-        }
-      delete [] r_wbuf;
-      delete [] r_icache;
-      delete [] r_dcache;
-
-      for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
-        {
-          delete    m_iss [num_cpu];
-          delete [] p_irq [num_cpu];
-        }
-      delete [] m_iss;
-      delete [] p_irq;
-    }
-
-    ////////////////////////
-    tmpl(void)::print_cpi()
-    ////////////////////////
-    {
-      for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
-        std::cout << "CPU " << m_srcid_rw << " : CPI = " 
-                  << (float)m_cpt_total_cycles/(m_cpt_total_cycles - m_cpt_frz_cycles[num_cpu]) << std::endl ;
-    }
-    ////////////////////////
-    tmpl(void)::print_stats(bool print_wbuf, bool print_fsm)
-               ////////////////////////
-    {
-      uint32_t m_cpt_data_read_cached  = m_cpt_data_read-m_cpt_data_read_uncached;
-      uint32_t m_cpt_data_write_cached = m_cpt_data_write-m_cpt_data_write_uncached;
-      std::cout << "------------------------------------" << std:: dec << std::endl;
-      std::cout << "CPU " << m_srcid_rw << " / Time = " << m_cpt_total_cycles << std::endl;
-      for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
-        {
-          float run_cycles = (float)(m_cpt_total_cycles - m_cpt_frz_cycles[num_cpu]);
-
-          std::cout << "- CPI                            : [" << num_cpu << "] "<< (float)m_cpt_total_cycles/run_cycles << std::endl ;
-          std::cout << "- IPC                            : [" << num_cpu << "] "<< (float)run_cycles/m_cpt_total_cycles << std::endl ;
-        }
-      std::cout << "- DATA READ *                    : " << m_cpt_data_read << std::endl ;
-      std::cout << "  + Uncached                     : " << m_cpt_data_read_uncached << " (" << (float)m_cpt_data_read_uncached*100.0/(float)m_cpt_data_read << "%)" << std::endl ;
-      std::cout << "  + Cached and miss              : " << m_cpt_data_read_miss << " (" << (float)m_cpt_data_read_miss*100.0/(float)m_cpt_data_read_cached << "%)" << std::endl;
-      std::cout << "- DATA WRITE *                   : " << m_cpt_data_write << std::endl ;
-      std::cout << "  + Uncached                     : " << m_cpt_data_write_uncached << " (" << (float)m_cpt_data_write_uncached*100.0/(float)m_cpt_data_write << "%)" << std::endl ;
-      std::cout << "  + Cached and miss              : " << m_cpt_data_write_miss << " (" << (float)m_cpt_data_write_miss*100.0/(float)m_cpt_data_write_cached << "%)" << std::endl;
-      // std::cout << "- WRITE RATE                     : " << (float)m_cpt_data_write/run_cycles << std::endl;
-      // std::cout << "- UNCACHED READ RATE             : " << (float)m_cpt_data_read_uncached/m_cpt_data_read << std::endl ;
-      // std::cout << "- CACHED WRITE RATE              : " << (float)m_cpt_data_write_cached/m_cpt_data_write << std::endl ;
-      // std::cout << "- IMISS_RATE                     : " << (float)m_cpt_ins_miss/run_cycles << std::endl;
-      // std::cout << "- DMISS RATE                     : " << (float)m_cpt_data_miss/(m_cpt_data_read-m_cpt_data_read_uncached) << std::endl ;
-      // std::cout << "- INS MISS COST                  : " << (float)m_cost_ins_miss_frz/m_cpt_ins_miss << std::endl;
-      // std::cout << "- IMISS TRANSACTION              : " << (float)m_cost_imiss_transaction/m_cpt_imiss_transaction << std::endl;
-      // std::cout << "- DMISS COST                     : " << (float)m_cost_data_miss_frz/m_cpt_data_miss << std::endl;
-      // std::cout << "- DMISS TRANSACTION              : " << (float)m_cost_dmiss_transaction/m_cpt_dmiss_transaction << std::endl;
-      // std::cout << "- UNC COST                       : " << (float)m_cost_unc_read_frz/m_cpt_data_read_uncached << std::endl;
-      // std::cout << "- UNC TRANSACTION                : " << (float)m_cost_unc_transaction/m_cpt_unc_transaction << std::endl;
-      // std::cout << "- WRITE COST                     : " << (float)m_cost_write_frz/m_cpt_data_write << std::endl;
-      // std::cout << "- WRITE TRANSACTION              : " << (float)m_cost_write_transaction/m_cpt_data_write_transaction << std::endl;
-      // std::cout << "- WRITE LENGTH                   : " << (float)m_length_write_transaction/m_cpt_data_write_transaction << std::endl;
-
-      std::cout << "- CC_UPDATE_ICACHE               : " << m_cpt_cc_update_icache  << std::endl;
-      std::cout << "  + AVERAGE WORD USEFUL          : " << (float)m_cpt_cc_update_icache_word_useful/(float)m_cpt_cc_update_icache << " on " << m_icache_words << " words" << std::endl; 
-      std::cout << "- CC_UPDATE_DCACHE               : " << m_cpt_cc_update_dcache  << std::endl;
-      std::cout << "  + AVERAGE WORD USEFUL          : " << (float)m_cpt_cc_update_dcache_word_useful/(float)m_cpt_cc_update_dcache << " on " << m_dcache_words << " words" << std::endl; 
-      uint32_t m_cpt_cc_inval = m_cpt_cc_inval_broadcast+m_cpt_cc_inval_icache+m_cpt_cc_inval_dcache;
-      std::cout << "- CC_INVALID                     : " << m_cpt_cc_inval << std::endl;
-      std::cout << "  + ICACHE Only                  : " << (float)m_cpt_cc_inval_icache   *100.0/(float)m_cpt_cc_inval << "%" << std::endl;
-      std::cout << "  + DCACHE Only                  : " << (float)m_cpt_cc_inval_dcache   *100.0/(float)m_cpt_cc_inval << "%" << std::endl;
-      std::cout << "  + BROADCAST                    : " << (float)m_cpt_cc_inval_broadcast*100.0/(float)m_cpt_cc_inval << "%" << std::endl;
-
-      uint32_t m_cpt_icache_access_all = 0;
-      for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
-        m_cpt_icache_access_all += m_cpt_icache_access [num_cache];
-
-      std::cout << "- ICACHE ACCESS                  : " << m_cpt_icache_access_all << std::endl;
-      for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
-        std::cout << "  + [" << num_cache << "] : " << m_cpt_icache_access [num_cache] << " (" << (float)m_cpt_icache_access [num_cache]*100.0/(float)m_cpt_icache_access_all << "%)" << std::endl;
-
-      uint32_t m_cpt_dcache_access_all = 0;
-      for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
-        m_cpt_dcache_access_all += m_cpt_dcache_access [num_cache];
-
-      std::cout << "- DCACHE ACCESS                  : " << m_cpt_dcache_access_all << std::endl;
-      for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
-        {
-          std::cout << "  + [" << num_cache << "] : " << m_cpt_dcache_access [num_cache] << " (" << (float)m_cpt_dcache_access [num_cache]*100.0/(float)m_cpt_dcache_access_all << "%)";
-
-          std::cout << " - store after store : " << m_cpt_dcache_store_after_store [num_cache];
-          std::cout << " - Hit after Miss : Read " << m_cpt_dcache_hit_after_miss_read [num_cache] << ", Write " << m_cpt_dcache_hit_after_miss_write [num_cache];
-          std::cout << std::endl;
-        }
-
-      uint32_t m_cpt_icache_miss_victim_wait_all = 0;
-      for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
-        m_cpt_icache_miss_victim_wait_all += m_cpt_icache_miss_victim_wait [num_cache];
-      std::cout << "- ICACHE MISS VICTIM WAIT        : " << m_cpt_icache_miss_victim_wait_all << std::endl;
-      for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
-        std::cout << "  + [" << num_cache << "] : " << m_cpt_icache_miss_victim_wait [num_cache] << std::endl;
-
-      uint32_t m_cpt_dcache_miss_victim_wait_all = 0;
-      for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
-        m_cpt_dcache_miss_victim_wait_all += m_cpt_dcache_miss_victim_wait [num_cache];
-      std::cout << "- DCACHE MISS VICTIM WAIT        : " << m_cpt_dcache_miss_victim_wait_all << std::endl;
-      for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
-        std::cout << "  + [" << num_cache << "] : " << m_cpt_dcache_miss_victim_wait [num_cache] << std::endl;
-
-      if (print_fsm)
-        {
-          std::cout << "- DCACHE FSM" << std::endl;
-          for (uint32_t i=0; i<soclib::common::size(dcache_fsm_state_str ); ++i)
-            {
-              std::cout << "  + "  << dcache_fsm_state_str[i] << " :\t ";
-              for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
-                std::cout << m_cpt_fsm_dcache [num_cache][i] << ", ";
-              std::cout << std::endl; 
-            }
-          std::cout << "- ICACHE FSM" << std::endl;
-          for (uint32_t i=0; i<soclib::common::size(icache_fsm_state_str ); ++i)
-            {
-              std::cout << "  + "  << icache_fsm_state_str[i] << " :\t ";
-              for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
-                std::cout << m_cpt_fsm_icache [num_cache][i] << ", ";
-              std::cout << std::endl; 
-            }
-          std::cout << "- CMD FSM" << std::endl;
-          for (uint32_t i=0; i<soclib::common::size(cmd_fsm_state_str ); ++i)
-            std::cout << "  + " << cmd_fsm_state_str[i] << " :\t " << m_cpt_fsm_cmd [i] << std::endl;
-          std::cout << "- RSP FSM" << std::endl;
-          for (uint32_t i=0; i<soclib::common::size(rsp_fsm_state_str ); ++i)
-            std::cout << "  + " << rsp_fsm_state_str[i] << " :\t " << m_cpt_fsm_rsp [i] << std::endl;
-          std::cout << "- TGT FSM" << std::endl;
-          for (uint32_t i=0; i<soclib::common::size(tgt_fsm_state_str ); ++i)
-            std::cout << "  + "  << tgt_fsm_state_str[i] << " :\t " << m_cpt_fsm_tgt [i] << std::endl;
-          std::cout << "- CLEANUP FSM" << std::endl;
-          for (uint32_t i=0; i<soclib::common::size(cleanup_fsm_state_str ); ++i)
-            std::cout << "  + "  << cleanup_fsm_state_str[i] << " :\t " << m_cpt_fsm_cleanup [i] << std::endl;
-        }
-
-      std::cout << "* : accepted or not by the cache" << std::endl ;
-
-      if (print_wbuf)
-        for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
-          r_wbuf[num_cache]->printStatistics();
-    }
-
-    ////////////////////////////////////
-    tmpl(void)::print_trace(size_t mode)
-               ////////////////////////////////////
-    {
-      // b0 : write buffer print trace
-      // b1 : write buffer verbose
-      // b2 : dcache print trace
-      // b3 : icache print trace
-
-      typename iss_t::InstructionRequest  ireq;
-      typename iss_t::DataRequest         dreq;
-
-      std::cout << std::dec << "Proc \"" << name() << "\"" << std::endl;
-
-      for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
-        {
-          m_iss[num_cpu]->getRequests( ireq, dreq );
-          std::cout << ireq << std::endl;
-          std::cout << dreq << std::endl;
-        }
-      for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
-        std::cout << "  " << icache_fsm_state_str[r_icache_fsm[num_cache]] << std::endl;
-      for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
-        std::cout << "  " << dcache_fsm_state_str[r_dcache_fsm[num_cache]] << std::endl;
-            
-      std::cout << "  " << cmd_fsm_state_str[r_vci_cmd_fsm]
-                << "  " << rsp_fsm_state_str[r_vci_rsp_fsm]
-                << "  " << tgt_fsm_state_str[r_vci_tgt_fsm]
-                << "  " << cleanup_fsm_state_str[r_cleanup_fsm] << std::endl;
-
-      if(mode & 0x1)
-        {
-          for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
-            r_wbuf[num_cache]->printTrace((mode>>1)&1);
-        }
-      if(mode & 0x4)
-        {
-          std::cout << "  Data cache" << std::endl;
-          for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
-            r_dcache[num_cache]->printTrace();
-        }
-      if(mode & 0x8)
-        {
-          std::cout << "  Instruction cache" << std::endl;
-          for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
-            r_icache[num_cache]->printTrace();
-        }
-    }
-
-    //////////////////////////
-    tmpl(void)::transition()
-    //////////////////////////
-    {
-
-      /////////////////////////////////////////////////////////////////////
-      // Reset
-      /////////////////////////////////////////////////////////////////////
-
-      if ( not p_resetn.read() ) {
-
-        r_cpu_prior = 0;
-
-        for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
-          m_iss[num_cpu]->reset();
-
-        // FSM states
-        for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
-          {
-            r_icache_fsm [num_cache] = ICACHE_IDLE;
-
-            r_icache_lock[num_cache] = m_nb_cpu;
-          }
-        for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
-          {
-            r_dcache_fsm [num_cache] = DCACHE_IDLE;
-
-            r_dcache_lock[num_cache] = m_nb_cpu;
-            r_dcache_sync[num_cache] = false;
-          }
-
-        r_vci_cmd_fsm = CMD_IDLE;
-        r_vci_rsp_fsm = RSP_IDLE;
-        r_vci_tgt_fsm = TGT_IDLE;
-        r_cleanup_fsm = CLEANUP_IDLE;
-
-        for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
-          {
-            // write buffer & caches
-            r_icache[num_cache]->reset();
-
-            // synchronisation flip-flops from ICACHE & DCACHE FSMs to VCI  FSMs
-            r_icache_miss_req    [num_cache] = false;
-            r_icache_unc_req     [num_cache] = false;
-            r_icache_cleanup_req [num_cache] = false;
-
-            // internal messages in DCACHE et ICACHE FSMs
-            r_icache_inval_rsp   [num_cache] = false;
-
-            // error signals from the VCI RSP FSM to the ICACHE or DCACHE FSMs
-            r_icache_buf_unc_valid [num_cache] = false;
-
-            // synchronisation flip-flops from TGT FSM to ICACHE & DCACHE FSMs
-            r_tgt_icache_req     [num_cache] = false;
-            r_tgt_icache_rsp     [num_cache] = false;
-
-            r_vci_rsp_ins_error  [num_cache] = false;
-          }// end for num_cache
-
-        for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
-          {
-            // write buffer & caches
-            r_wbuf  [num_cache]->reset();
-            r_dcache[num_cache]->reset();
-
-            // synchronisation flip-flops from ICACHE & DCACHE FSMs to VCI  FSMs
-            r_dcache_miss_req    [num_cache] = false;
-            r_dcache_unc_req     [num_cache] = false;
-            r_dcache_sc_req      [num_cache] = false;
-            r_dcache_cleanup_req [num_cache] = false;
-            r_dcache_previous_unc[num_cache] = false;
-
-            // internal messages in DCACHE et ICACHE FSMs
-            r_dcache_inval_rsp   [num_cache] = false;
-
-            // error signals from the VCI RSP FSM to the ICACHE or DCACHE FSMs
-            for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
-              r_dcache_ll_valid      [num_cache][num_cpu] = false;
-
-            // synchronisation flip-flops from TGT FSM to ICACHE & DCACHE FSMs
-            r_tgt_dcache_req     [num_cache] = false;
-            r_tgt_dcache_rsp     [num_cache] = false;
-
-            r_vci_rsp_data_error [num_cache] = false;
-          }// end for num_cache
-
-        r_cache_word         = 0;
-
-        r_vci_cmd_dcache_prior     = false;
-        r_vci_cmd_num_icache_prior = 0;
-        r_vci_cmd_num_dcache_prior = 0;
-
-        r_vci_rsp_fifo_icache_data      .init();
-        r_vci_rsp_fifo_icache_num_cache .init();
-        r_vci_rsp_fifo_dcache_data      .init();
-        r_vci_rsp_fifo_dcache_num_cache .init();
-        
-        // activity counters
-        m_cpt_dcache_data_read  = 0;
-        m_cpt_dcache_data_write = 0;
-        m_cpt_dcache_dir_read   = 0;
-        m_cpt_dcache_dir_write  = 0;
-        m_cpt_icache_data_read  = 0;
-        m_cpt_icache_data_write = 0;
-        m_cpt_icache_dir_read   = 0;
-        m_cpt_icache_dir_write  = 0;
-
-        m_cpt_cc_update_icache             = 0;
-        m_cpt_cc_update_dcache             = 0;
-        m_cpt_cc_inval_broadcast           = 0;
-        m_cpt_cc_inval_icache              = 0;
-        m_cpt_cc_inval_dcache              = 0;
-        m_cpt_cc_update_icache_word_useful = 0;
-        m_cpt_cc_update_dcache_word_useful = 0;
-
-        for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
-          m_cpt_frz_cycles [num_cpu]  = 0;
-        m_cpt_total_cycles = 0;
-
-        m_cpt_data_read            = 0;
-        m_cpt_data_read_miss       = 0;
-        m_cpt_data_read_uncached   = 0;
-        m_cpt_data_write           = 0;
-        m_cpt_data_write_miss      = 0;
-        m_cpt_data_write_uncached  = 0;
-
-        m_cpt_ins_miss     = 0;
-
-        m_cost_write_frz = 0;
-        m_cost_data_miss_frz = 0;
-        m_cost_unc_read_frz = 0;
-        m_cost_ins_miss_frz = 0;
-
-        m_cpt_imiss_transaction = 0;
-        m_cpt_dmiss_transaction = 0;
-        m_cpt_unc_transaction = 0;
-        m_cpt_data_write_transaction = 0;
-
-        m_cost_imiss_transaction = 0;
-        m_cost_dmiss_transaction = 0;
-        m_cost_unc_transaction = 0;
-        m_cost_write_transaction = 0;
-        m_length_write_transaction = 0;
-
-        for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
-          {
-            m_cpt_icache_access           [num_cache] = 0;
-            m_cpt_icache_miss_victim_wait [num_cache] = 0;
-
-            for (uint32_t i=0; i<soclib::common::size(icache_fsm_state_str ); ++i)
-              m_cpt_fsm_icache  [num_cache][i] = 0;
-          }
-        for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
-          {
-            m_cpt_dcache_access               [num_cache] = 0;
-            m_cpt_dcache_miss_victim_wait     [num_cache] = 0;
-            m_cpt_dcache_store_after_store    [num_cache] = 0;
-            m_cpt_dcache_hit_after_miss_read  [num_cache] = 0;
-            m_cpt_dcache_hit_after_miss_write [num_cache] = 0;
-            for (uint32_t i=0; i<soclib::common::size(dcache_fsm_state_str ); ++i)
-              m_cpt_fsm_dcache  [num_cache][i] = 0;
-          }
-
-        for (uint32_t i=0; i<soclib::common::size(cmd_fsm_state_str    ); ++i)
-          m_cpt_fsm_cmd     [i] = 0;
-        for (uint32_t i=0; i<soclib::common::size(rsp_fsm_state_str    ); ++i)
-          m_cpt_fsm_rsp     [i] = 0;
-        for (uint32_t i=0; i<soclib::common::size(tgt_fsm_state_str    ); ++i)
-          m_cpt_fsm_tgt     [i] = 0;
-        for (uint32_t i=0; i<soclib::common::size(cleanup_fsm_state_str); ++i)
-          m_cpt_fsm_cleanup [i] = 0;
-
-        return; // reset is finish, quit the transition fonction
-      }
-
-      bool     vci_rsp_fifo_icache_get       = false;
-      bool     vci_rsp_fifo_icache_put       = false;
-      data_t   vci_rsp_fifo_icache_data      = 0;
-      uint32_t vci_rsp_fifo_icache_num_cache = 0;
-
-      bool     vci_rsp_fifo_dcache_get       = false;
-      bool     vci_rsp_fifo_dcache_put       = false;
-      data_t   vci_rsp_fifo_dcache_data      = 0;
-      uint32_t vci_rsp_fifo_dcache_num_cache = 0;
-
-      /////////////////////////////////////////////////////////////////////
-      // VHDL TESTBENCH
-      // Create and initialize variable
-      /////////////////////////////////////////////////////////////////////
-
-#if MWBUF_VHDL_TESTBENCH
-      simulation_started = true;
-
-      vhdl_tb_t vhdl_mwbuf_test_empty            [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_port_empty            [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_port_flush            [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_port_write_val        [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_test_write_ack        [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_port_write_ack        [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_port_write_addr       [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_port_write_data       [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_port_write_be         [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_port_write_cached     [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_port_write_cpu_id     [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_test_sent_val         [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_port_sent_val         [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_port_sent_ack         [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_test_sent_word_min    [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_port_sent_word_min    [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_test_sent_word_max    [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_port_sent_word_max    [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_port_sent_word        [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_test_sent_addr        [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_port_sent_addr        [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_test_sent_data        [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_port_sent_data        [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_test_sent_be          [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_port_sent_be          [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_test_sent_index       [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_port_sent_index       [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_port_raw_test         [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_port_raw_addr         [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_test_raw_miss         [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_port_raw_miss         [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_port_completed_val    [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_port_completed_index  [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_test_completed_cached [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_port_completed_cached [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_test_completed_cpu_id [m_nb_dcache];
-      vhdl_tb_t vhdl_mwbuf_port_completed_cpu_id [m_nb_dcache];
-
-      for (uint32_t num_dcache=0; num_dcache<m_nb_dcache; ++num_dcache)
-        {
-          vhdl_mwbuf_test_empty            [num_dcache] = 0;
-          vhdl_mwbuf_port_empty            [num_dcache] = 0;
-          vhdl_mwbuf_port_flush            [num_dcache] = 0;
-          vhdl_mwbuf_port_write_val        [num_dcache] = 0;
-          vhdl_mwbuf_test_write_ack        [num_dcache] = 0;
-          vhdl_mwbuf_port_write_ack        [num_dcache] = 0;
-          vhdl_mwbuf_port_write_addr       [num_dcache] = 0;
-          vhdl_mwbuf_port_write_data       [num_dcache] = 0;
-          vhdl_mwbuf_port_write_be         [num_dcache] = 0;
-          vhdl_mwbuf_port_write_cached     [num_dcache] = 0;
-          vhdl_mwbuf_port_write_cpu_id     [num_dcache] = 0;
-          vhdl_mwbuf_test_sent_val         [num_dcache] = 0;
-          vhdl_mwbuf_port_sent_val         [num_dcache] = 0;
-          vhdl_mwbuf_port_sent_ack         [num_dcache] = 0;
-          vhdl_mwbuf_test_sent_word_min    [num_dcache] = 0;
-          vhdl_mwbuf_port_sent_word_min    [num_dcache] = 0;
-          vhdl_mwbuf_test_sent_word_max    [num_dcache] = 0;
-          vhdl_mwbuf_port_sent_word_max    [num_dcache] = 0;
-          vhdl_mwbuf_port_sent_word        [num_dcache] = 0;
-          vhdl_mwbuf_test_sent_addr        [num_dcache] = 0;
-          vhdl_mwbuf_port_sent_addr        [num_dcache] = 0;
-          vhdl_mwbuf_test_sent_data        [num_dcache] = 0;
-          vhdl_mwbuf_port_sent_data        [num_dcache] = 0;
-          vhdl_mwbuf_test_sent_be          [num_dcache] = 0;
-          vhdl_mwbuf_port_sent_be          [num_dcache] = 0;
-          vhdl_mwbuf_test_sent_index       [num_dcache] = 0;
-          vhdl_mwbuf_port_sent_index       [num_dcache] = 0;
-          vhdl_mwbuf_port_raw_test         [num_dcache] = 0;
-          vhdl_mwbuf_port_raw_addr         [num_dcache] = 0;
-          vhdl_mwbuf_test_raw_miss         [num_dcache] = 0;
-          vhdl_mwbuf_port_raw_miss         [num_dcache] = 0;
-          vhdl_mwbuf_port_completed_val    [num_dcache] = 0;
-          vhdl_mwbuf_port_completed_index  [num_dcache] = 0;
-          vhdl_mwbuf_test_completed_cached [num_dcache] = 0;
-          vhdl_mwbuf_port_completed_cached [num_dcache] = 0;
-          vhdl_mwbuf_test_completed_cpu_id [num_dcache] = 0;
-          vhdl_mwbuf_port_completed_cpu_id [num_dcache] = 0;
-        }
-#endif
-
-      /////////////////////////////////////////////////////////////////////
-      // DEBUG :
-      // print state of all fsm and main register
-      /////////////////////////////////////////////////////////////////////
-
-      // printf("%d\n",(uint32_t)m_cpt_total_cycles);
-
-      PRINTF("--------------------------------------------\n");
-      PRINTF("  * CC_XCACHE_WRAPPER \"%s\" Transition - Time = %d\n",name().c_str(),(uint32_t)m_cpt_total_cycles);
-      for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
-      PRINTF("    * fsm dcache              = [%.2d] %s - (%.2d) %llx (%llx)\n",num_cache,dcache_fsm_state_str[r_dcache_fsm[num_cache]],r_dcache_lock[num_cache].read(),(blob_t)r_dcache_addr_save[num_cache].read(),(blob_t)set_num_dcache_only(r_dcache_addr_save[num_cache].read(),num_cache));
-      for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
-        PRINTF("    * fsm icache              = [%.2d] %s - (%.2d) %llx (%llx)\n",num_cache,icache_fsm_state_str[r_icache_fsm[num_cache]],r_icache_lock[num_cache].read(),(blob_t)r_icache_addr_save[num_cache].read(),(blob_t)set_num_icache_only(r_icache_addr_save[num_cache].read(),num_cache));
-      PRINTF("    * fsm cmd                 = (%.2d) %s\n",r_vci_cmd_num_cache.read(), cmd_fsm_state_str[r_vci_cmd_fsm]);
-      PRINTF("    * fsm rsp                 = (%.2d) %s\n",r_vci_rsp_num_cache.read(), rsp_fsm_state_str[r_vci_rsp_fsm]);
-      PRINTF("    * fsm tgt                 = (%.2d) %s - i %llx d %llx\n",r_tgt_num_cache.read(), tgt_fsm_state_str[r_vci_tgt_fsm],(blob_t)r_tgt_iaddr.read(),(blob_t)r_tgt_daddr.read());
-    //PRINTF("    * fsm tgt                 =      %s - %llx\n",tgt_fsm_state_str[r_vci_tgt_fsm],(blob_t)r_tgt_addr.read());
-      PRINTF("    * fsm cleanup             = (%.2d) %s\n",r_cleanup_num_cache.read(), cleanup_fsm_state_str[r_cleanup_fsm]);
-      for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
-        {
-          for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
-            PRINTF("    * ll info                 : [%.2d][%.2d] %d %llx (%llx) %llx\n"
-                   ,num_cache
-                   ,num_cpu
-                   ,          r_dcache_ll_valid [num_cache][num_cpu].read()
-                   ,(blob_t)r_dcache_ll_addr  [num_cache][num_cpu].read()
-                   ,(blob_t)set_num_dcache_only(r_dcache_ll_addr [num_cache][num_cpu].read(),num_cache)
-                   ,(blob_t)r_dcache_ll_data [num_cache][num_cpu].read());
-
-          PRINTF("    * dcache_previous_unc     : [%.2d] %d\n",num_cache,r_dcache_previous_unc[num_cache].read());
-
-#if CC_XCACHE_WRAPPER_DEBUG
-          if (m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN)
-            r_wbuf[num_cache]->printTrace(1);
-#endif
-
-          // VHDL debug
-// #if MWBUF_VHDL_TESTBENCH
-//           printf("\nMWBUF[%d] - Time = %d\n\n",num_cache,(uint32_t)m_cpt_total_cycles);
-//           r_wbuf[num_cache]->printTrace(1);
-// #endif
-        }
-#if CC_XCACHE_WRAPPER_DEBUG
-      if (m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN)
-      {
-          PRINTF("    * rsp_fifo_icache %s\n",name().c_str());
-          r_vci_rsp_fifo_icache_data     .print();
-          r_vci_rsp_fifo_icache_num_cache.print();
-          PRINTF("    * rsp_fifo_dcache %s\n",name().c_str());
-          r_vci_rsp_fifo_dcache_data     .print();
-          r_vci_rsp_fifo_dcache_num_cache.print();
-      }
-#endif
-
-      /////////////////////////////////////////////////////////////////////
-      // Statistics
-      // Count state fsm activity
-      /////////////////////////////////////////////////////////////////////
-
-
-      for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
-        m_cpt_fsm_dcache  [num_cache][r_dcache_fsm[num_cache]] ++;
-      for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
-        m_cpt_fsm_icache  [num_cache][r_icache_fsm[num_cache]] ++;
-      m_cpt_fsm_cmd     [r_vci_cmd_fsm] ++;
-      m_cpt_fsm_rsp     [r_vci_rsp_fsm] ++;
-      m_cpt_fsm_tgt     [r_vci_tgt_fsm] ++;
-      m_cpt_fsm_cleanup [r_cleanup_fsm] ++;
-
-      m_cpt_total_cycles++;
-
-      /////////////////////////////////////////////////////////////////////
-      // The TGT_FSM controls the following ressources:
-      // - r_vci_tgt_fsm
-      // - r_tgt_buf[nwords]
-      // - r_tgt_be[nwords]
-      // - r_tgt_update
-      // - r_tgt_word
-      // - r_tgt_addr
-      // - r_tgt_srcid
-      // - r_tgt_trdid
-      // - r_tgt_pktid
-      // All VCI commands must be CMD_WRITE.
-      // If the VCI address offset is null, the command is an invalidate 
-      // request. It is an update request otherwise.
-      // The VCI_TGT FSM stores the external request arguments in the
-      // IDLE, UPDT_WORD & UPDT_DATA states. It sets the r_tgt_icache_req 
-      // & r_tgt_dcache_req flip-flops to signal the external request to 
-      // the ICACHE & DCACHE FSMs in the REQ state. It waits the completion
-      // of the update or invalidate request in the RSP state.
-      // -  for an invalidate request the VCI packet length is 1 word.
-      // The WDATA field contains the line index (i.e. the Z & Y fields).
-      // -  for an update request the VCI packet length is (n+2) words.
-      // The WDATA field of the first VCI word contains the line number.
-      // The WDATA field of the second VCI word contains the word index.
-      // The WDATA field of the n following words contains the values.
-      // -  for both invalidate & update requests, the VCI response
-      // is one single word.
-      // In case of errors in the VCI command packet, the simulation
-      // is stopped with an error message.
-      /////////////////////////////////////////////////////////////////////
-
-      switch(r_vci_tgt_fsm) {
-
-      case TGT_IDLE:
-        if ( p_vci_tgt.cmdval.read() ) 
-          {
-            PRINTF("    * <TGT> Request\n");
-
-            addr_40 address = p_vci_tgt.address.read();
-
-            if ( p_vci_tgt.cmd.read() != vci_param::CMD_WRITE) 
+            }
+            break;
+        }
+        /////////////////////
+        case DCACHE_UNC_WAIT:       // Waiting the response to an uncached request
+        {
+            if ( r_tgt_dcache_req )    // coherence request
+            {
+                r_dcache_fsm      = DCACHE_CC_CHECK;
+                r_dcache_fsm_save = r_dcache_fsm;
+                break;
+            } 
+
+            if ( r_vci_rsp_data_error ) 
+            {
+                r_dcache_fsm = DCACHE_ERROR;
+            }
+            else if ( r_vci_rsp_fifo_dcache.rok() )
+            {
+                vci_rsp_fifo_dcache_get = true;
+                r_dcache_unc_valid      = true;
+                r_dcache_unc_buf        = r_vci_rsp_fifo_dcache.read();
+                r_dcache_fsm            = DCACHE_IDLE;
+            }
+            break;
+        }
+        //////////////////
+        case DCACHE_ERROR:      // signal a read bus error to the processor
+        {
+            r_dcache_fsm         = DCACHE_IDLE;
+            r_vci_rsp_data_error = false;
+            drsp.error           = true;
+            drsp.valid           = true;
+            break;
+        }
+        //////////////////    
+        case DCACHE_INVAL:      // XTN inval is done in two cycles
+                                // In this state we test the cache hit
+        {                   
+            uint32_t    data;   // unused
+            size_t      word;   // unused
+            size_t      way;
+            size_t      set;
+            bool        hit = r_dcache->read( r_dcache_wdata_save.read(),
+                                              &data,
+                                              &way,
+                                              &set,
+                                              &word );
+            if ( hit )  // inval to be done
+            {
+                r_dcache_way_save = way;
+                r_dcache_set_save = set;
+                r_dcache_fsm      = DCACHE_INVAL_GO;
+            }
+            else        // nothing to do
+            {
+                drsp.valid        = true;
+                r_dcache_fsm      = DCACHE_IDLE;
+            }
+            break;
+        }
+        /////////////////////    
+        case DCACHE_INVAL_GO:   // XTN inval is done in two cycles
+                                // In this state we wait to post a cleanup request
+                                // and make the inval when cleanup is possible
+        {
+
+            if ( r_tgt_dcache_req )  // coherence request
+            {   
+                r_dcache_fsm      = DCACHE_CC_CHECK;
+                r_dcache_fsm_save = r_dcache_fsm;
+                break;
+            } 
+
+            if ( not r_dcache_cleanup_req .read() )
+            {
+                vci_addr_t  nline;
+                r_dcache_cleanup_req  = r_dcache->inval( r_dcache_way_save.read(),
+                                                         r_dcache_set_save.read(),
+                                                         &nline );
+
+                r_dcache_cleanup_line = r_dcache_wdata_save.read() >> m_cache_words_shift;
+                r_dcache_fsm          = DCACHE_IDLE;
+                drsp.valid            = true;      
+            }
+            break;
+        }
+        /////////////////
+        case DCACHE_SYNC:       // waiting until the write buffer is empty
+        {
+            if ( r_tgt_dcache_req )  // coherence request
+            {   
+                r_dcache_fsm      = DCACHE_CC_CHECK;
+                r_dcache_fsm_save = r_dcache_fsm;
+                break;
+            } 
+
+            if ( r_wbuf->empty() );
+            {
+                drsp.valid    = true;      
+                r_dcache_fsm  = DCACHE_IDLE;
+            }
+            break;
+        }
+        /////////////////////
+        case DCACHE_CC_CHECK:   // read directory in case of coherence request
+        {
+            vci_addr_t  addr  = r_tgt_addr.read();
+            vci_addr_t  mask  = ~((m_cache_words<<2)-1);
+
+            if( (r_dcache_fsm_save.read() == DCACHE_MISS_WAIT) and 
+                 ((r_dcache_addr_save.read() & mask) == (addr & mask)) )
+                 // The coherence request matches a pending miss
+            {
+                r_dcache_miss_inval = true;
+                r_tgt_dcache_req    = false;
+                r_tgt_dcache_rsp    = r_tgt_update.read();
+                r_dcache_fsm        = r_dcache_fsm_save.read();
+            }
+            else    // no match for a pending miss
+            {
+                size_t  way;
+                size_t  set;
+                size_t  word;
+                bool    hit   = r_dcache->hit( addr, 
+                                               &way, 
+                                               &set, 
+                                               &word );
+                r_dcache_cc_way = way;
+                r_dcache_cc_set = set;
+
+                m_conso_dcache_dir_read++;
+
+                if ( hit and r_tgt_update.read() )          // hit update
+                {
+                    r_dcache_fsm         = DCACHE_CC_UPDT;
+                    r_dcache_update_word = r_tgt_word_min.read();
+                }
+                else if (hit and not r_tgt_update.read() )  // hit inval
+                {
+                    r_dcache_fsm         = DCACHE_CC_INVAL;
+                }
+                else                                        // miss can happen
+                {
+                    r_tgt_dcache_req = false;
+                    r_tgt_dcache_rsp = r_tgt_update.read();
+                    r_dcache_fsm     = r_dcache_fsm_save.read();
+                }
+            }
+            break;
+        }
+        /////////////////////
+        case DCACHE_CC_INVAL:  
+        {
+            vci_addr_t  nline;
+            r_dcache->inval( r_dcache_cc_way.read(),
+                             r_dcache_cc_set.read(),
+                             &nline );
+            r_tgt_dcache_req = false;
+            r_tgt_dcache_rsp = true;
+            r_dcache_fsm     = r_dcache_fsm_save.read();
+            break;
+        }
+        ////////////////////
+        case DCACHE_CC_UPDT:   
+        {
+              size_t word = r_dcache_update_word.read();
+              r_dcache->write( r_dcache_cc_way.read(),
+                               r_dcache_cc_set.read(),
+                               word,
+                               r_tgt_buf[ word].read(),
+                               r_tgt_be[word].read() );
+
+              r_dcache_update_word = word+1;
+              if ( word == r_tgt_word_max.read() )      // last word
               {
-                std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
-                std::cout << "coherence request is not a write" << std::endl;
-                std::cout << "address = " << std::hex << address << std::dec << std::endl;
-                std::cout << "srcid   = " << p_vci_tgt.srcid.read() << std::endl;
-                exit(0);
-              }
-
-            // multi-update or multi-invalidate for data type
-            if ( ((address&0x3) != 0x3) and (not m_segment.contains(address)) ) 
-              {
-                std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
-                std::cout << "out of segment coherence request" << std::endl;
-                std::cout << "address = " << std::hex << address << std::dec << std::endl;
-                std::cout << "srcid   = " << p_vci_tgt.srcid.read() << std::endl;
-                exit(0);
-              }
-
-            addr_40 tgt_addr  = ((((addr_40)p_vci_tgt.be.read() & 0x3) << 32) | ((addr_40) p_vci_tgt.wdata.read())) << (addr_40)m_dcache_words_shift;
-            // * m_dcache_words * 4;
-
-            addr_40 tgt_iaddr = tgt_addr;
-            addr_40 tgt_daddr = tgt_addr;
-
-            PRINTF("    * <TGT> srcid            : %d\n",(uint32_t)p_vci_tgt.srcid.read());
-            PRINTF("    * <TGT> trdid            : %d\n",(uint32_t)p_vci_tgt.trdid.read());
-            PRINTF("    * <TGT> pktid            : %d\n",(uint32_t)p_vci_tgt.pktid.read());
-            PRINTF("    * <TGT> address (before) : %llx\n",(blob_t)tgt_iaddr);
-
-            r_tgt_srcid     = p_vci_tgt.srcid.read();
-            r_tgt_trdid     = p_vci_tgt.trdid.read();
-            r_tgt_pktid     = p_vci_tgt.pktid.read();
-            // r_tgt_plen      = p_vci_tgt.plen.read();
-                    
-            // BROADCAST
-            if ( (address&0x3) == 0x3 )   // broadcast invalidate for data or instruction type
-              {
-                if ( not p_vci_tgt.eop.read() ) 
-                  {
-                    std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
-                    std::cout << "the BROADCAST INVALIDATE command length must be one word" << std::endl;
-                    exit(0);
-                  }
-                r_tgt_update = false; 
-                // r_tgt_brdcast= true;
-                r_vci_tgt_fsm = TGT_REQ_BROADCAST;
-                uint32_t tgt_num_cache;
-                tgt_num_cache = get_num_icache(tgt_iaddr,0); // none effect (else CC_XCACHE_WRAPPER_MULTI_CACHE==1)
-                tgt_num_cache = get_num_dcache(tgt_daddr);
-                r_tgt_num_cache = tgt_num_cache;
-
-                PRINTF("    * <TGT> REQ_BROADCAST\n");
-                PRINTF("    * <TGT> num_cache (data) : %d\n",tgt_num_cache);
-
-                m_cpt_cc_inval_broadcast++ ;
-
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-                if (generate_log_transaction_file_tgt)
-                  {
-                    log_transaction_file_tgt
-                      << "[" << m_cpt_total_cycles << "] "
-                      << "BROADCAST  "
-                      << std::hex
-                      << " L " << std::setw(10) << (blob_t)tgt_addr
-                      << std::dec
-                      << " - " << tgt_num_cache
-                      << std::endl;
-                  }
-#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-
-              }
-            else                    // multi-update or multi-invalidate for data type
-              { 
-                uint32_t cell = address - m_segment.baseAddress(); // addr_40
-                // r_tgt_brdcast = false;
-
-                if (cell == 0) 
-                  {                                       // invalidate data
-                    if ( not p_vci_tgt.eop.read() ) 
-                      {
-                        std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
-                        std::cout << "the MULTI-INVALIDATE command length must be one word" << std::endl;
-                        exit(0);
-                      }
-                    r_tgt_update = false; 
-                    r_vci_tgt_fsm = TGT_REQ_DCACHE;
-                    uint32_t tgt_num_cache = get_num_dcache(tgt_daddr); // static partionnement
-                    r_tgt_num_cache = tgt_num_cache;
-                            
-                    PRINTF("    * <TGT> REQ_DCACHE\n");
-                    PRINTF("    * <TGT> num_cache        : %d\n",tgt_num_cache);
-
-                    m_cpt_cc_inval_dcache++ ;
-
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-                    if (generate_log_transaction_file_tgt)
-                      {
-                        log_transaction_file_tgt
-                          << "[" << m_cpt_total_cycles << "] "
-                          << "INVAL DATA "
-                          << std::hex
-                          << " L " << std::setw(10) << (blob_t)tgt_addr
-                          << std::dec 
-                          << " - " << tgt_num_cache
-                          << std::endl;
-                      }
-#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-
-                  } 
-                else if (cell == 4)                     // invalidate instruction
-                  {                         
-                    if ( not p_vci_tgt.eop.read() ) 
-                      {
-                        std::cout << "error in component VCI_CC_VCACHE_WRAPPER " << name() << std::endl;
-                        std::cout << "the MULTI-INVALIDATE command length must be one word" << std::endl;
-                        exit(0);
-                      }
-                    r_tgt_update = false; 
-                    r_vci_tgt_fsm = TGT_REQ_ICACHE;
-                    uint32_t tgt_num_cpu   = p_vci_tgt.pktid.read();
-                    uint32_t tgt_num_cache = get_num_icache(tgt_iaddr,tgt_num_cpu);
-                    r_tgt_num_cache = tgt_num_cache;
-                            
-                    PRINTF("    * <TGT> REQ_ICACHE\n");
-                    PRINTF("    * <TGT> num_cache        : %d\n",tgt_num_cache);
-
-                    m_cpt_cc_inval_icache++ ;
-
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-                    if (generate_log_transaction_file_tgt)
-                      {
-                        log_transaction_file_tgt
-                          << "[" << m_cpt_total_cycles << "] "
-                          << "INVAL INS  "
-                          << std::hex
-                          << " L " << std::setw(10) << (blob_t)tgt_addr
-                          << std::dec
-                          << " - " << tgt_num_cache
-                          << std::endl;
-                      }
-#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-
-                  } 
-                else if ( (cell == 8) or (cell==12) )    // update data or instruction
-                  {                                
-                    if ( p_vci_tgt.eop.read() ) 
-                      {
-                        std::cout << "error in component VCI_CC_VCACHE_WRAPPER " << name() << std::endl;
-                        std::cout << "the MULTI-UPDATE command length must be N+2 words" << std::endl;
-                        exit(0);
-                      }
-                    if(cell == 8)
-                      {
-                        m_cpt_cc_update_dcache++;
-                        r_tgt_update_data = true;
-
-                        uint32_t tgt_num_cache = get_num_dcache(tgt_daddr);
-                        r_tgt_num_cache = tgt_num_cache;
-                                
-                        PRINTF("    * <TGT> UPDT_WORD DATA\n");
-                        PRINTF("    * <TGT> num_cache        : %d\n",tgt_num_cache);
-
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-                        if (generate_log_transaction_file_tgt)
-                          {
-                            log_transaction_file_tgt
-                              << "[" << m_cpt_total_cycles << "] "
-                              << "UPT DATA   "
-                              << std::hex
-                              << " L " << std::setw(10) << (blob_t)tgt_addr
-                              << std::dec
-                              << " - " << tgt_num_cache
-                              << std::endl;
-                          }
-#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-                      }
-                    else
-                      {
-                        m_cpt_cc_update_icache++;
-                        r_tgt_update_data = false;
-
-                        uint32_t tgt_num_cpu   = p_vci_tgt.pktid.read();
-                        uint32_t tgt_num_cache = get_num_icache(tgt_iaddr,tgt_num_cpu);
-                        r_tgt_num_cache = tgt_num_cache;
-                                
-                        PRINTF("    * <TGT> UPDT_WORD INSTRUCTION\n");
-                        PRINTF("    * <TGT> num_cache        : %d\n",tgt_num_cache);
-
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-                        if (generate_log_transaction_file_tgt)
-                          {
-                            log_transaction_file_tgt
-                              << "[" << m_cpt_total_cycles << "] "
-                              << "UPT INS    "
-                              << std::hex
-                              << " L " << std::setw(10) << (blob_t)tgt_addr
-                              << std::dec
-                              << " - " << tgt_num_cache
-                              << std::endl;
-                          }
-#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-                      }
-                    r_tgt_update = true; 
-                    r_vci_tgt_fsm = TGT_UPDT_WORD;
-                  } 
-
-              } // end if address
-                    
-            r_tgt_iaddr      = tgt_iaddr;
-            r_tgt_daddr      = tgt_daddr;
-            PRINTF("    * <TGT> address (after)  : i %llx, d %llx\n",(blob_t)tgt_iaddr,(blob_t)tgt_daddr);
-
-          } // end if cmdval
-        break;
-
-      case TGT_UPDT_WORD:
-        if (p_vci_tgt.cmdval.read()) 
-          {
-            if ( p_vci_tgt.eop.read() ) 
-              {
-                std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
-                std::cout << "the MULTI-UPDATE command length must be N+2 words" << std::endl;
-                exit(0);
-              }
-            for ( size_t i=0 ; i<m_dcache_words ; i++ ) r_tgt_be[i] = 0;
-            r_tgt_word = p_vci_tgt.wdata.read(); // the first modified word index
-            r_vci_tgt_fsm = TGT_UPDT_DATA;
-          }
-        break;
-
-      case TGT_UPDT_DATA:
-        if (p_vci_tgt.cmdval.read()) 
-          {
-            size_t word = r_tgt_word.read();
-            if ( word >= m_cache_words ) 
-              {
-                std::cout << "error in component VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
-                std::cout << "the reveived MULTI-UPDATE command length is wrong" << std::endl;
-                exit(0);
-              }
-
-            r_tgt_buf[word] = p_vci_tgt.wdata.read();
-            r_tgt_be [word] = p_vci_tgt.be.read();
-
-            if (p_vci_tgt.be.read())
-              {
-                if(r_tgt_update_data.read())
-                  m_cpt_cc_update_dcache_word_useful++ ;
-                else
-                  m_cpt_cc_update_icache_word_useful++ ;
-              }
-
-            r_tgt_word = word + 1;
-            if (p_vci_tgt.eop.read()){
-
-              uint32_t word=0;
-              for (; word<m_cache_words; ++word)
-                if (r_tgt_be[word] != 0)
-                  break;
-              r_cache_word = word;
-
-              if(r_tgt_update_data.read()){
-                r_vci_tgt_fsm = TGT_REQ_DCACHE;
-              } else {
-                r_vci_tgt_fsm = TGT_REQ_ICACHE;
-              }
-            }
-          }
-        break;
-
-      case TGT_REQ_BROADCAST:
-        {
-          bool tgt_icache_req;
-
-#if   (CC_XCACHE_WRAPPER_MULTI_CACHE==1)
-          tgt_icache_req = r_tgt_icache_req[r_tgt_num_cache].read();
-#elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2)
-          tgt_icache_req = false;
-          for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
-            tgt_icache_req |= r_tgt_icache_req[num_cache].read();
-#endif
-          if (not tgt_icache_req and not r_tgt_dcache_req[r_tgt_num_cache].read()) 
-            {
-              r_vci_tgt_fsm = TGT_RSP_BROADCAST; 
-
-#if   (CC_XCACHE_WRAPPER_MULTI_CACHE==1)
-              r_tgt_icache_req[r_tgt_num_cache] = true;
-#elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2)
-              for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
-                r_tgt_icache_req[      num_cache] = true;
-#endif
-
-              r_tgt_dcache_req[r_tgt_num_cache] = true;
-            }
-        }
-        break;
-        ////////////////////
-      case TGT_REQ_ICACHE:
-        {
-          // Request treated by the icache
-          if ( not r_tgt_icache_req[r_tgt_num_cache].read() ) 
-            {
-              r_vci_tgt_fsm = TGT_RSP_ICACHE; 
-              r_tgt_icache_req[r_tgt_num_cache] = true;
-            }
-          break;
-        }
-
-      case TGT_REQ_DCACHE:
-        {
-          // Request treated by the dcache
-
-          if ( not r_tgt_dcache_req[r_tgt_num_cache].read() ) 
-            {
-              r_vci_tgt_fsm = TGT_RSP_DCACHE; 
-              r_tgt_dcache_req[r_tgt_num_cache] = true;
-            }
-          break;
-        }
-      case TGT_RSP_BROADCAST:
-        {
-          PRINTF("      * <TGT> dcache[%d] : %d - %d\n",(uint32_t)r_tgt_num_cache, (uint32_t)r_tgt_dcache_req[r_tgt_num_cache].read(),(uint32_t)r_tgt_dcache_rsp[r_tgt_num_cache].read());
-          for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
-            PRINTF("      * <TGT> icache[%d] : %d - %d\n",(uint32_t)num_cache, (uint32_t)r_tgt_icache_req[num_cache].read(),(uint32_t)r_tgt_icache_rsp[num_cache].read());
-
-          bool tgt_icache_req;
-                    
-#if   (CC_XCACHE_WRAPPER_MULTI_CACHE==1)
-          tgt_icache_req = r_tgt_icache_req[r_tgt_num_cache].read();
-#elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2)
-          tgt_icache_req = false;
-          for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
-            tgt_icache_req |= r_tgt_icache_req[num_cache].read();
-#endif
-          if (not tgt_icache_req and not r_tgt_dcache_req[r_tgt_num_cache].read()) 
-            {
-              bool     tgt_icache_rsp;
-              uint32_t tgt_icache_rsp_num_cache;
-                        
-#if   (CC_XCACHE_WRAPPER_MULTI_CACHE==1)
-              tgt_icache_rsp_num_cache = r_tgt_num_cache;
-              tgt_icache_rsp = r_tgt_icache_rsp[r_tgt_num_cache].read();
-#elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2)
-              tgt_icache_rsp_num_cache = 0;
-              for (;tgt_icache_rsp_num_cache<m_nb_icache; ++tgt_icache_rsp_num_cache)
-                {
-                  PRINTF("      * <TGT> icache[%d] : %d\n",(uint32_t)tgt_icache_rsp_num_cache, (uint32_t)r_tgt_icache_rsp[tgt_icache_rsp_num_cache].read());
-                            
-                  if (r_tgt_icache_rsp[tgt_icache_rsp_num_cache].read())
-                    break;
-                }
-
-              tgt_icache_rsp = (tgt_icache_rsp_num_cache<m_nb_icache);
-#endif
-
-              PRINTF("      * <TGT> icache_rsp [%d] : %d\n",tgt_icache_rsp_num_cache,(uint32_t) tgt_icache_rsp);
-              PRINTF("      * <TGT> dcache_rsp [%d] : %d\n",(uint32_t)r_tgt_num_cache,(uint32_t) r_tgt_dcache_rsp[r_tgt_num_cache]);
-
-              if (tgt_icache_rsp or r_tgt_dcache_rsp[r_tgt_num_cache])
-                {
-                  // Have send one response
-                  if ( p_vci_tgt.rspack.read())
-                    {
-                      // reset dcache if activated
-                      if (r_tgt_dcache_rsp[r_tgt_num_cache])
-                        r_tgt_dcache_rsp[r_tgt_num_cache] = false;
-                      else
-                        // reset one icache
-                        r_tgt_icache_rsp[tgt_icache_rsp_num_cache] = false;
-                    }
-                }
-
-              // // one response
-              // if ( not r_tgt_icache_rsp[r_tgt_num_cache] or not r_tgt_dcache_rsp[r_tgt_num_cache] )
-              // {
-              //     if ( p_vci_tgt.rspack.read() )
-              //     {
-              //         r_vci_tgt_fsm = TGT_IDLE; 
-              //         r_tgt_icache_rsp[r_tgt_num_cache] = false;
-              //         r_tgt_dcache_rsp[r_tgt_num_cache] = false;
-              //     }
-              // }
-                        
-              // // if data and instruction have the inval line, need two responses  
-              // if ( r_tgt_icache_rsp[r_tgt_num_cache] and r_tgt_dcache_rsp[r_tgt_num_cache] )
-              // {
-              //     if ( p_vci_tgt.rspack.read() )
-              //     {
-              //         r_tgt_icache_rsp[r_tgt_num_cache] = false; // only reset one for respond the second time 
-              //     }
-              // }
-
-              PRINTF("      * <TGT> icache_rsp    : %d\n",(uint32_t) r_tgt_icache_rsp[r_tgt_num_cache]);
-              PRINTF("      * <TGT> dcache_rsp[%d] : %d\n",(uint32_t)r_tgt_num_cache,(uint32_t)r_tgt_dcache_rsp[r_tgt_num_cache].read());
-              // if there is no need for a response
-              if (not tgt_icache_rsp and not r_tgt_dcache_rsp[r_tgt_num_cache] )
-                {
-                  r_vci_tgt_fsm = TGT_IDLE;
-                }
-                        
-            }
-          break;
-        }
-        ////////////////////
-      case TGT_RSP_ICACHE:
-        {
-          bool transaction_rsp = (p_vci_tgt.rspack.read() or not r_tgt_icache_rsp[r_tgt_num_cache].read()) and not r_tgt_icache_req[r_tgt_num_cache].read();
-
-          PRINTF("      * <TGT> RSP_ICACHE : transaction : %d ((%d or not %d) and not %d)\n",transaction_rsp
-                 ,(int)p_vci_tgt.rspack.read()
-                 ,(int)r_tgt_icache_rsp[r_tgt_num_cache].read()
-                 ,(int)r_tgt_icache_req[r_tgt_num_cache].read()
-                 );
-
-          if (transaction_rsp) 
-            {
-              r_vci_tgt_fsm = TGT_IDLE;
-              r_tgt_icache_rsp[r_tgt_num_cache] = false; 
-            }
-          break;
-        }
-
-      case TGT_RSP_DCACHE:
-        {
-          bool transaction_rsp = (p_vci_tgt.rspack.read() or not r_tgt_dcache_rsp[r_tgt_num_cache].read()) and not r_tgt_dcache_req[r_tgt_num_cache].read();
-
-          PRINTF("      * <TGT> RSP_DCACHE : transaction : %d\n",transaction_rsp);
-
-          if (transaction_rsp) 
-            {
-              r_vci_tgt_fsm = TGT_IDLE;
-              r_tgt_dcache_rsp[r_tgt_num_cache] = false; 
-            }
-          break;
-        }
-      } // end switch TGT_FSM
-
-        /////////////////////////////////////////////////////////////////////
-        // Interface between CPU and CACHE FSM
-        ///////////////////////////////////////////////////////////////////////
-
-      uint32_t ireq_num_cache [m_nb_cpu];
-      uint32_t dreq_num_cache [m_nb_cpu];
-      bool     have_sync = false;
-
-      {
-        typename iss_t::InstructionRequest _ireq = ISS_IREQ_INITIALIZER;
-        typename iss_t::DataRequest        _dreq = ISS_DREQ_INITIALIZER;
-
-        for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
-          {
-            ireq [num_cache] = _ireq;
-            //irsp [num_cache] = _irsp;
-          }
-        for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
-          {
-            dreq [num_cache] = _dreq;
-            //drsp [num_cache] = _drsp;
-                
-            have_sync |= r_dcache_sync [num_cache];
-          }
-      }
-
-      for (uint32_t _num_cpu=0; _num_cpu<m_nb_cpu; ++_num_cpu)
-        {
-          // round robin priority
-          uint32_t num_cpu = (r_cpu_prior+_num_cpu)%m_nb_cpu;
-
-          typename iss_t::InstructionRequest _ireq = ISS_IREQ_INITIALIZER;
-          typename iss_t::DataRequest        _dreq = ISS_DREQ_INITIALIZER;
-            
-          m_iss[num_cpu]->getRequests(_ireq, _dreq);
-
-          addr_40  addr;
-          uint32_t num_cache;
-
-          addr      = (addr_40)_ireq.addr;
-          num_cache = get_num_icache(addr,num_cpu);
-
-          bool icache_req_valid = ((not ireq[num_cache].valid and               // no previous request in this cycle
-                                    (r_icache_lock [num_cache] == m_nb_cpu)) or // no previous request in previous cycle
-                                   (r_icache_lock [num_cache] == num_cpu));     // previous request in previous cycle by this cpu
-
-          if (icache_req_valid)
-            {
-              bool valid = _ireq.valid;
-
-              if (valid)
-                {
-                  PRINTF("    * <CPU2CACHE> ICACHE :    Transaction between cpu %d and cache %d (lock)\n",num_cpu,num_cache);
-                  ireq_num_cache [num_cpu  ] = num_cache;
-                  r_icache_lock [num_cache] = num_cpu;
-                }
-              else
-                {
-                  PRINTF("    * <CPU2CACHE> ICACHE : No Transaction between cpu %d and cache %d : invalid\n",num_cpu,num_cache);
-                  ireq_num_cache [num_cpu] = m_nb_icache;
-                }
-
-              ireq_cached    [num_cache] = m_cacheability_table[(vci_addr_t)_ireq.addr];
-              ireq_num_cpu   [num_cache] = num_cpu;
-              ireq           [num_cache] = _ireq;
-              ireq           [num_cache].addr = addr;
-            }
-          else
-            {
-              PRINTF("    * <CPU2CACHE> ICACHE : No transaction (cpu %d)\n",num_cpu);
-
-              ireq_num_cache [num_cpu] = m_nb_icache;
-            }
-
-          addr      = (addr_40)_dreq.addr;
-          num_cache = get_num_dcache(addr);
-            
-
-          bool dcache_no_lock      = (r_dcache_lock [num_cache] == m_nb_cpu);
-          bool dcache_lock_owner   = (r_dcache_lock [num_cache] == num_cpu);
-          bool dcache_lock_no_owner= not dcache_no_lock and not dcache_lock_owner;
-          bool dcache_req_valid;
-
-          // multi cache : hit after miss)
-          if (m_nb_dcache > 0)
-          {
-              bool dcache_wait         = ((r_dcache_fsm[num_cache] == DCACHE_MISS_WAIT)//  or
-                                          // (r_dcache_fsm[num_cache] == DCACHE_UNC_WAIT) or
-                                          // (r_dcache_fsm[num_cache] == DCACHE_SC_WAIT)
-                                          );
-
-              dcache_req_valid = ((not dreq[num_cache].valid and               // no previous request in this cycle
-                                   not have_sync and                           // no sync instruction
-                                   (dcache_no_lock or
-                                    (dcache_lock_no_owner and dcache_wait))) or // no previous request in previous cycle
-                                  (dcache_lock_owner and not dcache_wait));     // previous request in previous cycle by this cpu
-          }
-          else
-          {
-              dcache_req_valid = ((not dreq[num_cache].valid and // no previous request in this cycle
-                                   not have_sync and             // no sync instruction
-                                   dcache_no_lock) or            // no previous request in previous cycle
-                                  dcache_lock_owner);            // previous request in previous cycle by this cpu
-          }
-
-          // test if already used
-          if (dcache_req_valid)
-            {
-              bool valid = _dreq.valid;
-
-              if (valid)
-                {
-                  PRINTF("    * <CPU2CACHE> DCACHE :    Transaction between cpu %d and cache %d (lock)\n",num_cpu,num_cache);
-                  dreq_num_cache [num_cpu  ] = num_cache;
-                  
-                  // always lock if no multi cache
-                  if ((m_nb_dcache == 1) or (not dcache_lock_no_owner))
-                    r_dcache_lock [num_cache] = num_cpu;
-                }
-              else
-                {
-                  PRINTF("    * <CPU2CACHE> DCACHE : No Transaction between cpu %d and cache %d : invalid\n",num_cpu,num_cache);
-                  dreq_num_cache [num_cpu] = m_nb_dcache;
-                }
-
-              dreq_cached    [num_cache] = m_cacheability_table[(vci_addr_t)_dreq.addr];
-              dreq_num_cpu   [num_cache] = num_cpu;
-              dreq           [num_cache] = _dreq;
-              dreq           [num_cache].addr = addr;
-            }
-          else
-            {
-              PRINTF("    * <CPU2CACHE> DCACHE : No transaction (cpu %d)\n",num_cpu);
-
-              dreq_num_cache [num_cpu] = m_nb_dcache;
-            }
-
-
-#if CC_XCACHE_WRAPPER_DEBUG
-          if (m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN)
-            {
-              std::cout << "    * <CPU2CACHE> Instruction Request   : " << ireq_num_cache[num_cpu] << " - " << _ireq << std::endl
-                        << "    * <CPU2CACHE> Data        Request   : " << dreq_num_cache[num_cpu] << " - " << _dreq << std::endl;
-            }
-#endif
-        }
-
-      // round robin priority
-      r_cpu_prior = (r_cpu_prior+1)%m_nb_cpu;
-
-      /////////////////////////////////////////////////////////////////////
-      // The ICACHE FSM controls the following ressources:
-      // - r_icache_fsm
-      // - r_icache_fsm_save
-      // - r_icache instruction cache access
-      // - r_icache_addr_save
-      // - r_icache_miss_req set
-      // - r_icache_unc_req set
-      // - r_icache_buf_unc_valid set
-      // - r_vci_rsp_icache_miss_ok reset
-      // - r_vci_rsp_ins_error reset
-      // - r_tgt_icache_req reset
-      // - ireq & irsp structures for communication with the processor
-      //
-      // 1/ External requests (update or invalidate) have highest priority.
-      //    They are taken into account in the IDLE and WAIT states.
-      //    As external hit should be extremly rare on the ICACHE,
-      //    all external requests are handled as invalidate...
-      //    In case of external request the ICACHE FSM goes to the CC_CHECK
-      //    state to test the external hit, and returns in the
-      //    pre-empted state after completion.
-      // 2/ Processor requests are taken into account only in the IDLE state.
-      //    In case of MISS, or in case of uncached instruction, the FSM 
-      //    writes the missing address line in the  r_icache_addr_save register 
-      //    and sets the r_icache_miss_req or the r_icache_unc_req flip-flops.
-      //    These request flip-flops are reset by the VCI_RSP FSM
-      //    when the VCI transaction is completed and the r_icache_buf_unc_valid
-      //    is set in case of uncached access.
-      //    In case of bus error, the VCI_RSP FSM sets the r_vci_rsp_ins_error 
-      //    flip-flop. It is reset by the ICACHE FSM.
-      ///////////////////////////////////////////////////////////////////////
-        
-      for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
-        {
-          typename iss_t::InstructionRequest  _ireq = ireq [num_cache];
-          typename iss_t::InstructionResponse _irsp = ISS_IRSP_INITIALIZER;
-
-          switch(r_icache_fsm[num_cache]) {
-            /////////////////
-          case ICACHE_IDLE:
-            {
-              if ( r_tgt_icache_req[num_cache] ) {   // external request
-                // if ( _ireq.valid ) m_cost_ins_miss_frz++;
-                r_icache_fsm     [num_cache] = ICACHE_CC_CHECK;
-                r_icache_fsm_save[num_cache] = r_icache_fsm[num_cache];
-                break;
-              } 
-              if ( _ireq.valid ) {
-                data_t   icache_ins         = 0;
-                bool     icache_hit         = false;
-                bool     icache_cached      = ireq_cached  [num_cache];
-                // uint32_t icache_num_cpu     = ireq_num_cpu [num_cache];
-                bool     icache_cleanup_hit = r_icache_cleanup_req[num_cache] and (((addr_40)_ireq.addr >> (addr_40)m_icache_words_shift) == r_icache_cleanup_line[num_cache].read());
-
-                // icache_hit & icache_ins evaluation
-                if ( icache_cached ) {
-                  icache_hit = r_icache[num_cache]->read((vci_addr_t) _ireq.addr, &icache_ins);
-                } else {
-                  // if uncache, again in the vci_rsp_fifo_icache
-                  icache_hit = (r_icache_buf_unc_valid[num_cache] and 
-                                ((addr_40) _ireq.addr == (addr_40)r_icache_addr_save[num_cache]));
-                  
-                  // Test if top of fifo_rsp is for this cache is in ICACHE_UNC_WAIT
-                  icache_ins = r_vci_rsp_fifo_icache_data.read();
-
-                  if (icache_hit)
-                      vci_rsp_fifo_icache_get = true;
-                }
-
-                PRINTF("    * <ICACHE [%d]> hit %d - cached %d - cleanup_hit %d\n",num_cache, icache_hit, icache_cached, icache_cleanup_hit);
-
-                if (icache_hit and icache_cleanup_hit)
-                  {
-                    PRINTF("    * <ICACHE [%d]> Warning : icache hit and icache_cleanup_hit\n",num_cache);
-                    icache_hit = false;
-                  }
-                else
-                  {
-                    if ( not icache_hit and not icache_cleanup_hit) 
-                      {
-                              
-                        m_cpt_ins_miss++;
-                        m_cost_ins_miss_frz++;
-                                
-                        r_icache_addr_save[num_cache] = (addr_40) _ireq.addr;
-
-                        if ( icache_cached )
-                          {
-                            // to prevent deadlock, miss victim don't be block
-                            if (not r_icache_cleanup_req[num_cache])
-                              {
-                                r_icache_fsm     [num_cache] = ICACHE_MISS_VICTIM;
-                                r_icache_miss_req[num_cache] = true;
-                              }
-                            else
-                              m_cpt_icache_miss_victim_wait [num_cache] ++;
-                          }
-                        else
-                          {
-                            r_icache_addr_save[num_cache] = (addr_40) _ireq.addr;
-
-                            r_icache_fsm    [num_cache] = ICACHE_UNC_WAIT;
-                            r_icache_unc_req[num_cache] = true;
-                          }
-                      }
-                    else
-                      {
-                        //     icache_hit and not icache_cleanup_hit
-                        // not icache_hit and     icache_cleanup_hit
-
-                        // request accepted, inval the buf unc
-
-                        r_icache_buf_unc_valid[num_cache] = false;
-                      }
-                    m_cpt_icache_dir_read += m_icache_ways;
-                    m_cpt_icache_data_read += m_icache_ways;
-                  }
-
-                _irsp.valid          = icache_hit;
-                _irsp.instruction    = icache_ins;
+                  r_tgt_dcache_req = false;
+                  r_tgt_dcache_rsp = true;
+                  r_dcache_fsm     = r_dcache_fsm_save.read();
               }
               break;
-            }
-            //////////////////////
-          case ICACHE_MISS_VICTIM:
-            {
-              // if (not r_icache_cleanup_req[num_cache])
-              {
-                size_t     way;
-                size_t     set;
-                vci_addr_t addr = (vci_addr_t) r_icache_addr_save[num_cache].read();
-                vci_addr_t victim;
-                        
-                r_icache_cleanup_req [num_cache] = r_icache[num_cache]->victim_select(addr, &victim, &way, &set );
-                r_icache_cleanup_line[num_cache] = (addr_40) victim;
-                r_icache_miss_way    [num_cache] = way;
-                r_icache_miss_set    [num_cache] = set;
-                        
-                r_icache_fsm         [num_cache] = ICACHE_MISS_WAIT;
-              }
-              break;
-            }
-            //////////////////////
-          case ICACHE_MISS_WAIT:
-            {
-              m_cost_ins_miss_frz++;
-              if ( r_tgt_icache_req[num_cache] ) {   // external request
-                r_icache_fsm      [num_cache] = ICACHE_CC_CHECK;
-                r_icache_fsm_save [num_cache] = r_icache_fsm[num_cache].read();
-                break;
-              }
-
-              bool val = (r_vci_rsp_fifo_icache_data.rok() and
-                          (r_vci_rsp_fifo_icache_num_cache.read() == num_cache));
-
-              PRINTF("    * <ICACHE [%d]> val                  : %d\n",num_cache,val);
-
-              if (val)
-                {
-                  PRINTF("    * <ICACHE [%d]> r_icache_inval_rsp   : %d\n",num_cache,(int) r_icache_inval_rsp  [num_cache]);
-                  PRINTF("    * <ICACHE [%d]> r_vci_rsp_ins_error  : %d\n",num_cache,(int) r_vci_rsp_ins_error [num_cache]);
-                  PRINTF("    * <ICACHE [%d]> r_icache_cleanup_req : %d\n",num_cache,(int) r_icache_cleanup_req[num_cache]);
-
-                  // Miss read response and no invalidation
-                  if ( r_vci_rsp_ins_error [num_cache]) {
-                    r_icache_fsm[num_cache] = ICACHE_ERROR;
-                  } else {
-                    r_icache_update_addr[num_cache] = 0;
-                    r_icache_fsm        [num_cache] = ICACHE_MISS_UPDT;
-                  }
-                }
-              break;
-            }
-            /////////////////////
-          case ICACHE_UNC_WAIT:
-            {
-              m_cost_ins_miss_frz++;
-              if ( r_tgt_icache_req[num_cache] ) {   // external request
-                r_icache_fsm     [num_cache] = ICACHE_CC_CHECK;
-                r_icache_fsm_save[num_cache] = r_icache_fsm[num_cache].read();
-                break;
-              }
-
-              bool ok = (r_vci_rsp_fifo_icache_data.rok() and
-                         (r_vci_rsp_fifo_icache_num_cache.read() == num_cache));
-
-              PRINTF("    * <ICACHE [%d]> ok                   : %d\n",num_cache,ok);
-              PRINTF("    * <ICACHE [%d]> error                : %d\n",num_cache,(uint32_t)r_vci_rsp_ins_error [num_cache]);
-
-              if (ok)
-                {
-                  if ( r_vci_rsp_ins_error [num_cache]) {
-                    r_icache_fsm[num_cache] = ICACHE_ERROR;
-                  } else {
-                    r_icache_fsm [num_cache] = ICACHE_IDLE;
-                    r_icache_buf_unc_valid[num_cache] = true;
-                  }
-                }
-              break;
-            }
-            //////////////////
-          case ICACHE_ERROR:
-            {
-              if ( (addr_40)_ireq.addr == (addr_40)r_icache_addr_save[num_cache] ) {
-                _irsp.error          = true;
-                _irsp.valid          = true;
-              }
-              r_icache_fsm        [num_cache] = ICACHE_IDLE;
-              r_vci_rsp_ins_error [num_cache] = false;
-              break;
-            }
-            //////////////////////
-          case ICACHE_MISS_UPDT: 
-            {
-              size_t     word =              r_icache_update_addr[num_cache].read();
-              vci_addr_t addr = (vci_addr_t) r_icache_addr_save  [num_cache].read();
-              size_t     way  = r_icache_miss_way[num_cache].read();
-              size_t     set  = r_icache_miss_set[num_cache].read();
-
-              bool val = (r_vci_rsp_fifo_icache_data.rok() and
-                          (r_vci_rsp_fifo_icache_num_cache.read() == num_cache));
-
-              if (val)
-                {
-                  PRINTF("    * <ICACHE [%d]> rsp_val            : %d/%d\n",num_cache,(int)r_icache_update_addr[num_cache],(int)m_icache_words);
-                  PRINTF("    * <ICACHE [%d]> r_icache_inval_rsp : %d\n"   ,num_cache,(int)r_icache_inval_rsp[num_cache]);
-                  PRINTF("    * <ICACHE [%d]> ins                : %x\n"   ,num_cache,(int)r_vci_rsp_fifo_icache_data.read());
-                  // m_cpt_icache_dir_write++;
-                  // m_cpt_icache_data_write++;
-                  // if ( _ireq.valid ) m_cost_ins_miss_frz++;
-
-                  // if need invalid rsp, don't modify the cache, but pop the buf_rsp
-                  if (not r_icache_inval_rsp[num_cache])
-                      r_icache[num_cache]->write(way, set, word, r_vci_rsp_fifo_icache_data.read());
-
-                  vci_rsp_fifo_icache_get = true;
-
-                  r_icache_update_addr[num_cache] = ++word;
-                            
-                  // if last word, finish the update
-                  if (word >= m_icache_words)
+          }
+    } // end switch r_dcache_fsm
+        
+    // save the DREQ and DRSP fields for the print_trace() function
+    m_dreq_valid = dreq.valid;
+    m_dreq_addr  = dreq.addr;
+    m_dreq_mode  = dreq.mode;
+    m_dreq_type  = dreq.type;
+    m_dreq_wdata = dreq.wdata;
+    m_dreq_be    = dreq.be;
+    
+    m_drsp_valid = drsp.valid;
+    m_drsp_rdata = drsp.rdata;
+    m_drsp_error = drsp.error;
+
+    ////////// write buffer state update  ////////////////////////////////////////////
+    // The update() method must be called at each cycle to update the internal state.
+
+    r_wbuf->update ();
+
+    /////////// test processor frozen /////////////////////////////////////////////
+    // The simulation exit if the number of consecutive frozen cycles
+    // is larger than the m_max_frozen_cycles (constructor parameter)
+    if ( (ireq.valid and not irsp.valid) or (dreq.valid and not drsp.valid) )       
+    {
+        m_cpt_frz_cycles++;         // used for instrumentation
+        m_cpt_stop_simulation++;    // used for processor stop if frozen
+        if ( m_cpt_stop_simulation > m_max_frozen_cycles )
+        {
+            std::cout << std::dec << "ERROR in CC_XCACHE_WRAPPER " << name()
+                      << " frozen since cycle " << m_cpt_total_cycles - m_max_frozen_cycles 
+                      << std::endl;
+            exit(1);
+        }
+    }
+    else
+    {
+        m_cpt_stop_simulation = 0;
+    }
+
+    /////////// execute one iss cycle /////////////////////////////////////////////
+
+    uint32_t it = 0;
+    for (size_t i=0; i<(size_t)iss_t::n_irq; i++) if ( p_irq[i].read() ) it |= (1<<i);
+                
+    r_iss->executeNCycles(1, irsp, drsp, it);
+
+    ////////////////////////////////////////////////////////////////////////////////
+    // The CLEANUP FSM send the cleanup commands on the coherence network,
+    // and supports simultaneous cleanup transactions, but two simultaneous
+    // transactions mut address different cache lines.
+    // Therefore, the line number is registered in an associative
+    // registration buffer (Content Adressable Memory) by the CLEANUP FSM,
+    // and the corresponding slot (identified by the VCI TRDID field) is cleared 
+    // when the cleanup transaction response is received.
+    // It handles cleanup requests from both the DCACHE FSM & ICACHE FSM
+    // with a round robin priority, and can support up to 16 simultaneous 
+    // cleanup transactions (16 slots in the registration buffer).
+    // The r_dcache_cleanup_req (or r_icache_cleanup_req) flip-flops are reset
+    // when the command has been sent.
+    // The VCI TRDID field is used to distinguish data/instruction cleanups:
+    // - if data cleanup        : TRDID = 2*index + 0
+    // - if instruction cleanup : TRDID = 2*index + 1
+    ////////////////////////////////////////////////////////////////////////////
+
+    switch ( r_cleanup_fsm.read() ) 
+    {
+        ///////////////////////
+        case CLEANUP_DATA_IDLE:     // dcache has highest priority
+        {
+            size_t  index = 0;
+            bool    ok;
+            if ( r_dcache_cleanup_req.read() )      // dcache request
+            {
+                ok = r_cleanup_buffer.register_value( r_dcache_cleanup_line.read(), 
+                                                      &index );   
+                if ( ok )   // successful registration
+                {
+                    r_cleanup_fsm   = CLEANUP_DATA_GO; 
+                    r_cleanup_trdid = index<<1;
+                }
+            }
+            else if ( r_icache_cleanup_req.read() ) // icache request
+            {
+                ok = r_cleanup_buffer.register_value( r_icache_cleanup_line.read(), 
+                                                      &index );   
+                if ( ok )   // successful registration
+                {
+                    r_cleanup_fsm   = CLEANUP_INS_GO; 
+                    r_cleanup_trdid = index<<1 + 1;
+                }
+            }
+            break;
+        }
+        //////////////////////
+        case CLEANUP_INS_IDLE:     // icache has highest priority
+        {
+            size_t  index = 0;
+            bool    ok;
+            if ( r_icache_cleanup_req.read() )      // icache request
+            {
+                ok = r_cleanup_buffer.register_value( r_icache_cleanup_line.read(),
+                                                      &index );   
+                if ( ok )   // successful registration
+                {
+                    r_cleanup_fsm   = CLEANUP_INS_GO;
+                    r_cleanup_trdid = index<<1 + 1;
+                }
+            }
+            else if ( r_dcache_cleanup_req.read() ) // dcache request
+            {
+                ok = r_cleanup_buffer.register_value( r_dcache_cleanup_line.read(),
+                                                      &index );   
+                if ( ok )   // successful registration
+                {
+                    r_cleanup_fsm   = CLEANUP_DATA_GO;
+                    r_cleanup_trdid = index<<1;
+                }
+            }
+            break;
+        }
+        /////////////////////
+        case CLEANUP_DATA_GO:
+        {
+            if ( p_vci_ini_c.cmdack.read() )
+            {
+                r_dcache_cleanup_req = false;
+                r_cleanup_fsm    = CLEANUP_INS_IDLE;
+            }
+        }
+        ////////////////////////
+        case CLEANUP_INS_GO:
+        {
+            if ( p_vci_ini_c.cmdack.read() )
+            {
+                r_icache_cleanup_req = false;
+                r_cleanup_fsm    = CLEANUP_DATA_IDLE;
+            }
+        }
+    } // end switch CLEANUP FSM
+
+    //////////////// Handling  cleanup responses //////////////////
+    if ( p_vci_ini_c.rspval.read() )    // valid response
+    {
+        r_cleanup_buffer.cancel_index( p_vci_ini_c.rtrdid.read() >> 1);
+    }
+
+    ////////////////////////////////////////////////////////////////////////////
+    // The VCI_CMD FSM controls the following ressources:
+    // - r_vci_cmd_fsm
+    // - r_vci_cmd_min
+    // - r_vci_cmd_max
+    // - r_vci_cmd_cpt
+    // - r_vci_cmd_imiss_prio
+    // - wbuf (reset)
+    // - r_icache_miss_req (reset)
+    // - r_icache_unc_req (reset)
+    // - r_dcache_miss_req (reset)
+    // - r_dcache_unc_req (reset)
+    // - r_dcache_sc_req (reset)
+    //
+    // This FSM handles requests from both the DCACHE FSM & the ICACHE FSM.
+    // There is 6 request types, with the following priorities : 
+    // 1 - Data Read Miss         : r_dcache_miss_req and miss in the write buffer
+    // 2 - Data Read Uncacheable   : r_dcache_unc_req  
+    // 3 - Instruction Miss       : r_icache_miss_req and miss in the write buffer
+    // 4 - Instruction Uncacheable : r_icache_unc_req 
+    // 5 - Data Write             : r_wbuf.rok()      
+    // 6 - Data Store Conditionnal: r_dcache_sc_req
+    //
+    // As we want to support several simultaneous VCI transactions, the VCI_CMD_FSM 
+    // and the VCI_RSP_FSM are fully desynchronized.
+    //
+    // VCI formats:
+    // According to the VCI advanced specification, all read requests packets 
+    // (data Uncached, Miss data, instruction Uncached, Miss instruction) 
+    // are one word packets.
+    // For write burst packets, all words are in the same cache line,
+    // and addresses must be contiguous (the BE field is 0 in case of "holes").
+    // The sc command packet implements actually a compare-and-swap mechanism
+    // and the packet contains two flits. 
+    //////////////////////////////////////////////////////////////////////////////
+
+    switch ( r_vci_cmd_fsm.read() ) 
+    {
+        //////////////
+        case CMD_IDLE:
+        {
+            // r_dcache_miss_req and r_icache_miss_req require both a write_buffer access 
+            // to check a possible pending write on the same cache line. 
+            // As there is only one possible access per cycle to write buffer, we implement 
+            // a round-robin priority for this access, using the r_vci_cmd_imiss_prio flip-flop.
+
+            size_t	wbuf_min;
+            size_t	wbuf_max;
+
+            bool dcache_miss_req = r_dcache_miss_req.read() 
+                 and ( not r_icache_miss_req.read() or not r_vci_cmd_imiss_prio.read() );
+            bool icache_miss_req = r_icache_miss_req.read() 
+                 and ( not r_dcache_miss_req.read() or r_vci_cmd_imiss_prio.read() );
+
+            // 1 - Data Read Miss
+            if ( dcache_miss_req and r_wbuf->miss(r_dcache_addr_save.read()) )
+            { 
+                r_vci_cmd_fsm        = CMD_DATA_MISS;
+                r_dcache_miss_req    = false;
+                r_vci_cmd_imiss_prio = true;
+                m_cpt_dmiss_transaction++; 
+            } 
+            // 2 - Data Read Uncacheable
+            else if ( r_dcache_unc_req.read() )
+            { 
+                r_vci_cmd_fsm    = CMD_DATA_UNC;
+                r_dcache_unc_req = false;
+                m_cpt_dunc_transaction++; 
+            }
+            // 3 - Instruction Miss
+            else if ( icache_miss_req and r_wbuf->miss(r_icache_addr_save.read()) )
+            {
+                r_vci_cmd_fsm        = CMD_INS_MISS; 
+                r_icache_miss_req    = false;
+                r_vci_cmd_imiss_prio = false;
+                m_cpt_imiss_transaction++;
+            } 
+            // 4 - Instruction Uncacheable
+            else if ( r_icache_unc_req.read() )
+            { 
+                r_vci_cmd_fsm    = CMD_INS_UNC; 
+                r_icache_unc_req = false;
+                m_cpt_iunc_transaction++;
+            }
+            // 5 - Data Write
+            else if ( r_wbuf->rok(&wbuf_min, &wbuf_max) )
+            { 
+                r_vci_cmd_fsm       = CMD_DATA_WRITE;
+                r_vci_cmd_cpt       = wbuf_min;
+                r_vci_cmd_min       = wbuf_min;
+                r_vci_cmd_max       = wbuf_max;
+                m_cpt_write_transaction++; 
+                m_length_write_transaction += (wbuf_max-wbuf_min+1); 
+            } 
+            // 6 - Data Store Conditionnal
+            else if ( r_dcache_sc_req.read() )
+            { 
+                r_vci_cmd_fsm       = CMD_DATA_SC;
+                r_dcache_sc_req = false;
+                r_vci_cmd_cpt       = 0;
+                m_cpt_sc_transaction++; 
+            }
+            break;
+        }
+        ////////////////////
+        case CMD_DATA_WRITE:
+        {
+            if ( p_vci_ini_d.cmdack.read() ) 
+            {
+                m_conso_wbuf_read++;
+                r_vci_cmd_cpt = r_vci_cmd_cpt + 1;
+                if (r_vci_cmd_cpt == r_vci_cmd_max) // last flit sent
+                {
+                    r_vci_cmd_fsm = CMD_IDLE ;
+                    r_wbuf->sent() ;
+                }
+            }
+            break;
+        }
+        /////////////////
+        case CMD_DATA_SC:
+        {
+            // The SC VCI command contains two flits
+            if ( p_vci_ini_d.cmdack.read() ) 
+            {
+               r_vci_cmd_cpt = r_vci_cmd_cpt + 1;
+               if (r_vci_cmd_cpt == 1) r_vci_cmd_fsm = CMD_IDLE ;
+            }
+            break;
+        }
+        //////////////////
+        case CMD_INS_MISS:
+        case CMD_INS_UNC:
+        case CMD_DATA_MISS:
+        case CMD_DATA_UNC:
+        {
+            // all read VCI commands contain one single flit
+            if ( p_vci_ini_d.cmdack.read() )  r_vci_cmd_fsm = CMD_IDLE; 
+            break;
+        }
+
+    } // end  switch r_vci_cmd_fsm
+
+    ///////////////////////////////////////////////////////////////////////////////
+    // The VCI_RSP FSM controls the following ressources:
+    // - r_vci_rsp_fsm:
+    // - r_vci_rsp_fifo_icache (push)
+    // - r_vci_rsp_fifo_dcache (push)
+    // - r_vci_rsp_data_error (set)
+    // - r_vci_rsp_ins_error (set)
+    // - r_vci_rsp_cpt
+    // 
+    // As we support several simultaneous transactions, this FSM uses
+    // the VCI TRDID field to identify the transactions.
+    //
+    // VCI vormat:
+    // This component Rcheks the response packet length and accepts only
+    // single word packets for write response packets. 
+    //
+    // Error handling:
+    // This FSM analyzes the VCI error code and signals directly the Write Bus Error. 
+    // In case of Read Data Error, the VCI_RSP FSM sets the r_vci_rsp_data_error 
+    // flip_flop and the error is signaled by the DCACHE FSM.  
+    // In case of Instruction Error, the VCI_RSP FSM sets the r_vci_rsp_ins_error 
+    // flip_flop and the error is signaled by the DCACHE FSM.  
+    // In case of Cleanup Error, the simulation stops with an error message...
+    /////////////////////////////////////////////////////////////////////////////////
+
+    switch ( r_vci_rsp_fsm.read() ) 
+    {
+        //////////////
+        case RSP_IDLE:
+        {
+            if( p_vci_ini_d.rspval.read() )
+            {
+                r_vci_rsp_cpt = 0;
+
+                if ( (p_vci_ini_d.rtrdid.read()>>(vci_param::T-1)) != 0 )
+                {
+                    r_vci_rsp_fsm = RSP_DATA_WRITE;
+                }
+                else if ( p_vci_ini_d.rtrdid.read() == TYPE_INS_MISS )
+                {
+                    r_vci_rsp_fsm = RSP_INS_MISS;
+                }
+                else if ( p_vci_ini_d.rtrdid.read() == TYPE_INS_UNC )
+                {
+                    r_vci_rsp_fsm = RSP_INS_UNC;
+                }
+                else if ( p_vci_ini_d.rtrdid.read() == TYPE_DATA_MISS )
+                {
+                    r_vci_rsp_fsm = RSP_DATA_MISS;
+                }
+                else if ( p_vci_ini_d.rtrdid.read() == TYPE_DATA_UNC )
+                {
+                    r_vci_rsp_fsm = RSP_DATA_UNC;
+                }
+                else
+                {
+                    assert(false and "Unexpected response");
+                }
+            }
+            break;
+        }
+        //////////////////
+        case RSP_INS_MISS:
+        {        
+            if ( p_vci_ini_d.rspval.read() )
+            {
+                if ( (p_vci_ini_d.rerror.read()&0x1) != 0 )  // error reported
+                {
+                    r_vci_rsp_ins_error = true;
+                    if ( p_vci_ini_d.reop.read() ) r_vci_rsp_fsm = RSP_IDLE;
+                }
+                else                                        // no error reported
+                {
+                    if ( r_vci_rsp_fifo_icache.wok() )
                     {
-                      // in all case (inval_rsp or not), update the victim tag
-                      r_icache[num_cache]->victim_update_tag(addr, way, set);
-
-                      // Last word : if previous invalid_rsp, can cleanup, else update the TAG
-                      if (r_icache_inval_rsp[num_cache])
+                        assert( (r_vci_rsp_cpt.read() < m_cache_words) and
+                        "The VCI response packet for instruction miss is too long" );
+
+                        r_vci_rsp_cpt                 = r_vci_rsp_cpt.read() + 1;
+                        vci_rsp_fifo_icache_put       = true,
+                        vci_rsp_fifo_icache_data      = p_vci_ini_d.rdata.read();
+                        if ( p_vci_ini_d.reop.read() ) 
                         {
-                          r_icache_inval_rsp[num_cache] = false;
-                          r_icache_fsm      [num_cache] = ICACHE_CC_CLEANUP;
-                        }
-                      else
-                        {
-                          r_icache_fsm [num_cache] = ICACHE_IDLE;
+                            assert( (r_vci_rsp_cpt.read() == m_cache_words - 1) and 
+                            "The VCI response packet for instruction miss is too short");
+
+                            r_vci_rsp_fsm    = RSP_IDLE;
                         }
                     }
                 }
-
-              break;
-            }
-            ////////////////////
-          case ICACHE_CC_CLEANUP:
-            {
-              // cleanup
-              if(not r_icache_cleanup_req[num_cache]){
-                r_icache_cleanup_req [num_cache] = true;
-                r_icache_cleanup_line[num_cache] = r_icache_addr_save[num_cache].read() >> m_icache_words_shift;
-                r_icache_fsm         [num_cache] = ICACHE_IDLE;
-
-                m_cpt_icache_dir_read += m_icache_ways;
-                r_icache[num_cache]->inval((addr_40)r_icache_addr_save[num_cache]);
-              }
-              break;
-            }
-            /////////////////////
-          case ICACHE_CC_CHECK:   // read directory in case of invalidate or update request
-            {
-
-              m_cpt_icache_dir_read  += m_icache_ways;
-              m_cpt_icache_data_read += m_icache_ways;
-              addr_40 ad = r_tgt_iaddr;
-
-              PRINTF("    * <ICACHE [%d]> CC_CHECK\n",num_cache);
-
-              if((r_icache_fsm_save[num_cache] == ICACHE_MISS_WAIT) and 
-                 ((r_icache_addr_save[num_cache].read() & ~((m_icache_words<<2)-1)) == (ad & ~((m_icache_words<<2)-1)))) {
-                PRINTF("    * <ICACHE [%d]> have request, need inval rsp\n",num_cache);
-
-                r_icache_inval_rsp[num_cache] = true;
-                r_tgt_icache_req  [num_cache] = false;
-                if(r_tgt_update){    // Also send a cleanup and answer
-                  PRINTF("    * <ICACHE [%d]> send a cleanup and answer\n",num_cache);
-                  r_tgt_icache_rsp[num_cache] = true;
-                } else {            // Also send a cleanup but don't answer
-                  PRINTF("    * <ICACHE [%d]> send a cleanup and but don't answer\n",num_cache);
-                  r_tgt_icache_rsp[num_cache] = false;
-                }
-                r_icache_fsm[num_cache] = r_icache_fsm_save[num_cache];
-              } else {
-                uint32_t word       = r_cache_word;
-                data_t   mask       = vci_param::be2mask(r_tgt_be[word]);
-                data_t   rdata      = 0;
-                bool     icache_hit = r_icache[num_cache]->read(ad+word*4,&rdata);
-
-                PRINTF("    * <ICACHE [%d]> have no request, hit cache : %d\n",num_cache,icache_hit);
-
-                if ( icache_hit and r_tgt_update) 
-                  {
-                    // Assumption : We have RAM for icache with write enable on byte.
-                    // Consequence : icache_read is only consultation of directory
-
-                    //if(r_tgt_be[word])
-                    r_icache[num_cache]->write(ad+word*4, (mask & r_tgt_buf[word]) | (~mask & rdata));
-                            
-                    word ++;
-                    
-                    // Find next valid word
-                    for (; word<m_icache_words; ++word)
-                      if (r_tgt_be[word] != 0)
-                        break;
-
-                    if (word==m_icache_words)
-                      {
-                          r_tgt_icache_req[num_cache] = false;
-                          r_tgt_icache_rsp[num_cache] = true;
-                          r_icache_fsm    [num_cache] = r_icache_fsm_save[num_cache].read();
-                          word = 0;
-                      }
-                    r_cache_word = word;
-
-                  } else if ( icache_hit and not r_tgt_update) {
-                  r_icache_fsm[num_cache] = ICACHE_CC_INVAL;
-                } else { // instruction not found (can happen)
-                  r_tgt_icache_req[num_cache] = false;
-                  if(r_tgt_update){
-                    r_tgt_icache_rsp[num_cache] = true;
-                  } else {
-                    r_tgt_icache_rsp[num_cache] = false;
-                  }
-                  r_icache_fsm[num_cache] = r_icache_fsm_save[num_cache];
-                }
-              }
-              break;
-            }
-            /////////////////////
-          case ICACHE_CC_INVAL:  
-            {                       
-              addr_40 ad  = r_tgt_iaddr;
-              // if ( _ireq.valid ) m_cost_ins_miss_frz++;
-              m_cpt_icache_dir_read += m_icache_ways;
-              r_tgt_icache_rsp[num_cache] = true;
-              r_icache[num_cache]->inval(ad);
-              r_tgt_icache_req[num_cache] = false;
-              r_icache_fsm    [num_cache] = r_icache_fsm_save[num_cache];
-              break;
-            }    
-          }// end switch r_icache_fsm
-
-          irsp [num_cache] = _irsp;
-          if (_ireq.valid and _irsp.valid)
-            {
-              PRINTF("    * <CPU2CACHE> Transaction between cpu %d and Icache %d (unlock)\n",r_icache_lock [num_cache].read(),num_cache);
-
-              r_icache_lock       [num_cache] = m_nb_cpu;
-              m_cpt_icache_access [num_cache] ++;
-            }
-
-        }// end for num_cache
-
-      //////////////////////////////////////////////////////////////////////://///////////
-      // The DCACHE FSM controls the following ressources:
-      // - r_dcache_fsm
-      // - r_dcache_fsm_save
-      // - r_dcache (data cache access)
-      // - r_dcache_addr_save
-      // - r_dcache_wdata_save
-      // - r_dcache_rdata_save
-      // - r_dcache_type_save
-      // - r_dcache_be_save
-      // - r_dcache_cached_save
-      // - r_dcache_miss_req set
-      // - r_dcache_unc_req set
-      // - r_dcache_cleanup_req set
-      // - r_vci_rsp_data_error reset
-      // - r_tgt_dcache_req reset
-      // - r_wbuf write
-      // - dreq & drsp structures for communication with the processor
-      //
-      // 1/ EXTERNAL REQUEST : 
-      //    There is an external request when the tgt_dcache req flip-flop is set,
-      //    requesting a line invalidation or a line update. 
-      //    External requests are taken into account in the states  IDLE, WRITE_REQ,  
-      //    UNC_WAIT, MISS_WAIT, and have the highest priority :
-      //    The actions associated to the pre-empted state are not executed, the DCACHE FSM
-      //    goes to the CC_CHECK state to execute the requested action, and returns to the
-      //    pre-empted state.
-      //  2/ PROCESSOR REQUEST : 
-      //   In order to support VCI write burst, the processor requests are taken into account
-      //   in the WRITE_REQ state as well as in the IDLE state.
-      //   - In the IDLE state, the processor request cannot be satisfied if
-      //   there is a cached read miss, or an uncached read.
-      //   - In the WRITE_REQ state, the request cannot be satisfied if
-      //   there is a cached read miss, or an uncached read,
-      //   or when the write buffer is full.
-      //   - In all other states, the processor request is not satisfied.
-      //
-      //   The cache access takes into account the cacheability_table.
-      //   In case of processor request, there is five conditions to exit the IDLE state:
-      //   - CACHED READ MISS => to the MISS_WAIT state (waiting the r_miss_ok signal), 
-      //     then to the MISS_UPDT state, and finally to the IDLE state.
-      //   - UNCACHED READ  => to the UNC_WAIT state (waiting the r_miss_ok signal), 
-      //     and to the IDLE state.
-      //   - CACHE INVALIDATE HIT => to the INVAL state for one cycle, then to IDLE state.
-      //   - WRITE MISS => directly to the WRITE_REQ state to access the write buffer.
-      //   - WRITE HIT => to the WRITE_UPDT state, then to the WRITE_REQ state.
-      //
-      // Error handling :  Read Bus Errors are synchronous events, but
-      // Write Bus Errors are asynchronous events (processor is not frozen).
-      // - If a Read Bus Error is detected, the VCI_RSP FSM sets the
-      //   r_vci_rsp_data_error flip-flop, and the synchronous error is signaled
-      //   by the DCACHE FSM.
-      // - If a Write Bus Error is detected, the VCI_RSP FSM  signals
-      //   the asynchronous error using the setWriteBerr() method.
-      ///////////////////////////////////////////////////////////////////////////////////
-
-      for (uint32_t num_cache=0; num_cache<m_nb_dcache; ++num_cache)
-        {
-          typename iss_t::DataRequest  _dreq = dreq [num_cache];
-          typename iss_t::DataResponse _drsp = ISS_DRSP_INITIALIZER;
-
-          switch ( r_dcache_fsm[num_cache]) {
-
-            /////////////////
-          case DCACHE_IDLE:
-            {
-              if ( r_tgt_dcache_req[num_cache]) {   // external request
-                r_dcache_fsm     [num_cache] = DCACHE_CC_CHECK;
-                r_dcache_fsm_save[num_cache] = r_dcache_fsm[num_cache];
-                break;
-              } 
-
-              if ( _dreq.valid ) {
-                PRINTF("    * <DCACHE [%d]> Have dreq\n",num_cache);
-
-                data_t      dcache_rdata       = 0;
-                // dcache_cached and dcache_hit don't used with _dreq.type == {DATA_SC, XTN_READ, XTN_WRITE}
-                bool        dcache_cached      = dreq_cached  [num_cache];
-                uint32_t    dcache_num_cpu     = dreq_num_cpu [num_cache];
-                bool        dcache_hit         = r_dcache[num_cache]->read((vci_addr_t) _dreq.addr, &dcache_rdata);
-                bool        dcache_cleanup_hit = r_dcache_cleanup_req[num_cache] and (((addr_40)_dreq.addr >> (addr_40)m_dcache_words_shift) == r_dcache_cleanup_line[num_cache].read());
-
-                PRINTF("    * <DCACHE [%d]> hit %d - cached %d - cleanup_hit %d\n",num_cache,dcache_hit, dcache_cached, dcache_cleanup_hit);
-                        
-                m_cpt_dcache_data_read += m_dcache_ways;
-                m_cpt_dcache_dir_read  += m_dcache_ways;
-
-                switch( _dreq.type ) {
-                case iss_t::DATA_READ:
-                case iss_t::DATA_LL:
-                  {
-                    m_cpt_data_read++; // new dcache read
-
-                    if (dcache_hit) // no special test for uncached read, because it's always miss
-                      {
-                        // address is in the cache : return the word
-                        r_dcache_fsm [num_cache] = DCACHE_IDLE;
-
-                        _drsp.valid   = true;
-                        _drsp.rdata   = dcache_rdata; // return read data (cf dcache_hit)
-                                            
-                        // if the request is a Load Linked instruction, save request information
-                        if(_dreq.type == iss_t::DATA_LL)
-                          {
-                            PRINTF("    * <DCACHE [%d]> ll_valid = true\n",num_cache);
-
-                            r_dcache_ll_valid  [num_cache][dcache_num_cpu] = true;
-                            r_dcache_ll_data   [num_cache][dcache_num_cpu] = dcache_rdata;
-                            r_dcache_ll_addr   [num_cache][dcache_num_cpu] = (vci_addr_t) _dreq.addr;
-                          }
-                      }
-                    else
-                      {
-                        if (not dcache_cleanup_hit)
-                          {
-                                                
-                            // Miss : send signal at the CMD_FSM (via r_dcache_miss_req or r_dcache_unc_req)
-                            if ( dcache_cached ) {
-                              // to prevent deadlock, miss victim don't be block
-                              if (not r_dcache_cleanup_req[num_cache].read())
-                                {
-                                  m_cpt_data_read_miss++;
-                                  m_cost_data_miss_frz++;
-                                  r_dcache_miss_req [num_cache] = true;
-                                  r_dcache_fsm [num_cache] = DCACHE_MISS_VICTIM;
-                                }
-                              else
-                                m_cpt_icache_miss_victim_wait [num_cache] ++;
-                            } else {
-                              if (not r_dcache_previous_unc[num_cache].read()) // strongly order to the uncached access
-                                {
-                                  r_dcache_previous_unc[num_cache] = true;
-                                                        
-                                  m_cpt_data_read_uncached++;
-                                  m_cost_unc_read_frz++;
-                                  r_dcache_unc_req[num_cache] = true;
-                                  r_dcache_fsm    [num_cache] = DCACHE_UNC_WAIT;
-                                }
-                            }
-                          }
-                      }
-                  }
-                  break;
-                case iss_t::DATA_SC:
-                  {
-                    PRINTF("    * <DCACHE [%d]> DATA_SC - ll_valid = %d, num_cpu = %d\n",num_cache,r_dcache_ll_valid[num_cache][dcache_num_cpu].read(),dcache_num_cpu);
-
-                    if (not r_dcache_previous_unc[num_cache].read() and not dcache_cleanup_hit) // strongly order to the uncached access
-                      {
-                        //m_cpt_data_read_unc++; // instruction must read the memory in uncached mode
-                        m_cost_unc_read_frz++;
-                                    
-                        // if previous load linked (with the same address), make a transaction
-                        // else, keep in IDLE state and return 1 (no OK)
-                        if( r_dcache_ll_valid[num_cache][dcache_num_cpu].read() and 
-                            (r_dcache_ll_addr [num_cache][dcache_num_cpu].read() == (vci_addr_t)_dreq.addr)){
-                          PRINTF("    * <DCACHE [%d]> have previous load linked\n",num_cache);
-                                        
-                          r_dcache_previous_unc[num_cache] = true;
-                          r_dcache_sc_req      [num_cache] = true;
-
-                          r_dcache_fsm         [num_cache] = DCACHE_SC_WAIT;
-                        } else {
-                          PRINTF("    * <DCACHE [%d]> don't have previous load linked\n",num_cache);
-                                        
-                          _drsp.valid = true;
-                          _drsp.rdata = 1; // SC rsp NOK
-                          r_dcache_ll_valid[num_cache][dcache_num_cpu] = false;
-                        }
-                      }
-
-                    break;
-                  }
-                case iss_t::XTN_READ:
-                case iss_t::XTN_WRITE:
-                  {
-                    bool valid = false;
-                    // only DCACHE INVALIDATE and SYNC request are supported
-                    switch (_dreq.addr>>2)
-                      {
-                      case iss_t::XTN_DCACHE_INVAL : 
+            }
+            break;
+        }
+        /////////////////
+        case RSP_INS_UNC:
+        {
+            if (p_vci_ini_d.rspval.read() )
+            {
+                assert( p_vci_ini_d.reop.read() and
+                "illegal VCI response packet for uncacheable instruction");
+
+                if ( (p_vci_ini_d.rerror.read()&0x1) != 0 )  // error reported
+                {
+                    r_vci_rsp_ins_error = true;
+                    r_vci_rsp_fsm = RSP_IDLE;
+                }
+                else                                         // no error reported
+                {   
+                    if ( r_vci_rsp_fifo_icache.wok())
+                    {
+                        vci_rsp_fifo_icache_put       = true;
+                        vci_rsp_fifo_icache_data      = p_vci_ini_d.rdata.read();
+                        r_vci_rsp_fsm = RSP_IDLE;
+                    }
+                }
+            }
+            break;
+        }
+        ///////////////////
+        case RSP_DATA_MISS:
+        {
+            if ( p_vci_ini_d.rspval.read() )
+            {
+                if ( (p_vci_ini_d.rerror.read()&0x1) != 0 )  // error reported
+                {
+                    r_vci_rsp_data_error = true;
+                    if ( p_vci_ini_d.reop.read() ) r_vci_rsp_fsm = RSP_IDLE;
+                }
+                else                                        // no error reported
+                {
+                    if ( r_vci_rsp_fifo_dcache.wok() )
+                    {
+                        assert( (r_vci_rsp_cpt.read() < m_cache_words) and
+                        "The VCI response packet for data miss is too long");
+
+                        r_vci_rsp_cpt                 = r_vci_rsp_cpt.read() + 1;
+                        vci_rsp_fifo_dcache_put       = true,
+                        vci_rsp_fifo_dcache_data      = p_vci_ini_d.rdata.read();
+                        if ( p_vci_ini_d.reop.read() ) 
                         {
-                          valid = true;
-                          r_dcache_fsm[num_cache] = DCACHE_INVAL;
-                          break;
-                        }
-                      case iss_t::XTN_SYNC :
-                        {
-                          // Test if write buffer is already empty
-                          //  * gain : 1 cycle
-                          //  * cost : can be on the critical path
-
-                          bool empty=true;
-                          for (uint32_t i=0; i<m_nb_dcache; ++i)
-                            empty &= r_wbuf[i]->empty();
-
-                          if (empty)
-                            {
-                              valid = true;
-                              r_dcache_fsm [num_cache] = DCACHE_IDLE;
-                            }
-                          else
-                            {
-                              valid = false;
-                              r_dcache_fsm [num_cache] = DCACHE_SYNC;
-                              r_dcache_sync[num_cache] = true;
-                            }
-                          break;
-                        }
-                      default :
-                        {
-                          // std::cout << "Warning in VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
-                          // std::cout << "Unsupported  external access : " << (_dreq.addr>>2) << std::endl;
-
-                          r_dcache_fsm [num_cache] = DCACHE_IDLE;
-                        }
-                      }//end switch (_dreq.addr>>2)
-
-                    _drsp.valid = valid;
-                    _drsp.rdata = 0;
-                    break;
-                  }
-                case iss_t::DATA_WRITE:
-
-                  PRINTF("    * <DCACHE [%d]> r_dcache_previous_unc : %d\n",num_cache,r_dcache_previous_unc[num_cache].read());
-
-                  if (dcache_cached or not r_dcache_previous_unc[num_cache].read()) // strongly order to the uncached access
-                    {
-                      bool valid;
-                      addr_40 addr = _dreq.addr;
-                      set_num_dcache(addr,num_cache);
-
-                      // FIXME : 
-                      //  * dans le wbuf, ne pas mettre l'adresse au complet (economie de surface)
-                      //  * pour cela, virer le set_num_dcache !
-                      valid = r_wbuf[num_cache]->write(addr, _dreq.be, _dreq.wdata, dcache_cached, dcache_num_cpu);
-
-#if MWBUF_VHDL_TESTBENCH
-                      vhdl_mwbuf_port_write_val        [num_cache] = (vhdl_tb_t)1;
-                      vhdl_mwbuf_test_write_ack        [num_cache] = (vhdl_tb_t)1;
-                      vhdl_mwbuf_port_write_ack        [num_cache] = (vhdl_tb_t)valid;
-                      vhdl_mwbuf_port_write_addr       [num_cache] = (vhdl_tb_t)addr;
-                      vhdl_mwbuf_port_write_data       [num_cache] = (vhdl_tb_t)_dreq.wdata;
-                      vhdl_mwbuf_port_write_be         [num_cache] = (vhdl_tb_t)_dreq.be;
-                      vhdl_mwbuf_port_write_cached     [num_cache] = (vhdl_tb_t)dcache_cached;
-                      vhdl_mwbuf_port_write_cpu_id     [num_cache] = (vhdl_tb_t)dcache_num_cpu;
-#endif
-
-
-                      PRINTF("    * <DCACHE [%d]> r_wbuf valid          : %d\n",num_cache,valid);
-
-                      if (valid)
-                        {
-                          m_cpt_data_write++;
-                                        
-                          if (not dcache_cached)
-                            {
-                                ASSERT(not dcache_hit,
-                                       "Request is uncached, but hit in dcache!");
-
-                              r_dcache_previous_unc[num_cache] = true;
-                              m_cpt_data_write_uncached++;
-                            }
-                          else if (not dcache_hit)
-                            m_cpt_data_write_miss++;
-                                   
-                          if (dcache_hit) {
-                            // update data cache
-                            r_dcache_fsm[num_cache] = DCACHE_WRITE_UPDT;
-                          } else {
-                            // write accepted
-                            r_dcache_fsm [num_cache] = DCACHE_IDLE;
-                          }
-                        }
-
-                      _drsp.valid = valid;
-                      _drsp.rdata = 0;
-                    }
-                  break;
-                } // end switch _dreq.type
-
-                r_dcache_addr_save   [num_cache] = (addr_40) _dreq.addr;
-                r_dcache_type_save   [num_cache] = _dreq.type;
-                r_dcache_wdata_save  [num_cache] = _dreq.wdata;
-                r_dcache_be_save     [num_cache] = _dreq.be;
-                r_dcache_rdata_save  [num_cache] = dcache_rdata;
-                r_dcache_cached_save [num_cache] = dcache_cached;
-                r_dcache_num_cpu_save[num_cache] = dcache_num_cpu;
-    
-              } else {    // end if _dreq.valid
-                r_dcache_fsm [num_cache] = DCACHE_IDLE;
-              }
-                    
-              break;
-            }
-            ///////////////////////
-          case DCACHE_WRITE_UPDT:
-            {
-              m_cpt_dcache_data_write++;
-              data_t     mask  = vci_param::be2mask(r_dcache_be_save[num_cache]);
-              data_t     wdata = (mask & r_dcache_wdata_save[num_cache]) | (~mask & r_dcache_rdata_save[num_cache]);
-              vci_addr_t ad    = r_dcache_addr_save[num_cache].read();
-              r_dcache[num_cache]->write(ad, wdata);
-
-              int dcache_fsm_next = DCACHE_IDLE; // default
-
-              // Test if write after write
-
-              if (_dreq.valid and (_dreq.type == iss_t::DATA_WRITE))
-                {
-                  PRINTF("    * <DCACHE [%d]> Have dreq (Write after Write)\n",num_cache);
-
-                  data_t      dcache_rdata       = 0;
-                  // dcache_cached and dcache_hit don't used with _dreq.type == {DATA_SC, XTN_READ, XTN_WRITE}
-                  bool        dcache_cached      = dreq_cached  [num_cache];
-                  uint32_t    dcache_num_cpu     = dreq_num_cpu [num_cache];
-                  bool        dcache_hit         = r_dcache[num_cache]->read((vci_addr_t) _dreq.addr, &dcache_rdata);
-
-                  m_cpt_dcache_data_read += m_dcache_ways;
-                  m_cpt_dcache_dir_read  += m_dcache_ways;
-
-                  PRINTF("    * <DCACHE [%d]> r_dcache_previous_unc : %d\n",num_cache,r_dcache_previous_unc[num_cache].read());
-                        
-                  if (dcache_cached or not r_dcache_previous_unc[num_cache].read()) // strongly order to the uncached access
-                    {
-                      bool valid;
-                      addr_40 addr = _dreq.addr;
-                      set_num_dcache(addr,num_cache);
-                                
-                      // FIXME : 
-                      //  * dans le wbuf, ne pas mettre l'adresse au complet (economie de surface)
-                      //  * pour cela, virer le set_num_dcache !
-                      valid = r_wbuf[num_cache]->write(addr, _dreq.be, _dreq.wdata, dcache_cached, dcache_num_cpu);
-
-#if MWBUF_VHDL_TESTBENCH
-                      vhdl_mwbuf_port_write_val        [num_cache] = (vhdl_tb_t)1;
-                      vhdl_mwbuf_test_write_ack        [num_cache] = (vhdl_tb_t)1;
-                      vhdl_mwbuf_port_write_ack        [num_cache] = (vhdl_tb_t)valid;
-                      vhdl_mwbuf_port_write_addr       [num_cache] = (vhdl_tb_t)addr;
-                      vhdl_mwbuf_port_write_data       [num_cache] = (vhdl_tb_t)_dreq.wdata;
-                      vhdl_mwbuf_port_write_be         [num_cache] = (vhdl_tb_t)_dreq.be;
-                      vhdl_mwbuf_port_write_cached     [num_cache] = (vhdl_tb_t)dcache_cached;
-                      vhdl_mwbuf_port_write_cpu_id     [num_cache] = (vhdl_tb_t)dcache_num_cpu;
-#endif
-
-                      PRINTF("    * <DCACHE [%d]> r_wbuf valid          : %d\n",num_cache,valid);
-
-                      if (valid)
-                        {
-                          m_cpt_dcache_store_after_store [num_cache] ++;
-                                        
-                          m_cpt_data_write++;
-                                        
-                          if (not dcache_cached)
-                            {
-                              r_dcache_previous_unc[num_cache] = true;
-                              m_cpt_data_write_uncached++;
-                            }
-                          else if (not dcache_hit)
-                            m_cpt_data_write_miss++;
-                                        
-                          if (dcache_hit) {
-                            // update data cache
-                            dcache_fsm_next = DCACHE_WRITE_UPDT;
-                          } else {
-                            // write accepted
-                            dcache_fsm_next = DCACHE_IDLE;
-                          }
-                        }
-                                
-                      _drsp.valid = valid;
-                      _drsp.rdata = 0;
-                    }
-
-                  r_dcache_addr_save   [num_cache] = (addr_40) _dreq.addr;
-               // r_dcache_type_save   [num_cache] = _dreq.type;
-                  r_dcache_wdata_save  [num_cache] = _dreq.wdata;
-                  r_dcache_be_save     [num_cache] = _dreq.be;
-                  r_dcache_rdata_save  [num_cache] = dcache_rdata;
-               // r_dcache_cached_save [num_cache] = dcache_cached;
-               // r_dcache_num_cpu_save[num_cache] = dcache_num_cpu;
-                }
-
-              r_dcache_fsm [num_cache] = dcache_fsm_next; // default
-
-              break;
-            }
-            //////////////////////
-          case DCACHE_MISS_VICTIM:
-            {
-              // if (not r_dcache_cleanup_req[num_cache].read())
-              {
-                size_t     way;
-                size_t     set;
-                vci_addr_t addr = (vci_addr_t) r_dcache_addr_save[num_cache].read();
-                vci_addr_t victim;
-                bool       victim_val = r_dcache[num_cache]->victim_select(addr, &victim, &way, &set );
-                         
-                r_dcache_cleanup_req  [num_cache] = victim_val;
-                r_dcache_cleanup_line [num_cache] = (addr_40) victim;
-                r_dcache_miss_way     [num_cache] = way;
-                r_dcache_miss_set     [num_cache] = set;
-                 
-                PRINTF("    * <DCACHE [%d]> MISS_VICTIM : Victim %d - %llx (way %d, set %d)\n",num_cache,victim_val, (blob_t)victim, (int)way, (int)set);
-        
-                r_dcache_fsm          [num_cache] = DCACHE_MISS_WAIT;
-              }
-                    
-              break;
-            }
-            //////////////////////
-          case DCACHE_MISS_WAIT:
-            {
-                // Multi_cache ; Hit after Miss
-                if (m_nb_dcache>0)
-                {
-                    data_t   dcache_rdata   = 0;
-                    bool     dcache_hit     = r_dcache[num_cache]->read((vci_addr_t) _dreq.addr, &dcache_rdata);
-                    // bool     dcache_cached  = dreq_cached  [num_cache];
-                    // uint32_t dcache_num_cpu = dreq_num_cpu [num_cache];
-                    
-                    m_cpt_dcache_data_read += m_dcache_ways;
-                    m_cpt_dcache_dir_read  += m_dcache_ways;
-                    
-                    if (_dreq.valid)
-                        switch (_dreq.type)
-                        {
-                        case iss_t::DATA_READ : // accept only hit dcache load
-                        {
-                            m_cpt_data_read++; // new dcache read
-                            
-                            if (dcache_hit) // no special test for uncached read, because it's always miss
-                            {
-                                m_cpt_dcache_hit_after_miss_read [num_cache] ++;
-                                
-                                // address is in the cache : return the word
-                                _drsp.valid = true;
-                                _drsp.rdata = dcache_rdata; // return read data (cf dcache_hit)
-                            }
-                            break;
-                        }
-                        // case iss_t::DATA_WRITE : // accept only cached write and miss in dcache (else need update dcache)
-                        //   {
-                        //     if (dcache_cached and not dcache_hit)
-                        //       {
-                        //         bool valid;
-                        //         addr_40 addr = _dreq.addr;
-                        //         set_num_dcache(addr,num_cache);
-                        
-                        //         // FIXME : 
-                        //         //  * dans le wbuf, ne pas mettre l'adresse au complet (economie de surface)
-                        //         //  * pour cela, virer le set_num_dcache !
-                        //         valid = r_wbuf[num_cache]->write(addr, _dreq.be, _dreq.wdata, dcache_cached, dcache_num_cpu);
-                        //         PRINTF("    * <DCACHE [%d]> r_wbuf valid          : %d\n",num_cache,valid);
-                        
-                        //         if (valid)
-                        //           {
-                        //             m_cpt_dcache_hit_after_miss_write [num_cache] ++;
-                        
-                        //             m_cpt_data_write++;
-                        //             m_cpt_data_write_miss++;
-                        //           }
-                        
-                        //         _drsp.valid = valid;
-                        //         _drsp.rdata = 0;
-                        //       }
-                        //     break;
-                        //   }
-                        default :
-                        {
-                            break;
-                        }
-                        }
-                } // end multi cache hit after miss
-
-              // if ( _dreq.valid ) m_cost_data_miss_frz++;
-              if ( r_tgt_dcache_req[num_cache].read() ) {   // external request
-                r_dcache_fsm      [num_cache] = DCACHE_CC_CHECK;
-                r_dcache_fsm_save [num_cache] = r_dcache_fsm[num_cache];
-                break;
-              }
-
-              bool val = (r_vci_rsp_fifo_dcache_data.rok() and
-                          (r_vci_rsp_fifo_dcache_num_cache.read() == num_cache));
-
-              if (val)
-                {
-                  // Miss read response and no invalidation
-                  if (r_vci_rsp_data_error[num_cache])
-                    {
-                      r_dcache_fsm [num_cache] = DCACHE_ERROR;
-                    } 
-                  else 
-                    {
-                      r_dcache_update_addr[num_cache] = 0;
-                      r_dcache_fsm        [num_cache] = DCACHE_MISS_UPDT;
-                    }
-                }
-              break;
-            }
-            //////////////////////
-          case DCACHE_MISS_UPDT:
-            {
-              size_t     word = r_dcache_update_addr[num_cache].read();
-              vci_addr_t addr = (vci_addr_t) r_dcache_addr_save[num_cache].read();
-              size_t     way  = r_dcache_miss_way[num_cache].read();
-              size_t     set  = r_dcache_miss_set[num_cache].read();
-                    
-              PRINTF("    * <DCACHE [%d]> MISS_UPDT : Victim way %d, set %d\n",num_cache, (int)way, (int)set);
-
-              bool val = (r_vci_rsp_fifo_dcache_data.rok() and
-                          (r_vci_rsp_fifo_dcache_num_cache.read() == num_cache));
-
-              if (val)
-                {
-                  // m_cpt_dcache_dir_write++;
-                  // if ( _dreq.valid ) m_cost_data_miss_frz++;
-
-                  // if need invalid rsp, don't modify the cache, but pop the buf_rsp
-                  // (power save)
-                  if (not r_dcache_inval_rsp[num_cache])
-                    {
-                      r_dcache[num_cache]->write(way, set, word, r_vci_rsp_fifo_dcache_data.read());
-                      m_cpt_dcache_data_write++;
-                    }
-
-                  vci_rsp_fifo_dcache_get = true;
-
-                  r_dcache_update_addr[num_cache] = ++word;
-                            
-                  // if last word, finish the update
-                  if (word >= m_dcache_words)
-                    {
-                      // in all case (inval_rsp or not), update the victim tag
-                      // because victim is already cleanup
-                      r_dcache[num_cache]->victim_update_tag(addr, way, set);
-
-                      // Last word : if previous invalid_rsp, can cleanup, else update the TAG
-                      if (r_dcache_inval_rsp[num_cache])
-                        {
-                          r_dcache_inval_rsp[num_cache] = false;
-                          r_dcache_fsm      [num_cache] = DCACHE_CC_CLEANUP;
-                        }
-                      else
-                        {
-                          r_dcache_fsm [num_cache] = DCACHE_IDLE;
+                            assert( (r_vci_rsp_cpt.read() == m_cache_words - 1) and
+                            "The VCI response packet for data miss is too short");
+
+                            r_vci_rsp_fsm     = RSP_IDLE;
                         }
                     }
                 }
-                
-              break;
-            }
-            ////////////////////
-          case DCACHE_UNC_WAIT:
-            {
-              // if ( _dreq.valid ) m_cost_unc_read_frz++;
-              if ( r_tgt_dcache_req[num_cache] ) {   // external request
-                r_dcache_fsm     [num_cache] = DCACHE_CC_CHECK;
-                r_dcache_fsm_save[num_cache] = r_dcache_fsm[num_cache];
-                break;
-              } 
-
-              bool ok = (r_vci_rsp_fifo_dcache_data.rok() and
-                         (r_vci_rsp_fifo_dcache_num_cache.read() == num_cache));
-
-              if (ok) {
-                if (r_vci_rsp_data_error[num_cache]) {
-                  r_dcache_fsm[num_cache] = DCACHE_ERROR;
-                } else {
-                  data_t rdata = r_vci_rsp_fifo_dcache_data.read();
-                  vci_rsp_fifo_dcache_get = true;
-
-                  if(_dreq.type == iss_t::DATA_LL){
-                    PRINTF("    * <DCACHE [%d]> ll_valid = true\n",num_cache);
-
-                    r_dcache_ll_valid  [num_cache][r_dcache_num_cpu_save[num_cache]] = true;
-                    r_dcache_ll_data   [num_cache][r_dcache_num_cpu_save[num_cache]] = rdata;
-                    r_dcache_ll_addr   [num_cache][r_dcache_num_cpu_save[num_cache]] = (vci_addr_t) _dreq.addr;
-                  }
-                  r_dcache_fsm [num_cache] = DCACHE_IDLE;
-
-                  _drsp.valid = true;
-                  _drsp.rdata = rdata;
-                }
-              }
-              break;
-            }
-            ////////////////////
-          case DCACHE_SC_WAIT:
-            {
-              // if ( _dreq.valid ) m_cost_unc_read_frz++;
-              if ( r_tgt_dcache_req[num_cache] ) {   // external request
-                r_dcache_fsm      [num_cache] = DCACHE_CC_CHECK;
-                r_dcache_fsm_save [num_cache] = r_dcache_fsm [num_cache];
-                break;
-              } 
-
-              bool ok = (r_vci_rsp_fifo_dcache_data.rok() and
-                         (r_vci_rsp_fifo_dcache_num_cache.read() == num_cache));
-
-              if (ok) {
-                if (r_vci_rsp_data_error[num_cache]) {
-                  r_dcache_fsm [num_cache] = DCACHE_ERROR;
-                } else {
-                  r_dcache_fsm [num_cache] = DCACHE_IDLE;
-
-                  _drsp.valid = true;
-                  _drsp.rdata = r_vci_rsp_fifo_dcache_data.read();
-                  vci_rsp_fifo_dcache_get = true;
-                  r_dcache_ll_valid [num_cache][r_dcache_num_cpu_save[num_cache]] = false;
-                }
-              }
-              break;
-            }
-
-            //////////////////
-          case DCACHE_ERROR:
-            {
-              r_dcache_fsm        [num_cache] = DCACHE_IDLE;
-
-              r_vci_rsp_data_error[num_cache] = false;
-              _drsp.error = true;
-              _drsp.valid = true;
-              break;
-            }
-            /////////////////    
-          case DCACHE_INVAL:
-            {
-              if ( r_tgt_dcache_req[num_cache].read() ) {   // external request
-                r_dcache_fsm      [num_cache] = DCACHE_CC_CHECK;
-                r_dcache_fsm_save [num_cache] = r_dcache_fsm [num_cache];
-                break;
-              }
-              if( not r_dcache_cleanup_req [num_cache].read() ){
-                m_cpt_dcache_dir_read += m_dcache_ways;
-                vci_addr_t  ad  = r_dcache_addr_save [num_cache].read();
-                r_dcache_cleanup_req  [num_cache] = r_dcache[num_cache]->inval(ad);
-                r_dcache_cleanup_line [num_cache] = r_dcache_addr_save [num_cache].read() >> m_dcache_words_shift;
-
-                r_dcache_fsm          [num_cache] = DCACHE_IDLE;
-              }
-              break;
-            }
-          case DCACHE_SYNC :
-            {
-              if ( r_tgt_dcache_req[num_cache] ) {   // external request
-                r_dcache_fsm     [num_cache] = DCACHE_CC_CHECK;
-                r_dcache_fsm_save[num_cache] = r_dcache_fsm[num_cache];
-                break;
-              } 
-
-              bool empty=true;
-              for (uint32_t i=0; i<m_nb_dcache; ++i)
-                empty &= r_wbuf[i]->empty();
-                    
-              if (empty)
-                {
-                  _drsp.valid = true; // end, can accept the sync request
-                  r_dcache_fsm [num_cache] = DCACHE_IDLE;
-                  r_dcache_sync[num_cache] = false;
-                }
-              break;
-            }
-            /////////////////////
-          case DCACHE_CC_CHECK:   // read directory in case of invalidate or update request
-            {
-              addr_40  ad          = r_tgt_daddr;
-
-              PRINTF("    * <DCACHE [%d]> CC_CHECK\n",num_cache);
-
-              // 
-              if((r_dcache_fsm_save[num_cache] == DCACHE_MISS_WAIT) and 
-                 ((r_dcache_addr_save[num_cache].read() & ~((m_dcache_words<<2)-1)) == (ad & ~((m_dcache_words<<2)-1)))) {
-                PRINTF("    * <DCACHE [%d]> have request, need inval rsp\n",num_cache);
-
-                r_dcache_inval_rsp[num_cache] = true;
-                r_tgt_dcache_req  [num_cache] = false;
-                if(r_tgt_update){    // Also send a cleanup and answer
-                  PRINTF("    * <DCACHE [%d]> send a cleanup and answer\n",num_cache);
-                  r_tgt_dcache_rsp[num_cache]     = true;
-                } else {            // Also send a cleanup but don't answer
-                  PRINTF("    * <DCACHE [%d]> send a cleanup and but don't answer\n",num_cache);
-                  r_tgt_dcache_rsp[num_cache]     = false;
-                }
-                r_dcache_fsm[num_cache] = r_dcache_fsm_save[num_cache];
-              } else {
-                uint32_t word       = r_cache_word;
-                data_t   mask       = vci_param::be2mask(r_tgt_be[word]);
-                data_t   rdata      = 0;
-                bool     dcache_hit = r_dcache[num_cache]->read(ad+word*4,&rdata);
-
-                PRINTF("    * <DCACHE [%d]> have no request, hit cache : %d, update : %d\n",num_cache,dcache_hit,(uint32_t)r_tgt_update);
-
-                m_cpt_dcache_data_write+= m_dcache_ways;
-                m_cpt_dcache_dir_read += m_dcache_ways;
-
-                if ( dcache_hit and r_tgt_update ) 
-                  {
-                    // Assumption : We have RAM for dcache with write enable on byte.
-                    // Consequence : dcache_read is only consultation of directory
-
-                    //if(r_tgt_be[word])
-                    r_dcache[num_cache]->write(ad+word*4, (mask & r_tgt_buf[word]) | (~mask & rdata));
-
-                    word ++;
-
-                    // find next valid word
-                    for (; word<m_dcache_words; ++word)
-                      if (r_tgt_be[word] != 0)
-                        break;
-
-                    if (word==m_dcache_words)
-                      {
-                        r_tgt_dcache_req[num_cache] = false;
-                        r_tgt_dcache_rsp[num_cache] = true;
-                        r_dcache_fsm    [num_cache] = r_dcache_fsm_save[num_cache];
-                        word = 0;
-                      }
-                    r_cache_word = word;
-
-                  } else if ( dcache_hit and not r_tgt_update ) {
-                  r_dcache_fsm[num_cache] = DCACHE_CC_INVAL;
-                } else {
-                  if(r_tgt_update){
-                    r_tgt_dcache_rsp[num_cache] = true;
-                  } else {
-                    r_tgt_dcache_rsp[num_cache] = false;
-                  }
-                  r_tgt_dcache_req[num_cache] = false;
-                  r_dcache_fsm    [num_cache] = r_dcache_fsm_save[num_cache];
-                }
-              }
-              break;
-            }
-            /////////////////////
-          case DCACHE_CC_INVAL:   // invalidate a cache line
-            {
-              addr_40  ad      = r_tgt_daddr;
-              r_tgt_dcache_rsp[num_cache] = true;
-              r_dcache        [num_cache]->inval(ad);
-              r_tgt_dcache_req[num_cache] = false;
-              r_dcache_fsm    [num_cache] = r_dcache_fsm_save[num_cache];
-              break;
-            }
-            ///////////////////
-          case DCACHE_CC_CLEANUP:   
-            {
-              // cleanup
-              if(not r_dcache_cleanup_req[num_cache]){
-                r_dcache_cleanup_req  [num_cache] = true;
-                r_dcache_cleanup_line [num_cache] = r_dcache_addr_save[num_cache].read() >> m_dcache_words_shift;
-                r_dcache_fsm          [num_cache] = DCACHE_IDLE;
-
-                m_cpt_dcache_dir_read += m_dcache_ways;
-                r_dcache[num_cache]->inval((addr_40)r_dcache_addr_save[num_cache]);
-              }
-              break;
-            }    
-
-          } // end switch r_dcache_fsm
-        
-          ////////// write buffer state update  /////////////
-          // The update() method must be called at each cycle to update the internal state.
-          // All pending write requests must be locked in case of SYNC
-
-          r_wbuf[num_cache]->update (have_sync);
-
-#if MWBUF_VHDL_TESTBENCH
-          vhdl_mwbuf_port_flush [num_cache] = (vhdl_tb_t)have_sync;
-#endif
-
-          drsp [num_cache] = _drsp;
-          if (_dreq.valid and _drsp.valid)
-            {
-              PRINTF("    * <CPU2CACHE> Transaction between cpu %d and Dcache %d (unlock)\n",r_dcache_lock [num_cache].read(),num_cache);
-
-              r_dcache_lock       [num_cache] = m_nb_cpu;
-              m_cpt_dcache_access [num_cache] ++;
-            }
-
-        }// end for num_cache
-
-      /////////// execute one iss cycle /////////////////////////////////////////////
-
-      for (uint32_t num_cpu=0; num_cpu<m_nb_cpu; ++num_cpu)
-        {
-          // Test if the resquest is accepted
-          typename iss_t::InstructionResponse _irsp = ISS_IRSP_INITIALIZER;
-          typename iss_t::DataResponse        _drsp = ISS_DRSP_INITIALIZER;
-
-          if (ireq_num_cache[num_cpu]<m_nb_icache)
-            _irsp = irsp[ireq_num_cache[num_cpu]];
-          if (dreq_num_cache[num_cpu]<m_nb_dcache)
-            _drsp = drsp[dreq_num_cache[num_cpu]];
-
-#if CC_XCACHE_WRAPPER_STOP_SIMULATION  or CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-          typename iss_t::InstructionRequest  _ireq = ISS_IREQ_INITIALIZER;
-          typename iss_t::DataRequest         _dreq = ISS_DREQ_INITIALIZER;
-
-          if (ireq_num_cache[num_cpu]<m_nb_icache)
-            _ireq = ireq[ireq_num_cache[num_cpu]];
-          if (dreq_num_cache[num_cpu]<m_nb_dcache)
-            _dreq = dreq[dreq_num_cache[num_cpu]];
-#endif
-
-#if CC_XCACHE_WRAPPER_DEBUG
-          if (m_cpt_total_cycles>=CC_XCACHE_WRAPPER_DEBUG_CYCLE_MIN)
-            {
-
-              std::cout << "    * CPU                    : " << num_cpu << std::endl
-                        << "      * Instruction Cache    : " << ireq_num_cache[num_cpu] << ", valid : " << (ireq_num_cache[num_cpu]<m_nb_icache) << std::endl
-                        << "      * Instruction Request  : " << _ireq << std::endl
-                        << "      * Instruction Response : " << _irsp << std::endl
-                        << "      * Data        Cache    : " << dreq_num_cache[num_cpu] << ", valid : " << (dreq_num_cache[num_cpu]<m_nb_dcache) << std::endl
-                        << "      * Data        Request  : " << _dreq << std::endl
-                        << "      * Data        Response : " << _drsp << std::endl;
-            }
-#endif
-
-          if ((_ireq.valid and not _irsp.valid) or 
-              (_dreq.valid and not _drsp.valid))
-            {
-              m_cpt_frz_cycles [num_cpu]++;
-#if CC_XCACHE_WRAPPER_STOP_SIMULATION
-              m_stop_simulation_nb_frz_cycles [num_cpu]++;
-                
-              if (m_stop_simulation and (m_stop_simulation_nb_frz_cycles [num_cpu]>= m_stop_simulation_nb_frz_cycles_max))
-                {
-                  std::cout << std::dec << "CC_XCACHE_WRAPPER \"" << name() << "\" (" << num_cpu << ") : cycle " << m_cpt_total_cycles << ", the cpu is frozen since " << m_stop_simulation_nb_frz_cycles [num_cpu]<< " cycles." << std::endl;
-                  ASSERT(false,"CPU : anormal activity"); // exit
-                }
-            }
-          else
-            {
-              m_stop_simulation_nb_frz_cycles [num_cpu] = 0; // reinit counter
-#endif //CC_XCACHE_WRAPPER_STOP_SIMULATION
-            }
-            
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-          if (generate_log_transaction_file_icache and _ireq.valid and _irsp.valid)
-            {
-              log_transaction_file_icache [num_cpu]
-                << "[" << m_cpt_total_cycles << "]"
-                << std::hex
-                << " @ "     << std::setw(8) << (uint32_t)_ireq.addr
-                << " ("      << std::setw(8) << (uint32_t)set_num_icache_only(_ireq.addr,ireq_num_cache[num_cpu]) 
-                << " - L "     << std::setw(8) <<((uint32_t)set_num_icache_only(_ireq.addr,ireq_num_cache[num_cpu])&m_icache_yzmask) << ")"
-                << " I "     << std::setw(8) << (uint32_t)_irsp.instruction
-                << " error "                 << (uint32_t)_irsp.error
-                << std::dec
-                << std::endl;
-            }
-
-          if (generate_log_transaction_file_dcache and _dreq.valid and _drsp.valid)
-            {
-              log_transaction_file_dcache [num_cpu]
-                << "[" << m_cpt_total_cycles << "]"
-                << std::hex
-                << " @ "     << std::setw(8) << (uint32_t)_dreq.addr
-                << " ("      << std::setw(8) << (uint32_t)set_num_dcache_only(_dreq.addr,dreq_num_cache[num_cpu])
-                << " - L "   << std::setw(8) <<((uint32_t)set_num_dcache_only(_dreq.addr,dreq_num_cache[num_cpu])&m_dcache_yzmask) << ")"
-                << " be "    << std::setw(1) << (uint32_t)_dreq.be
-                << " W "     << std::setw(8) << (uint32_t)_dreq.wdata
-                << " R "     << std::setw(8) << (uint32_t)_drsp.rdata
-                << " error "                 << (uint32_t)_drsp.error
-                << std::dec
-                << " "  << type_str(_dreq.type);
-                
-              if ((_dreq.type == iss_t::XTN_READ) or 
-                  (_dreq.type == iss_t::XTN_WRITE))
-                //log_transaction_file_dcache [num_cpu] << xtn_str(_dreq.addr>>2);
-                switch (_dreq.addr>>2)
-                  {
-                  case iss_t::XTN_DCACHE_INVAL : log_transaction_file_dcache [num_cpu]<< " INVAL"; break;
-                  case iss_t::XTN_SYNC         : log_transaction_file_dcache [num_cpu]<< " SYNC"; break;
-                  default                      : log_transaction_file_dcache [num_cpu]<< " invalid"; break;
-                  }
-                
-              log_transaction_file_dcache [num_cpu]<< std::endl;
-            }
-#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-            
-          {
-            uint32_t it = 0;
-            for (size_t i=0; i<(size_t)iss_t::n_irq; i++) 
-              if(p_irq[num_cpu][i].read()) it |= (1<<i);
-                
-            m_iss[num_cpu]->executeNCycles(1, _irsp, _drsp, it);
-          }
-        }//end num_cpu
-
-      ////////////////////////////////////////////////////////////////////////////
-      // This CLEANUP FSM controls the transmission of the cleanup transactions
-      // on the coherence network. It controls the following ressources:
-      // - r_cleanup_fsm
-      // - r_dcache_cleanup_req (reset)
-      // - r_icache_cleanup_req (reset)
-      // 
-      // This FSM handles cleanup requests from both the DCACHE FSM & ICACHE FSM
-      // - Instruction Cleanup  : r_icache_cleanup_req 
-      // - Data Cleanup         : r_dcache_cleanup_req 
-      // In case of simultaneous requests, the data request have highest priority.
-      // There is only one cleanup transaction at a given time (sequencial behavior)
-      // because the same FSM controls both command & response. 
-      // The the r_icache_cleanup_req & r_dcache_cleanup_req are reset only
-      // when the response packet is received.
-      // Error handling :
-      // As the coherence trafic is controled by hardware, errors are not reported
-      // to software : In case of errors, the simulation stops.
-      ////////////////////////////////////////////////////////////////////////////
-
-      switch (r_cleanup_fsm) {
-
-      case CLEANUP_IDLE:
-        {
-          uint32_t num_cache          = 0;
-          bool     cleanup_dcache_req = false;
-          bool     cleanup_icache_req = false;
-
-          // dcache is prior
-          for (uint32_t i=0; i<m_nb_dcache; ++i)
-            {
-              PRINTF("      * <CLEANUP> dcache_cleanup_req : [%d] %d\n",i,(int)r_dcache_cleanup_req[i]);
-              cleanup_dcache_req |= r_dcache_cleanup_req[i];
-              if (cleanup_dcache_req)
-                {
-                  PRINTF("      * <CLEANUP> ... find\n");
-                  num_cache=i;
-                  break;
-                }
-            }
- 
-          if (not cleanup_dcache_req)
-            for (uint32_t i=0; i<m_nb_icache; ++i)
-              {
-                PRINTF("      * <CLEANUP> icache_cleanup_req : [%d] %d\n",i,(int)r_icache_cleanup_req[i]);
-
-                cleanup_icache_req |= r_icache_cleanup_req[i];
-                if (cleanup_icache_req)
-                  {
-                    PRINTF("      * <CLEANUP> ... find\n");
-                    num_cache=i;
-                    break;
-                  }
-              }
-
-          PRINTF("      * <CLEANUP> cleanup_icache_req : %d\n",cleanup_icache_req);
-          PRINTF("      * <CLEANUP> cleanup_dcache_req : %d\n",cleanup_dcache_req);
-          PRINTF("      * <CLEANUP> num_cache          : %d\n",num_cache);
-
-          if (cleanup_icache_req or cleanup_dcache_req)
-            {
-              r_cleanup_fsm       = CLEANUP_REQ;
-              r_cleanup_icache    = cleanup_icache_req;
-              r_cleanup_num_cache = num_cache;
-
-              PRINTF("      * <CLEANUP> address            : %llx\n",((cleanup_icache_req)?((blob_t)set_num_icache_only(r_icache_cleanup_line[num_cache].read()<<m_icache_words_shift,num_cache)):((blob_t)set_num_dcache_only(r_dcache_cleanup_line[num_cache].read()<<m_dcache_words_shift,num_cache))));
-
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-              if (generate_log_transaction_file_cleanup)
-                {
-                  log_transaction_file_cleanup
-                    << "[" << m_cpt_total_cycles << "] "
-                    << ((cleanup_icache_req)?("icache "):("dcache "))
-                    << num_cache << " : "
-                    << std::hex
-                    << " L "     << std::setw(10) << ((cleanup_icache_req)?((blob_t)set_num_icache_only(r_icache_cleanup_line[num_cache].read()<<m_icache_words_shift,num_cache)):((blob_t)set_num_dcache_only(r_dcache_cleanup_line[num_cache].read()<<m_dcache_words_shift,num_cache)))
-                    // << " (" << std::setw(10) << addr << ")"
-                    << std::dec
-                    << std::endl;
-                }
-#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-
-            }
-          break;
-        }
-      case CLEANUP_REQ:
-        {
-          if ( p_vci_ini_c.cmdack )
-            {
-              if (r_cleanup_icache)
-                r_cleanup_fsm = CLEANUP_RSP_ICACHE;
-              else
-                r_cleanup_fsm = CLEANUP_RSP_DCACHE;
-            }
-          break;
-        }
-      case CLEANUP_RSP_DCACHE:
-        {
-          if ( p_vci_ini_c.rspval )
-            {
-              PRINTF("      * <CLEANUP> rerror : %d (%d)\n",(uint32_t)p_vci_ini_c.rerror.read(),0x2 & ( (1 << vci_param::E) - 1));
-              PRINTF("      * <CLEANUP> rpktid : %d, r_cleanup_num_cache : %d\n",(uint32_t)p_vci_ini_c.rpktid.read(), (uint32_t)r_cleanup_num_cache);
-
-              ASSERT(p_vci_ini_c.reop and (p_vci_ini_c.rtrdid.read() == TYPE_DATA_CLEANUP),
-                     "illegal response packet received for a cleanup transaction");
-              ASSERT((p_vci_ini_c.rerror.read()&1) == vci_param::ERR_NORMAL,
-                     "error signaled in a cleanup response" );
-              ASSERT(p_vci_ini_c.rpktid.read() == (sc_dt::sc_uint<vci_param::P>)r_cleanup_num_cache,
-                     "invalid pktid in a cleanup response");
-
-              r_cleanup_fsm = CLEANUP_IDLE;
-              r_dcache_cleanup_req[r_cleanup_num_cache] = false;
-              // m_cpt_cc_cleanup_data++;
-            }
-          break;
-        }
-      case CLEANUP_RSP_ICACHE:
-        {
-          if ( p_vci_ini_c.rspval )
-            {
-              PRINTF("      * <CLEANUP> rerror : %d (%d)\n",(uint32_t)p_vci_ini_c.rerror.read(),0x2 & ( (1 << vci_param::E) - 1));
-
-              ASSERT(p_vci_ini_c.reop and (p_vci_ini_c.rtrdid.read() == TYPE_INS_CLEANUP),
-                     "illegal response packet received for a cleanup transaction");
-              ASSERT((p_vci_ini_c.rerror.read()&1) == vci_param::ERR_NORMAL, 
-                     "error signaled in a cleanup response" );
-                    
-              r_cleanup_fsm = CLEANUP_IDLE;
-              r_icache_cleanup_req[r_cleanup_num_cache] = false;
-              // m_cpt_cc_cleanup_ins++;
-            }
-          break;
-        }
-      } // end switch r_cleanup_fsm    
-
-        ////////////////////////////////////////////////////////////////////////////
-        // The VCI_CMD FSM controls the following ressources:
-        // - r_vci_cmd_fsm
-        // - r_vci_cmd_min
-        // - r_vci_cmd_max
-        // - r_vci_cmd_cpt
-        // - wbuf (reset)
-        // - r_icache_miss_req (reset)
-        // - r_icache_unc_req (reset)
-        // - r_dcache_miss_req (reset)
-        // - r_dcache_sc_req (reset)
-        //
-        // This FSM handles requests from both the DCACHE FSM & the ICACHE FSM.
-        // There is 7 request types, with the following priorities : 
-        // 1 - Data Read Miss         : r_dcache_miss_req and miss in the write buffer
-        // 2 - Data Read Uncachable   : r_dcache_unc_req  and miss in the write buffer
-        // 3 - Instruction Miss       : r_icache_miss_req and miss in the write buffer
-        // 4 - Instruction Uncachable : r_icache_unc_req  and miss in the write buffer
-        // 5 - Data Write             : r_wbuf.rok()      
-        // 6 - Data Store Conditionnal: r_dcache_sc_req
-        // There is at most one (CMD/RSP) VCI transaction, as both CMD_FSM 
-        // and RSP_FSM exit simultaneously the IDLE state.
-        //
-        // VCI formats:
-        // According to the VCI advanced specification, all read requests packets 
-        // (read Uncached, Miss data, Miss instruction) are one word packets.
-        // For write burst packets, all words must be in the same cache line,
-        // and addresses must be contiguous (the BE field is 0 in case of "holes").
-        //////////////////////////////////////////////////////////////////////////////
-
-      // reverse priority
-      r_vci_cmd_dcache_prior = not r_vci_cmd_dcache_prior;
-      r_vci_cmd_num_icache_prior = (r_vci_cmd_num_icache_prior+1)%m_nb_icache;
-      r_vci_cmd_num_dcache_prior = (r_vci_cmd_num_dcache_prior+1)%m_nb_dcache;
-
-      size_t  wbuf_min   = 0;
-      size_t  wbuf_max   = 0;
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-      addr_40 wbuf_addr  = 0;
-      size_t  wbuf_index = 0;
-#endif
-
-      uint32_t dcache_write_num_cache = m_nb_dcache;
-
-      for (uint32_t i=0; i<m_nb_dcache; ++i)
-        {
-          uint32_t num_cache=(r_vci_cmd_num_dcache_prior+i)%m_nb_dcache;
-          bool     find = false;
-          
-          size_t  _wbuf_min   = 0;
-          size_t  _wbuf_max   = 0;
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-          addr_40 _wbuf_addr  = 0;
-          size_t  _wbuf_index = 0;
-#endif
-          
-          if (
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-              (r_wbuf[num_cache]->rok_info(&_wbuf_min, &_wbuf_max, &_wbuf_addr, &_wbuf_index)) and
-#else
-              (r_wbuf[num_cache]->rok     (&_wbuf_min, &_wbuf_max)) and
-#endif                      
-              (dcache_write_num_cache == m_nb_dcache))
-            {
-              find = true;
-              dcache_write_num_cache = num_cache;
-              
-              PRINTF("      * <CMD> wbuf min, max            : %d, %d\n",(int)_wbuf_min,(int)_wbuf_max);
-              
-              wbuf_min   = _wbuf_min  ;
-              wbuf_max   = _wbuf_max  ;
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-              wbuf_addr  = _wbuf_addr ;
-              wbuf_index = _wbuf_index;
-              
-              PRINTF("      * <CMD> wbuf index               : %d\n",(int)_wbuf_index);
-              PRINTF("      * <CMD> wbuf address             : %llx\n",(blob_t)_wbuf_addr);
-#endif
-            }
-          
-          PRINTF("      * <CMD> Test read after miss     : cache : %d, find : %d\n",dcache_write_num_cache, find);
-          
-#if MWBUF_VHDL_TESTBENCH
-          vhdl_mwbuf_test_sent_val         [dcache_write_num_cache] = (vhdl_tb_t)1;
-          vhdl_mwbuf_port_sent_val         [dcache_write_num_cache] = (vhdl_tb_t)find;
-          vhdl_mwbuf_test_sent_word_min    [dcache_write_num_cache] = (vhdl_tb_t)find;
-          vhdl_mwbuf_port_sent_word_min    [dcache_write_num_cache] = (vhdl_tb_t)wbuf_min;
-          vhdl_mwbuf_test_sent_word_max    [dcache_write_num_cache] = (vhdl_tb_t)find;
-          vhdl_mwbuf_port_sent_word_max    [dcache_write_num_cache] = (vhdl_tb_t)wbuf_max;
-#endif                
-        }
-
-      switch (r_vci_cmd_fsm) {
-
-      case CMD_IDLE:
-        {
-          // if (r_vci_rsp_fsm != RSP_IDLE) break;
-
-
-          // Requests :
-
-          // multi_write_buffer access is conditionnal with dcache_miss_req and icache_miss_req
-
-          bool     dcache_miss_req      = false;
-          bool     icache_miss_req      = false;
-          uint32_t dcache_miss_num_cache = m_nb_dcache;
-          uint32_t icache_miss_num_cache = m_nb_icache;
-          addr_40  addr = 0;
-
-          bool     wbuf_imiss = false;
-          bool     wbuf_dmiss = false;
+            }
+            break;
+        }
+        //////////////////
+        case RSP_DATA_UNC:
+        {
+            if (p_vci_ini_d.rspval.read() )
+            {
+                assert( p_vci_ini_d.reop.read() and
+                "illegal VCI response packet for uncacheable read data");
+
+                if ( (p_vci_ini_d.rerror.read()&0x1) != 0 )  // error reported
+                {
+                    r_vci_rsp_data_error = true;
+                    r_vci_rsp_fsm = RSP_IDLE;
+                }
+                else                                         // no error reported
+                {   
+                    if ( r_vci_rsp_fifo_dcache.wok())
+                    {
+                        vci_rsp_fifo_dcache_put       = true;
+                        vci_rsp_fifo_dcache_data      = p_vci_ini_d.rdata.read();
+                        r_vci_rsp_fsm = RSP_IDLE;
+                    }
+                }
+            }
+            break;
+        }
+        ////////////////////
+        case RSP_DATA_WRITE:
+        {
+            if (p_vci_ini_d.rspval.read())
+            {
+                assert( p_vci_ini_d.reop.read() and
+                "a VCI response packet must contain one flit for a write transaction");
+
+                r_vci_rsp_fsm = RSP_IDLE;
+                uint32_t wbuf_index = p_vci_ini_d.rtrdid.read() - (1<<(vci_param::T-1));
+                bool     cacheable  = r_wbuf->completed(wbuf_index);
+                if ( not cacheable ) r_dcache_pending_unc_write = false;
+                if ( (p_vci_ini_d.rerror.read()&0x1) != 0 ) r_iss->setWriteBerr();
+            }
+            break;
+        }
+    } // end switch r_vci_rsp_fsm
+
+    // FIFO_RSP update
+
+    r_vci_rsp_fifo_icache.update(vci_rsp_fifo_icache_get, 
+                                 vci_rsp_fifo_icache_put, 
+                                 vci_rsp_fifo_icache_data);
       
-          {
-            for (uint32_t i=0; i<m_nb_dcache; ++i)
-              {
-                uint32_t num_cache=(r_vci_cmd_num_dcache_prior+i)%m_nb_dcache;
-
-                dcache_miss_req = r_dcache_miss_req[num_cache];
-                if (dcache_miss_req)
-                {
-                    dcache_miss_num_cache = num_cache;
-                    break;
-                }
-              }
-            for (uint32_t i=0; i<m_nb_icache; ++i)
-              {
-                uint32_t num_cache=(r_vci_cmd_num_icache_prior+i)%m_nb_icache;
-
-                icache_miss_req = r_icache_miss_req[num_cache];
-                if (icache_miss_req)
-                {
-                    icache_miss_num_cache = num_cache;
-                    break;
-                }
-              }
-
-            PRINTF("      * <CMD> icache_miss_req (before) : %d\n",icache_miss_req);
-            PRINTF("      * <CMD> dcache_miss_req (before) : %d\n",dcache_miss_req);
-
-            //  one access with round robin priority
-            dcache_miss_req = ((dcache_miss_req and not icache_miss_req) or // only dcache
-                               (dcache_miss_req and r_vci_cmd_dcache_prior)); // dcache prior
-            icache_miss_req &= not dcache_miss_req;
-
-            PRINTF("      * <CMD> icache_miss_req (after ) : %d\n",icache_miss_req);
-            PRINTF("      * <CMD> dcache_miss_req (after ) : %d\n",dcache_miss_req);
-
-            PRINTF("      * <CMD> icache_miss_num_cache    : %d\n",icache_miss_num_cache);
-            PRINTF("      * <CMD> dcache_miss_num_cache    : %d\n",dcache_miss_num_cache);
-
-            if (icache_miss_req or dcache_miss_req)
-              {
-                addr = (icache_miss_req)?r_icache_addr_save[icache_miss_num_cache].read():r_dcache_addr_save[dcache_miss_num_cache].read();
-
-                PRINTF("      * <CMD> addr                     : %llx\n",(blob_t)addr);
-
-                if (icache_miss_req)
-                  {
-                    // FIXME : 
-                    // si wbuf contient des addresses partionné, set_num_icache puis get_num_dcache
-                    // dcache_miss_num_cache = icache_miss_num_cache;
-                    set_num_icache(addr,icache_miss_num_cache);
-                    // get_num_dcache(addr,dcache_miss_num_cache);
-                  }
-                else
-                  set_num_dcache(addr,dcache_miss_num_cache);
-
-                PRINTF("      * <CMD> addr                     : %llx\n",(blob_t)addr);
-                
-                uint32_t num_cache = get_num_dcache_only(addr);
-
-                wbuf_imiss = (icache_miss_req)?r_wbuf[num_cache]->miss(addr):false;
-                wbuf_dmiss = (dcache_miss_req)?r_wbuf[num_cache]->miss(addr):false;
-
-#if MWBUF_VHDL_TESTBENCH
-                vhdl_mwbuf_port_raw_test [num_cache] = (vhdl_tb_t)1;
-                vhdl_mwbuf_port_raw_addr [num_cache] = (vhdl_tb_t)addr;
-                vhdl_mwbuf_test_raw_miss [num_cache] = (vhdl_tb_t)1;
-                vhdl_mwbuf_port_raw_miss [num_cache] = (dcache_miss_req)?(vhdl_tb_t)wbuf_dmiss:(vhdl_tb_t)wbuf_imiss;
-#endif                
-              }
-          }
-
-          uint32_t dcache_unc_num_cache = m_nb_dcache;
-          for (uint32_t i=0; i<m_nb_dcache; ++i)
-          {
-              uint32_t num_cache=(r_vci_cmd_num_dcache_prior+i)%m_nb_dcache;
-              if (r_dcache_unc_req[num_cache])
-              {
-                  dcache_unc_num_cache = num_cache;
-                  break;
-              }
-          }
-          uint32_t icache_unc_num_cache = m_nb_icache;
-          for (uint32_t i=0; i<m_nb_icache; ++i)
-          {
-              uint32_t num_cache=(r_vci_cmd_num_icache_prior+i)%m_nb_icache;
-              if (r_icache_unc_req[num_cache])
-              {
-                  icache_unc_num_cache = num_cache;
-                  break;
-              }
-          }
-          uint32_t dcache_sc_num_cache = m_nb_dcache;
-          for (uint32_t i=0; i<m_nb_dcache; ++i)
-          {
-              uint32_t num_cache=(r_vci_cmd_num_dcache_prior+i)%m_nb_dcache;
-              if (r_dcache_sc_req[num_cache])
-              {
-                  dcache_sc_num_cache = num_cache;
-                  break;
-              }
-          }
-
-          // 1 - Data Read
-          if (wbuf_dmiss)
-            // (dcache_miss_req and r_wbuf[dcache_miss_num_cache]->miss(addr))
-            { 
-              r_vci_cmd_fsm       = CMD_DATA_MISS;
-              r_vci_cmd_num_cache = dcache_miss_num_cache;
-              r_dcache_miss_req[dcache_miss_num_cache] = false;
-              m_cpt_dmiss_transaction++; 
-
-
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-              if (generate_log_transaction_file_cmd)
-                {
-                  log_transaction_file_cmd
-                    << "[" << m_cpt_total_cycles << "] "
-                    << "CMD DATA MISS  "
-                    << "(" << dcache_miss_num_cache << ") "
-                    << std::hex
-                    << " @ " << std::setw(10) << (blob_t)addr
-                    << " (L " << std::setw(10) << ((blob_t)addr&(blob_t)m_dcache_yzmask) << ")"
-                    << std::dec
-                    << std::endl;
-                }
-#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-
-            } 
-
-          // 2 - Data Read Uncachable
-          else if (dcache_unc_num_cache < m_nb_dcache) // have r_dcache_unc_req
-            { 
-              r_vci_cmd_fsm       = CMD_DATA_UNC;
-              r_vci_cmd_num_cache = dcache_unc_num_cache;
-              r_dcache_unc_req[dcache_unc_num_cache] = false;
-              // m_cpt_data_unc_transaction++; 
-
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-              if (generate_log_transaction_file_cmd)
-                {
-                  addr_40 addr = (addr_40) r_dcache_addr_save[dcache_unc_num_cache].read() & ~0x3;
-                  set_num_dcache(addr,dcache_unc_num_cache);
-                        
-                  log_transaction_file_cmd
-                    << "[" << m_cpt_total_cycles << "] "
-                    << "CMD DATA UNC   "
-                    << "(" << dcache_unc_num_cache << ") "
-                    << std::hex
-                    << " @ " << std::setw(10) << (blob_t)addr
-                    << " (L " << std::setw(10) << ((blob_t)addr&(blob_t)m_dcache_yzmask) << ")"
-                    << std::dec
-                    << std::endl;
-                }
-#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-            }
-
-          // 3 - Instruction Miss
-          else if (wbuf_imiss)
-            //else if (icache_miss_req and r_wbuf[icache_miss_num_cache]->miss(addr))
-            {
-              r_vci_cmd_fsm       = CMD_INS_MISS; 
-              r_vci_cmd_num_cache = icache_miss_num_cache;
-              r_icache_miss_req[icache_miss_num_cache] = false;
-              m_cpt_imiss_transaction++;
-
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-              if (generate_log_transaction_file_cmd)
-                {
-                  log_transaction_file_cmd
-                    << "[" << m_cpt_total_cycles << "] "
-                    << "CMD INS  MISS  "
-                    << "(" << icache_miss_num_cache << ") "
-                    << std::hex
-                    << " @ " << std::setw(10) << (blob_t)addr
-                    << " (L " << std::setw(10) << ((blob_t)addr&(blob_t)m_icache_yzmask) << ")"
-                    << std::dec
-                    << std::endl;
-                }
-#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-            } 
-
-          // 4 - Instruction Uncachable
-          else if (icache_unc_num_cache < m_nb_icache) // have r_icache_unc_req
-            { 
-              r_vci_cmd_fsm       = CMD_INS_UNC; 
-              r_vci_cmd_num_cache = icache_unc_num_cache;
-              r_icache_unc_req[icache_unc_num_cache] = false;
-              // m_cpt_ins_unc_transaction++;
-
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-              if (generate_log_transaction_file_cmd)
-                {
-                  addr_40 addr = (addr_40) r_icache_addr_save[icache_unc_num_cache].read() & ~0x3;
-                  set_num_dcache(addr,icache_unc_num_cache);
-                        
-                  log_transaction_file_cmd
-                    << "[" << m_cpt_total_cycles << "] "
-                    << "CMD INS  UNC   "
-                    << "(" << icache_unc_num_cache << ") "
-                    << std::hex
-                    << " @ " << std::setw(10) << (blob_t)addr
-                    << " (L " << std::setw(10) << ((blob_t)addr&(blob_t)m_icache_yzmask) << ")"
-                    << std::dec
-                    << std::endl;
-                }
-#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-            }
-
-          // 5 - Data Write
-          else if (dcache_write_num_cache < m_nb_dcache) // have r_wbuf.rok(&wbuf_min, &wbuf_max)
-            { 
-              r_vci_cmd_num_cache = dcache_write_num_cache;
-              r_vci_cmd_fsm       = CMD_DATA_WRITE;
-              r_vci_cmd_cpt       = wbuf_min;
-              r_vci_cmd_min       = wbuf_min;
-              r_vci_cmd_max       = wbuf_max;
-              m_cpt_data_write_transaction++; 
-              m_length_write_transaction += (wbuf_max-wbuf_min+1); 
-
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-              if (generate_log_transaction_file_cmd)
-                {
-                  addr_40 addr = (addr_40) wbuf_addr&~0x3;
-                        
-                  log_transaction_file_cmd
-                    << "[" << m_cpt_total_cycles << "] "
-                    << "CMD DATA WRITE "
-                    << "(" << dcache_write_num_cache << ") "
-                    << std::hex
-                    << " @ " << std::setw(10) << (blob_t)addr
-                    << " (L " << std::setw(10) << ((blob_t)addr&(blob_t)m_dcache_yzmask) << ")"
-                    << " [" << wbuf_min << ":" << wbuf_max << "]"
-                    << " {" << wbuf_index << "}"
-                    << std::dec
-                    << std::endl;
-                }
-#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-            } 
-
-          // 6 - Data Store Conditionnal
-          else if (dcache_sc_num_cache < m_nb_dcache) // have r_dcache_sc_req
-            { 
-              r_vci_cmd_fsm       = CMD_DATA_SC;
-              r_vci_cmd_num_cache = dcache_sc_num_cache;
-              r_vci_cmd_cpt       = 0;
-              r_vci_cmd_min       = 0;
-              r_vci_cmd_max       = 1; 
-              m_cpt_unc_transaction++; 
-              r_dcache_sc_req[dcache_sc_num_cache] = false;
-
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-              if (generate_log_transaction_file_cmd)
-                {
-                  addr_40 addr = (addr_40) r_dcache_addr_save[dcache_sc_num_cache].read() & ~0x3;
-                  set_num_dcache(addr,dcache_sc_num_cache);
-                        
-                  log_transaction_file_cmd
-                    << "[" << m_cpt_total_cycles << "] "
-                    << "CMD DATA SC    "
-                    << "(" << dcache_sc_num_cache << ") "
-                    << std::hex
-                    << " @ " << std::setw(10) << (blob_t)addr
-                    << " (L " << std::setw(10) << ((blob_t)addr&(blob_t)m_dcache_yzmask) << ")"
-                    << std::dec
-                    << std::endl;
-                }
-#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-            }
-
-          break;
-        }
-      case CMD_DATA_WRITE:
-        if ( p_vci_ini_rw.cmdack.read() ) {
-
-#if MWBUF_VHDL_TESTBENCH
-              vhdl_mwbuf_port_sent_word        [r_vci_cmd_num_cache] = (vhdl_tb_t)r_vci_cmd_cpt;
-              vhdl_mwbuf_test_sent_addr        [r_vci_cmd_num_cache] = (vhdl_tb_t)1;
-              vhdl_mwbuf_port_sent_addr        [r_vci_cmd_num_cache] = (vhdl_tb_t)r_wbuf[r_vci_cmd_num_cache]->getAddress(r_vci_cmd_cpt);
-              vhdl_mwbuf_test_sent_data        [r_vci_cmd_num_cache] = (vhdl_tb_t)1;
-              vhdl_mwbuf_port_sent_data        [r_vci_cmd_num_cache] = (vhdl_tb_t)r_wbuf[r_vci_cmd_num_cache]->getData(r_vci_cmd_cpt);
-              vhdl_mwbuf_test_sent_be          [r_vci_cmd_num_cache] = (vhdl_tb_t)1;
-              vhdl_mwbuf_port_sent_be          [r_vci_cmd_num_cache] = (vhdl_tb_t)r_wbuf[r_vci_cmd_num_cache]->getBe(r_vci_cmd_cpt);
-              vhdl_mwbuf_test_sent_index       [r_vci_cmd_num_cache] = (vhdl_tb_t)1;
-              vhdl_mwbuf_port_sent_index       [r_vci_cmd_num_cache] = (vhdl_tb_t)r_wbuf[r_vci_cmd_num_cache]->getIndex();
-#endif
-
-          r_vci_cmd_cpt = r_vci_cmd_cpt + 1;
-          if (r_vci_cmd_cpt == r_vci_cmd_max) {
-            r_vci_cmd_fsm = CMD_IDLE ;
-            r_wbuf[r_vci_cmd_num_cache]->sent() ;
-#if MWBUF_VHDL_TESTBENCH
-            vhdl_mwbuf_port_sent_ack [r_vci_cmd_num_cache] = (vhdl_tb_t)1;
-#endif
-          }
-        }
-        break;
-
-      case CMD_DATA_SC:
-        if ( p_vci_ini_rw.cmdack.read() ) {
-          r_vci_cmd_cpt = r_vci_cmd_cpt + 1;
-          if (r_vci_cmd_cpt == r_vci_cmd_max) {
-            r_vci_cmd_fsm = CMD_IDLE ;
-          }
-        }
-        break;
-      case CMD_INS_MISS:
-      case CMD_INS_UNC:
-      case CMD_DATA_MISS:
-      case CMD_DATA_UNC:
-        if ( p_vci_ini_rw.cmdack.read() ) {
-          r_vci_cmd_fsm = CMD_IDLE;
-        }
-        break;
-
-      } // end  switch r_vci_cmd_fsm
-
-        //////////////////////////////////////////////////////////////////////////
-        // The VCI_RSP FSM controls the following ressources:
-        // - r_vci_rsp_fsm:
-        // - r_vci_rsp_fifo_icache[m_icache_words]
-        // - r_vci_rsp_fifo_dcache[m_dcache_words]
-        // - r_vci_rsp_data_error set
-        // - r_vci_rsp_ins_error set
-        // - r_vci_rsp_cpt
-        // In order to have only one active VCI transaction, this VCI_RSP_FSM 
-        // is synchronized with the VCI_CMD FSM, and both FSMs exit the
-        // IDLE state simultaneously.
-        // 
-        // VCI formats:
-        // This component accepts single word or multi-word response packets for
-        // write response packets. 
-        //
-        // Error handling:
-        // This FSM analyzes the VCI error code and signals directly the
-        // Write Bus Error. 
-        // In case of Read Data Error, the VCI_RSP FSM sets the r_vci_rsp_data_error 
-        // flip_flop and the error is signaled by the DCACHE FSM.  
-        // In case of Instruction Error, the VCI_RSP FSM sets the r_vci_rsp_ins_error 
-        // flip_flop and the error is signaled by the DCACHE FSM.  
-        // In case of Cleanup Error, the simulation stops with an error message...
-        //////////////////////////////////////////////////////////////////////////
-
-      switch (r_vci_rsp_fsm) {
-
-      case RSP_IDLE:
-
-        if( p_vci_ini_rw.rspval.read() )
-          {
-            PRINTF("      * <RSP> have rsp - trdid : %x - num_cache : %d\n",(uint32_t)p_vci_ini_rw.rtrdid.read(),(uint32_t)p_vci_ini_rw.rpktid.read());
-
-            ASSERT(p_vci_ini_rw.rpktid.read() <= (1<<vci_param::P),
-                   "invalid pktid in a cleanup response");
-
-            r_vci_rsp_cpt = 0;
-
-            if ((p_vci_ini_rw.rtrdid.read()>>(vci_param::T-1)) != 0 )
-              {
-                r_vci_rsp_fsm = RSP_DATA_WRITE;
-
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-                if (generate_log_transaction_file_cmd)
-                  {
-                    log_transaction_file_cmd
-                      << "[" << m_cpt_total_cycles << "] "
-                      << "RSP DATA WRITE "
-                      << "(" << p_vci_ini_rw.rpktid.read() << ") "
-                      << "{" << (p_vci_ini_rw.rtrdid.read() - (1<<(vci_param::T-1))) << "}"
-                      << std::endl;
-                  }
-#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-              }
-            else
-              {
-                switch (p_vci_ini_rw.rtrdid.read())
-                  {
-                  case TYPE_INS_MISS     : 
-                    {
-                      r_vci_rsp_fsm = RSP_INS_MISS;
-
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-                      if (generate_log_transaction_file_cmd)
-                        {
-                          log_transaction_file_cmd
-                            << "[" << m_cpt_total_cycles << "] "
-                            << "RSP INS  MISS  "
-                            << "(" << p_vci_ini_rw.rpktid.read() << ") "
-                            << std::endl;
-                        }
-#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-
-                      break;
-                    }
-                  case TYPE_INS_UNC      : 
-                    {
-                      r_vci_rsp_fsm = RSP_INS_UNC;
-
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-                      if (generate_log_transaction_file_cmd)
-                        {
-                          log_transaction_file_cmd
-                            << "[" << m_cpt_total_cycles << "] "
-                            << "RSP INS  UNC   "
-                            << "(" << p_vci_ini_rw.rpktid.read() << ") "
-                            << std::endl;
-                        }
-#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-
-                      break;
-                    }
-                  case TYPE_DATA_MISS    : 
-                    {
-                      r_vci_rsp_fsm = RSP_DATA_MISS;
-
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-                      if (generate_log_transaction_file_cmd)
-                        {
-                          log_transaction_file_cmd
-                            << "[" << m_cpt_total_cycles << "] "
-                            << "RSP DATA MISS  "
-                            << "(" << p_vci_ini_rw.rpktid.read() << ") "
-                            << std::endl;
-                        }
-#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-
-                      break;
-                    }
-                  case TYPE_DATA_UNC     : 
-                    {
-                      r_vci_rsp_fsm = RSP_DATA_UNC;
-
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-                      if (generate_log_transaction_file_cmd)
-                        {
-                          log_transaction_file_cmd
-                            << "[" << m_cpt_total_cycles << "] "
-                            << "RSP DATA UNC   "
-                            << "(" << p_vci_ini_rw.rpktid.read() << ") "
-                            << std::endl;
-                        }
-#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-
-                      break;
-                    }
-                  case TYPE_DATA_SC      : 
-                    {
-                      r_vci_rsp_fsm = RSP_DATA_SC;
-
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-                      if (generate_log_transaction_file_cmd)
-                        {
-                          log_transaction_file_cmd
-                            << "[" << m_cpt_total_cycles << "] "
-                            << "RSP DATA SC    "
-                            << "(" << p_vci_ini_rw.rpktid.read() << ") "
-                            << std::endl;
-                        }
-#endif //CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-
-                      break;
-                    }
-                  default : 
-                    {
-                      ASSERT(false, "Unexpected response");
-                    }
-                  }
-              }
-
-            r_vci_rsp_num_cache = p_vci_ini_rw.rpktid.read();
-          }
-        break;
-
-      case RSP_INS_MISS:
-
-        m_cost_imiss_transaction++;
-        PRINTF("      * <RSP> rspval : %d / r_vci_rsp_fifo_icache_data.wok %d\n",(uint32_t)p_vci_ini_rw.rspval.read(),(uint32_t)r_vci_rsp_fifo_icache_data.wok());
-
-        if (p_vci_ini_rw.rspval.read() and r_vci_rsp_fifo_icache_data.wok())
-          {
-            PRINTF("      * <RSP> have rsp - r_vci_rsp_cpt : %d/%d\n",(uint32_t)r_vci_rsp_cpt.read(),(uint32_t)m_icache_words);
-            PRINTF("      * <RSP> ins : %x\n",(int)p_vci_ini_rw.rdata.read());
-
-            ASSERT( (r_vci_rsp_cpt.read() < m_icache_words),
-                    "The VCI response packet for instruction miss is too long" );
-            r_vci_rsp_cpt = r_vci_rsp_cpt.read() + 1;
-            vci_rsp_fifo_icache_put       = true,
-            vci_rsp_fifo_icache_num_cache = r_vci_rsp_num_cache;
-            vci_rsp_fifo_icache_data      = p_vci_ini_rw.rdata.read();
-
-            if ( p_vci_ini_rw.reop.read() ) 
-              {
-                PRINTF("      * <RSP> have reop\n");
-
-                ASSERT( ((r_vci_rsp_cpt.read() == m_icache_words - 1) or
-                         (p_vci_ini_rw.rerror.read()&1) or
-                         (r_vci_rsp_ins_error[r_vci_rsp_num_cache].read()&0x1)),
-                        "The VCI response packet for instruction miss is too short");
-                r_vci_rsp_cpt    = 0;
-                r_vci_rsp_fsm    = RSP_IDLE;
-
-              }
-            if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_ins_error[r_vci_rsp_num_cache] = true;
-          }
-        break;
-
-      case RSP_INS_UNC:
-
-        m_cost_imiss_transaction++;
-        if (p_vci_ini_rw.rspval.read() and r_vci_rsp_fifo_icache_data.wok())
-          {
-            ASSERT(p_vci_ini_rw.reop.read(),
-                   "illegal VCI response packet for uncached instruction");
-
-            vci_rsp_fifo_icache_put       = true,
-            vci_rsp_fifo_icache_num_cache = r_vci_rsp_num_cache;
-            vci_rsp_fifo_icache_data      = p_vci_ini_rw.rdata.read();
-
-            r_vci_rsp_fsm = RSP_IDLE;
-
-            if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_ins_error[r_vci_rsp_num_cache] = true;
-          }
-        break;
-
-      case RSP_DATA_MISS:
-
-        m_cost_dmiss_transaction++;
-
-        PRINTF("      * <RSP> rspval : %d / r_vci_rsp_fifo_icache_data.wok %d\n",(uint32_t)p_vci_ini_rw.rspval.read(),(uint32_t)r_vci_rsp_fifo_dcache_data.wok());
-
-        if (p_vci_ini_rw.rspval.read() and r_vci_rsp_fifo_dcache_data.wok())
-          {
-              PRINTF("      * <RSP> have rsp - r_vci_rsp_cpt : %d/%d\n",(uint32_t)r_vci_rsp_cpt.read(),(uint32_t)m_icache_words);
-
-            ASSERT(r_vci_rsp_cpt.read() < m_dcache_words,
-                   "illegal VCI response packet for data read miss");
-            r_vci_rsp_cpt = r_vci_rsp_cpt.read() + 1;
-
-            vci_rsp_fifo_dcache_put       = true,
-            vci_rsp_fifo_dcache_num_cache = r_vci_rsp_num_cache;
-            vci_rsp_fifo_dcache_data      = p_vci_ini_rw.rdata.read();
-
-            if ( p_vci_ini_rw.reop.read() ) {
-              ASSERT( ((r_vci_rsp_cpt.read() == m_dcache_words - 1) 
-                       or (p_vci_ini_rw.rerror.read()&0x1)
-                       or r_vci_rsp_data_error[r_vci_rsp_num_cache].read()),
-                      "illegal VCI response packet for data read miss");
-              r_vci_rsp_cpt     = 0;
-              r_vci_rsp_fsm     = RSP_IDLE;
-            }
-            if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_data_error[r_vci_rsp_num_cache] = true;
-          }
-        break;
-
-      case RSP_DATA_WRITE:
-        m_cost_write_transaction++;
-        if (p_vci_ini_rw.rspval.read())
-          {
-            PRINTF("      * <RSP> have rspval - error : %d\n",(int)p_vci_ini_rw.rerror.read());
-
-            ASSERT(p_vci_ini_rw.reop.read(),
-                   "A VCI response packet must contain one flit for a write transaction");
-            r_vci_rsp_fsm = RSP_IDLE;
-            uint32_t wbuf_index = p_vci_ini_rw.rtrdid.read() - (1<<(vci_param::T-1));
-            size_t cpu_id = r_wbuf[r_vci_rsp_num_cache]->getCpuId (wbuf_index);
-            bool   cached = r_wbuf[r_vci_rsp_num_cache]->completed(wbuf_index);
-            PRINTF("      * <RSP> cached : %d\n",cached);
-
-            if (not cached)
-              r_dcache_previous_unc[r_vci_rsp_num_cache] = false;
-
-            if ((p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL)
-              m_iss[cpu_id]->setWriteBerr();
-
-#if MWBUF_VHDL_TESTBENCH
-            vhdl_mwbuf_port_completed_val    [r_vci_rsp_num_cache] = (vhdl_tb_t)1;
-            vhdl_mwbuf_port_completed_index  [r_vci_rsp_num_cache] = (vhdl_tb_t)wbuf_index;
-            vhdl_mwbuf_test_completed_cached [r_vci_rsp_num_cache] = (vhdl_tb_t)1;
-            vhdl_mwbuf_port_completed_cached [r_vci_rsp_num_cache] = (vhdl_tb_t)cached;
-            vhdl_mwbuf_test_completed_cpu_id [r_vci_rsp_num_cache] = (vhdl_tb_t)1;
-            vhdl_mwbuf_port_completed_cpu_id [r_vci_rsp_num_cache] = (vhdl_tb_t)cpu_id;
-#endif
-          }
-        break;
-
-      case RSP_DATA_UNC:
-        m_cost_unc_transaction++;
-        if (p_vci_ini_rw.rspval.read() and r_vci_rsp_fifo_dcache_data.wok())
-          {
-            ASSERT(p_vci_ini_rw.reop.read(),
-                   "illegal VCI response packet for data read uncached");
-
-            vci_rsp_fifo_dcache_put       = true,
-            vci_rsp_fifo_dcache_num_cache = r_vci_rsp_num_cache;
-            vci_rsp_fifo_dcache_data      = p_vci_ini_rw.rdata.read();
-
-            r_vci_rsp_fsm = RSP_IDLE;
-            r_dcache_previous_unc[r_vci_rsp_num_cache] = false;
-
-            if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_data_error[r_vci_rsp_num_cache] = true;
-          }
-        break;
-
-      case RSP_DATA_SC:
-        m_cost_unc_transaction++;
-        if (p_vci_ini_rw.rspval.read() and r_vci_rsp_fifo_dcache_data.wok())
-          {
-            ASSERT(p_vci_ini_rw.reop.read(),
-                   "illegal VCI response packet for data SC");
-
-            vci_rsp_fifo_dcache_put       = true,
-            vci_rsp_fifo_dcache_num_cache = r_vci_rsp_num_cache;
-            vci_rsp_fifo_dcache_data      = p_vci_ini_rw.rdata.read();
-
-            r_vci_rsp_fsm = RSP_IDLE;
-            r_dcache_previous_unc[r_vci_rsp_num_cache] = false;
-
-            if ( (p_vci_ini_rw.rerror.read()&0x1) != vci_param::ERR_NORMAL ) r_vci_rsp_data_error[r_vci_rsp_num_cache] = true;
-          }
-        break;
-
-      } // end switch r_vci_rsp_fsm
-
-        //////////////////////////////////////////////////////////////////////////
-        // FIFO_RSP
-        //////////////////////////////////////////////////////////////////////////
-
-      r_vci_rsp_fifo_icache_data     .update(vci_rsp_fifo_icache_get, 
-                                             vci_rsp_fifo_icache_put, 
-                                             vci_rsp_fifo_icache_data);
-      r_vci_rsp_fifo_icache_num_cache.update(vci_rsp_fifo_icache_get, 
-                                             vci_rsp_fifo_icache_put, 
-                                             vci_rsp_fifo_icache_num_cache);
-      
-      r_vci_rsp_fifo_dcache_data     .update(vci_rsp_fifo_dcache_get, 
-                                             vci_rsp_fifo_dcache_put, 
-                                             vci_rsp_fifo_dcache_data);
-      r_vci_rsp_fifo_dcache_num_cache.update(vci_rsp_fifo_dcache_get, 
-                                             vci_rsp_fifo_dcache_put, 
-                                             vci_rsp_fifo_dcache_num_cache);
-      
-#if MWBUF_VHDL_TESTBENCH
-      for (uint32_t num_dcache=0; num_dcache<m_nb_dcache; ++num_dcache)
-        {
-          vhdl_mwbuf_test_empty            [num_dcache] = (vhdl_tb_t)1;
-          vhdl_mwbuf_port_empty            [num_dcache] = (vhdl_tb_t)r_wbuf[num_dcache]->empty();
-
-          vhdl_testbench_mwbuf [num_dcache]
-            << std::hex
-            << vhdl_mwbuf_test_empty            [num_dcache] << " "
-            << vhdl_mwbuf_port_empty            [num_dcache] << " "
-            << vhdl_mwbuf_port_flush            [num_dcache] << " "
-            << vhdl_mwbuf_port_write_val        [num_dcache] << " "
-            << vhdl_mwbuf_test_write_ack        [num_dcache] << " "
-            << vhdl_mwbuf_port_write_ack        [num_dcache] << " "
-            << vhdl_mwbuf_port_write_addr       [num_dcache] << " "
-            << vhdl_mwbuf_port_write_data       [num_dcache] << " "
-            << vhdl_mwbuf_port_write_be         [num_dcache] << " "
-            << vhdl_mwbuf_port_write_cached     [num_dcache] << " "
-            << vhdl_mwbuf_port_write_cpu_id     [num_dcache] << " "
-            << vhdl_mwbuf_test_sent_val         [num_dcache] << " "
-            << vhdl_mwbuf_port_sent_val         [num_dcache] << " "
-            << vhdl_mwbuf_port_sent_ack         [num_dcache] << " "
-            << vhdl_mwbuf_test_sent_word_min    [num_dcache] << " "
-            << vhdl_mwbuf_port_sent_word_min    [num_dcache] << " "
-            << vhdl_mwbuf_test_sent_word_max    [num_dcache] << " "
-            << vhdl_mwbuf_port_sent_word_max    [num_dcache] << " "
-            << vhdl_mwbuf_port_sent_word        [num_dcache] << " "
-            << vhdl_mwbuf_test_sent_addr        [num_dcache] << " "
-            << vhdl_mwbuf_port_sent_addr        [num_dcache] << " "
-            << vhdl_mwbuf_test_sent_data        [num_dcache] << " "
-            << vhdl_mwbuf_port_sent_data        [num_dcache] << " "
-            << vhdl_mwbuf_test_sent_be          [num_dcache] << " "
-            << vhdl_mwbuf_port_sent_be          [num_dcache] << " "
-            << vhdl_mwbuf_test_sent_index       [num_dcache] << " "
-            << vhdl_mwbuf_port_sent_index       [num_dcache] << " "
-            << vhdl_mwbuf_port_raw_test         [num_dcache] << " "
-            << vhdl_mwbuf_port_raw_addr         [num_dcache] << " "
-            << vhdl_mwbuf_test_raw_miss         [num_dcache] << " "
-            << vhdl_mwbuf_port_raw_miss         [num_dcache] << " "
-            << vhdl_mwbuf_port_completed_val    [num_dcache] << " "
-            << vhdl_mwbuf_port_completed_index  [num_dcache] << " "
-            << vhdl_mwbuf_test_completed_cached [num_dcache] << " "
-            << vhdl_mwbuf_port_completed_cached [num_dcache] << " "
-            << vhdl_mwbuf_test_completed_cpu_id [num_dcache] << " "
-            << vhdl_mwbuf_port_completed_cpu_id [num_dcache]
-            << std::dec
-            << std::endl;
-        }
-#endif
-    } // end transition()
-
-    //////////////////////////////////////////////////////////////////////////////////
-    tmpl(void)::genMoore()
-    //////////////////////////////////////////////////////////////////////////////////
+    r_vci_rsp_fifo_dcache.update(vci_rsp_fifo_dcache_get, 
+                                 vci_rsp_fifo_dcache_put, 
+                                 vci_rsp_fifo_dcache_data);
+
+} // end transition()
+
+//////////////////////////
+tmpl(void)::genMoore()
+//////////////////////////
+{
+    ////////////////////////////////////////////////////////////////
+    // VCI initiator command on the coherence network (cleanup)
+
+    vci_addr_t  address;
+
+    if ( r_cleanup_fsm.read() == CLEANUP_DATA_GO )
+        address = (vci_addr_t)r_dcache_cleanup_line.read()<<m_cache_words_shift;
+    else if ( r_cleanup_fsm.read() == CLEANUP_INS_GO )
+        address = (vci_addr_t)r_icache_cleanup_line.read()<<m_cache_words_shift;
+    else
+        address = 0;
+
+    p_vci_ini_c.cmdval  = ((r_cleanup_fsm.read() == CLEANUP_DATA_GO) or
+                           (r_cleanup_fsm.read() == CLEANUP_INS_GO) );
+    p_vci_ini_c.address = address;
+    p_vci_ini_c.wdata   = 0;
+    p_vci_ini_c.be      = 0xF;
+    p_vci_ini_c.plen    = 4;
+    p_vci_ini_c.cmd     = vci_param::CMD_WRITE;
+    p_vci_ini_c.trdid   = r_cleanup_trdid.read();
+    p_vci_ini_c.pktid   = 0;
+    p_vci_ini_c.srcid   = m_srcid_c;
+    p_vci_ini_c.cons    = false;
+    p_vci_ini_c.wrap    = false;
+    p_vci_ini_c.contig  = false;
+    p_vci_ini_c.clen    = 0;
+    p_vci_ini_c.cfixed  = false;
+    p_vci_ini_c.eop     = true;
+
+    /////////////////////////////////////////////////////////////////
+    // VCI initiator response on the coherence network (cleanup)
+
+    p_vci_ini_c.rspack  = true;
+
+    //////////////////////////////////////////////
+    // VCI initiator command on the direct network
+    switch (r_vci_cmd_fsm.read() ) 
     {
-      PRINTF("--------------------------------------------\n");
-      PRINTF("  * CC_XCACHE_WRAPPER \"%s\" genMoore - Time = %d\n",name().c_str(),(uint32_t)m_cpt_total_cycles);
-
-      // VCI initiator response
-      switch ( r_cleanup_fsm.read() ) {
-      case CLEANUP_IDLE:
-        p_vci_ini_c.rspack  = false;
-        p_vci_ini_c.cmdval  = false;
-        p_vci_ini_c.address = 0;
-        p_vci_ini_c.wdata   = 0;
-        p_vci_ini_c.be      = 0;
-        p_vci_ini_c.plen    = 0;
-        p_vci_ini_c.cmd     = vci_param::CMD_WRITE;
-        p_vci_ini_c.trdid   = 0; 
-        p_vci_ini_c.pktid   = 0;
-        p_vci_ini_c.srcid   = 0;
-        p_vci_ini_c.cons    = false;
-        p_vci_ini_c.wrap    = false;
-        p_vci_ini_c.contig  = false;
-        p_vci_ini_c.clen    = 0;
-        p_vci_ini_c.cfixed  = false;
-        p_vci_ini_c.eop     = false;
-        break;
-
-      case CLEANUP_REQ:
-        {
-          addr_40 addr;
-          if (r_cleanup_icache)
-            {
-              addr = r_icache_cleanup_line[r_cleanup_num_cache].read()<<m_icache_words_shift;
-              set_num_icache(addr,r_cleanup_num_cache);
-
-              PRINTF("      * <CLEANUP> icache             : %llx\n",(blob_t)addr);
-            }
-          else
-            {
-              addr = r_dcache_cleanup_line[r_cleanup_num_cache].read()<<m_dcache_words_shift;
-              set_num_dcache(addr,r_cleanup_num_cache);
-
-              PRINTF("      * <CLEANUP> dcache             : %llx\n",(blob_t)addr);
-            }
-
-          p_vci_ini_c.rspack  = false;
-          p_vci_ini_c.cmdval  = true;
-          p_vci_ini_c.address = addr;
-          p_vci_ini_c.wdata   = 0;
-          p_vci_ini_c.be      = 0xF;
-          p_vci_ini_c.plen    = 4;
-          p_vci_ini_c.cmd     = vci_param::CMD_WRITE;
-          p_vci_ini_c.trdid   = (r_cleanup_icache)?TYPE_INS_CLEANUP:TYPE_DATA_CLEANUP;
-          p_vci_ini_c.pktid   = (sc_dt::sc_uint<vci_param::P>)r_cleanup_num_cache;
-          p_vci_ini_c.srcid   = m_srcid_c;
-          p_vci_ini_c.cons    = false;
-          p_vci_ini_c.wrap    = false;
-          p_vci_ini_c.contig  = false;
-          p_vci_ini_c.clen    = 0;
-          p_vci_ini_c.cfixed  = false;
-          p_vci_ini_c.eop     = true;
-
-          break;
-        }
-
-      case CLEANUP_RSP_DCACHE:
-        p_vci_ini_c.rspack  = true;
-        p_vci_ini_c.cmdval  = false;
-        p_vci_ini_c.address = 0;
-        p_vci_ini_c.wdata  = 0;
-        p_vci_ini_c.be     = 0;
-        p_vci_ini_c.plen   = 0;
-        p_vci_ini_c.cmd    = vci_param::CMD_WRITE;
-        p_vci_ini_c.trdid  = 0; 
-        p_vci_ini_c.pktid  = 0;
-        p_vci_ini_c.srcid  = 0;
-        p_vci_ini_c.cons   = false;
-        p_vci_ini_c.wrap   = false;
-        p_vci_ini_c.contig = false;
-        p_vci_ini_c.clen   = 0;
-        p_vci_ini_c.cfixed = false;
-        p_vci_ini_c.eop = false;
-        break;
-
-      case CLEANUP_RSP_ICACHE:
-        p_vci_ini_c.rspack  = true;
-        p_vci_ini_c.cmdval  = false;
-        p_vci_ini_c.address = 0;
-        p_vci_ini_c.wdata  = 0;
-        p_vci_ini_c.be     = 0;
-        p_vci_ini_c.plen   = 0;
-        p_vci_ini_c.cmd    = vci_param::CMD_WRITE;
-        p_vci_ini_c.trdid  = 0; 
-        p_vci_ini_c.pktid  = 0;
-        p_vci_ini_c.srcid  = 0;
-        p_vci_ini_c.cons   = false;
-        p_vci_ini_c.wrap   = false;
-        p_vci_ini_c.contig = false;
-        p_vci_ini_c.clen   = 0;
-        p_vci_ini_c.cfixed = false;
-        p_vci_ini_c.eop = false;
-        break;
-      } // end switch r_cleanup_fsm
-
-        // VCI initiator command
-
-      switch (r_vci_cmd_fsm.read() ) {
-      case CMD_IDLE:
-        {
-          p_vci_ini_rw.cmdval  = false;
-          p_vci_ini_rw.address = 0;
-          p_vci_ini_rw.wdata   = 0;
-          p_vci_ini_rw.be      = 0;
-          p_vci_ini_rw.plen    = 0;
-          p_vci_ini_rw.cmd     = vci_param::CMD_NOP;
-          p_vci_ini_rw.trdid   = 0;
-          p_vci_ini_rw.pktid   = 0;
-          p_vci_ini_rw.srcid   = 0;
-          p_vci_ini_rw.cons    = false;
-          p_vci_ini_rw.wrap    = false;
-          p_vci_ini_rw.contig  = false;
-          p_vci_ini_rw.clen    = 0;
-          p_vci_ini_rw.cfixed  = false;
-          p_vci_ini_rw.eop     = false;
-
-          break;
-        }
-      case CMD_DATA_UNC:
-        {
-          p_vci_ini_rw.cmdval = true;
-
-          addr_40 addr = (addr_40) r_dcache_addr_save[r_vci_cmd_num_cache].read() & ~0x3;
-          set_num_dcache(addr,r_vci_cmd_num_cache);
-
-          PRINTF("      * <CMD> DATA_UNC   : %d - %llx\n",(uint32_t)r_vci_cmd_num_cache,(blob_t)(addr));
-
-          p_vci_ini_rw.address = addr;
-          switch( r_dcache_type_save[r_vci_cmd_num_cache] ) {
-          case iss_t::DATA_READ:
-            p_vci_ini_rw.wdata = 0;
-            p_vci_ini_rw.be  = r_dcache_be_save[r_vci_cmd_num_cache].read();
-            p_vci_ini_rw.cmd = vci_param::CMD_READ;
-            break;
-          case iss_t::DATA_LL:
-            p_vci_ini_rw.wdata = 0;
-            p_vci_ini_rw.be  = 0xF;
-            p_vci_ini_rw.cmd = vci_param::CMD_LOCKED_READ;
-            break;
-          default:
-            ASSERT(false,"this should not happen");
-          }
-          p_vci_ini_rw.plen = 4;
-          p_vci_ini_rw.trdid  = TYPE_DATA_UNC;   // data cache uncached read
-          p_vci_ini_rw.pktid  = (sc_dt::sc_uint<vci_param::P>)r_vci_cmd_num_cache;
-          p_vci_ini_rw.srcid  = m_srcid_rw;
-          p_vci_ini_rw.cons   = false;
-          p_vci_ini_rw.wrap   = false;
-          p_vci_ini_rw.contig = true;
-          p_vci_ini_rw.clen   = 0;
-          p_vci_ini_rw.cfixed = false;
-          p_vci_ini_rw.eop    = true;
-
-          break;
-        }
-      case CMD_DATA_SC:
-        {
-          p_vci_ini_rw.cmdval = true;
-
-          addr_40 addr = (addr_40) r_dcache_addr_save[r_vci_cmd_num_cache].read() & ~0x3;
-          set_num_dcache(addr,r_vci_cmd_num_cache);
-
-          PRINTF("      * <CMD> DATA_SC    : %d - %llx\n",(uint32_t)r_vci_cmd_num_cache,(blob_t)(addr));
-
-          p_vci_ini_rw.address = addr;
-          if(r_vci_cmd_max.read() == 3){
-            ASSERT(false, "Not handled yet");
-          } else { // r_vci_cmd_cpt == 1
-            switch(r_vci_cmd_cpt.read()){
-            case 0:
-              p_vci_ini_rw.wdata = (uint32_t)(r_dcache_ll_data[r_vci_cmd_num_cache][r_dcache_num_cpu_save[r_vci_cmd_num_cache]].read() & 0xFFFFFFFF);
-              break;
-            case 1:
-              p_vci_ini_rw.wdata = r_dcache_wdata_save[r_vci_cmd_num_cache].read();
-              break;
-            }
-          }
-          p_vci_ini_rw.be     = 0xF;
-          p_vci_ini_rw.cmd    = vci_param::CMD_STORE_COND;
-          p_vci_ini_rw.plen   = 4*(r_vci_cmd_max.read()+1);
-          p_vci_ini_rw.trdid  = TYPE_DATA_SC;   // data cache uncached read
-          p_vci_ini_rw.pktid  = (sc_dt::sc_uint<vci_param::P>)r_vci_cmd_num_cache;
-          p_vci_ini_rw.srcid  = m_srcid_rw;
-          p_vci_ini_rw.cons   = true;
-          p_vci_ini_rw.wrap   = false;
-          p_vci_ini_rw.contig = false;
-          p_vci_ini_rw.clen   = 0;
-          p_vci_ini_rw.cfixed = false;
-          p_vci_ini_rw.eop    = (r_vci_cmd_cpt.read() == r_vci_cmd_max.read());
-
-          break;
-        }
-      case CMD_DATA_WRITE:
-        {
-          p_vci_ini_rw.cmdval  = true;
-
-          addr_40 addr       = (addr_40) r_wbuf[r_vci_cmd_num_cache]->getAddress(r_vci_cmd_cpt)&~0x3;
-
-          PRINTF("      * <CMD> DATA_WRITE : %d - %llx\n",(uint32_t)r_vci_cmd_num_cache,(blob_t)(addr));
-
-          p_vci_ini_rw.address = addr;
-          p_vci_ini_rw.wdata   = r_wbuf[r_vci_cmd_num_cache]->getData(r_vci_cmd_cpt);
-          p_vci_ini_rw.be      = r_wbuf[r_vci_cmd_num_cache]->getBe(r_vci_cmd_cpt);
-          p_vci_ini_rw.plen    = (r_vci_cmd_max - r_vci_cmd_min + 1)<<2;
-          p_vci_ini_rw.cmd     = vci_param::CMD_WRITE;
-          p_vci_ini_rw.trdid   = r_wbuf[r_vci_cmd_num_cache]->getIndex() + (1<<(vci_param::T-1));
-          p_vci_ini_rw.pktid   = (sc_dt::sc_uint<vci_param::P>)r_vci_cmd_num_cache;
-          p_vci_ini_rw.srcid   = m_srcid_rw;
-          p_vci_ini_rw.cons    = false;
-          p_vci_ini_rw.wrap    = false;
-          p_vci_ini_rw.contig  = true;
-          p_vci_ini_rw.clen    = 0;
-          p_vci_ini_rw.cfixed  = false;
-          p_vci_ini_rw.eop     = (r_vci_cmd_cpt == r_vci_cmd_max);
-
-          break;
-        }
-      case CMD_DATA_MISS:
-        {
-          p_vci_ini_rw.cmdval = true;
-
-          addr_40 addr = r_dcache_addr_save[r_vci_cmd_num_cache].read() & (addr_40) m_dcache_yzmask;
-          set_num_dcache(addr,r_vci_cmd_num_cache);
-
-          PRINTF("      * <CMD> DATA_MISS  : %d - %llx\n",(uint32_t)r_vci_cmd_num_cache,(blob_t)(addr));
-
-          p_vci_ini_rw.address = addr;
-          p_vci_ini_rw.be     = 0xF;
-          p_vci_ini_rw.plen   = m_dcache_words << 2;
-          p_vci_ini_rw.cmd    = vci_param::CMD_READ;
-          p_vci_ini_rw.trdid  = TYPE_DATA_MISS;   // data cache cached read
-          p_vci_ini_rw.pktid  = (sc_dt::sc_uint<vci_param::P>)r_vci_cmd_num_cache;
-          p_vci_ini_rw.srcid  = m_srcid_rw;
-          p_vci_ini_rw.cons   = false;
-          p_vci_ini_rw.wrap   = false;
-          p_vci_ini_rw.contig = true;
-          p_vci_ini_rw.clen   = 0;
-          p_vci_ini_rw.cfixed = false;
-          p_vci_ini_rw.eop = true;
-
-          break;
-        }
-      case CMD_INS_MISS:
-        {
-          p_vci_ini_rw.cmdval = true;
-
-          addr_40 addr = r_icache_addr_save[r_vci_cmd_num_cache].read() & (addr_40) m_icache_yzmask;
-          set_num_icache(addr,r_vci_cmd_num_cache);
-
-          PRINTF("      * <CMD> INS_MISS   : %d - %llx\n",(uint32_t)r_vci_cmd_num_cache,(blob_t)(addr));
-
-          p_vci_ini_rw.address = addr;
-          p_vci_ini_rw.be     = 0xF;
-          p_vci_ini_rw.plen   = m_icache_words << 2;
-          p_vci_ini_rw.cmd    = vci_param::CMD_READ;
-          p_vci_ini_rw.trdid  = TYPE_INS_MISS;   // ins cache cached read
-          p_vci_ini_rw.pktid  = (sc_dt::sc_uint<vci_param::P>)r_vci_cmd_num_cache;
-          p_vci_ini_rw.srcid  = m_srcid_rw;
-          p_vci_ini_rw.cons   = false;
-          p_vci_ini_rw.wrap   = false;
-          p_vci_ini_rw.contig = true;
-          p_vci_ini_rw.clen   = 0;
-          p_vci_ini_rw.cfixed = false;
-          p_vci_ini_rw.eop = true;
-
-          break;
-        }
-      case CMD_INS_UNC:
-        {
-          p_vci_ini_rw.cmdval = true;
-
-          addr_40 addr = r_icache_addr_save[r_vci_cmd_num_cache].read() & ~0x3;
-          set_num_icache(addr,r_vci_cmd_num_cache);
-
-          PRINTF("      * <CMD> INS_UNC    : %d - %llx\n",(uint32_t)r_vci_cmd_num_cache,(blob_t)(addr));
-
-          p_vci_ini_rw.address = addr;
-          p_vci_ini_rw.be     = 0xF;
-          p_vci_ini_rw.plen   = 4;
-          p_vci_ini_rw.cmd    = vci_param::CMD_READ;
-          p_vci_ini_rw.trdid  = TYPE_INS_UNC;   // ins cache uncached read
-          p_vci_ini_rw.pktid  = (sc_dt::sc_uint<vci_param::P>)r_vci_cmd_num_cache;
-          p_vci_ini_rw.srcid  = m_srcid_rw;
-          p_vci_ini_rw.cons   = false;
-          p_vci_ini_rw.wrap   = false;
-          p_vci_ini_rw.contig = true;
-          p_vci_ini_rw.clen   = 0;
-          p_vci_ini_rw.cfixed = false;
-          p_vci_ini_rw.eop = true;
-
-          break;
-        }
-      } // end switch r_vci_cmd_fsm
-
-      switch (r_vci_rsp_fsm.read() ) {
-      case RSP_DATA_WRITE : p_vci_ini_rw.rspack = true; break;
-      case RSP_INS_MISS   :
-      case RSP_INS_UNC    : p_vci_ini_rw.rspack = r_vci_rsp_fifo_icache_data.wok(); break;
-      case RSP_DATA_MISS  :
-      case RSP_DATA_UNC   :
-      case RSP_DATA_SC    : p_vci_ini_rw.rspack = r_vci_rsp_fifo_dcache_data.wok(); break;
-      case RSP_IDLE       :
-      default             : p_vci_ini_rw.rspack = false; break;
-      } // end switch r_vci_rsp_fsm
-
-      // VCI_TGT
-
-      // PRINTF("      * <TGT> srcid : %d\n", r_tgt_srcid.read());
-
-      switch ( r_vci_tgt_fsm.read() ) {
-
-      case TGT_IDLE:
-      case TGT_UPDT_WORD:
-      case TGT_UPDT_DATA:
-        p_vci_tgt.cmdack  = true;
-        p_vci_tgt.rspval  = false;
-        break;
-
-      case TGT_RSP_BROADCAST:
-        {
-          bool tgt_icache_req;
-          bool tgt_icache_rsp;
-
-#if   (CC_XCACHE_WRAPPER_MULTI_CACHE==1)
-          tgt_icache_req = r_tgt_icache_req[r_tgt_num_cache].read();
-          tgt_icache_rsp = r_tgt_icache_rsp[r_tgt_num_cache].read();
-#elif (CC_XCACHE_WRAPPER_MULTI_CACHE==2)
-          tgt_icache_req = false;
-          tgt_icache_rsp = false;
-          for (uint32_t num_cache=0; num_cache<m_nb_icache; ++num_cache)
-            {
-              tgt_icache_req |= r_tgt_icache_req[num_cache].read();
-              tgt_icache_rsp |= r_tgt_icache_rsp[num_cache].read();
-            }
-#endif
-
-          bool rspval = ((not tgt_icache_req and not r_tgt_dcache_req[r_tgt_num_cache].read()) 
-                         and (tgt_icache_rsp | r_tgt_dcache_rsp[r_tgt_num_cache]));
-
-          PRINTF("      * <TGT> RSP_BROADCAST : rspval : %d (i %d %d, d %d %d)\n",rspval,tgt_icache_req,tgt_icache_rsp, r_tgt_dcache_req[r_tgt_num_cache].read(), r_tgt_dcache_rsp[r_tgt_num_cache].read());
-                    
-          p_vci_tgt.cmdack  = false;
-          p_vci_tgt.rspval  = rspval;
-          p_vci_tgt.rsrcid  = r_tgt_srcid.read();
-          p_vci_tgt.rpktid  = r_tgt_pktid.read();
-          p_vci_tgt.rtrdid  = r_tgt_trdid.read();
-          p_vci_tgt.rdata   = 0;
-          p_vci_tgt.rerror  = 0x2 & ( (1 << vci_param::E) - 1); // Write OK
-          p_vci_tgt.reop    = true;
-          break;
-        }
-      case TGT_RSP_ICACHE:
-        {
-          bool rspval = not r_tgt_icache_req[r_tgt_num_cache].read() and r_tgt_icache_rsp[r_tgt_num_cache].read();
-
-          PRINTF("      * <TGT> RSP_ICACHE : rspval : %d\n",rspval);
-
-          p_vci_tgt.cmdack  = false;
-          p_vci_tgt.rspval  = rspval;
-          p_vci_tgt.rsrcid  = r_tgt_srcid.read();
-          p_vci_tgt.rpktid  = r_tgt_pktid.read();
-          p_vci_tgt.rtrdid  = r_tgt_trdid.read();
-          p_vci_tgt.rdata   = 0;
-          p_vci_tgt.rerror  = 0x2 & ( (1 << vci_param::E) - 1); // Write OK
-          p_vci_tgt.reop    = true;
-          break;
-        }
-      case TGT_RSP_DCACHE:
-        {
-          bool rspval = not r_tgt_dcache_req[r_tgt_num_cache].read() and r_tgt_dcache_rsp[r_tgt_num_cache].read();
-
-          PRINTF("      * <TGT> RSP_DCACHE : rspval : %d\n",rspval);
-                    
-          p_vci_tgt.cmdack  = false;
-          p_vci_tgt.rspval  = rspval;
-          p_vci_tgt.rsrcid  = r_tgt_srcid.read();
-          p_vci_tgt.rpktid  = r_tgt_pktid.read();
-          p_vci_tgt.rtrdid  = r_tgt_trdid.read();
-          p_vci_tgt.rdata   = 0;
-          p_vci_tgt.rerror  = 0x2 & ( (1 << vci_param::E) - 1); // Write OK
-          p_vci_tgt.reop    = true;
-          break;
-        }
-      case TGT_REQ_BROADCAST:
-      case TGT_REQ_ICACHE:
-      case TGT_REQ_DCACHE:
-        p_vci_tgt.cmdack  = false;
-        p_vci_tgt.rspval  = false;
-        break;
-
-      } // end switch TGT_FSM
-    } // end genMoore()
+        case CMD_IDLE:
+        {
+            p_vci_ini_d.cmdval  = false;
+            p_vci_ini_d.address = 0;
+            p_vci_ini_d.wdata   = 0;
+            p_vci_ini_d.be      = 0;
+            p_vci_ini_d.plen    = 0;
+            p_vci_ini_d.cmd     = vci_param::CMD_NOP;
+            p_vci_ini_d.trdid   = 0;
+            p_vci_ini_d.pktid   = 0;
+            p_vci_ini_d.srcid   = 0;
+            p_vci_ini_d.cons    = false;
+            p_vci_ini_d.wrap    = false;
+            p_vci_ini_d.contig  = false;
+            p_vci_ini_d.clen    = 0;
+            p_vci_ini_d.cfixed  = false;
+            p_vci_ini_d.eop     = false;
+            break;
+        }
+        case CMD_DATA_UNC:
+        {
+            p_vci_ini_d.cmdval  = true;
+            p_vci_ini_d.address = (vci_addr_t) r_dcache_addr_save.read() & ~0x3;
+            p_vci_ini_d.wdata   = 0;
+            p_vci_ini_d.be      = r_dcache_be_save.read();
+            p_vci_ini_d.cmd     = vci_param::CMD_READ;
+            p_vci_ini_d.plen    = 4;
+            p_vci_ini_d.trdid   = TYPE_DATA_UNC; 
+            p_vci_ini_d.pktid   = 0;
+            p_vci_ini_d.srcid   = m_srcid_d;
+            p_vci_ini_d.cons    = false;
+            p_vci_ini_d.wrap    = false;
+            p_vci_ini_d.contig  = true;
+            p_vci_ini_d.clen    = 0;
+            p_vci_ini_d.cfixed  = false;
+            p_vci_ini_d.eop     = true;
+            break;
+        }
+        case CMD_DATA_SC:
+        {
+            p_vci_ini_d.cmdval  = true;
+            p_vci_ini_d.address = (vci_addr_t)r_dcache_addr_save.read() & ~0x3;
+            if ( r_vci_cmd_cpt.read() == 0 ) p_vci_ini_d.wdata = r_dcache_ll_data.read();
+            else                             p_vci_ini_d.wdata = r_dcache_wdata_save.read();
+            p_vci_ini_d.be      = 0xF;
+            p_vci_ini_d.cmd     = vci_param::CMD_STORE_COND;
+            p_vci_ini_d.plen    = 8;
+            p_vci_ini_d.trdid   = TYPE_DATA_UNC; 
+            p_vci_ini_d.pktid   = 0;
+            p_vci_ini_d.srcid   = m_srcid_d;
+            p_vci_ini_d.cons    = true;
+            p_vci_ini_d.wrap    = false;
+            p_vci_ini_d.contig  = false;
+            p_vci_ini_d.clen    = 0;
+            p_vci_ini_d.cfixed  = false;
+            p_vci_ini_d.eop     = (r_vci_cmd_cpt.read() == 1);
+            break;
+        }
+        case CMD_DATA_WRITE:
+        {
+            p_vci_ini_d.cmdval  = true;
+            p_vci_ini_d.address = (vci_addr_t)r_wbuf->getAddress(r_vci_cmd_cpt.read())&~0x3;
+            p_vci_ini_d.wdata   = r_wbuf->getData(r_vci_cmd_cpt.read());
+            p_vci_ini_d.be      = r_wbuf->getBe(r_vci_cmd_cpt.read());
+            p_vci_ini_d.plen    = (r_vci_cmd_max - r_vci_cmd_min + 1)<<2;
+            p_vci_ini_d.cmd     = vci_param::CMD_WRITE;
+            p_vci_ini_d.trdid   = r_wbuf->getIndex() + (1<<(vci_param::T-1));
+            p_vci_ini_d.pktid   = 0;
+            p_vci_ini_d.srcid   = m_srcid_d;
+            p_vci_ini_d.cons    = false;
+            p_vci_ini_d.wrap    = false;
+            p_vci_ini_d.contig  = true;
+            p_vci_ini_d.clen    = 0;
+            p_vci_ini_d.cfixed  = false;
+            p_vci_ini_d.eop     = (r_vci_cmd_cpt.read() == r_vci_cmd_max.read());
+            break;
+        }
+        case CMD_DATA_MISS:
+        {
+            p_vci_ini_d.cmdval  = true;
+            p_vci_ini_d.address = (vci_addr_t)r_dcache_addr_save.read() & (vci_addr_t)m_cache_yzmask;
+            p_vci_ini_d.be      = 0xF;
+            p_vci_ini_d.plen    = m_cache_words << 2;
+            p_vci_ini_d.cmd     = vci_param::CMD_READ;
+            p_vci_ini_d.trdid   = TYPE_DATA_MISS; 
+            p_vci_ini_d.pktid   = 0;
+            p_vci_ini_d.srcid   = m_srcid_d;
+            p_vci_ini_d.cons    = false;
+            p_vci_ini_d.wrap    = false;
+            p_vci_ini_d.contig  = true;
+            p_vci_ini_d.clen    = 0;
+            p_vci_ini_d.cfixed  = false;
+            p_vci_ini_d.eop     = true;
+            break;
+        }
+        case CMD_INS_MISS:
+        {
+            p_vci_ini_d.cmdval  = true;
+            p_vci_ini_d.address = (vci_addr_t)r_icache_addr_save.read() & (vci_addr_t)m_cache_yzmask;
+            p_vci_ini_d.be      = 0xF;
+            p_vci_ini_d.plen    = m_cache_words << 2;
+            p_vci_ini_d.cmd     = vci_param::CMD_READ;
+            p_vci_ini_d.trdid   = TYPE_INS_MISS; 
+            p_vci_ini_d.pktid   = 0;
+            p_vci_ini_d.srcid   = m_srcid_d;
+            p_vci_ini_d.cons    = false;
+            p_vci_ini_d.wrap    = false;
+            p_vci_ini_d.contig  = true;
+            p_vci_ini_d.clen    = 0;
+            p_vci_ini_d.cfixed  = false;
+            p_vci_ini_d.eop     = true;
+            break;
+        }
+        case CMD_INS_UNC:
+        {
+            p_vci_ini_d.cmdval  = true;
+            p_vci_ini_d.address = (vci_addr_t)r_icache_addr_save.read() & ~0x3;
+            p_vci_ini_d.be      = 0xF;
+            p_vci_ini_d.plen    = 4;
+            p_vci_ini_d.cmd     = vci_param::CMD_READ;
+            p_vci_ini_d.trdid   = TYPE_INS_UNC;  
+            p_vci_ini_d.pktid   = 0;
+            p_vci_ini_d.srcid   = m_srcid_d;
+            p_vci_ini_d.cons    = false;
+            p_vci_ini_d.wrap    = false;
+            p_vci_ini_d.contig  = true;
+            p_vci_ini_d.clen    = 0;
+            p_vci_ini_d.cfixed  = false;
+            p_vci_ini_d.eop     = true;
+            break;
+        }
+    } // end switch r_vci_cmd_fsm
+
+    ///////////////////////////////////////////////
+    // VCI initiator response on the direct network
+    switch (r_vci_rsp_fsm.read() ) 
+    {
+        case RSP_DATA_WRITE : p_vci_ini_d.rspack = true; break;
+        case RSP_INS_MISS   :
+        case RSP_INS_UNC    : p_vci_ini_d.rspack = r_vci_rsp_fifo_icache.wok(); break;
+        case RSP_DATA_MISS  :
+        case RSP_DATA_UNC   :
+        case RSP_DATA_SC    : p_vci_ini_d.rspack = r_vci_rsp_fifo_dcache.wok(); break;
+        case RSP_IDLE       :
+        default             : p_vci_ini_d.rspack = false; break;
+    } // end switch r_vci_rsp_fsm
+
+    ////////////////////////////////////////////////////////////
+    // VCI target command and  response on the coherence network
+    switch ( r_tgt_fsm.read() ) 
+    {
+        case TGT_IDLE:
+        case TGT_UPDT_WORD:
+        case TGT_UPDT_DATA:
+        {
+            p_vci_tgt_c.cmdack  = true;
+            p_vci_tgt_c.rspval  = false;
+            break;
+        }
+        case TGT_RSP_BROADCAST:
+        {
+            p_vci_tgt_c.cmdack  = false;
+            p_vci_tgt_c.rspval  = (not r_tgt_icache_req.read() and not r_tgt_dcache_req.read()) 
+                                  and (r_tgt_icache_rsp.read() or r_tgt_dcache_rsp.read());
+            p_vci_tgt_c.rsrcid  = r_tgt_srcid.read();
+            p_vci_tgt_c.rpktid  = r_tgt_pktid.read();
+            p_vci_tgt_c.rtrdid  = r_tgt_trdid.read();
+            p_vci_tgt_c.rdata   = 0;
+            p_vci_tgt_c.rerror  = 0; 
+            p_vci_tgt_c.reop    = true;
+            break;
+        }
+        case TGT_RSP_ICACHE:
+        {
+            p_vci_tgt_c.cmdack  = false;
+            p_vci_tgt_c.rspval  = not r_tgt_icache_req.read() and r_tgt_icache_rsp.read();
+            p_vci_tgt_c.rsrcid  = r_tgt_srcid.read();
+            p_vci_tgt_c.rpktid  = r_tgt_pktid.read();
+            p_vci_tgt_c.rtrdid  = r_tgt_trdid.read();
+            p_vci_tgt_c.rdata   = 0;
+            p_vci_tgt_c.rerror  = 0; 
+            p_vci_tgt_c.reop    = true;
+            break;
+        }
+        case TGT_RSP_DCACHE:
+        {
+            p_vci_tgt_c.cmdack  = false;
+            p_vci_tgt_c.rspval  = not r_tgt_dcache_req.read() and r_tgt_dcache_rsp.read();
+            p_vci_tgt_c.rsrcid  = r_tgt_srcid.read();
+            p_vci_tgt_c.rpktid  = r_tgt_pktid.read();
+            p_vci_tgt_c.rtrdid  = r_tgt_trdid.read();
+            p_vci_tgt_c.rdata   = 0;
+            p_vci_tgt_c.rerror  = 0;
+            p_vci_tgt_c.reop    = true;
+            break;
+        }
+        case TGT_REQ_BROADCAST:
+        case TGT_REQ_ICACHE:
+        case TGT_REQ_DCACHE:
+        {
+            p_vci_tgt_c.cmdack  = false;
+            p_vci_tgt_c.rspval  = false;
+            break;
+        }
+    } // end switch TGT_FSM
+} // end genMoore()
   
-    //////////////////////////////////////////////////////////////////////////////////
-    tmpl(void)::stop_simulation (uint32_t nb_frz_cycles)
-    //////////////////////////////////////////////////////////////////////////////////
-    {
-#if CC_XCACHE_WRAPPER_STOP_SIMULATION
-      if (nb_frz_cycles == 0)
-        {
-          PRINTF("CC_XCACHE_WRAPPER \"%s\" : don't stop the simulation.\n",name().c_str());
-          m_stop_simulation = false;
-        }
-      else
-        {
-          PRINTF("CC_XCACHE_WRAPPER \"%s\" : stop the simulation after %d cycles.\n",name().c_str(),nb_frz_cycles);
-          m_stop_simulation = true;
-          m_stop_simulation_nb_frz_cycles_max = nb_frz_cycles;
-        }
-#else
-      std::cout << "CC_XCACHE_WRAPPER \"" << name() << "\" : flag CC_XCACHE_WRAPPER_STOP_SIMULATION is unset, you can't use stop_simulation." << std::endl;
-#endif // CC_XCACHE_WRAPPER_STOP_SIMULATION
-        
-    }
-
-    //////////////////////////////////////////////////////////////////////////////////
-    tmpl(void)::log_transaction ( bool generate_file_icache
-                                  ,bool generate_file_dcache
-                                  ,bool generate_file_cmd
-                                  ,bool generate_file_tgt
-                                  ,bool generate_file_cleanup)
-    //////////////////////////////////////////////////////////////////////////////////
-    {
-#if CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION
-      generate_log_transaction_file_icache  = generate_file_icache ;
-      generate_log_transaction_file_dcache  = generate_file_dcache ;
-      generate_log_transaction_file_cmd     = generate_file_cmd    ;
-      generate_log_transaction_file_tgt     = generate_file_tgt    ;
-      generate_log_transaction_file_cleanup = generate_file_cleanup;
-#else
-      std::cout << "CC_XCACHE_WRAPPER \"" << name() << "\" : flag CC_XCACHE_WRAPPER_DEBUG_FILE_TRANSACTION is unset, you can't use log_transaction." << std::endl;
-#endif // CC_XCACHE_WRAPPER_STOP_SIMULATION
-        
-    }
-
-    //////////////////////////////////////////////////////////////////////////////////
-    tmpl(void)::vhdl_testbench (bool generate_file_mwbuf)
-    //////////////////////////////////////////////////////////////////////////////////
-    {
-#if MWBUF_VHDL_TESTBENCH
-      if (simulation_started)
-        std::cout << "CC_XCACHE_WRAPPER \"" << name() << "\" : Simulation is starting, you can't use vhdl_testbench." << std::endl;
-      else
-        generate_vhdl_testbench_mwbuf = generate_file_mwbuf;
-#else
-      std::cout << "CC_XCACHE_WRAPPER \"" << name() << "\" : flag MWBUF_VHDL_TESTBENCH is unset, you can't use vhdl_testbench." << std::endl;
-#endif // CC_XCACHE_WRAPPER_STOP_SIMULATION
-    }
-
-    //////////////////////////////////////////////////////////////////////////////////
-    tmpl(uint32_t)::get_num_cache(addr_40 & addr)
-    //////////////////////////////////////////////////////////////////////////////////
-    {
-      uint32_t num_cache = get_num_cache_only(addr);
-
-      addr = ((addr&m_num_cache_LSB_mask) | // keep LSB
-              ((addr>>m_num_cache_MSB)<<m_num_cache_LSB)); // set MSB
-
-      return num_cache;
-    }
-
-    //////////////////////////////////////////////////////////////////////////////////
-    tmpl(uint32_t)::get_num_cache_only(addr_40 addr)
-    //////////////////////////////////////////////////////////////////////////////////
-    {
-      return (addr>>m_num_cache_LSB)&m_num_cache_mask;
-    }
-
-    //////////////////////////////////////////////////////////////////////////////////
-    tmpl(void)::set_num_cache(addr_40 & addr, uint32_t num_cache)
-    //////////////////////////////////////////////////////////////////////////////////
-    {
-      addr = ((addr&m_num_cache_LSB_mask) | // keep LSB
-              ((addr_40)num_cache << m_num_cache_LSB) |
-              ((addr>>m_num_cache_LSB)<<m_num_cache_MSB)); // set MSB
-    }
-
-    //////////////////////////////////////////////////////////////////////////////////
-    // FIXME : mettre le type addr_40
-    tmpl(sc_dt::sc_uint<40>)::set_num_cache_only(addr_40 addr, uint32_t num_cache) 
-    //////////////////////////////////////////////////////////////////////////////////
-    {
-      return ((addr&m_num_cache_LSB_mask) | // keep LSB
-              ((addr_40)num_cache << m_num_cache_LSB) |
-              ((addr>>m_num_cache_LSB)<<m_num_cache_MSB)); // set MSB
-    }
-
-
-  }} // end namespace
+
+}} // end namespace
 
 // Local Variables:
