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] - Diff between revs 43 and 48

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 43 Rev 48
#include <stdlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>
#include <unistd.h>
#include <unistd.h>
#include <string.h>
#include <string.h>
#include <limits.h>
#include <limits.h>
#include <ctype.h>
#include <ctype.h>
#include <stdint.h>
#include <stdint.h>
#include <inttypes.h>
#include <inttypes.h>
#include <verilated.h>          // Defines common routines
#include <verilated.h>          // Defines common routines
//#include "Vrouter1.h"          included in parameter.h
 
#include "Vnoc.h"
 
#include "Vtraffic.h"
#include "Vtraffic.h"
#include "parameter.h"
#include "Vpck_inj.h"
#include "traffic_task_graph.h"
#include <thread>
#include "traffic_synthetic.h"
#include <vector>
 
#include <atomic>
 
 
#define RATIO_INIT              2
 
#define DISABLE -1
 
#define MY_VL_SETBIT_W(data,bit) (data[VL_BITWORD_I(bit)] |= (VL_UL(1) << VL_BITBIT_I(bit)))
 
#define STND_DEV_EN 1
 
#define SYNTHETIC 0
 
#define CUSTOM 1 
 
 
 
 
 
//Vrouter *router;
 
//Vrouter1              *router1[NR];                     // Included in parameter.h file
 
Vnoc                    *noc;
 
Vtraffic                *traffic[NE];
 
int reset,clk;
 
int TRAFFIC_TYPE=SYNTHETIC;
 
int PACKET_SIZE=5;
 
int MIN_PACKET_SIZE=5;
 
int MAX_PACKET_SIZE=5;
 
int MAX_PCK_NUM;
 
int MAX_SIM_CLKs;
 
int HOTSPOT_NUM;
 
int C0_p=100, C1_p=0, C2_p=0, C3_p=0;
 
char * TRAFFIC;
 
unsigned char FIXED_SRC_DST_PAIR;
 
unsigned char  NEw=0;
 
unsigned long int main_time = 0;     // Current simulation time
 
unsigned int saved_time = 0;
 
unsigned int total_pck_num=0;
 
unsigned int sum_clk_h2h,sum_clk_h2t;
 
double           sum_clk_per_hop;
 
const int  CC=(C==0)? 1 : C;
 
unsigned int total_pck_num_per_class[CC]={0};
 
unsigned int sum_clk_h2h_per_class[CC]={0};
 
unsigned int sum_clk_h2t_per_class[CC]={0};
 
double           sum_clk_per_hop_per_class[CC]={0};
 
unsigned int rsvd_core_total_pck_num[NE]= {0};
 
unsigned int rsvd_core_worst_delay[NE] =  {0};
 
unsigned int sent_core_total_pck_num[NE]= {0};
 
unsigned int sent_core_worst_delay[NE] =  {0};
 
unsigned int random_var[NE] = {100};
 
unsigned int clk_counter;
 
unsigned int count_en;
 
unsigned int total_router;
 
char all_done=0;
 
unsigned int flit_counter =0;
 
int ratio=RATIO_INIT;
 
double first_avg_latency_flit,current_avg_latency_flit;
 
double sc_time_stamp ();
 
int pow2( int );
 
 
 
#if (STND_DEV_EN)
 
        //#include <math.h>
 
        double sqroot (double s){
 
                int i;
 
                double root = s/3;
 
                if (s<=0) return 0;
 
                for(i=0;i<32;i++) root = (root +s/root)/2;
 
                return root;
 
        }
 
 
 
        double       sum_clk_pow2=0;
 
        double       sum_clk_pow2_per_class[C];
 
        double standard_dev( double , unsigned int, double);
 
#endif
 
 
 
void update_noc_statistic (     int);
 
unsigned char pck_class_in_gen(unsigned int);
 
unsigned int pck_dst_gen_task_graph ( unsigned int);
 
void print_statistic (char *);
 
void print_parameter();
 
void reset_all_register();
 
unsigned int rnd_between (unsigned int, unsigned int );
 
 
 
 
 
 
 
void  usage(){
 
        printf(" ./simulator -f [Traffic Pattern file]\n\nor\n");
 
        printf(" ./simulator -t [Traffic Pattern]  -s  [MIN_PCK_SIZE] -m [MAX_PCK_SIZE] -n  [MAX_PCK_NUM]  c    [MAX SIM CLKs]   -i [INJECTION RATIO] -p [class traffic ratios (%%)]  -h[HOTSPOT info] \n");
 
        printf("      Traffic Pattern: \"HOTSPOT\" \"RANDOM\" \"TORNADO\" \"BIT_REVERSE\"  \"BIT_COMPLEMENT\"  \"TRANSPOSE1\"   \"TRANSPOSE2\"\n");
 
        printf("      MIN_PCK_SIZE: Minimum packet size in flit. The injected packet size is randomly selected between minimum and maximum packet size\n ");
 
        printf("      MAX_PCK_SIZE: Maximum packet size in flit. The injected packet size is randomly selected between minimum and maximum packet size\n ");
 
        printf("      MAX_PCK_NUM: total number of sent packets. Simulation will stop when total of sent packet by all nodes reach this number\n");
 
        printf("      MAX_SIM_CLKs: simulation clock limit. Simulation will stop when simulation clock number reach this value \n");
 
        printf("      INJECTION_RATIO: packet injection ratio");
 
        printf("      class traffic ratios %%: The percentage of traffic injected for each class. represented in string whit each class ratio is separated by comma. \"n0,n1,n2..\" \n");
 
        printf("      hotspot traffic info: represented in a string with following format:  \"HOTSPOT PERCENTAGE,HOTSPOT NUM,HOTSPOT CORE 1,HOTSPOT CORE 2,HOTSPOT CORE 3,HOTSPOT CORE 4,HOTSPOT CORE 5, ENABLE HOTSPOT CORES SEND \"   \n");
 
}
 
 
 
 
 
