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/] [Integration_test/] [synthetic_sim/] [src/] [src.pl] - Blame information for rev 54

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

Line No. Rev Author Line
1 54 alirezamon
#!/usr/bin/perl -w
2
 
3
use Proc::Background;
4
use File::Path qw( rmtree );
5
 
6
my $script_path = dirname(__FILE__);
7
my $dirname = "$script_path/..";
8
my $root = "$dirname/../..";
9
 
10
my $rtl_dir = "$ENV{PRONOC_WORK}/verify/rtl";
11
my $work    = "$ENV{PRONOC_WORK}/verify/work";
12
my $src_verilator = "$root/src_verilator";
13
my $src_c = "$root/src_c";
14
my $src = "$script_path";
15
my $report = "$dirname/report";
16
 
17
require "$root/perl_gui/lib/perl/common.pl";
18
require "$root/perl_gui/lib/perl/topology.pl";
19
 
20
use strict;
21
use warnings;
22
 
23
my $pp;
24
        $pp= do "$src/deafult_noc_param";
25
        die "Error reading: $@" if $@;
26
 
27
        my $param = $pp->{'noc_param'};
28
        my %default_noc_param=%{$param};
29
        my @params=object_get_attribute_order($pp,'noc_param');
30
 
31
 
32
 
33
#read default param
34
 
35
 
36
sub recompile_synful {
37
 
38
#recmpile synful
39
my      $cmd ="cd $src_c/synfull/traffic-generator/src; make; wait;\n";
40
                #run command in terminal
41
                print "*******************compile synful******************\n$cmd\n";
42
                my $proc1 = Proc::Background->new($cmd);
43
                $proc1->alive;
44
                $proc1->wait;
45
                $proc1->die;
46
 
47
}
48
 
49
sub gen_noc_param_h{
50
        my $mpsoc=shift;
51
        my $param_h="\n\n//NoC parameters\n";
52
 
53
        my $topology = $mpsoc->object_get_attribute('noc_param','TOPOLOGY');
54
        $topology =~ s/"//g;
55
        $param_h.="\t#define  IS_${topology}\n";
56
 
57
        my ($NE, $NR, $RAw, $EAw, $Fw) = get_topology_info($mpsoc);
58
 
59
        my @params=$mpsoc->object_get_attribute_order('noc_param');
60
        my $custom_topology = $mpsoc->object_get_attribute('noc_param','CUSTOM_TOPOLOGY_NAME');
61
        foreach my $p (@params){
62
                my $val=$mpsoc->object_get_attribute('noc_param',$p);
63
                next if($p eq "CUSTOM_TOPOLOGY_NAME");
64
                $val=$custom_topology if($p eq "TOPOLOGY" && $val eq "\"CUSTOM\"");
65
                if($p eq "MCAST_ENDP_LIST" || $p eq "ESCAP_VC_MASK"){
66
                        $val="$NE".$val if($p eq 'MCAST_ENDP_LIST');
67
                        $val =~ s/\'/\\\'/g;
68
                        $val="\"$val\"";
69
                }
70
                $param_h=$param_h."\t#define $p\t$val\n";
71
 
72
                #print "$p:$val\n";
73
 
74
        }
75
 
76
 
77
        my $v=$mpsoc->object_get_attribute('noc_param',"V")-1;
78
        my $escape=$mpsoc->object_get_attribute('noc_param',"ESCAP_VC_MASK");
79
        if (! defined $escape){
80
                #add_text_to_string (\$param_h,"\tlocalparam [$v        :0] ESCAP_VC_MASK=1;\n");
81
                #add_text_to_string (\$pass_param,".ESCAP_VC_MASK(ESCAP_VC_MASK),\n"); 
82
        }
83
        #add_text_to_string (\$param_h," \tlocalparam  CVw=(C==0)? V : C * V;\n");
84
        #add_text_to_string (\$pass_param,".CVw(CVw)\n");
85
 
86
        #remove 'b and 'h
87
        #$param_h =~ s/\d\'b/ /g;
88
        #$param_h =~ s/\'h/ /g;
89
 
90
 
91
        return  $param_h;
92
}
93
 
