Index: branches/fault_tolerance/platform/tsar_generic_iob/top.cpp
===================================================================
--- branches/fault_tolerance/platform/tsar_generic_iob/top.cpp	(revision 695)
+++ 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++) {
