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/] [perl_gui/] [lib/] [perl/] [emulate_ram_gen.pl] - Blame information for rev 30

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

Line No. Rev Author Line
1 25 alirezamon
#!/usr/bin/perl -w
2
use strict;
3
use warnings;
4
use List::Util 'shuffle';
5 28 alirezamon
require "widget.pl";
6 25 alirezamon
 
7
 
8 30 alirezamon
use constant SIM_RAM_GEN        => 0;
9 28 alirezamon
 
10
use constant JTAG_RAM_INDEX     => 128;
11
use constant JTAG_DONE_RESET_INDEX      => 127;
12
use constant RESET_NOC          => " $ENV{'PRONOC_WORK'}/toolchain/bin/jtag_main -n ".JTAG_DONE_RESET_INDEX." -d \"I:1,D:2:1,I:0\" ";
13
use constant UNRESET_NOC        => " $ENV{'PRONOC_WORK'}/toolchain/bin/jtag_main -n ".JTAG_DONE_RESET_INDEX." -d \"I:1,D:2:0,I:0\" ";
14
 
15
use constant READ_DONE_CMD      => " $ENV{'PRONOC_WORK'}/toolchain/bin/jtag_main -n ".JTAG_DONE_RESET_INDEX." -d \"I:2,R:2:0,I:0\" ";
16
 
17
use constant UPDATE_WB_ADDR     => 0x7;
18 25 alirezamon
use constant UPDATE_WB_WR_DATA  => 0x6;
19
use constant UPDATE_WB_RD_DATA  => 0x5;
20
use constant RD_WR_STATUS       => 0x4;
21
use constant PROBE_ST           => 0x2;
22
use constant SOURCE_ST          => 0x1;
23
use constant BYPAS_ST           => 0x0;
24 28 alirezamon
use constant RAM_BIN_FILE       => "$ENV{'PRONOC_WORK'}/emulate/emulate_ram.bin";
25
use constant RAM_SIM_FILE       => "$ENV{'PRONOC_WORK'}/emulate/ram";
26
 
27 25 alirezamon
 
28
 
29
 
30
 
31 28 alirezamon
sub reset_cmd {
32
        my ($ctrl_reset, $noc_reset)=@_;
33
        my $reset_vector= (($ctrl_reset & 0x1) << 1) +  ($noc_reset & 0x1);
34
        my $cmd = " $ENV{'PRONOC_WORK'}/toolchain/bin/jtag_main -n ".JTAG_DONE_RESET_INDEX." -d \"I:1,D:2:$reset_vector,I:0\" ";
35
        #print "$cmd\n";
36
        return  $cmd;
37 25 alirezamon
 
38 28 alirezamon
}
39 25 alirezamon
 
40
 
41
 
42
 
43 28 alirezamon
sub help {
44
                print
45
"       usage: ./ram_gen X  Y TRAFFIC
46
                X:  number of node in X direction 2<x<=16
47
                Y:  number of node in Y direction 2<y<=16
48
                TRAFFIC : select one of the following traffic patterns :
49
                        tornado,
50
                        transposed 1,
51
                        transposed 2,
52
                        random,
53
 
54
";
55 25 alirezamon
 
56 28 alirezamon
}
57 25 alirezamon
 
58 28 alirezamon
 
59
 
60
 
61
 
62
 
63
sub random_dest_gen {
64
        my $n=shift;
65
        my @c=(0..$n-1);
66
        my @o;
67
        for (my $i=0; $i<$n; $i++){
68
                my @l= shuffle @c;
69
                @l=remove_scolar_from_array(\@l,$i);
70
                $o[$i]=\@l;
71
 
72
        }
73
        return \@o;
74
 
75
}
76
 
77
sub run_cmd_update_info {
78
        my ($cmd,$info)=@_;
79
        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
80
                if($exit){
81
                        add_info($info, "$stdout\n") if(defined $stdout);
82
                        add_info($info, "$stderr\n") if(defined $stderr);
83
 
84
                }
85
        #print  "\n$cmd \n $stdout";
86
        return $exit;
87
}
88
 
89
 
