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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 alirezamon
#!/usr/bin/perl
2
use strict;
3
use warnings;
4
use constant::boolean;
5
 
6
use Cwd 'abs_path';
7
use base 'Class::Accessor::Fast';
8
require "widget.pl";
9
require "diagram.pl";
10
require "topology_verilog_gen.pl";
11
 
12
use String::Scanf; # imports sscanf()
13
 
14
use FindBin;
15
use lib $FindBin::Bin;
16
use tsort;
17
 
18
use File::Basename;
19
use Cwd 'abs_path';
20
 
21
__PACKAGE__->mk_accessors(qw{
22
        window
23
        sourceview
24
});
25
 
26
my $NAME = 'Network_maker';
27
exit network_maker_main() unless caller;
28
 
29
 
30
sub network_maker_main {
31
        my $app = __PACKAGE__->new();
32
 
33
        my @parameters = (
34
        {param_name=> "V ", value=>2},
35
    {param_name=> "B ", value=>4},
36
    {param_name=> "C ", value=>2},
37
    {param_name=> "Fpay ", value=>32},
38
    {param_name=> "MUX_TYPE", value=>'"ONE_HOT"'},
39
    {param_name=> "VC_REALLOCATION_TYPE ", value=>'"NONATOMIC"'},
40
    {param_name=> "COMBINATION_TYPE", value=>'"COMB_NONSPEC"'},
41
    {param_name=> "FIRST_ARBITER_EXT_P_EN ", value=>1},
42
    {param_name=> "CONGESTION_INDEX ", value=>7},
43
    {param_name=> "DEBUG_EN", value=>0},
44
    {param_name=> "AVC_ATOMIC_EN", value=>0},
45
    {param_name=> "ADD_PIPREG_AFTER_CROSSBAR", value=>0},
46
    {param_name=> "CVw", value=>"(C==0)? V : C * V"},
47
    {param_name=> "CLASS_SETTING ", value=>"{CVw{1\'b1}}"},
48
    {param_name=> "SSA_EN", value=>'"NO"'},
49
    {param_name=> "SWA_ARBITER_TYPE ", value=>'"RRA"'},
50
    {param_name=> "WEIGHTw ", value=>7},
51
    {param_name=> "MIN_PCK_SIZE", value=>2},
52
    {param_name=> "BYTE_EN", value=>0}
53
);
54
 
55
my @ports =(
56
        {name=> "flit_in_all", type=>"input", width=>"PFw", connect=>"flit_out_all",  pwidth=>"Fw", pname=> "flit_in", pconnect=>"flit_out", endp=>"yes"},
57
        {name=> "flit_in_wr_all", type=>"input", width=>"P", connect=>"flit_out_wr_all",  pwidth=>1, pname=> "flit_in_wr", pconnect=>"flit_out_wr",endp=>"yes"},
58
        {name=> "congestion_in_all", type=>"input", width=>"CONG_ALw", connect=>"congestion_out_all",  pwidth=>"CONGw", pname=> "congestion_in", pconnect=>"congestion_out",endp=>"no"},
59
        {name=> "credit_out_all", type=>"output", width=>"PV", connect=>"credit_in_all",  pwidth=>"V" ,pname=> "credit_out", pconnect=>"credit_in",endp=>"yes"}
60
);
61
 
62
 
63
  $app->object_add_attribute ('Verilog','Router_param',\@parameters);
64
  $app->object_add_attribute ('Verilog','Router_ports',\@ports);
65
 
66
 
67
 
68
 
69
        my $table=$app->build_network_maker_gui();
70
        return $table;
71
}
72
 
73
 
