Index: /branches/fault_tolerance/platform/tsar_generic_iob/Makefile
===================================================================
--- /branches/fault_tolerance/platform/tsar_generic_iob/Makefile	(revision 716)
+++ /branches/fault_tolerance/platform/tsar_generic_iob/Makefile	(revision 717)
@@ -1,10 +1,12 @@
-SOCLIB_CC := soclib-cc
-RM        := rm -rf
-CP        := cp -f
-MAKE      := make
-TARGET    := simul.x
-ARGS      ?=
+ARGS           ?=
+SOCLIB_CC      := soclib-cc
+RM             := rm -rf
+CP             := cp -f
+MAKE           := make
+CONFIG_DIR     := $(PWD)/conf
 
-all: $(TARGET) preloader tags
+TARGET         := simul.x
+
+all: $(TARGET) tags
 
 # create simulator
@@ -13,16 +15,15 @@
 SRCS += tsar_iob_cluster/caba/source/src/tsar_iob_cluster.cpp
 INCS := tsar_iob_cluster/caba/source/include/tsar_iob_cluster.h
+INCS += $(CONFIG_DIR)/hard_config.h
 INCS += top.desc
 INCS += soclib.conf
 
-$(TARGET): $(SRCS) $(INCS)
+$(TARGET): $(SRCS) $(INCS) soclib.conf
 	$(SOCLIB_CC) -P -p top.desc -I. -o simul.x
 
 # create preloader
 
-MESHSIZE       := 4c1p
-PRELOADER_CONF := $(PWD)/conf/preloader_$(MESHSIZE)
 PRELOADER_PATH := $(TSARPATH)/trunk/softs/tsar_boot
-PRELOADER_ARGS := "PLATFORM_DIR=$(PRELOADER_CONF) USE_DT=0 SOCLIB=1"
+PRELOADER_ARGS := "PLATFORM_DIR=$(CONFIG_DIR) USE_DT=0 SOCLIB=1"
 PRELOADER_NAME ?= soft/soft.elf
 
@@ -35,25 +36,29 @@
 # run simulator
 
-SIMULATOR_ARGS  = -SOFT $(PRELOADER_NAME)
-SIMULATOR_ARGS += -DISK soft/disk.dmg
-SIMULATOR_ARGS += -XSIZE 2 -YSIZE 2 -NPROCS 1
+SOFT           ?= $(PRELOADER_NAME)
+DISK           ?= /dev/null
+
+SIMULATOR_ARGS  = -SOFT $(SOFT)
+SIMULATOR_ARGS += -DISK $(DISK)
 SIMULATOR_ARGS += $(ARGS)
 
-run: $(TARGET) $(PRELOADER_NAME)
+run: $(TARGET) $(SOFT)
 	./$< $(SIMULATOR_ARGS)
 
-# create tags file with ctags
+# create tags file with cscope
+tags: cscope.out
 
-tags:
-	$(SOCLIB_CC) -p top.desc --tags --tags-type=ctags --tags-output=$@
+cscope.out:
+	$(SOCLIB_CC) -p top.desc --tags --tags-type=cscope --tags-output=$@
 
 # clean targets
 
 clean:
+	$(SOCLIB_CC) -X 
 	$(SOCLIB_CC) -x -p top.desc -I.
-	$(RM) *.o *.x tty* term*
+	$(RM) *.o *.x mtty_*
 
 clean-soft:
-	$(RM) $(PRELOADER_NAME)
+	$(RM) $(SOFT)
 
 clean-tags:
@@ -66,4 +71,4 @@
 
 
-.PHONY: tags preloader clean clean-soft clean-preloader
+.PHONY: tags simul.x preloader clean clean-soft clean-preloader
 
Index: /branches/fault_tolerance/platform/tsar_generic_iob/soclib.conf
===================================================================
--- /branches/fault_tolerance/platform/tsar_generic_iob/soclib.conf	(revision 716)
+++ /branches/fault_tolerance/platform/tsar_generic_iob/soclib.conf	(revision 717)
@@ -1,10 +1,19 @@
+cflags = config.default.toolchain.cflags \
+         + ['-Iconf'] \
+         + ['-DUSE_OPENMP=0'] \
+#        + ['-ggdb']
+
 config.default.toolchain.set(
-	"cflags", config.default.toolchain.cflags
-#	"cflags", config.default.toolchain.cflags + ['-ggdb']
+    "cflags", cflags
 )
 
 import os
 tsar_path = os.environ['TSARPATH']
+config.addDescPath(tsar_path + "/trunk/lib")
+config.addDescPath(tsar_path + "/trunk/communication")
+config.addDescPath(tsar_path + "/trunk/modules/dspin_router_tsar")
+config.addDescPath(tsar_path + "/trunk/modules/vci_io_bridge")
+config.addDescPath(tsar_path + "/trunk/modules/vci_iox_network")
+config.addDescPath(tsar_path + "/trunk/modules/vci_block_device_tsar")
 config.addDescPath(tsar_path + "/branches/fault_tolerance/module")
 config.addDescPath(tsar_path + "/branches/fault_tolerance/lib")
-
Index: /branches/fault_tolerance/platform/tsar_generic_iob/top.cpp
===================================================================
--- /branches/fault_tolerance/platform/tsar_generic_iob/top.cpp	(revision 716)
+++ /branches/fault_tolerance/platform/tsar_generic_iob/top.cpp	(revision 717)
@@ -38,16 +38,6 @@
 //    (VCI ADDDRESS = 40 bits / VCI DATA width = 64 bits)
 //
-// The external peripherals IRQs are connected to the XICU component
-// in cluster(0,0): therefore, the number of channels for the external
-// peripherals (MTTY, MNIC, CDMA) is limited by the number of IRQ ports...
-//
-// In cluster(0,0), the XICU HWI input ports are connected as follow:
-// - IRQ_IN[0]  to IRQ_IN[7]  grounded (reserved for PTI or SWI)
-// - IRQ_IN[8]  to IRQ_IN[9]  are connected to 2 NIC_RX channels.
-// - IRQ_IN[10] to IRQ_IN[11] are connected to 2 NIC_TX channels.
-// - IRQ_IN[12] to IRQ_IN[15] are connected to 4 CDMA channels
-// - IRQ_IN[16] to IRQ_IN[30] are connected to 15 TTY channels
-// - IRQ_IN[31]               is connected to BDEV
-// In other clusters, the XICU HWI input ports are grounded.
+// The external peripherals IRQs are connected to the XPIC component
+// in IOX interconnect.
 //
 // All clusters are identical, but cluster(0,0) and cluster(XMAX-1,YMAX-1)
@@ -59,5 +49,5 @@
 // - 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
+// - 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
@@ -68,38 +58,15 @@
 // - It contains one vci_xicu and one vci_multi_dma per cluster.
 // - It contains one vci_simple ram per cluster to model the L3 cache.
-//
-// The TsarIobCluster component is defined in files
-// tsar_iob_cluster.* (with * = cpp, h, sd)
-//
-// The main hardware parameters must be defined in the hard_config.h file :
-// - XMAX        : number of clusters in a row (power of 2)
-// - YMAX        : number of clusters in a column (power of 2)
-// - CLUSTER_SIZE     : size of the segment allocated to a cluster
-// - NB_PROCS_MAX     : number of processors per cluster (power of 2)
-// - NB_DMA_CHANNELS  : number of DMA channels per cluster (< 9)
-// - NB_TTY_CHANNELS  : number of TTY channels in I/O network (< 16)
-// - NB_NIC_CHANNELS  : number of NIC channels in I/O network (< 9)
-//
-// Some secondary hardware parameters must be defined in this top.cpp file:
-// - 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
-// - FBUF_X_SIZE      : width of frame buffer (pixels)
-// - FBUF_Y_SIZE      : heigth of frame buffer (lines)
-// - BDEV_SECTOR_SIZE : block size for block drvice
-// - 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
-// - NIC_TIMEOUT      : max number of cycles before closing a container
+// - It contains one vci_simple_rom per cluster which can be used for a
+//   distributed boot.
+// - It contains one vci_multi_tty per cluster for debug purposes (number
+//   of channels can be 0). This TTY is mostly useful when using distributed
+//   boot.
 //
 // 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 (x_width + y_width) MSB bits (left aligned) define
