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/] [smart-netrace/] [src/] [src.pl] - Blame information for rev 48

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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