Index: trunk/platforms/tsar_generic_leti/top.cpp
===================================================================
--- trunk/platforms/tsar_generic_leti/top.cpp	(revision 630)
+++ trunk/platforms/tsar_generic_leti/top.cpp	(revision 664)
@@ -1,4 +1,4 @@
 /////////////////////////////////////////////////////////////////////////
-// File: top.cpp 
+// File: top.cpp (for tsar_generic_leti)
 // Author: Alain Greiner 
 // Copyright: UPMC/LIP6
@@ -33,8 +33,8 @@
 //
 // Each processor receive 4 consecutive IRQ lines from the local XICU.
+//
 // In all clusters, the MEMC IRQ line (signaling a late write error)
 // is connected to XICU HWI[8]
-//
-// The cluster 0 contains two more peripherals:
+// The cluster (0,0) contains two "internal" peripherals:
 // - one block device controller, whose IRQ is connected to XICU HWI[9].
 // - one single channel TTY controller, whose IRQ is connected to XICU HWI[10].
@@ -43,5 +43,5 @@
 // that must be considered as an extension of this top.cpp file.
 //
-// Besides the hardware components contained in clusters, external peripherals 
+// Besides the hardware components in clusters, "external" peripherals 
 // are connected to an external IO bus (implemented as a vci_local_crossbar):
 // - one disk controller 
@@ -50,15 +50,17 @@
 // - one multi-channel tty controller 
 // - one frame buffer controller 
-// - one 16 channels iopic controller
+// - one 32 channels iopic controller
 //
 // This IOBUS is connected to the north  port of the DIR_CMD 
-// and DIR_RSP routers, in cluster(X_SIZE-1, Y_SIZE-1).
+// and DIR_RSP routers, in cluster(X_SIZE-1, Y_SIZE-2).
 // For all external peripherals, the hardware interrupts (HWI) are
-// translated to software interrupts (SWI) by the iopic component:
-// - IRQ_MNIC_RX[1:0]   connected to IOPIC HWI[1:0]
-// - IRQ_MNIC_TX[1:0]   connected to IOPIC HWI[3:2]
-// - IRQ_CDMA[3:0]      connected to IOPIC HWI[7:4]
-// - IRQ_BDEV           connected to IOPIC HWI[9] 
-// - IRQ_MTTY[3:0]      connected to IOPIC HWI[15:12]
+// translated to write interrupts (WTI) by the iopic component:
+// - IOPIC HWI[1:0]     connected to IRQ_NIC_RX[1:0]
+// - IOPIC HWI[3:2]     connected to IRQ_NIC_TX[1:0]      
+// - IOPIC HWI[7:4]     connected to IRQ_CMA_TX[3:0]]
+// - IOPIC HWI[8]       connected to IRQ_BDEV
+// - IOPIC HWI[15:9]    unused       (grounded)
+// - IOPIC HWI[23:16]   connected to IRQ_TTY_RX[7:0]]
+// - IOPIC HWI[31:24]   connected to IRQ_TTY_TX[7:0]]
 ////////////////////////////////////////////////////////////////////////////
 // The following parameters must be defined in the hard_config.h file :
@@ -68,8 +70,7 @@
 // - Y_SIZE           : number of clusters in a column 
 // - NB_PROCS_MAX     : number of processors per cluster (1, 2 or 4)
-// - NB_CMA_CHANNELS  : number of CMA channels in I/0 cluster (8 max)
-// - NB_TTY_CHANNELS  : number of TTY channels in I/O cluster (16 max)
+// - NB_CMA_CHANNELS  : number of CMA channels in I/0 cluster (4 max)
+// - NB_TTY_CHANNELS  : number of TTY channels in I/O cluster (8 max)
 // - NB_NIC_CHANNELS  : number of NIC channels in I/O cluster (2 max)
-// - USE_EXT_IO       : use external peripherals if non zero
 // 
 // Some other hardware parameters are not used when compiling the OS,
@@ -126,10 +127,14 @@
 #include "alloc_elems.h"
 
-///////////////////////////////////////////////////
-//      OS
-///////////////////////////////////////////////////
-
-#define USE_GIET_VM     0
-#define USE_GIET_TSAR   1
+//////////////////////////////////////////////////////////////////////////////////////////
+//    Parameters depending on the OS and software application         
+//    - path to hard_config file
+//    - path to binary code for the RAM loader
+//    - path to disk image for RAMDISK loader
+//    - path to disk image for IOC device
+//////////////////////////////////////////////////////////////////////////////////////////
+
+#define USE_GIET_VM     1
+#define USE_GIET_TSAR   0
 
 #if ( USE_GIET_VM and USE_GIET_TSAR )
@@ -139,4 +144,18 @@
 #if ( (not USE_GIET_VM) and (not USE_GIET_TSAR) )
 #error "You need to specify one OS"
+#endif
+
+#if USE_GIET_TSAR
+#include                         "../../softs/soft_transpose_giet/hard_config.h"
+#define BINARY_PATH_FOR_LOADER   "../../softs/soft_transpose_giet/bin.soft"
+#define RAMDISK_PATH_FOR_LOADER  "../../softs/soft_transpose_giet/images.raw@0x00800000:"
+#define DISK_IMAGE_PATH_FOR_IOC  "../../softs/soft_transpose_giet/images.raw"
+#endif
+
+#if USE_GIET_VM
+#include                         "../../../giet_vm/hard_config.h"
+#define BINARY_PATH_FOR_LOADER   "../../softs/tsar_boot/preloader.elf"
+#define RAMDISK_PATH_FOR_LOADER  "../../../giet_vm/hdd/virt_hdd.dmg@0x02000000:"
+#define DISK_IMAGE_PATH_FOR_IOC  "../../../giet_vm/hdd/virt_hdd.dmg"        
 #endif
 
@@ -181,17 +200,17 @@
 #define vci_wrplen_width      1
 
-////////////////////////////////////////////////////////////
-//    Main Hardware Parameters values         
-//////////////////////i/////////////////////////////////////
-
-#include "../../softs/soft_transpose_giet/hard_config.h"
-
-////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////////////////
 //    Secondary Hardware Parameters         
-//////////////////////i/////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
 
 #define RESET_ADDRESS         0x0
 
+#define MAX_TTY_CHANNELS      8
+#define MAX_CMA_CHANNELS      4
+#define MAX_NIC_CHANNELS      2
+
 #define XRAM_LATENCY          0
+#define XRAM_SIZE             0x04000000    // 64 Mbytes per cluster
 
 #define MEMC_WAYS             16
@@ -207,10 +226,8 @@
 #define FBUF_Y_SIZE           128
 
-#define BDEV_IMAGE_NAME       "../../softs/soft_transpose_giet/images.raw"
-
 #define NIC_MAC4              0XBABEF00D
 #define NIC_MAC2              0xBEEF