int parse_string ( char * str, int * array)
#include <cstdint>
{
#include <cstdlib>
    int i=0;
#include <iostream>
    char *pt;
 
    pt = strtok (str,",");
 
    while (pt != NULL) {
 
        int a = atoi(pt);
 
        array[i]=a;
 
        i++;
 
        pt = strtok (NULL, ",");
 
    }
 
   return i;
 
}
 
 
 
 
#include "simulator.h"
 
 
unsigned int pck_dst_gen (      unsigned int core_num) {
int main(int argc, char** argv) {
        if(TRAFFIC_TYPE==CUSTOM)        return          pck_dst_gen_task_graph ( core_num);
        char change_injection_ratio=0;
        if((strcmp (TOPOLOGY,"MESH")==0)||(strcmp (TOPOLOGY,"TORUS")==0)) return  pck_dst_gen_2D (core_num);
        int i,j,x,y;//,report_delay_counter=0;
        return pck_dst_gen_1D (core_num);
 
 
        char deafult_out[] = {"result"};
 
        NEw=Log2(NE);
 
        for(i=0;i<NE;i++)   custom_traffic_table[i]=INJECT_OFF; //off
 
        Verilated::commandArgs(argc, argv);   // Remember args
 
        processArgs ( argc,  argv );
 
 
 
        if (class_percentage==NULL) {
 
                        class_percentage =   (int *) malloc(sizeof(int));
 
                        class_percentage[0]=100;
}
}
 
 
 
 
 
        Vrouter_new();
 
        if( TRAFFIC_TYPE == NETRACE)    for(i=0;i<NE;i++)        pck_inj[i]  = new Vpck_inj;
 
        else                            for(i=0;i<NE;i++)        traffic[i]  = new Vtraffic;
 
 
void update_hotspot(char * str){
 
         int i;
        if( TRAFFIC_TYPE == NETRACE) netrace_init(netrace_file);
         int array[1000];
 
         int p;
        FIXED_SRC_DST_PAIR = strcmp (TRAFFIC,"RANDOM") &  strcmp(TRAFFIC,"HOTSPOT") & strcmp(TRAFFIC,"random") & strcmp(TRAFFIC,"hot spot") & strcmp(TRAFFIC,"TASK");
         int acuum=0;
 
         hotspot_st * new_node;
 
         p= parse_string (str, array);
        /********************
         if (p<4){
        *       initialize input
                        printf("Error in hotspot traffic parameters \n");
        *********************/
                        exit(1);
 
 
        reset=1;
 
        reset_all_register();
 
        start_i=0;
 
        topology_init();
 
        if( TRAFFIC_TYPE == NETRACE) pck_inj_init();
 
        else    traffic_gen_init();
 
        main_time=0;
 
        print_parameter();
 
        if( thread_num>1) initial_threads();
 
 
 
        while (!Verilated::gotFinish()) {
 
 
 
                if (main_time-saved_time >= 10 ) {
 
                        reset = 0;
         }
         }
         HOTSPOT_NUM=array[0];
 
         if (p<1+HOTSPOT_NUM*3){
                if(main_time == saved_time+21){ count_en=1; start_i=1;}
                        printf("Error in hotspot traffic parameters \n");
                if(main_time == saved_time+23) start_i=0;
                        exit(1);
 
 
                if(TRAFFIC_TYPE==NETRACE) netrace_posedge_event();
 
                else traffic_clk_posedge_event();
 
                //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
 
                //between modules when the clock .
 
                for (i=0;i<SMART_MAX+2;i++) {
 
                        if(TRAFFIC_TYPE==NETRACE) netrace_clk_negedge_event( );
 
                        else traffic_clk_negedge_event( );
 
                }
 
 
 
                if(simulation_done){
 
                        if( TRAFFIC_TYPE == NETRACE) netrace_final_report();
 
                        else traffic_gen_final_report();
 
                        sim_final_all();
 
                        return 0;
         }
         }
         new_node =  (hotspot_st *) malloc( HOTSPOT_NUM * sizeof(hotspot_st));
 
         if( new_node == NULL){
                main_time++;
        printf("Error: cannot allocate memory for hotspot traffic\n");
 
            exit(1);
        }//Simulating is done
 
 
 
        sim_final_all();
 
        return 0;
 
 
         }
         }
         for (i=1;i<3*HOTSPOT_NUM; i+=3){
 
                new_node[i/3]. ip_num = array[i];
 
            new_node[i/3]. send_enable=array[i+1];
#define __FILENAME__ (__FILE__ + SOURCE_PATH_SIZE)
            new_node[i/3]. percentage =  acuum + array[i+2];
 
            acuum= new_node[i/3]. percentage;
void  usage(char * bin_name){
 
        printf("Usage:\n"
 
" %s -t <synthetic Traffic Pattern name> [synthetic Traffic options]\n"
 
" %s -f <Task file> [Task options] or\n"
 
" %s -F <netrace file> [Netrace options] \n\n"
 
"synthetic Traffic options:\n"
 
"  -t <Traffic Pattern>        \"HOTSPOT\", \"RANDOM\", \"BIT_COMPLEMENT\" , \"BIT_REVERSE\",\n "
 
"                              \"TORNADO\", \"TRANSPOSE1\", \"TRANSPOSE2\", \"SHUFFEL\", \"CUSTOM\"\n"
 
"  -m <Packet size info>       packet size format  Random-Range or Random-discrete:\n"
 
"                              Random-Range : \"R,MIN,MAX\" : The injected packets' size in flits are\n"
 
"                                 randomly selected in range MIN <= PCK_size <=MAX \n"
 
"                              Random-discrete: \"D,S1,S2,..Sn,P,P1,P2,P3,...Pn\": Si are the discrete\n"
 
"                                 set of numbers representing packet size. The injected packet size is\n"
 
"                                 randomly selected among these discrete values according to associated\n"
 
"                                 probability values.\n"
 
"  -c <sim_end_clk_num>        Simulation will stop when simulation clock number reach this value\n"
 
"  -n <sim_end_pck_num>        Simulation will stop when total of sent packets to the noc reaches this number\n"
 
"  -i <injection ratio>        flit injection ratio in percentage\n"
 
"  -p <class traffic ratios>   The percentage of traffic injected for each class. represented in string\n"
 
"                              each class ratio is separated by comma. \"n0,n1,n2..\" \n"
 
"  -h <HOTSPOT traffic format> represented in a string with following format:\n"
 
"                              total number of hotspot nodes, first hotspot node ID, first hotspot node\n"
 
"                              send enable(1 or 0),first hotspot node percentage x10,second hotspot node ...\n"
 
"  -H <custom traffic pattern> custom traffic pattern: represented in a string with following format:\n"
 
"                              \"SRC1,DEST1, SRC2,DEST2, .., SRCn, DESTn\"   \n"
 
"  -T <thread-num>             total number of threads. The default is one (no-thread).   \n"
 
//"  -Q                          Quick (fast) simulation. ignore evaluating non-active routers \n"
 
"                              to speed up simulation time"
 
"\nTrace options:\n"
 
"  -f <Task file>              path to the task file. any custom task file can be generated using ProNoC gui\n"
 
"  -c <sim_end_clk_num>        Simulation will stop when simulation clock number reach this value \n"
 
"  -T <thread-num>             total number of threads. The default is one (no-thread).   \n"
 
//"  -Q                          Quick (fast) simulation. ignore evaluating non-active routers \n"
 
"                              to speed up simulation time"
 
"\nNetrace options:\n"
 
"  -F <Netrace file>           path to the task file. any custom task file can be generated using ProNoC gui\n"
 
"  -n <sim_end_pck_num>        Simulation will stop when total of sent packets to the NoC reaches this number\n"
 
"  -d                          ignore dependencies\n"
 
"  -r <start region>           start region\n"
 
"  -l                          reader throttling\n"
 
"  -v <level>                  Verbosity level. 0: off, 1:display a live number of injected packet,\n"
 
"                              3: print injected/ejected packets details, default is 1\n"
 
"  -T <thread-num>             total number of threads. The default is one (no-thread).   \n"
 
"  -s <speed-up-num>               the speed-up-num  is the ratio of netrace frequency to pronoc.The higher value\n"
 
"                              results in higher injection ratio to the NoC. Default is one"
 
//"  -Q                          Quick (fast) simulation. ignore evaluating non-active routers \n"
 
"                              to speed up simulation time"     ,
 
bin_name,bin_name,bin_name
 
);
 
 
         }
         }
         if(acuum> 1000){
 
                        printf("Warning: The hotspot traffic summation %f exceed than 100 percent.  \n", (float) acuum /10);
 
 
 
 
 
 
 
 
void netrace_processArgs (int argc, char **argv )
 
{
 
   char c;
 
 
 
   /* don't want getopt to moan - I can do that just fine thanks! */
 
   opterr = 0;
 
   if (argc < 2)  usage(argv[0]);
 
   while ((c = getopt (argc, argv, "F:dr:lv:T:n:s:")) != -1)
 
   {
 
         switch (c)
 
         {
 
                case 'F':
 
                        TRAFFIC_TYPE=NETRACE;
 
                        TRAFFIC=(char *) "NETRACE";
 
                        netrace_file = optarg;
 
                        break;
 
                case 'd':
 
                        ignore_dependencies=1;
 
                        break;
 
                case 'r':
 
                        start_region=atoi(optarg);
 
                        break;
 
                case 'l':
 
                        reader_throttling=1;
 
                        break;
 
                case 'v':
 
                        verbosity= atoi(optarg);
 
                        break;
 
                case  'T':
 
                        thread_num = atoi(optarg);
 
                        break;
 
                case 'n':
 
                        end_sim_pck_num=atoi(optarg);
 
                        break;
 
                case 's':
 
                        netrace_speed_up=atoi(optarg);
 
 
 
                        break;
 
                case '?':
 
                    if (isprint (optopt))
 
                        fprintf (stderr, "Unknown option `-%c'.\n", optopt);
 
                        else
 
                            fprintf (stderr,  "Unknown option character `\\x%x'.\n",  optopt);
 
             default:
 
                       usage(argv[0]);
 
                       exit(1);
 
          }
         }
         }
         hotspots=new_node;
 
}
}
 
 
 
 
 
 
void processArgs (int argc, char **argv )
void synthetic_task_processArgs (int argc, char **argv )
{
{
   char c;
   char c;
   int p;
   int p;
   int array[10];
   int array[10];
   float f;
   float f;
 
 
   /* don't want getopt to moan - I can do that just fine thanks! */
   /* don't want getopt to moan - I can do that just fine thanks! */
   opterr = 0;
   opterr = 0;
   if (argc < 2)  usage();
   if (argc < 2)  usage(argv[0]);
   while ((c = getopt (argc, argv, "t:s:m:n:c:i:p:h:f:")) != -1)
   while ((c = getopt (argc, argv, "t:m:n:c:i:p:h:H:f:T:Q")) != -1)
      {
      {
         switch (c)
         switch (c)
            {
            {
                case 'f':
                case 'f':
                        TRAFFIC_TYPE=CUSTOM;
                        TRAFFIC_TYPE=TASK;
                        TRAFFIC=(char *) "CUSTOM from file";
                        TRAFFIC=(char *) "TASK";
                        load_traffic_file(optarg,task_graph_data,task_graph_abstract);
                        task_traffic_init(optarg);
                        MAX_PCK_NUM=task_graph_total_pck_num;
 
                        break;
                        break;
            case 't':
            case 't':
                        TRAFFIC=optarg;
                        TRAFFIC=optarg;
                        total_active_routers=-1;
                        total_active_routers=-1;
                        break;
                        break;
                case 's':
                case 's':
                        MIN_PACKET_SIZE=atoi(optarg);
                        MIN_PACKET_SIZE=atoi(optarg);
                        break;
                        break;
                case 'm':
 
                        MAX_PACKET_SIZE=atoi(optarg);
 
                        break;
 
                case 'n':
                case 'n':
                         MAX_PCK_NUM=atoi(optarg);
                         end_sim_pck_num=atoi(optarg);
                         break;
                         break;
                case 'c':
                case 'c':
                         MAX_SIM_CLKs=atoi(optarg);
                         sim_end_clk_num=atoi(optarg);
                         break;
                         break;
                case 'i':
                case 'i':
                         f=atof(optarg);
                         f=atof(optarg);
                         f*=(MAX_RATIO/100);
                         f*=(MAX_RATIO/100);
                         ratio= (int) f;
                         ratio= (int) f;
                         break;
                         break;
                case 'p':
                case 'p':
                        p= parse_string (optarg, array);
                        p= parse_string (optarg, array);
                    C0_p=array[0];
                        if (p==0) {
                    C1_p=array[1];
                                printf("Warning: class setting is ignored!\n");
                    C2_p=array[2];
                                break;
                    C3_p=array[3];
                        }
 
                        class_percentage =   (int *) malloc( p * sizeof(int));
 
                        for(int k=0;k<p;k++){
 
                                class_percentage[k]=array[k];
 
                        }
 
                        if(p >1 && p>C){
 
                                printf("Warning: the number of given class %u is larger than the number of message classes in ProNoC (C=%u)!\n",p,C);
 
                        }
 
                        break;
 
                case 'm':
 
                        update_pck_size(optarg);
 
 
 
                        break;
 
                case 'H':
 
                        update_custom_traffic(optarg);
                        break;
                        break;
                case 'h':
                case 'h':
                        update_hotspot(optarg);
                        update_hotspot(optarg);
                        break;
                        break;
 
                case  'T':
 
                        thread_num = atoi(optarg);
 
                        break;
 
                case 'Q':
 
                        //Quick_sim_en=1;
 
                        fprintf (stderr, "Unknown option `-%c'.\n", optopt);
 
                        usage(argv[0]);
 
                        exit(1);
 
                        break;
            case '?':
            case '?':
               if (isprint (optopt))
               if (isprint (optopt))
                  fprintf (stderr, "Unknown option `-%c'.\n", optopt);
                  fprintf (stderr, "Unknown option `-%c'.\n", optopt);
               else
               else
                  fprintf (stderr,
                  fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
                           "Unknown option character `\\x%x'.\n",
 
                           optopt);
 
            default:
            default:
               usage();
               usage(argv[0]);
               exit(1);
               exit(1);
            }
            }
      }
      }
   PACKET_SIZE=(MIN_PACKET_SIZE+MAX_PACKET_SIZE)/2;// average packet size
 
}
}
 
 
 
 
 
 
 
 
int main(int argc, char** argv) {
int parse_string ( char * str, int * array)
        char change_injection_ratio=0,inject_done;
{
        int i,j,x,y;//,report_delay_counter=0;
    int i=0;
        char file_name[100];
    char *pt;
        char deafult_out[] = {"result"};
    pt = strtok (str,",");
        char * out_file_name;
    while (pt != NULL) {
        unsigned int dest_e_addr;
        int a = atoi(pt);
 
        array[i]=a;
 
        i++;
 
        pt = strtok (NULL, ",");
 
    }
 
   return i;
 
}
 
 
 
 
 
 
 
 
 
 
 
 
 
unsigned int pck_dst_gen (      unsigned int core_num) {
 
        if(TRAFFIC_TYPE==TASK)  return          pck_dst_gen_task_graph ( core_num);
 
        if((strcmp (TOPOLOGY,"MESH")==0)||(strcmp (TOPOLOGY,"TORUS")==0)) return  pck_dst_gen_2D (core_num);
 
        return pck_dst_gen_1D (core_num);
 
}
 
 
 
 
 
 
 
void update_hotspot(char * str){
 
         int i;
 
         int array[1000];
 
         int p;
 
         int acuum=0;
 
         hotspot_st * new_node;
 
         p= parse_string (str, array);
 
         if (p<4){
 
                    fprintf(stderr,"ERROR: in hotspot traffic parameters. 4 value should be given as hotspot parameter\n");
 
                        exit(1);
 
         }
 
         HOTSPOT_NUM=array[0];
 
         if (p<1+HOTSPOT_NUM*3){
 
                    fprintf(stderr,"ERROR: in hotspot traffic parameters \n");
 
                        exit(1);
 
         }
 
         new_node =  (hotspot_st *) malloc( HOTSPOT_NUM * sizeof(hotspot_st));
 
         if( new_node == NULL){
 
                 fprintf(stderr,"ERROR: cannot allocate memory for hotspot traffic\n");
 
            exit(1);
 
         }
 
         for (i=1;i<3*HOTSPOT_NUM; i+=3){
 
                new_node[i/3]. ip_num = array[i];
 
            new_node[i/3]. send_enable=array[i+1];
 
            new_node[i/3]. percentage =  acuum + array[i+2];
 
            acuum= new_node[i/3]. percentage;
 
 
 
         }
 
         if(acuum> 1000){
 
                        printf("Warning: The hotspot traffic summation %f exceed than 100 percent.  \n", (float) acuum /10);
 
         }
 
         hotspots=new_node;
 
}
 
 
 
void update_custom_traffic (char * str){
 
        int i;
 
        int array[10000];
 
        int p;
 
        p= parse_string (str, array);
 
        for (i=0;i<p; i+=2){
 
                custom_traffic_table[array[i]] = array[i+1];
 
        }
 
}
 
 
 
void update_pck_size(char *str){
 
        int i;
 
        int array[1000];
 
        char substring[1000];
 
        int p;
 
        char *pt,*pt2;
 
        MIN_PACKET_SIZE=100000;
 
        MAX_PACKET_SIZE=1;
 
 
 
 
 
        pt = strtok (str,",");
 
        if(*pt=='R'){//random range
 
                p= parse_string (str+2, array);
 
                if(p<2){
 
                        fprintf(stderr,"ERROR: Wrong Packet size format %s. It should be \"R,min,max\" : \n",str);
 
                        exit(1);
 
                }
 
 
 
                MIN_PACKET_SIZE=array[0];
 
                MAX_PACKET_SIZE=array[1];
 
                AVG_PACKET_SIZE=(MIN_PACKET_SIZE+MAX_PACKET_SIZE)/2;// average packet size
 
        }else if(*pt=='D'){//random discrete
 
                pck_size_sel =  RANDOM_discrete;
 
                pt = strtok (str+2,"P");
 
                pt2 = strtok (NULL,"P");
 
                if (pt == NULL || pt2==NULL) {
 
                        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);
 
                        exit(1);
 
                }
 
                p= parse_string (pt, array);
 
                if (p==0){
 
                        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);
 
                        exit(1);
 
                }
 
                int in=p;
 
                //alocate mmeory for pck size
 
                discrete_size = (int*)malloc((p) * sizeof(int));
 
                discrete_prob = (int*)malloc((p) * sizeof(int));
 
                // Check if the memory has been successfully allocated
 
                if (discrete_size == NULL || discrete_prob==NULL) {
 
                        printf("ERROR: Memory not allocated.\n");
 
                        exit(1);
 
                }
 
 
 
                for (i=0; i<p; i++){
 
 
 
                        //printf("I[%u]=%u,\n",i,array[i]);
 
                        discrete_size[i] = array[i];
 
                        if(MIN_PACKET_SIZE > array[i]) MIN_PACKET_SIZE = array[i];
 
                        if(MAX_PACKET_SIZE < array[i]) MAX_PACKET_SIZE = array[i];
 
                }
 
 
 
                p= parse_string (pt2+1, array);
 
                int sum=0;
 
                AVG_PACKET_SIZE=0;
 
                for (i=0; i<p; i++){
 
                        //printf("P[%u]=%u,\n",i,array[i]);
 
                        if(i<in){
 
                                 sum+=array[i];
 
                                 discrete_prob[i]=sum;
 
                                 AVG_PACKET_SIZE+=discrete_size[i] * array[i];
 
 
 
                        }
 
                }
 
                AVG_PACKET_SIZE/=100;
 
 
 
                if(sum!=100){
 
                        fprintf(stderr,"ERROR: The accumulatio of the first %u probebility values is %u which is not equal to 100\n",in,sum);
 
                        exit(1);
 
                }
 
 
 
        }else {
 
                fprintf(stderr,"ERROR: Wrong Packet size format %s. It should start with one of \"D\" or \"R\" letter\n",str);
 
                exit(1);
 
        }
 
        p=(MAX_PACKET_SIZE-MIN_PACKET_SIZE)+1;
 
        rsv_size_array = (unsigned int*) calloc ( p , sizeof(int));
 
        if (rsv_size_array==NULL){
 
                 fprintf(stderr,"ERROR: cannot allocate memory for rsv_size_array\n");
 
                 exit(1);
 
        }
 
 
 
}
 
 
 
 
 
