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] - Diff between revs 48 and 54

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 48 Rev 54
#!/usr/bin/perl
#!/usr/bin/perl
use strict;
use strict;
use warnings;
use warnings;
use constant::boolean;
use constant::boolean;
 
 
use Cwd 'abs_path';
use Cwd 'abs_path';
use base 'Class::Accessor::Fast';
use base 'Class::Accessor::Fast';
require "widget.pl";
require "widget.pl";
require "diagram.pl";
require "diagram.pl";
require "topology_verilog_gen.pl";
require "topology_verilog_gen.pl";
 
 
use String::Scanf; # imports sscanf()
use String::Scanf; # imports sscanf()
 
 
use FindBin;
use FindBin;
use lib $FindBin::Bin;
use lib $FindBin::Bin;
use tsort;
use tsort;
 
 
use File::Basename;
use File::Basename;
use Cwd 'abs_path';
use Cwd 'abs_path';
 
 
__PACKAGE__->mk_accessors(qw{
__PACKAGE__->mk_accessors(qw{
        window
        window
        sourceview
        sourceview
});
});
 
 
my $NAME = 'Network_maker';
my $NAME = 'Network_maker';
exit network_maker_main() unless caller;
exit network_maker_main() unless caller;
 
 
 
 
sub network_maker_main {
sub network_maker_main {
        my $app = __PACKAGE__->new();
        my $app = __PACKAGE__->new();
 
 
        my @parameters = (
        my @parameters = (
        {param_name=> "V ", value=>2},
        {param_name=> "V ", value=>2},
    {param_name=> "B ", value=>4},
    {param_name=> "B ", value=>4},
    {param_name=> "C ", value=>2},
    {param_name=> "C ", value=>2},
    {param_name=> "Fpay ", value=>32},
    {param_name=> "Fpay ", value=>32},
    {param_name=> "MUX_TYPE", value=>'"ONE_HOT"'},
    {param_name=> "MUX_TYPE", value=>'"ONE_HOT"'},
    {param_name=> "VC_REALLOCATION_TYPE ", value=>'"NONATOMIC"'},
    {param_name=> "VC_REALLOCATION_TYPE ", value=>'"NONATOMIC"'},
    {param_name=> "COMBINATION_TYPE", value=>'"COMB_NONSPEC"'},
    {param_name=> "COMBINATION_TYPE", value=>'"COMB_NONSPEC"'},
    {param_name=> "FIRST_ARBITER_EXT_P_EN ", value=>1},
    {param_name=> "FIRST_ARBITER_EXT_P_EN ", value=>1},
    {param_name=> "CONGESTION_INDEX ", value=>7},
    {param_name=> "CONGESTION_INDEX ", value=>7},
    {param_name=> "DEBUG_EN", value=>0},
    {param_name=> "DEBUG_EN", value=>0},
    {param_name=> "AVC_ATOMIC_EN", value=>0},
    {param_name=> "AVC_ATOMIC_EN", value=>0},
    {param_name=> "ADD_PIPREG_AFTER_CROSSBAR", value=>0},
    {param_name=> "ADD_PIPREG_AFTER_CROSSBAR", value=>0},
    {param_name=> "CVw", value=>"(C==0)? V : C * V"},
    {param_name=> "CVw", value=>"(C==0)? V : C * V"},
    {param_name=> "CLASS_SETTING ", value=>"{CVw{1\'b1}}"},
    {param_name=> "CLASS_SETTING ", value=>"{CVw{1\'b1}}"},
    {param_name=> "SSA_EN", value=>'"NO"'},
    {param_name=> "SSA_EN", value=>'"NO"'},
    {param_name=> "SWA_ARBITER_TYPE ", value=>'"RRA"'},
    {param_name=> "SWA_ARBITER_TYPE ", value=>'"RRA"'},
    {param_name=> "WEIGHTw ", value=>7},
    {param_name=> "WEIGHTw ", value=>7},
    {param_name=> "MIN_PCK_SIZE", value=>2},
    {param_name=> "MIN_PCK_SIZE", value=>2},
    {param_name=> "BYTE_EN", value=>0}
    {param_name=> "BYTE_EN", value=>0}
);
);
 
 
my @ports =(
my @ports =(
        {name=> "flit_in_all", type=>"input", width=>"PFw", connect=>"flit_out_all",  pwidth=>"Fw", pname=> "flit_in", pconnect=>"flit_out", endp=>"yes"},
        {name=> "flit_in_all", type=>"input", width=>"PFw", connect=>"flit_out_all",  pwidth=>"Fw", pname=> "flit_in", pconnect=>"flit_out", endp=>"yes"},
        {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"},
        {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"},
        {name=> "congestion_in_all", type=>"input", width=>"CONG_ALw", connect=>"congestion_out_all",  pwidth=>"CONGw", pname=> "congestion_in", pconnect=>"congestion_out",endp=>"no"},
        {name=> "congestion_in_all", type=>"input", width=>"CONG_ALw", connect=>"congestion_out_all",  pwidth=>"CONGw", pname=> "congestion_in", pconnect=>"congestion_out",endp=>"no"},
        {name=> "credit_out_all", type=>"output", width=>"PV", connect=>"credit_in_all",  pwidth=>"V" ,pname=> "credit_out", pconnect=>"credit_in",endp=>"yes"}
        {name=> "credit_out_all", type=>"output", width=>"PV", connect=>"credit_in_all",  pwidth=>"V" ,pname=> "credit_out", pconnect=>"credit_in",endp=>"yes"}
);
);
 
 
 
 
  $app->object_add_attribute ('Verilog','Router_param',\@parameters);
  $app->object_add_attribute ('Verilog','Router_param',\@parameters);
  $app->object_add_attribute ('Verilog','Router_ports',\@ports);
  $app->object_add_attribute ('Verilog','Router_ports',\@ports);
 
 
 
 
 
 
 
 
        my $table=$app->build_network_maker_gui();
        my $table=$app->build_network_maker_gui();
        return $table;
        return $table;
}
}
 
 
 
 
sub custom_topology_diagram {
sub custom_topology_diagram {
        my $self= shift;
        my $self= shift;
 
 
 
 
 
 
        my $table=def_table(20,20,FALSE);
        my $table=def_table(20,20,FALSE);
        my $scrolled_win = add_widget_to_scrolled_win();
        my $scrolled_win = add_widget_to_scrolled_win();
 
 
 
 
        my ($col,$row)=(0,0);
        my ($col,$row)=(0,0);
 
 
 
 
 
 
 
 
        my $plus = def_image_button('icons/plus.png',undef,TRUE);
        my $plus = def_image_button('icons/plus.png',undef,TRUE);
        my $minues = def_image_button('icons/minus.png',undef,TRUE);
        my $minues = def_image_button('icons/minus.png',undef,TRUE);
        my $save = def_image_button('icons/save.png',undef,TRUE);
        my $save = def_image_button('icons/save.png',undef,TRUE);
        my $dot_file = def_image_button('icons/add-notes.png',undef,TRUE);
        my $dot_file = def_image_button('icons/add-notes.png',undef,TRUE);
        set_tip($dot_file, "Show dot file.");
        set_tip($dot_file, "Show dot file.");
 
 
        my $scale=$self->object_get_attribute("tile_diagram","scale");
        my $scale=$self->object_get_attribute("tile_diagram","scale");
        $scale= 1 if (!defined $scale);
        $scale= 1 if (!defined $scale);
 
 
        my $state=$self->object_get_attribute("tile_diagram","auto_draw");
        my $state=$self->object_get_attribute("tile_diagram","auto_draw");
        if (!defined $state){
        if (!defined $state){
                $state='ON' ;
                $state='ON' ;
                $self->object_add_attribute("tile_diagram","auto_draw",$state);
                $self->object_add_attribute("tile_diagram","auto_draw",$state);
        }
        }
        my $auto= ($state eq 'ON')? def_colored_button('ON',17): def_colored_button('OFF',4);
        my $auto= ($state eq 'ON')? def_colored_button('ON',17): def_colored_button('OFF',4);
 
 
 
 
        my $gtype=$self->object_get_attribute("tile_diagram","gtype");
        my $gtype=$self->object_get_attribute("tile_diagram","gtype");
        if (!defined $gtype){
        if (!defined $gtype){
                $gtype='comp' ;
                $gtype='comp' ;
                $self->object_add_attribute("tile_diagram","gtype",$gtype);
                $self->object_add_attribute("tile_diagram","gtype",$gtype);
        }
        }
        my $graph_type= ($gtype eq 'comp')? def_colored_button('comp',17): def_colored_button('simple',4);
        my $graph_type= ($gtype eq 'comp')? def_colored_button('comp',17): def_colored_button('simple',4);
 
 
 
 
 
 
 
 
 
 
 
 
        $table->attach (gen_label_in_center  ("Auto Draw") ,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $row++;
        $table->attach (gen_label_in_center  ("Auto Draw") ,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $row++;
        $table->attach ($auto ,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $row++;
        $table->attach ($auto ,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $row++;
        $table->attach ($graph_type ,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $row++;
        $table->attach ($graph_type ,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $row++;
        $table->attach ($plus ,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $row++;
        $table->attach ($plus ,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $row++;
        $table->attach ($minues,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $row++;
        $table->attach ($minues,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $row++;
        $table->attach ($save,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $row++;
        $table->attach ($save,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $row++;
        $table->attach ($dot_file,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $row++;
        $table->attach ($dot_file,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $row++;
 
 
        $table->attach_defaults ($scrolled_win, 1, 20, 0, 20); #,'fill','shrink',2,2);
        $table->attach_defaults ($scrolled_win, 1, 20, 0, 20); #,'fill','shrink',2,2);
 
 
        ($col,$row)=(1,0);
        ($col,$row)=(1,0);
        while ($row<20){
        while ($row<20){
                my $tmp=gen_label_in_left('');
                my $tmp=gen_label_in_left('');
                $table->attach_defaults ($tmp, $col,  $col+1,$row,$row+1);$row++;
                $table->attach_defaults ($tmp, $col,  $col+1,$row,$row+1);$row++;
        }
        }
 
 
        $plus  -> signal_connect("clicked" => sub{
        $plus  -> signal_connect("clicked" => sub{
                $scale*=1.1 if ($scale <10);
                $scale*=1.1 if ($scale <10);
                $self->object_add_attribute("topology_diagram","scale", $scale );
                $self->object_add_attribute("topology_diagram","scale", $scale );
                show_custom_topology_diagram ($self,$scrolled_win,"topology_diagram");
                show_custom_topology_diagram ($self,$scrolled_win,"topology_diagram");
        });
        });
        $minues  -> signal_connect("clicked" => sub{
        $minues  -> signal_connect("clicked" => sub{
                $scale*=.9  if ($scale >0.1); ;
                $scale*=.9  if ($scale >0.1); ;
                $self->object_add_attribute("topology_diagram","scale", $scale );
                $self->object_add_attribute("topology_diagram","scale", $scale );
                show_custom_topology_diagram ($self,$scrolled_win,"topology_diagram");
                show_custom_topology_diagram ($self,$scrolled_win,"topology_diagram");
        });
        });
        $save-> signal_connect("clicked" => sub{
        $save-> signal_connect("clicked" => sub{
                        save_inline_diagram_as ($self);
                        save_inline_diagram_as ($self);
                });
                });
 
 
        $dot_file-> signal_connect("clicked" => sub{
        $dot_file-> signal_connect("clicked" => sub{
                        my $dotfile = generate_custom_topology_dot_file($self);
                        my $dotfile = generate_custom_topology_dot_file($self);
                        show_text_in_scrolled_win($self,$scrolled_win, $dotfile);
                        show_text_in_scrolled_win($self,$scrolled_win, $dotfile);
        });
        });
 
 
 
 
        $auto -> signal_connect("clicked" => sub{
        $auto -> signal_connect("clicked" => sub{
                        my $state=$self->object_get_attribute("tile_diagram","auto_draw");
                        my $state=$self->object_get_attribute("tile_diagram","auto_draw");
 
 
 
 
                        my $new = ($state eq "ON")? "OFF" : "ON";
                        my $new = ($state eq "ON")? "OFF" : "ON";
                        $self->object_add_attribute("tile_diagram","auto_draw",$new);
                        $self->object_add_attribute("tile_diagram","auto_draw",$new);
                        set_gui_status($self,"ref",1);
                        set_gui_status($self,"ref",1);
                });
                });
 
 
        $graph_type-> signal_connect("clicked" => sub{
        $graph_type-> signal_connect("clicked" => sub{
                        my $state=$self->object_get_attribute("tile_diagram","gtype");
                        my $state=$self->object_get_attribute("tile_diagram","gtype");
 
 
 
 
                        my $new = ($state eq "simple")? "comp" : "simple";
                        my $new = ($state eq "simple")? "comp" : "simple";
                        $self->object_add_attribute("tile_diagram","gtype",$new);
                        $self->object_add_attribute("tile_diagram","gtype",$new);
                        set_gui_status($self,"ref",1);
                        set_gui_status($self,"ref",1);
                });
                });
 
 
        if ($state eq 'ON'){
        if ($state eq 'ON'){
                show_custom_topology_diagram ($self,$scrolled_win,"topology_diagram");
                show_custom_topology_diagram ($self,$scrolled_win,"topology_diagram");
        }
        }
 
 
        return add_widget_to_scrolled_win ($table);
        return add_widget_to_scrolled_win ($table);
 
 
}
}
 
 
 
 
 
 
 
 
 
 
sub gen_right_paned {
sub gen_right_paned {
        my ($self,$info) =@_;
        my ($self,$info) =@_;
        my $page_num=$self->object_get_attribute ("process_notebook","currentpage");
        my $page_num=$self->object_get_attribute ("process_notebook","currentpage");
 
 
        return route_info_window($self,$info) if($page_num==3);
        return route_info_window($self,$info) if($page_num==3);
        return custom_topology_diagram ($self,$info);
        return custom_topology_diagram ($self,$info);
 
 
}
}
 
 
 
 
 
 
 
 
sub endp_node_dot_comp {
sub endp_node_dot_comp {
        my ($T,$instance)=@_;
        my ($T,$instance)=@_;
 
 
 
 
        return
        return
        "
        "
        $T\[
        $T\[
        label = \"$instance\"
        label = \"$instance\"
    shape=house
    shape=house
    margin=0
    margin=0
        color=orange
        color=orange
        style=filled
        style=filled
        fillcolor=orange
        fillcolor=orange
];
];
";
";
}
}
 
 
sub router_node_dot_comp{
sub router_node_dot_comp{
        my ($Pnum,$R,$instance)=@_;
        my ($Pnum,$R,$instance)=@_;
        $Pnum=1 if(!defined $Pnum);
        $Pnum=1 if(!defined $Pnum);
        my $label =
        my $label =
                ($Pnum==2)? "                        \{<p1>1|$instance|<p0>0\}":
                ($Pnum==2)? "                        \{<p1>1|$instance|<p0>0\}":
                ($Pnum==3)? "\{     |<p2>2|     \} | \{<p1>1|$instance|<p0>0\} ":
                ($Pnum==3)? "\{     |<p2>2|     \} | \{<p1>1|$instance|<p0>0\} ":
                ($Pnum==4)? "\{     |<p3>3|     \} | \{<p2>2|$instance|<p0>0\} | \{  <p1>1\}":
                ($Pnum==4)? "\{     |<p3>3|     \} | \{<p2>2|$instance|<p0>0\} | \{  <p1>1\}":
                ($Pnum==5)? "\{     |<p3>3|     \} | \{<p2>2|$instance|<p4>4\} | \{ |<p1>1|<p0>0\}":
                ($Pnum==5)? "\{     |<p3>3|     \} | \{<p2>2|$instance|<p4>4\} | \{ |<p1>1|<p0>0\}":
                ($Pnum==6)? "\{<p3>3|<p4>4|     \} | \{<p2>2|$instance|<p5>5\} | \{ |<p1>1|<p0>0\}":
                ($Pnum==6)? "\{<p3>3|<p4>4|     \} | \{<p2>2|$instance|<p5>5\} | \{ |<p1>1|<p0>0\}":
                ($Pnum==7)? "\{<p4>4|<p5>5|     \} | \{<p3>3|$instance|<p6>6\} | \{<p2>2 |<p1>1|<p0>0\}":
                ($Pnum==7)? "\{<p4>4|<p5>5|     \} | \{<p3>3|$instance|<p6>6\} | \{<p2>2 |<p1>1|<p0>0\}":
                ($Pnum==8)? "\{<p4>4|<p5>5|<p6>6\} | \{<p3>3|$instance|<p7>7\} | \{<p2>2 |<p1>1|<p0>0\}":
                ($Pnum==8)? "\{<p4>4|<p5>5|<p6>6\} | \{<p3>3|$instance|<p7>7\} | \{<p2>2 |<p1>1|<p0>0\}":
                ($Pnum==9)? "\{<p5>5|<p6>6|<p7>7\} | \{<p4>4|$instance|<p8>8\} | \{<p3>3 |<p2>2|<p1>1|<p0>0\}":
                ($Pnum==9)? "\{<p5>5|<p6>6|<p7>7\} | \{<p4>4|$instance|<p8>8\} | \{<p3>3 |<p2>2|<p1>1|<p0>0\}":
                ($Pnum==10)? "\{<p5>5|<p6>6|<p7>7|<p8>8\} | \{<p4>4|$instance|<p9>9\} | \{<p3>3 |<p2>2|<p1>1|<p0>0\}":
                ($Pnum==10)? "\{<p5>5|<p6>6|<p7>7|<p8>8\} | \{<p4>4|$instance|<p9>9\} | \{<p3>3 |<p2>2|<p1>1|<p0>0\}":
                ($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\}":
                ($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\}":
                ($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\}":
                ($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\}":
                  "\{ |<p2>2| \} | \{<p3>3|$instance|<p1>1\} | \{ |<p4>4|<p0>0\}";
                  "\{ |<p2>2| \} | \{<p3>3|$instance|<p1>1\} | \{ |<p4>4|<p0>0\}";
 
 
 
 
        return
        return
        "$R\[
        "$R\[
        label = \"$label\"
        label = \"$label\"
    shape=record
    shape=record
        color=blue
        color=blue
        style=filled
        style=filled
        fillcolor=blue
        fillcolor=blue
];
];
";
";
 
 
}
}
 
 
sub router_node_dot_sim{
sub router_node_dot_sim{
        my ($Pnum,$R,$instance)=@_;
        my ($Pnum,$R,$instance)=@_;
        $Pnum=1 if(!defined $Pnum);
        $Pnum=1 if(!defined $Pnum);
        my $label =      "$instance";
        my $label =      "$instance";
 
 
 
 
        return
        return
        "$R\[
        "$R\[
        label = \"$label\"
        label = \"$label\"
    shape=circle
    shape=circle
        color=blue
        color=blue
        style=filled
        style=filled
        fillcolor=blue
        fillcolor=blue
];
];
";
";
 
 
}
}
 
 
 
 
sub endp_node_dot_sim {
sub endp_node_dot_sim {
        my ($T,$instance)=@_;
        my ($T,$instance)=@_;
 
 
 
 
        return
        return
        "
        "
        $T\[
        $T\[
        label = \"$instance\"
        label = \"$instance\"
    shape=circle
    shape=circle
    margin=0
    margin=0
        color=orange
        color=orange
        style=filled
        style=filled
        fillcolor=orange
        fillcolor=orange
];
];
";
";
}
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
sub generate_custom_topology_dot_file{
sub generate_custom_topology_dot_file{
        my $self=shift;
        my $self=shift;
 
 
        my $gtype=$self->object_get_attribute("tile_diagram","gtype");
        my $gtype=$self->object_get_attribute("tile_diagram","gtype");
        $gtype = "simple" if (!defined $gtype);
        $gtype = "simple" if (!defined $gtype);
 
 
        my $dotfile=
        my $dotfile=
"digraph G {
"digraph G {
        graph [layout = twopi, rankdir = RL , splines = true, overlap = false];
        graph [layout = twopi, rankdir = RL , splines = true, overlap = false];
        node[shape=record];
        node[shape=record];
        ";
        ";
        #Add endpoints
        #Add endpoints
        my @nodes=get_list_of_all_endpoints($self);
        my @nodes=get_list_of_all_endpoints($self);
        my $i=0;
        my $i=0;
        foreach my $p (@nodes){
        foreach my $p (@nodes){
                my $instance= $self->object_get_attribute("$p","NAME");
                my $instance= $self->object_get_attribute("$p","NAME");
                $instance = "T$i" if(!defined $instance);
                $instance = "T$i" if(!defined $instance);
                $dotfile.= ($gtype eq 'simple')? endp_node_dot_sim($p,$instance) : endp_node_dot_comp($p,$instance);
                $dotfile.= ($gtype eq 'simple')? endp_node_dot_sim($p,$instance) : endp_node_dot_comp($p,$instance);
                $i++;
                $i++;
        }
        }
 
 
 
 
 
 
        #add routers
        #add routers
        @nodes=get_list_of_all_routers($self);
        @nodes=get_list_of_all_routers($self);
        $i=0;
        $i=0;
        foreach my $p (@nodes){
        foreach my $p (@nodes){
                my $instance= $self->object_get_attribute("$p","NAME");
                my $instance= $self->object_get_attribute("$p","NAME");
                $instance = "R$i" if(!defined $instance);
                $instance = "R$i" if(!defined $instance);
                my $pnum=$self->object_get_attribute("$p",'PNUM');
                my $pnum=$self->object_get_attribute("$p",'PNUM');
                $dotfile.=($gtype eq 'simple')? router_node_dot_sim($pnum,$p,$instance): router_node_dot_comp($pnum,$p,$instance);
                $dotfile.=($gtype eq 'simple')? router_node_dot_sim($pnum,$p,$instance): router_node_dot_comp($pnum,$p,$instance);
                $i++;
                $i++;
        }
        }
 
 
 
 
        #add connections
        #add connections
        my @all_nodes=get_list_of_all_nodes($self);
        my @all_nodes=get_list_of_all_nodes($self);
        my @draw;
        my @draw;
        foreach my $p (@all_nodes){
        foreach my $p (@all_nodes){
                my $pnum=$self->object_get_attribute("$p",'PNUM');
                my $pnum=$self->object_get_attribute("$p",'PNUM');
           #    my $inst=$self->object_get_attribute("$p",'NAME');
           #    my $inst=$self->object_get_attribute("$p",'NAME');
                my $type = $self->object_get_attribute("$p",'TYPE');
                my $type = $self->object_get_attribute("$p",'TYPE');
                $pnum = 0 if(!defined $pnum);
                $pnum = 0 if(!defined $pnum);
                for (my $i=0;$i<$pnum; $i++){
                for (my $i=0;$i<$pnum; $i++){
                        my $src_port = "Port[${i}]";
                        my $src_port = "Port[${i}]";
                        my $connect = $self->{$p}{'PCONNECT'}{$src_port};
                        my $connect = $self->{$p}{'PCONNECT'}{$src_port};
 
 
                        if (defined $connect) {
                        if (defined $connect) {
                                my $pos = get_scolar_pos($connect,@draw);
                                my $pos = get_scolar_pos($connect,@draw);
                                if ( !defined $pos ){
                                if ( !defined $pos ){
 
 
 
 
                                my ($node,$pnode)=split(/\s*,\s*/,$connect);
                                my ($node,$pnode)=split(/\s*,\s*/,$connect);
                                # check if $node exist
                                # check if $node exist
                                if ( defined get_scolar_pos($node, @all_nodes)){
                                if ( defined get_scolar_pos($node, @all_nodes)){
 
 
                                    my ($cp)= sscanf("Port[%u]","$pnode");
                                    my ($cp)= sscanf("Port[%u]","$pnode");
                                    # my $cinst=$self->object_get_attribute("$node",'NAME');
                                    # my $cinst=$self->object_get_attribute("$node",'NAME');
                                    my $ctype = $self->object_get_attribute("$node",'TYPE');
                                    my $ctype = $self->object_get_attribute("$node",'TYPE');
 
 
 
 
 
 
                                        my ($t2, $t1);
                                        my ($t2, $t1);
 
 
                                        if ($gtype eq 'simple'){
                                        if ($gtype eq 'simple'){
                                                $t2 =  "\"$p\"";
                                                $t2 =  "\"$p\"";
                                                $t1 =  "\"$node\"";
                                                $t1 =  "\"$node\"";
                                        } else {
                                        } else {
                                                $t2 = ($type eq "ENDP" )? "\"$p\"" : "\"$p\" : \"p$i\"";
                                                $t2 = ($type eq "ENDP" )? "\"$p\"" : "\"$p\" : \"p$i\"";
                                            $t1 = ($ctype eq "ENDP" )? "\"$node\"" : "\"$node\" : \"p$cp\"";
                                            $t1 = ($ctype eq "ENDP" )? "\"$node\"" : "\"$node\" : \"p$cp\"";
 
 
                                        }
                                        }
                                        my $t= "$t1 -> $t2 [ dir=none];\n";
                                        my $t= "$t1 -> $t2 [ dir=none];\n";
                                        $dotfile=$dotfile."$t";
                                        $dotfile=$dotfile."$t";
                                }
                                }
                                push(@draw,$connect);
                                push(@draw,$connect);
                                push(@draw,"$p,$src_port");
                                push(@draw,"$p,$src_port");
                                #print "@draw\n";
                                #print "@draw\n";
                        }
                        }
 
 
 
 
                }}
                }}
        }
        }
        $dotfile=$dotfile."\n}\n";
        $dotfile=$dotfile."\n}\n";
        #print  $dotfile;
        #print  $dotfile;
        return $dotfile;
        return $dotfile;
}
}
 
 
sub get_connection_port_num_between_two_nodes{
sub get_connection_port_num_between_two_nodes{
        my ($self,$n1,$n2)=@_;
        my ($self,$n1,$n2)=@_;
        my $PNUM=$self->object_get_attribute($n1,"PNUM");
        my $PNUM=$self->object_get_attribute($n1,"PNUM");
 
 
        for (my $p1=0; $p1<$PNUM; $p1++){
        for (my $p1=0; $p1<$PNUM; $p1++){
                my $connect=$self->{$n1}{"PCONNECT"}{"Port[$p1]"};
                my $connect=$self->{$n1}{"PCONNECT"}{"Port[$p1]"};
                next if(!defined $connect);
                next if(!defined $connect);
                my ($node,$pnode)=split(/\s*,\s*/,$connect);
                my ($node,$pnode)=split(/\s*,\s*/,$connect);
                my ($p2)= sscanf("Port[%u]","$pnode");
                my ($p2)= sscanf("Port[%u]","$pnode");
                return ($p1,$p2) if($node eq $n2 );
                return ($p1,$p2) if($node eq $n2 );
        }
        }
        return undef;
        return undef;
}
}
 
 
 
 
sub show_custom_topology_diagram {
sub show_custom_topology_diagram {
        my ($self,$scrolled_win, $name)=@_;
        my ($self,$scrolled_win, $name)=@_;
 
 
        my $state=$self->object_get_attribute("tile_diagram","auto_draw");
        my $state=$self->object_get_attribute("tile_diagram","auto_draw");
        if( $state eq "ON") {
        if( $state eq "ON") {
                my $dotfile = generate_custom_topology_dot_file($self);
                my $dotfile = generate_custom_topology_dot_file($self);
                generate_and_show_graph_using_graphviz($self,$scrolled_win,$dotfile,$name);
                generate_and_show_graph_using_graphviz($self,$scrolled_win,$dotfile,$name);
        }
        }
        else {
        else {
                my @list = $scrolled_win->get_children();
                my @list = $scrolled_win->get_children();
                foreach my $l (@list){
                foreach my $l (@list){
                        $scrolled_win->remove($l);
                        $scrolled_win->remove($l);
                }
                }
        }
        }
 
 
        return;
        return;
}
}
 
 
 
 
 
 
 
 
 
 
sub take_node_num_page{
sub take_node_num_page{
        my ($self)=@_;
        my ($self)=@_;
        my $table= def_table(2,10,FALSE);
        my $table= def_table(2,10,FALSE);
        my $row=0;
        my $row=0;
        my $col=4;
        my $col=4;
        $table->attach (def_label('Network Element'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col+=2;
        $table->attach (def_label('Network Element'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col+=2;
        $table->attach (def_label('Number'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);
        $table->attach (def_label('Number'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);
        $row++;$col=0;
        $row++;$col=0;
 
 
        $table->attach (def_icon('icons/e.png'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
        $table->attach (def_icon('icons/e.png'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
        ($row,$col)=add_param_widget ($self,"# Endpoints","NUM", 0,'Spin-button','0,1024,1',undef, $table,$row,$col,1,'ENDP',10,'redraw');$col=0;
        ($row,$col)=add_param_widget ($self,"# Endpoints","NUM", 0,'Spin-button','0,1024,1',undef, $table,$row,$col,1,'ENDP',10,'redraw');$col=0;
        for ( my $i=2;$i<=12; $i++){
        for ( my $i=2;$i<=12; $i++){
                $table->attach (def_icon('icons/r.png'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
                $table->attach (def_icon('icons/r.png'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
                ($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;
                ($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;
        }
        }
        return $table;
        return $table;
}
}
 
 
 
 
 
 
sub take_instance_page{
sub take_instance_page{
        my ($self)=@_;
        my ($self)=@_;
        my $table= def_table(2,10,FALSE);
        my $table= def_table(2,10,FALSE);
 
 
        initial_node_info($self);
        initial_node_info($self);
 
 
        my $row=0;
        my $row=0;
        my $col=0;
        my $col=0;
 
 
 
 
        $table->attach (def_label(' Network Element '),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col+=2;
        $table->attach (def_label(' Network Element '),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col+=2;
        $table->attach (def_label(' Instance name '),$col,$col+1,$row,$row+1,'fill','shrink',2,2);
        $table->attach (def_label(' Instance name '),$col,$col+1,$row,$row+1,'fill','shrink',2,2);
        $row++;$col=0;
        $row++;$col=0;
 
 
 
 
        my $EN= $self->object_get_attribute('ENDP','NUM');
        my $EN= $self->object_get_attribute('ENDP','NUM');
        $EN = 0 if(!defined $EN);
        $EN = 0 if(!defined $EN);
        for (my $i=0;$i<$EN; $i++){
        for (my $i=0;$i<$EN; $i++){
 
 
                 my $d=get_default_instance_name($self,"ENDP_$i");
                 my $d=get_default_instance_name($self,"ENDP_$i");
                ($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;
                ($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;
 
 
        }
        }
 
 
        #routers
        #routers
        my $Rnum=0;
        my $Rnum=0;
        for ( my $i=2;$i<=12; $i++){
        for ( my $i=2;$i<=12; $i++){
                my $n= $self->object_get_attribute("ROUTER${i}","NUM");
                my $n= $self->object_get_attribute("ROUTER${i}","NUM");
                $n=0 if(!defined $n);
                $n=0 if(!defined $n);
                 for ( my $j=0;$j<$n; $j++){
                 for ( my $j=0;$j<$n; $j++){
                        my $d=get_default_instance_name($self,"ROUTER${i}_$j");
                        my $d=get_default_instance_name($self,"ROUTER${i}_$j");
                        ($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;
                        ($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;
 
 
                         $Rnum++;
                         $Rnum++;
                 }
                 }
        }
        }
        return $table;
        return $table;
 
 
}
}
 
 
sub initial_node_info {
sub initial_node_info {
        my ($self)=@_;
        my ($self)=@_;
 
 
        my $EN= $self->object_get_attribute('ENDP','NUM');
        my $EN= $self->object_get_attribute('ENDP','NUM');
        $EN = 0 if(!defined $EN);
        $EN = 0 if(!defined $EN);
        for (my $i=0;$i<$EN; $i++){
        for (my $i=0;$i<$EN; $i++){
                 $self->object_add_attribute("ENDP_$i",'PNUM',1);
                 $self->object_add_attribute("ENDP_$i",'PNUM',1);
                 $self->object_add_attribute("ENDP_$i",'TYPE',"ENDP");
                 $self->object_add_attribute("ENDP_$i",'TYPE',"ENDP");
                 my $inst=$self->object_get_attribute("ENDP_$i",'NAME');
                 my $inst=$self->object_get_attribute("ENDP_$i",'NAME');
                 if(!defined $inst){
                 if(!defined $inst){
                        $inst=get_default_instance_name ($self,"ENDP_$i");
                        $inst=get_default_instance_name ($self,"ENDP_$i");
                        $self->object_add_attribute("ENDP_$i",'NAME',$inst);
                        $self->object_add_attribute("ENDP_$i",'NAME',$inst);
                 }
                 }
        }
        }
 
 
        #routers
        #routers
        my $Rnum=0;
        my $Rnum=0;
        for ( my $i=2;$i<=12; $i++){
        for ( my $i=2;$i<=12; $i++){
                my $n= $self->object_get_attribute("ROUTER${i}","NUM");
                my $n= $self->object_get_attribute("ROUTER${i}","NUM");
                $n=0 if(!defined $n);
                $n=0 if(!defined $n);
                 for ( my $j=0;$j<$n; $j++){
                 for ( my $j=0;$j<$n; $j++){
                         $self->object_add_attribute("ROUTER${i}_$j",'PNUM',${i});
                         $self->object_add_attribute("ROUTER${i}_$j",'PNUM',${i});
                         $self->object_add_attribute("ROUTER${i}_$j",'RNUM',$Rnum);
                         $self->object_add_attribute("ROUTER${i}_$j",'RNUM',$Rnum);
                         $self->object_add_attribute("ROUTER${i}_$j",'TYPE',"ROUTER");
                         $self->object_add_attribute("ROUTER${i}_$j",'TYPE',"ROUTER");
                         my $inst=$self->object_get_attribute("ROUTER${i}_$j",'NAME');
                         my $inst=$self->object_get_attribute("ROUTER${i}_$j",'NAME');
                         if(!defined $inst){
                         if(!defined $inst){
                                $inst=get_default_instance_name ($self,"ROUTER${i}_$j");
                                $inst=get_default_instance_name ($self,"ROUTER${i}_$j");
                                $self->object_add_attribute("ROUTER${i}_$j",'NAME',$inst);
                                $self->object_add_attribute("ROUTER${i}_$j",'NAME',$inst);
                         }
                         }
                         $Rnum++;
                         $Rnum++;
                 }
                 }
        }
        }
 
 
}
}
 
 
 
 
 
 
 
 
sub get_default_instance_name {
sub get_default_instance_name {
        my ($self,$name)=@_;
        my ($self,$name)=@_;
        my $type = $self->object_get_attribute($name,'TYPE');
        my $type = $self->object_get_attribute($name,'TYPE');
        my @nodes =($type eq 'ENDP')? get_list_of_all_endpoints($self):get_list_of_all_routers($self);
        my @nodes =($type eq 'ENDP')? get_list_of_all_endpoints($self):get_list_of_all_routers($self);
 
 
        my @R=("--");
        my @R=("--");
        foreach my $p (@nodes){
        foreach my $p (@nodes){
                my $n= $self->object_get_attribute("$p","NAME");
                my $n= $self->object_get_attribute("$p","NAME");
                push( @R, $n) if(defined $n);
                push( @R, $n) if(defined $n);
        }
        }
 
 
        my $i=0;
        my $i=0;
        my $inst =      ($type eq 'ENDP')? "T$i": "R$i";
        my $inst =      ($type eq 'ENDP')? "T$i": "R$i";
        my $pos= get_scolar_pos($inst,@R);
        my $pos= get_scolar_pos($inst,@R);
        while (defined $pos){
        while (defined $pos){
                $i++;
                $i++;
                $inst =         ($type eq 'ENDP')? "T$i": "R$i";
                $inst =         ($type eq 'ENDP')? "T$i": "R$i";
                $pos= get_scolar_pos($inst,@R);
                $pos= get_scolar_pos($inst,@R);
        }
        }
 
 
 
 
        return  $inst;
        return  $inst;
}
}
 
 
 
 
 
 
 
 
sub get_list_of_all_routers {
sub get_list_of_all_routers {
        my ($self)=@_;
        my ($self)=@_;
        my @R;
        my @R;
        for ( my $i=2;$i<=12; $i++){
        for ( my $i=2;$i<=12; $i++){
                 my $n= $self->object_get_attribute("ROUTER${i}","NUM");
                 my $n= $self->object_get_attribute("ROUTER${i}","NUM");
                 $n=0 if(!defined $n);
                 $n=0 if(!defined $n);
                 for ( my $j=0;$j<$n; $j++){
                 for ( my $j=0;$j<$n; $j++){
                        push( @R, "ROUTER${i}_$j");
                        push( @R, "ROUTER${i}_$j");
                 }
                 }
        }
        }
        return @R;
        return @R;
}
}
 
 
sub get_list_of_all_endpoints {
sub get_list_of_all_endpoints {
        my ($self)=@_;
        my ($self)=@_;
        my @E;
        my @E;
        my $EN= $self->object_get_attribute('ENDP','NUM');
        my $EN= $self->object_get_attribute('ENDP','NUM');
        $EN = 0 if(!defined $EN);
        $EN = 0 if(!defined $EN);
        for (my $i=0;$i<$EN; $i++){
        for (my $i=0;$i<$EN; $i++){
                push( @E, "ENDP_$i");
                push( @E, "ENDP_$i");
        }
        }
        return @E;
        return @E;
}
}
 
 
sub get_list_of_all_nodes {
sub get_list_of_all_nodes {
        my ($self)=@_;
        my ($self)=@_;
        my @R=get_list_of_all_routers($self);
        my @R=get_list_of_all_routers($self);
    my @E=get_list_of_all_endpoints($self);
    my @E=get_list_of_all_endpoints($self);
    my @all_nodes= (@E,@R);
    my @all_nodes= (@E,@R);
        return @all_nodes;
        return @all_nodes;
}
}
 
 
sub remove_connected_port{
sub remove_connected_port{
        my ($self,$node,$port,$info)=@_;
        my ($self,$node,$port,$info)=@_;
        my @all_nodes=get_list_of_all_nodes($self);
        my @all_nodes=get_list_of_all_nodes($self);
        foreach my $p (@all_nodes){
        foreach my $p (@all_nodes){
                my $pnum=$self->object_get_attribute("$p",'PNUM');
                my $pnum=$self->object_get_attribute("$p",'PNUM');
                my $inst=$self->object_get_attribute("$p",'NAME');
                my $inst=$self->object_get_attribute("$p",'NAME');
 
 
                $pnum = 0 if(!defined $pnum);
                $pnum = 0 if(!defined $pnum);
                for (my $i=0;$i<$pnum; $i++){
                for (my $i=0;$i<$pnum; $i++){
                        my $src_port = "Port[${i}]";
                        my $src_port = "Port[${i}]";
                        if(defined $self->{$p}{'PCONNECT'}{$src_port}){ if ($self->{$p}{'PCONNECT'}{$src_port} eq "$node,$port"){
                        if(defined $self->{$p}{'PCONNECT'}{$src_port}){ if ($self->{$p}{'PCONNECT'}{$src_port} eq "$node,$port"){
                                delete $self->{$p}{'PCONNECT'}{$src_port};
                                delete $self->{$p}{'PCONNECT'}{$src_port};
                                my $con_inst=$self->object_get_attribute("$node",'NAME');
                                my $con_inst=$self->object_get_attribute("$node",'NAME');
                                add_info($info,"** $inst  $src_port is disconnected from $con_inst $port \n") if (defined $info);
                                add_info($info,"** $inst  $src_port is disconnected from $con_inst $port \n") if (defined $info);
 
 
                        }}
                        }}
                }
                }
        }
        }
}
}
 
 
 
 
sub get_instance_to_node_name {
sub get_instance_to_node_name {
        my $self=shift;
        my $self=shift;
        my @all_nodes=get_list_of_all_nodes($self);
        my @all_nodes=get_list_of_all_nodes($self);
    my %par;
    my %par;
    foreach my $p (@all_nodes){
    foreach my $p (@all_nodes){
                my $inst=$self->object_get_attribute("$p",'NAME');
                my $inst=$self->object_get_attribute("$p",'NAME');
                $par{$inst}= $p;
                $par{$inst}= $p;
    }
    }
    return %par;
    return %par;
}
}
 
 
 
 
##############
##############
#       create_tree 
#       create_tree 
##############
##############
sub create_tree_view {
sub create_tree_view {
   my ($self,$source,$src_port,$info)=@_;
   my ($self,$source,$src_port,$info)=@_;
   my $window = def_popwin_size(30,85,"Select Connection Element and Port",'percent');
   my $window = def_popwin_size(30,85,"Select Connection Element and Port",'percent');
 
 
 
 
   my ($model,$tree_view,$column) =create_tree_model_network_maker();
   my ($model,$tree_view,$column) =create_tree_model_network_maker();
 
 
   my @all_nodes=get_list_of_all_nodes($self);
   my @all_nodes=get_list_of_all_nodes($self);
 
 
   unshift(@all_nodes,"-");
   unshift(@all_nodes,"-");
   my %par;
   my %par;
 
 
   foreach my $p (@all_nodes){
   foreach my $p (@all_nodes){
            my @childs;
            my @childs;
                my $pnum=$self->object_get_attribute("$p",'PNUM');
                my $pnum=$self->object_get_attribute("$p",'PNUM');
                my $inst=$self->object_get_attribute("$p",'NAME');
                my $inst=$self->object_get_attribute("$p",'NAME');
 
 
                $pnum = 0 if(!defined $pnum);
                $pnum = 0 if(!defined $pnum);
                $inst = "-" if(!defined $inst);
                $inst = "-" if(!defined $inst);
 
 
                $par{$inst}= $p;
                $par{$inst}= $p;
                for (my $i=0;$i<$pnum; $i++){
                for (my $i=0;$i<$pnum; $i++){
                        #donot add the source port itself to connection list
                        #donot add the source port itself to connection list
                        if(($source ne $p)|| ($src_port ne "Port[${i}]")){
                        if(($source ne $p)|| ($src_port ne "Port[${i}]")){
                                push(@childs, "Port[${i}]");
                                push(@childs, "Port[${i}]");
                        }
                        }
                }
                }
                my $iter = $model->append (undef);
                my $iter = $model->append (undef);
            $model->set ($iter, 0, $inst, 1, $inst || '', 2, 0 || '', 3,   FALSE);
            $model->set ($iter, 0, $inst, 1, $inst || '', 2, 0 || '', 3,   FALSE);
                foreach my $v ( @childs){
                foreach my $v ( @childs){
                         my $child_iter = $model->append ($iter);
                         my $child_iter = $model->append ($iter);
                         $model->set ($child_iter, 0, $v, 1, $inst|| '', 2, $v || '', 3,   FALSE);
                         $model->set ($child_iter, 0, $v, 1, $inst|| '', 2, $v || '', 3,   FALSE);
                }
                }
   }
   }
 
 
 
 
   $tree_view->append_column ($column);
   $tree_view->append_column ($column);
 
 
 
 
 
 
   $tree_view->signal_connect (row_activated => sub{
   $tree_view->signal_connect (row_activated => sub{
 
 
                my ($tree_view, $path, $column) = @_;
                my ($tree_view, $path, $column) = @_;
                my $model = $tree_view->get_model;
                my $model = $tree_view->get_model;
                my $iter = $model->get_iter ($path);
                my $iter = $model->get_iter ($path);
                my $parent = $model->get ($iter, 1);
                my $parent = $model->get ($iter, 1);
                my $child = $model->get ($iter, 2);
                my $child = $model->get ($iter, 2);
 
 
                if ($child){
                if ($child){
                                my $node=$par{$parent};
                                my $node=$par{$parent};
                                connect_nodes ($self,$node,$child,$source,$src_port,$info);
                                connect_nodes ($self,$node,$child,$source,$src_port,$info);
 
 
 
 
 
 
 
 
                                set_gui_status($self,'ref',1);
                                set_gui_status($self,'ref',1);
                                $window->destroy;
                                $window->destroy;
 
 
                                #add parent child
                                #add parent child
                        }
                        }
                elsif($parent ){
                elsif($parent ){
 
 
                        my $node=$par{$parent};
                        my $node=$par{$parent};
                        if ($node eq "-"){
                        if ($node eq "-"){
                                remove_connected_port($self,$source,$src_port);
                                remove_connected_port($self,$source,$src_port);
                                delete $self->{$source}{'PCONNECT'}{$src_port};
                                delete $self->{$source}{'PCONNECT'}{$src_port};
                        }
                        }
 
 
 
 
 
 
                        set_gui_status($self,'ref',1);
                        set_gui_status($self,'ref',1);
                        $window->destroy;
                        $window->destroy;
 
 
 
 
                }
                }
 
 
 
 
        #add parent child
        #add parent child
 
 
        });
        });
 
 
  #$tree_view->expand_all;
  #$tree_view->expand_all;
 
 
  my $scrolled_window = add_widget_to_scrolled_win($tree_view);
  my $scrolled_window = add_widget_to_scrolled_win($tree_view);
 
 
  my $hbox = def_hbox (FALSE, 0);
  my $hbox = def_hbox (FALSE, 0);
  $hbox->pack_start ( $scrolled_window, TRUE, TRUE, 0);
  $hbox->pack_start ( $scrolled_window, TRUE, TRUE, 0);
  $window ->add($hbox);
  $window ->add($hbox);
  $window->show_all;
  $window->show_all;
}
}
 
 
sub connect_nodes {
sub connect_nodes {
        my ($self,$node1,$src_port1,$node2,$src_port2,$info)=@_;
        my ($self,$node1,$src_port1,$node2,$src_port2,$info)=@_;
 
 
 
 
 
 
        #add_colored_info($info,"$node1,$src_port1,$node2,$src_port2;\n","red") if (defined $info);     
        #add_colored_info($info,"$node1,$src_port1,$node2,$src_port2;\n","red") if (defined $info);     
 
 
        #check if the selected port has been connected to another port before and remove the connection
        #check if the selected port has been connected to another port before and remove the connection
        remove_connected_port($self,$node1,$src_port1,$info);
        remove_connected_port($self,$node1,$src_port1,$info);
        remove_connected_port($self,$node2,$src_port2,$info);
        remove_connected_port($self,$node2,$src_port2,$info);
 
 
        $self->{$node1}{'PCONNECT'}{$src_port1}="$node2,$src_port2";
        $self->{$node1}{'PCONNECT'}{$src_port1}="$node2,$src_port2";
        $self->{$node2}{'PCONNECT'}{$src_port2}="$node1,$src_port1";
        $self->{$node2}{'PCONNECT'}{$src_port2}="$node1,$src_port1";
 
 
}
}
 
 
sub remove_all_connection {
sub remove_all_connection {
        my ($self)=@_;
        my ($self)=@_;
        my @all_nodes=get_list_of_all_nodes($self);
        my @all_nodes=get_list_of_all_nodes($self);
        foreach  my $node  (@all_nodes ){
        foreach  my $node  (@all_nodes ){
                $self->{$node}{'PCONNECT'}=undef;
                $self->{$node}{'PCONNECT'}=undef;
        }
        }
        set_gui_status($self,"ref",1);
        set_gui_status($self,"ref",1);
}
}
 
 
sub list_node_all_port{
sub list_node_all_port{
        my ($self,$node)=@_;
        my ($self,$node)=@_;
        my @l;
        my @l;
        my $pnum =  $self->object_get_attribute($node,'PNUM');
        my $pnum =  $self->object_get_attribute($node,'PNUM');
        for (my $i=0;$i<$pnum; $i++){
        for (my $i=0;$i<$pnum; $i++){
                push(@l,"Port[${i}]");
                push(@l,"Port[${i}]");
        }
        }
        return @l;
        return @l;
}
}
 
 
 
 
 
 
sub list_node_connected_port {
sub list_node_connected_port {
        my ($self,$node)=@_;
        my ($self,$node)=@_;
        my $r = $self->{$node}{'PCONNECT'};
        my $r = $self->{$node}{'PCONNECT'};
        my %c =(defined $r)? %{$r} : undef;
        my %c =(defined $r)? %{$r} : undef;
        return sort keys %c;
        return sort keys %c;
}
}
 
 
sub list_node_unconnected_port {
sub list_node_unconnected_port {
        my ($self,$node)=@_;
        my ($self,$node)=@_;
        my @p = list_node_all_port($self,$node);
        my @p = list_node_all_port($self,$node);
        my @cp = list_node_connected_port ($self,$node);
        my @cp = list_node_connected_port ($self,$node);
        #@p - @cp;
        #@p - @cp;
    my @np =get_diff_array(\@p,\@cp);
    my @np =get_diff_array(\@p,\@cp);
        return @np;
        return @np;
}
}
 
 
 
 
sub connection_page{
sub connection_page{
        my ($self,$info)=@_;
        my ($self,$info)=@_;
        my $table= def_table(2,10,FALSE);
        my $table= def_table(2,10,FALSE);
        my $row=0;
        my $row=0;
        my $col=0;
        my $col=0;
 
 
        initial_node_info($self);
        initial_node_info($self);
 
 
 
 
 
 
        my $eq = def_table(1,8,TRUE);
        my $eq = def_table(1,8,TRUE);
 
 
        my $label = gen_label_help("Eg: R[i]P[0]->T[i]P[0];i[0,10,1]","Equation:");
        my $label = gen_label_help("Eg: R[i]P[0]->T[i]P[0];i[0,10,1]","Equation:");
        my $entry = gen_entry();
        my $entry = gen_entry();
        my $open= def_image_button("icons/enter.png",undef,TRUE);
        my $open= def_image_button("icons/enter.png",undef,TRUE);
        $eq->attach ($label,0,2,  $row, $row+1,'fill','fill',2,2);
        $eq->attach ($label,0,2,  $row, $row+1,'fill','fill',2,2);
        $eq->attach_defaults ($entry,2, 9,  $row, $row+1);
        $eq->attach_defaults ($entry,2, 9,  $row, $row+1);
        $eq->attach ($open,9, 10,  $row, $row+1,'fill','shrink',2,2);
        $eq->attach ($open,9, 10,  $row, $row+1,'fill','shrink',2,2);
        $table->attach ($eq,0, 20,  $row, $row+1,'expand','fill',2,2);$row++;
        $table->attach ($eq,0, 20,  $row, $row+1,'expand','fill',2,2);$row++;
 
 
        $open->signal_connect("clicked" => sub {
        $open->signal_connect("clicked" => sub {
                                evaluate_eqation($self,$entry->get_text(),$info);
                                evaluate_eqation($self,$entry->get_text(),$info);
 
 
        });
        });
 
 
        $row++;
        $row++;
 
 
 
 
 
 
        add_Hsep_to_table($table,0, 20,  $row);$row++;
        add_Hsep_to_table($table,0, 20,  $row);$row++;
        my $savr=$row;$row++;
        my $savr=$row;$row++;
 
 
        my $maxp=1;
        my $maxp=1;
 
 
        my @all_nodes=get_list_of_all_nodes($self);
        my @all_nodes=get_list_of_all_nodes($self);
 
 
        foreach  my $p  (@all_nodes ){
        foreach  my $p  (@all_nodes ){
                my $inst=$self->object_get_attribute("$p",'NAME');
                my $inst=$self->object_get_attribute("$p",'NAME');
                my $pnum=$self->object_get_attribute("$p",'PNUM');
                my $pnum=$self->object_get_attribute("$p",'PNUM');
                $maxp=  $pnum if($pnum > $maxp );
                $maxp=  $pnum if($pnum > $maxp );
 
 
 
 
 
 
                my $label =gen_label_in_left("$inst:");
                my $label =gen_label_in_left("$inst:");
                attach_widget_to_table ($table,$row,undef,undef,$label,$col);  $col+=4;
                attach_widget_to_table ($table,$row,undef,undef,$label,$col);  $col+=4;
 
 
                for (my $i=0;$i<$pnum; $i++){
                for (my $i=0;$i<$pnum; $i++){
                        my $pname= "Port[${i}]";
                        my $pname= "Port[${i}]";
                        my $connect = $self->{$p}{'PCONNECT'}{$pname};
                        my $connect = $self->{$p}{'PCONNECT'}{$pname};
                        my $button =  def_button(" -> ");
                        my $button =  def_button(" -> ");
                        if (defined $connect) {
                        if (defined $connect) {
                                my ($node,$pnode)=split(/\s*,\s*/,$connect);
                                my ($node,$pnode)=split(/\s*,\s*/,$connect);
                        my $e=$self->object_get_attribute("$node",'NAME');
                        my $e=$self->object_get_attribute("$node",'NAME');
                                $button = def_button("$e->$pnode") if(defined $e);
                                $button = def_button("$e->$pnode") if(defined $e);
                        }
                        }
                        $button->signal_connect("clicked" => sub {
                        $button->signal_connect("clicked" => sub {
                                create_tree_view($self,$p,$pname,$info);
                                create_tree_view($self,$p,$pname,$info);
 
 
                        });
                        });
                        attach_widget_to_table ($table,$row,undef,undef,$button,$col);  $col+=4;
                        attach_widget_to_table ($table,$row,undef,undef,$button,$col);  $col+=4;
                }
                }
                $col=0;
                $col=0;
 
 
                #($row,$col)=add_param_widget ($self,"$instance","CNNT", undef,"Combo-box",$list,"router instance name", $table,$row,$col,1,"ENDP_$i",1,'ref','horizontal');
                #($row,$col)=add_param_widget ($self,"$instance","CNNT", undef,"Combo-box",$list,"router instance name", $table,$row,$col,1,"ENDP_$i",1,'ref','horizontal');
                # my $connect_r= $self->object_get_attribute("ENDP_$i","CNNT");
                # my $connect_r= $self->object_get_attribute("ENDP_$i","CNNT");
                # if( defined $connect_r){
                # if( defined $connect_r){
                #       print "cponnection is $R{$connect_r}\n";
                #       print "cponnection is $R{$connect_r}\n";
                #       my $conr= $R{$connect_r};
                #       my $conr= $R{$connect_r};
                #       my $p=0;
                #       my $p=0;
                #       ($row,$col)=add_param_widget ($self,"P$p","P_$p", undef,"Combo-box",$list,undef, $table,$row,$col,1,"ENDP_$i",1,'ref','horizontal');
                #       ($row,$col)=add_param_widget ($self,"P$p","P_$p", undef,"Combo-box",$list,undef, $table,$row,$col,1,"ENDP_$i",1,'ref','horizontal');
 
 
 
 
 
 
                # }
                # }
                 $row++;$col=0;
                 $row++;$col=0;
 
 
        }
        }
 
 
        #routers
        #routers
    for ( my $i=2;$i<=12; $i++){
    for ( my $i=2;$i<=12; $i++){
                 my $n= $self->object_get_attribute("ROUTER${i}","NUM");
                 my $n= $self->object_get_attribute("ROUTER${i}","NUM");
                 $n=0 if(!defined $n);
                 $n=0 if(!defined $n);
                 for ( my $j=0;$j<$n; $j++){
                 for ( my $j=0;$j<$n; $j++){
                        my $pnum=        $self->object_get_attribute("ROUTER${i}_$j",'PNUM');
                        my $pnum=        $self->object_get_attribute("ROUTER${i}_$j",'PNUM');
                         for ( my $p=0;$p<$pnum; $p++){
                         for ( my $p=0;$p<$pnum; $p++){
                                #       ($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');
                                #       ($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');
 
 
                         }
                         }
                          $row++;$col=0;
                          $row++;$col=0;
 
 
                 }
                 }
        }
        }
 
 
 
 
 
 
 
 
        #add lables
        #add lables
        $row=$savr;$col=0;
        $row=$savr;$col=0;
        $table->attach (def_label(' Network Element '),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col+=4;
        $table->attach (def_label(' Network Element '),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col+=4;
        for (my $i=0;$i<$maxp; $i++){
        for (my $i=0;$i<$maxp; $i++){
                $table->attach (def_label(" P$i "),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col+=4;
                $table->attach (def_label(" P$i "),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col+=4;
 
 
        }
        }
        return $table;
        return $table;
 
 
}
}
 
 
 
 
sub evaluate_eqation{
sub evaluate_eqation{
        my ($self,$exp,$info)=@_;
        my ($self,$exp,$info)=@_;
 
 
        my @str=split /;/, $exp;
        my @str=split /;/, $exp;
        my $eq_exp;
        my $eq_exp;
 
 
        my $f=0;
        my $f=0;
        my %vname;
        my %vname;
        my %vars;
        my %vars;
 
 
        my %nodes_name=get_instance_to_node_name($self);
        my %nodes_name=get_instance_to_node_name($self);
 
 
        foreach my $p (@str) {
        foreach my $p (@str) {
 
 
                if($f==0){
                if($f==0){
                        $eq_exp= $p;
                        $eq_exp= $p;
 
 
                }
                }
                else{
                else{
                        my ($v, $start, $end, $step) = sscanf("%s[%d,%d,%d]", $p);
                        my ($v, $start, $end, $step) = sscanf("%s[%d,%d,%d]", $p);
                        print "($v, $start, $end, $step)\n";
                        print "($v, $start, $end, $step)\n";
                        my @a;
                        my @a;
                        for (my $i=$start; $i<$end;$i++){
                        for (my $i=$start; $i<$end;$i++){
                                push (@a,$i);
                                push (@a,$i);
                        }
                        }
                        $vars{$f}=\@a;
                        $vars{$f}=\@a;
                        $vname{$f}=$v;
                        $vname{$f}=$v;
 
 
                }
                }
                $f++;
                $f++;
 
 
        }
        }
 
 
 
 
        my %vars2;
        my %vars2;
        my $v1=$vname{1};
        my $v1=$vname{1};
        foreach my $i (@{$vars{1}}){
        foreach my $i (@{$vars{1}}){
                $vars2{$v1}=$i;
                $vars2{$v1}=$i;
                my $v2=$vname{2};
                my $v2=$vname{2};
                if (defined $v2) {
                if (defined $v2) {
                        foreach my $j (@{$vars{2}}){
                        foreach my $j (@{$vars{2}}){
                                $vars2{$v2}=$j;
                                $vars2{$v2}=$j;
                                my $v3=$vname{3};
                                my $v3=$vname{3};
                                if (defined $v3) {
                                if (defined $v3) {
                                        foreach my $k (@{$vars{3}}){
                                        foreach my $k (@{$vars{3}}){
                                                $vars2{$v3}=$k;
                                                $vars2{$v3}=$k;
                                                eval_exp($self,$eq_exp,\%vars2,\%nodes_name,$info);
                                                eval_exp($self,$eq_exp,\%vars2,\%nodes_name,$info);
                                        }
                                        }
 
 
                                }
                                }
                                else {eval_exp($self,$eq_exp,\%vars2,\%nodes_name,$info)};
                                else {eval_exp($self,$eq_exp,\%vars2,\%nodes_name,$info)};
 
 
 
 
                        }
                        }
                }
                }
                else {eval_exp($self,$eq_exp,\%vars2,\%nodes_name,$info)};
                else {eval_exp($self,$eq_exp,\%vars2,\%nodes_name,$info)};
 
 
        }
        }
 
 
set_gui_status($self,'ref',1);
set_gui_status($self,'ref',1);
}
}
 
 
 
 
 
 
 
 
sub eval_exp {
sub eval_exp {
        my ($self,$exp,$ref,$ref2,$info)=@_;
        my ($self,$exp,$ref,$ref2,$info)=@_;
        my  %vars = %{$ref};
        my  %vars = %{$ref};
        my %nodes_name =%{$ref2};
        my %nodes_name =%{$ref2};
    foreach my $p (sort keys %vars){
    foreach my $p (sort keys %vars){
 
 
        chomp $exp;
        chomp $exp;
                ($exp=$exp)=~ s/\b$p\b/$vars{$p}/g;
                ($exp=$exp)=~ s/\b$p\b/$vars{$p}/g;
 
 
 
 
    }
    }
 
 
    my ($s1, $n1, $p1,$s2, $n2, $p2 ) = sscanf("%s[%s]P[%s]->%s[%s]P[%s]", $exp);
    my ($s1, $n1, $p1,$s2, $n2, $p2 ) = sscanf("%s[%s]P[%s]->%s[%s]P[%s]", $exp);
 
 
 
 
$n1 = eval $n1;
$n1 = eval $n1;
$p1 = eval $p1;
$p1 = eval $p1;
 
 
$n2 = eval $n2;
$n2 = eval $n2;
$p2 = eval $p2;
$p2 = eval $p2;
 
 
 
 
my $string= "$s1 [$n1] P [$p1] -> $s2 [$n2] P [$p2]\n";
my $string= "$s1 [$n1] P [$p1] -> $s2 [$n2] P [$p2]\n";
 
 
my $node1=$nodes_name{$s1.$n1};
my $node1=$nodes_name{$s1.$n1};
my $node2=$nodes_name{$s2.$n2};
my $node2=$nodes_name{$s2.$n2};
 
 
if(!defined $node1 ){
if(!defined $node1 ){
                add_colored_info($info,"No instance is named as \"$s1$n1\";\n","red") if (defined $info);
                add_colored_info($info,"No instance is named as \"$s1$n1\";\n","red") if (defined $info);
                return;
                return;
        }
        }
        if( !defined $node2 ){
        if( !defined $node2 ){
                add_colored_info($info,"No instance is named as \"$s2$n2\";\n","red") if (defined $info);
                add_colored_info($info,"No instance is named as \"$s2$n2\";\n","red") if (defined $info);
                return;
                return;
        }
        }
 
 
 
 
 connect_nodes ($self,$node1,"Port[$p1]",$node2,"Port[$p2]",$info);
 connect_nodes ($self,$node1,"Port[$p1]",$node2,"Port[$p2]",$info);
 
 
 
 
add_info($info,"$string") if (defined $info);
add_info($info,"$string") if (defined $info);
 
 
 
 
}
}
 
 
###########
###########
# connection_page_auto
# connection_page_auto
##########      
##########      
 
 
sub connection_page_auto{
sub connection_page_auto{
        my ($self,$info)=@_;
        my ($self,$info)=@_;
        my $table= def_table(2,10,FALSE);
        my $table= def_table(2,10,FALSE);
        my $row=0;
        my $row=0;
        my $col=0;
        my $col=0;
 
 
        initial_node_info($self);
        initial_node_info($self);
 
 
        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.";
        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.";
        my $help2 =  "Define the manimum number of endpoints that can be connected to a single router.";
        my $help2 =  "Define the manimum number of endpoints that can be connected to a single router.";
        my $help3 =  undef;
        my $help3 =  undef;
 
 
 
 
 
 
        my @widgets = (
        my @widgets = (
        { 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},
        { 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},
        { 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},
        { 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},
        { 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},
        { 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},
        { label=>"Topology Dimention",             param_name=>'DIMENTION',   type=>"Combo-box",     default_val=>"2D", content=>"2D,3D", info=>undef, param_parent=>'connection_auto', ref_delay=> undef},
        { label=>"Topology Dimention",             param_name=>'DIMENTION',   type=>"Combo-box",     default_val=>"2D", content=>"2D,3D", info=>undef, param_parent=>'connection_auto', ref_delay=> undef},
 
 
                );
                );
 
 
 
 
 
 
        foreach my $d (@widgets) {
        foreach my $d (@widgets) {
                my $w;
                my $w;
                ($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");
                ($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");
 
 
        }#foreach
        }#foreach
 
 
 
 
 
 
 
 
        my $auto = def_image_button('icons/gen.png','Auto Connect');
        my $auto = def_image_button('icons/gen.png','Auto Connect');
        $table->attach ($auto,1, 2,  $row, $row+1,'fill','fill',2,2);
        $table->attach ($auto,1, 2,  $row, $row+1,'fill','fill',2,2);
        $auto-> signal_connect("clicked" => sub{
        $auto-> signal_connect("clicked" => sub{
                        auto_connect($self,$info);
                        auto_connect($self,$info);
        });
        });
 
 
        my $clean = def_image_button('icons/clear.png','Remove All Connection');
        my $clean = def_image_button('icons/clear.png','Remove All Connection');
        $table->attach ($clean,0,1 ,  $row, $row+1,'fill','fill',2,2);
        $table->attach ($clean,0,1 ,  $row, $row+1,'fill','fill',2,2);
        $clean-> signal_connect("clicked" => sub{
        $clean-> signal_connect("clicked" => sub{
                        remove_all_connection($self);
                        remove_all_connection($self);
        });
        });
 
 
 
 
 
 
        return $table;
        return $table;
}
}
 
 
sub get_new_val_based_on_dist {
sub get_new_val_based_on_dist {
        my ($total_router,$total_endp, $router_Pnum,$min_endp,$max_endp,$dist_endp)=@_;
        my ($total_router,$total_endp, $router_Pnum,$min_endp,$max_endp,$dist_endp)=@_;
 
 
        if($dist_endp eq "uniform"){
        if($dist_endp eq "uniform"){
                my $a = int($total_endp/$total_router);
                my $a = int($total_endp/$total_router);
                return $a if($a >= $min_endp && $a <$router_Pnum );
                return $a if($a >= $min_endp && $a <$router_Pnum );
                return $min_endp if($a < $min_endp  );
                return $min_endp if($a < $min_endp  );
                return $router_Pnum -1 if($a >= $router_Pnum ) ;
                return $router_Pnum -1 if($a >= $router_Pnum ) ;
        }
        }
        #random distribution    
        #random distribution    
        my $a = int(rand($max_endp - $min_endp +1)) + $min_endp;
        my $a = int(rand($max_endp - $min_endp +1)) + $min_endp;
        return $a if($a >= $min_endp && $a <$router_Pnum );
        return $a if($a >= $min_endp && $a <$router_Pnum );
        return $min_endp if($a < $min_endp  );
        return $min_endp if($a < $min_endp  );
        return $router_Pnum -1 if($a >= $router_Pnum) ;
        return $router_Pnum -1 if($a >= $router_Pnum) ;
}
}
 
 
 
 
sub assign_endp_num_based_on_dist {
sub assign_endp_num_based_on_dist {
        my ($self,$routers_ref,$total_endp, $min_endp,$max_endp,$dist_endp,$info)=@_;
        my ($self,$routers_ref,$total_endp, $min_endp,$max_endp,$dist_endp,$info)=@_;
        my @routers = @{$routers_ref};
        my @routers = @{$routers_ref};
        my %assigned;
        my %assigned;
        my $total_router = scalar @routers;
        my $total_router = scalar @routers;
        my $valid=1;
        my $valid=1;
        while ($total_endp > 0 && $valid ==1){
        while ($total_endp > 0 && $valid ==1){
                $valid =0;
                $valid =0;
                foreach my $r (reverse @routers) {
                foreach my $r (reverse @routers) {
                        my $router_Pnum=$self->object_get_attribute("$r",'PNUM');
                        my $router_Pnum=$self->object_get_attribute("$r",'PNUM');
                        my $val  = $assigned{$r};
                        my $val  = $assigned{$r};
                        if (!defined $val) {
                        if (!defined $val) {
                                $val=0;
                                $val=0;
                                $assigned{$r}=0;
                                $assigned{$r}=0;
                        }
                        }
                        if ($min_endp >=$router_Pnum || $total_endp ==0 ){
                        if ($min_endp >=$router_Pnum || $total_endp ==0 ){
 
 
                        } else{
                        } else{
                        my $new =get_new_val_based_on_dist ($total_router,$total_endp, $router_Pnum,$min_endp,$max_endp,$dist_endp);
                        my $new =get_new_val_based_on_dist ($total_router,$total_endp, $router_Pnum,$min_endp,$max_endp,$dist_endp);
                                $new =$val + $total_endp  if(($new - $val) > $total_endp);
                                $new =$val + $total_endp  if(($new - $val) > $total_endp);
                                if  ($new<$min_endp){
                                if  ($new<$min_endp){
 
 
                                }
                                }
                                elsif ($new > $val){
                                elsif ($new > $val){
                                        $assigned{$r} = $new;
                                        $assigned{$r} = $new;
                                        $total_endp-=($new - $val);
                                        $total_endp-=($new - $val);
                                        $valid = 1;
                                        $valid = 1;
                                } elsif ($val < $router_Pnum-2 && $val +1 <=$max_endp ){
                                } elsif ($val < $router_Pnum-2 && $val +1 <=$max_endp ){
                                        $assigned{$r} = $val +1;
                                        $assigned{$r} = $val +1;
                                        $total_endp-=1;
                                        $total_endp-=1;
                                        $valid = 1;
                                        $valid = 1;
                                }
                                }
                        }#else
                        }#else
                }#for           
                }#for           
 
 
        }#while
        }#while
 
 
        if ($total_endp > 0) {
        if ($total_endp > 0) {
                add_colored_info($info, "Error: Unable to assign all endpoits to routers using requested configuration. Total of $total_endp endpoints left unconnected\n",'red');
                add_colored_info($info, "Error: Unable to assign all endpoits to routers using requested configuration. Total of $total_endp endpoints left unconnected\n",'red');
                return (\%assigned,0);
                return (\%assigned,0);
        }
        }
 
 
        return (\%assigned,1);
        return (\%assigned,1);
 
 
}
}
 
 
#list the manhatan distance of all nodes in dimention ($xd,$yd,$zd) to the node located in ($xm,$ym,$zm)
#list the manhatan distance of all nodes in dimention ($xd,$yd,$zd) to the node located in ($xm,$ym,$zm)
sub list_manhatan_distance {
sub list_manhatan_distance {
        my ($xd,$yd,$zd,$xm,$ym,$zm)=@_;
        my ($xd,$yd,$zd,$xm,$ym,$zm)=@_;
        my %manhatan;
        my %manhatan;
        for( my $x=0; $x<$xd;$x++){
        for( my $x=0; $x<$xd;$x++){
                for( my $y=0; $y<$yd;$y++){
                for( my $y=0; $y<$yd;$y++){
                        for( my $z=0; $z<$zd;$z++){
                        for( my $z=0; $z<$zd;$z++){
                                $manhatan{"$x,$y,$z"} = abs($x-$xm) + abs($y-$ym) + abs($z-$zm);
                                $manhatan{"$x,$y,$z"} = abs($x-$xm) + abs($y-$ym) + abs($z-$zm);
                        }
                        }
                }
                }
        }
        }
        return %manhatan;
        return %manhatan;
}
}
 
 
 
 
 
 
sub auto_connect {
sub auto_connect {
        my ($self,$info)=@_;
        my ($self,$info)=@_;
        show_colored_info($info, "Start auto connecting Nodes\n",'blue');
        show_colored_info($info, "Start auto connecting Nodes\n",'blue');
        add_info($info, "Step 1: Connect endpoints to the routers:\n");
        add_info($info, "Step 1: Connect endpoints to the routers:\n");
 
 
 
 
        my $min_endp  = $self->object_get_attribute('connection_auto','MIN_ENDP_PER_ROUTER');
        my $min_endp  = $self->object_get_attribute('connection_auto','MIN_ENDP_PER_ROUTER');
        my $max_endp  = $self->object_get_attribute('connection_auto','MAX_ENDP_PER_ROUTER');
        my $max_endp  = $self->object_get_attribute('connection_auto','MAX_ENDP_PER_ROUTER');
        my $dist_endp = $self->object_get_attribute('connection_auto','ENDP_PER_ROUTER_DIST');
        my $dist_endp = $self->object_get_attribute('connection_auto','ENDP_PER_ROUTER_DIST');
        my $dimention = $self->object_get_attribute('connection_auto','DIMENTION');
        my $dimention = $self->object_get_attribute('connection_auto','DIMENTION');
 
 
 
 
        #check min and max is correct
        #check min and max is correct
        if($min_endp > $max_endp ){
        if($min_endp > $max_endp ){
                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');
                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');
        }
        }
 
 
        initial_node_info($self);
        initial_node_info($self);
 
 
        my @all_endpoints=get_list_of_all_endpoints($self);
        my @all_endpoints=get_list_of_all_endpoints($self);
        my @routers=get_list_of_all_routers($self);
        my @routers=get_list_of_all_routers($self);
 
 
        #connect endpoints
        #connect endpoints
        my ($ref,$result)  = assign_endp_num_based_on_dist ($self,\@routers,scalar @all_endpoints, $min_endp,$max_endp,$dist_endp,$info);
        my ($ref,$result)  = assign_endp_num_based_on_dist ($self,\@routers,scalar @all_endpoints, $min_endp,$max_endp,$dist_endp,$info);
        my %assign = %{$ref};
        my %assign = %{$ref};
        my %router_free_port;
        my %router_free_port;
        foreach my $r (reverse @routers) {
        foreach my $r (reverse @routers) {
                $router_free_port{$r}=$self->object_get_attribute("$r",'PNUM');
                $router_free_port{$r}=$self->object_get_attribute("$r",'PNUM');
                my $num = $assign{$r};
                my $num = $assign{$r};
                for (my $p=0; $p<$num;$p++){
                for (my $p=0; $p<$num;$p++){
                        my $e = pop (@all_endpoints);
                        my $e = pop (@all_endpoints);
                        connect_nodes ($self,$r,"Port[$p]",$e,"Port[0]",$info);
                        connect_nodes ($self,$r,"Port[$p]",$e,"Port[0]",$info);
                        my $rinst=$self->object_get_attribute("$r",'NAME');
                        my $rinst=$self->object_get_attribute("$r",'NAME');
                        my $einst=$self->object_get_attribute("$e",'NAME');
                        my $einst=$self->object_get_attribute("$e",'NAME');
                        add_info($info,"\t connect $rinst-Port[$p] -> $einst-Port[0]\n",$info);
                        add_info($info,"\t connect $rinst-Port[$p] -> $einst-Port[0]\n",$info);
                        $router_free_port{$r}=$router_free_port{$r}-1;
                        $router_free_port{$r}=$router_free_port{$r}-1;
                }
                }
        }
        }
 
 
        #get dimention 
        #get dimention 
        my $routers_num =scalar @routers;
        my $routers_num =scalar @routers;
        my ($xd,$yd,$zd)=(1,1,1);
        my ($xd,$yd,$zd)=(1,1,1);
        ($xd,$yd)= network_dim_cal ($routers_num) if ($dimention eq '2D');
        ($xd,$yd)= network_dim_cal ($routers_num) if ($dimention eq '2D');
        ($xd,$yd,$zd)=network_3dim_cal ($routers_num) if ($dimention eq '3D');
        ($xd,$yd,$zd)=network_3dim_cal ($routers_num) if ($dimention eq '3D');
        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");
        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");
 
 
        #obtain routers location 
        #obtain routers location 
        #center loc
        #center loc
        my $xmid =int($xd/2);
        my $xmid =int($xd/2);
        my $ymid =int($yd/2);
        my $ymid =int($yd/2);
        my $zmid =int($zd/2);
        my $zmid =int($zd/2);
 
 
        #sort location based on manhatan distanc from the center
        #sort location based on manhatan distanc from the center
        my %manhatan = list_manhatan_distance ($xd,$yd,$zd,$xmid,$ymid,$zmid);
        my %manhatan = list_manhatan_distance ($xd,$yd,$zd,$xmid,$ymid,$zmid);
        my @sort_locs = (sort { $manhatan{$a} <=> $manhatan{$b} } keys %manhatan);
        my @sort_locs = (sort { $manhatan{$a} <=> $manhatan{$b} } keys %manhatan);
 
 
        #sort routers based on avilable ports
        #sort routers based on avilable ports
        my @sort_routers = (sort { $router_free_port{$b} <=> $router_free_port{$a} } keys %router_free_port);
        my @sort_routers = (sort { $router_free_port{$b} <=> $router_free_port{$a} } keys %router_free_port);
 
 
        #assign sorted routers to sorted locations 
        #assign sorted routers to sorted locations 
        my %locations;
        my %locations;
        foreach my $r (@sort_routers){
        foreach my $r (@sort_routers){
        my $loc = shift @sort_locs;
        my $loc = shift @sort_locs;
        my $inst=$self->object_get_attribute("$r",'NAME');
        my $inst=$self->object_get_attribute("$r",'NAME');
        add_info($info, "\t $inst with $router_free_port{$r} free port placed in $loc location\n");
        add_info($info, "\t $inst with $router_free_port{$r} free port placed in $loc location\n");
        $self->object_add_attribute("$r",'LOC_ASIC',$loc);
        $self->object_add_attribute("$r",'LOC_ASIC',$loc);
        $locations{$loc}=$r;
        $locations{$loc}=$r;
        }
        }
 
 
        #start from the center and connect each router to the N nearest router
        #start from the center and connect each router to the N nearest router
        add_info($info,"Step3 : start from the center and connect each router to the N nearest router\n",$info);
        add_info($info,"Step3 : start from the center and connect each router to the N nearest router\n",$info);
        foreach my $r (@sort_routers){
        foreach my $r (@sort_routers){
 
 
                my $avb_P_num =$router_free_port{$r};
                my $avb_P_num =$router_free_port{$r};
                my @up = list_node_unconnected_port($self,$r);
                my @up = list_node_unconnected_port($self,$r);
                my @cp = list_node_connected_port ($self,$r);
                my @cp = list_node_connected_port ($self,$r);
                my $loc = $self->object_get_attribute("$r",'LOC_ASIC');
                my $loc = $self->object_get_attribute("$r",'LOC_ASIC');
                my ($xc,$yc,$zc)=split(',',$loc);
                my ($xc,$yc,$zc)=split(',',$loc);
                my %manhatan = list_manhatan_distance ($xd,$yd,$zd,$xc,$yc,$zc);
                my %manhatan = list_manhatan_distance ($xd,$yd,$zd,$xc,$yc,$zc);
                my @sort_locs = (sort { $manhatan{$a} <=> $manhatan{$b} } keys %manhatan);
                my @sort_locs = (sort { $manhatan{$a} <=> $manhatan{$b} } keys %manhatan);
 
 
                while (scalar @up && scalar @sort_locs){
                while (scalar @up && scalar @sort_locs){
                        #select one unconnected port from current router
                        #select one unconnected port from current router
                        my $p = shift @up;
                        my $p = shift @up;
                        my $cr;
                        my $cr;
                        my $cp;
                        my $cp;
                        while (scalar @sort_locs && !defined $cp){
                        while (scalar @sort_locs && !defined $cp){
                                #select the nearest router to current one
                                #select the nearest router to current one
                                my $cl =shift @sort_locs;
                                my $cl =shift @sort_locs;
                                $cr=$locations{$cl};
                                $cr=$locations{$cl};
                                next if(!defined $cr);
                                next if(!defined $cr);
                                next if ($cr eq $r); #thes two routers are identical
                                next if ($cr eq $r); #thes two routers are identical
                                #check if they are not connected
                                #check if they are not connected
                                my $line =get_connection_port_num_between_two_nodes($self,$r,$cr);
                                my $line =get_connection_port_num_between_two_nodes($self,$r,$cr);
                                next if (defined $line); #these two routers are already connected
                                next if (defined $line); #these two routers are already connected
                                my @up_cr = list_node_unconnected_port($self,$cr);
                                my @up_cr = list_node_unconnected_port($self,$cr);
                                next if (scalar @up_cr == 0); # the target router has no free port
                                next if (scalar @up_cr == 0); # the target router has no free port
                                $cp=$up_cr[0];
                                $cp=$up_cr[0];
                        }
                        }
                        last if(!defined $cp);
                        last if(!defined $cp);
                        my $rinst=$self->object_get_attribute("$r",'NAME');
                        my $rinst=$self->object_get_attribute("$r",'NAME');
                        my $einst=$self->object_get_attribute("$cr",'NAME');
                        my $einst=$self->object_get_attribute("$cr",'NAME');
                        add_info($info,"\t connect $rinst-$p -> $einst-$cp\n",$info);
                        add_info($info,"\t connect $rinst-$p -> $einst-$cp\n",$info);
                        connect_nodes ($self,$r,"$p",$cr,"$cp",$info);
                        connect_nodes ($self,$r,"$p",$cr,"$cp",$info);
                }
                }
 
 
        }
        }
 
 
 
 
 
 
 
 
 
 
 
 
        set_gui_status($self,"ref",1);
        set_gui_status($self,"ref",1);
 
 
 
 
 
 
 
 
 
 
}
}
 
 
sub routing_page_auto{
sub routing_page_auto{
        my ($self,$info)=@_;
        my ($self,$info)=@_;
        my $table= def_table(2,10,FALSE);
        my $table= def_table(2,10,FALSE);
        my $row=0;
        my $row=0;
        my $col=0;
        my $col=0;
 
 
 
 
        $self->object_add_attribute('routing','type','turn_model');
        $self->object_add_attribute('routing','type','turn_model');
 
 
 
 
 
 
        my $auto = def_image_button('icons/gen.png','AutoGenerate');
        my $auto = def_image_button('icons/gen.png','AutoGenerate');
        #$table->attach ($auto,0, 1,  $row, $row+1,'fill','fill',2,2);
        #$table->attach ($auto,0, 1,  $row, $row+1,'fill','fill',2,2);
        my $clear = def_image_button('icons/clear.png','Clear');
        my $clear = def_image_button('icons/clear.png','Clear');
        #$table->attach ($clear,2,3 ,  $row, $row+1,'fill','fill',2,2);$row++;
        #$table->attach ($clear,2,3 ,  $row, $row+1,'fill','fill',2,2);$row++;
 
 
        my $box= def_pack_hbox( FALSE, 0 , $auto,$clear);
        my $box= def_pack_hbox( FALSE, 0 , $auto,$clear);
        $table->attach ($box,0,5 ,  $row, $row+1,'fill','fill',2,2);$row++;
        $table->attach ($box,0,5 ,  $row, $row+1,'fill','fill',2,2);$row++;
 
 
        $auto-> signal_connect("clicked" => sub{
        $auto-> signal_connect("clicked" => sub{
                        auto_route($self,$info);
                        auto_route($self,$info);
        });
        });
 
 
        $clear-> signal_connect("clicked" => sub{
        $clear-> signal_connect("clicked" => sub{
                        clean_route($self,$info);
                        clean_route($self,$info);
        });
        });
 
 
        my $manual = get_route_manual ($self,$info);
        my $manual = get_route_manual ($self,$info);
 
 
        my $mtable= def_table(2,2,FALSE);
        my $mtable= def_table(2,2,FALSE);
 
 
        $mtable->attach_defaults ($table  , 0, 1, 0,1);
        $mtable->attach_defaults ($table  , 0, 1, 0,1);
        $mtable->attach_defaults ($manual  , 0, 1, 1,2);
        $mtable->attach_defaults ($manual  , 0, 1, 1,2);
 
 
        return $mtable;
        return $mtable;
}
}
 
 
sub update_acycle_model {
sub update_acycle_model {
        my ($self,$alg_name,$info)=@_;
        my ($self,$alg_name,$info)=@_;
        my $tmp_dir  = "$ENV{'PRONOC_WORK'}/tmp";
        my $tmp_dir  = "$ENV{'PRONOC_WORK'}/tmp";
        my $model_file = "$tmp_dir/$alg_name.alg";
        my $model_file = "$tmp_dir/$alg_name.alg";
        my ($pp,$r,$err) = regen_object($model_file);
        my ($pp,$r,$err) = regen_object($model_file);
        if ($r){
        if ($r){
                add_colored_info($info,"**Error: cannot open $model_file file: $err\n",'red');
                add_colored_info($info,"**Error: cannot open $model_file file: $err\n",'red');
                $self->object_add_attribute('routing_auto','acyclic_turns_model',undef);
                $self->object_add_attribute('routing_auto','acyclic_turns_model',undef);
                return;
                return;
        } else {
        } else {
                add_info($info,"Use $alg_name algorithm for obtaing acyclic paths\n");
                add_info($info,"Use $alg_name algorithm for obtaing acyclic paths\n");
        }
        }
 
 
        my @acyclic_turns = @{$pp};
        my @acyclic_turns = @{$pp};
        $self->object_add_attribute('routing_auto','acyclic_turns_model',\@acyclic_turns);
        $self->object_add_attribute('routing_auto','acyclic_turns_model',\@acyclic_turns);
 
 
}
}
 
 
 
 
sub routing_page_manual{
sub routing_page_manual{
        my ($self,$info)=@_;
        my ($self,$info)=@_;
        my $table= def_table(2,10,FALSE);
        my $table= def_table(2,10,FALSE);
        my $row=0;
        my $row=0;
        my $col=0;
        my $col=0;
 
 
        $self->object_add_attribute('routing','type','minimal');
        $self->object_add_attribute('routing','type','minimal');
 
 
        initial_node_info($self);
        initial_node_info($self);
        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.";
        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.";
        my $help2 =  "Define the maximum number of routers (path length) paths which should be extracted for any specefic source-destination endpoints pair.";
        my $help2 =  "Define the maximum number of routers (path length) paths which should be extracted for any specefic source-destination endpoints pair.";
        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.";
        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.";
 
 
 
 
        my @widgets = (
        my @widgets = (
        { 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},
        { 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},
        { 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},
        { 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},
        { 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 },
        { 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 },
 
 
        );
        );
 
 
 
 
        foreach my $d (@widgets) {
        foreach my $d (@widgets) {
                my $w;
                my $w;
                ($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");
                ($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");
 
 
        }#foreach
        }#foreach
        my $offset = $self->object_get_attribute('routing_auto','OFFSET');
        my $offset = $self->object_get_attribute('routing_auto','OFFSET');
        my $max_len = $self->object_get_attribute('routing_auto','MAX_LENGTH');
        my $max_len = $self->object_get_attribute('routing_auto','MAX_LENGTH');
 
 
        my $auto = def_image_button('icons/gen.png','AutoGenerate');
        my $auto = def_image_button('icons/gen.png','AutoGenerate');
 
 
        my $path_select= $self->object_get_attribute("routing_auto",'PATH_SELECT');
        my $path_select= $self->object_get_attribute("routing_auto",'PATH_SELECT');
        if($path_select eq "Cycle-free paths") {
        if($path_select eq "Cycle-free paths") {
                my %algorithms;
                my %algorithms;
                my $ref  =$self->object_get_attribute('routing_auto','acyclic_algorithms');
                my $ref  =$self->object_get_attribute('routing_auto','acyclic_algorithms');
                %algorithms = %{$ref} if defined $ref;
                %algorithms = %{$ref} if defined $ref;
                my @algs = sort { $algorithms{$a} <=> $algorithms{$b} } keys(%algorithms);
                my @algs = sort { $algorithms{$a} <=> $algorithms{$b} } keys(%algorithms);
                my ($content,$default);
                my ($content,$default);
                foreach my $alg (@algs){
                foreach my $alg (@algs){
                        $content.="$alg  --  $algorithms{$alg},";
                        $content.="$alg  --  $algorithms{$alg},";
                        $default= "$alg  --  $algorithms{$alg};";
                        $default= "$alg  --  $algorithms{$alg};";
 
 
                }
                }
                if (!defined $content){
                if (!defined $content){
                        $content='-';
                        $content='-';
                        $default='-';
                        $default='-';
 
 
                }
                }
 
 
                my $alg;
                my $alg;
                ($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");
                ($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");
 
 
                $alg->signal_connect("changed" => sub{
                $alg->signal_connect("changed" => sub{
                        my $comb_text = $alg->get_active_text();
                        my $comb_text = $alg->get_active_text();
                        my ($alg_name,$line) = split (/\s+--\s+/,$comb_text);
                        my ($alg_name,$line) = split (/\s+--\s+/,$comb_text);
                        update_acycle_model ($self,$alg_name,$info);
                        update_acycle_model ($self,$alg_name,$info);
                        #print "bbbb:@acyclic_turns\n"; 
                        #print "bbbb:@acyclic_turns\n"; 
                });
                });
 
 
                $auto-> signal_connect("clicked" => sub{
                $auto-> signal_connect("clicked" => sub{
                        auto_route($self,$info);
                        auto_route($self,$info);
                });
                });
 
 
 
 
        }
        }
 
 
 
 
 
 
 
 
        my $clear = def_image_button('icons/clear.png','Clear');
        my $clear = def_image_button('icons/clear.png','Clear');
        my $gen_cycle_free = def_image_button('icons/turn.png','Generate Cycle-free Paths');
        my $gen_cycle_free = def_image_button('icons/turn.png','Generate Cycle-free Paths');
 
 
        if($path_select eq 'Cycle-free paths') {
        if($path_select eq 'Cycle-free paths') {
                $table->attach ($gen_cycle_free,0,2 ,  $row, $row+1,'fill','fill',2,2);$row++;
                $table->attach ($gen_cycle_free,0,2 ,  $row, $row+1,'fill','fill',2,2);$row++;
                $table->attach ($auto,2, 3,  $row, $row+1,'fill','fill',2,2);
                $table->attach ($auto,2, 3,  $row, $row+1,'fill','fill',2,2);
 
 
        }
        }
        $table->attach ($clear,0,2 ,  $row, $row+1,'fill','fill',2,2);$row++;
        $table->attach ($clear,0,2 ,  $row, $row+1,'fill','fill',2,2);$row++;
 
 
 
 
        $clear-> signal_connect("clicked" => sub{
        $clear-> signal_connect("clicked" => sub{
                        clean_route($self,$info);
                        clean_route($self,$info);
        });
        });
 
 
        $gen_cycle_free -> signal_connect("clicked" => sub{
        $gen_cycle_free -> signal_connect("clicked" => sub{
                        gen_aciclic_turn_graph($self,$info);
                        gen_aciclic_turn_graph($self,$info);
                        my %algorithms;
                        my %algorithms;
                        my $ref  =$self->object_get_attribute('routing_auto','acyclic_algorithms');
                        my $ref  =$self->object_get_attribute('routing_auto','acyclic_algorithms');
                        %algorithms = %{$ref} if defined $ref;
                        %algorithms = %{$ref} if defined $ref;
                        my @algs = sort { $algorithms{$a} <=> $algorithms{$b} } keys(%algorithms);
                        my @algs = sort { $algorithms{$a} <=> $algorithms{$b} } keys(%algorithms);
                        update_acycle_model ($self,$algs[0],$info);
                        update_acycle_model ($self,$algs[0],$info);
                        set_gui_status($self,'ref',1);
                        set_gui_status($self,'ref',1);
        });
        });
 
 
        my $manual = get_route_manual ($self,$info);
        my $manual = get_route_manual ($self,$info);
 
 
        my $mtable= def_table(2,2,FALSE);
        my $mtable= def_table(2,2,FALSE);
 
 
        $mtable->attach_defaults ($table  , 0, 1, 0,1);
        $mtable->attach_defaults ($table  , 0, 1, 0,1);
        $mtable->attach_defaults ($manual  , 0, 1, 1,2);
        $mtable->attach_defaults ($manual  , 0, 1, 1,2);
 
 
        return $mtable;
        return $mtable;
}
}
 
 
 
 
 
 
 
 
sub get_route_manual {
sub get_route_manual {
        my ($self,$info)=@_;
        my ($self,$info)=@_;
 
 
        my $row=0;
        my $row=0;
        my $col=0;
        my $col=0;
 
 
        my $table= def_table(2,10,FALSE);
        my $table= def_table(2,10,FALSE);
 
 
        add_Hsep_to_table ($table,0, 200,  $row);$row++;
        add_Hsep_to_table ($table,0, 200,  $row);$row++;
 
 
        my $refresh = def_image_button('icons/refresh.png','Refresh');
        my $refresh = def_image_button('icons/refresh.png','Refresh');
        $table->attach ($refresh,0,5 ,  $row, $row+1,'fill','fill',2,2);$row++;
        $table->attach ($refresh,0,5 ,  $row, $row+1,'fill','fill',2,2);$row++;
 
 
 
 
        $table->attach (gen_colored_label('Not selected',17),5,10,$row,$row+1,'fill','shrink',2,2);
        $table->attach (gen_colored_label('Not selected',17),5,10,$row,$row+1,'fill','shrink',2,2);
        $table->attach (gen_colored_label('Selected',0),10,15,$row,$row+1,'fill','shrink',2,2);
        $table->attach (gen_colored_label('Selected',0),10,15,$row,$row+1,'fill','shrink',2,2);
        $table->attach (gen_colored_label('Not Existed',11),15,20,$row,$row+1,'fill','shrink',2,2);
        $table->attach (gen_colored_label('Not Existed',11),15,20,$row,$row+1,'fill','shrink',2,2);
        $row++;
        $row++;
 
 
        $table->attach (def_label(' source -> destination '),10,15,$row,$row+1,'fill','shrink',2,2);
        $table->attach (def_label(' source -> destination '),10,15,$row,$row+1,'fill','shrink',2,2);
    $row++;
    $row++;
 
 
 
 
        my @all_endpoints=get_list_of_all_endpoints($self);
        my @all_endpoints=get_list_of_all_endpoints($self);
 
 
        foreach  my $src  (@all_endpoints ){
        foreach  my $src  (@all_endpoints ){
                foreach  my $dst  (@all_endpoints ){
                foreach  my $dst  (@all_endpoints ){
                        my $src_inst=$self->object_get_attribute("$src",'NAME');
                        my $src_inst=$self->object_get_attribute("$src",'NAME');
                        my $dst_inst=$self->object_get_attribute("$dst",'NAME');
                        my $dst_inst=$self->object_get_attribute("$dst",'NAME');
                        my $select = $self->object_get_attribute('Route',"${src}::$dst");
                        my $select = $self->object_get_attribute('Route',"${src}::$dst");
 
 
                        #my ($paths_to_dst,$ports_to_dst); #= get_all_paths_between_two_endps($self,$src, $dst);
                        #my ($paths_to_dst,$ports_to_dst); #= get_all_paths_between_two_endps($self,$src, $dst);
                        #my $color =(scalar @{$paths_to_dst}==0)? 11 :  (defined $select)? 0 : 17;                                      
                        #my $color =(scalar @{$paths_to_dst}==0)? 11 :  (defined $select)? 0 : 17;                                      
                        #my $button = ($src_inst ne $dst_inst )?  def_colored_button("${src_inst}->$dst_inst",$color): gen_label_in_center(' - ');      
                        #my $button = ($src_inst ne $dst_inst )?  def_colored_button("${src_inst}->$dst_inst",$color): gen_label_in_center(' - ');      
 
 
                        my $color = (defined $select)? 0 :17;
                        my $color = (defined $select)? 0 :17;
                        my $button = ($src_inst ne $dst_inst )?  def_colored_button("${src_inst}->$dst_inst",$color): gen_label_in_center(' - ');
                        my $button = ($src_inst ne $dst_inst )?  def_colored_button("${src_inst}->$dst_inst",$color): gen_label_in_center(' - ');
 
 
 
 
                        attach_widget_to_table ($table,$row,undef,undef,$button,$col);  $col+=4;
                        attach_widget_to_table ($table,$row,undef,undef,$button,$col);  $col+=4;
 
 
 
 
 
 
                        $button->signal_connect("clicked" => sub {
                        $button->signal_connect("clicked" => sub {
                                $self->object_add_attribute("SELECT_PATH","src",$src);
                                $self->object_add_attribute("SELECT_PATH","src",$src);
                                $self->object_add_attribute("SELECT_PATH","dst",$dst);
                                $self->object_add_attribute("SELECT_PATH","dst",$dst);
                                set_gui_status($self,"redraw",1);
                                set_gui_status($self,"redraw",1);
 
 
                        }) if($src_inst ne $dst_inst );
                        }) if($src_inst ne $dst_inst );
 
 
 
 
                }$row++;$col=0;
                }$row++;$col=0;
        }
        }
 
 
 
 
        $refresh->signal_connect("clicked" => sub{
        $refresh->signal_connect("clicked" => sub{
                        refresh_route_manual($self,$info);
                        refresh_route_manual($self,$info);
        });
        });
 
 
        return $table;
        return $table;
}
}
 
 
 
 
sub refresh_route_manual {
sub refresh_route_manual {
        my ($self,$info)=@_;
        my ($self,$info)=@_;
        my @all_endpoints=get_list_of_all_endpoints($self);
        my @all_endpoints=get_list_of_all_endpoints($self);
 
 
        my $path_select= $self->object_get_attribute("routing_auto",'PATH_SELECT');
        my $path_select= $self->object_get_attribute("routing_auto",'PATH_SELECT');
        my @acyclic_turns;
        my @acyclic_turns;
 
 
 
 
        if ($path_select ne "all-paths"){
        if ($path_select ne "all-paths"){
                 my $ref = $self->object_get_attribute('routing_auto','acyclic_turns_model');
                 my $ref = $self->object_get_attribute('routing_auto','acyclic_turns_model');
                 if(defined $ref) {
                 if(defined $ref) {
                        @acyclic_turns = @{$ref};
                        @acyclic_turns = @{$ref};
                 }else{
                 }else{
                        add_colored_info($info,"Info:No acyclic route model is selected\n",'green');
                        add_colored_info($info,"Info:No acyclic route model is selected\n",'green');
 
 
                 }
                 }
        }
        }
 
 
        foreach  my $src  (@all_endpoints ){
        foreach  my $src  (@all_endpoints ){
                foreach  my $dst  (@all_endpoints ){
                foreach  my $dst  (@all_endpoints ){
                        my $src_inst=$self->object_get_attribute("$src",'NAME');
                        my $src_inst=$self->object_get_attribute("$src",'NAME');
                        my $dst_inst=$self->object_get_attribute("$dst",'NAME');
                        my $dst_inst=$self->object_get_attribute("$dst",'NAME');
                        my $select = $self->object_get_attribute('Route',"${src}::$dst");
                        my $select = $self->object_get_attribute('Route',"${src}::$dst");
 
 
                        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) ;
                        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) ;
                        my @paths = @{$ref1};
                        my @paths = @{$ref1};
                        if (defined $select){
                        if (defined $select){
                                #check if select exist in @paths
                                #check if select exist in @paths
                                my $match=0;
                                my $match=0;
 
 
                                foreach  my $p (@paths ){
                                foreach  my $p (@paths ){
                                        my @a1 = @{$p};
                                        my @a1 = @{$p};
                                        my @a2 = @{$select};
                                        my @a2 = @{$select};
                                        my $st1=join('->',@a1);
                                        my $st1=join('->',@a1);
                                        my $st2=join('->',@a2);
                                        my $st2=join('->',@a2);
                                        if($st1 eq $st2){
                                        if($st1 eq $st2){
                                                $match=1;
                                                $match=1;
                                        }
                                        }
                                }#foreach
                                }#foreach
                                #remove it from the selected path
                                #remove it from the selected path
                                if ($match ==0){
                                if ($match ==0){
                                        my $selp;
                                        my $selp;
                                        foreach my $q ( @{$select}){
                                        foreach my $q ( @{$select}){
                                                my $inst=$self->object_get_attribute("$q",'NAME');
                                                my $inst=$self->object_get_attribute("$q",'NAME');
                                                $selp= (defined $selp)? $selp."->$inst" : $inst;
                                                $selp= (defined $selp)? $selp."->$inst" : $inst;
                                        }
                                        }
 
 
                                        add_info ($info,"$selp does not exist in path list anymore and it has been removed\n");
                                        add_info ($info,"$selp does not exist in path list anymore and it has been removed\n");
                                        $self->object_add_attribute('Route',"${src}::$dst",undef);
                                        $self->object_add_attribute('Route',"${src}::$dst",undef);
                                }#if 
                                }#if 
                        }#if 
                        }#if 
                }#foreach
                }#foreach
        }#foreach               
        }#foreach               
 
 
 
 
        set_gui_status($self,"ref",1);
        set_gui_status($self,"ref",1);
 
 
}
}
 
 
 
 
sub route_info_window{
sub route_info_window{
        my ($self,$info)= @_;
        my ($self,$info)= @_;
        my $w1 = show_paths_between_two_endps($self,$info);
        my $w1 = show_paths_between_two_endps($self,$info);
        my $w2 = routing_summary($self,$info);
        my $w2 = routing_summary($self,$info);
        my $h1=gen_hpaned($w1,.30,$w2);
        my $h1=gen_hpaned($w1,.30,$w2);
        return $h1;
        return $h1;
}
}
 
 
 
 
 
 
sub add_route_edge_to_graph{
sub add_route_edge_to_graph{
        my ($gref,$anodes_ref)=@_;
        my ($gref,$anodes_ref)=@_;
        my %graph=%{$gref};
        my %graph=%{$gref};
        my @a_nodes= @{$anodes_ref};
        my @a_nodes= @{$anodes_ref};
 
 
        my $old_r;
        my $old_r;
        foreach my $r (@a_nodes){
        foreach my $r (@a_nodes){
 
 
                if(defined $old_r){
                if(defined $old_r){
                                push(@{$graph{$old_r}},$r);
                                push(@{$graph{$old_r}},$r);
                }
                }
                $old_r=$r;
                $old_r=$r;
        }
        }
 
 
        return %graph;
        return %graph;
}
}
 
 
sub get_adjacent_node_in_a_path{
sub get_adjacent_node_in_a_path{
        my $ref=shift;
        my $ref=shift;
        my @result;
        my @result;
        my @path=@{$ref};
        my @path=@{$ref};
        my $old_r;
        my $old_r;
        foreach my $r (@path){
        foreach my $r (@path){
                push (@result,"${old_r}::$r") if(defined $old_r);
                push (@result,"${old_r}::$r") if(defined $old_r);
                $old_r=$r;
                $old_r=$r;
        }
        }
        return @result;
        return @result;
 
 
}
}
 
 
sub get_adjacent_router_in_a_path{
sub get_adjacent_router_in_a_path{
 
 
        my $ref=shift;
        my $ref=shift;
        my @result;
        my @result;
        my @path=@{$ref};
        my @path=@{$ref};
        shift @path; #remove source node from the path
        shift @path; #remove source node from the path
        pop @path; #remove the destination node from the path
        pop @path; #remove the destination node from the path
 
 
 
 
        my $old_r;
        my $old_r;
        foreach my $r (@path){
        foreach my $r (@path){
                push (@result,"${old_r}::$r") if(defined $old_r);
                push (@result,"${old_r}::$r") if(defined $old_r);
                $old_r=$r;
                $old_r=$r;
        }
        }
        return @result;
        return @result;
 
 
}
}
 
 
 
 
sub get_route_info{
sub get_route_info{
        my ($self)=@_;
        my ($self)=@_;
        my %R_num;
        my %R_num;
        my %L_num;
        my %L_num;
        my @all_endpoints=get_list_of_all_endpoints($self);
        my @all_endpoints=get_list_of_all_endpoints($self);
        foreach  my $r  (@all_endpoints ){
        foreach  my $r  (@all_endpoints ){
                $R_num{$r} =0;
                $R_num{$r} =0;
        }
        }
        my @nodes=get_list_of_all_routers($self);
        my @nodes=get_list_of_all_routers($self);
        foreach my $p (@nodes){
        foreach my $p (@nodes){
                $R_num{$p} =0;
                $R_num{$p} =0;
        }
        }
        foreach  my $src  (@all_endpoints ){
        foreach  my $src  (@all_endpoints ){
                foreach  my $dst  (@all_endpoints ){
                foreach  my $dst  (@all_endpoints ){
                        my $path = $self->object_get_attribute('Route',"${src}::$dst");
                        my $path = $self->object_get_attribute('Route',"${src}::$dst");
                        if (defined $path){
                        if (defined $path){
                                #router counting
                                #router counting
                                my @p=@{$path};
                                my @p=@{$path};
                                foreach my $r (@p){
                                foreach my $r (@p){
                                        $R_num{$r} ++;
                                        $R_num{$r} ++;
                                }
                                }
                                #path counting
                                #path counting
                                @p=     get_adjacent_router_in_a_path($path);
                                @p=     get_adjacent_router_in_a_path($path);
                                foreach my $r (@p){
                                foreach my $r (@p){
                                        $L_num{$r} ++;
                                        $L_num{$r} ++;
 
 
                                }
                                }
 
 
 
 
                        }
                        }
                }
                }
        }
        }
 
 
        my @Rkeys = sort { $R_num{$a} <=> $R_num{$b} } keys(%R_num);
        my @Rkeys = sort { $R_num{$a} <=> $R_num{$b} } keys(%R_num);
        my @Lkeys = sort { $L_num{$a} <=> $L_num{$b} } keys(%L_num);
        my @Lkeys = sort { $L_num{$a} <=> $L_num{$b} } keys(%L_num);
        my $sample="sample0";
        my $sample="sample0";
        foreach  my $r  (@nodes ){
        foreach  my $r  (@nodes ){
                my $inst=$self->object_get_attribute("$r",'NAME');
                my $inst=$self->object_get_attribute("$r",'NAME');
                update_result ($self,$sample,"router_all_paths_result",'-',$inst,$R_num{$r});
                update_result ($self,$sample,"router_all_paths_result",'-',$inst,$R_num{$r});
        }
        }
 
 
        my $max_r = (defined $Rkeys[-1]) ? $R_num{$Rkeys[-1]} : 0;
        my $max_r = (defined $Rkeys[-1]) ? $R_num{$Rkeys[-1]} : 0;
        my $min_r = (defined $Rkeys[ 0]) ? $R_num{$Rkeys[ 0]} : 0;
        my $min_r = (defined $Rkeys[ 0]) ? $R_num{$Rkeys[ 0]} : 0;
        my $max_l = (defined $Lkeys[-1]) ? $L_num{$Lkeys[-1]} : 0;
        my $max_l = (defined $Lkeys[-1]) ? $L_num{$Lkeys[-1]} : 0;
        my $min_l = (defined $Lkeys[ 0]) ? $L_num{$Lkeys[ 0]} : 0;
        my $min_l = (defined $Lkeys[ 0]) ? $L_num{$Lkeys[ 0]} : 0;
        my @l = sort  values (%L_num);
        my @l = sort  values (%L_num);
        my $std_l=stdev(\@l);
        my $std_l=stdev(\@l);
 
 
        $self->object_add_attribute ($sample,"link_all_paths_result",undef);
        $self->object_add_attribute ($sample,"link_all_paths_result",undef);
 
 
        my $nn=0;
        my $nn=0;
        my $min_l_name="-";
        my $min_l_name="-";
        my $max_l_name="-";
        my $max_l_name="-";
        my $siz = $#Lkeys;
        my $siz = $#Lkeys;
        foreach  my $r  (@Lkeys ){
        foreach  my $r  (@Lkeys ){
                my ($n1,$n2)=split(/::/,$r);
                my ($n1,$n2)=split(/::/,$r);
                my $inst1=$self->object_get_attribute("$n1",'NAME');
                my $inst1=$self->object_get_attribute("$n1",'NAME');
                my $inst2=$self->object_get_attribute("$n2",'NAME');
                my $inst2=$self->object_get_attribute("$n2",'NAME');
                my $inst = "$inst1-$inst2";
                my $inst = "$inst1-$inst2";
                update_result ($self,$sample,"link_all_paths_result",'-',$inst,$L_num{$r});
                update_result ($self,$sample,"link_all_paths_result",'-',$inst,$L_num{$r});
                $min_l_name= $inst if($nn==0);
                $min_l_name= $inst if($nn==0);
                $max_l_name= $inst if($nn==$siz-1);
                $max_l_name= $inst if($nn==$siz-1);
                $nn++;
                $nn++;
        }
        }
 
 
 
 
 
 
        my $max_r_name= (defined $Rkeys[-1])? $self->object_get_attribute("$Rkeys[-1]",'NAME') : "-";
        my $max_r_name= (defined $Rkeys[-1])? $self->object_get_attribute("$Rkeys[-1]",'NAME') : "-";
        my $min_r_name= (defined $Rkeys[0]) ? $self->object_get_attribute("$Rkeys[0]",'NAME') : "-";
        my $min_r_name= (defined $Rkeys[0]) ? $self->object_get_attribute("$Rkeys[0]",'NAME') : "-";
 
 
        $max_r_name= "-" if (!defined $max_r_name);
        $max_r_name= "-" if (!defined $max_r_name);
        $min_r_name= "-" if (!defined $min_r_name);
        $min_r_name= "-" if (!defined $min_r_name);
 
 
 
 
        return ($max_r,$min_r,$max_l,$min_l,$std_l,$max_r_name,$min_r_name,$max_l_name,$min_l_name);
        return ($max_r,$min_r,$max_l,$min_l,$std_l,$max_r_name,$min_r_name,$max_l_name,$min_l_name);
}
}
 
 
 
 
sub routing_summary{
sub routing_summary{
        my ($self,$info)= @_;
        my ($self,$info)= @_;
 
 
        my $sc_win = gen_scr_win_with_adjst($self,'map_info');
        my $sc_win = gen_scr_win_with_adjst($self,'map_info');
        #my $table= def_table(10,10,FALSE);
        #my $table= def_table(10,10,FALSE);
 
 
 
 
        my $row=0;
        my $row=0;
        my $col=0;
        my $col=0;
        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);
        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);
 
 
 
 
        my @data = (
        my @data = (
   {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.
   {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.
   {0 => "The Minimum number that a router is used in routing",  1 =>"$min_r", 2 =>"$min_r_name" },
   {0 => "The Minimum number that a router is used in routing",  1 =>"$min_r", 2 =>"$min_r_name" },
   {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.
   {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.
   {0 => "The Minimum number that a link is used in routing",  1=>"$min_l", 2 =>"$min_l_name" },
   {0 => "The Minimum number that a link is used in routing",  1=>"$min_l", 2 =>"$min_l_name" },
   {0 => "Link usage  standard deviation ",  1 =>"$std_l" }
   {0 => "Link usage  standard deviation ",  1 =>"$std_l" }
  );
  );
 
 
 
 
 
 
        my @clmn_type = ('Glib::String',  # => G_TYPE_STRING
        my @clmn_type = ('Glib::String',  # => G_TYPE_STRING
                                    'Glib::String',
                                    'Glib::String',
                                    'Glib::String'); # you get the idea
                                    'Glib::String'); # you get the idea
 
 
        my @clmns = ("Routing Summary", " ", " ");
        my @clmns = ("Routing Summary", " ", " ");
 
 
        my $list=       gen_list_store (\@data,\@clmn_type,\@clmns);
        my $list=       gen_list_store (\@data,\@clmn_type,\@clmns);
 
 
 
 
        add_widget_to_scrolled_win($list,$sc_win);
        add_widget_to_scrolled_win($list,$sc_win);
 
 
        my $charts =  gen_routing_charts($self,$info);
        my $charts =  gen_routing_charts($self,$info);
 
 
        my $v1=gen_vpaned($sc_win,.25,$charts);
        my $v1=gen_vpaned($sc_win,.25,$charts);
 
 
        $sc_win->show_all;
        $sc_win->show_all;
 
 
        return $v1;
        return $v1;
 
 
}
}
 
 
 
 
sub gen_routing_charts{
sub gen_routing_charts{
 
 
        my ($self,$info)=@_;
        my ($self,$info)=@_;
 
 
        my @pages =(
        my @pages =(
        {page_name=>" # Routers in all Paths", page_num=>0},
        {page_name=>" # Routers in all Paths", page_num=>0},
        {page_name=>" # Links in all Paths ", page_num=>1}
        {page_name=>" # Links in all Paths ", page_num=>1}
);
);
 
 
 
 
 
 
my @charts = (
my @charts = (
        { 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},
        { 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},
        { 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},
        { 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},
        #{ 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},
        #{ 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},
        #{ 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},
        #{ 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},
        #{ 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},
        #{ 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},
 
 
        );
        );
 
 
 
 
        my $chart   =gen_multiple_charts  ($self,\@pages,\@charts,.3);
        my $chart   =gen_multiple_charts  ($self,\@pages,\@charts,.3);
    return $chart;
    return $chart;
 
 
}
}
 
 
 
 
 
 
 
 
sub show_paths_between_two_endps{
sub show_paths_between_two_endps{
        my ($self,$info)= @_;
        my ($self,$info)= @_;
        my $table=def_table(20,20,FALSE);
        my $table=def_table(20,20,FALSE);
 
 
        my $row-=0;
        my $row-=0;
        my $col=0;
        my $col=0;
 
 
        my $src = $self->object_get_attribute("SELECT_PATH","src");
        my $src = $self->object_get_attribute("SELECT_PATH","src");
        my $dst = $self->object_get_attribute("SELECT_PATH","dst");
        my $dst = $self->object_get_attribute("SELECT_PATH","dst");
 
 
        my @acyclic_turns;
        my @acyclic_turns;
        my $path_select= $self->object_get_attribute("routing_auto",'PATH_SELECT');
        my $path_select= $self->object_get_attribute("routing_auto",'PATH_SELECT');
        if ($path_select ne "all-paths"){
        if ($path_select ne "all-paths"){
                 my $ref = $self->object_get_attribute('routing_auto','acyclic_turns_model');
                 my $ref = $self->object_get_attribute('routing_auto','acyclic_turns_model');
                 if(defined $ref) {
                 if(defined $ref) {
                        @acyclic_turns = @{$ref};
                        @acyclic_turns = @{$ref};
                 }else{
                 }else{
                        add_colored_info($info,"Info:No acyclic route model is selected\n",'green');
                        add_colored_info($info,"Info:No acyclic route model is selected\n",'green');
 
 
                 }
                 }
        }
        }
 
 
 
 
 
 
 
 
 
 
        if(defined $src && defined $dst ){
        if(defined $src && defined $dst ){
                my $s= $self->object_get_attribute("$src","NAME");
                my $s= $self->object_get_attribute("$src","NAME");
                my $d= $self->object_get_attribute("$dst","NAME");
                my $d= $self->object_get_attribute("$dst","NAME");
                $table->attach (def_label("Select path between $s to $d" ),$col,$col+10,$row,$row+1,'fill','shrink',2,2);
                $table->attach (def_label("Select path between $s to $d" ),$col,$col+10,$row,$row+1,'fill','shrink',2,2);
                add_info($info,"get list of all paths between $s to $d \n") if (defined $info);
                add_info($info,"get list of all paths between $s to $d \n") if (defined $info);
                $row=1;
                $row=1;
                my ($ref1,$ref2)= ($path_select eq "all-paths") ?  get_all_paths_between_two_endps($self,$src, $dst):
                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);
                get_all_paths_between_two_endps_using_accyclic_turn($self,$src, $dst,\@acyclic_turns);
 
 
 
 
                my @paths = @{$ref1};
                my @paths = @{$ref1};
                my @ports= @{$ref2};
                my @ports= @{$ref2};
                my $n=0;
                my $n=0;
                my $select = $self->object_get_attribute('Route',"${src}::$dst");
                my $select = $self->object_get_attribute('Route',"${src}::$dst");
                foreach my $p (@paths){
                foreach my $p (@paths){
                        my $scal;
                        my $scal;
                        my $selp;
                        my $selp;
                        my $path_num=$n;
                        my $path_num=$n;
                        my $path=$p;
                        my $path=$p;
                        foreach my $q ( @{$p}){
                        foreach my $q ( @{$p}){
                                my $inst=$self->object_get_attribute("$q",'NAME');
                                my $inst=$self->object_get_attribute("$q",'NAME');
                                $scal= (defined $scal)? $scal."->$inst" : $inst;
                                $scal= (defined $scal)? $scal."->$inst" : $inst;
                        }
                        }
 
 
                        foreach my $q ( @{$select}){
                        foreach my $q ( @{$select}){
                                my $inst=$self->object_get_attribute("$q",'NAME');
                                my $inst=$self->object_get_attribute("$q",'NAME');
                                $selp= (defined $selp)? $selp."->$inst" : $inst;
                                $selp= (defined $selp)? $selp."->$inst" : $inst;
                        }
                        }
 
 
 
 
                        my $check= gen_checkbutton();
                        my $check= gen_checkbutton();
                        #print "if($select eq $path)";
                        #print "if($select eq $path)";
                        if(defined $select && defined $scal && defined $selp) {if($selp eq $scal) {$check->set_active(TRUE);}}
                        if(defined $select && defined $scal && defined $selp) {if($selp eq $scal) {$check->set_active(TRUE);}}
                        else {$check->set_active(FALSE);}
                        else {$check->set_active(FALSE);}
 
 
                        $check-> signal_connect("toggled" => sub{
                        $check-> signal_connect("toggled" => sub{
                                if($check->get_active()) {
                                if($check->get_active()) {
 
 
                                        $self->object_add_attribute('Route',"${src}::$dst",$path);
                                        $self->object_add_attribute('Route',"${src}::$dst",$path);
                                }
                                }
                                else {
                                else {
 
 
                                        $self->object_add_attribute('Route',"${src}::$dst",undef);
                                        $self->object_add_attribute('Route',"${src}::$dst",undef);
                                }
                                }
                                set_gui_status($self,"ref",1);
                                set_gui_status($self,"ref",1);
                        });
                        });
 
 
 
 
                        my $label =gen_label_in_left("$scal");
                        my $label =gen_label_in_left("$scal");
                        $table->attach ($check ,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $col++;
                        $table->attach ($check ,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $col++;
                        $table->attach ($label ,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $row++;$col=0;
                        $table->attach ($label ,  $col, $col+1,$row,$row+1,'shrink','shrink',2,2); $row++;$col=0;
 
 
                        $n++;
                        $n++;
                }
                }
 
 
 
 
        }
        }
 
 
        return add_widget_to_scrolled_win($table);
        return add_widget_to_scrolled_win($table);
 
 
}
}
 
 
 
 
 
 
##########
##########
#       save
#       save
##########
##########
sub save_network {
sub save_network {
        my ($self)=@_;
        my ($self)=@_;
        # read topology  name
        # read topology  name
        my $name=$self->object_get_attribute('save_as');
        my $name=$self->object_get_attribute('save_as');
        #print $name;
        #print $name;
        my $s= (!defined $name)? 0 : (length($name)==0)? 0 :1;
        my $s= (!defined $name)? 0 : (length($name)==0)? 0 :1;
        if ($s == 0){
        if ($s == 0){
                message_dialog("Please set the topology name!");
                message_dialog("Please set the topology name!");
                return 0;
                return 0;
        }
        }
        # Write object file
        # Write object file
        my $fname = "$name.NWM";
        my $fname = "$name.NWM";
        open(FILE,  ">lib/netwmaker/$fname") || die "Can not open: $!";
        open(FILE,  ">lib/netwmaker/$fname") || die "Can not open: $!";
        print FILE perl_file_header("$fname");
        print FILE perl_file_header("$fname");
        print FILE Data::Dumper->Dump([\%$self],["nwmaker"]);
        print FILE Data::Dumper->Dump([\%$self],["nwmaker"]);
        close(FILE) || die "Error closing file: $!";
        close(FILE) || die "Error closing file: $!";
        message_dialog("Current network maker state is saved as lib/netwmaker/$fname!");
        message_dialog("Current network maker state is saved as lib/netwmaker/$fname!");
        return 1;
        return 1;
}
}
 
 
sub get_all_endp_ids{
sub get_all_endp_ids{
        my $self=shift;
        my $self=shift;
        my %e=  $self->object_get_attribute("E");
        my %e=  $self->object_get_attribute("E");
        my @list = sort keys %e;
        my @list = sort keys %e;
        return @list;
        return @list;
 
 
}
}
 
 
 
 
 
 
#############
#############
#    load
#    load
#############
#############
 
 
sub load_net_maker{
sub load_net_maker{
    my ($self,$info)=@_;
    my ($self,$info)=@_;
    my $file;
    my $file;
        my $dialog =  gen_file_dialog (undef, 'NWM');
        my $dialog =  gen_file_dialog (undef, 'NWM');
 
 
 
 
    my $dir = Cwd::getcwd();
    my $dir = Cwd::getcwd();
    $dialog->set_current_folder ("$dir/lib/netwmaker")    ;
    $dialog->set_current_folder ("$dir/lib/netwmaker")    ;
 
 
    if ( "ok" eq $dialog->run ) {
    if ( "ok" eq $dialog->run ) {
        $file = $dialog->get_filename;
        $file = $dialog->get_filename;
        my ($name,$path,$suffix) = fileparse("$file",qr"\..[^.]*$");
        my ($name,$path,$suffix) = fileparse("$file",qr"\..[^.]*$");
        if($suffix eq '.NWM'){
        if($suffix eq '.NWM'){
            my ($pp,$r,$err) = regen_object($file );
            my ($pp,$r,$err) = regen_object($file );
            if ($r){
            if ($r){
                add_info($info,"**Error: cannot open $file file: $err\n");
                add_info($info,"**Error: cannot open $file file: $err\n");
                 $dialog->destroy;
                 $dialog->destroy;
                return;
                return;
            }
            }
 
 
 
 
            clone_obj($self,$pp);
            clone_obj($self,$pp);
 
 
 
 
        }
        }
     }
     }
     $dialog->destroy;
     $dialog->destroy;
     set_gui_status($self,"ref",1)
     set_gui_status($self,"ref",1)
}
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
sub get_all_paths_between_two_endps{
sub get_all_paths_between_two_endps{
        my ($self,$src, $dst)=@_;
        my ($self,$src, $dst)=@_;
        my @proceed_nodes;
        my @proceed_nodes;
        my @head_nodes;
        my @head_nodes;
 
 
        my $offset = $self->object_get_attribute('routing_auto','OFFSET');
        my $offset = $self->object_get_attribute('routing_auto','OFFSET');
        my $max_len = $self->object_get_attribute('routing_auto','MAX_LENGTH');
        my $max_len = $self->object_get_attribute('routing_auto','MAX_LENGTH');
 
 
        push (@head_nodes,$src);
        push (@head_nodes,$src);
        push (@proceed_nodes,$src);
        push (@proceed_nodes,$src);
 
 
        my @paths;
        my @paths;
        my @ports;
        my @ports;
        my @paths_to_dst;
        my @paths_to_dst;
        my @ports_to_dst;
        my @ports_to_dst;
 
 
        my @first_path=($src);
        my @first_path=($src);
        my @first_port=(0);
        my @first_port=(0);
        $paths[0]=\@first_path;
        $paths[0]=\@first_path;
        $ports[0]=\@first_port;
        $ports[0]=\@first_port;
 
 
        # select one path
        # select one path
        my $n=0;
        my $n=0;
        my $min_dist=1000000;
        my $min_dist=1000000;
        do{
        do{
                my @current_path= @{$paths[$n]};
                my @current_path= @{$paths[$n]};
                my @current_port= @{$ports[$n]};
                my @current_port= @{$ports[$n]};
                # get head node
                # get head node
                my $head_node =         $current_path[-1];
                my $head_node =         $current_path[-1];
                if(defined $head_node){
                if(defined $head_node){
                        # get connected nodes for all ports 
                        # get connected nodes for all ports 
                        #print "hn=$head_node\n";
                        #print "hn=$head_node\n";
                        my $pnum =  $self->object_get_attribute($head_node,'PNUM');
                        my $pnum =  $self->object_get_attribute($head_node,'PNUM');
 
 
                        for (my $i=0;$i<$pnum; $i++){
                        for (my $i=0;$i<$pnum; $i++){
                                my @new_path=@current_path;
                                my @new_path=@current_path;
                                my @new_ports=@current_port;
                                my @new_ports=@current_port;
                                my $src_port = "Port[${i}]";
                                my $src_port = "Port[${i}]";
                                my $connect = $self->{$head_node}{'PCONNECT'}{$src_port};
                                my $connect = $self->{$head_node}{'PCONNECT'}{$src_port};
                                if(defined $connect){
                                if(defined $connect){
                                        my ($node,$pnode)=split(/\s*,\s*/,$connect);
                                        my ($node,$pnode)=split(/\s*,\s*/,$connect);
                                        #add connected nodes to head_nodes if they are not in path before
                                        #add connected nodes to head_nodes if they are not in path before
                                        if(!defined get_scolar_pos($node,@new_path)){
                                        if(!defined get_scolar_pos($node,@new_path)){
                                                my $size=scalar @new_path;
                                                my $size=scalar @new_path;
                                                #if ($min_dist > $size){
                                                #if ($min_dist > $size){
                                                if( ($min_dist+$offset) > $size &&   $max_len>=$size){
                                                if( ($min_dist+$offset) > $size &&   $max_len>=$size){
 
 
 
 
                                                        push (@new_path,$node);
                                                        push (@new_path,$node);
                                                        push (@new_ports,$pnode);
                                                        push (@new_ports,$pnode);
                                                        push (@paths,\@new_path);
                                                        push (@paths,\@new_path);
                                                        push (@ports,\@new_ports);
                                                        push (@ports,\@new_ports);
                                                        if($node eq $dst){
                                                        if($node eq $dst){
                                                                push(@paths_to_dst,\@new_path);
                                                                push(@paths_to_dst,\@new_path);
                                                                push(@ports_to_dst,\@new_ports);
                                                                push(@ports_to_dst,\@new_ports);
                                                                $min_dist=$size+1 if ($min_dist > $size);
                                                                $min_dist=$size+1 if ($min_dist > $size);
                                                        }
                                                        }
                                                }
                                                }
                                        } #if
                                        } #if
                                }
                                }
                        }#for
                        }#for
                }
                }
                $n++;
                $n++;
        }while( defined $paths[$n]);
        }while( defined $paths[$n]);
 
 
        #print "\@paths_to_dst". Dumper(@paths_to_dst). "\n \@ports_to_dst". Dumper(@ports_to_dst) . "\n" ;
        #print "\@paths_to_dst". Dumper(@paths_to_dst). "\n \@ports_to_dst". Dumper(@ports_to_dst) . "\n" ;
 
 
        return (\@paths_to_dst,\@ports_to_dst);
        return (\@paths_to_dst,\@ports_to_dst);
 
 
}
}
 
 
sub get_path_from_turns {
sub get_path_from_turns {
        my ($self,$ref)=@_;
        my ($self,$ref)=@_;
        my @new_turn = @{$ref} if(defined $ref);
        my @new_turn = @{$ref} if(defined $ref);
        my @path_nodes;
        my @path_nodes;
        my @path_ports;
        my @path_ports;
        my $st2;
        my $st2;
        foreach my $code (@new_turn){
        foreach my $code (@new_turn){
                my $pn2  =  $code & 0xF;
                my $pn2  =  $code & 0xF;
                $code >>=4;
                $code >>=4;
                my $rn2  = $code & 0xFFF;
                my $rn2  = $code & 0xFFF;
                $code >>=12;
                $code >>=12;
                my $pn1 =$code & 0xF;
                my $pn1 =$code & 0xF;
                $code >>=4;
                $code >>=4;
                my $rn1=$code;
                my $rn1=$code;
                my $st1 = ($pn1==1)? "ENDP_${rn1}" : "ROUTER${pn1}_${rn1}";
                my $st1 = ($pn1==1)? "ENDP_${rn1}" : "ROUTER${pn1}_${rn1}";
                $st2 = ($pn2==1)? "ENDP_${rn2}"    : "ROUTER${pn2}_${rn2}";
                $st2 = ($pn2==1)? "ENDP_${rn2}"    : "ROUTER${pn2}_${rn2}";
                push(@path_nodes,$st1);
                push(@path_nodes,$st1);
        }
        }
        push(@path_nodes,$st2);
        push(@path_nodes,$st2);
 
 
        @path_ports=(0);
        @path_ports=(0);
        for (my $i=0; $i<scalar @path_nodes-1; $i++){
        for (my $i=0; $i<scalar @path_nodes-1; $i++){
                my ($p1,$p2) =get_connection_port_num_between_two_nodes($self,$path_nodes[$i],$path_nodes[$i+1]);
                my ($p1,$p2) =get_connection_port_num_between_two_nodes($self,$path_nodes[$i],$path_nodes[$i+1]);
                push(@path_ports,"Port[$p2]");
                push(@path_ports,"Port[$p2]");
        }
        }
 
 
        return (\@path_nodes,\@path_ports);
        return (\@path_nodes,\@path_ports);
 
 
}
}
 
 
sub get_all_paths_between_two_endps_using_accyclic_turn{
sub get_all_paths_between_two_endps_using_accyclic_turn{
        my ($self,$src, $dst,$ref)=@_;
        my ($self,$src, $dst,$ref)=@_;
        my @proceed_turns;
        my @proceed_turns;
        my @head_turns;
        my @head_turns;
        my @accyclic_turn= @{$ref};
        my @accyclic_turn= @{$ref};
 
 
        my $offset = $self->object_get_attribute('routing_auto','OFFSET');
        my $offset = $self->object_get_attribute('routing_auto','OFFSET');
        my $max_len = $self->object_get_attribute('routing_auto','MAX_LENGTH');
        my $max_len = $self->object_get_attribute('routing_auto','MAX_LENGTH');
 
 
        my @paths_to_dst;
        my @paths_to_dst;
        my @ports_to_dst;
        my @ports_to_dst;
 
 
        my %graph;
        my %graph;
 
 
        foreach my $str (@accyclic_turn){
        foreach my $str (@accyclic_turn){
                my ($s1,$s2) = split /\s/, $str;
                my ($s1,$s2) = split /\s/, $str;
                push(@{$graph{$s1}},$s2);
                push(@{$graph{$s1}},$s2);
        }
        }
 
 
        my $start_turns;
        my $start_turns;
        my $ended_turns;
        my $ended_turns;
        my $src_port = "Port[0]";
        my $src_port = "Port[0]";
        my $connect = $self->{$src}{'PCONNECT'}{$src_port};
        my $connect = $self->{$src}{'PCONNECT'}{$src_port};
        if(defined $connect){
        if(defined $connect){
                my ($node,$pnode)=split(/\s*,\s*/,$connect);
                my ($node,$pnode)=split(/\s*,\s*/,$connect);
                $start_turns =  get_turn_code("${src}::${node}");
                $start_turns =  get_turn_code("${src}::${node}");
        }
        }
 
 
        $connect = $self->{$dst}{'PCONNECT'}{$src_port};
        $connect = $self->{$dst}{'PCONNECT'}{$src_port};
        if(defined $connect){
        if(defined $connect){
                my ($node,$pnode)=split(/\s*,\s*/,$connect);
                my ($node,$pnode)=split(/\s*,\s*/,$connect);
                $ended_turns =  get_turn_code("${node}::${dst}");
                $ended_turns =  get_turn_code("${node}::${dst}");
        }
        }
 
 
        push (@head_turns,$start_turns);
        push (@head_turns,$start_turns);
    push (@proceed_turns,$start_turns);
    push (@proceed_turns,$start_turns);
 
 
 
 
 
 
 
 
 
 
        my @turns;
        my @turns;
        my @ports;
        my @ports;
        my @turns_to_dst;
        my @turns_to_dst;
        my @first_turn=($start_turns);
        my @first_turn=($start_turns);
 
 
        $turns[0]=\@first_turn;
        $turns[0]=\@first_turn;
 
 
 
 
        # select one path
        # select one path
        my $n=0;
        my $n=0;
        my $min_dist=1000000;
        my $min_dist=1000000;
        do{
        do{
                my @current_turn= @{$turns[$n]};
                my @current_turn= @{$turns[$n]};
                # get head node
                # get head node
                my $head_turn =         $current_turn[-1];
                my $head_turn =         $current_turn[-1];
                if(defined $head_turn){
                if(defined $head_turn){
                        #get all turns 
                        #get all turns 
                        my @all_fwd_turns = @{$graph{$head_turn}} if (defined $graph{$head_turn});
                        my @all_fwd_turns = @{$graph{$head_turn}} if (defined $graph{$head_turn});
 
 
                        foreach my $fwd_turn (@all_fwd_turns){
                        foreach my $fwd_turn (@all_fwd_turns){
                                my @new_turn=@current_turn;
                                my @new_turn=@current_turn;
                                #add new turn to head_turns if they are not in turns before
                                #add new turn to head_turns if they are not in turns before
                                if(!defined get_scolar_pos($fwd_turn,@new_turn)){
                                if(!defined get_scolar_pos($fwd_turn,@new_turn)){
                                        my $size=scalar @new_turn;
                                        my $size=scalar @new_turn;
                                        #if ($min_dist > $size){
                                        #if ($min_dist > $size){
                                        if( ($min_dist+$offset) > $size &&   $max_len>=$size){
                                        if( ($min_dist+$offset) > $size &&   $max_len>=$size){
                                                push (@new_turn,$fwd_turn);
                                                push (@new_turn,$fwd_turn);
                                                push (@turns,\@new_turn);
                                                push (@turns,\@new_turn);
                                                if($fwd_turn eq $ended_turns){
                                                if($fwd_turn eq $ended_turns){
                                                        push(@turns_to_dst,\@new_turn);
                                                        push(@turns_to_dst,\@new_turn);
                                                        my ($path_ref,$port_ref) = get_path_from_turns($self,\@new_turn);
                                                        my ($path_ref,$port_ref) = get_path_from_turns($self,\@new_turn);
                                                        push(@paths_to_dst,$path_ref);
                                                        push(@paths_to_dst,$path_ref);
                                                        push(@ports_to_dst,$port_ref);
                                                        push(@ports_to_dst,$port_ref);
                                                        $min_dist=$size+1 if ($min_dist > $size);
                                                        $min_dist=$size+1 if ($min_dist > $size);
                                                } #if
                                                } #if
 
 
                                        }#if
                                        }#if
                                }#if
                                }#if
                        }#foreach
                        }#foreach
                }#if
                }#if
        $n++;
        $n++;
        }while( defined $turns[$n]);
        }while( defined $turns[$n]);
 
 
 
 
 
 
        #print "\@paths_to_dst". Dumper(@paths_to_dst). "\n \@ports_to_dst". Dumper(@ports_to_dst) . "\n" ;
        #print "\@paths_to_dst". Dumper(@paths_to_dst). "\n \@ports_to_dst". Dumper(@ports_to_dst) . "\n" ;
 
 
 
 
        return (\@paths_to_dst,\@ports_to_dst);
        return (\@paths_to_dst,\@ports_to_dst);
 
 
}
}
 
 
 
 
 
 
 
 
sub get_turn_code {
sub get_turn_code {
        my $turn =shift;
        my $turn =shift;
        my ($pn1,$rn1,$pn2,$rn2)= sscanf( "ROUTER%u_%u::ROUTER%u_%u",$turn);
        my ($pn1,$rn1,$pn2,$rn2)= sscanf( "ROUTER%u_%u::ROUTER%u_%u",$turn);
        if(defined $rn1){
        if(defined $rn1){
                return ( ($rn1 << 20)+ ($pn1 << 16) +  ($rn2 << 4) +  $pn2);
                return ( ($rn1 << 20)+ ($pn1 << 16) +  ($rn2 << 4) +  $pn2);
        }
        }
        ($rn1,$pn2,$rn2)= sscanf( "ENDP_%u::ROUTER%u_%u",$turn);
        ($rn1,$pn2,$rn2)= sscanf( "ENDP_%u::ROUTER%u_%u",$turn);
        if(defined $rn1){
        if(defined $rn1){
                return ( ($rn1 << 20)+ (1 << 16) +  ($rn2 << 4) +  $pn2);
                return ( ($rn1 << 20)+ (1 << 16) +  ($rn2 << 4) +  $pn2);
        }
        }
        ($pn1,$rn1,$rn2)= sscanf( "ROUTER%u_%u::ENDP_%u",$turn);
        ($pn1,$rn1,$rn2)= sscanf( "ROUTER%u_%u::ENDP_%u",$turn);
        return ( ($rn1 << 20)+ ($pn1 << 16) +  ($rn2 << 4) +  1);
        return ( ($rn1 << 20)+ ($pn1 << 16) +  ($rn2 << 4) +  1);
}
}
 
 
sub get_turn_str {
sub get_turn_str {
        my $code =shift;
        my $code =shift;
        my $pn2  =  $code & 0xF;
        my $pn2  =  $code & 0xF;
        $code >>=4;
        $code >>=4;
        my $rn2  = $code & 0xFFF;
        my $rn2  = $code & 0xFFF;
        $code >>=12;
        $code >>=12;
        my $pn1 =$code & 0xF;
        my $pn1 =$code & 0xF;
        $code >>=4;
        $code >>=4;
        my $rn1=$code;
        my $rn1=$code;
        my $st1 = ($pn1==1)? "ENDP_${rn1}" : "ROUTER${pn1}_${rn1}";
        my $st1 = ($pn1==1)? "ENDP_${rn1}" : "ROUTER${pn1}_${rn1}";
        my $st2 = ($pn2==1)? "ENDP_${rn2}" : "ROUTER${pn2}_${rn2}";
        my $st2 = ($pn2==1)? "ENDP_${rn2}" : "ROUTER${pn2}_${rn2}";
 
 
        return   "${st1}::${st2}";
        return   "${st1}::${st2}";
}
}
 
 
sub get_turn_involved_routrs{
sub get_turn_involved_routrs{
        my ($s1,$s2,$info)=@_;
        my ($s1,$s2,$info)=@_;
        my ($r1,$ra2) = split /::/, $s1;
        my ($r1,$ra2) = split /::/, $s1;
        my ($rb2,$r3) = split /::/, $s2;
        my ($rb2,$r3) = split /::/, $s2;
        add_colored_info($info,"Error in turn format. $s1 -> $s2 : $ra2 should be equal with $rb2 ",'red') if($ra2 ne $rb2);
        add_colored_info($info,"Error in turn format. $s1 -> $s2 : $ra2 should be equal with $rb2 ",'red') if($ra2 ne $rb2);
        return ($r1,$ra2,$r3);
        return ($r1,$ra2,$r3);
}
}
 
 
sub get_path_edges_graph_file{
sub get_path_edges_graph_file{
        my ($ref1,$ref2) = @_;
        my ($ref1,$ref2) = @_;
        my @a_nodes = @{$ref1};
        my @a_nodes = @{$ref1};
        my %graph   = %{$ref2};
        my %graph   = %{$ref2};
 
 
        my $old_r;
        my $old_r;
        foreach my $r (@a_nodes){
        foreach my $r (@a_nodes){
 
 
                if(defined $old_r){
                if(defined $old_r){
                        my $str1 = "$old_r $r";
                        my $str1 = "$old_r $r";
                        my $n1  = get_turn_code($old_r);
                        my $n1  = get_turn_code($old_r);
                        my $n2  = get_turn_code($r);
                        my $n2  = get_turn_code($r);
                        my $str2 = "$n1 $n2";
                        my $str2 = "$n1 $n2";
                        $graph{$str2}=$str1;
                        $graph{$str2}=$str1;
                }
                }
                $old_r=$r;
                $old_r=$r;
        }
        }
        return %graph;
        return %graph;
}
}
 
 
 
 
 
 
 
 
sub get_forbiden_turns_old {
sub get_forbiden_turns_old {
#sub gen_aciclic_turn_graph {   
#sub gen_aciclic_turn_graph {   
        my ($self,$info)=@_;
        my ($self,$info)=@_;
        my @forbiden_turn;
        my @forbiden_turn;
        add_info($info,"Calculate forbidden turns to avoid deadlock \n");
        add_info($info,"Calculate forbidden turns to avoid deadlock \n");
        #step 1: get the list of all  minimal paths between all source and destination pairs
        #step 1: get the list of all  minimal paths between all source and destination pairs
        my $graph='';
        my $graph='';
        my $graph_coded='';
        my $graph_coded='';
        my @all_endpoints=get_list_of_all_endpoints($self);
        my @all_endpoints=get_list_of_all_endpoints($self);
 
 
        my %edge_graph;
        my %edge_graph;
        foreach  my $src  (@all_endpoints ){
        foreach  my $src  (@all_endpoints ){
                foreach  my $dst  (@all_endpoints ){
                foreach  my $dst  (@all_endpoints ){
                        if($src ne $dst){
                        if($src ne $dst){
                                my ($paths_to_dst,$ports_to_dst) = get_all_paths_between_two_endps($self,$src, $dst);
                                my ($paths_to_dst,$ports_to_dst) = get_all_paths_between_two_endps($self,$src, $dst);
                                foreach my $path (@{$paths_to_dst}) {
                                foreach my $path (@{$paths_to_dst}) {
                                        if (defined $path){
                                        if (defined $path){
                                                #path counting
                                                #path counting
                                                my @a_nodes=    get_adjacent_node_in_a_path($path);#get_adjacent_router_in_a_path($path);
                                                my @a_nodes=    get_adjacent_node_in_a_path($path);#get_adjacent_router_in_a_path($path);
                                                print "@a_nodes = \@a_nodes \n";
                                                print "@a_nodes = \@a_nodes \n";
                                                %edge_graph = get_path_edges_graph_file (\@a_nodes,\%edge_graph);
                                                %edge_graph = get_path_edges_graph_file (\@a_nodes,\%edge_graph);
                                                #$graph  =$graph. $str1;
                                                #$graph  =$graph. $str1;
                                                #$graph_coded = $graph_coded . $str2;
                                                #$graph_coded = $graph_coded . $str2;
                                        }#defined path  
                                        }#defined path  
                                }#foreach       
                                }#foreach       
                        }#if                    
                        }#if                    
                }#froeach                               
                }#froeach                               
 
 
        }#froeach       
        }#froeach       
 
 
        foreach my $p (sort keys %edge_graph){
        foreach my $p (sort keys %edge_graph){
                $graph_coded  .="$p\n";
                $graph_coded  .="$p\n";
                $graph .= "$edge_graph{$p}\n";
                $graph .= "$edge_graph{$p}\n";
        }
        }
 
 
        my $tmp_dir  = "$ENV{'PRONOC_WORK'}/tmp";
        my $tmp_dir  = "$ENV{'PRONOC_WORK'}/tmp";
        save_file ("$tmp_dir/paths_graph.edges",$graph);
        save_file ("$tmp_dir/paths_graph.edges",$graph);
        save_file ("$tmp_dir/paths_graph_coded.edges",$graph_coded);
        save_file ("$tmp_dir/paths_graph_coded.edges",$graph_coded);
 
 
 
 
        #remove old files 
        #remove old files 
        my @files = File::Find::Rule->file()
        my @files = File::Find::Rule->file()
                            ->name( 'paths_graph_coded_removed*.edges')
                            ->name( 'paths_graph_coded_removed*.edges')
                            ->in( "$tmp_dir" );
                            ->in( "$tmp_dir" );
        foreach my $f (@files){
        foreach my $f (@files){
                unlink  $f if (-f "$f");
                unlink  $f if (-f "$f");
        }
        }
 
 
        # run remove_cycle_edges_by_dfs on coded graph 
        # run remove_cycle_edges_by_dfs on coded graph 
        my $remover_dire = get_project_dir()."/mpsoc/remove_cycle/";
        my $remover_dire = get_project_dir()."/mpsoc/remove_cycle/";
        my $cmd  =  "cd $remover_dire;
        my $cmd  =  "cd $remover_dire;
        python  break_cycles.py  -g $tmp_dir/paths_graph_coded.edges;
        python  break_cycles.py  -g $tmp_dir/paths_graph_coded.edges;
        python remove_cycle_edges_by_dfs.py -g $tmp_dir/paths_graph_coded.edges;
        python remove_cycle_edges_by_dfs.py -g $tmp_dir/paths_graph_coded.edges;
        python remove_cycle_edges_by_minimum_feedback_arc_set_greedy.py  -g $tmp_dir/paths_graph_coded.edges";
        python remove_cycle_edges_by_minimum_feedback_arc_set_greedy.py  -g $tmp_dir/paths_graph_coded.edges";
        #sort paths_graph_coded.edges | uniq > newfile.db
        #sort paths_graph_coded.edges | uniq > newfile.db
 
 
        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
        if(length $stderr>1){
        if(length $stderr>1){
                add_colored_info($info,"$stderr\n",'red');
                add_colored_info($info,"$stderr\n",'red');
        }else {
        }else {
                add_info($info,"$stdout\n");
                add_info($info,"$stdout\n");
        }
        }
        # find the files with the list edges removal
        # find the files with the list edges removal
        @files = File::Find::Rule->file()
        @files = File::Find::Rule->file()
                         ->name( 'paths_graph_coded_removed*.edges')
                         ->name( 'paths_graph_coded_removed*.edges')
                         ->in( "$tmp_dir" );
                         ->in( "$tmp_dir" );
 
 
 
 
        my $line_num;
        my $line_num;
        my $out;
        my $out;
        foreach my $f (@files){
        foreach my $f (@files){
                my $n =count_file_line_num ($f);
                my $n =count_file_line_num ($f);
                $line_num = $n if(! defined $line_num);
                $line_num = $n if(! defined $line_num);
                if($n <= $line_num){
                if($n <= $line_num){
                        $out = $f;
                        $out = $f;
                        $line_num=$n;
                        $line_num=$n;
                }
                }
        }
        }
 
 
 
 
        # check if the output file is generated 
        # check if the output file is generated 
        if (-f $out ){
        if (-f $out ){
                add_colored_info($info,"$out file has been selected as it has the minimum number of edge removal of $line_num \n",'blue');
                add_colored_info($info,"$out file has been selected as it has the minimum number of edge removal of $line_num \n",'blue');
 
 
        } else {
        } else {
                add_colored_info($info,"could not find a paths_graph_coded_removed*.edges file.  Please make sure $cmd has been run successfully\n",'red');
                add_colored_info($info,"could not find a paths_graph_coded_removed*.edges file.  Please make sure $cmd has been run successfully\n",'red');
                return;
                return;
 
 
        }
        }
 
 
 
 
 
 
 
 
        my $r;
        my $r;
        open my $fh, "<", $out or $r = "$!\n";
        open my $fh, "<", $out or $r = "$!\n";
    if(defined $r) {
    if(defined $r) {
        add_colored_info($info,"Could not open $out: $r",'red');
        add_colored_info($info,"Could not open $out: $r",'red');
                return;
                return;
    }
    }
 
 
    add_colored_info($info,"List of forbidden turns: \n",'blue');
    add_colored_info($info,"List of forbidden turns: \n",'blue');
 
 
        while (my $line = <$fh>) {
        while (my $line = <$fh>) {
        chomp $line;
        chomp $line;
        $line=~ s/^\s+|\s+$//g;
        $line=~ s/^\s+|\s+$//g;
        my ($s1,$s2) = split /\s/, $line;
        my ($s1,$s2) = split /\s/, $line;
        $s1  = get_turn_str($s1);
        $s1  = get_turn_str($s1);
                $s2  = get_turn_str($s2);
                $s2  = get_turn_str($s2);
                my @turn = get_turn_involved_routrs($s1,$s2);
                my @turn = get_turn_involved_routrs($s1,$s2);
                my $str = get_path_instance_string($self,\@turn);
                my $str = get_path_instance_string($self,\@turn);
                my $string=join('->',@turn);
                my $string=join('->',@turn);
                push (@forbiden_turn, $string);
                push (@forbiden_turn, $string);
                add_info($info,"$str\n");
                add_info($info,"$str\n");
 
 
  }
  }
  return @forbiden_turn;
  return @forbiden_turn;
 
 
}
}
 
 
 
 
sub gen_turn_graph{
sub gen_turn_graph{
        my $self=shift;
        my $self=shift;
        my %edge_graph;
        my %edge_graph;
        my @all_nodes=get_list_of_all_nodes($self);
        my @all_nodes=get_list_of_all_nodes($self);
        foreach  my $node1  (@all_nodes ){
        foreach  my $node1  (@all_nodes ){
                my $pnum1=$self->object_get_attribute("$node1",'PNUM');
                my $pnum1=$self->object_get_attribute("$node1",'PNUM');
                for (my $i=0;$i<$pnum1; $i++){
                for (my $i=0;$i<$pnum1; $i++){
                        my $port1 = "Port[${i}]";
                        my $port1 = "Port[${i}]";
                        my $connect1 = $self->{$node1}{'PCONNECT'}{$port1};
                        my $connect1 = $self->{$node1}{'PCONNECT'}{$port1};
                        if (defined $connect1) {
                        if (defined $connect1) {
                                my ($node2,$Rport2)=split(/\s*,\s*/,$connect1);
                                my ($node2,$Rport2)=split(/\s*,\s*/,$connect1);
                                my $pnum2=$self->object_get_attribute("$node2",'PNUM');
                                my $pnum2=$self->object_get_attribute("$node2",'PNUM');
                                for (my $j=0;$j<$pnum2; $j++){
                                for (my $j=0;$j<$pnum2; $j++){
                                        my $port2 = "Port[${j}]";
                                        my $port2 = "Port[${j}]";
                                        my $connect2 = $self->{$node2}{'PCONNECT'}{$port2};
                                        my $connect2 = $self->{$node2}{'PCONNECT'}{$port2};
                                        if (defined $connect2) {
                                        if (defined $connect2) {
                                                my ($node3,$Rport3)=split(/\s*,\s*/,$connect2);
                                                my ($node3,$Rport3)=split(/\s*,\s*/,$connect2);
                                                if($node1 ne $node3){
                                                if($node1 ne $node3){
                                                        my @a_nodes=    ("${node1}::${node2}","${node2}::${node3}");
                                                        my @a_nodes=    ("${node1}::${node2}","${node2}::${node3}");
                                                        %edge_graph = get_path_edges_graph_file (\@a_nodes,\%edge_graph);
                                                        %edge_graph = get_path_edges_graph_file (\@a_nodes,\%edge_graph);
                                                }
                                                }
 
 
                                        }#if    
                                        }#if    
                                }#for           
                                }#for           
                        }#if
                        }#if
                }#for    
                }#for    
        }
        }
        return %edge_graph;
        return %edge_graph;
}
}
 
 
sub gen_aciclic_turn_graph {
sub gen_aciclic_turn_graph {
 
 
        my ($self,$info)=@_;
        my ($self,$info)=@_;
 
 
        #my @forbiden_turn;
        #my @forbiden_turn;
 
 
        add_info($info,"Generate an acyclic turn graph to avoid deadlock \n");
        add_info($info,"Generate an acyclic turn graph to avoid deadlock \n");
        #step 1: get the list of turn in topology. A turn is a path that include three nodes.
        #step 1: get the list of turn in topology. A turn is a path that include three nodes.
        my $graph='';
        my $graph='';
        my $graph_coded='';
        my $graph_coded='';
 
 
        my %edge_graph =gen_turn_graph($self);
        my %edge_graph =gen_turn_graph($self);
 
 
 
 
        foreach my $p (sort keys %edge_graph){
        foreach my $p (sort keys %edge_graph){
                $graph_coded  .="$p\n";
                $graph_coded  .="$p\n";
                $graph .= "$edge_graph{$p}\n";
                $graph .= "$edge_graph{$p}\n";
        }
        }
 
 
        my $tmp_dir  = "$ENV{'PRONOC_WORK'}/tmp";
        my $tmp_dir  = "$ENV{'PRONOC_WORK'}/tmp";
        save_file ("$tmp_dir/paths_graph.edges",$graph);
        save_file ("$tmp_dir/paths_graph.edges",$graph);
        save_file ("$tmp_dir/paths_graph_coded.edges",$graph_coded);
        save_file ("$tmp_dir/paths_graph_coded.edges",$graph_coded);
 
 
 
 
        #remove old files 
        #remove old files 
        my @files = File::Find::Rule->file()
        my @files = File::Find::Rule->file()
                            ->name( 'paths_graph_coded_removed*.edges')
                            ->name( 'paths_graph_coded_removed*.edges')
                            ->in( "$tmp_dir" );
                            ->in( "$tmp_dir" );
        foreach my $f (@files){
        foreach my $f (@files){
                unlink  $f if (-f "$f");
                unlink  $f if (-f "$f");
        }
        }
 
 
        # run remove_cycle_edges_by_dfs on coded graph 
        # run remove_cycle_edges_by_dfs on coded graph 
        my $remover_dire = get_project_dir()."/mpsoc/remove_cycle/";
        my $remover_dire = get_project_dir()."/mpsoc/remove_cycle/";
        my $cmd  =  "cd $remover_dire;
        my $cmd  =  "cd $remover_dire;
        python  break_cycles.py  -g $tmp_dir/paths_graph_coded.edges;
        python  break_cycles.py  -g $tmp_dir/paths_graph_coded.edges;
        python remove_cycle_edges_by_dfs.py -g $tmp_dir/paths_graph_coded.edges;
        python remove_cycle_edges_by_dfs.py -g $tmp_dir/paths_graph_coded.edges;
        python remove_cycle_edges_by_minimum_feedback_arc_set_greedy.py  -g $tmp_dir/paths_graph_coded.edges";
        python remove_cycle_edges_by_minimum_feedback_arc_set_greedy.py  -g $tmp_dir/paths_graph_coded.edges";
        #sort paths_graph_coded.edges | uniq > newfile.db
        #sort paths_graph_coded.edges | uniq > newfile.db
 
 
        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
        if(length $stderr>1){
        if(length $stderr>1){
                add_colored_info($info,"$stderr\n",'red');
                add_colored_info($info,"$stderr\n",'red');
        }else {
        }else {
                add_info($info,"$stdout\n");
                add_info($info,"$stdout\n");
        }
        }
        # find the files with the list edges removal
        # find the files with the list edges removal
        @files = File::Find::Rule->file()
        @files = File::Find::Rule->file()
                         ->name( 'paths_graph_coded_removed*.edges')
                         ->name( 'paths_graph_coded_removed*.edges')
                         ->in( "$tmp_dir" );
                         ->in( "$tmp_dir" );
        my $line_num;
        my $line_num;
        my $out;
        my $out;
        my %all_outs;
        my %all_outs;
        foreach my $f (@files){
        foreach my $f (@files){
 
 
                my $n =count_file_line_num ($f);
                my $n =count_file_line_num ($f);
                $all_outs{$f}=$n;
                $all_outs{$f}=$n;
 
 
        }
        }
 
 
        my @graph_array=sort keys %edge_graph;
        my @graph_array=sort keys %edge_graph;
        my @acyclic_turns;
        my @acyclic_turns;
        my @removed_edge;
        my @removed_edge;
        my $result=0;
        my $result=0;
 
 
        my %algorithms;
        my %algorithms;
 
 
        foreach my $file  (sort {$all_outs{$a} <=> $all_outs{$b}} keys %all_outs) {
        foreach my $file  (sort {$all_outs{$a} <=> $all_outs{$b}} keys %all_outs) {
                $line_num = $all_outs{$file};
                $line_num = $all_outs{$file};
                $out=$file;
                $out=$file;
                add_info($info,"check if $file file $line_num edges removal results in a connected graph\n");
                add_info($info,"check if $file file $line_num edges removal results in a connected graph\n");
 
 
                @removed_edge=();
                @removed_edge=();
                open(FILE,$file);
                open(FILE,$file);
                if (tell FILE ){
                if (tell FILE ){
                        add_colored_info($info,"Cannot open $file to read: $!\n",'red');
                        add_colored_info($info,"Cannot open $file to read: $!\n",'red');
                        return;
                        return;
                }
                }
        while (my $line = <FILE>) {
        while (my $line = <FILE>) {
                chomp($line);
                chomp($line);
                $line=~ s/^\s+|\s+$//g;
                $line=~ s/^\s+|\s+$//g;
                        push(@removed_edge,$line);
                        push(@removed_edge,$line);
                }
                }
        close FILE;
        close FILE;
 
 
                @acyclic_turns = get_diff_array ( \@graph_array , \@removed_edge );
                @acyclic_turns = get_diff_array ( \@graph_array , \@removed_edge );
 
 
 
 
 
 
                $result = check_diff_graph_be_connected ($self,\@acyclic_turns,$info);
                $result = check_diff_graph_be_connected ($self,\@acyclic_turns,$info);
                if($result == 1){
                if($result == 1){
                        my $alg = capture_string_between ('paths_graph_coded_removed_by_',$file,".edges");
                        my $alg = capture_string_between ('paths_graph_coded_removed_by_',$file,".edges");
                        $algorithms{$alg}=$line_num;
                        $algorithms{$alg}=$line_num;
                        #save @acyclic_turns for this algorithm
                        #save @acyclic_turns for this algorithm
                        open(F,  ">$tmp_dir/$alg.alg") || die "Can not creat: $!";
                        open(F,  ">$tmp_dir/$alg.alg") || die "Can not creat: $!";
                print F perl_file_header("$alg.alg");
                print F perl_file_header("$alg.alg");
                print F Data::Dumper->Dump([\@acyclic_turns],['turn']);
                print F Data::Dumper->Dump([\@acyclic_turns],['turn']);
                close(F ) || die "Error closing file: $!";
                close(F ) || die "Error closing file: $!";
                }
                }
 
 
 
 
        }
        }
 
 
        $self->object_add_attribute('routing_auto','acyclic_algorithms',\%algorithms);
        $self->object_add_attribute('routing_auto','acyclic_algorithms',\%algorithms);
 
 
 
 
    if (scalar (keys %algorithms) == 0){
    if (scalar (keys %algorithms) == 0){
                add_colored_info($info,"Unable to find any directed acyclic graph for routing\n",'red');
                add_colored_info($info,"Unable to find any directed acyclic graph for routing\n",'red');
                return;
                return;
    }
    }
 
 
        return;
        return;
        #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');
        #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');
 
 
 
 
 
 
    #add_colored_info($info,"List of forbidden turns: \n",'blue');
    #add_colored_info($info,"List of forbidden turns: \n",'blue');
 
 
        foreach my $line (@removed_edge) {
        foreach my $line (@removed_edge) {
        chomp $line;
        chomp $line;
        my ($s1,$s2) = split /\s/, $line;
        my ($s1,$s2) = split /\s/, $line;
        $s1  = get_turn_str($s1);
        $s1  = get_turn_str($s1);
                $s2  = get_turn_str($s2);
                $s2  = get_turn_str($s2);
                my @turn = get_turn_involved_routrs($s1,$s2);
                my @turn = get_turn_involved_routrs($s1,$s2);
                my $str = get_path_instance_string($self,\@turn);
                my $str = get_path_instance_string($self,\@turn);
                my $string=join('->',@turn);
                my $string=join('->',@turn);
  #             push (@forbiden_turn, $string);
  #             push (@forbiden_turn, $string);
                add_info($info,"$str\n");
                add_info($info,"$str\n");
 
 
        }
        }
 
 
 # $self->object_add_attribute('routing_auto','acyclic_turns',\@acyclic_turns);
 # $self->object_add_attribute('routing_auto','acyclic_turns',\@acyclic_turns);
 
 
#  return @forbiden_turn;
#  return @forbiden_turn;
 
 
}
}
 
 
 
 
 
 
sub check_diff_graph_be_connected {
sub check_diff_graph_be_connected {
        my ($self,$ref,$info)=@_;
        my ($self,$ref,$info)=@_;
        my @diff = @{$ref};
        my @diff = @{$ref};
        my %all_turns;
        my %all_turns;
        my %graph;
        my %graph;
 
 
        foreach my $str (@diff){
        foreach my $str (@diff){
                my ($s1,$s2) = split /\s/, $str;
                my ($s1,$s2) = split /\s/, $str;
                $all_turns{$s1}=1;
                $all_turns{$s1}=1;
                $all_turns{$s2}=1;
                $all_turns{$s2}=1;
                push(@{$graph{$s1}},$s2);
                push(@{$graph{$s1}},$s2);
 
 
        }
        }
 
 
        my @all_endpoints=get_list_of_all_endpoints($self);
        my @all_endpoints=get_list_of_all_endpoints($self);
        my @start_turns;
        my @start_turns;
        my @ended_turns;
        my @ended_turns;
        foreach my $endp (@all_endpoints){
        foreach my $endp (@all_endpoints){
 
 
                                my $src_port = "Port[0]";
                                my $src_port = "Port[0]";
                                my $connect = $self->{$endp}{'PCONNECT'}{$src_port};
                                my $connect = $self->{$endp}{'PCONNECT'}{$src_port};
                                if(defined $connect){
                                if(defined $connect){
                                        my ($node,$pnode)=split(/\s*,\s*/,$connect);
                                        my ($node,$pnode)=split(/\s*,\s*/,$connect);
                                        push (@start_turns,     get_turn_code("${endp}::${node}"));
                                        push (@start_turns,     get_turn_code("${endp}::${node}"));
                                        push (@ended_turns,     get_turn_code("${node}::${endp}"));
                                        push (@ended_turns,     get_turn_code("${node}::${endp}"));
                                }
                                }
        }
        }
 
 
        my $k=0;
        my $k=0;
        foreach my $s (@start_turns){# we should see all @ended_turns
        foreach my $s (@start_turns){# we should see all @ended_turns
 
 
                my @seen_turns=($s,$ended_turns[$k]);# put connect to itself connection as seen node.  
                my @seen_turns=($s,$ended_turns[$k]);# put connect to itself connection as seen node.  
                $k++;
                $k++;
                my @next_turns =@{$graph{$s}};
                my @next_turns =@{$graph{$s}};
 
 
                while (scalar @next_turns>0){
                while (scalar @next_turns>0){
 
 
 
 
                        #print "\@next_nodes = @next_nodes\n";
                        #print "\@next_nodes = @next_nodes\n";
                        #print "\@seen_nodes = @seen_nodes\n";
                        #print "\@seen_nodes = @seen_nodes\n";
                        my $n = pop (@next_turns);
                        my $n = pop (@next_turns);
                        #print "\$n  = $n \n";
                        #print "\$n  = $n \n";
                        my @nn;
                        my @nn;
                        @nn = @{$graph{$n}} if (defined $graph{$n});
                        @nn = @{$graph{$n}} if (defined $graph{$n});
                        #print "\@nn  = @nn \n";
                        #print "\@nn  = @nn \n";
                        push (@seen_turns, $n);
                        push (@seen_turns, $n);
                        @diff = get_diff_array ( \@nn , \@seen_turns );
                        @diff = get_diff_array ( \@nn , \@seen_turns );
                        #print "\@diff  = @diff \n";
                        #print "\@diff  = @diff \n";
                        push (@next_turns,@diff);
                        push (@next_turns,@diff);
 
 
                }
                }
 
 
                my @sep = get_diff_array (\@ended_turns,\@seen_turns);
                my @sep = get_diff_array (\@ended_turns,\@seen_turns);
 
 
                if( scalar @sep > 0) {
                if( scalar @sep > 0) {
                        my $s1  = get_turn_str($s);
                        my $s1  = get_turn_str($s);
                        my ($a1,$a2) = split ('::',$s1);
                        my ($a1,$a2) = split ('::',$s1);
                        my $n1=$self->object_get_attribute("$a1",'NAME');
                        my $n1=$self->object_get_attribute("$a1",'NAME');
 
 
                        $s1  = get_turn_str($sep[0]);
                        $s1  = get_turn_str($sep[0]);
                        my($a3,$a4) = split ('::',$s1);
                        my($a3,$a4) = split ('::',$s1);
                        my $n2=$self->object_get_attribute("$a4",'NAME');
                        my $n2=$self->object_get_attribute("$a4",'NAME');
 
 
                        add_info($info,"\t $n1 is not connected to $n2. \n");
                        add_info($info,"\t $n1 is not connected to $n2. \n");
                        return 0;
                        return 0;
                }
                }
 
 
 
 
        }
        }
 
 
 
 
        add_info($info,"\t All endpoints are connected in chanel dpenedency graph. \n");
        add_info($info,"\t All endpoints are connected in chanel dpenedency graph. \n");
        return 1;
        return 1;
 
 
}
}
 
 
 
 
 
 
sub get_path_instance_string {
sub get_path_instance_string {
        my ($self,$path_ref)=@_;
        my ($self,$path_ref)=@_;
        my @path = @{$path_ref};
        my @path = @{$path_ref};
        my @path_inst;
        my @path_inst;
        foreach my $p (@path){
        foreach my $p (@path){
                push (@path_inst, $self->object_get_attribute("$p",'NAME'));
                push (@path_inst, $self->object_get_attribute("$p",'NAME'));
 
 
        }
        }
        my $string=join('->',@path_inst);
        my $string=join('->',@path_inst);
        return $string;
        return $string;
}
}
 
 
 
 
sub remove_cycle_paths {
sub remove_cycle_paths {
        my ($self,$info,$paths_ref, $fturn_ref)=@_;
        my ($self,$info,$paths_ref, $fturn_ref)=@_;
        my @free_paths;
        my @free_paths;
        my @paths= @{$paths_ref};
        my @paths= @{$paths_ref};
        my @fturns= @{$fturn_ref};
        my @fturns= @{$fturn_ref};
        my $remove;
        my $remove;
 
 
 
 
 
 
        foreach my $path (@paths) {
        foreach my $path (@paths) {
                my @p = @$path;
                my @p = @$path;
                my $turn;
                my $turn;
                my $string=join('->',@p);
                my $string=join('->',@p);
                #print "$string\n";     
                #print "$string\n";     
                $remove=0;
                $remove=0;
                foreach my $t (@fturns){
                foreach my $t (@fturns){
                         if ($string =~ /$t-/){
                         if ($string =~ /$t-/){
                                $remove=1;
                                $remove=1;
                                $turn=$t;
                                $turn=$t;
                                last;
                                last;
                         }
                         }
 
 
                }
                }
                push (@free_paths,$path) if($remove == 0);
                push (@free_paths,$path) if($remove == 0);
                if($remove == 1){
                if($remove == 1){
                        my @ft = split /->/, $turn;
                        my @ft = split /->/, $turn;
                        add_info($info,"path ".get_path_instance_string($self,$path)." is removed due to turn ".get_path_instance_string($self,\@ft)."\n")
                        add_info($info,"path ".get_path_instance_string($self,$path)." is removed due to turn ".get_path_instance_string($self,\@ft)."\n")
                }
                }
        }
        }
        return @free_paths;
        return @free_paths;
}
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
sub auto_route {
sub auto_route {
        my ($self,$info)=@_;
        my ($self,$info)=@_;
        my %Psize;
        my %Psize;
        my $alg = $self->object_get_attribute('routing_auto', 'CYCLE_FREE_ALG');
        my $alg = $self->object_get_attribute('routing_auto', 'CYCLE_FREE_ALG');
        my ($alg_name,$line) = split (/\s+--\s+/,$alg);
        my ($alg_name,$line) = split (/\s+--\s+/,$alg);
 
 
        if(!defined $line){
        if(!defined $line){
                add_colored_info($info,"No acyclic turn model is selected. click on Generate Cycle-free and make sure it runs successfully!\n",'red');
                add_colored_info($info,"No acyclic turn model is selected. click on Generate Cycle-free and make sure it runs successfully!\n",'red');
        return;
        return;
        }
        }
        my $tmp_dir  = "$ENV{'PRONOC_WORK'}/tmp";
        my $tmp_dir  = "$ENV{'PRONOC_WORK'}/tmp";
        my $model_file = "$tmp_dir/$alg_name.alg";
        my $model_file = "$tmp_dir/$alg_name.alg";
        my ($pp,$r,$err) = regen_object($model_file);
        my ($pp,$r,$err) = regen_object($model_file);
    if ($r){
    if ($r){
        add_colored_info($info,"**Error: cannot open $model_file file: $err\n",'red');
        add_colored_info($info,"**Error: cannot open $model_file file: $err\n",'red');
                return;
                return;
    } else {
    } else {
        add_info($info,"Use $alg_name algorithm for obtaing acyclic paths\n");
        add_info($info,"Use $alg_name algorithm for obtaing acyclic paths\n");
    }
    }
 
 
        my @acyclic_turns = @{$pp};
        my @acyclic_turns = @{$pp};
 
 
 
 
 
 
        #step 1: calculate all minimal paths between all source and destination pairs
        #step 1: calculate all minimal paths between all source and destination pairs
        add_info($info,"Calculate all  paths between all source and destination pairs\n");
        add_info($info,"Calculate all  paths between all source and destination pairs\n");
        my @all_endpoints=get_list_of_all_endpoints($self);
        my @all_endpoints=get_list_of_all_endpoints($self);
        foreach  my $src  (@all_endpoints ){
        foreach  my $src  (@all_endpoints ){
                foreach  my $dst  (@all_endpoints ){
                foreach  my $dst  (@all_endpoints ){
                        if($src ne $dst){
                        if($src ne $dst){
                                my ($paths_to_dst,$ports_to_dst) =  get_all_paths_between_two_endps_using_accyclic_turn($self,$src, $dst,\@acyclic_turns);
                                my ($paths_to_dst,$ports_to_dst) =  get_all_paths_between_two_endps_using_accyclic_turn($self,$src, $dst,\@acyclic_turns);
                                my @cyle_free_paths= @{$paths_to_dst} if (defined $paths_to_dst);
                                my @cyle_free_paths= @{$paths_to_dst} if (defined $paths_to_dst);
                                my $size = scalar  @cyle_free_paths;
                                my $size = scalar  @cyle_free_paths;
                                $Psize{"${src}::$dst"} = $size;
                                $Psize{"${src}::$dst"} = $size;
                        }
                        }
                }
                }
        }
        }
        #step 2: Remove cyclic paths between all source and destination pairs
        #step 2: Remove cyclic paths between all source and destination pairs
 
 
 
 
 
 
 
 
 
 
 
 
        #step 3 sort source destination based on the number of paths
        #step 3 sort source destination based on the number of paths
        my @keys = sort { $Psize{$a} <=> $Psize{$b} } keys(%Psize);
        my @keys = sort { $Psize{$a} <=> $Psize{$b} } keys(%Psize);
        for my $key ( @keys) {
        for my $key ( @keys) {
                my $size=$Psize{$key};
                my $size=$Psize{$key};
                #print "size = $size\n";
                #print "size = $size\n";
                next if(defined $self->object_get_attribute('Route',$key));
                next if(defined $self->object_get_attribute('Route',$key));
 
 
       # print "($key)->($Psize{$key})\n";
       # print "($key)->($Psize{$key})\n";
        my ($src , $dst)=split ('::',$key);
        my ($src , $dst)=split ('::',$key);
        my ($paths_to_dst,$ports_to_dst) = get_all_paths_between_two_endps_using_accyclic_turn($self,$src, $dst,\@acyclic_turns);
        my ($paths_to_dst,$ports_to_dst) = get_all_paths_between_two_endps_using_accyclic_turn($self,$src, $dst,\@acyclic_turns);
        #my @cyle_free_paths=remove_cycle_paths($self,$info,$paths_to_dst, \@forbiden_turn);
        #my @cyle_free_paths=remove_cycle_paths($self,$info,$paths_to_dst, \@forbiden_turn);
        my @cyle_free_paths= @{$paths_to_dst} if (defined $paths_to_dst);
        my @cyle_free_paths= @{$paths_to_dst} if (defined $paths_to_dst);
        my @sort_paths=sort_paths_based_on_link_usage($self,\@cyle_free_paths);
        my @sort_paths=sort_paths_based_on_link_usage($self,\@cyle_free_paths);
        my $path;
        my $path;
        my $n=0;
        my $n=0;
        foreach my $p (@sort_paths ){
        foreach my $p (@sort_paths ){
                if(check_cyclick_loop($self,$p)==0){
                if(check_cyclick_loop($self,$p)==0){
                        $path=$p;
                        $path=$p;
                        #my @rrr=($p);
                        #my @rrr=($p);
                        #remove_cycle_paths($self,$info,\@rrr, \@forbiden_turn);
                        #remove_cycle_paths($self,$info,\@rrr, \@forbiden_turn);
 
 
                        last;
                        last;
                }  else {
                }  else {
                        print "***Error  something goes wrong in acyclic turns model  ****************************\n";
                        print "***Error  something goes wrong in acyclic turns model  ****************************\n";
                }
                }
                $n++;
                $n++;
        }
        }
        if(!defined $path){
        if(!defined $path){
                #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
                #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
 
 
 
 
                set_gui_status($self,"ref",1);
                set_gui_status($self,"ref",1);
                add_colored_info($info,"Failed to find an acyclic routing paths for $key nodes!\n",'red');
                add_colored_info($info,"Failed to find an acyclic routing paths for $key nodes!\n",'red');
                return FALSE ;
                return FALSE ;
 
 
        }
        }
 
 
        $self->object_add_attribute('Route',$key,$path);
        $self->object_add_attribute('Route',$key,$path);
 
 
        }
        }
 
 
        set_gui_status($self,"ref",1);
        set_gui_status($self,"ref",1);
        add_colored_info($info,"The routeing function table is generated successfully!\n",'blue');
        add_colored_info($info,"The routeing function table is generated successfully!\n",'blue');
        return TRUE;
        return TRUE;
}
}
 
 
 
 
sub clean_route {
sub clean_route {
        my ($self,$info)=@_;
        my ($self,$info)=@_;
 
 
        my @all_endpoints=get_list_of_all_endpoints($self);
        my @all_endpoints=get_list_of_all_endpoints($self);
        foreach  my $src  (@all_endpoints ){
        foreach  my $src  (@all_endpoints ){
                foreach  my $dst  (@all_endpoints ){
                foreach  my $dst  (@all_endpoints ){
        $self->object_add_attribute('Route',"${src}::$dst",undef);
        $self->object_add_attribute('Route',"${src}::$dst",undef);
 
 
        }}
        }}
 
 
        set_gui_status($self,"ref",1);
        set_gui_status($self,"ref",1);
        add_colored_info($info,"The Routing function table is cleared!\n",'blue');
        add_colored_info($info,"The Routing function table is cleared!\n",'blue');
        return TRUE;
        return TRUE;
}
}
 
 
 
 
 
 
sub average{
sub average{
        my($data) = @_;
        my($data) = @_;
        if (not @$data) {
        if (not @$data) {
               return 0;
               return 0;
        }
        }
        my $total = 0;
        my $total = 0;
        foreach (@$data) {
        foreach (@$data) {
                $total += $_;
                $total += $_;
        }
        }
        my $average = $total / @$data;
        my $average = $total / @$data;
        return $average;
        return $average;
}
}
sub stdev{
sub stdev{
        my($data) = @_;
        my($data) = @_;
        if(@$data == 1){
        if(@$data == 1){
                return 0;
                return 0;
        }
        }
        my $average = &average($data);
        my $average = &average($data);
        my $sqtotal = 0;
        my $sqtotal = 0;
        foreach(@$data) {
        foreach(@$data) {
                $sqtotal += ($average-$_) ** 2;
                $sqtotal += ($average-$_) ** 2;
        }
        }
        my $std = ($sqtotal / (@$data-1)) ** 0.5;
        my $std = ($sqtotal / (@$data-1)) ** 0.5;
        return $std;
        return $std;
}
}
 
 
sub clone_hash{
sub clone_hash{
        my $ref=shift;
        my $ref=shift;
        my %hash=%{$ref};
        my %hash=%{$ref};
        my %copy;
        my %copy;
        foreach my $p (keys %hash){
        foreach my $p (keys %hash){
                if (defined $hash{$p}){ $copy{$p} =  $hash{$p};}
                if (defined $hash{$p}){ $copy{$p} =  $hash{$p};}
        }
        }
        return %copy;
        return %copy;
}
}
 
 
sub sort_paths_based_on_link_usage{
sub sort_paths_based_on_link_usage{
        my ($self,$paths_to_dst)=@_;
        my ($self,$paths_to_dst)=@_;
 
 
        my %L_num;
        my %L_num;
        my %max;
        my %max;
        my @all_endpoints=get_list_of_all_endpoints($self);
        my @all_endpoints=get_list_of_all_endpoints($self);
        #get link count
        #get link count
        foreach  my $src  (@all_endpoints ){
        foreach  my $src  (@all_endpoints ){
                foreach  my $dst  (@all_endpoints ){
                foreach  my $dst  (@all_endpoints ){
                        my $path = $self->object_get_attribute('Route',"${src}::$dst");
                        my $path = $self->object_get_attribute('Route',"${src}::$dst");
                        if (defined $path){
                        if (defined $path){
                                #path counting
                                #path counting
                                my @p=  get_adjacent_router_in_a_path($path);
                                my @p=  get_adjacent_router_in_a_path($path);
                                foreach my $r (@p){
                                foreach my $r (@p){
                                        $L_num{$r} ++;
                                        $L_num{$r} ++;
                                }
                                }
 
 
                        }
                        }
                }
                }
        }
        }
        #get std_devision of link  for each path if added   
        #get std_devision of link  for each path if added   
        my $i=0;
        my $i=0;
        foreach my $path (@{$paths_to_dst}) {
        foreach my $path (@{$paths_to_dst}) {
                my %copy = clone_hash(\%L_num);
                my %copy = clone_hash(\%L_num);
                my @p=get_adjacent_router_in_a_path($path);
                my @p=get_adjacent_router_in_a_path($path);
                foreach my $r (@p){
                foreach my $r (@p){
                                        $copy{$r} ++;
                                        $copy{$r} ++;
                }
                }
                my @l = sort  values (%copy);
                my @l = sort  values (%copy);
                my $std=stdev(\@l);
                my $std=stdev(\@l);
                $max{$i}=$std*100;
                $max{$i}=$std*100;
                $i++;
                $i++;
        }
        }
 
 
 
 
        my @order = sort { $max{$a} <=> $max{$b} } keys(%max);
        my @order = sort { $max{$a} <=> $max{$b} } keys(%max);
 
 
        #print "*********** @order ************"; 
        #print "*********** @order ************"; 
        my @sorted;
        my @sorted;
        $i=0;
        $i=0;
        foreach my $a ( @order){
        foreach my $a ( @order){
                $sorted[$i]=${$paths_to_dst}[$a];
                $sorted[$i]=${$paths_to_dst}[$a];
                $i++;
                $i++;
                #print "\$max{$a}=$max{$a},"
                #print "\$max{$a}=$max{$a},"
        }
        }
 
 
        #print "\n";
        #print "\n";
 
 
        return @sorted;
        return @sorted;
 
 
 
 
}
}
 
 
sub check_cyclick_loop{
sub check_cyclick_loop{
        my ($self,$paths_to_dst)=@_;
        my ($self,$paths_to_dst)=@_;
 
 
 
 
        my %graph;
        my %graph;
        my @all_endpoints=get_list_of_all_endpoints($self);
        my @all_endpoints=get_list_of_all_endpoints($self);
        # create routing dependency graph
        # create routing dependency graph
 
 
        foreach  my $src  (@all_endpoints ){
        foreach  my $src  (@all_endpoints ){
                foreach  my $dst  (@all_endpoints ){
                foreach  my $dst  (@all_endpoints ){
                        my $path = $self->object_get_attribute('Route',"${src}::$dst");
                        my $path = $self->object_get_attribute('Route',"${src}::$dst");
                        if (defined $path){
                        if (defined $path){
                                #path counting
                                #path counting
                                my @p=  get_adjacent_node_in_a_path($path);
                                my @p=  get_adjacent_node_in_a_path($path);
                                %graph=add_route_edge_to_graph(\%graph,\@p);
                                %graph=add_route_edge_to_graph(\%graph,\@p);
 
 
                        }
                        }
                }
                }
        }
        }
 
 
        my @p=  get_adjacent_node_in_a_path($paths_to_dst);
        my @p=  get_adjacent_node_in_a_path($paths_to_dst);
        %graph=add_route_edge_to_graph(\%graph,\@p);
        %graph=add_route_edge_to_graph(\%graph,\@p);
 
 
        my $result = Algorithm::TSort::cicle_detect( Algorithm::TSort::Graph( ADJ => \%graph ), keys %graph );
        my $result = Algorithm::TSort::cicle_detect( Algorithm::TSort::Graph( ADJ => \%graph ), keys %graph );
 
 
        #print Data::Dumper->Dump([\%graph],["link"]);
        #print Data::Dumper->Dump([\%graph],["link"]);
        #print "result=$result\n";
        #print "result=$result\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
        return  $result;
        return  $result;
 
 
 
 
}
}
 
 
sub generate_topology{
sub generate_topology{
        my ($self,$info)=@_;
        my ($self,$info)=@_;
        my $name=$self->object_get_attribute('save_as');
        my $name=$self->object_get_attribute('save_as');
    my $error = check_verilog_identifier_syntax($name);
    my $error = check_verilog_identifier_syntax($name);
    if ( defined $error ){
    if ( defined $error ){
        #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");
        #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");
        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";
        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";
        add_colored_info($info, $message,'red' );
        add_colored_info($info, $message,'red' );
        return 0;
        return 0;
    }
    }
    my $rname=$self->object_get_attribute('routing_name');
    my $rname=$self->object_get_attribute('routing_name');
    $error = check_verilog_identifier_syntax($rname);
    $error = check_verilog_identifier_syntax($rname);
    if ( defined $error ){
    if ( defined $error ){
        #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");
        #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");
        $rname='Undefined' if(!defined $rname);
        $rname='Undefined' if(!defined $rname);
        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";
        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";
        add_colored_info($info, $message,'red' );
        add_colored_info($info, $message,'red' );
        return 0;
        return 0;
    }
    }
 
 
 
 
 
 
 
 
        #make destination dir
        #make destination dir
        my $dir =get_project_dir()."/mpsoc/rtl/src_topolgy/$name";
        my $dir =get_project_dir()."/mpsoc/rtl/src_topolgy/$name";
        mkpath("$dir",1,01777) unless (-d $dir) ;
        mkpath("$dir",1,01777) unless (-d $dir) ;
    mkpath("$dir/../common",1,01777) unless (-d "$dir/../common") ;
    mkpath("$dir/../common",1,01777) unless (-d "$dir/../common") ;
 
 
        #save topology image file
        #save topology image file
        $self->object_add_attribute("graph_save","name","$dir/$name");
        $self->object_add_attribute("graph_save","name","$dir/$name");
        $self->object_add_attribute("graph_save","extension",'png');
        $self->object_add_attribute("graph_save","extension",'png');
        $self->object_add_attribute("graph_save","enable",1);
        $self->object_add_attribute("graph_save","enable",1);
 
 
        show_custom_topology_diagram ($self,undef,"topology_diagram");
        show_custom_topology_diagram ($self,undef,"topology_diagram");
 
 
 
 
 
 
        #generate topology top module verilog file
        #generate topology top module verilog file
        generate_topology_top_v($self,$info,$dir);
        generate_topology_top_v($self,$info,$dir);
        generate_topology_top_genvar_v($self,$info,$dir);
        generate_topology_top_genvar_v($self,$info,$dir);
        generate_routing_v($self,$info,$dir);
        generate_routing_v($self,$info,$dir);
        #generate_connection_v($self,$info,$dir);
        #generate_connection_v($self,$info,$dir);
        add_routing_instance_v($self,$info,$dir);
        add_routing_instance_v($self,$info,$dir);
        add_noc_instance_v($self,$info,$dir);
        add_noc_instance_v($self,$info,$dir);
 
        add_noc_custom_h($self,$info,$dir);
        save_topology_parameter_object_file($self,$info);
        save_topology_parameter_object_file($self,$info);
 
 
        #create the file list
        #create the file list
        my $txt="+incdir+./\n";
        my $txt="+incdir+./\n";
        my @files = File::Find::Rule->file()
        my @files = File::Find::Rule->file()
                            ->name( '*.v','*.sv')
                            ->name( '*.v','*.sv')
                            ->in( "$dir/../" );
                            ->in( "$dir/../" );
    foreach my $f (@files){
    foreach my $f (@files){
        my $d = basename(dirname(abs_path($f)));
        my $d = basename(dirname(abs_path($f)));
        my $n = basename($f);
        my $n = basename($f);
        $txt.="./$d/$n\n";
        $txt.="./$d/$n\n";
    }
    }
        save_file("$dir/../custom_flist.f",$txt);
        save_file("$dir/../custom_flist.f",$txt);
 
 
 
 
}
}
 
 
 
 
sub save_topology_parameter_object_file{
sub save_topology_parameter_object_file{
        my ($self,$info)=@_;
        my ($self,$info)=@_;
        my $name=$self->object_get_attribute('save_as');
        my $name=$self->object_get_attribute('save_as');
        my $rname=$self->object_get_attribute('routing_name');
        my $rname=$self->object_get_attribute('routing_name');
        my $dir =get_project_dir()."/mpsoc/rtl/src_topolgy";
        my $dir =get_project_dir()."/mpsoc/rtl/src_topolgy";
        my $file="$dir/param.obj";
        my $file="$dir/param.obj";
 
 
        my %param;
        my %param;
 
 
        if(-f $file){
        if(-f $file){
                 my ($pp,$r,$err) = regen_object($file );
                 my ($pp,$r,$err) = regen_object($file );
            if ($r){
            if ($r){
                add_info($info,"**Error: cannot open $file file: $err\n");
                add_info($info,"**Error: cannot open $file file: $err\n");
                return;
                return;
            }
            }
 
 
                %param=%{$pp};
                %param=%{$pp};
        }
        }
 
 
 
 
        my @ends=get_list_of_all_endpoints($self);
        my @ends=get_list_of_all_endpoints($self);
    my @routers=get_list_of_all_routers($self);
    my @routers=get_list_of_all_routers($self);
 
 
    my $MAX_P=0;
    my $MAX_P=0;
    my %router_ps;
    my %router_ps;
    foreach my $p (@routers){
    foreach my $p (@routers){
        my $Pnum=$self->object_get_attribute("$p",'PNUM');
        my $Pnum=$self->object_get_attribute("$p",'PNUM');
        $MAX_P =$Pnum  if($Pnum>$MAX_P );
        $MAX_P =$Pnum  if($Pnum>$MAX_P );
        $router_ps{$Pnum}=(defined $router_ps{$Pnum})? $router_ps{$Pnum}+1 : '1';
        $router_ps{$Pnum}=(defined $router_ps{$Pnum})? $router_ps{$Pnum}+1 : '1';
    }
    }
 
 
    my $NE= scalar @ends;
    my $NE= scalar @ends;
    my $NR= scalar @routers;
    my $NR= scalar @routers;
 
 
 
 
        $param{"\"$name\""}{'T1'}=$NE;
        $param{"\"$name\""}{'T1'}=$NE;
        $param{"\"$name\""}{'T2'}=$NR;
        $param{"\"$name\""}{'T2'}=$NR;
        $param{"\"$name\""}{'T3'}=$MAX_P;
        $param{"\"$name\""}{'T3'}=$MAX_P;
        my $routs = $param{"\"$name\""}{'ROUTE_NAME'};
        my $routs = $param{"\"$name\""}{'ROUTE_NAME'};
        my $new="\"$rname\"";
        my $new="\"$rname\"";
        if(!defined $routs){
        if(!defined $routs){
                $param{"\"$name\""}{'ROUTE_NAME'}=$new;
                $param{"\"$name\""}{'ROUTE_NAME'}=$new;
        }
        }
        else {
        else {
                my @r=split(/\s*,\s*/,$routs);
                my @r=split(/\s*,\s*/,$routs);
                unless( grep (/^$new$/,@r)){
                unless( grep (/^$new$/,@r)){
                        $param{"\"$name\""}{'ROUTE_NAME'}= $routs.",$new" ;
                        $param{"\"$name\""}{'ROUTE_NAME'}= $routs.",$new" ;
                }
                }
        }
        }
 
 
        $param{"\"$name\""}{'ROUTER_Ps'}= \%router_ps;
        $param{"\"$name\""}{'ROUTER_Ps'}= \%router_ps;
 
 
 
 
        my @er_addr;
        my @er_addr;
        foreach my $end (@ends){
        foreach my $end (@ends){
                my $connect = $self->{$end}{'PCONNECT'}{'Port[0]'};
                my $connect = $self->{$end}{'PCONNECT'}{'Port[0]'};
                my ($Rname,$Rport)=split(/\s*,\s*/,$connect);
                my ($Rname,$Rport)=split(/\s*,\s*/,$connect);
                my $R = get_scolar_pos($Rname,@routers);
                my $R = get_scolar_pos($Rname,@routers);
                push(@er_addr,$R);
                push(@er_addr,$R);
        }
        }
        $param{"\"$name\""}{'er_addr'}= \@er_addr;
        $param{"\"$name\""}{'er_addr'}= \@er_addr;
 
 
 
 
 
 
 
 
    open(FILE,  ">$file") || die "Can not open: $!";
    open(FILE,  ">$file") || die "Can not open: $!";
    print FILE perl_file_header("$file");
    print FILE perl_file_header("$file");
    print FILE Data::Dumper->Dump([\%param],['Topology']);
    print FILE Data::Dumper->Dump([\%param],['Topology']);
    close(FILE) || die "Error closing file: $!";
    close(FILE) || die "Error closing file: $!";
 
 
}
}
 
 
 
 
sub get_path_route_widgets {
sub get_path_route_widgets {
        my      ($self,$info)=@_;
        my      ($self,$info)=@_;
 
 
        my              $w1 = show_paths_between_two_endps($self,$info);
        my              $w1 = show_paths_between_two_endps($self,$info);
        my              $w2 = routing_summary($self,$info);
        my              $w2 = routing_summary($self,$info);
    my $h=gen_hpaned($w1,.15,$w2);
    my $h=gen_hpaned($w1,.15,$w2);
    $h -> pack1($w1, TRUE, TRUE);
    $h -> pack1($w1, TRUE, TRUE);
        $h -> pack2($w2, TRUE, TRUE);
        $h -> pack2($w2, TRUE, TRUE);
        return $h;
        return $h;
}
}
 
 
 
 
sub build_network_maker_gui {
sub build_network_maker_gui {
        my ($self) = @_;
        my ($self) = @_;
        set_gui_status($self,"ideal",0);
        set_gui_status($self,"ideal",0);
        $self->object_add_attribute ("process_notebook","currentpage",0);
        $self->object_add_attribute ("process_notebook","currentpage",0);
        my $main_table= def_table(2,10,FALSE);
        my $main_table= def_table(2,10,FALSE);
 
 
    my ($infobox,$info)= create_txview();
    my ($infobox,$info)= create_txview();
 
 
 
 
        my $notebook = gen_notebook();
        my $notebook = gen_notebook();
        $notebook->set_tab_pos ('left');
        $notebook->set_tab_pos ('left');
        $notebook->set_scrollable(TRUE);
        $notebook->set_scrollable(TRUE);
 
 
 
 
 
 
        my $page0=take_node_num_page($self);
        my $page0=take_node_num_page($self);
        my $page1=take_instance_page($self);
        my $page1=take_instance_page($self);
        my $page2=connection_page_auto($self,$info);
        my $page2=connection_page_auto($self,$info);
        my $page3=connection_page($self,$info);
        my $page3=connection_page($self,$info);
        my $page4=routing_page_manual($self,$info);
        my $page4=routing_page_manual($self,$info);
 
 
        my $page0_win = add_widget_to_scrolled_win($page0);
        my $page0_win = add_widget_to_scrolled_win($page0);
        my $page1_win = add_widget_to_scrolled_win($page1);
        my $page1_win = add_widget_to_scrolled_win($page1);
        my $page2_win = add_widget_to_scrolled_win($page2);
        my $page2_win = add_widget_to_scrolled_win($page2);
        my $page3_win = add_widget_to_scrolled_win($page3);
        my $page3_win = add_widget_to_scrolled_win($page3);
        my $page4_win = add_widget_to_scrolled_win($page4);
        my $page4_win = add_widget_to_scrolled_win($page4);
 
 
 
 
        $notebook->append_page ($page0_win,gen_label_in_center  (" Nodes #"));
        $notebook->append_page ($page0_win,gen_label_in_center  (" Nodes #"));
        $notebook->append_page ($page1_win,gen_label_in_center  ("Instance"));
        $notebook->append_page ($page1_win,gen_label_in_center  ("Instance"));
        $notebook->append_page ($page2_win,gen_label_in_center  ("Connection Auto"));
        $notebook->append_page ($page2_win,gen_label_in_center  ("Connection Auto"));
        $notebook->append_page ($page3_win,gen_label_in_center  ("Connection Manual"));
        $notebook->append_page ($page3_win,gen_label_in_center  ("Connection Manual"));
        $notebook->append_page ($page4_win,gen_label_in_center  ("Route Select"));
        $notebook->append_page ($page4_win,gen_label_in_center  ("Route Select"));
 
 
 
 
        $notebook->signal_connect( 'switch-page'=> sub{ # rebulid the current page              
        $notebook->signal_connect( 'switch-page'=> sub{ # rebulid the current page              
                $self->object_add_attribute ("process_notebook","currentpage",$_[2]);   #save the new pagenumber
                $self->object_add_attribute ("process_notebook","currentpage",$_[2]);   #save the new pagenumber
                set_gui_status($self,"ref",1);
                set_gui_status($self,"ref",1);
        });
        });
 
 
 
 
        my $draw=custom_topology_diagram($self);
        my $draw=custom_topology_diagram($self);
        my $h1=gen_hpaned($notebook,.35,$draw);
        my $h1=gen_hpaned($notebook,.35,$draw);
 
 
 
 
        my $v2=gen_vpaned($h1,.65,$infobox);
        my $v2=gen_vpaned($h1,.65,$infobox);
 
 
 
 
        my $generate = def_image_button('icons/gen.png','Generate');
        my $generate = def_image_button('icons/gen.png','Generate');
        my $open = def_image_button('icons/browse.png','Load');
        my $open = def_image_button('icons/browse.png','Load');
 
 
 
 
        my ($entrybox,$entry) = def_h_labeled_entry('Topology name:',undef);
        my ($entrybox,$entry) = def_h_labeled_entry('Topology name:',undef);
 
 
        $entry->signal_connect( 'changed'=> sub{
        $entry->signal_connect( 'changed'=> sub{
                my $name=$entry->get_text();
                my $name=$entry->get_text();
                $self->object_add_attribute ("save_as",undef,$name);
                $self->object_add_attribute ("save_as",undef,$name);
        });
        });
 
 
        my ($entrybox2,$entry2) = def_h_labeled_entry('Routing Alg. name:',undef);
        my ($entrybox2,$entry2) = def_h_labeled_entry('Routing Alg. name:',undef);
 
 
        $entry2->signal_connect( 'changed'=> sub{
        $entry2->signal_connect( 'changed'=> sub{
                my $name=$entry2->get_text();
                my $name=$entry2->get_text();
                $self->object_add_attribute ("routing_name",undef,$name);
                $self->object_add_attribute ("routing_name",undef,$name);
        });
        });
 
 
        my $save = def_image_button('icons/save.png','Save');
        my $save = def_image_button('icons/save.png','Save');
        #$entrybox->pack_end($save,   FALSE, FALSE,0);
        #$entrybox->pack_end($save,   FALSE, FALSE,0);
 
 
        $main_table->attach_defaults ($v2  , 0, 12, 0,24);
        $main_table->attach_defaults ($v2  , 0, 12, 0,24);
        $main_table->attach ($open,0, 1, 24,25,'expand','shrink',2,2);
        $main_table->attach ($open,0, 1, 24,25,'expand','shrink',2,2);
        $main_table->attach ($save,1, 2, 24,25,'expand','shrink',2,2);
        $main_table->attach ($save,1, 2, 24,25,'expand','shrink',2,2);
 
 
        $main_table->attach ($entrybox,2, 4, 24,25,'expand','shrink',2,2);
        $main_table->attach ($entrybox,2, 4, 24,25,'expand','shrink',2,2);
        $main_table->attach ($entrybox2,4, 6, 24,25,'expand','shrink',2,2);
        $main_table->attach ($entrybox2,4, 6, 24,25,'expand','shrink',2,2);
 
 
        $main_table->attach ($generate, 6, 9, 24,25,'expand','shrink',2,2);
        $main_table->attach ($generate, 6, 9, 24,25,'expand','shrink',2,2);
 
 
 
 
        my $sc_win = add_widget_to_scrolled_win($main_table);
        my $sc_win = add_widget_to_scrolled_win($main_table);
 
 
 
 
        #setting for graphs
        #setting for graphs
        my $n=0;
        my $n=0;
    my $sample="sample$n";
    my $sample="sample$n";
        $n++;
        $n++;
        $self->object_add_attribute("id",undef,$n);
        $self->object_add_attribute("id",undef,$n);
        $self->object_add_attribute("active_setting",undef,undef);
        $self->object_add_attribute("active_setting",undef,undef);
        $self->object_add_attribute_order("samples",$sample);
        $self->object_add_attribute_order("samples",$sample);
        $self->object_add_attribute($sample,"color",1);
        $self->object_add_attribute($sample,"color",1);
        add_color_to_gd($self);
        add_color_to_gd($self);
 
 
 
 
        $open-> signal_connect("clicked" => sub{
        $open-> signal_connect("clicked" => sub{
 
 
 
 
 
 
        load_net_maker($self,$info);
        load_net_maker($self,$info);
        my $n=0;
        my $n=0;
    my $sample="sample$n";
    my $sample="sample$n";
        $n++;
        $n++;
        $self->object_add_attribute("id",undef,$n);
        $self->object_add_attribute("id",undef,$n);
        $self->object_add_attribute("active_setting",undef,undef);
        $self->object_add_attribute("active_setting",undef,undef);
        $self->object_add_attribute_order("samples",$sample);
        $self->object_add_attribute_order("samples",$sample);
        $self->object_add_attribute($sample,"color",1);
        $self->object_add_attribute($sample,"color",1);
        add_color_to_gd($self);
        add_color_to_gd($self);
 
 
 
 
                set_gui_status($self,"ref",5);
                set_gui_status($self,"ref",5);
 
 
        });
        });
 
 
        $save-> signal_connect("clicked" => sub{
        $save-> signal_connect("clicked" => sub{
 
 
                save_network($self);
                save_network($self);
                set_gui_status($self,"ref",5);
                set_gui_status($self,"ref",5);
 
 
 
 
        });
        });
 
 
        $generate->signal_connect("clicked" => sub{
        $generate->signal_connect("clicked" => sub{
                generate_topology($self,$info);
                generate_topology($self,$info);
 
 
        });
        });
 
 
 
 
 
 
        #check soc status every 0.5 second. refresh device table if there is any changes 
        #check soc status every 0.5 second. refresh device table if there is any changes 
        Glib::Timeout->add (100, sub{
        Glib::Timeout->add (100, sub{
 
 
                my ($state,$timeout)= get_gui_status($self);
                my ($state,$timeout)= get_gui_status($self);
 
 
                if ($timeout>0){
                if ($timeout>0){
                        $timeout--;
                        $timeout--;
                        set_gui_status($self,$state,$timeout);
                        set_gui_status($self,$state,$timeout);
                        return TRUE;
                        return TRUE;
 
 
                }
                }
                if($state eq "ideal"){
                if($state eq "ideal"){
                        return TRUE;
                        return TRUE;
 
 
                }
                }
 
 
                if($state eq "ref" || $state eq "redraw"){
                if($state eq "ref" || $state eq "redraw"){
 
 
                        my $page_num=$self->object_get_attribute ("process_notebook","currentpage");
                        my $page_num=$self->object_get_attribute ("process_notebook","currentpage");
                        if($state eq "ref"){
                        if($state eq "ref"){
                                if($page_num==0){
                                if($page_num==0){
                                        $page0->destroy;
                                        $page0->destroy;
                                        $page0=take_node_num_page($self);
                                        $page0=take_node_num_page($self);
                                        add_widget_to_scrolled_win($page0,$page0_win);
                                        add_widget_to_scrolled_win($page0,$page0_win);
                                        $page0_win->show_all;
                                        $page0_win->show_all;
 
 
                                }
                                }
                                if($page_num==1){
                                if($page_num==1){
                                        $page1->destroy;
                                        $page1->destroy;
                                        $page1=take_instance_page($self);
                                        $page1=take_instance_page($self);
                                        add_widget_to_scrolled_win($page1,$page1_win);
                                        add_widget_to_scrolled_win($page1,$page1_win);
                                        $page1_win->show_all;
                                        $page1_win->show_all;
                                }
                                }
                                if($page_num==2){
                                if($page_num==2){
                                        $page2->destroy;
                                        $page2->destroy;
                                        $page2=connection_page_auto($self,$info);
                                        $page2=connection_page_auto($self,$info);
                                        add_widget_to_scrolled_win($page2,$page2_win);
                                        add_widget_to_scrolled_win($page2,$page2_win);
                                        $page2_win->show_all;
                                        $page2_win->show_all;
                                }
                                }
                                if($page_num==3){
                                if($page_num==3){
                                        $page3->destroy;
                                        $page3->destroy;
                                        $page3=connection_page($self,$info);
                                        $page3=connection_page($self,$info);
                                        add_widget_to_scrolled_win($page3,$page3_win);
                                        add_widget_to_scrolled_win($page3,$page3_win);
                                        $page3_win->show_all;
                                        $page3_win->show_all;
                                }
                                }
                                if($page_num==4){
                                if($page_num==4){
                                        $page4->destroy;
                                        $page4->destroy;
                                        $page4=routing_page_manual($self,$info);
                                        $page4=routing_page_manual($self,$info);
                                        add_widget_to_scrolled_win($page4,$page4_win);
                                        add_widget_to_scrolled_win($page4,$page4_win);
                                        $page4_win->show_all;
                                        $page4_win->show_all;
                                }
                                }
 
 
                        }
                        }
 
 
 
 
 
 
 
 
                        if($page_num==4  ){
                        if($page_num==4  ){
                                $draw->destroy;
                                $draw->destroy;
                                $draw = get_path_route_widgets($self,$info);
                                $draw = get_path_route_widgets($self,$info);
                                $h1 -> pack2($draw, TRUE, TRUE);
                                $h1 -> pack2($draw, TRUE, TRUE);
 
 
 
 
                        }else{
                        }else{
 
 
                                $draw->destroy;
                                $draw->destroy;
                                $draw=custom_topology_diagram($self);
                                $draw=custom_topology_diagram($self);
                                $h1 -> pack2($draw, TRUE, TRUE);
                                $h1 -> pack2($draw, TRUE, TRUE);
                        }
                        }
                        my $saved_name=$self->object_get_attribute('save_as');
                        my $saved_name=$self->object_get_attribute('save_as');
                    $entry->set_text($saved_name)if(defined $saved_name);
                    $entry->set_text($saved_name)if(defined $saved_name);
 
 
                    $saved_name = $self->object_get_attribute('routing_name');
                    $saved_name = $self->object_get_attribute('routing_name');
                    $entry2->set_text($saved_name) if(defined $saved_name);
                    $entry2->set_text($saved_name) if(defined $saved_name);
 
 
                        set_gui_status($self,"ideal",0);
                        set_gui_status($self,"ideal",0);
                        $main_table->show_all();
                        $main_table->show_all();
 
 
                        return TRUE;
                        return TRUE;
 
 
                }
                }
 
 
 
 
                #refresh GUI
                #refresh GUI
 
 
 
 
 
 
 
 
                $main_table->show_all();
                $main_table->show_all();
                set_gui_status($self,"ideal",0);
                set_gui_status($self,"ideal",0);
 
 
                return TRUE;
                return TRUE;
 
 
        } );
        } );
 
 
 
 
 
 
        return $sc_win;
        return $sc_win;
 
 
 
 
 
 
}
}
 
 

powered by: WebSVN 2.1.0

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