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 54

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 54 alirezamon
 
23 48 alirezamon
#include "simulator.h"
24 32 alirezamon
 
25 54 alirezamon
 
26
 
27
 
28 48 alirezamon
int main(int argc, char** argv) {
29
        char change_injection_ratio=0;
30
        int i,j,x,y;//,report_delay_counter=0;
31 32 alirezamon
 
32 48 alirezamon
        char deafult_out[] = {"result"};
33
        NEw=Log2(NE);
34
        for(i=0;i<NE;i++)   custom_traffic_table[i]=INJECT_OFF; //off
35
        Verilated::commandArgs(argc, argv);   // Remember args
36
        processArgs ( argc,  argv );
37 54 alirezamon
        allocate_rsv_pck_counters();
38 48 alirezamon
        if (class_percentage==NULL) {
39
                        class_percentage =   (int *) malloc(sizeof(int));
40
                        class_percentage[0]=100;
41 42 alirezamon
        }
42 32 alirezamon
 
43
 
44 48 alirezamon
        Vrouter_new();
45 54 alirezamon
        if (ENDP_TYPE == PCK_INJECTOR)  for(i=0;i<NE;i++)        pck_inj[i]  = new Vpck_inj;
46 48 alirezamon
        else                            for(i=0;i<NE;i++)        traffic[i]  = new Vtraffic;
47 32 alirezamon
 
48
 
49 48 alirezamon
 
50
        FIXED_SRC_DST_PAIR = strcmp (TRAFFIC,"RANDOM") &  strcmp(TRAFFIC,"HOTSPOT") & strcmp(TRAFFIC,"random") & strcmp(TRAFFIC,"hot spot") & strcmp(TRAFFIC,"TASK");
51
 
52
 
53
        /********************
54
        *       initialize input
55
        *********************/
56
 
57
        reset=1;
58
        reset_all_register();
59
        start_i=0;
60 54 alirezamon
 
61
        mcast_init();
62
 
63
 
64
 
65 48 alirezamon
        topology_init();
66 54 alirezamon
        if( TRAFFIC_TYPE == NETRACE){
67
                netrace_init(netrace_file); // should be called first to initiate header
68
                pck_inj_init((int)header->num_nodes);
69
        }
70
        else if (TRAFFIC_TYPE ==SYNFUL) {
71
                pck_inj_init(SYNFUL_ENDP_NUM); //should be called first to initiate node mapping needed by synful lib
72
                synful_init(synful_file,synful_SSExit,synful_random_seed,sim_end_clk_num,end_sim_pck_num);
73
        }
74 48 alirezamon
        else    traffic_gen_init();
75 54 alirezamon
 
76
 
77
 
78 48 alirezamon
        main_time=0;
79
        print_parameter();
80
        if( thread_num>1) initial_threads();
81
 
82
        while (!Verilated::gotFinish()) {
83
 
84
                if (main_time-saved_time >= 10 ) {
85
                        reset = 0;
86
                }
87
 
88
                if(main_time == saved_time+21){ count_en=1; start_i=1;}
89
                if(main_time == saved_time+23) start_i=0;
90
 
91
                if(TRAFFIC_TYPE==NETRACE) netrace_posedge_event();
92 54 alirezamon
                else if(TRAFFIC_TYPE ==SYNFUL) synful_posedge_event();
93 48 alirezamon
                else traffic_clk_posedge_event();
94 54 alirezamon
 
95
 
96 48 alirezamon
                //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
97
                //between modules when the clock .
98
                for (i=0;i<SMART_MAX+2;i++) {
99 54 alirezamon
                        if(TRAFFIC_TYPE==NETRACE) netrace_negedge_event();
100
                        else if(TRAFFIC_TYPE ==SYNFUL) synful_negedge_event();
101 48 alirezamon
                        else traffic_clk_negedge_event( );
102
                }
103
 
104
                if(simulation_done){
105 54 alirezamon
 
106 48 alirezamon
                        if( TRAFFIC_TYPE == NETRACE) netrace_final_report();
107 54 alirezamon
                        else if(TRAFFIC_TYPE ==SYNFUL) synful_final_report();
108 48 alirezamon
                        else traffic_gen_final_report();
109
                        sim_final_all();
110
                        return 0;
111
                }
112
 
113
                main_time++;
114
 
115
        }//Simulating is done
116
 
117
        sim_final_all();
118
        return 0;
119
 
120 32 alirezamon
}
121
 
122
 
123 48 alirezamon
#define __FILENAME__ (__FILE__ + SOURCE_PATH_SIZE)
124
 
125
void  usage(char * bin_name){
126
        printf("Usage:\n"
127
" %s -t <synthetic Traffic Pattern name> [synthetic Traffic options]\n"
128 54 alirezamon
" %s -f <Task file> [Task options]\n"
129
" %s -F <netrace file> [Netrace options] \n"
130
" %s -S <synful model file> [synful options]\n\n"
131 48 alirezamon
"synthetic Traffic options:\n"
132 54 alirezamon
"  -t <Traffic Pattern>        \"HOTSPOT\", \"RANDOM\", \"BIT_COMPLEMENT\" , \"BIT_REVERSE\",\n"
133 48 alirezamon
"                              \"TORNADO\", \"TRANSPOSE1\", \"TRANSPOSE2\", \"SHUFFEL\", \"CUSTOM\"\n"
134
"  -m <Packet size info>       packet size format  Random-Range or Random-discrete:\n"
135
"                              Random-Range : \"R,MIN,MAX\" : The injected packets' size in flits are\n"
136 54 alirezamon
"                              randomly selected in range MIN <= PCK_size <=MAX \n"
137 48 alirezamon
"                              Random-discrete: \"D,S1,S2,..Sn,P,P1,P2,P3,...Pn\": Si are the discrete\n"
138 54 alirezamon
"                              set of numbers representing packet size. The injected packet size is\n"
139
"                              randomly selected among these discrete values according to associated\n"
140
"                              probability values.\n"
141
"  -c <sim_end_clk_num>        The simulation will stop when the simulation clock number reaches this value\n"
142
"  -n <sim_end_pck_num>        The simulation will stop when the total sent packets to the NoC reaches this number\n"
143 48 alirezamon
"  -i <injection ratio>        flit injection ratio in percentage\n"
144 54 alirezamon
"  -p <class traffic ratios>   The percentage of traffic injected for each class. Represented in\n"
145
"                              comma-separated string format:\"n0,n1,n2..\" \n"
146
"  -h <HOTSPOT traffic format> represented in a string with the following format:\n"
147 48 alirezamon
"                              total number of hotspot nodes, first hotspot node ID, first hotspot node\n"
148
"                              send enable(1 or 0),first hotspot node percentage x10,second hotspot node ...\n"
149
"  -H <custom traffic pattern> custom traffic pattern: represented in a string with following format:\n"
150
"                              \"SRC1,DEST1, SRC2,DEST2, .., SRCn, DESTn\"   \n"
151 54 alirezamon
"  -T <thread-num>             total number of threads. The default is one (no-thread).\n"
152
"  -u <Multi/Broadcast format> represented in a string with following format:\n"
153
"                              \"ratio,min_pck_size,max_pck_size\"\n"
154
"                              ratio:The percentage of Multicast/broadcast packets against total injected \n"
155
"                              traffic. The Multicast/Broadcast packet size is randomly selected\n"
156
"                              between min_pck_size and max_pck_size. The max_pck_size must be smaller or equal\n"
157
"                              to the router buffer width. This filed is only valid when the NoC is configured\n"
158
"                              with the Multicast/Broadcast feature support.\n"
159 48 alirezamon
//"  -Q                          Quick (fast) simulation. ignore evaluating non-active routers \n"
160 54 alirezamon
//"                              to speed up simulation time"
161 48 alirezamon
"\nTrace options:\n"
162 54 alirezamon
"  -f <Task file>              Path to the task file. any custom task file can be generated using ProNoC gui\n"
163 48 alirezamon
"  -c <sim_end_clk_num>        Simulation will stop when simulation clock number reach this value \n"
164 54 alirezamon
"  -T <thread-num>             Total number of threads. The default is one (no-thread).\n"
165 48 alirezamon
//"  -Q                          Quick (fast) simulation. ignore evaluating non-active routers \n"
166 54 alirezamon
//"                              to speed up simulation time"
167 48 alirezamon
"\nNetrace options:\n"
168 54 alirezamon
"  -F <Netrace file>           Path to the task file. any custom task file can be generated using ProNoC gui\n"
169
"  -n <sim_end_pck_num>        The simulation will stop when the total sent packets to the NoC reaches this number\n"
170 48 alirezamon
"  -d                          ignore dependencies\n"
171 54 alirezamon
"  -r <start region>           Start region\n"
172
"  -l                          Reader throttling\n"
173
"  -v <level>                  Verbosity level. 0: off, 1:display a live number of injected packets,\n"
174
"                              3: print injected/ejected packets details, The default value is 1\n"
175
"  -T <thread-num>             Total number of threads. The default is one (no-thread).\n"
176
"  -s <speed-up-num>           The speed-up-num  is the ratio of netrace frequency to pronoc.The higher value\n"
177
"                              results in higher injection ratio to the NoC. Default is one\n"
178 48 alirezamon
//"  -Q                          Quick (fast) simulation. ignore evaluating non-active routers \n"
179 54 alirezamon
//"                              to speed up simulation time"
180
"\nsynful options:\n"
181
"  -S <model file>             Path to the synful application model file\n"
182
"  -r <seed value>             Seed value for random function\n"
183
"  -c <sim_end_clk_num>        The simulation will stop when the simulation clock number reaches this value \n"
184
"  -s                          Exit at steady state\n"
185
"  -n <sim_end_pck_num>        The simulation will stop when the total of sent packets to the NoC reaches this number\n"
186
"  -T <thread-num>             Total number of threads. The default is one (no-thread).\n"
187
"  -v <level>                  Verbosity level. 0: off, 1:display a live number of injected packets,\n"
188
"  -w <flit-size>              The synful flit size in Byte. It defines the number of flits that should be set to\n"
189
"                              ProNoC for each synful packets. The ProNoC packet size is:\n"
190
"                              Ceil(synful packet size/synful flit size).\n"
191
"                              3: print injected/ejected packets details, The default value is 1\n",
192
bin_name,bin_name,bin_name,bin_name
193 48 alirezamon
);
194
 
195
}
196
 
197
 