void task_traffic_init (char * str) {
 
        load_traffic_file(str,task_graph_data,task_graph_abstract);
 
        end_sim_pck_num=task_graph_total_pck_num;
 
        MIN_PACKET_SIZE = task_graph_min_pck_size;
 
        MAX_PACKET_SIZE = task_graph_max_pck_size;
 
        AVG_PACKET_SIZE=(MIN_PACKET_SIZE+MAX_PACKET_SIZE)/2;// average packet size
 
        int p=(MAX_PACKET_SIZE-MIN_PACKET_SIZE)+1;
 
        rsv_size_array = (unsigned int*) calloc ( p , sizeof(int));
 
        if (rsv_size_array==NULL){
 
                fprintf(stderr,"ERROR: cannot allocate (%d x int) memory for rsv_size_array. \n",p);
 
                 exit(1);
 
        }
 
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
void processArgs (int argc, char **argv ){
 
        int i;
 
        for( i = 1; i < argc; ++i ) {
 
                if( strcmp(argv[i], "-t") == 0 ) {
 
                        synthetic_task_processArgs ( argc, argv );
 
                        return;
 
                } else if( strcmp(argv[i], "-f") == 0 ) {
 
                        synthetic_task_processArgs ( argc, argv );
 
                        return;
 
 
 
                } else if( strcmp(argv[i], "-F") == 0 ) {
 
                        netrace_processArgs (argc, argv );
 
                        return;
 
                }
 
        }
 
        fprintf (stderr, "you should define one one of Synthetic,Task or nettrace based simulation. \n");
 
        usage(argv[0]);
 
        exit(1);
 
}
 
 
 
 
 
int get_new_pck_size(){
 
                if(pck_size_sel ==  RANDOM_discrete){
 
                                int rnd = rand() % 100; // 0~99
 
                                int i=0;
 
                                while( rnd > discrete_prob[i] ) i++;
 
                                return discrete_size [i];
 
                }
 
                //random range
 
                return rnd_between(MIN_PACKET_SIZE,MAX_PACKET_SIZE);
 
}
 
 
 
 
 
 
 
 
 
 
 
 
 
void traffic_gen_final_report(){
 
        int i;
 
        for (i=0;i<NE;i++) if(traffic[i]->pck_number>0) total_active_endp         =       total_active_endp +1;
 
        printf("\nsimulation results-------------------\n");
 
        printf("\tSimulation clock cycles:%d\n",clk_counter);
 
        printf("\n\tTotal injected packet in different size:\n");
 
        printf("\tflit_size,");
 
        for (i=0;i<=(MAX_PACKET_SIZE - MIN_PACKET_SIZE);i++){
 
                if(rsv_size_array[i]>0) printf("%u,",i+ MIN_PACKET_SIZE);
 
        }
 
        printf("\n\t#pck,");
 
        for (i=0;i<=(MAX_PACKET_SIZE - MIN_PACKET_SIZE);i++){
 
                if(rsv_size_array[i]>0) printf("%u,",rsv_size_array[i]);
 
        }
 
        printf("\n");
 
 
 
//      printf(" total received flits:%d\n",total_rsv_flit_number);
 
//      printf(" total sent flits:%d\n",total_sent_flit_number);
 
        print_statistic_new (clk_counter);
 
 
 
}
 
 
 
 
 
void traffic_gen_init( void ){
 
        int i;
 
        unsigned int dest_e_addr;
 
        for (i=0;i<NE;i++){
 
                random_var[i] = 100;
 
                traffic[i]->current_e_addr              = endp_addr_encoder(i);
 
                traffic[i]->start=0;
 
                traffic[i]->pck_class_in=  pck_class_in_gen( i);
 
                traffic[i]->pck_size_in=get_new_pck_size();
 
                dest_e_addr=pck_dst_gen (i);
 
                traffic[i]->dest_e_addr= dest_e_addr;
 
                if(dest_e_addr == INJECT_OFF) traffic[i]->stop=1;
 
                //printf("src=%u, des_eaddr=%x, dest=%x\n", i,dest_e_addr, endp_addr_decoder(dest_e_addr));
 
                if(inject_done) traffic[i]->stop=1;
 
                traffic[i]->start_delay=rnd_between(1,4*NE-2);
 
                if(TRAFFIC_TYPE==SYNTHETIC){
 
                        //traffic[i]->avg_pck_size_in=AVG_PACKET_SIZE;
 
                        traffic[i]->ratio=ratio;
 
                        traffic[i]->init_weight=1;
 
                }
 
        }
 
}
 
 
 
void pck_inj_init (void){
 
        int i;
 
        for (i=0;i<NE;i++){
 
                pck_inj[i]->current_e_addr              = endp_addr_encoder(i);
 
           //TODO mapping should be done according to number of NE and should be set by the user larer
 
                netrace_to_pronoc_map[i]=(int)((i* NE)/header->num_nodes);
 
                pck_inj[i]->pck_injct_in_ready= (0x1<<V)-1;
 
                pck_inj[i]->pck_injct_in_pck_wr=0;
 
                //pronoc_to_netrace_map[i]=i;
 
 
 
        }
 
 
 
}
 
 
 
/*************
 
 * sc_time_stamp
 
 *
 
 * **********/
 
double sc_time_stamp () {       // Called by $time in Verilog
 
        return main_time;
 
}
 
 
 
int pow2( int num){
 
        int pw;
 
        pw= (0x1 << num);
 
        return pw;
 
}
 
 
 
/*
 
volatile int *  lock;
 
unsigned int  nr_per_thread=0;
 
unsigned int  ne_per_thread=0;
 
 
 
void thread_function (int n){
 
        int i;
 
        unsigned int node=0;
 
        while(1){
 
                while(lock[n]==0) std::this_thread::yield();
 
                for(i=0;i<nr_per_thread;i++){
 
                        node= (n * nr_per_thread)+i;
 
                        if (node >= NR) break;
 
                        single_router_eval(node);
 
                }
 
                for(i=0;i<ne_per_thread;i++){
 
                        node= (n * ne_per_thread)+i;
 
                        if (node >= NE) break;
 
                        if( TRAFFIC_TYPE == NETRACE)   pck_inj[node]->eval();
 
                        else   traffic[node]->eval();
 
                }
 
 
 
                //router1[n]->eval();
 
                //if( TRAFFIC_TYPE == NETRACE)   pck_inj[n]->eval();
 
                //else   traffic[n]->eval();
 
 
 
                lock[n]=0;
 
                if(n==0) break;//first thread is the main process
 
        }
 
}
 
*/
 
 
 
class alignas(64) Vthread
 
{
 
    // Access specifier
 
    public:
 
        std::atomic<bool> ready;
 
    // Data Members
 
    int n;//thread num
 
        int nr_per_thread;
 
        int ne_per_thread;
 
    // Member Functions()
 
    //Parameterized Constructor
 
 
 
 
 
    void function ( ){
 
                int i;
 
                unsigned int node=0;
 
                while(1){
 
                        while(!ready) std::this_thread::yield();
 
                        for(i=0;i<nr_per_thread;i++){
 
                                node= (n * nr_per_thread)+i;
 
                                if (node >= NR) break;
 
                                //if(router_is_active[node] | (Quick_sim_en==0))
 
                                single_router_eval(node);
 
                        }
 
                        for(i=0;i<ne_per_thread;i++){
 
                                node= (n * ne_per_thread)+i;
 
                                if (node >= NE) break;
 
                                if( TRAFFIC_TYPE == NETRACE)   pck_inj[node]->eval();
 
                                else   traffic[node]->eval();
 
                        }
 
 
 
                        //router1[n]->eval();
 
                        //if( TRAFFIC_TYPE == NETRACE)   pck_inj[n]->eval();
 
                        //else   traffic[n]->eval();
 
 
 
                        ready=false;
 
                        if(n==0) break;//first thread is the main process 
 
                }
 
        }
 
 
 
        Vthread(int x,int r,int e)
 
    {
 
       n=x; nr_per_thread=r; ne_per_thread=e;
 
       ready=false;
 
       if(n!=0) {
 
                 std::thread th {&Vthread::function,this};
 
         th.detach();
 
           }
 
    }
 
 
 
 
        while((0x1<<NEw) < NE)NEw++;
};
        while((0x1<<nxw) < T1){nxw++;maskx<<=1; maskx|=1;}
 
        while((0x1<<nyw) < T2){nyw++;masky<<=1; masky|=1;}
 
 
 
        Verilated::commandArgs(argc, argv);   // Remember args
Vthread ** thread;
        Vrouter_new();
 
        noc                                                             = new Vnoc;
 
        for(i=0;i<NE;i++)        traffic[i]  = new Vtraffic;
 
 
 
        processArgs ( argc,  argv );
void initial_threads (void){
 
        int i;
 
        //devide nodes equally between threads
 
        unsigned int  nr_per_thread=0;
 
        unsigned int  ne_per_thread=0;
 
        nr_per_thread = (NR % thread_num)?  (unsigned int)(NR/thread_num) + 1 :  (unsigned int)(NR/thread_num);
 
        ne_per_thread = (NE % thread_num)?  (unsigned int)(NE/thread_num) + 1 :  (unsigned int)(NE/thread_num);
 
 
 
        //std::vector<std::thread> threads(thread_num-1);
 
        //lock = new int[thread_num];
 
        //for(i=0;i<thread_num;i++) lock [i]=0; 
 
 
        FIXED_SRC_DST_PAIR = strcmp (TRAFFIC,"RANDOM") &  strcmp(TRAFFIC,"HOTSPOT") & strcmp(TRAFFIC,"random") & strcmp(TRAFFIC,"hot spot") & strcmp(TRAFFIC,"CUSTOM from file");
        //Dynamically Allocating Memory
 
        thread = (Vthread **) new Vthread * [thread_num];
 
        for(i=0;i<thread_num;i++) thread[i] = new Vthread(i,nr_per_thread,ne_per_thread) ;
 
 
 
        //initiates (thread_num-1) number of live thread         
 
        //for(i=0;i<thread_num-1;i++) threads[i] = std::thread(&thread_function, (i+1));
 
        //for (auto& th : threads)    th.detach();
 
 
        /********************
        unsigned maxThreads = std::thread::hardware_concurrency();
        *       initialize input
    printf("Thread is initiated as following:\n"
        *********************/
    "\tMax hardware supported threads:%u\n"
 
    "\tthread_num:%u\n"
 
    "\trouter per thread:%u\n"
 
    "\tendpoint per thread:%u\n"
 
    ,maxThreads,thread_num,nr_per_thread,ne_per_thread);
 
}
 
 
        reset=1;
 
        reset_all_register();
 
        noc->start_i=0;
 
 
 
 
 
 
 
 