74
sub custom_topology_diagram {
75
        my $self= shift;
76
 
77
 
78
 
79
        my $table=def_table(20,20,FALSE);
80
        my $scrolled_win = add_widget_to_scrolled_win();
81
 
82
 
83
        my ($col,$row)=(0,0);
84
 
85
 
86
 
87
 
88
        my $plus = def_image_button('icons/plus.png',undef,TRUE);
89
        my $minues = def_image_button('icons/minus.png',undef,TRUE);
90
        my $save = def_image_button('icons/save.png',undef,TRUE);
91
        my $dot_file = def_image_button('icons/add-notes.png',undef,TRUE);
92
        set_tip($dot_file, "Show dot file.");
93
 
94
        my $scale=$self->object_get_attribute("tile_diagram","scale");
95
        $scale= 1 if (!defined $scale);
96
 
97
        my $state=$self->object_get_attribute("tile_diagram","auto_draw");
98
        if (!defined $state){
99
                $state='ON' ;
100
                $self->object_add_attribute("tile_diagram","auto_draw",$state);
101
        }
102
        my $auto= ($state eq 'ON')? def_colored_button('ON',17): def_colored_button('OFF',4);
103
 
104
 
105
        my $gtype=$self->object_get_attribute("tile_diagram","gtype");
106
        if (!defined $gtype){
107
                $gtype='comp' ;
108
                $self->object_add_attribute("tile_diagram","gtype",$gtype);
109
        }
110
        my $graph_type= ($gtype eq 'comp')? def_colored_button('comp',17): def_colored_button('simple',4);
111
 
112
 
113
 
114
 
115
 
116
 
117
        $table->attach (gen_label_in_center  ("Auto Draw") ,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $row++;
118
        $table->attach ($auto ,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $row++;
119
        $table->attach ($graph_type ,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $row++;
120
        $table->attach ($plus ,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $row++;
121
        $table->attach ($minues,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $row++;
122
        $table->attach ($save,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $row++;
123
        $table->attach ($dot_file,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $row++;
124
 
125
        $table->attach_defaults ($scrolled_win, 1, 20, 0, 20); #,'fill','shrink',2,2);
126
 
127
        ($col,$row)=(1,0);
128
        while ($row<20){
129
                my $tmp=gen_label_in_left('');
130
                $table->attach_defaults ($tmp, $col,  $col+1,$row,$row+1);$row++;
131
        }
132
 
133
        $plus  -> signal_connect("clicked" => sub{
134
                $scale*=1.1 if ($scale <10);
135
                $self->object_add_attribute("topology_diagram","scale", $scale );
136
                show_custom_topology_diagram ($self,$scrolled_win,"topology_diagram");
137
        });
138
        $minues  -> signal_connect("clicked" => sub{
139
                $scale*=.9  if ($scale >0.1); ;
140
                $self->object_add_attribute("topology_diagram","scale", $scale );
141
                show_custom_topology_diagram ($self,$scrolled_win,"topology_diagram");
142
        });
143
        $save-> signal_connect("clicked" => sub{
144
                        save_inline_diagram_as ($self);
145
                });
146
 
147
        $dot_file-> signal_connect("clicked" => sub{
148
                        my $dotfile = generate_custom_topology_dot_file($self);
149
                        show_text_in_scrolled_win($self,$scrolled_win, $dotfile);
150
        });
151
 
152
 
153
        $auto -> signal_connect("clicked" => sub{
154
                        my $state=$self->object_get_attribute("tile_diagram","auto_draw");
155
 
156
 
157
                        my $new = ($state eq "ON")? "OFF" : "ON";
158
                        $self->object_add_attribute("tile_diagram","auto_draw",$new);
159
                        set_gui_status($self,"ref",1);
160
                });
161
 
162
        $graph_type-> signal_connect("clicked" => sub{
163
                        my $state=$self->object_get_attribute("tile_diagram","gtype");
164
 
165
 
166
                        my $new = ($state eq "simple")? "comp" : "simple";
167
                        $self->object_add_attribute("tile_diagram","gtype",$new);
168
                        set_gui_status($self,"ref",1);
169
                });
170
 
171
        if ($state eq 'ON'){
172
                show_custom_topology_diagram ($self,$scrolled_win,"topology_diagram");
173
        }
174
 
175
        return add_widget_to_scrolled_win ($table);
176
 
177
}
178
 
179
 
180
 
181
 
182
 
183
sub gen_right_paned {
184
        my ($self,$info) =@_;
185
        my $page_num=$self->object_get_attribute ("process_notebook","currentpage");
186
 
187
        return route_info_window($self,$info) if($page_num==3);
188
        return custom_topology_diagram ($self,$info);
189
 
190
}
191
 
192
 
193
 
194
 
195
sub endp_node_dot_comp {
196
        my ($T,$instance)=@_;
197
 
198
 
199
        return
200
        "
201
        $T\[
202
        label = \"$instance\"
203
    shape=house
204
    margin=0
205
        color=orange
206
        style=filled
207
        fillcolor=orange
208
];
209
";
210
}
211
 
212
sub router_node_dot_comp{
213
        my ($Pnum,$R,$instance)=@_;
214
        $Pnum=1 if(!defined $Pnum);
215
        my $label =
216
                ($Pnum==2)? "                        \{<p1>1|$instance|<p0>0\}":
217
                ($Pnum==3)? "\{     |<p2>2|     \} | \{<p1>1|$instance|<p0>0\} ":
218
                ($Pnum==4)? "\{     |<p3>3|     \} | \{<p2>2|$instance|<p0>0\} | \{  <p1>1\}":
219
                ($Pnum==5)? "\{     |<p3>3|     \} | \{<p2>2|$instance|<p4>4\} | \{ |<p1>1|<p0>0\}":
220
                ($Pnum==6)? "\{<p3>3|<p4>4|     \} | \{<p2>2|$instance|<p5>5\} | \{ |<p1>1|<p0>0\}":
221
                ($Pnum==7)? "\{<p4>4|<p5>5|     \} | \{<p3>3|$instance|<p6>6\} | \{<p2>2 |<p1>1|<p0>0\}":
222
                ($Pnum==8)? "\{<p4>4|<p5>5|<p6>6\} | \{<p3>3|$instance|<p7>7\} | \{<p2>2 |<p1>1|<p0>0\}":
223
                ($Pnum==9)? "\{<p5>5|<p6>6|<p7>7\} | \{<p4>4|$instance|<p8>8\} | \{<p3>3 |<p2>2|<p1>1|<p0>0\}":
224
                ($Pnum==10)? "\{<p5>5|<p6>6|<p7>7|<p8>8\} | \{<p4>4|$instance|<p9>9\} | \{<p3>3 |<p2>2|<p1>1|<p0>0\}":
225
                ($Pnum==11)? "\{<p6>6|<p7>7|<p8>8|<p9>9\}| \{<p5>5| | |<p10>10\}  | \{<p4>4|$instance| \} | \{<p3>3 |<p2>2|<p1>1|<p0>0\}":
226
                ($Pnum==12)? "\{<p6>6|<p7>7|<p8>8|<p9>9\}| \{<p5>5| | |<p10>10\}  | \{<p4>4|$instance|<p11>11\} | \{<p3>3 |<p2>2|<p1>1|<p0>0\}":
227
                  "\{ |<p2>2| \} | \{<p3>3|$instance|<p1>1\} | \{ |<p4>4|<p0>0\}";
228
 
229
 
230
        return
231
        "$R\[
232
        label = \"$label\"
233
    shape=record
234
        color=blue
235
        style=filled
236
        fillcolor=blue
237
];
238
";
239
 
240
}
241
 
242
sub router_node_dot_sim{
243
        my ($Pnum,$R,$instance)=@_;
244
        $Pnum=1 if(!defined $Pnum);
245
        my $label =      "$instance";
246
 
247
 
248
        return
249
        "$R\[
250
        label = \"$label\"
251
    shape=circle
252
        color=blue
253
        style=filled
254
        fillcolor=blue
255
];
256
";
257
 
258
}
259
 
260
 
261
sub endp_node_dot_sim {
262
        my ($T,$instance)=@_;
263
 
264
 
265
        return
266
        "
267
        $T\[
268
        label = \"$instance\"
269
    shape=circle
270
    margin=0
271
        color=orange
272
        style=filled
273
        fillcolor=orange
274
];
275
";
276
}
277
 
278
 
279
 
280
 
281
 
282
 
283
 
284
 
285
 
286
 
287
 
288
 
289
sub generate_custom_topology_dot_file{
290
        my $self=shift;
291
 
292
        my $gtype=$self->object_get_attribute("tile_diagram","gtype");
293
        $gtype = "simple" if (!defined $gtype);
294
 
295
        my $dotfile=
296
"digraph G {
297
        graph [layout = twopi, rankdir = RL , splines = true, overlap = false];
298
        node[shape=record];
299
        ";
300
        #Add endpoints
301
        my @nodes=get_list_of_all_endpoints($self);
302
        my $i=0;
303
        foreach my $p (@nodes){
304
                my $instance= $self->object_get_attribute("$p","NAME");
305
                $instance = "T$i" if(!defined $instance);
306
                $dotfile.= ($gtype eq 'simple')? endp_node_dot_sim($p,$instance) : endp_node_dot_comp($p,$instance);
307
                $i++;
308
        }
309
 
310
 
311
 
312
        #add routers
313
        @nodes=get_list_of_all_routers($self);
314
        $i=0;
315
        foreach my $p (@nodes){
316
                my $instance= $self->object_get_attribute("$p","NAME");
317
                $instance = "R$i" if(!defined $instance);
318
                my $pnum=$self->object_get_attribute("$p",'PNUM');
319
                $dotfile.=($gtype eq 'simple')? router_node_dot_sim($pnum,$p,$instance): router_node_dot_comp($pnum,$p,$instance);
320
                $i++;
321
        }
322
 
323
 
324
        #add connections
325
        my @all_nodes=get_list_of_all_nodes($self);
326
        my @draw;
327
        foreach my $p (@all_nodes){
328
                my $pnum=$self->object_get_attribute("$p",'PNUM');
329
           #    my $inst=$self->object_get_attribute("$p",'NAME');
330
                my $type = $self->object_get_attribute("$p",'TYPE');
331
                $pnum = 0 if(!defined $pnum);
332
                for (my $i=0;$i<$pnum; $i++){
333
                        my $src_port = "Port[${i}]";
334
                        my $connect = $self->{$p}{'PCONNECT'}{$src_port};
335
 
336
                        if (defined $connect) {
337
                                my $pos = get_scolar_pos($connect,@draw);
338
                                if ( !defined $pos ){
339
 
340
 
341
                                my ($node,$pnode)=split(/\s*,\s*/,$connect);
342
                                # check if $node exist
343
                                if ( defined get_scolar_pos($node, @all_nodes)){
344
 
345
                                    my ($cp)= sscanf("Port[%u]","$pnode");
346
                                    # my $cinst=$self->object_get_attribute("$node",'NAME');
347
                                    my $ctype = $self->object_get_attribute("$node",'TYPE');
348
 
349
 
350
 
351
                                        my ($t2, $t1);
352
 
353
                                        if ($gtype eq 'simple'){
354
                                                $t2 =  "\"$p\"";
355
                                                $t1 =  "\"$node\"";
356
                                        } else {
357
                                                $t2 = ($type eq "ENDP" )? "\"$p\"" : "\"$p\" : \"p$i\"";
358
                                            $t1 = ($ctype eq "ENDP" )? "\"$node\"" : "\"$node\" : \"p$cp\"";
359
 
360
                                        }
361
                                        my $t= "$t1 -> $t2 [ dir=none];\n";
362
                                        $dotfile=$dotfile."$t";
363
                                }
364
                                push(@draw,$connect);
365
                                push(@draw,"$p,$src_port");
366
                                #print "@draw\n";
367
                        }
368
 
369
 
370
                }}
371
        }
372
        $dotfile=$dotfile."\n}\n";
373
        #print  $dotfile;
374
        return $dotfile;
375
}
376
 
377
sub get_connection_port_num_between_two_nodes{
378
        my ($self,$n1,$n2)=@_;
379
        my $PNUM=$self->object_get_attribute($n1,"PNUM");
380
 
381
        for (my $p1=0; $p1<$PNUM; $p1++){
382
                my $connect=$self->{$n1}{"PCONNECT"}{"Port[$p1]"};
383
                next if(!defined $connect);
384
                my ($node,$pnode)=split(/\s*,\s*/,$connect);
385
                my ($p2)= sscanf("Port[%u]","$pnode");
386
                return ($p1,$p2) if($node eq $n2 );
387
        }
388
        return undef;
389
}
390
 
391
 
392
sub show_custom_topology_diagram {
393
        my ($self,$scrolled_win, $name)=@_;
394
 
395
        my $state=$self->object_get_attribute("tile_diagram","auto_draw");
396
        if( $state eq "ON") {
397
                my $dotfile = generate_custom_topology_dot_file($self);
398
                generate_and_show_graph_using_graphviz($self,$scrolled_win,$dotfile,$name);
399
        }
400
        else {
401
                my @list = $scrolled_win->get_children();
402
                foreach my $l (@list){
403
                        $scrolled_win->remove($l);
404
                }
405
        }
406
 
407
        return;
408
}
409
 
410
 
411
 
412
 
413
 
414
sub take_node_num_page{
415
        my ($self)=@_;
416
        my $table= def_table(2,10,FALSE);
417
        my $row=0;
418
        my $col=4;
419
        $table->attach (def_label('Network Element'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col+=2;
420
        $table->attach (def_label('Number'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);
421
        $row++;$col=0;
422
 
423
        $table->attach (def_icon('icons/e.png'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
424
        ($row,$col)=add_param_widget ($self,"# Endpoints","NUM", 0,'Spin-button','0,1024,1',undef, $table,$row,$col,1,'ENDP',10,'redraw');$col=0;
425
        for ( my $i=2;$i<=12; $i++){
426
                $table->attach (def_icon('icons/r.png'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
427
                ($row,$col)=add_param_widget ($self,"# $i-Port Routers","NUM", 0,'Spin-button','0,1024,1',undef, $table,$row,$col,1,"ROUTER${i}",10,'redraw');$col=0;
428
        }
429
        return $table;
430
}
431
 
432
 
433
 
434
sub take_instance_page{
435
        my ($self)=@_;
436
        my $table= def_table(2,10,FALSE);
437
 
438
        initial_node_info($self);
439
 
440
        my $row=0;
441
        my $col=0;
442
 
443
 
444
        $table->attach (def_label(' Network Element '),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col+=2;
445
        $table->attach (def_label(' Instance name '),$col,$col+1,$row,$row+1,'fill','shrink',2,2);
446
        $row++;$col=0;
447
 
448
 
449
        my $EN= $self->object_get_attribute('ENDP','NUM');
450
        $EN = 0 if(!defined $EN);
451
        for (my $i=0;$i<$EN; $i++){
452
 
453
                 my $d=get_default_instance_name($self,"ENDP_$i");
454
                ($row,$col)=add_param_widget ($self,"Endpoint $i","NAME",$d ,'Entry',undef,"router instance name", $table,$row,$col,1,"ENDP_$i",10,'redraw');$col=0;
455
 
456
        }
457
 
458
        #routers
459
        my $Rnum=0;
460
        for ( my $i=2;$i<=12; $i++){
461
                my $n= $self->object_get_attribute("ROUTER${i}","NUM");
462
                $n=0 if(!defined $n);
463
                 for ( my $j=0;$j<$n; $j++){
464
                        my $d=get_default_instance_name($self,"ROUTER${i}_$j");
465
                        ($row,$col)=add_param_widget ($self,"Router $Rnum","NAME", "$d",'Entry',undef,"router instance name", $table,$row,$col,1,"ROUTER${i}_$j",10,'redraw');$col=0;
466
 
467
                         $Rnum++;
468
                 }
469
        }
470
        return $table;
471
 
472
}
473
 
474
sub initial_node_info {
475
        my ($self)=@_;
476
 
477
        my $EN= $self->object_get_attribute('ENDP','NUM');
478
        $EN = 0 if(!defined $EN);
479
        for (my $i=0;$i<$EN; $i++){
480
                 $self->object_add_attribute("ENDP_$i",'PNUM',1);
481
                 $self->object_add_attribute("ENDP_$i",'TYPE',"ENDP");
482
                 my $inst=$self->object_get_attribute("ENDP_$i",'NAME');
483
                 if(!defined $inst){
484
                        $inst=get_default_instance_name ($self,"ENDP_$i");
485
                        $self->object_add_attribute("ENDP_$i",'NAME',$inst);
486
                 }
487
        }
488
 
489
        #routers
490
        my $Rnum=0;
491
        for ( my $i=2;$i<=12; $i++){
492
                my $n= $self->object_get_attribute("ROUTER${i}","NUM");
493
                $n=0 if(!defined $n);
494
                 for ( my $j=0;$j<$n; $j++){
495
                         $self->object_add_attribute("ROUTER${i}_$j",'PNUM',${i});
496
                         $self->object_add_attribute("ROUTER${i}_$j",'RNUM',$Rnum);
497
                         $self->object_add_attribute("ROUTER${i}_$j",'TYPE',"ROUTER");
498
                         my $inst=$self->object_get_attribute("ROUTER${i}_$j",'NAME');
499
                         if(!defined $inst){
500
                                $inst=get_default_instance_name ($self,"ROUTER${i}_$j");
501
                                $self->object_add_attribute("ROUTER${i}_$j",'NAME',$inst);
502
                         }
503
                         $Rnum++;
504
                 }
505
        }
506
 
507
}
508
 
509
 
510
 
511
 
512
sub get_default_instance_name {
513
        my ($self,$name)=@_;
514
        my $type = $self->object_get_attribute($name,'TYPE');
515
        my @nodes =($type eq 'ENDP')? get_list_of_all_endpoints($self):get_list_of_all_routers($self);
516
 
517
        my @R=("--");
518
        foreach my $p (@nodes){
519
                my $n= $self->object_get_attribute("$p","NAME");
520
                push( @R, $n) if(defined $n);
521
        }
522
 
523
        my $i=0;
524
        my $inst =      ($type eq 'ENDP')? "T$i": "R$i";
525
        my $pos= get_scolar_pos($inst,@R);
526
        while (defined $pos){
527
                $i++;
528
                $inst =         ($type eq 'ENDP')? "T$i": "R$i";
529
                $pos= get_scolar_pos($inst,@R);
530
        }
531
 
532
 
533
        return  $inst;
534
}
535
 
536
 
537
 
538
 
539
sub get_list_of_all_routers {
540
        my ($self)=@_;
541
        my @R;
542
        for ( my $i=2;$i<=12; $i++){
543
                 my $n= $self->object_get_attribute("ROUTER${i}","NUM");
544
                 $n=0 if(!defined $n);
545
                 for ( my $j=0;$j<$n; $j++){
546
                        push( @R, "ROUTER${i}_$j");
547
                 }
548
        }
549
        return @R;
550
}
551
 
552
sub get_list_of_all_endpoints {
553
        my ($self)=@_;
554
        my @E;
555
        my $EN= $self->object_get_attribute('ENDP','NUM');
556
        $EN = 0 if(!defined $EN);
557
        for (my $i=0;$i<$EN; $i++){
558
                push( @E, "ENDP_$i");
559
        }
560
        return @E;
561
}
562
 
563
sub get_list_of_all_nodes {
564
        my ($self)=@_;
565
        my @R=get_list_of_all_routers($self);
566
    my @E=get_list_of_all_endpoints($self);
567
    my @all_nodes= (@E,@R);
568
        return @all_nodes;
569
}
570
 
571
sub remove_connected_port{
572
        my ($self,$node,$port,$info)=@_;
573
        my @all_nodes=get_list_of_all_nodes($self);
574
        foreach my $p (@all_nodes){
575
                my $pnum=$self->object_get_attribute("$p",'PNUM');
576
                my $inst=$self->object_get_attribute("$p",'NAME');
577
 
578
                $pnum = 0 if(!defined $pnum);
579
                for (my $i=0;$i<$pnum; $i++){
580
                        my $src_port = "Port[${i}]";
581
                        if(defined $self->{$p}{'PCONNECT'}{$src_port}){ if ($self->{$p}{'PCONNECT'}{$src_port} eq "$node,$port"){
582
                                delete $self->{$p}{'PCONNECT'}{$src_port};
583
                                my $con_inst=$self->object_get_attribute("$node",'NAME');
584
                                add_info($info,"** $inst  $src_port is disconnected from $con_inst $port \n") if (defined $info);
585
 
586
                        }}
587
                }
588
        }
589
}
590
 
591
 
592
sub get_instance_to_node_name {
593
        my $self=shift;
594
        my @all_nodes=get_list_of_all_nodes($self);
595
    my %par;
596
    foreach my $p (@all_nodes){
597
                my $inst=$self->object_get_attribute("$p",'NAME');
598
                $par{$inst}= $p;
599
    }
600
    return %par;
601
}
602
 
603
 
604
##############
605
#       create_tree 
606
##############
607
sub create_tree_view {
608
   my ($self,$source,$src_port,$info)=@_;
609
   my $window = def_popwin_size(30,85,"Select Connection Element and Port",'percent');
610
 
611
 
612
   my ($model,$tree_view,$column) =create_tree_model_network_maker();
613
 
614
   my @all_nodes=get_list_of_all_nodes($self);
615
 
616
   unshift(@all_nodes,"-");
617
   my %par;
618
 
619
   foreach my $p (@all_nodes){
620
            my @childs;
621
                my $pnum=$self->object_get_attribute("$p",'PNUM');
622
                my $inst=$self->object_get_attribute("$p",'NAME');
623
 
624
                $pnum = 0 if(!defined $pnum);
625
                $inst = "-" if(!defined $inst);
626
 
627
                $par{$inst}= $p;
628
                for (my $i=0;$i<$pnum; $i++){
629
                        #donot add the source port itself to connection list
630
                        if(($source ne $p)|| ($src_port ne "Port[${i}]")){
631
                                push(@childs, "Port[${i}]");
632
                        }
633
                }
634
                my $iter = $model->append (undef);
635
            $model->set ($iter, 0, $inst, 1, $inst || '', 2, 0 || '', 3,   FALSE);
636
                foreach my $v ( @childs){
637
                         my $child_iter = $model->append ($iter);
638
                         $model->set ($child_iter, 0, $v, 1, $inst|| '', 2, $v || '', 3,   FALSE);
639
                }
640
   }
641
 
642
 
643
   $tree_view->append_column ($column);
644
 
645
 
646
 
647
   $tree_view->signal_connect (row_activated => sub{
648
 
649
                my ($tree_view, $path, $column) = @_;
650
                my $model = $tree_view->get_model;
651
                my $iter = $model->get_iter ($path);
652
                my $parent = $model->get ($iter, 1);
653
                my $child = $model->get ($iter, 2);
654
 
655
                if ($child){
656
                                my $node=$par{$parent};
657
                                connect_nodes ($self,$node,$child,$source,$src_port,$info);
658
 
659
 
660
 
661
 
662
                                set_gui_status($self,'ref',1);
663
                                $window->destroy;
664
 
665
                                #add parent child
666
                        }
667
                elsif($parent ){
668
 
669
                        my $node=$par{$parent};
670
                        if ($node eq "-"){
671
                                remove_connected_port($self,$source,$src_port);
672
                                delete $self->{$source}{'PCONNECT'}{$src_port};
673
                        }
674
 
675
 
676
 
677
                        set_gui_status($self,'ref',1);
678
                        $window->destroy;
679
 
680
 
681
                }
682
 
683
 
684
        #add parent child
685
 
686
        });
687
 
688
  #$tree_view->expand_all;
689
 
690
  my $scrolled_window = add_widget_to_scrolled_win($tree_view);
691
 
692
  my $hbox = def_hbox (FALSE, 0);
693
  $hbox->pack_start ( $scrolled_window, TRUE, TRUE, 0);
694
  $window ->add($hbox);
695
  $window->show_all;
696
}
697
 
698
sub connect_nodes {
699
        my ($self,$node1,$src_port1,$node2,$src_port2,$info)=@_;
700
 
701
 
702
 
703
        #add_colored_info($info,"$node1,$src_port1,$node2,$src_port2;\n","red") if (defined $info);     
704
 
705
        #check if the selected port has been connected to another port before and remove the connection
706
        remove_connected_port($self,$node1,$src_port1,$info);
707
        remove_connected_port($self,$node2,$src_port2,$info);
708
 
709
        $self->{$node1}{'PCONNECT'}{$src_port1}="$node2,$src_port2";
710
        $self->{$node2}{'PCONNECT'}{$src_port2}="$node1,$src_port1";
711
 
712
}
713
 
714
sub remove_all_connection {
715
        my ($self)=@_;
716
        my @all_nodes=get_list_of_all_nodes($self);
717
        foreach  my $node  (@all_nodes ){
718
                $self->{$node}{'PCONNECT'}=undef;
719
        }
720
        set_gui_status($self,"ref",1);
721
}
722
 
723
sub list_node_all_port{
724
        my ($self,$node)=@_;
725
        my @l;
726
        my $pnum =  $self->object_get_attribute($node,'PNUM');
727
        for (my $i=0;$i<$pnum; $i++){
728
                push(@l,"Port[${i}]");
729
        }
730
        return @l;
731
}
732
 
733
 
734
 
735
sub list_node_connected_port {
736
        my ($self,$node)=@_;
737
        my $r = $self->{$node}{'PCONNECT'};
738
        my %c =(defined $r)? %{$r} : undef;
739
        return sort keys %c;
740
}
741
 
742
sub list_node_unconnected_port {
743
        my ($self,$node)=@_;
744
        my @p = list_node_all_port($self,$node);
745
        my @cp = list_node_connected_port ($self,$node);
746
        #@p - @cp;
747
    my @np =get_diff_array(\@p,\@cp);
748
        return @np;
749
}
750
 
751
 
752
sub connection_page{
753
        my ($self,$info)=@_;
754
        my $table= def_table(2,10,FALSE);
755
        my $row=0;
756
        my $col=0;
757
 
758
        initial_node_info($self);
759
 
760
 
761
 
762
        my $eq = def_table(1,8,TRUE);
763
 
764
        my $label = gen_label_help("Eg: R[i]P[0]->T[i]P[0];i[0,10,1]","Equation:");
765
        my $entry = gen_entry();
766
        my $open= def_image_button("icons/enter.png",undef,TRUE);
767
        $eq->attach ($label,0,2,  $row, $row+1,'fill','fill',2,2);
768
        $eq->attach_defaults ($entry,2, 9,  $row, $row+1);
769
        $eq->attach ($open,9, 10,  $row, $row+1,'fill','shrink',2,2);
770
        $table->attach ($eq,0, 20,  $row, $row+1,'expand','fill',2,2);$row++;
771
 
772
        $open->signal_connect("clicked" => sub {
773
                                evaluate_eqation($self,$entry->get_text(),$info);
774
 
775
        });
776
 
777
        $row++;
778
 
779
 
780
 
781
        add_Hsep_to_table($table,0, 20,  $row);$row++;
782
        my $savr=$row;$row++;
783
 
784
        my $maxp=1;
785
 
786
        my @all_nodes=get_list_of_all_nodes($self);
787
 
788
        foreach  my $p  (@all_nodes ){
789
                my $inst=$self->object_get_attribute("$p",'NAME');
790
                my $pnum=$self->object_get_attribute("$p",'PNUM');
791
                $maxp=  $pnum if($pnum > $maxp );
792
 
793
 
794
 
795
                my $label =gen_label_in_left("$inst:");
796
                attach_widget_to_table ($table,$row,undef,undef,$label,$col);  $col+=4;
797
 
798
                for (my $i=0;$i<$pnum; $i++){
799
                        my $pname= "Port[${i}]";
800
                        my $connect = $self->{$p}{'PCONNECT'}{$pname};
801
                        my $button =  def_button(" -> ");
802
                        if (defined $connect) {
803
                                my ($node,$pnode)=split(/\s*,\s*/,$connect);
804
                        my $e=$self->object_get_attribute("$node",'NAME');
805
                                $button = def_button("$e->$pnode") if(defined $e);
806
                        }
807
                        $button->signal_connect("clicked" => sub {
808
                                create_tree_view($self,$p,$pname,$info);
809
 
810
                        });
811
                        attach_widget_to_table ($table,$row,undef,undef,$button,$col);  $col+=4;
812
                }
813
                $col=0;
814
 
815
                #($row,$col)=add_param_widget ($self,"$instance","CNNT", undef,"Combo-box",$list,"router instance name", $table,$row,$col,1,"ENDP_$i",1,'ref','horizontal');
816
                # my $connect_r= $self->object_get_attribute("ENDP_$i","CNNT");
817
                # if( defined $connect_r){
818
                #       print "cponnection is $R{$connect_r}\n";
819
                #       my $conr= $R{$connect_r};
820
                #       my $p=0;
821
                #       ($row,$col)=add_param_widget ($self,"P$p","P_$p", undef,"Combo-box",$list,undef, $table,$row,$col,1,"ENDP_$i",1,'ref','horizontal');
822
 
823
 
824
 
825
                # }
826
                 $row++;$col=0;
827
 
828
        }
829
 
830
        #routers
831
    for ( my $i=2;$i<=12; $i++){
832
                 my $n= $self->object_get_attribute("ROUTER${i}","NUM");
833
                 $n=0 if(!defined $n);
834
                 for ( my $j=0;$j<$n; $j++){
835
                        my $pnum=        $self->object_get_attribute("ROUTER${i}_$j",'PNUM');
836
                         for ( my $p=0;$p<$pnum; $p++){
837
                                #       ($row,$col)=add_param_widget ($self,"P$p","P_$p", undef,"Combo-box",$list,undef, $table,$row,$col,1,"ROUTER${i}_$j",1,'ref','horizontal');
838
 
839
                         }
840
                          $row++;$col=0;
841
 
842
                 }
843
        }
844
 
845
 
846
 
847
 
848
        #add lables
849
        $row=$savr;$col=0;
850
        $table->attach (def_label(' Network Element '),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col+=4;
851
        for (my $i=0;$i<$maxp; $i++){
852
                $table->attach (def_label(" P$i "),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col+=4;
853
 
854
        }
855
        return $table;
856
 
857
}
858
 
859
 
860
sub evaluate_eqation{
861
        my ($self,$exp,$info)=@_;
862
 
863
        my @str=split /;/, $exp;
864
        my $eq_exp;
865
 
866
        my $f=0;
867
        my %vname;
868
        my %vars;
869
 
870
        my %nodes_name=get_instance_to_node_name($self);
871
 
872
        foreach my $p (@str) {
873
 
874
                if($f==0){
875
                        $eq_exp= $p;
876
 
877
                }
878
                else{
879
                        my ($v, $start, $end, $step) = sscanf("%s[%d,%d,%d]", $p);
880
                        print "($v, $start, $end, $step)\n";
881
                        my @a;
882
                        for (my $i=$start; $i<$end;$i++){
883
                                push (@a,$i);
884
                        }
885
                        $vars{$f}=\@a;
886
                        $vname{$f}=$v;
887
 
888
                }
889
                $f++;
890
 
891
        }
892
 
893
 
894
        my %vars2;
895
        my $v1=$vname{1};
896
        foreach my $i (@{$vars{1}}){
897
                $vars2{$v1}=$i;
898
                my $v2=$vname{2};
899
                if (defined $v2) {
900
                        foreach my $j (@{$vars{2}}){
901
                                $vars2{$v2}=$j;
902
                                my $v3=$vname{3};
903
                                if (defined $v3) {
904
                                        foreach my $k (@{$vars{3}}){
905
                                                $vars2{$v3}=$k;
906
                                                eval_exp($self,$eq_exp,\%vars2,\%nodes_name,$info);
907
                                        }
908
 
909
                                }
910
                                else {eval_exp($self,$eq_exp,\%vars2,\%nodes_name,$info)};
911
 
912
 
913
                        }
914
                }
915
                else {eval_exp($self,$eq_exp,\%vars2,\%nodes_name,$info)};
916
 
917
        }
918
 
919
set_gui_status($self,'ref',1);
920
}
921
 
922
 
923
 
924
 
925
sub eval_exp {
926
        my ($self,$exp,$ref,$ref2,$info)=@_;
927
        my  %vars = %{$ref};
928
        my %nodes_name =%{$ref2};
929
    foreach my $p (sort keys %vars){
930
 
931
        chomp $exp;
932
                ($exp=$exp)=~ s/\b$p\b/$vars{$p}/g;
933
 
934
 
935
    }
936
 
937
    my ($s1, $n1, $p1,$s2, $n2, $p2 ) = sscanf("%s[%s]P[%s]->%s[%s]P[%s]", $exp);
938
 
939
 
940
$n1 = eval $n1;
941
$p1 = eval $p1;
942
 
943
$n2 = eval $n2;
944
$p2 = eval $p2;
945
 
946
 
947
my $string= "$s1 [$n1] P [$p1] -> $s2 [$n2] P [$p2]\n";
948
 
949
my $node1=$nodes_name{$s1.$n1};
950
my $node2=$nodes_name{$s2.$n2};
951
 
952
if(!defined $node1 ){
953
                add_colored_info($info,"No instance is named as \"$s1$n1\";\n","red") if (defined $info);
954
                return;
955
        }
956
        if( !defined $node2 ){
957
                add_colored_info($info,"No instance is named as \"$s2$n2\";\n","red") if (defined $info);
958
                return;
959
        }
960
 
961
 
962
 connect_nodes ($self,$node1,"Port[$p1]",$node2,"Port[$p2]",$info);
963
 
964
 
965
add_info($info,"$string") if (defined $info);
966
 
967
 
968
}
969
 
970
###########
971
# connection_page_auto
972
##########      
973
 
974
sub connection_page_auto{
975
        my ($self,$info)=@_;
976
        my $table= def_table(2,10,FALSE);
977
        my $row=0;
978
        my $col=0;
979
 
980
        initial_node_info($self);
981
 
982
        my $help1 =  "Define the minimum number of endpoints that can be connected to a single router. Routers in the topology will have either at least a minum endpoint number or they will have no endpoints at all.";
983
        my $help2 =  "Define the manimum number of endpoints that can be connected to a single router.";
984
        my $help3 =  undef;
985
 
986
 
987
 
988
        my @widgets = (
989
        { label=>"Minimum Endp per Router",        param_name=>'MIN_ENDP_PER_ROUTER',   type=>"Spin-button",     default_val=>1, content=>"1,1024,1", info=>$help1, param_parent=>'connection_auto', ref_delay=> undef},
990
        { label=>"Maximum Endp per Router",        param_name=>'MAX_ENDP_PER_ROUTER',   type=>"Spin-button",     default_val=>1, content=>"1,1024,1", info=>$help2, param_parent=>'connection_auto', ref_delay=> undef},
991
        { label=>"Endp per Router distribution",   param_name=>'ENDP_PER_ROUTER_DIST',   type=>"Combo-box",     default_val=>"uniform", content=>"uniform,random", info=>$help3, param_parent=>'connection_auto', ref_delay=> undef},
992
        { label=>"Topology Dimention",             param_name=>'DIMENTION',   type=>"Combo-box",     default_val=>"2D", content=>"2D,3D", info=>undef, param_parent=>'connection_auto', ref_delay=> undef},
993
 
994
                );
995
 
996
 
997
 
998
        foreach my $d (@widgets) {
999
                my $w;
1000
                ($row,$col,$w)=add_param_widget ($self, $d->{label}, $d->{param_name}, $d->{default_val}, $d->{type}, $d->{content}, $d->{info}, $table,$row,$col,1, $d->{param_parent}, $d->{ref_delay},undef,"vertical");
1001
 
1002
        }#foreach
1003
 
1004
 
1005
 
1006
 
1007
        my $auto = def_image_button('icons/gen.png','Auto Connect');
1008
        $table->attach ($auto,1, 2,  $row, $row+1,'fill','fill',2,2);
1009
        $auto-> signal_connect("clicked" => sub{
1010
                        auto_connect($self,$info);
1011
        });
1012
 
1013
        my $clean = def_image_button('icons/clear.png','Remove All Connection');
1014
        $table->attach ($clean,0,1 ,  $row, $row+1,'fill','fill',2,2);
1015
        $clean-> signal_connect("clicked" => sub{
1016
                        remove_all_connection($self);
1017
        });
1018
 
1019
 
1020
 
1021
        return $table;
1022
}
1023
 
1024
sub get_new_val_based_on_dist {
1025
        my ($total_router,$total_endp, $router_Pnum,$min_endp,$max_endp,$dist_endp)=@_;
1026
 
1027
        if($dist_endp eq "uniform"){
1028
                my $a = int($total_endp/$total_router);
1029
                return $a if($a >= $min_endp && $a <$router_Pnum );
1030
                return $min_endp if($a < $min_endp  );
1031
                return $router_Pnum -1 if($a >= $router_Pnum ) ;
1032
        }
1033
        #random distribution    
1034
        my $a = int(rand($max_endp - $min_endp +1)) + $min_endp;
1035
        return $a if($a >= $min_endp && $a <$router_Pnum );
1036
        return $min_endp if($a < $min_endp  );
1037
        return $router_Pnum -1 if($a >= $router_Pnum) ;
1038
}
1039
 
1040
 
1041
sub assign_endp_num_based_on_dist {
1042
        my ($self,$routers_ref,$total_endp, $min_endp,$max_endp,$dist_endp,$info)=@_;
1043
        my @routers = @{$routers_ref};
1044
        my %assigned;
1045
        my $total_router = scalar @routers;
1046
        my $valid=1;
1047
        while ($total_endp > 0 && $valid ==1){
1048
                $valid =0;
1049
                foreach my $r (reverse @routers) {
1050
                        my $router_Pnum=$self->object_get_attribute("$r",'PNUM');
1051
                        my $val  = $assigned{$r};
1052
                        if (!defined $val) {
1053
                                $val=0;
1054
                                $assigned{$r}=0;
1055
                        }
1056
                        if ($min_endp >=$router_Pnum || $total_endp ==0 ){
1057
 
1058
                        } else{
1059
                        my $new =get_new_val_based_on_dist ($total_router,$total_endp, $router_Pnum,$min_endp,$max_endp,$dist_endp);
1060
                                $new =$val + $total_endp  if(($new - $val) > $total_endp);
1061
                                if  ($new<$min_endp){
1062
 
1063
                                }
1064
                                elsif ($new > $val){
1065
                                        $assigned{$r} = $new;
1066
                                        $total_endp-=($new - $val);
1067
                                        $valid = 1;
1068
                                } elsif ($val < $router_Pnum-2 && $val +1 <=$max_endp ){
1069
                                        $assigned{$r} = $val +1;
1070
                                        $total_endp-=1;
1071
                                        $valid = 1;
1072
                                }
1073
                        }#else
1074
                }#for           
1075
 
1076
        }#while
1077
 
1078
        if ($total_endp > 0) {
1079
                add_colored_info($info, "Error: Unable to assign all endpoits to routers using requested configuration. Total of $total_endp endpoints left unconnected\n",'red');
1080
                return (\%assigned,0);
1081
        }
1082
 
1083
        return (\%assigned,1);
1084
 
1085
}
1086
 
1087
#list the manhatan distance of all nodes in dimention ($xd,$yd,$zd) to the node located in ($xm,$ym,$zm)
1088
sub list_manhatan_distance {
1089
        my ($xd,$yd,$zd,$xm,$ym,$zm)=@_;
1090
        my %manhatan;
1091
        for( my $x=0; $x<$xd;$x++){
1092
                for( my $y=0; $y<$yd;$y++){
1093
                        for( my $z=0; $z<$zd;$z++){
1094
                                $manhatan{"$x,$y,$z"} = abs($x-$xm) + abs($y-$ym) + abs($z-$zm);
1095
                        }
1096
                }
1097
        }
1098
        return %manhatan;
1099
}
1100
 
1101
 
1102
 
1103
sub auto_connect {
1104
        my ($self,$info)=@_;
1105
        show_colored_info($info, "Start auto connecting Nodes\n",'blue');
1106
        add_info($info, "Step 1: Connect endpoints to the routers:\n");
1107
 
1108
 
1109
        my $min_endp  = $self->object_get_attribute('connection_auto','MIN_ENDP_PER_ROUTER');
1110
        my $max_endp  = $self->object_get_attribute('connection_auto','MAX_ENDP_PER_ROUTER');
1111
        my $dist_endp = $self->object_get_attribute('connection_auto','ENDP_PER_ROUTER_DIST');
1112
        my $dimention = $self->object_get_attribute('connection_auto','DIMENTION');
1113
 
1114
 
1115
        #check min and max is correct
1116
        if($min_endp > $max_endp ){
1117
                add_colored_info($info, "Error: Invalid Min & Max range for endpoint router numbr per router. MAX_ENDP_PER_ROUTER shuld >= MIN_ENDP_PER_ROUTER\n",'red');
1118
        }
1119
 
1120
        initial_node_info($self);
1121
 
1122
        my @all_endpoints=get_list_of_all_endpoints($self);
1123
        my @routers=get_list_of_all_routers($self);
1124
 
1125
        #connect endpoints
1126
        my ($ref,$result)  = assign_endp_num_based_on_dist ($self,\@routers,scalar @all_endpoints, $min_endp,$max_endp,$dist_endp,$info);
1127
        my %assign = %{$ref};
1128
        my %router_free_port;
1129
        foreach my $r (reverse @routers) {
1130
                $router_free_port{$r}=$self->object_get_attribute("$r",'PNUM');
1131
                my $num = $assign{$r};
1132
                for (my $p=0; $p<$num;$p++){
1133
                        my $e = pop (@all_endpoints);
1134
                        connect_nodes ($self,$r,"Port[$p]",$e,"Port[0]",$info);
1135
                        my $rinst=$self->object_get_attribute("$r",'NAME');
1136
                        my $einst=$self->object_get_attribute("$e",'NAME');
1137
                        add_info($info,"\t connect $rinst-Port[$p] -> $einst-Port[0]\n",$info);
1138
                        $router_free_port{$r}=$router_free_port{$r}-1;
1139
                }
1140
        }
1141
 
1142
        #get dimention 
1143
        my $routers_num =scalar @routers;
1144
        my ($xd,$yd,$zd)=(1,1,1);
1145
        ($xd,$yd)= network_dim_cal ($routers_num) if ($dimention eq '2D');
1146
        ($xd,$yd,$zd)=network_3dim_cal ($routers_num) if ($dimention eq '3D');
1147
        add_info($info, "Step 2: Map $routers_num routers in (x=$xd , y=$yd , z=$zd) dimention. Routers with higher number of free ports located in center:\n");
1148
 
1149
        #obtain routers location 
1150
        #center loc
1151
        my $xmid =int($xd/2);
1152
        my $ymid =int($yd/2);
1153
        my $zmid =int($zd/2);
1154
 
1155
        #sort location based on manhatan distanc from the center
1156
        my %manhatan = list_manhatan_distance ($xd,$yd,$zd,$xmid,$ymid,$zmid);
1157
        my @sort_locs = (sort { $manhatan{$a} <=> $manhatan{$b} } keys %manhatan);
1158
 
1159
        #sort routers based on avilable ports
1160
        my @sort_routers = (sort { $router_free_port{$b} <=> $router_free_port{$a} } keys %router_free_port);
1161
 
1162
        #assign sorted routers to sorted locations 
1163
        my %locations;
1164
        foreach my $r (@sort_routers){
1165
        my $loc = shift @sort_locs;
1166
        my $inst=$self->object_get_attribute("$r",'NAME');
1167
        add_info($info, "\t $inst with $router_free_port{$r} free port placed in $loc location\n");
1168
        $self->object_add_attribute("$r",'LOC_ASIC',$loc);
1169
        $locations{$loc}=$r;
1170
        }
1171
 
1172
        #start from the center and connect each router to the N nearest router
1173
        add_info($info,"Step3 : start from the center and connect each router to the N nearest router\n",$info);
1174
        foreach my $r (@sort_routers){
1175
 
1176
                my $avb_P_num =$router_free_port{$r};
1177
                my @up = list_node_unconnected_port($self,$r);
1178
                my @cp = list_node_connected_port ($self,$r);
1179
                my $loc = $self->object_get_attribute("$r",'LOC_ASIC');
1180
                my ($xc,$yc,$zc)=split(',',$loc);
1181
                my %manhatan = list_manhatan_distance ($xd,$yd,$zd,$xc,$yc,$zc);
1182
                my @sort_locs = (sort { $manhatan{$a} <=> $manhatan{$b} } keys %manhatan);
1183
 
1184
                while (scalar @up && scalar @sort_locs){
1185
                        #select one unconnected port from current router
1186
                        my $p = shift @up;
1187
                        my $cr;
1188
                        my $cp;
1189
                        while (scalar @sort_locs && !defined $cp){
1190
                                #select the nearest router to current one
1191
                                my $cl =shift @sort_locs;
1192
                                $cr=$locations{$cl};
1193
                                next if(!defined $cr);
1194
                                next if ($cr eq $r); #thes two routers are identical
1195
                                #check if they are not connected
1196
                                my $line =get_connection_port_num_between_two_nodes($self,$r,$cr);
1197
                                next if (defined $line); #these two routers are already connected
1198
                                my @up_cr = list_node_unconnected_port($self,$cr);
1199
                                next if (scalar @up_cr == 0); # the target router has no free port
1200
                                $cp=$up_cr[0];
1201
                        }
1202
                        last if(!defined $cp);
1203
                        my $rinst=$self->object_get_attribute("$r",'NAME');
1204
                        my $einst=$self->object_get_attribute("$cr",'NAME');
1205
                        add_info($info,"\t connect $rinst-$p -> $einst-$cp\n",$info);
1206
                        connect_nodes ($self,$r,"$p",$cr,"$cp",$info);
1207
                }
1208
 
1209
        }
1210
 
1211
 
1212
 
1213
 
1214
 
1215
 
1216
        set_gui_status($self,"ref",1);
1217
 
1218
 
1219
 
1220
 
1221
 
1222
}
1223
 
1224
sub routing_page_auto{
1225
        my ($self,$info)=@_;
1226
        my $table= def_table(2,10,FALSE);
1227
        my $row=0;
1228
        my $col=0;
1229
 
1230
 
1231
        $self->object_add_attribute('routing','type','turn_model');
1232
 
1233
 
1234
 
1235
        my $auto = def_image_button('icons/gen.png','AutoGenerate');
1236
        #$table->attach ($auto,0, 1,  $row, $row+1,'fill','fill',2,2);
1237
        my $clear = def_image_button('icons/clear.png','Clear');
1238
        #$table->attach ($clear,2,3 ,  $row, $row+1,'fill','fill',2,2);$row++;
1239
 
1240
        my $box= def_pack_hbox( FALSE, 0 , $auto,$clear);
1241
        $table->attach ($box,0,5 ,  $row, $row+1,'fill','fill',2,2);$row++;
1242
 
1243
        $auto-> signal_connect("clicked" => sub{
1244
                        auto_route($self,$info);
1245
        });
1246
 
1247
        $clear-> signal_connect("clicked" => sub{
1248
                        clean_route($self,$info);
1249
        });
1250
 
1251
        my $manual = get_route_manual ($self,$info);
1252
 
1253
        my $mtable= def_table(2,2,FALSE);
1254
 
1255
        $mtable->attach_defaults ($table  , 0, 1, 0,1);
1256
        $mtable->attach_defaults ($manual  , 0, 1, 1,2);
1257
 
1258
        return $mtable;
1259
}
1260
 
1261
sub update_acycle_model {
1262
        my ($self,$alg_name,$info)=@_;
1263
        my $tmp_dir  = "$ENV{'PRONOC_WORK'}/tmp";
1264
        my $model_file = "$tmp_dir/$alg_name.alg";
1265
        my ($pp,$r,$err) = regen_object($model_file);
1266
        if ($r){
1267
                add_colored_info($info,"**Error: cannot open $model_file file: $err\n",'red');
1268
                $self->object_add_attribute('routing_auto','acyclic_turns_model',undef);
1269
                return;
1270
        } else {
1271
                add_info($info,"Use $alg_name algorithm for obtaing acyclic paths\n");
1272
        }
1273
 
1274
        my @acyclic_turns = @{$pp};
1275
        $self->object_add_attribute('routing_auto','acyclic_turns_model',\@acyclic_turns);
1276
 
1277
}
1278
 
1279
 
1280
sub routing_page_manual{
1281
        my ($self,$info)=@_;
1282
        my $table= def_table(2,10,FALSE);
1283
        my $row=0;
1284
        my $col=0;
1285
 
1286
        $self->object_add_attribute('routing','type','minimal');
1287
 
1288
        initial_node_info($self);
1289
        my $help1 =  "Define the offset path value that is the maximum difference between the lentght of all paths which are extracted for any specefic source-destination endpoints pair. Define this valuse as zero for Minimal-path (MIN) routing algorithms.";
1290
        my $help2 =  "Define the maximum number of routers (path length) paths which should be extracted for any specefic source-destination endpoints pair.";
1291
        my $help3 =  "Define how to extract paths between two endpoints: all-paths: extract all paths between two specific endpoints that match the offset size and maximum size parameters. Cycle-free: only paths which do not generate a cyclic dependency in routing graph are extracted.";
1292
 
1293
 
1294
        my @widgets = (
1295
        { label=>"Route path offset size ",        param_name=>'OFFSET',   type=>"Spin-button",     default_val=>1, content=>"0,1024,1", info=>$help1, param_parent=>'routing_auto', ref_delay=>"1",ref_state=> undef},
1296
        { label=>"Route path maximum size",        param_name=>'MAX_LENGTH',   type=>"Spin-button",     default_val=>1000, content=>"1,1024,1", info=>$help2, param_parent=>'routing_auto', ref_delay=>"1",ref_state=> undef},
1297
        { label=>"Route paths select",        param_name=>'PATH_SELECT',   type=>"Combo-box",     default_val=>"Cycle-free paths", content=>"all-paths,Cycle-free paths", info=>$help3, param_parent=>'routing_auto', ref_delay=>"1",ref_state=> undef },
1298
 
1299
        );
1300
 
1301
 
1302
        foreach my $d (@widgets) {
1303
                my $w;
1304
                ($row,$col,$w)=add_param_widget ($self, $d->{label}, $d->{param_name}, $d->{default_val}, $d->{type}, $d->{content}, $d->{info}, $table,$row,$col,1, $d->{param_parent}, $d->{ref_delay},$d->{ref_state},"vertical");
1305
 
1306
        }#foreach
1307
        my $offset = $self->object_get_attribute('routing_auto','OFFSET');
1308
        my $max_len = $self->object_get_attribute('routing_auto','MAX_LENGTH');
1309
 
1310
        my $auto = def_image_button('icons/gen.png','AutoGenerate');
1311
 
1312
        my $path_select= $self->object_get_attribute("routing_auto",'PATH_SELECT');
1313
        if($path_select eq "Cycle-free paths") {
1314
                my %algorithms;
1315
                my $ref  =$self->object_get_attribute('routing_auto','acyclic_algorithms');
1316
                %algorithms = %{$ref} if defined $ref;
1317
                my @algs = sort { $algorithms{$a} <=> $algorithms{$b} } keys(%algorithms);
1318
                my ($content,$default);
1319
                foreach my $alg (@algs){
1320
                        $content.="$alg  --  $algorithms{$alg},";
1321
                        $default= "$alg  --  $algorithms{$alg};";
1322
 
1323
                }
1324
                if (!defined $content){
1325
                        $content='-';
1326
                        $default='-';
1327
 
1328
                }
1329
 
1330
                my $alg;
1331
                ($row,$col,$alg)=add_param_widget ($self,"cycle-remove algorithm:" , "CYCLE_FREE_ALG",$default , "Combo-box", $content, undef, $table,$row,$col,1,'routing_auto', undef,undef,"vertical");
1332
 
1333
                $alg->signal_connect("changed" => sub{
1334
                        my $comb_text = $alg->get_active_text();
1335
                        my ($alg_name,$line) = split (/\s+--\s+/,$comb_text);
1336
                        update_acycle_model ($self,$alg_name,$info);
1337
                        #print "bbbb:@acyclic_turns\n"; 
1338
                });
1339
 
1340
                $auto-> signal_connect("clicked" => sub{
1341
                        auto_route($self,$info);
1342
                });
1343
 
1344
 
1345
        }
1346
 
1347
 
1348
 
1349
 
1350
        my $clear = def_image_button('icons/clear.png','Clear');
1351
        my $gen_cycle_free = def_image_button('icons/turn.png','Generate Cycle-free Paths');
1352
 
1353
        if($path_select eq 'Cycle-free paths') {
1354
                $table->attach ($gen_cycle_free,0,2 ,  $row, $row+1,'fill','fill',2,2);$row++;
1355
                $table->attach ($auto,2, 3,  $row, $row+1,'fill','fill',2,2);
1356
 
1357
        }
1358
        $table->attach ($clear,0,2 ,  $row, $row+1,'fill','fill',2,2);$row++;
1359
 
1360
 
1361
        $clear-> signal_connect("clicked" => sub{
1362
                        clean_route($self,$info);
1363
        });
1364
 
1365
        $gen_cycle_free -> signal_connect("clicked" => sub{
1366
                        gen_aciclic_turn_graph($self,$info);
1367
                        my %algorithms;
1368
                        my $ref  =$self->object_get_attribute('routing_auto','acyclic_algorithms');
1369
                        %algorithms = %{$ref} if defined $ref;
1370
                        my @algs = sort { $algorithms{$a} <=> $algorithms{$b} } keys(%algorithms);
1371
                        update_acycle_model ($self,$algs[0],$info);
1372
                        set_gui_status($self,'ref',1);
1373
        });
1374
 
1375
        my $manual = get_route_manual ($self,$info);
1376
 
1377
        my $mtable= def_table(2,2,FALSE);
1378
 
1379
        $mtable->attach_defaults ($table  , 0, 1, 0,1);
1380
        $mtable->attach_defaults ($manual  , 0, 1, 1,2);
1381
 
1382
        return $mtable;
1383
}
1384
 
1385
 
1386
 
1387
 
1388
sub get_route_manual {
1389
        my ($self,$info)=@_;
1390
 
1391
        my $row=0;
1392
        my $col=0;
1393
 
1394
        my $table= def_table(2,10,FALSE);
1395
 
1396
        add_Hsep_to_table ($table,0, 200,  $row);$row++;
1397
 
1398
        my $refresh = def_image_button('icons/refresh.png','Refresh');
1399
        $table->attach ($refresh,0,5 ,  $row, $row+1,'fill','fill',2,2);$row++;
1400
 
1401
 
1402
        $table->attach (gen_colored_label('Not selected',17),5,10,$row,$row+1,'fill','shrink',2,2);
1403
        $table->attach (gen_colored_label('Selected',0),10,15,$row,$row+1,'fill','shrink',2,2);
1404
        $table->attach (gen_colored_label('Not Existed',11),15,20,$row,$row+1,'fill','shrink',2,2);
1405
        $row++;
1406
 
1407
        $table->attach (def_label(' source -> destination '),10,15,$row,$row+1,'fill','shrink',2,2);
1408
    $row++;
1409
 
1410
 
1411
        my @all_endpoints=get_list_of_all_endpoints($self);
1412
 
1413
        foreach  my $src  (@all_endpoints ){
1414
                foreach  my $dst  (@all_endpoints ){
1415
                        my $src_inst=$self->object_get_attribute("$src",'NAME');
1416
                        my $dst_inst=$self->object_get_attribute("$dst",'NAME');
1417
                        my $select = $self->object_get_attribute('Route',"${src}::$dst");
1418
 
1419
                        #my ($paths_to_dst,$ports_to_dst); #= get_all_paths_between_two_endps($self,$src, $dst);
1420
                        #my $color =(scalar @{$paths_to_dst}==0)? 11 :  (defined $select)? 0 : 17;                                      
1421
                        #my $button = ($src_inst ne $dst_inst )?  def_colored_button("${src_inst}->$dst_inst",$color): gen_label_in_center(' - ');      
1422
 
1423
                        my $color = (defined $select)? 0 :17;
1424
                        my $button = ($src_inst ne $dst_inst )?  def_colored_button("${src_inst}->$dst_inst",$color): gen_label_in_center(' - ');
1425
 
1426
 
1427
                        attach_widget_to_table ($table,$row,undef,undef,$button,$col);  $col+=4;
1428
 
1429
 
1430
 
1431
                        $button->signal_connect("clicked" => sub {
1432
                                $self->object_add_attribute("SELECT_PATH","src",$src);
1433
                                $self->object_add_attribute("SELECT_PATH","dst",$dst);
1434
                                set_gui_status($self,"redraw",1);
1435
 
1436
                        }) if($src_inst ne $dst_inst );
1437
 
1438
 
1439
                }$row++;$col=0;
1440
        }
1441
 
1442
 
1443
        $refresh->signal_connect("clicked" => sub{
1444
                        refresh_route_manual($self,$info);
1445
        });
1446
 
1447
        return $table;
1448
}
1449
 
1450
 
1451
sub refresh_route_manual {
1452
        my ($self,$info)=@_;
1453
        my @all_endpoints=get_list_of_all_endpoints($self);
1454
 
1455
        my $path_select= $self->object_get_attribute("routing_auto",'PATH_SELECT');
1456
        my @acyclic_turns;
1457
 
1458
 
1459
        if ($path_select ne "all-paths"){
1460
                 my $ref = $self->object_get_attribute('routing_auto','acyclic_turns_model');
1461
                 if(defined $ref) {
1462
                        @acyclic_turns = @{$ref};
1463
                 }else{
1464
                        add_colored_info($info,"Info:No acyclic route model is selected\n",'green');
1465
 
1466
                 }
1467
        }
1468
 
1469
        foreach  my $src  (@all_endpoints ){
1470
                foreach  my $dst  (@all_endpoints ){
1471
                        my $src_inst=$self->object_get_attribute("$src",'NAME');
1472
                        my $dst_inst=$self->object_get_attribute("$dst",'NAME');
1473
                        my $select = $self->object_get_attribute('Route',"${src}::$dst");
1474
 
1475
                        my ($ref1,$ref2)= ($path_select eq "all-paths")? get_all_paths_between_two_endps($self,$src, $dst) : get_all_paths_between_two_endps_using_accyclic_turn($self,$src, $dst,\@acyclic_turns) ;
1476
                        my @paths = @{$ref1};
1477
                        if (defined $select){
1478
                                #check if select exist in @paths
1479
                                my $match=0;
1480
 
1481
                                foreach  my $p (@paths ){
1482
                                        my @a1 = @{$p};
1483
                                        my @a2 = @{$select};
1484
                                        my $st1=join('->',@a1);
1485
                                        my $st2=join('->',@a2);
1486
                                        if($st1 eq $st2){
1487
                                                $match=1;
1488
                                        }
1489
                                }#foreach
1490
                                #remove it from the selected path
1491
                                if ($match ==0){
1492
                                        my $selp;
1493
                                        foreach my $q ( @{$select}){
1494
                                                my $inst=$self->object_get_attribute("$q",'NAME');
1495
                                                $selp= (defined $selp)? $selp."->$inst" : $inst;
1496
                                        }
1497
 
1498
                                        add_info ($info,"$selp does not exist in path list anymore and it has been removed\n");
1499
                                        $self->object_add_attribute('Route',"${src}::$dst",undef);
1500
                                }#if 
1501
                        }#if 
1502
                }#foreach
1503
        }#foreach               
1504
 
1505
 
1506
        set_gui_status($self,"ref",1);
1507
 
1508
}
1509
 
1510
 
1511
sub route_info_window{
1512
        my ($self,$info)= @_;
1513
        my $w1 = show_paths_between_two_endps($self,$info);
1514
        my $w2 = routing_summary($self,$info);
1515
        my $h1=gen_hpaned($w1,.30,$w2);
1516
        return $h1;
1517
}
1518
 
1519
 
1520
 
1521
sub add_route_edge_to_graph{
1522
        my ($gref,$anodes_ref)=@_;
1523
        my %graph=%{$gref};
1524
        my @a_nodes= @{$anodes_ref};
1525
 
1526
        my $old_r;
1527
        foreach my $r (@a_nodes){
1528
 
1529
                if(defined $old_r){
1530
                                push(@{$graph{$old_r}},$r);
1531
                }
1532
                $old_r=$r;
1533
        }
1534
 
1535
        return %graph;
1536
}
1537
 
1538
sub get_adjacent_node_in_a_path{
1539
        my $ref=shift;
1540
        my @result;
1541
        my @path=@{$ref};
1542
        my $old_r;
1543
        foreach my $r (@path){
1544
                push (@result,"${old_r}::$r") if(defined $old_r);
1545
                $old_r=$r;
1546
        }
1547
        return @result;
1548
 
1549
}
1550
 
1551
sub get_adjacent_router_in_a_path{
1552
 
1553
        my $ref=shift;
1554
        my @result;
1555
        my @path=@{$ref};
1556
        shift @path; #remove source node from the path
1557
        pop @path; #remove the destination node from the path
1558
 
1559
 
1560
        my $old_r;
1561
        foreach my $r (@path){
1562
                push (@result,"${old_r}::$r") if(defined $old_r);
1563
                $old_r=$r;
1564
        }
1565
        return @result;
1566
 
1567
}
1568
 
1569
 
1570
sub get_route_info{
1571
        my ($self)=@_;
1572
        my %R_num;
1573
        my %L_num;
1574
        my @all_endpoints=get_list_of_all_endpoints($self);
1575
        foreach  my $r  (@all_endpoints ){
1576 56 alirezamon
                #$R_num{$r} =0;
1577 48 alirezamon
        }
1578
        my @nodes=get_list_of_all_routers($self);
1579
        foreach my $p (@nodes){
1580
                $R_num{$p} =0;
1581
        }
1582
        foreach  my $src  (@all_endpoints ){
1583
                foreach  my $dst  (@all_endpoints ){
1584
                        my $path = $self->object_get_attribute('Route',"${src}::$dst");
1585 56 alirezamon
                        if (defined $path){
1586 48 alirezamon
                                #router counting
1587
                                my @p=@{$path};
1588 56 alirezamon
                                shift @p; #remove source node from the path
1589
                                pop @p; #remove the destination node from the path
1590 48 alirezamon
                                foreach my $r (@p){
1591
                                        $R_num{$r} ++;
1592
                                }
1593
                                #path counting
1594
                                @p=     get_adjacent_router_in_a_path($path);
1595
                                foreach my $r (@p){
1596
                                        $L_num{$r} ++;
1597
 
1598
                                }
1599
 
1600
 
1601
                        }
1602
                }
1603
        }
1604
 
1605
        my @Rkeys = sort { $R_num{$a} <=> $R_num{$b} } keys(%R_num);
1606
        my @Lkeys = sort { $L_num{$a} <=> $L_num{$b} } keys(%L_num);
1607
        my $sample="sample0";
1608
        foreach  my $r  (@nodes ){
1609
                my $inst=$self->object_get_attribute("$r",'NAME');
1610
                update_result ($self,$sample,"router_all_paths_result",'-',$inst,$R_num{$r});
1611
        }
1612
 
1613
        my $max_r = (defined $Rkeys[-1]) ? $R_num{$Rkeys[-1]} : 0;
1614
        my $min_r = (defined $Rkeys[ 0]) ? $R_num{$Rkeys[ 0]} : 0;
1615
        my $max_l = (defined $Lkeys[-1]) ? $L_num{$Lkeys[-1]} : 0;
1616
        my $min_l = (defined $Lkeys[ 0]) ? $L_num{$Lkeys[ 0]} : 0;
1617
        my @l = sort  values (%L_num);
1618
        my $std_l=stdev(\@l);
1619
 
1620
        $self->object_add_attribute ($sample,"link_all_paths_result",undef);
1621
 
1622
        my $nn=0;
1623
        my $min_l_name="-";
1624
        my $max_l_name="-";
1625
        my $siz = $#Lkeys;
1626
        foreach  my $r  (@Lkeys ){
1627
                my ($n1,$n2)=split(/::/,$r);
1628
                my $inst1=$self->object_get_attribute("$n1",'NAME');
1629
                my $inst2=$self->object_get_attribute("$n2",'NAME');
1630
                my $inst = "$inst1-$inst2";
1631
                update_result ($self,$sample,"link_all_paths_result",'-',$inst,$L_num{$r});
1632
                $min_l_name= $inst if($nn==0);
1633
                $max_l_name= $inst if($nn==$siz-1);
1634
                $nn++;
1635
        }
1636
 
1637
 
1638
 
1639
        my $max_r_name= (defined $Rkeys[-1])? $self->object_get_attribute("$Rkeys[-1]",'NAME') : "-";
1640
        my $min_r_name= (defined $Rkeys[0]) ? $self->object_get_attribute("$Rkeys[0]",'NAME') : "-";
1641
 
1642
        $max_r_name= "-" if (!defined $max_r_name);
1643
        $min_r_name= "-" if (!defined $min_r_name);
1644
 
1645
 
1646
        return ($max_r,$min_r,$max_l,$min_l,$std_l,$max_r_name,$min_r_name,$max_l_name,$min_l_name);
1647
}
1648
 
1649
 
1650
sub routing_summary{
1651
        my ($self,$info)= @_;
1652
 
1653
        my $sc_win = gen_scr_win_with_adjst($self,'map_info');
1654
        #my $table= def_table(10,10,FALSE);
1655
 
1656
 
1657
        my $row=0;
1658
        my $col=0;
1659
        my ($max_r,$min_r,$max_l,$min_l,$std_l,$max_r_name,$min_r_name,$max_l_name,$min_l_name)=get_route_info($self);
1660
 
1661
 
1662
        my @data = (
1663
   {0 => "The Maximum number that a router is used in routing",  1 =>"$max_r", 2 =>"$max_r_name"}, # The maximum number that a router is located in all paths between all source-destination pair in this routing algorithm.
1664
   {0 => "The Minimum number that a router is used in routing",  1 =>"$min_r", 2 =>"$min_r_name" },
1665
   {0 => "The Maximum number that a link is used in routing ",  1 =>"$max_l", 2 =>"$max_l_name"}, # The maximum number that a node-2-node link is located in all paths between all source-destination pair in this routing algorithm.
1666
   {0 => "The Minimum number that a link is used in routing",  1=>"$min_l", 2 =>"$min_l_name" },
1667
   {0 => "Link usage  standard deviation ",  1 =>"$std_l" }
1668
  );
1669
 
1670
 
1671
 
1672
        my @clmn_type = ('Glib::String',  # => G_TYPE_STRING
1673
                                    'Glib::String',
1674
                                    'Glib::String'); # you get the idea
1675
 
1676
        my @clmns = ("Routing Summary", " ", " ");
1677
 
1678
        my $list=       gen_list_store (\@data,\@clmn_type,\@clmns);
1679
 
1680
 
1681
        add_widget_to_scrolled_win($list,$sc_win);
1682
 
1683
        my $charts =  gen_routing_charts($self,$info);
1684
 
1685
        my $v1=gen_vpaned($sc_win,.25,$charts);
1686
 
1687
        $sc_win->show_all;
1688
 
1689
        return $v1;
1690
 
1691
}
1692
 
1693
 
1694
sub gen_routing_charts{
1695
 
1696
        my ($self,$info)=@_;
1697
 
1698
        my @pages =(
1699
        {page_name=>" # Routers in all Paths", page_num=>0},
1700
        {page_name=>" # Links in all Paths ", page_num=>1}
1701
);
1702
 
1703
 
1704
 
1705
my @charts = (
1706
        { type=>"3D_bar", page_num=>0, graph_name=> "# Router in all Paths", result_name => "router_all_paths_result", X_Title=> 'Router Name', Y_Title=>'The total number that a router is used in the routing', Z_Title=>undef},
1707
        { type=>"3D_bar", page_num=>1, graph_name=> "# Links in all paths", result_name => "link_all_paths_result", X_Title=> 'Connection Link', Y_Title=>'The total number that a link is used in the routing', Z_Title=>undef},
1708
        #{ type=>"2D_line", page_num=>0, graph_name=> "SD latency", result_name => "sd_latency_result", X_Title=> 'Desired Avg. Injected Load Per Router (flits/clock (%))', Y_Title=>'Latency Standard Deviation (clock)', Z_Title=>undef},
1709
        #{ type=>"3D_bar",  page_num=>1, graph_name=> "Received", result_name => "packet_rsvd_result", X_Title=>'Core ID' , Y_Title=>'Received Packets Per Router', Z_Title=>undef},
1710
        #{ type=>"3D_bar",  page_num=>1, graph_name=> "Sent", result_name => "packet_sent_result", X_Title=>'Core ID' , Y_Title=>'Sent Packets Per Router', Z_Title=>undef},
1711
 
1712
        );
1713
 
1714
 
1715
        my $chart   =gen_multiple_charts  ($self,\@pages,\@charts,.3);
1716
    return $chart;
1717
 
1718
}
1719
 
1720
 
1721
 
1722
 
1723
sub show_paths_between_two_endps{
1724
        my ($self,$info)= @_;
1725
        my $table=def_table(20,20,FALSE);
1726
 
1727
        my $row-=0;
1728
        my $col=0;
1729
 
1730
        my $src = $self->object_get_attribute("SELECT_PATH","src");
1731
        my $dst = $self->object_get_attribute("SELECT_PATH","dst");
1732
 
1733
        my @acyclic_turns;
1734
        my $path_select= $self->object_get_attribute("routing_auto",'PATH_SELECT');
1735
        if ($path_select ne "all-paths"){
1736
                 my $ref = $self->object_get_attribute('routing_auto','acyclic_turns_model');
1737
                 if(defined $ref) {
1738
                        @acyclic_turns = @{$ref};
1739
                 }else{
1740
                        add_colored_info($info,"Info:No acyclic route model is selected\n",'green');
1741
 
1742
                 }
1743
        }
1744
 
1745
 
1746
 
1747
 
1748
 
1749
        if(defined $src && defined $dst ){
1750
                my $s= $self->object_get_attribute("$src","NAME");
1751
                my $d= $self->object_get_attribute("$dst","NAME");
1752
                $table->attach (def_label("Select path between $s to $d" ),$col,$col+10,$row,$row+1,'fill','shrink',2,2);
1753
                add_info($info,"get list of all paths between $s to $d \n") if (defined $info);
1754
                $row=1;
1755
                my ($ref1,$ref2)= ($path_select eq "all-paths") ?  get_all_paths_between_two_endps($self,$src, $dst):
1756
                get_all_paths_between_two_endps_using_accyclic_turn($self,$src, $dst,\@acyclic_turns);
1757
 
1758
 
1759
                my @paths = @{$ref1};
1760
                my @ports= @{$ref2};
1761
                my $n=0;
1762
                my $select = $self->object_get_attribute('Route',"${src}::$dst");
1763
                foreach my $p (@paths){
1764
                        my $scal;
1765
                        my $selp;
1766
                        my $path_num=$n;
1767
                        my $path=$p;
1768
                        foreach my $q ( @{$p}){
1769
                                my $inst=$self->object_get_attribute("$q",'NAME');
1770
                                $scal= (defined $scal)? $scal."->$inst" : $inst;
1771
                        }
1772
 
1773
                        foreach my $q ( @{$select}){
1774
                                my $inst=$self->object_get_attribute("$q",'NAME');
1775
                                $selp= (defined $selp)? $selp."->$inst" : $inst;
1776
                        }
1777
 
1778
 
1779
                        my $check= gen_checkbutton();
1780
                        #print "if($select eq $path)";
1781
                        if(defined $select && defined $scal && defined $selp) {if($selp eq $scal) {$check->set_active(TRUE);}}
1782
                        else {$check->set_active(FALSE);}
1783
 
1784
                        $check-> signal_connect("toggled" => sub{
1785
                                if($check->get_active()) {
1786
 
1787
                                        $self->object_add_attribute('Route',"${src}::$dst",$path);
1788
                                }
1789
                                else {
1790
 
1791
                                        $self->object_add_attribute('Route',"${src}::$dst",undef);
1792
                                }
1793
                                set_gui_status($self,"ref",1);
1794
                        });
1795
 
1796
 
1797
                        my $label =gen_label_in_left("$scal");
1798
                        $table->attach ($check ,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $col++;
1799
                        $table->attach ($label ,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $row++;$col=0;
1800
 
1801
                        $n++;
1802
                }
1803
 
1804
 
1805
        }
1806
 
1807
        return add_widget_to_scrolled_win($table);
1808
 
1809
}
1810
 
1811
 
1812
 
1813
##########
1814
#       save
1815
##########
1816
sub save_network {
1817
        my ($self)=@_;
1818
        # read topology  name
1819
        my $name=$self->object_get_attribute('save_as');
1820
        #print $name;
1821
        my $s= (!defined $name)? 0 : (length($name)==0)? 0 :1;
1822
        if ($s == 0){
1823
                message_dialog("Please set the topology name!");
1824
                return 0;
1825
        }
1826
        # Write object file
1827
        my $fname = "$name.NWM";
1828
        open(FILE,  ">lib/netwmaker/$fname") || die "Can not open: $!";
1829
        print FILE perl_file_header("$fname");
1830
        print FILE Data::Dumper->Dump([\%$self],["nwmaker"]);
1831
        close(FILE) || die "Error closing file: $!";
1832
        message_dialog("Current network maker state is saved as lib/netwmaker/$fname!");
1833
        return 1;
1834
}
1835
 
1836
sub get_all_endp_ids{
1837
        my $self=shift;
1838
        my %e=  $self->object_get_attribute("E");
1839
        my @list = sort keys %e;
1840
        return @list;
1841
 
1842
}
1843
 
1844
 
1845
 
1846
#############
1847
#    load
1848
#############
1849
 
1850
sub load_net_maker{
1851
    my ($self,$info)=@_;
1852
    my $file;
1853
        my $dialog =  gen_file_dialog (undef, 'NWM');
1854
 
1855
 
1856
    my $dir = Cwd::getcwd();
1857
    $dialog->set_current_folder ("$dir/lib/netwmaker")    ;
1858
 
1859
    if ( "ok" eq $dialog->run ) {
1860
        $file = $dialog->get_filename;
1861
        my ($name,$path,$suffix) = fileparse("$file",qr"\..[^.]*$");
1862
        if($suffix eq '.NWM'){
1863
            my ($pp,$r,$err) = regen_object($file );
1864
            if ($r){
1865
                add_info($info,"**Error: cannot open $file file: $err\n");
1866
                 $dialog->destroy;
1867
                return;
1868
            }
1869
 
1870
 
1871
            clone_obj($self,$pp);
1872
 
1873
 
1874
        }
1875
     }
1876
     $dialog->destroy;
1877
     set_gui_status($self,"ref",1)
1878
}
1879
 
1880
 
1881
 
1882
 
1883
 
1884
 
1885
 
1886
sub get_all_paths_between_two_endps{
1887
        my ($self,$src, $dst)=@_;
1888
        my @proceed_nodes;
1889
        my @head_nodes;
1890
 
1891
        my $offset = $self->object_get_attribute('routing_auto','OFFSET');
1892
        my $max_len = $self->object_get_attribute('routing_auto','MAX_LENGTH');
1893
 
1894
        push (@head_nodes,$src);
1895
        push (@proceed_nodes,$src);
1896
 
1897
        my @paths;
1898
        my @ports;
1899
        my @paths_to_dst;
1900
        my @ports_to_dst;
1901
 
1902
        my @first_path=($src);
1903
        my @first_port=(0);
1904
        $paths[0]=\@first_path;
1905
        $ports[0]=\@first_port;
1906
 
1907
        # select one path
1908
        my $n=0;
1909
        my $min_dist=1000000;
1910
        do{
1911
                my @current_path= @{$paths[$n]};
1912
                my @current_port= @{$ports[$n]};
1913
                # get head node
1914
                my $head_node =         $current_path[-1];
1915
                if(defined $head_node){
1916
                        # get connected nodes for all ports 
1917
                        #print "hn=$head_node\n";
1918
                        my $pnum =  $self->object_get_attribute($head_node,'PNUM');
1919
 
1920
                        for (my $i=0;$i<$pnum; $i++){
1921
                                my @new_path=@current_path;
1922
                                my @new_ports=@current_port;
1923
                                my $src_port = "Port[${i}]";
1924
                                my $connect = $self->{$head_node}{'PCONNECT'}{$src_port};
1925
                                if(defined $connect){
1926
                                        my ($node,$pnode)=split(/\s*,\s*/,$connect);
1927
                                        #add connected nodes to head_nodes if they are not in path before
1928
                                        if(!defined get_scolar_pos($node,@new_path)){
1929
                                                my $size=scalar @new_path;
1930
                                                #if ($min_dist > $size){
1931
                                                if( ($min_dist+$offset) > $size &&   $max_len>=$size){
1932
 
1933
 
1934
                                                        push (@new_path,$node);
1935
                                                        push (@new_ports,$pnode);
1936
                                                        push (@paths,\@new_path);
1937
                                                        push (@ports,\@new_ports);
1938
                                                        if($node eq $dst){
1939
                                                                push(@paths_to_dst,\@new_path);
1940
                                                                push(@ports_to_dst,\@new_ports);
1941
                                                                $min_dist=$size+1 if ($min_dist > $size);
1942
                                                        }
1943
                                                }
1944
                                        } #if
1945
                                }
1946
                        }#for
1947
                }
1948
                $n++;
1949
        }while( defined $paths[$n]);
1950
 
1951
        #print "\@paths_to_dst". Dumper(@paths_to_dst). "\n \@ports_to_dst". Dumper(@ports_to_dst) . "\n" ;
1952
 
1953
        return (\@paths_to_dst,\@ports_to_dst);
1954
 
1955
}
1956
 
1957
sub get_path_from_turns {
1958
        my ($self,$ref)=@_;
1959
        my @new_turn = @{$ref} if(defined $ref);
1960
        my @path_nodes;
1961
        my @path_ports;
1962
        my $st2;
1963
        foreach my $code (@new_turn){
1964
                my $pn2  =  $code & 0xF;
1965
                $code >>=4;
1966
                my $rn2  = $code & 0xFFF;
1967
                $code >>=12;
1968
                my $pn1 =$code & 0xF;
1969
                $code >>=4;
1970
                my $rn1=$code;
1971
                my $st1 = ($pn1==1)? "ENDP_${rn1}" : "ROUTER${pn1}_${rn1}";
1972
                $st2 = ($pn2==1)? "ENDP_${rn2}"    : "ROUTER${pn2}_${rn2}";
1973
                push(@path_nodes,$st1);
1974
        }
1975
        push(@path_nodes,$st2);
1976
 
1977
        @path_ports=(0);
1978
        for (my $i=0; $i<scalar @path_nodes-1; $i++){
1979
                my ($p1,$p2) =get_connection_port_num_between_two_nodes($self,$path_nodes[$i],$path_nodes[$i+1]);
1980
                push(@path_ports,"Port[$p2]");
1981
        }
1982
 
1983
        return (\@path_nodes,\@path_ports);
1984
 
1985
}
1986
 
1987
sub get_all_paths_between_two_endps_using_accyclic_turn{
1988
        my ($self,$src, $dst,$ref)=@_;
1989
        my @proceed_turns;
1990
        my @head_turns;
1991
        my @accyclic_turn= @{$ref};
1992
 
1993
        my $offset = $self->object_get_attribute('routing_auto','OFFSET');
1994
        my $max_len = $self->object_get_attribute('routing_auto','MAX_LENGTH');
1995
 
1996
        my @paths_to_dst;
1997
        my @ports_to_dst;
1998
 
1999
        my %graph;
2000
 
2001
        foreach my $str (@accyclic_turn){
2002
                my ($s1,$s2) = split /\s/, $str;
2003
                push(@{$graph{$s1}},$s2);
2004
        }
2005
 
2006
        my $start_turns;
2007
        my $ended_turns;
2008
        my $src_port = "Port[0]";
2009
        my $connect = $self->{$src}{'PCONNECT'}{$src_port};
2010
        if(defined $connect){
2011
                my ($node,$pnode)=split(/\s*,\s*/,$connect);
2012
                $start_turns =  get_turn_code("${src}::${node}");
2013
        }
2014
 
2015
        $connect = $self->{$dst}{'PCONNECT'}{$src_port};
2016
        if(defined $connect){
2017
                my ($node,$pnode)=split(/\s*,\s*/,$connect);
2018
                $ended_turns =  get_turn_code("${node}::${dst}");
2019
        }
2020
 
2021
        push (@head_turns,$start_turns);
2022
    push (@proceed_turns,$start_turns);
2023
 
2024
 
2025
 
2026
 
2027
 
2028
        my @turns;
2029
        my @ports;
2030
        my @turns_to_dst;
2031
        my @first_turn=($start_turns);
2032
 
2033
        $turns[0]=\@first_turn;
2034
 
2035
 
2036
        # select one path
2037
        my $n=0;
2038
        my $min_dist=1000000;
2039
        do{
2040
                my @current_turn= @{$turns[$n]};
2041
                # get head node
2042
                my $head_turn =         $current_turn[-1];
2043
                if(defined $head_turn){
2044
                        #get all turns 
2045
                        my @all_fwd_turns = @{$graph{$head_turn}} if (defined $graph{$head_turn});
2046
 
2047
                        foreach my $fwd_turn (@all_fwd_turns){
2048
                                my @new_turn=@current_turn;
2049
                                #add new turn to head_turns if they are not in turns before
2050
                                if(!defined get_scolar_pos($fwd_turn,@new_turn)){
2051
                                        my $size=scalar @new_turn;
2052
                                        #if ($min_dist > $size){
2053
                                        if( ($min_dist+$offset) > $size &&   $max_len>=$size){
2054
                                                push (@new_turn,$fwd_turn);
2055
                                                push (@turns,\@new_turn);
2056
                                                if($fwd_turn eq $ended_turns){
2057
                                                        push(@turns_to_dst,\@new_turn);
2058
                                                        my ($path_ref,$port_ref) = get_path_from_turns($self,\@new_turn);
2059
                                                        push(@paths_to_dst,$path_ref);
2060
                                                        push(@ports_to_dst,$port_ref);
2061
                                                        $min_dist=$size+1 if ($min_dist > $size);
2062
                                                } #if
2063
 
2064
                                        }#if
2065
                                }#if
2066
                        }#foreach
2067
                }#if
2068
        $n++;
2069
        }while( defined $turns[$n]);
2070
 
2071
 
2072
 
2073
        #print "\@paths_to_dst". Dumper(@paths_to_dst). "\n \@ports_to_dst". Dumper(@ports_to_dst) . "\n" ;
2074
 
2075
 
2076
        return (\@paths_to_dst,\@ports_to_dst);
2077
 
2078
}
2079
 
2080
 
2081
 
2082
 
2083
sub get_turn_code {
2084
        my $turn =shift;
2085
        my ($pn1,$rn1,$pn2,$rn2)= sscanf( "ROUTER%u_%u::ROUTER%u_%u",$turn);
2086
        if(defined $rn1){
2087
                return ( ($rn1 << 20)+ ($pn1 << 16) +  ($rn2 << 4) +  $pn2);
2088
        }
2089
        ($rn1,$pn2,$rn2)= sscanf( "ENDP_%u::ROUTER%u_%u",$turn);
2090
        if(defined $rn1){
2091
                return ( ($rn1 << 20)+ (1 << 16) +  ($rn2 << 4) +  $pn2);
2092
        }
2093
        ($pn1,$rn1,$rn2)= sscanf( "ROUTER%u_%u::ENDP_%u",$turn);
2094
        return ( ($rn1 << 20)+ ($pn1 << 16) +  ($rn2 << 4) +  1);
2095
}
2096
 
2097
sub get_turn_str {
2098
        my $code =shift;
2099
        my $pn2  =  $code & 0xF;
2100
        $code >>=4;
2101
        my $rn2  = $code & 0xFFF;
2102
        $code >>=12;
2103
        my $pn1 =$code & 0xF;
2104
        $code >>=4;
2105
        my $rn1=$code;
2106
        my $st1 = ($pn1==1)? "ENDP_${rn1}" : "ROUTER${pn1}_${rn1}";
2107
        my $st2 = ($pn2==1)? "ENDP_${rn2}" : "ROUTER${pn2}_${rn2}";
2108
 
2109
        return   "${st1}::${st2}";
2110
}
2111
 
2112
sub get_turn_involved_routrs{
2113
        my ($s1,$s2,$info)=@_;
2114
        my ($r1,$ra2) = split /::/, $s1;
2115
        my ($rb2,$r3) = split /::/, $s2;
2116
        add_colored_info($info,"Error in turn format. $s1 -> $s2 : $ra2 should be equal with $rb2 ",'red') if($ra2 ne $rb2);
2117
        return ($r1,$ra2,$r3);
2118
}
2119
 
2120
sub get_path_edges_graph_file{
2121
        my ($ref1,$ref2) = @_;
2122
        my @a_nodes = @{$ref1};
2123
        my %graph   = %{$ref2};
2124
 
2125
        my $old_r;
2126
        foreach my $r (@a_nodes){
2127
 
2128
                if(defined $old_r){
2129
                        my $str1 = "$old_r $r";
2130
                        my $n1  = get_turn_code($old_r);
2131
                        my $n2  = get_turn_code($r);
2132
                        my $str2 = "$n1 $n2";
2133
                        $graph{$str2}=$str1;
2134
                }
2135
                $old_r=$r;
2136
        }
2137
        return %graph;
2138
}
2139
 
2140
 
2141
 
2142
 
2143
sub get_forbiden_turns_old {
2144
#sub gen_aciclic_turn_graph {   
2145
        my ($self,$info)=@_;
2146
        my @forbiden_turn;
2147
        add_info($info,"Calculate forbidden turns to avoid deadlock \n");
2148
        #step 1: get the list of all  minimal paths between all source and destination pairs
2149
        my $graph='';
2150
        my $graph_coded='';
2151
        my @all_endpoints=get_list_of_all_endpoints($self);
2152
 
2153
        my %edge_graph;
2154
        foreach  my $src  (@all_endpoints ){
2155
                foreach  my $dst  (@all_endpoints ){
2156
                        if($src ne $dst){
2157
                                my ($paths_to_dst,$ports_to_dst) = get_all_paths_between_two_endps($self,$src, $dst);
2158
                                foreach my $path (@{$paths_to_dst}) {
2159
                                        if (defined $path){
2160
                                                #path counting
2161
                                                my @a_nodes=    get_adjacent_node_in_a_path($path);#get_adjacent_router_in_a_path($path);
2162
                                                print "@a_nodes = \@a_nodes \n";
2163
                                                %edge_graph = get_path_edges_graph_file (\@a_nodes,\%edge_graph);
2164
                                                #$graph  =$graph. $str1;
2165
                                                #$graph_coded = $graph_coded . $str2;
2166
                                        }#defined path  
2167
                                }#foreach       
2168
                        }#if                    
2169
                }#froeach                               
2170
 
2171
        }#froeach       
2172
 
2173
        foreach my $p (sort keys %edge_graph){
2174
                $graph_coded  .="$p\n";
2175
                $graph .= "$edge_graph{$p}\n";
2176
        }
2177
 
2178
        my $tmp_dir  = "$ENV{'PRONOC_WORK'}/tmp";
2179
        save_file ("$tmp_dir/paths_graph.edges",$graph);
2180
        save_file ("$tmp_dir/paths_graph_coded.edges",$graph_coded);
2181
 
2182
 
2183
        #remove old files 
2184
        my @files = File::Find::Rule->file()
2185
                            ->name( 'paths_graph_coded_removed*.edges')
2186
                            ->in( "$tmp_dir" );
2187
        foreach my $f (@files){
2188
                unlink  $f if (-f "$f");
2189
        }
2190
 
2191
        # run remove_cycle_edges_by_dfs on coded graph 
2192
        my $remover_dire = get_project_dir()."/mpsoc/remove_cycle/";
2193
        my $cmd  =  "cd $remover_dire;
2194
        python  break_cycles.py  -g $tmp_dir/paths_graph_coded.edges;
2195
        python remove_cycle_edges_by_dfs.py -g $tmp_dir/paths_graph_coded.edges;
2196
        python remove_cycle_edges_by_minimum_feedback_arc_set_greedy.py  -g $tmp_dir/paths_graph_coded.edges";
2197
        #sort paths_graph_coded.edges | uniq > newfile.db
2198
 
2199
        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
2200
        if(length $stderr>1){
2201
                add_colored_info($info,"$stderr\n",'red');
2202
        }else {
2203
                add_info($info,"$stdout\n");
2204
        }
2205
        # find the files with the list edges removal
2206
        @files = File::Find::Rule->file()
2207
                         ->name( 'paths_graph_coded_removed*.edges')
2208
                         ->in( "$tmp_dir" );
2209
 
2210
 
2211
        my $line_num;
2212
        my $out;
2213
        foreach my $f (@files){
2214
                my $n =count_file_line_num ($f);
2215
                $line_num = $n if(! defined $line_num);
2216
                if($n <= $line_num){
2217
                        $out = $f;
2218
                        $line_num=$n;
2219
                }
2220
        }
2221
 
2222
 
2223
        # check if the output file is generated 
2224
        if (-f $out ){
2225
                add_colored_info($info,"$out file has been selected as it has the minimum number of edge removal of $line_num \n",'blue');
2226
 
2227
        } else {
2228
                add_colored_info($info,"could not find a paths_graph_coded_removed*.edges file.  Please make sure $cmd has been run successfully\n",'red');
2229
                return;
2230
 
2231
        }
2232
 
2233
 
2234
 
2235
 
2236
        my $r;
2237
        open my $fh, "<", $out or $r = "$!\n";
2238
    if(defined $r) {
2239
        add_colored_info($info,"Could not open $out: $r",'red');
2240
                return;
2241
    }
2242
 
2243
    add_colored_info($info,"List of forbidden turns: \n",'blue');
2244
 
2245
        while (my $line = <$fh>) {
2246
        chomp $line;
2247
        $line=~ s/^\s+|\s+$//g;
2248
        my ($s1,$s2) = split /\s/, $line;
2249
        $s1  = get_turn_str($s1);
2250
                $s2  = get_turn_str($s2);
2251
                my @turn = get_turn_involved_routrs($s1,$s2);
2252
                my $str = get_path_instance_string($self,\@turn);
2253
                my $string=join('->',@turn);
2254
                push (@forbiden_turn, $string);
2255
                add_info($info,"$str\n");
2256
 
2257
  }
2258
  return @forbiden_turn;
2259
 
2260
}
2261
 
2262
 
2263
sub gen_turn_graph{
2264
        my $self=shift;
2265
        my %edge_graph;
2266
        my @all_nodes=get_list_of_all_nodes($self);
2267
        foreach  my $node1  (@all_nodes ){
2268
                my $pnum1=$self->object_get_attribute("$node1",'PNUM');
2269
                for (my $i=0;$i<$pnum1; $i++){
2270
                        my $port1 = "Port[${i}]";
2271
                        my $connect1 = $self->{$node1}{'PCONNECT'}{$port1};
2272
                        if (defined $connect1) {
2273
                                my ($node2,$Rport2)=split(/\s*,\s*/,$connect1);
2274
                                my $pnum2=$self->object_get_attribute("$node2",'PNUM');
2275
                                for (my $j=0;$j<$pnum2; $j++){
2276
                                        my $port2 = "Port[${j}]";
2277
                                        my $connect2 = $self->{$node2}{'PCONNECT'}{$port2};
2278
                                        if (defined $connect2) {
2279
                                                my ($node3,$Rport3)=split(/\s*,\s*/,$connect2);
2280
                                                if($node1 ne $node3){
2281
                                                        my @a_nodes=    ("${node1}::${node2}","${node2}::${node3}");
2282
                                                        %edge_graph = get_path_edges_graph_file (\@a_nodes,\%edge_graph);
2283
                                                }
2284
 
2285
                                        }#if    
2286
                                }#for           
2287
                        }#if
2288
                }#for    
2289
        }
2290
        return %edge_graph;
2291
}
2292
 
2293
sub gen_aciclic_turn_graph {
2294
 
2295
        my ($self,$info)=@_;
2296
 
2297
        #my @forbiden_turn;
2298
 
2299
        add_info($info,"Generate an acyclic turn graph to avoid deadlock \n");
2300
        #step 1: get the list of turn in topology. A turn is a path that include three nodes.
2301
        my $graph='';
2302
        my $graph_coded='';
2303
 
2304
        my %edge_graph =gen_turn_graph($self);
2305
 
2306
 
2307
        foreach my $p (sort keys %edge_graph){
2308
                $graph_coded  .="$p\n";
2309
                $graph .= "$edge_graph{$p}\n";
2310
        }
2311
 
2312
        my $tmp_dir  = "$ENV{'PRONOC_WORK'}/tmp";
2313
        save_file ("$tmp_dir/paths_graph.edges",$graph);
2314
        save_file ("$tmp_dir/paths_graph_coded.edges",$graph_coded);
2315
 
2316
 
2317
        #remove old files 
2318
        my @files = File::Find::Rule->file()
2319
                            ->name( 'paths_graph_coded_removed*.edges')
2320
                            ->in( "$tmp_dir" );
2321
        foreach my $f (@files){
2322
                unlink  $f if (-f "$f");
2323
        }
2324
 
2325
        # run remove_cycle_edges_by_dfs on coded graph 
2326
        my $remover_dire = get_project_dir()."/mpsoc/remove_cycle/";
2327
        my $cmd  =  "cd $remover_dire;
2328
        python  break_cycles.py  -g $tmp_dir/paths_graph_coded.edges;
2329
        python remove_cycle_edges_by_dfs.py -g $tmp_dir/paths_graph_coded.edges;
2330
        python remove_cycle_edges_by_minimum_feedback_arc_set_greedy.py  -g $tmp_dir/paths_graph_coded.edges";
2331
        #sort paths_graph_coded.edges | uniq > newfile.db
2332
 
2333
        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
2334
        if(length $stderr>1){
2335
                add_colored_info($info,"$stderr\n",'red');
2336
        }else {
2337
                add_info($info,"$stdout\n");
2338
        }
2339
        # find the files with the list edges removal
2340
        @files = File::Find::Rule->file()
2341
                         ->name( 'paths_graph_coded_removed*.edges')
2342
                         ->in( "$tmp_dir" );
2343
        my $line_num;
2344
        my $out;
2345
        my %all_outs;
2346
        foreach my $f (@files){
2347
 
2348
                my $n =count_file_line_num ($f);
2349
                $all_outs{$f}=$n;
2350
 
2351
        }
2352
 
2353
        my @graph_array=sort keys %edge_graph;
2354
        my @acyclic_turns;
2355
        my @removed_edge;
2356
        my $result=0;
2357
 
2358
        my %algorithms;
2359
 
2360
        foreach my $file  (sort {$all_outs{$a} <=> $all_outs{$b}} keys %all_outs) {
2361
                $line_num = $all_outs{$file};
2362
                $out=$file;
2363
                add_info($info,"check if $file file $line_num edges removal results in a connected graph\n");
2364
 
2365
                @removed_edge=();
2366
                open(FILE,$file);
2367
                if (tell FILE ){
2368
                        add_colored_info($info,"Cannot open $file to read: $!\n",'red');
2369
                        return;
2370
                }
2371
        while (my $line = <FILE>) {
2372
                chomp($line);
2373
                $line=~ s/^\s+|\s+$//g;
2374
                        push(@removed_edge,$line);
2375
                }
2376
        close FILE;
2377
 
2378
                @acyclic_turns = get_diff_array ( \@graph_array , \@removed_edge );
2379
 
2380
 
2381
 
2382
                $result = check_diff_graph_be_connected ($self,\@acyclic_turns,$info);
2383
                if($result == 1){
2384
                        my $alg = capture_string_between ('paths_graph_coded_removed_by_',$file,".edges");
2385
                        $algorithms{$alg}=$line_num;
2386
                        #save @acyclic_turns for this algorithm
2387
                        open(F,  ">$tmp_dir/$alg.alg") || die "Can not creat: $!";
2388
                print F perl_file_header("$alg.alg");
2389
                print F Data::Dumper->Dump([\@acyclic_turns],['turn']);
2390
                close(F ) || die "Error closing file: $!";
2391
                }
2392
 
2393
 
2394
        }
2395
 
2396
        $self->object_add_attribute('routing_auto','acyclic_algorithms',\%algorithms);
2397
 
2398
 
2399
    if (scalar (keys %algorithms) == 0){
2400
                add_colored_info($info,"Unable to find any directed acyclic graph for routing\n",'red');
2401
                return;
2402
    }
2403
 
2404
        return;
2405
        #add_colored_info($info,"$out file has been selected as it has the minimum number of edge removal of $line_num and its connected\n",'blue');
2406
 
2407
 
2408
 
2409
    #add_colored_info($info,"List of forbidden turns: \n",'blue');
2410
 
2411
        foreach my $line (@removed_edge) {
2412
        chomp $line;
2413
        my ($s1,$s2) = split /\s/, $line;
2414
        $s1  = get_turn_str($s1);
2415
                $s2  = get_turn_str($s2);
2416
                my @turn = get_turn_involved_routrs($s1,$s2);
2417
                my $str = get_path_instance_string($self,\@turn);
2418
                my $string=join('->',@turn);
2419
  #             push (@forbiden_turn, $string);
2420
                add_info($info,"$str\n");
2421
 
2422
        }
2423
 
2424
 # $self->object_add_attribute('routing_auto','acyclic_turns',\@acyclic_turns);
2425
 
2426
#  return @forbiden_turn;
2427
 
2428
}
2429
 
2430
 
2431
 
2432
sub check_diff_graph_be_connected {
2433
        my ($self,$ref,$info)=@_;
2434
        my @diff = @{$ref};
2435
        my %all_turns;
2436
        my %graph;
2437
 
2438
        foreach my $str (@diff){
2439
                my ($s1,$s2) = split /\s/, $str;
2440
                $all_turns{$s1}=1;
2441
                $all_turns{$s2}=1;
2442
                push(@{$graph{$s1}},$s2);
2443
 
2444
        }
2445
 
2446
        my @all_endpoints=get_list_of_all_endpoints($self);
2447
        my @start_turns;
2448
        my @ended_turns;
2449
        foreach my $endp (@all_endpoints){
2450
 
2451
                                my $src_port = "Port[0]";
2452
                                my $connect = $self->{$endp}{'PCONNECT'}{$src_port};
2453
                                if(defined $connect){
2454
                                        my ($node,$pnode)=split(/\s*,\s*/,$connect);
2455
                                        push (@start_turns,     get_turn_code("${endp}::${node}"));
2456
                                        push (@ended_turns,     get_turn_code("${node}::${endp}"));
2457
                                }
2458
        }
2459
 
2460
        my $k=0;
2461
        foreach my $s (@start_turns){# we should see all @ended_turns
2462
 
2463
                my @seen_turns=($s,$ended_turns[$k]);# put connect to itself connection as seen node.  
2464
                $k++;
2465
                my @next_turns =@{$graph{$s}};
2466
 
2467
                while (scalar @next_turns>0){
2468
 
2469
 
2470
                        #print "\@next_nodes = @next_nodes\n";
2471
                        #print "\@seen_nodes = @seen_nodes\n";
2472
                        my $n = pop (@next_turns);
2473
                        #print "\$n  = $n \n";
2474
                        my @nn;
2475
                        @nn = @{$graph{$n}} if (defined $graph{$n});
2476
                        #print "\@nn  = @nn \n";
2477
                        push (@seen_turns, $n);
2478
                        @diff = get_diff_array ( \@nn , \@seen_turns );
2479
                        #print "\@diff  = @diff \n";
2480
                        push (@next_turns,@diff);
2481
 
2482
                }
2483
 
2484
                my @sep = get_diff_array (\@ended_turns,\@seen_turns);
2485
 
2486
                if( scalar @sep > 0) {
2487
                        my $s1  = get_turn_str($s);
2488
                        my ($a1,$a2) = split ('::',$s1);
2489
                        my $n1=$self->object_get_attribute("$a1",'NAME');
2490
 
2491
                        $s1  = get_turn_str($sep[0]);
2492
                        my($a3,$a4) = split ('::',$s1);
2493
                        my $n2=$self->object_get_attribute("$a4",'NAME');
2494
 
2495
                        add_info($info,"\t $n1 is not connected to $n2. \n");
2496
                        return 0;
2497
                }
2498
 
2499
 
2500
        }
2501
 
2502
 
2503
        add_info($info,"\t All endpoints are connected in chanel dpenedency graph. \n");
2504
        return 1;
2505
 
2506
}
2507
 
2508
 
2509
 
2510
sub get_path_instance_string {
2511
        my ($self,$path_ref)=@_;
2512
        my @path = @{$path_ref};
2513
        my @path_inst;
2514
        foreach my $p (@path){
2515
                push (@path_inst, $self->object_get_attribute("$p",'NAME'));
2516
 
2517
        }
2518
        my $string=join('->',@path_inst);
2519
        return $string;
2520
}
2521
 
2522
 
2523
sub remove_cycle_paths {
2524
        my ($self,$info,$paths_ref, $fturn_ref)=@_;
2525
        my @free_paths;
2526
        my @paths= @{$paths_ref};
2527
        my @fturns= @{$fturn_ref};
2528
        my $remove;
2529
 
2530
 
2531
 
2532
        foreach my $path (@paths) {
2533
                my @p = @$path;
2534
                my $turn;
2535
                my $string=join('->',@p);
2536
                #print "$string\n";     
2537
                $remove=0;
2538
                foreach my $t (@fturns){
2539
                         if ($string =~ /$t-/){
2540
                                $remove=1;
2541
                                $turn=$t;
2542
                                last;
2543
                         }
2544
 
2545
                }
2546
                push (@free_paths,$path) if($remove == 0);
2547
                if($remove == 1){
2548
                        my @ft = split /->/, $turn;
2549
                        add_info($info,"path ".get_path_instance_string($self,$path)." is removed due to turn ".get_path_instance_string($self,\@ft)."\n")
2550
                }
2551
        }
2552
        return @free_paths;
2553
}
2554
 
2555
 
2556
 
2557
 
2558
 
2559
 
2560
 
2561
 
2562
sub auto_route {
2563
        my ($self,$info)=@_;
2564
        my %Psize;
2565
        my $alg = $self->object_get_attribute('routing_auto', 'CYCLE_FREE_ALG');
2566
        my ($alg_name,$line) = split (/\s+--\s+/,$alg);
2567
 
2568
        if(!defined $line){
2569
                add_colored_info($info,"No acyclic turn model is selected. click on Generate Cycle-free and make sure it runs successfully!\n",'red');
2570
        return;
2571
        }
2572
        my $tmp_dir  = "$ENV{'PRONOC_WORK'}/tmp";
2573
        my $model_file = "$tmp_dir/$alg_name.alg";
2574
        my ($pp,$r,$err) = regen_object($model_file);
2575
    if ($r){
2576
        add_colored_info($info,"**Error: cannot open $model_file file: $err\n",'red');
2577
                return;
2578
    } else {
2579
        add_info($info,"Use $alg_name algorithm for obtaing acyclic paths\n");
2580
    }
2581
 
2582
        my @acyclic_turns = @{$pp};
2583 56 alirezamon
        my %rusage = get_router_usage ($self,\@acyclic_turns);
2584 48 alirezamon
 
2585
 
2586
        #step 1: calculate all minimal paths between all source and destination pairs
2587
        add_info($info,"Calculate all  paths between all source and destination pairs\n");
2588
        my @all_endpoints=get_list_of_all_endpoints($self);
2589
        foreach  my $src  (@all_endpoints ){
2590
                foreach  my $dst  (@all_endpoints ){
2591
                        if($src ne $dst){
2592
                                my ($paths_to_dst,$ports_to_dst) =  get_all_paths_between_two_endps_using_accyclic_turn($self,$src, $dst,\@acyclic_turns);
2593
                                my @cyle_free_paths= @{$paths_to_dst} if (defined $paths_to_dst);
2594
                                my $size = scalar  @cyle_free_paths;
2595
                                $Psize{"${src}::$dst"} = $size;
2596
                        }
2597
                }
2598
        }
2599
        #step 2: Remove cyclic paths between all source and destination pairs
2600
 
2601
 
2602
 
2603
 
2604
 
2605
 
2606
        #step 3 sort source destination based on the number of paths
2607
        my @keys = sort { $Psize{$a} <=> $Psize{$b} } keys(%Psize);
2608
        for my $key ( @keys) {
2609
                my $size=$Psize{$key};
2610
                #print "size = $size\n";
2611
                next if(defined $self->object_get_attribute('Route',$key));
2612
 
2613
       # print "($key)->($Psize{$key})\n";
2614
        my ($src , $dst)=split ('::',$key);
2615
        my ($paths_to_dst,$ports_to_dst) = get_all_paths_between_two_endps_using_accyclic_turn($self,$src, $dst,\@acyclic_turns);
2616
        #my @cyle_free_paths=remove_cycle_paths($self,$info,$paths_to_dst, \@forbiden_turn);
2617
        my @cyle_free_paths= @{$paths_to_dst} if (defined $paths_to_dst);
2618 56 alirezamon
        my @sort_paths=sort_paths_based_on_router_usage($self,\@cyle_free_paths,\%rusage);
2619
 
2620
      # my @sort_paths=sort_paths_based_on_link_usage($self,\@cyle_free_paths);
2621
 
2622
 
2623
 
2624 48 alirezamon
        my $path;
2625
        my $n=0;
2626
        foreach my $p (@sort_paths ){
2627
                if(check_cyclick_loop($self,$p)==0){
2628
                        $path=$p;
2629
                        #my @rrr=($p);
2630
                        #remove_cycle_paths($self,$info,\@rrr, \@forbiden_turn);
2631
 
2632
                        last;
2633
                }  else {
2634
                        print "***Error  something goes wrong in acyclic turns model  ****************************\n";
2635
                }
2636
                $n++;
2637
        }
2638
        if(!defined $path){
2639
                #extract path from acyclic turn graph. This graph is connected so there must be atleast a path between each endpoint pairs there. however this path does not match the offset or size lentgh
2640
 
2641
 
2642
                set_gui_status($self,"ref",1);
2643
                add_colored_info($info,"Failed to find an acyclic routing paths for $key nodes!\n",'red');
2644
                return FALSE ;
2645
 
2646
        }
2647
 
2648
        $self->object_add_attribute('Route',$key,$path);
2649
 
2650
        }
2651
 
2652
        set_gui_status($self,"ref",1);
2653
        add_colored_info($info,"The routeing function table is generated successfully!\n",'blue');
2654
        return TRUE;
2655
}
2656
 
2657
 
2658
sub clean_route {
2659
        my ($self,$info)=@_;
2660
 
2661
        my @all_endpoints=get_list_of_all_endpoints($self);
2662
        foreach  my $src  (@all_endpoints ){
2663
                foreach  my $dst  (@all_endpoints ){
2664
        $self->object_add_attribute('Route',"${src}::$dst",undef);
2665
 
2666
        }}
2667
 
2668
        set_gui_status($self,"ref",1);
2669
        add_colored_info($info,"The Routing function table is cleared!\n",'blue');
2670
        return TRUE;
2671
}
2672
 
2673
 
2674
 
2675
sub average{
2676
        my($data) = @_;
2677
        if (not @$data) {
2678
               return 0;
2679
        }
2680
        my $total = 0;
2681
        foreach (@$data) {
2682
                $total += $_;
2683
        }
2684
        my $average = $total / @$data;
2685
        return $average;
2686
}
2687
sub stdev{
2688
        my($data) = @_;
2689
        if(@$data == 1){
2690
                return 0;
2691
        }
2692
        my $average = &average($data);
2693
        my $sqtotal = 0;
2694
        foreach(@$data) {
2695
                $sqtotal += ($average-$_) ** 2;
2696
        }
2697
        my $std = ($sqtotal / (@$data-1)) ** 0.5;
2698
        return $std;
2699
}
2700
 
2701
sub clone_hash{
2702
        my $ref=shift;
2703
        my %hash=%{$ref};
2704
        my %copy;
2705
        foreach my $p (keys %hash){
2706
                if (defined $hash{$p}){ $copy{$p} =  $hash{$p};}
2707
        }
2708
        return %copy;
2709
}
2710
 
2711 56 alirezamon
 
2712
sub sort_paths_based_on_router_usage{
2713
        my ($self,$paths_to_dst,$usage)=@_;
2714
        my %scored;
2715
        my %usage_r= %{$usage};
2716
        #get list of 30% high congested ruters 
2717
        my @A = sort { $usage_r{$b} <=> $usage_r{$a} } keys %usage_r;
2718
        #my $t = (scalar @A)*.3; # %30 
2719
        my %congested;
2720
        foreach my $a ( @A){
2721
                $congested{$a}=$usage_r{$a};# if(scalar(keys %congested)<$t);
2722
        }
2723
 
2724
        my $i=0;
2725
        foreach my $path (@{$paths_to_dst}) {
2726
                my $val = 0;
2727
                my $num=0;
2728
                for my $r (@{$path}){
2729
                        if(defined $congested{$r}){
2730
                                $val+=$congested{$r}**1.5;# pow of 3/2 to give higher weight to more congested routers
2731
                                $num++;
2732
                        }
2733
                }
2734
                $scored{$i}=($num==0)? 0 : $val/$num;     #average weight of congested routers
2735
                $i++;
2736
        }
2737
 
2738
        my @order = sort { $scored{$a} <=> $scored{$b} } keys %scored;
2739
        my @sorted;
2740
 
2741
 
2742
 
2743
        $i=0;
2744
        foreach my $a ( @order){
2745
                $sorted[$i]=${$paths_to_dst}[$a];
2746
                $i++;
2747
                #print "\$max{$a}=$max{$a},"
2748
        }
2749
 
2750
        #print "\n";
2751
 
2752
        return @sorted;
2753
}
2754
 
2755
 
2756 48 alirezamon
sub sort_paths_based_on_link_usage{
2757
        my ($self,$paths_to_dst)=@_;
2758
 
2759
        my %L_num;
2760
        my %max;
2761
        my @all_endpoints=get_list_of_all_endpoints($self);
2762
        #get link count
2763
        foreach  my $src  (@all_endpoints ){
2764
                foreach  my $dst  (@all_endpoints ){
2765
                        my $path = $self->object_get_attribute('Route',"${src}::$dst");
2766
                        if (defined $path){
2767
                                #path counting
2768
                                my @p=  get_adjacent_router_in_a_path($path);
2769 56 alirezamon
 
2770 48 alirezamon
                                foreach my $r (@p){
2771
                                        $L_num{$r} ++;
2772
                                }
2773
 
2774
                        }
2775
                }
2776
        }
2777
        #get std_devision of link  for each path if added   
2778
        my $i=0;
2779
        foreach my $path (@{$paths_to_dst}) {
2780
                my %copy = clone_hash(\%L_num);
2781
                my @p=get_adjacent_router_in_a_path($path);
2782
                foreach my $r (@p){
2783
                                        $copy{$r} ++;
2784
                }
2785
                my @l = sort  values (%copy);
2786
                my $std=stdev(\@l);
2787
                $max{$i}=$std*100;
2788
                $i++;
2789
        }
2790
 
2791
 
2792
        my @order = sort { $max{$a} <=> $max{$b} } keys(%max);
2793
 
2794
        #print "*********** @order ************"; 
2795
        my @sorted;
2796
        $i=0;
2797
        foreach my $a ( @order){
2798
                $sorted[$i]=${$paths_to_dst}[$a];
2799
                $i++;
2800
                #print "\$max{$a}=$max{$a},"
2801
        }
2802
 
2803
        #print "\n";
2804
 
2805
        return @sorted;
2806
 
2807
 
2808
}
2809
 
2810 56 alirezamon
 
2811
sub get_router_usage{
2812
        my ($self,$acycle_turn_ref)=@_;
2813
 
2814
        my @all_endpoints=get_list_of_all_endpoints($self);
2815
        my %router_cnt;
2816
        #get router counts
2817
        foreach  my $src  (@all_endpoints ){
2818
                foreach  my $dst  (@all_endpoints ){
2819
                        #get list of all path between a source and destination nodes
2820
                         my ($paths_to_dst,$ports_to_dst)= get_all_paths_between_two_endps_using_accyclic_turn($self,$src, $dst,$acycle_turn_ref);
2821
 
2822
                        my @paths = @{$paths_to_dst};
2823
                        foreach my $path (@paths){
2824
                                shift @{$path}; #remove source node from the path
2825
                                pop @{$path}; #remove the destination node from the path        
2826
                                foreach my $q ( @{$path}){
2827
                                        $router_cnt{"$q"} = ( defined $router_cnt{"$q"})? $router_cnt{"$q"}+1 : 1;
2828
                                }
2829
                        }
2830
                }
2831
        }
2832
 
2833
        return %router_cnt;
2834
 
2835
}
2836
 
2837
 
2838 48 alirezamon
sub check_cyclick_loop{
2839
        my ($self,$paths_to_dst)=@_;
2840
 
2841
 
2842
        my %graph;
2843
        my @all_endpoints=get_list_of_all_endpoints($self);
2844
        # create routing dependency graph
2845
 
2846
        foreach  my $src  (@all_endpoints ){
2847
                foreach  my $dst  (@all_endpoints ){
2848
                        my $path = $self->object_get_attribute('Route',"${src}::$dst");
2849
                        if (defined $path){
2850
                                #path counting
2851
                                my @p=  get_adjacent_node_in_a_path($path);
2852
                                %graph=add_route_edge_to_graph(\%graph,\@p);
2853
 
2854
                        }
2855
                }
2856
        }
2857
 
2858
        my @p=  get_adjacent_node_in_a_path($paths_to_dst);
2859
        %graph=add_route_edge_to_graph(\%graph,\@p);
2860
 
2861
        my $result = Algorithm::TSort::cicle_detect( Algorithm::TSort::Graph( ADJ => \%graph ), keys %graph );
2862
 
2863
        #print Data::Dumper->Dump([\%graph],["link"]);
2864
        #print "result=$result\n";
2865
 
2866
 
2867
 
2868
 
2869
 
2870
 
2871
 
2872
        return  $result;
2873
 
2874
 
2875
}
2876
 
2877
sub generate_topology{
2878
        my ($self,$info)=@_;
2879
        my $name=$self->object_get_attribute('save_as');
2880
    my $error = check_verilog_identifier_syntax($name);
2881
    if ( defined $error ){
2882
        #message_dialog("The \"$name\" is given with an unacceptable formatting. The mpsoc name will be used as top level verilog module name so it must follow Verilog identifier declaration formatting:\n $error");
2883
        my $message = "The \"$name\" is given with an unacceptable formatting. The topology name will be used as top level Verilog module name so it must follow Verilog identifier declaration formatting:\n $error";
2884
        add_colored_info($info, $message,'red' );
2885
        return 0;
2886
    }
2887
    my $rname=$self->object_get_attribute('routing_name');
2888
    $error = check_verilog_identifier_syntax($rname);
2889
    if ( defined $error ){
2890
        #message_dialog("The \"$rname\" is given with an unacceptable formatting. The mpsoc name will be used as top level verilog module name so it must follow Verilog identifier declaration formatting:\n $error");
2891
        $rname='Undefined' if(!defined $rname);
2892
        my $message = "The \"$name\" is given with an unacceptable formatting. The routing name will be used as routing Verilog module name so it must follow Verilog identifier declaration formatting:\n $error";
2893
        add_colored_info($info, $message,'red' );
2894
        return 0;
2895
    }
2896
 
2897
 
2898
 
2899
 
2900
        #make destination dir
2901
        my $dir =get_project_dir()."/mpsoc/rtl/src_topolgy/$name";
2902
        mkpath("$dir",1,01777) unless (-d $dir) ;
2903
    mkpath("$dir/../common",1,01777) unless (-d "$dir/../common") ;
2904
 
2905
        #save topology image file
2906
        $self->object_add_attribute("graph_save","name","$dir/$name");
2907
        $self->object_add_attribute("graph_save","extension",'png');
2908
        $self->object_add_attribute("graph_save","enable",1);
2909
 
2910
        show_custom_topology_diagram ($self,undef,"topology_diagram");
2911
 
2912
 
2913
 
2914
        #generate topology top module verilog file
2915
        generate_topology_top_v($self,$info,$dir);
2916
        generate_topology_top_genvar_v($self,$info,$dir);
2917
        generate_routing_v($self,$info,$dir);
2918
        #generate_connection_v($self,$info,$dir);
2919
        add_routing_instance_v($self,$info,$dir);
2920
        add_noc_instance_v($self,$info,$dir);
2921 54 alirezamon
        add_noc_custom_h($self,$info,$dir);
2922 48 alirezamon
        save_topology_parameter_object_file($self,$info);
2923
 
2924
        #create the file list
2925
        my $txt="+incdir+./\n";
2926
        my @files = File::Find::Rule->file()
2927
                            ->name( '*.v','*.sv')
2928
                            ->in( "$dir/../" );
2929
    foreach my $f (@files){
2930
        my $d = basename(dirname(abs_path($f)));
2931
        my $n = basename($f);
2932
        $txt.="./$d/$n\n";
2933
    }
2934
        save_file("$dir/../custom_flist.f",$txt);
2935
 
2936
 
2937
}
2938
 
2939
 
2940
sub save_topology_parameter_object_file{
2941
        my ($self,$info)=@_;
2942
        my $name=$self->object_get_attribute('save_as');
2943
        my $rname=$self->object_get_attribute('routing_name');
2944
        my $dir =get_project_dir()."/mpsoc/rtl/src_topolgy";
2945
        my $file="$dir/param.obj";
2946
 
2947
        my %param;
2948
 
2949
        if(-f $file){
2950
                 my ($pp,$r,$err) = regen_object($file );
2951
            if ($r){
2952
                add_info($info,"**Error: cannot open $file file: $err\n");
2953
                return;
2954
            }
2955
 
2956
                %param=%{$pp};
2957
        }
2958
 
2959
 
2960
        my @ends=get_list_of_all_endpoints($self);
2961
    my @routers=get_list_of_all_routers($self);
2962
 
2963
    my $MAX_P=0;
2964
    my %router_ps;
2965
    foreach my $p (@routers){
2966
        my $Pnum=$self->object_get_attribute("$p",'PNUM');
2967
        $MAX_P =$Pnum  if($Pnum>$MAX_P );
2968
        $router_ps{$Pnum}=(defined $router_ps{$Pnum})? $router_ps{$Pnum}+1 : '1';
2969
    }
2970
 
2971
    my $NE= scalar @ends;
2972
    my $NR= scalar @routers;
2973
 
2974
 
2975
        $param{"\"$name\""}{'T1'}=$NE;
2976
        $param{"\"$name\""}{'T2'}=$NR;
2977
        $param{"\"$name\""}{'T3'}=$MAX_P;
2978
        my $routs = $param{"\"$name\""}{'ROUTE_NAME'};
2979
        my $new="\"$rname\"";
2980
        if(!defined $routs){
2981
                $param{"\"$name\""}{'ROUTE_NAME'}=$new;
2982
        }
2983
        else {
2984
                my @r=split(/\s*,\s*/,$routs);
2985
                unless( grep (/^$new$/,@r)){
2986
                        $param{"\"$name\""}{'ROUTE_NAME'}= $routs.",$new" ;
2987
                }
2988
        }
2989
 
2990
        $param{"\"$name\""}{'ROUTER_Ps'}= \%router_ps;
2991
 
2992
 
2993
        my @er_addr;
2994
        foreach my $end (@ends){
2995
                my $connect = $self->{$end}{'PCONNECT'}{'Port[0]'};
2996
                my ($Rname,$Rport)=split(/\s*,\s*/,$connect);
2997
                my $R = get_scolar_pos($Rname,@routers);
2998
                push(@er_addr,$R);
2999
        }
3000
        $param{"\"$name\""}{'er_addr'}= \@er_addr;
3001
 
3002
 
3003
 
3004
 
3005
    open(FILE,  ">$file") || die "Can not open: $!";
3006
    print FILE perl_file_header("$file");
3007
    print FILE Data::Dumper->Dump([\%param],['Topology']);
3008
    close(FILE) || die "Error closing file: $!";
3009
 
3010
}
3011
 
3012
 
3013
sub get_path_route_widgets {
3014
        my      ($self,$info)=@_;
3015
 
3016
        my              $w1 = show_paths_between_two_endps($self,$info);
3017
        my              $w2 = routing_summary($self,$info);
3018
    my $h=gen_hpaned($w1,.15,$w2);
3019
    $h -> pack1($w1, TRUE, TRUE);
3020
        $h -> pack2($w2, TRUE, TRUE);
3021
        return $h;
3022
}
3023
 
3024
 
3025
sub build_network_maker_gui {
3026
        my ($self) = @_;
3027
        set_gui_status($self,"ideal",0);
3028
        $self->object_add_attribute ("process_notebook","currentpage",0);
3029
        my $main_table= def_table(2,10,FALSE);
3030
 
3031
    my ($infobox,$info)= create_txview();
3032
 
3033
 
3034
        my $notebook = gen_notebook();
3035
        $notebook->set_tab_pos ('left');
3036
        $notebook->set_scrollable(TRUE);
3037
 
3038
 
3039
 
3040
        my $page0=take_node_num_page($self);
3041
        my $page1=take_instance_page($self);
3042
        my $page2=connection_page_auto($self,$info);
3043
        my $page3=connection_page($self,$info);
3044
        my $page4=routing_page_manual($self,$info);
3045
 
3046
        my $page0_win = add_widget_to_scrolled_win($page0);
3047
        my $page1_win = add_widget_to_scrolled_win($page1);
3048
        my $page2_win = add_widget_to_scrolled_win($page2);
3049
        my $page3_win = add_widget_to_scrolled_win($page3);
3050
        my $page4_win = add_widget_to_scrolled_win($page4);
3051
 
3052
 
3053
        $notebook->append_page ($page0_win,gen_label_in_center  (" Nodes #"));
3054
        $notebook->append_page ($page1_win,gen_label_in_center  ("Instance"));
3055
        $notebook->append_page ($page2_win,gen_label_in_center  ("Connection Auto"));
3056
        $notebook->append_page ($page3_win,gen_label_in_center  ("Connection Manual"));
3057
        $notebook->append_page ($page4_win,gen_label_in_center  ("Route Select"));
3058
 
3059
 
3060
        $notebook->signal_connect( 'switch-page'=> sub{ # rebulid the current page              
3061
                $self->object_add_attribute ("process_notebook","currentpage",$_[2]);   #save the new pagenumber
3062
                set_gui_status($self,"ref",1);
3063
        });
3064
 
3065
 
3066
        my $draw=custom_topology_diagram($self);
3067
        my $h1=gen_hpaned($notebook,.35,$draw);
3068
 
3069
 
3070
        my $v2=gen_vpaned($h1,.65,$infobox);
3071
 
3072
 
3073
        my $generate = def_image_button('icons/gen.png','Generate');
3074
        my $open = def_image_button('icons/browse.png','Load');
3075
 
3076
 
3077
        my ($entrybox,$entry) = def_h_labeled_entry('Topology name:',undef);
3078
 
3079
        $entry->signal_connect( 'changed'=> sub{
3080
                my $name=$entry->get_text();
3081
                $self->object_add_attribute ("save_as",undef,$name);
3082
        });
3083
 
3084
        my ($entrybox2,$entry2) = def_h_labeled_entry('Routing Alg. name:',undef);
3085
 
3086
        $entry2->signal_connect( 'changed'=> sub{
3087
                my $name=$entry2->get_text();
3088
                $self->object_add_attribute ("routing_name",undef,$name);
3089
        });
3090
 
3091
        my $save = def_image_button('icons/save.png','Save');
3092
        #$entrybox->pack_end($save,   FALSE, FALSE,0);
3093
 
3094
        $main_table->attach_defaults ($v2  , 0, 12, 0,24);
3095
        $main_table->attach ($open,0, 1, 24,25,'expand','shrink',2,2);
3096
        $main_table->attach ($save,1, 2, 24,25,'expand','shrink',2,2);
3097
 
3098
        $main_table->attach ($entrybox,2, 4, 24,25,'expand','shrink',2,2);
3099
        $main_table->attach ($entrybox2,4, 6, 24,25,'expand','shrink',2,2);
3100
 
3101
        $main_table->attach ($generate, 6, 9, 24,25,'expand','shrink',2,2);
3102
 
3103
 
3104
        my $sc_win = add_widget_to_scrolled_win($main_table);
3105
 
3106
 
3107
        #setting for graphs
3108
        my $n=0;
3109
    my $sample="sample$n";
3110
        $n++;
3111
        $self->object_add_attribute("id",undef,$n);
3112
        $self->object_add_attribute("active_setting",undef,undef);
3113
        $self->object_add_attribute_order("samples",$sample);
3114
        $self->object_add_attribute($sample,"color",1);
3115
        add_color_to_gd($self);
3116
 
3117
 
3118
        $open-> signal_connect("clicked" => sub{
3119
 
3120
 
3121
 
3122
        load_net_maker($self,$info);
3123
        my $n=0;
3124
    my $sample="sample$n";
3125
        $n++;
3126
        $self->object_add_attribute("id",undef,$n);
3127
        $self->object_add_attribute("active_setting",undef,undef);
3128
        $self->object_add_attribute_order("samples",$sample);
3129
        $self->object_add_attribute($sample,"color",1);
3130
        add_color_to_gd($self);
3131
 
3132
 
3133
                set_gui_status($self,"ref",5);
3134
 
3135
        });
3136
 
3137
        $save-> signal_connect("clicked" => sub{
3138
 
3139
                save_network($self);
3140
                set_gui_status($self,"ref",5);
3141
 
3142
 
3143
        });
3144
 
3145
        $generate->signal_connect("clicked" => sub{
3146
                generate_topology($self,$info);
3147
 
3148
        });
3149
 
3150
 
3151
 
3152
        #check soc status every 0.5 second. refresh device table if there is any changes 
3153
        Glib::Timeout->add (100, sub{
3154
 
3155
                my ($state,$timeout)= get_gui_status($self);
3156
 
3157
                if ($timeout>0){
3158
                        $timeout--;
3159
                        set_gui_status($self,$state,$timeout);
3160
                        return TRUE;
3161
 
3162
                }
3163
                if($state eq "ideal"){
3164
                        return TRUE;
3165
 
3166
                }
3167
 
3168
                if($state eq "ref" || $state eq "redraw"){
3169
 
3170
                        my $page_num=$self->object_get_attribute ("process_notebook","currentpage");
3171
                        if($state eq "ref"){
3172
                                if($page_num==0){
3173
                                        $page0->destroy;
3174
                                        $page0=take_node_num_page($self);
3175
                                        add_widget_to_scrolled_win($page0,$page0_win);
3176
                                        $page0_win->show_all;
3177
 
3178
                                }
3179
                                if($page_num==1){
3180
                                        $page1->destroy;
3181
                                        $page1=take_instance_page($self);
3182
                                        add_widget_to_scrolled_win($page1,$page1_win);
3183
                                        $page1_win->show_all;
3184
                                }
3185
                                if($page_num==2){
3186
                                        $page2->destroy;
3187
                                        $page2=connection_page_auto($self,$info);
3188
                                        add_widget_to_scrolled_win($page2,$page2_win);
3189
                                        $page2_win->show_all;
3190
                                }
3191
                                if($page_num==3){
3192
                                        $page3->destroy;
3193
                                        $page3=connection_page($self,$info);
3194
                                        add_widget_to_scrolled_win($page3,$page3_win);
3195
                                        $page3_win->show_all;
3196
                                }
3197
                                if($page_num==4){
3198
                                        $page4->destroy;
3199
                                        $page4=routing_page_manual($self,$info);
3200
                                        add_widget_to_scrolled_win($page4,$page4_win);
3201
                                        $page4_win->show_all;
3202
                                }
3203
 
3204
                        }
3205
 
3206
 
3207
 
3208
 
3209
                        if($page_num==4  ){
3210
                                $draw->destroy;
3211
                                $draw = get_path_route_widgets($self,$info);
3212
                                $h1 -> pack2($draw, TRUE, TRUE);
3213
 
3214
 
3215
                        }else{
3216
 
3217
                                $draw->destroy;
3218
                                $draw=custom_topology_diagram($self);
3219
                                $h1 -> pack2($draw, TRUE, TRUE);
3220
                        }
3221
                        my $saved_name=$self->object_get_attribute('save_as');
3222
                    $entry->set_text($saved_name)if(defined $saved_name);
3223
 
3224
                    $saved_name = $self->object_get_attribute('routing_name');
3225
                    $entry2->set_text($saved_name) if(defined $saved_name);
3226
 
3227
                        set_gui_status($self,"ideal",0);
3228
                        $main_table->show_all();
3229
 
3230
                        return TRUE;
3231
 
3232
                }
3233
 
3234
 
3235
                #refresh GUI
3236
 
3237
 
3238
 
3239
 
3240
                $main_table->show_all();
3241
                set_gui_status($self,"ideal",0);
3242
 
3243
                return TRUE;
3244
 
3245
        } );
3246
 
3247
 
3248
 
3249
        return $sc_win;
3250
 
3251
 
3252
 
3253
}

powered by: WebSVN 2.1.0

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