198
 
199
void netrace_processArgs (int argc, char **argv )
200
{
201
   char c;
202
 
203
   /* don't want getopt to moan - I can do that just fine thanks! */
204
   opterr = 0;
205
   if (argc < 2)  usage(argv[0]);
206
   while ((c = getopt (argc, argv, "F:dr:lv:T:n:s:")) != -1)
207
   {
208
         switch (c)
209
         {
210
                case 'F':
211
                        TRAFFIC_TYPE=NETRACE;
212
                        TRAFFIC=(char *) "NETRACE";
213 54 alirezamon
                        ENDP_TYPE = PCK_INJECTOR;
214 48 alirezamon
                        netrace_file = optarg;
215
                        break;
216
                case 'd':
217
                        ignore_dependencies=1;
218
                        break;
219
                case 'r':
220
                        start_region=atoi(optarg);
221
                        break;
222
                case 'l':
223
                        reader_throttling=1;
224
                        break;
225
                case 'v':
226
                        verbosity= atoi(optarg);
227
                        break;
228 54 alirezamon
                case 'T':
229 48 alirezamon
                        thread_num = atoi(optarg);
230
                        break;
231
                case 'n':
232
                        end_sim_pck_num=atoi(optarg);
233
                        break;
234
                case 's':
235
                        netrace_speed_up=atoi(optarg);
236
 
237
                        break;
238
                case '?':
239
                    if (isprint (optopt))
240
                        fprintf (stderr, "Unknown option `-%c'.\n", optopt);
241
                        else
242
                            fprintf (stderr,  "Unknown option character `\\x%x'.\n",  optopt);
243
             default:
244
                       usage(argv[0]);
245
                       exit(1);
246
          }
247
        }
248
}
249
 
250
 
251
 
252
void synthetic_task_processArgs (int argc, char **argv )
253
{
254
   char c;
255
   int p;
256
   int array[10];
257
   float f;
258
 
259
   /* don't want getopt to moan - I can do that just fine thanks! */
260
   opterr = 0;
261
   if (argc < 2)  usage(argv[0]);
262 54 alirezamon
   while ((c = getopt (argc, argv, "t:m:n:c:i:p:h:H:f:T:u:Q")) != -1)
263 48 alirezamon
      {
264
         switch (c)
265
            {
266
                case 'f':
267
                        TRAFFIC_TYPE=TASK;
268
                        TRAFFIC=(char *) "TASK";
269
                        task_traffic_init(optarg);
270
                        break;
271
            case 't':
272
                        TRAFFIC=optarg;
273
                        total_active_routers=-1;
274
                        break;
275
                case 's':
276
                        MIN_PACKET_SIZE=atoi(optarg);
277
                        break;
278
                case 'n':
279
                         end_sim_pck_num=atoi(optarg);
280
                         break;
281
                case 'c':
282
                         sim_end_clk_num=atoi(optarg);
283
                         break;
284
                case 'i':
285
                         f=atof(optarg);
286
                         f*=(MAX_RATIO/100);
287
                         ratio= (int) f;
288
                         break;
289
                case 'p':
290
                        p= parse_string (optarg, array);
291
                        if (p==0) {
292
                                printf("Warning: class setting is ignored!\n");
293
                                break;
294
                        }
295
                        class_percentage =   (int *) malloc( p * sizeof(int));
296
                        for(int k=0;k<p;k++){
297
                                class_percentage[k]=array[k];
298
                        }
299
                        if(p >1 && p>C){
300
                                printf("Warning: the number of given class %u is larger than the number of message classes in ProNoC (C=%u)!\n",p,C);
301
                        }
302
                        break;
303
                case 'm':
304
                        update_pck_size(optarg);
305
 
306
                        break;
307
                case 'H':
308
                        update_custom_traffic(optarg);
309
                        break;
310
                case 'h':
311
                        update_hotspot(optarg);
312
                        break;
313
                case  'T':
314
                        thread_num = atoi(optarg);
315
                        break;
316
                case 'Q':
317
                        //Quick_sim_en=1;
318
                        fprintf (stderr, "Unknown option `-%c'.\n", optopt);
319
                        usage(argv[0]);
320
                        exit(1);
321
                        break;
322 54 alirezamon
                case 'u':
323
                        update_mcast_traffic(optarg);
324
                        break;
325 48 alirezamon
            case '?':
326
               if (isprint (optopt))
327
                  fprintf (stderr, "Unknown option `-%c'.\n", optopt);
328
               else
329
                  fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
330
            default:
331
               usage(argv[0]);
332
               exit(1);
333
            }
334
      }
335
}
336
 
337
 
338
 
339
 
340 54 alirezamon
void synful_processArgs (int argc, char **argv)
341
{
342
   char c;
343
   /* don't want getopt to moan - I can do that just fine thanks! */
344
   opterr = 0;
345
   if (argc < 2)  usage(argv[0]);
346
   while ((c = getopt (argc, argv, "S:c:sn:v:T:r:w:")) != -1)
347
   {
348
         switch (c)
349
         {
350
                case 'S':
351
                        TRAFFIC_TYPE=SYNFUL;
352
                        TRAFFIC=(char *) "SYNFUL";
353
                        synful_file = optarg;
354
                        ENDP_TYPE   =PCK_INJECTOR;
355
                        break;
356
                case 'c':
357
                        sim_end_clk_num=atoi(optarg);
358
                        break;
359
                case 's':
360
                        synful_SSExit =true;
361
                        break;
362
                case 'n':
363
                        end_sim_pck_num=atoi(optarg);
364
                        break;
365
                case 'v':
366
                         verbosity= atoi(optarg);
367
                         break;
368
                case 'w':
369
                         synful_flitw= atoi(optarg);
370
                         break;
371
                case 'T':
372
                        thread_num = atoi(optarg);
373
                        break;
374
                case 'r':
375
                        synful_random_seed = atoi(optarg);
376
                        break;
377
                case '?':
378
                        if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt);
379
                        else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
380
                default:
381
                     usage(argv[0]);
382
                     exit(1);
383
         }//switch
384
   }//while
385
}
386
 
387
 
388
 
389 32 alirezamon
int parse_string ( char * str, int * array)
390
{
391
    int i=0;
392
    char *pt;
393
    pt = strtok (str,",");
394
    while (pt != NULL) {
395
        int a = atoi(pt);
396
        array[i]=a;
397
        i++;
398
        pt = strtok (NULL, ",");
399
    }
400
   return i;
401
}
402
 
403 43 alirezamon
 
404 48 alirezamon
 
405
 
406
 
407
 
408 54 alirezamon
unsigned int pck_dst_gen_unicast (      unsigned int core_num, unsigned char * inject_en) {
409
        if(TRAFFIC_TYPE==TASK)  return          pck_dst_gen_task_graph ( core_num, inject_en);
410
        if((strcmp (TOPOLOGY,"MESH")==0)||(strcmp (TOPOLOGY,"TORUS")==0)) return  pck_dst_gen_2D (core_num, inject_en);
411
        return pck_dst_gen_1D (core_num, inject_en);
412 43 alirezamon
}
413
 
414
 
415 54 alirezamon
void mcast_full_rnd (unsigned int core_num){
416
        unsigned int rnd;
417
        int a;
418
        for(;;)  {
419
                DEST_ADDR_ASSIGN_RAND(traffic[core_num]->dest_e_addr);
420
                if((strcmp (SELF_LOOP_EN,"NO")==0)) DEST_ADDR_BIT_CLR(traffic[core_num]->dest_e_addr,core_num);
421
                DEST_ADDR_IS_ZERO(a,traffic[core_num]->dest_e_addr);
422
                //rnd = rand() & ~(0x1<<core_num);
423
                //rnd &= ((1<<NE) -1);
424
                //if(rnd!=0) return rnd;
425
                if(a!=1) return;
426
        }
427
}
428 43 alirezamon
 
429 54 alirezamon
 
430
void mcast_partial_rnd (unsigned int core_num){
431
        unsigned int rnd;int a;
432
        //printf("m[%d]=%d\n",core_num,mcast_list_array[core_num]);
433
        if(mcast_list_array[core_num] == 1){ // the current node is located in multicast partial list
434
                unsigned int self_node_addr = endp_id_to_mcast_id(core_num);//current node location in multicast list
435
                self_node_addr++;
436
                for(;;){
437
                        DEST_ADDR_ASSIGN_RAND(traffic[core_num]->dest_e_addr);
438
                        DEST_ADDR_BIT_CLR(traffic[core_num]->dest_e_addr,0);
439
                        if((strcmp (SELF_LOOP_EN,"NO")==0))      DEST_ADDR_BIT_CLR(traffic[core_num]->dest_e_addr,self_node_addr);
440
                        //rnd = rand() & ~((0x1<<(self_node_addr+1))|0x1); // generate a random multicast destination. remove the current node flag and unicast_flag from destination list
441
                        //rnd &= ((1<<(MCAST_PRTLw+1)) -1);
442
                        //printf("rnd=%d\n",rnd);
443
                        DEST_ADDR_IS_ZERO(a,traffic[core_num]->dest_e_addr);
444
                        if(a!=1) return;
445
                        //if(rnd!=0) return rnd;
446
                }
447
        }else{
448
                for(;;){
449
                        DEST_ADDR_ASSIGN_RAND(traffic[core_num]->dest_e_addr);
450
                        DEST_ADDR_BIT_CLR(traffic[core_num]->dest_e_addr,0);
451
                        DEST_ADDR_IS_ZERO(a,traffic[core_num]->dest_e_addr);
452
                        if(a!=1) return;
453
                        //rnd = rand() & ~0x1;// deassert the unicast flag
454
                        //rnd &= ((1<<(MCAST_PRTLw+1)) -1);
455
                        //if(rnd!=0) return rnd;
456
                }
457
        }
458
//this function should not come here
459
 
460
}
461
 
462
 
463
 
464
 
