Index: trunk/modules/vci_mem_cache/caba/source/include/vci_mem_cache.h
===================================================================
--- trunk/modules/vci_mem_cache/caba/source/include/vci_mem_cache.h	(revision 532)
+++ trunk/modules/vci_mem_cache/caba/source/include/vci_mem_cache.h	(revision 535)
@@ -449,4 +449,5 @@
       uint32_t     m_cpt_write_miss;     // Number of MISS WRITE
       uint32_t     m_cpt_write_dirty;    // Cumulated length for WRITE transactions
+      uint32_t     m_cpt_write_broadcast;// Number of BROADCAST INVAL because write
 
       uint32_t     m_cpt_trt_rb;         // Read blocked by a hit in trt
@@ -724,4 +725,5 @@
       sc_signal<bool>     r_write_sc_fail;            // sc command failed
       sc_signal<data_t>   r_write_sc_key;             // sc command key
+      sc_signal<bool>     r_write_bc_data_we;         // Write enable for data buffer
 
       // Buffer between WRITE fsm and TGT_RSP fsm (acknowledge a write command from L1)
Index: trunk/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp
===================================================================
--- trunk/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp	(revision 532)
+++ trunk/modules/vci_mem_cache/caba/source/src/vci_mem_cache.cpp	(revision 535)
@@ -739,4 +739,5 @@
                 << "[036] PUT (UNIMPLEMENTED)       = " << m_cpt_put << std::endl
                 << "[037] GET (UNIMPLEMENTED)       = " << m_cpt_get << std::endl
+                << "[038] WRITE BROADCAST           = " << m_cpt_write_broadcast << std::endl
                 << std::endl;
         }
@@ -974,11 +975,12 @@
             m_cpt_cleanup_cost       = 0;
 
-            m_cpt_read_miss     = 0;
-            m_cpt_write_miss    = 0;
-            m_cpt_write_dirty   = 0;
-            m_cpt_trt_rb        = 0;
-            m_cpt_trt_full      = 0;
-            m_cpt_get           = 0;
-            m_cpt_put           = 0;
+            m_cpt_read_miss       = 0;
+            m_cpt_write_miss      = 0;
+            m_cpt_write_dirty     = 0;
+            m_cpt_write_broadcast = 0;
+            m_cpt_trt_rb          = 0;
+            m_cpt_trt_full        = 0;
+            m_cpt_get             = 0;
+            m_cpt_put             = 0;
 
             return;
@@ -3402,5 +3404,7 @@
 #if DEBUG_MEMC_WRITE
                         if (m_debug)
-                            std::cout << "  <MEMC " << name() << " WRITE_MISS_XRAM_REQ> Post a GET request to the IXR_CMD FSM" << std::endl;
+                            std::cout << "  <MEMC " << name() 
+                                      << " WRITE_MISS_XRAM_REQ> Post a GET request to the"
+                                      << " IXR_CMD FSM" << std::endl;
 #endif
                     }
@@ -3409,25 +3413,14 @@
                 ///////////////////////
             case WRITE_BC_DIR_READ:  // enter this state if a broadcast-inval is required
-                // the cache line must be erased in mem-cache, and written
-                // into XRAM. we read the cache and complete the buffer
+                                     // the cache line must be erased in mem-cache, and written
+                                     // into XRAM.
                 {
                     assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE) and
                             "MEMC ERROR in WRITE_BC_DIR_READ state: Bad DIR allocation");
 
-                    // update local buffer
-                    size_t set  = m_y[(addr_t)(r_write_address.read())];
-                    size_t way  = r_write_way.read();
-                    for(size_t word=0 ; word<m_words ; word++)
-                    {
-                        data_t mask = 0;
-                        if (r_write_be[word].read() & 0x1) mask = mask | 0x000000FF;
-                        if (r_write_be[word].read() & 0x2) mask = mask | 0x0000FF00;
-                        if (r_write_be[word].read() & 0x4) mask = mask | 0x00FF0000;
-                        if (r_write_be[word].read() & 0x8) mask = mask | 0xFF000000;
-
-                        // complete only if mask is not null (for energy consumption)
-                        r_write_data[word]  = (r_write_data[word].read() & mask) |
-                            (m_cache_data.read(way, set, word) & ~mask);
-                    } // end for
+                    m_cpt_write_broadcast++;
+
+                    // write enable signal for data buffer.
+                    r_write_bc_data_we = true;
 
                     r_write_fsm = WRITE_BC_TRT_LOCK;
