Index: trunk/modules/vci_cc_vcache_wrapper2_v1/caba/source/src/vci_cc_vcache_wrapper2_v1.cpp
===================================================================
--- trunk/modules/vci_cc_vcache_wrapper2_v1/caba/source/src/vci_cc_vcache_wrapper2_v1.cpp	(revision 73)
+++ trunk/modules/vci_cc_vcache_wrapper2_v1/caba/source/src/vci_cc_vcache_wrapper2_v1.cpp	(revision 79)
@@ -85,4 +85,5 @@
 	"DCACHE_SC_DIRTY_WAIT",
         "DCACHE_WRITE_UPDT", 
+        "DCACHE_WRITE_DIRTY",
         "DCACHE_WRITE_REQ",  
         "DCACHE_MISS_WAIT",  
@@ -459,5 +460,6 @@
         r_dcache_tlb_sc_acc_req   = false;    
         r_dcache_tlb_ll_dirty_req = false;   
-        r_dcache_tlb_sc_dirty_req = false;   
+        r_dcache_tlb_sc_dirty_req = false; 
+        r_dcache_sc_updt_dirty    = false;	
         r_dcache_itlb_ll_acc_req  = false;   
         r_dcache_itlb_sc_acc_req  = false;   
@@ -1007,5 +1009,4 @@
         else                                                                // MMU activated
         { 
-	    size_t c_way, c_set;
             m_cpt_ins_tlb_read++;
             icache_hit_t  = icache_tlb.cctranslate(ireq.addr, &tlb_ipaddr, &icache_pte_info, 
@@ -1015,16 +1016,4 @@
             spc_ipaddr    = ((paddr_t)r_icache_ppn_save << PAGE_K_NBITS) | (paddr_t)(ireq.addr & PAGE_K_MASK);
             icache_cached = icache_pte_info.c; 
-	    if (icache_hit_t) {
-	       if (!r_dcache.read(icache_tlb_nline << (uint32_log2(m_dcache_words) + 2), &icache_ins, &c_way, &c_set)) {
-		std::cout << "itlb PTE " << std::hex << icache_tlb_nline << " " << (icache_tlb_nline << (uint32_log2(m_dcache_words) + 2)) << " not in cache" << std::endl;
-		abort();
-	      }
-	      if (!r_dcache_in_itlb[m_dcache_sets*c_way+c_set]) {
-		std::cout << "itlb PTE " << std::hex << icache_tlb_nline << " "
-		    << (icache_tlb_nline << (uint32_log2(m_dcache_words) + 2)) <<
-		    " " << c_way << "," << c_set << " @" << &r_dcache_in_itlb[m_dcache_sets*c_way+c_set] << " not in_itlb" << std::endl;
-		abort();
-	      }
-	   }
         }
 
@@ -1329,6 +1318,5 @@
                 }
             }
-
-            if ( r_icache_inval_tlb_rsp ) // TLB miss read response and invalidation
+	    else  // TLB miss read response and invalidation
             {
                 if ( r_dcache_rsp_itlb_error ) 
@@ -1385,6 +1373,5 @@
                 }
             } 
-
-            if ( r_icache_inval_tlb_rsp) // TLB ET write response and invalidation     
+	    else   // TLB ET write response and invalidation     
             {   
                 if ( r_dcache_rsp_itlb_error ) 
@@ -1531,6 +1518,5 @@
                 }
             }
-            
-            if ( r_icache_inval_tlb_rsp ) // TLB miss read response and invalidation
+	    else  // TLB miss read response and invalidation
             {
                 if ( r_dcache_rsp_itlb_error ) 
@@ -1587,6 +1573,5 @@
                 }
             }
- 
-            if ( r_icache_inval_tlb_rsp ) // TLB ET write response and invalidation     
+	    else // TLB ET write response and invalidation     
             {   
                 if ( r_dcache_rsp_itlb_error ) 
@@ -2034,5 +2019,5 @@
             m_cost_ins_miss_frz++;
         }
