Index: trunk/lib/generic_cache_tsar/include/generic_cache.h
===================================================================
--- trunk/lib/generic_cache_tsar/include/generic_cache.h	(revision 303)
+++ trunk/lib/generic_cache_tsar/include/generic_cache.h	(revision 337)
@@ -399,4 +399,62 @@
     }
 
+    ////////////////////////////////////////////////////////////////////
+    // Read one or two 32 bits word.
+    // Both data and directory are accessed.
+    // returns the access status in the state argument:
+    // - VALID : (matching tag) and (state == VALID) 
+    // - ZOMBI : (matching tag) and (state == ZOMBI) 
+    // - MISS  : no matching tag or EMPTY state
+    // If VALID or ZOMBI, the data, the way, set and word index are 
+    // returned in the other arguments.
+    ////////////////////////////////////////////////////////////////////
+    inline void read( addr_t    ad,
+                      data_t*   dt,
+                      data_t*   dt_next,
+                      size_t*   selway,
+                      size_t*   selset,
+                      size_t*   selword,
+                      int*      state ) 
+    {
+        const tag_t       tag  = m_z[ad];
+        const size_t      set  = m_y[ad];
+        const size_t      word = m_x[ad];
+
+        // default return values 
+        *state   = CACHE_SLOT_STATE_EMPTY;
+        *selway  = 0;
+        *selset  = 0;
+        *selword = 0;
+        *dt      = 0;
+
+        for ( size_t way = 0; way < m_ways; way++ ) 
+        {
+            if ( tag == cache_tag(way, set) )  // matching tag
+            {
+
+                if ( cache_state(way, set) == CACHE_SLOT_STATE_VALID )
+                {
+                    *state   = CACHE_SLOT_STATE_VALID;
+                    *selway  = way;
+                    *selset  = set;
+                    *selword = word;
+                    *dt      = cache_data(way, set, word);
+                    if ( word+1 < m_words) 
+                    {
+                        *dt_next = cache_data(way, set, word+1);
+                    }
+                    cache_set_lru(way, set);
+                }
+                else if ( cache_state(way, set) == CACHE_SLOT_STATE_ZOMBI )
+                {
+                    *state   = CACHE_SLOT_STATE_ZOMBI;
+                    *selway  = way;
+                    *selset  = set;
+                    *selword = word;
+                }
+            }
+        }
+    }
+
     ///////////////////////////////////////////////////////////////////////////////
     // Checks the cache state for a given address.
