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 43

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
                return (($y*$T1)+$x)*$T3+$l;
191
        }
192
}
193
 
194
sub mask_gen{
195
        my $k=shift;
196
        my $kw=0;
197
        my $mask=0;
198
        while((0x1<<$kw) < $k){
199
                $kw++;
200
                $mask<<=1;
201
                $mask|=0x1;
202
        }
203
        return $mask;
204
}
205
 
206
 
207
sub mesh_tori_addr_sep {
208
        my ($code,$NX, $NY,$NL)=@_;
209
        my ($x, $y, $l);
210
        my $NXw=log2($NX);
211
        my $NYw=log2($NY);
212
        $x = $code &  mask_gen($NX);
213
        $code>>=$NXw;
214
        $y = $code &   mask_gen($NY);
215
        $code>>=$NYw;
216
        $l = $code;
217
}
218
 
219
sub mesh_tori_addrencode{
220
        my ($id,$T1, $T2,$T3)=@_;
221
        my ($x,$y,$l)=mesh_tori_addrencod_sep($id,$T1,$T2,$T3);
222
    return mesh_tori_addr_join($x,$y,$l,$T1, $T2,$T3);
223
}
224
 
225
sub  mesh_tori_addrencod_sep{
226
        my ($id,$T1,$T2,$T3)=@_;
227
        my ($x,$y,$l);
228
        $l=$id % $T3; # id%NL
229
        my $R= int($id / $T3);
230
        $x= $R % $T1;# (id/NL)%NX
231
        $y=int($R / $T1);# (id/NL)/NX
232
        return ($x,$y,$l);
233
}
234
 
235
sub mesh_tori_addr_join {
236
        my ($x, $y, $l,$T1, $T2,$T3)=@_;
237
        my $NXw=log2($T1);
238
        my $NYw=log2($T2);
239
    my $addrencode=0;
240
    $addrencode =($T3==1)?   ($y << $NXw | $x) : ($l<<($NXw+$NYw)|  ($y << $NXw) | $x);
241
    return $addrencode;
242
}
243
 
244
 
245
 
246
 
247
 
