Index: trunk/modules/vci_cc_xcache_wrapper_multi/caba/source/include/vci_cc_xcache_wrapper_multi.h
===================================================================
--- trunk/modules/vci_cc_xcache_wrapper_multi/caba/source/include/vci_cc_xcache_wrapper_multi.h	(revision 44)
+++ trunk/modules/vci_cc_xcache_wrapper_multi/caba/source/include/vci_cc_xcache_wrapper_multi.h	(revision 45)
@@ -65,4 +65,5 @@
         DCACHE_MISS_UPDT,
         DCACHE_UNC_WAIT,
+        DCACHE_UNC_GO,
         DCACHE_INVAL,
         DCACHE_SYNC,
@@ -80,4 +81,5 @@
         ICACHE_MISS_UPDT,
         ICACHE_UNC_WAIT,
+        ICACHE_UNC_GO,
         ICACHE_ERROR,
         ICACHE_CC_CHECK,
@@ -117,7 +119,7 @@
 
     enum cleanup_fsm_state_e {
-        CLEANUP_CMD,
-        CLEANUP_DCACHE_RSP,
-        CLEANUP_ICACHE_RSP,
+        CLEANUP_IDLE,
+        CLEANUP_DCACHE,
+        CLEANUP_ICACHE,
     };
 
@@ -148,5 +150,4 @@
     const uint32_t      						m_srcid_c;   
    
-    const size_t                                m_wbuf_nlines; 
     const size_t        						m_dcache_ways;
     const size_t        						m_dcache_words;
@@ -233,25 +234,34 @@
     uint32_t m_cpt_icache_dir_write;        // ICACHE DIR WRITE
 
-    uint32_t m_cpt_cc_update;               // number of coherence update packets 
-    uint32_t m_cpt_cc_inval;                // number of coherence inval packets
+    uint32_t m_cpt_cc_broadcast;            // number of coherence broadcast packets 
+    uint32_t m_cpt_cc_update_data;          // number of coherence data update packets 
+    uint32_t m_cpt_cc_update_ins;           // number of coherence instruction update packets 
+    uint32_t m_cpt_cc_inval_data;           // number of coherence data inval packets
+    uint32_t m_cpt_cc_inval_ins;            // number of coherence instruction inval packets
+    uint32_t m_cpt_cc_cleanup_data;         // number of coherence data cleanup packets
+    uint32_t m_cpt_cc_cleanup_ins;          // number of coherence instruction cleanup packets
 
     uint32_t m_cpt_frz_cycles;	            // number of cycles where the cpu is frozen
     uint32_t m_cpt_total_cycles;	    // total number of cycles 
 
-    uint32_t m_cpt_read;                    // total number of read instructions
-    uint32_t m_cpt_write;                   // total number of write instructions
+    uint32_t m_cpt_read;                    // total number of read requests
+    uint32_t m_cpt_write;                   // total number of write requests
+    uint32_t m_cpt_write_cached;            // number of cached write requests
+    uint32_t m_cpt_data_unc;                // number of uncachable data requests
+    uint32_t m_cpt_ins_unc;                 // number of uncachable instruction requests
+    uint32_t m_cpt_ll;                      // number of ll requests
+    uint32_t m_cpt_sc;                      // number of sc requests
     uint32_t m_cpt_data_miss;               // number of read miss
     uint32_t m_cpt_ins_miss;                // number of instruction miss
-    uint32_t m_cpt_unc_read;                // number of read uncached
-    uint32_t m_cpt_write_cached;            // number of cached write
 
     uint32_t m_cost_write_frz;              // number of frozen cycles related to write buffer         
     uint32_t m_cost_data_miss_frz;          // number of frozen cycles related to data miss
-    uint32_t m_cost_unc_read_frz;           // number of frozen cycles related to uncached read
+    uint32_t m_cost_unc_frz;                // number of frozen cycles related to uncached read
     uint32_t m_cost_ins_miss_frz;           // number of frozen cycles related to ins miss
 
     uint32_t m_cpt_imiss_transaction;       // number of VCI instruction miss transactions
     uint32_t m_cpt_dmiss_transaction;       // number of VCI data miss transactions
-    uint32_t m_cpt_unc_transaction;         // number of VCI uncached read transactions
+    uint32_t m_cpt_data_unc_transaction;    // number of VCI instruction uncached transactions
+    uint32_t m_cpt_ins_unc_transaction;     // number of VCI data uncached transactions
     uint32_t m_cpt_write_transaction;       // number of VCI write transactions
 
@@ -278,10 +288,11 @@
                        size_t dcache_words,
                        size_t wbuf_nwords,
-                       size_t wbuf_nlines );
+                       size_t wbuf_nlines,
+                       size_t wbuf_timeout);
 
     ~VciCcXCacheWrapperMulti();
 
-    void print_cpi();
-    void print_stats();
+    void printTrace(size_t mode);
+    void printStatistics();
 
 private:
@@ -290,6 +301,6 @@
     void genMoore();
 
-    soclib_static_assert((int)iss_t::SC_ATOMIC == (int)vci_param::STORE_COND_ATOMIC);
-    soclib_static_assert((int)iss_t::SC_NOT_ATOMIC == (int)vci_param::STORE_COND_NOT_ATOMIC);
+    static_assert((int)iss_t::SC_ATOMIC == (int)vci_param::STORE_COND_ATOMIC);
+    static_assert((int)iss_t::SC_NOT_ATOMIC == (int)vci_param::STORE_COND_NOT_ATOMIC);
 };
 
Index: trunk/modules/vci_cc_xcache_wrapper_multi/caba/source/src/vci_cc_xcache_wrapper_multi.cpp
===================================================================
--- trunk/modules/vci_cc_xcache_wrapper_multi/caba/source/src/vci_cc_xcache_wrapper_multi.cpp	(revision 44)
+++ trunk/modules/vci_cc_xcache_wrapper_multi/caba/source/src/vci_cc_xcache_wrapper_multi.cpp	(revision 45)
@@ -54,5 +54,5 @@
 //   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
+//   the requests are merged in the same word. In case of uncachable write
 //   requests, each request is transmited as a single VCI transaction.
 //   Both the data & instruction caches can be flushed in one single cycle.
@@ -65,5 +65,5 @@
 //   introduced. The VCI command & response FSMs are not synchronized anymore:
 //   The read requests can be transmitted before previous write requests
-//   (if the missing address does not match apending write in the write buffer)
+//   (if the missing address does not match a pending write in the write buffer)
 //   and several read & write requests can be simultaneously transmitted.
 //   The transactions can complete in any order, depending on the network.
@@ -76,11 +76,22 @@
 //   on the line index in the write buffer: PKTID = 2*wbuf_index + 1
 //   The transaction index has an even value for a read transaction, with only
-//   only four possible values, depending on cached/uncached & data/instruction.
+//   only four possible values, depending on cachable/uncachable & data/instruction.
 //   A new CLEANUP FSM has been introduced to transmit the cleanups 
 //   request from the DCACHE & ICACHE FSM on the coherence network.
-//   The LL/SC requests are still uncached.
+//   The LL/SC requests are still uncachable.
+// - 07/06/2010
+//   The DCACHE FSM has been modified to enforce a well defined consistency model:
+//   1) All uncachable acces (both read and write) are now blocking
+//      the processor until the VCI response is received.
+//      Uncachable access are considered as I/O access and must respect
+//      a strict sequencial policy.
+//   2) For cachable access, the write buffer supports the "read after write"
+//      rule, and the "write after write" rule : registered write requests
+//      are tested before handling a read miss, and before locking a buffer line.
+//   The MultiWriteBuffer component has been modified, to support
+//   these rules, and to have an associative behavior: it can exist several
+//   open lines, with a private time-out for each open line.
+//   A printTrace() method has been defined.
 ///////////////////////////////////////////////////////////////////////////////
-
-//#define SOCLIB_MODULE_DEBUG 1
 
 #include <cassert>
@@ -91,5 +102,4 @@
 namespace caba {
 
-#if SOCLIB_MODULE_DEBUG
     namespace {
         const char *dcache_fsm_state_str[] = {
@@ -102,4 +112,5 @@
             "DCACHE_MISS_UPDT   ",
             "DCACHE_UNC_WAIT    ",
+            "DCACHE_UNC_GO      ",
             "DCACHE_INVAL       ",
             "DCACHE_SYNC        ",
@@ -116,4 +127,5 @@
             "ICACHE_MISS_UPDT   ",
             "ICACHE_UNC_WAIT    ",
+            "ICACHE_UNC_GO      ",
             "ICACHE_ERROR       ",
             "ICACHE_CC_CHECK    ",
@@ -149,10 +161,9 @@
         };
         const char *cleanup_fsm_state_str[] = {
-            "CLEANUP_CMD",
-            "CLEANUP_DCACHE_RSP",
-            "CLEANUP_ICACHE_RSP",
+            "CLEANUP_IDLE",
+            "CLEANUP_DCACHE",
+            "CLEANUP_ICACHE",
         };
     }
-#endif
 
 #define tmpl(...)  template<typename vci_param, typename iss_t> __VA_ARGS__ VciCcXCacheWrapperMulti<vci_param, iss_t>
@@ -162,5 +173,4 @@
     /////////////////////////////////////
     tmpl(/**/)::VciCcXCacheWrapperMulti(
-    /////////////////////////////////////
             sc_module_name name,
             int proc_id,
@@ -177,5 +187,6 @@
             size_t dcache_words,
             size_t wbuf_nwords,
-            size_t wbuf_nlines )
+            size_t wbuf_nlines,
+            size_t wbuf_timeout)
         : 
             soclib::caba::BaseModule(name),
