Index: trunk/platforms/tsar_generic_iob/genmap.py
===================================================================
--- trunk/platforms/tsar_generic_iob/genmap.py	(revision 707)
+++ trunk/platforms/tsar_generic_iob/genmap.py	(revision 707)
@@ -0,0 +1,323 @@
+#!/usr/bin/env python
+
+from mapping import *
+
+#######################################################################################
+#   file   : genmap.py
+#   date   : may 2014
+#   author : Alain Greiner
+#######################################################################################
+#  This file contains a mapping generator for the "tsar_generic_iob" platform. 
+#  This includes both the hardware architecture (clusters, processors, peripherals,
+#  physical space segmentation) and the mapping of all kernel objects (global vsegs).
+#  This platform includes 6 external peripherals, accessible through two IO_Bridge
+# components located in cluster [0,0] and cluster [x_size-1, y_size-1].
+# Available peripherals are: TTY, BDV, FBF, ROM, NIC, CMA.
+#  The parameters are:
+#  - x_size    : number of clusters in a row
+#  - y_size    : number of clusters in a column
+#  - procs_max : number of processors per cluster
+#  - nb_ttys   : number of TTY channels
+#  - nb_nics   : number of NIC channels
+#  - fbf_size  : frame_buffer width = frame_buffer heigth
+#  - x_io      : cluster_io x coordinate
+#  - y_io      : cluster_io y coordinate
+####################################################################################
+
+##########################
+def genmap( x_size    = 2,
+            y_size    = 2,
+            nb_procs  = 2,
+            nb_ttys   = 1,
+            nb_nics   = 2, 
+            fbf_width = 128,
+            x_io      = 0,
+            y_io      = 0 ):
+                     
+    ### parameters checking
+    assert( nb_procs <= 4 )
+
+    assert( (x_size == 1) or (x_size == 2) or (x_size == 4) 
+             or (y_size == 8) or (x_size == 16) )
+
+    assert( (y_size == 1) or (y_size == 2) or (y_size == 4) 
+             or (y_size == 8) or (y_size == 16) )
+
+    assert( nb_ttys <= 2 )
+
+    assert( ((x_io == 0) and (y_io == 0)) or
+            ((x_io == x_size-1) and (y_io == y_size-1)) )
+
+    ### define architecture constants
+
+    platform_name = 'tsar_iob_%d_%d_%d' % ( x_size, y_size, nb_procs )
+    x_width       = 4
+    y_width       = 4
+    paddr_width   = 40
+    irq_per_proc  = 4
+    use_ramdisk   = False
+
+    ### define physical segments
+
+    ram_base = 0x0000000000
+    ram_size = 0x4000000                         # 64 Mbytes
+
+    xcu_base = 0x00B0000000 
+    xcu_size = 0x1000                            # 4 Kbytes 
+
+    dma_base = 0x00B1000000
+    dma_size = 0x1000 * nb_procs                 # 4 Kbytes * nb_procs
+
+    mmc_base = 0x00B2000000 
+    mmc_size = 0x1000                            # 4 Kbytes
+
+    offset_io = ((x_io << y_width) + y_io) << (paddr_width - x_width - y_width)
+
+    bdv_base  = 0x00B3000000 + offset_io
+    bdv_size  = 0x1000                           # 4kbytes
+
+    tty_base  = 0x00B4000000 + offset_io
+    tty_size  = 0x4000                           # 16 Kbytes
+
+    nic_base  = 0x00B5000000 + offset_io
+    nic_size  = 0x80000                          # 512 kbytes
+
+    cma_base  = 0x00B6000000 + offset_io
+    cma_size  = 0x1000 * 2 * nb_nics             # 4 kbytes * 2 * nb_nics
+
+    fbf_base  = 0x00B7000000 + offset_io
+    fbf_size  = fbf_width * fbf_width            # fbf_width * fbf_width bytes
+
+    pic_base  = 0x00B8000000 + offset_io
+    pic_size  = 0x1000                           # 4 Kbytes
+
+    iob_base  = 0x00BE000000 + offset_io
+    iob_size  = 0x1000                           # 4kbytes
+
+    rom_base  = 0x00BFC00000 + offset_io
+    rom_size  = 0x4000                           # 16 Kbytes
+
+    ### define  bootloader vsegs base addresses
+
+    boot_mapping_vbase   = 0x00000000            # ident
+    boot_mapping_size    = 0x00010000            # 64 Kbytes
+
+    boot_code_vbase      = 0x00010000            # ident
+    boot_code_size       = 0x00020000            # 128 Kbytes 
+  
+    boot_data_vbase      = 0x00030000            # ident
+    boot_data_size       = 0x00010000            # 64 Kbytes
+
+    boot_buffer_vbase    = 0x00040000            # ident
+    boot_buffer_size     = 0x00060000            # 384 Kbytes
+
+    boot_stack_vbase     = 0x000A0000            # ident
+    boot_stack_size      = 0x00050000            # 320 Kbytes
+
+    ### define kernel vsegs base addresses
+
+    kernel_code_vbase    = 0x80000000            
+    kernel_code_size     = 0x00020000            # 128 Kbytes
+
+    kernel_data_vbase    = 0x80020000
+    kernel_data_size     = 0x00060000            # 384 Kbytes
+
+    kernel_uncdata_vbase = 0x80080000
+    kernel_uncdata_size  = 0x00040000            # 256 Kbytes
+
+    kernel_init_vbase    = 0x800C0000
+    kernel_init_size     = 0x00010000            # 64 Kbytes
+
+    kernel_sched_vbase   = 0xF0000000            # distributed in all clusters
+    kernel_sched_size    = 0x1000 * nb_procs     # 4 kbytes per processor
+
+    ### create mapping
+
+    mapping = Mapping( name         = platform_name, 
+                       x_size       = x_size,        
+                       y_size       = y_size,        
+                       procs_max    = nb_procs,      
+                       x_width      = x_width,       
+                       y_width      = y_width,       
+                       paddr_width  = paddr_width,   
+                       coherence    = True,          
+                       irq_per_proc = irq_per_proc,  
+                       use_ramdisk  = use_ramdisk,  
+                       x_io         = x_io,          
+                       y_io         = y_io )         
+
+    ###  external peripherals (accessible in cluster[0,0] only for this mapping)
+
+    iob = mapping.addPeriph( 'IOB', base = iob_base, size = iob_size, ptype = 'IOB' )
+
+    bdv = mapping.addPeriph( 'BDV', base = bdv_base, size = bdv_size, ptype = 'IOC', subtype = 'BDV' )
+
+    tty = mapping.addPeriph( 'TTY', base = tty_base, size = tty_size, ptype = 'TTY', channels = nb_ttys )
+
+    nic = mapping.addPeriph( 'NIC', base = nic_base, size = nic_size, ptype = 'NIC', channels = nb_nics ) 
+
+    cma = mapping.addPeriph( 'CMA', base = cma_base, size = cma_size, ptype = 'CMA', channels = 2*nb_nics )
+
+    fbf = mapping.addPeriph( 'FBF', base = fbf_base, size = fbf_size, ptype = 'FBF', arg1 = 128, arg2 = 128 )
+
+    rom = mapping.addPeriph( 'ROM', base = rom_base, size = rom_size, ptype = 'ROM' )
+
+    pic = mapping.addPeriph( 'PIC', base = pic_base, size = pic_size, ptype = 'PIC', channels = 32 )
+
+    mapping.addIrq( pic, index = 0,  isrtype = 'ISR_NIC_RX', channel = 0 )
+    mapping.addIrq( pic, index = 1,  isrtype = 'ISR_NIC_RX', channel = 1 )
+    mapping.addIrq( pic, index = 2,  isrtype = 'ISR_NIC_TX', channel = 0 )
+    mapping.addIrq( pic, index = 3,  isrtype = 'ISR_NIC_TX', channel = 1 )
+
+    mapping.addIrq( pic, index = 4,  isrtype = 'ISR_CMA'   , channel = 0 )
+    mapping.addIrq( pic, index = 5,  isrtype = 'ISR_CMA'   , channel = 1 )
+    mapping.addIrq( pic, index = 6,  isrtype = 'ISR_CMA'   , channel = 2 )
+    mapping.addIrq( pic, index = 7,  isrtype = 'ISR_CMA'   , channel = 3 )
+
+    mapping.addIrq( pic, index = 8,  isrtype = 'ISR_BDV'   , channel = 0 )
+
+    mapping.addIrq( pic, index = 16, isrtype = 'ISR_TTY_RX', channel = 0 )
+    mapping.addIrq( pic, index = 17, isrtype = 'ISR_TTY_RX', channel = 1 )
+    mapping.addIrq( pic, index = 18, isrtype = 'ISR_TTY_RX', channel = 2 )
+    mapping.addIrq( pic, index = 19, isrtype = 'ISR_TTY_RX', channel = 3 )
+    mapping.addIrq( pic, index = 20, isrtype = 'ISR_TTY_RX', channel = 4 )
+    mapping.addIrq( pic, index = 21, isrtype = 'ISR_TTY_RX', channel = 5 )
+    mapping.addIrq( pic, index = 22, isrtype = 'ISR_TTY_RX', channel = 6 )
+    mapping.addIrq( pic, index = 23, isrtype = 'ISR_TTY_RX', channel = 7 )
+
+    ### hardware components replicated in all clusters   
+
+    for x in xrange( x_size ):
+        for y in xrange( y_size ):
+            cluster_xy = (x << y_width) + y;
+            offset     = cluster_xy << (paddr_width - x_width - y_width)
+
+            ram = mapping.addRam( 'RAM', base = ram_base + offset, size = ram_size )
+
+            mmc = mapping.addPeriph( 'MMC', base = mmc_base + offset, size = mmc_size, 
+                                     ptype = 'MMC' )
+
+            dma = mapping.addPeriph( 'DMA', base = dma_base + offset, size = dma_size, 
+                                     ptype = 'DMA', channels = nb_procs ) 
+
+            xcu = mapping.addPeriph( 'XCU', base = xcu_base + offset, size = xcu_size, 
+                                     ptype = 'XCU', channels = nb_procs * irq_per_proc, 
+                                     arg1 = 16, arg2 = 16, arg3 = 16 )
+
+            # MMC IRQ replicated in all clusters
+            mapping.addIrq( xcu, index = 0, isrtype = 'ISR_MMC' )
+
+            # DMA IRQs replicated in all clusters
+            for p in xrange( nb_procs ): 
+                mapping.addIrq( xcu, index = (p+1), isrtype = 'ISR_DMA', channel = p )
+            
+            # processors
+            for p in xrange ( nb_procs ):
+                mapping.addProc( x, y, p )
+
+    ### global vsegs for boot_loader / identity mapping
+
+    mapping.addGlobal( 'seg_boot_mapping'  , boot_mapping_vbase  , boot_mapping_size  , 'C_W_', 
+                       vtype = 'BLOB'  , x = 0, y = 0, pseg = 'RAM', identity = True )
+
+    mapping.addGlobal( 'seg_boot_code'     , boot_code_vbase     , boot_code_size     , 'CXW_', 
+                       vtype = 'BUFFER', x = 0, y = 0, pseg = 'RAM', identity = True )
+
+    mapping.addGlobal( 'seg_boot_data'     , boot_data_vbase     , boot_data_size     , 'C_W_', 
+                       vtype = 'BUFFER', x = 0, y = 0, pseg = 'RAM', identity = True )
+
+    mapping.addGlobal( 'seg_boot_buffer'   , boot_buffer_vbase   , boot_buffer_size   , 'C_W_', 
+                       vtype = 'BUFFER', x = 0, y = 0, pseg = 'RAM', identity = True )
+
+    mapping.addGlobal( 'seg_boot_stack'    , boot_stack_vbase    , boot_stack_size    , 'C_W_', 
+                       vtype = 'BUFFER', x = 0, y = 0, pseg = 'RAM', identity = True )
+
+    ### global vsegs for kernel   
+
+    mapping.addGlobal( 'seg_kernel_code'   , kernel_code_vbase   , kernel_code_size   , 'CXW_', 
+                       vtype = 'ELF'   , x = 0, y = 0, pseg = 'RAM', binpath = 'build/kernel/kernel.elf' )
+
+    mapping.addGlobal( 'seg_kernel_data'   , kernel_data_vbase   , kernel_data_size   , 'C_W_', 
+                       vtype = 'ELF'   , x = 0, y = 0, pseg = 'RAM', binpath = 'build/kernel/kernel.elf' )
+
+    mapping.addGlobal( 'seg_kernel_uncdata', kernel_uncdata_vbase, kernel_uncdata_size, '__W_', 
+                       vtype = 'ELF'   , x = 0, y = 0, pseg = 'RAM', binpath = 'build/kernel/kernel.elf' )
+
+    mapping.addGlobal( 'seg_kernel_init'   , kernel_init_vbase   , kernel_init_size   , 'CXW_', 
+                       vtype = 'ELF'   , x = 0, y = 0, pseg = 'RAM', binpath = 'build/kernel/kernel.elf' )
+
+    ### global vsegs for external peripherals / identity mapping
+
+    mapping.addGlobal( 'seg_iob', iob_base, iob_size, '__W_', 
+                       vtype = 'PERI', x = 0, y = 0, pseg = 'IOB', identity = True )
+
+    mapping.addGlobal( 'seg_bdv', bdv_base, bdv_size, '__W_', 
+                       vtype = 'PERI', x = 0, y = 0, pseg = 'BDV', identity = True )
+
+    mapping.addGlobal( 'seg_tty', tty_base, tty_size, '__W_', 
+                       vtype = 'PERI', x = 0, y = 0, pseg = 'TTY', identity = True )
+
+    mapping.addGlobal( 'seg_nic', nic_base, nic_size, '__W_', 
+                       vtype = 'PERI', x = 0, y = 0, pseg = 'NIC', identity = True )
+
+    mapping.addGlobal( 'seg_cma', cma_base, cma_size, '__W_', 
+                       vtype = 'PERI', x = 0, y = 0, pseg = 'CMA', identity = True )
+
+    mapping.addGlobal( 'seg_fbf', fbf_base, fbf_size, '__W_', 
+                       vtype = 'PERI', x = 0, y = 0, pseg = 'FBF', identity = True )
+
+    mapping.addGlobal( 'seg_pic', pic_base, pic_size, '__W_', 
+                       vtype = 'PERI', x = 0, y = 0, pseg = 'PIC', identity = True )
+
+    mapping.addGlobal( 'seg_rom', rom_base, rom_size, 'CXW_', 
+                       vtype = 'PERI', x = 0, y = 0, pseg = 'ROM', identity = True )
+
+    ### Global vsegs for replicated peripherals, and for scheduler 
+    ### Note: one vseg per cluster: the vseg name is indexed by (x,y)
+    ### the vseg base address is incremented by (cluster_xy * 0x10000)
+
+    mapping.addGlobal( 'seg_xcu'  , xcu_base          , xcu_size         , '__W_', 
+                       vtype = 'PERI' , x = 0, y = 0, pseg = 'XCU', replicated = True )
+
+    mapping.addGlobal( 'seg_dma'  , dma_base          , dma_size         , '__W_', 
+                       vtype = 'PERI' , x = 0, y = 0, pseg = 'DMA', replicated = True )
+
+    mapping.addGlobal( 'seg_mmc'  , mmc_base          , mmc_size         , '__W_', 
+                       vtype = 'PERI' , x = 0, y = 0, pseg = 'MMC', replicated = True )
+
+    mapping.addGlobal( 'seg_sched', kernel_sched_vbase, kernel_sched_size, 'C_W_', 
+                       vtype = 'SCHED', x = 0, y = 0, pseg = 'RAM', replicated = True )
+
+    ### return mapping ###
+
+    return mapping
+
+################################# platform test #######################################################
+
+if __name__ == '__main__':
+
+    mapping = genmap( x_size    = 2,
+                      y_size    = 2,
+                      nb_procs  = 2,
+                      nb_ttys   = 1,
+                      nb_nics   = 2, 
+                      fbf_width = 128,
+                      x_io      = 0,
+                      y_io      = 0 )
+
+#   print mapping.netbsd_dts()
+
+    print mapping.xml()
+
+#   print mapping.giet_vsegs()
+                     
+
+# Local Variables:
+# tab-width: 4;
+# c-basic-offset: 4;
+# c-file-offsets:((innamespace . 0)(inline-open . 0));
+# indent-tabs-mode: nil;
+# End:
+#
+# vim: filetype=python:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
+
Index: trunk/platforms/tsar_generic_iob/top.cpp
===================================================================
--- trunk/platforms/tsar_generic_iob/top.cpp	(revision 706)
+++ trunk/platforms/tsar_generic_iob/top.cpp	(revision 707)
@@ -1,4 +1,4 @@
 ///////////////////////////////////////////////////////////////////////////////