90
sub synthetic_destination{
91
        my($traffic,$x,$y,$xn,$yn,$line_num,$rnd)=@_;
92
        my $dest_x;
93
        my $dest_y;
94
        my $xw          =   log2($xn);
95
        my $yw          =   log2($yn);
96
 
97 25 alirezamon
        if( $traffic eq "transposed 1"){
98 28 alirezamon
                 $dest_x= $xn-$y-1;
99
                 $dest_y= $yn-$x-1;
100 25 alirezamon
 
101
        } elsif( $traffic eq "transposed 2"){
102
 
103 28 alirezamon
                $dest_x  = $y;
104
                $dest_y  = $x;
105 25 alirezamon
        } elsif( $traffic eq "bit reverse"){
106
                my $joint_addr= ($x << log2($xn))+$y;
107
                my $reverse_addr=0;
108
                my $pos=0;
109
                for(my $i=0; $i<($xw+$yw); $i++){#reverse the address
110
                         $pos= ((($xw+$yw)-1)-$i);
111
                         $reverse_addr|= (($joint_addr >> $pos) & 0x01) << $i;
112
                   # reverse_addr[i]  = joint_addr [((Xw+Yw)-1)-i];
113
                }
114 28 alirezamon
                $dest_x  = $reverse_addr>>$yw;
115
                $dest_y  = $reverse_addr&(0xFF>> (8-$yw));
116 25 alirezamon
         } elsif( $traffic  eq "bit complement") {
117
 
118 28 alirezamon
                 $dest_x   = (~$x) &(0xFF>> (8-$xw));
119
                 $dest_y   = (~$y) &(0xFF>> (8-$yw));
120 25 alirezamon
 
121
 
122 28 alirezamon
        }elsif( $traffic eq "tornado") {
123 25 alirezamon
 
124
                #[(x+(k/2-1)) mod k, (y+(k/2-1)) mod k],
125 28 alirezamon
                 $dest_x   = (($x + (($xn/2)-1))%$xn);
126
                 $dest_y   = (($y + (($yn/2)-1))%$yn);
127
        }elsif( $traffic eq "random") {
128 25 alirezamon
                 #my $num=($y * $xn) +  $x;
129
 
130 28 alirezamon
                my $xc=$xn * $yn;
131
                my @randoms=@{$rnd};
132
                my $num=($y * $xn) +    $x;
133
                my $dest = @{$randoms[$num]}[$line_num-1];
134
                #print "$num:$dest, "; # \@{ \$randoms\[$num\]\}\[$line_num\]"; 
135
                $dest_x   = $dest % $xn;
136
                $dest_y   = $dest  / $xn;
137 25 alirezamon
 
138 28 alirezamon
        } else{#off
139 25 alirezamon
                 print "***********************************$traffic is not defined*******************************************\n";
140 28 alirezamon
                 $dest_x= $x;
141
                 $dest_y= $y;
142 25 alirezamon
 
143
        }
144
 
145 28 alirezamon
        return ($dest_x,$dest_y);
146 25 alirezamon
 
147
}
148
 
149
 
150
 
151
 
152
 
153 28 alirezamon
 