@@ -199,5 +210,4 @@
             m_icache_words(icache_words),
             m_icache_yzmask((~0)<<(uint32_log2(icache_words) + 2)),
-            m_wbuf_nlines(wbuf_nlines),
 
             r_dcache_fsm("r_dcache_fsm"),
@@ -253,12 +263,14 @@
             r_cleanup_fsm("r_cleanup_fsm"),
 
-            r_wbuf("r_wbuf", wbuf_nwords, wbuf_nlines),
+            r_wbuf("r_wbuf", wbuf_nwords, wbuf_nlines, wbuf_timeout),
             r_icache("icache", icache_ways, icache_sets, icache_words),
             r_dcache("dcache", dcache_ways, dcache_sets, dcache_words)
 
             {
-
-                assert( (m_wbuf_nlines== 1 || m_wbuf_nlines == 2 || m_wbuf_nlines == 4 || m_wbuf_nlines == 8 || m_wbuf_nlines == 16) &&
-                      "number of lines must be power of 2, no larger than 16");
+                assert( (icache_words*vci_param::B) < (1<<vci_param::K) &&
+                        "I need more PLEN bits");
+
+                assert( (vci_param::T > 2) && ((1<<(vci_param::T-1)) >= wbuf_nlines) &&
+                        "I need more TRDID bits");
 
                 r_icache_miss_buf = new data_t[icache_words];
@@ -289,5 +301,4 @@
     //////////////////////////////////////
     tmpl(/**/)::~VciCcXCacheWrapperMulti()
-    //////////////////////////////////////
     {
         delete [] r_icache_miss_buf;
@@ -297,36 +308,66 @@
     }
 
-    ////////////////////////
-    tmpl(void)::print_cpi()
-    ////////////////////////
+    ///////////////////////////////////
+    tmpl(void)::printTrace(size_t mode)
     {
-        std::cout << "CPU " << m_srcid_d << " : CPI = " 
-            << (float)m_cpt_total_cycles/(m_cpt_total_cycles - m_cpt_frz_cycles) << std::endl ;
+        typename iss_t::InstructionRequest  ireq;
+        typename iss_t::DataRequest         dreq;
+
+        m_iss.getRequests( ireq, dreq );
+        std::cout << std::dec << "Proc " << m_srcid_d << std::endl;
+        std::cout << ireq << std::endl;
+        std::cout << dreq << std::endl;
+        std::cout << "  " << dcache_fsm_state_str[r_dcache_fsm]
+                  << "  " << icache_fsm_state_str[r_icache_fsm]
+                  << "  " << cmd_fsm_state_str[r_cmd_fsm]
+                  << "  " << rsp_fsm_state_str[r_rsp_fsm]
+                  << "  " << tgt_fsm_state_str[r_tgt_fsm] 
+                  << "  " << cleanup_fsm_state_str[r_cleanup_fsm] << std::endl;
+        if(mode & 0x1)
+        {
+            r_wbuf.printTrace();
+        }
+        if(mode & 0x2)
+        {
+            std::cout << "  Data cache" << std::endl;
+            r_dcache.printTrace();
+        }
+        if(mode & 0x4)
+        {
+            std::cout << "  Instruction cache" << std::endl;
+            r_icache.printTrace();
+        }
     }
-    ////////////////////////
-    tmpl(void)::print_stats()
-        ////////////////////////
+    /////////////////////////////
+    tmpl(void)::printStatistics()
     {
         float run_cycles = (float)(m_cpt_total_cycles - m_cpt_frz_cycles);
         std::cout << "------------------------------------" << std:: dec << std::endl
-        << "CPU " << m_srcid_d << " / Time = " << m_cpt_total_cycles << std::endl
+        << "CPU " << m_srcid_d << " / cycles = " << m_cpt_total_cycles << std::endl
         << "- CPI               = " << (float)m_cpt_total_cycles/run_cycles << std::endl
         << "- READ RATE         = " << (float)m_cpt_read/run_cycles << std::endl
-        << "- UNC READ RATE     = " << (float)m_cpt_unc_read/m_cpt_read << std::endl
         << "- WRITE RATE        = " << (float)m_cpt_write/run_cycles << std::endl
         << "- CACHED WRITE RATE = " << (float)m_cpt_write_cached/m_cpt_write << std::endl
+        << "- UNC RATE          = " << (float)m_cpt_data_unc/run_cycles << std::endl
+        << "- LL RATE           = " << (float)m_cpt_ll/run_cycles << std::endl
+        << "- SC RATE           = " << (float)m_cpt_sc/run_cycles << std::endl
         << "- IMISS_RATE        = " << (float)m_cpt_ins_miss/run_cycles << std::endl
         << "- IMISS COST        = " << (float)m_cost_ins_miss_frz/m_cpt_ins_miss << std::endl
-        << "- DMISS RATE        = " << (float)m_cpt_data_miss/(m_cpt_read-m_cpt_unc_read) << std::endl
+        << "- DMISS RATE        = " << (float)m_cpt_data_miss/m_cpt_read << std::endl
         << "- DMISS COST        = " << (float)m_cost_data_miss_frz/m_cpt_data_miss << std::endl
-        << "- UNC COST          = " << (float)m_cost_unc_read_frz/m_cpt_unc_read << std::endl
+        << "- UNC COST          = " << (float)m_cost_unc_frz/m_cpt_data_unc << std::endl
         << "- WRITE COST        = " << (float)m_cost_write_frz/m_cpt_write << std::endl
-        << "- WRITE LENGTH      = " << (float)m_length_write_transaction/m_cpt_write_transaction 
-        << std::endl;
+        << "- WRITE LENGTH      = " << (float)m_length_write_transaction/m_cpt_write_transaction << std::endl
+        << "- CC_BROADCAST      = " << m_cpt_cc_broadcast << std::endl
+        << "- CC_UPDATE_DATA    = " << m_cpt_cc_update_data << std::endl
+        << "- CC_UPDATE_INS     = " << m_cpt_cc_update_ins << std::endl
+        << "- CC_INVAL_DATA     = " << m_cpt_cc_inval_data << std::endl
+        << "- CC_INVAL_INS      = " << m_cpt_cc_inval_ins << std::endl
+        << "- CC_CLEANUP_DATA   = " << m_cpt_cc_cleanup_data << std::endl
+        << "- CC_CLEANUP_INS    = " << m_cpt_cc_cleanup_ins << std::endl;
     }
 
     //////////////////////////
     tmpl(void)::transition()
-    //////////////////////////
     {
         if ( ! p_resetn.read() ) {
@@ -340,5 +381,5 @@
             r_rsp_fsm 		= RSP_IDLE;
             r_tgt_fsm 		= TGT_IDLE;
-            r_cleanup_fsm 	= CLEANUP_CMD;
+            r_cleanup_fsm 	= CLEANUP_IDLE;
 
             // write buffer & caches
@@ -378,4 +419,5 @@
             m_cpt_dcache_dir_read  = 0;
             m_cpt_dcache_dir_write = 0;
+
             m_cpt_icache_data_read  = 0;
             m_cpt_icache_data_write = 0;
@@ -383,6 +425,11 @@
             m_cpt_icache_dir_write = 0;
 
-            m_cpt_cc_update = 0;
-            m_cpt_cc_inval = 0;
+            m_cpt_cc_broadcast = 0;
+            m_cpt_cc_update_data = 0;
+            m_cpt_cc_inval_data = 0;
+            m_cpt_cc_cleanup_data = 0;
+            m_cpt_cc_update_ins = 0;
+            m_cpt_cc_inval_ins = 0;
+            m_cpt_cc_cleanup_ins = 0;
 
             m_cpt_frz_cycles = 0;
@@ -391,17 +438,21 @@
             m_cpt_read = 0;
             m_cpt_write = 0;
+            m_cpt_write_cached = 0;
+            m_cpt_data_unc = 0;
+            m_cpt_ins_unc = 0;
+            m_cpt_ll = 0;
+            m_cpt_sc = 0;
             m_cpt_data_miss = 0;
             m_cpt_ins_miss = 0;
-            m_cpt_unc_read = 0;
-            m_cpt_write_cached = 0;
 
             m_cost_write_frz = 0;
             m_cost_data_miss_frz = 0;
-            m_cost_unc_read_frz = 0;
+            m_cost_unc_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_unc_transaction = 0;
+            m_cpt_ins_unc_transaction = 0;
             m_cpt_write_transaction = 0;
 
@@ -412,6 +463,5 @@
 if ( m_srcid_d == 0 )
 {
-std::cout << "--------------------------------------------" << std::endl
-          << std::dec << "CACHE " << m_srcid_d << " / Time = " << m_cpt_total_cycles << std::endl
+std::cout << std::dec << "CcXcache " << m_srcid_d << " / Time = " << m_cpt_total_cycles << std::endl
           << "  " << dcache_fsm_state_str[r_dcache_fsm] 
           << "  " << icache_fsm_state_str[r_icache_fsm]
@@ -420,5 +470,4 @@
           << "  " << cleanup_fsm_state_str[r_cleanup_fsm]
           << "  " << tgt_fsm_state_str[r_tgt_fsm] << std::endl;
-r_wbuf.print();
 }
 #endif
@@ -499,5 +548,5 @@
                         r_tgt_brdcast= true;
                         r_tgt_fsm = TGT_REQ_BROADCAST;
-                        m_cpt_cc_inval++ ;
+                        m_cpt_cc_broadcast++;
                     }
                     else                    // multicast-update or multicast-invalidate
@@ -516,5 +565,5 @@
                             r_tgt_data    = true;
                             r_tgt_fsm = TGT_REQ_DCACHE;
-                            m_cpt_cc_inval++ ;
+                            m_cpt_cc_inval_data++;
                         } 
                         else if (cell == 4)             // update data
@@ -530,5 +579,5 @@
                             r_tgt_data     = true;
                             r_tgt_fsm  = TGT_UPDT_WORD;
-                            m_cpt_cc_update++ ;
+                            m_cpt_cc_update_data++;
                         } 
                         else if (cell == 8)              // invalidate instruction