-// File: top.cpp 
+// File: top.cpp  (for tsar_generic_iob platform)
 // Author: Alain Greiner 
 // Copyright: UPMC/LIP6
@@ -7,5 +7,5 @@
 ///////////////////////////////////////////////////////////////////////////////
 // This file define a generic TSAR architecture with an IO network emulating 
-// an external bus (i.e. Hypertransport) to access external peripherals:
+// an external bus (i.e. Hypertransport) to access 7 external peripherals:
 //
 // - BROM : boot ROM
@@ -15,42 +15,51 @@
 // - CDMA : Chained Buffer DMA controller (up to 4 channels)
 // - BDEV : Dlock Device controler (1 channel)
-// 
-// The internal physical address space is 40 bits.
+// - IOPI : HWI to SWI translator.
 //
-// It contains a 2D mesh of XMAX*YMAX clusters, and the cluster index
-// is encoded on 8 bits (X_WIDTH = 4 / Y_WIDTH = 4) whatever the mesh size.
+// The internal physical address space is 40 bits, and the cluster index
+// is defined by the 8 MSB bits, using a fixed format: X is encoded on 4 bits,
+// Y is encodes on 4 bits, whatever the actual mesh size.
+// => at most 16 * 16 clusters. Each cluster contains up to 4 processors.
 //
 // It contains 3 networks:
 //