465
void pck_dst_gen (      unsigned int core_num, unsigned char * inject_en) {
466
 
467
        unsigned int dest = pck_dst_gen_unicast (core_num, inject_en);
468
        if(IS_UNICAST){
469
                traffic[core_num]->dest_e_addr= dest;
470
                return;
471
        }
472
        else if (*inject_en==0) return;
473
        //multicast
474
        DEST_ADDR_ASSIGN_ZERO(traffic[core_num]->dest_e_addr);//reset traffic[core_num]->dest_e_addr
475
 
476
        unsigned int dest_id = endp_addr_decoder (dest);
477
    //*inject_en = dest_id !=core_num;
478
 
479
        unsigned int rnd = rand() % 100; // 0~99
480
        if(rnd >= mcast.ratio){
481
                //send a unicast packet
482
                if((strcmp (SELF_LOOP_EN,"NO")==0) && dest_id==core_num){
483
                        *inject_en=0;
484
                        return;
485
                }
486
                if(IS_MCAST_FULL){
487
                        //return (0x1<<dest_id);// for mcast-full
488
                        DEST_ADDR_BIT_SET(traffic[core_num]->dest_e_addr,dest_id);
489
                        return;
490
                }
491
                // IS_MCAST_PARTIAL | IS_BCAST_FULL | IS_BCAST_PARTIAL
492
                dest = (dest << 1) | 0x1; // {dest_coded,unicast_flag}
493
                DEST_ADDR_ASSIGN_INT(traffic[core_num]->dest_e_addr,dest);
494
                return;
495
        }
496
        traffic[core_num]->pck_size_in=rnd_between(mcast.min,mcast.max);
497
 
498
        if (IS_MCAST_FULL) {
499
                mcast_full_rnd (core_num);
500
                return;
501
        }
502
        if (IS_MCAST_PARTIAL){
503
                mcast_partial_rnd(core_num);
504
                return;
505
        }
506
 
507
        return; //IS_BCAST_FULL | IS_BCAST_PARTIAL  traffic[core_num]->dest_e_addr=0;
508
}
509
 
510
 
511
 
512 38 alirezamon
void update_hotspot(char * str){
513
         int i;
514
         int array[1000];
515
         int p;
516
         int acuum=0;
517
         hotspot_st * new_node;
518
         p= parse_string (str, array);
519
         if (p<4){
520 48 alirezamon
                    fprintf(stderr,"ERROR: in hotspot traffic parameters. 4 value should be given as hotspot parameter\n");
521 38 alirezamon
                        exit(1);
522
         }
523
         HOTSPOT_NUM=array[0];
524
         if (p<1+HOTSPOT_NUM*3){
525 48 alirezamon
                    fprintf(stderr,"ERROR: in hotspot traffic parameters \n");
526 38 alirezamon
                        exit(1);
527
         }
528
         new_node =  (hotspot_st *) malloc( HOTSPOT_NUM * sizeof(hotspot_st));
529
         if( new_node == NULL){
530 48 alirezamon
                 fprintf(stderr,"ERROR: cannot allocate memory for hotspot traffic\n");
531 38 alirezamon
            exit(1);
532
         }
533
         for (i=1;i<3*HOTSPOT_NUM; i+=3){
534
                new_node[i/3]. ip_num = array[i];
535
            new_node[i/3]. send_enable=array[i+1];
536
            new_node[i/3]. percentage =  acuum + array[i+2];
537
            acuum= new_node[i/3]. percentage;
538
 
539
         }
540
         if(acuum> 1000){
541 48 alirezamon
                        printf("Warning: The hotspot traffic summation %f exceed than 100 percent.  \n", (float) acuum /10);
542 43 alirezamon
         }
543 38 alirezamon
         hotspots=new_node;
544
}
545
 
546 54 alirezamon
void  update_mcast_traffic(char * str){
547
        int i;
548
        int array[10];
549
        int p;
550
        int max_valid =(B > LB)? LB : B;
551
        p= parse_string (str, array);
552
        if(p>0)  mcast.ratio =array[0];
553
        if(p>1) mcast.min =array[1];
554
        if(p>2) mcast.max =array[2];
555
 
556
        if (mcast.ratio > 100)       { printf("ERROR: The given multicast traffic ratio (%d) is larger than 100\n",mcast.ratio);        exit(1);}
557
        if (mcast.min < MIN_PCK_SIZE){ printf("ERROR: The given multicast minimum packet size (%d) is larger than %d minimum packet size supported by the NoC\n",mcast.min, MIN_PCK_SIZE);      exit(1);}
558
        if (mcast.max > max_valid)   { printf("ERROR: The given multicast maximum packet size (%d) is larger than %d maximum router buffer size\n",mcast.max, max_valid);       exit(1);};
559
 
560
 
561
}
562
 
563 48 alirezamon
void update_custom_traffic (char * str){
564
        int i;
565
        int array[10000];
566
        int p;
567
        p= parse_string (str, array);
568
        for (i=0;i<p; i+=2){
569
                custom_traffic_table[array[i]] = array[i+1];
570
        }
571 32 alirezamon
}
572
 
573 48 alirezamon
void update_pck_size(char *str){
574
        int i;
575
        int array[1000];
576
        char substring[1000];
577
        int p;
578
        char *pt,*pt2;
579
        MIN_PACKET_SIZE=100000;
580
        MAX_PACKET_SIZE=1;
581 32 alirezamon
 
582 43 alirezamon
 
583 48 alirezamon
        pt = strtok (str,",");
584
        if(*pt=='R'){//random range
585
                p= parse_string (str+2, array);
586
                if(p<2){
587
                        fprintf(stderr,"ERROR: Wrong Packet size format %s. It should be \"R,min,max\" : \n",str);
588
                        exit(1);
589
                }
590 43 alirezamon
 
591 48 alirezamon
                MIN_PACKET_SIZE=array[0];
592
                MAX_PACKET_SIZE=array[1];
593
                AVG_PACKET_SIZE=(MIN_PACKET_SIZE+MAX_PACKET_SIZE)/2;// average packet size
594
        }else if(*pt=='D'){//random discrete
595
                pck_size_sel =  RANDOM_discrete;
596
                pt = strtok (str+2,"P");
597
                pt2 = strtok (NULL,"P");
598
                if (pt == NULL || pt2==NULL) {
599
                        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);
600
                        exit(1);
601
                }
602
                p= parse_string (pt, array);
603
                if (p==0){
604
                        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);
605
                        exit(1);
606
                }
607
                int in=p;
608
                //alocate mmeory for pck size
609
                discrete_size = (int*)malloc((p) * sizeof(int));
610
                discrete_prob = (int*)malloc((p) * sizeof(int));
611
                // Check if the memory has been successfully allocated
612
                if (discrete_size == NULL || discrete_prob==NULL) {
613
                        printf("ERROR: Memory not allocated.\n");
614
                        exit(1);
615
                }
616 43 alirezamon
 
617 48 alirezamon
                for (i=0; i<p; i++){
618 32 alirezamon
 
619 48 alirezamon
                        //printf("I[%u]=%u,\n",i,array[i]);
620
                        discrete_size[i] = array[i];
621
                        if(MIN_PACKET_SIZE > array[i]) MIN_PACKET_SIZE = array[i];
622
                        if(MAX_PACKET_SIZE < array[i]) MAX_PACKET_SIZE = array[i];
623
                }
624 32 alirezamon
 
625 48 alirezamon
                p= parse_string (pt2+1, array);
626
                int sum=0;
627
                AVG_PACKET_SIZE=0;
628
                for (i=0; i<p; i++){
629
                        //printf("P[%u]=%u,\n",i,array[i]);
630
                        if(i<in){
631
                                 sum+=array[i];
632
                                 discrete_prob[i]=sum;
633
                                 AVG_PACKET_SIZE+=discrete_size[i] * array[i];
634 32 alirezamon
 
635 48 alirezamon
                        }
636
                }
637
                AVG_PACKET_SIZE/=100;
638 32 alirezamon
 
639 48 alirezamon
                if(sum!=100){
640
                        fprintf(stderr,"ERROR: The accumulatio of the first %u probebility values is %u which is not equal to 100\n",in,sum);
641
                        exit(1);
642 32 alirezamon
                }
643
 
644 48 alirezamon
        }else {
645
                fprintf(stderr,"ERROR: Wrong Packet size format %s. It should start with one of \"D\" or \"R\" letter\n",str);
646
                exit(1);
647
        }
648 54 alirezamon
 
649
 
650
}
651
 
652
void allocate_rsv_pck_counters (void) {
653
        int p=(MAX_PACKET_SIZE-MIN_PACKET_SIZE)+1;
654 48 alirezamon
        rsv_size_array = (unsigned int*) calloc ( p , sizeof(int));
655
        if (rsv_size_array==NULL){
656
                 fprintf(stderr,"ERROR: cannot allocate memory for rsv_size_array\n");
657
                 exit(1);
658
        }
659
}
660 43 alirezamon
 
661 32 alirezamon
 
662 48 alirezamon
void task_traffic_init (char * str) {
663
        load_traffic_file(str,task_graph_data,task_graph_abstract);
664
        end_sim_pck_num=task_graph_total_pck_num;
665
        MIN_PACKET_SIZE = task_graph_min_pck_size;
666
        MAX_PACKET_SIZE = task_graph_max_pck_size;
667
        AVG_PACKET_SIZE=(MIN_PACKET_SIZE+MAX_PACKET_SIZE)/2;// average packet size
668
        int p=(MAX_PACKET_SIZE-MIN_PACKET_SIZE)+1;
669
        rsv_size_array = (unsigned int*) calloc ( p , sizeof(int));
670
        if (rsv_size_array==NULL){
671
                fprintf(stderr,"ERROR: cannot allocate (%d x int) memory for rsv_size_array. \n",p);
672 54 alirezamon
                exit(1);
673 48 alirezamon
        }
674
}
675 32 alirezamon
 
676
 
677
 
678
 
679
 
680 38 alirezamon
 
681 32 alirezamon
 
682 48 alirezamon
void processArgs (int argc, char **argv ){
683
        int i;
684 54 alirezamon
 
685
        mcast.ratio=50;
686
        mcast.min= MIN_PCK_SIZE;
687
        mcast.max= (B > LB)? LB : B;
688
 
689 48 alirezamon
        for( i = 1; i < argc; ++i ) {
690
                if( strcmp(argv[i], "-t") == 0 ) {
691
                        synthetic_task_processArgs ( argc, argv );
692
                        return;
693
                } else if( strcmp(argv[i], "-f") == 0 ) {
694
                        synthetic_task_processArgs ( argc, argv );
695
                        return;
696 32 alirezamon
 
697 48 alirezamon
                } else if( strcmp(argv[i], "-F") == 0 ) {
698
                        netrace_processArgs (argc, argv );
699
                        return;
700 54 alirezamon
                } else if ( strcmp(argv[i], "-S") == 0 ) {
701
                        synful_processArgs (argc, argv );
702
                        return;
703 48 alirezamon
                }
704
        }
705 54 alirezamon
        fprintf (stderr, "You should pass one of the Synthetic-, Task-, Synfull- or Nettrace- based simulation as input argument. \n");
706 48 alirezamon
        usage(argv[0]);
707
        exit(1);
708
}
709 32 alirezamon
 