-// the cluster index, and the LADR bits define the local index:
+// The (x_width + y_width) MSB bits define the cluster index, and the
+// LADR bits define the local index:
 //      | X_ID  | Y_ID  |---| LADR |     OFFSET          |
 //      |x_width|y_width|---|  8   |       24            |
@@ -129,4 +96,5 @@
 #include "vci_block_device_tsar.h"
 #include "vci_framebuffer.h"
+#include "vci_iopic.h"
 #include "vci_iox_network.h"
 
@@ -215,5 +183,5 @@
 // All initiators are in the same indexing space (14 bits).
 // The SRCID is structured in two fields:
-// - The 10 MSB bits define the cluster index (left aligned)
+// - The 10 MSB bits define the cluster index
 // - The 4  LSB bits define the local index.
 // Two different initiators cannot have the same SRCID, but a given
@@ -234,24 +202,26 @@
 #define MDMA_LOCAL_SRCID 0x8
 #define IOBX_LOCAL_SRCID 0x9
-#define MEMC_LOCAL_SRCID 0xA
-#define CDMA_LOCAL_SRCID 0xE // hard-coded in dspin_tsar
-#define BDEV_LOCAL_SRCID 0xF // hard-coded in dspin_tsar
+#define CDMA_LOCAL_SRCID 0xA
+#define BDEV_LOCAL_SRCID 0xB
+#define XPIC_LOCAL_SRCID 0xC
 
 ///////////////////////////////////////////////////////////////////////
-//     TGT_ID and INI_ID port indexing for I0X local interconnect
+//     TGT_ID and INI_ID port indexing for IOX local interconnect
 ///////////////////////////////////////////////////////////////////////
 
-#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_MTTY_TGT_ID 6
-
-#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_FBUF_TGT_ID 0
+#define IOX_BDEV_TGT_ID 1
+#define IOX_MNIC_TGT_ID 2
+#define IOX_CDMA_TGT_ID 3
+#define IOX_MTTY_TGT_ID 4
+#define IOX_XPIC_TGT_ID 5
+#define IOX_IOB0_TGT_ID 6
+#define IOX_IOB1_TGT_ID 7
+
+#define IOX_BDEV_INI_ID 0
+#define IOX_CDMA_INI_ID 1
+#define IOX_XPIC_INI_ID 2
+#define IOX_IOB0_INI_ID 3
+#define IOX_IOB1_INI_ID 4
 
 ////////////////////////////////////////////////////////////////////////
@@ -267,5 +237,5 @@
    char     nic_tx_name[256] = NIC_TX_NAME;       // path: tx packets file
    ssize_t  threads_nr       = 1;                 // simulator's threads
-   bool     debug_ok         = false;             // trace activated
+   bool     debug_ok         = false;
    size_t   debug_period     = 1;                 // trace period
    size_t   debug_memc_id    = 0xFFFFFFFF;        // idx of traced memc
@@ -274,4 +244,5 @@
    uint32_t debug_from       = 0;                 // trace start cycle
    uint32_t frozen_cycles    = MAX_FROZEN_CYCLES; // monitoring frozen procs
+   bool     distboot         = false;             // distributed boot
    const size_t block_size   = BDEV_SECTOR_SIZE;  // disk block size
    const size_t x_size       = X_SIZE;
@@ -296,5 +267,5 @@
          }
          if ((strcmp(argv[n],"-DEBUG") == 0) && ((n+1) < argc) ) {
-            debug_ok   = true;
+            debug_ok = true;
             debug_from = strtol(argv[n+1], NULL, 0);
             continue;
@@ -334,18 +305,28 @@
             continue;
          }
-
-         std::cout << "   Arguments are (key,value) couples.\n"
-            << "   The order is not important.\n"
-            << "   Accepted arguments are :\n\n"
-            << "     -NCYCLES number of simulated_cycles\n"
-            << "     -SOFT    pathname for embedded soft\n"
-            << "     -DISK    pathname for disk image\n"
-            << "     -DEBUG   debug start cycle\n"
-            << "     -MEMCID  index of memc to trace\n"
-            << "     -IOB     debug IOBs if non_zero_value\n\n"
-            << "     -PROCID  index of proc to trace\n"
-            << "     -THREADS simulator's threads number\n"
-            << "     -FROZEN  max number of frozen cycles\n"
-            << "     -PERIOD  number of cycles between trace\n\n";
+         if ((strcmp(argv[n], "-DISTBOOT") == 0)) {
+            distboot = true;
+            continue;
+         }
+
+         std::cout
+            << "\nArguments are (key,value) couples."
+            << "\nThe order is not important."
+            << "\nAccepted arguments are :\n"
+            << "\n    -NCYCLES   number of simulated_cycles"
+            << "\n    -SOFT      pathname for embedded soft"
+            << "\n    -DISK      pathname for disk image"
+            << "\n    -DEBUG     debug start cycle"
+            << "\n    -MEMCID    index of memc to trace"
+            << "\n    -IOB       debug IOBs if non_zero_value"
+            << "\n    -PROCID    index of proc to trace"
+            << "\n    -THREADS   simulator's threads number"
+            << "\n    -FROZEN    max number of frozen cycles"
+            << "\n    -PERIOD    number of cycles between trace"
+            << "\n    -DISTBOOT  use distributed boot ROM"
+            << "\n               (processors physical address extention is"
+            << "\n               initialized with local cluster id)"
+            << std::endl;
+
          exit(0);
       }
@@ -358,15 +339,19 @@
          "The NB_NIC_CHANNELS parameter must be 1" );
 
-   std::cout << std::endl;
-   std::cout << " - X_SIZE          = " << x_size          << std::endl;
-   std::cout << " - Y_SIZE          = " << y_size          << std::endl;
-   std::cout << " - NB_PROCS        = " << NB_PROCS        << std::endl;
-   std::cout << " - NB_DMA_CHANNELS = " << NB_DMA_CHANNELS << std::endl;
-   std::cout << " - NB_TTY_CHANNELS = " << NB_TTY_CHANNELS << std::endl;
-   std::cout << " - NB_NIC_CHANNELS = " << NB_NIC_CHANNELS << std::endl;
-   std::cout << " - MEMC_WAYS       = " << MEMC_WAYS       << std::endl;
-   std::cout << " - MEMC_SETS       = " << MEMC_SETS       << std::endl;
-   std::cout << " - RAM_LATENCY     = " << XRAM_LATENCY    << std::endl;
-   std::cout << " - MAX_FROZEN      = " << frozen_cycles   << std::endl;
+   assert( (x_size > 0) and (y_size > 0) and
+         "Number of clusters on X and Y must be at least 1" );
+
+   std::cout << "\n- X_SIZE          = " << x_size
+             << "\n- Y_SIZE          = " << y_size
+             << "\n- NB_PROCS        = " << NB_PROCS
+             << "\n- NB_DMA_CHANNELS = " << NB_DMA_CHANNELS
+             << "\n- NB_TTY_CHANNELS = " << NB_TTY_CHANNELS
+             << "\n- NB_NIC_CHANNELS = " << NB_NIC_CHANNELS
+             << "\n- MEMC_WAYS       = " << MEMC_WAYS
+             << "\n- MEMC_SETS       = " << MEMC_SETS
+             << "\n- RAM_LATENCY     = " << XRAM_LATENCY
+             << "\n- MAX_FROZEN      = " << frozen_cycles
+             << "\n- DISTBOOT        = " << distboot
+             << std::endl;
 
    std::cout << std::endl;
@@ -409,4 +394,7 @@
    size_t cluster_iob0 = cluster(0, 0);
    size_t cluster_iob1 = cluster(x_size - 1, y_size - 1);
+
+   // using mono cluster configuration (only one IO bridge) ?
+   bool is_mono_cluster = ((x_size == 1) && (y_size == 1));
 
    /////////////////////////////////////////////////////////////////////