154
sub gen_synthetic_traffic_ram_line{
155
        my ($emulate,  $x, $y,  $sample_num,$ratio ,$line_num,$rnd)=@_;
156
 
157 25 alirezamon
 
158 28 alirezamon
 
159
        my $ref=$emulate->object_get_attribute("sample$sample_num","noc_info");
160
        my %noc_info= %$ref;
161
        my $xn=$noc_info{NX};
162
        my $yn=$noc_info{NY};
163
        my $traffic=$emulate->object_get_attribute("sample$sample_num","traffic");
164 25 alirezamon
 
165 28 alirezamon
 
166
        my $pck_num_to_send=$emulate->object_get_attribute("sample$sample_num","PCK_NUM_LIMIT");
167
        my $pck_size=$emulate->object_get_attribute("sample$sample_num","PCK_SIZE");
168
        my $pck_class_in=0;
169
 
170
 
171
        if($line_num==0){ #first ram line shows how many times the ram content must be read 
172
                 #In random traffic each node sends 2 packets to other NC-1  nodes for (pck_num_to_send/2) times 
173
                        my $ram_cnt=  ($traffic eq 'random')? ($pck_num_to_send/(2*(($xn * $yn)-1)))+1:0 ;
174
                        return (0,$ram_cnt);
175
 
176
        }
177
        return (0,0) if($line_num>1  && $traffic ne 'random');
178
        return (0,0) if( $line_num>= $xn * $yn);
179 25 alirezamon
 
180 28 alirezamon
 
181 25 alirezamon
 
182 28 alirezamon
        #assign {pck_num_to_send_in,ratio_in, pck_size_in,dest_x_in, dest_y_in,pck_class_in, last_adr_in}= q_a;
183
        my $last_adr  = ( $traffic ne 'random') ? 1 :
184
                         ($line_num ==($xn * $yn)-1)? 1 :0;
185 25 alirezamon
 
186 28 alirezamon
        my ($dest_x, $dest_y)=synthetic_destination($traffic,$x,$y,$xn,$yn,$line_num,$rnd);
187 25 alirezamon
 
188 28 alirezamon
        my $vs= ( $traffic eq 'random')? 2 : $pck_num_to_send;
189
        $vs=($vs << 2 )+ ($ratio >>5) ;
190 25 alirezamon
 
191 28 alirezamon
        my $vl= ($ratio %32);
192
        $vl=($vl << PCK_SIZw )+$pck_size;
193
        $vl=($vl << MAXXw )+$dest_x;
194
        $vl=($vl << MAXYw )+$dest_y;
195
        $vl=($vl << MAXCw )+$pck_class_in;
196
        $vl=($vl << 1 )+$last_adr;
197 25 alirezamon
 
198 28 alirezamon
        return ($vs,$vl);
199 25 alirezamon
 
200 28 alirezamon
 
201 25 alirezamon
 
202
 
203
 
204
}
205
 
206 28 alirezamon
 
207
 
208
 
209
 
210
sub generate_synthetic_traffic_ram{
211
        my ($emulate,$x,$y,$sample_num,$ratio , $file,$rnd,$num)=@_;
212
        my $RAM_size=MAX_PATTERN+4;
213
 
214
 
215
 
216
        my $line_num;
217
        my $line_value;
218
        my $ram;
219
        if(SIM_RAM_GEN){
220
                my $ext= sprintf("%02u.txt",$num);
221
                open( $ram, '>', RAM_SIM_FILE.$ext) || die "Can not create: \">lib/emulate/emulate_ram.bin\" $!";
222
        }
223
        for ($line_num= 0; $line_num<MAX_PATTERN+4; $line_num++ ) {
224
                my ($value_s,$value_l)=gen_synthetic_traffic_ram_line ($emulate,  $x, $y,  $sample_num, $ratio ,$line_num,$rnd);
225
 
226
 
227
                #printf ("\n%08x\t",$value_s);
228
                #printf ("%08x\t",$value_l);
229
                if(SIM_RAM_GEN){
230
                        my $s=sprintf("%08X%08x",$value_s,$value_l);
231
                        print $ram "$s\n";
232 25 alirezamon
                }
233 28 alirezamon
                print_32_bit( $file, $value_s); # most significent 32 bit
234
                print_32_bit( $file, $value_l); # list significent 32 bit
235 25 alirezamon
 
236 28 alirezamon
        }
237
 
238 25 alirezamon
 
239 28 alirezamon
        if(SIM_RAM_GEN){
240
                close($ram);
241
        }
242
        #print "\n";
243 25 alirezamon
 
244 28 alirezamon
        #last ram three rows reserved for reading data from emulator
245 25 alirezamon
 
246 28 alirezamon
}
247 25 alirezamon
 
248
 
249 28 alirezamon
sub print_32_bit {
250
        my ($file,$v)=@_;
251
        for (my $i= 24; $i >=0 ; $i-=8) {
252
                my $byte= ($v >> $i ) & 0xFF;
253
                print $file pack('C*',$byte);
254
                #printf ("%02x\t",$byte);
255
        }
256
}
257 25 alirezamon
 
258
 
259 28 alirezamon
 