-        if( (( r_icache_fsm_save == ICACHE_TLB1_READ )   || ( r_icache_fsm_save == ICACHE_TLB2_READ )    ||
+        if( (( r_icache_fsm_save == ICACHE_TLB1_READ )   || ( r_icache_fsm_save == ICACHE_TLB2_READ )  ||
              ( r_icache_fsm_save == ICACHE_TLB1_WRITE )  || ( r_icache_fsm_save == ICACHE_TLB2_WRITE ) ||
              ( r_icache_fsm_save == ICACHE_TLB1_UPDT )   || ( r_icache_fsm_save == ICACHE_TLB2_UPDT ))   && (ireq.valid) )
@@ -2044,5 +2029,5 @@
         // invalidate cache
         if( (( r_icache_fsm_save == ICACHE_TLB1_READ ) || ( r_icache_fsm_save == ICACHE_TLB2_READ )  ||
-          ( r_icache_fsm_save == ICACHE_TLB1_WRITE )|| ( r_icache_fsm_save == ICACHE_TLB2_WRITE ) ||
+             ( r_icache_fsm_save == ICACHE_TLB1_WRITE )|| ( r_icache_fsm_save == ICACHE_TLB2_WRITE ) ||
              ( r_icache_fsm_save == ICACHE_TLB1_UPDT ) || ( r_icache_fsm_save == ICACHE_TLB2_UPDT )) && 
             (((r_icache_paddr_save.read() & ~((m_icache_words<<2)-1)) >> (uint32_log2(m_icache_words) + 2) ) == r_dcache_itlb_inval_line.read()) ) 
@@ -2569,5 +2554,4 @@
             else                                                            // MMU activated
             {
-		size_t c_way, c_set;
                 m_cpt_data_tlb_read++;
                 dcache_hit_t  = dcache_tlb.cctranslate(dreq.addr, &tlb_dpaddr, &dcache_pte_info, 
@@ -2579,16 +2563,4 @@
                                 ((dreq.type != iss_t::DATA_LL)  && (dreq.type != iss_t::DATA_SC) &&
                                  (dreq.type != iss_t::XTN_READ) && (dreq.type != iss_t::XTN_WRITE));    
-	       if (dcache_hit_t) {
-	           if (!r_dcache.read(dcache_tlb_nline << (uint32_log2(m_dcache_words) + 2), &dcache_rdata, &c_way, &c_set)) {
-		    std::cout << "dtlb PTE " << std::hex << dcache_tlb_nline << " " << (dcache_tlb_nline << (uint32_log2(m_dcache_words) + 2)) << " not in cache" << std::endl;
-		    abort();
-	          }
-	          if (!r_dcache_in_dtlb[m_dcache_sets*c_way+c_set]) {
-		    std::cout << "dtlb PTE " << std::hex << dcache_tlb_nline <<
-			" " << c_way << "," << c_set << " not in_dtlb" <<
-			std::endl;
-		    abort();
-	          }
-	      }
             }
 
@@ -2704,43 +2676,41 @@
                             else 
                             {
-				if (dreq.type == iss_t::DATA_SC &&
-				    (r_mmu_mode.read() & DATA_TLB_MASK) &&
-				    !dcache_pte_info.d)
+				if ((dreq.type == iss_t::DATA_SC) && !dcache_pte_info.d && (r_mmu_mode.read() & DATA_TLB_MASK))
 				{
-				    /* dirty bit update */
-				    m_cpt_data_tlb_update_dirty++;
-				    m_cost_data_tlb_update_dirty_frz++;
-				    if ( dcache_tlb.getpagesize(dcache_tlb_way, dcache_tlb_set) )	// 2M page size, one level page table 
-				    {
-					r_dcache_pte_update = dcache_tlb.getpte(dcache_tlb_way, dcache_tlb_set) | PTE_D_MASK;
-					r_dcache_tlb_paddr = (paddr_t)r_mmu_ptpr << (INDEX1_NBITS+2) | (paddr_t)((dreq.addr>>PAGE_M_NBITS)<<2);
-					r_dcache_tlb_ll_dirty_req = true;
-					r_dcache_fsm = DCACHE_LL_DIRTY_WAIT;
-				    }
-				    else	// 4k page size, two levels page table 
-				    {   
-					if (dcache_hit_p) 
-					{
-					    r_dcache_pte_update = dcache_tlb.getpte(dcache_tlb_way, dcache_tlb_set) | PTE_D_MASK;
-					    r_dcache_tlb_paddr = (paddr_t)r_dcache_ptba_save | (paddr_t)(((dreq.addr&PTD_ID2_MASK)>>PAGE_K_NBITS) << 3);
-					    r_dcache_tlb_ll_dirty_req = true;
-					    r_dcache_fsm = DCACHE_LL_DIRTY_WAIT;
-					}
-					else    // get PTBA to calculate the physical address of PTE
-					{
-					    r_dcache_pte_update = dcache_tlb.getpte(dcache_tlb_way, dcache_tlb_set) | PTE_D_MASK;
-					    r_dcache_tlb_paddr = (paddr_t)r_mmu_ptpr << (INDEX1_NBITS+2) | (paddr_t)((dreq.addr>>PAGE_M_NBITS)<<2);
-					    r_dcache_tlb_ptba_read = true;
-					    r_dcache_fsm = DCACHE_DTLB1_READ_CACHE;
-					}
-				    }
+			    	    m_cpt_data_tlb_update_dirty++;
+                                    m_cost_data_tlb_update_dirty_frz++;
+				    r_dcache_sc_updt_dirty = true;
+                                    if ( dcache_tlb.getpagesize(dcache_tlb_way, dcache_tlb_set) )	// 2M page size, one level page table 
+                            	    {
+                                        r_dcache_pte_update = dcache_tlb.getpte(dcache_tlb_way, dcache_tlb_set) | PTE_D_MASK;
+                                        r_dcache_tlb_paddr = (paddr_t)r_mmu_ptpr << (INDEX1_NBITS+2) | (paddr_t)((dreq.addr>>PAGE_M_NBITS)<<2);
+                                        r_dcache_tlb_ll_dirty_req = true;
+                                        r_dcache_fsm = DCACHE_LL_DIRTY_WAIT;
+                            	    }
+                                    else	// 4k page size, two levels page table 
+                                    {   
+                                        if (dcache_hit_p) 
+                                        {
+                                            r_dcache_pte_update = dcache_tlb.getpte(dcache_tlb_way, dcache_tlb_set) | PTE_D_MASK;
+                                            r_dcache_tlb_paddr = (paddr_t)r_dcache_ptba_save | (paddr_t)(((dreq.addr&PTD_ID2_MASK)>>PAGE_K_NBITS) << 3);
+                                            r_dcache_tlb_ll_dirty_req = true;
+                                            r_dcache_fsm = DCACHE_LL_DIRTY_WAIT;
+                                        }
+                                        else    // get PTBA to calculate the physical address of PTE
+                                        {
+                                            r_dcache_pte_update = dcache_tlb.getpte(dcache_tlb_way, dcache_tlb_set) | PTE_D_MASK;
+                                            r_dcache_tlb_paddr = (paddr_t)r_mmu_ptpr << (INDEX1_NBITS+2) | (paddr_t)((dreq.addr>>PAGE_M_NBITS)<<2);
+                                            r_dcache_tlb_ptba_read = true;
+                                            r_dcache_fsm = DCACHE_DTLB1_READ_CACHE;
+                                        }
+                                    }				
 				}
 				else
-				{
+				{	
                                     r_dcache_unc_req = true;
                                     r_dcache_fsm = DCACHE_UNC_WAIT;
                                     m_cpt_unc_read++;
-                                    m_cost_unc_read_frz++;
 				}
+                                m_cost_unc_read_frz++;
                             }
                         }
@@ -3022,4 +2992,5 @@
 		if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
 		if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;
+		if (r_dcache_sc_updt_dirty) r_dcache_sc_updt_dirty = false;
             }
 	    else
@@ -3040,4 +3011,5 @@
 		    if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
 		    if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;
+		    if (r_dcache_sc_updt_dirty) r_dcache_sc_updt_dirty = false;
 	        }
         	else if ( r_dcache_inval_tlb_rsp )
@@ -3045,4 +3017,5 @@
         	    r_dcache_inval_tlb_rsp = false;
         	    r_dcache_fsm = DCACHE_IDLE;
+		    if (r_dcache_sc_updt_dirty) r_dcache_sc_updt_dirty = false;
         	}
 		else if ( r_dcache_inval_rsp )