@@ -507,4 +495,10 @@
                      IntTab(cluster(x,y), INT_IOBX_TGT_ID),
                      not cacheable));
+
+            std::ostringstream spic;
+            sdma << "int_seg_xpic_" << x << "_" << y;
+            maptab_int.add(Segment(spic.str(), XPIC_BASE+offset, XPIC_SIZE,
+                     IntTab(cluster(x,y), INT_IOBX_TGT_ID),
+                     not cacheable));
          }
 
@@ -515,4 +509,6 @@
                IntTab(cluster(x,y), INT_MDMA_INI_ID));
          maptab_int.srcid_map(IntTab(cluster(x,y), IOBX_LOCAL_SRCID),
+               IntTab(cluster(x,y), INT_IOBX_INI_ID));
+         maptab_int.srcid_map(IntTab(cluster(x,y), XPIC_LOCAL_SRCID),
                IntTab(cluster(x,y), INT_IOBX_INI_ID));
 
@@ -535,5 +531,5 @@
    MappingTable maptab_ram(
          vci_address_width,
-         IntTab(X_WIDTH + Y_WIDTH, 16 - X_WIDTH - Y_WIDTH),
+         IntTab(X_WIDTH + Y_WIDTH, 0),
          IntTab(X_WIDTH + Y_WIDTH, vci_param_int::S - X_WIDTH - Y_WIDTH),
          0x00FF000000);
@@ -547,5 +543,5 @@
          sxram << "ext_seg_xram_" << x << "_" << y;
          maptab_ram.add(Segment(sxram.str(), XRAM_BASE+offset, XRAM_SIZE,
-                  IntTab(cluster(x,y), 0), false));
+                  IntTab(cluster(x,y), RAM_XRAM_TGT_ID), false));
       }
    }
@@ -557,12 +553,21 @@
    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),
-         IntTab(cluster_iob1, RAM_IOBX_INI_ID));
    maptab_ram.srcid_map(IntTab(cluster_iob0, BDEV_LOCAL_SRCID),
          IntTab(cluster_iob0, RAM_IOBX_INI_ID));
-   maptab_ram.srcid_map(IntTab(cluster_iob1, BDEV_LOCAL_SRCID),
-         IntTab(cluster_iob1, RAM_IOBX_INI_ID));
-   maptab_ram.srcid_map(IntTab(cluster_iob1, MEMC_LOCAL_SRCID),
-         IntTab(cluster_iob1, RAM_MEMC_INI_ID));
+   maptab_ram.srcid_map(IntTab(cluster_iob0, XPIC_LOCAL_SRCID),
+         IntTab(cluster_iob0, RAM_IOBX_INI_ID));
+   maptab_ram.srcid_map(IntTab(cluster_iob0, RAM_MEMC_INI_ID),
+         IntTab(cluster_iob0, RAM_MEMC_INI_ID));
+
+   if (not is_mono_cluster) {
+      maptab_ram.srcid_map(IntTab(cluster_iob1, CDMA_LOCAL_SRCID),
+            IntTab(cluster_iob1, RAM_IOBX_INI_ID));
+      maptab_ram.srcid_map(IntTab(cluster_iob1, BDEV_LOCAL_SRCID),
+            IntTab(cluster_iob1, RAM_IOBX_INI_ID));
+      maptab_ram.srcid_map(IntTab(cluster_iob1, XPIC_LOCAL_SRCID),
+            IntTab(cluster_iob1, RAM_IOBX_INI_ID));
+      maptab_ram.srcid_map(IntTab(cluster_iob1, RAM_MEMC_INI_ID),
+            IntTab(cluster_iob1, RAM_MEMC_INI_ID));
+   }
 
    std::cout << "RAM network " << maptab_ram << std::endl;
@@ -575,97 +580,115 @@
    // - 8 targets (IOB0, IOB1, BDEV, CDMA, MTTY, FBUF, BROM, MNIC)
    ///////////////////////////////////////////////////////////////////////
+   
+   const size_t iox_addr_drop_bits = X_WIDTH + Y_WIDTH - 1;
+   const size_t iox_addr_decd_bits = 16 - X_WIDTH - Y_WIDTH + 1;
    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),
+         IntTab(iox_addr_drop_bits, iox_addr_decd_bits),
+         IntTab(X_WIDTH + Y_WIDTH , vci_param_ext::S - X_WIDTH - Y_WIDTH),
          0x00FF000000);
 