void sim_eval_all (void){
 
        int i;
 
        if(thread_num>1) {
 
                for(i=0;i<thread_num;i++) thread[i]->ready=true;
 
                //thread_function (0);          
 
                thread[0]->function();
 
                for(i=0;i<thread_num;i++)while(thread[i]->ready);
 
        }else{// no thread
 
                //routers_eval();
 
                for(i=0;i<NR;i++){
 
                        //if(router_is_active[i] | (Quick_sim_en==0)) 
 
                        single_router_eval(i);
 
                }
 
                if( TRAFFIC_TYPE == NETRACE) for(i=0;i<NE;i++) pck_inj[i]->eval();
 
                else for(i=0;i<NE;i++) traffic[i]->eval();
 
        }
 
}
 
 
 
void sim_final_all (void){
 
        int i;
 
        routers_final();
 
        if( TRAFFIC_TYPE == NETRACE) for(i=0;i<NE;i++) pck_inj[i]->final();
 
        else for(i=0;i<NE;i++) traffic[i]->final();
 
        //noc->final(); 
 
}
 
 
 
void connect_clk_reset_start_all(void){
 
        int i;
 
        //noc-> clk = clk; 
 
        //noc-> reset = reset;
 
        if( TRAFFIC_TYPE == NETRACE) {
    for (i=0;i<NE;i++){
    for (i=0;i<NE;i++){
        random_var[i] = 100;
                        pck_inj[i]->reset= reset;
        traffic[i]->current_e_addr              = endp_addr_encoder(i);
                        pck_inj[i]->clk = clk;
        traffic[i]->start=0;
                }
        traffic[i]->pck_class_in=  pck_class_in_gen( i);
        }else {
        traffic[i]->pck_size_in=rnd_between(MIN_PACKET_SIZE,MAX_PACKET_SIZE);
                for(i=0;i<NE;i++)        {
        dest_e_addr=pck_dst_gen (i);
                        start_o[i]=start_i;
        traffic[i]->dest_e_addr= dest_e_addr;
                        traffic[i]->start= start_o[i];
        //printf("src=%u, des_eaddr=%x, dest=%x\n", i,dest_e_addr, endp_addr_decoder(dest_e_addr));
                        traffic[i]->reset= reset;
        traffic[i]->stop=0;
                        traffic[i]->clk = clk;
        if(TRAFFIC_TYPE==SYNTHETIC){
 
                traffic[i]->pck_size_in=PACKET_SIZE;
 
                traffic[i]->avg_pck_size_in=PACKET_SIZE;
 
                traffic[i]->ratio=ratio;
 
                traffic[i]->init_weight=1;
 
        }
        }
        }
        }
 
        connect_routers_reset_clk();
 
}
 
 
        main_time=0;
 
        print_parameter();
 
        if(strcmp(TRAFFIC,"CUSTOM from file")) printf("\n\n\n Flit injection ratio per router is =%f \n",(float)ratio*100/MAX_RATIO);
 
        //printf("\n\n\n delay= %u clk",router->delay);
 
        while (!Verilated::gotFinish()) {
 
 
 
                if (main_time-saved_time >= 10 ) {
void traffic_clk_negedge_event(void){
                        reset = 0;
        int i;
 
        clk = 0;
 
        //for (i=0;i<NR;i++) router_is_active [i]=0;
 
        topology_connect_all_nodes ();
 
 
 
        for (i=0;i<NE;i++){
 
                if(inject_done) traffic[i]->stop=1;
 
        }
 
        connect_clk_reset_start_all();
 
        sim_eval_all();
                }
                }
 
 
                if(main_time == saved_time+21){ count_en=1; noc->start_i=1;}//for(i=0;i<NC;i++) traffic[i]->start=1;}
 
                if(main_time == saved_time+26) noc->start_i=0;// for(i=0;i<NC;i++) traffic[i]->start=0;
 
 
 
                        if ((main_time % 4) == 0) {
 
 
 
 
void traffic_clk_posedge_event(void) {
 
        int i;
 
        unsigned int dest_e_addr;
                        clk = 1;       // Toggle clock
                        clk = 1;       // Toggle clock
                        if(count_en) clk_counter++;
                        if(count_en) clk_counter++;
                        inject_done= ((total_pck_num >= MAX_PCK_NUM) || (clk_counter>= MAX_SIM_CLKs) || total_active_routers == 0);
        inject_done= ((total_sent_pck_num >= end_sim_pck_num) || (clk_counter>= sim_end_clk_num) || total_active_routers == 0);
                        //if(inject_done) printf("clk_counter=========%d\n",clk_counter);
                        //if(inject_done) printf("clk_counter=========%d\n",clk_counter);
 
        total_rsv_flit_number_old=total_rsv_flit_number;
                        for (i=0;i<NE;i++){
                        for (i=0;i<NE;i++){
 
 
                                // a packet has been received
                                // a packet has been received
                                if(traffic[i]->update & ~reset){
                if(traffic[i]->update & ~reset){
                                        update_noc_statistic (i) ;
                                        update_noc_statistic (i) ;
 
 
                                }
                                }
                                // the header flit has been sent out
                // the header flit has been sent out
                                if(traffic[i]->hdr_flit_sent ){
                if(traffic[i]->hdr_flit_sent ){
                                        traffic[i]->pck_class_in=  pck_class_in_gen( i);
                        traffic[i]->pck_class_in=  pck_class_in_gen( i);
                                        sent_core_total_pck_num[i]++;
                                        sent_core_total_pck_num[i]++;
 
                        traffic[i]->pck_size_in=get_new_pck_size();
                                        if(!FIXED_SRC_DST_PAIR){
                                        if(!FIXED_SRC_DST_PAIR){
                                                traffic[i]->pck_size_in=rnd_between(MIN_PACKET_SIZE,MAX_PACKET_SIZE);
 
                                                dest_e_addr=pck_dst_gen (i);
                                                dest_e_addr=pck_dst_gen (i);
                                                traffic[i]->dest_e_addr= dest_e_addr;
                                                traffic[i]->dest_e_addr= dest_e_addr;
 
                                if(dest_e_addr == INJECT_OFF) traffic[i]->stop=1;
                                                //printf("src=%u, dest=%x\n", i,endp_addr_decoder(dest_e_addr));
                                                //printf("src=%u, dest=%x\n", i,endp_addr_decoder(dest_e_addr));
 
 
                                        }
                                        }
                                }
                }
 
 
                                if(traffic[i]->flit_out_wr==1) flit_counter++;
                        if(traffic[i]->flit_out_wr==1){
 
                                total_sent_flit_number++;
 
                                #if (C>1)
 
                                        sent_stat [i][traffic[i]->flit_out_class].flit_num++;
 
                                #else
 
                                        sent_stat [i].flit_num++;
 
                                #endif
 
                        }
 
                        if(traffic[i]->flit_in_wr==1){
 
                                total_rsv_flit_number++;
 
                                #if (C>1)
 
                                        rsvd_stat [i][traffic[i]->pck_class_out].flit_num++;
 
                                #else
 
                                        rsvd_stat [i].flit_num++;
 
                                #endif
 
                        }
 
                        if(traffic[i]->hdr_flit_sent==1){
 
                                total_sent_pck_num++;
 
                                #if (C>1)
 
                                        sent_stat [i][traffic[i]->flit_out_class].pck_num++;
 
                                #else
 
                                        sent_stat [i].pck_num++;
 
                                #endif
 
                        }
 
 
                        }//for
                        }//for
 
 
 
 
                        if(inject_done) {
                        if(inject_done) {
                                for (i=0;i<NE;i++) if(traffic[i]->pck_number>0) total_router      =       total_router +1;
                                if(total_rsv_flit_number_old == total_rsv_flit_number){
 
                                                ideal_rsv_cnt++;
 
                                                if(ideal_rsv_cnt >= 100){
 
                                                        print_statistic( );
 
                                                        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);
 
                                                        exit(1);
 
                                                }
 
                                }
 
                                if(total_sent_flit_number == total_rsv_flit_number ) simulation_done=1;
 
                        }
 
        connect_clk_reset_start_all();
 
        sim_eval_all();
 
 
                                printf(" simulation clock cycles:%d\n",clk_counter);
 
                                printf(" total received flits:%d\n",flit_counter);
 
                                print_statistic(out_file_name);
 
                                change_injection_ratio = 1;
 
                                routers_final();
 
                                for(i=0;i<NE;i++) traffic[i]->final();
 
                                noc->final();
 
                                return 0;
 
                        }
                        }
                }//if
 
                else
 
                {
 
 
 
                        clk = 0;
 
#if (NR<=64)
 
                        noc->ni_flit_in_wr =0;
 
#else
 
                        for(j=0;j<(sizeof(noc->ni_flit_in_wr)/sizeof(noc->ni_flit_in_wr[0])); j++) noc->ni_flit_in_wr[j]=0;
 
#endif
 
 
 
                        connect_all_routers_to_noc ();
/**********************************
 
 *
 
 *      update_noc_statistic
 
 *
 
 *
 
 *********************************/
 
 
 
 
                        for (i=0;i<NE;i++){
 
                                traffic[i]->current_r_addr              = noc->er_addr[i];
 
 
 
 
void update_statistic_at_ejection (
 
        int     core_num,
 
        unsigned int    clk_num_h2h,
 
        unsigned int    clk_num_h2t,
 
        unsigned int    distance,
 
        unsigned int    class_num,
 
        unsigned int    src     ){
 
 
#if (Fpay<=32)
        total_rsv_pck_num+=1;
                                traffic[i]->flit_in  = noc->ni_flit_out [i];
 
#else   
 
        for(j=0;j<(sizeof(traffic[i]->flit_out)/sizeof(traffic[i]->flit_out[0])); j++) traffic[i]->flit_in[j]  = noc->ni_flit_out [i][j];
 
#endif                                  
 
                                traffic[i]->credit_in= noc->ni_credit_out[i];
 
 
 
 
        if( TRAFFIC_TYPE != NETRACE){
 
 
                                noc->ni_credit_in[i] = traffic[i]->credit_out;
        //old st
#if (Fpay<=32)                          
        if((total_rsv_pck_num & 0Xffff )==0 ) printf(" packet sent total=%d\n",total_rsv_pck_num);
                                noc->ni_flit_in [i]  = traffic[i]->flit_out;
        sum_clk_h2h+=clk_num_h2h;
#else   
        sum_clk_h2t+=clk_num_h2t;
        for(j=0;j<(sizeof(traffic[i]->flit_out)/sizeof(traffic[i]->flit_out[0])); j++) noc->ni_flit_in [i][j]  = traffic[i]->flit_out[j];
#if (STND_DEV_EN)
 
        sum_clk_pow2+=(double)clk_num_h2h * (double) clk_num_h2h;
 
        sum_clk_pow2_per_class[class_num]+=(double)clk_num_h2h * (double) clk_num_h2h;
#endif
#endif
 
        sum_clk_per_hop+= ((double)clk_num_h2h/(double)distance);
 
        //printf("sum_clk_per_hop(%f)+= clk_num_h2h(%u)/distance(%u)\n",sum_clk_per_hop,clk_num_h2h,distance);
 
        total_rsv_pck_num_per_class[class_num]+=1;
 
        sum_clk_h2h_per_class[class_num]+=clk_num_h2h ;
 
        sum_clk_h2t_per_class[class_num]+=clk_num_h2t ;
 
        sum_clk_per_hop_per_class[class_num]+= ((double)clk_num_h2h/(double)distance);
 
        rsvd_core_total_pck_num[core_num]=rsvd_core_total_pck_num[core_num]+1;
 
 
 
                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;
 
                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;
 
 
 
                if( traffic[core_num]->pck_size_o >= MIN_PACKET_SIZE && traffic[core_num]->pck_size_o <=MAX_PACKET_SIZE){
 
                  if(rsv_size_array!=NULL)      rsv_size_array[traffic[core_num]->pck_size_o-MIN_PACKET_SIZE]++;
 
                }
 
        }
 
    //new one TODO remove old st
 
 
 
        if(verbosity==0 &&  TRAFFIC_TYPE == NETRACE) if((total_rsv_pck_num & 0X1FFFF )==0 ) printf(" packet sent total=%d\n",total_rsv_pck_num);
 
    unsigned int latency = (strcmp (AVG_LATENCY_METRIC,"HEAD_2_TAIL")==0)? clk_num_h2t :  clk_num_h2h;
 
    #if(C>1)
 
 
 
        rsvd_stat[core_num][class_num].pck_num ++;
 
        rsvd_stat[core_num][class_num].sum_clk_h2h +=clk_num_h2h;
 
        rsvd_stat[core_num][class_num].sum_clk_h2t +=clk_num_h2t;
 
        rsvd_stat[core_num][class_num].sum_clk_per_hop+= ((double)clk_num_h2h/(double)distance);
 
        if (rsvd_stat[core_num][class_num].worst_latency < latency ) rsvd_stat[core_num][class_num].worst_latency =latency;
 
        if (rsvd_stat[core_num][class_num].min_latency==0          ) rsvd_stat[core_num][class_num].min_latency   =latency;
 
        if (rsvd_stat[core_num][class_num].min_latency   > latency ) rsvd_stat[core_num][class_num].min_latency   =latency;
 
        if (sent_stat[src     ][class_num].worst_latency < latency ) sent_stat[src     ][class_num].worst_latency =latency;
 
        if (sent_stat[src     ][class_num].min_latency==0          ) sent_stat[src     ][class_num].min_latency   =latency;
 
        if (sent_stat[src     ][class_num].min_latency   > latency ) sent_stat[src     ][class_num].min_latency   =latency;
 
 
#if (NE<=64)
                #if (STND_DEV_EN)
                                if(traffic[i]->flit_out_wr) noc->ni_flit_in_wr = noc->ni_flit_in_wr | ((vluint64_t)1<<i);
                rsvd_stat[core_num][class_num].sum_clk_pow2 += (double)clk_num_h2h * (double) clk_num_h2h;
                                traffic[i]->flit_in_wr= ((noc->ni_flit_out_wr >> i) & 0x01);
                #endif
#else
#else
                                if(traffic[i]->flit_out_wr) MY_VL_SETBIT_W(noc->ni_flit_in_wr ,i);
        rsvd_stat[core_num].pck_num ++;
                                traffic[i]->flit_in_wr=   (VL_BITISSET_W(noc->ni_flit_out_wr,i)>0);
        rsvd_stat[core_num].sum_clk_h2h +=(double)clk_num_h2h;
 
        rsvd_stat[core_num].sum_clk_h2t +=(double)clk_num_h2t;
 
        rsvd_stat[core_num].sum_clk_per_hop+= ((double)clk_num_h2h/(double)distance);
 
        if (rsvd_stat[core_num].worst_latency < latency ) rsvd_stat[core_num].worst_latency=latency;
 
        if (rsvd_stat[core_num].min_latency==0          ) rsvd_stat[core_num].min_latency  =latency;
 
        if (rsvd_stat[core_num].min_latency   > latency ) rsvd_stat[core_num].min_latency  =latency;
 
        if (sent_stat[src     ].worst_latency < latency ) sent_stat[src     ].worst_latency=latency;
 
        if (sent_stat[src     ].min_latency==0          ) sent_stat[src     ].min_latency  =latency;
 
        if (sent_stat[src     ].min_latency   > latency ) sent_stat[src     ].min_latency  =latency;
 
 
 
                #if (STND_DEV_EN)
 
                rsvd_stat[core_num].sum_clk_pow2 += (double)clk_num_h2h * (double) clk_num_h2h;
 
                #endif
#endif
#endif
 
 
                        }//for
 
                }//else
 
                //if(main_time > 20 && main_time < 30 ) traffic->start=1; else traffic->start=0;
 
                //if(main_time == saved_time+25) router1[0]->flit_in_we_all=0;
 
                //if((main_time % 250)==0) printf("router->all_done =%u\n",router->all_done);
 
 
 
 
 
                noc-> clk = clk;
 
                noc-> reset = reset;
 
 
 
                for(i=0;i<NE;i++)        {
 
#if (NE<=64)
}
                        traffic[i]->start=  ((noc->start_o >>i)&  0x01);
 
#else
void update_noc_statistic (     int     core_num){
                        traffic[i]->start=   (VL_BITISSET_W(noc->start_o, i)>0);
        unsigned int    clk_num_h2h =traffic[core_num]->time_stamp_h2h;
 
        unsigned int    clk_num_h2t =traffic[core_num]->time_stamp_h2t;
 
    unsigned int    distance=traffic[core_num]->distance;
 
    unsigned int        class_num=traffic[core_num]->pck_class_out;
 
    unsigned int    src_e_addr=traffic[core_num]->src_e_addr;
 
    unsigned int        src = endp_addr_decoder (src_e_addr);
 
 
 
    update_statistic_at_ejection ( core_num,    clk_num_h2h,  clk_num_h2t,  distance,   class_num,      src);
 
 
 
 
 
}
 
 
 
avg_st_t finilize_statistic (unsigned long int total_clk, statistic_t rsvd_stat){
 
 
 
         avg_st_t avg_statistic;
 
         avg_statistic.avg_throughput= ((double)(rsvd_stat.flit_num*100)/NE )/total_clk;
 
         avg_statistic.avg_latency_flit    = rsvd_stat.sum_clk_h2h/rsvd_stat.pck_num;
 
         avg_statistic.avg_latency_pck     = rsvd_stat.sum_clk_h2t/rsvd_stat.pck_num;
 
         avg_statistic.avg_latency_per_hop = ( rsvd_stat.pck_num==0)? 0 : rsvd_stat.sum_clk_per_hop/rsvd_stat.pck_num;
 
         avg_statistic.avg_pck_siz        = ( rsvd_stat.pck_num==0)? 0 : (double)(rsvd_stat.flit_num / rsvd_stat.pck_num);
 
         #if (STND_DEV_EN)
 
                 avg_statistic.std_dev =standard_dev( rsvd_stat.sum_clk_pow2,rsvd_stat.pck_num, avg_statistic.avg_latency_flit);
#endif                  
#endif                  
                        traffic[i]->reset= reset;
         return avg_statistic;
                        traffic[i]->clk = clk;
 
                }
                }
 
 
                connect_routers_reset_clk();