@@ -3050,4 +3023,5 @@
         	    r_dcache_inval_rsp = false;
 		    r_dcache_fsm = DCACHE_IDLE;
+		    if (r_dcache_sc_updt_dirty) r_dcache_sc_updt_dirty = false;
 		}
 		else
@@ -3090,4 +3064,5 @@
 		if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
 		if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;		 	    
+		if (r_dcache_sc_updt_dirty) r_dcache_sc_updt_dirty = false;
 	    }
 	    else 
@@ -3099,10 +3074,12 @@
                     r_dcache_fsm = DCACHE_IDLE;
 		    if (r_dcache_tlb_sc_fail) r_dcache_tlb_sc_fail = false;
+		    if (r_dcache_sc_updt_dirty) r_dcache_sc_updt_dirty = false;
                 }
 		else if ( r_dcache_inval_rsp )
 		{
         	    r_dcache_inval_rsp = false;
+		    r_dcache_fsm = DCACHE_IDLE;
 		    if (r_dcache_tlb_sc_fail) r_dcache_tlb_sc_fail = false;
-		    r_dcache_fsm = DCACHE_IDLE;
+		    if (r_dcache_sc_updt_dirty) r_dcache_sc_updt_dirty = false;
 		}
 		else if ( r_dcache_tlb_sc_fail )