-// 1) the INT network supports Read/Write transactions
+// 1) the "INT" network supports Read/Write transactions
 //    between processors and L2 caches or peripherals. 
 //    (VCI ADDDRESS = 40 bits / VCI DATA width = 32 bits)
 //    It supports also coherence transactions between L1 & L2 caches.
-// 3) the RAM network is emulating the 3D network between L2 caches
+// 3) the "RAM" network is emulating the 3D network between L2 caches
 //    and L3 caches, and is implemented as a 2D mesh between the L2 caches,
 //    the two IO bridges and the physical RAMs disributed in all clusters.
 //    (VCI ADDRESS = 40 bits / VCI DATA = 64 bits)
 // 4) the IOX network connects the two IO bridge components to the
-//    6 external peripheral controllers.
+//    7 external peripheral controllers.
 //    (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...
+// The external peripherals HWI IRQs are translated to WTI IRQs by the 
+// external IOPIC component, that must be configured by the OS to route
+// these WTI ITQS to one or several internal XICU components. 
+// The total number of channels for the external peripherals (MTTY, MNIC, CDMA
+// IOC or HBA) is limited by the IOPIC 32 HWI inputs:..
+// - IOPIC HWI[1:0]     connected to IRQ_NIC_RX[1:0]
+// - IOPIC HWI[3:2]     connected to IRQ_NIC_TX[1:0]      
+// - IOPIC HWI[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]]   TBD
 //
-// 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.
+// Besides the external peripherals, each cluster contains on XICU component,
+// and one multi channels DMA component.
+// The XICU component is mainly used to handle WTI IRQs, as only 2 HWI IRQs
+// are connected to XICU in each cluster: 
+// - IRQ_IN[0] : MMC
+// - IRQ_IN[1] : DMA channel 0
+// - IRQ_IN[2] : DMA channel 1
+// - IRQ_IN[3] : DMA channel 2
+// - IRQ_IN[4] : DMA channel 3
 // 
 // All clusters are identical, but cluster(0,0) and cluster(XMAX-1,YMAX-1)
 // contain an extra IO bridge component. These IOB0 & IOB1 components are
 // connected to the three networks (INT, RAM, IOX).
-// The number of clusters cannot be larger than 256.
-// The number of processors per cluster cannot be larger than 4.
 // 
 // - It uses two dspin_local_crossbar per cluster to implement the
@@ -70,11 +79,10 @@
 //
 // 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
+// - X_SIZE           : number of clusters in a row 
+// - Y_SIZE           : number of clusters in a column
 // - NB_PROCS_MAX     : number of processors per cluster (power of 2)
