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_verilog_gen.pl] - Blame information for rev 54

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

Line No. Rev Author Line
1 48 alirezamon
use strict;
2
use warnings;
3
 
4
use FindBin;
5
use lib $FindBin::Bin;
6
 
7
 
8
 
9
 
10
sub generate_topology_top_v {
11
        my ($self,$info,$dir)=@_;
12
 
13
 
14
        #create topology top file
15
        my $name=$self->object_get_attribute('save_as');
16
 
17
        my $r;
18
        my $top="$dir/${name}_noc.sv";
19
    open my $fd, ">$top" or $r = "$!\n";
20
    if(defined $r) {
21
        add_colored_info($info,"Error in creating $top: $r",'red');
22
                return;
23
    }
24
    print $fd autogen_warning();
25
    print $fd get_license_header($top);
26 54 alirezamon
        print $fd '
27
`include "pronoc_def.v"
28
';
29 48 alirezamon
 
30
    my $param_str ="\tparameter TOPOLOGY = \"$name\",
31
\tparameter ROUTE_NAME = \"${name}_DETERMINISTIC\"";
32
 
33
   my @parameters=@{$self->object_get_attribute ('Verilog','Router_param')};
34
   my @ports= @{$self->object_get_attribute('Verilog','Router_ports')};
35
 
36
#       foreach my $d (@parameters){
37
#               $param_str = $param_str.",\n\tparameter $d->{param_name} = $d->{value}";
38
#       }
39
 
40
    my @ends=get_list_of_all_endpoints($self);
41
    my @routers=get_list_of_all_routers($self);
42
 
43
    my $MAX_P=0;
44
    foreach my $p (@routers){
45
        my $Pnum=$self->object_get_attribute("$p",'PNUM');
46
        $MAX_P =$Pnum  if($Pnum>$MAX_P );
47
    }
48
 
49
    my $NE= scalar @ends;
50
    my $NR= scalar @routers;
51
 
52
 
53
 
54
 
55
 
56
        #step 2         add routers
57
        my @nodes=get_list_of_all_routers($self);
58
        my $i=0;
59
 
60
        my $ports="\treset,
61
\tclk";
62
        my $wires='',
63
        my $routers='';
64
 
65
        foreach my $p (@ends){
66
                my $instance= $self->object_get_attribute("$p","NAME");
67
                $ports=$ports.",\n\t//$instance";
68
                $wires=$wires."
69
        /*******************
70
        *               $instance
71
        *******************/
72
";
73
 
74
                $wires=$wires."\tinput  smartflit_chanel_t ${instance}_chan_in;\n";
75
                $wires=$wires."\toutput smartflit_chanel_t ${instance}_chan_out;\n";
76 54 alirezamon
                $wires=$wires."\toutput router_event_t ${instance}_router_event;\n";
77
                $ports=$ports.",\n\t${instance}_chan_in,\n\t${instance}_chan_out,\n\t${instance}_router_event";
78 48 alirezamon
 
79
                foreach my $d (@ports){
80
                                my $range = ($d->{pwidth} eq 1)? " " :  " [$d->{pwidth}-1 : 0]";
81
                                my $type=$d->{type};
82
                                my $ctype= ($type eq 'input')? 'output' : 'input';
83
                                if( $d->{endp} eq "yes"){
84
                                        #$wires=$wires."\t$type $range ${instance}_$d->{pname};\n";
85
                                        #$wires=$wires."\t$ctype $range ${instance}_$d->{pconnect};\n";
86
                                        #$ports=$ports.",\n\t${instance}_$d->{pname},\n\t${instance}_$d->{pconnect}";
87
                                }
88
                }
89
        }
90
 
91
 
92
        foreach my $p (@nodes){
93
 
94
                my ($wire,$router) = get_router_instance_v($self,$p,$i,$NE,$NR,$MAX_P);
95
                $wires=$wires.$wire,
96
                $routers=$routers.$router;
97
 
98
 
99
                $i++;
100
        }
101
 
102
        my $assign="";
103
        foreach my $p (@ends){
104
                my $instance= $self->object_get_attribute("$p","NAME");
105
                my $pname= "Port[0]";
106
                my $connect = $self->{$p}{'PCONNECT'}{$pname};
107
                if(defined $connect){
108
                        my ($cname,$pnode)=split(/\s*,\s*/,$connect);
109
                        my $cinstance= $self->object_get_attribute("$cname","NAME");
110
                        my ($cp)= sscanf("Port[%u]","$pnode");
111
                        #$assign = $assign."//Connect $instance output ports 0 to  $cinstance input ports $cp\n";
112
                        my $cpplus=$cp+1;
113
 
114
 
115
                        foreach my $p (@ports){
116
                                my $w=$p->{pwidth};
117
                                my $range = ($w eq 1)?  " " : "[$w-1 :           0 ]";
118
                                my $crange = ($w eq 1)? "[$cp]" : "[($cpplus*$w)-1 :     $cp*$w ]";
119
                                my $cport =  "${cinstance}_$p->{connect}";
120
                                my $port ="${instance}_$p->{pconnect}";
121
                                if($p->{type} eq 'input' ){
122
                                        # $assign=  $assign."\t\tassign  $port $range = $cport $crange;\n" if($p->{endp} eq "yes");             
123
                                }else{
124
                                        # $assign=  $assign."\t\tassign  $cport $crange= $port $range;\n" if($p->{endp} eq "yes");              
125
                                }
126
 
127
                         }      #@port
128
                }
129
 
130
        }
131
 
132
 
133
 
134
 
135
         print $fd "
136
module   ${name}_noc
137
        import pronoc_pkg::*;
138
        (
139
   $ports
140
);
141
 
142
         function integer log2;
143
      input integer number; begin
144
         log2=(number <=1) ? 1: 0;
145
         while(2**log2<number) begin
146
            log2=log2+1;
147
         end
148
      end
149
    endfunction // log2
150
 
151
        localparam
152
                NE = $NE,
153
                NR = $NR,
154
                RAw=log2(NR);
155
 
156
 
157
 
158
 
159
    input reset,clk;
160
 
161
    $wires
162
 
163
    $routers
164
 
165
    $assign
166
 
167
endmodule
168
";
169
        add_info($info,"$top file is created\n  ");
170
        close $fd;
171
 
172
 
173
}
174
 
175
 
176
 
177
 
178
sub get_router_instance_v {
179
        my ($self,$rname,$current_r,$NE,$NR,$MAX_P)=@_;
180
 
181
 
182
        my $instance= $self->object_get_attribute("$rname","NAME");
183
        my $Pnum=$self->object_get_attribute("$rname",'PNUM');
184
 
185
        #read ruter parameters and ports
186
         my @parameters=@{$self->object_get_attribute ('Verilog','Router_param')};
187
     my @ports= @{$self->object_get_attribute('Verilog','Router_ports')};
188
 
189
        my $wires_v="
190
        /*******************
191
        *               $instance
192
        *******************/
193
\twire ${instance}_clk;
194
\twire ${instance}_reset;
195
 
196
\twire [RAw-1 :  0] ${instance}_current_r_addr;
197
 
198
\tsmartflit_chanel_t    ${instance}_chan_in   [$Pnum-1 : 0];
199
\tsmartflit_chanel_t    ${instance}_chan_out  [$Pnum-1 : 0];
200 54 alirezamon
\trouter_event_t ${instance}_router_event [$Pnum-1 : 0];
201 48 alirezamon
 
202
";
203
 
204
 
205
 
206
 
207
        my $router_v="
208
        /*******************
209
        *               $instance
210
        *******************/
211
        router_top #(
212
                .P($Pnum)
213
        )
214
        $instance
215
        (
216
                .clk(${instance}_clk),
217
                .reset(${instance}_reset),
218 54 alirezamon
                .current_r_id($current_r),
219 48 alirezamon
                .current_r_addr  (${instance}_current_r_addr),
220
                .chan_in   (${instance}_chan_in),
221 54 alirezamon
                .chan_out  (${instance}_chan_out),
222
                .router_event (${instance}_router_event)
223 48 alirezamon
        );
224
";
225
 
226
 
227
$router_v= $router_v."
228
\t\tassign ${instance}_clk = clk;
229
\t\tassign ${instance}_reset = reset;
230
\t\tassign ${instance}_current_r_addr = $current_r;
231
";
232
 
233
 
234
 
235
 
236
for (my $i=0;$i<$Pnum; $i++){
237
        my $pname= "Port[${i}]";
238
        my $connect = $self->{$rname}{'PCONNECT'}{$pname};
239
        my $iplus=$i+1;
240
        if(defined $connect){
241
                my ($cname,$pnode)=split(/\s*,\s*/,$connect);
242
                my $cinstance= $self->object_get_attribute("$cname","NAME");
243
                my $ctype = $self->object_get_attribute("$cname",'TYPE');
244
                my ($cp)= sscanf("Port[%u]","$pnode");
245
                $router_v = $router_v."//Connect $instance port $i to  $cinstance port $cp\n";
246
                if($ctype ne 'ENDP'){
247
                        $router_v.=" \t\tassign ${instance}_chan_in [$i]   = ${cinstance}_chan_out [$cp];\n";
248
                }else{
249
                        $router_v.=" \t\tassign ${instance}_chan_in [$i]  = ${cinstance}_chan_in;\n";
250
                        $router_v.=" \t\tassign ${cinstance}_chan_out = ${instance}_chan_out [$i];\n";
251 54 alirezamon
                        $router_v.=" \t\tassign ${cinstance}_router_event = ${instance}_router_event [$i];\n";
252
 
253 48 alirezamon
                }
254
                my $cpplus=$cp+1;
255
 
256
                #{name=> "flit_in_all", type=>"input", width=>"PFw", connect=>"flit_out_all",  pwidth=>"Fw" },
257
 
258
 
259
 
260
                foreach my $p (@ports){
261
                        my $w=$p->{pwidth};
262
                        my $range = ($w eq 1)?  "[$i]" : "[($iplus*$w)-1 :               $i*$w ]";
263
                        my $crange = ($ctype eq 'ENDP') ? '' :
264
                        ($w eq 1)? "[$cp]"      : "[($cpplus*$w)-1 :     $cp*$w ]";
265
                        my $cport = ($ctype eq 'ENDP') ? "${cinstance}_$p->{pname}" : "${cinstance}_$p->{connect}";
266
                        my $port ="${instance}_$p->{name}";
267
                        if($ctype eq 'ENDP' && $p->{endp} eq "no" && $p->{type} eq 'input' ){
268
                                # $router_v=  $router_v."\t\tassign  $port $range = 0;\n";              
269
 
270
                        }else{
271
                                if($p->{type} eq 'input' ){
272
                                # $router_v=  $router_v."\t\tassign  $port $range = $cport $crange;\n";         
273
                                }else{
274
                                # $router_v=  $router_v."\t\tassign  $cport $crange= $port $range;\n";  
275
                                }
276
                        }
277
                 }      #@port
278
 
279
        }else {
280
                        $router_v = $router_v."//Connect $instance port $i to  ground
281 52 alirezamon
\t      assign  ${instance}_chan_in [$i]= {SMARTFLIT_CHANEL_w{1'b0}};\n";
282 48 alirezamon
 
283
                        foreach my $p (@ports){
284
                                my $w=$p->{pwidth};
285
                                my $range = ($w eq 1)?  "[$i]" : "[($iplus*$w)-1 :               $i*$w ]";
286
                                if($p->{type} eq 'input' ){
287
                                #       $router_v=  $router_v."\t\tassign  ${instance}_$p->{name} $range = \{$w\{1'b0\}\};\n";          
288
                                }
289
                        }
290
        }
291
 
292
}
293
 
294
 
295
        return ($wires_v,$router_v);
296
}
297
 
298
 
299
 
300
#*******************
301
#       generate_topology_top_genvar_v
302
#********************
303
 
304
 
305
sub generate_topology_top_genvar_v{
306
        my ($self,$info,$dir)=@_;
307
 
308
 
309
        #create topology top file
310
        my $name=$self->object_get_attribute('save_as');
311
        my $r;
312
        my $top="$dir/${name}_noc_genvar.sv";
313
    open my $fd, ">$top" or $r = "$!\n";
314
    if(defined $r) {
315
        add_colored_info($info,"Error in creating $top: $r",'red');
316
                return;
317
    }
318
    print $fd autogen_warning();
319
    print $fd get_license_header($top);
320 54 alirezamon
        print $fd '
321
`include "pronoc_def.v"
322
';
323 48 alirezamon
 
324
    my $param_str ="\tparameter TOPOLOGY = \"$name\",
325
\tparameter ROUTE_NAME = \"${name}_DETERMINISTIC\"";
326
 
327
   my @parameters=@{$self->object_get_attribute ('Verilog','Router_param')};
328
   my @ports= @{$self->object_get_attribute('Verilog','Router_ports')};
329
 
330
        foreach my $d (@parameters){
331
                $param_str = $param_str.",\n\tparameter $d->{param_name} = $d->{value}";
332
        }
333
 
334
    my @ends=get_list_of_all_endpoints($self);
335
    my @routers=get_list_of_all_routers($self);
336
 
337
    my $MAX_P=0;
338
    foreach my $p (@routers){
339
        my $Pnum=$self->object_get_attribute("$p",'PNUM');
340
        $MAX_P =$Pnum  if($Pnum>$MAX_P );
341
    }
342
 
343
    my $NE= scalar @ends;
344
    my $NR= scalar @routers;
345
 
346
 
347
 
348
        my @nodes=get_list_of_all_routers($self);
349
        my $i=0;
350
 
351
        my $ports="\treset,
352
\tclk,
353
\tchan_in_all,
354 54 alirezamon
\tchan_out_all,
355
\trouter_event
356 48 alirezamon
";
357
    my $ports_def="
358
\tinput  reset;
359
\tinput  clk;
360
\tinput  smartflit_chanel_t chan_in_all  [NE-1 : 0];
361
\toutput smartflit_chanel_t chan_out_all [NE-1 : 0];
362
 
363 54 alirezamon
//Events
364
\toutput  router_event_t  router_event [NR-1 : 0][MAX_P-1 : 0];
365
 
366 48 alirezamon
//all routers port
367
\tsmartflit_chanel_t    router_chan_in   [NR-1 :0][MAX_P-1 : 0];
368
\tsmartflit_chanel_t    router_chan_out  [NR-1 :0][MAX_P-1 : 0];
369
 
370 54 alirezamon
 
371 48 alirezamon
\twire [RAw-1 : 0] current_r_addr [NR-1 : 0];
372
 
373
 
374
";
375
 
376
        my $router_wires="";
377
        my $endps_wires="";
378
 
379
 
380
 
381
 
382
        foreach my $d (@ports){
383
                my $range = ($d->{width} eq 1)? " " :  " [$d->{width}-1 : 0]";
384
                my $pdef_range = ($d->{pwidth} eq 1)? "[NE-1 : 0]" : "[(NE*$d->{pwidth})-1 : 0]";
385
                my $endp_range = "[$d->{pwidth}-1 : 0]";
386
                my $type=$d->{type};
387
                my $ctype= ($type eq 'input')? 'output' : 'input';
388
                if( $d->{endp} eq "yes"){
389
                        #$ports_def=$ports_def."\t$type $pdef_range $d->{name};\n";
390
                        #$ports_def=$ports_def."\t$ctype $pdef_range $d->{connect};\n";                 
391
                        #$ports=$ports.",\n\t$d->{name},\n\t$d->{connect}";
392
                }
393
                        if($d->{width} eq 1){
394
                                #$router_wires=$router_wires. "\twire [NR-1 :0] router_$d->{name};\n";
395
                                #$router_wires=$router_wires. "\twire [NR-1 :0] router_$d->{connect};\n";
396
                        }else{
397
                                #$router_wires=$router_wires. "\twire $range router_$d->{name} [NR-1 :0];\n";
398
                                #$router_wires=$router_wires. "\twire $range router_$d->{connect} [NR-1 :0];\n";
399
                        }
400
                if( $d->{endp} eq "yes"){
401
                    if($d->{pwidth} eq 1){
402
                        #$endps_wires=$endps_wires. "\twire [NE-1 :0] ni_$d->{pname};\n";
403
                                #$endps_wires=$endps_wires. "\twire [NE-1 :0] ni_$d->{pconnect};\n";
404
                    }else{
405
                                #$endps_wires=$endps_wires. "\twire $endp_range ni_$d->{pname} [NE-1 :0];\n";
406
                                #$endps_wires=$endps_wires. "\twire $endp_range ni_$d->{pconnect} [NE-1 :0];\n";
407
                    }
408
 
409
                }
410
        }
411
 
412
 
413
 
414
 
415
        #step 2         add routers
416
        my $Tnum=1;
417
 
418
        my $routers='
419
        genvar i;
420
        generate
421
        ';
422
        my $offset=0;
423
        my $assign="";
424 54 alirezamon
        my $assign_r2r="";
425
        my $assign_r2e="";
426 48 alirezamon
        my $init_h="";
427 54 alirezamon
        my $init_gnd_h="";
428 48 alirezamon
        my %new_h;
429
        my $addr=0;
430
        for ( my $i=2;$i<=12; $i++){
431
                my $n= $self->object_get_attribute("ROUTER${i}","NUM");
432
                $n=0 if(!defined $n);
433
                if($n>0){
434
 
435
                        for(my $rr=0; $rr<$n; $rr=$rr+1) {
436
                                my $pos= ($offset==0)? $rr : $rr+$offset;
437
                                $new_h{"TNUM_${pos}"}="$Tnum";
438
                                $new_h{"RNUM_${pos}"}="$rr";
439
 
440
                                $init_h.="router${Tnum}[$rr]->current_r_addr=$addr;\n";
441 54 alirezamon
                                $init_h.="router${Tnum}[$rr]->current_r_id=$addr;\n";
442 48 alirezamon
                                $addr++;
443
                        }
444
                        $offset+=       $n;
445
                        $Tnum++;
446
                }
447
        }
448
 
449
 
450
 
451
 
452
 
453
 
454
 
455
        $offset=0;
456 54 alirezamon
        my $R_num=0;
457 48 alirezamon
        for ( my $i=2;$i<=12; $i++){
458
                my $n= $self->object_get_attribute("ROUTER${i}","NUM");
459
                $n=0 if(!defined $n);
460
                if($n>0){
461
                        my $router_pos= ($offset==0)? 'i' : "i+$offset";
462
                        #my $instant=get_router_genvar_instance_v($self,$i,$router_pos,$NE,$NR,$MAX_P);
463 54 alirezamon
                        my $p = $i-1;
464 48 alirezamon
                        $routers=$routers."
465
\tfor( i=0; i<$n; i=i+1) begin : router_${i}_port_lp
466 54 alirezamon
        localparam RID = $router_pos;
467
        assign current_r_addr [RID] = RID[RAw-1: 0];
468 48 alirezamon
 
469
        router_top #(
470
                .P($i)
471
        )
472
        router_${i}_port
473
        (
474
                .clk(clk),
475
                .reset(reset),
476 54 alirezamon
                .current_r_id(RID),
477
                .current_r_addr(current_r_addr\[RID\]),
478
                .chan_in  (router_chan_in \[RID\] \[$p : 0\]),
479
                .chan_out (router_chan_out\[RID\] \[$p : 0\]),
480
                .router_event(router_event\[RID\] \[$p : 0\])
481 48 alirezamon
        );
482
 
483
 
484
 
485
\tend
486
                        ";
487
 
488
                        for ( my $j=0;$j<$n; $j++){
489
                                my $rname ="ROUTER${i}_$j";
490 54 alirezamon
                                my ($ass_v,$r2r_h,$r2e_h, $int_h,$gnd_h);
491
                                ($ass_v,$r2r_h,$r2e_h, $int_h,$gnd_h,$R_num) = get_wires_assignment_genvar_v($self,$rname,0,\%new_h,$R_num);
492 48 alirezamon
 
493
                                $assign=$assign.$ass_v;
494 54 alirezamon
                                $assign_r2r.=$r2r_h;
495
                                $assign_r2e.=$r2e_h;
496
                                $init_h.=$int_h;
497
                                $init_gnd_h.=$gnd_h;
498 48 alirezamon
                        }
499
 
500
                $offset+=       $n;
501
 
502
                }
503
        }