710 43 alirezamon
 
711 48 alirezamon
int get_new_pck_size(){
712
                if(pck_size_sel ==  RANDOM_discrete){
713
                                int rnd = rand() % 100; // 0~99
714
                                int i=0;
715
                                while( rnd > discrete_prob[i] ) i++;
716
                                return discrete_size [i];
717 32 alirezamon
                }
718 48 alirezamon
                //random range
719
                return rnd_between(MIN_PACKET_SIZE,MAX_PACKET_SIZE);
720
}
721 32 alirezamon
 
722
 
723
 
724
 
725 48 alirezamon
 
726
 
727
void traffic_gen_final_report(){
728
        int i;
729
        for (i=0;i<NE;i++) if(traffic[i]->pck_number>0) total_active_endp         =       total_active_endp +1;
730
        printf("\nsimulation results-------------------\n");
731
        printf("\tSimulation clock cycles:%d\n",clk_counter);
732 54 alirezamon
        printf("\n\tTotal received packet in different size:\n");
733 48 alirezamon
        printf("\tflit_size,");
734
        for (i=0;i<=(MAX_PACKET_SIZE - MIN_PACKET_SIZE);i++){
735
                if(rsv_size_array[i]>0) printf("%u,",i+ MIN_PACKET_SIZE);
736
        }
737
        printf("\n\t#pck,");
738
        for (i=0;i<=(MAX_PACKET_SIZE - MIN_PACKET_SIZE);i++){
739
                if(rsv_size_array[i]>0) printf("%u,",rsv_size_array[i]);
740
        }
741
        printf("\n");
742
 
743
//      printf(" total received flits:%d\n",total_rsv_flit_number);
744
//      printf(" total sent flits:%d\n",total_sent_flit_number);
745
        print_statistic_new (clk_counter);
746
 
747 32 alirezamon
}
748
 
749
 
750 48 alirezamon
void traffic_gen_init( void ){
751
        int i;
752
        unsigned int dest_e_addr;
753
        for (i=0;i<NE;i++){
754 54 alirezamon
                        unsigned char inject_en;
755 48 alirezamon
                random_var[i] = 100;
756
                traffic[i]->current_e_addr              = endp_addr_encoder(i);
757
                traffic[i]->start=0;
758
                traffic[i]->pck_class_in=  pck_class_in_gen( i);
759
                traffic[i]->pck_size_in=get_new_pck_size();
760 54 alirezamon
                pck_dst_gen (i, &inject_en);
761
                //traffic[i]->dest_e_addr= dest_e_addr;
762
                if(inject_en == 0) traffic[i]->stop=1;
763 48 alirezamon
                //printf("src=%u, des_eaddr=%x, dest=%x\n", i,dest_e_addr, endp_addr_decoder(dest_e_addr));
764
                if(inject_done) traffic[i]->stop=1;
765 54 alirezamon
                traffic[i]->start_delay=rnd_between(11,4*NE-12);
766 48 alirezamon
                if(TRAFFIC_TYPE==SYNTHETIC){
767
                        //traffic[i]->avg_pck_size_in=AVG_PACKET_SIZE;
768
                        traffic[i]->ratio=ratio;
769
                        traffic[i]->init_weight=1;
770
                }
771
        }
772
}
773 32 alirezamon
 
774 54 alirezamon
void pck_inj_init (int model_node_num){
775
        int i,tmp;
776 48 alirezamon
        for (i=0;i<NE;i++){
777
                pck_inj[i]->current_e_addr              = endp_addr_encoder(i);
778
                pck_inj[i]->pck_injct_in_ready= (0x1<<V)-1;
779
                pck_inj[i]->pck_injct_in_pck_wr=0;
780 54 alirezamon
        }
781
        std::cout << "Node mapping---------------------" << std::endl;
782
        std::cout << "\tMapping " << model_node_num << " " << TRAFFIC  << " Nodes to " << NE << " ProNoC Nodes" << std::endl;
783
        std::cout << "\t" << TRAFFIC  << "\tID \t<-> ProNoC ID "<< std::endl;
784
        traffic_model_mapping = (int *) malloc( model_node_num * sizeof(int));
785
        for (i=0;i<model_node_num;i++){
786
        //TODO mapping should be done according to number of NE and should be set by the user later
787
                        if(NE<=model_node_num){
788
                                // we have less or equal number of injectors in traffic model thatn the number of modes in ProNoC
789
                                // So we need to map multiples injector nodes from the model to one packet injector
790
                                tmp = ((i* NE)/model_node_num);
791
                                traffic_model_mapping[i]=tmp;
792
                        } else {
793
                                // we have more endpoints that what is defined in the model
794
                                if(i<model_node_num) traffic_model_mapping[i]=i;
795
                        }
796
                        std::cout<< "\t\t" << i << "\t<->\t"  << tmp << std::endl;
797 32 alirezamon
 
798 48 alirezamon
        }
799 54 alirezamon
        std::cout << "Node mapping---------------------" << std::endl;
800 48 alirezamon
}
801
 
802 38 alirezamon
/*************
803
 * sc_time_stamp
804
 *
805
 * **********/
806 32 alirezamon
double sc_time_stamp () {       // Called by $time in Verilog
807
        return main_time;
808
}
809
 
810
int pow2( int num){
811
        int pw;
812
        pw= (0x1 << num);
813
        return pw;
814
}
815
 
816 48 alirezamon
/*
817
volatile int *  lock;
818
unsigned int  nr_per_thread=0;
819
unsigned int  ne_per_thread=0;
820 32 alirezamon
 
821 48 alirezamon
void thread_function (int n){
822
        int i;
823
        unsigned int node=0;
824
        while(1){
825
                while(lock[n]==0) std::this_thread::yield();
826
                for(i=0;i<nr_per_thread;i++){
827
                        node= (n * nr_per_thread)+i;
828
                        if (node >= NR) break;
829
                        single_router_eval(node);
830
                }
831
                for(i=0;i<ne_per_thread;i++){
832
                        node= (n * ne_per_thread)+i;
833
                        if (node >= NE) break;
834
                        if( TRAFFIC_TYPE == NETRACE)   pck_inj[node]->eval();
835
                        else   traffic[node]->eval();
836
                }
837
 
838
                //router1[n]->eval();
839
                //if( TRAFFIC_TYPE == NETRACE)   pck_inj[n]->eval();
840
                //else   traffic[n]->eval();
841
 
842
                lock[n]=0;
843
                if(n==0) break;//first thread is the main process
844
        }
845
}
846
*/
847 32 alirezamon
 
848 48 alirezamon
class alignas(64) Vthread
849
{
850
    // Access specifier
851
    public:
852 54 alirezamon
        std::atomic<bool> eval;
853
        std::atomic<bool> copy;
854
        std::atomic<bool> update;
855 48 alirezamon
    // Data Members
856
    int n;//thread num
857
        int nr_per_thread;
858
        int ne_per_thread;
859
    // Member Functions()
860
    //Parameterized Constructor
861
 
862
 
863
    void function ( ){
864
                int i;
865
                unsigned int node=0;
866
                while(1){
867 54 alirezamon
                        while(!eval && !copy && !update) std::this_thread::yield();
868
                        if(eval){
869
                                //connect_clk_reset_start
870
                                for(i=0;i<ne_per_thread;i++){
871
                                        node= (n * ne_per_thread)+i;
872
                                        if (node >= NE) break;
873
                                        if(ENDP_TYPE == PCK_INJECTOR){
874
                                                pck_inj[node]->reset= reset;
875
                                                pck_inj[node]->clk      = clk;
876
                                        }
877
                                        else {
878
                                                traffic[node]->start= start_i;
879
                                                traffic[node]->reset= reset;
880
                                                traffic[node]->clk      = clk;
881
                                        }
882
                                }//endp
883
                                for(i=0;i<nr_per_thread;i++){
884
                                        node= (n * nr_per_thread)+i;
885
                                        if (node >= NR) break;
886
                                        //if(router_is_active[node] | (Quick_sim_en==0))
887
                                        single_router_reset_clk(node);
888
                                }
889
 
890
                                //eval
891
                                for(i=0;i<nr_per_thread;i++){
892
                                        node= (n * nr_per_thread)+i;
893
                                        if (node >= NR) break;
894
                                        //if(router_is_active[node] | (Quick_sim_en==0))
895
                                        single_router_eval(node);
896
                                }
897
                                for(i=0;i<ne_per_thread;i++){
898
                                        node= (n * ne_per_thread)+i;
899
                                        if (node >= NE) break;
900
                                        if(ENDP_TYPE == PCK_INJECTOR)   pck_inj[node]->eval();
901
                                        else   traffic[node]->eval();
902
                                }
903
                                eval=false;
904
                        }
905
 
906
                        if(copy){
907
                                for  (int i=0;   i<R2R_TABLE_SIZ; i++) {
908
                                        if(
909
                                        r2r_cnt_all[i].id1 >= (n * nr_per_thread)
910
                                        &&
911
                                        r2r_cnt_all[i].id1 <  ((n+1) * nr_per_thread)
912
                                        )
913
                                        topology_connect_r2r(i);
914
                                }
915
 
916
 
917
                                for(i=0;i<ne_per_thread;i++){
918
                                        node= (n * ne_per_thread)+i;
919
                                        if (node >= NE) break;
920
                                        topology_connect_r2e(node);
921
                                }
922
                                copy=false;
923
                        }
924 48 alirezamon
 
925 54 alirezamon
                        if(update){
926
                                for(i=0;i<nr_per_thread;i++){
927
                                        node= (n * nr_per_thread)+i;
928
                                        if (node >= NR) break;
929
                                        single_router_st_update(node);
930
                                }
931
                                update=false;
932
                        }
933
 
934 48 alirezamon
                        //router1[n]->eval();
935
                        //if( TRAFFIC_TYPE == NETRACE)   pck_inj[n]->eval();
936
                        //else   traffic[n]->eval();
937
 
938 54 alirezamon
 
939 48 alirezamon
                        if(n==0) break;//first thread is the main process 
940
                }
941
        }
942
 
943
        Vthread(int x,int r,int e)
944
    {
945
       n=x; nr_per_thread=r; ne_per_thread=e;
946 54 alirezamon
       eval=false;
947
       copy =false;
948
       update=false;
949 48 alirezamon
       if(n!=0) {
950
                 std::thread th {&Vthread::function,this};
951
         th.detach();
952
           }
953
    }
954
 
955
 
956
};
957
 