@@ -544,5 +593,5 @@
                             r_tgt_update  = false; 
                             r_tgt_fsm = TGT_REQ_ICACHE;
-                            m_cpt_cc_inval++ ;
+                            m_cpt_cc_inval_ins++;
                         } 
                         else if (cell == 12)             // update ins
@@ -558,5 +607,5 @@
                             r_tgt_data    = false;
                             r_tgt_fsm = TGT_UPDT_WORD;
-                            m_cpt_cc_update++ ;
+                            m_cpt_cc_update_ins++;
                         } 
 
@@ -680,21 +729,36 @@
         } // end switch TGT_FSM
 
+        typename iss_t::InstructionRequest  	ireq;
+        typename iss_t::InstructionResponse 	irsp;
+
+        typename iss_t::DataRequest  		dreq;
+        typename iss_t::DataResponse 		drsp;
+
+        ireq.valid = false;
+        dreq.valid = false;
+        irsp.valid = false;
+        irsp.error = false;
+        drsp.valid = false;
+        drsp.error = false;
+
+        m_iss.getRequests( ireq, dreq );
+
         //////////////////////////////////////////////////////////////////////////////
         // The ICACHE FSM controls the following ressources:
         // - r_icache_fsm
         // - r_icache_fsm_save
-        // - r_icache instruction cache access
+        // - r_icache (read & write)
         // - r_icache_addr_save
-        // - r_icache_miss_req set
-        // - r_icache_unc_req set
-        // - r_rsp_ins_ok reset
-        // - r_rsp_ins_error reset
-        // - r_tgt_icache_req reset
+        // - r_icache_miss_req (set)
+        // - r_icache_unc_req (set)
+        // - r_rsp_ins_ok (reset)
+        // - r_rsp_ins_error (reset)
+        // - r_tgt_icache_req (reset)
         // - r_tgt_icache_rsp
-        // - r_icache_cleanup_req set
-        // - r_icache_cleanup_ine
-        // - ireq & irsp structures for communication with the processor
+        // - r_icache_cleanup_req (set)
+        // - r_icache_cleanup_line
+        // - ireq & irsp structures (communication with the processor)
         //
-        // 1/ External requests (update or invalidate) 
+        // 1/ External coherence requests (update or invalidate) 
         //    There is an external request when the r_tgt_icache_req flip-flop is set,
         //    These requests are taken into account in the IDLE and WAIT states.
@@ -704,5 +768,6 @@
         //
         // 2/ Processor requests are taken into account only in the IDLE state.
-        //    In case of MISS, or in case of uncached instruction, the FSM 
+        //    The cache access takes into account the cacheability_table.
+        //    In case of MISS, or in case of uncachable 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.
@@ -719,129 +784,37 @@
         ////////////////////////////////////////////////////////////////////////////////////
 