504
 
505
 
506
$routers.="endgenerate\n";
507
 
508
 
509
 
510
 
511
 
512
 
513
         print $fd "
514
module   ${name}_noc_genvar
515
   import pronoc_pkg::*;
516
        (
517
 
518
    reset,
519
    clk,
520
    chan_in_all,
521 54 alirezamon
    chan_out_all,
522
    router_event
523 48 alirezamon
);
524
 
525
         function integer log2;
526
      input integer number; begin
527
         log2=(number <=1) ? 1: 0;
528
         while(2**log2<number) begin
529
            log2=log2+1;
530
         end
531
      end
532
    endfunction // log2
533
 
534
        localparam
535
                NE = $NE,
536
                NR = $NR,
537
                RAw=log2(NR),
538
                MAX_P=$MAX_P;
539
 
540
 
541
$ports_def
542
 
543
$router_wires
544
 
545
$endps_wires
546
 
547
$routers
548
 
549
$assign
550
 
551
 
552
 
553
endmodule
554
";
555
 
556
        close $fd;
557
        add_info($info,"$top file is created\n  ");
558
 
559
        my $project_dir = get_project_dir();
560
        $project_dir= "$project_dir/mpsoc";
561
        my $src_verilator_dir="$project_dir/src_verilator/topology/custom";