-   // compute base addresses for cluster_iob0 and cluster_iob1
+
+   // Each peripheral can be accessed through two segments,
+   // depending on the used IOB (IOB0 or 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);
-
-   // Each peripheral can be accessed through two segments,
-   // depending on the used IOB (IOB0 or IOB1).
+
    maptab_iox.add(Segment("iox_seg_mtty_0", XTTY_BASE + iob0_base, XTTY_SIZE,
-            IntTab(cluster_iob0, IOX_MTTY_TGT_ID), false));
-   maptab_iox.add(Segment("iox_seg_mtty_1", XTTY_BASE + iob1_base, XTTY_SIZE,
-            IntTab(cluster_iob1, IOX_MTTY_TGT_ID), false));
+            IntTab(0, 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_fbuf_1", FBUF_BASE + iob1_base, FBUF_SIZE,
-            IntTab(cluster_iob1, IOX_FBUF_TGT_ID), false));
+            IntTab(0, 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_bdev_1", BDEV_BASE + iob1_base, BDEV_SIZE,
-            IntTab(cluster_iob1, IOX_BDEV_TGT_ID), false));
+            IntTab(0, 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_mnic_1", MNIC_BASE + iob1_base, MNIC_SIZE,
-            IntTab(cluster_iob1, IOX_MNIC_TGT_ID), false));
+            IntTab(0, 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_cdma_1", CDMA_BASE + iob1_base, CDMA_SIZE,
-            IntTab(cluster_iob1, IOX_CDMA_TGT_ID), false));
-
-   // Each physical RAM can be accessed through IOB0, or through IOB1.
-   // if IOMMU is not activated, addresses are 40 bits (physical addresses),
-   // and the choice depends on on address bit A[39].
-   // if IOMMU is activated the addresses use only 32 bits (virtual
-   // addresses), and the choice depends on address bit A[31].
+            IntTab(0, IOX_CDMA_TGT_ID), false));
+   maptab_iox.add(Segment("iox_seg_xpic_0", XPIC_BASE + iob0_base, XPIC_SIZE,
+            IntTab(0, IOX_XPIC_TGT_ID), false));
+
+   if (not is_mono_cluster) {
+      uint64_t iob1_base = ((uint64_t)cluster_iob1)
+         << (vci_address_width - X_WIDTH - Y_WIDTH);
+
+      maptab_iox.add(Segment("iox_seg_mtty_1", XTTY_BASE + iob1_base,
+               XTTY_SIZE, IntTab(0, IOX_MTTY_TGT_ID), false));
+      maptab_iox.add(Segment("iox_seg_fbuf_1", FBUF_BASE + iob1_base,
+               FBUF_SIZE, IntTab(0, IOX_FBUF_TGT_ID), false));
+      maptab_iox.add(Segment("iox_seg_bdev_1", BDEV_BASE + iob1_base,
+               BDEV_SIZE, IntTab(0, IOX_BDEV_TGT_ID), false));
+      maptab_iox.add(Segment("iox_seg_mnic_1", MNIC_BASE + iob1_base,
+               MNIC_SIZE, IntTab(0, IOX_MNIC_TGT_ID), false));
+      maptab_iox.add(Segment("iox_seg_cdma_1", CDMA_BASE + iob1_base,
+               CDMA_SIZE, IntTab(0, IOX_CDMA_TGT_ID), false));
+      maptab_iox.add(Segment("iox_seg_xpic_1", XPIC_BASE + iob1_base,
+               XPIC_SIZE, IntTab(0, IOX_XPIC_TGT_ID), false));
+   }
+
+   ///////////////////////////////////////////////////////////////////////////
+   // - For external DMA peripherals, each physical RAM and replicated
+   //   XICU can be accessed through IOB0, or through IOB1 depending on address
+   //   bit A[32] (0 => IOB0, 1 => IOB1).
+   //
+   // NOTE: the special attribute in the XICU segments is used by the IOB to
+   //       route commands through the INT network. The commands on not special
+   //       segments (RAM) are routed by the IOB through the RAM network
+   //
+   // NOTE: The IOX interconnect is implemented as a local interconnect because
+   //       the global bits need to be dropped, but no locality check is
+   //       performed
+   ///////////////////////////////////////////////////////////////////////////
+
    for (size_t x = 0; x < x_size; x++) {
       for (size_t y = 0; y < y_size ; y++) {
-         uint64_t offset = static_cast<uint64_t>(cluster(x,y))
+         const bool special   = true;
+         const bool cacheable = true;
+
+         const uint64_t offset = static_cast<uint64_t>(cluster(x,y))
             << (vci_address_width - X_WIDTH - Y_WIDTH);
 
-         // send command to XRAM through IOB0
-         if ( x < (x_size/2) ) {
-            std::ostringstream siob0;
-            siob0 << "iox_seg_xram_" << x << "_" << y;
-            maptab_iox.add(Segment(siob0.str(),
-                     XRAM_BASE + offset, XRAM_SIZE,
-                     IntTab(cluster_iob0,IOX_IOB0_TGT_ID),
-                     false));
-         }
-         // send command to XRAM through IOB1
-         else {
-            std::ostringstream siob1;
-            siob1 << "iox_seg_xram_" << x << "_" << y;
-            maptab_iox.add(Segment(siob1.str(),
-                     XRAM_BASE + offset, XRAM_SIZE,
-                     IntTab(cluster_iob1,IOX_IOB1_TGT_ID),
-                     false));
+         const uint64_t xicu_base = XICU_BASE + offset;
+         if ( (y & 0x1) == 0 ) {
+            // segments mapped to IOB0
+            std::ostringstream sxcu0;
+            sxcu0 << "iox_seg_xcu0_" << x << "_" << y;
+            maptab_iox.add(Segment(sxcu0.str(), xicu_base, XICU_SIZE,
+                           IntTab(0, IOX_IOB0_TGT_ID), not cacheable, special));
+
+            std::ostringstream sram0;
+            sram0 << "iox_seg_ram0_" << x << "_" << y;
+            maptab_iox.add(Segment(sram0.str(), offset, XICU_BASE,
+                           IntTab(0, IOX_IOB0_TGT_ID), not cacheable, not special));
+         } else {
+            // segments mapped to IOB1
+            std::ostringstream sxcu1;
+            sxcu1 << "iox_seg_xcu1_" << x << "_" << y;
+            maptab_iox.add(Segment(sxcu1.str(), xicu_base | (1ULL<<32), XICU_SIZE,
+                           IntTab(0, IOX_IOB1_TGT_ID), not cacheable, special));
+
+            std::ostringstream sram1;
+            sram1 << "iox_seg_ram1_" << x << "_" << y;
+            maptab_iox.add(Segment(sram1.str(), offset | (1ULL<<32), XICU_BASE,
+                           IntTab(0, IOX_IOB1_TGT_ID), not cacheable, not special));
          }
       }
    }
-   // useful when IOMMU activated
-   //maptab_iox.add(Segment("iox_seg_xram", 0xc0000000, 0x40000000,
-   //                       IntTab(cluster_iob1,IOX_IOB1_TGT_ID), false));
 
    // This define the mapping between the initiators (identified by the SRCID)
    // and the port index on the IOX local interconnect.
-   // External initiator 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_iob1, CDMA_LOCAL_SRCID),
-         IntTab(cluster_iob1, 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_iob1, BDEV_LOCAL_SRCID),
-         IntTab(cluster_iob0, IOX_BDEV_INI_ID));
-
-   for (size_t x = 0; x < x_size; x++) {
-      for (size_t y = 0; y < y_size ; y++) {
-         size_t iob = (x < (x_size / 2)) ? IOX_IOB0_INI_ID : IOX_IOB1_INI_ID;
-
-         for (size_t p = 0 ; p < NB_PROCS ; p++) {
-            maptab_iox.srcid_map(IntTab(cluster(x,y), PROC_LOCAL_SRCID + p),
-                  IntTab(cluster(x,y), iob));
-         }
-         maptab_iox.srcid_map(IntTab( cluster(x,y), MDMA_LOCAL_SRCID),
-               IntTab( cluster(x,y), IOX_IOB0_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, XPIC_LOCAL_SRCID),
+                        IntTab(0, IOX_XPIC_INI_ID));
+   maptab_iox.srcid_map(IntTab(0, IOX_IOB0_INI_ID),
+                        IntTab(0, IOX_IOB0_INI_ID));
+
+   if (not is_mono_cluster) {
+      maptab_iox.srcid_map(IntTab(0, IOX_IOB1_INI_ID),
+                           IntTab(0, IOX_IOB1_INI_ID));
    }
 
@@ -697,4 +720,5 @@
    VciSignals<vci_param_ext> signal_vci_ini_bdev("signal_vci_ini_bdev");
    VciSignals<vci_param_ext> signal_vci_ini_cdma("signal_vci_ini_cdma");
+   VciSignals<vci_param_ext> signal_vci_ini_xpic("signal_vci_ini_xpic");
 
    VciSignals<vci_param_ext> signal_vci_tgt_iob0("signal_vci_tgt_iob0");
@@ -705,4 +729,5 @@
    VciSignals<vci_param_ext> signal_vci_tgt_bdev("signal_vci_tgt_bdev");
    VciSignals<vci_param_ext> signal_vci_tgt_cdma("signal_vci_tgt_cdma");
+   VciSignals<vci_param_ext> signal_vci_tgt_xpic("signal_vci_tgt_xpic");
 
    // Horizontal inter-clusters INT network DSPIN
@@ -807,10 +832,13 @@
       << std::endl;
 
+   const size_t nb_iox_initiators = (not is_mono_cluster) ? 5 : 4;
+   const size_t nb_iox_targets = (not is_mono_cluster) ? 8 : 7;
+
    // IOX network
    VciIoxNetwork<vci_param_ext>* iox_network;
    iox_network = new VciIoxNetwork<vci_param_ext>("iox_network",
          maptab_iox,
-         7,   // number of targets
-         4 ); // number of initiators
+         nb_iox_targets,      // number of targets
+         nb_iox_initiators ); // number of initiators
 
    // Network Controller
@@ -853,5 +881,6 @@
          IntTab(0, IOX_CDMA_TGT_ID),
          64,  // burst size (bytes)
-         2 * NB_NIC_CHANNELS);
+         NB_CMA_CHANNELS);
+
    // Multi-TTY controller
    std::vector<std::string> vect_names;
@@ -868,4 +897,13 @@
          vect_names);
 
+   // IOPIC
+   VciIopic<vci_param_ext>* xpic;
+   xpic = new VciIopic<vci_param_ext>( "xpic",
+                                       maptab_iox,
+                                       IntTab(0, XPIC_LOCAL_SRCID),
+                                       IntTab(0, IOX_XPIC_TGT_ID),
+                                       32 );        // number of input HWI
+
+
    TsarIobClusterType* clusters[x_size][y_size];
 
@@ -891,8 +929,15 @@
             sc << "cluster_" << x << "_" << y;
 
