Index: soft/giet_vm/applications/classif/main.c
===================================================================
--- soft/giet_vm/applications/classif/main.c	(revision 457)
+++ soft/giet_vm/applications/classif/main.c	(revision 473)
@@ -17,11 +17,19 @@
 // as global variables distributed in (up to) 16 clusters. 
 //
-// WARNING: the platform cannot contain more than 16 clusters: (X_SIZE < 4) && (Y_SIZE < 4)
-//
-// 1) The "load" task transfer one container from the kernel chbuf associated to the
-//    NIC_RX channel, to a private buffer. Then it copies this bufferer to the local MWMR fifo.
+// Initialisation is done in two steps by the "load" tasks:
+// - Task "load" in cluster[0][0] initialises NIC & CMA channel, and initialises 
+//   the barrier between all "load" tasks. Other "load" tasks are waiting on the
+//   global_sync synchronisation variable.
+// - In each cluster[x][y], the load" task allocates the MWMR fifo descriptor & the data
+//   buffer in the local heap, and store the pointers on a global array of pointers. 
+//   The "analyse" tasks are waiting on the sync[x][y] variables.
+//     
+// When initialisation is completed, all "load and "analyse" tasks loop on containers:
+// 1) The "load" task transfer containers from the kernel chbuf associated to the
+//    NIC_RX channel (in cluster[0][0]), to the local MWMR fifo (in cluster[x][y]),
+//    after an in termediate copy in a private stack buffer. 
 //    Each "load" task loads CONTAINERS_MAX containers before exit, and the
 //    task in cluster[0,0] displays the results stored in global counters filled
-//    by the "analyse" tasks.
+//    by the "analyse" tasks when all "load" tasks reach the barrier.
 //
 // 2) The "analyse" task transfer one container from the local MWMR fifo to a private
@@ -47,105 +55,25 @@
 #define CONTAINERS_MAX   10
 