958
Vthread ** thread;
959
 
960
void initial_threads (void){
961
        int i;
962
        //devide nodes equally between threads
963
        unsigned int  nr_per_thread=0;
964
        unsigned int  ne_per_thread=0;
965
        nr_per_thread = (NR % thread_num)?  (unsigned int)(NR/thread_num) + 1 :  (unsigned int)(NR/thread_num);
966
        ne_per_thread = (NE % thread_num)?  (unsigned int)(NE/thread_num) + 1 :  (unsigned int)(NE/thread_num);
967
 
968
        //std::vector<std::thread> threads(thread_num-1);
969
        //lock = new int[thread_num];
970
        //for(i=0;i<thread_num;i++) lock [i]=0; 
971
 
972
        //Dynamically Allocating Memory
973
        thread = (Vthread **) new Vthread * [thread_num];
974
        for(i=0;i<thread_num;i++) thread[i] = new Vthread(i,nr_per_thread,ne_per_thread) ;
975
 
976
        //initiates (thread_num-1) number of live thread         
977
        //for(i=0;i<thread_num-1;i++) threads[i] = std::thread(&thread_function, (i+1));
978
        //for (auto& th : threads)    th.detach();
979
 
980
        unsigned maxThreads = std::thread::hardware_concurrency();
981
    printf("Thread is initiated as following:\n"
982
    "\tMax hardware supported threads:%u\n"
983
    "\tthread_num:%u\n"
984
    "\trouter per thread:%u\n"
985
    "\tendpoint per thread:%u\n"
986
    ,maxThreads,thread_num,nr_per_thread,ne_per_thread);
987
}
988
 
989
 
990
 
991
 
992
void sim_eval_all (void){
993
        int i;
994
        if(thread_num>1) {
995 54 alirezamon
                for(i=0;i<thread_num;i++) thread[i]->eval=true;
996 48 alirezamon
                //thread_function (0);          
997
                thread[0]->function();
998 54 alirezamon
                for(i=0;i<thread_num;i++)while(thread[i]->eval);
999 48 alirezamon
        }else{// no thread
1000 54 alirezamon
 
1001
                connect_clk_reset_start_all();
1002
 
1003 48 alirezamon
                //routers_eval();
1004
                for(i=0;i<NR;i++){
1005
                        //if(router_is_active[i] | (Quick_sim_en==0)) 
1006
                        single_router_eval(i);
1007
                }
1008 54 alirezamon
                if(ENDP_TYPE == PCK_INJECTOR) for(i=0;i<NE;i++) pck_inj[i]->eval();
1009 48 alirezamon
                else for(i=0;i<NE;i++) traffic[i]->eval();
1010
        }
1011
}
1012
 
1013 54 alirezamon
 
1014
void topology_connect_all_nodes (void){
1015
 
1016
 
1017
        int i;
1018
        if(thread_num>1) {
1019
                for(i=0;i<thread_num;i++) thread[i]->copy=true;
1020
                //thread_function (0);
1021
                thread[0]->function();
1022
                for(i=0;i<thread_num;i++){
1023
                        while(thread[i]->copy==true);
1024
                }
1025
                return;
1026
        }//no thread
1027
        for  (int n=0; n<R2R_TABLE_SIZ; n++) {
1028
                topology_connect_r2r(n);
1029
        }
1030
 
1031
        for (int n=0;n<NE; n++){
1032
                topology_connect_r2e(n);
1033
        }
1034
}
1035
 
1036
 
1037 48 alirezamon
void sim_final_all (void){
1038
        int i;
1039
        routers_final();
1040 54 alirezamon
        if(ENDP_TYPE == PCK_INJECTOR) for(i=0;i<NE;i++) pck_inj[i]->final();
1041 48 alirezamon
        else for(i=0;i<NE;i++) traffic[i]->final();
1042
        //noc->final(); 
1043
}
1044
 
1045
void connect_clk_reset_start_all(void){
1046
        int i;
1047
        //noc-> clk = clk; 
1048
        //noc-> reset = reset;
1049 54 alirezamon
        if(ENDP_TYPE == PCK_INJECTOR) {
1050 48 alirezamon
                for(i=0;i<NE;i++)        {
1051
                        pck_inj[i]->reset= reset;
1052
                        pck_inj[i]->clk = clk;
1053
                }
1054
        }else {
1055
                for(i=0;i<NE;i++)        {
1056 54 alirezamon
                        traffic[i]->start= start_i;
1057 48 alirezamon
                        traffic[i]->reset= reset;
1058
                        traffic[i]->clk = clk;
1059
                }
1060
        }
1061
        connect_routers_reset_clk();
1062
}
1063
 
1064
 
1065
void traffic_clk_negedge_event(void){
1066
        int i;
1067
        clk = 0;
1068
        //for (i=0;i<NR;i++) router_is_active [i]=0;
1069
        topology_connect_all_nodes ();
1070
 
1071
        for (i=0;i<NE;i++){
1072
                if(inject_done) traffic[i]->stop=1;
1073
        }
1074 54 alirezamon
 
1075 48 alirezamon
        sim_eval_all();
1076
}
1077
 
1078 54 alirezamon
void update_traffic_injector_st (unsigned int i){
1079
        unsigned char inject_en;
1080
        // a packet has been received
1081
        if(traffic[i]->update & ~reset){
1082
                total_rsv_pck_num+=1;
1083
                update_noc_statistic (i) ;
1084
        }
1085
        // the header flit has been sent out
1086
        if(traffic[i]->hdr_flit_sent ){
1087
                traffic[i]->pck_class_in=  pck_class_in_gen( i);
1088
                traffic[i]->pck_size_in=get_new_pck_size();
1089
                if((!FIXED_SRC_DST_PAIR)| (!IS_UNICAST)){
1090
                        pck_dst_gen (i, &inject_en);
1091
                        //traffic[i]->dest_e_addr= dest_e_addr;
1092
                        if(inject_en == 0) traffic[i]->stop=1;
1093
                        //printf("src=%u, dest=%x\n", i,endp_addr_decoder(dest_e_addr));
1094
                }
1095
        }
1096 48 alirezamon
 
1097 54 alirezamon
        if(traffic[i]->flit_out_wr==1){
1098
                total_sent_flit_number++;
1099
                if (!IS_UNICAST){
1100
                        total_expect_rsv_flit_num+=traffic[i]->mcast_dst_num_o;
1101
                }else{
1102
                        total_expect_rsv_flit_num++;
1103
                }
1104
                #if (C>1)
1105
                        sent_stat [i][traffic[i]->flit_out_class].flit_num++;
1106
                #else
1107
                sent_stat [i].flit_num++;
1108
                #endif
1109
        }
1110 48 alirezamon
 
1111 54 alirezamon
        if(traffic[i]->flit_in_wr==1){
1112
                total_rsv_flit_number++;
1113
        }
1114 48 alirezamon
 
1115 54 alirezamon
        if(traffic[i]->hdr_flit_sent==1){
1116
                total_sent_pck_num++;
1117
                #if (C>1)
1118
                        sent_stat [i][traffic[i]->flit_out_class].pck_num++;
1119
                #else
1120
                        sent_stat [i].pck_num++;
1121
                #endif
1122
        }
1123
}
1124
 
1125
void update_all_traffic_injector_st(){
1126
        for (int i=0;i<NE;i++){
1127
                        update_traffic_injector_st(i);
1128
                }
1129
 
1130
}
1131
 
1132
 
1133
 
1134 48 alirezamon
void traffic_clk_posedge_event(void) {
1135
        int i;
1136
        unsigned int dest_e_addr;
1137 54 alirezamon
 
1138 48 alirezamon
        clk = 1;       // Toggle clock
1139
        if(count_en) clk_counter++;
1140
        inject_done= ((total_sent_pck_num >= end_sim_pck_num) || (clk_counter>= sim_end_clk_num) || total_active_routers == 0);
1141
        //if(inject_done) printf("clk_counter=========%d\n",clk_counter);
1142
        total_rsv_flit_number_old=total_rsv_flit_number;
1143 54 alirezamon
        update_all_router_stat();
1144
        update_all_traffic_injector_st();
1145 48 alirezamon
 
1146 54 alirezamon
        if(inject_done){
1147
                if(total_rsv_flit_number_old == total_rsv_flit_number){
1148
                        ideal_rsv_cnt++;
1149
                        if(ideal_rsv_cnt >= NE*10){
1150
                                traffic_gen_final_report( );
1151
                                fprintf(stderr,"ERROR: The number of expected (%u) & received flits (%u) were not equal at the end of simulation\n",total_expect_rsv_flit_num, total_rsv_flit_number);
1152
                                exit(1);
1153 48 alirezamon
                        }
1154 54 alirezamon
                }else ideal_rsv_cnt=0;
1155
                if(total_expect_rsv_flit_num == total_rsv_flit_number ) simulation_done=1;
1156
        }
1157 48 alirezamon
 
1158
        sim_eval_all();
1159
 
1160
}
1161
 
1162
 
1163 32 alirezamon
/**********************************
1164
 *
1165
 *      update_noc_statistic
1166
 *
1167
 *
1168
 *********************************/
1169
 
1170 54 alirezamon
void update_rsvd_st (
1171
                statistic_t *   rsvd_stat,
1172
                unsigned int    clk_num_h2h,
1173
                unsigned int    clk_num_h2t,
1174
                unsigned int    latency,
1175
                unsigned int    distance,
1176
                unsigned int    pck_size
1177 48 alirezamon
 
1178 54 alirezamon
) {
1179
        rsvd_stat->pck_num ++;
1180
        rsvd_stat->flit_num+=  pck_size;
1181
        rsvd_stat->sum_clk_h2h +=(double)clk_num_h2h;
1182
        rsvd_stat->sum_clk_h2t +=(double)clk_num_h2t;
1183
        rsvd_stat->sum_clk_per_hop+= ((double)clk_num_h2h/(double)distance);
1184
        if (rsvd_stat->worst_latency < latency ) rsvd_stat->worst_latency=latency;
1185
        if (rsvd_stat->min_latency==0          ) rsvd_stat->min_latency  =latency;
1186
        if (rsvd_stat->min_latency   > latency ) rsvd_stat->min_latency  =latency;
1187
        #if (STND_DEV_EN)
1188
                rsvd_stat->sum_clk_pow2 += (double)clk_num_h2h * (double) clk_num_h2h;
1189
        #endif
1190
}
1191 48 alirezamon
 
