Index: trunk/platforms/almos-tsarv3-platforms/README
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/README	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/README	(revision 259)
@@ -0,0 +1,24 @@
+======================================================================
+=                      Note about this package                       =
+=                         (27 august 2012)                           =
+======================================================================
+
+Information
+============
+This directory contains the hardware description of two TSAR platforms
+(mono and multi clusters) used by the distribution (almos-tsar-mipsel) 
+of ALMOS (Advanced Locality Management Operating System) found on 
+the project website: www.almos.fr.
+
+
+Important
+============
+The platform descriptions and their related components found in this
+directory match a specific, intermediate and no more maintaned version 
+of TSAR. This deprecated version is code-named "v3" and it has been 
+dropped in favor of an enhanced and actively maintainted version, 
+code-named "v4". You are encouraged to update these TSAR platform 
+descriptions to refer to the last version ("v4") of TSAR.
+
+======================================================================
+======================================================================
Index: trunk/platforms/almos-tsarv3-platforms/common/generic_cache/include/generic_cache.h
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/generic_cache/include/generic_cache.h	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/generic_cache/include/generic_cache.h	(revision 259)
@@ -0,0 +1,721 @@
+/* -*- c++ -*-
+ *
+ * SOCLIB_LGPL_HEADER_BEGIN
+ *
+ * This file is part of SoCLib, GNU LGPLv2.1.
+ *
+ * SoCLib is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 of the License.
+ *
+ * SoCLib is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with SoCLib; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * SOCLIB_LGPL_HEADER_END
+ *
+ * Copyright (c) UPMC, Lip6
+ *         Alain Greiner <alain.greiner@lip6.fr> July 2008
+ *
+ * Maintainers: alain yang
+ */
+
+//////////////////////////////////////////////////////////////////////////////////
+// This object is a generic, set associative, cache providing read(), write(),
+// inval() and update() access primitives. The replacement policy is pseudo-LRU.
+// The DATA part is implemented as an int32_t array.
+// The DIRECTORY part is implemented as an uint32_t array.
+//
+// Constructor parameters are :
+// - std::string    &name
+// - size_t         nways   : number of associativity levels 
+// - size_t         nsets   : number of sets
+// - size_t         nwords  : number of words in a cache line
+// The nways, nsets, nwords parameters must be power of 2
+// The nsets parameter cannot be larger than 1024
+// The nways parameter cannot be larger than 16
+// The nwords parameter cannot be larger than 64
+//
+// Template parameter is :
+// - addr_t : address format to access the cache 
+// The address can be larger than 32 bits, but the TAG field 
+// cannot be larger than 32 bits.
+/////////////////////////////////////////////////////////////////////////////////
+// History :
+// 05/01/2010
+// Two new methods select_before_update(), and update_after_select() have
+// been introduced to support update in two cycles, when the cache directory
+// is implemented as a simple port RAM.
+/////////////////////////////////////////////////////////////////////////////////
+
+#ifndef SOCLIB_GENERIC_CACHE_H
+#define SOCLIB_GENERIC_CACHE_H
+
+#include <systemc>
+#include <cassert>
+#include "arithmetics.h"
+#include "static_assert.h"
+#include "mapping_table.h"
+#include <cstring>
+
+namespace soclib { 
+
+//////////////////////////
+template<typename addr_t>
+class GenericCache 
+//////////////////////////
+{
+    typedef uint32_t    data_t;
+    typedef uint32_t    tag_t;
+
+    data_t              *r_data ;
+    tag_t               *r_tag ;
+    bool                *r_val ;
+    bool                *r_lru ;
+
+    size_t              m_ways;	
+    size_t              m_sets;	
+    size_t              m_words;
+    size_t              m_next_way;
+
+    const soclib::common::AddressMaskingTable<addr_t>  m_x ;
+    const soclib::common::AddressMaskingTable<addr_t>  m_y ;
+    const soclib::common::AddressMaskingTable<addr_t>  m_z ;
+
+    //////////////////////////////////////////////////////////////
+    inline data_t &cache_data(size_t way, size_t set, size_t word)
+    {
+        return r_data[(way*m_sets*m_words)+(set*m_words)+word];
+    }
+
+    //////////////////////////////////////////////
+    inline tag_t &cache_tag(size_t way, size_t set)
+    {
+        return r_tag[(way*m_sets)+set];
+    }
+
+    //////////////////////////////////////////////
+    inline bool &cache_val(size_t way, size_t set)
+    {
+        return r_val[(way*m_sets)+set];
+    }
+
+    //////////////////////////////////////////////
+    inline bool &cache_lru(size_t way, size_t set)
+    {
+        return r_lru[(way*m_sets)+set];
+    }
+
+    //////////////////////////////////////////////
+    inline void cache_set_lru(size_t way, size_t set)
+    {
+	size_t way2;
+
+        cache_lru(way, set) = true;
+	for (way2 = 0; way2 < m_ways; way2++ ) {
+	    if (cache_lru(way2, set) == false) return;
+	}
+	/* all lines are new -> they all become old */
+	for (way2 = 0; way2 < m_ways; way2++ ) {
+	    cache_lru(way2, set) = false;
+	}
+    }
+
+public:
+
+    //////////////////////////////////////////////
+    GenericCache(   const std::string   &name,
+                    size_t              nways, 
+                    size_t              nsets, 
+                    size_t              nwords)
+        : m_ways(nways),
+          m_sets(nsets),
+          m_words(nwords),
+
+#define l2 soclib::common::uint32_log2
+
+          m_x( l2(nwords), l2(sizeof(data_t))),
+          m_y( l2(nsets), l2(nwords) + l2(sizeof(data_t))),
+          m_z( 8*sizeof(addr_t) - l2(nsets) - l2(nwords) - l2(sizeof(data_t)),
+               l2(nsets) + l2(nwords) + l2(sizeof(data_t)))
+
+#undef l2
+    {
+        assert(IS_POW_OF_2(nways));
+        assert(IS_POW_OF_2(nsets));
+        assert(IS_POW_OF_2(nwords));
+        assert(nwords);
+        assert(nsets);
+        assert(nways);
+        assert(nwords <= 64);
+        assert(nsets <= 1024);
+        assert(nways <= 16);
+
+#ifdef GENERIC_CACHE_DEBUG
+        std::cout
+            << " m_x: " << m_x
+            << " m_y: " << m_y
+            << " m_z: " << m_z
+            << std::endl;
+#endif
+
+        r_data = new data_t[nways*nsets*nwords];
+        r_tag  = new tag_t[nways*nsets];
+        r_val  = new bool[nways*nsets];
+        r_lru  = new bool[nways*nsets];
+        m_next_way = 0;
+    }
+
+    ////////////////
+    ~GenericCache()
+    {
+        delete [] r_data;
+        delete [] r_tag;
+        delete [] r_val;
+        delete [] r_lru;
+    }
+
+    ////////////////////
+    inline void reset( )
+    {
+        std::memset(r_data, 0, sizeof(*r_data)*m_ways*m_sets*m_words);
+        std::memset(r_tag, 0, sizeof(*r_tag)*m_ways*m_sets);
+        std::memset(r_val, 0, sizeof(*r_val)*m_ways*m_sets);
+        std::memset(r_lru, 0, sizeof(*r_lru)*m_ways*m_sets);
+    }
+
+    ////////////////////////////////////////////////////////
+    inline bool flush(size_t way, size_t set, addr_t* nline)
+    {
+        if ( cache_val(way,set) ) 
+        {
+            cache_val(way,set) = false;
+            *nline = (data_t)cache_tag(way,set)* m_sets + set;
+            return true;
+        }
+        return false;
+    }
+
+    /////////////////////////////////////////
+    inline bool read( addr_t ad, data_t* dt)
+    {
+        const tag_t       tag  = m_z[ad];
+        const size_t      set  = m_y[ad];
+        const size_t      word = m_x[ad];
+
+#ifdef GENERIC_CACHE_DEBUG
+        std::cout << "Reading data at " << ad << ", "
+                  << " s/t=" << set << '/' << tag
+                  << ", ";
+#endif
+
+        for ( size_t way = 0; way < m_ways; way++ ) {
+            if ( (tag == cache_tag(way, set)) && cache_val(way, set) ) {
+                *dt = cache_data(way, set, word);
+                cache_set_lru(way, set);
+
+#ifdef GENERIC_CACHE_DEBUG
+                std::cout << "hit"
+                          << " w/s/t=" << way << '/' << set << '/' << tag
+                          << " = " << *dt << std::endl;
+#endif
+                return true;
+            }
+        }
+
+#ifdef GENERIC_CACHE_DEBUG
+        std::cout << "miss" << std::endl;
+#endif
+        return false;
+    }
+
+    /////////////////////////////////////////////////////////////////////
+    inline bool read( addr_t ad, data_t* dt, size_t* n_way, size_t* n_set)
+    {
+        const tag_t       tag  = m_z[ad];
+        const size_t      set  = m_y[ad];
+        const size_t      word = m_x[ad];
+
+#ifdef GENERIC_CACHE_DEBUG
+        std::cout << "Reading data at " << ad << ", "
+                  << " s/t=" << set << '/' << tag
+                  << ", ";
+#endif
+
+        for ( size_t way = 0; way < m_ways; way++ ) {
+            if ( (tag == cache_tag(way, set)) && cache_val(way, set) ) {
+                *dt = cache_data(way, set, word);
+                cache_set_lru(way, set);
+                *n_way = way;
+                *n_set = set;
+
+#ifdef GENERIC_CACHE_DEBUG
+                std::cout << "hit"
+                          << " w/s/t=" << way << '/' << set << '/' << tag
+                          << " = " << *dt << std::endl;
+#endif
+                return true;
+            }
+        }
+#ifdef GENERIC_CACHE_DEBUG
+        std::cout << "miss" << std::endl;
+#endif
+        return false;
+    }
+
+    //////////////////////////////////////////////////////
+    inline bool setinbit( addr_t ad, bool* buf, bool val )
+    {
+        const tag_t       tag  = m_z[ad];
+        const size_t      set  = m_y[ad];
+
+        for ( size_t way = 0; way < m_ways; way++ ) {
+            if ( (tag == cache_tag(way, set)) && cache_val(way, set) ) {
+                buf[m_sets*way+set] = val;
+
+#ifdef GENERIC_CACHE_DEBUG
+                std::cout << "hit"
+                          << " w/s=" << way << '/' << set 
+                          << std::endl;
+#endif
+                return true;
+            }
+        }
+#ifdef GENERIC_CACHE_DEBUG
+        std::cout << "miss" << std::endl;
+#endif
+        return false;
+    }
+
+    ////////////////////////////////////////////
+    inline tag_t get_tag(size_t way, size_t set)
+    {
+        return cache_tag(way, set);
+    }
+
+    /////////////////////////////////////////
+    inline bool write( addr_t ad, data_t dt )
+    {
+        const tag_t       tag  = m_z[ad];
+        const size_t      set  = m_y[ad];
+        const size_t      word = m_x[ad];
+
+#ifdef GENERIC_CACHE_DEBUG
+        std::cout << "Writing data at " << ad << ", "
+                  << " s/t=" << set << '/' << tag
+                  << ", ";
+#endif
+
+        for ( size_t way = 0; way < m_ways; way++ ) {
+            if ( (tag == cache_tag(way, set)) && cache_val(way, set) ) {
+                cache_data(way, set, word) = dt;
+                cache_set_lru(way, set);
+
+#ifdef GENERIC_CACHE_DEBUG
+                std::cout << "hit"
+                          << " w/s/t=" << way << '/' << set << '/' << tag
+                          << std::endl;
+#endif
+                return true;
+            }
+        }
+
+#ifdef GENERIC_CACHE_DEBUG
+        std::cout << "miss" << std::endl;
+#endif
+        return false;
+    }
+
+    /////////////////////////////////////////////////////////////////////
+    inline bool write( addr_t ad, data_t dt, size_t* nway, size_t* nset )
+    {
+        const tag_t       tag  = m_z[ad];
+        const size_t      set  = m_y[ad];
+        const size_t      word = m_x[ad];
+
+#ifdef GENERIC_CACHE_DEBUG
+        std::cout << "Writing data at " << ad << ", "
+                  << " s/t=" << set << '/' << tag
+                  << ", ";
+#endif
+
+        for ( size_t way = 0; way < m_ways; way++ ) {
+            if ( (tag == cache_tag(way, set)) && cache_val(way, set) ) {
+                cache_data(way, set, word) = dt;
+                cache_set_lru(way, set);
+                *nway = way;
+                *nset = set;
+
+#ifdef GENERIC_CACHE_DEBUG
+                std::cout << "hit"
+                          << " w/s/t=" << way << '/' << set << '/' << tag
+                          << std::endl;
+#endif
+                return true;
+            }
+        }
+
+#ifdef GENERIC_CACHE_DEBUG
+        std::cout << "miss" << std::endl;
+#endif
+        return false;
+    }
+
+    inline void write(size_t way, size_t set, size_t word, data_t data)
+    {
+        cache_data(way, set, word) = data;
+    }
+
+    //////////////////////////////
+    inline bool inval( addr_t ad )
+    {
+        bool        hit = false;
+        const tag_t       tag = m_z[ad];
+        const size_t      set = m_y[ad];
+
+#ifdef GENERIC_CACHE_DEBUG
+        std::cout << "Invalidating data at " << ad << ", "
+                  << " s/t=" << set << '/' << tag
+                  << ", ";
+#endif
+
+        for ( size_t way = 0 ; way < m_ways && !hit ; way++ ) {
+            if ( (tag == cache_tag(way, set)) && cache_val(way, set) ) {
+                hit     = true;
+                cache_val(way, set) = false;
+                cache_lru(way, set) = false;
+
+#ifdef GENERIC_CACHE_DEBUG
+                std::cout << "hit"
+                          << " w/s/t=" << way << '/' << set << '/' << tag
+                          << " ";
+#endif
+            }
+        }
+
+#ifdef GENERIC_CACHE_DEBUG
+        std::cout << std::endl;
+#endif
+        return hit;
+    }
+
+    ////////////////////////////////////////////////////////////
+    inline bool inval( addr_t ad, size_t* n_way, size_t* n_set )
+    {
+        bool    hit = false;
+        const tag_t       tag = m_z[ad];
+        const size_t      set = m_y[ad];
+
+#ifdef GENERIC_CACHE_DEBUG
+        std::cout << "Invalidating data at " << ad << ", "
+                  << " s/t=" << set << '/' << tag
+                  << ", ";
+#endif
+
+        for ( size_t way = 0 ; way < m_ways && !hit ; way++ ) {
+            if ( (tag == cache_tag(way, set)) && cache_val(way, set) ) {
+                hit     = true;
+                cache_val(way, set) = false;
+                cache_lru(way, set) = false;
+                *n_way = way;
+                *n_set = set;
+
+#ifdef GENERIC_CACHE_DEBUG
+                std::cout << "hit"
+                          << " w/s/t=" << way << '/' << set << '/' << tag
+                          << " ";
+#endif
+            }
+        }
+
+#ifdef GENERIC_CACHE_DEBUG
+        std::cout << std::endl;
+#endif
+        return hit;
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    // This function implements a pseudo LRU policy for a one cycle
+    // line replacement. It can be used if the directory is implemented
+    // as a dual port RAM.
+    // 1 - First we search an invalid way
+    // 2 - Il all ways are valid, we search the first old way
+    // 3 - If all ways are recent, they are all transformed to old.
+    //     and we select the way with index 0.
+    // The victim line index is returned in the victim parameter.
+    // This function returns true, if the victim line is valid.
+    ///////////////////////////////////////////////////////////////////
+    inline bool update( addr_t ad, data_t* buf, addr_t* victim )
+    {
+        size_t set, way;
+        bool   cleanup = victim_select(ad, victim, &way, &set);
+        victim_update_tag (ad, way, set);
+
+        for ( size_t word = 0 ; word < m_words ; word++ ) {
+            cache_data(way, set, word) = buf[word] ;
+        }
+
+        return cleanup;
+    }
+
+    inline bool victim_select( addr_t ad, addr_t* victim, size_t * way, size_t * set )
+    {
+        bool   found   = false;
+        bool   cleanup = false;
+        *set = m_y[ad];
+        *way = 0;
+
+        // Schearch and invalid slot
+        for ( size_t _way = 0 ; _way < m_ways && !found ; _way++ )
+        {
+            if ( !cache_val(_way, *set) )
+            {
+                found   = true;
+                cleanup = false;
+                *way    = _way;
+            }
+        }
+
+        // No invalid way, scearch the lru
+        if ( !found )
+        { 
+            for ( size_t _way = 0 ; _way < m_ways && !found ; _way++ )
+            {
+                if ( !cache_lru(_way, *set) )
+                {
+                    cache_val (_way, *set) = false;
+                    found   = true;
+                    cleanup = true;
+                    *way    = _way;
+                }
+            }
+        }
+
+        assert(found && "all ways can't be new at the same time");
+
+        *victim = (addr_t)((cache_tag(*way,*set) * m_sets) + *set);
+
+        return cleanup;
+    }
+
+    inline void victim_update_tag( addr_t ad, size_t way, size_t set )
+    {
+        tag_t  tag     = m_z[ad];
+
+        cache_tag    (way, set) = tag;
+        cache_val    (way, set) = true;
+        cache_set_lru(way, set);
+    }
+
+/*
+    //////////////////////////////////////////////////////////////////////////////
+    // The two functions select_before_update() & update_after_select()
+    // can be used to perform a line replacement in two cycles
+    // (when the directory is implemented as a single port RAM)
+    //
+    // The select_before_update function implements a pseudo LRU
+    // policy and and returns the victim line index and the selected 
+    // way in the return arguments. The selected cache line is invalidated.
+    // This function returns true, il the victim line is valid,
+    ////////////////////////////////////////////////////////////////////////////////
+    inline bool select_before_update( addr_t ad, size_t* selway, addr_t* victim )
+    {
+        size_t      set     = m_y[ad];
+        // search an empty slot (using valid bit)
+        for ( size_t way = 0 ; way < m_ways ; way++ ) 
+        {
+            if ( !cache_val(way, set) ) 
+            {
+                *selway = way;
+                *victim = (addr_t)((cache_tag(way, set) * m_sets) + set);
+                return  false;
+            }
+        }
+        // search an old line (using lru bit)
+        for ( size_t way = 0 ; way < m_ways ; way++ ) 
+        {
+            if ( !cache_lru(way, set) ) 
+            {
+                cache_val(way, set) = false;
+                *selway = way;
+                *victim = (addr_t)((cache_tag(way, set) * m_sets) + set);
+                return  true;
+            }
+        }
+        assert("all lines can't be new at the same time");
+        return true;
+    }
+
+    /////////////////////////////////////////////////////////////////////
+    // The two functions select_before_update() & update_after_select()
+    // can be used to perform a line replacement in two cycles
+    // (when the directory is implemented as a single port RAM)
+    //
+    // The update_after select() function performs the actual
+    // update of the cache line.
+    /////////////////////////////////////////////////////////////////////
+    inline void update_after_select( data_t* buf, size_t way, addr_t ad)
+    {
+        tag_t       tag     = m_z[ad];
+        size_t      set     = m_y[ad];
+
+        cache_tag(way, set) = tag;
+        cache_val(way, set) = true;
+        cache_set_lru(way, set);
+        for ( size_t word = 0 ; word < m_words ; word++ ) cache_data(way, set, word) = buf[word] ;
+    }
+*/
+    ///////////////////////////
+    inline bool find( addr_t ad, 
+                      bool* itlb_buf, bool* dtlb_buf,
+                      size_t* n_way, size_t* n_set, 
+                      addr_t* victim )
+    {
+        size_t      set     = m_y[ad];
+        size_t      selway  = 0;
+        bool        found   = false;
+        bool        cleanup = false;
+
+        for ( size_t way = 0 ; way < m_ways && !found ; way++ ) {
+            if ( !cache_val(way, set) ) {
+                found   = true;
+                cleanup = false;
+                selway  = way;
+            }
+        }
+        if ( !found ) {
+	    /* No invalid way, look for an old way, in priotity order:
+	     * an old way which is not refereced by any tlb
+	     * an old way which is not referenced by the itlb
+	     * an old way which is not referenced by the dtlb
+	     * an old way 
+	     */
+            for ( size_t way = 0 ; way < m_ways && !found ; way++ ) {
+                if ( !cache_lru(way, set) && !itlb_buf[m_sets*way+set]
+		    && !dtlb_buf[m_sets*way+set]) {
+                    found   = true;
+                    cleanup = true;
+                    selway  = way;
+                }
+            }
+            for ( size_t way = 0 ; way < m_ways && !found ; way++ ) {
+                if ( !cache_lru(way, set) && !itlb_buf[m_sets*way+set]) {
+                    found   = true;
+                    cleanup = true;
+                    selway = way;
+                }
+            }
+            for ( size_t way = 0 ; way < m_ways && !found ; way++ ) {
+                if ( !cache_lru(way, set) && !dtlb_buf[m_sets*way+set]) {
+                    found   = true;
+                    cleanup = true;
+                    selway = way;
+                }
+            }
+            for ( size_t way = 0 ; way < m_ways && !found ; way++ ) {
+                if ( !cache_lru(way, set)) {
+                    found   = true;
+                    cleanup = true;
+                    selway = way;
+                }
+            }
+        }
+	assert(found && "all ways can't be new at the same time");
+        *victim = (addr_t)((cache_tag(selway, set) * m_sets) + set);
+        cache_val(selway, set) = false;
+        *n_way = selway;
+        *n_set = set;
+        return cleanup;
+    }
+
+    /////////////////////////////////////////////////////////////////////////
+    inline void update( addr_t ad, size_t n_way, size_t n_set, data_t* buf )
+    {
+        tag_t tag = m_z[ad];
+
+        cache_tag(n_way, n_set) = tag;
+        cache_val(n_way, n_set) = true;
+        cache_set_lru(n_way, n_set);
+        for ( size_t word = 0 ; word < m_words ; word++ ) {
+            cache_data(n_way, n_set, word) = buf[word] ;
+        }
+    }
+
+    ///////////////////////////////////////////////////////////////////
+    // cleanupcheck function is used for checking whether a line exists
+    inline bool cleanupcheck( addr_t ad )
+    {
+        const tag_t       tag  = m_z[ad];
+        const size_t      set  = m_y[ad];
+
+        for ( size_t way = 0; way < m_ways; way++ ) {
+            if ( (tag == cache_tag(way, set)) && cache_val(way, set) ) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    ///////////////////////////
+    void fileTrace(FILE* file)
+    {
+        for( size_t nway = 0 ; nway < m_ways ; nway++) 
+        {
+            for( size_t nset = 0 ; nset < m_sets ; nset++) 
+            {
+                if( cache_val(nway, nset) ) fprintf(file, " V / ");
+                else                        fprintf(file, "   / ");
+                fprintf(file, "way %d / ", (int)nway);
+                fprintf(file, "set %d / ", (int)nset);
+                fprintf(file, "@ = %08zX / ", ((cache_tag(nway, nset)*m_sets+nset)*m_words*4));
+                for( size_t nword = m_words ; nword > 0 ; nword--) 
+                {
+                    unsigned int data = cache_data(nway, nset, nword-1);
+                    fprintf(file, "%08X ", data );
+                }
+                fprintf(file, "\n");
+            }
+        }
+    }
+
+    ////////////////////////
+    inline void printTrace()
+    {
+        for ( size_t way = 0; way < m_ways ; way++ ) 
+        {
+            for ( size_t set = 0 ; set < m_sets ; set++ )
+            {
+                if ( cache_val(way,set) ) std::cout << "  * " ;
+                else                      std::cout << "    " ;
+                std::cout << std::dec << "way " << way << std::hex << " | " ;
+                std::cout << "@ " << (cache_tag(way,set)*m_words*m_sets+m_words*set)*4 ;
+                for ( size_t word = 0 ; word < m_words ; word++ )
+                {
+                    std::cout << " | " << cache_data(way,set,word) ;
+                }
+                std::cout << std::endl ;
+            }
+        }
+    }
+    
+};
+
+} // namespace soclib
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: trunk/platforms/almos-tsarv3-platforms/common/generic_cache/metadata/generic_cache.sd
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/generic_cache/metadata/generic_cache.sd	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/generic_cache/metadata/generic_cache.sd	(revision 259)
@@ -0,0 +1,16 @@
+
+# -*- python -*-
+
+__id__ = "$Id: generic_cache.sd 917 2009-03-12 10:10:06Z nipo $"
+__version__ = "$Revision: 917 $"
+
+Module('caba:generic_cache',
+	classname = 'soclib::GenericCache',
+	header_files = ['../include/generic_cache.h',],
+	   tmpl_parameters = [
+	parameter.Type('addr_t'),
+	],
+	uses = [Uses('common:mapping_table'),
+			Uses('common:address_masking_table',
+				 data_t = parameter.Reference('addr_t')),],
+)
Index: trunk/platforms/almos-tsarv3-platforms/common/generic_fifo/include/caba/generic_fifo.h
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/generic_fifo/include/caba/generic_fifo.h	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/generic_fifo/include/caba/generic_fifo.h	(revision 259)
@@ -0,0 +1,179 @@
+/* -*- c++ -*-
+ *
+ * SOCLIB_LGPL_HEADER_BEGIN
+ * 
+ * This file is part of SoCLib, GNU LGPLv2.1.
+ * 
+ * SoCLib is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 of the License.
+ * 
+ * SoCLib is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with SoCLib; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ * 
+ * SOCLIB_LGPL_HEADER_END
+ *
+ * Copyright (c) UPMC, Lip6, Asim
+ *         Nicolas Pouillon <nipo@ssji.net>, 2007
+ *         Alain Greiner <alain.greiner@lip6.fr>, 2003
+ *
+ * Maintainers: nipo
+ */
+#ifndef SOCLIB_CABA_GENERIC_FIFO_H
+#define SOCLIB_CABA_GENERIC_FIFO_H
+
+#include <systemc>
+#include "register.h"
+
+namespace soclib { namespace caba {
+
+using namespace sc_core;
+
+template<typename T>
+class GenericFifo
+{
+    T *m_data;
+    sc_signal<int>    r_ptr;
+    sc_signal<int>    r_ptw;
+    sc_signal<int>    r_fill_state;
+    int m_depth;
+public:
+    typedef T data_t;
+
+    void print (void) const
+    {
+        std::cout << "r_fill_state  : " << r_fill_state << std::endl;
+        std::cout << "r_ptr/ptw/max : " << r_ptr << " - " << r_ptw << " - " << m_depth << std::endl;
+        std::cout << "m_data        : " << std::hex;
+        int i=0;
+        while (i<r_fill_state)
+            {
+                std::cout << m_data[(r_ptr+i)%m_depth] <<", ";
+                i++;
+            }
+        std::cout << std::dec << "end" << std::endl;
+    }
+
+    size_t size() const
+    {
+        return m_depth;
+    }
+
+    void init()
+    {
+        r_ptr = 0;
+        r_ptw = 0;
+        r_fill_state = 0;
+    }
+
+    inline uint32_t filled_status() const
+    {
+        return (uint32_t)r_fill_state;
+    }
+
+    inline bool empty() const
+    {
+        return !(uint32_t)r_fill_state;
+    }
+
+    inline bool full() const
+    {
+        return r_fill_state == m_depth;
+    }
+
+    void simple_put(const T &din)
+    {
+        if (r_fill_state != m_depth) { 
+            r_fill_state = r_fill_state + 1;
+            r_ptw = (r_ptw + 1) % m_depth;
+            m_data[r_ptw] = din; 
+        }
+    }
+
+    void simple_get()
+    {
+        if (r_fill_state != 0) {
+            r_fill_state = r_fill_state - 1;
+            r_ptr = (r_ptr + 1) % m_depth;
+        }
+    }
+
+    void put_and_get(const T &din)
+    {
+        if (r_fill_state == m_depth) {
+            r_fill_state = r_fill_state - 1;
+            r_ptr = (r_ptr + 1) % m_depth;
+        } else if (r_fill_state == 0) {
+            r_fill_state = r_fill_state + 1;
+            r_ptw = (r_ptw + 1) % m_depth;
+            m_data[r_ptw] = din; 
+        } else {
+            r_ptr = (r_ptr + 1) % m_depth;
+            r_ptw = (r_ptw + 1) % m_depth;
+            m_data[r_ptw] = din; 
+        }
+    }
+
+    void update (bool get, bool put, const T& din)
+    {
+        if (put and get)
+            put_and_get(din);
+        else
+        {
+            if (put)
+                simple_put(din);
+            if (get)
+                simple_get();
+        }
+    }
+
+    inline bool rok() const
+    {
+        return (r_fill_state != 0);
+    }
+
+    inline bool wok() const
+    {
+        return (r_fill_state != m_depth);
+    }
+
+    inline const T &read() const
+    {
+        return m_data[r_ptr];
+    }
+
+    GenericFifo(const std::string &name, size_t depth)
+        : m_data(new T[depth]),
+          r_ptr((name+"_r_ptr").c_str()),
+          r_ptw((name+"_r_ptw").c_str()),
+          r_fill_state((name+"_r_fill_state").c_str()),
+          m_depth(depth)
+    {
+    }
+
+    ~GenericFifo()
+    {
+        delete [] m_data;
+    }
+};
+
+}}
+
+#endif /* SOCLIB_CABA_GENERIC_FIFO_H */
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: trunk/platforms/almos-tsarv3-platforms/common/generic_fifo/metadata/generic_fifo.sd
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/generic_fifo/metadata/generic_fifo.sd	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/generic_fifo/metadata/generic_fifo.sd	(revision 259)
@@ -0,0 +1,10 @@
+
+# -*- python -*-
+
+__id__ = "$Id: generic_fifo.sd 917 2009-03-12 10:10:06Z nipo $"
+__version__ = "$Revision: 917 $"
+
+Module('caba:generic_fifo',
+	classname = 'soclib::caba::GenericFifo',
+	header_files = ['../include/caba/generic_fifo.h',],
+)
Index: trunk/platforms/almos-tsarv3-platforms/common/generic_tlb/include/generic_tlb.h
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/generic_tlb/include/generic_tlb.h	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/generic_tlb/include/generic_tlb.h	(revision 259)
@@ -0,0 +1,1149 @@
+/*****************************************************************
+ * File         : generic_tlb_40bits.h
+ * Date         : 02/06/2009
+ * Authors      : Alain Greiner, Yang GAO
+ * Copyright    : UPMC/LIP6
+ * 
+ * This file is distributed under the LGPL licence agreement.
+ ******************************************************************
+ * This object is a generic TLB (Translation Lookaside Buffer) to
+ * translate a 40 bits physical address for Hypertransport.
+ * It is implemented as a set-associative cache.
+ * The replacement algorithm is pseudo-LRU.
+ * Each TLB entry has the following format:
+ * - bool       valid            (0: unmapped; 1: mapped)
+ * - bool       locally accessed 
+ * - bool       remotely accessed 
+ * - bool       cacheable   (cached)
+ * - bool       writable    (writable access bit)
+ * - bool       executable  (executable access bit)
+ * - bool       user        (access in user mode allowed)
+ * - bool       global      (PTE not invalidated by a TLB flush)
+ * - bool       dirty       (page has been modified)
+ * Additional flag bits for every tlb entry: 
+ * - bool       pagesize    (0: 4K page size; 1: 2M page size)
+ * - bool       lru         (recently used for replace in TLB)
+ * - uint32_t   vpn         (virtual page number)
+ * - uint32_t   ppn         (physical page number)
+ *
+ * valid, lru and global are stored in registers, others are in ram.
+ *
+ *****************************************************************
+ * This file has three constructor parameters:
+ * - nways  : number of ways per associative set.
+ * - nsets  : number of associative sets.
+ * Both nways & nsets must be power of 2 no larger than 64.
+ *****************************************************************/
+
+#ifndef SOCLIB_CABA_GENERIC_TLB_H
+#define SOCLIB_CABA_GENERIC_TLB_H
+
+#include <inttypes.h>
+#include <systemc>
+#include <assert.h>
+#include "static_assert.h"
+#include "arithmetics.h"
+
+namespace soclib { 
+namespace caba {
+
+using namespace sc_core;
+
+    // PTE information struct
+    typedef struct pte_info_s {
+        bool v;    // valid             
+        bool t;    // type              
+        bool l;    // locally accessed     
+        bool r;    // remotely accessed 
+        bool c;    // cacheable    
+        bool w;    // writable    
+        bool x;    // executable  
+        bool u;    // user        
+        bool g;    // global      
+        bool d;    // dirty       
+    }pte_info_t;
+
+    enum {  
+        PTD_ID2_MASK  = 0x001FF000,
+        PAGE_K_MASK   = 0x00000FFF,
+        PAGE_M_MASK   = 0x001FFFFF,
+    };
+
+    enum {
+        PTE_V_MASK = 0x80000000,
+        PTE_T_MASK = 0x40000000,
+        PTE_L_MASK = 0x20000000,
+        PTE_R_MASK = 0x10000000,
+        PTE_C_MASK = 0x08000000,
+        PTE_W_MASK = 0x04000000,
+        PTE_X_MASK = 0x02000000,
+        PTE_U_MASK = 0x01000000,
+        PTE_G_MASK = 0x00800000,
+        PTE_D_MASK = 0x00400000,
+    };
+
+    enum {  
+        PTE_V_SHIFT = 31,
+        PTE_T_SHIFT = 30,
+        PTE_L_SHIFT = 29,
+        PTE_R_SHIFT = 28,
+        PTE_C_SHIFT = 27,
+        PTE_W_SHIFT = 26,
+        PTE_X_SHIFT = 25,
+        PTE_U_SHIFT = 24,
+        PTE_G_SHIFT = 23,
+        PTE_D_SHIFT = 22,
+    };
+
+    enum {  
+        PAGE_M_NBITS = 21,
+        PAGE_K_NBITS = 12,
+        INDEX1_NBITS = 11,
+    };
+
+using soclib::common::uint32_log2;
+
+// registers describing a TLB entry state
+typedef struct tlb_entry_state {
+	sc_signal<bool> v; //valid
+	sc_signal<bool> g; //global
+	sc_signal<bool> l; //LRU
+} tlb_entry_state_t;
+
+// registers describing a tlb set state
+typedef class tlb_set_state {
+private:
+	tlb_entry_state_t *entries;
+	size_t nways;
+public:
+	tlb_set_state()
+	{
+	}
+
+	~tlb_set_state()
+	{
+		delete [] entries;
+	}
+
+	void
+	init(size_t m_nways)
+	{
+		nways = m_nways;
+		entries = new tlb_entry_state_t[nways];
+	}
+
+	bool get_valid(size_t way)
+	{
+		return entries[way].v;
+	}
+	void set_valid(size_t way)
+	{
+		assert(entries[way].l == false &&
+		    "invalid entry should not have LRU");
+		entries[way].v = true;
+	}
+	void clear_valid(size_t way)
+	{
+		entries[way].v = false;
+		entries[way].l = false;
+	}
+
+	bool get_global(size_t way)
+	{
+		return entries[way].g;
+	}
+	void set_global(size_t way)
+	{
+		entries[way].g = true;
+	}
+	void clear_global(size_t way)
+	{
+		entries[way].g = false;
+	}
+
+	bool get_lru(size_t way)
+	{
+		return entries[way].l;
+	}
+	void set_lru(size_t way)
+	{
+		entries[way].l = true;
+		/*
+		 * if all LRU bits for the set are true, clear them
+		 */
+		for (size_t i = 0; i < nways; i++) 
+        {
+			if (i == way)
+				continue;
+			if (entries[i].l == false)
+				return;
+		}
+		// all LRU bits are set
+		for (size_t i = 0; i < nways; i++) 
+        {
+			entries[i].l = false;
+		}
+	}
+	void clear_lru(size_t way)
+	{
+		entries[way].l = false;
+	}
+
+	void reset()
+	{
+		for (size_t i = 0; i < nways; i++) 
+        {
+			entries[i].l = false;
+			entries[i].g = false;
+			entries[i].v = false;
+		}
+	}
+} tlb_set_state_t;
+
+template<typename paddr_t>
+class GenericTlb
+{
+protected:
+    typedef uint32_t vaddr_t;
+    typedef uint32_t data_t;
+
+    const size_t  m_nways;
+    const size_t  m_nsets;
+    const size_t  m_paddr_nbits;
+    const size_t  m_sets_shift;
+    const size_t  m_sets_mask;
+
+    data_t  *m_ppn; 
+    data_t  *m_vpn;
+    bool    *m_pagesize;  
+    bool    *m_locacc;
+    bool    *m_remacc;
+    bool    *m_cacheable;
+    bool    *m_writable;
+    bool    *m_executable;
+    bool    *m_user;
+    bool    *m_dirty;
+
+    tlb_set_state_t *m_setsstate;
+
+public:
+    // access methods 
+    void setlru(size_t way, size_t set)
+    { 
+        m_setsstate[set].set_lru(way); 
+    }
+
+    void clearlru(size_t way, size_t set)
+    { 
+        m_setsstate[set].clear_lru(way); 
+    }
+
+    bool lru(size_t way, size_t set)
+    { 
+        return m_setsstate[set].get_lru(way); 
+    }
+
+    void setvalid(size_t way, size_t set)
+    { 
+        m_setsstate[set].set_valid(way); 
+    }
+
+    void clearvalid(size_t way, size_t set)
+    { 
+        m_setsstate[set].clear_valid(way); 
+    }
+
+    bool valid(size_t way, size_t set)
+    { 
+        return m_setsstate[set].get_valid(way); 
+    }
+
+    void setglobal(size_t way, size_t set)
+    { 
+        m_setsstate[set].set_global(way); 
+    }
+
+    void clearglobal(size_t way, size_t set)
+    { 
+        m_setsstate[set].clear_global(way); 
+    }
+
+    bool global(size_t way, size_t set)
+    { 
+        return m_setsstate[set].get_global(way); 
+    }
+
+    data_t &ppn(size_t way, size_t set)
+    { 
+        return m_ppn[(way*m_nsets)+set]; 
+    }
+
+    data_t &vpn(size_t way, size_t set)
+    { 
+        return m_vpn[(way*m_nsets)+set]; 
+    }
+
+    bool &pagesize(size_t way, size_t set)
+    { 
+        return m_pagesize[(way*m_nsets)+set]; 
+    }
+
+    bool &locacc(size_t way, size_t set)
+    { 
+        return m_locacc[(way*m_nsets)+set]; 
+    }
+
+    bool &remacc(size_t way, size_t set)
+    { 
+        return m_remacc[(way*m_nsets)+set]; 
+    }
+
+    bool &cacheable(size_t way, size_t set)
+    { 
+        return m_cacheable[(way*m_nsets)+set]; 
+    }
+
+    bool &writable(size_t way, size_t set)
+    { 
+        return m_writable[(way*m_nsets)+set]; 
+    }
+
+    bool &executable(size_t way, size_t set)
+    { 
+        return m_executable[(way*m_nsets)+set]; 
+    }
+
+    bool &user(size_t way, size_t set)
+    { 
+        return m_user[(way*m_nsets)+set]; 
+    }
+
+    bool &dirty(size_t way, size_t set)
+    { 
+        return m_dirty[(way*m_nsets)+set]; 
+    }
+
+    //////////////////////////////////////////////////////////////
+    // constructor checks parameters, allocates the memory
+    // and computes m_page_mask, m_sets_mask and m_sets_shift
+    //////////////////////////////////////////////////////////////
+    GenericTlb(size_t nways, size_t nsets, size_t paddr_nbits):
+    m_nways(nways),
+    m_nsets(nsets),
+    m_paddr_nbits(paddr_nbits),
+    m_sets_shift(uint32_log2(nsets)),
+    m_sets_mask((1<<(int)uint32_log2(nsets))-1)
+    {
+        assert(IS_POW_OF_2(nsets));
+        assert(IS_POW_OF_2(nways));
+        assert(nsets <= 64);
+        assert(nways <= 64);
+
+        if((m_paddr_nbits < 32) || (m_paddr_nbits > 42))
+        {
+            printf("Error in the genericTlb component\n");
+            printf("The physical address parameter must be in the range [32,42]\n");
+            exit(1);
+        } 
+
+        m_ppn        = new data_t[nways * nsets];
+        m_vpn        = new data_t[nways * nsets];
+        m_pagesize   = new bool[nways * nsets];
+        m_locacc     = new bool[nways * nsets];
+        m_remacc     = new bool[nways * nsets];
+        m_cacheable   = new bool[nways * nsets];
+        m_writable   = new bool[nways * nsets];
+        m_executable = new bool[nways * nsets];
+        m_user       = new bool[nways * nsets];
+        m_dirty      = new bool[nways * nsets];
+	    m_setsstate = new tlb_set_state_t[nsets];
+	    for (size_t i = 0; i < nsets; i++)
+		    m_setsstate[i].init(nways);
+
+    } // end constructor
+
+    ~GenericTlb()
+    {
+        delete [] m_ppn;
+        delete [] m_vpn;
+        delete [] m_pagesize;
+        delete [] m_locacc;
+        delete [] m_remacc;
+        delete [] m_cacheable;
+        delete [] m_writable;
+        delete [] m_executable;
+        delete [] m_user;
+        delete [] m_dirty;
+	    delete [] m_setsstate;
+    }
+
+    /////////////////////////////////////////////////////////////
+    //  This method resets all the TLB entry.
+    /////////////////////////////////////////////////////////////
+    void reset() 
+    {
+	    for (size_t i = 0; i < m_nsets; i++)
+		    m_setsstate[i].reset();
+    } 
+
+    /////////////////////////////////////////////////////////
+    //  This method returns "false" in case of MISS
+    //  In case of HIT, the physical address, 
+    //  the pte informations, way and set are returned. 
+    /////////////////////////////////////////////////////////
+    bool translate(  vaddr_t vaddress,      // virtual address
+                            paddr_t *paddress,     // return physique address
+                            pte_info_t *pte_info,  // return pte information
+                            size_t *tw,            // return way  
+                            size_t *ts )           // return set   
+    {
+        size_t m_set = (vaddress >> PAGE_M_NBITS) & m_sets_mask; 
+        size_t k_set = (vaddress >> PAGE_K_NBITS) & m_sets_mask; 
+
+        for( size_t way = 0; way < m_nways; way++ ) 
+        {
+            // TLB hit test for 2M page size
+            if( valid(way,m_set) && pagesize(way,m_set) &&
+               (vpn(way,m_set) == (vaddress >> (PAGE_M_NBITS + m_sets_shift))) ) 
+            {
+                pte_info->l = locacc(way,m_set);
+                pte_info->r = remacc(way,m_set);
+                pte_info->c = cacheable(way,m_set);
+                pte_info->w = writable(way,m_set);
+                pte_info->x = executable(way,m_set);
+                pte_info->u = user(way,m_set);
+                pte_info->g = global(way,m_set);
+                pte_info->d = dirty(way,m_set);
+                *tw = way;
+                *ts = m_set;
+                *paddress = (paddr_t)((paddr_t)ppn(way,m_set) << PAGE_M_NBITS) | (paddr_t)(vaddress & PAGE_M_MASK);
+		setlru(way, m_set);
+                return true;
+            }
+
+            // TLB hit test for 4K page size
+            if( valid(way,k_set) && !pagesize(way,k_set) &&
+               (vpn(way,k_set) == (vaddress >> (PAGE_K_NBITS + m_sets_shift))) ) 
+            {  
+                pte_info->l = locacc(way,k_set);
+                pte_info->r = remacc(way,k_set);
+                pte_info->c = cacheable(way,k_set);
+                pte_info->w = writable(way,k_set);
+                pte_info->x = executable(way,k_set);
+                pte_info->u = user(way,k_set);
+                pte_info->g = global(way,k_set);
+                pte_info->d = dirty(way,k_set);
+                *tw = way;
+                *ts = k_set;
+                *paddress = (paddr_t)((paddr_t)ppn(way,k_set) << PAGE_K_NBITS) | (paddr_t)(vaddress & PAGE_K_MASK);
+		setlru(way, k_set);
+                return true;   
+            } 
+        } 
+        return false;
+    } // end translate()
+
+    /////////////////////////////////////////////////////////
+    //  This method returns "false" in case of MISS
+    //  In case of HIT, the physical page number is returned. 
+    /////////////////////////////////////////////////////////
+    bool translate(vaddr_t vaddress, paddr_t *paddress) 
+    {
+        size_t m_set = (vaddress >> PAGE_M_NBITS) & m_sets_mask; 
+        size_t k_set = (vaddress >> PAGE_K_NBITS) & m_sets_mask; 
+        for( size_t way = 0; way < m_nways; way++ ) 
+        {
+            // TLB hit test for 2M page size
+            if( valid(way,m_set) && pagesize(way,m_set) &&
+               (vpn(way,m_set) == (vaddress >> (PAGE_M_NBITS + m_sets_shift))) ) 
+            {
+                *paddress = (paddr_t)((paddr_t)ppn(way,m_set) << PAGE_M_NBITS) | (paddr_t)(vaddress & PAGE_M_MASK);
+		setlru(way, m_set);
+                return true;
+            }
+
+            // TLB hit test for 4K page size
+            if( valid(way,k_set) && !pagesize(way,k_set) &&
+               (vpn(way,k_set) == (vaddress >> (PAGE_K_NBITS + m_sets_shift))) ) 
+            {  
+                *paddress = (paddr_t)((paddr_t)ppn(way,k_set) << PAGE_K_NBITS) | (paddr_t)(vaddress & PAGE_K_MASK);
+		setlru(way, k_set);
+                return true;   
+            } 
+        }
+        return false;
+    } // end translate()
+    /////////////////////////////////////////////////////////////
+    //  This method resets all VALID bits in one cycle,
+    //  when the the argument is true.
+    //  Locked descriptors are preserved when it is false.
+    /////////////////////////////////////////////////////////////
+    void flush(bool all) 
+    {
+        for( size_t way = 0; way < m_nways; way++ ) 
+        {
+            for(size_t set = 0; set < m_nsets; set++) 
+            {
+		        if (!valid (way,set))
+			        continue;
+                if(global(way,set)) 
+                {
+                    if(all) 
+                    {
+			            clearvalid(way,set); // forced reset, the locked page invalid too
+		            }
+                } 
+                else 
+                {
+                    clearvalid(way,set); // not forced reset, the locked page conserve  
+                }
+            } 
+        } 
+    } // end flush
+
+    uint32_t getpte(size_t way,size_t set)   
+    {
+        data_t pte = 0; 
+        if ( pagesize(way,set) )    // 2M page size
+        {
+           pte = (data_t)ppn(way,set) | (PTE_V_MASK & (valid(way,set) << PTE_V_SHIFT));
+    
+           if ( locacc(way,set) )
+               pte = pte | PTE_L_MASK;
+           if ( remacc(way,set) )
+               pte = pte | PTE_R_MASK;
+           if ( cacheable(way,set) )
+               pte = pte | PTE_C_MASK;
+           if ( writable(way,set) )
+               pte = pte | PTE_W_MASK;
+           if ( executable(way,set) )
+               pte = pte | PTE_X_MASK;
+           if ( user(way,set) )
+               pte = pte | PTE_U_MASK;
+           if ( global(way,set) )
+               pte = pte | PTE_G_MASK;
+           if ( dirty(way,set) )
+               pte = pte | PTE_D_MASK;
+        }
+        else    // 4K page size
+        {
+           pte = (data_t)(PTE_V_MASK & (valid(way,set) << PTE_V_SHIFT));
+    
+           if ( locacc(way,set) )
+               pte = pte | PTE_L_MASK;
+           if ( remacc(way,set) )
+               pte = pte | PTE_R_MASK;
+           if ( cacheable(way,set) )
+               pte = pte | PTE_C_MASK;
+           if ( writable(way,set) )
+               pte = pte | PTE_W_MASK;
+           if ( executable(way,set) )
+               pte = pte | PTE_X_MASK;
+           if ( user(way,set) )
+               pte = pte | PTE_U_MASK;
+           if ( global(way,set) )
+               pte = pte | PTE_G_MASK;
+           if ( dirty(way,set) )
+               pte = pte | PTE_D_MASK;
+        }
+        return pte;
+    } // end getpte()
+
+    /////////////////////////////////////////////////////////////
+    //  This method return the index of the least recently
+    //  used descriptor in the associative set.
+    /////////////////////////////////////////////////////////////
+    size_t getlru(size_t set)
+    {
+        // check val bit firstly, replace the invalid PTE
+        for(size_t way = 0; way < m_nways; way++) 
+        {
+            if( !valid(way,set) ) 
+            {
+                return way;
+            }
+        } 
+
+        // then we check bit lock, remplace and old way which is not global
+        for( size_t way = 0; way < m_nways; way++ ) 
+        {
+            if( !global(way,set) && !lru(way,set) ) 
+            {
+                return way;
+            } 
+        }
+	
+	    // finally remplace the first old way
+        for( size_t way = 0; way < m_nways; way++ ) 
+        {
+            if( !lru(way,set) ) 
+            {
+                return way;
+            } 
+        }
+
+        assert(0 && "all TLB ways can't be new at the same time");
+	    return 0; /* avoid gcc warning */
+    } // end getlru()
+
+    /////////////////////////////////////////////////////////////
+    //  This method writes a new 2M page size entry in the TLB.
+    /////////////////////////////////////////////////////////////
+    void update(data_t pte, vaddr_t vaddress) 
+    {
+        size_t set = (vaddress >> PAGE_M_NBITS) & m_sets_mask; 
+        size_t way = getlru(set);
+      
+        vpn(way,set) = vaddress >> (PAGE_M_NBITS + m_sets_shift);
+        ppn(way,set) = pte & ((1<<(m_paddr_nbits - PAGE_M_NBITS))-1);
+
+        setvalid(way,set);
+        pagesize(way,set)   = true;
+        setlru(way,set);
+        locacc(way,set)     = (((pte & PTE_L_MASK) >> PTE_L_SHIFT) == 1) ? true : false;
+        remacc(way,set)     = (((pte & PTE_R_MASK) >> PTE_R_SHIFT) == 1) ? true : false;
+        cacheable(way,set)  = (((pte & PTE_C_MASK) >> PTE_C_SHIFT) == 1) ? true : false;
+        writable(way,set)   = (((pte & PTE_W_MASK) >> PTE_W_SHIFT) == 1) ? true : false;       
+        executable(way,set) = (((pte & PTE_X_MASK) >> PTE_X_SHIFT) == 1) ? true : false;
+        user(way,set)       = (((pte & PTE_U_MASK) >> PTE_U_SHIFT) == 1) ? true : false;
+	    if (((pte & PTE_G_MASK) >> PTE_G_SHIFT) == 1)
+		    setglobal(way,set);
+	    else
+		    clearglobal(way,set);
+
+        dirty(way,set)      = (((pte & PTE_D_MASK) >> PTE_D_SHIFT) == 1) ? true : false; 
+    } // end update()
+
+    /////////////////////////////////////////////////////////////
+    //  This method writes a new 4K page size entry in the TLB.
+    /////////////////////////////////////////////////////////////
+    void update(data_t pte, data_t ppn2 , vaddr_t vaddress) 
+    {
+        size_t set = (vaddress >> PAGE_K_NBITS) & m_sets_mask; 
+        size_t way = getlru(set);
+      
+        vpn(way,set) = vaddress >> (PAGE_K_NBITS + m_sets_shift);
+        ppn(way,set) = ppn2 & ((1<<(m_paddr_nbits - PAGE_K_NBITS))-1);  
+
+        setvalid(way,set);
+        pagesize(way,set)   = false;
+        setlru(way,set);
+        locacc(way,set)     = (((pte & PTE_L_MASK) >> PTE_L_SHIFT) == 1) ? true : false;
+        remacc(way,set)     = (((pte & PTE_R_MASK) >> PTE_R_SHIFT) == 1) ? true : false;
+        cacheable(way,set)  = (((pte & PTE_C_MASK) >> PTE_C_SHIFT) == 1) ? true : false;
+        writable(way,set)   = (((pte & PTE_W_MASK) >> PTE_W_SHIFT) == 1) ? true : false;       
+        executable(way,set) = (((pte & PTE_X_MASK) >> PTE_X_SHIFT) == 1) ? true : false;
+        user(way,set)       = (((pte & PTE_U_MASK) >> PTE_U_SHIFT) == 1) ? true : false;
+	    if (((pte & PTE_G_MASK) >> PTE_G_SHIFT) == 1)
+		    setglobal(way,set);
+	    else
+		    clearglobal(way,set);
+        dirty(way,set)      = (((pte & PTE_D_MASK) >> PTE_D_SHIFT) == 1) ? true : false; 
+    } // end update()
+
+    //////////////////////////////////////////////////////////////
+    //  This method invalidates a TLB entry
+    //  identified by the virtual page number.
+    //////////////////////////////////////////////////////////////
+    bool inval(vaddr_t vaddress) 
+    {
+        size_t m_set = (vaddress >> PAGE_M_NBITS) & m_sets_mask; 
+        size_t k_set = (vaddress >> PAGE_K_NBITS) & m_sets_mask; 
+        for( size_t way = 0; way < m_nways; way++ ) 
+        {
+            // TLB hit test for 2M page size
+            if( valid(way,m_set) && pagesize(way,m_set) &&
+               (vpn(way,m_set) == (vaddress >> (PAGE_M_NBITS + m_sets_shift))) ) 
+            {
+                clearvalid(way,m_set);
+                return true;
+            }
+
+            // TLB hit test for 4K page size
+            if( valid(way,k_set) && !pagesize(way,k_set) &&
+               (vpn(way,k_set) == (vaddress >> (PAGE_K_NBITS + m_sets_shift))) ) 
+            {  
+                clearvalid(way,k_set);
+                return true;   
+            } 
+        } 
+        return false;
+    } // end translate()
+
+    /////////////////////////////////////////////////////////////
+    //  This method writes a new entry in the TLB.
+    /////////////////////////////////////////////////////////////
+    void setdirty(size_t way, size_t set)
+    {
+        dirty(way,set) = true;
+    } // end setdirty()
+
+    /////////////////////////////////////////////////////////////
+    //  This method return the page size. 
+    /////////////////////////////////////////////////////////////
+    bool getpagesize(size_t way, size_t set)
+    {
+        return pagesize(way,set);
+    }
+
+}; // GenericTlb
+
+template<typename paddr_t>
+class GenericCcTlb : public GenericTlb<paddr_t>
+{
+public:
+    typedef uint32_t vaddr_t;
+    typedef uint32_t data_t;
+
+    paddr_t  *m_nline; 
+
+    // access methods 
+    paddr_t &nline(size_t way, size_t set)
+    { 
+        return m_nline[(way*this->m_nsets)+set]; 
+    }
+
+public:
+    //////////////////////////////////////////////////////////////
+    // constructor checks parameters, allocates the memory
+    // and computes m_page_mask, m_sets_mask and m_sets_shift
+    //////////////////////////////////////////////////////////////
+    GenericCcTlb(size_t nways, size_t nsets, size_t paddr_nbits):GenericTlb<paddr_t>::GenericTlb(nways, nsets, paddr_nbits)
+    {
+        m_nline = new paddr_t[this->m_nways * this->m_nsets];
+    } // end constructor
+
+    ~GenericCcTlb()
+    {
+        delete [] m_nline;
+    }
+
+    /////////////////////////////////////////////////////////
+    //  This method returns "false" in case of MISS
+    //  In case of HIT, the physical address, 
+    //  the pte informations, way and set are returned. 
+    /////////////////////////////////////////////////////////
+    bool cctranslate( vaddr_t vaddress,      // virtual address
+                             paddr_t *paddress,     // return physique address
+                             pte_info_t *pte_info,  // return pte information
+                             paddr_t *victim_index, // return nline
+                             size_t *tw,            // return way  
+                             size_t *ts )           // return set   
+    {
+        size_t m_set = (vaddress >> PAGE_M_NBITS) & this->m_sets_mask; 
+        size_t k_set = (vaddress >> PAGE_K_NBITS) & this->m_sets_mask; 
+
+        for( size_t way = 0; way < this->m_nways; way++ ) 
+        {
+            // TLB hit test for 2M page size
+            if( this->valid(way,m_set) && this->pagesize(way,m_set) &&
+               (this->vpn(way,m_set) == (vaddress >> (PAGE_M_NBITS + this->m_sets_shift))) ) 
+            {
+                pte_info->l = this->locacc(way,m_set);
+                pte_info->r = this->remacc(way,m_set);
+                pte_info->c = this->cacheable(way,m_set);
+                pte_info->w = this->writable(way,m_set);
+                pte_info->x = this->executable(way,m_set);
+                pte_info->u = this->user(way,m_set);
+                pte_info->g = this->global(way,m_set);
+                pte_info->d = this->dirty(way,m_set);
+                *victim_index = nline(way,m_set);
+                *tw = way;
+                *ts = m_set;
+                *paddress = (paddr_t)((paddr_t)this->ppn(way,m_set) << PAGE_M_NBITS) | (paddr_t)(vaddress & PAGE_M_MASK);
+		//this->setlru(way, m_set);
+                return true;
+            }
+
+            // TLB hit test for 4K page size
+            if( this->valid(way,k_set) && !(this->pagesize(way,k_set)) &&
+               (this->vpn(way,k_set) == (vaddress >> (PAGE_K_NBITS + this->m_sets_shift))) ) 
+            {  
+                pte_info->l = this->locacc(way,k_set);
+                pte_info->r = this->remacc(way,k_set);
+                pte_info->c = this->cacheable(way,k_set);
+                pte_info->w = this->writable(way,k_set);
+                pte_info->x = this->executable(way,k_set);
+                pte_info->u = this->user(way,k_set);
+                pte_info->g = this->global(way,k_set);
+                pte_info->d = this->dirty(way,k_set);
+                *victim_index = nline(way,k_set);
+                *tw = way;
+                *ts = k_set;
+                *paddress = (paddr_t)((paddr_t)this->ppn(way,k_set) << PAGE_K_NBITS) | (paddr_t)(vaddress & PAGE_K_MASK);
+		//this->setlru(way, k_set);
+                return true;   
+            } 
+        } 
+        return false;
+    } // end translate()
+
+    //////////////////////////////////////////////////////////////
+    //  This method invalidates a TLB entry for cc_vcache2
+    //  identified by the virtual page number.
+    //////////////////////////////////////////////////////////////
+    bool inval(vaddr_t vaddress, paddr_t* victim)
+    {
+        paddr_t vic_nline = 0;
+        size_t m_set = (vaddress >> PAGE_M_NBITS) & this->m_sets_mask; 
+        size_t k_set = (vaddress >> PAGE_K_NBITS) & this->m_sets_mask; 
+
+        for( size_t way = 0; way < this->m_nways; way++ ) 
+        {
+            if( this->valid(way,m_set) && this->pagesize(way,m_set) &&
+                (this->vpn(way,m_set) == (vaddress >> (PAGE_M_NBITS + this->m_sets_shift))) ) 
+            {
+                vic_nline = nline(way,m_set);
+                this->clearvalid(way,m_set);
+                break;
+            } 
+
+            if( this->valid(way,k_set) && !(this->pagesize(way,k_set)) &&
+                (this->vpn(way,k_set) == (vaddress >> (PAGE_K_NBITS + this->m_sets_shift))) ) 
+            {
+                vic_nline = nline(way,k_set);
+                this->clearvalid(way,k_set);
+                break;
+            }
+            if ( way == (this->m_nways-1)) return false; 
+        } 
+
+        *victim = vic_nline;
+        // verify whether need a cleanup
+        for( size_t way = 0; way < this->m_nways; way++ ) 
+        {
+            for( size_t set = 0; set < this->m_nsets; set++ ) 
+            {
+                if( (nline(way,set) == vic_nline) && (this->valid(way,set)) ) 
+                {
+                    return false;
+                }
+            } 
+        } 
+        return true;
+    } // end inval()
+
+    //////////////////////////////////////////////////////////////
+    //  This method invalidates a TLB entry for cc_vcache
+    //  identified by the virtual page number.
+    //////////////////////////////////////////////////////////////
+    bool inval1(vaddr_t vaddress, paddr_t* victim)
+    {
+        paddr_t vic_nline = 0;
+        size_t m_set = (vaddress >> PAGE_M_NBITS) & this->m_sets_mask; 
+        size_t k_set = (vaddress >> PAGE_K_NBITS) & this->m_sets_mask; 
+
+        for( size_t way = 0; way < this->m_nways; way++ ) 
+        {
+            if( this->valid(way,m_set) && this->pagesize(way,m_set) &&
+                (this->vpn(way,m_set) == (vaddress >> (PAGE_M_NBITS + this->m_sets_shift))) ) 
+            {
+                vic_nline = nline(way,m_set);
+                this->clearvalid(way,m_set);
+                break;
+            } 
+
+            if( this->valid(way,k_set) && !(this->pagesize(way,k_set)) &&
+                (this->vpn(way,k_set) == (vaddress >> (PAGE_K_NBITS + this->m_sets_shift))) ) 
+            {
+                vic_nline = nline(way,k_set);
+                this->clearvalid(way,k_set);
+                break;
+            }
+            if ( way == (this->m_nways-1)) return false; 
+        } 
+
+        *victim = vic_nline;
+        return true;
+    } // end inval1()
+
+    //////////////////////////////////////////////////////////////
+    //  This method coherence invalidates a TLB entry
+    //  identified by the virtual page number.
+    //////////////////////////////////////////////////////////////
+    void ccinval(size_t invway, size_t invset)
+    {
+        this->clearvalid(invway,invset);
+    } // end ccinval()
+
+    //////////////////////////////////////////////////////////////
+    //  This method coherence invalidates a TLB entry
+    //  identified by the virtual page number.
+    //////////////////////////////////////////////////////////////
+    size_t getnline(size_t way, size_t set)
+    {
+        return nline(way,set);
+    } // end getnline()
+
+    /////////////////////////////////////////////////////////////
+    //  This method for cc_vcache2 is used for context switch.  
+    //  In this case, allTLB entries should be invalidated except 
+    //  global entries.All the entries that are in the same data 
+    //  cache line have the same NLINE. Therefore only all the  
+    //  entries of one datacache line are not global, it send a  
+    //  cleanup request todata cache. The return value indicates 
+    //  whether need a cleanupand cleanup_nline contains the NLINE 
+    //  that is for cleanup.   
+    /////////////////////////////////////////////////////////////
+    bool checkcleanup(size_t nway, size_t nset, paddr_t* cleanup_nline)
+    {
+        bool cleanup = false;
+        bool isglobal = false;
+        if ( this->valid(nway,nset) )
+        {
+            size_t inval_line = nline(nway,nset);
+            for (size_t start = (nway*this->m_nsets+nset); start < this->m_nways*this->m_nsets; start++)
+            {
+                if ( this->valid(start/this->m_nsets,start%this->m_nsets) && (inval_line == nline(start/this->m_nsets,start%this->m_nsets)) )
+                {
+                    if (!this->global(start/this->m_nsets,start%this->m_nsets))
+                    {
+                        this->clearvalid(start/this->m_nsets,start%this->m_nsets);
+                    }
+                    else
+                    {
+                        isglobal = true;
+                    }
+                }
+            }
+
+            cleanup = !isglobal;
+            if(cleanup)
+                *cleanup_nline = inval_line;
+        }
+        return cleanup;
+    } // end checkcleanup
+
+    /////////////////////////////////////////////////////////////
+    //  This method for cc_vcache is used for context switch.  
+    //  In this case, allTLB entries should be invalidated except 
+    //  global entries.All the entries that are in the same data 
+    //  cache line have the same NLINE. Therefore only all the  
+    //  entries of one datacache line are not global, it send a  
+    //  cleanup request todata cache. The return value indicates 
+    //  whether need a cleanupand cleanup_nline contains the NLINE 
+    //  that is for cleanup.   
+    /////////////////////////////////////////////////////////////
+    bool checkcleanup1(size_t nway, size_t nset, paddr_t* cleanup_nline)
+    {
+        bool cleanup = false;
+        bool isglobal = false;
+        if ( this->valid(nway,nset) )
+        {
+            size_t inval_line = nline(nway,nset);
+            if (!this->global(nway,nset))
+            {
+                this->clearvalid(nway,nset);
+            }
+            else
+            {
+                isglobal = true;
+            }
+
+            cleanup = !isglobal;
+            if(cleanup)
+                *cleanup_nline = inval_line;
+        }
+        return cleanup;
+    } // end checkcleanup1
+
+    //////////////////////////////////////////////////////////////////////////
+    //  This method searchs a place for the missed TLB entry, if there is victim,
+    //  a cleanup must be sent. 
+    //////////////////////////////////////////////////////////////////////////
+    bool select(vaddr_t vaddress, paddr_t* victim, size_t *newway, size_t *newset)
+    {
+        size_t selset = vaddress & this->m_sets_mask;
+        size_t selway = this->getlru(selset);
+        bool cleanup = this->valid(selway,selset);
+
+	    if (cleanup) {
+            for( size_t way = 0; way < this->m_nways; way++ ) 
+            {
+                for( size_t set = 0; set < this->m_nsets; set++ ) 
+                {
+		            if ((way == selway) && (set == selset))
+			        continue;
+                    if ((nline(way,set) == nline(selway,selset)) && this->valid(way,set)) 
+                    {
+                        cleanup = false;
+                        break;
+                    }
+                } 
+            } 
+        }
+        
+        if (cleanup) *victim = nline(selway,selset);
+        *newway = selway;
+        *newset = selset;
+        return cleanup;
+    }
+
+    //////////////////////////////////////////////////////////////////////////
+    //  This method searchs a place for the missed TLB entry, if there is victim,
+    //  a cleanup must be sent. 
+    //////////////////////////////////////////////////////////////////////////
+    bool select1(vaddr_t vaddress, paddr_t* victim, size_t *newway, size_t *newset)
+    {
+        size_t selset = vaddress & this->m_sets_mask;
+        size_t selway = this->getlru(selset);
+        bool cleanup = this->valid(selway,selset);
+     
+        if (cleanup) *victim = nline(selway,selset);
+        *newway = selway;
+        *newset = selset;
+        return cleanup;
+    }
+
+    //////////////////////////////////////////////////////////////////////////
+    //  This method writes a new 2M page size entry in the TLB for cc_vcache2.
+    //////////////////////////////////////////////////////////////////////////
+    void update(data_t pte, vaddr_t vaddress, size_t selway, size_t selset, paddr_t line) 
+    {
+        this->vpn(selway,selset) = vaddress >> (PAGE_M_NBITS + this->m_sets_shift);
+        this->ppn(selway,selset) = pte & ((1<<(this->m_paddr_nbits - PAGE_M_NBITS))-1); 
+ 
+        this->setvalid(selway,selset);
+        this->pagesize(selway,selset)   = true;
+	    this->setlru(selway,selset);
+
+        this->locacc(selway,selset)     = (((pte & PTE_L_MASK) >> PTE_L_SHIFT) == 1) ? true : false;
+        this->remacc(selway,selset)     = (((pte & PTE_R_MASK) >> PTE_R_SHIFT) == 1) ? true : false;
+        this->cacheable(selway,selset)  = (((pte & PTE_C_MASK) >> PTE_C_SHIFT) == 1) ? true : false;
+        this->writable(selway,selset)   = (((pte & PTE_W_MASK) >> PTE_W_SHIFT) == 1) ? true : false;       
+        this->executable(selway,selset) = (((pte & PTE_X_MASK) >> PTE_X_SHIFT) == 1) ? true : false;
+        this->user(selway,selset)       = (((pte & PTE_U_MASK) >> PTE_U_SHIFT) == 1) ? true : false;
+	    if (((pte & PTE_G_MASK) >> PTE_G_SHIFT) == 1)
+		    this->setglobal(selway,selset);
+	    else
+		    this->clearglobal(selway,selset);
+        this->dirty(selway,selset)      = (((pte & PTE_D_MASK) >> PTE_D_SHIFT) == 1) ? true : false; 
+        nline(selway,selset) = line;  
+    } // end update()
+
+    //////////////////////////////////////////////////////////////////////////
+    //  This method writes a new 4K page size entry in the TLB for cc_vcache2.
+    //////////////////////////////////////////////////////////////////////////
+    void update(data_t pte, data_t ppn2, vaddr_t vaddress, size_t selway, size_t selset, paddr_t line) 
+    {
+        this->vpn(selway,selset) = vaddress >> (PAGE_K_NBITS + this->m_sets_shift);
+        this->ppn(selway,selset) = ppn2 & ((1<<(this->m_paddr_nbits - PAGE_K_NBITS))-1);  
+        this->setvalid(selway,selset);
+        this->pagesize(selway,selset)   = false;
+	    this->setlru(selway,selset);
+
+        this->locacc(selway,selset)     = (((pte & PTE_L_MASK) >> PTE_L_SHIFT) == 1) ? true : false;
+        this->remacc(selway,selset)     = (((pte & PTE_R_MASK) >> PTE_R_SHIFT) == 1) ? true : false;
+        this->cacheable(selway,selset)  = (((pte & PTE_C_MASK) >> PTE_C_SHIFT) == 1) ? true : false;
+        this->writable(selway,selset)   = (((pte & PTE_W_MASK) >> PTE_W_SHIFT) == 1) ? true : false;       
+        this->executable(selway,selset) = (((pte & PTE_X_MASK) >> PTE_X_SHIFT) == 1) ? true : false;
+        this->user(selway,selset)       = (((pte & PTE_U_MASK) >> PTE_U_SHIFT) == 1) ? true : false;
+	    if (((pte & PTE_G_MASK) >> PTE_G_SHIFT) == 1)
+		    this->setglobal(selway,selset);
+	    else
+		    this->clearglobal(selway,selset);
+		
+        this->dirty(selway,selset)      = (((pte & PTE_D_MASK) >> PTE_D_SHIFT) == 1) ? true : false; 
+        
+        nline(selway,selset) = line; 
+    } // end update()
+#if 0
+    //////////////////////////////////////////////////////////////////////////
+    //  This method writes a new 4K page size entry in the TLB for cc_vcache.
+    //////////////////////////////////////////////////////////////////////////
+    bool update1(data_t pte, data_t ppn2, vaddr_t vaddress, paddr_t line, paddr_t* victim ) 
+    {
+        size_t set = (vaddress >> PAGE_K_NBITS) & this->m_sets_mask;
+        size_t selway = this->getlru(set);
+        bool cleanup = this->valid(selway,set);
+
+        this->vpn(selway,set) = vaddress >> (PAGE_K_NBITS + this->m_sets_shift);
+        this->ppn(selway,set) = ppn2 & ((1<<(this->m_paddr_nbits - PAGE_K_NBITS))-1);  
+        this->setvalid(selway,set);
+        this->pagesize(selway,set)   = false;
+        this->setlru(selway,set);
+
+        this->locacc(selway,set)     = (((pte & PTE_L_MASK) >> PTE_L_SHIFT) == 1) ? true : false;
+        this->remacc(selway,set)     = (((pte & PTE_R_MASK) >> PTE_R_SHIFT) == 1) ? true : false;
+        this->cacheable(selway,set)  = (((pte & PTE_C_MASK) >> PTE_C_SHIFT) == 1) ? true : false;
+        this->writable(selway,set)   = (((pte & PTE_W_MASK) >> PTE_W_SHIFT) == 1) ? true : false;       
+        this->executable(selway,set) = (((pte & PTE_X_MASK) >> PTE_X_SHIFT) == 1) ? true : false;
+        this->user(selway,set)       = (((pte & PTE_U_MASK) >> PTE_U_SHIFT) == 1) ? true : false;
+	    if (((pte & PTE_G_MASK) >> PTE_G_SHIFT) == 1)
+		    this->setglobal(selway,set);
+	    else
+		    this->clearglobal(selway,set);
+        this->dirty(selway,set)      = (((pte & PTE_D_MASK) >> PTE_D_SHIFT) == 1) ? true : false; 
+        
+        *victim = nline(selway,set);
+        nline(selway,set) = line; 
+
+        return cleanup;
+    } // end update1()
+#endif
+    //////////////////////////////////////////////////////////////
+    //  This method verify whether all 16 words of a data cache line 
+    //  that are as PTE don't exist in TLB. If is true, a cleanup 
+    //  request is actived.
+    //////////////////////////////////////////////////////////////
+    bool cleanupcheck( paddr_t n_line ) 
+    {
+        for( size_t way = 0; way < this->m_nways; way++ ) 
+        {
+            for( size_t set = 0; set < this->m_nsets; set++ ) 
+            {
+                if ( (nline(way,set) == n_line) && this->valid(way,set) ) 
+                {
+                    return true;
+                }
+            } 
+        } 
+        return false;
+    } // end cccheck()
+
+    //////////////////////////////////////////////////////////////
+    //  This method invalidates a TLB entry
+    //  identified by the virtual page number.
+    //////////////////////////////////////////////////////////////
+    bool cccheck( paddr_t n_line, 
+                         size_t start_way, size_t start_set, 
+                         size_t* n_way, size_t* n_set,
+                         bool* end )
+    {
+        for ( size_t start = start_way*(this->m_nsets)+start_set; start < this->m_nways*this->m_nsets; start++ )
+        {
+            if (( nline((start/this->m_nsets),(start%this->m_nsets)) == n_line ) && this->valid((start/this->m_nsets),(start%this->m_nsets))) 
+            {
+                *n_way = start/this->m_nsets;
+                *n_set = start%this->m_nsets;
+                if ( ((start/this->m_nsets) == (this->m_nways-1)) && ((start%this->m_nsets) == (this->m_nsets-1)) )
+                {
+                    *end = true;
+                }
+                else
+                {
+                    *end = false;
+                }
+                return true;
+            }
+        }
+        *end = true;
+        return false;
+    } // end cccheck()
+}; // GenericCcTlb
+
+}}
+
+#endif /* SOCLIB_CABA_GENERIC_TLB_H */
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
+
+
Index: trunk/platforms/almos-tsarv3-platforms/common/generic_tlb/metadata/generic_tlb.sd
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/generic_tlb/metadata/generic_tlb.sd	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/generic_tlb/metadata/generic_tlb.sd	(revision 259)
@@ -0,0 +1,13 @@
+
+# -*- python -*-
+
+__id__ = "$Id: generic_tlb.sd 917 2009-03-12 10:10:06Z nipo $"
+__version__ = "$Revision: 917 $"
+
+Module('caba:generic_tlb',
+	classname = 'soclib::GenericTlb',
+	header_files = ['../include/generic_tlb.h',],
+	   tmpl_parameters = [
+	parameter.Type('addr_t'),
+	],
+)
Index: trunk/platforms/almos-tsarv3-platforms/common/vci_cc_vcache_wrapper2_v1/caba/metadata/vci_cc_vcache_wrapper2_v1.sd
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/vci_cc_vcache_wrapper2_v1/caba/metadata/vci_cc_vcache_wrapper2_v1.sd	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/vci_cc_vcache_wrapper2_v1/caba/metadata/vci_cc_vcache_wrapper2_v1.sd	(revision 259)
@@ -0,0 +1,67 @@
+
+# -*- python -*-
+
+__id__ = "$Id: vci_cc_vcache_wrapper2_v1.sd 20 2010-04-14 03:27:59Z nipo $"
+__version__ = "$Revision: 20 $"
+
+Module('caba:vci_cc_vcache_wrapper2_v1',
+	classname = 'soclib::caba::VciCcVCacheWrapper2V1',
+	   tmpl_parameters = [
+	parameter.Module('vci_param', default = 'caba:vci_param'),
+	parameter.Module('iss_t'),
+	],
+	header_files = [
+	'../source/include/vci_cc_vcache_wrapper2_v1.h',
+	],
+	implementation_files = [
+	'../source/src/vci_cc_vcache_wrapper2_v1.cpp',
+	],
+	uses = [
+	Uses('caba:base_module'),
+	Uses('caba:write_buffer'),
+	Uses('caba:generic_tlb', addr_t = parameter.StringExt('sc_dt::sc_uint<%d> ', parameter.Reference('addr_size'))),
+	Uses('caba:generic_cache', addr_t = parameter.StringExt('sc_dt::sc_uint<%d> ', parameter.Reference('addr_size'))),
+	Uses('common:address_masking_table', data_t = parameter.StringExt('sc_dt::sc_uint<%d> ', parameter.Reference('addr_size'))),
+	Uses('common:iss2'),
+	Uses('common:mapping_table'),
+	],
+	ports = [
+	Port('caba:vci_initiator', 'p_vci_ini_rw'),
+	Port('caba:vci_initiator', 'p_vci_ini_c'),
+	Port('caba:vci_target', 'p_vci_tgt'),
+	Port('caba:bit_in','p_irq', parameter.Constant('n_irq')),
+	Port('caba:bit_in', 'p_resetn', auto = 'resetn'),
+	Port('caba:clock_in', 'p_clk', auto = 'clock'),
+	],
+	instance_parameters = [
+	parameter.Int('proc_id'),
+	parameter.Module('mt', 'common:mapping_table'),
+	parameter.Module('mc', 'common:mapping_table'),
+	parameter.IntTab('initiator_rw_index'),
+	parameter.IntTab('initiator_c_index'),
+	parameter.IntTab('target_index'),
+    	parameter.Int('itlb_ways'),
+    	parameter.Int('itlb_sets'),
+    	parameter.Int('dtlb_ways'),
+    	parameter.Int('dtlb_sets'),
+    	parameter.Int('icache_ways'),
+    	parameter.Int('icache_sets'),
+    	parameter.Int('icache_words'),
+    	parameter.Int('dcache_ways'),
+    	parameter.Int('dcache_sets'),
+    	parameter.Int('dcache_words'),
+    	parameter.Int('write_buf_size'),
+	],
+	   extensions = [
+	'dsx:get_ident='
+        'initiator_rw_index:p_vci_ini_rw:mt,'
+        'initiator_c_index:p_vci_ini_c:mc,'
+        'target_index:p_vci_tgt:mc',
+	'dsx:cpu=wrapper:iss_t',
+	'dsx:addressable=target_index',
+    'dsx:on_segment=mc:add_index:initiator_rw_index',
+	'dsx:mapping_type=processor:proc_id',
+   ],
+)
+
+
Index: trunk/platforms/almos-tsarv3-platforms/common/vci_cc_vcache_wrapper2_v1/caba/source/include/vci_cc_vcache_wrapper2_v1.h
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/vci_cc_vcache_wrapper2_v1/caba/source/include/vci_cc_vcache_wrapper2_v1.h	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/vci_cc_vcache_wrapper2_v1/caba/source/include/vci_cc_vcache_wrapper2_v1.h	(revision 259)
@@ -0,0 +1,618 @@
+/* -*- c++ -*-
+ * File : vci_cc_vcache_wrapper2_v1.h
+ * Copyright (c) UPMC, Lip6, SoC
+ * Authors : Alain GREINER, Yang GAO
+ *
+ * SOCLIB_LGPL_HEADER_BEGIN
+ * 
+ * This file is part of SoCLib, GNU LGPLv2.1.
+ * 
+ * SoCLib is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 of the License.
+ * 
+ * SoCLib is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with SoCLib; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ * 
+ * SOCLIB_LGPL_HEADER_END
+ */
+ 
+#ifndef SOCLIB_CABA_VCI_CC_VCACHE_WRAPPER2_V1_H
+#define SOCLIB_CABA_VCI_CC_VCACHE_WRAPPER2_V1_H
+
+#include <inttypes.h>
+#include <iostream>
+#include <fstream>
+#include <systemc>
+#include "caba_base_module.h"
+#include "write_buffer.h"
+#include "generic_cache.h"
+#include "vci_initiator.h"
+#include "vci_target.h"
+#include "mapping_table.h"
+#include "generic_tlb.h"
+#include "static_assert.h"
+
+namespace soclib {
+namespace caba {
+
+using namespace sc_core;
+
+////////////////////////////////////////////
+template<typename vci_param, typename iss_t>
+class VciCcVCacheWrapper2V1
+////////////////////////////////////////////
+    : public soclib::caba::BaseModule
+{
+    typedef uint32_t vaddr_t;
+    typedef uint32_t data_t;
+    typedef uint32_t tag_t;
+    typedef uint32_t type_t;
+    typedef typename iss_t::DataOperationType data_op_t;
+
+    typedef typename vci_param::addr_t  paddr_t;
+    typedef typename vci_param::be_t    vci_be_t;
+	typedef typename vci_param::srcid_t vci_srcid_t;
+	typedef typename vci_param::trdid_t vci_trdid_t;
+	typedef typename vci_param::pktid_t vci_pktid_t;
+	typedef typename vci_param::plen_t  vci_plen_t;
+
+    enum icache_fsm_state_e {  
+        ICACHE_IDLE,                // 00
+        ICACHE_BIS,                 // 01
+        ICACHE_TLB1_READ,           // 02
+        ICACHE_TLB1_WRITE,          // 03
+        ICACHE_TLB1_UPDT_SEL,       // 04
+        ICACHE_TLB1_UPDT,           // 05
+        ICACHE_TLB2_READ,           // 06
+        ICACHE_TLB2_WRITE,          // 07
+        ICACHE_TLB2_UPDT_SEL,       // 08
+        ICACHE_TLB2_UPDT,           // 09
+        ICACHE_SW_FLUSH,            // 0a
+        ICACHE_TLB_FLUSH,           // 0b
+        ICACHE_CACHE_FLUSH,         // 0c
+        ICACHE_TLB_INVAL,           // 0d
+        ICACHE_CACHE_INVAL,         // 0e
+        ICACHE_CACHE_INVAL_PA,      // 0f
+        ICACHE_MISS_WAIT,           // 10
+        ICACHE_UNC_WAIT,            // 11
+        ICACHE_MISS_UPDT,           // 12
+        ICACHE_ERROR,               // 13
+        ICACHE_CC_INVAL,            // 14
+        ICACHE_TLB_CC_INVAL,        // 15
+    };
+
+    enum dcache_fsm_state_e {  
+        DCACHE_IDLE,                // 00
+        DCACHE_BIS,                 // 01
+        DCACHE_DTLB1_READ_CACHE,    // 02
+        DCACHE_TLB1_LL_WAIT,        // 03
+        DCACHE_TLB1_SC_WAIT,        // 04
+        DCACHE_TLB1_READ,           // 05
+        DCACHE_TLB1_READ_UPDT,      // 06
+        DCACHE_TLB1_UPDT_SEL,       // 07
+        DCACHE_TLB1_UPDT,           // 08
+        DCACHE_DTLB2_READ_CACHE,    // 09
+        DCACHE_TLB2_LL_WAIT,        // 0a
+        DCACHE_TLB2_SC_WAIT,        // 0b
+        DCACHE_TLB2_READ,           // 0c
+        DCACHE_TLB2_READ_UPDT,      // 0d
+        DCACHE_TLB2_UPDT_SEL,       // 0e
+        DCACHE_TLB2_UPDT,           // 0f
+        DCACHE_CTXT_SWITCH,         // 10
+        DCACHE_ICACHE_FLUSH,        // 11
+        DCACHE_DCACHE_FLUSH,        // 12
+        DCACHE_ITLB_INVAL,          // 13
+        DCACHE_DTLB_INVAL,          // 14
+        DCACHE_ICACHE_INVAL,        // 15
+        DCACHE_DCACHE_INVAL,        // 16
+	    DCACHE_ICACHE_INVAL_PA,     // 17
+	    DCACHE_DCACHE_INVAL_PA,     // 18
+        DCACHE_DCACHE_SYNC,         // 19
+        DCACHE_LL_DIRTY_WAIT,       // 1a
+        DCACHE_SC_DIRTY_WAIT,       // 1b
+        DCACHE_WRITE_UPDT,          // 1c
+        DCACHE_WRITE_DIRTY,         // 1d
+        DCACHE_WRITE_REQ,           // 1e
+        DCACHE_MISS_WAIT,           // 1f
+        DCACHE_MISS_UPDT,           // 20
+        DCACHE_UNC_WAIT,            // 21
+        DCACHE_ERROR,               // 22
+        DCACHE_ITLB_READ,           // 23
+        DCACHE_ITLB_UPDT,           // 24
+        DCACHE_ITLB_LL_WAIT,        // 25
+        DCACHE_ITLB_SC_WAIT,        // 26
+        DCACHE_CC_CHECK,            // 27
+        DCACHE_CC_INVAL,            // 28
+        DCACHE_CC_UPDT,             // 29
+        DCACHE_CC_NOP,              // 2a
+        DCACHE_TLB_CC_INVAL,        // 2b
+        DCACHE_ITLB_CLEANUP,        // 2c
+    };
+
+    enum cmd_fsm_state_e {      
+        CMD_IDLE,                   // 00
+        CMD_ITLB_READ,              // 01
+        CMD_ITLB_ACC_LL,            // 02
+        CMD_ITLB_ACC_SC,            // 03
+        CMD_INS_MISS,               // 04
+        CMD_INS_UNC,                // 05
+        CMD_DTLB_READ,              // 06
+        CMD_DTLB_ACC_LL,            // 07
+        CMD_DTLB_ACC_SC,            // 08
+        CMD_DTLB_DIRTY_LL,          // 09
+        CMD_DTLB_DIRTY_SC,          // 0a
+        CMD_DATA_UNC,               // 0b
+        CMD_DATA_MISS,              // 0c
+        CMD_DATA_WRITE,             // 0d
+    };
+
+    enum rsp_fsm_state_e {       
+        RSP_IDLE,                   // 00
+        RSP_ITLB_READ,              // 01
+        RSP_ITLB_ACC_LL,            // 02
+        RSP_ITLB_ACC_SC,            // 03
+        RSP_INS_MISS,               // 04
+        RSP_INS_UNC,                // 05
+        RSP_DTLB_READ,              // 06
+        RSP_DTLB_ACC_LL,            // 07
+        RSP_DTLB_ACC_SC,            // 08
+        RSP_DTLB_DIRTY_LL,          // 09
+        RSP_DTLB_DIRTY_SC,          // 0a
+        RSP_DATA_MISS,              // 0b
+        RSP_DATA_UNC,               // 0c
+        RSP_DATA_WRITE,             // 0d
+    };
+    enum cleanup_cmd_fsm_state_e {
+        CLEANUP_CMD_IDLE,               // 00
+        CLEANUP_CMD_DATA,               // 01
+        CLEANUP_CMD_INS,                // 02
+    };
+
+    enum cleanup_rsp_fsm_state_e {
+        CLEANUP_RSP_IDLE,               // 00
+        CLEANUP_RSP_DATA,               // 01
+        CLEANUP_RSP_INS,                // 02
+    };
+
+    enum tgt_fsm_state_e {  
+        TGT_IDLE,                   // 00
+        TGT_UPDT_WORD,              // 01
+        TGT_UPDT_DATA,              // 02
+        TGT_REQ_BROADCAST,          // 03
+        TGT_REQ_ICACHE,             // 04
+        TGT_REQ_DCACHE,             // 05
+        TGT_RSP_BROADCAST,          // 06
+        TGT_RSP_ICACHE,             // 07
+        TGT_RSP_DCACHE,             // 08
+    };
+
+    enum inval_itlb_fsm_state_e {
+        INVAL_ITLB_IDLE,            // 00
+        INVAL_ITLB_CHECK,           // 01
+        INVAL_ITLB_INVAL,           // 02
+        INVAL_ITLB_CLEAR,           // 03
+    };
+
+    enum inval_dtlb_fsm_state_e {
+        INVAL_DTLB_IDLE,            // 00
+        INVAL_DTLB_CHECK,           // 01
+        INVAL_DTLB_INVAL,           // 02
+        INVAL_DTLB_CLEAR,           // 03
+    };
+
+    // TLB Mode ITLB / DTLB / ICACHE / DCACHE
+    enum {          
+        ALL_DEACTIVE = 0x0000,   // TLBs disactive caches disactive
+        INS_TLB_MASK    = 0x8,
+        DATA_TLB_MASK   = 0x4,
+        INS_CACHE_MASK  = 0x2,
+        DATA_CACHE_MASK = 0x1,
+    };
+
+    // Error Type
+    enum mmu_error_type_e {
+        MMU_NONE                      = 0x0000, // None
+        MMU_WRITE_PT1_UNMAPPED 	      = 0x0001, // Write access of Page fault on Page Table 1          (non fatal error)
+        MMU_WRITE_PT2_UNMAPPED 	      = 0x0002, // Write access of Page fault on Page Table 2          (non fatal error)
+        MMU_WRITE_PRIVILEGE_VIOLATION = 0x0004, // Write access of Protected access in user mode       (user error)
+        MMU_WRITE_ACCES_VIOLATION 	  = 0x0008, // Write access of write access to a non writable page (user error)
+        MMU_WRITE_UNDEFINED_XTN 	  = 0x0020, // Write access of undefined external access address   (user error)
+        MMU_WRITE_PT1_ILLEGAL_ACCESS  = 0x0040, // Write access of Bus Error accessing Table 1         (kernel error)
+        MMU_WRITE_PT2_ILLEGAL_ACCESS  = 0x0080, // Write access of Bus Error accessing Table 2         (kernel error)
+        MMU_WRITE_DATA_ILLEGAL_ACCESS = 0x0100, // Write access of Bus Error in cache access           (kernel error)
+        MMU_READ_PT1_UNMAPPED 	      = 0x1001, // Read access of Page fault on Page Table 1  	       (non fatal error)
+        MMU_READ_PT2_UNMAPPED 	      = 0x1002, // Read access of Page fault on Page Table 2  	       (non fatal error)
+        MMU_READ_PRIVILEGE_VIOLATION  = 0x1004, // Read access of Protected access in user mode 	   (user error)
+        MMU_READ_EXEC_VIOLATION 	  = 0x1010, // Exec access to a non exec page                      (user error)
+        MMU_READ_UNDEFINED_XTN 	      = 0x1020, // Read access of Undefined external access address    (user error)
+        MMU_READ_PT1_ILLEGAL_ACCESS   = 0x1040, // Read access of Bus Error in Table1 access           (kernel error)
+        MMU_READ_PT2_ILLEGAL_ACCESS   = 0x1080, // Read access of Bus Error in Table2 access 	       (kernel error)
+        MMU_READ_DATA_ILLEGAL_ACCESS  = 0x1100, // Read access of Bus Error in cache access 	       (kernel error)
+    };
+
+public:
+    sc_in<bool>                             p_clk;
+    sc_in<bool>                             p_resetn;
+    sc_in<bool>                             p_irq[iss_t::n_irq];
+    soclib::caba::VciInitiator<vci_param>   p_vci_ini_rw;
+    soclib::caba::VciInitiator<vci_param>   p_vci_ini_c;
+    soclib::caba::VciTarget<vci_param>      p_vci_tgt;
+
+private:
+    // STRUCTURAL PARAMETERS
+    soclib::common::AddressDecodingTable<uint32_t, bool>    m_cacheability_table;
+    const soclib::common::Segment                           m_segment;
+    iss_t                                                   m_iss;   
+    const vci_srcid_t                                       m_srcid_rw;
+    const vci_srcid_t                                       m_srcid_c;
+
+    const size_t  m_itlb_ways;
+    const size_t  m_itlb_sets;
+
+    const size_t  m_dtlb_ways;
+    const size_t  m_dtlb_sets;
+
+    const size_t  m_icache_ways;
+    const size_t  m_icache_sets;
+    const size_t  m_icache_yzmask;
+    const size_t  m_icache_words;
+
+    const size_t  m_dcache_ways;
+    const size_t  m_dcache_sets;
+    const size_t  m_dcache_yzmask;
+    const size_t  m_dcache_words;
+
+    const size_t  m_write_buf_size;  
+    const size_t  m_paddr_nbits;  
+
+    // instruction and data vcache tlb instances 
+    soclib::caba::GenericCcTlb<paddr_t>    icache_tlb;
+    soclib::caba::GenericCcTlb<paddr_t>    dcache_tlb;
+
+    sc_signal<vaddr_t>      r_mmu_ptpr;             // page table pointer register
+    sc_signal<int>          r_mmu_mode;             // tlb mode register
+    sc_signal<int>          r_mmu_params;           // mmu parameters register
+    sc_signal<int>          r_mmu_release;          // mmu release register
+    sc_signal<int>          r_mmu_word_lo;          // mmu misc data low
+    sc_signal<int>          r_mmu_word_hi;          // mmu mmu misc data hight
+
+    // DCACHE FSM REGISTERS
+    sc_signal<int>          r_dcache_fsm;               // state register
+    sc_signal<paddr_t>      r_dcache_paddr_save;        // physical address
+    sc_signal<data_t>       r_dcache_wdata_save;        // write data
+    sc_signal<data_t>       r_dcache_rdata_save;        // read data
+    sc_signal<type_t>       r_dcache_type_save;         // access type
+    sc_signal<vci_be_t>     r_dcache_be_save;           // byte enable
+    sc_signal<bool>         r_dcache_cached_save;       // used by the write buffer
+    sc_signal<paddr_t>      r_dcache_tlb_paddr;         // physical address of tlb miss
+    sc_signal<bool>         r_dcache_dirty_save;        // used for TLB dirty bit update
+    sc_signal<size_t>       r_dcache_tlb_set_save;      // used for TLB dirty bit update
+    sc_signal<size_t>       r_dcache_tlb_way_save;      // used for TLB dirty bit update
+    sc_signal<vaddr_t>      r_dcache_id1_save;          // used by the PT1 bypass
+    sc_signal<paddr_t>      r_dcache_ptba_save;         // used by the PT1 bypass
+    sc_signal<bool>         r_dcache_ptba_ok;           // used by the PT1 bypass
+    sc_signal<data_t>       r_dcache_pte_update;        // used for page table update
+    sc_signal<data_t>       r_dcache_ppn_update;        // used for physical page number update 
+    sc_signal<tag_t>        r_dcache_ppn_save;          // used for speculative cache access
+    sc_signal<tag_t>        r_dcache_vpn_save;          // used for speculative cache access
+    sc_signal<bool>         r_dtlb_translation_valid;   // used for speculative address
+    sc_signal<bool>         r_dcache_buf_unc_valid;     // used for uncached read
+    sc_signal<bool>         r_dcache_hit_p_save;        // used to save hit_p in case BIS
+
+    sc_signal<data_t>       r_dcache_error_type;        // software visible register
+    sc_signal<vaddr_t>      r_dcache_bad_vaddr;         // software visible register 
+
+    sc_signal<bool>         r_dcache_miss_req;          // used for cached read miss
+    sc_signal<bool>         r_dcache_unc_req;           // used for uncached read miss
+    sc_signal<bool>         r_dcache_write_req;         // used for write 
+    sc_signal<bool>         r_dcache_tlb_read_req;      // used for tlb ptba or pte read
+
+    sc_signal<bool>         r_dcache_llsc_reserved;     // used for check address reserved
+    sc_signal<paddr_t>      r_dcache_llsc_addr_save;    // used for save llsc address
+ 
+    sc_signal<bool>         r_dcache_tlb_ll_acc_req;    // used for tlb access bit update
+    sc_signal<bool>         r_dcache_tlb_sc_acc_req;    // used for tlb access bit update
+    sc_signal<bool>         r_dcache_tlb_ll_dirty_req;  // used for tlb dirty bit update 
+    sc_signal<bool>         r_dcache_tlb_sc_dirty_req;  // used for tlb dirty bit update 
+    sc_signal<bool>         r_dcache_sc_updt_dirty;     // used for tlb dirty bit update 
+    sc_signal<bool>         r_dcache_tlb_ptba_read;     // used for tlb ptba read when write dirty bit 
+    sc_signal<bool>         r_dcache_xtn_req;           // used for xtn write for ICACHE
+
+    bool                    *r_dcache_in_itlb;          // indicates some words of dcache line in ins TLB 
+    bool                    *r_dcache_in_dtlb;          // indicates some words of dcache line in data TLB 
+    sc_signal<bool>         r_dreq_isUser_save;         // For instrumentation: is User access ? 
+
+    // coherence registers
+    sc_signal<int>          r_dcache_fsm_save;          // state save register
+    sc_signal<size_t>       r_dcache_way;
+    sc_signal<size_t>       r_dcache_set;
+    sc_signal<bool>         r_dcache_cleanup_req;       // data cleanup request
+    sc_signal<paddr_t>      r_dcache_cleanup_line;      // data cleanup NLINE
+    sc_signal<bool>         r_dcache_inval_rsp;         // data cache invalidate
+
+    // ICACHE FSM REGISTERS
+    sc_signal<int>          r_icache_fsm;               // state register
+    sc_signal<paddr_t>      r_icache_paddr_save;        // physical address
+    sc_signal<vaddr_t>      r_icache_id1_save;          // used by the PT1 bypass
+    sc_signal<paddr_t>      r_icache_ptba_save;         // used by the PT1 bypass
+    sc_signal<bool>         r_icache_ptba_ok;           // used by the PT1 bypass
+    sc_signal<data_t>       r_icache_pte_update;        // used for page table update
+    sc_signal<tag_t>        r_icache_ppn_save;          // used for speculative cache access
+    sc_signal<tag_t>        r_icache_vpn_save;          // used for speculative cache access
+    sc_signal<bool>         r_itlb_translation_valid;   // used for speculative physical address
+    sc_signal<bool>         r_icache_buf_unc_valid;     // used for uncached read
+    sc_signal<data_t>       r_icache_error_type;        // software visible registers
+    sc_signal<vaddr_t>      r_icache_bad_vaddr;         // software visible registers
+
+    sc_signal<bool>         r_icache_miss_req;          // used for cached read miss
+    sc_signal<bool>         r_icache_unc_req;           // used for uncached read miss
+    sc_signal<bool>         r_dcache_itlb_read_req;     // used for tlb ptba or pte read 
+
+    sc_signal<bool>         r_dcache_itlb_ll_acc_req;   // used for tlb access bit update
+    sc_signal<bool>         r_dcache_itlb_sc_acc_req;   // used for tlb access bit update
+
+    sc_signal<bool>	        r_itlb_read_dcache_req;     // used for instruction tlb miss, request in data cache
+    sc_signal<bool>	        r_itlb_k_read_dcache;       // used for instruction tlb miss, request in data cache
+    sc_signal<bool>	        r_itlb_acc_dcache_req;      // used for itlb update access bit via dcache
+    sc_signal<bool>	        r_itlb_acc_redo_req;        // used for itlb update access bit via dcache
+    sc_signal<bool>	        r_dcache_rsp_itlb_error;    // used for data cache rsp error when itlb miss
+    sc_signal<data_t>	    r_dcache_rsp_itlb_miss;	    // used for dcache rsp data when itlb miss
+    sc_signal<data_t>	    r_dcache_rsp_itlb_ppn;	    // used for dcache rsp ppn when itlb miss
+    sc_signal<vaddr_t>      r_icache_vaddr_req;			// virtual address requested by the CPU
+    sc_signal<bool>         r_ireq_isUser_save;         // For instrumentation: is User access ? 
+
+    // coherence registers
+    sc_signal<int>          r_icache_fsm_save;          // state save register
+    sc_signal<size_t>       r_icache_way;
+    sc_signal<size_t>       r_icache_set;
+    sc_signal<bool>         r_icache_cleanup_req;       // ins cleanup request
+    sc_signal<paddr_t>      r_icache_cleanup_line;      // ins cleanup NLINE
+    sc_signal<bool>         r_icache_inval_rsp;         // ins cache invalidate
+
+    // VCI_CMD FSM REGISTERS
+    sc_signal<int>          r_vci_cmd_fsm;
+    sc_signal<size_t>       r_vci_cmd_min;       
+    sc_signal<size_t>       r_vci_cmd_max;       
+    sc_signal<size_t>       r_vci_cmd_cpt;     
+
+    // VCI_RSP FSM REGISTERS
+    sc_signal<int>          r_vci_rsp_fsm;
+    sc_signal<size_t>       r_vci_rsp_cpt;
+    sc_signal<bool>         r_vci_rsp_ins_error;
+    sc_signal<bool>         r_vci_rsp_data_error;
+    sc_signal<bool>         r_dcache_tlb_sc_fail;
+
+    data_t                  *r_icache_miss_buf;    
+    data_t                  *r_dcache_miss_buf;  
+
+    sc_signal<int>          r_cleanup_cmd_fsm;
+    sc_signal<int>          r_cleanup_rsp_fsm;
+
+    // VCI_TGT FSM REGISTERS
+    data_t                  *r_tgt_buf;
+    bool                    *r_tgt_val;
+
+    sc_signal<int>          r_vci_tgt_fsm;
+    sc_signal<paddr_t>      r_tgt_addr;
+    sc_signal<size_t>       r_tgt_word;
+    sc_signal<bool>         r_tgt_update;
+    sc_signal<vci_srcid_t>  r_tgt_srcid;
+    sc_signal<vci_pktid_t>  r_tgt_pktid;
+    sc_signal<vci_trdid_t>  r_tgt_trdid;
+    sc_signal<vci_plen_t>   r_tgt_plen;
+    sc_signal<bool>         r_tgt_req;
+    sc_signal<bool>         r_tgt_icache_req;
+    sc_signal<bool>         r_tgt_dcache_req;
+    sc_signal<bool>         r_tgt_icache_rsp;
+    sc_signal<bool>         r_tgt_dcache_rsp;
+
+    // INVAL CHECK FSM
+    sc_signal<int>          r_inval_itlb_fsm;          
+    sc_signal<bool>         r_dcache_itlb_inval_req;
+    sc_signal<paddr_t>      r_dcache_itlb_inval_line;
+    sc_signal<bool>         r_itlb_cc_check_end;
+    sc_signal<size_t>       r_ccinval_itlb_way; 
+    sc_signal<size_t>       r_ccinval_itlb_set; 
+    sc_signal<bool>         r_icache_inval_tlb_rsp;
+    sc_signal<paddr_t>      r_icache_tlb_nline;
+
+    sc_signal<int>          r_inval_dtlb_fsm;          
+    sc_signal<bool>         r_dcache_dtlb_inval_req;
+    sc_signal<paddr_t>      r_dcache_dtlb_inval_line;
+    sc_signal<bool>         r_dtlb_cc_check_end;
+    sc_signal<size_t>       r_ccinval_dtlb_way; 
+    sc_signal<size_t>       r_ccinval_dtlb_set; 
+    sc_signal<bool>         r_dcache_inval_tlb_rsp;
+    sc_signal<paddr_t>      r_dcache_tlb_nline;
+
+    sc_signal<bool>         r_dcache_itlb_cleanup_req;
+    sc_signal<paddr_t>      r_dcache_itlb_cleanup_line;
+
+    sc_signal<bool>         r_dcache_dtlb_cleanup_req;
+    sc_signal<paddr_t>      r_dcache_dtlb_cleanup_line;
+
+    sc_signal<bool>         r_itlb_inval_req;
+    sc_signal<bool>         r_dcache_cc_check;
+
+    WriteBuffer<paddr_t>     r_wbuf;
+    GenericCache<paddr_t>    r_icache;
+    GenericCache<paddr_t>    r_dcache;
+
+    uint32_t m_proc_id;
+
+    // Activity counters
+    uint32_t m_cpt_dcache_data_read;        // DCACHE DATA READ
+    uint32_t m_cpt_dcache_data_write;       // DCACHE DATA WRITE
+    uint32_t m_cpt_dcache_dir_read;         // DCACHE DIR READ
+    uint32_t m_cpt_dcache_dir_write;        // DCACHE DIR WRITE
+
+    uint32_t m_cpt_icache_data_read;        // ICACHE DATA READ
+    uint32_t m_cpt_icache_data_write;       // ICACHE DATA WRITE
+    uint32_t m_cpt_icache_dir_read;         // ICACHE DIR READ
+    uint32_t m_cpt_icache_dir_write;        // ICACHE DIR WRITE
+
+    uint32_t m_cpt_frz_cycles;	            // number of cycles where the cpu is frozen
+    uint32_t m_cpt_total_cycles;	        // total number of cycles
+    uint32_t m_cpt_dcache_frz_cycles;       // number of cycles where the data cache is frozen    
+
+    // Cache activity counters
+    uint32_t m_cpt_read;                    // total number of read data
+    uint32_t m_cpt_write;                   // total number of write data
+    uint32_t m_cpt_data_miss;               // number of read miss
+    uint32_t m_cpt_ins_miss;                // number of instruction miss
+    uint32_t m_cpt_unc_read;                // number of read uncached
+    uint32_t m_cpt_write_cached;            // number of cached write
+    uint32_t m_cpt_ins_read;                // number of instruction read
+
+    uint32_t m_cost_write_frz;              // number of frozen cycles related to write buffer         
+    uint32_t m_cost_data_miss_frz;          // number of frozen cycles related to data miss
+    uint32_t m_cost_unc_read_frz;           // number of frozen cycles related to uncached read
+    uint32_t m_cost_ins_miss_frz;           // number of frozen cycles related to ins miss
+
+    uint32_t m_cpt_imiss_transaction;       // number of VCI instruction miss transactions
+    uint32_t m_cpt_dmiss_transaction;       // number of VCI data miss transactions
+    uint32_t m_cpt_unc_transaction;         // number of VCI uncached read transactions
+    uint32_t m_cpt_write_transaction;       // number of VCI write transactions
+    uint32_t m_cpt_icache_unc_transaction;
+
+    uint32_t m_cost_imiss_transaction;      // cumulated duration for VCI IMISS transactions
+    uint32_t m_cost_dmiss_transaction;      // cumulated duration for VCI DMISS transactions
+    uint32_t m_cost_unc_transaction;        // cumulated duration for VCI UNC transactions
+    uint32_t m_cost_write_transaction;      // cumulated duration for VCI WRITE transactions
+    uint32_t m_cost_icache_unc_transaction; // cumulated duration for VCI IUNC transactions    
+    uint32_t m_length_write_transaction;    // cumulated length for VCI WRITE transactions
+
+    // TLB activity counters
+    uint32_t m_cpt_ins_tlb_read;            // number of instruction tlb read
+    uint32_t m_cpt_ins_tlb_miss;            // number of instruction tlb miss
+    uint32_t m_cpt_ins_tlb_update_acc;      // number of instruction tlb update acc
+    uint32_t m_cpt_data_tlb_read;           // number of data tlb read
+    uint32_t m_cpt_data_tlb_miss;           // number of data tlb miss
+    uint32_t m_cpt_data_tlb_update_acc;     // number of data tlb update acc
+    uint32_t m_cpt_data_tlb_update_dirty;   // number of data tlb update dirty
+    uint32_t m_cpt_ins_tlb_hit_dcache;      // number of instruction tlb hit in data cache
+    uint32_t m_cpt_data_tlb_hit_dcache;     // number of data tlb hit in data cache
+    uint32_t m_cpt_ins_tlb_occup_cache;     // number of instruction tlb occupy data cache line 
+    uint32_t m_cpt_data_tlb_occup_cache;    // number of data tlb occupy data cache line
+    uint32_t m_cpt_tlb_occup_dcache;
+    
+    uint32_t m_cost_ins_tlb_miss_frz;       // number of frozen cycles related to instruction tlb miss
+    uint32_t m_cost_data_tlb_miss_frz;      // number of frozen cycles related to data tlb miss
+    uint32_t m_cost_ins_tlb_update_acc_frz;    // number of frozen cycles related to instruction tlb update acc
+    uint32_t m_cost_data_tlb_update_acc_frz;   // number of frozen cycles related to data tlb update acc
+    uint32_t m_cost_data_tlb_update_dirty_frz; // number of frozen cycles related to data tlb update dirty
+    uint32_t m_cost_ins_tlb_occup_cache_frz;   // number of frozen cycles related to instruction tlb miss operate in dcache
+    uint32_t m_cost_data_tlb_occup_cache_frz;  // number of frozen cycles related to data tlb miss operate in dcache
+
+    uint32_t m_cpt_itlbmiss_transaction;       // number of itlb miss transactions
+    uint32_t m_cpt_itlb_ll_transaction;        // number of itlb ll acc transactions
+    uint32_t m_cpt_itlb_sc_transaction;        // number of itlb sc acc transactions
+    uint32_t m_cpt_dtlbmiss_transaction;       // number of dtlb miss transactions
+    uint32_t m_cpt_dtlb_ll_transaction;        // number of dtlb ll acc transactions
+    uint32_t m_cpt_dtlb_sc_transaction;        // number of dtlb sc acc transactions
+    uint32_t m_cpt_dtlb_ll_dirty_transaction;  // number of dtlb ll dirty transactions
+    uint32_t m_cpt_dtlb_sc_dirty_transaction;  // number of dtlb sc dirty transactions
+
+    uint32_t m_cost_itlbmiss_transaction;     // cumulated duration for VCI instruction TLB miss transactions
+    uint32_t m_cost_itlb_ll_transaction;      // cumulated duration for VCI instruction TLB ll acc transactions
+    uint32_t m_cost_itlb_sc_transaction;      // cumulated duration for VCI instruction TLB sc acc transactions
+    uint32_t m_cost_dtlbmiss_transaction;     // cumulated duration for VCI data TLB miss transactions
+    uint32_t m_cost_dtlb_ll_transaction;      // cumulated duration for VCI data TLB ll acc transactions
+    uint32_t m_cost_dtlb_sc_transaction;      // cumulated duration for VCI data TLB sc acc transactions
+    uint32_t m_cost_dtlb_ll_dirty_transaction;// cumulated duration for VCI data TLB ll dirty transactions
+    uint32_t m_cost_dtlb_sc_dirty_transaction;// cumulated duration for VCI data TLB sc dirty transactions
+
+    uint32_t m_cpt_cc_update_data;              // number of coherence update data packets 
+    uint32_t m_cpt_cc_inval_ins;                // number of coherence inval instruction packets
+    uint32_t m_cpt_cc_inval_data;               // number of coherence inval data packets
+    uint32_t m_cpt_cc_broadcast;                // number of coherence broadcast packets
+    
+    uint32_t m_cost_updt_data_frz;              // number of frozen cycles related to coherence update data packets
+    uint32_t m_cost_inval_ins_frz;              // number of frozen cycles related to coherence inval instruction packets
+    uint32_t m_cost_inval_data_frz;             // number of frozen cycles related to coherence inval data packets
+    uint32_t m_cost_broadcast_frz;              // number of frozen cycles related to coherence broadcast packets
+
+    uint32_t m_cpt_cc_cleanup_ins;              // number of coherence cleanup packets
+    uint32_t m_cpt_cc_cleanup_data;             // number of coherence cleanup packets
+
+    uint32_t m_cpt_icleanup_transaction;        // number of instruction cleanup transactions
+    uint32_t m_cpt_dcleanup_transaction;        // number of instructinumber of data cleanup transactions
+    uint32_t m_cost_icleanup_transaction;       // cumulated duration for VCI instruction cleanup transactions
+    uint32_t m_cost_dcleanup_transaction;       // cumulated duration for VCI data cleanup transactions
+
+    uint32_t m_cost_ins_tlb_inval_frz;      // number of frozen cycles related to checking ins tlb invalidate
+    uint32_t m_cpt_ins_tlb_inval;           // number of ins tlb invalidate
+
+    uint32_t m_cost_data_tlb_inval_frz;     // number of frozen cycles related to checking data tlb invalidate    
+    uint32_t m_cpt_data_tlb_inval;          // number of data tlb invalidate
+    
+    size_t m_tm_start;
+    size_t m_tm_end;
+    size_t m_period;
+
+public:
+    std::ofstream m_log;    
+    
+protected:
+    SC_HAS_PROCESS(VciCcVCacheWrapper2V1);
+
+public:
+    VciCcVCacheWrapper2V1(
+        sc_module_name insname,
+        int proc_id,
+        const soclib::common::MappingTable &mtp,
+        const soclib::common::MappingTable &mtc,
+        const soclib::common::IntTab &initiator_index_rw,
+        const soclib::common::IntTab &initiator_index_c,
+        const soclib::common::IntTab &target_index,
+        size_t itlb_ways,
+        size_t itlb_sets,
+        size_t dtlb_ways,
+        size_t dtlb_sets,
+        size_t icache_ways,
+        size_t icache_sets,
+        size_t icache_words,
+        size_t dcache_ways,
+        size_t dcache_sets,
+        size_t dcache_words,
+        size_t write_buf_size );
+
+    ~VciCcVCacheWrapper2V1();
+
+    void print_cpi();
+    void print_stats();
+    void clear_stats();
+    void print_trace(size_t mode = 0);
+
+private:
+    void transition();
+    void genMoore();
+
+    soclib_static_assert((int)iss_t::SC_ATOMIC == (int)vci_param::STORE_COND_ATOMIC);
+    soclib_static_assert((int)iss_t::SC_NOT_ATOMIC == (int)vci_param::STORE_COND_NOT_ATOMIC);
+};
+
+}}
+
+#endif /* SOCLIB_CABA_VCI_CC_VCACHE_WRAPPER2_V1_H */
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
+
+
+
Index: trunk/platforms/almos-tsarv3-platforms/common/vci_cc_vcache_wrapper2_v1/caba/source/src/vci_cc_vcache_wrapper2_v1.cpp
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/vci_cc_vcache_wrapper2_v1/caba/source/src/vci_cc_vcache_wrapper2_v1.cpp	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/vci_cc_vcache_wrapper2_v1/caba/source/src/vci_cc_vcache_wrapper2_v1.cpp	(revision 259)
@@ -0,0 +1,6470 @@
+/* -*- c++ -*-
+ * File : vci_cc_vcache_wrapper2_v1.cpp
+ * Copyright (c) UPMC, Lip6, SoC
+ * Authors : Alain GREINER, Yang GAO
+ *
+ * SOCLIB_LGPL_HEADER_BEGIN
+ * 
+ * This file is part of SoCLib, GNU LGPLv2.1.
+ * 
+ * SoCLib is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 of the License.
+ * 
+ * SoCLib is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with SoCLib; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ * 
+ * SOCLIB_LGPL_HEADER_END
+ */
+
+#include <cassert>
+#include "arithmetics.h"
+#include "../include/vci_cc_vcache_wrapper2_v1.h"
+
+namespace soclib { 
+namespace caba {
+
+//#define SOCLIB_MODULE_DEBUG
+//#define EVALUATION_CACHE
+
+//#ifdef SOCLIB_MODULE_DEBUG
+namespace {
+const char *icache_fsm_state_str[] = {
+        "ICACHE_IDLE",
+        "ICACHE_BIS",       
+        "ICACHE_TLB1_READ",  
+        "ICACHE_TLB1_WRITE",
+        "ICACHE_TLB1_UPDT_SEL",  
+        "ICACHE_TLB1_UPDT",  
+        "ICACHE_TLB2_READ",  
+        "ICACHE_TLB2_WRITE",
+        "ICACHE_TLB2_UPDT_SEL",  
+        "ICACHE_TLB2_UPDT",  
+        "ICACHE_SW_FLUSH", 
+        "ICACHE_TLB_FLUSH", 
+        "ICACHE_CACHE_FLUSH", 
+        "ICACHE_TLB_INVAL",  
+        "ICACHE_CACHE_INVAL",
+        "ICACHE_CACHE_INVAL_PA",
+        "ICACHE_MISS_WAIT",
+        "ICACHE_UNC_WAIT",  
+        "ICACHE_MISS_UPDT",  
+        "ICACHE_ERROR", 
+        "ICACHE_CC_INVAL", 
+        "ICACHE_TLB_CC_INVAL",        
+    };
+const char *dcache_fsm_state_str[] = {
+        "DCACHE_IDLE",       
+        "DCACHE_BIS",   
+        "DCACHE_DTLB1_READ_CACHE",
+        "DCACHE_TLB1_LL_WAIT",
+        "DCACHE_TLB1_SC_WAIT",    
+        "DCACHE_TLB1_READ",
+        "DCACHE_TLB1_READ_UPDT",
+        "DCACHE_TLB1_UPDT_SEL",  
+        "DCACHE_TLB1_UPDT", 
+        "DCACHE_DTLB2_READ_CACHE", 
+        "DCACHE_TLB2_LL_WAIT",
+        "DCACHE_TLB2_SC_WAIT",   
+        "DCACHE_TLB2_READ",
+        "DCACHE_TLB2_READ_UPDT",  
+        "DCACHE_TLB2_UPDT_SEL",
+        "DCACHE_TLB2_UPDT",   
+        "DCACHE_CTXT_SWITCH",   
+        "DCACHE_ICACHE_FLUSH", 
+        "DCACHE_DCACHE_FLUSH", 
+        "DCACHE_ITLB_INVAL",
+        "DCACHE_DTLB_INVAL",
+        "DCACHE_ICACHE_INVAL",
+        "DCACHE_DCACHE_INVAL",
+        "DCACHE_ICACHE_INVAL_PA",
+        "DCACHE_DCACHE_INVAL_PA",
+        "DCACHE_DCACHE_SYNC",
+        "DCACHE_LL_DIRTY_WAIT",
+        "DCACHE_SC_DIRTY_WAIT",
+        "DCACHE_WRITE_UPDT", 
+        "DCACHE_WRITE_DIRTY",
+        "DCACHE_WRITE_REQ",  
+        "DCACHE_MISS_WAIT",  
+        "DCACHE_MISS_UPDT",  
+        "DCACHE_UNC_WAIT",   
+        "DCACHE_ERROR", 
+        "DCACHE_ITLB_READ",
+        "DCACHE_ITLB_UPDT",
+        "DCACHE_ITLB_LL_WAIT",        
+        "DCACHE_ITLB_SC_WAIT",        
+        "DCACHE_CC_CHECK",
+        "DCACHE_CC_INVAL",
+        "DCACHE_CC_UPDT",
+        "DCACHE_CC_NOP",
+        "DCACHE_TLB_CC_INVAL",
+        "DCACHE_ITLB_CLEANUP",
+    };
+const char *cmd_fsm_state_str[] = {
+        "CMD_IDLE",           
+        "CMD_ITLB_READ", 
+        "CMD_ITLB_ACC_LL",                
+        "CMD_ITLB_ACC_SC",                
+        "CMD_INS_MISS",     
+        "CMD_INS_UNC",     
+        "CMD_DTLB_READ",   
+        "CMD_DTLB_ACC_LL",            
+        "CMD_DTLB_ACC_SC",            
+        "CMD_DTLB_DIRTY_LL",          
+        "CMD_DTLB_DIRTY_SC",          
+        "CMD_DATA_UNC",     
+        "CMD_DATA_MISS",    
+        "CMD_DATA_WRITE", 
+    };
+const char *rsp_fsm_state_str[] = {
+        "RSP_IDLE",                  
+        "RSP_ITLB_READ",             
+        "RSP_ITLB_ACC_LL",                
+        "RSP_ITLB_ACC_SC",                
+        "RSP_INS_MISS",   
+        "RSP_INS_UNC",           
+        "RSP_DTLB_READ",            
+        "RSP_DTLB_ACC_LL",            
+        "RSP_DTLB_ACC_SC",            
+        "RSP_DTLB_DIRTY_LL",          
+        "RSP_DTLB_DIRTY_SC",          
+        "RSP_DATA_MISS",             
+        "RSP_DATA_UNC",              
+        "RSP_DATA_WRITE",     
+    };
+const char *cleanup_cmd_fsm_state_str[] = {
+        "CLEANUP_CMD_IDLE",           
+        "CLEANUP_CMD_DATA",    
+        "CLEANUP_CMD_INS",      
+    };
+const char *cleanup_rsp_fsm_state_str[] = {
+        "CLEANUP_RSP_IDLE",           
+        "CLEANUP_RSP_DATA",    
+        "CLEANUP_RSP_INS",      
+    };
+const char *tgt_fsm_state_str[] = {
+        "TGT_IDLE",
+        "TGT_UPDT_WORD",
+        "TGT_UPDT_DATA",
+        "TGT_REQ_BROADCAST",
+        "TGT_REQ_ICACHE",
+        "TGT_REQ_DCACHE",
+        "TGT_RSP_BROADCAST",
+        "TGT_RSP_ICACHE",
+        "TGT_RSP_DCACHE",
+    };	
+const char *inval_itlb_fsm_state_str[] = {
+        "INVAL_ITLB_IDLE",        
+        "INVAL_ITLB_CHECK"  , 
+        "INVAL_ITLB_INVAL",      
+        "INVAL_ITLB_CLEAR",           
+    };
+const char *inval_dtlb_fsm_state_str[] = {
+        "INVAL_DTLB_IDLE",        
+        "INVAL_DTLB_CHECK", 
+        "INVAL_DTLB_INVAL",    
+        "INVAL_DTLB_CLEAR",         
+    };
+}
+//#endif
+
+#define tmpl(...)  template<typename vci_param, typename iss_t> __VA_ARGS__ VciCcVCacheWrapper2V1<vci_param, iss_t>
+
+using soclib::common::uint32_log2;
+
+/***********************************************/
+tmpl(/**/)::VciCcVCacheWrapper2V1(
+    sc_module_name name,
+    int proc_id,
+    const soclib::common::MappingTable &mtp,
+    const soclib::common::MappingTable &mtc,
+    const soclib::common::IntTab &initiator_index_rw,
+    const soclib::common::IntTab &initiator_index_c,
+    const soclib::common::IntTab &target_index,
+    size_t itlb_ways,
+    size_t itlb_sets,
+    size_t dtlb_ways,
+    size_t dtlb_sets,
+    size_t icache_ways,
+    size_t icache_sets,
+    size_t icache_words,
+    size_t dcache_ways,
+    size_t dcache_sets,
+    size_t dcache_words,
+    size_t write_buf_size )
+/***********************************************/
+    : soclib::caba::BaseModule(name),
+
+      p_clk("clk"),
+      p_resetn("resetn"),
+      p_vci_ini_rw("vci_ini_rw"),
+      p_vci_ini_c("vci_ini_c"),
+      p_vci_tgt("vci_tgt"),
+
+      m_cacheability_table(mtp.getCacheabilityTable()),
+      m_segment(mtc.getSegment(target_index)),
+      m_iss(this->name(), proc_id),
+      m_srcid_rw(mtp.indexForId(initiator_index_rw)),
+      m_srcid_c(mtp.indexForId(initiator_index_c)),
+
+      m_itlb_ways(itlb_ways),
+      m_itlb_sets(itlb_sets),
+
+      m_dtlb_ways(dtlb_ways),
+      m_dtlb_sets(dtlb_sets),
+
+      m_icache_ways(icache_ways),
+      m_icache_sets(icache_sets),
+      m_icache_yzmask((~0)<<(uint32_log2(icache_words) + 2)),
+      m_icache_words(icache_words),
+
+      m_dcache_ways(dcache_ways),
+      m_dcache_sets(dcache_sets),
+      m_dcache_yzmask((~0)<<(uint32_log2(dcache_words) + 2)),
+      m_dcache_words(dcache_words),
+
+      m_write_buf_size(write_buf_size),	
+      m_paddr_nbits(vci_param::N),
+
+      icache_tlb(itlb_ways,itlb_sets,vci_param::N),
+      dcache_tlb(dtlb_ways,dtlb_sets,vci_param::N),
+
+      r_dcache_fsm("r_dcache_fsm"),
+      r_dcache_paddr_save("r_dcache_paddr_save"),
+      r_dcache_wdata_save("r_dcache_wdata_save"),
+      r_dcache_rdata_save("r_dcache_rdata_save"),
+      r_dcache_type_save("r_dcache_type_save"),
+      r_dcache_be_save("r_dcache_be_save"),
+      r_dcache_cached_save("r_dcache_cached_save"),
+      r_dcache_tlb_paddr("r_dcache_tlb_paddr"),
+      r_dcache_miss_req("r_dcache_miss_req"),
+      r_dcache_unc_req("r_dcache_unc_req"),
+      r_dcache_write_req("r_dcache_write_req"),
+      r_dcache_tlb_read_req("r_dcache_tlb_read_req"),
+
+      r_dcache_tlb_ll_acc_req("r_dcache_tlb_ll_acc_req"),       
+      r_dcache_tlb_sc_acc_req("r_dcache_tlb_sc_acc_req"),       
+      r_dcache_tlb_ll_dirty_req("r_dcache_tlb_ll_dirty_req"),    
+      r_dcache_tlb_sc_dirty_req("r_dcache_tlb_sc_dirty_req"), 
+      r_dcache_tlb_ptba_read("r_dcache_tlb_ptba_read"),
+      r_dcache_xtn_req("r_dcache_xtn_req"),
+
+      r_dcache_fsm_save("r_dcache_fsm_save"),
+      r_dcache_cleanup_req("r_dcache_cleanup_req"),
+      r_dcache_inval_rsp("r_dcache_inval_rsp"),
+
+      r_icache_fsm("r_icache_fsm"),
+      r_icache_paddr_save("r_icache_paddr_save"),
+      r_icache_miss_req("r_icache_miss_req"),
+      r_icache_unc_req("r_icache_unc_req"),
+      r_dcache_itlb_read_req("r_dcache_itlb_read_req"),
+      r_dcache_itlb_ll_acc_req("r_dcache_itlb_ll_acc_req"),     
+      r_dcache_itlb_sc_acc_req("r_dcache_itlb_sc_acc_req"),
+
+      r_itlb_read_dcache_req("r_itlb_read_dcache_req"),
+      r_itlb_k_read_dcache("r_itlb_k_read_dcache"),
+      r_itlb_acc_dcache_req("r_itlb_acc_dcache_req"),
+      r_dcache_rsp_itlb_error("r_dcache_rsp_itlb_error"),
+
+      r_icache_fsm_save("r_icache_fsm_save"),
+      r_icache_cleanup_req("r_icache_cleanup_req"),
+      r_icache_inval_rsp("r_icache_inval_rsp"),
+
+      r_vci_cmd_fsm("r_vci_cmd_fsm"),
+      r_vci_cmd_min("r_vci_cmd_min"),
+      r_vci_cmd_max("r_vci_cmd_max"),
+      r_vci_cmd_cpt("r_vci_cmd_cpt"),
+
+      r_vci_rsp_fsm("r_vci_rsp_fsm"),
+      r_vci_rsp_cpt("r_vci_rsp_cpt"),
+      r_vci_rsp_ins_error("r_vci_rsp_ins_error"),
+      r_vci_rsp_data_error("r_vci_rsp_data_error"),
+      r_dcache_tlb_sc_fail("r_dcache_tlb_sc_fail"),
+
+      r_cleanup_cmd_fsm("r_cleanup_cmd_fsm"),
+      r_cleanup_rsp_fsm("r_cleanup_rsp_fsm"),
+
+      r_vci_tgt_fsm("r_vci_tgt_fsm"),
+      r_tgt_addr("r_tgt_addr"),
+      r_tgt_word("r_tgt_word"),
+      r_tgt_update("r_tgt_update"),
+      r_tgt_srcid("r_tgt_srcid"),
+      r_tgt_pktid("r_tgt_pktid"),
+      r_tgt_trdid("r_tgt_trdid"),
+      r_tgt_icache_req("r_tgt_icache_req"),
+      r_tgt_dcache_req("r_tgt_dcache_req"),
+
+      r_inval_itlb_fsm("r_inval_itlb_fsm"),          
+      r_dcache_itlb_inval_req("r_dcache_itlb_inval_req"),
+      r_dcache_itlb_inval_line("r_dcache_itlb_inval_line"),
+      r_itlb_cc_check_end("r_itlb_cc_check_end"),
+      r_ccinval_itlb_way("r_ccinval_itlb_way"), 
+      r_ccinval_itlb_set("r_ccinval_itlb_set"), 
+      r_icache_inval_tlb_rsp("r_icache_inval_tlb_rsp"),
+      r_icache_tlb_nline("r_icache_tlb_nline"),
+
+      r_inval_dtlb_fsm("r_inval_dtlb_fsm"),          
+      r_dcache_dtlb_inval_req("r_dcache_dtlb_inval_req"),
+      r_dcache_dtlb_inval_line("r_dcache_dtlb_inval_line"),
+      r_dtlb_cc_check_end("r_dtlb_cc_check_end"),
+      r_ccinval_dtlb_way("r_ccinval_dtlb_way"), 
+      r_ccinval_dtlb_set("r_ccinval_dtlb_set"), 
+      r_dcache_inval_tlb_rsp("r_dcache_inval_tlb_rsp"),
+      r_dcache_tlb_nline("r_dcache_tlb_nline"),
+
+      r_dcache_itlb_cleanup_req("r_dcache_itlb_cleanup_req"),
+      r_dcache_itlb_cleanup_line("r_dcache_itlb_cleanup_line"),
+
+      r_dcache_dtlb_cleanup_req("r_dcache_dtlb_cleanup_req"),
+      r_dcache_dtlb_cleanup_line("r_dcache_dtlb_cleanup_line"),
+
+      r_wbuf("wbuf", write_buf_size ),
+      r_icache("icache", icache_ways, icache_sets, icache_words),
+      r_dcache("dcache", dcache_ways, dcache_sets, dcache_words)
+{
+    r_icache_miss_buf = new data_t[icache_words];
+    r_dcache_miss_buf = new data_t[dcache_words];
+    r_tgt_buf         = new data_t[dcache_words];
+    r_tgt_val         = new bool[dcache_words];
+    r_dcache_in_itlb  = new bool[dcache_ways*dcache_sets];           
+    r_dcache_in_dtlb  = new bool[dcache_ways*dcache_sets];          
+
+    m_proc_id = proc_id;
+
+    m_tm_start = 0;
+    m_tm_end = 0;
+    m_period = 0;
+    
+    char *ptr;
+    
+    ptr = getenv("TSAR_L1_TM_START");
+    
+    if(ptr != NULL)
+        m_tm_start = (size_t) atol(ptr);
+    
+    ptr = getenv("TSAR_L1_TM_END");
+    
+    if(ptr != NULL)
+        m_tm_end = (size_t) atol(ptr);
+    
+    ptr = getenv("TSAR_L1_PERIOD");
+    
+    if(ptr != NULL)
+        m_period = (size_t) atol(ptr);
+    
+    if(m_period != 0)
+        m_log.open(name, std::ios::out);
+    else
+        m_log.open("/dev/null", std::ios::out);
+    
+    if(m_proc_id == 0)
+    {
+        std::cout << "TSAR_L1_TM_START =" << m_tm_start << std::endl
+                  << "TSAR_L1_TM_END   =" << m_tm_end << std::endl
+                  << "TSAR_L1_PERIOD   =" << m_period << std::endl;
+    }
+
+    SC_METHOD(transition);
+    dont_initialize();
+    sensitive << p_clk.pos();
+  
+    SC_METHOD(genMoore);
+    dont_initialize();
+    sensitive << p_clk.neg();
+
+    typename iss_t::CacheInfo cache_info;
+    cache_info.has_mmu = true;
+    cache_info.icache_line_size = icache_words*sizeof(data_t);
+    cache_info.icache_assoc = icache_ways;
+    cache_info.icache_n_lines = icache_sets;
+    cache_info.dcache_line_size = dcache_words*sizeof(data_t);
+    cache_info.dcache_assoc = dcache_ways;
+    cache_info.dcache_n_lines = dcache_sets;
+    m_iss.setCacheInfo(cache_info);
+}
+
+/////////////////////////////////////
+tmpl(/**/)::~VciCcVCacheWrapper2V1()
+/////////////////////////////////////
+{
+    delete [] r_icache_miss_buf;
+    delete [] r_dcache_miss_buf;
+    delete [] r_tgt_val;
+    delete [] r_tgt_buf;
+    delete [] r_dcache_in_itlb;           
+    delete [] r_dcache_in_dtlb;          
+}
+
+////////////////////////
+tmpl(void)::print_cpi()
+////////////////////////
+{
+    std::cout << name() << " CPI = " 
+        << (float)m_cpt_total_cycles/(m_cpt_total_cycles - m_cpt_frz_cycles) << std::endl ;
+}
+
+////////////////////////////////////
+tmpl(void)::print_trace(size_t mode)
+////////////////////////////////////
+{
+    typename iss_t::InstructionRequest  ireq;
+    typename iss_t::DataRequest         dreq;
+
+    std::ostream  &output = m_log;
+
+    m_iss.getRequests( ireq, dreq );
+   
+    output << std::dec << "L1_(" << name() << ") cycle: " << m_cpt_total_cycles << std::endl;
+    output << " Proc state: PC = " << std::hex << ireq.addr << " / AD = " << dreq.addr 
+              << std::dec << " / V = " << dreq.valid << " / TYPE = " << dreq.type << std::endl;
+    
+    output << " Cache state:"
+              << " tgt fsm: " << tgt_fsm_state_str[r_vci_tgt_fsm]
+              << " dcache fsm: " << dcache_fsm_state_str[r_dcache_fsm]
+              << " icache fsm: " << icache_fsm_state_str[r_icache_fsm]
+              << " cmd fsm: " << cmd_fsm_state_str[r_vci_cmd_fsm]
+              << " rsp fsm: " << rsp_fsm_state_str[r_vci_rsp_fsm] 
+              << " cleanup cmd fsm: " << cleanup_cmd_fsm_state_str[r_cleanup_cmd_fsm]
+              << " cleanup rsp fsm: " << cleanup_rsp_fsm_state_str[r_cleanup_rsp_fsm]
+              << " inval itlb fsm: " << inval_itlb_fsm_state_str[r_inval_itlb_fsm] 
+              << " inval dtlb fsm: " << inval_dtlb_fsm_state_str[r_inval_dtlb_fsm] << std::endl;
+
+    if( r_vci_tgt_fsm != TGT_IDLE ) 
+        output << "    ... coherence request address = " << std::hex << r_tgt_addr.read() << std::endl;
+    
+    if(mode & 0x1)
+    {
+        r_wbuf.printTrace();
+    }
+}
+
+////////////////////////
+tmpl(void)::print_stats()
+////////////////////////
+{
+    std::ostream  &output = m_log;
+
+    float run_cycles = (float)(m_cpt_total_cycles - m_cpt_frz_cycles);
+    output << name() << std::endl
+              << "CPI                     = " << (float)m_cpt_total_cycles/run_cycles << std::endl 
+              << "READ_RATE               = " << (float)m_cpt_read/run_cycles << std::endl 
+              << "WRITE_RATE              = " << (float)m_cpt_write/run_cycles << std::endl
+              << "IMISS_RATE              = " << (float)m_cpt_ins_miss/m_cpt_ins_read << std::endl
+              << "DMISS_RATE              = " << (float)m_cpt_data_miss/(m_cpt_read-m_cpt_unc_read) << std::endl  
+              << "INS_MISS_COST           = " << (float)m_cost_ins_miss_frz/m_cpt_ins_miss << std::endl     
+              << "DATA_MISS_COST          = " << (float)m_cost_data_miss_frz/m_cpt_data_miss << std::endl 
+              << "WRITE_COST              = " << (float)m_cost_write_frz/m_cpt_write << std::endl        
+              << "UNC_COST                = " << (float)m_cost_unc_read_frz/m_cpt_unc_read << std::endl
+              << "UNCACHED_READ_RATE      = " << (float)m_cpt_unc_read/m_cpt_read << std::endl 
+              << "CACHED_WRITE_RATE       = " << (float)m_cpt_write_cached/m_cpt_write << std::endl 
+              << "INS_TLB_MISS_RATE       = " << (float)m_cpt_ins_tlb_miss/m_cpt_ins_tlb_read << std::endl
+              << "DATA_TLB_MISS_RATE      = " << (float)m_cpt_data_tlb_miss/m_cpt_data_tlb_read << std::endl
+              << "ITLB_MISS_COST          = " << (float)m_cost_ins_tlb_miss_frz/m_cpt_ins_tlb_miss << std::endl
+              << "DTLB_MISS_COST          = " << (float)m_cost_data_tlb_miss_frz/m_cpt_data_tlb_miss << std::endl   
+              << "ITLB_UPDATE_ACC_COST    = " << (float)m_cost_ins_tlb_update_acc_frz/m_cpt_ins_tlb_update_acc << std::endl
+              << "DTLB_UPDATE_ACC_COST    = " << (float)m_cost_data_tlb_update_acc_frz/m_cpt_data_tlb_update_acc << std::endl
+              << "DTLB_UPDATE_DIRTY_COST  = " << (float)m_cost_data_tlb_update_dirty_frz/m_cpt_data_tlb_update_dirty << std::endl
+              << "ITLB_HIT_IN_DCACHE_RATE = " << (float)m_cpt_ins_tlb_hit_dcache/m_cpt_ins_tlb_miss << std::endl
+              << "DTLB_HIT_IN_DCACHE_RATE = " << (float)m_cpt_data_tlb_hit_dcache/m_cpt_data_tlb_miss << std::endl
+              << "DCACHE FROZEN BY ITLB   = " << (float)m_cost_ins_tlb_occup_cache_frz/m_cpt_dcache_frz_cycles << std::endl
+              << "DCACHE_FOR_TLB_%        = " << (float)m_cpt_tlb_occup_dcache/(m_dcache_ways*m_dcache_sets) << std::endl
+              << "NB_CC_BROADCAST         = " << m_cpt_cc_broadcast << std::endl
+              << "NB_CC_UPDATE_DATA       = " << m_cpt_cc_update_data << std::endl
+              << "NB_CC_INVAL_DATA        = " << m_cpt_cc_inval_data << std::endl
+              << "NB_CC_INVAL_INS         = " << m_cpt_cc_inval_ins << std::endl
+              << "NB_CC_CLEANUP_DATA      = " << m_cpt_cc_cleanup_data << std::endl
+              << "NB_CC_CLEANUP_INS       = " << m_cpt_cc_cleanup_ins << std::endl
+              << "CC BROADCAST COST       = " << (float)m_cost_broadcast_frz/m_cpt_cc_broadcast << std::endl
+              << "CC UPDATE DATA COST     = " << (float)m_cost_updt_data_frz/m_cpt_cc_update_data << std::endl
+              << "CC INVAL DATA COST      = " << (float)m_cost_inval_data_frz/m_cpt_cc_inval_data << std::endl
+              << "CC INVAL INS COST       = " << (float)m_cost_inval_ins_frz/m_cpt_cc_inval_ins << std::endl
+              << "IMISS_TRANSACTION       = " << (float)m_cost_imiss_transaction/m_cpt_imiss_transaction << std::endl
+              << "DMISS_TRANSACTION       = " << (float)m_cost_dmiss_transaction/m_cpt_dmiss_transaction << std::endl
+              << "UNC_TRANSACTION         = " << (float)m_cost_unc_transaction/m_cpt_unc_transaction << std::endl
+              << "WRITE_TRANSACTION       = " << (float)m_cost_write_transaction/m_cpt_write_transaction << std::endl
+              << "WRITE_LENGTH            = " << (float)m_length_write_transaction/m_cpt_write_transaction << std::endl
+              << "ITLB_MISS_TRANSACTION   = " << (float)m_cost_itlbmiss_transaction/m_cpt_itlbmiss_transaction << std::endl
+              << "DTLB_MISS_TRANSACTION   = " << (float)m_cost_dtlbmiss_transaction/m_cpt_dtlbmiss_transaction << std::endl;
+}
+
+////////////////////////
+tmpl(void)::clear_stats()
+////////////////////////
+{
+    m_cpt_dcache_data_read  = 0;
+    m_cpt_dcache_data_write = 0;
+    m_cpt_dcache_dir_read   = 0;
+    m_cpt_dcache_dir_write  = 0;
+    m_cpt_icache_data_read  = 0;
+    m_cpt_icache_data_write = 0;
+    m_cpt_icache_dir_read   = 0;
+    m_cpt_icache_dir_write  = 0;
+    
+    m_cpt_frz_cycles        = 0;
+    m_cpt_dcache_frz_cycles = 0;
+    m_cpt_total_cycles      = 0;
+    
+    m_cpt_read         = 0;
+    m_cpt_write        = 0;
+    m_cpt_data_miss    = 0;
+    m_cpt_ins_miss     = 0;
+    m_cpt_unc_read     = 0;
+    m_cpt_write_cached = 0;
+    m_cpt_ins_read     = 0;
+    
+    m_cost_write_frz     = 0;
+    m_cost_data_miss_frz = 0;
+    m_cost_unc_read_frz  = 0;
+    m_cost_ins_miss_frz  = 0;
+    
+    m_cpt_imiss_transaction      = 0;
+    m_cpt_dmiss_transaction      = 0;
+    m_cpt_unc_transaction        = 0;
+    m_cpt_write_transaction      = 0;
+    m_cpt_icache_unc_transaction = 0;	
+    
+    m_cost_imiss_transaction      = 0;
+    m_cost_dmiss_transaction      = 0;
+    m_cost_unc_transaction        = 0;
+    m_cost_write_transaction      = 0;
+    m_cost_icache_unc_transaction = 0;
+    m_length_write_transaction    = 0;
+    
+    m_cpt_ins_tlb_read       = 0;             
+    m_cpt_ins_tlb_miss       = 0;             
+    m_cpt_ins_tlb_update_acc = 0;         
+    
+    m_cpt_data_tlb_read         = 0;           
+    m_cpt_data_tlb_miss         = 0;           
+    m_cpt_data_tlb_update_acc   = 0;       
+    m_cpt_data_tlb_update_dirty = 0;    
+    m_cpt_ins_tlb_hit_dcache    = 0;
+    m_cpt_data_tlb_hit_dcache   = 0;
+    m_cpt_ins_tlb_occup_cache   = 0;
+    m_cpt_data_tlb_occup_cache  = 0;
+    
+    m_cost_ins_tlb_miss_frz          = 0;      
+    m_cost_data_tlb_miss_frz         = 0;      
+    m_cost_ins_tlb_update_acc_frz    = 0;
+    m_cost_data_tlb_update_acc_frz   = 0;
+    m_cost_data_tlb_update_dirty_frz = 0;
+    m_cost_ins_tlb_occup_cache_frz   = 0;
+    m_cost_data_tlb_occup_cache_frz  = 0;
+    
+    m_cpt_itlbmiss_transaction      = 0;    
+    m_cpt_itlb_ll_transaction       = 0;  
+    m_cpt_itlb_sc_transaction       = 0;  
+    m_cpt_dtlbmiss_transaction      = 0;  
+    m_cpt_dtlb_ll_transaction       = 0;  
+    m_cpt_dtlb_sc_transaction       = 0;  
+    m_cpt_dtlb_ll_dirty_transaction = 0;  
+    m_cpt_dtlb_sc_dirty_transaction = 0;  
+    
+    m_cost_itlbmiss_transaction      = 0;   
+    m_cost_itlb_ll_transaction       = 0;  
+    m_cost_itlb_sc_transaction       = 0;  
+    m_cost_dtlbmiss_transaction      = 0;   
+    m_cost_dtlb_ll_transaction       = 0;   
+    m_cost_dtlb_sc_transaction       = 0;   
+    m_cost_dtlb_ll_dirty_transaction = 0;   
+    m_cost_dtlb_sc_dirty_transaction = 0;
+
+    m_cpt_cc_update_data = 0;
+    m_cpt_cc_inval_ins   = 0;
+    m_cpt_cc_inval_data  = 0;
+    m_cpt_cc_broadcast   = 0;
+
+    m_cost_updt_data_frz  = 0;
+    m_cost_inval_ins_frz  = 0;
+    m_cost_inval_data_frz = 0;
+    m_cost_broadcast_frz  = 0;
+
+    m_cpt_cc_cleanup_data = 0;
+    m_cpt_cc_cleanup_ins  = 0;
+}
+
+/*************************************************/
+tmpl(void)::transition()
+/*************************************************/
+{
+    if ( ! p_resetn.read() ) 
+    {
+        m_iss.reset();
+
+        r_dcache_fsm = DCACHE_IDLE;
+        r_icache_fsm = ICACHE_IDLE;
+        r_vci_cmd_fsm = CMD_IDLE;
+        r_vci_rsp_fsm = RSP_IDLE;
+        r_vci_tgt_fsm = TGT_IDLE;
+        r_inval_itlb_fsm = INVAL_ITLB_IDLE;          
+        r_inval_dtlb_fsm = INVAL_DTLB_IDLE;          
+        r_cleanup_cmd_fsm = CLEANUP_CMD_IDLE;
+        r_cleanup_rsp_fsm = CLEANUP_RSP_IDLE;
+
+        // write buffer & caches
+        r_wbuf.reset();
+        r_icache.reset();
+        r_dcache.reset();
+
+        icache_tlb.reset();    
+        dcache_tlb.reset();    
+
+        std::memset(r_dcache_in_itlb, 0, sizeof(*r_dcache_in_itlb)*m_icache_ways*m_icache_sets);
+        std::memset(r_dcache_in_dtlb, 0, sizeof(*r_dcache_in_dtlb)*m_dcache_ways*m_dcache_sets);
+
+        //r_mmu_mode = ALL_DEACTIVE;
+        r_mmu_mode = 0x3;
+        r_mmu_params = (uint32_log2(m_dtlb_ways) << 29)   | (uint32_log2(m_dtlb_sets) << 25)   |
+                       (uint32_log2(m_dcache_ways) << 22) | (uint32_log2(m_dcache_sets) << 18) |
+                       (uint32_log2(m_itlb_ways) << 15)   | (uint32_log2(m_itlb_sets) << 11)   |
+                       (uint32_log2(m_icache_ways) << 8)  | (uint32_log2(m_icache_sets) << 4)  |
+                       (uint32_log2(m_icache_words * 4));
+        r_mmu_release = (uint32_t)(1 << 16) | 0x1;
+
+        r_icache_miss_req         = false;
+        r_icache_unc_req          = false;
+        r_dcache_itlb_read_req    = false;
+
+        r_itlb_read_dcache_req    = false;      
+        r_itlb_k_read_dcache      = false;      
+        r_itlb_acc_dcache_req     = false;   
+        r_itlb_acc_redo_req 	  = false;
+        r_dcache_rsp_itlb_error   = false;
+ 
+        r_dcache_miss_req         = false;
+        r_dcache_unc_req          = false;
+        r_dcache_write_req        = false;
+        r_dcache_tlb_read_req     = false;
+        r_dcache_tlb_ptba_read    = false;
+        r_dcache_xtn_req          = false;
+        r_dcache_llsc_reserved    = false;
+
+        r_dcache_tlb_ll_acc_req   = false;    
+        r_dcache_tlb_sc_acc_req   = false;    
+        r_dcache_tlb_ll_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;   
+
+        r_icache_cleanup_req      = false;
+        r_dcache_cleanup_req      = false;
+
+        r_tgt_icache_req          = false;
+        r_tgt_dcache_req          = false;
+
+        r_icache_inval_rsp        = false;
+        r_dcache_inval_rsp        = false;
+
+        r_dcache_dirty_save       = false;
+        r_dcache_hit_p_save       = false;
+        r_dcache_cached_save      = false;
+
+        r_icache_buf_unc_valid    = false;
+        r_dcache_buf_unc_valid    = false;
+
+        r_vci_rsp_ins_error       = false;
+        r_vci_rsp_data_error      = false;
+
+        r_icache_id1_save         = 0;
+        r_icache_ppn_save         = 0;
+        r_icache_vpn_save         = 0;
+        r_itlb_translation_valid  = false;
+
+        r_dcache_id1_save         = 0;
+        r_dcache_ppn_save         = 0;
+        r_dcache_vpn_save         = 0;
+        r_dtlb_translation_valid  = false;
+
+        r_icache_ptba_ok          = false;
+        r_dcache_ptba_ok          = false;
+
+        r_icache_error_type       = MMU_NONE;
+        r_dcache_error_type       = MMU_NONE;
+
+        // coherence registers
+        r_icache_way              = 0;
+        r_icache_set              = 0;
+        r_icache_cleanup_req      = false;
+        r_icache_inval_rsp        = false;
+
+        r_dcache_way              = 0;
+        r_dcache_set              = 0;
+        r_dcache_cleanup_req      = false;
+        r_dcache_inval_rsp        = false;
+
+        r_itlb_inval_req 	  = false;
+        r_dcache_itlb_inval_req   = false;
+        r_itlb_cc_check_end       = false;
+        r_ccinval_itlb_way        = 0; 
+        r_ccinval_itlb_set        = 0; 
+        r_icache_inval_tlb_rsp    = false;
+
+        r_dcache_dtlb_inval_req   = false;
+        r_dtlb_cc_check_end       = false;
+        r_ccinval_dtlb_way        = 0; 
+        r_ccinval_dtlb_set        = 0; 
+        r_dcache_inval_tlb_rsp    = false;
+
+        r_dcache_itlb_cleanup_req = false;
+        r_dcache_dtlb_cleanup_req = false;
+
+        r_dcache_cc_check         = false;
+        r_dcache_tlb_sc_fail	  = false;
+
+        // activity counters
+        m_cpt_dcache_data_read  = 0;
+        m_cpt_dcache_data_write = 0;
+        m_cpt_dcache_dir_read   = 0;
+        m_cpt_dcache_dir_write  = 0;
+        m_cpt_icache_data_read  = 0;
+        m_cpt_icache_data_write = 0;
+        m_cpt_icache_dir_read   = 0;
+        m_cpt_icache_dir_write  = 0;
+
+        m_cpt_frz_cycles        = 0;
+        m_cpt_dcache_frz_cycles = 0;
+        m_cpt_total_cycles      = 0;
+
+        m_cpt_read         = 0;
+        m_cpt_write        = 0;
+        m_cpt_data_miss    = 0;
+        m_cpt_ins_miss     = 0;
+        m_cpt_unc_read     = 0;
+        m_cpt_write_cached = 0;
+        m_cpt_ins_read     = 0;
+
+        m_cost_write_frz     = 0;
+        m_cost_data_miss_frz = 0;
+        m_cost_unc_read_frz  = 0;
+        m_cost_ins_miss_frz  = 0;
+
+        m_cpt_imiss_transaction      = 0;
+        m_cpt_dmiss_transaction      = 0;
+        m_cpt_unc_transaction        = 0;
+        m_cpt_write_transaction      = 0;
+        m_cpt_icache_unc_transaction = 0;	
+
+        m_cost_imiss_transaction      = 0;
+        m_cost_dmiss_transaction      = 0;
+        m_cost_unc_transaction        = 0;
+        m_cost_write_transaction      = 0;
+        m_cost_icache_unc_transaction = 0;
+        m_length_write_transaction    = 0;
+
+        m_cpt_ins_tlb_read       = 0;             
+        m_cpt_ins_tlb_miss       = 0;             
+        m_cpt_ins_tlb_update_acc = 0;         
+
+        m_cpt_data_tlb_read         = 0;           
+        m_cpt_data_tlb_miss         = 0;           
+        m_cpt_data_tlb_update_acc   = 0;       
+        m_cpt_data_tlb_update_dirty = 0;    
+        m_cpt_ins_tlb_hit_dcache    = 0;
+        m_cpt_data_tlb_hit_dcache   = 0;
+        m_cpt_ins_tlb_occup_cache   = 0;
+        m_cpt_data_tlb_occup_cache  = 0;
+
+        m_cost_ins_tlb_miss_frz          = 0;      
+        m_cost_data_tlb_miss_frz         = 0;      
+        m_cost_ins_tlb_update_acc_frz    = 0;
+        m_cost_data_tlb_update_acc_frz   = 0;
+        m_cost_data_tlb_update_dirty_frz = 0;
+        m_cost_ins_tlb_occup_cache_frz   = 0;
+        m_cost_data_tlb_occup_cache_frz  = 0;
+
+    	m_cpt_ins_tlb_inval       = 0;           
+    	m_cpt_data_tlb_inval      = 0;          
+    	m_cost_ins_tlb_inval_frz  = 0;     
+    	m_cost_data_tlb_inval_frz = 0;         
+
+        m_cpt_cc_update_data = 0;
+        m_cpt_cc_inval_ins   = 0;
+        m_cpt_cc_inval_data  = 0;
+        m_cpt_cc_broadcast   = 0;
+        
+        m_cost_updt_data_frz  = 0;
+        m_cost_inval_ins_frz  = 0;
+        m_cost_inval_data_frz = 0;
+        m_cost_broadcast_frz  = 0;
+
+        m_cpt_cc_cleanup_data = 0;
+        m_cpt_cc_cleanup_ins  = 0;
+
+        m_cpt_itlbmiss_transaction      = 0;    
+        m_cpt_itlb_ll_transaction       = 0;  
+        m_cpt_itlb_sc_transaction       = 0;  
+        m_cpt_dtlbmiss_transaction      = 0;  
+        m_cpt_dtlb_ll_transaction       = 0;  
+        m_cpt_dtlb_sc_transaction       = 0;  
+        m_cpt_dtlb_ll_dirty_transaction = 0;  
+        m_cpt_dtlb_sc_dirty_transaction = 0;  
+ 
+        m_cost_itlbmiss_transaction      = 0;   
+        m_cost_itlb_ll_transaction       = 0;  
+        m_cost_itlb_sc_transaction       = 0;  
+        m_cost_dtlbmiss_transaction      = 0;   
+        m_cost_dtlb_ll_transaction       = 0;   
+        m_cost_dtlb_sc_transaction       = 0;   
+        m_cost_dtlb_ll_dirty_transaction = 0;   
+        m_cost_dtlb_sc_dirty_transaction = 0;   
+
+        /// For instrumentation
+        r_ireq_isUser_save = false;
+        r_dreq_isUser_save = false;
+        return;
+    }
+
+#ifdef SOCLIB_MODULE_DEBUG
+std::cout << name() << " cycle = " << std::dec << m_cpt_total_cycles  
+       	  << " tgt fsm: " << tgt_fsm_state_str[r_vci_tgt_fsm]
+       	  << " dcache fsm: " << dcache_fsm_state_str[r_dcache_fsm]
+       	  << " icache fsm: " << icache_fsm_state_str[r_icache_fsm]
+       	  << " cmd fsm: " << cmd_fsm_state_str[r_vci_cmd_fsm]
+       	  << " rsp fsm: " << rsp_fsm_state_str[r_vci_rsp_fsm] 
+          << " cleanup cmd fsm: " << cleanup_cmd_fsm_state_str[r_cleanup_cmd_fsm]
+          << " cleanup rsp fsm: " << cleanup_rsp_fsm_state_str[r_cleanup_rsp_fsm]
+       	  << " inval itlb fsm: " << inval_itlb_fsm_state_str[r_inval_itlb_fsm] 
+          << " inval dtlb fsm: " << inval_dtlb_fsm_state_str[r_inval_dtlb_fsm] << std::endl;
+#endif
+
+    m_cpt_total_cycles++;
+
+    if((m_period != 0) && ((m_cpt_total_cycles % m_period) == 0))
+    {
+        print_stats();
+        clear_stats();
+    }
+
+    typename iss_t::InstructionRequest ireq = ISS_IREQ_INITIALIZER;
+    typename iss_t::InstructionResponse irsp = ISS_IRSP_INITIALIZER;
+
+    typename iss_t::DataRequest dreq = ISS_DREQ_INITIALIZER;
+    typename iss_t::DataResponse drsp = ISS_DRSP_INITIALIZER;
+
+    m_iss.getRequests( ireq, dreq );
+
+#ifdef SOCLIB_MODULE_DEBUG
+    std::cout << name() << " Instruction Request: " << ireq << std::endl;
+    std::cout << name() << " Data Request: " << dreq << std::endl;
+#endif
+
+    /////////////////////////////////////////////////////////////////////
+    // The TGT_FSM controls the following ressources:
+    // - r_vci_tgt_fsm
+    // - r_tgt_buf[nwords]
+    // - r_tgt_val[nwords]
+    // - r_tgt_update
+    // - r_tgt_word
+    // - r_tgt_addr
+    // - r_tgt_srcid
+    // - r_tgt_trdid
+    // - r_tgt_pktid
+    // All VCI commands must be CMD_WRITE.
+    // If the VCI address offset is null, the command is an invalidate 
+    // request. It is an update request otherwise.
+    // The VCI_TGT FSM stores the external request arguments in the
+    // IDLE, UPDT_WORD & UPDT_DATA states. It sets the r_tgt_icache_req 
+    // & r_tgt_dcache_req flip-flops to signal the external request to 
+    // the ICACHE & DCACHE FSMs in the REQ state. It waits the completion
+    // of the update or invalidate request in the RSP state.
+    // -  for an invalidate request the VCI packet length is 1 word.
+    // The WDATA field contains the line index (i.e. the Z & Y fields).
+    // -  for an update request the VCI packet length is (n+2) words.
+    // The WDATA field of the first VCI word contains the line number.
+    // The WDATA field of the second VCI word contains the word index.
+    // The WDATA field of the n following words contains the values.
+    // -  for both invalidate & update requests, the VCI response
+    // is one single word.
+    // In case of errors in the VCI command packet, the simulation
+    // is stopped with an error message.
+    /////////////////////////////////////////////////////////////////////
+    
+    switch(r_vci_tgt_fsm) {
+    //////////////
+    case TGT_IDLE:
+    {
+        if ( p_vci_tgt.cmdval.read() ) 
+        {
+            paddr_t address = p_vci_tgt.address.read();
+
+            if ( p_vci_tgt.cmd.read() != vci_param::CMD_WRITE) 
+            {
+                std::cout << "error in component VCI_CC_VCACHE_WRAPPER " << name() << std::endl;
+                std::cout << "the received VCI command is not a write" << std::endl;
+                exit(0);
+            }
+
+            // multi-update or multi-invalidate for data type
+            if ( ( (address & 0x3) != 0x3 ) && ( ! m_segment.contains(address)) ) 
+            {
+                std::cout << "error in component VCI_CC_VCACHE_WRAPPER " << name() << std::endl;
+                std::cout << "out of segment VCI command received for a multi-updt or multi-inval request" << std::endl;
+                exit(0);
+            }
+
+            r_tgt_srcid = p_vci_tgt.srcid.read();
+            r_tgt_trdid = p_vci_tgt.trdid.read();
+            r_tgt_pktid = p_vci_tgt.pktid.read();
+            r_tgt_plen  = p_vci_tgt.plen.read(); // todo: wait L2 modification
+            r_tgt_addr  = ((paddr_t)(p_vci_tgt.be.read() & 0x3) << 32)   |
+                          ((paddr_t)p_vci_tgt.wdata.read() * m_dcache_words * 4); 
+
+            if ( (address & 0x3) == 0x3 ) // broadcast invalidate for data or instruction type
+            {
+                if ( ! p_vci_tgt.eop.read() ) 
+                {
+                    std::cout << "error in component VCI_CC_VCACHE_WRAPPER " << name() << std::endl;
+                    std::cout << "the BROADCAST INVALIDATE command length must be one word" << std::endl;
+                    exit(0);
+                }
+
+                r_tgt_update = false; 
+                r_vci_tgt_fsm = TGT_REQ_BROADCAST;
+                m_cpt_cc_broadcast++;
+                m_cost_broadcast_frz++;
+            }
+            else                // multi-update or multi-invalidate for data type
+            {
+                paddr_t cell = address - m_segment.baseAddress();   
+
+                if (cell == 0)                      // invalidate   
+                {                         
+                    if ( ! p_vci_tgt.eop.read() ) 
+                    {
+                        std::cout << "error in component VCI_CC_VCACHE_WRAPPER " << name() << std::endl;
+                        std::cout << "the MULTI-INVALIDATE command length must be one word" << std::endl;
+                        exit(0);
+                    }
+
+                    r_tgt_update = false; 
+                    r_vci_tgt_fsm = TGT_REQ_DCACHE;
+                    m_cpt_cc_inval_data++ ;
+                    m_cost_inval_data_frz++;
+                }
+                else if (cell == 4)                // update 
+                {                                
+                    if ( p_vci_tgt.eop.read() ) 
+                    {
+                        std::cout << "error in component VCI_CC_VCACHE_WRAPPER " << name() << std::endl;
+                        std::cout << "the MULTI-UPDATE command length must be N+2 words" << std::endl;
+                        exit(0);
+                    }
+
+                    r_tgt_update = true; 
+                    r_vci_tgt_fsm = TGT_UPDT_WORD;
+                    m_cpt_cc_update_data++ ;
+                    m_cost_updt_data_frz++;
+                }     
+                else if (cell == 8)
+                {
+                    if ( ! p_vci_tgt.eop.read() ) 
+                    {
+                        std::cout << "error in component VCI_CC_VCACHE_WRAPPER " << name() << std::endl;
+                        std::cout << "the MULTI-INVALIDATE command length must be one word" << std::endl;
+                        exit(0);
+                    }
+                
+                    r_tgt_update = false; 
+                    r_vci_tgt_fsm = TGT_REQ_ICACHE;
+                    m_cpt_cc_inval_ins++ ;
+                    m_cost_inval_ins_frz++;
+                }
+            } // end if address    
+        } // end if cmdval
+        break;
+    }
+    ///////////////////
+    case TGT_UPDT_WORD:
+    {
+        m_cost_updt_data_frz++;
+
+        if (p_vci_tgt.cmdval.read()) 
+        {
+            if ( p_vci_tgt.eop.read() ) 
+            {
+                std::cout << "error in component VCI_CC_VCACHE_WRAPPER " << name() << std::endl;
+                std::cout << "the MULTI-UPDATE command length must be N+2 words" << std::endl;
+                exit(0);
+            }
+            for ( size_t i=0 ; i < m_dcache_words ; i++ ) r_tgt_val[i] = false;
+            r_tgt_word = p_vci_tgt.wdata.read(); // the first modified word index
+            r_vci_tgt_fsm = TGT_UPDT_DATA;
+        }
+        break;
+    }
+    ///////////////////
+    case TGT_UPDT_DATA:
+    {
+        m_cost_updt_data_frz++;
+
+        if (p_vci_tgt.cmdval.read()) 
+        {
+            size_t word = r_tgt_word.read();
+            if (word >= m_dcache_words) 
+            {
+                std::cout << "error in component VCI_CC_VCACHE_WRAPPER " << name() << std::endl;
+                std::cout << "the reveived MULTI-UPDATE command length is wrong" << std::endl;
+                exit(0);
+            }
+            r_tgt_buf[word] = p_vci_tgt.wdata.read();
+            if(p_vci_tgt.be.read())    r_tgt_val[word] = true;
+            r_tgt_word = word + 1;
+            if (p_vci_tgt.eop.read())  r_vci_tgt_fsm = TGT_REQ_DCACHE;
+        }
+        break;
+    }
+    ////////////////////////
+    case TGT_REQ_BROADCAST:
+    {
+        m_cost_broadcast_frz++;
+
+        if ( !r_tgt_icache_req.read() && !r_tgt_dcache_req.read() ) 
+        {
+            r_vci_tgt_fsm = TGT_RSP_BROADCAST; 
+            r_tgt_icache_req = true;
+            r_tgt_dcache_req = true;
+        }
+        break;
+    }
+    /////////////////////
+    case TGT_REQ_ICACHE:
+    {
+        m_cost_inval_ins_frz++;
+
+        if ( !r_tgt_icache_req.read() ) 
+        {
+            r_vci_tgt_fsm = TGT_RSP_ICACHE; 
+            r_tgt_icache_req = true;
+        }
+        break;
+    }
+    /////////////////////
+    case TGT_REQ_DCACHE:
+    {
+        if (r_tgt_update) 
+            m_cost_updt_data_frz++;
+        else 
+            m_cost_inval_data_frz++;
+
+        if ( !r_tgt_dcache_req.read() ) 
+        {
+            r_vci_tgt_fsm = TGT_RSP_DCACHE; 
+            r_tgt_dcache_req = true;
+        }
+        break;
+    }
+    ///////////////////////
+    case TGT_RSP_BROADCAST:
+    {
+        m_cost_broadcast_frz++;
+
+        // no response
+        if ( !r_tgt_icache_rsp.read() && !r_tgt_dcache_rsp.read() && !r_tgt_icache_req.read() && !r_tgt_dcache_req.read() )
+        {
+            r_vci_tgt_fsm = TGT_IDLE;
+            break;
+        }
+
+        if ( p_vci_tgt.rspack.read() && !r_tgt_icache_req.read() && !r_tgt_dcache_req.read() ) 
+        {
+            // one response
+            if ( !r_tgt_icache_rsp || !r_tgt_dcache_rsp )
+            {
+                r_vci_tgt_fsm = TGT_IDLE; 
+                r_tgt_icache_rsp = false;
+                r_tgt_dcache_rsp = false;
+            }
+
+            // if data and instruction have the inval line, need two responses  
+            if ( r_tgt_icache_rsp && r_tgt_dcache_rsp )
+            {
+                r_tgt_icache_rsp = false; // only reset one for respond the second time 
+            }
+        }
+        break;
+    }
+    /////////////////////
+    case TGT_RSP_ICACHE:
+    {
+        m_cost_inval_ins_frz++;
+
+        if ( (p_vci_tgt.rspack.read() || !r_tgt_icache_rsp.read()) && !r_tgt_icache_req.read() ) 
+        {
+            r_vci_tgt_fsm = TGT_IDLE;
+            r_tgt_icache_rsp = false; 
+        }
+        break;
+    }
+    /////////////////////
+    case TGT_RSP_DCACHE:
+    {
+        if (r_tgt_update) 
+            m_cost_updt_data_frz++;
+        else 
+            m_cost_inval_data_frz++;
+        
+        if ( (p_vci_tgt.rspack.read() || !r_tgt_dcache_rsp.read()) && !r_tgt_dcache_req.read() )
+        {
+            r_vci_tgt_fsm = TGT_IDLE;
+            r_tgt_dcache_rsp = false; 
+        }
+        break;
+    }
+    } // end switch TGT_FSM
+
+    ////////////////////////////////////////////////////////////////////////////////////////
+    //      ICACHE_FSM
+    //
+    // There is 9 mutually exclusive conditions to exit the IDLE state.
+    // Four configurations corresponding to an XTN request from processor,
+    // - Flush TLB (in case of Context switch) => TLB_FLUSH state 
+    // - Flush cache => CACHE_FLUSH state 
+    // - Invalidate a TLB entry => TLB_INVAL state
+    // - Invalidate a cache line => CACHE_INVAL state
+    // Five configurations corresponding to various TLB or cache MISS :
+    // - TLB miss(in case hit_p miss) => TLB1_READ state
+    // - TLB miss(in case hit_p hit) => TLB2_READ state
+    // - Hit in TLB but VPN changed => BIS state
+    // - Cached read miss => MISS_REQ state
+    // - Uncache read miss => UNC_REQ state
+    // 
+    // In case of MISS, the controller writes a request in the r_icache_paddr_save register 
+    // and sets the corresponding request flip-flop : r_dcache_itlb_read_req, r_icache_miss_req 
+    // or r_icache_unc_req. These request flip-flops are reset by the VCI_RSP controller 
+    // when the response is ready in the ICACHE buffer.
+    //
+    // The DCACHE FSM signals XTN processor requests using the r_dcache_xtn_req flip-flop. 
+    // The request opcod and the address to be invalidated are transmitted
+    // in the r_dcache_paddr_save & r_dcache_wdata_save registers respectively.
+    // The request flip-flop is reset by the ICACHE_FSM when the operation is completed.
+    //
+    // The r_vci_rsp_ins_error flip-flop is set by the VCI_RSP FSM and reset
+    // by the ICACHE-FSM in the ICACHE_ERROR state.
+    //
+    //----------------------------------------------------------------------------------- 
+    // Instruction TLB: 
+    //  
+    // - int        ET          (00: unmapped; 01: unused or PTD)
+    //                          (10: PTE new;  11: PTE old      )
+    // - bool       cachable    (cached bit)
+    // - bool       writable    (** not used alwayse false) 
+    // - bool       executable  (executable bit)
+    // - bool       user        (access in user mode allowed)
+    // - bool       global      (PTE not invalidated by a TLB flush)
+    // - bool       dirty       (** not used alwayse false) 
+    // - uint32_t   vpn         (virtual page number)
+    // - uint32_t   ppn         (physical page number)
+    ////////////////////////////////////////////////////////////////////////////////////////
+
+    switch(r_icache_fsm) {
+
+    ////////////////
+    case ICACHE_IDLE:
+    {
+        pte_info_t  icache_pte_info;
+        paddr_t     tlb_ipaddr       = 0;    	// physical address obtained from TLB                         
+        paddr_t     spc_ipaddr       = 0;    	// physical adress obtained from PPN_save (speculative)       
+        data_t      icache_ins       = 0;    	// read instruction
+        bool        icache_hit_c     = false;	// Cache hit
+        bool        icache_cached    = false;	// cacheable access (read)
+        bool        icache_hit_t     = false;	// hit on TLB
+        bool        icache_hit_x     = false;	// VPN unmodified (can use spc_dpaddr)
+        bool        icache_hit_p     = false;	// PTP unmodified (can skip first level page table walk)
+        size_t      icache_tlb_way   = 0;    	// selected way (in case of cache hit)
+        size_t      icache_tlb_set   = 0;    	// selected set (Y field in address)
+        paddr_t     icache_tlb_nline = 0;  	    // TLB NLINE 
+
+        // Decoding processor XTN requests
+        // They are sent by DCACHE FSM  
+
+        if (r_dcache_xtn_req)
+        {
+            if ((int)r_dcache_type_save == (int)iss_t::XTN_PTPR )  
+            {
+                r_icache_way = 0;
+                r_icache_set = 0;
+                r_icache_fsm = ICACHE_SW_FLUSH;   
+                break;
+            }
+            if ((int)r_dcache_type_save == (int)iss_t::XTN_ICACHE_FLUSH)
+            {
+                r_icache_way = 0;
+                r_icache_set = 0;
+                r_icache_fsm = ICACHE_CACHE_FLUSH;   
+                break;
+            }
+            if ((int)r_dcache_type_save == (int)iss_t::XTN_ITLB_INVAL) 
+            {
+                r_icache_fsm = ICACHE_TLB_INVAL;   
+                break;
+            }
+            if ((int)r_dcache_type_save == (int)iss_t::XTN_ICACHE_INVAL) 
+            {
+                r_icache_fsm = ICACHE_CACHE_INVAL;   
+                break;
+            }
+            if ((int)r_dcache_type_save == (int)iss_t::XTN_MMU_ICACHE_PA_INV) 
+            {
+                r_icache_fsm = ICACHE_CACHE_INVAL_PA;   
+                break;
+            }
+            if ((int)r_dcache_type_save == (int)iss_t::XTN_DCACHE_FLUSH )  
+            {
+                // special for ins tlb miss via data cache
+                r_icache_fsm = ICACHE_TLB_FLUSH;   
+                break;
+            }
+        } // end if xtn_req
+
+        // external cache invalidate request
+        if ( r_tgt_icache_req )
+        {
+            r_icache_fsm = ICACHE_CC_INVAL;
+            r_icache_fsm_save = r_icache_fsm;
+            break;
+        }
+
+        // external tlb invalidate request
+        if ( r_dcache_itlb_inval_req )
+        {
+            r_itlb_inval_req = true;
+            r_icache_fsm = ICACHE_TLB_CC_INVAL;
+            r_icache_fsm_save = r_icache_fsm;
+            break;
+        }
+
+        // icache_hit_t_m, icache_hit_t_k, icache_hit_x, icache_hit_p 
+        // icache_pte_info, icache_tlb_way, icache_tlb_set & ipaddr & cacheability 
+        // - If MMU activated : cacheability is defined by the cachable bit in the TLB
+        // - If MMU not activated : cacheability is defined by the segment table.
+
+        if ( !(r_mmu_mode.read() & INS_TLB_MASK) )   // MMU not activated 
+        {
+            icache_hit_t  = true;         
+            icache_hit_x  = true;         
+            icache_hit_p  = true;         
+            tlb_ipaddr    = ireq.addr;
+            spc_ipaddr    = ireq.addr;
+            icache_cached = m_cacheability_table[ireq.addr];
+        } 
+        else                                                                // MMU activated
+        { 
+            m_cpt_ins_tlb_read++;
+            icache_hit_t  = icache_tlb.cctranslate(ireq.addr, 
+                                                   &tlb_ipaddr, 
+                                                   &icache_pte_info, 
+                                                   &icache_tlb_nline, 
+                                                   &icache_tlb_way, 
+                                                   &icache_tlb_set);
+ 
+            icache_hit_x  = (((vaddr_t)r_icache_vpn_save << PAGE_K_NBITS) == (ireq.addr & ~PAGE_K_MASK)) && r_itlb_translation_valid;
+            icache_hit_p  = (((ireq.addr >> PAGE_M_NBITS) == r_icache_id1_save) && r_icache_ptba_ok); 
+            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 ( !(r_mmu_mode.read() & INS_CACHE_MASK) )   // cache not actived
+        {
+            icache_cached = false;
+        }
+
+        if ( ireq.valid ) 
+        {
+            m_cpt_icache_dir_read += m_icache_ways;
+            m_cpt_icache_data_read += m_icache_ways;
+
+            // icache_hit_c & icache_ins
+            if ( icache_cached )    // using speculative physical address for cached access
+            {
+                icache_hit_c = r_icache.read(spc_ipaddr, &icache_ins);
+            }
+            else                    // using actual physical address for uncached access
+            {
+                icache_hit_c = ( r_icache_buf_unc_valid && (tlb_ipaddr == (paddr_t)r_icache_paddr_save) );
+                icache_ins = r_icache_miss_buf[0];
+            }
+
+            // For instrumentation: is User access ? 
+            r_ireq_isUser_save = (dreq.mode == iss_t::MODE_USER) ? true : false;        
+
+            if ( r_mmu_mode.read() & INS_TLB_MASK ) 
+            {
+                if ( icache_hit_t ) 
+                {
+                    // check access rights
+                    if ( !icache_pte_info.u && (ireq.mode == iss_t::MODE_USER)) 
+                    {
+                        r_icache_error_type = MMU_READ_PRIVILEGE_VIOLATION;  
+                        r_icache_bad_vaddr = ireq.addr;
+                        irsp.valid = true;
+                        irsp.error = true;
+                        irsp.instruction = 0;
+                        break;
+                    }
+                    if ( !icache_pte_info.x ) 
+                    {
+                        r_icache_error_type = MMU_READ_EXEC_VIOLATION;  
+                        r_icache_bad_vaddr = ireq.addr;
+                        irsp.valid = true;
+                        irsp.error = true;
+                        irsp.instruction = 0;
+                        break;
+                    }
+                }
+
+                // update LRU, save ppn, vpn and page type
+                if ( icache_hit_t )
+                {  
+                    icache_tlb.setlru(icache_tlb_way,icache_tlb_set);     
+                    r_icache_ppn_save = tlb_ipaddr >> PAGE_K_NBITS;
+                    r_icache_vpn_save = ireq.addr >> PAGE_K_NBITS;
+                    r_icache_tlb_nline = icache_tlb_nline;
+                    r_itlb_translation_valid = true;
+                }
+                else
+                {
+                    r_itlb_translation_valid = false;
+                }
+
+            } // end if MMU activated
+
+            // compute next state 
+            if ( !icache_hit_t && !icache_hit_p )      // TLB miss
+            {
+                // walk page table  level 1
+                r_icache_paddr_save = (paddr_t)r_mmu_ptpr << (INDEX1_NBITS+2) | (paddr_t)((ireq.addr>>PAGE_M_NBITS)<<2);
+                r_itlb_read_dcache_req = true;
+                r_icache_vaddr_req = ireq.addr;
+                r_icache_fsm = ICACHE_TLB1_READ;
+                m_cpt_ins_tlb_miss++;
+                m_cost_ins_tlb_miss_frz++;
+            }
+            else if ( !icache_hit_t && icache_hit_p )  // TLB Miss with possibility of bypass first level page
+            {
+                // walk page table level 2
+                r_icache_paddr_save = (paddr_t)r_icache_ptba_save | 
+                                      (paddr_t)(((ireq.addr&PTD_ID2_MASK)>>PAGE_K_NBITS) << 3);
+                r_itlb_read_dcache_req = true;
+                r_icache_vaddr_req = ireq.addr;
+                r_itlb_k_read_dcache   = true;
+                r_icache_fsm = ICACHE_TLB2_READ;
+                m_cpt_ins_tlb_miss++;
+                m_cost_ins_tlb_miss_frz++;
+            }
+            else if ( icache_hit_t && !icache_hit_x && icache_cached ) // cached access with an ucorrect speculative physical address
+            {
+                r_icache_paddr_save = tlb_ipaddr;   // save actual physical address for BIS
+                r_icache_vaddr_req = ireq.addr;
+                r_icache_fsm = ICACHE_BIS;
+                //m_cost_ins_miss_frz++;
+            }
+            else    // cached or uncached access with a correct speculative physical address 
+            {        
+                m_cpt_ins_read++; 
+                if ( !icache_hit_c ) 
+                {
+                    if ( icache_cached ) 
+                    {
+                        r_icache_miss_req = true;
+                    	r_icache_paddr_save = spc_ipaddr; 
+                        r_icache_vaddr_req = ireq.addr;
+                        r_icache_fsm = ICACHE_MISS_WAIT;
+                    	m_cpt_ins_miss++;
+                    	m_cost_ins_miss_frz++;
+                    } 
+                    else 
+                    {
+                        r_icache_unc_req = true;
+                        r_icache_buf_unc_valid = false;
+                    	r_icache_paddr_save = tlb_ipaddr; 
+                        r_icache_vaddr_req = ireq.addr;
+                        r_icache_fsm = ICACHE_UNC_WAIT;
+                    } 
+                } 
+                else 
+                {
+                    r_icache_buf_unc_valid = false;
+                    r_icache_fsm = ICACHE_IDLE;
+                }
+                irsp.valid = icache_hit_c;
+                irsp.instruction = icache_ins;
+            } // end if next states
+            
+        } // end if ireq.valid
+        break;
+    }
+    ////////////////
+    case ICACHE_BIS: 
+    {
+        // external cache invalidate request
+        if ( r_tgt_icache_req )
+        {
+            r_icache_fsm = ICACHE_CC_INVAL;
+            r_icache_fsm_save = r_icache_fsm;
+            break;
+        }
+
+        // external tlb invalidate request
+        if ( r_dcache_itlb_inval_req )
+        {
+	    r_itlb_inval_req = true;
+            r_icache_fsm = ICACHE_TLB_CC_INVAL;
+            r_icache_fsm_save = r_icache_fsm;
+            break;
+        }
+      
+        // using page is invalidated 
+        if ( r_icache_inval_tlb_rsp )
+        {
+            r_icache_inval_tlb_rsp = false;
+            r_icache_fsm = ICACHE_IDLE;
+            break;
+        }
+ 
+        data_t	icache_ins = 0;
+        bool	icache_hit_c = false;
+        bool    icache_hit_t = false;
+        paddr_t	tlb_ipaddr = 0;
+
+        icache_hit_t = icache_tlb.translate(ireq.addr, &tlb_ipaddr);
+
+        if ( (tlb_ipaddr == r_icache_paddr_save.read()) && ireq.valid && icache_hit_t )		// unmodified & valid
+        {
+            m_cpt_ins_read++;
+
+            // acces is always cached in this state
+            icache_hit_c = r_icache.read(r_icache_paddr_save, &icache_ins);
+
+            if ( !icache_hit_c )
+            {
+                r_icache_miss_req = true;
+                r_icache_fsm = ICACHE_MISS_WAIT;
+                m_cpt_ins_miss++;
+                m_cost_ins_miss_frz++;
+            } 
+            else
+            {
+                r_icache_fsm = ICACHE_IDLE; 
+            }
+            irsp.valid = icache_hit_c;
+            if (irsp.valid)
+                assert((r_icache_vaddr_req.read() == ireq.addr) &&
+                       "vaddress should not be modified while ICACHE_BIS");
+            irsp.error = false;
+            irsp.instruction = icache_ins;
+        }
+        else	// modified or invalid
+        {
+            irsp.valid = false;
+            irsp.error = false;
+            irsp.instruction = 0;
+            r_icache_fsm = ICACHE_IDLE;
+        }
+        break;
+    }
+    //////////////////////
+    case ICACHE_TLB1_READ:
+    {
+        if ( ireq.valid ) m_cost_ins_tlb_miss_frz++;
+
+        // external cache invalidate request
+        if ( r_tgt_icache_req )
+        {
+            r_icache_fsm = ICACHE_CC_INVAL;
+            r_icache_fsm_save = r_icache_fsm;
+            break;
+        }
+
+        // external tlb invalidate request
+        if ( r_dcache_itlb_inval_req )
+        {
+	    r_itlb_inval_req = true;
+            r_icache_fsm = ICACHE_TLB_CC_INVAL;
+            r_icache_fsm_save = r_icache_fsm;
+            break;
+        }
+
+        if ( !r_itlb_read_dcache_req )
+        {
+            if (r_icache_vaddr_req.read() != ireq.addr || !ireq.valid) 
+            {
+                /* request modified, drop response and restart */
+                r_icache_ptba_ok = false;
+            	if ( r_icache_inval_tlb_rsp )	r_icache_inval_tlb_rsp = false;
+                if ( r_dcache_rsp_itlb_error )	r_dcache_rsp_itlb_error = false;
+                r_icache_fsm = ICACHE_IDLE;
+                break;
+            }
+
+            if ( !r_icache_inval_tlb_rsp ) // TLB miss read response and no invalidation
+            {
+                if ( !r_dcache_rsp_itlb_error ) // vci response ok
+                {  
+                    if (r_itlb_acc_redo_req)
+                    {
+                        r_itlb_acc_redo_req = false;
+                        r_itlb_read_dcache_req = true;
+                        //r_icache_fsm = ICACHE_IDLE;  
+                    }
+            	    else if ( !(r_dcache_rsp_itlb_miss >> PTE_V_SHIFT) ) // unmapped
+            	    {
+                        r_icache_ptba_ok    = false;	
+                        r_icache_error_type = MMU_READ_PT1_UNMAPPED;  
+                        r_icache_bad_vaddr  = r_icache_vaddr_req.read();
+                        r_icache_fsm        = ICACHE_ERROR;
+            	    }
+            	    else if ( (r_dcache_rsp_itlb_miss & PTE_T_MASK ) >> PTE_T_SHIFT ) // PTD
+            	    {
+                        r_icache_ptba_ok       = true;	
+                        r_icache_ptba_save     = (paddr_t)(r_dcache_rsp_itlb_miss & ((1<<(m_paddr_nbits - PAGE_K_NBITS))-1)) << PAGE_K_NBITS; 
+                        r_icache_id1_save      = r_icache_vaddr_req.read() >> PAGE_M_NBITS;
+                        r_icache_paddr_save    = (paddr_t)(r_dcache_rsp_itlb_miss & ((1<<(m_paddr_nbits - PAGE_K_NBITS))-1)) << PAGE_K_NBITS |
+                                                 (paddr_t)(((r_icache_vaddr_req.read() & PTD_ID2_MASK) >> PAGE_K_NBITS) << 3); 
+                        r_itlb_read_dcache_req = true;
+                        r_itlb_k_read_dcache   = true;
+                        r_icache_fsm           = ICACHE_TLB2_READ;
+             	    }	
+            	    else
+            	    {
+                        r_icache_ptba_ok = false;
+            
+            	        if ( (m_srcid_rw >> 4) == ((r_dcache_rsp_itlb_miss & ((1<<(m_paddr_nbits - PAGE_M_NBITS))-1)) >> (m_paddr_nbits - PAGE_M_NBITS -10)) ) // local
+            	        {
+                            if ( (r_dcache_rsp_itlb_miss & PTE_L_MASK ) >> PTE_L_SHIFT ) // L bit is set
+                            {
+                                r_icache_pte_update = r_dcache_rsp_itlb_miss;
+                                r_icache_fsm        = ICACHE_TLB1_UPDT_SEL;
+                            }
+                            else
+                            {
+                                r_icache_pte_update   = r_dcache_rsp_itlb_miss | PTE_L_MASK;
+                                r_itlb_acc_dcache_req = true;
+                                r_icache_fsm          = ICACHE_TLB1_WRITE;
+                                m_cpt_ins_tlb_update_acc++;
+                                m_cost_ins_tlb_update_acc_frz++;
+                            }
+                        }
+            	        else // remotely
+            	        {
+                            if ( (r_dcache_rsp_itlb_miss & PTE_R_MASK ) >> PTE_R_SHIFT ) // R bit is set
+                            {
+                                r_icache_pte_update = r_dcache_rsp_itlb_miss;
+                                r_icache_fsm        = ICACHE_TLB1_UPDT_SEL;
+                            }
+                            else
+                            {
+                                r_icache_pte_update   = r_dcache_rsp_itlb_miss | PTE_R_MASK;
+                                r_itlb_acc_dcache_req = true;
+                                r_icache_fsm          = ICACHE_TLB1_WRITE;
+                                m_cpt_ins_tlb_update_acc++;
+                                m_cost_ins_tlb_update_acc_frz++;
+                            }
+            	        }
+            	    }
+                }
+                else                        // vci response error
+                {  
+                    r_icache_fsm = ICACHE_ERROR;
+                    r_icache_error_type = MMU_READ_PT1_ILLEGAL_ACCESS;    
+                    r_icache_bad_vaddr = r_icache_vaddr_req.read();
+                }
+            }
+            else  // TLB miss read response and invalidation
+            {
+                if ( r_dcache_rsp_itlb_error ) 
+                {
+                    r_icache_inval_tlb_rsp = false;
+                    r_icache_error_type = MMU_READ_PT1_ILLEGAL_ACCESS;    
+                    r_icache_bad_vaddr = r_icache_vaddr_req.read();
+                    r_icache_fsm = ICACHE_ERROR;
+                } 
+                else 
+                {
+	            if ( r_itlb_acc_redo_req ) r_itlb_acc_redo_req = false;
+                    r_icache_inval_tlb_rsp = false;
+                    r_icache_fsm = ICACHE_IDLE;  
+                } 
+            }
+        }
+        break;
+    }
+    ///////////////////////
+    case ICACHE_TLB1_WRITE:  
+    {
+        if ( ireq.valid ) m_cost_ins_tlb_miss_frz++;
+        m_cost_ins_tlb_update_acc_frz++;
+
+        // external cache invalidate request
+        if ( r_tgt_icache_req )
+        {
+            r_icache_fsm = ICACHE_CC_INVAL;
+            r_icache_fsm_save = r_icache_fsm;
+            break;
+        }
+        // external tlb invalidate request
+        if ( r_dcache_itlb_inval_req )
+        {
+            r_itlb_inval_req = true;
+            r_icache_fsm = ICACHE_TLB_CC_INVAL;
+            r_icache_fsm_save = r_icache_fsm;
+            break;
+        }
+
+        if ( !r_itlb_acc_dcache_req ) // TLB access bits write response 
+        {        
+            if ( !r_icache_inval_tlb_rsp ) // TLB access bits write response and no invalidation        
+            { 
+                if ( r_dcache_rsp_itlb_error ) 
+                {
+                    r_icache_error_type = MMU_READ_PT1_ILLEGAL_ACCESS;  
+                    r_icache_bad_vaddr = r_icache_vaddr_req.read();
+                    r_icache_fsm = ICACHE_ERROR;
+                } 
+                else if ( r_itlb_acc_redo_req )
+                {
+                    r_itlb_acc_redo_req = false;
+                    r_icache_fsm = ICACHE_IDLE;    
+                }
+                else  
+                {
+                    r_icache_fsm = ICACHE_TLB1_UPDT_SEL;  
+                }
+            } 
+            else   // TLB ET write response and invalidation     
+            {   
+                if ( r_dcache_rsp_itlb_error ) 
+                {
+                    r_icache_inval_tlb_rsp = false;
+                    r_icache_error_type = MMU_READ_PT1_ILLEGAL_ACCESS;  
+                    r_icache_bad_vaddr = r_icache_vaddr_req.read();
+                    r_icache_fsm = ICACHE_ERROR;
+                } 
+                else if ( r_itlb_acc_redo_req )
+                {
+                    r_itlb_acc_redo_req = false;
+                    r_icache_inval_tlb_rsp = false;
+                    r_icache_fsm = ICACHE_IDLE;    
+                }
+                else  
+                {
+                    r_icache_inval_tlb_rsp = false;
+                    r_icache_fsm = ICACHE_IDLE;    
+                }
+            }
+        }
+        break;
+    }
+    //////////////////////
+    case ICACHE_TLB1_UPDT_SEL:
+    {
+        if ( ireq.valid ) m_cost_ins_tlb_miss_frz++;
+        m_cost_ins_tlb_update_acc_frz++;
+
+        // external cache invalidate request
+        if ( r_tgt_icache_req )
+        {
+            r_icache_fsm = ICACHE_CC_INVAL;
+            r_icache_fsm_save = r_icache_fsm;
+            break;
+        }
+
+        // external tlb invalidate request
+        if ( r_dcache_itlb_inval_req ) 
+        {
+            r_itlb_inval_req = true;
+            r_icache_fsm = ICACHE_TLB_CC_INVAL;
+            r_icache_fsm_save = r_icache_fsm;
+            break;
+        }
+
+        // TLB update and invalidate same PTE
+        if ( r_icache_inval_tlb_rsp )                                 
+        {
+            r_icache_inval_tlb_rsp = false;
+            r_icache_fsm = ICACHE_IDLE;
+            break;
+        }
+
+        if ( r_dcache_itlb_cleanup_req ) break; 
+
+        size_t way = 0;
+        size_t set = 0;
+        paddr_t victim_index = 0;
+        
+        bool cleanup = icache_tlb.select((r_icache_vaddr_req.read()>> PAGE_M_NBITS),&victim_index,&way,&set);
+        r_icache_way = way;
+        r_icache_set = set;
+        if (cleanup)
+        {
+            r_dcache_itlb_cleanup_req = true;
+            r_dcache_itlb_cleanup_line = victim_index;
+            //m_cpt_cc_cleanup_ins++;
+        }
+        r_icache_fsm = ICACHE_TLB1_UPDT;
+        break; 
+    }
+    /////////////////////
+    case ICACHE_TLB1_UPDT:
+    {
+        if ( ireq.valid ) m_cost_ins_tlb_miss_frz++;
+        m_cost_ins_tlb_update_acc_frz++;
+        
+        icache_tlb.update(r_icache_pte_update,r_icache_vaddr_req.read(),r_icache_way.read(),r_icache_set.read(),(r_icache_paddr_save.read() >> (uint32_log2(m_dcache_words)+2)));
+        r_icache_fsm = ICACHE_IDLE;
+        break;
+    }
+    /////////////////////
+    case ICACHE_TLB2_READ:
+    {
+        if ( ireq.valid ) m_cost_ins_tlb_miss_frz++;
+
+        // external cache invalidate request
+        if ( r_tgt_icache_req )
+        {
+            r_icache_fsm = ICACHE_CC_INVAL;
+            r_icache_fsm_save = r_icache_fsm;
+            break;
+        }
+
+        // external tlb invalidate request
+        if ( r_dcache_itlb_inval_req )
+        {
+            r_itlb_inval_req = true;
+            r_icache_fsm = ICACHE_TLB_CC_INVAL;
+            r_icache_fsm_save = r_icache_fsm;
+            break;
+        }
+
+        if ( !r_itlb_read_dcache_req  ) // TLB miss read response
+        { 
+            if (r_icache_vaddr_req.read() != ireq.addr || !ireq.valid) 
+            {
+                /* request modified, drop response and restart */
+                r_icache_ptba_ok = false;
+            	if ( r_icache_inval_tlb_rsp )	r_icache_inval_tlb_rsp = false;
+                if ( r_dcache_rsp_itlb_error )	r_dcache_rsp_itlb_error = false;
+                r_icache_fsm = ICACHE_IDLE;
+                break;
+            }
+            
+            if ( !r_icache_inval_tlb_rsp ) // TLB miss read response 
+            {
+                if ( !r_dcache_rsp_itlb_error ) // VCI response ok        
+                {
+                    if (r_itlb_acc_redo_req)
+                    {
+                        r_itlb_acc_redo_req = false;
+                        r_itlb_read_dcache_req = true;
+                    }
+            	    else if ( !(r_dcache_rsp_itlb_miss >> PTE_V_SHIFT) ) // unmapped
+                    {
+                        r_icache_error_type = MMU_READ_PT2_UNMAPPED;  
+                        r_icache_bad_vaddr  = r_icache_vaddr_req.read();
+                        r_icache_fsm = ICACHE_ERROR;
+            	    }
+            	    else
+            	    {
+            	        if ( (m_srcid_rw >> 4) == ((r_dcache_rsp_itlb_miss & ((1<<(m_paddr_nbits - PAGE_M_NBITS))-1)) >> (m_paddr_nbits - PAGE_M_NBITS -10)) ) // local
+                        {
+                            if ( (r_dcache_rsp_itlb_miss & PTE_L_MASK ) >> PTE_L_SHIFT ) // L bit is set
+                            {
+                                r_icache_fsm        = ICACHE_TLB2_UPDT_SEL;
+                                r_icache_pte_update = r_dcache_rsp_itlb_miss;
+                            }
+                            else
+                            {
+                                r_icache_pte_update   = r_dcache_rsp_itlb_miss | PTE_L_MASK;
+                                r_itlb_acc_dcache_req = true;
+                                r_icache_fsm          = ICACHE_TLB2_WRITE;
+                                m_cpt_ins_tlb_update_acc++;
+                                m_cost_ins_tlb_update_acc_frz++;
+                            }
+                        }
+            	    	else // remotely
+                        {
+                            if ( (r_dcache_rsp_itlb_miss & PTE_R_MASK ) >> PTE_R_SHIFT ) // R bit is set
+                            {
+                                r_icache_fsm        = ICACHE_TLB2_UPDT_SEL;
+                                r_icache_pte_update = r_dcache_rsp_itlb_miss;
+                            }
+                            else
+                            {
+                                r_icache_pte_update   = r_dcache_rsp_itlb_miss | PTE_R_MASK;
+                                r_itlb_acc_dcache_req = true;
+                                r_icache_fsm          = ICACHE_TLB2_WRITE;
+                                m_cpt_ins_tlb_update_acc++;
+                                m_cost_ins_tlb_update_acc_frz++;
+                            }
+            	        }
+            	    }
+                }
+                else                            // VCI response error        
+                {
+                    r_icache_error_type = MMU_READ_PT2_ILLEGAL_ACCESS;
+                    r_icache_bad_vaddr = r_icache_vaddr_req.read();
+                    r_icache_fsm = ICACHE_ERROR;
+                }
+            }
+            else  // TLB miss read response and invalidation
+            {
+                if ( r_dcache_rsp_itlb_error ) 
+                {
+                    r_icache_inval_tlb_rsp = false;
+                    r_icache_error_type = MMU_READ_PT2_ILLEGAL_ACCESS;    
+                    r_icache_bad_vaddr = r_icache_vaddr_req.read();
+                    r_icache_fsm = ICACHE_ERROR;
+                } 
+                else 
+                {
+                    if ( r_itlb_acc_redo_req ) r_itlb_acc_redo_req = false;
+                    r_icache_inval_tlb_rsp = false;
+                    r_icache_fsm = ICACHE_IDLE;  
+                } 
+            }
+	}
+        break;
+    }
+    /////////////////////////
+    case ICACHE_TLB2_WRITE:
+    {  
+        if ( ireq.valid ) m_cost_ins_tlb_miss_frz++;
+        m_cost_ins_tlb_update_acc_frz++;
+
+        // external cache invalidate request
+        if ( r_tgt_icache_req )
+        {
+            r_icache_fsm = ICACHE_CC_INVAL;
+            r_icache_fsm_save = r_icache_fsm;
+            break;
+        }
+        // external tlb invalidate request
+        if ( r_dcache_itlb_inval_req )
+        {
+	    r_itlb_inval_req = true;
+            r_icache_fsm = ICACHE_TLB_CC_INVAL;
+            r_icache_fsm_save = r_icache_fsm;
+            break;
+        }
+
+        if ( !r_itlb_acc_dcache_req ) // TLB access bits write response          
+        {
+            if ( !r_icache_inval_tlb_rsp ) // TLB access bits write response          
+            {
+                if ( r_dcache_rsp_itlb_error )             
+                {
+                    r_icache_error_type = MMU_READ_PT2_ILLEGAL_ACCESS;  
+                    r_icache_bad_vaddr = r_icache_vaddr_req.read();
+                    r_icache_fsm = ICACHE_ERROR;
+                } 
+                else if ( r_itlb_acc_redo_req )
+                {
+                    r_itlb_acc_redo_req = false;
+                    r_icache_fsm = ICACHE_IDLE;    
+                }
+                else  
+                {
+                    r_icache_fsm = ICACHE_TLB2_UPDT_SEL;  
+                }
+            }
+            else // TLB ET write response and invalidation     
+            {   
+                if ( r_dcache_rsp_itlb_error ) 
+                {
+                    r_icache_inval_tlb_rsp = false;
+                    r_icache_error_type = MMU_READ_PT2_ILLEGAL_ACCESS;  
+                    r_icache_bad_vaddr = r_icache_vaddr_req.read();
+                    r_icache_fsm = ICACHE_ERROR;
+                } 
+                else if ( r_itlb_acc_redo_req )
+                {
+                    r_itlb_acc_redo_req = false;
+                    r_icache_inval_tlb_rsp = false;
+                    r_icache_fsm = ICACHE_IDLE;    
+                }
+                else  
+                {
+                    r_icache_inval_tlb_rsp = false;
+                    r_icache_fsm = ICACHE_IDLE;    
+                }
+            }
+        }
+        break;
+    }
+    //////////////////////////
+    case ICACHE_TLB2_UPDT_SEL: 
+    {
+        if ( ireq.valid ) m_cost_ins_tlb_miss_frz++;
+        m_cost_ins_tlb_update_acc_frz++;
+
+        // external cache invalidate request
+        if ( r_tgt_icache_req )
+        {
+            r_icache_fsm = ICACHE_CC_INVAL;
+            r_icache_fsm_save = r_icache_fsm;
+            break;
+        }
+
+        // external tlb invalidate request
+        if ( r_dcache_itlb_inval_req ) 
+        {
+            r_itlb_inval_req = true;
+            r_icache_fsm = ICACHE_TLB_CC_INVAL;
+            r_icache_fsm_save = r_icache_fsm;
+            break;
+        }
+
+        // TLB update and invalidate same PTE
+        if ( r_icache_inval_tlb_rsp )                            
+        {
+            r_icache_inval_tlb_rsp = false;
+            r_icache_fsm = ICACHE_IDLE;
+            break;
+        }
+
+        if ( r_dcache_itlb_cleanup_req ) break; 
+
+        size_t way = 0;
+        size_t set = 0;
+        paddr_t victim_index = 0;
+        
+        bool cleanup = icache_tlb.select((r_icache_vaddr_req.read()>> PAGE_K_NBITS),&victim_index,&way,&set);
+        r_icache_way = way;
+        r_icache_set = set;
+        if (cleanup)
+        {
+            r_dcache_itlb_cleanup_req = true;
+            r_dcache_itlb_cleanup_line = victim_index;
+            //m_cpt_cc_cleanup_ins++;
+        }
+        r_icache_fsm = ICACHE_TLB2_UPDT;
+        break;
+    }
+    /////////////////////
+    case ICACHE_TLB2_UPDT: 
+    {
+        if ( ireq.valid ) m_cost_ins_tlb_miss_frz++;
+        m_cost_ins_tlb_update_acc_frz++;
+
+        icache_tlb.update(r_icache_pte_update,r_dcache_rsp_itlb_ppn,r_icache_vaddr_req.read(),r_icache_way.read(),r_icache_set.read(),(r_icache_paddr_save.read() >> (uint32_log2(m_dcache_words)+2)));
+        r_icache_fsm = ICACHE_IDLE;
+        break;
+    }
+    /////////////////////////////
+    case ICACHE_SW_FLUSH:
+    {
+        size_t way = r_icache_way;
+        size_t set = r_icache_set;
+        bool clean = false;
+
+        // 4K page size TLB flush leads to cleanup req to data cache 
+        if ( !r_dcache_itlb_cleanup_req )    // last cleanup finish
+        {
+            paddr_t victim_index = 0;
+            for ( ; way < m_itlb_ways; way++)
+            {
+                for ( ; set < m_itlb_sets; set++)
+                {
+                    if(icache_tlb.checkcleanup(way, set, &victim_index))
+                    {
+                        clean = true;
+                        r_dcache_itlb_cleanup_req = true;
+                        r_dcache_itlb_cleanup_line = victim_index;
+                        r_icache_way = way + ((set+1)/m_itlb_sets);
+                        r_icache_set = (set+1) % m_itlb_sets;
+                        break;
+                    }
+                }
+                if (clean) break;
+                set = 0;
+            }
+
+            if (way == m_itlb_ways)
+            {
+                r_dcache_xtn_req = false;
+                r_itlb_translation_valid = false;
+                r_icache_ptba_ok = false;
+                r_icache_fsm = ICACHE_IDLE;
+                break;
+            }
+        }
+        break;
+    }
+    /////////////////////
+    case ICACHE_TLB_FLUSH:
+    {   
+        // data cache flush leads to ins tlb flush, flush all tlb entry 
+        icache_tlb.flush(true);    // global entries are invalidated
+        r_dcache_xtn_req = false;
+        r_itlb_translation_valid = false;
+        r_icache_ptba_ok = false;
+        r_icache_fsm = ICACHE_IDLE;
+        break;
+    }
+    ////////////////////////
+    case ICACHE_CACHE_FLUSH:
+    {
+        // external cache invalidate request
+        if ( r_tgt_icache_req )
+        {
+            r_icache_fsm = ICACHE_CC_INVAL;
+            r_icache_fsm_save = r_icache_fsm;
+            break;
+        }
+
+        size_t way = r_icache_way;
+        size_t set = r_icache_set;
+        bool clean = false;
+
+        // cache flush and send cleanup to external
+        if ( !r_icache_cleanup_req )
+        {
+            paddr_t victim_index = 0;
+            for ( ; way < m_icache_ways; way++ )
+            {    
+                for ( ; set < m_icache_sets; set++ )
+                {    
+                    if ( r_icache.flush(way, set, &victim_index) )
+                    {
+                        clean = true;
+                        r_icache_cleanup_req = true;
+                        r_icache_cleanup_line = victim_index;
+                        m_cpt_cc_cleanup_ins++;
+                        r_icache_way = way + ((set+1)/m_icache_sets);
+                        r_icache_set = (set+1) % m_icache_sets;
+                        break;
+                    }
+                }
+                if (clean) break;
+                set = 0;
+            }
+            if (way == m_icache_ways)
+            {
+                r_dcache_xtn_req = false;
+                r_icache_fsm = ICACHE_IDLE;
+                break;
+            }
+        }
+        break;
+    }
+    /////////////////////
+    case ICACHE_TLB_INVAL:  
+    {
+        paddr_t victim_index = 0;
+
+        if ( !r_dcache_itlb_cleanup_req )
+        {
+            bool dcache_itlb_cleanup_req = icache_tlb.inval(r_dcache_wdata_save, &victim_index);
+            r_dcache_itlb_cleanup_req = dcache_itlb_cleanup_req;
+            r_dcache_itlb_cleanup_line = victim_index;
+            //if (dcache_itlb_cleanup_req) m_cpt_cc_cleanup_ins++;
+            r_dcache_xtn_req = false;
+            r_itlb_translation_valid = false;
+            r_icache_ptba_ok = false;
+            r_icache_fsm = ICACHE_IDLE;
+        }
+        break;
+    }
+    ////////////////////////
+    case ICACHE_CACHE_INVAL:
+    {	
+        // external cache invalidate request
+        if ( r_tgt_icache_req )
+        {
+            r_icache_fsm = ICACHE_CC_INVAL;
+            r_icache_fsm_save = r_icache_fsm;
+            break;
+        }
+
+        paddr_t ipaddr = 0;                     
+        bool    icache_hit_t = false;
+
+        if ( !r_icache_cleanup_req )
+        {    
+            if ( r_mmu_mode.read() & INS_TLB_MASK ) 
+            {
+                icache_hit_t = icache_tlb.translate(r_dcache_wdata_save, &ipaddr); 
+            } 
+            else 
+            {
+                ipaddr = (paddr_t)r_dcache_wdata_save;
+                icache_hit_t = true;
+            }
+            if ( icache_hit_t )
+            {
+                // invalidate and cleanup if necessary
+                bool icache_cleanup_req = r_icache.inval(ipaddr);
+                r_icache_cleanup_req = icache_cleanup_req;
+                r_icache_cleanup_line = ipaddr >> (uint32_log2(m_icache_words) + 2);  
+                if (icache_cleanup_req) m_cpt_cc_cleanup_ins++;	
+            }
+            r_dcache_xtn_req = false; 
+            r_icache_fsm = ICACHE_IDLE;
+        }
+        break;
+    }
+    ////////////////////////
+    case ICACHE_CACHE_INVAL_PA:
+    {
+        // external cache invalidate request
+        if ( r_tgt_icache_req )
+        {
+            r_icache_fsm = ICACHE_CC_INVAL;
+            r_icache_fsm_save = r_icache_fsm;
+            break;
+        }
+	
+        paddr_t ipaddr = (paddr_t)r_mmu_word_hi.read() << 32 | r_mmu_word_lo.read();
+
+        if ( !r_icache_cleanup_req )
+        {    
+            // invalidate and cleanup if necessary
+            bool icache_cleanup_req = r_icache.inval(ipaddr);
+            r_icache_cleanup_req = icache_cleanup_req;
+            r_icache_cleanup_line = ipaddr >> (uint32_log2(m_icache_words) + 2);  
+            if (icache_cleanup_req) m_cpt_cc_cleanup_ins++; 
+            r_dcache_xtn_req = false; 
+            r_icache_fsm = ICACHE_IDLE;
+        }
+        break;
+    }
+    ///////////////////////
+    case ICACHE_MISS_WAIT:
+    {
+        m_cost_ins_miss_frz++;
+
+        // external cache invalidate request
+        if ( r_tgt_icache_req )     
+        {
+            r_icache_fsm = ICACHE_CC_INVAL;
+            r_icache_fsm_save = r_icache_fsm;
+            break;
+        }
+
+        // external tlb invalidate request
+        if ( r_dcache_itlb_inval_req )
+        {
+            r_itlb_inval_req = true;
+            r_icache_fsm = ICACHE_TLB_CC_INVAL;
+            r_icache_fsm_save = r_icache_fsm;
+            break;
+        }
+       
+        if ( !r_icache_miss_req )
+        {
+            if ( r_vci_rsp_ins_error ) 
+            {
+                r_icache_error_type = MMU_READ_DATA_ILLEGAL_ACCESS; 
+                r_icache_bad_vaddr = ireq.addr;
+                r_icache_fsm = ICACHE_ERROR;
+
+            	if ( r_icache_inval_tlb_rsp ) r_icache_inval_tlb_rsp = false;
+            	if ( r_icache_inval_rsp ) r_icache_inval_rsp = false;
+                break;
+            }
+
+            if ( r_icache_inval_tlb_rsp ) // Miss read response and tlb invalidation
+            {
+                if ( r_icache_cleanup_req ) break;
+                r_icache_cleanup_req = true;
+                r_icache_cleanup_line = r_icache_paddr_save.read() >> (uint32_log2(m_icache_words) + 2); 
+                m_cpt_cc_cleanup_ins++;	
+                r_icache_fsm = ICACHE_IDLE;
+                r_icache_inval_tlb_rsp = false;
+                if ( r_icache_inval_rsp ) r_icache_inval_rsp = false;
+                break;
+            }
+	
+            if ( r_icache_inval_rsp ) // Miss read response and tlb invalidation
+            {
+                if ( r_icache_cleanup_req ) break;
+                r_icache_cleanup_req = true;
+                r_icache_cleanup_line = r_icache_paddr_save.read() >> (uint32_log2(m_icache_words) + 2);  
+                m_cpt_cc_cleanup_ins++;
+                r_icache_fsm = ICACHE_IDLE;
+                r_icache_inval_rsp = false;
+                break;
+            }
+            r_icache_fsm = ICACHE_MISS_UPDT;  
+        }	
+        break;
+    }
+    ////////////////////
+    case ICACHE_UNC_WAIT:
+    {
+        // external cache invalidate request
+        if ( r_tgt_icache_req ) 
+        {
+            r_icache_fsm = ICACHE_CC_INVAL;
+            r_icache_fsm_save = r_icache_fsm;
+            break;
+        }
+
+        // external tlb invalidate request
+        if ( r_dcache_itlb_inval_req )
+        {
+            r_itlb_inval_req = true;
+            r_icache_fsm = ICACHE_TLB_CC_INVAL;
+            r_icache_fsm_save = r_icache_fsm;
+            break;
+        }
+
+        if ( !r_icache_unc_req )
+        {
+            if ( r_vci_rsp_ins_error ) 
+            {
+                r_icache_error_type = MMU_READ_DATA_ILLEGAL_ACCESS;    
+                r_icache_bad_vaddr = ireq.addr;
+                r_icache_fsm = ICACHE_ERROR;
+
+            	if ( r_icache_inval_tlb_rsp ) r_icache_inval_tlb_rsp = false;
+                break;
+            }
+
+            if ( r_icache_inval_tlb_rsp ) // Miss read response and tlb invalidation
+            {
+                r_icache_inval_tlb_rsp = false;
+                r_icache_fsm = ICACHE_IDLE;
+                break;
+            }
+
+            // Miss read response and no invalidation
+            r_icache_buf_unc_valid = true;
+            r_icache_fsm = ICACHE_IDLE;
+        }	
+        break;
+    }
+    //////////////////////
+    case ICACHE_MISS_UPDT:
+    {
+        m_cost_ins_miss_frz++;
+
+        // external cache invalidate request
+        if ( r_tgt_icache_req )   
+        {
+            r_icache_fsm = ICACHE_CC_INVAL;
+            r_icache_fsm_save = r_icache_fsm;
+            break;
+        }
+
+        // external tlb invalidate request
+        if ( r_dcache_itlb_inval_req )
+        {
+            r_itlb_inval_req = true;
+            r_icache_fsm = ICACHE_TLB_CC_INVAL;
+            r_icache_fsm_save = r_icache_fsm;
+            break;
+        }
+
+        if ( r_icache_inval_tlb_rsp ) // tlb invalidation
+        {
+            if ( r_icache_cleanup_req ) break;
+            r_icache_cleanup_req = true;
+            r_icache_cleanup_line = r_icache_paddr_save.read() >> (uint32_log2(m_icache_words) + 2); 
+            m_cpt_cc_cleanup_ins++; 
+            r_icache_inval_tlb_rsp = false;
+            if ( r_icache_inval_rsp ) r_icache_inval_rsp = false;
+            r_icache_fsm = ICACHE_IDLE;
+            break;
+        }
+
+        if ( !r_icache_cleanup_req ) // Miss update and no invalidation
+        {
+            if ( r_icache_inval_rsp ) // invalidation
+            {
+                r_icache_cleanup_req = true;
+                r_icache_cleanup_line = r_icache_paddr_save.read() >> (uint32_log2(m_icache_words) + 2); 
+                m_cpt_cc_cleanup_ins++;	
+                r_icache_fsm = ICACHE_IDLE;
+                r_icache_inval_rsp = false;
+            } 
+	    else
+	    {
+                data_t* buf = r_icache_miss_buf;
+                paddr_t  victim_index = 0;
+                m_cpt_icache_dir_write++;
+                m_cpt_icache_data_write++;
+
+                bool icache_cleanup_req = r_icache.update(r_icache_paddr_save.read(), buf, &victim_index);
+                r_icache_cleanup_req = icache_cleanup_req;
+                r_icache_cleanup_line = victim_index;                        
+                if (icache_cleanup_req) m_cpt_cc_cleanup_ins++;
+                r_icache_fsm = ICACHE_IDLE;
+	    }
+        }
+        break;
+    }
+    ///////////////////
+    case ICACHE_ERROR:
+    {
+        r_vci_rsp_ins_error = false;
+        r_dcache_rsp_itlb_error = false;
+        irsp.valid = true;
+        irsp.error = true;
+        irsp.instruction = 0; 
+        r_icache_fsm = ICACHE_IDLE;
+        break;
+    }
+    /////////////////////
+    case ICACHE_CC_INVAL:  
+    {                       
+        m_cpt_icache_dir_read += m_icache_ways;
+        /* activity counter */
+        if ( (( r_icache_fsm_save == ICACHE_BIS ) ||( r_icache_fsm_save == ICACHE_MISS_WAIT ) || ( r_icache_fsm_save == ICACHE_MISS_UPDT ) ) && ( ireq.valid ) )        
+        {
+            m_cost_ins_miss_frz++;
+        }
+        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_SEL ) || ( r_icache_fsm_save == ICACHE_TLB2_UPDT_SEL )) && (ireq.valid) )
+        {
+            m_cost_ins_tlb_miss_frz++;
+        }
+
+        // invalidate cache
+        if( (( r_icache_fsm_save == ICACHE_MISS_WAIT ) || ( r_icache_fsm_save == ICACHE_MISS_UPDT ) /*|| 
+             ( r_icache_fsm_save == ICACHE_UNC_WAIT )*/ ) && 
+            ((r_icache_paddr_save.read() & ~((m_icache_words<<2)-1)) == (r_tgt_addr.read() & ~((m_icache_words<<2)-1))) ) 
+        {
+            r_icache_inval_rsp = true;
+            r_tgt_icache_rsp = false;
+        } 
+        else 
+        {
+            r_tgt_icache_rsp = r_icache.inval(r_tgt_addr.read());
+        }
+        r_tgt_icache_req = false;
+        r_icache_fsm = r_icache_fsm_save;
+        break;
+    }
+    /////////////////////////
+    case ICACHE_TLB_CC_INVAL:
+    {
+        /* activity counter */
+        if ( (( r_icache_fsm_save == ICACHE_BIS ) ||( r_icache_fsm_save == ICACHE_MISS_WAIT ) || ( r_icache_fsm_save == ICACHE_MISS_UPDT ) ) && ( ireq.valid ) )        
+        {
+            m_cost_ins_miss_frz++;
+        }
+        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_SEL ) || ( r_icache_fsm_save == ICACHE_TLB2_UPDT_SEL )) && (ireq.valid) )
+        {
+            m_cost_ins_tlb_miss_frz++;
+        }
+
+        if ( r_itlb_inval_req ) break;
+        // 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_UPDT_SEL ) || ( r_icache_fsm_save == ICACHE_TLB2_UPDT_SEL )) && 
+            (((r_icache_paddr_save.read() & ~((m_icache_words<<2)-1)) >> (uint32_log2(m_icache_words) + 2) ) == r_dcache_itlb_inval_line.read()) ) 
+        {
+            r_icache_inval_tlb_rsp = true;
+        } 
+        else if (((r_icache_fsm_save == ICACHE_BIS)||(r_icache_fsm_save == ICACHE_MISS_WAIT) ||
+               /* (r_icache_fsm_save == ICACHE_UNC_WAIT)||*/(r_icache_fsm_save == ICACHE_MISS_UPDT)) && 
+                (r_icache_tlb_nline.read() == r_dcache_itlb_inval_line.read()))
+        {
+            r_icache_inval_tlb_rsp = true;
+        }
+        r_dcache_itlb_inval_req = false;
+        r_itlb_translation_valid = false;
+        r_icache_ptba_ok = false;
+        r_icache_fsm = r_icache_fsm_save;
+        break;
+    }
+    } // end switch r_icache_fsm
+
+#ifdef SOCLIB_MODULE_DEBUG
+    std::cout << name() << " Instruction Response: " << irsp << std::endl;
+#endif
+
+    ////////////////////////////////////////////////////////////////////////////////////
+    //      INVAL ITLB CHECK FSM 
+    ////////////////////////////////////////////////////////////////////////////////////////
+    switch(r_inval_itlb_fsm) {
+    /////////////////////
+    case INVAL_ITLB_IDLE:
+    {
+        if ( r_itlb_inval_req )
+        {
+            r_ccinval_itlb_way = 0; 
+            r_ccinval_itlb_set = 0;
+            r_inval_itlb_fsm = INVAL_ITLB_CHECK;   
+            m_cost_ins_tlb_inval_frz++; 
+        }   
+        break;
+    }
+    ////////////////////////////
+    case INVAL_ITLB_CHECK:
+    {
+        m_cost_ins_tlb_inval_frz++; 
+
+        size_t way = r_ccinval_itlb_way; 
+        size_t set = r_ccinval_itlb_set;
+        bool end = false;        
+        bool tlb_hit = icache_tlb.cccheck(r_dcache_itlb_inval_line.read(), way, set, &way, &set, &end); 
+    
+        if ( tlb_hit )
+        {
+            r_ccinval_itlb_way = way; 
+            r_ccinval_itlb_set = set;
+            r_itlb_cc_check_end = end;
+            r_inval_itlb_fsm = INVAL_ITLB_INVAL; 
+            m_cpt_ins_tlb_inval++;   
+        }        
+        else
+        {
+            r_inval_itlb_fsm = INVAL_ITLB_CLEAR;    
+        }
+        break;
+    }
+    /////////////////////////
+    case INVAL_ITLB_INVAL:
+    {
+        m_cost_ins_tlb_inval_frz++;
+ 
+        icache_tlb.ccinval(r_ccinval_itlb_way, r_ccinval_itlb_set);
+
+        if ( !r_itlb_cc_check_end )
+        {
+            r_inval_itlb_fsm = INVAL_ITLB_CHECK; 
+        }
+        else
+        {
+            r_inval_itlb_fsm = INVAL_ITLB_CLEAR;    
+        }
+        break;
+    }
+    ////////////////////
+    case INVAL_ITLB_CLEAR:
+    {
+        r_itlb_inval_req = false;
+        r_itlb_cc_check_end = false;
+        r_ccinval_itlb_way = 0; 
+        r_ccinval_itlb_set = 0; 
+        r_inval_itlb_fsm = INVAL_ITLB_IDLE;    
+        m_cost_ins_tlb_inval_frz++; 
+        break;
+    }
+    } // end switch r_inval_itlb_fsm
+
+    ////////////////////////////////////////////////////////////////////////////////////
+    //      DCACHE FSM 
+    //
+    // Both the Cacheability Table, and the MMU cached bit are used to define
+    // the cacheability.
+    // 
+    // There is 14 mutually exclusive conditions to exit the IDLE state.
+    // Seven configurations corresponding to an XTN request from processor:
+    // - Context switch => CTXT_SWITCH state
+    // - Flush dcache => DCACHE_FLUSH state 
+    // - Flush icache => ICACHE_FLUSH state 
+    // - Invalidate a dtlb entry => DTLB_INVAL state
+    // - Invalidate a itlb entry => ITLB_INVAL state
+    // - Invalidate a dcache line => DCACHE_INVAL state
+    // - Invalidate a icache line => ICACHE_INVAL state
+    // Seven configurations corresponding to various read miss or write requests: 
+    // - TLB miss(in case hit_p miss) => TLB1_READ state
+    // - TLB miss(in case hit_p hit) => TLB2_READ state
+    // - Hit in TLB but VPN changed => BIS state
+    // - Cached read miss => MISS_REQ state
+    // - Uncache read miss => UNC_REQ state
+    // - Write hit => WRITE_UPDT state
+    // - Write miss => WRITE_REQ
+    //
+    // The r_vci_rsp_data_error flip-flop is set by the VCI_RSP controller and reset 
+    // by DCACHE-FSM when its state is in DCACHE_ERROR. 
+    //--------------------------------------------------------------------- 
+    // Data TLB: 
+    //  
+    // - int        ET          (00: unmapped; 01: unused or PTD)
+    //                          (10: PTE new;  11: PTE old      )
+    // - bool       cachable    (cached bit)
+    // - bool       writable    (writable bit) 
+    // - bool       executable  (** not used alwayse false)
+    // - bool       user        (access in user mode allowed)
+    // - bool       global      (PTE not invalidated by a TLB flush)
+    // - bool       dirty       (page has been modified) 
+    // - uint32_t   vpn         (virtual page number)
+    // - uint32_t   ppn         (physical page number)
+    ////////////////////////////////////////////////////////////////////////////////////////
+
+    switch (r_dcache_fsm) {
+    //////////////////////
+    case DCACHE_WRITE_REQ:
+    {
+        // external cache invalidate request
+        if ( r_tgt_dcache_req ) 
+        {
+            r_dcache_fsm = DCACHE_CC_CHECK;
+            r_dcache_fsm_save = r_dcache_fsm;
+            break;
+        }
+
+        // try to post the write request in the write buffer
+        if ( !r_dcache_write_req )     // no previous write transaction     
+        {
+            if ( r_wbuf.wok(r_dcache_paddr_save) )   // write request in the same cache line 
+            {    
+                r_wbuf.write(r_dcache_paddr_save.read(), r_dcache_be_save.read(), r_dcache_wdata_save);
+                // closing the write packet if uncached
+                if ( !r_dcache_cached_save )
+                { 
+                    r_dcache_write_req = true;
+                }
+            } 
+            else 
+            {    // close the write packet if write request not in the same cache line
+                r_dcache_write_req = true;
+                m_cost_write_frz++;
+                break;  //  posting not possible : stay in DCACHE_WRITEREQ state
+            }
+        } 
+        else     //  previous write transaction not completed
+        {
+            m_cost_write_frz++;
+            break;  //  posting not possible : stay in DCACHE_WRITEREQ state
+        }
+
+        // close the write packet if the next processor request is not a write 
+        if ( !dreq.valid || (dreq.type != iss_t::DATA_WRITE)) 
+        {
+            r_dcache_write_req = true;
+        }
+        
+        // The next state and the processor request parameters are computed 
+        // as in the DCACHE_IDLE state (see below ...)
+    }
+    /////////////////
+    case DCACHE_IDLE:
+    {
+        // external cache invalidate request
+        if ( r_tgt_dcache_req )   
+        {
+            r_dcache_fsm = DCACHE_CC_CHECK;
+            r_dcache_fsm_save = DCACHE_IDLE;
+            break;
+        }        
+
+        // ins tlb cleanup
+        if ( r_dcache_itlb_cleanup_req )
+        {
+            r_dcache_fsm = DCACHE_ITLB_CLEANUP;
+            break;
+        }    
+        // ins tlb miss
+    	if ( r_itlb_read_dcache_req )
+    	{
+            if ( dreq.valid ) m_cost_ins_tlb_occup_cache_frz++;		
+            data_t rsp_itlb_miss;
+            data_t rsp_itlb_ppn;
+
+    	    bool itlb_hit_dcache = r_dcache.read(r_icache_paddr_save, &rsp_itlb_miss);
+	    if ( r_itlb_k_read_dcache && itlb_hit_dcache )
+	    {	
+            r_itlb_k_read_dcache = false;
+	        bool itlb_hit_ppn = r_dcache.read(r_icache_paddr_save.read()+4, &rsp_itlb_ppn);
+            assert(itlb_hit_ppn && "Address of pte[64-32] and pte[31-0] should be successive");
+	    }
+
+        m_cpt_dcache_data_read += m_dcache_ways;
+        m_cpt_dcache_dir_read += m_dcache_ways;
+        
+        if ( itlb_hit_dcache )  // ins TLB request hits in data cache 
+    	{
+            if (!((rsp_itlb_miss & PTE_T_MASK ) >> PTE_T_SHIFT)) m_cpt_ins_tlb_hit_dcache++;		    
+            r_dcache_rsp_itlb_miss = rsp_itlb_miss; 
+            r_dcache_rsp_itlb_ppn = rsp_itlb_ppn; 
+            r_itlb_read_dcache_req = false;
+            r_dcache_fsm = DCACHE_IDLE;
+                
+            // set TLB bit if it's a PTE
+            if ( !((rsp_itlb_miss & PTE_T_MASK ) >> PTE_T_SHIFT) )
+            {
+                bool set_hit = r_dcache.setinbit(r_icache_paddr_save, r_dcache_in_itlb, true);
+                assert(set_hit && "D$ IDLE ITLB set hit error");  
+            }
+        }
+        else                    // ins TLB request miss in data cache
+    	{
+            r_dcache_itlb_read_req = true;
+            r_dcache_fsm = DCACHE_ITLB_READ;
+        }
+    	}
+    	else if ( r_itlb_acc_dcache_req ) // ins tlb write access bit
+    	{
+            if ( dreq.valid ) m_cost_ins_tlb_occup_cache_frz++;
+            
+            data_t rsp_itlb_miss;
+    	    bool itlb_hit_dcache = r_dcache.read(r_icache_paddr_save, &rsp_itlb_miss);
+            if ( itlb_hit_dcache )
+            {
+                r_dcache_itlb_ll_acc_req = true;
+                r_dcache_fsm = DCACHE_ITLB_LL_WAIT;	    	
+                m_cpt_dcache_data_write++;	    
+            }
+            else
+            {
+                r_itlb_acc_dcache_req = false;
+                r_itlb_acc_redo_req = true;
+                r_dcache_fsm = DCACHE_IDLE;
+            }    
+    	}
+        else if (dreq.valid) 
+        {
+            pte_info_t  dcache_pte_info;
+            int         xtn_opcod        = (int)dreq.addr/4;
+            paddr_t     tlb_dpaddr       = 0;        // physical address obtained from TLB
+            paddr_t     spc_dpaddr       = 0;        // physical adress obtained from PPN_save (speculative)
+            bool        dcache_hit_t     = false;    // hit on 4Kilo TLB
+            bool        dcache_hit_x     = false;    // VPN unmodified (can use spc_dpaddr)
+            bool        dcache_hit_p     = false;    // PTP unmodified (can skip first level page table walk)
+            bool        dcache_hit_c     = false;    // Cache hit
+            bool        dcache_cached    = false;    // cacheable access (read or write)
+            size_t      dcache_tlb_way   = 0;        // selected way (in case of cache hit)
+            size_t      dcache_tlb_set   = 0;        // selected set (Y field in address)
+            data_t      dcache_rdata     = 0;        // read data
+            paddr_t     dcache_tlb_nline = 0;        // TLB NLINE 
+
+            m_cpt_dcache_data_read += m_dcache_ways;
+            m_cpt_dcache_dir_read += m_dcache_ways;
+
+            // Decoding READ XTN requests from processor
+            // They are executed in this DCACHE_IDLE state
+
+            if (dreq.type == iss_t::XTN_READ) 
+            {
+                switch(xtn_opcod) {
+                case iss_t::XTN_INS_ERROR_TYPE:
+                    drsp.rdata = (uint32_t)r_icache_error_type;
+                    r_icache_error_type = MMU_NONE;
+                    drsp.valid = true;
+                    drsp.error = false;
+                    break;
+                case iss_t::XTN_DATA_ERROR_TYPE:
+                    drsp.rdata = (uint32_t)r_dcache_error_type;
+                    r_dcache_error_type = MMU_NONE;
+                    drsp.valid = true;
+                    drsp.error = false;
+                    break;
+                case iss_t::XTN_INS_BAD_VADDR:
+                    drsp.rdata = (uint32_t)r_icache_bad_vaddr;       
+                    drsp.valid = true;
+                    drsp.error = false;
+                    break;
+                case iss_t::XTN_DATA_BAD_VADDR:
+                    drsp.rdata = (uint32_t)r_dcache_bad_vaddr;        
+                    drsp.valid = true;
+                    drsp.error = false;
+                    break;
+                case iss_t::XTN_PTPR:
+                    drsp.rdata = (uint32_t)r_mmu_ptpr;
+                    drsp.valid = true;
+                    drsp.error = false;
+                    break;
+                case iss_t::XTN_TLB_MODE:
+                    drsp.rdata = (uint32_t)r_mmu_mode;
+                    drsp.valid = true;
+                    drsp.error = false;
+                    break;
+                case iss_t::XTN_MMU_PARAMS:
+                    drsp.rdata = (uint32_t)r_mmu_params;
+                    drsp.valid = true;
+                    drsp.error = false;
+                    break;
+                case iss_t::XTN_MMU_RELEASE:
+                    drsp.rdata = (uint32_t)r_mmu_release;
+                    drsp.valid = true;
+                    drsp.error = false;
+                    break;
+                case iss_t::XTN_MMU_WORD_LO:
+                    drsp.rdata = (uint32_t)r_mmu_word_lo;
+                    drsp.valid = true;
+                    drsp.error = false;
+                    break;
+                case iss_t::XTN_MMU_WORD_HI:
+                    drsp.rdata = (uint32_t)r_mmu_word_hi;
+                    drsp.valid = true;
+                    drsp.error = false;
+                    break;
+                default:
+                    r_dcache_error_type = MMU_READ_UNDEFINED_XTN; 
+                    r_dcache_bad_vaddr  = dreq.addr;
+                    drsp.valid = true;
+                    drsp.error = true;
+                    break;
+                }
+                r_dcache_fsm = DCACHE_IDLE;
+                break;
+            }
+
+            // Decoding WRITE XTN requests from processor
+            // If there is no privilege violation, they are not executed in this DCACHE_IDLE state,
+            // but in the next state, because they generally require access to the caches or the TLBs 
+
+            if (dreq.type == iss_t::XTN_WRITE) 
+            {
+                drsp.valid = false;
+                drsp.error = false;
+                drsp.rdata = 0;
+                r_dcache_wdata_save = dreq.wdata;   
+                switch(xtn_opcod) {     
+
+                case iss_t::XTN_PTPR:       // context switch : checking the kernel mode
+                                            // both instruction & data TLBs must be flushed
+                    if ((dreq.mode == iss_t::MODE_HYPER) || (dreq.mode == iss_t::MODE_KERNEL)) 
+                    {
+                        r_mmu_ptpr = dreq.wdata;
+                        r_icache_error_type = MMU_NONE;
+                        r_dcache_error_type = MMU_NONE;
+                        r_dcache_type_save = dreq.addr/4; 
+                        r_dcache_xtn_req = true;
+                        r_dcache_fsm = DCACHE_CTXT_SWITCH;
+                    } 
+                    else 
+                    { 
+                        r_dcache_error_type = MMU_WRITE_PRIVILEGE_VIOLATION; 
+                        r_dcache_bad_vaddr  = dreq.addr;
+                        drsp.valid = true;
+                        drsp.error = true;
+                        r_dcache_fsm = DCACHE_IDLE;
+                    }
+                    break;
+
+                case iss_t::XTN_TLB_MODE:     // modifying TLBs mode : checking the kernel mode
+                    if ((dreq.mode == iss_t::MODE_HYPER) || (dreq.mode == iss_t::MODE_KERNEL)) 
+                    {
+                        r_mmu_mode = (int)dreq.wdata;
+                        drsp.valid = true;
+                    } 
+                    else 
+                    {
+                        r_dcache_error_type = MMU_WRITE_PRIVILEGE_VIOLATION; 
+                        r_dcache_bad_vaddr  = dreq.addr;
+                        drsp.valid = true;
+                        drsp.error = true;
+                    }
+                    r_dcache_fsm = DCACHE_IDLE;
+                    break;
+
+                case iss_t::XTN_DTLB_INVAL:     //  checking the kernel mode
+                    if ((dreq.mode == iss_t::MODE_HYPER) || (dreq.mode == iss_t::MODE_KERNEL)) 
+                    {
+                        r_dcache_fsm = DCACHE_DTLB_INVAL;  
+                    } 
+                    else 
+                    {
+                        r_dcache_error_type = MMU_WRITE_PRIVILEGE_VIOLATION; 
+                        r_dcache_bad_vaddr  = dreq.addr;
+                        drsp.valid = true;
+                        drsp.error = true;
+                	r_dcache_fsm = DCACHE_IDLE;
+                    }
+                    break;
+
+                case iss_t::XTN_ITLB_INVAL:     //  checking the kernel mode
+                    if ((dreq.mode == iss_t::MODE_HYPER) || (dreq.mode == iss_t::MODE_KERNEL)) 
+                    {
+                        r_dcache_xtn_req = true;
+                        r_dcache_type_save = dreq.addr/4;
+                        r_dcache_fsm = DCACHE_ITLB_INVAL;  
+                    } 
+                    else 
+                    {
+                        r_dcache_error_type = MMU_WRITE_PRIVILEGE_VIOLATION; 
+                        r_dcache_bad_vaddr  = dreq.addr;
+                        drsp.valid = true;
+                        drsp.error = true;
+                	r_dcache_fsm = DCACHE_IDLE;
+                    }
+                    break;
+
+                case iss_t::XTN_DCACHE_INVAL:   // cache inval can be executed in user mode.
+                    r_dcache_fsm = DCACHE_DCACHE_INVAL;
+                    break;
+
+                case iss_t::XTN_MMU_DCACHE_PA_INV:   // cache inval can be executed in user mode.
+                    r_dcache_fsm = DCACHE_DCACHE_INVAL_PA;
+                    break;
+
+                case iss_t::XTN_DCACHE_FLUSH:   // cache flush can be executed in user mode.
+                    r_dcache_type_save = dreq.addr/4; 
+                    r_dcache_xtn_req = true;
+                    r_dcache_way = 0;
+                    r_dcache_set = 0;
+                    r_dcache_fsm = DCACHE_DCACHE_FLUSH; 
+                    break;
+
+                case iss_t::XTN_ICACHE_INVAL:   // cache inval can be executed in user mode.
+                    r_dcache_type_save = dreq.addr/4; 
+                    r_dcache_xtn_req = true;
+                    r_dcache_fsm = DCACHE_ICACHE_INVAL; 
+                    break;
+
+                case iss_t::XTN_MMU_ICACHE_PA_INV:   // cache inval can be executed in user mode.
+                    r_dcache_type_save = dreq.addr/4; 
+                    r_dcache_xtn_req = true;
+                    r_dcache_fsm = DCACHE_ICACHE_INVAL_PA; 
+                    break;
+
+                case iss_t::XTN_ICACHE_FLUSH:   // cache flush can be executed in user mode.
+                    r_dcache_type_save = dreq.addr/4; 
+                    r_dcache_xtn_req = true; 
+                    r_dcache_fsm = DCACHE_ICACHE_FLUSH;
+                    break;
+
+                case iss_t::XTN_SYNC:           // cache synchronization can be executed in user mode.
+                    if (r_wbuf.rok())
+                    {
+                        r_dcache_fsm = DCACHE_DCACHE_SYNC; 
+                    }
+                    else
+                    {
+                        drsp.valid = true;
+                        r_dcache_fsm = DCACHE_IDLE;
+                    }
+                    break;
+
+                case iss_t::XTN_MMU_WORD_LO: // modifying MMU misc registers
+                    if ((dreq.mode == iss_t::MODE_HYPER) || (dreq.mode == iss_t::MODE_KERNEL)) 
+                    {
+                        r_mmu_word_lo = (int)dreq.wdata;
+                        drsp.valid = true;
+                    } 
+                    else 
+                    {
+                        r_dcache_error_type = MMU_WRITE_PRIVILEGE_VIOLATION; 
+                        r_dcache_bad_vaddr  = dreq.addr;
+                        drsp.valid = true;
+                        drsp.error = true;
+                    }
+                    r_dcache_fsm = DCACHE_IDLE;
+                    break;
+
+                case iss_t::XTN_MMU_WORD_HI: // modifying MMU misc registers
+                    if ((dreq.mode == iss_t::MODE_HYPER) || (dreq.mode == iss_t::MODE_KERNEL)) 
+                    {
+                        r_mmu_word_hi = (int)dreq.wdata;
+                        drsp.valid = true;
+                    } 
+                    else 
+                    {
+                        r_dcache_error_type = MMU_WRITE_PRIVILEGE_VIOLATION; 
+                        r_dcache_bad_vaddr  = dreq.addr;
+                        drsp.valid = true;
+                        drsp.error = true;
+                    }
+                    r_dcache_fsm = DCACHE_IDLE;
+                    break;
+
+                case iss_t::XTN_ICACHE_PREFETCH:
+                case iss_t::XTN_DCACHE_PREFETCH:
+                    drsp.valid = true;
+                    drsp.error = false;
+                    break;
+                    
+                default:
+                    r_dcache_error_type = MMU_WRITE_UNDEFINED_XTN; 
+                    r_dcache_bad_vaddr  = dreq.addr;
+                    drsp.valid = true;
+                    drsp.error = true;
+                    r_dcache_fsm = DCACHE_IDLE;
+                    break;
+                } // end switch xtn_opcod
+
+                break;
+            } // end if XTN_WRITE
+
+            // Evaluating dcache_hit_t, dcache_hit_x, dcache_hit_p, dcache_hit_c,
+            // dcache_pte_info, dcache_tlb_way, dcache_tlb_set & dpaddr & cacheability 
+            // - If MMU activated : cacheability is defined by the cachable bit in the TLB
+            // - If MMU not activated : cacheability is defined by the segment table.
+            
+            // For instrumentation: is User access ? 
+            r_dreq_isUser_save = (dreq.mode == iss_t::MODE_USER) ? true : false;        
+
+            if ( !(r_mmu_mode.read() & DATA_TLB_MASK) ) // MMU not activated
+            {
+                dcache_hit_t  = true;       
+                dcache_hit_x  = true;   
+                dcache_hit_p  = true;  
+                tlb_dpaddr    = dreq.addr; 
+                spc_dpaddr    = dreq.addr;    
+                dcache_cached = m_cacheability_table[dreq.addr] && 
+                    ((dreq.type != iss_t::DATA_LL)  && (dreq.type != iss_t::DATA_SC) &&
+                     (dreq.type != iss_t::XTN_READ) && (dreq.type != iss_t::XTN_WRITE));     
+            } 
+            else                                                            // MMU activated
+            {
+                m_cpt_data_tlb_read++;
+                dcache_hit_t  = dcache_tlb.cctranslate(dreq.addr, &tlb_dpaddr, &dcache_pte_info, 
+                                                       &dcache_tlb_nline, &dcache_tlb_way, &dcache_tlb_set);                  
+                dcache_hit_x  = (((vaddr_t)r_dcache_vpn_save << PAGE_K_NBITS) == (dreq.addr & ~PAGE_K_MASK)) && r_dtlb_translation_valid; 
+                dcache_hit_p  = (((dreq.addr >> PAGE_M_NBITS) == r_dcache_id1_save) && r_dcache_ptba_ok );
+                spc_dpaddr    = ((paddr_t)r_dcache_ppn_save << PAGE_K_NBITS) | (paddr_t)((dreq.addr & PAGE_K_MASK));
+                dcache_cached = dcache_pte_info.c && 
+                                ((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 ( !(r_mmu_mode.read() & DATA_CACHE_MASK) )   // cache not actived
+            {
+                dcache_cached = false;
+            }
+
+            // dcache_hit_c & dcache_rdata
+            if ( dcache_cached )    // using speculative physical address for cached access
+            {
+                dcache_hit_c = r_dcache.read(spc_dpaddr, &dcache_rdata);
+            } 
+            else                    // using actual physical address for uncached access
+            {
+                dcache_hit_c = false;
+            }
+            if ( r_mmu_mode.read() & DATA_TLB_MASK ) 
+            {
+                // Checking access rights
+                if ( dcache_hit_t ) 
+                {
+                    if (!dcache_pte_info.u && (dreq.mode == iss_t::MODE_USER)) 
+                    {
+                        if ((dreq.type == iss_t::DATA_READ)||(dreq.type == iss_t::DATA_LL))
+                        {
+                            r_dcache_error_type = MMU_READ_PRIVILEGE_VIOLATION;
+                        }
+                        else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
+                        {
+                            r_dcache_error_type = MMU_WRITE_PRIVILEGE_VIOLATION;
+                        }  
+                        r_dcache_bad_vaddr = dreq.addr;
+                        drsp.valid = true;
+                        drsp.error = true;
+                        drsp.rdata = 0;
+                        r_dcache_fsm = DCACHE_IDLE;
+                        break;
+                    }
+                    if (!dcache_pte_info.w && ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))) 
+                    {
+                        r_dcache_error_type = MMU_WRITE_ACCES_VIOLATION;  
+                        r_dcache_bad_vaddr = dreq.addr;
+                        drsp.valid = true;
+                        drsp.error = true;
+                        drsp.rdata = 0;
+                        r_dcache_fsm = DCACHE_IDLE;
+                        break;
+                    }
+                }
+
+                // update LRU, save ppn, vpn and page type
+                if ( dcache_hit_t ) {
+                    dcache_tlb.setlru(dcache_tlb_way,dcache_tlb_set); 
+                    r_dcache_ppn_save = tlb_dpaddr >> PAGE_K_NBITS;
+                    r_dcache_vpn_save = dreq.addr >> PAGE_K_NBITS;
+                    r_dcache_tlb_nline = dcache_tlb_nline;
+                    r_dtlb_translation_valid = true;
+                }
+                else
+                {
+                    r_dtlb_translation_valid = false;
+                }
+
+            } // end if MMU activated
+
+            // compute next state 
+            if ( !dcache_hit_p && !dcache_hit_t )  // TLB miss
+            {
+                r_dcache_tlb_paddr = (paddr_t)r_mmu_ptpr << (INDEX1_NBITS+2) | (paddr_t)((dreq.addr>>PAGE_M_NBITS)<<2);
+                r_dcache_fsm = DCACHE_DTLB1_READ_CACHE;
+                m_cpt_data_tlb_miss++;
+                m_cost_data_tlb_miss_frz++;
+            }
+            else if ( dcache_hit_p && !dcache_hit_t )  // TLB Miss with possibility of bypass first level page
+            {
+                // walk page table level 2
+                r_dcache_tlb_paddr = (paddr_t)r_dcache_ptba_save | 
+                                     (paddr_t)(((dreq.addr&PTD_ID2_MASK)>>PAGE_K_NBITS) << 3); 
+                r_dcache_fsm = DCACHE_DTLB2_READ_CACHE;
+                m_cpt_data_tlb_miss++;
+                m_cost_data_tlb_miss_frz++;
+            }
+            else if ( dcache_hit_t && !dcache_hit_x && dcache_cached )// cached access with an ucorrect speculative physical address
+            {
+                r_dcache_hit_p_save = dcache_hit_p;
+                r_dcache_fsm = DCACHE_BIS;
+                //m_cost_data_tlb_miss_frz++;
+            }
+            else  // cached or uncached access with a correct speculative physical address
+            {
+                switch( dreq.type ) {
+                    case iss_t::DATA_READ:
+                    case iss_t::DATA_LL:
+                    case iss_t::DATA_SC:
+                        m_cpt_read++;
+                        if ( dcache_hit_c ) 
+                        {
+                            r_dcache_fsm = DCACHE_IDLE;
+                            drsp.valid = true;
+                            drsp.rdata = dcache_rdata;
+                        } 
+                        else 
+                        {
+                            if ( dcache_cached ) 
+                            {
+                                r_dcache_miss_req = true;
+                                r_dcache_fsm = DCACHE_MISS_WAIT;
+                                m_cpt_data_miss++;
+                                m_cost_data_miss_frz++;
+                            } 
+                            else 
+                            {
+                                if ((dreq.type == iss_t::DATA_SC) && !dcache_pte_info.d && (r_mmu_mode.read() & DATA_TLB_MASK))
+                                {
+                                    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
+                                        {
+                                            data_t ptba;
+                                            if (r_dcache.read((paddr_t)r_mmu_ptpr << (INDEX1_NBITS+2) | (paddr_t)((dreq.addr>>PAGE_M_NBITS)<<2), &ptba))
+                                            {
+                                                r_dcache_pte_update = dcache_tlb.getpte(dcache_tlb_way, dcache_tlb_set) | PTE_D_MASK;
+                                                r_dcache_tlb_paddr = (paddr_t)(ptba & ((1<<(m_paddr_nbits - PAGE_K_NBITS))-1)) << PAGE_K_NBITS | 
+                                                    (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
+                                            {
+                                                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++;
+                            }
+                        }
+                        break;
+                case iss_t::DATA_WRITE:
+                        m_cpt_write++;
+                        if ( dcache_cached ) m_cpt_write_cached++;
+                        m_cost_write_frz++;
+                        if ( dcache_hit_c && dcache_cached )    // cache update required
+                        {
+                            r_dcache_fsm = DCACHE_WRITE_UPDT;
+                        } 
+                        else if ( !dcache_pte_info.d && (r_mmu_mode.read() & DATA_TLB_MASK) )   // dirty bit update required
+                        {
+                            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;
+                                    data_t ptba;
+                                    if (r_dcache.read((paddr_t)r_mmu_ptpr << (INDEX1_NBITS+2) | (paddr_t)((dreq.addr>>PAGE_M_NBITS)<<2), &ptba))
+                                        {
+                                            r_dcache_tlb_paddr = (paddr_t)(ptba & ((1<<(m_paddr_nbits - PAGE_K_NBITS))-1)) << PAGE_K_NBITS | (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
+                                        {
+                                            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                                    // no cache update, not dirty bit update
+                        {
+                            r_dcache_fsm = DCACHE_WRITE_REQ;
+                            drsp.valid = true;
+                            drsp.rdata = 0;
+                        }
+                        break;
+                    default:
+                        break;
+                } // end switch dreq.type
+            } // end if next states
+
+            // save values for the next states
+            r_dcache_paddr_save   = tlb_dpaddr;
+            r_dcache_type_save    = dreq.type;
+            r_dcache_wdata_save   = dreq.wdata;
+            r_dcache_be_save      = dreq.be;
+            r_dcache_rdata_save   = dcache_rdata;
+            r_dcache_cached_save  = dcache_cached;
+            r_dcache_dirty_save   = dcache_pte_info.d;
+            r_dcache_tlb_set_save = dcache_tlb_set;
+            r_dcache_tlb_way_save = dcache_tlb_way;
+
+        } // end if dreq.valid
+        else 
+        {   
+            r_dcache_fsm = DCACHE_IDLE;
+        }
+
+        // processor request are not accepted in the WRITE_REQ state 
+        // when the write buffer is not writeable
+
+        if ((r_dcache_fsm == DCACHE_WRITE_REQ) && 
+            (r_dcache_write_req || !r_wbuf.wok(r_dcache_paddr_save))) 
+        {
+            drsp.valid = false;
+        }
+        break;
+    }
+    /////////////////
+    case DCACHE_BIS:
+    {
+        // external cache invalidate request
+        if ( r_tgt_dcache_req )   
+        {
+            r_dcache_fsm = DCACHE_CC_CHECK;
+            r_dcache_fsm_save = r_dcache_fsm;
+            break;
+        }
+
+        // Using tlb entry is invalidated 
+        if ( r_dcache_inval_tlb_rsp )
+        {
+            r_dcache_inval_tlb_rsp = false;
+            r_dcache_fsm = DCACHE_IDLE;
+            break;
+        }
+
+        data_t  dcache_rdata = 0;
+        bool    dcache_hit_c = false;
+        bool    dcache_hit_t = false;
+        paddr_t tlb_dpaddr   = 0;
+
+	dcache_hit_t = dcache_tlb.translate(dreq.addr, &tlb_dpaddr);
+
+	if ( (tlb_dpaddr == r_dcache_paddr_save.read()) && dreq.valid && dcache_hit_t ) 
+	{
+	    // acces always cached in this state
+	    dcache_hit_c = r_dcache.read(r_dcache_paddr_save, &dcache_rdata);
+	    
+	    if ( dreq.type == iss_t::DATA_READ )  // cached read
+	    {
+	        m_cpt_read++;
+	        if ( !dcache_hit_c ) 
+	        {
+	            r_dcache_miss_req = true;
+	            r_dcache_fsm = DCACHE_MISS_WAIT;
+	            m_cpt_data_miss++;
+	            m_cost_data_miss_frz++;
+	        }
+	        else
+	        {
+	            r_dcache_fsm = DCACHE_IDLE;
+	        }
+	        drsp.valid = dcache_hit_c;
+	        drsp.error = false;
+	        drsp.rdata = dcache_rdata;
+	    }
+	    else    // cached write
+	    {
+	        m_cpt_write++;
+	        m_cpt_write_cached++;
+	        if ( dcache_hit_c )    // cache update required
+	        {
+	            r_dcache_rdata_save = dcache_rdata;
+	            r_dcache_fsm = DCACHE_WRITE_UPDT;
+	        } 
+	        else if (!r_dcache_dirty_save && (r_mmu_mode.read() & DATA_TLB_MASK))   // dirty bit update required
+	        {
+                    m_cpt_data_tlb_update_dirty++;
+                    m_cost_data_tlb_update_dirty_frz++;  			
+	            if (dcache_tlb.getpagesize(r_dcache_tlb_way_save, r_dcache_tlb_set_save)) 
+	            {
+	                r_dcache_pte_update = dcache_tlb.getpte(r_dcache_tlb_way_save, r_dcache_tlb_set_save) | 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
+	            {   
+	                if (r_dcache_hit_p_save) 
+	                {
+	                    r_dcache_pte_update = dcache_tlb.getpte(r_dcache_tlb_way_save, r_dcache_tlb_set_save) | 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
+	                {
+	                    r_dcache_pte_update = dcache_tlb.getpte(r_dcache_tlb_way_save, r_dcache_tlb_set_save) | PTE_D_MASK;
+                        data_t ptba;
+            		    if (r_dcache.read((paddr_t)r_mmu_ptpr << (INDEX1_NBITS+2) | (paddr_t)((dreq.addr>>PAGE_M_NBITS)<<2), &ptba))
+                        {
+                	        r_dcache_tlb_paddr = (paddr_t)(ptba & ((1<<(m_paddr_nbits - PAGE_K_NBITS))-1)) << PAGE_K_NBITS | (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
+                        {
+                            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                                    // no cache update, not dirty bit update
+	        {
+	            r_dcache_fsm = DCACHE_WRITE_REQ;
+	            drsp.valid = true;
+	            drsp.rdata = 0;
+	        }
+	    }
+	}
+	else
+	{
+            drsp.valid = false;
+            drsp.error = false;
+            drsp.rdata = 0;
+            r_dcache_fsm = DCACHE_IDLE;
+	}
+        break;
+    }
+    //////////////////////////
+    case DCACHE_LL_DIRTY_WAIT:
+    {
+        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_tlb_ll_dirty_req)
+	{
+        if ( r_vci_rsp_data_error ) // VCI response ko
+        {
+            if (dcache_tlb.getpagesize(r_dcache_tlb_way_save, r_dcache_tlb_set_save)) 
+            {
+                r_dcache_error_type = MMU_WRITE_PT1_ILLEGAL_ACCESS;     
+            }
+            else
+            {
+                r_dcache_error_type = MMU_WRITE_PT2_ILLEGAL_ACCESS;     
+            }
+            r_dcache_bad_vaddr = dreq.addr;
+            r_dcache_fsm = DCACHE_ERROR; 
+
+            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_miss_buf[0] >> PTE_V_SHIFT) )	// unmapped
+            {
+                if (dcache_tlb.getpagesize(r_dcache_tlb_way_save, r_dcache_tlb_set_save))
+                { 
+                    r_dcache_error_type = MMU_WRITE_PT1_UNMAPPED;       
+                }
+                else
+                {
+                    r_dcache_error_type = MMU_WRITE_PT2_UNMAPPED;       
+                }
+                
+                r_dcache_bad_vaddr = dreq.addr;
+                r_dcache_fsm = DCACHE_ERROR;
+
+                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 )
+        	{
+        	    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 )
+            {
+        	    r_dcache_inval_rsp = false;
+                r_dcache_fsm = DCACHE_IDLE;
+                if (r_dcache_sc_updt_dirty) r_dcache_sc_updt_dirty = false;
+            }
+            else
+            {
+                r_dcache_tlb_sc_dirty_req = true;
+                r_dcache_pte_update = r_dcache_miss_buf[0] | r_dcache_pte_update.read();
+                r_dcache_fsm = DCACHE_SC_DIRTY_WAIT; 
+            }
+	    }
+	}
+	break;
+    }
+    //////////////////////////
+    case DCACHE_SC_DIRTY_WAIT:
+    {
+        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_tlb_sc_dirty_req )
+	{
+	    if ( r_vci_rsp_data_error ) // VCI response ko
+	    {
+	        if (dcache_tlb.getpagesize(r_dcache_tlb_way_save, r_dcache_tlb_set_save))
+	        {
+	            r_dcache_error_type = MMU_WRITE_PT1_ILLEGAL_ACCESS;    
+	        }
+	        else
+	        {
+	            r_dcache_error_type = MMU_WRITE_PT2_ILLEGAL_ACCESS;    
+	        }
+	        r_dcache_bad_vaddr = dreq.addr;
+	        r_dcache_fsm = DCACHE_ERROR;
+
+            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 
+	    {
+                // Using tlb entry is invalidated 
+                if ( r_dcache_inval_tlb_rsp )
+                {
+                    r_dcache_inval_tlb_rsp = false;
+                    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;
+		    if (r_dcache_sc_updt_dirty) r_dcache_sc_updt_dirty = false;
+		}
+		else if ( r_dcache_tlb_sc_fail )
+	    {
+		    r_dcache_tlb_ll_dirty_req = true;
+		    r_dcache_tlb_sc_fail = false;
+            r_dcache_fsm = DCACHE_LL_DIRTY_WAIT;
+		    m_cpt_data_tlb_update_dirty++; 
+        }
+		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 dirty bit");
+                    r_dcache_fsm = DCACHE_WRITE_DIRTY; 
+                    m_cpt_dcache_data_write++; 
+		}
+	    }
+	}
+	break;
+    }
+    ////////////////////////////
+    case DCACHE_DTLB1_READ_CACHE:
+    {
+        m_cost_data_tlb_miss_frz++;
+        if ( r_dcache_tlb_ptba_read ) 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;
+        }        
+
+        // Using tlb entry is invalidated 
+        if ( r_dcache_inval_tlb_rsp )
+        {
+            r_dcache_inval_tlb_rsp = false;
+            r_dcache_fsm = DCACHE_IDLE;
+            if ( r_dcache_tlb_ptba_read ) r_dcache_tlb_ptba_read = false;
+            break;
+        }
+
+        data_t tlb_data = 0;
+        bool tlb_hit_cache = r_dcache.read(r_dcache_tlb_paddr, &tlb_data);
+
+        // DTLB request hit in cache
+        if ( tlb_hit_cache )
+        {
+            if ( !(tlb_data >> PTE_V_SHIFT) )	// unmapped
+            {
+                r_dcache_ptba_ok    = false;
+                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
+                {
+                    r_dcache_error_type = MMU_READ_PT1_UNMAPPED;
+                }
+                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
+                {
+                    r_dcache_error_type = MMU_WRITE_PT1_UNMAPPED;
+                }  
+                r_dcache_bad_vaddr  = dreq.addr;
+                r_dcache_fsm        = DCACHE_ERROR;
+            }
+            else if ( (tlb_data & PTE_T_MASK) >> PTE_T_SHIFT )	// PTD
+            {
+                r_dcache_ptba_ok   = true;
+                r_dcache_ptba_save = (paddr_t)(tlb_data & ((1<<(m_paddr_nbits - PAGE_K_NBITS))-1)) << PAGE_K_NBITS;  
+                r_dcache_id1_save  = dreq.addr >> PAGE_M_NBITS;
+                r_dcache_tlb_paddr = (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);
+                if ( r_dcache_tlb_ptba_read )
+                {
+                    paddr_t tlb_dpaddr;
+                    data_t data;
+                    r_dcache_tlb_ptba_read = false;
+                    if (dcache_tlb.translate(dreq.addr, &tlb_dpaddr) && r_dcache.read( (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) ,&data))
+                    {
+                        r_dcache_tlb_ll_dirty_req = true;
+                        r_dcache_fsm = DCACHE_LL_DIRTY_WAIT;
+                    }	        
+                    else
+                    {
+                        r_dcache_fsm = DCACHE_IDLE;
+                    }
+                }
+                else
+                {
+                    r_dcache_fsm = DCACHE_DTLB2_READ_CACHE;
+                }
+            }
+            else	// PTE
+            {
+                m_cpt_data_tlb_hit_dcache++;
+                r_dcache_ptba_ok = false;
+                if ( (m_srcid_rw >> 4) == ((r_dcache_tlb_paddr.read() & ((1<<(m_paddr_nbits - PAGE_M_NBITS))-1)) >> (m_paddr_nbits - PAGE_M_NBITS -10)) ) // local
+                {
+                    if ( (tlb_data & PTE_L_MASK ) >> PTE_L_SHIFT ) // L bit is set
+                    {
+                        r_dcache_pte_update = tlb_data;
+                        r_dcache_fsm = DCACHE_TLB1_UPDT_SEL;
+                    }
+                    else
+                    {
+                        r_dcache_pte_update = tlb_data | PTE_L_MASK;
+                        r_dcache_tlb_ll_acc_req = true;
+                        r_dcache_fsm = DCACHE_TLB1_LL_WAIT;
+                        m_cpt_data_tlb_update_acc++;
+                        m_cost_data_tlb_update_acc_frz++;
+                    }
+                }
+                else // remotely
+                {
+                    if ( (tlb_data & PTE_R_MASK ) >> PTE_R_SHIFT ) // R bit is set
+                    {
+                        r_dcache_pte_update = tlb_data;
+                        r_dcache_fsm = DCACHE_TLB1_UPDT_SEL;
+                    }
+                    else
+                    {
+                        r_dcache_pte_update = tlb_data | PTE_R_MASK;
+                        r_dcache_tlb_ll_acc_req = true;
+                        r_dcache_fsm = DCACHE_TLB1_LL_WAIT;
+                        m_cpt_data_tlb_update_acc++;
+                        m_cost_data_tlb_update_acc_frz++;
+                    }
+                }
+            }
+        }
+        else
+        {
+            // DTLB request miss in cache and walk page table level 1
+            r_dcache_tlb_read_req = true;
+            r_dcache_fsm = DCACHE_TLB1_READ;
+        }
+        break;
+    }
+    ///////////////////////
+    case DCACHE_TLB1_LL_WAIT:
+    {
+        if ( dreq.valid ) m_cost_data_tlb_miss_frz++;
+        m_cost_data_tlb_update_acc_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_tlb_ll_acc_req)
+	{
+            if ( r_vci_rsp_data_error ) // VCI response ko
+            {
+                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
+                {
+                    r_dcache_error_type = MMU_READ_PT1_ILLEGAL_ACCESS;
+                }
+                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
+                {
+                    r_dcache_error_type = MMU_WRITE_PT1_ILLEGAL_ACCESS;
+                } 
+                r_dcache_bad_vaddr = dreq.addr;
+                r_dcache_fsm = DCACHE_ERROR;
+
+		if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
+		if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;		 
+            }
+	    else
+	    {
+		if ( !(r_dcache_miss_buf[0] >> PTE_V_SHIFT) )	// unmapped
+	        {
+               	    if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
+               	    {
+               	        r_dcache_error_type = MMU_READ_PT1_UNMAPPED;
+               	    }
+               	    else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
+               	    {
+               	        r_dcache_error_type = MMU_WRITE_PT1_UNMAPPED;
+               	    }  
+                    r_dcache_bad_vaddr  = dreq.addr;
+                    r_dcache_fsm        = DCACHE_ERROR;
+
+		    if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
+		    if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;	
+	        }
+       		else if ( r_dcache_inval_tlb_rsp )
+       		{
+       		    r_dcache_inval_tlb_rsp = false;
+       		    r_dcache_fsm = DCACHE_IDLE;
+       		}
+		else if ( r_dcache_inval_rsp )
+       		{
+       		    r_dcache_inval_rsp = false;
+       		    r_dcache_fsm = DCACHE_IDLE;
+       		}
+		else
+		{
+		    r_dcache_tlb_sc_acc_req = true;
+		    r_dcache_pte_update = r_dcache_miss_buf[0] | r_dcache_pte_update.read();
+                    r_dcache_fsm = DCACHE_TLB1_SC_WAIT; 
+		}
+	    }
+	}
+	break;
+    }
+    ///////////////////////
+    case DCACHE_TLB1_SC_WAIT:
+    {
+        if ( dreq.valid ) m_cost_data_tlb_miss_frz++;
+        m_cost_data_tlb_update_acc_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_tlb_sc_acc_req )
+	{
+	    if ( r_vci_rsp_data_error ) // VCI response ko
+	    {
+                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
+                {
+                    r_dcache_error_type = MMU_READ_PT1_ILLEGAL_ACCESS;
+                }
+                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
+                {
+                    r_dcache_error_type = MMU_WRITE_PT1_ILLEGAL_ACCESS;
+                } 
+	        r_dcache_bad_vaddr = dreq.addr;
+	        r_dcache_fsm = DCACHE_ERROR; 
+
+		if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
+		if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;	
+	    }
+	    else
+	    {
+        	// Using tlb entry is invalidated 
+        	if ( r_dcache_inval_tlb_rsp )
+        	{
+        	    r_dcache_inval_tlb_rsp = false;
+        	    r_dcache_fsm = DCACHE_IDLE;
+		    if (r_dcache_tlb_sc_fail) r_dcache_tlb_sc_fail = false;
+        	}
+		else if ( r_dcache_inval_rsp )
+        	{
+        	    r_dcache_inval_rsp = false;
+		    if (r_dcache_tlb_sc_fail) r_dcache_tlb_sc_fail = false;
+        	    r_dcache_fsm = DCACHE_IDLE;
+        	}
+	    	else if ( r_dcache_tlb_sc_fail )
+	    	{
+		    r_dcache_tlb_sc_fail = false;
+		    r_dcache_tlb_ll_acc_req = true;
+	    	    r_dcache_fsm = DCACHE_TLB1_LL_WAIT;
+                    m_cpt_data_tlb_update_acc++;
+	    	}
+	    	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_SEL; 
+		    m_cpt_dcache_data_write++;
+	    	}
+	    }
+	}
+	break;
+    }
+    //////////////////////
+    case DCACHE_TLB1_READ:
+    {
+        if ( dreq.valid ) m_cost_data_tlb_miss_frz++;
+        if ( r_dcache_tlb_ptba_read ) 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_tlb_read_req )
+	{	
+            if ( r_vci_rsp_data_error ) // VCI response ko
+            {
+                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
+                {
+                    r_dcache_error_type = MMU_READ_PT1_ILLEGAL_ACCESS;
+                }
+                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
+                {
+                    r_dcache_error_type = MMU_WRITE_PT1_ILLEGAL_ACCESS;
+                } 
+                r_dcache_bad_vaddr = dreq.addr;
+                r_dcache_fsm = DCACHE_ERROR; 
+
+		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_tlb_ptba_read ) r_dcache_tlb_ptba_read = false;
+		break;
+            }
+
+            if ( r_dcache_inval_tlb_rsp )  // TLB miss response and invalidation
+            {
+                r_dcache_fsm = DCACHE_IDLE; 
+            	r_dcache_inval_tlb_rsp = false;
+                if ( r_dcache_tlb_ptba_read ) r_dcache_tlb_ptba_read = false;
+		break;
+            }
+
+	    if ( r_dcache_inval_rsp ) // TLB miss response and cache invalidation
+	    {
+	        if ( r_dcache_cleanup_req ) break;
+                r_dcache_cleanup_req = true;
+                r_dcache_cleanup_line = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words) + 2);  
+		m_cpt_cc_cleanup_data++;
+                r_dcache_fsm = DCACHE_IDLE;
+                r_dcache_inval_rsp = false;
+                if ( r_dcache_tlb_ptba_read ) r_dcache_tlb_ptba_read = false;
+                break;
+	    }
+
+	    // TLB miss response and no invalidation
+	    r_dcache_fsm = DCACHE_TLB1_READ_UPDT;
+	}
+        break;
+    }
+    //////////////////////////
+    case DCACHE_TLB1_READ_UPDT:
+    {
+        m_cost_data_tlb_miss_frz++;
+        if ( r_dcache_tlb_ptba_read ) 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;
+        }        
+
+        // Using tlb entry is invalidated 
+        if ( r_dcache_inval_tlb_rsp )
+        {
+            r_dcache_inval_tlb_rsp = false;
+            r_dcache_fsm = DCACHE_IDLE;
+            if ( r_dcache_tlb_ptba_read ) r_dcache_tlb_ptba_read = false;
+            break;
+        }
+
+        if ( !r_dcache_cleanup_req ) // Miss update and no invalidation
+        {
+            // update dcache
+            data_t   rsp_dtlb_miss = 0;
+            paddr_t  victim_index = 0;
+            size_t way = 0;
+            size_t set = 0;
+
+            // Using tlb entry is in the invalidated cache line  
+            if ( r_dcache_inval_rsp )
+            {
+                r_dcache_cleanup_req = true;
+                r_dcache_cleanup_line = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words) + 2); 
+	        m_cpt_cc_cleanup_data++;	
+                r_dcache_fsm = DCACHE_IDLE;
+                r_dcache_inval_rsp = false;
+                if ( r_dcache_tlb_ptba_read ) r_dcache_tlb_ptba_read = false;
+                break;
+            }
+
+            bool cleanup_req = r_dcache.find(r_dcache_tlb_paddr, r_dcache_in_itlb, r_dcache_in_dtlb, &way, &set, &victim_index);
+            
+	    if ( cleanup_req )
+	    {	    
+		// ins tlb invalidate verification    
+                r_dcache_itlb_inval_req = r_dcache_in_itlb[m_dcache_sets*way+set];
+                r_dcache_itlb_inval_line = victim_index;
+                r_dcache_in_itlb[way*m_dcache_sets+set] = false;
+
+                // data tlb invalidate verification
+                r_dcache_dtlb_inval_req = r_dcache_in_dtlb[m_dcache_sets*way+set]; 
+                r_dcache_dtlb_inval_line = victim_index;
+                r_dcache_in_dtlb[way*m_dcache_sets+set] = false;
+
+                r_dcache_cleanup_req = true; 
+                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;
+	    }
+
+	    r_dcache.update(r_dcache_tlb_paddr, way, set, r_dcache_miss_buf);
+            r_dcache.read(r_dcache_tlb_paddr, &rsp_dtlb_miss);	
+	    m_cpt_data_tlb_occup_cache++;
+
+	    if ( !(rsp_dtlb_miss >> PTE_V_SHIFT) )	// unmapped
+	    {
+                r_dcache_ptba_ok    = false;
+                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
+                {
+                    r_dcache_error_type = MMU_READ_PT1_UNMAPPED;
+                }
+                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
+                {
+                    r_dcache_error_type = MMU_WRITE_PT1_UNMAPPED;
+                } 
+                r_dcache_bad_vaddr  = dreq.addr;
+                r_dcache_fsm        = DCACHE_ERROR;
+                if ( r_dcache_tlb_ptba_read ) r_dcache_tlb_ptba_read = false;
+	    }
+	    else if ( (rsp_dtlb_miss & PTE_T_MASK) >> PTE_T_SHIFT ) // PTD
+	    {
+                r_dcache_ptba_ok   = true;
+                r_dcache_ptba_save = (paddr_t)(rsp_dtlb_miss & ((1<<(m_paddr_nbits - PAGE_K_NBITS))-1)) << PAGE_K_NBITS;  
+                r_dcache_id1_save  = dreq.addr >> PAGE_M_NBITS;
+                r_dcache_tlb_paddr = (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);
+                if ( r_dcache_tlb_ptba_read )
+                {
+                    paddr_t tlb_dpaddr;
+		    data_t data;
+                    r_dcache_tlb_ptba_read = false;
+		    if (dcache_tlb.translate(dreq.addr, &tlb_dpaddr) && r_dcache.read((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),&data))
+		    {
+                        r_dcache_tlb_ll_dirty_req = true;
+                        r_dcache_fsm = DCACHE_LL_DIRTY_WAIT;
+ 		    }	        
+		    else
+		    {
+		    	r_dcache_fsm = DCACHE_IDLE;
+                    }
+                }
+                else
+                {
+                    r_dcache_fsm = DCACHE_DTLB2_READ_CACHE;
+                }
+	    }
+	    else	// PTE
+	    {
+                r_dcache_ptba_ok = false;
+	        if ( (m_srcid_rw >> 4) == ((r_dcache_tlb_paddr.read() & ((1<<(m_paddr_nbits - PAGE_M_NBITS))-1)) >> (m_paddr_nbits - PAGE_M_NBITS -10)) ) // local
+		{
+		    if ( (rsp_dtlb_miss & PTE_L_MASK ) >> PTE_L_SHIFT ) // L bit is set
+		    {
+                        r_dcache_pte_update = rsp_dtlb_miss;
+                        r_dcache_fsm        = DCACHE_TLB1_UPDT_SEL;
+		    }
+		    else
+		    {
+                        r_dcache_pte_update = rsp_dtlb_miss | PTE_L_MASK;
+                        r_dcache_tlb_ll_acc_req = true;
+                        r_dcache_fsm        = DCACHE_TLB1_LL_WAIT;
+			m_cpt_data_tlb_update_acc++;
+                        m_cost_data_tlb_update_acc_frz++;
+		    }
+    	        }
+		else // remotely
+		{
+		    if ( (rsp_dtlb_miss & PTE_R_MASK ) >> PTE_R_SHIFT ) // R bit is set
+		    {
+                        r_dcache_pte_update = rsp_dtlb_miss;
+                        r_dcache_fsm        = DCACHE_TLB1_UPDT_SEL;
+		    }
+		    else
+		    {
+                        r_dcache_pte_update = rsp_dtlb_miss | PTE_R_MASK;
+                        r_dcache_tlb_ll_acc_req = true;
+                        r_dcache_fsm        = DCACHE_TLB1_LL_WAIT;
+			m_cpt_data_tlb_update_acc++;
+                        m_cost_data_tlb_update_acc_frz++;
+		    }
+		}
+	    }
+        }
+        break;
+    }
+    /////////////////////////
+    case DCACHE_TLB1_UPDT_SEL: 
+    {
+        m_cost_data_tlb_miss_frz++;
+        m_cost_data_tlb_update_acc_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 && !r_dcache_inval_rsp )
+        {
+	    size_t way = 0;
+	    size_t set = 0;
+            paddr_t victim_index = 0;
+	    bool cleanup = dcache_tlb.select((dreq.addr >> PAGE_M_NBITS),&victim_index,&way,&set);
+	    if (cleanup)
+	    {
+	        r_dcache_dtlb_cleanup_req = true;
+		r_dcache_dtlb_cleanup_line = victim_index;
+		//m_cpt_cc_cleanup_data++;
+	    }
+	    r_dcache_way = way;
+	    r_dcache_set = set;
+            r_dcache_fsm = DCACHE_TLB1_UPDT;
+        }
+        else  
+        {
+            if ( r_dcache_inval_tlb_rsp ) r_dcache_inval_tlb_rsp = false;
+            if ( r_dcache_inval_rsp ) r_dcache_inval_rsp = false;
+            r_dcache_fsm = DCACHE_IDLE;
+        }
+        break;
+    }
+    //////////////////////
+    case DCACHE_TLB1_UPDT: 
+    {
+        m_cost_data_tlb_miss_frz++;
+        m_cost_data_tlb_update_acc_frz++;
+
+	if (r_dcache_dtlb_cleanup_req) r_dcache.setinbit(r_dcache_dtlb_cleanup_line.read() << (uint32_log2(m_dcache_words)+2), r_dcache_in_dtlb, false);
+        bool set_hit = r_dcache.setinbit(r_dcache_tlb_paddr, r_dcache_in_dtlb, true);
+        assert(set_hit && "TLB1_UPDT set hit error");  
+	dcache_tlb.update(r_dcache_pte_update,dreq.addr,r_dcache_way.read(),r_dcache_set.read(),(r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words)+2)));
+        r_dcache_fsm = DCACHE_IDLE;
+	break;
+    }
+    /////////////////////////////
+    case DCACHE_DTLB2_READ_CACHE:
+    {
+        m_cost_data_tlb_miss_frz++;
+
+        // external cache invalidate request
+        if ( r_tgt_dcache_req )   
+        {
+            r_dcache_fsm = DCACHE_CC_CHECK;
+            r_dcache_fsm_save = r_dcache_fsm;
+            break;
+        }        
+
+        // Using tlb entry is invalidated 
+        if ( r_dcache_inval_tlb_rsp )
+        {
+            r_dcache_inval_tlb_rsp = false;
+            r_dcache_fsm = DCACHE_IDLE;
+            break;
+        }
+
+        data_t tlb_data = 0;
+        data_t tlb_data_ppn = 0;
+        bool tlb_hit_cache = r_dcache.read(r_dcache_tlb_paddr, &tlb_data);
+
+	if ( tlb_hit_cache )
+	{
+            bool tlb_hit_ppn = r_dcache.read(r_dcache_tlb_paddr.read()+4, &tlb_data_ppn);
+	    assert(tlb_hit_ppn && "Address of pte[64-32] and pte[31-0] should be successive");
+	}
+
+        // DTLB request hit in cache
+        if ( tlb_hit_cache )
+        {
+	    if ( !(tlb_data >> PTE_V_SHIFT) )	// unmapped
+	    {
+                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
+                {
+                    r_dcache_error_type = MMU_READ_PT2_UNMAPPED;
+                }
+                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
+                {
+                    r_dcache_error_type = MMU_WRITE_PT2_UNMAPPED;
+                } 
+                r_dcache_bad_vaddr  = dreq.addr;
+                r_dcache_fsm        = DCACHE_ERROR;
+	    }
+	    else if ( (tlb_data & PTE_T_MASK) >> PTE_T_SHIFT ) //PTD
+	    {
+                r_dcache_pte_update = tlb_data;
+	        r_dcache_ppn_update = tlb_data_ppn;
+		r_dcache_fsm = DCACHE_TLB2_UPDT_SEL;
+	    }
+	    else 
+	    {
+		m_cpt_data_tlb_hit_dcache++;
+	        if ( (m_srcid_rw >> 4) == ((r_dcache_tlb_paddr.read() & ((1<<(m_paddr_nbits - PAGE_M_NBITS))-1)) >> (m_paddr_nbits - PAGE_M_NBITS -10)) ) // local
+		{
+		    if ( (tlb_data & PTE_L_MASK ) >> PTE_L_SHIFT ) // L bit is set
+		    {
+                        r_dcache_pte_update = tlb_data;
+			r_dcache_ppn_update = tlb_data_ppn;
+                        r_dcache_fsm        = DCACHE_TLB2_UPDT_SEL;
+		    }
+		    else
+		    {
+                        r_dcache_pte_update = tlb_data | PTE_L_MASK;
+	        	r_dcache_ppn_update = tlb_data_ppn;
+                        r_dcache_tlb_ll_acc_req = true;
+                        r_dcache_fsm = DCACHE_TLB2_LL_WAIT;
+                        m_cpt_data_tlb_update_acc++;
+                        m_cost_data_tlb_update_acc_frz++;
+		    }
+    	        }
+		else // remotely
+		{
+		    if ( (tlb_data & PTE_R_MASK ) >> PTE_R_SHIFT ) // R bit is set
+		    {
+                        r_dcache_pte_update = tlb_data;
+			r_dcache_ppn_update = tlb_data_ppn;
+                        r_dcache_fsm        = DCACHE_TLB2_UPDT_SEL;
+		    }
+		    else
+		    {
+                        r_dcache_pte_update = tlb_data | PTE_R_MASK;
+	        	r_dcache_ppn_update = tlb_data_ppn;
+                        r_dcache_tlb_ll_acc_req = true;
+                        r_dcache_fsm = DCACHE_TLB2_LL_WAIT;
+                        m_cpt_data_tlb_update_acc++;
+                        m_cost_data_tlb_update_acc_frz++;
+		    }
+		}
+	    }
+        }
+        else
+        {
+            // DTLB request miss in cache and walk page table level 2
+            r_dcache_tlb_read_req = true;
+            r_dcache_fsm = DCACHE_TLB2_READ;
+        }
+        break;
+    }
+    ///////////////////////
+    case DCACHE_TLB2_LL_WAIT:
+    {
+        if ( dreq.valid ) m_cost_data_tlb_miss_frz++;
+        m_cost_data_tlb_update_acc_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_tlb_ll_acc_req)
+	{
+            if ( r_vci_rsp_data_error ) // VCI response ko
+            {
+                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
+                {
+                    r_dcache_error_type = MMU_READ_PT2_ILLEGAL_ACCESS;
+                }
+                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
+                {
+                    r_dcache_error_type = MMU_WRITE_PT2_ILLEGAL_ACCESS;
+                } 
+                r_dcache_bad_vaddr = dreq.addr;
+                r_dcache_fsm = DCACHE_ERROR; 
+
+		if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
+		if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;
+            }
+	    else
+	    {
+	        if ( !(r_dcache_miss_buf[0] >> PTE_V_SHIFT) )	// unmapped
+	        {
+               	    if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
+               	    {
+               	        r_dcache_error_type = MMU_READ_PT2_UNMAPPED;
+               	    }
+               	    else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
+               	    {
+               	        r_dcache_error_type = MMU_WRITE_PT2_UNMAPPED;
+               	    } 
+                    r_dcache_bad_vaddr = dreq.addr;
+                    r_dcache_fsm = DCACHE_ERROR;
+
+		    if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
+		    if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;
+	        }
+        	else if ( r_dcache_inval_tlb_rsp )
+        	{
+        	    r_dcache_inval_tlb_rsp = false;
+        	    r_dcache_fsm = DCACHE_IDLE;
+        	}
+		else if ( r_dcache_inval_rsp )
+		{
+        	    r_dcache_inval_rsp = false;
+		    r_dcache_fsm = DCACHE_IDLE;
+		}
+		else
+		{
+		    r_dcache_tlb_sc_acc_req = true;
+		    r_dcache_pte_update = r_dcache_miss_buf[0] | r_dcache_pte_update.read();
+                    r_dcache_fsm = DCACHE_TLB2_SC_WAIT; 
+		}
+	    }
+	}
+	break;
+    }
+    ///////////////////////
+    case DCACHE_TLB2_SC_WAIT:
+    {
+        if ( dreq.valid ) m_cost_data_tlb_miss_frz++;
+        m_cost_data_tlb_update_acc_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_tlb_sc_acc_req )
+	{
+	    if ( r_vci_rsp_data_error ) // VCI response ko
+	    {
+                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
+                {
+                    r_dcache_error_type = MMU_READ_PT2_ILLEGAL_ACCESS;
+                }
+                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
+                {
+                    r_dcache_error_type = MMU_WRITE_PT2_ILLEGAL_ACCESS;
+                } 
+	        r_dcache_bad_vaddr = dreq.addr;
+	        r_dcache_fsm = DCACHE_ERROR; 
+
+		if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
+		if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;	
+	    }
+	    else
+	    { 
+                // Using tlb entry is invalidated 
+                if ( r_dcache_inval_tlb_rsp )
+                {
+                    r_dcache_inval_tlb_rsp = false;
+		    if (r_dcache_tlb_sc_fail) r_dcache_tlb_sc_fail = false;
+                    r_dcache_fsm = DCACHE_IDLE;
+                }
+		else if ( r_dcache_inval_rsp )
+		{
+        	    r_dcache_inval_rsp = false;
+		    if (r_dcache_tlb_sc_fail) r_dcache_tlb_sc_fail = false;
+		    r_dcache_fsm = DCACHE_IDLE;
+		}
+	        else if ( r_dcache_tlb_sc_fail )
+	        {
+	            r_dcache_tlb_ll_acc_req = true;
+		    r_dcache_tlb_sc_fail = false;
+	            r_dcache_fsm = DCACHE_TLB2_LL_WAIT;
+		    m_cpt_data_tlb_update_acc++;
+	        }
+	        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_SEL; 
+		    m_cpt_dcache_data_write++;
+	        }
+	    }
+	}
+	break;
+    }
+    /////////////////////
+    case DCACHE_TLB2_READ:
+    {
+        m_cost_data_tlb_miss_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_tlb_read_req )
+	{
+            if ( r_vci_rsp_data_error ) // VCI response ko
+            {
+                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
+                {
+                    r_dcache_error_type = MMU_READ_PT2_ILLEGAL_ACCESS;
+                }
+                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
+                {
+                    r_dcache_error_type = MMU_WRITE_PT2_ILLEGAL_ACCESS;
+                } 
+                r_dcache_bad_vaddr = dreq.addr;
+                r_dcache_fsm = DCACHE_ERROR; 
+
+		if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
+		if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;
+		break;
+            }	
+
+            if ( r_dcache_inval_tlb_rsp )  // TLB miss response and invalidation
+            {
+                r_dcache_fsm = DCACHE_IDLE; 
+                r_dcache_inval_tlb_rsp = false;
+                break;
+            }  
+
+	    if ( r_dcache_inval_rsp ) // TLB miss response and cache invalidation
+	    {
+	        if ( r_dcache_cleanup_req ) break;
+                r_dcache_cleanup_req = true;
+                r_dcache_cleanup_line = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words) + 2);  
+		m_cpt_cc_cleanup_data++;
+                r_dcache_fsm = DCACHE_IDLE;
+                r_dcache_inval_rsp = false;
+                break;
+	    } 
+
+	    // TLB miss response and no invalidation
+	    r_dcache_fsm = DCACHE_TLB2_READ_UPDT;
+	}	
+        break;
+    }
+    //////////////////////////
+    case DCACHE_TLB2_READ_UPDT:
+    {
+        m_cost_data_tlb_miss_frz++;
+
+        // external cache invalidate request
+        if ( r_tgt_dcache_req )   
+        {
+            r_dcache_fsm = DCACHE_CC_CHECK;
+            r_dcache_fsm_save = r_dcache_fsm;
+            break;
+        }        
+
+        // Using tlb entry is invalidated 
+        if ( r_dcache_inval_tlb_rsp )
+        {
+            r_dcache_inval_tlb_rsp = false;
+            r_dcache_fsm = DCACHE_IDLE;
+            break;
+        }
+
+        if ( !r_dcache_cleanup_req )
+        {
+            // update cache
+            data_t rsp_dtlb_miss;
+            data_t tlb_data_ppn;
+            paddr_t  victim_index = 0;
+            size_t way = 0;
+            size_t set = 0;
+
+            // Using tlb entry is in the invalidated cache line  
+            if ( r_dcache_inval_rsp )
+            {
+                r_dcache_cleanup_req = true;
+                r_dcache_cleanup_line = r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words) + 2);  
+		m_cpt_cc_cleanup_data++;
+                r_dcache_fsm = DCACHE_IDLE;
+                r_dcache_inval_rsp = false;
+                break;
+            }
+
+            bool cleanup_req = r_dcache.find(r_dcache_tlb_paddr, r_dcache_in_itlb, r_dcache_in_dtlb, &way, &set, &victim_index);
+
+	    if ( cleanup_req )
+	    {	    
+		// ins tlb invalidate verification    
+                r_dcache_itlb_inval_req = r_dcache_in_itlb[m_dcache_sets*way+set];
+                r_dcache_itlb_inval_line = victim_index;
+                r_dcache_in_itlb[way*m_dcache_sets+set] = false;
+
+                // data tlb invalidate verification
+                r_dcache_dtlb_inval_req = r_dcache_in_dtlb[m_dcache_sets*way+set]; 
+                r_dcache_dtlb_inval_line = victim_index;
+                r_dcache_in_dtlb[way*m_dcache_sets+set] = false;
+
+                r_dcache_cleanup_req = true; 
+                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;
+	    }
+
+	    r_dcache.update(r_dcache_tlb_paddr, way, set, r_dcache_miss_buf);
+	    r_dcache.read(r_dcache_tlb_paddr, &rsp_dtlb_miss);
+	    m_cpt_data_tlb_occup_cache++;
+
+	    bool tlb_hit_ppn = r_dcache.read(r_dcache_tlb_paddr.read()+4, &tlb_data_ppn);
+	    assert(tlb_hit_ppn && "Address of pte[64-32] and pte[31-0] should be successive");
+
+	    if ( !(rsp_dtlb_miss >> PTE_V_SHIFT) )	// unmapped
+	    {
+                if ((r_dcache_type_save == iss_t::DATA_READ)||(r_dcache_type_save == iss_t::DATA_LL))
+                {
+                    r_dcache_error_type = MMU_READ_PT2_UNMAPPED;
+                }
+                else /*if ((dreq.type == iss_t::DATA_WRITE)||(dreq.type == iss_t::DATA_SC))*/
+                {
+                    r_dcache_error_type = MMU_WRITE_PT2_UNMAPPED;
+                }  
+                r_dcache_bad_vaddr  = dreq.addr;
+                r_dcache_fsm        = DCACHE_ERROR;
+	    }
+	    else if ( (rsp_dtlb_miss & PTE_T_MASK) >> PTE_T_SHIFT ) // PTD
+	    {
+                r_dcache_pte_update = rsp_dtlb_miss;
+	        r_dcache_ppn_update = tlb_data_ppn;
+		r_dcache_fsm = DCACHE_TLB2_UPDT_SEL;
+	    }
+	    else
+	    {
+	        if ( (m_srcid_rw >> 4) == ((r_dcache_tlb_paddr.read() & ((1<<(m_paddr_nbits - PAGE_M_NBITS))-1)) >> (m_paddr_nbits - PAGE_M_NBITS -10)) ) // local
+		{
+		    if ( (rsp_dtlb_miss & PTE_L_MASK ) >> PTE_L_SHIFT ) // L bit is set
+		    {
+                        r_dcache_pte_update = rsp_dtlb_miss;
+			r_dcache_ppn_update = tlb_data_ppn;
+                        r_dcache_fsm        = DCACHE_TLB2_UPDT_SEL;
+		    }
+		    else
+		    {
+                        r_dcache_pte_update = rsp_dtlb_miss | PTE_L_MASK;
+	        	r_dcache_ppn_update = tlb_data_ppn;
+                        r_dcache_tlb_ll_acc_req = true;
+                        r_dcache_fsm = DCACHE_TLB2_LL_WAIT;
+                        m_cpt_data_tlb_update_acc++;
+                        m_cost_data_tlb_update_acc_frz++;
+		    }
+    	        }
+		else // remotely
+		{
+		    if ( (rsp_dtlb_miss & PTE_R_MASK ) >> PTE_R_SHIFT ) // R bit is set
+		    {
+                        r_dcache_pte_update = rsp_dtlb_miss;
+			r_dcache_ppn_update = tlb_data_ppn;
+                        r_dcache_fsm        = DCACHE_TLB2_UPDT_SEL;
+		    }
+		    else
+		    {
+                        r_dcache_pte_update = rsp_dtlb_miss | PTE_R_MASK;
+	        	r_dcache_ppn_update = tlb_data_ppn;
+                        r_dcache_tlb_ll_acc_req = true;
+                        r_dcache_fsm = DCACHE_TLB2_LL_WAIT;
+                        m_cpt_data_tlb_update_acc++;
+                        m_cost_data_tlb_update_acc_frz++;
+		    }
+		}
+	    }
+        }
+        break;
+    }
+    //////////////////////////
+    case DCACHE_TLB2_UPDT_SEL:  
+    {
+        m_cost_data_tlb_miss_frz++;
+        m_cost_data_tlb_update_acc_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 && !r_dcache_inval_rsp )
+        {
+	    size_t way = 0;
+	    size_t set = 0;
+            paddr_t victim_index = 0;
+	    bool cleanup = dcache_tlb.select((dreq.addr >> PAGE_K_NBITS),&victim_index,&way,&set);
+	    if (cleanup) 
+	    {
+	        r_dcache_dtlb_cleanup_req = true;
+		r_dcache_dtlb_cleanup_line = victim_index;
+		//m_cpt_cc_cleanup_data++;
+	    }
+	    r_dcache_way = way;
+	    r_dcache_set = set;
+            r_dcache_fsm = DCACHE_TLB2_UPDT;
+        }
+        else  
+        {
+            if ( r_dcache_inval_tlb_rsp ) r_dcache_inval_tlb_rsp = false;
+            if ( r_dcache_inval_rsp ) r_dcache_inval_rsp = false;
+            r_dcache_fsm = DCACHE_IDLE;
+        }
+        break;
+    }
+    //////////////////////
+    case DCACHE_TLB2_UPDT:  
+    {
+        m_cost_data_tlb_miss_frz++;
+        m_cost_data_tlb_update_acc_frz++;
+
+	if (r_dcache_dtlb_cleanup_req) r_dcache.setinbit(r_dcache_dtlb_cleanup_line.read() << (uint32_log2(m_dcache_words)+2), r_dcache_in_dtlb, false);
+        bool set_hit = r_dcache.setinbit(r_dcache_tlb_paddr, r_dcache_in_dtlb, true);
+        assert(set_hit && "TLB2_UPDT set hit error");  
+        dcache_tlb.update(r_dcache_pte_update,r_dcache_ppn_update,dreq.addr,r_dcache_way.read(),r_dcache_set.read(),(r_dcache_tlb_paddr.read() >> (uint32_log2(m_dcache_words)+2)));
+        r_dcache_fsm = DCACHE_IDLE;
+	break;
+    }
+    ///////////////////////
+    case DCACHE_CTXT_SWITCH:
+    {
+        // TLB flush leads to cleanup corresponding data cache line 
+        paddr_t victim_index = 0;
+        size_t way = 0;
+        size_t set = 0;
+
+        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_itlb_cleanup_req = false;
+	}
+
+        for ( way = 0; way < m_dtlb_ways; way++)
+        {
+            for ( set = 0; set < m_dtlb_sets; set++)
+            {
+                if(dcache_tlb.checkcleanup(way, set, &victim_index))
+                {
+                    r_dcache.setinbit((paddr_t)(victim_index << (uint32_log2(m_dcache_words)+2)), r_dcache_in_dtlb, false); 
+                }
+            }
+        }
+
+        if ( !r_dcache_xtn_req )
+        {
+            r_dcache_fsm = DCACHE_IDLE;
+            r_dtlb_translation_valid = false;
+            r_dcache_ptba_ok = false;
+            drsp.valid = true;
+        }
+        break;
+    }
+    ////////////////////////
+    case DCACHE_ICACHE_FLUSH:
+    case DCACHE_ICACHE_INVAL:
+    case DCACHE_ICACHE_INVAL_PA:
+    case DCACHE_ITLB_INVAL:
+    {
+        // 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_xtn_req ) 
+        {
+            r_dcache_fsm = DCACHE_IDLE;
+            drsp.valid = true;
+        }
+        break;
+    }
+    ////////////////////////
+    case DCACHE_DCACHE_FLUSH:
+    {
+        // external cache invalidate request
+        if ( r_tgt_dcache_req )   
+        {
+            r_dcache_fsm = DCACHE_CC_CHECK;
+            r_dcache_fsm_save = r_dcache_fsm;
+            break;
+        }  
+        size_t way = r_dcache_way;
+        size_t set = r_dcache_set;
+        bool clean = false;
+        
+        // cache flush and send cleanup to external
+        if ( !r_dcache_cleanup_req )
+        {
+            paddr_t victim_index = 0;
+            for ( ; way < m_dcache_ways; way++ )
+            {    
+                for ( ; set < m_dcache_sets; set++ )
+                {  
+                    if ( r_dcache.flush(way, set, &victim_index) )
+                    {
+                        clean = true;
+                        r_dcache_cleanup_req = true;
+                        r_dcache_cleanup_line = victim_index;
+                        m_cpt_cc_cleanup_data++;
+                        r_dcache_way = way + ((set+1)/m_dcache_sets);
+                        r_dcache_set = (set+1) % m_dcache_sets;
+                        break;
+                    }
+                }
+                if (clean) break;
+                set = 0;
+            }
+
+            if ((way == m_dcache_ways) && !r_dcache_xtn_req ) 
+            {
+                // data TLB flush 
+                dcache_tlb.flush(true);      // global entries are invalidated
+            	r_dtlb_translation_valid = false;
+            	r_dcache_ptba_ok = false;
+
+                for (size_t line = 0; line < m_dcache_ways*m_dcache_sets; line++)
+                {
+                    r_dcache_in_itlb[line] = false;
+                    r_dcache_in_dtlb[line] = false;
+                }
+
+                r_dcache_fsm = DCACHE_IDLE;
+                drsp.valid = true;
+                break;
+            }
+        }
+	break;
+    }
+    //////////////////////
+    case DCACHE_DTLB_INVAL: 
+    {
+        paddr_t victim_index = 0;
+        // clean indicate data tlb bit
+        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_dtlb_translation_valid = false;
+        r_dcache_ptba_ok = false;
+        r_dcache_fsm = DCACHE_IDLE;
+        drsp.valid = true;
+        break;
+    }
+    ////////////////////////
+    case DCACHE_DCACHE_INVAL:
+    {
+        // external cache invalidate request
+        if ( r_tgt_dcache_req )   
+        {
+            r_dcache_fsm = DCACHE_CC_CHECK;
+            r_dcache_fsm_save = r_dcache_fsm;
+            break;
+        }  
+
+        m_cpt_dcache_dir_read += m_dcache_ways;
+        vaddr_t invadr = dreq.wdata;
+        paddr_t dpaddr = 0;
+        bool dcache_hit_t = false; 
+        size_t way = 0;
+        size_t set = 0;
+
+	if ( !r_dcache_cleanup_req )
+	{
+            if ( r_mmu_mode.read() & DATA_TLB_MASK ) 
+            {
+                dcache_hit_t = dcache_tlb.translate(invadr, &dpaddr); 
+            } 
+            else 
+            {
+                dpaddr = invadr;  
+                dcache_hit_t = true;
+            }
+
+            if ( dcache_hit_t )
+            {
+		bool dcache_cleanup_req = r_dcache.inval(dpaddr, &way, &set);
+		r_dcache_cleanup_req = dcache_cleanup_req;
+		r_dcache_cleanup_line = dpaddr >> (uint32_log2(m_dcache_words)+2);
+		if (dcache_cleanup_req) m_cpt_cc_cleanup_data++;
+		
+		if ( r_dcache_in_itlb[way*m_dcache_sets+set] || r_dcache_in_dtlb[way*m_dcache_sets+set] ) 
+		{	
+		    // ins tlb invalidate verification
+		    r_dcache_itlb_inval_req = r_dcache_in_itlb[way*m_dcache_sets+set];
+		    r_dcache_itlb_inval_line = dpaddr >> (uint32_log2(m_dcache_words)+2);
+		    r_dcache_in_itlb[way*m_dcache_sets+set] = false;
+		
+		    // data tlb invalidate verification
+		    r_dcache_dtlb_inval_req = r_dcache_in_dtlb[way*m_dcache_sets+set];
+		    r_dcache_dtlb_inval_line = dpaddr >> (uint32_log2(m_dcache_words)+2);
+		    r_dcache_in_dtlb[way*m_dcache_sets+set] = false;
+		    r_dcache_fsm = DCACHE_TLB_CC_INVAL;
+		    r_dcache_fsm_save = r_dcache_fsm;
+		    break;
+		}
+            }
+            r_dcache_fsm = DCACHE_IDLE;
+            drsp.valid = true;
+	}
+        break;
+    }
+    ////////////////////////
+    case DCACHE_DCACHE_INVAL_PA:
+    {
+        // external cache invalidate request
+        if ( r_tgt_dcache_req )   
+        {
+            r_dcache_fsm = DCACHE_CC_CHECK;
+            r_dcache_fsm_save = r_dcache_fsm;
+            break;
+        }  
+        m_cpt_dcache_dir_read += m_dcache_ways;
+        paddr_t dpaddr = (paddr_t)r_mmu_word_hi.read() << 32 | r_mmu_word_lo.read();
+        size_t way = 0;
+        size_t set = 0;
+
+	if ( !r_dcache_cleanup_req )
+	{
+	    bool dcache_cleanup_req = r_dcache.inval(dpaddr, &way, &set);
+	    r_dcache_cleanup_req = dcache_cleanup_req;
+	    r_dcache_cleanup_line = dpaddr >> (uint32_log2(m_dcache_words)+2);
+	    if (dcache_cleanup_req) m_cpt_cc_cleanup_data++;
+	    
+	    if ( r_dcache_in_itlb[way*m_dcache_sets+set] || r_dcache_in_dtlb[way*m_dcache_sets+set] ) 
+	    {	
+	        // ins tlb invalidate verification
+	        r_dcache_itlb_inval_req = r_dcache_in_itlb[way*m_dcache_sets+set];
+	        r_dcache_itlb_inval_line = dpaddr >> (uint32_log2(m_dcache_words)+2);
+	        r_dcache_in_itlb[way*m_dcache_sets+set] = false;
+	    
+	        // data tlb invalidate verification
+	        r_dcache_dtlb_inval_req = r_dcache_in_dtlb[way*m_dcache_sets+set];
+	        r_dcache_dtlb_inval_line = dpaddr >> (uint32_log2(m_dcache_words)+2);
+	        r_dcache_in_dtlb[way*m_dcache_sets+set] = false;
+	        r_dcache_fsm = DCACHE_TLB_CC_INVAL;
+	        r_dcache_fsm_save = r_dcache_fsm;
+	        break;
+	    }
+            r_dcache_fsm = DCACHE_IDLE;
+            drsp.valid = true;
+	}
+        break;
+    }
+    /////////////////////////
+    case DCACHE_DCACHE_SYNC:
+    {
+        // 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_write_req ) 
+        {
+            r_dcache_write_req = r_wbuf.rok();
+            drsp.valid = true;
+            r_dcache_fsm = DCACHE_IDLE;
+        }    
+        break;
+    }
+    /////////////////////
+    case DCACHE_MISS_WAIT:
+    {
+        m_cost_data_miss_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_miss_req )
+	{
+            if ( r_vci_rsp_data_error ) 
+            {
+                r_dcache_error_type = MMU_READ_DATA_ILLEGAL_ACCESS; 
+                r_dcache_bad_vaddr = dreq.addr;
+                r_dcache_fsm = DCACHE_ERROR;
+
+		if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
+		if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;
+		break;
+            } 
+
+            if ( r_dcache_inval_tlb_rsp ) // Miss read response and tlb invalidation
+            {
+                if ( r_dcache_cleanup_req ) break;
+                r_dcache_cleanup_req = true;
+                r_dcache_cleanup_line = r_dcache_paddr_save.read() >> (uint32_log2(m_dcache_words) + 2);  
+                m_cpt_cc_cleanup_data++;
+                r_dcache_fsm = DCACHE_IDLE;
+                r_dcache_inval_tlb_rsp = false;
+                if ( r_dcache_inval_rsp ) r_dcache_inval_rsp = false;
+                break;
+            }	
+
+	    if ( r_dcache_inval_rsp ) // TLB miss response and cache invalidation
+	    {
+                if ( r_dcache_cleanup_req ) break;
+                r_dcache_cleanup_req = true;
+                r_dcache_cleanup_line = r_dcache_paddr_save.read() >> (uint32_log2(m_dcache_words) + 2);  
+                m_cpt_cc_cleanup_data++;
+                r_dcache_fsm = DCACHE_IDLE;
+                r_dcache_inval_rsp = false;
+                break;
+	    }
+	    // Miss read response and no tlb invalidation
+	    r_dcache_fsm = DCACHE_MISS_UPDT;
+	}	
+        break;
+    }
+    /////////////////////
+    case DCACHE_MISS_UPDT:
+    {
+        m_cost_data_miss_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 ) // tlb invalidation
+        {
+            if ( r_dcache_cleanup_req ) break;
+            r_dcache_cleanup_req = true;
+            r_dcache_cleanup_line = r_dcache_paddr_save.read() >> (uint32_log2(m_dcache_words) + 2);  
+            m_cpt_cc_cleanup_data++;
+            r_dcache_inval_tlb_rsp = false;
+            r_dcache_inval_rsp = false;
+            r_dcache_fsm = DCACHE_IDLE;
+            break;
+        }
+
+        if (!r_dcache_cleanup_req ) // Miss update and no invalidation
+        {
+            paddr_t  victim_index = 0;
+            size_t way = 0;
+            size_t set = 0;
+
+            // Using tlb entry is in the invalidated cache line  
+            if ( r_dcache_inval_rsp )
+            {
+                r_dcache_cleanup_req = true;
+                r_dcache_cleanup_line = r_dcache_paddr_save.read() >> (uint32_log2(m_dcache_words) + 2);  
+                m_cpt_cc_cleanup_data++;
+                r_dcache_fsm = DCACHE_IDLE;
+                r_dcache_inval_rsp = false;
+                break;
+            }
+
+            bool cleanup_req = r_dcache.find(r_dcache_paddr_save.read(), r_dcache_in_itlb, r_dcache_in_dtlb, &way, &set, &victim_index);
+
+            if ( cleanup_req )
+            {	    
+                // ins tlb invalidate verification    
+                r_dcache_itlb_inval_req = r_dcache_in_itlb[m_dcache_sets*way+set];
+                r_dcache_itlb_inval_line = victim_index;
+                
+                // data tlb invalidate verification
+                r_dcache_dtlb_inval_req = r_dcache_in_dtlb[m_dcache_sets*way+set]; 
+                r_dcache_dtlb_inval_line = victim_index;
+
+                r_dcache_cleanup_req = true; 
+                r_dcache_cleanup_line = victim_index;
+                m_cpt_cc_cleanup_data++;
+
+                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;
+                    r_dcache_in_itlb[way*m_dcache_sets+set] = false;
+                    r_dcache_in_dtlb[way*m_dcache_sets+set] = false;
+                    break;
+                }
+            }
+            m_cpt_dcache_dir_write++;
+            m_cpt_dcache_data_write++;
+            r_dcache.update(r_dcache_paddr_save.read(), way, set, r_dcache_miss_buf);
+            r_dcache_fsm = DCACHE_IDLE;
+        }
+        break;
+    }
+    //////////////////////
+    case DCACHE_UNC_WAIT:
+    {
+        m_cost_unc_read_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_unc_req )
+	{
+            if ( r_vci_rsp_data_error ) 
+            {
+                r_dcache_error_type = MMU_READ_DATA_ILLEGAL_ACCESS; 
+                r_dcache_bad_vaddr = dreq.addr;
+                r_dcache_fsm = DCACHE_ERROR;
+
+		if (r_dcache_inval_tlb_rsp) r_dcache_inval_tlb_rsp = false;
+		break;
+            }
+
+            if ( r_dcache_inval_tlb_rsp ) // Miss read response and tlb invalidation
+            {
+                r_dcache_inval_tlb_rsp = false;
+            }
+
+	    drsp.valid = true;
+	    drsp.rdata = r_dcache_miss_buf[0];
+	    r_dcache_fsm = DCACHE_IDLE;
+	}	
+        break;
+    }
+    ///////////////////////
+    case DCACHE_WRITE_UPDT:
+    {
+        m_cost_write_frz++;
+	m_cpt_dcache_data_write++; 
+        size_t way = 0;
+        size_t set = 0;
+	bool write_hit = false;
+        data_t mask = vci_param::be2mask(r_dcache_be_save.read());
+        data_t wdata = (mask & r_dcache_wdata_save) | (~mask & r_dcache_rdata_save);
+        write_hit = r_dcache.write(r_dcache_paddr_save, wdata, &way, &set);
+        assert(write_hit && "Write on miss ignores data");
+        
+        if (r_dcache_in_itlb[way*m_dcache_sets+set] || r_dcache_in_dtlb[m_dcache_sets*way+set])
+        {
+	    // ins tlb invalidate verification    
+            r_dcache_itlb_inval_req = r_dcache_in_itlb[m_dcache_sets*way+set];
+            r_dcache_itlb_inval_line = (r_dcache.get_tag(way, set) * m_dcache_sets) + set;
+            r_dcache_in_itlb[way*m_dcache_sets+set] = false;
+
+            // data tlb invalidate verification
+            r_dcache_dtlb_inval_req = r_dcache_in_dtlb[m_dcache_sets*way+set]; 
+            r_dcache_dtlb_inval_line = (r_dcache.get_tag(way, set) * m_dcache_sets) + set;
+            r_dcache_in_dtlb[way*m_dcache_sets+set] = false;
+
+	    r_dcache_fsm = DCACHE_TLB_CC_INVAL;
+            r_dcache_fsm_save = r_dcache_fsm;
+            break;
+	}
+
+        if ( !r_dcache_dirty_save && (r_mmu_mode.read() & DATA_TLB_MASK) )   
+        {
+            m_cpt_data_tlb_update_dirty++;
+            m_cost_data_tlb_update_dirty_frz++;	
+            if ( dcache_tlb.getpagesize(r_dcache_tlb_way_save, r_dcache_tlb_set_save) )	// 2M page size, one level page table 
+            {		    
+                r_dcache_pte_update = dcache_tlb.getpte(r_dcache_tlb_way_save, r_dcache_tlb_set_save) | 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
+            {   
+                if (r_dcache_hit_p_save) 
+                {
+                    r_dcache_pte_update = dcache_tlb.getpte(r_dcache_tlb_way_save, r_dcache_tlb_set_save) | 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
+                {
+                    r_dcache_pte_update = dcache_tlb.getpte(r_dcache_tlb_way_save, r_dcache_tlb_set_save) | PTE_D_MASK;
+		    data_t ptba;
+            	    if (r_dcache.read((paddr_t)r_mmu_ptpr << (INDEX1_NBITS+2) | (paddr_t)((dreq.addr>>PAGE_M_NBITS)<<2), &ptba))
+		    {
+                        r_dcache_tlb_paddr = (paddr_t)(ptba & ((1<<(m_paddr_nbits - PAGE_K_NBITS))-1)) << PAGE_K_NBITS | (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
+		    {
+                        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_fsm = DCACHE_WRITE_REQ;
+            drsp.valid = true;
+            drsp.rdata = 0;
+        }
+        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:
+    {
+        r_vci_rsp_data_error = false;
+        drsp.valid = true;
+        drsp.error = true;
+        drsp.rdata = 0;
+        r_dcache_fsm = DCACHE_IDLE;
+        break;
+    }   
+    ////////////////////// 
+    case DCACHE_ITLB_READ:
+    {
+       if ( dreq.valid ) m_cost_ins_tlb_occup_cache_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_itlb_read_req ) // vci response ok
+        {  
+            if ( r_vci_rsp_data_error )
+            {
+                r_dcache_rsp_itlb_error = true;	
+                r_itlb_read_dcache_req = false;
+                r_vci_rsp_data_error = false;
+                r_dcache_fsm = DCACHE_IDLE;
+
+		if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;
+            }
+	    else if ( r_dcache_inval_rsp ) // TLB miss response and cache invalidation
+	    {
+	        if ( r_dcache_cleanup_req ) break;
+                r_dcache_cleanup_req = true;
+                r_dcache_cleanup_line = r_icache_paddr_save.read() >> (uint32_log2(m_dcache_words) + 2);  
+		m_cpt_cc_cleanup_data++;
+                r_dcache_fsm = DCACHE_IDLE;
+                r_dcache_inval_rsp = false;
+                r_itlb_read_dcache_req = false;
+	        r_itlb_acc_redo_req = true;
+	    }
+	    else
+	    {
+                r_dcache_fsm = DCACHE_ITLB_UPDT;
+	    }
+        }
+	break;    	
+    }
+    //////////////////////
+    case DCACHE_ITLB_UPDT:
+    {
+        if ( dreq.valid ) m_cost_ins_tlb_occup_cache_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_cleanup_req )
+        {
+            data_t rsp_itlb_miss = 0;
+	    data_t rsp_itlb_ppn = 0;
+
+            paddr_t  victim_index = 0;
+            size_t way = 0;
+            size_t set = 0;
+
+	    if ( r_dcache_inval_rsp ) // TLB miss response and cache invalidation
+	    {
+                r_dcache_cleanup_req = true;
+                r_dcache_cleanup_line = r_icache_paddr_save.read() >> (uint32_log2(m_dcache_words) + 2);  
+                m_cpt_cc_cleanup_data++;
+                r_dcache_fsm = DCACHE_IDLE;
+                r_dcache_inval_rsp = false;
+                r_itlb_read_dcache_req = false;
+                r_itlb_acc_redo_req = true;
+                break;
+	    }           
+ 
+            bool cleanup = r_dcache.find(r_icache_paddr_save, r_dcache_in_itlb, r_dcache_in_dtlb, &way, &set, &victim_index);
+
+	    if ( cleanup )
+	    {	    
+                // ins tlb invalidate verification    
+                r_dcache_itlb_inval_req = r_dcache_in_itlb[m_dcache_sets*way+set];
+                r_dcache_itlb_inval_line = victim_index;
+
+                // data tlb invalidate verification
+                r_dcache_dtlb_inval_req = r_dcache_in_dtlb[m_dcache_sets*way+set]; 
+                r_dcache_dtlb_inval_line = victim_index;
+
+                r_dcache_cleanup_req = true; 
+                r_dcache_cleanup_line = victim_index;
+                m_cpt_cc_cleanup_data++;
+		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;
+                    r_dcache_in_itlb[way*m_dcache_sets+set] = false;
+                    r_dcache_in_dtlb[way*m_dcache_sets+set] = false;
+		    break;
+		}
+	    }
+
+            r_dcache.update(r_icache_paddr_save, way, set, r_dcache_miss_buf);
+
+            bool set_hit = r_dcache.setinbit(r_icache_paddr_save, r_dcache_in_itlb, true);
+            assert(set_hit && "ITLB_UPDT set hit error");  
+            bool itlb_hit_dcache = r_dcache.read(r_icache_paddr_save, &rsp_itlb_miss);	
+            m_cpt_ins_tlb_occup_cache++; 
+
+	    if ( r_itlb_k_read_dcache && itlb_hit_dcache )
+	    {	
+		r_itlb_k_read_dcache = false;
+            	bool itlb_hit_ppn = r_dcache.read(r_icache_paddr_save.read()+4, &rsp_itlb_ppn);
+		assert(itlb_hit_ppn && "Address of pte[64-32] and pte[31-0] should be successive");
+	    }
+
+            r_dcache_rsp_itlb_miss = rsp_itlb_miss;
+            r_dcache_rsp_itlb_ppn = rsp_itlb_ppn;
+            r_dcache_rsp_itlb_error = false;	
+            r_itlb_read_dcache_req = false;
+            r_dcache_fsm = DCACHE_IDLE;
+        }
+        break;
+    }
+    //////////////////////////
+    case DCACHE_ITLB_LL_WAIT:
+    {
+        if ( dreq.valid ) 
+            m_cost_ins_tlb_occup_cache_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_itlb_ll_acc_req)
+	{
+            if ( r_vci_rsp_data_error ) // VCI response ko
+            {
+                r_dcache_rsp_itlb_error = true;  
+                r_vci_rsp_data_error = false;
+                r_itlb_acc_dcache_req = false;
+                r_dcache_fsm = DCACHE_IDLE;
+                if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;	
+            }
+            else
+            {
+                if ( !(r_dcache_miss_buf[0] >> PTE_V_SHIFT) )	// unmapped
+                {
+                    r_dcache_rsp_itlb_error = true;  
+                    r_itlb_acc_dcache_req = false;
+                    r_dcache_fsm = DCACHE_IDLE;	
+                    if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;	
+                }
+                else if ( r_dcache_inval_rsp )
+                {
+                    r_dcache_inval_rsp = false;
+                    r_dcache_fsm = DCACHE_IDLE;
+                }
+                else
+                {
+                    r_dcache_itlb_sc_acc_req = true;
+                    r_icache_pte_update = r_dcache_miss_buf[0] | r_icache_pte_update.read();	
+                    r_dcache_fsm = DCACHE_ITLB_SC_WAIT; 
+                }
+            }
+	}
+	break;
+    }
+    //////////////////////////
+    case DCACHE_ITLB_SC_WAIT:
+    {
+        if ( dreq.valid ) m_cost_ins_tlb_occup_cache_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_itlb_sc_acc_req ) 
+        {
+            if ( r_vci_rsp_data_error ) // VCI response ko
+            {
+                r_dcache_rsp_itlb_error = true;  
+                r_vci_rsp_data_error = false;
+                r_itlb_acc_dcache_req = false;
+                r_dcache_fsm = DCACHE_IDLE;
+                if (r_dcache_inval_rsp) r_dcache_inval_rsp = false;		
+            }
+            else
+            {
+                if ( r_dcache_inval_rsp )
+                {
+                        r_itlb_acc_dcache_req = false;
+                        r_itlb_acc_redo_req = true;
+                        r_dcache_inval_rsp = false;
+                        r_dcache_fsm = DCACHE_IDLE;
+                        if (r_dcache_tlb_sc_fail) r_dcache_tlb_sc_fail = false;
+                }
+                else if ( r_dcache_tlb_sc_fail )
+                {
+                    r_dcache_tlb_sc_fail = false;
+                    r_dcache_itlb_ll_acc_req = true;
+                    r_dcache_fsm = DCACHE_ITLB_LL_WAIT; 
+                }
+                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; 
+                }
+            }
+        }
+        break;
+    }
+    /////////////////////
+    case DCACHE_CC_CHECK:   // read directory in case of invalidate or update request
+    {
+        m_cpt_dcache_dir_read += m_dcache_ways;
+        m_cpt_dcache_data_read += m_dcache_ways;
+
+        /* activity counter */
+        if ( (( r_dcache_fsm_save == DCACHE_BIS ) ||( r_dcache_fsm_save == DCACHE_MISS_WAIT ) || ( r_dcache_fsm_save == DCACHE_MISS_UPDT ) ) && ( dreq.valid ) )        
+        {
+            m_cost_data_miss_frz++;
+        }
+        if( (( r_dcache_fsm_save == DCACHE_DTLB1_READ_CACHE ) || ( r_dcache_fsm_save == DCACHE_DTLB2_READ_CACHE ) ||
+             ( r_dcache_fsm_save == DCACHE_TLB1_READ )        || ( r_dcache_fsm_save == DCACHE_TLB2_READ )        ||
+             ( 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_TLB1_READ_UPDT )   || ( r_dcache_fsm_save == DCACHE_TLB2_READ_UPDT )   ||
+             ( r_dcache_fsm_save == DCACHE_TLB1_UPDT_SEL )    || ( r_dcache_fsm_save == DCACHE_TLB2_UPDT_SEL )) && (dreq.valid) )
+        {
+            m_cost_data_tlb_miss_frz++;
+        }
+
+        if ( ( r_dcache_fsm_save == DCACHE_ITLB_READ ) ||( r_dcache_fsm_save == DCACHE_ITLB_UPDT ) || ( r_dcache_fsm_save == DCACHE_ITLB_LL_WAIT ) || ( r_dcache_fsm_save == DCACHE_ITLB_SC_WAIT ) )        
+        {
+            m_cost_ins_tlb_occup_cache_frz++;
+        }
+
+	// 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 ) ||*/
+	     ( r_dcache_fsm_save == DCACHE_MISS_WAIT ) || ( r_dcache_fsm_save == DCACHE_MISS_UPDT ) ) && 
+           ( (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_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_icache_paddr_save.read() & ~((m_dcache_words<<2)-1)) == (r_tgt_addr.read() & ~((m_dcache_words<<2)-1))) ) ) 
+        {
+            r_dcache_inval_rsp = true;
+            r_tgt_dcache_req = false;
+            if ( r_tgt_update )
+	    {    // Also send a cleanup and answer
+                r_tgt_dcache_rsp = true;
+            } 
+	    else 
+	    {            // Also send a cleanup but don't answer
+                r_tgt_dcache_rsp = false;
+            }
+            r_dcache_fsm = r_dcache_fsm_save;
+        }
+	else
+	{
+            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);
+
+            if ( dcache_hit )
+            {
+		if (((( r_dcache_fsm_save == DCACHE_TLB1_UPDT_SEL ) || ( r_dcache_fsm_save == DCACHE_TLB2_UPDT_SEL ) ||
+		      ( 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_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_UPDT )    ||
+                      ( r_dcache_fsm_save == DCACHE_ITLB_LL_WAIT ) || ( r_dcache_fsm_save == DCACHE_ITLB_SC_WAIT ) ) && 
+                    ((r_icache_paddr_save.read() & ~((m_dcache_words<<2)-1)) == (r_tgt_addr.read() & ~((m_dcache_words<<2)-1)))))
+		{
+		    r_dcache_inval_rsp = true;
+		}
+
+                if ( r_dcache_in_dtlb[m_dcache_sets*way+set] || r_dcache_in_itlb[m_dcache_sets*way+set] )
+                {
+            	    // ins tlb invalidate verification    
+                    r_dcache_itlb_inval_req = r_dcache_in_itlb[m_dcache_sets*way+set];
+                    r_dcache_itlb_inval_line = r_tgt_addr.read() >> (uint32_log2(m_dcache_words)+2);
+                    r_dcache_in_itlb[way*m_dcache_sets+set] = false;
+
+                    // data tlb invalidate verification
+                    r_dcache_dtlb_inval_req = r_dcache_in_dtlb[m_dcache_sets*way+set]; 
+                    r_dcache_dtlb_inval_line = r_tgt_addr.read() >> (uint32_log2(m_dcache_words)+2);
+                    r_dcache_in_dtlb[way*m_dcache_sets+set] = false;
+            	
+            	    r_dcache_cc_check = true;
+            	    r_dcache_fsm = DCACHE_TLB_CC_INVAL;
+            	    break;
+                }
+
+                if ( r_tgt_update ) // update 
+                {
+                    r_dcache_fsm = DCACHE_CC_UPDT;
+                } 
+                else                // invalidate 
+                {
+                    r_dcache_fsm = DCACHE_CC_INVAL;
+                }
+            }
+            else                    // nothing
+            {
+                r_dcache_fsm = DCACHE_CC_NOP;
+            }
+	}
+        break;
+    }
+    ///////////////////
+    case DCACHE_CC_UPDT:    // update directory and data cache        
+    {
+        /* activity counter */
+        if ( (( r_dcache_fsm_save == DCACHE_BIS ) ||( r_dcache_fsm_save == DCACHE_MISS_WAIT ) || ( r_dcache_fsm_save == DCACHE_MISS_UPDT ) ) && ( dreq.valid ) )        
+        {
+            m_cost_data_miss_frz++;
+        }
+        if( (( r_dcache_fsm_save == DCACHE_DTLB1_READ_CACHE ) || ( r_dcache_fsm_save == DCACHE_DTLB2_READ_CACHE ) ||
+             ( r_dcache_fsm_save == DCACHE_TLB1_READ )        || ( r_dcache_fsm_save == DCACHE_TLB2_READ )        ||
+             ( 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_TLB1_READ_UPDT )   || ( r_dcache_fsm_save == DCACHE_TLB2_READ_UPDT )   ||
+             ( r_dcache_fsm_save == DCACHE_TLB1_UPDT_SEL )    || ( r_dcache_fsm_save == DCACHE_TLB2_UPDT_SEL )) && (dreq.valid) )
+        {
+            m_cost_data_tlb_miss_frz++;
+        }
+
+        if ( ( r_dcache_fsm_save == DCACHE_ITLB_READ ) ||( r_dcache_fsm_save == DCACHE_ITLB_UPDT ) || ( r_dcache_fsm_save == DCACHE_ITLB_LL_WAIT ) || ( r_dcache_fsm_save == DCACHE_ITLB_SC_WAIT ) )        
+        {
+            m_cost_ins_tlb_occup_cache_frz++;
+        }
+
+        m_cpt_dcache_dir_write++;
+        m_cpt_dcache_data_write++;
+        data_t* buf = r_tgt_buf;
+        for( size_t i = 0; i < m_dcache_words; i++ )
+        {
+            if( r_tgt_val[i] ) r_dcache.write( r_tgt_addr.read() + i*4, buf[i] );
+        }
+           
+        r_tgt_dcache_req = false;
+	r_tgt_dcache_rsp = true;
+        r_dcache_fsm = r_dcache_fsm_save;
+        break;
+    }
+    /////////////////////
+    case DCACHE_CC_INVAL:   // invalidate a cache line
+    {
+        /* activity counter */
+        if ( (( r_dcache_fsm_save == DCACHE_BIS ) ||( r_dcache_fsm_save == DCACHE_MISS_WAIT ) || ( r_dcache_fsm_save == DCACHE_MISS_UPDT ) ) && ( dreq.valid ) )        
+        {
+            m_cost_data_miss_frz++;
+        }
+        if( (( r_dcache_fsm_save == DCACHE_DTLB1_READ_CACHE ) || ( r_dcache_fsm_save == DCACHE_DTLB2_READ_CACHE ) ||
+             ( r_dcache_fsm_save == DCACHE_TLB1_READ )        || ( r_dcache_fsm_save == DCACHE_TLB2_READ )        ||
+             ( 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_TLB1_READ_UPDT )   || ( r_dcache_fsm_save == DCACHE_TLB2_READ_UPDT )   ||
+             ( r_dcache_fsm_save == DCACHE_TLB1_UPDT_SEL )    || ( r_dcache_fsm_save == DCACHE_TLB2_UPDT_SEL )) && (dreq.valid) )
+        {
+            m_cost_data_tlb_miss_frz++;
+        }
+        if ( ( r_dcache_fsm_save == DCACHE_ITLB_READ ) ||( r_dcache_fsm_save == DCACHE_ITLB_UPDT ) || ( r_dcache_fsm_save == DCACHE_ITLB_LL_WAIT ) || ( r_dcache_fsm_save == DCACHE_ITLB_SC_WAIT ) )        
+        {
+            m_cost_ins_tlb_occup_cache_frz++;
+        }
+
+        r_tgt_dcache_rsp = r_dcache.inval(r_tgt_addr.read());
+        r_tgt_dcache_req = false;
+        r_dcache_fsm = r_dcache_fsm_save;
+        break;
+    }
+    ///////////////////
+    case DCACHE_CC_NOP:     // no external hit
+    {
+        /* activity counter */
+        if ( (( r_dcache_fsm_save == DCACHE_BIS ) ||( r_dcache_fsm_save == DCACHE_MISS_WAIT ) || ( r_dcache_fsm_save == DCACHE_MISS_UPDT ) ) && ( dreq.valid ) )        
+        {
+            m_cost_data_miss_frz++;
+        }
+        if( (( r_dcache_fsm_save == DCACHE_DTLB1_READ_CACHE ) || ( r_dcache_fsm_save == DCACHE_DTLB2_READ_CACHE ) ||
+             ( r_dcache_fsm_save == DCACHE_TLB1_READ )        || ( r_dcache_fsm_save == DCACHE_TLB2_READ )        ||
+             ( 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_TLB1_READ_UPDT )   || ( r_dcache_fsm_save == DCACHE_TLB2_READ_UPDT )   ||
+             ( r_dcache_fsm_save == DCACHE_TLB1_UPDT_SEL )    || ( r_dcache_fsm_save == DCACHE_TLB2_UPDT_SEL )) && (dreq.valid) )
+        {
+            m_cost_data_tlb_miss_frz++;
+        }
+        if ( ( r_dcache_fsm_save == DCACHE_ITLB_READ ) ||( r_dcache_fsm_save == DCACHE_ITLB_UPDT ) || ( r_dcache_fsm_save == DCACHE_ITLB_LL_WAIT ) || ( r_dcache_fsm_save == DCACHE_ITLB_SC_WAIT ) )        
+        {
+            m_cost_ins_tlb_occup_cache_frz++;
+        }
+
+        r_tgt_dcache_req = false;
+        if ( r_tgt_update )
+	{
+            r_tgt_dcache_rsp = true;
+        } 
+	else 
+	{
+            r_tgt_dcache_rsp = false;
+        }
+
+        r_dcache_fsm = r_dcache_fsm_save;
+        break;
+    }   
+    /////////////////////////
+    case DCACHE_TLB_CC_INVAL:
+    {
+        /* activity counter */
+        if ( (( r_dcache_fsm_save == DCACHE_BIS ) ||( r_dcache_fsm_save == DCACHE_MISS_WAIT ) || ( r_dcache_fsm_save == DCACHE_MISS_UPDT ) ) && ( dreq.valid ) )        
+        {
+            m_cost_data_miss_frz++;
+        }
+        if( (( r_dcache_fsm_save == DCACHE_DTLB1_READ_CACHE ) || ( r_dcache_fsm_save == DCACHE_DTLB2_READ_CACHE ) ||
+             ( r_dcache_fsm_save == DCACHE_TLB1_READ )        || ( r_dcache_fsm_save == DCACHE_TLB2_READ )        ||
+             ( 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_TLB1_READ_UPDT )   || ( r_dcache_fsm_save == DCACHE_TLB2_READ_UPDT )   ||
+             ( r_dcache_fsm_save == DCACHE_TLB1_UPDT_SEL )    || ( r_dcache_fsm_save == DCACHE_TLB2_UPDT_SEL )) && (dreq.valid) )
+        {
+            m_cost_data_tlb_miss_frz++;
+        }
+        if ( ( r_dcache_fsm_save == DCACHE_ITLB_READ ) ||( r_dcache_fsm_save == DCACHE_ITLB_UPDT ) || ( r_dcache_fsm_save == DCACHE_ITLB_LL_WAIT ) || ( r_dcache_fsm_save == DCACHE_ITLB_SC_WAIT ) )        
+        {
+            m_cost_ins_tlb_occup_cache_frz++;
+        }
+
+	if ( r_dcache_itlb_inval_req || r_dcache_dtlb_inval_req ) break;
+
+        if( (( 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_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_TLB1_UPDT_SEL )    || ( r_dcache_fsm_save == DCACHE_TLB2_UPDT_SEL )    ||
+             ( 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_WRITE_DIRTY )) && 
+            (((r_dcache_tlb_paddr.read() & ~((m_dcache_words<<2)-1)) >> (uint32_log2(m_dcache_words) + 2)) == r_dcache_dtlb_inval_line.read()) ) 
+        {
+            r_dcache_inval_tlb_rsp = true;
+        } 
+
+        if (((r_dcache_fsm_save == DCACHE_BIS)||(r_dcache_fsm_save == DCACHE_MISS_WAIT) ||
+             (r_dcache_fsm_save == DCACHE_MISS_UPDT)) && 
+             (r_dcache_tlb_nline.read() == r_dcache_dtlb_inval_line.read()))
+        {
+            r_dcache_inval_tlb_rsp = true;
+        }
+
+	if ( !r_dcache_cc_check )
+	{
+            r_dcache_fsm = r_dcache_fsm_save;
+	}
+	else
+	{
+            r_dcache_fsm = DCACHE_CC_CHECK;
+	    r_dcache_cc_check = false;
+	}
+	r_dtlb_translation_valid = false;
+        r_dcache_ptba_ok = false;
+        break;
+    }
+    /////////////////////////
+    case DCACHE_ITLB_CLEANUP:
+    {
+        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;
+        break;
+    }
+    } // end switch r_dcache_fsm
+
+#ifdef SOCLIB_MODULE_DEBUG
+    std::cout << name() << " Data Response: " << drsp << std::endl;
+#endif
+    ////////////////////////////////////////////////////////////////////////////////////
+    //      INVAL DTLB CHECK FSM 
+    ////////////////////////////////////////////////////////////////////////////////////////
+    switch(r_inval_dtlb_fsm) {
+    /////////////////////
+    case INVAL_DTLB_IDLE:
+    {
+        if ( r_dcache_dtlb_inval_req ) 
+        {
+            r_ccinval_dtlb_way = 0;
+            r_ccinval_dtlb_set = 0;
+            r_inval_dtlb_fsm = INVAL_DTLB_CHECK;    
+            m_cost_data_tlb_inval_frz++;
+        }   
+        break;
+    }
+    ////////////////////////////
+    case INVAL_DTLB_CHECK:
+    {
+        m_cost_data_tlb_inval_frz++;
+
+        size_t way = r_ccinval_dtlb_way; 
+        size_t set = r_ccinval_dtlb_set;
+        bool end = false;        
+        bool tlb_hit = dcache_tlb.cccheck(r_dcache_dtlb_inval_line.read(), way, set, &way, &set, &end); 
+    
+        if ( tlb_hit )
+        {
+            r_ccinval_dtlb_way = way; 
+            r_ccinval_dtlb_set = set;
+            r_dtlb_cc_check_end = end;
+            r_inval_dtlb_fsm = INVAL_DTLB_INVAL;
+            m_cpt_data_tlb_inval++;    
+        }        
+        else
+        {
+            r_inval_dtlb_fsm = INVAL_DTLB_CLEAR;    
+        }
+        break;
+    }
+    /////////////////////////
+    case INVAL_DTLB_INVAL:
+    {
+        m_cost_data_tlb_inval_frz++;
+
+        dcache_tlb.ccinval(r_ccinval_dtlb_way, r_ccinval_dtlb_set);
+
+        if ( !r_dtlb_cc_check_end )
+        {
+            r_inval_dtlb_fsm = INVAL_DTLB_CHECK; 
+        }
+        else
+        {
+            r_inval_dtlb_fsm = INVAL_DTLB_CLEAR;    
+        }
+        break;
+    }
+    ////////////////////
+    case INVAL_DTLB_CLEAR:
+    {
+        r_dcache_dtlb_inval_req = false;
+        r_dtlb_cc_check_end = false;
+        r_ccinval_dtlb_way = 0; 
+        r_ccinval_dtlb_set = 0; 
+        r_inval_dtlb_fsm = INVAL_DTLB_IDLE;   
+        m_cpt_data_tlb_inval++;    
+        break;
+    }
+    } // end switch r_inval_itlb_fsm
+
+    /////////// execute one iss cycle /////////////////////////////////
+    {
+    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);
+    m_iss.executeNCycles(1, irsp, drsp, it);
+    }
+
+    ////////////// number of frozen cycles //////////////////////////
+    if ( (ireq.valid && !irsp.valid) || (dreq.valid && !drsp.valid) )
+    {
+        m_cpt_frz_cycles++;
+    }
+    if ( dreq.valid && !drsp.valid ) 
+    {
+        m_cpt_dcache_frz_cycles++;
+    }
+#ifdef EVALUATION_CACHE
+    for (size_t way = 0; way < m_dcache_ways; way++ )
+    {    
+        for (size_t set = 0; set < m_dcache_sets; set++ )
+        {
+	    if (r_dcache_in_itlb[way*m_dcache_sets+set] || r_dcache_in_dtlb[way*m_dcache_sets+set])
+		m_cpt_tlb_occup_dcache++;
+	}
+    }
+#endif
+    ////////////////////////////////////////////////////////////////////////////
+    //     VCI_CMD FSM 
+    //
+    // This FSM handles requests from both the DCACHE controler
+    // (request registers) and the ICACHE controler (request registers).
+    // There is 10 VCI transaction types :
+    // - INS_TLB_READ
+    // - INS_TLB_WRITE
+    // - INS_MISS
+    // - INS_UNC_MISS
+    // - DATA_TLB_READ
+    // - DATA_TLB_WRITE
+    // - DATA_TLB_DIRTY
+    // - DATA_MISS
+    // - DATA_UNC 
+    // - DATA_WRITE
+    // The ICACHE requests have the highest priority.
+    // There is at most one (CMD/RSP) VCI transaction, as both CMD_FSM and RSP_FSM
+    // exit simultaneously the IDLE state.
+    //////////////////////////////////////////////////////////////////////////////
+
+    switch (r_vci_cmd_fsm) {
+    
+    case CMD_IDLE:
+        if (r_vci_rsp_fsm != RSP_IDLE)
+            break;
+
+        r_vci_cmd_cpt = 0;
+
+        if ( (r_dcache_cleanup_req && r_dcache_itlb_read_req && (((r_icache_paddr_save.read() & ~((m_dcache_words<<2)-1)) >> (uint32_log2(m_dcache_words) + 2)) == r_dcache_cleanup_line.read())) 
+             || (r_dcache_cleanup_req && r_dcache_tlb_read_req && (((r_dcache_tlb_paddr.read() & ~((m_dcache_words<<2)-1)) >> (uint32_log2(m_dcache_words) + 2)) == r_dcache_cleanup_line.read()))
+             || (r_dcache_cleanup_req && r_dcache_miss_req && (((r_dcache_paddr_save.read() & ~((m_dcache_words<<2)-1)) >> (uint32_log2(m_dcache_words) + 2)) == r_dcache_cleanup_line.read()))
+             || (r_icache_cleanup_req && r_icache_miss_req && (((r_icache_paddr_save.read() & ~((m_icache_words<<2)-1)) >> (uint32_log2(m_icache_words) + 2)) == r_icache_cleanup_line.read())) )
+        {
+            break;
+        }
+
+        if (r_dcache_itlb_read_req)           
+        {            
+            r_vci_cmd_fsm = CMD_ITLB_READ;
+            m_cpt_itlbmiss_transaction++; 
+        } 
+        else if (r_dcache_itlb_ll_acc_req)
+        {
+            r_vci_cmd_fsm = CMD_ITLB_ACC_LL;
+            m_cpt_itlb_ll_transaction++; 
+        }
+        else if (r_dcache_itlb_sc_acc_req)
+        {
+            r_vci_cmd_fsm = CMD_ITLB_ACC_SC;
+            m_cpt_itlb_sc_transaction++; 
+        }
+        else if (r_icache_miss_req) 
+        {    
+            r_vci_cmd_fsm = CMD_INS_MISS;
+            m_cpt_imiss_transaction++; 
+        }
+        else if (r_icache_unc_req) 
+        {    
+            r_vci_cmd_fsm = CMD_INS_UNC;
+            m_cpt_icache_unc_transaction++; 
+        }  
+        else if (r_dcache_tlb_read_req) 
+        {            
+            r_vci_cmd_fsm = CMD_DTLB_READ;
+            m_cpt_dtlbmiss_transaction++; 
+        } 
+        else if (r_dcache_tlb_ll_acc_req) 
+        {  
+            r_vci_cmd_fsm = CMD_DTLB_ACC_LL;
+            m_cpt_dtlb_ll_transaction++; 
+        } 
+        else if (r_dcache_tlb_sc_acc_req) 
+        {  
+            r_vci_cmd_fsm = CMD_DTLB_ACC_SC;
+            m_cpt_dtlb_sc_transaction++; 
+        } 
+        else if (r_dcache_tlb_ll_dirty_req) 
+        {  
+            r_vci_cmd_fsm = CMD_DTLB_DIRTY_LL;
+            m_cpt_dtlb_ll_dirty_transaction++; 
+        } 
+        else if (r_dcache_tlb_sc_dirty_req) 
+        {  
+            r_vci_cmd_fsm = CMD_DTLB_DIRTY_SC;
+            m_cpt_dtlb_sc_dirty_transaction++; 
+        } 
+        else if (r_dcache_write_req)
+        {
+            r_vci_cmd_fsm = CMD_DATA_WRITE;
+            r_vci_cmd_cpt = r_wbuf.getMin();
+            r_vci_cmd_min = r_wbuf.getMin();
+            r_vci_cmd_max = r_wbuf.getMax(); 
+            m_cpt_write_transaction++; 
+            m_length_write_transaction += (r_wbuf.getMax() - r_wbuf.getMin() + 1);
+        }
+        else if (r_dcache_miss_req)  
+        {
+            r_vci_cmd_fsm = CMD_DATA_MISS;
+            m_cpt_dmiss_transaction++; 
+        }
+        else if (r_dcache_unc_req)  
+        {
+            r_vci_cmd_fsm = CMD_DATA_UNC;
+            m_cpt_unc_transaction++; 
+        }
+        break;
+
+    case CMD_DATA_WRITE:
+        if ( p_vci_ini_rw.cmdack.read() ) 
+        {
+            r_vci_cmd_cpt = r_vci_cmd_cpt + 1;
+            if (r_vci_cmd_cpt == r_vci_cmd_max) 
+            {
+                r_vci_cmd_fsm = CMD_IDLE;
+                r_wbuf.reset();
+            }
+        }
+        break;
+
+    default:
+        if ( p_vci_ini_rw.cmdack.read() )
+        {  
+            r_vci_cmd_fsm = CMD_IDLE;
+        }
+        break;
+
+    } // end  switch r_vci_cmd_fsm
+
+    //////////////////////////////////////////////////////////////////////////
+    //      VCI_RSP FSM 
+    //
+    // This FSM is synchronized with the VCI_CMD FSM, as both FSMs exit the
+    // IDLE state simultaneously.
+    //////////////////////////////////////////////////////////////////////////
+
+    switch (r_vci_rsp_fsm) {
+
+    case RSP_IDLE:
+        assert( !p_vci_ini_rw.rspval.read() && "Unexpected response" );
+
+        if (r_vci_cmd_fsm != CMD_IDLE)
+            break;
+
+        r_vci_rsp_cpt = 0;
+
+	if ( (r_dcache_cleanup_req && r_dcache_itlb_read_req && (((r_icache_paddr_save.read() & ~((m_dcache_words<<2)-1)) >> (uint32_log2(m_dcache_words) + 2)) == r_dcache_cleanup_line.read())) 
+	  || (r_dcache_cleanup_req && r_dcache_tlb_read_req && (((r_dcache_tlb_paddr.read() & ~((m_dcache_words<<2)-1)) >> (uint32_log2(m_dcache_words) + 2)) == r_dcache_cleanup_line.read()))
+	  || (r_dcache_cleanup_req && r_dcache_miss_req && (((r_dcache_paddr_save.read() & ~((m_dcache_words<<2)-1)) >> (uint32_log2(m_dcache_words) + 2)) == r_dcache_cleanup_line.read()))
+	  || (r_icache_cleanup_req && r_icache_miss_req && (((r_icache_paddr_save.read() & ~((m_icache_words<<2)-1)) >> (uint32_log2(m_icache_words) + 2)) == r_icache_cleanup_line.read())) )
+	{
+	    break;
+	}
+
+        if (r_dcache_itlb_read_req)          // ITLB miss response
+        {            
+            r_vci_rsp_fsm = RSP_ITLB_READ;
+        } 
+        else if (r_dcache_itlb_ll_acc_req)   // ITLB linked load response
+        {   
+            r_vci_rsp_fsm = RSP_ITLB_ACC_LL;
+        } 
+        else if (r_dcache_itlb_sc_acc_req)   // ITLB store conditional response
+        {   
+            r_vci_rsp_fsm = RSP_ITLB_ACC_SC;
+        } 
+        else if (r_icache_miss_req)          // ICACHE cached miss response
+        {   
+            r_vci_rsp_fsm = RSP_INS_MISS;
+        }
+        else if (r_icache_unc_req)           // ICACHE uncached miss response
+        {   
+            r_vci_rsp_fsm = RSP_INS_UNC;
+        }  
+        else if (r_dcache_tlb_read_req)      // ITLB miss response
+        {
+            r_vci_rsp_fsm = RSP_DTLB_READ; 
+        }
+        else if (r_dcache_tlb_ll_acc_req)    // DTLB access bits linked load response
+        {
+            r_vci_rsp_fsm = RSP_DTLB_ACC_LL; 
+        }
+        else if (r_dcache_tlb_sc_acc_req)    // DTLB access bits store conditional response
+        {
+            r_vci_rsp_fsm = RSP_DTLB_ACC_SC; 
+        }
+        else if (r_dcache_tlb_ll_dirty_req)  // DTLB dirty bit linked load response
+        {
+            r_vci_rsp_fsm = RSP_DTLB_DIRTY_LL; 
+        }
+        else if (r_dcache_tlb_sc_dirty_req)  // DTLB dirty bit store conditional response
+        {
+            r_vci_rsp_fsm = RSP_DTLB_DIRTY_SC; 
+        }
+        else if (r_dcache_write_req)         // DCACHE write response
+        {
+            r_vci_rsp_fsm = RSP_DATA_WRITE;
+        }
+        else if (r_dcache_miss_req)          // DCACHE read response
+        {
+            r_vci_rsp_fsm = RSP_DATA_MISS;
+        }
+        else if (r_dcache_unc_req)           // DCACHE uncached read response
+        {
+            r_vci_rsp_fsm = RSP_DATA_UNC;
+        }
+        break;
+
+    case RSP_ITLB_READ:
+        m_cost_itlbmiss_transaction++;
+        if ( ! p_vci_ini_rw.rspval.read() )
+            break;
+
+        assert(r_vci_rsp_cpt != m_dcache_words &&
+               "illegal VCI response packet for data read miss");
+
+        r_vci_rsp_cpt = r_vci_rsp_cpt + 1;
+        r_dcache_miss_buf[r_vci_rsp_cpt] = (data_t)p_vci_ini_rw.rdata.read();
+        if ( p_vci_ini_rw.reop.read() ) 
+        {
+            assert(r_vci_rsp_cpt == m_dcache_words - 1 &&
+                    "illegal VCI response packet for data read miss");
+            r_dcache_itlb_read_req = false;
+            r_vci_rsp_fsm = RSP_IDLE;
+        } 
+        if ( (p_vci_ini_rw.rerror.read() % 1) != vci_param::ERR_NORMAL )
+        {
+            r_vci_rsp_data_error = true;
+        }
+        break;
+
+    case RSP_ITLB_ACC_LL:
+	m_cost_itlb_ll_transaction++;
+        if ( ! p_vci_ini_rw.rspval.read() )
+            break;
+
+        assert(p_vci_ini_rw.reop.read() &&
+               "illegal VCI response packet for ll tlb");
+
+        if ( (p_vci_ini_rw.rerror.read() % 1) != vci_param::ERR_NORMAL ) 
+        {
+            r_vci_rsp_data_error = true;
+        }
+	else
+	{
+	    r_dcache_miss_buf[0] = (data_t)p_vci_ini_rw.rdata.read();
+	}
+        r_dcache_itlb_ll_acc_req = false;
+        r_vci_rsp_fsm = RSP_IDLE;
+	break;
+
+    case RSP_ITLB_ACC_SC:
+	m_cost_itlb_sc_transaction++;
+        if ( ! p_vci_ini_rw.rspval.read() )
+            break;
+
+        assert(p_vci_ini_rw.reop.read() &&
+               "illegal VCI response packet for sc tlb");
+
+        if ( (p_vci_ini_rw.rerror.read() % 1) != vci_param::ERR_NORMAL ) 
+        {
+            r_vci_rsp_data_error = true;
+        }
+	else if ( p_vci_ini_rw.rdata.read() == 1 ) // store conditional is not successful
+	{
+	    r_dcache_tlb_sc_fail = true;
+	    //r_dcache_itlb_ll_acc_req = true;
+	}
+        r_dcache_itlb_sc_acc_req = false;
+        r_vci_rsp_fsm = RSP_IDLE;
+	break;
+
+    case RSP_INS_MISS:
+        m_cost_imiss_transaction++;
+        if ( ! p_vci_ini_rw.rspval.read() )
+            break;
+
+        assert( (r_vci_rsp_cpt < m_icache_words) && 
+               "The VCI response packet for instruction miss is too long");
+        r_vci_rsp_cpt = r_vci_rsp_cpt + 1;
+        r_icache_miss_buf[r_vci_rsp_cpt] = (data_t)p_vci_ini_rw.rdata.read();
+
+        if ( p_vci_ini_rw.reop.read() ) 
+        {
+            assert( (r_vci_rsp_cpt == m_icache_words - 1) &&
+                       "The VCI response packet for instruction miss is too short");
+            r_icache_miss_req = false;
+            r_vci_rsp_fsm = RSP_IDLE;
+                
+        } 
+        if ( (p_vci_ini_rw.rerror.read() % 1) != vci_param::ERR_NORMAL )
+        {
+            r_vci_rsp_ins_error = true;
+        }
+        break;
+
+    case RSP_INS_UNC:
+        m_cost_icache_unc_transaction++;
+        if ( ! p_vci_ini_rw.rspval.read() )
+            break;
+
+        assert(p_vci_ini_rw.reop.read() &&
+               "illegal VCI response packet for uncached instruction");
+
+        r_icache_miss_buf[0] = (data_t)p_vci_ini_rw.rdata.read();
+        r_icache_buf_unc_valid = true;
+        r_icache_unc_req = false;
+        r_vci_rsp_fsm = RSP_IDLE;
+
+        if ( (p_vci_ini_rw.rerror.read() % 1) != vci_param::ERR_NORMAL )
+        {
+            r_vci_rsp_ins_error = true;
+        }
+        break;
+
+    case RSP_DTLB_READ:
+        m_cost_dtlbmiss_transaction++;
+        if ( ! p_vci_ini_rw.rspval.read() )
+            break;
+
+        assert(r_vci_rsp_cpt != m_dcache_words &&
+               "illegal VCI response packet for data read miss");
+
+        r_vci_rsp_cpt = r_vci_rsp_cpt + 1;
+        r_dcache_miss_buf[r_vci_rsp_cpt] = (data_t)p_vci_ini_rw.rdata.read();
+        if ( p_vci_ini_rw.reop.read() ) 
+        {
+            assert(r_vci_rsp_cpt == m_dcache_words - 1 &&
+                    "illegal VCI response packet for data read miss");
+            r_dcache_tlb_read_req = false;
+            r_vci_rsp_fsm = RSP_IDLE;
+        } 
+        if ( (p_vci_ini_rw.rerror.read() % 1) != vci_param::ERR_NORMAL )
+        {
+            r_vci_rsp_data_error = true;
+        }
+        break;
+
+    case RSP_DTLB_ACC_LL:
+	m_cost_dtlb_ll_transaction++; 
+        if ( ! p_vci_ini_rw.rspval.read() )
+            break;
+
+        assert(p_vci_ini_rw.reop.read() &&
+               "illegal VCI response packet for ll tlb");
+
+        if ( (p_vci_ini_rw.rerror.read() % 1) != vci_param::ERR_NORMAL ) 
+        {
+            r_vci_rsp_data_error = true;
+        }
+	else
+	{
+	    r_dcache_miss_buf[0] = (data_t)p_vci_ini_rw.rdata.read();
+	}
+        r_dcache_tlb_ll_acc_req = false;
+        r_vci_rsp_fsm = RSP_IDLE;
+	break;
+
+    case RSP_DTLB_ACC_SC:
+	m_cost_dtlb_sc_transaction++;
+        if ( ! p_vci_ini_rw.rspval.read() )
+            break;
+
+        assert(p_vci_ini_rw.reop.read() &&
+               "illegal VCI response packet for sc tlb");
+
+        if ( (p_vci_ini_rw.rerror.read()  % 1 )!= vci_param::ERR_NORMAL ) 
+        {
+            r_vci_rsp_data_error = true;
+        }
+	else if ( p_vci_ini_rw.rdata.read() == 1 ) // store conditional is not successful
+	{
+	    r_dcache_tlb_sc_fail = true;
+	}
+        r_dcache_tlb_sc_acc_req = false;
+        r_vci_rsp_fsm = RSP_IDLE;
+	break;
+
+    case RSP_DTLB_DIRTY_LL:
+	m_cost_dtlb_ll_dirty_transaction++; 
+        if ( ! p_vci_ini_rw.rspval.read() )
+            break;
+
+        assert(p_vci_ini_rw.reop.read() &&
+               "illegal VCI response packet for ll tlb");
+
+        if ( (p_vci_ini_rw.rerror.read() % 1) != vci_param::ERR_NORMAL ) 
+        {
+            r_vci_rsp_data_error = true;
+        }
+	else
+	{
+	    r_dcache_miss_buf[0] = (data_t)p_vci_ini_rw.rdata.read();
+	}
+        r_dcache_tlb_ll_dirty_req = false;
+        r_vci_rsp_fsm = RSP_IDLE;
+	break;
+
+    case RSP_DTLB_DIRTY_SC:
+	m_cost_dtlb_sc_dirty_transaction++; 
+        if ( ! p_vci_ini_rw.rspval.read() )
+            break;
+
+        assert(p_vci_ini_rw.reop.read() &&
+               "illegal VCI response packet for sc tlb");
+
+        if ( (p_vci_ini_rw.rerror.read() % 1) != vci_param::ERR_NORMAL ) 
+        {
+            r_vci_rsp_data_error = true;
+        }
+	else if ( p_vci_ini_rw.rdata.read() == 1 ) // store conditional is not successful
+	{
+	    r_dcache_tlb_sc_fail = true;
+	}
+        r_dcache_tlb_sc_dirty_req = false;
+        r_vci_rsp_fsm = RSP_IDLE;
+	break;
+
+    case RSP_DATA_UNC:
+        m_cost_unc_transaction++;
+        if ( ! p_vci_ini_rw.rspval.read() ) 
+            break;
+
+        assert(p_vci_ini_rw.reop.read() &&
+               "illegal VCI response packet for data read uncached");
+
+        if ( (p_vci_ini_rw.rerror.read() % 1) != vci_param::ERR_NORMAL ) 
+        {
+            r_vci_rsp_data_error = true;
+        }
+        else
+        {
+            r_dcache_miss_buf[0] = (data_t)p_vci_ini_rw.rdata.read();
+            r_dcache_buf_unc_valid = true;
+        }
+        r_dcache_unc_req = false;
+        r_vci_rsp_fsm = RSP_IDLE;
+        break;
+
+    case RSP_DATA_MISS:
+        m_cost_dmiss_transaction++;
+        if ( ! p_vci_ini_rw.rspval.read() )
+            break;
+
+        assert(r_vci_rsp_cpt != m_dcache_words &&
+               "illegal VCI response packet for data read miss");
+
+        r_vci_rsp_cpt = r_vci_rsp_cpt + 1;
+        r_dcache_miss_buf[r_vci_rsp_cpt] = (data_t)p_vci_ini_rw.rdata.read();
+        if ( p_vci_ini_rw.reop.read() ) 
+        {
+            assert(r_vci_rsp_cpt == m_dcache_words - 1 &&
+                    "illegal VCI response packet for data read miss");
+            r_dcache_miss_req = false;
+            r_vci_rsp_fsm = RSP_IDLE;
+        } 
+        if ( (p_vci_ini_rw.rerror.read() % 1) != vci_param::ERR_NORMAL )
+        {
+            r_vci_rsp_data_error = true;
+        }
+        break;
+
+    case RSP_DATA_WRITE:
+        m_cost_write_transaction++;
+        if ( ! p_vci_ini_rw.rspval.read() )
+            break;
+
+        if ( p_vci_ini_rw.reop.read() ) 
+        {
+            r_vci_rsp_fsm = RSP_IDLE;
+            r_dcache_write_req = false;
+        }
+        if ( (p_vci_ini_rw.rerror.read() % 1) != vci_param::ERR_NORMAL ) 
+        {
+            m_iss.setWriteBerr();
+        }
+        break;
+    } // end switch r_vci_rsp_fsm
+
+    //////////////////////////////////////////////////////////////////////////
+    //      CLEANUP CMD FSM 
+    //
+    // This FSM is synchronized with the CLEANUP RSP FSM, as both FSMs exit the
+    // IDLE state simultaneously.
+    //////////////////////////////////////////////////////////////////////////
+
+    switch (r_cleanup_cmd_fsm) {
+    
+    case CLEANUP_CMD_IDLE:
+        if (r_cleanup_rsp_fsm != CLEANUP_RSP_IDLE)
+            break;
+
+        if (r_dcache_cleanup_req)
+        {
+            r_cleanup_cmd_fsm = CLEANUP_CMD_DATA;
+	        m_cpt_dcleanup_transaction++;
+        }
+        else if (r_icache_cleanup_req)
+        {
+            r_cleanup_cmd_fsm = CLEANUP_CMD_INS;
+	        m_cpt_icleanup_transaction++;
+        }
+        break;
+
+    default:
+        if ( p_vci_ini_c.cmdack.read() )
+        {  
+            r_cleanup_cmd_fsm = CLEANUP_CMD_IDLE;
+        }
+        break;
+
+    } // end  switch r_vci_cmd_fsm
+
+    //////////////////////////////////////////////////////////////////////////
+    //      CLEANUP RSP FSM 
+    //
+    // This FSM is synchronized with the CLEANUP CMD FSM, as both FSMs exit the
+    // IDLE state simultaneously.
+    //////////////////////////////////////////////////////////////////////////
+
+    switch (r_cleanup_rsp_fsm) {
+
+    case CLEANUP_RSP_IDLE:	
+    {
+        assert(!p_vci_ini_c.rspval.read() && "Unexpected response" );
+
+        if (r_cleanup_cmd_fsm != CLEANUP_CMD_IDLE)
+            break;
+
+        if (r_dcache_cleanup_req)
+        {
+            r_cleanup_rsp_fsm = CLEANUP_RSP_DATA;
+        }
+        else if (r_icache_cleanup_req)
+        {
+            r_cleanup_rsp_fsm = CLEANUP_RSP_INS;
+        }
+        break;
+    }
+    case CLEANUP_RSP_DATA:
+    {
+	    m_cost_dcleanup_transaction++;
+        if ( ! p_vci_ini_c.rspval.read() )
+            break;
+        assert( p_vci_ini_c.reop.read() &&
+                "illegal VCI response packet for dcache cleanup");
+        assert( ((p_vci_ini_c.rerror.read() % 1) == vci_param::ERR_NORMAL) &&
+                "error in response packet for dcache cleanup");    
+
+        r_dcache_cleanup_req = false;
+        r_cleanup_rsp_fsm = CLEANUP_RSP_IDLE;    
+	break;  	    
+    }
+    case CLEANUP_RSP_INS:
+    {
+	    m_cost_icleanup_transaction++;
+        if ( ! p_vci_ini_c.rspval.read() )
+            break;
+        assert( p_vci_ini_c.reop.read() &&
+                "illegal VCI response packet for icache cleanup");
+        assert( ((p_vci_ini_c.rerror.read() % 1) == vci_param::ERR_NORMAL) &&
+                "error in response packet for icache cleanup");
+
+        r_icache_cleanup_req = false;
+        r_cleanup_rsp_fsm = CLEANUP_RSP_IDLE;    
+	break;    
+    }
+    } // end  switch r_cleanup_fsm
+
+} // end transition()
+
+
+#define   _CMD_ITLB    0x1
+#define   _CMD_DTLB    0x2   
+#define   _CMD_USR     0x4
+
+///////////////////////
+tmpl(void)::genMoore()
+///////////////////////
+{
+    // VCI initiator response
+    p_vci_ini_rw.rspack = true;
+
+    // VCI initiator command
+    p_vci_ini_rw.pktid  = 0;
+    p_vci_ini_rw.srcid  = m_srcid_rw;
+    p_vci_ini_rw.cons   = false;
+    p_vci_ini_rw.wrap   = false;
+    p_vci_ini_rw.contig = true;
+    p_vci_ini_rw.clen   = 0;
+    p_vci_ini_rw.cfixed = false;
+
+    switch (r_vci_cmd_fsm) {
+
+    case CMD_IDLE:
+        p_vci_ini_rw.cmdval  = false;
+        p_vci_ini_rw.address = 0;
+        p_vci_ini_rw.wdata   = 0;
+        p_vci_ini_rw.be      = 0;
+        p_vci_ini_rw.trdid   = 0;
+        p_vci_ini_rw.plen    = 0;
+        p_vci_ini_rw.cmd     = vci_param::CMD_NOP;
+        p_vci_ini_rw.eop     = false;
+        break;
+
+    case CMD_ITLB_READ:     
+        p_vci_ini_rw.cmdval  = true;
+        p_vci_ini_rw.address = r_icache_paddr_save.read() & m_dcache_yzmask;
+        p_vci_ini_rw.wdata   = 0;
+        p_vci_ini_rw.be      = 0xF;
+        p_vci_ini_rw.trdid   = 1; // via data cache cached read
+        p_vci_ini_rw.plen    = m_dcache_words << 2;
+        p_vci_ini_rw.cmd     = vci_param::CMD_READ;
+        p_vci_ini_rw.eop     = true;
+        p_vci_ini_rw.pktid   = (r_ireq_isUser_save == true) ? _CMD_ITLB | _CMD_USR : _CMD_ITLB;
+        break;
+
+    case CMD_ITLB_ACC_LL:
+        p_vci_ini_rw.cmdval  = true;
+        p_vci_ini_rw.address = r_icache_paddr_save.read() & ~0x3;
+        p_vci_ini_rw.wdata   = 0;
+        p_vci_ini_rw.be      = 0xF;
+        p_vci_ini_rw.trdid   = 0; // data cache uncached read
+        p_vci_ini_rw.plen    = 4;
+        p_vci_ini_rw.cmd     = vci_param::CMD_LOCKED_READ;
+        p_vci_ini_rw.eop     = true;
+        p_vci_ini_rw.pktid   = (r_ireq_isUser_save == true) ? _CMD_ITLB | _CMD_USR : _CMD_ITLB;
+	break;
+
+    case CMD_ITLB_ACC_SC:
+        p_vci_ini_rw.cmdval  = true;
+        p_vci_ini_rw.address = r_icache_paddr_save.read() & ~0x3;
+        p_vci_ini_rw.wdata   = r_icache_pte_update.read();
+        p_vci_ini_rw.be      = 0xF;
+        p_vci_ini_rw.trdid   = 0; // data cache uncached read
+        p_vci_ini_rw.plen    = 4;
+        p_vci_ini_rw.cmd     = vci_param::CMD_STORE_COND;
+        p_vci_ini_rw.eop     = true;
+        p_vci_ini_rw.pktid   = (r_ireq_isUser_save == true) ? _CMD_ITLB | _CMD_USR : _CMD_ITLB;
+	break;	
+
+    case CMD_INS_MISS:
+        p_vci_ini_rw.cmdval  = true;
+        p_vci_ini_rw.address = r_icache_paddr_save.read() & m_icache_yzmask;
+        p_vci_ini_rw.wdata   = 0;
+        p_vci_ini_rw.be      = 0xF;
+        p_vci_ini_rw.trdid   = 3; // ins cache cached read
+        p_vci_ini_rw.plen    = m_icache_words << 2;
+        p_vci_ini_rw.cmd     = vci_param::CMD_READ;
+        p_vci_ini_rw.eop     = true;
+        p_vci_ini_rw.pktid   = (r_ireq_isUser_save == true) ? _CMD_USR : 0;
+        break;
+
+    case CMD_INS_UNC:
+        p_vci_ini_rw.cmdval  = true;
+        p_vci_ini_rw.address = r_icache_paddr_save.read() & ~0x3;
+        p_vci_ini_rw.wdata   = 0;
+        p_vci_ini_rw.be      = 0xF;
+        p_vci_ini_rw.trdid   = 2; // ins cache uncached read
+        p_vci_ini_rw.plen    = 4;
+        p_vci_ini_rw.cmd     = vci_param::CMD_READ;
+        p_vci_ini_rw.eop     = true;
+        p_vci_ini_rw.pktid   = (r_ireq_isUser_save == true) ? _CMD_USR : 0;
+        break;
+
+    case CMD_DTLB_READ:     
+        p_vci_ini_rw.cmdval  = true;
+        p_vci_ini_rw.address = r_dcache_tlb_paddr.read() & m_dcache_yzmask;
+        p_vci_ini_rw.wdata   = 0;
+        p_vci_ini_rw.be      = 0xF;
+        p_vci_ini_rw.trdid   = 1; // via dcache cached read
+        p_vci_ini_rw.plen    = m_dcache_words << 2;
+        p_vci_ini_rw.cmd     = vci_param::CMD_READ;
+        p_vci_ini_rw.eop     = true;
+        p_vci_ini_rw.pktid   = (r_dreq_isUser_save == true) ? _CMD_DTLB | _CMD_USR : _CMD_DTLB;
+        break;
+
+    case CMD_DTLB_ACC_LL:
+        p_vci_ini_rw.cmdval  = true;
+        p_vci_ini_rw.address = r_dcache_tlb_paddr.read() & ~0x3;
+        p_vci_ini_rw.wdata   = 0;
+        p_vci_ini_rw.be      = 0xF;
+        p_vci_ini_rw.trdid   = 0; // data cache uncached read
+        p_vci_ini_rw.plen    = 4;
+        p_vci_ini_rw.cmd     = vci_param::CMD_LOCKED_READ;
+        p_vci_ini_rw.eop     = true;
+        p_vci_ini_rw.pktid   = (r_dreq_isUser_save == true) ? _CMD_DTLB | _CMD_USR : _CMD_DTLB;
+	break;
+
+    case CMD_DTLB_ACC_SC:
+        p_vci_ini_rw.cmdval  = true;
+        p_vci_ini_rw.address = r_dcache_tlb_paddr.read() & ~0x3;
+        p_vci_ini_rw.wdata   = r_dcache_pte_update.read();
+        p_vci_ini_rw.be      = 0xF;
+        p_vci_ini_rw.trdid   = 0; // data cache uncached read
+        p_vci_ini_rw.plen    = 4;
+        p_vci_ini_rw.cmd     = vci_param::CMD_STORE_COND;
+        p_vci_ini_rw.eop     = true;
+        p_vci_ini_rw.pktid   = (r_dreq_isUser_save == true) ? _CMD_DTLB | _CMD_USR : _CMD_DTLB;
+	break;	
+
+    case CMD_DTLB_DIRTY_LL:
+        p_vci_ini_rw.cmdval  = true;
+        p_vci_ini_rw.address = r_dcache_tlb_paddr.read() & ~0x3;
+        p_vci_ini_rw.wdata   = 0;
+        p_vci_ini_rw.be      = 0xF;
+        p_vci_ini_rw.trdid   = 0; // data cache uncached read
+        p_vci_ini_rw.plen    = 4;
+        p_vci_ini_rw.cmd     = vci_param::CMD_LOCKED_READ;
+        p_vci_ini_rw.eop     = true;
+        p_vci_ini_rw.pktid   = (r_dreq_isUser_save == true) ? _CMD_DTLB | _CMD_USR : _CMD_DTLB;
+	break;
+
+    case CMD_DTLB_DIRTY_SC:
+        p_vci_ini_rw.cmdval  = true;
+        p_vci_ini_rw.address = r_dcache_tlb_paddr.read() & ~0x3;
+        p_vci_ini_rw.wdata   = r_dcache_pte_update.read();
+        p_vci_ini_rw.be      = 0xF;
+        p_vci_ini_rw.trdid   = 0; // data cache uncached read
+        p_vci_ini_rw.plen    = 4;
+        p_vci_ini_rw.cmd     = vci_param::CMD_STORE_COND;
+        p_vci_ini_rw.eop     = true;
+        p_vci_ini_rw.pktid   = (r_dreq_isUser_save == true) ? _CMD_DTLB | _CMD_USR : _CMD_DTLB;
+	break;	
+
+    case CMD_DATA_UNC:
+        p_vci_ini_rw.cmdval  = true;
+        p_vci_ini_rw.address = r_dcache_paddr_save.read() & ~0x3;
+        p_vci_ini_rw.trdid   = 0; // data cache uncached read
+        p_vci_ini_rw.plen    = 4;
+        p_vci_ini_rw.eop     = true;
+        p_vci_ini_rw.pktid   = (r_dreq_isUser_save == true) ? _CMD_USR : 0;
+        switch(r_dcache_type_save) {
+        case iss_t::DATA_READ:
+            p_vci_ini_rw.wdata = 0;
+            p_vci_ini_rw.be    = r_dcache_be_save.read();
+            p_vci_ini_rw.cmd   = vci_param::CMD_READ;
+            break;
+        case iss_t::DATA_LL:
+            p_vci_ini_rw.wdata = 0;
+            p_vci_ini_rw.be    = 0xF;
+            p_vci_ini_rw.cmd   = vci_param::CMD_LOCKED_READ;
+            break;
+        case iss_t::DATA_SC:
+            p_vci_ini_rw.wdata = r_dcache_wdata_save.read();
+            p_vci_ini_rw.be    = 0xF;
+            p_vci_ini_rw.cmd   = vci_param::CMD_STORE_COND;
+            break;
+        default:
+            assert("this should not happen");
+        }
+        break;
+
+    case CMD_DATA_WRITE:
+        p_vci_ini_rw.cmdval  = true;
+        p_vci_ini_rw.address = r_wbuf.getAddress(r_vci_cmd_cpt);
+        p_vci_ini_rw.wdata   = r_wbuf.getData(r_vci_cmd_cpt);
+        p_vci_ini_rw.be      = r_wbuf.getBe(r_vci_cmd_cpt);
+        p_vci_ini_rw.trdid   = 0; // data cache write
+        p_vci_ini_rw.plen    = (r_vci_cmd_max - r_vci_cmd_min + 1)<<2;
+        p_vci_ini_rw.cmd     = vci_param::CMD_WRITE;
+        p_vci_ini_rw.eop     = (r_vci_cmd_cpt == r_vci_cmd_max);
+        p_vci_ini_rw.pktid   = (r_dreq_isUser_save == true) ? _CMD_USR : 0;
+        break;
+
+    case CMD_DATA_MISS:
+        p_vci_ini_rw.cmdval  = true;
+        p_vci_ini_rw.address = r_dcache_paddr_save.read() & m_dcache_yzmask;
+        p_vci_ini_rw.wdata   = 0;
+        p_vci_ini_rw.be      = 0xF;
+        p_vci_ini_rw.trdid   = 1; // data cache cached read
+        p_vci_ini_rw.plen    = m_dcache_words << 2;
+        p_vci_ini_rw.cmd     = vci_param::CMD_READ;
+        p_vci_ini_rw.eop     = true;
+        p_vci_ini_rw.pktid   = (r_dreq_isUser_save == true) ? _CMD_USR : 0;
+        break;
+    } // end switch r_vci_cmd_fsm
+
+    p_vci_ini_c.rspack = true;
+
+    switch (r_cleanup_cmd_fsm) {
+
+    case CLEANUP_CMD_IDLE:
+        p_vci_ini_c.cmdval  = false;
+        p_vci_ini_c.address = 0;
+        p_vci_ini_c.trdid   = 0; 
+        p_vci_ini_c.wdata   = 0;
+        p_vci_ini_c.be      = 0;
+        p_vci_ini_c.plen    = 0;
+        p_vci_ini_c.cmd     = vci_param::CMD_NOP;
+        p_vci_ini_c.pktid   = 0;
+        p_vci_ini_c.srcid   = m_srcid_c;
+        p_vci_ini_c.cons    = false;
+        p_vci_ini_c.wrap    = false;
+        p_vci_ini_c.contig  = false;
+        p_vci_ini_c.clen    = 0;
+        p_vci_ini_c.cfixed  = false;
+        p_vci_ini_c.eop     = false;
+        break;
+
+    case CLEANUP_CMD_DATA:
+        p_vci_ini_c.cmdval  = true;
+        p_vci_ini_c.address = r_dcache_cleanup_line.read() * (m_dcache_words<<2);
+        p_vci_ini_c.trdid  = 0; // data cleanup 
+        p_vci_ini_c.wdata  = 0;
+        p_vci_ini_c.be     = 0;
+        p_vci_ini_c.plen   = 4;
+        p_vci_ini_c.cmd    = vci_param::CMD_WRITE;
+        p_vci_ini_c.pktid  = 0;
+        p_vci_ini_c.srcid  = m_srcid_c;
+        p_vci_ini_c.cons   = false;
+        p_vci_ini_c.wrap   = false;
+        p_vci_ini_c.contig = false;
+        p_vci_ini_c.clen   = 0;
+        p_vci_ini_c.cfixed = false;
+        p_vci_ini_c.eop    = true;
+        break;
+
+    case CLEANUP_CMD_INS:
+        p_vci_ini_c.cmdval  = true;
+        p_vci_ini_c.address = r_icache_cleanup_line.read() * (m_icache_words<<2);
+        p_vci_ini_c.trdid  = 1; // ins cleanup 
+        p_vci_ini_c.wdata  = 0;
+        p_vci_ini_c.be     = 0;
+        p_vci_ini_c.plen   = 4;
+        p_vci_ini_c.cmd    = vci_param::CMD_WRITE;
+        p_vci_ini_c.pktid  = 0;
+        p_vci_ini_c.srcid  = m_srcid_c;
+        p_vci_ini_c.cons   = false;
+        p_vci_ini_c.wrap   = false;
+        p_vci_ini_c.contig = false;
+        p_vci_ini_c.clen   = 0;
+        p_vci_ini_c.cfixed = false;
+        p_vci_ini_c.eop    = true;
+        break;
+      } // end switch r_vci_cmd_cleanup_fsm
+
+    // VCI_TGT
+    switch ( r_vci_tgt_fsm.read() ) {
+
+    case TGT_IDLE:
+    case TGT_UPDT_WORD:
+    case TGT_UPDT_DATA:
+        p_vci_tgt.cmdack  = true;
+        p_vci_tgt.rspval  = false;
+        break;
+
+    case TGT_RSP_BROADCAST:
+        p_vci_tgt.cmdack  = false;
+        p_vci_tgt.rspval  = !r_tgt_icache_req.read() && !r_tgt_dcache_req.read() && ( r_tgt_icache_rsp | r_tgt_dcache_rsp );
+        p_vci_tgt.rsrcid  = r_tgt_srcid.read();
+        p_vci_tgt.rpktid  = r_tgt_pktid.read();
+        p_vci_tgt.rtrdid  = r_tgt_trdid.read();
+        p_vci_tgt.rdata   = 0;
+        p_vci_tgt.rerror  = 0;
+        p_vci_tgt.reop    = true;
+        break;
+
+    case TGT_RSP_ICACHE:
+        p_vci_tgt.cmdack  = false;
+        p_vci_tgt.rspval  = !r_tgt_icache_req.read() && r_tgt_icache_rsp.read();
+        p_vci_tgt.rsrcid  = r_tgt_srcid.read();
+        p_vci_tgt.rpktid  = r_tgt_pktid.read();
+        p_vci_tgt.rtrdid  = r_tgt_trdid.read();
+        p_vci_tgt.rdata   = 0;
+        p_vci_tgt.rerror  = 0;
+        p_vci_tgt.reop    = true;
+        break;
+
+    case TGT_RSP_DCACHE:
+        p_vci_tgt.cmdack  = false;
+        p_vci_tgt.rspval  = !r_tgt_dcache_req.read() && r_tgt_dcache_rsp.read();
+        p_vci_tgt.rsrcid  = r_tgt_srcid.read();
+        p_vci_tgt.rpktid  = r_tgt_pktid.read();
+        p_vci_tgt.rtrdid  = r_tgt_trdid.read();
+        p_vci_tgt.rdata   = 0;
+        p_vci_tgt.rerror  = 0;
+        p_vci_tgt.reop    = true;
+        break;
+
+    case TGT_REQ_BROADCAST:
+    case TGT_REQ_ICACHE:
+    case TGT_REQ_DCACHE:
+        p_vci_tgt.cmdack  = false;
+        p_vci_tgt.rspval  = false;
+        break;
+
+    } // end switch TGT_FSM
+
+#ifdef SOCLIB_MODULE_DEBUG
+   std::cout << name() 
+      	     << " Moore R/W:" << std::hex
+      	     << " p_vci_ini_rw.cmdval: " << p_vci_ini_rw.cmdval
+      	     << " p_vci_ini_rw.address: " << p_vci_ini_rw.address
+      	     << " p_vci_ini_rw.srcid: " << p_vci_ini_rw.srcid
+      	     << " p_vci_ini_rw.wdata: " << p_vci_ini_rw.wdata
+      	     << " p_vci_ini_rw.cmd: " << p_vci_ini_rw.cmd
+      	     << " p_vci_ini_rw.eop: " << p_vci_ini_rw.eop
+      	     << std::endl;
+
+   std::cout << name() 
+      	     << " Moore TGT:" << std::hex
+      	     << " p_vci_tgt.rspval: " << p_vci_tgt.rspval
+      	     << std::endl;
+
+   std::cout << name() 
+      	     << " Moore Cleanup:" << std::hex
+      	     << " p_vci_ini_c.cmdval: " << p_vci_ini_c.cmdval
+      	     << " p_vci_ini_c.address: " << p_vci_ini_c.address
+      	     << " p_vci_ini_c.trdid: " << p_vci_ini_c.trdid
+      	     << " p_vci_ini_c.cmd: " << p_vci_ini_c.cmd
+      	     << " p_vci_ini_c.eop: " << p_vci_ini_c.eop
+      	     << std::endl;
+#endif
+}
+
+}}
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
+
+
+
+
+
+
+
+
+
Index: trunk/platforms/almos-tsarv3-platforms/common/vci_dma_tsar_v2/caba/metadata/vci_dma_tsar_v2.sd
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/vci_dma_tsar_v2/caba/metadata/vci_dma_tsar_v2.sd	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/vci_dma_tsar_v2/caba/metadata/vci_dma_tsar_v2.sd	(revision 259)
@@ -0,0 +1,43 @@
+
+# -*- python -*-
+
+__id__ = "$Id: vci_dma_tsar_v2.sd 20 2010-04-14 03:27:59Z nipo $"
+__version__ = "$Revision: 20 $"
+
+Module('caba:vci_dma_tsar_v2',
+	classname = 'soclib::caba::VciDmaTsarV2',
+	   tmpl_parameters = [
+	parameter.Module('vci_param',  default = 'caba:vci_param'),
+	],
+	header_files = ['../source/include/vci_dma_tsar_v2.h',
+					],
+    interface_files = [
+					'../../include/soclib/dma_tsar_v2.h',
+					],
+	implementation_files = ['../source/src/vci_dma_tsar_v2.cpp',],
+			  ports = [
+	Port('caba:vci_target', 'p_vci_target'),
+	Port('caba:vci_initiator', 'p_vci_initiator'),
+	Port('caba:bit_out', 'p_irq'),
+	Port('caba:bit_in', 'p_resetn', auto = 'resetn'),
+	Port('caba:clock_in', 'p_clk', auto = 'clock'),
+	],
+	uses = [
+		Uses('caba:base_module'),
+		Uses('caba:vci_target_fsm', default_target = 'true', support_llsc = 'false'),
+		Uses('caba:vci_initiator_simple_read_req'),
+		Uses('caba:vci_initiator_simple_write_req'),
+		Uses('caba:vci_initiator_fsm'),
+		],
+	instance_parameters = [
+        parameter.Module('mt', typename = 'common:mapping_table', auto = 'env:mapping_table'),
+		parameter.IntTab('srcid'),
+		parameter.IntTab('tgtid'),
+        parameter.Int('burst_size'),
+	],
+	   extensions = [
+	'dsx:addressable=tgtid',
+	'dsx:max_segments=1',
+	'dsx:get_ident=tgtid:p_vci_target:mt,srcid:p_vci_initiator:mt',
+   ],
+)
Index: trunk/platforms/almos-tsarv3-platforms/common/vci_dma_tsar_v2/caba/source/include/vci_dma_tsar_v2.h
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/vci_dma_tsar_v2/caba/source/include/vci_dma_tsar_v2.h	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/vci_dma_tsar_v2/caba/source/include/vci_dma_tsar_v2.h	(revision 259)
@@ -0,0 +1,106 @@
+/* -*- c++ -*-
+ *
+ * SOCLIB_LGPL_HEADER_BEGIN
+ * 
+ * This file is part of SoCLib, GNU LGPLv2.1.
+ * 
+ * SoCLib is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 of the License.
+ * 
+ * SoCLib is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with SoCLib; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ * 
+ * SOCLIB_LGPL_HEADER_END
+ *
+ * Copyright (c) UPMC, Lip6, Asim
+ *         Nicolas Pouillon <nipo@ssji.net>, 2007
+ *
+ * Maintainers: nipo
+ */
+#ifndef SOCLIB_VCI_DMA_TSAR_V2_H
+#define SOCLIB_VCI_DMA_TSAR_V2_H
+
+#include <stdint.h>
+#include <systemc>
+#include "vci_target_fsm.h"
+#include "vci_initiator_fsm.h"
+#include "caba_base_module.h"
+#include "mapping_table.h"
+
+namespace soclib {
+namespace caba {
+
+using namespace sc_core;
+
+template<typename vci_param>
+class VciDmaTsarV2
+	: public caba::BaseModule
+{
+private:
+    soclib::caba::VciTargetFsm<vci_param, true> m_vci_target_fsm;
+    soclib::caba::VciInitiatorFsm<vci_param> m_vci_init_fsm;
+    typedef typename soclib::caba::VciInitiatorReq<vci_param> req_t;
+
+    bool on_write(int seg, typename vci_param::addr_t addr, typename vci_param::data_t data, int be);
+    bool on_read(int seg, typename vci_param::addr_t addr, typename vci_param::data_t &data);
+    void read_done( req_t *req );
+    void write_finish( req_t *req );
+    void transition();
+    void genMoore();
+
+	uint32_t m_src;
+	uint32_t m_dst;
+	uint32_t m_len;
+	uint32_t m_offset;
+    uint32_t m_offset_buffer;
+    bool m_partial;
+    bool m_must_finish;
+	bool m_irq_enabled;
+	bool r_irq;
+
+	std::vector<uint8_t> m_data;
+
+	bool m_handling;
+
+	void next_req();
+	void ended();
+
+protected:
+    SC_HAS_PROCESS(VciDmaTsarV2);
+
+public:
+    sc_in<bool> p_clk;
+    sc_in<bool> p_resetn;
+    soclib::caba::VciTarget<vci_param> p_vci_target;
+    soclib::caba::VciInitiator<vci_param> p_vci_initiator;
+    sc_out<bool> p_irq;
+
+	VciDmaTsarV2(
+		sc_module_name name,
+		const soclib::common::MappingTable &mt,
+		const soclib::common::IntTab &srcid,
+		const soclib::common::IntTab &tgtid,
+		const size_t burst_size );
+};
+
+}}
+
+#endif /* SOCLIB_VCI_DMA_TSAR_V2_H */
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: trunk/platforms/almos-tsarv3-platforms/common/vci_dma_tsar_v2/caba/source/src/vci_dma_tsar_v2.cpp
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/vci_dma_tsar_v2/caba/source/src/vci_dma_tsar_v2.cpp	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/vci_dma_tsar_v2/caba/source/src/vci_dma_tsar_v2.cpp	(revision 259)
@@ -0,0 +1,246 @@
+/* -*- c++ -*-
+ *
+ * SOCLIB_LGPL_HEADER_BEGIN
+ * 
+ * This file is part of SoCLib, GNU LGPLv2.1.
+ * 
+ * SoCLib is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 of the License.
+ * 
+ * SoCLib is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with SoCLib; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ * 
+ * SOCLIB_LGPL_HEADER_END
+ *
+ * Copyright (c) UPMC, Lip6, Asim
+ *         Nicolas Pouillon <nipo@ssji.net>, 2007
+ */
+
+#include <stdint.h>
+#include "register.h"
+#include "../include/vci_dma_tsar_v2.h"
+#include "dma_tsar_v2.h"
+
+namespace soclib { namespace caba {
+
+#define tmpl(t) template<typename vci_param> t VciDmaTsarV2<vci_param>
+
+tmpl(bool)::on_write(int seg, typename vci_param::addr_t addr, typename vci_param::data_t data, int be)
+{
+    int cell = (int)addr / vci_param::B;
+
+	switch ((enum SoclibDmaRegisters)cell) {
+	case DMA_SRC:
+		m_src = data;
+		return true;
+    case DMA_DST:
+		m_dst = data;
+		return true;
+    case DMA_LEN:
+		m_len = data;
+		return true;
+    case DMA_RESET:
+        m_must_finish = true;
+        m_irq_enabled = false;
+		r_irq = false;
+        return true;
+    case DMA_IRQ_DISABLED:
+		m_irq_enabled = !data;
+		return true;
+	};
+	return false;
+}
+
+tmpl(void)::ended()
+{
+	if ( m_irq_enabled )
+		r_irq = true;
+	m_len = 0;
+    m_must_finish = false;
+	m_handling = false;
+}
+
+tmpl(bool)::on_read(int seg, typename vci_param::addr_t addr, typename vci_param::data_t &data)
+{
+    int cell = (int)addr / vci_param::B;
+
+	switch ((enum SoclibDmaRegisters)cell) {
+	case DMA_SRC:
+		data = m_src;
+		return true;
+    case DMA_DST:
+		data = m_dst;
+		return true;
+	case DMA_LEN:
+		data = m_len;
+		return true;
+    default:
+        return false;
+	}
+	return false;
+}
+
+tmpl(void)::read_done( req_t *req )
+{
+	if ( !req->failed() && !m_must_finish ) {
+		ssize_t burst = m_offset_buffer;
+
+        m_partial = false;
+        if( (( m_dst+m_offset ) & ~( m_data.size()-1 )) !=
+            (( m_dst+m_offset+m_offset_buffer-1 ) & ~( m_data.size()-1 )) ){
+            burst = (((m_dst+m_offset) & ~( m_data.size()-1))+m_data.size()) - (m_dst+m_offset);
+            m_partial = true;
+        }
+		VciInitSimpleWriteReq<vci_param> *new_req =
+			new VciInitSimpleWriteReq<vci_param>( m_dst+m_offset, &m_data[0], burst );
+		new_req->setDone( this, ON_T(write_finish) );
+		m_vci_init_fsm.doReq( new_req );
+	} else {
+		ended();
+	}
+	delete req;
+}
+
+tmpl(void)::write_finish( req_t *req )
+{
+    ssize_t burst = 0;
+    uint32_t offset = 0;
+    if( m_partial ){
+        burst = m_dst + m_offset + m_offset_buffer - ((m_dst+m_offset+m_offset_buffer) & ~( m_data.size()-1));
+        offset = m_offset_buffer - burst ;
+    } else {
+	    m_offset += m_offset_buffer;
+    }
+	if ( !req->failed() && !m_must_finish ){
+        if(m_partial){
+            VciInitSimpleWriteReq<vci_param> *new_req =
+                new VciInitSimpleWriteReq<vci_param>( m_dst+m_offset+offset, &m_data[offset], burst );
+            new_req->setDone( this, ON_T(write_finish) );
+            m_partial = false;
+            m_vci_init_fsm.doReq( new_req );
+            delete req;
+            return;
+        }
+		next_req();
+    }
+	else {
+		ended();
+	}
+	delete req;
+}
+
+tmpl(void)::next_req()
+{
+	ssize_t remaining = (ssize_t)m_len-(size_t)m_offset;
+	if ( remaining <= 0 ) {
+		ended();
+		return;
+	}
+
+	ssize_t burst = m_data.size();
+    m_partial = false;
+    if ( ( m_src+m_offset ) & ( m_data.size()-1 ) ){
+        burst = m_data.size() - ( (m_src+m_offset) & (m_data.size()-1) );
+        m_partial = true;
+    }
+	if ( remaining < burst ){
+		burst = remaining;
+        m_partial = true;
+    }
+
+    m_offset_buffer = burst;
+
+	VciInitSimpleReadReq<vci_param> *req =
+		new VciInitSimpleReadReq<vci_param>(
+			&m_data[0], (m_src+m_offset), burst );
+	req->setDone( this, ON_T(read_done) );
+	m_vci_init_fsm.doReq( req );
+}
+
+tmpl(void)::transition()
+{
+	if (!p_resetn) {
+		m_vci_target_fsm.reset();
+		m_vci_init_fsm.reset();
+		r_irq = false;
+		m_irq_enabled = false;
+		m_len = 0;
+        m_offset_buffer = 0;
+		m_handling = false;
+        m_must_finish = false;
+		return;
+	}
+
+
+	if ( m_len && !m_handling ) {
+		m_handling = true;
+		m_offset = 0;
+
+		next_req();
+	}
+    
+    if( !m_handling )
+        m_must_finish = false;
+
+	m_vci_target_fsm.transition();
+	m_vci_init_fsm.transition();
+}
+
+tmpl(void)::genMoore()
+{
+	m_vci_target_fsm.genMoore();
+	m_vci_init_fsm.genMoore();
+
+	p_irq = r_irq && m_irq_enabled;
+}
+
+tmpl(/**/)::VciDmaTsarV2(
+    sc_module_name name,
+    const MappingTable &mt,
+    const IntTab &srcid,
+    const IntTab &tgtid,
+	const size_t burst_size )
+	: caba::BaseModule(name),
+	  m_vci_target_fsm(p_vci_target, mt.getSegmentList(tgtid)),
+	  m_vci_init_fsm(p_vci_initiator, mt.indexForId(srcid)),
+	  m_len(0),
+	  m_data(burst_size, (uint8_t)0),
+      p_clk("clk"),
+      p_resetn("resetn"),
+      p_vci_target("vci_target"),
+      p_vci_initiator("vci_initiator"),
+      p_irq("irq")
+{
+	m_vci_target_fsm.on_read_write(on_read, on_write);
+    
+    assert(burst_size && "Useless DMA with no buffer");
+    assert(burst_size < (1<<vci_param::K) && "I will be unable to create requests that big");
+
+	SC_METHOD(transition);
+	dont_initialize();
+	sensitive << p_clk.pos();
+
+	SC_METHOD(genMoore);
+	dont_initialize();
+	sensitive << p_clk.neg();
+}
+
+}}
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: trunk/platforms/almos-tsarv3-platforms/common/vci_dma_tsar_v2/include/soclib/dma_tsar_v2.h
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/vci_dma_tsar_v2/include/soclib/dma_tsar_v2.h	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/vci_dma_tsar_v2/include/soclib/dma_tsar_v2.h	(revision 259)
@@ -0,0 +1,49 @@
+/*
+ * SOCLIB_LGPL_HEADER_BEGIN
+ * 
+ * This file is part of SoCLib, GNU LGPLv2.1.
+ * 
+ * SoCLib is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 of the License.
+ * 
+ * SoCLib is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with SoCLib; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ * 
+ * SOCLIB_LGPL_HEADER_END
+ *
+ * Copyright (c) UPMC, Lip6, Asim
+ *         Nicolas Pouillon <nipo@ssji.net>, 2007
+ *         Eric Guthmuller  <eric.guthmuller@polytechnique.edu>, 2009
+ *
+ * Maintainers: nipo eric.guthmuller@polytechnique.edu
+ */
+#ifndef DMA_REGS_TSAR_V2_H
+#define DMA_REGS_TSAR_V2_H
+
+enum SoclibDmaRegisters {
+    DMA_SRC,
+    DMA_DST,
+    DMA_LEN,
+    DMA_RESET,
+    DMA_IRQ_DISABLED,
+};
+
+#endif /* DMA_REGS_TSAR_V2_H */
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: trunk/platforms/almos-tsarv3-platforms/common/vci_mem_cache_v3/caba/metadata/vci_mem_cache_v3.sd
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/vci_mem_cache_v3/caba/metadata/vci_mem_cache_v3.sd	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/vci_mem_cache_v3/caba/metadata/vci_mem_cache_v3.sd	(revision 259)
@@ -0,0 +1,49 @@
+
+# -*- python -*-
+
+__id__ = "$Id: vci_mem_cache_v3.sd 20 2010-04-14 03:27:59Z nipo $"
+__version__ = "$Revision: 20 $"
+
+Module('caba:vci_mem_cache_v3',
+       classname = 'soclib::caba::VciMemCacheV3',
+       tmpl_parameters = [parameter.Module('vci_param', default = 'caba:vci_param'),],
+       header_files = ['../source/include/vci_mem_cache_v3.h',
+                       '../source/include/xram_transaction_v3.h',
+                       '../source/include/mem_cache_directory_v3.h',
+                       '../source/include/atomic_tab_v3.h',
+                       '../source/include/update_tab_v3.h',],
+       implementation_files = ['../source/src/vci_mem_cache_v3.cpp',],
+       uses = [Uses('caba:base_module'),
+               Uses('common:loader'),
+               Uses('common:mapping_table'),
+               Uses('caba:generic_fifo'),
+               Uses('config:config'),
+               ],
+       ports = [Port('caba:vci_target', 'p_vci_tgt'),
+		Port('caba:vci_target','p_vci_tgt_cleanup'),
+		Port('caba:vci_initiator','p_vci_ini'),
+		Port('caba:vci_initiator','p_vci_ixr'),
+                Port('caba:bit_in', 'p_resetn', auto = 'resetn'),
+                Port('caba:clock_in', 'p_clk', auto = 'clock'),],
+       instance_parameters = [
+		parameter.Module('mtp', 'common:mapping_table'),
+		parameter.Module('mtc', 'common:mapping_table'),
+		parameter.Module('mtx', 'common:mapping_table'),
+		parameter.IntTab('vci_ixr_index'),
+		parameter.IntTab('vci_ini_index'),
+		parameter.IntTab('vci_tgt_index'),
+		parameter.IntTab('vci_tgt_index_cleanup'),
+    parameter.Int('nways'),
+		parameter.Int('nsets'),
+		parameter.Int('nwords'),
+		parameter.Int('heap_size'),
+		],
+       extensions = [
+          'dsx:get_ident='
+          'vci_ini_index:p_vci_ini:mtc,'
+          'vci_tgt_index_cleanup:p_vci_tgt_cleanup:mtc,'
+          'vci_tgt_index:p_vci_tgt:mtp,'
+          'vci_ixr_index:p_vci_ixr:mtx',
+		'dsx:addressable=vci_tgt_index,vci_tgt_index_cleanup',
+       ],
+)
Index: trunk/platforms/almos-tsarv3-platforms/common/vci_mem_cache_v3/caba/source/include/atomic_tab_v3.h
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/vci_mem_cache_v3/caba/source/include/atomic_tab_v3.h	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/vci_mem_cache_v3/caba/source/include/atomic_tab_v3.h	(revision 259)
@@ -0,0 +1,121 @@
+#ifndef ATOMIC_TAB_V3_H_
+#define ATOMIC_TAB_V3_H_
+
+#include <inttypes.h>
+#include <systemc>
+#include <cassert>
+#include "arithmetics.h"
+
+
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+/*                  The atomic access tab                             */
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+
+class AtomicTab{
+    typedef uint32_t size_t;
+    typedef sc_dt::sc_uint<40> addr_t;
+
+private:
+    size_t size_tab;                            // The size of the tab
+    std::vector<addr_t> addr_tab;               // Address entries
+    std::vector<bool>   valid_tab;              // Valid entries
+
+public:
+
+    AtomicTab()
+	: addr_tab(0),
+	  valid_tab(0)
+	{
+    	size_tab=0;
+    }
+
+    AtomicTab(size_t size_tab_i)
+	: addr_tab(size_tab_i),
+	  valid_tab(size_tab_i)
+	{
+	    size_tab=size_tab_i;
+    }
+
+
+    /////////////////////////////////////////////////////////////////////
+    /* The size() function returns the size of the tab */
+    /////////////////////////////////////////////////////////////////////
+    const size_t size(){
+	    return size_tab;
+    }
+
+
+    /////////////////////////////////////////////////////////////////////
+    /* The init() function initializes the transaction tab entries */
+    /////////////////////////////////////////////////////////////////////
+    void init(){
+    	for ( size_t i=0; i<size_tab; i++) {
+		    addr_tab[i]=0;
+		    valid_tab[i]=false;
+    	}
+    }
+
+
+    /////////////////////////////////////////////////////////////////////
+    /* The set() function sets an entry 
+       Arguments :
+       - id : the id of the initiator (index of the entry)
+       - addr : the address of the lock
+     */
+    /////////////////////////////////////////////////////////////////////
+    void set(const size_t id, const addr_t addr){
+	    assert( (id<size_tab) && "Atomic Tab Error : bad entry");
+	    addr_tab[id]=addr;
+	    valid_tab[id]=true;
+	    return;
+    }
+
+
+    /////////////////////////////////////////////////////////////////////
+    /* The isatomic() function tests if the SC request corresponds to an entry
+       Arguments :
+       - id : the id of the initiator (index of the entry)
+       - addr : the address of the lock
+
+       This function return true if the request corresponds
+     */
+    /////////////////////////////////////////////////////////////////////
+    bool isatomic(const size_t id, const addr_t addr){
+	    assert( (id<size_tab) && "Atomic Tab Error : bad entry");
+	    bool test=valid_tab[id];
+	    test=test && (addr == addr_tab[id]);
+	    return test;
+    }
+
+
+    /////////////////////////////////////////////////////////////////////
+    /* The reset() function resets all the entries for this lock
+       Arguments :
+       - addr : the address of the lock
+     */
+    /////////////////////////////////////////////////////////////////////
+    void reset(const addr_t addr){
+	    for(size_t i=0 ; i<size_tab ; i++){
+		    if(addr == addr_tab[i]){
+			    valid_tab[i]=false;
+		    }
+	    }
+	    return;
+    }
+
+};
+ 
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: trunk/platforms/almos-tsarv3-platforms/common/vci_mem_cache_v3/caba/source/include/mem_cache_directory_v3.h
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/vci_mem_cache_v3/caba/source/include/mem_cache_directory_v3.h	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/vci_mem_cache_v3/caba/source/include/mem_cache_directory_v3.h	(revision 259)
@@ -0,0 +1,562 @@
+#ifndef SOCLIB_CABA_MEM_CACHE_DIRECTORY_V3_H
+#define SOCLIB_CABA_MEM_CACHE_DIRECTORY_V3_H 
+
+#include <inttypes.h>
+#include <systemc>
+#include <cassert>
+#include "arithmetics.h"
+
+namespace soclib { namespace caba {
+
+  using namespace sc_core;
+
+  ////////////////////////////////////////////////////////////////////////
+  //                    A LRU entry 
+  ////////////////////////////////////////////////////////////////////////
+  class LruEntry {
+
+    public:
+
+      bool recent;            
+
+      void init()
+      {
+        recent=false;
+      }
+
+  }; // end class LruEntry
+
+  ////////////////////////////////////////////////////////////////////////
+  //                    An Owner
+  ////////////////////////////////////////////////////////////////////////
+  class Owner{
+    typedef uint32_t size_t;
+    
+    public:
+    // Fields
+      bool      inst;       // Is the owner an ICache ?
+      size_t    srcid;      // The SRCID of the owner
+
+    ////////////////////////
+    // Constructors
+    ////////////////////////
+      Owner(bool i_inst,size_t i_srcid){
+        inst    = i_inst;
+        srcid   = i_srcid;
+      }
+
+      Owner(const Owner &a){
+        inst    = a.inst;
+        srcid   = a.srcid;
+      }
+
+      Owner(){
+        inst    = false;
+        srcid   = 0;
+      }
+      // end constructors
+
+  }; // end class Owner
+
+
+  ////////////////////////////////////////////////////////////////////////
+  //                    A directory entry                               
+  ////////////////////////////////////////////////////////////////////////
+  class DirectoryEntry {
+
+    typedef uint32_t tag_t;
+    typedef uint32_t size_t;
+
+    public:
+
+    bool    valid;                  // entry valid
+    bool    is_cnt;                 // directory entry is in counter mode
+    bool    dirty;                  // entry dirty
+    bool    lock;                   // entry locked
+    bool    inst;                   // at least one ICache owner
+    tag_t   tag;                    // tag of the entry
+    size_t  count;                  // number of copies
+    Owner   owner;                  // an owner of the line 
+    size_t  ptr;                    // pointer to the next owner
+
+    DirectoryEntry()
+    {
+      valid         = false;
+      is_cnt        = false;
+      dirty         = false;
+      lock          = false;
+      inst          = false;
+      tag           = 0;
+      count         = 0;
+      owner.inst    = 0;
+      owner.srcid   = 0;
+      ptr           = 0;
+    }
+
+    DirectoryEntry(const DirectoryEntry &source)
+    {
+      valid         = source.valid;
+      is_cnt        = source.is_cnt;
+      dirty         = source.dirty;
+      lock          = source.lock;
+      inst          = source.inst;
+      tag           = source.tag;
+      count         = source.count;
+      owner         = source.owner;
+      ptr           = source.ptr;
+    }          
+
+    /////////////////////////////////////////////////////////////////////
+    // The init() function initializes the entry 
+    /////////////////////////////////////////////////////////////////////
+    void init()
+    {
+      valid     = false;
+      is_cnt    = false;
+      dirty     = false;
+      lock      = false;
+      inst      = false;
+      count     = 0;
+    }
+
+    /////////////////////////////////////////////////////////////////////
+    // The copy() function copies an existing source entry to a target 
+    /////////////////////////////////////////////////////////////////////
+    void copy(const DirectoryEntry &source)
+    {
+      valid	    = source.valid;
+      is_cnt    = source.is_cnt;
+      dirty	    = source.dirty;
+      lock	    = source.lock;
+      inst      = source.inst;
+      tag	    = source.tag;
+      count     = source.count;
+      owner     = source.owner;
+      ptr       = source.ptr;
+    }
+
+    ////////////////////////////////////////////////////////////////////
+    // The print() function prints the entry 
+    ////////////////////////////////////////////////////////////////////
+    void print(std::ostream &output)
+    {
+        output << "Valid = " << valid 
+                  << " ; IS COUNT = " << is_cnt 
+                  << " ; Dirty = " << dirty 
+                  << " ; Lock = "  << lock 
+                  << " ; Inst = " << inst 
+                  << " ; Tag = " << std::hex << tag 
+                  << std::dec << " ; Count = " << count 
+                  << " ; Owner = " << owner.srcid << " " 
+                  << owner.inst << " ; Pointer = " << ptr << std::endl;
+    }
+
+  }; // end class DirectoryEntry
+
+  ////////////////////////////////////////////////////////////////////////
+  //                       The directory  
+  ////////////////////////////////////////////////////////////////////////
+  class CacheDirectory {
+
+    typedef sc_dt::sc_uint<40> addr_t;
+    typedef uint32_t data_t;
+    typedef uint32_t tag_t;
+    typedef uint32_t size_t;
+
+    private:
+
+    // Directory constants
+    size_t					m_ways;
+    size_t					m_sets;
+    size_t					m_words;
+    size_t					m_width;
+
+    // the directory & lru tables
+    DirectoryEntry 				**m_dir_tab;
+    LruEntry	 				**m_lru_tab;
+
+    public:
+
+    ////////////////////////
+    // Constructor
+    ////////////////////////
+    CacheDirectory( size_t ways, size_t sets, size_t words, size_t address_width)	 
+    {
+      m_ways  = ways; 
+      m_sets  = sets;
+      m_words = words;
+      m_width = address_width;
+
+      m_dir_tab = new DirectoryEntry*[sets];
+      for ( size_t i=0; i<sets; i++ ) {
+        m_dir_tab[i] = new DirectoryEntry[ways];
+        for ( size_t j=0 ; j<ways ; j++) m_dir_tab[i][j].init();
+      }
+      m_lru_tab = new LruEntry*[sets];
+      for ( size_t i=0; i<sets; i++ ) {
+        m_lru_tab[i] = new LruEntry[ways];
+        for ( size_t j=0 ; j<ways ; j++) m_lru_tab[i][j].init();
+      }
+    } // end constructor
+
+    /////////////////
+    // Destructor
+    /////////////////
+    ~CacheDirectory()
+    {
+      for(size_t i=0 ; i<m_sets ; i++){
+        delete [] m_dir_tab[i];
+        delete [] m_lru_tab[i];
+      }
+      delete [] m_dir_tab;
+      delete [] m_lru_tab;
+    } // end destructor
+
+    /////////////////////////////////////////////////////////////////////
+    // The read() function reads a directory entry. In case of hit, the
+    // LRU is updated.
+    // Arguments :
+    // - address : the address of the entry 
+    // - way : (return argument) the way of the entry in case of hit
+    // The function returns a copy of a (valid or invalid) entry  
+    /////////////////////////////////////////////////////////////////////
+    DirectoryEntry read(const addr_t &address,size_t &way)
+    {
+
+#define L2 soclib::common::uint32_log2
+      const size_t set = (size_t)(address >> (L2(m_words) + 2)) & (m_sets - 1);
+      const tag_t  tag = (tag_t)(address >> (L2(m_sets) + L2(m_words) + 2));
+#undef L2
+
+      bool hit       = false;
+      for ( size_t i=0 ; i<m_ways ; i++ ) {
+        bool equal = ( m_dir_tab[set][i].tag == tag );
+        bool valid = m_dir_tab[set][i].valid;
+        hit = equal && valid;
+        if ( hit ) {			
+          way = i;
+          break;
+        } 
+      }
+      if ( hit ) {
+        m_lru_tab[set][way].recent = true;
+        return DirectoryEntry(m_dir_tab[set][way]);
+      } else {
+        return DirectoryEntry();
+      }
+    } // end read()
+
+    /////////////////////////////////////////////////////////////////////
+    // The write function writes a new entry, 
+    // and updates the LRU bits if necessary.
+    // Arguments :
+    // - set : the set of the entry
+    // - way : the way of the entry
+    // - entry : the entry value
+    /////////////////////////////////////////////////////////////////////
+    void write(const size_t &set, const size_t &way, const DirectoryEntry &entry)
+    {
+      assert( (set<m_sets) 
+          && "Cache Directory write : The set index is invalid");
+      assert( (way<m_ways) 
+          && "Cache Directory write : The way index is invalid");
+
+      // update Directory
+      m_dir_tab[set][way].copy(entry);
+
+      // update LRU bits
+      bool all_recent = true;
+      for ( size_t i=0 ; i<m_ways ; i++ ) {
+        if ( i != way ) all_recent = m_lru_tab[set][i].recent && all_recent;
+      }
+      if ( all_recent ) {
+        for( size_t i=0 ; i<m_ways ; i++ ) m_lru_tab[set][i].recent = false;
+      } else {
+        m_lru_tab[set][way].recent = true;
+      }
+    } // end write()
+
+    /////////////////////////////////////////////////////////////////////
+    // The print() function prints a selected directory entry
+    // Arguments :
+    // - set : the set of the entry to print
+    // - way : the way of the entry to print
+    /////////////////////////////////////////////////////////////////////
+    void print(const size_t &set, const size_t &way, std::ostream &output)
+    {
+      output << std::dec << " set : " << set << " ; way : " << way << " ; " ;
+      m_dir_tab[set][way].print(output);
+    } // end print()
+
+    /////////////////////////////////////////////////////////////////////
+    // The select() function selects a directory entry to evince.
+    // Arguments :
+    // - set   : (input argument) the set to modify
+    // - way   : (return argument) the way to evince
+    /////////////////////////////////////////////////////////////////////
+    DirectoryEntry select(const size_t &set, size_t &way)
+    {
+      assert( (set < m_sets) 
+          && "Cache Directory : (select) The set index is invalid");
+
+      for(size_t i=0; i<m_ways; i++){
+        if(!m_dir_tab[set][i].valid){
+          way=i;
+          return DirectoryEntry(m_dir_tab[set][way]);
+        }
+      }
+      for(size_t i=0; i<m_ways; i++){
+        if(!(m_lru_tab[set][i].recent) && !(m_dir_tab[set][i].lock)){
+          way=i;
+          return DirectoryEntry(m_dir_tab[set][way]);
+        }
+      }
+      for(size_t i=0; i<m_ways; i++){
+        if( !(m_lru_tab[set][i].recent) && (m_dir_tab[set][i].lock)){
+          way=i;
+          return DirectoryEntry(m_dir_tab[set][way]);
+        }
+      }
+      for(size_t i=0; i<m_ways; i++){
+        if( (m_lru_tab[set][i].recent) && !(m_dir_tab[set][i].lock)){
+          way=i;
+          return DirectoryEntry(m_dir_tab[set][way]);
+        }
+      }
+      way = 0;
+      return DirectoryEntry(m_dir_tab[set][0]);
+    } // end select()
+
+    /////////////////////////////////////////////////////////////////////
+    // 		Global initialisation function
+    /////////////////////////////////////////////////////////////////////
+    void init()
+    {
+      for ( size_t set=0 ; set<m_sets ; set++ ) {
+        for ( size_t way=0 ; way<m_ways ; way++ ) {
+          m_dir_tab[set][way].init();
+          m_lru_tab[set][way].init();
+        }
+      }
+    } // end init()
+
+  }; // end class CacheDirectory
+
+  ///////////////////////////////////////////////////////////////////////
+  //                    A Heap Entry
+  ///////////////////////////////////////////////////////////////////////
+  class HeapEntry{
+    typedef uint32_t size_t;
+
+    public:
+    // Fields of the entry
+      Owner     owner;
+      size_t    next;
+
+    ////////////////////////
+    // Constructor
+    ////////////////////////
+      HeapEntry()
+      :owner(false,0)
+      {
+        next = 0;
+      } // end constructor
+
+    ////////////////////////
+    // Constructor
+    ////////////////////////
+      HeapEntry(const HeapEntry &entry){
+        owner.srcid = entry.owner.srcid;
+        owner.inst  = entry.owner.inst;
+        next        = entry.next;
+      } // end constructor
+
+    /////////////////////////////////////////////////////////////////////
+    // The copy() function copies an existing source entry to a target 
+    /////////////////////////////////////////////////////////////////////
+      void copy(const HeapEntry &entry){
+        owner.srcid = entry.owner.srcid;
+        owner.inst  = entry.owner.inst;
+        next        = entry.next;
+      } // end copy()
+
+    ////////////////////////////////////////////////////////////////////
+    // The print() function prints the entry 
+    ////////////////////////////////////////////////////////////////////
+      void print(std::ostream &output){
+        output
+        << " -- owner.srcid : " << std::dec << owner.srcid << std::endl
+        << " -- owner.inst  : " << std::dec << owner.inst << std::endl
+        << " -- next        : " << std::dec << next << std::endl;
+
+      } // end print()
+
+  }; // end class HeapEntry
+
+  ////////////////////////////////////////////////////////////////////////
+  //                        The Heap 
+  ////////////////////////////////////////////////////////////////////////
+  class HeapDirectory{
+    typedef uint32_t size_t;
+    
+    private:
+    // Registers and the heap
+      size_t    ptr_free;
+      bool      full;
+      HeapEntry *m_heap_tab;
+
+    // Constants for debugging purpose
+      size_t    tab_size;
+
+    public:
+    ////////////////////////
+    // Constructor
+    ////////////////////////
+      HeapDirectory(uint32_t size){
+        assert(size>0 && "Memory Cache, HeapDirectory constructor : invalid size");
+        ptr_free    = 0;
+        full        = false;
+        m_heap_tab  = new HeapEntry[size];
+        tab_size    = size;
+      } // end constructor
+
+    /////////////////
+    // Destructor
+    /////////////////
+      ~HeapDirectory(){
+        delete [] m_heap_tab;
+      } // end destructor
+
+    /////////////////////////////////////////////////////////////////////
+    // 		Global initialisation function
+    /////////////////////////////////////////////////////////////////////
+      void init(){
+        ptr_free=0;
+        full=false;
+        for(size_t i=0; i< tab_size-1;i++){
+          m_heap_tab[i].next = i+1;
+        }
+        m_heap_tab[tab_size-1].next = tab_size-1;
+        return;
+      }
+
+    /////////////////////////////////////////////////////////////////////
+    // The print() function prints a selected directory entry
+    // Arguments :
+    // - ptr : the pointer to the entry to print
+    /////////////////////////////////////////////////////////////////////
+      void print(const size_t &ptr, std::ostream &output){
+        output << "Heap, printing the entry : " << std::dec << ptr << std::endl;
+        m_heap_tab[ptr].print(output);
+      } // end print()
+
+    /////////////////////////////////////////////////////////////////////
+    // The print_list() function prints a list from selected directory entry
+    // Arguments :
+    // - ptr : the pointer to the first entry to print
+    /////////////////////////////////////////////////////////////////////
+      void print_list(const size_t &ptr, std::ostream &output){
+        bool end = false;
+        size_t ptr_temp = ptr;
+        output << "Heap, printing the list from : " << std::dec << ptr << std::endl;
+        while(!end){
+            m_heap_tab[ptr_temp].print(output);
+            if(ptr_temp == m_heap_tab[ptr_temp].next) end = true;
+            ptr_temp = m_heap_tab[ptr_temp].next;
+        } 
+      } // end print_list()
+
+
+    /////////////////////////////////////////////////////////////////////
+    // The is_full() function return true if the heap is full.
+    /////////////////////////////////////////////////////////////////////
+      bool is_full(){
+        return full;
+      } // end is_full()
+
+    /////////////////////////////////////////////////////////////////////
+    // The next_free_ptr() function returns the pointer 
+    // to the next free entry.
+    /////////////////////////////////////////////////////////////////////
+      size_t next_free_ptr(){
+        return ptr_free;
+      } // end next_free_ptr()
+
+    /////////////////////////////////////////////////////////////////////
+    // The next_free_entry() function returns 
+    // a copy of the next free entry.
+    /////////////////////////////////////////////////////////////////////
+      HeapEntry next_free_entry(){
+        return HeapEntry(m_heap_tab[ptr_free]);
+      } // end next_free_entry()
+   
+    /////////////////////////////////////////////////////////////////////
+    // The write_free_entry() function modify the next free entry.
+    // Arguments :
+    // - entry : the entry to write
+    /////////////////////////////////////////////////////////////////////
+      void write_free_entry(const HeapEntry &entry){
+        m_heap_tab[ptr_free].copy(entry);
+      } // end write_free_entry()
+
+    /////////////////////////////////////////////////////////////////////
+    // The write_free_ptr() function writes the pointer
+    // to the next free entry
+    /////////////////////////////////////////////////////////////////////
+      void write_free_ptr(const size_t &ptr){
+        assert( (ptr<tab_size) && "HeapDirectory error : try to write a wrong free pointer");
+        ptr_free = ptr;
+      } // end write_free_ptr()
+
+    /////////////////////////////////////////////////////////////////////
+    // The set_full() function sets the full bit (to true).
+    /////////////////////////////////////////////////////////////////////
+      void set_full(){
+        full = true;
+      } // end set_full()
+
+    /////////////////////////////////////////////////////////////////////
+    // The unset_full() function unsets the full bit (to false).
+    /////////////////////////////////////////////////////////////////////
+      void unset_full(){
+        full = false;
+      } // end unset_full()
+
+    /////////////////////////////////////////////////////////////////////
+    // The read() function returns a copy of
+    // the entry pointed by the argument
+    // Arguments :
+    //  - ptr : the pointer to the entry to read
+    /////////////////////////////////////////////////////////////////////
+      HeapEntry read(const size_t &ptr){
+        assert( (ptr<tab_size) && "HeapDirectory error : try to write a wrong free pointer");
+        return HeapEntry(m_heap_tab[ptr]);
+      } // end read()
+
+    /////////////////////////////////////////////////////////////////////
+    // The write() function writes an entry in the heap
+    // Arguments :
+    //  - ptr : the pointer to the entry to replace
+    //  - entry : the entry to write
+    /////////////////////////////////////////////////////////////////////
+      void write(const size_t &ptr, const HeapEntry &entry){
+        assert( (ptr<tab_size) && "HeapDirectory error : try to write a wrong free pointer");
+        m_heap_tab[ptr].copy(entry);
+      } // end write()
+
+  }; // end class HeapDirectory
+
+
+}} // end namespaces
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: trunk/platforms/almos-tsarv3-platforms/common/vci_mem_cache_v3/caba/source/include/update_tab_v3.h
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/vci_mem_cache_v3/caba/source/include/update_tab_v3.h	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/vci_mem_cache_v3/caba/source/include/update_tab_v3.h	(revision 259)
@@ -0,0 +1,402 @@
+#ifndef UPDATE_TAB_V3_H_
+#define UPDATE_TAB_V3_H_
+
+#include <inttypes.h>
+#include <systemc>
+#include <cassert>
+#include "arithmetics.h"
+
+////////////////////////////////////////////////////////////////////////
+//                  An update tab entry    
+////////////////////////////////////////////////////////////////////////
+class UpdateTabEntry {
+  typedef uint32_t size_t;
+  typedef sc_dt::sc_uint<40> addr_t;
+
+  public:
+  bool 	valid;                // It is a valid pending transaction
+  bool	update;               // It is an update transaction
+  bool  brdcast;              // It is a broadcast invalidate
+  bool  rsp;                  // It needs a response to the initiator
+  size_t 	srcid;        // The srcid of the initiator which wrote the data
+  size_t 	trdid;        // The trdid of the initiator which wrote the data
+  size_t 	pktid;        // The pktid of the initiator which wrote the data
+  addr_t	nline;	      // The identifier of the cache line
+  size_t 	count;        // The number of acknowledge responses to receive
+
+  UpdateTabEntry(){
+    valid	= false;
+    update  = false;
+    brdcast = false;
+    rsp     = false;
+    srcid	= 0;
+    trdid	= 0;
+    pktid	= 0;
+    nline	= 0;
+    count	= 0;
+  }
+
+  UpdateTabEntry(bool   i_valid, 
+      bool   i_update,
+      bool   i_brdcast,
+      bool   i_rsp,
+      size_t i_srcid, 
+      size_t i_trdid, 
+      size_t i_pktid, 
+      addr_t i_nline,
+      size_t i_count) 
+  {
+    valid		= i_valid;
+    update	    = i_update;
+    brdcast     = i_brdcast;
+    rsp         = i_rsp;
+    srcid		= i_srcid;
+    trdid		= i_trdid;
+    pktid		= i_pktid;
+    nline		= i_nline;
+    count		= i_count;
+  }
+
+  UpdateTabEntry(const UpdateTabEntry &source)
+  {
+    valid   = source.valid;
+    update  = source.update;
+    brdcast = source.brdcast;
+    rsp     = source.rsp;
+    srcid   = source.srcid;
+    trdid   = source.trdid;
+    pktid   = source.pktid;
+    nline   = source.nline;
+    count   = source.count;
+  }
+
+  ////////////////////////////////////////////////////
+  // The init() function initializes the entry 
+  ///////////////////////////////////////////////////
+  void init()
+  {
+    valid  = false;
+    update = false;
+    brdcast= false;
+    rsp    = false;
+    srcid  = 0;
+    trdid  = 0;
+    pktid  = 0;
+    nline  = 0;
+    count  = 0;
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // The copy() function copies an existing entry
+  // Its arguments are :
+  // - source : the update tab entry to copy
+  ////////////////////////////////////////////////////////////////////
+  void copy(const UpdateTabEntry &source)
+  {
+    valid  = source.valid;
+    update = source.update;
+    brdcast= source.brdcast;
+    rsp    = source.rsp;
+    srcid  = source.srcid;
+    trdid  = source.trdid;
+    pktid  = source.pktid;
+    nline  = source.nline;
+    count  = source.count;
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // The print() function prints the entry  
+  ////////////////////////////////////////////////////////////////////
+  void print(){
+    std::cout << std::dec << "valid  = " << valid  << std::endl;
+    std::cout << "update = " << update << std::endl;
+    std::cout << "brdcast= " << brdcast<< std::endl;
+    std::cout << "rsp    = " << rsp    << std::endl;
+    std::cout << "srcid  = " << srcid  << std::endl; 
+    std::cout << "trdid  = " << trdid  << std::endl; 
+    std::cout << "pktid  = " << pktid  << std::endl; 
+    std::cout << std::hex << "nline  = " << nline  << std::endl;
+    std::cout << std::dec << "count  = " << count  << std::endl;
+  }
+};
+
+////////////////////////////////////////////////////////////////////////
+//                        The update tab             
+////////////////////////////////////////////////////////////////////////
+class UpdateTab{
+
+  typedef uint32_t size_t;
+  typedef sc_dt::sc_uint<40> addr_t;
+
+  private:
+  size_t size_tab;
+  std::vector<UpdateTabEntry> tab;
+
+  public:
+
+  UpdateTab()
+    : tab(0)
+  {
+    size_tab=0;
+  }
+
+  UpdateTab(size_t size_tab_i)
+    : tab(size_tab_i)
+  {
+    size_tab=size_tab_i;
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // The size() function returns the size of the tab  
+  ////////////////////////////////////////////////////////////////////
+  const size_t size(){
+    return size_tab;
+  }
+
+
+  ////////////////////////////////////////////////////////////////////
+  // The size() function returns the size of the tab  
+  ////////////////////////////////////////////////////////////////////
+  void print(){
+    for(size_t i=0; i<size_tab; i++) {
+      std::cout << "UPDATE TAB ENTRY " << std::dec << i << "--------" << std::endl;
+      tab[i].print();
+    }
+    return;
+  }
+
+
+  /////////////////////////////////////////////////////////////////////
+  // The init() function initializes the tab 
+  /////////////////////////////////////////////////////////////////////
+  void init(){
+    for ( size_t i=0; i<size_tab; i++) {
+      tab[i].init();
+    }
+  }
+
+
+  /////////////////////////////////////////////////////////////////////
+  // The reads() function reads an entry 
+  // Arguments :
+  // - entry : the entry to read
+  // This function returns a copy of the entry.
+  /////////////////////////////////////////////////////////////////////
+  UpdateTabEntry read (size_t entry)
+  {
+    assert(entry<size_tab && "Bad Update Tab Entry");
+    return UpdateTabEntry(tab[entry]);
+  }
+
+  ///////////////////////////////////////////////////////////////////////////
+  // The set() function writes an entry in the Update Table
+  // Arguments :
+  // - update : transaction type (bool)
+  // - srcid : srcid of the initiator
+  // - trdid : trdid of the initiator
+  // - pktid : pktid of the initiator
+  // - count : number of expected responses
+  // - index : (return argument) index of the selected entry
+  // This function returns true if the write successed (an entry was empty).
+  ///////////////////////////////////////////////////////////////////////////
+  bool set(const bool	update,
+      const bool   brdcast,
+      const bool   rsp,
+      const size_t srcid,
+      const size_t trdid,
+      const size_t pktid,
+      const addr_t nline,
+      const size_t count,
+      size_t &index)
+  {
+    for ( size_t i=0 ; i<size_tab ; i++ ) {
+      if( !tab[i].valid ) {
+        tab[i].valid		= true;
+        tab[i].update		= update;
+        tab[i].brdcast      = brdcast;
+        tab[i].rsp          = rsp;
+        tab[i].srcid		= (size_t) srcid;
+        tab[i].trdid		= (size_t) trdid;
+        tab[i].pktid		= (size_t) pktid;
+        tab[i].nline		= (addr_t) nline;
+        tab[i].count		= (size_t) count;
+        index			    = i;
+        return true;
+      }
+    }
+    return false;
+  } // end set()
+
+  /////////////////////////////////////////////////////////////////////
+  // The decrement() function decrements the counter for a given entry.
+  // Arguments :
+  // - index   : the index of the entry
+  // - counter : (return argument) value of the counter after decrement
+  // This function returns true if the entry is valid.
+  /////////////////////////////////////////////////////////////////////
+  bool decrement( const size_t index,
+      size_t &counter ) 
+  {
+    assert((index<size_tab) && "Bad Update Tab Entry");
+    if ( tab[index].valid ) {
+      tab[index].count--;
+      counter = tab[index].count;
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The is_full() function returns true if the table is full
+  /////////////////////////////////////////////////////////////////////
+  bool is_full()
+  {
+    for(size_t i = 0 ; i < size_tab ; i++){
+      if(!tab[i].valid){
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The need_rsp() function returns the need of a response
+  // Arguments :
+  // - index : the index of the entry
+  /////////////////////////////////////////////////////////////////////
+  bool need_rsp(const size_t index)
+  {
+    assert(index<size_tab && "Bad Update Tab Entry");
+    return tab[index].rsp;	
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The is_update() function returns the transaction type
+  // Arguments :
+  // - index : the index of the entry
+  /////////////////////////////////////////////////////////////////////
+  bool is_brdcast(const size_t index)
+  {
+    assert(index<size_tab && "Bad Update Tab Entry");
+    return tab[index].brdcast;	
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The is_update() function returns the transaction type
+  // Arguments :
+  // - index : the index of the entry
+  /////////////////////////////////////////////////////////////////////
+  bool is_update(const size_t index)
+  {
+    assert(index<size_tab && "Bad Update Tab Entry");
+    return tab[index].update;	
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The srcid() function returns the srcid value
+  // Arguments :
+  // - index : the index of the entry
+  /////////////////////////////////////////////////////////////////////
+  size_t srcid(const size_t index)
+  {
+    assert(index<size_tab && "Bad Update Tab Entry");
+    return tab[index].srcid;	
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The trdid() function returns the trdid value
+  // Arguments :
+  // - index : the index of the entry
+  /////////////////////////////////////////////////////////////////////
+  size_t trdid(const size_t index)
+  {
+    assert(index<size_tab && "Bad Update Tab Entry");
+    return tab[index].trdid;	
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The pktid() function returns the pktid value
+  // Arguments :
+  // - index : the index of the entry
+  /////////////////////////////////////////////////////////////////////
+  size_t pktid(const size_t index)
+  {
+    assert(index<size_tab && "Bad Update Tab Entry");
+    return tab[index].pktid;	
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The nline() function returns the nline value
+  // Arguments :
+  // - index : the index of the entry
+  /////////////////////////////////////////////////////////////////////
+  addr_t nline(const size_t index)
+  {
+    assert(index<size_tab && "Bad Update Tab Entry");
+    return tab[index].nline;
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The search_inval() function returns the index of the entry in UPT
+  // Arguments :
+  // - nline : the line number of the entry in the directory
+  /////////////////////////////////////////////////////////////////////
+  bool search_inval(const addr_t nline,size_t &index)
+  {
+    size_t i ;
+
+    for (i = 0 ; i < size_tab ; i++){
+      if((tab[i].nline == nline) && tab[i].valid){
+        if(!tab[i].update){
+          index = i ;
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The read_nline() function returns the index of the entry in UPT
+  // Arguments :
+  // - nline : the line number of the entry in the directory
+  /////////////////////////////////////////////////////////////////////
+  bool read_nline(const addr_t nline,size_t &index) 
+  {
+    size_t i ;
+
+    for (i = 0 ; i < size_tab ; i++){
+      if((tab[i].nline == nline) && tab[i].valid){
+        index = i ;
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The clear() function erases an entry of the tab
+  // Arguments :
+  // - index : the index of the entry
+  /////////////////////////////////////////////////////////////////////       
+  void clear(const size_t index)
+  {
+    assert(index<size_tab && "Bad Update Tab Entry");
+    tab[index].valid=false;
+    return;	
+  }
+
+};
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: trunk/platforms/almos-tsarv3-platforms/common/vci_mem_cache_v3/caba/source/include/vci_mem_cache_v3.h
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/vci_mem_cache_v3/caba/source/include/vci_mem_cache_v3.h	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/vci_mem_cache_v3/caba/source/include/vci_mem_cache_v3.h	(revision 259)
@@ -0,0 +1,733 @@
+/* -*- c++ -*-
+ * File         : vci_mem_cache_v3.h
+ * Date         : 26/10/2008
+ * Copyright    : UPMC / LIP6
+ * Authors      : Alain Greiner / Eric Guthmuller
+ *
+ * SOCLIB_LGPL_HEADER_BEGIN
+ *
+ * This file is part of SoCLib, GNU LGPLv2.1.
+ *
+ * SoCLib is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 of the License.
+ *
+ * SoCLib is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with SoCLib; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * SOCLIB_LGPL_HEADER_END
+ *
+ * Maintainers: alain eric.guthmuller@polytechnique.edu
+ */
+/*
+ *
+ * Modifications done by Christophe Choichillon on the 7/04/2009:
+ * - Adding new states in the CLEANUP FSM : CLEANUP_UPT_LOCK and CLEANUP_UPT_WRITE
+ * - Adding a new VCI target port for the CLEANUP network
+ * - Adding new state in the ALLOC_UPT_FSM : ALLOC_UPT_CLEANUP
+ * 
+ * Modifications to do :
+ * - Adding new variables used by the CLEANUP FSM
+ *
+ */
+
+#ifndef SOCLIB_CABA_MEM_CACHE_V3_H
+#define SOCLIB_CABA_MEM_CACHE_V3_H
+
+#include <inttypes.h>
+#include <systemc>
+#include <list>
+#include <cassert>
+#include <iostream>
+#include <fstream>
+#include "arithmetics.h"
+#include "alloc_elems.h"
+#include "caba_base_module.h"
+#include "vci_target.h"
+#include "vci_initiator.h"
+#include "generic_fifo.h"
+#include "mapping_table.h"
+#include "int_tab.h"
+#include "mem_cache_directory_v3.h"
+#include "xram_transaction_v3.h"
+#include "update_tab_v3.h"
+#include "atomic_tab_v3.h"
+#include "config.h"
+
+#define TRANSACTION_TAB_LINES   CONFIG_MEMC_TRANSACTION_TAB_LINES     // Number of lines in the transaction tab
+#define UPDATE_TAB_LINES        CONFIG_MEMC_UPDATE_TAB_LINES    // Number of lines in the update tab
+
+namespace soclib {  namespace caba {
+  using namespace sc_core;
+
+  template<typename vci_param>
+    class VciMemCacheV3
+    : public soclib::caba::BaseModule
+    {
+      typedef sc_dt::sc_uint<40> addr_t;
+      typedef typename vci_param::fast_addr_t vci_addr_t;
+      typedef uint32_t data_t;
+      typedef uint32_t tag_t;
+      typedef uint32_t size_t;
+      typedef uint32_t be_t;
+      typedef uint32_t copy_t;
+
+      /* States of the TGT_CMD fsm */
+      enum tgt_cmd_fsm_state_e{
+        TGT_CMD_IDLE,
+        TGT_CMD_READ,
+        TGT_CMD_READ_EOP,
+        TGT_CMD_WRITE,
+        TGT_CMD_ATOMIC,
+      };
+
+      /* States of the TGT_RSP fsm */
+      enum tgt_rsp_fsm_state_e{
+        TGT_RSP_READ_IDLE,
+        TGT_RSP_WRITE_IDLE,
+        TGT_RSP_LLSC_IDLE,
+        TGT_RSP_XRAM_IDLE,
+        TGT_RSP_INIT_IDLE,
+        TGT_RSP_CLEANUP_IDLE,
+        TGT_RSP_READ,
+        TGT_RSP_WRITE,
+        TGT_RSP_LLSC,
+        TGT_RSP_XRAM,
+        TGT_RSP_INIT,
+        TGT_RSP_CLEANUP,
+      };
+
+      /* States of the INIT_CMD fsm */
+      enum init_cmd_fsm_state_e{
+        INIT_CMD_INVAL_IDLE,
+        INIT_CMD_INVAL_NLINE,
+        INIT_CMD_XRAM_BRDCAST,
+        INIT_CMD_UPDT_IDLE,
+        INIT_CMD_WRITE_BRDCAST,
+        INIT_CMD_UPDT_NLINE,
+        INIT_CMD_UPDT_INDEX,
+        INIT_CMD_UPDT_DATA,
+        INIT_CMD_SC_UPDT_IDLE,
+        INIT_CMD_SC_BRDCAST,
+        INIT_CMD_SC_UPDT_NLINE,
+        INIT_CMD_SC_UPDT_INDEX,
+        INIT_CMD_SC_UPDT_DATA,
+      };
+
+      /* States of the INIT_RSP fsm */
+      enum init_rsp_fsm_state_e{
+        INIT_RSP_IDLE,
+        INIT_RSP_UPT_LOCK,
+        INIT_RSP_UPT_CLEAR,
+        INIT_RSP_END,
+      };
+
+      /* States of the READ fsm */
+      enum read_fsm_state_e{
+        READ_IDLE,
+        READ_DIR_LOCK,
+        READ_DIR_HIT,
+        READ_HEAP_LOCK,
+        READ_HEAP_WRITE,
+        READ_HEAP_ERASE,
+        READ_HEAP_LAST,
+        READ_RSP,
+        READ_TRT_LOCK,
+        READ_TRT_SET,
+        READ_XRAM_REQ,
+      };
+
+      /* States of the WRITE fsm */
+      enum write_fsm_state_e{
+        WRITE_IDLE,
+        WRITE_NEXT,
+        WRITE_DIR_LOCK,
+        WRITE_DIR_HIT_READ,
+        WRITE_DIR_HIT,
+        WRITE_DIR_HIT_RSP,
+        WRITE_UPT_LOCK,
+        WRITE_HEAP_LOCK,
+        WRITE_UPT_REQ,
+        WRITE_UPDATE,
+        WRITE_UPT_DEC,
+        WRITE_RSP,
+        WRITE_TRT_LOCK,
+        WRITE_TRT_DATA,
+        WRITE_TRT_SET,
+        WRITE_WAIT,
+        WRITE_XRAM_REQ,
+        WRITE_TRT_WRITE_LOCK,
+        WRITE_INVAL_LOCK,
+        WRITE_DIR_INVAL,
+        WRITE_INVAL,
+        WRITE_XRAM_SEND,
+        WRITE_HEAP_ERASE,
+        WRITE_HEAP_LAST,
+      };
+
+      /* States of the IXR_RSP fsm */
+      enum ixr_rsp_fsm_state_e{
+        IXR_RSP_IDLE,
+        IXR_RSP_ACK,
+        IXR_RSP_TRT_ERASE,
+        IXR_RSP_TRT_READ,
+      };
+
+      /* States of the XRAM_RSP fsm */
+      enum xram_rsp_fsm_state_e{
+        XRAM_RSP_IDLE,
+        XRAM_RSP_TRT_COPY,
+        XRAM_RSP_TRT_DIRTY,
+        XRAM_RSP_DIR_LOCK,
+        XRAM_RSP_DIR_UPDT,
+        XRAM_RSP_DIR_RSP,
+        XRAM_RSP_INVAL_LOCK,
+        XRAM_RSP_INVAL_WAIT,
+        XRAM_RSP_INVAL,
+        XRAM_RSP_WRITE_DIRTY,
+        XRAM_RSP_HEAP_ERASE,
+        XRAM_RSP_HEAP_LAST,
+      };
+
+      /* States of the IXR_CMD fsm */
+      enum ixr_cmd_fsm_state_e{
+        IXR_CMD_READ_IDLE,
+        IXR_CMD_WRITE_IDLE,
+        IXR_CMD_LLSC_IDLE,
+        IXR_CMD_XRAM_IDLE,
+        IXR_CMD_READ_NLINE,
+        IXR_CMD_WRITE_NLINE,
+        IXR_CMD_LLSC_NLINE,
+        IXR_CMD_XRAM_DATA,
+      };
+
+      /* States of the LLSC fsm */
+      enum llsc_fsm_state_e{
+        LLSC_IDLE,
+        LL_DIR_LOCK,
+        LL_DIR_HIT,
+        LL_RSP,
+        SC_DIR_LOCK,
+        SC_DIR_HIT,
+        SC_UPT_LOCK,
+        SC_WAIT,
+        SC_HEAP_LOCK,
+        SC_UPT_REQ,
+        SC_UPDATE,
+        SC_TRT_LOCK,
+        SC_INVAL_LOCK,
+        SC_DIR_INVAL,
+        SC_INVAL,
+        SC_XRAM_SEND,
+        SC_HEAP_ERASE,
+        SC_HEAP_LAST, 
+        SC_RSP_FALSE,
+        SC_RSP_TRUE,
+        LLSC_TRT_LOCK,
+        LLSC_TRT_SET,
+        LLSC_XRAM_REQ,
+      };
+
+      /* States of the CLEANUP fsm */
+      enum cleanup_fsm_state_e{
+        CLEANUP_IDLE,
+        CLEANUP_DIR_LOCK,
+        CLEANUP_DIR_WRITE,
+        CLEANUP_HEAP_LOCK,
+        CLEANUP_HEAP_SEARCH,
+        CLEANUP_HEAP_CLEAN,
+        CLEANUP_HEAP_FREE,
+        CLEANUP_UPT_LOCK,
+        CLEANUP_UPT_WRITE,
+        CLEANUP_WRITE_RSP,
+        CLEANUP_RSP,
+      };
+
+      /* States of the ALLOC_DIR fsm */
+      enum alloc_dir_fsm_state_e{
+        ALLOC_DIR_READ,
+        ALLOC_DIR_WRITE,
+        ALLOC_DIR_LLSC,
+        ALLOC_DIR_CLEANUP,
+        ALLOC_DIR_XRAM_RSP,
+      };
+
+      /* States of the ALLOC_TRT fsm */
+      enum alloc_trt_fsm_state_e{
+        ALLOC_TRT_READ,
+        ALLOC_TRT_WRITE,
+        ALLOC_TRT_LLSC,
+        ALLOC_TRT_XRAM_RSP,
+        ALLOC_TRT_IXR_RSP,
+      };
+
+      /* States of the ALLOC_UPT fsm */
+      enum alloc_upt_fsm_state_e{
+        ALLOC_UPT_WRITE,
+        ALLOC_UPT_XRAM_RSP,
+        ALLOC_UPT_INIT_RSP,
+        ALLOC_UPT_CLEANUP,
+        ALLOC_UPT_LLSC,
+      };
+
+      /* States of the ALLOC_HEAP fsm */
+      enum alloc_heap_fsm_state_e{
+        ALLOC_HEAP_READ,
+        ALLOC_HEAP_WRITE,
+        ALLOC_HEAP_LLSC,
+        ALLOC_HEAP_CLEANUP,
+        ALLOC_HEAP_XRAM_RSP,
+      };
+
+      uint32_t	   m_cpt_cycles;            // Counter of cycles 
+      uint32_t	   m_cpt_read;              // Number of READ transactions
+      uint32_t	   m_cpt_read_miss;         // Number of MISS READ 
+      uint32_t	   m_cpt_write;             // Number of WRITE transactions
+      uint32_t	   m_cpt_write_miss;        // Number of MISS WRITE
+      uint32_t     m_cpt_write_cells;	    // Cumulated length for WRITE transactions
+      uint32_t     m_cpt_write_dirty;	    // Cumulated length for WRITE transactions
+      uint32_t	   m_cpt_update;            // Number of UPDATE transactions
+      uint32_t	   m_cpt_update_mult;       // Number of targets for UPDATE
+      uint32_t	   m_cpt_inval;             // Number of INVAL  transactions
+      uint32_t	   m_cpt_inval_mult;        // Number of targets for INVAL  
+      uint32_t	   m_cpt_inval_brdcast;     // Number of BROADCAST INVAL  
+      uint32_t	   m_cpt_cleanup;           // Number of CLEANUP transactions
+      uint32_t	   m_cpt_ll;                // Number of LL transactions
+      uint32_t	   m_cpt_sc;                // Number of SC transactions
+      uint32_t     m_total_cycles;
+      unsigned long m_waiting_cycles;        // Number of TGT FSM waiting cycles 
+      double        m_wait_threshold;       // Trace threshold upon waiting cycles percentage
+
+      protected:
+
+      SC_HAS_PROCESS(VciMemCacheV3);
+
+      public:
+      sc_in<bool> 			  	p_clk;
+      sc_in<bool> 			  	p_resetn;
+      soclib::caba::VciTarget<vci_param>    	p_vci_tgt;
+      soclib::caba::VciTarget<vci_param>    	p_vci_tgt_cleanup;
+      soclib::caba::VciInitiator<vci_param> 	p_vci_ini;	
+      soclib::caba::VciInitiator<vci_param> 	p_vci_ixr;
+
+      VciMemCacheV3(
+          sc_module_name name,                              // Instance Name 
+          const soclib::common::MappingTable &mtp,          // Mapping table for primary requets
+          const soclib::common::MappingTable &mtc,          // Mapping table for coherence requets
+          const soclib::common::MappingTable &mtx,          // Mapping table for XRAM
+          const soclib::common::IntTab &vci_ixr_index,      // VCI port to XRAM (initiator)
+          const soclib::common::IntTab &vci_ini_index,      // VCI port to PROC (initiator)
+          const soclib::common::IntTab &vci_tgt_index,      // VCI port to PROC (target)
+          const soclib::common::IntTab &vci_tgt_index_cleanup,    // VCI port to PROC (target) for cleanup
+          size_t nways,                                     // Number of ways per set 
+          size_t nsets,                                     // Number of sets
+          size_t nwords,                                    // Number of words per line
+          size_t heap_size=1024);                           // Size of the heap
+
+      ~VciMemCacheV3();
+
+      void transition();
+
+      void genMoore();
+
+      void print_stats();
+      void clear_stats();
+
+      private:
+        
+        void print_log();
+        void print_trace_to_log_file();
+        
+      // Component attributes
+      const size_t              m_initiators;           // Number of initiators
+      const size_t              m_heap_size;            // Size of the heap
+      const size_t              m_ways;                 // Number of ways in a set
+      const size_t              m_sets;                 // Number of cache sets
+      const size_t              m_words;		        // Number of words in a line
+      const size_t              m_srcid_ixr;		    // Srcid for requests to XRAM 
+      const size_t              m_srcid_ini;		    // Srcid for requests to processors
+      std::list<soclib::common::Segment>  m_seglist;    // memory cached into the cache
+      std::list<soclib::common::Segment>  m_cseglist;   // coherence segment for the cache
+      vci_addr_t        		*m_coherence_table; 	// address(srcid)
+      AtomicTab                 m_atomic_tab;           // atomic access table
+      TransactionTab      		m_transaction_tab;	    // xram transaction table
+      UpdateTab                 m_update_tab;		    // pending update & invalidate 
+      CacheDirectory			m_cache_directory;	    // data cache directory
+      HeapDirectory             m_heap_directory;       // heap directory
+
+      data_t	        	       ***m_cache_data;		// data array[set][way][word]
+        std::ofstream             m_log;
+      size_t                    m_tm_start;
+      long long                 m_debug_start;
+      size_t                    m_tm_end;
+      size_t                    m_period;
+
+
+      // adress masks
+      const soclib::common::AddressMaskingTable<vci_addr_t>   m_x;
+      const soclib::common::AddressMaskingTable<vci_addr_t>   m_y;
+      const soclib::common::AddressMaskingTable<vci_addr_t>   m_z;
+      const soclib::common::AddressMaskingTable<vci_addr_t>   m_nline; 
+
+      // broadcast address
+      vci_addr_t broadcast_addr;
+
+      //////////////////////////////////////////////////
+      // Others registers
+      //////////////////////////////////////////////////
+      size_t m_copy_threshold;
+      sc_signal<size_t>   r_copies_limit; // Limit of the number of copies for one line
+
+      //////////////////////////////////////////////////
+      // Registers controlled by the TGT_CMD fsm
+      //////////////////////////////////////////////////
+
+      // Fifo between TGT_CMD fsm and READ fsm
+      GenericFifo<uint64_t>  m_cmd_read_addr_fifo;
+      GenericFifo<size_t>    m_cmd_read_length_fifo;
+      GenericFifo<size_t>    m_cmd_read_srcid_fifo;
+      GenericFifo<size_t>    m_cmd_read_trdid_fifo;
+      GenericFifo<size_t>    m_cmd_read_pktid_fifo;
+
+      // Fifo between TGT_CMD fsm and WRITE fsm    
+      GenericFifo<uint64_t>  m_cmd_write_addr_fifo;
+      GenericFifo<bool>      m_cmd_write_eop_fifo;
+      GenericFifo<size_t>    m_cmd_write_srcid_fifo;
+      GenericFifo<size_t>    m_cmd_write_trdid_fifo;
+      GenericFifo<size_t>    m_cmd_write_pktid_fifo;
+      GenericFifo<data_t>    m_cmd_write_data_fifo;
+      GenericFifo<be_t>	     m_cmd_write_be_fifo;
+
+      // Fifo between TGT_CMD fsm and LLSC fsm
+      GenericFifo<uint64_t>  m_cmd_llsc_addr_fifo;
+      GenericFifo<bool>      m_cmd_llsc_sc_fifo;
+      GenericFifo<size_t>    m_cmd_llsc_srcid_fifo;
+      GenericFifo<size_t>    m_cmd_llsc_trdid_fifo;
+      GenericFifo<size_t>    m_cmd_llsc_pktid_fifo;
+      GenericFifo<data_t>    m_cmd_llsc_wdata_fifo;
+
+      sc_signal<int>         r_tgt_cmd_fsm;
+
+      sc_signal<size_t>	     r_index;
+      size_t nseg;
+      size_t ncseg;
+      soclib::common::Segment  **m_seg;
+      soclib::common::Segment  **m_cseg;
+      ///////////////////////////////////////////////////////
+      // Registers controlled by the READ fsm
+      ///////////////////////////////////////////////////////
+
+      sc_signal<int>         r_read_fsm;        // FSM state 
+      sc_signal<size_t>      r_read_copy;       // Srcid of the first copy
+      sc_signal<bool>        r_read_copy_inst;  // Type of the first copy
+      sc_signal<tag_t>       r_read_tag;	    // cache line tag (in directory)
+      sc_signal<bool>        r_read_is_cnt;	    // is_cnt bit (in directory)
+      sc_signal<bool>        r_read_lock;	    // lock bit (in directory)
+      sc_signal<bool>        r_read_dirty;	    // dirty bit (in directory)
+      sc_signal<bool>        r_read_inst;       // it is an instruction line
+      sc_signal<size_t>      r_read_count;      // number of copies
+      sc_signal<size_t>      r_read_ptr;        // pointer to the heap
+      sc_signal<data_t>     *r_read_data;       // data (one cache line)
+      sc_signal<size_t>      r_read_way;        // associative way (in cache)
+      sc_signal<size_t>      r_read_trt_index;  // Transaction Table index
+      sc_signal<size_t>      r_read_next_ptr;   // Next entry to point to
+      sc_signal<bool>        r_read_last_free;  // Last free entry
+
+      // Buffer between READ fsm and IXR_CMD fsm (ask a missing cache line to XRAM)   
+      sc_signal<bool>        r_read_to_ixr_cmd_req;     // valid request
+      sc_signal<addr_t>      r_read_to_ixr_cmd_nline;   // cache line index
+      sc_signal<size_t>      r_read_to_ixr_cmd_trdid;   // index in Transaction Table
+
+      // Buffer between READ fsm and TGT_RSP fsm (send a hit read response to L1 cache)
+      sc_signal<bool>	   r_read_to_tgt_rsp_req;       // valid request
+      sc_signal<size_t>	   r_read_to_tgt_rsp_srcid;	    // Transaction srcid
+      sc_signal<size_t>	   r_read_to_tgt_rsp_trdid;	    // Transaction trdid
+      sc_signal<size_t>	   r_read_to_tgt_rsp_pktid;	    // Transaction pktid
+      sc_signal<data_t>   *r_read_to_tgt_rsp_data;	    // data (one cache line)
+      sc_signal<size_t>    r_read_to_tgt_rsp_word;      // first word of the response
+      sc_signal<size_t>    r_read_to_tgt_rsp_length;    // length of the response
+
+      ///////////////////////////////////////////////////////////////
+      // Registers controlled by the WRITE fsm
+      ///////////////////////////////////////////////////////////////
+
+      sc_signal<int>       r_write_fsm;             // FSM state
+      sc_signal<addr_t>	   r_write_address;         // first word address
+      sc_signal<size_t>    r_write_word_index;      // first word index in line
+      sc_signal<size_t>    r_write_word_count;      // number of words in line
+      sc_signal<size_t>    r_write_srcid;           // transaction srcid
+      sc_signal<size_t>    r_write_trdid;           // transaction trdid
+      sc_signal<size_t>    r_write_pktid;           // transaction pktid
+      sc_signal<data_t>	  *r_write_data;            // data (one cache line)	
+      sc_signal<be_t>     *r_write_be;              // one byte enable per word
+      sc_signal<bool>      r_write_byte;            // is it a byte write
+      sc_signal<bool>      r_write_is_cnt;          // is_cnt bit (in directory)
+      sc_signal<bool>      r_write_lock;            // lock bit (in directory)
+      sc_signal<bool>      r_write_inst;            // instruction bit
+      sc_signal<tag_t>     r_write_tag;             // cache line tag (in directory)
+      sc_signal<size_t>    r_write_copy;            // first owner of the line
+      sc_signal<bool>      r_write_copy_inst;       // is this owner a ICache ?
+      sc_signal<size_t>	   r_write_count;           // number of copies
+      sc_signal<size_t>    r_write_ptr;             // pointer to the heap
+      sc_signal<size_t>    r_write_next_ptr;        // next pointer to the heap
+      sc_signal<bool>      r_write_to_dec;          // need to decrement update counter
+      sc_signal<size_t>	   r_write_way;		        // way of the line
+      sc_signal<size_t>    r_write_trt_index;	    // index in Transaction Table
+      sc_signal<size_t>    r_write_upt_index;	    // index in Update Table
+
+      // Buffer between WRITE fsm and TGT_RSP fsm (acknowledge a write command from L1)
+      sc_signal<bool>      r_write_to_tgt_rsp_req;		// valid request
+      sc_signal<size_t>    r_write_to_tgt_rsp_srcid;    // transaction srcid
+      sc_signal<size_t>    r_write_to_tgt_rsp_trdid;	// transaction trdid
+      sc_signal<size_t>    r_write_to_tgt_rsp_pktid;	// transaction pktid
+
+      // Buffer between WRITE fsm and IXR_CMD fsm (ask a missing cache line to XRAM) 
+      sc_signal<bool>	   r_write_to_ixr_cmd_req;      // valid request
+      sc_signal<bool>	   r_write_to_ixr_cmd_write;    // write request
+      sc_signal<addr_t>    r_write_to_ixr_cmd_nline; 	// cache line index
+      sc_signal<data_t>	  *r_write_to_ixr_cmd_data;	    // cache line data
+      sc_signal<size_t>    r_write_to_ixr_cmd_trdid;	// index in Transaction Table
+
+      // Buffer between WRITE fsm and INIT_CMD fsm (Update/Invalidate L1 caches)
+      sc_signal<bool>	   r_write_to_init_cmd_multi_req;   // valid multicast request
+      sc_signal<bool>	   r_write_to_init_cmd_brdcast_req; // valid brdcast request
+      sc_signal<addr_t>	   r_write_to_init_cmd_nline;	    // cache line index
+      sc_signal<size_t>	   r_write_to_init_cmd_trdid;	    // index in Update Table
+      sc_signal<data_t>   *r_write_to_init_cmd_data;	    // data (one cache line)
+      sc_signal<bool>     *r_write_to_init_cmd_we;	        // word enable
+      sc_signal<size_t>	   r_write_to_init_cmd_count;	    // number of words in line
+      sc_signal<size_t>	   r_write_to_init_cmd_index;	    // index of first word in line
+      GenericFifo<bool>    m_write_to_init_cmd_inst_fifo;   // fifo for the L1 type
+      GenericFifo<size_t>  m_write_to_init_cmd_srcid_fifo;  // fifo for srcids
+
+      // Buffer between WRITE fsm and INIT_RSP fsm (Decrement UPT entry)
+      sc_signal<bool>      r_write_to_init_rsp_req;         // valid request
+      sc_signal<size_t>    r_write_to_init_rsp_upt_index;   // index in update table
+
+      /////////////////////////////////////////////////////////
+      // Registers controlled by INIT_RSP fsm
+      //////////////////////////////////////////////////////////
+
+      sc_signal<int> 	   r_init_rsp_fsm;        // FSM state
+      sc_signal<size_t>	   r_init_rsp_upt_index;  // index in the Update Table
+      sc_signal<size_t>	   r_init_rsp_srcid;	  // pending write srcid      
+      sc_signal<size_t>	   r_init_rsp_trdid;	  // pending write trdid      
+      sc_signal<size_t>	   r_init_rsp_pktid;	  // pending write pktid      
+      sc_signal<addr_t>	   r_init_rsp_nline;	  // pending write nline      
+
+      // Buffer between INIT_RSP fsm and TGT_RSP fsm (complete write/update transaction)
+      sc_signal<bool>	     r_init_rsp_to_tgt_rsp_req;   	// valid request
+      sc_signal<size_t>	   r_init_rsp_to_tgt_rsp_srcid;		// Transaction srcid
+      sc_signal<size_t>	   r_init_rsp_to_tgt_rsp_trdid;		// Transaction trdid
+      sc_signal<size_t>	   r_init_rsp_to_tgt_rsp_pktid;		// Transaction pktid
+
+      ///////////////////////////////////////////////////////
+      // Registers controlled by CLEANUP fsm
+      ///////////////////////////////////////////////////////
+
+      sc_signal<int> 	     r_cleanup_fsm;         // FSM state
+      sc_signal<size_t>      r_cleanup_srcid;       // transaction srcid
+      sc_signal<size_t>      r_cleanup_trdid;       // transaction trdid
+      sc_signal<size_t>      r_cleanup_pktid;       // transaction pktid
+      sc_signal<addr_t>      r_cleanup_nline;       // cache line index
+
+      sc_signal<copy_t>      r_cleanup_copy;        // first copy
+      sc_signal<size_t>      r_cleanup_copy_inst;   // type of the first copy
+      sc_signal<copy_t>      r_cleanup_count;       // number of copies 
+      sc_signal<size_t>      r_cleanup_ptr;         // pointer to the heap
+      sc_signal<size_t>      r_cleanup_prev_ptr;    // previous pointer to the heap
+      sc_signal<size_t>      r_cleanup_prev_srcid;  // srcid of previous heap entry
+      sc_signal<bool>        r_cleanup_prev_inst;   // inst bit of previous heap entry
+      sc_signal<size_t>      r_cleanup_next_ptr;    // next pointer to the heap
+      sc_signal<tag_t>       r_cleanup_tag;	        // cache line tag (in directory)
+      sc_signal<bool>        r_cleanup_is_cnt;      // inst bit (in directory)
+      sc_signal<bool>        r_cleanup_lock;	    // lock bit (in directory)
+      sc_signal<bool>        r_cleanup_inst;	    // inst bit (in directory)
+      sc_signal<bool>        r_cleanup_dirty;	    // dirty bit (in directory)
+      sc_signal<size_t>      r_cleanup_way;	        // associative way (in cache)
+
+      sc_signal<size_t>      r_cleanup_write_srcid; // srcid of write response
+      sc_signal<size_t>      r_cleanup_write_trdid; // trdid of write rsp
+      sc_signal<size_t>      r_cleanup_write_pktid; // pktid of write rsp
+      sc_signal<bool>        r_cleanup_need_rsp;    // needs a write rsp
+
+      sc_signal<size_t>      r_cleanup_index;	    // index of the INVAL line (in the UPT)
+
+      // Buffer between CLEANUP fsm and TGT_RSP fsm (acknowledge a write command from L1)
+      sc_signal<bool>      r_cleanup_to_tgt_rsp_req;    // valid request
+      sc_signal<size_t>    r_cleanup_to_tgt_rsp_srcid;  // transaction srcid
+      sc_signal<size_t>    r_cleanup_to_tgt_rsp_trdid;	// transaction trdid
+      sc_signal<size_t>    r_cleanup_to_tgt_rsp_pktid;	// transaction pktid
+
+      ///////////////////////////////////////////////////////
+      // Registers controlled by LLSC fsm
+      ///////////////////////////////////////////////////////
+
+      sc_signal<int>       r_llsc_fsm;          // FSM state
+      sc_signal<data_t>	   r_llsc_data;		    // read data word
+      sc_signal<copy_t>    r_llsc_copy; 	    // Srcid of the first copy
+      sc_signal<bool>      r_llsc_copy_inst;	// Type of the first copy
+      sc_signal<size_t>    r_llsc_count;	    // number of copies
+      sc_signal<size_t>    r_llsc_ptr;  	    // pointer to the heap
+      sc_signal<size_t>    r_llsc_next_ptr;  	// next pointer to the heap
+      sc_signal<bool>      r_llsc_is_cnt;	    // is_cnt bit (in directory)
+      sc_signal<bool>      r_llsc_dirty;	    // dirty bit (in directory)
+      sc_signal<bool>      r_llsc_inst;         // inst bit
+      sc_signal<size_t>    r_llsc_way;		    // way in directory
+      sc_signal<size_t>    r_llsc_set;		    // set in directory
+      sc_signal<data_t>    r_llsc_tag;		    // cache line tag (in directory)
+      sc_signal<size_t>    r_llsc_trt_index;    // Transaction Table index
+      sc_signal<size_t>    r_llsc_upt_index;    // Update Table index
+
+      // Buffer between LLSC fsm and INIT_CMD fsm (XRAM read)	
+      sc_signal<bool>	   r_llsc_to_ixr_cmd_req;   // valid request
+      sc_signal<addr_t>	   r_llsc_to_ixr_cmd_nline; // cache line index
+      sc_signal<size_t>	   r_llsc_to_ixr_cmd_trdid; // index in Transaction Table
+      sc_signal<bool>	   r_llsc_to_ixr_cmd_write; // write request
+      sc_signal<data_t>	  *r_llsc_to_ixr_cmd_data;  // cache line data
+
+
+      // Buffer between LLSC fsm and TGT_RSP fsm
+      sc_signal<bool>	   r_llsc_to_tgt_rsp_req;   // valid request
+      sc_signal<data_t>    r_llsc_to_tgt_rsp_data;  // read data word
+      sc_signal<size_t>	   r_llsc_to_tgt_rsp_srcid; // Transaction srcid
+      sc_signal<size_t>	   r_llsc_to_tgt_rsp_trdid; // Transaction trdid
+      sc_signal<size_t>	   r_llsc_to_tgt_rsp_pktid; // Transaction pktid
+
+      // Buffer between LLSC fsm and INIT_CMD fsm (Update/Invalidate L1 caches)
+      sc_signal<bool>	   r_llsc_to_init_cmd_multi_req;    // valid request
+      sc_signal<bool>	   r_llsc_to_init_cmd_brdcast_req;  // brdcast request
+      sc_signal<addr_t>	   r_llsc_to_init_cmd_nline;	    // cache line index
+      sc_signal<size_t>	   r_llsc_to_init_cmd_trdid;	    // index in Update Table
+      sc_signal<data_t>    r_llsc_to_init_cmd_wdata;        // data (one word)
+      sc_signal<size_t>	   r_llsc_to_init_cmd_index;	    // index of the word in line
+      GenericFifo<bool>    m_llsc_to_init_cmd_inst_fifo;    // fifo for the L1 type
+      GenericFifo<size_t>  m_llsc_to_init_cmd_srcid_fifo;   // fifo for srcids
+
+      // Buffer between LLSC fsm and INIT_RSP fsm (Decrement UPT entry)
+      sc_signal<bool>      r_llsc_to_init_rsp_req;          // valid request
+      sc_signal<size_t>    r_llsc_to_init_rsp_upt_index;    // index in update table
+
+      ////////////////////////////////////////////////////
+      // Registers controlled by the IXR_RSP fsm
+      ////////////////////////////////////////////////////
+
+      sc_signal<int> 	   r_ixr_rsp_fsm;       // FSM state
+      sc_signal<size_t>	   r_ixr_rsp_trt_index;	// TRT entry index
+      sc_signal<size_t>    r_ixr_rsp_cpt;	    // word counter
+
+      // Buffer between IXR_RSP fsm and XRAM_RSP fsm  (response from the XRAM)
+      sc_signal<bool>	  *r_ixr_rsp_to_xram_rsp_rok;	// A xram response is ready
+
+      ////////////////////////////////////////////////////
+      // Registers controlled by the XRAM_RSP fsm
+      ////////////////////////////////////////////////////
+
+      sc_signal<int> 	   r_xram_rsp_fsm;		        // FSM state
+      sc_signal<size_t>	   r_xram_rsp_trt_index;	    // TRT entry index
+      TransactionTabEntry  r_xram_rsp_trt_buf;		    // TRT entry local buffer
+      sc_signal<bool>	   r_xram_rsp_victim_inval;	    // victim line invalidate 
+      sc_signal<bool>	   r_xram_rsp_victim_is_cnt;    // victim line inst bit
+      sc_signal<bool>	   r_xram_rsp_victim_dirty;	    // victim line dirty bit
+      sc_signal<size_t>    r_xram_rsp_victim_way;	    // victim line way
+      sc_signal<size_t>    r_xram_rsp_victim_set;	    // victim line set
+      sc_signal<addr_t>    r_xram_rsp_victim_nline;     // victim line index
+      sc_signal<copy_t>    r_xram_rsp_victim_copy;  	// victim line first copy
+      sc_signal<bool>      r_xram_rsp_victim_copy_inst;	// victim line type of first copy
+      sc_signal<size_t>    r_xram_rsp_victim_count;	    // victim line number of copies
+      sc_signal<size_t>    r_xram_rsp_victim_ptr;       // victim line pointer to the heap
+      sc_signal<data_t>	  *r_xram_rsp_victim_data;	    // victim line data
+      sc_signal<size_t>	   r_xram_rsp_upt_index;	    // UPT entry index
+      sc_signal<size_t>    r_xram_rsp_next_ptr;         // Next pointer to the heap
+
+      // Buffer between XRAM_RSP fsm and TGT_RSP fsm  (response to L1 cache)
+      sc_signal<bool>	   r_xram_rsp_to_tgt_rsp_req;	// Valid request
+      sc_signal<size_t>    r_xram_rsp_to_tgt_rsp_srcid;	// Transaction srcid
+      sc_signal<size_t>    r_xram_rsp_to_tgt_rsp_trdid;	// Transaction trdid
+      sc_signal<size_t>    r_xram_rsp_to_tgt_rsp_pktid;	// Transaction pktid
+      sc_signal<data_t>   *r_xram_rsp_to_tgt_rsp_data;	// data (one cache line)
+      sc_signal<size_t>    r_xram_rsp_to_tgt_rsp_word;  // first word index
+      sc_signal<size_t>    r_xram_rsp_to_tgt_rsp_length;// length of the response
+
+      // Buffer between XRAM_RSP fsm and INIT_CMD fsm (Inval L1 Caches) 
+      sc_signal<bool>	    r_xram_rsp_to_init_cmd_multi_req;       // Valid request
+      sc_signal<bool>       r_xram_rsp_to_init_cmd_brdcast_req;     // Broadcast request
+      sc_signal<addr_t>     r_xram_rsp_to_init_cmd_nline;           // cache line index;
+      sc_signal<size_t>	    r_xram_rsp_to_init_cmd_trdid;           // index of UPT entry
+      GenericFifo<bool>     m_xram_rsp_to_init_cmd_inst_fifo;       // fifo for the L1 type
+      GenericFifo<size_t>   m_xram_rsp_to_init_cmd_srcid_fifo;      // fifo for srcids
+
+      // Buffer between XRAM_RSP fsm and IXR_CMD fsm (XRAM write)
+      sc_signal<bool>	   r_xram_rsp_to_ixr_cmd_req;	// Valid request
+      sc_signal<addr_t>	   r_xram_rsp_to_ixr_cmd_nline;	// cache line index
+      sc_signal<data_t>	  *r_xram_rsp_to_ixr_cmd_data;	// cache line data
+      sc_signal<size_t>	   r_xram_rsp_to_ixr_cmd_trdid;	// index in transaction table
+
+      ////////////////////////////////////////////////////
+      // Registers controlled by the IXR_CMD fsm
+      ////////////////////////////////////////////////////
+
+      sc_signal<int> 	   r_ixr_cmd_fsm;
+      sc_signal<size_t>	   r_ixr_cmd_cpt;
+
+      ////////////////////////////////////////////////////
+      // Registers controlled by TGT_RSP fsm
+      ////////////////////////////////////////////////////
+
+      sc_signal<int> 	   r_tgt_rsp_fsm;
+      sc_signal<size_t>    r_tgt_rsp_cpt;
+
+      ////////////////////////////////////////////////////
+      // Registers controlled by INIT_CMD fsm
+      ////////////////////////////////////////////////////
+
+      sc_signal<int> 	  r_init_cmd_fsm;
+      sc_signal<size_t>   r_init_cmd_cpt;
+      sc_signal<bool>     r_init_cmd_inst;
+
+      ////////////////////////////////////////////////////
+      // Registers controlled by ALLOC_DIR fsm
+      ////////////////////////////////////////////////////
+
+      sc_signal<int> 		r_alloc_dir_fsm;
+
+      ////////////////////////////////////////////////////
+      // Registers controlled by ALLOC_TRT fsm
+      ////////////////////////////////////////////////////
+
+      sc_signal<int> 		r_alloc_trt_fsm;
+
+      ////////////////////////////////////////////////////
+      // Registers controlled by ALLOC_UPT fsm
+      ////////////////////////////////////////////////////
+
+      sc_signal<int> 		r_alloc_upt_fsm;
+
+      ////////////////////////////////////////////////////
+      // Registers controlled by ALLOC_HEAP fsm
+      ////////////////////////////////////////////////////
+
+      sc_signal<int> 		r_alloc_heap_fsm;
+
+    }; // end class VciMemCacheV3
+
+}}
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: trunk/platforms/almos-tsarv3-platforms/common/vci_mem_cache_v3/caba/source/include/xram_transaction_v3.h
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/vci_mem_cache_v3/caba/source/include/xram_transaction_v3.h	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/vci_mem_cache_v3/caba/source/include/xram_transaction_v3.h	(revision 259)
@@ -0,0 +1,412 @@
+#ifndef XRAM_TRANSACTION_V3_H_
+#define XRAM_TRANSACTION_V3_H_
+ 
+#include <inttypes.h>
+#include <systemc>
+#include <cassert>
+#include <fstream>
+#include <iostream>
+#include "arithmetics.h"
+
+#define DEBUG_XRAM_TRANSACTION 0
+
+////////////////////////////////////////////////////////////////////////
+//                  A transaction tab entry         
+////////////////////////////////////////////////////////////////////////
+
+class TransactionTabEntry {
+  typedef uint32_t size_t;
+  typedef uint32_t data_t;
+  typedef sc_dt::sc_uint<40> addr_t;
+  typedef uint32_t be_t;
+
+ public:
+  bool 		      valid;     	    // entry valid 
+  bool 		      xram_read; 	    // read request to XRAM
+  addr_t   	      nline;    	    // index (zy) of the requested line
+  size_t 	      srcid;     	    // processor requesting the transaction
+  size_t 	      trdid;     	    // processor requesting the transaction
+  size_t 	      pktid;     	    // processor requesting the transaction
+  bool 		      proc_read;	    // read request from processor
+  size_t 		  read_length;      // length of the read (for the response)
+  size_t 	      word_index;    	// index of the first read word (for the response)
+  std::vector<data_t> wdata;        // write buffer (one cache line)
+  std::vector<be_t>   wdata_be;    	// be for each data in the write buffer
+  /////////////////////////////////////////////////////////////////////
+  // The init() function initializes the entry 
+  /////////////////////////////////////////////////////////////////////
+  void init()
+  {
+    valid		= false;
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The alloc() function initializes the vectors of an entry
+  // Its arguments are :
+  // - n_words : number of words per line in the cache
+  /////////////////////////////////////////////////////////////////////
+  void alloc(size_t n_words)
+  {
+    wdata_be.reserve( (int)n_words );
+    wdata.reserve( (int)n_words );
+    for(size_t i=0; i<n_words; i++){
+      wdata_be.push_back(false);
+      wdata.push_back(0);
+    }
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // The copy() function copies an existing entry
+  // Its arguments are :
+  // - source : the transaction tab entry to copy
+  ////////////////////////////////////////////////////////////////////
+  void copy(const TransactionTabEntry &source)
+  {
+    valid	    = source.valid;
+    xram_read 	= source.xram_read;
+    nline	    = source.nline;
+    srcid	    = source.srcid;
+    trdid	    = source.trdid;
+    pktid	    = source.pktid;
+    proc_read 	= source.proc_read;
+    read_length = source.read_length;
+    word_index	= source.word_index;
+    wdata_be.assign(source.wdata_be.begin(),source.wdata_be.end());
+    wdata.assign(source.wdata.begin(),source.wdata.end());	
+  }
+
+  ////////////////////////////////////////////////////////////////////
+  // The print() function prints the entry 
+  ////////////////////////////////////////////////////////////////////
+  void print(std::ostream &m_log){
+    m_log << "valid       = " << valid        << std::endl;
+    m_log << "xram_read   = " << xram_read    << std::endl;
+    m_log << "nline       = " << std::hex << nline << std::endl;
+    m_log << "srcid       = " << srcid        << std::endl;
+    m_log << "trdid       = " << trdid        << std::endl;
+    m_log << "pktid       = " << pktid        << std::endl;
+    m_log << "proc_read   = " << proc_read    << std::endl;
+    m_log << "read_length = " << read_length  << std::endl;
+    m_log << "word_index  = " << word_index   << std::endl; 
+    for(size_t i=0; i<wdata_be.size() ; i++){
+      m_log << "wdata_be [" << i <<"] = " << wdata_be[i] << std::endl;
+    }
+    for(size_t i=0; i<wdata.size() ; i++){
+      m_log << "wdata [" << i <<"] = " << wdata[i] << std::endl;
+    }
+    m_log << std::endl;
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // 		Constructors
+  /////////////////////////////////////////////////////////////////////
+
+  TransactionTabEntry()
+    {
+      wdata_be.clear();
+      wdata.clear();
+      valid=false;
+    }
+
+  TransactionTabEntry(const TransactionTabEntry &source){
+    valid	    = source.valid;
+    xram_read	= source.xram_read;
+    nline	    = source.nline;
+    srcid	    = source.srcid;
+    trdid	    = source.trdid;
+    pktid	    = source.pktid;
+    proc_read	= source.proc_read;
+    read_length = source.read_length;
+    word_index	= source.word_index;
+    wdata_be.assign(source.wdata_be.begin(),source.wdata_be.end());
+    wdata.assign(source.wdata.begin(),source.wdata.end());
+  }
+
+}; // end class TransactionTabEntry
+
+////////////////////////////////////////////////////////////////////////
+//                  The transaction tab                              
+////////////////////////////////////////////////////////////////////////
+class TransactionTab{
+  typedef uint32_t size_t;
+  typedef uint32_t data_t;
+  typedef sc_dt::sc_uint<40> addr_t;
+  typedef uint32_t be_t;
+
+ private:
+  size_t size_tab;                // The size of the tab
+
+  data_t be_to_mask(be_t be)
+  {
+    data_t ret = 0;
+    if ( be&0x1 ) {
+      ret = ret | 0x000000FF;
+    }
+    if ( be&0x2 ) {
+      ret = ret | 0x0000FF00;
+    }
+    if ( be&0x4 ) {
+      ret = ret | 0x00FF0000;
+    }
+    if ( be&0x8 ) {
+      ret = ret | 0xFF000000;
+    }
+    return ret;
+  }
+
+ public:
+  TransactionTabEntry *tab;       // The transaction tab
+
+  ////////////////////////////////////////////////////////////////////
+  //		Constructors
+  ////////////////////////////////////////////////////////////////////
+  TransactionTab()
+    {
+      size_tab=0;
+      tab=NULL;
+    }
+
+  TransactionTab(size_t n_entries, size_t n_words)
+    {
+      size_tab = n_entries;
+      tab = new TransactionTabEntry[size_tab];
+      for ( size_t i=0; i<size_tab; i++) {
+          tab[i].alloc(n_words);
+      }
+    }
+
+  ~TransactionTab()
+    {
+      delete [] tab;
+    }
+
+  /////////////////////////////////////////////////////////////////////
+  // The size() function returns the size of the tab
+  /////////////////////////////////////////////////////////////////////
+  size_t size()
+  {
+    return size_tab;
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The init() function initializes the transaction tab entries
+  /////////////////////////////////////////////////////////////////////
+  void init()
+  {
+    for ( size_t i=0; i<size_tab; i++) {
+      tab[i].init();
+    }
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The print() function prints a transaction tab entry
+  // Arguments :
+  // - index : the index of the entry to print
+  /////////////////////////////////////////////////////////////////////
+  void print(const size_t index, std::ostream &output)
+  {
+    assert( (index < size_tab) 
+	    && "Invalid Transaction Tab Entry");
+    tab[index].print(output);
+    return;
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The read() function returns a transaction tab entry.
+  // Arguments :
+  // - index : the index of the entry to read
+  /////////////////////////////////////////////////////////////////////
+  TransactionTabEntry read(const size_t index)
+  {
+    assert( (index < size_tab) 
+	    && "Invalid Transaction Tab Entry");
+    return tab[index];
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The full() function returns the state of the transaction tab
+  // Arguments :
+  // - index : (return argument) the index of an empty entry 
+  // The function returns true if the transaction tab is full
+  /////////////////////////////////////////////////////////////////////
+  bool full(size_t &index)
+  {
+    for(size_t i=0; i<size_tab; i++){
+      if(!tab[i].valid){
+	    index=i;
+	    return false;	
+      }
+    }
+    return true;
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The hit_read() function checks if an XRAM read transaction exists 
+  // for a given cache line.
+  // Arguments :
+  // - index : (return argument) the index of the hit entry, if there is 
+  // - nline : the index (zy) of the requested line
+  // The function returns true if a read request has already been sent
+  //////////////////////////////////////////////////////////////////////
+  bool hit_read(const addr_t nline,size_t &index)
+  {
+    for(size_t i=0; i<size_tab; i++){
+      if((tab[i].valid && (nline==tab[i].nline)) && (tab[i].xram_read)) {
+	    index=i;
+	    return true;	
+      }
+    }
+    return false;
+  }
+
+  ///////////////////////////////////////////////////////////////////////
+  // The hit_write() function looks if an XRAM write transaction exists 
+  // for a given line.
+  // Arguments :
+  // - nline : the index (zy) of the requested line
+  // The function returns true if a write request has already been sent
+  ///////////////////////////////////////////////////////////////////////
+  bool hit_write(const addr_t nline)
+  {
+    for(size_t i=0; i<size_tab; i++){
+      if(tab[i].valid && (nline==tab[i].nline) && !(tab[i].xram_read)) {
+	    return true;	
+      }
+    }
+    return false;
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The write_data_mask() function writes a vector of data (a line).
+  // The data is written only if the corresponding bits are set
+  // in the be vector. 
+  // Arguments :
+  // - index : the index of the request in the transaction tab
+  // - be   : vector of be 
+  // - data : vector of data
+  /////////////////////////////////////////////////////////////////////
+  void write_data_mask(const size_t index, 
+		       const std::vector<be_t> &be, 
+		       const std::vector<data_t> &data) 
+  {
+    assert( (index < size_tab) 
+	    && "Invalid Transaction Tab Entry");
+    assert(be.size()==tab[index].wdata_be.size() 
+	   && "Bad data mask in write_data_mask in TransactionTab");
+    assert(data.size()==tab[index].wdata.size() 
+	   && "Bad data in write_data_mask in TransactionTab");
+
+    for(size_t i=0; i<tab[index].wdata_be.size() ; i++) {
+      tab[index].wdata_be[i] = tab[index].wdata_be[i] | be[i];
+      data_t mask = be_to_mask(be[i]);
+      tab[index].wdata[i] = (tab[index].wdata[i] & ~mask) | (data[i] & mask);
+    }
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The set() function registers a transaction (read or write)
+  // to the XRAM in the transaction tab.
+  // Arguments :
+  // - index : index in the transaction tab
+  // - xram_read : transaction type (read or write a cache line)
+  // - nline : the index (zy) of the cache line
+  // - srcid : srcid of the initiator that caused the transaction
+  // - trdid : trdid of the initiator that caused the transaction
+  // - pktid : pktid of the initiator that caused the transaction
+  // - proc_read : does the initiator want a copy
+  // - read_length : length of read (in case of processor read)
+  // - word_index : index in the line (in case of single word read)
+  // - data : the data to write (in case of write)
+  // - data_be : the mask of the data to write (in case of write)
+  /////////////////////////////////////////////////////////////////////
+  void set(const size_t index,
+	   const bool xram_read,
+	   const addr_t nline,
+	   const size_t srcid,
+	   const size_t trdid,
+	   const size_t pktid,
+	   const bool proc_read,
+	   const size_t read_length,
+	   const size_t word_index,
+	   const std::vector<be_t> &data_be,
+	   const std::vector<data_t> &data) 
+  {
+    assert( (index < size_tab) 
+	    && "The selected entry is out of range in set() Transaction Tab");
+    assert(data_be.size()==tab[index].wdata_be.size() 
+	   && "Bad data_be argument in set() TransactionTab");
+    assert(data.size()==tab[index].wdata.size() 
+	   && "Bad data argument in set() TransactionTab");
+
+    tab[index].valid	        = true;
+    tab[index].xram_read        = xram_read;
+    tab[index].nline	        = nline;
+    tab[index].srcid	        = srcid;
+    tab[index].trdid	        = trdid;
+    tab[index].pktid	        = pktid;
+    tab[index].proc_read	    = proc_read;
+    tab[index].read_length	    = read_length;
+    tab[index].word_index	    = word_index;
+    for(size_t i=0; i<tab[index].wdata.size(); i++) {
+      tab[index].wdata_be[i]    = data_be[i];
+      tab[index].wdata[i]       = data[i];
+    }
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The write_rsp() function writes a word of the response to an 
+  // XRAM read transaction.
+  // The data is only written when the corresponding BE field is Ox0.
+  // Arguments :
+  // - index : the index of the transaction in the transaction tab
+  // - word_index : the index of the data in the line
+  // - data : the data to write
+  /////////////////////////////////////////////////////////////////////
+  void write_rsp(const size_t index,
+		 const size_t word,
+		 const data_t data)
+  {
+    assert( (index < size_tab) 
+	    && "Selected entry  out of range in write_rsp() Transaction Tab");
+    assert( (word <= tab[index].wdata_be.size()) 
+	    && "Bad word_index in write_rsp() in TransactionTab");
+  
+    if(!(tab[index].valid))
+    {        
+        print(index, std::cout);
+    }
+
+    assert( tab[index].valid 
+	    && "Transaction Tab Entry invalid in write_rsp()");
+  
+    assert( tab[index].xram_read 
+                && "Selected entry is not an XRAM read transaction in write_rsp()");
+
+    data_t mask = be_to_mask(tab[index].wdata_be[word]);
+    tab[index].wdata[word] = (tab[index].wdata[word] & mask) | (data & ~mask);
+  }
+
+  /////////////////////////////////////////////////////////////////////
+  // The erase() function erases an entry in the transaction tab.
+  // Arguments :
+  // - index : the index of the request in the transaction tab
+  /////////////////////////////////////////////////////////////////////
+  void erase(const size_t index)
+  {
+    assert( (index < size_tab) 
+	    && "The selected entry is out of range in erase() Transaction Tab");
+    tab[index].valid	= false;
+  }
+}; // end class TransactionTab
+
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: trunk/platforms/almos-tsarv3-platforms/common/vci_mem_cache_v3/caba/source/src/TAGS
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/vci_mem_cache_v3/caba/source/src/TAGS	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/vci_mem_cache_v3/caba/source/src/TAGS	(revision 259)
@@ -0,0 +1,654 @@
+
+
+vci_mem_cache_v3.cpp,678
+#define MEMC_INI_ID 36,1183
+#define TRACE_MSG(38,1211
+namespace soclib 44,1522
+namespace soclib { namespace caba soclib::caba44,1522
+#define tmpl(224,5523
+  using soclib::common::uint32_log2;soclib::caba::soclib::common::uint32_log2226,5596
+  tmpl(soclib::caba::tmpl232,5724
+#define L2 271,7054
+#undef L2276,7306
+  tmpl(soclib::caba::tmpl456,13347
+  tmpl(soclib::caba::tmpl477,13900
+  tmpl(soclib::caba::tmpl500,15551
+  tmpl(soclib::caba::tmpl521,17270
+  tmpl(soclib::caba::tmpl543,18820
+  tmpl(soclib::caba::tmpl572,19526
+#define L2 2586,103429
+#undef L22588,103559
+#define L2 2638,105577
+#undef L22640,105709
+  tmpl(soclib::caba::tmpl4370,180469
+
+
+../include/atomic_tab_v3.h,652
+#define ATOMIC_TAB_V3_H_2,25
+class AtomicTab{AtomicTab17,505
+    typedef uint32_t size_t;AtomicTab::size_t18,522
+    typedef sc_dt::sc_uint<40> addr_t;AtomicTab::addr_t19,551
+    size_t size_tab;AtomicTab::size_tab22,600
+    std::vector<addr_t> addr_tab;AtomicTab::addr_tab23,671
+    std::vector<bool>   valid_tab;AtomicTab::valid_tab24,738
+    AtomicTab(AtomicTab::AtomicTab28,813
+    AtomicTab(AtomicTab::AtomicTab35,888
+    const size_t size(AtomicTab::size46,1214
+    void init(AtomicTab::init54,1487
+    void set(AtomicTab::set69,1923
+    bool isatomic(AtomicTab::isatomic86,2520
+    void reset(AtomicTab::reset100,3016
+
+
+../include/mem_cache_directory_v3.h,3393
+#define SOCLIB_CABA_MEM_CACHE_DIRECTORY_V3_H 2,45
+  class LruEntry 16,430
+      bool recent;20,463
+      void init(22,495
+  class Owner{Owner32,763
+    typedef uint32_t size_t;33,778
+      bool      inst;37,838
+      size_t    srcid;38,894
+      Owner(43,1027
+      Owner(48,1130
+      Owner(53,1221
+  class DirectoryEntry 65,1566
+    typedef uint32_t tag_t;67,1592
+    typedef uint32_t size_t;68,1620
+    bool    valid;72,1663
+    bool    is_cnt;73,1714
+    bool    dirty;74,1788
+    bool    lock;75,1839
+    bool    inst;76,1891
+    tag_t   tag;77,1956
+    size_t  count;78,2012
+    Owner   owner;79,2068
+    size_t  ptr;80,2129
+    DirectoryEntry(82,2195
+    DirectoryEntry(96,2499
+    void init(112,3088
+    void copy(125,3483
+    void print(141,4012
+  class CacheDirectory 159,4749
+    typedef sc_dt::sc_uint<40> addr_t;CacheDirectory::addr_t161,4775
+    typedef uint32_t data_t;CacheDirectory::data_t162,4814
+    typedef uint32_t tag_t;CacheDirectory::tag_t163,4843
+    typedef uint32_t size_t;CacheDirectory::size_t164,4871
+    size_t					m_ways;CacheDirectory::m_ways169,4942
+    size_t					m_sets;CacheDirectory::m_sets170,4965
+    size_t					m_words;CacheDirectory::m_words171,4988
+    size_t					m_width;CacheDirectory::m_width172,5012
+    DirectoryEntry 				**m_dir_tab;CacheDirectory::m_dir_tab175,5071
+    LruEntry	 				**m_lru_tab;CacheDirectory::m_lru_tab176,5107
+    CacheDirectory(CacheDirectory::CacheDirectory183,5229
+    ~CacheDirectory(CacheDirectory::~CacheDirectory205,5909
+    DirectoryEntry read(CacheDirectory::read223,6571
+#define L2 226,6637
+#undef L2229,6833
+    void write(CacheDirectory::write257,7684
+    void print(CacheDirectory::print285,8721
+    DirectoryEntry select(CacheDirectory::select297,9281
+    void init(CacheDirectory::init333,10475
+  class HeapEntry{HeapEntry348,10933
+    typedef uint32_t size_t;HeapEntry::size_t349,10952
+      Owner     owner;HeapEntry::owner353,11021
+      size_t    next;HeapEntry::next354,11044
+      HeapEntry(HeapEntry::HeapEntry359,11144
+      HeapEntry(HeapEntry::HeapEntry368,11315
+      void copy(HeapEntry::copy377,11719
+      void print(HeapEntry::print386,12090
+  class HeapDirectory{HeapDirectory399,12596
+    typedef uint32_t size_t;HeapDirectory::size_t400,12619
+      size_t    ptr_free;HeapDirectory::ptr_free404,12696
+      bool      full;HeapDirectory::full405,12722
+      HeapEntry *m_heap_tab;HeapDirectory::m_heap_tab406,12744
+      size_t    tab_size;HeapDirectory::tab_size409,12813
+      HeapDirectory(HeapDirectory::HeapDirectory415,12929
+      ~HeapDirectory(HeapDirectory::~HeapDirectory426,13264
+      void init(HeapDirectory::init433,13533
+      void print(HeapDirectory::print448,14035
+      void print_list(HeapDirectory::print_list458,14537
+      bool is_full(HeapDirectory::is_full473,15180
+      size_t next_free_ptr(HeapDirectory::next_free_ptr481,15485
+      HeapEntry next_free_entry(HeapDirectory::next_free_entry489,15805
+      void write_free_entry(HeapDirectory::write_free_entry498,16195
+      void write_free_ptr(HeapDirectory::write_free_ptr506,16559
+      void set_full(HeapDirectory::set_full514,16964
+      void unset_full(HeapDirectory::unset_full521,17248
+      HeapEntry read(HeapDirectory::read531,17626
+      void write(HeapDirectory::write542,18139
+
+
+../include/update_tab_v3.h,1996
+#define UPDATE_TAB_V3_H_2,25
+class UpdateTabEntry 12,327
+  typedef uint32_t size_t;UpdateTabEntry::size_t13,350
+  typedef sc_dt::sc_uint<40> addr_t;UpdateTabEntry::addr_t14,377
+  bool 	valid;UpdateTabEntry::valid17,425
+  bool	update;UpdateTabEntry::update18,492
+  bool  brdcast;UpdateTabEntry::brdcast19,552
+  bool  rsp;UpdateTabEntry::rsp20,614
+  size_t 	srcid;UpdateTabEntry::srcid21,684
+  size_t 	trdid;UpdateTabEntry::trdid22,759
+  size_t 	pktid;UpdateTabEntry::pktid23,834
+  addr_t	nline;UpdateTabEntry::nline24,909
+  size_t 	count;UpdateTabEntry::count25,967
+  UpdateTabEntry(UpdateTabEntry::UpdateTabEntry27,1042
+  UpdateTabEntry(UpdateTabEntry::UpdateTabEntry39,1224
+  UpdateTabEntry(UpdateTabEntry::UpdateTabEntry60,1661
+  void init(UpdateTabEntry::init76,2127
+  void copy(UpdateTabEntry::copy94,2572
+  void print(UpdateTabEntry::print110,3054
+class UpdateTab{UpdateTab126,3794
+  typedef uint32_t size_t;UpdateTab::size_t128,3812
+  typedef sc_dt::sc_uint<40> addr_t;UpdateTab::addr_t129,3839
+  size_t size_tab;UpdateTab::size_tab132,3888
+  std::vector<UpdateTabEntry> tab;UpdateTab::tab133,3907
+  UpdateTab(UpdateTab::UpdateTab137,3954
+  UpdateTab(UpdateTab::UpdateTab143,4006
+  const size_t size(UpdateTab::size152,4290
+  void print(UpdateTab::print160,4537
+  void init(UpdateTab::init172,4912
+  UpdateTabEntry read UpdateTab::read185,5285
+  bool set(UpdateTab::set202,5993
+  bool decrement(UpdateTab::decrement237,7135
+  bool is_full(UpdateTab::is_full253,7617
+  bool need_rsp(UpdateTab::need_rsp268,8024
+  bool is_brdcast(UpdateTab::is_brdcast279,8409
+  bool is_update(UpdateTab::is_update290,8800
+  size_t srcid(UpdateTab::srcid301,9180
+  size_t trdid(UpdateTab::trdid312,9557
+  size_t pktid(UpdateTab::pktid323,9934
+  addr_t nline(UpdateTab::nline334,10311
+  bool search_inval(UpdateTab::search_inval345,10731
+  bool read_nline(UpdateTab::read_nline365,11305
+  void clear(UpdateTab::clear383,11804
+
+
+../include/vci_mem_cache_v3.h,38250
+#define SOCLIB_CABA_MEM_CACHE_V3_H42,1409
+#define TRANSACTION_TAB_LINES 64,1909
+#define UPDATE_TAB_LINES 65,2021
+    class VciMemCacheV371,2219
+      typedef sc_dt::sc_uint<40> addr_t;VciMemCacheV3::addr_t74,2287
+      typedef typename vci_param::fast_addr_t vci_addr_t;VciMemCacheV3::vci_addr_t75,2328
+      typedef uint32_t data_t;VciMemCacheV3::data_t76,2386
+      typedef uint32_t tag_t;VciMemCacheV3::tag_t77,2417
+      typedef uint32_t size_t;VciMemCacheV3::size_t78,2447
+      typedef uint32_t be_t;VciMemCacheV3::be_t79,2478
+      typedef uint32_t copy_t;VciMemCacheV3::copy_t80,2507
+      enum tgt_cmd_fsm_state_e{VciMemCacheV3::tgt_cmd_fsm_state_e83,2577
+        TGT_CMD_IDLE,VciMemCacheV3::tgt_cmd_fsm_state_e::TGT_CMD_IDLE84,2609
+        TGT_CMD_READ,VciMemCacheV3::tgt_cmd_fsm_state_e::TGT_CMD_READ85,2631
+        TGT_CMD_READ_EOP,VciMemCacheV3::tgt_cmd_fsm_state_e::TGT_CMD_READ_EOP86,2653
+        TGT_CMD_WRITE,VciMemCacheV3::tgt_cmd_fsm_state_e::TGT_CMD_WRITE87,2679
+        TGT_CMD_ATOMIC,VciMemCacheV3::tgt_cmd_fsm_state_e::TGT_CMD_ATOMIC88,2702
+      enum tgt_rsp_fsm_state_e{VciMemCacheV3::tgt_rsp_fsm_state_e92,2774
+        TGT_RSP_READ_IDLE,VciMemCacheV3::tgt_rsp_fsm_state_e::TGT_RSP_READ_IDLE93,2806
+        TGT_RSP_WRITE_IDLE,VciMemCacheV3::tgt_rsp_fsm_state_e::TGT_RSP_WRITE_IDLE94,2833
+        TGT_RSP_LLSC_IDLE,VciMemCacheV3::tgt_rsp_fsm_state_e::TGT_RSP_LLSC_IDLE95,2861
+        TGT_RSP_XRAM_IDLE,VciMemCacheV3::tgt_rsp_fsm_state_e::TGT_RSP_XRAM_IDLE96,2888
+        TGT_RSP_INIT_IDLE,VciMemCacheV3::tgt_rsp_fsm_state_e::TGT_RSP_INIT_IDLE97,2915
+        TGT_RSP_CLEANUP_IDLE,VciMemCacheV3::tgt_rsp_fsm_state_e::TGT_RSP_CLEANUP_IDLE98,2942
+        TGT_RSP_READ,VciMemCacheV3::tgt_rsp_fsm_state_e::TGT_RSP_READ99,2972
+        TGT_RSP_WRITE,VciMemCacheV3::tgt_rsp_fsm_state_e::TGT_RSP_WRITE100,2994
+        TGT_RSP_LLSC,VciMemCacheV3::tgt_rsp_fsm_state_e::TGT_RSP_LLSC101,3017
+        TGT_RSP_XRAM,VciMemCacheV3::tgt_rsp_fsm_state_e::TGT_RSP_XRAM102,3039
+        TGT_RSP_INIT,VciMemCacheV3::tgt_rsp_fsm_state_e::TGT_RSP_INIT103,3061
+        TGT_RSP_CLEANUP,VciMemCacheV3::tgt_rsp_fsm_state_e::TGT_RSP_CLEANUP104,3083
+      enum init_cmd_fsm_state_e{VciMemCacheV3::init_cmd_fsm_state_e108,3157
+        INIT_CMD_INVAL_IDLE,VciMemCacheV3::init_cmd_fsm_state_e::INIT_CMD_INVAL_IDLE109,3190
+        INIT_CMD_INVAL_NLINE,VciMemCacheV3::init_cmd_fsm_state_e::INIT_CMD_INVAL_NLINE110,3219
+        INIT_CMD_XRAM_BRDCAST,VciMemCacheV3::init_cmd_fsm_state_e::INIT_CMD_XRAM_BRDCAST111,3249
+        INIT_CMD_UPDT_IDLE,VciMemCacheV3::init_cmd_fsm_state_e::INIT_CMD_UPDT_IDLE112,3280
+        INIT_CMD_WRITE_BRDCAST,VciMemCacheV3::init_cmd_fsm_state_e::INIT_CMD_WRITE_BRDCAST113,3308
+        INIT_CMD_UPDT_NLINE,VciMemCacheV3::init_cmd_fsm_state_e::INIT_CMD_UPDT_NLINE114,3340
+        INIT_CMD_UPDT_INDEX,VciMemCacheV3::init_cmd_fsm_state_e::INIT_CMD_UPDT_INDEX115,3369
+        INIT_CMD_UPDT_DATA,VciMemCacheV3::init_cmd_fsm_state_e::INIT_CMD_UPDT_DATA116,3398
+        INIT_CMD_SC_UPDT_IDLE,VciMemCacheV3::init_cmd_fsm_state_e::INIT_CMD_SC_UPDT_IDLE117,3426
+        INIT_CMD_SC_BRDCAST,VciMemCacheV3::init_cmd_fsm_state_e::INIT_CMD_SC_BRDCAST118,3457
+        INIT_CMD_SC_UPDT_NLINE,VciMemCacheV3::init_cmd_fsm_state_e::INIT_CMD_SC_UPDT_NLINE119,3486
+        INIT_CMD_SC_UPDT_INDEX,VciMemCacheV3::init_cmd_fsm_state_e::INIT_CMD_SC_UPDT_INDEX120,3518
+        INIT_CMD_SC_UPDT_DATA,VciMemCacheV3::init_cmd_fsm_state_e::INIT_CMD_SC_UPDT_DATA121,3550
+      enum init_rsp_fsm_state_e{VciMemCacheV3::init_rsp_fsm_state_e125,3630
+        INIT_RSP_IDLE,VciMemCacheV3::init_rsp_fsm_state_e::INIT_RSP_IDLE126,3663
+        INIT_RSP_UPT_LOCK,VciMemCacheV3::init_rsp_fsm_state_e::INIT_RSP_UPT_LOCK127,3686
+        INIT_RSP_UPT_CLEAR,VciMemCacheV3::init_rsp_fsm_state_e::INIT_RSP_UPT_CLEAR128,3713
+        INIT_RSP_END,VciMemCacheV3::init_rsp_fsm_state_e::INIT_RSP_END129,3741
+      enum read_fsm_state_e{VciMemCacheV3::read_fsm_state_e133,3808
+        READ_IDLE,VciMemCacheV3::read_fsm_state_e::READ_IDLE134,3837
+        READ_DIR_LOCK,VciMemCacheV3::read_fsm_state_e::READ_DIR_LOCK135,3856
+        READ_DIR_HIT,VciMemCacheV3::read_fsm_state_e::READ_DIR_HIT136,3879
+        READ_HEAP_LOCK,VciMemCacheV3::read_fsm_state_e::READ_HEAP_LOCK137,3901
+        READ_HEAP_WRITE,VciMemCacheV3::read_fsm_state_e::READ_HEAP_WRITE138,3925
+        READ_HEAP_ERASE,VciMemCacheV3::read_fsm_state_e::READ_HEAP_ERASE139,3950
+        READ_HEAP_LAST,VciMemCacheV3::read_fsm_state_e::READ_HEAP_LAST140,3975
+        READ_RSP,VciMemCacheV3::read_fsm_state_e::READ_RSP141,3999
+        READ_TRT_LOCK,VciMemCacheV3::read_fsm_state_e::READ_TRT_LOCK142,4017
+        READ_TRT_SET,VciMemCacheV3::read_fsm_state_e::READ_TRT_SET143,4040
+        READ_XRAM_REQ,VciMemCacheV3::read_fsm_state_e::READ_XRAM_REQ144,4062
+      enum write_fsm_state_e{VciMemCacheV3::write_fsm_state_e148,4131
+        WRITE_IDLE,VciMemCacheV3::write_fsm_state_e::WRITE_IDLE149,4161
+        WRITE_NEXT,VciMemCacheV3::write_fsm_state_e::WRITE_NEXT150,4181
+        WRITE_DIR_LOCK,VciMemCacheV3::write_fsm_state_e::WRITE_DIR_LOCK151,4201
+        WRITE_DIR_HIT_READ,VciMemCacheV3::write_fsm_state_e::WRITE_DIR_HIT_READ152,4225
+        WRITE_DIR_HIT,VciMemCacheV3::write_fsm_state_e::WRITE_DIR_HIT153,4253
+        WRITE_DIR_HIT_RSP,VciMemCacheV3::write_fsm_state_e::WRITE_DIR_HIT_RSP154,4276
+        WRITE_UPT_LOCK,VciMemCacheV3::write_fsm_state_e::WRITE_UPT_LOCK155,4303
+        WRITE_HEAP_LOCK,VciMemCacheV3::write_fsm_state_e::WRITE_HEAP_LOCK156,4327
+        WRITE_UPT_REQ,VciMemCacheV3::write_fsm_state_e::WRITE_UPT_REQ157,4352
+        WRITE_UPDATE,VciMemCacheV3::write_fsm_state_e::WRITE_UPDATE158,4375
+        WRITE_UPT_DEC,VciMemCacheV3::write_fsm_state_e::WRITE_UPT_DEC159,4397
+        WRITE_RSP,VciMemCacheV3::write_fsm_state_e::WRITE_RSP160,4420
+        WRITE_TRT_LOCK,VciMemCacheV3::write_fsm_state_e::WRITE_TRT_LOCK161,4439
+        WRITE_TRT_DATA,VciMemCacheV3::write_fsm_state_e::WRITE_TRT_DATA162,4463
+        WRITE_TRT_SET,VciMemCacheV3::write_fsm_state_e::WRITE_TRT_SET163,4487
+        WRITE_WAIT,VciMemCacheV3::write_fsm_state_e::WRITE_WAIT164,4510
+        WRITE_XRAM_REQ,VciMemCacheV3::write_fsm_state_e::WRITE_XRAM_REQ165,4530
+        WRITE_TRT_WRITE_LOCK,VciMemCacheV3::write_fsm_state_e::WRITE_TRT_WRITE_LOCK166,4554
+        WRITE_INVAL_LOCK,VciMemCacheV3::write_fsm_state_e::WRITE_INVAL_LOCK167,4584
+        WRITE_DIR_INVAL,VciMemCacheV3::write_fsm_state_e::WRITE_DIR_INVAL168,4610
+        WRITE_INVAL,VciMemCacheV3::write_fsm_state_e::WRITE_INVAL169,4635
+        WRITE_XRAM_SEND,VciMemCacheV3::write_fsm_state_e::WRITE_XRAM_SEND170,4656
+        WRITE_HEAP_ERASE,VciMemCacheV3::write_fsm_state_e::WRITE_HEAP_ERASE171,4681
+        WRITE_HEAP_LAST,VciMemCacheV3::write_fsm_state_e::WRITE_HEAP_LAST172,4707
+      enum ixr_rsp_fsm_state_e{VciMemCacheV3::ixr_rsp_fsm_state_e176,4780
+        IXR_RSP_IDLE,VciMemCacheV3::ixr_rsp_fsm_state_e::IXR_RSP_IDLE177,4812
+        IXR_RSP_ACK,VciMemCacheV3::ixr_rsp_fsm_state_e::IXR_RSP_ACK178,4834
+        IXR_RSP_TRT_ERASE,VciMemCacheV3::ixr_rsp_fsm_state_e::IXR_RSP_TRT_ERASE179,4855
+        IXR_RSP_TRT_READ,VciMemCacheV3::ixr_rsp_fsm_state_e::IXR_RSP_TRT_READ180,4882
+      enum xram_rsp_fsm_state_e{VciMemCacheV3::xram_rsp_fsm_state_e184,4957
+        XRAM_RSP_IDLE,VciMemCacheV3::xram_rsp_fsm_state_e::XRAM_RSP_IDLE185,4990
+        XRAM_RSP_TRT_COPY,VciMemCacheV3::xram_rsp_fsm_state_e::XRAM_RSP_TRT_COPY186,5013
+        XRAM_RSP_TRT_DIRTY,VciMemCacheV3::xram_rsp_fsm_state_e::XRAM_RSP_TRT_DIRTY187,5040
+        XRAM_RSP_DIR_LOCK,VciMemCacheV3::xram_rsp_fsm_state_e::XRAM_RSP_DIR_LOCK188,5068
+        XRAM_RSP_DIR_UPDT,VciMemCacheV3::xram_rsp_fsm_state_e::XRAM_RSP_DIR_UPDT189,5095
+        XRAM_RSP_DIR_RSP,VciMemCacheV3::xram_rsp_fsm_state_e::XRAM_RSP_DIR_RSP190,5122
+        XRAM_RSP_INVAL_LOCK,VciMemCacheV3::xram_rsp_fsm_state_e::XRAM_RSP_INVAL_LOCK191,5148
+        XRAM_RSP_INVAL_WAIT,VciMemCacheV3::xram_rsp_fsm_state_e::XRAM_RSP_INVAL_WAIT192,5177
+        XRAM_RSP_INVAL,VciMemCacheV3::xram_rsp_fsm_state_e::XRAM_RSP_INVAL193,5206
+        XRAM_RSP_WRITE_DIRTY,VciMemCacheV3::xram_rsp_fsm_state_e::XRAM_RSP_WRITE_DIRTY194,5230
+        XRAM_RSP_HEAP_ERASE,VciMemCacheV3::xram_rsp_fsm_state_e::XRAM_RSP_HEAP_ERASE195,5260
+        XRAM_RSP_HEAP_LAST,VciMemCacheV3::xram_rsp_fsm_state_e::XRAM_RSP_HEAP_LAST196,5289
+      enum ixr_cmd_fsm_state_e{VciMemCacheV3::ixr_cmd_fsm_state_e200,5365
+        IXR_CMD_READ_IDLE,VciMemCacheV3::ixr_cmd_fsm_state_e::IXR_CMD_READ_IDLE201,5397
+        IXR_CMD_WRITE_IDLE,VciMemCacheV3::ixr_cmd_fsm_state_e::IXR_CMD_WRITE_IDLE202,5424
+        IXR_CMD_LLSC_IDLE,VciMemCacheV3::ixr_cmd_fsm_state_e::IXR_CMD_LLSC_IDLE203,5452
+        IXR_CMD_XRAM_IDLE,VciMemCacheV3::ixr_cmd_fsm_state_e::IXR_CMD_XRAM_IDLE204,5479
+        IXR_CMD_READ_NLINE,VciMemCacheV3::ixr_cmd_fsm_state_e::IXR_CMD_READ_NLINE205,5506
+        IXR_CMD_WRITE_NLINE,VciMemCacheV3::ixr_cmd_fsm_state_e::IXR_CMD_WRITE_NLINE206,5534
+        IXR_CMD_LLSC_NLINE,VciMemCacheV3::ixr_cmd_fsm_state_e::IXR_CMD_LLSC_NLINE207,5563
+        IXR_CMD_XRAM_DATA,VciMemCacheV3::ixr_cmd_fsm_state_e::IXR_CMD_XRAM_DATA208,5591
+      enum llsc_fsm_state_e{VciMemCacheV3::llsc_fsm_state_e212,5663
+        LLSC_IDLE,VciMemCacheV3::llsc_fsm_state_e::LLSC_IDLE213,5692
+        LL_DIR_LOCK,VciMemCacheV3::llsc_fsm_state_e::LL_DIR_LOCK214,5711
+        LL_DIR_HIT,VciMemCacheV3::llsc_fsm_state_e::LL_DIR_HIT215,5732
+        LL_RSP,VciMemCacheV3::llsc_fsm_state_e::LL_RSP216,5752
+        SC_DIR_LOCK,VciMemCacheV3::llsc_fsm_state_e::SC_DIR_LOCK217,5768
+        SC_DIR_HIT,VciMemCacheV3::llsc_fsm_state_e::SC_DIR_HIT218,5789
+        SC_UPT_LOCK,VciMemCacheV3::llsc_fsm_state_e::SC_UPT_LOCK219,5809
+        SC_WAIT,VciMemCacheV3::llsc_fsm_state_e::SC_WAIT220,5830
+        SC_HEAP_LOCK,VciMemCacheV3::llsc_fsm_state_e::SC_HEAP_LOCK221,5847
+        SC_UPT_REQ,VciMemCacheV3::llsc_fsm_state_e::SC_UPT_REQ222,5869
+        SC_UPDATE,VciMemCacheV3::llsc_fsm_state_e::SC_UPDATE223,5889
+        SC_TRT_LOCK,VciMemCacheV3::llsc_fsm_state_e::SC_TRT_LOCK224,5908
+        SC_INVAL_LOCK,VciMemCacheV3::llsc_fsm_state_e::SC_INVAL_LOCK225,5929
+        SC_DIR_INVAL,VciMemCacheV3::llsc_fsm_state_e::SC_DIR_INVAL226,5952
+        SC_INVAL,VciMemCacheV3::llsc_fsm_state_e::SC_INVAL227,5974
+        SC_XRAM_SEND,VciMemCacheV3::llsc_fsm_state_e::SC_XRAM_SEND228,5992
+        SC_HEAP_ERASE,VciMemCacheV3::llsc_fsm_state_e::SC_HEAP_ERASE229,6014
+        SC_HEAP_LAST,VciMemCacheV3::llsc_fsm_state_e::SC_HEAP_LAST230,6037
+        SC_RSP_FALSE,VciMemCacheV3::llsc_fsm_state_e::SC_RSP_FALSE231,6060
+        SC_RSP_TRUE,VciMemCacheV3::llsc_fsm_state_e::SC_RSP_TRUE232,6082
+        LLSC_TRT_LOCK,VciMemCacheV3::llsc_fsm_state_e::LLSC_TRT_LOCK233,6103
+        LLSC_TRT_SET,VciMemCacheV3::llsc_fsm_state_e::LLSC_TRT_SET234,6126
+        LLSC_XRAM_REQ,VciMemCacheV3::llsc_fsm_state_e::LLSC_XRAM_REQ235,6148
+      enum cleanup_fsm_state_e{VciMemCacheV3::cleanup_fsm_state_e239,6219
+        CLEANUP_IDLE,VciMemCacheV3::cleanup_fsm_state_e::CLEANUP_IDLE240,6251
+        CLEANUP_DIR_LOCK,VciMemCacheV3::cleanup_fsm_state_e::CLEANUP_DIR_LOCK241,6273
+        CLEANUP_DIR_WRITE,VciMemCacheV3::cleanup_fsm_state_e::CLEANUP_DIR_WRITE242,6299
+        CLEANUP_HEAP_LOCK,VciMemCacheV3::cleanup_fsm_state_e::CLEANUP_HEAP_LOCK243,6326
+        CLEANUP_HEAP_SEARCH,VciMemCacheV3::cleanup_fsm_state_e::CLEANUP_HEAP_SEARCH244,6353
+        CLEANUP_HEAP_CLEAN,VciMemCacheV3::cleanup_fsm_state_e::CLEANUP_HEAP_CLEAN245,6382
+        CLEANUP_HEAP_FREE,VciMemCacheV3::cleanup_fsm_state_e::CLEANUP_HEAP_FREE246,6410
+        CLEANUP_UPT_LOCK,VciMemCacheV3::cleanup_fsm_state_e::CLEANUP_UPT_LOCK247,6437
+        CLEANUP_UPT_WRITE,VciMemCacheV3::cleanup_fsm_state_e::CLEANUP_UPT_WRITE248,6463
+        CLEANUP_WRITE_RSP,VciMemCacheV3::cleanup_fsm_state_e::CLEANUP_WRITE_RSP249,6490
+        CLEANUP_RSP,VciMemCacheV3::cleanup_fsm_state_e::CLEANUP_RSP250,6517
+      enum alloc_dir_fsm_state_e{VciMemCacheV3::alloc_dir_fsm_state_e254,6588
+        ALLOC_DIR_READ,VciMemCacheV3::alloc_dir_fsm_state_e::ALLOC_DIR_READ255,6622
+        ALLOC_DIR_WRITE,VciMemCacheV3::alloc_dir_fsm_state_e::ALLOC_DIR_WRITE256,6646
+        ALLOC_DIR_LLSC,VciMemCacheV3::alloc_dir_fsm_state_e::ALLOC_DIR_LLSC257,6671
+        ALLOC_DIR_CLEANUP,VciMemCacheV3::alloc_dir_fsm_state_e::ALLOC_DIR_CLEANUP258,6695
+        ALLOC_DIR_XRAM_RSP,VciMemCacheV3::alloc_dir_fsm_state_e::ALLOC_DIR_XRAM_RSP259,6722
+      enum alloc_trt_fsm_state_e{VciMemCacheV3::alloc_trt_fsm_state_e263,6800
+        ALLOC_TRT_READ,VciMemCacheV3::alloc_trt_fsm_state_e::ALLOC_TRT_READ264,6834
+        ALLOC_TRT_WRITE,VciMemCacheV3::alloc_trt_fsm_state_e::ALLOC_TRT_WRITE265,6858
+        ALLOC_TRT_LLSC,VciMemCacheV3::alloc_trt_fsm_state_e::ALLOC_TRT_LLSC266,6883
+        ALLOC_TRT_XRAM_RSP,VciMemCacheV3::alloc_trt_fsm_state_e::ALLOC_TRT_XRAM_RSP267,6907
+        ALLOC_TRT_IXR_RSP,VciMemCacheV3::alloc_trt_fsm_state_e::ALLOC_TRT_IXR_RSP268,6935
+      enum alloc_upt_fsm_state_e{VciMemCacheV3::alloc_upt_fsm_state_e272,7012
+        ALLOC_UPT_WRITE,VciMemCacheV3::alloc_upt_fsm_state_e::ALLOC_UPT_WRITE273,7046
+        ALLOC_UPT_XRAM_RSP,VciMemCacheV3::alloc_upt_fsm_state_e::ALLOC_UPT_XRAM_RSP274,7071
+        ALLOC_UPT_INIT_RSP,VciMemCacheV3::alloc_upt_fsm_state_e::ALLOC_UPT_INIT_RSP275,7099
+        ALLOC_UPT_CLEANUP,VciMemCacheV3::alloc_upt_fsm_state_e::ALLOC_UPT_CLEANUP276,7127
+        ALLOC_UPT_LLSC,VciMemCacheV3::alloc_upt_fsm_state_e::ALLOC_UPT_LLSC277,7154
+      enum alloc_heap_fsm_state_e{VciMemCacheV3::alloc_heap_fsm_state_e281,7229
+        ALLOC_HEAP_READ,VciMemCacheV3::alloc_heap_fsm_state_e::ALLOC_HEAP_READ282,7264
+        ALLOC_HEAP_WRITE,VciMemCacheV3::alloc_heap_fsm_state_e::ALLOC_HEAP_WRITE283,7289
+        ALLOC_HEAP_LLSC,VciMemCacheV3::alloc_heap_fsm_state_e::ALLOC_HEAP_LLSC284,7315
+        ALLOC_HEAP_CLEANUP,VciMemCacheV3::alloc_heap_fsm_state_e::ALLOC_HEAP_CLEANUP285,7340
+        ALLOC_HEAP_XRAM_RSP,VciMemCacheV3::alloc_heap_fsm_state_e::ALLOC_HEAP_XRAM_RSP286,7368
+      uint32_t	   m_cpt_cycles;VciMemCacheV3::m_cpt_cycles289,7407
+      uint32_t	   m_cpt_read;VciMemCacheV3::m_cpt_read290,7472
+      uint32_t	   m_cpt_read_miss;VciMemCacheV3::m_cpt_read_miss291,7546
+      uint32_t	   m_cpt_write;VciMemCacheV3::m_cpt_write292,7613
+      uint32_t	   m_cpt_write_miss;VciMemCacheV3::m_cpt_write_miss293,7688
+      uint32_t     m_cpt_write_cells;VciMemCacheV3::m_cpt_write_cells294,7755
+      uint32_t     m_cpt_write_dirty;VciMemCacheV3::m_cpt_write_dirty295,7840
+      uint32_t	   m_cpt_update;VciMemCacheV3::m_cpt_update296,7925
+      uint32_t	   m_cpt_update_mult;VciMemCacheV3::m_cpt_update_mult297,8001
+      uint32_t	   m_cpt_inval;VciMemCacheV3::m_cpt_inval298,8076
+      uint32_t	   m_cpt_inval_mult;VciMemCacheV3::m_cpt_inval_mult299,8152
+      uint32_t	   m_cpt_inval_brdcast;VciMemCacheV3::m_cpt_inval_brdcast300,8228
+      uint32_t	   m_cpt_cleanup;VciMemCacheV3::m_cpt_cleanup301,8302
+      uint32_t	   m_cpt_ll;VciMemCacheV3::m_cpt_ll302,8379
+      uint32_t	   m_cpt_sc;VciMemCacheV3::m_cpt_sc303,8451
+      uint32_t     m_total_cycles;VciMemCacheV3::m_total_cycles304,8523
+        unsigned long m_waiting_cycles;VciMemCacheV3::m_waiting_cycles305,8558
+      sc_in<bool> 			  	p_clk;VciMemCacheV3::p_clk312,8713
+      sc_in<bool> 			  	p_resetn;VciMemCacheV3::p_resetn313,8744
+      soclib::caba::VciTarget<vci_param>    	p_vci_tgt;VciMemCacheV3::p_vci_tgt314,8778
+      soclib::caba::VciTarget<vci_param>    	p_vci_tgt_cleanup;VciMemCacheV3::p_vci_tgt_cleanup315,8834
+      soclib::caba::VciInitiator<vci_param> 	p_vci_ini;VciMemCacheV3::p_vci_ini316,8898
+      soclib::caba::VciInitiator<vci_param> 	p_vci_ixr;VciMemCacheV3::p_vci_ixr317,8955
+      const size_t              m_initiators;VciMemCacheV3::m_initiators348,10364
+      const size_t              m_heap_size;VciMemCacheV3::m_heap_size349,10444
+      const size_t              m_ways;VciMemCacheV3::m_ways350,10520
+      const size_t              m_sets;VciMemCacheV3::m_sets351,10603
+      const size_t              m_words;VciMemCacheV3::m_words352,10683
+      const size_t              m_srcid_ixr;VciMemCacheV3::m_srcid_ixr353,10762
+      const size_t              m_srcid_ini;VciMemCacheV3::m_srcid_ini354,10843
+      std::list<soclib::common::Segment>  m_seglist;VciMemCacheV3::m_seglist355,10929
+      std::list<soclib::common::Segment>  m_cseglist;VciMemCacheV3::m_cseglist356,11017
+      vci_addr_t        		*m_coherence_table;VciMemCacheV3::m_coherence_table357,11108
+      AtomicTab                 m_atomic_tab;VciMemCacheV3::m_atomic_tab358,11173
+      TransactionTab      		m_transaction_tab;VciMemCacheV3::m_transaction_tab359,11252
+      UpdateTab                 m_update_tab;VciMemCacheV3::m_update_tab360,11329
+      CacheDirectory			m_cache_directory;VciMemCacheV3::m_cache_directory361,11412
+      HeapDirectory             m_heap_directory;VciMemCacheV3::m_heap_directory362,11482
+      data_t	        	       ***m_cache_data;VciMemCacheV3::m_cache_data364,11557
+        std::ofstream             m_log;VciMemCacheV3::m_log365,11634
+      size_t                    m_tm_start;VciMemCacheV3::m_tm_start366,11675
+      long long                 m_debug_start;VciMemCacheV3::m_debug_start367,11719
+      size_t                    m_tm_end;VciMemCacheV3::m_tm_end368,11766
+      size_t                    m_period;VciMemCacheV3::m_period369,11808
+      const soclib::common::AddressMaskingTable<vci_addr_t>   m_x;VciMemCacheV3::m_x373,11874
+      const soclib::common::AddressMaskingTable<vci_addr_t>   m_y;VciMemCacheV3::m_y374,11941
+      const soclib::common::AddressMaskingTable<vci_addr_t>   m_z;VciMemCacheV3::m_z375,12008
+      const soclib::common::AddressMaskingTable<vci_addr_t>   m_nline;VciMemCacheV3::m_nline376,12075
+      vci_addr_t broadcast_addr;VciMemCacheV3::broadcast_addr379,12175
+      sc_signal<size_t>   r_copies_limit;VciMemCacheV3::r_copies_limit384,12349
+      GenericFifo<uint64_t>  m_cmd_read_addr_fifo;VciMemCacheV3::m_cmd_read_addr_fifo391,12649
+      GenericFifo<size_t>    m_cmd_read_length_fifo;VciMemCacheV3::m_cmd_read_length_fifo392,12700
+      GenericFifo<size_t>    m_cmd_read_srcid_fifo;VciMemCacheV3::m_cmd_read_srcid_fifo393,12753
+      GenericFifo<size_t>    m_cmd_read_trdid_fifo;VciMemCacheV3::m_cmd_read_trdid_fifo394,12805
+      GenericFifo<size_t>    m_cmd_read_pktid_fifo;VciMemCacheV3::m_cmd_read_pktid_fifo395,12857
+      GenericFifo<uint64_t>  m_cmd_write_addr_fifo;VciMemCacheV3::m_cmd_write_addr_fifo398,12962
+      GenericFifo<bool>      m_cmd_write_eop_fifo;VciMemCacheV3::m_cmd_write_eop_fifo399,13014
+      GenericFifo<size_t>    m_cmd_write_srcid_fifo;VciMemCacheV3::m_cmd_write_srcid_fifo400,13065
+      GenericFifo<size_t>    m_cmd_write_trdid_fifo;VciMemCacheV3::m_cmd_write_trdid_fifo401,13118
+      GenericFifo<size_t>    m_cmd_write_pktid_fifo;VciMemCacheV3::m_cmd_write_pktid_fifo402,13171
+      GenericFifo<data_t>    m_cmd_write_data_fifo;VciMemCacheV3::m_cmd_write_data_fifo403,13224
+      GenericFifo<be_t>	     m_cmd_write_be_fifo;VciMemCacheV3::m_cmd_write_be_fifo404,13276
+      GenericFifo<uint64_t>  m_cmd_llsc_addr_fifo;VciMemCacheV3::m_cmd_llsc_addr_fifo407,13374
+      GenericFifo<bool>      m_cmd_llsc_sc_fifo;VciMemCacheV3::m_cmd_llsc_sc_fifo408,13425
+      GenericFifo<size_t>    m_cmd_llsc_srcid_fifo;VciMemCacheV3::m_cmd_llsc_srcid_fifo409,13474
+      GenericFifo<size_t>    m_cmd_llsc_trdid_fifo;VciMemCacheV3::m_cmd_llsc_trdid_fifo410,13526
+      GenericFifo<size_t>    m_cmd_llsc_pktid_fifo;VciMemCacheV3::m_cmd_llsc_pktid_fifo411,13578
+      GenericFifo<data_t>    m_cmd_llsc_wdata_fifo;VciMemCacheV3::m_cmd_llsc_wdata_fifo412,13630
+      sc_signal<int>         r_tgt_cmd_fsm;VciMemCacheV3::r_tgt_cmd_fsm414,13683
+      sc_signal<size_t>	     r_index;VciMemCacheV3::r_index416,13728
+      size_t nseg;VciMemCacheV3::nseg417,13766
+      size_t ncseg;VciMemCacheV3::ncseg418,13785
+      soclib::common::Segment  **m_seg;VciMemCacheV3::m_seg419,13805
+      soclib::common::Segment  **m_cseg;VciMemCacheV3::m_cseg420,13845
+      sc_signal<int>         r_read_fsm;VciMemCacheV3::r_read_fsm425,14057
+      sc_signal<size_t>      r_read_copy;VciMemCacheV3::r_read_copy426,14119
+      sc_signal<bool>        r_read_copy_inst;VciMemCacheV3::r_read_copy_inst427,14194
+      sc_signal<tag_t>       r_read_tag;VciMemCacheV3::r_read_tag428,14268
+      sc_signal<bool>        r_read_is_cnt;VciMemCacheV3::r_read_is_cnt429,14346
+      sc_signal<bool>        r_read_lock;VciMemCacheV3::r_read_lock430,14423
+      sc_signal<bool>        r_read_dirty;VciMemCacheV3::r_read_dirty431,14496
+      sc_signal<bool>        r_read_inst;VciMemCacheV3::r_read_inst432,14571
+      sc_signal<size_t>      r_read_count;VciMemCacheV3::r_read_count433,14648
+      sc_signal<size_t>      r_read_ptr;VciMemCacheV3::r_read_ptr434,14716
+      sc_signal<data_t>     *r_read_data;VciMemCacheV3::r_read_data435,14787
+      sc_signal<size_t>      r_read_way;VciMemCacheV3::r_read_way436,14860
+      sc_signal<size_t>      r_read_trt_index;VciMemCacheV3::r_read_trt_index437,14938
+      sc_signal<size_t>      r_read_next_ptr;VciMemCacheV3::r_read_next_ptr438,15013
+      sc_signal<bool>        r_read_last_free;VciMemCacheV3::r_read_last_free439,15087
+      sc_signal<bool>        r_read_to_ixr_cmd_req;VciMemCacheV3::r_read_to_ixr_cmd_req442,15242
+      sc_signal<addr_t>      r_read_to_ixr_cmd_nline;VciMemCacheV3::r_read_to_ixr_cmd_nline443,15315
+      sc_signal<size_t>      r_read_to_ixr_cmd_trdid;VciMemCacheV3::r_read_to_ixr_cmd_trdid444,15391
+      sc_signal<bool>	   r_read_to_tgt_rsp_req;VciMemCacheV3::r_read_to_tgt_rsp_req447,15566
+      sc_signal<size_t>	   r_read_to_tgt_rsp_srcid;VciMemCacheV3::r_read_to_tgt_rsp_srcid448,15637
+      sc_signal<size_t>	   r_read_to_tgt_rsp_trdid;VciMemCacheV3::r_read_to_tgt_rsp_trdid449,15714
+      sc_signal<size_t>	   r_read_to_tgt_rsp_pktid;VciMemCacheV3::r_read_to_tgt_rsp_pktid450,15791
+      sc_signal<data_t>   *r_read_to_tgt_rsp_data;VciMemCacheV3::r_read_to_tgt_rsp_data451,15868
+      sc_signal<size_t>    r_read_to_tgt_rsp_word;VciMemCacheV3::r_read_to_tgt_rsp_word452,15948
+      sc_signal<size_t>    r_read_to_tgt_rsp_length;VciMemCacheV3::r_read_to_tgt_rsp_length453,16034
+      sc_signal<int>       r_write_fsm;VciMemCacheV3::r_write_fsm459,16305
+      sc_signal<addr_t>	   r_write_address;VciMemCacheV3::r_write_address460,16370
+      sc_signal<size_t>    r_write_word_index;VciMemCacheV3::r_write_word_index461,16444
+      sc_signal<size_t>    r_write_word_count;VciMemCacheV3::r_write_word_count462,16524
+      sc_signal<size_t>    r_write_srcid;VciMemCacheV3::r_write_srcid463,16603
+      sc_signal<size_t>    r_write_trdid;VciMemCacheV3::r_write_trdid464,16676
+      sc_signal<size_t>    r_write_pktid;VciMemCacheV3::r_write_pktid465,16749
+      sc_signal<data_t>	  *r_write_data;VciMemCacheV3::r_write_data466,16822
+      sc_signal<be_t>     *r_write_be;VciMemCacheV3::r_write_be467,16900
+      sc_signal<bool>      r_write_byte;VciMemCacheV3::r_write_byte468,16980
+      sc_signal<bool>      r_write_is_cnt;VciMemCacheV3::r_write_is_cnt469,17054
+      sc_signal<bool>      r_write_lock;VciMemCacheV3::r_write_lock470,17135
+      sc_signal<bool>      r_write_inst;VciMemCacheV3::r_write_inst471,17214
+      sc_signal<tag_t>     r_write_tag;VciMemCacheV3::r_write_tag472,17285
+      sc_signal<size_t>    r_write_copy;VciMemCacheV3::r_write_copy473,17370
+      sc_signal<bool>      r_write_copy_inst;VciMemCacheV3::r_write_copy_inst474,17449
+      sc_signal<size_t>	   r_write_count;VciMemCacheV3::r_write_count475,17529
+      sc_signal<size_t>    r_write_ptr;VciMemCacheV3::r_write_ptr476,17601
+      sc_signal<size_t>    r_write_next_ptr;VciMemCacheV3::r_write_next_ptr477,17676
+      sc_signal<bool>      r_write_to_dec;VciMemCacheV3::r_write_to_dec478,17756
+      sc_signal<size_t>	   r_write_way;VciMemCacheV3::r_write_way479,17844
+      sc_signal<size_t>    r_write_trt_index;VciMemCacheV3::r_write_trt_index480,17912
+      sc_signal<size_t>    r_write_upt_index;VciMemCacheV3::r_write_upt_index481,17992
+      sc_signal<bool>      r_write_to_tgt_rsp_req;VciMemCacheV3::r_write_to_tgt_rsp_req484,18156
+      sc_signal<size_t>    r_write_to_tgt_rsp_srcid;VciMemCacheV3::r_write_to_tgt_rsp_srcid485,18225
+      sc_signal<size_t>    r_write_to_tgt_rsp_trdid;VciMemCacheV3::r_write_to_tgt_rsp_trdid486,18302
+      sc_signal<size_t>    r_write_to_tgt_rsp_pktid;VciMemCacheV3::r_write_to_tgt_rsp_pktid487,18376
+      sc_signal<bool>	   r_write_to_ixr_cmd_req;VciMemCacheV3::r_write_to_ixr_cmd_req490,18537
+      sc_signal<bool>	   r_write_to_ixr_cmd_write;VciMemCacheV3::r_write_to_ixr_cmd_write491,18608
+      sc_signal<addr_t>    r_write_to_ixr_cmd_nline;VciMemCacheV3::r_write_to_ixr_cmd_nline492,18679
+      sc_signal<data_t>	  *r_write_to_ixr_cmd_data;VciMemCacheV3::r_write_to_ixr_cmd_data493,18753
+      sc_signal<size_t>    r_write_to_ixr_cmd_trdid;VciMemCacheV3::r_write_to_ixr_cmd_trdid494,18828
+      sc_signal<bool>	   r_write_to_init_cmd_multi_req;VciMemCacheV3::r_write_to_init_cmd_multi_req497,18993
+      sc_signal<bool>	   r_write_to_init_cmd_brdcast_req;VciMemCacheV3::r_write_to_init_cmd_brdcast_req498,19078
+      sc_signal<addr_t>	   r_write_to_init_cmd_nline;VciMemCacheV3::r_write_to_init_cmd_nline499,19161
+      sc_signal<size_t>	   r_write_to_init_cmd_trdid;VciMemCacheV3::r_write_to_init_cmd_trdid500,19239
+      sc_signal<data_t>   *r_write_to_init_cmd_data;VciMemCacheV3::r_write_to_init_cmd_data501,19322
+      sc_signal<bool>     *r_write_to_init_cmd_we;VciMemCacheV3::r_write_to_init_cmd_we502,19404
+      sc_signal<size_t>	   r_write_to_init_cmd_count;VciMemCacheV3::r_write_to_init_cmd_count503,19478
+      sc_signal<size_t>	   r_write_to_init_cmd_index;VciMemCacheV3::r_write_to_init_cmd_index504,19563
+      GenericFifo<bool>    m_write_to_init_cmd_inst_fifo;VciMemCacheV3::m_write_to_init_cmd_inst_fifo505,19652
+      GenericFifo<size_t>  m_write_to_init_cmd_srcid_fifo;VciMemCacheV3::m_write_to_init_cmd_srcid_fifo506,19736
+      sc_signal<bool>      r_write_to_init_rsp_req;VciMemCacheV3::r_write_to_init_rsp_req509,19889
+      sc_signal<size_t>    r_write_to_init_rsp_upt_index;VciMemCacheV3::r_write_to_init_rsp_upt_index510,19966
+      sc_signal<int> 	   r_init_rsp_fsm;VciMemCacheV3::r_init_rsp_fsm516,20228
+      sc_signal<size_t>	   r_init_rsp_upt_index;VciMemCacheV3::r_init_rsp_upt_index517,20289
+      sc_signal<size_t>	   r_init_rsp_srcid;VciMemCacheV3::r_init_rsp_srcid518,20368
+      sc_signal<size_t>	   r_init_rsp_trdid;VciMemCacheV3::r_init_rsp_trdid519,20444
+      sc_signal<size_t>	   r_init_rsp_pktid;VciMemCacheV3::r_init_rsp_pktid520,20520
+      sc_signal<addr_t>	   r_init_rsp_nline;VciMemCacheV3::r_init_rsp_nline521,20596
+      sc_signal<bool>	     r_init_rsp_to_tgt_rsp_req;VciMemCacheV3::r_init_rsp_to_tgt_rsp_req524,20762
+      sc_signal<size_t>	   r_init_rsp_to_tgt_rsp_srcid;VciMemCacheV3::r_init_rsp_to_tgt_rsp_srcid525,20836
+      sc_signal<size_t>	   r_init_rsp_to_tgt_rsp_trdid;VciMemCacheV3::r_init_rsp_to_tgt_rsp_trdid526,20914
+      sc_signal<size_t>	   r_init_rsp_to_tgt_rsp_pktid;VciMemCacheV3::r_init_rsp_to_tgt_rsp_pktid527,20992
+      sc_signal<int> 	     r_cleanup_fsm;VciMemCacheV3::r_cleanup_fsm533,21241
+      sc_signal<size_t>      r_cleanup_srcid;VciMemCacheV3::r_cleanup_srcid534,21304
+      sc_signal<size_t>      r_cleanup_trdid;VciMemCacheV3::r_cleanup_trdid535,21377
+      sc_signal<size_t>      r_cleanup_pktid;VciMemCacheV3::r_cleanup_pktid536,21450
+      sc_signal<addr_t>      r_cleanup_nline;VciMemCacheV3::r_cleanup_nline537,21523
+      sc_signal<copy_t>      r_cleanup_copy;VciMemCacheV3::r_cleanup_copy539,21596
+      sc_signal<size_t>      r_cleanup_copy_inst;VciMemCacheV3::r_cleanup_copy_inst540,21662
+      sc_signal<copy_t>      r_cleanup_count;VciMemCacheV3::r_cleanup_count541,21740
+      sc_signal<size_t>      r_cleanup_ptr;VciMemCacheV3::r_cleanup_ptr542,21813
+      sc_signal<size_t>      r_cleanup_prev_ptr;VciMemCacheV3::r_cleanup_prev_ptr543,21888
+      sc_signal<size_t>      r_cleanup_prev_srcid;VciMemCacheV3::r_cleanup_prev_srcid544,21972
+      sc_signal<bool>        r_cleanup_prev_inst;VciMemCacheV3::r_cleanup_prev_inst545,22056
+      sc_signal<size_t>      r_cleanup_next_ptr;VciMemCacheV3::r_cleanup_next_ptr546,22143
+      sc_signal<tag_t>       r_cleanup_tag;VciMemCacheV3::r_cleanup_tag547,22223
+      sc_signal<bool>        r_cleanup_is_cnt;VciMemCacheV3::r_cleanup_is_cnt548,22308
+      sc_signal<bool>        r_cleanup_lock;VciMemCacheV3::r_cleanup_lock549,22387
+      sc_signal<bool>        r_cleanup_inst;VciMemCacheV3::r_cleanup_inst550,22463
+      sc_signal<bool>        r_cleanup_dirty;VciMemCacheV3::r_cleanup_dirty551,22539
+      sc_signal<size_t>      r_cleanup_way;VciMemCacheV3::r_cleanup_way552,22617
+      sc_signal<size_t>      r_cleanup_write_srcid;VciMemCacheV3::r_cleanup_write_srcid554,22700
+      sc_signal<size_t>      r_cleanup_write_trdid;VciMemCacheV3::r_cleanup_write_trdid555,22779
+      sc_signal<size_t>      r_cleanup_write_pktid;VciMemCacheV3::r_cleanup_write_pktid556,22853
+      sc_signal<bool>        r_cleanup_need_rsp;VciMemCacheV3::r_cleanup_need_rsp557,22927
+      sc_signal<size_t>      r_cleanup_index;VciMemCacheV3::r_cleanup_index559,23001
+      sc_signal<bool>      r_cleanup_to_tgt_rsp_req;VciMemCacheV3::r_cleanup_to_tgt_rsp_req562,23182
+      sc_signal<size_t>    r_cleanup_to_tgt_rsp_srcid;VciMemCacheV3::r_cleanup_to_tgt_rsp_srcid563,23255
+      sc_signal<size_t>    r_cleanup_to_tgt_rsp_trdid;VciMemCacheV3::r_cleanup_to_tgt_rsp_trdid564,23332
+      sc_signal<size_t>    r_cleanup_to_tgt_rsp_pktid;VciMemCacheV3::r_cleanup_to_tgt_rsp_pktid565,23408
+      sc_signal<int>       r_llsc_fsm;VciMemCacheV3::r_llsc_fsm571,23652
+      sc_signal<data_t>	   r_llsc_data;VciMemCacheV3::r_llsc_data572,23713
+      sc_signal<copy_t>    r_llsc_copy;VciMemCacheV3::r_llsc_copy573,23776
+      sc_signal<bool>      r_llsc_copy_inst;VciMemCacheV3::r_llsc_copy_inst574,23848
+      sc_signal<size_t>    r_llsc_count;VciMemCacheV3::r_llsc_count575,23919
+      sc_signal<size_t>    r_llsc_ptr;VciMemCacheV3::r_llsc_ptr576,23984
+      sc_signal<size_t>    r_llsc_next_ptr;VciMemCacheV3::r_llsc_next_ptr577,24052
+      sc_signal<bool>      r_llsc_is_cnt;VciMemCacheV3::r_llsc_is_cnt578,24126
+      sc_signal<bool>      r_llsc_dirty;VciMemCacheV3::r_llsc_dirty579,24201
+      sc_signal<bool>      r_llsc_inst;VciMemCacheV3::r_llsc_inst580,24274
+      sc_signal<size_t>    r_llsc_way;VciMemCacheV3::r_llsc_way581,24334
+      sc_signal<size_t>    r_llsc_set;VciMemCacheV3::r_llsc_set582,24398
+      sc_signal<data_t>    r_llsc_tag;VciMemCacheV3::r_llsc_tag583,24462
+      sc_signal<size_t>    r_llsc_trt_index;VciMemCacheV3::r_llsc_trt_index584,24539
+      sc_signal<size_t>    r_llsc_upt_index;VciMemCacheV3::r_llsc_upt_index585,24614
+      sc_signal<bool>	   r_llsc_to_ixr_cmd_req;VciMemCacheV3::r_llsc_to_ixr_cmd_req588,24748
+      sc_signal<addr_t>	   r_llsc_to_ixr_cmd_nline;VciMemCacheV3::r_llsc_to_ixr_cmd_nline589,24815
+      sc_signal<size_t>	   r_llsc_to_ixr_cmd_trdid;VciMemCacheV3::r_llsc_to_ixr_cmd_trdid590,24887
+      sc_signal<bool>	   r_llsc_to_ixr_cmd_write;VciMemCacheV3::r_llsc_to_ixr_cmd_write591,24969
+      sc_signal<data_t>	  *r_llsc_to_ixr_cmd_data;VciMemCacheV3::r_llsc_to_ixr_cmd_data592,25036
+      sc_signal<bool>	   r_llsc_to_tgt_rsp_req;VciMemCacheV3::r_llsc_to_tgt_rsp_req596,25158
+      sc_signal<data_t>    r_llsc_to_tgt_rsp_data;VciMemCacheV3::r_llsc_to_tgt_rsp_data597,25225
+      sc_signal<size_t>	   r_llsc_to_tgt_rsp_srcid;VciMemCacheV3::r_llsc_to_tgt_rsp_srcid598,25295
+      sc_signal<size_t>	   r_llsc_to_tgt_rsp_trdid;VciMemCacheV3::r_llsc_to_tgt_rsp_trdid599,25368
+      sc_signal<size_t>	   r_llsc_to_tgt_rsp_pktid;VciMemCacheV3::r_llsc_to_tgt_rsp_pktid600,25441
+      sc_signal<bool>	   r_llsc_to_init_cmd_multi_req;VciMemCacheV3::r_llsc_to_init_cmd_multi_req603,25595
+      sc_signal<bool>	   r_llsc_to_init_cmd_brdcast_req;VciMemCacheV3::r_llsc_to_init_cmd_brdcast_req604,25670
+      sc_signal<addr_t>	   r_llsc_to_init_cmd_nline;VciMemCacheV3::r_llsc_to_init_cmd_nline605,25747
+      sc_signal<size_t>	   r_llsc_to_init_cmd_trdid;VciMemCacheV3::r_llsc_to_init_cmd_trdid606,25824
+      sc_signal<data_t>    r_llsc_to_init_cmd_wdata;VciMemCacheV3::r_llsc_to_init_cmd_wdata607,25906
+      sc_signal<size_t>	   r_llsc_to_init_cmd_index;VciMemCacheV3::r_llsc_to_init_cmd_index608,25985
+      GenericFifo<bool>    m_llsc_to_init_cmd_inst_fifo;VciMemCacheV3::m_llsc_to_init_cmd_inst_fifo609,26071
+      GenericFifo<size_t>  m_llsc_to_init_cmd_srcid_fifo;VciMemCacheV3::m_llsc_to_init_cmd_srcid_fifo610,26155
+      sc_signal<bool>      r_llsc_to_init_rsp_req;VciMemCacheV3::r_llsc_to_init_rsp_req613,26307
+      sc_signal<size_t>    r_llsc_to_init_rsp_upt_index;VciMemCacheV3::r_llsc_to_init_rsp_upt_index614,26384
+      sc_signal<int> 	   r_ixr_rsp_fsm;VciMemCacheV3::r_ixr_rsp_fsm620,26638
+      sc_signal<size_t>	   r_ixr_rsp_trt_index;VciMemCacheV3::r_ixr_rsp_trt_index621,26697
+      sc_signal<size_t>    r_ixr_rsp_cpt;VciMemCacheV3::r_ixr_rsp_cpt622,26764
+      sc_signal<bool>	  *r_ixr_rsp_to_xram_rsp_rok;VciMemCacheV3::r_ixr_rsp_to_xram_rsp_rok625,26906
+      sc_signal<int> 	   r_xram_rsp_fsm;VciMemCacheV3::r_xram_rsp_fsm631,27156
+      sc_signal<size_t>	   r_xram_rsp_trt_index;VciMemCacheV3::r_xram_rsp_trt_index632,27219
+      TransactionTabEntry  r_xram_rsp_trt_buf;VciMemCacheV3::r_xram_rsp_trt_buf633,27291
+      sc_signal<bool>	   r_xram_rsp_victim_inval;VciMemCacheV3::r_xram_rsp_victim_inval634,27369
+      sc_signal<bool>	   r_xram_rsp_victim_is_cnt;VciMemCacheV3::r_xram_rsp_victim_is_cnt635,27450
+      sc_signal<bool>	   r_xram_rsp_victim_dirty;VciMemCacheV3::r_xram_rsp_victim_dirty636,27528
+      sc_signal<size_t>    r_xram_rsp_victim_way;VciMemCacheV3::r_xram_rsp_victim_way637,27607
+      sc_signal<size_t>    r_xram_rsp_victim_set;VciMemCacheV3::r_xram_rsp_victim_set638,27680
+      sc_signal<addr_t>    r_xram_rsp_victim_nline;VciMemCacheV3::r_xram_rsp_victim_nline639,27753
+      sc_signal<copy_t>    r_xram_rsp_victim_copy;VciMemCacheV3::r_xram_rsp_victim_copy640,27830
+      sc_signal<bool>      r_xram_rsp_victim_copy_inst;VciMemCacheV3::r_xram_rsp_victim_copy_inst641,27909
+      sc_signal<size_t>    r_xram_rsp_victim_count;VciMemCacheV3::r_xram_rsp_victim_count642,27999
+      sc_signal<size_t>    r_xram_rsp_victim_ptr;VciMemCacheV3::r_xram_rsp_victim_ptr643,28087
+      sc_signal<data_t>	  *r_xram_rsp_victim_data;VciMemCacheV3::r_xram_rsp_victim_data644,28178
+      sc_signal<size_t>	   r_xram_rsp_upt_index;VciMemCacheV3::r_xram_rsp_upt_index645,28253
+      sc_signal<size_t>    r_xram_rsp_next_ptr;VciMemCacheV3::r_xram_rsp_next_ptr646,28325
+      sc_signal<bool>	   r_xram_rsp_to_tgt_rsp_req;VciMemCacheV3::r_xram_rsp_to_tgt_rsp_req649,28487
+      sc_signal<size_t>    r_xram_rsp_to_tgt_rsp_srcid;VciMemCacheV3::r_xram_rsp_to_tgt_rsp_srcid650,28556
+      sc_signal<size_t>    r_xram_rsp_to_tgt_rsp_trdid;VciMemCacheV3::r_xram_rsp_to_tgt_rsp_trdid651,28633
+      sc_signal<size_t>    r_xram_rsp_to_tgt_rsp_pktid;VciMemCacheV3::r_xram_rsp_to_tgt_rsp_pktid652,28710
+      sc_signal<data_t>   *r_xram_rsp_to_tgt_rsp_data;VciMemCacheV3::r_xram_rsp_to_tgt_rsp_data653,28787
+      sc_signal<size_t>    r_xram_rsp_to_tgt_rsp_word;VciMemCacheV3::r_xram_rsp_to_tgt_rsp_word654,28867
+      sc_signal<size_t>    r_xram_rsp_to_tgt_rsp_length;VciMemCacheV3::r_xram_rsp_to_tgt_rsp_length655,28943
+      sc_signal<bool>	    r_xram_rsp_to_init_cmd_multi_req;VciMemCacheV3::r_xram_rsp_to_init_cmd_multi_req658,29099
+      sc_signal<bool>       r_xram_rsp_to_init_cmd_brdcast_req;VciMemCacheV3::r_xram_rsp_to_init_cmd_brdcast_req659,29182
+      sc_signal<addr_t>     r_xram_rsp_to_init_cmd_nline;VciMemCacheV3::r_xram_rsp_to_init_cmd_nline660,29271
+      sc_signal<size_t>	    r_xram_rsp_to_init_cmd_trdid;VciMemCacheV3::r_xram_rsp_to_init_cmd_trdid661,29360
+      GenericFifo<bool>     m_xram_rsp_to_init_cmd_inst_fifo;VciMemCacheV3::m_xram_rsp_to_init_cmd_inst_fifo662,29450
+      GenericFifo<size_t>   m_xram_rsp_to_init_cmd_srcid_fifo;VciMemCacheV3::m_xram_rsp_to_init_cmd_srcid_fifo663,29542
+      sc_signal<bool>	   r_xram_rsp_to_ixr_cmd_req;VciMemCacheV3::r_xram_rsp_to_ixr_cmd_req666,29696
+      sc_signal<addr_t>	   r_xram_rsp_to_ixr_cmd_nline;VciMemCacheV3::r_xram_rsp_to_ixr_cmd_nline667,29765
+      sc_signal<data_t>	  *r_xram_rsp_to_ixr_cmd_data;VciMemCacheV3::r_xram_rsp_to_ixr_cmd_data668,29841
+      sc_signal<size_t>	   r_xram_rsp_to_ixr_cmd_trdid;VciMemCacheV3::r_xram_rsp_to_ixr_cmd_trdid669,29915
+      sc_signal<int> 	   r_ixr_cmd_fsm;VciMemCacheV3::r_ixr_cmd_fsm675,30170
+      sc_signal<size_t>	   r_ixr_cmd_cpt;VciMemCacheV3::r_ixr_cmd_cpt676,30210
+      sc_signal<int> 	   r_tgt_rsp_fsm;VciMemCacheV3::r_tgt_rsp_fsm682,30417
+      sc_signal<size_t>    r_tgt_rsp_cpt;VciMemCacheV3::r_tgt_rsp_cpt683,30457
+      sc_signal<int> 	  r_init_cmd_fsm;VciMemCacheV3::r_init_cmd_fsm689,30665
+      sc_signal<size_t>   r_init_cmd_cpt;VciMemCacheV3::r_init_cmd_cpt690,30705
+      sc_signal<bool>     r_init_cmd_inst;VciMemCacheV3::r_init_cmd_inst691,30747
+      sc_signal<int> 		r_alloc_dir_fsm;VciMemCacheV3::r_alloc_dir_fsm697,30957
+      sc_signal<int> 		r_alloc_trt_fsm;VciMemCacheV3::r_alloc_trt_fsm703,31164
+      sc_signal<int> 		r_alloc_upt_fsm;VciMemCacheV3::r_alloc_upt_fsm709,31371
+      sc_signal<int> 		r_alloc_heap_fsm;VciMemCacheV3::r_alloc_heap_fsm715,31579
+
+
+../include/xram_transaction_v3.h,2560
+#define XRAM_TRANSACTION_V3_H_2,31
+#define DEBUG_XRAM_TRANSACTION 11,189
+class TransactionTabEntry 17,423
+  typedef uint32_t size_t;TransactionTabEntry::size_t18,451
+  typedef uint32_t data_t;TransactionTabEntry::data_t19,478
+  typedef sc_dt::sc_uint<40> addr_t;TransactionTabEntry::addr_t20,505
+  typedef uint32_t be_t;TransactionTabEntry::be_t21,542
+  bool 		      valid;TransactionTabEntry::valid24,577
+  bool 		      xram_read;TransactionTabEntry::xram_read25,624
+  addr_t   	      nline;TransactionTabEntry::nline26,679
+  size_t 	      srcid;TransactionTabEntry::srcid27,748
+  size_t 	      trdid;TransactionTabEntry::trdid28,820
+  size_t 	      pktid;TransactionTabEntry::pktid29,892
+  bool 		      proc_read;TransactionTabEntry::proc_read30,964
+  size_t 		  read_length;TransactionTabEntry::read_length31,1025
+  size_t 	      word_index;TransactionTabEntry::word_index32,1097
+  std::vector<data_t> wdata;TransactionTabEntry::wdata33,1180
+  std::vector<be_t>   wdata_be;TransactionTabEntry::wdata_be34,1249
+  void init(TransactionTabEntry::init38,1517
+  void alloc(TransactionTabEntry::alloc48,1846
+  void copy(TransactionTabEntry::copy63,2326
+  void print(TransactionTabEntry::print81,2990
+  TransactionTabEntry(TransactionTabEntry::TransactionTabEntry104,4002
+  TransactionTabEntry(TransactionTabEntry::TransactionTabEntry111,4103
+class TransactionTab{TransactionTab130,4838
+  typedef uint32_t size_t;TransactionTab::size_t131,4860
+  typedef uint32_t data_t;TransactionTab::data_t132,4887
+  typedef sc_dt::sc_uint<40> addr_t;TransactionTab::addr_t133,4914
+  typedef uint32_t be_t;TransactionTab::be_t134,4951
+  size_t size_tab;TransactionTab::size_tab137,4987
+  data_t be_to_mask(TransactionTab::be_to_mask139,5045
+  TransactionTabEntry *tab;TransactionTab::tab158,5352
+  TransactionTab(TransactionTab::TransactionTab163,5571
+  TransactionTab(TransactionTab::TransactionTab169,5637
+  ~TransactionTab(TransactionTab::~TransactionTab178,5860
+  size_t size(TransactionTab::size186,6111
+  void init(TransactionTab::init194,6366
+  void print(TransactionTab::print206,6722
+  TransactionTabEntry read(TransactionTab::read219,7167
+  bool full(TransactionTab::full232,7671
+  bool hit_read(TransactionTab::hit_read251,8295
+  bool hit_write(TransactionTab::hit_write269,8916
+  void write_data_mask(TransactionTab::write_data_mask288,9563
+  void set(TransactionTab::set322,11155
+  void write_rsp(TransactionTab::write_rsp365,12790
+  void erase(TransactionTab::erase394,13815
Index: trunk/platforms/almos-tsarv3-platforms/common/vci_mem_cache_v3/caba/source/src/vci_mem_cache_v3.cpp
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/vci_mem_cache_v3/caba/source/src/vci_mem_cache_v3.cpp	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/vci_mem_cache_v3/caba/source/src/vci_mem_cache_v3.cpp	(revision 259)
@@ -0,0 +1,4807 @@
+/* -*- c++ -*-
+ * File 	: vci_mem_cache_v3.cpp
+ * Date 	: 30/10/2008
+ * Copyright 	: UPMC / LIP6
+ * Authors 	: Alain Greiner / Eric Guthmuller
+ *
+ * SOCLIB_LGPL_HEADER_BEGIN
+ *
+ * This file is part of SoCLib, GNU LGPLv2.1.
+ *
+ * SoCLib is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; version 2.1 of the License.
+ *
+ * SoCLib is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with SoCLib; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * SOCLIB_LGPL_HEADER_END
+ *
+ * Maintainers: alain eric.guthmuller@polytechnique.edu
+ */
+#include "../include/vci_mem_cache_v3.h"
+
+//#define TDEBUG // Transaction tab debug
+//#define IDEBUG // Update tab debug
+//#define DDEBUG // Directory debug
+//#define DEBUG_VCI_MEM_CACHE 1
+
+#define MEMC_INI_ID  8196 
+
+#define TRACE_MSG(...)                                                  \
+    do{                                                                 \
+        if((m_total_cycles > m_debug_start) || (current_waiting >= m_wait_threshold)) \
+            __VA_ARGS__;                                                \
+    }while(0)
+
+#define DUMP_UPDATE_TABLE                            \
+    do{                                         \
+        if((m_total_cycles > m_debug_start) || (current_waiting >= m_wait_threshold)) \
+            m_update_tab.print();                                       \
+    }while(0)
+
+
+#define DUMP_TRANSACTION_TABLE                            \
+    do{                                         \
+        if((m_total_cycles > m_debug_start) || (current_waiting >= m_wait_threshold)) { \
+            for(size_t i = 0 ; i < m_transaction_tab.size() ; i++)      \
+                m_transaction_tab.print(i, m_log);                      \
+        }                                                               \
+    }while(0)
+
+
+#define DUMP_ENTRY(x)  \
+    do {                                                                \
+        if((m_total_cycles > m_debug_start) || (current_waiting >= m_wait_threshold)) \
+            entry.print();                                              \
+    }while(0)
+
+namespace soclib { namespace caba {
+
+  const char *tgt_cmd_fsm_str[] = {
+    "TGT_CMD_IDLE",
+    "TGT_CMD_READ",
+    "TGT_CMD_READ_EOP",
+    "TGT_CMD_WRITE",
+    "TGT_CMD_ATOMIC",
+  };
+  const char *tgt_rsp_fsm_str[] = {
+    "TGT_RSP_READ_IDLE",
+    "TGT_RSP_WRITE_IDLE",
+    "TGT_RSP_LLSC_IDLE",
+    "TGT_RSP_XRAM_IDLE",
+    "TGT_RSP_INIT_IDLE",
+    "TGT_RSP_CLEANUP_IDLE",
+    "TGT_RSP_READ",
+    "TGT_RSP_WRITE",
+    "TGT_RSP_LLSC",
+    "TGT_RSP_XRAM",
+    "TGT_RSP_INIT",
+    "TGT_RSP_CLEANUP",
+  };
+  const char *init_cmd_fsm_str[] = {
+    "INIT_CMD_INVAL_IDLE",
+    "INIT_CMD_INVAL_NLINE",
+    "INIT_CMD_XRAM_BRDCAST",
+    "INIT_CMD_UPDT_IDLE",
+    "INIT_CMD_WRITE_BRDCAST",
+    "INIT_CMD_UPDT_NLINE",
+    "INIT_CMD_UPDT_INDEX",
+    "INIT_CMD_UPDT_DATA",
+    "INIT_CMD_SC_UPDT_IDLE",
+    "INIT_CMD_SC_BRDCAST",
+    "INIT_CMD_SC_UPDT_NLINE",
+    "INIT_CMD_SC_UPDT_INDEX",
+    "INIT_CMD_SC_UPDT_DATA",
+  };
+  const char *init_rsp_fsm_str[] = {
+    "INIT_RSP_IDLE",
+    "INIT_RSP_UPT_LOCK",
+    "INIT_RSP_UPT_CLEAR",
+    "INIT_RSP_END",
+  };
+  const char *read_fsm_str[] = {
+    "READ_IDLE",
+    "READ_DIR_LOCK",
+    "READ_DIR_HIT",
+    "READ_HEAP_LOCK",
+    "READ_HEAP_WRITE",
+    "READ_HEAP_ERASE",
+    "READ_HEAP_LAST",
+    "READ_RSP",
+    "READ_TRT_LOCK",
+    "READ_TRT_SET",
+    "READ_XRAM_REQ",
+  };
+  const char *write_fsm_str[] = {
+    "WRITE_IDLE",
+    "WRITE_NEXT",
+    "WRITE_DIR_LOCK",
+    "WRITE_DIR_HIT_READ",
+    "WRITE_DIR_HIT",
+    "WRITE_DIR_HIT_RSP",
+    "WRITE_UPT_LOCK",
+    "WRITE_HEAP_LOCK",
+    "WRITE_UPT_REQ",
+    "WRITE_UPDATE",
+    "WRITE_UPT_DEC",
+    "WRITE_RSP",
+    "WRITE_TRT_LOCK",
+    "WRITE_TRT_DATA",
+    "WRITE_TRT_SET",
+    "WRITE_WAIT",
+    "WRITE_XRAM_REQ",
+    "WRITE_TRT_WRITE_LOCK",
+    "WRITE_INVAL_LOCK",
+    "WRITE_DIR_INVAL",
+    "WRITE_INVAL",
+    "WRITE_XRAM_SEND",
+    "WRITE_HEAP_ERASE",
+    "WRITE_HEAP_LAST",
+  };
+  const char *ixr_rsp_fsm_str[] = {
+    "IXR_RSP_IDLE",
+    "IXR_RSP_ACK",
+    "IXR_RSP_TRT_ERASE",
+    "IXR_RSP_TRT_READ",
+  };
+  const char *xram_rsp_fsm_str[] = {
+    "XRAM_RSP_IDLE",
+    "XRAM_RSP_TRT_COPY",
+    "XRAM_RSP_TRT_DIRTY",
+    "XRAM_RSP_DIR_LOCK",
+    "XRAM_RSP_DIR_UPDT",
+    "XRAM_RSP_DIR_RSP",
+    "XRAM_RSP_INVAL_LOCK",
+    "XRAM_RSP_INVAL_WAIT",
+    "XRAM_RSP_INVAL",
+    "XRAM_RSP_WRITE_DIRTY",
+    "XRAM_RSP_HEAP_ERASE",
+    "XRAM_RSP_HEAP_LAST",
+  };
+  const char *ixr_cmd_fsm_str[] = {
+    "IXR_CMD_READ_IDLE",
+    "IXR_CMD_WRITE_IDLE",
+    "IXR_CMD_LLSC_IDLE",
+    "IXR_CMD_XRAM_IDLE",
+    "IXR_CMD_READ_NLINE",
+    "IXR_CMD_WRITE_NLINE",
+    "IXR_CMD_LLSC_NLINE",
+    "IXR_CMD_XRAM_DATA",
+  };
+  const char *llsc_fsm_str[] = {
+    "LLSC_IDLE",
+    "LL_DIR_LOCK",
+    "LL_DIR_HIT",
+    "LL_RSP",
+    "SC_DIR_LOCK",
+    "SC_DIR_HIT",
+    "SC_UPT_LOCK",
+    "SC_WAIT",
+    "SC_HEAP_LOCK",
+    "SC_UPT_REQ",
+    "SC_UPDATE",
+    "SC_TRT_LOCK",
+    "SC_INVAL_LOCK",
+    "SC_DIR_INVAL",
+    "SC_INVAL",
+    "SC_XRAM_SEND",
+    "SC_HEAP_ERASE",
+    "SC_HEAP_LAST",
+    "SC_RSP_FALSE",
+    "SC_RSP_TRUE",
+    "LLSC_TRT_LOCK",
+    "LLSC_TRT_SET",
+    "LLSC_XRAM_REQ",
+  };
+  const char *cleanup_fsm_str[] = {
+    "CLEANUP_IDLE",
+    "CLEANUP_DIR_LOCK",
+    "CLEANUP_DIR_WRITE",
+    "CLEANUP_HEAP_LOCK",
+    "CLEANUP_HEAP_SEARCH",
+    "CLEANUP_HEAP_CLEAN",
+    "CLEANUP_HEAP_FREE",
+    "CLEANUP_UPT_LOCK",
+    "CLEANUP_UPT_WRITE",
+    "CLEANUP_WRITE_RSP",
+    "CLEANUP_RSP",
+  };
+  const char *alloc_dir_fsm_str[] = {
+    "ALLOC_DIR_READ",
+    "ALLOC_DIR_WRITE",
+    "ALLOC_DIR_LLSC",
+    "ALLOC_DIR_CLEANUP",
+    "ALLOC_DIR_XRAM_RSP",
+  };
+  const char *alloc_trt_fsm_str[] = {
+    "ALLOC_TRT_READ",
+    "ALLOC_TRT_WRITE",
+    "ALLOC_TRT_LLSC",
+    "ALLOC_TRT_XRAM_RSP",
+    "ALLOC_TRT_IXR_RSP",
+  };
+  const char *alloc_upt_fsm_str[] = {
+    "ALLOC_UPT_WRITE",
+    "ALLOC_UPT_XRAM_RSP",
+    "ALLOC_UPT_INIT_RSP",
+    "ALLOC_UPT_CLEANUP",
+  };
+  const char *alloc_heap_fsm_str[] = {
+    "ALLOC_HEAP_READ",
+    "ALLOC_HEAP_WRITE",
+    "ALLOC_HEAP_LLSC",
+    "ALLOC_HEAP_CLEANUP",
+    "ALLOC_HEAP_XRAM_RSP",
+  };
+
+
+#define tmpl(x) template<typename vci_param> x VciMemCacheV3<vci_param>
+
+  using soclib::common::uint32_log2;
+
+  ////////////////////////////////
+  // 	Constructor 
+  ////////////////////////////////
+
+  tmpl(/**/)::VciMemCacheV3( 
+      sc_module_name name,
+      const soclib::common::MappingTable &mtp,
+      const soclib::common::MappingTable &mtc,
+      const soclib::common::MappingTable &mtx,
+      const soclib::common::IntTab &vci_ixr_index,
+      const soclib::common::IntTab &vci_ini_index,
+      const soclib::common::IntTab &vci_tgt_index,
+      const soclib::common::IntTab &vci_tgt_index_cleanup,
+      size_t nways,
+      size_t nsets,
+      size_t nwords,
+      size_t heap_size)
+
+    : soclib::caba::BaseModule(name),
+
+    p_clk("clk"),
+    p_resetn("resetn"),
+    p_vci_tgt("vci_tgt"),
+    p_vci_tgt_cleanup("vci_tgt_cleanup"),
+    p_vci_ini("vci_ini"),
+    p_vci_ixr("vci_ixr"),
+
+    m_initiators( 1 << vci_param::S ),
+    m_heap_size( heap_size ),
+    m_ways( nways ),
+    m_sets( nsets ),
+    m_words( nwords ),
+    m_srcid_ixr( mtx.indexForId(vci_ixr_index) ),
+    m_srcid_ini( mtc.indexForId(vci_ini_index) ),
+    m_seglist(mtp.getSegmentList(vci_tgt_index)),
+    m_cseglist(mtc.getSegmentList(vci_tgt_index_cleanup)),
+    m_coherence_table( mtc.getCoherenceTable<vci_addr_t>() ),
+    m_atomic_tab( m_initiators ),
+    m_transaction_tab( TRANSACTION_TAB_LINES, nwords ),
+    m_update_tab( UPDATE_TAB_LINES ),
+    m_cache_directory( nways, nsets, nwords, vci_param::N ),
+    m_heap_directory( m_heap_size ),
+
+#define L2 soclib::common::uint32_log2
+    m_x( L2(m_words), 2),
+    m_y( L2(m_sets), L2(m_words) + 2),
+    m_z( vci_param::N - L2(m_sets) - L2(m_words) - 2, L2(m_sets) + L2(m_words) + 2),
+    m_nline( vci_param::N - L2(m_words) - 2, L2(m_words) + 2),
+#undef L2
+
+    //  FIFOs 
+    m_cmd_read_addr_fifo("m_cmd_read_addr_fifo", 4),
+    m_cmd_read_length_fifo("m_cmd_read_length_fifo", 4),
+    m_cmd_read_srcid_fifo("m_cmd_read_srcid_fifo", 4),
+    m_cmd_read_trdid_fifo("m_cmd_read_trdid_fifo", 4),
+    m_cmd_read_pktid_fifo("m_cmd_read_pktid_fifo", 4),
+
+    m_cmd_write_addr_fifo("m_cmd_write_addr_fifo",8),
+    m_cmd_write_eop_fifo("m_cmd_write_eop_fifo",8),
+    m_cmd_write_srcid_fifo("m_cmd_write_srcid_fifo",8),
+    m_cmd_write_trdid_fifo("m_cmd_write_trdid_fifo",8),
+    m_cmd_write_pktid_fifo("m_cmd_write_pktid_fifo",8),
+    m_cmd_write_data_fifo("m_cmd_write_data_fifo",8),
+    m_cmd_write_be_fifo("m_cmd_write_be_fifo",8),
+
+    m_cmd_llsc_addr_fifo("m_cmd_llsc_addr_fifo",4),
+    m_cmd_llsc_sc_fifo("m_cmd_llsc_sc_fifo",4),
+    m_cmd_llsc_srcid_fifo("m_cmd_llsc_srcid_fifo",4),
+    m_cmd_llsc_trdid_fifo("m_cmd_llsc_trdid_fifo",4),
+    m_cmd_llsc_pktid_fifo("m_cmd_llsc_pktid_fifo",4),
+    m_cmd_llsc_wdata_fifo("m_cmd_llsc_wdata_fifo",4),
+
+    r_tgt_cmd_fsm("r_tgt_cmd_fsm"),
+    
+    nseg(0),	
+    ncseg(0),	
+
+    r_read_fsm("r_read_fsm"),
+    r_write_fsm("r_write_fsm"),
+    m_write_to_init_cmd_inst_fifo("m_write_to_init_cmd_inst_fifo",8),
+    m_write_to_init_cmd_srcid_fifo("m_write_to_init_cmd_srcid_fifo",8),
+    r_init_rsp_fsm("r_init_rsp_fsm"),
+    r_cleanup_fsm("r_cleanup_fsm"),
+    r_llsc_fsm("r_llsc_fsm"),
+    m_llsc_to_init_cmd_inst_fifo("m_llsc_to_init_cmd_inst_fifo",8),
+    m_llsc_to_init_cmd_srcid_fifo("m_llsc_to_init_cmd_srcid_fifo",8),
+    r_ixr_rsp_fsm("r_ixr_rsp_fsm"),
+    r_xram_rsp_fsm("r_xram_rsp_fsm"),
+    m_xram_rsp_to_init_cmd_inst_fifo("m_xram_rsp_to_init_cmd_inst_fifo",8),
+    m_xram_rsp_to_init_cmd_srcid_fifo("m_xram_rsp_to_init_cmd_srcid_fifo",8),
+    r_ixr_cmd_fsm("r_ixr_cmd_fsm"),
+    r_tgt_rsp_fsm("r_tgt_rsp_fsm"),
+    r_init_cmd_fsm("r_init_cmd_fsm"),
+    r_alloc_dir_fsm("r_alloc_dir_fsm"),
+    r_alloc_trt_fsm("r_alloc_trt_fsm"),
+    r_alloc_upt_fsm("r_alloc_upt_fsm")
+    {
+      assert(IS_POW_OF_2(nsets));
+      assert(IS_POW_OF_2(nwords));
+      assert(IS_POW_OF_2(nways));
+      assert(nsets);
+      assert(nwords);
+      assert(nways);
+      assert(nsets <= 1024);
+      assert(nwords <= 32);
+      assert(nways <= 32);
+
+      // Set the broadcast address with Xmin,Xmax,Ymin,Ymax set to maximum
+      broadcast_addr = 0x3 | (0x7C1F << (vci_param::N-20));
+
+      // Get the segments associated to the MemCache 
+      std::list<soclib::common::Segment>::iterator seg;
+
+      for(seg = m_seglist.begin(); seg != m_seglist.end() ; seg++) {
+        nseg++;
+      }
+      for(seg = m_cseglist.begin(); seg != m_cseglist.end() ; seg++) {
+        ncseg++;
+      }
+
+      m_seg = new soclib::common::Segment*[nseg];
+      size_t i = 0;
+      for ( seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++ ) { 
+        m_seg[i] = &(*seg);
+        i++;
+      }
+      m_cseg = new soclib::common::Segment*[ncseg];
+      i = 0;
+      for ( seg = m_cseglist.begin() ; seg != m_cseglist.end() ; seg++ ) { 
+          m_cseg[i] = &(*seg);
+          i++;
+      }
+
+      // Memory cache allocation & initialisation
+      m_cache_data = new data_t**[nways];
+      for ( size_t i=0 ; i<nways ; ++i ) {
+        m_cache_data[i] = new data_t*[nsets];
+      }
+      for ( size_t i=0; i<nways; ++i ) {
+        for ( size_t j=0; j<nsets; ++j ) {
+          m_cache_data[i][j] = new data_t[nwords];
+          for ( size_t k=0; k<nwords; k++){
+            m_cache_data[i][j][k]=0;
+          }	
+        }
+      }
+
+      // Allocation for IXR_RSP FSM
+      r_ixr_rsp_to_xram_rsp_rok	    = new sc_signal<bool>[TRANSACTION_TAB_LINES];
+
+      // Allocation for XRAM_RSP FSM
+      r_xram_rsp_victim_data        = new sc_signal<data_t>[nwords];
+      r_xram_rsp_to_tgt_rsp_data    = new sc_signal<data_t>[nwords];
+      r_xram_rsp_to_ixr_cmd_data    = new sc_signal<data_t>[nwords];
+
+      // Allocation for READ FSM
+      r_read_data 			        = new sc_signal<data_t>[nwords];
+      r_read_to_tgt_rsp_data 		= new sc_signal<data_t>[nwords];
+
+      // Allocation for WRITE FSM
+      r_write_data 			        = new sc_signal<data_t>[nwords];
+      r_write_be 			        = new sc_signal<be_t>[nwords];
+      r_write_to_init_cmd_data 		= new sc_signal<data_t>[nwords];
+      r_write_to_init_cmd_we		= new sc_signal<bool>[nwords];
+      r_write_to_ixr_cmd_data	    = new sc_signal<data_t>[nwords];
+
+      // Allocation for LLSC FSM
+      r_llsc_to_ixr_cmd_data	    = new sc_signal<data_t>[nwords];
+
+
+      m_tm_start = 0;
+      m_tm_end = 0;
+      m_period = 0;
+      m_debug_start = 499999999LL;
+
+      char *ptr;
+
+      ptr = getenv("TSAR_MEMC_COPY_THRESHOLD");
+
+      if(ptr != NULL)
+          m_copy_threshold = atol(ptr);
+      else
+          m_copy_threshold = 3;
+      
+      ptr = getenv("TSAR_MEMC_TM_START");
+
+      if(ptr != NULL)
+          m_tm_start = (size_t) atol(ptr);
+
+      ptr = getenv("TSAR_MEMC_TM_END");
+
+      if(ptr != NULL)
+          m_tm_end = (size_t) atol(ptr);
+
+      ptr = getenv("TSAR_MEMC_PERIOD");
+
+      if(ptr != NULL)
+          m_period = (size_t) atol(ptr);
+      
+      ptr = getenv("TSAR_MEMC_DEBUG_START");
+
+      if(ptr != NULL)
+          m_debug_start = (long long) atoll(ptr);
+
+      if(m_period != 0)
+          m_log.open(name, std::ios::out);
+
+      ptr = getenv("TSAR_MEMC_WAIT_THRESHOLD");
+
+      if(ptr != NULL)
+          m_wait_threshold = atof(ptr);
+      else
+          m_wait_threshold = 0.95;
+
+
+      //std::cout << name << " srcid " << m_srcid_ini << std::endl;
+
+      if(m_srcid_ini == 4)
+      {
+          std::cout << "TSAR_MEMC_TM_START    =" << m_tm_start << std::endl
+                    << "TSAR_MEMC_TM_END      =" << m_tm_end << std::endl
+                    << "TSAR_MEMC_PERIOD      =" << m_period << std::endl
+                    << "TSAR_MEMC_DEBUG_START =" << m_debug_start << std::endl
+                    << "CPY_TH                =" << m_copy_threshold << std::endl
+                    << "TRT_TBL               =" << TRANSACTION_TAB_LINES << std::endl
+                    << "UPD_TBL               =" << UPDATE_TAB_LINES << std::endl;
+      }
+  
+      // Simulation
+
+      SC_METHOD(transition);
+      dont_initialize();
+      sensitive << p_clk.pos();
+
+      SC_METHOD(genMoore);
+      dont_initialize();
+      sensitive << p_clk.neg();
+
+    } // end constructor
+
+  /////////////////////////////////////////
+  // This function prints the statistics 
+  /////////////////////////////////////////
+
+  tmpl(void)::clear_stats()
+  {
+      // Activity counters
+      m_cpt_cycles		    = 0;
+      m_cpt_read		    = 0;
+      m_cpt_read_miss	    = 0;
+      m_cpt_write		    = 0;
+      m_cpt_write_miss	    = 0;
+      m_cpt_write_cells	    = 0;
+      m_cpt_write_dirty	    = 0;
+      m_cpt_update		    = 0;
+      m_cpt_update_mult     = 0;
+      m_cpt_inval_brdcast 	= 0;
+      m_cpt_inval 		    = 0;
+      m_cpt_inval_mult 		= 0;
+      m_cpt_cleanup		    = 0;
+      m_cpt_ll     		    = 0;
+      m_cpt_sc     		    = 0;
+      m_waiting_cycles      = 0;
+  }
+
+  tmpl(void)::print_log()
+  {
+      m_log << "----------------------------------" << std::dec << std::endl;
+      m_log << "MEM_CACHE " << m_srcid_ini << " / Time = " << m_total_cycles << std::endl
+            << "READ_RATE             = " << (double)m_cpt_read/m_cpt_cycles << std::endl
+            << "READ_MISS_RATE        = " << (double)m_cpt_read_miss/m_cpt_read << std::endl
+            << "WRITE_RATE            = " << (double)m_cpt_write/m_cpt_cycles << std::endl
+            << "WRITE_MISS_RATE       = " << (double)m_cpt_write_miss/m_cpt_write << std::endl
+            << "WRITE_BURST_LENGTH    = " << (double)m_cpt_write_cells/m_cpt_write << std::endl
+            << "UPDATE_RATE           = " << (double)m_cpt_update/m_cpt_cycles << std::endl
+            << "UPDATE_ARITY          = " << (double)m_cpt_update_mult/m_cpt_update << std::endl
+            << "INVAL_MULTICAST_RATE  = " << (double)(m_cpt_inval-m_cpt_inval_brdcast)/m_cpt_cycles << std::endl
+            << "INVAL_MULTICAST_ARITY = " << (double)m_cpt_inval_mult/(m_cpt_inval-m_cpt_inval_brdcast) << std::endl
+            << "INVAL_BROADCAST_RATE  = " << (double)m_cpt_inval_brdcast/m_cpt_cycles << std::endl
+            << "SAVE_DIRTY_RATE       = " << (double)m_cpt_write_dirty/m_cpt_cycles << std::endl
+            << "CLEANUP_RATE          = " << (double)m_cpt_cleanup/m_cpt_cycles << std::endl
+            << "LL_RATE               = " << (double)m_cpt_ll/m_cpt_cycles << std::endl
+            << "SC_RATE               = " << (double)m_cpt_sc/m_cpt_cycles << std::endl
+            << "TGT_WAITING_%         = " << (double)m_waiting_cycles/m_cpt_cycles << std::endl;
+  }
+
+
+
+  tmpl(void)::print_stats()
+  {
+      std::cout << "----------------------------------" << std::dec << std::endl;
+      std::cout << "MEM_CACHE " << m_srcid_ini << " / Time = " << m_total_cycles << std::endl
+                << "READ_RATE             = " << (double)m_cpt_read/m_cpt_cycles << std::endl
+                << "READ_MISS_RATE        = " << (double)m_cpt_read_miss/m_cpt_read << std::endl
+                << "WRITE_RATE            = " << (double)m_cpt_write/m_cpt_cycles << std::endl
+                << "WRITE_MISS_RATE       = " << (double)m_cpt_write_miss/m_cpt_write << std::endl
+                << "WRITE_BURST_LENGTH    = " << (double)m_cpt_write_cells/m_cpt_write << std::endl
+                << "UPDATE_RATE           = " << (double)m_cpt_update/m_cpt_cycles << std::endl
+                << "UPDATE_ARITY          = " << (double)m_cpt_update_mult/m_cpt_update << std::endl
+                << "INVAL_MULTICAST_RATE  = " << (double)(m_cpt_inval-m_cpt_inval_brdcast)/m_cpt_cycles << std::endl
+                << "INVAL_MULTICAST_ARITY = " << (double)m_cpt_inval_mult/(m_cpt_inval-m_cpt_inval_brdcast) << std::endl
+                << "INVAL_BROADCAST_RATE  = " << (double)m_cpt_inval_brdcast/m_cpt_cycles << std::endl
+                << "SAVE_DIRTY_RATE       = " << (double)m_cpt_write_dirty/m_cpt_cycles << std::endl
+                << "CLEANUP_RATE          = " << (double)m_cpt_cleanup/m_cpt_cycles << std::endl
+                << "LL_RATE               = " << (double)m_cpt_ll/m_cpt_cycles << std::endl
+                << "SC_RATE               = " << (double)m_cpt_sc/m_cpt_cycles << std::endl
+                << "TGT_WAITING_%         = " << (double)m_waiting_cycles/m_cpt_cycles << std::endl;
+  }
+
+  tmpl(void)::print_trace_to_log_file()
+  {
+      m_log << "---------------------------------------------" << std::dec << std::endl;
+      m_log << "MEM_CACHE " << m_srcid_ini << " ; Time = " << m_cpt_cycles << std::endl
+            << " - TGT_CMD FSM    = " << tgt_cmd_fsm_str[r_tgt_cmd_fsm] << std::endl
+            << " - TGT_RSP FSM    = " << tgt_rsp_fsm_str[r_tgt_rsp_fsm] << std::endl
+            << " - INIT_CMD FSM   = " << init_cmd_fsm_str[r_init_cmd_fsm] << std::endl
+            << " - INIT_RSP FSM   = " << init_rsp_fsm_str[r_init_rsp_fsm] << std::endl
+            << " - READ FSM       = " << read_fsm_str[r_read_fsm] << std::endl
+            << " - WRITE FSM      = " << write_fsm_str[r_write_fsm] << std::endl
+            << " - LLSC FSM       = " << llsc_fsm_str[r_llsc_fsm] << std::endl
+            << " - CLEANUP FSM    = " << cleanup_fsm_str[r_cleanup_fsm] << std::endl
+            << " - IXR_CMD FSM    = " << ixr_cmd_fsm_str[r_ixr_cmd_fsm] << std::endl
+            << " - IXR_RSP FSM    = " << ixr_rsp_fsm_str[r_ixr_rsp_fsm] << std::endl
+            << " - XRAM_RSP FSM   = " << xram_rsp_fsm_str[r_xram_rsp_fsm] << std::endl
+            << " - ALLOC_DIR FSM  = " << alloc_dir_fsm_str[r_alloc_dir_fsm] << std::endl
+            << " - ALLOC_TRT FSM  = " << alloc_trt_fsm_str[r_alloc_trt_fsm] << std::endl
+            << " - ALLOC_UPT FSM  = " << alloc_upt_fsm_str[r_alloc_upt_fsm] << std::endl
+            << " - ALLOC_HEAP FSM = " << alloc_heap_fsm_str[r_alloc_heap_fsm] << std::endl;
+  }
+    
+  /////////////////////////////////
+  tmpl(/**/)::~VciMemCacheV3()
+    /////////////////////////////////
+  {
+    for(size_t i=0; i<m_ways ; i++){
+      for(size_t j=0; j<m_sets ; j++){
+        delete [] m_cache_data[i][j];
+      }
+    }
+    for(size_t i=0; i<m_ways ; i++){
+      delete [] m_cache_data[i];
+    }
+    delete [] m_cache_data;
+    delete [] m_coherence_table;
+
+    delete [] r_ixr_rsp_to_xram_rsp_rok;
+
+    delete [] r_xram_rsp_victim_data;
+    delete [] r_xram_rsp_to_tgt_rsp_data;
+    delete [] r_xram_rsp_to_ixr_cmd_data;
+
+    delete [] r_read_data;
+    delete [] r_read_to_tgt_rsp_data;
+
+    delete [] r_write_data;
+    delete [] r_write_be;
+    delete [] r_write_to_init_cmd_data;
+  }
+
+  //////////////////////////////////
+  tmpl(void)::transition()
+    //////////////////////////////////
+  {
+    using soclib::common::uint32_log2;
+    //  RESET          
+    if ( ! p_resetn.read() ) {
+
+      //     Initializing FSMs
+      r_tgt_cmd_fsm 	= TGT_CMD_IDLE;
+      r_tgt_rsp_fsm 	= TGT_RSP_READ_IDLE;
+      r_init_cmd_fsm 	= INIT_CMD_INVAL_IDLE;
+      r_init_rsp_fsm 	= INIT_RSP_IDLE;
+      r_read_fsm 	= READ_IDLE;
+      r_write_fsm 	= WRITE_IDLE;
+      r_llsc_fsm 	= LLSC_IDLE;
+      r_cleanup_fsm 	= CLEANUP_IDLE;
+      r_alloc_dir_fsm   = ALLOC_DIR_READ;
+      r_alloc_trt_fsm   = ALLOC_TRT_READ;
+      r_alloc_upt_fsm   = ALLOC_UPT_WRITE;
+      r_ixr_rsp_fsm 	= IXR_RSP_IDLE;
+      r_xram_rsp_fsm 	= XRAM_RSP_IDLE;
+      r_ixr_cmd_fsm 	= IXR_CMD_READ_IDLE;
+
+      //  Initializing Tables
+      m_cache_directory.init();
+      m_atomic_tab.init();	
+      m_transaction_tab.init();
+      m_heap_directory.init();
+
+      // initializing FIFOs and communication Buffers
+
+      m_cmd_read_addr_fifo.init();
+      m_cmd_read_length_fifo.init();
+      m_cmd_read_srcid_fifo.init();
+      m_cmd_read_trdid_fifo.init();
+      m_cmd_read_pktid_fifo.init();
+
+      m_cmd_write_addr_fifo.init();
+      m_cmd_write_eop_fifo.init();
+      m_cmd_write_srcid_fifo.init();
+      m_cmd_write_trdid_fifo.init();
+      m_cmd_write_pktid_fifo.init();
+      m_cmd_write_data_fifo.init();
+
+      m_cmd_llsc_addr_fifo.init();
+      m_cmd_llsc_srcid_fifo.init();
+      m_cmd_llsc_trdid_fifo.init();
+      m_cmd_llsc_pktid_fifo.init();
+      m_cmd_llsc_wdata_fifo.init();
+      m_cmd_llsc_sc_fifo.init();
+
+      r_read_to_tgt_rsp_req	    = false;
+      r_read_to_ixr_cmd_req	    = false;
+
+      r_write_to_tgt_rsp_req	        = false;
+      r_write_to_ixr_cmd_req	        = false;
+      r_write_to_init_cmd_multi_req	    = false;
+      r_write_to_init_cmd_brdcast_req	= false;
+      r_write_to_init_rsp_req           = false;
+      m_write_to_init_cmd_inst_fifo.init();
+      m_write_to_init_cmd_srcid_fifo.init();
+
+      r_cleanup_to_tgt_rsp_req	= false;
+
+      r_init_rsp_to_tgt_rsp_req	= false;
+
+      r_llsc_to_tgt_rsp_req	            = false;
+      r_llsc_to_ixr_cmd_req	            = false;
+      r_llsc_to_init_cmd_multi_req	    = false;
+      r_llsc_to_init_cmd_brdcast_req	= false;
+      m_llsc_to_init_cmd_inst_fifo.init();
+      m_llsc_to_init_cmd_srcid_fifo.init();
+
+      for(size_t i=0; i<TRANSACTION_TAB_LINES ; i++){
+        r_ixr_rsp_to_xram_rsp_rok[i] = false;
+      }
+
+      r_xram_rsp_to_tgt_rsp_req	            = false;
+      r_xram_rsp_to_init_cmd_multi_req      = false;
+      r_xram_rsp_to_init_cmd_brdcast_req    = false;
+      r_xram_rsp_to_ixr_cmd_req	            = false;
+      r_xram_rsp_trt_index	                = 0;
+      m_xram_rsp_to_init_cmd_inst_fifo.init();
+      m_xram_rsp_to_init_cmd_srcid_fifo.init();
+
+      r_ixr_cmd_cpt         = 0;
+
+      r_copies_limit        = m_copy_threshold;
+      m_total_cycles = 0;
+      clear_stats();
+      return;
+    }
+
+    double current_waiting = 0;
+
+    if(m_period != 0)
+    {
+        size_t current_period;
+
+        current_period  = (m_cpt_cycles == 0) ? 1 : m_cpt_cycles;
+        current_waiting = (double)(m_waiting_cycles / current_period);
+        
+        if(current_waiting > m_wait_threshold)
+            print_trace_to_log_file();
+    }
+
+    bool    cmd_read_fifo_put = false;
+    bool    cmd_read_fifo_get = false;
+
+    bool    cmd_write_fifo_put = false;
+    bool    cmd_write_fifo_get = false;
+
+    bool    cmd_llsc_fifo_put = false;
+    bool    cmd_llsc_fifo_get = false;
+
+    bool    write_to_init_cmd_fifo_put   = false;
+    bool    write_to_init_cmd_fifo_get   = false;
+    bool    write_to_init_cmd_fifo_inst  = false;
+    size_t  write_to_init_cmd_fifo_srcid = 0;
+
+    bool    xram_rsp_to_init_cmd_fifo_put   = false;
+    bool    xram_rsp_to_init_cmd_fifo_get   = false;
+    bool    xram_rsp_to_init_cmd_fifo_inst  = false;
+    size_t  xram_rsp_to_init_cmd_fifo_srcid = 0;
+
+    bool    llsc_to_init_cmd_fifo_put   = false;
+    bool    llsc_to_init_cmd_fifo_get   = false;
+    bool    llsc_to_init_cmd_fifo_inst  = false;
+    size_t  llsc_to_init_cmd_fifo_srcid = 0;
+
+
+    ////////////////////////////////////////////////////////////////////////////////////
+    //		TGT_CMD FSM
+    ////////////////////////////////////////////////////////////////////////////////////
+    // The TGT_CMD_FSM controls the incoming VCI command pakets from the processors
+    //
+    // There is 4 types of packets for the m_mem_segment :
+    // - READ    : a READ request has a length of 1 VCI cell. It can be a single word 
+    //             or an entire cache line, depending on the PLEN value.
+    // - WRITE   : a WRITE request has a maximum length of 16 cells, and can only
+    //             concern words in a same line.
+    // - LL      : The LL request has a length of 1 cell.
+    // - SC      : The SC request has a length of 1 cell. 
+    //             The WDATA field contains the data to write.
+    //
+    ////////////////////////////////////////////////////////////////////////////////////
+
+    switch ( r_tgt_cmd_fsm.read() ) {
+
+      //////////////////
+      case TGT_CMD_IDLE:
+        {
+          if ( p_vci_tgt.cmdval ) 
+          {
+              m_waiting_cycles ++;
+
+              assert( (p_vci_tgt.srcid.read() < m_initiators)
+                      && "VCI_MEM_CACHE error in VCI_MEM_CACHE : The received SRCID is larger than the number of initiators");
+              
+              bool reached = false;
+              for ( size_t index = 0 ; index < nseg && !reached ; index++) 
+              {
+                  //              if ( m_seg[index]->contains((addr_t)(p_vci_tgt.address.read())) ) {
+                  if ( m_seg[index]->contains(p_vci_tgt.address.read()) ) {
+                      reached = true;
+                      r_index = index;
+                  }
+              }
+
+
+              if ( !reached ) 
+              { 
+                  std::cout << "VCI_MEM_CACHE Out of segment access in VCI_MEM_CACHE" << std::endl;
+                  std::cout << "Faulty address = " << std::hex << (addr_t)(p_vci_tgt.address.read()) << std::endl;
+                  std::cout << "Faulty initiator = " << std::dec << p_vci_tgt.srcid.read() << std::endl;
+                  exit(0);
+              } 
+              else if ( p_vci_tgt.cmd.read() == vci_param::CMD_READ ) 
+              {
+                  r_tgt_cmd_fsm = TGT_CMD_READ;
+              } 
+              else if ( p_vci_tgt.cmd.read() == vci_param::CMD_WRITE )
+              {  
+                  r_tgt_cmd_fsm = TGT_CMD_WRITE;
+              } 
+              else if ((p_vci_tgt.cmd.read() == vci_param::CMD_LOCKED_READ) || 
+                       (p_vci_tgt.cmd.read() == vci_param::CMD_STORE_COND) ) 
+              {
+                  r_tgt_cmd_fsm = TGT_CMD_ATOMIC;
+              } 
+          }
+          break;
+        }
+        //////////////////
+      case TGT_CMD_READ:
+
+        {
+          assert(((m_x[(vci_addr_t)p_vci_tgt.address.read()]+(p_vci_tgt.plen.read()>>2))<=16)
+              && "VCI_MEM_CACHE All read request to the MemCache must stay within a cache line"); 
+
+          m_waiting_cycles ++;
+
+          if ( p_vci_tgt.cmdval && m_cmd_read_addr_fifo.wok() ) {
+            cmd_read_fifo_put = true;
+            if ( p_vci_tgt.eop )  r_tgt_cmd_fsm = TGT_CMD_IDLE;
+            else                  r_tgt_cmd_fsm = TGT_CMD_READ_EOP;		
+          } 
+          break;
+        }
+        //////////////////////
+      case TGT_CMD_READ_EOP:
+        {
+            m_waiting_cycles ++;
+         
+            if ( p_vci_tgt.cmdval && p_vci_tgt.eop ){
+                r_tgt_cmd_fsm = TGT_CMD_IDLE;
+            }
+            break;
+        }
+        ///////////////////
+      case TGT_CMD_WRITE:
+        {
+
+            m_waiting_cycles ++;
+
+            if ( p_vci_tgt.cmdval && m_cmd_write_addr_fifo.wok() ) {
+                cmd_write_fifo_put = true;
+                if(  p_vci_tgt.eop )  r_tgt_cmd_fsm = TGT_CMD_IDLE;
+                
+            }
+            break;
+        }
+        ////////////////////
+      case TGT_CMD_ATOMIC:
+        {
+          assert(p_vci_tgt.eop && "Memory Cache Error: LL or SC command with length > 1 ");
+
+          m_waiting_cycles ++;
+
+          if ( p_vci_tgt.cmdval && m_cmd_llsc_addr_fifo.wok() ) {
+              cmd_llsc_fifo_put = true;
+              r_tgt_cmd_fsm = TGT_CMD_IDLE;
+          }
+          break;
+        }
+    } // end switch tgt_cmd_fsm
+
+    /////////////////////////////////////////////////////////////////////////
+    //		INIT_RSP FSM
+    /////////////////////////////////////////////////////////////////////////
+    // This FSM controls the response to the update or invalidate requests
+    // sent by the memory cache to the L1 caches :
+    //
+    // - update request initiated by the WRITE FSM.  
+    //   The FSM decrements the proper entry in the Update/Inval Table.
+    //   It sends a request to the TGT_RSP FSM to complete the pending 
+    //   write transaction (acknowledge response to the writer processor), 
+    //   and clear the UPT entry when all responses have been received.  
+    // - invalidate request initiated by the XRAM_RSP FSM.
+    //   The FSM decrements the proper entry in the Update/Inval_Table,
+    //   and clear the entry when all responses have been received.
+    //
+    // All those response packets are one word, compact
+    // packets complying with the VCI advanced format. 
+    // The index in the Table is defined in the RTRDID field, and
+    // the Transaction type is defined in the Update/Inval Table.
+    /////////////////////////////////////////////////////////////////////
+
+    switch ( r_init_rsp_fsm.read() ) {
+
+      ///////////////////
+      case INIT_RSP_IDLE:
+        {
+
+          if ( p_vci_ini.rspval ) {
+
+            assert ( ( p_vci_ini.rtrdid.read() < m_update_tab.size() )
+                && "VCI_MEM_CACHE UPT index too large in VCI response paquet received by memory cache" );
+            assert ( p_vci_ini.reop 
+                && "VCI_MEM_CACHE All response packets to update/invalidate requests must be one cell" );
+            r_init_rsp_upt_index = p_vci_ini.rtrdid.read(); 
+            r_init_rsp_fsm = INIT_RSP_UPT_LOCK;
+          } else if( r_write_to_init_rsp_req.read() ){
+            r_init_rsp_upt_index = r_write_to_init_rsp_upt_index.read();
+            r_write_to_init_rsp_req = false;
+            r_init_rsp_fsm = INIT_RSP_UPT_LOCK;
+          }
+          break;
+        }
+        ///////////////////////
+      case INIT_RSP_UPT_LOCK:	// decrement the number of expected responses
+        {
+
+          if ( r_alloc_upt_fsm.read() == ALLOC_UPT_INIT_RSP ) { 
+            size_t count = 0;
+            bool valid  = m_update_tab.decrement(r_init_rsp_upt_index.read(), count);
+#ifdef IDEBUG
+            TRACE_MSG(m_log
+                      << m_total_cycles 
+                      << " " << name() 
+                      << " INIT_RSP_UPT_LOCK update table : " << std::endl);
+            
+            DUMP_UPDATE_TABLE;
+#endif
+            assert ( valid 
+                && "VCI_MEM_CACHE Invalid UPT entry in VCI response paquet received by memory cache" );
+
+            if ( count == 0 ) r_init_rsp_fsm = INIT_RSP_UPT_CLEAR;
+            else              r_init_rsp_fsm = INIT_RSP_IDLE;
+          }
+          break;
+        }
+        ////////////////////////
+      case INIT_RSP_UPT_CLEAR:	// clear the UPT entry
+        {
+          if ( r_alloc_upt_fsm.read() == ALLOC_UPT_INIT_RSP ) {
+            r_init_rsp_srcid = m_update_tab.srcid(r_init_rsp_upt_index.read());
+            r_init_rsp_trdid = m_update_tab.trdid(r_init_rsp_upt_index.read());
+            r_init_rsp_pktid = m_update_tab.pktid(r_init_rsp_upt_index.read());
+            r_init_rsp_nline = m_update_tab.nline(r_init_rsp_upt_index.read());
+            bool need_rsp = m_update_tab.need_rsp(r_init_rsp_upt_index.read());
+            if ( need_rsp ) r_init_rsp_fsm = INIT_RSP_END;
+            else            r_init_rsp_fsm = INIT_RSP_IDLE;
+            m_update_tab.clear(r_init_rsp_upt_index.read());
+
+#ifdef IDEBUG
+            TRACE_MSG(std::cout << m_total_cycles << " " << name() << " INIT_RSP_UPT_CLEAR update table : " << std::endl);
+            DUMP_UPDATE_TABLE;
+#endif
+          }
+          break;
+        }
+        //////////////////
+      case INIT_RSP_END:
+        {
+
+          if ( !r_init_rsp_to_tgt_rsp_req ) {
+            r_init_rsp_to_tgt_rsp_req = true;
+            r_init_rsp_to_tgt_rsp_srcid = r_init_rsp_srcid.read();
+            r_init_rsp_to_tgt_rsp_trdid = r_init_rsp_trdid.read();
+            r_init_rsp_to_tgt_rsp_pktid = r_init_rsp_pktid.read();
+            r_init_rsp_fsm = INIT_RSP_IDLE;
+          }
+          break;
+        }
+    } // end switch r_init_rsp_fsm
+
+    ////////////////////////////////////////////////////////////////////////////////////
+    //		READ FSM
+    ////////////////////////////////////////////////////////////////////////////////////
+    // The READ FSM controls the read requests sent by processors.
+    // It takes the lock protecting the cache directory to check the cache line status:
+    // - In case of HIT, the fsm copies the data (one line, or one single word)
+    //   in the r_read_to_tgt_rsp buffer. It waits if this buffer is not empty.
+    //   The requesting initiator is registered in the cache directory.
+    // - In case of MISS, the READ fsm takes the lock protecting the transaction tab.
+    //   If a read transaction to the XRAM for this line already exists,
+    //   or if the transaction tab is full, the fsm is stalled.
+    //   If a transaction entry is free, the READ fsm sends a request to the XRAM.
+    ////////////////////////////////////////////////////////////////////////////////////
+
+    switch ( r_read_fsm.read() ) {
+
+      ///////////////
+      case READ_IDLE:
+        {
+          if (m_cmd_read_addr_fifo.rok()) {
+            m_cpt_read++;
+            r_read_fsm = READ_DIR_LOCK;
+          }
+          break;
+        }
+        ///////////////////
+      case READ_DIR_LOCK:	// check directory for hit / miss
+        {
+          if( r_alloc_dir_fsm.read() == ALLOC_DIR_READ ) {
+            size_t way = 0;
+            DirectoryEntry entry = m_cache_directory.read(m_cmd_read_addr_fifo.read(), way);
+#ifdef DDEBUG
+            TRACE_MSG(m_log << "In READ_DIR_LOCK printing the entry of address is : " 
+                      << std::hex << m_cmd_read_addr_fifo.read() 
+                      << std::endl);
+            DUMP_ENTRY(entry);
+            TRACE_MSG(m_log << "done" << std::endl);
+#endif
+
+            r_read_is_cnt   = entry.is_cnt;
+            r_read_dirty    = entry.dirty;
+            r_read_lock	    = entry.lock;
+            r_read_inst     = entry.inst;
+            r_read_tag	    = entry.tag;
+            r_read_way	    = way;
+            r_read_count    = entry.count;
+            r_read_copy     = entry.owner.srcid; 
+            r_read_copy_inst= entry.owner.inst;
+            r_read_ptr      = entry.ptr;
+
+            bool cached_read = (m_cmd_read_trdid_fifo.read() & 0x1);
+            // In case of hit, the read acces must be registered in the copies bit-vector
+            if( entry.valid ) 
+            {
+                if(entry.is_cnt || (entry.count == 0) || !cached_read)  { // No new entry in the heap
+                    r_read_fsm = READ_DIR_HIT;
+                } else {
+                    r_read_fsm = READ_HEAP_LOCK;
+                }
+            } 
+            else 
+            {
+                r_read_fsm = READ_TRT_LOCK;
+                m_cpt_read_miss++;
+            }
+          }
+          break;
+        }
+        //////////////////
+      case READ_DIR_HIT:	// read hit : update the memory cache
+        {
+          if( r_alloc_dir_fsm.read() == ALLOC_DIR_READ ) {
+            // signals generation
+            bool inst_read = (m_cmd_read_trdid_fifo.read() & 0x2);
+            bool cached_read = (m_cmd_read_trdid_fifo.read() & 0x1);
+            bool is_cnt = r_read_is_cnt.read();
+
+            // read data in the cache
+            size_t set = m_y[(vci_addr_t)(m_cmd_read_addr_fifo.read())];
+            size_t way = r_read_way.read();
+            for ( size_t i=0 ; i<m_words ; i++ ) {
+              r_read_data[i] = m_cache_data[way][set][i];
+            }
+
+            // update the cache directory (for the copies)
+            DirectoryEntry entry;
+            entry.valid	  = true;
+            entry.is_cnt  = is_cnt; 
+            entry.dirty	  = r_read_dirty.read();
+            entry.tag	  = r_read_tag.read();
+            entry.lock	  = r_read_lock.read();
+            entry.ptr     = r_read_ptr.read();
+            if(cached_read){  // Cached read, we update the copy
+              if(!is_cnt){ // Not counter mode
+                entry.owner.srcid   = m_cmd_read_srcid_fifo.read();
+                entry.owner.inst    = inst_read;
+                entry.inst          = r_read_inst.read() || inst_read;
+                entry.count         = r_read_count.read() + 1;
+              } else { // Counter mode
+                entry.owner.srcid   = 0;
+                entry.owner.inst    = false;
+                entry.inst          = r_read_inst.read() || inst_read;
+                entry.count         = r_read_count.read() + 1;
+              } 
+            } else { // Uncached read
+              entry.owner.srcid     = r_read_copy.read();
+              entry.owner.inst      = r_read_copy_inst.read();
+              entry.inst            = r_read_inst.read();
+              entry.count           = r_read_count.read();
+            }
+#ifdef DDEBUG
+            TRACE_MSG(m_log << "In READ_DIR_HIT printing the entry of address is : " << std::endl);
+            DUMP_ENTRY(entry);
+            TRACE_MSG(m_log << "done" << std::endl);
+#endif
+
+            m_cache_directory.write(set, way, entry);
+            r_read_fsm    = READ_RSP;
+          }
+          break;
+        }
+        //////////////
+      case READ_HEAP_LOCK:
+        {
+          if( r_alloc_heap_fsm.read() == ALLOC_HEAP_READ ) 
+          {
+              size_t copies_count = r_read_count.read() + 1;
+              bool inst_read = (m_cmd_read_trdid_fifo.read() & 0x2);
+              //bool is_cnt    = (r_read_count.read() >= r_copies_limit.read()) || m_heap_directory.is_full();
+              bool is_cnt    = (r_copies_limit.read() == 2) ? true : ((copies_count >= r_copies_limit.read()) || m_heap_directory.is_full());
+
+              // read data in the cache
+              size_t set     = m_y[(vci_addr_t)(m_cmd_read_addr_fifo.read())];
+              size_t way     = r_read_way.read();
+
+              for ( size_t i=0 ; i<m_words ; i++ ) {
+                  r_read_data[i] = m_cache_data[way][set][i];
+              }
+
+              // update the cache directory (for the copies)
+              DirectoryEntry entry;
+              entry.valid	  = true;
+              entry.is_cnt    = is_cnt; // when we reach the limit of copies or the heap is full
+              entry.dirty	  = r_read_dirty.read();
+              entry.tag	      = r_read_tag.read();
+              entry.lock	  = r_read_lock.read();
+              if(!is_cnt){ // Not counter mode
+                entry.owner.srcid   = r_read_copy.read();
+                entry.owner.inst    = r_read_copy_inst.read();
+                entry.inst          = r_read_inst.read() || inst_read;
+                entry.count         = r_read_count.read() + 1;
+                entry.ptr           = m_heap_directory.next_free_ptr();
+              } else { // Counter mode
+                entry.owner.srcid   = 0;
+                entry.owner.inst    = false;
+                entry.inst          = r_read_inst.read() || inst_read;
+                entry.count         = r_read_count.read() + 1;
+                entry.ptr           = 0;
+              }
+
+#ifdef DDEBUG
+              TRACE_MSG(m_log << "In READ_HEAP_LOCK printing the entry of address is : " << std::endl);
+              DUMP_ENTRY(entry);
+              TRACE_MSG(m_log << "done" << std::endl);
+#endif
+
+              m_cache_directory.write(set, way, entry);
+
+              if(!is_cnt)
+              {
+                  HeapEntry free_heap_entry = m_heap_directory.next_free_entry();
+                  r_read_next_ptr           = free_heap_entry.next;
+
+                  if( free_heap_entry.next == m_heap_directory.next_free_ptr() ) { // Last free heap entry
+                      r_read_last_free = true;
+                  } else {
+                      r_read_last_free = false;
+                  }
+
+                  r_read_fsm = READ_HEAP_WRITE; // we add an entry in the list of copies
+              } 
+              else 
+              {
+                  if(r_read_count.read()>1) 
+                  { // else there is no list of copies...
+                      HeapEntry next_entry = m_heap_directory.read(r_read_ptr.read());
+                      r_read_next_ptr = m_heap_directory.next_free_ptr();
+                      m_heap_directory.write_free_ptr(r_read_ptr.read());
+                      if( next_entry.next == r_read_ptr.read() ) { // The last list member
+                          r_read_fsm = READ_HEAP_LAST; // we erase the list of copies (counter mode)
+                      } else { // Not the end of the list
+                          r_read_ptr = next_entry.next;
+                          r_read_fsm = READ_HEAP_ERASE; // we erase the list of copies (counter mode)
+                      }
+                  } 
+                  else 
+                  {
+                      r_read_fsm = READ_RSP;
+                  }
+              }
+          }
+          break;
+        }
+        //////////////
+      case READ_HEAP_WRITE:
+        {
+          if(r_alloc_heap_fsm.read() == ALLOC_HEAP_READ){
+            bool inst_read = (m_cmd_read_trdid_fifo.read() & 0x2);
+            HeapEntry new_heap_entry;
+            new_heap_entry.owner.srcid  = m_cmd_read_srcid_fifo.read();
+            new_heap_entry.owner.inst   = inst_read;
+            if(r_read_count.read() == 1){ // creation of a new list
+              new_heap_entry.next         = m_heap_directory.next_free_ptr(); 
+            } else {                      // it is an insertion
+              new_heap_entry.next         = r_read_ptr.read();
+            }
+            m_heap_directory.write_free_entry(new_heap_entry);
+            m_heap_directory.write_free_ptr(r_read_next_ptr.read());
+            if(r_read_last_free.read()) {
+              m_heap_directory.set_full();
+            }
+
+            r_read_fsm = READ_RSP;
+          } else {
+            assert(false && "MEMCACHE Error : Bad HEAP allocation");
+          }
+          break;
+        }
+        //////////////
+      case READ_HEAP_ERASE:
+        {
+          if(r_alloc_heap_fsm.read() == ALLOC_HEAP_READ){
+            HeapEntry next_entry = m_heap_directory.read(r_read_ptr.read());
+            if( next_entry.next == r_read_ptr.read() ){
+              r_read_fsm = READ_HEAP_LAST;
+            } else {
+              r_read_ptr = next_entry.next;
+              r_read_fsm = READ_HEAP_ERASE;
+            }
+          } else {
+            assert(false && "MEMCACHE Error : Bad HEAP allocation");
+          }
+          break;
+        }
+        //////////////
+      case READ_HEAP_LAST:
+        {
+          if(r_alloc_heap_fsm.read() == ALLOC_HEAP_READ){
+            HeapEntry last_entry;
+            last_entry.owner.srcid = 0;
+            last_entry.owner.inst  = false;
+            if(m_heap_directory.is_full()){
+              last_entry.next      = r_read_ptr.read();
+              m_heap_directory.unset_full();
+            } else {
+              last_entry.next      = r_read_next_ptr.read();
+            }
+            m_heap_directory.write(r_read_ptr.read(),last_entry);
+            r_read_fsm = READ_RSP;
+          } else {
+            assert(false && "MEMCACHE Error : Bad HEAP allocation");
+          }
+          break;
+        }
+        //////////////
+      case READ_RSP: 		//  request the TGT_RSP FSM to return data
+        {
+          if( !r_read_to_tgt_rsp_req ) {	
+            for ( size_t i=0 ; i<m_words ; i++ ) {
+              r_read_to_tgt_rsp_data[i] = r_read_data[i];
+            }
+            r_read_to_tgt_rsp_word   = m_x[(vci_addr_t)m_cmd_read_addr_fifo.read()];
+            r_read_to_tgt_rsp_length = m_cmd_read_length_fifo.read();
+            cmd_read_fifo_get 		 = true;
+            r_read_to_tgt_rsp_req	 = true;
+            r_read_to_tgt_rsp_srcid	 = m_cmd_read_srcid_fifo.read();
+            r_read_to_tgt_rsp_trdid	 = m_cmd_read_trdid_fifo.read();
+            r_read_to_tgt_rsp_pktid	 = m_cmd_read_pktid_fifo.read();
+            r_read_fsm 			     = READ_IDLE;  
+          }
+          break;
+        }
+        ///////////////////
+      case READ_TRT_LOCK:	// read miss : check the Transaction Table
+        {
+          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_READ ) {
+#ifdef TDEBUG
+              TRACE_MSG(m_log << m_total_cycles << " " << name() << " READ_TRT_LOCK " << std::endl);
+#endif
+            size_t index     = 0;
+            bool   hit_read  = m_transaction_tab.hit_read(m_nline[(vci_addr_t)(m_cmd_read_addr_fifo.read())], index);
+            bool   hit_write = m_transaction_tab.hit_write(m_nline[(vci_addr_t)(m_cmd_read_addr_fifo.read())]);
+            bool   wok       = !m_transaction_tab.full(index);
+
+            if( hit_read || !wok || hit_write )  // missing line already requested or no space
+            {  
+              r_read_fsm = READ_IDLE; 
+              
+              TRACE_MSG(m_log << m_total_cycles 
+                        << " " << name() 
+                        << " READ_TRT_LOCK -> READ_IDLE"
+                        << " address = " << std::hex << m_cmd_read_addr_fifo.read()
+                        << " read hit = " << hit_read
+                        << ", write hit = " << hit_write
+                        << std::endl);
+            }
+            else 		                         // missing line is requested to the XRAM 
+            {	
+              r_read_trt_index = index;
+              r_read_fsm       = READ_TRT_SET;
+            }
+          }
+          break;
+        }
+        //////////////////
+      case READ_TRT_SET:
+        {
+          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_READ ) {
+            m_transaction_tab.set(r_read_trt_index.read(),
+                true,
+                m_nline[(vci_addr_t)(m_cmd_read_addr_fifo.read())],
+                m_cmd_read_srcid_fifo.read(),
+                m_cmd_read_trdid_fifo.read(),
+                m_cmd_read_pktid_fifo.read(),
+                true,
+                m_cmd_read_length_fifo.read(),
+                m_x[(vci_addr_t)(m_cmd_read_addr_fifo.read())],
+                std::vector<be_t>(m_words,0),
+                std::vector<data_t>(m_words,0));
+#ifdef TDEBUG
+            TRACE_MSG(m_log << m_total_cycles << " " << name() 
+                      << " Address = " << std::hex << m_cmd_read_addr_fifo.read()
+                      << " READ_TRT_SET transaction table : " << std::endl);
+
+            DUMP_TRANSACTION_TABLE;
+#endif
+
+            r_read_fsm 	 = READ_XRAM_REQ;
+          }
+          break;
+        }
+        /////////////////////
+      case READ_XRAM_REQ:
+        {
+          if( !r_read_to_ixr_cmd_req ) {
+            cmd_read_fifo_get		= true;
+            r_read_to_ixr_cmd_req  	= true;
+            r_read_to_ixr_cmd_nline 	= m_nline[(vci_addr_t)(m_cmd_read_addr_fifo.read())];
+            r_read_to_ixr_cmd_trdid 	= r_read_trt_index.read();
+            r_read_fsm 			          = READ_IDLE;
+          }
+          break;
+        }
+    } // end switch read_fsm
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //		WRITE FSM
+    ///////////////////////////////////////////////////////////////////////////////////
+    // The WRITE FSM handles the write bursts sent by the processors.
+    // All addresses in a burst must be in the same cache line.
+    // A complete write burst is consumed in the FIFO & copied to a local buffer.
+    // Then the FSM takes the lock protecting the cache directory, to check
+    // if the line is in the cache.
+    //
+    // - In case of HIT, the cache is updated.
+    //   If there is no other copy, an acknowledge response is immediately
+    //   returned to the writing processor.
+    //   if the data is cached by other processoris, the FSM takes the lock
+    //   protecting the Update Table (UPT) to register this update transaction.
+    //   If the UPT is full, it releases the lock  and waits. Then, it sends 
+    //   a multi-update request to all owners of the line (but the writer), 
+    //   through the INIT_CMD FSM. In case of multi-update transaction, the WRITE FSM 
+    //   does not respond to the writing processor, as this response will be sent by 
+    //   the INIT_RSP FSM when all update responses have been received.
+    //
+    // - In case of MISS, the WRITE FSM takes the lock protecting the transaction
+    //   table (TRT). If a read transaction to the XRAM for this line already exists, 
+    //   it writes in the TRT (write buffer). Otherwise, if a TRT entry is free, 
+    //   the WRITE FSM register a new transaction in TRT, and sends a read line request 
+    //   to the XRAM. If the TRT is full, it releases the lock, and waits.
+    //   Finally, the WRITE FSM returns an aknowledge response to the writing processor.
+    /////////////////////////////////////////////////////////////////////////////////////
+
+    switch ( r_write_fsm.read() ) {
+
+      ////////////////
+      case WRITE_IDLE:	// copy first word of a write burst in local buffer	
+        {
+          if ( m_cmd_write_addr_fifo.rok()) {
+            m_cpt_write++;
+            m_cpt_write_cells++;
+            // consume a word in the FIFO & write it in the local buffer 
+            cmd_write_fifo_get	= true;
+            size_t index 	    = m_x[(vci_addr_t)(m_cmd_write_addr_fifo.read())];
+            r_write_address	    = (addr_t)(m_cmd_write_addr_fifo.read());
+            r_write_word_index	= index;
+            r_write_word_count	= 1;
+            r_write_data[index]	= m_cmd_write_data_fifo.read();
+            r_write_srcid	    = m_cmd_write_srcid_fifo.read();
+            r_write_trdid	    = m_cmd_write_trdid_fifo.read();
+            r_write_pktid	    = m_cmd_write_pktid_fifo.read();
+
+            // the be field must be set for all words 
+            for ( size_t i=0 ; i<m_words ; i++ ) {
+              if ( i == index ) r_write_be[i] = m_cmd_write_be_fifo.read();
+              else		        r_write_be[i] = 0x0;
+            }
+            if( !((m_cmd_write_be_fifo.read() == 0x0)||(m_cmd_write_be_fifo.read() == 0xF)) )
+                    r_write_byte=true;
+            else    r_write_byte=false;
+
+            if( m_cmd_write_eop_fifo.read() )  r_write_fsm = WRITE_DIR_LOCK;
+            else                               r_write_fsm = WRITE_NEXT;
+          }
+          break;
+        }
+        ////////////////
+      case WRITE_NEXT:	// copy next word of a write burst in local buffer
+        {
+          if ( m_cmd_write_addr_fifo.rok() ) {
+            m_cpt_write_cells++;
+
+            // check that the next word is in the same cache line
+            assert( (m_nline[(vci_addr_t)(r_write_address.read())] == m_nline[(vci_addr_t)(m_cmd_write_addr_fifo.read())])  
+                && "VCI_MEM_CACHE write error in vci_mem_cache : write burst over a line" );
+            // consume a word in the FIFO & write it in the local buffer 
+            cmd_write_fifo_get=true;
+            size_t index 	        = r_write_word_index.read() + r_write_word_count.read();
+            r_write_be[index]       = m_cmd_write_be_fifo.read();
+            r_write_data[index]     = m_cmd_write_data_fifo.read();
+            r_write_word_count 	    = r_write_word_count.read() + 1;
+            if( !((m_cmd_write_be_fifo.read() == 0x0)||(m_cmd_write_be_fifo.read() == 0xF)) )
+              r_write_byte=true;
+            if ( m_cmd_write_eop_fifo.read() )  r_write_fsm = WRITE_DIR_LOCK;
+          }
+          break;
+        }
+        ////////////////////
+      case WRITE_DIR_LOCK:	// access directory to check hit/miss
+        {
+          if ( r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE ) {
+            size_t  way = 0;
+            DirectoryEntry entry(m_cache_directory.read(r_write_address.read(), way));
+
+            // copy directory entry in local buffers in case of hit
+            if ( entry.valid )  {	
+              r_write_is_cnt    = entry.is_cnt;
+              r_write_lock	    = entry.lock;
+              r_write_inst      = entry.inst;
+              r_write_tag       = entry.tag;
+              r_write_copy      = entry.owner.srcid;
+              r_write_copy_inst = entry.owner.inst;
+              r_write_count     = entry.count;
+              r_write_ptr       = entry.ptr;
+              r_write_way  	    = way;
+              
+              bool owner = (entry.owner.srcid==r_write_srcid.read()) && !entry.owner.inst;
+              bool no_update = (entry.count==0) || ( owner && (entry.count==1));
+
+              if((entry.is_cnt && entry.count) || entry.inst)
+              {
+                  r_write_fsm      = WRITE_DIR_HIT_READ;
+              } 
+              else 
+              {
+                  if(r_write_byte.read())
+                      r_write_fsm      = WRITE_DIR_HIT_READ;
+                  else
+                  { 
+                      if( no_update) r_write_fsm  = WRITE_DIR_HIT_RSP;
+                      else           r_write_fsm  = WRITE_DIR_HIT;
+                  }
+              }
+            } 
+            else 
+            {
+                r_write_fsm = WRITE_TRT_LOCK;
+                m_cpt_write_miss++;
+            }
+          }
+          break;
+        }
+        ///////////////////
+      case WRITE_DIR_HIT_READ:	// read the cache and complete the buffer (data, when be!=0xF)
+        {
+          // update local buffer
+          size_t set	= m_y[(vci_addr_t)(r_write_address.read())];
+          size_t way	= r_write_way.read();
+          for(size_t i=0 ; i<m_words ; i++) {
+            data_t mask      = 0;
+            if  (r_write_be[i].read() & 0x1) mask = mask | 0x000000FF;
+            if  (r_write_be[i].read() & 0x2) mask = mask | 0x0000FF00;
+            if  (r_write_be[i].read() & 0x4) mask = mask | 0x00FF0000;
+            if  (r_write_be[i].read() & 0x8) mask = mask | 0xFF000000;
+            if(r_write_be[i].read()||r_write_is_cnt.read()||r_write_inst.read()) { // complete only if mask is not null (for energy consumption)
+              r_write_data[i]  = (r_write_data[i].read() & mask) | 
+                (m_cache_data[way][set][i] & ~mask);
+            }
+          } // end for
+
+          bool owner = (r_write_copy.read()==r_write_srcid.read()) && !r_write_copy_inst.read();
+          bool no_update = (r_write_count.read()==0) || ( owner && (r_write_count.read()==1));
+          if((r_write_is_cnt.read() && r_write_count.read()) ||
+              r_write_inst.read()){
+            r_write_fsm            = WRITE_TRT_WRITE_LOCK;
+          } else {
+            if( no_update ) r_write_fsm = WRITE_DIR_HIT_RSP;
+            else            r_write_fsm = WRITE_DIR_HIT;
+          }
+          break;
+        }
+        ///////////////////
+      case WRITE_DIR_HIT:	// update the cache (data & dirty bit)
+        {
+          // update directory with Dirty bit
+          DirectoryEntry entry;
+          entry.valid	    = true;
+          entry.dirty	    = true;
+          entry.tag	        = r_write_tag.read();
+          entry.is_cnt      = r_write_is_cnt.read();
+          entry.lock	    = r_write_lock.read();
+          entry.inst        = r_write_inst.read();
+          entry.owner.srcid = r_write_copy.read();
+          entry.owner.inst  = r_write_copy_inst.read();
+          entry.count       = r_write_count.read();
+          entry.ptr         = r_write_ptr.read();
+          size_t set	    = m_y[(vci_addr_t)(r_write_address.read())];
+          size_t way	    = r_write_way.read();
+          m_cache_directory.write(set, way, entry);
+
+          bool owner = (r_write_copy.read()==r_write_srcid.read()) && !r_write_copy_inst.read();
+
+          size_t count_signal   = r_write_count.read();
+          if(owner){
+            count_signal        = count_signal - 1;
+          }
+          r_write_count         = count_signal;
+          r_write_to_dec        = false;
+
+          if( !r_write_to_init_cmd_multi_req.read() && 
+              !r_write_to_init_cmd_brdcast_req.read()  )
+            r_write_fsm = WRITE_UPT_LOCK;
+          else
+            r_write_fsm = WRITE_WAIT;
+          break;
+        }
+        ///////////////////
+      case WRITE_DIR_HIT_RSP:	// update the cache (data & dirty bit) no update
+        {
+          // update directory with Dirty bit
+          DirectoryEntry entry;
+          entry.valid	    = true;
+          entry.dirty	    = true;
+          entry.tag	        = r_write_tag.read();
+          entry.is_cnt      = r_write_is_cnt.read();
+          entry.lock	    = r_write_lock.read();
+          entry.inst        = r_write_inst.read();
+          entry.owner.srcid = r_write_copy.read();
+          entry.owner.inst  = r_write_copy_inst.read();
+          entry.count       = r_write_count.read();
+          entry.ptr         = r_write_ptr.read();
+          size_t set	    = m_y[(vci_addr_t)(r_write_address.read())];
+          size_t way	    = r_write_way.read();
+          m_cache_directory.write(set, way, entry);
+
+          bool owner = (r_write_copy.read()==r_write_srcid.read()) && !r_write_copy_inst.read();
+
+          // write data in cache
+          for(size_t i=0 ; i<m_words ; i++) {
+              if  ( r_write_be[i].read() ) {
+                  m_cache_data[way][set][i]  = r_write_data[i].read();
+              }
+          } // end for
+
+          if ( !r_write_to_tgt_rsp_req.read() ) {
+            r_write_to_tgt_rsp_req	    = true;
+            r_write_to_tgt_rsp_srcid	= r_write_srcid.read();
+            r_write_to_tgt_rsp_trdid	= r_write_trdid.read();
+            r_write_to_tgt_rsp_pktid	= r_write_pktid.read();
+            r_write_fsm 		        = WRITE_IDLE;
+          } else {
+            r_write_fsm = WRITE_RSP;
+          }
+          break;
+        }
+        /////////////////////
+      case WRITE_UPT_LOCK: 	// Try to register the request in Update Table
+        {
+
+          if ( r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE ) {
+            bool        wok        = false;
+            size_t      index      = 0;
+            size_t      srcid      = r_write_srcid.read();
+            size_t      trdid      = r_write_trdid.read();
+            size_t      pktid      = r_write_pktid.read();
+            addr_t      nline      = m_nline[(vci_addr_t)(r_write_address.read())];
+            size_t      nb_copies  = r_write_count.read();
+            size_t set	    = m_y[(vci_addr_t)(r_write_address.read())];
+            size_t way	    = r_write_way.read();
+
+            wok =m_update_tab.set(true,	// it's an update transaction
+                false,                  // it's not a broadcast
+                true,                   // it needs a response
+                srcid,
+                trdid,
+                pktid,
+                nline,
+                nb_copies,
+                index);
+            if(wok){
+              // write data in cache
+              for(size_t i=0 ; i<m_words ; i++) {
+                if  ( r_write_be[i].read() ) {
+                  m_cache_data[way][set][i]  = r_write_data[i].read();
+                }
+              } // end for
+            }
+#ifdef IDEBUG
+            if((wok) && (m_total_cycles > m_debug_start) && (m_srcid_ini == MEMC_INI_ID)){
+                TRACE_MSG(m_log << 
+                          m_total_cycles 
+                          << " " << name() << " WRITE_UPT_LOCK update table : " 
+                          << std::endl);
+                m_update_tab.print();
+            }
+#endif
+            r_write_upt_index = index;
+            //  releases the lock protecting the Update Table and the Directory if no entry...
+            if ( wok ) r_write_fsm = WRITE_HEAP_LOCK;
+            else       r_write_fsm = WRITE_WAIT;
+          }
+          break;
+        }
+        //////////////////
+      case WRITE_HEAP_LOCK:
+        {
+          if( r_alloc_heap_fsm.read() == ALLOC_HEAP_WRITE ){
+            r_write_fsm = WRITE_UPT_REQ;
+          }
+          break;
+        }
+        //////////////////
+      case WRITE_UPT_REQ:
+        {
+          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_WRITE) &&
+                    "MemCache ERROR : bad HEAP allocation");
+          if( !r_write_to_init_cmd_multi_req.read() && 
+              !r_write_to_init_cmd_brdcast_req.read()  ){
+            r_write_to_init_cmd_brdcast_req  = false;
+            r_write_to_init_cmd_trdid        = r_write_upt_index.read();
+            r_write_to_init_cmd_nline        = m_nline[(vci_addr_t)(r_write_address.read())];
+            r_write_to_init_cmd_index        = r_write_word_index.read();
+            r_write_to_init_cmd_count        = r_write_word_count.read();
+
+            for(size_t i=0; i<m_words ; i++){
+              if(r_write_be[i].read())  r_write_to_init_cmd_we[i]=true;
+              else                      r_write_to_init_cmd_we[i]=false;
+            }
+
+            size_t min = r_write_word_index.read();
+            size_t max = r_write_word_index.read() + r_write_word_count.read();
+            for (size_t i=min ; i<max ; i++) {
+              r_write_to_init_cmd_data[i] = r_write_data[i];
+            }
+            
+            if( r_write_copy.read() != r_write_srcid.read() ) {
+              // We put the first copy in the fifo
+              write_to_init_cmd_fifo_put     = true;
+              write_to_init_cmd_fifo_inst    = r_write_copy_inst.read();
+              write_to_init_cmd_fifo_srcid   = r_write_copy.read();
+              if(r_write_count.read() == 1){
+                r_write_fsm = WRITE_IDLE;
+                r_write_to_init_cmd_multi_req = true;
+              } else {
+                r_write_fsm = WRITE_UPDATE;
+              }
+            } else {
+              r_write_fsm = WRITE_UPDATE;
+            }
+          }
+          break;
+        }
+        //////////////////
+      case WRITE_UPDATE:	// send a multi-update request to INIT_CMD fsm
+        {
+          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_WRITE) &&
+                    "MemCache ERROR : bad HEAP allocation");
+          HeapEntry entry = m_heap_directory.read(r_write_ptr.read());
+          write_to_init_cmd_fifo_inst  = entry.owner.inst;
+          write_to_init_cmd_fifo_srcid = entry.owner.srcid;
+          bool dec_upt_counter = r_write_to_dec.read();
+          if( (entry.owner.srcid != r_write_srcid.read()) || entry.owner.inst ){
+            write_to_init_cmd_fifo_put = true;
+          } else {
+            dec_upt_counter = true;
+          }
+          r_write_to_dec = dec_upt_counter;
+
+          if( m_write_to_init_cmd_inst_fifo.wok() ){
+            r_write_ptr = entry.next;
+            if( entry.next == r_write_ptr.read() ) { // last copy
+              r_write_to_init_cmd_multi_req = true;
+              if(dec_upt_counter){
+                r_write_fsm = WRITE_UPT_DEC;
+              } else {
+                r_write_fsm = WRITE_IDLE;
+              }
+            } else {
+              r_write_fsm = WRITE_UPDATE;
+            }
+          } else {
+            r_write_fsm = WRITE_UPDATE;
+          }
+          break;
+        }
+        //////////////////
+      case WRITE_UPT_DEC:
+        {
+          if(!r_write_to_init_rsp_req.read()){
+            r_write_to_init_rsp_req = true;
+            r_write_to_init_rsp_upt_index = r_write_upt_index.read();
+            r_write_fsm = WRITE_IDLE;
+          }
+          break;
+        }
+        ///////////////
+      case WRITE_RSP:		// send a request to TGT_RSP FSM to acknowledge the write
+        {
+          if ( !r_write_to_tgt_rsp_req.read() ) {
+            r_write_to_tgt_rsp_req	    = true;
+            r_write_to_tgt_rsp_srcid	= r_write_srcid.read();
+            r_write_to_tgt_rsp_trdid	= r_write_trdid.read();
+            r_write_to_tgt_rsp_pktid	= r_write_pktid.read();
+            r_write_fsm 		        = WRITE_IDLE;
+          }
+          break;
+        }
+        ////////////////////
+      case WRITE_TRT_LOCK:	// Miss : check Transaction Table
+        {
+          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE ) {
+#ifdef TDEBUG
+              TRACE_MSG(m_log << m_total_cycles << " " << name() << " READ_TRT_LOCK " << std::endl);
+#endif
+            size_t hit_index = 0;
+            size_t wok_index = 0;
+            bool hit_read    = m_transaction_tab.hit_read(m_nline[(vci_addr_t)(r_write_address.read())], hit_index);
+            bool hit_write   = m_transaction_tab.hit_write(m_nline[(vci_addr_t)(r_write_address.read())]);
+            bool wok         = !m_transaction_tab.full(wok_index);
+
+            if ( hit_read ) {	// register the modified data in TRT 
+              r_write_trt_index = hit_index;
+              r_write_fsm       = WRITE_TRT_DATA;
+            } else if ( wok && !hit_write ) {	// set a new entry in TRT
+              r_write_trt_index = wok_index;
+              r_write_fsm       = WRITE_TRT_SET;
+            } else {		    // wait an empty entry in TRT
+              r_write_fsm       = WRITE_WAIT;
+            }
+          }
+          break;
+        }
+        ////////////////////
+      case WRITE_WAIT:	// release the lock protecting TRT
+        { 
+          r_write_fsm = WRITE_DIR_LOCK;
+          break;
+        }
+        ///////////////////
+      case WRITE_TRT_SET:	// register a new transaction in TRT (Write Buffer)
+        {  
+          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE ) 
+          {
+            std::vector<be_t> be_vector;
+            std::vector<data_t> data_vector;
+            be_vector.clear();
+            data_vector.clear();
+            for ( size_t i=0; i<m_words; i++ ) 
+            {
+              be_vector.push_back(r_write_be[i]);
+              data_vector.push_back(r_write_data[i]);
+            }
+            m_transaction_tab.set(r_write_trt_index.read(),
+                true,				// read request to XRAM
+                m_nline[(vci_addr_t)(r_write_address.read())],
+                r_write_srcid.read(),
+                r_write_trdid.read(),
+                r_write_pktid.read(),
+                false,				// not a processor read
+                0,  				// not a single word 
+                0,		        	// word index
+                be_vector,
+                data_vector);
+#ifdef TDEBUG
+            TRACE_MSG(m_log << m_total_cycles << " " << name() << " WRITE_TRT_SET transaction table : " << std::endl);
+            DUMP_TRANSACTION_TABLE;
+#endif
+
+            r_write_fsm = WRITE_XRAM_REQ;
+          }
+          break;
+        }  
+        ///////////////////
+      case WRITE_TRT_DATA:	// update an entry in TRT (Write Buffer)
+        { 
+          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE ) {
+            std::vector<be_t> be_vector;
+            std::vector<data_t> data_vector;
+            be_vector.clear();
+            data_vector.clear();
+            for ( size_t i=0; i<m_words; i++ ) {
+              be_vector.push_back(r_write_be[i]);
+              data_vector.push_back(r_write_data[i]);
+            }
+            m_transaction_tab.write_data_mask(r_write_trt_index.read(),
+                be_vector,
+                data_vector);
+            r_write_fsm = WRITE_RSP;
+#ifdef TDEBUG
+            TRACE_MSG(m_log << m_total_cycles << " " << name() << " WRITE_TRT_DATA transaction table : " << std::endl);
+              
+            DUMP_TRANSACTION_TABLE;
+#endif
+
+          }
+          break;
+        }
+        ////////////////////
+      case WRITE_XRAM_REQ:	// send a request to IXR_CMD FSM
+        {  
+
+          if ( !r_write_to_ixr_cmd_req ) {
+            r_write_to_ixr_cmd_req   = true;
+            r_write_to_ixr_cmd_write = false;
+            r_write_to_ixr_cmd_nline = m_nline[(vci_addr_t)(r_write_address.read())];
+            r_write_to_ixr_cmd_trdid = r_write_trt_index.read();
+            r_write_fsm              = WRITE_RSP;
+          }
+          break;
+        }
+        ////////////////////
+      case WRITE_TRT_WRITE_LOCK:
+        {
+          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE ) {
+            size_t wok_index = 0;
+            bool wok = !m_transaction_tab.full(wok_index);
+            if ( wok ) {	// set a new entry in TRT
+              r_write_trt_index = wok_index;
+              r_write_fsm       = WRITE_INVAL_LOCK;
+            } else {		// wait an empty entry in TRT
+              r_write_fsm       = WRITE_WAIT;
+            }
+          }
+
+          break;
+        }
+        ////////////////////
+      case WRITE_INVAL_LOCK:
+        {
+          if ( r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE ) {
+            bool        wok       = false;
+            size_t      index     = 0;
+            size_t      srcid     = r_write_srcid.read();
+            size_t      trdid     = r_write_trdid.read();
+            size_t      pktid     = r_write_pktid.read();
+            addr_t	    nline     = m_nline[(vci_addr_t)(r_write_address.read())];
+            size_t      nb_copies = r_write_count.read();
+
+            wok =m_update_tab.set(false,	// it's an inval transaction
+                true,                       // it's a broadcast
+                true,                       // it needs a response
+                srcid,
+                trdid,
+                pktid,
+                nline,
+                nb_copies,
+                index);
+#ifdef IDEBUG
+            if(wok){
+       
+                TRACE_MSG(m_log << 
+                          m_total_cycles << " " << name() 
+                          << " WRITE_INVAL_LOCK update table : " 
+                          << std::endl);
+
+                DUMP_UPDATE_TABLE;   
+            }
+#endif
+            r_write_upt_index = index;
+            //  releases the lock protecting Update Table if no entry...
+            if ( wok ) r_write_fsm = WRITE_DIR_INVAL;
+            else       r_write_fsm = WRITE_WAIT;
+          }
+
+          break;
+        }
+        ////////////////////
+      case WRITE_DIR_INVAL:
+        {
+            assert(((r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE ) &&
+                    (r_alloc_upt_fsm.read() == ALLOC_UPT_WRITE ) &&
+                    (r_alloc_dir_fsm.read() == ALLOC_DIR_WRITE ))&&
+                    "MemCache ERROR : bad TRT,DIR or UPT allocation error");
+            m_transaction_tab.set(r_write_trt_index.read(),
+                false,				// write request to XRAM
+                m_nline[(vci_addr_t)(r_write_address.read())],
+                0,
+                0,
+                0,
+                false,				// not a processor read
+                0,  				// not a single word 
+                0,		        	// word index
+                std::vector<be_t>(m_words,0),
+                std::vector<data_t>(m_words,0));
+#ifdef TDEBUG
+            TRACE_MSG(m_log << m_total_cycles 
+                      << " " << name() << " WRITE_DIR_INVAL transaction table : " << std::endl);
+
+            DUMP_TRANSACTION_TABLE;
+#endif
+
+            // invalidate directory entry
+            DirectoryEntry entry;
+            entry.valid	        = false;
+            entry.dirty	        = false;
+            entry.tag	        = 0;
+            entry.is_cnt        = false;
+            entry.lock          = false;
+            entry.inst          = false;
+            entry.owner.srcid   = 0;
+            entry.owner.inst    = false;
+            entry.ptr           = 0;
+            entry.count         = 0;
+            size_t set	        = m_y[(vci_addr_t)(r_write_address.read())];
+            size_t way	        = r_write_way.read();
+            m_cache_directory.write(set, way, entry);
+
+            r_write_fsm = WRITE_INVAL;
+            break;
+        }
+        ////////////////////
+      case WRITE_INVAL:
+        {
+          if (  !r_write_to_init_cmd_multi_req.read() &&
+                !r_write_to_init_cmd_brdcast_req.read() ) {
+            r_write_to_init_cmd_multi_req   = false;
+            r_write_to_init_cmd_brdcast_req = true;
+            r_write_to_init_cmd_trdid       = r_write_upt_index.read();
+            r_write_to_init_cmd_nline       = m_nline[(vci_addr_t)(r_write_address.read())];
+            r_write_to_init_cmd_index       = 0;
+            r_write_to_init_cmd_count       = 0;
+
+            for(size_t i=0; i<m_words ; i++){
+              r_write_to_init_cmd_we[i]=false;
+              r_write_to_init_cmd_data[i] = 0;
+            }
+            r_write_fsm = WRITE_XRAM_SEND;
+            // all inval responses
+          }
+
+          break;
+        }
+        ////////////////////
+      case WRITE_XRAM_SEND:
+        {
+          if ( !r_write_to_ixr_cmd_req ) {
+            r_write_to_ixr_cmd_req     = true;
+            r_write_to_ixr_cmd_write   = true;
+            r_write_to_ixr_cmd_nline   = m_nline[(vci_addr_t)(r_write_address.read())];
+            r_write_to_ixr_cmd_trdid   = r_write_trt_index.read();
+            for(size_t i=0; i<m_words; i++){
+              r_write_to_ixr_cmd_data[i] = r_write_data[i];
+            }
+            if(  r_write_is_cnt.read() ||
+                ((!r_write_is_cnt.read()) && (r_write_count.read()==1)) ){
+              r_write_fsm = WRITE_IDLE;
+            } else {
+              r_write_fsm = WRITE_HEAP_ERASE;
+              r_write_next_ptr = r_write_ptr.read();
+            }
+          }
+          break;
+        }
+        ////////////////////
+      case WRITE_HEAP_ERASE:
+        {
+          if(r_alloc_heap_fsm.read() == ALLOC_HEAP_WRITE){
+            HeapEntry next_entry = m_heap_directory.read(r_write_next_ptr.read());
+            if( next_entry.next == r_write_next_ptr.read()){
+              r_write_fsm = WRITE_HEAP_LAST;
+            } else {
+              r_write_next_ptr = next_entry.next;
+              r_write_fsm = WRITE_HEAP_ERASE;
+            }
+          }
+          break;
+        }
+        ////////////////////
+      case WRITE_HEAP_LAST:
+        {
+          assert((r_alloc_heap_fsm.read() == ALLOC_HEAP_WRITE) &&
+                  "MemCache ERROR : bad HEAP allocation");
+          size_t free_pointer = m_heap_directory.next_free_ptr();
+
+          HeapEntry last_entry;
+          last_entry.owner.srcid = 0;
+          last_entry.owner.inst  = false;
+          if(m_heap_directory.is_full()){
+            last_entry.next     = r_write_next_ptr.read();
+            m_heap_directory.unset_full();
+          } else {
+            last_entry.next     = free_pointer;
+          }
+
+          m_heap_directory.write_free_ptr(r_write_ptr.read());
+          m_heap_directory.write(r_write_next_ptr.read(),last_entry);
+
+          r_write_fsm = WRITE_IDLE;
+          break;
+        }
+    } // end switch r_write_fsm
+
+    ///////////////////////////////////////////////////////////////////////
+    //		IXR_CMD FSM
+    ///////////////////////////////////////////////////////////////////////
+    // The IXR_CMD fsm controls the command packets to the XRAM :
+    // - It sends a single cell VCI read to the XRAM in case of MISS request
+    // posted by the READ, WRITE or LLSC FSMs : the TRDID field contains 
+    // the Transaction Tab index.
+    // The VCI response is a multi-cell packet : the N cells contain
+    // the N data words.
+    // - It sends a multi-cell VCI write when the XRAM_RSP FSM request 
+    // to save a dirty line to the XRAM. 
+    // The VCI response is a single cell packet.
+    // This FSM handles requests from the READ, WRITE, LLSC & XRAM_RSP FSMs 
+    // with a round-robin priority.
+    ////////////////////////////////////////////////////////////////////////
+
+    switch ( r_ixr_cmd_fsm.read() ) {
+      //////////////////////// 
+      case IXR_CMD_READ_IDLE:
+        if      ( r_write_to_ixr_cmd_req )     r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE;
+        else if ( r_llsc_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_LLSC_NLINE;
+        else if ( r_xram_rsp_to_ixr_cmd_req  ) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA;
+        else if ( r_read_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_READ_NLINE;
+        break;
+        //////////////////////// 
+      case IXR_CMD_WRITE_IDLE:
+        if      ( r_llsc_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_LLSC_NLINE;
+        else if ( r_xram_rsp_to_ixr_cmd_req  ) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA;
+        else if ( r_read_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_READ_NLINE;
+        else if ( r_write_to_ixr_cmd_req )     r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE;
+        break;
+        //////////////////////// 
+      case IXR_CMD_LLSC_IDLE:
+        if      ( r_xram_rsp_to_ixr_cmd_req  ) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA;
+        else if ( r_read_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_READ_NLINE;
+        else if ( r_write_to_ixr_cmd_req )     r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE;
+        else if ( r_llsc_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_LLSC_NLINE;
+        break;
+        //////////////////////// 
+      case IXR_CMD_XRAM_IDLE:
+        if      ( r_read_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_READ_NLINE;
+        else if ( r_write_to_ixr_cmd_req )     r_ixr_cmd_fsm = IXR_CMD_WRITE_NLINE;
+        else if ( r_llsc_to_ixr_cmd_req  )     r_ixr_cmd_fsm = IXR_CMD_LLSC_NLINE;
+        else if ( r_xram_rsp_to_ixr_cmd_req  ) r_ixr_cmd_fsm = IXR_CMD_XRAM_DATA;
+        break;
+        /////////////////////////
+      case IXR_CMD_READ_NLINE:
+        if ( p_vci_ixr.cmdack ) {
+          r_ixr_cmd_fsm = IXR_CMD_READ_IDLE;		
+          r_read_to_ixr_cmd_req = false;
+        }
+        break;
+        //////////////////////////
+      case IXR_CMD_WRITE_NLINE:
+        if ( p_vci_ixr.cmdack ) {
+          if( r_write_to_ixr_cmd_write.read()){
+            if ( r_ixr_cmd_cpt.read() == (m_words - 1) ) {
+              r_ixr_cmd_cpt = 0;
+              r_ixr_cmd_fsm = IXR_CMD_WRITE_IDLE;
+              r_write_to_ixr_cmd_req = false;
+            } else {
+              r_ixr_cmd_cpt = r_ixr_cmd_cpt + 1;
+            }
+          } else {
+            r_ixr_cmd_fsm = IXR_CMD_WRITE_IDLE;		
+            r_write_to_ixr_cmd_req = false;
+          }
+        }
+        break;
+        /////////////////////////
+      case IXR_CMD_LLSC_NLINE:
+        if ( p_vci_ixr.cmdack ) {
+          if( r_llsc_to_ixr_cmd_write.read()){
+            if ( r_ixr_cmd_cpt.read() == (m_words - 1) ) {
+              r_ixr_cmd_cpt = 0;
+              r_ixr_cmd_fsm = IXR_CMD_LLSC_IDLE;
+              r_llsc_to_ixr_cmd_req = false;
+            } else {
+              r_ixr_cmd_cpt = r_ixr_cmd_cpt + 1;
+            }
+          } else {
+            r_ixr_cmd_fsm = IXR_CMD_LLSC_IDLE;		
+            r_llsc_to_ixr_cmd_req = false;
+          }
+        }
+        break;
+        ////////////////////////
+      case IXR_CMD_XRAM_DATA:
+        if ( p_vci_ixr.cmdack ) {
+          if ( r_ixr_cmd_cpt.read() == (m_words - 1) ) {
+            r_ixr_cmd_cpt = 0;
+            r_ixr_cmd_fsm = IXR_CMD_XRAM_IDLE;
+            r_xram_rsp_to_ixr_cmd_req = false;
+          } else {
+            r_ixr_cmd_cpt = r_ixr_cmd_cpt + 1;
+          }
+        }
+        break;
+
+    } // end switch r_ixr_cmd_fsm
+
+    ////////////////////////////////////////////////////////////////////////////
+    //                IXR_RSP FSM
+    ////////////////////////////////////////////////////////////////////////////
+    // The IXR_RSP FSM receives the response packets from the XRAM,
+    // for both write transaction, and read transaction.
+    //
+    // - A response to a write request is a single-cell VCI packet.
+    // The Transaction Tab index is contained in the RTRDID field.
+    // The FSM takes the lock protecting the TRT, and the corresponding
+    // entry is erased.
+    //	
+    // - A response to a read request is a multi-cell VCI packet.
+    // The Transaction Tab index is contained in the RTRDID field.
+    // The N cells contain the N words of the cache line in the RDATA field.
+    // The FSM takes the lock protecting the TRT to store the line in the TRT
+    // (taking into account the write requests already stored in the TRT).
+    // When the line is completely written, the corresponding rok signal is set.
+    ///////////////////////////////////////////////////////////////////////////////
+
+    switch ( r_ixr_rsp_fsm.read() ) {
+
+      ///////////////////
+      case IXR_RSP_IDLE:	// test if it's a read or a write transaction
+        {
+          if ( p_vci_ixr.rspval ) {
+            r_ixr_rsp_cpt   = 0;
+            r_ixr_rsp_trt_index = p_vci_ixr.rtrdid.read();
+            if ( p_vci_ixr.reop )  r_ixr_rsp_fsm = IXR_RSP_ACK;
+            else                   r_ixr_rsp_fsm = IXR_RSP_TRT_READ;
+          }
+          break;  
+        }
+        ////////////////////////
+      case IXR_RSP_ACK:        // Acknowledge the vci response
+        r_ixr_rsp_fsm = IXR_RSP_TRT_ERASE;
+        break;
+        ////////////////////////
+      case IXR_RSP_TRT_ERASE: 	// erase the entry in the TRT
+        {
+          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP ) {
+            m_transaction_tab.erase(r_ixr_rsp_trt_index.read());
+            r_ixr_rsp_fsm = IXR_RSP_IDLE;
+
+#ifdef TDEBUG            
+            TRACE_MSG(m_log << m_total_cycles << " " << name() << " IXR_RSP_TRT_ERASE transaction table : " << std::endl);
+            DUMP_TRANSACTION_TABLE;
+#endif
+
+          }
+          break;
+        }
+        ///////////////////////
+      case IXR_RSP_TRT_READ:		// write data in the TRT
+        {
+          if ( (r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP) &&  p_vci_ixr.rspval ) {
+            bool   eop  	= p_vci_ixr.reop.read();
+            data_t data 	= p_vci_ixr.rdata.read();
+            size_t index        = r_ixr_rsp_trt_index.read();
+            assert( eop == (r_ixr_rsp_cpt.read() == (m_words-1)) 
+                && "Error in VCI_MEM_CACHE : invalid length for a response from XRAM");
+
+
+            if(m_total_cycles > m_debug_start)
+            {
+                m_log << "[ " << std::dec << m_total_cycles << " ]"
+                      << " " << name() << " m_srcid_ini " << m_srcid_ini
+                      << " IXR_RSP_TRT_READ: calling write_rsp with [i:" 
+                      << index
+                      << ",cntr:"
+                      << r_ixr_rsp_cpt.read()
+                      << ",data:" << std::hex
+                      << data << "]" << std::dec << std::endl;
+            }
+
+            m_transaction_tab.write_rsp(index, r_ixr_rsp_cpt.read(), data);
+
+            if(m_total_cycles > m_debug_start)
+            {
+                m_log << std::dec << m_total_cycles
+                      << " " << name()
+                      << " Done" << std::endl;
+            }
+
+            r_ixr_rsp_cpt = r_ixr_rsp_cpt.read() + 1;
+
+            if ( eop ) {
+#ifdef TDEBUG
+                TRACE_MSG(m_log << m_total_cycles << " " << name() << " IXR_RSP_TRT_READ transaction table : " << std::endl);
+                DUMP_TRANSACTION_TABLE;
+#endif
+
+              r_ixr_rsp_to_xram_rsp_rok[r_ixr_rsp_trt_index.read()]=true;
+              r_ixr_rsp_fsm = IXR_RSP_IDLE;
+            }
+          }
+          break;
+        }
+    } // end swich r_ixr_rsp_fsm
+
+
+    ////////////////////////////////////////////////////////////////////////////
+    //                XRAM_RSP FSM
+    ////////////////////////////////////////////////////////////////////////////
+    // The XRAM_RSP FSM handles the incoming cache lines from the XRAM.
+    // The cache line has been written in the TRT buffer by the IXR_FSM.
+    //
+    // When a response is available, the corresponding TRT entry 
+    // is copied in a local buffer to be written in the cache. 
+    // Then, the FSM releases the lock protecting the TRT, and takes the lock 
+    // protecting the cache directory.
+    // It selects a cache slot and writes the line in the cache.
+    // If it was a read MISS, the XRAM_RSP FSM send a request to the TGT_RSP
+    // FSM to return the cache line to the registered processor.
+    // If there is no empty slot, a victim line is evicted, and
+    // invalidate requests are sent to the L1 caches containing copies.
+    // If this line is dirty, the XRAM_RSP FSM send a request to the IXR_CMD 
+    // FSM to save the victim line to the XRAM, and register the write transaction
+    // in the TRT (using the entry previously used by the read transaction).
+    ///////////////////////////////////////////////////////////////////////////////
+
+    switch ( r_xram_rsp_fsm.read() ) {
+
+      ///////////////////
+      case XRAM_RSP_IDLE:	// test if there is a response with a round robin priority
+        {
+          size_t ptr   = r_xram_rsp_trt_index.read();
+          size_t lines = TRANSACTION_TAB_LINES;
+          for(size_t i=0; i<lines; i++){
+            size_t index=(i+ptr+1)%lines;
+            if(r_ixr_rsp_to_xram_rsp_rok[index]){
+              r_xram_rsp_trt_index=index;
+              r_ixr_rsp_to_xram_rsp_rok[index]=false;
+              r_xram_rsp_fsm           = XRAM_RSP_DIR_LOCK;
+              break;
+
+#ifdef TDEBUG
+              TRACE_MSG(m_log << "XRAM_RSP FSM in XRAM_RSP_IDLE state" << std::endl);
+#endif
+            }
+          }
+          break;  
+        }
+        ///////////////////////
+      case XRAM_RSP_DIR_LOCK: 	// Take the lock on the directory
+        {
+          if( r_alloc_dir_fsm.read() == ALLOC_DIR_XRAM_RSP ) {
+            r_xram_rsp_fsm           = XRAM_RSP_TRT_COPY;
+#ifdef TDEBUG
+            TRACE_MSG(m_log << "XRAM_RSP FSM in XRAM_RSP_DIR_LOCK state" << std::endl);
+#endif
+          }
+          break;
+        }
+        ///////////////////////
+      case XRAM_RSP_TRT_COPY:		// Copy the TRT entry in the local buffer and eviction of a cache line
+        {
+          if ( (r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP) ) {
+            size_t index = r_xram_rsp_trt_index.read();
+            TransactionTabEntry    trt_entry(m_transaction_tab.read(index));	
+
+            r_xram_rsp_trt_buf.copy(trt_entry);  // TRT entry local buffer
+
+            // selects & extracts a victim line from cache
+            size_t way = 0;
+            size_t set = m_y[(vci_addr_t)(trt_entry.nline * m_words * 4)];
+            DirectoryEntry victim(m_cache_directory.select(set, way));
+
+            for (size_t i=0 ; i<m_words ; i++) r_xram_rsp_victim_data[i] = m_cache_data[way][set][i];
+
+            bool inval = (victim.count && victim.valid) ;
+
+            r_xram_rsp_victim_copy      = victim.owner.srcid;
+            r_xram_rsp_victim_copy_inst = victim.owner.inst;
+            r_xram_rsp_victim_count     = victim.count;
+            r_xram_rsp_victim_ptr       = victim.ptr;
+            r_xram_rsp_victim_way       = way;
+            r_xram_rsp_victim_set       = set;
+            r_xram_rsp_victim_nline     = victim.tag*m_sets + set;
+            r_xram_rsp_victim_is_cnt    = victim.is_cnt;
+            r_xram_rsp_victim_inval     = inval ;
+            r_xram_rsp_victim_dirty     = victim.dirty;
+
+            r_xram_rsp_fsm = XRAM_RSP_INVAL_LOCK;
+
+#ifdef TDEBUG
+            TRACE_MSG(m_log << "XRAM_RSP FSM in XRAM_RSP_TRT_COPY state" << std::endl);
+            TRACE_MSG(m_log << "Victim way : " << std::hex << way << " set " << std::hex << set << std::endl);
+            DUMP_ENTRY(victim);
+#endif
+          }
+          break;
+        }
+        ///////////////////////
+      case XRAM_RSP_INVAL_LOCK:
+        {
+          if ( r_alloc_upt_fsm == ALLOC_UPT_XRAM_RSP ) 
+          {
+
+#ifdef IDEBUG
+              TRACE_MSG(m_log << "XRAM_RSP FSM in XRAM_RSP_INVAL_LOCK state, line = " 
+                        << std::hex << r_xram_rsp_trt_buf.nline
+                        << std::endl);
+#endif
+              size_t index;
+              
+              if(m_update_tab.search_inval(r_xram_rsp_trt_buf.nline, index))
+              {
+                  r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT;
+                  
+#ifdef IDEBUG
+                  TRACE_MSG(m_log << "XRAM_RSP FSM in XRAM_RSP_INVAL_LOCK state to XRAM_RSP_INVAL_WAIT state" << std::endl);
+                  TRACE_MSG(m_log << "A invalidation is already registered at this address" << std::endl);
+                  
+                  DUMP_UPDATE_TABLE;
+#endif
+              }
+              else if(m_update_tab.is_full() && r_xram_rsp_victim_inval.read())
+              {
+                  r_xram_rsp_fsm = XRAM_RSP_INVAL_WAIT;
+                  
+#ifdef IDEBUG
+                  TRACE_MSG(m_log << "XRAM_RSP FSM in XRAM_RSP_INVAL_LOCK state to XRAM_RSP_INVAL_WAIT state" << std::endl);
+                  TRACE_MSG(m_log << "The inval tab is full" << std::endl);
+
+                  DUMP_UPDATE_TABLE;
+#endif
+              }
+              else 
+              {
+                  r_xram_rsp_fsm = XRAM_RSP_DIR_UPDT;
+#ifdef IDEBUG
+                  TRACE_MSG(m_log << "XRAM_RSP FSM in XRAM_RSP_INVAL_LOCK state to XRAM_RSP_DIR_UPDT state" << std::endl);
+                  DUMP_UPDATE_TABLE;
+#endif
+              }
+          }
+          break;
+        }
+        ///////////////////////
+      case XRAM_RSP_INVAL_WAIT:
+        {
+          r_xram_rsp_fsm = XRAM_RSP_DIR_LOCK;
+#ifdef IDEBUG
+          TRACE_MSG(m_log << "XRAM_RSP FSM in XRAM_RSP_INVAL_WAIT state" << std::endl);
+#endif
+          break;
+        }
+        ///////////////////////
+      case XRAM_RSP_DIR_UPDT:		// updates the cache (both data & directory)
+        {
+          // signals generation
+          bool inst_read = (r_xram_rsp_trt_buf.trdid & 0x2) && r_xram_rsp_trt_buf.proc_read; // It is an instruction read
+          bool cached_read = (r_xram_rsp_trt_buf.trdid & 0x1) && r_xram_rsp_trt_buf.proc_read ;
+          // update data
+          size_t set   = r_xram_rsp_victim_set.read();
+          size_t way   = r_xram_rsp_victim_way.read();
+          for(size_t i=0; i<m_words ; i++){
+            m_cache_data[way][set][i] = r_xram_rsp_trt_buf.wdata[i];
+          }
+          // compute dirty 
+          bool dirty = false;
+          for(size_t i=0; i<m_words;i++){
+            dirty = dirty || (r_xram_rsp_trt_buf.wdata_be[i] != 0);
+          }
+
+          // update directory
+          DirectoryEntry entry;
+          entry.valid	  = true;
+          entry.is_cnt    = false;
+          entry.lock	  = false;
+          entry.dirty	  = dirty;
+          entry.tag	      = r_xram_rsp_trt_buf.nline / m_sets;
+          entry.ptr       = 0;
+          if(cached_read) {
+            if(inst_read) {
+              entry.inst        = true;
+              entry.owner.srcid = r_xram_rsp_trt_buf.srcid;
+              entry.owner.inst  = true;
+              entry.count       = 1;
+            } else {
+              entry.inst        = false;
+              entry.owner.srcid = r_xram_rsp_trt_buf.srcid;
+              entry.owner.inst  = false;
+              entry.count       = 1;
+            }
+          } else {
+            entry.owner.srcid = 0;
+            entry.owner.inst  = 0;
+            entry.inst        = false;
+            entry.count       = 0;
+          }
+          m_cache_directory.write(set, way, entry);
+#ifdef DDEBUG
+          TRACE_MSG(m_log << "printing the entry : " << std::endl);
+          DUMP_ENTRY(entry);
+          TRACE_MSG(m_log << "done" << std::endl);
+#endif
+
+#ifdef TDEBUG
+          TRACE_MSG(m_log << m_total_cycles << " " << name() << " XRAM_RSP_DIR_UPDT transaction table : " << std::endl);
+          DUMP_TRANSACTION_TABLE;
+#endif
+
+          if(r_xram_rsp_victim_inval.read()){
+            bool    brdcast = r_xram_rsp_victim_is_cnt.read();
+            size_t index;
+            size_t count_copies = r_xram_rsp_victim_count.read();
+
+            bool	 wok = m_update_tab.set(false,	// it's an inval transaction
+                                            brdcast,                          // set brdcast bit
+                                            false,  // it does not need a response
+                                            0,
+                                            0,
+                                            0,
+                                            r_xram_rsp_victim_nline.read(),
+                                            count_copies,
+                                            index);
+
+#ifdef IDEBUG
+            TRACE_MSG(m_log << "xram_rsp : record invalidation, time = " << std::dec << m_cpt_cycles << std::endl);
+            
+            DUMP_UPDATE_TABLE;
+#endif
+            r_xram_rsp_upt_index = index;
+            if(!wok) {
+              assert(false && "mem_cache error : xram_rsp_dir_upt, an update_tab entry was free but write unsuccessful");
+            }
+          }
+          // If the victim is not dirty, we erase the entry in the TRT
+          if      (!r_xram_rsp_victim_dirty.read()){
+              m_transaction_tab.erase(r_xram_rsp_trt_index.read());
+
+	  }
+          // Next state
+          if      ( r_xram_rsp_victim_dirty.read())       r_xram_rsp_fsm = XRAM_RSP_TRT_DIRTY;
+          else if ( r_xram_rsp_trt_buf.proc_read  )       r_xram_rsp_fsm = XRAM_RSP_DIR_RSP;
+          else if ( r_xram_rsp_victim_inval.read())       r_xram_rsp_fsm = XRAM_RSP_INVAL;
+          else                                            r_xram_rsp_fsm = XRAM_RSP_IDLE;
+          break;
+        }
+        ////////////////////////
+      case XRAM_RSP_TRT_DIRTY:		// set the TRT entry (write line to XRAM) if the victim is dirty
+        {
+          if ( r_alloc_trt_fsm.read() == ALLOC_TRT_XRAM_RSP ) {
+            m_transaction_tab.set(r_xram_rsp_trt_index.read(),
+                false,				// write to XRAM
+                r_xram_rsp_victim_nline.read(), // line index
+                0,
+                0,
+                0,
+                false,
+                0,
+                0,
+                std::vector<be_t>(m_words,0),
+                std::vector<data_t>(m_words,0) );
+#ifdef TDEBUG
+            TRACE_MSG(m_log << m_total_cycles << " " << name() << " XRAM_RSP_TRT_DIRTY transaction table : " << std::endl);
+            DUMP_TRANSACTION_TABLE;
+#endif
+
+            if      ( r_xram_rsp_trt_buf.proc_read  )       r_xram_rsp_fsm = XRAM_RSP_DIR_RSP;
+            else if ( r_xram_rsp_victim_inval.read())       r_xram_rsp_fsm = XRAM_RSP_INVAL;
+            else                                            r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
+          }
+          break;
+        }
+        //////////////////////
+      case XRAM_RSP_DIR_RSP:     // send a request to TGT_RSP FSM in case of read
+        {
+          if ( !r_xram_rsp_to_tgt_rsp_req.read() ) {
+            r_xram_rsp_to_tgt_rsp_srcid = r_xram_rsp_trt_buf.srcid;
+            r_xram_rsp_to_tgt_rsp_trdid = r_xram_rsp_trt_buf.trdid;
+            r_xram_rsp_to_tgt_rsp_pktid = r_xram_rsp_trt_buf.pktid;
+            for (size_t i=0; i < m_words; i++) {
+              r_xram_rsp_to_tgt_rsp_data[i] = r_xram_rsp_trt_buf.wdata[i];
+            } 
+            r_xram_rsp_to_tgt_rsp_word   = r_xram_rsp_trt_buf.word_index;
+            r_xram_rsp_to_tgt_rsp_length = r_xram_rsp_trt_buf.read_length;
+            r_xram_rsp_to_tgt_rsp_req    = true;
+
+            if      ( r_xram_rsp_victim_inval ) r_xram_rsp_fsm = XRAM_RSP_INVAL;
+            else if ( r_xram_rsp_victim_dirty ) r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY; 
+            else                                r_xram_rsp_fsm = XRAM_RSP_IDLE;
+
+#ifdef DDEBUG
+            TRACE_MSG(m_log << "XRAM_RSP FSM in XRAM_RSP_DIR_RSP state" << std::endl);
+#endif
+          }
+          break;
+        }
+        ////////////////////
+      case XRAM_RSP_INVAL:	// send invalidate request to INIT_CMD FSM
+        {
+          if(   !r_xram_rsp_to_init_cmd_multi_req.read() && 
+                !r_xram_rsp_to_init_cmd_brdcast_req.read() ) {	      
+            
+            bool multi_req = !r_xram_rsp_victim_is_cnt.read();
+            bool last_multi_req  = multi_req && (r_xram_rsp_victim_count.read() == 1);
+            bool not_last_multi_req = multi_req && (r_xram_rsp_victim_count.read() != 1);
+
+            r_xram_rsp_to_init_cmd_multi_req    = last_multi_req; 
+            r_xram_rsp_to_init_cmd_brdcast_req  = r_xram_rsp_victim_is_cnt.read();
+            r_xram_rsp_to_init_cmd_nline        = r_xram_rsp_victim_nline.read();
+            r_xram_rsp_to_init_cmd_trdid        = r_xram_rsp_upt_index;
+            xram_rsp_to_init_cmd_fifo_srcid     = r_xram_rsp_victim_copy.read();
+            xram_rsp_to_init_cmd_fifo_inst      = r_xram_rsp_victim_copy_inst.read();
+            xram_rsp_to_init_cmd_fifo_put       = multi_req;
+            
+            r_xram_rsp_next_ptr                 = r_xram_rsp_victim_ptr.read();
+
+            if ( r_xram_rsp_victim_dirty )  r_xram_rsp_fsm = XRAM_RSP_WRITE_DIRTY;
+            else if (not_last_multi_req)    r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE;
+            else                            r_xram_rsp_fsm = XRAM_RSP_IDLE;
+#ifdef IDEBUG
+            TRACE_MSG(m_log << "XRAM_RSP FSM in XRAM_RSP_INVAL state" << std::endl);
+#endif
+          }
+          break;
+        }
+        //////////////////////////
+      case XRAM_RSP_WRITE_DIRTY:	// send a write request to IXR_CMD FSM
+        {
+          if ( !r_xram_rsp_to_ixr_cmd_req.read() ) {
+            r_xram_rsp_to_ixr_cmd_req = true;
+            r_xram_rsp_to_ixr_cmd_nline = r_xram_rsp_victim_nline.read();
+            r_xram_rsp_to_ixr_cmd_trdid = r_xram_rsp_trt_index.read();
+            for(size_t i=0; i<m_words ; i++) {
+              r_xram_rsp_to_ixr_cmd_data[i] = r_xram_rsp_victim_data[i];
+            }
+            m_cpt_write_dirty++;
+            bool multi_req = !r_xram_rsp_victim_is_cnt.read() && r_xram_rsp_victim_inval.read();
+            bool not_last_multi_req = multi_req && (r_xram_rsp_victim_count.read() != 1);
+            if ( not_last_multi_req )   r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE;
+            else                        r_xram_rsp_fsm = XRAM_RSP_IDLE;
+#ifdef TDEBUG
+            TRACE_MSG(m_log << "XRAM_RSP FSM in XRAM_RSP_WRITE_DIRTY state" << std::endl);
+#endif
+          }
+          break;
+        }
+        //////////////////////////
+      case XRAM_RSP_HEAP_ERASE:	// erase the list of copies and sent invalidations
+        {
+          if( r_alloc_heap_fsm.read() == ALLOC_HEAP_XRAM_RSP ) {
+            HeapEntry entry = m_heap_directory.read(r_xram_rsp_next_ptr.read());
+            xram_rsp_to_init_cmd_fifo_srcid = entry.owner.srcid;
+            xram_rsp_to_init_cmd_fifo_inst  = entry.owner.inst;
+            xram_rsp_to_init_cmd_fifo_put   = true;
+            if( m_xram_rsp_to_init_cmd_inst_fifo.wok() ){
+              r_xram_rsp_next_ptr = entry.next;
+              if( entry.next == r_xram_rsp_next_ptr.read() ){ // last copy
+                r_xram_rsp_to_init_cmd_multi_req = true;
+                r_xram_rsp_fsm = XRAM_RSP_HEAP_LAST;
+              } else {
+                r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE;
+              }
+            } else {
+              r_xram_rsp_fsm = XRAM_RSP_HEAP_ERASE;
+            }
+          }
+          break;
+        }
+        //////////////////////////
+      case XRAM_RSP_HEAP_LAST:	// last member of the list
+        {
+          assert((r_alloc_heap_fsm.read() == ALLOC_HEAP_XRAM_RSP) &&
+                  "MemCache ERROR : bad HEAP allocation");
+          size_t free_pointer = m_heap_directory.next_free_ptr();
+
+          HeapEntry last_entry;
+          last_entry.owner.srcid = 0;
+          last_entry.owner.inst  = false;
+          if(m_heap_directory.is_full()){
+            last_entry.next     = r_xram_rsp_next_ptr.read();
+            m_heap_directory.unset_full();
+          } else {
+            last_entry.next     = free_pointer;
+          }
+
+          m_heap_directory.write_free_ptr(r_xram_rsp_victim_ptr.read());
+          m_heap_directory.write(r_xram_rsp_next_ptr.read(),last_entry);
+
+          r_xram_rsp_fsm = XRAM_RSP_IDLE;
+
+          break;
+        }
+    } // end swich r_xram_rsp_fsm
+
+    ////////////////////////////////////////////////////////////////////////////////////
+    //		CLEANUP FSM
+    ////////////////////////////////////////////////////////////////////////////////////
+    // The CLEANUP FSM handles the cleanup request from L1 caches.
+    // It accesses the cache directory to update the list of copies.
+    //
+    ////////////////////////////////////////////////////////////////////////////////////
+    switch ( r_cleanup_fsm.read() ) {
+
+      ///////////////////
+      case CLEANUP_IDLE:
+        {
+
+          if ( p_vci_tgt_cleanup.cmdval.read() ) {
+            assert( (p_vci_tgt_cleanup.srcid.read() < m_initiators) &&
+                "VCI_MEM_CACHE error in VCI_MEM_CACHE in the CLEANUP network : The received SRCID is larger than the number of initiators");
+            bool reached = false;
+            for ( size_t index = 0 ; index < ncseg && !reached ; index++ ){
+              if ( m_cseg[index]->contains((addr_t)(p_vci_tgt_cleanup.address.read())) ){
+                reached = true;
+              }
+            }
+            if ( (p_vci_tgt_cleanup.cmd.read() == vci_param::CMD_WRITE) &&
+                (((addr_t)(p_vci_tgt_cleanup.address.read())&0x3) != 0x3) &&
+                reached) {
+
+              m_cpt_cleanup++;
+
+              r_cleanup_nline      = (addr_t)(m_nline[(vci_addr_t)(p_vci_tgt_cleanup.address.read())]) ;
+              r_cleanup_srcid      = p_vci_tgt_cleanup.srcid.read();
+              r_cleanup_trdid      = p_vci_tgt_cleanup.trdid.read();
+              r_cleanup_pktid      = p_vci_tgt_cleanup.pktid.read();
+
+              r_cleanup_fsm        = CLEANUP_DIR_LOCK;
+            }
+          }
+          break;
+        }
+        //////////////////////
+      case CLEANUP_DIR_LOCK:
+        {
+          if ( r_alloc_dir_fsm.read() == ALLOC_DIR_CLEANUP ) {
+
+            // Read the directory
+            size_t way = 0;
+	   addr_t cleanup_address = r_cleanup_nline.read() * m_words * 4;
+           DirectoryEntry entry = m_cache_directory.read(cleanup_address , way);
+#ifdef DDEBUG
+           TRACE_MSG(m_log << "In CLEANUP_DIR_LOCK printing the entry of address is : " << std::hex << cleanup_address << std::endl);
+           DUMP_ENTRY(entry);
+           TRACE_MSG(m_log << "done" << std::endl);
+#endif
+            r_cleanup_is_cnt    = entry.is_cnt;
+            r_cleanup_dirty	    = entry.dirty;
+            r_cleanup_tag	    = entry.tag;
+            r_cleanup_lock	    = entry.lock;
+            r_cleanup_inst      = entry.inst;
+            r_cleanup_way	    = way;
+            r_cleanup_copy      = entry.owner.srcid;
+            r_cleanup_copy_inst = entry.owner.inst;
+            r_cleanup_count     = entry.count;
+            r_cleanup_ptr       = entry.ptr;
+
+
+            // In case of hit, the copy must be cleaned in the copies bit-vector
+            if( entry.valid){
+              if ( (entry.count==1) || (entry.is_cnt) )  { // no access to the heap
+                r_cleanup_fsm = CLEANUP_DIR_WRITE;
+              } else {
+                r_cleanup_fsm = CLEANUP_HEAP_LOCK;
+              }
+            } else {
+              r_cleanup_fsm = CLEANUP_UPT_LOCK;
+            }
+          }
+          break;
+        }
+        ///////////////////////
+      case CLEANUP_DIR_WRITE:
+        {
+          assert( (r_alloc_dir_fsm.read() == ALLOC_DIR_CLEANUP ) && 
+                "MemCache ERROR : Bad DIR allocation");
+          size_t way      = r_cleanup_way.read();
+#define L2 soclib::common::uint32_log2
+          size_t set      = m_y[(vci_addr_t)(r_cleanup_nline.read() << (L2(m_words) +2))];
+#undef L2
+          bool cleanup_inst  = r_cleanup_trdid.read() & 0x1; 
+          bool match_srcid   = (r_cleanup_copy.read() == r_cleanup_srcid.read());
+          bool match_inst    = (r_cleanup_copy_inst.read()  == cleanup_inst);
+          bool match         = match_srcid && match_inst;
+
+          // update the cache directory (for the copies)
+          DirectoryEntry entry;
+          entry.valid	= true;
+          entry.is_cnt  = r_cleanup_is_cnt.read();
+          entry.dirty	= r_cleanup_dirty.read();
+          entry.tag	    = r_cleanup_tag.read();
+          entry.lock	= r_cleanup_lock.read();
+          entry.ptr     = r_cleanup_ptr.read();
+          if(r_cleanup_is_cnt.read()) { // Directory is a counter
+            entry.count  = r_cleanup_count.read() -1;
+            if((r_cleanup_count.read()-1) == 0){
+              entry.inst    = false;
+            } else {
+              entry.inst    = r_cleanup_inst.read();
+            }
+            entry.owner.srcid = 0;
+            entry.owner.inst  = 0;
+            // response to the cache 
+            r_cleanup_fsm = CLEANUP_RSP;
+          }
+          else{                         // Directory is a list
+            if(match) { // hit
+              entry.count       = 0; // no more copy
+              entry.owner.srcid = 0;
+              entry.owner.inst  = 0;
+              entry.inst        = false;
+              r_cleanup_fsm     = CLEANUP_RSP; 
+            } else { // miss
+              entry.count       = r_cleanup_count.read();
+              entry.owner.srcid = r_cleanup_copy.read();
+              entry.owner.inst  = r_cleanup_copy_inst.read();
+              entry.inst        = r_cleanup_inst.read();
+              r_cleanup_fsm     = CLEANUP_UPT_LOCK;
+            }
+          }
+          m_cache_directory.write(set, way, entry);  
+
+          break;
+        }
+        /////////////////
+      case CLEANUP_HEAP_LOCK:
+        {
+          if(r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP){
+            size_t way      = r_cleanup_way.read();
+#define L2 soclib::common::uint32_log2
+            size_t set      = m_y[(vci_addr_t)(r_cleanup_nline.read() << (L2(m_words) +2))];
+#undef L2
+            HeapEntry heap_entry = m_heap_directory.read(r_cleanup_ptr.read());
+            bool last = (heap_entry.next == r_cleanup_ptr.read());
+            bool cleanup_inst       = r_cleanup_trdid.read() & 0x1; 
+            bool match_dir_srcid    = (r_cleanup_copy.read() == r_cleanup_srcid.read());
+            bool match_dir_inst     = (r_cleanup_copy_inst.read()  == cleanup_inst);
+            bool match_dir          = match_dir_srcid && match_dir_inst;
+            bool match_heap_srcid   = (heap_entry.owner.srcid == r_cleanup_srcid.read());
+            bool match_heap_inst    = (heap_entry.owner.inst  == cleanup_inst);
+            bool match_heap         = match_heap_srcid && match_heap_inst;
+
+            r_cleanup_prev_ptr = r_cleanup_ptr.read();
+            r_cleanup_prev_srcid = heap_entry.owner.srcid;
+            r_cleanup_prev_inst  = heap_entry.owner.inst;
+
+            if(match_dir){
+              DirectoryEntry dir_entry;
+              dir_entry.valid	    = true;
+              dir_entry.is_cnt      = r_cleanup_is_cnt.read();
+              dir_entry.dirty	    = r_cleanup_dirty.read();
+              dir_entry.tag	        = r_cleanup_tag.read();
+              dir_entry.lock	    = r_cleanup_lock.read();
+              dir_entry.ptr         = heap_entry.next;
+              dir_entry.count       = r_cleanup_count.read()-1;
+              dir_entry.owner.srcid = heap_entry.owner.srcid;
+              dir_entry.owner.inst  = heap_entry.owner.inst;
+              dir_entry.inst        = r_cleanup_inst.read();
+              m_cache_directory.write(set,way,dir_entry);
+              r_cleanup_next_ptr    = r_cleanup_ptr.read();
+              r_cleanup_fsm         = CLEANUP_HEAP_FREE;
+            }
+            else if(match_heap){
+              DirectoryEntry dir_entry;
+              dir_entry.valid	    = true;
+              dir_entry.is_cnt      = r_cleanup_is_cnt.read();
+              dir_entry.dirty	    = r_cleanup_dirty.read();
+              dir_entry.tag	        = r_cleanup_tag.read();
+              dir_entry.lock	    = r_cleanup_lock.read();
+              dir_entry.ptr         = heap_entry.next;
+              dir_entry.count       = r_cleanup_count.read()-1;
+              dir_entry.owner.srcid = r_cleanup_copy.read();
+              dir_entry.owner.inst  = r_cleanup_copy_inst.read();
+              dir_entry.inst        = r_cleanup_inst.read();
+              m_cache_directory.write(set,way,dir_entry);
+              r_cleanup_next_ptr    = r_cleanup_ptr.read();
+              r_cleanup_fsm         = CLEANUP_HEAP_FREE; 
+            }
+            else{
+              if(!last){
+                DirectoryEntry dir_entry;
+                dir_entry.valid	        = true;
+                dir_entry.is_cnt        = r_cleanup_is_cnt.read();
+                dir_entry.dirty	        = r_cleanup_dirty.read();
+                dir_entry.tag	        = r_cleanup_tag.read();
+                dir_entry.lock	        = r_cleanup_lock.read();
+                dir_entry.ptr           = r_cleanup_ptr.read();
+                dir_entry.count         = r_cleanup_count.read()-1;
+                dir_entry.owner.srcid   = r_cleanup_copy.read();
+                dir_entry.owner.inst    = r_cleanup_copy_inst.read();
+                dir_entry.inst          = r_cleanup_inst.read();
+                m_cache_directory.write(set,way,dir_entry);
+
+                r_cleanup_next_ptr = heap_entry.next;
+                r_cleanup_fsm      = CLEANUP_HEAP_SEARCH;
+
+              } else{
+                assert(false && "MemCache ERROR : CLEANUP hit but line not shared");
+              }
+            }
+          }
+          break;
+        }
+        /////////////////
+      case CLEANUP_HEAP_SEARCH:
+        {
+          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP) &&
+                    "MemCache ERROR : bad HEAP allocation");
+          HeapEntry heap_entry = m_heap_directory.read(r_cleanup_next_ptr.read());
+          bool last = (heap_entry.next == r_cleanup_next_ptr.read());
+          bool cleanup_inst       = r_cleanup_trdid.read() & 0x1; 
+          bool match_heap_srcid   = (heap_entry.owner.srcid == r_cleanup_srcid.read());
+          bool match_heap_inst    = (heap_entry.owner.inst  == cleanup_inst);
+          bool match_heap         = match_heap_srcid && match_heap_inst;
+
+          if(match_heap){
+            r_cleanup_ptr           = heap_entry.next; // reuse ressources
+            r_cleanup_fsm = CLEANUP_HEAP_CLEAN;
+          }
+          else{
+            if(last) {
+              assert(false && "MemCache ERROR : CLEANUP hit but line not shared");
+            } else {
+              r_cleanup_prev_ptr = r_cleanup_next_ptr.read();
+              r_cleanup_prev_srcid = heap_entry.owner.srcid;
+              r_cleanup_prev_inst  = heap_entry.owner.inst;
+              r_cleanup_next_ptr = heap_entry.next;
+              r_cleanup_fsm      = CLEANUP_HEAP_SEARCH;
+            }
+          }
+
+          break;
+        }
+        /////////////////
+      case CLEANUP_HEAP_CLEAN:
+        {
+          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP) &&
+                    "MemCache ERROR : bad HEAP allocation");
+          bool last = (r_cleanup_next_ptr.read() == r_cleanup_ptr.read());
+          HeapEntry heap_entry; 
+          heap_entry.owner.srcid = r_cleanup_prev_srcid.read();
+          heap_entry.owner.inst  = r_cleanup_prev_inst.read();
+          if(last){ // this is the last entry of the list of copies
+            heap_entry.next     = r_cleanup_prev_ptr.read();
+          } else { // this is not the last entry
+            heap_entry.next     = r_cleanup_ptr.read();
+          }
+          m_heap_directory.write(r_cleanup_prev_ptr.read(),heap_entry);
+          r_cleanup_fsm = CLEANUP_HEAP_FREE;
+          break;
+        }
+        /////////////////
+      case CLEANUP_HEAP_FREE:
+        {
+          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_CLEANUP) &&
+                    "MemCache ERROR : bad HEAP allocation");
+          HeapEntry heap_entry;
+          heap_entry.owner.srcid = 0;
+          heap_entry.owner.inst  = false;
+          if(m_heap_directory.is_full()){
+            heap_entry.next     = r_cleanup_next_ptr.read();
+          } else {
+            heap_entry.next     = m_heap_directory.next_free_ptr();
+          }
+          m_heap_directory.write(r_cleanup_next_ptr.read(),heap_entry);
+          m_heap_directory.write_free_ptr(r_cleanup_next_ptr.read());
+          m_heap_directory.unset_full();
+          r_cleanup_fsm = CLEANUP_RSP;
+          break;
+        }
+        /////////////////
+      case CLEANUP_UPT_LOCK:
+        {
+          if( r_alloc_upt_fsm.read() == ALLOC_UPT_CLEANUP )
+          {
+            size_t index;
+            bool hit_inval;
+            hit_inval = m_update_tab.search_inval(r_cleanup_nline.read(),index);
+            if(!hit_inval) {
+#ifdef DEBUG_VCI_MEM_CACHE
+                TRACE_MSG(m_log << "MEM_CACHE WARNING: cleanup with no corresponding entry at address : " << std::hex << (r_cleanup_nline.read()*4*m_words) << std::dec << std::endl);
+#endif
+              r_cleanup_fsm = CLEANUP_RSP;
+            } else {
+              r_cleanup_write_srcid = m_update_tab.srcid(index);
+              r_cleanup_write_trdid = m_update_tab.trdid(index);
+              r_cleanup_write_pktid = m_update_tab.pktid(index);
+              r_cleanup_need_rsp    = m_update_tab.need_rsp(index);
+              r_cleanup_fsm = CLEANUP_UPT_WRITE;
+            }
+            r_cleanup_index.write(index) ; 
+          }
+          break;
+        }
+        /////////////////
+      case CLEANUP_UPT_WRITE:
+        {
+          size_t count = 0;
+          m_update_tab.decrement(r_cleanup_index.read(), count); // &count
+          if(count == 0){
+            m_update_tab.clear(r_cleanup_index.read());
+#ifdef IDEBUG
+            TRACE_MSG(m_log << m_total_cycles << " " << name() << " CLEANUP_UPT_WRITE update table : " << std::endl);
+            DUMP_UPDATE_TABLE;
+#endif
+
+            if(r_cleanup_need_rsp.read()){
+              r_cleanup_fsm = CLEANUP_WRITE_RSP ;
+            } else {
+              r_cleanup_fsm = CLEANUP_RSP;
+            }
+          } else {
+            r_cleanup_fsm = CLEANUP_RSP ;
+          }
+          break;
+        }
+        /////////////////
+      case CLEANUP_WRITE_RSP:
+        {
+          if( !r_cleanup_to_tgt_rsp_req.read()) {
+            r_cleanup_to_tgt_rsp_req     = true;
+            r_cleanup_to_tgt_rsp_srcid   = r_cleanup_write_srcid.read();
+            r_cleanup_to_tgt_rsp_trdid   = r_cleanup_write_trdid.read();
+            r_cleanup_to_tgt_rsp_pktid   = r_cleanup_write_pktid.read();
+            r_cleanup_fsm = CLEANUP_RSP;
+          }
+          break;
+        }
+        /////////////////
+      case CLEANUP_RSP:
+        {
+          if(p_vci_tgt_cleanup.rspack)
+            r_cleanup_fsm = CLEANUP_IDLE;
+          break;
+        }
+    } // end switch cleanup fsm
+
+
+    ////////////////////////////////////////////////////////////////////////////////////
+    //		LLSC FSM
+    ////////////////////////////////////////////////////////////////////////////////////
+    // The LLSC FSM handles the LL & SC atomic access.
+    //
+    // For a LL :
+    // It access the directory to check hit / miss.
+    // - In case of hit, the LL request is registered in the Atomic Table and the
+    // response is sent to the requesting processor.
+    // - In case of miss, the LLSC FSM accesses the transaction table. 
+    // If a read transaction to the XRAM for this line already exists, 
+    // or if the transaction table is full, it returns to IDLE state.
+    // Otherwise, a new transaction to the XRAM is initiated.
+    // In both cases, the LL request is not consumed in the FIFO.
+    //
+    // For a SC :
+    // It access the directory to check hit / miss.
+    // - In case of hit, the Atomic Table is checked and the proper response
+    // (true or false is sent to the requesting processor.
+    // - In case of miss, the LLSC FSM accesses the transaction table. 
+    // If a read transaction to the XRAM for this line already exists, 
+    // or if the transaction table is full, it returns to IDLE state. 
+    // Otherwise, a new transaction to the XRAM is initiated.
+    // In both cases, the SC request is not consumed in the FIFO.
+    /////////////////////////////////////////////////////////////////////
+
+    switch ( r_llsc_fsm.read() ) {
+
+      ///////////////
+      case LLSC_IDLE:		// test LL / SC
+        {
+          if( m_cmd_llsc_addr_fifo.rok() ) {
+            if(m_cmd_llsc_sc_fifo.read()){
+              m_cpt_sc++;
+              r_llsc_fsm = SC_DIR_LOCK;
+            }
+            else{
+              m_cpt_ll++;
+              r_llsc_fsm = LL_DIR_LOCK;
+            }
+          }	
+          break;
+        }
+        /////////////////
+      case LL_DIR_LOCK:		// check directory for hit / miss
+        {
+          if( r_alloc_dir_fsm.read() == ALLOC_DIR_LLSC ) {
+            size_t way = 0;
+            DirectoryEntry entry(m_cache_directory.read(m_cmd_llsc_addr_fifo.read(), way));
+            r_llsc_is_cnt     = entry.is_cnt;
+            r_llsc_dirty      = entry.dirty;
+            r_llsc_inst       = entry.inst;
+            r_llsc_tag        = entry.tag;
+            r_llsc_way        = way;
+            r_llsc_copy       = entry.owner.srcid;
+            r_llsc_copy_inst  = entry.owner.inst;
+            r_llsc_count      = entry.count;
+            r_llsc_ptr        = entry.ptr;
+
+            // set Atomic Table
+            m_atomic_tab.set(m_cmd_llsc_srcid_fifo.read(), m_cmd_llsc_addr_fifo.read());
+
+            if ( entry.valid )  r_llsc_fsm = LL_DIR_HIT;
+            else                r_llsc_fsm = LLSC_TRT_LOCK;
+          }
+          break;
+        }
+        ////////////////
+      case LL_DIR_HIT:		// read hit : update the memory cache
+        {
+          size_t way	= r_llsc_way.read();
+          size_t set	= m_y[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
+          size_t word	= m_x[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
+
+          // update directory (lock bit & copies)
+          DirectoryEntry entry;
+          entry.valid	    = true;
+          entry.is_cnt      = r_llsc_is_cnt.read();
+          entry.dirty	    = r_llsc_dirty.read();
+          entry.lock	    = true;
+          entry.inst        = r_llsc_inst.read();
+          entry.tag	        = r_llsc_tag.read();
+          entry.owner.srcid = r_llsc_copy.read();
+          entry.owner.inst  = r_llsc_copy_inst.read();
+          entry.count       = r_llsc_count.read();
+          entry.ptr         = r_llsc_ptr.read();
+          m_cache_directory.write(set, way, entry);
+
+          // read data in cache
+          r_llsc_data	= m_cache_data[way][set][word];
+
+          r_llsc_fsm 	= LL_RSP;
+          break;
+        }
+        ////////////
+      case LL_RSP:		// request the TGT_RSP FSM to return data
+        {
+          if ( !r_llsc_to_tgt_rsp_req ) {
+            cmd_llsc_fifo_get		= true;
+            r_llsc_to_tgt_rsp_data	= r_llsc_data.read();
+            r_llsc_to_tgt_rsp_srcid	= m_cmd_llsc_srcid_fifo.read();
+            r_llsc_to_tgt_rsp_trdid	= m_cmd_llsc_trdid_fifo.read();
+            r_llsc_to_tgt_rsp_pktid	= m_cmd_llsc_pktid_fifo.read();
+            r_llsc_to_tgt_rsp_req	= true;
+            r_llsc_fsm = LLSC_IDLE;
+          }
+          break;
+        }
+        /////////////////
+      case SC_DIR_LOCK:
+        {
+          if( r_alloc_dir_fsm.read() == ALLOC_DIR_LLSC ) {
+            size_t way = 0;
+            DirectoryEntry entry(m_cache_directory.read(m_cmd_llsc_addr_fifo.read(), way));
+            bool ok = m_atomic_tab.isatomic(m_cmd_llsc_srcid_fifo.read(),m_cmd_llsc_addr_fifo.read());
+            if( ok ) {
+              r_llsc_is_cnt   = entry.is_cnt;
+              r_llsc_dirty    = entry.dirty;
+              r_llsc_tag      = entry.tag;
+              r_llsc_way      = way;
+              r_llsc_copy     = entry.owner.srcid;
+              r_llsc_copy_inst= entry.owner.inst;
+              r_llsc_inst     = entry.inst;
+              r_llsc_ptr      = entry.ptr;
+              r_llsc_count    = entry.count;
+              if ( entry.valid ){
+                if((entry.is_cnt && entry.count) || entry.inst) {
+                  r_llsc_fsm = SC_TRT_LOCK;
+                } else {
+                  r_llsc_fsm = SC_DIR_HIT;
+                }
+              }
+              else r_llsc_fsm = LLSC_TRT_LOCK;
+            } else {
+              r_llsc_fsm = SC_RSP_FALSE;
+            }
+          }
+          break;
+        }
+        ////////////////
+      case SC_DIR_HIT:
+        {
+          size_t way	= r_llsc_way.read();
+          size_t set	= m_y[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())]; 
+          size_t word	= m_x[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())]; 
+
+          // update directory (lock & dirty bits
+          DirectoryEntry entry;
+          entry.valid	    = true;
+          entry.is_cnt      = r_llsc_is_cnt.read();
+          entry.dirty	    = true;
+          entry.lock	    = true;
+          entry.inst        = r_llsc_inst.read();
+          entry.tag	        = r_llsc_tag.read();
+          entry.owner.srcid = r_llsc_copy.read();
+          entry.owner.inst  = r_llsc_copy_inst.read();
+          entry.count       = r_llsc_count.read();
+          entry.ptr         = r_llsc_ptr.read();
+          m_cache_directory.write(set, way, entry);
+
+          if(!r_llsc_count.read()){ // no update
+            // write data in cache
+            m_cache_data[way][set][word] = m_cmd_llsc_wdata_fifo.read();
+            // reset Atomic Table
+            m_atomic_tab.reset(m_cmd_llsc_addr_fifo.read());
+          }
+          
+          if(r_llsc_count.read()) {  // Shared line
+              if( !r_llsc_to_init_cmd_multi_req.read() && 
+                  !r_llsc_to_init_cmd_brdcast_req.read()  )
+                  r_llsc_fsm = SC_UPT_LOCK;
+              else
+                  r_llsc_fsm = SC_WAIT;
+          } else {
+            r_llsc_fsm = SC_RSP_TRUE;
+          }
+          break;
+        }
+        /////////////////////
+      case SC_UPT_LOCK: 	// Try to register the request in Update Table
+        {
+
+          if ( r_alloc_upt_fsm.read() == ALLOC_UPT_LLSC ) {
+            size_t way	= r_llsc_way.read();
+            size_t set	= m_y[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())]; 
+            size_t word	= m_x[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())]; 
+            bool        wok        = false;
+            size_t      index      = 0;
+            size_t      srcid      = m_cmd_llsc_srcid_fifo.read();
+            size_t      trdid      = m_cmd_llsc_trdid_fifo.read();
+            size_t      pktid      = m_cmd_llsc_pktid_fifo.read();
+            addr_t	    nline      = m_nline[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
+            size_t      nb_copies  = r_llsc_count.read();
+
+            wok =m_update_tab.set(true,	// it's an update transaction
+                false,                  // it's not a broadcast
+                true,                   // it needs a response
+                srcid,
+                trdid,
+                pktid,
+                nline,
+                nb_copies,
+                index);
+            if(wok){
+              // write data in cache
+              m_cache_data[way][set][word] = m_cmd_llsc_wdata_fifo.read();
+              // reset Atomic Table
+              m_atomic_tab.reset(m_cmd_llsc_addr_fifo.read());
+            }
+#ifdef IDEBUG
+            if(wok){
+                TRACE_MSG(m_log << m_total_cycles << " " << name() << " SC_UPT_LOCK update table : " << std::endl);
+                DUMP_UPDATE_TABLE;
+            }
+#endif
+            r_llsc_upt_index = index;
+            //  releases the lock protecting the Update Table and the Directory if no entry...
+            if ( wok ) r_llsc_fsm = SC_HEAP_LOCK;
+            else       r_llsc_fsm = SC_WAIT;
+          }
+          break;
+        }
+        ////////////////////
+      case SC_WAIT: 	// release all locks
+        {
+          r_llsc_fsm = SC_DIR_LOCK;
+          break;
+        }
+        ////////////////////
+      case SC_HEAP_LOCK: 	// lock the heap
+        {
+          if( r_alloc_heap_fsm.read() == ALLOC_HEAP_LLSC ){
+            r_llsc_fsm = SC_UPT_REQ;
+          }
+          break;
+        }
+        ////////////////////
+      case SC_UPT_REQ: 	// Request the update
+        {
+          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_LLSC) &&
+                    "MemCache ERROR : bad HEAP allocation");
+          if( !r_llsc_to_init_cmd_multi_req.read() && 
+              !r_llsc_to_init_cmd_brdcast_req.read()  ){
+            r_llsc_to_init_cmd_brdcast_req  = false;
+            r_llsc_to_init_cmd_trdid        = r_llsc_upt_index.read();
+            r_llsc_to_init_cmd_nline        = m_nline[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
+            r_llsc_to_init_cmd_index        = m_x[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
+            r_llsc_to_init_cmd_wdata        = m_cmd_llsc_wdata_fifo.read();
+
+            // We put the first copy in the fifo
+            llsc_to_init_cmd_fifo_put     = true;
+            llsc_to_init_cmd_fifo_inst    = r_llsc_copy_inst.read();
+            llsc_to_init_cmd_fifo_srcid   = r_llsc_copy.read();
+            if(r_llsc_count.read() == 1){
+              r_llsc_fsm = LLSC_IDLE;
+              cmd_llsc_fifo_get            = true;
+              r_llsc_to_init_cmd_multi_req = true;
+            } else {
+              r_llsc_fsm = SC_UPDATE;
+            }
+          }
+          break;
+        }
+        //////////////////
+      case SC_UPDATE:   	// send a multi-update request to INIT_CMD fsm
+        {
+          assert( (r_alloc_heap_fsm.read() == ALLOC_HEAP_LLSC) &&
+                    "MemCache ERROR : bad HEAP allocation");
+          HeapEntry entry = m_heap_directory.read(r_llsc_ptr.read());
+          llsc_to_init_cmd_fifo_inst  = entry.owner.inst;
+          llsc_to_init_cmd_fifo_srcid = entry.owner.srcid;
+          llsc_to_init_cmd_fifo_put = true;
+
+          if( m_llsc_to_init_cmd_inst_fifo.wok() ){
+            r_llsc_ptr = entry.next;
+            if( entry.next == r_llsc_ptr.read() ) { // last copy
+              r_llsc_to_init_cmd_multi_req = true;
+              r_llsc_fsm = LLSC_IDLE; // Response will be sent after receiving
+                                      // all update responses
+              cmd_llsc_fifo_get         = true;
+            } else {
+              r_llsc_fsm = SC_UPDATE;
+            }
+          } else {
+            r_llsc_fsm = SC_UPDATE;
+          }
+          
+          break;
+        }
+        //////////////////
+      case SC_TRT_LOCK:
+        {
+          if( r_alloc_trt_fsm.read() == ALLOC_TRT_LLSC ) {
+            if( !r_llsc_to_ixr_cmd_req ) { // we can transfer the data to the buffer
+              size_t way	= r_llsc_way.read();
+              size_t set	= m_y[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
+              for(size_t i = 0; i<m_words; i++){
+                if(i==m_x[(vci_addr_t)m_cmd_llsc_addr_fifo.read()]) {
+                  r_llsc_to_ixr_cmd_data[i] = m_cmd_llsc_wdata_fifo.read();
+                } else {
+                  r_llsc_to_ixr_cmd_data[i] = m_cache_data[way][set][i];
+                }
+              }
+              size_t wok_index = 0;
+              bool wok = !m_transaction_tab.full(wok_index);
+              if ( wok ) { // set a new entry in TRT
+                r_llsc_trt_index = wok_index;
+                r_llsc_fsm       = SC_INVAL_LOCK; 
+              } else {
+                r_llsc_fsm       = SC_WAIT;
+              }
+            } else {
+              r_llsc_fsm = SC_WAIT;
+            }
+          }
+          break;
+        }
+        //////////////////
+      case SC_INVAL_LOCK:
+        {
+          if ( r_alloc_upt_fsm.read() == ALLOC_UPT_LLSC ) {
+            bool        wok       = false;
+            size_t      index     = 0;
+            size_t      srcid     = m_cmd_llsc_srcid_fifo.read();
+            size_t      trdid     = m_cmd_llsc_trdid_fifo.read();
+            size_t      pktid     = m_cmd_llsc_pktid_fifo.read();
+            addr_t	    nline     = m_nline[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
+            size_t      nb_copies = r_llsc_count.read();
+
+            wok =m_update_tab.set(false,	// it's an inval transaction
+                true,                       // it's a broadcast
+                true,                       // it needs a response
+                srcid,
+                trdid,
+                pktid,
+                nline,
+                nb_copies,
+                index);
+#ifdef IDEBUG
+            if(wok){
+                TRACE_MSG(m_log << m_total_cycles << " " << name() << " LLSC_INVAL_LOCK update table : " << std::endl);
+                DUMP_UPDATE_TABLE;
+            }
+#endif
+            r_llsc_upt_index = index;
+            //  releases the lock protecting Update Table if no entry...
+            if ( wok ) r_llsc_fsm = SC_DIR_INVAL;
+            else       r_llsc_fsm = SC_WAIT;
+          }
+          break;
+        }
+        //////////////////
+      case SC_DIR_INVAL:
+        {
+          if ( (r_alloc_trt_fsm.read() == ALLOC_TRT_LLSC ) &&
+              (r_alloc_upt_fsm.read() == ALLOC_UPT_LLSC )  &&
+              (r_alloc_dir_fsm.read() == ALLOC_DIR_LLSC ))
+          {
+            m_transaction_tab.set(r_llsc_trt_index.read(),
+                false,				// write request to XRAM
+                m_nline[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())],
+                0,
+                0,
+                0,
+                false,				// not a processor read
+                0,  				// not a single word 
+                0,		        	// word index
+                std::vector<be_t>(m_words,0),
+                std::vector<data_t>(m_words,0));
+#ifdef TDEBUG
+            TRACE_MSG(m_log << m_total_cycles << " " << name() << " SC_DIR_INVAL transaction table : " << std::endl);
+            DUMP_TRANSACTION_TABLE;
+#endif
+            // reset Atomic Table
+            m_atomic_tab.reset(m_cmd_llsc_addr_fifo.read());
+
+            // invalidate directory entry
+            DirectoryEntry entry;
+            entry.valid	   = false;
+            entry.dirty	   = false;
+            entry.tag	   = 0;
+            entry.is_cnt   = false;
+            entry.lock	   = false;
+//            entry.d_copies = 0;
+//            entry.i_copies = 0;
+            entry.count    = 0;
+            size_t set	   = m_y[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
+            size_t way	   = r_llsc_way.read();
+            m_cache_directory.write(set, way, entry);
+
+            r_llsc_fsm = SC_INVAL;
+          } else {
+            assert(false && "LOCK ERROR in LLSC_FSM, STATE = LLSC_DIR_INVAL");
+          }
+
+          break;
+
+        }
+        //////////////////
+      case SC_INVAL:
+        {
+          if ( !r_llsc_to_init_cmd_multi_req.read() &&
+               !r_llsc_to_init_cmd_brdcast_req.read()) {
+            r_llsc_to_init_cmd_multi_req    = false;
+            r_llsc_to_init_cmd_brdcast_req  = true;
+            r_llsc_to_init_cmd_trdid        = r_llsc_upt_index.read();
+            r_llsc_to_init_cmd_nline        = m_nline[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
+            r_llsc_to_init_cmd_index        = 0;
+            r_llsc_to_init_cmd_wdata        = 0;
+
+            r_llsc_fsm = SC_XRAM_SEND;
+            // all update responses
+          }
+
+          break;
+        }
+        //////////////////
+      case SC_XRAM_SEND:
+        {
+          if ( !r_llsc_to_ixr_cmd_req ) {
+            r_llsc_to_ixr_cmd_req     = true;
+            r_llsc_to_ixr_cmd_write   = true;
+            r_llsc_to_ixr_cmd_nline   = m_nline[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())];
+            r_llsc_to_ixr_cmd_trdid   = r_llsc_trt_index.read();
+            if(  r_llsc_is_cnt.read() ||
+                ((!r_llsc_is_cnt.read()) && (r_llsc_count.read()==1)) ){
+              r_llsc_fsm        = LLSC_IDLE;
+              cmd_llsc_fifo_get = true;
+            } else {
+              r_llsc_fsm        = SC_HEAP_ERASE;
+              r_llsc_next_ptr   = r_llsc_ptr.read();
+            }
+          } else {
+            assert( false && "MEM_CACHE, LLSC FSM : SC_XRAM_SEND state : the request should not have been previously set");
+          }
+          break;
+        }
+        //////////////////
+      case SC_HEAP_ERASE:
+        {
+          if(r_alloc_heap_fsm.read() == ALLOC_HEAP_LLSC){
+            HeapEntry next_entry = m_heap_directory.read(r_llsc_next_ptr.read());
+            if( next_entry.next == r_llsc_next_ptr.read()){
+                //r_write_fsm = SC_HEAP_LAST;
+                r_llsc_fsm = SC_HEAP_LAST; // As suggest by Alexendre J.
+            } else {
+              r_llsc_next_ptr = next_entry.next;
+              r_llsc_fsm = SC_HEAP_ERASE;
+            }
+          }
+          break;
+        }
+        //////////////////
+      case SC_HEAP_LAST:
+        {
+          assert((r_alloc_heap_fsm.read() == ALLOC_HEAP_LLSC) &&
+                  "MemCache ERROR : bad HEAP allocation");
+          size_t free_pointer = m_heap_directory.next_free_ptr();
+
+          HeapEntry last_entry;
+          last_entry.owner.srcid = 0;
+          last_entry.owner.inst  = false;
+          if(m_heap_directory.is_full()){
+            last_entry.next     = r_llsc_next_ptr.read();
+            m_heap_directory.unset_full();
+          } else {
+            last_entry.next     = free_pointer;
+          }
+
+          m_heap_directory.write_free_ptr(r_llsc_ptr.read());
+          m_heap_directory.write(r_llsc_next_ptr.read(),last_entry);
+
+          cmd_llsc_fifo_get		= true;
+          r_llsc_fsm = LLSC_IDLE;
+          break;
+        }
+        //////////////////
+      case SC_RSP_FALSE:
+        {
+          if( !r_llsc_to_tgt_rsp_req ) {
+            cmd_llsc_fifo_get		= true;
+            r_llsc_to_tgt_rsp_req	= true;
+            r_llsc_to_tgt_rsp_data	= 1;
+            r_llsc_to_tgt_rsp_srcid	= m_cmd_llsc_srcid_fifo.read();
+            r_llsc_to_tgt_rsp_trdid	= m_cmd_llsc_trdid_fifo.read();
+            r_llsc_to_tgt_rsp_pktid	= m_cmd_llsc_pktid_fifo.read();
+            r_llsc_fsm 			    = LLSC_IDLE;
+          }
+          break;
+        }
+        /////////////////
+      case SC_RSP_TRUE:
+        {
+          if( !r_llsc_to_tgt_rsp_req ) {
+            cmd_llsc_fifo_get	    = true;
+            r_llsc_to_tgt_rsp_req	= true;
+            r_llsc_to_tgt_rsp_data	= 0;
+            r_llsc_to_tgt_rsp_srcid	= m_cmd_llsc_srcid_fifo.read();
+            r_llsc_to_tgt_rsp_trdid	= m_cmd_llsc_trdid_fifo.read();
+            r_llsc_to_tgt_rsp_pktid	= m_cmd_llsc_pktid_fifo.read();
+            r_llsc_fsm 			    = LLSC_IDLE;
+          }
+          break;
+        }
+        ///////////////////
+      case LLSC_TRT_LOCK:         // read or write miss : check the Transaction Table
+        {
+          if( r_alloc_trt_fsm.read() == ALLOC_TRT_LLSC ) {
+            size_t   index = 0;
+            bool hit_read = m_transaction_tab.hit_read(m_nline[(vci_addr_t)m_cmd_llsc_addr_fifo.read()],index);
+            bool hit_write = m_transaction_tab.hit_write(m_nline[(vci_addr_t)m_cmd_llsc_addr_fifo.read()]);
+            bool wok = !m_transaction_tab.full(index);
+
+            if ( hit_read || !wok || hit_write ) {  // missing line already requested or no space in TRT
+              r_llsc_fsm = LLSC_IDLE;
+            } else {
+              r_llsc_trt_index = index;
+              r_llsc_fsm       = LLSC_TRT_SET;
+            }
+          }
+          break;
+        }
+        //////////////////
+      case LLSC_TRT_SET:	// register the XRAM transaction in Transaction Table
+        {
+          if( r_alloc_trt_fsm.read() == ALLOC_TRT_LLSC ) {
+            size_t word	= m_x[(vci_addr_t)(m_cmd_llsc_addr_fifo.read())]; 
+            bool proc_read = !m_cmd_llsc_sc_fifo.read();
+            if(proc_read){
+              m_transaction_tab.set(r_llsc_trt_index.read(),
+                  true,
+                  m_nline[(vci_addr_t)m_cmd_llsc_addr_fifo.read()],
+                  m_cmd_llsc_srcid_fifo.read(),
+                  m_cmd_llsc_trdid_fifo.read(),
+                  m_cmd_llsc_pktid_fifo.read(),
+                  true,
+                  1,
+                  word,
+                  std::vector<be_t>(m_words,0),
+                  std::vector<data_t>(m_words,0));
+            }else{
+              std::vector<be_t> be_vector;
+              std::vector<data_t> data_vector;
+              be_vector.clear();
+              data_vector.clear();
+              // reset Atomic Table
+              m_atomic_tab.reset(m_cmd_llsc_addr_fifo.read());
+              for ( size_t i=0; i<m_words; i++ ) 
+              {   
+                if(i == word){
+                  be_vector.push_back(0xF);
+                  data_vector.push_back(m_cmd_llsc_wdata_fifo.read());
+                } else {
+                  be_vector.push_back(0);
+                  data_vector.push_back(0);
+                }
+              }
+ 
+              m_transaction_tab.set(r_llsc_trt_index.read(),
+                  true,
+                  m_nline[(vci_addr_t)m_cmd_llsc_addr_fifo.read()],
+                  m_cmd_llsc_srcid_fifo.read(),
+                  m_cmd_llsc_trdid_fifo.read(),
+                  m_cmd_llsc_pktid_fifo.read(),
+                  false,
+                  0,
+                  0,
+                  be_vector,
+                  data_vector);
+            }
+#ifdef TDEBUG
+            TRACE_MSG(m_log << m_total_cycles << " " << name() << " LLSC_TRT_SET transaction table : " << std::endl);
+            DUMP_TRANSACTION_TABLE;
+#endif
+
+            r_llsc_fsm = LLSC_XRAM_REQ;
+          }
+          break;
+        }
+        ///////////////////
+      case LLSC_XRAM_REQ:	// request the IXR_CMD FSM to fetch the missing line
+        {
+          if ( !r_llsc_to_ixr_cmd_req ) {
+            r_llsc_to_ixr_cmd_req        = true;
+            r_llsc_to_ixr_cmd_write      = false;
+            r_llsc_to_ixr_cmd_trdid      = r_llsc_trt_index.read();
+            r_llsc_to_ixr_cmd_nline      = m_nline[(vci_addr_t)m_cmd_llsc_addr_fifo.read()];
+            if( m_cmd_llsc_sc_fifo.read() ) {
+              r_llsc_fsm                 = SC_RSP_TRUE;
+            } else {
+              cmd_llsc_fifo_get          = true;
+              r_llsc_fsm                 = LLSC_IDLE;
+            }
+          }
+          break;
+        }
+    } // end switch r_llsc_fsm
+
+
+    //////////////////////////////////////////////////////////////////////////////
+    //		INIT_CMD FSM
+    //////////////////////////////////////////////////////////////////////////////
+    // The INIT_CMD fsm controls the VCI CMD initiator port, used to update
+    // or invalidate cache lines in L1 caches.
+    // It implements a round-robin priority between the two following requests:
+    // - r_write_to_init_cmd_req : update request from WRITE FSM 
+    // - r_xram_rsp_to_init_cmd_req : invalidate request from XRAM_RSP FSM 
+    // The inval request is a single cell VCI write command containing the 
+    // index of the line to be invalidated.
+    // The update request is a multi-cells VCI write command : The first cell 
+    // contains the index of the cache line to be updated. The second cell contains 
+    // the index of the first modified word in the line. The following cells
+    // contain the data.
+    ///////////////////////////////////////////////////////////////////////////////
+
+    switch ( r_init_cmd_fsm.read() ) {
+
+      //////////////////////// 
+      case INIT_CMD_UPDT_IDLE:	// Invalidate requests have highest priority
+        {
+
+          if ( m_xram_rsp_to_init_cmd_inst_fifo.rok() ||
+               r_xram_rsp_to_init_cmd_multi_req.read()  ) {
+            r_init_cmd_fsm = INIT_CMD_INVAL_NLINE;
+            m_cpt_inval++;
+          } else if ( r_xram_rsp_to_init_cmd_brdcast_req.read() ) {
+            r_init_cmd_fsm = INIT_CMD_XRAM_BRDCAST;
+            m_cpt_inval++;
+          } else if ( m_write_to_init_cmd_inst_fifo.rok() ||
+                      r_write_to_init_cmd_multi_req.read() ) {
+            r_init_cmd_fsm = INIT_CMD_UPDT_NLINE;
+            m_cpt_update++;
+          } else if ( r_write_to_init_cmd_brdcast_req.read() ){
+            r_init_cmd_fsm = INIT_CMD_WRITE_BRDCAST;
+            m_cpt_inval++;
+          } else if ( m_llsc_to_init_cmd_inst_fifo.rok() ||
+                      r_llsc_to_init_cmd_multi_req.read()  ) {
+            r_init_cmd_fsm = INIT_CMD_SC_UPDT_NLINE;
+            m_cpt_update++;
+          } else if( r_llsc_to_init_cmd_brdcast_req.read() ){
+            r_init_cmd_fsm = INIT_CMD_SC_BRDCAST;
+            m_cpt_inval++;
+          }
+          break;
+        }
+        /////////////////////////
+      case INIT_CMD_INVAL_IDLE:	// Update requests have highest priority
+        {
+          if ( m_write_to_init_cmd_inst_fifo.rok() ||
+               r_write_to_init_cmd_multi_req.read() ) {
+            r_init_cmd_fsm = INIT_CMD_UPDT_NLINE;
+            m_cpt_update++;
+          } else if ( r_write_to_init_cmd_brdcast_req.read() ){
+            r_init_cmd_fsm = INIT_CMD_WRITE_BRDCAST;
+            m_cpt_inval++;
+          } else if ( m_llsc_to_init_cmd_inst_fifo.rok() ||
+                      r_llsc_to_init_cmd_multi_req.read()  ) {
+            r_init_cmd_fsm = INIT_CMD_SC_UPDT_NLINE;
+            m_cpt_update++;
+          } else if( r_llsc_to_init_cmd_brdcast_req.read() ){
+            r_init_cmd_fsm = INIT_CMD_SC_BRDCAST;
+            m_cpt_inval++;
+          } else if ( m_xram_rsp_to_init_cmd_inst_fifo.rok() ||
+                      r_xram_rsp_to_init_cmd_multi_req.read()  ) {
+            r_init_cmd_fsm = INIT_CMD_INVAL_NLINE;
+            m_cpt_inval++;
+          } else if ( r_xram_rsp_to_init_cmd_brdcast_req.read() ) {
+            r_init_cmd_fsm = INIT_CMD_XRAM_BRDCAST;
+            m_cpt_inval++;
+          }
+          break;
+        }
+        /////////////////////////
+      case INIT_CMD_SC_UPDT_IDLE:	// Update requests for SCs have highest priority
+        {
+          if ( m_llsc_to_init_cmd_inst_fifo.rok() ||
+               r_llsc_to_init_cmd_multi_req.read()  ) {
+            r_init_cmd_fsm = INIT_CMD_SC_UPDT_NLINE;
+            m_cpt_update++;
+          } else if( r_llsc_to_init_cmd_brdcast_req.read() ){
+            r_init_cmd_fsm = INIT_CMD_SC_BRDCAST;
+            m_cpt_inval++;
+          } else if ( m_xram_rsp_to_init_cmd_inst_fifo.rok() ||
+                      r_xram_rsp_to_init_cmd_multi_req.read()  ) {
+            r_init_cmd_fsm = INIT_CMD_INVAL_NLINE;
+            m_cpt_inval++;
+          } else if ( r_xram_rsp_to_init_cmd_brdcast_req.read() ) {
+            r_init_cmd_fsm = INIT_CMD_XRAM_BRDCAST;
+            m_cpt_inval++;
+          } else if ( m_write_to_init_cmd_inst_fifo.rok() ||
+                      r_write_to_init_cmd_multi_req.read() ) {
+            r_init_cmd_fsm = INIT_CMD_UPDT_NLINE;
+            m_cpt_update++;
+          } else if ( r_write_to_init_cmd_brdcast_req.read() ){
+            r_init_cmd_fsm = INIT_CMD_WRITE_BRDCAST;
+            m_cpt_inval++;
+          }
+          break;
+        }
+        ////////////////////////
+      case INIT_CMD_INVAL_NLINE:	// send the cache line index
+        {
+          if ( m_xram_rsp_to_init_cmd_inst_fifo.rok() ){
+            if ( p_vci_ini.cmdack ) {
+              m_cpt_inval_mult++;
+              r_init_cmd_fsm = INIT_CMD_INVAL_NLINE;
+              xram_rsp_to_init_cmd_fifo_get = true;
+            }
+          } else {
+            if( r_xram_rsp_to_init_cmd_multi_req.read() ){
+              r_xram_rsp_to_init_cmd_multi_req = false;
+            } 
+            r_init_cmd_fsm = INIT_CMD_INVAL_IDLE;
+          }
+          break;
+        }
+        ////////////////////////
+      case INIT_CMD_XRAM_BRDCAST:	// send the cache line index
+        {
+          if ( p_vci_ini.cmdack ) {
+            m_cpt_inval_brdcast++;
+            r_init_cmd_fsm = INIT_CMD_INVAL_IDLE;
+            r_xram_rsp_to_init_cmd_brdcast_req = false;
+          }
+          break;
+        }
+        /////////////////////////
+      case INIT_CMD_WRITE_BRDCAST:
+        {
+          if( p_vci_ini.cmdack ) {
+            m_cpt_inval_brdcast++;
+            r_write_to_init_cmd_brdcast_req = false;
+            r_init_cmd_fsm = INIT_CMD_UPDT_IDLE;
+          }
+          break;
+        }
+        /////////////////////////
+      case INIT_CMD_UPDT_NLINE:	// send the cache line index
+        {
+          if ( m_write_to_init_cmd_inst_fifo.rok() ) {
+            if ( p_vci_ini.cmdack ){
+              m_cpt_update_mult++;
+              r_init_cmd_fsm = INIT_CMD_UPDT_INDEX;
+            }
+          } else {
+            if ( r_write_to_init_cmd_multi_req.read() ){
+              r_write_to_init_cmd_multi_req = false;
+            }
+            r_init_cmd_fsm = INIT_CMD_UPDT_IDLE;
+          }
+          break;
+        }
+        /////////////////////////
+      case INIT_CMD_UPDT_INDEX:	// send the first word index
+        {
+          r_init_cmd_cpt    = 0;
+          if ( p_vci_ini.cmdack )  r_init_cmd_fsm = INIT_CMD_UPDT_DATA;
+          break;
+        }
+        ////////////////////////
+      case INIT_CMD_UPDT_DATA:	// send the data
+        {
+          if ( p_vci_ini.cmdack ) {
+            if ( r_init_cmd_cpt.read() == (r_write_to_init_cmd_count.read()-1) ) {
+              r_init_cmd_fsm = INIT_CMD_UPDT_NLINE;
+              write_to_init_cmd_fifo_get = true;
+            } else {
+              r_init_cmd_cpt = r_init_cmd_cpt.read() + 1;
+            }
+          }
+          break;
+        }
+        /////////////////////////
+      case INIT_CMD_SC_BRDCAST:
+        {
+          if( p_vci_ini.cmdack ) {
+            m_cpt_inval_brdcast++;
+            r_llsc_to_init_cmd_brdcast_req = false;
+            r_init_cmd_fsm = INIT_CMD_SC_UPDT_IDLE;
+          }
+          break;
+        }
+        /////////////////////////
+      case INIT_CMD_SC_UPDT_NLINE:	// send the cache line index
+        {
+          if ( m_llsc_to_init_cmd_inst_fifo.rok() ){
+            if ( p_vci_ini.cmdack ){
+              m_cpt_update_mult++;
+              r_init_cmd_fsm = INIT_CMD_SC_UPDT_INDEX;
+            }
+          } else {
+            if( r_llsc_to_init_cmd_multi_req.read() ){
+              r_llsc_to_init_cmd_multi_req = false;
+            }
+            r_init_cmd_fsm = INIT_CMD_SC_UPDT_IDLE;
+          }
+          break;
+        }
+        /////////////////////////
+      case INIT_CMD_SC_UPDT_INDEX:	// send the first word index
+        {
+          if ( p_vci_ini.cmdack )  r_init_cmd_fsm = INIT_CMD_SC_UPDT_DATA;
+          break;
+        }
+        ////////////////////////
+      case INIT_CMD_SC_UPDT_DATA:	// send the data
+        {
+          if ( p_vci_ini.cmdack ) {
+            llsc_to_init_cmd_fifo_get = true;
+            r_init_cmd_fsm = INIT_CMD_SC_UPDT_NLINE;
+          }
+          break;
+        }
+
+    } // end switch r_init_cmd_fsm
+
+    /////////////////////////////////////////////////////////////////////
+    //		TGT_RSP FSM
+    /////////////////////////////////////////////////////////////////////
+    // The TGT_RSP fsm sends the responses on the VCI target port
+    // with a round robin priority between six requests :
+    // - r_read_to_tgt_rsp_req
+    // - r_write_to_tgt_rsp_req
+    // - r_llsc_to_tgt_rsp_req
+    // - r_cleanup_to_tgt_rsp_req
+    // - r_init_rsp_to_tgt_rsp_req
+    // - r_xram_rsp_to_tgt_rsp_req
+    // The  ordering is :  read > write > llsc > cleanup > xram > init
+    /////////////////////////////////////////////////////////////////////
+
+    switch ( r_tgt_rsp_fsm.read() ) {
+
+      ///////////////////////
+      case TGT_RSP_READ_IDLE:		// write requests have the highest priority
+        {
+          if      ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
+          else if ( r_llsc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_LLSC;
+          else if ( r_xram_rsp_to_tgt_rsp_req ) {
+            r_tgt_rsp_fsm = TGT_RSP_XRAM;
+            r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();
+          }
+          else if ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
+          else if ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
+          else if ( r_read_to_tgt_rsp_req     ) {
+            r_tgt_rsp_fsm = TGT_RSP_READ;
+            r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();
+          }
+          break;
+        }
+        ////////////////////////
+      case TGT_RSP_WRITE_IDLE:		// llsc requests have the highest priority
+        {
+          if      ( r_llsc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_LLSC;
+          else if ( r_xram_rsp_to_tgt_rsp_req ) {
+            r_tgt_rsp_fsm = TGT_RSP_XRAM;
+            r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();
+          }
+          else if ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
+          else if ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
+          else if ( r_read_to_tgt_rsp_req     ) {
+            r_tgt_rsp_fsm = TGT_RSP_READ;
+            r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();
+          }
+
+          else if ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
+          break;
+        }
+        ///////////////////////
+      case TGT_RSP_LLSC_IDLE:		// cleanup requests have the highest priority
+        {
+          if ( r_xram_rsp_to_tgt_rsp_req )  {
+            r_tgt_rsp_fsm = TGT_RSP_XRAM;
+            r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();
+          }
+          else if ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
+          else if ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
+          else if ( r_read_to_tgt_rsp_req     ) {
+            r_tgt_rsp_fsm = TGT_RSP_READ;
+            r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();
+          }
+          else if ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
+          else if ( r_llsc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_LLSC;
+          break;
+        }
+      case TGT_RSP_XRAM_IDLE:		// init requests have the highest priority
+        {
+
+          if      ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
+          else if ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
+          else if ( r_read_to_tgt_rsp_req     ) {
+            r_tgt_rsp_fsm = TGT_RSP_READ;
+            r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();
+          }
+          else if ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
+          else if ( r_llsc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_LLSC;
+          else if ( r_xram_rsp_to_tgt_rsp_req )  {
+            r_tgt_rsp_fsm = TGT_RSP_XRAM;
+            r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();
+          }
+          break;
+        }
+        ///////////////////////
+      case TGT_RSP_INIT_IDLE:		// cleanup requests have the highest priority
+        {
+          if      ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
+          else if ( r_read_to_tgt_rsp_req     ) {
+            r_tgt_rsp_fsm = TGT_RSP_READ;
+            r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();
+          }
+          else if ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
+          else if ( r_llsc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_LLSC;
+          else if ( r_xram_rsp_to_tgt_rsp_req ) {
+            r_tgt_rsp_fsm = TGT_RSP_XRAM;
+            r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();
+          }
+          else if ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
+          break;
+        }
+        ///////////////////////
+      case TGT_RSP_CLEANUP_IDLE:		// read requests have the highest priority
+        {
+          if      ( r_read_to_tgt_rsp_req     ) {
+            r_tgt_rsp_fsm = TGT_RSP_READ;
+            r_tgt_rsp_cpt = r_read_to_tgt_rsp_word.read();
+          }
+          else if ( r_write_to_tgt_rsp_req    ) r_tgt_rsp_fsm = TGT_RSP_WRITE;
+          else if ( r_llsc_to_tgt_rsp_req     ) r_tgt_rsp_fsm = TGT_RSP_LLSC;
+          else if ( r_xram_rsp_to_tgt_rsp_req ) {
+            r_tgt_rsp_fsm = TGT_RSP_XRAM;
+            r_tgt_rsp_cpt = r_xram_rsp_to_tgt_rsp_word.read();
+          }
+          else if ( r_init_rsp_to_tgt_rsp_req ) r_tgt_rsp_fsm = TGT_RSP_INIT;
+          else if ( r_cleanup_to_tgt_rsp_req  ) r_tgt_rsp_fsm = TGT_RSP_CLEANUP;
+          break;
+        }
+        ///////////////////////
+      case TGT_RSP_READ:		// send the response
+        {
+          if ( p_vci_tgt.rspack ) {
+            if ( r_tgt_rsp_cpt.read() == (r_read_to_tgt_rsp_word.read()+r_read_to_tgt_rsp_length-1) ) {
+              r_tgt_rsp_fsm = TGT_RSP_READ_IDLE;
+              r_read_to_tgt_rsp_req = false;
+            } else {
+              r_tgt_rsp_cpt = r_tgt_rsp_cpt.read() + 1;
+            }
+          }
+          break;
+        }
+        ///////////////////
+      case TGT_RSP_WRITE:		// send the write acknowledge
+        {
+          if ( p_vci_tgt.rspack ) {
+            r_tgt_rsp_fsm = TGT_RSP_WRITE_IDLE;
+            r_write_to_tgt_rsp_req = false;
+          }
+          break;
+        }
+        ///////////////////
+      case TGT_RSP_CLEANUP:		// send the write acknowledge
+        {
+          if ( p_vci_tgt.rspack ) {
+            r_tgt_rsp_fsm = TGT_RSP_CLEANUP_IDLE;
+            r_cleanup_to_tgt_rsp_req = false;
+          }
+          break;
+        }
+        //////////////////
+      case TGT_RSP_LLSC:		// send one atomic word response
+        {
+          if ( p_vci_tgt.rspack ) {
+            r_tgt_rsp_fsm = TGT_RSP_LLSC_IDLE;
+            r_llsc_to_tgt_rsp_req = false;
+          }
+          break;
+        }
+
+        ///////////////////////
+      case TGT_RSP_XRAM:		// send the response
+        {
+          if ( p_vci_tgt.rspack ) {
+            if ( r_tgt_rsp_cpt.read() == (r_xram_rsp_to_tgt_rsp_word.read()+r_xram_rsp_to_tgt_rsp_length.read()-1)) {
+              r_tgt_rsp_fsm = TGT_RSP_XRAM_IDLE;
+              r_xram_rsp_to_tgt_rsp_req = false;
+            } else {
+              r_tgt_rsp_cpt = r_tgt_rsp_cpt.read() + 1;
+            }
+          }
+          break;
+        }
+        ///////////////////
+      case TGT_RSP_INIT:		// send the pending write acknowledge
+        {
+          if ( p_vci_tgt.rspack ) {
+            r_tgt_rsp_fsm = TGT_RSP_INIT_IDLE;
+            r_init_rsp_to_tgt_rsp_req = false;
+          }
+          break;
+        }
+    } // end switch tgt_rsp_fsm
+    ////////////////////////////////////////////////////////////////////////////////////
+    //		NEW ALLOC_UPT FSM
+    ////////////////////////////////////////////////////////////////////////////////////
+    // The ALLOC_UPT FSM allocates the access to the Update/Inval Table (UPT).
+    // with a round robin priority between three FSMs : INIT_RSP > WRITE > XRAM_RSP > CLEANUP 
+    // - The WRITE FSM initiates update transactions and sets  new entry in UPT.
+    // - The XRAM_RSP FSM initiates inval transactions and sets  new entry in UPT.
+    // - The INIT_RSP FSM complete those trasactions and erase the UPT entry.
+    // - The CLEANUP  FSM decrement an entry in UPT.
+    // The resource is always allocated.
+    /////////////////////////////////////////////////////////////////////////////////////
+
+    switch ( r_alloc_upt_fsm.read() ) {
+
+      ////////////////////////
+      case ALLOC_UPT_INIT_RSP:
+        if ( (r_init_rsp_fsm.read() != INIT_RSP_UPT_LOCK) && 
+             (r_init_rsp_fsm.read() != INIT_RSP_UPT_CLEAR) ) 
+        {
+          if      ((r_write_fsm.read() == WRITE_UPT_LOCK) ||
+                   (r_write_fsm.read() == WRITE_INVAL_LOCK))        r_alloc_upt_fsm = ALLOC_UPT_WRITE;
+          else if (r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)    r_alloc_upt_fsm = ALLOC_UPT_XRAM_RSP;
+          else if (r_cleanup_fsm.read() == CLEANUP_UPT_LOCK)        r_alloc_upt_fsm = ALLOC_UPT_CLEANUP;
+          else if ((r_llsc_fsm.read() == SC_UPT_LOCK) ||
+                   (r_llsc_fsm.read() == SC_INVAL_LOCK))            r_alloc_upt_fsm = ALLOC_UPT_LLSC;
+        }
+        break;
+
+        /////////////////////
+      case ALLOC_UPT_WRITE:
+        if ( (r_write_fsm.read() != WRITE_UPT_LOCK) &&
+             (r_write_fsm.read() != WRITE_INVAL_LOCK)) 
+        {
+          if      (r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)    r_alloc_upt_fsm = ALLOC_UPT_XRAM_RSP;
+          else if (r_cleanup_fsm.read() == CLEANUP_UPT_LOCK)        r_alloc_upt_fsm = ALLOC_UPT_CLEANUP;
+          else if ((r_llsc_fsm.read() == SC_UPT_LOCK) ||
+                   (r_llsc_fsm.read() == SC_INVAL_LOCK))            r_alloc_upt_fsm = ALLOC_UPT_LLSC;
+          else if (r_init_rsp_fsm.read() == INIT_RSP_UPT_LOCK)      r_alloc_upt_fsm = ALLOC_UPT_INIT_RSP;
+        }
+        break;
+
+        ////////////////////////
+      case ALLOC_UPT_XRAM_RSP:
+        if (r_xram_rsp_fsm.read() != XRAM_RSP_INVAL_LOCK) 
+        { 
+          if       (r_cleanup_fsm.read() == CLEANUP_UPT_LOCK)       r_alloc_upt_fsm = ALLOC_UPT_CLEANUP;
+          else if ((r_llsc_fsm.read() == SC_UPT_LOCK) ||
+                   (r_llsc_fsm.read() == SC_INVAL_LOCK))            r_alloc_upt_fsm = ALLOC_UPT_LLSC;
+          else if  (r_init_rsp_fsm.read() == INIT_RSP_UPT_LOCK)     r_alloc_upt_fsm = ALLOC_UPT_INIT_RSP;
+          else if ((r_write_fsm.read() == WRITE_UPT_LOCK)   ||
+                   (r_write_fsm.read() == WRITE_INVAL_LOCK))        r_alloc_upt_fsm = ALLOC_UPT_WRITE;
+        }
+        break;
+
+        //////////////////////////
+      case ALLOC_UPT_CLEANUP:
+        if(r_cleanup_fsm.read() != CLEANUP_UPT_LOCK )
+        {
+          if      ((r_llsc_fsm.read() == SC_UPT_LOCK) ||
+                   (r_llsc_fsm.read() == SC_INVAL_LOCK))            r_alloc_upt_fsm = ALLOC_UPT_LLSC;
+          else if  (r_init_rsp_fsm.read() == INIT_RSP_UPT_LOCK)     r_alloc_upt_fsm = ALLOC_UPT_INIT_RSP;
+          else if ((r_write_fsm.read() == WRITE_UPT_LOCK) ||
+                   (r_write_fsm.read() == WRITE_INVAL_LOCK))        r_alloc_upt_fsm = ALLOC_UPT_WRITE;
+          else if (r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)    r_alloc_upt_fsm = ALLOC_UPT_XRAM_RSP;
+        }
+        break;
+        
+        //////////////////////////
+      case ALLOC_UPT_LLSC:
+        if( (r_llsc_fsm.read() != SC_UPT_LOCK) && 
+            (r_llsc_fsm.read() != SC_INVAL_LOCK))
+        {
+          if      (r_init_rsp_fsm.read() == INIT_RSP_UPT_LOCK)      r_alloc_upt_fsm = ALLOC_UPT_INIT_RSP;
+          else if ((r_write_fsm.read() == WRITE_UPT_LOCK) ||
+                   (r_write_fsm.read() == WRITE_INVAL_LOCK))        r_alloc_upt_fsm = ALLOC_UPT_WRITE;
+          else if (r_xram_rsp_fsm.read() == XRAM_RSP_INVAL_LOCK)    r_alloc_upt_fsm = ALLOC_UPT_XRAM_RSP;
+          else if (r_cleanup_fsm.read() == CLEANUP_UPT_LOCK)        r_alloc_upt_fsm = ALLOC_UPT_CLEANUP;
+        }
+        break;
+
+    } // end switch r_alloc_upt_fsm
+
+    ////////////////////////////////////////////////////////////////////////////////////
+    //		ALLOC_DIR FSM
+    ////////////////////////////////////////////////////////////////////////////////////
+    // The ALLOC_DIR FSM allocates the access to the directory and
+    // the data cache with a round robin priority between 5 user FSMs :
+    // The cyclic ordering is READ > WRITE > LLSC > CLEANUP > XRAM_RSP
+    // The ressource is always allocated.
+    /////////////////////////////////////////////////////////////////////////////////////
+
+    switch ( r_alloc_dir_fsm.read() ) {
+
+      ////////////////////
+      case ALLOC_DIR_READ:
+        if ( ( (r_read_fsm.read() != READ_DIR_LOCK) &&
+              (r_read_fsm.read() != READ_TRT_LOCK)  &&
+              (r_read_fsm.read() != READ_HEAP_LOCK))
+            ||
+            ( (r_read_fsm.read()        == READ_HEAP_LOCK) &&
+              (r_alloc_heap_fsm.read()  == ALLOC_HEAP_READ) )
+            ||
+            ( (r_read_fsm.read()      == READ_TRT_LOCK)  &&
+              (r_alloc_trt_fsm.read() == ALLOC_TRT_READ)    )  ) 
+        {
+          if        (r_write_fsm.read() == WRITE_DIR_LOCK)          r_alloc_dir_fsm = ALLOC_DIR_WRITE;
+          else if   ((r_llsc_fsm.read() == LL_DIR_LOCK) || 
+                    (r_llsc_fsm.read() == SC_DIR_LOCK))             r_alloc_dir_fsm = ALLOC_DIR_LLSC;
+          else if   (r_cleanup_fsm.read() == CLEANUP_DIR_LOCK)      r_alloc_dir_fsm = ALLOC_DIR_CLEANUP;
+          else if   (r_xram_rsp_fsm.read() == XRAM_RSP_DIR_LOCK)    r_alloc_dir_fsm = ALLOC_DIR_XRAM_RSP;
+        }
+        break;
+
+        /////////////////////
+      case ALLOC_DIR_WRITE:
+        if ( ( (r_write_fsm.read() != WRITE_DIR_LOCK)     &&
+              (r_write_fsm.read() != WRITE_TRT_LOCK)     &&
+              (r_write_fsm.read() != WRITE_DIR_HIT_READ) &&
+              (r_write_fsm.read() != WRITE_DIR_HIT) &&
+              (r_write_fsm.read() != WRITE_TRT_WRITE_LOCK) &&
+              (r_write_fsm.read() != WRITE_INVAL_LOCK) &&
+              (r_write_fsm.read() != WRITE_UPT_LOCK) &&
+              (r_write_fsm.read() != WRITE_HEAP_LOCK))
+            ||
+            ( (r_write_fsm.read()       == WRITE_HEAP_LOCK) &&
+              (r_alloc_heap_fsm.read()  == ALLOC_HEAP_WRITE) )
+            ||
+            ( (r_write_fsm.read()     == WRITE_TRT_LOCK) &&
+              (r_alloc_trt_fsm.read() == ALLOC_TRT_WRITE)   )   )
+        {
+          if        ((r_llsc_fsm.read() == LL_DIR_LOCK) || 
+                    (r_llsc_fsm.read() == SC_DIR_LOCK))             r_alloc_dir_fsm = ALLOC_DIR_LLSC;
+          else if   (r_cleanup_fsm.read() == CLEANUP_DIR_LOCK)      r_alloc_dir_fsm = ALLOC_DIR_CLEANUP;
+          else if   (r_xram_rsp_fsm.read() == XRAM_RSP_DIR_LOCK)    r_alloc_dir_fsm = ALLOC_DIR_XRAM_RSP;
+          else if   (r_read_fsm.read() == READ_DIR_LOCK) 	        r_alloc_dir_fsm = ALLOC_DIR_READ;
+        }
+        break;
+
+        ////////////////////
+      case ALLOC_DIR_LLSC:
+        if ( ( (r_llsc_fsm.read() != LL_DIR_LOCK)    &&
+              (r_llsc_fsm.read() != LL_DIR_HIT )    &&
+              (r_llsc_fsm.read() != SC_DIR_LOCK)    &&
+              (r_llsc_fsm.read() != SC_DIR_HIT )    &&
+              (r_llsc_fsm.read() != LLSC_TRT_LOCK ) &&
+              (r_llsc_fsm.read() != SC_TRT_LOCK)    &&
+              (r_llsc_fsm.read() != SC_INVAL_LOCK)  &&
+              (r_llsc_fsm.read() != SC_UPT_LOCK)    &&
+              (r_llsc_fsm.read() != SC_HEAP_LOCK))
+            ||
+            ( (r_llsc_fsm.read()       == SC_HEAP_LOCK) &&
+              (r_alloc_heap_fsm.read() == ALLOC_HEAP_LLSC) )
+            ||
+            ( (r_llsc_fsm.read()      == LLSC_TRT_LOCK ) &&
+              (r_alloc_trt_fsm.read() == ALLOC_TRT_LLSC)    ) )
+        {
+          if      (r_cleanup_fsm.read() == CLEANUP_DIR_LOCK)    r_alloc_dir_fsm = ALLOC_DIR_CLEANUP;
+          else if (r_xram_rsp_fsm.read() == XRAM_RSP_DIR_LOCK)  r_alloc_dir_fsm = ALLOC_DIR_XRAM_RSP;
+          else if (r_read_fsm.read() == READ_DIR_LOCK) 	        r_alloc_dir_fsm = ALLOC_DIR_READ;
+          else if (r_write_fsm.read() == WRITE_DIR_LOCK)        r_alloc_dir_fsm = ALLOC_DIR_WRITE;
+        }
+        break;
+
+        ///////////////////////
+      case ALLOC_DIR_CLEANUP:
+        if ( (r_cleanup_fsm.read() != CLEANUP_DIR_LOCK) &&
+            (r_cleanup_fsm.read() != CLEANUP_HEAP_LOCK) )
+        {
+          if        (r_xram_rsp_fsm.read() == XRAM_RSP_DIR_LOCK)    r_alloc_dir_fsm = ALLOC_DIR_XRAM_RSP;
+          else if   (r_read_fsm.read() == READ_DIR_LOCK)            r_alloc_dir_fsm = ALLOC_DIR_READ;
+          else if   (r_write_fsm.read() == WRITE_DIR_LOCK)          r_alloc_dir_fsm = ALLOC_DIR_WRITE;
+          else if   ((r_llsc_fsm.read() == LL_DIR_LOCK) || 
+                    (r_llsc_fsm.read() == SC_DIR_LOCK))             r_alloc_dir_fsm = ALLOC_DIR_LLSC;
+        }
+        break;
+        ////////////////////////
+      case ALLOC_DIR_XRAM_RSP:
+        if ( (r_xram_rsp_fsm.read() != XRAM_RSP_DIR_LOCK)  &&
+            (r_xram_rsp_fsm.read() != XRAM_RSP_TRT_COPY)   && 
+            (r_xram_rsp_fsm.read() != XRAM_RSP_INVAL_LOCK))
+        {
+          if      (r_read_fsm.read() == READ_DIR_LOCK) 	        r_alloc_dir_fsm = ALLOC_DIR_READ;
+          else if (r_write_fsm.read() == WRITE_DIR_LOCK)        r_alloc_dir_fsm = ALLOC_DIR_WRITE;
+          else if ( (r_llsc_fsm.read() == LL_DIR_LOCK) || 
+                    (r_llsc_fsm.read() == SC_DIR_LOCK))         r_alloc_dir_fsm = ALLOC_DIR_LLSC;
+          else if (r_cleanup_fsm.read() == CLEANUP_DIR_LOCK)    r_alloc_dir_fsm = ALLOC_DIR_CLEANUP;
+        }
+        break;
+
+    } // end switch alloc_dir_fsm
+
+    ////////////////////////////////////////////////////////////////////////////////////
+    //		ALLOC_TRT FSM
+    ////////////////////////////////////////////////////////////////////////////////////
+    // The ALLOC_TRT fsm allocates the access to the Transaction Table (write buffer)
+    // with a round robin priority between 4 user FSMs :
+    // The cyclic priority is READ > WRITE > LLSC > XRAM_RSP
+    // The ressource is always allocated.
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    switch (r_alloc_trt_fsm) {
+
+      ////////////////////
+      case ALLOC_TRT_READ:
+        if ( r_read_fsm.read() != READ_TRT_LOCK ) 
+        {
+          if      ((r_write_fsm.read() == WRITE_TRT_LOCK)   ||
+                   (r_write_fsm.read() == WRITE_TRT_WRITE_LOCK))    r_alloc_trt_fsm = ALLOC_TRT_WRITE;
+          else if ((r_llsc_fsm.read() == LLSC_TRT_LOCK) ||
+                   (r_llsc_fsm.read() == SC_TRT_LOCK))              r_alloc_trt_fsm = ALLOC_TRT_LLSC;
+          else if (r_xram_rsp_fsm.read() == XRAM_RSP_TRT_COPY)      r_alloc_trt_fsm = ALLOC_TRT_XRAM_RSP;
+          else if ( (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_ERASE) ||
+                    (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ) )    r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP;
+        }
+        break;
+        /////////////////////
+      case ALLOC_TRT_WRITE:
+        if ( (r_write_fsm.read() != WRITE_TRT_LOCK) &&
+             (r_write_fsm.read() != WRITE_TRT_WRITE_LOCK) &&
+             (r_write_fsm.read() != WRITE_INVAL_LOCK)) 
+        {
+          if      ((r_llsc_fsm.read() == LLSC_TRT_LOCK) ||
+                   (r_llsc_fsm.read() == SC_TRT_LOCK))              r_alloc_trt_fsm = ALLOC_TRT_LLSC;
+          else if (r_xram_rsp_fsm.read() == XRAM_RSP_TRT_COPY)      r_alloc_trt_fsm = ALLOC_TRT_XRAM_RSP;
+          else if ( (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_ERASE) ||
+                    (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ))     r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP;
+          else if (r_read_fsm.read() == READ_TRT_LOCK) 	            r_alloc_trt_fsm = ALLOC_TRT_READ;
+        }
+        break;
+        ////////////////////
+      case ALLOC_TRT_LLSC:
+        if ( (r_llsc_fsm.read() != LLSC_TRT_LOCK) &&
+             (r_llsc_fsm.read() != SC_TRT_LOCK) &&
+             (r_llsc_fsm.read() != SC_INVAL_LOCK))
+        { 
+          if      (r_xram_rsp_fsm.read() == XRAM_RSP_TRT_COPY)      r_alloc_trt_fsm = ALLOC_TRT_XRAM_RSP;
+          else if ( (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_ERASE) ||
+                    (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ))     r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP;
+          else if (r_read_fsm.read() == READ_TRT_LOCK) 	            r_alloc_trt_fsm = ALLOC_TRT_READ;
+          else if ((r_write_fsm.read() == WRITE_TRT_LOCK)     ||
+                   (r_write_fsm.read() == WRITE_TRT_WRITE_LOCK))    r_alloc_trt_fsm = ALLOC_TRT_WRITE;
+        }
+        break;
+        ////////////////////////
+      case ALLOC_TRT_XRAM_RSP:
+        if ( (r_xram_rsp_fsm.read() != XRAM_RSP_TRT_COPY)  &&
+            (r_xram_rsp_fsm.read() != XRAM_RSP_DIR_UPDT)   &&
+            (r_xram_rsp_fsm.read() != XRAM_RSP_INVAL_LOCK)) {
+          if      ( (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_ERASE) ||
+                    (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ))     r_alloc_trt_fsm = ALLOC_TRT_IXR_RSP;
+          else if (r_read_fsm.read() == READ_TRT_LOCK) 	            r_alloc_trt_fsm = ALLOC_TRT_READ;
+          else if ((r_write_fsm.read() == WRITE_TRT_LOCK)    ||
+                   (r_write_fsm.read() == WRITE_TRT_WRITE_LOCK))    r_alloc_trt_fsm = ALLOC_TRT_WRITE;
+          else if ((r_llsc_fsm.read() == LLSC_TRT_LOCK) ||
+                   (r_llsc_fsm.read() == SC_TRT_LOCK))              r_alloc_trt_fsm = ALLOC_TRT_LLSC;
+        }
+        break;
+        ////////////////////////
+      case ALLOC_TRT_IXR_RSP:
+        if ( (r_ixr_rsp_fsm.read() != IXR_RSP_TRT_ERASE) &&
+            (r_ixr_rsp_fsm.read() != IXR_RSP_TRT_READ) ) {
+          if      (r_read_fsm.read() == READ_TRT_LOCK) 	            r_alloc_trt_fsm = ALLOC_TRT_READ;
+          else if ((r_write_fsm.read() == WRITE_TRT_LOCK)   ||
+                   (r_write_fsm.read() == WRITE_TRT_WRITE_LOCK))    r_alloc_trt_fsm = ALLOC_TRT_WRITE;
+          else if ((r_llsc_fsm.read() == LLSC_TRT_LOCK) ||
+                   (r_llsc_fsm.read() == SC_TRT_LOCK))              r_alloc_trt_fsm = ALLOC_TRT_LLSC;
+          else if (r_xram_rsp_fsm.read() == XRAM_RSP_TRT_COPY)      r_alloc_trt_fsm = ALLOC_TRT_XRAM_RSP;
+        }
+        break;
+
+    } // end switch alloc_trt_fsm
+
+    ////////////////////////////////////////////////////////////////////////////////////
+    //		ALLOC_HEAP FSM
+    ////////////////////////////////////////////////////////////////////////////////////
+    // The ALLOC_HEAP FSM allocates the access to the heap
+    // with a round robin priority between 5 user FSMs :
+    // The cyclic ordering is READ > WRITE > LLSC > CLEANUP > XRAM_RSP
+    // The ressource is always allocated.
+    /////////////////////////////////////////////////////////////////////////////////////
+
+    switch ( r_alloc_heap_fsm.read() ) {
+
+      ////////////////////
+      case ALLOC_HEAP_READ:
+        if (  (r_read_fsm.read() != READ_HEAP_LOCK) &&
+              (r_read_fsm.read() != READ_HEAP_ERASE)     ) 
+        {
+          if        ((r_write_fsm.read() == WRITE_HEAP_LOCK) ||         
+                     (r_write_fsm.read() == WRITE_HEAP_ERASE))      r_alloc_heap_fsm = ALLOC_HEAP_WRITE;
+          else if  ((r_llsc_fsm.read() == SC_HEAP_LOCK) || 
+                    (r_llsc_fsm.read() == SC_HEAP_ERASE))           r_alloc_heap_fsm = ALLOC_HEAP_LLSC;
+          else if   (r_cleanup_fsm.read() == CLEANUP_HEAP_LOCK)     r_alloc_heap_fsm = ALLOC_HEAP_CLEANUP;
+          else if   (r_xram_rsp_fsm.read() == XRAM_RSP_HEAP_ERASE)  r_alloc_heap_fsm = ALLOC_HEAP_XRAM_RSP;
+        }
+        break;
+
+        /////////////////////
+      case ALLOC_HEAP_WRITE:
+        if (  (r_write_fsm.read() != WRITE_HEAP_LOCK)   &&
+              (r_write_fsm.read() != WRITE_UPT_REQ)     &&
+              (r_write_fsm.read() != WRITE_UPDATE)      &&
+              (r_write_fsm.read() != WRITE_HEAP_ERASE))
+        {
+          if       ((r_llsc_fsm.read() == SC_HEAP_LOCK) || 
+                    (r_llsc_fsm.read() == SC_HEAP_ERASE))           r_alloc_heap_fsm = ALLOC_HEAP_LLSC;
+          else if   (r_cleanup_fsm.read() == CLEANUP_HEAP_LOCK)     r_alloc_heap_fsm = ALLOC_HEAP_CLEANUP;
+          else if   (r_xram_rsp_fsm.read() == XRAM_RSP_HEAP_ERASE)  r_alloc_heap_fsm = ALLOC_HEAP_XRAM_RSP;
+          else if   (r_read_fsm.read() == READ_HEAP_LOCK) 	        r_alloc_heap_fsm = ALLOC_HEAP_READ;
+        }
+        break;
+
+        ////////////////////
+      case ALLOC_HEAP_LLSC:
+        if (  (r_llsc_fsm.read() != SC_HEAP_LOCK)  &&
+              (r_llsc_fsm.read() != SC_UPT_REQ )    &&
+              (r_llsc_fsm.read() != SC_UPDATE)      &&
+              (r_llsc_fsm.read() != SC_HEAP_ERASE ) )
+        {
+          if      (r_cleanup_fsm.read() == CLEANUP_HEAP_LOCK)     r_alloc_heap_fsm = ALLOC_HEAP_CLEANUP;
+          else if (r_xram_rsp_fsm.read() == XRAM_RSP_HEAP_ERASE)  r_alloc_heap_fsm = ALLOC_HEAP_XRAM_RSP;
+          else if (r_read_fsm.read() == READ_HEAP_LOCK)           r_alloc_heap_fsm = ALLOC_HEAP_READ;
+          else if ((r_write_fsm.read() == WRITE_HEAP_LOCK) ||        
+                   (r_write_fsm.read() == WRITE_HEAP_ERASE))      r_alloc_heap_fsm = ALLOC_HEAP_WRITE;
+        }
+        break;
+
+        ///////////////////////
+      case ALLOC_HEAP_CLEANUP:
+        if ( (r_cleanup_fsm.read() != CLEANUP_HEAP_LOCK) &&
+            (r_cleanup_fsm.read() != CLEANUP_HEAP_SEARCH)&&
+            (r_cleanup_fsm.read() != CLEANUP_HEAP_CLEAN)    )
+        {
+          if        (r_xram_rsp_fsm.read() == XRAM_RSP_HEAP_ERASE)  r_alloc_heap_fsm = ALLOC_HEAP_XRAM_RSP;
+          else if   (r_read_fsm.read() == READ_HEAP_LOCK)           r_alloc_heap_fsm = ALLOC_HEAP_READ;
+          else if   ((r_write_fsm.read() == WRITE_HEAP_LOCK) ||        
+                     (r_write_fsm.read() == WRITE_HEAP_ERASE))      r_alloc_heap_fsm = ALLOC_HEAP_WRITE;
+          else if   ((r_llsc_fsm.read() == SC_HEAP_LOCK) || 
+                    (r_llsc_fsm.read() == SC_HEAP_ERASE))           r_alloc_heap_fsm = ALLOC_HEAP_LLSC;
+        }
+        break;
+        ////////////////////////
+      case ALLOC_HEAP_XRAM_RSP:
+        if ( r_xram_rsp_fsm.read() != XRAM_RSP_HEAP_ERASE )
+        {
+          if        (r_read_fsm.read() == READ_HEAP_LOCK) 	        r_alloc_heap_fsm = ALLOC_HEAP_READ;
+          else if   ((r_write_fsm.read() == WRITE_HEAP_LOCK) ||        
+                     (r_write_fsm.read() == WRITE_HEAP_ERASE))      r_alloc_heap_fsm = ALLOC_HEAP_WRITE;
+          else if   ( (r_llsc_fsm.read() == SC_HEAP_LOCK) || 
+                    (r_llsc_fsm.read() == SC_HEAP_ERASE))           r_alloc_heap_fsm = ALLOC_HEAP_LLSC;
+          else if   (r_cleanup_fsm.read() == CLEANUP_HEAP_LOCK)     r_alloc_heap_fsm = ALLOC_HEAP_CLEANUP;
+        }
+        break;
+
+    } // end switch alloc_heap_fsm
+
+
+    ////////////////////////////////////////////////////////////////////////////////////
+    //		TGT_CMD to READ FIFO
+    ////////////////////////////////////////////////////////////////////////////////////
+
+    if ( cmd_read_fifo_put ) {
+      if ( cmd_read_fifo_get ) {
+        m_cmd_read_addr_fifo.put_and_get((addr_t)(p_vci_tgt.address.read()));
+        m_cmd_read_length_fifo.put_and_get(p_vci_tgt.plen.read()>>2);
+        m_cmd_read_srcid_fifo.put_and_get(p_vci_tgt.srcid.read());
+        m_cmd_read_trdid_fifo.put_and_get(p_vci_tgt.trdid.read());
+        m_cmd_read_pktid_fifo.put_and_get(p_vci_tgt.pktid.read());
+      } else {
+        m_cmd_read_addr_fifo.simple_put((addr_t)(p_vci_tgt.address.read()));
+        m_cmd_read_length_fifo.simple_put(p_vci_tgt.plen.read()>>2);
+        m_cmd_read_srcid_fifo.simple_put(p_vci_tgt.srcid.read());
+        m_cmd_read_trdid_fifo.simple_put(p_vci_tgt.trdid.read());
+        m_cmd_read_pktid_fifo.simple_put(p_vci_tgt.pktid.read());
+      }
+    } else {
+      if ( cmd_read_fifo_get ) {
+        m_cmd_read_addr_fifo.simple_get();
+        m_cmd_read_length_fifo.simple_get();
+        m_cmd_read_srcid_fifo.simple_get();
+        m_cmd_read_trdid_fifo.simple_get();
+        m_cmd_read_pktid_fifo.simple_get();
+      }
+    }
+    /////////////////////////////////////////////////////////////////////
+    //		TGT_CMD to WRITE FIFO
+    /////////////////////////////////////////////////////////////////////
+
+    if ( cmd_write_fifo_put ) {
+      if ( cmd_write_fifo_get ) {
+        m_cmd_write_addr_fifo.put_and_get((addr_t)(p_vci_tgt.address.read()));
+        m_cmd_write_eop_fifo.put_and_get(p_vci_tgt.eop.read());
+        m_cmd_write_srcid_fifo.put_and_get(p_vci_tgt.srcid.read());
+        m_cmd_write_trdid_fifo.put_and_get(p_vci_tgt.trdid.read());
+        m_cmd_write_pktid_fifo.put_and_get(p_vci_tgt.pktid.read());
+        m_cmd_write_data_fifo.put_and_get(p_vci_tgt.wdata.read());
+        m_cmd_write_be_fifo.put_and_get(p_vci_tgt.be.read());
+      } else {
+        m_cmd_write_addr_fifo.simple_put((addr_t)(p_vci_tgt.address.read()));
+        m_cmd_write_eop_fifo.simple_put(p_vci_tgt.eop.read());
+        m_cmd_write_srcid_fifo.simple_put(p_vci_tgt.srcid.read());
+        m_cmd_write_trdid_fifo.simple_put(p_vci_tgt.trdid.read());
+        m_cmd_write_pktid_fifo.simple_put(p_vci_tgt.pktid.read());
+        m_cmd_write_data_fifo.simple_put(p_vci_tgt.wdata.read());
+        m_cmd_write_be_fifo.simple_put(p_vci_tgt.be.read());
+      }
+    } else {
+      if ( cmd_write_fifo_get ) {
+        m_cmd_write_addr_fifo.simple_get();
+        m_cmd_write_eop_fifo.simple_get();
+        m_cmd_write_srcid_fifo.simple_get();
+        m_cmd_write_trdid_fifo.simple_get();
+        m_cmd_write_pktid_fifo.simple_get();
+        m_cmd_write_data_fifo.simple_get();
+        m_cmd_write_be_fifo.simple_get();
+      }
+    }
+    ////////////////////////////////////////////////////////////////////////////////////
+    //		TGT_CMD to LLSC FIFO
+    ////////////////////////////////////////////////////////////////////////////////////
+
+    if ( cmd_llsc_fifo_put ) {
+      if ( cmd_llsc_fifo_get ) {
+        m_cmd_llsc_addr_fifo.put_and_get((addr_t)(p_vci_tgt.address.read()));
+        m_cmd_llsc_sc_fifo.put_and_get(p_vci_tgt.cmd.read() == vci_param::CMD_STORE_COND); 
+        m_cmd_llsc_srcid_fifo.put_and_get(p_vci_tgt.srcid.read());
+        m_cmd_llsc_trdid_fifo.put_and_get(p_vci_tgt.trdid.read());
+        m_cmd_llsc_pktid_fifo.put_and_get(p_vci_tgt.pktid.read());
+        m_cmd_llsc_wdata_fifo.put_and_get(p_vci_tgt.wdata.read());
+      } else {
+        m_cmd_llsc_addr_fifo.simple_put((addr_t)(p_vci_tgt.address.read()));
+        m_cmd_llsc_sc_fifo.simple_put(p_vci_tgt.cmd.read() == vci_param::CMD_STORE_COND); 
+        m_cmd_llsc_srcid_fifo.simple_put(p_vci_tgt.srcid.read());
+        m_cmd_llsc_trdid_fifo.simple_put(p_vci_tgt.trdid.read());
+        m_cmd_llsc_pktid_fifo.simple_put(p_vci_tgt.pktid.read());
+        m_cmd_llsc_wdata_fifo.simple_put(p_vci_tgt.wdata.read());
+      }
+    } else {
+      if ( cmd_llsc_fifo_get ) {
+        m_cmd_llsc_addr_fifo.simple_get();
+        m_cmd_llsc_sc_fifo.simple_get();
+        m_cmd_llsc_srcid_fifo.simple_get();
+        m_cmd_llsc_trdid_fifo.simple_get();
+        m_cmd_llsc_pktid_fifo.simple_get();
+        m_cmd_llsc_wdata_fifo.simple_get();
+      }
+    }
+    ////////////////////////////////////////////////////////////////////////////////////
+    //		WRITE to INIT_CMD FIFO
+    ////////////////////////////////////////////////////////////////////////////////////
+
+    if ( write_to_init_cmd_fifo_put ) {
+      if ( write_to_init_cmd_fifo_get ) {
+        m_write_to_init_cmd_inst_fifo.put_and_get(write_to_init_cmd_fifo_inst);
+        m_write_to_init_cmd_srcid_fifo.put_and_get(write_to_init_cmd_fifo_srcid);
+      } else {
+        m_write_to_init_cmd_inst_fifo.simple_put(write_to_init_cmd_fifo_inst);
+        m_write_to_init_cmd_srcid_fifo.simple_put(write_to_init_cmd_fifo_srcid);
+      }
+    } else {
+      if ( write_to_init_cmd_fifo_get ) {
+        m_write_to_init_cmd_inst_fifo.simple_get();
+        m_write_to_init_cmd_srcid_fifo.simple_get();
+      }
+    }
+    ////////////////////////////////////////////////////////////////////////////////////
+    //		XRAM_RSP to INIT_CMD FIFO
+    ////////////////////////////////////////////////////////////////////////////////////
+
+    if ( xram_rsp_to_init_cmd_fifo_put ) {
+      if ( xram_rsp_to_init_cmd_fifo_get ) {
+        m_xram_rsp_to_init_cmd_inst_fifo.put_and_get(xram_rsp_to_init_cmd_fifo_inst);
+        m_xram_rsp_to_init_cmd_srcid_fifo.put_and_get(xram_rsp_to_init_cmd_fifo_srcid);
+      } else {
+        m_xram_rsp_to_init_cmd_inst_fifo.simple_put(xram_rsp_to_init_cmd_fifo_inst);
+        m_xram_rsp_to_init_cmd_srcid_fifo.simple_put(xram_rsp_to_init_cmd_fifo_srcid);
+      }
+    } else {
+      if ( xram_rsp_to_init_cmd_fifo_get ) {
+        m_xram_rsp_to_init_cmd_inst_fifo.simple_get();
+        m_xram_rsp_to_init_cmd_srcid_fifo.simple_get();
+      }
+    }
+    ////////////////////////////////////////////////////////////////////////////////////
+    //		LLSC to INIT_CMD FIFO
+    ////////////////////////////////////////////////////////////////////////////////////
+
+    if ( llsc_to_init_cmd_fifo_put ) {
+      if ( llsc_to_init_cmd_fifo_get ) {
+        m_llsc_to_init_cmd_inst_fifo.put_and_get(llsc_to_init_cmd_fifo_inst);
+        m_llsc_to_init_cmd_srcid_fifo.put_and_get(llsc_to_init_cmd_fifo_srcid);
+      } else {
+        m_llsc_to_init_cmd_inst_fifo.simple_put(llsc_to_init_cmd_fifo_inst);
+        m_llsc_to_init_cmd_srcid_fifo.simple_put(llsc_to_init_cmd_fifo_srcid);
+      }
+    } else {
+      if ( llsc_to_init_cmd_fifo_get ) {
+        m_llsc_to_init_cmd_inst_fifo.simple_get();
+        m_llsc_to_init_cmd_srcid_fifo.simple_get();
+      }
+    }
+
+
+  //////////////////////////////////////////////////////////////
+    m_cpt_cycles++;
+    m_total_cycles++;
+
+    if((m_period != 0) && ((m_cpt_cycles % m_period) == 0))
+    {
+        print_log();
+        clear_stats();
+    }
+
+  } // end transition()
+
+  /////////////////////////////
+  tmpl(void)::genMoore()
+    /////////////////////////////
+  {
+    ////////////////////////////////////////////////////////////
+    // Command signals on the p_vci_ixr port
+    ////////////////////////////////////////////////////////////
+
+
+    p_vci_ixr.be      = 0xF;
+    p_vci_ixr.pktid   = 0;
+    p_vci_ixr.srcid   = m_srcid_ixr;
+    p_vci_ixr.cons    = false;
+    p_vci_ixr.wrap    = false;
+    p_vci_ixr.contig  = true;
+    p_vci_ixr.clen    = 0;
+    p_vci_ixr.cfixed  = false;
+
+    if ( r_ixr_cmd_fsm.read() == IXR_CMD_READ_NLINE ) {
+      p_vci_ixr.cmd     = vci_param::CMD_READ;
+      p_vci_ixr.cmdval  = true;
+      p_vci_ixr.address = (addr_t)(r_read_to_ixr_cmd_nline.read()*m_words*4);
+      p_vci_ixr.plen    = m_words*4;
+      p_vci_ixr.wdata   = 0x00000000;
+      p_vci_ixr.trdid   = r_read_to_ixr_cmd_trdid.read();
+      p_vci_ixr.eop     = true;
+    } 
+    else if ( r_ixr_cmd_fsm.read() == IXR_CMD_LLSC_NLINE ) {
+      if(r_llsc_to_ixr_cmd_write.read()){
+        p_vci_ixr.cmd     = vci_param::CMD_WRITE;
+        p_vci_ixr.cmdval  = true;
+        p_vci_ixr.address = (addr_t)((r_llsc_to_ixr_cmd_nline.read()*m_words+r_ixr_cmd_cpt.read())*4);
+        p_vci_ixr.plen    = m_words*4;
+        p_vci_ixr.wdata   = r_llsc_to_ixr_cmd_data[r_ixr_cmd_cpt.read()].read();
+        p_vci_ixr.trdid   = r_llsc_to_ixr_cmd_trdid.read();
+        p_vci_ixr.eop     = (r_ixr_cmd_cpt == (m_words-1));
+      } else {
+        p_vci_ixr.cmd     = vci_param::CMD_READ;
+        p_vci_ixr.cmdval  = true;
+        p_vci_ixr.address = (addr_t)(r_llsc_to_ixr_cmd_nline.read()*m_words*4);
+        p_vci_ixr.plen    = m_words*4;
+        p_vci_ixr.wdata   = 0x00000000;
+        p_vci_ixr.trdid   = r_llsc_to_ixr_cmd_trdid.read();
+        p_vci_ixr.eop     = true;
+      }
+    } 
+    else if ( r_ixr_cmd_fsm.read() == IXR_CMD_WRITE_NLINE ) {
+      if(r_write_to_ixr_cmd_write.read()){
+        p_vci_ixr.cmd     = vci_param::CMD_WRITE;
+        p_vci_ixr.cmdval  = true;
+        p_vci_ixr.address = (addr_t)((r_write_to_ixr_cmd_nline.read()*m_words+r_ixr_cmd_cpt.read())*4);
+        p_vci_ixr.plen    = m_words*4;
+        p_vci_ixr.wdata   = r_write_to_ixr_cmd_data[r_ixr_cmd_cpt.read()].read();
+        p_vci_ixr.trdid   = r_write_to_ixr_cmd_trdid.read();
+        p_vci_ixr.eop     = (r_ixr_cmd_cpt == (m_words-1));
+      } else {
+        p_vci_ixr.cmd     = vci_param::CMD_READ;
+        p_vci_ixr.cmdval  = true;
+        p_vci_ixr.address = (addr_t)(r_write_to_ixr_cmd_nline.read()*m_words*4);
+        p_vci_ixr.plen    = m_words*4;
+        p_vci_ixr.wdata   = 0x00000000;
+        p_vci_ixr.trdid   = r_write_to_ixr_cmd_trdid.read();
+        p_vci_ixr.eop     = true;
+      }
+    } 
+    else if ( r_ixr_cmd_fsm.read() == IXR_CMD_XRAM_DATA ) {
+      p_vci_ixr.cmd     = vci_param::CMD_WRITE;
+      p_vci_ixr.cmdval  = true;
+      p_vci_ixr.address = (addr_t)((r_xram_rsp_to_ixr_cmd_nline.read()*m_words+r_ixr_cmd_cpt.read())*4);
+      p_vci_ixr.plen    = m_words*4;
+      p_vci_ixr.wdata   = r_xram_rsp_to_ixr_cmd_data[r_ixr_cmd_cpt.read()].read();
+      p_vci_ixr.trdid   = r_xram_rsp_to_ixr_cmd_trdid.read();
+      p_vci_ixr.eop     = (r_ixr_cmd_cpt == (m_words-1));
+    } else {
+      p_vci_ixr.cmdval  = false;
+      p_vci_ixr.address = 0;
+      p_vci_ixr.plen    = 0;
+      p_vci_ixr.wdata   = 0;
+      p_vci_ixr.trdid   = 0;
+      p_vci_ixr.eop	= false;
+    }
+
+    ////////////////////////////////////////////////////
+    // Response signals on the p_vci_ixr port
+    ////////////////////////////////////////////////////
+
+    if ( ((r_alloc_trt_fsm.read() == ALLOC_TRT_IXR_RSP) &&
+          (r_ixr_rsp_fsm.read() == IXR_RSP_TRT_READ)) || 
+        (r_ixr_rsp_fsm.read() == IXR_RSP_ACK) ) p_vci_ixr.rspack = true;
+    else                                        p_vci_ixr.rspack = false;
+
+    ////////////////////////////////////////////////////
+    // Command signals on the p_vci_tgt port
+    ////////////////////////////////////////////////////
+
+    switch ((tgt_cmd_fsm_state_e)r_tgt_cmd_fsm.read()) {
+      case TGT_CMD_IDLE:
+        p_vci_tgt.cmdack  = false;
+        break;
+      case TGT_CMD_READ:
+        p_vci_tgt.cmdack  = m_cmd_read_addr_fifo.wok();
+        break;
+      case TGT_CMD_READ_EOP:
+        p_vci_tgt.cmdack  = true;
+        break;
+      case TGT_CMD_WRITE:
+        p_vci_tgt.cmdack  = m_cmd_write_addr_fifo.wok();
+        break;
+      case TGT_CMD_ATOMIC:
+        p_vci_tgt.cmdack  = m_cmd_llsc_addr_fifo.wok();
+        break;
+      default:
+        p_vci_tgt.cmdack = false;
+        break;
+    }
+
+    ////////////////////////////////////////////////////
+    // Response signals on the p_vci_tgt port
+    ////////////////////////////////////////////////////
+    switch ( r_tgt_rsp_fsm.read() ) {
+
+      case TGT_RSP_READ_IDLE:
+      case TGT_RSP_WRITE_IDLE:
+      case TGT_RSP_LLSC_IDLE:
+      case TGT_RSP_XRAM_IDLE:
+      case TGT_RSP_INIT_IDLE:
+      case TGT_RSP_CLEANUP_IDLE:
+        p_vci_tgt.rspval  = false;
+        p_vci_tgt.rsrcid  = 0;
+        p_vci_tgt.rdata   = 0;
+        p_vci_tgt.rpktid  = 0;
+        p_vci_tgt.rtrdid  = 0;
+        p_vci_tgt.rerror  = 0;
+        p_vci_tgt.reop    = false;	
+        break;
+      case TGT_RSP_READ:
+        p_vci_tgt.rspval   = true;
+        p_vci_tgt.rdata    = r_read_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read();
+        p_vci_tgt.rsrcid   = r_read_to_tgt_rsp_srcid.read();
+        p_vci_tgt.rtrdid   = r_read_to_tgt_rsp_trdid.read();
+        p_vci_tgt.rpktid   = r_read_to_tgt_rsp_pktid.read();
+        p_vci_tgt.rerror   = 0;
+        p_vci_tgt.reop     = ( r_tgt_rsp_cpt.read() == (r_read_to_tgt_rsp_word.read()+r_read_to_tgt_rsp_length-1) );
+        break;
+      case TGT_RSP_WRITE:
+        p_vci_tgt.rspval   = true;
+        p_vci_tgt.rdata    = 0;
+        p_vci_tgt.rsrcid   = r_write_to_tgt_rsp_srcid.read();
+        p_vci_tgt.rtrdid   = r_write_to_tgt_rsp_trdid.read();
+        p_vci_tgt.rpktid   = r_write_to_tgt_rsp_pktid.read();
+        p_vci_tgt.rerror   = 0x2 & ( (1 << vci_param::E) - 1); // Write OK
+        p_vci_tgt.reop     = true;
+        break;
+      case TGT_RSP_CLEANUP:
+        p_vci_tgt.rspval   = true;
+        p_vci_tgt.rdata    = 0;
+        p_vci_tgt.rsrcid   = r_cleanup_to_tgt_rsp_srcid.read();
+        p_vci_tgt.rtrdid   = r_cleanup_to_tgt_rsp_trdid.read();
+        p_vci_tgt.rpktid   = r_cleanup_to_tgt_rsp_pktid.read();
+        p_vci_tgt.rerror   = 0;
+        p_vci_tgt.reop     = true;
+        break;
+      case TGT_RSP_LLSC:
+        p_vci_tgt.rspval   = true;
+        p_vci_tgt.rdata    = r_llsc_to_tgt_rsp_data.read();
+        p_vci_tgt.rsrcid   = r_llsc_to_tgt_rsp_srcid.read();
+        p_vci_tgt.rtrdid   = r_llsc_to_tgt_rsp_trdid.read();
+        p_vci_tgt.rpktid   = r_llsc_to_tgt_rsp_pktid.read();
+        p_vci_tgt.rerror   = 0;
+        p_vci_tgt.reop     = true;
+        break;
+      case TGT_RSP_XRAM:
+        p_vci_tgt.rspval   = true;
+        p_vci_tgt.rdata    = r_xram_rsp_to_tgt_rsp_data[r_tgt_rsp_cpt.read()].read();
+        p_vci_tgt.rsrcid   = r_xram_rsp_to_tgt_rsp_srcid.read();
+        p_vci_tgt.rtrdid   = r_xram_rsp_to_tgt_rsp_trdid.read();
+        p_vci_tgt.rpktid   = r_xram_rsp_to_tgt_rsp_pktid.read();
+        p_vci_tgt.rerror   = 0;
+        p_vci_tgt.reop     = ( r_tgt_rsp_cpt.read() == (r_xram_rsp_to_tgt_rsp_word.read()+r_xram_rsp_to_tgt_rsp_length.read()-1));
+        break;
+      case TGT_RSP_INIT:
+        p_vci_tgt.rspval   = true;
+        p_vci_tgt.rdata    = 0;
+        p_vci_tgt.rsrcid   = r_init_rsp_to_tgt_rsp_srcid.read();
+        p_vci_tgt.rtrdid   = r_init_rsp_to_tgt_rsp_trdid.read();
+        p_vci_tgt.rpktid   = r_init_rsp_to_tgt_rsp_pktid.read();
+        p_vci_tgt.rerror   = 0;
+        p_vci_tgt.reop     = true;	
+        break;
+    } // end switch r_tgt_rsp_fsm
+
+    ///////////////////////////////////////////////////
+    // Command signals on the p_vci_ini port
+    ///////////////////////////////////////////////////
+
+    p_vci_ini.cmd     = vci_param::CMD_WRITE;
+    p_vci_ini.srcid   = m_srcid_ini;
+    p_vci_ini.pktid   = 0;
+    p_vci_ini.cons    = true;
+    p_vci_ini.wrap    = false;
+    p_vci_ini.contig  = false;
+    p_vci_ini.clen    = 0;
+    p_vci_ini.cfixed  = false;
+
+    switch ( r_init_cmd_fsm.read() ) {
+
+      case INIT_CMD_UPDT_IDLE:
+      case INIT_CMD_INVAL_IDLE:
+      case INIT_CMD_SC_UPDT_IDLE:
+        p_vci_ini.cmdval  = false;
+        p_vci_ini.address = 0;
+        p_vci_ini.wdata   = 0;
+        p_vci_ini.be      = 0;
+        p_vci_ini.plen    = 0;
+        p_vci_ini.trdid   = 0;
+        p_vci_ini.eop     = false;
+        break;
+      case INIT_CMD_INVAL_NLINE:
+        p_vci_ini.cmdval  = m_xram_rsp_to_init_cmd_inst_fifo.rok();
+        if(m_xram_rsp_to_init_cmd_inst_fifo.rok()){
+          if(m_xram_rsp_to_init_cmd_inst_fifo.read()) {
+            p_vci_ini.address = (addr_t)(m_coherence_table[m_xram_rsp_to_init_cmd_srcid_fifo.read()]+8);
+          } else {
+            p_vci_ini.address = (addr_t)(m_coherence_table[m_xram_rsp_to_init_cmd_srcid_fifo.read()]);
+          }
+        } else p_vci_ini.address = 0; // prevent segmentation faults by reading an empty fifo
+        p_vci_ini.wdata   = (uint32_t)r_xram_rsp_to_init_cmd_nline.read();
+        p_vci_ini.be      = ((r_xram_rsp_to_init_cmd_nline.read() >> 32) & 0x3);
+        p_vci_ini.plen    = 4;
+        p_vci_ini.trdid   = r_xram_rsp_to_init_cmd_trdid.read();
+        p_vci_ini.eop     = true;
+        break;
+      case INIT_CMD_XRAM_BRDCAST:
+        p_vci_ini.cmdval  = true;
+        p_vci_ini.address = broadcast_addr;
+        p_vci_ini.wdata   = (uint32_t)r_xram_rsp_to_init_cmd_nline.read();
+        p_vci_ini.be      = ((r_xram_rsp_to_init_cmd_nline.read() >> 32) & 0x3);
+        p_vci_ini.plen    = 4;
+        p_vci_ini.trdid   = r_xram_rsp_to_init_cmd_trdid.read();
+        p_vci_ini.eop     = true;
+        break;
+
+      case INIT_CMD_WRITE_BRDCAST:
+        p_vci_ini.cmdval  = true;
+        p_vci_ini.address = broadcast_addr;
+        p_vci_ini.wdata   = (addr_t)r_write_to_init_cmd_nline.read();
+        p_vci_ini.be      = ((r_write_to_init_cmd_nline.read() >> 32) & 0x3);
+        p_vci_ini.plen    = 4 ;
+        p_vci_ini.eop     = true;
+        p_vci_ini.trdid   = r_write_to_init_cmd_trdid.read();
+        break;
+      case INIT_CMD_UPDT_NLINE:
+        p_vci_ini.cmdval  = m_write_to_init_cmd_inst_fifo.rok();
+        if(m_write_to_init_cmd_inst_fifo.rok()){
+          p_vci_ini.address = (addr_t)(m_coherence_table[m_write_to_init_cmd_srcid_fifo.read()] + 4);
+        } else {
+          p_vci_ini.address = 0;
+        }
+        p_vci_ini.wdata   = (uint32_t)r_write_to_init_cmd_nline.read();
+        p_vci_ini.be      = ((r_write_to_init_cmd_nline.read() >> 32 ) & 0x3);
+        p_vci_ini.plen    = 4 * (r_write_to_init_cmd_count.read() + 2);
+        p_vci_ini.eop     = false;
+        p_vci_ini.trdid   = r_write_to_init_cmd_trdid.read();
+        break;
+      case INIT_CMD_UPDT_INDEX:
+        p_vci_ini.cmdval  = true;
+        p_vci_ini.address = (addr_t)(m_coherence_table[m_write_to_init_cmd_srcid_fifo.read()] + 4);
+        p_vci_ini.wdata   = r_write_to_init_cmd_index.read();
+        p_vci_ini.be      = 0xF;
+        p_vci_ini.plen    = 4 * (r_write_to_init_cmd_count.read() + 2);
+        p_vci_ini.trdid   = r_write_to_init_cmd_trdid.read();
+        p_vci_ini.eop     = false;
+        break;
+      case INIT_CMD_UPDT_DATA:
+        p_vci_ini.cmdval  = true;
+        p_vci_ini.address = (addr_t)(m_coherence_table[m_write_to_init_cmd_srcid_fifo.read()] + 4);
+        p_vci_ini.wdata   = r_write_to_init_cmd_data[r_init_cmd_cpt.read() +
+          r_write_to_init_cmd_index.read()].read();
+        if(r_write_to_init_cmd_we[r_init_cmd_cpt.read() +
+            r_write_to_init_cmd_index.read()].read())  
+          p_vci_ini.be      = 0xF;
+        else			p_vci_ini.be      = 0x0;
+        p_vci_ini.plen    = 4 * (r_write_to_init_cmd_count.read() + 2);
+        p_vci_ini.trdid   = r_write_to_init_cmd_trdid.read();
+        p_vci_ini.eop     = ( r_init_cmd_cpt.read() == (r_write_to_init_cmd_count.read()-1) );
+        break;
+
+      case INIT_CMD_SC_BRDCAST:
+        p_vci_ini.cmdval  = true;
+        p_vci_ini.address = broadcast_addr;
+        p_vci_ini.wdata   = (addr_t)r_llsc_to_init_cmd_nline.read();
+        p_vci_ini.be      = ((r_llsc_to_init_cmd_nline.read() >> 32) & 0x3);
+        p_vci_ini.plen    = 4 ;
+        p_vci_ini.eop     = true;
+        p_vci_ini.trdid   = r_llsc_to_init_cmd_trdid.read();
+        break;
+      case INIT_CMD_SC_UPDT_NLINE:
+        p_vci_ini.cmdval  = m_llsc_to_init_cmd_inst_fifo.rok();
+        if(m_llsc_to_init_cmd_inst_fifo.rok()){
+          p_vci_ini.address = (addr_t)(m_coherence_table[m_llsc_to_init_cmd_srcid_fifo.read()] + 4);
+        } else {
+          p_vci_ini.address = 0;
+        }
+        p_vci_ini.wdata   = (uint32_t)r_llsc_to_init_cmd_nline.read();
+        p_vci_ini.be      = ((r_llsc_to_init_cmd_nline.read() >> 32 ) & 0x3);
+        p_vci_ini.plen    = 4 * 3;
+        p_vci_ini.eop     = false;
+        p_vci_ini.trdid   = r_llsc_to_init_cmd_trdid.read();
+        break;
+      case INIT_CMD_SC_UPDT_INDEX:
+        p_vci_ini.cmdval  = true;
+        p_vci_ini.address = (addr_t)(m_coherence_table[m_llsc_to_init_cmd_srcid_fifo.read()] + 4);
+        p_vci_ini.wdata   = r_llsc_to_init_cmd_index.read();
+        p_vci_ini.be      = 0xF;
+        p_vci_ini.plen    = 4 * 3;
+        p_vci_ini.trdid   = r_llsc_to_init_cmd_trdid.read();
+        p_vci_ini.eop     = false;
+        break;
+      case INIT_CMD_SC_UPDT_DATA:
+        p_vci_ini.cmdval  = true;
+        p_vci_ini.address = (addr_t)(m_coherence_table[m_llsc_to_init_cmd_srcid_fifo.read()] + 4);
+        p_vci_ini.wdata   = r_llsc_to_init_cmd_wdata.read();
+        p_vci_ini.be      = 0xF;
+        p_vci_ini.plen    = 4 * 3;
+        p_vci_ini.trdid   = r_llsc_to_init_cmd_trdid.read();
+        p_vci_ini.eop     = true;
+        break;
+
+    } // end switch r_init_cmd_fsm
+
+    //////////////////////////////////////////////////////
+    // Response signals on the p_vci_ini port
+    //////////////////////////////////////////////////////
+
+    if ( r_init_rsp_fsm.read() == INIT_RSP_IDLE ) p_vci_ini.rspack  = true;
+    else                                          p_vci_ini.rspack  = false;
+
+    //////////////////////////////////////////////////////
+    // Response signals on the p_vci_tgt_cleanup port
+    //////////////////////////////////////////////////////
+    p_vci_tgt_cleanup.rspval = false;
+    p_vci_tgt_cleanup.rsrcid = 0;
+    p_vci_tgt_cleanup.rdata  = 0;
+    p_vci_tgt_cleanup.rpktid = 0;
+    p_vci_tgt_cleanup.rtrdid = 0;
+    p_vci_tgt_cleanup.rerror = 0;
+    p_vci_tgt_cleanup.reop   = false;
+    p_vci_tgt_cleanup.cmdack = false ;
+
+    switch(r_cleanup_fsm.read()){
+      case CLEANUP_IDLE:
+        {
+          p_vci_tgt_cleanup.cmdack = true ;
+          break;
+        }
+      case CLEANUP_RSP:
+        {
+          p_vci_tgt_cleanup.rspval = true;
+          p_vci_tgt_cleanup.rdata  = 0;
+          p_vci_tgt_cleanup.rsrcid = r_cleanup_srcid.read();
+          p_vci_tgt_cleanup.rpktid = r_cleanup_pktid.read();
+          p_vci_tgt_cleanup.rtrdid = r_cleanup_trdid.read();
+          p_vci_tgt_cleanup.rerror = 0x2 & ( (1 << vci_param::E) - 1);
+          p_vci_tgt_cleanup.reop   = 1;
+          break;
+        }
+
+    }
+
+  } // end genMoore()
+
+}} // end name space
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: trunk/platforms/almos-tsarv3-platforms/common/vci_vdspin_initiator_wrapper/caba/metadata/vci_vdspin_initiator_wrapper.sd
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/vci_vdspin_initiator_wrapper/caba/metadata/vci_vdspin_initiator_wrapper.sd	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/vci_vdspin_initiator_wrapper/caba/metadata/vci_vdspin_initiator_wrapper.sd	(revision 259)
@@ -0,0 +1,25 @@
+
+# -*- python -*-
+
+Module('caba:vci_vdspin_initiator_wrapper',
+		classname = 'soclib::caba::VciVdspinInitiatorWrapper',
+	tmpl_parameters = [
+		parameter.Module('vci_param',  default = 'caba:vci_param'),
+		parameter.Int('dspin_cmd_width'),
+		parameter.Int('dspin_rsp_width'), ],
+        header_files = ['../source/include/vci_vdspin_initiator_wrapper.h', ],
+        implementation_files = ['../source/src/vci_vdspin_initiator_wrapper.cpp',],
+        ports = [
+		Port('caba:vci_initiator', 'p_vci'),
+                Port('caba:dspin_output', 'p_dspin_out', dspin_data_size = parameter.Reference('dspin_cmd_width')),
+                Port('caba:dspin_input', 'p_dspin_in', dspin_data_size = parameter.Reference('dspin_rsp_width')),
+		Port('caba:bit_in', 'p_resetn', auto = 'resetn'),
+		Port('caba:clock_in', 'p_clk', auto = 'clock'), ],
+	uses = [
+		Uses('caba:base_module'),
+		Uses('caba:generic_fifo'),
+		],
+	instance_parameters = [
+		parameter.Int('cmd_fifo_depth'),
+		parameter.Int('rsp_fifo_depth'), ],
+)
Index: trunk/platforms/almos-tsarv3-platforms/common/vci_vdspin_initiator_wrapper/caba/source/include/vci_vdspin_initiator_wrapper.h
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/vci_vdspin_initiator_wrapper/caba/source/include/vci_vdspin_initiator_wrapper.h	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/vci_vdspin_initiator_wrapper/caba/source/include/vci_vdspin_initiator_wrapper.h	(revision 259)
@@ -0,0 +1,125 @@
+/* -*- c++ -*-
+  * File : vci_vdspin_initiator_wrapper.h
+  * Copyright (c) UPMC, Lip6
+  * Author : Alain Greiner
+  *
+  * SOCLIB_LGPL_HEADER_BEGIN
+  * 
+  * This file is part of SoCLib, GNU LGPLv2.1.
+  * 
+  * SoCLib is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU Lesser General Public License as published
+  * by the Free Software Foundation; version 2.1 of the License.
+  * 
+  * SoCLib is distributed in the hope that it will be useful, but
+  * WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  * 
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with SoCLib; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+  * 02110-1301 USA
+  * 
+  * SOCLIB_LGPL_HEADER_END
+  */
+
+/////////////////////////////////////////////////////////////////////////
+// This component performs the protocol translation between VCI & DSPIN,
+// and can be used to connect a VCI initiator to a DSPIN network.
+// It is implemented as two fully independant sub-components:
+// - translation from a VCI CMD to a DSPIN CMD
+// - translation from a DSPIN RSP to a VCI RSP
+// Each subcomponent contains a FIFO containing DSPIN flits.
+// For the DSPIN interfaces, the widths of the CMD & RSP flits
+// are defined as template parameters for future evolutions,
+// but the VCI to DSPIN translation makes the following assumptions:
+// - DSPIN CMD flit width = 40 bits
+// - DSPIN RSP flit width = 33 bits
+// - VCI address width    <= 40 bits
+// - VCI data             == 32 bits
+// - VCI plen             == 8  bits
+// - VCI srcid            <= 14 bits
+// - VCI trdid            <= 8  bits
+// - VCI pktid field not transmitted
+// - VCI rerror           == 2 bits
+////////////////////////////////////////////////////////////////////////
+
+#ifndef VCI_VDSPIN_INITIATOR_WRAPPER_H_
+#define VCI_VDSPIN_INITIATOR_WRAPPER_H_
+
+#include <systemc>
+#include <assert.h>
+#include "caba_base_module.h"
+#include "vci_target.h"
+#include "generic_fifo.h"
+#include "dspin_interface.h"
+
+namespace soclib { namespace caba {
+
+template<typename vci_param, int dspin_cmd_width, int dspin_rsp_width>
+class VciVdspinInitiatorWrapper
+	: public soclib::caba::BaseModule
+{
+    // Command FSM 
+    enum fsm_state_cmd{
+	CMD_IDLE,
+	CMD_BROADCAST,
+	CMD_READ,
+	CMD_WRITE,
+	CMD_WDATA,
+    };
+
+    // Response FSM
+    enum fsm_state_rsp{
+	RSP_IDLE,
+	RSP_READ,		
+	RSP_WRITE,	
+    };
+
+protected:
+    SC_HAS_PROCESS(VciVdspinInitiatorWrapper);
+
+public:
+    // ports
+    sc_core::sc_in<bool>                             		p_clk;
+    sc_core::sc_in<bool>                             		p_resetn;
+    soclib::caba::DspinOutput<dspin_cmd_width>			p_dspin_out;
+    soclib::caba::DspinInput<dspin_rsp_width>			p_dspin_in;
+    soclib::caba::VciTarget<vci_param>      			p_vci;
+
+    // constructor / destructor
+    VciVdspinInitiatorWrapper(	sc_module_name 			name, 
+				size_t				cmd_fifo_depth,
+				size_t				rsp_fifo_depth);
+private:
+    // internal registers
+    sc_core::sc_signal<int>        				r_cmd_fsm;
+    sc_core::sc_signal<int>        				r_rsp_fsm;
+    sc_core::sc_signal<sc_uint<dspin_rsp_width>	>		r_rsp_buf;
+
+    // fifos cmd and rsp
+    soclib::caba::GenericFifo<sc_uint<dspin_cmd_width> >  	r_fifo_cmd;
+    soclib::caba::GenericFifo<sc_uint<dspin_rsp_width> >  	r_fifo_rsp;
+
+    // methods systemc
+    void transition();
+    void genMoore();
+
+public:
+    void print_trace();
+
+};
+
+}} // end namespace
+               
+#endif // VCI_VDSPIN_INITIATOR_WRAPPER_H_
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Index: trunk/platforms/almos-tsarv3-platforms/common/vci_vdspin_initiator_wrapper/caba/source/src/vci_vdspin_initiator_wrapper.cpp
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/vci_vdspin_initiator_wrapper/caba/source/src/vci_vdspin_initiator_wrapper.cpp	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/vci_vdspin_initiator_wrapper/caba/source/src/vci_vdspin_initiator_wrapper.cpp	(revision 259)
@@ -0,0 +1,351 @@
+/* -*- c++ -*-
+  * File : vci_vdspin_initiator_wrapper.cpp
+  * Copyright (c) UPMC, Lip6
+  * Authors : Alain Greiner
+  *
+  * SOCLIB_LGPL_HEADER_BEGIN
+  * 
+  * This file is part of SoCLib, GNU LGPLv2.1.
+  * 
+  * SoCLib is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU Lesser General Public License as published
+  * by the Free Software Foundation; version 2.1 of the License.
+  * 
+  * SoCLib is distributed in the hope that it will be useful, but
+  * WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  * 
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with SoCLib; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+  * 02110-1301 USA
+  * 
+  * SOCLIB_LGPL_HEADER_END
+  */
+
+#include "../include/vci_vdspin_initiator_wrapper.h"
+
+namespace soclib { namespace caba {
+
+#define tmpl(x) template<typename vci_param, int dspin_cmd_width, int dspin_rsp_width> x VciVdspinInitiatorWrapper<vci_param, dspin_cmd_width, dspin_rsp_width>
+
+//////////////////////////////////////////////////////////:////////////////////////////////
+tmpl(/**/)::VciVdspinInitiatorWrapper(sc_module_name 			name,
+				      size_t				cmd_fifo_depth,
+				      size_t				rsp_fifo_depth)
+	       : soclib::caba::BaseModule(name),
+                 p_clk("p_clk"),
+                 p_resetn("p_resetn"),
+                 p_dspin_out("p_dspin_out"),
+                 p_dspin_in("p_dspin_in"),
+                 p_vci("p_vci"),
+                 r_cmd_fsm("r_cmd_fsm"),
+                 r_rsp_fsm("r_rsp_fsm"),
+	         r_fifo_cmd("r_fifo_cmd", cmd_fifo_depth),
+	         r_fifo_rsp("r_fifo_rsp", rsp_fifo_depth)
+    {
+	SC_METHOD (transition);
+	dont_initialize();
+	sensitive << p_clk.pos();
+	SC_METHOD (genMoore);
+	dont_initialize();
+	sensitive  << p_clk.neg();
+
+        assert( (dspin_cmd_width == 40) && "The DSPIN CMD flit width must have 40 bits");
+        assert( (dspin_rsp_width == 33) && "The DSPIN RSP flit width must have 33 bits");
+        assert( (vci_param::N    <= 40) && "The VCI ADDRESS field cannot have more than 40 bits"); 
+        assert( (vci_param::B    == 4) && "The VCI DATA filds must have 32 bits");
+        assert( (vci_param::K    == 8) && "The VCI PLEN field cannot have more than 8 bits");
+        assert( (vci_param::S    <= 14) && "The VCI SRCID field cannot have more than 8 bits");
+        assert( (vci_param::T    <= 8) && "The VCI TRDID field cannot have more than 8 bits");
+        //assert( (vci_param::E    == 2) && "The VCI RERROR field cannot have more than 2 bits");
+
+    } //  end constructor
+
+/////////////////////////
+tmpl(void)::transition()
+{
+	sc_uint<dspin_cmd_width>	cmd_fifo_data;
+	bool				cmd_fifo_write;
+	bool				cmd_fifo_read;
+
+	sc_uint<dspin_rsp_width>	rsp_fifo_data;
+	bool				rsp_fifo_write;
+	bool				rsp_fifo_read;
+
+	if (p_resetn == false) 
+        {
+	    r_fifo_cmd.init();
+	    r_fifo_rsp.init();
+	    r_cmd_fsm = CMD_IDLE;
+	    r_rsp_fsm = RSP_IDLE;
+	    return;
+	} // end reset
+
+        /////////////////////////////////////////////////////////////
+	// VCI command packet to DSPIN command packet
+	// The VCI packet is analysed, translated,
+	// and the DSPIN packet is stored in the fifo_cmd
+        /////////////////////////////////////////////////////////////
+        // - A N flits VCI write command packet is translated
+        //   to a N+2 flits DSPIN command.
+        // - A single flit VCI read command packet is translated 
+        //   to a 2 flits DSPIN command.
+        // - A single flit VCI broadcast packet is translated to
+        //   a 2 flits DSPIN command.
+        // A DSPIN flit is written in the fifo_cmd in all states
+        // but a VCI flit is consumed only in the CMD_READ,
+        // CMD_BROACAST,  and CMD_WDATA states.
+        //////////////////////////////////////////////////////////////
+
+	// cmd_fifo_read
+	cmd_fifo_read = p_dspin_out.read.read();
+
+	// r_cmd_fsm, cmd_fifo_write and cmd_fifo_data
+        cmd_fifo_write = false;		// default value
+
+	switch(r_cmd_fsm) {
+	    case CMD_IDLE:		// write first DSPIN flit into fifo_cmd
+            {
+		if( p_vci.cmdval && r_fifo_cmd.wok() ) 
+                {
+		    cmd_fifo_write = true;
+                    sc_uint<dspin_cmd_width> address = (sc_uint<dspin_cmd_width>)p_vci.address.read();
+                    sc_uint<dspin_cmd_width> srcid   = (sc_uint<dspin_cmd_width>)p_vci.srcid.read();
+                    sc_uint<dspin_cmd_width> trdid   = (sc_uint<dspin_cmd_width>)p_vci.trdid.read();
+                    sc_uint<dspin_cmd_width> cmd     = (sc_uint<dspin_cmd_width>)p_vci.cmd.read();
+
+                    bool is_broadcast = ( (address & 0x3) != 0);
+                    bool is_read = ((cmd == vci_param::CMD_READ) || (cmd == vci_param::CMD_LOCKED_READ));
+
+                    if ( vci_param::N == 40 ) address = address >> 1;
+                    else                      address = address << (39 - vci_param::N);              
+
+                    if ( is_broadcast )	// VCI broacast command
+                    {
+                        r_cmd_fsm     = CMD_BROADCAST;
+                        cmd_fifo_data = (address      & 0x7FFFF80000ULL) |
+                                        ((srcid << 5) & 0x000007FFE0) | 
+                                        ((trdid << 1) & 0x000000001E) | 
+                                                        0x0000000001;		
+                    }
+                    else if (is_read )			// VCI READ  command
+                    {
+		        r_cmd_fsm     = CMD_READ;
+                        cmd_fifo_data = address & 0x7FFFFFFFFEULL;
+		    }
+                    else 				// VCI WRITE command
+                    {
+		        r_cmd_fsm     = CMD_WRITE;
+                        cmd_fifo_data = address & 0x7FFFFFFFFEULL;
+		    }
+		}
+	 	break;
+            }
+	    case CMD_BROADCAST:		// write second DSPIN flit in case of broadcast
+            {    
+		if( p_vci.cmdval && r_fifo_cmd.wok() ) 
+                {
+                    cmd_fifo_write   = true;
+                    sc_uint<dspin_cmd_width> data = (sc_uint<dspin_cmd_width>)p_vci.wdata.read();
+                    sc_uint<dspin_cmd_width> be   = (sc_uint<dspin_cmd_width>)p_vci.be.read();
+                    cmd_fifo_data    = (data       & 0x00FFFFFFFFUL) | 
+                                       ((be << 32) & 0x0300000000ULL) |
+                                                     0x8000000000ULL; 
+                    r_cmd_fsm = CMD_IDLE;
+                }
+                break;
+            }
+            case CMD_READ:	// write second DSPIN flit in case of read/write
+            case CMD_WRITE:
+            {
+		if( p_vci.cmdval && r_fifo_cmd.wok() ) 
+                {
+		    cmd_fifo_write      = true;
+                    sc_uint<dspin_cmd_width> srcid   = (sc_uint<dspin_cmd_width>)p_vci.srcid.read();
+                    sc_uint<dspin_cmd_width> trdid   = (sc_uint<dspin_cmd_width>)p_vci.trdid.read();
+                    sc_uint<dspin_cmd_width> cmd     = (sc_uint<dspin_cmd_width>)p_vci.cmd.read();
+                    sc_uint<dspin_cmd_width> plen    = (sc_uint<dspin_cmd_width>)p_vci.plen.read();
+                    sc_uint<dspin_cmd_width> be      = (sc_uint<dspin_cmd_width>)p_vci.be.read();
+		    cmd_fifo_data       = ((be    << 1 ) & 0x000000001E) |
+                                          ((trdid << 5 ) & 0x0000001FE0) |
+                                          ((plen  << 13) & 0x00001FE000) |
+                                          ((cmd   << 23) & 0x0001800000) |
+                                          ((srcid << 25) & 0x7FFE000000ULL) ;
+                    if ( p_vci.contig.read() ) cmd_fifo_data = cmd_fifo_data | 0x0000400000 ;
+                    if ( p_vci.cons.read()   ) cmd_fifo_data = cmd_fifo_data | 0x0000200000 ;
+
+                    if( r_cmd_fsm == CMD_READ )  // read command
+                    {
+                        r_cmd_fsm = CMD_IDLE;
+                        cmd_fifo_data = cmd_fifo_data    | 0x8000000000ULL ;
+                    }
+                    else			// write command
+                    {
+                        r_cmd_fsm = CMD_WDATA;
+                    }
+		}
+		break;
+            }
+	    case CMD_WDATA:
+            {
+		if( p_vci.cmdval && r_fifo_cmd.wok() ) 
+                {
+		    cmd_fifo_write = true;
+                    sc_uint<dspin_cmd_width> data = (sc_uint<dspin_cmd_width>)p_vci.wdata.read();
+                    sc_uint<dspin_cmd_width> be   = (sc_uint<dspin_cmd_width>)p_vci.be.read();
+		    cmd_fifo_data    = (data       & 0x00FFFFFFFFUL) | 
+                                       ((be << 32) & 0x0F00000000ULL) ;
+                                       
+                    if ( p_vci.eop.read() )
+                    {
+                        cmd_fifo_data = cmd_fifo_data | 0x8000000000ULL;
+                        r_cmd_fsm = CMD_IDLE;
+                    }
+                }                
+                break;
+            }
+	} // end switch r_cmd_fsm
+	
+	// fifo_cmd
+	if((cmd_fifo_write == true)  && (cmd_fifo_read == false)) { r_fifo_cmd.simple_put(cmd_fifo_data); } 
+	if((cmd_fifo_write == true)  && (cmd_fifo_read == true))  { r_fifo_cmd.put_and_get(cmd_fifo_data); } 
+	if((cmd_fifo_write == false) && (cmd_fifo_read == true))  { r_fifo_cmd.simple_get(); }
+
+        //////////////////////////////////////////////////////////////
+	// DSPIN response packet to VCI response packet
+	// The DSPIN packet is stored in the fifo_rsp
+	// The FIFO output is analysed and translated to a VCI packet
+        //////////////////////////////////////////////////////////////
+        // - A N+1 flits DSPIN read response packet is translated
+        //   to a N flits VCI response.
+        // - A single flit DSPIN write response packet is translated
+        //   to a single flit VCI response.
+        // A valid DSPIN flit in the fifo_rsp is always consumed   
+        // in the CMD_IDLE state, but no VCI flit is transmitted.
+        // The VCI flits are sent in the RSP_READ & RSP_WRITE states.
+        //////////////////////////////////////////////////////////////
+
+	// rsp_fifo_write, rsp_fifo_data
+	rsp_fifo_write = p_dspin_in.write.read();
+	rsp_fifo_data  = p_dspin_in.data.read();
+
+	// r_rsp_fsm, rsp_fifo_read
+        rsp_fifo_read = false;		// default value
+
+	switch(r_rsp_fsm) {
+	    case RSP_IDLE:
+            {
+		if( r_fifo_rsp.rok() )
+                {
+		    rsp_fifo_read = true;
+                    r_rsp_buf = r_fifo_rsp.read();
+                    if ( (r_fifo_rsp.read() & 0x000020000) == 0 )  r_rsp_fsm = RSP_READ;
+                    else 					   r_rsp_fsm = RSP_WRITE;
+		}
+		break;
+            }
+	    case RSP_READ:		
+	    {
+		if( r_fifo_rsp.rok() && p_vci.rspack.read() )
+                {
+		    rsp_fifo_read = true;
+                    if ( (r_fifo_rsp.read() & 0x100000000ULL) ) r_rsp_fsm = RSP_IDLE;
+		}
+		break;
+            }
+            case RSP_WRITE:
+            {
+                if ( p_vci.rspack.read() ) r_rsp_fsm = RSP_IDLE;
+            }
+	} // end switch r_rsp_fsm
+
+	// fifo_rsp
+	if((rsp_fifo_write == true)  && (rsp_fifo_read == false)) { r_fifo_rsp.simple_put(rsp_fifo_data); } 
+	if((rsp_fifo_write == true)  && (rsp_fifo_read == true))  { r_fifo_rsp.put_and_get(rsp_fifo_data); } 
+	if((rsp_fifo_write == false) && (rsp_fifo_read == true))  { r_fifo_rsp.simple_get(); }
+
+}; // end transition
+
+//////////////////////
+tmpl(void)::genMoore()
+{
+	// VCI CMD interface
+        if ( ( r_cmd_fsm.read() == CMD_IDLE ) || ( r_cmd_fsm.read() == CMD_WRITE ) ) 
+        {
+            p_vci.cmdack = false; 
+        }
+	else
+        {
+            p_vci.cmdack = r_fifo_cmd.wok();
+        }
+
+	// VCI RSP interface
+	if ( r_rsp_fsm.read() == RSP_IDLE )
+        {
+            p_vci.rspval = false;
+        }
+        else if ( r_rsp_fsm.read() == RSP_WRITE )
+        {
+            p_vci.rspval = true;
+	    p_vci.rdata  = 0;
+            p_vci.rsrcid = (sc_uint<vci_param::S>)((r_rsp_buf.read() & 0x0FFFC0000ULL) >> 18);
+            p_vci.rtrdid = (sc_uint<vci_param::T>)((r_rsp_buf.read() & 0x00000FF00) >> 8);
+            p_vci.rpktid = 0;
+            p_vci.rerror = (sc_uint<vci_param::E>)((r_rsp_buf.read() & 0x000030000) >> 16);
+            p_vci.reop   = true;
+        }
+        else if ( r_rsp_fsm.read() == RSP_READ )
+        {
+            p_vci.rspval = r_fifo_rsp.rok();
+            p_vci.rdata  = (sc_uint<8*vci_param::B>)(r_fifo_rsp.read() & 0x0FFFFFFFFUL);
+            p_vci.rsrcid = (sc_uint<vci_param::S>)((r_rsp_buf.read()   & 0x0FFFC0000) >> 18);
+            p_vci.rtrdid = (sc_uint<vci_param::T>)((r_rsp_buf.read()   & 0x00000FF00) >> 8);
+            p_vci.rpktid = 0;
+            p_vci.rerror = (sc_uint<vci_param::E>)((r_rsp_buf.read()   & 0x000030000) >> 16);
+            p_vci.reop   = ((r_fifo_rsp.read() & 0x100000000ULL) == 0x100000000ULL); 
+        }
+
+	// DSPIN_OUT interface
+	p_dspin_out.write = r_fifo_cmd.rok();
+	p_dspin_out.data  = r_fifo_cmd.read();
+
+	// DSPIN_IN interface
+	p_dspin_in.read = r_fifo_rsp.wok();
+
+}; // end genMoore
+
+/////////////////////////
+tmpl(void)::print_trace()
+{
+    const char* cmd_str[] = {
+    "CMD_IDLE     ",
+    "CMD_BROADCAST",
+    "CMD_READ     ",
+    "CMD_WRITE    ",
+    "CMD_WDATA    ",
+    };
+    const char* rsp_str[] = {
+    "RSP_IDLE     ",
+    "RSP_READ     ",
+    "RSP_WRITE    ",
+    };
+
+    std::cout << name() << " : " << cmd_str[r_cmd_fsm.read()]
+                        << " | " << rsp_str[r_rsp_fsm.read()] 
+                        << " | fifo_cmd = " << r_fifo_cmd.filled_status()
+                        << " | fifo_rsp = " << r_fifo_rsp.filled_status()
+                        << std::endl;
+}
+
+}} // end namespace
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Index: trunk/platforms/almos-tsarv3-platforms/common/vci_vdspin_target_wrapper/caba/metadata/vci_vdspin_target_wrapper.sd
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/vci_vdspin_target_wrapper/caba/metadata/vci_vdspin_target_wrapper.sd	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/vci_vdspin_target_wrapper/caba/metadata/vci_vdspin_target_wrapper.sd	(revision 259)
@@ -0,0 +1,25 @@
+
+# -*- python -*-
+
+Module('caba:vci_vdspin_target_wrapper',
+	classname = 'soclib::caba::VciVdspinTargetWrapper',
+	tmpl_parameters = [
+		parameter.Module('vci_param',  default = 'caba:vci_param'),
+		parameter.Int('dspin_cmd_width'),
+		parameter.Int('dspin_rsp_width'), ],
+        header_files = ['../source/include/vci_vdspin_target_wrapper.h', ],
+        implementation_files = ['../source/src/vci_vdspin_target_wrapper.cpp',],
+        ports = [
+		Port('caba:vci_initiator', 'p_vci'),
+                Port('caba:dspin_output', 'p_dspin_out', dspin_data_size = parameter.Reference('dspin_rsp_width')),
+                Port('caba:dspin_input', 'p_dspin_in', dspin_data_size = parameter.Reference('dspin_cmd_width')),
+		Port('caba:bit_in', 'p_resetn', auto = 'resetn'),
+		Port('caba:clock_in', 'p_clk', auto = 'clock'), ],
+	uses = [
+		Uses('caba:base_module'),
+		Uses('caba:generic_fifo'),
+		],
+	instance_parameters = [
+		parameter.Int('cmd_fifo_depth'),
+		parameter.Int('rsp_fifo_depth'), ],
+)
Index: trunk/platforms/almos-tsarv3-platforms/common/vci_vdspin_target_wrapper/caba/source/include/vci_vdspin_target_wrapper.h
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/vci_vdspin_target_wrapper/caba/source/include/vci_vdspin_target_wrapper.h	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/vci_vdspin_target_wrapper/caba/source/include/vci_vdspin_target_wrapper.h	(revision 259)
@@ -0,0 +1,129 @@
+/* -*- c++ -*-
+  * File : vci_vdspin_target_wrapper.h
+  * Copyright (c) UPMC, Lip6
+  * Author : Alain Greiner
+  *
+  * SOCLIB_LGPL_HEADER_BEGIN
+  * 
+  * This file is part of SoCLib, GNU LGPLv2.1.
+  * 
+  * SoCLib is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU Lesser General Public License as published
+  * by the Free Software Foundation; version 2.1 of the License.
+  * 
+  * SoCLib is distributed in the hope that it will be useful, but
+  * WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  * 
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with SoCLib; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+  * 02110-1301 USA
+  * 
+  * SOCLIB_LGPL_HEADER_END
+  */
+
+/////////////////////////////////////////////////////////////////////////
+// This component performs the protocol translation between VCI & DSPIN,
+// and can be used to connect a VCI target to a DSPIN netnork.
+// It is implemented as two fully independant sub-components:
+// - translation from a DSPIN CMD to a VCI CMD
+// - translation from a VCI RSP to a DSPIN RSP
+// Each subcomponent contains a FIFO containing DSPIN flits.
+// For the DSPIN interfaces, the widths of the CMD & RSP flits
+// are defined as template parameters for future evolutions,
+// but the VCI to DSPIN translation makes the following assumptions:
+// - DSPIN CMD flit width == 40 bits
+// - DSPIN RSP flit width == 33 bits
+// - VCI address width    <= 40 bits
+// - VCI data             == 32 bits
+// - VCI plen		  == 8  bits
+// - VCI srcid		  <= 14 bits
+// - VCI trdid		  <= 8  bits
+// - VCI pktid field not transmitted
+// - VCI rerror		  == 2 bits
+////////////////////////////////////////////////////////////////////////
+
+#ifndef VCI_VDSPIN_TARGET_WRAPPER_H_
+#define VCI_VDSPIN_TARGET_WRAPPER_H_
+
+#include <systemc>
+#include <assert.h>
+#include "caba_base_module.h"
+#include "vci_initiator.h"
+#include "generic_fifo.h"
+#include "dspin_interface.h"
+
+namespace soclib { namespace caba {
+
+
+template<typename vci_param, int dspin_cmd_width, int dspin_rsp_width>
+class VciVdspinTargetWrapper
+	: public soclib::caba::BaseModule
+{
+
+    // Command FSM 
+    enum fsm_state_cmd{
+    CMD_IDLE,
+    CMD_BROADCAST,
+    CMD_RW,
+    CMD_READ,
+    CMD_WDATA,
+    };
+
+    // Response FSM
+    enum fsm_state_rsp{
+    RSP_IDLE,
+    RSP_READ,
+    RSP_WRITE,
+    };
+
+protected:
+    SC_HAS_PROCESS(VciVdspinTargetWrapper);
+
+public:
+    // ports
+    sc_core::sc_in<bool>                             		p_clk;
+    sc_core::sc_in<bool>                             		p_resetn;
+    soclib::caba::DspinOutput<dspin_rsp_width>			p_dspin_out;
+    soclib::caba::DspinInput<dspin_cmd_width>			p_dspin_in;
+    soclib::caba::VciInitiator<vci_param>      			p_vci;
+
+    // constructor / destructor
+    VciVdspinTargetWrapper(	sc_module_name 			name, 
+				size_t				cmd_fifo_depth,
+				size_t				rsp_fifo_depth);
+private:
+    // internal registers
+    sc_core::sc_signal<int>        				r_cmd_fsm;
+    sc_core::sc_signal<sc_uint<dspin_cmd_width>	>		r_cmd_buf0;
+    sc_core::sc_signal<sc_uint<dspin_cmd_width>	>		r_cmd_buf1;
+    sc_core::sc_signal<int>        				r_rsp_fsm;
+    sc_core::sc_signal<size_t>					r_flit_count;
+
+    // fifos cmd and rsp
+    soclib::caba::GenericFifo<sc_uint<dspin_cmd_width> >  	r_fifo_cmd;
+    soclib::caba::GenericFifo<sc_uint<dspin_rsp_width> >  	r_fifo_rsp;
+
+    // methods systemc
+    void transition();
+    void genMoore();
+
+public:
+    void print_trace();
+
+};
+
+}} // end namespace
+               
+#endif // VCI_VDSPIN_TARGET_WRAPPER_H_
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Index: trunk/platforms/almos-tsarv3-platforms/common/vci_vdspin_target_wrapper/caba/source/src/vci_vdspin_target_wrapper.cpp
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/common/vci_vdspin_target_wrapper/caba/source/src/vci_vdspin_target_wrapper.cpp	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/common/vci_vdspin_target_wrapper/caba/source/src/vci_vdspin_target_wrapper.cpp	(revision 259)
@@ -0,0 +1,361 @@
+/* -*- c++ -*-
+  * File : vci_vdspin_target_wrapper.cpp
+  * Copyright (c) UPMC, Lip6
+  * Author : Alain Greiner
+  *
+  * SOCLIB_LGPL_HEADER_BEGIN
+  * 
+  * This file is part of SoCLib, GNU LGPLv2.1.
+  * 
+  * SoCLib is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU Lesser General Public License as published
+  * by the Free Software Foundation; version 2.1 of the License.
+  * 
+  * SoCLib is distributed in the hope that it will be useful, but
+  * WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  * 
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with SoCLib; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+  * 02110-1301 USA
+  * 
+  * SOCLIB_LGPL_HEADER_END
+  */
+
+#include "../include/vci_vdspin_target_wrapper.h"
+
+namespace soclib { namespace caba {
+
+#define tmpl(x) template<typename vci_param, int dspin_cmd_width, int dspin_rsp_width> x VciVdspinTargetWrapper<vci_param, dspin_cmd_width, dspin_rsp_width>
+
+//////////////////////////////////////////////////////////:////////////////////////////////
+tmpl(/**/)::VciVdspinTargetWrapper(sc_module_name 			name,
+			     	   size_t				cmd_fifo_depth,
+				   size_t				rsp_fifo_depth)
+	       : soclib::caba::BaseModule(name),
+                 p_clk("p_clk"),
+                 p_resetn("p_resetn"),
+                 p_dspin_out("p_dspin_out"),
+                 p_dspin_in("p_dspin_in"),
+                 p_vci("p_vci"),
+                 r_cmd_fsm("r_cmd_fsm"),
+                 r_rsp_fsm("r_rsp_fsm"),
+	         r_fifo_cmd("r_fifo_cmd", cmd_fifo_depth),
+	         r_fifo_rsp("r_fifo_rsp", rsp_fifo_depth)
+    {
+	SC_METHOD (transition);
+	dont_initialize();
+	sensitive << p_clk.pos();
+	SC_METHOD (genMoore);
+	dont_initialize();
+	sensitive  << p_clk.neg();
+
+        assert( (dspin_cmd_width == 40) && "The DSPIN CMD flit width must have 40 bits");
+        assert( (dspin_rsp_width == 33) && "The DSPIN RSP flit width must have 33 bits");
+        assert( (vci_param::N    <= 40) && "The VCI ADDRESS field cannot have more than 40 bits"); 
+        assert( (vci_param::B    == 4) && "The VCI DATA filds must have 32 bits");
+        assert( (vci_param::K    == 8) && "The VCI PLEN field cannot have more than 8 bits");
+        assert( (vci_param::S    <= 14) && "The VCI SRCID field cannot have more than 8 bits");
+        assert( (vci_param::T    <= 8) && "The VCI TRDID field cannot have more than 8 bits");
+        //assert( (vci_param::E    == 2) && "The VCI RERROR field cannot have more than 2 bits");
+
+    } //  end constructor
+
+/////////////////////////
+tmpl(void)::transition()
+{
+	sc_uint<dspin_cmd_width>	cmd_fifo_data;
+	bool				cmd_fifo_write;
+	bool				cmd_fifo_read;
+
+	sc_uint<dspin_rsp_width>	rsp_fifo_data;
+	bool				rsp_fifo_write;
+	bool				rsp_fifo_read;
+
+	if (p_resetn == false) 
+        {
+	    r_fifo_cmd.init();
+	    r_fifo_rsp.init();
+	    r_cmd_fsm = CMD_IDLE;
+	    r_rsp_fsm = RSP_IDLE;
+	    return;
+	} // end reset
+
+        /////////////////////////////////////////////////////////////
+	// VCI response packet to DSPIN response packet.
+	// The VCI packet is analysed, translated,
+	// and the DSPIN packet is stored in the fifo_rsp
+        /////////////////////////////////////////////////////////////
+        // - A single flit VCI write response packet is translated
+        //   to a single flit DSPIN response.
+        // - A N flits VCI read response packet is translated 
+        //   to a N+1 flits DSPIN response
+        // In the RSP_IDLE state, the first DSPIN flit is written 
+        // in fifo_rsp , but no VCI flit is consumed. The VCI flits 
+        // are consumed in the RSP_READ or RSP_WRITE states.
+        //////////////////////////////////////////////////////////////
+
+	// rsp_fifo_read
+	rsp_fifo_read = p_dspin_out.read.read();
+
+	// r_rsp_fsm, rsp_fifo_write and rsp_fifo_data
+        rsp_fifo_write = false;		// default value
+
+	switch(r_rsp_fsm) {
+	    case RSP_IDLE:		// write first DSPIN flit into rsp_fifo
+            {
+		if( p_vci.rspval && r_fifo_rsp.wok() ) 
+                {
+                    bool is_read = ( (p_vci.rerror.read() & 0x2) == 0);
+
+		    rsp_fifo_write = true;
+                    rsp_fifo_data = (((sc_uint<dspin_rsp_width>)p_vci.rsrcid.read()) << 18) |
+                                    (((sc_uint<dspin_rsp_width>)p_vci.rerror.read()) << 16) |
+                                    (((sc_uint<dspin_rsp_width>)p_vci.rtrdid.read()) << 8);
+                    if ( is_read ) 
+                    {
+                        r_rsp_fsm = RSP_READ;
+                    }
+                    else
+                    {
+                        rsp_fifo_data = rsp_fifo_data | 0x100000000ULL;
+                        r_rsp_fsm = RSP_WRITE;
+                    }
+		}
+	 	break;
+            }
+	    case RSP_READ:		// write DSPIN data flit in case of read
+            {    
+                if( p_vci.rspval && r_fifo_rsp.wok() )
+                {
+                    rsp_fifo_write   = true;
+                    rsp_fifo_data = ((sc_uint<dspin_rsp_width>)p_vci.rdata.read());
+                    if ( p_vci.reop ) 
+                    {
+                        rsp_fifo_data = rsp_fifo_data | 0x100000000ULL;
+                        r_rsp_fsm = RSP_IDLE;
+                    }
+                }
+                break;
+            }
+            case RSP_WRITE:
+            {
+                rsp_fifo_write = false;
+                if ( r_fifo_rsp.wok() ) r_rsp_fsm = RSP_IDLE;
+                break;
+            }
+	} // end switch r_cmd_fsm
+	
+	// fifo_rsp
+	if((rsp_fifo_write == true)  && (rsp_fifo_read == false)) { r_fifo_rsp.simple_put(rsp_fifo_data); } 
+	if((rsp_fifo_write == true)  && (rsp_fifo_read == true))  { r_fifo_rsp.put_and_get(rsp_fifo_data); } 
+	if((rsp_fifo_write == false) && (rsp_fifo_read == true))  { r_fifo_rsp.simple_get(); }
+
+        //////////////////////////////////////////////////////////////
+	// DSPIN command packet to VCI command packet
+	// The DSPIN packet is stored in the fifo_rsp
+	// The FIFO output is analysed and translated to a VCI packet
+        //////////////////////////////////////////////////////////////
+        // - A 2 flits DSPIN broadcast command is translated
+        //   to a 1 flit VCI broadcast command.
+        // - A 2 flits DSPIN read command is translated
+        //   to a 1 flit VCI read command.
+        // - A N+2 flits DSPIN write command is translated
+        //   to a N flits VCI write command. 
+        // The VCI flits are sent in the CMD_READ, CMD_WDATA 
+        // & CMD_BROADCAST states. 
+        // The r_cmd_buf0 et r_cmd_buf1 buffers are used to store
+        // the two first DSPIN flits (in case of write).
+        //////////////////////////////////////////////////////////////
+
+	// cmd_fifo_write, cmd_fifo_data
+	cmd_fifo_write = p_dspin_in.write.read();
+	cmd_fifo_data  = p_dspin_in.data.read();
+
+	// r_cmd_fsm, cmd_fifo_read
+        cmd_fifo_read = false; 		// default value
+
+	switch(r_cmd_fsm) {
+	    case CMD_IDLE:
+            {
+		if( r_fifo_cmd.rok() )
+                {
+                    bool is_broadcast = ( (r_fifo_cmd.read() & 0x1) == 0x1);
+
+		    cmd_fifo_read = true;
+                    r_cmd_buf0    = r_fifo_cmd.read(); 		// save address
+                    if ( is_broadcast ) r_cmd_fsm = CMD_BROADCAST;
+                    else		r_cmd_fsm = CMD_RW;
+		}
+		break;
+            }
+	    case CMD_BROADCAST:
+	    {
+		if( r_fifo_cmd.rok() && p_vci.cmdack )
+                {
+                    cmd_fifo_read = true;
+                    r_cmd_fsm = CMD_IDLE;
+                }
+                break;
+            }
+            case CMD_RW:
+            {
+		if( r_fifo_cmd.rok() )
+                {
+		    cmd_fifo_read = true;
+                    r_cmd_buf1 = r_fifo_cmd.read();		// save command parameters
+                    // read command if EOP
+                    if ( (r_fifo_cmd.read() & 0x8000000000ULL) )   r_cmd_fsm = CMD_READ;
+                    else					r_cmd_fsm = CMD_WDATA;
+                    r_flit_count = 0;
+		}
+		break;
+            }
+            case CMD_READ:
+            {
+                if ( p_vci.cmdack.read() ) r_cmd_fsm = CMD_IDLE;
+                break;
+            }
+            case CMD_WDATA:
+            {
+		if( r_fifo_cmd.rok() && p_vci.cmdack.read() )
+                {
+                    if ( (r_cmd_buf1.read() & 0x0000200000) == 0 ) r_flit_count = r_flit_count + 1;
+		               cmd_fifo_read = true;
+                    if ( (r_fifo_cmd.read() & 0x8000000000ULL) ) 	r_cmd_fsm = CMD_IDLE;
+		}
+                break;
+            }
+	} // end switch r_cmd_fsm
+
+	// fifo_cmd
+	if((cmd_fifo_write == true)  && (cmd_fifo_read == false)) { r_fifo_cmd.simple_put(cmd_fifo_data); } 
+	if((cmd_fifo_write == true)  && (cmd_fifo_read == true))  { r_fifo_cmd.put_and_get(cmd_fifo_data); } 
+	if((cmd_fifo_write == false) && (cmd_fifo_read == true))  { r_fifo_cmd.simple_get(); }
+
+}; // end transition
+
+//////////////////////
+tmpl(void)::genMoore()
+{
+	// VCI RSP interface
+        if ( r_rsp_fsm.read() == RSP_IDLE )	p_vci.rspack = false;
+	else                                   	p_vci.rspack = r_fifo_rsp.wok();
+
+	// VCI CMD interface
+	if ( (r_cmd_fsm.read() == CMD_IDLE) || (r_cmd_fsm.read() == CMD_RW) )
+        {
+            p_vci.cmdval = false;
+        }
+        else if ( r_cmd_fsm.read() == CMD_BROADCAST )	// VCI CMD broadcast
+        {
+            if ( r_fifo_cmd.rok() )
+            {
+                sc_uint<dspin_cmd_width>  minmax = r_cmd_buf0.read() & 0x7FFFF80000ULL;
+                if ( vci_param::N == 40 ) minmax = (minmax << 1);
+                else			  minmax = (minmax >> (39 - vci_param::N) ); 
+                p_vci.cmdval  = true;
+	        p_vci.address = (sc_uint<vci_param::N>)minmax | 0x3;
+                p_vci.cmd     = vci_param::CMD_WRITE;
+                p_vci.wdata   = (sc_uint<8*vci_param::B>)(r_fifo_cmd.read() & 0x00FFFFFFFFUL);
+                p_vci.be      = (sc_uint<vci_param::B>)((r_fifo_cmd.read() & 0x0F00000000ULL) >> 32);
+                p_vci.srcid   = (sc_uint<vci_param::S>)((r_cmd_buf0.read() & 0x000007FFE0) >> 5);
+                p_vci.trdid   = (sc_uint<vci_param::T>)((r_cmd_buf0.read() & 0x000000001E) >> 1);
+		p_vci.pktid   = 0;
+                p_vci.plen    = vci_param::B;
+                p_vci.contig  = true;
+                p_vci.cons    = false;
+                p_vci.eop     = true;
+            }
+            else
+            {
+            	p_vci.cmdval = false;
+            }
+        }
+        else if ( r_cmd_fsm.read() == CMD_READ )	// VCI CMD read
+        {            
+            sc_uint<vci_param::N> address;
+            if ( vci_param::N == 40 ) address = (r_cmd_buf0.read() << 1);
+            else                      address = (r_cmd_buf0.read() >> (39 - vci_param::N) ); 
+            p_vci.cmdval  = true;
+	    p_vci.address = address;
+            p_vci.cmd     = (sc_uint<2>)((r_cmd_buf1.read()            & 0x0001800000) >> 23);
+	    p_vci.wdata   = 0;
+            p_vci.be      = (sc_uint<vci_param::B>)((r_cmd_buf1.read() & 0x000000001E) >> 1);
+            p_vci.srcid   = (sc_uint<vci_param::S>)((r_cmd_buf1.read() & 0x7FFE000000ULL) >> 25);
+            p_vci.trdid   = (sc_uint<vci_param::T>)((r_cmd_buf1.read() & 0x0000001FE0) >> 5);
+	    p_vci.pktid   = 0;
+            p_vci.plen    = (sc_uint<vci_param::K>)((r_cmd_buf1.read() & 0x00001FE000) >> 13);
+            p_vci.contig  = ((r_cmd_buf1.read() & 0x0000400000) != 0);
+            p_vci.cons    = ((r_cmd_buf1.read() & 0x0000200000) != 0);
+            p_vci.eop     = true;
+	}
+        else if ( r_cmd_fsm.read() == CMD_WDATA )	// VCI write command
+        {
+            if ( r_fifo_cmd.rok() )  
+            {
+                sc_uint<vci_param::N> address;
+                if ( vci_param::N == 40 ) address = (r_cmd_buf0.read() << 1);
+                else                      address = (r_cmd_buf0.read() >> (39 - vci_param::N) ); 
+                p_vci.cmdval  = true;
+	        p_vci.address = address + (r_flit_count.read()*vci_param::B);
+                p_vci.cmd     = (sc_uint<2>)((r_cmd_buf1.read()              & 0x0001800000) >> 23);
+		p_vci.wdata   = (sc_uint<8*vci_param::B>)(r_fifo_cmd.read()  & 0x00FFFFFFFFUL);
+		p_vci.be      = (sc_uint<vci_param::B>)((r_fifo_cmd.read()   & 0x0F00000000ULL) >> 32);
+                p_vci.srcid   = (sc_uint<vci_param::S>)((r_cmd_buf1.read()   & 0x7FFE000000ULL) >> 25);
+                p_vci.trdid   = (sc_uint<vci_param::T>)((r_cmd_buf1.read()   & 0x0000001FE0) >> 5);
+		p_vci.pktid   = 0;
+                p_vci.plen    = (sc_uint<vci_param::K>)((r_cmd_buf1.read() & 0x00001FE000) >> 13);
+                p_vci.contig  = ((r_cmd_buf1.read() & 0x0000400000) != 0);
+                p_vci.cons    = ((r_cmd_buf1.read() & 0x0000200000) != 0);
+		p_vci.eop     = ((r_fifo_cmd.read() & 0x8000000000ULL) == 0x8000000000ULL); 
+            }
+            else
+            {
+            	p_vci.cmdval = false;
+            }
+        }
+
+	// DSPIN_OUT interface
+	p_dspin_out.write = r_fifo_rsp.rok();
+	p_dspin_out.data  = r_fifo_rsp.read();
+
+	// DSPIN_IN interface
+	p_dspin_in.read = r_fifo_cmd.wok();
+
+}; // end genMoore
+
+/////////////////////////
+tmpl(void)::print_trace()
+{
+    const char* cmd_str[] = {
+    "CMD_IDLE     ",
+    "CMD_BROADCAST",
+    "CMD_RW       ",
+    "CMD_READ     ",
+    "CMD_WDATA    ",
+    };
+    const char* rsp_str[] = {
+    "RSP_IDLE     ",
+    "RSP_READ     ",
+    "RSP_WRITE    ",
+    };
+    std::cout << name() << " : " << cmd_str[r_cmd_fsm.read()]
+                        << " | " << rsp_str[r_rsp_fsm.read()] 
+                        << " | fifo_cmd = " << r_fifo_cmd.filled_status()
+                        << " | fifo_rsp = " << r_fifo_rsp.filled_status()
+			<< std::endl;
+}
+
+}} // end namespace
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Index: trunk/platforms/almos-tsarv3-platforms/mono-cluster/Makefile
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/mono-cluster/Makefile	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/mono-cluster/Makefile	(revision 259)
@@ -0,0 +1,6 @@
+ARCH=mips32el
+SOCLIB?=$(shell soclib-cc --getpath)
+NO_SOFT=1
+export SOCLIB
+SOCLIB_CC_ADD_ARGS='-v -I. -I../common'
+include $(SOCLIB)/soclib/platform/topcells/all.mk
Index: trunk/platforms/almos-tsarv3-platforms/mono-cluster/config.h
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/mono-cluster/config.h	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/mono-cluster/config.h	(revision 259)
@@ -0,0 +1,2 @@
+#define CONFIG_MEMC_TRANSACTION_TAB_LINES 8
+#define CONFIG_MEMC_UPDATE_TAB_LINES      8
Index: trunk/platforms/almos-tsarv3-platforms/mono-cluster/config/config.h
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/mono-cluster/config/config.h	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/mono-cluster/config/config.h	(revision 259)
@@ -0,0 +1,3 @@
+namespace config {
+  #include "../config.h"
+}
Index: trunk/platforms/almos-tsarv3-platforms/mono-cluster/config/config.sd
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/mono-cluster/config/config.sd	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/mono-cluster/config/config.sd	(revision 259)
@@ -0,0 +1,13 @@
+
+# -*- python -*-
+
+__id__ = "$Id: todo $"
+__version__ = "$vision: 0 $"
+
+Module('config:config',
+	header_files = [
+		'../config.h',
+		]
+)
+
+
Index: trunk/platforms/almos-tsarv3-platforms/mono-cluster/platform_desc
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/mono-cluster/platform_desc	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/mono-cluster/platform_desc	(revision 259)
@@ -0,0 +1,37 @@
+
+# -*- python -*-
+
+
+todo = Platform('caba', 'top.cpp',
+                uses = [
+	Uses('caba:vci_cc_vcache_wrapper2_v1', iss_t = 'common:mips32el'),
+	Uses('caba:vci_simple_ram'),
+	Uses('caba:vci_multi_tty'),
+        Uses('caba:vci_xicu'),
+        Uses('caba:vci_dma_tsar_v2'),
+	Uses('caba:vci_block_device_tsar_v2'),
+        Uses('caba:vci_framebuffer'),
+	Uses('caba:vci_vgmn'),
+        Uses('caba:vci_profiler', iss_t = 'common:mips32el'),
+#        Uses('caba:vci_simple_ring_fast',
+#             ring_cmd_data_size = 40,
+#             ring_rsp_data_size =33),
+        Uses('caba:vci_logger'),
+#        Uses('caba:vci_mem_cache_v4'),
+	Uses('caba:vci_mem_cache_v3'),
+#        Uses('caba:vci_mem_cache_v2'),
+	Uses('common:elf_file_loader'),
+	Uses('common:plain_file_loader'),
+	],
+	cell_size = 4,
+	plen_size = 8,
+	addr_size = 32,
+	rerror_size = 1,
+	clen_size = 1,
+	rflag_size = 1,
+	srcid_size = 8,
+	pktid_size = 4,
+	trdid_size = 4,
+	wrplen_size = 1
+)
+
Index: trunk/platforms/almos-tsarv3-platforms/mono-cluster/segmentation.h
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/mono-cluster/segmentation.h	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/mono-cluster/segmentation.h	(revision 259)
@@ -0,0 +1,59 @@
+/////////////////////////////////////////
+//   Devices mapped segments 
+/////////////////////////////////////////
+#define     XICU_BASE   0x11800000
+#define     XICU_SIZE   0x00001000
+
+#define	    DMA_BASE	0x32200000
+#define	    DMA_SIZE	0x00000014
+
+#define     TTY_BASE    0x12200000
+#define     TTY_SIZE    0x00000040
+
+#define     BD_BASE     0x15200000
+#define     BD_SIZE     0x20
+
+#define FB_XSIZE 512
+#define FB_YSIZE 512
+#define	FB_BASE	0x13200000
+#define FB_SIZE 0x200000
+////////////////////////////////////////
+
+//////////////////////////////////////////
+//       ROM mapped segments
+//////////////////////////////////////////
+#define ROM_BASE        0xbfc00000
+#define BOOT_BASE       ROM_BASE
+#define BOOT_SIZE       0x00008000
+#define BOOT_INFO_BLOCK 0xbfc08000
+#define KERNEL_BIN_IMG  0xbfc10000
+#define ROM_SIZE        0x00100000
+//////////////////////////////////////////
+
+//////////////////////////////////////////
+//                RAM
+//////////////////////////////////////////
+#define     RAM_BASE    0x00000000
+#define     RAM_SIZE    0x08000000
+//////////////////////////////////////////
+
+
+////////////////////////////////////////
+
+////////////////////////////////////////
+//	Reserved segments
+////////////////////////////////////////
+
+#define PROC0_BASE	0x08200000
+#define PROC0_SIZE	0x00000010
+
+#define PROC1_BASE	0x09200000
+#define PROC1_SIZE	0x00000010
+
+#define PROC2_BASE	0x0a200000
+#define PROC2_SIZE	0x00000010
+
+#define PROC3_BASE	0x0b200000
+#define PROC3_SIZE	0x00000010
+
+////////////////////////////////////////
Index: trunk/platforms/almos-tsarv3-platforms/mono-cluster/top.cpp
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/mono-cluster/top.cpp	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/mono-cluster/top.cpp	(revision 259)
@@ -0,0 +1,684 @@
+#define yes 1
+#define no  0
+
+#define USE_RING       no
+#define USE_TSAR_V3    yes
+#define SECTOR_SIZE    4096
+
+#define L1_WAYS        4
+#define L1_SETS        64
+
+#define MEMC_WAYS      16
+#define MEMC_SETS      256
+
+#define MEMC_HEAP      1024 //4096
+
+#define XRAM_LATENCY   0
+
+#define USE_VCI_LOGGER_ON_L1_CPU0  no
+#define USE_VCI_LOGGER_ON_L1_CPU1  no
+#define USE_VCI_LOGGER_ON_L1_CPU2  no
+#define USE_VCI_LOGGER_ON_L1_CPU3  no
+
+#define USE_VCI_LOGGER_ON_ROM      no
+
+#define USE_VCI_PROFILER_ON_CPU0   yes
+#define USE_VCI_PROFILER_ON_CPU1   yes
+#define USE_VCI_PROFILER_ON_CPU2   yes
+#define USE_VCI_PROFILER_ON_CPU3   yes
+
+#define USE_VCI_PROFILER (USE_VCI_PROFILER_ON_CPU0 || USE_VCI_PROFILER_ON_CPU1 || USE_VCI_PROFILER_ON_CPU2 || USE_VCI_PROFILER_ON_CPU3)
+
+#include <systemc>
+#include <sys/time.h>
+#include <iostream>
+#include <cstdlib>
+#include <cstdarg>
+#include <unistd.h>
+#include <getopt.h>
+
+#include "mapping_table.h"
+#include "mips32.h"
+#include "vci_simple_ram.h"
+#include "vci_multi_tty.h"
+
+#if USE_RING
+#include "vci_simple_ring_fast.h"
+#else
+#include "vci_vgmn.h"
+#endif
+
+#if USE_VCI_PROFILER
+#include "vci_profiler.h"
+#endif
+
+
+#if USE_TSAR_V3
+#include "vci_mem_cache_v3.h"
+#else
+#include "vci_mem_cache_v2.h"
+#endif
+
+#include "vci_cc_vcache_wrapper2_v1.h"
+#include "vci_logger.h"
+#include "vci_xicu.h"
+#include "vci_framebuffer.h"
+#include "vci_dma_tsar_v2.h"
+#include "vci_block_device_tsar_v2.h"
+
+#ifdef USE_GDB_SERVER
+#include "iss/gdbserver.h"
+#endif
+
+//#define  VCI_LOGGER_ON_L1
+//#define  VCI_LOGGER_ON_ROM
+//#define VCI_LOGGER_ON_L1_TGT
+
+#define _TO_STR(x) #x
+#define TO_STR(x) _TO_STR(x)
+
+#include "segmentation.h"
+
+#if  !(defined(KERNEL_BIN_IMG) || defined(BOOT_INFO_BLOCK))
+#error KERNEL_BIN_IMG or BOOT_INFO_BLOCK macros definition are missed
+#endif 
+
+#include <config.h>
+
+
+static const struct option opts[] = {{"XFB",    required_argument, NULL, 'x'},
+				     {"YFB",    required_argument, NULL, 'y'},
+				     {"FBMODE", required_argument, NULL, 'm'},
+				     {"SSTEP",  required_argument, NULL, 's'},
+				     {"LOGMC0", required_argument, NULL, 'l'},
+				     {"BLKSZ",  required_argument, NULL, 'b'},
+				     {"HELP",   no_argument,       NULL, 'h'},
+				     {NULL,     no_argument,       NULL,  0}};
+
+int _main(int argc, char *argv[])
+{
+	uint64_t       ms1, ms2;
+	struct timeval t1, t2;
+	uint64_t     sstep    = 10000000000ULL;
+	uint64_t     ncycles  = 10000000000ULL;
+	size_t       xfb      = FB_XSIZE;
+	size_t       yfb      = FB_YSIZE;
+	size_t       fb_mode  = 420;
+	size_t       blksz    = SECTOR_SIZE;
+	int          longIndex;
+	int          c;
+	bool         do_loggerMc0 = false;
+
+	using namespace sc_core;
+	// Avoid repeating these everywhere
+	using soclib::common::IntTab;
+	using soclib::common::Segment;
+
+	// Define VCI parameters
+	typedef soclib::caba::VciParams<4,8,32,1,1,1,8,4,4,1> vci_param;
+	typedef soclib::common::Mips32ElIss proc_iss;
+	// Mapping table
+
+	while ((c = getopt_long(argc, argv, "x:y:s:m:l:b:h", opts, &longIndex)) != -1) 
+	{
+	  switch(c) 
+	  {
+	  case 'x':
+	    xfb = atoi(optarg);
+	    break;
+
+	  case 'y':
+	    yfb = atoi(optarg); 
+	    break;
+
+	  case 'm':
+	    fb_mode = atoi(optarg);
+	    break;
+
+	  case 's':
+	    sstep = atoll(optarg);
+	    break;
+
+	  case 'l':
+	    if(strcmp(optarg, "ON") == 0)
+	      do_loggerMc0 = true;
+	    break;
+
+	  case 'b':
+	    blksz = atoi(optarg);
+	    break;
+      
+	  case 'h':
+	    std::cout << "Usage: "<< argv[0] << " <options>" << std::endl << std::endl;
+	    std::cout << "Options:" << std::endl;
+	    std::cout << "  --XFB     : FrameBuffer XSIZE" << std::endl;
+	    std::cout << "  --YFB     : FrameBuffer YSIZE" << std::endl;
+	    std::cout << "  --FBMODE  : FrameBuffer MODE {YUV:420, YUV:422, RGB:0, RGB:16, RGB:32, RGBPAL:256}" << std::endl;
+	    std::cout << "  --SSTEP   : Statistics period" << std::endl;
+	    std::cout << "  --LOGMC0  : {ON|OFF} Trace the charge of directe network input of MemCache0" << std::endl;
+	    std::cout << "  --BLKSZ   : Sector Size (in bytes)" << std::endl;
+	    std::cout << "  --HELP    : Print out command line options" << std::endl << std::endl;
+	    std::cout << "Default: "  << argv[0] 
+		      << " --XFB "    << xfb 
+		      << " --YFB "    << yfb 
+		      << " --FBMODE " << fb_mode
+		      << " --SSTEP "  << sstep 
+		      << " --LOGMC0 " << "OFF"
+		      << " --BLKSZ "  << blksz
+		      << std::endl;
+	    exit(0);
+	    break;
+	  }
+	}
+
+	std::cout << "CONFIG_MEMC_UPDATE_TAB_LINES = " << CONFIG_MEMC_UPDATE_TAB_LINES << std::endl;
+
+	soclib::common::MappingTable maptabp(32, IntTab(8), IntTab(8), 0xF0000000);
+	
+	maptabp.add(Segment("mc_m" , RAM_BASE , RAM_SIZE , IntTab(0), true));
+	maptabp.add(Segment("rom", ROM_BASE, ROM_SIZE, IntTab(1), true));
+
+	maptabp.add(Segment("bd", BD_BASE, BD_SIZE, IntTab(2), false));
+	maptabp.add(Segment("tty"  , TTY_BASE  , TTY_SIZE  , IntTab(3), false));
+	maptabp.add(Segment("xicu" , XICU_BASE , XICU_SIZE , IntTab(4), false));
+	maptabp.add(Segment("dma", DMA_BASE, DMA_SIZE, IntTab(5), false));
+	maptabp.add(Segment("fb", FB_BASE, FB_SIZE, IntTab(6), false));
+
+	std::cout << maptabp << std::endl;
+
+        soclib::common::MappingTable maptabc(32, IntTab(8), IntTab(8), 0xF0000000);
+	maptabc.add(Segment("c_proc0" , PROC0_BASE , PROC0_SIZE , IntTab(0), false, true, IntTab(0)));
+	maptabc.add(Segment("c_proc1" , PROC1_BASE , PROC1_SIZE , IntTab(1), false, true, IntTab(1)));
+	maptabc.add(Segment("c_proc2" , PROC2_BASE , PROC2_SIZE , IntTab(2), false, true, IntTab(2)));
+	maptabc.add(Segment("c_proc3" , PROC3_BASE , PROC3_SIZE , IntTab(3), false, true, IntTab(3)));
+	maptabc.add(Segment("mc_m" , RAM_BASE , RAM_SIZE , IntTab(4), false ));
+	
+	maptabc.add(Segment("rom", ROM_BASE, ROM_SIZE, IntTab(4), true));
+
+	std::cout << maptabc << std::endl;
+	
+	soclib::common::MappingTable maptabx(32, IntTab(8), IntTab(8), 0xF0000000);
+	maptabx.add(Segment("xram" , RAM_BASE , RAM_SIZE , IntTab(0), false));
+	
+	
+	std::cout << maptabx << std::endl;
+
+	//soclib::caba::VciLogger<vci_param> vci_logger0("vci_logger_mc0", maptabp, do_loggerMc0);
+	
+	// Signals
+
+	sc_clock	signal_clk("clk");
+	sc_signal<bool> signal_resetn("resetn");
+   
+	sc_signal<bool> signal_proc0_it0("mips0_it0"); 
+	sc_signal<bool> signal_proc0_it1("mips0_it1"); 
+	sc_signal<bool> signal_proc0_it2("mips0_it2"); 
+	sc_signal<bool> signal_proc0_it3("mips0_it3"); 
+	sc_signal<bool> signal_proc0_it4("mips0_it4"); 
+	sc_signal<bool> signal_proc0_it5("mips0_it5");
+
+	sc_signal<bool> signal_proc1_it0("mips1_it0"); 
+	sc_signal<bool> signal_proc1_it1("mips1_it1"); 
+	sc_signal<bool> signal_proc1_it2("mips1_it2"); 
+	sc_signal<bool> signal_proc1_it3("mips1_it3"); 
+	sc_signal<bool> signal_proc1_it4("mips1_it4"); 
+	sc_signal<bool> signal_proc1_it5("mips1_it5");
+
+	sc_signal<bool> signal_proc2_it0("mips2_it0"); 
+	sc_signal<bool> signal_proc2_it1("mips2_it1"); 
+	sc_signal<bool> signal_proc2_it2("mips2_it2"); 
+	sc_signal<bool> signal_proc2_it3("mips2_it3"); 
+	sc_signal<bool> signal_proc2_it4("mips2_it4"); 
+	sc_signal<bool> signal_proc2_it5("mips2_it5");
+
+	sc_signal<bool> signal_proc3_it0("mips3_it0"); 
+	sc_signal<bool> signal_proc3_it1("mips3_it1"); 
+	sc_signal<bool> signal_proc3_it2("mips3_it2"); 
+	sc_signal<bool> signal_proc3_it3("mips3_it3"); 
+	sc_signal<bool> signal_proc3_it4("mips3_it4"); 
+	sc_signal<bool> signal_proc3_it5("mips3_it5");
+
+	soclib::caba::VciSignals<vci_param> signal_vci_ini_rw_proc0("vci_ini_rw_proc0");
+	soclib::caba::VciSignals<vci_param> signal_vci_ini_c_proc0("vci_ini_c_proc0");
+	soclib::caba::VciSignals<vci_param> signal_vci_tgt_proc0("vci_tgt_proc0");
+
+	soclib::caba::VciSignals<vci_param> signal_vci_ini_rw_proc1("vci_ini_rw_proc1");
+	soclib::caba::VciSignals<vci_param> signal_vci_ini_c_proc1("vci_ini_c_proc1");
+	soclib::caba::VciSignals<vci_param> signal_vci_tgt_proc1("vci_tgt_proc1");
+
+	soclib::caba::VciSignals<vci_param> signal_vci_ini_rw_proc2("vci_ini_rw_proc2");
+	soclib::caba::VciSignals<vci_param> signal_vci_ini_c_proc2("vci_ini_c_proc2");
+	soclib::caba::VciSignals<vci_param> signal_vci_tgt_proc2("vci_tgt_proc2");
+
+	soclib::caba::VciSignals<vci_param> signal_vci_ini_rw_proc3("vci_ini_rw_proc3");
+	soclib::caba::VciSignals<vci_param> signal_vci_ini_c_proc3("vci_ini_c_proc3");
+	soclib::caba::VciSignals<vci_param> signal_vci_tgt_proc3("vci_tgt_proc3");
+
+	soclib::caba::VciSignals<vci_param> signal_vci_tty("signal_vci_tty");
+
+	
+	soclib::caba::VciSignals<vci_param> signal_vci_xicu("signal_vci_xicu");
+	soclib::caba::VciSignals<vci_param> signal_vci_dmai("signal_vci_dmai");
+	soclib::caba::VciSignals<vci_param> signal_vci_dmat("signal_vci_dmat");
+	soclib::caba::VciSignals<vci_param> signal_vci_vcifb("signal_vci_vcifb");
+	soclib::caba::VciSignals<vci_param> signal_vci_vcibd_i("signal_vci_vcibd_i");
+	soclib::caba::VciSignals<vci_param> signal_vci_vcibd_t("signal_vci_vcibd_t");
+	soclib::caba::VciSignals<vci_param> signal_vci_tgt_rom("vci_tgt_rom");
+
+	soclib::caba::VciSignals<vci_param> signal_vci_tgt_xram("vci_tgt_xram");
+
+	soclib::caba::VciSignals<vci_param> signal_vci_ixr_memc("vci_ixr_memc");
+	soclib::caba::VciSignals<vci_param> signal_vci_ini_memc("vci_ini_memc");
+	soclib::caba::VciSignals<vci_param> signal_vci_tgt_memc("vci_tgt_memc");
+	soclib::caba::VciSignals<vci_param> signal_vci_tgt_cleanup_memc("vci_tgt_cleanup_memc");
+
+	sc_signal<bool> signal_icu_irq0("signal_xicu_irq0");
+	sc_signal<bool> signal_icu_irq1("signal_xicu_irq1");
+	sc_signal<bool> signal_icu_irq2("signal_xicu_irq2");
+	sc_signal<bool> signal_icu_irq3("signal_xicu_irq3");
+	sc_signal<bool> signal_icu_irq4("signal_xicu_irq4");
+	sc_signal<bool> signal_icu_irq5("signal_xicu_irq5");
+	sc_signal<bool> signal_icu_irq6("signal_xicu_irq6");
+
+	
+	soclib::common::Loader loader("bootloader.bin",
+				      "kernel-soclib.bin@"TO_STR(KERNEL_BIN_IMG)":D",
+				      "arch-info.bin@"TO_STR(BOOT_INFO_BLOCK)":D");
+
+
+        //                                  init_rw   init_c   tgt
+	soclib::caba::VciCcVCacheWrapper2V1<vci_param, proc_iss > 
+	proc0("proc_0", 0, maptabp, maptabc, IntTab(0),IntTab(0),IntTab(0),
+	      4,16,4,16,
+	      L1_WAYS,L1_SETS,16,
+	      L1_WAYS,L1_SETS,16,
+	      16);
+
+	soclib::caba::VciCcVCacheWrapper2V1<vci_param, proc_iss > 
+	proc1("proc_1", 1, maptabp, maptabc, IntTab(1),IntTab(1),IntTab(1),
+	      4,16,4,16,
+	      L1_WAYS,L1_SETS,16,
+	      L1_WAYS,L1_SETS,16,
+	      16);
+
+	soclib::caba::VciCcVCacheWrapper2V1<vci_param, proc_iss > 
+	proc2("proc_2", 2, maptabp, maptabc, IntTab(2),IntTab(2),IntTab(2),
+	      4,16,4,16,
+	      L1_WAYS,L1_SETS,16,
+	      L1_WAYS,L1_SETS,16,
+	      16);
+
+	soclib::caba::VciCcVCacheWrapper2V1<vci_param, proc_iss > 
+	proc3("proc_3", 3, maptabp, maptabc, IntTab(3),IntTab(3),IntTab(3),
+	      4,16,4,16,
+	      L1_WAYS,L1_SETS,16,
+	      L1_WAYS,L1_SETS,16,
+	      16);
+
+	soclib::caba::VciSimpleRam<vci_param> 
+	rom("rom", IntTab(1), maptabp, loader);
+
+	soclib::caba::VciSimpleRam<vci_param> 
+	  xram("xram", IntTab(0), maptabx, loader, XRAM_LATENCY);
+
+        //                                  x_init    c_init    p_tgt     c_tgt
+	
+#if USE_TSAR_V3
+	soclib::caba::VciMemCacheV3<vci_param> 
+	  memc("memc",maptabp,maptabc,maptabx,IntTab(0),IntTab(4),IntTab(0), IntTab(4),MEMC_WAYS,MEMC_SETS,16,MEMC_HEAP);
+#else
+	soclib::caba::VciMemCacheV2<vci_param> 
+	memc("memc",maptabp,maptabc,maptabx,IntTab(0),IntTab(4),IntTab(0), IntTab(4),16,256,16);
+#endif
+	//memc("memc",maptabp,maptabc,maptabx,IntTab(0),IntTab(4),IntTab(2), IntTab(4),4,16,16,32);
+       
+	soclib::caba::VciXicu<vci_param> vcixicu("vcixicu", maptabp, IntTab(4), 4 /* npti */, 6 /* nhwi */, 4 /* nwti */, 4 /* nirq */);
+
+	soclib::caba::VciMultiTty<vci_param> vcitty("vcitty",	IntTab(3), maptabp, "tty0" ,"tty1", "tty2", "tty3", NULL);
+	soclib::caba::VciDmaTsarV2<vci_param> vcidma("vcidma", maptabp, IntTab(4), IntTab(5), 64);//(1<<(vci_param::K-1))); 
+
+	soclib::caba::VciBlockDeviceTsarV2<vci_param> vcibd("vcitbd", 
+							    maptabp, 
+							    IntTab(5), 
+							    IntTab(2), 
+							    "hdd-img.bin", 
+							    blksz);
+
+	soclib::caba::VciFrameBuffer<vci_param> vcifb("vcifb", IntTab(6), maptabp, xfb, yfb, fb_mode);
+	
+
+#if USE_VCI_LOGGER_ON_L1_CPU0
+  soclib::caba::VciLogger<vci_param> vci_logger0("vci_logger0",maptabp);
+#endif
+
+#if USE_VCI_LOGGER_ON_CPU1
+  soclib::caba::VciLogger<vci_param> vci_logger1("vci_logger1",maptabp);
+#endif
+
+#if USE_VCI_LOGGER_ON_CPU2
+  soclib::caba::VciLogger<vci_param> vci_logger2("vci_logger2",maptabp);
+#endif
+
+#if USE_VCI_LOGGER_ON_CPU3
+  soclib::caba::VciLogger<vci_param> vci_logger3("vci_logger3",maptabp);
+#endif
+
+#if USE_VCI_LOGGER_ON_ROM
+  soclib::caba::VciLogger<vci_param> vci_logger4("vci_logger4",maptabp);
+#endif
+
+
+#if USE_VCI_PROFILER_ON_CPU0
+  soclib::caba::VciProfiler<vci_param, proc_iss> vci_prof0("vci_prof0", 0, 0, 0, 1, 1, 32);
+#endif
+
+#if USE_VCI_PROFILER_ON_CPU1
+  soclib::caba::VciProfiler<vci_param, proc_iss> vci_prof1("vci_prof1", 0, 0, 0, 1, 1, 32);
+#endif
+
+#if USE_VCI_PROFILER_ON_CPU2
+  soclib::caba::VciProfiler<vci_param, proc_iss> vci_prof2("vci_prof2", 0, 0, 0, 1, 1, 32);
+#endif
+
+#if USE_VCI_PROFILER_ON_CPU3
+  soclib::caba::VciProfiler<vci_param, proc_iss> vci_prof3("vci_prof3", 0, 0, 0, 1, 1, 32);
+#endif
+
+#if USE_RING
+  std::cout << "Local Interconnect Type : RING" << std::endl;
+	//soclib::caba::VciVgmn<vci_param> 
+	soclib::caba::VciSimpleRingFast<vci_param, 40, 33> 
+	  ringp("ringp",maptabp, IntTab(), 4, 6, 7);//, /*3*/1, 8);
+	
+	//soclib::caba::VciVgmn<vci_param> 
+	soclib::caba::VciSimpleRingFast<vci_param, 40, 33> 
+	  ringc("ringc",maptabc, IntTab(), 4, 5, 5);//, /*2*/1, 8);
+
+#else
+	std::cout << "Local Interconnect Type : VGMN" << std::endl;
+	soclib::caba::VciVgmn<vci_param> 
+	  ringp("ringp",maptabp, 6, 7, 1, 8);
+	
+	soclib::caba::VciVgmn<vci_param> 
+	  ringc("ringc",maptabc, 5, 5, 1, 8);
+#endif
+
+	proc0.p_clk(signal_clk);  
+	proc0.p_resetn(signal_resetn);  
+	proc0.p_irq[0](signal_proc0_it0); 
+	proc0.p_irq[1](signal_proc0_it1); 
+	proc0.p_irq[2](signal_proc0_it2); 
+	proc0.p_irq[3](signal_proc0_it3); 
+	proc0.p_irq[4](signal_proc0_it4); 
+	proc0.p_irq[5](signal_proc0_it5); 
+	proc0.p_vci_ini_rw(signal_vci_ini_rw_proc0);
+	proc0.p_vci_ini_c(signal_vci_ini_c_proc0);
+	proc0.p_vci_tgt(signal_vci_tgt_proc0);
+
+	proc1.p_clk(signal_clk);  
+	proc1.p_resetn(signal_resetn);  
+	proc1.p_irq[0](signal_proc1_it0); 
+	proc1.p_irq[1](signal_proc1_it1); 
+	proc1.p_irq[2](signal_proc1_it2); 
+	proc1.p_irq[3](signal_proc1_it3); 
+	proc1.p_irq[4](signal_proc1_it4); 
+	proc1.p_irq[5](signal_proc1_it5); 
+	proc1.p_vci_ini_rw(signal_vci_ini_rw_proc1);
+	proc1.p_vci_ini_c(signal_vci_ini_c_proc1);
+	proc1.p_vci_tgt(signal_vci_tgt_proc1);
+
+	proc2.p_clk(signal_clk);  
+	proc2.p_resetn(signal_resetn);  
+	proc2.p_irq[0](signal_proc2_it0); 
+	proc2.p_irq[1](signal_proc2_it1); 
+	proc2.p_irq[2](signal_proc2_it2); 
+	proc2.p_irq[3](signal_proc2_it3); 
+	proc2.p_irq[4](signal_proc2_it4); 
+	proc2.p_irq[5](signal_proc2_it5); 
+	proc2.p_vci_ini_rw(signal_vci_ini_rw_proc2);
+	proc2.p_vci_ini_c(signal_vci_ini_c_proc2);
+	proc2.p_vci_tgt(signal_vci_tgt_proc2);
+
+	proc3.p_clk(signal_clk);  
+	proc3.p_resetn(signal_resetn);  
+	proc3.p_irq[0](signal_proc3_it0); 
+	proc3.p_irq[1](signal_proc3_it1); 
+	proc3.p_irq[2](signal_proc3_it2); 
+	proc3.p_irq[3](signal_proc3_it3); 
+	proc3.p_irq[4](signal_proc3_it4); 
+	proc3.p_irq[5](signal_proc3_it5); 
+	proc3.p_vci_ini_rw(signal_vci_ini_rw_proc3);
+	proc3.p_vci_ini_c(signal_vci_ini_c_proc3);
+	proc3.p_vci_tgt(signal_vci_tgt_proc3);
+
+	rom.p_clk(signal_clk);
+	rom.p_resetn(signal_resetn);
+	rom.p_vci(signal_vci_tgt_rom);
+
+#if USE_VCI_LOGGER_ON_L1_CPU0
+	vci_logger0.p_clk(signal_clk);
+	vci_logger0.p_resetn(signal_resetn);
+	vci_logger0.p_vci(signal_vci_ini_rw_proc0);
+#endif
+
+
+#if USE_VCI_LOGGER_ON_L1_CPU1
+	vci_logger1.p_clk(signal_clk);
+	vci_logger1.p_resetn(signal_resetn);
+	vci_logger1.p_vci(signal_vci_ini_rw_proc1);
+#endif
+
+#if USE_VCI_LOGGER_ON_L1_CPU2
+	vci_logger2.p_clk(signal_clk);
+	vci_logger2.p_resetn(signal_resetn);
+	vci_logger2.p_vci(signal_vci_ini_rw_proc2);
+#endif
+
+#if USE_VCI_LOGGER_ON_L1_CPU3
+	vci_logger3.p_clk(signal_clk);
+	vci_logger3.p_resetn(signal_resetn);
+	vci_logger3.p_vci(signal_vci_ini_rw_proc3);
+#endif
+
+#if USE_VCI_LOGGER_ON_ROM
+	vci_logger4.p_clk(signal_clk);
+	vci_logger4.p_resetn(signal_resetn);
+	vci_logger4.p_vci(signal_vci_tgt_rom);
+#endif
+
+
+#if USE_VCI_PROFILER_ON_CPU0
+	vci_prof0.p_clk(signal_clk);
+	vci_prof0.p_resetn(signal_resetn);
+	vci_prof0.p_vci(signal_vci_ini_rw_proc0);
+	vci_prof0.set_L1_cache(&proc0);
+#endif
+
+#if USE_VCI_PROFILER_ON_CPU1
+	vci_prof1.p_clk(signal_clk);
+	vci_prof1.p_resetn(signal_resetn);
+	vci_prof1.p_vci(signal_vci_ini_rw_proc1);
+	vci_prof1.set_L1_cache(&proc1);
+#endif
+
+#if USE_VCI_PROFILER_ON_CPU2
+	vci_prof2.p_clk(signal_clk);
+	vci_prof2.p_resetn(signal_resetn);
+	vci_prof2.p_vci(signal_vci_ini_rw_proc2);
+	vci_prof2.set_L1_cache(&proc2);
+#endif
+
+#if USE_VCI_PROFILER_ON_CPU3
+	vci_prof3.p_clk(signal_clk);
+	vci_prof3.p_resetn(signal_resetn);
+	vci_prof3.p_vci(signal_vci_ini_rw_proc3);
+	vci_prof3.set_L1_cache(&proc3);
+#endif
+
+	vcixicu.p_resetn(signal_resetn);
+	vcixicu.p_clk(signal_clk);
+	vcixicu.p_vci(signal_vci_xicu);
+	vcixicu.p_hwi[0](signal_icu_irq0);
+	vcixicu.p_hwi[1](signal_icu_irq1);
+	vcixicu.p_hwi[2](signal_icu_irq2);
+	vcixicu.p_hwi[3](signal_icu_irq3);
+	vcixicu.p_hwi[4](signal_icu_irq4);
+	vcixicu.p_hwi[5](signal_icu_irq5);
+
+	vcixicu.p_irq[0](signal_proc0_it0);
+	vcixicu.p_irq[1](signal_proc1_it0);
+	vcixicu.p_irq[2](signal_proc2_it0);
+	vcixicu.p_irq[3](signal_proc3_it0);
+	vcidma.p_clk(signal_clk);
+	vcidma.p_resetn(signal_resetn);
+	vcidma.p_irq(signal_icu_irq4); 
+
+	vcifb.p_clk(signal_clk);
+	vcifb.p_resetn(signal_resetn);
+	vcifb.p_vci(signal_vci_vcifb);
+
+	vcitty.p_clk(signal_clk);
+	vcitty.p_resetn(signal_resetn);
+	vcitty.p_vci(signal_vci_tty);
+	vcitty.p_irq[0](signal_icu_irq0); 
+	vcitty.p_irq[1](signal_icu_irq1); 
+	vcitty.p_irq[2](signal_icu_irq2); 
+	vcitty.p_irq[3](signal_icu_irq3); 
+
+
+	vcidma.p_vci_target(signal_vci_dmat);
+	vcidma.p_vci_initiator(signal_vci_dmai);
+	
+	memc.p_clk(signal_clk);
+	memc.p_resetn(signal_resetn);
+	memc.p_vci_tgt(signal_vci_tgt_memc);
+	memc.p_vci_tgt_cleanup(signal_vci_tgt_cleanup_memc);
+	memc.p_vci_ini(signal_vci_ini_memc);
+	memc.p_vci_ixr(signal_vci_ixr_memc);
+
+	vcibd.p_clk(signal_clk);
+	vcibd.p_resetn(signal_resetn);
+	vcibd.p_vci_target(signal_vci_vcibd_t);
+	vcibd.p_vci_initiator(signal_vci_vcibd_i);
+	vcibd.p_irq(signal_icu_irq5);
+
+
+	xram.p_clk(signal_clk);
+	xram.p_resetn(signal_resetn);
+	xram.p_vci(signal_vci_ixr_memc);
+	
+
+	ringp.p_clk(signal_clk);
+	ringp.p_resetn(signal_resetn);
+
+	ringc.p_clk(signal_clk);
+	ringc.p_resetn(signal_resetn);
+
+	ringp.p_to_initiator[0](signal_vci_ini_rw_proc0);
+	ringp.p_to_initiator[1](signal_vci_ini_rw_proc1);
+	ringp.p_to_initiator[2](signal_vci_ini_rw_proc2);
+	ringp.p_to_initiator[3](signal_vci_ini_rw_proc3);
+	ringp.p_to_initiator[4](signal_vci_dmai);
+	ringp.p_to_initiator[5](signal_vci_vcibd_i);
+	
+
+	ringc.p_to_initiator[0](signal_vci_ini_c_proc0);
+	ringc.p_to_initiator[1](signal_vci_ini_c_proc1);
+	ringc.p_to_initiator[2](signal_vci_ini_c_proc2);
+	ringc.p_to_initiator[3](signal_vci_ini_c_proc3);
+	ringc.p_to_initiator[4](signal_vci_ini_memc);
+
+
+	ringp.p_to_target[0](signal_vci_tgt_memc);
+	ringp.p_to_target[1](signal_vci_tgt_rom);
+	ringp.p_to_target[2](signal_vci_vcibd_t);
+	ringp.p_to_target[3](signal_vci_tty);
+	ringp.p_to_target[4](signal_vci_xicu);
+	ringp.p_to_target[5](signal_vci_dmat);
+	ringp.p_to_target[6](signal_vci_vcifb);
+
+	ringc.p_to_target[0](signal_vci_tgt_proc0);
+	ringc.p_to_target[1](signal_vci_tgt_proc1);
+	ringc.p_to_target[2](signal_vci_tgt_proc2);
+	ringc.p_to_target[3](signal_vci_tgt_proc3);
+	ringc.p_to_target[4](signal_vci_tgt_cleanup_memc);
+
+
+	sc_start(sc_core::sc_time(0, SC_NS));
+	signal_resetn = false;
+
+	sc_start(sc_core::sc_time(1, SC_NS));
+	signal_resetn = true;
+
+	if (gettimeofday(&t1, NULL) != 0) {
+	      perror("gettimeofday");
+	      return EXIT_FAILURE;
+	}
+	
+	for(uint64_t i=1 ; i<ncycles ; i++)
+	{
+	  sc_start(sc_core::sc_time(1, SC_NS));
+	  
+	  if ( (i % sstep) == 0)
+	  {
+	    memc.print_stats();
+	    proc0.print_trace();
+	    proc0.print_stats();
+	    proc0.clear_stats();
+	   
+#if 1
+	    proc1.print_trace();
+	    proc1.print_stats();
+	    proc1.clear_stats();
+	    
+	    proc2.print_trace();
+	    proc2.print_stats();
+	    proc2.clear_stats();
+	    
+	    proc3.print_trace();
+	    proc3.print_stats();
+	    proc3.clear_stats();
+#endif
+	  }
+
+	  /*
+	   * execute 10 million cycle, compute how many time it took and
+	   * print the clock frequency
+	   */
+	  
+	  if( (i % 10000000) == 0)
+	  {
+
+	    if (gettimeofday(&t2, NULL) != 0) 
+	    {
+	      perror("gettimeofday");
+	      return EXIT_FAILURE;
+	    }
+	    
+	    ms1 = (uint64_t)t1.tv_sec * 1000ULL + (uint64_t)t1.tv_usec / 1000;
+	    ms2 = (uint64_t)t2.tv_sec * 1000ULL + (uint64_t)t2.tv_usec / 1000;
+	    std::cerr << "platform clock frequency " << (double)10000000ULL / (double)(ms2 - ms1) << "Khz" << std::endl;
+	   
+	    if (gettimeofday(&t1, NULL) != 0) 
+	    {
+	      perror("gettimeofday");
+	      return EXIT_FAILURE;
+	    }
+	  }
+	}
+
+	return EXIT_SUCCESS;
+}
+
+int sc_main (int argc, char *argv[])
+{
+	try {
+		return _main(argc, argv);
+	} catch (std::exception &e) {
+		std::cout << e.what() << std::endl;
+	} catch (...) {
+		std::cout << "Unknown exception occured" << std::endl;
+		throw;
+	}
+	return 1;
+}
Index: trunk/platforms/almos-tsarv3-platforms/multi-clusters/Makefile
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/multi-clusters/Makefile	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/multi-clusters/Makefile	(revision 259)
@@ -0,0 +1,6 @@
+ARCH=mips32el
+SOCLIB?=$(shell soclib-cc --getpath)
+NO_SOFT=1
+export SOCLIB
+SOCLIB_CC_ADD_ARGS='-v -I../common -I.'
+include $(SOCLIB)/soclib/platform/topcells/all.mk
Index: trunk/platforms/almos-tsarv3-platforms/multi-clusters/config.h
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/multi-clusters/config.h	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/multi-clusters/config.h	(revision 259)
@@ -0,0 +1,150 @@
+#ifndef _TSAR_CONFIG_H_
+#define _TSAR_CONFIG_H_
+
+#define yes 1
+#define no  0
+
+///////////////////////////////////////////////////
+//                Memory system          
+///////////////////////////////////////////////////
+
+#define USE_MEMCACHE_V3                       yes
+#define USE_MEMCACHE_V4                       no
+
+#define CONFIG_MEMC_UPDATE_TAB_LINES          4
+#define CONFIG_MEMC_TRANSACTION_TAB_LINES     4
+
+#define MEMC_WAYS                             16
+#define MEMC_SETS                             256
+
+#define L1_IWAYS                              4
+#define L1_ISETS                              64
+
+#define L1_DWAYS                              4
+#define L1_DSETS                              64
+
+#define TLB_IWAYS                             4
+#define TLB_ISETS                             16
+
+#define TLB_DWAYS                             4
+#define TLB_DSETS                             16
+
+#define CONFIG_XRAM_LATENCY                   0
+
+///////////////////////////////////////////////////
+//              Operating System
+///////////////////////////////////////////////////
+
+#define USE_ALMOS                yes
+
+
+///////////////////////////////////////////////////
+//              Peripheral Devices 
+/////////////////////////////////////////////////// 
+
+#define USE_FRAME_BUFFER         no
+
+#define	SECTOR_SIZE	         4096
+#define BDEV_IMAGE_NAME	         "hdd-img.bin"
+#define BDEV_NAME_LEN            128
+
+#define N_TTYS		         4
+
+///////////////////////////////////////////////////
+//               Parallelisation
+///////////////////////////////////////////////////
+#define USE_OPENMP               yes
+
+///////////////////////////////////////////////////
+//               Local-Interconnect
+//////////////////////////////////////////////////
+#define USE_LOCAL_RING           no
+
+///////////////////////////////////////////////////
+//               Global-Interconnect
+///////////////////////////////////////////////////
+#define VDSPIN_CMD_IN_LEN         4
+#define VDSPIN_CMD_OUT_LEN        4
+#define VDSPIN_RSP_IN_LEN         4
+#define VDSPIN_RSP_OUT_LEN        4
+
+///////////////////////////////////////////////////
+//               Profiling & Debug
+///////////////////////////////////////////////////
+
+#define USE_LOGGER_ON_CPUs           no
+#define USE_LOGGER_ON_DMA            no
+#define USE_PROFILER_ON_CPUs         yes
+#define USE_GDBSERVER                no
+
+#define VCI_LOGGER_ON_ROM            no
+#define VCI_LOGGER_ON_MC_IO          no
+#define VCI_LOGGER_ON_MC0_D          no
+#define VCI_LOGGER_ON_MC2_D          no
+#define VCI_LOGGER_ON_BDEV           no
+
+#define CONFIG_LOGGER_START_CYCLE    6000000
+
+#define CONFIG_RING_IDEBUG           no
+#define CONFIG_RING_HIDEBUG          no
+#define CONFIG_RING_TDEBUG           no
+#define CONFIG_RING_HTDEBUG          no
+
+
+///////////////////////////////////////////////////
+//        Physical Address Sapce         
+///////////////////////////////////////////////////
+// segments definition in direct space.
+// There is 16 Mbytes address space per cluster.
+// The 8 MSB bits define the cluster index (x,y),
+// even if the number of clusters is less than 256.
+// Each memory cache contains up to 12 Mbytes.
+// There is one MEMC segment and one XICU segment 
+// per cluster. The peripherals BDEV, FBUF, MTTY, 
+// CDMA and the boot BROM are mapped in cluster 
+// containing address 0xBFC00000
+///////////////////////////////////////////////////
+
+#define MEMC_BASE                0x00000000      
+#define MEMC_SIZE                0x00C00000
+
+#define BROM_BASE                0xBFC00000      
+#define BROM_SIZE                0x00100000
+
+#define FBUF_BASE                0xBFD00000      
+#define FBUF_SIZE                0x00200000
+
+#define XICU_BASE                0x00F00000      
+#define XICU_SIZE                0x00002000
+
+#define BDEV_BASE                0xBFF10000      
+#define BDEV_SIZE                0x00000100
+
+#define MTTY_BASE                0xBFF20000      
+#define MTTY_SIZE                0x00000100
+
+#define CDMA_BASE                0xBFF30000      
+#define CDMA_SIZE                0x00000100
+
+
+////////////////////////////////////////////////////////////////////
+//     TGTID & SRCID definition in direct space
+// For all components:  global TGTID = global SRCID = cluster_index
+// For processors, the local SRCID is between 0 & nprocs-1
+////////////////////////////////////////////////////////////////////
+
+#define MEMC_TGTID               0
+#define XICU_TGTID               1
+#define FBUF_TGTID               2
+#define MTTY_TGTID               3
+#define BROM_TGTID               4
+#define BDEV_TGTID               5
+#define CDMA_TGTID               6
+
+#define PROC_SRCID               0
+#define BDEV_SRCID               nprocs
+#define CDMA_SRCID               (nprocs+1)
+
+#define CONFIG_ADDRESS_WIDTH     32
+
+#endif	/* _TSAR_CONFIG_H_ */
Index: trunk/platforms/almos-tsarv3-platforms/multi-clusters/config/config.h
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/multi-clusters/config/config.h	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/multi-clusters/config/config.h	(revision 259)
@@ -0,0 +1,3 @@
+namespace config {
+  #include "../config.h"
+}
Index: trunk/platforms/almos-tsarv3-platforms/multi-clusters/config/config.sd
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/multi-clusters/config/config.sd	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/multi-clusters/config/config.sd	(revision 259)
@@ -0,0 +1,13 @@
+
+# -*- python -*-
+
+__id__ = "$Id: todo $"
+__version__ = "$vision: 0 $"
+
+Module('config:config',
+	header_files = [
+		'../config.h',
+		]
+)
+
+
Index: trunk/platforms/almos-tsarv3-platforms/multi-clusters/platform_desc
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/multi-clusters/platform_desc	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/multi-clusters/platform_desc	(revision 259)
@@ -0,0 +1,26 @@
+ 
+# -*- python -*-
+
+todo = Platform('caba', 'top.cpp',
+	uses = [
+    
+#           Uses('caba:vci_cc_vcache_wrapper2_v1', iss_t = 'common:mips32el'),
+#           Uses('caba:vci_mem_cache_v3'),
+#           Uses('caba:vci_local_ring_fast', ring_cmd_data_size = 40, ring_rsp_data_size = 33),
+#	    Uses('caba:vci_cluster', iss_t = 'common:gdb_iss', gdb_iss_t = 'common:mips32el', cmd_width = 40, rsp_width = 33),
+
+            Uses('caba:tsarv4_cluster_xbar', iss_t = 'common:mips32el', cmd_width = 40, rsp_width = 33),
+            Uses('common:elf_file_loader'),
+            Uses('common:plain_file_loader'),
+	],
+	cell_size = 4,
+	plen_size = 8,
+	addr_size = 32,
+	rerror_size = 1,
+	clen_size = 1,
+	rflag_size = 1,
+	srcid_size = 14,
+	pktid_size = 4,
+	trdid_size = 4,
+	wrplen_size = 1,
+)
Index: trunk/platforms/almos-tsarv3-platforms/multi-clusters/soclib.conf
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/multi-clusters/soclib.conf	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/multi-clusters/soclib.conf	(revision 259)
@@ -0,0 +1,23 @@
+config.lib_systemcass_openmp_mine = Library(
+	parent = config.systemc,
+	dir = "/users/outil/nbsdtsar/systemcass",
+	libdir = "%(dir)s/lib-linux",
+	cflags = config.systemc.cflags+['-fopenmp']+['-O3'],
+	#cflags = config.systemc.cflags,
+	libs = ['-ldl', '-lm', '-lpthread', '-L%(libdir)s', '-lsystemc', '-rdynamic', '-fopenmp'],
+	#libs = ['-ldl', '-lm', '-lpthread', '-L%(libdir)s', '-lsystemc', '-rdynamic'],
+)
+
+config.systemcass_openmp_mine = BuildEnv(
+	parent = config.systemc_64,
+	libraries = [ config.lib_systemcass_openmp_mine ],
+	#base = config.systemc_32,
+	repos = "/dsk/l1/misc/almaless/soclib-cc/head/systemcass-mine",
+	cache_file = "/dsk/l1/misc/almaless/soclib-cc/head/systemcass-mine/soclib_cc.cache",
+	toolchain = config.toolchain_64,
+	#toolchain = config.dist_toolchain,
+)
+
+#config.default = config.systemcass
+#config.default = config.systemcass_openmp
+config.default = config.systemcass_openmp_mine
Index: trunk/platforms/almos-tsarv3-platforms/multi-clusters/soclib.conf32
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/multi-clusters/soclib.conf32	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/multi-clusters/soclib.conf32	(revision 259)
@@ -0,0 +1,23 @@
+config.lib_systemcass_openmp_mine = Library(
+	parent = config.systemc,
+	dir = "/users/outil/nbsdtsar/systemcass32",
+	libdir = "%(dir)s/lib-linux",
+	cflags = config.systemc.cflags+['-fopenmp']+['-O3'],
+	#cflags = config.systemc.cflags,
+	libs = ['-ldl', '-lm', '-lpthread', '-L%(libdir)s', '-lsystemc', '-rdynamic', '-fopenmp'],
+	#libs = ['-ldl', '-lm', '-lpthread', '-L%(libdir)s', '-lsystemc', '-rdynamic'],
+)
+
+config.systemcass_openmp_mine = BuildEnv(
+	parent = config.systemc,
+	libraries = [ config.lib_systemcass_openmp_mine ],
+	base = config.systemc_32,
+	repos = "/dsk/l1/misc/almaless/soclib-cc/head/systemcass-mine-32",
+	cache_file = "/dsk/l1/misc/almaless/soclib-cc/head/systemcass-mine-32/soclib_cc.cache",
+	toolchain = config.toolchain,
+	#toolchain = config.dist_toolchain,
+)
+
+#config.default = config.systemcass
+#config.default = config.systemcass_openmp
+config.default = config.systemcass_openmp_mine
Index: trunk/platforms/almos-tsarv3-platforms/multi-clusters/soclib.conf64
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/multi-clusters/soclib.conf64	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/multi-clusters/soclib.conf64	(revision 259)
@@ -0,0 +1,23 @@
+config.lib_systemcass_openmp_mine = Library(
+	parent = config.systemc,
+	dir = "/users/outil/nbsdtsar/systemcass",
+	libdir = "%(dir)s/lib-linux",
+	cflags = config.systemc.cflags+['-fopenmp']+['-O3'],
+	#cflags = config.systemc.cflags,
+	libs = ['-ldl', '-lm', '-lpthread', '-L%(libdir)s', '-lsystemc', '-rdynamic', '-fopenmp'],
+	#libs = ['-ldl', '-lm', '-lpthread', '-L%(libdir)s', '-lsystemc', '-rdynamic'],
+)
+
+config.systemcass_openmp_mine = BuildEnv(
+	parent = config.systemc_64,
+	libraries = [ config.lib_systemcass_openmp_mine ],
+	#base = config.systemc_32,
+	repos = "/dsk/l1/misc/almaless/soclib-cc/head/systemcass-mine",
+	cache_file = "/dsk/l1/misc/almaless/soclib-cc/head/systemcass-mine/soclib_cc.cache",
+	toolchain = config.toolchain_64,
+	#toolchain = config.dist_toolchain,
+)
+
+#config.default = config.systemcass
+#config.default = config.systemcass_openmp
+config.default = config.systemcass_openmp_mine
Index: trunk/platforms/almos-tsarv3-platforms/multi-clusters/top.cpp
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/multi-clusters/top.cpp	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/multi-clusters/top.cpp	(revision 259)
@@ -0,0 +1,773 @@
+/////////////////////////////////////////////////////////////////////////
+// File: tsarv4_vgmn_generic_32_top.cpp
+// Author: Alain Greiner
+// Copyright: UPMC/LIP6
+// Date : november 5 2010
+// This program is released under the GNU public license
+/////////////////////////////////////////////////////////////////////////
+// This file define a generic TSAR architecture without virtual memory.
+// - It uses the vci_vgmn as global interconnect 
+// - It uses the vci_local_crossbar  as local interconnect 
+// - It uses the vci_cc_xcache (No MMU) 
+// The physical address space is 32 bits.
+// The number of clusters cannot be larger than 256.
+// The three parameters are 
+// - xmax : number of clusters in a row
+// - ymax : number of clusters in a column
+// - nprocs : number of processor per cluster
+//
+// Each cluster contains nprocs processors, one Memory Cache,
+// and one XICU component.
+// The peripherals BDEV, CDMA, FBUF, MTTY and the boot BROM
+// are in the cluster containing address 0xBFC00000.
+// - The bdev_irq is connected to IRQ_IN[0]
+// - The cdma_irq is connected to IRQ_IN[1]
+// - The tty_irq[i] is connected to IRQ_IN[i+2]
+// For all clusters, the XICU component contains nprocs timers.
+// 
+// As we target up to 256 clusters, each cluster can contain 
+// at most 16 Mbytes (in a 4Gbytes address space).
+// There is one MEMC segment and one XICU segment per cluster.
+// - Each memory cache contains 8 Mbytes.
+// - The Frame buffer contains 4 Mbytes.
+// - The Boot ROM contains 1 Mbytes
+//
+// General policy for 32 bits address decoding:
+// To simplifly, all segments base addresses are aligned
+// on 64 Kbytes addresses. Therefore the 16 address MSB bits
+// define the target in the direct address space.
+// In these 16 bits, the (x_width + y_width) MSB bits define
+// the cluster index, and the 8 LSB bits define the local index:
+// 
+//      | X_ID  | Y_ID  |---| L_ID |     OFFSET          |
+//	|x_width|y_width|---|  8   |       16            |
+/////////////////////////////////////////////////////////////////////////
+
+#include <systemc>
+#include <sys/time.h>
+#include <iostream>
+#include <sstream>
+#include <cstdlib>
+#include <cstdarg>
+#include <stdint.h>
+
+#include "mapping_table.h"
+#include "tsarv4_cluster_xbar.h"
+#include "mips32.h"
+#include "vci_simple_ram.h"
+
+#include "alloc_elems.h"
+#include "config.h"
+
+#if USE_OPENMP
+#include <omp.h>
+#endif
+
+#if USE_VCI_PROFILER
+#include "vci_profiler.h"
+#endif
+
+#if USE_GDBSERVER
+#include "gdbserver.h"
+#endif
+
+
+#if USE_ALMOS
+#define BOOT_INFO_BLOCK 0xbfc08000
+#define KERNEL_BIN_IMG  0xbfc10000
+#endif
+
+//  cluster index (computed from x,y coordinates)
+#define cluster(x,y)	(y + ymax*x)
+
+#define _TO_STR(_str) #_str
+#define  TO_STR(_str) _TO_STR(_str)
+
+// flit widths for the DSPIN network
+#define cmd_width	         40
+#define rsp_width	         33
+
+// VCI format
+#define cell_width	         4
+#define address_width	         32
+#define plen_width	         8
+#define error_width	         1
+#define clen_width	         1
+#define rflag_width	         1
+#define srcid_width	         14
+#define pktid_width	         4
+#define trdid_width	         4
+#define wrplen_width	         1
+
+
+/////////////////////////////////
+int _main(int argc, char *argv[])
+{
+    using namespace sc_core;
+    using namespace soclib::caba;
+    using namespace soclib::common;
+    
+    uint64_t       ms1, ms2;
+    struct timeval t1, t2;
+    
+    char    soft_name[BDEV_NAME_LEN] = "to_be_defined";	// pathname to binary code
+    char    disk_name[BDEV_NAME_LEN] = BDEV_IMAGE_NAME;   // pathname to the disk image
+    size_t  ncycles        = 1000000000;       // simulated cycles
+    size_t  xmax           = 2;		       // number of clusters in a row
+    size_t  ymax           = 2;                // number of clusters in a column
+    size_t  nprocs         = 1;		// number of processors per cluster
+    size_t  xfb            = 512;	// frameBuffer column number
+    size_t  yfb            = 512;       // frameBuffer lines number
+    size_t  fb_mode        = 420;
+    #define DEBUG_OK       no
+    size_t  from_cycle     = 0;                // debug start cycle
+    size_t  memc_size      = MEMC_SIZE;
+    size_t  blk_size       = SECTOR_SIZE;
+    size_t  l1_i_ways      = L1_IWAYS;
+    size_t  l1_d_ways      = L1_DWAYS;
+    size_t  l1_i_sets      = L1_ISETS;
+    size_t  l1_d_sets      = L1_DSETS;
+    size_t  memc_sets      = MEMC_SETS;
+    size_t  memc_ways      = MEMC_WAYS;
+    size_t  itlb_ways      = TLB_IWAYS;
+    size_t  itlb_sets      = TLB_ISETS;
+    size_t  dtlb_ways      = TLB_DWAYS;
+    size_t  dtlb_sets      = TLB_DSETS;
+    size_t  xram_latency   = CONFIG_XRAM_LATENCY;
+    size_t  omp_threads    = 1;
+    ////////////// command line arguments //////////////////////
+    if (argc > 1)
+    {
+      for( int n=1 ; n<argc ; n=n+2 )
+      {
+	    if( (strcmp(argv[n],"-NCYCLES") == 0) && (n+1<argc) )
+            {
+                ncycles = atoi(argv[n+1]);
+            }
+            else if( (strcmp(argv[n],"-NPROCS") == 0) && (n+1<argc) )
+            {
+                nprocs = atoi(argv[n+1]);
+                assert( ((nprocs == 1) || (nprocs == 2) || (nprocs == 4)) &&
+                        "NPROCS must be equal to 1, 2, or 4");
+            }
+            else if( (strcmp(argv[n],"-THREADS") == 0) && (n+1<argc) )
+            {
+	        omp_threads = atoi(argv[n+1]);
+            }
+            else if( (strcmp(argv[n],"-XMAX") == 0) && (n+1<argc) )
+            {
+                xmax = atoi(argv[n+1]);
+                assert( ((xmax == 1) || (xmax == 2) || (xmax == 4) || (xmax == 8) || (xmax == 16)) 
+                         && "The XMAX parameter must be 2, 4, 8, or 16" );
+            }
+	    else if( (strcmp(argv[n],"-YMAX") == 0) && (n+1<argc) )
+            {
+                ymax = atoi(argv[n+1]);
+                assert( ((ymax == 1) || (ymax == 2) || (ymax == 4) || (ymax == 8) || (ymax == 16)) 
+                         && "The YMAX parameter must be 2, 4, 8, or 16" );
+            }
+	    else if( (strcmp(argv[n],"-XFB") == 0) && (n+1<argc) )
+            {
+	        xfb = atoi(argv[n+1]);
+            }
+	    else if( (strcmp(argv[n],"-YFB") == 0) && (n+1<argc) )
+            {
+                yfb = atoi(argv[n+1]);
+            }
+	    else if( (strcmp(argv[n], "-FBMODE") == 0) && (n+1 < argc))
+	    {
+	      fb_mode = atoi(argv[n+1]);
+	    }
+            else if( (strcmp(argv[n],"-SOFT") == 0) && (n+1<argc) )
+            {
+                strcpy(soft_name, argv[n+1]);
+            }
+            else if( (strcmp(argv[n],"-DISK") == 0) && (n+1<argc) )
+            {
+                strcpy(disk_name, argv[n+1]);
+            }
+	    else if( (strcmp(argv[n],"-BLKSZ") == 0) && (n+1<argc) )
+            {
+	      blk_size = atoi(argv[n+1]);
+	      assert(((blk_size % 512) == 0) && "BDEV: Block size must be multiple of 512 bytes");
+            }
+            else if( (strcmp(argv[n],"-TRACE") == 0) && (n+1<argc) )
+            {
+                from_cycle = atoi(argv[n+1]);
+            }
+	    else if((strcmp(argv[n], "-MEMSZ") == 0) && (n+1 < argc))
+	    {
+	        memc_size = atoi(argv[n+1]);
+	    }
+	    else if((strcmp(argv[n], "-MCWAYS") == 0) && (n+1 < argc))
+	    {
+	        memc_ways = atoi(argv[n+1]);
+	    }
+	    else if((strcmp(argv[n], "-MCSETS") == 0) && (n+1 < argc))
+	    {
+	        memc_sets = atoi(argv[n+1]);
+	    }
+	    else if((strcmp(argv[n], "-L1_IWAYS") == 0) && (n+1 < argc))
+	    {
+	        l1_i_ways = atoi(argv[n+1]);
+	    }
+	    else if((strcmp(argv[n], "-L1_ISETS") == 0) && (n+1 < argc))
+	    {
+	        l1_i_sets = atoi(argv[n+1]);
+	    }
+	    else if((strcmp(argv[n], "-L1_DWAYS") == 0) && (n+1 < argc))
+	    {
+	        l1_d_ways = atoi(argv[n+1]);
+	    }
+	    else if((strcmp(argv[n], "-L1_DSETS") == 0) && (n+1 < argc))
+	    {
+	        l1_d_sets = atoi(argv[n+1]);
+	    }
+	    else if((strcmp(argv[n], "-ITLB_WAYS") == 0) && (n+1 < argc))
+	    {
+	        itlb_ways = atoi(argv[n+1]);
+	    }
+	    else if((strcmp(argv[n], "-ITLB_SETS") == 0) && (n+1 < argc))
+	    {
+	        itlb_sets = atoi(argv[n+1]);
+	    }
+	    else if((strcmp(argv[n], "-DTLB_WAYS") == 0) && (n+1 < argc))
+	    {
+	        dtlb_ways = atoi(argv[n+1]);
+	    }
+	    else if((strcmp(argv[n], "-DTLB_SETS") == 0) && (n+1 < argc))
+	    {
+	        dtlb_sets = atoi(argv[n+1]);
+	    }
+	    else if((strcmp(argv[n], "-XLATENCY") == 0) && (n+1 < argc))
+	    {
+	        xram_latency = atoi(argv[n+1]);
+	    }
+            else
+            {
+                std::cout << "   Arguments on the command line are (key,value) couples." << std::endl;
+                std::cout << "   The order is not important." << std::endl;
+                std::cout << "   Accepted arguments are :" << std::endl << std::endl;
+                std::cout << "     -SOFT pathname_for_embedded_soft" << std::endl;
+                std::cout << "     -DISK pathname_for_disk_image" << std::endl;
+		std::cout << "     -BLKSZ sector size in bytes ( must be multiple of 512 bytes )" << std::endl;
+                std::cout << "     -NCYCLES number_of_simulated_cycles" << std::endl;
+                std::cout << "     -NPROCS number_of_processors_per_cluster" << std::endl;
+                std::cout << "     -XMAX number_of_clusters_in_a_row" << std::endl;
+                std::cout << "     -YMAX number_of_clusters_in_a_column" << std::endl;
+                std::cout << "     -TRACE debug_start_cycle" << std::endl;
+                std::cout << "     -MCWAYS memory_cache_number_of_ways" << std::endl;
+                std::cout << "     -MCSETS memory_cache_number_of_sets" << std::endl;
+		std::cout << "     -L1_IWAYS L1_instruction_cache_number_of_ways" << std::endl;
+		std::cout << "     -L1_ISETS L1_instruction_cache_number_of_sets" << std::endl;
+		std::cout << "     -L1_DWAYS L1_data_cache_number_of_ways" << std::endl;
+		std::cout << "     -L1_DSETS L1_data_cache_number_of_sets" << std::endl;
+                std::cout << "     -XLATENCY external_ram_latency_value" << std::endl;
+                std::cout << "     -XFB fram_buffer_number_of_pixels" << std::endl;
+                std::cout << "     -YFB fram_buffer_number_of_lines" << std::endl;
+		std::cout << "     -FBMODE fram buffer subsampling integer value (YUV:420,YUV:422,RGB:0,RGB:16,RGB:32,RGBPAL:256)" << std::endl;
+		std::cout << "     -MEMSZ per-cluster memory size ( <= 12 MB )" << std::endl;
+                std::cout << "     -THREADS number_of_cores_for_OpenMP" << std::endl;
+                exit(0);
+            }
+        }
+    }
+
+    
+    std::cout << "Simulation Parameters:" << std::endl;
+    std::cout << "          OMP_THREADS_NR        = " << omp_threads << std::endl;
+    std::cout << "          XFB                   = " << xfb << std::endl;
+    std::cout << "          YFB                   = " << yfb << std::endl;
+    std::cout << "          FB_MODE               = " << fb_mode << std::endl;
+    std::cout << "          SECTOR_SIZE  (Bytes)  = " << blk_size << std::endl;
+    std::cout << "          RAM/CLSTR    (Bytes)  = " << memc_size << std::endl;
+    std::cout << "          XRAM_LATENCY (cycles) = " << xram_latency << std::endl;
+    std::cout << "          MEMC_UPD_TBL          = " << CONFIG_MEMC_UPDATE_TAB_LINES << std::endl;
+    std::cout << "          MEMC_TRN_TLB          = " << CONFIG_MEMC_TRANSACTION_TAB_LINES <<std::endl;
+    std::cout << "          MEMC_WAYS             = " << memc_ways << std::endl;
+    std::cout << "          MEMC_SETS             = " << memc_sets << std::endl;
+    std::cout << "          L1_IWAYS              = " << l1_i_ways << std::endl;
+    std::cout << "          L1_ISETS              = " << l1_i_sets << std::endl;
+    std::cout << "          L1_DWAYS              = " << l1_d_ways << std::endl;
+    std::cout << "          L1_DSETS              = " << l1_d_sets << std::endl;
+    std::cout << "          ITLB_WAYS             = " << itlb_ways << std::endl;
+    std::cout << "          ITLB_SETS             = " << itlb_sets << std::endl;
+    std::cout << "          DTLB_WAYS             = " << dtlb_ways << std::endl;
+    std::cout << "          DTLB_SETS             = " << dtlb_sets << std::endl;
+    
+#define CONFIG_MEMC_TRANSACTION_TAB_LINES     8
+
+#define MEMC_WAYS                             16
+#define MEMC_SETS                             256
+
+#define L1_IWAYS                              4
+#define L1_ISETS                              64
+
+#define L1_DWAYS                              4
+#define L1_DSETS                              64
+
+#define TLB_IWAYS                             4
+#define TLB_ISETS                             16
+
+#define TLB_DWAYS                             4
+#define TLB_DSETS                             16
+
+#define CONFIG_XRAM_LATENCY                   0
+
+
+
+#if USE_OPENMP
+        omp_set_dynamic(false);
+        omp_set_num_threads(omp_threads);
+        std::cerr << "Built with openmp version " << _OPENMP << std::endl;
+#endif
+
+
+    // Define VCI parameters
+    typedef soclib::caba::VciParams<cell_width,
+                                    plen_width,
+                                    address_width,
+                                    error_width,                                   
+                                    clen_width,
+                                    rflag_width,
+                                    srcid_width,
+                                    pktid_width,
+                                    trdid_width,
+                                    wrplen_width> vci_param;
+
+    size_t	cluster_io_index;
+    size_t	x_width;
+    size_t	y_width;
+
+    if      (xmax == 2) x_width = 1;
+    else if (xmax <= 4) x_width = 2;
+    else if (xmax <= 8) x_width = 3;
+    else                x_width = 4;
+
+    if      (ymax == 2) y_width = 1;
+    else if (ymax <= 4) y_width = 2;
+    else if (ymax <= 8) y_width = 3;
+    else                y_width = 4;
+
+    cluster_io_index = 0xBF >> (8 - x_width - y_width);
+    
+    /////////////////////
+    //  Mapping Tables
+    /////////////////////
+
+    // direct network
+    MappingTable maptabd(address_width, 
+                         IntTab(x_width + y_width, 16 - x_width - y_width), 
+                         IntTab(x_width + y_width, srcid_width - x_width - y_width), 
+                         0x00F00000);
+
+    for ( size_t x = 0 ; x < xmax ; x++)
+    {
+        for ( size_t y = 0 ; y < ymax ; y++)
+        {
+            sc_uint<address_width> offset  = cluster(x,y) << (address_width-x_width-y_width);
+            std::ostringstream 	sm;
+            sm << "d_seg_memc_" << x << "_" << y;
+            maptabd.add(Segment(sm.str(), MEMC_BASE+offset, memc_size, IntTab(cluster(x,y),MEMC_TGTID), true));
+            std::ostringstream 	si;
+            si << "d_seg_xicu_" << x << "_" << y;
+            maptabd.add(Segment(si.str(), XICU_BASE+offset, XICU_SIZE, IntTab(cluster(x,y),XICU_TGTID), false));
+            if ( cluster(x,y) == cluster_io_index )
+            {
+	      maptabd.add(Segment("d_seg_fbuf", FBUF_BASE, FBUF_SIZE, IntTab(cluster(x,y),FBUF_TGTID), false));
+	      maptabd.add(Segment("d_seg_bdev", BDEV_BASE, BDEV_SIZE, IntTab(cluster(x,y),BDEV_TGTID), false));
+	      maptabd.add(Segment("d_seg_mtty", MTTY_BASE, MTTY_SIZE, IntTab(cluster(x,y),MTTY_TGTID), false));
+	      maptabd.add(Segment("d_seg_brom", BROM_BASE, BROM_SIZE, IntTab(cluster(x,y),BROM_TGTID), true));
+	      maptabd.add(Segment("d_seg_cdma", CDMA_BASE, CDMA_SIZE, IntTab(cluster(x,y),CDMA_TGTID), false));
+            }
+        }
+    }
+    std::cout << maptabd << std::endl;
+
+    // coherence network
+    MappingTable maptabc(address_width, 
+                         IntTab(x_width + y_width, 12 - x_width - y_width), 
+                         IntTab(x_width + y_width, srcid_width - x_width - y_width), 
+                         0xF0000000);
+
+    for ( size_t x = 0 ; x < xmax ; x++)
+    {
+        for ( size_t y = 0 ; y < ymax ; y++)
+        {
+            sc_uint<address_width> offset  = cluster(x,y) << (address_width-x_width-y_width);
+            
+            std::ostringstream sm;
+            sm << "c_seg_memc_" << x << "_" << y;
+            maptabc.add(Segment(sm.str(), MEMC_BASE+offset, memc_size, IntTab(cluster(x,y), nprocs), false));
+            // the segment base and size will be modified 
+            // when the segmentation of the coherence space will be simplified
+
+            if ( cluster(x,y) == cluster_io_index )
+            {
+                std::ostringstream sr;
+                sr << "c_seg_brom_" << x << "_" << y;
+                maptabc.add(Segment(sr.str(), BROM_BASE, BROM_SIZE, IntTab(cluster(x,y), nprocs), false));
+            }
+
+	    sc_uint<address_width> avoid_collision  = 0;
+	    for ( size_t p = 0 ; p < nprocs ; p++)
+            {
+	        sc_uint<address_width> base = memc_size + (p*0x100000) + offset;
+                // the following test is to avoid a collision between the c_seg_brom segment
+                // and a c_seg_proc segment (all segments base addresses being multiple of 1Mbytes)
+                if ( base == BROM_BASE ) avoid_collision = 0x100000;
+	        std::ostringstream sp;
+	        sp << "c_seg_proc_" << x << "_" << y << "_" << p;
+	        maptabc.add(Segment(sp.str(), base + avoid_collision, 0x20, IntTab(cluster(x,y), p), false, 
+				  true, IntTab(cluster(x,y), p))); 
+                // the two last arguments will be removed 
+                // when the segmentation of the coherence space will be simplified
+            }
+        }
+    }
+    std::cout << maptabc << std::endl;
+
+    // external network
+    MappingTable maptabx(address_width, IntTab(1), IntTab(10), 0xF0000000);
+
+    for ( size_t x = 0 ; x < xmax ; x++)
+    {
+        for ( size_t y = 0 ; y < ymax ; y++)
+        { 
+	  sc_uint<address_width> offset  = cluster(x,y) << (address_width-x_width-y_width);
+	  std::ostringstream sx;
+	  
+	  sx << "seg_xram_" << x << "_" << y;
+	  maptabx.add(Segment(sx.str(), MEMC_BASE + offset, memc_size, IntTab(cluster(x,y)), false));
+        }
+    }
+    std::cout << maptabx << std::endl;
+
+    ////////////////////
+    // Signals
+    ///////////////////
+
+    sc_clock		signal_clk("clk");
+    sc_signal<bool> 	signal_resetn("resetn");
+    sc_signal<bool>	signal_false;
+   
+
+    // Horizontal inter-clusters DSPIN signals
+    DspinSignals<cmd_width>*** signal_dspin_h_cmd_inc =
+      alloc_elems<DspinSignals<cmd_width> >("signal_dspin_h_cmd_inc", xmax-1, ymax, 2);
+    DspinSignals<cmd_width>*** signal_dspin_h_cmd_dec =
+      alloc_elems<DspinSignals<cmd_width> >("signal_dspin_h_cmd_dec", xmax-1, ymax, 2);
+    DspinSignals<rsp_width>*** signal_dspin_h_rsp_inc =
+      alloc_elems<DspinSignals<rsp_width> >("signal_dspin_h_rsp_inc", xmax-1, ymax, 2);
+    DspinSignals<rsp_width>*** signal_dspin_h_rsp_dec =
+      alloc_elems<DspinSignals<rsp_width> >("signal_dspin_h_rsp_dec", xmax-1, ymax, 2);
+
+    // Vertical inter-clusters DSPIN signals
+    DspinSignals<cmd_width>*** signal_dspin_v_cmd_inc =
+      alloc_elems<DspinSignals<cmd_width> >("signal_dspin_v_cmd_inc", xmax, ymax-1, 2);
+    DspinSignals<cmd_width>*** signal_dspin_v_cmd_dec =
+        alloc_elems<DspinSignals<cmd_width> >("signal_dspin_v_cmd_dec", xmax, ymax-1, 2);
+    DspinSignals<rsp_width>*** signal_dspin_v_rsp_inc =
+        alloc_elems<DspinSignals<rsp_width> >("signal_dspin_v_rsp_inc", xmax, ymax-1, 2);
+    DspinSignals<rsp_width>*** signal_dspin_v_rsp_dec =
+        alloc_elems<DspinSignals<rsp_width> >("signal_dspin_v_rsp_dec", xmax, ymax-1, 2);
+
+    // Mesh boundaries DSPIN signals
+    DspinSignals<cmd_width>**** signal_dspin_false_cmd_in =
+        alloc_elems<DspinSignals<cmd_width> >("signal_dspin_false_cmd_in", xmax,  ymax, 2, 4);
+    DspinSignals<cmd_width>**** signal_dspin_false_cmd_out =
+        alloc_elems<DspinSignals<cmd_width> >("signal_dspin_false_cmd_out", xmax, ymax, 2, 4);
+    DspinSignals<rsp_width>**** signal_dspin_false_rsp_in =
+        alloc_elems<DspinSignals<rsp_width> >("signal_dspin_false_rsp_in", xmax, ymax, 2, 4);
+    DspinSignals<rsp_width>**** signal_dspin_false_rsp_out =
+        alloc_elems<DspinSignals<rsp_width> >("signal_dspin_false_rsp_out", xmax, ymax, 2, 4);
+
+    // Xternal network VCI signals
+    VciSignals<vci_param> signal_vci_tgt_x_xram("signal_vci_tgt_x_xram");
+
+    ////////////////////////////
+    //      Components
+    ////////////////////////////
+
+#if USE_ALMOS
+    soclib::common::Loader loader("bootloader.bin",
+				  "arch-info.bin@"TO_STR(BOOT_INFO_BLOCK)":D",
+				  "kernel-soclib.bin@"TO_STR(KERNEL_BIN_IMG)":D");
+#else
+    soclib::common::Loader loader(soft_name);
+#endif
+
+#if USE_GDBSERVER
+    typedef soclib::common::GdbServer<soclib::common::Mips32ElIss> proc_iss;
+    proc_iss::set_loader(loader);
+#else
+    typedef soclib::common::Mips32ElIss proc_iss;
+#endif
+
+
+    TsarV4ClusterXbar<vci_param, proc_iss, cmd_width, rsp_width>* clusters[xmax][ymax];
+
+#if USE_OPENMP
+
+#pragma omp parallel
+    {
+#pragma omp for
+      for( int i = 0 ; i  < (xmax * ymax); i++)
+      {
+	size_t x = i / ymax;
+	size_t y = i % ymax;
+#pragma omp critical
+	{
+	  std::ostringstream sc;
+	  sc << "cluster_" << x << "_" << y;
+	  clusters[x][y] = new TsarV4ClusterXbar<vci_param, proc_iss, cmd_width, rsp_width>
+	    (sc.str().c_str(),
+	   nprocs,
+	     x,
+	     y,
+	     cluster(x,y),
+	     maptabd,
+	     maptabc,
+	     maptabx,
+	     x_width,
+	     y_width,
+	     MEMC_TGTID,
+	     XICU_TGTID,
+	     FBUF_TGTID,
+	     MTTY_TGTID,
+	     BROM_TGTID,
+	     BDEV_TGTID,
+	     CDMA_TGTID,
+	     memc_ways,
+	     memc_sets,
+	     l1_i_ways,
+	     l1_i_sets,
+	     l1_d_ways,
+	     l1_d_sets,
+	     xram_latency,
+	     (cluster(x,y) == cluster_io_index),
+	     xfb,
+	     yfb,
+	     fb_mode,
+	     disk_name,
+	     blk_size,
+	     loader);
+	}
+      }
+    }
+
+#else  // USE_OPENMP
+    for( size_t x = 0 ; x  < xmax ; x++)
+    {
+      for( size_t y = 0 ; y < ymax ; y++ )
+      {
+	std::ostringstream sc;
+	sc << "cluster_" << x << "_" << y;
+	
+	clusters[x][y] = new TsarV4ClusterXbar<vci_param, proc_iss, cmd_width, rsp_width>
+	  (sc.str().c_str(),
+	   nprocs,
+	   x,
+	   y,
+	   cluster(x,y),
+	   maptabd,
+	   maptabc,
+	   maptabx,
+	   x_width,
+	   y_width,
+	   MEMC_TGTID,
+	   XICU_TGTID,
+	   FBUF_TGTID,
+	   MTTY_TGTID,
+	   BROM_TGTID,
+	   BDEV_TGTID,
+	   CDMA_TGTID,
+	   memc_ways,
+	   memc_sets,
+	   l1_i_ways,
+	   l1_i_sets,
+	   l1_d_ways,
+	   l1_d_sets,
+	   xram_latency,
+	   (cluster(x,y) == cluster_io_index),
+	   xfb,
+	   yfb,
+	   fb_mode,
+	   disk_name,
+	   blk_size,
+	   loader);
+	}
+      }
+#endif	// USE_OPENMP
+
+    ///////////////////////////////////////////////////////////////
+    //     Net-list 
+    ///////////////////////////////////////////////////////////////
+
+    // Clock & RESET
+    for ( size_t x = 0 ; x < (xmax) ; x++ )
+    {
+        for ( size_t y = 0 ; y < ymax ; y++ )
+        {
+            clusters[x][y]->p_clk			(signal_clk);
+            clusters[x][y]->p_resetn			(signal_resetn);
+        }
+    }
+
+    // Inter Clusters horizontal connections
+    if ( xmax > 1 )
+    {
+        for ( size_t x = 0 ; x < (xmax-1) ; x++ )
+        {
+            for ( size_t y = 0 ; y < ymax ; y++ )
+            {
+                for ( size_t k = 0 ; k < 2 ; k++ )
+                {
+		clusters[x][y]->p_cmd_out[k][EAST]      (signal_dspin_h_cmd_inc[x][y][k]);
+                clusters[x+1][y]->p_cmd_in[k][WEST]     (signal_dspin_h_cmd_inc[x][y][k]);
+                clusters[x][y]->p_cmd_in[k][EAST]       (signal_dspin_h_cmd_dec[x][y][k]);
+                clusters[x+1][y]->p_cmd_out[k][WEST]    (signal_dspin_h_cmd_dec[x][y][k]);
+                clusters[x][y]->p_rsp_out[k][EAST]      (signal_dspin_h_rsp_inc[x][y][k]);
+                clusters[x+1][y]->p_rsp_in[k][WEST]     (signal_dspin_h_rsp_inc[x][y][k]);
+                clusters[x][y]->p_rsp_in[k][EAST]       (signal_dspin_h_rsp_dec[x][y][k]);
+                clusters[x+1][y]->p_rsp_out[k][WEST]    (signal_dspin_h_rsp_dec[x][y][k]);
+                }
+            }
+        }
+    }
+    std::cout << "Horizontal connections established" << std::endl;	
+
+    // Inter Clusters vertical connections
+    if ( ymax > 1 )
+    {
+        for ( size_t y = 0 ; y < (ymax-1) ; y++ )
+        {
+            for ( size_t x = 0 ; x < xmax ; x++ )
+            {
+                for ( size_t k = 0 ; k < 2 ; k++ )
+                {
+                clusters[x][y]->p_cmd_out[k][NORTH]     (signal_dspin_v_cmd_inc[x][y][k]);
+                clusters[x][y+1]->p_cmd_in[k][SOUTH]    (signal_dspin_v_cmd_inc[x][y][k]);
+                clusters[x][y]->p_cmd_in[k][NORTH]      (signal_dspin_v_cmd_dec[x][y][k]);
+                clusters[x][y+1]->p_cmd_out[k][SOUTH]   (signal_dspin_v_cmd_dec[x][y][k]);
+                clusters[x][y]->p_rsp_out[k][NORTH]     (signal_dspin_v_rsp_inc[x][y][k]);
+                clusters[x][y+1]->p_rsp_in[k][SOUTH]    (signal_dspin_v_rsp_inc[x][y][k]);
+                clusters[x][y]->p_rsp_in[k][NORTH]      (signal_dspin_v_rsp_dec[x][y][k]);
+                clusters[x][y+1]->p_rsp_out[k][SOUTH]   (signal_dspin_v_rsp_dec[x][y][k]);
+                }
+            }
+        }
+    }
+
+   std::cout << "Vertical connections established" << std::endl;
+
+    // East & West boundary cluster connections
+    for ( size_t y = 0 ; y < ymax ; y++ )
+    {
+        for ( size_t k = 0 ; k < 2 ; k++ )
+        {
+	    clusters[0][y]->p_cmd_in[k][WEST]       	(signal_dspin_false_cmd_in[0][y][k][WEST]);
+	    clusters[0][y]->p_cmd_out[k][WEST]      	(signal_dspin_false_cmd_out[0][y][k][WEST]);
+	    clusters[0][y]->p_rsp_in[k][WEST]       	(signal_dspin_false_rsp_in[0][y][k][WEST]);
+	    clusters[0][y]->p_rsp_out[k][WEST]      	(signal_dspin_false_rsp_out[0][y][k][WEST]);
+	  
+	    clusters[xmax-1][y]->p_cmd_in[k][EAST]  	(signal_dspin_false_cmd_in[xmax-1][y][k][EAST]);
+	    clusters[xmax-1][y]->p_cmd_out[k][EAST] 	(signal_dspin_false_cmd_out[xmax-1][y][k][EAST]);
+	    clusters[xmax-1][y]->p_rsp_in[k][EAST]  	(signal_dspin_false_rsp_in[xmax-1][y][k][EAST]);
+	    clusters[xmax-1][y]->p_rsp_out[k][EAST] 	(signal_dspin_false_rsp_out[xmax-1][y][k][EAST]);
+	}
+    }
+    
+    // North & South boundary clusters connections
+    for ( size_t x = 0 ; x < xmax ; x++ )
+    {
+        for ( size_t k = 0 ; k < 2 ; k++ )
+        {
+	    clusters[x][0]->p_cmd_in[k][SOUTH]      	(signal_dspin_false_cmd_in[x][0][k][SOUTH]);
+	    clusters[x][0]->p_cmd_out[k][SOUTH]     	(signal_dspin_false_cmd_out[x][0][k][SOUTH]);
+	    clusters[x][0]->p_rsp_in[k][SOUTH]      	(signal_dspin_false_rsp_in[x][0][k][SOUTH]);
+	    clusters[x][0]->p_rsp_out[k][SOUTH]     	(signal_dspin_false_rsp_out[x][0][k][SOUTH]);
+	    
+	    clusters[x][ymax-1]->p_cmd_in[k][NORTH] 	(signal_dspin_false_cmd_in[x][ymax-1][k][NORTH]);
+	    clusters[x][ymax-1]->p_cmd_out[k][NORTH]	(signal_dspin_false_cmd_out[x][ymax-1][k][NORTH]);
+	    clusters[x][ymax-1]->p_rsp_in[k][NORTH] 	(signal_dspin_false_rsp_in[x][ymax-1][k][NORTH]);
+	    clusters[x][ymax-1]->p_rsp_out[k][NORTH]	(signal_dspin_false_rsp_out[x][ymax-1][k][NORTH]);
+	}
+    }
+      
+    ////////////////////////////////////////////////////////
+    //   Simulation
+    ///////////////////////////////////////////////////////
+
+    sc_start(sc_core::sc_time(0, SC_NS));
+    signal_resetn = false;
+
+    // network boundaries signals
+    for(size_t x=0; x<xmax ; x++)
+    {
+        for(size_t y=0 ; y<ymax ; y++)
+        {
+            for (size_t k=0; k<2; k++)
+            {
+                for(size_t a=0; a<4; a++)
+                {
+		        signal_dspin_false_cmd_in[x][y][k][a].write = false;
+		        signal_dspin_false_cmd_in[x][y][k][a].read = true;
+                        signal_dspin_false_cmd_out[x][y][k][a].write = false;
+                        signal_dspin_false_cmd_out[x][y][k][a].read = true;
+
+                        signal_dspin_false_rsp_in[x][y][k][a].write = false;
+                        signal_dspin_false_rsp_in[x][y][k][a].read = true;
+                        signal_dspin_false_rsp_out[x][y][k][a].write = false;
+                        signal_dspin_false_rsp_out[x][y][k][a].read = true;
+		}
+            }
+        }
+    }
+
+    sc_start(sc_core::sc_time(1, SC_NS));
+    signal_resetn = true;
+
+    if (gettimeofday(&t1, NULL) != 0) 
+    {
+      perror("gettimeofday");
+      return EXIT_FAILURE;
+    }
+
+    while(1)
+    {
+      sc_start(sc_core::sc_time(100000000, SC_NS));
+
+      if (gettimeofday(&t2, NULL) != 0) 
+      {
+	perror("gettimeofday");
+	return EXIT_FAILURE;
+      }
+	    
+      ms1 = (uint64_t)t1.tv_sec * 1000ULL + (uint64_t)t1.tv_usec / 1000;
+      ms2 = (uint64_t)t2.tv_sec * 1000ULL + (uint64_t)t2.tv_usec / 1000;
+      
+      std::cerr << "platform clock frequency " << (double)100000000ULL / (double)(ms2 - ms1) << "Khz" << std::endl;
+	   
+      if (gettimeofday(&t1, NULL) != 0) 
+      {
+	perror("gettimeofday");
+	return EXIT_FAILURE;
+      }
+    }
+
+    return EXIT_SUCCESS;
+}
+
+int sc_main (int argc, char *argv[])
+{
+	try {
+		return _main(argc, argv);
+	} catch (std::exception &e) {
+		std::cout << e.what() << std::endl;
+	} catch (...) {
+		std::cout << "Unknown exception occured" << std::endl;
+		throw;
+	}
+	return 1;
+}
Index: trunk/platforms/almos-tsarv3-platforms/multi-clusters/tsarv4_cluster_xbar/caba/metadata/tsarv4_cluster_xbar.sd
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/multi-clusters/tsarv4_cluster_xbar/caba/metadata/tsarv4_cluster_xbar.sd	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/multi-clusters/tsarv4_cluster_xbar/caba/metadata/tsarv4_cluster_xbar.sd	(revision 259)
@@ -0,0 +1,85 @@
+
+# -*- python -*-
+
+Module('caba:tsarv4_cluster_xbar',
+	classname = 'soclib::caba::TsarV4ClusterXbar',
+	tmpl_parameters = [
+		parameter.Module('vci_param', default = 'caba:vci_param'),
+		parameter.Module('iss_t'),
+		parameter.Int('cmd_width'),
+		parameter.Int('rsp_width'),
+		],
+	header_files = [ '../source/include/tsarv4_cluster_xbar.h', ],
+	implementation_files = [ '../source/src/tsarv4_cluster_xbar.cpp', ],
+	uses = [
+		Uses('caba:base_module'),
+		Uses('common:mapping_table'),
+		Uses('common:iss2'),
+                Uses('config:config'),
+                Uses('caba:vci_cc_vcache_wrapper2_v1', iss_t = 'common:mips32el'),
+                #Uses('caba:vci_cc_xcache_wrapper_v4', iss_t = 'common:gdb_iss', gdb_iss_t = 'common:mips32el'),
+                #Uses('caba:vci_mem_cache_v4'),
+                Uses('caba:vci_mem_cache_v3'),
+            	Uses('caba:vci_simple_ram'),
+            	Uses('caba:vci_xicu'),
+            	Uses('caba:vci_local_crossbar'),
+            	Uses('caba:virtual_dspin_router', flit_width = parameter.Reference('cmd_width')),
+            	Uses('caba:virtual_dspin_router', flit_width = parameter.Reference('rsp_width')),
+                
+            	Uses('caba:vci_vdspin_target_wrapper',
+                     dspin_cmd_width = parameter.Reference('cmd_width'), 
+                     dspin_rsp_width = parameter.Reference('rsp_width')),
+
+            	Uses('caba:vci_vdspin_initiator_wrapper',
+                     dspin_cmd_width = parameter.Reference('cmd_width'), 
+                     dspin_rsp_width = parameter.Reference('rsp_width')),
+                
+                Uses('caba:vci_local_ring_fast',
+                     ring_cmd_data_size = parameter.Reference('cmd_width'),
+                     ring_rsp_data_size = parameter.Reference('rsp_width')),
+                
+		Uses('caba:vci_multi_tty'),
+		Uses('caba:vci_framebuffer'),
+                Uses('caba:vci_profiler'),
+                Uses('caba:vci_logger'),
+		Uses('caba:vci_block_device_tsar_v2'),
+		Uses('caba:vci_dma_tsar_v2'),
+		Uses('common:elf_file_loader'),
+		],
+        instance_parameters = [
+                parameter.Int('n_x'),
+                parameter.Int('n_y'),
+		parameter.Int('n_cluster'),
+		parameter.Module('mtd', 'common:mapping_table'),
+                parameter.Module('mtc', 'common:mapping_table'),
+		parameter.Module('mtx', 'common:mapping_table'),
+		parameter.Int('x_width'),
+		parameter.Int('y_width'),
+		parameter.Int('memc_tgtid'),
+		parameter.Int('xicu_tgtid'),
+		parameter.Int('fbuf_tgtid'),
+		parameter.Int('mtty_tgtid'),
+		parameter.Int('brom_tgtid'),
+		parameter.Int('bdev_tgtid'),
+		parameter.Int('cdma_tgtid'),
+		parameter.Int('memc_ways'),
+		parameter.Int('memc_sets'),
+		parameter.Int('l1_i_ways'),
+		parameter.Int('l1_i_sets'),
+		parameter.Int('l1_d_ways'),
+		parameter.Int('l1_d_sets'),
+                parameter.Int('xram_latency'),
+		parameter.Bool('io'),
+                ],
+
+	ports = [
+		Port('caba:bit_in', 'p_resetn', auto = 'resetn'),
+		Port('caba:clock_in', 'p_clk', auto = 'clock'),
+		Port('caba:dspin_output', 'p_cmd_out', [2, 4], dspin_data_size = parameter.Reference('cmd_width')),
+		Port('caba:dspin_input', 'p_cmd_in', [2, 4], dspin_data_size = parameter.Reference('cmd_width')),
+		Port('caba:dspin_output', 'p_rsp_out', [2, 4], dspin_data_size = parameter.Reference('rsp_width')), 
+                Port('caba:dspin_input', 'p_rsp_in', [2, 4], dspin_data_size = parameter.Reference('rsp_width')),
+		],
+)
+
+
Index: trunk/platforms/almos-tsarv3-platforms/multi-clusters/tsarv4_cluster_xbar/caba/source/include/tsarv4_cluster_xbar.h
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/multi-clusters/tsarv4_cluster_xbar/caba/source/include/tsarv4_cluster_xbar.h	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/multi-clusters/tsarv4_cluster_xbar/caba/source/include/tsarv4_cluster_xbar.h	(revision 259)
@@ -0,0 +1,233 @@
+//////////////////////////////////////////////////////////////////////////////
+// File: tsarv4_cluster_xbar.h
+// Author: Alain Greiner 
+// Copyright: UPMC/LIP6
+// Date : march 2011
+// This program is released under the GNU public license
+//////////////////////////////////////////////////////////////////////////////
+// This file define a TSAR cluster architecture without virtual memory,
+// - It uses the virtual_dspin_router  as distributed global interconnect 
+// - It uses the vci_local_crossbar as local interconnect 
+// - It uses the vci_cc_xcache_wrapper_v4
+// - It uses the vci_mem_cache_v4
+// - It contains a private RAM a variable latency to emulate the L3 cache
+// - It can contains 1, 2 or 4 processors
+// - Each processor has a private local TTY terminal (vci_multi_tty)
+// - Each processor has a private dma channel (vci_multi_dma)
+// - It uses the vci_xicu interrupt controller
+// - The nprocs tty irq are connected to IRQ_IN[0]...IRQ_IN[3]
+// - The nprocs dma irq are connected to IRQ_IN[4]...IRQ_IN[7]
+// - The peripherals BDEV, FBUF, and the boot BROM are in the cluster 
+//   containing address 0xBFC00000, and the bdev_irq is connected to IRQ_IN[8]
+////////////////////////////////////////////////////////////////////////////////// 
+
+#ifndef SOCLIB_CABA_TSAR_CLUSTER_V4_XBAR_H
+#define SOCLIB_CABA_TSAR_CLUSTER_V4_XBAR_H
+
+#include <systemc>
+#include <sys/time.h>
+#include <iostream>
+#include <sstream>
+#include <cstdlib>
+#include <cstdarg>
+
+//#include "gdbserver.h"
+#include "virtual_dspin_router.h"
+#include "mapping_table.h"
+#include "mips32.h"
+#include "vci_simple_ram.h"
+#include "vci_xicu.h"
+#include "vci_multi_tty.h"
+#include "vci_block_device_tsar_v2.h"
+#include "vci_framebuffer.h"
+#include "vci_dma_tsar_v2.h"
+#include "vci_logger.h"
+#include "config.h"
+
+#if USE_LOCAL_RING
+#include "vci_local_ring_fast.h"
+#else
+#include "vci_local_crossbar.h"
+#include "vci_vdspin_target_wrapper.h"
+#include "vci_vdspin_initiator_wrapper.h"
+#endif
+
+#if USE_MEMCACHE_V3
+#include "vci_mem_cache_v3.h"
+#include "vci_cc_vcache_wrapper2_v1.h"
+#endif
+
+#if USE_MEMCACHE_V4
+#include "vci_mem_cache_v4.h"
+#include "vci_cc_xcache_wrapper_v4.h"
+#endif
+
+
+#if !(USE_MEMCACHE_V3 ^ USE_MEMCACHE_V4)
+#error One version of TSAR memory system must be provieded (V3 or V4)
+#endif
+
+#if (USE_LOGGER_ON_CPUs && USE_PROFILER_ON_CPUs)
+#error Either Logger or Profiler can be used, you have to make a choice !
+#endif
+
+
+#if USE_PROFILER_ON_CPUs
+#include "vci_profiler.h"
+#endif
+
+namespace soclib {
+namespace caba	{
+
+///////////////////////////////////////////////////////////////////////////
+template<typename vci_param, typename iss_t, int cmd_width, int rsp_width>
+class TsarV4ClusterXbar 
+///////////////////////////////////////////////////////////////////////////
+    : public soclib::caba::BaseModule
+{
+
+  public:
+
+	// Ports
+    	sc_in<bool>                             		p_clk;
+    	sc_in<bool>                             		p_resetn;
+	soclib::caba::DspinOutput<cmd_width>   			**p_cmd_out;
+	soclib::caba::DspinInput<cmd_width>    			**p_cmd_in;
+        soclib::caba::DspinOutput<rsp_width>                   	**p_rsp_out;
+        soclib::caba::DspinInput<rsp_width>                   	**p_rsp_in;
+
+        // interrupt signals
+	sc_signal<bool>     		signal_false;
+	sc_signal<bool> 		signal_proc_it[4];
+	//sc_signal<bool> 		signal_irq_mdma[4];
+	sc_signal<bool> 		signal_irq_cdma;
+	sc_signal<bool>*    		signal_irq_mtty;
+	sc_signal<bool> 		signal_irq_bdev;
+	
+	// DSPIN signals between DSPIN routers and VCI/DSPIN wrappers
+	DspinSignals<cmd_width> 	signal_dspin_cmd_l2g_d; 
+	DspinSignals<cmd_width> 	signal_dspin_cmd_g2l_d; 
+	DspinSignals<cmd_width> 	signal_dspin_cmd_l2g_c;
+	DspinSignals<cmd_width> 	signal_dspin_cmd_g2l_c; 
+	DspinSignals<rsp_width> 	signal_dspin_rsp_l2g_d; 
+	DspinSignals<rsp_width> 	signal_dspin_rsp_g2l_d; 
+	DspinSignals<rsp_width> 	signal_dspin_rsp_l2g_c;
+	DspinSignals<rsp_width> 	signal_dspin_rsp_g2l_c;
+
+	// VCI signals between VCI/DSPIN wrappers and local crossbars
+	VciSignals<vci_param>  		signal_vci_l2g_d; 
+	VciSignals<vci_param>  		signal_vci_g2l_d; 
+	VciSignals<vci_param>  		signal_vci_l2g_c; 
+	VciSignals<vci_param>  		signal_vci_g2l_c; 
+
+	// Direct VCI signals
+	VciSignals<vci_param> 		signal_vci_ini_d_proc[4]; 
+	VciSignals<vci_param>  		signal_vci_ini_d_bdev; 
+	VciSignals<vci_param>  		signal_vci_ini_d_cdma; 
+
+	VciSignals<vci_param>		signal_vci_tgt_d_memc;
+	VciSignals<vci_param> 		signal_vci_tgt_d_mtty;
+	VciSignals<vci_param> 		signal_vci_tgt_d_xicu;
+	VciSignals<vci_param> 		signal_vci_tgt_d_bdev;
+	VciSignals<vci_param> 		signal_vci_tgt_d_cdma;
+	VciSignals<vci_param> 		signal_vci_tgt_d_brom;
+	VciSignals<vci_param> 		signal_vci_tgt_d_fbuf;
+
+	// Coherence VCi signals
+	VciSignals<vci_param> 		signal_vci_ini_c_proc[4];
+	VciSignals<vci_param> 		signal_vci_tgt_c_proc[4];
+	VciSignals<vci_param> 		signal_vci_ini_c_memc;
+	VciSignals<vci_param> 		signal_vci_tgt_c_memc;
+
+	// external RAM VCI signal
+	VciSignals<vci_param> 		signal_vci_xram;
+	
+        // Components
+
+#if USE_MEMCACHE_V4
+        VciCcXCacheWrapperV4<vci_param, iss_t>*                 	proc[4];
+        VciMemCacheV4<vci_param>*                               	memc;
+#endif
+
+#if USE_MEMCACHE_V3
+        VciCcVCacheWrapper2V1<vci_param, iss_t>*                        proc[4];
+        VciMemCacheV3<vci_param>*                                       memc;
+#endif
+
+#if USE_PROFILER_ON_CPUs
+	soclib::caba::VciProfiler<vci_param, iss_t> *profiler[4];
+#endif
+
+#if USE_LOGGER_ON_CPUs
+	VciLogger<vci_param> *vci_logger[10];
+#endif
+
+#if USE_LOGGER_ON_DMA
+	VciLogger<vci_param> *vci_dma_logger;
+#endif
+
+	VciXicu<vci_param>*                                     	xicu;
+
+#if USE_LOCAL_RING
+	VciLocalRingFast<vci_param,cmd_width,rsp_width>*                xbard;
+        VciLocalRingFast<vci_param,cmd_width,rsp_width>*                xbarc;
+#else
+        VciLocalCrossbar<vci_param>*        				xbard;
+        VciLocalCrossbar<vci_param>*        				xbarc;
+	VciVdspinTargetWrapper<vci_param,cmd_width,rsp_width>*		tgtwrapperd;
+        VciVdspinInitiatorWrapper<vci_param,cmd_width,rsp_width>*	iniwrapperd;
+        VciVdspinTargetWrapper<vci_param,cmd_width,rsp_width>*		tgtwrapperc;
+        VciVdspinInitiatorWrapper<vci_param,cmd_width,rsp_width>*	iniwrapperc;
+#endif
+	VirtualDspinRouter<cmd_width>*   	                	cmdrouter;
+        VirtualDspinRouter<rsp_width>*	                        	rsprouter;
+        VciSimpleRam<vci_param>*                 			brom;
+        VciMultiTty<vci_param>*                  			mtty;
+
+#if USE_FRAME_BUFFER
+        VciFrameBuffer<vci_param>*               			fbuf;
+#else
+	VciLogger<vci_param>*                   			fbuf;
+#endif
+
+        VciBlockDeviceTsarV2<vci_param>*         			bdev;
+	VciDmaTsarV2<vci_param>*                                        cdma;
+        VciSimpleRam<vci_param>*					xram;
+
+	TsarV4ClusterXbar(	sc_module_name  insname,
+                        size_t		nprocs,					// number of processors 
+			size_t		n_x,					// x coordinate
+			size_t		n_y,					// y coordinate
+			size_t		n_cluster,				// y + ymax*x
+			const 		soclib::common::MappingTable &mtd,	// direct mapping table
+			const		soclib::common::MappingTable &mtc,	// coherence mapping table
+			const		soclib::common::MappingTable &mtx,	// xram mapping table
+			size_t		x_width,				// x field number of bits
+			size_t		y_width,				// y field number of bits
+                        size_t		tgtid_memc,
+                        size_t		tgtid_xicu,
+                        size_t		tgtid_fbuf,
+                        size_t		tgtid_mtty,
+                        size_t		tgtid_brom,
+                        size_t		tgtid_bdev,
+                        size_t		tgtid_mdma,
+                        size_t		memc_ways,				// number of ways for MEMC
+                        size_t		memc_sets,				// number of sets for MEMC
+                        size_t		l1_i_ways,				// number of ways for L1 ICACHE
+                        size_t		l1_i_sets,				// number of sets for L1 ICACHE
+                        size_t		l1_d_ways,				// number of ways for L1 DCACHE
+                        size_t		l1_d_sets,				// number of sets for L1 DCACHE
+                        size_t		xram_latency,				// external ram latency
+			bool		io,					// I/O cluster if true
+                        size_t          xfb,					// frame buffer pixels
+                        size_t          yfb,					// frame buffer lines
+			size_t          fb_mode,                                // frame buffer subsampling mode
+                        char*           disk_name,				// virtual disk name for BDEV
+                        size_t          block_size,				// block size for BDEV
+                        const Loader    &loader);				// loader for BROM
+
+	~TsarV4ClusterXbar();
+};
+}}
+
+#endif
Index: trunk/platforms/almos-tsarv3-platforms/multi-clusters/tsarv4_cluster_xbar/caba/source/src/tsarv4_cluster_xbar.cpp
===================================================================
--- trunk/platforms/almos-tsarv3-platforms/multi-clusters/tsarv4_cluster_xbar/caba/source/src/tsarv4_cluster_xbar.cpp	(revision 259)
+++ trunk/platforms/almos-tsarv3-platforms/multi-clusters/tsarv4_cluster_xbar/caba/source/src/tsarv4_cluster_xbar.cpp	(revision 259)
@@ -0,0 +1,590 @@
+#include "../include/tsarv4_cluster_xbar.h"
+
+namespace soclib {
+namespace caba  {
+
+//////////////////////////////////////////////////////////////////////////
+//                 Constructor
+//////////////////////////////////////////////////////////////////////////
+template<typename vci_param, typename iss_t, int cmd_width, int rsp_width>
+TsarV4ClusterXbar<vci_param, iss_t, cmd_width, rsp_width>::TsarV4ClusterXbar(
+                        sc_module_name  insname,
+                        size_t          nprocs,
+                        size_t          x_id,
+                        size_t          y_id,
+                        size_t          cluster_id,
+                        const   	soclib::common::MappingTable &mtd,
+                        const   	soclib::common::MappingTable &mtc, 
+                        const   	soclib::common::MappingTable &mtx, 
+                        size_t          x_width,
+                        size_t          y_width,
+                        size_t		tgtid_memc,
+                        size_t		tgtid_xicu,
+                        size_t		tgtid_fbuf,
+                        size_t		tgtid_mtty,
+                        size_t		tgtid_brom,
+                        size_t		tgtid_bdev,
+                        size_t		tgtid_mdma,
+                        size_t		memc_ways,
+                        size_t		memc_sets,
+                        size_t		l1_i_ways,
+                        size_t		l1_i_sets,
+                        size_t		l1_d_ways,
+                        size_t		l1_d_sets,
+                        size_t		xram_latency,
+                        bool            io,
+                        size_t		xfb,
+                        size_t		yfb,
+                        size_t          fb_mode,
+                        char*		disk_name,
+                        size_t		block_size,
+                        const Loader	&loader)
+      : soclib::caba::BaseModule(insname),
+        p_clk("clk"),
+        p_resetn("resetn"),
+
+        signal_dspin_cmd_l2g_d("signal_dspin_cmd_l2g_d"),
+        signal_dspin_cmd_g2l_d("signal_dspin_cmd_g2l_d"),
+        signal_dspin_cmd_l2g_c("signal_dspin_cmd_l2g_c"),
+        signal_dspin_cmd_g2l_c("signal_dspin_cmd_g2l_c"),
+        signal_dspin_rsp_l2g_d("signal_dspin_rsp_l2g_d"),
+        signal_dspin_rsp_g2l_d("signal_dspin_rsp_g2l_d"),
+        signal_dspin_rsp_l2g_c("signal_dspin_rsp_l2g_c"),
+        signal_dspin_rsp_g2l_c("signal_dspin_rsp_g2l_c"),
+
+	signal_vci_ini_d_bdev("signal_vci_ini_d_bdev"),
+	signal_vci_ini_d_cdma("signal_vci_ini_d_cdma"),
+
+        signal_vci_tgt_d_memc("signal_vci_tgt_d_memc"),
+        signal_vci_tgt_d_mtty("signal_vci_tgt_d_mtty"),
+        signal_vci_tgt_d_xicu("signal_vci_tgt_d_xicu"),
+        signal_vci_tgt_d_bdev("signal_vci_tgt_d_bdev"),
+        signal_vci_tgt_d_cdma("signal_vci_tgt_d_cdma"),
+        signal_vci_tgt_d_brom("signal_vci_tgt_d_brom"),
+        signal_vci_tgt_d_fbuf("signal_vci_tgt_d_fbuf"),
+
+        signal_vci_ini_c_memc("signal_vci_ini_c_memc"), 
+        signal_vci_tgt_c_memc("signal_vci_tgt_c_memc"),
+
+        signal_vci_xram("signal_vci_xram")
+
+{
+        // Vectors of ports definition
+
+        p_cmd_in        = alloc_elems<DspinInput<cmd_width> >("p_cmd_in", 2, 4);
+        p_cmd_out       = alloc_elems<DspinOutput<cmd_width> >("p_cmd_out", 2, 4);
+        p_rsp_in        = alloc_elems<DspinInput<rsp_width> >("p_rsp_in", 2, 4);
+        p_rsp_out       = alloc_elems<DspinOutput<rsp_width> >("p_rsp_out", 2, 4);
+	
+        // Components definition 
+
+        // on direct network : local srcid[proc] in [0...nprocs-1]
+        // on direct network : local srcid[mdma] = nprocs
+        // on direct network : local srcid[bdev] = nprocs + 1
+
+        // on coherence network : local srcid[proc] in [0...nprocs-1]
+	// on coherence network : local srcid[memc] = nprocs
+
+std::cout << "  - building proc_" << x_id << "_" << y_id << "-*" << std::endl;
+
+        for ( size_t p=0 ; p<nprocs ; p++ )
+        { 
+	  std::ostringstream sproc;
+	  sproc << "proc_" << x_id << "_" << y_id << "_" << p;
+
+#if USE_MEMCACHE_V4
+            proc[p] = new VciCcXCacheWrapperV4<vci_param, iss_t>(
+                sproc.str().c_str(),
+                cluster_id*nprocs + p,
+                mtd,				// Mapping Table Direct
+                mtc,				// Mapping Table Coherence
+                IntTab(cluster_id,p),    	// SRCID_D
+                IntTab(cluster_id,p),    	// SRCID_C
+                IntTab(cluster_id,p),    	// TGTID_C
+                1,				// single core
+                1,				// single dcache
+                l1_i_ways,l1_i_sets,16,  	// ICACHE size
+                l1_d_ways,l1_d_sets,16,      	// DCACHE size
+                4,				// WBUF width
+                8 				// WBUF depth
+                );
+#endif	// USE_MEMCACHE_V4
+
+#if USE_MEMCACHE_V3
+	    proc[p] = new VciCcVCacheWrapper2V1<vci_param, iss_t>(
+								  sproc.str().c_str(),
+								  cluster_id*nprocs + p,
+								  mtd, mtc,
+								  IntTab(cluster_id,p),     // SRCID_D
+								  IntTab(cluster_id,p),     // SRCID_C
+								  IntTab(cluster_id,p),     // TGTID_C
+								  TLB_IWAYS,TLB_ISETS,TLB_DWAYS,TLB_DSETS,
+								  l1_i_ways,l1_i_sets,16,
+								  l1_d_ways,l1_d_sets,16,
+								  16);      // TLB, Icache and Dcache sizes
+#endif	// USE_MEMCACHE_V3
+
+#if USE_PROFILER_ON_CPUs
+	    std::ostringstream sp;
+	    sp << "profiler_" << x_id << "_" << y_id << "-" << p;
+	    
+	    profiler[p] = new VciProfiler <vci_param, iss_t> (sp.str().c_str(), 
+							      cluster_id,
+							      x_id,
+							      y_id,
+							      x_width,
+							      y_width, 
+							      CONFIG_ADDRESS_WIDTH);
+	    profiler[p]->p_clk                  (this->p_clk);
+	    profiler[p]->p_resetn               (this->p_resetn);
+	    profiler[p]->p_vci                  (signal_vci_ini_d_proc[p]);
+	    profiler[p]->set_L1_cache(proc[p]);
+#endif	// USE_PROFILER_ON_CPUs
+
+#if USE_LOGGER_ON_CPUs
+	    std::ostringstream sp2;
+	    sp2 << "logger_" << x_id << "_" << y_id << "-" << p;
+	    vci_logger[p] = new VciLogger <vci_param> (sp2.str().c_str(), mtd);
+	    vci_logger[p]->p_clk    (this->p_clk);
+	    vci_logger[p]->p_resetn (this->p_resetn);
+	    vci_logger[p]->p_vci (signal_vci_ini_d_proc[p]);
+#endif	// USE_LOGGER_ON_CPUs
+
+        } // for on CPUs number
+
+std::cout << "  - building memc_" << x_id << "_" << y_id << std::endl;
+
+        std::ostringstream smemc;
+        smemc << "memc_" << x_id << "_" << y_id;
+
+#if USE_MEMCACHE_V4
+        memc = new VciMemCacheV4<vci_param>(
+                   smemc.str().c_str(),
+                   mtd, mtc, mtx,
+                   IntTab(cluster_id),           	// SRCID_X
+                   IntTab(cluster_id, nprocs),   	// SRCID_C
+                   IntTab(cluster_id, tgtid_memc),	// TGTID_D
+                   IntTab(cluster_id, nprocs),   	// TGTID_C
+                   memc_ways, memc_sets, 16,	 	// CACHE SIZE
+                   4096,     			 	// HEAP SIZE
+                   8,					// TRANSACTION TABLE DEPTH
+                   8);					// UPDATE TABLE DEPTH
+#endif
+
+#if USE_MEMCACHE_V3
+	memc = new VciMemCacheV3<vci_param>(
+					    smemc.str().c_str(),
+					    mtd, mtc, mtx,
+					    IntTab(cluster_id),                   	// SRCID_X
+					    IntTab(cluster_id, nprocs),           	// SRCID_C
+					    IntTab(cluster_id, tgtid_memc),        	// TGTID_D
+					    IntTab(cluster_id, nprocs),           	// TGTID_C
+					    memc_ways, memc_sets, 16,
+					    4096); 
+#endif	// USE_MEMCACHE_V3
+
+        
+std::cout << "  - building xram_" << x_id << "_" << y_id << std::endl;
+
+        std::ostringstream sxram;
+        sxram << "xram_" << x_id << "_" << y_id;
+        xram = new VciSimpleRam<vci_param>(
+                   sxram.str().c_str(),
+                   IntTab(cluster_id),
+                   mtx,
+                   loader,
+                   xram_latency);
+
+std::cout << "  - building xicu_" << x_id << "_" << y_id << std::endl;
+
+        //size_t  nhwi = 8;				// always 8 (or 9) ports, even if 
+        //if( io == true ) nhwi = 9;			// there if less than 4 processors
+
+
+         size_t   nhwi = 0;
+	 if(io == true) nhwi = 6;
+
+        std::ostringstream sicu;
+        sicu << "xicu_" << x_id << "_" << y_id;
+        xicu = new VciXicu<vci_param>(
+                  sicu.str().c_str(),
+                  mtd,				  	// mapping table
+                  IntTab(cluster_id, tgtid_xicu),  	// TGTID_D
+                  nprocs,				// number of timer IRQs
+                  nhwi,                          	// number of hard IRQs
+                  nprocs,				// number of soft IRQs
+                  nprocs);				// number of output IRQs
+
+std::cout << "  - building xbard_" << x_id << "_" << y_id << std::endl;
+
+        // direct local crossbar
+        size_t nb_direct_initiators      = nprocs;
+        size_t nb_direct_targets         = 2;
+
+        if( io == true )
+        {
+            nb_direct_initiators         = nprocs + 2;
+            nb_direct_targets            = 7;
+	}
+
+        std::ostringstream sd;
+        sd << "xbard_" << x_id << "_" << y_id;
+
+#if USE_LOCAL_RING
+	xbard = new VciLocalRingFast<vci_param,cmd_width,rsp_width>(
+		    sd.str().c_str(),
+		    mtd,
+		    IntTab(cluster_id),              // cluster index
+		    4,                               // wrapper fifo depth
+		    18,                              // gateway fifo depth
+		    nb_direct_initiators ,           // number of initiators
+		    nb_direct_targets);              // number of targets			
+#else
+        xbard = new VciLocalCrossbar<vci_param>(
+                    sd.str().c_str(),
+                    mtd,
+                    IntTab(cluster_id),              	// cluster initiator index
+                    IntTab(cluster_id),              	// cluster target index
+                    nb_direct_initiators,           	// number of initiators
+                    nb_direct_targets);             	// number of targets      
+#endif // USE_LOCAL_RING
+
+        
+std::cout << "  - building xbarc_" << x_id << "_" << y_id << std::endl;
+
+        // coherence local crossbar
+        std::ostringstream sc;
+        sc << "xbarc_" << x_id << "_" << y_id;
+
+#if USE_LOCAL_RING
+        xbarc = new VciLocalRingFast<vci_param,cmd_width,rsp_width>(
+		     sc.str().c_str(),
+		     mtc,
+		     IntTab(cluster_id),                   	// cluster index
+		     4,                                      	// wrapper fifo depth
+		     18,                                     	// gateway fifo depth
+		     nprocs + 1,                               	// number of initiators
+		     nprocs + 1);                              	// number of targets
+	
+#else
+        xbarc = new VciLocalCrossbar<vci_param>(
+                    sc.str().c_str(),
+                    mtc,
+                    IntTab(cluster_id),                	// cluster initiator index
+                    IntTab(cluster_id),                	// cluster target index
+                    nprocs + 1,                		// number of initiators
+                    nprocs + 1);               		// number of targets
+#endif  // USE_LOCAL_RING 
+
+#if !(USE_LOCAL_RING)
+std::cout << "  - building wrappers in cluster_" << x_id << "_" << y_id << std::endl;
+
+        // direct initiator wrapper
+        std::ostringstream wid;
+        wid << "iniwrapperd_" << x_id << "_" << y_id;
+        iniwrapperd = new VciVdspinInitiatorWrapper<vci_param,cmd_width,rsp_width>(
+                          wid.str().c_str(),
+                          4,				// cmd fifo depth
+                          4);				// rsp fifo depth
+
+        // direct target wrapper
+        std::ostringstream wtd;
+        wtd << "tgtwrapperd_" << x_id << "_" << y_id;
+        tgtwrapperd = new VciVdspinTargetWrapper<vci_param,cmd_width,rsp_width>(
+                          wtd.str().c_str(),
+                          4,				// cmd fifo depth
+                          4);				// rsp fifo depth
+
+        // coherence initiator wrapper
+        std::ostringstream wic;
+        wic << "iniwrapperc_" << x_id << "_" << y_id;
+        iniwrapperc = new VciVdspinInitiatorWrapper<vci_param,cmd_width,rsp_width>(
+                          wic.str().c_str(),
+                          4,				// cmd fifo depth
+                          4);				// rsp fifo depth
+
+        // coherence target wrapper
+        std::ostringstream wtc;
+        wtc << "tgtwrapperc_" << x_id << "_" << y_id;
+        tgtwrapperc = new VciVdspinTargetWrapper<vci_param,cmd_width,rsp_width>(
+                          wtc.str().c_str(),
+                          4,				// cmd fifo depth
+                          4);				// rsp fifo depth
+#endif	// !(USE_LOCAL_RING)
+
+std::cout << "  - building cmdrouter_" << x_id << "_" << y_id << std::endl;
+
+        // CMD router
+        std::ostringstream scmd;
+        scmd << "cmdrouter_" << x_id << "_" << y_id;
+        cmdrouter = new VirtualDspinRouter<cmd_width>(
+                        scmd.str().c_str(),
+                        x_id,y_id,                    // coordinate in the mesh
+                        x_width, y_width,             // x & y fields width
+                        4,4);                         // input & output fifo depths
+        
+std::cout << "  - building rsprouter_" << x_id << "_" << y_id << std::endl;
+
+        // RSP router
+        std::ostringstream srsp;
+        srsp << "rsprouter_" << x_id << "_" << y_id;
+        rsprouter = new VirtualDspinRouter<rsp_width>(
+                        srsp.str().c_str(),
+                        x_id,y_id,                    // coordinates in mesh
+                        x_width, y_width,             // x & y fields width
+                        4,4);                         // input & output fifo depths
+        
+        // IO cluster components
+        if ( io == true )
+	{
+            brom = new VciSimpleRam<vci_param>(
+                       "brom",
+                       IntTab(cluster_id, tgtid_brom),
+                       mtd,
+                       loader);
+
+#if USE_FRAME_BUFFER
+            fbuf = new VciFrameBuffer<vci_param>(
+                       "fbuf",
+                       IntTab(cluster_id, tgtid_fbuf),
+                       mtd,
+		       xfb, 
+		       yfb,
+		       fb_mode); 
+#else
+	    std::ostringstream sf;
+	    sd << "fb_logger__" << x_id << "_" << y_id;
+	    fbuf = new VciLogger <vci_param> (sd.str().c_str(), mtd);
+#endif
+
+	    cdma = new VciDmaTsarV2<vci_param>(
+		      "cdma", 
+		      mtd, 
+		      IntTab(cluster_id, nprocs),
+		      IntTab(cluster_id, tgtid_mdma),
+		      64);
+
+#if USE_LOGGER_ON_DMA
+	    std::ostringstream sd;
+	    sd << "dma_logger_" << x_id << "_" << y_id;
+	    vci_dma_logger = new VciLogger <vci_param> (sd.str().c_str(), mtd);
+	    vci_dma_logger->p_clk    (this->p_clk);
+	    vci_dma_logger->p_resetn (this->p_resetn);
+	    vci_dma_logger->p_vci (signal_vci_ini_d_cdma);
+#endif	// USE_LOGGER_ON_DMA
+
+	    bdev = new VciBlockDeviceTsarV2<vci_param>(
+                       "bdev",
+                       mtd,
+                       IntTab(cluster_id, nprocs+1),
+                       IntTab(cluster_id, tgtid_bdev),
+                       disk_name,
+                       block_size);
+
+	    // tty
+	    signal_irq_mtty = alloc_elems<sc_signal<bool> >("signal_irq_mtty", 4);
+
+	    std::ostringstream stty;
+	    stty << "tty_" << x_id << "_" << y_id;
+	    mtty = new VciMultiTty<vci_param>(
+					      stty.str().c_str(),
+					      IntTab(cluster_id, tgtid_mtty),
+					      mtd, "tty0", "tty1", "tty2", "tty3", NULL);
+	}
+
+std::cout << "  - all components constructed" << std::endl;
+
+        ////////////////////////////////////
+        // Connections are defined here
+        ////////////////////////////////////
+
+        // CMDROUTER and RSPROUTER
+        cmdrouter->p_clk                	(this->p_clk);
+        cmdrouter->p_resetn             	(this->p_resetn);
+        rsprouter->p_clk                	(this->p_clk);
+        rsprouter->p_resetn             	(this->p_resetn);
+        for(int x = 0; x < 2; x++)
+        {
+          for(int y = 0; y < 4; y++)
+          {
+            cmdrouter->p_out[x][y]              (this->p_cmd_out[x][y]);
+            cmdrouter->p_in[x][y]               (this->p_cmd_in[x][y]);
+            rsprouter->p_out[x][y]              (this->p_rsp_out[x][y]);
+            rsprouter->p_in[x][y]               (this->p_rsp_in[x][y]);
+          }
+        }
+        
+        cmdrouter->p_out[0][4]  		(signal_dspin_cmd_g2l_d);
+        cmdrouter->p_out[1][4]  		(signal_dspin_cmd_g2l_c);
+        cmdrouter->p_in[0][4]   		(signal_dspin_cmd_l2g_d);
+        cmdrouter->p_in[1][4]   		(signal_dspin_cmd_l2g_c);
+
+        rsprouter->p_out[0][4]  		(signal_dspin_rsp_g2l_d);
+        rsprouter->p_out[1][4]  		(signal_dspin_rsp_g2l_c);
+        rsprouter->p_in[0][4]   		(signal_dspin_rsp_l2g_d);
+        rsprouter->p_in[1][4]   		(signal_dspin_rsp_l2g_c);
+
+#if !(USE_LOCAL_RING)
+        // VCI/DSPIN WRAPPERS
+        iniwrapperd->p_clk			(this->p_clk);
+        iniwrapperd->p_resetn			(this->p_resetn);
+	iniwrapperd->p_vci			(signal_vci_l2g_d);
+	iniwrapperd->p_dspin_out		(signal_dspin_cmd_l2g_d);
+	iniwrapperd->p_dspin_in			(signal_dspin_rsp_g2l_d);
+
+        tgtwrapperd->p_clk			(this->p_clk);
+        tgtwrapperd->p_resetn			(this->p_resetn);
+	tgtwrapperd->p_vci			(signal_vci_g2l_d);
+	tgtwrapperd->p_dspin_out		(signal_dspin_rsp_l2g_d);
+	tgtwrapperd->p_dspin_in			(signal_dspin_cmd_g2l_d);
+
+        iniwrapperc->p_clk			(this->p_clk);
+        iniwrapperc->p_resetn			(this->p_resetn);
+	iniwrapperc->p_vci			(signal_vci_l2g_c);
+	iniwrapperc->p_dspin_out		(signal_dspin_cmd_l2g_c);
+	iniwrapperc->p_dspin_in			(signal_dspin_rsp_g2l_c);
+
+        tgtwrapperc->p_clk			(this->p_clk);
+        tgtwrapperc->p_resetn			(this->p_resetn);
+	tgtwrapperc->p_vci			(signal_vci_g2l_c);
+	tgtwrapperc->p_dspin_out		(signal_dspin_rsp_l2g_c);
+	tgtwrapperc->p_dspin_in			(signal_dspin_cmd_g2l_c);
+#endif
+
+        // CROSSBAR direct
+        xbard->p_clk                  		(this->p_clk);
+        xbard->p_resetn                 	(this->p_resetn);
+
+#if USE_LOCAL_RING
+	xbard->p_gate_cmd_out                   (signal_dspin_cmd_l2g_d);
+        xbard->p_gate_cmd_in                    (signal_dspin_cmd_g2l_d);
+        xbard->p_gate_rsp_out                   (signal_dspin_rsp_l2g_d);
+        xbard->p_gate_rsp_in                    (signal_dspin_rsp_g2l_d);
+#else
+        xbard->p_initiator_to_up        	(signal_vci_l2g_d);
+        xbard->p_target_to_up           	(signal_vci_g2l_d);
+#endif     
+        xbard->p_to_target[tgtid_memc]  	(signal_vci_tgt_d_memc);
+        xbard->p_to_target[tgtid_xicu]  	(signal_vci_tgt_d_xicu);          
+        
+        for ( size_t p=0 ; p<nprocs ; p++)
+            xbard->p_to_initiator[p]		(signal_vci_ini_d_proc[p]);
+
+	if ( io == true )
+	{
+            xbard->p_to_target[tgtid_brom]  	(signal_vci_tgt_d_brom);
+            xbard->p_to_target[tgtid_bdev]  	(signal_vci_tgt_d_bdev);
+            xbard->p_to_target[tgtid_fbuf]  	(signal_vci_tgt_d_fbuf);
+	    xbard->p_to_target[tgtid_mtty]  	(signal_vci_tgt_d_mtty);
+	    xbard->p_to_target[tgtid_mdma]  	(signal_vci_tgt_d_cdma);
+
+	    xbard->p_to_initiator[nprocs]  	(signal_vci_ini_d_cdma);
+            xbard->p_to_initiator[nprocs+1]  	(signal_vci_ini_d_bdev);
+	}
+        
+        // CROSSBAR coherence
+        xbarc->p_clk                    	(this->p_clk);
+        xbarc->p_resetn                 	(this->p_resetn);
+
+#if USE_LOCAL_RING
+	xbarc->p_gate_cmd_out                   (signal_dspin_cmd_l2g_c);
+        xbarc->p_gate_cmd_in                    (signal_dspin_cmd_g2l_c);
+        xbarc->p_gate_rsp_out                   (signal_dspin_rsp_l2g_c);
+        xbarc->p_gate_rsp_in                    (signal_dspin_rsp_g2l_c);
+#else
+        xbarc->p_initiator_to_up        	(signal_vci_l2g_c);
+        xbarc->p_target_to_up           	(signal_vci_g2l_c);
+#endif
+        xbarc->p_to_initiator[nprocs]  		(signal_vci_ini_c_memc);
+        xbarc->p_to_target[nprocs]     		(signal_vci_tgt_c_memc);
+
+        for ( size_t p=0 ; p<nprocs ; p++)
+        {
+            xbarc->p_to_target[p]       	(signal_vci_tgt_c_proc[p]);
+            xbarc->p_to_initiator[p]    	(signal_vci_ini_c_proc[p]);
+        }
+
+        // Processors
+        for ( size_t p=0 ; p<nprocs ; p++)
+        {
+            proc[p]->p_clk              	(this->p_clk);
+            proc[p]->p_resetn           	(this->p_resetn);
+            proc[p]->p_vci_ini_rw       	(signal_vci_ini_d_proc[p]);
+            proc[p]->p_vci_ini_c        	(signal_vci_ini_c_proc[p]);
+            proc[p]->p_vci_tgt          	(signal_vci_tgt_c_proc[p]);
+            proc[p]->p_irq[0]           	(signal_proc_it[p]);
+
+            for ( size_t j = 1 ; j < 6 ; j++ )
+                proc[p]->p_irq[j]       	(signal_false);
+        }
+        
+        // XICU
+        xicu->p_clk                     	(this->p_clk);
+        xicu->p_resetn                  	(this->p_resetn);
+        xicu->p_vci                     	(signal_vci_tgt_d_xicu);
+
+        for ( size_t p=0 ; p<nprocs ; p++)
+	  xicu->p_irq[p]              	(signal_proc_it[p]);
+	
+        // MEMC
+        memc->p_clk                     	(this->p_clk);
+        memc->p_resetn                  	(this->p_resetn);
+        memc->p_vci_ixr                 	(signal_vci_xram);
+        memc->p_vci_tgt                 	(signal_vci_tgt_d_memc);
+        memc->p_vci_ini                 	(signal_vci_ini_c_memc);
+        memc->p_vci_tgt_cleanup         	(signal_vci_tgt_c_memc);
+
+        // XRAM
+        xram->p_clk                     	(this->p_clk);
+        xram->p_resetn                  	(this->p_resetn);
+        xram->p_vci                 		(signal_vci_xram);
+
+	// Components in IO cluster
+	if ( io == true )
+	{
+        	// BDEV            
+		bdev->p_clk                      (this->p_clk);
+        	bdev->p_resetn                   (this->p_resetn);
+        	bdev->p_irq                      (signal_irq_bdev);
+        	bdev->p_vci_target               (signal_vci_tgt_d_bdev);
+        	bdev->p_vci_initiator            (signal_vci_ini_d_bdev);
+
+        	// FBUF
+        	fbuf->p_clk                       (this->p_clk);
+        	fbuf->p_resetn                    (this->p_resetn);
+        	fbuf->p_vci                       (signal_vci_tgt_d_fbuf);
+
+        	// BROM
+        	brom->p_clk                       (this->p_clk);
+        	brom->p_resetn                    (this->p_resetn);
+        	brom->p_vci                       (signal_vci_tgt_d_brom);
+		
+		// MTTY
+		mtty->p_clk                       (this->p_clk);
+		mtty->p_resetn                    (this->p_resetn);
+		mtty->p_vci                       (signal_vci_tgt_d_mtty);
+		for(size_t i=0 ; i<4 ; i++)
+		  mtty->p_irq[i]                   (signal_irq_mtty[i]);
+
+		// CDMA
+		cdma->p_clk                       (this->p_clk);
+		cdma->p_resetn                    (this->p_resetn);
+		cdma->p_irq                       (signal_irq_cdma);
+		cdma->p_vci_target                (signal_vci_tgt_d_cdma);
+		cdma->p_vci_initiator             (signal_vci_ini_d_cdma);
+
+		xicu->p_hwi[0]             (signal_irq_bdev);
+		xicu->p_hwi[1]             (signal_irq_cdma);
+		
+		for(size_t i=0 ; i<4 ; i++)
+		  xicu->p_hwi[2+i]        (signal_irq_mtty[i]);
+        }
+} // end constructor
+
+///////////////////////////////////////////////////////////////////////////
+//    destructor
+///////////////////////////////////////////////////////////////////////////
+template<typename vci_param, typename iss_t, int cmd_width, int rsp_width>
+TsarV4ClusterXbar<vci_param, iss_t, cmd_width, rsp_width>::~TsarV4ClusterXbar() {}
+
+}}
