Index: /trunk/platforms/tsar_generic_iob/top.cpp
===================================================================
--- /trunk/platforms/tsar_generic_iob/top.cpp	(revision 717)
+++ /trunk/platforms/tsar_generic_iob/top.cpp	(revision 718)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////////
 // File: top.cpp  (for tsar_generic_iob platform)
-// Author: Alain Greiner 
+// Author: Alain Greiner
 // Copyright: UPMC/LIP6
 // Date : august 2013
 // This program is released under the GNU public license
 ///////////////////////////////////////////////////////////////////////////////
-// This file define a generic TSAR architecture with an IO network emulating 
+// This file define a generic TSAR architecture with an IO network emulating
 // an external bus (i.e. Hypertransport) to access 7 external peripherals:
 //
@@ -25,8 +25,8 @@
 //
 // 1) the "INT" network supports Read/Write transactions
-//    between processors and L2 caches or peripherals. 
+//    between processors and L2 caches or peripherals.
 //    (VCI ADDDRESS = 40 bits / VCI DATA width = 32 bits)
 //    It supports also coherence transactions between L1 & L2 caches.
-// 3) the "RAM" network is emulating the 3D network between L2 caches
+// 3) the "RAM" network emulates the 3D network between L2 caches
 //    and L3 caches, and is implemented as a 2D mesh between the L2 caches,
 //    the two IO bridges and the physical RAMs disributed in all clusters.
@@ -35,12 +35,12 @@
 //    7 external peripheral controllers.
 //    (VCI ADDDRESS = 40 bits / VCI DATA width = 64 bits)
-// 
-// The external peripherals HWI IRQs are translated to WTI IRQs by the 
+//
+// The external peripherals HWI IRQs are translated to WTI IRQs by the
 // external IOPIC component, that must be configured by the OS to route
-// these WTI ITQS to one or several internal XICU components. 
+// these WTI ITQS to one or several internal XICU components.
 // The total number of channels for the external peripherals (MTTY, MNIC, CDMA
 // IOC or HBA) is limited by the IOPIC 32 HWI inputs:..
 // - IOPIC HWI[1:0]     connected to IRQ_NIC_RX[1:0]
-// - IOPIC HWI[3:2]     connected to IRQ_NIC_TX[1:0]      
+// - IOPIC HWI[3:2]     connected to IRQ_NIC_TX[1:0]
 // - IOPIC HWI[7:4]     connected to IRQ_CMA_TX[3:0]]
 // - IOPIC HWI[8]       connected to IRQ_BDEV
@@ -52,5 +52,5 @@
 // and one multi channels DMA component.
 // The XICU component is mainly used to handle WTI IRQs, as only 2 HWI IRQs
-// are connected to XICU in each cluster: 
+// are connected to XICU in each cluster:
 // - IRQ_IN[0] : MMC
 // - IRQ_IN[1] : DMA channel 0
@@ -58,13 +58,13 @@
 // - IRQ_IN[3] : DMA channel 2
 // - IRQ_IN[4] : DMA channel 3
-// 
+//
 // All clusters are identical, but cluster(0,0) and cluster(XMAX-1,YMAX-1)
 // contain an extra IO bridge component. These IOB0 & IOB1 components are
 // connected to the three networks (INT, RAM, IOX).
-// 
+//
 // - It uses two dspin_local_crossbar per cluster to implement the
-//   local interconnect correponding to the INT network. 
-// - It uses two dspin_local_crossbar per cluster to implement the
-//   local interconnect correponding to the coherence INT network. 
+//   local interconnect correponding to the INT network.
+// - It uses three dspin_local_crossbar per cluster to implement the
+//   local interconnect correponding to the coherence INT network.
 // - It uses two virtual_dspin_router per cluster to implement
 //   the INT network (routing both the direct and coherence trafic).
@@ -79,5 +79,5 @@
 //
 // The main hardware parameters must be defined in the hard_config.h file :
-// - X_SIZE           : number of clusters in a row 
+// - X_SIZE           : number of clusters in a row
 // - Y_SIZE           : number of clusters in a column
 // - NB_PROCS_MAX     : number of processors per cluster (power of 2)
@@ -88,14 +88,14 @@
 // - FBUF_Y_SIZE      : heigth of frame buffer (lines)
 // - XCU_NB_INPUTS    : number of HWIs = number of WTIs = number of PTIs
-// 
+//
 // Some secondary hardware parameters must be defined in this top.cpp file:
-// - XRAM_LATENCY     : external ram latency 
+// - XRAM_LATENCY     : external ram latency
 // - MEMC_WAYS        : L2 cache number of ways
 // - MEMC_SETS        : L2 cache number of sets
-// - L1_IWAYS     
-// - L1_ISETS    
-// - L1_DWAYS   
-// - L1_DSETS  
-// - BDEV_IMAGE_NAME  : file pathname for block device 
+// - L1_IWAYS
+// - L1_ISETS
+// - L1_DWAYS
+// - L1_DSETS
+// - BDEV_IMAGE_NAME  : file pathname for block device
 // - NIC_RX_NAME      : file pathname for NIC received packets
 // - NIC_TX_NAME      : file pathname for NIC transmited packets
@@ -104,5 +104,5 @@
 // General policy for 40 bits physical address decoding:
 // All physical segments base addresses are multiple of 1 Mbytes
-// (=> the 24 LSB bits = 0, and the 16 MSB bits define the target) 
+// (=> the 24 LSB bits = 0, and the 16 MSB bits define the target)
 // The (x_width + y_width) MSB bits (left aligned) define
 // the cluster index, and the LADR bits define the local index:
@@ -159,5 +159,5 @@
 
 ///////////////////////////////////////////////////////////
-//          DSPIN parameters           
+//          DSPIN parameters
 ///////////////////////////////////////////////////////////
 
@@ -169,5 +169,5 @@
 
 ///////////////////////////////////////////////////////////
-//         VCI fields width  for the 3 VCI networks          
+//         VCI fields width  for the 3 VCI networks
 ///////////////////////////////////////////////////////////
 
@@ -186,5 +186,5 @@
 
 ////////////////////////////////////////////////////////////
-//    Main Hardware Parameters values         
+//    Main Hardware Parameters values
 //////////////////////i/////////////////////////////////////
 
@@ -192,5 +192,5 @@
 
 ////////////////////////////////////////////////////////////
-//    Secondary Hardware Parameters values         
+//    Secondary Hardware Parameters values
 //////////////////////i/////////////////////////////////////
 
@@ -223,5 +223,5 @@
 
 ////////////////////////////////////////////////////////////
-//    Software to be loaded in ROM & RAM         
+//    Software to be loaded in ROM & RAM
 //////////////////////i/////////////////////////////////////
 
@@ -229,5 +229,5 @@
 
 ////////////////////////////////////////////////////////////
-//     DEBUG Parameters default values         
+//     DEBUG Parameters default values
 //////////////////////i/////////////////////////////////////
 
@@ -238,47 +238,9 @@
 /////////////////////////////////////////////////////////
 
-// Non replicated peripherals (must be in cluster 0)
-
-#define BROM_BASE             0x00BFC00000      
-#define BROM_SIZE             0x0000100000   // 1 M Kbytes
-
-#define IOBX_BASE             0x00BE000000
-#define IOBX_SIZE             0x0000001000   // 4 Kbytes
-
-#define BDEV_BASE             0x00B3000000      
-#define BDEV_SIZE             0x0000001000   // 4 Kbytes
-
-#define MTTY_BASE             0x00B4000000      
-#define MTTY_SIZE             0x0000001000   // 4 Kbytes
-
-#define MNIC_BASE             0x00B5000000      
-#define MNIC_SIZE             0x0000080000   // 512 Kbytes
-
-#define CDMA_BASE             0x00B6000000      
-#define CDMA_SIZE             0x0000001000 * (NB_CMA_CHANNELS)  // 4 Kbytes per channel 
-
-#define FBUF_BASE             0x00B7000000      
-#define FBUF_SIZE             FBUF_X_SIZE * FBUF_Y_SIZE
-
-#define IOPI_BASE             0x00B8000000      
-#define IOPI_SIZE             0x0000001000   // 4 Kbytes
-
-// Replicated peripherals : address is incremented by a cluster offset 
+// Replicated RAMs : address is incremented by a cluster offset
 //     offset  = cluster(x,y) << (address_width-x_width-y_width);
 
-#define XRAM_BASE             0x0000000000      
-#define XRAM_SIZE             0x0004000000   // 64 Mbytes
-
-#define XICU_BASE             0x00B0000000      
-#define XICU_SIZE             0x0000001000   // 4 Kbytes
-
-#define MDMA_BASE             0x00B1000000      
-#define MDMA_SIZE             0x0000001000 * NB_DMA_CHANNELS // 4 Kbytes per channel  
-
-// Replicated memory segments (XRAM) : address is incremented by a cluster offset 
-//     offset  = cluster(x,y) << (address_width-x_width-y_width);
-
-#define MEMC_BASE             0x00B2000000      
-#define MEMC_SIZE             0x0000001000   // 4 Kbytes 
+#define SEG_RAM_BASE          0x0000000000
+#define SEG_RAM_SIZE          0x0004000000   // 64 Mbytes
 
 ////////////////////////////////////////////////////////////////////////
@@ -289,17 +251,17 @@
 // - The 10 MSB bits define the cluster index (left aligned)
 // - The 4  LSB bits define the local index.
-// Two different initiators cannot have the same SRCID, but a given 
-// initiator can have two alias SRCIDs: 
+// Two different initiators cannot have the same SRCID, but a given
+// initiator can have two alias SRCIDs:
 // - Internal initiators (procs, mdma) are replicated in all clusters,
 //   and each initiator has one single SRCID.
 // - External initiators (bdev, cdma) are not replicated, but can be
-//   accessed in 2 clusters : cluster_iob0 and cluster_iob1. 
+//   accessed in 2 clusters : cluster_iob0 and cluster_iob1.
 //   They have the same local index, but two different cluster indexes.
 //
 // As cluster_iob0 and cluster_iob1 contain both internal initiators
-// and external initiators, they must have different local indexes. 
+// and external initiators, they must have different local indexes.
 // Consequence: For a local interconnect, the INI_ID port index
 // is NOT equal to the SRCID local index, and the local interconnect
-// must make a translation: SRCID => INI_ID 
+// must make a translation: SRCID => INI_ID
 ////////////////////////////////////////////////////////////////////////
 
@@ -308,7 +270,7 @@
 #define IOBX_LOCAL_SRCID             0x9
 #define MEMC_LOCAL_SRCID             0xA
+#define CDMA_LOCAL_SRCID             0xB
+#define BDEV_LOCAL_SRCID             0xC
 #define IOPI_LOCAL_SRCID             0xD
-#define CDMA_LOCAL_SRCID             0xE    // hard-coded in dspin_tsar
-#define BDEV_LOCAL_SRCID             0xF    // hard-coded in dspin_tsar
 
 ///////////////////////////////////////////////////////////////////////
@@ -338,19 +300,19 @@
 ///////////////////////////////////////////////////////////////////////
 
