Index: /trunk/modules/vci_cc_vcache_wrapper_v4/caba/source/include/vci_cc_vcache_wrapper_v4.h
===================================================================
--- /trunk/modules/vci_cc_vcache_wrapper_v4/caba/source/include/vci_cc_vcache_wrapper_v4.h	(revision 204)
+++ /trunk/modules/vci_cc_vcache_wrapper_v4/caba/source/include/vci_cc_vcache_wrapper_v4.h	(revision 205)
@@ -100,6 +100,6 @@
         DCACHE_TLB_PTE2_SELECT,       
         DCACHE_TLB_PTE2_UPDT,           
-        DCACHE_TLB_SC_UPDT,           
-        DCACHE_TLB_SC_WAIT,           
+        DCACHE_TLB_LR_UPDT,           
+        DCACHE_TLB_LR_WAIT,           
         DCACHE_TLB_RETURN,         
 	    // handling processor XTN requests
@@ -116,9 +116,9 @@
         DCACHE_XTN_DC_INVAL_GO,          
         DCACHE_XTN_DT_INVAL,          
-        //handling fourth stage write
-        DCACHE_WRITE_TLB_DIRTY,
-        DCACHE_WRITE_CACHE_DIRTY,
-        DCACHE_WRITE_SC_WAIT,           
-        DCACHE_WRITE_UNC_WAIT,
+        //handling long write (set dirty bit)
+        DCACHE_DIRTY_TLB_SET,
+        DCACHE_DIRTY_CACHE_SET,
+        DCACHE_DIRTY_SC_WAIT,           
+        DCACHE_DIRTY_UNC_WAIT,
 	    // handling processor miss requests
         DCACHE_MISS_VICTIM,
@@ -129,4 +129,5 @@
         // handling processor unc and sc requests
         DCACHE_UNC_WAIT,            
+        DCACHE_SC_WAIT,            
         // handling coherence requests
         DCACHE_CC_CHECK,            
@@ -263,25 +264,10 @@
 
     ////////////////////////////////////////
-    // Variables used by print_trace()
+    // Communication with processor ISS
     ////////////////////////////////////////
-
-    bool							            m_ireq_valid;
-    uint32_t						            m_ireq_addr;
-    soclib::common::Iss2::ExecMode	            m_ireq_mode;
-
-    bool					            		m_irsp_valid;
-    uint32_t				            		m_irsp_instruction;
-    bool						            	m_irsp_error;
-
-    bool							            m_dreq_valid;
-    uint32_t						            m_dreq_addr;
-    soclib::common::Iss2::ExecMode	            m_dreq_mode;
-    soclib::common::Iss2::DataOperationType		m_dreq_type;
-    uint32_t							        m_dreq_wdata;
-    uint8_t				    		        	m_dreq_be;
-
-    bool					            		m_drsp_valid;
-    uint32_t							        m_drsp_rdata;
-    bool				            			m_drsp_error;
+    typename iss_t::InstructionRequest  m_ireq;
+    typename iss_t::InstructionResponse m_irsp;
+    typename iss_t::DataRequest         m_dreq;
+    typename iss_t::DataResponse        m_drsp;
 
     /////////////////////////////////////////////
@@ -379,13 +365,11 @@
     sc_signal<bool>         r_dcache_p1_tlb_big;      	// big page bit (from dtlb)
     // registers written in P2 stage (used in long write)
-    sc_signal<uint32_t>     r_dcache_p2_vaddr;          // virtual address (from proc)
-    sc_signal<size_t>       r_dcache_p2_tlb_way;	    // selected way in dtlb 
-    sc_signal<size_t>       r_dcache_p2_tlb_set;	    // selected set in dtlb
-    sc_signal<bool>         r_dcache_p2_set_dirty;	    // PTE dirty bit must be set
+    sc_signal<size_t>       r_dcache_p2_way;	        // selected way in dtlb or dcache 
+    sc_signal<size_t>       r_dcache_p2_set;	        // selected set in dtlb or dcache
+    sc_signal<size_t>       r_dcache_p2_word;	        // selected word in dcache
     sc_signal<paddr_t>      r_dcache_p2_pte_paddr;      // PTE physical address 
-    sc_signal<size_t>       r_dcache_p2_pte_way;	    // selected way in dcache
-    sc_signal<size_t>       r_dcache_p2_pte_set;	    // selected set in dcache
-    sc_signal<size_t>       r_dcache_p2_pte_word;	    // selected word in dcache
-    sc_signal<size_t>       r_dcache_p2_pte;	        // pte value read in dcache
+    sc_signal<size_t>       r_dcache_p2_pte_value;      // PTE value
+    sc_signal<bool>         r_dcache_p2_type_sc;	    // request type (WRITE or SC)
+    sc_signal<bool>         r_dcache_p2_sc_success;     // successful SC request
     
     // communication between DCACHE FSM and VCI_CMD FSM
@@ -406,5 +390,5 @@
 
     // handling dcache miss
-    sc_signal<int>	    r_dcache_miss_type;		        // type of miss depending on the requester
+    sc_signal<int>	        r_dcache_miss_type;		    // type of miss depending on the requester
     sc_signal<size_t>       r_dcache_miss_word;		    // word index for sequencial cache update
     sc_signal<size_t>       r_dcache_miss_way;		    // selected way for cache update
Index: /trunk/modules/vci_cc_vcache_wrapper_v4/caba/source/src/vci_cc_vcache_wrapper_v4.cpp
===================================================================
--- /trunk/modules/vci_cc_vcache_wrapper_v4/caba/source/src/vci_cc_vcache_wrapper_v4.cpp	(revision 204)
+++ /trunk/modules/vci_cc_vcache_wrapper_v4/caba/source/src/vci_cc_vcache_wrapper_v4.cpp	(revision 205)
@@ -71,6 +71,6 @@
 	"DCACHE_TLB_PTE2_SELECT",
         "DCACHE_TLB_PTE2_UPDT",   
-        "DCACHE_TLB_SC_UPDT",
-        "DCACHE_TLB_SC_WAIT",
+        "DCACHE_TLB_LR_UPDT",
+        "DCACHE_TLB_LR_WAIT",
         "DCACHE_TLB_RETURN",
 
@@ -88,8 +88,8 @@
         "DCACHE_XTN_DT_INVAL",
 
-        "DCACHE_WRITE_TLB_DIRTY",
-        "DCACHE_WRITE_CACHE_DIRTY",
-        "DCACHE_WRITE_SC_WAIT",  
-        "DCACHE_WRITE_UNC_WAIT",  
+        "DCACHE_DIRTY_TLB_SET",
+        "DCACHE_DIRTY_CACHE_SET",
+        "DCACHE_DIRTY_SC_WAIT",  
+        "DCACHE_DIRTY_UNC_WAIT",  
 
         "DCACHE_MISS_VICTIM",
@@ -100,4 +100,5 @@
 
         "DCACHE_UNC_WAIT",   
+        "DCACHE_SC_WAIT",   
 
         "DCACHE_CC_CHECK",
@@ -273,13 +274,11 @@
       r_dcache_p1_tlb_big("r_dcache_p1_tlb_big"),
 
-      r_dcache_p2_vaddr("r_dcache_p2_vaddr"),
-      r_dcache_p2_tlb_way("r_dcache_p2_tlb_way"),
-      r_dcache_p2_tlb_set("r_dcache_p2_tlb_set"),
-      r_dcache_p2_set_dirty("r_dcache_p2_set_dirty"),
+      r_dcache_p2_way("r_dcache_p2_way"),
+      r_dcache_p2_set("r_dcache_p2_set"),
+      r_dcache_p2_word("r_dcache_p2_word"),
       r_dcache_p2_pte_paddr("r_dcache_p2_pte_paddr"),
-      r_dcache_p2_pte_way("r_dcache_p2_pte_way"),
-      r_dcache_p2_pte_set("r_dcache_p2_pte_set"),
-      r_dcache_p2_pte_word("r_dcache_p2_pte_word"),
-      r_dcache_p2_pte("r_dcache_p2_pte"),
+      r_dcache_p2_pte_value("r_dcache_p2_pte_value"),
+      r_dcache_p2_type_sc("r_dcache_p2_type_sc"),
+      r_dcache_p2_sc_success("r_dcache_p2_sc_success"),
 
       r_dcache_vci_paddr("r_dcache_vci_paddr"),
