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 44

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

Line No. Rev Author Line
1 43 alirezamon
#!/usr/bin/perl -w
2
 
3
#this fle contains NoC topology related subfunctions
4
 
5
use Glib qw/TRUE FALSE/;
6
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
 
26
sub get_topology_info_sub {
27
 
28
        my ($topology, $T1, $T2, $T3,$V, $Fpay)=@_;
29
 
30
        my $NE; # number of end points
31
        my $NR; # number of routers
32
        my $RAw; # routers address width
33
        my $EAw; # Endpoints address width
34
 
35
 
36
        my $Fw = 2+$V+$Fpay;
37
        if($topology eq '"TREE"') {
38
                my $K =  $T1;
39
        my $L =  $T2;
40
        $NE = powi( $K,$L );
41
        $NR = sum_powi ( $K,$L );
42
        my $Kw=log2($K);
43
        my $LKw=$L*$Kw;
44
        my $Lw=log2($L);
45
        $RAw=$LKw + $Lw;
46
        $EAw = $RAw;
47
 
48
        }elsif($topology eq '"FATTREE"') {
49
                my $K =  $T1;
50
        my $L =  $T2;
51
                $NE = powi( $K,$L );
52
        $NR = $L * powi( $L , $L - 1 );
53
        my $Kw=log2($K);
54
        my $LKw=$L*$Kw;
55
        my $Lw=log2($L);
56
        $RAw=$LKw + $Lw;
57
        $EAw = $RAw;
58
 
59
        }elsif ($topology eq '"RING"' || $topology eq '"LINE"'){
60
                my $NX=$T1;
61
                my $NY=1;
62
                my $NL=$T3;
63
                $NE = $NX*$NY*$NL;
64
        $NR = $NX*$NY;
65
        my $Xw=log2($NX);
66
        my $Yw=log2($NY);
67
        my $Lw=log2($NL);
68
        $RAw = $Xw;
69
        $EAw = ($NL==1) ? $RAw : $RAw + $Lw;
70
 
71
        }else {#mesh torus
72
                my $NX=$T1;
73
                my $NY=$T2;
74
                my $NL=$T3;
75
                $NE = $NX*$NY*$NL;
76
                $NR = $NX*$NY;
77
        my $Xw=log2($NX);
78
        my $Yw=log2($NY);
79
        my $Lw=log2($NL);
80
        $RAw = $Xw + $Yw;
81
        $EAw = ($NL==1) ? $RAw : $RAw + $Lw;
82
        }
83
 
84
        return ($NE, $NR, $RAw, $EAw, $Fw);
85
}
86
 
87
 
88
sub fattree_addrencode {
89
        my ( $pos, $k, $l)=@_;
90
        my  $pow; my $ tmp;
91
        my $addrencode=0;
92
        my $kw=log2($k);
93
        $pow=1;
94
        for (my $i = 0; $i <$l; $i=$i+1 ) {
95
                $tmp=int($pos/$pow);
96
                $tmp=$tmp % $k;
97
                $tmp=$tmp<<($i)*$kw;
98
                $addrencode=$addrencode | $tmp;
99
                $pow=$pow * $k;
100
        }
101
         return $addrencode;
102
}
103
 
104
sub fattree_addrdecode{
105
        my ($addrencode, $k, $l)=@_;
106
        my $kw=0;
107
        my $mask=0;
108
        my $pow; my $tmp;
109
        my $pos=0;
110
        while((0x1<<$kw) < $k){
111
                $kw++;
112
                $mask<<=1;
113
                $mask|=0x1;
114
        }
115
        $pow=1;
116
        for (my $i = 0; $i <$l; $i=$i+1 ) {
117
                $tmp = $addrencode & $mask;
118
                #printf("tmp1=%u\n",tmp);
119
                $tmp=($tmp*$pow);
120
                $pos= $pos + $tmp;
121
                $pow=$pow * $k;
122
                $addrencode>>=$kw;
123
        }
124
        return $pos;
125
}
126
 
