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 48

Go to most recent revision | 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
                $R_num{$r} =0;
1577
        }
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
                        if (defined $path){
1586
                                #router counting
1587
                                my @p=@{$path};
1588
                                foreach my $r (@p){
1589
                                        $R_num{$r} ++;
1590
                                }
1591
                                #path counting
1592
                                @p=     get_adjacent_router_in_a_path($path);
1593
                                foreach my $r (@p){
1594
                                        $L_num{$r} ++;
1595
 
1596
                                }
1597
 
1598
 
1599
                        }
1600
                }
1601
        }
1602
 
1603
        my @Rkeys = sort { $R_num{$a} <=> $R_num{$b} } keys(%R_num);
1604
        my @Lkeys = sort { $L_num{$a} <=> $L_num{$b} } keys(%L_num);
1605
        my $sample="sample0";
1606
        foreach  my $r  (@nodes ){
1607
                my $inst=$self->object_get_attribute("$r",'NAME');
1608
                update_result ($self,$sample,"router_all_paths_result",'-',$inst,$R_num{$r});
1609
        }
1610
 
1611
        my $max_r = (defined $Rkeys[-1]) ? $R_num{$Rkeys[-1]} : 0;
1612
        my $min_r = (defined $Rkeys[ 0]) ? $R_num{$Rkeys[ 0]} : 0;
1613
        my $max_l = (defined $Lkeys[-1]) ? $L_num{$Lkeys[-1]} : 0;
1614
        my $min_l = (defined $Lkeys[ 0]) ? $L_num{$Lkeys[ 0]} : 0;
1615
        my @l = sort  values (%L_num);
1616
        my $std_l=stdev(\@l);
1617
 
1618
        $self->object_add_attribute ($sample,"link_all_paths_result",undef);
1619
 
1620
        my $nn=0;
1621
        my $min_l_name="-";
1622
        my $max_l_name="-";
1623
        my $siz = $#Lkeys;
1624
        foreach  my $r  (@Lkeys ){
1625
                my ($n1,$n2)=split(/::/,$r);
1626
                my $inst1=$self->object_get_attribute("$n1",'NAME');
1627
                my $inst2=$self->object_get_attribute("$n2",'NAME');
1628
                my $inst = "$inst1-$inst2";
1629
                update_result ($self,$sample,"link_all_paths_result",'-',$inst,$L_num{$r});
1630
                $min_l_name= $inst if($nn==0);
1631
                $max_l_name= $inst if($nn==$siz-1);
1632
                $nn++;
1633
        }
1634
 
1635
 
1636
 
1637
        my $max_r_name= (defined $Rkeys[-1])? $self->object_get_attribute("$Rkeys[-1]",'NAME') : "-";
1638
        my $min_r_name= (defined $Rkeys[0]) ? $self->object_get_attribute("$Rkeys[0]",'NAME') : "-";
1639
 
1640
        $max_r_name= "-" if (!defined $max_r_name);
1641
        $min_r_name= "-" if (!defined $min_r_name);
1642
 
1643
 
1644
        return ($max_r,$min_r,$max_l,$min_l,$std_l,$max_r_name,$min_r_name,$max_l_name,$min_l_name);
1645
}
1646
 
1647
 
1648
sub routing_summary{
1649
        my ($self,$info)= @_;
1650
 
1651
        my $sc_win = gen_scr_win_with_adjst($self,'map_info');
1652
        #my $table= def_table(10,10,FALSE);
1653
 
1654
 
1655
        my $row=0;
1656
        my $col=0;
1657
        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);
1658
 
1659
 