@@ -442,39 +441,17 @@
 ////////////////////////////////////
 {
-    // b0 : write buffer print trace
+    // b0 : write buffer 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;
+    // b2 : dcache trace
+    // b3 : icache trace
+    // b4 : dtlb trace
+    // b5 : itlb trace
 
     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 << "  " << m_ireq << std::endl;
+    std::cout << "  " << m_irsp << std::endl;
+    std::cout << "  " << m_dreq << std::endl;
+    std::cout << "  " << m_drsp << std::endl;
 
     std::cout << "  " << icache_fsm_state_str[r_icache_fsm.read()]
@@ -488,17 +465,27 @@
     std::cout << std::endl;
 
-    if(mode & 0x1)
+    if(mode & 0x01)
     {
         r_wbuf.printTrace((mode>>1)&1);
     }
-    if(mode & 0x4)
-    {
-        std::cout << "  Data cache" << std::endl;
+    if(mode & 0x04)
+    {
+        std::cout << "  Data Cache" << std::endl;
         r_dcache.printTrace();
     }
-    if(mode & 0x8)
-    {
-        std::cout << "  Instruction cache" << std::endl;
+    if(mode & 0x08)
+    {
+        std::cout << "  Instruction Cache" << std::endl;
         r_icache.printTrace();
+    }
+    if(mode & 0x10)
+    {
+        std::cout << "  Data TLB" << std::endl;
+        r_dtlb.printTrace();
+    }
+    if(mode & 0x20)
+    {
+        std::cout << "  Instruction TLB" << std::endl;
+        r_itlb.printTrace();
     }
 }
@@ -1185,8 +1172,5 @@
     ///////////////////////////////////////////////////////////////////////
 
-    typename iss_t::InstructionRequest  ireq = ISS_IREQ_INITIALIZER;
-    typename iss_t::DataRequest         dreq = ISS_DREQ_INITIALIZER;
-
-    r_iss.getRequests(ireq, dreq);
+    r_iss.getRequests(m_ireq, m_dreq);
 
     ////////////////////////////////////////////////////////////////////////////////////
@@ -1239,6 +1223,6 @@
     ////////////////////////////////////////////////////////////////////////////////////////
 
-    // The default value for irsp.valid is false
-    typename iss_t::InstructionResponse irsp = ISS_IRSP_INITIALIZER;
+    // default value for m_irsp.valid
+    m_irsp.valid = false;
 
     switch( r_icache_fsm.read() ) 
@@ -1296,5 +1280,5 @@
 
         // processor request
-        if ( ireq.valid )
+        if ( m_ireq.valid )
         {
             bool	cacheable;
@@ -1302,5 +1286,5 @@
 
             // We register processor request
-            r_icache_vaddr_save = ireq.addr;
+            r_icache_vaddr_save = m_ireq.addr;
 
             // speculative icache access (if cache activated)
@@ -1313,5 +1297,5 @@
             {
                 paddr_t   spc_paddr = (r_icache_vci_paddr.read() & ~PAGE_K_MASK) |
-                                      ((paddr_t)ireq.addr & PAGE_K_MASK);
+                                      ((paddr_t)m_ireq.addr & PAGE_K_MASK);
 
 #ifdef INSTRUMENTATION
@@ -1339,5 +1323,5 @@
 m_cpt_itlb_read++;
 #endif
-                tlb_hit = r_itlb.translate( ireq.addr,
+                tlb_hit = r_itlb.translate( m_ireq.addr,
                                             &tlb_paddr,
                                             &tlb_flags,
@@ -1359,8 +1343,8 @@
                 // cacheability
                 if ( not (r_mmu_mode.read() & INS_CACHE_MASK) ) cacheable = false;
-                else     cacheable = m_cacheability_table[ireq.addr];
+                else     cacheable = m_cacheability_table[m_ireq.addr];
 
                 // physical address
-                paddr = (paddr_t)ireq.addr;
+                paddr = (paddr_t)m_ireq.addr;
             }
             else						// itlb activated
@@ -1376,11 +1360,11 @@
 
                     // access rights checking 
-                    if ( not tlb_flags.u && (ireq.mode == iss_t::MODE_USER) )
+                    if ( not tlb_flags.u && (m_ireq.mode == iss_t::MODE_USER) )
                     {
                         r_mmu_ietr        = MMU_READ_PRIVILEGE_VIOLATION;
-                        r_mmu_ibvar       = ireq.addr;
-                        irsp.valid        = true;
-                        irsp.error        = true;
-                        irsp.instruction  = 0;
+                        r_mmu_ibvar       = m_ireq.addr;
+                        m_irsp.valid        = true;
+                        m_irsp.error        = true;
+                        m_irsp.instruction  = 0;
                         break;
                     }
@@ -1388,8 +1372,8 @@
                     {
                         r_mmu_ietr        = MMU_READ_EXEC_VIOLATION;
-                        r_mmu_ibvar       = ireq.addr;
-                        irsp.valid        = true;
-                        irsp.error        = true;
-                        irsp.instruction  = 0;
+                        r_mmu_ibvar       = m_ireq.addr;
+                        m_irsp.valid        = true;
+                        m_irsp.error        = true;
+                        m_irsp.instruction  = 0;
                         break;
                     }
@@ -1449,6 +1433,6 @@
 m_cpt_ins_read++; 
 #endif
-                    irsp.valid       = true;
-                    irsp.instruction = cache_inst;
+                    m_irsp.valid       = true;
+                    m_irsp.instruction = cache_inst;
                 }
             }
@@ -1458,5 +1442,5 @@
                 r_icache_fsm      = ICACHE_UNC_WAIT;
             }
-        }    // end if ireq.valid
+        }    // end if m_ireq.valid
         break;
     }
@@ -1477,5 +1461,5 @@
         }
 
-        if ( ireq.valid ) m_cost_ins_tlb_miss_frz++;
+        if ( m_ireq.valid ) m_cost_ins_tlb_miss_frz++;
 
         // DCACHE FSM signals response by reseting the request flip-flop
@@ -1485,6 +1469,6 @@
             {
                 r_icache_tlb_rsp_error = false;
-                irsp.error             = true;
-                irsp.valid             = true;
+                m_irsp.error             = true;
+                m_irsp.valid             = true;
                 r_icache_fsm           = ICACHE_IDLE;
             }