-///////////  distributed data /////////////////////////////////////////////////////////////
-// - fifo_x_y is the local MWMR fifo descriptor
-// - data_x_y is the local MWMR fifo data buffer
-// - sync_x_y is the local variable signaling MWMR fifo initialisation
-///////////  distributed data /////////////////////////////////////////////////////////////
-
-#if ( (X_SIZE > 0) && (Y_SIZE > 0) )
-__attribute__((section (".data_0_0")))  mwmr_channel_t fifo_0_0;
-__attribute__((section (".data_0_0")))  unsigned int   data_0_0[NB_PROCS_MAX<<10];
-__attribute__((section (".data_0_0")))  unsigned int   sync_0_0 = 0;
-#endif
-#if ( (X_SIZE > 0) && (Y_SIZE > 1) )
-__attribute__((section (".data_0_1")))  mwmr_channel_t fifo_0_1;
-__attribute__((section (".data_0_1")))  unsigned int   data_0_1[NB_PROCS_MAX<<10];
-__attribute__((section (".data_0_1")))  unsigned int   sync_0_1 = 0;
-#endif
-#if ( (X_SIZE > 0) && (Y_SIZE > 2) )
-__attribute__((section (".data_0_2")))  mwmr_channel_t fifo_0_2;
-__attribute__((section (".data_0_2")))  unsigned int   data_0_2[NB_PROCS_MAX<<10];
-__attribute__((section (".data_0_2")))  unsigned int   sync_0_2 = 0;
-#endif
-#if ( (X_SIZE > 0) && (Y_SIZE > 3) )
-__attribute__((section (".data_0_3")))  mwmr_channel_t fifo_0_3;
-__attribute__((section (".data_0_3")))  unsigned int   data_0_3[NB_PROCS_MAX<<10];
-__attribute__((section (".data_0_3")))  unsigned int   sync_0_3 = 0;
-#endif
-#if ( (X_SIZE > 1) && (Y_SIZE > 0) )
-__attribute__((section (".data_1_0")))  mwmr_channel_t fifo_1_0;
-__attribute__((section (".data_1_0")))  unsigned int   data_1_0[NB_PROCS_MAX<<10];
-__attribute__((section (".data_1_0")))  unsigned int   sync_1_0 = 0;
-#endif
-#if ( (X_SIZE > 1) && (Y_SIZE > 1) )
-__attribute__((section (".data_1_1")))  mwmr_channel_t fifo_1_1;
-__attribute__((section (".data_1_1")))  unsigned int   data_1_1[NB_PROCS_MAX<<10];
-__attribute__((section (".data_1_1")))  unsigned int   sync_1_1 = 0;
-#endif
-#if ( (X_SIZE > 1) && (Y_SIZE > 2) )
-__attribute__((section (".data_1_2")))  mwmr_channel_t fifo_1_2;
-__attribute__((section (".data_1_2")))  unsigned int   data_1_2[NB_PROCS_MAX<<10];
-__attribute__((section (".data_1_2")))  unsigned int   sync_1_2 = 0;
-#endif
-#if ( (X_SIZE > 1) && (Y_SIZE > 3) )
-__attribute__((section (".data_1_3")))  mwmr_channel_t fifo_1_3;
-__attribute__((section (".data_1_3")))  unsigned int   data_1_3[NB_PROCS_MAX<<10];
-__attribute__((section (".data_1_3")))  unsigned int   sync_1_3 = 0;
-#endif
-#if ( (X_SIZE > 2) && (Y_SIZE > 0) )
-__attribute__((section (".data_2_0")))  mwmr_channel_t fifo_2_0;
-__attribute__((section (".data_2_0")))  unsigned int   data_2_0[NB_PROCS_MAX<<10];
-__attribute__((section (".data_2_0")))  unsigned int   sync_2_0 = 0;
-#endif
-#if ( (X_SIZE > 2) && (Y_SIZE > 1) )
-__attribute__((section (".data_2_1")))  mwmr_channel_t fifo_2_1;
-__attribute__((section (".data_2_1")))  unsigned int   data_2_1[NB_PROCS_MAX<<10];
-__attribute__((section (".data_2_1")))  unsigned int   sync_2_1 = 0;
-#endif
-#if ( (X_SIZE > 2) && (Y_SIZE > 2) )
-__attribute__((section (".data_2_2")))  mwmr_channel_t fifo_2_2;
-__attribute__((section (".data_2_2")))  unsigned int   data_2_2[NB_PROCS_MAX<<10];
-__attribute__((section (".data_2_2")))  unsigned int   sync_2_2 = 0;
-#endif
-#if ( (X_SIZE > 2) && (Y_SIZE > 3) )
-__attribute__((section (".data_2_3")))  mwmr_channel_t fifo_2_3;
-__attribute__((section (".data_2_3")))  unsigned int   data_2_3[NB_PROCS_MAX<<10];
-__attribute__((section (".data_2_3")))  unsigned int   sync_2_3 = 0;
-#endif
-#if ( (X_SIZE > 3) && (Y_SIZE > 0) )
-__attribute__((section (".data_3_0")))  mwmr_channel_t fifo_3_0;
-__attribute__((section (".data_3_0")))  unsigned int   data_3_0[NB_PROCS_MAX<<10];
-__attribute__((section (".data_3_0")))  unsigned int   sync_3_0 = 0;
-#endif
-#if ( (X_SIZE > 3) && (Y_SIZE > 1) )
-__attribute__((section (".data_3_1")))  mwmr_channel_t fifo_3_1;
-__attribute__((section (".data_3_1")))  unsigned int   data_3_1[NB_PROCS_MAX<<10];
-__attribute__((section (".data_3_1")))  unsigned int   sync_3_1 = 0;
-#endif
-#if ( (X_SIZE > 3) && (Y_SIZE > 2) )
-__attribute__((section (".data_3_2")))  mwmr_channel_t fifo_3_2;
-__attribute__((section (".data_3_2")))  unsigned int   data_3_2[NB_PROCS_MAX<<10];
-__attribute__((section (".data_3_2")))  unsigned int   sync_3_2 = 0;
-#endif
-#if ( (X_SIZE > 3) && (Y_SIZE > 3) )
-__attribute__((section (".data_3_3")))  mwmr_channel_t fifo_3_3;
-__attribute__((section (".data_3_3")))  unsigned int   data_3_3[NB_PROCS_MAX<<10];
-__attribute__((section (".data_3_3")))  unsigned int   sync_3_3 = 0;
-#endif
-
-/////////// shared variables in cluster[0,0] //////////////////////////
-
-__attribute__((section (".data_0_0")))  unsigned int count[16];
-
-__attribute__((section (".data_0_0")))  giet_barrier_t barrier;
-
-__attribute__((section (".data_0_0")))  unsigned int global_init_ok = 0;
-
-__attribute__((section (".data_0_0")))  unsigned int nic_channel;
-
-
-/////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////
+//    Global variables
+// The communication channels are distributed in the clusters, 
+// but the pointers arrays are global variables in cluster[0][0]
+///////////////////////////////////////////////////////////////////////////////////////////
+
+mwmr_channel_t*  mwmr[X_SIZE][Y_SIZE];        // distributed MWMR fifos pointers
+
+unsigned int     local_sync[X_SIZE][Y_SIZE];  // distributed synchros "load" / "analyse"
+
+unsigned int     global_sync = 0;             // global synchro between "load" tasks
+
+unsigned int     count[16];                   // instrumentation counters
+
+giet_barrier_t   barrier;                     // barrier between "load" (instrumentation)
+
+unsigned int     nic_channel;                 // allocated NIC channel index
+
+///////////////////////////////////////////////////////////////////////////////////////////
 __attribute__ ((constructor)) void load()