@@ -3115,9 +3092,8 @@
 		else
 		{
-	            /*
-		     * SC succeeded, but has updated the cache and
-		     * invalidated the TLB entry. Redo the translation
-		     */
-		    r_dcache_fsm = DCACHE_IDLE;
+                    bool write_hit = r_dcache.write(r_dcache_tlb_paddr, r_dcache_pte_update);
+		    assert(write_hit && "Write on miss ignores data for data MMU update dirty bit");
+	            r_dcache_fsm = DCACHE_WRITE_DIRTY; 
+		    m_cpt_dcache_data_write++; 
 		}
 	    }
@@ -3147,5 +3123,4 @@
 
         data_t tlb_data = 0;
-	bool write_hit = false;
         bool tlb_hit_cache = r_dcache.read(r_dcache_tlb_paddr, &tlb_data);
 
@@ -3177,7 +3152,9 @@
                 {
                     r_dcache_tlb_ptba_read = false;
+                    //write_hit = r_dcache.write(((paddr_t)(tlb_data & ((1<<(m_paddr_nbits - PAGE_K_NBITS))-1)) << PAGE_K_NBITS | (paddr_t)(((dreq.addr & PTD_ID2_MASK) >> PAGE_K_NBITS) << 3)), r_dcache_pte_update);
+                    //assert(write_hit && "Write on miss ignores data");
                     r_dcache_tlb_ll_dirty_req = true;
                     r_dcache_fsm = DCACHE_LL_DIRTY_WAIT;
-		    m_cpt_dcache_data_write++; 
+		    //m_cpt_dcache_data_write++; 
                     m_cost_data_tlb_update_dirty_frz++;
                 }
@@ -3202,6 +3179,8 @@
                         r_dcache_pte_update = tlb_data | PTE_L_MASK;
                         r_dcache_tlb_ll_acc_req = true;
+                	//write_hit = r_dcache.write(r_dcache_tlb_paddr,(tlb_data | PTE_L_MASK));  
+                	//assert(write_hit && "Write on miss ignores data");  
                         r_dcache_fsm = DCACHE_TLB1_LL_WAIT;
-			m_cpt_dcache_data_write++; 
+			//m_cpt_dcache_data_write++; 
                         m_cpt_data_tlb_update_acc++;
                         m_cost_data_tlb_update_acc_frz++;
@@ -3219,6 +3198,8 @@
                         r_dcache_pte_update = tlb_data | PTE_R_MASK;
                         r_dcache_tlb_ll_acc_req = true;
+                	//write_hit = r_dcache.write(r_dcache_tlb_paddr,(tlb_data | PTE_R_MASK));  
+                	//assert(write_hit && "Write on miss ignores data");  
                         r_dcache_fsm = DCACHE_TLB1_LL_WAIT;
-			m_cpt_dcache_data_write++; 
+			//m_cpt_dcache_data_write++; 
                         m_cpt_data_tlb_update_acc++;
                         m_cost_data_tlb_update_acc_frz++;
@@ -3359,5 +3340,8 @@
 	    	else 
 	    	{
+		    bool write_hit = r_dcache.write(r_dcache_tlb_paddr,r_dcache_pte_update);  
+                    assert(write_hit && "Write on miss ignores data for data MMU update data access bit"); 
 	    	    r_dcache_fsm = DCACHE_TLB1_UPDT; 
+		    m_cpt_dcache_data_write++;
 	    	}
 	    }
@@ -3447,5 +3431,5 @@
             data_t   rsp_dtlb_miss = 0;
             paddr_t  victim_index = 0;
-	    bool write_hit = false;
+	    //bool write_hit = false;
             size_t way = 0;
             size_t set = 0;