-// - 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)
+// - NB_TTY_CHANNELS  : number of TTY channels in I/O network (up to 16)
+// - NB_NIC_CHANNELS  : number of NIC channels in I/O network (up to 2)
+// - NB_CMA_CHANNELS  : number of CMA channels in I/O network (up to 4)
 // 
 // Some secondary hardware parameters must be defined in this top.cpp file:
@@ -99,11 +107,11 @@
 // The (x_width + y_width) MSB bits (left aligned) define
 // the cluster index, and the LADR bits define the local index:
-//      | X_ID  | Y_ID  |---| LADR |     OFFSET          |
-//      |x_width|y_width|---|  8   |       24            |
+//      |X_ID|Y_ID|  LADR  |     OFFSET          |
+//      |  4 |  4 |   8    |       24            |
 //
 // General policy for 14 bits SRCID decoding:
 // Each component is identified by (x_id, y_id, l_id) tuple.
-//      | X_ID  | Y_ID  |---| L_ID |
-//      |x_width|y_width|---|  6   |
+//      |X_ID|Y_ID| L_ID |
+//      |  4 |  4 |  6   |
 /////////////////////////////////////////////////////////////////////////
 
@@ -127,4 +135,6 @@
 #include "vci_framebuffer.h"
 #include "vci_iox_network.h"
+#include "vci_iox_network.h"
+#include "vci_iopic.h"
 
 #include "alloc_elems.h"
@@ -179,5 +189,5 @@
 //////////////////////i/////////////////////////////////////
 
-#include "giet_vm/hard_config.h"
+#include "hard_config.h"
 
 ////////////////////////////////////////////////////////////
@@ -238,11 +248,11 @@
 
 #define IOBX_BASE             0x00BE000000
-#define IOBX_SIZE             0x0000001000   // 4 K Kbytes
+#define IOBX_SIZE             0x0000001000   // 4 Kbytes
 
 #define BDEV_BASE             0x00B3000000      
-#define BDEV_SIZE             0x0000008000   // 4 Kbytes
+#define BDEV_SIZE             0x0000001000   // 4 Kbytes
 
 #define MTTY_BASE             0x00B4000000      
-#define MTTY_SIZE             0x0000001000 * NB_TTY_CHANNELS  // 4 Kbytes
+#define MTTY_SIZE             0x0000001000   // 4 Kbytes
 
 #define MNIC_BASE             0x00B5000000      
@@ -250,14 +260,17 @@
 
 #define CDMA_BASE             0x00B6000000      
-#define CDMA_SIZE             0x0000001000 * (NB_NIC_CHANNELS * 2)  // 4 Kbytes per channel 
+#define CDMA_SIZE             0x0000001000 * (NB_CMA_CHANNELS)  // 4 Kbytes per channel 
 
 #define FBUF_BASE             0x00B7000000      
 #define FBUF_SIZE             FBUF_X_SIZE * FBUF_Y_SIZE
 
+#define IOPI_BASE             0x00B8000000      
+#define IOPI_SIZE             0x0000001000   // 4 Kbytes
+
 // Replicated peripherals : address is incremented by a cluster offset 
 //     offset  = cluster(x,y) << (address_width-x_width-y_width);
 
 #define XRAM_BASE             0x0000000000      
-#define XRAM_SIZE             0x0010000000   // 256 Mbytes
+#define XRAM_SIZE             0x0004000000   // 64 Mbytes
 
 #define XICU_BASE             0x00B0000000      
@@ -287,9 +300,10 @@
 //   accessed in 2 clusters : cluster_iob0 and cluster_iob1. 
 //   They have the same local index, but two different cluster indexes.
+//
 // As cluster_iob0 and cluster_iob1 contain both internal initiators
 // and external initiators, they must have different local indexes. 
 // Consequence: For a local interconnect, the INI_ID port index
 // is NOT equal to the SRCID local index, and the local interconnect
-// must make a translation: SRCID => INI_ID (port index)
+// must make a translation: SRCID => INI_ID 
 ////////////////////////////////////////////////////////////////////////
 
@@ -298,4 +312,5 @@
 #define IOBX_LOCAL_SRCID             0x9
 #define MEMC_LOCAL_SRCID             0xA
+#define IOPI_LOCAL_SRCID             0xD
 #define CDMA_LOCAL_SRCID             0xE    // hard-coded in dspin_tsar
 #define BDEV_LOCAL_SRCID             0xF    // hard-coded in dspin_tsar
@@ -311,5 +326,5 @@
 
 #define INT_PROC_INI_ID              0   // from 0 to (NB_PROCS_MAX-1)
-#define INT_MDMA_INI_ID              NB_PROCS_MAX
+#define INT_MDMA_INI_ID              (NB_PROCS_MAX)
 #define INT_IOBX_INI_ID              (NB_PROCS_MAX+1)
 
@@ -335,4 +350,5 @@
 #define IOX_BROM_TGT_ID              6
 #define IOX_MTTY_TGT_ID              7
+#define IOX_IOPI_TGT_ID              8
 
 #define IOX_IOB0_INI_ID              0    // Don't change this value 
@@ -340,4 +356,5 @@
 #define IOX_BDEV_INI_ID              2     
 #define IOX_CDMA_INI_ID              3  
+#define IOX_IOPI_INI_ID              4 
 
 ////////////////////////////////////////////////////////////////////////
@@ -360,4 +377,5 @@
    size_t   debug_memc_id    = 0xFFFFFFFF;                 // index of traced memc   
    size_t   debug_proc_id    = 0xFFFFFFFF;                 // index of traced proc 
+   size_t   debug_xram_id    = 0xFFFFFFFF;                 // index of traced xram 
    bool     debug_iob        = false;                      // trace iob0 & iob1 when true
    uint32_t debug_from       = 0;                          // trace start cycle
@@ -401,5 +419,16 @@
             if( (x>=XMAX) || (y>=YMAX) )
             {
-                std::cout << "PROCID parameter does'nt fit XMAX/YMAX" << std::endl;
+                std::cout << "MEMCID parameter does'nt fit XMAX/YMAX" << std::endl;
+                exit(0);
+            }
+         }
+         else if ((strcmp(argv[n],"-XRAMID") == 0) && (n+1<argc) )
+         {
+            debug_xram_id = atoi(argv[n+1]);
+            size_t x = debug_xram_id >> 4;
+            size_t y = debug_xram_id & 0xF;
+            if( (x>=XMAX) || (y>=YMAX) )
+            {
+                std::cout << "XRAMID parameter does'nt fit XMAX/YMAX" << std::endl;
                 exit(0);
             }
@@ -447,4 +476,5 @@
             std::cout << "     -PERIOD number_of_cycles between trace" << std::endl;
             std::cout << "     -MEMCID index_memc_to_be_traced" << std::endl;
+            std::cout << "     -XRAMID index_xram_to_be_traced" << std::endl;
             std::cout << "     -PROCID index_proc_to_be_traced" << std::endl;
             std::cout << "     -IOB    non_zero_value" << std::endl;
@@ -473,15 +503,18 @@
            "The NB_NIC_CHANNELS parameter must be 2" );
 