-            bool memc_debug =
-               debug_ok && (cluster(x,y) == debug_memc_id);
-            bool proc_debug = 
-               debug_ok && (cluster(x,y) == (debug_proc_id / NB_PROCS));
+            bool memc_debug = (cluster(x,y) == debug_memc_id);
+            bool proc_debug = (cluster(x,y) == (debug_proc_id / NB_PROCS));
+
+            bool is_io0 = (cluster(x,y) == cluster_iob0);
+            bool is_io1 = (cluster(x,y) == cluster_iob1);
+            bool is_io = is_io0 || is_io1;
+
+            IntTab iox_iob_tgtid =
+               IntTab(0, is_io0 ? IOX_IOB0_TGT_ID : IOX_IOB1_TGT_ID);
+            IntTab iox_iob_srcid =
+               IntTab(0, is_io0 ? IOX_IOB0_INI_ID : IOX_IOB1_INI_ID);
 
             TsarIobClusterType::ClusterParams params = {
@@ -905,4 +950,8 @@
                .mt_ext            = maptab_ram,
                .mt_iox            = maptab_iox,
+
+               .is_io             = is_io,
+               .iox_iob_tgtid     = iox_iob_tgtid,
+               .iox_iob_srcid     = iox_iob_srcid,
 
                .memc_ways         = MEMC_WAYS,
@@ -916,9 +965,11 @@
                .loader            = loader,
 
+               .distboot          = distboot,
+
                .frozen_cycles     = frozen_cycles,
                .debug_start_cycle = debug_from,
-               .memc_debug_ok     = memc_debug, 
-               .proc_debug_ok     = proc_debug, 
-               .iob_debug_ok      = debug_ok and debug_iob
+               .memc_debug_ok     = memc_debug,
+               .proc_debug_ok     = proc_debug,
+               .iob_debug_ok      = debug_iob
             };
 
@@ -942,10 +993,8 @@
    iox_network->p_clk                     (signal_clk);
    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);
-   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_ini[IOX_XPIC_INI_ID] (signal_vci_ini_xpic);
+   iox_network->p_to_ini[IOX_IOB0_INI_ID] (signal_vci_ini_iob0);
    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);
@@ -953,13 +1002,16 @@
    iox_network->p_to_tgt[IOX_BDEV_TGT_ID] (signal_vci_tgt_bdev);
    iox_network->p_to_tgt[IOX_CDMA_TGT_ID] (signal_vci_tgt_cdma);
+   iox_network->p_to_tgt[IOX_XPIC_TGT_ID] (signal_vci_tgt_xpic);
+   iox_network->p_to_tgt[IOX_IOB0_TGT_ID] (signal_vci_tgt_iob0);
+
+   if (not is_mono_cluster) {
+      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_resetn (signal_resetn);
-   bdev->p_irq    (signal_irq_bdev);
-
-   // For AHCI
-   // bdev->p_channel_irq[0]                             (signal_irq_bdev);
-
+   bdev->p_clk           (signal_clk);
+   bdev->p_resetn        (signal_resetn);
+   bdev->p_irq           (signal_irq_bdev);
    bdev->p_vci_target    (signal_vci_tgt_bdev);
    bdev->p_vci_initiator (signal_vci_ini_bdev);
@@ -1001,5 +1053,5 @@
    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++) {
+   for ( size_t i=0 ; i<NB_CMA_CHANNELS ; i++) {
       cdma->p_irq[i]    (signal_irq_cdma[i]);
    }
@@ -1007,21 +1059,23 @@
    std::cout << "  - CDMA connected" << std::endl;
 
-   // IRQ connexions from external peripherals (cluster_iob0 only)
-   // IRQ_MNIC_RX  -> IRQ[08] to IRQ[09]
-   // IRQ_MNIC_TX  -> IRQ[10] to IRQ[11]
-   // IRQ_CDMA     -> IRQ[12] to IRQ[15]
-   // IRQ_MTTY     -> IRQ[16] to IRQ[30]
-   // IRQ_BDEV     -> IRQ[31]
-
-   size_t mx = 16 + NB_TTY_CHANNELS;
-   for ( size_t n=0 ; n<32 ; n++ ) {
-      if      ( n < 8  ) (*clusters[0][0]->p_irq[n]) (signal_irq_false);
-      else if ( n < 10 ) (*clusters[0][0]->p_irq[n]) (signal_irq_false);
-      else if ( n < 12 ) (*clusters[0][0]->p_irq[n]) (signal_irq_false);
-      else if ( n < 16 ) (*clusters[0][0]->p_irq[n]) (signal_irq_false);
-      else if ( n < mx ) (*clusters[0][0]->p_irq[n]) (signal_irq_mtty[n-16]);
-      else if ( n < 31 ) (*clusters[0][0]->p_irq[n]) (signal_irq_false);
-      else               (*clusters[0][0]->p_irq[n]) (signal_irq_bdev);
-   }
+   // XPIC connexion
+   xpic->p_clk           (signal_clk);
+   xpic->p_resetn        (signal_resetn);
+   xpic->p_vci_target    (signal_vci_tgt_xpic);
+   xpic->p_vci_initiator (signal_vci_ini_xpic);
+   for ( size_t i=0 ; i<32 ; i++)
+   {
+      if      (i < NB_NIC_CHANNELS)   xpic->p_hwi[i] (signal_irq_mnic_rx[i]);
+      else if (i < 2)                 xpic->p_hwi[i] (signal_irq_false);
+      else if (i < 2+NB_NIC_CHANNELS) xpic->p_hwi[i] (signal_irq_mnic_tx[i-2]);
+      else if (i < 4)                 xpic->p_hwi[i] (signal_irq_false);
+      else if (i < 4+NB_CMA_CHANNELS) xpic->p_hwi[i] (signal_irq_cdma[i-4]);
+      else if (i < 8)                 xpic->p_hwi[i] (signal_irq_false);
+      else if (i < 9)                 xpic->p_hwi[i] (signal_irq_bdev);
+      else if (i < 9+NB_TTY_CHANNELS) xpic->p_hwi[i] (signal_irq_mtty[i-9]);
+      else                            xpic->p_hwi[i] (signal_irq_false);
+   }
+
+   std::cout << "  - XPIC connected" << std::endl;
 
    // IOB0 cluster connexion to IOX network
@@ -1030,6 +1084,8 @@
 
    // IOB1 cluster connexion to IOX network
-   (*clusters[x_size-1][y_size-1]->p_vci_iob_iox_ini) (signal_vci_ini_iob1);
-   (*clusters[x_size-1][y_size-1]->p_vci_iob_iox_tgt) (signal_vci_tgt_iob1);
+   if (not is_mono_cluster) {
+      (*clusters[x_size-1][y_size-1]->p_vci_iob_iox_ini) (signal_vci_ini_iob1);
+      (*clusters[x_size-1][y_size-1]->p_vci_iob_iox_tgt) (signal_vci_tgt_iob1);
+   }
 
    // All clusters Clock & RESET connexions
@@ -1145,4 +1201,5 @@
    // East & West boundary cluster connections
    for (size_t y = 0; y < y_size; y++) {
+      // L1-L2 cmd network boundary connections
       for (size_t k = 0; k < 3; k++) {
          clusters[0][y]->p_dspin_int_cmd_in[WEST][k](
@@ -1156,4 +1213,5 @@
       }
 
+      // L1-L2 rsp network boundary connections
       for (size_t k = 0; k < 2; k++) {
          clusters[0][y]->p_dspin_int_rsp_in[WEST][k](
@@ -1167,57 +1225,23 @@
       }
 
-      // handling IOB to RAM network connection in cluster_iob0
-      if( y == 0 ) {
-         (*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]);
-      }
-
-      // handling IOB to RAM network connection in cluster_iob1
-      if( y == y_size-1 ) {
-         (*clusters[x_size-1][y_size-1]->p_dspin_iob_cmd_out)(
-               signal_dspin_cmd_iob1_loopback);
-         clusters[x_size-1][y_size-1]->p_dspin_ram_cmd_in[EAST](
-               signal_dspin_cmd_iob1_loopback);
-
-         clusters[x_size-1][y_size-1]->p_dspin_ram_cmd_out[EAST](
-               signal_dspin_false_ram_cmd_out[x_size-1][y_size-1][EAST]);
-         clusters[x_size-1][y_size-1]->p_dspin_ram_rsp_in[EAST](
-               signal_dspin_false_ram_rsp_in[x_size-1][y_size-1][EAST]);
-
-         clusters[x_size-1][y_size-1]->p_dspin_ram_rsp_out[EAST](
-               signal_dspin_rsp_iob1_loopback);
-         (*clusters[x_size-1][y_size-1]->p_dspin_iob_rsp_in)(
-               signal_dspin_rsp_iob1_loopback);
-      }
-      else {
-         clusters[x_size-1][y]->p_dspin_ram_cmd_in[EAST](
-               signal_dspin_false_ram_cmd_in[x_size-1][y][EAST]);
-         clusters[x_size-1][y]->p_dspin_ram_cmd_out[EAST](
-               signal_dspin_false_ram_cmd_out[x_size-1][y][EAST]);
-         clusters[x_size-1][y]->p_dspin_ram_rsp_in[EAST](
-               signal_dspin_false_ram_rsp_in[x_size-1][y][EAST]);
-         clusters[x_size-1][y]->p_dspin_ram_rsp_out[EAST](
-               signal_dspin_false_ram_rsp_out[x_size-1][y][EAST]);
-      }
+      // L2-XRAM cmd network boundary connections
+      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[x_size-1][y]->p_dspin_ram_cmd_in[EAST](
+            signal_dspin_false_ram_cmd_in[x_size-1][y][EAST]);
+      clusters[x_size-1][y]->p_dspin_ram_cmd_out[EAST](
+            signal_dspin_false_ram_cmd_out[x_size-1][y][EAST]);
+
+      // L2-XRAM rsp network boundary connections
+      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[x_size-1][y]->p_dspin_ram_rsp_in[EAST](
+            signal_dspin_false_ram_rsp_in[x_size-1][y][EAST]);
+      clusters[x_size-1][y]->p_dspin_ram_rsp_out[EAST](
+            signal_dspin_false_ram_rsp_out[x_size-1][y][EAST]);
    }
 
@@ -1277,5 +1301,4 @@
 
    signal_resetn = false;
-
    signal_irq_false = false;
 
@@ -1368,25 +1391,31 @@
          }
 
+         // trace RAM xbar (between MEMC and IOB)
+         // clusters[0][0]->ram_xbar_cmd->print_trace();
+         // clusters[0][0]->ram_xbar_rsp->print_trace();
+         // clusters[x_size-1][y_size-1]->ram_xbar_cmd->print_trace();
+         // clusters[x_size-1][y_size-1]->ram_xbar_rsp->print_trace();
+
          // trace INT network
-         //          clusters[0][0]->int_xbar_d->print_trace();
-
-         //          clusters[0][0]->signal_int_dspin_cmd_l2g_d.print_trace(
-         //             "[SIG] INT_CMD_L2G_D_0_0");
-         //          clusters[0][0]->signal_int_dspin_rsp_g2l_d.print_trace(
-         //             "[SIG] INT_RSP_G2L_D_0_0");
-
-         //          clusters[0][0]->int_router_cmd->print_trace(0);
-         //          clusters[0][0]->int_router_rsp->print_trace(0);
+         // clusters[0][0]->int_xbar_d->print_trace();
+
+         // clusters[0][0]->signal_int_dspin_cmd_l2g_d.print_trace(
+         //    "[SIG] INT_CMD_L2G_D_0_0");
+         // clusters[0][0]->signal_int_dspin_rsp_g2l_d.print_trace(
+         //    "[SIG] INT_RSP_G2L_D_0_0");
+
+         // clusters[0][0]->int_router_cmd->print_trace(0);
+         // clusters[0][0]->int_router_rsp->print_trace(0);
 
          // trace INT_CMD_D xbar and router in cluster 0_1
-         //          clusters[0][1]->int_router_cmd->print_trace(0);
-         //          clusters[0][1]->int_router_rsp->print_trace(0);
-
-         //          clusters[0][1]->signal_int_dspin_cmd_g2l_d.print_trace(
-         //             "[SIG] INT_CMD_G2L_D_0_0");
-         //          clusters[0][1]->signal_int_dspin_rsp_l2g_d.print_trace(
-         //             "[SIG] INT_RSP_L2G_D_0_0");
-
-         //          clusters[0][1]->int_xbar_cmd_d->print_trace();
+         // clusters[0][1]->int_router_cmd->print_trace(0);
+         // clusters[0][1]->int_router_rsp->print_trace(0);
+
+         // clusters[0][1]->signal_int_dspin_cmd_g2l_d.print_trace(
+         //    "[SIG] INT_CMD_G2L_D_0_0");
+         // clusters[0][1]->signal_int_dspin_rsp_l2g_d.print_trace(
+         //    "[SIG] INT_RSP_L2G_D_0_0");
+
+         // clusters[0][1]->int_xbar_cmd_d->print_trace();
 
          // trace memc[debug_memc_id]
@@ -1412,26 +1441,26 @@
 
          // 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");
-
-            signal_vci_ini_iob0.print_trace("[SIG]IOB0_IOX_INI");
-            signal_vci_tgt_iob0.print_trace("[SIG]IOB0_IOX_TGT");
-
-            cdma->print_trace();
-            signal_vci_tgt_cdma.print_trace("[SIG]IOX_CDMA_TGT");
-            signal_vci_ini_cdma.print_trace("[SIG]IOX_CDMA_INI");
-
-            iox_network->print_trace();
-
-            // interrupts
-            if (signal_irq_bdev) std::cout << "### IRQ_BDEV ACTIVATED"
-               << std::endl;
-         }
+         //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");
+
+         //   signal_vci_ini_iob0.print_trace("[SIG]IOB0_IOX_INI");
+         //   signal_vci_tgt_iob0.print_trace("[SIG]IOB0_IOX_TGT");
+
+         //   cdma->print_trace();
+         //   signal_vci_tgt_cdma.print_trace("[SIG]IOX_CDMA_TGT");
+         //   signal_vci_ini_cdma.print_trace("[SIG]IOX_CDMA_INI");
+
+         //   iox_network->print_trace();
+
+         //   // interrupts
+         //   if (signal_irq_bdev) std::cout << "### IRQ_BDEV ACTIVATED"
+         //      << std::endl;
+         //}
       }
       sc_start(sc_core::sc_time(1, SC_NS));