260
sub generate_emulator_ram {
261
        my ($emulate, $sample_num,$ratio_in,$info)=@_;
262
        my $ref=$emulate->object_get_attribute("sample$sample_num","noc_info");
263 25 alirezamon
        my %noc_info= %$ref;
264
        my $C=$noc_info{C};
265
        my $xn=$noc_info{NX};
266
        my $yn=$noc_info{NY};
267 28 alirezamon
        my $xc=$xn*$yn;
268
        my $rnd=random_dest_gen($xc); # generate a matrix of sudo random number
269
        my $traffic=$emulate->object_get_attribute("sample$sample_num","traffic");
270 25 alirezamon
        my @traffics=("tornado", "transposed 1", "transposed 2", "bit reverse", "bit complement","random", "hot spot" );
271 28 alirezamon
 
272 25 alirezamon
        if ( !defined $xn || $xn!~ /\s*\d+\b/ ){ add_info($info,"programe_pck_gens:invalid X value\n"); help(); return 0;}
273
        if ( !defined $yn || $yn!~ /\s*\d+\b/ ){ add_info($info,"programe_pck_gens:invalid Y value\n"); help(); return 0;}
274
        if ( !grep( /^$traffic$/, @traffics ) ){add_info($info,"programe_pck_gens:$traffic is an invalid Traffic name\n"); help(); return 0;}
275
        if ( $xn <2 || $xn >16 ){ add_info($info,"programe_pck_gens:invalid X value: ($xn). should be between 2 and 16 \n"); help(); return 0;}
276
        if ( $yn <2 || $yn >16 ){ add_info($info,"programe_pck_gens:invalid Y value:($yn). should be between 2 and 16 \n"); help(); return 0;}
277 28 alirezamon
        #open file pointer
278
        #open(my $file, RAM_BIN_FILE) || die "Can not create: \">lib/emulate/emulate_ram.bin\" $!";
279
        open(my $file, '>', RAM_BIN_FILE) || die "Can not create: \">lib/emulate/emulate_ram.bin\" $!";
280 25 alirezamon
 
281 28 alirezamon
        #generate each node ram data
282 25 alirezamon
        for (my $y=0; $y<$yn; $y=$y+1){
283 28 alirezamon
                for (my $x=0; $x<$xn; $x=$x+1){
284
                        my $num=($y * $xn) +    $x;
285
                        generate_synthetic_traffic_ram($emulate,$x,$y,$sample_num,$ratio_in, $file,$rnd,$num);
286 25 alirezamon
 
287 28 alirezamon
                }
288
        }
289
        close($file);
290
        return 1;
291 25 alirezamon
 
292 28 alirezamon
}
293 25 alirezamon
 
294 28 alirezamon
sub programe_pck_gens{
295
        my ($emulate, $sample_num,$ratio_in,$info)= @_;
296 25 alirezamon
 
297 28 alirezamon
        return 0 if(!generate_emulator_ram($emulate, $sample_num,$ratio_in,$info));
298 25 alirezamon
 
299 28 alirezamon
        #reset the FPGA board   
300
        #run_cmd_in_back_ground("quartus_stp -t ./lib/tcl/mem.tcl reset");
301
        return 0 if(run_cmd_update_info(reset_cmd(1,1),$info)); #reset both noc and jtag
302
        return 0 if(run_cmd_update_info(reset_cmd(0,1),$info)); #enable jtag keep noc in reset
303
        #programe packet generators rams
304
        my $cmd= "$ENV{'PRONOC_WORK'}/toolchain/bin/jtag_main -n ".JTAG_RAM_INDEX." -w 8 -i ".RAM_BIN_FILE." -c";
305
        #my ($result,$exit) = run_cmd_in_back_ground_get_stdout($cmd);
306 25 alirezamon
 
307 28 alirezamon
        return 0 if(run_cmd_update_info ($cmd,$info));
308
        #print $result;
309
 
310
        return 0 if(run_cmd_update_info(reset_cmd(1,1),$info)); #reset both
311
        return 0 if(run_cmd_update_info(reset_cmd(0,0),$info)); #enable both
312 25 alirezamon
#run_cmd_in_back_ground("quartus_stp -t ./lib/tcl/mem.tcl unreset");
313
#add_info($info,"$r\n");
314
 
315
return 1;
316
 
317
}
318
 
319
 