562
        mkpath("$src_verilator_dir",1,01777) unless -f $src_verilator_dir;
563
    $top="$src_verilator_dir/${name}_noc.h";
564
    open $fd, ">$top" or $r = "$!\n";
565
    if(defined $r) {
566
        add_colored_info($info,"Error in creating $top: $r",'red');
567
                return;
568
    }
569 54 alirezamon
 
570
  my $fr2r="";
571
  for (my $i=0;$i<$R_num ; $i++){
572
        $fr2r.="\n" if($i%10==0);
573
        $fr2r.=($i==0) ? "single_r2r$i" : ",single_r2r$i";
574
 
575
  }
576
 
577
  my $fr2e="";
578
  for (my $i=0;$i<$NE ; $i++){
579
        $fr2e.="\n" if($i%10==0);
580
        $fr2e.=($i==0) ? "single_r2e$i" : ",single_r2e$i";
581
  }
582
 
583
 
584 48 alirezamon
    print $fd "
585
 
586
 
587 54 alirezamon
$assign_r2r
588 48 alirezamon
 
589 54 alirezamon
$assign_r2e
590
 
591
 
592
void (*r2r_func_ptr[$R_num])() = {$fr2r};
593
void (*r2e_func_ptr[$NE])() = {$fr2e};
594
 
595
void topology_connect_r2r (int n){
596
         (*r2r_func_ptr[n])();
597 48 alirezamon
}
598
 
599 54 alirezamon
void topology_connect_r2e (int n){
600
         (*r2e_func_ptr[n])();
601
}
602
 
603
 
604
 
605 48 alirezamon
void topology_init(void){
606
        $init_h
607 54 alirezamon
        R2R_TABLE_SIZ=$R_num;
608
        $init_gnd_h
609 48 alirezamon
}
610
";
611
    close $fd;
612
        add_info($info,"$top file is created\n  ");
613
 
614
}
615
 
616
 
617
 
618
 
619
sub get_router_genvar_instance_v{
620
        my ($self,$Pnum,$router_pos,$NE,$NR,$MAX_P)=@_;
621
 
622
        #read ruter parameters and ports
623
        my @parameters=@{$self->object_get_attribute ('Verilog','Router_param')};
624
    my @ports= @{$self->object_get_attribute('Verilog','Router_ports')};
625
 
626
 
627
 
628
        my $router_v="
629
 
630
        router_top #(
631
                .P($Pnum)
632
        )
633
        router_${Pnum}_port
634
        (
635
                .clk(clk),
636
                .reset(reset),
637
                .current_r_addr($router_pos),
638 54 alirezamon
                .current_r_id($router_pos),
639 48 alirezamon
                .chan_in (router_chan_in\[$router_pos\]),
640 54 alirezamon
                .chan_out(router_chan_out\[$router_pos\]),
641
                .router_event(router_event\[$router_pos\])
642 48 alirezamon
        );
643
 
644
 
645
 
646
";
647
 
648
return $router_v;
649
 
650
 
651
}
652
 
653
 