template<typename T>
 
        void myout(T value)
 
        {
 
           std::cout << value << std::endl;
 
        }
 
template<typename First, typename ... Rest>
 
        void myout(First first, Rest ... rest)
 
        {
 
           std::cout << first << ",";
 
           myout(rest...);
 
        }
 
 
                //evaluate
void print_st_single (unsigned long int total_clk, statistic_t rsvd_stat, statistic_t sent_stat){
                noc->eval();
 
                routers_eval();
 
                for(i=0;i<NE;i++) traffic[i]->eval();
 
 
 
                //router1[0]->eval();            // Evaluate model
 
                //printf("clk=%x\n",router->clk );
 
 
 
                main_time++;
 
                //getchar();   
 
 
 
 
        avg_st_t avg;
 
        avg=finilize_statistic (total_clk,  rsvd_stat);
 
 
 
        myout(
 
                        sent_stat.pck_num,
 
                        rsvd_stat.pck_num,
 
                        sent_stat.flit_num,
 
                        rsvd_stat.flit_num,
 
                        sent_stat.worst_latency,
 
                        rsvd_stat.worst_latency,
 
                        sent_stat.min_latency,
 
                        rsvd_stat.min_latency,
 
                        avg.avg_latency_per_hop,
 
                        avg.avg_latency_flit,
 
                        avg.avg_latency_pck,
 
                        avg.avg_throughput,
 
                        avg.avg_pck_siz,
 
                        #if (STND_DEV_EN)
 
                        avg.std_dev
 
                        #endif
 
        );
 
//      printf("\n");
 
 
 
}
 
 
        }// Done simulating
 
 
 
        routers_final();