@@ -3512,7 +3496,9 @@
                 {
                     r_dcache_tlb_ptba_read = false;
+                    //write_hit = r_dcache.write(((paddr_t)(rsp_dtlb_miss & ((1<<(m_paddr_nbits - PAGE_K_NBITS))-1)) << PAGE_K_NBITS | (paddr_t)(((dreq.addr & PTD_ID2_MASK) >> PAGE_K_NBITS) << 3)),r_dcache_pte_update);
+                    //assert(write_hit && "Write on miss ignores data");
                     r_dcache_tlb_ll_dirty_req = true;
                     r_dcache_fsm = DCACHE_LL_DIRTY_WAIT;
-		    m_cpt_dcache_data_write++; 
+		    //m_cpt_dcache_data_write++; 
                     m_cpt_data_tlb_update_dirty++;
                     m_cost_data_tlb_update_dirty_frz++;
@@ -3537,6 +3523,8 @@
                         r_dcache_pte_update = rsp_dtlb_miss | PTE_L_MASK;
                         r_dcache_tlb_ll_acc_req = true;
+                	//write_hit = r_dcache.write(r_dcache_tlb_paddr,(rsp_dtlb_miss | PTE_L_MASK));  
+                	//assert(write_hit && "Write on miss ignores data");  
                         r_dcache_fsm        = DCACHE_TLB1_LL_WAIT;
-			m_cpt_dcache_data_write++; 
+			//m_cpt_dcache_data_write++; 
 			m_cpt_data_tlb_update_acc++;
                         m_cost_data_tlb_update_acc_frz++;
@@ -3554,6 +3542,8 @@
                         r_dcache_pte_update = rsp_dtlb_miss | PTE_R_MASK;
                         r_dcache_tlb_ll_acc_req = true;
+                	//write_hit = r_dcache.write(r_dcache_tlb_paddr,(rsp_dtlb_miss | PTE_R_MASK));  
+                	//assert(write_hit && "Write on miss ignores data");  
                         r_dcache_fsm        = DCACHE_TLB1_LL_WAIT;
-			m_cpt_dcache_data_write++; 
+			//m_cpt_dcache_data_write++; 
 			m_cpt_data_tlb_update_acc++;
                         m_cost_data_tlb_update_acc_frz++;
@@ -3582,5 +3572,5 @@
             if (dcache_tlb.update(r_dcache_pte_update,dreq.addr,(r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words)+2)),&victim_index))
             {
-                r_dcache.setinbit((paddr_t)victim_index << (uint32_log2(m_dcache_words) + 2), r_dcache_in_dtlb, false);
+                r_dcache.setinbit((paddr_t)victim_index << (uint32_log2(m_dcache_words)+2), r_dcache_in_dtlb, false);
             }
             r_dcache.setinbit(r_dcache_tlb_paddr, r_dcache_in_dtlb, true);
@@ -3618,5 +3608,5 @@
         data_t tlb_data = 0;
         data_t tlb_data_ppn = 0;
-	bool write_hit = false;
+	//bool write_hit = false;
         bool tlb_hit_cache = r_dcache.read(r_dcache_tlb_paddr, &tlb_data);
 
@@ -3665,6 +3655,8 @@
 	        	r_dcache_ppn_update = tlb_data_ppn;
                         r_dcache_tlb_ll_acc_req = true;
+                	//write_hit = r_dcache.write(r_dcache_tlb_paddr,(tlb_data | PTE_L_MASK));  
+                	//assert(write_hit && "Write on miss ignores data");  
                         r_dcache_fsm = DCACHE_TLB2_LL_WAIT;
-			m_cpt_dcache_data_write++; 
+			//m_cpt_dcache_data_write++; 
                         m_cpt_data_tlb_update_acc++;
                         m_cost_data_tlb_update_acc_frz++;
@@ -3684,6 +3676,8 @@
 	        	r_dcache_ppn_update = tlb_data_ppn;
                         r_dcache_tlb_ll_acc_req = true;
+                	//write_hit = r_dcache.write(r_dcache_tlb_paddr,(tlb_data | PTE_R_MASK));  
+                	//assert(write_hit && "Write on miss ignores data");  
                         r_dcache_fsm = DCACHE_TLB2_LL_WAIT;
-			m_cpt_dcache_data_write++; 
+			//m_cpt_dcache_data_write++; 
                         m_cpt_data_tlb_update_acc++;
                         m_cost_data_tlb_update_acc_frz++;
@@ -3825,5 +3819,8 @@
 	        else 
 	        {
+		    bool write_hit = r_dcache.write(r_dcache_tlb_paddr,r_dcache_pte_update);  
+                    assert(write_hit && "Write on miss ignores data for data MMU update data access bit"); 
 	            r_dcache_fsm = DCACHE_TLB2_UPDT; 
+		    m_cpt_dcache_data_write++;
 	        }
 	    }