94
 
95
sub gen_sim_parameter_h {
96
        my ($param_h,$includ_h,$ne,$nr,$router_p,$fifow)=@_;
97
 
98
        $param_h =~ s/\d\'b/ /g;
99
        my $text=  "
100
#ifndef     INCLUDE_PARAM
101
        #define   INCLUDE_PARAM \n \n
102
 
103
        $param_h
104
 
105
        #define NE  $ne
106
        #define NR  $nr
107
        #define ROUTER_P_NUM $router_p
108
 
109
        extern Vtraffic         *traffic[NE];
110
        extern Vpck_inj     *pck_inj[NE];
111
        extern int reset,clk;
112
 
113
        //simulation parameter
114
        #define MAX_RATIO   1000
115
        #define AVG_LATENCY_METRIC \"HEAD_2_TAIL\"
116
        #define TIMSTMP_FIFO_NUM   $fifow
117
 
118
        $includ_h
119
\n \n \#endif" ;
120
        return $text;
121
}
122
 
123
 
124
sub extract_and_update_noc_sim_statistic {
125
        my ($stdout)=@_;
126
        my $avg_latency =capture_number_after("average packet latency =",$stdout);
127
        my $avg_flit_latency =capture_number_after("average flit latency =",$stdout);
128
        my $sd_latency =capture_number_after("standard_dev =",$stdout);
129
        my $avg_thput =capture_number_after("Avg throughput is:",$stdout);
130
        my $total_time =capture_number_after("simulation clock cycles:",$stdout);
131
        my $latency_perhop = capture_number_after("average latency per hop =",$stdout);
132
        my %packet_rsvd_per_core = capture_cores_data("total number of received packets:",$stdout);
133
        my %worst_rsvd_delay_per_core = capture_cores_data('worst-case-delay of received packets \(clks\):',$stdout);
134
        my %packet_sent_per_core = capture_cores_data("total number of sent packets:",$stdout);
135
        my %worst_sent_delay_per_core = capture_cores_data('worst-case-delay of sent packets \(clks\):',$stdout);
136
 
137
 
138
}
139
 
140
sub get_model_parameter {
141
        my $model =shift;
142
        my $o;
143
        $o= do $model;
144
        my %new_param=%{$o};
145
    die "Error reading: $@" if $@;
146
        my %temp;
147
        foreach my $p (@params){
148
                $temp{$p} = $default_noc_param{$p};
149
        }
150
        foreach my $p (sort keys %new_param){
151
                $temp{$p} = $new_param{$p};
152
        }
153
        return %temp;
154
}
155
 
156
sub gen_noc_localparam_v {
157
        my ($m,$ref) = @_;
158
        my %model = %{$ref};
159
        my %temp;
160
 
161
 
162
        foreach my $p (@params){
163
                $temp{$p} = $default_noc_param{$p};
164
        $m->{noc_param}{$p}=$default_noc_param{$p};
165
        }
166
        foreach my $p (sort keys %model){
167
                $temp{$p} = $model{$p};
168
                $m->{noc_param}{$p}=$model{$p};
169
        }
170
 
171
        object_add_attribute_order($m,'noc_param',@params);
172
 
173
        my $param_v="`ifdef NOC_LOCAL_PARAM \n";
174
        foreach my $p (@params){
175
                $param_v.="localparam $p = $temp{$p};\n";
176
        }
177
        $param_v.="`endif\n";
178
 
179
        my ($nr,$ne,$router_p,$ref_tops,$includ_h) = get_noc_verilator_top_modules_info($m);
180
        my %tops = %{$ref_tops};
181
        $tops{Vtraffic} = "--top-module traffic_gen_top";
182
        $tops{Vpck_inj} = "--top-module packet_injector_verilator";
183
 
184
 
185
 
186
 
187
        my $param_h=gen_noc_param_h($m);
188
        $includ_h = gen_sim_parameter_h($param_h,$includ_h,$ne,$nr,$router_p,'16');
189
 
190
        return ($param_v,$includ_h,\%tops);
191
 
192
}
193
 
