OpenCores
URL https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk

Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc

[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [src_verilator/] [simulator.cpp] - Blame information for rev 48

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 32 alirezamon
#include <stdlib.h>
2
#include <stdio.h>
3
#include <unistd.h>
4
#include <string.h>
5 41 alirezamon
#include <limits.h>
6 32 alirezamon
#include <ctype.h>
7
#include <stdint.h>
8
#include <inttypes.h>
9
#include <verilated.h>          // Defines common routines
10 48 alirezamon
 
11 32 alirezamon
#include "Vtraffic.h"
12 48 alirezamon
#include "Vpck_inj.h"
13
#include <thread>
14
#include <vector>
15
#include <atomic>
16 32 alirezamon
 
17
 
18 48 alirezamon
#include <cstdint>
19
#include <cstdlib>
20
#include <iostream>
21 32 alirezamon
 
22 48 alirezamon
#include "simulator.h"
23 32 alirezamon
 
24 48 alirezamon
int main(int argc, char** argv) {
25
        char change_injection_ratio=0;
26
        int i,j,x,y;//,report_delay_counter=0;
27 32 alirezamon
 
28 48 alirezamon
        char deafult_out[] = {"result"};
29
        NEw=Log2(NE);
30
        for(i=0;i<NE;i++)   custom_traffic_table[i]=INJECT_OFF; //off
31
        Verilated::commandArgs(argc, argv);   // Remember args
32
        processArgs ( argc,  argv );
33
 
34
        if (class_percentage==NULL) {
35
                        class_percentage =   (int *) malloc(sizeof(int));
36
                        class_percentage[0]=100;
37 42 alirezamon
        }
38 32 alirezamon
 
39
 
40 48 alirezamon
        Vrouter_new();
41
        if( TRAFFIC_TYPE == NETRACE)    for(i=0;i<NE;i++)        pck_inj[i]  = new Vpck_inj;
42
        else                            for(i=0;i<NE;i++)        traffic[i]  = new Vtraffic;
43 32 alirezamon
 
44
 
45 48 alirezamon
        if( TRAFFIC_TYPE == NETRACE) netrace_init(netrace_file);
46
 
47
        FIXED_SRC_DST_PAIR = strcmp (TRAFFIC,"RANDOM") &  strcmp(TRAFFIC,"HOTSPOT") & strcmp(TRAFFIC,"random") & strcmp(TRAFFIC,"hot spot") & strcmp(TRAFFIC,"TASK");
48
 
49
 
50
        /********************
51
        *       initialize input
52
        *********************/
53
 
54
        reset=1;
55
        reset_all_register();
56
        start_i=0;
57
        topology_init();
58
        if( TRAFFIC_TYPE == NETRACE) pck_inj_init();
59
        else    traffic_gen_init();
60
        main_time=0;
61
        print_parameter();
62
        if( thread_num>1) initial_threads();
63
 
64
        while (!Verilated::gotFinish()) {
65
 
66
                if (main_time-saved_time >= 10 ) {
67
                        reset = 0;
68
                }
69
 
70
                if(main_time == saved_time+21){ count_en=1; start_i=1;}
71
                if(main_time == saved_time+23) start_i=0;
72
 
73
                if(TRAFFIC_TYPE==NETRACE) netrace_posedge_event();
74
                else traffic_clk_posedge_event();
75
                //The valus of all registers and input ports valuse change @ posedge of the clock. Once clk is deasserted,  as multiple modules are connected inside the testbench we need several eval for propogating combinational logic values
76
                //between modules when the clock .
77
                for (i=0;i<SMART_MAX+2;i++) {
78
                        if(TRAFFIC_TYPE==NETRACE) netrace_clk_negedge_event( );
79
                        else traffic_clk_negedge_event( );
80
                }
81
 
82
                if(simulation_done){
83
                        if( TRAFFIC_TYPE == NETRACE) netrace_final_report();
84
                        else traffic_gen_final_report();
85
                        sim_final_all();
86
                        return 0;
87
                }
88
 
89
                main_time++;
90
 
91
        }//Simulating is done
92
 
93
        sim_final_all();
94
        return 0;
95
 
96 32 alirezamon
}
97
 
98
 
99 48 alirezamon
#define __FILENAME__ (__FILE__ + SOURCE_PATH_SIZE)
100
 
101
void  usage(char * bin_name){
102
        printf("Usage:\n"
103
" %s -t <synthetic Traffic Pattern name> [synthetic Traffic options]\n"
104
" %s -f <Task file> [Task options] or\n"
105
" %s -F <netrace file> [Netrace options] \n\n"
106
"synthetic Traffic options:\n"
107
"  -t <Traffic Pattern>        \"HOTSPOT\", \"RANDOM\", \"BIT_COMPLEMENT\" , \"BIT_REVERSE\",\n "
108
"                              \"TORNADO\", \"TRANSPOSE1\", \"TRANSPOSE2\", \"SHUFFEL\", \"CUSTOM\"\n"
109
"  -m <Packet size info>       packet size format  Random-Range or Random-discrete:\n"
110
"                              Random-Range : \"R,MIN,MAX\" : The injected packets' size in flits are\n"
111
"                                 randomly selected in range MIN <= PCK_size <=MAX \n"
112
"                              Random-discrete: \"D,S1,S2,..Sn,P,P1,P2,P3,...Pn\": Si are the discrete\n"
113
"                                 set of numbers representing packet size. The injected packet size is\n"
114
"                                 randomly selected among these discrete values according to associated\n"
115
"                                 probability values.\n"
116
"  -c <sim_end_clk_num>        Simulation will stop when simulation clock number reach this value\n"
117
"  -n <sim_end_pck_num>        Simulation will stop when total of sent packets to the noc reaches this number\n"
118
"  -i <injection ratio>        flit injection ratio in percentage\n"
119
"  -p <class traffic ratios>   The percentage of traffic injected for each class. represented in string\n"
120
"                              each class ratio is separated by comma. \"n0,n1,n2..\" \n"
121
"  -h <HOTSPOT traffic format> represented in a string with following format:\n"
122
"                              total number of hotspot nodes, first hotspot node ID, first hotspot node\n"
123
"                              send enable(1 or 0),first hotspot node percentage x10,second hotspot node ...\n"
124
"  -H <custom traffic pattern> custom traffic pattern: represented in a string with following format:\n"
125
"                              \"SRC1,DEST1, SRC2,DEST2, .., SRCn, DESTn\"   \n"
126
"  -T <thread-num>             total number of threads. The default is one (no-thread).   \n"
127
//"  -Q                          Quick (fast) simulation. ignore evaluating non-active routers \n"
128
"                              to speed up simulation time"
129
"\nTrace options:\n"
130
"  -f <Task file>              path to the task file. any custom task file can be generated using ProNoC gui\n"
131
"  -c <sim_end_clk_num>        Simulation will stop when simulation clock number reach this value \n"
132
"  -T <thread-num>             total number of threads. The default is one (no-thread).   \n"
133
//"  -Q                          Quick (fast) simulation. ignore evaluating non-active routers \n"
134
"                              to speed up simulation time"
135
"\nNetrace options:\n"
136
"  -F <Netrace file>           path to the task file. any custom task file can be generated using ProNoC gui\n"
137
"  -n <sim_end_pck_num>        Simulation will stop when total of sent packets to the NoC reaches this number\n"
138
"  -d                          ignore dependencies\n"
139
"  -r <start region>           start region\n"
140
"  -l                          reader throttling\n"
141
"  -v <level>                  Verbosity level. 0: off, 1:display a live number of injected packet,\n"
142
"                              3: print injected/ejected packets details, default is 1\n"
143
"  -T <thread-num>             total number of threads. The default is one (no-thread).   \n"
144
"  -s <speed-up-num>               the speed-up-num  is the ratio of netrace frequency to pronoc.The higher value\n"
145
"                              results in higher injection ratio to the NoC. Default is one"
146
//"  -Q                          Quick (fast) simulation. ignore evaluating non-active routers \n"
147
"                              to speed up simulation time"     ,
148
bin_name,bin_name,bin_name
149
);
150
 
151
}
152
 
153
 
154
 
155
void netrace_processArgs (int argc, char **argv )
156
{
157
   char c;
158
 
159
   /* don't want getopt to moan - I can do that just fine thanks! */
160
   opterr = 0;
161
   if (argc < 2)  usage(argv[0]);
162
   while ((c = getopt (argc, argv, "F:dr:lv:T:n:s:")) != -1)
163
   {
164
         switch (c)
165
         {
166
                case 'F':
167
                        TRAFFIC_TYPE=NETRACE;
168
                        TRAFFIC=(char *) "NETRACE";
169
                        netrace_file = optarg;
170
                        break;
171
                case 'd':
172
                        ignore_dependencies=1;
173
                        break;
174
                case 'r':
175
                        start_region=atoi(optarg);
176
                        break;
177
                case 'l':
178
                        reader_throttling=1;
179
                        break;
180
                case 'v':
181
                        verbosity= atoi(optarg);
182
                        break;
183
                case  'T':
184
                        thread_num = atoi(optarg);
185
                        break;
186
                case 'n':
187
                        end_sim_pck_num=atoi(optarg);
188
                        break;
189
                case 's':
190
                        netrace_speed_up=atoi(optarg);
191
 
192
                        break;
193
                case '?':
194
                    if (isprint (optopt))
195
                        fprintf (stderr, "Unknown option `-%c'.\n", optopt);
196
                        else
197
                            fprintf (stderr,  "Unknown option character `\\x%x'.\n",  optopt);
198
             default:
199
                       usage(argv[0]);
200
                       exit(1);
201
          }
202
        }
203
}
204
 
205
 
206
 
207
void synthetic_task_processArgs (int argc, char **argv )
208
{
209
   char c;
210
   int p;
211
   int array[10];
212
   float f;
213
 
214
   /* don't want getopt to moan - I can do that just fine thanks! */
215
   opterr = 0;
216
   if (argc < 2)  usage(argv[0]);
217
   while ((c = getopt (argc, argv, "t:m:n:c:i:p:h:H:f:T:Q")) != -1)
218
      {
219
         switch (c)
220
            {
221
                case 'f':
222
                        TRAFFIC_TYPE=TASK;
223
                        TRAFFIC=(char *) "TASK";
224
                        task_traffic_init(optarg);
225
                        break;
226
            case 't':
227
                        TRAFFIC=optarg;
228
                        total_active_routers=-1;
229
                        break;
230
                case 's':
231
                        MIN_PACKET_SIZE=atoi(optarg);
232
                        break;
233
                case 'n':
234
                         end_sim_pck_num=atoi(optarg);
235
                         break;
236
                case 'c':
237
                         sim_end_clk_num=atoi(optarg);
238
                         break;
239
                case 'i':
240
                         f=atof(optarg);
241
                         f*=(MAX_RATIO/100);
242
                         ratio= (int) f;
243
                         break;
244
                case 'p':
245
                        p= parse_string (optarg, array);
246
                        if (p==0) {
247
                                printf("Warning: class setting is ignored!\n");
248
                                break;
249
                        }
250
                        class_percentage =   (int *) malloc( p * sizeof(int));
251
                        for(int k=0;k<p;k++){
252
                                class_percentage[k]=array[k];
253
                        }
254
                        if(p >1 && p>C){
255
                                printf("Warning: the number of given class %u is larger than the number of message classes in ProNoC (C=%u)!\n",p,C);
256
                        }
257
                        break;
258
                case 'm':
259
                        update_pck_size(optarg);
260
 
261
                        break;
262
                case 'H':
263
                        update_custom_traffic(optarg);
264
                        break;
265
                case 'h':
266
                        update_hotspot(optarg);
267
                        break;
268
                case  'T':
269
                        thread_num = atoi(optarg);
270
                        break;
271
                case 'Q':
272
                        //Quick_sim_en=1;
273
                        fprintf (stderr, "Unknown option `-%c'.\n", optopt);
274
                        usage(argv[0]);
275
                        exit(1);
276
                        break;
277
            case '?':
278
               if (isprint (optopt))
279
                  fprintf (stderr, "Unknown option `-%c'.\n", optopt);
280
               else
281
                  fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
282
            default:
283
               usage(argv[0]);
284
               exit(1);
285
            }
286
      }
287
}
288
 
289
 
290
 
291
 
292 32 alirezamon
int parse_string ( char * str, int * array)
293
{
294
    int i=0;
295
    char *pt;
296
    pt = strtok (str,",");
297
    while (pt != NULL) {
298
        int a = atoi(pt);
299
        array[i]=a;
300
        i++;
301
        pt = strtok (NULL, ",");
302
    }
303
   return i;
304
}
305
 
306 43 alirezamon
 
307 48 alirezamon
 
308
 
309
 
310
 
311 43 alirezamon
unsigned int pck_dst_gen (      unsigned int core_num) {
312 48 alirezamon
        if(TRAFFIC_TYPE==TASK)  return          pck_dst_gen_task_graph ( core_num);
313 43 alirezamon
        if((strcmp (TOPOLOGY,"MESH")==0)||(strcmp (TOPOLOGY,"TORUS")==0)) return  pck_dst_gen_2D (core_num);
314
        return pck_dst_gen_1D (core_num);
315
}
316
 
317
 
318
 
319 38 alirezamon
void update_hotspot(char * str){
320
         int i;
321
         int array[1000];
322
         int p;
323
         int acuum=0;
324
         hotspot_st * new_node;
325
         p= parse_string (str, array);
326
         if (p<4){
327 48 alirezamon
                    fprintf(stderr,"ERROR: in hotspot traffic parameters. 4 value should be given as hotspot parameter\n");
328 38 alirezamon
                        exit(1);
329
         }
330
         HOTSPOT_NUM=array[0];
331
         if (p<1+HOTSPOT_NUM*3){
332 48 alirezamon
                    fprintf(stderr,"ERROR: in hotspot traffic parameters \n");
333 38 alirezamon
                        exit(1);
334
         }
335
         new_node =  (hotspot_st *) malloc( HOTSPOT_NUM * sizeof(hotspot_st));
336
         if( new_node == NULL){
337 48 alirezamon
                 fprintf(stderr,"ERROR: cannot allocate memory for hotspot traffic\n");
338 38 alirezamon
            exit(1);
339
         }
340
         for (i=1;i<3*HOTSPOT_NUM; i+=3){
341
                new_node[i/3]. ip_num = array[i];
342
            new_node[i/3]. send_enable=array[i+1];
343
            new_node[i/3]. percentage =  acuum + array[i+2];
344
            acuum= new_node[i/3]. percentage;
345
 
346
         }
347
         if(acuum> 1000){
348 48 alirezamon
                        printf("Warning: The hotspot traffic summation %f exceed than 100 percent.  \n", (float) acuum /10);
349 43 alirezamon
         }
350 38 alirezamon
         hotspots=new_node;
351
}
352
 
353 48 alirezamon
void update_custom_traffic (char * str){
354
        int i;
355
        int array[10000];
356
        int p;
357
        p= parse_string (str, array);
358
        for (i=0;i<p; i+=2){
359
                custom_traffic_table[array[i]] = array[i+1];
360
        }
361 32 alirezamon
}
362
 
363 48 alirezamon
void update_pck_size(char *str){
364
        int i;
365
        int array[1000];
366
        char substring[1000];
367
        int p;
368
        char *pt,*pt2;
369
        MIN_PACKET_SIZE=100000;
370
        MAX_PACKET_SIZE=1;
371 32 alirezamon
 
372 43 alirezamon
 
373 48 alirezamon
        pt = strtok (str,",");
374
        if(*pt=='R'){//random range
375
                p= parse_string (str+2, array);
376
                if(p<2){
377
                        fprintf(stderr,"ERROR: Wrong Packet size format %s. It should be \"R,min,max\" : \n",str);
378
                        exit(1);
379
                }
380 43 alirezamon
 
381 48 alirezamon
                MIN_PACKET_SIZE=array[0];
382
                MAX_PACKET_SIZE=array[1];
383
                AVG_PACKET_SIZE=(MIN_PACKET_SIZE+MAX_PACKET_SIZE)/2;// average packet size
384
        }else if(*pt=='D'){//random discrete
385
                pck_size_sel =  RANDOM_discrete;
386
                pt = strtok (str+2,"P");
387
                pt2 = strtok (NULL,"P");
388
                if (pt == NULL || pt2==NULL) {
389
                        fprintf(stderr,"ERROR: Wrong Packet size format %s. It should be \"D,s1,s2..sn,P,p1,p2..pn\". missing letter \"P\" in format  \n",str);
390
                        exit(1);
391
                }
392
                p= parse_string (pt, array);
393
                if (p==0){
394
                        fprintf(stderr,"ERROR: Wrong Packet size format %s. It should be \"D,s1,s2..sn,P,p1,p2..pn\". missing si values after letter \"D\" \"P\" in format  \n",str);
395
                        exit(1);
396
                }
397
                int in=p;
398
                //alocate mmeory for pck size
399
                discrete_size = (int*)malloc((p) * sizeof(int));
400
                discrete_prob = (int*)malloc((p) * sizeof(int));
401
                // Check if the memory has been successfully allocated
402
                if (discrete_size == NULL || discrete_prob==NULL) {
403
                        printf("ERROR: Memory not allocated.\n");
404
                        exit(1);
405
                }
406 43 alirezamon
 
407 48 alirezamon
                for (i=0; i<p; i++){
408 32 alirezamon
 
409 48 alirezamon
                        //printf("I[%u]=%u,\n",i,array[i]);
410
                        discrete_size[i] = array[i];
411
                        if(MIN_PACKET_SIZE > array[i]) MIN_PACKET_SIZE = array[i];
412
                        if(MAX_PACKET_SIZE < array[i]) MAX_PACKET_SIZE = array[i];
413
                }
414 32 alirezamon
 
415 48 alirezamon
                p= parse_string (pt2+1, array);
416
                int sum=0;
417
                AVG_PACKET_SIZE=0;
418
                for (i=0; i<p; i++){
419
                        //printf("P[%u]=%u,\n",i,array[i]);
420
                        if(i<in){
421
                                 sum+=array[i];
422
                                 discrete_prob[i]=sum;
423
                                 AVG_PACKET_SIZE+=discrete_size[i] * array[i];
424 32 alirezamon
 
425 48 alirezamon
                        }
426
                }
427
                AVG_PACKET_SIZE/=100;
428 32 alirezamon
 
429 48 alirezamon
                if(sum!=100){
430
                        fprintf(stderr,"ERROR: The accumulatio of the first %u probebility values is %u which is not equal to 100\n",in,sum);
431
                        exit(1);
432 32 alirezamon
                }
433
 
434 48 alirezamon
        }else {
435
                fprintf(stderr,"ERROR: Wrong Packet size format %s. It should start with one of \"D\" or \"R\" letter\n",str);
436
                exit(1);
437
        }
438
        p=(MAX_PACKET_SIZE-MIN_PACKET_SIZE)+1;
439
        rsv_size_array = (unsigned int*) calloc ( p , sizeof(int));
440
        if (rsv_size_array==NULL){
441
                 fprintf(stderr,"ERROR: cannot allocate memory for rsv_size_array\n");
442
                 exit(1);
443
        }
444 43 alirezamon
 
445 48 alirezamon
}
446 43 alirezamon
 
447 32 alirezamon
 
448 48 alirezamon
void task_traffic_init (char * str) {
449
        load_traffic_file(str,task_graph_data,task_graph_abstract);
450
        end_sim_pck_num=task_graph_total_pck_num;
451
        MIN_PACKET_SIZE = task_graph_min_pck_size;
452
        MAX_PACKET_SIZE = task_graph_max_pck_size;
453
        AVG_PACKET_SIZE=(MIN_PACKET_SIZE+MAX_PACKET_SIZE)/2;// average packet size
454
        int p=(MAX_PACKET_SIZE-MIN_PACKET_SIZE)+1;
455
        rsv_size_array = (unsigned int*) calloc ( p , sizeof(int));
456
        if (rsv_size_array==NULL){
457
                fprintf(stderr,"ERROR: cannot allocate (%d x int) memory for rsv_size_array. \n",p);
458
                 exit(1);
459
        }
460
}
461 32 alirezamon
 
462
 
463
 
464
 
465
 
466 38 alirezamon
 
467 32 alirezamon
 
468 48 alirezamon
void processArgs (int argc, char **argv ){
469
        int i;
470
        for( i = 1; i < argc; ++i ) {
471
                if( strcmp(argv[i], "-t") == 0 ) {
472
                        synthetic_task_processArgs ( argc, argv );
473
                        return;
474
                } else if( strcmp(argv[i], "-f") == 0 ) {
475
                        synthetic_task_processArgs ( argc, argv );
476
                        return;
477 32 alirezamon
 
478 48 alirezamon
                } else if( strcmp(argv[i], "-F") == 0 ) {
479
                        netrace_processArgs (argc, argv );
480
                        return;
481
                }
482
        }
483
        fprintf (stderr, "you should define one one of Synthetic,Task or nettrace based simulation. \n");
484
        usage(argv[0]);
485
        exit(1);
486
}
487 32 alirezamon
 
488 43 alirezamon
 
489 48 alirezamon
int get_new_pck_size(){
490
                if(pck_size_sel ==  RANDOM_discrete){
491
                                int rnd = rand() % 100; // 0~99
492
                                int i=0;
493
                                while( rnd > discrete_prob[i] ) i++;
494
                                return discrete_size [i];
495 32 alirezamon
                }
496 48 alirezamon
                //random range
497
                return rnd_between(MIN_PACKET_SIZE,MAX_PACKET_SIZE);
498
}
499 32 alirezamon
 
500
 
501
 
502
 
503 48 alirezamon
 
504
 
505
void traffic_gen_final_report(){
506
        int i;
507
        for (i=0;i<NE;i++) if(traffic[i]->pck_number>0) total_active_endp         =       total_active_endp +1;
508
        printf("\nsimulation results-------------------\n");
509
        printf("\tSimulation clock cycles:%d\n",clk_counter);
510
        printf("\n\tTotal injected packet in different size:\n");
511
        printf("\tflit_size,");
512
        for (i=0;i<=(MAX_PACKET_SIZE - MIN_PACKET_SIZE);i++){
513
                if(rsv_size_array[i]>0) printf("%u,",i+ MIN_PACKET_SIZE);
514
        }
515
        printf("\n\t#pck,");
516
        for (i=0;i<=(MAX_PACKET_SIZE - MIN_PACKET_SIZE);i++){
517
                if(rsv_size_array[i]>0) printf("%u,",rsv_size_array[i]);
518
        }
519
        printf("\n");
520
 
521
//      printf(" total received flits:%d\n",total_rsv_flit_number);
522
//      printf(" total sent flits:%d\n",total_sent_flit_number);
523
        print_statistic_new (clk_counter);
524
 
525 32 alirezamon
}
526
 
527
 
528 48 alirezamon
void traffic_gen_init( void ){
529
        int i;
530
        unsigned int dest_e_addr;
531
        for (i=0;i<NE;i++){
532
                random_var[i] = 100;
533
                traffic[i]->current_e_addr              = endp_addr_encoder(i);
534
                traffic[i]->start=0;
535
                traffic[i]->pck_class_in=  pck_class_in_gen( i);
536
                traffic[i]->pck_size_in=get_new_pck_size();
537
                dest_e_addr=pck_dst_gen (i);
538
                traffic[i]->dest_e_addr= dest_e_addr;
539
                if(dest_e_addr == INJECT_OFF) traffic[i]->stop=1;
540
                //printf("src=%u, des_eaddr=%x, dest=%x\n", i,dest_e_addr, endp_addr_decoder(dest_e_addr));
541
                if(inject_done) traffic[i]->stop=1;
542
                traffic[i]->start_delay=rnd_between(1,4*NE-2);
543
                if(TRAFFIC_TYPE==SYNTHETIC){
544
                        //traffic[i]->avg_pck_size_in=AVG_PACKET_SIZE;
545
                        traffic[i]->ratio=ratio;
546
                        traffic[i]->init_weight=1;
547
                }
548
        }
549
}
550 32 alirezamon
 
551 48 alirezamon
void pck_inj_init (void){
552
        int i;
553
        for (i=0;i<NE;i++){
554
                pck_inj[i]->current_e_addr              = endp_addr_encoder(i);
555
           //TODO mapping should be done according to number of NE and should be set by the user larer
556
                netrace_to_pronoc_map[i]=(int)((i* NE)/header->num_nodes);
557
                pck_inj[i]->pck_injct_in_ready= (0x1<<V)-1;
558
                pck_inj[i]->pck_injct_in_pck_wr=0;
559
                //pronoc_to_netrace_map[i]=i;
560 32 alirezamon
 
561 48 alirezamon
        }
562
 
563
}
564
 
565 38 alirezamon
/*************
566
 * sc_time_stamp
567
 *
568
 * **********/
569 32 alirezamon
double sc_time_stamp () {       // Called by $time in Verilog
570
        return main_time;
571
}
572
 
573
int pow2( int num){
574
        int pw;
575
        pw= (0x1 << num);
576
        return pw;
577
}
578
 
579 48 alirezamon
/*
580
volatile int *  lock;
581
unsigned int  nr_per_thread=0;
582
unsigned int  ne_per_thread=0;
583 32 alirezamon
 
584 48 alirezamon
void thread_function (int n){
585
        int i;
586
        unsigned int node=0;
587
        while(1){
588
                while(lock[n]==0) std::this_thread::yield();
589
                for(i=0;i<nr_per_thread;i++){
590
                        node= (n * nr_per_thread)+i;
591
                        if (node >= NR) break;
592
                        single_router_eval(node);
593
                }
594
                for(i=0;i<ne_per_thread;i++){
595
                        node= (n * ne_per_thread)+i;
596
                        if (node >= NE) break;
597
                        if( TRAFFIC_TYPE == NETRACE)   pck_inj[node]->eval();
598
                        else   traffic[node]->eval();
599
                }
600
 
601
                //router1[n]->eval();
602
                //if( TRAFFIC_TYPE == NETRACE)   pck_inj[n]->eval();
603
                //else   traffic[n]->eval();
604
 
605
                lock[n]=0;
606
                if(n==0) break;//first thread is the main process
607
        }
608
}
609
*/
610 32 alirezamon
 
611 48 alirezamon
class alignas(64) Vthread
612
{
613
    // Access specifier
614
    public:
615
        std::atomic<bool> ready;
616
    // Data Members
617
    int n;//thread num
618
        int nr_per_thread;
619
        int ne_per_thread;
620
    // Member Functions()
621
    //Parameterized Constructor
622
 
623
 
624
    void function ( ){
625
                int i;
626
                unsigned int node=0;
627
                while(1){
628
                        while(!ready) std::this_thread::yield();
629
                        for(i=0;i<nr_per_thread;i++){
630
                                node= (n * nr_per_thread)+i;
631
                                if (node >= NR) break;
632
                                //if(router_is_active[node] | (Quick_sim_en==0))
633
                                single_router_eval(node);
634
                        }
635
                        for(i=0;i<ne_per_thread;i++){
636
                                node= (n * ne_per_thread)+i;
637
                                if (node >= NE) break;
638
                                if( TRAFFIC_TYPE == NETRACE)   pck_inj[node]->eval();
639
                                else   traffic[node]->eval();
640
                        }
641
 
642
                        //router1[n]->eval();
643
                        //if( TRAFFIC_TYPE == NETRACE)   pck_inj[n]->eval();
644
                        //else   traffic[n]->eval();
645
 
646
                        ready=false;
647
                        if(n==0) break;//first thread is the main process 
648
                }
649
        }
650
 
651
        Vthread(int x,int r,int e)
652
    {
653
       n=x; nr_per_thread=r; ne_per_thread=e;
654
       ready=false;
655
       if(n!=0) {
656
                 std::thread th {&Vthread::function,this};
657
         th.detach();
658
           }
659
    }
660
 
661
 
662
};
663
 
664
Vthread ** thread;
665
 
666
void initial_threads (void){
667
        int i;
668
        //devide nodes equally between threads
669
        unsigned int  nr_per_thread=0;
670
        unsigned int  ne_per_thread=0;
671
        nr_per_thread = (NR % thread_num)?  (unsigned int)(NR/thread_num) + 1 :  (unsigned int)(NR/thread_num);
672
        ne_per_thread = (NE % thread_num)?  (unsigned int)(NE/thread_num) + 1 :  (unsigned int)(NE/thread_num);
673
 
674
        //std::vector<std::thread> threads(thread_num-1);
675
        //lock = new int[thread_num];
676
        //for(i=0;i<thread_num;i++) lock [i]=0; 
677
 
678
        //Dynamically Allocating Memory
679
        thread = (Vthread **) new Vthread * [thread_num];
680
        for(i=0;i<thread_num;i++) thread[i] = new Vthread(i,nr_per_thread,ne_per_thread) ;
681
 
682
        //initiates (thread_num-1) number of live thread         
683
        //for(i=0;i<thread_num-1;i++) threads[i] = std::thread(&thread_function, (i+1));
684
        //for (auto& th : threads)    th.detach();
685
 
686
        unsigned maxThreads = std::thread::hardware_concurrency();
687
    printf("Thread is initiated as following:\n"
688
    "\tMax hardware supported threads:%u\n"
689
    "\tthread_num:%u\n"
690
    "\trouter per thread:%u\n"
691
    "\tendpoint per thread:%u\n"
692
    ,maxThreads,thread_num,nr_per_thread,ne_per_thread);
693
}
694
 
695
 
696
 
697
 
698
void sim_eval_all (void){
699
        int i;
700
        if(thread_num>1) {
701
                for(i=0;i<thread_num;i++) thread[i]->ready=true;
702
                //thread_function (0);          
703
                thread[0]->function();
704
                for(i=0;i<thread_num;i++)while(thread[i]->ready);
705
        }else{// no thread
706
                //routers_eval();
707
                for(i=0;i<NR;i++){
708
                        //if(router_is_active[i] | (Quick_sim_en==0)) 
709
                        single_router_eval(i);
710
                }
711
                if( TRAFFIC_TYPE == NETRACE) for(i=0;i<NE;i++) pck_inj[i]->eval();
712
                else for(i=0;i<NE;i++) traffic[i]->eval();
713
        }
714
}
715
 
716
void sim_final_all (void){
717
        int i;
718
        routers_final();
719
        if( TRAFFIC_TYPE == NETRACE) for(i=0;i<NE;i++) pck_inj[i]->final();
720
        else for(i=0;i<NE;i++) traffic[i]->final();
721
        //noc->final(); 
722
}
723
 
724
void connect_clk_reset_start_all(void){
725
        int i;
726
        //noc-> clk = clk; 
727
        //noc-> reset = reset;
728
        if( TRAFFIC_TYPE == NETRACE) {
729
                for(i=0;i<NE;i++)        {
730
                        pck_inj[i]->reset= reset;
731
                        pck_inj[i]->clk = clk;
732
                }
733
        }else {
734
                for(i=0;i<NE;i++)        {
735
                        start_o[i]=start_i;
736
                        traffic[i]->start= start_o[i];
737
                        traffic[i]->reset= reset;
738
                        traffic[i]->clk = clk;
739
                }
740
        }
741
        connect_routers_reset_clk();
742
}
743
 
744
 
745
void traffic_clk_negedge_event(void){
746
        int i;
747
        clk = 0;
748
        //for (i=0;i<NR;i++) router_is_active [i]=0;
749
        topology_connect_all_nodes ();
750
 
751
        for (i=0;i<NE;i++){
752
                if(inject_done) traffic[i]->stop=1;
753
        }
754
        connect_clk_reset_start_all();
755
        sim_eval_all();
756
}
757
 
758
 
759
 
760
 
761
void traffic_clk_posedge_event(void) {
762
        int i;
763
        unsigned int dest_e_addr;
764
        clk = 1;       // Toggle clock
765
        if(count_en) clk_counter++;
766
        inject_done= ((total_sent_pck_num >= end_sim_pck_num) || (clk_counter>= sim_end_clk_num) || total_active_routers == 0);
767
        //if(inject_done) printf("clk_counter=========%d\n",clk_counter);
768
        total_rsv_flit_number_old=total_rsv_flit_number;
769
        for (i=0;i<NE;i++){
770
                // a packet has been received
771
                if(traffic[i]->update & ~reset){
772
                        update_noc_statistic (i) ;
773
                }
774
                // the header flit has been sent out
775
                if(traffic[i]->hdr_flit_sent ){
776
                        traffic[i]->pck_class_in=  pck_class_in_gen( i);
777
                        sent_core_total_pck_num[i]++;
778
                        traffic[i]->pck_size_in=get_new_pck_size();
779
                        if(!FIXED_SRC_DST_PAIR){
780
                                dest_e_addr=pck_dst_gen (i);
781
                                traffic[i]->dest_e_addr= dest_e_addr;
782
                                if(dest_e_addr == INJECT_OFF) traffic[i]->stop=1;
783
                                //printf("src=%u, dest=%x\n", i,endp_addr_decoder(dest_e_addr));
784
                        }
785
                }
786
 
787
                        if(traffic[i]->flit_out_wr==1){
788
                                total_sent_flit_number++;
789
                                #if (C>1)
790
                                        sent_stat [i][traffic[i]->flit_out_class].flit_num++;
791
                                #else
792
                                        sent_stat [i].flit_num++;
793
                                #endif
794
                        }
795
                        if(traffic[i]->flit_in_wr==1){
796
                                total_rsv_flit_number++;
797
                                #if (C>1)
798
                                        rsvd_stat [i][traffic[i]->pck_class_out].flit_num++;
799
                                #else
800
                                        rsvd_stat [i].flit_num++;
801
                                #endif
802
                        }
803
                        if(traffic[i]->hdr_flit_sent==1){
804
                                total_sent_pck_num++;
805
                                #if (C>1)
806
                                        sent_stat [i][traffic[i]->flit_out_class].pck_num++;
807
                                #else
808
                                        sent_stat [i].pck_num++;
809
                                #endif
810
                        }
811
 
812
                }//for
813
 
814
 
815
                        if(inject_done){
816
                                if(total_rsv_flit_number_old == total_rsv_flit_number){
817
                                                ideal_rsv_cnt++;
818
                                                if(ideal_rsv_cnt >= 100){
819
                                                        print_statistic( );
820
                                                        fprintf(stderr,"ERROR: The number of sent (%u) & received flits (%u) were not equal at the end of simulation\n",total_sent_flit_number, total_rsv_flit_number);
821
                                                        exit(1);
822
                                                }
823
                                }
824
                                if(total_sent_flit_number == total_rsv_flit_number ) simulation_done=1;
825
                        }
826
        connect_clk_reset_start_all();
827
        sim_eval_all();
828
 
829
}
830
 
831
 
832 32 alirezamon
/**********************************
833
 *
834
 *      update_noc_statistic
835
 *
836
 *
837
 *********************************/
838
 
839 48 alirezamon
 
840
 
841
void update_statistic_at_ejection (
842
        int     core_num,
843
        unsigned int    clk_num_h2h,
844
        unsigned int    clk_num_h2t,
845
        unsigned int    distance,
846
        unsigned int    class_num,
847
        unsigned int    src     ){
848
 
849
        total_rsv_pck_num+=1;
850
 
851
        if( TRAFFIC_TYPE != NETRACE){
852
 
853
        //old st
854
        if((total_rsv_pck_num & 0Xffff )==0 ) printf(" packet sent total=%d\n",total_rsv_pck_num);
855 38 alirezamon
        sum_clk_h2h+=clk_num_h2h;
856
        sum_clk_h2t+=clk_num_h2t;
857 32 alirezamon
#if (STND_DEV_EN)
858 38 alirezamon
        sum_clk_pow2+=(double)clk_num_h2h * (double) clk_num_h2h;
859
        sum_clk_pow2_per_class[class_num]+=(double)clk_num_h2h * (double) clk_num_h2h;
860 43 alirezamon
#endif                                          
861 38 alirezamon
        sum_clk_per_hop+= ((double)clk_num_h2h/(double)distance);
862 48 alirezamon
        //printf("sum_clk_per_hop(%f)+= clk_num_h2h(%u)/distance(%u)\n",sum_clk_per_hop,clk_num_h2h,distance);
863
        total_rsv_pck_num_per_class[class_num]+=1;
864 38 alirezamon
        sum_clk_h2h_per_class[class_num]+=clk_num_h2h ;
865
        sum_clk_h2t_per_class[class_num]+=clk_num_h2t ;
866
        sum_clk_per_hop_per_class[class_num]+= ((double)clk_num_h2h/(double)distance);
867
        rsvd_core_total_pck_num[core_num]=rsvd_core_total_pck_num[core_num]+1;
868 48 alirezamon
 
869
                if (rsvd_core_worst_delay[core_num] < clk_num_h2t) rsvd_core_worst_delay[core_num] = (strcmp (AVG_LATENCY_METRIC,"HEAD_2_TAIL")==0)?  clk_num_h2t :  clk_num_h2h;
870
                if (sent_core_worst_delay[src] < clk_num_h2t) sent_core_worst_delay[src] = (strcmp (AVG_LATENCY_METRIC,"HEAD_2_TAIL")==0)?  clk_num_h2t :  clk_num_h2h;
871
 
872
                if( traffic[core_num]->pck_size_o >= MIN_PACKET_SIZE && traffic[core_num]->pck_size_o <=MAX_PACKET_SIZE){
873
                  if(rsv_size_array!=NULL)      rsv_size_array[traffic[core_num]->pck_size_o-MIN_PACKET_SIZE]++;
874
                }
875
        }
876
    //new one TODO remove old st
877
 
878
        if(verbosity==0 &&  TRAFFIC_TYPE == NETRACE) if((total_rsv_pck_num & 0X1FFFF )==0 ) printf(" packet sent total=%d\n",total_rsv_pck_num);
879
    unsigned int latency = (strcmp (AVG_LATENCY_METRIC,"HEAD_2_TAIL")==0)? clk_num_h2t :  clk_num_h2h;
880
    #if(C>1)
881
 
882
        rsvd_stat[core_num][class_num].pck_num ++;
883
        rsvd_stat[core_num][class_num].sum_clk_h2h +=clk_num_h2h;
884
        rsvd_stat[core_num][class_num].sum_clk_h2t +=clk_num_h2t;
885
        rsvd_stat[core_num][class_num].sum_clk_per_hop+= ((double)clk_num_h2h/(double)distance);
886
        if (rsvd_stat[core_num][class_num].worst_latency < latency ) rsvd_stat[core_num][class_num].worst_latency =latency;
887
        if (rsvd_stat[core_num][class_num].min_latency==0          ) rsvd_stat[core_num][class_num].min_latency   =latency;
888
        if (rsvd_stat[core_num][class_num].min_latency   > latency ) rsvd_stat[core_num][class_num].min_latency   =latency;
889
        if (sent_stat[src     ][class_num].worst_latency < latency ) sent_stat[src     ][class_num].worst_latency =latency;
890
        if (sent_stat[src     ][class_num].min_latency==0          ) sent_stat[src     ][class_num].min_latency   =latency;
891
        if (sent_stat[src     ][class_num].min_latency   > latency ) sent_stat[src     ][class_num].min_latency   =latency;
892
 
893
                #if (STND_DEV_EN)
894
                rsvd_stat[core_num][class_num].sum_clk_pow2 += (double)clk_num_h2h * (double) clk_num_h2h;
895
                #endif
896
        #else
897
        rsvd_stat[core_num].pck_num ++;
898
        rsvd_stat[core_num].sum_clk_h2h +=(double)clk_num_h2h;
899
        rsvd_stat[core_num].sum_clk_h2t +=(double)clk_num_h2t;
900
        rsvd_stat[core_num].sum_clk_per_hop+= ((double)clk_num_h2h/(double)distance);
901
        if (rsvd_stat[core_num].worst_latency < latency ) rsvd_stat[core_num].worst_latency=latency;
902
        if (rsvd_stat[core_num].min_latency==0          ) rsvd_stat[core_num].min_latency  =latency;
903
        if (rsvd_stat[core_num].min_latency   > latency ) rsvd_stat[core_num].min_latency  =latency;
904
        if (sent_stat[src     ].worst_latency < latency ) sent_stat[src     ].worst_latency=latency;
905
        if (sent_stat[src     ].min_latency==0          ) sent_stat[src     ].min_latency  =latency;
906
        if (sent_stat[src     ].min_latency   > latency ) sent_stat[src     ].min_latency  =latency;
907
 
908
                #if (STND_DEV_EN)
909
                rsvd_stat[core_num].sum_clk_pow2 += (double)clk_num_h2h * (double) clk_num_h2h;
910
                #endif
911
        #endif
912
 
913
 
914
 
915
 
916
 
917 38 alirezamon
}
918 32 alirezamon
 
919 48 alirezamon
void update_noc_statistic (     int     core_num){
920
        unsigned int    clk_num_h2h =traffic[core_num]->time_stamp_h2h;
921
        unsigned int    clk_num_h2t =traffic[core_num]->time_stamp_h2t;
922
    unsigned int    distance=traffic[core_num]->distance;
923
    unsigned int        class_num=traffic[core_num]->pck_class_out;
924
    unsigned int    src_e_addr=traffic[core_num]->src_e_addr;
925
    unsigned int        src = endp_addr_decoder (src_e_addr);
926 32 alirezamon
 
927 48 alirezamon
    update_statistic_at_ejection ( core_num,    clk_num_h2h,  clk_num_h2t,  distance,   class_num,      src);
928 32 alirezamon
 
929 48 alirezamon
 
930
}
931
 
932
avg_st_t finilize_statistic (unsigned long int total_clk, statistic_t rsvd_stat){
933
 
934
         avg_st_t avg_statistic;
935
         avg_statistic.avg_throughput= ((double)(rsvd_stat.flit_num*100)/NE )/total_clk;
936
         avg_statistic.avg_latency_flit    = rsvd_stat.sum_clk_h2h/rsvd_stat.pck_num;
937
         avg_statistic.avg_latency_pck     = rsvd_stat.sum_clk_h2t/rsvd_stat.pck_num;
938
         avg_statistic.avg_latency_per_hop = ( rsvd_stat.pck_num==0)? 0 : rsvd_stat.sum_clk_per_hop/rsvd_stat.pck_num;
939
         avg_statistic.avg_pck_siz        = ( rsvd_stat.pck_num==0)? 0 : (double)(rsvd_stat.flit_num / rsvd_stat.pck_num);
940
         #if (STND_DEV_EN)
941
                 avg_statistic.std_dev =standard_dev( rsvd_stat.sum_clk_pow2,rsvd_stat.pck_num, avg_statistic.avg_latency_flit);
942
         #endif
943
         return avg_statistic;
944
}
945
 
946
template<typename T>
947
        void myout(T value)
948
        {
949
           std::cout << value << std::endl;
950
        }
951
template<typename First, typename ... Rest>
952
        void myout(First first, Rest ... rest)
953
        {
954
           std::cout << first << ",";
955
           myout(rest...);
956
        }
957
 
958
void print_st_single (unsigned long int total_clk, statistic_t rsvd_stat, statistic_t sent_stat){
959
 
960
 
961
 
962
        avg_st_t avg;
963
        avg=finilize_statistic (total_clk,  rsvd_stat);
964
 
965
        myout(
966
                        sent_stat.pck_num,
967
                        rsvd_stat.pck_num,
968
                        sent_stat.flit_num,
969
                        rsvd_stat.flit_num,
970
                        sent_stat.worst_latency,
971
                        rsvd_stat.worst_latency,
972
                        sent_stat.min_latency,
973
                        rsvd_stat.min_latency,
974
                        avg.avg_latency_per_hop,
975
                        avg.avg_latency_flit,
976
                        avg.avg_latency_pck,
977
                        avg.avg_throughput,
978
                        avg.avg_pck_siz,
979
                        #if (STND_DEV_EN)
980
                        avg.std_dev
981
                        #endif
982
        );
983
//      printf("\n");
984
 
985
}
986
 
987
 
988
void merge_statistic (statistic_t * merge_stat, statistic_t stat_in){
989
        merge_stat->pck_num+=stat_in.pck_num;
990
        merge_stat->flit_num+=stat_in.flit_num;
991
        if(merge_stat->worst_latency <  stat_in.worst_latency) merge_stat->worst_latency= stat_in.worst_latency;
992
        if(merge_stat->min_latency   == 0                       ) merge_stat->min_latency  = stat_in.min_latency;
993
        if(merge_stat->min_latency   > stat_in.min_latency  && stat_in.min_latency!=0   ) merge_stat->min_latency  = stat_in.min_latency;
994
        merge_stat->sum_clk_h2h      +=stat_in.sum_clk_h2h    ;
995
        merge_stat->sum_clk_h2t      +=stat_in.sum_clk_h2t    ;
996
        merge_stat->sum_clk_per_hop  +=stat_in.sum_clk_per_hop;
997
        #if (STND_DEV_EN)
998
                merge_stat->sum_clk_pow2 +=stat_in.sum_clk_pow2;
999
    #endif
1000
 
1001
}
1002
 
1003
void print_statistic_new (unsigned long int total_clk){
1004 32 alirezamon
        int i;
1005 48 alirezamon
        printf("\n\t#node,"
1006
                        "sent_stat.pck_num,"
1007
                        "rsvd_stat.pck_num,"
1008
                        "sent_stat.flit_num,"
1009
                        "rsvd_stat.flit_num,"
1010
                        "sent_stat.worst_latency,"
1011
                        "rsvd_stat.worst_latency,"
1012
                        "sent_stat.min_latency,"
1013
                        "rsvd_stat.min_latency,"
1014
                        "avg_latency_per_hop,"
1015
                        "avg_latency_flit,"
1016
                        "avg_latency_pck,"
1017
                        "avg_throughput(%%),"
1018
                        "avg_pck_size,"
1019
                        #if (STND_DEV_EN)
1020
                        "avg.std_dev"
1021
                        #endif
1022
                        "\n");
1023
 
1024
 
1025
 
1026
#if(C>1)
1027
        int c;
1028
        statistic_t sent_stat_class [NE];
1029
        statistic_t rsvd_stat_class [NE];
1030
        statistic_t sent_stat_per_class [C];
1031
        statistic_t rsvd_stat_per_class [C];
1032
 
1033
        memset (&rsvd_stat_class,0,sizeof(statistic_t)*NE);
1034
        memset (&sent_stat_class,0,sizeof(statistic_t)*NE);
1035
        memset (&rsvd_stat_per_class,0,sizeof(statistic_t)*C);
1036
        memset (&sent_stat_per_class,0,sizeof(statistic_t)*C);
1037
 
1038
 
1039
        for (i=0; i<NE;i++){
1040
                for (c=0; c<C;c++){
1041
                        merge_statistic (&rsvd_stat_class[i],rsvd_stat[i][c]);
1042
                        merge_statistic (&sent_stat_class[i],sent_stat[i][c]);
1043
                        merge_statistic (&rsvd_stat_per_class[c],rsvd_stat[i][c]);
1044
                        merge_statistic (&sent_stat_per_class[c],sent_stat[i][c]);
1045
                }
1046
        }
1047
 
1048
 
1049
 
1050
 
1051
#else
1052
        #define sent_stat_class  sent_stat
1053
        #define rsvd_stat_class  rsvd_stat
1054 32 alirezamon
#endif
1055
 
1056 48 alirezamon
 
1057
 
1058
 
1059
 
1060
        statistic_t rsvd_stat_total, sent_stat_total;
1061
        memset (&rsvd_stat_total,0,sizeof(statistic_t));
1062
        memset (&sent_stat_total,0,sizeof(statistic_t));
1063
        for (i=0; i<NE;i++){
1064
                merge_statistic (&rsvd_stat_total,rsvd_stat_class[i]);
1065
                merge_statistic (&sent_stat_total,sent_stat_class[i]);
1066
        }
1067
        printf("\ttotal,");
1068
        print_st_single (total_clk, rsvd_stat_total,sent_stat_total);
1069
 
1070
#if(C>1)
1071
        for (c=0; c<C;c++){
1072
                printf("\ttotal_class%u,",c);
1073
                print_st_single (total_clk, rsvd_stat_per_class[c],sent_stat_per_class[c]);
1074
        }
1075 32 alirezamon
#endif
1076 48 alirezamon
 
1077
    for (i=0; i<NE;i++){
1078
        printf("\t%u,",i);
1079
        print_st_single (total_clk, rsvd_stat_class[i],sent_stat_class[i] );
1080
    }
1081 32 alirezamon
}
1082
 
1083
 
1084
 
1085 48 alirezamon
void print_statistic (void){
1086
        double avg_latency_per_hop,  avg_latency_flit, avg_latency_pck, avg_throughput,min_avg_latency_per_class;
1087
        int i;
1088
#if (STND_DEV_EN)
1089
        double  std_dev;
1090
#endif
1091 32 alirezamon
 
1092 48 alirezamon
        avg_throughput= ((double)(total_sent_flit_number*100)/total_active_endp )/clk_counter;
1093
        printf(" Total active Endpoint: %d \n",total_active_endp);
1094
        printf(" Avg throughput is: %f (flits/clk/Total active Endpoint %%)\n",    avg_throughput);
1095
        avg_latency_flit   = (double)sum_clk_h2h/total_rsv_pck_num;
1096
        avg_latency_pck    = (double)sum_clk_h2t/total_rsv_pck_num;
1097
        if(ratio==RATIO_INIT) first_avg_latency_flit=avg_latency_flit;
1098 32 alirezamon
#if (STND_DEV_EN)
1099 48 alirezamon
        std_dev= standard_dev( sum_clk_pow2,total_rsv_pck_num, avg_latency_flit);
1100
        printf(" standard_dev = %f\n",std_dev);
1101
#endif
1102
    avg_latency_per_hop    = (double)sum_clk_per_hop/total_rsv_pck_num;
1103
    printf("\nall : \n");
1104
        printf(" Total number of packet = %d \n average latency per hop = %f \n",total_rsv_pck_num,avg_latency_per_hop);
1105
        printf(" average packet latency = %f \n average flit latency = %f \n",avg_latency_pck, avg_latency_flit);
1106
    min_avg_latency_per_class=1000000;
1107
    printf(" Total injected packet in different size:\n");
1108
    for (i=0;i<=(MAX_PACKET_SIZE - MIN_PACKET_SIZE);i++){
1109
        if(rsv_size_array[i]>0) printf("\t %u flit_sized pck = %u\n",i+ MIN_PACKET_SIZE, rsv_size_array[i]);
1110
    }
1111
    printf("\n");
1112 32 alirezamon
 
1113 48 alirezamon
    for(i=0;i<C;i++){
1114
                avg_throughput           = (total_rsv_pck_num_per_class[i]>0)? ((double)(total_rsv_pck_num_per_class[i]*AVG_PACKET_SIZE*100)/total_active_endp )/clk_counter:0;
1115
                        avg_latency_flit         = (total_rsv_pck_num_per_class[i]>0)? (double)sum_clk_h2h_per_class[i]/total_rsv_pck_num_per_class[i]:0;
1116
                        avg_latency_pck          = (total_rsv_pck_num_per_class[i]>0)? (double)sum_clk_h2t_per_class[i]/total_rsv_pck_num_per_class[i]:0;
1117
                        avg_latency_per_hop  = (total_rsv_pck_num_per_class[i]>0)? (double)sum_clk_per_hop_per_class[i]/total_rsv_pck_num_per_class[i]:0;
1118
                        printf ("\nclass : %d  \n",i);
1119
                printf (" Total number of packet = %d \n avg_throughput = %f \n average latency per hop = %f \n ",total_rsv_pck_num_per_class[i],avg_throughput,avg_latency_per_hop);
1120
            printf (" average packet latency = %f \n average flit latency = %f \n",avg_latency_pck,avg_latency_flit);
1121
            if(min_avg_latency_per_class > avg_latency_flit) min_avg_latency_per_class=avg_latency_flit;
1122
 
1123
#if (STND_DEV_EN)
1124
            std_dev= (total_rsv_pck_num_per_class[i]>0)?  standard_dev( sum_clk_pow2_per_class[i],total_rsv_pck_num_per_class[i], avg_latency_flit):0;
1125
            printf(" standard_dev = %f\n",std_dev);
1126 32 alirezamon
#endif
1127 48 alirezamon
        }//for
1128
        current_avg_latency_flit=min_avg_latency_per_class;
1129 43 alirezamon
        for (i=0;i<NE;i++) {
1130 48 alirezamon
                printf   ("\n\nEnd_point %d\n",i);
1131
                printf   ("\n\ttotal number of received packets: %u\n",rsvd_core_total_pck_num[i]);
1132
                printf   ("\n\tworst-case-delay of received packets (clks): %u\n",rsvd_core_worst_delay[i] );
1133
                printf   ("\n\ttotal number of sent packets: %u\n",traffic[i]->pck_number);
1134
                printf   ("\n\tworst-case-delay of sent packets (clks): %u\n",sent_core_worst_delay[i] );
1135 38 alirezamon
        }
1136 48 alirezamon
 
1137
        print_statistic_new (clk_counter);
1138
 
1139
 
1140 43 alirezamon
}
1141 32 alirezamon
 
1142
 
1143
void print_parameter (){
1144 48 alirezamon
                printf ("NoC parameters:---------------- \n");
1145 32 alirezamon
                printf ("\tTopology: %s\n",TOPOLOGY);
1146
                printf ("\tRouting algorithm: %s\n",ROUTE_NAME);
1147
                printf ("\tVC_per port: %d\n", V);
1148 48 alirezamon
                printf ("\tNon-local port buffer_width per VC: %d\n", B);
1149
                printf ("\tLocal port buffer_width per VC: %d\n", LB);
1150 43 alirezamon
if((strcmp (TOPOLOGY,"MESH")==0)||(strcmp (TOPOLOGY,"TORUS")==0)){
1151
            printf ("\tRouter num in row: %d \n",T1);
1152
            printf ("\tRouter num in column: %d \n",T2);
1153 48 alirezamon
            printf ("\tEndpoint num per router: %d\n",T3);
1154 43 alirezamon
}else if ((strcmp (TOPOLOGY,"RING")==0)||(strcmp (TOPOLOGY,"LINE")==0)){
1155 48 alirezamon
                printf ("\tTotal Router num: %d \n",T1);
1156
                printf ("\tEndpoint num per router: %d\n",T3);
1157 43 alirezamon
}
1158 48 alirezamon
else if ((strcmp (TOPOLOGY,"TREE")==0)||(strcmp (TOPOLOGY,"FATTREE")==0)){
1159 43 alirezamon
                printf ("\tK: %d \n",T1);
1160
                printf ("\tL: %d \n",T2);
1161 48 alirezamon
} else{ //CUSTOM
1162
            printf ("\tTotal Endpoints number: %d \n",T1);
1163
                printf ("\tTotal Routers number: %d \n",T2);
1164 43 alirezamon
}
1165 32 alirezamon
            printf ("\tNumber of Class: %d\n", C);
1166
            printf ("\tFlit data width: %d \n", Fpay);
1167
            printf ("\tVC reallocation mechanism: %s \n",  VC_REALLOCATION_TYPE);
1168
            printf ("\tVC/sw combination mechanism: %s \n", COMBINATION_TYPE);
1169
            printf ("\tAVC_ATOMIC_EN:%d \n", AVC_ATOMIC_EN);
1170
            printf ("\tCongestion Index:%d \n",CONGESTION_INDEX);
1171
            printf ("\tADD_PIPREG_AFTER_CROSSBAR:%d\n",ADD_PIPREG_AFTER_CROSSBAR);
1172 38 alirezamon
            printf ("\tSSA_EN enabled:%s \n",SSA_EN);
1173
            printf ("\tSwitch allocator arbitration type:%s \n",SWA_ARBITER_TYPE);
1174 43 alirezamon
            printf ("\tMinimum supported packet size:%d flit(s) \n",MIN_PCK_SIZE);
1175 48 alirezamon
            printf ("\tLoop back is enabled:%s",SELF_LOOP_EN);
1176
            printf ("\tNumber of multihop bypass (SMART max):%d \n",SMART_MAX);
1177
        printf ("NoC parameters:---------------- \n");
1178
        printf ("\nSimulation parameters-------------\n");
1179 32 alirezamon
#if(DEBUG_EN)
1180 38 alirezamon
    printf ("\tDebuging is enabled\n");
1181 32 alirezamon
#else
1182 38 alirezamon
    printf ("\tDebuging is disabled\n");
1183 32 alirezamon
#endif
1184 48 alirezamon
        //if(strcmp (AVG_LATENCY_METRIC,"HEAD_2_TAIL")==0)printf ("\tOutput is the average latency on sending the packet header until receiving tail\n");
1185
        //else printf ("\tOutput is the average latency on sending the packet header until receiving header flit at destination node\n");
1186 32 alirezamon
        printf ("\tTraffic pattern:%s\n",TRAFFIC);
1187 48 alirezamon
        size_t n = sizeof(class_percentage)/sizeof(class_percentage[0]);
1188
        for(int p=0;p<n; p++){
1189
                printf ("\ttraffic percentage of class %u is : %d\n",p,  class_percentage[p]);
1190
        }
1191 38 alirezamon
        if(strcmp (TRAFFIC,"HOTSPOT")==0){
1192
                //printf ("\tHot spot percentage: %u\n", HOTSPOT_PERCENTAGE);
1193 32 alirezamon
            printf ("\tNumber of hot spot cores: %d\n", HOTSPOT_NUM);
1194
 
1195
        }
1196
            //printf ("\tTotal packets sent by one router: %u\n", TOTAL_PKT_PER_ROUTER);
1197 48 alirezamon
                if(sim_end_clk_num!=0) printf ("\tSimulation timeout =%d\n", sim_end_clk_num);
1198
                if(end_sim_pck_num!=0) printf ("\tSimulation ends on total packet num of =%d\n", end_sim_pck_num);
1199
                if(TRAFFIC_TYPE!=NETRACE){
1200
                        printf ("\tPacket size (min,max,average) in flits: (%u,%u,%u)\n",MIN_PACKET_SIZE,MAX_PACKET_SIZE,AVG_PACKET_SIZE);
1201
                        printf ("\tPacket injector FIFO width in flit:%u \n",TIMSTMP_FIFO_NUM);
1202
                }
1203
                if( TRAFFIC_TYPE == SYNTHETIC) printf("\tFlit injection ratio per router is =%f (flits/clk/Total Endpoint %%)\n",(float)ratio*100/MAX_RATIO);
1204
                printf ("Simulation parameters-------------\n");
1205 32 alirezamon
}
1206
 
1207
 
1208 38 alirezamon
 
1209
 
1210
 
1211 32 alirezamon
/************************
1212
 *
1213
 *      reset system
1214
 *
1215
 *
1216
 * *******************/
1217
 
1218
void reset_all_register (void){
1219
        int i;
1220 48 alirezamon
         total_active_endp=0;
1221
         total_rsv_pck_num=0;
1222
         total_sent_pck_num=0;
1223 32 alirezamon
         sum_clk_h2h=0;
1224
         sum_clk_h2t=0;
1225 48 alirezamon
         ideal_rsv_cnt=0;
1226 32 alirezamon
#if (STND_DEV_EN)
1227
         sum_clk_pow2=0;
1228
#endif
1229
 
1230
         sum_clk_per_hop=0;
1231
         count_en=0;
1232
         clk_counter=0;
1233
 
1234
         for(i=0;i<C;i++)
1235
         {
1236 48 alirezamon
                 total_rsv_pck_num_per_class[i]=0;
1237 32 alirezamon
             sum_clk_h2h_per_class[i]=0;
1238
             sum_clk_h2t_per_class[i]=0;
1239
                 sum_clk_per_hop_per_class[i]=0;
1240
#if (STND_DEV_EN)
1241
                 sum_clk_pow2_per_class[i]=0;
1242
#endif
1243
 
1244
         }  //for
1245 48 alirezamon
         total_sent_flit_number=0;
1246
 
1247
 
1248 32 alirezamon
}
1249
 
1250
 
1251
 
1252
 
1253
/***********************
1254
 *
1255
 *      standard_dev
1256
 *
1257
 * ******************/
1258
 
1259
#if (STND_DEV_EN)
1260 42 alirezamon
/************************
1261
 * std_dev = sqrt[(B-A^2/N)/N]  = sqrt [(B/N)- (A/N)^2] = sqrt [B/N - mean^2]
1262
 * A = sum of the values
1263
 * B = sum of the squarded values
1264
 * *************/
1265 32 alirezamon
 
1266
double standard_dev( double sum_pow2, unsigned int  total_num, double average){
1267
        double std_dev;
1268 42 alirezamon
 
1269
        /*
1270
        double  A, B, N;
1271
        N= total_num;
1272
        A= average * N;
1273
        B= sum_pow2;
1274 32 alirezamon
 
1275 42 alirezamon
        A=(A*A)/N;
1276
        std_dev = (B-A)/N;
1277 32 alirezamon
        std_dev = sqrt(std_dev);
1278 42 alirezamon
*/
1279 48 alirezamon
        if(total_num==0) return 0;
1280 32 alirezamon
 
1281 42 alirezamon
        std_dev = sum_pow2/(double)total_num; //B/N
1282
        std_dev -= (average*average);// (B/N) - mean^2
1283
        std_dev = sqroot(std_dev);// sqrt [B/N - mean^2]
1284
 
1285 32 alirezamon
        return std_dev;
1286
 
1287
}
1288
 
1289
#endif
1290
 
1291
 
1292
 
1293
/**********************
1294
 *
1295
 *      pck_class_in_gen
1296
 *
1297
 * *****************/
1298
 
1299
unsigned char  pck_class_in_gen(
1300
         unsigned int  core_num
1301
 
1302
) {
1303
        unsigned char pck_class_in;
1304
        unsigned char  rnd=rand()%100;
1305 48 alirezamon
        int c=0;
1306
        int sum=class_percentage[0];
1307
        size_t n = sizeof(class_percentage)/sizeof(class_percentage[0]);
1308
        for(;;){
1309
                if( rnd < sum) return c;
1310
                if( c==n-1 ) return c;
1311
                c++;
1312
                sum+=class_percentage[c];
1313
        }
1314
        return 0;
1315 32 alirezamon
}
1316
 
1317 38 alirezamon
 
1318 32 alirezamon
 
1319
 
1320 38 alirezamon
void update_injct_var(unsigned int src,  unsigned int injct_var){
1321
        //printf("before%u=%u\n",src,random_var[src]);
1322
        random_var[src]= rnd_between(100-injct_var, 100+injct_var);
1323
        //printf("after=%u\n",random_var[src]);
1324
}
1325
 
1326
unsigned int pck_dst_gen_task_graph ( unsigned int src){
1327
         task_t  task;
1328
        float f,v;
1329
 
1330
        int index = task_graph_abstract[src].active_index;
1331
 
1332
        if(index == DISABLE){
1333
                traffic[src]->ratio=0;
1334
                traffic[src]->stop=1;
1335 48 alirezamon
                 return INJECT_OFF; //disable sending
1336 38 alirezamon
        }
1337
 
1338
        if(     read(task_graph_data[src],index,&task)==0){
1339
                traffic[src]->ratio=0;
1340
                traffic[src]->stop=1;
1341 48 alirezamon
                 return INJECT_OFF; //disable sending
1342 38 alirezamon
 
1343
        }
1344
 
1345
        if(sent_core_total_pck_num[src] & 0xFF){//sent 255 packets
1346
                        //printf("uu=%u\n",task.jnjct_var);
1347
                        update_injct_var(src, task.jnjct_var);
1348
 
1349
                }
1350
 
1351
        task_graph_total_pck_num++;
1352
        task.pck_sent = task.pck_sent +1;
1353
        task.burst_sent= task.burst_sent+1;
1354
        task.byte_sent = task.byte_sent + (task.avg_pck_size * (Fpay/8) );
1355
 
1356
        traffic[src]->pck_class_in=  pck_class_in_gen(src);
1357 48 alirezamon
        //traffic[src]->avg_pck_size_in=task.avg_pck_size;
1358 38 alirezamon
        traffic[src]->pck_size_in=rnd_between(task.min_pck_size,task.max_pck_size);
1359
 
1360
        f=  task.injection_rate;
1361
        v= random_var[src];
1362
        f*= (v /100);
1363
        if(f>100) f= 100;
1364
        f=  f * MAX_RATIO / 100;
1365
 
1366
        traffic[src]->ratio=(unsigned int)f;
1367
        traffic[src]->init_weight=task.initial_weight;
1368
 
1369
        if (task.burst_sent >= task.burst_size){
1370
                task.burst_sent=0;
1371
                task_graph_abstract[src].active_index=task_graph_abstract[src].active_index+1;
1372
                if(task_graph_abstract[src].active_index>=task_graph_abstract[src].total_index) task_graph_abstract[src].active_index=0;
1373
 
1374
        }
1375
 
1376
        update_by_index(task_graph_data[src],index,task);
1377
 
1378
        if (task.byte_sent  >= task.bytes){ // This task is done remove it from the queue
1379
                                remove_by_index(&task_graph_data[src],index);
1380
                                task_graph_abstract[src].total_index = task_graph_abstract[src].total_index-1;
1381
                                if(task_graph_abstract[src].total_index==0){ //all tasks are done turned off the core
1382
                                        task_graph_abstract[src].active_index=-1;
1383
                                        traffic[src]->ratio=0;
1384
                                        traffic[src]->stop=1;
1385
                                        if(total_active_routers!=0) total_active_routers--;
1386 48 alirezamon
                                        return INJECT_OFF;
1387 38 alirezamon
                                }
1388
                                if(task_graph_abstract[src].active_index>=task_graph_abstract[src].total_index) task_graph_abstract[src].active_index=0;
1389
        }
1390
 
1391 48 alirezamon
        return endp_addr_encoder(task.dst);
1392 38 alirezamon
}
1393
 
1394
 
1395
 
1396
 
1397
 
1398
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.