@@ -3913,5 +3910,5 @@
             data_t rsp_dtlb_miss;
             data_t tlb_data_ppn;
-	    bool write_hit = false;
+	    //bool write_hit = false;
             paddr_t  victim_index = 0;
             size_t way = 0;
@@ -3992,6 +3989,8 @@
 	        	r_dcache_ppn_update = tlb_data_ppn;
                         r_dcache_tlb_ll_acc_req = true;
+                	//write_hit = r_dcache.write(r_dcache_tlb_paddr,(rsp_dtlb_miss | PTE_L_MASK));  
+                	//assert(write_hit && "Write on miss ignores data");  
                         r_dcache_fsm = DCACHE_TLB2_LL_WAIT;
-			m_cpt_dcache_data_write++; 
+			//m_cpt_dcache_data_write++; 
                         m_cpt_data_tlb_update_acc++;
                         m_cost_data_tlb_update_acc_frz++;
@@ -4011,6 +4010,8 @@
 	        	r_dcache_ppn_update = tlb_data_ppn;
                         r_dcache_tlb_ll_acc_req = true;
+                	//write_hit = r_dcache.write(r_dcache_tlb_paddr,(rsp_dtlb_miss | PTE_R_MASK));  
+                	//assert(write_hit && "Write on miss ignores data");  
                         r_dcache_fsm = DCACHE_TLB2_LL_WAIT;
-			m_cpt_dcache_data_write++; 
+			//m_cpt_dcache_data_write++; 
                         m_cpt_data_tlb_update_acc++;
                         m_cost_data_tlb_update_acc_frz++;
@@ -4039,5 +4040,5 @@
             if (dcache_tlb.update(r_dcache_pte_update,r_dcache_ppn_update,dreq.addr,(r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words)+2)),&victim_index))
             {
-                r_dcache.setinbit((paddr_t)victim_index << (uint32_log2(m_dcache_words) + 2), r_dcache_in_dtlb, false);
+                r_dcache.setinbit((paddr_t)victim_index << (uint32_log2(m_dcache_words)+2), r_dcache_in_dtlb, false);
             }
             r_dcache.setinbit(r_dcache_tlb_paddr, r_dcache_in_dtlb, true);
@@ -4062,5 +4063,5 @@
         if ( r_dcache_itlb_cleanup_req )
         {    
-            r_dcache.setinbit(((paddr_t)r_dcache_itlb_cleanup_line.read() << (uint32_log2(m_dcache_words) + 2)), r_dcache_in_itlb, false);
+            r_dcache.setinbit(((paddr_t)r_dcache_itlb_cleanup_line.read() << (uint32_log2(m_dcache_words)+2)), r_dcache_in_itlb, false);
             r_dcache_itlb_cleanup_req = false;
 	}
@@ -4072,9 +4073,5 @@
                 if(dcache_tlb.checkcleanup(way, set, &victim_index))
                 {
-		    /*
-		     * this is correct because checkcleanup returns true only
-		     * if none of the PTE entries of the line is global.
-		     */
-                    r_dcache.setinbit((paddr_t)victim_index << (uint32_log2(m_dcache_words) + 2), r_dcache_in_dtlb, false); 
+                    r_dcache.setinbit((paddr_t)(victim_index << (uint32_log2(m_dcache_words)+2)), r_dcache_in_dtlb, false); 
                 }
             }
@@ -4173,5 +4170,5 @@
         if ( dcache_tlb.inval(r_dcache_wdata_save, &victim_index) )
         {  
-            r_dcache.setinbit((paddr_t)(victim_index << (uint32_log2(m_dcache_words) + 2)), r_dcache_in_dtlb, false); 
+            r_dcache.setinbit((paddr_t)(victim_index << (uint32_log2(m_dcache_words)+2)), r_dcache_in_dtlb, false); 
         }
         r_dtlb_translation_valid = false;
@@ -4409,7 +4406,10 @@
                 r_dcache_cleanup_line = victim_index;
 		m_cpt_cc_cleanup_data++;
-		r_dcache_fsm = DCACHE_TLB_CC_INVAL;
-                r_dcache_fsm_save = r_dcache_fsm;
-		break;
+		if ( r_dcache_in_itlb[m_dcache_sets*way+set] || r_dcache_in_dtlb[m_dcache_sets*way+set] )
+		{
+		    r_dcache_fsm = DCACHE_TLB_CC_INVAL;
+                    r_dcache_fsm_save = r_dcache_fsm;
+		    break;
+		}
 	    }
 	    m_cpt_dcache_dir_write++;
