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/] [topology.pl] - Blame information for rev 56

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 43 alirezamon
#!/usr/bin/perl -w
2
 
3 48 alirezamon
#this file contains NoC topology related sub-functions
4 43 alirezamon
 
5 48 alirezamon
use constant::boolean;
6 43 alirezamon
use strict;
7
use warnings;
8
 
9
use FindBin;
10
use lib $FindBin::Bin;
11
 
12
sub get_topology_info {
13
        my ($self) =@_;
14
        my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
15
        my $T1=$self->object_get_attribute('noc_param','T1');
16
        my $T2=$self->object_get_attribute('noc_param','T2');
17
        my $T3=$self->object_get_attribute('noc_param','T3');
18
        my $V = $self->object_get_attribute('noc_param','V');
19
        my $Fpay = $self->object_get_attribute('noc_param','Fpay');
20
 
21
        return get_topology_info_sub($topology, $T1, $T2, $T3,$V, $Fpay);
22
}
23
 
24
 
25 54 alirezamon
sub get_topology_info_from_parameters {
26
        my ($ref) =@_;
27
        my %noc_info;
28
        my %param= %$ref if(defined $ref );
29
        my $topology=$param{'TOPOLOGY'};
30
        my $T1  =$param{'T1'};
31
        my $T2  =$param{'T2'};
32
        my $T3  =$param{'T3'};
33
        my $V   =$param{'V'};
34
        my $Fpay=$param{'Fpay'};
35
        return get_topology_info_sub($topology, $T1, $T2, $T3,$V, $Fpay);
36
}
37 43 alirezamon
 
38 54 alirezamon
 
39
 
40 43 alirezamon
sub get_topology_info_sub {
41
 
42
        my ($topology, $T1, $T2, $T3,$V, $Fpay)=@_;
43
 
44
        my $NE; # number of end points
45
        my $NR; # number of routers
46
        my $RAw; # routers address width
47
        my $EAw; # Endpoints address width
48
 
49
 
50
        my $Fw = 2+$V+$Fpay;
51
        if($topology eq '"TREE"') {
52
                my $K =  $T1;
53
        my $L =  $T2;
54
        $NE = powi( $K,$L );
55
        $NR = sum_powi ( $K,$L );
56
        my $Kw=log2($K);
57
        my $LKw=$L*$Kw;
58
        my $Lw=log2($L);
59
        $RAw=$LKw + $Lw;
60 48 alirezamon
        $EAw = $LKw;
61 43 alirezamon
 
62
        }elsif($topology eq '"FATTREE"') {
63
                my $K =  $T1;
64
        my $L =  $T2;
65
                $NE = powi( $K,$L );
66 48 alirezamon
        $NR = $L * powi( $K , $L - 1 );
67 43 alirezamon
        my $Kw=log2($K);
68
        my $LKw=$L*$Kw;
69
        my $Lw=log2($L);
70
        $RAw=$LKw + $Lw;
71 48 alirezamon
        $EAw = $LKw;
72 43 alirezamon
 
73
        }elsif ($topology eq '"RING"' || $topology eq '"LINE"'){
74
                my $NX=$T1;
75
                my $NY=1;
76
                my $NL=$T3;
77
                $NE = $NX*$NY*$NL;
78
        $NR = $NX*$NY;
79
        my $Xw=log2($NX);
80
        my $Yw=log2($NY);
81
        my $Lw=log2($NL);
82
        $RAw = $Xw;
83
        $EAw = ($NL==1) ? $RAw : $RAw + $Lw;
84
 
85 48 alirezamon
        }elsif ($topology eq '"MESH"' || $topology eq '"TORUS"' ) {
86 43 alirezamon
                my $NX=$T1;
87
                my $NY=$T2;
88
                my $NL=$T3;
89
                $NE = $NX*$NY*$NL;
90
                $NR = $NX*$NY;
91
        my $Xw=log2($NX);
92
        my $Yw=log2($NY);
93
        my $Lw=log2($NL);
94
        $RAw = $Xw + $Yw;
95
        $EAw = ($NL==1) ? $RAw : $RAw + $Lw;
96 48 alirezamon
        }elsif ($topology eq '"FMESH"'){
97
                my $NX=$T1;
98
                my $NY=$T2;
99
                my $NL=$T3;
100
                $NE = $NX*$NY*$NL + 2*($NX + $NY);
101
                $NR = $NX*$NY;
102
        my $Xw=log2($NX);
103
        my $Yw=log2($NY);
104
        my $Lw=log2($NL);
105
        $RAw = $Xw + $Yw;
106
        $EAw = $RAw + log2(4+$NL);
107 43 alirezamon
 
108 48 alirezamon
        }elsif ($topology eq '"STAR"' ) {
109
                $NE= $T1;
110
                $NR= 1;
111
                $RAw=log2($NR);
112
                $EAw=log2($NE);
113
 
114
        }else{ #custom
115
                $NE= $T1;
116
                $NR= $T2;
117
                $RAw=log2($NR);
118
                $EAw=log2($NE);
119
        }
120 43 alirezamon
        return ($NE, $NR, $RAw, $EAw, $Fw);
121
}
122
 