@@ -1638,5 +1622,5 @@
                                            // when the selected slot is not empty
     {
-        if ( ireq.valid ) m_cost_ins_miss_frz++;
+        if ( m_ireq.valid ) m_cost_ins_miss_frz++;
 
         bool	valid;
@@ -1679,5 +1663,5 @@
     case ICACHE_MISS_WAIT:	// waiting a response to a miss request from VCI_RSP FSM
     {
-        if ( ireq.valid ) m_cost_ins_miss_frz++;
+        if ( m_ireq.valid ) m_cost_ins_miss_frz++;
 
         // external coherence request
@@ -1693,6 +1677,6 @@
             r_mmu_ietr = MMU_READ_DATA_ILLEGAL_ACCESS; 
             r_mmu_ibvar  = r_icache_vaddr_save.read();
-            irsp.valid           = true;
-            irsp.error           = true;
+            m_irsp.valid           = true;
+            m_irsp.error           = true;
             r_vci_rsp_ins_error  = false;
             r_icache_fsm = ICACHE_IDLE;
@@ -1708,5 +1692,5 @@
     case ICACHE_MISS_UPDT:	// update the cache (one word per cycle)
     {
-        if ( ireq.valid ) m_cost_ins_miss_frz++;
+        if ( m_ireq.valid ) m_cost_ins_miss_frz++;
 
         if ( r_vci_rsp_fifo_icache.rok() )	// response available
@@ -1778,8 +1762,8 @@
         {
             r_mmu_ietr          = MMU_READ_DATA_ILLEGAL_ACCESS;    
-            r_mmu_ibvar         = ireq.addr;
+            r_mmu_ibvar         = m_ireq.addr;
             r_vci_rsp_ins_error = false;
-            irsp.valid          = true;
-            irsp.error          = true;
+            m_irsp.valid          = true;
+            m_irsp.error          = true;
             r_icache_fsm        = ICACHE_IDLE;
         }
@@ -1788,8 +1772,8 @@
             vci_rsp_fifo_icache_get = true;
             r_icache_fsm            = ICACHE_IDLE;
-            if ( ireq.valid and (ireq.addr == r_icache_vaddr_save.read()) )  // request not modified
-            {
-                irsp.valid       = true;
-                irsp.instruction = r_vci_rsp_fifo_icache.read();
+            if ( m_ireq.valid and (m_ireq.addr == r_icache_vaddr_save.read()) )  // request not modified
+            {
+                m_irsp.valid       = true;
+                m_irsp.instruction = r_vci_rsp_fifo_icache.read();
             }
 	}	
@@ -1887,13 +1871,4 @@
 
     } // 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;
 
     ////////////////////////////////////////////////////////////////////////////////////
@@ -1911,5 +1886,11 @@
     //    pre-empted state.
     //
-    // 2/ processor requests : 
+    // 2/ TLB miss
+    //    The page tables can be cacheable.
+    //    In case of miss in itlb or dtlb, the tlb miss is handled by a dedicated
+    //    sub-fsm (DCACHE_TLB_MISS state), that handle possible miss in DCACHE,
+    //    this sub-fsm implement the table-walk...
+    //
+    // 3/ processor requests : 
     //    Processor READ, WRITE, LL or SC requests are taken in IDLE state only.
     //    The IDLE state implements a three stages pipe-line to handle write bursts:
@@ -1917,13 +1898,14 @@
     //    - The registration in wbuf and the dcache hit are computed in stage P1. 
     //    - The dcache update is done in stage P2.  
-    //    A write operation can require a fourth stage if the dirty bit must be updated, 
-    //    or if the TLBs must be cleared, but these "long write" operation requires  
-    //    to exit the IDLE stage
+    //    A write operation can require a "long write" operation (if the PTE dirty bit 
+    //    must be updated) handled by a dedicated sub-fsm (DCACHE_DIRTY_TLB_SET state).
+    //    If a PTE is modified, the both te itlb and dtlb are selectively, but sequencially
+    //    cleared by a dedicated sub_fsm (DCACHE_INVAL_TLB_SCAN state).
     //    If there is no write in the pipe, dcache and dtlb are accessed in parallel,
     //    (virtual address for itlb, and speculative physical address computed during 
     //    previous cycle for dcache) in order to return the data in one cycle for a read.
-    //    We just pay an extra cycle when the speculative access is illegal.
+    //    We just pay an extra cycle when the speculative access is failing.
     //
-    // 3/ Atomic instructions LL/SC
+    // 4/ Atomic instructions LL/SC
     //    The LL/SC address can be cacheable or non cacheable.
     //    The reservation registers (r_dcache_ll_valid, r_dcache_ll_vaddr and
@@ -1933,8 +1915,11 @@
     //      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
+    //      memory cache as Compare&swap requests (both the data value stored in the
     //      r_dcache_ll_data register and the new value). 
+    //      The cache is not updated, as this is done in case of success by the
+    //      coherence transaction.
+    //      If rqired, the dirty bit is updated in PTE by a "long write".
     //
-    // 4/ Non cacheable access:
+    // 5/ 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
@@ -1946,5 +1931,5 @@
     //    pending non cacheable write transaction completes).
     //
-    // 5/ Error handling:  
+    // 6/ Error handling:  
     //    When the MMU is not activated, Read Bus Errors are synchronous events, 
     //    but Write Bus Errors are asynchronous events (processor is not frozen).
@@ -1959,11 +1944,11 @@
     ////////////////////////////////////////////////////////////////////////////////////////
 
-    // The default value for drsp.valid is false
-    typename iss_t::DataResponse  drsp = ISS_DRSP_INITIALIZER;
+    // default value for m_drsp.valid 
+    m_drsp.valid = false;
 
     switch ( r_dcache_fsm.read() ) 
     {
     case DCACHE_IDLE:	// There is 8 conditions to exit the IDLE state :
-    			// 1) Long write request (DCACHE FSM)	=> DCACHE_WRITE_***
+    			// 1) Long write request (DCACHE FSM)	=> DCACHE_DIRTY_***
     			// 2) Coherence request (TGT FSM) 	=> DCACHE_CC_CHECK 
     			// 3) ITLB miss request (ICACHE FSM) 	=> DCACHE_TLB_MISS
@@ -1992,8 +1977,8 @@
         //   DCACHE_INVAL_TLB 
         // - If the PTE dirty bit must be updated, we start a "long write", that is 
-        //   blocking for the processor, because we switch to the DCACHE_WRITE_SET_DIRTY
-
-        bool long_write_set_dirty = false;
-        bool tlb_inval_required	  = false;
+        //   blocking for the processor, because we switch to the DCACHE_DIRTY_SET_DIRTY
+
+        bool long_write_set_dirty = false;	// default value
+        bool tlb_inval_required	  = false;	// default value
 
         if ( r_dcache_p1_valid.read() )		// P2 stage activated
@@ -2045,8 +2030,6 @@
             {
                 long_write_set_dirty  = true;
-                r_dcache_p2_vaddr     = r_dcache_p1_vaddr.read();
-                r_dcache_p2_set_dirty = r_dcache_p1_set_dirty.read();
-                r_dcache_p2_tlb_way   = r_dcache_p1_tlb_way.read();	
-                r_dcache_p2_tlb_set   = r_dcache_p1_tlb_set.read();	
+                r_dcache_p2_way   = r_dcache_p1_tlb_way.read();	
+                r_dcache_p2_set   = r_dcache_p1_tlb_set.read();	
                 // The PTE physical address is the concatenation of the nline value (from dtlb),
                 // with the word index (obtained from the proper bits of the virtual address)
@@ -2059,5 +2042,5 @@
                 {
                     r_dcache_p2_pte_paddr = (paddr_t)(r_dcache_p1_tlb_nline.read()*(m_dcache_words<<2)) |
-                                            (paddr_t)((r_dcache_p1_vaddr.read()>>10) & 0x3c);
+                                            (paddr_t)((r_dcache_p1_vaddr.read()>>9) & 0x38);
                 }
             }
@@ -2171,5 +2154,6 @@
         /////////////////////////////////////////////////////////////////////////////
         // handling P0 pipe-line stage
-        // This stage is controlling the DCACHE FSM state register:
+        // This stage is controlling r_dcache_fsm and r_dcache_p0_* registers. 
+        // The r_dcache_p0_valid flip-flop is only set in case of WRITE request.
         // - the TLB invalidate requests have the highest priority,
         // - then the long write requests, 
@@ -2177,10 +2161,21 @@
         // - then the itlb miss requests,
         // - and finally the processor requests. 
-        // A processor read request generate a dcache access using speculative PPN 
-        // only if the write pipe-line is empty. There is an unconditionnal access 
-        // to the dtlb, using virtual address from processor.
-        // The r_dcache_p0_valid value must be computed at all cycles.
-
-        bool p0_valid = false;	// default value
+        // If dtlb is activated, there is an unconditionnal access to dtlb, 
+        // for address translation.
+        // 1) A processor WRITE request enters the three stage pipe-line (handled
+        //    by the IDLE state), and can be completed by a "long write" if the 
+        //    PTE dirty bit must be updated in dtb, dcache and RAM.
+        // 2) A processor READ request generate a simultaneouss access to
+        //    both dcache data and dcache directoty, using speculative PPN, but
+        //    is delayed if the write pipe-line is not empty.
+        //    In case of miss, we wait the VCI response in DCACHE_UNC_WAIT or 
+        //    DCACHE_MISS_WAIT states.
+        // 3) A processor LL request is handled as a READ request.
+        // 4) A processor SC request is delayed until the write pipe-line is empty.
+        //    A VCI SC transaction is launched, and we wait the VCI response in
+        //    DCACHE_SC_WAIT state. It can be completed by a "long write" if the 
+        //    PTE dirty bit must be updated in dtlb, dcache, and RAM.
+        //    The data is not modified in dcache, as it will be done by the
+        //    coherence transaction.   
 
         // TLB inval required
@@ -2189,4 +2184,5 @@
             r_dcache_fsm_save = DCACHE_IDLE;
             r_dcache_fsm      = DCACHE_INVAL_TLB_SCAN;
+            r_dcache_p0_valid = false;
         }
 
@@ -2194,5 +2190,6 @@
         else if ( long_write_set_dirty )
         {
-            r_dcache_fsm = DCACHE_WRITE_TLB_DIRTY;
+            r_dcache_fsm = DCACHE_DIRTY_TLB_SET;
+            r_dcache_p0_valid = false;
         }
 
@@ -2202,4 +2199,5 @@
             r_dcache_fsm_save = DCACHE_IDLE;
             r_dcache_fsm      = DCACHE_CC_CHECK;
+            r_dcache_p0_valid = false;
         }        
 
@@ -2210,8 +2208,9 @@
             r_dcache_tlb_vaddr  = r_icache_vaddr_save.read();
             r_dcache_fsm        = DCACHE_TLB_MISS;
+            r_dcache_p0_valid = false;
         }
 
         // processor request
