diff --git a/MPSoC/soclib/soclib/lib/mapping_table/include/int_tab.h b/MPSoC/soclib/soclib/lib/mapping_table/include/int_tab.h
index 0edf8c8e56b6ad1fe2fabadf02aba02c434b3b50..3dcdc3af62707d5d5395807192b3009a397c4a90 100644
--- a/MPSoC/soclib/soclib/lib/mapping_table/include/int_tab.h
+++ b/MPSoC/soclib/soclib/lib/mapping_table/include/int_tab.h
@@ -30,6 +30,7 @@
 
 #include <vector>
 #include "exception.h"
+#include <cstdlib>
 
 namespace soclib { namespace common {
 
@@ -126,7 +127,8 @@ private:
                 return;
             }
         }
-        throw soclib::exception::ValueError("Too much levels");
+        std::cout << "ERROR IntTab.init() function : Too much levels" << std::endl;
+        exit(0);
     }
 
 public:
@@ -134,7 +136,10 @@ public:
     value_t operator[]( size_t level ) const
     {
         if ( level > m_level )
-            throw soclib::exception::ValueError("Level out of bounds");
+        {
+            std::cout << "ERROR IntTab.[] operator : level too large" << std::endl;
+            exit(0);
+        }
         return m_values[level];
     }
 
@@ -142,7 +147,10 @@ public:
     value_t operator*( const IntTab &widths ) const
     {
         if ( widths.level() != m_level )
-            throw soclib::exception::ValueError("Levels not matching");
+        {
+            std::cout << "ERROR IntTab.* operator : levels not matching" << std::endl;
+            exit(0);
+        }
         value_t ret = 0;
 
         for ( size_t l=0; l<m_level; ++l ) {
diff --git a/MPSoC/soclib/soclib/lib/mapping_table/include/mapping_table.h b/MPSoC/soclib/soclib/lib/mapping_table/include/mapping_table.h
index 0b4da1542f83819fc1a6158585ddb2b02da6654d..07dc85ca7e90b7d6094d10cb334a270fcf2cd2e1 100644
--- a/MPSoC/soclib/soclib/lib/mapping_table/include/mapping_table.h
+++ b/MPSoC/soclib/soclib/lib/mapping_table/include/mapping_table.h
@@ -21,12 +21,22 @@
  * SOCLIB_LGPL_HEADER_END
  *
  * Copyright (c) UPMC, Lip6, Asim
- *         Nicolas Pouillon <nipo@ssji.net>, 2007
+ *         Alain Greiner <alain.greiner@lip6.fr> 2005 
+ *         Nicolas Pouillon <nipo@ssji.net> 2007
+ *         Alain Greiner <alain.greiner@lip6.fr> 2013
  *
- * Based on previous works by Francois Pecheux & Alain Greiner
- *
- * Maintainers: nipo
+ * Maintainers: alain
  */
+
+/////////////////////////////////////////////////////////////////////////
+// Implementation Note (October 2013)
+// 1) Regarding the various ADDRESS or SRCID decoding tables:
+//   - ADDRESSES values are supposed to use uint64_t type
+//   - SRCID values     are supposed to use uint32_t type
+// 2) Regarding SRCID decoding, the m_srcid[array] is always used.
+//    Identity mapping is handled as a default value in this array.
+/////////////////////////////////////////////////////////////////////////
+
 #ifndef SOCLIB_MAPPING_TABLE_H
 #define SOCLIB_MAPPING_TABLE_H
 
@@ -45,66 +55,79 @@ namespace soclib { namespace common {
 class MappingTable
 //////////////////////////////////////
 {
-public:
-    typedef uint64_t addr64_t;
-    typedef uint32_t addr32_t;
 
 private:
     std::list<soclib::common::Segment> m_segment_list;     // list of all segments
-    size_t                             m_addr_width;       // address width 
-    addr64_t                           m_addr_mask;
-    IntTab                             m_level_addr_bits;  // number of bits per level (addr)
-    IntTab                             m_level_id_bits;    // number of bits per level (srcid)
-    addr64_t                           m_cacheability_mask;
-    addr64_t                           m_rt_size;          // max segment size for 1 target
+    size_t                             m_addr_width;       // number of bits
+    size_t                             m_srcid_width;      // number of bits
+    uint64_t                           m_addr_mask;
+    IntTab                             m_level_addr_bits;  // nb  bits per level (addr)
+    IntTab                             m_level_id_bits;    // nb  bits per level (srcid)
+    uint64_t                           m_cacheability_mask;
+    uint64_t                           m_rt_size;          // max segment size for 1 target
     bool                               m_used;             // no more modif when true
     size_t*                            m_srcid_array;      // array indexed by srcid,
-                                                           // and containing local port index
+                                                           // containing local port index
 
 public:
     MappingTable( const MappingTable& );
+
     const MappingTable &operator=( const MappingTable & );
 
     MappingTable( size_t           addr_width,
                   const IntTab     &level_addr_bits,
                   const IntTab     &level_id_bits,
-                  const addr64_t   cacheability_mask );
+                  const uint64_t   cacheability_mask );
     
     ~MappingTable();
 
+    //////////////////////////////////////////////
     void add( const soclib::common::Segment &seg );
 
-    void srcid_map( const IntTab &srcid, size_t portid );
+    ////////////////////////////////////////////////////
+    void srcid_map( const IntTab &srcid, 
+                    const IntTab &portid );
 
+    ///////////////////////////////////////////////////////////////
     std::list<Segment> getSegmentList( const IntTab &index ) const;
 
+    ////////////////////////////////////////////////////
     const std::list<Segment> &getAllSegmentList() const;
 
+    ////////////////////////////////////////////////////////////////
     soclib::common::Segment getSegment( const IntTab &index ) const;
 
-    template<typename desired_addr_t>
-    AddressDecodingTable<desired_addr_t, bool> 
-    getCacheabilityTable() const;
-
-    template<typename desired_addr_t>
-    AddressDecodingTable<desired_addr_t, bool> 
-    getLocalityTable( const IntTab &index ) const;
-
-    template<typename desired_addr_t>
-    AddressDecodingTable<desired_addr_t, int> 
-    getRoutingTable( const IntTab &index, int default_index = 0 ) const;
-    
+    //////////////////////////////////////
     AddressDecodingTable<uint64_t, size_t>
-    getPortidFromAddress( const size_t cluster_id, const size_t default_id = 0 ) const;
+    getLocalIndexFromAddress( const size_t cluster_id, 
+                              const size_t default_id = 0 ) const;
 
-    AddressDecodingTable<uint64_t, size_t>
-    getPortidFromSrcid( const size_t cluster_id ) const;
+    ///////////////////////////////////////
+    AddressDecodingTable<uint32_t, size_t>
+    getLocalIndexFromSrcid( const size_t cluster_id ) const;
 
+    /////////////////////////////////////
+    AddressDecodingTable<uint64_t, bool> 
+    getLocalMatchFromAddress( const size_t cluster_id ) const;
+
+    /////////////////////////////////////
     AddressDecodingTable<uint32_t, bool> 
-    getIdLocalityTable( const IntTab &index ) const;
+    getLocalMatchFromSrcid( const size_t cluster_id ) const;
+
+    //////////////////////////////////////
+    AddressDecodingTable<uint64_t, size_t> 
+    getGlobalIndexFromAddress( const size_t default_id = 0 ) const;
+    
+    //////////////////////////////////////
+    AddressDecodingTable<uint32_t, size_t> 
+    getGlobalIndexFromSrcid() const;
+    
+    ////////////////////////////////////
+    AddressDecodingTable<uint64_t, bool> 
+    getCacheabilityTable() const;
 
-    AddressMaskingTable<uint32_t> 
-    getIdMaskingTable( const int level ) const;
+    ////////////////////////////////////
+    void print( std::ostream &o ) const;
 
     //////////////////////////////
     size_t getAddressWidth() const
@@ -112,7 +135,10 @@ public:
         return m_addr_width;
     }
 
-    void print( std::ostream &o ) const;
+    inline const IntTab& getSrcidLevelBits() const
+    {
+        return m_level_id_bits;
+    }
 
     //////////////////////////////////////////////////////////////////////////
     friend std::ostream &operator << (std::ostream &o, const MappingTable &mt)
@@ -121,14 +147,9 @@ public:
         return o;
     }
 
-    ///////////////////////////////////////////////////////////
-    inline unsigned int indexForId( const IntTab &index ) const
+    /////////////////////////////////////////////////////
+    inline size_t indexForId( const IntTab &index ) const
     {
-    //DG 24.10.2016
-
-     std::cout << " index : " << index << std::endl;
-     std::cout << " m_level_id_bits : " << m_level_id_bits << std::endl;
-     std::cout << " index*m_level_id_bits: " << index*m_level_id_bits << std::endl;
         return index*m_level_id_bits;
     }
 
@@ -137,27 +158,6 @@ public:
     {
         return m_level_addr_bits.level();
     }
-
-    //////////////////// simpler variants ///////////////////////////
-
-    AddressDecodingTable<addr32_t, bool> 
-    getCacheabilityTable() const
-    {
-        return getCacheabilityTable<addr32_t>();
-    }
-
-    AddressDecodingTable<addr32_t, bool> 
-    getLocalityTable( const IntTab &index ) const
-    {
-        return getLocalityTable<addr32_t>( index );
-    }
-
-    AddressDecodingTable<addr32_t, int> 
-    getRoutingTable( const IntTab &index, int default_index = 0 ) const
-    {
-        return getRoutingTable<addr32_t>( index, default_index );
-    }
-
 };
 
 }}
diff --git a/MPSoC/soclib/soclib/lib/mapping_table/src/mapping_table.cpp b/MPSoC/soclib/soclib/lib/mapping_table/src/mapping_table.cpp
index 0131edb7cc36393fb4d3d766e0b35f9484514f32..2a6e6593c52d1b34c56a6ce84854261464688b6a 100644
--- a/MPSoC/soclib/soclib/lib/mapping_table/src/mapping_table.cpp
+++ b/MPSoC/soclib/soclib/lib/mapping_table/src/mapping_table.cpp
@@ -20,11 +20,22 @@
  * SOCLIB_LGPL_HEADER_END
  *
  * Copyright (c) UPMC, Lip6, Asim
- *         Nicolas Pouillon <nipo@ssji.net>, 2007
+ *         Alain Greiner <alain.greiner@lip6.fr> 2005 
+ *         Nicolas Pouillon <nipo@ssji.net> 2007
+ *         Alain Greiner <alain.greiner@lip6.fr> 2013
  *
- * Based on previous works by Francois Pecheux & Alain Greiner
+ * Maintainers: alain
  */
 
+/////////////////////////////////////////////////////////////////////////////
+// Implementation Note (October 2013)
+// 1) Regarding the various ADDRESS or SRCID decoding tables:
+//   - ADDRESSES values are supposed to use uint64_t type
+//   - SRCID values     are supposed to use uint32_t type
+// 2) Regarding SRCID decoding, the m_srcid[array] is always used.
+//    Identity mapping is handled as a default value: m_srcid_array[i] = i
+/////////////////////////////////////////////////////////////////////////////
+
 #include <cassert>
 #include <sstream>
 #include "mapping_table.h"