-#define NIC_RX_NAME           "../../softs/soft_hello_giet/fake"
-#define NIC_TX_NAME           "../../softs/soft_hello_giet/fake"
+#define NIC_RX_NAME           "./fake"
+#define NIC_TX_NAME           "./fake"
 
 #define NORTH                 0
@@ -219,47 +236,40 @@
 #define WEST                  3
 
-////////////////////////////////////////////////////////////
-//    Arguments for the SoCLib loader         
-//////////////////////i/////////////////////////////////////
-
-#define elf_loader           "../../softs/soft_transpose_giet/bin.soft"
-#define ramdisk_loader       "../../softs/soft_transpose_giet/images.raw@0x00800000:"
-
-////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////
 //     DEBUG Parameters default values         
-//////////////////////i/////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////
 
 #define MAX_FROZEN_CYCLES     10000
 
-////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////
 //     LOCAL TGTID & SRCID definition 
 // For all components:  global TGTID = global SRCID = cluster_index
-////////////////////////////////////////////////////////////////////
-
-#define MEMC_TGTID      0
-#define XICU_TGTID      1
-#define MTTY_TGTID      2
-#define BDEV_TGTID      3
-#define FBUF_TGTID      4
-#define MNIC_TGTID      5
-#define CDMA_TGTID      6
-#define IOPI_TGTID      7
-
-#define BDEV_SRCID      NB_PROCS_MAX
-#define CDMA_SRCID      NB_PROCS_MAX + 1
-#define IOPI_SRCID      NB_PROCS_MAX + 2
-
-/////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////
+
+#define MEMC_TGTID            0
+#define XICU_TGTID            1
+#define MTTY_TGTID            2
+#define BDEV_TGTID            3
+#define FBUF_TGTID            4
+#define MNIC_TGTID            5
+#define CDMA_TGTID            6
+#define IOPI_TGTID            7
+
+#define BDEV_SRCID            NB_PROCS_MAX
+#define CDMA_SRCID            NB_PROCS_MAX + 1
+#define IOPI_SRCID            NB_PROCS_MAX + 2
+
+//////////////////////////////////////////////////////////////////////////////////////
 //    Physical segments definition
-/////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////
 // - 3 segments are replicated in all clusters
 // - 2 segments are replicated in cluster[0,0] & [X_SIZE-1,Y_SIZE-1] 
-// - 4 segments are only in cluster [X_SIZE-1,Y_SIZE] 
+// - 4 segments are only in cluster [X_SIZE-1,Y_SIZE-1] 
 // The following values are for segments in cluster 0,
 // and these 32 bits values must be concatenate with the cluster 
 // index (on 8 bits) to obtain the 40 bits address.
-/////////////////////////////////////////////////////////////////////
-
-   // in cluster [0,0] & [X_SIZE-1,Y_SIZE] 
+//////////////////////////////////////////////////////////////////////////////////////
+
+   // in cluster [0,0] & [X_SIZE-1,Y_SIZE-1] 
 
    #define MTTY_BASE    0xF4000000
@@ -269,5 +279,5 @@
    #define BDEV_SIZE    0x00001000   // 4 Kbytes
 
-   // in cluster [X_SIZE-1,Y_SIZE]
+   // in cluster [X_SIZE-1,Y_SIZE-1]
 
    #define FBUF_BASE    0xF3000000
@@ -286,5 +296,5 @@
 
    #define MEMC_BASE    0x00000000
-   #define MEMC_SIZE    0x01000000   // 16 Mbytes per cluster
+   #define MEMC_SIZE    XRAM_SIZE
 
    #define MCFG_BASE    0xE0000000
@@ -336,5 +346,5 @@
             size_t y = trace_memc_id & ((1<<Y_WIDTH)-1);
 
-            assert( (x <= X_SIZE) and (y <= Y_SIZE) &&
+            assert( (x < X_SIZE) and (y < (Y_SIZE-1)) and
                   "MEMCID parameter refers a not valid memory cache");
          }
@@ -346,6 +356,7 @@
             size_t x          = cluster_xy >> Y_WIDTH;
             size_t y          = cluster_xy & ((1<<Y_WIDTH)-1);
-
-            assert( (x <= X_SIZE) and (y <= Y_SIZE) &&
+            size_t l          = trace_proc_id % NB_PROCS_MAX ;
+
+            assert( (x < X_SIZE) and (y < (Y_SIZE-1)) and l < NB_PROCS_MAX and
                   "PROCID parameter refers a not valid processor");
          }
@@ -383,14 +394,14 @@
             "The Y_SIZE parameter cannot be larger than 16" );
 