@@ -4523,4 +4523,49 @@
         break;
     }
+    ////////////////////////
+    case DCACHE_WRITE_DIRTY:
+    {
+	m_cost_data_tlb_update_dirty_frz++;
+
+        // external cache invalidate request
+        if ( r_tgt_dcache_req ) 
+        {
+            r_dcache_fsm = DCACHE_CC_CHECK;
+            r_dcache_fsm_save = r_dcache_fsm;
+            break;
+        }
+
+        if ( r_dcache_inval_tlb_rsp ) // Miss read response and tlb invalidation
+        {
+            r_dcache_fsm = DCACHE_IDLE;
+	    if ( r_dcache_sc_updt_dirty ) r_dcache_sc_updt_dirty = false;
+            r_dcache_inval_tlb_rsp = false;
+	    break;
+        }
+
+	if ( r_dcache_inval_rsp ) // TLB miss response and cache invalidation
+	{
+            r_dcache_fsm = DCACHE_IDLE; 
+	    if ( r_dcache_sc_updt_dirty ) r_dcache_sc_updt_dirty = false;
+            r_dcache_inval_rsp = false;
+	    break;	    
+	}
+
+        dcache_tlb.setdirty(r_dcache_tlb_way_save, r_dcache_tlb_set_save);
+	if (  r_dcache_sc_updt_dirty )
+	{
+	    r_dcache_sc_updt_dirty = false;
+            r_dcache_unc_req = true;
+            r_dcache_fsm = DCACHE_UNC_WAIT;
+            m_cpt_unc_read++;
+	}
+	else
+	{
+            r_dcache_fsm = DCACHE_WRITE_REQ;
+            drsp.valid = true;
+            drsp.rdata = 0;	
+	}	
+        break;
+    }
     /////////////////
     case DCACHE_ERROR:
@@ -4623,7 +4668,10 @@
                 r_dcache_cleanup_line = victim_index;
 		m_cpt_cc_cleanup_data++;
-		r_dcache_fsm = DCACHE_TLB_CC_INVAL;
-                r_dcache_fsm_save = r_dcache_fsm;
-		break;
+		if ( r_dcache_in_itlb[m_dcache_sets*way+set] || r_dcache_in_dtlb[m_dcache_sets*way+set] )
+		{
+		    r_dcache_fsm = DCACHE_TLB_CC_INVAL;
+                    r_dcache_fsm_save = r_dcache_fsm;
+		    break;
+		}
 	    }
 
@@ -4733,4 +4781,6 @@
 	        else 
 	        {
+		    bool write_hit = r_dcache.write(r_icache_paddr_save, r_icache_pte_update);
+                    assert(write_hit && "Write on miss ignores data for data MMU update ins access bit");
 	            r_itlb_acc_dcache_req = false;
 	            r_dcache_fsm = DCACHE_IDLE; 
@@ -4761,5 +4811,5 @@
         }
 