127
sub get_connected_router_id_to_endp{
128
        my ($self,$endp_id)=@_;
129
        my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
130
        my $T1=$self->object_get_attribute('noc_param','T1');
131
        my $T2=$self->object_get_attribute('noc_param','T2');
132
        my $T3=$self->object_get_attribute('noc_param','T3');
133
        if($topology eq '"FATTREE"' || $topology eq '"TREE"') {
134
                return int($endp_id/$T1);
135
        }else{
136
                 return int($endp_id/$T3);
137
        }
138
}
139
 
140
 
141
sub get_router_num {
142
        my ($self,$x, $y)=@_;
143
        my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
144
        my $T1=$self->object_get_attribute('noc_param','T1');
145
        my $T2=$self->object_get_attribute('noc_param','T2');
146
        if($topology eq '"FATTREE"') {
147
                return fattree_addrdecode($x, $T1, $T2);
148
        }else{
149
                 return ($y*$T1)+$x;
150
        }
151
}
152
 
153
sub router_addr_encoder{
154
        my ($self, $id)=@_;
155
        my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
156
        my $T1=$self->object_get_attribute('noc_param','T1');
157
        my $T2=$self->object_get_attribute('noc_param','T2');
158
        my $T3=$self->object_get_attribute('noc_param','T3');
159
        if($topology eq '"FATTREE"' || $topology eq '"TREE"') {
160
                return fattree_addrencode($id, $T1, $T2);
161
        }else{
162
                return mesh_tori_addrencode($id,$T1, $T2,1);
163
        }
164
}
165
 
166
sub endp_addr_encoder{
167
        my ($self, $id)=@_;
168
        my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
169
        my $T1=$self->object_get_attribute('noc_param','T1');
170
        my $T2=$self->object_get_attribute('noc_param','T2');
171
        my $T3=$self->object_get_attribute('noc_param','T3');
172
        if($topology eq '"FATTREE"' || $topology eq '"TREE"') {
173
                return fattree_addrencode($id, $T1, $T2);
174
        }else{
175
        return mesh_tori_addrencode($id,$T1, $T2,$T3);
176
        }
177
}
178
 
179
sub endp_addr_decoder {
180
        my ($self,$code)=@_;
181
        my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
182
        my $T1=$self->object_get_attribute('noc_param','T1');
183
        my $T2=$self->object_get_attribute('noc_param','T2');
184
        my $T3=$self->object_get_attribute('noc_param','T3');
185
        if($topology eq '"FATTREE"' || $topology eq '"TREE"') {
186
                return fattree_addrdecode($code, $T1, $T2);
187
        }
188
        else{
189
                my ($x, $y, $l) = mesh_tori_addr_sep($code,$T1, $T2,$T3);
190 44 alirezamon
                #print "my ($x, $y, $l) = mesh_tori_addr_sep($code,$T1, $T2,$T3);\n";
191 43 alirezamon
                return (($y*$T1)+$x)*$T3+$l;
192
        }
193
}
194
 
195
sub mask_gen{
196
        my $k=shift;
197
        my $kw=0;
198
        my $mask=0;
199
        while((0x1<<$kw) < $k){
200
                $kw++;
201
                $mask<<=1;
202
                $mask|=0x1;
203
        }
204
        return $mask;
205
}
206
 
207
 
208
sub mesh_tori_addr_sep {
209
        my ($code,$NX, $NY,$NL)=@_;
210
        my ($x, $y, $l);
211
        my $NXw=log2($NX);
212
        my $NYw=log2($NY);
213
        $x = $code &  mask_gen($NX);
214
        $code>>=$NXw;
215
        $y = $code &   mask_gen($NY);
216
        $code>>=$NYw;
217
        $l = $code;
218 44 alirezamon
        return ($x, $y, $l);
219 43 alirezamon
}
220
 
221
sub mesh_tori_addrencode{
222
        my ($id,$T1, $T2,$T3)=@_;
223
        my ($x,$y,$l)=mesh_tori_addrencod_sep($id,$T1,$T2,$T3);
224
    return mesh_tori_addr_join($x,$y,$l,$T1, $T2,$T3);
225
}
226
 
227
sub  mesh_tori_addrencod_sep{
228
        my ($id,$T1,$T2,$T3)=@_;
229
        my ($x,$y,$l);
230
        $l=$id % $T3; # id%NL
231
        my $R= int($id / $T3);
232
        $x= $R % $T1;# (id/NL)%NX
233
        $y=int($R / $T1);# (id/NL)/NX
234
        return ($x,$y,$l);
235
}
236
 