-        typename iss_t::InstructionRequest  ireq = ISS_IREQ_INITIALIZER;
-        typename iss_t::InstructionResponse irsp = ISS_IRSP_INITIALIZER;
-
-        typename iss_t::DataRequest  dreq = ISS_DREQ_INITIALIZER;
-        typename iss_t::DataResponse drsp = ISS_DRSP_INITIALIZER;
-
-        m_iss.getRequests( ireq, dreq );
-
         switch(r_icache_fsm) {
  
-            case ICACHE_IDLE:
-            {
-                if ( r_tgt_icache_req )    // external request
-                {
-                    if ( ireq.valid ) m_cost_ins_miss_frz++;
-                    r_icache_fsm = ICACHE_CC_CHECK;
-                    r_icache_fsm_save = r_icache_fsm;
-                    break;
-                } 
-                if ( ireq.valid ) 
-                {
-                    data_t  icache_ins = 0;
-                    bool    icache_hit = false;
-                    bool    icache_cached = m_cacheability_table[(addr_t)ireq.addr];
-                    // icache_hit & icache_ins evaluation
-                    if ( icache_cached ) 
-                    {
-                        icache_hit = r_icache.read((addr_t)ireq.addr, &icache_ins);
-                    } 
-                    else 
-                    {
-                        icache_hit = (r_rsp_ins_ok && ( (addr_t)ireq.addr == (addr_t)r_icache_addr_save));
-                        icache_ins = r_icache_miss_buf[0];
-                    }
-                    if ( ! icache_hit )  // miss
+        case ICACHE_IDLE:
+        {
+            if ( r_tgt_icache_req )    // external request
+            {
+                if ( ireq.valid ) m_cost_ins_miss_frz++;
+                r_icache_fsm = ICACHE_CC_CHECK;
+                r_icache_fsm_save = r_icache_fsm;
+                break;
+            } 
+            if ( ireq.valid ) 
+            {
+                data_t  icache_ins;
+                bool    icache_cachable = m_cacheability_table[(addr_t)ireq.addr];
+                m_cpt_icache_dir_read += m_icache_ways;
+                m_cpt_icache_data_read += m_icache_ways;
+                if ( icache_cachable ) 
+                {
+                    if ( r_icache.read((addr_t)ireq.addr, &icache_ins) ) 	// hit
+                    {
+                        r_icache_fsm        = ICACHE_IDLE;
+                        irsp.valid          = true;
+                        irsp.instruction    = icache_ins;
+                    }
+                    else                                           		// miss
                     {
                         m_cpt_ins_miss++;
                         m_cost_ins_miss_frz++;
-                        r_icache_addr_save = (addr_t)ireq.addr;
-                        if ( icache_cached ) 	// cached line
-                        {
-                            // if the missing line corresponds to a pending cleanup
-                            // the miss request to the CMD FSM must be delayed
-                            if ( r_icache_cleanup_req && 
-                               ((addr_t)r_icache_cleanup_line == (addr_t)(ireq.addr/(m_icache_words*4))) ) 
-                            {
-                                break;
-                            }
-                            else
-                            {
-                                r_icache_fsm 		= ICACHE_MISS_SELECT;
-                                r_icache_miss_req 	= true;
-                                r_rsp_ins_ok		= false;
-                            }
-                        } 
-                        else 			// uncached line
-                        {
-                            r_icache_fsm 	= ICACHE_UNC_WAIT;
-                            r_icache_unc_req 	= true;
-                            r_rsp_ins_ok	= false;
-                        }
-                    } 
-                    else  // hit : the uncached data should not be re-used
-                    {
-                        r_rsp_ins_ok = 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;
-                } // end if ireq.valid
-                break;
-            }
-            case ICACHE_MISS_SELECT:
-            {
-                m_cost_ins_miss_frz++;
-                size_t	way;
-                addr_t	index;
-                addr_t  ad = r_icache_addr_save;
-                if ( r_icache.select_before_update( ad, &way, &index) )
-                {
-                    r_icache_fsm          = ICACHE_MISS_CLEANUP; 
-                    r_icache_cleanup_save = index;
-                    r_icache_way_save     = way;
-                }
-                else
-                {
-                    r_icache_way_save     = way;
-                    r_icache_fsm          = ICACHE_MISS_WAIT;
-                }
-                break;
-            }
-            case ICACHE_MISS_CLEANUP: // try to post a cleanup request to the CLEANUP FSM
-            {
-                m_cost_ins_miss_frz++;
-                if ( r_tgt_icache_req )    // coherence request 
-                {
-                    r_icache_fsm = ICACHE_CC_CHECK;
-                    r_icache_fsm_save = r_icache_fsm;
-                    break;
-                } 
-                if ( !r_icache_cleanup_req )	// no pending cleanup
-                {
-                    r_icache_cleanup_req 	= true;
-                    r_icache_cleanup_line   = r_icache_cleanup_save.read();
-                    r_icache_fsm	    	= ICACHE_MISS_WAIT;
-                }
-                break;                
-            }
-            case ICACHE_MISS_WAIT:  // waiting the response from the RSP FSM
-            {
-                m_cost_ins_miss_frz++;
-                if ( r_tgt_icache_req )    // coherence request
-                {
-                    r_icache_fsm = ICACHE_CC_CHECK;
-                    r_icache_fsm_save = r_icache_fsm;
-                    break;
-                } 
-                if ( r_rsp_ins_ok )  // there is a response
-                {
-                    if      ( r_rsp_ins_error )		r_icache_fsm = ICACHE_ERROR;
-                    else if ( !r_icache_inval_pending )	r_icache_fsm = ICACHE_MISS_UPDT;
-                    else
-                    {
-                        if ( r_icache_cleanup_req ) 
+                        // if the missing line corresponds to a pending cleanup
+                        // the miss request to the CMD FSM must be delayed
+                        if ( r_icache_cleanup_req && 
+                           ((addr_t)r_icache_cleanup_line == (addr_t)(ireq.addr/(m_icache_words*4))) ) 
                         {
                             break;
@@ -849,103 +822,190 @@
                         else
                         {
-                            r_icache_cleanup_req = true;
-                            r_icache_cleanup_line = r_icache_addr_save.read() >> (uint32_log2(m_icache_words) + 2);
-                            r_icache_fsm = ICACHE_IDLE;
-                            r_icache_inval_pending = false;
+                            r_icache_fsm 	= ICACHE_MISS_SELECT;
+                            r_icache_addr_save  = ireq.addr;
+                            r_icache_miss_req 	= true;
+                            r_rsp_ins_ok	= false;
                         }
                     }
                 }
-                break;
-            }
-            case ICACHE_MISS_UPDT:  // update the cache 
-            {
-                m_cost_ins_miss_frz++;
-                m_cpt_icache_dir_write++;
-                m_cpt_icache_data_write++;
-                addr_t 		ad   	= (addr_t) r_icache_addr_save;
-                data_t*   	buf   	= (data_t*) r_icache_miss_buf;
-                size_t		way	= (size_t) r_icache_way_save;
-                r_icache.update_after_select( buf, way, ad );
-                r_icache_fsm = ICACHE_IDLE;
-                break;
-            }
-            case ICACHE_UNC_WAIT:
-            {
-                m_cost_ins_miss_frz++;
-                if ( r_tgt_icache_req )    // external request
-                {
-                    r_icache_fsm = ICACHE_CC_CHECK;
-                    r_icache_fsm_save = r_icache_fsm;
-                    break;
+                else                        // uncachable instruction
+                {
+                    m_cpt_ins_unc++;
+                    m_cost_ins_miss_frz++;
+                    r_icache_addr_save      = ireq.addr;
+                    r_icache_fsm            = ICACHE_UNC_WAIT;
+                    r_icache_unc_req        = true;
+                    r_rsp_ins_ok            = false;
+                }
+            }
+            break;
+        }
+        case ICACHE_MISS_SELECT: // select a victim 
+        {
+            m_cost_ins_miss_frz++;
+            size_t	way;
+            addr_t	index;
+            addr_t  ad = r_icache_addr_save;
+            if ( r_icache.select_before_update( ad, &way, &index) )
+            {
+                r_icache_fsm          = ICACHE_MISS_CLEANUP; 
+                r_icache_cleanup_save = index;
+                r_icache_way_save     = way;
+            }
+            else
+            {
+                r_icache_way_save     = way;
+                r_icache_fsm          = ICACHE_MISS_WAIT;
+            }
+            break;
+        }
+        case ICACHE_MISS_CLEANUP: // try to post a cleanup request to the CLEANUP FSM
+        {
+            m_cost_ins_miss_frz++;
+            if ( r_tgt_icache_req )    // coherence request 
+            {
+                r_icache_fsm = ICACHE_CC_CHECK;
+                r_icache_fsm_save = r_icache_fsm;
+                break;
+            } 
+            if ( !r_icache_cleanup_req )	// no pending cleanup
+            {
+                r_icache_cleanup_req 	= true;
+                r_icache_cleanup_line   = r_icache_cleanup_save;
+                r_icache_fsm	    	= ICACHE_MISS_WAIT;
+            }
+            break;                
+        }
+        case ICACHE_MISS_WAIT:  // waiting the response from the RSP FSM
+        {
+            m_cost_ins_miss_frz++;
+            if ( r_tgt_icache_req )    // coherence request
+            {
+                r_icache_fsm = ICACHE_CC_CHECK;
+                r_icache_fsm_save = r_icache_fsm;
+                break;
+            } 
+            if ( r_rsp_ins_ok )  // there is a response
+            {
+                if      ( r_rsp_ins_error )		r_icache_fsm = ICACHE_ERROR;
+                else if ( !r_icache_inval_pending )	r_icache_fsm = ICACHE_MISS_UPDT;
+                else
+                {
+                    if ( r_icache_cleanup_req ) 
+                    {
+                        break;
+                    }
+                    else
+                    {
+                        // the cache is not updated in case of pending inval 
+                        r_icache_cleanup_req = true;
+                        r_icache_cleanup_line = r_icache_addr_save.read() >> (uint32_log2(m_icache_words) + 2);
+                        r_icache_fsm = ICACHE_IDLE;
+                        r_icache_inval_pending = false;
+                    }
+                }
+            }
+            break;
+        }
+        case ICACHE_MISS_UPDT:  // update the cache 
+        {
+            m_cost_ins_miss_frz++;
+            m_cpt_icache_dir_write++;
+            m_cpt_icache_data_write++;
+            addr_t 	ad   	= (addr_t) r_icache_addr_save;
+            data_t*   	buf   	= (data_t*) r_icache_miss_buf;
+            size_t	way	= (size_t) r_icache_way_save;
+            r_icache.update_after_select( buf, way, ad );
+            r_icache_fsm = ICACHE_IDLE;
+            break;
+        }
+        case ICACHE_UNC_WAIT:
+        {
+            m_cost_ins_miss_frz++;
+            if ( r_tgt_icache_req )    // external request
+            {
+                r_icache_fsm = ICACHE_CC_CHECK;
+                r_icache_fsm_save = r_icache_fsm;
+                break;
+            } 
+            if ( r_rsp_ins_ok ) 
+            {
+                if ( r_rsp_ins_error ) 	r_icache_fsm = ICACHE_ERROR;
+                else 			r_icache_fsm = ICACHE_UNC_GO;
+            }
+            break;
+        }
+        case ICACHE_UNC_GO:
+        {
+            r_icache_fsm    = ICACHE_IDLE;
+            if( ireq.addr == r_icache_addr_save )
+            {
+                irsp.valid          = true;
+                irsp.instruction    = r_icache_miss_buf[0];
+            }
+        }
+        case ICACHE_ERROR:
+        {
+            r_icache_fsm 	= ICACHE_IDLE;
+            r_rsp_ins_error     = false;
+            irsp.error          = true;
+            irsp.valid          = true;
+            break;
+        } 
+        case ICACHE_CC_CHECK:   // read directory in case of external request
+        {
+            m_cpt_icache_dir_read += m_icache_ways;
+            m_cpt_icache_data_read += m_icache_ways;
+            if ( ( (r_icache_fsm_save == ICACHE_MISS_WAIT) || (r_icache_fsm_save == ICACHE_MISS_CLEANUP) ) && 
+                ((r_icache_addr_save & ~((m_icache_words<<2)-1))==(r_tgt_addr & ~((m_icache_words<<2)-1))))
+                 // the external request matches a miss
+            {
+                r_icache_inval_pending 	= true;
+                r_tgt_icache_req       	= false;
+                r_tgt_icache_rsp       	= r_tgt_update;  // always a response in case of update 
+                r_icache_fsm 		= r_icache_fsm_save;
+            } 
+            else  // the external request is not matching a pending miss
+            {
+                data_t  data;
+                bool    icache_hit   	= r_icache.read(r_tgt_addr, &data);
+                if ( icache_hit && r_tgt_update )  // hit update
+                {
+                    r_icache_fsm = ICACHE_CC_UPDT;
                 } 
-                if ( r_rsp_ins_ok ) 
-                {
-                    if ( r_rsp_ins_error ) 	r_icache_fsm = ICACHE_ERROR;
-                    else 			r_icache_fsm = ICACHE_IDLE;
-                }
-                break;
-            }
-            case ICACHE_ERROR:
-            {
-                r_icache_fsm = ICACHE_IDLE;
-                r_rsp_ins_error     = false;
-                irsp.error          = true;
-                irsp.valid          = true;
-                break;
-            } 
-            case ICACHE_CC_CHECK:   // read directory in case of external request
-            {
-                m_cpt_icache_dir_read += m_icache_ways;
-                m_cpt_icache_data_read += m_icache_ways;
-                if ( ( (r_icache_fsm_save == ICACHE_MISS_WAIT) || (r_icache_fsm_save == ICACHE_MISS_CLEANUP) ) && // external request matches a miss
-                ((r_icache_addr_save & ~((m_icache_words<<2)-1))==(r_tgt_addr & ~((m_icache_words<<2)-1))))
-                {
-                    r_icache_inval_pending 	= true;
-                    r_tgt_icache_req       	= false;
-                    r_tgt_icache_rsp       	= r_tgt_update;  // always a response n case of update 
-                    r_icache_fsm 		= r_icache_fsm_save;
+                else if ( icache_hit && !r_tgt_update ) // hit inval
+                {
+                    r_icache_fsm = ICACHE_CC_INVAL;
                 } 
-                else  // the external request is not matching a pending miss
-                {
-                    data_t  data;
-                    bool    icache_hit   	= r_icache.read(r_tgt_addr, &data);
-                    if ( icache_hit && r_tgt_update )  // hit update
-                    {
-                        r_icache_fsm = ICACHE_CC_UPDT;
-                    } 
-                    else if ( icache_hit && !r_tgt_update ) // hit inval
-                    {
-                        r_icache_fsm = ICACHE_CC_INVAL;
-                    } 
-                    else	// miss 
-                    { 
-                        r_tgt_icache_req 	= false;
-                        r_tgt_icache_rsp 	= r_tgt_update; // alaways a response in case of update
-                        r_icache_fsm 		= r_icache_fsm_save;
-                    }
-                }
-                break;
-            }
-            case ICACHE_CC_UPDT:    // update the cache line        
-            {
-                m_cpt_icache_dir_write++;
-                m_cpt_icache_data_write++;
-                for(size_t i=0; i<m_icache_words; i++)
-                {
-                    if(r_tgt_val[i]) r_icache.write( (r_tgt_addr + i*4), r_tgt_buf[i] );
-                }
-                r_tgt_icache_rsp = true;
-                r_tgt_icache_req = false;
-                r_icache_fsm = r_icache_fsm_save;
-                break;
-            }
-            case ICACHE_CC_INVAL:   // invalidate a cache line
-            {
-                r_icache.inval(r_tgt_addr);
-                r_tgt_icache_rsp = true;
-                r_tgt_icache_req = false;
-                r_icache_fsm = r_icache_fsm_save;
-                break;
-            }
+                else	// miss 
+                { 
+                    r_tgt_icache_req 	= false;
+                    r_tgt_icache_rsp 	= r_tgt_update; // alaways a response in case of update
+                    r_icache_fsm 	= r_icache_fsm_save;
+                }
+            }
+            break;
+        }
+        case ICACHE_CC_UPDT:    // update the cache line        
+        {
+            m_cpt_icache_dir_write++;
+            m_cpt_icache_data_write++;
+            for(size_t i=0; i<m_icache_words; i++)
+            {
+                if(r_tgt_val[i]) r_icache.write( (r_tgt_addr + i*4), r_tgt_buf[i] );
+            }
+            r_tgt_icache_rsp = true;
+            r_tgt_icache_req = false;
+            r_icache_fsm = r_icache_fsm_save;
+            break;
+        }
+        case ICACHE_CC_INVAL:   // invalidate a cache line
+        {
+            r_icache.inval(r_tgt_addr);
+            r_tgt_icache_rsp = true;
+            r_tgt_icache_req = false;
+            r_icache_fsm = r_icache_fsm_save;
+            break;
+        }
         } // end switch r_icache_fsm
 
@@ -954,5 +1014,5 @@
         // - r_dcache_fsm
         // - r_dcache_fsm_save
-        // - r_dcache (data cache access)
+        // - r_dcache (read and write)
         // - r_dcache_addr_save
         // - r_dcache_wdata_save
@@ -960,14 +1020,14 @@
         // - r_dcache_type_save
         // - r_dcache_be_save
-        // - r_dcache_miss_req set
-        // - r_dcache_unc_req set
-        // - r_rsp_data_ok reset
-        // - r_rsp_data_error reset
-        // - r_dcache_cleanup_req set
+        // - r_dcache_miss_req (set)
+        // - r_dcache_unc_req (set)
+        // - r_rsp_data_ok (reset)
+        // - r_rsp_data_error (reset)
+        // - r_dcache_cleanup_req (set)
         // - r_dcache_cleanup_ine
-        // - r_tgt_dcache_req reset
+        // - r_tgt_dcache_req (reset)
         // - r_tgt_dcache_rsp
-        // - r_wbuf write()
-        // - dreq & drsp structures for communication with the processor
+        // - r_wbuf (write)
+        // - dreq & drsp structures (communication with the processor)
         //
         // 1/ external request (invalidate or update)
@@ -982,24 +1042,23 @@
         //   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.
+        // - In IDLE state, the request is satisfied if it is a cachable read hit, 
+        //   an XTN request, or a cachable write. 
+        // - In WRITE_REQ state, the request is satisfied if it is a cachable read hit,
+        //   an XTN request, or a write when the write buffer is not full.
+        // - Both the uncachable read and the uncachable write requests block the processor
+        //   until the corresponding VCI transaction is completed.
         //
         //   The cache access takes into account the cacheability_table.
         //   In case of processor request, there is six conditions to exit the IDLE state:
-        //   - CACHED READ MISS => to the MISS_WAIT state, waiting the r_rsp_data_ok signal.
-        //     It can be delayed in the MISS_DELAY state in case of matching pending
-        //     cleanup request.  Then it goes to the MISS_UPDT state, then to the CLEANUP_REQ
-        //     state (if necessary), and finally to the IDLE state.
-        //   - UNCACHED READ  => to the UNC_WAIT state, waiting the r_rsp_data_ok signal, 
-        //     and back to the IDLE state. LL & SC are handled as uncached read.
-        //   - WRITE MISS => directly to the WRITE_REQ state to post a request in the
-        //     write buffer.
+        //   - CACHED READ MISS => to the MISS_WAIT state (waiting r_rsp_data_ok),
+        //     then to the MISS_UPDT state, and finally to the IDLE state.
+        //   - UNCACHED READ or WRITE => to the UNC_WAIT state (waiting r_rsp_data_ok),
+        //     then to the UNC_GO state, and finally to the IDLE state.
+        //   - XTN_INVAL => to the INVAL state for one cycle, then to IDLE state.
+        //   - XTN_SYNC  => to the SYNC state until write buffer empty, 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.
-        //   - LINE INVALIDATE => to the INVAL state for one cycle, then to IDLE state.
-        //   - SYNC REQUEST => to the SYNC state until the write buffer is empty.
+        //
+        //   All LL or SC requests are handled as uncachable.
         //
         // Error handling :  Read Bus Errors are synchronous events, but
@@ -1022,11 +1081,8 @@
                 break;
             }
-            if( !r_wbuf.wok(r_dcache_addr_save) ) 
+            if( !r_wbuf.write(r_dcache_addr_save, r_dcache_be_save, r_dcache_wdata_save) ) 
             {
                 // stay in DCACHE_WRITEREQ state if the write request is not accepted 
-                // by the write buffer 
                 m_cost_write_frz++;
-                drsp.valid = false;
-                drsp.rdata = 0;
                 break;
             }
@@ -1045,119 +1101,15 @@
             if ( dreq.valid ) 
             {              
-                bool        dcache_hit     = false;
-                data_t      dcache_rdata   = 0;
-                bool        dcache_cached;
+                bool        dcache_hit;
+                data_t      dcache_rdata;
+                bool        dcache_cachable;
+
+                // dcache_cachable, dcache_hit & dcache_rdata evaluation
                 m_cpt_dcache_data_read += m_dcache_ways;
                 m_cpt_dcache_dir_read += m_dcache_ways;
-
-                // dcache_cached evaluation
-                switch (dreq.type) {
-                    case iss_t::DATA_LL:
-                    case iss_t::DATA_SC:
-                    case iss_t::XTN_READ:
-                    case iss_t::XTN_WRITE:
-                        dcache_cached = false;
-                        break;
-                    default:
-                        dcache_cached = m_cacheability_table[dreq.addr];
-                }
-
-                // dcache_hit & dcache_rdata evaluation
-                if ( dcache_cached ) 
-                {
-                    dcache_hit = r_dcache.read((addr_t) dreq.addr, &dcache_rdata);
-                } 
-                else 
-                {
-                    dcache_hit = ( r_rsp_data_ok && ( dreq.addr == r_dcache_addr_save) );
-                    dcache_rdata = r_dcache_miss_buf[0];
-                }
-
-                // next state & response evaluation
-                switch( dreq.type ) {
-                    case iss_t::DATA_READ:
-                    case iss_t::DATA_LL:
-                    case iss_t::DATA_SC:
-                        m_cpt_read++;
-                        if ( dcache_hit ) 
-                        {
-                            r_dcache_fsm = DCACHE_IDLE;
-                            drsp.valid = true;
-                            drsp.rdata = dcache_rdata;
-                            r_rsp_data_ok = false;
-                        } 
-                        else 		
-                        {
-                            if ( dcache_cached )   // miss
-                            {
-                                m_cpt_data_miss++;
-                                m_cost_data_miss_frz++;
-                                // if the missing line corresponds to a pending cleanup
-                                // the miss request to the CMD FSM must be delayed
-                                if ( r_dcache_cleanup_req &&
-                                   ((addr_t)r_dcache_cleanup_line == (addr_t)(dreq.addr/(m_dcache_words*4))) )
-                                {
-                                    break;
-                                }
-                                else
-                                {
-                                    r_dcache_miss_req = true;
-                                    r_rsp_data_ok = false;
-                                    r_dcache_fsm = DCACHE_MISS_SELECT;
-                                }
-                                drsp.valid = false;
-                                drsp.rdata = 0;
-                            } 
-                            else 		// uncached
-                            {
-                                m_cpt_unc_read++;
-                                m_cost_unc_read_frz++;
-                                r_dcache_unc_req = true;
-                                r_rsp_data_ok = false;
-                                r_dcache_fsm = DCACHE_UNC_WAIT;
-                                drsp.valid = false;
-                                drsp.rdata = 0;
-                            }
-                        }
-                        break;
-                    case iss_t::XTN_READ:
-                    case iss_t::XTN_WRITE:
-                        // only DCACHE_INVAL & SYNC requests are supported
-                        if ( dreq.addr/4 == iss_t::XTN_DCACHE_INVAL )
-                        {
-                            r_dcache_fsm = DCACHE_INVAL;
-                        } 
-                        else if ( dreq.addr/4 == iss_t::XTN_SYNC )
-                        {
-                            r_dcache_fsm = DCACHE_SYNC;
-                        }
-                        else
-                        {
-//                          std::cout << "warning in VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
-//                          std::cout << "unsupported external access " << dreq.addr/4 << std::endl;
-//                          std::cout << "only XTN_DCACHE_INVAL & XTN_SYNC are supported" << std::endl;
-                        }
-                        r_dcache_fsm = DCACHE_IDLE; 
-                        drsp.valid = true;
-                        drsp.rdata = 0;
-                        break;
-                    case iss_t::DATA_WRITE:
-                        m_cpt_write++;
-                        if ( dcache_hit && dcache_cached ) 
-                        {
-                            m_cpt_write_cached++;
-                            r_dcache_fsm = DCACHE_WRITE_UPDT;
-                            drsp.valid = true;
-                            drsp.rdata = 0;
-                        } 
-                        else 
-                        {
-                            r_dcache_fsm = DCACHE_WRITE_REQ;
-                            drsp.valid = true;
-                            drsp.rdata = 0;
-                        }
-                        break;
-                } // end switch dreq.type
-
+                dcache_cachable     = m_cacheability_table[dreq.addr];
+                dcache_hit          = r_dcache.read(dreq.addr, &dcache_rdata);
+
+                // Save data request 
                 r_dcache_addr_save      = dreq.addr;
                 r_dcache_type_save      = dreq.type;
@@ -1165,13 +1117,122 @@
                 r_dcache_be_save        = dreq.be;
                 r_dcache_rdata_save     = dcache_rdata;
-            } 
-            else  // no dreq.valid
-            {
-                drsp.valid 	= false;
-                drsp.rdata 	= 0;
-                r_dcache_fsm 	= DCACHE_IDLE;
-            }
-            break;
-        }       
+
+                // reset r_rsp_data_ok
+                r_rsp_data_ok               = false;
+
+                // next FSM state, request to VCI, and processor response 
+                if(dreq.type  == iss_t::DATA_READ)
+                {
+                    if(!dcache_cachable)                              // uncachable read 
+                    {
+                        m_cpt_data_unc++;
+                        m_cost_unc_frz++;
+                        r_dcache_unc_req            = true;
+                        r_dcache_fsm                = DCACHE_UNC_WAIT;
+                    }
+                    else
+                    {
+                        m_cpt_read++;
+                        if(dcache_hit)                               // cachable read hit
+                        {
+                            drsp.valid         	= true;
+                            drsp.rdata          = dcache_rdata;
+                            r_dcache_fsm  	= DCACHE_IDLE;
+                        }
+                        else                                         // cachable read miss
+                        {
+                            m_cost_data_miss_frz++;
+                            // if the missing line corresponds to a pending cleanup
+                            // the miss request to the CMD FSM must be delayed
+                            if ( r_dcache_cleanup_req &&
+                               ((addr_t)r_dcache_cleanup_line == (addr_t)(dreq.addr/(m_dcache_words*4))) )
+                            {
+                                break;
+                            }
+                            else
+                            {
+                                m_cpt_data_miss++;
+                                r_dcache_miss_req       = true;
+                                r_dcache_fsm 		= DCACHE_MISS_SELECT;
+                            }
+                        }
+                    }
+                }
+                else if(dreq.type == iss_t::DATA_WRITE)
+                {
+                    if(!dcache_cachable)                              // uncachable write
+                    {
+                        m_cpt_data_unc++;
+                        m_cost_unc_frz++;
+                        r_dcache_unc_req       	= true;
+                        r_dcache_fsm           	= DCACHE_UNC_WAIT;
+                    }
+                    else
+                    {
+                        m_cpt_write++;
+                        if(!dcache_hit)                              // cachable write miss 
+                        {
+                            drsp.rdata         	= 0;
+                            drsp.valid         	= true;
+                            r_dcache_fsm       	= DCACHE_WRITE_REQ;
+                        }
+                        else                                         // cachable write hit 
+                        {
+                            m_cpt_write_cached++;
+                            drsp.rdata         	= 0;
+                            drsp.valid         	= true;
+                            r_dcache_fsm       	= DCACHE_WRITE_UPDT;
+                        }
+                    }
+                }
+                else if(dreq.type == iss_t::DATA_LL)                        // linked read
+                //  all LL  requests are handled as uncachable  
+                {
+                    m_cpt_ll++;
+                    m_cost_unc_frz++;
+                    r_dcache_unc_req           	= true;
+                    r_dcache_fsm               	= DCACHE_UNC_WAIT;
+                }
+                else if(dreq.type == iss_t::DATA_SC)                        // conditional write
+                //  all SC requests are handled as uncachable   
+                {
+                    m_cpt_sc++;
+                    m_cost_unc_frz++;
+                    r_dcache_unc_req           	= true;
+                    r_dcache_fsm               	= DCACHE_UNC_WAIT;
+                }
+                else if((dreq.type == iss_t::XTN_WRITE) || (dreq.type == iss_t::XTN_READ))  // XTN access
+                // only INVAL & SYNC requests are supported
+                {
+                    drsp.valid = true;
+                    drsp.rdata = 0;
+                    if ( dreq.addr/4 == iss_t::XTN_DCACHE_INVAL )
+                    {
+                        r_dcache_fsm = DCACHE_INVAL;
+                    }
+                    else if ( dreq.addr/4 == iss_t::XTN_SYNC )
+                    {
+                        r_dcache_fsm = DCACHE_SYNC;
+                    }
+                    else if ( dreq.addr/4 == iss_t::XTN_TLB_MODE )
+                    {
+                        r_dcache_fsm = DCACHE_IDLE;
+                    }
+                    else
+                    {
+                        std::cout << "warning in VCI_CC_XCACHE_WRAPPER " << name() << std::endl;
+                        std::cout << "unsupported  external access : " << dreq.addr/4 << std::endl;
+                        std::cout << "only TLB_MODE, DCACHE_INVAL & SYNC are supported" << std::endl;
+                    }
+                }
+            }
+            else // no dreq.valid
+            {
+                r_dcache_fsm = DCACHE_IDLE;
+                drsp.valid = true;
+                drsp.rdata = 0;
+            }
+            break;
+        }
         case DCACHE_WRITE_UPDT:
         {
@@ -1188,6 +1249,6 @@
             size_t	way;
             addr_t	index;
-            addr_t  ad = r_dcache_addr_save;
-            if ( r_dcache.select_before_update( ad, &way, &index) )
+            addr_t    	addr = r_dcache_addr_save;
+            if ( r_dcache.select_before_update( addr, &way, &index) )
             {
                 r_dcache_fsm          = DCACHE_MISS_CLEANUP; 
@@ -1240,4 +1301,5 @@
                     else
                     {
+                        // the cache is not updated in case of pending inval
                         r_dcache_cleanup_req = true;
                         r_dcache_cleanup_line = r_dcache_addr_save >> (uint32_log2(m_icache_words) + 2);
@@ -1263,5 +1325,5 @@
         case DCACHE_UNC_WAIT:
         {
-            if ( dreq.valid ) m_cost_unc_read_frz++;
+            if ( dreq.valid ) m_cost_unc_frz++;
             if ( r_tgt_dcache_req )    // external request
             {
@@ -1272,20 +1334,14 @@
             if ( r_rsp_data_ok ) 
             {
-                if ( r_rsp_data_error ) r_dcache_fsm = DCACHE_ERROR;
-                else 
-                {
-                    // If request is a DATA_SC we need to invalidate the corresponding cache line,
-                    // so that subsequent access to this line are read from RAM
-                    if (dreq.type == iss_t::DATA_SC)    
-                    {
-                        r_dcache_fsm = DCACHE_INVAL;
-                        r_dcache_wdata_save = r_dcache_addr_save;
-                    }
-                    else
-                    {
-                       r_dcache_fsm = DCACHE_IDLE;
-                    }
-                }
-            }
+                if ( r_rsp_data_error ) 	r_dcache_fsm = DCACHE_ERROR;
+                else 				r_dcache_fsm = DCACHE_UNC_GO;
+            }
+            break;
+        }
+        case DCACHE_UNC_GO:
+        {
+            r_dcache_fsm = DCACHE_IDLE;
+            drsp.valid = true;
+            drsp.rdata = r_dcache_miss_buf[0];
             break;
         }
@@ -1298,5 +1354,5 @@
             break;
         }
-        case DCACHE_INVAL:
+        case DCACHE_INVAL:  // local inval requiring a cleanup in case of hit
         {
             if( !r_dcache_cleanup_req )
@@ -1315,48 +1371,52 @@
         }
         case DCACHE_CC_CHECK:   // read directory in case of external request
+        {
             m_cpt_dcache_dir_read += m_dcache_ways;
             m_cpt_dcache_data_read += m_dcache_ways;
-            if ( ( (r_dcache_fsm_save == DCACHE_MISS_WAIT) || (r_dcache_fsm_save == DCACHE_MISS_CLEANUP) ) && // external request matches a miss
+            if ( ( (r_dcache_fsm_save == DCACHE_MISS_WAIT) || (r_dcache_fsm_save == DCACHE_MISS_CLEANUP) ) && 
             ((r_dcache_addr_save & ~((m_dcache_words<<2)-1))==(r_tgt_addr & ~((m_dcache_words<<2)-1))))
-                {
-                    r_dcache_inval_pending 	= true;
-                    r_tgt_dcache_req       	= false;
-                    r_tgt_dcache_rsp       	= r_tgt_update; // always a response to an update
-                    r_dcache_fsm 		= r_dcache_fsm_save;
+                    // external request matches a miss
+            {
+                r_dcache_inval_pending 	= true;
+                r_tgt_dcache_req       	= false;
+                r_tgt_dcache_rsp       	= r_tgt_update; // always a response to an update
+                r_dcache_fsm 		= r_dcache_fsm_save;
+            } 
+            else  // the external request is not matching a pending miss
+            {
+                data_t  data;
+                bool    dcache_hit   	= r_dcache.read(r_tgt_addr, &data);
+                if ( dcache_hit && r_tgt_update )  // hit update
+                {
+                    r_dcache_fsm = DCACHE_CC_UPDT;
                 } 
-                else  // the external request is not matching a pending miss
-                {
-                    data_t  data;
-                    bool    dcache_hit   	= r_dcache.read(r_tgt_addr, &data);
-                    if ( dcache_hit && r_tgt_update )  // hit update
-                    {
-                        r_dcache_fsm = DCACHE_CC_UPDT;
-                    } 
-                    else if ( dcache_hit && !r_tgt_update ) // hit inval
-                    {
-                        r_dcache_fsm = DCACHE_CC_INVAL;
-                    } 
-                    else	// miss 
-                    { 
-                        r_tgt_dcache_req = false;
-                        r_tgt_dcache_rsp = r_tgt_update;  // always a respons in case of update
-                        r_dcache_fsm = r_dcache_fsm_save;
-                    }
-                }
-                break;
-            
-            case DCACHE_CC_UPDT:    // update the cache line        
-                m_cpt_dcache_dir_write++;
-                m_cpt_dcache_data_write++;
-                for(size_t i=0; i<m_dcache_words; i++)
-                {
-                    if(r_tgt_val[i]) r_dcache.write( (r_tgt_addr + i*4), r_tgt_buf[i] );
-                }
-                r_tgt_dcache_rsp = true;
-                r_tgt_dcache_req = false;
-                r_dcache_fsm = r_dcache_fsm_save;
-                break;
- 
-            case DCACHE_CC_INVAL:   // invalidate a cache line
+                else if ( dcache_hit && !r_tgt_update ) // hit inval
+                {
+                    r_dcache_fsm = DCACHE_CC_INVAL;
+                } 
+                else	// miss 
+                { 
+                    r_tgt_dcache_req = false;
+                    r_tgt_dcache_rsp = r_tgt_update;  // always a respons in case of update
+                    r_dcache_fsm = r_dcache_fsm_save;
+                }
+            }
+            break;
+        }   
+        case DCACHE_CC_UPDT:    // update the cache line        
+        {
+            m_cpt_dcache_dir_write++;
+            m_cpt_dcache_data_write++;
+            for(size_t i=0; i<m_dcache_words; i++)
+            {
+                if(r_tgt_val[i]) r_dcache.write( (r_tgt_addr + i*4), r_tgt_buf[i] );
+            }
+            r_tgt_dcache_rsp = true;
+            r_tgt_dcache_req = false;
+            r_dcache_fsm = r_dcache_fsm_save;
+            break;
+        }
+        case DCACHE_CC_INVAL:   // invalidate a cache line
+        {        
                 r_dcache.inval(r_tgt_addr);
                 r_tgt_dcache_rsp = true;
@@ -1364,14 +1424,20 @@
                 r_dcache_fsm = r_dcache_fsm_save;
                 break;
+        }
         } // end switch r_dcache_fsm
 
-        ////////// write buffer handling //////////////////
-        if( r_dcache_fsm == DCACHE_WRITE_REQ ) 
-            r_wbuf.write(true, r_dcache_addr_save, r_dcache_be_save, r_dcache_wdata_save);
-        else 
-            r_wbuf.write(false, 0, 0, 0);
+        ////////// 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 or in case of MISS.
+        if( (r_dcache_fsm == DCACHE_SYNC) || (r_dcache_fsm == DCACHE_MISS_WAIT) )
+        {
+            r_wbuf.update(true);
+        }
+        else
+        {
+            r_wbuf.update(false);
+        }
 
 #if SOCLIB_MODULE_DEBUG
-if ( m_srcid_d == 0 )
 std::cout << ireq << std::endl << irsp << std::endl << dreq << std::endl << drsp << std::endl;
 #endif
@@ -1391,10 +1457,10 @@
         // on the coherence network. It controls the following ressources:
         // - r_cleanup_fsm
-        // - r_dcache_cleanup_req reset
-        // - r_icache_cleanup_req reset
+        // - r_dcache_cleanup_req (reset)
+        // - r_icache_cleanup_req (reset)
         // 
         // This FSM handles cleanup requests from both the DCACHE FSM & ICACHE FSM
-        // 1 - Instruction Cleanup  : r_icache_cleanup_req 
-        // 2 - Data Cleanup         : r_dcache_cleanup_req 
+        // - 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)
@@ -1409,14 +1475,14 @@
         switch (r_cleanup_fsm) {
 
-            case CLEANUP_CMD:
+            case CLEANUP_IDLE:
             {    
                 if ( p_vci_ini_c.cmdack )
                 {
-                    if      (r_dcache_cleanup_req) 	r_cleanup_fsm = CLEANUP_DCACHE_RSP;
-                    else if (r_icache_cleanup_req) 	r_cleanup_fsm = CLEANUP_ICACHE_RSP;
-                }
-                break;
-            }
-            case CLEANUP_DCACHE_RSP:
+                    if      (r_dcache_cleanup_req) 	r_cleanup_fsm = CLEANUP_DCACHE;
+                    else if (r_icache_cleanup_req) 	r_cleanup_fsm = CLEANUP_ICACHE;
+                }
+                break;
+            }
+            case CLEANUP_DCACHE:
             {
                 if ( p_vci_ini_c.rspval )
@@ -1427,10 +1493,11 @@
                       "error signaled in a cleanup response" );
                     
-                    r_cleanup_fsm = CLEANUP_CMD;
+                    r_cleanup_fsm = CLEANUP_IDLE;
                     r_dcache_cleanup_req = false;
-                }
-                break;
-            }
-            case CLEANUP_ICACHE_RSP:
+                    m_cpt_cc_cleanup_data++;
+                }
+                break;
+            }
+            case CLEANUP_ICACHE:
             {
                 if ( p_vci_ini_c.rspval )
@@ -1441,6 +1508,7 @@
                       "error signaled in a cleanup response" );
                     