1192 54 alirezamon
void update_sent_st (
1193
        statistic_t *  sent_stat,
1194
        unsigned int    latency
1195
) {
1196
 
1197
        if (sent_stat->worst_latency < latency ) sent_stat->worst_latency=latency;
1198
        if (sent_stat->min_latency==0          ) sent_stat->min_latency  =latency;
1199
        if (sent_stat->min_latency   > latency ) sent_stat->min_latency  =latency;
1200
 
1201
}
1202
 
1203
 
1204 48 alirezamon
void update_statistic_at_ejection (
1205
        int     core_num,
1206
        unsigned int    clk_num_h2h,
1207
        unsigned int    clk_num_h2t,
1208
        unsigned int    distance,
1209
        unsigned int    class_num,
1210 54 alirezamon
        unsigned int    src,
1211
        unsigned int    pck_size
1212
        ){
1213 48 alirezamon
 
1214
 
1215
 
1216 54 alirezamon
        if(ENDP_TYPE == TRFC_INJECTOR) {
1217 48 alirezamon
                if( traffic[core_num]->pck_size_o >= MIN_PACKET_SIZE && traffic[core_num]->pck_size_o <=MAX_PACKET_SIZE){
1218 54 alirezamon
                          if(rsv_size_array!=NULL)      rsv_size_array[traffic[core_num]->pck_size_o-MIN_PACKET_SIZE]++;
1219 48 alirezamon
                }
1220
        }
1221
 
1222 54 alirezamon
        if(verbosity==0 && ( TRAFFIC_TYPE == NETRACE || TRAFFIC_TYPE ==SYNFUL)) if((total_rsv_pck_num & 0X1FFFF )==0 ) printf(" packet sent total=%d\n",total_rsv_pck_num);
1223 48 alirezamon
    unsigned int latency = (strcmp (AVG_LATENCY_METRIC,"HEAD_2_TAIL")==0)? clk_num_h2t :  clk_num_h2h;
1224
    #if(C>1)
1225 54 alirezamon
        update_rsvd_st ( &rsvd_stat[core_num][class_num],       clk_num_h2h,   clk_num_h2t,     latency,    distance,pck_size);
1226
        update_sent_st ( &sent_stat[src     ][class_num],       latency);
1227
    #else
1228
        update_rsvd_st ( &rsvd_stat[core_num], clk_num_h2h,   clk_num_h2t,      latency,    distance,pck_size);
1229
        update_sent_st ( &sent_stat[src     ], latency);
1230
        #endif
1231 48 alirezamon
 
1232 54 alirezamon
    update_rsvd_st ( &endp_to_endp[src][core_num],      clk_num_h2h,   clk_num_h2t,     latency,    distance, pck_size);
1233 48 alirezamon
 
1234 54 alirezamon
}
1235 48 alirezamon
 
1236
 
1237
 
1238
 
1239
 
1240
void update_noc_statistic (     int     core_num){
1241
        unsigned int    clk_num_h2h =traffic[core_num]->time_stamp_h2h;
1242
        unsigned int    clk_num_h2t =traffic[core_num]->time_stamp_h2t;
1243
    unsigned int    distance=traffic[core_num]->distance;
1244
    unsigned int        class_num=traffic[core_num]->pck_class_out;
1245
    unsigned int    src_e_addr=traffic[core_num]->src_e_addr;
1246
    unsigned int        src = endp_addr_decoder (src_e_addr);
1247 54 alirezamon
    unsigned int    pck_size = traffic[core_num]-> pck_size_o;
1248
    update_statistic_at_ejection ( core_num,    clk_num_h2h,  clk_num_h2t,  distance,   class_num,      src,pck_size);
1249 32 alirezamon
 
1250
 
1251 48 alirezamon
}
1252
 
1253
avg_st_t finilize_statistic (unsigned long int total_clk, statistic_t rsvd_stat){
1254
 
1255
         avg_st_t avg_statistic;
1256
         avg_statistic.avg_throughput= ((double)(rsvd_stat.flit_num*100)/NE )/total_clk;
1257
         avg_statistic.avg_latency_flit    = rsvd_stat.sum_clk_h2h/rsvd_stat.pck_num;
1258
         avg_statistic.avg_latency_pck     = rsvd_stat.sum_clk_h2t/rsvd_stat.pck_num;
1259
         avg_statistic.avg_latency_per_hop = ( rsvd_stat.pck_num==0)? 0 : rsvd_stat.sum_clk_per_hop/rsvd_stat.pck_num;
1260
         avg_statistic.avg_pck_siz        = ( rsvd_stat.pck_num==0)? 0 : (double)(rsvd_stat.flit_num / rsvd_stat.pck_num);
1261
         #if (STND_DEV_EN)
1262
                 avg_statistic.std_dev =standard_dev( rsvd_stat.sum_clk_pow2,rsvd_stat.pck_num, avg_statistic.avg_latency_flit);
1263
         #endif
1264
         return avg_statistic;
1265
}
1266
 
1267
template<typename T>
1268
        void myout(T value)
1269
        {
1270
           std::cout << value << std::endl;
1271
        }
1272
template<typename First, typename ... Rest>
1273
        void myout(First first, Rest ... rest)
1274
        {
1275
           std::cout << first << ",";
1276
           myout(rest...);
1277
        }
1278
 
1279
void print_st_single (unsigned long int total_clk, statistic_t rsvd_stat, statistic_t sent_stat){
1280
 
1281
 
1282
 
1283
        avg_st_t avg;
1284
        avg=finilize_statistic (total_clk,  rsvd_stat);
1285
 
1286
        myout(
1287
                        sent_stat.pck_num,
1288
                        rsvd_stat.pck_num,
1289
                        sent_stat.flit_num,
1290
                        rsvd_stat.flit_num,
1291
                        sent_stat.worst_latency,
1292
                        rsvd_stat.worst_latency,
1293
                        sent_stat.min_latency,
1294
                        rsvd_stat.min_latency,
1295
                        avg.avg_latency_per_hop,
1296
                        avg.avg_latency_flit,
1297
                        avg.avg_latency_pck,
1298
                        avg.avg_throughput,
1299
                        avg.avg_pck_siz,
1300
                        #if (STND_DEV_EN)
1301
                        avg.std_dev
1302
                        #endif
1303
        );
1304
//      printf("\n");
1305
 
1306
}
1307
 
1308
 
1309
void merge_statistic (statistic_t * merge_stat, statistic_t stat_in){
1310
        merge_stat->pck_num+=stat_in.pck_num;
1311
        merge_stat->flit_num+=stat_in.flit_num;
1312
        if(merge_stat->worst_latency <  stat_in.worst_latency) merge_stat->worst_latency= stat_in.worst_latency;
1313
        if(merge_stat->min_latency   == 0                       ) merge_stat->min_latency  = stat_in.min_latency;
1314
        if(merge_stat->min_latency   > stat_in.min_latency  && stat_in.min_latency!=0   ) merge_stat->min_latency  = stat_in.min_latency;
1315
        merge_stat->sum_clk_h2h      +=stat_in.sum_clk_h2h    ;
1316
        merge_stat->sum_clk_h2t      +=stat_in.sum_clk_h2t    ;
1317
        merge_stat->sum_clk_per_hop  +=stat_in.sum_clk_per_hop;
1318
        #if (STND_DEV_EN)
1319
                merge_stat->sum_clk_pow2 +=stat_in.sum_clk_pow2;
1320
    #endif
1321
 
1322
}
1323
 
1324
void print_statistic_new (unsigned long int total_clk){
1325 32 alirezamon
        int i;
1326 54 alirezamon
 
1327
 
1328
        print_router_st();
1329
        print_endp_to_endp_st("pck_num");
1330
        print_endp_to_endp_st("flit_num");
1331
 
1332
        printf( "\n\tEndpoints Statistics:\n"
1333
                        "\t#EID,"
1334 48 alirezamon
                        "sent_stat.pck_num,"
1335
                        "rsvd_stat.pck_num,"
1336
                        "sent_stat.flit_num,"
1337
                        "rsvd_stat.flit_num,"
1338
                        "sent_stat.worst_latency,"
1339
                        "rsvd_stat.worst_latency,"
1340
                        "sent_stat.min_latency,"
1341
                        "rsvd_stat.min_latency,"
1342
                        "avg_latency_per_hop,"
1343
                        "avg_latency_flit,"
1344
                        "avg_latency_pck,"
1345
                        "avg_throughput(%%),"
1346
                        "avg_pck_size,"
1347
                        #if (STND_DEV_EN)
1348
                        "avg.std_dev"
1349
                        #endif
1350
                        "\n");
1351
 
1352
 
1353
 
1354
#if(C>1)
1355
        int c;
1356
        statistic_t sent_stat_class [NE];
1357
        statistic_t rsvd_stat_class [NE];
1358
        statistic_t sent_stat_per_class [C];
1359
        statistic_t rsvd_stat_per_class [C];
1360
 
1361
        memset (&rsvd_stat_class,0,sizeof(statistic_t)*NE);
1362
        memset (&sent_stat_class,0,sizeof(statistic_t)*NE);
1363
        memset (&rsvd_stat_per_class,0,sizeof(statistic_t)*C);
1364
        memset (&sent_stat_per_class,0,sizeof(statistic_t)*C);
1365
 
1366
 
1367
        for (i=0; i<NE;i++){
1368
                for (c=0; c<C;c++){
1369
                        merge_statistic (&rsvd_stat_class[i],rsvd_stat[i][c]);
1370
                        merge_statistic (&sent_stat_class[i],sent_stat[i][c]);
1371
                        merge_statistic (&rsvd_stat_per_class[c],rsvd_stat[i][c]);
1372
                        merge_statistic (&sent_stat_per_class[c],sent_stat[i][c]);
1373
                }
1374
        }
1375
 
1376
 
1377
 
1378
 
1379
#else
1380
        #define sent_stat_class  sent_stat
1381
        #define rsvd_stat_class  rsvd_stat
1382 32 alirezamon
#endif
1383
 
1384 48 alirezamon
 
1385
 
1386
 
1387
 
1388
        statistic_t rsvd_stat_total, sent_stat_total;
1389
        memset (&rsvd_stat_total,0,sizeof(statistic_t));
1390
        memset (&sent_stat_total,0,sizeof(statistic_t));
1391
        for (i=0; i<NE;i++){
1392
                merge_statistic (&rsvd_stat_total,rsvd_stat_class[i]);
1393
                merge_statistic (&sent_stat_total,sent_stat_class[i]);
1394
        }
1395
        printf("\ttotal,");
1396
        print_st_single (total_clk, rsvd_stat_total,sent_stat_total);
1397
 
1398
#if(C>1)
1399
        for (c=0; c<C;c++){
1400
                printf("\ttotal_class%u,",c);
1401
                print_st_single (total_clk, rsvd_stat_per_class[c],sent_stat_per_class[c]);
1402
        }
1403 32 alirezamon
#endif
1404 48 alirezamon
 
1405
    for (i=0; i<NE;i++){
1406
        printf("\t%u,",i);
1407
        print_st_single (total_clk, rsvd_stat_class[i],sent_stat_class[i] );
1408
    }
1409 32 alirezamon
 
1410
 
1411
 
1412
 
1413
 
1414 54 alirezamon
}
1415 48 alirezamon
 