@@ -1444,4 +1473,5 @@
    delete cdma;
    delete mtty;
+   delete xpic;
 
    for(size_t x = 0; x < x_size; x++) {
Index: /branches/fault_tolerance/platform/tsar_generic_iob/top.desc
===================================================================
--- /branches/fault_tolerance/platform/tsar_generic_iob/top.desc	(revision 716)
+++ /branches/fault_tolerance/platform/tsar_generic_iob/top.desc	(revision 717)
@@ -2,5 +2,5 @@
 # -*- python -*-
 
-# VCI parameters 
+# VCI parameters
 vci_cell_size_int   = 4
 vci_cell_size_ext   = 8
@@ -16,5 +16,5 @@
 vci_wrplen_size     = 1
 
-# internal DSPIN network parameters 
+# internal DSPIN network parameters
 int_dspin_cmd_flit_size = 39
 int_dspin_rsp_flit_size = 32
@@ -27,34 +27,38 @@
     uses = [
             # cluster
-            Uses('caba:tsar_iob_cluster', 
+            Uses('caba:tsar_iob_cluster',
                   vci_data_width_int  = vci_cell_size_int,
-                  vci_data_width_ext  = vci_cell_size_ext, 
+                  vci_data_width_ext  = vci_cell_size_ext,
                   dspin_int_cmd_width = int_dspin_cmd_flit_size,
                   dspin_int_rsp_width = int_dspin_rsp_flit_size,
                   dspin_ram_cmd_width = ram_dspin_cmd_flit_size,
                   dspin_ram_rsp_width = ram_dspin_rsp_flit_size),
-                  
+
             # IOX Network
-            Uses('caba:vci_iox_network', 
+            Uses('caba:vci_iox_network',
                   cell_size = vci_cell_size_ext),
 
             # Frame Buffer
-            Uses('caba:vci_framebuffer', 
+            Uses('caba:vci_framebuffer',
                   cell_size = vci_cell_size_ext),
 
             # Block Device
-            Uses('caba:vci_block_device_tsar', 
+            Uses('caba:vci_block_device_tsar',
                   cell_size = vci_cell_size_ext),
 
-            # NIC 
-            Uses('caba:vci_multi_nic', 
+            # NIC
+            Uses('caba:vci_multi_nic',
                   cell_size = vci_cell_size_ext),
 
             # Chained DMA
-            Uses('caba:vci_chbuf_dma', 
+            Uses('caba:vci_chbuf_dma',
                   cell_size = vci_cell_size_ext),
 
             # TTY
-            Uses('caba:vci_multi_tty', 
+            Uses('caba:vci_multi_tty',
+                  cell_size = vci_cell_size_ext),
+
+            # PIC
+            Uses('caba:vci_iopic',
                   cell_size = vci_cell_size_ext),
 
@@ -64,5 +68,5 @@
 
     # default VCI parameters (global variables)
-    cell_size   = vci_cell_size_int,  
+    cell_size   = vci_cell_size_int,
     plen_size   = vci_plen_size,
     addr_size   = vci_addr_size,
Index: /branches/fault_tolerance/platform/tsar_generic_iob/tsar_iob_cluster/caba/metadata/tsar_iob_cluster.sd
===================================================================
--- /branches/fault_tolerance/platform/tsar_generic_iob/tsar_iob_cluster/caba/metadata/tsar_iob_cluster.sd	(revision 716)
+++ /branches/fault_tolerance/platform/tsar_generic_iob/tsar_iob_cluster/caba/metadata/tsar_iob_cluster.sd	(revision 717)
@@ -66,4 +66,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'),
@@ -93,8 +99,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: /branches/fault_tolerance/platform/tsar_generic_iob/tsar_iob_cluster/caba/source/include/tsar_iob_cluster.h
===================================================================
--- /branches/fault_tolerance/platform/tsar_generic_iob/tsar_iob_cluster/caba/source/include/tsar_iob_cluster.h	(revision 716)
+++ /branches/fault_tolerance/platform/tsar_generic_iob/tsar_iob_cluster/caba/source/include/tsar_iob_cluster.h	(revision 717)
@@ -27,5 +27,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"
@@ -89,12 +89,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 ports are used to connect hard IRQ from external peripherals to
-      // IOB0
-      sc_in<bool>* p_irq[32];
-
       // These arrays of ports are used to connect the INT & RAM networks in
       // top cell
@@ -111,7 +103,7 @@
       // interrupt signals
       sc_signal<bool> signal_false;
-      sc_signal<bool> signal_proc_it[8];
-      sc_signal<bool> signal_irq_mdma[8];
-      sc_signal<bool> signal_irq_mtty[8];
+      sc_signal<bool> signal_proc_it[NB_PROCS*IRQ_PER_PROCESSOR];
+      sc_signal<bool> signal_irq_mdma[NB_DMA_CHANNELS];
+      sc_signal<bool> signal_irq_mtty[NB_DEBUG_TTY_CHANNELS];
       sc_signal<bool> signal_irq_memc;
 
@@ -130,5 +122,5 @@
 
       // INT network VCI signals between VCI components and VCI local crossbar
-      VciSignals<vci_param_int> signal_int_vci_ini_proc[8];
+      VciSignals<vci_param_int> signal_int_vci_ini_proc[NB_PROCS];
       VciSignals<vci_param_int> signal_int_vci_ini_mdma;
       VciSignals<vci_param_int> signal_int_vci_ini_iobx;
@@ -149,7 +141,7 @@
       DspinSignals<dspin_int_cmd_width> signal_int_dspin_clack_memc;
       DspinSignals<dspin_int_rsp_width> signal_int_dspin_p2m_memc;
-      DspinSignals<dspin_int_cmd_width> signal_int_dspin_m2p_proc[8];
-      DspinSignals<dspin_int_cmd_width> signal_int_dspin_clack_proc[8];
-      DspinSignals<dspin_int_rsp_width> signal_int_dspin_p2m_proc[8];
+      DspinSignals<dspin_int_cmd_width> signal_int_dspin_m2p_proc[NB_PROCS];
+      DspinSignals<dspin_int_cmd_width> signal_int_dspin_clack_proc[NB_PROCS];
+      DspinSignals<dspin_int_rsp_width> signal_int_dspin_p2m_proc[NB_PROCS];
 
       // RAM network VCI signals between VCI components and VCI/DSPIN wrappers
@@ -161,6 +153,17 @@
       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;
+
 
       //////////////////////////////////////
@@ -213,6 +216,9 @@
       VciExtDspinTargetWrapperType* 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)
@@ -232,4 +238,8 @@
          const soclib::common::MappingTable &mt_ext;
          const soclib::common::MappingTable &mt_iox;
+
+         const bool is_io;
+         const soclib::common::IntTab iox_iob_tgtid;
+         const soclib::common::IntTab iox_iob_srcid;
 
          size_t memc_ways;
@@ -243,4 +253,6 @@
          const Loader& loader;
 
+         bool distboot;
+
          uint32_t frozen_cycles;
          uint32_t debug_start_cycle;
@@ -255,4 +267,9 @@
       };
 
+
+      SC_HAS_PROCESS(TsarIobCluster);
+
+      void init();
+
       // cluster constructor
       TsarIobCluster(struct ClusterParams& params);
Index: /branches/fault_tolerance/platform/tsar_generic_iob/tsar_iob_cluster/caba/source/src/tsar_iob_cluster.cpp
===================================================================
--- /branches/fault_tolerance/platform/tsar_generic_iob/tsar_iob_cluster/caba/source/src/tsar_iob_cluster.cpp	(revision 716)
+++ /branches/fault_tolerance/platform/tsar_generic_iob/tsar_iob_cluster/caba/source/src/tsar_iob_cluster.cpp	(revision 717)
@@ -9,7 +9,7 @@
 // Modified on: mars 2014
 //////////////////////////////////////////////////////////////////////////////
-// Cluster(0,0) & Cluster(xmax-1,ymax-1) contains the IOB0 & IOB1 components.
-// These two clusters contain 6 extra components:
-// - 1 vci_io_bridge (connected to the 3 networks.
+// IO clusters contains the IOB component.
+// These clusters contain 6 extra components:
+// - 1 vci_io_bridge (connected to the 3 networks).
 // - 3 vci_dspin_wrapper for the IOB.
 // - 2 dspin_local_crossbar for commands and responses. 
@@ -39,11 +39,5 @@
    assert((params.x_id < X_MAX) && (params.y_id < Y_MAX));
 
-   size_t cid           = this->clusterId(params.x_id, params.y_id);
-   size_t cluster_iob0  = this->clusterId(0, 0);
-   size_t cluster_iob1  = this->clusterId(X_SIZE - 1, Y_SIZE - 1);
-   size_t is_iob0       = (cid == cluster_iob0);
-   size_t is_iob1       = (cid == cluster_iob1);
-   bool   is_io_cluster = is_iob0 || is_iob1;
-
+   size_t cid     = this->clusterId(params.x_id, params.y_id);
    size_t l_width = vci_param_int::S - X_WIDTH - Y_WIDTH;
 
@@ -67,22 +61,13 @@
       alloc_elems<DspinOutput<dspin_ram_rsp_width> >("p_ext_rsp_out", 4);
 
-   // ports in cluster_iob0 and cluster_iob1 only
+   // ports in IO clusters only
    p_vci_iob_iox_ini   = NULL;
    p_vci_iob_iox_tgt   = NULL;
-   p_dspin_iob_cmd_out = NULL;
-   p_dspin_iob_rsp_in  = NULL;
-   if ( is_io_cluster ) {
+   if ( params.is_io ) {
+      std::cout << "   Creating signals for IOB" << std::endl;
+
       // VCI ports from IOB to IOX network
       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>;
-   }
-
-   // IRQ ports in cluster_iob0 only
-   for ( size_t n = 0 ; n < 32 ; n++ ) {
-      p_irq[n] = ( is_iob0 ) ? new sc_in<bool> : NULL;
    }
 
@@ -110,6 +95,10 @@
             params.debug_start_cycle, params.proc_debug_ok);
 
-      proc[p]->set_dcache_paddr_ext_reset(cid);
-      proc[p]->set_icache_paddr_ext_reset(cid);
+      // Physical address extention register is initialized with local cluster
+      // ID when distributed boot is activated.
+      if (params.distboot) {
+         proc[p]->set_dcache_paddr_ext_reset(cid);
+         proc[p]->set_icache_paddr_ext_reset(cid);
+      }
    }
 
@@ -149,5 +138,5 @@
 
    // Multi-TTY controller
-   mtty        = NULL;
+   mtty = NULL;
    if (NB_DEBUG_TTY_CHANNELS) {
       assert(NB_DEBUG_TTY_CHANNELS < 8);
@@ -175,6 +164,6 @@
          params.mt_int,
          IntTab(cid, INT_XICU_TGT_ID),
-         32, 32, 32,
-         NB_PROCS);
+         32, 1, 32,
+         NB_PROCS * IRQ_PER_PROCESSOR);
 
    ////////////  MDMA
@@ -195,5 +184,5 @@
       nb_direct_targets++;
    }
-   if ( is_io_cluster ) {
+   if ( params.is_io ) {
       nb_direct_initiators++;
       nb_direct_targets++;
@@ -306,40 +295,23 @@
    std::ostringstream s_ram_router_cmd;
    s_ram_router_cmd << "ram_router_cmd_" << params.x_id << "_" << params.y_id;
-   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(),
          params.x_id, params.y_id,
          X_WIDTH, Y_WIDTH,
-         4, 4,
-         is_iob0, is_iob1,
-         false,
-         l_width);
+         4, 4);
 
    std::ostringstream s_ram_router_rsp;
    s_ram_router_rsp << "ram_router_rsp_" << params.x_id << "_" << params.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(),
          params.x_id, params.y_id,
          X_WIDTH, Y_WIDTH,
-         4, 4,
-         is_iob0, is_iob1,
-         true,
-         l_width);
+         4, 4);
 
    ////////////////////// I/O  CLUSTER ONLY ///////////////////////
    iob        = NULL;
    iob_ram_wi = NULL;
-   if ( is_io_cluster ) {
+   if ( params.is_io ) {
       ///////////  IO_BRIDGE
-      size_t iox_local_id;
-      bool   has_irqs;
-      if ( is_iob0 ) {
-         iox_local_id = 0;
-         has_irqs     = true;
-      }
-      else {
-         iox_local_id = 1;
-         has_irqs     = false;
-      }
-
       std::ostringstream s_iob;
       s_iob << "iob_" << params.x_id << "_" << params.y_id;   
@@ -351,6 +323,6 @@
             IntTab(cid, INT_IOBX_TGT_ID),
             IntTab(cid, INT_IOBX_INI_ID),
-            IntTab(cid, iox_local_id ),
-            has_irqs,
+            params.iox_iob_tgtid,
+            params.iox_iob_srcid,
             16,
             8,
@@ -364,4 +336,30 @@
             s_iob_ram_wi.str().c_str(),
             vci_param_int::S);
+
+      std::ostringstream s_ram_xbar_cmd;
+      s_ram_xbar_cmd << "s_ram_xbar_cmd_" << params.x_id << "_" << params.y_id;
+      ram_xbar_cmd = new DspinLocalCrossbar<dspin_ram_cmd_width>(
+            s_ram_xbar_cmd.str().c_str(), // name
+            params.mt_ext,                // mapping table
+            params.x_id, params.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_" << params.x_id << "_" << params.y_id;
+      ram_xbar_rsp = new DspinLocalCrossbar<dspin_ram_rsp_width>(
+            s_ram_xbar_rsp.str().c_str(), // name
+            params.mt_ext,                // mapping table
+            params.x_id, params.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 ?
    }
 
@@ -372,7 +370,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
@@ -425,5 +420,5 @@
    }
 
-   if ( is_io_cluster ) {
+   if ( params.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);
@@ -480,7 +475,11 @@
       proc[p]->p_dspin_p2m    (signal_int_dspin_p2m_proc[p]);
       proc[p]->p_dspin_clack  (signal_int_dspin_clack_proc[p]);
-      proc[p]->p_irq[0]       (signal_proc_it[p]);
-      for ( size_t j = 1 ; j < 6 ; j++) {
-         proc[p]->p_irq[j]    (signal_false);
+      for ( size_t j = 0 ; j < 6 ; j++) {
+         if ( j < IRQ_PER_PROCESSOR ) {
+            proc[p]->p_irq[j] (signal_proc_it[IRQ_PER_PROCESSOR * p + j]);
+         }
+         else {
+            proc[p]->p_irq[j] (signal_false);
+         }
       }
    }
@@ -490,13 +489,8 @@
    xicu->p_resetn (this->p_resetn);
    xicu->p_vci    (signal_int_vci_tgt_xicu);
-   for ( size_t p = 0 ; p < NB_PROCS ; p++) {
-      xicu->p_irq[p] (signal_proc_it[p]);
-   }
-   for ( size_t i=0 ; i<32 ; i++) {
-      if ( is_iob0 ) 
-         xicu->p_hwi[i] (*(this->p_irq[i]));
-      else  
-         xicu->p_hwi[i] (signal_false);
-   }                     
+   for ( size_t irq = 0 ; irq < (IRQ_PER_PROCESSOR * NB_PROCS) ; irq++) {
+      xicu->p_irq[irq] (signal_proc_it[irq]);
+   }
+   xicu->p_hwi[0] (signal_irq_memc);
 
    ///////////////////////////////////// MEMC
@@ -564,11 +558,15 @@
       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);
-
-   ///////////////////////// IOB exists only in cluster_iob0 & cluster_iob1. 
-   if ( is_io_cluster ) {
+
+   ram_router_cmd->p_out[4] (signal_ram_dspin_cmd_xram_t);
+   if (params.is_io) ram_router_cmd->p_in[4] (signal_ram_dspin_cmd_xbar);
+   else              ram_router_cmd->p_in[4] (signal_ram_dspin_cmd_memc_i);
+
+   ram_router_rsp->p_in[4] (signal_ram_dspin_rsp_xram_t);
+   if (params.is_io) ram_router_rsp->p_out[4] (signal_ram_dspin_rsp_xbar);
+   else              ram_router_rsp->p_out[4] (signal_ram_dspin_rsp_memc_i);
+
+   ///////////////////////// IOB exists only in IO clusters. 
+   if ( params.is_io ) {
       // IO bridge
       iob->p_clk         (this->p_clk);
@@ -580,30 +578,41 @@
       iob->p_vci_ini_ram (signal_ram_vci_ini_iobx);
 
-      if ( is_iob0 ) {
-         for ( size_t n = 0 ; n < 32 ; n++ ) {
-            (*iob->p_irq[n]) (*(this->p_irq[n]));
-         }
-      }
-
       // 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);
+
+      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[0]  (signal_ram_dspin_cmd_memc_i);
+      ram_xbar_cmd->p_local_in[1]  (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[0] (signal_ram_dspin_rsp_memc_i);
+      ram_xbar_rsp->p_local_out[1] (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;
+}
 
 tmpl(/**/)::~TsarIobCluster() {
    if (p_vci_iob_iox_ini)   delete p_vci_iob_iox_ini;
    if (p_vci_iob_iox_tgt)   delete p_vci_iob_iox_tgt;
-   if (p_dspin_iob_cmd_out) delete p_dspin_iob_cmd_out;
-   if (p_dspin_iob_rsp_in)  delete p_dspin_iob_rsp_in;
    if (iob)                 delete iob;
    if (iob_ram_wi)          delete iob_ram_wi;
-
-   for (size_t n = 0 ; n < 32 ; n++) {
-      if (p_irq[n]) delete p_irq[n];
-   }
 
    for (size_t p = 0; p < NB_PROCS; p++) { 
@@ -627,4 +636,6 @@
    delete ram_router_cmd;
    delete ram_router_rsp;
+   delete ram_xbar_cmd;
+   delete ram_xbar_rsp;
 }
 