-        else if (dreq.valid )
+        else if ( m_dreq.valid )
         {
             // dcache access using speculative PPN only if pipe-line empty
@@ -2228,5 +2227,5 @@
             {
                 cache_paddr = (r_dcache_p0_paddr.read() & ~PAGE_K_MASK) | 
-                              ((paddr_t)dreq.addr & PAGE_K_MASK);
+                              ((paddr_t)m_dreq.addr & PAGE_K_MASK);
 
                 cache_hit = r_dcache.read( cache_paddr,
@@ -2256,5 +2255,5 @@
             if ( r_mmu_mode.read() & DATA_TLB_MASK )	// TLB activated
             {
-                tlb_hit = r_dtlb.translate( dreq.addr,
+                tlb_hit = r_dtlb.translate( m_dreq.addr,
                                             &tlb_paddr,
                                             &tlb_flags,
@@ -2278,22 +2277,22 @@
 
             // register the processor request
-            r_dcache_p0_vaddr = dreq.addr;
-            r_dcache_p0_be    = dreq.be;
-            r_dcache_p0_wdata = dreq.wdata;
+            r_dcache_p0_vaddr = m_dreq.addr;
+            r_dcache_p0_be    = m_dreq.be;
+            r_dcache_p0_wdata = m_dreq.wdata;
 
             // Handling READ XTN requests from processor
             // They are executed in this DCACHE_IDLE state.
             // The processor must not be in user mode
-            if (dreq.type == iss_t::XTN_READ) 
-            {
-                int xtn_opcode = (int)dreq.addr/4;
+            if (m_dreq.type == iss_t::XTN_READ) 
+            {
+                int xtn_opcode = (int)m_dreq.addr/4;
 
                 // checking processor mode:
-                if (dreq.mode  == iss_t::MODE_USER)
+                if (m_dreq.mode  == iss_t::MODE_USER)
                 {
                     r_mmu_detr = MMU_READ_PRIVILEGE_VIOLATION; 
-                    r_mmu_dbvar  = dreq.addr;
-                    drsp.valid            = true;
-                    drsp.error            = true;
+                    r_mmu_dbvar  = m_dreq.addr;
+                    m_drsp.valid            = true;
+                    m_drsp.error            = true;
                     r_dcache_fsm          = DCACHE_IDLE;
                 }
@@ -2303,61 +2302,62 @@
                     {
                     case iss_t::XTN_INS_ERROR_TYPE:
-                        drsp.rdata = r_mmu_ietr.read();
-                        drsp.valid = true;
+                        m_drsp.rdata = r_mmu_ietr.read();
+                        m_drsp.valid = true;
                         break;
 
                     case iss_t::XTN_DATA_ERROR_TYPE:
-                        drsp.rdata = r_mmu_detr.read();
-                        drsp.valid = true;
+                        m_drsp.rdata = r_mmu_detr.read();
+                        m_drsp.valid = true;
                         break;
 
                     case iss_t::XTN_INS_BAD_VADDR:
-                        drsp.rdata = r_mmu_ibvar.read();       
-                        drsp.valid = true;
+                        m_drsp.rdata = r_mmu_ibvar.read();       
+                        m_drsp.valid = true;
                         break;
 
                     case iss_t::XTN_DATA_BAD_VADDR:
-                        drsp.rdata = r_mmu_dbvar.read();        
-                        drsp.valid = true;
+                        m_drsp.rdata = r_mmu_dbvar.read();        
+                        m_drsp.valid = true;
                         break;
 
                     case iss_t::XTN_PTPR:
-                        drsp.rdata = r_mmu_ptpr.read();
-                        drsp.valid = true;
+                        m_drsp.rdata = r_mmu_ptpr.read();
+                        m_drsp.valid = true;
                         break;
 
                     case iss_t::XTN_TLB_MODE:
-                        drsp.rdata = r_mmu_mode.read();
-                        drsp.valid = true;
+                        m_drsp.rdata = r_mmu_mode.read();
+                        m_drsp.valid = true;
                         break;
 
                     case iss_t::XTN_MMU_PARAMS:
-                        drsp.rdata = r_mmu_params;
-                        drsp.valid = true;
+                        m_drsp.rdata = r_mmu_params;
+                        m_drsp.valid = true;
                         break;
 
                     case iss_t::XTN_MMU_RELEASE:
-                        drsp.rdata = r_mmu_release;
-                        drsp.valid = true;
+                        m_drsp.rdata = r_mmu_release;
+                        m_drsp.valid = true;
                         break;
 
                     case iss_t::XTN_MMU_WORD_LO:
-                        drsp.rdata = r_mmu_word_lo.read();
-                        drsp.valid = true;
+                        m_drsp.rdata = r_mmu_word_lo.read();
+                        m_drsp.valid = true;
                         break;
 
                     case iss_t::XTN_MMU_WORD_HI:
-                        drsp.rdata = r_mmu_word_hi.read();
-                        drsp.valid = true;
+                        m_drsp.rdata = r_mmu_word_hi.read();
+                        m_drsp.valid = true;
                         break;
 
                     default:
                         r_mmu_detr = MMU_READ_UNDEFINED_XTN; 
-                        r_mmu_dbvar  = dreq.addr;
-                        drsp.valid = true;
-                        drsp.error = true;
+                        r_mmu_dbvar  = m_dreq.addr;
+                        m_drsp.valid = true;
+                        m_drsp.error = true;
                         break;
                     } // end switch xtn_opcode
                 } // end else
+                r_dcache_p0_valid = false;
             } // end if XTN_READ
 
@@ -2368,11 +2368,11 @@
             // Caches can be invalidated or flushed in user mode,
             // and the sync instruction can be executed in user mode
-            else if (dreq.type == iss_t::XTN_WRITE) 
-            {
-                int xtn_opcode      = (int)dreq.addr/4;
+            else if (m_dreq.type == iss_t::XTN_WRITE) 
+            {
+                int xtn_opcode      = (int)m_dreq.addr/4;
                 r_dcache_xtn_opcode = xtn_opcode;
 
                 // checking processor mode:
-                if ( (dreq.mode  == iss_t::MODE_USER) &&
+                if ( (m_dreq.mode  == iss_t::MODE_USER) &&
                      (xtn_opcode != iss_t:: XTN_SYNC) &&
                      (xtn_opcode != iss_t::XTN_DCACHE_INVAL) &&
@@ -2382,7 +2382,7 @@
                 {
                     r_mmu_detr = MMU_WRITE_PRIVILEGE_VIOLATION; 
-                    r_mmu_dbvar  = dreq.addr;
-                    drsp.valid          = true;
-                    drsp.error          = true;
+                    r_mmu_dbvar  = m_dreq.addr;
+                    m_drsp.valid          = true;
+                    m_drsp.error          = true;
                     r_dcache_fsm        = DCACHE_IDLE;
                 }
@@ -2392,5 +2392,5 @@
                     {     
                     case iss_t::XTN_PTPR:   			// itlb & dtlb must be flushed
-                        r_mmu_ptpr       = dreq.wdata;
+                        r_mmu_ptpr       = m_dreq.wdata;
                         r_dcache_xtn_req = true;
                         r_dcache_fsm     = DCACHE_XTN_SWITCH;
@@ -2398,6 +2398,6 @@
 
                     case iss_t::XTN_TLB_MODE:			// no cache or tlb access 
-                        r_mmu_mode = dreq.wdata;
-                        drsp.valid = true;
+                        r_mmu_mode = m_dreq.wdata;
+                        m_drsp.valid = true;
                         r_dcache_fsm = DCACHE_IDLE;
                         break;
@@ -2447,12 +2447,12 @@
 
                     case iss_t::XTN_MMU_WORD_LO: 		// no cache or tlb access
-                        r_mmu_word_lo = dreq.wdata;
-                        drsp.valid    = true;
+                        r_mmu_word_lo = m_dreq.wdata;
+                        m_drsp.valid    = true;
                         r_dcache_fsm  = DCACHE_IDLE;
                         break;
 
                     case iss_t::XTN_MMU_WORD_HI: 		// no cache or tlb access
-                        r_mmu_word_hi = dreq.wdata;
-                        drsp.valid    = true;
+                        r_mmu_word_hi = m_dreq.wdata;
+                        m_drsp.valid    = true;
                         r_dcache_fsm  = DCACHE_IDLE;
                         break;
@@ -2460,5 +2460,5 @@
 	            case iss_t::XTN_ICACHE_PREFETCH:		// not implemented : no action
 	            case iss_t::XTN_DCACHE_PREFETCH:		// not implemented : no action
-                        drsp.valid   = true;
+                        m_drsp.valid   = true;
                         r_dcache_fsm = DCACHE_IDLE;
 		        break;
@@ -2466,14 +2466,15 @@
                     default:
                         r_mmu_detr = MMU_WRITE_UNDEFINED_XTN; 
-                        r_mmu_dbvar  = dreq.addr;
-                        drsp.valid = true;
-                        drsp.error = true;
+                        r_mmu_dbvar  = m_dreq.addr;
+                        m_drsp.valid = true;
+                        m_drsp.error = true;
                         r_dcache_fsm = DCACHE_IDLE;
                         break;
                     } // end switch xtn_opcode
                 } // end else 
+                r_dcache_p0_valid = false;
             } // end if XTN_WRITE
 
-            // Handling read/write processor requests.
+            // Handling read/write/ll/sc processor requests.
             // The dtlb and dcache can be activated or not.
             // We compute the physical address, the cacheability, and check processor request.
@@ -2498,8 +2499,8 @@
                     // cacheability
                     if ( not (r_mmu_mode.read() & DATA_CACHE_MASK) ) cacheable = false;
-                    else cacheable = m_cacheability_table[dreq.addr];
+                    else cacheable = m_cacheability_table[m_dreq.addr];
 
                     // physical address
-                    paddr       = (paddr_t)dreq.addr;
+                    paddr       = (paddr_t)m_dreq.addr;
                 }
                 else 							// dtlb activated
@@ -2512,25 +2513,25 @@
 
                         // access rights checking 
-                        if ( not tlb_flags.u and (dreq.mode == iss_t::MODE_USER)) 
+                        if ( not tlb_flags.u and (m_dreq.mode == iss_t::MODE_USER)) 
                         {
-                            if ( (dreq.type == iss_t::DATA_READ) or (dreq.type == iss_t::DATA_LL) )
+                            if ( (m_dreq.type == iss_t::DATA_READ) or (m_dreq.type == iss_t::DATA_LL) )
                                 r_mmu_detr = MMU_READ_PRIVILEGE_VIOLATION;
                             else 
                                 r_mmu_detr = MMU_WRITE_PRIVILEGE_VIOLATION;
 
-                            r_mmu_dbvar  = dreq.addr;
-                            drsp.valid   = true;
-                            drsp.error   = true;
-                            drsp.rdata   = 0;
+                            r_mmu_dbvar  = m_dreq.addr;
+                            m_drsp.valid   = true;
+                            m_drsp.error   = true;
+                            m_drsp.rdata   = 0;
                         }
                         else if ( not tlb_flags.w and 
-                                  ((dreq.type == iss_t::DATA_WRITE) or 
-                                   (dreq.type == iss_t::DATA_SC)) ) 
+                                  ((m_dreq.type == iss_t::DATA_WRITE) or 
+                                   (m_dreq.type == iss_t::DATA_SC)) ) 
                         {
                             r_mmu_detr   = MMU_WRITE_ACCES_VIOLATION;  
-                            r_mmu_dbvar  = dreq.addr;
-                            drsp.valid   = true;
-                            drsp.error   = true;
-                            drsp.rdata   = 0;
+                            r_mmu_dbvar  = m_dreq.addr;
+                            m_drsp.valid   = true;
+                            m_drsp.error   = true;
+                            m_drsp.rdata   = 0;
                         }
                         else
@@ -2544,5 +2545,5 @@
                     else						// tlb miss
                     {
-                        r_dcache_tlb_vaddr   = dreq.addr;
+                        r_dcache_tlb_vaddr   = m_dreq.addr;
                         r_dcache_tlb_ins     = false; 
                         r_dcache_fsm         = DCACHE_TLB_MISS;
@@ -2550,5 +2551,5 @@
                 }    // end DTLB activated
 
-                if ( valid_req ) 	// processor request is valid 
+                if ( valid_req ) 	// processor request is valid after TLB check
                 {
                     // physical address and cacheability registration 
@@ -2562,6 +2563,6 @@
                     // If dcache miss, we go to DCACHE_MISS_VICTIM state.
                     // If uncacheable, we go to DCACHE_UNC_WAIT state.
-                    if ( ((dreq.type == iss_t::DATA_READ) or (dreq.type == iss_t::DATA_LL)) and
-                         not r_dcache_p0_valid.read() and not r_dcache_p1_valid.read() )
+                    if ( ((m_dreq.type == iss_t::DATA_READ) or (m_dreq.type == iss_t::DATA_LL)) 
+                        and not r_dcache_p0_valid.read() and not r_dcache_p1_valid.read() )
                     { 
                         if ( cacheable )            		// cacheable read
@@ -2596,6 +2597,6 @@
 m_cpt_data_read++;
 #endif
-                                drsp.valid   = true;
-                                drsp.rdata   = cache_rdata;
+                                m_drsp.valid   = true;
+                                m_drsp.rdata   = cache_rdata;
                             }
                         }
@@ -2603,5 +2604,5 @@
                         {
                             r_dcache_vci_paddr    = paddr;
-                            r_dcache_vci_unc_be   = dreq.be;
+                            r_dcache_vci_unc_be   = m_dreq.be;
                             r_dcache_vci_unc_req  = true;
                             r_dcache_fsm          = DCACHE_UNC_WAIT;
@@ -2609,17 +2610,18 @@
 
                         // makes reservation in case of LL
-                        if ( dreq.type == iss_t::DATA_LL )
+                        if ( m_dreq.type == iss_t::DATA_LL )
                         {
                             r_dcache_ll_valid = true;
                             r_dcache_ll_data  = cache_rdata;
-                            r_dcache_ll_vaddr = dreq.addr;
+                            r_dcache_ll_vaddr = m_dreq.addr;
                         }
+                        r_dcache_p0_valid = false;
                     } // end READ or LL
 
                     // WRITE request:
-                    // The write request arguments have been registered.
+                    // The write request arguments have been registered in r_dcache_p0 registers.
                     // The physical address has been computed and registered.
                     // We acknowledge the processor request and activate the P1 pipeline stage.
-                    else if ( dreq.type == iss_t::DATA_WRITE )
+                    else if ( m_dreq.type == iss_t::DATA_WRITE )
                     {
 
@@ -2627,59 +2629,77 @@
 m_cpt_data_write++;
 #endif
-                        p0_valid   = true;
-                        drsp.valid = true;
-                        drsp.rdata = 0;
+                        m_drsp.valid      = true;
+                        m_drsp.rdata      = 0;
+                        r_dcache_p0_valid = true;
                     } // end WRITE
  
                     // SC request:
+                    // The SC requests are taken only if the write pipe-line is empty.
                     // - if a valid LL reservation (with the same address) is registered, 
-                    // we request a SC transaction to CMD FSM and go to the DCACHE_UNC_WAIT state
-                    // that will directly return the response to the processor, and invalidate 
-                    // the LL reservation. We don't check a possible write hit in dcache, 
-                    // as the cache update is done by the coherence transaction...
-                    // - if there is no registerd LL, we just stay in IDLE state, invalidate
-                    // the LL reservation, and return 1 (atomic access failed)
-                    else if ( dreq.type == iss_t::DATA_SC )
+                    // we request a SC transaction to CMD FSM and go to the DCACHE_SC_WAIT state
+                    // that will directly return the response to the processor, invalidate 
+                    // the LL reservation, and set the Dirty bit if required.
+                    // We don't check a possible write hit in dcache, as the cache update 
+                    // is done by the coherence transaction...
+                    // - if there is no valid registered LL, we just stay in IDLE state,
+                    // and return 1 (atomic access failed)
+                    else if ( ( m_dreq.type == iss_t::DATA_SC )
+                        and not r_dcache_p0_valid.read() and not r_dcache_p1_valid.read() )
                     {
+
 #ifdef INSTRUMENTATION
 m_cpt_data_sc++;
 #endif
                         // test if valid registered LL
-                        if ( r_dcache_ll_valid.read() and (r_dcache_ll_vaddr.read() == dreq.addr))
+                        if ( r_dcache_ll_valid.read() and (r_dcache_ll_vaddr.read() == m_dreq.addr))
                         { 
-                            r_dcache_vci_paddr      = paddr;
-                            r_dcache_vci_sc_req     = true;
-                            r_dcache_vci_sc_old     = r_dcache_ll_data.read();
-                            r_dcache_vci_sc_new     = dreq.wdata;
-                            r_dcache_fsm            = DCACHE_UNC_WAIT;
+                            r_dcache_vci_paddr  = paddr;
+                            r_dcache_vci_sc_req = true;
+                            r_dcache_vci_sc_old = r_dcache_ll_data.read();
+                            r_dcache_vci_sc_new = m_dreq.wdata;
+                            r_dcache_fsm        = DCACHE_SC_WAIT;
                         }
                         else                                    // no registered LL
                         {
-                            drsp.valid        = true;
-                            drsp.rdata        = 1;
-                            r_dcache_ll_valid = false;
+                            
+                            m_drsp.valid        = true;
+                            m_drsp.rdata        = 1;
+                            r_dcache_ll_valid   = false;
                         }
+                        r_dcache_p0_valid = false;
                     } // end SC
+                    else
+                    {
+                        r_dcache_p0_valid = false;
+                    }
                 } // end valid_req
-            }  // end if read/write request	
+                else
+                {
+                    r_dcache_p0_valid = false;
+                }
+            }  // end if read/write/ll/sc request	
+        } // end dreq.valid
+        else
+        {
+            r_dcache_p0_valid = false;
         } // end P0 pipe stage
-
-        r_dcache_p0_valid = p0_valid;
         break;
     } 
     /////////////////////
     case DCACHE_TLB_MISS: // This is the entry point for the sub-fsm handling all tlb miss.
-                          // - Input arguments are r_dcache_tlb_vaddr & r_dcache_tlb_ins 
-                          // - The sub-fsm access the dcache to find the missing TLB entry,
-                          //   and activates the cache miss procedure in case of miss.
-                          // - It bypass the first level page table access if possible.
-                          // - It uses atomic access to update the R/L access bits
-                          //   in the page table if required.
-                          // - It directly updates the itlb or dtlb, and writes into the 
-                          //   r_mmu_ins_* or r_mmu_data* error reporting registers.
+                          // Input arguments are:
+                          // - r_dcache_tlb_vaddr
+                          // - r_dcache_tlb_ins (true when itlb miss) 
+                          // The sub-fsm access the dcache to find the missing TLB entry,
+                          // and activates the cache miss procedure in case of miss.
+                          // It bypass the first level page table access if possible.
+                          // It uses atomic access to update the R/L access bits
+                          // in the page table if required.
+                          // It directly updates the itlb or dtlb, and writes into the 
+                          // r_mmu_ins_* or r_mmu_data* error reporting registers.
     {
         uint32_t	ptba = 0;
         bool		bypass;
-        paddr_t		paddr;
+        paddr_t		pte_paddr;
 
         // evaluate bypass in order to skip first level page table access
@@ -2693,16 +2713,16 @@
         }
 
-        if ( not bypass )     // Try to read the PTE1/PTD1 in dcache
-        {
-            paddr = (paddr_t)r_mmu_ptpr.read() << (INDEX1_NBITS+2) |
-                    (paddr_t)((r_dcache_tlb_vaddr.read() >> PAGE_M_NBITS) << 2);
-            r_dcache_tlb_paddr = paddr;
+        if ( not bypass )     // Try to read PTE1/PTD1 in dcache
+        {
+            pte_paddr = (paddr_t)r_mmu_ptpr.read() << (INDEX1_NBITS+2) |
+                        (paddr_t)((r_dcache_tlb_vaddr.read() >> PAGE_M_NBITS) << 2);
+            r_dcache_tlb_paddr = pte_paddr;
             r_dcache_fsm       = DCACHE_TLB_PTE1_GET;
         }
-        else                  // Try to read the PTE2 in dcache
-        {
-            paddr = (paddr_t)ptba << PAGE_K_NBITS |
-                    (paddr_t)(r_dcache_tlb_vaddr.read()&PTD_ID2_MASK)>>(PAGE_K_NBITS-3);
-            r_dcache_tlb_paddr = paddr;
+        else                  // Try to read PTE2 in dcache
+        {
+            pte_paddr = (paddr_t)ptba << PAGE_K_NBITS |
+                        (paddr_t)(r_dcache_tlb_vaddr.read()&PTD_ID2_MASK)>>(PAGE_K_NBITS-3);
+            r_dcache_tlb_paddr = pte_paddr;
             r_dcache_fsm       = DCACHE_TLB_PTE2_GET;
         }
@@ -2712,10 +2732,14 @@
 {
     if ( r_dcache_tlb_ins.read() ) 
-        std::cout << "  <PROC.DCACHE_TLB_MISS> ITLB miss request:";
-    else                           
-        std::cout << "  <PROC.DCACHE_TLB_MISS> DTLB miss request:";
-    std::cout << " vaddr = " << std::hex << r_dcache_tlb_vaddr.read()
-              << " / bypass = " << bypass 
-              << " / PTE address = " << paddr << std::endl;
+    {
+        std::cout << "  <PROC.DCACHE_TLB_MISS> ITLB miss";
+    }
+    else
+    {                           
+        std::cout << "  <PROC.DCACHE_TLB_MISS> DTLB miss";
+    }
+    std::cout << " / VADDR = " << std::hex << r_dcache_tlb_vaddr.read()
+              << " / BYPASS = " << bypass 
+              << " / PTE_ADR = " << pte_paddr << std::endl;
 }
 #endif
@@ -2755,6 +2779,6 @@
                     r_mmu_detr             = MMU_READ_PT1_UNMAPPED;
                     r_mmu_dbvar            = r_dcache_tlb_vaddr.read();
-                    drsp.valid             = true;
-                    drsp.error             = true;
+                    m_drsp.valid             = true;
+                    m_drsp.error             = true;
                 }
                 r_dcache_fsm          = DCACHE_IDLE;
@@ -2829,8 +2853,8 @@
         else		// we must load the missing cache line in dcache
         {
+            r_dcache_vci_miss_req  = true;		
             r_dcache_vci_paddr     = r_dcache_tlb_paddr.read(); 
             r_dcache_miss_type     = PTE1_MISS;
             r_dcache_fsm           = DCACHE_MISS_VICTIM;	 
-            r_dcache_vci_miss_req  = true;		
 
 #if DEBUG_DCACHE
@@ -2895,29 +2919,31 @@
         uint32_t  pte   = r_dcache_tlb_pte_flags.read();
         bool	  updt  = false;
-
-        //  test the access bits L/R, depending on the physical address locality
-        //  we must use the 10 MSB bits of the 19 bits PPN1 to obtain the target index
-        //  we must use the 10 MSB bits of the SRCID to obtain the local index
-        //  set the r_dcache_vci_sc_old and r_dcache_vci_sc_new registers if SC required
-
-        uint32_t target = (pte >> 9) & 0x3FF;
-        uint32_t local  = m_srcid_d >> 4;
-
-        if ( local == target )						// local_address
+        bool	  local = true;
+
+        // We should compute the access locality: 
+        // The PPN MSB bits define the destination cluster index.
+        // The m_srcid_d MSB bits define the source cluster index.
+        // The number of bits to compare depends on the number of clusters, 
+        // and can be obtained in the mapping table.
+        // As long as this computation is not done, all access are local.
+
+        if ( local )						// local access
         {
             if ( not ((pte & PTE_L_MASK) == PTE_L_MASK) ) // we must set the L bit
             {
-                updt            = true;
-                r_dcache_vci_sc_old = r_dcache_tlb_pte_flags.read();
-                r_dcache_vci_sc_new = r_dcache_tlb_pte_flags.read() | PTE_L_MASK;
-            }
-        }
-        else 								// remote address
+                updt                = true;
+                r_dcache_vci_sc_old = pte;
+                r_dcache_vci_sc_new = pte | PTE_L_MASK;
+                pte                 = pte | PTE_L_MASK;
+            }
+        }
+        else 							// remote access
         {
             if ( not ((pte & PTE_R_MASK) == PTE_R_MASK) ) // we must set the R bit
             {
                 updt                = true;
-                r_dcache_vci_sc_old = r_dcache_tlb_pte_flags.read();
-                r_dcache_vci_sc_new = r_dcache_tlb_pte_flags.read() | PTE_R_MASK;
+                r_dcache_vci_sc_old = pte;
+                r_dcache_vci_sc_new = pte | PTE_R_MASK;
+                pte                 = pte | PTE_R_MASK;
             }
         }
@@ -2951,5 +2977,5 @@
         }
         // next state