-    assert( (NB_PROCS_MAX <= 8) and
+    assert( (NB_PROCS_MAX <= 4) and
             "The NB_PROCS_MAX parameter cannot be larger than 4" );
 
-    assert( (NB_CMA_CHANNELS <= 4) and
+    assert( (NB_CMA_CHANNELS <= MAX_CMA_CHANNELS) and
             "The NB_CMA_CHANNELS parameter cannot be larger than 4" );
 
-    assert( (NB_TTY_CHANNELS <= 4) and
-            "The NB_TTY_CHANNELS parameter cannot be larger than 4" );
-
-    assert( (NB_NIC_CHANNELS <= 2) and
+    assert( (NB_TTY_CHANNELS <= MAX_TTY_CHANNELS) and
+            "The NB_TTY_CHANNELS parameter cannot be larger than 8" );
+
+    assert( (NB_NIC_CHANNELS <= MAX_NIC_CHANNELS) and
             "The NB_NIC_CHANNELS parameter cannot be larger than 2" );
 
@@ -415,6 +426,6 @@
     std::cout << " - MAX_CYCLES       = " << ncycles << std::endl;
     std::cout << " - RESET_ADDRESS    = " << RESET_ADDRESS << std::endl;
-    std::cout << " - SOFT_FILENAME    = " << elf_loader << std::endl;
-    std::cout << " - RAMDISK_FILENAME = " << ramdisk_loader << std::endl;
+    std::cout << " - SOFT_PATH_NAME   = " << BINARY_PATH_FOR_LOADER << std::endl;
+    std::cout << " - DISK_IMAGE_PATH  = " << DISK_IMAGE_PATH_FOR_IOC << std::endl;
 
     std::cout << std::endl;
@@ -462,5 +473,5 @@
    for (size_t x = 0; x < X_SIZE; x++)
    {
-      for (size_t y = 0; y < Y_SIZE; y++)
+      for (size_t y = 0; y < (Y_SIZE-1) ; y++)
       {
          sc_uint<vci_address_width> offset;
@@ -484,5 +495,5 @@
    }
 
-   // segments in cluster(0,0)
+   // segments for peripherals in cluster(0,0)
    maptabd.add(Segment("seg_tty0", MTTY_BASE, MTTY_SIZE, 
                IntTab(cluster(0,0),MTTY_TGTID), false));
@@ -491,25 +502,25 @@
                IntTab(cluster(0,0),BDEV_TGTID), false));
 
-   // segments in cluster_io (X_SIZE-1,Y_SIZE)
+   // segments for peripherals in cluster_io (X_SIZE-1,Y_SIZE-1)
    sc_uint<vci_address_width> offset;
-   offset = ((sc_uint<vci_address_width>)cluster(X_SIZE-1,Y_SIZE)) << 32;
+   offset = ((sc_uint<vci_address_width>)cluster(X_SIZE-1,Y_SIZE-1)) << 32;
 
    maptabd.add(Segment("seg_mtty", MTTY_BASE + offset, MTTY_SIZE, 
-               IntTab(cluster(X_SIZE-1, Y_SIZE),MTTY_TGTID), false));
+               IntTab(cluster(X_SIZE-1, Y_SIZE-1),MTTY_TGTID), false));
 
    maptabd.add(Segment("seg_fbuf", FBUF_BASE + offset, FBUF_SIZE, 
-               IntTab(cluster(X_SIZE-1, Y_SIZE),FBUF_TGTID), false));
+               IntTab(cluster(X_SIZE-1, Y_SIZE-1),FBUF_TGTID), false));
 
    maptabd.add(Segment("seg_bdev", BDEV_BASE + offset, BDEV_SIZE, 
-               IntTab(cluster(X_SIZE-1, Y_SIZE),BDEV_TGTID), false));
+               IntTab(cluster(X_SIZE-1, Y_SIZE-1),BDEV_TGTID), false));
 
    maptabd.add(Segment("seg_mnic", MNIC_BASE + offset, MNIC_SIZE, 
-               IntTab(cluster(X_SIZE-1, Y_SIZE),MNIC_TGTID), false));
+               IntTab(cluster(X_SIZE-1, Y_SIZE-1),MNIC_TGTID), false));
 
    maptabd.add(Segment("seg_cdma", CDMA_BASE + offset, CDMA_SIZE, 
-               IntTab(cluster(X_SIZE-1, Y_SIZE),CDMA_TGTID), false));
+               IntTab(cluster(X_SIZE-1, Y_SIZE-1),CDMA_TGTID), false));
 
    maptabd.add(Segment("seg_iopi", IOPI_BASE + offset, IOPI_SIZE, 
-               IntTab(cluster(X_SIZE-1, Y_SIZE),IOPI_TGTID), false));
+               IntTab(cluster(X_SIZE-1, Y_SIZE-1),IOPI_TGTID), false));
 
    std::cout << maptabd << std::endl;