void merge_statistic (statistic_t * merge_stat, statistic_t stat_in){
        for(i=0;i<NE;i++) traffic[i]->final();
        merge_stat->pck_num+=stat_in.pck_num;
        noc->final();
        merge_stat->flit_num+=stat_in.flit_num;
 
        if(merge_stat->worst_latency <  stat_in.worst_latency) merge_stat->worst_latency= stat_in.worst_latency;
 
        if(merge_stat->min_latency   == 0                       ) merge_stat->min_latency  = stat_in.min_latency;
 
        if(merge_stat->min_latency   > stat_in.min_latency  && stat_in.min_latency!=0   ) merge_stat->min_latency  = stat_in.min_latency;
 
        merge_stat->sum_clk_h2h      +=stat_in.sum_clk_h2h    ;
 
        merge_stat->sum_clk_h2t      +=stat_in.sum_clk_h2t    ;
 
        merge_stat->sum_clk_per_hop  +=stat_in.sum_clk_per_hop;
 
        #if (STND_DEV_EN)
 
                merge_stat->sum_clk_pow2 +=stat_in.sum_clk_pow2;
 
    #endif
 
 
}
}
 
 
 
void print_statistic_new (unsigned long int total_clk){
 
        int i;
 
        printf("\n\t#node,"
 
                        "sent_stat.pck_num,"
 
                        "rsvd_stat.pck_num,"
 
                        "sent_stat.flit_num,"
 
                        "rsvd_stat.flit_num,"
 
                        "sent_stat.worst_latency,"
 
                        "rsvd_stat.worst_latency,"
 
                        "sent_stat.min_latency,"
 
                        "rsvd_stat.min_latency,"
 
                        "avg_latency_per_hop,"
 
                        "avg_latency_flit,"
 
                        "avg_latency_pck,"
 
                        "avg_throughput(%%),"
 
                        "avg_pck_size,"
 
                        #if (STND_DEV_EN)
 
                        "avg.std_dev"
 
                        #endif
 
                        "\n");
 
 
 
 
 
 
/*************
#if(C>1)
 * sc_time_stamp
        int c;
 *
        statistic_t sent_stat_class [NE];
 * **********/
        statistic_t rsvd_stat_class [NE];
double sc_time_stamp () {       // Called by $time in Verilog
        statistic_t sent_stat_per_class [C];
        return main_time;
        statistic_t rsvd_stat_per_class [C];
}
 
 
 
int pow2( int num){
        memset (&rsvd_stat_class,0,sizeof(statistic_t)*NE);
        int pw;
        memset (&sent_stat_class,0,sizeof(statistic_t)*NE);
        pw= (0x1 << num);
        memset (&rsvd_stat_per_class,0,sizeof(statistic_t)*C);
        return pw;
        memset (&sent_stat_per_class,0,sizeof(statistic_t)*C);
 
 
 
 
 
        for (i=0; i<NE;i++){
 
                for (c=0; c<C;c++){
 
                        merge_statistic (&rsvd_stat_class[i],rsvd_stat[i][c]);
 
                        merge_statistic (&sent_stat_class[i],sent_stat[i][c]);
 
                        merge_statistic (&rsvd_stat_per_class[c],rsvd_stat[i][c]);
 
                        merge_statistic (&sent_stat_per_class[c],sent_stat[i][c]);
 
                }
}
}
 
 
 
 
 
 
/**********************************
 
 *
 
 *      update_noc_statistic
 
 *
 
 *
 
 *********************************/
 
 
 
void update_noc_statistic (     int     core_num){
#else
        unsigned int    clk_num_h2h =traffic[core_num]->time_stamp_h2h;
        #define sent_stat_class  sent_stat
        unsigned int    clk_num_h2t =traffic[core_num]->time_stamp_h2t;
        #define rsvd_stat_class  rsvd_stat
    unsigned int    distance=traffic[core_num]->distance;
 
    unsigned int        class_num=traffic[core_num]->pck_class_out;
 
    unsigned int    src_e_addr=traffic[core_num]->src_e_addr;
 
    unsigned int        src = endp_addr_decoder (src_e_addr);
 
        total_pck_num+=1;
 
        if((total_pck_num & 0Xffff )==0 ) printf(" packet sent total=%d\n",total_pck_num);
 
        sum_clk_h2h+=clk_num_h2h;
 
        sum_clk_h2t+=clk_num_h2t;
 
#if (STND_DEV_EN)
 
        sum_clk_pow2+=(double)clk_num_h2h * (double) clk_num_h2h;
 
        sum_clk_pow2_per_class[class_num]+=(double)clk_num_h2h * (double) clk_num_h2h;
 
#endif                                          
#endif                                          
        sum_clk_per_hop+= ((double)clk_num_h2h/(double)distance);
 
        total_pck_num_per_class[class_num]+=1;
 
        sum_clk_h2h_per_class[class_num]+=clk_num_h2h ;
 
        sum_clk_h2t_per_class[class_num]+=clk_num_h2t ;
 
        sum_clk_per_hop_per_class[class_num]+= ((double)clk_num_h2h/(double)distance);
 
        rsvd_core_total_pck_num[core_num]=rsvd_core_total_pck_num[core_num]+1;
        statistic_t rsvd_stat_total, sent_stat_total;
        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;
        memset (&rsvd_stat_total,0,sizeof(statistic_t));
    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;
        memset (&sent_stat_total,0,sizeof(statistic_t));
 
        for (i=0; i<NE;i++){
 
                merge_statistic (&rsvd_stat_total,rsvd_stat_class[i]);
 
                merge_statistic (&sent_stat_total,sent_stat_class[i]);
 
        }
 
        printf("\ttotal,");
 
        print_st_single (total_clk, rsvd_stat_total,sent_stat_total);
 
 
 
#if(C>1)
 
        for (c=0; c<C;c++){
 
                printf("\ttotal_class%u,",c);
 
                print_st_single (total_clk, rsvd_stat_per_class[c],sent_stat_per_class[c]);
 
        }
 
#endif
 
 
 
    for (i=0; i<NE;i++){
 
        printf("\t%u,",i);
 
        print_st_single (total_clk, rsvd_stat_class[i],sent_stat_class[i] );
 
    }
}
}
 
 
 
 
 
 
void print_statistic (char * out_file_name){
void print_statistic (void){
        double avg_latency_per_hop,  avg_latency_flit, avg_latency_pck, avg_throughput,min_avg_latency_per_class;
        double avg_latency_per_hop,  avg_latency_flit, avg_latency_pck, avg_throughput,min_avg_latency_per_class;
        int i;
        int i;
#if (STND_DEV_EN)
#if (STND_DEV_EN)
        double  std_dev;
        double  std_dev;
#endif
#endif
                                        char file_name[100];
 
                                        avg_throughput= ((double)(flit_counter*100)/total_router )/clk_counter;
        avg_throughput= ((double)(total_sent_flit_number*100)/total_active_endp )/clk_counter;
                                        printf(" Total active routers: %d \n",total_router);
        printf(" Total active Endpoint: %d \n",total_active_endp);
                                        printf(" Avg throughput is: %f (flits/clk/node %%)\n",    avg_throughput);
        printf(" Avg throughput is: %f (flits/clk/Total active Endpoint %%)\n",    avg_throughput);
                        avg_latency_flit   = (double)sum_clk_h2h/total_pck_num;
        avg_latency_flit   = (double)sum_clk_h2h/total_rsv_pck_num;
                        avg_latency_pck    = (double)sum_clk_h2t/total_pck_num;
        avg_latency_pck    = (double)sum_clk_h2t/total_rsv_pck_num;
                        if(ratio==RATIO_INIT) first_avg_latency_flit=avg_latency_flit;
                        if(ratio==RATIO_INIT) first_avg_latency_flit=avg_latency_flit;
#if (STND_DEV_EN)
#if (STND_DEV_EN)
                        std_dev= standard_dev( sum_clk_pow2,total_pck_num, avg_latency_flit);
        std_dev= standard_dev( sum_clk_pow2,total_rsv_pck_num, avg_latency_flit);
                        printf(" standard_dev = %f\n",std_dev);
                        printf(" standard_dev = %f\n",std_dev);
 
 
                       // sprintf(file_name,"%s_std.txt",out_file_name);
 
                        //update_file( file_name,avg_throughput,std_dev);
 
 
 
#endif
#endif
                        avg_latency_per_hop    = (double)sum_clk_per_hop/total_pck_num;
    avg_latency_per_hop    = (double)sum_clk_per_hop/total_rsv_pck_num;
                        printf   ("\nall : \n");
                        printf   ("\nall : \n");
                      //  sprintf(file_name,"%s_all.txt",out_file_name);
        printf(" Total number of packet = %d \n average latency per hop = %f \n",total_rsv_pck_num,avg_latency_per_hop);
                        //update_file(file_name ,ratio,avg_latency );
        printf(" average packet latency = %f \n average flit latency = %f \n",avg_latency_pck, avg_latency_flit);
if(strcmp (AVG_LATENCY_METRIC,"HEAD_2_TAIL")==0){
 
                        printf(" Total number of packet = %d \n average latency per hop = %f \n average latency = %f\n",total_pck_num,avg_latency_per_hop,avg_latency_pck);
 
                      // update_file(file_name ,avg_throughput,avg_latency_pck);
 
 
 
}else{
 
                         printf(" Total number of packet = %d \n average latency per hop = %f \n average latency = %f\n",total_pck_num,avg_latency_per_hop,avg_latency_flit);
 
                     //   update_file(file_name ,avg_throughput,avg_latency_flit);
 
 
 
}
 
                        //fwrite(fp,"%d,%f,%f,%f,",total_pck_num,avg_latency_per_hop,avg_latency,max_latency_per_hop);
 
                        min_avg_latency_per_class=1000000;
                        min_avg_latency_per_class=1000000;
                        for(i=0;i<C;i++){
    printf(" Total injected packet in different size:\n");
                                avg_throughput           = (total_pck_num_per_class[i]>0)? ((double)(total_pck_num_per_class[i]*PACKET_SIZE*100)/total_router )/clk_counter:0;
    for (i=0;i<=(MAX_PACKET_SIZE - MIN_PACKET_SIZE);i++){
                                                avg_latency_flit         = (total_pck_num_per_class[i]>0)? (double)sum_clk_h2h_per_class[i]/total_pck_num_per_class[i]:0;
        if(rsv_size_array[i]>0) printf("\t %u flit_sized pck = %u\n",i+ MIN_PACKET_SIZE, rsv_size_array[i]);
                                                avg_latency_pck          = (total_pck_num_per_class[i]>0)? (double)sum_clk_h2t_per_class[i]/total_pck_num_per_class[i]:0;
    }
                                                avg_latency_per_hop  = (total_pck_num_per_class[i]>0)? (double)sum_clk_per_hop_per_class[i]/total_pck_num_per_class[i]:0;
    printf("\n");
if(strcmp (AVG_LATENCY_METRIC,"HEAD_2_TAIL")==0){
 
                                                 printf  ("\nclass : %d  \n",i);
 
                            printf      (" Total number of packet  = %d \n avg_throughput = %f \n average latency per hop = %f \n average latency = %f\n",total_pck_num_per_class[i],avg_throughput,avg_latency_per_hop,avg_latency_pck);
 
                            //sprintf(file_name,"%s_c%u.txt",out_file_name,i);
 
                           // update_file( file_name,avg_throughput,avg_latency_pck );
 
}else{
 
 
 
 
    for(i=0;i<C;i++){
 
                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;
 
                        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;
 
                        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;
 
                        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;
printf   ("\nclass : %d  \n",i);
printf   ("\nclass : %d  \n",i);
                            printf      (" Total number of packet  = %d \n avg_throughput = %f \n average latency per hop = %f \n average latency = %f\n",total_pck_num_per_class[i],avg_throughput,avg_latency_per_hop,avg_latency_flit);
                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);
                           // sprintf(file_name,"%s_c%u.txt",out_file_name,i);
            printf (" average packet latency = %f \n average flit latency = %f \n",avg_latency_pck,avg_latency_flit);
                           // update_file( file_name,avg_throughput,avg_latency_flit );
 
 
 
 
 
}
 
                            if(min_avg_latency_per_class > avg_latency_flit) min_avg_latency_per_class=avg_latency_flit;
                            if(min_avg_latency_per_class > avg_latency_flit) min_avg_latency_per_class=avg_latency_flit;
 
 
#if (STND_DEV_EN)
#if (STND_DEV_EN)
                            std_dev= (total_pck_num_per_class[i]>0)?  standard_dev( sum_clk_pow2_per_class[i],total_pck_num_per_class[i], avg_latency_flit):0;
            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;
                           // sprintf(file_name,"%s_std%u.txt",out_file_name,i);
            printf(" standard_dev = %f\n",std_dev);
                           // update_file( file_name,avg_throughput,std_dev);
 
 
 
#endif
#endif
                         }//for
        }//for
                        current_avg_latency_flit=min_avg_latency_per_class;
                        current_avg_latency_flit=min_avg_latency_per_class;
 
 
        for (i=0;i<NE;i++) {
        for (i=0;i<NE;i++) {
                printf   ("\n\nCore %d\n",i);
                printf   ("\n\nEnd_point %d\n",i);
                        printf   ("\n\ttotal number of received packets: %u\n",rsvd_core_total_pck_num[i]);
                        printf   ("\n\ttotal number of received packets: %u\n",rsvd_core_total_pck_num[i]);
                        printf   ("\n\tworst-case-delay of received pckets (clks): %u\n",rsvd_core_worst_delay[i] );
                printf   ("\n\tworst-case-delay of received packets (clks): %u\n",rsvd_core_worst_delay[i] );
                        printf   ("\n\ttotal number of sent packets: %u\n",traffic[i]->pck_number);
                        printf   ("\n\ttotal number of sent packets: %u\n",traffic[i]->pck_number);
                        printf   ("\n\tworst-case-delay of sent pckets (clks): %u\n",sent_core_worst_delay[i] );
                printf   ("\n\tworst-case-delay of sent packets (clks): %u\n",sent_core_worst_delay[i] );
        }
        }
 
 
 
        print_statistic_new (clk_counter);
 
 
 
 
}
}
 
 
 
 
void print_parameter (){
void print_parameter (){
                printf ("Router parameters: \n");
                printf ("NoC parameters:---------------- \n");
                printf ("\tTopology: %s\n",TOPOLOGY);
                printf ("\tTopology: %s\n",TOPOLOGY);
                printf ("\tRouting algorithm: %s\n",ROUTE_NAME);
                printf ("\tRouting algorithm: %s\n",ROUTE_NAME);
                printf ("\tVC_per port: %d\n", V);
                printf ("\tVC_per port: %d\n", V);
                printf ("\tBuffer_width: %d\n", B);
                printf ("\tNon-local port buffer_width per VC: %d\n", B);
 
                printf ("\tLocal port buffer_width per VC: %d\n", LB);
if((strcmp (TOPOLOGY,"MESH")==0)||(strcmp (TOPOLOGY,"TORUS")==0)){
if((strcmp (TOPOLOGY,"MESH")==0)||(strcmp (TOPOLOGY,"TORUS")==0)){
            printf ("\tRouter num in row: %d \n",T1);
            printf ("\tRouter num in row: %d \n",T1);
            printf ("\tRouter num in column: %d \n",T2);
            printf ("\tRouter num in column: %d \n",T2);
 
            printf ("\tEndpoint num per router: %d\n",T3);
}else if ((strcmp (TOPOLOGY,"RING")==0)||(strcmp (TOPOLOGY,"LINE")==0)){
}else if ((strcmp (TOPOLOGY,"RING")==0)||(strcmp (TOPOLOGY,"LINE")==0)){
                printf ("\t Total Router num: %d \n",T1);
                printf ("\t Total Router num: %d \n",T1);
 
                printf ("\tEndpoint num per router: %d\n",T3);
}
}
else{
else if ((strcmp (TOPOLOGY,"TREE")==0)||(strcmp (TOPOLOGY,"FATTREE")==0)){
                printf ("\tK: %d \n",T1);
                printf ("\tK: %d \n",T1);
                printf ("\tL: %d \n",T2);
                printf ("\tL: %d \n",T2);
 
} else{ //CUSTOM
 
            printf ("\tTotal Endpoints number: %d \n",T1);
 
                printf ("\tTotal Routers number: %d \n",T2);
}
}
            printf ("\tNumber of Class: %d\n", C);
            printf ("\tNumber of Class: %d\n", C);
            printf ("\tFlit data width: %d \n", Fpay);
            printf ("\tFlit data width: %d \n", Fpay);
            printf ("\tVC reallocation mechanism: %s \n",  VC_REALLOCATION_TYPE);
            printf ("\tVC reallocation mechanism: %s \n",  VC_REALLOCATION_TYPE);
            printf ("\tVC/sw combination mechanism: %s \n", COMBINATION_TYPE);
            printf ("\tVC/sw combination mechanism: %s \n", COMBINATION_TYPE);
            printf ("\tAVC_ATOMIC_EN:%d \n", AVC_ATOMIC_EN);
            printf ("\tAVC_ATOMIC_EN:%d \n", AVC_ATOMIC_EN);
            printf ("\tCongestion Index:%d \n",CONGESTION_INDEX);
            printf ("\tCongestion Index:%d \n",CONGESTION_INDEX);
            printf ("\tADD_PIPREG_AFTER_CROSSBAR:%d\n",ADD_PIPREG_AFTER_CROSSBAR);
            printf ("\tADD_PIPREG_AFTER_CROSSBAR:%d\n",ADD_PIPREG_AFTER_CROSSBAR);
            printf ("\tSSA_EN enabled:%s \n",SSA_EN);
            printf ("\tSSA_EN enabled:%s \n",SSA_EN);
            printf ("\tSwitch allocator arbitration type:%s \n",SWA_ARBITER_TYPE);
            printf ("\tSwitch allocator arbitration type:%s \n",SWA_ARBITER_TYPE);
            printf ("\tMinimum supported packet size:%d flit(s) \n",MIN_PCK_SIZE);
            printf ("\tMinimum supported packet size:%d flit(s) \n",MIN_PCK_SIZE);
 
            printf ("\tLoop back is enabled:%s",SELF_LOOP_EN);
 
            printf ("\tNumber of multihop bypass (SMART max):%d \n",SMART_MAX);
        printf ("\nSimulation parameters\n");
        printf ("NoC parameters:---------------- \n");
 
        printf ("\nSimulation parameters-------------\n");
#if(DEBUG_EN)
#if(DEBUG_EN)
    printf ("\tDebuging is enabled\n");
    printf ("\tDebuging is enabled\n");
#else
#else
    printf ("\tDebuging is disabled\n");
    printf ("\tDebuging is disabled\n");
#endif
#endif
        if(strcmp (AVG_LATENCY_METRIC,"HEAD_2_TAIL")==0)printf ("\tOutput is the average latency on sending the packet header until receiving tail\n");
        //if(strcmp (AVG_LATENCY_METRIC,"HEAD_2_TAIL")==0)printf ("\tOutput is the average latency on sending the packet header until receiving tail\n");
        else printf ("\tOutput is the average latency on sending the packet header until receiving header flit at destination node\n");
        //else printf ("\tOutput is the average latency on sending the packet header until receiving header flit at destination node\n");
        printf ("\tTraffic pattern:%s\n",TRAFFIC);
        printf ("\tTraffic pattern:%s\n",TRAFFIC);
        if(C>0) printf ("\ttraffic percentage of class 0 is : %d\n", C0_p);
        size_t n = sizeof(class_percentage)/sizeof(class_percentage[0]);
        if(C>1) printf ("\ttraffic percentage of class 1 is : %d\n", C1_p);
        for(int p=0;p<n; p++){
        if(C>2) printf ("\ttraffic percentage of class 2 is : %d\n", C2_p);
                printf ("\ttraffic percentage of class %u is : %d\n",p,  class_percentage[p]);
        if(C>3) printf ("\ttraffic percentage of class 3 is : %d\n", C3_p);
        }
        if(strcmp (TRAFFIC,"HOTSPOT")==0){
        if(strcmp (TRAFFIC,"HOTSPOT")==0){
                //printf ("\tHot spot percentage: %u\n", HOTSPOT_PERCENTAGE);
                //printf ("\tHot spot percentage: %u\n", HOTSPOT_PERCENTAGE);
            printf ("\tNumber of hot spot cores: %d\n", HOTSPOT_NUM);
            printf ("\tNumber of hot spot cores: %d\n", HOTSPOT_NUM);
 
 
        }
        }
            //printf ("\tTotal packets sent by one router: %u\n", TOTAL_PKT_PER_ROUTER);
            //printf ("\tTotal packets sent by one router: %u\n", TOTAL_PKT_PER_ROUTER);
                printf ("\tSimulation timeout =%d\n", MAX_SIM_CLKs);
                if(sim_end_clk_num!=0) printf ("\tSimulation timeout =%d\n", sim_end_clk_num);
                printf ("\tSimulation ends on total packet num of =%d\n", MAX_PCK_NUM);
                if(end_sim_pck_num!=0) printf ("\tSimulation ends on total packet num of =%d\n", end_sim_pck_num);
            printf ("\tPacket size (min,max,average) in flits: (%u,%u,%u)\n",MIN_PACKET_SIZE,MAX_PACKET_SIZE,PACKET_SIZE);
                if(TRAFFIC_TYPE!=NETRACE){
 
                        printf ("\tPacket size (min,max,average) in flits: (%u,%u,%u)\n",MIN_PACKET_SIZE,MAX_PACKET_SIZE,AVG_PACKET_SIZE);
            printf ("\tPacket injector FIFO width in flit:%u \n",TIMSTMP_FIFO_NUM);
            printf ("\tPacket injector FIFO width in flit:%u \n",TIMSTMP_FIFO_NUM);
}
}
 
                if( TRAFFIC_TYPE == SYNTHETIC) printf("\tFlit injection ratio per router is =%f (flits/clk/Total Endpoint %%)\n",(float)ratio*100/MAX_RATIO);
 
                printf ("Simulation parameters-------------\n");
 
}
 
 
 
 
 
 
 
 
 
 
/************************
/************************
 *
 *
 *      reset system
 *      reset system
 *
 *
 *
 *
 * *******************/
 * *******************/
 
 