194
 
195
sub copy_src_files{
196
 
197
        if(defined $ENV{PRONOC_WORK}){
198
                rmtree("$rtl_dir");
199
                unless (-d "$rtl_dir"){
200
                        print "make a working directory inside $rtl_dir\n";
201
                        mkdir("$rtl_dir", 0700);
202
 
203
                }
204
        }else{
205
                        print  "Please set PRONOC_WORK variable first!";
206
                        exit;
207
        }
208
 
209
        dircopy("$root/rtl/src_noc"    , "$rtl_dir/src_noc"    ) or die("$!\n") unless (-d "$rtl_dir/src_noc"    );
210
    dircopy("$root/rtl/src_topolgy", "$rtl_dir/src_topolgy") or die("$!\n") unless (-d "$rtl_dir/src_topolgy");
211
 
212
    unlink "$rtl_dir/src_noc/noc_localparam.v";
213
    for my $file (glob "$root/rtl/*.v") {
214
                 copy $file, "$rtl_dir" or die $! ;
215
        }
216
 
217
 
218
 
219
}
220
 
221
 
222
 
223
 
224
sub gen_file_list{
225
        my $path=shift;
226
        my $f="+incdir+$rtl_dir/
227
+incdir+$rtl_dir/src_noc/
228
+incdir+$path
229
";
230
 
231
        my @files = File::Find::Rule->file()
232
                          ->name( '*.v','*.V','*.sv' )
233
                          ->in( "$rtl_dir" );
234
 
235
        #make sure source files have key word 'module' 
236
        my @sources;
237
        foreach my $p (@files){
238
                push (@sources,$p)      if(check_file_has_string($p,'endpackage'));
239
        }
240
        foreach my $p (@files){
241
                push (@sources,$p)      if(check_file_has_string($p,'module'));
242
        }
243
        my $files = join ("\n",@sources);
244
        $f.=$files;
245
 
246
 
247
        open(FILE,  ">$path/file_list.f") || die "Can not open: $!";
248
        print FILE $f;
249
        close FILE;
250
}
251
 
252
sub gen_verilator_sh{
253
        my ($ref,$file)=@_;
254
        my %tops = %{$ref};
255
        my $make_lib="";
256
    my $jobs=0;
257
        my $cmd= '#!/bin/bash
258
        SCRPT_FULL_PATH=$(realpath ${BASH_SOURCE[0]})
259
        SCRPT_DIR_PATH=$(dirname $SCRPT_FULL_PATH)
260
 
261
        cmn="-O3  -CFLAGS -O3"
262
        currentver=$(verilator --version | head -n1 | cut -d" " -f2)
263
        requiredver="4.0.0"
264
        if [ "$(printf \'%s\n\' "$requiredver" "$currentver" | sort -V | head -n1)" = "$requiredver" ]; then
265
        echo "Verilator vesrion Greater than or equal to ${requiredver}, compile with -Wno-TIMESCALEMOD flag"
266
                cmn=" $cmn -Wno-TIMESCALEMOD";
267
        else
268
        echo "Verilator vesrion is Less than ${requiredver}"
269
        fi
270
';
271
 
272
        foreach my $top (sort keys %tops) {
273
                $cmd.= "verilator  -f \$SCRPT_DIR_PATH/file_list.f --cc $tops{$top}  --prefix \"$top\" \$cmn & \n";
274
        }
275
        $cmd.="wait\n";
276
        foreach my $top (sort keys %tops) {
277
 
278
                $cmd.="
279
        if ! [ -f \$SCRPT_DIR_PATH/obj_dir/$top.cpp ]; then
280
                echo  \"Failed to generate: \$SCRPT_DIR_PATH/obj_dir/$top.cpp \"
281
                exit 1
282
        fi\n";
283
                $make_lib.="make lib$jobs &\n";
284
                $jobs++;
285
        }
286
 
287
 
288
        $cmd.="
289
cd \$SCRPT_DIR_PATH/obj_dir/
290
$make_lib
291
wait
292
 
293
make sim
294
";
295
        save_file("$file",$cmd);
296
 
297
}
298
 
