[451] | 1 | ///////////////////////////////////////////////////////////////////////////////////////////// |
---|
| 2 | // File : main.c (for router application) |
---|
| 3 | // Date : november 2014 |
---|
| 4 | // author : Alain Greiner |
---|
| 5 | ///////////////////////////////////////////////////////////////////////////////////////////// |
---|
| 6 | // This multi-threaded application emulates a packet routing communication application, |
---|
| 7 | // described as a TCG (Task and Communication Graph). |
---|
| 8 | // It contains 2 + N tasks : one "producer", one "consumer" and N "router") |
---|
| 9 | // It contains 2 MWMR channels : "fifo_in" and "fifo_out". |
---|
| 10 | // - The "producer" task writes NMAX token into "fifo_in". |
---|
| 11 | // - The N "router" tasks read token from "fifo_in" and write them into "fifo_out". |
---|
| 12 | // - The "consumer" task read token from "fifo_out" and displays instrumentation results. |
---|
| 13 | // Token are indexed (by the producer) from 0 to NMAX-1. |
---|
| 14 | // The router task contain a random delay emulating a variable processing time. |
---|
| 15 | // |
---|
| 16 | // This application is intended to run on a multi-processors, multi-clusters architecture, |
---|
| 17 | // with one thread per processor. |
---|
| 18 | // |
---|
| 19 | // It uses the he following hardware parameters, defined in the hard_config.h file: |
---|
| 20 | // - X_SIZE : number of clusters in a row |
---|
| 21 | // - Y_SIZE : number of clusters in a column |
---|
| 22 | // - NB_PROCS_MAX : number of processors per cluster |
---|
| 23 | // |
---|
| 24 | // There is two global arrays (indexed by the token index) for insrumentation: |
---|
| 25 | // - The "router_tab" array is filled concurrently by all "router" tasks. |
---|
| 26 | // Each entry contains the processor index that routed the token. |
---|
| 27 | // - The "consumer_tab" array is filled by the "consumer" task. |
---|
| 28 | // Each entry contain the arrival order to the consumer task. |
---|
| 29 | ///////////////////////////////////////////////////////////////////////////////////////////// |
---|
| 30 | |
---|
[191] | 31 | #include "stdio.h" |
---|
| 32 | #include "mwmr_channel.h" |
---|
| 33 | #include "mapping_info.h" |
---|
[295] | 34 | #include "hard_config.h" |
---|
[191] | 35 | |
---|
[345] | 36 | |
---|
[451] | 37 | #define NMAX 50 // total number of token |
---|
| 38 | #define DEPTH 20 // MWMR channels depth |
---|
[191] | 39 | |
---|
[451] | 40 | //////////////// MWMR channels ///////////////////////////////////////////// |
---|
| 41 | |
---|
| 42 | __attribute__((section (".data_in"))) mwmr_channel_t fifo_in; |
---|
| 43 | __attribute__((section (".data_out"))) mwmr_channel_t fifo_out; |
---|
| 44 | |
---|
| 45 | //////////////// Instrumentation Counters ////////////////////////////////// |
---|
| 46 | |
---|
| 47 | __attribute__((section (".data_out"))) unsigned int consumer_tab[NMAX]; |
---|
| 48 | __attribute__((section (".data_out"))) unsigned int router_tab[NMAX]; |
---|
| 49 | |
---|
| 50 | |
---|
| 51 | |
---|
[191] | 52 | ///////////////////////////////////////////// |
---|
| 53 | __attribute__ ((constructor)) void producer() |
---|
| 54 | { |
---|
| 55 | |
---|
| 56 | unsigned int n; |
---|
| 57 | unsigned int buf; |
---|
| 58 | |
---|
[432] | 59 | // get processor identifiers |
---|
| 60 | unsigned int x; |
---|
| 61 | unsigned int y; |
---|
| 62 | unsigned int lpid; |
---|
| 63 | giet_proc_xyp( &x, &y, &lpid ); |
---|
[191] | 64 | |
---|
[451] | 65 | giet_shr_printf("\n*** Starting task producer on P[%d,%d,%d] at cycle %d\n", |
---|
| 66 | x, y, lpid, giet_proctime() ); |
---|
[191] | 67 | |
---|
[451] | 68 | // initializes fifo_in |
---|
| 69 | mwmr_init( &fifo_in, 1 , DEPTH ); |
---|
[295] | 70 | |
---|
[264] | 71 | // main loop : display token value = source index |
---|
[191] | 72 | for(n = 0 ; n < NMAX ; n++) |
---|
| 73 | { |
---|
| 74 | buf = n; |
---|
[451] | 75 | mwmr_write( &fifo_in , &buf , 1 ); |
---|
[191] | 76 | } |
---|
| 77 | |
---|
[295] | 78 | giet_exit( "Producer task completed"); |
---|
[191] | 79 | |
---|
| 80 | } // end producer() |
---|
| 81 | |
---|
| 82 | ///////////////////////////////////////////// |
---|
| 83 | __attribute__ ((constructor)) void consumer() |
---|
| 84 | { |
---|
| 85 | unsigned int n; |
---|
| 86 | unsigned int buf; |
---|
| 87 | |
---|
[432] | 88 | // get processor identifiers |
---|
| 89 | unsigned int x; |
---|
| 90 | unsigned int y; |
---|
| 91 | unsigned int lpid; |
---|
| 92 | giet_proc_xyp( &x, &y, &lpid ); |
---|
[191] | 93 | |
---|
[451] | 94 | giet_shr_printf("\n*** Starting task consumer on P[%d,%d,%d] at cycle %d\n", |
---|
| 95 | x, y, lpid, giet_proctime() ); |
---|
[191] | 96 | |
---|
[451] | 97 | // initializes fifo_out |
---|
| 98 | mwmr_init( &fifo_out, 1 , DEPTH ); |
---|
[295] | 99 | |
---|
[451] | 100 | // main loop : register token arrival index and value |
---|
| 101 | for( n = 0 ; n < NMAX ; n++ ) |
---|
[191] | 102 | { |
---|
[451] | 103 | mwmr_read( &fifo_out , &buf , 1 ); |
---|
| 104 | consumer_tab[n] = buf; |
---|
[191] | 105 | } |
---|
| 106 | |
---|
[451] | 107 | // instrumentation display |
---|
| 108 | giet_shr_printf("\n"); |
---|
| 109 | for( n = 0 ; n < NMAX ; n++ ) |
---|
| 110 | { |
---|
| 111 | giet_shr_printf("@@@ arrival = %d / value = %d / router = %x\n", |
---|
| 112 | n, consumer_tab[n], router_tab[n] ); |
---|
| 113 | } |
---|
| 114 | |
---|
[295] | 115 | giet_exit( "Consumer task completed"); |
---|
[191] | 116 | |
---|
| 117 | } // end consumer() |
---|
| 118 | |
---|
| 119 | /////////////////////////////////////////// |
---|
| 120 | __attribute__ ((constructor)) void router() |
---|
| 121 | { |
---|
[264] | 122 | unsigned int buf; |
---|
[295] | 123 | unsigned int n; |
---|
[191] | 124 | unsigned int tempo; |
---|
| 125 | |
---|
[432] | 126 | // get processor identifiers |
---|
| 127 | unsigned int x; |
---|
| 128 | unsigned int y; |
---|
| 129 | unsigned int lpid; |
---|
| 130 | giet_proc_xyp( &x, &y, &lpid ); |
---|
[191] | 131 | |
---|
[451] | 132 | giet_shr_printf("\n*** Starting task router on P[%d,%d,%d] at cycle %d\n", |
---|
| 133 | x, y, lpid, giet_proctime() ); |
---|
[191] | 134 | |
---|
[451] | 135 | // waiting fifo_in and fifo_out initialisation |
---|
| 136 | while( (fifo_in.depth == 0) || (fifo_out.depth == 0) ) asm volatile( "nop" ); |
---|
[191] | 137 | |
---|
| 138 | // main loop |
---|
| 139 | while(1) |
---|
| 140 | { |
---|
[451] | 141 | mwmr_read( &fifo_in , &buf , 1 ); |
---|
| 142 | |
---|
| 143 | tempo = giet_rand(); |
---|
| 144 | for ( n = 0 ; n < tempo ; n++ ) asm volatile ( "nop" ); |
---|
| 145 | |
---|
| 146 | router_tab[buf] = (x<<(Y_WIDTH + P_WIDTH)) + (y<<P_WIDTH) + lpid; |
---|
| 147 | |
---|
| 148 | mwmr_write( &fifo_out , &buf , 1 ); |
---|
[191] | 149 | } |
---|
[451] | 150 | } // end router |
---|