123
 
124
sub fattree_addrencode {
125
        my ( $pos, $k, $l)=@_;
126
        my  $pow; my $ tmp;
127
        my $addrencode=0;
128
        my $kw=log2($k);
129
        $pow=1;
130
        for (my $i = 0; $i <$l; $i=$i+1 ) {
131
                $tmp=int($pos/$pow);
132
                $tmp=$tmp % $k;
133 56 alirezamon
                $tmp=$tmp << ($i)*$kw;
134 43 alirezamon
                $addrencode=$addrencode | $tmp;
135
                $pow=$pow * $k;
136
        }
137
         return $addrencode;
138
}
139
 
140
sub fattree_addrdecode{
141
        my ($addrencode, $k, $l)=@_;
142
        my $kw=0;
143
        my $mask=0;
144
        my $pow; my $tmp;
145
        my $pos=0;
146 56 alirezamon
        while((0x1 << $kw) < $k){
147 43 alirezamon
                $kw++;
148
                $mask<<=1;
149
                $mask|=0x1;
150
        }
151
        $pow=1;
152
        for (my $i = 0; $i <$l; $i=$i+1 ) {
153
                $tmp = $addrencode & $mask;
154
                #printf("tmp1=%u\n",tmp);
155
                $tmp=($tmp*$pow);
156
                $pos= $pos + $tmp;
157
                $pow=$pow * $k;
158
                $addrencode>>=$kw;
159
        }
160
        return $pos;
161
}
162
 
163 48 alirezamon
 
164
 
165
 
166
 
167
 
168
 
169
 
170
 
171 43 alirezamon
sub get_connected_router_id_to_endp{
172
        my ($self,$endp_id)=@_;
173
        my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
174
        my $T1=$self->object_get_attribute('noc_param','T1');
175
        my $T2=$self->object_get_attribute('noc_param','T2');
176
        my $T3=$self->object_get_attribute('noc_param','T3');
177
        if($topology eq '"FATTREE"' || $topology eq '"TREE"') {
178
                return int($endp_id/$T1);
179 48 alirezamon
        }elsif ($topology eq '"RING"' || $topology eq '"LINE"'  ||  $topology eq '"MESH"' || $topology eq '"TORUS"'){
180 43 alirezamon
                 return int($endp_id/$T3);
181 48 alirezamon
        }elsif ($topology eq '"STAR"' ) {
182
                 return 0;#there is only one routerin star topology
183
        }elsif ($topology eq '"FMESH"'){
184
                my $tmp = $T1*$T2*$T3;
185
                return int($endp_id/$T3) if($endp_id<$tmp);
186
                return $endp_id-$tmp if($endp_id<$tmp+$T1);
187
                return ($endp_id-$tmp-$T1)+ $T1*($T2-1) if($endp_id<$tmp+2*$T1);
188
                return ($endp_id-$tmp-2*$T1)*$T1 if($endp_id<$tmp+2*$T1+$T2);
189
                return ($endp_id-$tmp-2*$T1-$T2+1)*$T1-1;
190
 
191
        }else{#custom
192
                my @er_addr = $self->object_get_attribute('noc_connection','er_addr');
193
                return $er_addr[$endp_id];
194 43 alirezamon
        }
195
}
196
 
197
 
198 48 alirezamon
sub fmesh_addrencode{
199
        my($id,$T1,$T2,$T3)=@_;
200
        my  ($y, $x, $l,$p, $diff,$mul);
201
        $mul  = $T1*$T2*$T3;
202
 
203
        my  $LOCAL   =   0;
204
        my      $EAST    =   1;
205
        my      $NORTH   =   2;
206
        my      $WEST    =   3;
207
        my      $SOUTH   =   4;
208
 
209
        if($id < $mul) {
210
                $y = (($id/$T3) / $T1 );
211
                $x = (($id/$T3) % $T1 );
212
                $l = ( $id %$T3);
213
                $p = ($l==0)? $LOCAL : 4+$l;
214
        }else{
215
                $diff = $id -  $mul ;
216
                if( $diff <  $T1){ #top mesh edge
217
                        $y = 0;
218
                        $x = $diff;
219
                        $p = $NORTH;
220
                }
221
                elsif ( $diff < 2* $T1) { #bottom mesh edge 
222
                        $y = $T2-1;
223
                        $x = $diff-$T1;
224
                        $p = $SOUTH;
225
                }
226
                elsif ( $diff < (2* $T1)+$T2 ) { #left mesh edge 
227
                        $y = $diff - (2* $T1);
228
                        $x = 0;
229
                        $p = $WEST;
230
                }
231
                else {  #right mesh edge 
232
                        $y = $diff - (2* $T1) -$T2;
233
                        $x = $T1-1;
234
                        $p = $EAST;
235
                }
236
        }
237
        my $NXw=log2($T1);
238
        my $NYw=log2($T2);
239
    my $addrencode=0;
240 56 alirezamon
    $addrencode = ($p << ($NXw+$NYw)|  ($y << $NXw) | $x);
241 48 alirezamon
    return $addrencode;
242
}
243
 