299
sub get_model_names {
300
        my ($mref,$inref) = @_;
301
        my @models = @{$mref};
302
        my ($paralel_run,$MIN,$MAX,$STEP,$model_dir)=@{$inref};
303
        my $full_path;
304
        $full_path = "$model_dir" if (-d "$model_dir");
305
        $full_path = "$dirname/$model_dir" if (-d "$dirname/$model_dir");
306
        if (!defined  $full_path){
307
                 die "Error the model directory  $model_dir or $dirname/$model_dir is not found\n";
308
        }
309
        my @m;
310
        if(scalar @models == 0){
311
                @m = glob("$full_path/*");
312
                return @m;
313
        }
314
        foreach my $p (@models) {
315
                push (@m,"$full_path/$p");
316
        }
317
        return @m;
318
}
319
 
320
 
321
sub gen_models {
322
        my ($mref, $inref) = @_;
323
        my @models = get_model_names(@_);
324
 
325
 
326
    mkdir("$work", 0700);
327
        foreach my $m (@models){
328
                print "$m\n";
329
                #make noc localparam
330
                my $o;
331
                $o= do $m;
332
        die "Error reading: $@" if $@;
333
                my $param = $o->{'noc_param'};
334
                my ($fname,$fpath,$fsuffix) = fileparse("$m",qr"\..[^.]*$");
335
 
336
 
337
                my $name = $fname;
338
                my $make =$o->{'makefile'};
339
 
340
 
341
                my      ($param_v,$include_h,$tops)=   gen_noc_localparam_v( $o,$param);
342
 
343
                mkdir("$work/$name", 0700);
344
                rmtree("$work/$name/obj_dir");
345
        mkdir("$work/$name/obj_dir", 0700);
346
                save_file("$work/$name/noc_localparam.v",$param_v);
347
 
348
                #generate file list             
349
                gen_file_list("$work/$name");
350
                gen_verilator_sh($tops,"$work/$name/verilator.sh");
351
 
352
 
353
 
354
                #copy C files
355
                my @files = File::Find::Rule->file()
356
                          ->name( '*.h' )
357
                          ->in( "$src_verilator" );
358
                foreach my $p (@files){
359
                        copy $p, "$work/$name/obj_dir/";
360
                }
361
                copy "$src_verilator/simulator.cpp", "$work/$name/obj_dir/testbench.cpp";
362
 
363
                #copy nettrace & synful
364
            dircopy("$src_c/netrace-1.0","$work/$name/obj_dir/netrace-1.0");
365
            dircopy("$src_c/synfull","$work/$name/obj_dir/synful");
366
 
367
 
368
 
369
 
370
                #generate make file
371
                gen_verilator_makefile($tops,"$work/$name/obj_dir/Makefile");
372
                #generate param.h file
373
 
374
 
375
                save_file("$work/$name/obj_dir/parameter.h",$include_h);
376
 
377
 
378
        }
379
 
380
}
381
 
382
 
383
 
384
 
385
 
386
 
387
sub compile_models{
388
        my($self,$inref,$mref)=@_;
389
    my ($paralel_run,$MIN,$MAX,$STEP) = @{$inref};
390
 
391
 
392
        my @models = get_model_names($mref,$inref);
393
 
394
        #generate compile command
395
        my $i=0;
396
        my $cmd;
397
        foreach my $m (@models){
398
                my ($fname,$fpath,$fsuffix) = fileparse("$m",qr"\..[^.]*$");
399
                $cmd.=" cd $work/$fname;  bash verilator.sh >  $work/$fname/out.log 2>&1  &\n";
400
                $i++;
401
                $cmd.="wait\n" if(($i % $paralel_run)==0) ;
402
        }
403
        $cmd.="wait\n" if(($i % $paralel_run)!=0) ;
404
        #run command in terminal
405
        print "*******************compile models******************\n$cmd\n";
406
        my $proc1 = Proc::Background->new($cmd);
407
        $proc1->alive;
408
        $proc1->wait;
409
        $proc1->die;
410
 
411
}
412
sub check_compilation_log {
413
        my ($name,$ref,$inref) = @_;
414
    my @log_report_match =@{$ref};
415
        my ($paralel_run,$MIN,$MAX,$STEP) = @{$inref};
416
        my $logfile     = "$work/$name/out.log";
417
 
418
        my @found;
419
        foreach my $m (@log_report_match){
420
                open my $INPUT, '<', $logfile;
421
                push(@found , grep ( /$m/, <$INPUT>)) ;
422
                close($INPUT);
423
        }
424
 
425
        foreach my $line (@found) {
426
              append_text_to_file($report,"\t $line\n");
427
    }
428
}
429
 