-#define IOX_IOB0_TGT_ID              0    // don't change this value
-#define IOX_IOB1_TGT_ID              1    // don't change this value
-#define IOX_FBUF_TGT_ID              2
-#define IOX_BDEV_TGT_ID              3
-#define IOX_MNIC_TGT_ID              4
-#define IOX_CDMA_TGT_ID              5
-#define IOX_BROM_TGT_ID              6
-#define IOX_MTTY_TGT_ID              7
-#define IOX_IOPI_TGT_ID              8
-
-#define IOX_IOB0_INI_ID              0    // Don't change this value 
-#define IOX_IOB1_INI_ID              1    // Don't change this value 
-#define IOX_BDEV_INI_ID              2     
-#define IOX_CDMA_INI_ID              3  
-#define IOX_IOPI_INI_ID              4 
+#define IOX_FBUF_TGT_ID              0
+#define IOX_BDEV_TGT_ID              1
+#define IOX_MNIC_TGT_ID              2
+#define IOX_CDMA_TGT_ID              3
+#define IOX_BROM_TGT_ID              4
+#define IOX_MTTY_TGT_ID              5
+#define IOX_IOPI_TGT_ID              6
+#define IOX_IOB0_TGT_ID              7
+#define IOX_IOB1_TGT_ID              8
+
+#define IOX_BDEV_INI_ID              0
+#define IOX_CDMA_INI_ID              1
+#define IOX_IOPI_INI_ID              2
+#define IOX_IOB0_INI_ID              3
+#define IOX_IOB1_INI_ID              4
 
 ////////////////////////////////////////////////////////////////////////
@@ -371,7 +333,7 @@
    bool     debug_ok         = false;                      // trace activated
    size_t   debug_period     = 1;                          // trace period
-   size_t   debug_memc_id    = 0xFFFFFFFF;                 // index of traced memc   
-   size_t   debug_proc_id    = 0xFFFFFFFF;                 // index of traced proc 
-   size_t   debug_xram_id    = 0xFFFFFFFF;                 // index of traced xram 
+   size_t   debug_memc_id    = 0xFFFFFFFF;                 // index of traced memc
+   size_t   debug_proc_id    = 0xFFFFFFFF;                 // index of traced proc
+   size_t   debug_xram_id    = 0xFFFFFFFF;                 // index of traced xram
    bool     debug_iob        = false;                      // trace iob0 & iob1 when true
    uint32_t debug_from       = 0;                          // trace start cycle
@@ -384,5 +346,5 @@
    assert( (X_WIDTH == 4) and (Y_WIDTH == 4) and
    "ERROR: we must have X_WIDTH == Y_WIDTH == 4");
- 
+
    ////////////// command line arguments //////////////////////
    if (argc > 1)
@@ -536,5 +498,5 @@
                                    vci_plen_width,
                                    vci_address_width,
-                                   vci_rerror_width, 
+                                   vci_rerror_width,
                                    vci_clen_width,
                                    vci_rflag_width,
@@ -551,7 +513,7 @@
    // - 4 local targets (MEMC, XICU, MDMA, IOBX) per cluster
    /////////////////////////////////////////////////////////////////////