1416
 
1417
 
1418
 
1419 32 alirezamon
 
1420
 
1421 54 alirezamon
 
1422 32 alirezamon
void print_parameter (){
1423 54 alirezamon
        printf ("NoC parameters:---------------- \n");
1424
        printf ("\tTopology: %s\n",TOPOLOGY);
1425
        printf ("\tRouting algorithm: %s\n",ROUTE_NAME);
1426
        printf ("\tVC_per port: %d\n", V);
1427
        printf ("\tNon-local port buffer_width per VC: %d\n", B);
1428
        printf ("\tLocal port buffer_width per VC: %d\n", LB);
1429
 
1430
        #if defined (IS_MESH) || defined (IS_FMESH) || defined (IS_TORUS)
1431 43 alirezamon
            printf ("\tRouter num in row: %d \n",T1);
1432
            printf ("\tRouter num in column: %d \n",T2);
1433 48 alirezamon
            printf ("\tEndpoint num per router: %d\n",T3);
1434 54 alirezamon
        #elif defined (IS_LINE) || defined (IS_RING )
1435
            printf ("\tTotal Router num: %d \n",T1);
1436
            printf ("\tEndpoint num per router: %d\n",T3);
1437
        #elif defined (IS_FATTREE) || defined (IS_TREE)
1438
            printf ("\tK: %d \n",T1);
1439
            printf ("\tL: %d \n",T2);
1440
        #elif defined (IS_STAR)
1441 48 alirezamon
            printf ("\tTotal Endpoints number: %d \n",T1);
1442 54 alirezamon
        #else//CUSTOM
1443
            printf ("\tTotal Endpoints number: %d \n",T1);
1444 48 alirezamon
                printf ("\tTotal Routers number: %d \n",T2);
1445 54 alirezamon
    #endif
1446
 
1447
        printf ("\tNumber of Class: %d\n", C);
1448
        printf ("\tFlit data width: %d \n", Fpay);
1449
        printf ("\tVC reallocation mechanism: %s \n",  VC_REALLOCATION_TYPE);
1450
        printf ("\tVC/sw combination mechanism: %s \n", COMBINATION_TYPE);
1451
        printf ("\tAVC_ATOMIC_EN:%d \n", AVC_ATOMIC_EN);
1452
        printf ("\tCongestion Index:%d \n",CONGESTION_INDEX);
1453
        printf ("\tADD_PIPREG_AFTER_CROSSBAR:%d\n",ADD_PIPREG_AFTER_CROSSBAR);
1454
        printf ("\tSSA_EN enabled:%s \n",SSA_EN);
1455
        printf ("\tSwitch allocator arbitration type:%s \n",SWA_ARBITER_TYPE);
1456
        printf ("\tMinimum supported packet size:%d flit(s) \n",MIN_PCK_SIZE);
1457
        printf ("\tLoop back is enabled:%s \n",SELF_LOOP_EN);
1458
        printf ("\tNumber of multihop bypass (SMART max):%d \n",SMART_MAX);
1459
        printf ("\tCastying type:%s.\n",CAST_TYPE);
1460
        if (IS_MCAST_PARTIAL){
1461
                printf ("\tCAST LIST:%s\n",MCAST_ENDP_LIST);
1462
        }
1463 48 alirezamon
        printf ("NoC parameters:---------------- \n");
1464
        printf ("\nSimulation parameters-------------\n");
1465 54 alirezamon
        #if(DEBUG_EN)
1466
                printf ("\tDebuging is enabled\n");
1467
        #else
1468
                printf ("\tDebuging is disabled\n");
1469
        #endif
1470 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");
1471
        //else printf ("\tOutput is the average latency on sending the packet header until receiving header flit at destination node\n");
1472 32 alirezamon
        printf ("\tTraffic pattern:%s\n",TRAFFIC);
1473 48 alirezamon
        size_t n = sizeof(class_percentage)/sizeof(class_percentage[0]);
1474
        for(int p=0;p<n; p++){
1475
                printf ("\ttraffic percentage of class %u is : %d\n",p,  class_percentage[p]);
1476
        }
1477 38 alirezamon
        if(strcmp (TRAFFIC,"HOTSPOT")==0){
1478
                //printf ("\tHot spot percentage: %u\n", HOTSPOT_PERCENTAGE);
1479 32 alirezamon
            printf ("\tNumber of hot spot cores: %d\n", HOTSPOT_NUM);
1480 54 alirezamon
        }
1481
        if (strcmp (CAST_TYPE,"UNICAST")){
1482
                printf ("\tMULTICAST traffic ratio: %d(%%), min: %d, max: %d\n", mcast.ratio,mcast.min,mcast.max);
1483
        }
1484 32 alirezamon
 
1485 54 alirezamon
 
1486
        //printf ("\tTotal packets sent by one router: %u\n", TOTAL_PKT_PER_ROUTER);
1487
        if(sim_end_clk_num!=0) printf ("\tSimulation timeout =%d\n", sim_end_clk_num);
1488
        if(end_sim_pck_num!=0) printf ("\tSimulation ends on total packet num of =%d\n", end_sim_pck_num);
1489
        if(TRAFFIC_TYPE!=NETRACE && TRAFFIC_TYPE!=SYNFUL){
1490
                printf ("\tPacket size (min,max,average) in flits: (%u,%u,%u)\n",MIN_PACKET_SIZE,MAX_PACKET_SIZE,AVG_PACKET_SIZE);
1491
                printf ("\tPacket injector FIFO width in flit:%u \n",TIMSTMP_FIFO_NUM);
1492 32 alirezamon
        }
1493 54 alirezamon
        if( TRAFFIC_TYPE == SYNTHETIC) printf("\tFlit injection ratio per router is =%f (flits/clk/Total Endpoint %%)\n",(float)ratio*100/MAX_RATIO);
1494
        printf ("Simulation parameters-------------\n");
1495
 
1496
 
1497
 
1498 32 alirezamon
}
1499
 
1500
 
1501 38 alirezamon
 
1502
 
1503
 
1504 32 alirezamon
/************************
1505
 *
1506
 *      reset system
1507
 *
1508
 *
1509
 * *******************/
1510
 
1511
void reset_all_register (void){
1512
        int i;
1513 48 alirezamon
         total_active_endp=0;
1514
         total_rsv_pck_num=0;
1515
         total_sent_pck_num=0;
1516 32 alirezamon
         sum_clk_h2h=0;
1517
         sum_clk_h2t=0;
1518 48 alirezamon
         ideal_rsv_cnt=0;
1519 32 alirezamon
#if (STND_DEV_EN)
1520
         sum_clk_pow2=0;
1521
#endif
1522
 
1523
         sum_clk_per_hop=0;
1524
         count_en=0;
1525
         clk_counter=0;
1526
 
1527
         for(i=0;i<C;i++)
1528
         {
1529 48 alirezamon
                 total_rsv_pck_num_per_class[i]=0;
1530 32 alirezamon
             sum_clk_h2h_per_class[i]=0;
1531
             sum_clk_h2t_per_class[i]=0;
1532
                 sum_clk_per_hop_per_class[i]=0;
1533
#if (STND_DEV_EN)
1534
                 sum_clk_pow2_per_class[i]=0;
1535
#endif
1536
 
1537
         }  //for
1538 48 alirezamon
         total_sent_flit_number=0;
1539 54 alirezamon
         total_expect_rsv_flit_num=0;
1540 48 alirezamon
 
1541
 
1542 32 alirezamon
}
1543
 
1544
 
1545
 
1546
 
1547
/***********************
1548
 *
1549
 *      standard_dev
1550
 *
1551
 * ******************/
1552
 
1553
#if (STND_DEV_EN)
1554 42 alirezamon
/************************
1555
 * std_dev = sqrt[(B-A^2/N)/N]  = sqrt [(B/N)- (A/N)^2] = sqrt [B/N - mean^2]
1556
 * A = sum of the values
1557
 * B = sum of the squarded values
1558
 * *************/
1559 32 alirezamon
 
1560
double standard_dev( double sum_pow2, unsigned int  total_num, double average){
1561
        double std_dev;
1562 42 alirezamon
 
1563
        /*
1564
        double  A, B, N;
1565
        N= total_num;
1566
        A= average * N;
1567
        B= sum_pow2;
1568 32 alirezamon
 
1569 42 alirezamon
        A=(A*A)/N;
1570
        std_dev = (B-A)/N;
1571 32 alirezamon
        std_dev = sqrt(std_dev);
1572 42 alirezamon
*/
1573 48 alirezamon
        if(total_num==0) return 0;
1574 32 alirezamon
 
1575 42 alirezamon
        std_dev = sum_pow2/(double)total_num; //B/N
1576
        std_dev -= (average*average);// (B/N) - mean^2
1577
        std_dev = sqroot(std_dev);// sqrt [B/N - mean^2]
1578
 
1579 32 alirezamon
        return std_dev;
1580
 
1581
}
1582
 
1583
#endif
1584
 
1585
 
1586
 
1587
/**********************
1588
 *
1589
 *      pck_class_in_gen
1590
 *
1591
 * *****************/