248
sub get_noc_verilator_top_modules_info {
249
        my ($self) =@_;
250
 
251
        my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
252
        my $T1=$self->object_get_attribute('noc_param','T1');
253
        my $T2=$self->object_get_attribute('noc_param','T2');
254
        my $T3=$self->object_get_attribute('noc_param','T3');
255
 
256
        my %tops;
257
        my %nr_p; # number of routers have $p port num
258
        my $router_p; #number of routers with different port number in topology 
259
 
260
        my ($ne,$nr) =get_topology_info($self);
261
 
262
        if($topology eq '"FATTREE"') {
263
                my $K =  $T1;
264
        my $L =  $T2;
265
        my $p2 = 2*$K;
266
        $router_p=2;
267
        my $NRL= $ne/$K; #number of router in  each layer
268
        $nr_p{1}=$NRL;
269
        $nr_p{2}=$nr-$NRL;
270
        $nr_p{p1}=$K;
271
        $nr_p{p2}=2*$K;
272
 
273
        %tops = (
274
                        "Vrouter1" => "router_verilator_p${K}.v",
275
                        "Vrouter2" => "router_verilator_p${p2}.v",
276
                "Vnoc" => "noc_connection.sv",
277
 
278
        );
279
        }elsif ($topology eq '"TREE"'){
280
        my $K =  $T1;
281
        my $L =  $T2;
282
        my $p2 = $K+1;
283
        $router_p=2;# number of router with different port number                        
284
        $nr_p{1}=1;
285
        $nr_p{2}=$nr-1;
286
        $nr_p{p1}=$K;
287
        $nr_p{p2}=$K+1;
288
 
289
        %tops = (
290
                        "Vrouter1" => "router_verilator_p${K}.v",
291
                        "Vrouter2" => "router_verilator_p${p2}.v",
292
                "Vnoc" => "noc_connection.sv",
293
        );
294
 
295
        }elsif ($topology eq '"RING"' || $topology eq '"LINE"'){
296
 
297
                $router_p=1;
298
                $nr_p{1}=$nr;
299
                my $ports= 3+$T3-1;
300
                $nr_p{p1}=$ports;
301
                %tops = (
302
                        "Vrouter1" => "router_verilator_p${ports}.v",
303
                "Vnoc" => "noc_connection.sv",
304
 
305
        );
306
 
307
 
308
        }else {#mesh torus
309
 
310
        $router_p=1;
311
        $nr_p{1}=$nr;
312
        my $ports= 5+$T3-1;
313
                $nr_p{p1}=$ports;
314
        %tops = (
315
                        "Vrouter1" => "router_verilator_p${ports}.v",
316
                "Vnoc" => "noc_connection.sv",
317
 
318
        );
319
 
320
        }
321
 
322
        my $includ_h="\n";
323
        for (my $p=1; $p<=$router_p ; $p++){
324
                 $includ_h=$includ_h."#include \"Vrouter$p.h\" \n";
325
        }
326
        for (my $p=1; $p<=$router_p ; $p++){
327
                 $includ_h=$includ_h."#define NR${p} $nr_p{$p}\n";
328
                 $includ_h=$includ_h."Vrouter${p}               *router${p}[ $nr_p{$p} ];   // Instantiation of router with   port number\n";
329
        }
330
 
331
        for (my $p=1; $p<=$router_p ; $p++){
332
                $includ_h=$includ_h."
333
 
334
        #define NE  $ne
335
        #define NR  $nr
336
        #define ROUTER_P_NUM $router_p
337
 
338
        extern Vnoc                     *noc;
339
    extern int reset,clk;
340
 
341
 
342
 
343
void router${p}_connect_to_noc (unsigned int r, unsigned int n){
344
        unsigned int j;
345
        int flit_out_all_size = sizeof(router${p}[0]->flit_out_all)/sizeof(router${p}[0]->flit_out_all[0]);
346
        router${p}[r]->current_r_addr   = noc->current_r_addr[n];
347
        router${p}[r]->neighbors_r_addr         = noc->neighbors_r_addr[n];
348
 
349
 
350
        router${p}[r]->flit_in_we_all   = noc->router_flit_out_we_all[n];
351
        router${p}[r]->credit_in_all    = noc->router_credit_out_all[n];
352
        router${p}[r]->congestion_in_all        = noc->router_congestion_out_all[n];
353
        for(j=0;j<flit_out_all_size;j++)router${p}[r]->flit_in_all[j]   = noc->router_flit_out_all[n][j];
354
                noc->router_flit_in_we_all[n]   =       router${p}[r]->flit_out_we_all ;
355
                noc->router_credit_in_all[n]    =       router${p}[r]->credit_out_all;
356
                noc->router_congestion_in_all[n]=       router${p}[r]->congestion_out_all;
357
        for(j=0;j<flit_out_all_size;j++) noc->router_flit_in_all[n][j]  = router${p}[r]->flit_out_all[j] ;
358
}
359
";
360
        }
361
$includ_h=$includ_h."
362
void inline connect_all_routers_to_noc ( ){
363
        int i;
364
if((strcmp(TOPOLOGY ,\"FATTREE\")==0) || (strcmp(TOPOLOGY ,\"TREE\")==0) ){
365
                                for(i=0;i<NR1;i++) router1_connect_to_noc (i, i);
366
#if             ROUTER_P_NUM >1
367
                                for(i=0;i<NR2;i++) router2_connect_to_noc (i, i+NR1);
368
#endif
369
 
370
                        }else{
371
                                for (i=0;i<NR1;i++)     router1_connect_to_noc (i, i);
372
                        }
373
}
374
 
375
void Vrouter_new(){
376
        int i=0;
377
        for(i=0;i<NR1;i++)      router1[i]      = new Vrouter1;             // root nodes
378
#if             ROUTER_P_NUM >1
379
        for(i=0;i<NR2;i++)      router2[i]      = new Vrouter2;             // leaves
380
#endif
381
 
382
 
383
}
384
 
385
void inline connect_routers_reset_clk(){
386
        int i;
387
        for(i=0;i<NR1;i++) {
388
                router1[i]->reset= reset;
389
                router1[i]->clk= clk ;
390
        }
391
#if             ROUTER_P_NUM >1
392
        for(i=0;i<NR2;i++) {
393
                router2[i]->reset= reset;
394
                router2[i]->clk= clk ;
395
        }
396
#endif
397
}
398
 
399
 
400
void inline routers_eval(){
401
        int i=0;
402
        for(i=0;i<NR1;i++) router1[i]->eval();
403
#if             ROUTER_P_NUM >1
404
        for(i=0;i<NR2;i++) router2[i]->eval();
405
#endif
406
}
407
 
408
void inline routers_final(){
409
        int i;
410
        for(i=0;i<NR1;i++) router1[i]->final();
411
#if             ROUTER_P_NUM >1
412
                for(i=0;i<NR2;i++) router2[i]->final();
413
#endif
414
}
415
";
416
         return ($nr,$ne,$router_p,\%tops,$includ_h);
417
}
418
 
419
 
420
sub gen_tiles_physical_addrsses_header_file{
421
        my ($self,$file)=@_;
422
        my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
423
        my $txt = "#ifndef PHY_ADDR_H
424
        #define PHY_ADDR_H\n\n";
425
 
426
        #add phy addresses
427
        my ($NE, $NR, $RAw, $EAw)=get_topology_info($self);
428
        for (my $id=0; $id<$NE; $id++){
429
                my $phy= endp_addr_encoder($self,$id);
430
                my $hex = sprintf("0x%x", $phy);
431
                $txt=$txt."\t#define PHY_ADDR_ENDP_$id  $hex\n";
432
 
433
        }
434
 
435
 
436
        $txt=$txt."#endif\n";
437
        save_file($file,$txt);
438
}
439
 
440
 
441
 
442
1

powered by: WebSVN 2.1.0

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