@@ -526,5 +537,5 @@
     for (size_t x = 0; x < X_SIZE; x++)
     {
-        for (size_t y = 0; y < Y_SIZE ; y++)
+        for (size_t y = 0; y < (Y_SIZE-1) ; y++)
         { 
             sc_uint<vci_address_width> offset;
@@ -552,5 +563,6 @@
     sc_signal<bool>                   signal_irq_mnic_rx[NB_NIC_CHANNELS];
     sc_signal<bool>                   signal_irq_mnic_tx[NB_NIC_CHANNELS];
-    sc_signal<bool>                   signal_irq_mtty[NB_TTY_CHANNELS];
+    sc_signal<bool>                   signal_irq_mtty_rx[NB_TTY_CHANNELS];
+//  sc_signal<bool>                   signal_irq_mtty_tx[NB_TTY_CHANNELS];
     sc_signal<bool>                   signal_irq_cdma[NB_CMA_CHANNELS];
     sc_signal<bool>                   signal_irq_false;
@@ -558,79 +570,79 @@
    // Horizontal inter-clusters DSPIN signals
    DspinSignals<dspin_cmd_width>** signal_dspin_h_cmd_inc =
-      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_h_cmd_inc", X_SIZE-1, Y_SIZE);
+      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_h_cmd_inc", X_SIZE-1, Y_SIZE-1);
    DspinSignals<dspin_cmd_width>** signal_dspin_h_cmd_dec =
-      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_h_cmd_dec", X_SIZE-1, Y_SIZE);
+      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_h_cmd_dec", X_SIZE-1, Y_SIZE-1);
 
    DspinSignals<dspin_rsp_width>** signal_dspin_h_rsp_inc =
-      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_h_rsp_inc", X_SIZE-1, Y_SIZE);
+      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_h_rsp_inc", X_SIZE-1, Y_SIZE-1);
    DspinSignals<dspin_rsp_width>** signal_dspin_h_rsp_dec =
-      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_h_rsp_dec", X_SIZE-1, Y_SIZE);
+      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_h_rsp_dec", X_SIZE-1, Y_SIZE-1);
 
    DspinSignals<dspin_cmd_width>** signal_dspin_h_m2p_inc =
-      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_h_m2p_inc", X_SIZE-1, Y_SIZE);
+      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_h_m2p_inc", X_SIZE-1, Y_SIZE-1);
    DspinSignals<dspin_cmd_width>** signal_dspin_h_m2p_dec =
-      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_h_m2p_dec", X_SIZE-1, Y_SIZE);
+      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_h_m2p_dec", X_SIZE-1, Y_SIZE-1);
 
    DspinSignals<dspin_rsp_width>** signal_dspin_h_p2m_inc =
-      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_h_p2m_inc", X_SIZE-1, Y_SIZE);
+      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_h_p2m_inc", X_SIZE-1, Y_SIZE-1);
    DspinSignals<dspin_rsp_width>** signal_dspin_h_p2m_dec =
-      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_h_p2m_dec", X_SIZE-1, Y_SIZE);
+      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_h_p2m_dec", X_SIZE-1, Y_SIZE-1);
 
    DspinSignals<dspin_cmd_width>** signal_dspin_h_cla_inc =
-      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_h_cla_inc", X_SIZE-1, Y_SIZE);
+      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_h_cla_inc", X_SIZE-1, Y_SIZE-1);
    DspinSignals<dspin_cmd_width>** signal_dspin_h_cla_dec =
-      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_h_cla_dec", X_SIZE-1, Y_SIZE);
+      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_h_cla_dec", X_SIZE-1, Y_SIZE-1);
 
    // Vertical inter-clusters DSPIN signals
    DspinSignals<dspin_cmd_width>** signal_dspin_v_cmd_inc =
-      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_v_cmd_inc", X_SIZE, Y_SIZE-1);
+      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_v_cmd_inc", X_SIZE, Y_SIZE-2);
    DspinSignals<dspin_cmd_width>** signal_dspin_v_cmd_dec =
-      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_v_cmd_dec", X_SIZE, Y_SIZE-1);
+      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_v_cmd_dec", X_SIZE, Y_SIZE-2);
 
    DspinSignals<dspin_rsp_width>** signal_dspin_v_rsp_inc =
-      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_v_rsp_inc", X_SIZE, Y_SIZE-1);
+      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_v_rsp_inc", X_SIZE, Y_SIZE-2);
    DspinSignals<dspin_rsp_width>** signal_dspin_v_rsp_dec =
-      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_v_rsp_dec", X_SIZE, Y_SIZE-1);
+      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_v_rsp_dec", X_SIZE, Y_SIZE-2);
 
    DspinSignals<dspin_cmd_width>** signal_dspin_v_m2p_inc =
-      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_v_m2p_inc", X_SIZE, Y_SIZE-1);
+      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_v_m2p_inc", X_SIZE, Y_SIZE-2);
    DspinSignals<dspin_cmd_width>** signal_dspin_v_m2p_dec =
-      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_v_m2p_dec", X_SIZE, Y_SIZE-1);
+      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_v_m2p_dec", X_SIZE, Y_SIZE-2);
 
    DspinSignals<dspin_rsp_width>** signal_dspin_v_p2m_inc =
-      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_v_p2m_inc", X_SIZE, Y_SIZE-1);
+      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_v_p2m_inc", X_SIZE, Y_SIZE-2);
    DspinSignals<dspin_rsp_width>** signal_dspin_v_p2m_dec =
-      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_v_p2m_dec", X_SIZE, Y_SIZE-1);
+      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_v_p2m_dec", X_SIZE, Y_SIZE-2);
 
    DspinSignals<dspin_cmd_width>** signal_dspin_v_cla_inc =
-      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_v_cla_inc", X_SIZE, Y_SIZE-1);
+      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_v_cla_inc", X_SIZE, Y_SIZE-2);
    DspinSignals<dspin_cmd_width>** signal_dspin_v_cla_dec =
-      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_v_cla_dec", X_SIZE, Y_SIZE-1);
+      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_v_cla_dec", X_SIZE, Y_SIZE-2);
 
    // Mesh boundaries DSPIN signals (Most of those signals are not used...)
    DspinSignals<dspin_cmd_width>*** signal_dspin_bound_cmd_in =
-      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_bound_cmd_in" , X_SIZE, Y_SIZE, 4);
+      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_bound_cmd_in" , X_SIZE, Y_SIZE-1, 4);
    DspinSignals<dspin_cmd_width>*** signal_dspin_bound_cmd_out =
-      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_bound_cmd_out", X_SIZE, Y_SIZE, 4);
+      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_bound_cmd_out", X_SIZE, Y_SIZE-1, 4);
 
    DspinSignals<dspin_rsp_width>*** signal_dspin_bound_rsp_in =
-      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_bound_rsp_in" , X_SIZE, Y_SIZE, 4);
+      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_bound_rsp_in" , X_SIZE, Y_SIZE-1, 4);
    DspinSignals<dspin_rsp_width>*** signal_dspin_bound_rsp_out =
-      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_bound_rsp_out", X_SIZE, Y_SIZE, 4);
+      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_bound_rsp_out", X_SIZE, Y_SIZE-1, 4);
 
    DspinSignals<dspin_cmd_width>*** signal_dspin_bound_m2p_in =
-      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_bound_m2p_in" , X_SIZE, Y_SIZE, 4);
+      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_bound_m2p_in" , X_SIZE, Y_SIZE-1, 4);
    DspinSignals<dspin_cmd_width>*** signal_dspin_bound_m2p_out =
-      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_bound_m2p_out", X_SIZE, Y_SIZE, 4);
+      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_bound_m2p_out", X_SIZE, Y_SIZE-1, 4);
 
    DspinSignals<dspin_rsp_width>*** signal_dspin_bound_p2m_in =
-      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_bound_p2m_in" , X_SIZE, Y_SIZE, 4);
+      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_bound_p2m_in" , X_SIZE, Y_SIZE-1, 4);
    DspinSignals<dspin_rsp_width>*** signal_dspin_bound_p2m_out =
-      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_bound_p2m_out", X_SIZE, Y_SIZE, 4);
+      alloc_elems<DspinSignals<dspin_rsp_width> >("signal_dspin_bound_p2m_out", X_SIZE, Y_SIZE-1, 4);
 
    DspinSignals<dspin_cmd_width>*** signal_dspin_bound_cla_in =
-      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_bound_cla_in" , X_SIZE, Y_SIZE, 4);
+      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_bound_cla_in" , X_SIZE, Y_SIZE-1, 4);
    DspinSignals<dspin_cmd_width>*** signal_dspin_bound_cla_out =
-      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_bound_cla_out", X_SIZE, Y_SIZE, 4);
+      alloc_elems<DspinSignals<dspin_cmd_width> >("signal_dspin_bound_cla_out", X_SIZE, Y_SIZE-1, 4);
 
    // VCI signals for iobus and peripherals
@@ -658,5 +670,9 @@
    ////////////////////////////
 
-   soclib::common::Loader loader( elf_loader, ramdisk_loader );
+#if USE_IOC_RDK
+   soclib::common::Loader loader( BINARY_PATH_FOR_LOADER, RAMDISK_PATH_FOR_LOADER );
+#else
+   soclib::common::Loader loader( BINARY_PATH_FOR_LOADER );
+#endif
 
    ///////////////////////////
@@ -667,12 +683,12 @@
    proc_iss::set_loader( loader );
 
-   ////////////////////////////
-   // Clusters construction
-   ////////////////////////////
+   //////////////////////////////////////////////////////////////
+   // mesh construction: only (X_SIZE) * (Y_SIZE-1) clusters
+   //////////////////////////////////////////////////////////////
 
    TsarLetiCluster<dspin_cmd_width,
                    dspin_rsp_width,
                    vci_param_int,
-                   vci_param_ext>*          clusters[X_SIZE][Y_SIZE];
+                   vci_param_ext>*          clusters[X_SIZE][Y_SIZE-1];
 
 #if USE_OPENMP
@@ -681,8 +697,8 @@
 #pragma omp for
 #endif
-        for (size_t i = 0; i  < (X_SIZE * Y_SIZE); i++)
+        for (size_t i = 0; i  < (X_SIZE * (Y_SIZE-1)); i++)
         {
-            size_t x = i / Y_SIZE;
-            size_t y = i % Y_SIZE;
+            size_t x = i / (Y_SIZE-1);
+            size_t y = i % (Y_SIZE-1);
 
 #if USE_OPENMP
@@ -695,4 +711,7 @@
             std::cout << std::endl;
 
+            std::ostringstream cluster_name;
+            cluster_name <<  "cluster_" << std::dec << x << "_" << y;
+
             clusters[x][y] = new TsarLetiCluster<dspin_cmd_width,
                                                  dspin_rsp_width,
@@ -700,5 +719,5 @@
                                                  vci_param_ext>
             (
-                "cluster",
+                cluster_name.str().c_str(),
                 NB_PROCS_MAX,
                 x,
@@ -715,5 +734,5 @@
                 MTTY_TGTID,
                 BDEV_TGTID,
-                BDEV_IMAGE_NAME,
+                DISK_IMAGE_PATH_FOR_IOC,
                 MEMC_WAYS,
                 MEMC_SETS,
@@ -742,7 +761,18 @@
     //////////////////////////////////////////////////////////////////
     // IO bus and external peripherals in cluster[X_SIZE-1,Y_SIZE]
+    // - 6 local targets    : FBF, TTY, CMA, NIC, PIC, IOC
+    // - 3 local initiators : IOC, CMA, PIC
+    // There is no PROC, no MEMC and no XICU in this cluster,
+    // but the crossbar has (NB_PROCS_MAX + 3) intiators and
+    // 8 targets, in order to use the same SRCID and TGTID space
+    // (same mapping table for the internal components, 
+    //  and for the external peripherals) 
     //////////////////////////////////////////////////////////////////
 
-    size_t cluster_io = cluster(X_SIZE-1, Y_SIZE);
+    std::cout << std::endl;
+    std::cout << " Building IO cluster (external peripherals)" << std::endl;
+    std::cout << std::endl;
+  
+    size_t cluster_io = cluster(X_SIZE-1, Y_SIZE-1);
 
     //////////// vci_local_crossbar  
@@ -771,5 +801,5 @@
                 IntTab(cluster_io, BDEV_SRCID),
                 IntTab(cluster_io, BDEV_TGTID),
-                BDEV_IMAGE_NAME,
+                DISK_IMAGE_PATH_FOR_IOC,
                 512,                          // block size
                 64 );                         // burst size
@@ -820,5 +850,6 @@
                 IntTab(cluster_io, IOPI_SRCID),
                 IntTab(cluster_io, IOPI_TGTID),
-                16 );
+                32,
+                20000000 );
 
     ////////////// vci_dspin wrappers 
@@ -909,5 +940,5 @@
     for ( size_t i=0 ; i<NB_TTY_CHANNELS ; i++ )
     {
-        mtty->p_irq[i]              	(signal_irq_mtty[i]);
+        mtty->p_irq[i]              	(signal_irq_mtty_rx[i]);
     }
 
@@ -915,9 +946,12 @@
 
     // iopic
+    // NB_NIC_CHANNELS <= 2
+    // NB_CMA_CHANNELS <= 4
+    // NB_TTY_CHANNELS <= 8
     iopic->p_clk                       (signal_clk);
     iopic->p_resetn                    (signal_resetn);
     iopic->p_vci_target                (signal_vci_tgt_iopi);
     iopic->p_vci_initiator             (signal_vci_ini_iopi);
-    for ( size_t i=0 ; i<16 ; i++)
+    for ( size_t i=0 ; i<32 ; i++)
     {
        if     (i < NB_NIC_CHANNELS)    iopic->p_hwi[i] (signal_irq_mnic_rx[i]);
@@ -926,10 +960,15 @@
        else if(i < 4 )                 iopic->p_hwi[i] (signal_irq_false);
        else if(i < 4+NB_CMA_CHANNELS)  iopic->p_hwi[i] (signal_irq_cdma[i-4]);
-       else if(i < 9)                  iopic->p_hwi[i] (signal_irq_false);
-       else if(i == 9)                 iopic->p_hwi[i] (signal_irq_bdev);
-       else if(i < 12)                 iopic->p_hwi[i] (signal_irq_false);
-       else if(i < 12+NB_TTY_CHANNELS) iopic->p_hwi[i] (signal_irq_mtty[i-12]);
+       else if(i < 8)                  iopic->p_hwi[i] (signal_irq_false);
+       else if(i == 8)                 iopic->p_hwi[i] (signal_irq_bdev);
+       else if(i < 16)                 iopic->p_hwi[i] (signal_irq_false);
+       else if(i < 16+NB_TTY_CHANNELS) iopic->p_hwi[i] (signal_irq_mtty_rx[i-16]);
+       else if(i < 24)                 iopic->p_hwi[i] (signal_irq_false);
+       else if(i < 24+NB_TTY_CHANNELS) iopic->p_hwi[i] (signal_irq_false);
+//     else if(i < 24+NB_TTY_CHANNELS) iopic->p_hwi[i] (signal_irq_mtty_tx[i-24]);
        else                            iopic->p_hwi[i] (signal_irq_false);
     }
+
+    std::cout << "  - IOPIC connected" << std::endl;
 
     // vci/dspin wrappers
@@ -937,6 +976,6 @@
     wi_iobus->p_resetn                 (signal_resetn);
     wi_iobus->p_vci                    (signal_vci_cmd_to_noc);
-    wi_iobus->p_dspin_cmd              (signal_dspin_bound_cmd_in[X_SIZE-1][Y_SIZE-1][NORTH]);
-    wi_iobus->p_dspin_rsp              (signal_dspin_bound_rsp_out[X_SIZE-1][Y_SIZE-1][NORTH]);
+    wi_iobus->p_dspin_cmd              (signal_dspin_bound_cmd_in[X_SIZE-1][Y_SIZE-2][NORTH]);
+    wi_iobus->p_dspin_rsp              (signal_dspin_bound_rsp_out[X_SIZE-1][Y_SIZE-2][NORTH]);
 
     // vci/dspin wrappers
@@ -944,11 +983,11 @@
     wt_iobus->p_resetn                 (signal_resetn);
     wt_iobus->p_vci                    (signal_vci_cmd_from_noc);
-    wt_iobus->p_dspin_cmd              (signal_dspin_bound_cmd_out[X_SIZE-1][Y_SIZE-1][NORTH]);
-    wt_iobus->p_dspin_rsp              (signal_dspin_bound_rsp_in[X_SIZE-1][Y_SIZE-1][NORTH]);
+    wt_iobus->p_dspin_cmd              (signal_dspin_bound_cmd_out[X_SIZE-1][Y_SIZE-2][NORTH]);
+    wt_iobus->p_dspin_rsp              (signal_dspin_bound_rsp_in[X_SIZE-1][Y_SIZE-2][NORTH]);
 
     // Clock & RESET for clusters
     for (size_t x = 0; x < (X_SIZE); x++)
     {
-        for (size_t y = 0; y < Y_SIZE; y++)
+        for (size_t y = 0; y < (Y_SIZE-1); y++)
         {
             clusters[x][y]->p_clk                    (signal_clk);
@@ -962,5 +1001,5 @@
         for (size_t x = 0; x < (X_SIZE-1); x++)
         {
-            for (size_t y = 0; y < Y_SIZE; y++)
+            for (size_t y = 0; y < (Y_SIZE-1); y++)
             {
                 clusters[x][y]->p_cmd_out[EAST]      (signal_dspin_h_cmd_inc[x][y]);
@@ -994,7 +1033,7 @@
 
     // Inter Clusters vertical connections
-    if (Y_SIZE > 1) 
-    {
-        for (size_t y = 0; y < (Y_SIZE-1); y++)
+    if (Y_SIZE > 2) 
+    {
+        for (size_t y = 0; y < (Y_SIZE-2); y++)
         {
             for (size_t x = 0; x < X_SIZE; x++)
@@ -1030,5 +1069,5 @@
 
     // East & West boundary cluster connections
-    for (size_t y = 0; y < Y_SIZE; y++)
+    for (size_t y = 0; y < (Y_SIZE-1); y++)
     {
         clusters[0][y]->p_cmd_in[WEST]           (signal_dspin_bound_cmd_in[0][y][WEST]);
@@ -1058,4 +1097,6 @@
     }
 
+    std::cout << std::endl << "West & East boundaries connections done" << std::endl;
+
     // North & South boundary clusters connections
     for (size_t x = 0; x < X_SIZE; x++)
@@ -1063,29 +1104,30 @@
         clusters[x][0]->p_cmd_in[SOUTH]          (signal_dspin_bound_cmd_in[x][0][SOUTH]);
         clusters[x][0]->p_cmd_out[SOUTH]         (signal_dspin_bound_cmd_out[x][0][SOUTH]);
-        clusters[x][Y_SIZE-1]->p_cmd_in[NORTH]   (signal_dspin_bound_cmd_in[x][Y_SIZE-1][NORTH]);
-        clusters[x][Y_SIZE-1]->p_cmd_out[NORTH]  (signal_dspin_bound_cmd_out[x][Y_SIZE-1][NORTH]);
+        clusters[x][Y_SIZE-2]->p_cmd_in[NORTH]   (signal_dspin_bound_cmd_in[x][Y_SIZE-2][NORTH]);
+        clusters[x][Y_SIZE-2]->p_cmd_out[NORTH]  (signal_dspin_bound_cmd_out[x][Y_SIZE-2][NORTH]);
 
         clusters[x][0]->p_rsp_in[SOUTH]          (signal_dspin_bound_rsp_in[x][0][SOUTH]);
         clusters[x][0]->p_rsp_out[SOUTH]         (signal_dspin_bound_rsp_out[x][0][SOUTH]);
-        clusters[x][Y_SIZE-1]->p_rsp_in[NORTH]   (signal_dspin_bound_rsp_in[x][Y_SIZE-1][NORTH]);
-        clusters[x][Y_SIZE-1]->p_rsp_out[NORTH]  (signal_dspin_bound_rsp_out[x][Y_SIZE-1][NORTH]);
+        clusters[x][Y_SIZE-2]->p_rsp_in[NORTH]   (signal_dspin_bound_rsp_in[x][Y_SIZE-2][NORTH]);
+        clusters[x][Y_SIZE-2]->p_rsp_out[NORTH]  (signal_dspin_bound_rsp_out[x][Y_SIZE-2][NORTH]);
 
         clusters[x][0]->p_m2p_in[SOUTH]          (signal_dspin_bound_m2p_in[x][0][SOUTH]);
         clusters[x][0]->p_m2p_out[SOUTH]         (signal_dspin_bound_m2p_out[x][0][SOUTH]);
-        clusters[x][Y_SIZE-1]->p_m2p_in[NORTH]   (signal_dspin_bound_m2p_in[x][Y_SIZE-1][NORTH]);
-        clusters[x][Y_SIZE-1]->p_m2p_out[NORTH]  (signal_dspin_bound_m2p_out[x][Y_SIZE-1][NORTH]);
+        clusters[x][Y_SIZE-2]->p_m2p_in[NORTH]   (signal_dspin_bound_m2p_in[x][Y_SIZE-2][NORTH]);
+        clusters[x][Y_SIZE-2]->p_m2p_out[NORTH]  (signal_dspin_bound_m2p_out[x][Y_SIZE-2][NORTH]);
 
         clusters[x][0]->p_p2m_in[SOUTH]          (signal_dspin_bound_p2m_in[x][0][SOUTH]);
         clusters[x][0]->p_p2m_out[SOUTH]         (signal_dspin_bound_p2m_out[x][0][SOUTH]);
-        clusters[x][Y_SIZE-1]->p_p2m_in[NORTH]   (signal_dspin_bound_p2m_in[x][Y_SIZE-1][NORTH]);
-        clusters[x][Y_SIZE-1]->p_p2m_out[NORTH]  (signal_dspin_bound_p2m_out[x][Y_SIZE-1][NORTH]);
+        clusters[x][Y_SIZE-2]->p_p2m_in[NORTH]   (signal_dspin_bound_p2m_in[x][Y_SIZE-2][NORTH]);
+        clusters[x][Y_SIZE-2]->p_p2m_out[NORTH]  (signal_dspin_bound_p2m_out[x][Y_SIZE-2][NORTH]);
 
         clusters[x][0]->p_cla_in[SOUTH]          (signal_dspin_bound_cla_in[x][0][SOUTH]);
         clusters[x][0]->p_cla_out[SOUTH]         (signal_dspin_bound_cla_out[x][0][SOUTH]);
-        clusters[x][Y_SIZE-1]->p_cla_in[NORTH]   (signal_dspin_bound_cla_in[x][Y_SIZE-1][NORTH]);
-        clusters[x][Y_SIZE-1]->p_cla_out[NORTH]  (signal_dspin_bound_cla_out[x][Y_SIZE-1][NORTH]);
-    }
-
-    std::cout << std::endl << "North, South, West, East connections done" << std::endl;
+        clusters[x][Y_SIZE-2]->p_cla_in[NORTH]   (signal_dspin_bound_cla_in[x][Y_SIZE-2][NORTH]);
+        clusters[x][Y_SIZE-2]->p_cla_out[NORTH]  (signal_dspin_bound_cla_out[x][Y_SIZE-2][NORTH]);
+    }
+
+    std::cout << std::endl << "North & South boundaries connections done" << std::endl;
+
     std::cout << std::endl;
 
@@ -1102,9 +1144,9 @@
     for (size_t x = 0; x < X_SIZE ; x++)
     {
-        for (size_t y = 0; y < Y_SIZE ; y++)
+        for (size_t y = 0; y < Y_SIZE-1 ; y++)
         {
             for (size_t face = 0; face < 4; face++)
             {
-                if ( (x != X_SIZE-1) or (y != Y_SIZE-1) or (face != NORTH) )
+                if ( (x != X_SIZE-1) or (y != Y_SIZE-2) or (face != NORTH) )
                 {
                     signal_dspin_bound_cmd_in [x][y][face].write = false;
@@ -1137,4 +1179,9 @@
     }
 
+    // set default values for VCI signals connected to unused ports on iobus 
+    signal_vci_tgt_memc.rspval = false;
+    signal_vci_tgt_xicu.rspval = false;
+    for ( size_t p = 0 ; p < NB_PROCS_MAX ; p++ ) signal_vci_ini_proc[p].cmdval = false;
+
     sc_start(sc_core::sc_time(1, SC_NS));
     signal_resetn = true;
@@ -1146,120 +1193,177 @@
     }
 
-   for (uint64_t n = 1; n < ncycles && !stop_called; n++)
-   {
-      // Monitor a specific address for L1 & L2 caches
-      // clusters[0][0]->proc[0]->cache_monitor(0x0000010000ULL);
-      // clusters[0][0]->memc->cache_monitor(0x0000030000ULL);
-
-      if( (n % 5000000) == 0)
-      {
-
-         if (gettimeofday(&t2, NULL) != 0) 
-         {
-            perror("gettimeofday");
-            return EXIT_FAILURE;
-         }
-
-         ms1 = (uint64_t) t1.tv_sec * 1000ULL + (uint64_t) t1.tv_usec / 1000;
-         ms2 = (uint64_t) t2.tv_sec * 1000ULL + (uint64_t) t2.tv_usec / 1000;
-         std::cerr << "platform clock frequency " 
-                   << (double) 5000000 / (double) (ms2 - ms1) << "Khz" << std::endl;
-
-         if (gettimeofday(&t1, NULL) != 0) 
-         {
-            perror("gettimeofday");
-            return EXIT_FAILURE;
-         }
-      }
-
-      if ( trace_ok and (n > trace_from) )
-      {
-         std::cout << "****************** cycle " << std::dec << n ;
-         std::cout << " ************************************************" << std::endl;
-
-        // trace proc[trace_proc_id] 
-        size_t l = trace_proc_id % NB_PROCS_MAX ;
-        size_t x = (trace_proc_id / NB_PROCS_MAX) >> Y_WIDTH ;
-        size_t y = (trace_proc_id / NB_PROCS_MAX) & ((1<<Y_WIDTH) - 1);
-
-        std::ostringstream proc_signame;
-        proc_signame << "[SIG]PROC_" << x << "_" << y << "_" << l ;
-        std::ostringstream xicu_signame;
-        xicu_signame << "[SIG]XICU_" << x << "_" << y ;
-
-        clusters[x][y]->proc[l]->print_trace(0x1);
-        clusters[x][y]->signal_vci_ini_proc[l].print_trace(proc_signame.str());
-
-        clusters[x][y]->xicu->print_trace(0);
-        clusters[x][y]->signal_vci_tgt_xicu.print_trace(xicu_signame.str());
-      
-        if ( clusters[x][y]->signal_proc_irq[0].read() )  
-            std::cout << " IRQ_PROC active in cluster " << cluster(x,y) << std::endl;
-      
-        if ( signal_irq_bdev.read() )  
-            std::cout << " IRQ_BDEV in cluster_io active" << std::endl;
-      
-        // trace memc[trace_memc_id] and xram[trace_memc_id]
-        x = trace_memc_id >> Y_WIDTH;
-        y = trace_memc_id & ((1<<Y_WIDTH) - 1);
-
-        std::ostringstream smemc;
-        smemc << "[SIG]MEMC_" << x << "_" << y;
-        std::ostringstream sxram;
-        sxram << "[SIG]XRAM_" << x << "_" << y;
-
-        clusters[x][y]->memc->print_trace();
-        clusters[x][y]->signal_vci_tgt_memc.print_trace(smemc.str());
-        clusters[x][y]->signal_vci_xram.print_trace(sxram.str());
+    // variable used for IRQ trace
+    bool prev_irq_bdev = false;
+    bool prev_irq_mtty_rx[8];
+    bool prev_irq_proc[16][16][4];
+
+    for( size_t x = 0 ; x<8  ; x++ ) prev_irq_mtty_rx[x] = false;
+
+    for( size_t x = 0 ; x<16 ; x++ )
+    for( size_t y = 0 ; y<16 ; y++ )
+    for( size_t i = 0 ; i<4  ; i++ ) prev_irq_proc[x][y][i] = false;
+
+    for (uint64_t n = 1; n < ncycles && !stop_called; n++)
+    {
+        // Monitor a specific address for L1 & L2 caches
+        // clusters[0][0]->proc[0]->cache_monitor(0x110002C078ULL);
+        // clusters[1][1]->memc->cache_monitor(0x110002c078ULL);
+
+        // stats display
+        if( (n % 5000000) == 0)
+        {
+
+            if (gettimeofday(&t2, NULL) != 0) 
+            {
+                perror("gettimeofday");
+                return EXIT_FAILURE;
+            }
+
+            ms1 = (uint64_t) t1.tv_sec * 1000ULL + (uint64_t) t1.tv_usec / 1000;
+            ms2 = (uint64_t) t2.tv_sec * 1000ULL + (uint64_t) t2.tv_usec / 1000;
+            std::cerr << "platform clock frequency " 
+                      << (double) 5000000 / (double) (ms2 - ms1) << "Khz" << std::endl;
+
+            if (gettimeofday(&t1, NULL) != 0) 
+            {
+                perror("gettimeofday");
+                return EXIT_FAILURE;
+            }
+        }
+
+        // trace display
+        if ( trace_ok and (n > trace_from) )
+        {
+            std::cout << "****************** cycle " << std::dec << n ;
+            std::cout << " ************************************************" << std::endl;
+
+            size_t l = 0;
+            size_t x = 0;
+            size_t y = 0;
+
+            if ( trace_proc_ok )
+            {
+                l = trace_proc_id % NB_PROCS_MAX ;
+                x = (trace_proc_id / NB_PROCS_MAX) >> Y_WIDTH ;
+                y = (trace_proc_id / NB_PROCS_MAX) & ((1<<Y_WIDTH) - 1);
+
+                std::ostringstream proc_signame;
+                proc_signame << "[SIG]PROC_" << x << "_" << y << "_" << l ;
+                clusters[x][y]->proc[l]->print_trace();
+                clusters[x][y]->signal_vci_ini_proc[l].print_trace(proc_signame.str());
+
+                std::ostringstream xicu_signame;
+                xicu_signame << "[SIG]XICU_" << x << "_" << y ;
+                clusters[x][y]->xicu->print_trace(0);
+                clusters[x][y]->signal_vci_tgt_xicu.print_trace(xicu_signame.str());
+            }
+
+            if ( trace_memc_ok )
+            {
+                x = trace_memc_id >> Y_WIDTH;
+                y = trace_memc_id & ((1<<Y_WIDTH) - 1);
+
+                std::ostringstream smemc;
+                smemc << "[SIG]MEMC_" << x << "_" << y;
+                std::ostringstream sxram;
+                sxram << "[SIG]XRAM_" << x << "_" << y;
+
+                clusters[x][y]->memc->print_trace();
+                clusters[x][y]->signal_vci_tgt_memc.print_trace(smemc.str());
+                clusters[x][y]->signal_vci_xram.print_trace(sxram.str());
+            }   
+
+            // trace coherence signals
+            // clusters[0][0]->signal_dspin_m2p_proc[0].print_trace("[CC_M2P_0_0]");
+            // clusters[0][1]->signal_dspin_m2p_proc[0].print_trace("[CC_M2P_0_1]");
+            // clusters[1][0]->signal_dspin_m2p_proc[0].print_trace("[CC_M2P_1_0]");
+            // clusters[1][1]->signal_dspin_m2p_proc[0].print_trace("[CC_M2P_1_1]");
+
+            // clusters[0][0]->signal_dspin_p2m_proc[0].print_trace("[CC_P2M_0_0]");
+            // clusters[0][1]->signal_dspin_p2m_proc[0].print_trace("[CC_P2M_0_1]");
+            // clusters[1][0]->signal_dspin_p2m_proc[0].print_trace("[CC_P2M_1_0]");
+            // clusters[1][1]->signal_dspin_p2m_proc[0].print_trace("[CC_P2M_1_1]");
+
+            // trace xbar(s) m2p
+            // clusters[0][0]->xbar_m2p->print_trace();
+            // clusters[1][0]->xbar_m2p->print_trace();
+            // clusters[0][1]->xbar_m2p->print_trace();
+            // clusters[1][1]->xbar_m2p->print_trace();
         
-        // trace coherence signals
-        // clusters[0][0]->signal_dspin_m2p_proc[0].print_trace("[CC_M2P_0_0]");
-        // clusters[0][1]->signal_dspin_m2p_proc[0].print_trace("[CC_M2P_0_1]");
-        // clusters[1][0]->signal_dspin_m2p_proc[0].print_trace("[CC_M2P_1_0]");
-        // clusters[1][1]->signal_dspin_m2p_proc[0].print_trace("[CC_M2P_1_1]");
-
-        // clusters[0][0]->signal_dspin_p2m_proc[0].print_trace("[CC_P2M_0_0]");
-        // clusters[0][1]->signal_dspin_p2m_proc[0].print_trace("[CC_P2M_0_1]");
-        // clusters[1][0]->signal_dspin_p2m_proc[0].print_trace("[CC_P2M_1_0]");
-        // clusters[1][1]->signal_dspin_p2m_proc[0].print_trace("[CC_P2M_1_1]");
-
-        // trace xbar(s) m2p
-        // clusters[0][0]->xbar_m2p->print_trace();
-        // clusters[1][0]->xbar_m2p->print_trace();
-        // clusters[0][1]->xbar_m2p->print_trace();
-        // clusters[1][1]->xbar_m2p->print_trace();
+            // trace router(s) m2p
+            // clusters[0][0]->router_m2p->print_trace();
+            // clusters[1][0]->router_m2p->print_trace();
+            // clusters[0][1]->router_m2p->print_trace();
+            // clusters[1][1]->router_m2p->print_trace();
         
-        // trace router(s) m2p
-        // clusters[0][0]->router_m2p->print_trace();
-        // clusters[1][0]->router_m2p->print_trace();
-        // clusters[0][1]->router_m2p->print_trace();
-        // clusters[1][1]->router_m2p->print_trace();
+            // trace external ioc
+            bdev->print_trace();
+            signal_vci_tgt_bdev.print_trace("[SIG]BDEV_TGT");
+            signal_vci_ini_bdev.print_trace("[SIG]BDEV_INI");
+
+            // trace external iopic
+            iopic->print_trace();
+            signal_vci_tgt_iopi.print_trace("[SIG]IOPI_TGT");
+            signal_vci_ini_iopi.print_trace("[SIG]IOPI_INI");
+
+            // trace internal tty
+            // clusters[0][0]->mtty->print_trace();
+            // clusters[0][0]->signal_vci_tgt_mtty.print_trace("[SIG]MTTY");
+
+        }  // end trace
+
+        if (0)
+        {
+            // trace BDV interrupts events
+            if ( signal_irq_bdev.read() != prev_irq_bdev ) 
+            {
+                prev_irq_bdev = signal_irq_bdev.read();
+                std::cout << std::dec << "@@@ IRQ_BDEV = " << signal_irq_bdev.read()
+                          << " at cycle " << n << std::endl;
+            }
         
-        // trace external peripherals
-        bdev->print_trace();
-        signal_vci_tgt_bdev.print_trace("[SIG]BDEV_TGT");
-        signal_vci_ini_bdev.print_trace("[SIG]BDEV_INI");
-
-        iopic->print_trace();
-        signal_vci_tgt_iopi.print_trace("[SIG]IOPI_TGT");
-        signal_vci_ini_iopi.print_trace("[SIG]IOPI_INI");
-
-        clusters[0][0]->mtty->print_trace();
-        clusters[0][0]->signal_vci_tgt_mtty.print_trace("[SIG]MTTY");
-      }  // end trace
-
-      sc_start(sc_core::sc_time(1, SC_NS));
-   }
-
-   
-   // Free memory
-   for (size_t i = 0; i  < (X_SIZE * Y_SIZE); i++)
-   {
-      size_t x = i / Y_SIZE;
-      size_t y = i % Y_SIZE;
-      delete clusters[x][y];
-   }
-
-   return EXIT_SUCCESS;
+            // trace TTY interrupts events
+            for ( size_t x = 0 ; x < 8 ; x++ )
+            {
+                if ( signal_irq_mtty_rx[x].read() != prev_irq_mtty_rx[x] ) 
+                {
+                    prev_irq_mtty_rx[x] = signal_irq_mtty_rx[x].read();
+                    std::cout << std::dec << "@@@ IRQ_MTTY["<<x<<"] = " 
+                              << signal_irq_mtty_rx[x].read()
+                              << " at cycle " << n << std::endl;
+                }
+            }
+
+            // trace processor interrupts events
+            for ( size_t x = 0 ; x < 2 ; x++ )
+            for ( size_t y = 0 ; y < 2 ; y++ )
+            for ( size_t i = 0 ; i < 4 ; i++ )
+            {
+                if ( clusters[x][y]->signal_proc_irq[i] != prev_irq_proc[x][y][i] )
+                { 
+                    prev_irq_proc[x][y][i] = clusters[x][y]->signal_proc_irq[i];
+                    std::cout << std::dec << "@@@ IRQ_PROC["<<x<<","<<y<<","<<i<<"] = "
+                              << clusters[x][y]->signal_proc_irq[i]
+                              << " at cycle " << n << std::endl;
+                }
+            }
+
+            // trace VCI transactions on IOPIC and XCU(0,0)
+            signal_vci_tgt_iopi.print_trace("@@@ IOPI_TGT");
+            signal_vci_ini_iopi.print_trace("@@@ IOPI_INI");
+            clusters[0][0]->signal_vci_tgt_xicu.print_trace("@@@ XCU_0_0");
+        }
+
+        sc_start(sc_core::sc_time(1, SC_NS));
+    }
+    // Free memory
+    for (size_t i = 0 ; i  < (X_SIZE * (Y_SIZE-1)) ; i++)
+    {
+        size_t x = i / (Y_SIZE-1);
+        size_t y = i % (Y_SIZE-1);
+        delete clusters[x][y];
+    }
+
+    return EXIT_SUCCESS;
 }
 