244
sub fmesh_endp_addr_decoder {
245
        my ($code, $T1, $T2, $T3)=@_;
246
        my ($x, $y, $p) =mesh_tori_addr_sep ($code, $T1, $T2, $T3);
247
        my  $LOCAL   =   0;
248
        my      $EAST    =   1;
249
        my      $NORTH   =   2;
250
        my      $WEST    =   3;
251
        my      $SOUTH   =   4;
252
        return (($y*$T1)+$x)*$T3 if($p== $LOCAL);
253
        return (($y*$T1)+$x)*$T3+($p-$SOUTH) if($p > $SOUTH);
254
        return (($T1*$T2*$T3) + $x) if($p== $NORTH);
255
        return (($T1*$T2*$T3) + $T1 + $x) if($p== $SOUTH);
256
        return (($T1*$T2*$T3) + 2*$T1 + $y) if($p== $WEST );
257
        return (($T1*$T2*$T3) + 2*$T1 + $T2 + $y) if($p== $EAST );
258
        return 0; #should not reach here
259
}
260
 
261
 
262
 
263
 
264
 
265 43 alirezamon
sub get_router_num {
266
        my ($self,$x, $y)=@_;
267
        my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
268
        my $T1=$self->object_get_attribute('noc_param','T1');
269
        my $T2=$self->object_get_attribute('noc_param','T2');
270
        if($topology eq '"FATTREE"') {
271
                return fattree_addrdecode($x, $T1, $T2);
272 48 alirezamon
        }elsif ($topology eq '"RING"' || $topology eq '"LINE"' ||  $topology eq '"FMESH"'  ||  $topology eq '"MESH"' || $topology eq '"TORUS"'){
273 43 alirezamon
                 return ($y*$T1)+$x;
274 48 alirezamon
        }else{#custom
275
                #It is not used for custom & STAR topology 
276 43 alirezamon
        }
277
}
278
 
279
sub router_addr_encoder{
280
        my ($self, $id)=@_;
281
        my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
282
        my $T1=$self->object_get_attribute('noc_param','T1');
283
        my $T2=$self->object_get_attribute('noc_param','T2');
284
        my $T3=$self->object_get_attribute('noc_param','T3');
285
        if($topology eq '"FATTREE"' || $topology eq '"TREE"') {
286
                return fattree_addrencode($id, $T1, $T2);
287 48 alirezamon
        }elsif ($topology eq '"RING"' || $topology eq '"LINE"'  ||  $topology eq '"MESH"' || $topology eq '"FESH"' || $topology eq '"TORUS"'){
288 43 alirezamon
                return mesh_tori_addrencode($id,$T1, $T2,1);
289 48 alirezamon
        }else { #custom & STAR
290
                return $id;
291 43 alirezamon
        }
292
}
293
 
294
sub endp_addr_encoder{
295
        my ($self, $id)=@_;
296
        my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
297
        my $T1=$self->object_get_attribute('noc_param','T1');
298
        my $T2=$self->object_get_attribute('noc_param','T2');
299
        my $T3=$self->object_get_attribute('noc_param','T3');
300
        if($topology eq '"FATTREE"' || $topology eq '"TREE"') {
301
                return fattree_addrencode($id, $T1, $T2);
302 56 alirezamon
        }elsif ($topology eq '"MESH"' || $topology eq '"TORUS"'){
303 48 alirezamon
                return mesh_tori_addrencode($id,$T1, $T2,$T3);
304 56 alirezamon
        }elsif ($topology eq '"RING"' || $topology eq '"LINE"'){
305
                return ring_line_addrencode($id,$T1, $T3);
306 48 alirezamon
        }elsif ($topology eq '"FMESH"' ){
307
                return  fmesh_addrencode($id,$T1, $T2,$T3);
308
        }else{#CUSTOM & STAR
309
                return $id;
310 43 alirezamon
        }
311
}
312
 