void reset_all_register (void){
void reset_all_register (void){
        int i;
        int i;
         total_router=0;
         total_active_endp=0;
         total_pck_num=0;
         total_rsv_pck_num=0;
 
         total_sent_pck_num=0;
         sum_clk_h2h=0;
         sum_clk_h2h=0;
         sum_clk_h2t=0;
         sum_clk_h2t=0;
 
         ideal_rsv_cnt=0;
#if (STND_DEV_EN)
#if (STND_DEV_EN)
         sum_clk_pow2=0;
         sum_clk_pow2=0;
#endif
#endif
 
 
         sum_clk_per_hop=0;
         sum_clk_per_hop=0;
         count_en=0;
         count_en=0;
         clk_counter=0;
         clk_counter=0;
 
 
         for(i=0;i<C;i++)
         for(i=0;i<C;i++)
         {
         {
                 total_pck_num_per_class[i]=0;
                 total_rsv_pck_num_per_class[i]=0;
             sum_clk_h2h_per_class[i]=0;
             sum_clk_h2h_per_class[i]=0;
             sum_clk_h2t_per_class[i]=0;
             sum_clk_h2t_per_class[i]=0;
                 sum_clk_per_hop_per_class[i]=0;
                 sum_clk_per_hop_per_class[i]=0;
#if (STND_DEV_EN)
#if (STND_DEV_EN)
                 sum_clk_pow2_per_class[i]=0;
                 sum_clk_pow2_per_class[i]=0;
#endif
#endif
 
 
         }  //for
         }  //for
         flit_counter=0;
         total_sent_flit_number=0;
 
 
 
 
}
}
 
 
 
 
 
 
 
 
/***********************
/***********************
 *
 *
 *      standard_dev
 *      standard_dev
 *
 *
 * ******************/
 * ******************/
 
 