-        if ( updt ) r_dcache_fsm = DCACHE_TLB_SC_UPDT; 	// dcache and page table update
+        if ( updt ) r_dcache_fsm = DCACHE_TLB_LR_UPDT; 	// dcache and page table update
         else        r_dcache_fsm = DCACHE_TLB_RETURN;	// exit sub-fsm
 
@@ -2959,15 +2985,15 @@
     if ( r_dcache_tlb_ins.read() ) 
     {
-        std::cout << "  <PROC.DCACHE_TLB_PTE1_UPDT> write PTE1 in ITLB:";
-        std::cout << " way = " << std::dec << r_dcache_tlb_way.read()
-                  << " / set = " << r_dcache_tlb_set.read() << std::endl;
-        r_itlb.print();
+        std::cout << "  <PROC.DCACHE_TLB_PTE1_UPDT> write PTE1 in ITLB";
+        std::cout << " / set = " << std::dec << r_dcache_tlb_set.read()
+                  << " / way = " << r_dcache_tlb_way.read() << std::endl;
+        r_itlb.printTrace();
     }
     else                           
     {
-        std::cout << "  <PROC.DCACHE_TLB_PTE1_UPDT> write PTE1 in DTLB:";
-        std::cout << " way = " << std::dec << r_dcache_tlb_way.read()
-                  << " / set = " << r_dcache_tlb_set.read() << std::endl;
-        r_dtlb.print();
+        std::cout << "  <PROC.DCACHE_TLB_PTE1_UPDT> write PTE1 in DTLB";
+        std::cout << " / set = " << std::dec << r_dcache_tlb_set.read()
+                  << " / way = " << r_dcache_tlb_way.read() << std::endl;
+        r_dtlb.printTrace();
     }
     