-   std::cout << std::endl;
-   std::cout << " - XMAX            = " << XMAX << std::endl;
-   std::cout << " - YMAX            = " << YMAX << std::endl;
-   std::cout << " - NB_PROCS_MAX    = " << NB_PROCS_MAX <<  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;
+   std::cout << std::endl << std::dec
+             << " - XMAX            = " << XMAX << std::endl
+             << " - YMAX            = " << YMAX << std::endl
+             << " - NB_PROCS_MAX    = " << NB_PROCS_MAX <<  std::endl
+             << " - NB_DMA_CHANNELS = " << NB_DMA_CHANNELS <<  std::endl
+             << " - NB_TTY_CHANNELS = " << NB_TTY_CHANNELS <<  std::endl
+             << " - NB_NIC_CHANNELS = " << NB_NIC_CHANNELS <<  std::endl
+             << " - MEMC_WAYS       = " << MEMC_WAYS << std::endl
+             << " - MEMC_SETS       = " << MEMC_SETS << std::endl
+             << " - RAM_LATENCY     = " << XRAM_LATENCY << std::endl
+             << " - MAX_FROZEN      = " << frozen_cycles << std::endl
+             << " - DEBUG_PROCID    = " << debug_proc_id << std::endl
+             << " - DEBUG_MEMCID    = " << debug_memc_id << std::endl
+             << " - DEBUG_XRAMID    = " << debug_xram_id << std::endl;
 
    std::cout << std::endl;
@@ -597,4 +630,9 @@
             maptab_int.add(Segment(sdma.str(), CDMA_BASE+offset, CDMA_SIZE, 
                         IntTab(cluster(x,y), INT_IOBX_TGT_ID), not cacheable));
+
+            std::ostringstream    spic;
+            spic << "int_seg_iopi_" << x << "_" << y;
+            maptab_int.add(Segment(spic.str(), IOPI_BASE+offset, IOPI_SIZE, 
+                        IntTab(cluster(x,y), INT_IOBX_TGT_ID), not cacheable));
          }
 
@@ -606,4 +644,7 @@
 
          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), IOPI_LOCAL_SRCID ),
                                IntTab( cluster(x,y), INT_IOBX_INI_ID ) );
 
@@ -667,6 +708,6 @@
     // - two levels address decoding for commands
     // - two levels srcid decoding for responses
-    // - 4 initiators (IOB0, IOB1, BDEV, CDMA)
-    // - 8 targets (IOB0, IOB1, BDEV, CDMA, MTTY, FBUF, BROM, MNIC)
+    // - 5 initiators (IOB0, IOB1, BDEV, CDMA, IOPI)
+    // - 9 targets (IOB0, IOB1, BDEV, CDMA, MTTY, FBUF, BROM, MNIC, IOPI)
     ///////////////////////////////////////////////////////////////////////
     MappingTable maptab_iox( vci_address_width, 
@@ -679,41 +720,44 @@
     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).
+    // External peripherals segments
+    // WHen there is more than one cluster, external peripherals can be accessed
+    // through two segments, depending on the used IOB (IOB0 or IOB1).
     maptab_iox.add(Segment("iox_seg_mtty_0", MTTY_BASE + iob0_base, MTTY_SIZE, 
                    IntTab(cluster_iob0,IOX_MTTY_TGT_ID), false));
-    maptab_iox.add(Segment("iox_seg_mtty_1", MTTY_BASE + iob1_base, MTTY_SIZE, 
-                   IntTab(cluster_iob1,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));
-
     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));
-
     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));
-
     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));
-
     maptab_iox.add(Segment("iox_seg_brom_0", BROM_BASE + iob0_base, BROM_SIZE, 
                    IntTab(cluster_iob0,IOX_BROM_TGT_ID), false));