-/////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////
 {
     // get processor identifiers
@@ -158,18 +86,33 @@
     if (Y_SIZE > 4 )  giet_exit("The Y_SIZE parameter cannot be larger than 4\n");
 
-    // local buffer to store one container
+    // local buffer to store one container in private stack
     unsigned int  temp[1024];
 
-    // get pointer on local MWMR fifo descriptor and data buffer
-    unsigned int    offset = ((x * 4) + y) * 0x10000;
-    mwmr_channel_t* fifo = (mwmr_channel_t*)(((unsigned int)&fifo_0_0) + offset);
-    unsigned int*   data = (unsigned int*)  (((unsigned int)data_0_0)  + offset);
-    unsigned int*   sync = (unsigned int*)  (((unsigned int)&sync_0_0) + offset);
-
+// giet_shr_printf("\n@@@ P[%d,%d,%d] enters load task at cycle %d\n", 
+//                 x, y, l, giet_proctime() );
+
+    // allocates data buffer for MWMR fifo in local heap
+    unsigned int*  data = malloc( NB_PROCS_MAX<<12 );
+
+//giet_shr_printf("\n@@@ P[%d,%d,%d] completes data malloc at cycle %d "
+//                "/ &data = %x\n", x, y, l, giet_proctime(), (unsigned int)data );
+
+    // allocates MWMR fifo descriptor in local heap
+    mwmr_channel_t*  fifo = malloc( sizeof(mwmr_channel_t) );
+
+//giet_shr_printf("\n@@@ P[%d,%d,%d] completes mwmr malloc at cycle %d "
+//                "/ &mwmr = %x\n", x, y, l, giet_proctime(), (unsigned int)mwmr );
+
+    // makes copy of pointer in global array for "analyse" tasks
+    mwmr[x][y] = fifo;
+
+    // display status for cluster[X_SIZE-1][Y_SIZE-1]
     if ( (x==X_SIZE-1) && (y==Y_SIZE-1) )
     giet_shr_printf("\n*** Task load starts on P[%d,%d,%d] at cycle %d\n"
-                    "      &fifo = %x / &data = %x / &sync = %x\n",
-                    x, y, l, giet_proctime(), 
-                    (unsigned int)fifo, (unsigned int)data, (unsigned int)sync ); 
+                    "      &fifo  = %x / &data  = %x / &sync  = %x\n"
+                    "      x_size = %d / y_size = %d / nprocs = %d\n",
+                    x , y , l , giet_proctime() , 
+                    (unsigned int)fifo , (unsigned int)data, (unsigned int)(&local_sync[x][y]) ,
+                    X_SIZE, Y_SIZE, NB_PROCS_MAX ); 
 
     // Task load on cluster[0,0] makes global initialisation:
@@ -188,9 +131,12 @@
         barrier_init( &barrier, X_SIZE * Y_SIZE );
 
-        global_init_ok = 1;
+        // clear NIC RX channels stats
+        giet_nic_rx_clear(); 
+
+        global_sync = 1;
     }
     else
     {
-        while ( global_init_ok == 0 ) asm volatile ("nop");
+        while ( global_sync == 0 ) asm volatile ("nop");
     }    
 
@@ -198,6 +144,6 @@
     mwmr_init( fifo , data , 1024 , NB_PROCS_MAX );
 
-    // signal MWMR fifo initialisation completion
-    *sync = 1;
+    // signal MWMR fifo initialisation completion to analyse tasks
+    local_sync[x][y] = 1;
 
     // main loop (on containers)
@@ -226,7 +172,9 @@
     barrier_wait( &barrier );
 
-    // Task load in cluster[0,0] displays counters and stops NIC / CMA transfer
+    // Task load in cluster[0,0] stops NIC and displays results 
     if ( (x==0) && (y==0) )
     {
+        giet_nic_rx_stop();
+
         giet_shr_printf("\n@@@@ Clasification Results @@@\n"
                         " - TYPE 0 : %d packets\n"
@@ -246,10 +194,8 @@
                         " - TYPE E : %d packets\n"
                         " - TYPE F : %d packets\n",
-            count[0x0], count[0x1], count[0x2], count[0x3],
-            count[0x4], count[0x5], count[0x6], count[0x7],
-            count[0x8], count[0x9], count[0xA], count[0xB],
-            count[0xC], count[0xD], count[0xE], count[0xF] );
-
-        giet_nic_rx_stop();
+                        count[0x0], count[0x1], count[0x2], count[0x3],
+                        count[0x4], count[0x5], count[0x6], count[0x7],
+                        count[0x8], count[0x9], count[0xA], count[0xB],
+                        count[0xC], count[0xD], count[0xE], count[0xF] );
 
         giet_nic_rx_stats();
@@ -277,19 +223,18 @@
     unsigned int  temp[1024];
 
+    // wait MWMR channel initialisation (done by task load)
+    while ( local_sync[x][y] == 0 ) asm volatile ("nop");
+
     // get pointer on MWMR channel descriptor 
-    unsigned int    offset = ((x * 4) + y) * 0x10000;
-    mwmr_channel_t* fifo = (mwmr_channel_t*)(((unsigned int)&fifo_0_0) + offset);
-    unsigned int*   sync = (unsigned int*)  (((unsigned int)&sync_0_0) + offset);
-
+    mwmr_channel_t* fifo = mwmr[x][y];
+
+    // display status for cluster[X_SIZE-1][Y_SIZE-1]
     if ( (x==X_SIZE-1) && (y==Y_SIZE-1) )
     giet_shr_printf("\n*** Task analyse starts on P[%d,%d,%d] at cycle %d\n"
                     "       &fifo = %x / &sync = %x\n",
                     x, y, l, giet_proctime(), 
-                    (unsigned int)fifo, (unsigned int)sync );
+                    (unsigned int)fifo, (unsigned int)(&local_sync[x][y]) );
     
-    // wait MWMR channel initialisation (done by task load)
-    while ( *sync == 0 ) asm volatile ("nop");
-
-    // infinite loop (on containers)
+    // main loop (on containers)
     unsigned int nwords;     // number of words in container
     unsigned int npackets;   // number of packets in container