1660
        my @data = (
1661
   {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.
1662
   {0 => "The Minimum number that a router is used in routing",  1 =>"$min_r", 2 =>"$min_r_name" },
1663
   {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.
1664
   {0 => "The Minimum number that a link is used in routing",  1=>"$min_l", 2 =>"$min_l_name" },
1665
   {0 => "Link usage  standard deviation ",  1 =>"$std_l" }
1666
  );
1667
 
1668
 
1669
 
1670
        my @clmn_type = ('Glib::String',  # => G_TYPE_STRING
1671
                                    'Glib::String',
1672
                                    'Glib::String'); # you get the idea
1673
 
1674
        my @clmns = ("Routing Summary", " ", " ");
1675
 
1676
        my $list=       gen_list_store (\@data,\@clmn_type,\@clmns);
1677
 
1678
 
1679
        add_widget_to_scrolled_win($list,$sc_win);
1680
 
1681
        my $charts =  gen_routing_charts($self,$info);
1682
 
1683
        my $v1=gen_vpaned($sc_win,.25,$charts);
1684
 
1685
        $sc_win->show_all;
1686
 
1687
        return $v1;
1688
 
1689
}
1690
 
1691
 
1692
sub gen_routing_charts{
1693
 
1694
        my ($self,$info)=@_;
1695
 
1696
        my @pages =(
1697
        {page_name=>" # Routers in all Paths", page_num=>0},
1698
        {page_name=>" # Links in all Paths ", page_num=>1}
1699
);
1700
 
1701
 
1702
 
1703
my @charts = (
1704
        { 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},
1705
        { 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},
1706
        #{ 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},
1707
        #{ 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},
1708
        #{ 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},
1709
 
1710
        );
1711
 
1712
 
1713
        my $chart   =gen_multiple_charts  ($self,\@pages,\@charts,.3);
1714
    return $chart;
1715
 
1716
}
1717
 
1718
 
1719
 
1720
 
1721
sub show_paths_between_two_endps{
1722
        my ($self,$info)= @_;
1723
        my $table=def_table(20,20,FALSE);
1724
 
1725
        my $row-=0;
1726
        my $col=0;
1727
 
1728
        my $src = $self->object_get_attribute("SELECT_PATH","src");
1729
        my $dst = $self->object_get_attribute("SELECT_PATH","dst");
1730
 
1731
        my @acyclic_turns;
1732
        my $path_select= $self->object_get_attribute("routing_auto",'PATH_SELECT');
1733
        if ($path_select ne "all-paths"){
1734
                 my $ref = $self->object_get_attribute('routing_auto','acyclic_turns_model');
1735
                 if(defined $ref) {
1736
                        @acyclic_turns = @{$ref};
1737
                 }else{
1738
                        add_colored_info($info,"Info:No acyclic route model is selected\n",'green');
1739
 
1740
                 }
1741
        }
1742
 
1743
 
1744
 
1745
 
1746
 
1747
        if(defined $src && defined $dst ){
1748
                my $s= $self->object_get_attribute("$src","NAME");
1749
                my $d= $self->object_get_attribute("$dst","NAME");
1750
                $table->attach (def_label("Select path between $s to $d" ),$col,$col+10,$row,$row+1,'fill','shrink',2,2);
1751
                add_info($info,"get list of all paths between $s to $d \n") if (defined $info);
1752
                $row=1;
1753
                my ($ref1,$ref2)= ($path_select eq "all-paths") ?  get_all_paths_between_two_endps($self,$src, $dst):
1754
                get_all_paths_between_two_endps_using_accyclic_turn($self,$src, $dst,\@acyclic_turns);
1755
 
1756
 
1757
                my @paths = @{$ref1};
1758
                my @ports= @{$ref2};
1759
                my $n=0;
1760
                my $select = $self->object_get_attribute('Route',"${src}::$dst");
1761
                foreach my $p (@paths){
1762
                        my $scal;
1763
                        my $selp;
1764
                        my $path_num=$n;
1765
                        my $path=$p;
1766
                        foreach my $q ( @{$p}){
1767
                                my $inst=$self->object_get_attribute("$q",'NAME');
1768
                                $scal= (defined $scal)? $scal."->$inst" : $inst;
1769
                        }
1770
 
1771
                        foreach my $q ( @{$select}){
1772
                                my $inst=$self->object_get_attribute("$q",'NAME');
1773
                                $selp= (defined $selp)? $selp."->$inst" : $inst;
1774
                        }
1775
 
1776
 
1777
                        my $check= gen_checkbutton();
1778
                        #print "if($select eq $path)";
1779
                        if(defined $select && defined $scal && defined $selp) {if($selp eq $scal) {$check->set_active(TRUE);}}
1780
                        else {$check->set_active(FALSE);}
1781
 
1782
                        $check-> signal_connect("toggled" => sub{
1783
                                if($check->get_active()) {
1784
 
1785
                                        $self->object_add_attribute('Route',"${src}::$dst",$path);
1786
                                }
1787
                                else {
1788
 
1789
                                        $self->object_add_attribute('Route',"${src}::$dst",undef);
1790
                                }
1791
                                set_gui_status($self,"ref",1);
1792
                        });
1793
 
1794
 
1795
                        my $label =gen_label_in_left("$scal");
1796
                        $table->attach ($check ,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $col++;
1797
                        $table->attach ($label ,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $row++;$col=0;
1798
 
1799
                        $n++;
1800
                }
1801
 
1802
 
1803
        }
1804
 
1805
        return add_widget_to_scrolled_win($table);
1806
 
1807
}
1808
 
1809
 
1810
 
1811
##########
1812
#       save
1813
##########
1814
sub save_network {
1815
        my ($self)=@_;
1816
        # read topology  name
1817
        my $name=$self->object_get_attribute('save_as');
1818
        #print $name;
1819
        my $s= (!defined $name)? 0 : (length($name)==0)? 0 :1;
1820
        if ($s == 0){
1821
                message_dialog("Please set the topology name!");
1822
                return 0;
1823
        }
1824
        # Write object file
1825
        my $fname = "$name.NWM";
1826
        open(FILE,  ">lib/netwmaker/$fname") || die "Can not open: $!";
1827
        print FILE perl_file_header("$fname");
1828
        print FILE Data::Dumper->Dump([\%$self],["nwmaker"]);
1829
        close(FILE) || die "Error closing file: $!";
1830
        message_dialog("Current network maker state is saved as lib/netwmaker/$fname!");
1831
        return 1;
1832
}
1833
 
1834
sub get_all_endp_ids{
1835
        my $self=shift;
1836
        my %e=  $self->object_get_attribute("E");
1837
        my @list = sort keys %e;
1838
        return @list;
1839
 
1840
}
1841
 
1842
 
1843
 
1844
#############
1845
#    load
1846
#############
1847
 
1848
sub load_net_maker{
1849
    my ($self,$info)=@_;
1850
    my $file;
1851
        my $dialog =  gen_file_dialog (undef, 'NWM');
1852
 
1853
 
1854
    my $dir = Cwd::getcwd();
1855
    $dialog->set_current_folder ("$dir/lib/netwmaker")    ;
1856
 
1857
    if ( "ok" eq $dialog->run ) {
1858
        $file = $dialog->get_filename;
1859
        my ($name,$path,$suffix) = fileparse("$file",qr"\..[^.]*$");
1860
        if($suffix eq '.NWM'){
1861
            my ($pp,$r,$err) = regen_object($file );
1862
            if ($r){
1863
                add_info($info,"**Error: cannot open $file file: $err\n");
1864
                 $dialog->destroy;
1865
                return;
1866
            }
1867
 
1868
 
1869
            clone_obj($self,$pp);
1870
 
1871
 
1872
        }
1873
     }
1874
     $dialog->destroy;
1875
     set_gui_status($self,"ref",1)
1876
}
1877
 
1878
 
1879
 
1880
 
1881
 
1882
 
1883
 
1884
sub get_all_paths_between_two_endps{
1885
        my ($self,$src, $dst)=@_;
1886
        my @proceed_nodes;
1887
        my @head_nodes;
1888
 
1889
        my $offset = $self->object_get_attribute('routing_auto','OFFSET');
1890
        my $max_len = $self->object_get_attribute('routing_auto','MAX_LENGTH');
1891
 
1892
        push (@head_nodes,$src);
1893
        push (@proceed_nodes,$src);
1894
 
1895
        my @paths;
1896
        my @ports;
1897
        my @paths_to_dst;
1898
        my @ports_to_dst;
1899
 
1900
        my @first_path=($src);
1901
        my @first_port=(0);
1902
        $paths[0]=\@first_path;
1903
        $ports[0]=\@first_port;
1904
 
1905
        # select one path
1906
        my $n=0;
1907
        my $min_dist=1000000;
1908
        do{
1909
                my @current_path= @{$paths[$n]};
1910
                my @current_port= @{$ports[$n]};
1911
                # get head node
1912
                my $head_node =         $current_path[-1];
1913
                if(defined $head_node){
1914
                        # get connected nodes for all ports 
1915
                        #print "hn=$head_node\n";
1916
                        my $pnum =  $self->object_get_attribute($head_node,'PNUM');
1917
 
1918
                        for (my $i=0;$i<$pnum; $i++){
1919
                                my @new_path=@current_path;
1920
                                my @new_ports=@current_port;
1921
                                my $src_port = "Port[${i}]";
1922
                                my $connect = $self->{$head_node}{'PCONNECT'}{$src_port};
1923
                                if(defined $connect){
1924
                                        my ($node,$pnode)=split(/\s*,\s*/,$connect);
1925
                                        #add connected nodes to head_nodes if they are not in path before
1926
                                        if(!defined get_scolar_pos($node,@new_path)){
1927
                                                my $size=scalar @new_path;
1928
                                                #if ($min_dist > $size){
1929
                                                if( ($min_dist+$offset) > $size &&   $max_len>=$size){
1930
 
1931
 
1932
                                                        push (@new_path,$node);
1933
                                                        push (@new_ports,$pnode);
1934
                                                        push (@paths,\@new_path);
1935
                                                        push (@ports,\@new_ports);
1936
                                                        if($node eq $dst){
1937
                                                                push(@paths_to_dst,\@new_path);
1938
                                                                push(@ports_to_dst,\@new_ports);
1939
                                                                $min_dist=$size+1 if ($min_dist > $size);
1940
                                                        }
1941
                                                }
1942
                                        } #if
1943
                                }
1944
                        }#for
1945
                }
1946
                $n++;
1947
        }while( defined $paths[$n]);
1948
 
1949
        #print "\@paths_to_dst". Dumper(@paths_to_dst). "\n \@ports_to_dst". Dumper(@ports_to_dst) . "\n" ;
1950
 
1951
        return (\@paths_to_dst,\@ports_to_dst);
1952
 
1953
}
1954
 
1955
sub get_path_from_turns {
1956
        my ($self,$ref)=@_;
1957
        my @new_turn = @{$ref} if(defined $ref);
1958
        my @path_nodes;
1959
        my @path_ports;
1960
        my $st2;
1961
        foreach my $code (@new_turn){
1962
                my $pn2  =  $code & 0xF;
1963
                $code >>=4;
1964
                my $rn2  = $code & 0xFFF;
1965
                $code >>=12;
1966
                my $pn1 =$code & 0xF;
1967
                $code >>=4;
1968
                my $rn1=$code;
1969
                my $st1 = ($pn1==1)? "ENDP_${rn1}" : "ROUTER${pn1}_${rn1}";
1970
                $st2 = ($pn2==1)? "ENDP_${rn2}"    : "ROUTER${pn2}_${rn2}";
1971
                push(@path_nodes,$st1);
1972
        }
1973
        push(@path_nodes,$st2);
1974
 
1975
        @path_ports=(0);
1976
        for (my $i=0; $i<scalar @path_nodes-1; $i++){
1977
                my ($p1,$p2) =get_connection_port_num_between_two_nodes($self,$path_nodes[$i],$path_nodes[$i+1]);
1978
                push(@path_ports,"Port[$p2]");
1979
        }
1980
 
1981
        return (\@path_nodes,\@path_ports);
1982
 
1983
}
1984
 
1985
sub get_all_paths_between_two_endps_using_accyclic_turn{
1986
        my ($self,$src, $dst,$ref)=@_;
1987
        my @proceed_turns;
1988
        my @head_turns;
1989
        my @accyclic_turn= @{$ref};
1990
 
1991
        my $offset = $self->object_get_attribute('routing_auto','OFFSET');
1992
        my $max_len = $self->object_get_attribute('routing_auto','MAX_LENGTH');
1993
 
1994
        my @paths_to_dst;
1995
        my @ports_to_dst;
1996
 
1997
        my %graph;
1998
 
1999
        foreach my $str (@accyclic_turn){
2000
                my ($s1,$s2) = split /\s/, $str;
2001
                push(@{$graph{$s1}},$s2);
2002
        }
2003
 
2004
        my $start_turns;
2005
        my $ended_turns;
2006
        my $src_port = "Port[0]";
2007
        my $connect = $self->{$src}{'PCONNECT'}{$src_port};
2008
        if(defined $connect){
2009
                my ($node,$pnode)=split(/\s*,\s*/,$connect);
2010
                $start_turns =  get_turn_code("${src}::${node}");
2011
        }
2012
 
2013
        $connect = $self->{$dst}{'PCONNECT'}{$src_port};
2014
        if(defined $connect){
2015
                my ($node,$pnode)=split(/\s*,\s*/,$connect);
2016
                $ended_turns =  get_turn_code("${node}::${dst}");
2017
        }
2018
 
2019
        push (@head_turns,$start_turns);
2020
    push (@proceed_turns,$start_turns);
2021
 
2022
 
2023
 
2024
 
2025
 
2026
        my @turns;
2027
        my @ports;
2028
        my @turns_to_dst;
2029
        my @first_turn=($start_turns);
2030
 
2031
        $turns[0]=\@first_turn;
2032
 
2033
 
2034
        # select one path
2035
        my $n=0;
2036
        my $min_dist=1000000;
2037
        do{
2038
                my @current_turn= @{$turns[$n]};
2039
                # get head node
2040
                my $head_turn =         $current_turn[-1];
2041
                if(defined $head_turn){
2042
                        #get all turns 
2043
                        my @all_fwd_turns = @{$graph{$head_turn}} if (defined $graph{$head_turn});
2044
 
2045
                        foreach my $fwd_turn (@all_fwd_turns){
2046
                                my @new_turn=@current_turn;
2047
                                #add new turn to head_turns if they are not in turns before
2048
                                if(!defined get_scolar_pos($fwd_turn,@new_turn)){
2049
                                        my $size=scalar @new_turn;
2050
                                        #if ($min_dist > $size){
2051
                                        if( ($min_dist+$offset) > $size &&   $max_len>=$size){
2052
                                                push (@new_turn,$fwd_turn);
2053
                                                push (@turns,\@new_turn);
2054
                                                if($fwd_turn eq $ended_turns){
2055
                                                        push(@turns_to_dst,\@new_turn);
2056
                                                        my ($path_ref,$port_ref) = get_path_from_turns($self,\@new_turn);
2057
                                                        push(@paths_to_dst,$path_ref);
2058
                                                        push(@ports_to_dst,$port_ref);
2059
                                                        $min_dist=$size+1 if ($min_dist > $size);
2060
                                                } #if
2061
 
2062
                                        }#if
2063
                                }#if
2064
                        }#foreach
2065
                }#if
2066
        $n++;
2067
        }while( defined $turns[$n]);
2068
 
2069
 
2070
 
2071
        #print "\@paths_to_dst". Dumper(@paths_to_dst). "\n \@ports_to_dst". Dumper(@ports_to_dst) . "\n" ;
2072
 
2073
 
2074
        return (\@paths_to_dst,\@ports_to_dst);
2075
 
2076
}
2077
 
2078
 
2079
 
2080
 
2081
sub get_turn_code {
2082
        my $turn =shift;
2083
        my ($pn1,$rn1,$pn2,$rn2)= sscanf( "ROUTER%u_%u::ROUTER%u_%u",$turn);
2084
        if(defined $rn1){
2085
                return ( ($rn1 << 20)+ ($pn1 << 16) +  ($rn2 << 4) +  $pn2);
2086
        }
2087
        ($rn1,$pn2,$rn2)= sscanf( "ENDP_%u::ROUTER%u_%u",$turn);
2088
        if(defined $rn1){
2089
                return ( ($rn1 << 20)+ (1 << 16) +  ($rn2 << 4) +  $pn2);
2090
        }
2091
        ($pn1,$rn1,$rn2)= sscanf( "ROUTER%u_%u::ENDP_%u",$turn);
2092
        return ( ($rn1 << 20)+ ($pn1 << 16) +  ($rn2 << 4) +  1);
2093
}
2094
 
2095
sub get_turn_str {
2096
        my $code =shift;
2097
        my $pn2  =  $code & 0xF;
2098
        $code >>=4;
2099
        my $rn2  = $code & 0xFFF;
2100
        $code >>=12;
2101
        my $pn1 =$code & 0xF;
2102
        $code >>=4;
2103
        my $rn1=$code;
2104
        my $st1 = ($pn1==1)? "ENDP_${rn1}" : "ROUTER${pn1}_${rn1}";
2105
        my $st2 = ($pn2==1)? "ENDP_${rn2}" : "ROUTER${pn2}_${rn2}";
2106
 
2107
        return   "${st1}::${st2}";
2108
}
2109
 
2110
sub get_turn_involved_routrs{
2111
        my ($s1,$s2,$info)=@_;
2112
        my ($r1,$ra2) = split /::/, $s1;
2113
        my ($rb2,$r3) = split /::/, $s2;
2114
        add_colored_info($info,"Error in turn format. $s1 -> $s2 : $ra2 should be equal with $rb2 ",'red') if($ra2 ne $rb2);
2115
        return ($r1,$ra2,$r3);
2116
}
2117
 
2118
sub get_path_edges_graph_file{
2119
        my ($ref1,$ref2) = @_;
2120
        my @a_nodes = @{$ref1};
2121
        my %graph   = %{$ref2};
2122
 
2123
        my $old_r;
2124
        foreach my $r (@a_nodes){
2125
 
2126
                if(defined $old_r){
2127
                        my $str1 = "$old_r $r";
2128
                        my $n1  = get_turn_code($old_r);
2129
                        my $n2  = get_turn_code($r);
2130
                        my $str2 = "$n1 $n2";
2131
                        $graph{$str2}=$str1;
2132
                }
2133
                $old_r=$r;
2134
        }
2135
        return %graph;
2136
}
2137
 
2138
 
2139
 
2140
 
2141
sub get_forbiden_turns_old {
2142
#sub gen_aciclic_turn_graph {   
2143
        my ($self,$info)=@_;
2144
        my @forbiden_turn;
2145
        add_info($info,"Calculate forbidden turns to avoid deadlock \n");
2146
        #step 1: get the list of all  minimal paths between all source and destination pairs
2147
        my $graph='';
2148
        my $graph_coded='';
2149
        my @all_endpoints=get_list_of_all_endpoints($self);
2150
 
2151
        my %edge_graph;
2152
        foreach  my $src  (@all_endpoints ){
2153
                foreach  my $dst  (@all_endpoints ){
2154
                        if($src ne $dst){
2155
                                my ($paths_to_dst,$ports_to_dst) = get_all_paths_between_two_endps($self,$src, $dst);
2156
                                foreach my $path (@{$paths_to_dst}) {
2157
                                        if (defined $path){
2158
                                                #path counting
2159
                                                my @a_nodes=    get_adjacent_node_in_a_path($path);#get_adjacent_router_in_a_path($path);
2160
                                                print "@a_nodes = \@a_nodes \n";
2161
                                                %edge_graph = get_path_edges_graph_file (\@a_nodes,\%edge_graph);
2162
                                                #$graph  =$graph. $str1;
2163
                                                #$graph_coded = $graph_coded . $str2;
2164
                                        }#defined path  
2165
                                }#foreach       
2166
                        }#if                    
2167
                }#froeach                               
2168
 
2169
        }#froeach       
2170
 
2171
        foreach my $p (sort keys %edge_graph){
2172
                $graph_coded  .="$p\n";
2173
                $graph .= "$edge_graph{$p}\n";
2174
        }
2175
 
2176
        my $tmp_dir  = "$ENV{'PRONOC_WORK'}/tmp";
2177
        save_file ("$tmp_dir/paths_graph.edges",$graph);
2178
        save_file ("$tmp_dir/paths_graph_coded.edges",$graph_coded);
2179
 
2180
 
2181
        #remove old files 
2182
        my @files = File::Find::Rule->file()
2183
                            ->name( 'paths_graph_coded_removed*.edges')
2184
                            ->in( "$tmp_dir" );
2185
        foreach my $f (@files){
2186
                unlink  $f if (-f "$f");
2187
        }
2188
 
2189
        # run remove_cycle_edges_by_dfs on coded graph 
2190
        my $remover_dire = get_project_dir()."/mpsoc/remove_cycle/";
2191
        my $cmd  =  "cd $remover_dire;
2192
        python  break_cycles.py  -g $tmp_dir/paths_graph_coded.edges;
2193
        python remove_cycle_edges_by_dfs.py -g $tmp_dir/paths_graph_coded.edges;
2194
        python remove_cycle_edges_by_minimum_feedback_arc_set_greedy.py  -g $tmp_dir/paths_graph_coded.edges";
2195
        #sort paths_graph_coded.edges | uniq > newfile.db
2196
 
2197
        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
2198
        if(length $stderr>1){
2199
                add_colored_info($info,"$stderr\n",'red');
2200
        }else {
2201
                add_info($info,"$stdout\n");
2202
        }
2203
        # find the files with the list edges removal
2204
        @files = File::Find::Rule->file()
2205
                         ->name( 'paths_graph_coded_removed*.edges')
2206
                         ->in( "$tmp_dir" );
2207
 
2208
 
2209
        my $line_num;
2210
        my $out;
2211
        foreach my $f (@files){
2212
                my $n =count_file_line_num ($f);
2213
                $line_num = $n if(! defined $line_num);
2214
                if($n <= $line_num){
2215
                        $out = $f;
2216
                        $line_num=$n;
2217
                }
2218
        }
2219
 
2220
 
2221
        # check if the output file is generated 
2222
        if (-f $out ){
2223
                add_colored_info($info,"$out file has been selected as it has the minimum number of edge removal of $line_num \n",'blue');
2224
 
2225
        } else {
2226
                add_colored_info($info,"could not find a paths_graph_coded_removed*.edges file.  Please make sure $cmd has been run successfully\n",'red');
2227
                return;
2228
 
2229
        }
2230
 
2231
 
2232
 
2233
 
2234
        my $r;
2235
        open my $fh, "<", $out or $r = "$!\n";
2236
    if(defined $r) {
2237
        add_colored_info($info,"Could not open $out: $r",'red');
2238
                return;
2239
    }
2240
 
2241
    add_colored_info($info,"List of forbidden turns: \n",'blue');
2242
 
2243
        while (my $line = <$fh>) {
2244
        chomp $line;
2245
        $line=~ s/^\s+|\s+$//g;
2246
        my ($s1,$s2) = split /\s/, $line;
2247
        $s1  = get_turn_str($s1);
2248
                $s2  = get_turn_str($s2);
2249
                my @turn = get_turn_involved_routrs($s1,$s2);
2250
                my $str = get_path_instance_string($self,\@turn);
2251
                my $string=join('->',@turn);
2252
                push (@forbiden_turn, $string);
2253
                add_info($info,"$str\n");
2254
 
2255
  }
2256
  return @forbiden_turn;
2257
 
2258
}
2259
 
2260
 
2261
sub gen_turn_graph{
2262
        my $self=shift;
2263
        my %edge_graph;
2264
        my @all_nodes=get_list_of_all_nodes($self);
2265
        foreach  my $node1  (@all_nodes ){
2266
                my $pnum1=$self->object_get_attribute("$node1",'PNUM');
2267
                for (my $i=0;$i<$pnum1; $i++){
2268
                        my $port1 = "Port[${i}]";
2269
                        my $connect1 = $self->{$node1}{'PCONNECT'}{$port1};
2270
                        if (defined $connect1) {
2271
                                my ($node2,$Rport2)=split(/\s*,\s*/,$connect1);
2272
                                my $pnum2=$self->object_get_attribute("$node2",'PNUM');
2273
                                for (my $j=0;$j<$pnum2; $j++){
2274
                                        my $port2 = "Port[${j}]";
2275
                                        my $connect2 = $self->{$node2}{'PCONNECT'}{$port2};
2276
                                        if (defined $connect2) {
2277
                                                my ($node3,$Rport3)=split(/\s*,\s*/,$connect2);
2278
                                                if($node1 ne $node3){
2279
                                                        my @a_nodes=    ("${node1}::${node2}","${node2}::${node3}");
2280
                                                        %edge_graph = get_path_edges_graph_file (\@a_nodes,\%edge_graph);
2281
                                                }
2282
 
2283
                                        }#if    
2284
                                }#for           
2285
                        }#if
2286
                }#for    
2287
        }
2288
        return %edge_graph;
2289
}
2290
 
2291
sub gen_aciclic_turn_graph {
2292
 
2293
        my ($self,$info)=@_;
2294
 
2295
        #my @forbiden_turn;
2296
 
2297
        add_info($info,"Generate an acyclic turn graph to avoid deadlock \n");
2298
        #step 1: get the list of turn in topology. A turn is a path that include three nodes.
2299
        my $graph='';
2300
        my $graph_coded='';
2301
 
2302
        my %edge_graph =gen_turn_graph($self);
2303
 
2304
 
2305
        foreach my $p (sort keys %edge_graph){
2306
                $graph_coded  .="$p\n";
2307
                $graph .= "$edge_graph{$p}\n";
2308
        }
2309
 
2310
        my $tmp_dir  = "$ENV{'PRONOC_WORK'}/tmp";
2311
        save_file ("$tmp_dir/paths_graph.edges",$graph);
2312
        save_file ("$tmp_dir/paths_graph_coded.edges",$graph_coded);
2313
 
2314
 
2315
        #remove old files 
2316
        my @files = File::Find::Rule->file()
2317
                            ->name( 'paths_graph_coded_removed*.edges')
2318
                            ->in( "$tmp_dir" );
2319
        foreach my $f (@files){
2320
                unlink  $f if (-f "$f");
2321
        }
2322
 
2323
        # run remove_cycle_edges_by_dfs on coded graph 
2324
        my $remover_dire = get_project_dir()."/mpsoc/remove_cycle/";
2325
        my $cmd  =  "cd $remover_dire;
2326
        python  break_cycles.py  -g $tmp_dir/paths_graph_coded.edges;
2327
        python remove_cycle_edges_by_dfs.py -g $tmp_dir/paths_graph_coded.edges;
2328
        python remove_cycle_edges_by_minimum_feedback_arc_set_greedy.py  -g $tmp_dir/paths_graph_coded.edges";
2329
        #sort paths_graph_coded.edges | uniq > newfile.db
2330
 
2331
        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
2332
        if(length $stderr>1){
2333
                add_colored_info($info,"$stderr\n",'red');
2334
        }else {
2335
                add_info($info,"$stdout\n");
2336
        }
2337
        # find the files with the list edges removal
2338
        @files = File::Find::Rule->file()
2339
                         ->name( 'paths_graph_coded_removed*.edges')
2340
                         ->in( "$tmp_dir" );
2341
        my $line_num;
2342
        my $out;
2343
        my %all_outs;
2344
        foreach my $f (@files){
2345
 
2346
                my $n =count_file_line_num ($f);
2347
                $all_outs{$f}=$n;
2348
 
2349
        }
2350
 
2351
        my @graph_array=sort keys %edge_graph;
2352
        my @acyclic_turns;
2353
        my @removed_edge;
2354
        my $result=0;
2355
 
2356
        my %algorithms;
2357
 
2358
        foreach my $file  (sort {$all_outs{$a} <=> $all_outs{$b}} keys %all_outs) {
2359
                $line_num = $all_outs{$file};
2360
                $out=$file;
2361
                add_info($info,"check if $file file $line_num edges removal results in a connected graph\n");
2362
 
2363
                @removed_edge=();
2364
                open(FILE,$file);
2365
                if (tell FILE ){
2366
                        add_colored_info($info,"Cannot open $file to read: $!\n",'red');
2367
                        return;
2368
                }
2369
        while (my $line = <FILE>) {
2370
                chomp($line);
2371
                $line=~ s/^\s+|\s+$//g;
2372
                        push(@removed_edge,$line);
2373
                }
2374
        close FILE;
2375
 
2376
                @acyclic_turns = get_diff_array ( \@graph_array , \@removed_edge );
2377
 
2378
 
2379
 
2380
                $result = check_diff_graph_be_connected ($self,\@acyclic_turns,$info);
2381
                if($result == 1){
2382
                        my $alg = capture_string_between ('paths_graph_coded_removed_by_',$file,".edges");
2383
                        $algorithms{$alg}=$line_num;
2384
                        #save @acyclic_turns for this algorithm
2385
                        open(F,  ">$tmp_dir/$alg.alg") || die "Can not creat: $!";
2386
                print F perl_file_header("$alg.alg");
2387
                print F Data::Dumper->Dump([\@acyclic_turns],['turn']);
2388
                close(F ) || die "Error closing file: $!";
2389
                }
2390
 
2391
 
2392
        }
2393
 
2394
        $self->object_add_attribute('routing_auto','acyclic_algorithms',\%algorithms);
2395
 
2396
 
2397
    if (scalar (keys %algorithms) == 0){
2398
                add_colored_info($info,"Unable to find any directed acyclic graph for routing\n",'red');
2399
                return;
2400
    }
2401
 
2402
        return;
2403
        #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');
2404
 
2405
 
2406
 
2407
    #add_colored_info($info,"List of forbidden turns: \n",'blue');
2408
 
2409
        foreach my $line (@removed_edge) {
2410
        chomp $line;
2411
        my ($s1,$s2) = split /\s/, $line;
2412
        $s1  = get_turn_str($s1);
2413
                $s2  = get_turn_str($s2);
2414
                my @turn = get_turn_involved_routrs($s1,$s2);
2415
                my $str = get_path_instance_string($self,\@turn);
2416
                my $string=join('->',@turn);
2417
  #             push (@forbiden_turn, $string);
2418
                add_info($info,"$str\n");
2419
 
2420
        }
2421
 
2422
 # $self->object_add_attribute('routing_auto','acyclic_turns',\@acyclic_turns);
2423
 
2424
#  return @forbiden_turn;
2425
 
2426
}
2427
 
2428
 
2429
 
2430
sub check_diff_graph_be_connected {
2431
        my ($self,$ref,$info)=@_;
2432
        my @diff = @{$ref};
2433
        my %all_turns;
2434
        my %graph;
2435
 
2436
        foreach my $str (@diff){
2437
                my ($s1,$s2) = split /\s/, $str;
2438
                $all_turns{$s1}=1;
2439
                $all_turns{$s2}=1;
2440
                push(@{$graph{$s1}},$s2);
2441
 
2442
        }
2443
 
2444
        my @all_endpoints=get_list_of_all_endpoints($self);
2445
        my @start_turns;
2446
        my @ended_turns;
2447
        foreach my $endp (@all_endpoints){
2448
 
2449
                                my $src_port = "Port[0]";
2450
                                my $connect = $self->{$endp}{'PCONNECT'}{$src_port};
2451
                                if(defined $connect){
2452
                                        my ($node,$pnode)=split(/\s*,\s*/,$connect);
2453
                                        push (@start_turns,     get_turn_code("${endp}::${node}"));
2454
                                        push (@ended_turns,     get_turn_code("${node}::${endp}"));
2455
                                }
2456
        }
2457
 
2458
        my $k=0;
2459
        foreach my $s (@start_turns){# we should see all @ended_turns
2460
 
2461
                my @seen_turns=($s,$ended_turns[$k]);# put connect to itself connection as seen node.  
2462
                $k++;
2463
                my @next_turns =@{$graph{$s}};
2464
 
2465
                while (scalar @next_turns>0){
2466
 
2467
 
2468
                        #print "\@next_nodes = @next_nodes\n";
2469
                        #print "\@seen_nodes = @seen_nodes\n";
2470
                        my $n = pop (@next_turns);
2471
                        #print "\$n  = $n \n";
2472
                        my @nn;
2473
                        @nn = @{$graph{$n}} if (defined $graph{$n});
2474
                        #print "\@nn  = @nn \n";
2475
                        push (@seen_turns, $n);
2476
                        @diff = get_diff_array ( \@nn , \@seen_turns );
2477
                        #print "\@diff  = @diff \n";
2478
                        push (@next_turns,@diff);
2479
 
2480
                }
2481
 
2482
                my @sep = get_diff_array (\@ended_turns,\@seen_turns);
2483
 
2484
                if( scalar @sep > 0) {
2485
                        my $s1  = get_turn_str($s);
2486
                        my ($a1,$a2) = split ('::',$s1);
2487
                        my $n1=$self->object_get_attribute("$a1",'NAME');
2488
 
2489
                        $s1  = get_turn_str($sep[0]);
2490
                        my($a3,$a4) = split ('::',$s1);
2491
                        my $n2=$self->object_get_attribute("$a4",'NAME');
2492
 
2493
                        add_info($info,"\t $n1 is not connected to $n2. \n");
2494
                        return 0;
2495
                }
2496
 
2497
 
2498
        }
2499
 
2500
 
2501
        add_info($info,"\t All endpoints are connected in chanel dpenedency graph. \n");
2502
        return 1;
2503
 
2504
}
2505
 
2506
 
2507
 
2508
sub get_path_instance_string {
2509
        my ($self,$path_ref)=@_;
2510
        my @path = @{$path_ref};
2511
        my @path_inst;
2512
        foreach my $p (@path){
2513
                push (@path_inst, $self->object_get_attribute("$p",'NAME'));
2514
 
2515
        }
2516
        my $string=join('->',@path_inst);
2517
        return $string;
2518
}
2519
 
2520
 
2521
sub remove_cycle_paths {
2522
        my ($self,$info,$paths_ref, $fturn_ref)=@_;
2523
        my @free_paths;
2524
        my @paths= @{$paths_ref};
2525
        my @fturns= @{$fturn_ref};
2526
        my $remove;
2527
 
2528
 
2529
 
2530
        foreach my $path (@paths) {
2531
                my @p = @$path;
2532
                my $turn;
2533
                my $string=join('->',@p);
2534
                #print "$string\n";     
2535
                $remove=0;
2536
                foreach my $t (@fturns){
2537
                         if ($string =~ /$t-/){
2538
                                $remove=1;
2539
                                $turn=$t;
2540
                                last;
2541
                         }
2542
 
2543
                }
2544
                push (@free_paths,$path) if($remove == 0);
2545
                if($remove == 1){
2546
                        my @ft = split /->/, $turn;
2547
                        add_info($info,"path ".get_path_instance_string($self,$path)." is removed due to turn ".get_path_instance_string($self,\@ft)."\n")
2548
                }
2549
        }
2550
        return @free_paths;
2551
}
2552
 
2553
 
2554
 
2555
 
2556
 
2557
 
2558
 
2559
 
2560
sub auto_route {
2561
        my ($self,$info)=@_;
2562
        my %Psize;
2563
        my $alg = $self->object_get_attribute('routing_auto', 'CYCLE_FREE_ALG');
2564
        my ($alg_name,$line) = split (/\s+--\s+/,$alg);
2565
 
2566
        if(!defined $line){
2567
                add_colored_info($info,"No acyclic turn model is selected. click on Generate Cycle-free and make sure it runs successfully!\n",'red');
2568
        return;
2569
        }
2570
        my $tmp_dir  = "$ENV{'PRONOC_WORK'}/tmp";
2571
        my $model_file = "$tmp_dir/$alg_name.alg";
2572
        my ($pp,$r,$err) = regen_object($model_file);
2573
    if ($r){
2574
        add_colored_info($info,"**Error: cannot open $model_file file: $err\n",'red');
2575
                return;
2576
    } else {
2577
        add_info($info,"Use $alg_name algorithm for obtaing acyclic paths\n");
2578
    }
2579
 
2580
        my @acyclic_turns = @{$pp};
2581
 
2582
 
2583
 
2584
        #step 1: calculate all minimal paths between all source and destination pairs
2585
        add_info($info,"Calculate all  paths between all source and destination pairs\n");
2586
        my @all_endpoints=get_list_of_all_endpoints($self);
2587
        foreach  my $src  (@all_endpoints ){
2588
                foreach  my $dst  (@all_endpoints ){
2589
                        if($src ne $dst){
2590
                                my ($paths_to_dst,$ports_to_dst) =  get_all_paths_between_two_endps_using_accyclic_turn($self,$src, $dst,\@acyclic_turns);
2591
                                my @cyle_free_paths= @{$paths_to_dst} if (defined $paths_to_dst);
2592
                                my $size = scalar  @cyle_free_paths;
2593
                                $Psize{"${src}::$dst"} = $size;
2594
                        }
2595
                }
2596
        }
2597
        #step 2: Remove cyclic paths between all source and destination pairs
2598
 
2599
 
2600
 
2601
 
2602
 
2603
 
2604
        #step 3 sort source destination based on the number of paths
2605
        my @keys = sort { $Psize{$a} <=> $Psize{$b} } keys(%Psize);
2606
        for my $key ( @keys) {
2607
                my $size=$Psize{$key};
2608
                #print "size = $size\n";
2609
                next if(defined $self->object_get_attribute('Route',$key));
2610
 
2611
       # print "($key)->($Psize{$key})\n";
2612
        my ($src , $dst)=split ('::',$key);
2613
        my ($paths_to_dst,$ports_to_dst) = get_all_paths_between_two_endps_using_accyclic_turn($self,$src, $dst,\@acyclic_turns);
2614
        #my @cyle_free_paths=remove_cycle_paths($self,$info,$paths_to_dst, \@forbiden_turn);
2615
        my @cyle_free_paths= @{$paths_to_dst} if (defined $paths_to_dst);
2616
        my @sort_paths=sort_paths_based_on_link_usage($self,\@cyle_free_paths);
2617
        my $path;
2618
        my $n=0;
2619
        foreach my $p (@sort_paths ){
2620
                if(check_cyclick_loop($self,$p)==0){
2621
                        $path=$p;
2622
                        #my @rrr=($p);
2623
                        #remove_cycle_paths($self,$info,\@rrr, \@forbiden_turn);
2624
 
2625
                        last;
2626
                }  else {
2627
                        print "***Error  something goes wrong in acyclic turns model  ****************************\n";
2628
                }
2629
                $n++;
2630
        }
2631
        if(!defined $path){
2632
                #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
2633
 
2634
 
2635
                set_gui_status($self,"ref",1);
2636
                add_colored_info($info,"Failed to find an acyclic routing paths for $key nodes!\n",'red');
2637
                return FALSE ;
2638
 
2639
        }
2640
 
2641
        $self->object_add_attribute('Route',$key,$path);
2642
 
2643
        }
2644
 
2645
        set_gui_status($self,"ref",1);
2646
        add_colored_info($info,"The routeing function table is generated successfully!\n",'blue');
2647
        return TRUE;
2648
}
2649
 
2650
 
2651
sub clean_route {
2652
        my ($self,$info)=@_;
2653
 
2654
        my @all_endpoints=get_list_of_all_endpoints($self);
2655
        foreach  my $src  (@all_endpoints ){
2656
                foreach  my $dst  (@all_endpoints ){
2657
        $self->object_add_attribute('Route',"${src}::$dst",undef);
2658
 
2659
        }}
2660
 
2661
        set_gui_status($self,"ref",1);
2662
        add_colored_info($info,"The Routing function table is cleared!\n",'blue');
2663
        return TRUE;
2664
}
2665
 
2666
 
2667
 
2668
sub average{
2669
        my($data) = @_;
2670
        if (not @$data) {
2671
               return 0;
2672
        }
2673
        my $total = 0;
2674
        foreach (@$data) {
2675
                $total += $_;
2676
        }
2677
        my $average = $total / @$data;
2678
        return $average;
2679
}
2680
sub stdev{
2681
        my($data) = @_;
2682
        if(@$data == 1){
2683
                return 0;
2684
        }
2685
        my $average = &average($data);
2686
        my $sqtotal = 0;
2687
        foreach(@$data) {
2688
                $sqtotal += ($average-$_) ** 2;
2689
        }
2690
        my $std = ($sqtotal / (@$data-1)) ** 0.5;
2691
        return $std;
2692
}
2693
 
2694
sub clone_hash{
2695
        my $ref=shift;
2696
        my %hash=%{$ref};
2697
        my %copy;
2698
        foreach my $p (keys %hash){
2699
                if (defined $hash{$p}){ $copy{$p} =  $hash{$p};}
2700
        }
2701
        return %copy;
2702
}
2703
 
2704
sub sort_paths_based_on_link_usage{
2705
        my ($self,$paths_to_dst)=@_;
2706
 
2707
        my %L_num;
2708
        my %max;
2709
        my @all_endpoints=get_list_of_all_endpoints($self);
2710
        #get link count
2711
        foreach  my $src  (@all_endpoints ){
2712
                foreach  my $dst  (@all_endpoints ){
2713
                        my $path = $self->object_get_attribute('Route',"${src}::$dst");
2714
                        if (defined $path){
2715
                                #path counting
2716
                                my @p=  get_adjacent_router_in_a_path($path);
2717
                                foreach my $r (@p){
2718
                                        $L_num{$r} ++;
2719
                                }
2720
 
2721
                        }
2722
                }
2723
        }
2724
        #get std_devision of link  for each path if added   
2725
        my $i=0;
2726
        foreach my $path (@{$paths_to_dst}) {
2727
                my %copy = clone_hash(\%L_num);
2728
                my @p=get_adjacent_router_in_a_path($path);
2729
                foreach my $r (@p){
2730
                                        $copy{$r} ++;
2731
                }
2732
                my @l = sort  values (%copy);
2733
                my $std=stdev(\@l);
2734
                $max{$i}=$std*100;
2735
                $i++;
2736
        }
2737
 
2738
 
2739
        my @order = sort { $max{$a} <=> $max{$b} } keys(%max);
2740
 
2741
        #print "*********** @order ************"; 
2742
        my @sorted;
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
 
2757
sub check_cyclick_loop{
2758
        my ($self,$paths_to_dst)=@_;
2759
 
2760
 
2761
        my %graph;
2762
        my @all_endpoints=get_list_of_all_endpoints($self);
2763
        # create routing dependency graph
2764
 
2765
        foreach  my $src  (@all_endpoints ){
2766
                foreach  my $dst  (@all_endpoints ){
2767
                        my $path = $self->object_get_attribute('Route',"${src}::$dst");
2768
                        if (defined $path){
2769
                                #path counting
2770
                                my @p=  get_adjacent_node_in_a_path($path);
2771
                                %graph=add_route_edge_to_graph(\%graph,\@p);
2772
 
2773
                        }
2774
                }
2775
        }
2776
 
2777
        my @p=  get_adjacent_node_in_a_path($paths_to_dst);
2778
        %graph=add_route_edge_to_graph(\%graph,\@p);
2779
 
2780
        my $result = Algorithm::TSort::cicle_detect( Algorithm::TSort::Graph( ADJ => \%graph ), keys %graph );
2781
 
2782
        #print Data::Dumper->Dump([\%graph],["link"]);
2783
        #print "result=$result\n";
2784
 
2785
 
2786
 
2787
 
2788
 
2789
 
2790
 
2791
        return  $result;
2792
 
2793
 
2794
}
2795
 
2796
sub generate_topology{
2797
        my ($self,$info)=@_;
2798
        my $name=$self->object_get_attribute('save_as');
2799
    my $error = check_verilog_identifier_syntax($name);
2800
    if ( defined $error ){
2801
        #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");
2802
        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";
2803
        add_colored_info($info, $message,'red' );
2804
        return 0;
2805
    }
2806
    my $rname=$self->object_get_attribute('routing_name');
2807
    $error = check_verilog_identifier_syntax($rname);
2808
    if ( defined $error ){
2809
        #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");
2810
        $rname='Undefined' if(!defined $rname);
2811
        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";
2812
        add_colored_info($info, $message,'red' );
2813
        return 0;
2814
    }
2815
 
2816
 
2817
 
2818
 
2819
        #make destination dir
2820
        my $dir =get_project_dir()."/mpsoc/rtl/src_topolgy/$name";
2821
        mkpath("$dir",1,01777) unless (-d $dir) ;
2822
    mkpath("$dir/../common",1,01777) unless (-d "$dir/../common") ;
2823
 
2824
        #save topology image file
2825
        $self->object_add_attribute("graph_save","name","$dir/$name");
2826
        $self->object_add_attribute("graph_save","extension",'png');
2827
        $self->object_add_attribute("graph_save","enable",1);
2828
 
2829
        show_custom_topology_diagram ($self,undef,"topology_diagram");
2830
 
2831
 
2832
 
2833
        #generate topology top module verilog file
2834
        generate_topology_top_v($self,$info,$dir);
2835
        generate_topology_top_genvar_v($self,$info,$dir);
2836
        generate_routing_v($self,$info,$dir);
2837
        #generate_connection_v($self,$info,$dir);
2838
        add_routing_instance_v($self,$info,$dir);
2839
        add_noc_instance_v($self,$info,$dir);
2840
        save_topology_parameter_object_file($self,$info);
2841
 
2842
        #create the file list
2843
        my $txt="+incdir+./\n";
2844
        my @files = File::Find::Rule->file()
2845
                            ->name( '*.v','*.sv')
2846
                            ->in( "$dir/../" );
2847
    foreach my $f (@files){
2848
        my $d = basename(dirname(abs_path($f)));
2849
        my $n = basename($f);
2850
        $txt.="./$d/$n\n";
2851
    }
2852
        save_file("$dir/../custom_flist.f",$txt);
2853
 
2854
 
2855
}
2856
 
2857
 
2858
sub save_topology_parameter_object_file{
2859
        my ($self,$info)=@_;
2860
        my $name=$self->object_get_attribute('save_as');
2861
        my $rname=$self->object_get_attribute('routing_name');
2862
        my $dir =get_project_dir()."/mpsoc/rtl/src_topolgy";
2863
        my $file="$dir/param.obj";
2864
 
2865
        my %param;
2866
 
2867
        if(-f $file){
2868
                 my ($pp,$r,$err) = regen_object($file );
2869
            if ($r){
2870
                add_info($info,"**Error: cannot open $file file: $err\n");
2871
                return;
2872
            }
2873
 
2874
                %param=%{$pp};
2875
        }
2876
 
2877
 
2878
        my @ends=get_list_of_all_endpoints($self);
2879
    my @routers=get_list_of_all_routers($self);
2880
 
2881
    my $MAX_P=0;
2882
    my %router_ps;
2883
    foreach my $p (@routers){
2884
        my $Pnum=$self->object_get_attribute("$p",'PNUM');
2885
        $MAX_P =$Pnum  if($Pnum>$MAX_P );
2886
        $router_ps{$Pnum}=(defined $router_ps{$Pnum})? $router_ps{$Pnum}+1 : '1';
2887
    }
2888
 
2889
    my $NE= scalar @ends;
2890
    my $NR= scalar @routers;
2891
 
2892
 
2893
        $param{"\"$name\""}{'T1'}=$NE;
2894
        $param{"\"$name\""}{'T2'}=$NR;
2895
        $param{"\"$name\""}{'T3'}=$MAX_P;
2896
        my $routs = $param{"\"$name\""}{'ROUTE_NAME'};
2897
        my $new="\"$rname\"";
2898
        if(!defined $routs){
2899
                $param{"\"$name\""}{'ROUTE_NAME'}=$new;
2900
        }
2901
        else {
2902
                my @r=split(/\s*,\s*/,$routs);
2903
                unless( grep (/^$new$/,@r)){
2904
                        $param{"\"$name\""}{'ROUTE_NAME'}= $routs.",$new" ;
2905
                }
2906
        }
2907
 
2908
        $param{"\"$name\""}{'ROUTER_Ps'}= \%router_ps;
2909
 
2910
 
2911
        my @er_addr;
2912
        foreach my $end (@ends){
2913
                my $connect = $self->{$end}{'PCONNECT'}{'Port[0]'};
2914
                my ($Rname,$Rport)=split(/\s*,\s*/,$connect);
2915
                my $R = get_scolar_pos($Rname,@routers);
2916
                push(@er_addr,$R);
2917
        }
2918
        $param{"\"$name\""}{'er_addr'}= \@er_addr;
2919
 
2920
 
2921
 
2922
 
2923
    open(FILE,  ">$file") || die "Can not open: $!";
2924
    print FILE perl_file_header("$file");
2925
    print FILE Data::Dumper->Dump([\%param],['Topology']);
2926
    close(FILE) || die "Error closing file: $!";
2927
 
2928
}
2929
 
2930
 
2931
sub get_path_route_widgets {
2932
        my      ($self,$info)=@_;
2933
 
2934
        my              $w1 = show_paths_between_two_endps($self,$info);
2935
        my              $w2 = routing_summary($self,$info);
2936
    my $h=gen_hpaned($w1,.15,$w2);
2937
    $h -> pack1($w1, TRUE, TRUE);
2938
        $h -> pack2($w2, TRUE, TRUE);
2939
        return $h;
2940
}
2941
 
2942
 
2943
sub build_network_maker_gui {
2944
        my ($self) = @_;
2945
        set_gui_status($self,"ideal",0);
2946
        $self->object_add_attribute ("process_notebook","currentpage",0);
2947
        my $main_table= def_table(2,10,FALSE);
2948
 
2949
    my ($infobox,$info)= create_txview();
2950
 
2951
 
2952
        my $notebook = gen_notebook();
2953
        $notebook->set_tab_pos ('left');
2954
        $notebook->set_scrollable(TRUE);
2955
 
2956
 
2957
 
2958
        my $page0=take_node_num_page($self);
2959
        my $page1=take_instance_page($self);
2960
        my $page2=connection_page_auto($self,$info);
2961
        my $page3=connection_page($self,$info);
2962
        my $page4=routing_page_manual($self,$info);
2963
 
2964
        my $page0_win = add_widget_to_scrolled_win($page0);
2965
        my $page1_win = add_widget_to_scrolled_win($page1);
2966
        my $page2_win = add_widget_to_scrolled_win($page2);
2967
        my $page3_win = add_widget_to_scrolled_win($page3);
2968
        my $page4_win = add_widget_to_scrolled_win($page4);
2969
 
2970
 
2971
        $notebook->append_page ($page0_win,gen_label_in_center  (" Nodes #"));
2972
        $notebook->append_page ($page1_win,gen_label_in_center  ("Instance"));
2973
        $notebook->append_page ($page2_win,gen_label_in_center  ("Connection Auto"));
2974
        $notebook->append_page ($page3_win,gen_label_in_center  ("Connection Manual"));
2975
        $notebook->append_page ($page4_win,gen_label_in_center  ("Route Select"));
2976
 
2977
 
2978
        $notebook->signal_connect( 'switch-page'=> sub{ # rebulid the current page              
2979
                $self->object_add_attribute ("process_notebook","currentpage",$_[2]);   #save the new pagenumber
2980
                set_gui_status($self,"ref",1);
2981
        });
2982
 
2983
 
2984
        my $draw=custom_topology_diagram($self);
2985
        my $h1=gen_hpaned($notebook,.35,$draw);
2986
 
2987
 
2988
        my $v2=gen_vpaned($h1,.65,$infobox);
2989
 
2990
 
2991
        my $generate = def_image_button('icons/gen.png','Generate');
2992
        my $open = def_image_button('icons/browse.png','Load');
2993
 
2994
 
2995
        my ($entrybox,$entry) = def_h_labeled_entry('Topology name:',undef);
2996
 
2997
        $entry->signal_connect( 'changed'=> sub{
2998
                my $name=$entry->get_text();
2999
                $self->object_add_attribute ("save_as",undef,$name);
3000
        });
3001
 
3002
        my ($entrybox2,$entry2) = def_h_labeled_entry('Routing Alg. name:',undef);
3003
 
3004
        $entry2->signal_connect( 'changed'=> sub{
3005
                my $name=$entry2->get_text();
3006
                $self->object_add_attribute ("routing_name",undef,$name);
3007
        });
3008
 
3009
        my $save = def_image_button('icons/save.png','Save');
3010
        #$entrybox->pack_end($save,   FALSE, FALSE,0);
3011
 
3012
        $main_table->attach_defaults ($v2  , 0, 12, 0,24);
3013
        $main_table->attach ($open,0, 1, 24,25,'expand','shrink',2,2);
3014
        $main_table->attach ($save,1, 2, 24,25,'expand','shrink',2,2);
3015
 
3016
        $main_table->attach ($entrybox,2, 4, 24,25,'expand','shrink',2,2);
3017
        $main_table->attach ($entrybox2,4, 6, 24,25,'expand','shrink',2,2);
3018
 
3019
        $main_table->attach ($generate, 6, 9, 24,25,'expand','shrink',2,2);
3020
 
3021
 
3022
        my $sc_win = add_widget_to_scrolled_win($main_table);
3023
 
3024
 
3025
        #setting for graphs
3026
        my $n=0;
3027
    my $sample="sample$n";
3028
        $n++;
3029
        $self->object_add_attribute("id",undef,$n);
3030
        $self->object_add_attribute("active_setting",undef,undef);
3031
        $self->object_add_attribute_order("samples",$sample);
3032
        $self->object_add_attribute($sample,"color",1);
3033
        add_color_to_gd($self);
3034
 
3035
 
3036
        $open-> signal_connect("clicked" => sub{
3037
 
3038
 
3039
 
3040
        load_net_maker($self,$info);
3041
        my $n=0;
3042
    my $sample="sample$n";
3043
        $n++;
3044
        $self->object_add_attribute("id",undef,$n);
3045
        $self->object_add_attribute("active_setting",undef,undef);
3046
        $self->object_add_attribute_order("samples",$sample);
3047
        $self->object_add_attribute($sample,"color",1);
3048
        add_color_to_gd($self);
3049
 
3050
 
3051
                set_gui_status($self,"ref",5);
3052
 
3053
        });
3054
 
3055
        $save-> signal_connect("clicked" => sub{
3056
 
3057
                save_network($self);
3058
                set_gui_status($self,"ref",5);
3059
 
3060
 
3061
        });
3062
 
3063
        $generate->signal_connect("clicked" => sub{
3064
                generate_topology($self,$info);
3065
 
3066
        });
3067
 
3068
 
3069
 
3070
        #check soc status every 0.5 second. refresh device table if there is any changes 
3071
        Glib::Timeout->add (100, sub{
3072
 
3073
                my ($state,$timeout)= get_gui_status($self);
3074
 
3075
                if ($timeout>0){
3076
                        $timeout--;
3077
                        set_gui_status($self,$state,$timeout);
3078
                        return TRUE;
3079
 
3080
                }
3081
                if($state eq "ideal"){
3082
                        return TRUE;
3083
 
3084
                }
3085
 
3086
                if($state eq "ref" || $state eq "redraw"){
3087
 
3088
                        my $page_num=$self->object_get_attribute ("process_notebook","currentpage");
3089
                        if($state eq "ref"){
3090
                                if($page_num==0){
3091
                                        $page0->destroy;
3092
                                        $page0=take_node_num_page($self);
3093
                                        add_widget_to_scrolled_win($page0,$page0_win);
3094
                                        $page0_win->show_all;
3095
 
3096
                                }
3097
                                if($page_num==1){
3098
                                        $page1->destroy;
3099
                                        $page1=take_instance_page($self);
3100
                                        add_widget_to_scrolled_win($page1,$page1_win);
3101
                                        $page1_win->show_all;
3102
                                }
3103
                                if($page_num==2){
3104
                                        $page2->destroy;
3105
                                        $page2=connection_page_auto($self,$info);
3106
                                        add_widget_to_scrolled_win($page2,$page2_win);
3107
                                        $page2_win->show_all;
3108
                                }
3109
                                if($page_num==3){
3110
                                        $page3->destroy;
3111
                                        $page3=connection_page($self,$info);
3112
                                        add_widget_to_scrolled_win($page3,$page3_win);
3113
                                        $page3_win->show_all;
3114
                                }
3115
                                if($page_num==4){
3116
                                        $page4->destroy;
3117
                                        $page4=routing_page_manual($self,$info);
3118
                                        add_widget_to_scrolled_win($page4,$page4_win);
3119
                                        $page4_win->show_all;
3120
                                }
3121
 
3122
                        }
3123
 
3124
 
3125
 
3126
 
3127
                        if($page_num==4  ){
3128
                                $draw->destroy;
3129
                                $draw = get_path_route_widgets($self,$info);
3130
                                $h1 -> pack2($draw, TRUE, TRUE);
3131
 
3132
 
3133
                        }else{
3134
 
3135
                                $draw->destroy;
3136
                                $draw=custom_topology_diagram($self);
3137
                                $h1 -> pack2($draw, TRUE, TRUE);
3138
                        }
3139
                        my $saved_name=$self->object_get_attribute('save_as');
3140
                    $entry->set_text($saved_name)if(defined $saved_name);
3141
 
3142
                    $saved_name = $self->object_get_attribute('routing_name');
3143
                    $entry2->set_text($saved_name) if(defined $saved_name);
3144
 
3145
                        set_gui_status($self,"ideal",0);
3146
                        $main_table->show_all();
3147
 
3148
                        return TRUE;
3149
 
3150
                }
3151
 
3152
 
3153
                #refresh GUI
3154
 
3155
 
3156
 
3157
 
3158
                $main_table->show_all();
3159
                set_gui_status($self,"ideal",0);
3160
 
3161
                return TRUE;
3162
 
3163
        } );
3164
 
3165
 
3166
 
3167
        return $sc_win;
3168
 
3169
 
3170
 
3171
}

powered by: WebSVN 2.1.0

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