313
sub endp_addr_decoder {
314
        my ($self,$code)=@_;
315
        my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
316
        my $T1=$self->object_get_attribute('noc_param','T1');
317
        my $T2=$self->object_get_attribute('noc_param','T2');
318
        my $T3=$self->object_get_attribute('noc_param','T3');
319
        if($topology eq '"FATTREE"' || $topology eq '"TREE"') {
320
                return fattree_addrdecode($code, $T1, $T2);
321
        }
322 48 alirezamon
        elsif ($topology eq '"RING"' || $topology eq '"LINE"'  ||  $topology eq '"MESH"' || $topology eq '"TORUS"'){
323 43 alirezamon
                my ($x, $y, $l) = mesh_tori_addr_sep($code,$T1, $T2,$T3);
324 44 alirezamon
                #print "my ($x, $y, $l) = mesh_tori_addr_sep($code,$T1, $T2,$T3);\n";
325 43 alirezamon
                return (($y*$T1)+$x)*$T3+$l;
326 48 alirezamon
        }elsif ($topology eq '"FMESH"' ){
327
                return fmesh_endp_addr_decoder($code,$T1, $T2,$T3);
328
        }else{#custom & STAR
329
                return $code;
330 43 alirezamon
        }
331
}
332
 
333
sub mask_gen{
334
        my $k=shift;
335
        my $kw=0;
336
        my $mask=0;
337 56 alirezamon
        while((0x1 << $kw) < $k){
338 43 alirezamon
                $kw++;
339
                $mask<<=1;
340
                $mask|=0x1;
341
        }
342
        return $mask;
343
}
344
 
345
 
346
sub mesh_tori_addr_sep {
347
        my ($code,$NX, $NY,$NL)=@_;
348
        my ($x, $y, $l);
349
        my $NXw=log2($NX);
350
        my $NYw=log2($NY);
351
        $x = $code &  mask_gen($NX);
352
        $code>>=$NXw;
353
        $y = $code &   mask_gen($NY);
354
        $code>>=$NYw;
355
        $l = $code;
356 44 alirezamon
        return ($x, $y, $l);
357 43 alirezamon
}
358
 
359
sub mesh_tori_addrencode{
360
        my ($id,$T1, $T2,$T3)=@_;
361
        my ($x,$y,$l)=mesh_tori_addrencod_sep($id,$T1,$T2,$T3);
362
    return mesh_tori_addr_join($x,$y,$l,$T1, $T2,$T3);
363
}
364
 
365 56 alirezamon
sub ring_line_addrencode {
366
        my ($id,$T1, $T3)=@_;
367
        my ($x,$y,$l)=mesh_tori_addrencod_sep($id,$T1,0,$T3);
368
        return ring_line_addr_join($x,$y,$l,$T1, $T3);
369
}
370
 
371 43 alirezamon
sub  mesh_tori_addrencod_sep{
372
        my ($id,$T1,$T2,$T3)=@_;
373
        my ($x,$y,$l);
374
        $l=$id % $T3; # id%NL
375
        my $R= int($id / $T3);
376
        $x= $R % $T1;# (id/NL)%NX
377
        $y=int($R / $T1);# (id/NL)/NX
378
        return ($x,$y,$l);
379
}
380
 
381
sub mesh_tori_addr_join {
382
        my ($x, $y, $l,$T1, $T2,$T3)=@_;
383
        my $NXw=log2($T1);
384
        my $NYw=log2($T2);
385
    my $addrencode=0;
386 56 alirezamon
    $addrencode =($T3==1)?   ($y << $NXw | $x) : ($l << ($NXw+$NYw)|  ($y << $NXw) | $x);
387 43 alirezamon
    return $addrencode;
388
}
389
 
390 56 alirezamon
sub ring_line_addr_join {
391
        my ($x, $y, $l,$T1, $T3)=@_;
392
        my $NXw=log2($T1);
393
        my $addrencode=0;
394
    $addrencode =($T3==1)?  $x : ($l << $NXw) |  $x;
395
    return $addrencode;
396
}
397 43 alirezamon
 
398 56 alirezamon
 
399
 