-    maptab_iox.add(Segment("iox_seg_brom_1", BROM_BASE + iob1_base, BROM_SIZE, 
+    maptab_iox.add(Segment("iox_seg_iopi_0", IOPI_BASE + iob0_base, IOPI_SIZE, 
+                   IntTab(cluster_iob0,IOX_IOPI_TGT_ID), false));
+    
+    if ( cluster_iob0 != cluster_iob1 )
+    {
+        maptab_iox.add(Segment("iox_seg_mtty_1", MTTY_BASE + iob1_base, MTTY_SIZE, 
+                   IntTab(cluster_iob1,IOX_MTTY_TGT_ID), false));
+        maptab_iox.add(Segment("iox_seg_fbuf_1", FBUF_BASE + iob1_base, FBUF_SIZE, 
+                   IntTab(cluster_iob1,IOX_FBUF_TGT_ID), false));
+        maptab_iox.add(Segment("iox_seg_bdev_1", BDEV_BASE + iob1_base, BDEV_SIZE, 
+                   IntTab(cluster_iob1,IOX_BDEV_TGT_ID), false));
+        maptab_iox.add(Segment("iox_seg_mnic_1", MNIC_BASE + iob1_base, MNIC_SIZE, 
+                   IntTab(cluster_iob1,IOX_MNIC_TGT_ID), false));
+        maptab_iox.add(Segment("iox_seg_cdma_1", CDMA_BASE + iob1_base, CDMA_SIZE, 
+                   IntTab(cluster_iob1,IOX_CDMA_TGT_ID), false));
+        maptab_iox.add(Segment("iox_seg_brom_1", BROM_BASE + iob1_base, BROM_SIZE, 
                    IntTab(cluster_iob1,IOX_BROM_TGT_ID), false));
-
-    // 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].
+        maptab_iox.add(Segment("iox_seg_iopi_1", IOPI_BASE + iob1_base, IOPI_SIZE, 
+                   IntTab(cluster_iob1,IOX_IOPI_TGT_ID), false));
+    }
+
+    // If there is more than one cluster, external peripherals 
+    // can access RAM through two segments (IOB0 / IOB1).
+    // As IOMMU is not activated, addresses are 40 bits (physical addresses),
+    // and the choice depends on address bit A[39].
     for (size_t x = 0; x < XMAX; x++)
     {
@@ -723,39 +767,45 @@
                              << (vci_address_width-x_width-y_width);
 
-            if ( x < (XMAX/2) ) // send command to XRAM through IOB0
+            if ( (cluster_iob0 != cluster_iob1) and (x >= (XMAX/2)) ) // use IOB1
+            {
+                std::ostringstream siob1;
+                siob1 << "iox_seg_xram_" << x << "_" << y;
+                maptab_iox.add(Segment(siob1.str(), offset, XRAM_SIZE, 
+                            IntTab(cluster_iob1,IOX_IOB1_TGT_ID), false));
+            }
+            else                                                     // USE IOB0
             {
                 std::ostringstream siob0;
                 siob0 << "iox_seg_xram_" << x << "_" << y;
-                maptab_iox.add(Segment(siob0.str(), offset, 0x80000000, 
+                maptab_iox.add(Segment(siob0.str(), offset, XRAM_SIZE, 
                             IntTab(cluster_iob0,IOX_IOB0_TGT_ID), false));
-            }
-            else                // send command to XRAM through IOB1
-            {
-                std::ostringstream siob1;
-                siob1 << "iox_seg_xram_" << x << "_" << y;
-                maptab_iox.add(Segment(siob1.str(), offset, 0x80000000, 
-                            IntTab(cluster_iob1,IOX_IOB1_TGT_ID), false));
             }
         }
     }
-    // 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)
+
+    // This define the mapping between the external initiators (SRCID)
     // and the port index on the IOX local interconnect.
-    // External initiator have two alias SRCID (iob0 / iob1 access)  
-
+    // If there is more than one cluster, external initiators
+    // have two alias SRCID (iob0 / iob1 access)  
     maptab_iox.srcid_map( IntTab( cluster_iob0, CDMA_LOCAL_SRCID ), 
                           IntTab( cluster_iob0, IOX_CDMA_INI_ID ) );
-
-    maptab_iox.srcid_map( IntTab( cluster_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 ) );
+    maptab_iox.srcid_map( IntTab( cluster_iob0, IOPI_LOCAL_SRCID ),
+                          IntTab( cluster_iob0, IOX_IOPI_INI_ID ) );
+
+    if ( cluster_iob0 != cluster_iob1 )
+    {
+        maptab_iox.srcid_map( IntTab( cluster_iob1, CDMA_LOCAL_SRCID ),
+                              IntTab( cluster_iob1, IOX_CDMA_INI_ID ) );
+        maptab_iox.srcid_map( IntTab( cluster_iob1, BDEV_LOCAL_SRCID ),
+                              IntTab( cluster_iob1, IOX_BDEV_INI_ID ) );
+        maptab_iox.srcid_map( IntTab( cluster_iob1, BDEV_LOCAL_SRCID ),
+                              IntTab( cluster_iob1, IOX_IOPI_INI_ID ) );
+    }
+
+    // This define the mapping between the internal initiators (SRCID)
+    // and the port index on the IOX local interconnect.
+    // If there is more than one cluster, external initiators
 
     for (size_t x = 0; x < XMAX; x++)
@@ -763,12 +813,22 @@
         for (size_t y = 0; y < YMAX ; y++)
         { 
-            size_t iob = ( x < (XMAX/2) ) ? IOX_IOB0_INI_ID : IOX_IOB1_INI_ID;
-
-            for (size_t p = 0 ; p < NB_PROCS_MAX ; 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 ) );
+            if ( (cluster_iob0 != cluster_iob1) and (x >= (XMAX/2)) ) // use IOB1
+            {
+                for (size_t p = 0 ; p < NB_PROCS_MAX ; p++)
+                maptab_iox.srcid_map( IntTab( cluster(x,y), PROC_LOCAL_SRCID + p ), 
+                                      IntTab( cluster_iob1, IOX_IOB1_INI_ID ) );
+
+                maptab_iox.srcid_map( IntTab( cluster(x,y), MDMA_LOCAL_SRCID ),
+                                      IntTab( cluster_iob1, IOX_IOB1_INI_ID ) );
+            }
+            else                                                      // USE IOB0
+            {
+                for (size_t p = 0 ; p < NB_PROCS_MAX ; p++)
+                maptab_iox.srcid_map( IntTab( cluster(x,y), PROC_LOCAL_SRCID + p ), 
+                                      IntTab( cluster_iob0, IOX_IOB0_INI_ID ) );
+
+                maptab_iox.srcid_map( IntTab( cluster(x,y), MDMA_LOCAL_SRCID ),
+                                      IntTab( cluster_iob0, IOX_IOB0_INI_ID ) );
+            }
         }
     }
@@ -787,6 +847,7 @@
     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_cdma[NB_NIC_CHANNELS*2];
+    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];
 
     // DSPIN signals for loopback in cluster_iob0 & cluster_iob1
@@ -801,4 +862,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_iopi("signal_vci_ini_iopi");
 
     VciSignals<vci_param_ext>         signal_vci_tgt_iob0("signal_vci_tgt_iob0");
@@ -810,4 +872,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_iopi("signal_vci_ini_iopi");
 
    // Horizontal inter-clusters INT network DSPIN 
@@ -897,6 +960,6 @@
    iox_network = new VciIoxNetwork<vci_param_ext>( "iox_network",  
                                                    maptab_iox,
-                                                   8,        // number of targets
-                                                   4 );      // number of initiators
+                                                   9,        // number of targets
+                                                   5 );      // number of initiators
    // boot ROM
    VciSimpleRom<vci_param_ext>*  brom;
@@ -950,12 +1013,21 @@
    {
       std::ostringstream term_name;
-      term_name <<  "term" << tid;
-      vect_names.push_back(term_name.str().c_str());
-   }
-   VciMultiTty<vci_param_ext>*  mtty;
-   mtty = new VciMultiTty<vci_param_ext>( "mtty",
-                                          IntTab(0, IOX_MTTY_TGT_ID),
-                                          maptab_iox, 
-                                          vect_names);
+         term_name <<  "term" << tid;
+         vect_names.push_back(term_name.str().c_str());
+      }
+      VciMultiTty<vci_param_ext>*  mtty;
+      mtty = new VciMultiTty<vci_param_ext>( "mtty",
+                                             IntTab(0, IOX_MTTY_TGT_ID),
+                                             maptab_iox, 
+                                             vect_names);
+
+   // IOPIC
+   VciIopic<vci_param_ext>* iopi;
+   iopi = new VciIopic<vci_param_ext>( "iopi",
+                                       maptab_iox,
+                                       IntTab(0, IOPI_LOCAL_SRCID),
+                                       IntTab(0, IOX_IOPI_TGT_ID),
+                                       32,          // number of input HWI             
+                                       5000 );      // period between WTI
    // Clusters 
    TsarIobCluster<vci_param_int,
@@ -1061,4 +1133,6 @@
     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_ini[IOX_IOPI_INI_ID]               (signal_vci_ini_iopi);
+
     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);
@@ -1069,4 +1143,5 @@
     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_IOPI_TGT_ID]               (signal_vci_tgt_iopi);
 
     // BDEV connexion
@@ -1115,5 +1190,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]);
     }
 
@@ -1127,43 +1202,45 @@
     for ( size_t i=0 ; i<(NB_NIC_CHANNELS*2) ; i++)
     {
-        cdma->p_irq[i]                                   (signal_irq_cdma[i]);
+        cdma->p_irq[i]                                 (signal_irq_cdma[i]);
     }
 
     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++ )