-	// DCACHE_TLB1_LL_WAIT  DCACHE_TLB1_SC_WAIT  DCACHE_LL_DIRTY_WAIT  DCACHE_ITLB_LL_WAIT  DCACHE_ITLB_SC_WAIT
+	// DCACHE_TLB1_LL_WAIT  DCACHE_TLB1_SC_WAIT  DCACHE_LL_DIRTY_WAIT  DCACHE_WRITE_DIRTY DCACHE_ITLB_LL_WAIT  DCACHE_ITLB_SC_WAIT
 	// DCACHE_TLB2_LL_WAIT  DCACHE_TLB2_SC_WAIT  DCACHE_SC_DIRTY_WAIT
         if((( /*( r_dcache_fsm_save == DCACHE_UNC_WAIT ) ||*/
@@ -4767,8 +4817,10 @@
            ( (r_dcache_paddr_save.read() & ~((m_dcache_words<<2)-1)) == (r_tgt_addr.read() & ~((m_dcache_words<<2)-1)))) 
         || (( ( r_dcache_fsm_save == DCACHE_TLB1_READ )      || ( r_dcache_fsm_save == DCACHE_TLB2_READ )      ||
-	     ( r_dcache_fsm_save == DCACHE_TLB1_READ_UPDT ) || ( r_dcache_fsm_save == DCACHE_TLB2_READ_UPDT) /* ||
+	     ( r_dcache_fsm_save == DCACHE_TLB1_READ_UPDT ) || ( r_dcache_fsm_save == DCACHE_TLB2_READ_UPDT ) ||
+             ( r_dcache_fsm_save == DCACHE_TLB1_UPDT )      || ( r_dcache_fsm_save == DCACHE_TLB2_UPDT )	 /* ||
 	     ( r_dcache_fsm_save == DCACHE_TLB1_LL_WAIT )   || ( r_dcache_fsm_save == DCACHE_TLB2_LL_WAIT )   ||
 	     ( r_dcache_fsm_save == DCACHE_TLB1_SC_WAIT )   || ( r_dcache_fsm_save == DCACHE_TLB2_SC_WAIT )   ||
-	     ( r_dcache_fsm_save == DCACHE_LL_DIRTY_WAIT )  || ( r_dcache_fsm_save == DCACHE_SC_DIRTY_WAIT )  */ ) && 
+	     ( r_dcache_fsm_save == DCACHE_LL_DIRTY_WAIT )  || ( r_dcache_fsm_save == DCACHE_SC_DIRTY_WAIT )  ||
+	     ( r_dcache_fsm_save == DCACHE_WRITE_DIRTY )*/ ) && 
            ( (r_dcache_tlb_paddr.read() & ~((m_dcache_words<<2)-1)) == (r_tgt_addr.read() & ~((m_dcache_words<<2)-1))) ) 
         || (( ( r_dcache_fsm_save == DCACHE_ITLB_READ ) || ( r_dcache_fsm_save == DCACHE_ITLB_UPDT ) /*||
@@ -4776,10 +4828,4 @@
            ( (r_icache_paddr_save.read() & ~((m_dcache_words<<2)-1)) == (r_tgt_addr.read() & ~((m_dcache_words<<2)-1))) ) ) 
         {
-	    data_t dcache_rdata = 0;
-	    size_t way = 0;
-	    size_t set = 0;
-	    bool dcache_hit = r_dcache.read(r_tgt_addr.read(), &dcache_rdata, &way, &set);
-	    assert(!dcache_hit && "ignored update req should not be in dcache");
-
             r_dcache_inval_rsp = true;
             r_tgt_dcache_req = false;
@@ -4804,9 +4850,4 @@
             if ( dcache_hit )
             {
-		if (((r_dcache_tlb_paddr.read() & ~((m_dcache_words<<2)-1)) ==
-		     (r_tgt_addr.read() & ~((m_dcache_words<<2)-1))) &&
-		    (r_dcache_fsm_save == DCACHE_TLB1_UPDT ||
-		     r_dcache_fsm_save == DCACHE_TLB2_UPDT))
-			r_dcache_inval_rsp = true;
                 if ( r_dcache_in_dtlb[m_dcache_sets*way+set] || r_dcache_in_itlb[m_dcache_sets*way+set] )
                 {
@@ -4953,5 +4994,6 @@
              ( r_dcache_fsm_save == DCACHE_TLB1_UPDT )        || ( r_dcache_fsm_save == DCACHE_TLB2_UPDT )        ||
              ( r_dcache_fsm_save == DCACHE_DTLB1_READ_CACHE ) || ( r_dcache_fsm_save == DCACHE_DTLB2_READ_CACHE ) ||
-             ( r_dcache_fsm_save == DCACHE_LL_DIRTY_WAIT )    || ( r_dcache_fsm_save == DCACHE_SC_DIRTY_WAIT ) ) && 
+             ( r_dcache_fsm_save == DCACHE_LL_DIRTY_WAIT )    || ( r_dcache_fsm_save == DCACHE_SC_DIRTY_WAIT )    ||
+	     ( r_dcache_fsm_save == DCACHE_WRITE_DIRTY )) && 
             (((r_dcache_tlb_paddr.read() & ~((m_dcache_words<<2)-1)) >> (uint32_log2(m_dcache_words) + 2)) == r_dcache_dtlb_inval_line.read()) ) 
         {
@@ -4984,5 +5026,5 @@
         if ( dreq.valid ) m_cost_data_miss_frz++;
 
-        r_dcache.setinbit((paddr_t)r_dcache_itlb_cleanup_line.read() << (uint32_log2(m_dcache_words) + 2), r_dcache_in_itlb, false);
+        r_dcache.setinbit(((paddr_t)r_dcache_itlb_cleanup_line.read()<<(uint32_log2(m_dcache_words)+2)), r_dcache_in_itlb, false);
         r_dcache_itlb_cleanup_req = false;
         r_dcache_fsm = DCACHE_IDLE;