@@ -3010,6 +3036,6 @@
                     r_mmu_detr             = MMU_READ_PT2_UNMAPPED;
                     r_mmu_dbvar            = r_dcache_tlb_vaddr.read();
-                    drsp.valid             = true;
-                    drsp.error             = true;
+                    m_drsp.valid             = true;
+                    m_drsp.error             = true;
                 }
                 r_dcache_fsm          = DCACHE_IDLE;
@@ -3047,8 +3073,8 @@
         else            // we must load the missing cache line in dcache
         {
+            r_dcache_fsm          = DCACHE_MISS_VICTIM; 
+            r_dcache_vci_miss_req = true;
             r_dcache_vci_paddr    = r_dcache_tlb_paddr.read();
             r_dcache_miss_type    = PTE2_MISS;
-            r_dcache_fsm          = DCACHE_MISS_VICTIM; 
-            r_dcache_vci_miss_req = true;
 
 #if DEBUG_DCACHE
@@ -3088,4 +3114,16 @@
 #endif
         }
+
+#if DEBUG_DCACHE
+if ( m_debug_dcache_fsm )
+{
+    if ( r_dcache_tlb_ins.read() ) 
+        std::cout << "  <PROC.DCACHE_TLB_PTE2_SELECT> Select a slot in ITLB:";
+    else                           
+        std::cout << "  <PROC.DCACHE_TLB_PTE2_SELECT> Select a slot in DTLB:";
+        std::cout << " way = " << std::dec << way
+                  << " / set = " << set << std::endl;
+}
+#endif
         r_dcache_tlb_way = way;
         r_dcache_tlb_set = set;
@@ -3095,36 +3133,38 @@
     //////////////////////////
     case DCACHE_TLB_PTE2_UPDT:      	// write a new PTE2 in tlb after testing the L/R bit
-				    	// if L/R bit already set exit the sub-fsm
+				    	// if L/R bit already set, exit the sub-fsm
                                     	// if not, the page table must be updated by an atomic access
     {
-        paddr_t		nline     = r_dcache_p0_paddr.read() >> (uint32_log2(m_dcache_words)+2);   
+        paddr_t	        nline     = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words)+2);   
         uint32_t        pte_flags = r_dcache_tlb_pte_flags.read();
         uint32_t        pte_ppn   = r_dcache_tlb_pte_ppn.read();
-        bool            updt      = false;                         // page table update required
-
-        //  test the access bit L/R, depending on the physical address locality
-        //  we must use the 10 MSB bits of the 28 bits PPN2 to obtain the target cluster index
-        //  we must use the 10 MSB bits of the SRCID to obtain the local cluster index
-        //  set the r_dcache_vci_sc_old and r_dcache_vci_sc_new registers if SC required.
-
-        uint32_t target = (pte_ppn >> 18) & 0x3FF;
-        uint32_t local  = m_srcid_d >> 4;
-
-        if ( local == target )						// local address
+        bool            updt      = false;
+        bool            local     = true;
+
+        // We should compute the access locality: 
+        // The PPN MSB bits define the destination cluster index.
+        // The m_srcid_d MSB bits define the source cluster index.
+        // The number of bits to compare depends on the number of clusters, 
+        // and can be obtained in the mapping table.
+        // As long as this computation is not done, all access are local.
+
+        if ( local )						// local access
         {
             if ( not ((pte_flags & PTE_L_MASK) == PTE_L_MASK) ) // we must set the L bit
             {
+                updt                = true;
+                r_dcache_vci_sc_old = pte_flags;
+                r_dcache_vci_sc_new = pte_flags | PTE_L_MASK;
+                pte_flags           = pte_flags | PTE_L_MASK;
+            }
+        }
+        else                                                    // remote access
+        {
+            if ( not ((pte_flags & PTE_R_MASK) == PTE_R_MASK) ) // we must set the R bit
+            {
                 updt                   = true;
-                r_dcache_vci_sc_old        = r_dcache_tlb_pte_flags.read();
-                r_dcache_vci_sc_new        = r_dcache_tlb_pte_flags.read() | PTE_L_MASK;
-            }
-        }
-        else                                                             // remote address
-        {
-            if ( not ((pte_flags & PTE_R_MASK) == PTE_R_MASK) ) // we must set the R bit
-            {
-                updt                   = true;
-                r_dcache_vci_sc_old        = r_dcache_tlb_pte_flags.read();
-                r_dcache_vci_sc_new        = r_dcache_tlb_pte_flags.read() | PTE_R_MASK;
+                r_dcache_vci_sc_old = pte_flags;
+                r_dcache_vci_sc_new = pte_flags | PTE_R_MASK;
+                pte_flags           = pte_flags | PTE_R_MASK;
             }
         }