@@ -3436,5 +3429,5 @@
                     if (m_debug)
                         std::cout << "  <MEMC " << name() << " WRITE_BC_DIR_READ>"
-                            << " Read the cache to complete local buffer" << std::endl;
+                                  << " Read the cache to complete local buffer" << std::endl;
 #endif
                     break;
@@ -3446,24 +3439,58 @@
                             "MEMC ERROR in WRITE_BC_TRT_LOCK state: Bad DIR allocation");
 
-                    if (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE)
-                    {
-                        size_t wok_index = 0;
-                        bool wok = not m_trt.full(wok_index);
-                        if (wok )       
-                        {
-                            r_write_trt_index = wok_index;
-                            r_write_fsm       = WRITE_BC_IVT_LOCK;
-                        }
-                        else  // wait an empty slot in TRT
-                        {
-                            r_write_fsm       = WRITE_WAIT;
-                        }
-
+                    // We read the cache and complete the buffer. As the DATA cache uses a
+                    // synchronous RAM, the read DATA request has been performed in the
+                    // WRITE_BC_DIR_READ state but the data is available in this state.
+                    if (r_write_bc_data_we.read())
+                    {
+                        size_t set  = m_y[(addr_t)(r_write_address.read())];
+                        size_t way  = r_write_way.read();
+                        for(size_t word=0 ; word<m_words ; word++)
+                        {
+                            data_t mask = 0;
+                            if (r_write_be[word].read() & 0x1) mask = mask | 0x000000FF;
+                            if (r_write_be[word].read() & 0x2) mask = mask | 0x0000FF00;
+                            if (r_write_be[word].read() & 0x4) mask = mask | 0x00FF0000;
+                            if (r_write_be[word].read() & 0x8) mask = mask | 0xFF000000;
+
+                            // complete only if mask is not null (for energy consumption)
+                            r_write_data[word] =
+                                (r_write_data[word].read()         &  mask) |
+                                (m_cache_data.read(way, set, word) & ~mask);
+                        }
 #if DEBUG_MEMC_WRITE
                         if (m_debug)
-                            std::cout << "  <MEMC " << name() << " WRITE_BC_TRT_LOCK> Check TRT"
-                                << " : wok = " << wok << " / index = " << wok_index << std::endl;
-#endif
-                    }
+                            std::cout 
+                                << "  <MEMC "  << name()
+                                << " WRITE_BC_TRT_LOCK> Complete data buffer" << std::endl;
+#endif
+                    }
+
+                    if (r_alloc_trt_fsm.read() != ALLOC_TRT_WRITE)
+                    {
+                        // if we loop in this state, the data does not need to be
+                        // rewritten (for energy consuption)
+                        r_write_bc_data_we = false;
+                        break;
+                    }
+
+                    size_t wok_index = 0;
+                    bool wok = not m_trt.full(wok_index);
+                    if (wok )       
+                    {
+                        r_write_trt_index = wok_index;
+                        r_write_fsm       = WRITE_BC_IVT_LOCK;
+                    }
+                    else  // wait an empty slot in TRT
+                    {
+                        r_write_fsm       = WRITE_WAIT;
+                    }
+
+#if DEBUG_MEMC_WRITE
+                    if (m_debug)
+                        std::cout << "  <MEMC "  << name()
+                                  << " WRITE_BC_TRT_LOCK> Check TRT : wok = " << wok
+                                  << " / index = " << wok_index << std::endl;
+#endif
                     break;
                 }