400 54 alirezamon
sub mcast_partial_width {
401
        my ($p,$NE)=@_;
402
        my $m=0;
403
        $p=remove_not_hex($p);
404
        my @arr=split (//, $p);
405
        foreach my $i (@arr) {
406
                my $n=hex($i);
407
                $m++ if($n & 0x1);
408
                $m++ if($n & 0x2);
409
                $m++ if($n & 0x4);
410
                $m++ if($n & 0x8);
411
        }
412
       return $m;
413
}
414 43 alirezamon
 
415
 
416
 
417
sub get_noc_verilator_top_modules_info {
418
        my ($self) =@_;
419
 
420
        my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
421
        my $T1=$self->object_get_attribute('noc_param','T1');
422
        my $T2=$self->object_get_attribute('noc_param','T2');
423
        my $T3=$self->object_get_attribute('noc_param','T3');
424 54 alirezamon
        my $cast = $self->object_get_attribute('noc_param','MCAST_ENDP_LIST');
425
        my $CAST_TYPE= $self->object_get_attribute('noc_param','CAST_TYPE');
426
        my $DAw_OFFSETw  =  ($topology eq '"MESH"' || $topology eq '"TORUS"' || $topology eq '"FMESH"')?  $T1 : 0;
427 43 alirezamon
 
428 54 alirezamon
 
429 43 alirezamon
        my %tops;
430
        my %nr_p; # number of routers have $p port num
431
        my $router_p; #number of routers with different port number in topology 
432
 
433 48 alirezamon
        my ($ne, $nr, $RAw, $EAw)=get_topology_info($self);
434
 
435 54 alirezamon
        my $MCAST_PRTLw= mcast_partial_width($cast,$ne);
436
        my $MCASTw =
437
            ($CAST_TYPE eq '"MULTICAST_FULL"') ? $ne :
438
            ($CAST_TYPE eq '"MULTICAST_PARTIAL"' && $EAw >= $MCAST_PRTLw) ? $EAw +1 :
439
            ($CAST_TYPE eq '"MULTICAST_PARTIAL"' && $EAw <  $MCAST_PRTLw) ? $MCAST_PRTLw +1 :
440
            $EAw +1; #broadcast
441
 
442
        my $DAw = ($CAST_TYPE eq '"UNICAST"') ?   $EAw: $MCASTw +  $DAw_OFFSETw;
443
 
444 48 alirezamon
        my $custom_include="";
445 43 alirezamon
        if($topology eq '"FATTREE"') {
446
                my $K =  $T1;
447
        my $L =  $T2;
448
        my $p2 = 2*$K;
449
        $router_p=2;
450
        my $NRL= $ne/$K; #number of router in  each layer
451
        $nr_p{1}=$NRL;
452
        $nr_p{2}=$nr-$NRL;
453
        $nr_p{p1}=$K;
454
        $nr_p{p2}=2*$K;
455
 
456
        %tops = (
457 48 alirezamon
                        #"Vrouter1" => "router_top_v_p${K}.v", 
458
                        #"Vrouter2" => "router_top_v_p${p2}.v", 
459
                        "Vrouter1" => "--top-module  router_top_v  -GP=${K}  ",
460
                        "Vrouter2" => "--top-module  router_top_v  -GP=${p2} ",
461
               # "Vnoc" => " --top-module noc_connection ",
462 43 alirezamon
 
463
        );
464
        }elsif ($topology eq '"TREE"'){
465
        my $K =  $T1;
466
        my $L =  $T2;
467
        my $p2 = $K+1;
468
        $router_p=2;# number of router with different port number                        
469
        $nr_p{1}=1;
470
        $nr_p{2}=$nr-1;
471
        $nr_p{p1}=$K;
472
        $nr_p{p2}=$K+1;
473
 
474
        %tops = (
475 48 alirezamon
                        #"Vrouter1" => "router_top_v_p${K}.v", 
476
                        #"Vrouter2" => "router_top_v_p${p2}.v",
477
                        "Vrouter1" => "--top-module  router_top_v  -GP=${K}  ",
478
                        "Vrouter2" => "--top-module  router_top_v  -GP=${p2} ",
479
               # "Vnoc" => " --top-module noc_connection ",             
480 43 alirezamon
        );
481
 
482
        }elsif ($topology eq '"RING"' || $topology eq '"LINE"'){
483
 
484
                $router_p=1;
485
                $nr_p{1}=$nr;
486
                my $ports= 3+$T3-1;
487
                $nr_p{p1}=$ports;
488
                %tops = (
489 48 alirezamon
                        #"Vrouter1" => "router_top_v_p${ports}.v", 
490
               "Vrouter1" => "--top-module  router_top_v  -GP=${ports}  ",
491
                  # "Vnoc" => " --top-module noc_connection ",
492 43 alirezamon
 
493
        );
494
 
495
 
496 48 alirezamon
        }elsif ($topology eq '"MESH"' || $topology eq '"TORUS"' || $topology eq '"FMESH"') {
497 43 alirezamon
 
498
        $router_p=1;
499
        $nr_p{1}=$nr;
500
        my $ports= 5+$T3-1;
501
                $nr_p{p1}=$ports;
502
        %tops = (
503 48 alirezamon
                #"Vrouter1" => "router_top_v_p${ports}.v",
504
                "Vrouter1" => "--top-module  router_top_v  -GP=${ports}  ",
505
              #  "Vnoc" => " --top-module noc_connection",
506 43 alirezamon
 
507
        );
508 48 alirezamon
    }elsif ($topology eq '"STAR"') {
509
         $router_p=1;# number of router with different port number
510
         my $ports= $T1;
511 54 alirezamon
         $nr_p{p1}=$ports;
512 48 alirezamon
         $nr_p{1}=1;
513
          %tops = (
514
                #"Vrouter1" => "router_top_v_p${ports}.v",
515
                "Vrouter1" => "--top-module  router_top_v  -GP=${ports}  ",
516
              #  "Vnoc" => " --top-module noc_connection",
517
 
518
        );
519 43 alirezamon
 
520 48 alirezamon
        }else {#custom
521
 
522
                my $dir =get_project_dir()."/mpsoc/rtl/src_topolgy";
523
                my $file="$dir/param.obj";
524
                my %param;
525
                if(-f $file){
526
                        my ($pp,$r,$err) = regen_object($file );
527
                if ($r){
528
                        print "**Error: cannot open $file file: $err\n";
529
                    return;
530
                 }
531
 
532
                        %param=%{$pp};
533
                }else {
534
                        print "**Error: cannot find $file \n";
535
                        return;
536
                }
537
 
538
            my $topology_name=$self->object_get_attribute('noc_param','CUSTOM_TOPOLOGY_NAME');
539
                my $ref=$param{$topology_name}{'ROUTER_Ps'};
540
                print $ref;
541
                my %router_ps= %{$ref};
542
                my $i=1;
543
                #%tops = ("Vnoc" => " --top-module noc_connection");
544
 
545
                #should sort neumeric. The router with smaller port number should comes first
546
 
547
                foreach my $p (sort { $a <=> $b } keys  %router_ps){
548
                        $nr_p{$i}=$router_ps{$p};
549
            $nr_p{"p$i"}=$p;
550
            #$tops{"Vrouter$i"}= "router_top_v_p${p}.v", 
551
            $tops{"Vrouter$i"}= "--top-module  router_top_v  -GP=${p}  ",
552
                        $i++;
553
 
554
                }
555
                $router_p=$i-1;
556
                ${topology_name} =~ s/\"+//g;
557 54 alirezamon
                $custom_include="#define IS_${topology_name}_noc\n";
558 48 alirezamon
        }#else
559 43 alirezamon
 
560 48 alirezamon
 
561
 
562 43 alirezamon
        my $includ_h="\n";
563
        for (my $p=1; $p<=$router_p ; $p++){
564
                 $includ_h=$includ_h."#include \"Vrouter$p.h\" \n";
565
        }
566 48 alirezamon
        my $rns_num = $router_p+1;
567
        $includ_h.="int router_NRs[$rns_num];\n";
568 54 alirezamon
 
569
        my $max_p=0;
570 43 alirezamon
        for (my $p=1; $p<=$router_p ; $p++){
571 54 alirezamon
                  my $pnum= $nr_p{"p$p"};
572 43 alirezamon
                 $includ_h=$includ_h."#define NR${p} $nr_p{$p}\n";
573 54 alirezamon
                 $includ_h=$includ_h."#define NR${p}_PNUM $pnum\n";
574
 
575 48 alirezamon
                 $includ_h=$includ_h."Vrouter${p}               *router${p}[ $nr_p{$p} ];   // Instantiation of router with $pnum  port number\n";
576 54 alirezamon
                 $max_p = $pnum if($max_p < $pnum);
577 43 alirezamon
        }
578 54 alirezamon
        $includ_h.="#define MAX_P  $max_p //The maximum number of ports available in a router in this topology\n";
579 43 alirezamon
 
580 54 alirezamon
        $includ_h.="#define DAw $DAw //The traffic generator's destination address width\n";
581 48 alirezamon
 
582 54 alirezamon
 
583 48 alirezamon
        my $st1='';
584
        my $st2='';
585
        my $st3='';
586
        my $st4='';
587
        my $st5='';
588
        my $st6='';
589 54 alirezamon
        my $st7='';
590
        my $st8='';
591
 
592 48 alirezamon
        my $i=1;
593
        my $j=0;
594
        my $accum=0;
595 43 alirezamon
        for (my $p=1; $p<=$router_p ; $p++){
596
                $includ_h=$includ_h."
597
 
598
 
599
 
600
";
601 48 alirezamon
#if             ROUTER_P_NUM >$j
602
 
603
#endif
604
 
605
$st2=$st2."
606
    router_NRs[$p] =$nr_p{$p};
607
        for(i=0;i<NR${i};i++)   router${i}[i]   = new Vrouter${i};
608
";
609
 
610
$st3=$st3."
611
        for(i=0;i<NR${i};i++){
612
                router${i}[i]->reset= reset;
613
                router${i}[i]->clk= clk ;
614 43 alirezamon
        }
615 48 alirezamon
";
616
 
617
$st4=$st4."
618
        for(i=0;i<NR${i};i++) router${i}[i]->eval();
619
";
620
 
621
 
622
$st5=$st5."
623
        for(i=0;i<NR${i};i++) router${i}[i]->final();
624
";
625
 
626
 
627
$st6=$st6."
628
        if (i<NR${i}){ router${i}[i]->eval(); return;}
629
        i-=     NR${i};
630
";
631 54 alirezamon
 
632
 
633
 
634
 
635
 
636
$st7.="
637
        if (i<NR${i}){
638
                update_router_st(
639
                        NR${i}_PNUM,
640
                        router${i}[i]->current_r_id,
641 56 alirezamon
                        router${i}[i]->router_event,
642
                        sizeof(router${i}[i]->router_event[0])
643 54 alirezamon
                );
644
                return;
645
        }
646
        i-=     NR${i};
647
";
648
 
649
$st8=$st8."
650
        if (i<NR${i}){
651
                router${i}[i]->reset= reset;
652
                router${i}[i]->clk= clk ;
653
                return;
654
        }
655
        i-=     NR${i};
656
";
657
 
658
 
659
 
660 48 alirezamon
        $i++;
661
        $j++;
662
        $accum=$accum+$nr_p{$p};
663
 
664
}
665
 
666
 
667 43 alirezamon
$includ_h=$includ_h."
668
 
669 48 alirezamon
 
670 43 alirezamon
void Vrouter_new(){
671
        int i=0;
672 48 alirezamon
        $st2
673 43 alirezamon
}
674
 
675 48 alirezamon
$custom_include
676
 
677 43 alirezamon
void inline connect_routers_reset_clk(){
678
        int i;
679 48 alirezamon
        $st3
680 43 alirezamon
}
681
 
682
 
683
void inline routers_eval(){
684
        int i=0;
685 48 alirezamon
        $st4
686 43 alirezamon
}
687
 
688
void inline routers_final(){
689
        int i;
690 48 alirezamon
        $st5
691
}
692
 
693
void inline single_router_eval(int i){
694
        $st6
695
}
696
 
697 54 alirezamon
#define SMART_NUM  ((SMART_MAX==0)? 1 : SMART_MAX)
698 48 alirezamon
 
699 56 alirezamon
 
700 54 alirezamon
extern void update_router_st (
701
  unsigned int,
702
  unsigned int,
703 56 alirezamon
  void * ,
704
  size_t
705 54 alirezamon
);
706
 
707
void  single_router_st_update(int i){
708
        $st7
709
}
710
 
711
void  inline single_router_reset_clk(int i){
712
        $st8
713
}
714
 
715 48 alirezamon
 
716 43 alirezamon
";
717 48 alirezamon
 
718
#$includ_h.=" void connect_all_nodes(){\n";
719
 
720
#my $dot_file=get_dot_file_text($self,'topology');
721
#print "$dot_file\n";
722
#my @lines =split ("\n",$dot_file);
723
#foreach my $l (@lines) {
724
#    if ( $l =~  m{#*\"\s*R(\d+)\"\s*:\s*\"[pP](\d+)\"\s*->\s*\"R(\d+)\"\s*:\s*\"[pP](\d+)\"} ) {
725
#               my ($R1, $P1, $R2,$P2) = ($1, $2,$3,$4);
726
#               $includ_h.=connect_sim_nodes ($self,$topology,$R1, $P1, $R2, $P2);
727
#               
728
#   
729
#       }
730
#       if ( $l =~  m{#*\"\s*R(\d+)\"\s*:\s*\"[pP](\d+)\"\s*->\s*\"[Tt](\d+)\"} ) {
731
#               my ($R1, $P1, $T) = ($1, $2,$3);
732
#               $includ_h.=connect_sim_nodes($self,$topology,$R1, $P1, $T);
733
#               
734
#   
735
#       }
736
#       if ( $l =~  m{#*\s*\"[Tt](\d+)\"\s*->\s*\"R(\d+)\"\s*:\s*\"[pP](\d+)\"} ) {
737
#               my ($T, $R1, $P1) = ($1, $2,$3);
738
#               $includ_h.=connect_sim_nodes($self,$topology,$R1, $P1, $T);
739
#       }
740
#} 
741
#$includ_h.="\n}\n";
742
 
743 43 alirezamon
         return ($nr,$ne,$router_p,\%tops,$includ_h);
744
}
745
 
746 48 alirezamon
sub connect_sim_nodes{
747
        my ($self,$topology,$R1, $P1, $R2, $P2)=@_;
748
        if(defined $P2){ #R2R
749
                if($topology eq '"FATTREE"' || $topology eq '"TREE"'){
750
 
751
                }else{
752
                        return connect_r2r(1,$R1, $P1,1, $R2, $P2);
753
 
754
                }
755
        }else {
756
                my $T=$R2;
757
                if($topology eq '"FATTREE"' || $topology eq '"TREE"'){
758
 
759
                }else{
760
                        return connect_r2t(1,$R1, $P1, $T);
761
 
762
                }
763
 
764
        }
765
 
766
 
767
}
768 43 alirezamon
 
769 48 alirezamon
sub connect_r2r{
770
        my ($vrouter1_num,$r1,$p1,$vrouter2_num,$r2,$p2)=@_;
771
return "
772
        memcpy(&router${vrouter1_num}[$r1]->chan_in[$p1], router${vrouter2_num}[$r2]->chan_out[$p2] , sizeof( router${vrouter1_num}[$r1]->chan_in[$p1] ) );
773
        memcpy(&router${vrouter2_num}[$r2]->chan_in[$p2], router${vrouter1_num}[$r1]->chan_out[$p1] , sizeof( router${vrouter1_num}[$r1]->chan_in[$p1] ) );
774
        ";
775
}
776
 
777
sub connect_r2t{
778
my ($vrouter1_num,$r1, $p1, $T)=@_;
779
return "
780
        memcpy(&router${vrouter1_num}[$r1]->chan_in[$p1], traffic[$T]->chan_out , sizeof( traffic[$T]->chan_in ) );
781
        memcpy(&traffic[$T]->chan_in, router${vrouter1_num}[$r1]->chan_out[$p1] , sizeof( traffic[$T]->chan_in ) );
782
        ";
783
}
784
 
785
 
786 43 alirezamon
sub gen_tiles_physical_addrsses_header_file{
787
        my ($self,$file)=@_;
788
        my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
789
        my $txt = "#ifndef PHY_ADDR_H
790
        #define PHY_ADDR_H\n\n";
791
 
792
        #add phy addresses
793 48 alirezamon
        my ($NE, $NR, $RAw, $EAw,$Fw)=get_topology_info($self);
794 43 alirezamon
        for (my $id=0; $id<$NE; $id++){
795
                my $phy= endp_addr_encoder($self,$id);
796
                my $hex = sprintf("0x%x", $phy);
797
                $txt=$txt."\t#define PHY_ADDR_ENDP_$id  $hex\n";
798
 
799
        }
800
 
801
 
802
        $txt=$txt."#endif\n";
803
        save_file($file,$txt);
804
}
805
 
806
 
807 48 alirezamon
sub get_endpoints_mah_distance {
808
        my ($self,$endp1,$endp2)=@_;
809
 
810
        my $router1=get_connected_router_id_to_endp($self,$endp1);
811
        my $router2=get_connected_router_id_to_endp($self,$endp2);
812
 
813
        my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
814
        if($topology eq '"FATTREE"' || $topology eq '"TREE"') {
815
                return fattree_mah_distance($self, $router1,$router2);
816
        }elsif ($topology eq '"RING"' || $topology eq '"LINE"'  ||  $topology eq '"MESH"' || $topology eq '"TORUS"' || $topology eq '"FMESH"' ){
817
                return mesh_tori_mah_distance($self, $router1,$router2);
818
        }elsif ($topology eq '"STAR"'){
819
                return 1;
820
        }else { #custom
821
                return undef;
822
        }
823
 
824
}
825 43 alirezamon
 
826 48 alirezamon
sub mesh_tori_mah_distance {
827
        my ($self, $router1,$router2)=@_;
828
        my $T1=$self->object_get_attribute('noc_param','T1');
829
        my $T2=$self->object_get_attribute('noc_param','T2');
830
        my ($x1,$y1,$l1) = mesh_tori_addrencod_sep ($router1,$T1,$T2,1);
831
        my ($x2,$y2,$l2) = mesh_tori_addrencod_sep ($router2,$T1,$T2,1);
832
        my $x_diff = ($x1 > $x2) ? ($x1 - $x2) : ($x2 - $x1);
833
        my $y_diff = ($y1 > $y2) ? ($y1 - $y2) : ($y2 - $y1);
834
        my $mah_distance = $x_diff + $y_diff;
835
        return $mah_distance;
836
}
837
 
838
sub fattree_mah_distance {
839
        my ($self, $router1,$router2)=@_;
840
        my $k =$self->object_get_attribute('noc_param','T1');
841
        my $l =$self->object_get_attribute('noc_param','T2');
842
 
843
        my  $pow;
844
        my $tmp1;
845
        my $tmp2;
846
        my $distance=0;
847
        $pow=1;
848
        for (my $i = 0; $i <$l; $i=$i+1 ) {
849
                $tmp1=int($router1/$pow);
850
                $tmp2=int($router2/$pow);
851
                $tmp1=$tmp1 % $k;
852
                $tmp2=$tmp2 % $k;
853
                $pow=$pow * $k;
854
                $distance= ($i+1)*2-1 if($tmp1!=$tmp2); # distance obtained based on the highest level index which differ 
855
 
856
        }
857
         return $distance;
858
}
859
 
860 43 alirezamon
1

powered by: WebSVN 2.1.0

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