@@ -32,28 +43,37 @@
 namespace soclib { namespace common {
 
 ///////////////////////////
-MappingTable::MappingTable(
-    size_t addr_width,
-    const IntTab &level_addr_bits,
-    const IntTab &level_id_bits,
-    const addr64_t cacheability_mask )
+MappingTable::MappingTable( size_t         addr_width,
+                            const IntTab   &level_addr_bits,
+                            const IntTab   &level_id_bits,
+                            const uint64_t cacheability_mask )
         : m_segment_list(),
-          m_addr_width(addr_width),
-          m_addr_mask((addr_width == 64) ? ((addr64_t)-1) : (((addr64_t)1<<addr_width)-1)),
-          m_level_addr_bits(level_addr_bits),
-          m_level_id_bits(level_id_bits),
-          m_cacheability_mask(cacheability_mask),
-          m_used(false)
+          m_addr_width( addr_width ),
+          m_srcid_width( level_id_bits.sum() ),
+          m_addr_mask((addr_width == 64) ? ((uint64_t)-1) : (((uint64_t)1<<addr_width)-1)),
+          m_level_addr_bits( level_addr_bits ),
+          m_level_id_bits( level_id_bits ),
+          m_cacheability_mask( cacheability_mask ),
+          m_used( false )
 {
+    assert( (addr_width <= 64) and
+    "ERROR in mapping table : address larger than 64 bits not supported\n");
+
     m_rt_size = 1ULL << (addr_width - m_level_addr_bits.sum());
-    addr64_t cm_rt_size = 1 << AddressMaskingTable<addr64_t>(m_cacheability_mask).getDrop();
-    m_rt_size = std::min<addr64_t>(cm_rt_size, m_rt_size);
+    uint64_t cm_rt_size = 1 << AddressMaskingTable<uint64_t>(m_cacheability_mask).getDrop();
+    m_rt_size = std::min<uint64_t>(cm_rt_size, m_rt_size);
 
-    m_srcid_array = new size_t[1<<m_level_id_bits.sum()];
-}
+    size_t srcid_size  = 1<<m_srcid_width;
 
+    m_srcid_array = new size_t[srcid_size];
+
+    // set identity default values
+    for( size_t i=0 ; i<srcid_size ; i++ ) m_srcid_array[i] = i;
+}
 
-MappingTable::~MappingTable() {
+/////////////////////////////
+MappingTable::~MappingTable() 
+{
     delete [] m_srcid_array;
 }
 
@@ -86,11 +106,14 @@ const MappingTable &MappingTable::operator=( const MappingTable &ref )
 
 /////////////////////////////////////////////////////
 void MappingTable::srcid_map( const IntTab   &srcid,
-                              size_t         portid )
+                              const IntTab   &portid )
 {
-    m_srcid_array[indexForId(srcid)] = portid;
+    const int index = indexForId(srcid);
+    assert((index < (1 << m_srcid_width)) &&
+           "srcid do not fit the srcid width");
+    m_srcid_array[index] = indexForId(portid);
 }
- 
+
 /////////////////////////////////////////////
 void MappingTable::add( const Segment &_seg )
 {
@@ -102,9 +125,9 @@ void MappingTable::add( const Segment &_seg )
 
     if ( seg.index().level() != m_level_addr_bits.level() ) 
     {
-        std::ostringstream o;
-        o << seg << " is not the same level as the mapping table.";
-        throw soclib::exception::ValueError(o.str());
+        std::cout << "ERROR in mapping table for segment " << seg
+                  << " : inconsistent level" << std::endl;
+        exit(0);
     }
 
     for ( i = m_segment_list.begin();
@@ -112,18 +135,19 @@ void MappingTable::add( const Segment &_seg )
           i++ ) 
     {
         Segment &s = *i;
-        if ( s.isOverlapping(seg) ) {
-            std::ostringstream o;
-            o << seg << " bumps in " << s;
-            throw soclib::exception::Collision(o.str());
+        if ( s.isOverlapping(seg) ) 
+        {
+            std::cout << "ERROR in mapping table for segment " << seg
+                      << " : bumps in segment " << s << std::endl;
+            exit(0);
         }
 
-        for ( addr64_t address = s.baseAddress() & ~(m_rt_size-1);
+        for ( uint64_t address = s.baseAddress() & ~(m_rt_size-1);
               (address < s.baseAddress()+s.size()) &&
                   (address >= (s.baseAddress() & ~(m_rt_size-1)));
               address += m_rt_size ) 
         {
-            for ( addr64_t segaddress = seg.baseAddress() & ~(m_rt_size-1);
+            for ( uint64_t segaddress = seg.baseAddress() & ~(m_rt_size-1);
                   (segaddress < seg.baseAddress()+seg.size()) &&
                       (segaddress >= (seg.baseAddress() & ~(m_rt_size-1)));
                   segaddress += m_rt_size ) 
@@ -131,11 +155,10 @@ void MappingTable::add( const Segment &_seg )
                 if ( (m_cacheability_mask & address) == (m_cacheability_mask & segaddress)
                     && s.cacheable() != seg.cacheable() ) 
                 {
-                    std::ostringstream oss;
-                    oss << "Segment " << s
-                        << " has a different cacheability attribute with same MSBs than " 
-                        << seg << std::endl;
-                    throw soclib::exception::RunTimeError(oss.str());
+                    std::cout << "ERROR in mapping table for segment " << seg
+                              << " : has different cacheability with same mask "
+                              << " bits than segment " << s << std::endl;
+                    exit(0);
                 }
             }
         }
@@ -183,7 +206,9 @@ Segment MappingTable::getSegment( const IntTab &index ) const
 
     const_cast<MappingTable*>(this)->m_used = true;
 
-    assert(list.size() == 1);
+    assert( (list.size() == 1) and
+    "ERROR in getSegment() : more than one segment allocated to target\n");
+
     return list.front();
 }
 
@@ -195,33 +220,32 @@ Segment MappingTable::getSegment( const IntTab &index ) const
 // This ADT can depend on the cluster_id.
 ///////////////////////////////////////////////////////////////////////////
 AddressDecodingTable<uint64_t,size_t> 
-MappingTable::getPortidFromAddress( const size_t cluster_id, 
-                                    const size_t default_tgt_id ) const
+MappingTable::getLocalIndexFromAddress( const size_t cluster_id, 
+                                        const size_t default_target_id ) const
 {
-    // checking mapping table (two levels interconnect)
+    // checking two levels interconnect
     if ( m_level_addr_bits.level() != 2 )
     {
-        std::cout << "ERROR in Mapping Table : the getPortidfromAddress() function"
+        std::cout << "ERROR in Mapping Table : the getLocalIndexFromAddress() function"
                   << " requires a two levels interconnect" << std::endl;
-        std::cout << *this << std::endl;
         exit(0);
     }
 
+    const_cast<MappingTable*>(this)->m_used = true;
+
     size_t global_bits  = m_level_addr_bits[0];   // number of address global bits
     size_t local_bits   = m_level_addr_bits[1];   // number of address local bits
 
     // ADT to be returned
     AddressDecodingTable<uint64_t,size_t> 
     adt( local_bits, m_addr_width - global_bits - local_bits );
-	adt.reset( default_tgt_id );
+	adt.reset( default_target_id );
 
     // temporary ADT for checking
     AddressDecodingTable<uint64_t,bool>
     done( local_bits, m_addr_width - global_bits - local_bits );
 	done.reset( false );
 
-    const_cast<MappingTable*>(this)->m_used = true;
-
     // loop on all segments
     std::list<Segment>::const_iterator seg;
     for ( seg = m_segment_list.begin();
@@ -231,11 +255,9 @@ MappingTable::getPortidFromAddress( const size_t cluster_id,
         // skip segment if cluster_id does not match
         if ( (size_t)seg->index()[0] != cluster_id )    continue; 
 
-        uint64_t base = seg->baseAddress() & ~(m_rt_size-1);
-
         // loop on all possible values for the address local bits
-        for ( uint64_t addr = base ;
-              (addr < base + seg->size()) and (addr >= base);
+        for ( uint64_t addr = seg->baseAddress() & ~(m_rt_size-1);
+              addr < (seg->baseAddress() + seg->size());
               addr += m_rt_size ) 
         {
             size_t port_id = seg->index()[1];
@@ -244,233 +266,274 @@ MappingTable::getPortidFromAddress( const size_t cluster_id,
             {
                 std::cout << "ERROR in Mapping Table : segment " << *seg
                           << " allocated to a different target than another segment"
-                          << " with the same routing bits" << std::endl;
-                std::cout << *this << std::endl;
+                          << " with the same local routing bits" << std::endl;
+                exit(0);
             }
             adt.set( addr, port_id );
             done.set( addr, true );
         }
 	}
-
     return adt;
-}
+} // end getLocalIndexFromAddress()
 
 ///////////////////////////////////////////////////////////////////////////
 // This function returns an ADT that can be used to get
-// the local port_id for an initiator identified by the VCI srcid
+// the local port_id for an initiator identified by the SRCID
 // in a clusterized architecture (two levels interconnect).
-// Only the local bits in the srcid are decoded.
+// Only the local bits in the SRCID are decoded.
 // This ADT can depend on the cluster_id.
 ///////////////////////////////////////////////////////////////////////////
-AddressDecodingTable<uint64_t, size_t> 
-MappingTable::getPortidFromSrcid( const size_t cluster_id ) const
+AddressDecodingTable<uint32_t, size_t> 
+MappingTable::getLocalIndexFromSrcid( const size_t cluster_id ) const
 {
-    // checking mapping table (two levels interconnect)
+    // checking two levels interconnect
     if ( m_level_addr_bits.level() != 2 )
     {
-        std::cout << "ERROR in Mapping Table : the getPortidfromSrcid() function"
+        std::cout << "ERROR in Mapping Table : the getLocalIndexFromSrcid() function"
                   << " requires a two levels interconnect" << std::endl;
-        std::cout << *this << std::endl;
         exit(0);
     }
 
-    size_t local_id_bits  = m_level_id_bits[1];   // number of local bits in SRCID 
-    size_t local_id_max   = 1<<local_id_bits;     // adt size
-
     const_cast<MappingTable*>(this)->m_used = true;
 
+    size_t local_width  = m_level_id_bits[1];   // number of local bits in SRCID 
+    size_t adt_size   = 1<<local_width;         // number of entries in adt
+    size_t local_mask = adt_size - 1;           // SRCID mask for local bits
+
     // ADT to be returned
-    AddressDecodingTable<uint64_t, size_t> adt(local_id_bits, 0);
+    AddressDecodingTable<uint32_t, size_t> 
+    adt(local_width, 0);
 
-    for ( size_t loc = 0 ; loc < local_id_max ; loc++ )
+    // loop on all possible local index values
+    for ( size_t i = 0 ; i < adt_size ; i++ )
     {
-        uint64_t srcid = (cluster_id<<local_id_bits) + loc;
-        adt.set( srcid , m_srcid_array[srcid] );
+        size_t srcid = (cluster_id<<local_width) + i;
+        adt.set( srcid, m_srcid_array[srcid] & local_mask );
     }
-
     return adt;
-}
+} // end getLocalIndexFromSrcid()
 
 ////////////////////////////////////////////////////////////
 // This function returns an ADT that can be used to get
-// the cacheability attribute from a physical address
+// the "is_local" condition from a physical address
+// in a clusterized architecture (two levels interconnect).
+// Only the global bits in the address are decoded.
 ////////////////////////////////////////////////////////////
-template<typename desired_addr_t>
-AddressDecodingTable<desired_addr_t, bool> 
-MappingTable::getCacheabilityTable() const
+AddressDecodingTable<uint64_t, bool>
+MappingTable::getLocalMatchFromAddress( const size_t cluster_id ) const
 {
+    // checking two levels interconnect
+    if ( m_level_addr_bits.level() != 2 )
+    {
+        std::cout << "ERROR in Mapping Table : the getLocalMatchFromAddress() function"
+                  << " requires a two levels interconnect" << std::endl;
+        exit(0);
+    }
+
+    const_cast<MappingTable*>(this)->m_used = true;
+
+    // number of global bits in physical address
+	size_t global_bits = m_level_addr_bits[0];
+
     // ADT to be returned
-    AddressDecodingTable<desired_addr_t, bool> adt(m_cacheability_mask);
+    AddressDecodingTable<uint64_t, bool> 
+    adt( global_bits, m_addr_width - global_bits );
 	adt.reset(false);
 
     // temporary ADT for checking
-    AddressDecodingTable<desired_addr_t, bool> done(m_cacheability_mask);
+    AddressDecodingTable<uint64_t, bool> 
+    done( global_bits, m_addr_width - global_bits );
 	done.reset(false);
 
-    const_cast<MappingTable*>(this)->m_used = true;
-
-    std::list<Segment>::const_iterator i;
-    for ( i = m_segment_list.begin();
-          i != m_segment_list.end();
-          i++ ) 
+    // loop on all segments
+    std::list<Segment>::const_iterator seg;
+    for ( seg = m_segment_list.begin();
+          seg != m_segment_list.end();
+          seg++ ) 
     {
-        for ( desired_addr_t addr = i->baseAddress() & ~(m_rt_size-1);
-              (addr < i->baseAddress()+i->size()) &&
-                  (addr >= (i->baseAddress() & ~(m_rt_size-1)));
+        bool local = ( (size_t)(seg->index()[0]) == cluster_id );
+
+        for ( uint64_t addr = seg->baseAddress() & ~(m_rt_size-1);
+              addr < (seg->baseAddress() + seg->size());
               addr += m_rt_size ) 
         {
-            if ( done[addr] && adt[addr] != i->cacheable() ) 
+            if ( done[addr] && adt[addr] != local ) 
             {
-                std::ostringstream oss;
-                oss << "Incoherent Mapping Table:" << std::endl
-                    << "Segment " << *i 
-                    << " has different cacheability than other segment with same mask"
-                    << std::endl
-                    << "Mapping table:" << std::endl
-                    << *this;
-                throw soclib::exception::RunTimeError(oss.str());
+                std::cout << "ERROR in Mapping Table : segment " << *seg
+                          << " allocated to a different target than another segment"
+                          << " with the same global routing bits" << std::endl;
+                exit(0);
             }
-            adt.set( addr, i->cacheable() );
+            adt.set( addr, local );
             done.set( addr, true );
         }
-    }
+	}
     return adt;
-}
+} // end getLocalMatchFromAddress()
 
 ////////////////////////////////////////////////////////////
-/// This function returns an ADT that can be used to get
-// the local condition from a physical address
+// This function returns an ADT that can be used to get
+// the "is_local" condition from the SRCID value
+// in a clusterized architecture (two levels interconnect).
+// Only the global bits in the SRCID are decoded.
+// We do not asssume identity mapping for m_srcid_array[]
 ////////////////////////////////////////////////////////////
-template<typename desired_addr_t> 
-AddressDecodingTable<desired_addr_t, bool>
-MappingTable::getLocalityTable( const IntTab &index ) const
+AddressDecodingTable<uint32_t, bool>
+MappingTable::getLocalMatchFromSrcid( const size_t cluster_id ) const
 {
-	size_t nbits = m_level_addr_bits.sum(index.level());
+    // checking two levels interconnect
+    if ( m_level_addr_bits.level() != 2 )
+    {
+        std::cout << "ERROR in Mapping Table : the getLocalMatchFromSrcid() function"
+                  << " requires a two levels interconnect" << std::endl;
+        exit(0);
+    }
+
+    const_cast<MappingTable*>(this)->m_used = true;
+
+	size_t global_width = m_level_id_bits[0];  // number of global bits in SRCID
+	size_t local_width  = m_level_id_bits[1];  // number of local bits in SRCID
+    size_t adt_size     = 1<<global_width;     // number of entries in adt
 
     // ADT to be returned
-    AddressDecodingTable<desired_addr_t, bool> adt(nbits, m_addr_width - nbits);
-	adt.reset(true);
+    AddressDecodingTable<uint32_t, bool> 
+    adt( global_width, local_width );
 
-    // temporary ADT for checking
-    AddressDecodingTable<desired_addr_t, bool> done(nbits, m_addr_width - nbits);
-	done.reset(false);
+    // loop on all possible global index values)
+    for ( size_t i = 0 ; i < adt_size ; i++ )
+    {
+        bool match = ( cluster_id == (m_srcid_array[i<<local_width]>>local_width) );
+        adt.set( i<<local_width , match );
+    }
+    return adt;
+} // end getLocalMatchFromAddress()
 
+//////////////////////////////////////////////////////////////////
+// This function returns an ADT that can be used to get
+// the target port index from the MSB bits of a physical address.
+// It can be used in a flat (non clusterized) interconnect,
+// or in a two level interconnect to perform global routing.
+// Only the global bits in the address are decoded.
+//////////////////////////////////////////////////////////////////
+AddressDecodingTable<uint64_t, size_t>
+MappingTable::getGlobalIndexFromAddress( const size_t default_id ) const
+{
     const_cast<MappingTable*>(this)->m_used = true;
 
-    std::list<Segment>::const_iterator i;
-    for ( i = m_segment_list.begin();
-          i != m_segment_list.end();
-          i++ ) 
+	size_t global_bits = m_level_addr_bits[0];
+
+    //  ADT to be returned 
+    AddressDecodingTable<uint64_t, size_t> 
+    adt( global_bits, m_addr_width - global_bits );
+	adt.reset( default_id );
+
+    // temporary ADT for checking
+    AddressDecodingTable<uint64_t, bool>
+    done( global_bits, m_addr_width - global_bits );
+	done.reset(false);
+
+    // loop on all segments
+    std::list<Segment>::const_iterator seg;
+    for ( seg = m_segment_list.begin();
+          seg != m_segment_list.end();
+          seg++ ) 
     {
-        for ( desired_addr_t addr = i->baseAddress() & ~(m_rt_size-1);
-              (addr < i->baseAddress()+i->size()) &&
-                  (addr >= (i->baseAddress() & ~(m_rt_size-1)));
+        size_t global_id = (size_t)(seg->index()[0]);
+
+        for ( uint64_t addr = seg->baseAddress() & ~(m_rt_size-1);
+              addr < (seg->baseAddress() + seg->size());
               addr += m_rt_size ) 
         {
-            bool val = (i->index().idMatches(index) );
-
-            if ( done[addr] && adt[addr] != val ) 
+            if ( done[addr] && adt[addr] != global_id ) 
             {
-                std::ostringstream oss;
-                oss << "Incoherent Mapping Table:" << std::endl
-                    << "Segment " << *i 
-                    << " targets different component than other segments with same MSBs" 
-                    << std::endl
-                    << "Mapping table:" << std::endl
-                    << *this;
-                throw soclib::exception::RunTimeError(oss.str());
+                std::cout << "ERROR in Mapping Table : segment " << *seg
+                          << " allocated to a different target than another segment"
+                          << " with the same global routing bits" << std::endl;
+                exit(0);
             }
-            adt.set( addr, val );
+            adt.set( addr, global_id );
             done.set( addr, true );
         }
 	}
     return adt;
-}
+} // end getGlobaIndexFromAddress()
 
-///////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////
 // This function returns an ADT that can be used to get
-// the target port index from a physical address
-///////////////////////////////////////////////////////////
-template<typename desired_addr_t>
-AddressDecodingTable<desired_addr_t, int>
-MappingTable::getRoutingTable( const IntTab &index, int default_index ) const
+// the initiator port index from the MSB bits of a SRCID.
+// It can be used in a flat (non clusterized) interconnect,
+// or in a two level interconnect to perform global routing.
+// Only the global bits in the SRCID are decoded.
+//////////////////////////////////////////////////////////////////
+AddressDecodingTable<uint32_t, size_t>
+MappingTable::getGlobalIndexFromSrcid() const
 {
-#ifdef SOCLIB_MODULE_DEBUG
-    std::cout << __FUNCTION__ << std::endl;
-#endif
-	size_t before = m_level_addr_bits.sum(index.level());
-	size_t at     = m_level_addr_bits[index.level()];
+    const_cast<MappingTable*>(this)->m_used = true;
+
+    size_t global_width = m_level_id_bits[0];
+    size_t local_width  = m_srcid_width - global_width;
+    size_t adt_size     = 1<<global_width;
 
     //  ADT to be returned 
-    AddressDecodingTable<desired_addr_t, int> adt(at, m_addr_width - at - before);
-	adt.reset(default_index);
+    AddressDecodingTable<uint32_t, size_t> 
+    adt( global_width, local_width );
+
+    // loop on all possible global index values)
+    for ( size_t i = 0 ; i < adt_size ; i++ )
+    {
+        size_t global_id = m_srcid_array[i<<local_width]>>local_width;
+        adt.set( i<<local_width , global_id );
+    }
+    return adt;
+} // end getGlobaIndexFromSrcid()
+
+////////////////////////////////////////////////////////////////////////
+// This function returns an ADT that can be used to get
+// the cacheability attribute from a physical address.
+// Only the bits corresponding to the cacheability mask are decoded.
+////////////////////////////////////////////////////////////////////////
+AddressDecodingTable<uint64_t, bool> 
+MappingTable::getCacheabilityTable() const
+{
+    // ADT to be returned
+    AddressDecodingTable<uint64_t, bool> 
+    adt(m_cacheability_mask);
+	adt.reset(false);
 
     // temporary ADT for checking
-    AddressDecodingTable<desired_addr_t, bool> done(at, m_addr_width - at - before);
+    AddressDecodingTable<uint64_t, bool> 
+    done(m_cacheability_mask);
 	done.reset(false);
 
     const_cast<MappingTable*>(this)->m_used = true;
 
-    std::list<Segment>::const_iterator i;
-    for ( i = m_segment_list.begin();
-          i != m_segment_list.end();
-          i++ ) 
+    // loop on all segments
+    std::list<Segment>::const_iterator seg;
+    for ( seg = m_segment_list.begin();
+          seg != m_segment_list.end();
+          seg++ ) 
     {
-#ifdef SOCLIB_MODULE_DEBUG
-        std::cout << *i
-                  << ", m_rt_size=" << m_rt_size
-                  << ", m_rt_mask=" << ~(m_rt_size-1)
-                  << std::endl;
-#endif
-        if ( ! i->index().idMatches(index) ) 
-        {
-#ifdef SOCLIB_MODULE_DEBUG
-			std::cout << i->index() << " does not match " << index << std::endl;
-#endif
-			continue;
-		}
-
-        #ifdef SOCLIB_MODULE_DEBUG
-        std::cout
-            << ' ' << (i->baseAddress() & ~(m_rt_size-1))
-            << ' ' << (i->baseAddress() + i->size())
-            << ' ' << (((i->baseAddress() & ~(m_rt_size-1)) < i->baseAddress()+i->size()))
-            << ' ' << (((i->baseAddress() & ~(m_rt_size-1)) >= (i->baseAddress() & ~(m_rt_size-1))))
-            << std::endl;
-        #endif
-
-        for ( desired_addr_t addr = i->baseAddress() & ~(m_rt_size-1);
-              (addr < i->baseAddress()+i->size()) &&
-                  (addr >= (i->baseAddress() & ~(m_rt_size-1)));
+        for ( uint64_t addr = seg->baseAddress() & ~(m_rt_size-1);
+              addr < (seg->baseAddress() + seg->size());
               addr += m_rt_size ) 
         {
-            int val = i->index()[index.level()];
-
-            #ifdef SOCLIB_MODULE_DEBUG
-			std::cout << addr << " -> " << val << std::endl;
-            #endif
-
-            if ( done[addr] && adt[addr] != val ) 
+            if ( done[addr] and adt[addr] != seg->cacheable() ) 
             {
-                std::ostringstream oss;
-                oss << "Incoherent Mapping Table: for " << index << std::endl
-                    << "Segment " << *i << " targets different target (or cluster) than other segments with same routing bits" << std::endl
-                    << "Mapping table:" << std::endl
-                    << *this;
-                  throw soclib::exception::RunTimeError(oss.str());
+                std::cout << "ERROR in Mapping Table : segment " << *seg
+                          << " has different cacheability than other segment "
+                          << " with the same cacheability mask" << std::endl;
+                exit(0);
             }
-            adt.set( addr, val );
+            adt.set( addr, seg->cacheable() );
             done.set( addr, true );
         }
-#ifdef SOCLIB_MODULE_DEBUG
-        std::cout << std::endl;
-#endif
-	}
+    }
     return adt;
-}
+} // end getCacheabilityFromAddress() 
 
 //////////////////////////////////////////////////
 void MappingTable::print( std::ostream &o ) const
+//////////////////////////////////////////////////
 {
     std::list<Segment>::const_iterator i;
 
@@ -480,64 +543,12 @@ void MappingTable::print( std::ostream &o ) const
       << std::endl;
     for ( i = m_segment_list.begin();
           i != m_segment_list.end();
-          i++ ) {
+          i++ ) 
+    {
         o << " " << (*i) << std::endl;
     }
 }
 
-/////////////////////////////////////////////////////////
-AddressMaskingTable<uint32_t> 
-MappingTable::getIdMaskingTable( const int level ) const
-{
-    int use = m_level_id_bits[level];
-    int drop = 0;
-    const_cast<MappingTable*>(this)->m_used = true;
-
-    for ( size_t i=level+1; i<m_level_id_bits.level(); ++i )
-        drop += m_level_id_bits[i];
-    return AddressMaskingTable<uint32_t>( use, drop );
-}
-
-/////////////////////////////////////
-AddressDecodingTable<uint32_t, bool> 
-MappingTable::getIdLocalityTable( const IntTab &index ) const
-{
-    size_t 	nbits = m_level_id_bits.sum(index.level());
-    size_t 	id_width = m_level_id_bits.sum();
-    IntTab	complete_index(index, 0);
-    uint32_t 	match = (uint32_t)indexForId(complete_index);
-    const_cast<MappingTable*>(this)->m_used = true;
-
-    AddressDecodingTable<uint32_t, bool> adt(nbits, id_width-nbits);
-    adt.reset(false);
-    adt.set(match, true);
-    return adt;
-}
-
-template
-AddressDecodingTable<uint64_t, bool>
-MappingTable::getCacheabilityTable<uint64_t>() const;
-
-template
-AddressDecodingTable<uint64_t, bool>
-MappingTable::getLocalityTable<uint64_t>( const IntTab &index ) const;
-
-template
-AddressDecodingTable<uint64_t, int>
-MappingTable::getRoutingTable<uint64_t>( const IntTab &index, int default_index ) const;
-    
-template
-AddressDecodingTable<uint32_t, bool>
-MappingTable::getCacheabilityTable<uint32_t>() const;
-
-template
-AddressDecodingTable<uint32_t, bool>
-MappingTable::getLocalityTable<uint32_t>( const IntTab &index ) const;
-
-template
-AddressDecodingTable<uint32_t, int>
-MappingTable::getRoutingTable<uint32_t>( const IntTab &index, int default_index ) const;
-    
 }}
 
 // Local Variables:
diff --git a/MPSoC/soclib/soclib/module/internal_component/vci_xcache_wrapper/caba/source/include/vci_xcache_wrapper.h b/MPSoC/soclib/soclib/module/internal_component/vci_xcache_wrapper/caba/source/include/vci_xcache_wrapper.h
index b65fd105da6d9fdb64ed7e7c2dbd8d0966d4bd9d..20534945aeda79daef23c98043acec1b334c2c52 100644
--- a/MPSoC/soclib/soclib/module/internal_component/vci_xcache_wrapper/caba/source/include/vci_xcache_wrapper.h
+++ b/MPSoC/soclib/soclib/module/internal_component/vci_xcache_wrapper/caba/source/include/vci_xcache_wrapper.h
@@ -106,7 +106,7 @@ public:
 private:
 
     // STRUCTURAL PARAMETERS
-    const soclib::common::AddressDecodingTable<uint32_t, bool>  m_cacheability_table;
+    const soclib::common::AddressDecodingTable<uint64_t, bool>  m_cacheability_table;
     iss_t                                                       m_iss;
     const uint32_t                                              m_srcid;
 
@@ -123,6 +123,10 @@ private:
     typename iss_t::DataRequest                 m_dreq;
     typename iss_t::DataResponse                m_drsp;
 
+    // Debug variables
+    bool                                        m_debug_previous_i_hit;
+    bool                                        m_debug_previous_d_hit;
+
     // REGISTERS
     sc_signal<int>          r_dcache_fsm;
     sc_signal<addr_t>       r_dcache_addr_save;         // request address
@@ -168,7 +172,6 @@ private:
     // Activity counters
     uint32_t m_cpt_icache_read;             // ICACHE READ
     uint32_t m_cpt_icache_write;            // ICACHE WRITE
-
     uint32_t m_cpt_dcache_read;             // DCACHE READ
     uint32_t m_cpt_dcache_write;            // DCACHE WRITE
 
@@ -180,24 +183,18 @@ private:
     uint32_t m_cpt_write;                   // total number of write instructions
     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_data_unc;                // number of data read/write uncached
+    uint32_t m_cpt_ins_unc;                 // number of instruction uncached
     uint32_t m_cpt_write_cached;            // number of cached write
 
     uint32_t m_cost_write_frz;              // frozen cycles related to write buffer
     uint32_t m_cost_data_miss_frz;          // frozen cycles related to data miss
-    uint32_t m_cost_unc_read_frz;           // frozen cycles related to uncached read
     uint32_t m_cost_ins_miss_frz;           // frozen cycles related to ins miss
+    uint32_t m_cost_data_unc_frz;           // frozen cycles related to uncached R/W
+    uint32_t m_cost_ins_unc_frz;            // frozen cycles related to uncached ins
 
-    uint32_t m_cpt_imiss_transaction;       // VCI instruction miss transactions
-    uint32_t m_cpt_dmiss_transaction;       // VCI data miss transactions
-    uint32_t m_cpt_unc_transaction;         // VCI uncached read transactions
     uint32_t m_cpt_write_transaction;       // VCI write transactions
-
-    uint32_t m_cost_imiss_transaction;      // cumulated duration IMISS transactions
-    uint32_t m_cost_dmiss_transaction;      // cumulated duration DMISS transactions
-    uint32_t m_cost_unc_transaction;        // cumulated duration UNC transactions
-    uint32_t m_cost_write_transaction;      // cumulated duration WRITE transactions
-    uint32_t m_length_write_transaction;    // cumulated length   WRITE transactions
+    uint32_t m_length_write_transaction;    // cumulated length VCI write transactions
 
 
 protected:
@@ -221,10 +218,10 @@ public:
 
     void print_cpi();
     void print_stats();
-    void print_latency();//DG
     void print_trace(size_t mode = 0);
     void file_stats(FILE* file);
     void file_trace(FILE* file);
+    void cache_monitor( addr_t addr);
 
 private:
 
diff --git a/MPSoC/soclib/soclib/module/internal_component/vci_xcache_wrapper/caba/source/src/vci_xcache_wrapper.cpp b/MPSoC/soclib/soclib/module/internal_component/vci_xcache_wrapper/caba/source/src/vci_xcache_wrapper.cpp
index 3ffbaa0f66cfa9a46cec812d2efc47dde102b8ac..7bab94440e3ff0a1564860df3744750499109a81 100644
--- a/MPSoC/soclib/soclib/module/internal_component/vci_xcache_wrapper/caba/source/src/vci_xcache_wrapper.cpp
+++ b/MPSoC/soclib/soclib/module/internal_component/vci_xcache_wrapper/caba/source/src/vci_xcache_wrapper.cpp
@@ -1,4 +1,3 @@
-
 /* -*- c++ -*-
  *
  * SOCLIB_LGPL_HEADER_BEGIN
@@ -187,8 +186,9 @@ tmpl(/**/)::VciXcacheWrapper(
       r_icache("icache", icache_ways, icache_sets, icache_words),
       r_dcache("dcache", dcache_ways, dcache_sets, dcache_words)
 {
-    assert((icache_words*vci_param::B) < (1<<vci_param::K) and "I need more PLEN bits");
+    std::cout << "  - Building VciXcacheWrapper " << name << std::endl;
 
+    assert((icache_words*vci_param::B) < (1<<vci_param::K) and "I need more PLEN bits");
 
     SC_METHOD(transition);
     dont_initialize();
@@ -213,7 +213,51 @@ tmpl(/**/)::VciXcacheWrapper(
 tmpl(/**/)::~VciXcacheWrapper()
 /////////////////////////////////
 {
-     print_stats();
+}
+
+//////////////////////////////////////////
+tmpl(void)::cache_monitor( addr_t addr )
+//////////////////////////////////////////
+{
+    bool        cache_hit;
+    size_t	    cache_way = 0;
+    size_t	    cache_set = 0;
+    size_t	    cache_word = 0;
+    uint32_t	cache_rdata = 0;
+
+    cache_hit = r_dcache.read_neutral( addr,
+                                       &cache_rdata,
+                                       &cache_way,
+                                       &cache_set,
+                                       &cache_word );
+
+    if ( cache_hit != m_debug_previous_d_hit )
+    {
+        std::cout << "Monitor PROC " << name()
+                  << " DCACHE at cycle " << std::dec << m_cpt_total_cycles
+                  << " / HIT = " << cache_hit 
+                  << " / PADDR = " << std::hex << addr
+                  << " / DATA = " << cache_rdata 
+                  << " / WAY = " << cache_way << std::endl;
+	    m_debug_previous_d_hit = cache_hit;
+    }
+
+    cache_hit = r_icache.read_neutral( addr,
+                                       &cache_rdata,
+                                       &cache_way,
+                                       &cache_set,
+                                       &cache_word );
+
+    if ( cache_hit != m_debug_previous_i_hit )
+    {
+        std::cout << "Monitor PROC " << name()
+                  << " ICACHE at cycle " << std::dec << m_cpt_total_cycles
+                  << " / HIT = " << cache_hit 
+                  << " / PADDR = " << std::hex << addr
+                  << " / DATA = " << cache_rdata 
+                  << " / WAY = " << cache_way << std::endl;
+	    m_debug_previous_i_hit = cache_hit;
+    }
 }
 
 //////////////////////////////////
@@ -236,14 +280,14 @@ tmpl(void)::file_stats(FILE* file)
 //////////////////////////////////
 {
     float imiss_rate 	= (float)m_cpt_ins_miss / (float)(m_cpt_exec_ins);
-    float dmiss_rate 	= (float)m_cpt_data_miss / (float)(m_cpt_read - m_cpt_unc_read);
+    float dmiss_rate 	= (float)m_cpt_data_miss / (float)(m_cpt_read);
     float cpi		= (float)m_cpt_total_cycles / (float)(m_cpt_exec_ins);
 
     fprintf(file,"%8d %8d %8d %8d %8d    %f    %f    %f \n", 
             m_cpt_total_cycles, 
             m_cpt_exec_ins,
             m_cpt_ins_miss,
-            m_cpt_read-m_cpt_unc_read,
+            m_cpt_read,
             m_cpt_data_miss,
             imiss_rate, 
             dmiss_rate,
@@ -257,29 +301,25 @@ tmpl(void)::print_cpi()
 
               << (float)m_cpt_total_cycles/(float)(m_cpt_exec_ins) << std::endl;
 }
-
 ////////////////////////
 tmpl(void)::print_stats()
 ////////////////////////
 {
-    std::cout << "------------------------------------" << std:: dec << std::endl;
-    std::cout << name() << " / Time = " << m_cpt_total_cycles << std::endl;
-    std::cout << "- CPI                = " << (float)m_cpt_total_cycles/m_cpt_exec_ins << std::endl ;
-    std::cout << "- READ RATE          = " << (float)m_cpt_read/m_cpt_exec_ins << std::endl ;
-    std::cout << "- WRITE RATE         = " << (float)m_cpt_write/m_cpt_exec_ins << std::endl;
-    std::cout << "- UNCACHED READ RATE = " << (float)m_cpt_unc_read/m_cpt_read << std::endl ;
-    std::cout << "- CACHED WRITE RATE  = " << (float)m_cpt_write_cached/m_cpt_write << std::endl ;
-    std::cout << "- IMISS_RATE         = " << (float)m_cpt_ins_miss/m_cpt_exec_ins << std::endl;
-    std::cout << "- DMISS RATE         = " << (float)m_cpt_data_miss/(m_cpt_read-m_cpt_unc_read) << std::endl ;
-    std::cout << "- INS MISS COST      = " << (float)m_cost_ins_miss_frz/m_cpt_ins_miss << std::endl;
-    std::cout << "- IMISS TRANSACTION  = " << (float)m_cost_imiss_transaction/m_cpt_imiss_transaction << std::endl;
-    std::cout << "- DMISS COST         = " << (float)m_cost_data_miss_frz/m_cpt_data_miss << std::endl;
-    std::cout << "- DMISS TRANSACTION  = " << (float)m_cost_dmiss_transaction/m_cpt_dmiss_transaction << std::endl;
-    std::cout << "- UNC COST           = " << (float)m_cost_unc_read_frz/m_cpt_unc_read << std::endl;
-    std::cout << "- UNC TRANSACTION    = " << (float)m_cost_unc_transaction/m_cpt_unc_transaction << std::endl;
-    std::cout << "- WRITE COST         = " << (float)m_cost_write_frz/m_cpt_write << std::endl;
-    std::cout << "- WRITE TRANSACTION  = " << (float)m_cost_write_transaction/m_cpt_write_transaction << std::endl;
-    std::cout << "- WRITE LENGTH       = " << (float)m_length_write_transaction/m_cpt_write_transaction << std::endl;
+    std::cout << "------------------------------------" << std:: dec << std::endl
+    << name() << " / Time = " << m_cpt_total_cycles << std::endl
+    << "- CPI               = " << (float)m_cpt_total_cycles/m_cpt_exec_ins << std::endl
+    << "- READ RATE         = " << (float)m_cpt_read/m_cpt_exec_ins << std::endl 
+    << "- WRITE RATE        = " << (float)m_cpt_write/m_cpt_exec_ins << std::endl
+    << "- UNC RATE          = " << (float)m_cpt_data_unc/m_cpt_exec_ins << std::endl 
+    << "- CACHED WRITE RATE = " << (float)m_cpt_write_cached/m_cpt_write << std::endl
+    << "- IMISS_RATE        = " << (float)m_cpt_ins_miss/m_cpt_exec_ins << std::endl
+    << "- DMISS RATE        = " << (float)m_cpt_data_miss/m_cpt_read << std::endl 
+    << "- INS MISS COST     = " << (float)m_cost_ins_miss_frz/m_cpt_ins_miss << std::endl
+    << "- DMISS COST        = " << (float)m_cost_data_miss_frz/m_cpt_data_miss << std::endl
+    << "- UNC COST          = " << (float)m_cost_data_unc_frz/m_cpt_data_unc << std::endl
+    << "- WRITE COST        = " << (float)m_cost_write_frz/m_cpt_write << std::endl
+    << "- WRITE LENGTH      = " << (float)m_length_write_transaction/m_cpt_write_transaction 
+    << std::endl;
 }
 ////////////////////////////////////
 tmpl(void)::print_trace(size_t mode)
@@ -350,6 +390,10 @@ tmpl(void)::transition()
         r_icache_updated	= false;
         r_dcache_updated	= false;
 
+        // Debug variables
+        m_debug_previous_i_hit = false;
+        m_debug_previous_d_hit = false;
+
         // activity counters
         m_cpt_dcache_read  = 0;
         m_cpt_dcache_write = 0;
@@ -363,23 +407,17 @@ tmpl(void)::transition()
         m_cpt_write = 0;
         m_cpt_data_miss = 0;
         m_cpt_ins_miss = 0;
-        m_cpt_unc_read = 0;
+        m_cpt_data_unc = 0;
+        m_cpt_ins_unc = 0;
         m_cpt_write_cached = 0;
 
         m_cost_write_frz = 0;
         m_cost_data_miss_frz = 0;
-        m_cost_unc_read_frz = 0;
+        m_cost_data_unc_frz = 0;
         m_cost_ins_miss_frz = 0;
+        m_cost_ins_unc_frz = 0;
 
-        m_cpt_imiss_transaction = 0;
-        m_cpt_dmiss_transaction = 0;
-        m_cpt_unc_transaction = 0;
         m_cpt_write_transaction = 0;
-
-        m_cost_imiss_transaction = 0;
-        m_cost_dmiss_transaction = 0;
-        m_cost_unc_transaction = 0;
-        m_cost_write_transaction = 0;
         m_length_write_transaction = 0;
 
         return;
@@ -394,14 +432,14 @@ tmpl(void)::transition()
     bool       vci_rsp_fifo_data_put       = false;
     data_t     vci_rsp_fifo_data_data      = 0;
 
-    #ifdef SOCLIB_MODULE_DEBUG
+#ifdef SOCLIB_MODULE_DEBUG
     std::cout
         << name()
         << " dcache fsm: " << dcache_fsm_state_str[r_data_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] << std::endl;
-    #endif
+#endif
 
     m_cpt_total_cycles++;
 
@@ -439,7 +477,7 @@ tmpl(void)::transition()
     m_irsp.instruction = 0;
 
     switch(r_icache_fsm) 
-        {
+    {
     /////////////////
     case ICACHE_IDLE:
     {
@@ -450,7 +488,7 @@ tmpl(void)::transition()
 
             m_cpt_icache_read++;
 
-            bool    icache_cacheable = m_cacheability_table[m_ireq.addr];
+            bool    icache_cacheable = m_cacheability_table[(uint64_t)m_ireq.addr];
 
             if ( icache_cacheable )    // cacheable access
             {
@@ -473,6 +511,9 @@ tmpl(void)::transition()
             }
             else                        // non cacheable access 
             {
+                m_cpt_ins_unc++;
+                m_cost_ins_unc_frz++;
+
                 r_icache_addr_save = m_ireq.addr;
                 r_icache_fsm       = ICACHE_UNC_WAIT;
                 r_icache_unc_req   = true;
@@ -523,7 +564,8 @@ tmpl(void)::transition()
         {
             m_irsp.valid          = true;
             m_irsp.error          = true;
-            r_vci_rsp_ins_error = false;
+            r_vci_rsp_ins_error   = false;
+            r_icache_fsm          = ICACHE_IDLE;
         }
         else if ( r_vci_rsp_fifo_ins.rok() )   // available instruction 
         {
@@ -561,7 +603,8 @@ tmpl(void)::transition()
         else if ( r_vci_rsp_fifo_ins.rok() ) // instruction available
         {
             vci_rsp_fifo_ins_get = true;
-            if ( m_ireq.valid and (m_ireq.addr == r_icache_addr_save.read()) ) // unmodified
+            if ( m_ireq.valid and 
+                 (m_ireq.addr == r_icache_addr_save.read()) ) // unmodified
             {
                 m_irsp.valid       = true;
                 m_irsp.instruction = r_vci_rsp_fifo_ins.read();
@@ -646,7 +689,6 @@ tmpl(void)::transition()
     /////////////////
     case DCACHE_IDLE:
     {
-
         if ( m_dreq.valid ) 
         {
             bool        dcache_cacheable;
@@ -682,6 +724,8 @@ tmpl(void)::transition()
 
                 if ( m_dreq.type == iss_t::DATA_READ )        // cacheable read
                 {
+                    m_cpt_read++;
+
                     if ( not dcache_hit )   // read miss
                     {
                         m_cpt_data_miss++;
@@ -702,6 +746,8 @@ tmpl(void)::transition()
                 }
                 else if ( m_dreq.type == iss_t::DATA_WRITE )  // cacheable write
                 {
+                    m_cpt_write++;
+
                     if ( not dcache_hit )   // write miss
                     {
                         m_drsp.valid        = true;
@@ -709,6 +755,8 @@ tmpl(void)::transition()
                     }
                     else                    // write hit
                     {
+                        m_cpt_write_cached++;
+
                         m_drsp.valid        = true;
                         r_dcache_fsm        = DCACHE_WRITE_UPDT;
                         r_dcache_way_save   = dcache_way;
@@ -726,7 +774,6 @@ tmpl(void)::transition()
             } 
             else                    // uncacheable request
             {
-                r_dcache_cacheable_save = false;
                 switch( m_dreq.type ) 
                 {
                 // we expect a single word rdata for these 3 requests
@@ -734,8 +781,8 @@ tmpl(void)::transition()
                 case iss_t::DATA_LL:
                 case iss_t::DATA_SC:
                 {
-                    m_cpt_unc_read++;
-                    m_cost_unc_read_frz++;
+                    m_cpt_data_unc++;
+                    m_cost_data_unc_frz++;
 
                     r_dcache_unc_req   = true;
                     r_dcache_addr_save = m_dreq.addr;
@@ -774,7 +821,7 @@ tmpl(void)::transition()
                 }
                 case iss_t::DATA_WRITE:
                 {
-                    m_cpt_write++;
+                    m_cpt_data_unc++;
 
                     r_dcache_fsm = DCACHE_WRITE_REQ;
                     m_drsp.valid = true;
@@ -843,10 +890,10 @@ tmpl(void)::transition()
 
         if ( r_vci_rsp_data_error.read() )       // error reported
         {
-            assert(m_dreq.valid);
             m_drsp.valid         = true;
             m_drsp.error         = true;
             r_vci_rsp_data_error = false;
+            r_dcache_fsm         = DCACHE_IDLE;
         }
         else if ( r_vci_rsp_fifo_data.rok() )    // available data 
         {
@@ -872,22 +919,21 @@ tmpl(void)::transition()
     /////////////////////
     case DCACHE_UNC_WAIT:   // wait rdata for LL, SC, or uncacheable read
     {
-        m_cost_unc_read_frz++;
+        m_cost_data_unc_frz++;
 
         if ( r_vci_rsp_data_error.read() )      // error reported
         {
-            r_vci_rsp_data_error  = false;
-            assert(m_dreq.valid);
             m_drsp.valid          = true;
             m_drsp.error          = true;
+            r_vci_rsp_data_error  = false;
             r_dcache_fsm          = DCACHE_IDLE;
         }
         else if ( r_vci_rsp_fifo_data.rok() )   // available data
         {
             vci_rsp_fifo_data_get = true;
-            if ( m_dreq.valid and (m_dreq.addr == r_dcache_addr_save.read()) ) // request unmodified
+            if ( m_dreq.valid and 
+                 (m_dreq.addr == r_dcache_addr_save.read()) ) // request unmodified
             {
-                assert(m_dreq.valid);
                 m_drsp.valid = true;
                 m_drsp.rdata = r_vci_rsp_fifo_data.read();
             }
@@ -916,7 +962,6 @@ tmpl(void)::transition()
         else		// miss : nothing to do
         {
             r_dcache_fsm      = DCACHE_IDLE;
-            assert(m_dreq.valid);
             m_drsp.valid      = true;
         }
         break;
@@ -929,7 +974,6 @@ tmpl(void)::transition()
                         r_dcache_set_save.read(),
                         &nline );
         r_dcache_fsm = DCACHE_IDLE;
-        assert(m_dreq.valid);
         m_drsp.valid = true;
         break;
     }
@@ -939,14 +983,7 @@ tmpl(void)::transition()
     std::cout << name() << " Data Response: " << m_drsp << std::endl;
 #endif
 
-    /////////// 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, m_irsp, m_drsp, it);
-
+    ////////// Compute number of executed instructions ////////////////
     if ( (m_ireq.valid and m_irsp.valid) and 
          (!m_dreq.valid or m_drsp.valid) and 
          (m_ireq.addr != m_pc_previous) )
@@ -955,6 +992,14 @@ tmpl(void)::transition()
         m_pc_previous = m_ireq.addr;
     }
 
+    /////////// 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, m_irsp, m_drsp, it);
+
     ////////////////////////////////////////////////////////////////////////////
     // This FSM handles requests from both the DCACHE FSM & the ICACHE FSM.
     // There is 5 request types, with the following priorities :
@@ -985,13 +1030,11 @@ tmpl(void)::transition()
         r_vci_cmd_cpt = 0;
         if ( r_icache_miss_req ) 
         {
-            m_cpt_imiss_transaction++;
             r_vci_cmd_fsm     = CMD_INS_MISS;
             r_icache_miss_req = false;
         } 
         else if ( r_icache_unc_req ) 
         {
-            m_cpt_imiss_transaction++;
             r_vci_cmd_fsm    = CMD_INS_UNC;
             r_icache_unc_req = false;
         } 
@@ -1006,14 +1049,11 @@ tmpl(void)::transition()
         } 
         else if ( r_dcache_miss_req ) 
         {
-            m_cpt_dmiss_transaction++;
-            
             r_vci_cmd_fsm     = CMD_DATA_MISS;
             r_dcache_miss_req = false;
         } 
         else if ( r_dcache_unc_req ) 
         {
-            m_cpt_unc_transaction++;
             r_vci_cmd_fsm    = CMD_DATA_UNC;
             r_dcache_unc_req = false;
         }
@@ -1089,7 +1129,6 @@ tmpl(void)::transition()
     //////////////////
     case RSP_INS_MISS:
     {
-        m_cost_imiss_transaction++;
         if ( p_vci.rspval.read() )
         {
             if ( (p_vci.rerror.read()&0x1) != 0 )       // error reported
@@ -1101,15 +1140,15 @@ tmpl(void)::transition()
             {
                 if ( r_vci_rsp_fifo_ins.wok() )
                 {
-                    assert( (r_vci_rsp_cpt.read() < m_dcache_words) and
-                    "The VCI response packet for data miss is too long");
+                    assert( (r_vci_rsp_cpt.read() < m_icache_words) and
+                    "The VCI response packet for instruction miss is too long");
                     r_vci_rsp_cpt              = r_vci_rsp_cpt.read() + 1;
                     vci_rsp_fifo_ins_put       = true,
                     vci_rsp_fifo_ins_data      = p_vci.rdata.read();
                     if ( p_vci.reop.read() )
                     {
-                        assert( (r_vci_rsp_cpt.read() == m_dcache_words - 1) and
-                        "The VCI response packet for data miss is too short");
+                        assert( (r_vci_rsp_cpt.read() == (m_icache_words - 1)) and
+                        "The VCI response packet for instruction miss is too short");
                         r_vci_rsp_fsm     = RSP_IDLE;
                     }
                 }
@@ -1120,7 +1159,6 @@ tmpl(void)::transition()
     /////////////////
     case RSP_INS_UNC:
     {
-        m_cost_imiss_transaction++;
         if ( p_vci.rspval.read() )
         {
             assert(p_vci.reop.read() and
@@ -1145,7 +1183,6 @@ tmpl(void)::transition()
     ///////////////////
     case RSP_DATA_MISS:
     {
-        m_cost_dmiss_transaction++;
         if ( p_vci.rspval.read() )
         {
             if ( (p_vci.rerror.read()&0x1) != 0 )       // error reported
@@ -1176,7 +1213,6 @@ tmpl(void)::transition()
     ////////////////////
     case RSP_DATA_WRITE:
     {
-        m_cost_write_transaction++;
         if (  p_vci.rspval.read() )
         {
             if ( (p_vci.rerror.read() & 0x1) == 0x1 ) m_iss.setWriteBerr(); 
@@ -1187,7 +1223,6 @@ tmpl(void)::transition()
     //////////////////
     case RSP_DATA_UNC:
     {
-        m_cost_dmiss_transaction++;
         if ( p_vci.rspval.read() )
         {
             assert(p_vci.reop.read() and
@@ -1219,7 +1254,7 @@ tmpl(void)::transition()
     r_vci_rsp_fifo_data.update(vci_rsp_fifo_data_get,
                                vci_rsp_fifo_data_put,
                                vci_rsp_fifo_data_data);
-    
+
 } // end transition()
 
 //////////////////////////////////////////////////////////////////////////////////
diff --git a/MPSoC/soclib/soclib/module/network_component/vci_local_crossbar/caba/metadata/vci_local_crossbar.sd b/MPSoC/soclib/soclib/module/network_component/vci_local_crossbar/caba/metadata/vci_local_crossbar.sd
index 707d579f060027cd4d453b9eb5f3c52db26ace39..393e3370b8af9cc0d7daf195654cf2a82ce3913c 100644
--- a/MPSoC/soclib/soclib/module/network_component/vci_local_crossbar/caba/metadata/vci_local_crossbar.sd
+++ b/MPSoC/soclib/soclib/module/network_component/vci_local_crossbar/caba/metadata/vci_local_crossbar.sd
@@ -1,16 +1,20 @@
 
 # -*- python -*-
 
-__id__ = "$Id: vci_local_crossbar.sd 1711 2010-04-20 10:30:27Z nipo $"
-__version__ = "$Revision: 1711 $"
+__id__ = "$Id: vci_local_crossbar.sd 2582 2015-01-19 09:09:29Z meunier $"
+__version__ = "$Revision: 2582 $"
 
 Module('caba:vci_local_crossbar',
 	classname = 'soclib::caba::VciLocalCrossbar',
-	   tmpl_parameters = [
-	parameter.Module('vci_param',  default = 'caba:vci_param'),
+	tmpl_parameters = [
+	    parameter.Module('vci_param',  default = 'caba:vci_param'),
 	],
-	header_files = ['../source/include/vci_local_crossbar.h',],
-	implementation_files = ['../source/src/vci_local_crossbar.cpp',],
+	header_files = [
+        '../source/include/vci_local_crossbar.h',
+    ],
+	implementation_files = [
+        '../source/src/vci_local_crossbar.cpp',
+    ],
 	ports = [
 	    Port('caba:vci_initiator', 'p_to_target', parameter.Reference('nb_attached_target')),
 	    Port('caba:vci_target', 'p_to_initiator', parameter.Reference('nb_attached_initiator')),
@@ -21,21 +25,25 @@ Module('caba:vci_local_crossbar',
 	],
 	instance_parameters = [
         parameter.Module('mt', typename = 'common:mapping_table'),
-        parameter.IntTab('tgtid'),
-        parameter.IntTab('srcid'),
-        parameter.Int('nb_attached_initiator'),
-        parameter.Int('nb_attached_target'),
+        parameter.Int('cluster_id'),
+        parameter.Int('nb_attached_initiators'),
+        parameter.Int('nb_attached_targets'),
+        parameter.Int('default_target_id'),
 	],
 	uses = [
 		Uses('caba:base_module'),
 		Uses('common:mapping_table'),
 		Uses('caba:vci_buffers'),
-		],
-	   extensions = [
-	'dsx:interconnect',
-	'dsx:mapping_type=interconnect',
-	'dsx:get_ident=srcid:p_initiator_to_up:mt,tgtid:p_target_to_up:mt',
-	'dsx:obtain_ident_method=port',
-    'dsx:interconnect_port_assoc=p_to_initiator:p_initiator_to_up,p_to_target:p_target_to_up'
+        Uses('common:address_decoding_table', input_t = 'uint64_t', output_t = 'size_t'),
+        Uses('common:address_decoding_table', input_t = 'uint64_t', output_t = 'bool'),
+        Uses('common:address_decoding_table', input_t = 'uint32_t', output_t = 'size_t'),
+        Uses('common:address_decoding_table', input_t = 'uint32_t', output_t = 'bool'),
+	],
+    extensions = [
+        'dsx:interconnect',
+	    'dsx:mapping_type=interconnect',
+        'dsx:get_ident=srcid:p_initiator_to_up:mt,tgtid:p_target_to_up:mt',
+	    'dsx:obtain_ident_method=port',
+        'dsx:interconnect_port_assoc=p_to_initiator:p_initiator_to_up,p_to_target:p_target_to_up'
 	],
 )
diff --git a/MPSoC/soclib/soclib/module/network_component/vci_local_crossbar/caba/source/include/vci_local_crossbar.h b/MPSoC/soclib/soclib/module/network_component/vci_local_crossbar/caba/source/include/vci_local_crossbar.h
index d090f4f7eb790f36920596d11e5d187526d25952..54e450eaff0c0cc12e8d9318f24d2f2dda574267 100644
--- a/MPSoC/soclib/soclib/module/network_component/vci_local_crossbar/caba/source/include/vci_local_crossbar.h
+++ b/MPSoC/soclib/soclib/module/network_component/vci_local_crossbar/caba/source/include/vci_local_crossbar.h
@@ -21,12 +21,12 @@
  * SOCLIB_LGPL_HEADER_END
  *
  * Copyright (c) UPMC, Lip6, Asim
+ *         Alain Greiner <alain.greiner@lip6.fr>, 2005
  *         Nicolas Pouillon <nipo@ssji.net>, 2008
  *
- * Based on previous works by Alain Greiner, 2005
- *
- * Maintainers: nipo
+ * Maintainers: alain
  */
+
 #ifndef SOCLIB_CABA_VCI_LOCAL_CROSSBAR_H_
 #define SOCLIB_CABA_VCI_LOCAL_CROSSBAR_H_
 
@@ -36,54 +36,62 @@
 #include "vci_target.h"
 #include "vci_buffers.h"
 #include "mapping_table.h"
+#include "address_decoding_table.h"
 
 namespace soclib { namespace caba {
 
-namespace _local_crossbar {
-template<typename pkt_t> class Crossbar;
-}
+using namespace soclib::common;
 
+template<typename pkt_t> class SimpleCrossbar;
+
+////////////////////////////////////
 template<typename vci_param>
 class VciLocalCrossbar
+////////////////////////////////////
     : public BaseModule
 {
 public:
-    sc_in<bool> p_clk;
-    sc_in<bool> p_resetn;
 
-    VciInitiator<vci_param> *p_to_target;
-    VciTarget<vci_param> *p_to_initiator;
-    VciTarget<vci_param> p_target_to_up;
-    VciInitiator<vci_param> p_initiator_to_up;
+    sc_in<bool>                               p_clk;
+    sc_in<bool>                               p_resetn;
+
+    VciInitiator<vci_param>                  *p_to_target;
+    VciTarget<vci_param>                     *p_to_initiator;
+    VciTarget<vci_param>                      p_target_to_up;
+    VciInitiator<vci_param>                   p_initiator_to_up;
 
 private:
-    size_t m_nb_attached_initiat;
-    size_t m_nb_attached_target;
 
-    VciInitiator<vci_param> **m_ports_to_target;
-    VciTarget<vci_param> **m_ports_to_initiator;
+    size_t                                    m_nb_attached_initiators;
+    size_t                                    m_nb_attached_targets;
 
-    typedef _local_crossbar::Crossbar<VciCmdBuffer<vci_param> > cmd_crossbar_t;
-    typedef _local_crossbar::Crossbar<VciRspBuffer<vci_param> > rsp_crossbar_t;
+    AddressDecodingTable<uint64_t, size_t>    m_cmd_rt;   // command routing table
+    AddressDecodingTable<uint64_t, bool>      m_cmd_lt;   // command locality table
+
+    AddressDecodingTable<uint32_t, size_t>    m_rsp_rt;   // response routing table
+    AddressDecodingTable<uint32_t, bool>      m_rsp_lt;   // response locality table
+
+    VciInitiator<vci_param>                 **m_ports_to_target;
+    VciTarget<vci_param>                    **m_ports_to_initiator;
+
+    SimpleCrossbar<VciCmdBuffer<vci_param> > *m_cmd_crossbar;
+    SimpleCrossbar<VciRspBuffer<vci_param> > *m_rsp_crossbar;
 
     void transition();
     void genMealy();
 
-	cmd_crossbar_t *m_cmd_crossbar;
-	rsp_crossbar_t *m_rsp_crossbar;
-
 protected:
     SC_HAS_PROCESS(VciLocalCrossbar);
 
 public:
     void print_trace();
 
-    VciLocalCrossbar( sc_module_name name,
-					  const soclib::common::MappingTable &mt,
-					  const soclib::common::IntTab &srcid,
-					  const soclib::common::IntTab &tgtid,
-					  size_t nb_attached_initiat,
-					  size_t nb_attached_target );
+    VciLocalCrossbar( sc_core::sc_module_name             name,
+					  const soclib::common::MappingTable  &mt,
+					  const size_t                        cluster_id,
+					  const size_t                        nb_attached_initiators,
+					  const size_t                        nb_attached_targets,
+                      const size_t                        default_target_id );
     ~VciLocalCrossbar();
 };
 
diff --git a/MPSoC/soclib/soclib/module/network_component/vci_local_crossbar/caba/source/src/vci_local_crossbar.cpp b/MPSoC/soclib/soclib/module/network_component/vci_local_crossbar/caba/source/src/vci_local_crossbar.cpp
index 22a02537e5341d461983b063b850ca4db2bd31e5..f46f4dfbaade38ed83513aa8095d9188e0d1a861 100644
--- a/MPSoC/soclib/soclib/module/network_component/vci_local_crossbar/caba/source/src/vci_local_crossbar.cpp
+++ b/MPSoC/soclib/soclib/module/network_component/vci_local_crossbar/caba/source/src/vci_local_crossbar.cpp
@@ -20,47 +20,45 @@
  * SOCLIB_LGPL_HEADER_END
  *
  * Copyright (c) UPMC, Lip6, Asim
-           Alain Greiner <alain.greiner@lip6.fr> 2005 & 2011
+           Alain Greiner <alain.greiner@lip6.fr> 2005 
  *         Nicolas Pouillon <nipo@ssji.net>, 2008
  *
- * Maintainers: nipo, alain
+ * Maintainers: alain
  */
 
 ///////////////////////////////////////////////////////////////////////////
 // Implementation Note :
-// This component is implemented as two independant crossbars,
-// for VCI commands and VCI responses respectively.
+// This component is implemented as two independant combinational 
+// crossbars, for VCI commands and VCI responses respectively.
 // - The CMD crossbar has NI local plus one global input
 // ports. It has NT local + one global output ports.
-// - The RSP crossbar has NT target local plus one global input
+// - The RSP crossbar has NT local plus one global input
 // ports. It has NI local + one global output ports.
 // For each generic crossbar, the input and output ports are impemented
 // as arrays of ports, and the last port (i.e. the largest index value)
-// is the ports connected to the global interconnect.
+// is the port connected to the global interconnect.
 //
-// This component support single flit VCI broadcast commands : If the
+// This component does not contain FIFOs, and behaves as a Mealy FSM.
+//
+// It supportsi single flit VCI broadcast commands : If the
 // two lsb bits of the VCI ADDRESS are non zero, the corresponding
 // command is considered as a broadcast. 
-// As the broadcast command arriving on input port (i) should not be 
-// transmitted to the requester, it is not transmitted on output port (i).
-// Therefore, in case of broadcast, NI & NT must be equal, and all
-// connected components mus have the same index dfor input & output ports.
-// 
-// In case of broadcast, the single VCI flit is SEQUENCIALLY transmitted 
+// For a broadcast, the single VCI flit is SEQUENCIALLY transmitted 
 // to the (NT+1) output ports, but not to the requesting input port.
 // For each transmitted flit to a given output port, the standard 
 // round-robin allocation policy is respected.
+// As the broadcast command arriving on input port (i) should not be 
+// transmitted to the requester, it is not transmitted on output port (i).
+// Therefore, in case of broadcast, NI & NT must be equal, and all
+// connected components mus have the same index for input & output ports.
 ///////////////////////////////////////////////////////////////////////////
 
 #include <systemc>
 #include <cassert>
-//#include "vci_buffers.h"
-#include "./vci_buffers.h"
+#include "vci_buffers.h"
 #include "../include/vci_local_crossbar.h"
 #include "alloc_elems.h"
 
-//#define CROSSBAR_DEBUG
-
 namespace soclib { namespace caba {
 
 using soclib::common::alloc_elems;
@@ -68,85 +66,132 @@ using soclib::common::dealloc_elems;
 
 using namespace sc_core;
 
-namespace _local_crossbar {
-
-///////////////////////////////////////
-template<typename pkt_t> class Crossbar
-{
-    typedef typename pkt_t::routing_table_t routing_table_t;
-    typedef typename pkt_t::locality_table_t locality_table_t;
-    typedef typename pkt_t::input_port_t input_port_t;
-    typedef typename pkt_t::output_port_t output_port_t;
-
-    const size_t 		m_in_size;		// total number of inputs (local + global)
-    const size_t 		m_out_size;		// total number of outputs (local + global)
-    const routing_table_t 	m_rt;
-    const locality_table_t 	m_lt;
-
-    sc_signal<bool>*		r_allocated;		// for each output port: allocation state 
+////////////////////////////////////////////////
+template<typename pkt_t> 
+class SimpleCrossbar
+////////////////////////////////////////////////
+{   
+    const size_t 		    m_cluster_id;   // cluster index
+    const size_t 		    m_in_size;		// total number of inputs (local + global)
+    const size_t 		    m_out_size;		// total number of outputs (local + global)
+    const void*             m_rt;           // routing table if cmd  / masking table if rsp
+    const void* 	        m_lt;           // locality table if cmd / id_locality table if rsp
+    const bool              m_is_cmd;       // cmd crossbar when true
+
+    sc_signal<bool>*		r_allocated;	// for each output port: allocation state 
     sc_signal<size_t>*		r_origin;		// for each output port: input port index
     sc_signal<bool>*		r_bc_state;		// for each input port: broadcast requested
     sc_signal<size_t>*		r_bc_count;		// for each input port: requested output index
 
 public:
-    /////////
-    Crossbar(
-	size_t in_size, size_t out_size,
-	const routing_table_t &rt,
-	const locality_table_t &lt)
-	: m_in_size(in_size),
-	  m_out_size(out_size),
-	  m_rt(rt),
-	  m_lt(lt)
+    ////////////////////////////////
+    SimpleCrossbar( size_t  cluster_id,     // cluster index
+                    size_t  in_size,        // number of inputs
+                    size_t  out_size,       // number of outputs
+	                void*   rt,             // routing table 
+	                void*   lt,             // locality table
+                    bool    is_cmd )
+	: m_cluster_id( cluster_id ),
+      m_in_size( in_size ),
+	  m_out_size( out_size ),
+	  m_rt( rt ),
+	  m_lt( lt ),
+      m_is_cmd( is_cmd )
 	{
 	    r_allocated = new sc_signal<bool>[out_size];
 	    r_origin	= new sc_signal<size_t>[out_size];
-            r_bc_state	= new sc_signal<bool>[in_size];
+        r_bc_state	= new sc_signal<bool>[in_size];
 	    r_bc_count	= new sc_signal<size_t>[in_size];
-	}
+	} // end constructor 
+
+    ~SimpleCrossbar() {
+        delete [] r_allocated;
+        delete [] r_origin;
+        delete [] r_bc_state;
+        delete [] r_bc_count;
+    }
 
     ////////////
     void reset()
     {
-	for (size_t i=0; i<m_out_size; ++i) 
+	    for (size_t i=0; i<m_out_size; ++i) 
         {
-	    r_origin[i]    = 0;
-	    r_allocated[i] = false;
-	}
-	for (size_t i=0; i<m_in_size; ++i) 
+	        r_origin[i]    = 0;
+	        r_allocated[i] = false;
+	    }
+	    for (size_t i=0; i<m_in_size; ++i) 
         {
-	    r_bc_state[i] = false;
-	    r_bc_count[i] = 0;
-	}
-    }
+	        r_bc_state[i] = false;
+	        r_bc_count[i] = 0;
+	    }
+    } // end reset()
 
-    //////////////////////////////
-    void print_trace(bool command)
+    //////////////////
+    void print_trace()
     {
         for( size_t out=0 ; out<m_out_size ; out++)
         {
             if( r_allocated[out].read() ) 
             {
-                if(command) std::cout << std::dec << "target " << out
-                                      << " allocated to initiator " << r_origin[out].read() << std::endl;
-                else        std::cout << std::dec << "initiator " << out
-                                      << " allocated to target " << r_origin[out].read() << std::endl;
+                if( m_is_cmd ) std::cout << std::dec 
+                                         << "initiator " << r_origin[out].read()
+                                         << " =>  target " << out;
+                else           std::cout << std::dec 
+                                         << "target " << r_origin[out].read()
+                                         << " => initiator " << out; 
             }
         }
         for ( size_t in=0 ; in<m_in_size ; in++)
         {
             if( r_bc_state[in].read() )
             {
-                if(command) std::cout << " broadcast request from initiator " << in 
-                                      << " requesting target " << r_bc_count[in].read() << std::endl;
-                else        std::cout << " broadcast request from target " << in 
-                                      << " requesting initiator " << r_bc_count[in].read() << std::endl;
+                if( m_is_cmd ) std::cout << " broadcast request from initiator " << in 
+                                         << " requesting target " 
+                                         << r_bc_count[in].read();
+                else           std::cout << " broadcast request from target " << in 
+                                         << " requesting initiator " 
+                                         << r_bc_count[in].read();
             }
         }
-    }
+    } // end print_trace()
 
-    ////////////////////////////////////////////////////////////////////////
-    void transition( input_port_t **input_port, output_port_t **output_port )
+    //////////////////////////
+    size_t route( pkt_t flit )
+    {
+        if( m_is_cmd )  // we use a 64 bits AddressDecodingTable for ADDRESS
+        {
+            soclib::common::AddressDecodingTable<uint64_t, size_t>* rt =
+                   (soclib::common::AddressDecodingTable<uint64_t, size_t>*)m_rt;
+            return rt->get_value( (uint64_t)(flit.dest()) );
+        }
+        else            // we use a 32 bits AddressDecodingTable for SRCID
+        {
+            soclib::common::AddressDecodingTable<uint32_t, size_t>* rt =
+                   (soclib::common::AddressDecodingTable<uint32_t, size_t>*)m_rt;
+            return rt->get_value( (uint32_t)(flit.dest()) );
+        }  
+    } // end route()
+
+    ///////////////////////////
+    bool is_local( pkt_t flit )
+    {
+        if( m_is_cmd )  // we use a 64 bits AddressDecoding Table for ADDRESS
+        {
+            soclib::common::AddressDecodingTable<uint64_t, bool>* lt =
+                   (soclib::common::AddressDecodingTable<uint64_t, bool>*)m_lt;
+            return lt->get_value( (uint64_t)(flit.dest()) );
+        }
+        else            // we use a 32 bits AddressDecodingTable for SRCID
+        {
+            soclib::common::AddressDecodingTable<uint32_t, bool>* lt =
+                   (soclib::common::AddressDecodingTable<uint32_t, bool>*)m_lt;
+            return lt->get_value( (uint32_t)(flit.dest()) );
+        }
+    } // end is_local()
+
+    //////////////////////////////////////////////////////////////
+    void transition( typename pkt_t::input_port_t   **input_port, 
+                     typename pkt_t::output_port_t  **output_port )
     {
         // loop on the input ports to handle r_bc_state[in] and r_bc_count[in]
         for( size_t in = 0 ; in < m_in_size ; in++ )
@@ -158,12 +203,12 @@ public:
                     size_t out = r_bc_count[in];
                     if ( ( r_allocated[out].read() ) &&
                          ( r_origin[out].read() == in ) &&
-                         ( output_port[out]->toPeerEnd() ) )	// flit successfully transmitted 
+                         ( output_port[out]->toPeerEnd() ) )	// successfully transmitted 
                     {
                         // the broadcast should not be sent to the requester...
                         if ( (out == 0) || ((out == 1) && (in == 0)) ) 	r_bc_state[in] = false;
-                        else if ( (out-1) != in )			r_bc_count[in] = out-1;
-                        else 						r_bc_count[in] = out-2;
+                        else if ( (out-1) != in )	r_bc_count[in] = out-1;
+                        else                        r_bc_count[in] = out-2;
                     }
                 }
                 else				// no pending proadcast
@@ -173,11 +218,12 @@ public:
                     if ( tmp.is_broadcast() )		// broadcast request
                     {
                         assert( input_port[in]->eop && 
-                                "error in vci_local_crossbar : VCI broacast packet must be one flit");
+                        "error in vci_local_crossbar : VCI broacast packet must be one flit");
+
                         r_bc_state[in] = true;
                         // the broadcast should not be sent to the requester...
                         if ( in == m_in_size-1 ) r_bc_count[in] = m_out_size-2;  
-                        else			 r_bc_count[in] = m_out_size-1; 
+                        else                     r_bc_count[in] = m_out_size-1; 
                     }
                 }
             }
@@ -201,10 +247,15 @@ public:
                     {
                         pkt_t tmp;
                         tmp.readFrom(*input_port[in]);
-
-                        if ( (tmp.is_broadcast() && r_bc_state[in].read() && (r_bc_count[in].read() == out)) ||
-                             (!tmp.is_broadcast() && !tmp.isLocal(m_lt) && (out == m_out_size-1))            ||
-                             (!tmp.is_broadcast() && tmp.isLocal(m_lt) && (out == (size_t)tmp.route(m_rt)))  )  
+                        if ( (tmp.is_broadcast() and 
+                              r_bc_state[in].read() and 
+                              (r_bc_count[in].read() == out))   or   // broadcast request
+                             (not tmp.is_broadcast() and 
+                              not is_local( tmp ) and 
+                              (out == m_out_size-1))            or   // to global network
+                             (not tmp.is_broadcast() and
+                              is_local( tmp ) and
+                              (out == route( tmp )) ) )              // to local component
                         {
                             r_allocated[out] = true;
                             r_origin[out] = in;
@@ -216,8 +267,9 @@ public:
         }
     } // end transition
 
-    ///////////////////////////////////////////////////////////////////////
-    void genMealy( input_port_t **input_port, output_port_t **output_port )
+    /////////////////////////////////////////////////////////////
+    void genMealy( typename pkt_t::input_port_t   **input_port, 
+                   typename pkt_t::output_port_t  **output_port )
     {
         bool ack[m_in_size];
         for( size_t in = 0; in < m_in_size; in++) ack[in] = false;
@@ -227,7 +279,7 @@ public:
         {
             if (r_allocated[out]) 
             {
-		size_t in = r_origin[out];
+		        size_t in = r_origin[out];
                 pkt_t tmp;
                 tmp.readFrom(*input_port[in]);
                 tmp.writeTo(*output_port[out]);
@@ -241,17 +293,15 @@ public:
             } 
             else 
             {
-                output_port[out]->setVal(false);
+                output_port[out]->setVal( false );
             }
         }
 
         // Send acknowledges on input ports
-        for( size_t in = 0; in < m_in_size; in++) input_port[in]->setAck(ack[in]);
+        for( size_t in = 0; in < m_in_size; in++) input_port[in]->setAck( ack[in] );
     } // en genmealy
 
-}; // end class Crossbar
-
-}
+}; // end class SimpleCrossbar
 
 #define tmpl(x) template<typename vci_param> x VciLocalCrossbar<vci_param>
 
@@ -259,8 +309,8 @@ public:
 tmpl(void)::print_trace()
 {
     std::cout << "LOCAL_CROSSBAR " << name() << " / ";
-    m_cmd_crossbar->print_trace(true);
-    m_rsp_crossbar->print_trace(false);
+    m_cmd_crossbar->print_trace();
+    m_rsp_crossbar->print_trace(); 
     std::cout << std::endl;
 }
 
@@ -285,26 +335,35 @@ tmpl(void)::genMealy()
     m_rsp_crossbar->genMealy( m_ports_to_target, m_ports_to_initiator );
 }
 
-/////////////////////////////
-tmpl(/**/)::VciLocalCrossbar(
-	sc_core::sc_module_name name,
-	const soclib::common::MappingTable &mt,
-	const soclib::common::IntTab &srcid,
-	const soclib::common::IntTab &tgtid,
-	size_t nb_attached_initiat,
-	size_t nb_attached_target )
-           : BaseModule(name),
-           p_clk("clk"),
-           p_resetn("resetn"),
+///////////////////////////////////////////////////////////////////////
+tmpl(/**/)::VciLocalCrossbar( sc_core::sc_module_name            name,
+                              const soclib::common::MappingTable &mt,
+                              const size_t                       cluster_id,
+	                          const size_t                       nb_attached_initiators,
+	                          const size_t                       nb_attached_targets,
+                              const size_t                       default_target_id )
+       : BaseModule(name),
+       p_clk("clk"),
+       p_resetn("resetn"),
 	   p_to_target(soclib::common::alloc_elems<VciInitiator<vci_param> >(
-                           "to_target", nb_attached_target)),
+                           "to_target", nb_attached_targets)),
 	   p_to_initiator(soclib::common::alloc_elems<VciTarget<vci_param> >(
-                              "to_initiator", nb_attached_initiat)),
-           p_target_to_up("target_to_up"),
-           p_initiator_to_up("initiator_to_up"),
-           m_nb_attached_initiat(nb_attached_initiat),
-           m_nb_attached_target(nb_attached_target)
+                           "to_initiator", nb_attached_initiators)),
+       p_target_to_up("target_to_up"),
+       p_initiator_to_up("initiator_to_up"),
+       m_nb_attached_initiators(nb_attached_initiators),
+       m_nb_attached_targets(nb_attached_targets),
+       m_cmd_rt ( mt.getLocalIndexFromAddress( cluster_id, default_target_id ) ),
+       m_cmd_lt ( mt.getLocalMatchFromAddress( cluster_id ) ),
+       m_rsp_rt ( mt.getLocalIndexFromSrcid( cluster_id ) ),
+       m_rsp_lt ( mt.getLocalMatchFromSrcid( cluster_id ) )
 {
+    std::cout << "  - Building VciLocalCrossbar " << name << std::dec << std::endl
+              << "    => cluster_id     = " << cluster_id << std::endl
+              << "    => targets        = " << nb_attached_targets << std::endl
+              << "    => initiators     = " << nb_attached_initiators << std::endl
+              << "    => default target = " << default_target_id << std::endl;
+
     SC_METHOD(transition);
     dont_initialize();
     sensitive << p_clk.pos();
@@ -313,42 +372,51 @@ tmpl(/**/)::VciLocalCrossbar(
     dont_initialize();
     sensitive << p_clk.neg();
 
-	for ( size_t i=0; i<nb_attached_initiat; ++i )
+	for ( size_t i=0; i<nb_attached_initiators; ++i )
 		sensitive << p_to_initiator[i];
-	for ( size_t i=0; i<nb_attached_target; ++i )
+	for ( size_t i=0; i<nb_attached_targets; ++i )
 		sensitive << p_to_target[i];
 
     sensitive << p_target_to_up
               << p_initiator_to_up;
 
-	m_cmd_crossbar = new cmd_crossbar_t(
-		nb_attached_initiat+1, 
-		nb_attached_target+1,
-		mt.getRoutingTable(tgtid),
-        	mt.getLocalityTable(tgtid));
-
-	m_rsp_crossbar = new rsp_crossbar_t(
-		nb_attached_target+1, 
-		nb_attached_initiat+1,
-		mt.getIdMaskingTable(srcid.level()),
-        	mt.getIdLocalityTable(srcid));
-
-    m_ports_to_initiator = new VciTarget<vci_param>*[nb_attached_initiat+1];
-    for (size_t i=0; i<nb_attached_initiat; ++i)
+    // building cmd and rsp crossbars
+	m_cmd_crossbar = new SimpleCrossbar<VciCmdBuffer<vci_param> >(
+                         cluster_id,
+                         nb_attached_initiators+1, 
+		                 nb_attached_targets+1,
+                         (void*)(&m_cmd_rt),
+                         (void*)(&m_cmd_lt),
+                         true );
+
+	m_rsp_crossbar = new SimpleCrossbar<VciRspBuffer<vci_param> >(
+		                 cluster_id,
+                         nb_attached_targets+1, 
+		                 nb_attached_initiators+1,
+                         (void*)(&m_rsp_rt),
+                         (void*)(&m_rsp_lt),
+                         false );
+
+    m_ports_to_initiator = new VciTarget<vci_param>*[nb_attached_initiators+1];
+    for (size_t i=0; i<nb_attached_initiators; ++i)
         m_ports_to_initiator[i] = &p_to_initiator[i];
-    m_ports_to_initiator[nb_attached_initiat] = &p_target_to_up;
+    m_ports_to_initiator[nb_attached_initiators] = &p_target_to_up;
 
-    m_ports_to_target = new VciInitiator<vci_param>*[nb_attached_target+1];
-    for (size_t i=0; i<nb_attached_target; ++i)
+    m_ports_to_target = new VciInitiator<vci_param>*[nb_attached_targets+1];
+    for (size_t i=0; i<nb_attached_targets; ++i)
         m_ports_to_target[i] = &p_to_target[i];
-    m_ports_to_target[nb_attached_target] = &p_initiator_to_up;
+    m_ports_to_target[nb_attached_targets] = &p_initiator_to_up;
 }
 
 ///////////////////////////////
 tmpl(/**/)::~VciLocalCrossbar()
 {
-    soclib::common::dealloc_elems(p_to_initiator, m_nb_attached_initiat);
-    soclib::common::dealloc_elems(p_to_target, m_nb_attached_target);
+    soclib::common::dealloc_elems(p_to_initiator, m_nb_attached_initiators);
+    soclib::common::dealloc_elems(p_to_target, m_nb_attached_targets);
+    delete m_cmd_crossbar;
+    delete m_rsp_crossbar;
+    delete [] m_ports_to_initiator;
+    delete [] m_ports_to_target;
 }
 
 }}
diff --git a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/caba/source/include/vci_vgmn.h b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/caba/source/include/vci_vgmn.h
index 0b686b96ea1a0a42dae9af0d07c1de5f18a0b5f9..d01cb534d3d005f9f1bdd22796d316bbd7da58fe 100644
--- a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/caba/source/include/vci_vgmn.h
+++ b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/caba/source/include/vci_vgmn.h
@@ -21,12 +21,13 @@
  * SOCLIB_LGPL_HEADER_END
  *
  * Copyright (c) UPMC, Lip6, Asim
- *         Nicolas Pouillon <nipo@ssji.net>, 2007
+ *         Alain Greiner <alain.greiner@lip6.fr> 2005
+ *         Nicolas Pouillon <nipo@ssji.net> 2007
+ *         Alain Greiner <alain.greiner@lip6.fr> 2013
  *
- * Based on previous works by Laurent Mortiez & Alain Greiner, 2005
- *
- * Maintainers: nipo
+ * Maintainers: alain
  */
+
 #ifndef SOCLIB_CABA_VCI_VGMN_H_
 #define SOCLIB_CABA_VCI_VGMN_H_
 
@@ -34,8 +35,7 @@
 #include "caba_base_module.h"
 #include "vci_initiator.h"
 #include "vci_target.h"
-#include "vci_buffers.h" 
-//#include "vci_buffers_vgmn.h" //DG 31.08. we require a different kind of buffer than the vci_local_crossbar
+#include "vci_buffers.h"
 #include "address_decoding_table.h"
 #include "address_masking_table.h"
 #include "mapping_table.h"
@@ -51,6 +51,7 @@ template<typename vci_flit_t,
          typename vci_input_t,
          typename vci_output_t> class VgmnMicroNetwork;
 
+///////////////////////////////////
 template<typename vci_param>
 class VciVgmn
     : public soclib::caba::BaseModule
@@ -63,11 +64,11 @@ public:
     VciTarget<vci_param>                        *p_to_initiator;
 
 private:
-    const size_t                                m_nb_initiat;
-    const size_t                                m_nb_target;
+    const size_t                                m_nb_initiators;
+    const size_t                                m_nb_targets;
 
-    AddressDecodingTable<uint32_t, int>         m_cmd_routing_table;
-    AddressMaskingTable<uint32_t>               m_rsp_routing_table;
+    AddressDecodingTable<uint64_t, size_t>      m_cmd_rt;
+    AddressDecodingTable<uint32_t, size_t>      m_rsp_rt;
  
     VgmnMicroNetwork<VciCmdBuffer<vci_param>,
                      VciTarget<vci_param>,
@@ -86,13 +87,13 @@ protected:
 public:
     void print_trace();
 
-    VciVgmn( sc_module_name name,
+    VciVgmn( sc_module_name                      name,
               const soclib::common::MappingTable &mt,
-              size_t nb_initiat,
-              size_t nb_target,
-              size_t min_latency,
-              size_t fifo_depth,
-              const soclib::common::IntTab &default_index = 0);
+              size_t                             nb_initiators,
+              size_t                             nb_targets,
+              size_t                             min_latency,
+              size_t                             fifo_depth,
+              const size_t                       default_index = 0 );
 
     ~VciVgmn();
 };
diff --git a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/caba/source/src/vci_vgmn.cpp b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/caba/source/src/vci_vgmn.cpp
index c96d1e9978d789925d6b8b97dcdc1aacd842923e..6564a4556634ae89624340db52760a8c8296dbd2 100644
--- a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/caba/source/src/vci_vgmn.cpp
+++ b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/caba/source/src/vci_vgmn.cpp
@@ -20,12 +20,31 @@
  * SOCLIB_LGPL_HEADER_END
  *
  * Copyright (c) UPMC, Lip6, Asim
- *         Nicolas Pouillon <nipo@ssji.net>, 2007-2009
- *         Alain Greiner <alain.greiner@lip6.fr> 2005 & 2013
+ *         Alain Greiner <alain.greiner@lip6.fr> 2005 
+ *         Nicolas Pouillon <nipo@ssji.net> 2007-2009
+ *         Alain Greiner <alain.greiner@lip6.fr> 2013
  *
  * Maintainers: alain
  */
 
+/////////////////////////////////////////////////////////////////////////////////
+// Implementation note:
+// The VciVgmn component contains two independant micro-network for CMD & RSP.
+// Each micro-network is composed of a variable number of "input ports"
+// and a variable number of "output ports".
+// - Each Input Port contains an input generic fifo, a routing function, 
+//   and a dedicated FSM to handle (sequencial) broadcast.
+// - Each Output Port contains several intermediate fifos (one per input port),
+//   an allocation FSM, and an output fifo acting as a delay line.
+// The two micro-networks have three template parameters:
+// - CMD network: vci_flit_t   == VciCmdBuffer
+//                vci_input_t  == VciTarget
+//                vci_output_t == VciInitiator
+// - RSP network: vci_flit_t   == VciRspBuffer
+//                vci_input_t  == VciInitiator
+//                vci_output_t == VciTarget   
+/////////////////////////////////////////////////////////////////////////////////
+
 #include <systemc>
 #include <vector>
 #include <cassert>
@@ -35,6 +54,7 @@
 namespace soclib { namespace caba {
 
 using namespace sc_core;
+using namespace soclib::common;
 
 ////////////////////////////////////////////
 template<typename data_t> class DelayLine
@@ -174,7 +194,7 @@ public:
 // An output module is associated to each output port of a micro-network 
 // Each output module implements a separate allocation mechanism, and
 // contains as many intermediate FIFOs as the number of input ports, 
-// and one single output delay line.
+// and one single output fifo acting as a delay line.
 // For a CMD micro-network:  vci_flit_t   == VciCmdBuffer
 //                           vci_output_t == VciInitiator
 // For a RSP micro-network:  vci_flit_t   == VciRspBuffer
@@ -374,15 +394,15 @@ public:
         size_t out;
         if( r_is_cmd )
         {
-            soclib::common::AddressDecodingTable<uint32_t, int>* routing_table =
-                   (soclib::common::AddressDecodingTable<uint32_t, int>*)r_rt;
-            out = (size_t)(routing_table->get_value( (uint32_t)flit.dest() ));
+            AddressDecodingTable<uint64_t, size_t>* rt =
+                (AddressDecodingTable<uint64_t, size_t>*)r_rt;
+            out = rt->get_value( (uint64_t)flit.dest() );
         }
         else
         {
-            soclib::common::AddressMaskingTable<uint32_t>*  masking_table =
-                   (soclib::common::AddressMaskingTable<uint32_t>*)r_rt;
-            out = (size_t)(masking_table->get_value( (uint32_t)flit.dest() ));
+            AddressDecodingTable<uint32_t, size_t>* rt =
+                (AddressDecodingTable<uint32_t, size_t>*)r_rt;
+            out = rt->get_value( (uint32_t)flit.dest() );
         }  
         return out;
     }
@@ -488,14 +508,6 @@ public:
     }
 };    // end class InputModule
 
-/////////////////////////////////////////////////////////////////////////////////
-// The VciVgmn component contains two independant micro-network for CMD & RSP
-// - CMD network: vci_flit_t   == VciCmdBuffer
-//                vci_input_t  == VciTarget
-//                vci_output_t == VciInitiator
-// - RSP network: vci_flit_t   == VciRspBuffer
-//                vci_input_t  == VciInitiator
-//                vci_output_t == VciTarget   
 /////////////////////////////////////////////////////////////////////////////////
 template<typename vci_flit_t,   
          typename vci_input_t,
@@ -624,16 +636,21 @@ tmpl(void)::print_trace()
 //////////////////////////////////////////////////////////////
 tmpl(/**/)::VciVgmn( sc_module_name                     name,
                      const soclib::common::MappingTable &mt,
-                     size_t                             nb_attached_initiat,
-                     size_t                             nb_attached_target,
+                     size_t                             nb_attached_initiators,
+                     size_t                             nb_attached_targets,
                      size_t                             min_latency,
                      size_t                             fifo_depth,
-                     const soclib::common::IntTab       &default_index)
+                     const size_t                       default_index)
    : soclib::caba::BaseModule(name),
-     m_nb_initiat(nb_attached_initiat),
-     m_nb_target(nb_attached_target)
+     m_nb_initiators( nb_attached_initiators ),
+     m_nb_targets( nb_attached_targets ),
+     m_cmd_rt( mt.getGlobalIndexFromAddress( default_index ) ),
+     m_rsp_rt( mt.getGlobalIndexFromSrcid() )
 {
-    std::cout << "  - Building VciVgmn : " << name << std::endl;
+    std::cout << "  - Building VciVgmn : " << name << std::dec << std::endl
+              << "    => targets        = "  << nb_attached_targets << std::endl
+              << "    => initiators     = "  << nb_attached_initiators << std::endl
+              << "    => default target = "  << default_index << std::endl;
 
     assert( (min_latency > 2) and
     "VCI_VGMN error : min_latency cannot be smaller than 3 cycles");
@@ -642,43 +659,28 @@ tmpl(/**/)::VciVgmn( sc_module_name                     name,
     "VCI_VGMN error : fifo_depth cannot be  smaller than 2 slots");
 
     p_to_initiator = soclib::common::alloc_elems<soclib::caba::VciTarget<vci_param> >(
-                     "to_initiator", nb_attached_initiat);
+                     "to_initiator", nb_attached_initiators);
     p_to_target = soclib::common::alloc_elems<soclib::caba::VciInitiator<vci_param> >(
-                     "to_target", nb_attached_target);
-
-    // build cmd routing table and cmd network
+                     "to_target", nb_attached_targets);
 
-    
-    m_cmd_routing_table = mt.getRoutingTable( soclib::common::IntTab(), 
-                                              mt.indexForId(default_index) );
-
-    // m_cmd_routing_table = mt.getRoutingTable( soclib::common::IntTab(), 
-    //                                     0 );
-   
+    // build  cmd network and rsp network 
 
     m_cmd_mn = new VgmnMicroNetwork<VciCmdBuffer<vci_param>,
                                     VciTarget<vci_param>,
-                                    VciInitiator<vci_param> >( nb_attached_initiat, 
-                                                               nb_attached_target,
+                                    VciInitiator<vci_param> >( nb_attached_initiators, 
+                                                               nb_attached_targets,
                                                                min_latency-2, 
                                                                fifo_depth,
-                                                               (void*)(&m_cmd_routing_table),
+                                                               (void*)(&m_cmd_rt),
                                                                true );
-
-
-    // build rsp routing table and rsp network
-    m_rsp_routing_table = mt.getIdMaskingTable(0);
-    
     m_rsp_mn = new VgmnMicroNetwork<VciRspBuffer<vci_param>, 
                                     VciInitiator<vci_param>,
-                                    VciTarget<vci_param> >( nb_attached_target, 
-                                                            nb_attached_initiat,
+                                    VciTarget<vci_param> >( nb_attached_targets, 
+                                                            nb_attached_initiators,
                                                             min_latency-2, 
                                                             fifo_depth,
-                                                            (void*)(&m_rsp_routing_table),
+                                                            (void*)(&m_rsp_rt),
                                                             false );
-
- 
     SC_METHOD(transition);
     dont_initialize();
     sensitive << p_clk.pos();
@@ -693,8 +695,8 @@ tmpl(/**/)::~VciVgmn()
 {
     delete m_rsp_mn;
     delete m_cmd_mn;
-    soclib::common::dealloc_elems(p_to_initiator, m_nb_initiat);
-    soclib::common::dealloc_elems(p_to_target, m_nb_target);
+    soclib::common::dealloc_elems( p_to_initiator, m_nb_initiators );
+    soclib::common::dealloc_elems( p_to_target, m_nb_targets );
 }
 
 }}
diff --git a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/metadata/vci_vgmn.sd b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/metadata/vci_vgmn.sd
index ce9fc020115bc2aa9dafeea81ae33b2d3c72464d..c865d19aba1ea36bbed74c627a0f3297abc21fe1 100644
--- a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/metadata/vci_vgmn.sd
+++ b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/metadata/vci_vgmn.sd
@@ -20,24 +20,22 @@
 # 
 # SOCLIB_LGPL_HEADER_END
 #
-# Maintainers: fpecheux, nipo, alinevieiramello@hotmail.com, hgioja
+# Maintainers: fpecheux, nipo, alinevieiramello@hotmail.com, hgioja, alain
 #
 # Copyright (c) UPMC / Lip6, 2008
 #     Francois Pecheux <francois.pecheux@lip6.fr>
 #     Nicolas Pouillon <nipo@ssji.net>
 #     Aline Vieira de Mello <aline.vieira-de-mello@lip6.fr>
 #     Hermann Gioja <hermann.gioja@lip6.fr>
+#     Alain.Greiner <alain.greiner@lip6.fr>
 
 
-__id__ = "$Id: vci_vgmn.sd 917 2009-03-12 10:10:06Z nipo $"
-__version__ = "$Revision: 917 $"
-
 Module('tlmdt:vci_vgmn',
        classname = 'soclib::tlmdt::VciVgmn',
        header_files = [ '../source/include/vci_vgmn.h', ],
        implementation_files = ['../source/src/vci_vgmn.cpp', ],
        uses = [ Uses('common:tlmdt'),
-		Uses('tlmdt:interconnect'),
-		],
-      #debug = True,
+                Uses('common:mapping_table'),
+                Uses('tlmdt:centralized_buffer'),
+		      ],
        )
diff --git a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/include/centralized_buffer.h b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/include/centralized_buffer.h
index f60cab4580d9fae514006cfdd5904cbac4866359..6e388f7db9b4dc08df59f5937184cdb2f488e910 100644
--- a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/include/centralized_buffer.h
+++ b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/include/centralized_buffer.h
@@ -27,55 +27,84 @@
  *     Aline Vieira de Mello <aline.vieira-de-mello@lip6.fr>
  */
 
+/////////////////////////////////////////////////////////////////////////////////////
+// Implementation note:
+// The centralized_buffer is actually an array of initiator ports descriptors.
+// There is one entry per initiator connected to the interconnect in this array.
+// Each port descriptor can store one or several transaction (payload, phase, time)
+// in a circular buffer (defined in soclib/lib) acting as a software FIFO.
+/////////////////////////////////////////////////////////////////////////////////////
+
 #ifndef CENTRALIZED_BUFFER_H
 #define CENTRALIZED_BUFFER_H
 
-#include <tlmdt>	             // TLM-DT headers
+#include <tlmdt>	            
 #include "circular_buffer.h"
 
 namespace soclib { namespace tlmdt {
 
-class _command;
+////////////////////////////
+class init_port_descriptor
+////////////////////////////
+{
+    friend class centralized_buffer;
+  
+    circular_buffer         buffer;      // circular buffer of transactions
+    sc_core::sc_time        port_time;   // date of last transaction transmited 
+    bool                    active;      // initiator port activated if true
+
+public:
+
+    // constructor    
+    init_port_descriptor()
+    : buffer() , port_time(sc_core::SC_ZERO_TIME)
+    {
+        active = true;
+    }
+};
 
+//////////////////////////
 class centralized_buffer
-  : public sc_core::sc_module        // inherit from SC module base clase
+//////////////////////////
+  : public sc_core::sc_module       
 {
-  const size_t        m_slots;
-  _command           *m_centralized_struct;
-
-  int                 m_count_push;
-  int                 m_count_pop;
+    // member variables
+    const size_t            m_slots;       // number of initiators                 
+    init_port_descriptor*   m_port_array;  // array of initiator port descriptors
+    int                     m_count_push;  // cumulated push counter
+    int                     m_count_pop;   // cumulate pop counter
+    size_t                  m_previous;    // last selected port index (for round-robin)
 
 public:
-  centralized_buffer
-  ( sc_core::sc_module_name module_name,  // SC module name
-    size_t                  max);
 
-  ~centralized_buffer();
+    // constructor destructor
+    centralized_buffer( sc_core::sc_module_name name,
+                        size_t                  slots );
+
+    ~centralized_buffer();
 
-  bool push
-  ( size_t                    from,
-    tlm::tlm_generic_payload &payload,
-    tlm::tlm_phase           &phase,
-    sc_core::sc_time         &time);
+    // methods
+    bool push ( size_t                    from,
+                tlm::tlm_generic_payload  &payload,
+                tlm::tlm_phase            &phase,
+                sc_core::sc_time          &time );
 
-  bool pop
-  ( size_t                    &from,
-    tlm::tlm_generic_payload *&payload,
-    tlm::tlm_phase           *&phase,
-    sc_core::sc_time         *&time);
+    bool pop (  size_t                    &from,
+                tlm::tlm_generic_payload* &payload,
+                tlm::tlm_phase*           &phase,
+                sc_core::sc_time*         &time );
 
-  circular_buffer get_buffer(int i);
+    circular_buffer get_buffer(size_t index);
 
-  const size_t get_nslots();
+    const size_t get_nslots();
 
-  const size_t get_free_slots();
+    const size_t get_free_slots();
 
-  sc_core::sc_time get_delta_time(unsigned int index);
+    sc_core::sc_time get_port_time(size_t index);
 
-  void set_activity(unsigned int index, bool b);
+    void set_activity(size_t index, bool b);
 
-  void set_delta_time(unsigned int index, sc_core::sc_time t);
+    void set_port_time(size_t index, sc_core::sc_time t);
 };
 
 }}
diff --git a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/include/interconnect.h b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/include/interconnect.h
index 8b055e46bd3d71e7112b27bccbedbd6d413416e8..0e2ee8ada320c3231dc78f9c0636e23ea888e949 100644
--- a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/include/interconnect.h
+++ b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/include/interconnect.h
@@ -31,39 +31,43 @@
 #ifndef __INTERCONNECT_H__ 
 #define __INTERCONNECT_H__
 
-#include <tlmdt>	                                        // TLM-DT headers
-#include "mapping_table.h"                                      // mapping table
-#include "centralized_buffer.h"                                 // centralized buffer
+#include <tlmdt>	            // TLM-DT headers
+#include "mapping_table.h"                        
+#include "centralized_buffer.h"          
 
 namespace soclib { namespace tlmdt {
 
-class Interconnect                                              // Interconnect
-  : public sc_core::sc_module           	                // inherit from SC module base clase
+////////////////////
+class Interconnect 
+////////////////////
+  : public sc_core::sc_module  
+  , virtual public tlm::tlm_fw_transport_if<tlm::tlm_base_protocol_types> 
+  , virtual public tlm::tlm_bw_transport_if<tlm::tlm_base_protocol_types> 
 {
 private:
  
-  typedef soclib::common::AddressDecodingTable<uint32_t, int>  routing_table_t;     
-  typedef soclib::common::AddressDecodingTable<uint32_t, bool> locality_table_t;   
-  typedef soclib::common::AddressMaskingTable<uint32_t>        resp_routing_table_t; 
-  typedef soclib::common::AddressDecodingTable<uint32_t, bool> resp_locality_table_t;
+  typedef soclib::common::AddressDecodingTable<uint64_t, size_t> cmd_routing_table_t;     
+  typedef soclib::common::AddressDecodingTable<uint32_t, bool>   cmd_locality_table_t;   
+  typedef soclib::common::AddressDecodingTable<uint32_t, size_t> rsp_routing_table_t; 
+  typedef soclib::common::AddressDecodingTable<uint32_t, bool>   rsp_locality_table_t;
 
   /////////////////////////////////////////////////////////////////////////////////////
   // Member Variables
   /////////////////////////////////////////////////////////////////////////////////////
-  int 				m_id;                 	// identifier
-  int 				m_inits;              	// number of initiiators
-  int 				m_targets;            	// number of targets
-  size_t 			m_delay;              	// interconnect delay
-  size_t 			m_local_delta_time;	// minimal time between send & response LOCAL
-  size_t  			m_no_local_delta_time;  // minimal time between send & response NOT LOCAL
-  bool                          m_is_local_crossbar;  	// true if the module is a loca interconnect
-
-  centralized_buffer 		m_centralized_buffer; 	// centralized buffer
-  const routing_table_t         m_routing_table;      	// routing table
-  const locality_table_t        m_locality_table;     	// locality table
-  const resp_routing_table_t    m_resp_routing_table; 	// response routing table
-  const resp_locality_table_t   m_resp_locality_table;	// response locality table
-  pdes_local_time*              m_pdes_local_time;    	// local time
+  size_t                        m_id;                 	// identifier
+  size_t                        m_inits;              	// number of initiiators
+  size_t                        m_targets;            	// number of targets
+  size_t                        m_delay;              	// interconnect delay
+  size_t                        m_local_delta_time;	    // minimal time between cmd/rsp
+  size_t                        m_no_local_delta_time;  // minimal time between cmd/rsp
+  bool                          m_is_local_crossbar;  	// true if local interconnect
+
+  centralized_buffer            m_centralized_buffer; 	// centralized buffer
+  const cmd_routing_table_t     m_cmd_routing_table;    // command routing table
+  const cmd_locality_table_t    m_cmd_locality_table;   // command locality table
+  const rsp_routing_table_t     m_rsp_routing_table; 	// response routing table
+  const rsp_locality_table_t    m_rsp_locality_table;	// response locality table
+  pdes_local_time*              m_pdes_local_time;    	// local time (pointer)
 
   // instrumentation counters
   size_t                        m_msg_count;
@@ -91,78 +95,84 @@ private:
   /////////////////////////////////////////////////////////////////////////////////////
   void init();
 
-  void behavior(void);
+  void execLoop(void);
 
-  void routing
-  ( size_t                   from,      // port source
-    tlm::tlm_generic_payload &payload,   // payload
-    tlm::tlm_phase           &phase,     // phase
-    sc_core::sc_time         &time);     // time
+  void route ( size_t                   from,       // port source
+               tlm::tlm_generic_payload &payload,   // payload
+               tlm::tlm_phase           &phase,     // phase
+               sc_core::sc_time         &time);     // time
 
   void create_token();
 
   /////////////////////////////////////////////////////////////////////////////////////
-  // Fuction  tlm::tlm_fw_transport_if (VCI TARGET SOCKET)
+  // Function executed when receiving command from VCI initiator
   /////////////////////////////////////////////////////////////////////////////////////
-  tlm::tlm_sync_enum nb_transport_fw     // receive command from initiator
-  ( int                       id,        // socket id
-    tlm::tlm_generic_payload &payload,   // payload
-    tlm::tlm_phase           &phase,     // phase
-    sc_core::sc_time         &time);     // time
+  tlm::tlm_sync_enum nb_transport_fw ( int                      id,         // socket id
+                                       tlm::tlm_generic_payload &payload,   // payload
+                                       tlm::tlm_phase           &phase,     // phase
+                                       sc_core::sc_time         &time);     // time
  
   /////////////////////////////////////////////////////////////////////////////////////
-  // Virtual Fuctions  tlm::tlm_bw_transport_if (VCI INITIATOR SOCKET)
+  // Function executed when receiving response from VCI target
   /////////////////////////////////////////////////////////////////////////////////////
-  tlm::tlm_sync_enum nb_transport_bw     // receive answer from target
-  ( int                       id,        // socket id
-    tlm::tlm_generic_payload &payload,   // payload
-    tlm::tlm_phase           &phase,     // phase
-    sc_core::sc_time         &time);     // time
+  tlm::tlm_sync_enum nb_transport_bw ( int                       id,        // socket id
+                                       tlm::tlm_generic_payload &payload,   // payload
+                                       tlm::tlm_phase           &phase,     // phase
+                                       sc_core::sc_time         &time);     // time
 
  protected:
+
   SC_HAS_PROCESS(Interconnect);
+
 public:  
 
-  std::vector<tlm_utils::simple_target_socket_tagged<Interconnect,32,tlm::tlm_base_protocol_types> *> p_to_initiator;
-  std::vector<tlm_utils::simple_initiator_socket_tagged<Interconnect,32,tlm::tlm_base_protocol_types> *> p_to_target;
-
-  Interconnect(                                                // constructor
-	       sc_core::sc_module_name module_name             // SC module name
-	       , int id                                        // identifier
-	       , const routing_table_t &rt                     // routing table
-	       , const resp_routing_table_t &rrt               // response routing table
-	       , size_t n_inits                                // number of inits
-	       , size_t n_targets                              // number of targets
-	       , size_t delay);                                // interconnect delay
-
-  Interconnect(                                                // constructor
-	       sc_core::sc_module_name module_name             // SC module name
-	       , const routing_table_t &rt                     // routing table
-	       , const resp_routing_table_t &rrt               // response routing table
-	       , size_t n_inits                                // number of inits
-	       , size_t n_targets                              // number of targets
-	       , size_t delay);                                // interconnect delay
-  
-  Interconnect(                                                // constructor
-	       sc_core::sc_module_name module_name             // SC module name
-	       , int id                                        // identifier
-	       , const routing_table_t &rt                     // routing table
-	       , const locality_table_t &lt                    // locality table
-	       , const resp_routing_table_t &rrt               // response routing table
-	       , const resp_locality_table_t &rlt              // response locality table
-	       , size_t n_inits                                // number of inits
-	       , size_t n_targets                              // number of targets
-	       , size_t delay);                                // interconnect delay
-
-  Interconnect(                                                // constructor
-	       sc_core::sc_module_name module_name             // SC module name
-	       , const routing_table_t &rt                     // routing table
-	       , const locality_table_t &lt                    // locality table
-	       , const resp_routing_table_t &rrt               // response routing table
-	       , const resp_locality_table_t &rlt              // response locality table
-	       , size_t n_inits                                // number of inits
-	       , size_t n_targets                              // number of targets
-	       , size_t delay);                                // interconnect delay
+  std::vector<tlm_utils::simple_target_socket_tagged
+  <Interconnect,32,tlm::tlm_base_protocol_types> *>       p_to_initiator;
+
+  std::vector<tlm_utils::simple_initiator_socket_tagged
+  <Interconnect,32,tlm::tlm_base_protocol_types> *>       p_to_target;
+
+  ////////////////////////////////
+  // Constructors
+  ////////////////////////////////
+
+  // Global interconnect
+  Interconnect( sc_core::sc_module_name     module_name,   // module name
+	            const size_t                id,            // identifier
+	            const cmd_routing_table_t   &cmd_rt,       // command routing table
+	            const rsp_routing_table_t   &rsp_rt,       // response routing table
+	            const size_t                n_inits,       // number of initiators
+	            const size_t                n_targets,     // number of targets
+	            const size_t                delay );       // interconnect latency
+
+  // Global interconnect without identifier
+  Interconnect( sc_core::sc_module_name     module_name,   // module name
+	            const cmd_routing_table_t   &cmd_rt,       // command routing table
+	            const rsp_routing_table_t   &rsp_rt,       // response routing table
+	            const size_t                n_inits,       // number of initiators
+	            const size_t                n_targets,     // number of targets
+	            const size_t                delay );       // interconnect latency
+
+  // Local interconnect
+  Interconnect( sc_core::sc_module_name     module_name,   // module name
+	            const size_t                id,            // identifier
+	            const cmd_routing_table_t   &cmd_rt,       // command routing table
+	            const cmd_locality_table_t  &cmd_lt,       // command locality table
+	            const rsp_routing_table_t   &rsp_rt,       // response routing table
+	            const rsp_locality_table_t  &rsp_lt,       // response locality table
+	            const size_t                n_inits,       // number of initators
+	            const size_t                n_targets,     // number of targets
+	            const size_t                delay );       // interconnect latency
+
+  // Local interconnect without identifier
+  Interconnect( sc_core::sc_module_name     module_name,   // module name
+	            const cmd_routing_table_t   &cmd_rt,       // command routing table
+	            const cmd_locality_table_t  &cmd_lt,       // command locality table
+	            const rsp_routing_table_t   &rsp_rt,       // response routing table
+	            const rsp_locality_table_t  &rsp_lt,       // response locality table
+	            size_t                      n_inits,       // number of initators
+	            size_t                      n_targets,     // number of targets
+	            size_t                      delay );       // interconnect latency
 
   ~Interconnect();
 
diff --git a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/include/vci_vgmn.h b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/include/vci_vgmn.h
index cd5242209bbfe9ee5fcc4f7f4614701bad497984..c609caa48519e8408ecae73531388fbb83a9ea83 100644
--- a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/include/vci_vgmn.h
+++ b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/include/vci_vgmn.h
@@ -20,41 +20,128 @@
  * 
  * SOCLIB_LGPL_HEADER_END
  *
- * Maintainers: fpecheux, alinevieiramello@hotmail.com
+ * Maintainers: alinevieiramello@hotmail.com, alain
  *
  * Copyright (c) UPMC / Lip6, 2008
- *     Fran�ois P�cheux <francois.pecheux@lip6.fr>
+ *     Fran�ois P�cheux <francois.pecheux@lip6.fr> 
  *     Aline Vieira de Mello <aline.vieira-de-mello@lip6.fr>
+ *     Alain Greiner <alain.greiner@lip6.fr> 
  */
 
 #ifndef __VCI_VGMN_H__ 
 #define __VCI_VGMN_H__
 
-#include <tlmdt>	                                        // TLM-DT headers
-#include "interconnect.h"                                       // interconnect
+#include <tlmdt>
+#include "centralized_buffer.h"
+#include "mapping_table.h"
 
 namespace soclib { namespace tlmdt {
 
-class VciVgmn                                                   // VciVgmn
-  : public Interconnect                  	                // inherit from SC module base clase
+////////////////////////
+class VciVgmn   
+////////////////////////
+  : public sc_core::sc_module  
 {
+
+private:
+ 
+    typedef soclib::common::AddressDecodingTable<uint64_t, size_t> cmd_routing_table_t;     
+    typedef soclib::common::AddressDecodingTable<uint32_t, bool>   cmd_locality_table_t;   
+    typedef soclib::common::AddressDecodingTable<uint32_t, size_t> rsp_routing_table_t; 
+    typedef soclib::common::AddressDecodingTable<uint32_t, bool>   rsp_locality_table_t;
+
+    /////////////////////////////////////////////////////////////////////////////////////
+    // Member Variables
+    /////////////////////////////////////////////////////////////////////////////////////
+
+    size_t                        m_inits;                // number of initiiators
+    size_t                        m_targets;              // number of targets
+    size_t                        m_latency;              // interconnect delay
+
+    centralized_buffer            m_central_buffer; 	  // input fifos
+ 
+    const cmd_routing_table_t     m_cmd_routing_table;    // command routing table
+    const rsp_routing_table_t     m_rsp_routing_table; 	  // response routing table
+
+    pdes_local_time*              m_pdes_local_time;      // local time (pointer)
+ 
+    sc_core::sc_event             m_cmd_received;         // any command received
+
+    // instrumentation counters
+    size_t                        m_push_vci_count;
+    size_t                        m_pop_vci_count;
+    size_t                        m_push_null_count;
+    size_t                        m_pop_null_count;
+    size_t                        m_push_activity_count;
+    size_t                        m_pop_activity_count;
+
+    size_t                        m_null_sent_count;
+
+    // FIELDS OF NULL TRANSACTION
+    tlm::tlm_generic_payload      m_null_payload;
+    tlm::tlm_phase                m_null_phase;
+    sc_core::sc_time              m_null_time;
+    soclib_payload_extension      m_null_extension;
+
+    /////////////////////////////////////////////////////////////////////////////////////
+    // Functions
+    /////////////////////////////////////////////////////////////////////////////////////
+
+    void execLoop(void);
+
+    void route ( size_t                   from,       // port source
+                 tlm::tlm_generic_payload &payload,   // payload
+                 tlm::tlm_phase           &phase,     // phase
+                 sc_core::sc_time         &time);     // time
+
+    /////////////////////////////////////////////////////////////////////////////////////
+    // Function executed when receiving command from VCI initiator[id]
+    /////////////////////////////////////////////////////////////////////////////////////
+    tlm::tlm_sync_enum nb_transport_fw ( int                      id,         
+                                         tlm::tlm_generic_payload &payload,
+                                         tlm::tlm_phase           &phase,
+                                         sc_core::sc_time         &time); 
+ 
+    /////////////////////////////////////////////////////////////////////////////////////
+    // Function executed when receiving response from VCI target[id]
+    /////////////////////////////////////////////////////////////////////////////////////
+    tlm::tlm_sync_enum nb_transport_bw ( int                      id,       
+                                         tlm::tlm_generic_payload &payload,
+                                         tlm::tlm_phase           &phase, 
+                                         sc_core::sc_time         &time );
+
+protected:
+
+    SC_HAS_PROCESS( VciVgmn );
+
 public:  
 
-  VciVgmn(                                                // constructor
-	  sc_core::sc_module_name module_name             // SC module name
-	  , const soclib::common::MappingTable &mt        // mapping table
-	  , size_t n_inits                                // number of inits
-	  , size_t n_targets                              // number of targets
-	  , size_t min_latency                            // minimal latency
-	  , size_t fifo_depth);                           // parameter do not used
-  
-  VciVgmn(                                                // constructor
-	  sc_core::sc_module_name module_name             // SC module name
-	  , const soclib::common::MappingTable &mt        // mapping table
-	  , const soclib::common::IntTab &index           // mapping table index
-	  , int n_inits                                   // number of inits
-	  , int n_targets                                 // number of targets
-	  , sc_core::sc_time delay);                      // interconnect delay
+    std::vector<tlm_utils::simple_target_socket_tagged
+    <VciVgmn,32,tlm::tlm_base_protocol_types> *>             p_to_initiator;
+
+    std::vector<tlm_utils::simple_initiator_socket_tagged
+    <VciVgmn,32,tlm::tlm_base_protocol_types> *>             p_to_target;
+
+    ////////////////////////////////
+    // Constructor
+    ////////////////////////////////
+
+    VciVgmn( sc_core::sc_module_name             name,         // module name
+	         const soclib::common::MappingTable  &mt,          // mapping table
+	         const size_t                        n_inits,      // number of initiators
+	         const size_t                        n_targets,    // number of targets
+             const size_t                        min_latency,  // interconnect latency
+             const size_t                        fifo_depth,   // unused in tlmdt
+             const size_t                        default_tgtid = 0 );
+
+    ~VciVgmn() {}
+
+    ////////////////////////////////////////
+    // Instrumentation functions
+    ////////////////////////////////////////
+
+    void print();
+
 };
 
 }}
diff --git a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/src/centralized_buffer.cpp b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/src/centralized_buffer.cpp
index 5257089ab07b4bdf4324ffe129dfa9a9953d20b0..2519c59657d14f3564716ec2b54f6007319fb992 100644
--- a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/src/centralized_buffer.cpp
+++ b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/src/centralized_buffer.cpp
@@ -32,150 +32,157 @@
 
 namespace soclib { namespace tlmdt {
 
-class _command
-{
-  friend class centralized_buffer;
-  
-  circular_buffer         buffer;
-  sc_core::sc_time        delta_time;
-  bool                    active;
-
-public:
-  _command()
-    : buffer()
-    , delta_time(sc_core::SC_ZERO_TIME)
-  {
-    active = true;
-  }
-
-};
-
-centralized_buffer::centralized_buffer
-( sc_core::sc_module_name module_name,               // module name
-  size_t nslots )
-  : sc_module(module_name)
+////////////////////////////////////////////////////////////////////////////
+//   constructor / destructor for central buffer
+////////////////////////////////////////////////////////////////////////////
+centralized_buffer::centralized_buffer ( sc_core::sc_module_name   name,
+                                         size_t                    nslots )
+  : sc_module(name)
   , m_slots(nslots)
-  , m_centralized_struct(new _command[nslots])
+  , m_port_array(new init_port_descriptor[nslots])
+  , m_previous( nslots - 1 )
 {
-  for(unsigned int i=0; i<nslots; i++){
-    std::ostringstream buf_name;
-    buf_name << name() << "_buf" << i;
-    m_centralized_struct[i].buffer.set_name(buf_name.str());
-  }
+    for(unsigned int i=0; i<nslots; i++)
+    {
+        std::ostringstream buf_name;
+        buf_name << "slot_" << i;
+        m_port_array[i].buffer.set_name(buf_name.str());
+    }
 }
 
 centralized_buffer::~centralized_buffer()
 {
-  delete [] m_centralized_struct;
+  delete [] m_port_array;
 }
 
-bool centralized_buffer::push
-( size_t                    from,
-  tlm::tlm_generic_payload &payload,
-  tlm::tlm_phase           &phase,
-  sc_core::sc_time         &time)
+///////////////////////////////////////////////////////////////
+// This function push a transaction (payload, phase, time)
+// in the circular buffer associated to initiator (from)
+///////////////////////////////////////////////////////////////
+bool centralized_buffer::push ( size_t                    from,
+                                tlm::tlm_generic_payload  &payload,
+                                tlm::tlm_phase            &phase,
+                                sc_core::sc_time          &time)
 {
+
 #if SOCLIB_MODULE_DEBUG
-  std::cout << "[" << name() << "] PUSH [" << from <<"] " << std::endl;
+std::cout << "[" << name() << "] PUSH [" << from <<"] " << std::endl;
 #endif
 
-  assert(!(time < m_centralized_struct[from].delta_time) && "PUSH transaction with the time smaller than the precedent");
+    assert(!(time < m_port_array[from].port_time) and
+    "PUSH transaction in a slot with a time smaller than precedent");
 
-  return m_centralized_struct[from].buffer.push(payload, phase, time);
+    return m_port_array[from].buffer.push(payload, phase, time);
 }
 
-    
-bool centralized_buffer::pop
-( size_t                    &from,
-  tlm::tlm_generic_payload *&payload,
-  tlm::tlm_phase           *&phase,
-  sc_core::sc_time         *&time)
+///////////////////////////////////////////////////////////////////////////////
+// This function implements the PDES time filtering algorithm:
+// All active initiators are scanned, to select the earliest date.
+// - if there is no transaction for this initiator, (false) is returned,
+//   and no transaction is consumed in the central buffer.
+// - if there is a transaction, (true) is returned. The selected 
+//   initiator index is returned in (from). The transaction parameters 
+//   are returned in (payload, phase, time), the transaction is 
+//   removed from the central buffer, and the selected port time is updated.
+///////////////////////////////////////////////////////////////////////////////
+bool centralized_buffer::pop ( size_t                    &from,
+                               tlm::tlm_generic_payload* &payload,
+                               tlm::tlm_phase*           &phase,
+                               sc_core::sc_time*         &time )
 {
-  bool ok = false;
-  int min_idx = -1;
-  uint64_t min_time = MAX_TIME;
-  uint64_t time_value;
+    uint64_t min_time = MAX_TIME;
+    size_t sel_id = 0;              // selected port
+    uint64_t time_value;            // date of the port
   
-  for(unsigned int i=0; i<m_slots; i++){
-    if(m_centralized_struct[i].active){
-      if(m_centralized_struct[i].buffer.is_empty()){
-	time = &m_centralized_struct[i].delta_time;
-	time_value = (*time).value();
-#if SOCLIB_MODULE_DEBUG
-	std::cout << "[" << name() << "] MD FOR POP " << i << " IS EMPTY time = " << time_value << std::endl;
-#endif
-	if(time_value < min_time){
-	  min_idx = i;
-	  min_time = time_value;
-	  ok = false;
-	}
-      }
-      else{
-	bool header = m_centralized_struct[i].buffer.get_front(payload, phase, time);
-	assert(header);
-	time_value = (*time).value();
-	  
-#if SOCLIB_MODULE_DEBUG
-	std::cout << "[" << name() << "] MD FOR POP " << i << " NOT EMPTY time = " << time_value << std::endl;
-#endif
-
-	if(time_value < min_time || time_value == min_time){
-	  min_idx = i;
-	  min_time = time_value;
-	  ok = true;
-	}
-      }
+    // searching the earliest (smaller time) active port
+    // we implement a round-robin priority because,
+    // in case of equal times, the first found is selected
+    for( size_t k=0 ; k<m_slots ; k++ )
+    {
+        size_t i = (m_previous + k + 1) % m_slots;
+
+        if(m_port_array[i].active)   // only active ports are competing
+        {
+            // get time
+            if(m_port_array[i].buffer.is_empty())   // no transaction available
+            {
+	            time_value = m_port_array[i].port_time.value();
+
+std::cout << "@@@ port " << i << " / empty / time = " << std::dec << time_value << std::endl;
+
+            }
+            else                                    // front transaction is earliest
+            {
+	            m_port_array[i].buffer.get_front(payload, phase, time);
+	            time_value = (*time).value();
+
+std::cout << "@@@ port " << i << " /  ok   / time = " << std::dec << time_value << std::endl;
+
+            }
+
+            // test if it is the earliest
+            if(time_value < min_time)
+            {
+	            min_time = time_value;
+                sel_id   = i;
+	        }
+        }
     }
-  }
 
-  from = min_idx;
-
-  if(ok){
-#if SOCLIB_MODULE_DEBUG
-  std::cout << "[" << name() << "] POP from " << min_idx << std::endl;
-#endif
-    bool pop = m_centralized_struct[min_idx].buffer.pop(payload, phase, time);
-    assert(pop);
-  }
-  else{
-#if SOCLIB_MODULE_DEBUG
-    std::cout << "[" << name() << "] NOT POP from " << min_idx << " IS EMPTY" << std::endl;
-#endif
-  }
-
-  return ok;
-}
+    if( not m_port_array[sel_id].buffer.is_empty() )    // success
+    {
+        m_port_array[sel_id].buffer.pop( payload,
+                                         phase,
+                                         time);
+        from = sel_id;      
+        m_previous = sel_id;
+        set_port_time( sel_id, *time );
+        return true;
+    }
+    else                                                 // no eligible command
+    {
+        return false;
+    }
+} // end pop()
    
-
-circular_buffer centralized_buffer::get_buffer(int i)
+////////////////////////////////////////////////////////////
+circular_buffer centralized_buffer::get_buffer(size_t index)
 {
-  return m_centralized_struct[i].buffer;
+    return m_port_array[index].buffer;
 }
 
+/////////////////////////////////////////////
 const size_t centralized_buffer::get_nslots()
 {
-  return m_slots;
+    return m_slots;
 }
 
-sc_core::sc_time centralized_buffer::get_delta_time(unsigned int index)
+////////////////////////////////////////////////////////////////
+sc_core::sc_time centralized_buffer::get_port_time(size_t index)
 {
-  return m_centralized_struct[index].delta_time;
+    return m_port_array[index].port_time;
 }
 
-void centralized_buffer::set_delta_time(unsigned int index, sc_core::sc_time t)
+////////////////////////////////////////////////////////////////////////
+void centralized_buffer::set_port_time(size_t index, sc_core::sc_time t)
 {
-  m_centralized_struct[index].delta_time = t;
+    m_port_array[index].port_time = t;
+
 #if SOCLIB_MODULE_DEBUG
-  std::cout << "[" << name() << "] DELTA_TIME[" << index <<"] = " << t.value() << std::endl;
+std::cout << "[" << name() << "] DELTA_TIME[" << index <<"] = " << t.value() << std::endl;
 #endif
+
 }
 
-void centralized_buffer::set_activity(unsigned int index, bool b)
+///////////////////////////////////////////////////////////
+void centralized_buffer::set_activity(size_t index, bool b)
 {
-  m_centralized_struct[index].active = b;
+    m_port_array[index].active = b;
+
 #if SOCLIB_MODULE_DEBUG
-  std::cout << "[" << name() << "] ACTIVE[" << index <<"] = " << b << std::endl;
+std::cout << "[" << name() << "] ACTIVE[" << index <<"] = " << b << std::endl;
 #endif
+
 }
 
 }}
diff --git a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/src/interconnect.cpp b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/src/interconnect.cpp
index cfd1343731da60fe454832504ea0bf37c0d317b2..0ef58394842a465a4dc8605b313c1fb4cbb87dc0 100644
--- a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/src/interconnect.cpp
+++ b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/src/interconnect.cpp
@@ -27,28 +27,28 @@
  *     Aline Vieira de Mello <aline.vieira-de-mello@lip6.fr>
  */
 
-#include "interconnect.h"                           // our header
+#include "interconnect.h" 
                     
-//#define SOCLIB_MODULE_DEBUG 1
+#define SOCLIB_MODULE_DEBUG 1
 
 namespace soclib { namespace tlmdt {
 
 #define tmpl(x) x Interconnect
 
 /////////////////////////////////////////////////////////////////////////////////////
-// Constructor
+//             Constructors
 /////////////////////////////////////////////////////////////////////////////////////
-tmpl(/**/)::Interconnect
-( sc_core::sc_module_name module_name               // module name
-  , int id                                          // identifier
-  , const routing_table_t &rt                       // routing table
-  , const locality_table_t &lt                      // locality table
-  , const resp_routing_table_t &rrt                 // response routing table
-  , const resp_locality_table_t &rlt                // response locality table
-  , size_t n_inits                                  // number of inits
-  , size_t n_targets                                // number of targets
-  , size_t delay                                    // interconnect delay
-  ) 
+
+// Local interconnect
+tmpl(/**/)::Interconnect( sc_core::sc_module_name    module_name,
+                          const size_t               id,
+                          const cmd_routing_table_t  &cmd_rt,
+                          const cmd_locality_table_t &cmd_lt,
+                          const rsp_routing_table_t  &rsp_rt,
+                          const rsp_locality_table_t &rsp_lt,
+                          const size_t               n_inits,
+                          const size_t               n_targets,
+                          const size_t               delay )
   : sc_module(module_name)
   , m_id(id)
   , m_inits(n_inits)
@@ -56,10 +56,10 @@ tmpl(/**/)::Interconnect
   , m_delay(delay)
   , m_is_local_crossbar(true)
   , m_centralized_buffer("centralized_buffer", n_inits)
-  , m_routing_table(rt)
-  , m_locality_table(lt)
-  , m_resp_routing_table(rrt)
-  , m_resp_locality_table(rlt)
+  , m_cmd_routing_table(cmd_rt)
+  , m_cmd_locality_table(cmd_lt)
+  , m_rsp_routing_table(rsp_rt)
+  , m_rsp_locality_table(rsp_lt)
   , m_msg_count(0)
   , m_local_msg_count(0)
   , m_non_local_msg_count(0)
@@ -68,16 +68,15 @@ tmpl(/**/)::Interconnect
   init();
 }
 
-tmpl(/**/)::Interconnect
-( sc_core::sc_module_name module_name               // module name
-  , const routing_table_t &rt                       // routing table
-  , const locality_table_t &lt                      // locality table
-  , const resp_routing_table_t &rrt                 // response routing table
-  , const resp_locality_table_t &rlt                // response locality table
-  , size_t n_inits                                  // number of inits
-  , size_t n_targets                                // number of targets
-  , size_t delay                                    // interconnect delay
-  ) 
+// Local interconnect without identfier
+tmpl(/**/)::Interconnect( sc_core::sc_module_name    module_name,
+                          const cmd_routing_table_t  &cmd_rt,
+                          const cmd_locality_table_t &cmd_lt,
+                          const rsp_routing_table_t  &rsp_rt,
+                          const rsp_locality_table_t &rsp_lt,
+                          const size_t               n_inits,
+                          const size_t               n_targets,
+                          const size_t               delay )
   : sc_module(module_name)
   , m_id(0)
   , m_inits(n_inits)
@@ -85,10 +84,10 @@ tmpl(/**/)::Interconnect
   , m_delay(delay)
   , m_is_local_crossbar(true)
   , m_centralized_buffer("centralized_buffer", n_inits)
-  , m_routing_table(rt)
-  , m_locality_table(lt)
-  , m_resp_routing_table(rrt)
-  , m_resp_locality_table(rlt)
+  , m_cmd_routing_table(cmd_rt)
+  , m_cmd_locality_table(cmd_lt)
+  , m_rsp_routing_table(rsp_rt)
+  , m_rsp_locality_table(rsp_lt)
   , m_msg_count(0)
   , m_local_msg_count(0)
   , m_non_local_msg_count(0)
@@ -97,15 +96,14 @@ tmpl(/**/)::Interconnect
   init();
 }
 
-tmpl(/**/)::Interconnect
-( sc_core::sc_module_name module_name               // module name
-  , int id                                          // identifier
-  , const routing_table_t &rt                       // routing table
-  , const resp_routing_table_t &rrt                 // response routing table
-  , size_t n_inits                                  // number of inits
-  , size_t n_targets                                // number of targets
-  , size_t delay                                    // interconnect delay
-  ) 
+// Global interconnect
+tmpl(/**/)::Interconnect( sc_core::sc_module_name    module_name,
+                          const size_t               id,
+                          const cmd_routing_table_t  &cmd_rt,
+                          const rsp_routing_table_t  &rsp_rt,
+                          const size_t               n_inits,
+                          const size_t               n_targets,
+                          const size_t               delay )
   : sc_module(module_name)
   , m_id(id)
   , m_inits(n_inits)
@@ -113,8 +111,8 @@ tmpl(/**/)::Interconnect
   , m_delay(delay)
   , m_is_local_crossbar(false)
   , m_centralized_buffer("centralized_buffer", n_inits)
-  , m_routing_table(rt)
-  , m_resp_routing_table(rrt)
+  , m_cmd_routing_table(cmd_rt)
+  , m_rsp_routing_table(rsp_rt)
   , m_msg_count(0)
   , m_local_msg_count(0)
   , m_non_local_msg_count(0)
@@ -123,14 +121,13 @@ tmpl(/**/)::Interconnect
   init();
 }
 
-tmpl(/**/)::Interconnect
-( sc_core::sc_module_name module_name               // module name
-  , const routing_table_t &rt                       // routing table
-  , const resp_routing_table_t &rrt                 // response routing table
-  , size_t n_inits                                  // number of inits
-  , size_t n_targets                                // number of targets
-  , size_t delay                                    // interconnect delay
-  ) 
+// Global interconnect without identifier
+tmpl(/**/)::Interconnect( sc_core::sc_module_name    module_name,
+                          const cmd_routing_table_t  &cmd_rt,
+                          const rsp_routing_table_t  &rsp_rt,
+                          const size_t               n_inits,
+                          const size_t               n_targets,
+                          const size_t               delay )
   : sc_module(module_name)
   , m_id(0)
   , m_inits(n_inits)
@@ -138,8 +135,8 @@ tmpl(/**/)::Interconnect
   , m_delay(delay)
   , m_is_local_crossbar(false)
   , m_centralized_buffer("centralized_buffer", n_inits)
-  , m_routing_table(rt)
-  , m_resp_routing_table(rrt)
+  , m_cmd_routing_table(cmd_rt)
+  , m_rsp_routing_table(rsp_rt)
   , m_msg_count(0)
   , m_local_msg_count(0)
   , m_non_local_msg_count(0)
@@ -148,30 +145,35 @@ tmpl(/**/)::Interconnect
   init();
 }
 
-tmpl(/**/)::~Interconnect(){
-}
+tmpl(/**/)::~Interconnect(){ }
 
 ///////////////////
 tmpl(void)::init()
 {
-    // bind VCI TARGET SOCKETS
-    for(int i=0;i<m_inits;i++)
+    // allocate & bind p_to_initiator[i] VCI ports
+    for(size_t i=0;i<m_inits;i++)
     {
-        std::ostringstream target_name;
-        target_name << "target" << i;
+        std::ostringstream name;
+        name << "p_to_initiator_" << i;
         p_to_initiator.push_back(new tlm_utils::simple_target_socket_tagged
-           <Interconnect,32,tlm::tlm_base_protocol_types>(target_name.str().c_str()));
-        p_to_initiator[i]->register_nb_transport_fw(this, &Interconnect::nb_transport_fw, i);
+           <Interconnect,32,tlm::tlm_base_protocol_types>(name.str().c_str()));
+
+        p_to_initiator[i]->register_nb_transport_fw( this, 
+                                                     &Interconnect::nb_transport_fw, 
+                                                     i );
     }
 
-    // bind VCI INITIATOR SOCKETS
-    for(int i=0;i<m_targets;i++)
+    // allocate & bind p_to_target[i] VCI ports
+    for(size_t i=0;i<m_targets;i++)
     {
-        std::ostringstream init_name;
-        init_name << "init" << i;
+        std::ostringstream name;
+        name << "p_to_target_" << i;
         p_to_target.push_back(new tlm_utils::simple_initiator_socket_tagged
-           <Interconnect,32,tlm::tlm_base_protocol_types>(init_name.str().c_str()));
-        p_to_target[i]->register_nb_transport_bw(this, &Interconnect::nb_transport_bw, i);
+           <Interconnect,32,tlm::tlm_base_protocol_types>(name.str().c_str()));
+
+        p_to_target[i]->register_nb_transport_bw( this, 
+                                                  &Interconnect::nb_transport_bw, 
+                                                  i );
     }
 
     // minimal local latency
@@ -196,25 +198,32 @@ tmpl(void)::init()
     }
 
     // register thread process
-    SC_THREAD(behavior);                  
+    SC_THREAD(execLoop);                  
 }
 
 /////////////////////////////////////////////////////////////////////////////////////
-// Functions
+// Instrumentation Functions
 /////////////////////////////////////////////////////////////////////////////////////
-tmpl(uint32_t)::getLocalMsgCounter(){
+tmpl(uint32_t)::getLocalMsgCounter()
+{
   return m_local_msg_count;
 }
 
-tmpl(uint32_t)::getNonLocalMsgCounter(){
+///////////////////////////////////////
+tmpl(uint32_t)::getNonLocalMsgCounter()
+{
   return m_non_local_msg_count;
 }
 
-tmpl(uint32_t)::getTokenMsgCounter(){
+////////////////////////////////////
+tmpl(uint32_t)::getTokenMsgCounter()
+{
   return m_token_msg_count;
 }
 
-tmpl(void)::print(){
+///////////////////
+tmpl(void)::print()
+{
   uint32_t local_msg_count     = getLocalMsgCounter();
   uint32_t non_local_msg_count = getNonLocalMsgCounter();
   uint32_t token_msg_count     = getTokenMsgCounter();
@@ -227,36 +236,41 @@ tmpl(void)::print(){
 
 }
 
-///////////////////////////////////////////////////////
-tmpl(void)::routing( size_t                       from,      
-                     tlm::tlm_generic_payload    &payload, 
-                     tlm::tlm_phase              &phase,  
-                     sc_core::sc_time            &time)  
+////////////////////////////////////////////////////////////////////////////////
+// This function analyses the transaction poped from the the central buffer,
+// and execute the required action.
+////////////////////////////////////////////////////////////////////////////////
+tmpl(void)::route( size_t                     from,      
+                   tlm::tlm_generic_payload   &payload, 
+                   tlm::tlm_phase             &phase,  
+                   sc_core::sc_time           &time)  
 {
-    bool 	send;
-    int 	dest;
+    bool 	send_required; 
+    size_t  dest;
 
     // get payload extension
     soclib_payload_extension *extension_ptr;
     payload.get_extension(extension_ptr);
 
-    ///////////////////////////////////////////////////////////////
-    // if transaction command is activation/deactivation
-    // the source is actived or desactived and no transaction is sent
+    /////////////////////////////////////////////////////////////////////////
+    // if message is activation/deactivation, the corresponding
+    // initiator port is actived/desactived, but no message is sent.
     if(extension_ptr->is_active() || extension_ptr->is_inactive())
     {
 
 #ifdef SOCLIB_MODULE_DEBUG
-printf("[%s] time = %d  HANDLING ACTIVITY MSG from = %d\n", 
+printf("[%s] / time = %d / HANDLING ACTIVITY MSG from port %d\n", 
        name(), (int)time.value(), (int)from);
 #endif
-
-        send = false;
+        // initiator port activation/deactivation 
         m_centralized_buffer.set_activity(from, extension_ptr->is_active());
+
+        send_required = false;
     }
 
-    /////////////////////////////////////////////////////////////////////////
-    // if transaction command is a token, it must be sent to the target[from]
+    ////////////////////////////////////////////////////////////////////////////
+    // if transaction command is a token, it must be sent to the target
+    // corresponding to the source initiator
     else if(extension_ptr->is_token_message())
     {
 
@@ -268,7 +282,7 @@ printf("[%s] time = %d  HANDLING TOKEN MSG from = %d\n",
         // set the delta_time which this init wont send another message
         m_centralized_buffer.set_delta_time(from, time);
 
-        send = true;
+        send_required = true;
 
         m_msg_count++;
         m_token_msg_count++;
@@ -276,7 +290,7 @@ printf("[%s] time = %d  HANDLING TOKEN MSG from = %d\n",
         if ( m_is_local_crossbar )
         {
             dest = m_targets - 1;
-            extension_ptr->set_pkt_id(extension_ptr->get_pkt_id()+1);
+            extension_ptr->set_pkt_id(extension_ptr->get_pkt_id()+1); // ??? AG
         }
         else
         {
@@ -285,8 +299,8 @@ printf("[%s] time = %d  HANDLING TOKEN MSG from = %d\n",
     }
 
     //////////////////////////////////////////////////////////////////////////////////
-    // if transaction command is a null message, the response is sent to the initiator
-    // to synchronize it, but this null message is not transmited
+    // if transaction command is a null message, a response is sent to the initiator
+    // to synchronize it, but this null message is not transmited.
     else if(extension_ptr->is_null_message())
     {
 
@@ -301,59 +315,63 @@ printf("[%s] time = %d  HANDLING NULL MSG from = %d\n",
         // send the response
         (*p_to_initiator[from])->nb_transport_bw(payload, phase, time);
 
-        send = false;
+        send_required = false;
     }
 
     ///////////////////////////////////////////////////////////////////////////////
     // if transaction is a VCI command, it must be sent to appropriated target
-    // no response is sent to the initiator
+    // no response is sent to the initiator.
     else
     {
-        send = true;
+        send_required = true;
+
         if(m_is_local_crossbar)  // local interconnect
         {
-            if (!m_locality_table[payload.get_address()]) // non local target
+            if ( not m_cmd_locality_table[payload.get_address()] ) // non local target
             {
-	        if(from == m_centralized_buffer.get_nslots()-1)
+	            if(from == m_centralized_buffer.get_nslots()-1)
                 {
-	            // set the delta_time which this init wont send another message
-	            m_centralized_buffer.set_delta_time(from, time);
-	        }
-	        else
+	                // set the delta_time which this init wont send another message
+	                m_centralized_buffer.set_delta_time(from, time);
+	            }
+	            else
                 {
-	            // set the delta_time which this init wont send another message
-	            m_centralized_buffer.set_delta_time(from, time + (m_no_local_delta_time*UNIT_TIME));
-	        }
+	                // set the delta_time which this init wont send another message
+	                m_centralized_buffer.set_delta_time(from, 
+                        time + (m_no_local_delta_time*UNIT_TIME));
+	            }
 	
-	        m_msg_count++;
-	        m_non_local_msg_count++;
-	        dest = m_targets - 1;
+                m_msg_count++;
+                m_non_local_msg_count++;
+                dest = m_targets - 1;
             }
             else  // local target
             {
-	        if(from == m_centralized_buffer.get_nslots()-1)
+	            if(from == m_centralized_buffer.get_nslots()-1)
                 {
-	            //set the delta_time which this init wont send another message
-	            m_centralized_buffer.set_delta_time(from, time);
-	        }
-	        else
+	                //set the delta_time which this init wont send another message
+	                m_centralized_buffer.set_delta_time(from, time);
+	            }
+	            else
                 {
-	            //set the delta_time which this init wont send another message
-	            m_centralized_buffer.set_delta_time(from, time + (m_local_delta_time*UNIT_TIME));
-	        }
+	                //set the delta_time which this init wont send another message
+	                m_centralized_buffer.set_delta_time(from, 
+                         time + (m_local_delta_time*UNIT_TIME));
+	            }
 	
-	        m_msg_count++;
-	        m_local_msg_count++;
-	        dest = m_routing_table[payload.get_address()];
-	        assert( dest >= 0 && dest < m_targets );
+	            m_msg_count++;
+	            m_local_msg_count++;
+	            dest = m_cmd_routing_table[payload.get_address()];
+	            assert( dest >= 0 && dest < m_targets );
             }
         }
-        else  // global interconnect
+        else                 // global interconnect
         {
             // set the delta_time which this init wont send another message
             m_centralized_buffer.set_delta_time(from, time);
-            dest = m_routing_table[payload.get_address()];
-            assert( dest >= 0 && dest < m_targets );
+
+            dest = m_cmd_routing_table[payload.get_address()];
+            assert( dest < m_targets );
 	
             m_msg_count++;
             m_local_msg_count++;
@@ -366,17 +384,17 @@ printf("[%s] time = %d  ROUTING VCI MSG from = %d to %d\n",
 	
     }
 
-    if (send)  // transmit the command to the selected target
+    if (send_required)  // transmit the command to the selected target
     {
         time = time + (m_delay*UNIT_TIME);
         (*p_to_target[dest])->nb_transport_fw(payload, phase, time);
     }
-}  // end routing()
+}  // end route()
   
 //////////////////////////
 tmpl(void)::create_token()
 {
-  // create token message in beginning of simulation
+  // create token message at beginning of simulation
   m_extension_token.set_token_message();
   m_extension_token.set_src_id(m_id);
   m_extension_token.set_pkt_id(0);
@@ -390,15 +408,16 @@ printf("[%s] send Token time = %d\n", name(), (int)m_time_token.value());
 
   //push a token in the centralized buffer
   m_centralized_buffer.push(m_inits-1, m_payload_token, m_phase_token, m_time_token);
+
 #ifdef SOCLIB_MODULE_DEBUG
-  printf("[%s] send Token time = %d\n", name(), (int)m_time_token.value());
+printf("[%s] send Token time = %d\n", name(), (int)m_time_token.value());
 #endif
 }
 
 /////////////////////////////////////////////////////////////////////////////////////
-//  consumer thread 
+//      PDES process 
 /////////////////////////////////////////////////////////////////////////////////////
-tmpl(void)::behavior()  
+tmpl(void)::execLoop()  
 {
     size_t                    	from;
     tlm::tlm_generic_payload* 	payload_ptr;
@@ -413,36 +432,39 @@ printf("[%s] WHILE CONSUMER\n", name());
 #endif
 
         // pop the earliest transaction from centralized buffer
-        while(m_centralized_buffer.pop(from, payload_ptr, phase_ptr, time_ptr))
+        while( m_centralized_buffer.pop( from, payload_ptr, phase_ptr, time_ptr) )
         {
             m_pop_count++;
 
-            assert(!(*time_ptr < m_pdes_local_time->get()) 
-                   && "Transaction time must not be smaller than the interconnect time");
+            assert( not (*time_ptr < m_pdes_local_time->get()) 
+            && "Transaction time must not be smaller than the interconnect time");
  
             // update local time
             m_pdes_local_time->set(*time_ptr);
 
             // process the transaction
-            routing(from, *payload_ptr, *phase_ptr, *time_ptr);
+            route( from, *payload_ptr, *phase_ptr, *time_ptr);
+
         } // end while buffer not empty
     
         // send periodically NULL messages to all local targets 
-        // if it is a local interconnect
+        // if this interconnect is a local interconnect
         if ( m_is_local_crossbar && m_pdes_local_time->need_sync() )
         {
             m_pdes_local_time->reset_sync();
             m_null_time = m_pdes_local_time->get();
-            for ( int i=0 ; i<(m_targets-1) ; i++ )
+            for ( size_t i=0 ; i<(m_targets-1) ; i++ )
+            {
                 (*p_to_target[i])->nb_transport_fw(m_null_payload, 
                                                    m_null_phase, 
                                                    m_null_time);
+            }
         }
 
 #ifdef SOCLIB_MODULE_DEBUG
 printf("[%s] CONSUMER WAITING id = %d\n", name(), (int)from);
 #endif
-
+        // deschedule if buffer empty
         sc_core::wait(sc_core::SC_ZERO_TIME);
 
 #ifdef SOCLIB_MODULE_DEBUG
@@ -453,8 +475,8 @@ printf("[%s] CONSUMER WAKE-UP\n", name());
 }
     
 /////////////////////////////////////////////////////////////////////////////////////
-// Interface function executed when receiving a command on an initiator port
-// It registers the command in the central buffer
+// Interface function executed when receiving a command from a VCI initiator.
+// It registers the command in the central buffer, to make time filtering.
 /////////////////////////////////////////////////////////////////////////////////////
 tmpl(tlm::tlm_sync_enum)::nb_transport_fw   (int                         id,          
                                              tlm::tlm_generic_payload    &payload,    
@@ -467,31 +489,32 @@ tmpl(tlm::tlm_sync_enum)::nb_transport_fw   (int                         id,
     {
 
 #ifdef SOCLIB_MODULE_DEBUG
-printf("[%s] time = %d RECEIVE a COMMAND on port %d\n", name(), (int)time.value(), id);
+printf( "[%s] RECEIVE COMMAND from INITIATOR %d / time = %d \n", 
+       name(), id, (int)time.value() );
 #endif
 
-        //push a transaction in the centralized buffer
+        // push a transaction in the centralized buffer
         push = m_centralized_buffer.push(id, payload, phase, time);
 
-        if(!push)
+        if( not push )
         {
             try_push++;
 
 #ifdef SOCLIB_MODULE_DEBUG
-printf("[%s] PRODUCER id = %d <<<<<<<<< NOT PUSH >>>>>>>> try_push = %d \n",name(),id, try_push);
+printf("[%s] INITIATOR %d <<<<<<<<< CANNOT PUSH >>>>>>>>\n", name(),id);
 #endif
 
-            sc_core::wait(sc_core::SC_ZERO_TIME);
+            sc_core::wait( sc_core::SC_ZERO_TIME );
         }
-    } while (!push);
+    } while ( not push );
 
     return  tlm::TLM_COMPLETED;
 
 } //end nb_transport_fw
 
 /////////////////////////////////////////////////////////////////////////////////////
-// Interface function executed when receiving a response on a target port
-// It directly routes the response to the proper initiator
+// Interface function executed when receiving a response from target port.
+// It directly routes the response to the proper VCI initiator (no time filtering).
 /////////////////////////////////////////////////////////////////////////////////////
 tmpl(tlm::tlm_sync_enum)::nb_transport_bw ( int                        id,   
                                             tlm::tlm_generic_payload   &payload,  
@@ -507,25 +530,25 @@ tmpl(tlm::tlm_sync_enum)::nb_transport_bw ( int                        id,
     srcid = resp_extension_ptr->get_src_id();
   
 #ifdef SOCLIB_MODULE_DEBUG
-printf("[%s] time = %d  RECEIVE RESPONSE on port %d / srcid = %d\n", 
+printf("[%s] / time = %d / RECEIVE RESPONSE from port %d for initiator %d\n", 
         name(), (int)time.value(), id, srcid);
 #endif
 
     if(m_is_local_crossbar)
     {
-        if (!m_resp_locality_table[srcid])  	dest = m_inits - 1;
-        else  					dest = m_resp_routing_table[srcid]; 
+        if (!m_rsp_locality_table[srcid]) dest = m_inits - 1;
+        else                              dest = m_rsp_routing_table[srcid]; 
     }
     else	// global interconnect
     {
-    						dest = m_resp_routing_table[srcid];
+        dest = m_rsp_routing_table[srcid];
     }
 
     // update the transaction time
     time = time + (m_delay*UNIT_TIME);
   
 #ifdef SOCLIB_MODULE_DEBUG
-printf("[%s] time = %d  SEND RESPONSE on port %d / srcid = %d\n", 
+printf("[%s] / time = %d / SEND RESPONSE on port %d\n", 
         name(), (int)time.value(), dest, srcid);
 #endif
 
diff --git a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/src/vci_vgmn.cpp b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/src/vci_vgmn.cpp
index 546650597e409da3eb23d0f77c01cdb3f01a87d4..830621da2366000c5f5a3d9995c5feb352d2789e 100644
--- a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/src/vci_vgmn.cpp
+++ b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/src/vci_vgmn.cpp
@@ -20,33 +20,327 @@
  * 
  * SOCLIB_LGPL_HEADER_END
  *
- * Maintainers: fpecheux, alinevieiramello@hotmail.com
+ * Maintainers: alinevieiramello@hotmail.com, alain
  *
  * Copyright (c) UPMC / Lip6, 2008
  *     Fran�ois P�cheux <francois.pecheux@lip6.fr>
  *     Aline Vieira de Mello <aline.vieira-de-mello@lip6.fr>
+ *     Alain Greiner <alain.greiner@lip6.fr>
  */
 
-#include "vci_vgmn.h"                        // our header
+#include "vci_vgmn.h"       
+
+#define SOCLIB_MODULE_DEBUG 1
                     
 namespace soclib { namespace tlmdt {
 
 #define tmpl(x) x VciVgmn
 
+////////////////////////////////////////////////////////////////////////////////////////////
+tmpl(/**/)::VciVgmn ( sc_core::sc_module_name             name,           // module name
+                      const soclib::common::MappingTable  &mt,            // mapping table
+                      const size_t                        n_inits,        // number of initiators
+                      const size_t                        n_targets,      // number of targets
+                      const size_t                        min_latency,    // minimal latency
+                      const size_t                        fifo_depth,     // not used in TLMDT
+                      const size_t                        default_tgtid ) // default target index
+  : sc_module( name )
+  , m_inits( n_inits )
+  , m_targets( n_targets )
+  , m_latency( min_latency )
+  , m_central_buffer( "central_buffer", n_inits )
+  , m_cmd_routing_table( mt.getGlobalIndexFromAddress( default_tgtid ) )
+  , m_rsp_routing_table( mt.getGlobalIndexFromSrcid() )
+  , m_push_vci_count( 0 )
+  , m_pop_vci_count( 0 )
+  , m_push_null_count( 0 )
+  , m_pop_null_count( 0 )
+  , m_push_activity_count( 0 )
+  , m_pop_activity_count( 0 )
+  , m_null_sent_count( 0 )
+{
+    // allocate & bind p_to_initiator VCI ports
+    for( size_t i=0 ; i<m_inits ; i++ )
+    {
+        std::ostringstream name;
+        name << "p_to_initiator_" << i;
+        p_to_initiator.push_back(new tlm_utils::simple_target_socket_tagged
+           <VciVgmn,32,tlm::tlm_base_protocol_types>(name.str().c_str()));
+
+        p_to_initiator[i]->register_nb_transport_fw( this, 
+                                                     &VciVgmn::nb_transport_fw, 
+                                                     i );
+    }
+
+    // allocate & bind p_to_target VCI ports
+    for( size_t i=0 ; i<m_targets ; i++ )
+    {
+        std::ostringstream name;
+        name << "p_to_target_" << i;
+        p_to_target.push_back(new tlm_utils::simple_initiator_socket_tagged
+           <VciVgmn,32,tlm::tlm_base_protocol_types>(name.str().c_str()));
+
+        p_to_target[i]->register_nb_transport_bw( this, 
+                                                  &VciVgmn::nb_transport_bw, 
+                                                  i );
+    }
+
+    // PDES local time
+    m_pdes_local_time = new pdes_local_time(100*UNIT_TIME);
+
+    // initialises payload, phase and extension for null messages
+    m_null_payload.set_extension(&m_null_extension);
+    m_null_extension.set_null_message();
+    m_null_phase = tlm::BEGIN_REQ;
+
+    // register thread process
+    SC_THREAD(execLoop);                  
+} // end init()
+
+
+//////////////////////////////////////////////////////////////////////////////////////
+// This function analyses the type of transaction poped from the the central buffer,
+// and execute the required action.
+//////////////////////////////////////////////////////////////////////////////////////
+tmpl(void)::route( size_t                     from,       // initiator index
+                   tlm::tlm_generic_payload   &payload, 
+                   tlm::tlm_phase             &phase,  
+                   sc_core::sc_time           &time)  
+{
+    // get payload extension
+    soclib_payload_extension *extension_ptr;
+    payload.get_extension(extension_ptr);
+
+    // if message is activation/deactivation, the initiator port is actived/desactived, 
+    // but no message is transmit, and no response is returned
+    if( extension_ptr->is_active() || extension_ptr->is_inactive() )
+    {
+
+#ifdef SOCLIB_MODULE_DEBUG
+m_pop_activity_count++;
+printf("    [%s] handle ACTIVITY from port %d / time = %d \n", 
+       name(), (int)from, (int)time.value() );
+#endif
+        // initiator port activation/deactivation 
+        m_central_buffer.set_activity(from, extension_ptr->is_active());
+    }
+
+    // if transaction command is a NULL message, a response is sent to the initiator
+    // but this NULL message is not transmit.
+    else if( extension_ptr->is_null_message() )
+    {
+
+#ifdef SOCLIB_MODULE_DEBUG
+m_pop_null_count++;
+printf("    [%s] handle NULL from port %d / time = %d \n", 
+       name(), (int)from, (int)time.value() );
+#endif
+        // send the response
+        (*p_to_initiator[from])->nb_transport_bw( payload, 
+                                                  phase, 
+                                                  time);
+    }
+
+    // if transaction is a VCI command, it must be sent to the appropriate target,
+    // and no response is sent to the initiator.
+    else
+    {
+        size_t dest = m_cmd_routing_table[payload.get_address()];
+
+        assert( ( dest < m_targets ) and
+        "ERROR in VGMN: illegal target index" );
+	
+        time = time + (m_latency*UNIT_TIME);
+
+#ifdef SOCLIB_MODULE_DEBUG
+m_pop_vci_count++;
+printf("    [%s] transfer VCI command from init %d to target %d / time = %d\n", 
+       name(), (int)from, (int)dest, (int)time.value() );
+#endif
+        // transfer VCI command
+        (*p_to_target[dest])->nb_transport_fw( payload, 
+                                               phase, 
+                                               time );
+    }
+}  // end route()
+  
+///////////////////////////////////////////////////////////////////////////////////////
+//      PDES process 
+// ALL command from initiators (VCI, NULL, or ACTIVITY) are registered in the central
+// buffer and are handled in a strict increasing time (time filtering).
+// The local time is updated each time a new transaction is poped from central buffer.
+// Non blocking NULL messages are sent to all targets when time quantum elapsed.
+// The thread deschedule if there is no more eligible command in central buffer,
+// and wake up when a new command is received.
+///////////////////////////////////////////////////////////////////////////////////////
+tmpl(void)::execLoop()  
+{
+    size_t                    	from;
+    tlm::tlm_generic_payload* 	payload_ptr;
+    tlm::tlm_phase*           	phase_ptr;
+    sc_core::sc_time*         	time_ptr;
+
+    while (true)
+    {
+
+#ifdef SOCLIB_MODULE_DEBUG
+printf("######    [%s] wake up / time = %d\n",
+       name(), (int)m_pdes_local_time->get().value() );
+#endif
+
+        // pop the earliest transaction from central buffer
+        // while eligible command is found in central buffer
+        while( m_central_buffer.pop( from, 
+                                     payload_ptr, 
+                                     phase_ptr, 
+                                     time_ptr) )
+        {
+            assert( not (*time_ptr < m_pdes_local_time->get()) 
+            && "ERROR in VGMN: Transaction time smaller than local time");
+ 
+            // update local time
+            m_pdes_local_time->set(*time_ptr);
+
+            // process the transaction
+            route( from, 
+                   *payload_ptr, 
+                   *phase_ptr, 
+                   *time_ptr );
+
+            // send NULL messages to all targets if time_quantum elapsed
+            if ( m_pdes_local_time->need_sync() )
+            {
+                m_pdes_local_time->reset_sync();
+                m_null_time = m_pdes_local_time->get();
+                m_null_sent_count += m_targets;
+
+                for ( size_t i=0 ; i<(m_targets-1) ; i++ )
+                {
+                    (*p_to_target[i])->nb_transport_fw(m_null_payload, 
+                                                       m_null_phase, 
+                                                       m_null_time);
+                }
+            }
+        } // end while buffer not empty
+    
+        
+#ifdef SOCLIB_MODULE_DEBUG
+printf("######    [%s] no eligible transaction => deschedule / time = %d\n",
+       name(), (int)m_pdes_local_time->get().value() );
+#endif
+        ////////////////////////////////
+        sc_core::wait( m_cmd_received );
+        ////////////////////////////////
+
+    } // end infinite while
+} // end execLoop()
+    
 /////////////////////////////////////////////////////////////////////////////////////
-// Constructor
+// Interface function executed when receiving a command from VCI initiator[id].
+// It registers the command in the central buffer.
+// The initiator thread is desceduled if the buffer is full.
 /////////////////////////////////////////////////////////////////////////////////////
-tmpl(/**/)::VciVgmn
-( sc_core::sc_module_name module_name               // module name
-  , const soclib::common::MappingTable &mt          // mapping table
-  , size_t n_inits                                  // number of inits
-  , size_t n_targets                                // number of targets
-  , size_t min_latency                              // minimal latency
-  , size_t fifo_depth                               // parameter do not used
-  ) 
-	   //: Interconnect(module_name,mt,soclib::common::IntTab(),n_inits,n_targets,min_latency)
-	   : Interconnect(module_name,mt.getRoutingTable(soclib::common::IntTab(),0),mt.getIdMaskingTable(0),n_inits,n_targets,min_latency/2)
+tmpl(tlm::tlm_sync_enum)::nb_transport_fw( int                         id,          
+                                           tlm::tlm_generic_payload    &payload,    
+                                           tlm::tlm_phase              &phase,     
+                                           sc_core::sc_time            &time)     
+{
+
+#ifdef SOCLIB_MODULE_DEBUG
+printf( "    [%s] receive COMMAND from init %d / time = %d \n", 
+       name(), id, (int)time.value() );
+#endif
+
+    bool push = false;
+    do
+    {
+        // try to push a transaction in the central buffer
+        push = m_central_buffer.push( id, 
+                                      payload, 
+                                      phase, 
+                                      time );
+        if( not push )
+        {
+
+#ifdef SOCLIB_MODULE_DEBUG
+printf("######    [init %d] cannot push into VGMN buffer => deschedule \n", id);
+#endif
+            ///////////////////////////////////////
+            sc_core::wait( sc_core::SC_ZERO_TIME );
+            ///////////////////////////////////////
+
+#ifdef SOCLIB_MODULE_DEBUG
+printf("######    [init %d] wake up \n", id);
+#endif
+
+        }
+        else
+        {
+
+#ifdef SOCLIB_MODULE_DEBUG
+soclib_payload_extension *extension_ptr;
+payload.get_extension(extension_ptr);
+if( extension_ptr->is_active() || extension_ptr->is_inactive() )
 {
+    m_push_activity_count++;
+    printf( "    [%s] push ACTIVITY command into buffer\n", name() );
 }
+else if( extension_ptr->is_null_message() )
+{
+    m_push_null_count++;
+    printf( "    [%s] push NULL command into buffer\n", name() );
+}
+else
+{
+    m_push_vci_count++;
+    printf( "    [%s] push VCI command into buffer\n", name() );
+}
+#endif
+            // notify to wake up the thread
+            m_cmd_received.notify( sc_core::SC_ZERO_TIME );
+        }
+    } while ( not push );
+
+    return  tlm::TLM_COMPLETED;
+
+} //end nb_transport_fw
+
+/////////////////////////////////////////////////////////////////////////////////////
+// Interface function executed when receiving a response from VCI target[id].
+// It directly routes the response to the proper VCI initiator (no time filtering).
+/////////////////////////////////////////////////////////////////////////////////////
+tmpl(tlm::tlm_sync_enum)::nb_transport_bw( int                        id,   
+                                           tlm::tlm_generic_payload   &payload,  
+                                           tlm::tlm_phase             &phase,   
+                                           sc_core::sc_time           &time)  
+{
+    // get message SRCID
+    soclib_payload_extension *resp_extension_ptr;
+    payload.get_extension(resp_extension_ptr);
+
+    unsigned int	srcid = resp_extension_ptr->get_src_id();
+  
+#ifdef SOCLIB_MODULE_DEBUG
+printf("    [%s] receive VCI RESPONSE from target %d for init %d / time = %d\n", 
+        name(), id, srcid, (int)time.value() );
+#endif
+
+    // get destination
+//    unsigned int dest = m_rsp_routing_table[srcid];
+    unsigned int dest = srcid;
+
+    // update the transaction time
+    time = time + (m_latency*UNIT_TIME);
+  
+#ifdef SOCLIB_MODULE_DEBUG
+printf("    [%s] send VCI RESPONSE on port %d / time = %d\n", 
+        name(), dest, (int)time.value() );
+#endif
+
+    (*p_to_initiator[dest])->nb_transport_bw( payload, 
+                                              phase, 
+                                              time);
+    return tlm::TLM_COMPLETED;
+} // end nb_transport_bw 
 
 }}