430
 
431
 
432
 
433
 
434
sub check_compilation {
435
        my ($self,$ref1,$inref,$mref)=@_;
436
 
437
        my @models = get_model_names($mref,$inref);
438
 
439
        foreach my $m (@models){
440
                my ($name,$fpath,$fsuffix) = fileparse("$m",qr"\..[^.]*$");
441
                append_text_to_file($report,"****************************$name : Compile *******************************:\n");
442
                #check if testbench is generated successfully   
443
                if(-f "$work/$name/obj_dir/testbench"){
444
                        append_text_to_file($report,"\t model is generated successfully.\n");
445
                        check_compilation_log($name,$ref1,$inref);
446
 
447
                }else{
448
                        append_text_to_file($report,"\t model generation is FAILED.\n");
449
                        check_compilation_log($name,$ref1,$inref);
450
                }
451
 
452
        }
453
}
454
 
455
 
456
sub run_all_models {
457
        my ($self,$inref,$mref) =@_;
458
    my ($paralel_run,$MIN,$MAX,$STEP) = @{$inref};
459
        my @models = get_model_names($mref,$inref);
460
    foreach my $m (@models){
461
                run_traffic ($self,$m,'random',$inref);
462
        }
463
        foreach my $m (@models){
464
                run_traffic ($self,$m,'transposed 1',$inref);
465
        }
466
}
467
 
468
 
469
 
470
sub run_traffic {
471
        my ($self,$model,$traffic,$inref)=@_;
472
     my ($paralel_run,$MIN,$MAX,$STEP) = @{$inref};
473
        my ($name,$fpath,$fsuffix) = fileparse("$model",qr"\..[^.]*$");
474
 
475
        my %param = get_model_parameter($model);
476
        my $min_pck = $param{'MIN_PCK_SIZE'};
477
 
478
    append_text_to_file($report,"****************************$name      : $traffic traffic *******************************:\n");
479
        unless (-f "$work/$name/obj_dir/testbench"){
480
                append_text_to_file($report,"\t failed. Simulation model is not avaialable\n");
481
                return;
482
        }
483
 
484
 
485
 
486
        my $file_name="${traffic}_results";
487
    $file_name =~ s/\s+//g;
488
 
489
        mkdir("$work/$name/$file_name/", 0700);
490
 
491
        my $i=0;
492
        my $cmd;
493
 
494
 
495
        for (my $inject=$MIN; $inject<=$MAX; $inject+=$STEP){
496
                $cmd.="$work/$name/obj_dir/testbench -t \"$traffic\"   -m \"R,$min_pck,10\"  -n  20000  -c      10000   -i $inject -p \"100,0,0,0,0\" >  $work/$name/$file_name/sim$inject 2>&1  &\n";
497
                $i++;
498
                $cmd.="wait\n" if(($i % $paralel_run)==0) ;
499
        }
500
        $cmd.="wait\n" if(($i % $paralel_run)!=0) ;
501
        #run command in terminal
502
        print "*******************run models******************\n$cmd\n";
503
        my $proc1 = Proc::Background->new($cmd);
504
        $proc1->alive;
505
        $proc1->wait;
506
        $proc1->die;
507
 
508
        check_sim_results($self,$name,$traffic,$inref);
509
 
510
}
511
 