1592
 
1593
unsigned char  pck_class_in_gen(
1594
         unsigned int  core_num
1595
 
1596
) {
1597
        unsigned char pck_class_in;
1598
        unsigned char  rnd=rand()%100;
1599 48 alirezamon
        int c=0;
1600
        int sum=class_percentage[0];
1601
        size_t n = sizeof(class_percentage)/sizeof(class_percentage[0]);
1602
        for(;;){
1603
                if( rnd < sum) return c;
1604
                if( c==n-1 ) return c;
1605
                c++;
1606
                sum+=class_percentage[c];
1607
        }
1608
        return 0;
1609 32 alirezamon
}
1610
 
1611 38 alirezamon
 
1612 32 alirezamon
 
1613
 
1614 38 alirezamon
void update_injct_var(unsigned int src,  unsigned int injct_var){
1615
        //printf("before%u=%u\n",src,random_var[src]);
1616
        random_var[src]= rnd_between(100-injct_var, 100+injct_var);
1617
        //printf("after=%u\n",random_var[src]);
1618
}
1619
 
1620 54 alirezamon
unsigned int pck_dst_gen_task_graph ( unsigned int src, unsigned char * inject_en){
1621 38 alirezamon
         task_t  task;
1622
        float f,v;
1623 54 alirezamon
        *inject_en=1;
1624 38 alirezamon
        int index = task_graph_abstract[src].active_index;
1625
 
1626
        if(index == DISABLE){
1627
                traffic[src]->ratio=0;
1628
                traffic[src]->stop=1;
1629 54 alirezamon
                *inject_en=0;
1630
                return INJECT_OFF; //disable sending
1631 38 alirezamon
        }
1632
 
1633
        if(     read(task_graph_data[src],index,&task)==0){
1634
                traffic[src]->ratio=0;
1635
                traffic[src]->stop=1;
1636 54 alirezamon
                *inject_en=0;
1637
                return INJECT_OFF; //disable sending
1638 38 alirezamon
 
1639
        }
1640
 
1641 54 alirezamon
#if (C>1)
1642
        if(sent_stat[src][traffic[src]->flit_out_class].pck_num & 0xFF){//sent 255 packets
1643
#else
1644
        if(sent_stat[src].pck_num & 0xFF){//sent 255 packets
1645
#endif
1646
 
1647 38 alirezamon
                        //printf("uu=%u\n",task.jnjct_var);
1648
                        update_injct_var(src, task.jnjct_var);
1649
 
1650
                }
1651
 
1652
        task_graph_total_pck_num++;
1653
        task.pck_sent = task.pck_sent +1;
1654
        task.burst_sent= task.burst_sent+1;
1655
        task.byte_sent = task.byte_sent + (task.avg_pck_size * (Fpay/8) );
1656
 
1657
        traffic[src]->pck_class_in=  pck_class_in_gen(src);
1658 48 alirezamon
        //traffic[src]->avg_pck_size_in=task.avg_pck_size;
1659 38 alirezamon
        traffic[src]->pck_size_in=rnd_between(task.min_pck_size,task.max_pck_size);
1660
 
1661
        f=  task.injection_rate;
1662
        v= random_var[src];
1663
        f*= (v /100);
1664
        if(f>100) f= 100;
1665
        f=  f * MAX_RATIO / 100;
1666
 
1667
        traffic[src]->ratio=(unsigned int)f;
1668
        traffic[src]->init_weight=task.initial_weight;
1669
 
1670
        if (task.burst_sent >= task.burst_size){
1671
                task.burst_sent=0;
1672
                task_graph_abstract[src].active_index=task_graph_abstract[src].active_index+1;
1673
                if(task_graph_abstract[src].active_index>=task_graph_abstract[src].total_index) task_graph_abstract[src].active_index=0;
1674
 
1675
        }
1676
 
1677
        update_by_index(task_graph_data[src],index,task);
1678
 
1679
        if (task.byte_sent  >= task.bytes){ // This task is done remove it from the queue
1680
                                remove_by_index(&task_graph_data[src],index);
1681
                                task_graph_abstract[src].total_index = task_graph_abstract[src].total_index-1;
1682
                                if(task_graph_abstract[src].total_index==0){ //all tasks are done turned off the core
1683
                                        task_graph_abstract[src].active_index=-1;
1684
                                        traffic[src]->ratio=0;
1685
                                        traffic[src]->stop=1;
1686
                                        if(total_active_routers!=0) total_active_routers--;
1687 54 alirezamon
                                        *inject_en=0;
1688 48 alirezamon
                                        return INJECT_OFF;
1689 38 alirezamon
                                }
1690
                                if(task_graph_abstract[src].active_index>=task_graph_abstract[src].total_index) task_graph_abstract[src].active_index=0;
1691
        }
1692
 
1693 48 alirezamon
        return endp_addr_encoder(task.dst);
1694 38 alirezamon
}
1695
 
1696
 
1697 54 alirezamon
void update_all_router_stat(void){
1698
        if(thread_num>1) {
1699
                int i;
1700
                for(i=0;i<thread_num;i++) thread[i]->update=true;
1701
                //thread_function (0);
1702
                thread[0]->function();
1703
                for(i=0;i<thread_num;i++)while(thread[i]->update==true);
1704
                return;
1705
        }
1706
        //no thread
1707
        for (int i=0; i<NR; i++) single_router_st_update(i);
1708
}
1709 38 alirezamon
 
1710 54 alirezamon
void update_router_st (
1711
                unsigned int Pnum,
1712
                unsigned int rid,
1713
                EVENT * event
1714 38 alirezamon
 
1715 54 alirezamon
){
1716 38 alirezamon
 
1717 54 alirezamon
        for (int p=0;p<Pnum;p++){
1718
                if(event[p] & FLIT_IN_WR_FLG ) router_stat [rid][p].flit_num_in++;
1719
                if(event[p] & PCK_IN_WR_FLG  ) router_stat [rid][p].pck_num_in++;
1720
                if(event[p] & FLIT_OUT_WR_FLG) router_stat [rid][p].flit_num_out++;
1721
                if(event[p] & PCK_OUT_WR_FLG ) router_stat [rid][p].pck_num_out++;
1722
                if(event[p] & FLIT_IN_BYPASSED)router_stat [rid][p].flit_num_in_bypassed++;
1723
                else if( event[p] & FLIT_IN_WR_FLG){
1724
                        router_stat [rid][p].flit_num_in_buffered++;
1725
                        int bypassed_times = (event[p] >> BYPASS_LSB);
1726
                        router_stat [rid][p].bypass_counter[bypassed_times]++;
1727
                }
1728
        }
1729
}
1730 38 alirezamon
 
1731 54 alirezamon
 
1732
void print_router_st (void) {
1733
 
1734
        //report router statistic
1735
        printf("\n\n\tRouters' statistics:\n");
1736
        printf("\t#RID, #Port,"
1737
                "flit_in,"
1738
                "pck_in,"
1739
                "flit_out,"
1740
                "pck_out,"
1741
                "flit_in_buffered,"
1742
                "flit_in_bypassed,"
1743
        );
1744
        if(SMART_MAX>0) for (int k=0;k<SMART_MAX+1;k++) printf("bypsd_%0d_times,",k);
1745
        printf("\n");
1746
 
1747
        for (int i=0; i<NR; i++){
1748
 
1749
                for (int p=0;p<MAX_P;p++){
1750
 
1751
                        printf("\t%u,%u,",i,p);
1752
                        printf("%d,%d,%d,%d,%d,%d,",
1753
                        router_stat [i][p].flit_num_in,
1754
                        router_stat [i][p].pck_num_in,
1755
                                router_stat [i][p].flit_num_out,
1756
                                router_stat [i][p].pck_num_out,
1757
                                router_stat [i][p].flit_num_in_buffered,
1758
                                router_stat [i][p].flit_num_in_bypassed
1759
                        );
1760
                if(SMART_MAX>0) for (int k=0;k<SMART_MAX+1;k++) printf("%d," ,router_stat [i][p].bypass_counter[k]);
1761
                printf("\n");
1762
                router_stat_accum [i].flit_num_in              += router_stat [i][p].flit_num_in;
1763
                router_stat_accum [i].pck_num_in               += router_stat [i][p].pck_num_in;
1764
                router_stat_accum [i].flit_num_out             += router_stat [i][p].flit_num_out;
1765
                router_stat_accum [i].pck_num_out              += router_stat [i][p].pck_num_out;
1766
                router_stat_accum [i].flit_num_in_buffered     += router_stat [i][p].flit_num_in_buffered;
1767
                router_stat_accum [i].flit_num_in_bypassed     += router_stat [i][p].flit_num_in_bypassed;
1768
                if(SMART_MAX>0) for (int k=0;k<SMART_MAX+1;k++) router_stat_accum [i].bypass_counter[k]+= router_stat [i][p].bypass_counter[k];
1769
 
1770
                }
1771
                printf("\t%u,total,",i);
1772
                printf("%d,%d,%d,%d,%d,%d,",
1773
                router_stat_accum [i].flit_num_in,
1774
                router_stat_accum [i].pck_num_in,
1775
                router_stat_accum [i].flit_num_out,
1776
                router_stat_accum [i].pck_num_out,
1777
                router_stat_accum [i].flit_num_in_buffered,
1778
                router_stat_accum [i].flit_num_in_bypassed
1779
                );
1780
                if(SMART_MAX>0) for (int k=0;k<SMART_MAX+1;k++) printf("%d," , router_stat_accum [i].bypass_counter[k]);
1781
                printf("\n");
1782
          }
1783
}
1784
 
1785
 
1786
void print_endp_to_endp_st(const char * st)  {
1787
        printf ("\n\tEndp_to_Endp %s:\n\t#EID,",st);
1788
        for (int src=0; src<NE; src++) printf ("%u,",src);
1789
        printf ("\n");
1790
        for (int src=0; src<NE; src++){
1791
                printf ("\t%u,",src);
1792
                for (int dst=0;dst<NE;dst++){
1793
                        if(strcmp(st,"pck_num")==0)  printf("%u,",endp_to_endp[src][dst].pck_num);
1794
                        if(strcmp(st,"flit_num")==0) printf("%u,",endp_to_endp[src][dst].flit_num);
1795
                }
1796
                printf ("\n");
1797
        }
1798
}

powered by: WebSVN 2.1.0

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