#if (STND_DEV_EN)
#if (STND_DEV_EN)
/************************
/************************
 * std_dev = sqrt[(B-A^2/N)/N]  = sqrt [(B/N)- (A/N)^2] = sqrt [B/N - mean^2]
 * std_dev = sqrt[(B-A^2/N)/N]  = sqrt [(B/N)- (A/N)^2] = sqrt [B/N - mean^2]
 * A = sum of the values
 * A = sum of the values
 * B = sum of the squarded values
 * B = sum of the squarded values
 * *************/
 * *************/
 
 
double standard_dev( double sum_pow2, unsigned int  total_num, double average){
double standard_dev( double sum_pow2, unsigned int  total_num, double average){
        double std_dev;
        double std_dev;
 
 
        /*
        /*
        double  A, B, N;
        double  A, B, N;
        N= total_num;
        N= total_num;
        A= average * N;
        A= average * N;
        B= sum_pow2;
        B= sum_pow2;
 
 
        A=(A*A)/N;
        A=(A*A)/N;
        std_dev = (B-A)/N;
        std_dev = (B-A)/N;
        std_dev = sqrt(std_dev);
        std_dev = sqrt(std_dev);
*/
*/
 
        if(total_num==0) return 0;
 
 
        std_dev = sum_pow2/(double)total_num; //B/N
        std_dev = sum_pow2/(double)total_num; //B/N
        std_dev -= (average*average);// (B/N) - mean^2
        std_dev -= (average*average);// (B/N) - mean^2
        std_dev = sqroot(std_dev);// sqrt [B/N - mean^2]
        std_dev = sqroot(std_dev);// sqrt [B/N - mean^2]
 
 
        return std_dev;
        return std_dev;
 
 
}
}
 
 
#endif
#endif
 
 
 
 
 
 
/**********************
/**********************
 *
 *
 *      pck_class_in_gen
 *      pck_class_in_gen
 *
 *
 * *****************/
 * *****************/
 
 
unsigned char  pck_class_in_gen(
unsigned char  pck_class_in_gen(
         unsigned int  core_num
         unsigned int  core_num
 
 
) {
) {
        unsigned char pck_class_in;
        unsigned char pck_class_in;
        unsigned char  rnd=rand()%100;
        unsigned char  rnd=rand()%100;
        pck_class_in=     ( rnd <    C0_p               )?  0:
        int c=0;
                                  ( rnd <   (C0_p+C1_p) )?      1:
        int sum=class_percentage[0];
                                  ( rnd <   (C0_p+C1_p+C2_p))?2:3;
        size_t n = sizeof(class_percentage)/sizeof(class_percentage[0]);
    return pck_class_in;
        for(;;){
 
                if( rnd < sum) return c;
 
                if( c==n-1 ) return c;
 
                c++;
 
                sum+=class_percentage[c];
 
        }
 
        return 0;
}
}
 
 
 
 
 
 
 
 
void update_injct_var(unsigned int src,  unsigned int injct_var){
void update_injct_var(unsigned int src,  unsigned int injct_var){
        //printf("before%u=%u\n",src,random_var[src]);
        //printf("before%u=%u\n",src,random_var[src]);
        random_var[src]= rnd_between(100-injct_var, 100+injct_var);
        random_var[src]= rnd_between(100-injct_var, 100+injct_var);
        //printf("after=%u\n",random_var[src]);
        //printf("after=%u\n",random_var[src]);
}
}
 
 
unsigned int pck_dst_gen_task_graph ( unsigned int src){
unsigned int pck_dst_gen_task_graph ( unsigned int src){
         task_t  task;
         task_t  task;
        float f,v;
        float f,v;
 
 
        int index = task_graph_abstract[src].active_index;
        int index = task_graph_abstract[src].active_index;
 
 
        if(index == DISABLE){
        if(index == DISABLE){
                traffic[src]->ratio=0;
                traffic[src]->ratio=0;
                traffic[src]->stop=1;
                traffic[src]->stop=1;
                 return src; //disable sending
                 return INJECT_OFF; //disable sending
        }
        }
 
 
        if(     read(task_graph_data[src],index,&task)==0){
        if(     read(task_graph_data[src],index,&task)==0){
                traffic[src]->ratio=0;
                traffic[src]->ratio=0;
                traffic[src]->stop=1;
                traffic[src]->stop=1;
                 return src; //disable sending
                 return INJECT_OFF; //disable sending
 
 
        }
        }
 
 
        if(sent_core_total_pck_num[src] & 0xFF){//sent 255 packets
        if(sent_core_total_pck_num[src] & 0xFF){//sent 255 packets
                        //printf("uu=%u\n",task.jnjct_var);
                        //printf("uu=%u\n",task.jnjct_var);
                        update_injct_var(src, task.jnjct_var);
                        update_injct_var(src, task.jnjct_var);
 
 
                }
                }
 
 
        task_graph_total_pck_num++;
        task_graph_total_pck_num++;
        task.pck_sent = task.pck_sent +1;
        task.pck_sent = task.pck_sent +1;
        task.burst_sent= task.burst_sent+1;
        task.burst_sent= task.burst_sent+1;
        task.byte_sent = task.byte_sent + (task.avg_pck_size * (Fpay/8) );
        task.byte_sent = task.byte_sent + (task.avg_pck_size * (Fpay/8) );
 
 
        traffic[src]->pck_class_in=  pck_class_in_gen(src);
        traffic[src]->pck_class_in=  pck_class_in_gen(src);
        traffic[src]->avg_pck_size_in=task.avg_pck_size;
        //traffic[src]->avg_pck_size_in=task.avg_pck_size;
        traffic[src]->pck_size_in=rnd_between(task.min_pck_size,task.max_pck_size);
        traffic[src]->pck_size_in=rnd_between(task.min_pck_size,task.max_pck_size);
 
 
        f=  task.injection_rate;
        f=  task.injection_rate;
        v= random_var[src];
        v= random_var[src];
        f*= (v /100);
        f*= (v /100);
        if(f>100) f= 100;
        if(f>100) f= 100;
        f=  f * MAX_RATIO / 100;
        f=  f * MAX_RATIO / 100;
 
 
        traffic[src]->ratio=(unsigned int)f;
        traffic[src]->ratio=(unsigned int)f;
        traffic[src]->init_weight=task.initial_weight;
        traffic[src]->init_weight=task.initial_weight;
 
 
        if (task.burst_sent >= task.burst_size){
        if (task.burst_sent >= task.burst_size){
                task.burst_sent=0;
                task.burst_sent=0;
                task_graph_abstract[src].active_index=task_graph_abstract[src].active_index+1;
                task_graph_abstract[src].active_index=task_graph_abstract[src].active_index+1;
                if(task_graph_abstract[src].active_index>=task_graph_abstract[src].total_index) task_graph_abstract[src].active_index=0;
                if(task_graph_abstract[src].active_index>=task_graph_abstract[src].total_index) task_graph_abstract[src].active_index=0;
 
 
        }
        }
 
 
        update_by_index(task_graph_data[src],index,task);
        update_by_index(task_graph_data[src],index,task);
 
 
        if (task.byte_sent  >= task.bytes){ // This task is done remove it from the queue
        if (task.byte_sent  >= task.bytes){ // This task is done remove it from the queue
                                remove_by_index(&task_graph_data[src],index);
                                remove_by_index(&task_graph_data[src],index);
                                task_graph_abstract[src].total_index = task_graph_abstract[src].total_index-1;
                                task_graph_abstract[src].total_index = task_graph_abstract[src].total_index-1;
                                if(task_graph_abstract[src].total_index==0){ //all tasks are done turned off the core
                                if(task_graph_abstract[src].total_index==0){ //all tasks are done turned off the core
                                        task_graph_abstract[src].active_index=-1;
                                        task_graph_abstract[src].active_index=-1;
                                        traffic[src]->ratio=0;
                                        traffic[src]->ratio=0;
                                        traffic[src]->stop=1;
                                        traffic[src]->stop=1;
                                        if(total_active_routers!=0) total_active_routers--;
                                        if(total_active_routers!=0) total_active_routers--;
                                        return src;
                                        return INJECT_OFF;
                                }
                                }
                                if(task_graph_abstract[src].active_index>=task_graph_abstract[src].total_index) task_graph_abstract[src].active_index=0;
                                if(task_graph_abstract[src].active_index>=task_graph_abstract[src].total_index) task_graph_abstract[src].active_index=0;
        }
        }
 
 
        return task.dst;
        return endp_addr_encoder(task.dst);
}
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 

powered by: WebSVN 2.1.0

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