-                    r_cleanup_fsm = CLEANUP_CMD;
+                    r_cleanup_fsm = CLEANUP_IDLE;
                     r_icache_cleanup_req = false;
+                    m_cpt_cc_cleanup_ins++;
                 }
                 break;
@@ -1464,7 +1532,7 @@
         // There is 5 request types, with the following priorities : 
         // 1 - Data Read Miss       : r_dcache_miss_req (if no hit in the write buffer)
-        // 2 - Data Read Uncached   : r_dcache_unc_req (if no hit in the write buffer)
+        // 2 - Data Read Uncachable   : r_dcache_unc_req (if no hit in the write buffer)
         // 3 - Instruction Miss     : r_icache_miss_req (if no hit in the write buffer)
-        // 4 - Instruction Uncached : r_icache_unc_req (if no hit in the write buffer)
+        // 4 - Instruction Uncachable : r_icache_unc_req (if no hit in the write buffer)
         // 5 - Data Write           : r_wbuf.rok()      
         // The read requests have highest priority, because the processor is blocked.
@@ -1472,14 +1540,19 @@
         // VCI formats:
         // According to the VCI advanced specification, all read requests packets 
-        // (read Uncached, Miss data, Miss instruction) are one word packets.
+        // (read Uncachable, 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").
         // The PLEN VCI field is always documented.