+    // IOPI connexion
+    iopi->p_clk                       	                (signal_clk);
+    iopi->p_resetn                    	                (signal_resetn);
+    iopi->p_vci_target                	                (signal_vci_tgt_iopi);
+    iopi->p_vci_initiator             	                (signal_vci_ini_iopi);
+    for ( size_t i=0 ; i<32 ; i++)
     {
-        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 < 10 ) (*clusters[0][0]->p_irq[n])       (signal_irq_mnic_rx[n-8]);
-
-        else if ( n < 12 ) (*clusters[0][0]->p_irq[n])       (signal_irq_false);
-//      else if ( n < 12 ) (*clusters[0][0]->p_irq[n])       (signal_irq_mnic_tx[n-10]);
-
-        else if ( n < 16 ) (*clusters[0][0]->p_irq[n])       (signal_irq_false);
-//      else if ( n < 16 ) (*clusters[0][0]->p_irq[n])       (signal_irq_cdma[n-12]);
-
-        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);
+       if     (i < NB_NIC_CHANNELS)    iopi->p_hwi[i] (signal_irq_mnic_rx[i]);
+       else if(i < 2 )                 iopi->p_hwi[i] (signal_irq_false);
+       else if(i < 2+NB_NIC_CHANNELS)  iopi->p_hwi[i] (signal_irq_mnic_tx[i-2]);
+       else if(i < 4 )                 iopi->p_hwi[i] (signal_irq_false);
+       else if(i < 4+NB_CMA_CHANNELS)  iopi->p_hwi[i] (signal_irq_cdma[i-4]);
+       else if(i < 8)                  iopi->p_hwi[i] (signal_irq_false);
+       else if(i == 8)                 iopi->p_hwi[i] (signal_irq_bdev);
+       else if(i < 16)                 iopi->p_hwi[i] (signal_irq_false);
+       else if(i < 16+NB_TTY_CHANNELS) iopi->p_hwi[i] (signal_irq_mtty_rx[i-16]);
+       else if(i < 24)                 iopi->p_hwi[i] (signal_irq_false);
+       else if(i < 24+NB_TTY_CHANNELS) iopi->p_hwi[i] (signal_irq_false);
+//     else if(i < 24+NB_TTY_CHANNELS) iopi->p_hwi[i] (signal_irq_mtty_tx[i-24]);
+       else                            iopi->p_hwi[i] (signal_irq_false);
     }
 
+    std::cout << "  - IOPIC connected" << std::endl;
+
+    
     // IOB0 cluster connexion to IOX network
-    (*clusters[0][0]->p_vci_iob_iox_ini)                     (signal_vci_ini_iob0);
-    (*clusters[0][0]->p_vci_iob_iox_tgt)                     (signal_vci_tgt_iob0);
-
-    // IOB1 cluster connexion to IOX network
-    (*clusters[XMAX-1][YMAX-1]->p_vci_iob_iox_ini)           (signal_vci_ini_iob1);
-    (*clusters[XMAX-1][YMAX-1]->p_vci_iob_iox_tgt)           (signal_vci_tgt_iob1);
+    (*clusters[0][0]->p_vci_iob_iox_ini)               (signal_vci_ini_iob0);
+    (*clusters[0][0]->p_vci_iob_iox_tgt)               (signal_vci_tgt_iob0);
+
+    // IOB1 cluster connexion to IOX network 
+    // (only when there is more than 1 cluster)
+    if ( cluster_iob0 != cluster_iob1 )
+    {
+        (*clusters[XMAX-1][YMAX-1]->p_vci_iob_iox_ini) (signal_vci_ini_iob1);
+        (*clusters[XMAX-1][YMAX-1]->p_vci_iob_iox_tgt) (signal_vci_tgt_iob1);
+    }
 
     // All clusters Clock & RESET connexions
@@ -1290,5 +1367,5 @@
       }
 
-      if( y == YMAX-1 )   // handling IOB to RAM network connection in cluster_iob1
+      if( (y == YMAX-1) and (cluster_iob0 != cluster_iob1) )  // handling IOB to RAM network connection in cluster_iob1
       {
          (*clusters[XMAX-1][YMAX-1]->p_dspin_iob_cmd_out)     (signal_dspin_cmd_iob1_loopback); 
@@ -1354,4 +1431,13 @@
    signal_irq_false = false;
 
+   // only one cluster case:
+   if ( cluster_iob0 == cluster_iob1 )
+   {
+      signal_vci_ini_iob1.cmdval = false;
+      signal_vci_ini_iob1.rspack = true;
+      signal_vci_tgt_iob1.cmdack = true;
+      signal_vci_tgt_iob1.rspval = false;
+   }
+      
    // network boundaries signals
    for (size_t x = 0; x < XMAX ; x++)
@@ -1393,6 +1479,9 @@
     signal_resetn = true;
 
+
+    // simulation loop
     struct timeval t1,t2;
     gettimeofday(&t1, NULL);
+
     for (size_t n = 1; n < ncycles; n++)
     {
@@ -1485,4 +1574,5 @@
                 smemc_ini << "[SIG]MEMC_INI_" << x << "_" << y;
                 clusters[x][y]->signal_ram_vci_ini_memc.print_trace(smemc_ini.str());
+
                 clusters[x][y]->xram->print_trace();
                 std::ostringstream sxram_tgt;
@@ -1491,12 +1581,19 @@
             }
 
-            // trace RAM network routers
-//          for( size_t cluster = 0 ; cluster < XMAX*YMAX ; cluster++ )
-//          {
-//              size_t x = cluster / YMAX;
-//              size_t y = cluster % YMAX;
-//              clusters[x][y]->ram_router_cmd->print_trace();
-//              clusters[x][y]->ram_router_rsp->print_trace();
-//          }
+
+            // trace XRAM and XRAM network routers in cluster[debug_xram_id]
+            if ( debug_xram_id != 0xFFFFFFFF )
+            {
+                size_t x = debug_xram_id >> 4;
+                size_t y = debug_xram_id & 0xF;
+            
+                clusters[x][y]->xram->print_trace();
+                std::ostringstream sxram_tgt;
+                sxram_tgt << "[SIG]XRAM_TGT_" << x << "_" << y;
+                clusters[x][y]->signal_ram_vci_tgt_xram.print_trace(sxram_tgt.str());
+
+                clusters[x][y]->ram_router_cmd->print_trace();
+                clusters[x][y]->ram_router_rsp->print_trace();
+            }
         
             // trace iob, iox and external peripherals  
@@ -1514,25 +1611,29 @@
 //              signal_dspin_rsp_iob0_loopback.print_trace("[SIG]IOB0_RSP_LOOPBACK"); 
 
-                cdma->print_trace();
-                signal_vci_tgt_cdma.print_trace("[SIG]IOX_CDMA_TGT");
-                signal_vci_ini_cdma.print_trace("[SIG]IOX_CDMA_INI");
-
-//              brom->print_trace();
-//              signal_vci_tgt_brom.print_trace("[SIG]IOX_BROM_TGT");
+//              cdma->print_trace();
+//              signal_vci_tgt_cdma.print_trace("[SIG]IOX_CDMA_TGT");
+//              signal_vci_ini_cdma.print_trace("[SIG]IOX_CDMA_INI");
+
+                brom->print_trace();
+                signal_vci_tgt_brom.print_trace("[SIG]IOX_BROM_TGT");
 
 //              mtty->print_trace();
 //              signal_vci_tgt_mtty.print_trace("[SIG]IOX_MTTY_TGT");
 
-//              bdev->print_trace();
-//              signal_vci_tgt_bdev.print_trace("[SIG]IOX_BDEV_TGT");
-//              signal_vci_ini_bdev.print_trace("[SIG]IOX_BDEV_INI");
+                bdev->print_trace();
+                signal_vci_tgt_bdev.print_trace("[SIG]BDEV_TGT");
+                signal_vci_ini_bdev.print_trace("[SIG]BDEV_INI");
 
 //              fbuf->print_trace();
 //              signal_vci_tgt_fbuf.print_trace("[SIG]FBUF");
 
+                iopi->print_trace();
+                signal_vci_ini_iopi.print_trace("[SIG]IOPI_INI");
+                signal_vci_tgt_iopi.print_trace("[SIG]IOPI_TGT");
                 iox_network->print_trace();
 
                 // interrupts
-                if (signal_irq_bdev) std::cout << "### IRQ_BDEV ACTIVATED" << std::endl;
+                if (signal_irq_bdev)       std::cout << "### IRQ_BDEV ACTIVE" << std::endl;
+                if (signal_irq_mtty_rx[0]) std::cout << "### IRQ_MTTY ACTIVE" << std::endl;
             }
         }