654
sub get_wires_assignment_genvar_v{
655 54 alirezamon
        my ($self,$rname,$reverse,$cref,$R_num)=@_;
656 48 alirezamon
    $reverse = 0 if(!defined $reverse);
657
        my $instance= $self->object_get_attribute("$rname","NAME");
658
        my $Pnum=$self->object_get_attribute("$rname",'PNUM');
659
 
660
        #read ruter parameters and ports
661
         my @parameters=@{$self->object_get_attribute ('Verilog','Router_param')};
662
     my @ports= @{$self->object_get_attribute('Verilog','Router_ports')};
663
 
664
        my $assign="";
665 54 alirezamon
        my $r2e_h="";
666
        my $r2r_h="";
667
        my $init_h="";
668
        my $gnd_h="";
669
 
670
 
671 48 alirezamon
 
672
        my @ends=get_list_of_all_endpoints($self);
673
    my @routers=get_list_of_all_routers($self);
674
 
675
        my $pos = get_scolar_pos($rname,@routers);
676
        my $type = "ROUTER";
677
        if(!defined $pos){
678
                $pos = get_scolar_pos($rname,@ends);
679
                $type = "ENDP";
680
        }
681
 
682
        my %rinfo = %{$cref} if (defined $cref);
683
 
684
for (my $i=0;$i<$Pnum; $i++){
685
        my $pname= "Port[${i}]";
686
        my $connect = $self->{$rname}{'PCONNECT'}{$pname};
687
        my $iplus=$i+1;
688
        if(defined $connect){
689
                my ($cname,$pnode)=split(/\s*,\s*/,$connect);
690
                my $cinstance= $self->object_get_attribute("$cname","NAME");
691
                my $ctype = $self->object_get_attribute("$cname",'TYPE');
692
                my ($cp)= sscanf("Port[%u]","$pnode");
693
                $assign.="//Connect $instance input ports $i to  $cinstance output ports $cp\n";
694
 
695 54 alirezamon
 
696 48 alirezamon
                my $cpos =($ctype eq 'ENDP')?  get_scolar_pos($cname,@ends) :  get_scolar_pos($cname,@routers);
697
 
698
                my $cpplus=$cp+1;
699
                my $cposplus = $cpos+1;
700
                my $posplus=$pos+1;
701
                #{name=> "flit_in_all", type=>"input", width=>"PFw", connect=>"flit_out_all",  pwidth=>"Fw" },
702
 
703
                my $TNUM_pos  = $rinfo{"TNUM_${pos}"};
704
                my $RNUM_pos  = $rinfo{"RNUM_${pos}"};
705
                my $TNUM_cpos = $rinfo{"TNUM_${cpos}"};
706
                my $RNUM_cpos = $rinfo{"RNUM_${cpos}"};
707
 
708
                #$assign = $assign."//connet  $instance input port $i to  $cinstance output port $cp\n";
709
                if($type  ne 'ENDP'  &&  $ctype eq 'ENDP'){
710 54 alirezamon
 
711 48 alirezamon
                        $assign=  $assign."\t\tassign  router_chan_in \[$pos\]\[$i\] = chan_in_all \[$cpos\];\n" if($reverse==0);
712
                        $assign=  $assign."\t\tassign  chan_in_all \[$cpos\] = router_chan_in \[$pos\]\[$i\];\n" if($reverse==1);
713
 
714
                        $assign=  $assign."\t\tassign  chan_out_all \[$cpos\] = router_chan_out \[$pos\]\[$i\];\n" if($reverse==0);
715
                        $assign=  $assign."\t\tassign  router_chan_out \[$pos\]\[$i\] = chan_out_all \[$cpos\];\n" if($reverse==1);
716
 
717 54 alirezamon
                        $r2e_h.="//Connect $instance input ports $i to  $cinstance output ports $cp\n";
718
                        $r2e_h.=  "void single_r2e$cpos(void) {connect_r2e($TNUM_pos,$RNUM_pos,$i,$cpos);}\n"   if (defined $TNUM_pos);
719 48 alirezamon
 
720
 
721
                }elsif ($type  ne 'ENDP'  &&  $ctype ne 'ENDP'){
722
                        $assign=  $assign."\t\tassign  router_chan_in \[$pos\]\[$i\] = router_chan_out \[$cpos\]\[$cp\];\n" if($reverse==0);
723
                        $assign=  $assign."\t\tassign  router_chan_out \[$cpos\]\[$cp\] = router_chan_in \[$pos\]\[$i\];\n" if($reverse==1);
724 54 alirezamon
                        $r2r_h.="//Connect $instance input ports $i to  $cinstance output ports $cp\n";
725
                        $r2r_h.=  "void single_r2r$R_num(void){conect_r2r($TNUM_pos,$RNUM_pos,$i,$TNUM_cpos,$RNUM_cpos,$cp);}\n" if (defined $TNUM_pos);
726
                        $init_h.="\tr2r_cnt_all[$R_num] =(r2r_cnt_table_t){.id1=$pos, .t1=$TNUM_pos, .r1=$RNUM_pos, .p1=$i,.id2=$cpos, .t2=$TNUM_cpos, .r2=$RNUM_cpos, .p2=$cp };\n";
727
                        $R_num++;
728 48 alirezamon
                }
729
 
730
 
731
 
732
 
733
 
734
        }else {
735
                        my $TNUM_pos  = $rinfo{"TNUM_${pos}" };
736
                        my $RNUM_pos  = $rinfo{"RNUM_${pos}" };
737
 
738 54 alirezamon
                        $assign = $assign."//Connect $instance port $i to  ground\n";
739 52 alirezamon
                        $assign=  $assign."\t\tassign  router_chan_in  \[$pos\]\[$i\] ={SMARTFLIT_CHANEL_w{1'b0}};\n    " if($reverse==0);
740
                        $assign=  $assign."\t\tassign  router_chan_out \[$pos\]\[$i\] ={SMARTFLIT_CHANEL_w{1'b0}};\n    " if($reverse==1);
741 54 alirezamon
 
742
                        $gnd_h.="//Connect $instance port $i to  ground\n";
743
                        $gnd_h.=  "\tconnect_r2gnd($TNUM_pos,$RNUM_pos,$i);\n" if (defined $TNUM_pos);
744 48 alirezamon
        }
745
 
746
}
747
 
748 54 alirezamon
 
749
 
750
        return ($assign,$r2r_h,$r2e_h,$init_h,$gnd_h,$R_num);
751 48 alirezamon
}
752
 
753
 
754
 
755
 
756
 