-        // - Read transactions  : index = 4*cached + 2*instruction  (even values)
-        //////////////////////////////////////////////////////////////////////////////
+        // As simultaneous VCI transactions are supported, the TRDID field is used:
+        // - Write transactions : TRDID = wbuf_index + (1<<(trdid_size-1))
+        // - Read transactions  : TRDID = 2*cachable + instruction  
+        ///////////////////////////////////////////////////////////////////////////////////
 
         switch (r_cmd_fsm) {
 
             case CMD_IDLE:
+            {
+                size_t	min;
+                size_t	max;
                 if ( r_dcache_miss_req & r_wbuf.miss( r_dcache_addr_save ) )
                 { 
@@ -1488,10 +1561,4 @@
                     m_cpt_dmiss_transaction++; 
                 } 
-                else if ( r_dcache_unc_req & r_wbuf.miss( r_dcache_addr_save ) )
-                { 
-                    r_cmd_fsm = CMD_DATA_UNC;
-                    r_dcache_unc_req = false;
-                    m_cpt_unc_transaction++; 
-                }
                 else if ( r_icache_miss_req & r_wbuf.miss( r_icache_addr_save ) )
                 { 
@@ -1500,22 +1567,29 @@
                     m_cpt_imiss_transaction++;
                 } 
-                else if ( r_icache_unc_req & r_wbuf.miss( r_icache_addr_save ) )
+                else if ( r_wbuf.rok(&min, &max) ) 
+                { 
+                    r_cmd_fsm = CMD_DATA_WRITE;
+                    r_cmd_cpt = min;
+                    r_cmd_min = min;
+                    r_cmd_max = max;
+                    m_cpt_write_transaction++; 
+                    m_length_write_transaction += (max-min+1); 
+                } 
+                else if ( r_dcache_unc_req )
+                { 
+                    r_cmd_fsm = CMD_DATA_UNC;
+                    r_dcache_unc_req = false;
+                    m_cpt_data_unc_transaction++; 
+                }
+                else if ( r_icache_unc_req )
                 { 
                     r_cmd_fsm = CMD_INS_UNC; 
                     r_icache_unc_req = false;
-                    m_cpt_imiss_transaction++;
-                }
-                else if ( r_wbuf.rok() ) 
-                { 
-                    r_cmd_fsm = CMD_DATA_WRITE;
-                    r_cmd_cpt = r_wbuf.getMin();
-                    r_cmd_min = r_wbuf.getMin();
-                    r_cmd_max = r_wbuf.getMax(); 
-                    m_cpt_write_transaction++; 
-                    m_length_write_transaction += (r_wbuf.getMax() - r_wbuf.getMin() + 1); 
-                } 
-                break;
-
+                    m_cpt_ins_unc_transaction++;
+                }
+                break;
+            }
             case CMD_DATA_WRITE:
+            {
                 if ( p_vci_ini_d.cmdack.read() ) 
                 {
@@ -1528,11 +1602,13 @@
                 }
                 break;
-
+            }
             case CMD_INS_MISS:
             case CMD_INS_UNC:
             case CMD_DATA_MISS:
             case CMD_DATA_UNC:
+            {
                 if ( p_vci_ini_d.cmdack.read() )  r_cmd_fsm = CMD_IDLE;
                 break;
+            }
         } // end  switch r_cmd_fsm
 
@@ -1557,39 +1633,51 @@
         // VCI formats:
         // This component accepts only single word write response packets. 
+        // As simultaneous VCI transactions are supported, the TRDID field is used:
+        // - Write transactions : TRDID = wbuf_index + (1<<(trdid_size-1))
+        // - Read transactions  : TRDID = 2*cachable + instruction  
         //
         // Error handling:
-        // This FSM analyzes the VCI error code and signals the  Write Bus Error. 
-        // In case of Read Data Error, the VCI_RSP FSM sets the r_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_rsp_ins_error 
-        // flip_flop and the error is signaled by the DCACHE FSM.  
+        // - In case of Write error, the error is directly signaled by the RSP FSM.
+        // - In case of Read Data Error, the VCI_RSP FSM sets the r_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_rsp_ins_error 
+        //   flip_flop and the error is signaled by the ICACHE FSM.  
         //////////////////////////////////////////////////////////////////////////