Index: trunk/platforms/tsar_generic_iob/top.desc
===================================================================
--- trunk/platforms/tsar_generic_iob/top.desc	(revision 706)
+++ trunk/platforms/tsar_generic_iob/top.desc	(revision 707)
@@ -64,4 +64,8 @@
                   cell_size = vci_cell_size_ext),
 
+            # IOPIC
+            Uses('caba:vci_iopic', 
+                  cell_size = vci_cell_size_ext),
+
 	        Uses('common:elf_file_loader'),
             Uses('common:plain_file_loader'),
Index: trunk/platforms/tsar_generic_iob/tsar_iob_cluster/caba/source/include/tsar_iob_cluster.h
===================================================================
--- trunk/platforms/tsar_generic_iob/tsar_iob_cluster/caba/source/include/tsar_iob_cluster.h	(revision 706)
+++ trunk/platforms/tsar_generic_iob/tsar_iob_cluster/caba/source/include/tsar_iob_cluster.h	(revision 707)
@@ -61,7 +61,4 @@
     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
     soclib::caba::DspinOutput<dspin_int_cmd_width>**   p_dspin_int_cmd_out;
Index: trunk/platforms/tsar_generic_iob/tsar_iob_cluster/caba/source/src/tsar_iob_cluster.cpp
===================================================================
--- trunk/platforms/tsar_generic_iob/tsar_iob_cluster/caba/source/src/tsar_iob_cluster.cpp	(revision 706)
+++ trunk/platforms/tsar_generic_iob/tsar_iob_cluster/caba/source/src/tsar_iob_cluster.cpp	(revision 707)
@@ -110,10 +110,4 @@
         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
-    if ( cluster_id == cluster_iob0 )
-    {
-        for ( size_t n=0 ; n<32 ; n++ ) p_irq[n] = new sc_in<bool>;
     }
 
@@ -192,5 +186,5 @@
                      32,                                // number of hard IRQs
                      32,                                // number of soft IRQs
-                     nb_procs);                         // number of output IRQs
+                     32);                               // number of output IRQs
 
     ////////////  MDMA
@@ -241,5 +235,4 @@
                      s_int_dspin_tgt_wrapper_gate_d.str().c_str(),
                      x_width + y_width + l_width);
-
 
     ////////////  Coherence LOCAL_XBAR(S)
@@ -283,5 +276,5 @@
                      1, 1,                         // fifo depths
                      true,                         // CMD
-                     false,                        // don't use local routing table
+                     false,                        // no routing table
                      false);                       // broadcast
 
@@ -359,10 +352,8 @@
         size_t iox_local_id;
         size_t global_id;
-        bool   has_irqs;
         if ( cluster_id == cluster_iob0 ) 
         {
             iox_local_id = 0;
             global_id    = cluster_iob0;
-            has_irqs     = true;
         }
         else
@@ -370,5 +361,4 @@
             iox_local_id = 1;
             global_id    = cluster_iob1;
-            has_irqs     = false;
         }
 
@@ -384,5 +374,4 @@
                      IntTab( global_id, iobx_int_srcid ),  // INT SRCID
                      IntTab( global_id, iox_local_id   ),  // IOX TGTID
-                     has_irqs, 
                      16,                                   // cache line words
                      8,                                    // IOTLB ways
@@ -511,8 +500,9 @@
         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++)
+
+        for ( size_t j = 0 ; j < 6 ; j++)
         {
-            proc[p]->p_irq[j]                    (signal_false);
+            if ( j < 4 ) proc[p]->p_irq[j]       (signal_proc_it[4*p + j]);
+            else         proc[p]->p_irq[j]       (signal_false);
         }
     }
@@ -522,5 +512,5 @@
     xicu->p_resetn                               (this->p_resetn);
     xicu->p_vci                                  (signal_int_vci_tgt_xicu);
-    for ( size_t p=0 ; p<nb_procs ; p++)
+    for ( size_t p=0 ; p < 32  ; p++)
     {
         xicu->p_irq[p]                           (signal_proc_it[p]);
@@ -528,8 +518,7 @@
     for ( size_t i=0 ; i<32 ; i++)
     {
-        if (cluster_id == cluster_iob0) 
-            xicu->p_hwi[i]                       (*(this->p_irq[i]));
-        else  
-            xicu->p_hwi[i]                       (signal_false);
+        if      ( i == 0 )       xicu->p_hwi[i]  (signal_irq_memc);
+        else if ( i <= nb_dmas ) xicu->p_hwi[i]  (signal_irq_mdma[i-1]);
+        else                     xicu->p_hwi[i]  (signal_false);
     }                     
 
@@ -572,19 +561,19 @@
 
     //////////////////////////// RAM network CMD & RSP routers
-    ram_router_cmd->p_clk                    (this->p_clk);
-    ram_router_cmd->p_resetn                 (this->p_resetn);
-    ram_router_rsp->p_clk                    (this->p_clk);
-    ram_router_rsp->p_resetn                 (this->p_resetn);
+    ram_router_cmd->p_clk                        (this->p_clk);
+    ram_router_cmd->p_resetn                     (this->p_resetn);
+    ram_router_rsp->p_clk                        (this->p_clk);
+    ram_router_rsp->p_resetn                     (this->p_resetn);
     for( size_t n=0 ; n<4 ; n++)
     {
-        ram_router_cmd->p_out[n]             (this->p_dspin_ram_cmd_out[n]);
-        ram_router_cmd->p_in[n]              (this->p_dspin_ram_cmd_in[n]);
-        ram_router_rsp->p_out[n]             (this->p_dspin_ram_rsp_out[n]);
-        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);
+        ram_router_cmd->p_out[n]                 (this->p_dspin_ram_cmd_out[n]);
+        ram_router_cmd->p_in[n]                  (this->p_dspin_ram_cmd_in[n]);
+        ram_router_rsp->p_out[n]                 (this->p_dspin_ram_rsp_out[n]);
+        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. 
@@ -600,8 +589,4 @@
         iob->p_vci_ini_ram                       (signal_ram_vci_ini_iobx);
 
-        if ( cluster_id == cluster_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);