@@ -3133,5 +3173,5 @@
         if ( r_dcache_tlb_ins.read() )  
         {
-            r_itlb.write( false,	// 2K page
+            r_itlb.write( false,	// 4K page
                           pte_flags,
                           pte_ppn,
@@ -3146,5 +3186,5 @@
         else
         {
-            r_dtlb.write( false,	// 2K page
+            r_dtlb.write( false,	// 4K page
                           pte_flags,
                           pte_ppn,
@@ -3163,25 +3203,25 @@
     if ( r_dcache_tlb_ins.read() ) 
     {
-        std::cout << "  <PROC.DCACHE_TLB_PTE2_UPDT> write PTE2 in ITLB:";
-        std::cout << " way = " << std::dec << r_dcache_tlb_way.read()
-                  << " / set = " << r_dcache_tlb_set.read() << std::endl;
-        r_itlb.print();
+        std::cout << "  <PROC.DCACHE_TLB_PTE2_UPDT> write PTE2 in ITLB";
+        std::cout << " / set = " << std::dec << r_dcache_tlb_set.read()
+                  << " / way = " << r_dcache_tlb_way.read() << std::endl;
+        r_itlb.printTrace();
     }
     else                           
     {
-        std::cout << "  <PROC.DCACHE_TLB_PTE2_UPDT> write PTE2 in DTLB:";
-        std::cout << " way = " << std::dec << r_dcache_tlb_way.read()
-                  << " / set = " << r_dcache_tlb_set.read() << std::endl;
-        r_dtlb.print();
+        std::cout << "  <PROC.DCACHE_TLB_PTE2_UPDT> write PTE2 in DTLB";
+        std::cout << " / set = " << std::dec << r_dcache_tlb_set.read()
+                  << " / way = " << r_dcache_tlb_way.read() << std::endl;
+        r_dtlb.printTrace();
     }
 }
 #endif
         // next state
-        if ( updt ) r_dcache_fsm = DCACHE_TLB_SC_UPDT; 	// dcache and page table update
+        if ( updt ) r_dcache_fsm = DCACHE_TLB_LR_UPDT; 	// dcache and page table update
         else        r_dcache_fsm = DCACHE_TLB_RETURN;	// exit sub-fsm
         break;
     }
     ////////////////////////
-    case DCACHE_TLB_SC_UPDT:		// update the dcache after a tlb miss (L/R bit),
+    case DCACHE_TLB_LR_UPDT:		// update the dcache after a tlb miss (L/R bit),
                                         // request a SC transaction to CMD FSM 
     {
@@ -3189,5 +3229,5 @@
 if ( m_debug_dcache_fsm )
 {
-    std::cout << "  <PROC.DCACHE_TLB_SC_UPDT> Update dcache: (L/R) bit" << std::endl;
+    std::cout << "  <PROC.DCACHE_TLB_LR_UPDT> Update dcache: (L/R) bit" << std::endl;
 }
 #endif
@@ -3200,10 +3240,11 @@
 #endif
         // r_dcache_vci_sc_old & r_dcache_vci_sc_new registers are already set
+        r_dcache_vci_paddr   = r_dcache_tlb_paddr.read();
         r_dcache_vci_sc_req  = true;
-        r_dcache_fsm         = DCACHE_TLB_SC_WAIT;
+        r_dcache_fsm         = DCACHE_TLB_LR_WAIT;
         break;
     }
     ////////////////////////
-    case DCACHE_TLB_SC_WAIT:		// Waiting a response to SC transaction.
+    case DCACHE_TLB_LR_WAIT:		// Waiting a response to SC transaction.
                                         // We consume the response in rsp FIFO, 
                                         // and exit the sub-fsm, but we don't
@@ -3224,5 +3265,5 @@
         if ( r_vci_rsp_data_error.read() ) 	// bus error
         {
-            std::cout << "BUS ERROR in DCACHE_TLB_SC_WAIT state" << std::endl;
+            std::cout << "BUS ERROR in DCACHE_TLB_LR_WAIT state" << std::endl;
             std::cout << "This should not happen in this state" << std::endl;
             exit(0);
@@ -3233,5 +3274,5 @@
 if ( m_debug_dcache_fsm )
 {
-    std::cout << "  <PROC.DCACHE_TLB_SC_WAIT> SC response received" << std::endl;
+    std::cout << "  <PROC.DCACHE_TLB_LR_WAIT> SC response received" << std::endl;
 }
 #endif
@@ -3261,5 +3302,5 @@
             r_dtlb.flush();
             r_dcache_fsm = DCACHE_IDLE;
-            drsp.valid = true;
+            m_drsp.valid = true;
         }
         break;
@@ -3279,5 +3320,5 @@
         if ( r_wbuf.empty() )
         {
-            drsp.valid   = true;
+            m_drsp.valid   = true;
             r_dcache_fsm = DCACHE_IDLE;
         }
@@ -3311,5 +3352,5 @@
         {
             r_dcache_fsm = DCACHE_IDLE;
-            drsp.valid = true;
+            m_drsp.valid = true;
         }
         break;
@@ -3351,5 +3392,5 @@
                 }
                 r_dcache_fsm = DCACHE_IDLE;
-                drsp.valid = true;
+                m_drsp.valid = true;
             }
         }
@@ -3361,5 +3402,5 @@
         r_dtlb.inval(r_dcache_p0_wdata.read());
         r_dcache_fsm        = DCACHE_IDLE;
-        drsp.valid          = true;
+        m_drsp.valid          = true;
         break;
     }
@@ -3429,5 +3470,5 @@
         {
             r_dcache_fsm      = DCACHE_IDLE;
-            drsp.valid        = true;
+            m_drsp.valid        = true;
         }
         break;
@@ -3480,5 +3521,5 @@
             {
                 r_dcache_fsm = DCACHE_IDLE;
-                drsp.valid = true;
+                m_drsp.valid = true;
             }
 	}
@@ -3489,5 +3530,5 @@
     {
         r_dcache_fsm = DCACHE_IDLE;
-        drsp.valid = true;
+        m_drsp.valid = true;
         break;
     }
@@ -3593,6 +3634,6 @@
                     r_mmu_detr            = MMU_READ_DATA_ILLEGAL_ACCESS; 
                     r_mmu_dbvar           = r_dcache_p0_vaddr.read();
-                    drsp.valid            = true;
-                    drsp.error            = true;
+                    m_drsp.valid            = true;
+                    m_drsp.error            = true;
                     r_dcache_fsm          = DCACHE_IDLE;
                     break;
@@ -3611,6 +3652,6 @@
                         r_mmu_detr              = MMU_READ_PT1_ILLEGAL_ACCESS;
                         r_mmu_dbvar             = r_dcache_tlb_vaddr.read();
-                        drsp.valid              = true;
-                        drsp.error              = true;
+                        m_drsp.valid              = true;
+                        m_drsp.error              = true;
                     }
                     r_dcache_fsm                = DCACHE_IDLE;
@@ -3630,6 +3671,6 @@
                         r_mmu_detr              = MMU_READ_PT2_ILLEGAL_ACCESS;
                         r_mmu_dbvar             = r_dcache_tlb_vaddr.read();
-                        drsp.valid              = true;
-                        drsp.error              = true;
+                        m_drsp.valid              = true;
+                        m_drsp.error              = true;
                     }
                     r_dcache_fsm                = DCACHE_IDLE;
@@ -3755,8 +3796,8 @@
         {
             r_mmu_detr           = MMU_READ_DATA_ILLEGAL_ACCESS; 
-            r_mmu_dbvar          = dreq.addr;
+            r_mmu_dbvar          = m_dreq.addr;
             r_vci_rsp_data_error = false;
-            drsp.error           = true;
-            drsp.valid           = true;
+            m_drsp.error           = true;
+            m_drsp.valid           = true;
             r_dcache_fsm         = DCACHE_IDLE;
             break;
@@ -3767,19 +3808,84 @@
             r_dcache_fsm            = DCACHE_IDLE;
             // we acknowledge the processor request if it has not been modified
-            if ( dreq.valid and (dreq.addr == r_dcache_p0_vaddr.read()) )
-            {
-	        drsp.valid          = true;
-	        drsp.rdata          = r_vci_rsp_fifo_dcache.read();
+            if ( m_dreq.valid and (m_dreq.addr == r_dcache_p0_vaddr.read()) )
+            {
+	        m_drsp.valid          = true;
+	        m_drsp.rdata          = r_vci_rsp_fifo_dcache.read();
             }
 	}	
         break;
     }