+        // Implementation note
+        // It should be possible to save one cycle on the MISS cost by a simple
+        // modification of this RSP FSM : The first flit of a valid response
+        // could be decoded and handled directly in the IDLE state.
+        // The computation of the RSPACK condition become more complex... 
+        //////////////////////////////////////////////////////////////////////////: 
 
         switch (r_rsp_fsm) {
 
         case RSP_IDLE:
+        {
             if( p_vci_ini_d.rspval.read() )
             {
                 r_rsp_cpt = 0;
-                if ( p_vci_ini_d.rtrdid.read()/m_wbuf_nlines != 0 )		r_rsp_fsm = RSP_DATA_WRITE;
-                else if ( p_vci_ini_d.rtrdid.read() == TYPE_DATA_MISS ) r_rsp_fsm = RSP_DATA_MISS;
-                else if ( p_vci_ini_d.rtrdid.read() == TYPE_DATA_UNC ) 	r_rsp_fsm = RSP_DATA_UNC;
-                else if ( p_vci_ini_d.rtrdid.read() == TYPE_INS_MISS ) 	r_rsp_fsm = RSP_INS_MISS;
-                else if ( p_vci_ini_d.rtrdid.read() == TYPE_INS_UNC ) 	r_rsp_fsm = RSP_INS_UNC;
-            }
-            break;
-
+                if ( (p_vci_ini_d.rtrdid.read()>>(vci_param::T-1)) != 0 )	r_rsp_fsm = RSP_DATA_WRITE;
+                else if ( p_vci_ini_d.rtrdid.read() == TYPE_DATA_MISS ) 	r_rsp_fsm = RSP_DATA_MISS;
+                else if ( p_vci_ini_d.rtrdid.read() == TYPE_DATA_UNC ) 		r_rsp_fsm = RSP_DATA_UNC;
+                else if ( p_vci_ini_d.rtrdid.read() == TYPE_INS_MISS ) 		r_rsp_fsm = RSP_INS_MISS;
+                else if ( p_vci_ini_d.rtrdid.read() == TYPE_INS_UNC ) 		r_rsp_fsm = RSP_INS_UNC;
+            }
+            break;
+        }
         case RSP_DATA_WRITE:
+        {
             if ( p_vci_ini_d.rspval.read() )
             {
                 assert(p_vci_ini_d.reop.read() &&
-                   "illegal VCI response packet for a write transaction");
+                   "A VCI response packet must contain one flit for a write transaction");
                 r_rsp_fsm = RSP_IDLE;
-                r_wbuf.completed( p_vci_ini_d.rtrdid.read() - m_wbuf_nlines );
+                r_wbuf.completed( p_vci_ini_d.rtrdid.read() - (1<<(vci_param::T-1)) );
                 if ( p_vci_ini_d.rerror.read() != vci_param::ERR_NORMAL ) m_iss.setWriteBerr();
             }
             break;
-
+        }
         case RSP_INS_MISS:
+        {
             if ( p_vci_ini_d.rspval.read() )
             {  
@@ -1607,10 +1695,11 @@
             }
             break;
-
+        }
         case RSP_INS_UNC:
+        {
             if ( p_vci_ini_d.rspval.read() )
             {
                 assert(p_vci_ini_d.reop.read() &&
-                   "illegal VCI response packet for uncached instruction");
+                   "illegal VCI response packet for uncachable instruction");
                 r_icache_miss_buf[0] = (data_t)p_vci_ini_d.rdata.read();
                 r_rsp_ins_ok = true;
@@ -1619,10 +1708,11 @@
             }
             break;
-
+        }
         case RSP_DATA_MISS:
+        {
             if ( p_vci_ini_d.rspval.read() )
             {
-                assert(r_rsp_cpt != m_dcache_words &&
-                   "illegal VCI response packet for data read miss");
+                assert( (r_rsp_cpt < m_dcache_words) &&
+                        "The VCI response packet for data miss is too long" );
                 r_rsp_cpt = r_rsp_cpt + 1;
                 r_dcache_miss_buf[r_rsp_cpt] = (data_t)p_vci_ini_d.rdata.read();
@@ -1630,5 +1720,5 @@
                 {
                     assert(r_rsp_cpt == m_dcache_words - 1 &&
-                       "illegal VCI response packet for instruction miss");
+                        "The VCI response packet for data miss is too short" );
                     r_rsp_data_ok = true;
                     r_rsp_fsm = RSP_IDLE;
@@ -1637,10 +1727,11 @@
             }
             break;
-
+        }
         case RSP_DATA_UNC:
+        {
             if ( p_vci_ini_d.rspval.read() )
             {
                 assert(p_vci_ini_d.reop.read() &&
-                   "illegal VCI response packet for uncached read data");
+                   "illegal VCI response packet for uncachable data");
                 r_dcache_miss_buf[0] = (data_t)p_vci_ini_d.rdata.read();
                 r_rsp_data_ok = true;
@@ -1649,11 +1740,11 @@
             }
             break;
+        }
         } // end switch r_rsp_fsm
 
     } // end transition()
 
-    //////////////////////////////////////////////////////////////////////////////////
+    //////////////////////
     tmpl(void)::genMoore()
-    //////////////////////////////////////////////////////////////////////////////////
     {
         // Coherence network (initiator port)
@@ -1661,15 +1752,15 @@
         switch ( r_cleanup_fsm.read() ) {
 
-            case CLEANUP_CMD:
+            case CLEANUP_IDLE:
                 p_vci_ini_c.rspack  = false;
                 p_vci_ini_c.cmdval  = r_icache_cleanup_req || r_dcache_cleanup_req;
                 if ( r_dcache_cleanup_req )
                 {
-                    p_vci_ini_c.address =  r_dcache_cleanup_line.read() * m_dcache_words * 4;
+                    p_vci_ini_c.address =  r_dcache_cleanup_line.read() * (m_dcache_words << 2);
                     p_vci_ini_c.trdid   = 0;
                 }
                 else
                 {
-                    p_vci_ini_c.address =  r_icache_cleanup_line.read() * (m_icache_words << 2); //* 4;
+                    p_vci_ini_c.address =  r_icache_cleanup_line.read() * (m_icache_words << 2); 
                     p_vci_ini_c.trdid   = 1;
                 }
@@ -1688,5 +1779,5 @@
                 break;
 
-           case CLEANUP_DCACHE_RSP:
+           case CLEANUP_DCACHE:
                 p_vci_ini_c.rspack  = true;
                 p_vci_ini_c.cmdval  = false;
@@ -1707,5 +1798,5 @@
                 break;
 
-           case CLEANUP_ICACHE_RSP:
+           case CLEANUP_ICACHE:
                 p_vci_ini_c.rspack  = true;
                 p_vci_ini_c.cmdval  = false;
@@ -1755,11 +1846,11 @@
             case CMD_DATA_WRITE:
                 p_vci_ini_d.cmdval  = true;
-                p_vci_ini_d.address = r_wbuf.getAddress(r_cmd_cpt)&~0x3;
+                p_vci_ini_d.address = r_wbuf.getAddress(r_cmd_cpt);
                 p_vci_ini_d.wdata   = r_wbuf.getData(r_cmd_cpt);
                 p_vci_ini_d.be      = r_wbuf.getBe(r_cmd_cpt);
                 p_vci_ini_d.plen    = (r_cmd_max - r_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.trdid   = r_wbuf.getIndex() + m_wbuf_nlines;
                 p_vci_ini_d.srcid   = m_srcid_d;
                 p_vci_ini_d.cons    = false;
@@ -1771,8 +1862,30 @@
                 break;
 
+            case CMD_DATA_MISS:
+                p_vci_ini_d.cmdval = true;
+                p_vci_ini_d.address = r_dcache_addr_save & (addr_t)m_dcache_yzmask;
+                p_vci_ini_d.be     = 0xF;
+                p_vci_ini_d.plen   = m_dcache_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_DATA_UNC:
                 p_vci_ini_d.cmdval = true;
                 p_vci_ini_d.address = r_dcache_addr_save & ~0x3;
                 switch( r_dcache_type_save ) {
+                    case iss_t::DATA_WRITE:
+                        p_vci_ini_d.wdata = r_dcache_wdata_save.read();
+                        p_vci_ini_d.be  = r_dcache_be_save.read();
+                        p_vci_ini_d.cmd = vci_param::CMD_WRITE;
+                        break;
                     case iss_t::DATA_READ:
                         p_vci_ini_d.wdata = 0;
@@ -1793,5 +1906,5 @@
                         assert("this should not happen");
                 }
-                p_vci_ini_d.plen = 4;
+                p_vci_ini_d.plen   = 4;
                 p_vci_ini_d.trdid  = TYPE_DATA_UNC;
                 p_vci_ini_d.pktid  = 0;
@@ -1805,24 +1918,7 @@
                 break;
 
-            case CMD_DATA_MISS:
-                p_vci_ini_d.cmdval = true;
-                p_vci_ini_d.address = r_dcache_addr_save.read() & (addr_t) m_dcache_yzmask;
-                p_vci_ini_d.be     = 0xF;
-                p_vci_ini_d.plen   = m_dcache_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 = r_icache_addr_save & (addr_t) m_icache_yzmask;
+                p_vci_ini_d.address = r_icache_addr_save & (addr_t)m_icache_yzmask;
                 p_vci_ini_d.be     = 0xF;
                 p_vci_ini_d.plen   = m_icache_words << 2;