757
sub generate_routing_v {
758
        my ($self,$info,$dir)=@_;
759
 
760
        my @ends=get_list_of_all_endpoints($self);
761
        my @routers=get_list_of_all_routers($self);
762
 
763
#########################       
764
#  conventional_routing
765
#########################
766
 
767
 
768
        #create routing file
769
        my $name=$self->object_get_attribute('save_as');
770
        my $rname=$self->object_get_attribute('routing_name');
771
        my $Vname="T${name}R${rname}";
772
 
773
        my $r;
774
        my $top="$dir/${Vname}_conventional_routing.v";
775
    open my $fd, ">$top" or $r = "$!\n";
776
    if(defined $r) {
777
        add_colored_info($info,"Error in creating $top: $r",'red');
778
                return;
779
    }
780
    print $fd autogen_warning();
781
    print $fd get_license_header($top);
782
 
783
 
784
 
785
 
786
 
787
        my $route_str="\talways@(*)begin
788
\t\tdestport=0;
789
\t\tcase(src_e_addr) //source address of each individual NI is fixed. So this CASE will be optimized by the synthesizer for each endpoint.
790
";
791
 
792
        foreach my $src (@ends){
793
                my $PNUM=$self->object_get_attribute($src,"PNUM");
794
                my $src_num=get_scolar_pos($src,@ends);
795
            my %route;
796
                $route_str=$route_str."\t\t$src_num: begin
797
\t\t\tcase(dest_e_addr)
798
";
799
 
800
                foreach my $dst (@ends){
801
                            my $dest_num = get_scolar_pos($dst,@ends);
802
                                my $ref = $self->object_get_attribute('Route',"${src}::$dst");
803
                                next if(!defined $ref);
804
                                my @path = @{$ref};
805
                                my ($p1,$p2)= get_connection_port_num_between_two_nodes($self,$path[1],$path[2] );
806
                                #print " ($p1,$p2)= get_connection_port_num_between_two_nodes($self,$path[1],$path[2] );\n";
807
                                $route{$p1} = (defined $route{$p1})? $route{$p1}.",$dest_num" : "$dest_num";
808
                }
809
                foreach my $q (sort {$a <=> $b} keys %route){
810
                        $route_str=$route_str."\t\t\t$route{$q}: begin
811
\t\t\t\tdestport= $q;
812
\t\t\tend
813
";
814
                }
815
                $route_str=$route_str."
816
\t\t\tdefault: begin
817
\t\t\t\tdestport= {DSTPw{1\'bX}};
818
\t\t\tend
819
\t\t\tendcase\n\t\tend//$src_num\n";
820
        }
821
        $route_str=$route_str."
822
\t\tdefault: begin
823
\t\t\tdestport= {DSTPw{1\'bX}};
824
\t\tend
825
\t\tendcase\n\tend\n";
826
 
827
 
828
 
829
         print $fd "module ${Vname}_conventional_routing  #(
830
\tparameter RAw = 3,
831
\tparameter EAw = 3,
832
\tparameter DSTPw=4
833
)
834
(
835
\tdest_e_addr,
836
\tsrc_e_addr,
837
\tdestport
838
);
839
 
840
\tinput   [EAw-1   :0] dest_e_addr;
841
\tinput   [EAw-1   :0] src_e_addr;
842
\toutput reg [DSTPw-1 :0] destport;
843
 
844
 
845
$route_str
846
 
847
 
848
endmodule
849
 
850
";
851
close($fd);
852
add_info($info,"$top file is created\n  ");
853
 
854
##################
855
#   look_ahead_routing
856
###################
857
 
858
#create routing file
859
        $top="$dir/${Vname}_look_ahead_routing.v";
860
    open  $fd, ">$top" or $r = "$!\n";
861
    if(defined $r) {
862
        add_colored_info($info,"Error in creating $top: $r",'red');
863
                return;
864
    }
865
    print $fd autogen_warning();
866
    print $fd get_license_header($top);
867
 
868
 
869
        $route_str="\talways@(*)begin
870
\t\tdestport=0;
871
\t\tcase(current_r_addr) //current_r_addr of each individual router is fixed. So this CASE will be optimized by the synthesizer for each router.
872
";
873
 
874
 
875
 
876
foreach my $router (@routers){
877
                my $PNUM=$self->object_get_attribute($router,"PNUM");
878
                my $router_num=get_scolar_pos($router,@routers);
879
            my %route;
880
                $route_str=$route_str."\t\t$router_num: begin
881
\t\t\tcase({src_e_addr,dest_e_addr})
882
";
883
        # for each src-dest check if $router include in path 
884
        foreach my $src (@ends){
885
                foreach my $dst (@ends){
886
                        my $ref = $self->object_get_attribute('Route',"${src}::$dst");
887
                        next if(!defined $ref);
888
                        my @path = @{$ref};
889
                    my $loc= get_scolar_pos($router,@path);
890
                    next if(!defined $loc);# this router does not exist in path skip it
891
                    my $next_router1=$path[$loc+1];
892
                    my $next_router2=$path[$loc+2];
893
                    next if(!defined $next_router2);
894
                    my ($p1,$p2)= get_connection_port_num_between_two_nodes($self,$next_router1,$next_router2);
895
                    next if(!defined $p1);
896
                    my $src_num=get_scolar_pos($src,@ends);
897
                    my $dest_num = get_scolar_pos($dst,@ends);
898
                        $route{$p1} = (defined $route{$p1})? $route{$p1}.",{E$src_num,E$dest_num}" : "{E$src_num,E$dest_num}";
899
 
900
                        #print "@path\n";
901
                        #print "(current_router, next_router1, next_router2)=($router, $next_router1, $next_router2)\n";
902
                        #print "($p1,$p2)= get_connection_port_num_between_two_nodes(\$self,$next_router1,$next_router2)\n";    
903
                        #print "\$route{$p1} ={E$src_num,E$dest_num}\n";
904
                        #print"***************************\n"; 
905
 
906
                }
907
        }
908
        foreach my $q (sort {$a <=> $b} keys %route){
909
                        $route_str=$route_str."\t\t\t$route{$q}: begin
910
\t\t\t\tdestport= $q;
911
\t\t\tend
912
";
913
 
914
        }
915
 
916
        $route_str.="\t\t\tdefault: begin
917
\t\t\t\tdestport= {DSTPw{1\'bX}};
918
\t\t\tend
919
\t\t\tendcase\n\t\tend//$router_num\n";
920
        }
921
$route_str.="\t\tdefault: begin
922
\t\t\tdestport= {DSTPw{1\'bX}};
923
\t\tend
924
\t\tendcase\n\tend\n";
925
 
926
 
927
 
928
my $localparam="";
929
        my $i=0;
930
        foreach my $src (@ends){
931
                $localparam= $localparam."localparam [EAw-1 : 0]\tE$i=$i;\n";
932
                $i++;
933
        }
934
 
935
 
936
 
937
 
938
 print $fd "
939 54 alirezamon
 
940
 `include \"pronoc_def.v\"
941 48 alirezamon
/*******************
942
*  ${Vname}_look_ahead_routing
943
*******************/
944
module ${Vname}_look_ahead_routing  #(
945
\tparameter RAw = 3,
946
\tparameter EAw = 3,
947
\tparameter DSTPw=4
948
)
949
(
950
\treset,
951
\tclk,
952
\tcurrent_r_addr,
953
\tdest_e_addr,
954
\tsrc_e_addr,
955
\tdestport
956
);
957
 
958
\tinput   [RAw-1   :0] current_r_addr;
959
\tinput   [EAw-1   :0] dest_e_addr;
960
\tinput   [EAw-1   :0] src_e_addr;
961
\toutput  [DSTPw-1 :0] destport;
962
\tinput reset,clk;
963
 
964
        reg [EAw-1   :0] dest_e_addr_delay;
965
        reg [EAw-1   :0] src_e_addr_delay;
966
 
967 54 alirezamon
        always @ (`pronoc_clk_reset_edge )begin
968
        if(`pronoc_reset)begin
969 48 alirezamon
                        dest_e_addr_delay<={EAw{1'b0}};
970
                        src_e_addr_delay<={EAw{1'b0}};
971
                end else begin
972
                        dest_e_addr_delay<=dest_e_addr;
973
                        src_e_addr_delay<=src_e_addr;
974
                end
975
        end
976
 
977
        ${Vname}_look_ahead_routing_comb  #(
978
                .RAw(RAw),
979
                .EAw(EAw),
980
                .DSTPw(DSTPw)
981
        )
982
        lkp_cmb
983
        (
984
                .current_r_addr(current_r_addr),
985
                .dest_e_addr(dest_e_addr_delay),
986
                .src_e_addr(src_e_addr_delay),
987
                .destport(destport)
988
        );
989
 
990
 
991
 
992
endmodule
993
 
994
/*******************
995
*  ${Vname}_look_ahead_routing_comb
996
*******************/
997
 
998
 module ${Vname}_look_ahead_routing_comb  #(
999
\tparameter RAw = 3,
1000
\tparameter EAw = 3,
1001
\tparameter DSTPw=4
1002
)
1003
(
1004
\tcurrent_r_addr,
1005
\tdest_e_addr,
1006
\tsrc_e_addr,
1007
\tdestport
1008
);
1009
 
1010
\tinput   [RAw-1   :0] current_r_addr;
1011
\tinput   [EAw-1   :0] dest_e_addr;
1012
\tinput   [EAw-1   :0] src_e_addr;
1013
\toutput reg [DSTPw-1 :0] destport;
1014
 
1015
$localparam
1016
 
1017
$route_str
1018
 
1019
 
1020
endmodule
1021
 
1022
 
1023
";
1024
 
1025
close($fd);
1026
add_info($info,"$top file is created\n  ");
1027
 
1028
#########################       
1029
#  conventional_routing_genvar
1030
#########################
1031
 
1032
 
1033
        #create routing file
1034
        $top="$dir/${Vname}_conventional_routing_genvar.v";
1035
    open $fd, ">$top" or $r = "$!\n";
1036
    if(defined $r) {
1037
        add_colored_info($info,"Error in creating $top: $r",'red');
1038
                return;
1039
    }
1040
    print $fd autogen_warning();
1041
    print $fd get_license_header($top);
1042
 
1043
 
1044
 
1045
 
1046
 
1047
        $route_str="\tgenerate
1048
 
1049
";
1050
 
1051
        foreach my $src (@ends){
1052
                my $PNUM=$self->object_get_attribute($src,"PNUM");
1053
                my $src_num=get_scolar_pos($src,@ends);
1054
            my %route;
1055
                $route_str=$route_str."\tif(SRC_E_ADDR == $src_num) begin : SRC$src_num
1056
\t\talways@(*)begin
1057
\t\t\tdestport= 0;
1058
\t\t\tcase(dest_e_addr)
1059
";
1060
 
1061
                foreach my $dst (@ends){
1062
                            my $dest_num = get_scolar_pos($dst,@ends);
1063
                                my $ref = $self->object_get_attribute('Route',"${src}::$dst");
1064
                                next if(!defined $ref);
1065
                                my @path = @{$ref};
1066
                                my ($p1,$p2)= get_connection_port_num_between_two_nodes($self,$path[1],$path[2] );
1067
                                #print " ($p1,$p2)= get_connection_port_num_between_two_nodes($self,$path[1],$path[2] );\n";
1068
                                $route{$p1} = (defined $route{$p1})? $route{$p1}.",$dest_num" : "$dest_num";
1069
                }
1070
                foreach my $q (sort {$a <=> $b} keys %route){
1071
                        $route_str=$route_str."\t\t\t$route{$q}: begin
1072
\t\t\t\tdestport= $q;
1073
\t\t\tend
1074
";
1075
                }
1076
                $route_str=$route_str."\t\t\tdefault: begin
1077
\t\t\t\tdestport= {DSTPw{1\'bX}};
1078
\t\t\tend
1079
 
1080
\t\t\tendcase\n\t\tend\n\tend//SRC$src_num\n\n";
1081
        }
1082
        $route_str=$route_str."\tendgenerate\n";
1083
 
1084
 
1085
 
1086
         print $fd "module ${Vname}_conventional_routing_genvar  #(
1087
\tparameter RAw = 3,
1088
\tparameter EAw = 3,
1089
\tparameter DSTPw=4,
1090
\tparameter SRC_E_ADDR=0
1091
)
1092
(
1093
\tdest_e_addr,
1094
\tdestport
1095
);
1096
 
1097
\tinput   [EAw-1   :0] dest_e_addr;
1098
\toutput reg [DSTPw-1 :0] destport;
1099
 
1100
 
1101
$route_str
1102
 
1103
 
1104
endmodule
1105
 
1106
";
1107
close($fd);
1108
add_info($info,"$top file is created\n  ");
1109
 
1110
##################
1111
#   look_ahead_routing_genvar
1112
###################
1113
 
1114
#create routing file
1115
        $top="$dir/${Vname}_look_ahead_routing_genvar.v";
1116
    open  $fd, ">$top" or $r = "$!\n";
1117
    if(defined $r) {
1118
        add_colored_info($info,"Error in creating $top: $r",'red');
1119
                return;
1120
    }
1121
    print $fd autogen_warning();
1122
    print $fd get_license_header($top);
1123
 
1124
 
1125
 
1126
        $route_str="\talways@(*)begin
1127
\t\tdestport=0;
1128
\t\tcase(current_r_addr) //current_r_addr of each individual router is fixed. So this CASE will be optimized by the synthesizer for each router.
1129
";
1130
 
1131
$route_str="\tgenerate\n";
1132
 
1133
 
1134
foreach my $router (@routers){
1135
                my $PNUM=$self->object_get_attribute($router,"PNUM");
1136
                my $router_num=get_scolar_pos($router,@routers);
1137
            my %route;
1138
                $route_str=$route_str."\tif(CURRENT_R_ADDR == $router_num) begin :R$router_num
1139
\t\talways@(*)begin
1140
\t\t\tdestport= 0;
1141
\t\t\tcase({src_e_addr,dest_e_addr})
1142
";
1143
        # for each src-dest check if $router include in path 
1144
        foreach my $src (@ends){
1145
                foreach my $dst (@ends){
1146
                        my $ref = $self->object_get_attribute('Route',"${src}::$dst");
1147
                        next if(!defined $ref);
1148
                        my @path = @{$ref};
1149
                    my $loc= get_scolar_pos($router,@path);
1150
                    next if(!defined $loc);# this router does not exist in path skip it
1151
                    my $next_router1=$path[$loc+1];
1152
                    my $next_router2=$path[$loc+2];
1153
                    next if(!defined $next_router2);
1154
                    my ($p1,$p2)= get_connection_port_num_between_two_nodes($self,$next_router1,$next_router2);
1155
                    next if(!defined $p1);
1156
                    my $src_num=get_scolar_pos($src,@ends);
1157
                    my $dest_num = get_scolar_pos($dst,@ends);
1158
                        $route{$p1} = (defined $route{$p1})? $route{$p1}.",{E$src_num,E$dest_num}" : "{E$src_num,E$dest_num}";
1159
 
1160
                        #print "@path\n";
1161
                        #print "(current_router, next_router1, next_router2)=($router, $next_router1, $next_router2)\n";
1162
                        #print "($p1,$p2)= get_connection_port_num_between_two_nodes(\$self,$next_router1,$next_router2)\n";    
1163
                        #print "\$route{$p1} ={E$src_num,E$dest_num}\n";
1164
                        #print"***************************\n"; 
1165
 
1166
                }
1167
        }
1168
        foreach my $q (sort {$a <=> $b} keys %route){
1169
                        $route_str=$route_str."\t\t\t$route{$q}: begin
1170
\t\t\t\tdestport= $q;
1171
\t\t\tend
1172
";
1173
 
1174
        }
1175
 
1176
        $route_str=$route_str."\t\t\tendcase\n\t\tend\n\tend//R$router_num\n\n";
1177
        }
1178
        $route_str=$route_str."\tendgenerate\n";
1179
 
1180
 
1181
 
1182
 print $fd "
1183 54 alirezamon
 `include \"pronoc_def.v\"
1184
 
1185 48 alirezamon
/*****************************
1186
*       ${Vname}_look_ahead_routing_genvar
1187
******************************/
1188
module ${Vname}_look_ahead_routing_genvar  #(
1189
\tparameter RAw = 3,
1190
\tparameter EAw = 3,
1191
\tparameter DSTPw=4,
1192
\tparameter CURRENT_R_ADDR=0
1193
)
1194
(
1195
\tdest_e_addr,
1196
\tsrc_e_addr,
1197
\tdestport,
1198
\treset,
1199
\tclk
1200
);
1201
 
1202
\tinput   [EAw-1   :0] dest_e_addr;
1203
\tinput   [EAw-1   :0] src_e_addr;
1204
\toutput  [DSTPw-1 :0] destport;
1205
\tinput reset,clk;
1206
 
1207
        reg [EAw-1   :0] dest_e_addr_delay;
1208
        reg [EAw-1   :0] src_e_addr_delay;
1209
 
1210 54 alirezamon
         always @ (`pronoc_clk_reset_edge )begin
1211
        if(`pronoc_reset) begin
1212 48 alirezamon
                        dest_e_addr_delay<={EAw{1'b0}};
1213
                        src_e_addr_delay<={EAw{1'b0}};
1214
                end else begin
1215
                        dest_e_addr_delay<=dest_e_addr;
1216
                        src_e_addr_delay<=src_e_addr;
1217
                end
1218
        end
1219
 
1220
        ${name}_look_ahead_routing_genvar_comb  #(
1221
                .RAw(RAw),
1222
                .EAw(EAw),
1223
                .DSTPw(DSTPw),
1224
                .CURRENT_R_ADDR(CURRENT_R_ADDR)
1225
        )
1226
        lkp_cmb
1227
        (
1228
 
1229
                .dest_e_addr(dest_e_addr_delay),
1230
                .src_e_addr(src_e_addr_delay),
1231
                .destport(destport)
1232
        );
1233
 
1234
 
1235
 
1236
endmodule
1237
 
1238
/*******************
1239
* ${Vname}_look_ahead_routing_genvar_comb
1240
********************/
1241
 
1242
 
1243
 module ${Vname}_look_ahead_routing_genvar_comb  #(
1244
\tparameter RAw = 3,
1245
\tparameter EAw = 3,
1246
\tparameter DSTPw=4,
1247
\tparameter CURRENT_R_ADDR=0
1248
)
1249
(
1250
\tdest_e_addr,
1251
\tsrc_e_addr,
1252
\tdestport
1253
);
1254
 
1255
\tinput   [EAw-1   :0] dest_e_addr;
1256
\tinput   [EAw-1   :0] src_e_addr;
1257
\toutput  reg [DSTPw-1 :0] destport;
1258
 
1259
$localparam
1260
 
1261
$route_str
1262
 
1263
 
1264
endmodule
1265
 
1266
 
1267
";
1268
 
1269
 
1270
close($fd);
1271
add_info($info,"$top file is created\n  ");
1272
 
1273
}
1274
 
1275
 
1276
 
1277
sub generate_connection_v{
1278
        my($self,$info,$dir)=@_;
1279
 
1280
        #create connection top file
1281
        my $name=$self->object_get_attribute('save_as');
1282
 
1283
        my $r;
1284
        my $top="$dir/${name}_connection.sv";
1285
    open my $fd, ">$top" or $r = "$!\n";
1286
    if(defined $r) {
1287
        add_colored_info($info,"Error in creating $top: $r",'red');
1288
                return;
1289
    }
1290
    print $fd autogen_warning();
1291
    print $fd get_license_header($top);
1292 54 alirezamon
print $fd '
1293
`include "pronoc_def.v"
1294
';
1295 48 alirezamon
 
1296
 
1297
 
1298
 
1299
 
1300
 
1301
   my @parameters=@{$self->object_get_attribute ('Verilog','Router_param')};
1302
   my @ports= @{$self->object_get_attribute('Verilog','Router_ports')};
1303
 
1304
 
1305
 
1306
    my @ends=get_list_of_all_endpoints($self);
1307
    my @routers=get_list_of_all_routers($self);
1308
 
1309
    my $MAX_P=0;
1310
    foreach my $p (@routers){
1311
        my $Pnum=$self->object_get_attribute("$p",'PNUM');
1312
        $MAX_P =$Pnum  if($Pnum>$MAX_P );
1313
    }
1314
 
1315
    my $NE= scalar @ends;
1316
    my $NR= scalar @routers;
1317
 
1318
 
1319
 
1320
        my @nodes=get_list_of_all_routers($self);
1321
        my $i=0;
1322
 
1323
        my $ports="\treset,
1324
\tclk,
1325
\tstart_i,
1326
\tstart_o,
1327
\ter_addr,
1328
\tcurrent_r_addr,
1329
\tchan_in_all,
1330
\tchan_out_all,
1331
\trouter_chan_in,
1332
\trouter_chan_out
1333
";
1334
 
1335
 
1336
    my $ports_def="
1337
\tinput reset;
1338
\tinput clk;
1339
\tinput start_i;
1340
\toutput [RAw-1 : 0] er_addr [NE-1 : 0]; // provide router address for each connected endpoint
1341
\toutput [RAw-1 : 0] current_r_addr [NR-1 : 0]; // provide each router current address  ;
1342
\toutput [NE-1 : 0] start_o;
1343
\toutput smartflit_chanel_t chan_in_all [NE-1 : 0];
1344
\tinput  smartflit_chanel_t chan_out_all [NE-1 : 0];
1345
\tinput  smartflit_chanel_t    router_chan_in   [NR-1 :0][MAX_P-1 : 0];
1346
\toutput smartflit_chanel_t    router_chan_out  [NR-1 :0][MAX_P-1 : 0];
1347
 
1348
";
1349
 
1350
        my $router_wires="";
1351
        my $endps_wires="";
1352
 
1353
 
1354
 
1355
 
1356
        foreach my $d (@ports){
1357
                my $range = ($d->{width} eq 1)? " " :  " [$d->{width}-1 : 0]";
1358
                my $pdef_range = ($d->{pwidth} eq 1)? "[NE-1 : 0]" : "[$d->{pwidth}-1 : 0]";
1359
                my $pdef_range2 = ($d->{pwidth} eq 1)? "" : "[NE-1 : 0]";
1360
                #$ports=$ports.",\n\trouter_$d->{name},\n\trouter_$d->{connect}";
1361
                my $type=$d->{type};
1362
                my $ctype= ($type eq 'input')? 'output' : 'input';
1363
                if( $d->{endp} eq "yes"){
1364
                        #$ports_def=$ports_def."\t$type\t$pdef_range ni_$d->{pname} $pdef_range2;\n";
1365
                        #$ports_def=$ports_def."\t$ctype\t$pdef_range ni_$d->{pconnect} $pdef_range2;\n";                       
1366
                        #$ports=$ports.",\n\tni_$d->{pname},\n\tni_$d->{pconnect}";
1367
                }
1368
                if($d->{width} eq 1){
1369
                        #$ports_def=$ports_def. "\t$type\t[NR-1 :0] router_$d->{name};\n";
1370
                        #$ports_def=$ports_def. "\t$ctype\t[NR-1 :0] router_$d->{connect};\n";
1371
                }else{
1372
                        #$ports_def=$ports_def. "\t$type\t$range router_$d->{name} [NR-1 :0];\n";
1373
                        #$ports_def=$ports_def. "\t$ctype\t$range router_$d->{connect} [NR-1 :0];\n";
1374
                }
1375
 
1376
 
1377
        }
1378
 
1379
 
1380
 
1381
 
1382
        my $routers='
1383
        genvar i;
1384
        generate
1385
        ';
1386
        my $offset=0;
1387
        my $assign="";
1388 54 alirezamon
        my $R_num=0;
1389 48 alirezamon
        for ( my $i=2;$i<=12; $i++){
1390
                my $n= $self->object_get_attribute("ROUTER${i}","NUM");
1391
                $n=0 if(!defined $n);
1392
                if($n>0){
1393
                        my $router_pos= ($offset==0)? 'i' : "i+$offset";
1394
                        my $instant=get_router_genvar_instance_v($self,$i,$router_pos,$NE,$NR,$MAX_P);
1395
 
1396
                        $routers=$routers."
1397
\tfor( i=0; i<$n; i=i+1) begin : router_${i}_port_lp
1398
\t\t$instant
1399
 
1400
\tend
1401
                        ";
1402
 
1403
                        for ( my $j=0;$j<$n; $j++){
1404
                                my $rname ="ROUTER${i}_$j";
1405 54 alirezamon
                                my ($ass_v, $r2r_h,$r2e_h, $int_h,$gnd_h,$R_num)=       get_wires_assignment_genvar_v($self,$rname,1,undef,$R_num);
1406 48 alirezamon
                                $assign=$assign.$ass_v;
1407
                        }
1408
 
1409
                $offset+=       $n;
1410
 
1411
                }
1412
        }
1413
 
1414
 
1415
 
1416
        foreach my $end (@ends){
1417
                #$assign=$assign.get_wires_assignment_genvar_v($self,$end,1);           
1418
        }
1419
 
1420
        $assign=$assign."\n";
1421
 
1422
 
1423
        my $pos=0;
1424
        $assign.="//The router address connected to each endpoint\n";
1425
        foreach my $end (@ends){
1426
                my $connect = $self->{$end}{'PCONNECT'}{'Port[0]'};
1427
                my ($Rname,$Rport)=split(/\s*,\s*/,$connect);
1428
                my $R = get_scolar_pos($Rname,@routers);
1429
                my $rname = $self->object_get_attribute("$Rname","NAME");
1430
                my $tname = $self->object_get_attribute("$end","NAME");
1431
                $assign=$assign."\tassign er_addr [$pos] = $R; //$tname -> $rname\n";
1432
                $pos++;
1433
        }
1434
 
1435
        $assign=$assign."\n";
1436
 
1437
        $pos=0;
1438
        foreach my $router (@routers){
1439
                my $rname = $self->object_get_attribute("$router","NAME");
1440
                $assign=$assign."\tassign current_r_addr [$pos] = $pos; // $rname\n";
1441
                $pos++;
1442
        }
1443
 
1444
 
1445
 
1446
 
1447
                 print $fd "
1448
module  ${name}_connection
1449
        import pronoc_pkg::*;
1450
(
1451
    $ports
1452
);
1453
 
1454
         function integer log2;
1455
      input integer number; begin
1456
         log2=(number <=1) ? 1: 0;
1457
         while(2**log2<number) begin
1458
            log2=log2+1;
1459
         end
1460
      end
1461
    endfunction // log2
1462
 
1463
        localparam
1464
                NE = $NE,
1465
                NR = $NR,
1466
                RAw=log2(NR),
1467
                MAX_P=$MAX_P;
1468
 
1469
 
1470
 
1471
 
1472
 
1473
 
1474
 
1475
 
1476
 
1477
        localparam
1478
                P= MAX_P,
1479
        PV = V * P,
1480
        PFw = P * Fw,
1481
        CONG_ALw = CONGw * P,
1482
        PRAw = P * RAw;
1483
 
1484
 
1485
 
1486
 
1487
 
1488
 
1489
$ports_def
1490
 
1491
$router_wires
1492
 
1493
$endps_wires
1494
 
1495
 
1496
$assign
1497
 
1498
 
1499
        start_delay_gen #(
1500
        .NC(NE)
1501
    )
1502
    delay_gen
1503
    (
1504
        .clk(clk),
1505
        .reset(reset),
1506
        .start_i(start_i),
1507
        .start_o(start_o)
1508
    );
1509
 
1510
 
1511
endmodule
1512
";
1513
 
1514
        add_info($info,"$top file is created\n  ");
1515
        close $fd;
1516
 
1517
 
1518
 
1519
}
1520
 
1521 54 alirezamon
sub add_noc_custom_h{
1522
        my ($self,$info,$dir)=@_;
1523
        my $name=$self->object_get_attribute('save_as');
1524
        my $str="
1525
                //do not modify this line ===${name}===
1526
                #ifdef IS_${name}_noc
1527
                        #include \"${name}_noc.h\"
1528
                #endif
1529
        ";
1530
 
1531
 
1532
        my $file = "$dir/../../../src_verilator/topology/custom/custom.h";
1533
        #check if ***$name**** exist in the file
1534
        unless (-f $file){
1535
                add_colored_info($info,"$file dose not exist\n",'red');
1536
                return;
1537
        }
1538
        my $r = check_file_has_string($file, "===${name}===");
1539
        if ($r==1){
1540
                add_info($info,"The instance  ${name}_noc exists in $file. This file is not modified\n  ",'blue');
1541
 
1542
        }else{
1543
                my $text = read_file_cntent($file,' ');
1544
        my @a = split('endgenerate',$text);
1545
        save_file($file,"$a[0] $str $a[1]");
1546
        add_info($info,"$file has been modified. The  ${name}_noc has been added to the file\n  ",'blue');
1547
 
1548
        }
1549
 
1550
}
1551 48 alirezamon
 
1552
 
1553
 
1554
sub add_routing_instance_v{
1555
        my ($self,$info,$dir)=@_;
1556
        my $name=$self->object_get_attribute('save_as');
1557
        my $rname=$self->object_get_attribute('routing_name');
1558
        my $Vname="T${name}R${rname}";
1559
        #####################################
1560
        #                       custom_ni_routing
1561
        ####################################
1562
        my $str="
1563
        //do not modify this line ===${Vname}===
1564
    if(TOPOLOGY == \"$name\" && ROUTE_NAME== \"$rname\" ) begin : $Vname
1565
 
1566
        ${Vname}_conventional_routing  #(
1567
            .RAw(RAw),
1568
            .EAw(EAw),
1569
            .DSTPw(DSTPw)
1570
        )
1571
        the_conventional_routing
1572
        (
1573
            .dest_e_addr(dest_e_addr),
1574
            .src_e_addr(src_e_addr),
1575
            .destport(destport)
1576
        );
1577
 
1578
    end
1579
 
1580
    endgenerate
1581
 
1582
";
1583
 
1584
        my $file = "$dir/../common/custom_ni_routing.v";
1585
        #check if ***$name**** exist in the file
1586
        unless (-f $file){
1587
                add_colored_info($info,"$file dose not exist\n",'red');
1588
                return;
1589
        }
1590
        my $r = check_file_has_string($file, "===${Vname}===");
1591
        if ($r==1){
1592
                add_info($info,"The instance  ${Vname}_conventional_routing exists in $file. This file is not modified\n  ",'blue');
1593
 
1594
        }else{
1595
                my $text = read_file_cntent($file,' ');
1596
        my @a = split('endgenerate',$text);
1597
        save_file($file,"$a[0] $str $a[1]");
1598
        add_info($info,"$file has been modified. The  ${Vname}_conventional_routing has been added to the file\n  ",'blue');
1599
 
1600
        }
1601
 
1602
 
1603
 
1604
        #####################################
1605
        #                       custom_lkh_routing
1606
        ####################################
1607
         $str="
1608
        //do not modify this line ===${Vname}===
1609
    if(TOPOLOGY == \"$name\" && ROUTE_NAME== \"$rname\" ) begin : ${Vname}
1610
 
1611
           ${Vname}_look_ahead_routing  #(
1612
            .RAw(RAw),
1613
            .EAw(EAw),
1614
            .DSTPw(DSTPw)
1615
        )
1616
        the_lkh_routing
1617
        (
1618
            .current_r_addr(current_r_addr),
1619
            .dest_e_addr(dest_e_addr),
1620
            .src_e_addr(src_e_addr),
1621
            .destport(destport),
1622
            .reset(reset),
1623
            .clk(clk)
1624
        );
1625
 
1626
    end
1627
 
1628
    endgenerate
1629
 
1630
";
1631
 
1632
        $file = "$dir/../common/custom_lkh_routing.v";
1633
 
1634
        unless (-f $file){
1635
                add_colored_info($info,"$file dose not exist\n",'red');
1636
                return;
1637
        }
1638
        $r = check_file_has_string($file, "===${Vname}===");
1639
        if ($r==1){
1640
                add_info($info,"The instance ${Vname}_look_ahead_routing exist in $file. This file is not modified\n  ",'blue');
1641
 
1642
        }else{
1643
                my $text = read_file_cntent($file,' ');
1644
        my @a = split('endgenerate',$text);
1645
        save_file($file,"$a[0] $str $a[1]");
1646
        add_info($info,"$file has been modified. The  ${Vname}_look_ahead_routing has been added to the file\n  ",'blue');
1647
 
1648
        }
1649
 
1650
 
1651
}
1652
 
1653
sub add_noc_instance_v{
1654
        my ($self,$info,$dir)=@_;
1655
        my $name=$self->object_get_attribute('save_as');
1656
 
1657
        #####################################
1658
        #                       add connection
1659
        ####################################
1660
 
1661
        my $ports="\t\t.reset(reset),
1662
\t\t.clk(clk),
1663
\t\t.start_i(start_i),
1664
\t\t.start_o(start_o),
1665
\t\t.er_addr(er_addr),
1666
\t\t.current_r_addr(current_r_addr),
1667
\t\t.chan_in_all(chan_in_all),
1668
\t\t.chan_out_all(chan_out_all),
1669
\t\t.router_chan_in(router_chan_in),
1670
\t\t.router_chan_out(router_chan_out)
1671
 
1672
 
1673
";
1674
 
1675
 
1676
 
1677
 
1678
        my $str="
1679
        //do not modify this line ===${name}===
1680
    if(TOPOLOGY == \"$name\" ) begin : T$name
1681
 
1682
        ${name}_connection  connection
1683
        (
1684
$ports
1685
        );
1686
 
1687
    end
1688
 
1689
    endgenerate
1690
 
1691
";
1692
 
1693
        #my $file = "$dir/../common/custom_noc_connection.sv";  
1694
        #check if ***$name**** exist in the file
1695
        #unless (-f $file){
1696
        #       add_colored_info($info,"$file dose not exist\n",'red');
1697
        #       return; 
1698
        #}      
1699
        #my $r = check_file_has_string($file, "===${name}==="); 
1700
        #if ($r==1){
1701
                #add_info($info,"The instance  ${name}_connection exists in $file. This file is not modified\n  ",'blue');
1702
 
1703
        #}else{
1704
                #my $text = read_file_cntent($file,' ');
1705
       # my @a = split('endgenerate',$text);
1706
      #  save_file($file,"$a[0] $str $a[1]");
1707
       # add_info($info,"$file has been modified. The  ${name}_connection has been added to the file\n  ",'blue');
1708
 
1709
        #}
1710
 
1711
 
1712
        #####################################
1713
        #               add NoC 
1714
        ####################################
1715
 
1716
 
1717
         my $param_str ="\t\t.TOPOLOGY(TOPOLOGY),
1718
\t\t.ROUTE_NAME(ROUTE_NAME)";
1719
 
1720
   my @parameters=@{$self->object_get_attribute ('Verilog','Router_param')};
1721
 
1722
        foreach my $d (@parameters){
1723
                $param_str = $param_str.",\n\t\t.$d->{param_name}($d->{param_name})";
1724
        }
1725
 
1726
        $ports="\t\t.reset(reset),
1727
\t\t.clk(clk)";
1728
 
1729
 
1730
 
1731
 
1732
        $str="
1733
        //do not modify this line ===${name}===
1734
    if(TOPOLOGY == \"$name\" ) begin : T$name
1735
 
1736
                ${name}_noc_genvar the_noc
1737
                (
1738
                    .reset(reset),
1739
                    .clk(clk),
1740
                    .chan_in_all(chan_in_all),
1741 54 alirezamon
                    .chan_out_all(chan_out_all),
1742
                    .router_event(router_event)
1743 48 alirezamon
                );
1744 51 alirezamon
    end
1745 52 alirezamon
 
1746 48 alirezamon
    endgenerate
1747
 
1748
        ";
1749
 
1750
 
1751
 
1752
        my $file = "$dir/../common/custom_noc_top.sv";
1753
        #check if ***$name**** exist in the file
1754
        unless (-f $file){
1755
                add_colored_info($info,"$file dose not exist\n",'red');
1756
                return;
1757
        }
1758
        my $r = check_file_has_string($file, "===${name}===");
1759
        if ($r==1){
1760
                add_info($info,"The instance  ${name}_noc exists in $file. This file is not modified\n  ",'blue');
1761
 
1762
        }else{
1763
                my $text = read_file_cntent($file,' ');
1764
        my @a = split('endgenerate',$text);
1765
        save_file($file,"$a[0] $str $a[1]");
1766
        add_info($info,"$file has been modified. The  ${name}_noc has been added to the file\n  ",'blue');
1767
        }
1768
 
1769
 
1770
 
1771
 
1772
 
1773
 
1774
 
1775
 
1776
 
1777
 
1778
 
1779
}
1780
 
1781
 
1782
1

powered by: WebSVN 2.1.0

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