Index: /trunk/platforms/tsarv4_generic_xbar/Makefile
===================================================================
--- /trunk/platforms/tsarv4_generic_xbar/Makefile	(revision 154)
+++ /trunk/platforms/tsarv4_generic_xbar/Makefile	(revision 154)
@@ -0,0 +1,8 @@
+
+simulator.x: top.cpp top.desc
+	soclib-cc -P -p top.desc -I. -b caba:vci_local_crossbar -o simul.x
+
+clean:
+	soclib-cc -x -p top.desc -I.
+	rm -rf *.o *.x tty*
+
Index: /trunk/platforms/tsarv4_generic_xbar/soclib.conf
===================================================================
--- /trunk/platforms/tsarv4_generic_xbar/soclib.conf	(revision 154)
+++ /trunk/platforms/tsarv4_generic_xbar/soclib.conf	(revision 154)
@@ -0,0 +1,1 @@
+config.default = config.systemcass
Index: /trunk/platforms/tsarv4_generic_xbar/soft_filter/Makefile
===================================================================
--- /trunk/platforms/tsarv4_generic_xbar/soft_filter/Makefile	(revision 154)
+++ /trunk/platforms/tsarv4_generic_xbar/soft_filter/Makefile	(revision 154)
@@ -0,0 +1,46 @@
+LD=mipsel-unknown-elf-ld
+CC=mipsel-unknown-elf-gcc
+AS=mipsel-unknown-elf-as
+DU=mipsel-unknown-elf-objdump
+
+OBJS=   reset.o \
+	giet.o \
+	isr.o \
+	drivers.o \
+	stdio.o \
+	main.o
+
+CFLAGS= -Wall -mno-gpopt -ffreestanding -fomit-frame-pointer -mips32 -ggdb
+
+GIET=	/Users/alain/Documents/licence/almo/soft/giet
+
+bin.soft: $(OBJS) ldscript
+	$(LD) -o $@ -T ldscript $(OBJS)
+	$(DU) -D $@ > $@.txt
+
+reset.o: reset.s
+	$(AS) -g -mips32 -o $@ $<
+	$(DU) -D $@ > $@.txt
+
+giet.o: $(GIET)/giet.s
+	$(AS) -g -mips32 -o $@ $<
+	$(DU) -D $@ > $@.txt
+
+isr.o: $(GIET)/isr.c
+	$(CC) $(CFLAGS) -c -o $@ $<
+	$(DU) -D $@ > $@.txt
+
+stdio.o: $(GIET)/stdio.c
+	$(CC) $(CFLAGS) -c -o $@ $<
+	$(DU) -D $@ > $@.txt
+
+drivers.o: $(GIET)/drivers.c
+	$(CC) $(CFLAGS) -c -o $@ $<
+	$(DU) -D $@ > $@.txt
+
+main.o: main.c
+	$(CC) $(CFLAGS) -I$(GIET) -c -o $@ $<
+	$(DU) -D $@ > $@.txt
+
+clean:
+	rm -f *.o bin.soft *.txt core *~ proc* term* temp
Index: /trunk/platforms/tsarv4_generic_xbar/soft_filter/ldscript
===================================================================
--- /trunk/platforms/tsarv4_generic_xbar/soft_filter/ldscript	(revision 154)
+++ /trunk/platforms/tsarv4_generic_xbar/soft_filter/ldscript	(revision 154)
@@ -0,0 +1,90 @@
+/**********************************************************
+	File : ldscript 
+	Author : Alain Greiner
+	Date : March 2011  
+**********************************************************/
+
+/* definition of various hardware parameters.
+These variables are referenced in the drivers.c file,
+and must be defined, even if the corresponding
+peripherals are not present in the architecture */
+
+NB_CLUSTERS		= 16;		/* number of clusters */
+NB_PROCS		= 4;		/* number of processors per cluster */
+NB_TASKS		= 1;		/* number of tasks per processor */
+NB_TIMERS       	= 1;		/* max number of timers per processor */
+NB_LOCKS        	= 8;		/* number of spin_locks */
+
+/* definition of the base address for all segments 
+The peripherals base addresses are referenced by the
+software drivers and must be defined, even if the 
+peripherals are not present in the architecture */
+
+seg_code_base   = 0x00000000;       /* le code utilisateur */ 
+seg_data_base   = 0x00100000;       /* les données utilisateur */
+
+seg_heap_base   = 0x00300000;       /* le tas utilisateur */
+seg_stack_base  = 0x00800000;       /* la pile utilisateur */
+
+seg_kcode_base  = 0x80000000;       /* le code du système */
+seg_kdata_base  = 0x80100000;       /* les donnees du système */
+seg_kunc_base   = 0x80200000;       /* les données non cachées du système */
+
+seg_icu_base    = 0x00F00000;       /* controleur ICU */
+seg_tty_base    = 0x00F10000;       /* controleur TTY */
+seg_dma_base    = 0x00F20000;       /* controleur DMA */
+
+seg_reset_base  = 0xBFC00000;       /* le code de boot */
+seg_fb_base     = 0xBFD00000;       /* controleur FRAME BUFFER */
+seg_ioc_base    = 0xBFF30000;       /* controleur I/O */
+
+seg_timer_base  = 0xBFF40000;       /* controleur TIMER */
+seg_gcd_base    = 0xBFF50000;       /* controleur GCD */
+
+/* Grouping sections into segments */
+
+SECTIONS
+{
+   . = seg_kcode_base;
+   seg_kcode : {
+      *(.giet)
+      *(.switch)
+      *(.drivers)
+      *(.isr)
+   } 
+   . = seg_kdata_base;
+   seg_kdata : {
+      *(.kdata)
+   } 
+   . = seg_kunc_base;
+   seg_kunc : {
+      *(.unckdata)
+   } 
+   . = seg_kdata_base;
+   seg_kdata : {
+      *(.ksave)
+   } 
+   . = seg_code_base;
+   seg_code : {
+      *(.text)
+   } 
+   . = seg_reset_base;
+   seg_reset : {
+      *(.reset)
+   } 
+   . = seg_data_base;
+   seg_data : {
+      *(.rodata)
+      . = ALIGN(4);
+      *(.rodata.*)
+      . = ALIGN(4);
+      *(.data)
+      . = ALIGN(4);
+      *(.sdata)
+      . = ALIGN(4);
+      *(.bss)
+      *(COMMON)
+      *(.sbss)
+   } 
+}
+
Index: /trunk/platforms/tsarv4_generic_xbar/soft_filter/main.c
===================================================================
--- /trunk/platforms/tsarv4_generic_xbar/soft_filter/main.c	(revision 154)
+++ /trunk/platforms/tsarv4_generic_xbar/soft_filter/main.c	(revision 154)
@@ -0,0 +1,365 @@
+#include "stdio.h"
+
+////////////////////////////////////
+// Image parameters
+
+#define PIXEL_SIZE	2
+#define NL		1024
+#define NP		1024
+#define BLOCK_SIZE	1512
+
+#define PRINTF		if(lid==0) tty_printf
+
+#define TA(c,l,p)  (A[c][((NP)*(l))+(p)])
+#define TB(c,p,l)  (B[c][((NL)*(p))+(l)])
+#define TC(c,l,p)  (C[c][((NP)*(l))+(p)])
+#define TD(c,l,p)  (D[c][((NP)*(l))+(p)])
+
+#define max(x,y) ((x) > (y) ? (x) : (y))
+#define min(x,y) ((x) < (y) ? (x) : (y))
+
+///////////////////////////////////////////
+// tricks to read parameters from ldscript
+///////////////////////////////////////////
+
+struct plaf;
+
+extern struct plaf seg_heap_base;
+extern struct plaf NB_PROCS;
+extern struct plaf NB_CLUSTERS;
+
+/////////////
+void main()
+{
+
+//////////////////////////////////
+// convolution kernel parameters
+// The content of this section is
+// Philips proprietary information.
+///////////////////////////////////
+
+    int	vrange = 17;
+    int	vnorm  = 115;
+    int	vf[35];
+    vf[0]  = 1;
+    vf[1]  = 1;
+    vf[2]  = 2;
+    vf[3]  = 2;
+    vf[4]  = 2;
+    vf[5]  = 2;
+    vf[6]  = 3;
+    vf[7]  = 3;
+    vf[8]  = 3;
+    vf[9]  = 4;
+    vf[10] = 4;
+    vf[11] = 4;
+    vf[12] = 4;
+    vf[13] = 5;
+    vf[14] = 5;
+    vf[15] = 5;
+    vf[16] = 5;
+    vf[17] = 5;
+    vf[18] = 5;
+    vf[19] = 5;
+    vf[20] = 5;
+    vf[21] = 5;
+    vf[22] = 4;
+    vf[23] = 4;
+    vf[24] = 4;
+    vf[25] = 4;
+    vf[26] = 3;
+    vf[27] = 3;
+    vf[28] = 3;
+    vf[29] = 2;
+    vf[30] = 2;
+    vf[31] = 2;
+    vf[32] = 2;
+    vf[33] = 1;
+    vf[34] = 1;
+
+    int hrange = 100;
+    int hnorm  = 201;
+
+    unsigned int date      = 0;
+    unsigned int delta     = 0;
+
+    int c;                                              	// cluster index for loops
+    int l;                                              	// line index for loops
+    int p;                                              	// pixel index for loops
+    int x;                                              	// filter index for loops
+
+    int pid                 = procid();                         // processor id
+    int nprocs              = (unsigned int)&NB_PROCS;          // number of processors per cluster
+    int nclusters           = (unsigned int)&NB_CLUSTERS;       // number of clusters
+    int lid                 = pid%nprocs;                       // local processor id
+    int cid                 = pid/nprocs;                       // local processor id
+    int base                = (unsigned int)&seg_heap_base;     // base address for shared buffers
+    int increment           = (0x80000000 / nclusters) * 2;     // cluster increment
+    int ntasks              = nclusters * nprocs;               // number of tasks
+    int nblocks             = (NP*NL*PIXEL_SIZE)/BLOCK_SIZE;  	// number of blocks per image 
+
+    int lines_per_task      = NL/ntasks;			// number of lines per task
+    int lines_per_cluster   = NL/nclusters;			// number of lines per cluster
+    int columns_per_task    = NP/ntasks;			// number of columns per task
+    int columns_per_cluster = NP/nclusters;			// number of columns per cluster
+
+    PRINTF("\n *** Processor %d entering main at cycle %d ***\n\n", pid, proctime());
+    
+    //////////////////////////
+    //  parameters checking
+    if( (nprocs != 1) && (nprocs != 2) && (nprocs != 4) )
+    {
+        PRINTF("NB_PROCS must be 1, 2 or 4\n");
+        while(1);
+    }
+    if( (nclusters !=  4) && (nclusters !=  8) && (nclusters != 16) && 
+        (nclusters != 32) && (nclusters != 64) && (nclusters !=128) && (nclusters != 256) )
+    {
+        PRINTF("NB_CLUSTERS must be a power of 2 between 4 and 256\n");
+        while(1);
+    }
+    if( pid >= ntasks )
+    {
+        PRINTF("processor id %d larger than NB_CLUSTERS*NB_PROCS\n", pid);
+        while(1);
+    }
+    if ( NL % nclusters != 0 )
+    {
+        PRINTF("NB_CLUSTERS must be a divider of NL");
+        while(1);
+    }
+    if( NP % nclusters != 0 )
+    {
+        PRINTF("NB_CLUSTERS must be a divider of NP");
+        while(1);
+    }
+
+    //////////////////////////////////////////////////////////////////
+    // Arrays of pointers on the shared, distributed buffers  
+    // containing the images (sized for the worst case : 256 clusters)
+    unsigned short*	A[256];
+    int*		B[256];
+    int*		C[256];
+    int*		D[256];
+    
+    // The shared, distributed buffers addresses are computed
+    // from the seg_heap_base value defined in the ldscript file
+    // and from the cluster increment = 4Gbytes/nclusters.
+    // These arrays of pointers are identical and
+    // replicated in the stack of each task 
+    for( c=0 ; c<nclusters ; c++)
+    {
+        A[c] = (unsigned short*)(base + increment*c);
+        B[c] = (int*)(base + 4*NP*NL/nclusters + increment*c);
+        C[c] = (int*)(base + 8*NP*NL/nclusters + increment*c);
+        D[c] = (int*)(base + 12*NP*NL/nclusters + increment*c);
+    }
+
+    unsigned char* line_buf = (unsigned char*)(base + 2*NP*NL/nclusters + increment*c);
+    
+    PRINTF("NCLUSTERS = %d\n", nclusters); 
+    PRINTF("NPROCS    = %d\n\n", nprocs); 
+
+    PRINTF("*** starting barrier init at cycle %d ***\n", proctime());
+
+    //  barriers initialization
+    barrier_init(0, ntasks);
+    barrier_init(1, ntasks);
+    barrier_init(2, ntasks);
+
+    PRINTF("*** completing barrier init at cycle %d ***\n", proctime());
+
+    ////////////////////////////////////////////////////////
+    // pseudo parallel load from disk to A[c] buffers
+    // only task running on processor with (lid==0) does it
+    // nblocks/nclusters are loaded in each cluster
+
+    if ( lid == 0 )
+    {
+        delta = proctime() - date;
+        date  = date + delta;
+        PRINTF("\n *** Starting load at cycle %d (%d)\n", date, delta);
+
+        if( ioc_read(nblocks*cid/nclusters, 
+                     A[cid] , 
+                     nblocks/nclusters) )
+        {
+            PRINTF("echec ioc_read\n");
+            while(1);
+        }
+        if ( ioc_completed() )
+        {
+            PRINTF("echec ioc_completed\n");
+            while(1);
+        }
+
+        delta = proctime() - date;
+        date  = date + delta;
+        PRINTF(" *** Completing load at cycle %d (%d)\n", date, delta);
+    }
+
+    barrier_wait(0);
+
+    //////////////////////////////////////////////////////////
+    // parallel horizontal filter : 
+    //  B <= transpose(FH(A))
+    //  D <= A - FH(A)
+    // each task computes (NL/ntasks) lines 
+
+    delta = proctime() - date;
+    date  = date + delta;
+    PRINTF("\n *** starting horizontal filter at cycle %d (%d)\n", date, delta);
+
+    // l = line index in the cluster / p = pixel index 
+    for ( l = lines_per_task*lid ; l < lines_per_task*(lid+1) ; l++)
+    {
+        // The image must be extended :
+        // if (p<0) 	TA(cid,l,p) == TA(cid,l,0)
+        // if (p>NP-1)	TA(cid,l,p) == TA(cid,l,NL-1)
+        // We use the spécific values of the horizontal ep-filter for optimisation:
+        // sum(p) = sum(p-1) + TA[p+hrange] - TA[p-hrange-1]
+        // To minimize the number of tests, the loop on pixels is split in three domains 
+
+        int sum = (hrange+2)*TA(cid,l,0);
+        for ( x = 1 ; x < hrange ; x++) sum = sum + TA(cid,l,x);
+
+        // first domain : from 0 to hrange
+        for ( p = 0 ; p < hrange+1 ; p++)
+        {
+            sum = sum + TA(cid,l,p+hrange) - TA(cid,l,0);
+            TB((p/columns_per_cluster),(p%columns_per_cluster),(cid*lines_per_cluster+l)) = sum/hnorm;
+            TD(cid,l,p) = TA(cid,l,p) - sum/hnorm;
+        }
+        // second domain : from (hrange+1) to (NP-hrange-1)
+        for ( p = hrange+1 ; p < NP-hrange ; p++)
+        {
+            sum = sum + TA(cid,l,p+hrange) - TA(cid,l,p-hrange-1);
+            TB((p/columns_per_cluster),(p%columns_per_cluster),(cid*lines_per_cluster+l)) = sum/hnorm;
+            TD(cid,l,p) = TA(cid,l,p) - sum/hnorm;
+        }
+        // third domain : from (NP-hrange) to (NP-1)
+        for ( p = NP-hrange ; p < NP ; p++)
+        {
+            sum = sum + TA(cid,l,NP-1) - TA(cid,l,p-hrange-1);
+            TB((p/columns_per_cluster),(p%columns_per_cluster),(cid*lines_per_cluster+l)) = sum/hnorm;
+            TD(cid,l,p) = TA(cid,l,p) - sum/hnorm;
+        }
+
+        PRINTF(" - line %d computed at cycle %d\n", l, proctime());
+    }
+
+    delta = proctime() - date;
+    date  = date + delta;
+    PRINTF(" *** completing horizontal filter at cycle %d (%d)\n", date, delta);
+
+    barrier_wait(1);
+
+    //////////////////////////////////////////////////////////
+    // parallel vertical filter : 
+    //  C <= transpose(FV(B))
+    // each processor computes (NP/ntasks) columns
+
+    delta = proctime() - date;
+    date  = date + delta;
+    PRINTF("\n *** starting vertical filter at cycle %d (%d)\n", date, delta);
+
+    // l = line index / p = column index in the cluster
+    for ( p = columns_per_task*lid ; p < columns_per_task*(lid+1) ; p++)
+    {
+        unsigned int sum = 0;
+
+        // The image must be extended :
+        // if (l<0) 	TB(cid,p,x) == TB(cid,p,0)
+        // if (l>NL-1)	TB(cid,p,x) == TB(cid,p,NL-1)
+        // We use the spécific values of the vertical ep-filter
+        // To minimize the number of tests, the NL lines are split in three domains 
+
+        // first domain
+        for ( l = 0 ; l < vrange ; l++)
+        {
+            for ( x = 0 ; x < (2*vrange+1) ; x++ )
+            {
+                sum = sum + vf[x] * TB(cid,p,max(l-vrange+x,0));
+            }
+            TC((l/lines_per_cluster),(l%lines_per_cluster),(cid*columns_per_cluster+p)) = sum/vnorm;
+        }
+        // second domain
+        for ( l = vrange ; l < NL-vrange ; l++ )
+        {
+            sum = sum + TB(cid,p,l+4)
+                      + TB(cid,p,l+8)
+                      + TB(cid,p,l+11)
+                      + TB(cid,p,l+15)
+                      + TB(cid,p,l+17)
+                      - TB(cid,p,l-5)
+                      - TB(cid,p,l-9)
+                      - TB(cid,p,l-12)
+                      - TB(cid,p,l-16)
+                      - TB(cid,p,max(l-18,0));
+            TC((l/lines_per_cluster),(l%lines_per_cluster),(cid*columns_per_cluster+p)) = sum/vnorm;
+        }
+        // third domain
+        for ( l = NL-vrange ; l < NL ; l++ )
+        {
+            sum = sum + TB(cid,p,min(l+5,NL-1))
+                      + TB(cid,p,min(l+9,NL-1))
+                      + TB(cid,p,min(l+12,NL-1))
+                      + TB(cid,p,min(l+16,NL-1))
+                      + TB(cid,p,min(l+18,NL-1))
+                      - TB(cid,p,l-4)
+                      - TB(cid,p,l-8)
+                      - TB(cid,p,l-11)
+                      - TB(cid,p,l-15)
+                      - TB(cid,p,l-17);
+            TC((l/lines_per_cluster),(l%lines_per_cluster),(cid*columns_per_cluster+p)) = sum/vnorm;
+        }
+
+        PRINTF(" - column %d computed at cycle %d\n", p, proctime());
+    }
+
+    delta = proctime() - date;
+    date  = date + delta;
+    PRINTF(" *** completing vertical filter at cycle %d (%d)\n", date, delta);
+
+    barrier_wait(2);
+
+    ////////////////////////////////////////////////////////////////////////////
+    // final computation and parallel display using the distributed DMA
+    // D <= D + C
+    // Each processor use its private DMA channel to display 
+    // the resulting image, line  per line (one byte per pixel).
+    // Eah processor computes & displays (NL/ntasks) lines. 
+
+    delta = proctime() - date;
+    date  = date + delta;
+    PRINTF("\n *** final computation and display at cycle %d (%d)\n", date, delta);
+
+    for ( l = 0 ; l < lines_per_task ; l++)
+    {
+        for ( p = 0 ; p < NP ; p++)
+        {
+            TD(cid,l,p) = TD(cid,l,p) + TC(cid,l,p);
+            line_buf[p] = (unsigned char)(TD(cid,l,p));
+        }
+        int xxx = ( fb_write( NP*(cid*lines_per_cluster+lid*lines_per_task+l), line_buf, NP) );
+        if ( xxx )
+        {
+            PRINTF("echec fb_write = %d\n", xxx);
+            while(1);
+        }
+        if ( fb_completed() )
+        {
+            PRINTF("echec fb_completed\n");
+            while(1);
+        }
+        PRINTF(" - line %d displayed at cycle %d\n", l, proctime());
+    }
+
+    delta = proctime() - date;
+    date  = date + delta;
+    PRINTF(" *** completing display at cycle %d (%d)\n", date, delta);
+
+    while(1);
+
+} // end main()
+
Index: /trunk/platforms/tsarv4_generic_xbar/soft_filter/reset.s
===================================================================
--- /trunk/platforms/tsarv4_generic_xbar/soft_filter/reset.s	(revision 154)
+++ /trunk/platforms/tsarv4_generic_xbar/soft_filter/reset.s	(revision 154)
@@ -0,0 +1,134 @@
+#################################################################################
+#	File : reset.s
+#	Author : Alain Greiner
+#	Date : 15/04/2011
+#################################################################################
+# 	This is a boot code for a generic multi-clusters / multi-processors
+#       TSAR architecture (up to 256 clusters / up to 4  processors per cluster). 
+#       There is one XICU, one TTY, one DMA and one stack segment per cluster.
+#       segment base adresses = base + cluster_segment_increment*cluster_id
+#	- Each processor initializes the stack pointer ($29) depending on pid.
+#	- Only processor 0 initializes the Interrupt vector (TTY, DMA & IOC).
+#       - Each processor initialises its private ICU mask register.
+#	- Each processor initializes the Status Register (SR) 
+#	- Each processor initializes the EPC register, and jumps to the main 
+#	  address in kernel mode...
+#################################################################################
+		
+	.section .reset,"ax",@progbits
+
+	.extern	seg_stack_base
+	.extern	seg_icu_base
+	.extern _interrupt_vector
+	.extern _isr_tty_get
+	.extern _isr_dma
+	.extern _isr_ioc
+
+        .extern NB_PROCS
+        .extern NB_CLUSTERS
+
+	.globl  reset	 			# makes reset an external symbol 
+	.ent	reset
+	.align	2
+
+reset:
+       	.set noreorder
+
+# computes proc_id, local_id, cluster_id, and cluster_increment
+    mfc0    $26,    $15,    1
+    andi    $10,    $26,    0x3FF	# $10 <= proc_id (at most 1024 processors)
+    la      $26,    NB_PROCS		# $26 <= number of processors per cluster
+    divu    $10,    $26
+    mfhi    $11                 	# $11 <= local_id = proc_id % NB_PROCS
+    mflo    $12              		# $12 <= cluster_id = proc_id / NB_PROCS
+    la      $26,    NB_CLUSTERS
+    li      $13,    0x80000000
+    divu    $13,    $26
+    mflo    $14
+    sll     $14,    1			# $14 <= cluster_increment = 4G / NB_CLUSTERS
+    mult    $14,    $12	
+    mflo    $13                 	# $13 <= cluster_id * cluster_increment
+
+# initializes stack pointer depending on both the local_id and the cluster_id
+    la      $27,    seg_stack_base
+    addu    $27,    $27,    $13		# $27 <= seg_stack_base + cluster_id * increment
+    li      $26,    0x10000		# $26 <= 64K
+    addi    $25,    $11,    1		# $25 <= local_id + 1
+    mult    $25,    $26
+    mflo    $24				# $24 <= 64K * (local_id+1)
+    addu    $29,    $27,    $24		# $29 <= seg_stack_base + (cluster_id*increment) + (local_id+1)*64K
+
+# in each cluster, each processor initializes its private XICU mask register
+# in each cluster, the ICU base address depends on the cluster_id
+    la      $20,    seg_icu_base
+    addu    $20,    $20,    $13		# $20 <= seg_icu_base + cluster_id*cluster_increment
+    la      $21,    _reset_switch
+    sll     $22,    $11,    2           # $22 <= local_id*4
+    addu    $23,    $21,    $22         # $23 <= &_reset_switch[local_id*4]
+    lw      $24,    0($23)
+    jr      $24
+    nop
+_reset_proc0:
+    li      $13,    0b010010000000      # offset for MSK_HWI_ENABLE & proc[0]
+    addu    $13,    $20,    $13
+    li      $27,    0x111		# TTY[0] DMA[0] IOC
+    sw      $27,    0($13)              # MASK[0]
+    j       _reset_itvector
+_reset_proc1:
+    li      $13,    0b010010000100      # offset for MSK_HWI_ENABLE & proc[1]
+    addu    $13,    $20,    $13
+    li      $27,    0x022		# TTY[1] DMA[1]
+    sw      $27,    0($13)              # MASK[1]
+    j       _reset_itvector
+_reset_proc2:
+    li      $13,    0b010010001000      # offset for MSK_HWI_ENABLE & proc[2]
+    addu    $13,    $20,    $13
+    li      $27,    0x044		# TTY[2] DMA[2]
+    sw      $27,    0($13)              # MASK[2]
+    j       _reset_itvector
+_reset_proc3:
+    li      $13,    0b010010001100      # offset for MSK_HWI_ENABLE & proc[3]
+    addu    $13,    $20,    $13
+    li      $27,    0x088		# TTY[3] DMA[3]
+    sw      $27,    0($13)              # MASK[3]
+    j       _reset_itvector
+    nop
+
+_reset_switch:
+    .word	_reset_proc0
+    .word	_reset_proc1
+    .word	_reset_proc2
+    .word	_reset_proc3
+
+# only processor 0 in cluster 0 initializes interrupt vector
+
+_reset_itvector:
+    bne	    $10,    $0,    _reset_end
+    la      $26,    _interrupt_vector   # interrupt vector address
+    la      $27,    _isr_tty_get 
+    sw      $27,    0($26)              # interrupt_vector[0] <= _isr_tty_get
+    sw      $27,    4($26)              # interrupt_vector[1] <= _isr_tty_get
+    sw      $27,    8($26)              # interrupt_vector[2] <= _isr_tty_get
+    sw      $27,   12($26)              # interrupt_vector[3] <= _isr_tty_get
+    la      $27,    _isr_dma 
+    sw      $27,   16($26)              # interrupt_vector[4] <= _isr_dma
+    sw      $27,   20($26)              # interrupt_vector[5] <= _isr_dma
+    sw      $27,   24($26)              # interrupt_vector[6] <= _isr_dma
+    sw      $27,   28($26)              # interrupt_vector[7] <= _isr_dma
+    la      $27,    _isr_ioc 
+    sw      $27,   32($26)              # interrupt_vector[8] <= _isr_ioc
+
+_reset_end:
+
+# initializes SR register
+    li	    $26,    0x0000FF01		
+    mtc0    $26,    $12			# SR <= kernel mode / IRQ enable 
+
+# jumps to main in kernel mode
+    la	    $26,    main
+    jr      $26
+    nop
+
+    .end	reset
+
+    .set reorder
Index: /trunk/platforms/tsarv4_generic_xbar/soft_transpose/Makefile
===================================================================
--- /trunk/platforms/tsarv4_generic_xbar/soft_transpose/Makefile	(revision 154)
+++ /trunk/platforms/tsarv4_generic_xbar/soft_transpose/Makefile	(revision 154)
@@ -0,0 +1,46 @@
+LD=mipsel-unknown-elf-ld
+CC=mipsel-unknown-elf-gcc
+AS=mipsel-unknown-elf-as
+DU=mipsel-unknown-elf-objdump
+
+OBJS=   reset.o \
+	giet.o \
+	isr.o \
+	drivers.o \
+	stdio.o \
+	main.o
+
+CFLAGS= -Wall -mno-gpopt -ffreestanding -fomit-frame-pointer -mips32 -ggdb
+
+GIET=	/Users/alain/Documents/licence/almo/soft/giet
+
+bin.soft: $(OBJS) ldscript
+	$(LD) -o $@ -T ldscript $(OBJS)
+	$(DU) -D $@ > $@.txt
+
+reset.o: reset.s
+	$(AS) -g -mips32 -o $@ $<
+	$(DU) -D $@ > $@.txt
+
+giet.o: $(GIET)/giet.s
+	$(AS) -g -mips32 -o $@ $<
+	$(DU) -D $@ > $@.txt
+
+isr.o: $(GIET)/isr.c
+	$(CC) $(CFLAGS) -c -o $@ $<
+	$(DU) -D $@ > $@.txt
+
+stdio.o: $(GIET)/stdio.c
+	$(CC) $(CFLAGS) -c -o $@ $<
+	$(DU) -D $@ > $@.txt
+
+drivers.o: $(GIET)/drivers.c
+	$(CC) $(CFLAGS) -c -o $@ $<
+	$(DU) -D $@ > $@.txt
+
+main.o: main.c
+	$(CC) $(CFLAGS) -I$(GIET) -c -o $@ $<
+	$(DU) -D $@ > $@.txt
+
+clean:
+	rm -f *.o bin.soft *.txt core *~ proc* term* temp
Index: /trunk/platforms/tsarv4_generic_xbar/soft_transpose/ldscript
===================================================================
--- /trunk/platforms/tsarv4_generic_xbar/soft_transpose/ldscript	(revision 154)
+++ /trunk/platforms/tsarv4_generic_xbar/soft_transpose/ldscript	(revision 154)
@@ -0,0 +1,90 @@
+/**********************************************************
+	File : ldscript 
+	Author : Alain Greiner
+	Date : March 2011  
+**********************************************************/
+
+/* definition of various hardware parameters.
+These variables are referenced in the drivers.c file,
+and must be defined, even if the corresponding
+peripherals are not present in the architecture */
+
+NB_CLUSTERS		= 32;		/* number of clusters */
+NB_PROCS		= 4;		/* number of processors per cluster */
+NB_TASKS		= 1;		/* number of tasks per processor */
+NB_TIMERS       	= 1;		/* max number of timers per processor */
+NB_LOCKS        	= 8;		/* number of spin_locks */
+
+/* definition of the base address for all segments 
+The peripherals base addresses are referenced by the
+software drivers and must be defined, even if the 
+peripherals are not present in the architecture */
+
+seg_code_base   = 0x00000000;       /* le code utilisateur */ 
+seg_data_base   = 0x00100000;       /* les données utilisateur */
+
+seg_heap_base   = 0x00300000;       /* le tas utilisateur */
+seg_stack_base  = 0x00800000;       /* la pile utilisateur */
+
+seg_kcode_base  = 0x80000000;       /* le code du système */
+seg_kdata_base  = 0x80100000;       /* les donnees du système */
+seg_kunc_base   = 0x80200000;       /* les données non cachées du système */
+
+seg_icu_base    = 0x00F00000;       /* controleur ICU */
+seg_tty_base    = 0x00F10000;       /* controleur TTY */
+seg_dma_base    = 0x00F20000;       /* controleur DMA */
+
+seg_reset_base  = 0xBFC00000;       /* le code de boot */
+seg_fb_base     = 0xBFD00000;       /* controleur FRAME BUFFER */
+seg_ioc_base    = 0xBFF30000;       /* controleur I/O */
+
+seg_timer_base  = 0xBFF40000;       /* controleur TIMER */
+seg_gcd_base    = 0xBFF50000;       /* controleur GCD */
+
+/* Grouping sections into segments */
+
+SECTIONS
+{
+   . = seg_kcode_base;
+   seg_kcode : {
+      *(.giet)
+      *(.switch)
+      *(.drivers)
+      *(.isr)
+   } 
+   . = seg_kdata_base;
+   seg_kdata : {
+      *(.kdata)
+   } 
+   . = seg_kunc_base;
+   seg_kunc : {
+      *(.unckdata)
+   } 
+   . = seg_kdata_base;
+   seg_kdata : {
+      *(.ksave)
+   } 
+   . = seg_code_base;
+   seg_code : {
+      *(.text)
+   } 
+   . = seg_reset_base;
+   seg_reset : {
+      *(.reset)
+   } 
+   . = seg_data_base;
+   seg_data : {
+      *(.rodata)
+      . = ALIGN(4);
+      *(.rodata.*)
+      . = ALIGN(4);
+      *(.data)
+      . = ALIGN(4);
+      *(.sdata)
+      . = ALIGN(4);
+      *(.bss)
+      *(COMMON)
+      *(.sbss)
+   } 
+}
+
Index: /trunk/platforms/tsarv4_generic_xbar/soft_transpose/main.c
===================================================================
--- /trunk/platforms/tsarv4_generic_xbar/soft_transpose/main.c	(revision 154)
+++ /trunk/platforms/tsarv4_generic_xbar/soft_transpose/main.c	(revision 154)
@@ -0,0 +1,188 @@
+#include "stdio.h"
+
+#define NL		128
+#define NP		128
+#define NB_IMAGES	2
+#define BLOCK_SIZE	128
+
+#define PRINTF		if(local_id == 0) tty_printf
+
+///////////////////////////////////////////
+// tricks to read parameters from ldscript
+///////////////////////////////////////////
+
+struct plaf;
+
+extern struct plaf seg_heap_base;
+extern struct plaf NB_PROCS;
+extern struct plaf NB_CLUSTERS;
+
+/////////////
+void main()
+{
+    unsigned int 	image     = 0;
+    unsigned int 	date      = 0;
+    unsigned int 	delta     = 0;
+
+    unsigned int	c;					  	// cluster index for loops
+    unsigned int	l;					  	// line index for loops
+    unsigned int	p;					  	// pixel index for loops
+
+    unsigned int	proc_id     = procid(); 		  	// processor id
+    unsigned int	nprocs 	    = (unsigned int)&NB_PROCS; 	  	// number of processors per cluster
+    unsigned int	nclusters   = (unsigned int)&NB_CLUSTERS;   	// number of clusters
+    unsigned int        local_id    = proc_id%nprocs;			// local processor id
+    unsigned int        cluster_id  = proc_id/nprocs;			// local processor id
+    unsigned int	base        = (unsigned int)&seg_heap_base; 	// base address for shared buffers
+    unsigned int	increment   = (0x80000000 / nclusters) * 2; 	// cluster increment
+    unsigned int	ntasks	    = nclusters * nprocs;		// number of tasks
+    unsigned int	nblocks     = (NP*NL) / BLOCK_SIZE;		// number of blocks per image 
+
+    PRINTF("\n *** Entering main at cycle %d ***\n\n", proctime());
+
+    //  parameters checking
+    if( (nprocs != 1) && (nprocs != 2) && (nprocs != 4) )
+    {
+        PRINTF("NB_PROCS must be 1, 2 or 4\n");
+
+        exit();
+    }
+    if( (nclusters !=  1) && (nclusters !=  2) && (nclusters !=  4) && (nclusters !=  8) &&
+        (nclusters != 16) && (nclusters != 32) && (nclusters != 64) && (nclusters !=128) )
+    {
+        PRINTF("NB_CLUSTERS must be a power of 2 between 1 and 128\n");
+        exit();
+    }
+    if( ntasks > 128 )
+    {
+        PRINTF("NB_PROCS * NB_CLUSTERS cannot be larger than 128 4\n");
+        exit();
+    }
+    if( proc_id >= ntasks )
+    {
+        PRINTF("processor id %d larger than NB_CLUSTERS*NB_PROCS\n", proc_id);
+    }
+
+    // Arrays of pointers on the shared, distributed buffers  
+    // containing the images (sized for the worst case : 128 clusters)
+    unsigned char*	A[128];
+    unsigned char*	B[128];
+    
+    // shared buffers address definition 
+    // from the seg_heap_base and segment_increment 
+    // values defined in the ldscript file.
+    // These arrays of pointers are identical and
+    // replicated in the stack of each task 
+    for( c=0 ; c<nclusters ; c++)
+    {
+        A[c] = (unsigned char*)(base + increment*c);
+        B[c] = (unsigned char*)(base + NL*NP + increment*c);
+    }
+
+    PRINTF("NB_CLUSTERS = %d\n", nclusters); 
+    PRINTF("NB_PROCS    = %d\n\n", nprocs); 
+
+    PRINTF("*** starting barrier init at cycle %d ***\n", proctime());
+
+    //  barriers initialization
+    barrier_init(0, ntasks);
+    barrier_init(1, ntasks);
+    barrier_init(2, ntasks);
+
+    PRINTF("*** completing barrier init at cycle %d ***\n", proctime());
+
+    // Main loop (on images)
+    while(image < NB_IMAGES) 
+    {
+        // pseudo parallel load from disk to A[c] buffer : nblocks/nclusters blocks
+        // only task running on processor with (local_id == 0) does it
+
+        delta = proctime() - date;
+        date  = date + delta;
+
+        if ( local_id == 0 )
+        {
+            PRINTF("\n*** Starting load for image %d *** at cycle %d (%d)\n", image, date, delta);
+
+            if( ioc_read(image*nblocks + nblocks*cluster_id/nclusters , A[cluster_id], nblocks/nclusters) )
+            {
+                tty_printf("echec ioc_read\n");
+                exit();
+            }
+            if ( ioc_completed() )
+            {
+                tty_printf("echec ioc_completed\n");
+                exit();
+            }
+            delta = proctime() - date;
+            date  = date + delta;
+            PRINTF("*** Completing load for image %d *** at cycle %d (%d)\n", image, date, delta);
+        }
+
+        barrier_wait(0);
+
+        // parallel transpose from A to B buffers
+	// each processor makes the transposition for (NL/ntasks) lines
+        // (p,l) are the (x,y) pixel coordinates in the source image
+
+        delta = proctime() - date;
+        date  = date + delta;
+
+        PRINTF("\n*** starting transpose for image %d at cycle %d (%d)\n", image, date, delta);
+
+        unsigned int nlt = NL/ntasks;
+
+        for ( l = nlt*local_id ; l < nlt*(local_id+1) ; l++)
+        {
+            PRINTF( "    - processing line %d at cycle %d\n", l + NL*cluster_id/nclusters, proctime() );
+            for ( p=0 ; p<NP ; p++)
+            {
+//                unsigned int source_cluster = l/(NL/nclusters);
+//                unsigned int source_index   = (l%(NL/nclusters))*NP + p;
+//                unsigned int dest_cluster   = p / (NP/nclusters);
+//                unsigned int dest_index     = (p%(NP/nclusters))*NL + l;
+//                B[dest_cluster][dest_index] = A[source_cluster][source_index];
+
+                B[cluster_id][l*NP+p] = A[cluster_id][l*NP+p];
+            }
+
+        }
+        delta = proctime() - date;
+        date  = date + delta;
+        PRINTF("*** Completing transpose for image %d *** at cycle %d (%d)\n", image, date, delta);
+
+        barrier_wait(1);
+
+        // parallel display from B[c] to frame buffer 
+        // each processor uses its private dma to display NL*NP/ntasks pixels
+
+        delta = proctime() - date;
+        date  = date + delta;
+
+        PRINTF("\n *** starting display for image %d at cycle %d (%d)\n", image, date, delta);
+
+        unsigned int npxt = NL*NP/ntasks;	// number of pixels per task
+
+        if ( fb_write(npxt*proc_id, B[cluster_id] + npxt*local_id, npxt) )
+        {
+            PRINTF("echec fb_sync_write\n");
+            exit();
+        }
+        if ( fb_completed() )
+        {
+            PRINTF("echec fb_completed\n");
+            exit();
+        }
+
+        delta = proctime() - date;
+        date  = date + delta;
+        PRINTF(" *** completing display for image %d at cycle %d (%d)\n", image, date, delta);
+
+        barrier_wait(2);
+
+        // next image
+        image++;
+    } // end while image      
+    while(1);
+} // end main()
+
Index: /trunk/platforms/tsarv4_generic_xbar/soft_transpose/reset.s
===================================================================
--- /trunk/platforms/tsarv4_generic_xbar/soft_transpose/reset.s	(revision 154)
+++ /trunk/platforms/tsarv4_generic_xbar/soft_transpose/reset.s	(revision 154)
@@ -0,0 +1,134 @@
+#################################################################################
+#	File : reset.s
+#	Author : Alain Greiner
+#	Date : 15/04/2011
+#################################################################################
+# 	This is a boot code for a generic multi-clusters / multi-processors
+#       TSAR architecture (up to 256 clusters / up to 4  processors per cluster). 
+#       There is one XICU, one TTY, one DMA and one stack segment per cluster.
+#       segment base adresses = base + cluster_segment_increment*cluster_id
+#	- Each processor initializes the stack pointer ($29) depending on pid.
+#	- Only processor 0 initializes the Interrupt vector (TTY, DMA & IOC).
+#       - Each processor initialises its private ICU mask register.
+#	- Each processor initializes the Status Register (SR) 
+#	- Each processor initializes the EPC register, and jumps to the main 
+#	  address in kernel mode...
+#################################################################################
+		
+	.section .reset,"ax",@progbits
+
+	.extern	seg_stack_base
+	.extern	seg_icu_base
+	.extern _interrupt_vector
+	.extern _isr_tty_get
+	.extern _isr_dma
+	.extern _isr_ioc
+
+        .extern NB_PROCS
+        .extern NB_CLUSTERS
+
+	.globl  reset	 			# makes reset an external symbol 
+	.ent	reset
+	.align	2
+
+reset:
+       	.set noreorder
+
+# computes proc_id, local_id, cluster_id, and cluster_increment
+    mfc0    $26,    $15,    1
+    andi    $10,    $26,    0x3FF	# $10 <= proc_id (at most 1024 processors)
+    la      $26,    NB_PROCS		# $26 <= number of processors per cluster
+    divu    $10,    $26
+    mfhi    $11                 	# $11 <= local_id = proc_id % NB_PROCS
+    mflo    $12              		# $12 <= cluster_id = proc_id / NB_PROCS
+    la      $26,    NB_CLUSTERS
+    li      $13,    0x80000000
+    divu    $13,    $26
+    mflo    $14
+    sll     $14,    1			# $14 <= cluster_increment = 4G / NB_CLUSTERS
+    mult    $14,    $12	
+    mflo    $13                 	# $13 <= cluster_id * cluster_increment
+
+# initializes stack pointer depending on both the local_id and the cluster_id
+    la      $27,    seg_stack_base
+    addu    $27,    $27,    $13		# $27 <= seg_stack_base + cluster_id * increment
+    li      $26,    0x10000		# $26 <= 64K
+    addi    $25,    $11,    1		# $25 <= local_id + 1
+    mult    $25,    $26
+    mflo    $24				# $24 <= 64K * (local_id+1)
+    addu    $29,    $27,    $24		# $29 <= seg_stack_base + (cluster_id*increment) + (local_id+1)*64K
+
+# in each cluster, each processor initializes its private XICU mask register
+# in each cluster, the ICU base address depends on the cluster_id
+    la      $20,    seg_icu_base
+    addu    $20,    $20,    $13		# $20 <= seg_icu_base + cluster_id*cluster_increment
+    la      $21,    _reset_switch
+    sll     $22,    $11,    2           # $22 <= local_id*4
+    addu    $23,    $21,    $22         # $23 <= &_reset_switch[local_id*4]
+    lw      $24,    0($23)
+    jr      $24
+    nop
+_reset_proc0:
+    li      $13,    0b010010000000      # offset for MSK_HWI_ENABLE & proc[0]
+    addu    $13,    $20,    $13
+    li      $27,    0x111		# TTY[0] DMA[0] IOC
+    sw      $27,    0($13)              # MASK[0]
+    j       _reset_itvector
+_reset_proc1:
+    li      $13,    0b010010000100      # offset for MSK_HWI_ENABLE & proc[1]
+    addu    $13,    $20,    $13
+    li      $27,    0x022		# TTY[1] DMA[1]
+    sw      $27,    0($13)              # MASK[1]
+    j       _reset_itvector
+_reset_proc2:
+    li      $13,    0b010010001000      # offset for MSK_HWI_ENABLE & proc[2]
+    addu    $13,    $20,    $13
+    li      $27,    0x044		# TTY[2] DMA[2]
+    sw      $27,    0($13)              # MASK[2]
+    j       _reset_itvector
+_reset_proc3:
+    li      $13,    0b010010001100      # offset for MSK_HWI_ENABLE & proc[3]
+    addu    $13,    $20,    $13
+    li      $27,    0x088		# TTY[3] DMA[3]
+    sw      $27,    0($13)              # MASK[3]
+    j       _reset_itvector
+    nop
+
+_reset_switch:
+    .word	_reset_proc0
+    .word	_reset_proc1
+    .word	_reset_proc2
+    .word	_reset_proc3
+
+# only processor 0 in cluster 0 initializes interrupt vector
+
+_reset_itvector:
+    bne	    $10,    $0,    _reset_end
+    la      $26,    _interrupt_vector   # interrupt vector address
+    la      $27,    _isr_tty_get 
+    sw      $27,    0($26)              # interrupt_vector[0] <= _isr_tty_get
+    sw      $27,    4($26)              # interrupt_vector[1] <= _isr_tty_get
+    sw      $27,    8($26)              # interrupt_vector[2] <= _isr_tty_get
+    sw      $27,   12($26)              # interrupt_vector[3] <= _isr_tty_get
+    la      $27,    _isr_dma 
+    sw      $27,   16($26)              # interrupt_vector[4] <= _isr_dma
+    sw      $27,   20($26)              # interrupt_vector[5] <= _isr_dma
+    sw      $27,   24($26)              # interrupt_vector[6] <= _isr_dma
+    sw      $27,   28($26)              # interrupt_vector[7] <= _isr_dma
+    la      $27,    _isr_ioc 
+    sw      $27,   32($26)              # interrupt_vector[8] <= _isr_ioc
+
+_reset_end:
+
+# initializes SR register
+    li	    $26,    0x0000FF01		
+    mtc0    $26,    $12			# SR <= kernel mode / IRQ enable 
+
+# jumps to main in kernel mode
+    la	    $26,    main
+    jr      $26
+    nop
+
+    .end	reset
+
+    .set reorder
Index: /trunk/platforms/tsarv4_generic_xbar/top.cpp
===================================================================
--- /trunk/platforms/tsarv4_generic_xbar/top.cpp	(revision 154)
+++ /trunk/platforms/tsarv4_generic_xbar/top.cpp	(revision 154)
@@ -0,0 +1,958 @@
+/////////////////////////////////////////////////////////////////////////
+// File: tsarv4_generic_xbar.cpp
+// Author: Alain Greiner 
+// Copyright: UPMC/LIP6
+// Date : april 2011
+// This program is released under the GNU public license
+/////////////////////////////////////////////////////////////////////////
+// This file define a generic TSAR architecture without virtual memory.
+// - It uses vci_local_crossbar as local interconnect 
+// - It uses virtual_dspin as global interconnect
+// - It uses the vci_cc_xcache_wrapper_v4 
+// - It uses the vci_mem_cache_v4
+// - It uses the vci_xicu, with one vci_multi_tty, and one
+//   vci_multi_dma controlers per cluster.
+// The physical address space is 32 bits.
+// The number of clusters cannot be larger than 256.
+// The number of processors per cluster cannot be larger than 4.
+// The parameters must be power of 2.
+// - xmax   : number of clusters in a row
+// - ymax   : number of clusters in a column
+// - nprocs : number of processors per cluster
+//
+// The peripherals BDEV, FBUF, and the boot BROM
+// are in the cluster containing address 0xBFC00000.
+// - The nprocs TTY IRQs are connected to IRQ_IN[0] to IRQ_IN[3]
+// - The nprocs DMA IRQs are connected to IRQ_IN[4] to IRQ_IN[7]
+// - The IOC IRQ is connected to IRQ_IN[8]
+// 
+// General policy for 32 bits address decoding in direct space:
+// All segments base addresses are multiple of 64 Kbytes
+// Therefore the 16 address MSB bits completely define the target: 
+// The (x_width + y_width) MSB bits (left aligned) define
+// the cluster index, and the 8 LSB bits define the local index:
+// 
+//      | X_ID  | Y_ID  |---| LADR |     OFFSET          |
+//      |x_width|y_width|---|  8   |       16            |
+//
+// Half of all clusters being in the protected address space domain 
+// (addresses larger than 0x8000000), software must execute in
+// kernel mode to access memory if we want to exploit locality,
+// because some stacks and heaps will be in the protected domain.
+/////////////////////////////////////////////////////////////////////////
+
+#include <systemc>
+#include <sys/time.h>
+#include <iostream>
+#include <sstream>
+#include <cstdlib>
+#include <cstdarg>
+#include <stdint.h>
+
+#include "gdbserver.h"
+#include "mapping_table.h"
+#include "tsarv4_cluster_xbar.h"
+#include "alloc_elems.h"
+
+///////////////////////////////////////////////////
+//               Parallelisation
+///////////////////////////////////////////////////
+
+#define USE_OPENMP               0
+#define OPENMP_THREADS_NR        8
+
+#if USE_OPENMP
+#include <omp.h>
+#endif
+
+
+//  cluster index (computed from x,y coordinates)
+#define cluster(x,y)	(y + ymax*x)
+
+// flit widths for the DSPIN network
+#define cmd_width	         40
+#define rsp_width	         33
+
+// VCI format
+#define cell_width	         4
+#define address_width	         32
+#define plen_width	         8
+#define error_width	         2
+#define clen_width	         1
+#define rflag_width	         1
+#define srcid_width	         14
+#define pktid_width	         4
+#define trdid_width	         4
+#define wrplen_width	         1
+
+///////////////////////////////////////////////////
+//     Parameters default values         
+///////////////////////////////////////////////////
+
+#define MESH_XMAX		1
+#define MESH_YMAX		1
+
+#define NPROCS			1
+#define XRAM_LATENCY            0
+
+#define MEMC_WAYS               16
+#define MEMC_SETS               256
+
+#define L1_IWAYS                4
+#define L1_ISETS                64
+
+#define L1_DWAYS                4
+#define L1_DSETS                64
+
+#define FBUF_X_SIZE             1024
+#define FBUF_Y_SIZE             1024
+
+#define	BDEV_SECTOR_SIZE 	512
+#define BDEV_IMAGE_NAME	        "soft_filter/philips_image.raw"
+
+#define BOOT_SOFT_NAME	 	"soft_filter/bin.soft"
+
+/////////////////////////////////////////////////////////
+// Segments definition 
+/////////////////////////////////////////////////////////
+// There is 5 segments replicated in all clusters:
+// - seg_icu 	-> ICU  / LADR = 0xF0
+// - seg_tty 	-> MTTY / LADR = 0xF1
+// - seg_dma 	-> CDMA / LADR = 0xF2
+// - seg_stack	-> RAM  / LADR = 0x80 to 0x8F
+// - seg_heap	-> RAM  / LADR = 0x30 to 0x7F
+//
+// There is 3 specific segments in the "IO" cluster 
+// (containing address 0xBF000000)
+// - seg_reset	-> BROM / LADR = 0xC0 to 0xCF
+// - seg_fbuf	-> FBUF / LADR = 0xD0 to OxEF
+// - seg_bdev	-> BDEV / LADR = 0xF3
+//
+// There is 3 specific segments in the "kcode" cluster
+// (containing address 0x80000000)
+// - seg_kcode	-> RAM  / LADR = 0x00 to 0x0F
+// - seg_kdata	-> RAM  / LADR = 0x10 to 0x1F
+// - seg_kunc 	-> RAM  / LADR = 0x20 to 0x2F
+//
+// There is 2 specific segments in the "code" cluster
+// (containing address 0x00000000)
+// - seg_code	-> RAM  / LADR = 0x00 to Ox0F
+// - seg_data 	-> RAM  / LADR = 0x10 to 0x1F
+//
+// There is one special segment corresponding to
+// the processors in the coherence address space
+// - seg_proc	-> PROCS / LADR = 0xB0 to 0xBF
+///////////////////////////////////////////////////
+
+// specific segments in "kcode" cluster
+
+#define KCOD_BASE               0x80000000      
+#define KCOD_SIZE               0x00010000
+
+#define KDAT_BASE               0x80100000      
+#define KDAT_SIZE               0x00010000
+
+#define KUNC_BASE               0x80200000      
+#define KUNC_SIZE               0x00010000
+
+// specific segments in "code" cluster
+
+#define CODE_BASE               0x00000000      
+#define CODE_SIZE               0x00010000
+
+#define DATA_BASE               0x00100000      
+#define DATA_SIZE               0x00010000
+
+// specific segments in "IO" cluster
+
+#define BROM_BASE               0xBFC00000      
+#define BROM_SIZE               0x00010000
+
+#define FBUF_BASE               0xBFD00000      
+#define FBUF_SIZE               0x00200000
+
+#define BDEV_BASE               0xBFF30000      
+#define BDEV_SIZE               0x00000020
+
+// replicated segments
+
+#define HEAP_BASE               0x00300000      
+#define HEAP_SIZE               0x00500000
+
+#define STAK_BASE               0x00800000      
+#define STAK_SIZE               0x00100000
+
+#define XICU_BASE               0x00F00000      
+#define XICU_SIZE               0x00001000
+
+#define MTTY_BASE               0x00F10000      
+#define MTTY_SIZE               0x00000040
+
+#define CDMA_BASE               0x00F20000      
+#define CDMA_SIZE               0x00000080
+
+#define PROC_BASE               0x00B00000      
+#define PROC_SIZE               0x00000010
+
+////////////////////////////////////////////////////////////////////
+//     TGTID definition in direct space
+// For all components:  global TGTID = global SRCID = cluster_index
+////////////////////////////////////////////////////////////////////
+
+#define MEMC_TGTID               0
+#define XICU_TGTID               1
+#define MTTY_TGTID               2
+#define CDMA_TGTID               3
+#define FBUF_TGTID               4
+#define BROM_TGTID               5
+#define BDEV_TGTID               6
+
+///////////////////////////////////////////////////
+// service functions for VCI & DSIN signal trace
+//////////////////////////////////////////////////
+
+template <typename T>
+void  print_vci_signal(std::string name, T &sig) 
+{
+    if ( sig.cmdval )
+    {
+        std::cout << name << std::hex << " CMD VCI : "; 
+        if ( sig.cmd.read() == 1 ) 	std::cout << "RD ";
+        if ( sig.cmd.read() == 2 ) 	std::cout << "WR ";
+        if ( sig.cmd.read() == 3 ) 	std::cout << "LL ";
+        if ( sig.cmd.read() == 0 ) 	std::cout << "SC ";
+        std::cout  << " @ = " << sig.address 
+                   << " | wdata = " << sig.wdata  
+                   << " | srcid = " << sig.srcid 
+                   << " | trdid = " << sig.trdid 
+                   << " | eop = " << sig.eop 
+                   << " | ack = " << sig.cmdack << std::endl;
+    }
+    if ( sig.rspval )
+    {
+         std::cout << name << std::hex 
+                   << " RSP VCI : rerror = " << sig.rerror
+                   << " | rdata = " << sig.rdata 
+                   << " | rsrcid = " << sig.rsrcid 
+                   << " | rtrdid = " << sig.rtrdid 
+                   << " | reop = " << sig.reop
+                   << " | ack = " << sig.rspack << std::endl;
+    }
+}
+
+template <typename T>
+void print_dspin_signal(std::string name, T &sig)
+{
+    if ( sig.write )
+    {
+        std::cout << name << " DSPIN : data = " << std::hex << sig.data
+                  << " | ack = " << sig.read << std::endl;
+    }
+}
+
+/////////////////////////////////
+int _main(int argc, char *argv[])
+{
+    using namespace sc_core;
+    using namespace soclib::caba;
+    using namespace soclib::common;
+    
+    
+    char    soft_name[256] = BOOT_SOFT_NAME;  	// pathname to binary code
+    size_t  ncycles        = 1000000000;       	// simulated cycles
+    size_t  xmax           = MESH_XMAX;  	// number of clusters in a row
+    size_t  ymax           = MESH_YMAX;         // number of clusters in a column
+    size_t  nprocs         = NPROCS;    	// number of processors per cluster
+    size_t  xfb            = FBUF_X_SIZE;	// frameBuffer column number
+    size_t  yfb            = FBUF_Y_SIZE;      	// frameBuffer lines number
+    size_t  memc_ways      = MEMC_WAYS;
+    size_t  memc_sets      = MEMC_SETS;
+    size_t  l1_d_ways      = L1_DWAYS;
+    size_t  l1_d_sets      = L1_DSETS;
+    size_t  l1_i_ways      = L1_IWAYS;
+    size_t  l1_i_sets      = L1_ISETS;
+    char    disk_name[256] = BDEV_IMAGE_NAME;  	// pathname to the disk image
+    size_t  blk_size       = BDEV_SECTOR_SIZE;  // block size (in bytes)
+    size_t  xram_latency   = XRAM_LATENCY;	// external RAM latency
+    bool    trace_ok       = false;            	// debug activated
+    size_t  from_cycle     = 0;                	// debug start cycle
+
+    ////////////// command line arguments //////////////////////
+    if (argc > 1)
+    {
+        for( int n=1 ; n<argc ; n=n+2 )
+        {
+            if( (strcmp(argv[n],"-NCYCLES") == 0) && (n+1<argc) )
+            {
+                ncycles = atoi(argv[n+1]);
+            }
+            else if( (strcmp(argv[n],"-NPROCS") == 0) && (n+1<argc) )
+            {
+                nprocs = atoi(argv[n+1]);
+                assert( ((nprocs == 1) || (nprocs == 2) || (nprocs == 4)) &&
+                        "NPROCS must be equal to 1, 2, or 4");
+            }
+            else if( (strcmp(argv[n],"-XMAX") == 0) && (n+1<argc) )
+            {
+                xmax = atoi(argv[n+1]);
+                assert( ((xmax == 1) || (xmax == 2) || (xmax == 4) || (xmax == 8) || (xmax == 16)) 
+                         && "The XMAX parameter must be 2, 4, 8, or 16" );
+            }
+            
+	    else if( (strcmp(argv[n],"-YMAX") == 0) && (n+1<argc) )
+            {
+                ymax = atoi(argv[n+1]);
+                assert( ((ymax == 1) || (ymax == 2) || (ymax == 4) || (ymax == 8) || (ymax == 16)) 
+                         && "The YMAX parameter must be 2, 4, 8, or 16" );
+            }
+	    else if( (strcmp(argv[n],"-XFB") == 0) && (n+1<argc) )
+            {
+	        xfb = atoi(argv[n+1]);
+            }
+	    else if( (strcmp(argv[n],"-YFB") == 0) && (n+1<argc) )
+            {
+                yfb = atoi(argv[n+1]);
+            }
+            else if( (strcmp(argv[n],"-SOFT") == 0) && (n+1<argc) )
+            {
+                strcpy(soft_name, argv[n+1]);
+            }
+            else if( (strcmp(argv[n],"-DISK") == 0) && (n+1<argc) )
+            {
+                strcpy(disk_name, argv[n+1]);
+            }
+            else if( (strcmp(argv[n],"-TRACE") == 0) && (n+1<argc) )
+            {
+                trace_ok = true;
+                from_cycle = atoi(argv[n+1]);
+            }
+	    else if((strcmp(argv[n], "-MCWAYS") == 0) && (n+1 < argc))
+	    {
+	        memc_ways = atoi(argv[n+1]);
+	    }
+	    else if((strcmp(argv[n], "-MCSETS") == 0) && (n+1 < argc))
+	    {
+	        memc_sets = atoi(argv[n+1]);
+	    }
+	    else if((strcmp(argv[n], "-XLATENCY") == 0) && (n+1 < argc))
+	    {
+	        xram_latency = atoi(argv[n+1]);
+	    }
+            else
+            {
+                std::cout << "   Arguments on the command line are (key,value) couples." << std::endl;
+                std::cout << "   The order is not important." << std::endl;
+                std::cout << "   Accepted arguments are :" << std::endl << std::endl;
+                std::cout << "     -SOFT pathname_for_embedded_soft" << std::endl;
+                std::cout << "     -DISK pathname_for_disk_image" << std::endl;
+                std::cout << "     -NCYCLES number_of_simulated_cycles" << std::endl;
+                std::cout << "     -NPROCS number_of_processors_per_cluster" << std::endl;
+                std::cout << "     -XMAX number_of_clusters_in_a_row" << std::endl;
+                std::cout << "     -YMAX number_of_clusters_in_a_column" << std::endl;
+                std::cout << "     -TRACE debug_start_cycle" << std::endl;
+                std::cout << "     -MCWAYS memory_cache_number_of_ways" << std::endl;
+                std::cout << "     -MCSETS memory_cache_number_of_sets" << std::endl;
+                std::cout << "     -XLATENCY external_ram_latency_value" << std::endl;
+                std::cout << "     -XFB fram_buffer_number_of_pixels" << std::endl;
+                std::cout << "     -YFB fram_buffer_number_of_lines" << std::endl;
+                exit(0);
+            }
+        }
+    }
+
+    std::cout << std::endl;
+    std::cout << " - NPROCS    = " << nprocs <<  std::endl;
+    std::cout << " - NCLUSTERS = " << xmax*ymax << std::endl;
+    std::cout << std::endl;
+
+#if USE_OPENMP
+        omp_set_dynamic(false);
+        omp_set_num_threads(threads_nr);
+        std::cerr << "Built with openmp version " << _OPENMP << std::endl;
+#endif
+
+    // Define VCI parameters
+    typedef soclib::caba::VciParams<cell_width,
+                                    plen_width,
+                                    address_width,
+                                    error_width,                                   
+                                    clen_width,
+                                    rflag_width,
+                                    srcid_width,
+                                    pktid_width,
+                                    trdid_width,
+                                    wrplen_width> vci_param;
+
+    size_t	cluster_io_index;
+    size_t	cluster_code_index;
+    size_t	cluster_kcode_index;
+    size_t	x_width;
+    size_t	y_width;
+
+    if      (xmax == 1) x_width = 0;
+    else if (xmax == 2) x_width = 1;
+    else if (xmax <= 4) x_width = 2;
+    else if (xmax <= 8) x_width = 3;
+    else                x_width = 4;
+
+    if      (ymax == 1) y_width = 0;
+    else if (ymax == 2) y_width = 1;
+    else if (ymax <= 4) y_width = 2;
+    else if (ymax <= 8) y_width = 3;
+    else                y_width = 4;
+
+    cluster_io_index = 0xBF >> (8 - x_width - y_width);
+    cluster_kcode_index = 0x80 >> (8 - x_width - y_width);
+    cluster_code_index = 0;
+    
+    /////////////////////
+    //  Mapping Tables
+    /////////////////////
+
+    // direct network
+    MappingTable maptabd(address_width, 
+                         IntTab(x_width + y_width, 16 - x_width - y_width), 
+                         IntTab(x_width + y_width, srcid_width - x_width - y_width), 
+                         0x00FF0000);
+
+    for ( size_t x = 0 ; x < xmax ; x++)
+    {
+        for ( size_t y = 0 ; y < ymax ; y++)
+        {
+            sc_uint<address_width> offset  = cluster(x,y) << (address_width-x_width-y_width);
+
+            std::ostringstream 	sh;
+            sh << "d_seg_heap_" << x << "_" << y;
+            maptabd.add(Segment(sh.str(), HEAP_BASE+offset, HEAP_SIZE, IntTab(cluster(x,y),MEMC_TGTID), true));
+
+            std::ostringstream 	ss;
+            ss << "d_seg_stak_" << x << "_" << y;
+            maptabd.add(Segment(ss.str(), STAK_BASE+offset, STAK_SIZE, IntTab(cluster(x,y),MEMC_TGTID), true));
+
+            std::ostringstream 	si;
+            si << "d_seg_xicu_" << x << "_" << y;
+            maptabd.add(Segment(si.str(), XICU_BASE+offset, XICU_SIZE, IntTab(cluster(x,y),XICU_TGTID), false));
+
+            std::ostringstream 	st;
+            st << "d_seg_mtty_" << x << "_" << y;
+            maptabd.add(Segment(st.str(), MTTY_BASE+offset, MTTY_SIZE, IntTab(cluster(x,y),MTTY_TGTID), false));
+
+            std::ostringstream 	sd;
+            sd << "d_seg_cdma_" << x << "_" << y;
+            maptabd.add(Segment(sd.str(), CDMA_BASE+offset, CDMA_SIZE, IntTab(cluster(x,y),CDMA_TGTID), false));
+
+            if ( cluster(x,y) == cluster_io_index )
+            {
+	      maptabd.add(Segment("d_seg_fbuf    ", FBUF_BASE, FBUF_SIZE, IntTab(cluster(x,y),FBUF_TGTID), false));
+	      maptabd.add(Segment("d_seg_bdev    ", BDEV_BASE, BDEV_SIZE, IntTab(cluster(x,y),BDEV_TGTID), false));
+	      maptabd.add(Segment("d_seg_brom    ", BROM_BASE, BROM_SIZE, IntTab(cluster(x,y),BROM_TGTID), true));
+            }
+            if ( cluster(x,y) == cluster_code_index )
+            {
+	      maptabd.add(Segment("d_seg_code    ", CODE_BASE, CODE_SIZE, IntTab(cluster(x,y),MEMC_TGTID), true));
+	      maptabd.add(Segment("d_seg_data    ", DATA_BASE, DATA_SIZE, IntTab(cluster(x,y),MEMC_TGTID), true));
+            }
+            if ( cluster(x,y) == cluster_kcode_index )
+            {
+	      maptabd.add(Segment("d_seg_kcod    ", KCOD_BASE, KCOD_SIZE, IntTab(cluster(x,y),MEMC_TGTID), true));
+	      maptabd.add(Segment("d_seg_kdat    ", KDAT_BASE, KDAT_SIZE, IntTab(cluster(x,y),MEMC_TGTID), true));
+	      maptabd.add(Segment("d_seg_kunc    ", KUNC_BASE, KUNC_SIZE, IntTab(cluster(x,y),MEMC_TGTID), true));
+            }
+        }
+    }
+    std::cout << maptabd << std::endl;
+
+    // coherence network
+    // - tgtid_c_proc = srcid_c_proc = local procid
+    // - tgtid_c_memc = srcid_c_memc = nprocs
+    MappingTable maptabc(address_width, 
+                         IntTab(x_width + y_width, 16 - x_width - y_width), 
+                         IntTab(x_width + y_width, srcid_width - x_width - y_width), 
+                         0x00FF0000);
+
+    for ( size_t x = 0 ; x < xmax ; x++)
+    {
+        for ( size_t y = 0 ; y < ymax ; y++)
+        {
+            sc_uint<address_width> offset  = cluster(x,y) << (address_width-x_width-y_width);
+
+            // cleanup requests regarding the heap segment must be routed to the memory cache
+            std::ostringstream sh;
+            sh << "c_seg_heap_" << x << "_" << y;
+            maptabc.add(Segment(sh.str(), HEAP_BASE+offset, HEAP_SIZE, IntTab(cluster(x,y), nprocs), false));
+
+            // cleanup requests regarding the stack segmentmust be routed to the memory cache
+            std::ostringstream ss;
+            ss << "c_seg_stak_" << x << "_" << y;
+            maptabc.add(Segment(ss.str(), STAK_BASE+offset, STAK_SIZE, IntTab(cluster(x,y), nprocs), false));
+
+            // cleanup requests regarding the BROM segment are also be routed to the memory cache
+            if ( cluster(x,y) == cluster_io_index )
+            {
+                maptabc.add(Segment("c_seg_brom    ", BROM_BASE, BROM_SIZE, IntTab(cluster(x,y), nprocs), false));
+            }
+
+            // cleanup requests regarding the code and data segment musts be send to the memory cache
+            if ( cluster(x,y) == cluster_code_index )
+            {
+                maptabc.add(Segment("c_seg_code    ", CODE_BASE, CODE_SIZE, IntTab(cluster(x,y), nprocs), false));
+                maptabc.add(Segment("c_seg_data    ", DATA_BASE, DATA_SIZE, IntTab(cluster(x,y), nprocs), false));
+            }
+            // cleanup requests regarding the kcode, kunc, and kdata segments must be send to the memory cache
+            if ( cluster(x,y) == cluster_kcode_index )
+            {
+                maptabc.add(Segment("c_seg_kcod    ", KCOD_BASE, KCOD_SIZE, IntTab(cluster(x,y), nprocs), false));
+                maptabc.add(Segment("c_seg_kdat    ", KDAT_BASE, KDAT_SIZE, IntTab(cluster(x,y), nprocs), false));
+                maptabc.add(Segment("c_seg_kunc    ", KUNC_BASE, KUNC_SIZE, IntTab(cluster(x,y), nprocs), false));
+            }
+
+            // update & invalidate requests must be routed to the proper processor
+	    for ( size_t p = 0 ; p < nprocs ; p++)
+            {
+                std::ostringstream sp;
+	        sp << "c_seg_proc_" << x << "_" << y << "_" << p;
+	        maptabc.add(Segment(sp.str(), PROC_BASE+offset+(p*0x10000), PROC_SIZE, 
+                            IntTab(cluster(x,y), p), false, true, IntTab(cluster(x,y), p))); 
+            }
+        }
+    }
+    std::cout << maptabc << std::endl;
+
+    // external network
+    MappingTable maptabx(address_width, IntTab(1), IntTab(x_width+y_width), 0xF0000000);
+
+    for ( size_t x = 0 ; x < xmax ; x++)
+    {
+        for ( size_t y = 0 ; y < ymax ; y++)
+        { 
+
+            sc_uint<address_width> offset  = cluster(x,y) << (address_width-x_width-y_width);
+
+            std::ostringstream sh;
+            sh << "x_seg_heap_" << x << "_" << y;
+            maptabx.add(Segment(sh.str(), HEAP_BASE+offset, HEAP_SIZE, IntTab(cluster(x,y)), false));
+
+            std::ostringstream ss;
+            ss << "x_seg_stak_" << x << "_" << y;
+            maptabx.add(Segment(ss.str(), STAK_BASE+offset, STAK_SIZE, IntTab(cluster(x,y)), false));
+
+            if ( cluster(x,y) == cluster_code_index )
+            {
+                maptabx.add(Segment("x_seg_code    ", CODE_BASE, CODE_SIZE, IntTab(cluster(x,y)), false));
+                maptabx.add(Segment("x_seg_data    ", DATA_BASE, DATA_SIZE, IntTab(cluster(x,y)), false));
+            }
+            if ( cluster(x,y) == cluster_kcode_index )
+            {
+                maptabx.add(Segment("x_seg_kcod    ", KCOD_BASE, KCOD_SIZE, IntTab(cluster(x,y)), false));
+                maptabx.add(Segment("x_seg_kdat    ", KDAT_BASE, KDAT_SIZE, IntTab(cluster(x,y)), false));
+                maptabx.add(Segment("x_seg_kunc    ", KUNC_BASE, KUNC_SIZE, IntTab(cluster(x,y)), false));
+            }
+        }
+    }
+    std::cout << maptabx << std::endl;
+
+    ////////////////////
+    // Signals
+    ///////////////////
+
+    sc_clock		signal_clk("clk");
+    sc_signal<bool> 	signal_resetn("resetn");
+
+    // Horizontal inter-clusters DSPIN signals
+    DspinSignals<cmd_width>*** signal_dspin_h_cmd_inc =
+      alloc_elems<DspinSignals<cmd_width> >("signal_dspin_h_cmd_inc", xmax-1, ymax, 2);
+    DspinSignals<cmd_width>*** signal_dspin_h_cmd_dec =
+      alloc_elems<DspinSignals<cmd_width> >("signal_dspin_h_cmd_dec", xmax-1, ymax, 2);
+    DspinSignals<rsp_width>*** signal_dspin_h_rsp_inc =
+      alloc_elems<DspinSignals<rsp_width> >("signal_dspin_h_rsp_inc", xmax-1, ymax, 2);
+    DspinSignals<rsp_width>*** signal_dspin_h_rsp_dec =
+      alloc_elems<DspinSignals<rsp_width> >("signal_dspin_h_rsp_dec", xmax-1, ymax, 2);
+
+    // Vertical inter-clusters DSPIN signals
+    DspinSignals<cmd_width>*** signal_dspin_v_cmd_inc =
+        alloc_elems<DspinSignals<cmd_width> >("signal_dspin_v_cmd_inc", xmax, ymax-1, 2);
+    DspinSignals<cmd_width>*** signal_dspin_v_cmd_dec =
+        alloc_elems<DspinSignals<cmd_width> >("signal_dspin_v_cmd_dec", xmax, ymax-1, 2);
+    DspinSignals<rsp_width>*** signal_dspin_v_rsp_inc =
+        alloc_elems<DspinSignals<rsp_width> >("signal_dspin_v_rsp_inc", xmax, ymax-1, 2);
+    DspinSignals<rsp_width>*** signal_dspin_v_rsp_dec =
+        alloc_elems<DspinSignals<rsp_width> >("signal_dspin_v_rsp_dec", xmax, ymax-1, 2);
+
+    // Mesh boundaries DSPIN signals
+    DspinSignals<cmd_width>**** signal_dspin_false_cmd_in =
+        alloc_elems<DspinSignals<cmd_width> >("signal_dspin_false_cmd_in", xmax, ymax, 2, 4);
+    DspinSignals<cmd_width>**** signal_dspin_false_cmd_out =
+        alloc_elems<DspinSignals<cmd_width> >("signal_dspin_false_cmd_out", xmax, ymax, 2, 4);
+    DspinSignals<rsp_width>**** signal_dspin_false_rsp_in =
+        alloc_elems<DspinSignals<rsp_width> >("signal_dspin_false_rsp_in", xmax, ymax, 2, 4);
+    DspinSignals<rsp_width>**** signal_dspin_false_rsp_out =
+        alloc_elems<DspinSignals<rsp_width> >("signal_dspin_false_rsp_out", xmax, ymax, 2, 4);
+
+
+    ////////////////////////////
+    //      Components
+    ////////////////////////////
+
+#if USE_ALMOS
+    soclib::common::Loader loader("bootloader.bin",
+				  "arch-info.bin@"TO_STR(BOOT_INFO_BLOCK)":D",
+				  "kernel-soclib.bin@"TO_STR(KERNEL_BIN_IMG)":D");
+#else
+    soclib::common::Loader loader(soft_name);
+#endif
+
+    typedef soclib::common::GdbServer<soclib::common::Mips32ElIss> proc_iss;
+    proc_iss::set_loader(loader);
+
+    TsarV4ClusterXbar<vci_param, proc_iss, cmd_width, rsp_width>* clusters[xmax][ymax];
+
+#if USE_OPENMP
+
+#pragma omp parallel
+{
+#pragma omp for
+    for( size_t i = 0 ; i  < (xmax * ymax); i++)
+    {
+        size_t x = i / ymax;
+        size_t y = i % ymax;
+
+#pragma omp critical
+	std::ostringstream sc;
+	sc << "cluster_" << x << "_" << y;
+	clusters[x][y] = new TsarV4ClusterXbar<vci_param, proc_iss, cmd_width, rsp_width>
+	    (sc.str().c_str(),
+             nprocs,
+	     x,
+	     y,
+	     cluster(x,y),
+	     maptabd,
+	     maptabc,
+	     maptabx,
+	     x_width,
+	     y_width,
+	     MEMC_TGTID,
+	     XICU_TGTID,
+	     FBUF_TGTID,
+	     MTTY_TGTID,
+	     BROM_TGTID,
+	     BDEV_TGTID,
+	     CDMA_TGTID,
+             memc_ways,
+             memc_sets,
+             l1_i_ways,
+             l1_i_sets,
+             l1_d_ways,
+             l1_d_sets,
+             xram_latency,
+	     (cluster(x,y) == cluster_io_index),
+	     xfb,
+	     yfb,
+	     disk_name,
+	     blk_size,
+	     loader);
+	}
+
+#else  // USE_OPENMP
+
+    for( size_t x = 0 ; x  < xmax ; x++)
+    {
+        for( size_t y = 0 ; y < ymax ; y++ )
+        {
+
+std::cout << "building cluster_" << x << "_" << y << std::endl;
+
+	    std::ostringstream sc;
+	    sc << "cluster_" << x << "_" << y;
+	    clusters[x][y] = new TsarV4ClusterXbar<vci_param, proc_iss, cmd_width, rsp_width>
+	    (sc.str().c_str(),
+             nprocs,
+	     x,
+	     y,
+	     cluster(x,y),
+	     maptabd,
+	     maptabc,
+	     maptabx,
+	     x_width,
+	     y_width,
+	     MEMC_TGTID,
+	     XICU_TGTID,
+	     FBUF_TGTID,
+	     MTTY_TGTID,
+	     BROM_TGTID,
+	     BDEV_TGTID,
+	     CDMA_TGTID,
+             memc_ways,
+             memc_sets,
+             l1_i_ways,
+             l1_i_sets,
+             l1_d_ways,
+             l1_d_sets,
+             xram_latency,
+	     (cluster(x,y) == cluster_io_index),
+	     xfb,
+	     yfb,
+	     disk_name,
+	     blk_size,
+	     loader);
+
+std::cout << "cluster_" << x << "_" << y << " constructed" << std::endl;
+
+	}
+    }
+    
+#endif	// USE_OPENMP
+
+    ///////////////////////////////////////////////////////////////
+    //     Net-list 
+    ///////////////////////////////////////////////////////////////
+
+    // Clock & RESET
+    for ( size_t x = 0 ; x < (xmax) ; x++ )
+    {
+        for ( size_t y = 0 ; y < ymax ; y++ )
+        {
+            clusters[x][y]->p_clk			(signal_clk);
+            clusters[x][y]->p_resetn			(signal_resetn);
+        }
+    }
+
+    // Inter Clusters horizontal connections
+    if ( xmax > 1 )
+    {
+        for ( size_t x = 0 ; x < (xmax-1) ; x++ )
+        {
+            for ( size_t y = 0 ; y < ymax ; y++ )
+            {
+                for ( size_t k = 0 ; k < 2 ; k++ )
+                {
+		clusters[x][y]->p_cmd_out[k][EAST]      (signal_dspin_h_cmd_inc[x][y][k]);
+                clusters[x+1][y]->p_cmd_in[k][WEST]     (signal_dspin_h_cmd_inc[x][y][k]);
+                clusters[x][y]->p_cmd_in[k][EAST]       (signal_dspin_h_cmd_dec[x][y][k]);
+                clusters[x+1][y]->p_cmd_out[k][WEST]    (signal_dspin_h_cmd_dec[x][y][k]);
+                clusters[x][y]->p_rsp_out[k][EAST]      (signal_dspin_h_rsp_inc[x][y][k]);
+                clusters[x+1][y]->p_rsp_in[k][WEST]     (signal_dspin_h_rsp_inc[x][y][k]);
+                clusters[x][y]->p_rsp_in[k][EAST]       (signal_dspin_h_rsp_dec[x][y][k]);
+                clusters[x+1][y]->p_rsp_out[k][WEST]    (signal_dspin_h_rsp_dec[x][y][k]);
+                }
+            }
+        }
+    }
+    std::cout << "Horizontal connections established" << std::endl;	
+
+    // Inter Clusters vertical connections
+    if ( ymax > 1 )
+    {
+        for ( size_t y = 0 ; y < (ymax-1) ; y++ )
+        {
+            for ( size_t x = 0 ; x < xmax ; x++ )
+            {
+                for ( size_t k = 0 ; k < 2 ; k++ )
+                {
+                clusters[x][y]->p_cmd_out[k][NORTH]     (signal_dspin_v_cmd_inc[x][y][k]);
+                clusters[x][y+1]->p_cmd_in[k][SOUTH]    (signal_dspin_v_cmd_inc[x][y][k]);
+                clusters[x][y]->p_cmd_in[k][NORTH]      (signal_dspin_v_cmd_dec[x][y][k]);
+                clusters[x][y+1]->p_cmd_out[k][SOUTH]   (signal_dspin_v_cmd_dec[x][y][k]);
+                clusters[x][y]->p_rsp_out[k][NORTH]     (signal_dspin_v_rsp_inc[x][y][k]);
+                clusters[x][y+1]->p_rsp_in[k][SOUTH]    (signal_dspin_v_rsp_inc[x][y][k]);
+                clusters[x][y]->p_rsp_in[k][NORTH]      (signal_dspin_v_rsp_dec[x][y][k]);
+                clusters[x][y+1]->p_rsp_out[k][SOUTH]   (signal_dspin_v_rsp_dec[x][y][k]);
+                }
+            }
+        }
+    }
+    std::cout << "Vertical connections established" << std::endl;
+
+    // East & West boundary cluster connections
+    for ( size_t y = 0 ; y < ymax ; y++ )
+    {
+        for ( size_t k = 0 ; k < 2 ; k++ )
+        {
+	    clusters[0][y]->p_cmd_in[k][WEST]       	(signal_dspin_false_cmd_in[0][y][k][WEST]);
+	    clusters[0][y]->p_cmd_out[k][WEST]      	(signal_dspin_false_cmd_out[0][y][k][WEST]);
+	    clusters[0][y]->p_rsp_in[k][WEST]       	(signal_dspin_false_rsp_in[0][y][k][WEST]);
+	    clusters[0][y]->p_rsp_out[k][WEST]      	(signal_dspin_false_rsp_out[0][y][k][WEST]);
+	  
+	    clusters[xmax-1][y]->p_cmd_in[k][EAST]  	(signal_dspin_false_cmd_in[xmax-1][y][k][EAST]);
+	    clusters[xmax-1][y]->p_cmd_out[k][EAST] 	(signal_dspin_false_cmd_out[xmax-1][y][k][EAST]);
+	    clusters[xmax-1][y]->p_rsp_in[k][EAST]  	(signal_dspin_false_rsp_in[xmax-1][y][k][EAST]);
+	    clusters[xmax-1][y]->p_rsp_out[k][EAST] 	(signal_dspin_false_rsp_out[xmax-1][y][k][EAST]);
+	}
+    }
+    
+    // North & South boundary clusters connections
+    for ( size_t x = 0 ; x < xmax ; x++ )
+    {
+        for ( size_t k = 0 ; k < 2 ; k++ )
+        {
+	    clusters[x][0]->p_cmd_in[k][SOUTH]      	(signal_dspin_false_cmd_in[x][0][k][SOUTH]);
+	    clusters[x][0]->p_cmd_out[k][SOUTH]     	(signal_dspin_false_cmd_out[x][0][k][SOUTH]);
+	    clusters[x][0]->p_rsp_in[k][SOUTH]      	(signal_dspin_false_rsp_in[x][0][k][SOUTH]);
+	    clusters[x][0]->p_rsp_out[k][SOUTH]     	(signal_dspin_false_rsp_out[x][0][k][SOUTH]);
+	    
+	    clusters[x][ymax-1]->p_cmd_in[k][NORTH] 	(signal_dspin_false_cmd_in[x][ymax-1][k][NORTH]);
+	    clusters[x][ymax-1]->p_cmd_out[k][NORTH]	(signal_dspin_false_cmd_out[x][ymax-1][k][NORTH]);
+	    clusters[x][ymax-1]->p_rsp_in[k][NORTH] 	(signal_dspin_false_rsp_in[x][ymax-1][k][NORTH]);
+	    clusters[x][ymax-1]->p_rsp_out[k][NORTH]	(signal_dspin_false_rsp_out[x][ymax-1][k][NORTH]);
+	}
+    }
+      
+
+    ////////////////////////////////////////////////////////
+    //   Simulation
+    ///////////////////////////////////////////////////////
+
+    sc_start(sc_core::sc_time(0, SC_NS));
+    signal_resetn = false;
+
+    // network boundaries signals
+    for(size_t x=0; x<xmax ; x++)
+    {
+        for(size_t y=0 ; y<ymax ; y++)
+        {
+            for (size_t k=0; k<2; k++)
+            {
+                for(size_t a=0; a<4; a++)
+                {
+		        signal_dspin_false_cmd_in[x][y][k][a].write = false;
+		        signal_dspin_false_cmd_in[x][y][k][a].read = true;
+                        signal_dspin_false_cmd_out[x][y][k][a].write = false;
+                        signal_dspin_false_cmd_out[x][y][k][a].read = true;
+
+                        signal_dspin_false_rsp_in[x][y][k][a].write = false;
+                        signal_dspin_false_rsp_in[x][y][k][a].read = true;
+                        signal_dspin_false_rsp_out[x][y][k][a].write = false;
+                        signal_dspin_false_rsp_out[x][y][k][a].read = true;
+		}
+            }
+        }
+    }
+
+    sc_start(sc_core::sc_time(1, SC_NS));
+    signal_resetn = true;
+
+    for ( size_t n=0 ; n<ncycles ; n++)
+    {
+        sc_start(sc_core::sc_time(1, SC_NS));
+        if ( trace_ok && (n > from_cycle) )
+        {
+            std::cout << "****************** cycle " << std::dec << n ;
+            std::cout << " ***********************************" << std::endl;
+/*
+            clusters[0][0]->proc[0]->print_trace();
+            clusters[0][0]->proc[1]->print_trace();
+            clusters[0][0]->proc[2]->print_trace();
+            clusters[0][0]->proc[3]->print_trace();
+
+            std::cout << std::endl;  
+
+            clusters[0][1]->proc[0]->print_trace();
+            clusters[0][1]->proc[1]->print_trace();
+            clusters[0][1]->proc[2]->print_trace();
+            clusters[0][1]->proc[3]->print_trace();
+
+            std::cout << std::endl;  
+
+            clusters[1][0]->proc[0]->print_trace();
+            clusters[1][0]->proc[1]->print_trace();
+*/
+            clusters[1][0]->iniwrapperd->print_trace();
+            clusters[1][0]->proc[2]->print_trace();
+            print_vci_signal("proc_1_0_2_tgt_c", clusters[1][0]->signal_vci_tgt_c_proc[2]);
+            print_vci_signal("proc_1_0_2_d", clusters[1][0]->signal_vci_ini_d_proc[2]);
+            print_vci_signal("memc_0_0_d", clusters[0][0]->signal_vci_tgt_d_memc);
+            print_vci_signal("g2l_0_0_d", clusters[0][0]->signal_vci_g2l_d);
+            print_dspin_signal("l2g_0_0_d RSP", clusters[0][0]->signal_dspin_rsp_l2g_d);
+            print_dspin_signal("c10_to_c00 RSP", signal_dspin_h_rsp_dec[0][0][0]);
+            print_dspin_signal("c00_to_c10 RSP", signal_dspin_h_rsp_inc[0][0][0]);
+            print_dspin_signal("g2l_1_0_d RSP", clusters[1][0]->signal_dspin_rsp_g2l_d);
+            print_vci_signal("l2g_1_0_d", clusters[1][0]->signal_vci_l2g_d);
+/*
+            clusters[1][0]->proc[3]->print_trace();
+
+            std::cout << std::endl;  
+
+            clusters[1][1]->proc[0]->print_trace();
+            clusters[1][1]->proc[1]->print_trace();
+            clusters[1][1]->proc[2]->print_trace();
+            clusters[1][1]->proc[3]->print_trace();
+
+            std::cout << std::endl;  
+
+            clusters[0][0]->memc->print_trace();
+            clusters[0][1]->memc->print_trace();
+            clusters[1][0]->memc->print_trace();
+            clusters[1][1]->memc->print_trace();
+
+            clusters[0][0]->iniwrapperd->print_trace();
+            clusters[0][0]->tgtwrapperd->print_trace();
+            clusters[1][0]->iniwrapperd->print_trace();
+            clusters[1][0]->tgtwrapperd->print_trace();
+            clusters[0][1]->iniwrapperd->print_trace();
+            clusters[0][1]->tgtwrapperd->print_trace();
+            clusters[1][1]->iniwrapperd->print_trace();
+            clusters[1][1]->tgtwrapperd->print_trace();
+
+            std::cout << std::endl;  
+
+            print_vci_signal("proc_0_0_0_d", clusters[0][0]->signal_vci_ini_d_proc[0]);
+            print_vci_signal("proc_1_0_0_d", clusters[1][0]->signal_vci_ini_d_proc[0]);
+            print_vci_signal("proc_0_1_0_d", clusters[0][1]->signal_vci_ini_d_proc[0]);
+            print_vci_signal("proc_1_1_0_d", clusters[1][1]->signal_vci_ini_d_proc[0]);
+
+            print_vci_signal("proc_0_0_0_c", clusters[0][0]->signal_vci_tgt_c_proc[0]);
+            print_vci_signal("proc_1_0_0_c", clusters[1][0]->signal_vci_tgt_c_proc[0]);
+            print_vci_signal("proc_0_1_0_c", clusters[0][1]->signal_vci_tgt_c_proc[0]);
+            print_vci_signal("proc_1_1_0_c", clusters[1][1]->signal_vci_tgt_c_proc[0]);
+
+            print_vci_signal("memc_0_0_d", clusters[0][0]->signal_vci_tgt_d_memc);
+            print_vci_signal("memc_1_0_d", clusters[1][0]->signal_vci_tgt_d_memc);
+            print_vci_signal("memc_0_1_d", clusters[0][1]->signal_vci_tgt_d_memc);
+            print_vci_signal("memc_1_1_d", clusters[1][1]->signal_vci_tgt_d_memc);
+
+            print_vci_signal("memc_1_0_ini_c", clusters[1][0]->signal_vci_ini_c_memc);
+
+            print_vci_signal("l2g_1_0_c", clusters[1][0]->signal_vci_l2g_c);
+
+            print_dspin_signal("l2g_1_0_c CMD", clusters[1][0]->signal_dspin_cmd_l2g_c);
+
+            print_vci_signal("l2g_0_0_d", clusters[0][0]->signal_vci_l2g_d);
+            print_vci_signal("g2l_0_0_d", clusters[0][0]->signal_vci_g2l_d);
+
+            print_vci_signal("l2g_1_0_d", clusters[1][0]->signal_vci_l2g_d);
+            print_vci_signal("g2l_1_0_d", clusters[1][0]->signal_vci_g2l_d);
+
+            print_dspin_signal("l2g_0_0_d CMD", clusters[0][0]->signal_dspin_cmd_l2g_d);
+            print_dspin_signal("g2l_0_0_d CMD", clusters[0][0]->signal_dspin_cmd_g2l_d);
+            print_dspin_signal("l2g_0_0_d RSP", clusters[0][0]->signal_dspin_rsp_l2g_d);
+            print_dspin_signal("g2l_0_0_d RSP", clusters[0][0]->signal_dspin_rsp_g2l_d);
+
+            print_dspin_signal("l2g_1_0_d CMD", clusters[1][0]->signal_dspin_cmd_l2g_d);
+            print_dspin_signal("g2l_1_0_d CMD", clusters[1][0]->signal_dspin_cmd_g2l_d);
+            print_dspin_signal("l2g_1_0_d RSP", clusters[1][0]->signal_dspin_rsp_l2g_d);
+            print_dspin_signal("g2l_1_0_d RSP", clusters[1][0]->signal_dspin_rsp_g2l_d);
+
+            print_vci_signal("bdev_tgt", clusters[1][0]->signal_vci_tgt_d_bdev);
+            print_vci_signal("bdev_ini", clusters[1][0]->signal_vci_ini_d_bdev);
+
+            print_vci_signal("brom_tgt", clusters[1][0]->signal_vci_tgt_d_brom);
+            
+            if ( clusters[0][0]->signal_irq_bdev.read() != 0) std::cout << " IRQ_BDEV" << std::endl;
+            if ( clusters[0][0]->signal_proc_it[0].read() != 0) std::cout << " IRQ_PROC" << std::endl;
+*/
+        }
+    }
+    return EXIT_SUCCESS;
+}
+
+int sc_main (int argc, char *argv[])
+{
+	try {
+		return _main(argc, argv);
+	} catch (std::exception &e) {
+		std::cout << e.what() << std::endl;
+	} catch (...) {
+		std::cout << "Unknown exception occured" << std::endl;
+		throw;
+	}
+	return 1;
+}
Index: /trunk/platforms/tsarv4_generic_xbar/top.desc
===================================================================
--- /trunk/platforms/tsarv4_generic_xbar/top.desc	(revision 154)
+++ /trunk/platforms/tsarv4_generic_xbar/top.desc	(revision 154)
@@ -0,0 +1,22 @@
+
+# -*- python -*-
+
+todo = Platform('caba', 'top.cpp',
+	uses = [
+            Uses('caba:tsarv4_cluster_xbar', iss_t = 'common:gdb_iss', 
+                                              gdb_iss_t = 'common:mips32el', 
+                                              cmd_width = 40, rsp_width = 33),
+	    Uses('common:elf_file_loader'),
+            Uses('common:plain_file_loader'),
+	],
+	cell_size = 4,
+	plen_size = 8,
+	addr_size = 32,
+	rerror_size = 2,
+	clen_size = 1,
+	rflag_size = 1,
+	srcid_size = 14,
+	pktid_size = 4,
+	trdid_size = 4,
+	wrplen_size = 1,
+)
Index: /trunk/platforms/tsarv4_generic_xbar/tsarv4_cluster_xbar/caba/metadata/tsarv4_cluster_xbar.sd
===================================================================
--- /trunk/platforms/tsarv4_generic_xbar/tsarv4_cluster_xbar/caba/metadata/tsarv4_cluster_xbar.sd	(revision 154)
+++ /trunk/platforms/tsarv4_generic_xbar/tsarv4_cluster_xbar/caba/metadata/tsarv4_cluster_xbar.sd	(revision 154)
@@ -0,0 +1,71 @@
+
+# -*- python -*-
+
+Module('caba:tsarv4_cluster_xbar',
+	classname = 'soclib::caba::TsarV4ClusterXbar',
+	tmpl_parameters = [
+		parameter.Module('vci_param', default = 'caba:vci_param'),
+		parameter.Module('iss_t'),
+		parameter.Int('cmd_width'),
+		parameter.Int('rsp_width'),
+		],
+	header_files = [ '../source/include/tsarv4_cluster_xbar.h', ],
+	implementation_files = [ '../source/src/tsarv4_cluster_xbar.cpp', ],
+	uses = [
+		Uses('caba:base_module'),
+		Uses('common:mapping_table'),
+		Uses('common:iss2'),
+                Uses('caba:vci_cc_xcache_wrapper_v4', iss_t = 'common:gdb_iss', gdb_iss_t = 'common:mips32el'),
+                Uses('caba:vci_mem_cache_v4'),
+            	Uses('caba:vci_simple_ram'),
+            	Uses('caba:vci_xicu'),
+            	Uses('caba:vci_local_crossbar'),
+            	Uses('caba:virtual_dspin_router', flit_width = parameter.Reference('cmd_width')),
+            	Uses('caba:virtual_dspin_router', flit_width = parameter.Reference('rsp_width')),
+            	Uses('caba:vci_vdspin_target_wrapper', dspin_cmd_width = parameter.Reference('cmd_width'), 
+                                                       dspin_rsp_width = parameter.Reference('rsp_width')),
+            	Uses('caba:vci_vdspin_initiator_wrapper', dspin_cmd_width = parameter.Reference('cmd_width'), 
+                                                          dspin_rsp_width = parameter.Reference('rsp_width')),
+		Uses('caba:vci_multi_tty'),
+		Uses('caba:vci_framebuffer'),
+		Uses('caba:vci_block_device_tsar_v4'),
+		Uses('caba:vci_multi_dma'),
+		Uses('common:elf_file_loader'),
+		],
+        instance_parameters = [
+                parameter.Int('n_x'),
+                parameter.Int('n_y'),
+		parameter.Int('n_cluster'),
+		parameter.Module('mtd', 'common:mapping_table'),
+                parameter.Module('mtc', 'common:mapping_table'),
+		parameter.Module('mtx', 'common:mapping_table'),
+		parameter.Int('x_width'),
+		parameter.Int('y_width'),
+		parameter.Int('memc_tgtid'),
+		parameter.Int('xicu_tgtid'),
+		parameter.Int('fbuf_tgtid'),
+		parameter.Int('mtty_tgtid'),
+		parameter.Int('brom_tgtid'),
+		parameter.Int('bdev_tgtid'),
+		parameter.Int('cdma_tgtid'),
+		parameter.Int('memc_ways'),
+		parameter.Int('memc_sets'),
+		parameter.Int('l1_i_ways'),
+		parameter.Int('l1_i_sets'),
+		parameter.Int('l1_d_ways'),
+		parameter.Int('l1_d_sets'),
+                parameter.Int('xram_latency'),
+		parameter.Bool('io'),
+                ],
+
+	ports = [
+		Port('caba:bit_in', 'p_resetn', auto = 'resetn'),
+		Port('caba:clock_in', 'p_clk', auto = 'clock'),
+		Port('caba:dspin_output', 'p_cmd_out', [2, 4], dspin_data_size = parameter.Reference('cmd_width')),
+		Port('caba:dspin_input', 'p_cmd_in', [2, 4], dspin_data_size = parameter.Reference('cmd_width')),
+		Port('caba:dspin_output', 'p_rsp_out', [2, 4], dspin_data_size = parameter.Reference('rsp_width')), 
+                Port('caba:dspin_input', 'p_rsp_in', [2, 4], dspin_data_size = parameter.Reference('rsp_width')),
+		],
+)
+
+
Index: /trunk/platforms/tsarv4_generic_xbar/tsarv4_cluster_xbar/caba/source/include/tsarv4_cluster_xbar.h
===================================================================
--- /trunk/platforms/tsarv4_generic_xbar/tsarv4_cluster_xbar/caba/source/include/tsarv4_cluster_xbar.h	(revision 154)
+++ /trunk/platforms/tsarv4_generic_xbar/tsarv4_cluster_xbar/caba/source/include/tsarv4_cluster_xbar.h	(revision 154)
@@ -0,0 +1,170 @@
+//////////////////////////////////////////////////////////////////////////////
+// File: tsarv4_cluster_xbar.h
+// Author: Alain Greiner 
+// Copyright: UPMC/LIP6
+// Date : march 2011
+// This program is released under the GNU public license
+//////////////////////////////////////////////////////////////////////////////
+// This file define a TSAR cluster architecture without virtual memory,
+// - It uses the virtual_dspin_router  as distributed global interconnect 
+// - It uses the vci_local_crossbar as local interconnect 
+// - It uses the vci_cc_xcache_wrapper_v4
+// - It uses the vci_mem_cache_v4
+// - It contains a private RAM a variable latency to emulate the L3 cache
+// - It can contains 1, 2 or 4 processors
+// - Each processor has a private local TTY terminal (vci_multi_tty)
+// - Each processor has a private dma channel (vci_multi_dma)
+// - It uses the vci_xicu interrupt controller
+// - The nprocs tty irq are connected to IRQ_IN[0]...IRQ_IN[3]
+// - The nprocs dma irq are connected to IRQ_IN[4]...IRQ_IN[7]
+// - The peripherals BDEV, FBUF, and the boot BROM are in the cluster 
+//   containing address 0xBFC00000, and the bdev_irq is connected to IRQ_IN[8]
+////////////////////////////////////////////////////////////////////////////////// 
+
+#ifndef SOCLIB_CABA_TSAR_CLUSTER_V4_XBAR_H
+#define SOCLIB_CABA_TSAR_CLUSTER_V4_XBAR_H
+
+#include <systemc>
+#include <sys/time.h>
+#include <iostream>
+#include <sstream>
+#include <cstdlib>
+#include <cstdarg>
+
+#include "gdbserver.h"
+#include "mapping_table.h"
+#include "mips32.h"
+#include "vci_simple_ram.h"
+#include "vci_xicu.h"
+#include "vci_local_crossbar.h"
+#include "virtual_dspin_router.h"
+#include "vci_vdspin_target_wrapper.h"
+#include "vci_vdspin_initiator_wrapper.h"
+#include "vci_multi_tty.h"
+#include "vci_block_device_tsar_v4.h"
+#include "vci_framebuffer.h"
+#include "vci_multi_dma.h"
+#include "vci_mem_cache_v4.h"
+#include "vci_cc_xcache_wrapper_v4.h"
+
+namespace soclib {
+namespace caba	{
+
+///////////////////////////////////////////////////////////////////////////
+template<typename vci_param, typename iss_t, int cmd_width, int rsp_width>
+class TsarV4ClusterXbar 
+///////////////////////////////////////////////////////////////////////////
+    : public soclib::caba::BaseModule
+{
+
+  public:
+
+	// Ports
+    	sc_in<bool>                             		p_clk;
+    	sc_in<bool>                             		p_resetn;
+	soclib::caba::DspinOutput<cmd_width>   			**p_cmd_out;
+	soclib::caba::DspinInput<cmd_width>    			**p_cmd_in;
+        soclib::caba::DspinOutput<rsp_width>                   	**p_rsp_out;
+        soclib::caba::DspinInput<rsp_width>                   	**p_rsp_in;
+
+        // interrupt signals
+	sc_signal<bool>     		signal_false;
+	sc_signal<bool> 		signal_proc_it[4];
+	sc_signal<bool> 		signal_irq_mdma[4];
+	sc_signal<bool>			signal_irq_mtty;
+	sc_signal<bool> 		signal_irq_bdev;
+	
+	// DSPIN signals between DSPIN routers and VCI/DSPIN wrappers
+	DspinSignals<cmd_width> 	signal_dspin_cmd_l2g_d; 
+	DspinSignals<cmd_width> 	signal_dspin_cmd_g2l_d; 
+	DspinSignals<cmd_width> 	signal_dspin_cmd_l2g_c;
+	DspinSignals<cmd_width> 	signal_dspin_cmd_g2l_c; 
+	DspinSignals<rsp_width> 	signal_dspin_rsp_l2g_d; 
+	DspinSignals<rsp_width> 	signal_dspin_rsp_g2l_d; 
+	DspinSignals<rsp_width> 	signal_dspin_rsp_l2g_c;
+	DspinSignals<rsp_width> 	signal_dspin_rsp_g2l_c;
+
+	// VCI signals between VCI/DSPIN wrappers and local crossbars
+	VciSignals<vci_param>  		signal_vci_l2g_d; 
+	VciSignals<vci_param>  		signal_vci_g2l_d; 
+	VciSignals<vci_param>  		signal_vci_l2g_c; 
+	VciSignals<vci_param>  		signal_vci_g2l_c; 
+
+	// Direct VCI signals
+	VciSignals<vci_param> 		signal_vci_ini_d_proc[4]; 
+	VciSignals<vci_param>  		signal_vci_ini_d_bdev; 
+	VciSignals<vci_param>  		signal_vci_ini_d_mdma; 
+
+	VciSignals<vci_param>		signal_vci_tgt_d_memc;
+	VciSignals<vci_param> 		signal_vci_tgt_d_mtty;
+	VciSignals<vci_param> 		signal_vci_tgt_d_xicu;
+	VciSignals<vci_param> 		signal_vci_tgt_d_bdev;
+	VciSignals<vci_param> 		signal_vci_tgt_d_mdma;
+	VciSignals<vci_param> 		signal_vci_tgt_d_brom;
+	VciSignals<vci_param> 		signal_vci_tgt_d_fbuf;
+
+	// Coherence VCi signals
+	VciSignals<vci_param> 		signal_vci_ini_c_proc[4];
+	VciSignals<vci_param> 		signal_vci_tgt_c_proc[4];
+	VciSignals<vci_param> 		signal_vci_ini_c_memc;
+	VciSignals<vci_param> 		signal_vci_tgt_c_memc;
+
+	// external RAM VCI signal
+	VciSignals<vci_param> 		signal_vci_xram;
+	
+        // Components
+
+        VciCcXCacheWrapperV4<vci_param, iss_t>*                 	proc[4];
+        VciMemCacheV4<vci_param>*                               	memc;
+        VciXicu<vci_param>*                                     	xicu;
+        VciLocalCrossbar<vci_param>*        				xbard;
+        VciLocalCrossbar<vci_param>*        				xbarc;
+        VciVdspinTargetWrapper<vci_param,cmd_width,rsp_width>*		tgtwrapperd;
+        VciVdspinInitiatorWrapper<vci_param,cmd_width,rsp_width>*	iniwrapperd;
+        VciVdspinTargetWrapper<vci_param,cmd_width,rsp_width>*		tgtwrapperc;
+        VciVdspinInitiatorWrapper<vci_param,cmd_width,rsp_width>*	iniwrapperc;
+        VirtualDspinRouter<cmd_width>*   	                	cmdrouter;
+        VirtualDspinRouter<rsp_width>*	                        	rsprouter;
+        VciSimpleRam<vci_param>*                 			brom;
+        VciMultiTty<vci_param>*                  			mtty;
+        VciFrameBuffer<vci_param>*               			fbuf;
+        VciBlockDeviceTsarV4<vci_param>*         			bdev;
+        VciMultiDma<vci_param>*                 			mdma;
+        VciSimpleRam<vci_param>*					xram;
+
+	TsarV4ClusterXbar(	sc_module_name  insname,
+                        size_t		nprocs,					// number of processors 
+			size_t		n_x,					// x coordinate
+			size_t		n_y,					// y coordinate
+			size_t		n_cluster,				// y + ymax*x
+			const 		soclib::common::MappingTable &mtd,	// direct mapping table
+			const		soclib::common::MappingTable &mtc,	// coherence mapping table
+			const		soclib::common::MappingTable &mtx,	// xram mapping table
+			size_t		x_width,				// x field number of bits
+			size_t		y_width,				// y field number of bits
+                        size_t		tgtid_memc,
+                        size_t		tgtid_xicu,
+                        size_t		tgtid_fbuf,
+                        size_t		tgtid_mtty,
+                        size_t		tgtid_brom,
+                        size_t		tgtid_bdev,
+                        size_t		tgtid_mdma,
+                        size_t		memc_ways,				// number of ways for MEMC
+                        size_t		memc_sets,				// number of sets for MEMC
+                        size_t		l1_i_ways,				// number of ways for L1 ICACHE
+                        size_t		l1_i_sets,				// number of sets for L1 ICACHE
+                        size_t		l1_d_ways,				// number of ways for L1 DCACHE
+                        size_t		l1_d_sets,				// number of sets for L1 DCACHE
+                        size_t		xram_latency,				// external ram latency
+			bool		io,					// I/O cluster if true
+                        size_t          xfb,					// frame buffer pixels
+                        size_t          yfb,					// frame buffer lines
+                        char*           disk_name,				// virtual disk name for BDEV
+                        size_t          block_size,				// block size for BDEV
+                        Loader          loader);				// loader for BROM
+
+	~TsarV4ClusterXbar();
+};
+}}
+
+#endif
Index: /trunk/platforms/tsarv4_generic_xbar/tsarv4_cluster_xbar/caba/source/src/tsarv4_cluster_xbar.cpp
===================================================================
--- /trunk/platforms/tsarv4_generic_xbar/tsarv4_cluster_xbar/caba/source/src/tsarv4_cluster_xbar.cpp	(revision 154)
+++ /trunk/platforms/tsarv4_generic_xbar/tsarv4_cluster_xbar/caba/source/src/tsarv4_cluster_xbar.cpp	(revision 154)
@@ -0,0 +1,481 @@
+#include "../include/tsarv4_cluster_xbar.h"
+
+namespace soclib {
+namespace caba  {
+
+//////////////////////////////////////////////////////////////////////////
+//                 Constructor
+//////////////////////////////////////////////////////////////////////////
+template<typename vci_param, typename iss_t, int cmd_width, int rsp_width>
+TsarV4ClusterXbar<vci_param, iss_t, cmd_width, rsp_width>::TsarV4ClusterXbar(
+                        sc_module_name  insname,
+                        size_t          nprocs,
+                        size_t          x_id,
+                        size_t          y_id,
+                        size_t          cluster_id,
+                        const   	soclib::common::MappingTable &mtd,
+                        const   	soclib::common::MappingTable &mtc, 
+                        const   	soclib::common::MappingTable &mtx, 
+                        size_t          x_width,
+                        size_t          y_width,
+                        size_t		tgtid_memc,
+                        size_t		tgtid_xicu,
+                        size_t		tgtid_fbuf,
+                        size_t		tgtid_mtty,
+                        size_t		tgtid_brom,
+                        size_t		tgtid_bdev,
+                        size_t		tgtid_mdma,
+                        size_t		memc_ways,
+                        size_t		memc_sets,
+                        size_t		l1_i_ways,
+                        size_t		l1_i_sets,
+                        size_t		l1_d_ways,
+                        size_t		l1_d_sets,
+                        size_t		xram_latency,
+                        bool            io,
+                        size_t		xfb,
+                        size_t		yfb,
+                        char*		disk_name,
+                        size_t		block_size,
+                        Loader		loader)
+      : soclib::caba::BaseModule(insname),
+        p_clk("clk"),
+        p_resetn("resetn"),
+
+        signal_dspin_cmd_l2g_d("signal_dspin_cmd_l2g_d"),
+        signal_dspin_cmd_g2l_d("signal_dspin_cmd_g2l_d"),
+        signal_dspin_cmd_l2g_c("signal_dspin_cmd_l2g_c"),
+        signal_dspin_cmd_g2l_c("signal_dspin_cmd_g2l_c"),
+        signal_dspin_rsp_l2g_d("signal_dspin_rsp_l2g_d"),
+        signal_dspin_rsp_g2l_d("signal_dspin_rsp_g2l_d"),
+        signal_dspin_rsp_l2g_c("signal_dspin_rsp_l2g_c"),
+        signal_dspin_rsp_g2l_c("signal_dspin_rsp_g2l_c"),
+
+	signal_vci_ini_d_bdev("signal_vci_ini_d_bdev"),
+	signal_vci_ini_d_mdma("signal_vci_ini_d_mdma"),
+
+        signal_vci_tgt_d_memc("signal_vci_tgt_d_memc"),
+        signal_vci_tgt_d_mtty("signal_vci_tgt_d_mtty"),
+        signal_vci_tgt_d_xicu("signal_vci_tgt_d_xicu"),
+        signal_vci_tgt_d_bdev("signal_vci_tgt_d_bdev"),
+        signal_vci_tgt_d_mdma("signal_vci_tgt_d_mdma"),
+        signal_vci_tgt_d_brom("signal_vci_tgt_d_brom"),
+        signal_vci_tgt_d_fbuf("signal_vci_tgt_d_fbuf"),
+
+        signal_vci_ini_c_memc("signal_vci_ini_c_memc"), 
+        signal_vci_tgt_c_memc("signal_vci_tgt_c_memc"),
+
+        signal_vci_xram("signal_vci_xram")
+
+{
+        // Vectors of ports definition
+
+        p_cmd_in        = alloc_elems<DspinInput<cmd_width> >("p_cmd_in", 2, 4);
+        p_cmd_out       = alloc_elems<DspinOutput<cmd_width> >("p_cmd_out", 2, 4);
+        p_rsp_in        = alloc_elems<DspinInput<rsp_width> >("p_rsp_in", 2, 4);
+        p_rsp_out       = alloc_elems<DspinOutput<rsp_width> >("p_rsp_out", 2, 4);
+
+        // Components definition 
+
+        // on direct network : local srcid[proc] in [0...nprocs-1]
+        // on direct network : local srcid[mdma] = nprocs
+        // on direct network : local srcid[bdev] = nprocs + 1
+
+        // on coherence network : local srcid[proc] in [0...nprocs-1]
+	// on coherence network : local srcid[memc] = nprocs
+
+std::cout << "  - building proc_" << x_id << "_" << y_id << "-*" << std::endl;
+
+        for ( size_t p=0 ; p<nprocs ; p++ )
+        { 
+            std::ostringstream sproc;
+            sproc << "proc_" << x_id << "_" << y_id << "_" << p;
+            proc[p] = new VciCcXCacheWrapperV4<vci_param, iss_t>(
+                sproc.str().c_str(),
+                cluster_id*nprocs + p,
+                mtd, mtc,
+                IntTab(cluster_id,p),    	// SRCID_D
+                IntTab(cluster_id,p),    	// SRCID_C
+                IntTab(cluster_id,p),    	// TGTID_C
+                l1_i_ways,l1_i_sets,16,  	// ICACHE size
+                l1_d_ways,l1_d_sets,16,      	// DCACHE size
+                16,				// WBUF width
+                1,				// WBUF depth
+                0);				// WBUF timeout
+        }
+
+std::cout << "  - building memc_" << x_id << "_" << y_id << std::endl;
+
+        std::ostringstream smemc;
+        smemc << "memc_" << x_id << "_" << y_id;
+        memc = new VciMemCacheV4<vci_param>(
+                   smemc.str().c_str(),
+                   mtd, mtc, mtx,
+                   IntTab(cluster_id),           	// SRCID_X
+                   IntTab(cluster_id, nprocs),   	// SRCID_C
+                   IntTab(cluster_id, tgtid_memc),	// TGTID_D
+                   IntTab(cluster_id, nprocs),   	// TGTID_C
+                   memc_ways, memc_sets, 16,	 	// CACHE SIZE
+                   4096,     			 	// HEAP SIZE
+                   8,					// TRANSACTION TABLE DEPTH
+                   8);					// UPDATE TABLE DEPTH
+
+        
+std::cout << "  - building xram_" << x_id << "_" << y_id << std::endl;
+
+        std::ostringstream sxram;
+        sxram << "xram_" << x_id << "_" << y_id;
+        xram = new VciSimpleRam<vci_param>(
+                   sxram.str().c_str(),
+                   IntTab(cluster_id),
+                   mtx,
+                   loader,
+                   xram_latency);
+
+std::cout << "  - building xicu_" << x_id << "_" << y_id << std::endl;
+
+        size_t  nhwi = 8;				// always 8 (or 9) ports, even if 
+        if( io == true ) nhwi = 9;			// there if less than 4 processors
+        std::ostringstream sicu;
+        sicu << "xicu_" << x_id << "_" << y_id;
+        xicu = new VciXicu<vci_param>(
+                  sicu.str().c_str(),
+                  mtd,				  	// mapping table
+                  IntTab(cluster_id, tgtid_xicu),  	// TGTID_D
+                  0,					// number of timer IRQs
+                  nhwi,                          	// number of hard IRQs
+                  0,					// number of soft IRQs
+                  nprocs);				// number of output IRQs
+
+std::cout << "  - building tty_" << x_id << "_" << y_id << std::endl;
+
+        // tty
+        std::ostringstream stty;
+        stty << "tty_" << x_id << "_" << y_id;
+        mtty = new VciMultiTty<vci_param>(
+                   stty.str().c_str(),
+                   IntTab(cluster_id, tgtid_mtty),
+                   mtd, stty.str().c_str(), NULL);
+        
+std::cout << "  - building dma_" << x_id << "_" << y_id << std::endl;
+
+        // dma
+        std::ostringstream sdma;
+        sdma << "dma_" << x_id << "_" << y_id;
+        mdma = new VciMultiDma<vci_param>(
+                   sdma.str().c_str(),
+                   mtd,
+                   IntTab(cluster_id, nprocs),		// SRCID
+                   IntTab(cluster_id, tgtid_mdma),	// TGTID
+                   64,					// burst size
+                   nprocs);				// number of IRQs
+
+std::cout << "  - building xbard_" << x_id << "_" << y_id << std::endl;
+
+        // direct local crossbar
+        size_t nb_direct_initiators      = nprocs + 1;
+        size_t nb_direct_targets         = 4;
+        if( io == true )
+        {
+            nb_direct_initiators         = nprocs + 2;
+            nb_direct_targets            = 7;
+	}
+        std::ostringstream sd;
+        sd << "xbard_" << x_id << "_" << y_id;
+        xbard = new VciLocalCrossbar<vci_param>(
+                    sd.str().c_str(),
+                    mtd,
+                    IntTab(cluster_id),              	// cluster initiator index
+                    IntTab(cluster_id),              	// cluster target index
+                    nb_direct_initiators,           	// number of initiators
+                    nb_direct_targets);             	// number of targets      
+        
+std::cout << "  - building xbarc_" << x_id << "_" << y_id << std::endl;
+
+        // coherence local crossbar
+        std::ostringstream sc;
+        sc << "xbarc_" << x_id << "_" << y_id;
+        xbarc = new VciLocalCrossbar<vci_param>(
+                    sc.str().c_str(),
+                    mtc,
+                    IntTab(cluster_id),                	// cluster initiator index
+                    IntTab(cluster_id),                	// cluster target index
+                    nprocs + 1,                		// number of initiators
+                    nprocs + 1);               		// number of targets
+        
+std::cout << "  - building wrappers in cluster_" << x_id << "_" << y_id << std::endl;
+
+        // direct initiator wrapper
+        std::ostringstream wid;
+        wid << "iniwrapperd_" << x_id << "_" << y_id;
+        iniwrapperd = new VciVdspinInitiatorWrapper<vci_param,cmd_width,rsp_width>(
+                          wid.str().c_str(),
+                          4,				// cmd fifo depth
+                          4);				// rsp fifo depth
+
+        // direct target wrapper
+        std::ostringstream wtd;
+        wtd << "tgtwrapperd_" << x_id << "_" << y_id;
+        tgtwrapperd = new VciVdspinTargetWrapper<vci_param,cmd_width,rsp_width>(
+                          wtd.str().c_str(),
+                          4,				// cmd fifo depth
+                          4);				// rsp fifo depth
+
+        // coherence initiator wrapper
+        std::ostringstream wic;
+        wic << "iniwrapperc_" << x_id << "_" << y_id;
+        iniwrapperc = new VciVdspinInitiatorWrapper<vci_param,cmd_width,rsp_width>(
+                          wic.str().c_str(),
+                          4,				// cmd fifo depth
+                          4);				// rsp fifo depth
+
+        // coherence target wrapper
+        std::ostringstream wtc;
+        wtc << "tgtwrapperc_" << x_id << "_" << y_id;
+        tgtwrapperc = new VciVdspinTargetWrapper<vci_param,cmd_width,rsp_width>(
+                          wtc.str().c_str(),
+                          4,				// cmd fifo depth
+                          4);				// rsp fifo depth
+
+std::cout << "  - building cmdrouter_" << x_id << "_" << y_id << std::endl;
+
+        // CMD router
+        std::ostringstream scmd;
+        scmd << "cmdrouter_" << x_id << "_" << y_id;
+        cmdrouter = new VirtualDspinRouter<cmd_width>(
+                        scmd.str().c_str(),
+                        x_id,y_id,                    // coordinate in the mesh
+                        x_width, y_width,             // x & y fields width
+                        4,4);                         // input & output fifo depths
+        
+std::cout << "  - building rsprouter_" << x_id << "_" << y_id << std::endl;
+
+        // RSP router
+        std::ostringstream srsp;
+        srsp << "rsprouter_" << x_id << "_" << y_id;
+        rsprouter = new VirtualDspinRouter<rsp_width>(
+                        srsp.str().c_str(),
+                        x_id,y_id,                    // coordinates in mesh
+                        x_width, y_width,             // x & y fields width
+                        4,4);                         // input & output fifo depths
+        
+        // IO cluster components
+        if ( io == true )
+	{
+            brom = new VciSimpleRam<vci_param>(
+                       "brom",
+                       IntTab(cluster_id, tgtid_brom),
+                       mtd,
+                       loader);
+
+            fbuf = new VciFrameBuffer<vci_param>(
+                       "fbuf",
+                       IntTab(cluster_id, tgtid_fbuf),
+                       mtd,
+		       xfb, yfb); 
+
+            bdev = new VciBlockDeviceTsarV4<vci_param>(
+                       "bdev",
+                       mtd,
+                       IntTab(cluster_id, nprocs+1),
+                       IntTab(cluster_id, tgtid_bdev),
+                       disk_name,
+                       block_size);
+	}
+
+std::cout << "  - all components constructed" << std::endl;
+
+        ////////////////////////////////////
+        // Connections are defined here
+        ////////////////////////////////////
+
+        // CMDROUTER and RSPROUTER
+        cmdrouter->p_clk                	(this->p_clk);
+        cmdrouter->p_resetn             	(this->p_resetn);
+        rsprouter->p_clk                	(this->p_clk);
+        rsprouter->p_resetn             	(this->p_resetn);
+        for(int x = 0; x < 2; x++)
+        {
+          for(int y = 0; y < 4; y++)
+          {
+            cmdrouter->p_out[x][y]              (this->p_cmd_out[x][y]);
+            cmdrouter->p_in[x][y]               (this->p_cmd_in[x][y]);
+            rsprouter->p_out[x][y]              (this->p_rsp_out[x][y]);
+            rsprouter->p_in[x][y]               (this->p_rsp_in[x][y]);
+          }
+        }
+        
+        cmdrouter->p_out[0][4]  		(signal_dspin_cmd_g2l_d);
+        cmdrouter->p_out[1][4]  		(signal_dspin_cmd_g2l_c);
+        cmdrouter->p_in[0][4]   		(signal_dspin_cmd_l2g_d);
+        cmdrouter->p_in[1][4]   		(signal_dspin_cmd_l2g_c);
+
+        rsprouter->p_out[0][4]  		(signal_dspin_rsp_g2l_d);
+        rsprouter->p_out[1][4]  		(signal_dspin_rsp_g2l_c);
+        rsprouter->p_in[0][4]   		(signal_dspin_rsp_l2g_d);
+        rsprouter->p_in[1][4]   		(signal_dspin_rsp_l2g_c);
+
+        // VCI/DSPIN WRAPPERS
+        iniwrapperd->p_clk			(this->p_clk);
+        iniwrapperd->p_resetn			(this->p_resetn);
+	iniwrapperd->p_vci			(signal_vci_l2g_d);
+	iniwrapperd->p_dspin_out		(signal_dspin_cmd_l2g_d);
+	iniwrapperd->p_dspin_in			(signal_dspin_rsp_g2l_d);
+
+        tgtwrapperd->p_clk			(this->p_clk);
+        tgtwrapperd->p_resetn			(this->p_resetn);
+	tgtwrapperd->p_vci			(signal_vci_g2l_d);
+	tgtwrapperd->p_dspin_out		(signal_dspin_rsp_l2g_d);
+	tgtwrapperd->p_dspin_in			(signal_dspin_cmd_g2l_d);
+
+        iniwrapperc->p_clk			(this->p_clk);
+        iniwrapperc->p_resetn			(this->p_resetn);
+	iniwrapperc->p_vci			(signal_vci_l2g_c);
+	iniwrapperc->p_dspin_out		(signal_dspin_cmd_l2g_c);
+	iniwrapperc->p_dspin_in			(signal_dspin_rsp_g2l_c);
+
+        tgtwrapperc->p_clk			(this->p_clk);
+        tgtwrapperc->p_resetn			(this->p_resetn);
+	tgtwrapperc->p_vci			(signal_vci_g2l_c);
+	tgtwrapperc->p_dspin_out		(signal_dspin_rsp_l2g_c);
+	tgtwrapperc->p_dspin_in			(signal_dspin_cmd_g2l_c);
+
+        // CROSSBAR direct
+        xbard->p_clk                  		(this->p_clk);
+        xbard->p_resetn                 	(this->p_resetn);
+        xbard->p_initiator_to_up        	(signal_vci_l2g_d);
+        xbard->p_target_to_up           	(signal_vci_g2l_d);
+          
+        xbard->p_to_target[tgtid_memc]  	(signal_vci_tgt_d_memc);
+        xbard->p_to_target[tgtid_xicu]  	(signal_vci_tgt_d_xicu);
+        xbard->p_to_target[tgtid_mtty]  	(signal_vci_tgt_d_mtty);
+        xbard->p_to_target[tgtid_mdma]  	(signal_vci_tgt_d_mdma);
+          
+        xbard->p_to_initiator[nprocs]  		(signal_vci_ini_d_mdma);
+        for ( size_t p=0 ; p<nprocs ; p++)
+        {
+            xbard->p_to_initiator[p]		(signal_vci_ini_d_proc[p]);
+        }
+
+	if ( io == true )
+	{
+            xbard->p_to_target[tgtid_brom]  	(signal_vci_tgt_d_brom);
+            xbard->p_to_target[tgtid_bdev]  	(signal_vci_tgt_d_bdev);
+            xbard->p_to_target[tgtid_fbuf]  	(signal_vci_tgt_d_fbuf);
+            
+            xbard->p_to_initiator[nprocs+1]  	(signal_vci_ini_d_bdev);
+	}
+        
+        // CROSSBAR coherence
+        xbarc->p_clk                    	(this->p_clk);
+        xbarc->p_resetn                 	(this->p_resetn);
+        xbarc->p_initiator_to_up        	(signal_vci_l2g_c);
+        xbarc->p_target_to_up           	(signal_vci_g2l_c);
+        xbarc->p_to_initiator[nprocs]  		(signal_vci_ini_c_memc);
+        xbarc->p_to_target[nprocs]     		(signal_vci_tgt_c_memc);
+        for ( size_t p=0 ; p<nprocs ; p++)
+        {
+            xbarc->p_to_target[p]       	(signal_vci_tgt_c_proc[p]);
+            xbarc->p_to_initiator[p]    	(signal_vci_ini_c_proc[p]);
+        }
+
+        // Processors
+        for ( size_t p=0 ; p<nprocs ; p++)
+        {
+            proc[p]->p_clk              	(this->p_clk);
+            proc[p]->p_resetn           	(this->p_resetn);
+            proc[p]->p_vci_ini_rw       	(signal_vci_ini_d_proc[p]);
+            proc[p]->p_vci_ini_c        	(signal_vci_ini_c_proc[p]);
+            proc[p]->p_vci_tgt          	(signal_vci_tgt_c_proc[p]);
+            proc[p]->p_irq[0]           	(signal_proc_it[p]);
+            for ( size_t j = 1 ; j < 6 ; j++ )
+            {
+                proc[p]->p_irq[j]       	(signal_false);
+            }
+        }
+        
+        // XICU
+        xicu->p_clk                     	(this->p_clk);
+        xicu->p_resetn                  	(this->p_resetn);
+        xicu->p_vci                     	(signal_vci_tgt_d_xicu);
+        for ( size_t p=0 ; p<nprocs ; p++)
+        {
+            xicu->p_irq[p]              	(signal_proc_it[p]);
+        }
+        xicu->p_hwi[0]				(signal_irq_mtty);
+        xicu->p_hwi[1]				(signal_false);
+        xicu->p_hwi[2]				(signal_false);
+        xicu->p_hwi[3]				(signal_false);
+        for ( size_t p=0 ; p<nprocs ; p++)
+        {
+            xicu->p_hwi[p+4]			(signal_irq_mdma[p]);
+        }
+        for ( size_t x=nprocs ; x<4 ; x++)
+        {
+            xicu->p_hwi[x+4]			(signal_false);
+        }
+        if ( io == true )
+	{
+            xicu->p_hwi[8]			(signal_irq_bdev);
+	}
+
+        // MEMC
+        memc->p_clk                     	(this->p_clk);
+        memc->p_resetn                  	(this->p_resetn);
+        memc->p_vci_ixr                 	(signal_vci_xram);
+        memc->p_vci_tgt                 	(signal_vci_tgt_d_memc);
+        memc->p_vci_ini                 	(signal_vci_ini_c_memc);
+        memc->p_vci_tgt_cleanup         	(signal_vci_tgt_c_memc);
+
+        // XRAM
+        xram->p_clk                     	(this->p_clk);
+        xram->p_resetn                  	(this->p_resetn);
+        xram->p_vci                 		(signal_vci_xram);
+
+        // MTTY
+        mtty->p_clk                       	(this->p_clk);
+        mtty->p_resetn                    	(this->p_resetn);
+        mtty->p_vci                       	(signal_vci_tgt_d_mtty);
+        mtty->p_irq[0]           		(signal_irq_mtty);
+
+        // CDMA
+        mdma->p_clk                       	(this->p_clk);
+        mdma->p_resetn                    	(this->p_resetn);
+        mdma->p_vci_target                	(signal_vci_tgt_d_mdma);
+        mdma->p_vci_initiator             	(signal_vci_ini_d_mdma);
+        for (size_t p=0 ; p<nprocs ; p++)
+        {
+            mdma->p_irq[p]                       (signal_irq_mdma[p]);
+        }
+
+	// Components in IO cluster
+
+	if ( io == true )
+	{
+        	// BDEV            
+		bdev->p_clk                      (this->p_clk);
+        	bdev->p_resetn                   (this->p_resetn);
+        	bdev->p_irq                      (signal_irq_bdev);
+        	bdev->p_vci_target               (signal_vci_tgt_d_bdev);
+        	bdev->p_vci_initiator            (signal_vci_ini_d_bdev);
+
+        	// FBUF
+        	fbuf->p_clk                       (this->p_clk);
+        	fbuf->p_resetn                    (this->p_resetn);
+        	fbuf->p_vci                       (signal_vci_tgt_d_fbuf);
+
+        	// BROM
+        	brom->p_clk                       (this->p_clk);
+        	brom->p_resetn                    (this->p_resetn);
+        	brom->p_vci                       (signal_vci_tgt_d_brom);
+
+        }
+} // end constructor
+
+///////////////////////////////////////////////////////////////////////////
+//    destructor
+///////////////////////////////////////////////////////////////////////////
+template<typename vci_param, typename iss_t, int cmd_width, int rsp_width>
+TsarV4ClusterXbar<vci_param, iss_t, cmd_width, rsp_width>::~TsarV4ClusterXbar() {}
+
+}}