512
 
513
sub extract_result {
514
        my ($self,$file,$filed)=@_;
515
 
516
        my @r = unix_grep($file,$filed);
517
    my $string = $r[0];
518
    $string =~ s/[^0-9.]+//g;
519
        return $string;
520
 
521
}
522
 
523
sub get_zero_load_and_saturation{
524
        my ($self,$name,$traffic,$path)=@_;
525
        my %results;
526
        my $ref = $self->{'name'}{"$name"}{'traffic'}{$traffic}{"packet_latency"};
527
        return if !defined $ref;
528
        %results = %{$ref};
529
 
530
        my $zero_latency=9999999;
531
    my $saturat_inject=100;
532
    my $zero_inject;
533
    my $saturat_latency='-';
534
 
535
        my $txt = "#name:$name\n";
536
 
537
        foreach my $inj (sort {$a <=> $b} keys %results){
538
                $txt.="$inj $results{$inj}\n";
539
                if ($zero_latency > $results{$inj}) {
540
                        $zero_latency = $results{$inj};
541
                        $zero_inject  = $inj;
542
                }
543
        }
544
        # assum saturation happens when the latency is 5 times of zero load
545
        foreach my $inj (sort {$a <=> $b} keys %results){
546
                if($results{$inj} >= 5 * $zero_latency ) {
547
                        if($saturat_inject > $inj){
548
                                $saturat_inject =$inj;
549
                                $saturat_latency=$results{$inj};
550
                        }
551
                }
552
        }
553
        $txt.="\n";
554
        save_file("$path/packet_latency.sv",$txt);
555
 
556
 
557
        return ($zero_inject,$zero_latency, $saturat_inject,$saturat_latency);
558
}
559
 
560
 
561
 
562
 
563
sub check_sim_results{
564
        my ($self,$name,$traffic,$inref)=@_;
565
    my ($paralel_run,$MIN,$MAX,$STEP) = @{$inref};
566
    my $file_name="${traffic}_results";
567
    $file_name =~ s/\s+//g;
568
        my $results_path = "$work/$name/$file_name";
569
 
570
        #my @results = glob("$results_path/*");
571
        #check for error
572
 
573
        for (my $inject=$MIN; $inject<=$MAX; $inject+=$STEP){
574
                my $file = "$results_path/sim$inject";
575
 
576
                my @errors = unix_grep("$file","ERROR:");
577
                if (scalar @errors  ){
578
                        append_text_to_file($report,"\t Error in running simulation: @errors \n");
579
                        $self->{'name'}{"$name"}{'traffic'}{$traffic}{'overal_result'}="Failed";
580
                        $self->{'name'}{"$name"}{'traffic'}{$traffic}{'message'}="@errors";
581
                        return;
582
                }
583
                my @r = unix_grep($file,"\ttotal,");
584
        my $string = $r[0];
585
                my @fileds=split(',',$string);
586
                my $val=$fileds[11];
587
                $val =~ s/[^0-9.]+//g;
588
        #       my $val = extract_result($self,$file,"average packet latency");         
589
                if(length $val ==0){
590
                        $self->{'name'}{"$name"}{'traffic'}{$traffic}{'overal_result'}="Failed";
591
                        $self->{'name'}{"$name"}{'traffic'}{$traffic}{'message'}="The average packet latency is undefined for $inject";
592
                        return;
593
                }
594
                $self->{'name'}{"$name"}{'traffic'}{$traffic}{"packet_latency"}{$inject}="$val";
595
 
596
        }
597
        my  ($z,$zl, $s,$sl) = get_zero_load_and_saturation ($self,$name,$traffic,$results_path);
598
        print "($z,$zl, $s,$sl)\n";
599
 
600
        #save results in a text file 
601
 
602
 
603
 
604
        append_text_to_file($report,"\t Passed:   zero load ($z,$zl) saturation ($s,$sl)\n");
605
    $self->{'name'}{"$name"}{'traffic'}{$traffic}{'overal_result'}="passed";
606
}
607
 

powered by: WebSVN 2.1.0

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