320 28 alirezamon
sub read_jtag_memory{
321
        my $addr=shift;
322
        my $cmd= "$ENV{'PRONOC_WORK'}/toolchain/bin/jtag_main -n ".JTAG_RAM_INDEX." -w 8 -d \"I:".UPDATE_WB_ADDR.",D:64:$addr,I:5,R:64:$addr,I:0\"";
323
        #print "$cmd\n";        
324
        my ($result,$exit) = run_cmd_in_back_ground_get_stdout($cmd);
325
        my @q =split  (/###read data#/,$result);
326
        my $d=$q[1];
327
        my $s= substr $d,2;
328
        #print "$s\n";
329
        return hex($s);
330
}
331 25 alirezamon
 
332 28 alirezamon
 
333
 
334
 
335
 
336
 
337 25 alirezamon
sub read_pack_gen{
338 28 alirezamon
        my ($emulate,$sample_num,$info)= @_;
339
        my $ref=$emulate->object_get_attribute("sample$sample_num","noc_info");
340 25 alirezamon
        my %noc_info= %$ref;
341
        my $xn=$noc_info{NX};
342
        my $yn=$noc_info{NY};
343
#wait for done 
344
    add_info($info, "wait for done\n");
345
    my $done=0;
346
    my $counter=0;
347
    while ($done ==0){
348 28 alirezamon
                usleep(300000);
349 25 alirezamon
                #my ($result,$exit) = run_cmd_in_back_ground_get_stdout("quartus_stp -t ./lib/tcl/read.tcl done");
350
                my ($result,$exit) = run_cmd_in_back_ground_get_stdout(READ_DONE_CMD);
351 28 alirezamon
                if($exit != 0 ){
352
                        add_info($info,$result);
353
                        return undef;
354
                }
355 25 alirezamon
                my @q =split  (/###read data#/,$result);
356
                #print "\$result=$result\n";
357
 
358
 
359
                $done=($q[1] eq "0x0")? 0 : 1;
360
                #print "\$q[1]=$q[1] done=$done\n";
361 28 alirezamon
 
362 25 alirezamon
                $counter++;
363
                if($counter == 15){ # 
364
                        add_info($info,"Done is not asserted. I reset the board and try again\n");
365 28 alirezamon
                        return if(run_cmd_update_info (reset_cmd(1,1),$info));
366 25 alirezamon
                        #run_cmd_in_back_ground("quartus_stp -t ./lib/tcl/mem.tcl reset");
367
                        usleep(300000);
368 28 alirezamon
                        return if(run_cmd_update_info (reset_cmd(0,0),$info));
369 25 alirezamon
                        #run_cmd_in_back_ground("quartus_stp -t ./lib/tcl/mem.tcl unreset");                    
370
                }
371
                if($counter>30){
372
                          #something is wrong
373
                        add_info($info,"Done is not asserted again. I  am going to ignore this test case");
374
                        return undef;
375
                }
376
        }
377
 
378
        add_info($info,"Done is asserted\n");
379 28 alirezamon
        #print" Done is asserted\n";
380 25 alirezamon
        #my $i=0;
381
        my %results;
382
        my $sum_of_latency=0;
383
        my $sum_of_pck=0;
384 28 alirezamon
        for (my $y=0; $y<$yn; $y=$y+1){
385
                for (my $x=0; $x<$xn; $x=$x+1){
386 25 alirezamon
                        my $num=($y * $xn) +    $x;
387 28 alirezamon
                        my $read_addr=($num * RAM_SIZE) + MAX_PATTERN +1;
388
 
389
                        my $sent_pck_addr=  sprintf ("%X",$read_addr);
390
                        my $got_pck_addr =  sprintf ("%X",$read_addr+1);
391
                        my $latency_addr =  sprintf ("%X",$read_addr+2);
392
 
393
                        $results{$num}{sent_pck}=read_jtag_memory($sent_pck_addr);
394
                        $results{$num}{got_pck}=read_jtag_memory($got_pck_addr);
395
                        $results{$num}{latency}=read_jtag_memory($latency_addr);
396
                        print "read pckgen $num\n";
397 25 alirezamon
 
398 28 alirezamon
                        $sum_of_latency+=$results{$num}{latency};
399
                        $sum_of_pck+=$results{$num}{got_pck};
400 25 alirezamon
                #$i=$i+2;
401
        }}
402
 
403
        foreach my $p (sort keys %results){
404
 
405
 
406
                #print "$p  : \n latency: $results{$p}{latency}\n";
407
                #print " got_pck : $results{$p}{got_pck}\n";
408
                #print "sent_pck:$results{$p}{sent_pck}\n\n";
409
 
410
        }
411
        my $avg= ($sum_of_pck>0)? $sum_of_latency/$sum_of_pck : 0;
412 28 alirezamon
 
413 25 alirezamon
        return sprintf("%.1f", $avg);
414
}
415
 

powered by: WebSVN 2.1.0

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