-    ////////////////////////////
-    case DCACHE_WRITE_TLB_DIRTY:	// set PTE dirty bit in dtlb
+    ////////////////////
+    case DCACHE_SC_WAIT:	// waiting VCI response after a processor SC request
+                                // a long write is launched if dirty bit must be set
+    {
+        // external coherence request
+        if ( r_tgt_dcache_req.read() ) 
+        {
+            r_dcache_fsm = DCACHE_CC_CHECK;
+            r_dcache_fsm_save = r_dcache_fsm;
+            break;
+        }
+
+        if ( r_vci_rsp_data_error.read() ) 		// bus error
+        {
+            r_mmu_detr           = MMU_READ_DATA_ILLEGAL_ACCESS; 
+            r_mmu_dbvar          = m_dreq.addr;
+            r_vci_rsp_data_error = false;
+            m_drsp.error         = true;
+            m_drsp.valid         = true;
+            r_dcache_fsm         = DCACHE_IDLE;
+            break;
+        }
+	else if ( r_vci_rsp_fifo_dcache.rok() )     	// response available
+	{
+            bool sc_success = (r_vci_rsp_fifo_dcache.read() == 0);
+            vci_rsp_fifo_dcache_get = true;     
+
+            if ( sc_success and not r_dcache_p0_tlb_dirty.read() )	// Dirty bit must be set
+            {
+                // The PTE physical address is the concatenation of the nline value (from dtlb),
+                // with the word index (obtained from the proper bits of the virtual address)
+                if ( r_dcache_p0_tlb_big.read() )	// PTE1
+                {
+                    r_dcache_p2_pte_paddr = (paddr_t)(r_dcache_p0_tlb_nline.read()*(m_dcache_words<<2)) |
+                                            (paddr_t)((r_dcache_p0_vaddr.read()>>19) & 0x3c);
+                }
+                else					// PTE2
+                {
+                    r_dcache_p2_pte_paddr = (paddr_t)(r_dcache_p0_tlb_nline.read()*(m_dcache_words<<2)) |
+                                            (paddr_t)((r_dcache_p0_vaddr.read()>>9) & 0x38);
+                }
+                r_dcache_p2_sc_success = sc_success;
+                r_dcache_p2_way        = r_dcache_p0_tlb_way.read();
+                r_dcache_p2_set        = r_dcache_p0_tlb_set.read();
+                r_dcache_fsm           = DCACHE_DIRTY_TLB_SET;
+         
+            }
+            else
+            {
+	        m_drsp.valid            = true;
+	        m_drsp.rdata            = r_vci_rsp_fifo_dcache.read();
+                r_dcache_fsm            = DCACHE_IDLE;
+            }
+	}	
+        break;
+    }
+    //////////////////////////
+    case DCACHE_DIRTY_TLB_SET:		// Enter this sub_fsm in case of long write:
+                                        // - in case of WRITE request (r_dcache_p2_type_sc == false)
+                                        // - in case of SC request    (r_dcache_p2_type_sc == true)
+					// Inputs arguments are:
+                                        // - r_dcache_p2_way,
+                                        // - r_dcache_p2_set, 
+                                        // - r_dcache_p2_pte_paddr,
+                                        // - r_dcache_p2_type_sc, 
+                                        // - r_dcache_p2_sc_success,
+                                        // In this first state, we set PTE dirty bit in dtlb
 					// and get PTE in dcache
     {
         // set dirty bit in dtlb
-        r_dtlb.set_dirty( r_dcache_p2_tlb_way.read(),
-                          r_dcache_p2_tlb_set.read() );
+        r_dtlb.set_dirty( r_dcache_p2_way.read(),
+                          r_dcache_p2_set.read() );
 
         // get PTE in dcache
@@ -3801,33 +3907,33 @@
 if ( m_debug_dcache_fsm )
 {
-    std::cout << "  <PROC.DCACHE_WRITE_TLB_DIRTY> Set dirty bit in dtlb:" << std::dec
-              << " / tlb_way = " << r_dcache_p2_tlb_way.read()
-              << " / tlb_set = " << r_dcache_p2_tlb_set.read() << std::endl;
-    r_dtlb.print();
-    std::cout << "                                Get PTE in dcache:" << std::hex
-              << " paddr = " << r_dcache_p2_pte_paddr.read() 
+    std::cout << "  <PROC.DCACHE_DIRTY_TLB_SET> Set dirty bit in dtlb:" << std::dec
+              << " / tlb_set = " << r_dcache_p2_set.read()
+              << " / tlb_way = " << r_dcache_p2_way.read() << std::endl;
+    r_dtlb.printTrace();
+    std::cout << "      and get PTE in dcache" << std::hex
+              << " / PADDR = " << r_dcache_p2_pte_paddr.read() 
               << " / PTE = " << pte << std::dec
-              << " / dcache_way = " << way
-              << " / dcache_set = " << set << std::endl;
+              << " / set = " << set
+              << " / way = " << way << std::endl;
 }
 #endif
-        assert( hit and "error in DCACHE_WRITE_TLB_DIRTY: the PTE should be in dcache" );
-
-        r_dcache_p2_pte_way   = way;			// register pte way in dcache
-        r_dcache_p2_pte_set   = set;			// register pte set in dcache;
-        r_dcache_p2_pte_word  = word;			// register pte word in dcache;
-        r_dcache_p2_pte       = pte;			// register pte value
-        r_dcache_fsm          = DCACHE_WRITE_CACHE_DIRTY;
-        break;
-    }
-    //////////////////////////////
-    case DCACHE_WRITE_CACHE_DIRTY:	// set PTE dirty bit in dcache
+        assert( hit and "error in DCACHE_DIRTY_TLB_SET: the PTE should be in dcache" );
+
+        r_dcache_p2_way       = way;			// register pte way in dcache
+        r_dcache_p2_set       = set;			// register pte set in dcache;
+        r_dcache_p2_word      = word;			// register pte word in dcache;
+        r_dcache_p2_pte_value = pte;			// register pte value
+        r_dcache_fsm          = DCACHE_DIRTY_CACHE_SET;
+        break;
+    }
+    ////////////////////////////
+    case DCACHE_DIRTY_CACHE_SET:	// set PTE dirty bit in dcache
                                         // request SC tranansaction to CMD FSM 
     {
 	// set PTE dirty bit in dcache
-        r_dcache.write( r_dcache_p2_pte_way.read(),
-                        r_dcache_p2_pte_set.read(),
-                        r_dcache_p2_pte_word.read(),
-                        r_dcache_p2_pte.read() | PTE_D_MASK,
+        r_dcache.write( r_dcache_p2_way.read(),
+                        r_dcache_p2_set.read(),
+                        r_dcache_p2_word.read(),
+                        r_dcache_p2_pte_value.read() | PTE_D_MASK,
                         0xF );
 
@@ -3835,29 +3941,30 @@
 m_cpt_dcache_data_write++;
 #endif
-        
+        // request sc transaction to CMD_FSM
+        r_dcache_vci_sc_req = true;
+        r_dcache_vci_paddr  = r_dcache_p2_pte_paddr.read();
+        r_dcache_vci_sc_old = r_dcache_p2_pte_value.read();
+        r_dcache_vci_sc_new = r_dcache_p2_pte_value.read() | PTE_D_MASK;
+        r_dcache_fsm        = DCACHE_DIRTY_SC_WAIT;    
+
 #if DEBUG_DCACHE
 if ( m_debug_dcache_fsm )
 {
-    std::cout << "  <PROC.DCACHE_WRITE_CACHE_DIRTY> Set PTE dirty bit in dcache"
-              << " / way = " << r_dcache_p2_pte_way.read()
-              << " / set = " << r_dcache_p2_pte_set.read() 
-              << " / word = " << r_dcache_p2_pte_word.read() << std::endl;
-    std::cout << "                                  Request SC transaction"
-              << " / address = " << "bloup"
-              << " / old = " << r_dcache_p2_pte.read()
-              << " / new = " << (r_dcache_p2_pte.read() | PTE_D_MASK) << std::endl;
+    std::cout << "  <PROC.DCACHE_DIRTY_CACHE_SET> Set PTE dirty bit in dcache"
+              << " / way = " << r_dcache_p2_way.read()
+              << " / set = " << r_dcache_p2_set.read() 
+              << " / word = " << r_dcache_p2_word.read() << std::endl;
+    std::cout << "   and request SC transaction for dirty bit update"
+              << " / address = " << r_dcache_p2_pte_paddr.read()
+              << " / old = " << r_dcache_p2_pte_value.read()
+              << " / new = " << (r_dcache_p2_pte_value.read() | PTE_D_MASK) << std::endl;
 }
 #endif
-        // request sc transaction to CMD_FSM
-        r_dcache_vci_sc_req = true;
-        r_dcache_vci_sc_old = r_dcache_p2_pte.read();
-        r_dcache_vci_sc_new = r_dcache_p2_pte.read() | PTE_D_MASK;
-        r_dcache_fsm        = DCACHE_WRITE_SC_WAIT;    
         break;
     }
     //////////////////////////
-    case DCACHE_WRITE_SC_WAIT:		// wait completion of SC
+    case DCACHE_DIRTY_SC_WAIT:		// wait completion of SC for PTE Dirty bit
                                         // if atomic, write completed : return to IDLE state
-                                        // else, makes an uncacheable read to retry the SC
+                                        // else, read the mofified PTE to retry the SC
     {
         // external coherence request
@@ -3871,24 +3978,30 @@
         if ( r_vci_rsp_data_error.read() )	// bus error
         {
-            r_mmu_detr   = MMU_WRITE_PT2_ILLEGAL_ACCESS; 
-            r_mmu_dbvar  = r_dcache_p2_vaddr;
-            drsp.valid   = true;
-            drsp.error   = true;
-            r_dcache_fsm = DCACHE_IDLE;
-            break;
+            std::cout << "BUS ERROR in DCACHE_DIRTY_SC_WAIT state" << std::endl;
+            std::cout << "This should not happen in this state" << std::endl;
+            exit(0);
         }
         else if ( r_vci_rsp_fifo_dcache.rok() )	// response available
         {
-            if ( r_vci_rsp_fifo_dcache.read() == 0 )		// atomic
-            {
-                drsp.valid   = true;		// acknowledge the initial write
-                r_dcache_fsm = DCACHE_IDLE;
-            }
-            else						
+            vci_rsp_fifo_dcache_get = true;
+            if ( r_vci_rsp_fifo_dcache.read() == 0 )	// exit if dirty bit update atomic
+            {
+                if ( r_dcache_p2_type_sc.read() )	// long write for SC request
+                {
+                    m_drsp.valid = true;
+                    m_drsp.rdata = ( r_dcache_p2_sc_success.read() ? 0 : 1 ); 
+                    r_dcache_fsm = DCACHE_IDLE;
+                }
+                else					// long write for WRITE request
+                {
+                    r_dcache_fsm = DCACHE_IDLE;
+                }
+            }
+            else					// retry if dirty bit update failed
             {
                 r_dcache_vci_paddr   = r_dcache_p2_pte_paddr;
                 r_dcache_vci_unc_req = true;
                 r_dcache_vci_unc_be  = 0xF;
-                r_dcache_fsm         = DCACHE_WRITE_UNC_WAIT;
+                r_dcache_fsm         = DCACHE_DIRTY_UNC_WAIT;
             }
         }
@@ -3896,6 +4009,6 @@
     }
     ///////////////////////////
-    case DCACHE_WRITE_UNC_WAIT:		// wait completion of uncacheable read
-                                        // in case of success we retry a SC request to
+    case DCACHE_DIRTY_UNC_WAIT:		// wait completion of PTE read
+                                        // and retry a SC request to
                                         // set the dirty bit in the PTE
     {
@@ -3910,10 +4023,7 @@
         if ( r_vci_rsp_data_error.read() )	// bus error
         {
-            r_mmu_detr   = MMU_READ_PT2_ILLEGAL_ACCESS; 
-            r_mmu_dbvar  = r_dcache_p2_vaddr;
-            drsp.valid   = true;
-            drsp.error   = true;
-            r_dcache_fsm = DCACHE_IDLE;
-            break;
+            std::cout << "BUS ERROR in DCACHE_DIRTY_UNC_WAIT state" << std::endl;
+            std::cout << "This should not happen in this state" << std::endl;
+            exit(0);
         }
         if ( r_vci_rsp_fifo_dcache.rok() )	// PTE available
@@ -3922,5 +4032,5 @@
             r_dcache_vci_sc_old = r_vci_rsp_fifo_dcache.read();
             r_dcache_vci_sc_new = r_vci_rsp_fifo_dcache.read() | PTE_D_MASK;
-            r_dcache_fsm        = DCACHE_WRITE_SC_WAIT;    
+            r_dcache_fsm        = DCACHE_DIRTY_SC_WAIT;    
         }
         break;
@@ -4169,5 +4279,5 @@
               << " / set = " << set 
               << " / way = " << way << std::endl;
-    r_itlb.print();
+    r_itlb.printTrace();
 }
 #endif
@@ -4186,5 +4296,5 @@
               << " / set = " << set 
               << " / way = " << way << std::endl;
-    r_dtlb.print();
+    r_dtlb.printTrace();
 }
 #endif
@@ -4207,24 +4317,11 @@
     } // end switch r_dcache_fsm
 
-
-    //////////////////// save DREQ and DRSP fields for print_trace() ////////////////
-    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;
-
     ///////////////// wbuf update //////////////////////////////////////////////////////
     r_wbuf.update();
 
-    /////////// test processor frozen /////////////////////////////////////////////
+    //////////////// 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) )       
+    if ( (m_ireq.valid and not m_irsp.valid) or (m_dreq.valid and not m_drsp.valid) )       
     {
         m_cpt_frz_cycles++; 		// used for instrumentation
@@ -4248,5 +4345,5 @@
     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);
+    r_iss.executeNCycles(1, m_irsp, m_drsp, it);
     }
 