-   MappingTable maptab_int( vci_address_width, 
-                            IntTab(x_width + y_width, 16 - x_width - y_width), 
-                            IntTab(x_width + y_width, vci_srcid_width - x_width - y_width), 
+   MappingTable maptab_int( vci_address_width,
+                            IntTab(x_width + y_width, 16 - x_width - y_width),
+                            IntTab(x_width + y_width, vci_srcid_width - x_width - y_width),
                             0x00FF000000);
 
@@ -560,5 +522,5 @@
       for (size_t y = 0; y < YMAX; y++)
       {
-         uint64_t offset = ((uint64_t)cluster(x,y)) 
+         uint64_t offset = ((uint64_t)cluster(x,y))
                               << (vci_address_width-x_width-y_width);
          bool config    = true;
@@ -569,64 +531,64 @@
          std::ostringstream    smemc_conf;
          smemc_conf << "int_seg_memc_conf_" << x << "_" << y;
-         maptab_int.add(Segment(smemc_conf.str(), MEMC_BASE+offset, MEMC_SIZE,
-                     IntTab(cluster(x,y),INT_MEMC_TGT_ID), not cacheable, config ));
+         maptab_int.add(Segment(smemc_conf.str(), SEG_MMC_BASE+offset, SEG_MMC_SIZE,
+                     IntTab(cluster(x,y), INT_MEMC_TGT_ID), not cacheable, config ));
 
          std::ostringstream    smemc_xram;
          smemc_xram << "int_seg_memc_xram_" << x << "_" << y;
-         maptab_int.add(Segment(smemc_xram.str(), XRAM_BASE+offset, XRAM_SIZE,
-                     IntTab(cluster(x,y),INT_MEMC_TGT_ID), cacheable));
+         maptab_int.add(Segment(smemc_xram.str(), SEG_RAM_BASE+offset, SEG_RAM_SIZE,
+                     IntTab(cluster(x,y), INT_MEMC_TGT_ID), cacheable));
 
          std::ostringstream    sxicu;
          sxicu << "int_seg_xicu_" << x << "_" << y;
-         maptab_int.add(Segment(sxicu.str(), XICU_BASE+offset, XICU_SIZE, 
-                     IntTab(cluster(x,y),INT_XICU_TGT_ID), not cacheable));
+         maptab_int.add(Segment(sxicu.str(), SEG_XCU_BASE+offset, SEG_XCU_SIZE,
+                     IntTab(cluster(x,y), INT_XICU_TGT_ID), not cacheable));
 
          std::ostringstream    smdma;
          smdma << "int_seg_mdma_" << x << "_" << y;
-         maptab_int.add(Segment(smdma.str(), MDMA_BASE+offset, MDMA_SIZE, 
-                     IntTab(cluster(x,y),INT_MDMA_TGT_ID), not cacheable));
+         maptab_int.add(Segment(smdma.str(), SEG_DMA_BASE+offset, SEG_DMA_SIZE,
+                     IntTab(cluster(x,y), INT_MDMA_TGT_ID), not cacheable));
 
          // the following segments are only defined in cluster_iob0 or in cluster_iob1
 
-         if ( (cluster(x,y) == cluster_iob0) or (cluster(x,y) == cluster_iob1) )  
+         if ( (cluster(x,y) == cluster_iob0) or (cluster(x,y) == cluster_iob1) )
          {
             std::ostringstream    siobx;
             siobx << "int_seg_iobx_" << x << "_" << y;
-            maptab_int.add(Segment(siobx.str(), IOBX_BASE+offset, IOBX_SIZE, 
+            maptab_int.add(Segment(siobx.str(), SEG_IOB_BASE+offset, SEG_IOB_SIZE,
                         IntTab(cluster(x,y), INT_IOBX_TGT_ID), not cacheable, config ));
 
             std::ostringstream    stty;
             stty << "int_seg_mtty_" << x << "_" << y;
-            maptab_int.add(Segment(stty.str(), MTTY_BASE+offset, MTTY_SIZE, 
+            maptab_int.add(Segment(stty.str(), SEG_TTY_BASE+offset, SEG_TTY_SIZE,
                         IntTab(cluster(x,y), INT_IOBX_TGT_ID), not cacheable));
 
             std::ostringstream    sfbf;
             sfbf << "int_seg_fbuf_" << x << "_" << y;
-            maptab_int.add(Segment(sfbf.str(), FBUF_BASE+offset, FBUF_SIZE, 
+            maptab_int.add(Segment(sfbf.str(), SEG_FBF_BASE+offset, SEG_FBF_SIZE,
                         IntTab(cluster(x,y), INT_IOBX_TGT_ID), not cacheable));
 
             std::ostringstream    sbdv;
             sbdv << "int_seg_bdev_" << x << "_" << y;
-            maptab_int.add(Segment(sbdv.str(), BDEV_BASE+offset, BDEV_SIZE, 
+            maptab_int.add(Segment(sbdv.str(), SEG_IOC_BASE+offset, SEG_IOC_SIZE,
                         IntTab(cluster(x,y), INT_IOBX_TGT_ID), not cacheable));
 
             std::ostringstream    snic;
             snic << "int_seg_mnic_" << x << "_" << y;
-            maptab_int.add(Segment(snic.str(), MNIC_BASE+offset, MNIC_SIZE, 
+            maptab_int.add(Segment(snic.str(), SEG_NIC_BASE+offset, SEG_NIC_SIZE,
                         IntTab(cluster(x,y), INT_IOBX_TGT_ID), not cacheable));
 
             std::ostringstream    srom;
             srom << "int_seg_brom_" << x << "_" << y;
-            maptab_int.add(Segment(srom.str(), BROM_BASE+offset, BROM_SIZE, 
+            maptab_int.add(Segment(srom.str(), SEG_ROM_BASE+offset, SEG_ROM_SIZE,
                         IntTab(cluster(x,y), INT_IOBX_TGT_ID), cacheable ));
 
             std::ostringstream    sdma;
             sdma << "int_seg_cdma_" << x << "_" << y;
-            maptab_int.add(Segment(sdma.str(), CDMA_BASE+offset, CDMA_SIZE, 
+            maptab_int.add(Segment(sdma.str(), SEG_CMA_BASE+offset, SEG_CMA_SIZE,
                         IntTab(cluster(x,y), INT_IOBX_TGT_ID), not cacheable));
 
             std::ostringstream    spic;
             spic << "int_seg_iopi_" << x << "_" << y;
-            maptab_int.add(Segment(spic.str(), IOPI_BASE+offset, IOPI_SIZE, 
+            maptab_int.add(Segment(spic.str(), SEG_PIC_BASE+offset, SEG_PIC_SIZE,
                         IntTab(cluster(x,y), INT_IOBX_TGT_ID), not cacheable));
          }
@@ -635,5 +597,5 @@
          // and the port index on the local interconnect.
 
-         maptab_int.srcid_map( IntTab( cluster(x,y), MDMA_LOCAL_SRCID ), 
+         maptab_int.srcid_map( IntTab( cluster(x,y), MDMA_LOCAL_SRCID ),
                                IntTab( cluster(x,y), INT_MDMA_INI_ID ) );
 
@@ -645,5 +607,5 @@
 
          for ( size_t p = 0 ; p < NB_PROCS_MAX ; p++ )
-         maptab_int.srcid_map( IntTab( cluster(x,y), PROC_LOCAL_SRCID+p ), 
+         maptab_int.srcid_map( IntTab( cluster(x,y), PROC_LOCAL_SRCID+p ),
                                IntTab( cluster(x,y), INT_PROC_INI_ID+p ) );
       }
@@ -652,14 +614,14 @@
 
     /////////////////////////////////////////////////////////////////////////
-    // RAM network mapping table 
+    // RAM network mapping table
     // - two levels address decoding for commands
     // - two levels srcid decoding for responses
-    // - 2 local initiators (MEMC, IOBX) per cluster 
+    // - 2 local initiators (MEMC, IOBX) per cluster
     //   (IOBX component only in cluster_iob0 and cluster_iob1)
     // - 1 local target (XRAM) per cluster
     ////////////////////////////////////////////////////////////////////////
     MappingTable maptab_ram( vci_address_width,
-                             IntTab(x_width+y_width, 16 - x_width - y_width),
-                             IntTab(x_width+y_width, vci_srcid_width - x_width - y_width), 
+                             IntTab(x_width+y_width, 0),
+                             IntTab(x_width+y_width, vci_srcid_width - x_width - y_width),
                              0x00FF000000);
 
@@ -667,12 +629,12 @@
     {
         for (size_t y = 0; y < YMAX ; y++)
-        { 
-            uint64_t offset = ((uint64_t)cluster(x,y)) 
+        {
+            uint64_t offset = ((uint64_t)cluster(x,y))
                                 << (vci_address_width-x_width-y_width);
 
             std::ostringstream sxram;
             sxram << "ext_seg_xram_" << x << "_" << y;
-            maptab_ram.add(Segment(sxram.str(), XRAM_BASE+offset, 
-                           XRAM_SIZE, IntTab(cluster(x,y), 0), false));
+            maptab_ram.add(Segment(sxram.str(), SEG_RAM_BASE+offset,
+                           SEG_RAM_SIZE, IntTab(cluster(x,y), RAM_XRAM_TGT_ID), false));
         }
     }
@@ -680,10 +642,10 @@
     // This define the mapping between the initiators SRCID
     // and the port index on the RAM local interconnect.
-    // External initiator have two alias SRCID (iob0 / iob1)  
-
-    maptab_ram.srcid_map( IntTab( cluster_iob0, CDMA_LOCAL_SRCID ), 
+    // External initiator have two alias SRCID (iob0 / iob1)
+
+    maptab_ram.srcid_map( IntTab( cluster_iob0, CDMA_LOCAL_SRCID ),
                           IntTab( cluster_iob0, RAM_IOBX_INI_ID ) );
 
-    maptab_ram.srcid_map( IntTab( cluster_iob1, CDMA_LOCAL_SRCID ), 
+    maptab_ram.srcid_map( IntTab( cluster_iob1, CDMA_LOCAL_SRCID ),
                           IntTab( cluster_iob1, RAM_IOBX_INI_ID ) );
 
@@ -694,5 +656,14 @@
                           IntTab( cluster_iob1, RAM_IOBX_INI_ID ) );
 
-    maptab_ram.srcid_map( IntTab( cluster_iob1, MEMC_LOCAL_SRCID ), 
+    maptab_ram.srcid_map( IntTab( cluster_iob0, IOPI_LOCAL_SRCID ),
+                          IntTab( cluster_iob0, RAM_IOBX_INI_ID ) );
+
+    maptab_ram.srcid_map( IntTab( cluster_iob1, IOPI_LOCAL_SRCID ),
+                          IntTab( cluster_iob1, RAM_IOBX_INI_ID ) );
+
+    maptab_ram.srcid_map( IntTab( cluster_iob0, MEMC_LOCAL_SRCID ),
+                          IntTab( cluster_iob0, RAM_MEMC_INI_ID ) );
+
+    maptab_ram.srcid_map( IntTab( cluster_iob1, MEMC_LOCAL_SRCID ),
                           IntTab( cluster_iob1, RAM_MEMC_INI_ID ) );
 
@@ -700,79 +671,101 @@
 
     ///////////////////////////////////////////////////////////////////////
-    // IOX network mapping table  
-    // - two levels address decoding for commands
+    // IOX network mapping table
+    // - two levels address decoding for commands (9, 7) bits
     // - two levels srcid decoding for responses
     // - 5 initiators (IOB0, IOB1, BDEV, CDMA, IOPI)
     // - 9 targets (IOB0, IOB1, BDEV, CDMA, MTTY, FBUF, BROM, MNIC, IOPI)
+    //
+    // Address bit 32 is used to determine if a command must be routed to
+    // IOB0 or IOB1.
     ///////////////////////////////////////////////////////////////////////
-    MappingTable maptab_iox( vci_address_width, 
-                             IntTab(x_width+y_width, 16 - x_width - y_width),
-                             IntTab(x_width+y_width, vci_srcid_width - x_width - y_width), 
-                             0x00FF000000);
-
-    // compute base addresses for cluster_iob0 and cluster_iob1
-    uint64_t iob0_base = ((uint64_t)cluster_iob0) << (vci_address_width - x_width - y_width); 
-    uint64_t iob1_base = ((uint64_t)cluster_iob1) << (vci_address_width - x_width - y_width); 
+    MappingTable maptab_iox(
+          vci_address_width,
+          IntTab(x_width + y_width - 1, 16 - x_width - y_width + 1),
+          IntTab(x_width + y_width    , vci_param_ext::S - x_width - y_width),
+          0x00FF000000);
 
     // External peripherals segments
-    // WHen there is more than one cluster, external peripherals can be accessed
+    // When there is more than one cluster, external peripherals can be accessed
     // through two segments, depending on the used IOB (IOB0 or IOB1).
-    maptab_iox.add(Segment("iox_seg_mtty_0", MTTY_BASE + iob0_base, MTTY_SIZE, 
-                   IntTab(cluster_iob0,IOX_MTTY_TGT_ID), false));
-    maptab_iox.add(Segment("iox_seg_fbuf_0", FBUF_BASE + iob0_base, FBUF_SIZE, 
-                   IntTab(cluster_iob0,IOX_FBUF_TGT_ID), false));
-    maptab_iox.add(Segment("iox_seg_bdev_0", BDEV_BASE + iob0_base, BDEV_SIZE, 
-                   IntTab(cluster_iob0,IOX_BDEV_TGT_ID), false));
-    maptab_iox.add(Segment("iox_seg_mnic_0", MNIC_BASE + iob0_base, MNIC_SIZE, 
-                   IntTab(cluster_iob0,IOX_MNIC_TGT_ID), false));
-    maptab_iox.add(Segment("iox_seg_cdma_0", CDMA_BASE + iob0_base, CDMA_SIZE, 
-                   IntTab(cluster_iob0,IOX_CDMA_TGT_ID), false));
-    maptab_iox.add(Segment("iox_seg_brom_0", BROM_BASE + iob0_base, BROM_SIZE, 
-                   IntTab(cluster_iob0,IOX_BROM_TGT_ID), false));
-    maptab_iox.add(Segment("iox_seg_iopi_0", IOPI_BASE + iob0_base, IOPI_SIZE, 
-                   IntTab(cluster_iob0,IOX_IOPI_TGT_ID), false));
-    
+
+    const uint64_t iob0_base = ((uint64_t)cluster_iob0)
+       << (vci_address_width - x_width - y_width);
+
+    maptab_iox.add(Segment("iox_seg_mtty_0", SEG_TTY_BASE + iob0_base, SEG_TTY_SIZE,
+                   IntTab(0, IOX_MTTY_TGT_ID), false));
+    maptab_iox.add(Segment("iox_seg_fbuf_0", SEG_FBF_BASE + iob0_base, SEG_FBF_SIZE,
+                   IntTab(0, IOX_FBUF_TGT_ID), false));
+    maptab_iox.add(Segment("iox_seg_bdev_0", SEG_IOC_BASE + iob0_base, SEG_IOC_SIZE,
+                   IntTab(0, IOX_BDEV_TGT_ID), false));
+    maptab_iox.add(Segment("iox_seg_mnic_0", SEG_NIC_BASE + iob0_base, SEG_NIC_SIZE,
+                   IntTab(0, IOX_MNIC_TGT_ID), false));
+    maptab_iox.add(Segment("iox_seg_cdma_0", SEG_CMA_BASE + iob0_base, SEG_CMA_SIZE,
+                   IntTab(0, IOX_CDMA_TGT_ID), false));
+    maptab_iox.add(Segment("iox_seg_brom_0", SEG_ROM_BASE + iob0_base, SEG_ROM_SIZE,
+                   IntTab(0, IOX_BROM_TGT_ID), false));
+    maptab_iox.add(Segment("iox_seg_iopi_0", SEG_PIC_BASE + iob0_base, SEG_PIC_SIZE,
+                   IntTab(0, IOX_IOPI_TGT_ID), false));
+
     if ( cluster_iob0 != cluster_iob1 )
     {
-        maptab_iox.add(Segment("iox_seg_mtty_1", MTTY_BASE + iob1_base, MTTY_SIZE, 
-                   IntTab(cluster_iob1,IOX_MTTY_TGT_ID), false));
-        maptab_iox.add(Segment("iox_seg_fbuf_1", FBUF_BASE + iob1_base, FBUF_SIZE, 
-                   IntTab(cluster_iob1,IOX_FBUF_TGT_ID), false));
-        maptab_iox.add(Segment("iox_seg_bdev_1", BDEV_BASE + iob1_base, BDEV_SIZE, 
-                   IntTab(cluster_iob1,IOX_BDEV_TGT_ID), false));
-        maptab_iox.add(Segment("iox_seg_mnic_1", MNIC_BASE + iob1_base, MNIC_SIZE, 
-                   IntTab(cluster_iob1,IOX_MNIC_TGT_ID), false));
-        maptab_iox.add(Segment("iox_seg_cdma_1", CDMA_BASE + iob1_base, CDMA_SIZE, 
-                   IntTab(cluster_iob1,IOX_CDMA_TGT_ID), false));
-        maptab_iox.add(Segment("iox_seg_brom_1", BROM_BASE + iob1_base, BROM_SIZE, 
-                   IntTab(cluster_iob1,IOX_BROM_TGT_ID), false));
-        maptab_iox.add(Segment("iox_seg_iopi_1", IOPI_BASE + iob1_base, IOPI_SIZE, 
-                   IntTab(cluster_iob1,IOX_IOPI_TGT_ID), false));
+       const uint64_t iob1_base = ((uint64_t)cluster_iob1)
+          << (vci_address_width - x_width - y_width);
+
+        maptab_iox.add(Segment("iox_seg_mtty_1", SEG_TTY_BASE + iob1_base, SEG_TTY_SIZE,
+                   IntTab(0, IOX_MTTY_TGT_ID), false));
+        maptab_iox.add(Segment("iox_seg_fbuf_1", SEG_FBF_BASE + iob1_base, SEG_FBF_SIZE,
+                   IntTab(0, IOX_FBUF_TGT_ID), false));
+        maptab_iox.add(Segment("iox_seg_bdev_1", SEG_IOC_BASE + iob1_base, SEG_IOC_SIZE,
+                   IntTab(0, IOX_BDEV_TGT_ID), false));
+        maptab_iox.add(Segment("iox_seg_mnic_1", SEG_NIC_BASE + iob1_base, SEG_NIC_SIZE,
+                   IntTab(0, IOX_MNIC_TGT_ID), false));
+        maptab_iox.add(Segment("iox_seg_cdma_1", SEG_CMA_BASE + iob1_base, SEG_CMA_SIZE,
+                   IntTab(0, IOX_CDMA_TGT_ID), false));
+        maptab_iox.add(Segment("iox_seg_brom_1", SEG_ROM_BASE + iob1_base, SEG_ROM_SIZE,
+                   IntTab(0, IOX_BROM_TGT_ID), false));
+        maptab_iox.add(Segment("iox_seg_iopi_1", SEG_PIC_BASE + iob1_base, SEG_PIC_SIZE,
+                   IntTab(0, IOX_IOPI_TGT_ID), false));
     }
 
-    // If there is more than one cluster, external peripherals 
+    // If there is more than one cluster, external peripherals
     // can access RAM through two segments (IOB0 / IOB1).
     // As IOMMU is not activated, addresses are 40 bits (physical addresses),
-    // and the choice depends on address bit A[39].
+    // and the choice depends on address bit A[32].
     for (size_t x = 0; x < XMAX; x++)
     {
         for (size_t y = 0; y < YMAX ; y++)
-        { 
-            uint64_t offset = ((uint64_t)cluster(x,y)) 
-                             << (vci_address_width-x_width-y_width);
-
-            if ( (cluster_iob0 != cluster_iob1) and (x >= (XMAX/2)) ) // use IOB1
+        {
+            const bool wti       = true;
+            const bool cacheable = true;
+
+            const uint64_t offset = ((uint64_t)cluster(x,y))
+                << (vci_address_width-x_width-y_width);
+
+            const uint64_t xicu_base = SEG_XCU_BASE + offset;
+
+            if ( (y & 0x1) == 0 ) // use IOB0
             {
+                std::ostringstream sxcu0;
+                sxcu0 << "iox_seg_xcu0_" << x << "_" << y;
+                maptab_iox.add(Segment(sxcu0.str(), xicu_base, SEG_XCU_SIZE,
+                            IntTab(0, IOX_IOB0_TGT_ID), not cacheable, wti));
+
+                std::ostringstream siob0;
+                siob0 << "iox_seg_ram0_" << x << "_" << y;
+                maptab_iox.add(Segment(siob0.str(), offset, SEG_XCU_BASE,
+                            IntTab(0, IOX_IOB0_TGT_ID), not cacheable, not wti));
+            }
+            else                  // USE IOB1
+            {
+                std::ostringstream sxcu1;
+                sxcu1 << "iox_seg_xcu1_" << x << "_" << y;
+                maptab_iox.add(Segment(sxcu1.str(), xicu_base, SEG_XCU_SIZE,
+                            IntTab(0, IOX_IOB1_TGT_ID), not cacheable, wti));
+
                 std::ostringstream siob1;
-                siob1 << "iox_seg_xram_" << x << "_" << y;
-                maptab_iox.add(Segment(siob1.str(), offset, XRAM_SIZE, 
-                            IntTab(cluster_iob1,IOX_IOB1_TGT_ID), false));
-            }
-            else                                                     // USE IOB0
-            {
-                std::ostringstream siob0;
-                siob0 << "iox_seg_xram_" << x << "_" << y;
-                maptab_iox.add(Segment(siob0.str(), offset, XRAM_SIZE, 
-                            IntTab(cluster_iob0,IOX_IOB0_TGT_ID), false));
+                siob1 << "iox_seg_ram1_" << x << "_" << y;
+                maptab_iox.add(Segment(siob1.str(), offset, SEG_XCU_BASE,
+                            IntTab(0, IOX_IOB1_TGT_ID), not cacheable, not wti));
             }
         }
@@ -781,50 +774,18 @@
     // This define the mapping between the external initiators (SRCID)
     // and the port index on the IOX local interconnect.
-    // If there is more than one cluster, external initiators
-    // have two alias SRCID (iob0 / iob1 access)  
-    maptab_iox.srcid_map( IntTab( cluster_iob0, CDMA_LOCAL_SRCID ), 
-                          IntTab( cluster_iob0, IOX_CDMA_INI_ID ) );
-    maptab_iox.srcid_map( IntTab( cluster_iob0, BDEV_LOCAL_SRCID ),
-                          IntTab( cluster_iob0, IOX_BDEV_INI_ID ) );
-    maptab_iox.srcid_map( IntTab( cluster_iob0, IOPI_LOCAL_SRCID ),
-                          IntTab( cluster_iob0, IOX_IOPI_INI_ID ) );
+
+    maptab_iox.srcid_map( IntTab( 0, CDMA_LOCAL_SRCID ) ,
+                          IntTab( 0, IOX_CDMA_INI_ID  ) );
+    maptab_iox.srcid_map( IntTab( 0, BDEV_LOCAL_SRCID ) ,
+                          IntTab( 0, IOX_BDEV_INI_ID  ) );
+    maptab_iox.srcid_map( IntTab( 0, IOPI_LOCAL_SRCID ) ,
+                          IntTab( 0, IOX_IOPI_INI_ID  ) );
+    maptab_iox.srcid_map( IntTab( 0, IOX_IOB0_INI_ID  ) ,
+                          IntTab( 0, IOX_IOB0_INI_ID  ) );
 
     if ( cluster_iob0 != cluster_iob1 )
     {
-        maptab_iox.srcid_map( IntTab( cluster_iob1, CDMA_LOCAL_SRCID ),
-                              IntTab( cluster_iob1, IOX_CDMA_INI_ID ) );
-        maptab_iox.srcid_map( IntTab( cluster_iob1, BDEV_LOCAL_SRCID ),
-                              IntTab( cluster_iob1, IOX_BDEV_INI_ID ) );
-        maptab_iox.srcid_map( IntTab( cluster_iob1, BDEV_LOCAL_SRCID ),
-                              IntTab( cluster_iob1, IOX_IOPI_INI_ID ) );
-    }
-
-    // This define the mapping between the internal initiators (SRCID)
-    // and the port index on the IOX local interconnect.
-    // If there is more than one cluster, external initiators
-
-    for (size_t x = 0; x < XMAX; x++)
-    {
-        for (size_t y = 0; y < YMAX ; y++)
-        { 
-            if ( (cluster_iob0 != cluster_iob1) and (x >= (XMAX/2)) ) // use IOB1
-            {
-                for (size_t p = 0 ; p < NB_PROCS_MAX ; p++)
-                maptab_iox.srcid_map( IntTab( cluster(x,y), PROC_LOCAL_SRCID + p ), 
-                                      IntTab( cluster_iob1, IOX_IOB1_INI_ID ) );
-
-                maptab_iox.srcid_map( IntTab( cluster(x,y), MDMA_LOCAL_SRCID ),
-                                      IntTab( cluster_iob1, IOX_IOB1_INI_ID ) );
-            }
-            else                                                      // USE IOB0
-            {
-                for (size_t p = 0 ; p < NB_PROCS_MAX ; p++)
-                maptab_iox.srcid_map( IntTab( cluster(x,y), PROC_LOCAL_SRCID + p ), 
-                                      IntTab( cluster_iob0, IOX_IOB0_INI_ID ) );
-
-                maptab_iox.srcid_map( IntTab( cluster(x,y), MDMA_LOCAL_SRCID ),
-                                      IntTab( cluster_iob0, IOX_IOB0_INI_ID ) );
-            }
-        }
+        maptab_iox.srcid_map( IntTab( 0, IOX_IOB1_INI_ID ) ,
+                              IntTab( 0, IOX_IOB1_INI_ID ) );
     }
 
@@ -844,10 +805,4 @@
     sc_signal<bool>                   signal_irq_mnic_tx[NB_NIC_CHANNELS];
     sc_signal<bool>                   signal_irq_cdma[NB_CMA_CHANNELS];
-
-    // DSPIN signals for loopback in cluster_iob0 & cluster_iob1
-    DspinSignals<dspin_ram_cmd_width> signal_dspin_cmd_iob0_loopback; 
-    DspinSignals<dspin_ram_rsp_width> signal_dspin_rsp_iob0_loopback; 
-    DspinSignals<dspin_ram_cmd_width> signal_dspin_cmd_iob1_loopback; 
-    DspinSignals<dspin_ram_rsp_width> signal_dspin_rsp_iob1_loopback; 
 
     // VCI signals for IOX network
@@ -868,5 +823,5 @@
     VciSignals<vci_param_ext>         signal_vci_tgt_iopi("signal_vci_ini_iopi");
 
-   // Horizontal inter-clusters INT network DSPIN 
+   // Horizontal inter-clusters INT network DSPIN
    DspinSignals<dspin_int_cmd_width>*** signal_dspin_int_cmd_h_inc =
       alloc_elems<DspinSignals<dspin_int_cmd_width> >("signal_dspin_int_cmd_h_inc", XMAX-1, YMAX, 3);
@@ -888,5 +843,5 @@
       alloc_elems<DspinSignals<dspin_int_rsp_width> >("signal_dspin_int_rsp_v_dec", XMAX, YMAX-1, 2);
 
-   // Mesh boundaries INT network DSPIN 
+   // Mesh boundaries INT network DSPIN
    DspinSignals<dspin_int_cmd_width>**** signal_dspin_false_int_cmd_in =
       alloc_elems<DspinSignals<dspin_int_cmd_width> >("signal_dspin_false_int_cmd_in", XMAX, YMAX, 4, 3);
@@ -899,5 +854,5 @@
 
 
-   // Horizontal inter-clusters RAM network DSPIN 
+   // Horizontal inter-clusters RAM network DSPIN
    DspinSignals<dspin_ram_cmd_width>** signal_dspin_ram_cmd_h_inc =
       alloc_elems<DspinSignals<dspin_ram_cmd_width> >("signal_dspin_ram_cmd_h_inc", XMAX-1, YMAX);
@@ -919,5 +874,5 @@
       alloc_elems<DspinSignals<dspin_ram_rsp_width> >("signal_dspin_ram_rsp_v_dec", XMAX, YMAX-1);
 
-   // Mesh boundaries RAM network DSPIN 
+   // Mesh boundaries RAM network DSPIN
    DspinSignals<dspin_ram_cmd_width>*** signal_dspin_false_ram_cmd_in =
       alloc_elems<DspinSignals<dspin_ram_cmd_width> >("signal_dspin_false_ram_cmd_in", XMAX, YMAX, 4);
@@ -930,5 +885,5 @@
 
    ////////////////////////////
-   //      Loader    
+   //      Loader
    ////////////////////////////
 
@@ -950,10 +905,13 @@
    std::cout << std::endl << "External Bus and Peripherals" << std::endl << std::endl;
 
+   const size_t nb_iox_initiators = (cluster_iob0 != cluster_iob1) ? 5 : 4;
+   const size_t nb_iox_targets = (cluster_iob0 != cluster_iob1) ? 9 : 8;
+
    // IOX network
    VciIoxNetwork<vci_param_ext>* iox_network;
-   iox_network = new VciIoxNetwork<vci_param_ext>( "iox_network",  
+   iox_network = new VciIoxNetwork<vci_param_ext>( "iox_network",
                                                    maptab_iox,
-                                                   9,        // number of targets
-                                                   5 );      // number of initiators
+                                                   nb_iox_targets,
+                                                   nb_iox_initiators );
    // boot ROM
    VciSimpleRom<vci_param_ext>*  brom;
@@ -991,6 +949,6 @@
                                                   disk_name,
                                                   512,        // block size
-                                                  64,         // burst size (bytes) 
-                                                  0 );        // disk latency 
+                                                  64,         // burst size (bytes)
+                                                  0 );        // disk latency
 
    // Chained Buffer DMA controller
@@ -1013,5 +971,5 @@
       mtty = new VciMultiTty<vci_param_ext>( "mtty",
                                              IntTab(0, IOX_MTTY_TGT_ID),
-                                             maptab_iox, 
+                                             maptab_iox,
                                              vect_names);
 
@@ -1022,6 +980,6 @@
                                        IntTab(0, IOPI_LOCAL_SRCID),
                                        IntTab(0, IOX_IOPI_TGT_ID),
-                                       32 );        // number of input HWI             
-   // Clusters 
+                                       32 );        // number of input HWI
+   // Clusters
    TsarIobCluster<vci_param_int,
                   vci_param_ext,
@@ -1048,4 +1006,15 @@
             std::cout << "Cluster_" << std::dec << x << "_" << y << std::endl;
             std::cout << std::endl;
+
+            const bool is_iob0 = (cluster(x,y) == cluster_iob0);
+            const bool is_iob1 = (cluster(x,y) == cluster_iob1);
+            const bool is_io_cluster = is_iob0 || is_iob1;
+
+            const int iox_iob_ini_id = is_iob0 ?
+                IOX_IOB0_INI_ID :
+                IOX_IOB1_INI_ID ;
+            const int iox_iob_tgt_id = is_iob0 ?
+                IOX_IOB0_TGT_ID :
+                IOX_IOB1_TGT_ID ;
 
             std::ostringstream sc;
@@ -1088,4 +1057,8 @@
                 RAM_IOBX_INI_ID,
 
+                is_io_cluster,
+                iox_iob_tgt_id,
+                iox_iob_ini_id,
+
                 MEMC_WAYS,
                 MEMC_SETS,
@@ -1117,5 +1090,5 @@
 
     ///////////////////////////////////////////////////////////////////////////////
-    //     Net-list 
+    //     Net-list
     ///////////////////////////////////////////////////////////////////////////////
 
@@ -1124,5 +1097,4 @@
     iox_network->p_resetn                                (signal_resetn);
     iox_network->p_to_ini[IOX_IOB0_INI_ID]               (signal_vci_ini_iob0);
-    iox_network->p_to_ini[IOX_IOB1_INI_ID]               (signal_vci_ini_iob1);
     iox_network->p_to_ini[IOX_BDEV_INI_ID]               (signal_vci_ini_bdev);
     iox_network->p_to_ini[IOX_CDMA_INI_ID]               (signal_vci_ini_cdma);
@@ -1130,5 +1102,4 @@
 
     iox_network->p_to_tgt[IOX_IOB0_TGT_ID]               (signal_vci_tgt_iob0);
-    iox_network->p_to_tgt[IOX_IOB1_TGT_ID]               (signal_vci_tgt_iob1);
     iox_network->p_to_tgt[IOX_MTTY_TGT_ID]               (signal_vci_tgt_mtty);
     iox_network->p_to_tgt[IOX_FBUF_TGT_ID]               (signal_vci_tgt_fbuf);
@@ -1139,6 +1110,12 @@
     iox_network->p_to_tgt[IOX_IOPI_TGT_ID]               (signal_vci_tgt_iopi);
 
+    if (cluster_iob0 != cluster_iob1)
+    {
+        iox_network->p_to_ini[IOX_IOB1_INI_ID]           (signal_vci_ini_iob1);
+        iox_network->p_to_tgt[IOX_IOB1_TGT_ID]           (signal_vci_tgt_iob1);
+    }
+
     // BDEV connexion
-	 bdev->p_clk                                          (signal_clk);
+    bdev->p_clk                                          (signal_clk);
     bdev->p_resetn                                       (signal_resetn);
     bdev->p_irq                                          (signal_irq_bdev);
@@ -1178,16 +1155,16 @@
     mtty->p_resetn                                       (signal_resetn);
     mtty->p_vci                                          (signal_vci_tgt_mtty);
-    mtty->p_irq[0]              	                        (signal_irq_mtty_rx);
+    mtty->p_irq[0]                                       (signal_irq_mtty_rx);
 
     std::cout << "  - MTTY connected" << std::endl;
 
     // CDMA connexion
-    cdma->p_clk                       	                (signal_clk);
-    cdma->p_resetn                    	                (signal_resetn);
-    cdma->p_vci_target                	                (signal_vci_tgt_cdma);
-    cdma->p_vci_initiator             	                (signal_vci_ini_cdma);
+    cdma->p_clk                                          (signal_clk);
+    cdma->p_resetn                                       (signal_resetn);
+    cdma->p_vci_target                                   (signal_vci_tgt_cdma);
+    cdma->p_vci_initiator                                (signal_vci_ini_cdma);
     for ( size_t i=0 ; i<(NB_NIC_CHANNELS*2) ; i++)
     {
-        cdma->p_irq[i]                                 (signal_irq_cdma[i]);
+        cdma->p_irq[i]                                   (signal_irq_cdma[i]);
     }
 
@@ -1195,8 +1172,8 @@
 
     // IOPI connexion
-    iopi->p_clk                       	                (signal_clk);
-    iopi->p_resetn                    	                (signal_resetn);
-    iopi->p_vci_target                	                (signal_vci_tgt_iopi);
-    iopi->p_vci_initiator             	                (signal_vci_ini_iopi);
+    iopi->p_clk                                          (signal_clk);
+    iopi->p_resetn                                       (signal_resetn);
+    iopi->p_vci_target                                   (signal_vci_tgt_iopi);
+    iopi->p_vci_initiator                                (signal_vci_ini_iopi);
     for ( size_t i=0 ; i<32 ; i++)
     {
@@ -1214,10 +1191,10 @@
     std::cout << "  - IOPIC connected" << std::endl;
 
-    
+
     // IOB0 cluster connexion to IOX network
-    (*clusters[0][0]->p_vci_iob_iox_ini)               (signal_vci_ini_iob0);
-    (*clusters[0][0]->p_vci_iob_iox_tgt)               (signal_vci_tgt_iob0);
-
-    // IOB1 cluster connexion to IOX network 
+    (*clusters[0][0]->p_vci_iob_iox_ini) (signal_vci_ini_iob0);
+    (*clusters[0][0]->p_vci_iob_iox_tgt) (signal_vci_tgt_iob0);
+
+    // IOB1 cluster connexion to IOX network
     // (only when there is more than 1 cluster)
     if ( cluster_iob0 != cluster_iob1 )
@@ -1272,8 +1249,8 @@
    }
 
-   std::cout << std::endl << "Horizontal connections established" << std::endl;   
+   std::cout << std::endl << "Horizontal connections established" << std::endl;
 
    // Inter Clusters vertical connections
-   if (YMAX > 1) 
+   if (YMAX > 1)
    {
       for (size_t y = 0; y < (YMAX-1); y++)
@@ -1330,42 +1307,13 @@
       }
 
-      if( y == 0 )        // handling IOB to RAM network connection in cluster_iob0
-      {
-         (*clusters[0][0]->p_dspin_iob_cmd_out)               (signal_dspin_cmd_iob0_loopback); 
-         clusters[0][0]->p_dspin_ram_cmd_in[WEST]             (signal_dspin_cmd_iob0_loopback);
-
-         clusters[0][0]->p_dspin_ram_cmd_out[WEST]            (signal_dspin_false_ram_cmd_out[0][0][WEST]);
-         clusters[0][0]->p_dspin_ram_rsp_in[WEST]             (signal_dspin_false_ram_rsp_in[0][0][WEST]);
-
-         clusters[0][0]->p_dspin_ram_rsp_out[WEST]            (signal_dspin_rsp_iob0_loopback);
-         (*clusters[0][0]->p_dspin_iob_rsp_in)                (signal_dspin_rsp_iob0_loopback);
-
-      }
-      else
-      {
-         clusters[0][y]->p_dspin_ram_cmd_in[WEST]             (signal_dspin_false_ram_cmd_in[0][y][WEST]);
-         clusters[0][y]->p_dspin_ram_cmd_out[WEST]            (signal_dspin_false_ram_cmd_out[0][y][WEST]);
-         clusters[0][y]->p_dspin_ram_rsp_in[WEST]             (signal_dspin_false_ram_rsp_in[0][y][WEST]);
-         clusters[0][y]->p_dspin_ram_rsp_out[WEST]            (signal_dspin_false_ram_rsp_out[0][y][WEST]);
-      }
-
-      if( (y == YMAX-1) and (cluster_iob0 != cluster_iob1) )  // handling IOB to RAM network connection in cluster_iob1
-      {
-         (*clusters[XMAX-1][YMAX-1]->p_dspin_iob_cmd_out)     (signal_dspin_cmd_iob1_loopback); 
-         clusters[XMAX-1][YMAX-1]->p_dspin_ram_cmd_in[EAST]   (signal_dspin_cmd_iob1_loopback);
-
-         clusters[XMAX-1][YMAX-1]->p_dspin_ram_cmd_out[EAST]  (signal_dspin_false_ram_cmd_out[XMAX-1][YMAX-1][EAST]);
-         clusters[XMAX-1][YMAX-1]->p_dspin_ram_rsp_in[EAST]   (signal_dspin_false_ram_rsp_in[XMAX-1][YMAX-1][EAST]);
-
-         clusters[XMAX-1][YMAX-1]->p_dspin_ram_rsp_out[EAST]  (signal_dspin_rsp_iob1_loopback);
-         (*clusters[XMAX-1][YMAX-1]->p_dspin_iob_rsp_in)      (signal_dspin_rsp_iob1_loopback); 
-      }
-      else
-      {
-         clusters[XMAX-1][y]->p_dspin_ram_cmd_in[EAST]        (signal_dspin_false_ram_cmd_in[XMAX-1][y][EAST]);
-         clusters[XMAX-1][y]->p_dspin_ram_cmd_out[EAST]       (signal_dspin_false_ram_cmd_out[XMAX-1][y][EAST]);
-         clusters[XMAX-1][y]->p_dspin_ram_rsp_in[EAST]        (signal_dspin_false_ram_rsp_in[XMAX-1][y][EAST]);
-         clusters[XMAX-1][y]->p_dspin_ram_rsp_out[EAST]       (signal_dspin_false_ram_rsp_out[XMAX-1][y][EAST]);
-      }
+     clusters[0][y]->p_dspin_ram_cmd_in[WEST]       (signal_dspin_false_ram_cmd_in[0][y][WEST]);
+     clusters[0][y]->p_dspin_ram_cmd_out[WEST]      (signal_dspin_false_ram_cmd_out[0][y][WEST]);
+     clusters[0][y]->p_dspin_ram_rsp_in[WEST]       (signal_dspin_false_ram_rsp_in[0][y][WEST]);
+     clusters[0][y]->p_dspin_ram_rsp_out[WEST]      (signal_dspin_false_ram_rsp_out[0][y][WEST]);
+
+     clusters[XMAX-1][y]->p_dspin_ram_cmd_in[EAST]  (signal_dspin_false_ram_cmd_in[XMAX-1][y][EAST]);
+     clusters[XMAX-1][y]->p_dspin_ram_cmd_out[EAST] (signal_dspin_false_ram_cmd_out[XMAX-1][y][EAST]);
+     clusters[XMAX-1][y]->p_dspin_ram_rsp_in[EAST]  (signal_dspin_false_ram_rsp_in[XMAX-1][y][EAST]);
+     clusters[XMAX-1][y]->p_dspin_ram_rsp_out[EAST] (signal_dspin_false_ram_rsp_out[XMAX-1][y][EAST]);
    }
 
@@ -1391,13 +1339,13 @@
       }
 
-      clusters[x][0]->p_dspin_ram_cmd_in[SOUTH]               (signal_dspin_false_ram_cmd_in[x][0][SOUTH]);
-      clusters[x][0]->p_dspin_ram_cmd_out[SOUTH]              (signal_dspin_false_ram_cmd_out[x][0][SOUTH]);
-      clusters[x][0]->p_dspin_ram_rsp_in[SOUTH]               (signal_dspin_false_ram_rsp_in[x][0][SOUTH]);
-      clusters[x][0]->p_dspin_ram_rsp_out[SOUTH]              (signal_dspin_false_ram_rsp_out[x][0][SOUTH]);
-
-      clusters[x][YMAX-1]->p_dspin_ram_cmd_in[NORTH]          (signal_dspin_false_ram_cmd_in[x][YMAX-1][NORTH]);
-      clusters[x][YMAX-1]->p_dspin_ram_cmd_out[NORTH]         (signal_dspin_false_ram_cmd_out[x][YMAX-1][NORTH]);
-      clusters[x][YMAX-1]->p_dspin_ram_rsp_in[NORTH]          (signal_dspin_false_ram_rsp_in[x][YMAX-1][NORTH]);
-      clusters[x][YMAX-1]->p_dspin_ram_rsp_out[NORTH]         (signal_dspin_false_ram_rsp_out[x][YMAX-1][NORTH]);
+      clusters[x][0]->p_dspin_ram_cmd_in[SOUTH]       (signal_dspin_false_ram_cmd_in[x][0][SOUTH]);
+      clusters[x][0]->p_dspin_ram_cmd_out[SOUTH]      (signal_dspin_false_ram_cmd_out[x][0][SOUTH]);
+      clusters[x][0]->p_dspin_ram_rsp_in[SOUTH]       (signal_dspin_false_ram_rsp_in[x][0][SOUTH]);
+      clusters[x][0]->p_dspin_ram_rsp_out[SOUTH]      (signal_dspin_false_ram_rsp_out[x][0][SOUTH]);
+
+      clusters[x][YMAX-1]->p_dspin_ram_cmd_in[NORTH]  (signal_dspin_false_ram_cmd_in[x][YMAX-1][NORTH]);
+      clusters[x][YMAX-1]->p_dspin_ram_cmd_out[NORTH] (signal_dspin_false_ram_cmd_out[x][YMAX-1][NORTH]);
+      clusters[x][YMAX-1]->p_dspin_ram_rsp_in[NORTH]  (signal_dspin_false_ram_rsp_in[x][YMAX-1][NORTH]);
+      clusters[x][YMAX-1]->p_dspin_ram_rsp_out[NORTH] (signal_dspin_false_ram_rsp_out[x][YMAX-1][NORTH]);
    }
 
@@ -1411,16 +1359,6 @@
 
    signal_resetn = false;
-
    signal_irq_false = false;
 
-   // only one cluster case:
-   if ( cluster_iob0 == cluster_iob1 )
-   {
-      signal_vci_ini_iob1.cmdval = false;
-      signal_vci_ini_iob1.rspack = true;
-      signal_vci_tgt_iob1.cmdack = true;
-      signal_vci_tgt_iob1.rspval = false;
-   }
-      
    // network boundaries signals
    for (size_t x = 0; x < XMAX ; x++)
@@ -1478,7 +1416,7 @@
             uint64_t ms2 = (uint64_t) t2.tv_sec  * 1000ULL +
                            (uint64_t) t2.tv_usec / 1000;
-            std::cerr << "### cycle = " << n 
-                      << " / frequency = " 
-                      << (double) 5000000 / (double) (ms2 - ms1) << "Khz"
+            std::cerr << "### cycle = " << n
+                      << " / frequency = "
+                      << (double) 1000000 / (double) (ms2 - ms1) << "Khz"
                       << std::endl;
 
@@ -1500,5 +1438,5 @@
             std::cout << " ************************************************" << std::endl;
 
-            // trace proc[debug_proc_id] 
+            // trace proc[debug_proc_id]
             if ( debug_proc_id != 0xFFFFFFFF )
             {
@@ -1523,15 +1461,15 @@
 //              clusters[x][y]->signal_int_vci_tgt_mdma.print_trace(mdma_signame.str());
 
-                if( clusters[x][y]->signal_proc_it[l].read() ) 
+                if( clusters[x][y]->signal_proc_it[l].read() )
                     std::cout << "### IRQ_PROC_" << std::dec
                               << x << "_" << y << "_" << l << " ACTIVE" << std::endl;
-            }   
-
-            // trace memc[debug_memc_id] 
+            }
+
+            // trace memc[debug_memc_id]
             if ( debug_memc_id != 0xFFFFFFFF )
             {
                 size_t x = debug_memc_id >> 4;
                 size_t y = debug_memc_id & 0xF;
-            
+
                 clusters[x][y]->memc->print_trace(0);
                 std::ostringstream smemc_tgt;
@@ -1554,5 +1492,5 @@
                 size_t x = debug_xram_id >> 4;
                 size_t y = debug_xram_id & 0xF;
-            
+
                 clusters[x][y]->xram->print_trace();
                 std::ostringstream sxram_tgt;
@@ -1563,18 +1501,16 @@
                 clusters[x][y]->ram_router_rsp->print_trace();
             }
-        
-            // trace iob, iox and external peripherals  
+
+            // trace iob, iox and external peripherals
             if ( debug_iob )
             {
                 clusters[0][0]->iob->print_trace();
-                clusters[0][0]->signal_int_vci_tgt_iobx.print_trace( "[SIG]IOB0_INT_TGT");
-                clusters[0][0]->signal_int_vci_ini_iobx.print_trace( "[SIG]IOB0_INT_INI");
-                clusters[0][0]->signal_ram_vci_ini_iobx.print_trace( "[SIG]IOB0_RAM_INI");
+                clusters[XMAX-1][YMAX-1]->iob->print_trace();
+//              clusters[0][0]->signal_int_vci_tgt_iobx.print_trace( "[SIG]IOB0_INT_TGT");
+//              clusters[0][0]->signal_int_vci_ini_iobx.print_trace( "[SIG]IOB0_INT_INI");
+//              clusters[0][0]->signal_ram_vci_ini_iobx.print_trace( "[SIG]IOB0_RAM_INI");
 
                 signal_vci_ini_iob0.print_trace("[SIG]IOB0_IOX_INI");
                 signal_vci_tgt_iob0.print_trace("[SIG]IOB0_IOX_TGT");
-
-//              signal_dspin_cmd_iob0_loopback.print_trace("[SIG]IOB0_CMD_LOOPBACK"); 
-//              signal_dspin_rsp_iob0_loopback.print_trace("[SIG]IOB0_RSP_LOOPBACK"); 
 
 //              cdma->print_trace();
Index: /trunk/platforms/tsar_generic_iob/tsar_iob_cluster/caba/metadata/tsar_iob_cluster.sd
===================================================================
--- /trunk/platforms/tsar_generic_iob/tsar_iob_cluster/caba/metadata/tsar_iob_cluster.sd	(revision 717)
+++ /trunk/platforms/tsar_generic_iob/tsar_iob_cluster/caba/metadata/tsar_iob_cluster.sd	(revision 718)
@@ -59,4 +59,10 @@
               flit_width         = parameter.Reference('dspin_int_rsp_width')),
 
+        Uses('caba:dspin_local_crossbar', 
+              flit_width         = parameter.Reference('dspin_ram_cmd_width')),
+
+        Uses('caba:dspin_local_crossbar', 
+              flit_width         = parameter.Reference('dspin_ram_rsp_width')),
+
         Uses('caba:vci_dspin_initiator_wrapper', 
               cell_size          = parameter.Reference('vci_data_width_int'),
@@ -86,8 +92,8 @@
               dspin_rsp_width    = parameter.Reference('dspin_ram_rsp_width')),
 
-        Uses('caba:dspin_router_tsar', 
+        Uses('caba:dspin_router', 
               flit_width         = parameter.Reference('dspin_ram_cmd_width')),
 
-        Uses('caba:dspin_router_tsar', 
+        Uses('caba:dspin_router', 
               flit_width         = parameter.Reference('dspin_ram_rsp_width')),
 
Index: /trunk/platforms/tsar_generic_iob/tsar_iob_cluster/caba/source/include/tsar_iob_cluster.h
===================================================================
--- /trunk/platforms/tsar_generic_iob/tsar_iob_cluster/caba/source/include/tsar_iob_cluster.h	(revision 717)
+++ /trunk/platforms/tsar_generic_iob/tsar_iob_cluster/caba/source/include/tsar_iob_cluster.h	(revision 718)
@@ -26,5 +26,5 @@
 #include "vci_dspin_initiator_wrapper.h"
 #include "vci_dspin_target_wrapper.h"
-#include "dspin_router_tsar.h"
+#include "dspin_router.h"
 #include "virtual_dspin_router.h"
 #include "vci_multi_dma.h"
@@ -57,8 +57,4 @@
     soclib::caba::VciTarget<vci_param_ext>*            p_vci_iob_iox_tgt; 
 
-    // These ports are used to connect IOB to RAM network in top cell
-    soclib::caba::DspinOutput<dspin_ram_cmd_width>*    p_dspin_iob_cmd_out;  
-    soclib::caba::DspinInput<dspin_ram_rsp_width>*     p_dspin_iob_rsp_in;  
-
     // These arrays of ports are used to connect the INT & RAM networks in top cell
     soclib::caba::DspinOutput<dspin_int_cmd_width>**   p_dspin_int_cmd_out;
@@ -116,9 +112,16 @@
     VciSignals<vci_param_ext>             signal_ram_vci_tgt_xram;
 
-    // RAM network DSPIN signals between VCI/DSPIN wrappers and routers 
+    // RAM network DSPIN signals between VCI/DSPIN wrappers, RAM dspin crossbar
+    // and routers 
     DspinSignals<dspin_ram_cmd_width>     signal_ram_dspin_cmd_xram_t;
     DspinSignals<dspin_ram_rsp_width>     signal_ram_dspin_rsp_xram_t;
     DspinSignals<dspin_ram_cmd_width>     signal_ram_dspin_cmd_memc_i;
     DspinSignals<dspin_ram_rsp_width>     signal_ram_dspin_rsp_memc_i;
+    DspinSignals<dspin_ram_cmd_width>     signal_ram_dspin_cmd_iob_i;
+    DspinSignals<dspin_ram_rsp_width>     signal_ram_dspin_rsp_iob_i;
+    DspinSignals<dspin_ram_cmd_width>     signal_ram_dspin_cmd_xbar;
+    DspinSignals<dspin_ram_rsp_width>     signal_ram_dspin_rsp_xbar;
+    DspinSignals<dspin_ram_cmd_width>     signal_ram_dspin_cmd_false;
+    DspinSignals<dspin_ram_rsp_width>     signal_ram_dspin_rsp_false;
   
     //////////////////////////////////////
@@ -166,6 +169,10 @@
                           dspin_ram_rsp_width>*       xram_ram_wt;
     
-    DspinRouterTsar<dspin_ram_cmd_width>*             ram_router_cmd;
-    DspinRouterTsar<dspin_ram_rsp_width>*             ram_router_rsp;
+    DspinRouter<dspin_ram_cmd_width>*                 ram_router_cmd;
+    DspinRouter<dspin_ram_rsp_width>*                 ram_router_rsp;
+
+    DspinLocalCrossbar<dspin_ram_cmd_width>*          ram_xbar_cmd;
+    DspinLocalCrossbar<dspin_ram_rsp_width>*          ram_xbar_rsp;
+    
 
     // IO Network Components (not instanciated in all clusters)
@@ -177,5 +184,5 @@
                              dspin_ram_cmd_width,
                              dspin_ram_rsp_width>*    iob_ram_wi;
-    
+
     // cluster constructor
     TsarIobCluster( sc_module_name                     insname,
@@ -195,17 +202,19 @@
                     size_t                             l_width,       // l field  bits
 
-                    size_t                             int_memc_tgtid,
-                    size_t                             int_xicu_tgtid,
-                    size_t                             int_mdma_tgtid,
-                    size_t                             int_iobx_tgtid,
-
-                    size_t                             int_proc_srcid,
-                    size_t                             int_mdma_srcid,
-                    size_t                             int_iobx_srcid,
-
-                    size_t                             ext_xram_tgtid,
-
-                    size_t                             ext_memc_srcid,
-                    size_t                             ext_iobx_srcid,
+                    size_t                             int_memc_tgt_id,
+                    size_t                             int_xicu_tgt_id,
+                    size_t                             int_mdma_tgt_id,
+                    size_t                             int_iobx_tgt_id,
+                    size_t                             int_proc_ini_id,
+                    size_t                             int_mdma_ini_id,
+                    size_t                             int_iobx_ini_id,
+
+                    size_t                             ram_xram_tgt_id,
+                    size_t                             ram_memc_ini_id,
+                    size_t                             ram_iobx_ini_id,
+
+                    bool                               is_io,
+                    size_t                             iox_iobx_tgt_id,
+                    size_t                             iox_iobx_ini_id,
 
                     size_t                             memc_ways,
@@ -226,4 +235,11 @@
                     bool                               iob0_debug_ok ); 
 
+  protected:
+
+    SC_HAS_PROCESS(TsarIobCluster);
+
+    void init();
+ 
+
 };
 
@@ -231,2 +247,12 @@
 
 #endif
+
+// Local Variables:
+// tab-width: 3
+// c-basic-offset: 3
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+
+// vim: filetype=cpp:expandtab:shiftwidth=3:tabstop=3:softtabstop=3
+//
Index: /trunk/platforms/tsar_generic_iob/tsar_iob_cluster/caba/source/src/tsar_iob_cluster.cpp
===================================================================
--- /trunk/platforms/tsar_generic_iob/tsar_iob_cluster/caba/source/src/tsar_iob_cluster.cpp	(revision 717)
+++ /trunk/platforms/tsar_generic_iob/tsar_iob_cluster/caba/source/src/tsar_iob_cluster.cpp	(revision 718)
@@ -15,4 +15,13 @@
 #include "../include/tsar_iob_cluster.h"
 
+#define tmpl(x) \
+   template<typename vci_param_int      , typename vci_param_ext,\
+            size_t   dspin_int_cmd_width, size_t   dspin_int_rsp_width,\
+            size_t   dspin_ram_cmd_width, size_t   dspin_ram_rsp_width>\
+            x TsarIobCluster<\
+                  vci_param_int      , vci_param_ext,\
+                  dspin_int_cmd_width, dspin_int_rsp_width,\
+                  dspin_ram_cmd_width, dspin_ram_rsp_width>
+
 namespace soclib { namespace caba  {
 
@@ -20,16 +29,5 @@
 //                 Constructor
 //////////////////////////////////////////////////////////////////////////
-template<typename vci_param_int, 
-         typename vci_param_ext,
-         size_t   dspin_int_cmd_width, 
-         size_t   dspin_int_rsp_width,
-         size_t   dspin_ram_cmd_width, 
-         size_t   dspin_ram_rsp_width>
-TsarIobCluster<vci_param_int, 
-               vci_param_ext,
-               dspin_int_cmd_width, 
-               dspin_int_rsp_width,
-               dspin_ram_cmd_width, 
-               dspin_ram_rsp_width>::TsarIobCluster(
+tmpl(/**/)::TsarIobCluster(
 //////////////////////////////////////////////////////////////////////////
                     sc_module_name                     insname,
@@ -49,17 +47,20 @@
                     size_t                             l_width,
 
-                    size_t                             memc_int_tgtid,  // local index
-                    size_t                             xicu_int_tgtid,  // local index
-                    size_t                             mdma_int_tgtid,  // local index
-                    size_t                             iobx_int_tgtid,  // local index
-
-                    size_t                             proc_int_srcid,  // local index
-                    size_t                             mdma_int_srcid,  // local index
-                    size_t                             iobx_int_srcid,  // local index
-
-                    size_t                             xram_ram_tgtid,  // local index
-
-                    size_t                             memc_ram_srcid,  // local index
-                    size_t                             iobx_ram_srcid,  // local index
+                    size_t                             int_memc_tgt_id, // local index
+                    size_t                             int_xicu_tgt_id, // local index
+                    size_t                             int_mdma_tgt_id, // local index
+                    size_t                             int_iobx_tgt_id, // local index
+
+                    size_t                             int_proc_ini_id, // local index
+                    size_t                             int_mdma_ini_id, // local index
+                    size_t                             int_iobx_ini_id, // local index
+
+                    size_t                             ram_xram_tgt_id, // local index
+                    size_t                             ram_memc_ini_id, // local index
+                    size_t                             ram_iobx_ini_id, // local index
+
+                    bool                               is_io,           // is IO cluster (IOB)?
+                    size_t                             iox_iobx_tgt_id, // local_index
+                    size_t                             iox_iobx_ini_id, // local index
 
                     size_t                             memc_ways,
@@ -87,7 +88,4 @@
     size_t cluster_id = (x_id<<4) + y_id;
 
-    size_t cluster_iob0 = 0;                            // South-West cluster
-    size_t cluster_iob1 = ((xmax-1)<<4) + ymax-1;       // North-East cluster
-
     // Vectors of DSPIN ports for inter-cluster communications
     p_dspin_int_cmd_in  = alloc_elems<DspinInput<dspin_int_cmd_width> >("p_int_cmd_in", 4, 3);
@@ -101,14 +99,9 @@
     p_dspin_ram_rsp_out = alloc_elems<DspinOutput<dspin_ram_rsp_width> >("p_ext_rsp_out", 4);
 
-    // ports in cluster_iob0 and cluster_iob1 only
-    if ( (cluster_id == cluster_iob0) or (cluster_id == cluster_iob1) )
-    {
-        // VCI ports from IOB to IOX network
+    // VCI ports from IOB to IOX network (only in IO clusters)
+    if ( is_io )
+    {
         p_vci_iob_iox_ini = new soclib::caba::VciInitiator<vci_param_ext>;
         p_vci_iob_iox_tgt = new soclib::caba::VciTarget<vci_param_ext>; 
-
-        // DSPIN ports from IOB to RAM network
-        p_dspin_iob_cmd_out = new soclib::caba::DspinOutput<dspin_ram_cmd_width>;
-        p_dspin_iob_rsp_in  = new soclib::caba::DspinInput<dspin_ram_rsp_width>;
     }
 
@@ -135,6 +128,6 @@
                       8,                              // DTLB ways
                       8,                              // DTLB sets
-                      l1_i_ways,l1_i_sets,16,         // ICACHE size
-                      l1_d_ways,l1_d_sets,16,         // DCACHE size
+                      l1_i_ways, l1_i_sets, 16,       // ICACHE size
+                      l1_d_ways, l1_d_sets, 16,       // DCACHE size
                       4,                              // WBUF nlines
                       4,                              // WBUF nwords
@@ -154,16 +147,16 @@
                            dspin_int_cmd_width>(
                      s_memc.str().c_str(),
-                     mt_int,                             // Mapping Table INT network
-                     mt_ram,                             // Mapping Table RAM network
-                     IntTab(cluster_id, memc_ram_srcid), // SRCID RAM network
-                     IntTab(cluster_id, memc_int_tgtid), // TGTID INT network
-                     x_width,                            // number of bits for x coordinate
-                     y_width,                            // number of bits for y coordinate
-                     memc_ways, memc_sets, 16,           // CACHE SIZE
-                     3,                                  // MAX NUMBER OF COPIES
-                     4096,                               // HEAP SIZE
-                     8,                                  // TRANSACTION TABLE DEPTH
-                     8,                                  // UPDATE TABLE DEPTH
-                     8,                                  // INVALIDATE TABLE DEPTH
+                     mt_int,                              // Mapping Table INT network
+                     mt_ram,                              // Mapping Table RAM network
+                     IntTab(cluster_id, ram_memc_ini_id), // SRCID RAM network
+                     IntTab(cluster_id, int_memc_tgt_id), // TGTID INT network
+                     x_width,                             // number of bits for x coordinate
+                     y_width,                             // number of bits for y coordinate
+                     memc_ways, memc_sets, 16,            // CACHE SIZE
+                     3,                                   // MAX NUMBER OF COPIES
+                     4096,                                // HEAP SIZE
+                     8,                                   // TRANSACTION TABLE DEPTH
+                     8,                                   // UPDATE TABLE DEPTH
+                     8,                                   // INVALIDATE TABLE DEPTH
                      debug_start_cycle,
                      memc_debug_ok );
@@ -182,10 +175,10 @@
     xicu = new VciXicu<vci_param_int>(
                      s_xicu.str().c_str(),
-                     mt_int,                            // mapping table INT network
-                     IntTab(cluster_id,xicu_int_tgtid), // TGTID direct space
-                     xcu_nb_inputs,                     // number of timer IRQs
-                     xcu_nb_inputs,                     // number of hard IRQs
-                     xcu_nb_inputs,                     // number of soft IRQs
-                     16);                               // number of output IRQs
+                     mt_int,                              // mapping table INT network
+                     IntTab(cluster_id, int_xicu_tgt_id), // TGTID direct space
+                     xcu_nb_inputs,                       // number of timer IRQs
+                     xcu_nb_inputs,                       // number of hard IRQs
+                     xcu_nb_inputs,                       // number of soft IRQs
+                     16);                                 // number of output IRQs
 
     ////////////  MDMA
@@ -196,16 +189,11 @@
                      mt_int,
                      IntTab(cluster_id, nb_procs),        // SRCID
-                     IntTab(cluster_id, mdma_int_tgtid),  // TGTID
+                     IntTab(cluster_id, int_mdma_tgt_id), // TGTID
                      64,                                  // burst size
                      nb_dmas);                            // number of IRQs
 
     ///////////  Direct LOCAL_XBAR(S)
-    size_t nb_direct_initiators      = nb_procs + 1;
-    size_t nb_direct_targets         = 3;
-    if ( (cluster_id == cluster_iob0) or (cluster_id == cluster_iob1) )
-    {
-        nb_direct_initiators         = nb_procs + 2;
-        nb_direct_targets            = 4;
-    }
+    size_t nb_direct_initiators = is_io ? nb_procs + 2 : nb_procs + 1;
+    size_t nb_direct_targets    = is_io ? 4 : 3;
 
     std::ostringstream s_int_xbar_d;
@@ -304,5 +292,5 @@
     xram = new VciSimpleRam<vci_param_ext>(
                      s_xram.str().c_str(),
-                     IntTab(cluster_id, xram_ram_tgtid ),
+                     IntTab(cluster_id, ram_xram_tgt_id),
                      mt_ram,
                      loader,
@@ -320,48 +308,25 @@
     std::ostringstream s_ram_router_cmd;
     s_ram_router_cmd << "ram_router_cmd_" << x_id << "_" << y_id;
-    size_t is_iob0 = (x_id == 0) and (y_id == 0);
-    size_t is_iob1 = (x_id == (xmax-1)) and (y_id == (ymax-1));
-    ram_router_cmd = new DspinRouterTsar<dspin_ram_cmd_width>(
+    ram_router_cmd = new DspinRouter<dspin_ram_cmd_width>(
                      s_ram_router_cmd.str().c_str(),
                      x_id, y_id,                     // router coordinates in mesh
                      x_width,                        // x field width in first flit
                      y_width,                        // y field width in first flit
-                     4, 4,                           // input & output fifo depths
-                     is_iob0,                        // cluster contains IOB0
-                     is_iob1,                        // cluster contains IOB1
-                     false,                          // not a response router
-                     l_width);                       // local field width in first flit
+                     4, 4);                          // input & output fifo depths
 
     std::ostringstream s_ram_router_rsp;
     s_ram_router_rsp << "ram_router_rsp_" << x_id << "_" << y_id;
-    ram_router_rsp = new DspinRouterTsar<dspin_ram_rsp_width>(
+    ram_router_rsp = new DspinRouter<dspin_ram_rsp_width>(
                      s_ram_router_rsp.str().c_str(),
                      x_id, y_id,                     // coordinates in mesh
                      x_width,                        // x field width in first flit
                      y_width,                        // y field width in first flit
-                     4, 4,                           // input & output fifo depths
-                     is_iob0,                        // cluster contains IOB0
-                     is_iob1,                        // cluster contains IOB1
-                     true,                           // response router
-                     l_width);                       // local field width in first flit
+                     4, 4);                          // input & output fifo depths
 
 
     ////////////////////// I/O  CLUSTER ONLY    ///////////////////////
-    if ( (cluster_id == cluster_iob0) or (cluster_id == cluster_iob1) )
+    if ( is_io )
     {
         ///////////  IO_BRIDGE
-        size_t iox_local_id;
-        size_t global_id;
-        if ( cluster_id == cluster_iob0 ) 
-        {
-            iox_local_id = 0;
-            global_id    = cluster_iob0;
-        }
-        else
-        {
-            iox_local_id = 1;
-            global_id    = cluster_iob1;
-        }
-
         std::ostringstream s_iob;
         s_iob << "iob_" << x_id << "_" << y_id;   
@@ -369,13 +334,14 @@
                               vci_param_ext>(  
                      s_iob.str().c_str(),
-                     mt_ram,                               // EXT network maptab
-                     mt_int,                               // INT network maptab
-                     mt_iox,                               // IOX network maptab
-                     IntTab( global_id, iobx_int_tgtid ),  // INT TGTID
-                     IntTab( global_id, iobx_int_srcid ),  // INT SRCID
-                     IntTab( global_id, iox_local_id   ),  // IOX TGTID
-                     16,                                   // cache line words
-                     8,                                    // IOTLB ways
-                     8,                                    // IOTLB sets
+                     mt_ram,                                // EXT network maptab
+                     mt_int,                                // INT network maptab
+                     mt_iox,                                // IOX network maptab
+                     IntTab( cluster_id, int_iobx_tgt_id ), // INT TGTID
+                     IntTab( cluster_id, int_iobx_ini_id ), // INT SRCID
+                     IntTab( 0         , iox_iobx_tgt_id ), // IOX TGTID
+                     IntTab( 0         , iox_iobx_ini_id ), // IOX SRCID
+                     16,                                    // cache line words
+                     8,                                     // IOTLB ways
+                     8,                                     // IOTLB sets
                      debug_start_cycle,
                      iob_debug_ok );
@@ -387,5 +353,31 @@
                                                   dspin_ram_rsp_width>(
                      s_iob_ram_wi.str().c_str(),
-                     x_width + y_width + l_width);
+                     vci_param_int::S);
+
+        std::ostringstream s_ram_xbar_cmd;
+        s_ram_xbar_cmd << "s_ram_xbar_cmd_" << x_id << "_" << y_id;
+        ram_xbar_cmd = new DspinLocalCrossbar<dspin_ram_cmd_width>(
+              s_ram_xbar_cmd.str().c_str(), // name
+              mt_ram,                       // mapping table
+              x_id, y_id,                   // x, y
+              x_width, y_width, l_width,    // x_width, y_width, l_width
+              2, 0,                         // local inputs, local outputs
+              2, 2,                         // in fifo, out fifo depths
+              true,                         // is cmd ?
+              false,                        // use routing table ?
+              false);                       // support broadcast ?
+
+        std::ostringstream s_ram_xbar_rsp;
+        s_ram_xbar_rsp << "s_ram_xbar_rsp_" << x_id << "_" << y_id;
+        ram_xbar_rsp = new DspinLocalCrossbar<dspin_ram_rsp_width>(
+              s_ram_xbar_rsp.str().c_str(), // name
+              mt_ram,                       // mapping table
+              x_id, y_id,                   // x, y
+              x_width, y_width, l_width,    // x_width, y_width, l_width
+              0, 2,                         // local inputs, local outputs
+              2, 2,                         // in fifo, out fifo depths
+              false,                        // is cmd ?
+              true,                         // use routing table ?
+              false);                       // support broadcast ?
     } // end if IO
 
@@ -396,7 +388,4 @@
     // on coherence network : local srcid[proc] in [0...nb_procs-1]
     //                      : local srcid[memc] = nb_procs
-    // In cluster_iob0, 32 HWI interrupts from external peripherals
-    // are connected to the XICU ports p_hwi[0:31] 
-    // In other clusters, no HWI interrupts are connected to XICU
  
     //////////////////////// internal CMD & RSP routers
@@ -440,15 +429,15 @@
     int_xbar_d->p_target_to_up                        (signal_int_vci_g2l);
 
-    int_xbar_d->p_to_target[memc_int_tgtid]           (signal_int_vci_tgt_memc);
-    int_xbar_d->p_to_target[xicu_int_tgtid]           (signal_int_vci_tgt_xicu);
-    int_xbar_d->p_to_target[mdma_int_tgtid]           (signal_int_vci_tgt_mdma);
-    int_xbar_d->p_to_initiator[mdma_int_srcid]        (signal_int_vci_ini_mdma);
+    int_xbar_d->p_to_target[int_memc_tgt_id]          (signal_int_vci_tgt_memc);
+    int_xbar_d->p_to_target[int_xicu_tgt_id]          (signal_int_vci_tgt_xicu);
+    int_xbar_d->p_to_target[int_mdma_tgt_id]          (signal_int_vci_tgt_mdma);
+    int_xbar_d->p_to_initiator[int_mdma_ini_id]       (signal_int_vci_ini_mdma);
     for (size_t p = 0; p < nb_procs; p++)
-       int_xbar_d->p_to_initiator[proc_int_srcid + p] (signal_int_vci_ini_proc[p]);
-
-    if ( (cluster_id == cluster_iob0) or (cluster_id == cluster_iob1) )
-    {
-       int_xbar_d->p_to_target[iobx_int_tgtid]        (signal_int_vci_tgt_iobx);
-       int_xbar_d->p_to_initiator[iobx_int_srcid]     (signal_int_vci_ini_iobx);
+       int_xbar_d->p_to_initiator[int_proc_ini_id + p] (signal_int_vci_ini_proc[p]);
+
+    if ( is_io )
+    {
+       int_xbar_d->p_to_target[int_iobx_tgt_id]        (signal_int_vci_tgt_iobx);
+       int_xbar_d->p_to_initiator[int_iobx_ini_id]     (signal_int_vci_ini_iobx);
     }
 
@@ -573,30 +562,64 @@
         ram_router_rsp->p_in[n]                  (this->p_dspin_ram_rsp_in[n]);
     }
+
     ram_router_cmd->p_out[4]                     (signal_ram_dspin_cmd_xram_t);
-    ram_router_cmd->p_in[4]                      (signal_ram_dspin_cmd_memc_i);
-    ram_router_rsp->p_out[4]                     (signal_ram_dspin_rsp_memc_i);
     ram_router_rsp->p_in[4]                      (signal_ram_dspin_rsp_xram_t);
+
+    if ( is_io )
+    {
+       ram_router_cmd->p_in[4]                   (signal_ram_dspin_cmd_xbar);
+       ram_router_rsp->p_out[4]                  (signal_ram_dspin_rsp_xbar);
+    }
+    else
+    {
+       ram_router_cmd->p_in[4]                   (signal_ram_dspin_cmd_memc_i);
+       ram_router_rsp->p_out[4]                  (signal_ram_dspin_rsp_memc_i);
+    }
    
     ///////////////////////// IOB exists only in cluster_iob0 & cluster_iob1. 
-    if ( (cluster_id == cluster_iob0) or (cluster_id == cluster_iob1) )
+    if ( is_io )
     {
         // IO bridge
-        iob->p_clk                               (this->p_clk);
-        iob->p_resetn                            (this->p_resetn);
-        iob->p_vci_ini_iox                       (*(this->p_vci_iob_iox_ini));
-        iob->p_vci_tgt_iox                       (*(this->p_vci_iob_iox_tgt));
-        iob->p_vci_tgt_int                       (signal_int_vci_tgt_iobx);
-        iob->p_vci_ini_int                       (signal_int_vci_ini_iobx);
-        iob->p_vci_ini_ram                       (signal_ram_vci_ini_iobx);
+        iob->p_clk                                 (this->p_clk);
+        iob->p_resetn                              (this->p_resetn);
+        iob->p_vci_ini_iox                         (*(this->p_vci_iob_iox_ini));
+        iob->p_vci_tgt_iox                         (*(this->p_vci_iob_iox_tgt));
+        iob->p_vci_tgt_int                         (signal_int_vci_tgt_iobx);
+        iob->p_vci_ini_int                         (signal_int_vci_ini_iobx);
+        iob->p_vci_ini_ram                         (signal_ram_vci_ini_iobx);
 
         // initiator wrapper to RAM network
-        iob_ram_wi->p_clk                        (this->p_clk);
-        iob_ram_wi->p_resetn                     (this->p_resetn);
-        iob_ram_wi->p_dspin_cmd                  (*(this->p_dspin_iob_cmd_out));
-        iob_ram_wi->p_dspin_rsp                  (*(this->p_dspin_iob_rsp_in));
-        iob_ram_wi->p_vci                        (signal_ram_vci_ini_iobx);
-    }
-
+        iob_ram_wi->p_clk                          (this->p_clk);
+        iob_ram_wi->p_resetn                       (this->p_resetn);
+        iob_ram_wi->p_dspin_cmd                    (signal_ram_dspin_cmd_iob_i);
+        iob_ram_wi->p_dspin_rsp                    (signal_ram_dspin_rsp_iob_i);
+        iob_ram_wi->p_vci                          (signal_ram_vci_ini_iobx);
+
+        // crossbar between MEMC and IOB to RAM network
+        ram_xbar_cmd->p_clk                        (this->p_clk);
+        ram_xbar_cmd->p_resetn                     (this->p_resetn);
+        ram_xbar_cmd->p_global_out                 (signal_ram_dspin_cmd_xbar);
+        ram_xbar_cmd->p_global_in                  (signal_ram_dspin_cmd_false);
+        ram_xbar_cmd->p_local_in[ram_memc_ini_id]  (signal_ram_dspin_cmd_memc_i);
+        ram_xbar_cmd->p_local_in[ram_iobx_ini_id]  (signal_ram_dspin_cmd_iob_i);
+
+        ram_xbar_rsp->p_clk                        (this->p_clk);
+        ram_xbar_rsp->p_resetn                     (this->p_resetn);
+        ram_xbar_rsp->p_global_out                 (signal_ram_dspin_rsp_false);
+        ram_xbar_rsp->p_global_in                  (signal_ram_dspin_rsp_xbar);
+        ram_xbar_rsp->p_local_out[ram_memc_ini_id] (signal_ram_dspin_rsp_memc_i);
+        ram_xbar_rsp->p_local_out[ram_iobx_ini_id] (signal_ram_dspin_rsp_iob_i);
+    }
+
+   SC_METHOD(init);
 } // end constructor
+
+tmpl(void)::init()
+{
+   signal_ram_dspin_cmd_false.write = false;
+   signal_ram_dspin_cmd_false.read = true;
+   signal_ram_dspin_rsp_false.write = false;
+   signal_ram_dspin_rsp_false.read = true;
+} // end init
 
 }}
@@ -612,4 +635,2 @@
 // vim: filetype=cpp:expandtab:shiftwidth=3:tabstop=3:softtabstop=3
 
-
-