237
sub mesh_tori_addr_join {
238
        my ($x, $y, $l,$T1, $T2,$T3)=@_;
239
        my $NXw=log2($T1);
240
        my $NYw=log2($T2);
241
    my $addrencode=0;
242
    $addrencode =($T3==1)?   ($y << $NXw | $x) : ($l<<($NXw+$NYw)|  ($y << $NXw) | $x);
243
    return $addrencode;
244
}
245
 
246
 
247
 
248
 
249
 
250
sub get_noc_verilator_top_modules_info {
251
        my ($self) =@_;
252
 
253
        my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
254
        my $T1=$self->object_get_attribute('noc_param','T1');
255
        my $T2=$self->object_get_attribute('noc_param','T2');
256
        my $T3=$self->object_get_attribute('noc_param','T3');
257
 
258
        my %tops;
259
        my %nr_p; # number of routers have $p port num
260
        my $router_p; #number of routers with different port number in topology 
261
 
262
        my ($ne,$nr) =get_topology_info($self);
263
 
264
        if($topology eq '"FATTREE"') {
265
                my $K =  $T1;
266
        my $L =  $T2;
267
        my $p2 = 2*$K;
268
        $router_p=2;
269
        my $NRL= $ne/$K; #number of router in  each layer
270
        $nr_p{1}=$NRL;
271
        $nr_p{2}=$nr-$NRL;
272
        $nr_p{p1}=$K;
273
        $nr_p{p2}=2*$K;
274
 
275
        %tops = (
276
                        "Vrouter1" => "router_verilator_p${K}.v",
277
                        "Vrouter2" => "router_verilator_p${p2}.v",
278
                "Vnoc" => "noc_connection.sv",
279
 
280
        );
281
        }elsif ($topology eq '"TREE"'){
282
        my $K =  $T1;
283
        my $L =  $T2;
284
        my $p2 = $K+1;
285
        $router_p=2;# number of router with different port number                        
286
        $nr_p{1}=1;
287
        $nr_p{2}=$nr-1;
288
        $nr_p{p1}=$K;
289
        $nr_p{p2}=$K+1;
290
 
291
        %tops = (
292
                        "Vrouter1" => "router_verilator_p${K}.v",
293
                        "Vrouter2" => "router_verilator_p${p2}.v",
294
                "Vnoc" => "noc_connection.sv",
295
        );
296
 
297
        }elsif ($topology eq '"RING"' || $topology eq '"LINE"'){
298
 
299
                $router_p=1;
300
                $nr_p{1}=$nr;
301
                my $ports= 3+$T3-1;
302
                $nr_p{p1}=$ports;
303
                %tops = (
304
                        "Vrouter1" => "router_verilator_p${ports}.v",
305
                "Vnoc" => "noc_connection.sv",
306
 
307
        );
308
 
309
 
310
        }else {#mesh torus
311
 
312
        $router_p=1;
313
        $nr_p{1}=$nr;
314
        my $ports= 5+$T3-1;
315
                $nr_p{p1}=$ports;
316
        %tops = (
317
                        "Vrouter1" => "router_verilator_p${ports}.v",
318
                "Vnoc" => "noc_connection.sv",
319
 
320
        );
321
 
322
        }
323
 
324
        my $includ_h="\n";
325
        for (my $p=1; $p<=$router_p ; $p++){
326
                 $includ_h=$includ_h."#include \"Vrouter$p.h\" \n";
327
        }
328
        for (my $p=1; $p<=$router_p ; $p++){
329
                 $includ_h=$includ_h."#define NR${p} $nr_p{$p}\n";
330
                 $includ_h=$includ_h."Vrouter${p}               *router${p}[ $nr_p{$p} ];   // Instantiation of router with   port number\n";
331
        }
332
 
333
        for (my $p=1; $p<=$router_p ; $p++){
334
                $includ_h=$includ_h."
335
 
336
        #define NE  $ne
337
        #define NR  $nr
338
        #define ROUTER_P_NUM $router_p
339
 
340
        extern Vnoc                     *noc;
341
    extern int reset,clk;
342
 
343
 
344
 
345
void router${p}_connect_to_noc (unsigned int r, unsigned int n){
346
        unsigned int j;
347
        int flit_out_all_size = sizeof(router${p}[0]->flit_out_all)/sizeof(router${p}[0]->flit_out_all[0]);
348
        router${p}[r]->current_r_addr   = noc->current_r_addr[n];
349
        router${p}[r]->neighbors_r_addr         = noc->neighbors_r_addr[n];
350
 
351
 
352
        router${p}[r]->flit_in_we_all   = noc->router_flit_out_we_all[n];
353
        router${p}[r]->credit_in_all    = noc->router_credit_out_all[n];
354
        router${p}[r]->congestion_in_all        = noc->router_congestion_out_all[n];
355
        for(j=0;j<flit_out_all_size;j++)router${p}[r]->flit_in_all[j]   = noc->router_flit_out_all[n][j];
356
                noc->router_flit_in_we_all[n]   =       router${p}[r]->flit_out_we_all ;
357
                noc->router_credit_in_all[n]    =       router${p}[r]->credit_out_all;
358
                noc->router_congestion_in_all[n]=       router${p}[r]->congestion_out_all;
359
        for(j=0;j<flit_out_all_size;j++) noc->router_flit_in_all[n][j]  = router${p}[r]->flit_out_all[j] ;
360
}
361
";
362
        }
363
$includ_h=$includ_h."
364
void inline connect_all_routers_to_noc ( ){
365
        int i;
366
if((strcmp(TOPOLOGY ,\"FATTREE\")==0) || (strcmp(TOPOLOGY ,\"TREE\")==0) ){
367
                                for(i=0;i<NR1;i++) router1_connect_to_noc (i, i);
368
#if             ROUTER_P_NUM >1
369
                                for(i=0;i<NR2;i++) router2_connect_to_noc (i, i+NR1);
370
#endif
371
 
372
                        }else{
373
                                for (i=0;i<NR1;i++)     router1_connect_to_noc (i, i);
374
                        }
375
}
376
 
377
void Vrouter_new(){
378
        int i=0;
379
        for(i=0;i<NR1;i++)      router1[i]      = new Vrouter1;             // root nodes
380
#if             ROUTER_P_NUM >1
381
        for(i=0;i<NR2;i++)      router2[i]      = new Vrouter2;             // leaves
382
#endif
383
 
384
 
385
}
386
 
387
void inline connect_routers_reset_clk(){
388
        int i;
389
        for(i=0;i<NR1;i++) {
390
                router1[i]->reset= reset;
391
                router1[i]->clk= clk ;
392
        }
393
#if             ROUTER_P_NUM >1
394
        for(i=0;i<NR2;i++) {
395
                router2[i]->reset= reset;
396
                router2[i]->clk= clk ;
397
        }
398
#endif
399
}
400
 
401
 
402
void inline routers_eval(){
403
        int i=0;
404
        for(i=0;i<NR1;i++) router1[i]->eval();
405
#if             ROUTER_P_NUM >1
406
        for(i=0;i<NR2;i++) router2[i]->eval();
407
#endif
408
}
409
 
410
void inline routers_final(){
411
        int i;
412
        for(i=0;i<NR1;i++) router1[i]->final();
413
#if             ROUTER_P_NUM >1
414
                for(i=0;i<NR2;i++) router2[i]->final();
415
#endif
416
}
417
";
418
         return ($nr,$ne,$router_p,\%tops,$includ_h);
419
}
420
 
421
 
422
sub gen_tiles_physical_addrsses_header_file{
423
        my ($self,$file)=@_;
424
        my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
425
        my $txt = "#ifndef PHY_ADDR_H
426
        #define PHY_ADDR_H\n\n";
427
 
428
        #add phy addresses
429
        my ($NE, $NR, $RAw, $EAw)=get_topology_info($self);
430
        for (my $id=0; $id<$NE; $id++){
431
                my $phy= endp_addr_encoder($self,$id);
432
                my $hex = sprintf("0x%x", $phy);
433
                $txt=$txt."\t#define PHY_ADDR_ENDP_$id  $hex\n";
434
 
435
        }
436
 
437
 
438
        $txt=$txt."#endif\n";
439
        save_file($file,$txt);
440
}
441
 
442
 
443
 
444
1

powered by: WebSVN 2.1.0

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