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/] [compile.pl] - Diff between revs 48 and 56

Only display areas with differences | Details | Blame | View Log

Rev 48 Rev 56
#!/usr/bin/perl -w
#!/usr/bin/perl -w
use constant::boolean;
use constant::boolean;
use strict;
use strict;
use warnings;
use warnings;
 
 
use FindBin;
use FindBin;
use lib $FindBin::Bin;
use lib $FindBin::Bin;
 
 
use soc;
use soc;
 
 
 
 
use File::Path;
use File::Path;
use File::Find::Rule;
use File::Find::Rule;
use File::Copy;
use File::Copy;
use File::Copy::Recursive qw(dircopy);
use File::Copy::Recursive qw(dircopy);
use Cwd 'abs_path';
use Cwd 'abs_path';
use Verilog::EditFiles;
use Verilog::EditFiles;
 
 
 
 
 
 
use List::MoreUtils qw( minmax );
use List::MoreUtils qw( minmax );
 
 
 
 
 
 
################
################
#       Compile
#       Compile
#################
#################
 
 
 
 
 
 
sub is_capital_sensitive()
sub is_capital_sensitive()
{
{
  my ($cell_layout, $cell, $tree_model, $iter, $data) = @_;
  my ($cell_layout, $cell, $tree_model, $iter, $data) = @_;
  my $sensitive = !$tree_model->iter_has_child($iter);
  my $sensitive = !$tree_model->iter_has_child($iter);
  $cell->set('sensitive', $sensitive);
  $cell->set('sensitive', $sensitive);
}
}
 
 
 
 
 
 
sub get_range {
sub get_range {
        my ($board,$self,$porttype,$assignname,$portrange,$portname) =@_;
        my ($board,$self,$porttype,$assignname,$portrange,$portname) =@_;
        my $box= def_hbox(FALSE,0);
        my $box= def_hbox(FALSE,0);
        my @range=$board->board_get_pin_range($porttype,$assignname);
        my @range=$board->board_get_pin_range($porttype,$assignname);
 
 
 
 
        if ($range[0] ne '*undefine*'){
        if ($range[0] ne '*undefine*'){
                my $content = join(",", @range);
                my $content = join(",", @range);
                my ($min, $max) = minmax @range;
                my ($min, $max) = minmax @range;
                if  (length($portrange)!=0){
                if  (length($portrange)!=0){
                        my $range_hsb=gen_combobox_object($self,'compile_pin_range_hsb',$portname,$content,$max,undef,undef);
                        my $range_hsb=gen_combobox_object($self,'compile_pin_range_hsb',$portname,$content,$max,undef,undef);
                        $box->pack_start( $range_hsb, FALSE, FALSE, 0);
                        $box->pack_start( $range_hsb, FALSE, FALSE, 0);
                        $box->pack_start(gen_label_in_center(':'),, FALSE, FALSE, 0);
                        $box->pack_start(gen_label_in_center(':'),, FALSE, FALSE, 0);
                }
                }
 
 
                my $range_lsb=gen_combobox_object($self,'compile_pin_range_lsb',$portname,$content,$min,undef,undef);
                my $range_lsb=gen_combobox_object($self,'compile_pin_range_lsb',$portname,$content,$min,undef,undef);
                $box->pack_start( $range_lsb, FALSE, FALSE, 0);
                $box->pack_start( $range_lsb, FALSE, FALSE, 0);
 
 
        }
        }
        return $box;
        return $box;
 
 
}
}
 
 
 
 
sub read_top_v_file{
sub read_top_v_file{
        my $top_v=shift;
        my $top_v=shift;
        my $board = soc->board_new();
        my $board = soc->board_new();
        my $vdb=read_verilog_file($top_v);
        my $vdb=read_verilog_file($top_v);
        my @modules=sort $vdb->get_modules($top_v);
        my @modules=sort $vdb->get_modules($top_v);
        my %Ptypes=get_ports_type($vdb,$modules[0]);
        my %Ptypes=get_ports_type($vdb,$modules[0]);
        my %Pranges=get_ports_rang($vdb,$modules[0]);
        my %Pranges=get_ports_rang($vdb,$modules[0]);
        foreach my $p (sort keys %Ptypes){
        foreach my $p (sort keys %Ptypes){
                my $Ptype=$Ptypes{$p};
                my $Ptype=$Ptypes{$p};
                my $Prange=$Pranges{$p};
                my $Prange=$Pranges{$p};
                my $type=($Ptype eq "input")? "Input" : ($Ptype eq "output")? 'Output' : 'Bidir';
                my $type=($Ptype eq "input")? "Input" : ($Ptype eq "output")? 'Output' : 'Bidir';
                if (  $Prange ne ''){
                if (  $Prange ne ''){
                        my @r=split(":",$Prange);
                        my @r=split(":",$Prange);
                        my $a=($r[0]<$r[1])? $r[0] : $r[1];
                        my $a=($r[0]<$r[1])? $r[0] : $r[1];
                        my $b=($r[0]<$r[1])? $r[1] : $r[0];
                        my $b=($r[0]<$r[1])? $r[1] : $r[0];
                        for (my $i=$a; $i<=$b; $i++){
                        for (my $i=$a; $i<=$b; $i++){
                                $board->board_add_pin ($type,"$p\[$i\]");
                                $board->board_add_pin ($type,"$p\[$i\]");
 
 
                        }
                        }
                }
                }
                else {$board->board_add_pin ($type,$p);}
                else {$board->board_add_pin ($type,$p);}
        }
        }
        return $board;
        return $board;
}
}
 
 
 
 
 
 
 
 
sub gen_top_v{
sub gen_top_v{
        my ($self,$board,$name,$top)=@_;
        my ($self,$board,$name,$top)=@_;
 
 
        my $top_v=get_license_header("Top.v");
        my $top_v=get_license_header("Top.v");
        #read port list 
        #read port list 
        my $vdb=read_verilog_file($top);
        my $vdb=read_verilog_file($top);
        my %port_type=get_ports_type($vdb,"${name}_top");
        my %port_type=get_ports_type($vdb,"${name}_top");
        my %port_range=get_ports_rang($vdb,"${name}_top");
        my %port_range=get_ports_rang($vdb,"${name}_top");
 
 
 
 
        my $io='';
        my $io='';
        my $io_def='';
        my $io_def='';
        my $io_assign='';
        my $io_assign='';
        my %board_io;
        my %board_io;
        my $first=1;
        my $first=1;
        foreach my $p (sort keys %port_type){
        foreach my $p (sort keys %port_type){
                my $porttype=$port_type{$p};
                my $porttype=$port_type{$p};
                my $portrange=$port_range{$p};
                my $portrange=$port_range{$p};
                my $assign_type = $self->object_get_attribute('compile_assign_type',$p);
                my $assign_type = $self->object_get_attribute('compile_assign_type',$p);
                my $assign_name = $self->object_get_attribute('compile_pin',$p);
                my $assign_name = $self->object_get_attribute('compile_pin',$p);
                my $range_hsb   = $self->object_get_attribute('compile_pin_range_hsb',$p);
                my $range_hsb   = $self->object_get_attribute('compile_pin_range_hsb',$p);
                my $range_lsb   = $self->object_get_attribute('compile_pin_range_lsb',$p);
                my $range_lsb   = $self->object_get_attribute('compile_pin_range_lsb',$p);
                my $assign="\t";
                my $assign="\t";
                if (defined $assign_name){
                if (defined $assign_name){
                        if($assign_name eq '*VCC'){
                        if($assign_name eq '*VCC'){
                                $assign= (length($portrange)!=0)? '{32{1\'b1}}' : '1\'b1';
                                $assign= (length($portrange)!=0)? '{32{1\'b1}}' : '1\'b1';
                        } elsif ($assign_name eq '*GND'){
                        } elsif ($assign_name eq '*GND'){
                                $assign= (length($portrange)!=0)? '{32{1\'b0}}' : '1\'b0';
                                $assign= (length($portrange)!=0)? '{32{1\'b0}}' : '1\'b0';
                        }elsif ($assign_name eq '*NOCONNECT'){
                        }elsif ($assign_name eq '*NOCONNECT'){
                                $assign="\t";
                                $assign="\t";
 
 
                        }else{
                        }else{
 
 
                                $board_io{$assign_name}=$porttype;
                                $board_io{$assign_name}=$porttype;
 
 
 
 
                                my $range = (defined $range_hsb) ? "[$range_hsb : $range_lsb]" :
                                my $range = (defined $range_hsb) ? "[$range_hsb : $range_lsb]" :
                                            (defined $range_lsb) ?  "[ $range_lsb]" : " ";
                                            (defined $range_lsb) ?  "[ $range_lsb]" : " ";
                                my $l=(defined $assign_type)?
                                my $l=(defined $assign_type)?
                                        ($assign_type eq 'Direct') ? '' : '~' : '';
                                        ($assign_type eq 'Direct') ? '' : '~' : '';
                                $assign="$l $assign_name $range";
                                $assign="$l $assign_name $range";
 
 
 
 
                        }
                        }
                }
                }
                $io_assign= ($first)? "$io_assign \t  .$p($assign)":"$io_assign,\n \t  .$p($assign)";
                $io_assign= ($first)? "$io_assign \t  .$p($assign)":"$io_assign,\n \t  .$p($assign)";
                $first=0;
                $first=0;
        }
        }
        $first=1;
        $first=1;
        foreach my $p (sort keys %board_io){
        foreach my $p (sort keys %board_io){
                        $io=($first)? "\t$p" : "$io,\n\t$p";
                        $io=($first)? "\t$p" : "$io,\n\t$p";
                        my $dir=$board_io{$p};
                        my $dir=$board_io{$p};
                        my $range;
                        my $range;
                        my $type= ($dir eq  'input') ? 'Input' :
                        my $type= ($dir eq  'input') ? 'Input' :
                                  ($dir eq  'output')? 'Output' : 'Bidir';
                                  ($dir eq  'output')? 'Output' : 'Bidir';
                        my @r= $board->board_get_pin_range($type,$p);
                        my @r= $board->board_get_pin_range($type,$p);
                        if ($r[0] eq '*undefine*'){
                        if ($r[0] eq '*undefine*'){
                                $range="\t\t\t";
                                $range="\t\t\t";
                        } else {
                        } else {
                                my ($min, $max) = minmax @r;
                                my ($min, $max) = minmax @r;
                                $range="\t[$max : $min]\t";
                                $range="\t[$max : $min]\t";
                        }
                        }
                        $io_def = "$io_def \t $dir $range $p;\n";
                        $io_def = "$io_def \t $dir $range $p;\n";
                        $first=0;
                        $first=0;
 
 
        }
        }
        $top_v="$top_v
        $top_v="$top_v
module Top (
module Top (
$io
$io
);
);
$io_def
$io_def
 
 
        ${name}_top uut(
        ${name}_top uut(
$io_assign
$io_assign
        );
        );
 
 
 
 
endmodule
endmodule
";
";
        my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
        my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
        my $board_top_file= "$fpath/Top.v";
        my $board_top_file= "$fpath/Top.v";
        save_file($board_top_file,$top_v);
        save_file($board_top_file,$top_v);
}
}
 
 
 
 
 
 
 
 
sub select_compiler {
sub select_compiler {
        my ($self,$name,$top,$target_dir,$end_func)=@_;
        my ($self,$name,$top,$target_dir,$end_func)=@_;
        my $window = def_popwin_size(40,40,"Step 1: Select Compiler",'percent');
        my $window = def_popwin_size(40,40,"Step 1: Select Compiler",'percent');
 
 
        my $table = def_table(2, 2, FALSE);
        my $table = def_table(2, 2, FALSE);
        my $col=0;
        my $col=0;
        my $row=0;
        my $row=0;
 
 
        my $compilers=$self->object_get_attribute('compile','compilers');#"QuartusII,Vivado,Verilator,Modelsim"
        my $compilers=$self->object_get_attribute('compile','compilers');#"QuartusII,Vivado,Verilator,Modelsim"
 
 
        my $compiler=gen_combobox_object ($self,'compile','type',$compilers,"QuartusII",undef,undef);
        my $compiler=gen_combobox_object ($self,'compile','type',$compilers,"QuartusII",undef,undef);
        $table->attach(gen_label_in_center("Compiler tool"),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
        $table->attach(gen_label_in_center("Compiler tool"),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
        $table->attach($compiler,$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
        $table->attach($compiler,$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
        $row++;$col=0;
        $row++;$col=0;
 
 
        my $old_board_name=$self->object_get_attribute('compile','board');
        my $old_board_name=$self->object_get_attribute('compile','board');
        my $old_compiler=$self->object_get_attribute('compile','type');
        my $old_compiler=$self->object_get_attribute('compile','type');
        my $vendor= ($old_compiler eq "QuartusII")? 'Altera' : 'Xilinx';
        my $vendor= ($old_compiler eq "QuartusII")? 'Altera' : 'Xilinx';
 
 
        #get the list of boards located in "boards/*" folder
        #get the list of boards located in "boards/*" folder
        my @dirs = grep {-d} glob("../boards/$vendor/*");
        my @dirs = grep {-d} glob("../boards/$vendor/*");
        my ($fpgas,$init);
        my ($fpgas,$init);
        foreach my $dir (@dirs) {
        foreach my $dir (@dirs) {
                my ($name,$path,$suffix) = fileparse("$dir",qr"\..[^.]*$");
                my ($name,$path,$suffix) = fileparse("$dir",qr"\..[^.]*$");
                $init=$name;
                $init=$name;
                $fpgas= (defined $fpgas)? "$fpgas,$name" : "$name";
                $fpgas= (defined $fpgas)? "$fpgas,$name" : "$name";
        }
        }
 
 
 
 
        my $compiler_options =
        my $compiler_options =
                ($old_compiler eq "QuartusII")? select_board  ($self,$name,$top,$target_dir,$vendor):
                ($old_compiler eq "QuartusII")? select_board  ($self,$name,$top,$target_dir,$vendor):
                ($old_compiler eq "Vivado"   )? select_board  ($self,$name,$top,$target_dir,$vendor):
                ($old_compiler eq "Vivado"   )? select_board  ($self,$name,$top,$target_dir,$vendor):
                ($old_compiler eq "Modelsim" )? select_model_path  ($self,$name,$top,$target_dir):
                ($old_compiler eq "Modelsim" )? select_model_path  ($self,$name,$top,$target_dir):
                ($old_compiler eq "Verilator")? select_parallel_process_num ($self,$name,$top,$target_dir):
                ($old_compiler eq "Verilator")? select_parallel_process_num ($self,$name,$top,$target_dir):
                gen_label_in_center(" ");
                gen_label_in_center(" ");
 
 
        $table->attach($compiler_options,$col,$col+2,$row,$row+1,'fill','shrink',2,2); $row++;
        $table->attach($compiler_options,$col,$col+2,$row,$row+1,'fill','shrink',2,2); $row++;
 
 
        $col=1;
        $col=1;
        my $i;
        my $i;
        for ($i=$row; $i<5; $i++){
        for ($i=$row; $i<5; $i++){
 
 
                my $temp=gen_label_in_center(" ");
                my $temp=gen_label_in_center(" ");
                $table->attach_defaults ($temp, 0, 1 , $i, $i+1);
                $table->attach_defaults ($temp, 0, 1 , $i, $i+1);
        }
        }
        $row=$i;
        $row=$i;
 
 
 
 
        $window->add ($table);
        $window->add ($table);
        $window->show_all();
        $window->show_all();
        my $next=def_image_button('icons/right.png','_Next',FALSE,1);
        my $next=def_image_button('icons/right.png','_Next',FALSE,1);
        $table->attach($next,$col,$col+1,$row,$row+1,'shrink','shrink',2,2);$col++;
        $table->attach($next,$col,$col+1,$row,$row+1,'shrink','shrink',2,2);$col++;
        $next-> signal_connect("clicked" => sub{
        $next-> signal_connect("clicked" => sub{
                my $compiler_type=$self->object_get_attribute('compile','type');
                my $compiler_type=$self->object_get_attribute('compile','type');
                if($compiler_type eq "QuartusII" || $compiler_type eq "Vivado"){
                if($compiler_type eq "QuartusII" || $compiler_type eq "Vivado"){
                        $vendor= ($compiler_type eq "QuartusII")? 'Altera' : 'Xilinx';
                        $vendor= ($compiler_type eq "QuartusII")? 'Altera' : 'Xilinx';
                        my $new_board_name=$self->object_get_attribute('compile','board');
                        my $new_board_name=$self->object_get_attribute('compile','board');
                        if(defined $old_board_name) {
                        if(defined $old_board_name) {
                                if ($old_board_name ne $new_board_name){
                                if ($old_board_name ne $new_board_name){
                                        remove_pin_assignment($self);
                                        remove_pin_assignment($self);
                                        my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
                                        my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
                                        #delete jtag_intfc.sh file
                                        #delete jtag_intfc.sh file
                                        unlink "${fpath}../sw/jtag_intfc.sh";
                                        unlink "${fpath}../sw/jtag_intfc.sh";
                                        #program_device.sh file  
                                        #program_device.sh file  
                                        unlink "${fpath}../program_device.sh";
                                        unlink "${fpath}../program_device.sh";
                                }
                                }
 
 
                                my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
                                my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
                                my $board_top_file= "$fpath/Top.v";
                                my $board_top_file= "$fpath/Top.v";
                                unlink $board_top_file if ($old_board_name ne $new_board_name);
                                unlink $board_top_file if ($old_board_name ne $new_board_name);
 
 
 
 
                        }
                        }
                        if($new_board_name eq "Add New Board") {add_new_fpga_board($self,$name,$top,$target_dir,$end_func,$vendor);}
                        if($new_board_name eq "Add New Board") {add_new_fpga_board($self,$name,$top,$target_dir,$end_func,$vendor);}
                        else {get_pin_assignment($self,$name,$top,$target_dir,$end_func,$vendor);}
                        else {get_pin_assignment($self,$name,$top,$target_dir,$end_func,$vendor);}
                }
                }
 
 
 
 
 
 
 
 
 
 
 
 
                elsif($compiler_type eq "Modelsim"){
                elsif($compiler_type eq "Modelsim"){
                        modelsim_compilation($self,$name,$top,$target_dir,$vendor);
                        modelsim_compilation($self,$name,$top,$target_dir,$vendor);
 
 
                }else{#verilator
                }else{#verilator
                        verilator_compilation_win($self,$name,$top,$target_dir,$vendor);
                        verilator_compilation_win($self,$name,$top,$target_dir,$vendor);
 
 
                }
                }
 
 
                $window->destroy;
                $window->destroy;
 
 
        });
        });
 
 
        $compiler->signal_connect("changed" => sub{
        $compiler->signal_connect("changed" => sub{
                $compiler_options->destroy;
                $compiler_options->destroy;
                my $new_board_name=$self->object_get_attribute('compile','type');
                my $new_board_name=$self->object_get_attribute('compile','type');
                $compiler_options =
                $compiler_options =
                        ($new_board_name eq "QuartusII")? select_board  ($self,$name,$top,$target_dir,"Altera"):
                        ($new_board_name eq "QuartusII")? select_board  ($self,$name,$top,$target_dir,"Altera"):
                        ($new_board_name eq "Vivado")? select_board  ($self,$name,$top,$target_dir,"Xilinx"):
                        ($new_board_name eq "Vivado")? select_board  ($self,$name,$top,$target_dir,"Xilinx"):
                        ($new_board_name eq "Modelsim")?  select_model_path  ($self,$name,$top,$target_dir):
                        ($new_board_name eq "Modelsim")?  select_model_path  ($self,$name,$top,$target_dir):
                        ($new_board_name eq "Verilator")? select_parallel_process_num ($self,$name,$top,$target_dir):
                        ($new_board_name eq "Verilator")? select_parallel_process_num ($self,$name,$top,$target_dir):
                        gen_label_in_center(" ");
                        gen_label_in_center(" ");
                $table->attach($compiler_options,0,2,1,2,'fill','shrink',2,2);
                $table->attach($compiler_options,0,2,1,2,'fill','shrink',2,2);
                $table->show_all;
                $table->show_all;
 
 
        });
        });
 
 
}
}
 
 
 
 
 
 
 
 
 
 
 
 
sub select_board {
sub select_board {
        my ($self,$name,$top,$target_dir,$vendor)=@_;
        my ($self,$name,$top,$target_dir,$vendor)=@_;
 
 
        #get the list of boards located in "boards/*" folder
        #get the list of boards located in "boards/*" folder
        my @dirs = grep {-d} glob("../boards/$vendor/*");
        my @dirs = grep {-d} glob("../boards/$vendor/*");
        my ($fpgas,$init);
        my ($fpgas,$init);
        $fpgas="Add New Board";
        $fpgas="Add New Board";
 
 
        foreach my $dir (@dirs) {
        foreach my $dir (@dirs) {
                my ($name,$path,$suffix) = fileparse("$dir",qr"\..[^.]*$");
                my ($name,$path,$suffix) = fileparse("$dir",qr"\..[^.]*$");
 
 
                $fpgas= (defined $fpgas)? "$fpgas,$name" : "$name";
                $fpgas= (defined $fpgas)? "$fpgas,$name" : "$name";
                $init="$name";
                $init="$name";
        }
        }
        my $table = def_table(2, 2, FALSE);
        my $table = def_table(2, 2, FALSE);
        my $col=0;
        my $col=0;
        my $row=0;
        my $row=0;
    my $compiler = ($vendor eq "Altera")? 'quartus' : 'vivado';
    my $compiler = ($vendor eq "Altera")? 'quartus' : 'vivado';
    my $bin_name = "$compiler bin";
    my $bin_name = "$compiler bin";
    my $env = ($vendor eq "Altera")? "QUARTUS_BIN" : "VIVADO_BIN";
    my $env = ($vendor eq "Altera")? "QUARTUS_BIN" : "VIVADO_BIN";
        my $Fpga_bin=   $ENV{$env};
        my $Fpga_bin=   $ENV{$env};
 
 
        my $old_board_name=$self->object_get_attribute('compile','board');
        my $old_board_name=$self->object_get_attribute('compile','board');
        $table->attach(gen_label_help("The list of supported boards are obtained from \"mpsoc/boards/$vendor\" path. You can add your boards by adding its required files in aformentioned path. Note that currently Altera and Xilinx FPGAs are supported.",'Targeted Board:'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
        $table->attach(gen_label_help("The list of supported boards are obtained from \"mpsoc/boards/$vendor\" path. You can add your boards by adding its required files in aformentioned path. Note that currently Altera and Xilinx FPGAs are supported.",'Targeted Board:'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
        $table->attach(gen_combobox_object ($self,'compile','board',$fpgas,$init,undef,undef),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$row++;
        $table->attach(gen_combobox_object ($self,'compile','board',$fpgas,$init,undef,undef),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$row++;
        my $bin =  $self->object_get_attribute('compile',$bin_name);
        my $bin =  $self->object_get_attribute('compile',$bin_name);
 
 
        $col=0;
        $col=0;
        $self->object_add_attribute('compile',$bin_name,$Fpga_bin) if (!defined $bin && defined $Fpga_bin);
        $self->object_add_attribute('compile',$bin_name,$Fpga_bin) if (!defined $bin && defined $Fpga_bin);
        $table->attach(gen_label_help("Path to $vendor/bin directory. You can set a default path as $env environment variable in ~/.bashrc file.
        $table->attach(gen_label_help("Path to $vendor/bin directory. You can set a default path as $env environment variable in ~/.bashrc file.
e.g:  export $env=/home/alireza/$compiler/bin","$env:"),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
e.g:  export $env=/home/alireza/$compiler/bin","$env:"),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
        $table->attach(get_dir_in_object ($self,'compile',$bin_name,undef,undef,undef),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$row++;
        $table->attach(get_dir_in_object ($self,'compile',$bin_name,undef,undef,undef),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$row++;
 
 
 
 
 
 
 
 
 
 
        return $table;
        return $table;
 
 
}
}
 
 
 
 
 
 
 
 
sub select_model_path {
sub select_model_path {
        my ($self,$name,$top,$target_dir)=@_;
        my ($self,$name,$top,$target_dir)=@_;
 
 
 
 
        my $table = def_table(2, 2, FALSE);
        my $table = def_table(2, 2, FALSE);
        my $col=0;
        my $col=0;
        my $row=0;
        my $row=0;
 
 
 
 
 
 
 
 
        my $bin = $self->object_get_attribute('compile','modelsim_bin');
        my $bin = $self->object_get_attribute('compile','modelsim_bin');
        my $modelsim_bin=  $ENV{MODELSIM_BIN};
        my $modelsim_bin=  $ENV{MODELSIM_BIN};
        $col=0;
        $col=0;
        $self->object_add_attribute('compile','modelsim_bin',$modelsim_bin) if (!defined $bin && defined $modelsim_bin);
        $self->object_add_attribute('compile','modelsim_bin',$modelsim_bin) if (!defined $bin && defined $modelsim_bin);
        $table->attach(gen_label_help("Path to modelsim/bin directory. You can set a default path as MODELSIM_BIN environment variable in ~/.bashrc file.
        $table->attach(gen_label_help("Path to modelsim/bin directory. You can set a default path as MODELSIM_BIN environment variable in ~/.bashrc file.
e.g.  export MODELSIM_BIN=/home/alireza/altera/modeltech/bin",'Modelsim  bin:'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
e.g.  export MODELSIM_BIN=/home/alireza/altera/modeltech/bin",'Modelsim  bin:'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
        $table->attach(get_dir_in_object ($self,'compile','modelsim_bin',undef,undef,undef),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$row++;
        $table->attach(get_dir_in_object ($self,'compile','modelsim_bin',undef,undef,undef),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$row++;
 
 
        return $table;
        return $table;
 
 
}
}
 
 
 
my $cpu_num;
sub select_parallel_process_num {
sub select_parallel_process_num {
        my ($self,$name,$top,$target_dir)=@_;
        my ($self,$name,$top,$target_dir)=@_;
        my $table = def_table(2, 2, FALSE);
        my $table = def_table(2, 2, FALSE);
        my $col=0;
        my $col=0;
        my $row=0;
        my $row=0;
 
 
        #get total number of processor in the system
        #get total number of processor in the system
        my $cmd = "nproc\n";
        my $cmd = "nproc\n";
        my $cpu_num=4;
        if(!defined $cpu_num){
        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){
                #nproc command has failed. set default 4 paralel processor
                        #nproc command has failed. set default 4 paralel processor
 
 
        }else {
                }else {
                 my ($number ) = $stdout =~ /(\d+)/;
                        my ($number ) = $stdout =~ /(\d+)/;
                 if (defined  $number ){
                        if (defined  $number ){
                        $cpu_num =$number if  ($number > 0 );
                                $cpu_num =$number if  ($number > 0 );
                 }
                        }
        }
        }
 
        }
        ($row,$col)= add_param_widget ($self,"Paralle run:" , "cpu_num", 1, 'Spin-button', "1,$cpu_num,1","specify the number of processors the Verilator can use at once to run parallel compilations/simulations", $table,$row,$col,1, 'compile', undef,undef,'vertical');
        ($row,$col)= add_param_widget ($self,"Paralle run:" , "cpu_num", 1, 'Spin-button', "1,$cpu_num,1","specify the number of processors the Verilator can use at once to run parallel compilations/simulations", $table,$row,$col,1, 'compile', undef,undef,'vertical');
        return $table;
        return $table;
}
}
 
 
sub select_parallel_thread_num {
sub select_parallel_thread_num {
        my ($self,$name,$top,$target_dir)=@_;
        my ($self,$name,$top,$target_dir)=@_;
        my $table = def_table(2, 2, FALSE);
        my $table = def_table(2, 2, FALSE);
        my $col=0;
        my $col=0;
        my $row=0;
        my $row=0;
 
 
        #get total number of processor in the system
        #get total number of processor in the system
        my $cmd = "nproc\n";
        my $cmd = "nproc\n";
        my $cpu_num=4;
        if(!defined $cpu_num){
        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){
                #nproc command has failed. set default 4 paralel processor
                        #nproc command has failed. set default 4 paralel processor
 
 
        }else {
                }else {
                 my ($number ) = $stdout =~ /(\d+)/;
                        my ($number ) = $stdout =~ /(\d+)/;
                 if (defined  $number ){
                        if (defined  $number ){
                        $cpu_num =$number if  ($number > 0 );
                                $cpu_num =$number if  ($number > 0 );
                 }
                        }
        }
        }
 
        }
        ($row,$col)= add_param_widget ($self,"Thread run:" , "thread_num", 1, 'Spin-button', "1,$cpu_num,1","specify the number of threads the Verilator can use at once in one simulation", $table,$row,$col,1, 'compile', undef,undef,'vertical');
        ($row,$col)= add_param_widget ($self,"Thread run:" , "thread_num", 1, 'Spin-button', "1,$cpu_num,1","specify the number of threads the Verilator can use at once in one simulation", $table,$row,$col,1, 'compile', undef,undef,'vertical');
        return $table;
        return $table;
}
}
 
 
 
 
 
 
 
 
sub remove_pin_assignment{
sub remove_pin_assignment{
        my $self=shift;
        my $self=shift;
        $self->object_remove_attribute('compile_pin_pos');
        $self->object_remove_attribute('compile_pin_pos');
        $self->object_remove_attribute('compile_pin');
        $self->object_remove_attribute('compile_pin');
        $self->object_remove_attribute('compile_assign_type');
        $self->object_remove_attribute('compile_assign_type');
        $self->object_remove_attribute('compile_pin_range_hsb');
        $self->object_remove_attribute('compile_pin_range_hsb');
        $self->object_remove_attribute('compile_pin_range_lsb');
        $self->object_remove_attribute('compile_pin_range_lsb');
}
}
 
 
 
 
 
 
sub add_new_fpga_board{
sub add_new_fpga_board{
 
 
        my ($self,$name,$top,$target_dir,$end_func,$vendor)=@_;
        my ($self,$name,$top,$target_dir,$end_func,$vendor)=@_;
 
 
        my $window = def_popwin_size(50,80,"Add New $vendor FPGA Board",'percent');
        my $window = def_popwin_size(50,80,"Add New $vendor FPGA Board",'percent');
        my $table = def_table(2, 2, FALSE);
        my $table = def_table(2, 2, FALSE);
        my $scrolled_win=add_widget_to_scrolled_win($table);
        my $scrolled_win=add_widget_to_scrolled_win($table);
 
 
 
 
        my $mtable = def_table(10, 10, FALSE);
        my $mtable = def_table(10, 10, FALSE);
 
 
        my $next=def_image_button('icons/plus.png','Add');
        my $next=def_image_button('icons/plus.png','Add');
        my $back=def_image_button('icons/left.png','Previous');
        my $back=def_image_button('icons/left.png','Previous');
        $mtable->attach_defaults($scrolled_win,0,10,0,9);
        $mtable->attach_defaults($scrolled_win,0,10,0,9);
        $mtable->attach($back,2,3,9,10,'shrink','shrink',2,2) if (defined $name);
        $mtable->attach($back,2,3,9,10,'shrink','shrink',2,2) if (defined $name);
        $mtable->attach($next,8,9,9,10,'shrink','shrink',2,2);
        $mtable->attach($next,8,9,9,10,'shrink','shrink',2,2);
 
 
 
 
        my ($Twin,$tview)=create_txview();
        my ($Twin,$tview)=create_txview();
 
 
 
 
        my $widgets=
        my $widgets=
                ($vendor eq 'Altera')? add_new_altera_fpga_board_widgets($self,$name,$top,$target_dir,$end_func,$vendor):
                ($vendor eq 'Altera')? add_new_altera_fpga_board_widgets($self,$name,$top,$target_dir,$end_func,$vendor):
                add_new_xilinx_fpga_board_widgets($self,$name,$top,$target_dir,$end_func,$vendor,$tview);
                add_new_xilinx_fpga_board_widgets($self,$name,$top,$target_dir,$end_func,$vendor,$tview);
 
 
 
 
 
 
        my $v1=gen_vpaned($widgets,0.3,$Twin);
        my $v1=gen_vpaned($widgets,0.3,$Twin);
 
 
        $table->attach_defaults($v1,0,3,0,2);
        $table->attach_defaults($v1,0,3,0,2);
        #$table->attach_defaults( $Twin,0,3,1,2);       
        #$table->attach_defaults( $Twin,0,3,1,2);       
 
 
 
 
 
 
 
 
        $back-> signal_connect("clicked" => sub{
        $back-> signal_connect("clicked" => sub{
 
 
                $window->destroy;
                $window->destroy;
                select_compiler($self,$name,$top,$target_dir,$end_func);
                select_compiler($self,$name,$top,$target_dir,$end_func);
 
 
        });
        });
 
 
        $next-> signal_connect("clicked" => sub{
        $next-> signal_connect("clicked" => sub{
                my $result = ($vendor eq 'Altera')?
                my $result = ($vendor eq 'Altera')?
                        add_new_altera_fpga_board_files($self,$vendor):
                        add_new_altera_fpga_board_files($self,$vendor):
                        add_new_xilinx_fpga_board_files($self,$vendor);
                        add_new_xilinx_fpga_board_files($self,$vendor);
 
 
                if(! defined $result ){
                if(! defined $result ){
                        select_compiler($self,$name,$top,$target_dir,$end_func) if (defined $name);
                        select_compiler($self,$name,$top,$target_dir,$end_func) if (defined $name);
                        $window->destroy;
                        $window->destroy;
                        message_dialog("The new board has been added successfully!");
                        message_dialog("The new board has been added successfully!");
                }else {
                }else {
                        show_info($tview," ");
                        show_info($tview," ");
                        show_colored_info($tview,$result,'red');
                        show_colored_info($tview,$result,'red');
                }
                }
 
 
        });
        });
 
 
 
 
 
 
        if($vendor eq 'Altera'){
        if($vendor eq 'Altera'){
            my $auto=def_image_button('icons/advance.png','Auto-fill');
            my $auto=def_image_button('icons/advance.png','Auto-fill');
            set_tip($auto, "Auto-fill JTAG configuration. The board must be powered on and be connected to the PC.");
            set_tip($auto, "Auto-fill JTAG configuration. The board must be powered on and be connected to the PC.");
                $mtable->attach($auto,5,6,9,10,'shrink','shrink',2,2);
                $mtable->attach($auto,5,6,9,10,'shrink','shrink',2,2);
                $auto-> signal_connect("clicked" => sub{
                $auto-> signal_connect("clicked" => sub{
                        my $pid;
                        my $pid;
                        my $hw;
                        my $hw;
 
 
                        my $project_dir   = get_project_dir();
                        my $project_dir   = get_project_dir();
                        my $command=  "$project_dir/mpsoc/src_c/jtag/jtag_libusb/list_usb_dev";
                        my $command=  "$project_dir/mpsoc/src_c/jtag/jtag_libusb/list_usb_dev";
                        add_info($tview,"$command\n");
                        add_info($tview,"$command\n");
                        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($command);
                        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($command);
                        if(length $stderr>1){
                        if(length $stderr>1){
                                add_colored_info($tview,"$stderr\n",'red');
                                add_colored_info($tview,"$stderr\n",'red');
                                add_colored_info($tview,"$command was not run successfully!\n",'red');
                                add_colored_info($tview,"$command was not run successfully!\n",'red');
                        }else {
                        }else {
 
 
                                if($exit){
                                if($exit){
                                        add_colored_info($tview,"$stdout\n",'red');
                                        add_colored_info($tview,"$stdout\n",'red');
                                        add_colored_info($tview,"$command was not run successfully!\n",'red');
                                        add_colored_info($tview,"$command was not run successfully!\n",'red');
                                }else{
                                }else{
                                        add_info($tview,"$stdout\n");
                                        add_info($tview,"$stdout\n");
                                        my @a=split /vid=9fb/, $stdout;
                                        my @a=split /vid=9fb/, $stdout;
                                        if(defined $a[1]){
                                        if(defined $a[1]){
                                                my @b=split /pid=/, $a[1];
                                                my @b=split /pid=/, $a[1];
                                                my @c=split /\n/, $b[1];
                                                my @c=split /\n/, $b[1];
                                                $pid=$c[0];
                                                $pid=$c[0];
                                                $self->object_add_attribute('compile','quartus_pid',$pid);
                                                $self->object_add_attribute('compile','quartus_pid',$pid);
                                                add_colored_info($tview,"Detected PID: $pid\n",'blue');
                                                add_colored_info($tview,"Detected PID: $pid\n",'blue');
 
 
                                        }else{
                                        }else{
                                                add_colored_info($tview,"The Altera vendor ID of 9fb is not detected. Make sure You have connected your Altera board to your USB port\n",'red');
                                                add_colored_info($tview,"The Altera vendor ID of 9fb is not detected. Make sure You have connected your Altera board to your USB port\n",'red');
                                                return;
                                                return;
                                        }
                                        }
                                }
                                }
                        }
                        }
 
 
 
 
                        $command=  "$ENV{QUARTUS_BIN}/jtagconfig";
                        $command=  "$ENV{QUARTUS_BIN}/jtagconfig";
                        add_info($tview,"$command\n");
                        add_info($tview,"$command\n");
                        ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($command);
                        ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($command);
                        if(length $stderr>1){
                        if(length $stderr>1){
                                add_colored_info($tview,"$stderr\n",'red');
                                add_colored_info($tview,"$stderr\n",'red');
                                add_colored_info($tview,"$command was not run successfully!\n",'red');
                                add_colored_info($tview,"$command was not run successfully!\n",'red');
                        }else {
                        }else {
 
 
                                if($exit){
                                if($exit){
                                        add_colored_info($tview,"$stdout\n",'red');
                                        add_colored_info($tview,"$stdout\n",'red');
                                        add_colored_info($tview,"$command was not run successfully!\n",'red');
                                        add_colored_info($tview,"$command was not run successfully!\n",'red');
                                }else{
                                }else{
                                        add_info($tview,"$stdout\n");
                                        add_info($tview,"$stdout\n");
                                        my @a=split /1\)\s+/, $stdout;
                                        my @a=split /1\)\s+/, $stdout;
                                        if(defined $a[1]){
                                        if(defined $a[1]){
                                                my @b=split /\s+/, $a[1];
                                                my @b=split /\s+/, $a[1];
                                                $hw=$b[0];
                                                $hw=$b[0];
                                                $self->object_add_attribute('compile','quartus_hardware',$hw);
                                                $self->object_add_attribute('compile','quartus_hardware',$hw);
                                                add_colored_info($tview,"Detected Hardware: $hw\n",'blue');
                                                add_colored_info($tview,"Detected Hardware: $hw\n",'blue');
                                                my $qsf=$self->object_get_attribute('compile','board_confg_file');
                                                my $qsf=$self->object_get_attribute('compile','board_confg_file');
                                                if(!defined $qsf ){
                                                if(!defined $qsf ){
                                                        add_colored_info ($tview,"Cannot detect device location in JTAG chin. Please enter the QSF file or fill in manually \n",'red');
                                                        add_colored_info ($tview,"Cannot detect device location in JTAG chin. Please enter the QSF file or fill in manually \n",'red');
 
 
                                                }else{
                                                }else{
                                                        #search for device name in qsf file
                                                        #search for device name in qsf file
                                                        $qsf=add_project_dir_to_addr($qsf);
                                                        $qsf=add_project_dir_to_addr($qsf);
                                                        if (!(-f $qsf)){
                                                        if (!(-f $qsf)){
                                                                add_colored_info($tview, "Error Could not find $qsf file!\n");
                                                                add_colored_info($tview, "Error Could not find $qsf file!\n");
                                                                return;
                                                                return;
                                                        }
                                                        }
                                                        my $str=load_file($qsf);
                                                        my $str=load_file($qsf);
                                                        my $dw= capture_string_between(' DEVICE ',$str,"\n");
                                                        my $dw= capture_string_between(' DEVICE ',$str,"\n");
                                                        if(defined $dw){
                                                        if(defined $dw){
                                                        add_colored_info($tview,"Device name in qsf file is: $dw\n",'blue');
                                                        add_colored_info($tview,"Device name in qsf file is: $dw\n",'blue');
                                                        @b=split /\n/, $a[1];
                                                        @b=split /\n/, $a[1];
 
 
                                                        #capture device name in JTAG chain
                                                        #capture device name in JTAG chain
                                                                my @f=(0);
                                                                my @f=(0);
                                                                foreach my $c (@b){
                                                                foreach my $c (@b){
                                                                        my @e=split /\s+/, $c;
                                                                        my @e=split /\s+/, $c;
                                                                        push(@f,$e[2]) if(defined $e[2]);
                                                                        push(@f,$e[2]) if(defined $e[2]);
                                                                }
                                                                }
 
 
                                                                my $pos=find_the_most_similar_position($dw ,@f);
                                                                my $pos=find_the_most_similar_position($dw ,@f);
                                                                $self->object_add_attribute('compile','quartus_device',$pos);
                                                                $self->object_add_attribute('compile','quartus_device',$pos);
                                                        add_colored_info($tview,"$dw has the most similarity with $f[$pos] in JTAG chain\n",'blue');
                                                        add_colored_info($tview,"$dw has the most similarity with $f[$pos] in JTAG chain\n",'blue');
 
 
 
 
                                                    }else{
                                                    }else{
                                                        add_colored_info ($tview, "Could not find device name in the $qsf file!\n");
                                                        add_colored_info ($tview, "Could not find device name in the $qsf file!\n");
                                                    }
                                                    }
 
 
                                                }
                                                }
 
 
 
 
                                        }else{
                                        }else{
                                                #add_colored_info($tview,"The Altera vendor ID of 9fb is not detected. Make sure You have connected your Altera board to your USB port\n",'red');
                                                #add_colored_info($tview,"The Altera vendor ID of 9fb is not detected. Make sure You have connected your Altera board to your USB port\n",'red');
 
 
                                        }
                                        }
 
 
                                }
                                }
                        }
                        }
                        $widgets->destroy();
                        $widgets->destroy();
                        $widgets= add_new_altera_fpga_board_widgets($self,$name,$top,$target_dir,$end_func,$vendor);
                        $widgets= add_new_altera_fpga_board_widgets($self,$name,$top,$target_dir,$end_func,$vendor);
                        $v1-> pack1($widgets, TRUE, TRUE);
                        $v1-> pack1($widgets, TRUE, TRUE);
                        #$table->attach_defaults($widgets,0,3,0,1); 
                        #$table->attach_defaults($widgets,0,3,0,1); 
                        $table->show_all();
                        $table->show_all();
                 #      my $cmd=" $ENV{'QUARTUS_BIN'}"
                 #      my $cmd=" $ENV{'QUARTUS_BIN'}"
 
 
                });
                });
 
 
 
 
        }
        }
 
 
 
 
 
 
 
 
        $window->add ($mtable);
        $window->add ($mtable);
        $window->show_all();
        $window->show_all();
 
 
}
}
 
 
 
 
 
 
sub add_new_xilinx_fpga_board_widgets{
sub add_new_xilinx_fpga_board_widgets{
        my ($self,$name,$top,$target_dir,$end_func,$vendor,$tview)=@_;
        my ($self,$name,$top,$target_dir,$end_func,$vendor,$tview)=@_;
        my $table = def_table(2, 2, FALSE);
        my $table = def_table(2, 2, FALSE);
 
 
        my $col=0;
        my $col=0;
        my $row=0;
        my $row=0;
 
 
        my $help1="Your given FPGA Board name. Do not use any space in given name";
        my $help1="Your given FPGA Board name. Do not use any space in given name";
        my $help2="Path to FPGA board xdc file. In your Xilinx board installation CD or in the Internet, search for a xdc file containing your FPGA device pin assignment constrain).";
        my $help2="Path to FPGA board xdc file. In your Xilinx board installation CD or in the Internet, search for a xdc file containing your FPGA device pin assignment constrain).";
        my $help3="Path to FPGA_board_top.v file. A Verilog file containing all your FPGA device IO ports.";
        my $help3="Path to FPGA_board_top.v file. A Verilog file containing all your FPGA device IO ports.";
        my $help4="Your Board name (Board PART) e.g. digilentinc.com:arty-z7-20:part0:1.0";
        my $help4="Your Board name (Board PART) e.g. digilentinc.com:arty-z7-20:part0:1.0";
        my $help5="Your FPGA device name (PART) e.g. xc7z020clg400-1 ";
        my $help5="Your FPGA device name (PART) e.g. xc7z020clg400-1 ";
        my $help6="The order number of target device in jtag chain. Run jtag targets after \"connect\" command in xsct terminal to list all available targets.";
        my $help6="The order number of target device in jtag chain. Run jtag targets after \"connect\" command in xsct terminal to list all available targets.";
        my $help7="Path to Vivado board files repository. E.g download the repo from https://github.com/Digilent/vivado-boards and save in \$ProNoC_work/toolchain/board_files folder.";
        my $help7="Path to Vivado board files repository. E.g download the repo from https://github.com/Digilent/vivado-boards and save in \$ProNoC_work/toolchain/board_files folder.";
        my $help8="Hardware device name e.g. xc7z020_1. To find it you can connect your FPGA board to your PC. In tcl terminal run
        my $help8="Hardware device name e.g. xc7z020_1. To find it you can connect your FPGA board to your PC. In tcl terminal run
                open_hw
                open_hw
                connect_hw_server
                connect_hw_server
                open_hw_target
                open_hw_target
                get_hw_devices
                get_hw_devices
It supposed to show the list of your hardware devices in your FPGA. Select the name represent your FPGA device
It supposed to show the list of your hardware devices in your FPGA. Select the name represent your FPGA device
                ";
                ";
 
 
 
 
        my $repo ="$ENV{PRONOC_WORK}/toolchain/board_files";
        my $repo ="$ENV{PRONOC_WORK}/toolchain/board_files";
 
 
 
 
        $row++;
        $row++;
 
 
        my @info = (
        my @info = (
        { label=>"FPGA board display name:",        param_name=>'fpga_board', type=>"Entry",     default_val=>undef, content=>undef, info=>$help1, param_parent=>'compile', ref_delay=> undef},
        { label=>"FPGA board display name:",        param_name=>'fpga_board', type=>"Entry",     default_val=>undef, content=>undef, info=>$help1, param_parent=>'compile', ref_delay=> undef},
        { label=>"Set board repo:", param_name=>'fpga_board_repo',  type=>"DIR_path", default_val=>"$repo", content=>undef, info=>$help7, param_parent=>'compile',ref_delay=>undef},
        { label=>"Set board repo:", param_name=>'fpga_board_repo',  type=>"DIR_path", default_val=>"$repo", content=>undef, info=>$help7, param_parent=>'compile',ref_delay=>undef},
        { label=>"FPGA board part name:", param_name=>'fpga_board_part', type=>"EntryCombo",default_val=>undef, content=>undef, info =>$help4, param_parent=>'compile', ref_delay=> undef},
        { label=>"FPGA board part name:", param_name=>'fpga_board_part', type=>"EntryCombo",default_val=>undef, content=>undef, info =>$help4, param_parent=>'compile', ref_delay=> undef},
        { label=>"FPGA part name:",       param_name=>'fpga_part', type=>"Entry",     default_val=>undef, content=>undef, info=>$help5, param_parent=>'compile', ref_delay=> undef},
        { label=>"FPGA part name:",       param_name=>'fpga_part', type=>"Entry",     default_val=>undef, content=>undef, info=>$help5, param_parent=>'compile', ref_delay=> undef},
    { label=>"FPGA Hardware device name:", param_name=>'fpga_hw_device', type=>"EntryCombo", default_val=>undef, content=>undef, info=>$help8, param_parent=>'compile', ref_delay=> undef},
    { label=>"FPGA Hardware device name:", param_name=>'fpga_hw_device', type=>"EntryCombo", default_val=>undef, content=>undef, info=>$help8, param_parent=>'compile', ref_delay=> undef},
        { label=>"Target device JTAG chain order number", param_name=>'fpga_board_order',  type=>"Spin-button", default_val=>1, content=>"0,256,1", info=>$help6, param_parent=>'compile',ref_delay=>undef},
        { label=>"Target device JTAG chain order number", param_name=>'fpga_board_order',  type=>"Spin-button", default_val=>1, content=>"0,256,1", info=>$help6, param_parent=>'compile',ref_delay=>undef},
        { label=>'FPGA board xdc file:',    param_name=>'board_confg_file',   type=>"FILE_path", default_val=>undef, content=>"xdc", info=>$help2, param_parent=>'compile', ref_delay=>undef},
        { label=>'FPGA board xdc file:',    param_name=>'board_confg_file',   type=>"FILE_path", default_val=>undef, content=>"xdc", info=>$help2, param_parent=>'compile', ref_delay=>undef},
        { label=>"FPGA board golden top Verilog file", param_name=>'fpga_board_v',     type=>"FILE_path", default_val=>undef, content=>"v", info=>$help3, param_parent=>'compile',ref_delay=>undef},
        { label=>"FPGA board golden top Verilog file", param_name=>'fpga_board_v',     type=>"FILE_path", default_val=>undef, content=>"v", info=>$help3, param_parent=>'compile',ref_delay=>undef},
                );
                );
        my %widgets;
        my %widgets;
        my %rows;
        my %rows;
        foreach my $d (@info) {
        foreach my $d (@info) {
                $rows{$d->{param_name}} =$row;
                $rows{$d->{param_name}} =$row;
                ($row,$col,$widgets{$d->{param_name}})=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,$widgets{$d->{param_name}})=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');
        }
        }
 
 
        my $icon = 'icons/advance.png';
        my $icon = 'icons/advance.png';
        my $search=def_image_button($icon,undef);
        my $search=def_image_button($icon,undef);
        my $search_board=def_image_button ($icon,undef);
        my $search_board=def_image_button ($icon,undef);
        my $search_dev=def_image_button ($icon,undef);
        my $search_dev=def_image_button ($icon,undef);
        my $search_chain=def_image_button ($icon,undef);
        my $search_chain=def_image_button ($icon,undef);
 
 
        $table->attach($search,4,5,$rows{'fpga_board_part'},$rows{'fpga_board_part'}+1,'fill','shrink',2,2);
        $table->attach($search,4,5,$rows{'fpga_board_part'},$rows{'fpga_board_part'}+1,'fill','shrink',2,2);
        $table->attach($search_board,4,5,$rows{'fpga_part'},$rows{'fpga_part'}+1,'fill','shrink',2,2);
        $table->attach($search_board,4,5,$rows{'fpga_part'},$rows{'fpga_part'}+1,'fill','shrink',2,2);
        $table->attach($search_dev,4,5,$rows{'fpga_hw_device'},$rows{'fpga_hw_device'}+1,'fill','shrink',2,2);
        $table->attach($search_dev,4,5,$rows{'fpga_hw_device'},$rows{'fpga_hw_device'}+1,'fill','shrink',2,2);
        $table->attach($search_chain,4,5,$rows{'fpga_board_order'},$rows{'fpga_board_order'}+1,'fill','shrink',2,2);
        $table->attach($search_chain,4,5,$rows{'fpga_board_order'},$rows{'fpga_board_order'}+1,'fill','shrink',2,2);
 
 
 
 
        $search->signal_connect("clicked" => sub{
        $search->signal_connect("clicked" => sub{
                        my $load= show_gif("icons/load.gif");
                        my $load= show_gif("icons/load.gif");
                        $table->attach ($load,5, 6, $rows{'fpga_board_part'},$rows{'fpga_board_part'}+ 1,'shrink','shrink',0,0);
                        $table->attach ($load,5, 6, $rows{'fpga_board_part'},$rows{'fpga_board_part'}+ 1,'shrink','shrink',0,0);
                        $table->show_all;
                        $table->show_all;
                        my $result=     set_xilinx_board_from_repo($self,$tview);
                        my $result=     set_xilinx_board_from_repo($self,$tview);
                        update_combo_entry_content($widgets{'fpga_board_part'}, $result);
                        update_combo_entry_content($widgets{'fpga_board_part'}, $result);
                        $load->destroy;
                        $load->destroy;
                        $table->show_all;
                        $table->show_all;
                });
                });
 
 
 
 
        $search_board->signal_connect("clicked" => sub{
        $search_board->signal_connect("clicked" => sub{
                        my $load= show_gif("icons/load.gif");
                        my $load= show_gif("icons/load.gif");
                        $table->attach ($load,5, 6, $rows{'fpga_part'},$rows{'fpga_part'}+1, 'shrink','shrink',0,0);
                        $table->attach ($load,5, 6, $rows{'fpga_part'},$rows{'fpga_part'}+1, 'shrink','shrink',0,0);
                        $table->show_all;
                        $table->show_all;
                        my $result=     get_xilinx_board_part($self,$tview);
                        my $result=     get_xilinx_board_part($self,$tview);
                        $widgets{'fpga_part'}->set_text($result);
                        $widgets{'fpga_part'}->set_text($result);
                        #print "result = $result\n";
                        #print "result = $result\n";
                        $load->destroy;
                        $load->destroy;
                        $table->show_all;
                        $table->show_all;
                });
                });
        $search_dev->signal_connect("clicked" => sub{
        $search_dev->signal_connect("clicked" => sub{
                        my $load= show_gif("icons/load.gif");
                        my $load= show_gif("icons/load.gif");
                        $table->attach ($load,5, 6, $rows{'fpga_hw_device'},$rows{'fpga_hw_device'}+ 1,'shrink','shrink',0,0);
                        $table->attach ($load,5, 6, $rows{'fpga_hw_device'},$rows{'fpga_hw_device'}+ 1,'shrink','shrink',0,0);
                        $table->show_all;
                        $table->show_all;
                        my $result=     get_xilinx_device_names($self,$tview);
                        my $result=     get_xilinx_device_names($self,$tview);
                        update_combo_entry_content($widgets{'fpga_hw_device'}, $result);
                        update_combo_entry_content($widgets{'fpga_hw_device'}, $result);
                        $load->destroy;
                        $load->destroy;
                        $table->show_all;
                        $table->show_all;
                });
                });
        $search_chain->signal_connect("clicked" => sub{
        $search_chain->signal_connect("clicked" => sub{
                my $targets = show_all_xilinx_targets($self,$tview);
                my $targets = show_all_xilinx_targets($self,$tview);
                if(!defined $targets){
                if(!defined $targets){
                        add_info($tview,"Unable to find the FPGA board target list. Make sure you have connected your FPGA board to your PC first and it is powered on.\n");
                        add_info($tview,"Unable to find the FPGA board target list. Make sure you have connected your FPGA board to your PC first and it is powered on.\n");
                        return;
                        return;
                }
                }
 
 
                my @lines=split(/\r?\n/,$targets);
                my @lines=split(/\r?\n/,$targets);
                my @list1;
                my @list1;
                my @list2;
                my @list2;
                foreach my $p (@lines){
                foreach my $p (@lines){
                        $p =~ s/^\s+//;#left trim
                        $p =~ s/^\s+//;#left trim
                        my @words=split(/\s+/,$p);
                        my @words=split(/\s+/,$p);
                        push (@list1,$words[0]);
                        push (@list1,$words[0]);
                        push (@list2,$words[1]);
                        push (@list2,$words[1]);
                }
                }
                my $hw =  $self->object_get_attribute('compile','fpga_hw_device');
                my $hw =  $self->object_get_attribute('compile','fpga_hw_device');
                if( !defined $hw){
                if( !defined $hw){
                        add_colored_info($tview,"Please define the FPGA hardware device name first!\n",'red');
                        add_colored_info($tview,"Please define the FPGA hardware device name first!\n",'red');
                        return;
                        return;
                }
                }
                my $pos = find_the_most_similar_position ($hw ,@list2);
                my $pos = find_the_most_similar_position ($hw ,@list2);
                add_info($tview,"$hw matched with target $list1[$pos] $list2[$pos]  ");
                add_info($tview,"$hw matched with target $list1[$pos] $list2[$pos]  ");
                $widgets{'fpga_board_order'}->set_value($list1[$pos]);
                $widgets{'fpga_board_order'}->set_value($list1[$pos]);
        });
        });
 
 
        return ($row, $col, $table);
        return ($row, $col, $table);
}
}
 
 
 
 
 
 
sub set_xilinx_board_from_repo{
sub set_xilinx_board_from_repo{
        my ($self,$tview)=@_;
        my ($self,$tview)=@_;
        my $bin =  $self->object_get_attribute('compile',"vivado bin");
        my $bin =  $self->object_get_attribute('compile',"vivado bin");
        my $vivado =(defined $bin)?  "${bin}/vivado" :  "vivado";
        my $vivado =(defined $bin)?  "${bin}/vivado" :  "vivado";
        my $result;
        my $result;
        my $repo= $self->object_get_attribute('compile','fpga_board_repo');
        my $repo= $self->object_get_attribute('compile','fpga_board_repo');
        my $tcl= get_project_dir()."/mpsoc/perl_gui/lib/tcl/vivado_get_boards.tcl -tclargs $repo";
        my $tcl= get_project_dir()."/mpsoc/perl_gui/lib/tcl/vivado_get_boards.tcl -tclargs $repo";
        my $command = "cd $ENV{PRONOC_WORK}/tmp;   $vivado -mode tcl -source $tcl";
        my $command = "cd $ENV{PRONOC_WORK}/tmp;   $vivado -mode tcl -source $tcl";
 
 
        add_info($tview,"$command\n");
        add_info($tview,"$command\n");
        my $stdout=run_cmd_textview_errors($command,$tview);
        my $stdout=run_cmd_textview_errors($command,$tview);
        return if (!defined $stdout);
        return if (!defined $stdout);
        add_info($tview,"$stdout\n");
        add_info($tview,"$stdout\n");
        my @boards=split(/\s+/,$stdout);
        my @boards=split(/\s+/,$stdout);
        my $r=0;
        my $r=0;
        foreach my $board (@boards){
        foreach my $board (@boards){
                my @pp=split(':',$board);
                my @pp=split(':',$board);
                if(scalar @pp  == 4 && $pp[1] =~ /[a-zA-Z]+/) {
                if(scalar @pp  == 4 && $pp[1] =~ /[a-zA-Z]+/) {
                        $r=1;
                        $r=1;
                        $result= (!defined $result)? "$board" : $result.",$board";
                        $result= (!defined $result)? "$board" : $result.",$board";
                }
                }
        }
        }
        add_colored_info($tview,"$stdout\n",'red') if($r==0);
        add_colored_info($tview,"$stdout\n",'red') if($r==0);
        return $result;
        return $result;
}
}
 
 
 
 
sub get_xilinx_device_names{
sub get_xilinx_device_names{
        my ($self,$tview)=@_;
        my ($self,$tview)=@_;
        my $bin =  $self->object_get_attribute('compile',"vivado bin");
        my $bin =  $self->object_get_attribute('compile',"vivado bin");
        my $vivado =(defined $bin)?  "${bin}/vivado" :  "vivado";
        my $vivado =(defined $bin)?  "${bin}/vivado" :  "vivado";
        my $result;
        my $result;
        my $repo= $self->object_get_attribute('compile','fpga_board_repo');
        my $repo= $self->object_get_attribute('compile','fpga_board_repo');
        my $tcl= get_project_dir()."/mpsoc/perl_gui/lib/tcl/vivado_get_hw_device.tcl -tclargs";
        my $tcl= get_project_dir()."/mpsoc/perl_gui/lib/tcl/vivado_get_hw_device.tcl -tclargs";
        my $command = "cd $ENV{PRONOC_WORK}/tmp;   $vivado -mode tcl -source $tcl";
        my $command = "cd $ENV{PRONOC_WORK}/tmp;   $vivado -mode tcl -source $tcl";
 
 
        add_info($tview,"$command\n");
        add_info($tview,"$command\n");
        my $stdout=run_cmd_textview_errors($command,$tview);
        my $stdout=run_cmd_textview_errors($command,$tview);
        if (!defined $stdout){
        if (!defined $stdout){
                add_info($tview,"Unable to find the FPGA board devices list. Make sure you have connected your FPGA board to your PC first and it is powered on.\n");
                add_info($tview,"Unable to find the FPGA board devices list. Make sure you have connected your FPGA board to your PC first and it is powered on.\n");
                return;
                return;
        }
        }
        add_info($tview,"$stdout\n");
        add_info($tview,"$stdout\n");
        my $devices =  capture_string_between ('\n\*RESULT:',$stdout,"\n");
        my $devices =  capture_string_between ('\n\*RESULT:',$stdout,"\n");
        my @D=split(/\s+/,$devices);
        my @D=split(/\s+/,$devices);
        return join ',', @D;
        return join ',', @D;
}
}
 
 
 
 
 
 
 
 
 
 
 
 
sub get_xilinx_board_part{
sub get_xilinx_board_part{
        my ($self,$tview)=@_;
        my ($self,$tview)=@_;
        my $bin =  $self->object_get_attribute('compile',"vivado bin");
        my $bin =  $self->object_get_attribute('compile',"vivado bin");
        my $vivado =(defined $bin)?  "${bin}/vivado" :  "vivado";
        my $vivado =(defined $bin)?  "${bin}/vivado" :  "vivado";
        my $result;
        my $result;
        my $repo= $self->object_get_attribute('compile','fpga_board_repo');
        my $repo= $self->object_get_attribute('compile','fpga_board_repo');
        my $board_part= $self->object_get_attribute('compile' ,'fpga_board_part');
        my $board_part= $self->object_get_attribute('compile' ,'fpga_board_part');
        if (!defined $board_part  ){
        if (!defined $board_part  ){
                add_colored_info($tview,"Please define the FPGA board part name first!\n",'red');
                add_colored_info($tview,"Please define the FPGA board part name first!\n",'red');
                return;
                return;
        }
        }
 
 
        my $tcl= get_project_dir()."/mpsoc/perl_gui/lib/tcl/vivado_get_part.tcl -tclargs $board_part $repo ";
        my $tcl= get_project_dir()."/mpsoc/perl_gui/lib/tcl/vivado_get_part.tcl -tclargs $board_part $repo ";
 
 
 
 
        my $command = "cd $ENV{PRONOC_WORK}/tmp;   $vivado -mode tcl -source $tcl";
        my $command = "cd $ENV{PRONOC_WORK}/tmp;   $vivado -mode tcl -source $tcl";
 
 
        add_info($tview,"$command\n");
        add_info($tview,"$command\n");
        my $stdout=run_cmd_textview_errors($command,$tview);
        my $stdout=run_cmd_textview_errors($command,$tview);
        return if (!defined $stdout);
        return if (!defined $stdout);
        add_info($tview,"$stdout\n");
        add_info($tview,"$stdout\n");
        return capture_string_between ('\n\*RESULT:',$stdout,"\n");
        return capture_string_between ('\n\*RESULT:',$stdout,"\n");
}
}
 
 
 
 
 
 
sub add_new_altera_fpga_board_widgets{
sub add_new_altera_fpga_board_widgets{
        my ($self,$name,$top,$target_dir,$end_func,$vendor)=@_;
        my ($self,$name,$top,$target_dir,$end_func,$vendor)=@_;
        my $table = def_table(2, 2, FALSE);
        my $table = def_table(2, 2, FALSE);
 
 
        my $help1="FPGA Board name. Do not use any space in given name";
        my $help1="FPGA Board name. Do not use any space in given name";
        my $help2="Path to FPGA board qsf file. In your Altra board installation CD or in the Internet search for a QSF file containing your FPGA device name with other necessary global project setting including the pin assignments (e.g DE10_Nano_golden_top.qsf).";
        my $help2="Path to FPGA board qsf file. In your Altra board installation CD or in the Internet search for a QSF file containing your FPGA device name with other necessary global project setting including the pin assignments (e.g DE10_Nano_golden_top.qsf).";
        my $help3="Path to FPGA_board_top.v file. In your Altra board installation CD or in the Internet search for a Verilog file containing all your FPGA device IO ports (e.g DE10_Nano_golden_top.v).";
        my $help3="Path to FPGA_board_top.v file. In your Altra board installation CD or in the Internet search for a Verilog file containing all your FPGA device IO ports (e.g DE10_Nano_golden_top.v).";
        my $help4="FPGA Board USB-Blaster product ID (PID). Power on your FPGA board and connect it to your PC. Then press Auto-fill button to find PID. Optionally you can run mpsoc/
        my $help4="FPGA Board USB-Blaster product ID (PID). Power on your FPGA board and connect it to your PC. Then press Auto-fill button to find PID. Optionally you can run mpsoc/
src_c/jtag/jtag_libusb/list_usb_dev to find your USB-Blaster PID. Search for PID of a device having 9fb (altera) Vendor ID (VID)";
src_c/jtag/jtag_libusb/list_usb_dev to find your USB-Blaster PID. Search for PID of a device having 9fb (altera) Vendor ID (VID)";
        my $help5="Power on your FPGA board and connect it to your PC. Then press Auto-fill button to find your hardware name. Optionally you can run \$QUARTUS_BIN/jtagconfig to find your programming hardware name.
        my $help5="Power on your FPGA board and connect it to your PC. Then press Auto-fill button to find your hardware name. Optionally you can run \$QUARTUS_BIN/jtagconfig to find your programming hardware name.
an example of output from the 'jtagconfig' command:
an example of output from the 'jtagconfig' command:
\t  1) ByteBlasterMV on LPT1
\t  1) ByteBlasterMV on LPT1
\t       090010DD   EPXA10
\t       090010DD   EPXA10
\t       049220DD   EPXA_ARM922
\t       049220DD   EPXA_ARM922
or
or
\t   1) DE-SoC [1-3]
\t   1) DE-SoC [1-3]
\t       48A00477   SOCVHP5
\t       48A00477   SOCVHP5
\t       02D020DC   5CS(EBA6ES|XFC6c6ES)
\t       02D020DC   5CS(EBA6ES|XFC6c6ES)
ByteBlasterMV \& DE-SoC are the programming hardware name.";
ByteBlasterMV \& DE-SoC are the programming hardware name.";
my $help6="Power on your FPGA board and connect it to your PC. Then press Auto-fill button to find your device location in jtag chain. Optionally you can run \$QUARTUS_BIN/jtagconfig to find your target device location in jtag chain.";
my $help6="Power on your FPGA board and connect it to your PC. Then press Auto-fill button to find your device location in jtag chain. Optionally you can run \$QUARTUS_BIN/jtagconfig to find your target device location in jtag chain.";
 
 
 
 
 
 
 
 
        my @info = (
        my @info = (
        { label=>"FPGA Board Name:",                   param_name=>'fpga_board', type=>"Entry",     default_val=>undef, content=>undef, info=>$help1, param_parent=>'compile', ref_delay=> undef},
        { label=>"FPGA Board Name:",                   param_name=>'fpga_board', type=>"Entry",     default_val=>undef, content=>undef, info=>$help1, param_parent=>'compile', ref_delay=> undef},
        { label=>'FPGA Board Golden top QSF file:',    param_name=>'board_confg_file',   type=>"FILE_path", default_val=>undef, content=>"qsf", info=>$help2, param_parent=>'compile', ref_delay=>undef},
        { label=>'FPGA Board Golden top QSF file:',    param_name=>'board_confg_file',   type=>"FILE_path", default_val=>undef, content=>"qsf", info=>$help2, param_parent=>'compile', ref_delay=>undef},
        { label=>"FPGA Board Golden top Verilog file", param_name=>'fpga_board_v',     type=>"FILE_path", default_val=>undef, content=>"v", info=>$help3, param_parent=>'compile',ref_delay=>undef },
        { label=>"FPGA Board Golden top Verilog file", param_name=>'fpga_board_v',     type=>"FILE_path", default_val=>undef, content=>"v", info=>$help3, param_parent=>'compile',ref_delay=>undef },
        );
        );
 
 
        my @usb = (
        my @usb = (
        { label=>"FPGA Board USB Blaster PID:",        param_name=>'quartus_pid',   type=>"Entry",     default_val=>undef, content=>undef, info=>$help4, param_parent=>'compile', ref_delay=> undef},
        { label=>"FPGA Board USB Blaster PID:",        param_name=>'quartus_pid',   type=>"Entry",     default_val=>undef, content=>undef, info=>$help4, param_parent=>'compile', ref_delay=> undef},
        { label=>"FPGA Board Programming Hardware Name:", param_name=>'quartus_hardware',   type=>"Entry",     default_val=>undef, content=>undef, info=>$help5, param_parent=>'compile', ref_delay=> undef},
        { label=>"FPGA Board Programming Hardware Name:", param_name=>'quartus_hardware',   type=>"Entry",     default_val=>undef, content=>undef, info=>$help5, param_parent=>'compile', ref_delay=> undef},
        { label=>"FPGA Board Device location in JTAG chain:", param_name=>'quartus_device',   type=>"Spin-button",     default_val=>0, content=>"0,100,1", info=>$help6, param_parent=>'compile', ref_delay=> undef},
        { label=>"FPGA Board Device location in JTAG chain:", param_name=>'quartus_device',   type=>"Spin-button",     default_val=>0, content=>"0,100,1", info=>$help6, param_parent=>'compile', ref_delay=> undef},
        );
        );
 
 
 
 
        my $col=0;
        my $col=0;
        my $row=0;
        my $row=0;
        foreach my $d (@info) {
        foreach my $d (@info) {
                ($row,$col)=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)=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");
        }
        }
 
 
        my $labl=def_pack_vbox(FALSE, 0,(gen_Hsep(),gen_label_in_center("FPGA Board JTAG Configuration"),gen_Hsep()));
        my $labl=def_pack_vbox(FALSE, 0,(gen_Hsep(),gen_label_in_center("FPGA Board JTAG Configuration"),gen_Hsep()));
 
 
        $table->attach( $labl,0,3,$row,$row+1,'fill','shrink',2,2); $row++; $col=0;
        $table->attach( $labl,0,3,$row,$row+1,'fill','shrink',2,2); $row++; $col=0;
 
 
        foreach my $d (@usb) {
        foreach my $d (@usb) {
                ($row,$col)=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)=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");
        }
        }
 
 
 
 
        return ($row, $col, $table);
        return ($row, $col, $table);
}
}
 
 
 
 
sub add_new_xilinx_fpga_board_files{
sub add_new_xilinx_fpga_board_files{
        my ($self,$vendor)=@_;
        my ($self,$vendor)=@_;
        #check the board name
        #check the board name
        my $board_name=$self->object_get_attribute('compile','fpga_board');
        my $board_name=$self->object_get_attribute('compile','fpga_board');
        return "Please define the Board Name\n" if(! defined $board_name );
        return "Please define the Board Name\n" if(! defined $board_name );
        return "Please define the Board Name\n" if(length($board_name) ==0 );
        return "Please define the Board Name\n" if(length($board_name) ==0 );
        my $r=check_verilog_identifier_syntax($board_name);
        my $r=check_verilog_identifier_syntax($board_name);
        return "Error in given Board Name: $r\n" if(defined $r );
        return "Error in given Board Name: $r\n" if(defined $r );
 
 
        #check xdc file 
        #check xdc file 
        my $xdc=$self->object_get_attribute('compile','board_confg_file');
        my $xdc=$self->object_get_attribute('compile','board_confg_file');
        return "Please define the xdc file\n" if(!defined $xdc );
        return "Please define the xdc file\n" if(!defined $xdc );
        $xdc=add_project_dir_to_addr($xdc);
        $xdc=add_project_dir_to_addr($xdc);
 
 
        #check v file 
        #check v file 
        my $top=$self->object_get_attribute('compile','fpga_board_v');
        my $top=$self->object_get_attribute('compile','fpga_board_v');
        return "Please define the verilog file file\n" if(!defined $top );
        return "Please define the verilog file file\n" if(!defined $top );
        $top=add_project_dir_to_addr($top);
        $top=add_project_dir_to_addr($top);
 
 
        #check board part 
        #check board part 
        my $part=$self->object_get_attribute('compile','fpga_part');
        my $part=$self->object_get_attribute('compile','fpga_part');
        my $board_part=$self->object_get_attribute('compile','fpga_board_part');
        my $board_part=$self->object_get_attribute('compile','fpga_board_part');
        return "Please define at least one of FPGA board part or FPGA part names"if(!defined $part && !defined $board_part  );
        return "Please define at least one of FPGA board part or FPGA part names"if(!defined $part && !defined $board_part  );
 
 
        #make board directory
        #make board directory
        my $project_dir = get_project_dir();
        my $project_dir = get_project_dir();
        my $path="$project_dir/mpsoc/boards/$vendor/$board_name";
        my $path="$project_dir/mpsoc/boards/$vendor/$board_name";
        mkpath($path,1,01777);
        mkpath($path,1,01777);
        return "Error cannot make $path path" if ((-d $path)==0);
        return "Error cannot make $path path" if ((-d $path)==0);
        copy( $xdc,"$path/$board_name.xdc");
        copy( $xdc,"$path/$board_name.xdc");
        copy($top,"$path/$board_name.v");
        copy($top,"$path/$board_name.v");
 
 
 
 
 
 
        my $a=$self->object_get_attribute('compile','fpga_board_order');
        my $a=$self->object_get_attribute('compile','fpga_board_order');
        my $jtag_intfc="#!/bin/bash
        my $jtag_intfc="#!/bin/bash
JTAG_INTFC=\"\$PRONOC_WORK/toolchain/bin/jtag_xilinx_xsct -a $a -b 36\"
JTAG_INTFC=\"\$PRONOC_WORK/toolchain/bin/jtag_xilinx_xsct -a $a -b 36\"
#it works only for 32-bit jtag data width for 64 pass -b 68
#it works only for 32-bit jtag data width for 64 pass -b 68
";
";
        save_file ("$path/jtag_intfc.sh",$jtag_intfc);
        save_file ("$path/jtag_intfc.sh",$jtag_intfc);
 
 
 
 
        my $bin =  $self->object_get_attribute('compile',"vivado bin");
        my $bin =  $self->object_get_attribute('compile',"vivado bin");
    my $hw_dev=$self->object_get_attribute('compile',"fpga_hw_device");
    my $hw_dev=$self->object_get_attribute('compile',"fpga_hw_device");
    my $repo=  $self->object_get_attribute('compile','fpga_board_repo');
    my $repo=  $self->object_get_attribute('compile','fpga_board_repo');
 
 
 
 
        my $tcl="proc set_project_properties { } {\n";
        my $tcl="proc set_project_properties { } {\n";
        if(-d $repo){
        if(-d $repo){
                $tcl=$tcl."\tset_property  \"board_part_repo_paths\" [list \"$repo\"] [current_project]\n";
                $tcl=$tcl."\tset_property  \"board_part_repo_paths\" [list \"$repo\"] [current_project]\n";
        }else {
        }else {
                $tcl=$tcl."\tset_property  \"board_part_repo_paths\" [get_property LOCAL_ROOT_DIR [xhub::get_xstores xilinx_board_store]] [current_project]\n" if(defined $board_part);
                $tcl=$tcl."\tset_property  \"board_part_repo_paths\" [get_property LOCAL_ROOT_DIR [xhub::get_xstores xilinx_board_store]] [current_project]\n" if(defined $board_part);
        }
        }
        $tcl=$tcl."\tset_property \"part\" \"$part\" [current_project]\n" if(defined $part);
        $tcl=$tcl."\tset_property \"part\" \"$part\" [current_project]\n" if(defined $part);
        $tcl=$tcl."\tset_property \"board_part\" \"$board_part\" [current_project]\n" if(defined $board_part);
        $tcl=$tcl."\tset_property \"board_part\" \"$board_part\" [current_project]\n" if(defined $board_part);
        $tcl=$tcl."\tset_property \"default_lib\" \"xil_defaultlib\" [current_project]\n}\n";
        $tcl=$tcl."\tset_property \"default_lib\" \"xil_defaultlib\" [current_project]\n}\n";
 
 
 
 
 
 
        if (defined $hw_dev){
        if (defined $hw_dev){
$tcl=$tcl."\n
$tcl=$tcl."\n
proc program_board {bit_file} {
proc program_board {bit_file} {
        open_hw
        open_hw
        connect_hw_server
        connect_hw_server
        open_hw_target
        open_hw_target
        set_property PROGRAM.FILE \$bit_file [get_hw_devices $hw_dev]
        set_property PROGRAM.FILE \$bit_file [get_hw_devices $hw_dev]
        program_hw_devices [get_hw_devices $hw_dev]
        program_hw_devices [get_hw_devices $hw_dev]
        refresh_hw_device [get_hw_devices $hw_dev]
        refresh_hw_device [get_hw_devices $hw_dev]
}
}
";
";
        }
        }
        save_file ("$path/board_property.tcl",$tcl);
        save_file ("$path/board_property.tcl",$tcl);
 
 
 
 
        $self->object_add_attribute('compile','board',$board_name);
        $self->object_add_attribute('compile','board',$board_name);
        return undef;
        return undef;
 
 
 
 
}
}
 
 
 
 
sub add_new_altera_fpga_board_files{
sub add_new_altera_fpga_board_files{
        my ($self,$vendor)=@_;
        my ($self,$vendor)=@_;
 
 
        #check the board name
        #check the board name
        my $board_name=$self->object_get_attribute('compile','fpga_board');
        my $board_name=$self->object_get_attribute('compile','fpga_board');
        return "Please define the Board Name\n" if(! defined $board_name );
        return "Please define the Board Name\n" if(! defined $board_name );
        return "Please define the Board Name\n" if(length($board_name) ==0 );
        return "Please define the Board Name\n" if(length($board_name) ==0 );
        my $r=check_verilog_identifier_syntax($board_name);
        my $r=check_verilog_identifier_syntax($board_name);
        return "Error in given Board Name: $r\n" if(defined $r );
        return "Error in given Board Name: $r\n" if(defined $r );
 
 
        #check qsf file 
        #check qsf file 
        my $qsf=$self->object_get_attribute('compile','board_confg_file');
        my $qsf=$self->object_get_attribute('compile','board_confg_file');
        return "Please define the QSF file\n" if(!defined $qsf );
        return "Please define the QSF file\n" if(!defined $qsf );
 
 
        #check v file 
        #check v file 
        my $top=$self->object_get_attribute('compile','fpga_board_v');
        my $top=$self->object_get_attribute('compile','fpga_board_v');
        return "Please define the verilog file file\n" if(!defined $top );
        return "Please define the verilog file file\n" if(!defined $top );
 
 
        #check PID
        #check PID
        my $pid=$self->object_get_attribute('compile','quartus_pid');
        my $pid=$self->object_get_attribute('compile','quartus_pid');
        return "Please define the PID\n" if(! defined $pid );
        return "Please define the PID\n" if(! defined $pid );
        return "Please define the PID\n" if(length($pid) ==0 );
        return "Please define the PID\n" if(length($pid) ==0 );
 
 
        #check Hardware name
        #check Hardware name
        my $hw=$self->object_get_attribute('compile','quartus_hardware');
        my $hw=$self->object_get_attribute('compile','quartus_hardware');
        return "Please define the Hardware Name\n" if(! defined $hw );
        return "Please define the Hardware Name\n" if(! defined $hw );
        return "Please define the Hardware Name\n" if(length($hw) ==0 );
        return "Please define the Hardware Name\n" if(length($hw) ==0 );
 
 
 
 
        #check Device name name
        #check Device name name
        my $dw=$self->object_get_attribute('compile','quartus_device');
        my $dw=$self->object_get_attribute('compile','quartus_device');
        return "Please define targeted Device location in JTAG chain. The device location must be larger than zero.\n" if( $dw == 0 );
        return "Please define targeted Device location in JTAG chain. The device location must be larger than zero.\n" if( $dw == 0 );
 
 
 
 
 
 
        #make board directory
        #make board directory
        my $project_dir = get_project_dir();
        my $project_dir = get_project_dir();
        my $path="$project_dir/mpsoc/boards/$vendor/$board_name";
        my $path="$project_dir/mpsoc/boards/$vendor/$board_name";
        mkpath($path,1,01777);
        mkpath($path,1,01777);
        return "Error cannot make $path path" if ((-d $path)==0);
        return "Error cannot make $path path" if ((-d $path)==0);
 
 
        #generate new qsf file
        #generate new qsf file
        $qsf=add_project_dir_to_addr($qsf);
        $qsf=add_project_dir_to_addr($qsf);
        $top=add_project_dir_to_addr($top);
        $top=add_project_dir_to_addr($top);
        open my $file, "<", $qsf or return "Error Could not open $qsf file in read mode!";
        open my $file, "<", $qsf or return "Error Could not open $qsf file in read mode!";
        open my $newqsf, ">", "$path/$board_name.qsf" or return "Error Could not create $path/$board_name.qsf file in write mode!";
        open my $newqsf, ">", "$path/$board_name.qsf" or return "Error Could not create $path/$board_name.qsf file in write mode!";
 
 
        #remove the lines contain following strings
        #remove the lines contain following strings
        my @p=("TOP_LEVEL_ENTITY","VERILOG_FILE","SYSTEMVERILOG_FILE","VHDL_FILE","AHDL_FILE","PROJECT_OUTPUT_DIRECTORY" );
        my @p=("TOP_LEVEL_ENTITY","VERILOG_FILE","SYSTEMVERILOG_FILE","VHDL_FILE","AHDL_FILE","PROJECT_OUTPUT_DIRECTORY" );
        while (my $line = <$file>){
        while (my $line = <$file>){
                if ($line =~ /\Q$p[0]\E/ || $line =~ /\Q$p[1]\E/ || $line =~ /\Q$p[2]\E/ ||  $line =~ /\Q$p[3]\E/ ||  $line =~ /\Q$p[4]\E/){#dont copy the line contain TOP_LEVEL_ENTITY
                if ($line =~ /\Q$p[0]\E/ || $line =~ /\Q$p[1]\E/ || $line =~ /\Q$p[2]\E/ ||  $line =~ /\Q$p[3]\E/ ||  $line =~ /\Q$p[4]\E/){#dont copy the line contain TOP_LEVEL_ENTITY
 
 
                }
                }
 
 
                else{
                else{
                        print $newqsf $line;
                        print $newqsf $line;
                }
                }
 
 
        }
        }
        print $newqsf "\nset_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files\n";
        print $newqsf "\nset_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files\n";
 
 
        close $newqsf;
        close $newqsf;
        close $file;
        close $file;
        copy($top,"$path/$board_name.v");
        copy($top,"$path/$board_name.v");
 
 
        #generate jtag_intfc.sh
        #generate jtag_intfc.sh
        open $file, ">", "$path/jtag_intfc.sh" or return "Error: Could not create $path/jtag_intfc.sh file in write mode!";
        open $file, ">", "$path/jtag_intfc.sh" or return "Error: Could not create $path/jtag_intfc.sh file in write mode!";
        my $jtag;
        my $jtag;
        if($pid eq 6001 || $pid eq 6002 || $pid eq 6003){
        if($pid eq 6001 || $pid eq 6002 || $pid eq 6003){
                $jtag="JTAG_INTFC=\"\$PRONOC_WORK/toolchain/bin/jtag_libusb -a \$PRODUCT_ID\"";
                $jtag="JTAG_INTFC=\"\$PRONOC_WORK/toolchain/bin/jtag_libusb -a \$PRODUCT_ID\"";
 
 
        }else{
        }else{
                $jtag="JTAG_INTFC=\"\$PRONOC_WORK/toolchain/bin/jtag_quartus_stp -a \$HARDWARE_NAME -b \$DEVICE_NAME\"";
                $jtag="JTAG_INTFC=\"\$PRONOC_WORK/toolchain/bin/jtag_quartus_stp -a \$HARDWARE_NAME -b \$DEVICE_NAME\"";
 
 
        }
        }
        print $file "#!/bin/bash
        print $file "#!/bin/bash
 
 
PRODUCT_ID=\"0x$pid\"
PRODUCT_ID=\"0x$pid\"
HARDWARE_NAME=\'$hw *\'
HARDWARE_NAME=\'$hw *\'
DEVICE_NAME=\"\@$dw*\"
DEVICE_NAME=\"\@$dw*\"
 
 
$jtag
$jtag
 
 
        ";
        ";
        close $file;
        close $file;
 
 
 
 
        #generate program_device.sh
        #generate program_device.sh
        open $file, ">", "$path/program_device.sh" or return "Error: Could not create $path/program_device.sh file in write mode!";
        open $file, ">", "$path/program_device.sh" or return "Error: Could not create $path/program_device.sh file in write mode!";
 
 
 
 
print $file "#!/bin/bash
print $file "#!/bin/bash
 
 
#usage:
#usage:
#       bash program_device.sh  programming_file.sof
#       bash program_device.sh  programming_file.sof
 
 
#programming file
#programming file
#given as an argument:  \$1
#given as an argument:  \$1
 
 
#Programming mode
#Programming mode
PROG_MODE=jtag
PROG_MODE=jtag
 
 
#cable name. Connect the board to ur PC and then run jtagconfig in terminal to find the cable name
#cable name. Connect the board to ur PC and then run jtagconfig in terminal to find the cable name
NAME=\"$hw\"
NAME=\"$hw\"
 
 
#device name
#device name
DEVICE=\@$dw".'
DEVICE=\@$dw".'
 
 
 
 
#programming command
#programming command
if [ -n "${QUARTUS_BIN+set}" ]; then
if [ -n "${QUARTUS_BIN+set}" ]; then
  $QUARTUS_BIN/quartus_pgm -m $PROG_MODE -c "$NAME" -o "p;${1}${DEVICE}"
  $QUARTUS_BIN/quartus_pgm -m $PROG_MODE -c "$NAME" -o "p;${1}${DEVICE}"
else
else
  quartus_pgm -m $PROG_MODE -c "$NAME" -o "p;${1}${DEVICE}"
  quartus_pgm -m $PROG_MODE -c "$NAME" -o "p;${1}${DEVICE}"
fi
fi
';
';
 
 
close $file;
close $file;
$self->object_add_attribute('compile','board',$board_name);
$self->object_add_attribute('compile','board',$board_name);
 
 
        return undef;
        return undef;
}
}
 
 
 
 
 
 
 
 
 
 
sub  get_pin_assignment{
sub  get_pin_assignment{
        my ($self,$name,$top,$target_dir,$end_func,$vendor)=@_;
        my ($self,$name,$top,$target_dir,$end_func,$vendor)=@_;
        my $window = def_popwin_size(80,80,"Step 2: Pin Assignment",'percent');
        my $window = def_popwin_size(80,80,"Step 2: Pin Assignment",'percent');
 
 
        my $table = def_table(2, 2, FALSE);
        my $table = def_table(2, 2, FALSE);
        my $scrolled_win = add_widget_to_scrolled_win($table);
        my $scrolled_win = add_widget_to_scrolled_win($table);
 
 
        my $mtable = def_table(10, 10, FALSE);
        my $mtable = def_table(10, 10, FALSE);
        my $next=def_image_button('icons/right.png','Next');
        my $next=def_image_button('icons/right.png','Next');
        my $back=def_image_button('icons/left.png','Previous');
        my $back=def_image_button('icons/left.png','Previous');
        $mtable->attach_defaults($scrolled_win,0,10,0,9);
        $mtable->attach_defaults($scrolled_win,0,10,0,9);
        $mtable->attach($back,2,3,9,10,'shrink','shrink',2,2);
        $mtable->attach($back,2,3,9,10,'shrink','shrink',2,2);
        $mtable->attach($next,8,9,9,10,'shrink','shrink',2,2);
        $mtable->attach($next,8,9,9,10,'shrink','shrink',2,2);
 
 
        my $board_name=$self->object_get_attribute('compile','board');
        my $board_name=$self->object_get_attribute('compile','board');
 
 
        #copy board jtag_intfc.sh file 
        #copy board jtag_intfc.sh file 
        my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
        my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
        copy("../boards/$vendor/$board_name/jtag_intfc.sh","${fpath}../sw/jtag_intfc.sh");
        copy("../boards/$vendor/$board_name/jtag_intfc.sh","${fpath}../sw/jtag_intfc.sh");
        my $m= $self->object_get_attribute('mpsoc_name',undef);
        my $m= $self->object_get_attribute('mpsoc_name',undef);
        if(defined $m){ # we are compiling a complete NoC-based mpsoc                                           
        if(defined $m){ # we are compiling a complete NoC-based mpsoc                                           
                 my ($nr,$ne,$router_p,$ref_tops)= get_noc_verilator_top_modules_info($self);
                 my ($nr,$ne,$router_p,$ref_tops)= get_noc_verilator_top_modules_info($self);
         for (my $tile_num=0;$tile_num<$ne;$tile_num++){
         for (my $tile_num=0;$tile_num<$ne;$tile_num++){
                    #print "$tile_num\n";
                    #print "$tile_num\n";
                        my ($soc_name,$num)= $self->mpsoc_get_tile_soc_name($tile_num);
                        my ($soc_name,$num)= $self->mpsoc_get_tile_soc_name($tile_num);
                        next if(!defined $soc_name);
                        next if(!defined $soc_name);
                        copy("../boards/$vendor/$board_name/jtag_intfc.sh","${fpath}../sw/tile$tile_num/jtag_intfc.sh");
                        copy("../boards/$vendor/$board_name/jtag_intfc.sh","${fpath}../sw/tile$tile_num/jtag_intfc.sh");
                }
                }
 
 
        }
        }
 
 
 
 
 
 
        #copy board program_device.sh file 
        #copy board program_device.sh file 
        copy("../boards/$vendor/$board_name/program_device.sh","${fpath}../program_device.sh");
        copy("../boards/$vendor/$board_name/program_device.sh","${fpath}../program_device.sh");
 
 
        #get boards pin list
        #get boards pin list
        my $top_v= "../boards/$vendor/$board_name/$board_name.v";
        my $top_v= "../boards/$vendor/$board_name/$board_name.v";
 
 
        if(!-f $top_v){
        if(!-f $top_v){
                message_dialog("Error: Could not load the board pin list. The $top_v does not exist!",'error');
                message_dialog("Error: Could not load the board pin list. The $top_v does not exist!",'error');
                $window->destroy;
                $window->destroy;
        }
        }
 
 
        my $board=read_top_v_file($top_v);
        my $board=read_top_v_file($top_v);
 
 
        # Write object file
        # Write object file
        #open(FILE,  ">lib/soc/tttttttt") || die "Can not open: $!";
        #open(FILE,  ">lib/soc/tttttttt") || die "Can not open: $!";
        #print FILE Data::Dumper->Dump([\%$board],['board']);
        #print FILE Data::Dumper->Dump([\%$board],['board']);
        #close(FILE) || die "Error closing file: $!";
        #close(FILE) || die "Error closing file: $!";
 
 
        my @dirs = ('Input', 'Bidir', 'Output');
        my @dirs = ('Input', 'Bidir', 'Output');
        my %models;
        my %models;
        foreach my $p (@dirs){
        foreach my $p (@dirs){
                my %pins=$board->board_get_pin($p);
                my %pins=$board->board_get_pin($p);
                $models{$p}=gen_combo_model(\%pins);
                $models{$p}=gen_combo_model(\%pins);
 
 
        }
        }
 
 
        my $row=0;
        my $row=0;
        my $col=0;
        my $col=0;
        my @labels= ('Port Direction','Port Range     ','Port name      ','Assignment Type','Board Port name ','Board Port Range');
        my @labels= ('Port Direction','Port Range     ','Port name      ','Assignment Type','Board Port name ','Board Port Range');
        foreach my $p (@labels){
        foreach my $p (@labels){
                my $l=gen_label_in_left($p);
                my $l=gen_label_in_left($p);
                $l->set_markup("<b>  $p    </b>");
                $l->set_markup("<b>  $p    </b>");
                $table->attach ($l, $col,$col+1, $row, $row+1,'fill','shrink',2,2);
                $table->attach ($l, $col,$col+1, $row, $row+1,'fill','shrink',2,2);
                $col++
                $col++
        }
        }
        $row++;
        $row++;
 
 
 
 
        #read port list 
        #read port list 
        my $vdb=read_verilog_file($top);
        my $vdb=read_verilog_file($top);
        my %port_type=get_ports_type($vdb,"${name}_top");
        my %port_type=get_ports_type($vdb,"${name}_top");
        my %port_range=get_ports_rang($vdb,"${name}_top");
        my %port_range=get_ports_rang($vdb,"${name}_top");
        my %param = $vdb->get_modules_parameters("${name}_top");
        my %param = $vdb->get_modules_parameters("${name}_top");
 
 
        foreach my $p (sort keys %port_type){
        foreach my $p (sort keys %port_type){
                my $porttype=$port_type{$p};
                my $porttype=$port_type{$p};
                my $portrange=$port_range{$p};
                my $portrange=$port_range{$p};
 
 
                if  (length($portrange)!=0){
                if  (length($portrange)!=0){
                        #replace parameter with their values            
                        #replace parameter with their values            
                        my @a= split (/\b/,$portrange);
                        my @a= split (/\b/,$portrange);
 
 
                        foreach my $l (@a){
                        foreach my $l (@a){
                                my $value=$param{$l};
                                my $value=$param{$l};
                                if(defined $value){
                                if(defined $value){
                                        chomp $value;
                                        chomp $value;
                                        ($portrange=$portrange)=~ s/\b$l\b/$value/g      if(defined $param{$l});
                                        ($portrange=$portrange)=~ s/\b$l\b/$value/g      if(defined $param{$l});
                                #       print"($portrange=$portrange)=~ s/\b$l\b/$value/g      if(defined $param{$l})\n";
                                #       print"($portrange=$portrange)=~ s/\b$l\b/$value/g      if(defined $param{$l})\n";
                                }
                                }
                        }
                        }
 
 
                        my($s1,$s2)=split (":",$portrange);
                        my($s1,$s2)=split (":",$portrange);
                        {
                        {
                                no warnings 'numeric';
                                no warnings 'numeric';
                                $s1 = eval $s1;
                                $s1 = eval $s1;
                                $s2 = eval $s2;
                                $s2 = eval $s2;
                        }
                        }
                        $portrange = "[ $portrange ]" ;
                        $portrange = "[ $portrange ]" ;
                    if(defined $s1 && defined $s2 ){
                    if(defined $s1 && defined $s2 ){
                        $portrange = "" if($s1 eq 0 && $s2 eq 0);                  #the upper and lower range are equal zero so remove it                         
                        $portrange = "" if($s1 eq 0 && $s2 eq 0);                  #the upper and lower range are equal zero so remove it                         
                        }
                        }
                }
                }
 
 
                my $label1= gen_label_in_left("  $porttype");
                my $label1= gen_label_in_left("  $porttype");
                my $label2= gen_label_in_left("  $portrange");
                my $label2= gen_label_in_left("  $portrange");
                my $label3= gen_label_in_left("  $p");
                my $label3= gen_label_in_left("  $p");
 
 
                $table->attach($label1, 0,1, $row, $row+1,'fill','shrink',2,2);
                $table->attach($label1, 0,1, $row, $row+1,'fill','shrink',2,2);
                $table->attach($label2, 1,2, $row, $row+1,'fill','shrink',2,2);
                $table->attach($label2, 1,2, $row, $row+1,'fill','shrink',2,2);
                $table->attach($label3, 2,3, $row, $row+1,'fill','shrink',2,2);
                $table->attach($label3, 2,3, $row, $row+1,'fill','shrink',2,2);
 
 
                my $assign_type= "Direct,Negate(~)";
                my $assign_type= "Direct,Negate(~)";
                if ($porttype eq  'input') {
                if ($porttype eq  'input') {
                        my $assign_combo=gen_combobox_object($self,'compile_assign_type',$p,$assign_type,'Direct',undef,undef);
                        my $assign_combo=gen_combobox_object($self,'compile_assign_type',$p,$assign_type,'Direct',undef,undef);
                        $table->attach( $assign_combo, 3,4, $row, $row+1,'fill','shrink',2,2);
                        $table->attach( $assign_combo, 3,4, $row, $row+1,'fill','shrink',2,2);
                }
                }
 
 
                my $type= ($porttype eq  'input') ? 'Input' :
                my $type= ($porttype eq  'input') ? 'Input' :
                          ($porttype eq  'output')? 'Output' : 'Bidir';
                          ($porttype eq  'output')? 'Output' : 'Bidir';
 
 
                my $combo= gen_tree_combo($models{$type});
                my $combo= gen_tree_combo($models{$type});
                my $saved=$self->object_get_attribute('compile_pin_pos',$p);
                my $saved=$self->object_get_attribute('compile_pin_pos',$p);
                my $box;
                my $box;
                my $loc=$row;
                my $loc=$row;
                if(defined $saved) {
                if(defined $saved) {
                          my @indices=@{$saved};
                          my @indices=@{$saved};
                          my $path = TreePath_new_from_indices(@indices);
                          my $path = TreePath_new_from_indices(@indices);
                          my $iter = $models{$type}->get_iter($path);
                          my $iter = $models{$type}->get_iter($path);
                          undef $path;
                          undef $path;
                          $combo->set_active_iter($iter);
                          $combo->set_active_iter($iter);
                          $box->destroy if(defined $box);
                          $box->destroy if(defined $box);
                          my $text=$self->object_get_attribute('compile_pin',$p);
                          my $text=$self->object_get_attribute('compile_pin',$p);
                          $box=get_range ($board,$self,$type,$text,$portrange,$p);
                          $box=get_range ($board,$self,$type,$text,$portrange,$p);
                          $table->attach($box, 5,6, $loc, $loc+1,'fill','shrink',2,2);
                          $table->attach($box, 5,6, $loc, $loc+1,'fill','shrink',2,2);
                }
                }
 
 
 
 
                $combo->signal_connect("changed" => sub{
                $combo->signal_connect("changed" => sub{
 
 
                        #get and saved new value
                        #get and saved new value
                        my $treeiter=  $combo->get_active_iter();
                        my $treeiter=  $combo->get_active_iter();
                        my $text = $models{$type}->get_value($treeiter, 0);
                        my $text = $models{$type}->get_value($treeiter, 0);
                        $self->object_add_attribute('compile_pin',$p,$text);
                        $self->object_add_attribute('compile_pin',$p,$text);
                        #get and saved value position in model
                        #get and saved value position in model
                        my $treepath = $models{$type}->get_path ($treeiter);
                        my $treepath = $models{$type}->get_path ($treeiter);
                        my @indices=   $treepath->get_indices();
                        my @indices=   $treepath->get_indices();
                        $self->object_add_attribute('compile_pin_pos',$p,\@indices);
                        $self->object_add_attribute('compile_pin_pos',$p,\@indices);
                        #update borad port range
                        #update borad port range
                        $box->destroy if(defined $box);
                        $box->destroy if(defined $box);
                        $box=get_range ($board,$self,$type,$text,$portrange,$p);
                        $box=get_range ($board,$self,$type,$text,$portrange,$p);
                        $table->attach($box, 5,6, $loc, $loc+1,'fill','shrink',2,2);
                        $table->attach($box, 5,6, $loc, $loc+1,'fill','shrink',2,2);
                        $table->show_all;
                        $table->show_all;
 
 
                });
                });
 
 
                $table->attach($combo, 4,5, $row, $row+1,'fill','shrink',2,2);
                $table->attach($combo, 4,5, $row, $row+1,'fill','shrink',2,2);
 
 
                $row++;
                $row++;
 
 
        }
        }
        $next-> signal_connect("clicked" => sub{
        $next-> signal_connect("clicked" => sub{
 
 
                $window->destroy;
                $window->destroy;
                fpga_compilation($self,$board,$name,$top,$target_dir,$end_func,$vendor);
                fpga_compilation($self,$board,$name,$top,$target_dir,$end_func,$vendor);
 
 
        });
        });
        $back-> signal_connect("clicked" => sub{
        $back-> signal_connect("clicked" => sub{
 
 
                $window->destroy;
                $window->destroy;
                select_compiler($self,$name,$top,$target_dir,$end_func,$vendor);
                select_compiler($self,$name,$top,$target_dir,$end_func,$vendor);
 
 
        });
        });
 
 
 
 
        $window->add ($mtable);
        $window->add ($mtable);
        $window->show_all();
        $window->show_all();
}
}
 
 
 
 
 
 
 
 
 
 
sub fpga_compilation{
sub fpga_compilation{
        my ($self,$board,$name,$top,$target_dir,$end_func,$vendor)=@_;
        my ($self,$board,$name,$top,$target_dir,$end_func,$vendor)=@_;
 
 
        my $run=def_image_button('icons/gate.png','Compile');
        my $run=def_image_button('icons/gate.png','Compile');
        my $back=def_image_button('icons/left.png','Previous');
        my $back=def_image_button('icons/left.png','Previous');
        my $regen=def_image_button('icons/refresh.png','Regenerate Top.v');
        my $regen=def_image_button('icons/refresh.png','Regenerate Top.v');
        my $prog=def_image_button('icons/write.png','Program the board');
        my $prog=def_image_button('icons/write.png','Program the board');
 
 
 
 
        my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
        my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
        my $board_top_file ="${fpath}Top.v";
        my $board_top_file ="${fpath}Top.v";
        unless (-e $board_top_file ){
        unless (-e $board_top_file ){
                gen_top_v($self,$board,$name,$top) ;
                gen_top_v($self,$board,$name,$top) ;
        }
        }
 
 
        my ($app,$table,$tview,$window) = software_main($fpath,'Top.v');
        my ($app,$table,$tview,$window) = software_main($fpath,'Top.v');
        $table->attach($back,1,2,1,2,'shrink','shrink',2,2);
        $table->attach($back,1,2,1,2,'shrink','shrink',2,2);
        $table->attach($regen,4,5,1,2,'shrink','shrink',2,2);
        $table->attach($regen,4,5,1,2,'shrink','shrink',2,2);
        $table->attach ($run,6, 7, 1,2,'shrink','shrink',2,2);
        $table->attach ($run,6, 7, 1,2,'shrink','shrink',2,2);
        $table->attach($prog,9,10,1,2,'shrink','shrink',2,2);
        $table->attach($prog,9,10,1,2,'shrink','shrink',2,2);
 
 
 
 
 
 
        $regen-> signal_connect("clicked" => sub{
        $regen-> signal_connect("clicked" => sub{
 
 
                my $response =  yes_no_dialog("Are you sure you want to regenerate the Top.v file? Note that any changes you have made will be lost");
                my $response =  yes_no_dialog("Are you sure you want to regenerate the Top.v file? Note that any changes you have made will be lost");
                if ($response eq 'yes') {
                if ($response eq 'yes') {
                        gen_top_v($self,$board,$name,$top);
                        gen_top_v($self,$board,$name,$top);
                        $app->refresh_source("$board_top_file");
                        $app->refresh_source("$board_top_file");
                }
                }
        });
        });
 
 
 
 
 
 
        $back-> signal_connect("clicked" => sub{
        $back-> signal_connect("clicked" => sub{
 
 
                $window->destroy;
                $window->destroy;
                get_pin_assignment($self,$name,$top,$target_dir,$end_func,$vendor);
                get_pin_assignment($self,$name,$top,$target_dir,$end_func,$vendor);
 
 
        });
        });
 
 
 
 
        #compile
        #compile
        $run-> signal_connect("clicked" => sub{
        $run-> signal_connect("clicked" => sub{
                my $load= show_gif("icons/load.gif");
                my $load= show_gif("icons/load.gif");
                $table->attach ($load,8, 9, 1,2,'shrink','shrink',2,2);
                $table->attach ($load,8, 9, 1,2,'shrink','shrink',2,2);
                $load->show_all;
                $load->show_all;
 
 
                set_gui_status($self,'save_project',1);
                set_gui_status($self,'save_project',1);
                $app->ask_to_save_changes();
                $app->ask_to_save_changes();
 
 
                quartus_run_compile ($self,$app,$tview,$target_dir,$name,$window,$end_func,$vendor) if($vendor eq 'Altera');
                quartus_run_compile ($self,$app,$tview,$target_dir,$name,$window,$end_func,$vendor) if($vendor eq 'Altera');
                xilinx_run_compile ($self,$app,$tview,$target_dir,$name,$window,$end_func,$vendor)  if($vendor eq 'Xilinx');
                xilinx_run_compile ($self,$app,$tview,$target_dir,$name,$window,$end_func,$vendor)  if($vendor eq 'Xilinx');
 
 
                $load->destroy;
                $load->destroy;
 
 
        });
        });
 
 
 
 
        #Programe the board 
        #Programe the board 
        $prog-> signal_connect("clicked" => sub{
        $prog-> signal_connect("clicked" => sub{
                quartus_program_the_board($self,$tview,$target_dir,$name,$vendor) if($vendor eq 'Altera');
                quartus_program_the_board($self,$tview,$target_dir,$name,$vendor) if($vendor eq 'Altera');
                vivado_program_the_board($self,$tview,$target_dir,$name,$vendor) if($vendor eq 'Xilinx');
                vivado_program_the_board($self,$tview,$target_dir,$name,$vendor) if($vendor eq 'Xilinx');
        });
        });
 
 
}
}
 
 
sub vivado_program_the_board {
sub vivado_program_the_board {
        my      ($self,$tview,$target_dir,$name,$vendor) =@_;
        my      ($self,$tview,$target_dir,$name,$vendor) =@_;
 
 
        my $bit_file="$target_dir/Vivado/xilinx_compile/${name}.runs/impl_1/Top.bit";
        my $bit_file="$target_dir/Vivado/xilinx_compile/${name}.runs/impl_1/Top.bit";
 
 
 
 
 
 
        unless (-f "$target_dir/Vivado/program_board.tcl"){
        unless (-f "$target_dir/Vivado/program_board.tcl"){
        #create tcl file
        #create tcl file
        my $xpr = "\$tcl_path/xilinx_compile/${name}.xpr";
        my $xpr = "\$tcl_path/xilinx_compile/${name}.xpr";
        my $tcl="
        my $tcl="
#Get tcl shell path relative to current script
#Get tcl shell path relative to current script
set tcl_path    [file dirname [info script]]
set tcl_path    [file dirname [info script]]
 
 
set projectName $name
set projectName $name
 
 
source \"\$tcl_path/board_property.tcl\"
source \"\$tcl_path/board_property.tcl\"
set projectXpr \"$xpr\"
set projectXpr \"$xpr\"
#Open project
#Open project
open_project   \$projectXpr
open_project   \$projectXpr
program_board \"\$tcl_path/xilinx_compile/${name}.runs/impl_1/Top.bit\"
program_board \"\$tcl_path/xilinx_compile/${name}.runs/impl_1/Top.bit\"
close_project
close_project
exit
exit
 
 
        ";
        ";
        save_file ("$target_dir/Vivado/program_board.tcl",$tcl);
        save_file ("$target_dir/Vivado/program_board.tcl",$tcl);
        add_info($tview,"File $target_dir/Vivado/program_board.tcl is created\n");
        add_info($tview,"File $target_dir/Vivado/program_board.tcl is created\n");
        }
        }
 
 
        #check bit file existance
        #check bit file existance
        unless (-f $bit_file){
        unless (-f $bit_file){
                add_colored_info($tview,"Could not find $bit_file. Click on project Compile button first and make sure it runs successfully.",'red');
                add_colored_info($tview,"Could not find $bit_file. Click on project Compile button first and make sure it runs successfully.",'red');
                return
                return
        }
        }
 
 
 
 
        #run vivado using program_board.tcl
        #run vivado using program_board.tcl
        my $error =run_vivado ($self,$target_dir,$tview,"$target_dir/Vivado/program_board.tcl");
        my $error =run_vivado ($self,$target_dir,$tview,"$target_dir/Vivado/program_board.tcl");
        add_colored_info($tview,"Board is programmed successfully!\n",'blue') if($error==0);
        add_colored_info($tview,"Board is programmed successfully!\n",'blue') if($error==0);
 
 
 
 
}
}
 
 
 
 
 
 
 
 
sub quartus_program_the_board{
sub quartus_program_the_board{
        my ($self,$tview,$target_dir,$name,$vendor)=@_;
        my ($self,$tview,$target_dir,$name,$vendor)=@_;
        my $error = 0;
        my $error = 0;
        my $sof_file="$target_dir/Quartus/output_files/${name}.sof";
        my $sof_file="$target_dir/Quartus/output_files/${name}.sof";
        my $bash_file="$target_dir/program_device.sh";
        my $bash_file="$target_dir/program_device.sh";
 
 
        add_info($tview,"Program the board using Quartus_pgm and $sof_file file\n");
        add_info($tview,"Program the board using Quartus_pgm and $sof_file file\n");
        #check if the programming file exists
        #check if the programming file exists
        unless (-f $sof_file) {
        unless (-f $sof_file) {
                add_colored_info($tview,"\tThe $sof_file does not exists! Make sure you have compiled the code successfully.\n", 'red');
                add_colored_info($tview,"\tThe $sof_file does not exists! Make sure you have compiled the code successfully.\n", 'red');
                $error=1;
                $error=1;
        }
        }
        #check if the program_device.sh file exists
        #check if the program_device.sh file exists
        unless (-f $bash_file) {
        unless (-f $bash_file) {
                add_colored_info($tview,"\tThe $bash_file does not exist! This file varies depending on your target board and must be available inside mpsoc/boards/$vendor/[board_name].\n", 'red');
                add_colored_info($tview,"\tThe $bash_file does not exist! This file varies depending on your target board and must be available inside mpsoc/boards/$vendor/[board_name].\n", 'red');
                $error=1;
                $error=1;
        }
        }
        return if($error);
        return if($error);
        my $command = "bash $bash_file $sof_file";
        my $command = "bash $bash_file $sof_file";
        add_info($tview,"$command\n");
        add_info($tview,"$command\n");
        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($command);
        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($command);
        if(length $stderr>1){
        if(length $stderr>1){
                add_colored_info($tview,"$stderr\n",'red');
                add_colored_info($tview,"$stderr\n",'red');
                add_colored_info($tview,"Board was not programmed successfully!\n",'red');
                add_colored_info($tview,"Board was not programmed successfully!\n",'red');
        }else {
        }else {
                if($exit){
                if($exit){
                        add_colored_info($tview,"$stdout\n",'red');
                        add_colored_info($tview,"$stdout\n",'red');
                        add_colored_info($tview,"Board was not programmed successfully!\n",'red');
                        add_colored_info($tview,"Board was not programmed successfully!\n",'red');
                }else{
                }else{
                        add_info($tview,"$stdout\n");
                        add_info($tview,"$stdout\n");
                        add_colored_info($tview,"Board is programmed successfully!\n",'blue');
                        add_colored_info($tview,"Board is programmed successfully!\n",'blue');
                }
                }
 
 
        }
        }
}
}
 
 
 
 
sub quartus_run_compile{
sub quartus_run_compile{
        my ($self,$app,$tview,$target_dir,$name,$window,$end_func,$vendor)=@_;
        my ($self,$app,$tview,$target_dir,$name,$window,$end_func,$vendor)=@_;
 
 
        my $error = 0;
        my $error = 0;
        add_info($tview,"CREATE: start creating Quartus project in $target_dir/Quartus folder\n");
        add_info($tview,"CREATE: start creating Quartus project in $target_dir/Quartus folder\n");
 
 
        mkpath("$target_dir/Quartus",1,01777);
        mkpath("$target_dir/Quartus",1,01777);
 
 
        #get list of source file
        #get list of source file
        add_info($tview,"        Read the list of all source files $target_dir/src_verilog\n");
        add_info($tview,"        Read the list of all source files $target_dir/src_verilog\n");
        my @files = File::Find::Rule->file()
        my @files = File::Find::Rule->file()
                          ->name( '*.v','*.V','*.sv' )
                          ->name( '*.v','*.V','*.sv' )
                          ->in( "$target_dir/src_verilog" );
                          ->in( "$target_dir/src_verilog" );
 
 
        #make sure source files have key word 'module' 
        #make sure source files have key word 'module' 
        my @sources;
        my @sources;
        foreach my $p (@files){
        foreach my $p (@files){
                push (@sources,$p)      if(check_file_has_string($p,'endpackage'));
                push (@sources,$p)      if(check_file_has_string($p,'endpackage'));
        }
        }
        foreach my $p (@files){
        foreach my $p (@files){
                push (@sources,$p)      if(check_file_has_string($p,'module'));
                push (@sources,$p)      if(check_file_has_string($p,'module'));
        }
        }
        my $files = join ("\n",@sources);
        my $files = join ("\n",@sources);
        add_info($tview,"$files\n");
        add_info($tview,"$files\n");
 
 
        #creat project qsf file
        #creat project qsf file
        my $qsf_file="$target_dir/Quartus/${name}.qsf";
        my $qsf_file="$target_dir/Quartus/${name}.qsf";
        save_file ($qsf_file,"# Generated using ProNoC\n");
        save_file ($qsf_file,"# Generated using ProNoC\n");
 
 
        #append global assignets to qsf file
        #append global assignets to qsf file
        my $board_name=$self->object_get_attribute('compile','board');
        my $board_name=$self->object_get_attribute('compile','board');
        my @qsfs =   glob("../boards/$vendor/$board_name/*.qsf");
        my @qsfs =   glob("../boards/$vendor/$board_name/*.qsf");
        if(!defined $qsfs[0]){
        if(!defined $qsfs[0]){
                message_dialog("Error: ../boards/$vendor/$board_name folder does not contain the qsf file.!",'error');
                message_dialog("Error: ../boards/$vendor/$board_name folder does not contain the qsf file.!",'error');
                $window->destroy;
                $window->destroy;
        }
        }
 
 
        my $assignment_file =  $qsfs[0];
        my $assignment_file =  $qsfs[0];
 
 
        if(-f $assignment_file){
        if(-f $assignment_file){
                merg_files ($assignment_file,$qsf_file);
                merg_files ($assignment_file,$qsf_file);
        }
        }
 
 
        my %paths;
        my %paths;
 
 
        #add the list of source fils to qsf file
        #add the list of source fils to qsf file
        my $s="\n\n\n set_global_assignment -name TOP_LEVEL_ENTITY Top\n";
        my $s="\n\n\n set_global_assignment -name TOP_LEVEL_ENTITY Top\n";
        foreach my $p (@sources){
        foreach my $p (@sources){
                my ($name,$path,$suffix) = fileparse("$p",qr"\..[^.]*$");
                my ($name,$path,$suffix) = fileparse("$p",qr"\..[^.]*$");
                $s="$s set_global_assignment -name VERILOG_FILE $p\n" if ($suffix eq ".v");
                $s="$s set_global_assignment -name VERILOG_FILE $p\n" if ($suffix eq ".v");
                $s="$s set_global_assignment -name SYSTEMVERILOG_FILE $p\n" if ($suffix eq ".sv");
                $s="$s set_global_assignment -name SYSTEMVERILOG_FILE $p\n" if ($suffix eq ".sv");
                $paths{$path}=1;
                $paths{$path}=1;
        }
        }
 
 
 
 
 
 
 
 
 
 
 
 
        foreach my $p (sort keys %paths){
        foreach my $p (sort keys %paths){
                $s="$s set_global_assignment -name SEARCH_PATH  $p\n";
                $s="$s set_global_assignment -name SEARCH_PATH  $p\n";
        }
        }
 
 
        append_text_to_file($qsf_file,$s);
        append_text_to_file($qsf_file,$s);
        add_info($tview,"\n Qsf file has been created\n");
        add_info($tview,"\n Qsf file has been created\n");
 
 
 
 
 
 
 
 
        #start compilation
        #start compilation
        my $Quartus_bin= $self->object_get_attribute('compile','quartus bin');
        my $Quartus_bin= $self->object_get_attribute('compile','quartus bin');
        my @qfiles = ("quartus_map","quartus_fit","quartus_asm","quartus_sta");
        my @qfiles = ("quartus_map","quartus_fit","quartus_asm","quartus_sta");
        foreach my $f (@qfiles){
        foreach my $f (@qfiles){
                unless(-f "$Quartus_bin/$f" ){
                unless(-f "$Quartus_bin/$f" ){
                        $error=1;
                        $error=1;
                        add_colored_info($tview, "$Quartus_bin/$f No such file or directory\n",'red');
                        add_colored_info($tview, "$Quartus_bin/$f No such file or directory\n",'red');
                        last;
                        last;
                }
                }
 
 
        }
        }
 
 
        my $run_sh = "#!/bin/bash
        my $run_sh = "#!/bin/bash
$Quartus_bin/quartus_map --64bit $name --read_settings_files=on
$Quartus_bin/quartus_map --64bit $name --read_settings_files=on
$Quartus_bin/quartus_fit --64bit $name --read_settings_files=on
$Quartus_bin/quartus_fit --64bit $name --read_settings_files=on
$Quartus_bin/quartus_asm --64bit $name --read_settings_files=on
$Quartus_bin/quartus_asm --64bit $name --read_settings_files=on
$Quartus_bin/quartus_sta --64bit $name
$Quartus_bin/quartus_sta --64bit $name
        ";
        ";
 
 
        save_file("$target_dir/Quartus/run.sh",  $run_sh);
        save_file("$target_dir/Quartus/run.sh",  $run_sh);
 
 
        add_info($tview, "Start Quartus compilation.....\n");
        add_info($tview, "Start Quartus compilation.....\n");
        my @compilation_command =(
        my @compilation_command =(
                "cd \"$target_dir/Quartus\" \n xterm -e bash -c '$Quartus_bin/quartus_map --64bit $name --read_settings_files=on; echo \$? > status; sleep 1' ",
                "cd \"$target_dir/Quartus\" \n xterm -e bash -c '$Quartus_bin/quartus_map --64bit $name --read_settings_files=on; echo \$? > status; sleep 1' ",
                "cd \"$target_dir/Quartus\" \n xterm -e bash -c '$Quartus_bin/quartus_fit --64bit $name --read_settings_files=on; echo \$? > status; sleep 1' ",
                "cd \"$target_dir/Quartus\" \n xterm -e bash -c '$Quartus_bin/quartus_fit --64bit $name --read_settings_files=on; echo \$? > status; sleep 1' ",
                "cd \"$target_dir/Quartus\" \n xterm -e bash -c '$Quartus_bin/quartus_asm --64bit $name --read_settings_files=on; echo \$? > status; sleep 1' ",
                "cd \"$target_dir/Quartus\" \n xterm -e bash -c '$Quartus_bin/quartus_asm --64bit $name --read_settings_files=on; echo \$? > status; sleep 1' ",
                "cd \"$target_dir/Quartus\" \n xterm -e bash -c '$Quartus_bin/quartus_sta --64bit $name; echo \$? > status; sleep 1 ' ");
                "cd \"$target_dir/Quartus\" \n xterm -e bash -c '$Quartus_bin/quartus_sta --64bit $name; echo \$? > status; sleep 1 ' ");
 
 
                foreach my $cmd (@compilation_command){
                foreach my $cmd (@compilation_command){
                        last if($error);
                        last if($error);
                add_info($tview,"$cmd\n");
                add_info($tview,"$cmd\n");
                unlink "$target_dir/Quartus/status";
                unlink "$target_dir/Quartus/status";
                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($exit){
                if($exit){
                        add_colored_info($tview, "$stdout\n",'red') if(defined $stdout);
                        add_colored_info($tview, "$stdout\n",'red') if(defined $stdout);
                        add_colored_info($tview, "$stderr\n",'red') if(defined $stderr);
                        add_colored_info($tview, "$stderr\n",'red') if(defined $stderr);
                        $error=1;
                        $error=1;
                        last;
                        last;
                }
                }
 
 
                open(my $fh,  "<$target_dir/Quartus/status") || die "Can not open: $!";
                open(my $fh,  "<$target_dir/Quartus/status") || die "Can not open: $!";
                read($fh,my $status,1);
                read($fh,my $status,1);
                close($fh);
                close($fh);
                if("$status" != "0"){
                if("$status" != "0"){
                        ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout("cd \"$target_dir/Quartus/output_files/\" \n grep -h \"Error (\" *");
                        ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout("cd \"$target_dir/Quartus/output_files/\" \n grep -h \"Error (\" *");
                        add_colored_info($tview,"$stderr\n",'red') if(defined $stderr);
                        add_colored_info($tview,"$stderr\n",'red') if(defined $stderr);
                        add_colored_info($tview,"$stdout\n",'red');
                        add_colored_info($tview,"$stdout\n",'red');
                        $error=1;
                        $error=1;
                        last;
                        last;
                }
                }
        }
        }
        add_colored_info($tview,"Quartus compilation failed !\n",'red') if($error==1);
        add_colored_info($tview,"Quartus compilation failed !\n",'red') if($error==1);
        add_colored_info($tview,"Quartus compilation is done successfully in $target_dir/Quartus!\n", 'blue') if($error==0);
        add_colored_info($tview,"Quartus compilation is done successfully in $target_dir/Quartus!\n", 'blue') if($error==0);
        if (defined $end_func){
        if (defined $end_func){
                if ($error==0){
                if ($error==0){
                        $end_func->($self);
                        $end_func->($self);
                        $window->destroy;
                        $window->destroy;
                }else {
                }else {
                        message_dialog("Error in Quartus compilation!",'error');
                        message_dialog("Error in Quartus compilation!",'error');
                }
                }
        }
        }
 
 
 
 
 
 
}
}
 
 
 
 
 
 
 
 
 
 
 
 
sub xilinx_run_compile{
sub xilinx_run_compile{
        my ($self,$app,$tview,$target_dir,$name,$window,$end_func,$vendor)=@_;
        my ($self,$app,$tview,$target_dir,$name,$window,$end_func,$vendor)=@_;
 
 
        add_info($tview,"CREATE: start creating Vivado project in $target_dir/Vivado\n");
        add_info($tview,"CREATE: start creating Vivado project in $target_dir/Vivado\n");
        #get list of source file
        #get list of source file
        add_info($tview,"        Read the list of all source files $target_dir/src_verilog\n");
        add_info($tview,"        Read the list of all source files $target_dir/src_verilog\n");
        my @files = File::Find::Rule->file()
        my @files = File::Find::Rule->file()
                          ->name( '*.v','*.V','*.sv' )
                          ->name( '*.v','*.V','*.sv' )
                          ->in( "$target_dir/src_verilog" );
                          ->in( "$target_dir/src_verilog" );
 
 
        #make sure source files have key word 'module' 
        #make sure source files have key word 'module' 
        my @sources;
        my @sources;
        foreach my $p (@files){
        foreach my $p (@files){
                push (@sources,$p)      if(check_file_has_string($p,'endpackage'));
                push (@sources,$p)      if(check_file_has_string($p,'endpackage'));
        }
        }
        foreach my $p (@files){
        foreach my $p (@files){
                push (@sources,$p)      if(check_file_has_string($p,'module'));
                push (@sources,$p)      if(check_file_has_string($p,'module'));
        }
        }
 
 
        my %paths;
        my %paths;
        foreach my $p (@files){
        foreach my $p (@files){
                my ($name,$path,$suffix) = fileparse("$p",qr"\..[^.]*$");
                my ($name,$path,$suffix) = fileparse("$p",qr"\..[^.]*$");
                #print "$path\n";
                #print "$path\n";
                my $remove="$target_dir/";
                my $remove="$target_dir/";
                $path =~ s/$remove//;
                $path =~ s/$remove//;
                $paths{$path}=1;
                $paths{$path}=1;
        }
        }
 
 
 
 
 
 
 
 
        my $incdir="set include_dir_list [list";
        my $incdir="set include_dir_list [list";
        foreach my $p (sort keys %paths){
        foreach my $p (sort keys %paths){
                $incdir.=" \$Dir/$p";
                $incdir.=" \$Dir/$p";
         }
         }
        $incdir.="]";
        $incdir.="]";
 
 
        my $files = join ("\n",@sources);
        my $files = join ("\n",@sources);
 
 
 
 
 
 
        #add mem initial file to sources
        #add mem initial file to sources
        my $mem_files="";
        my $mem_files="";
        my @initial_files = File::Find::Rule->file()
        my @initial_files = File::Find::Rule->file()
                          ->name( '*.mem')
                          ->name( '*.mem')
                          ->in( "$target_dir/sw" );
                          ->in( "$target_dir/sw" );
        mkpath("$target_dir/Vivado/xilinx_mem",1,01777) unless -f "$target_dir/Vivado/xilinx_mem";
        mkpath("$target_dir/Vivado/xilinx_mem",1,01777) unless -f "$target_dir/Vivado/xilinx_mem";
        foreach my $f   (@initial_files){
        foreach my $f   (@initial_files){
                #       /home/alireza/work/hca_git/mpsoc_work/SOC/mor1k_soc/sw/RAM/ram0.mif  fpr soc
                #       /home/alireza/work/hca_git/mpsoc_work/SOC/mor1k_soc/sw/RAM/ram0.mif  fpr soc
                #   /home/alireza/work/hca_git/mpsoc_work/MPSOC/newAdder/sw/tile0/RAM/ram0.mif fpr mpsoc
                #   /home/alireza/work/hca_git/mpsoc_work/MPSOC/newAdder/sw/tile0/RAM/ram0.mif fpr mpsoc
                my @m = split('\/sw\/',$f );
                my @m = split('\/sw\/',$f );
                my $d = $m[-1];#take the last file path name after /sw/
                my $d = $m[-1];#take the last file path name after /sw/
                $d=~ s/RAM//g; #remove RAM
                $d=~ s/RAM//g; #remove RAM
                $d=~ s/\///g; #remove /
                $d=~ s/\///g; #remove /
                $d = "tile0".$d unless($m[-1]=~/^tile/); #add tile0 to soc
                $d = "tile0".$d unless($m[-1]=~/^tile/); #add tile0 to soc
                copy($f,"$target_dir/Vivado/xilinx_mem/$d");
                copy($f,"$target_dir/Vivado/xilinx_mem/$d");
                $mem_files="$mem_files \$tcl_path/xilinx_mem/$d";
                $mem_files="$mem_files \$tcl_path/xilinx_mem/$d";
        }
        }
        add_info($tview,"HDL sources:\n$files\nMem sources:\n$mem_files\n");
        add_info($tview,"HDL sources:\n$files\nMem sources:\n$mem_files\n");
        #make tcl file
        #make tcl file
        my $tcl="
        my $tcl="
#Get tcl shell path relative to current script
#Get tcl shell path relative to current script
set tcl_path    [file dirname [info script]]
set tcl_path    [file dirname [info script]]
set Dir \"\$tcl_path/..\"
set Dir \"\$tcl_path/..\"
";
";
 
 
        $tcl=$tcl."set projectName $name";
        $tcl=$tcl."set projectName $name";
 
 
        $tcl =$tcl."
        $tcl =$tcl."
source \"\$tcl_path/board_property.tcl\"
source \"\$tcl_path/board_property.tcl\"
#Create output directory and clear contents
#Create output directory and clear contents
set outputdir \"\$tcl_path/xilinx_compile\"";
set outputdir \"\$tcl_path/xilinx_compile\"";
        $tcl =$tcl.'
        $tcl =$tcl.'
file mkdir $outputdir
file mkdir $outputdir
set files [glob -nocomplain "$outputdir/*"]
set files [glob -nocomplain "$outputdir/*"]
if {[llength $files] != 0} {
if {[llength $files] != 0} {
    puts "deleting contents of $outputdir"
    puts "deleting contents of $outputdir"
    file delete -force {*}[glob -directory $outputdir *]; # clear folder contents
    file delete -force {*}[glob -directory $outputdir *]; # clear folder contents
} else {
} else {
    puts "$outputdir is empty"
    puts "$outputdir is empty"
}
}
 
 
#Create project
#Create project
create_project  $projectName $outputdir
create_project  $projectName $outputdir
 
 
set_project_properties
set_project_properties
 
 
#add source files to Vivado project
#add source files to Vivado project
';
';
 
 
        #get top level port names
        #get top level port names
        #get boards pin list
        #get boards pin list
        my $top_v= "$target_dir/src_verilog/Top.v";
        my $top_v= "$target_dir/src_verilog/Top.v";
        if(!-f $top_v){
        if(!-f $top_v){
                message_dialog("Error: Could not load the board pin list. The Top.v does not exist!",'error');
                message_dialog("Error: Could not load the board pin list. The Top.v does not exist!",'error');
                $window->destroy;
                $window->destroy;
        }
        }
 
 
 
 
        my @ports=verilog_file_get_ports_list(read_verilog_file($top_v),"Top");
        my @ports=verilog_file_get_ports_list(read_verilog_file($top_v),"Top");
 
 
        #get board tcl
        #get board tcl
        my $board_name=$self->object_get_attribute('compile','board');
        my $board_name=$self->object_get_attribute('compile','board');
        my @tcls= glob("../boards/$vendor/$board_name/*.tcl");
        my @tcls= glob("../boards/$vendor/$board_name/*.tcl");
        foreach my $f (@tcls){
        foreach my $f (@tcls){
                copy($f,"$target_dir/Vivado");
                copy($f,"$target_dir/Vivado");
        }
        }
 
 
        #get board xdc
        #get board xdc
        my @xdcs= glob("../boards/$vendor/$board_name/*.xdc");
        my @xdcs= glob("../boards/$vendor/$board_name/*.xdc");
        my $i=1;
        my $i=1;
 
 
        foreach my $f (@xdcs){
        foreach my $f (@xdcs){
                my $out="";
                my $out="";
                #capture file content
                #capture file content
                my $string= load_file($f);
                my $string= load_file($f);
                my @lines=split('\n',$string);
                my @lines=split('\n',$string);
                #make sure lines describing the port name are not comment
                #make sure lines describing the port name are not comment
                foreach my $l (@lines){
                foreach my $l (@lines){
                        foreach my $p (@ports){
                        foreach my $p (@ports){
 
 
                                $l=~ s/^\s*#/ /g if($l =~ /^\s*#/   && $l =~  /\[\s*get_ports\s*[{\s]\s*$p[\s\[\]\}]/ );#             /\[get_ports\s*{\s*$p[\s\}\[]/);
                                $l=~ s/^\s*#/ /g if($l =~ /^\s*#/   && $l =~  /\[\s*get_ports\s*[{\s]\s*$p[\s\[\]\}]/ );#             /\[get_ports\s*{\s*$p[\s\}\[]/);
 
 
                        }
                        }
                        $out=$out."$l\n";
                        $out=$out."$l\n";
                }
                }
                my ($fname,$fpath,$fsuffix) = fileparse("$f",qr"\..[^.]*$");
                my ($fname,$fpath,$fsuffix) = fileparse("$f",qr"\..[^.]*$");
                my $xdc_file = "$target_dir/Vivado/$fname.xdc";
                my $xdc_file = "$target_dir/Vivado/$fname.xdc";
                #save new xdc file
                #save new xdc file
                save_file($xdc_file,$out);
                save_file($xdc_file,$out);
                #add xdc to tcl file
                #add xdc to tcl file
                $tcl =$tcl."add_files -fileset constrs_1 \$tcl_path/$fname.xdc\n";
                $tcl =$tcl."add_files -fileset constrs_1 \$tcl_path/$fname.xdc\n";
                $i++;
                $i++;
        }
        }
 
 
        #internal clock constrain
        #internal clock constrain
        my $clk_xdc=get_clk_constrain_file($self);
        my $clk_xdc=get_clk_constrain_file($self);
        #save_file ("$target_dir/clk.xdc",$clk_xdc);
        #save_file ("$target_dir/clk.xdc",$clk_xdc);
        #$tcl =$tcl."add_files -fileset constrs_1 \$tcl_path/clk.xdc\n";
        #$tcl =$tcl."add_files -fileset constrs_1 \$tcl_path/clk.xdc\n";
 
 
 
 
 
 
        $tcl =$tcl."add_files ";
        $tcl =$tcl."add_files ";
        #add hdl sources
        #add hdl sources
        foreach my $f (@sources){
        foreach my $f (@sources){
                my $p =cut_dir_path($f,'src_verilog');
                my $p =cut_dir_path($f,'src_verilog');
                $tcl =$tcl." \$Dir/src_verilog/$p ";
                $tcl =$tcl." \$Dir/src_verilog/$p ";
        }
        }
        $tcl =$tcl."\n";
        $tcl =$tcl."\n";
 
 
        $tcl =$tcl."#add memory initial files to Vivado project
        $tcl =$tcl."#add memory initial files to Vivado project
        add_files -norecurse $mem_files" if(length($mem_files)>3);
        add_files -norecurse $mem_files" if(length($mem_files)>3);
 
 
 
 
        $tcl =$tcl."\n set_property \"top\"  \"Top\" [current_fileset]\n";
        $tcl =$tcl."\n set_property \"top\"  \"Top\" [current_fileset]\n";
        $tcl =$tcl."
        $tcl =$tcl."
        update_compile_order -fileset sources_1
        update_compile_order -fileset sources_1
        #launch synthesis
        #launch synthesis
 
 
        # Make all reset syncron
        # Make all reset syncron
        set_property verilog_define {{SYNC_RESET_MODE}} [current_fileset]
        set_property verilog_define {{SYNC_RESET_MODE}} [current_fileset]
 
 
        # include source dirs
        # include source dirs
        $incdir
        $incdir
        set_property include_dirs  \$include_dir_list [current_fileset]
        set_property include_dirs  \$include_dir_list [current_fileset]
 
 
        launch_runs synth_1
        launch_runs synth_1
        wait_on_run synth_1
        wait_on_run synth_1
        #Run implementation and generate bitstream
        #Run implementation and generate bitstream
        set_property STEPS.PHYS_OPT_DESIGN.IS_ENABLED true [get_runs impl_1]
        set_property STEPS.PHYS_OPT_DESIGN.IS_ENABLED true [get_runs impl_1]
        launch_runs impl_1 -to_step write_bitstream
        launch_runs impl_1 -to_step write_bitstream
        wait_on_run impl_1
        wait_on_run impl_1
        puts \"Implementation done!\"
        puts \"Implementation done!\"
        ";
        ";
 
 
 
 
        $tcl =$tcl."\nexit";
        $tcl =$tcl."\nexit";
        #creat make_project tcl file
        #creat make_project tcl file
        save_file ("$target_dir/Vivado/make_project.tcl",$tcl);
        save_file ("$target_dir/Vivado/make_project.tcl",$tcl);
 
 
        my $error =run_vivado ($self,$target_dir,$tview,"$target_dir/Vivado/make_project.tcl");
        my $error =run_vivado ($self,$target_dir,$tview,"$target_dir/Vivado/make_project.tcl");
        add_colored_info($tview,"Vivado compilation is done successfully in $target_dir/Vivado!\n", 'blue') if($error==0);
        add_colored_info($tview,"Vivado compilation is done successfully in $target_dir/Vivado!\n", 'blue') if($error==0);
        if (defined $end_func){
        if (defined $end_func){
                if ($error==0){
                if ($error==0){
                        $end_func->($self);
                        $end_func->($self);
                        $window->destroy;
                        $window->destroy;
                }else {
                }else {
                        message_dialog("Error in Vivado compilation!",'error');
                        message_dialog("Error in Vivado compilation!",'error');
                }
                }
        }
        }
 
 
 
 
}
}
 
 
 
 
sub run_vivado {
sub run_vivado {
        my ($self,$target_dir,$tview,$tcl)=@_;
        my ($self,$target_dir,$tview,$tcl)=@_;
        my $error=0;
        my $error=0;
        #start compilation
        #start compilation
        my $vivado_bin= $self->object_get_attribute('compile','vivado bin');
        my $vivado_bin= $self->object_get_attribute('compile','vivado bin');
        add_info($tview, "Start compilation using vivado.....\n");
        add_info($tview, "Start compilation using vivado.....\n");
        my @compilation_command =(
        my @compilation_command =(
                "cd \"$target_dir/Vivado/\" \n xterm -e bash -c '$vivado_bin/vivado -mode tcl -source $tcl'"
                "cd \"$target_dir/Vivado/\" \n xterm -e bash -c '$vivado_bin/vivado -mode tcl -source $tcl'"
        );
        );
 
 
        save_file("$target_dir/Vivado/run.sh",  "#!/bin/bash \n $vivado_bin/vivado -mode tcl -source $tcl");
        save_file("$target_dir/Vivado/run.sh",  "#!/bin/bash \n $vivado_bin/vivado -mode tcl -source $tcl");
 
 
 
 
        my $log="$target_dir/Vivado/vivado.log";
        my $log="$target_dir/Vivado/vivado.log";
        #unlink $log;
        #unlink $log;
 
 
        foreach my $cmd (@compilation_command){
        foreach my $cmd (@compilation_command){
                add_info($tview,"$cmd\n");
                add_info($tview,"$cmd\n");
 
 
                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($exit){
                if($exit){
                        $error=1;
                        $error=1;
                        add_colored_info($tview, "$stdout\n",'red') if(defined $stdout);
                        add_colored_info($tview, "$stdout\n",'red') if(defined $stdout);
                        add_colored_info($tview, "$stderr\n",'red') if(defined $stderr);
                        add_colored_info($tview, "$stderr\n",'red') if(defined $stderr);
                }
                }
 
 
        }
        }
 
 
        #check vivado.log for error
        #check vivado.log for error
        my $r;
        my $r;
        open my $fd, "<" , $log or $r=$!;
        open my $fd, "<" , $log or $r=$!;
        if(defined $r ) {
        if(defined $r ) {
                add_colored_info($tview, "could not open $log to check errors: $r\n",'red');
                add_colored_info($tview, "could not open $log to check errors: $r\n",'red');
                $error=1;
                $error=1;
        }
        }
        else{
        else{
 
 
                #check error
                #check error
                while (my $line = <$fd>) {
                while (my $line = <$fd>) {
                        chomp $line;
                        chomp $line;
                        if( $line =~ /ERROR:/){
                        if( $line =~ /ERROR:/){
                                add_colored_info($tview, "$line\n",'red');
                                add_colored_info($tview, "$line\n",'red');
                                $error=1;
                                $error=1;
                        }
                        }
                }
                }
 
 
                #check warning
                #check warning
                close($fd);
                close($fd);
                open $fd, "<" , $log;
                open $fd, "<" , $log;
                #print  "$log\n";
                #print  "$log\n";
                if($error==0){
                if($error==0){
                        while (my $line = <$fd>) {
                        while (my $line = <$fd>) {
                                chomp $line;
                                chomp $line;
                                if( $line =~ /^\s*WARNING:/){
                                if( $line =~ /^\s*WARNING:/){
                                        add_info($tview, "$line\n");
                                        add_info($tview, "$line\n");
 
 
                                }
                                }
                        }
                        }
                }
                }
 
 
                #check critical warning
                #check critical warning
                close($fd);
                close($fd);
                open $fd, "<" , $log;
                open $fd, "<" , $log;
                #print  "$log\n";
                #print  "$log\n";
                if($error==0){
                if($error==0){
                        while (my $line = <$fd>) {
                        while (my $line = <$fd>) {
                                chomp $line;
                                chomp $line;
                                if( $line =~ /^\s*CRITICAL WARNING:/){
                                if( $line =~ /^\s*CRITICAL WARNING:/){
                                        add_colored_info($tview, "$line\n",'green');
                                        add_colored_info($tview, "$line\n",'green');
                                }
                                }
                        }
                        }
                }
                }
                close($fd);
                close($fd);
        }
        }
        return $error;
        return $error;
}
}
 
 
 
 
 
 
 
 
 
 
sub modelsim_compilation{
sub modelsim_compilation{
        my ($self,$name,$top,$target_dir,$vendor)=@_;
        my ($self,$name,$top,$target_dir,$vendor)=@_;
        #my $window = def_popwin_size(80,80,"Step 2: Compile",'percent');
        #my $window = def_popwin_size(80,80,"Step 2: Compile",'percent');
 
 
 
 
        my $run=def_image_button('icons/run.png','_run',FALSE,1);
        my $run=def_image_button('icons/run.png','_run',FALSE,1);
        my $back=def_image_button('icons/left.png','Previous');
        my $back=def_image_button('icons/left.png','Previous');
        my $regen=def_image_button('icons/refresh.png','Regenerate testbench.v');
        my $regen=def_image_button('icons/refresh.png','Regenerate testbench.v');
 
 
 
 
        #creat modelsim dir
        #creat modelsim dir
 
 
        my $model="$target_dir/Modelsim";
        my $model="$target_dir/Modelsim";
        unlink("$model/model.tcl");
        unlink("$model/model.tcl");
        rmtree("$target_dir/rtl_work");
        rmtree("$target_dir/rtl_work");
        mkpath("$model/rtl_work",1,01777);
        mkpath("$model/rtl_work",1,01777);
 
 
        my ($app,$table,$tview,$window) = software_main("$target_dir/Modelsim",undef);
        my ($app,$table,$tview,$window) = software_main("$target_dir/Modelsim",undef);
        #create testbench.v
        #create testbench.v
        gen_modelsim_soc_testbench ($self,$name,$top,$target_dir,$tview) unless (-f "$target_dir/Modelsim/testbench.v");
        gen_modelsim_soc_testbench ($self,$name,$top,$target_dir,$tview) unless (-f "$target_dir/Modelsim/testbench.v");
        $app->refresh_source("$target_dir/Modelsim/testbench.v");
        $app->refresh_source("$target_dir/Modelsim/testbench.v");
 
 
 
 
 
 
        add_info($tview,"create Modelsim dir in $target_dir\n");
        add_info($tview,"create Modelsim dir in $target_dir\n");
        $table->attach($back,1,2,1,2,'shrink','shrink',2,2);
        $table->attach($back,1,2,1,2,'shrink','shrink',2,2);
        $table->attach($regen,4,5,1,2,'shrink','shrink',2,2);
        $table->attach($regen,4,5,1,2,'shrink','shrink',2,2);
        $table->attach ($run,9, 10, 1,2,'shrink','shrink',0,0);
        $table->attach ($run,9, 10, 1,2,'shrink','shrink',0,0);
 
 
 
 
 
 
        $regen-> signal_connect("clicked" => sub{
        $regen-> signal_connect("clicked" => sub{
                my $response =  yes_no_dialog("Are you sure you want to regenerate the testbench.v file? Note that any changes you have made will be lost");
                my $response =  yes_no_dialog("Are you sure you want to regenerate the testbench.v file? Note that any changes you have made will be lost");
                if ($response eq 'yes') {
                if ($response eq 'yes') {
                        gen_modelsim_soc_testbench ($self,$name,$top,$target_dir,$tview);
                        gen_modelsim_soc_testbench ($self,$name,$top,$target_dir,$tview);
                        $app->refresh_source("$target_dir/Modelsim/testbench.v");
                        $app->refresh_source("$target_dir/Modelsim/testbench.v");
                }
                }
        });
        });
 
 
        $back-> signal_connect("clicked" => sub{
        $back-> signal_connect("clicked" => sub{
 
 
                $window->destroy;
                $window->destroy;
                select_compiler($self,$name,$top,$target_dir);
                select_compiler($self,$name,$top,$target_dir);
 
 
        });
        });
 
 
        #Get the list of  all verilog files in src_verilog folder
        #Get the list of  all verilog files in src_verilog folder
        add_info($tview,"Get the list of all Verilog files in src_verilog folder\n");
        add_info($tview,"Get the list of all Verilog files in src_verilog folder\n");
        my @files = File::Find::Rule->file()
        my @files = File::Find::Rule->file()
                ->name( '*.v','*.V','*.sv' )
                ->name( '*.v','*.V','*.sv' )
                ->in( "$target_dir/src_verilog" );
                ->in( "$target_dir/src_verilog" );
 
 
        #get list of all verilog files in src_sim folder 
        #get list of all verilog files in src_sim folder 
    my @sim_files = File::Find::Rule->file()
    my @sim_files = File::Find::Rule->file()
                ->name( '*.v','*.V','*.sv' )
                ->name( '*.v','*.V','*.sv' )
                ->in( "$target_dir/src_sim" );
                ->in( "$target_dir/src_sim" );
        push (@files, @sim_files);
        push (@files, @sim_files);
        #add testnemch.v
        #add testnemch.v
        push (@files, "$target_dir/Modelsim/testbench.v");
        push (@files, "$target_dir/Modelsim/testbench.v");
 
 
        #create a file list
        #create a file list
        my $tt =create_file_list($target_dir,\@files,'modelsim');
        my $tt =create_file_list($target_dir,\@files,'modelsim');
        save_file("$target_dir/Modelsim/file_list.f",  "$tt");
        save_file("$target_dir/Modelsim/file_list.f",  "$tt");
 
 
 
 
        #create modelsim.tcl file
        #create modelsim.tcl file
my $tcl="#!/usr/bin/tclsh
my $tcl="#!/usr/bin/tclsh
 
 
 
 
transcript on
transcript on
if {[file exists rtl_work]} {
if {[file exists rtl_work]} {
        vdel -lib rtl_work -all
        vdel -lib rtl_work -all
}
}
vlib rtl_work
vlib rtl_work
vmap work rtl_work
vmap work rtl_work
 
 
 
 
vlog  +acc=rn  -F $target_dir/Modelsim/file_list.f
vlog  +acc=rn  -F $target_dir/Modelsim/file_list.f
 
 
vsim -t 1ps  -L rtl_work -L work -voptargs=\"+acc\"  testbench
vsim -t 1ps  -L rtl_work -L work -voptargs=\"+acc\"  testbench
 
 
add wave *
add wave *
view structure
view structure
view signals
view signals
run -all
run -all
";
";
        add_info($tview,"Create model.tcl, run.sh files\n");
        add_info($tview,"Create model.tcl, run.sh files\n");
        save_file ("$model/model.tcl",$tcl);
        save_file ("$model/model.tcl",$tcl);
        my $modelsim_bin= $self->object_get_attribute('compile','modelsim_bin');
        my $modelsim_bin= $self->object_get_attribute('compile','modelsim_bin');
        my $cmd="cd $target_dir/Modelsim; rm -Rf rtl_work; $modelsim_bin/vsim -do $model/model.tcl";
        my $cmd="cd $target_dir/Modelsim; rm -Rf rtl_work; $modelsim_bin/vsim -do $model/model.tcl";
        save_file ("$model/run.sh",'#!/bin/bash'."\n".$cmd);
        save_file ("$model/run.sh",'#!/bin/bash'."\n".$cmd);
 
 
        $run -> signal_connect("clicked" => sub{
        $run -> signal_connect("clicked" => sub{
                set_gui_status($self,'save_project',1);
                set_gui_status($self,'save_project',1);
                $app->ask_to_save_changes();
                $app->ask_to_save_changes();
 
 
 
 
                add_info($tview,"$cmd\n");
                add_info($tview,"$cmd\n");
                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($tview,"$stderr\n","red");
                        add_colored_info($tview,"$stderr\n","red");
 
 
                }else {
                }else {
                        add_info($tview,"$stdout\n");
                        add_info($tview,"$stdout\n");
                }
                }
 
 
        });
        });
 
 
        #$window->show_all();
        #$window->show_all();
}
}
 
 
 
 
# source files : $target_dir/src_verilog
# source files : $target_dir/src_verilog
# work dir : $target_dir/src_verilog
# work dir : $target_dir/src_verilog
 
 
 
 
sub create_file_list {
sub create_file_list {
        my ($target_dir,$files_ref, $platform)=@_;
        my ($target_dir,$files_ref, $platform)=@_;
        my @ff=@{$files_ref} if(defined $files_ref);
        my @ff=@{$files_ref} if(defined $files_ref);
        my $pakages="";
        my $pakages="";
        my $file_list="";
        my $file_list="";
        my $include="";
        my $include="";
 
 
        my %paths;
        my %paths;
        my @files = File::Find::Rule->file()
        my @files = File::Find::Rule->file()
                ->name( '*.v','*.V','*.sv','*.vh')
                ->name( '*.v','*.V','*.sv','*.vh')
            ->in( @ff );
            ->in( @ff );
 
 
    @ff =uniq( @ff);
    @ff =uniq( @ff);
 
 
        foreach my $file (@files) {
        foreach my $file (@files) {
                my ($name,$path,$suffix) = fileparse("$file",qr"\..[^.]*$");
                my ($name,$path,$suffix) = fileparse("$file",qr"\..[^.]*$");
                #print "$path\n";
                #print "$path\n";
                my $remove="$target_dir/";
                my $remove="$target_dir/";
                $path =~ s/$remove//;
                $path =~ s/$remove//;
                $paths{$path}=1;
                $paths{$path}=1;
 
 
                #put packages at the top of the list 
                #put packages at the top of the list 
                if(check_file_has_string($file,'endpackage')){
                if(check_file_has_string($file,'endpackage')){
                        $pakages.="../${path}${name}$suffix\n" if($platform eq 'modelsim');
                        $pakages.="../${path}${name}$suffix\n" if($platform eq 'modelsim');
                        $pakages.="./${name}$suffix\n" if($platform eq 'verilator');
                        $pakages.="./${name}$suffix\n" if($platform eq 'verilator');
                } else{
                } else{
                        $file_list.= "../${path}${name}$suffix\n"if($platform eq 'modelsim');
                        $file_list.= "../${path}${name}$suffix\n"if($platform eq 'modelsim');
                        $file_list.= "./${name}$suffix\n"if($platform eq 'verilator');
                        $file_list.= "./${name}$suffix\n"if($platform eq 'verilator');
                }
                }
        }
        }
         foreach my $p (sort keys %paths){
         foreach my $p (sort keys %paths){
                $include.="+incdir+../$p\n";
                $include.="+incdir+../$p\n";
         }
         }
 
 
        return "$include\n$pakages\n$file_list";
        return "$include\n$pakages\n$file_list";
}
}
 
 
 
 
sub verilator_compilation {
sub verilator_compilation {
        my ($top_ref,$target_dir,$outtext,$cpu_num)=@_;
        my ($top_ref,$target_dir,$outtext,$cpu_num)=@_;
        $cpu_num = 1 if (!defined $cpu_num);
        $cpu_num = 1 if (!defined $cpu_num);
        my %tops = %{$top_ref};
        my %tops = %{$top_ref};
        #creat verilator dir
        #creat verilator dir
        add_info($outtext,"create verilator dir in $target_dir\n");
        add_info($outtext,"create verilator dir in $target_dir\n");
        my $verilator="$target_dir/verilator";
        my $verilator="$target_dir/verilator";
 
 
        rmtree("$verilator");
        rmtree("$verilator");
        mkpath("$verilator",1,01777);
        mkpath("$verilator",1,01777);
 
 
        my @ff = ("$target_dir/src_verilog");
        my @ff = ("$target_dir/src_verilog");
        push (@ff,"$target_dir/src_verilator") if (-d "$target_dir/src_verilator");
        push (@ff,"$target_dir/src_verilator") if (-d "$target_dir/src_verilator");
        push (@ff,"$target_dir/src_sim") if (-d "$target_dir/src_sim");
        push (@ff,"$target_dir/src_sim") if (-d "$target_dir/src_sim");
 
 
        #create a file list
        #create a file list
        add_info($outtext,"make a file list containig all RTL modules\n");
        add_info($outtext,"make a file list containig all RTL modules\n");
        my $tt =create_file_list($target_dir,\@ff,'verilator');
        my $tt =create_file_list($target_dir,\@ff,'verilator');
        save_file("$verilator/file_list.f",  "$tt");
        save_file("$verilator/file_list.f",  "$tt");
 
 
        #check if -Wno-TIMESCALEMOD flag is supported"
        #check if -Wno-TIMESCALEMOD flag is supported"
    my $flag="";
    my $flag="";
 #   my $cmd ="verilator --version | head -n1 | cut -d\" \" -f2";
 #   my $cmd ="verilator --version | head -n1 | cut -d\" \" -f2";
  #     my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
  #     my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
 
 
   #    my $current_v=$stdout;
   #    my $current_v=$stdout;
   #    $current_v =~ s/[^0-9.]//g;
   #    $current_v =~ s/[^0-9.]//g;
   #    if (defined $current_v){
   #    if (defined $current_v){
   #            $cmd = "printf \'%s\n\' \"4.0.0\" \"$current_v\" | sort -V | head -n1";
   #            $cmd = "printf \'%s\n\' \"4.0.0\" \"$current_v\" | sort -V | head -n1";
   #            my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
   #            my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
   #            $stdout =~ s/[^0-9.]//g;
   #            $stdout =~ s/[^0-9.]//g;
   #            if ($stdout eq "4.0.0" ){
   #            if ($stdout eq "4.0.0" ){
   #                    add_info($outtext, "Verilator vesrion $current_v is Greater than or equal to 4.0.0. So compile with -Wno-TIMESCALEMOD flag\n");
   #                    add_info($outtext, "Verilator vesrion $current_v is Greater than or equal to 4.0.0. So compile with -Wno-TIMESCALEMOD flag\n");
   #                    $flag.="-Wno-TIMESCALEMOD";
   #                    $flag.="-Wno-TIMESCALEMOD";
   #            }else{
   #            }else{
   #                    add_info($outtext, "Verilator vesrion is $current_v\n");
   #                    add_info($outtext, "Verilator vesrion is $current_v\n");
   #            }
   #            }
   #    }
   #    }
  my $pdir        = get_project_dir();
  my $pdir        = get_project_dir();
  my $tmp = "$pdir/mpsoc/perl_gui/lib/verilog/tmp.v";
  my $tmp = "$pdir/mpsoc/perl_gui/lib/verilog/tmp.v";
  my $cmd = "verilator --lint-only $tmp  -Wno-TIMESCALEMOD";
  my $cmd = "verilator --lint-only $tmp  -Wno-TIMESCALEMOD";
  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){ #-Wno-TIMESCALEMOD not supported                
  if(length $stderr>1){ #-Wno-TIMESCALEMOD not supported                
                #add_info($outtext,"$stderr\n"); #verilator compain some ignoerabe warnning as error.  
                #add_info($outtext,"$stderr\n"); #verilator compain some ignoerabe warnning as error.  
  }else {
  }else {
                #add_info($outtext,"compile verilator with -Wno-TIMESCALEMOD\n");
                #add_info($outtext,"compile verilator with -Wno-TIMESCALEMOD\n");
                $flag.="-Wno-TIMESCALEMOD";
                $flag.="-Wno-TIMESCALEMOD";
  }
  }
 
 
        #run verilator
        #run verilator
        my $jobs=0; #a counter to limit the number of paralle process 
        my $jobs=0; #a counter to limit the number of paralle process 
        my $make_lib="";
        my $make_lib="";
        $cmd="cd \"$verilator\"; ";
        $cmd="cd \"$verilator\"; ";
        my $vrun="#!/bin/bash
        my $vrun="#!/bin/bash
cd \"$verilator\"
cd \"$verilator\"
";
";
        #my $cmd= "cd \"$verilator/processed_rtl\" \n xterm -e bash -c ' verilator  --cc $name.v --profile-cfuncs --prefix \"Vtop\" -O3  -CFLAGS -O3'";
        #my $cmd= "cd \"$verilator/processed_rtl\" \n xterm -e bash -c ' verilator  --cc $name.v --profile-cfuncs --prefix \"Vtop\" -O3  -CFLAGS -O3'";
        my $length = scalar (keys %tops);
        my $length = scalar (keys %tops);
        foreach my $top (sort keys %tops) {
        foreach my $top (sort keys %tops) {
                add_colored_info($outtext,"Generate $top Verilator model from $tops{$top} file\n",'green');
                add_colored_info($outtext,"Generate $top Verilator model from $tops{$top} file\n",'green');
                $cmd.= "verilator  -f ./file_list.f --cc $tops{$top}  --prefix \"$top\" $flag -O3  -CFLAGS -O3 & ";
                $cmd.= "verilator  -f ./file_list.f --cc $tops{$top}  --prefix \"$top\" $flag -O3  -CFLAGS -O3 & ";
                $vrun.="verilator  -f ./file_list.f --cc $tops{$top}  --prefix \"$top\" $flag -O3  -CFLAGS -O3 &\n";
                $vrun.="verilator  -f ./file_list.f --cc $tops{$top}  --prefix \"$top\" $flag -O3  -CFLAGS -O3 &\n";
 
 
                $make_lib.="make lib$jobs &\n";
                $make_lib.="make lib$jobs &\n";
                $jobs++;
                $jobs++;
 
 
                if( $jobs % $cpu_num == 0 || $jobs == $length){
                if( $jobs % $cpu_num == 0 || $jobs == $length){
                        $vrun.="wait\n"; $make_lib.="wait\n"; $cmd.="wait\n";
                        $vrun.="wait\n"; $make_lib.="wait\n"; $cmd.="wait\n";
                        add_info($outtext,"$cmd\n");
                        add_info($outtext,"$cmd\n");
                        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_info($outtext,"$stderr\n"); #verilator compain some ignoerabe warnning as error.  
                                add_info($outtext,"$stderr\n"); #verilator compain some ignoerabe warnning as error.  
                        }else {
                        }else {
                                add_info($outtext,"$stdout\n");
                                add_info($outtext,"$stdout\n");
                        }
                        }
                        $cmd="cd \"$verilator\"; ";
                        $cmd="cd \"$verilator\"; ";
                }
                }
        }
        }
 
 
 
 
 
 
        #check if verilator model has been generated 
        #check if verilator model has been generated 
        foreach my $top (sort keys %tops) {
        foreach my $top (sort keys %tops) {
 
 
                $vrun.="
                $vrun.="
if ! [ -f $verilator/obj_dir/$top.cpp ]; then
if ! [ -f $verilator/obj_dir/$top.cpp ]; then
        echo  \"Failed to generate: $verilator/obj_dir/$top.cpp \"
        echo  \"Failed to generate: $verilator/obj_dir/$top.cpp \"
        exit 1
        exit 1
fi
fi
";
";
 
 
                if (-f "$verilator/obj_dir/$top.cpp"){#succsess
                if (-f "$verilator/obj_dir/$top.cpp"){#succsess
 
 
 
 
                }else {
                }else {
                        return 0;
                        return 0;
                }
                }
        }
        }
        #generate makefile
        #generate makefile
        gen_verilator_makefile($top_ref,"$verilator/obj_dir/Makefile");
        gen_verilator_makefile($top_ref,"$verilator/obj_dir/Makefile");
 
 
$vrun.="        echo  \"Verilator modules are generated successfully\".
$vrun.="        echo  \"Verilator modules are generated successfully\".
 
 
cd $verilator/obj_dir/
cd $verilator/obj_dir/
 
 
#run make file
#run make file
$make_lib
$make_lib
 
 
make sim
make sim
#done
#done
";
";
 
 
 
 
        save_file ("$verilator/verilate.sh",$vrun);
        save_file ("$verilator/verilate.sh",$vrun);
        #copy topology connection header files
        #copy topology connection header files
        my $project_dir = get_project_dir();
        my $project_dir = get_project_dir();
        $project_dir= "$project_dir/mpsoc";
        $project_dir= "$project_dir/mpsoc";
        my $src_verilator_dir="$project_dir/src_verilator";
        my $src_verilator_dir="$project_dir/src_verilator";
        my @files = File::Find::Rule->file()
        my @files = File::Find::Rule->file()
                ->name( '*.h')
                ->name( '*.h')
            ->in( "$src_verilator_dir" );
            ->in( "$src_verilator_dir" );
        copy_file_and_folders (\@files,$project_dir,"$verilator/obj_dir/");
        copy_file_and_folders (\@files,$project_dir,"$verilator/obj_dir/");
 
 
        return 1;
        return 1;
}
}
 
 
 
 
 
 
 
 
 
 
sub verilator_compilation_win {
sub verilator_compilation_win {
        my ($self,$name,$top,$target_dir,$vendor)=@_;
        my ($self,$name,$top,$target_dir,$vendor)=@_;
        my $window = def_popwin_size(80,80,"Step 2: Compile",'percent');
        my $window = def_popwin_size(80,80,"Step 2: Compile",'percent');
        my $mtable = def_table(10, 10, FALSE);
        my $mtable = def_table(10, 10, FALSE);
        my ($outbox,$outtext)= create_txview();
        my ($outbox,$outtext)= create_txview();
 
 
 
 
        my $next=def_image_button('icons/run.png','Next');
        my $next=def_image_button('icons/run.png','Next');
        my $back=def_image_button('icons/left.png','Previous');
        my $back=def_image_button('icons/left.png','Previous');
        my $load= show_gif("icons/load.gif");
        my $load= show_gif("icons/load.gif");
        $mtable->attach($load,8,9,9,10,'shrink','shrink',2,2);
        $mtable->attach($load,8,9,9,10,'shrink','shrink',2,2);
 
 
        $mtable->attach_defaults ($outbox ,0, 10, 4,9);
        $mtable->attach_defaults ($outbox ,0, 10, 4,9);
        $mtable->attach($back,2,3,9,10,'shrink','shrink',2,2);
        $mtable->attach($back,2,3,9,10,'shrink','shrink',2,2);
 
 
 
 
 
 
 
 
        $back-> signal_connect("clicked" => sub{
        $back-> signal_connect("clicked" => sub{
 
 
                $window->destroy;
                $window->destroy;
                select_compiler($self,$name,$top,$target_dir);
                select_compiler($self,$name,$top,$target_dir);
 
 
        });
        });
        $next-> signal_connect("clicked" => sub{
        $next-> signal_connect("clicked" => sub{
 
 
                $window->destroy;
                $window->destroy;
                verilator_testbench($self,$name,$top,$target_dir,$vendor);
                verilator_testbench($self,$name,$top,$target_dir,$vendor);
 
 
        });
        });
 
 
        $window->add ($mtable);
        $window->add ($mtable);
        $window->show_all();
        $window->show_all();
 
 
 
 
        my $result;
        my $result;
        my $cpu_num = $self->object_get_attribute('compile', 'cpu_num');
        my $cpu_num = $self->object_get_attribute('compile', 'cpu_num');
 
 
        my $n= $self->object_get_attribute('soc_name',undef);
        my $n= $self->object_get_attribute('soc_name',undef);
        if(defined $n){ #we are compiling a single tile as SoC
        if(defined $n){ #we are compiling a single tile as SoC
                my $sw_path     = "$target_dir/sw";
                my $sw_path     = "$target_dir/sw";
                my %params = soc_get_all_parameters($self);
                my %params = soc_get_all_parameters($self);
                my $verilator = soc_generate_verilator ($self,$sw_path,"verilator_$n",\%params);
                my $verilator = soc_generate_verilator ($self,$sw_path,"verilator_$n",\%params);
        my %tops;
        my %tops;
                $tops{"Vtop"}= "--top-module verilator_$n";
                $tops{"Vtop"}= "--top-module verilator_$n";
                my $target_verilator_dr ="$target_dir/src_verilator";
                my $target_verilator_dr ="$target_dir/src_verilator";
        mkpath("$target_verilator_dr",1,01777);
        mkpath("$target_verilator_dr",1,01777);
        save_file ("$target_verilator_dr/verilator_${n}.sv",$verilator);
        save_file ("$target_verilator_dr/verilator_${n}.sv",$verilator);
 
 
 
 
 
 
 
 
 
 
                #$tops{"Vtop"}= "--top-module $name";
                #$tops{"Vtop"}= "--top-module $name";
                $result = verilator_compilation (\%tops,$target_dir,$outtext,$cpu_num);
                $result = verilator_compilation (\%tops,$target_dir,$outtext,$cpu_num);
                $self->object_add_attribute('verilator','libs',\%tops);
                $self->object_add_attribute('verilator','libs',\%tops);
        }
        }
        else { # we are compiling a complete NoC-based mpsoc
        else { # we are compiling a complete NoC-based mpsoc
                $result = gen_mpsoc_verilator_model ($self,$name,$top,$target_dir,$outtext,$cpu_num);
                $result = gen_mpsoc_verilator_model ($self,$name,$top,$target_dir,$outtext,$cpu_num);
 
 
 
 
        }
        }
 
 
 
 
        #check if verilator model has been generated 
        #check if verilator model has been generated 
        if ($result){
        if ($result){
                add_colored_info($outtext,"Veriator model has been generated successfully!",'blue');
                add_colored_info($outtext,"Veriator model has been generated successfully!",'blue');
                $load->destroy();
                $load->destroy();
                $mtable->attach($next,8,9,9,10,'shrink','shrink',2,2);
                $mtable->attach($next,8,9,9,10,'shrink','shrink',2,2);
        }else {
        }else {
                add_colored_info($outtext,"Verilator compilation failed!\n","red");
                add_colored_info($outtext,"Verilator compilation failed!\n","red");
                $load->destroy();
                $load->destroy();
                $next->destroy();
                $next->destroy();
        }
        }
}
}
 
 
 
 
 
 
 
 
 
 
sub  gen_mpsoc_verilator_model{
sub  gen_mpsoc_verilator_model{
        my ($self,$name,$top,$target_dir,$outtext,$cpu_num)=@_;
        my ($self,$name,$top,$target_dir,$outtext,$cpu_num)=@_;
 
 
        my $project_dir = get_project_dir();
        my $project_dir = get_project_dir();
        $project_dir= "$project_dir/mpsoc";
        $project_dir= "$project_dir/mpsoc";
        my $src_verilator_dir="$project_dir/src_verilator";
        my $src_verilator_dir="$project_dir/src_verilator";
        my $target_verilog_dr ="$target_dir/src_verilog";
        my $target_verilog_dr ="$target_dir/src_verilog";
        my $target_verilator_dr ="$target_dir/src_verilator";
        my $target_verilator_dr ="$target_dir/src_verilator";
 
 
        my $sw_dir      = "$target_dir/sw";
        my $sw_dir      = "$target_dir/sw";
        my $src_noc_dir="$project_dir/rtl/src_noc";
        my $src_noc_dir="$project_dir/rtl/src_noc";
        mkpath("$target_verilator_dr",1,01777);
        mkpath("$target_verilator_dr",1,01777);
 
 
        #copy src_verilator files
        #copy src_verilator files
        my @files_list = File::Find::Rule->file()
        my @files_list = File::Find::Rule->file()
                            ->name( '*.v','*.V','*.sv' )
                            ->name( '*.v','*.V','*.sv' )
                            ->in( "$src_verilator_dir" );
                            ->in( "$src_verilator_dir" );
 
 
        #make sure source files have key word 'module' 
        #make sure source files have key word 'module' 
        my @files;
        my @files;
        foreach my $p (@files_list){
        foreach my $p (@files_list){
                push (@files,$p)        if(check_file_has_string($p,'module'));
                push (@files,$p)        if(check_file_has_string($p,'module'));
        }
        }
        copy_file_and_folders (\@files,$project_dir,$target_verilator_dr);
        copy_file_and_folders (\@files,$project_dir,$target_verilator_dr);
 
 
 
 
 
 
        #copy src_noc files
        #copy src_noc files
        #my @files2;
        #my @files2;
        #push (@files2,$src_noc_dir);
        #push (@files2,$src_noc_dir);
        #copy_file_and_folders (\@files2,$project_dir,$target_verilog_dr);
        #copy_file_and_folders (\@files2,$project_dir,$target_verilog_dr);
 
 
 
 
        #create each tile top module    
        #create each tile top module    
    my $processors_en=0;
    my $processors_en=0;
    my $mpsoc=$self;
    my $mpsoc=$self;
    my $lisence= get_license_header("verilator_tiles");
    my $lisence= get_license_header("verilator_tiles");
        my $warning=autogen_warning();
        my $warning=autogen_warning();
    my $verilator=$lisence.$warning;
    my $verilator=$lisence.$warning;
 
 
 
 
    # generate NoC parameter file
    # generate NoC parameter file
        my ($noc_param,$pass_param)=gen_noc_param_v($self);
        my ($noc_param,$pass_param)=gen_noc_param_v($self);
 
 
        my $noc_param_v= " \`ifdef     INCLUDE_PARAM \n \n
        my $noc_param_v= " \`ifdef     INCLUDE_PARAM \n \n
        $noc_param
        $noc_param
 
 
        //simulation parameter
        //simulation parameter
 
 
\n \n \`endif" ;
\n \n \`endif" ;
        #save_file("$target_verilator_dr/parameter.v",$noc_param_v);
        #save_file("$target_verilator_dr/parameter.v",$noc_param_v);
 
 
 
 
 
 
 
 
    my ($nr,$ne,$router_p,$ref_tops)= get_noc_verilator_top_modules_info($self);
    my ($nr,$ne,$router_p,$ref_tops)= get_noc_verilator_top_modules_info($self);
    my %tops = %{$ref_tops};
    my %tops = %{$ref_tops};
 
 
    for (my $tile_num=0;$tile_num<$ne;$tile_num++){
    for (my $tile_num=0;$tile_num<$ne;$tile_num++){
 
 
                #print "$tile_num\n";
                #print "$tile_num\n";
                my ($soc_name,$num)= $mpsoc->mpsoc_get_tile_soc_name($tile_num);
                my ($soc_name,$num)= $mpsoc->mpsoc_get_tile_soc_name($tile_num);
 
 
                my $soc=eval_soc($mpsoc,$soc_name,$outtext);
                my $soc=eval_soc($mpsoc,$soc_name,$outtext);
 
 
 
 
                my $top=$mpsoc->mpsoc_get_soc($soc_name);
                my $top=$mpsoc->mpsoc_get_soc($soc_name);
                my $soc_num= $tile_num;
                my $soc_num= $tile_num;
 
 
 
 
                #update core id
                #update core id
                $soc->object_add_attribute('global_param','CORE_ID',$tile_num);
                $soc->object_add_attribute('global_param','CORE_ID',$tile_num);
 
 
                #update NoC param
                #update NoC param
                my $nocparam =$mpsoc->object_get_attribute('noc_param',undef);
                my $nocparam =$mpsoc->object_get_attribute('noc_param',undef);
                my ($NE, $NR, $RAw, $EAw, $Fw) = get_topology_info($mpsoc);
                my ($NE, $NR, $RAw, $EAw, $Fw) = get_topology_info($mpsoc);
                my %y=%{$nocparam};
                my %y=%{$nocparam};
                $y{'EAw'} = $EAw;
                $y{'EAw'} = $EAw;
                $y{'RAw'} = $RAw;
                $y{'RAw'} = $RAw;
                $y{'Fw'}  = $Fw;
                $y{'Fw'}  = $Fw;
                my @nis=get_NI_instance_list($top);
                my @nis=get_NI_instance_list($top);
                $soc->soc_add_instance_param($nis[0] ,\%y );
                $soc->soc_add_instance_param($nis[0] ,\%y );
                my %z;
                my %z;
 
 
                my %param_type=  $soc->soc_get_module_param_type($nis[0]);
                my %param_type=  $soc->soc_get_module_param_type($nis[0]);
                foreach my $p (sort keys %y){
                foreach my $p (sort keys %y){
                        $z{$p}=$param_type{$p}; #"Parameter";
                        $z{$p}=$param_type{$p}; #"Parameter";
                }
                }
 
 
 
 
 
 
 
 
                $soc->soc_add_instance_param_type($nis[0] ,\%z );
                $soc->soc_add_instance_param_type($nis[0] ,\%z );
 
 
 
 
                my $tile=$tile_num;
                my $tile=$tile_num;
                my $setting=$mpsoc->mpsoc_get_tile_param_setting($tile);
                my $setting=$mpsoc->mpsoc_get_tile_param_setting($tile);
                my %params;
                my %params;
                #if ($setting eq 'Custom'){
                #if ($setting eq 'Custom'){
                         %params= $top->top_get_custom_soc_param($tile);
                         %params= $top->top_get_custom_soc_param($tile);
                #}else{
                #}else{
                #        %params=$top->top_get_default_soc_param();
                #        %params=$top->top_get_default_soc_param();
                #}
                #}
 
 
 
 
                my $sw_path     = "$sw_dir/tile$tile_num";
                my $sw_path     = "$sw_dir/tile$tile_num";
                $verilator = $verilator.soc_generate_verilator ($soc,$sw_path,"tile_$tile",\%params);
                $verilator = $verilator.soc_generate_verilator ($soc,$sw_path,"tile_$tile",\%params);
                $tops{"Vtile$tile_num"}= "--top-module tile_$tile";
                $tops{"Vtile$tile_num"}= "--top-module tile_$tile";
 
 
 
 
        }
        }
 
 
        save_file ("$target_verilator_dr/verilator_tiles.sv",$verilator);
        save_file ("$target_verilator_dr/verilator_tiles.sv",$verilator);
        my $result = verilator_compilation (\%tops,$target_dir,$outtext,$cpu_num);
        my $result = verilator_compilation (\%tops,$target_dir,$outtext,$cpu_num);
        $self->object_add_attribute('verilator','libs',\%tops);
        $self->object_add_attribute('verilator','libs',\%tops);
        return $result;
        return $result;
 
 
}
}
 
 
 
 
sub gen_verilator_soc_testbench {
sub gen_verilator_soc_testbench {
        my ($self,$name,$top,$target_dir)=@_;
        my ($self,$name,$top,$target_dir)=@_;
        my $verilator="$target_dir/verilator";
        my $verilator="$target_dir/verilator";
        my $dir="$verilator/";
        my $dir="$verilator/";
        my $soc_top= $self->soc_get_top ();
        my $soc_top= $self->soc_get_top ();
 
 
        my $include='#include <stdlib.h>
        my $include='#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>
#include <unistd.h>
#include <unistd.h>
#include <string.h>
#include <string.h>
';
';
        my @intfcs=$soc_top->top_get_intfc_list();
        my @intfcs=$soc_top->top_get_intfc_list();
        my %PP;
        my %PP;
        my %rxds;
        my %rxds;
        my $top_port_info="IO type\t  port_size\t  port_name\n";
        my $top_port_info="IO type\t  port_size\t  port_name\n";
        foreach my $intfc (@intfcs){
        foreach my $intfc (@intfcs){
                my $key= ( $intfc eq 'plug:clk[0]')? 'clk' :
                my $key= ( $intfc eq 'plug:clk[0]')? 'clk' :
                         ( $intfc eq 'plug:reset[0]')? 'reset':
                         ( $intfc eq 'plug:reset[0]')? 'reset':
                         ( $intfc eq 'plug:enable[0]')? 'en' :
                         ( $intfc eq 'plug:enable[0]')? 'en' :
                         ( $intfc eq  'socket:RxD_sim[0]')? 'rxd':
                         ( $intfc eq  'socket:RxD_sim[0]')? 'rxd':
                         'other';
                         'other';
 
 
 
 
                my $key1="${key}1";
                my $key1="${key}1";
                my $key0="${key}0";
                my $key0="${key}0";
 
 
                my @ports=$soc_top->top_get_intfc_ports_list($intfc);
                my @ports=$soc_top->top_get_intfc_ports_list($intfc);
                foreach my $p (@ports){
                foreach my $p (@ports){
                        my($inst,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
                        my($inst,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
                        $PP{$key1}= (defined $PP{$key1})? "$PP{$key1} top->$p=1;\n" : "top->$p=1;\n";
                        $PP{$key1}= (defined $PP{$key1})? "$PP{$key1} top->$p=1;\n" : "top->$p=1;\n";
                        $PP{$key0}= (defined $PP{$key0})? "$PP{$key0} top->$p=0;\n" : "top->$p=0;\n";
                        $PP{$key0}= (defined $PP{$key0})? "$PP{$key0} top->$p=0;\n" : "top->$p=0;\n";
                        $top_port_info="$top_port_info $type  $range  top->$p \n";
                        $top_port_info="$top_port_info $type  $range  top->$p \n";
                }
                }
                if($key eq 'rxd'){
                if($key eq 'rxd'){
                        my @ports=$soc_top->top_get_intfc_ports_list($intfc);
                        my @ports=$soc_top->top_get_intfc_ports_list($intfc);
                        foreach my $p (@ports){
                        foreach my $p (@ports){
                                my($id,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
                                my($id,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
                                my @q =split  (/RxD_ready_si/,$p);
                                my @q =split  (/RxD_ready_si/,$p);
                                $rxds{$id}{p}=$q[0]  if( defined $q[1]);
                                $rxds{$id}{p}=$q[0]  if( defined $q[1]);
                                $rxds{$id}{top}='top'  if( defined $q[1]);
                                $rxds{$id}{top}='top'  if( defined $q[1]);
                        }
                        }
                }
                }
 
 
        }
        }
 
 
 
 
 my ($rxd_info, $rxd_num, $rxd_wr_cal,$rxd_cap_cal, $include1)=rxd_testbench_verilator_gen (\%rxds,$dir);
 my ($rxd_info, $rxd_num, $rxd_wr_cal,$rxd_cap_cal, $include1)=rxd_testbench_verilator_gen (\%rxds,$dir);
 my $include2="";
 my $include2="";
 $include2 .= '#include "RxDsim.h" // Header file for sending charactor to UART from STDIN' if($rxd_num > 0);
 $include2 .= '#include "RxDsim.h" // Header file for sending charactor to UART from STDIN' if($rxd_num > 0);
 
 
my $main_c=get_license_header("testbench.cpp");
my $main_c=get_license_header("testbench.cpp");
 
 
 
 
 
 
$main_c="$main_c
$main_c="$main_c
$include
$include
$include1
$include1
#include <verilated.h>          // Defines common routines
#include <verilated.h>          // Defines common routines
#include \"Vtop.h\"               // From Verilating \"$name.v\" file
#include \"Vtop.h\"               // From Verilating \"$name.v\" file
Vtop                    *top;
Vtop                    *top;
$include2
$include2
/*
/*
$top_port_info
$top_port_info
*/
*/
 
 
 
 
 
 
int reset,clk;
int reset,clk;
unsigned int main_time = 0; // Current simulation time
unsigned int main_time = 0; // Current simulation time
 
 
int main(int argc, char** argv) {
int main(int argc, char** argv) {
        $rxd_info
        $rxd_info
        Verilated::commandArgs(argc, argv);   // Remember args
        Verilated::commandArgs(argc, argv);   // Remember args
        top     = new Vtop;
        top     = new Vtop;
 
 
        /********************
        /********************
        *       initialize input
        *       initialize input
        *********************/
        *********************/
 
 
        $PP{reset1}
        $PP{reset1}
        $PP{en1}
        $PP{en1}
        main_time=0;
        main_time=0;
        printf(\"Start Simulation\\n\");
        printf(\"Start Simulation\\n\");
        while (!Verilated::gotFinish()) {
        while (!Verilated::gotFinish()) {
                $rxd_cap_cal
                $rxd_cap_cal
            if ((main_time & 0x3FF)==0) fflush(stdout); // fflush \$dispaly command each 1024 clock cycle
            if ((main_time & 0x3FF)==0) fflush(stdout); // fflush \$dispaly command each 1024 clock cycle
                if (main_time >= 10 ) {
                if (main_time >= 10 ) {
                        $PP{reset0}
                        $PP{reset0}
                }
                }
 
 
 
 
                if ((main_time & 1) == 0) {
                if ((main_time & 1) == 0) {
                        $PP{clk1}      // Toggle clock
                        $PP{clk1}      // Toggle clock
                        // you can change the inputs and read the outputs here in case they are captured at posedge of clock
                        // you can change the inputs and read the outputs here in case they are captured at posedge of clock
                        $rxd_wr_cal
                        $rxd_wr_cal
 
 
 
 
                }//if
                }//if
                else
                else
                {
                {
                        $PP{clk0}
                        $PP{clk0}
 
 
 
 
 
 
                }//else
                }//else
 
 
 
 
                main_time ++;
                main_time ++;
                top->eval();
                top->eval();
                }
                }
        top->final();
        top->final();
}
}
 
 
double sc_time_stamp () {       // Called by \$time in Verilog
double sc_time_stamp () {       // Called by \$time in Verilog
        return main_time;
        return main_time;
}
}
";
";
        save_file("$dir/testbench.cpp",$main_c);
        save_file("$dir/testbench.cpp",$main_c);
 
 
 
 
 
 
}
}
 
 
sub eval_soc{
sub eval_soc{
        my ($mpsoc,$soc_name,$outtext)=@_;
        my ($mpsoc,$soc_name,$outtext)=@_;
        my $path=$mpsoc->object_get_attribute('setting','soc_path');
        my $path=$mpsoc->object_get_attribute('setting','soc_path');
        $path=~ s/ /\\ /g;
        $path=~ s/ /\\ /g;
        my $p = "$path/$soc_name.SOC";
        my $p = "$path/$soc_name.SOC";
        my ($soc,$r,$err) = regen_object($p);
        my ($soc,$r,$err) = regen_object($p);
        if ($r){
        if ($r){
                show_info($outtext,"**Error reading  $p file: $err\n");
                show_info($outtext,"**Error reading  $p file: $err\n");
               next;
               next;
        }
        }
        return $soc;
        return $soc;
}
}
 
 
sub rxd_testbench_verilator_gen {
sub rxd_testbench_verilator_gen {
my      ($rxds_ref,$dir)=@_;
my      ($rxds_ref,$dir)=@_;
 
 
my $rxd_info='';
my $rxd_info='';
my $rxd_num=0;
my $rxd_num=0;
my $rxd_func='';
my $rxd_func='';
my $rxd_wr_cal='';
my $rxd_wr_cal='';
my $rxd_cap_cal='';
my $rxd_cap_cal='';
my $include='';
my $include='';
 
 
my %rxds=%{$rxds_ref};
my %rxds=%{$rxds_ref};
 
 
foreach my $rxd (sort keys %rxds){
foreach my $rxd (sort keys %rxds){
        my $n=$rxds{$rxd}{p};
        my $n=$rxds{$rxd}{p};
        my $top=$rxds{$rxd}{top};
        my $top=$rxds{$rxd}{top};
        $rxd_info.="\\t$rxd_num : ${top}_${n}RXD\\n";
        $rxd_info.="\\t$rxd_num : ${top}_${n}RXD\\n";
 
 
        $rxd_func.="
        $rxd_func.="
        // we have a character to send to interface $rxd_num
        // we have a character to send to interface $rxd_num
        if (sent_table[$rxd_num]!=0 &&  $top->${n}RxD_ready_sim){
        if (sent_table[$rxd_num]!=0 &&  $top->${n}RxD_ready_sim){
                $top->${n}RxD_din_sim=sent_table[$rxd_num];
                $top->${n}RxD_din_sim=sent_table[$rxd_num];
        $top->${n}RxD_wr_sim=1;
        $top->${n}RxD_wr_sim=1;
        sent_table[$rxd_num]=0;
        sent_table[$rxd_num]=0;
        }else {
        }else {
                $top->${n}RxD_wr_sim=0;
                $top->${n}RxD_wr_sim=0;
        }
        }
";
";
        $rxd_num++;
        $rxd_num++;
}
}
 
 
 
 
 
 
if($rxd_num>0){
if($rxd_num>0){
$rxd_func="
$rxd_func="
#ifndef RXD_SIM_H
#ifndef RXD_SIM_H
#define RXD_SIM_H
#define RXD_SIM_H
        #define RXD_NUM  $rxd_num  // number of rxd input interfaces
        #define RXD_NUM  $rxd_num  // number of rxd input interfaces
        char sent_table[RXD_NUM]={0};
        char sent_table[RXD_NUM]={0};
        unsigned char active_rxd_num=0;
        unsigned char active_rxd_num=0;
        void write_char_on_RXD( ) {
        void write_char_on_RXD( ) {
                $rxd_func
                $rxd_func
        }
        }
 
 
        int kbhit(void) {
        int kbhit(void) {
          struct termios oldt, newt;
          struct termios oldt, newt;
          int ch;
          int ch;
          int oldf;
          int oldf;
 
 
          tcgetattr(STDIN_FILENO, &oldt);
          tcgetattr(STDIN_FILENO, &oldt);
          newt = oldt;
          newt = oldt;
          newt.c_lflag &= ~(ICANON | ECHO);
          newt.c_lflag &= ~(ICANON | ECHO);
          tcsetattr(STDIN_FILENO, TCSANOW, &newt);
          tcsetattr(STDIN_FILENO, TCSANOW, &newt);
          oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
          oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
          fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
          fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
 
 
          ch = getchar();
          ch = getchar();
 
 
          tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
          tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
          fcntl(STDIN_FILENO, F_SETFL, oldf);
          fcntl(STDIN_FILENO, F_SETFL, oldf);
 
 
          if(ch != EOF)
          if(ch != EOF)
          {
          {
            ungetc(ch, stdin);
            ungetc(ch, stdin);
            return 1;
            return 1;
          }
          }
          return 0;
          return 0;
        }
        }
 
 
        void capture_char_on_RXD (){
        void capture_char_on_RXD (){
                char c;
                char c;
                if(kbhit()){
                if(kbhit()){
                        c=getchar();
                        c=getchar();
                        if(c=='+'){
                        if(c=='+'){
                                active_rxd_num++;
                                active_rxd_num++;
                                if(active_rxd_num>=$rxd_num) active_rxd_num=0;
                                if(active_rxd_num>=$rxd_num) active_rxd_num=0;
                                printf(\"The active input interface num is \%u\\n\",active_rxd_num);
                                printf(\"The active input interface num is \%u\\n\",active_rxd_num);
                        }else if(c=='-'){
                        }else if(c=='-'){
                                active_rxd_num--;
                                active_rxd_num--;
                                if(active_rxd_num>=$rxd_num) active_rxd_num=($rxd_num-1);
                                if(active_rxd_num>=$rxd_num) active_rxd_num=($rxd_num-1);
                                printf(\"The active input interface num is \%u\\n\",active_rxd_num);
                                printf(\"The active input interface num is \%u\\n\",active_rxd_num);
                        }else{
                        }else{
                                sent_table[active_rxd_num]=c;
                                sent_table[active_rxd_num]=c;
                        }
                        }
 
 
                }
                }
        }
        }
#endif
#endif
        ";
        ";
 
 
 
 
        $include .='#include <termios.h>
        $include .='#include <termios.h>
#include <fcntl.h>
#include <fcntl.h>
';
';
        $rxd_wr_cal="write_char_on_RXD( );";
        $rxd_wr_cal="write_char_on_RXD( );";
        $rxd_cap_cal="capture_char_on_RXD( );";
        $rxd_cap_cal="capture_char_on_RXD( );";
        $rxd_info="printf(\"There are total of $rxd_num RXD (UART) interface ports in the top module:\\n${rxd_info}The default interfce is 0. You can switch to different interfaces by pressing + or - key.\\n\");"
        $rxd_info="printf(\"There are total of $rxd_num RXD (UART) interface ports in the top module:\\n${rxd_info}The default interfce is 0. You can switch to different interfaces by pressing + or - key.\\n\");"
}
}
 
 
        my $rxsim_c=get_license_header("RxDsim.h");
        my $rxsim_c=get_license_header("RxDsim.h");
        $rxsim_c.="$rxd_func";
        $rxsim_c.="$rxd_func";
        save_file("$dir/RxDsim.h",$rxsim_c) if($rxd_num > 0);
        save_file("$dir/RxDsim.h",$rxsim_c) if($rxd_num > 0);
 
 
        return ($rxd_info, $rxd_num, $rxd_wr_cal,$rxd_cap_cal, $include);
        return ($rxd_info, $rxd_num, $rxd_wr_cal,$rxd_cap_cal, $include);
 
 
}
}
 
 
 
 
 
 
sub gen_verilator_mpsoc_testbench {
sub gen_verilator_mpsoc_testbench {
        my ($mpsoc,$name,$top,$target_dir,$tview)=@_;
        my ($mpsoc,$name,$top,$target_dir,$tview)=@_;
        my $verilator="$target_dir/verilator";
        my $verilator="$target_dir/verilator";
        my $dir="$verilator/";
        my $dir="$verilator/";
        my $parameter_h=gen_noc_param_h($mpsoc);
        my $parameter_h=gen_noc_param_h($mpsoc);
 
 
 
 
        my ($nr,$ne,$router_p,$ref_tops,$includ_h)= get_noc_verilator_top_modules_info($mpsoc);
        my ($nr,$ne,$router_p,$ref_tops,$includ_h)= get_noc_verilator_top_modules_info($mpsoc);
 
 
        $parameter_h.="
        $parameter_h.="
        #define NE  $ne
        #define NE  $ne
        #define NR  $nr
        #define NR  $nr
        ";
        ";
        $parameter_h=$parameter_h.$includ_h;
        $parameter_h=$parameter_h.$includ_h;
 
 
 
 
 
 
        my $libh="";
        my $libh="";
        my $inst= "";
        my $inst= "";
        my $newinst="";
        my $newinst="";
 
 
        my $tile_addr="";
        my $tile_addr="";
        my $tile_flit_in="";
        my $tile_flit_in="";
        my $tile_flit_in_l="";
        my $tile_flit_in_l="";
        my $tile_credit="";
        my $tile_credit="";
        my $noc_credit="";
        my $noc_credit="";
        my $noc_flit_in="";
        my $noc_flit_in="";
        my $noc_flit_in_l="";
        my $noc_flit_in_l="";
        my $noc_flit_in_wr="";
        my $noc_flit_in_wr="";
        my $noc_flit_in_wr_l="";
        my $noc_flit_in_wr_l="";
        my $tile_flit_in_wr="";
        my $tile_flit_in_wr="";
        my $tile_flit_in_wr_l="";
        my $tile_flit_in_wr_l="";
        my $tile_eval="";
        my $tile_eval="";
        my $tile_final="";
        my $tile_final="";
        my $tile_reset="";
        my $tile_reset="";
        my $tile_clk="";
        my $tile_clk="";
        my $tile_en="";
        my $tile_en="";
        my $top_port_info="IO type\t  port_size\t  port_name\n";
        my $top_port_info="IO type\t  port_size\t  port_name\n";
        my $no_connected='';
        my $no_connected='';
        my %rxds;
        my %rxds;
 
 
        my $tile_chans="";
        my $tile_chans="";
        my $tmp_reg='';
        my $tmp_reg='';
        for (my $endp=0; $endp<$ne;$endp++){
        for (my $endp=0; $endp<$ne;$endp++){
 
 
 
 
                my $e_addr=endp_addr_encoder($mpsoc,$endp);
                my $e_addr=endp_addr_encoder($mpsoc,$endp);
                my $router_num = get_connected_router_id_to_endp($mpsoc,$endp);
                my $router_num = get_connected_router_id_to_endp($mpsoc,$endp);
                my $r_addr=router_addr_encoder($mpsoc,$router_num);
                my $r_addr=router_addr_encoder($mpsoc,$router_num);
 
 
 
 
                my ($soc_name,$num)= $mpsoc->mpsoc_get_tile_soc_name($endp);
                my ($soc_name,$num)= $mpsoc->mpsoc_get_tile_soc_name($endp);
                if(defined $soc_name) {#we have a conncted tile
                if(defined $soc_name) {#we have a conncted tile
 
 
                        #get ni instance name
                        #get ni instance name
                        my $ni_name;
                        my $ni_name;
                        my $soc=eval_soc($mpsoc,$soc_name,$tview);
                        my $soc=eval_soc($mpsoc,$soc_name,$tview);
                        my $soc_top=$soc->object_get_attribute('top_ip',undef);
                        my $soc_top=$soc->object_get_attribute('top_ip',undef);
                        my @intfcs=$soc_top->top_get_intfc_list();
                        my @intfcs=$soc_top->top_get_intfc_list();
                        my @instances=$soc->soc_get_all_instances();
                        my @instances=$soc->soc_get_all_instances();
                        foreach my $id (@instances){
                        foreach my $id (@instances){
                                        my $category = $soc->soc_get_category($id);
                                        my $category = $soc->soc_get_category($id);
                                        if ($category eq 'NoC') {
                                        if ($category eq 'NoC') {
                                                 $ni_name=  $soc->soc_get_instance_name($id);
                                                 $ni_name=  $soc->soc_get_instance_name($id);
                                        }
                                        }
                        }
                        }
 
 
                                $tile_chans.="\ttile_chan_out[$endp] = &tile$endp->ni_chan_out;\n\ttile_chan_in[$endp] = &tile$endp->ni_chan_in;\n";
                                $tile_chans.="\ttile_chan_out[$endp] = &tile$endp->ni_chan_out;\n\ttile_chan_in[$endp] = &tile$endp->ni_chan_in;\n";
                                $libh=$libh."#include \"Vtile${endp}.h\"\n";
                                $libh=$libh."#include \"Vtile${endp}.h\"\n";
                                $inst=$inst."Vtile${endp}\t*tile${endp};\t  // Instantiation of tile${endp}\n";
                                $inst=$inst."Vtile${endp}\t*tile${endp};\t  // Instantiation of tile${endp}\n";
                                $newinst = $newinst."\ttile${endp}\t=\tnew Vtile${endp};\n";
                                $newinst = $newinst."\ttile${endp}\t=\tnew Vtile${endp};\n";
                                $tile_flit_in = $tile_flit_in . "\ttile${endp}->${ni_name}_flit_in  = noc->ni_flit_out [${endp}];\n";
                                $tile_flit_in = $tile_flit_in . "\ttile${endp}->${ni_name}_flit_in  = noc->ni_flit_out [${endp}];\n";
                                $tile_flit_in_l = $tile_flit_in_l . "\t\ttile${endp}->${ni_name}_flit_in[j]  = noc->ni_flit_out [${endp}][j];\n";
                                $tile_flit_in_l = $tile_flit_in_l . "\t\ttile${endp}->${ni_name}_flit_in[j]  = noc->ni_flit_out [${endp}][j];\n";
                                $tile_credit= $tile_credit."\ttile${endp}->${ni_name}_credit_in= noc->ni_credit_out[${endp}];\n";
                                $tile_credit= $tile_credit."\ttile${endp}->${ni_name}_credit_in= noc->ni_credit_out[${endp}];\n";
                                $noc_credit= $noc_credit."\tnoc->ni_credit_in[${endp}] = tile${endp}->${ni_name}_credit_out;\n";
                                $noc_credit= $noc_credit."\tnoc->ni_credit_in[${endp}] = tile${endp}->${ni_name}_credit_out;\n";
                                $noc_flit_in=$noc_flit_in."\tnoc->ni_flit_in [${endp}]  = tile${endp}->${ni_name}_flit_out;\n";
                                $noc_flit_in=$noc_flit_in."\tnoc->ni_flit_in [${endp}]  = tile${endp}->${ni_name}_flit_out;\n";
                                $noc_flit_in_l=$noc_flit_in_l."\t\t\tnoc->ni_flit_in [${endp}][j]  = tile${endp}->${ni_name}_flit_out[j];\n";
                                $noc_flit_in_l=$noc_flit_in_l."\t\t\tnoc->ni_flit_in [${endp}][j]  = tile${endp}->${ni_name}_flit_out[j];\n";
                                $noc_flit_in_wr= $noc_flit_in_wr."\tif(tile${endp}->${ni_name}_flit_out_wr) noc->ni_flit_in_wr = noc->ni_flit_in_wr | ((vluint64_t)1<<${endp});\n";
                                $noc_flit_in_wr= $noc_flit_in_wr."\tif(tile${endp}->${ni_name}_flit_out_wr) noc->ni_flit_in_wr = noc->ni_flit_in_wr | ((vluint64_t)1<<${endp});\n";
                                $tile_flit_in_wr=$tile_flit_in_wr."\ttile${endp}->${ni_name}_flit_in_wr= ((noc->ni_flit_out_wr >> ${endp}) & 0x01);\n";
                                $tile_flit_in_wr=$tile_flit_in_wr."\ttile${endp}->${ni_name}_flit_in_wr= ((noc->ni_flit_out_wr >> ${endp}) & 0x01);\n";
                                $noc_flit_in_wr_l= $noc_flit_in_wr_l."\tif(tile${endp}->${ni_name}_flit_out_wr) MY_VL_SETBIT_W(noc->ni_flit_in_wr ,${endp});\n";
                                $noc_flit_in_wr_l= $noc_flit_in_wr_l."\tif(tile${endp}->${ni_name}_flit_out_wr) MY_VL_SETBIT_W(noc->ni_flit_in_wr ,${endp});\n";
                                $tile_flit_in_wr_l=$tile_flit_in_wr_l."\ttile${endp}->${ni_name}_flit_in_wr=   (VL_BITISSET_W(noc->ni_flit_out_wr,${endp})>0);\n";
                                $tile_flit_in_wr_l=$tile_flit_in_wr_l."\ttile${endp}->${ni_name}_flit_in_wr=   (VL_BITISSET_W(noc->ni_flit_out_wr,${endp})>0);\n";
                                $tile_eval=$tile_eval."\ttile${endp}->eval();\n";
                                $tile_eval=$tile_eval."\ttile${endp}->eval();\n";
                                $tile_final=$tile_final."\ttile${endp}->final();\n";
                                $tile_final=$tile_final."\ttile${endp}->final();\n";
 
 
 
 
                                foreach my $intfc (@intfcs){
                                foreach my $intfc (@intfcs){
                                        my $key=($intfc eq 'plug:clk[0]')? 'clk' :
                                        my $key=($intfc eq 'plug:clk[0]')? 'clk' :
                                                         ($intfc eq 'plug:reset[0]')? 'reset':
                                                         ($intfc eq 'plug:reset[0]')? 'reset':
                                                         ($intfc eq 'plug:enable[0]')? 'en' :
                                                         ($intfc eq 'plug:enable[0]')? 'en' :
                                                         ($intfc eq 'socket:RxD_sim[0]')? 'rxd':
                                                         ($intfc eq 'socket:RxD_sim[0]')? 'rxd':
                                                         'other';
                                                         'other';
 
 
                                        my @ports=$soc_top->top_get_intfc_ports_list($intfc);
                                        my @ports=$soc_top->top_get_intfc_ports_list($intfc);
                                        foreach my $p (@ports){
                                        foreach my $p (@ports){
                                                my($inst,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
                                                my($inst,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
                                                $tile_reset=$tile_reset."\t\ttile${endp}->$p=reset;\n" if $key eq 'reset';
                                                $tile_reset=$tile_reset."\t\ttile${endp}->$p=reset;\n" if $key eq 'reset';
                                                $tile_clk=$tile_clk."\t\ttile${endp}->$p=clk;\n" if $key eq 'clk';
                                                $tile_clk=$tile_clk."\t\ttile${endp}->$p=clk;\n" if $key eq 'clk';
                                                $tile_en=$tile_en."\t\ttile${endp}->$p=enable;\n" if $key eq 'en';      ;
                                                $tile_en=$tile_en."\t\ttile${endp}->$p=enable;\n" if $key eq 'en';      ;
                                                $top_port_info="$top_port_info $type  $range  tile${endp}->$p \n";
                                                $top_port_info="$top_port_info $type  $range  tile${endp}->$p \n";
                                        }#ports
                                        }#ports
 
 
                                        if($key eq 'rxd'){
                                        if($key eq 'rxd'){
                                                my @ports=$soc_top->top_get_intfc_ports_list($intfc);
                                                my @ports=$soc_top->top_get_intfc_ports_list($intfc);
                                                foreach my $p (@ports){
                                                foreach my $p (@ports){
                                                        my($id,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
                                                        my($id,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
                                                        my @q =split  (/RxD_ready_si/,$p);
                                                        my @q =split  (/RxD_ready_si/,$p);
                                                        $rxds{$endp.$id}{p}=$q[0]  if( defined $q[1]);
                                                        $rxds{$endp.$id}{p}=$q[0]  if( defined $q[1]);
                                                        $rxds{$endp.$id}{top}="tile$endp"  if( defined $q[1]);
                                                        $rxds{$endp.$id}{top}="tile$endp"  if( defined $q[1]);
                                                }
                                                }
                                        }
                                        }
 
 
 
 
                                }#interface
                                }#interface
 
 
                                $tile_addr= $tile_addr."\ttile${endp}->${ni_name}_current_r_addr=$r_addr; // noc->er_addr[${endp}];\n";
                                $tile_addr= $tile_addr."\ttile${endp}->${ni_name}_current_r_addr=$r_addr; // noc->er_addr[${endp}];\n";
                                $tile_addr= $tile_addr."\ttile${endp}->${ni_name}_current_e_addr=$e_addr;\n";
                                $tile_addr= $tile_addr."\ttile${endp}->${ni_name}_current_e_addr=$e_addr;\n";
 
 
                        }else{
                        }else{
                                #this tile is not connected to any ip. the noc input ports will be connected to ground
                                #this tile is not connected to any ip. the noc input ports will be connected to ground
                                $tmp_reg.="\tunsigned char tmp1 [1024]={0};\n \tunsigned char tmp2 [1024]={0};";
                                $tmp_reg.="\tunsigned char tmp1 [1024]={0};\n \tunsigned char tmp2 [1024]={0};";
                                $tile_chans.="\n // Tile:$endp ($e_addr)   is not assigned to any ip. Connet coresponding chan to ground.\n";
                                $tile_chans.="\n // Tile:$endp ($e_addr)   is not assigned to any ip. Connet coresponding chan to ground.\n";
                                $tile_chans.="\ttile_chan_out[$endp] = tmp1;\n\ttile_chan_in[$endp] = tmp2;\n";
                                $tile_chans.="\ttile_chan_out[$endp] = tmp1;\n\ttile_chan_in[$endp] = tmp2;\n";
 
 
                        }
                        }
 
 
 
 
        }
        }
 
 
        my ($rxd_info, $rxd_num, $rxd_wr_cal,$rxd_cap_cal, $include1)=rxd_testbench_verilator_gen (\%rxds,$dir);
        my ($rxd_info, $rxd_num, $rxd_wr_cal,$rxd_cap_cal, $include1)=rxd_testbench_verilator_gen (\%rxds,$dir);
        my $include2="";
        my $include2="";
        $include2 .= '#include "RxDsim.h" // Header file for sending charactor to UART from STDIN' if($rxd_num > 0);
        $include2 .= '#include "RxDsim.h" // Header file for sending charactor to UART from STDIN' if($rxd_num > 0);
 
 
        my $main_c=get_license_header("testbench.cpp");
        my $main_c=get_license_header("testbench.cpp");
 
 
$main_c="$main_c
$main_c="$main_c
#include <stdlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>
#include <unistd.h>
#include <unistd.h>
#include <string.h>
#include <string.h>
$include1
$include1
#include <verilated.h>          // Defines common routines
#include <verilated.h>          // Defines common routines
$tmp_reg
$tmp_reg
 
 
 
 
$libh
$libh
 
 
 
 
$inst
$inst
int reset,clk,enable;
int reset,clk,enable;
 
 
 
 
#include \"parameter.h\"
#include \"parameter.h\"
void * tile_chan_out[NE];
void * tile_chan_out[NE];
void * tile_chan_in[NE];
void * tile_chan_in[NE];
 
 
 
 
 
 
#define CHAN_SIZE   sizeof(tile0->ni_chan_in)
#define CHAN_SIZE   sizeof(tile0->ni_chan_in)
 
 
#define conect_r2r(T1,r1,p1,T2,r2,p2)  \\
#define conect_r2r(T1,r1,p1,T2,r2,p2)  \\
        memcpy(&router##T1 [r1]->chan_in[p1] , &router##T2 [r2]->chan_out[p2], CHAN_SIZE )
        memcpy(&router##T1 [r1]->chan_in[p1] , &router##T2 [r2]->chan_out[p2], CHAN_SIZE )
 
 
#define connect_r2gnd(T,r,p)\\
#define connect_r2gnd(T,r,p)\\
        memset(&router##T [r]->chan_in [p],0x00,CHAN_SIZE)
        memset(&router##T [r]->chan_in [p],0x00,CHAN_SIZE)
 
 
#define connect_r2e(T,r,p,e) \\
#define connect_r2e(T,r,p,e) \\
        memcpy(&router##T [r]->chan_in[p], tile_chan_out[e], CHAN_SIZE );\\
        memcpy(&router##T [r]->chan_in[p], tile_chan_out[e], CHAN_SIZE );\\
        memcpy(tile_chan_in[e], &router##T [r]->chan_out[p], CHAN_SIZE )
        memcpy(tile_chan_in[e], &router##T [r]->chan_out[p], CHAN_SIZE )
 
 
 
 
 
 
#include \"topology_top.h\"
#include \"topology_top.h\"
$include2
$include2
 
 
/*
/*
$top_port_info
$top_port_info
*/
*/
 
 
 
 
unsigned int main_time = 0; // Current simulation time
unsigned int main_time = 0; // Current simulation time
 
 
 
 
 
 
void connect_clk_reset_en_all(void){
void connect_clk_reset_en_all(void){
        //clk,reset,enable
        //clk,reset,enable
$tile_reset
$tile_reset
$tile_clk
$tile_clk
$tile_en
$tile_en
        connect_routers_reset_clk();
        connect_routers_reset_clk();
}
}
 
 
void sim_eval_all(void){
void sim_eval_all(void){
        routers_eval();
        routers_eval();
$tile_eval
$tile_eval
}
}
 
 
void sim_final_all(void ){
void sim_final_all(void ){
        routers_final();
        routers_final();
$tile_final
$tile_final
}
}
 
 
void clk_posedge_event(void) {
void clk_posedge_event(void) {
 
 
        clk = 1;       // Toggle clock
        clk = 1;       // Toggle clock
        // you can change the inputs and read the outputs here in case they are captured at posedge of clock
        // you can change the inputs and read the outputs here in case they are captured at posedge of clock
        $rxd_wr_cal
        $rxd_wr_cal
        connect_clk_reset_en_all();
        connect_clk_reset_en_all();
        sim_eval_all();
        sim_eval_all();
}
}
 
 
 
 
void clk_negedge_event(void){
void clk_negedge_event(void){
 
 
        clk = 0;
        clk = 0;
        topology_connect_all_nodes ();
        topology_connect_all_nodes ();
        connect_clk_reset_en_all();
        connect_clk_reset_en_all();
        sim_eval_all();
        sim_eval_all();
}
}
 
 
 
 
int main(int argc, char** argv) {
int main(int argc, char** argv) {
        int i,j,x,y;
        int i,j,x,y;
        $rxd_info
        $rxd_info
        Verilated::commandArgs(argc, argv);   // Remember args
        Verilated::commandArgs(argc, argv);   // Remember args
        Vrouter_new();             // Create instance
        Vrouter_new();             // Create instance
 
 
$newinst
$newinst
 
 
        /********************
        /********************
        *       initialize input
        *       initialize input
        *********************/
        *********************/
        $tile_chans
        $tile_chans
 
 
        reset=1;
        reset=1;
        enable=1;
        enable=1;
        topology_init();
        topology_init();
 
 
        $no_connected
        $no_connected
 
 
$tile_addr
$tile_addr
 
 
 
 
        main_time=0;
        main_time=0;
        printf(\"Start Simulation\\n\");
        printf(\"Start Simulation\\n\");
        while (!Verilated::gotFinish()) {
        while (!Verilated::gotFinish()) {
            $rxd_cap_cal
            $rxd_cap_cal
            if ((main_time & 0x3FF)==0) fflush(stdout); // fflush \$dispaly command each 1024 clock cycle
            if ((main_time & 0x3FF)==0) fflush(stdout); // fflush \$dispaly command each 1024 clock cycle
                if (main_time >= 10 )   reset=0;
                if (main_time >= 10 )   reset=0;
 
 
                clk_posedge_event( );
                clk_posedge_event( );
                //The valus of all registers and input ports valuse change @ posedge of the clock. Once clk is deasserted,  as multiple modules are connected inside the testbench we need several eval for propogating combinational logic values
                //The valus of all registers and input ports valuse change @ posedge of the clock. Once clk is deasserted,  as multiple modules are connected inside the testbench we need several eval for propogating combinational logic values
                //between modules when the clock .
                //between modules when the clock .
                for (i=0;i<2*(SMART_MAX+1);i++) clk_negedge_event( );
                for (i=0;i<2*(SMART_MAX+1);i++) clk_negedge_event( );
 
 
                main_time++;
                main_time++;
        }//while
        }//while
 
 
        // Simulation is done
        // Simulation is done
        sim_final_all();
        sim_final_all();
}
}
 
 
double sc_time_stamp () {       // Called by \$time in Verilog
double sc_time_stamp () {       // Called by \$time in Verilog
        return main_time;
        return main_time;
}
}
 
 
 
 
";
";
 
 
        save_file("$dir/parameter.h",$parameter_h);
        save_file("$dir/parameter.h",$parameter_h);
        save_file("$dir/testbench.cpp",$main_c);
        save_file("$dir/testbench.cpp",$main_c);
 
 
}
}
 
 
 
 
 
 
sub soc_get_all_parameters {
sub soc_get_all_parameters {
        my $soc=shift;
        my $soc=shift;
        my @instances=$soc->soc_get_all_instances();
        my @instances=$soc->soc_get_all_instances();
 
 
        my %all_param;
        my %all_param;
        foreach my $id (@instances){
        foreach my $id (@instances){
 
 
                my $module      =$soc->soc_get_module($id);
                my $module      =$soc->soc_get_module($id);
                my $category    =$soc->soc_get_category($id);
                my $category    =$soc->soc_get_category($id);
                my $inst        = $soc->soc_get_instance_name($id);
                my $inst        = $soc->soc_get_instance_name($id);
                my %params      = $soc->soc_get_module_param($id);
                my %params      = $soc->soc_get_module_param($id);
                my %params_type = $soc->soc_get_module_param_type($id);
                my %params_type = $soc->soc_get_module_param_type($id);
                my $ip = ip->lib_new ();
                my $ip = ip->lib_new ();
                my @param_order=$soc->soc_get_instance_param_order($id);
                my @param_order=$soc->soc_get_instance_param_order($id);
 
 
                foreach my $p (sort keys %params){
                foreach my $p (sort keys %params){
                        my $inst_param= "$inst\_$p";
                        my $inst_param= "$inst\_$p";
                        #add instance name to parameter value
                        #add instance name to parameter value
                        $params{$p}=add_instantc_name_to_parameters(\%params,$inst,$params{$p});
                        $params{$p}=add_instantc_name_to_parameters(\%params,$inst,$params{$p});
                        my ($default,$type,$content,$info,$vfile_param_type,$redefine_param)= $ip->ip_get_parameter($category,$module,$p);
                        my ($default,$type,$content,$info,$vfile_param_type,$redefine_param)= $ip->ip_get_parameter($category,$module,$p);
 
 
                        $vfile_param_type= "Don't include" if (!defined $vfile_param_type );
                        $vfile_param_type= "Don't include" if (!defined $vfile_param_type );
                        if ($vfile_param_type eq "Localparam"){
                        if ($vfile_param_type eq "Localparam"){
                                my $type = $params_type{$p};
                                my $type = $params_type{$p};
                                $type = "Localparam" if (! defined $type);
                                $type = "Localparam" if (! defined $type);
                                $vfile_param_type = ($type eq 'Parameter')?  "Parameter" : "Localparam";
                                $vfile_param_type = ($type eq 'Parameter')?  "Parameter" : "Localparam";
                        }
                        }
 
 
                        #$vfile_param_type= "Parameter"  if ($vfile_param_type eq 1);
                        #$vfile_param_type= "Parameter"  if ($vfile_param_type eq 1);
                        #$vfile_param_type= "Localparam" if ($vfile_param_type eq 0);
                        #$vfile_param_type= "Localparam" if ($vfile_param_type eq 0);
                        $all_param{ $inst_param} =      $params{ $p} if($vfile_param_type eq "Parameter" || $vfile_param_type eq "Localparam"  );
                        $all_param{ $inst_param} =      $params{ $p} if($vfile_param_type eq "Parameter" || $vfile_param_type eq "Localparam"  );
                        #print"$all_param{ $inst_param} =       $params{ $p} if($vfile_param_type eq \"Parameter\" || $vfile_param_type eq \"Localparam\"  );   \n";
                        #print"$all_param{ $inst_param} =       $params{ $p} if($vfile_param_type eq \"Parameter\" || $vfile_param_type eq \"Localparam\"  );   \n";
                }
                }
        }
        }
        return %all_param;
        return %all_param;
}
}
 
 
sub soc_get_all_parameters_order {
sub soc_get_all_parameters_order {
        my $soc=shift;
        my $soc=shift;
        my @instances=$soc->soc_get_all_instances();
        my @instances=$soc->soc_get_all_instances();
        my $ip = ip->lib_new ();
        my $ip = ip->lib_new ();
        my @all_order;
        my @all_order;
        foreach my $id (@instances){
        foreach my $id (@instances){
                my $module      =$soc->soc_get_module($id);
                my $module      =$soc->soc_get_module($id);
                my $category    =$soc->soc_get_category($id);
                my $category    =$soc->soc_get_category($id);
                my $inst        = $soc->soc_get_instance_name($id);
                my $inst        = $soc->soc_get_instance_name($id);
                my @order       = $soc->soc_get_instance_param_order($id);
                my @order       = $soc->soc_get_instance_param_order($id);
                my %params_type = $soc->soc_get_module_param_type($id);
                my %params_type = $soc->soc_get_module_param_type($id);
                foreach my $p ( @order){
                foreach my $p ( @order){
                        my $inst_param= "$inst\_$p";
                        my $inst_param= "$inst\_$p";
                        my ($default,$type,$content,$info,$vfile_param_type,$redefine_param)= $ip->ip_get_parameter($category,$module,$p);
                        my ($default,$type,$content,$info,$vfile_param_type,$redefine_param)= $ip->ip_get_parameter($category,$module,$p);
                        $vfile_param_type= "Don't include" if (!defined $vfile_param_type );
                        $vfile_param_type= "Don't include" if (!defined $vfile_param_type );
                        if ($vfile_param_type eq "Localparam"){
                        if ($vfile_param_type eq "Localparam"){
                                my $type = $params_type{$p};
                                my $type = $params_type{$p};
                                $type = "Localparam" if (! defined $type);
                                $type = "Localparam" if (! defined $type);
                                $vfile_param_type = ($type eq 'Parameter')?  "Parameter" : "Localparam";
                                $vfile_param_type = ($type eq 'Parameter')?  "Parameter" : "Localparam";
                        }
                        }
                        #$vfile_param_type= "Parameter"  if ($vfile_param_type eq 1);
                        #$vfile_param_type= "Parameter"  if ($vfile_param_type eq 1);
                        #$vfile_param_type= "Localparam" if ($vfile_param_type eq 0);
                        #$vfile_param_type= "Localparam" if ($vfile_param_type eq 0);
                        push(@all_order, $inst_param) if($vfile_param_type eq "Parameter" || $vfile_param_type eq "Localparam"  );
                        push(@all_order, $inst_param) if($vfile_param_type eq "Parameter" || $vfile_param_type eq "Localparam"  );
                }
                }
        }
        }
        return @all_order;
        return @all_order;
}
}
 
 
 
 
 
 
sub gen_modelsim_soc_testbench {
sub gen_modelsim_soc_testbench {
        my ($self,$name,$top,$target_dir,$tview)=@_;
        my ($self,$name,$top,$target_dir,$tview)=@_;
        my $dir="$target_dir/Modelsim";
        my $dir="$target_dir/Modelsim";
        my $soc_top= $self->object_get_attribute('top_ip',undef);
        my $soc_top= $self->object_get_attribute('top_ip',undef);
 
 
        my @intfcs=$soc_top->top_get_intfc_list();
        my @intfcs=$soc_top->top_get_intfc_list();
        my %PP;
        my %PP;
        my $top_port_def="// ${name}.v IO definition \n";
        my $top_port_def="// ${name}.v IO definition \n";
        my $pin_assign;
        my $pin_assign;
        my $rst_inputs='';
        my $rst_inputs='';
 
 
 
 
 
 
 
 
        #add functions
        #add functions
        my $project_dir   = get_project_dir();
        my $project_dir   = get_project_dir();
        open my $file1, "<", "$project_dir/mpsoc/perl_gui/lib/verilog/functions.v" or die;
        open my $file1, "<", "$project_dir/mpsoc/perl_gui/lib/verilog/functions.v" or die;
        my $functions_all='';
        my $functions_all='';
        while (my $f1 = readline ($file1)) {
        while (my $f1 = readline ($file1)) {
                 $functions_all="$functions_all $f1 ";
                 $functions_all="$functions_all $f1 ";
        }
        }
        close($file1);
        close($file1);
 
 
        #get parameters
        #get parameters
        my $params_v="";
        my $params_v="";
        my $n= $self->object_get_attribute('soc_name',undef);
        my $n= $self->object_get_attribute('soc_name',undef);
 
 
        if(defined $n){ #we are compiling a single tile as SoC
        if(defined $n){ #we are compiling a single tile as SoC
                my $core_id= $self->object_get_attribute('global_param','CORE_ID');
                my $core_id= $self->object_get_attribute('global_param','CORE_ID');
                my $sw_loc = $self->object_get_attribute('global_param','SW_LOC');
                my $sw_loc = $self->object_get_attribute('global_param','SW_LOC');
 
 
                        $params_v="\tlocalparam\tCORE_ID=$core_id;
                        $params_v="\tlocalparam\tCORE_ID=$core_id;
\tlocalparam\tSW_LOC=\"$sw_loc\";\n";
\tlocalparam\tSW_LOC=\"$sw_loc\";\n";
                my %params=soc_get_all_parameters($self);
                my %params=soc_get_all_parameters($self);
                my @order= soc_get_all_parameters_order($self);
                my @order= soc_get_all_parameters_order($self);
                foreach my $p (@order){
                foreach my $p (@order){
                        add_text_to_string(\$params_v,"\tlocalparam  $p = $params{$p};\n") if(defined $params{$p} );
                        add_text_to_string(\$params_v,"\tlocalparam  $p = $params{$p};\n") if(defined $params{$p} );
                }
                }
        }else{ # we are simulating a mpsoc
        }else{ # we are simulating a mpsoc
                $params_v= gen_socs_param($self);
                $params_v= gen_socs_param($self);
 
 
 
 
        }
        }
 
 
        foreach my $intfc (@intfcs){
        foreach my $intfc (@intfcs){
                my $key= ( $intfc eq 'plug:clk[0]')? 'clk' :
                my $key= ( $intfc eq 'plug:clk[0]')? 'clk' :
                         ( $intfc eq 'plug:reset[0]')? 'reset':
                         ( $intfc eq 'plug:reset[0]')? 'reset':
                         ( $intfc eq 'plug:enable[0]')? 'en' : 'other';
                         ( $intfc eq 'plug:enable[0]')? 'en' : 'other';
                my $key1="${key}1";
                my $key1="${key}1";
                my $key0="${key}0";
                my $key0="${key}0";
 
 
                my @ports=$soc_top->top_get_intfc_ports_list($intfc);
                my @ports=$soc_top->top_get_intfc_ports_list($intfc);
                my $f=1;
                my $f=1;
                foreach my $p (@ports){
                foreach my $p (@ports){
                        my($inst,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
                        my($inst,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
 
 
                        $PP{$key1}= (defined $PP{$key1})? "$PP{$key1} $p=1;\n" : "$p=1;\n";
                        $PP{$key1}= (defined $PP{$key1})? "$PP{$key1} $p=1;\n" : "$p=1;\n";
                        $PP{$key0}= (defined $PP{$key0})? "$PP{$key0} $p=0;\n" : "$p=0;\n";
                        $PP{$key0}= (defined $PP{$key0})? "$PP{$key0} $p=0;\n" : "$p=0;\n";
 
 
 
 
                        if  (length($range)!=0){
                        if  (length($range)!=0){
#                               #replace parameter with their values            #
#                               #replace parameter with their values            #
#                               my @a= split (/\b/,$range);
#                               my @a= split (/\b/,$range);
#                               print "a=@a\n";
#                               print "a=@a\n";
#                               foreach my $l (@a){
#                               foreach my $l (@a){
#                                       my $value=$params{$l};
#                                       my $value=$params{$l};
#                                       if(defined $value){
#                                       if(defined $value){
#                                               chomp $value;
#                                               chomp $value;
#                                               ($range=$range)=~ s/\b$l\b/$value/g      if(defined $params{$l});
#                                               ($range=$range)=~ s/\b$l\b/$value/g      if(defined $params{$l});
#                                               print "($range=$range)=~ s/\b$l\b/$value/g      if(defined $params{$l}); \n";
#                                               print "($range=$range)=~ s/\b$l\b/$value/g      if(defined $params{$l}); \n";
#                                       }
#                                       }
#                               }
#                               }
                                $range = "[ $range ]" ;
                                $range = "[ $range ]" ;
                        }
                        }
 
 
 
 
 
 
 
 
 
 
                        if($type eq 'input'){
                        if($type eq 'input'){
                                $top_port_def="$top_port_def  reg  $range  $p;\n"
                                $top_port_def="$top_port_def  reg  $range  $p;\n"
                        }else{
                        }else{
                                $top_port_def="$top_port_def  wire  $range  $p;\n"
                                $top_port_def="$top_port_def  wire  $range  $p;\n"
                        }
                        }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                        $pin_assign=(defined $pin_assign)? "$pin_assign,\n\t\t.$p($p)":  "\t\t.$p($p)";
                        $pin_assign=(defined $pin_assign)? "$pin_assign,\n\t\t.$p($p)":  "\t\t.$p($p)";
                        $rst_inputs= "$rst_inputs $p=0;\n" if ($key eq 'other' && $type eq 'input' );
                        $rst_inputs= "$rst_inputs $p=0;\n" if ($key eq 'other' && $type eq 'input' );
                }
                }
 
 
 
 
        }
        }
my $global_localparam=get_golal_param_v();
my $global_localparam=get_golal_param_v();
my $test_v= get_license_header("testbench.v");
my $test_v= get_license_header("testbench.v");
 
 
my $mpsoc_name=$self->object_get_attribute('mpsoc_name');
my $mpsoc_name=$self->object_get_attribute('mpsoc_name');
#if(defined $mpsoc_name){
#if(defined $mpsoc_name){
        if(0){
        if(0){
 
 
 
 
        my $top_ip=ip_gen->top_gen_new();
        my $top_ip=ip_gen->top_gen_new();
        my $target_dir  = "$ENV{'PRONOC_WORK'}/MPSOC/$mpsoc_name";
        my $target_dir  = "$ENV{'PRONOC_WORK'}/MPSOC/$mpsoc_name";
    my $hw_dir     = "$target_dir/src_verilog";
    my $hw_dir     = "$target_dir/src_verilog";
    my $sw_dir     = "$target_dir/sw";
    my $sw_dir     = "$target_dir/sw";
        my ($socs_v,$io_short,$io_full,$top_io_short,$top_io_full,$top_io_pass,$href)=gen_socs_v($self,$top_ip,$sw_dir,$tview);
        my ($socs_v,$io_short,$io_full,$top_io_short,$top_io_full,$top_io_pass,$href)=gen_socs_v($self,$top_ip,$sw_dir,$tview);
        my $socs_param= gen_socs_param($self);
        my $socs_param= gen_socs_param($self);
        my $global_localparam=get_golal_param_v();
        my $global_localparam=get_golal_param_v();
        my ($clk_set, $clk_io_sim,$clk_io_full, $clk_assigned_port)= get_top_clk_setting($self);
        my ($clk_set, $clk_io_sim,$clk_io_full, $clk_assigned_port)= get_top_clk_setting($self);
 
 
 
 
$test_v.="
$test_v.="
 
 
$clk_set, $clk_io_sim,$clk_io_full, $clk_assigned_port
$clk_set, $clk_io_sim,$clk_io_full, $clk_assigned_port
 
 
`timescale       1ns/1ps
`timescale       1ns/1ps
 
 
module testbench;
module testbench;
 
 
$functions_all
$functions_all
 
 
$global_localparam
$global_localparam
 
 
$socs_param
$socs_param
 
 
$top_port_def
$top_port_def
 
 
 
 
\t${mpsoc_name} the_${mpsoc_name} (
\t${mpsoc_name} the_${mpsoc_name} (
$top_io_pass
$top_io_pass
 
 
\t);
\t);
/*****************************************************************/
/*****************************************************************/
";
";
 
 
 
 
}
}
 
 
$test_v ="$test_v
$test_v ="$test_v
 
 
`timescale       1ns/1ps
`timescale       1ns/1ps
 
 
module testbench;
module testbench;
 
 
$functions_all
$functions_all
 
 
$global_localparam
$global_localparam
 
 
$params_v
$params_v
 
 
$top_port_def
$top_port_def
 
 
 
 
        $name uut (
        $name uut (
$pin_assign
$pin_assign
        );
        );
 
 
//clock defination
//clock defination
initial begin
initial begin
        forever begin
        forever begin
        #5 $PP{clk0}
        #5 $PP{clk0}
        #5 $PP{clk1}
        #5 $PP{clk1}
        end
        end
end
end
 
 
 
 
 
 
initial begin
initial begin
        // reset $name module at the start up
        // reset $name module at the start up
        $PP{reset1}
        $PP{reset1}
        $PP{en1}
        $PP{en1}
        $rst_inputs
        $rst_inputs
        // deasert the reset after 200 ns
        // deasert the reset after 200 ns
        #200
        #200
        $PP{reset0}
        $PP{reset0}
 
 
        // write your testbench here
        // write your testbench here
 
 
 
 
 
 
 
 
end
end
 
 
endmodule
endmodule
";
";
        save_file("$dir/testbench.v",$test_v);
        save_file("$dir/testbench.v",$test_v);
 
 
 
 
 
 
}
}
 
 
sub verilator_testbench{
sub verilator_testbench{
        my ($self,$name,$top,$target_dir,$vendor)=@_;
        my ($self,$name,$top,$target_dir,$vendor)=@_;
        my $verilator="$target_dir/verilator";
        my $verilator="$target_dir/verilator";
        my $dir="$verilator";
        my $dir="$verilator";
 
 
        my ($app,$table,$tview,$window) = software_main($dir,'testbench.cpp');
        my ($app,$table,$tview,$window) = software_main($dir,'testbench.cpp');
 
 
        my $n= $self->object_get_attribute('soc_name',undef);
        my $n= $self->object_get_attribute('soc_name',undef);
        if(defined $n){ #we are compiling a single tile as SoC
        if(defined $n){ #we are compiling a single tile as SoC
                gen_verilator_soc_testbench (@_) if((-f "$dir/testbench.cpp")==0);
                gen_verilator_soc_testbench (@_) if((-f "$dir/testbench.cpp")==0);
        }
        }
        else { # we are compiling a complete NoC-based mpsoc
        else { # we are compiling a complete NoC-based mpsoc
                gen_verilator_mpsoc_testbench (@_,$tview) if((-f "$dir/testbench.cpp")==0);
                gen_verilator_mpsoc_testbench (@_,$tview) if((-f "$dir/testbench.cpp")==0);
 
 
        }
        }
 
 
        #copy makefile
        #copy makefile
        #copy("../script/verilator_soc_make", "$verilator/obj_dir/Makefile");
        #copy("../script/verilator_soc_make", "$verilator/obj_dir/Makefile");
 
 
 
 
 
 
 
 
 
 
        my $make = def_image_button('icons/gen.png','Compile');
        my $make = def_image_button('icons/gen.png','Compile');
        my $regen=def_image_button('icons/refresh.png','Regenerate Testbench.cpp');
        my $regen=def_image_button('icons/refresh.png','Regenerate Testbench.cpp');
        my $run = def_image_button('icons/run.png','Run');
        my $run = def_image_button('icons/run.png','Run');
        my $back=def_image_button('icons/left.png','Previous');
        my $back=def_image_button('icons/left.png','Previous');
 
 
 
 
 
 
        $table->attach ($back,1,2,1,2,'shrink','shrink',0,0);
        $table->attach ($back,1,2,1,2,'shrink','shrink',0,0);
        $table->attach ($regen,3,4,1,2,'shrink','shrink',0,0);
        $table->attach ($regen,3,4,1,2,'shrink','shrink',0,0);
        $table->attach ($make,6, 7, 1,2,'shrink','shrink',0,0);
        $table->attach ($make,6, 7, 1,2,'shrink','shrink',0,0);
        $table->attach ($run,9, 10, 1,2,'shrink','shrink',0,0);
        $table->attach ($run,9, 10, 1,2,'shrink','shrink',0,0);
 
 
        $back-> signal_connect("clicked" => sub{
        $back-> signal_connect("clicked" => sub{
 
 
                $window->destroy;
                $window->destroy;
                verilator_compilation_win($self,$name,$top,$target_dir,$vendor);
                verilator_compilation_win($self,$name,$top,$target_dir,$vendor);
 
 
        });
        });
 
 
        $regen-> signal_connect("clicked" => sub{
        $regen-> signal_connect("clicked" => sub{
                my $response = yes_no_dialog("Are you sure you want to regenerate the testbench.cpp file? Note that any changes you have made will be lost");
                my $response = yes_no_dialog("Are you sure you want to regenerate the testbench.cpp file? Note that any changes you have made will be lost");
                if ($response eq 'yes') {
                if ($response eq 'yes') {
                        my $n= $self->object_get_attribute('soc_name',undef);
                        my $n= $self->object_get_attribute('soc_name',undef);
                        if(defined $n){ #we are compiling a single tile as SoC
                        if(defined $n){ #we are compiling a single tile as SoC
                                gen_verilator_soc_testbench ($self,$name,$top,$target_dir);
                                gen_verilator_soc_testbench ($self,$name,$top,$target_dir);
                        }
                        }
                        else { # we are compiling a complete NoC-based mpsoc
                        else { # we are compiling a complete NoC-based mpsoc
                                gen_verilator_mpsoc_testbench ($self,$name,$top,$target_dir,$tview);
                                gen_verilator_mpsoc_testbench ($self,$name,$top,$target_dir,$tview);
 
 
                        }
                        }
 
 
                        $app->refresh_source("$dir/testbench.cpp");
                        $app->refresh_source("$dir/testbench.cpp");
                }
                }
        });
        });
 
 
 
 
        $make -> signal_connect("clicked" => sub{
        $make -> signal_connect("clicked" => sub{
                $make->hide;
                $make->hide;
                my $load= show_gif("icons/load.gif");
                my $load= show_gif("icons/load.gif");
                $table->attach ($load,8, 9, 1,2,'shrink','shrink',0,0);
                $table->attach ($load,8, 9, 1,2,'shrink','shrink',0,0);
                $table->show_all;
                $table->show_all;
                $app->ask_to_save_changes();
                $app->ask_to_save_changes();
                copy("$dir/testbench.cpp", "$verilator/obj_dir/testbench.cpp");
                copy("$dir/testbench.cpp", "$verilator/obj_dir/testbench.cpp");
                copy("$dir/parameter.h", "$verilator/obj_dir/parameter.h") if(-f "$dir/parameter.h");
                copy("$dir/parameter.h", "$verilator/obj_dir/parameter.h") if(-f "$dir/parameter.h");
                copy("$dir/RxDsim.h", "$verilator/obj_dir/RxDsim.h") if(-f "$dir/RxDsim.h");
                copy("$dir/RxDsim.h", "$verilator/obj_dir/RxDsim.h") if(-f "$dir/RxDsim.h");
 
 
                my $tops_ref=$self->object_get_attribute('verilator','libs');
                my $tops_ref=$self->object_get_attribute('verilator','libs');
                my %tops=%{$tops_ref};
                my %tops=%{$tops_ref};
                my $lib_num=0;
                my $lib_num=0;
                my $cpu_num = $self->object_get_attribute('compile', 'cpu_num');
                my $cpu_num = $self->object_get_attribute('compile', 'cpu_num');
                $cpu_num = 1 if (!defined $cpu_num);
                $cpu_num = 1 if (!defined $cpu_num);
                add_colored_info($tview,"Makefie will use the maximum number of $cpu_num core(s) in parallel for compilation\n",'green');
                add_colored_info($tview,"Makefie will use the maximum number of $cpu_num core(s) in parallel for compilation\n",'green');
                my $length=scalar (keys %tops);
                my $length=scalar (keys %tops);
                my $cmd="";
                my $cmd="";
                foreach my $top (sort keys %tops) {
                foreach my $top (sort keys %tops) {
                        $cmd.= "lib$lib_num & ";
                        $cmd.= "lib$lib_num & ";
                        $lib_num++;
                        $lib_num++;
                        if( $lib_num % $cpu_num == 0 || $lib_num == $length){
                        if( $lib_num % $cpu_num == 0 || $lib_num == $length){
                                $cmd.="wait\n";
                                $cmd.="wait\n";
                                run_make_file("$verilator/obj_dir/",$tview,$cmd);
                                run_make_file("$verilator/obj_dir/",$tview,$cmd);
                                $cmd="";
                                $cmd="";
                        }else {
                        }else {
                                $cmd.=" make ";
                                $cmd.=" make ";
                        }
                        }
                }
                }
 
 
 
 
                #foreach my $top (sort keys %tops) {
                #foreach my $top (sort keys %tops) {
                #               run_make_file("$verilator/obj_dir/",$tview,"lib$lib_num");
                #               run_make_file("$verilator/obj_dir/",$tview,"lib$lib_num");
                #               $lib_num++;
                #               $lib_num++;
                #}
                #}
 
 
 
 
 
 
                run_make_file("$verilator/obj_dir/",$tview,"sim");
                run_make_file("$verilator/obj_dir/",$tview,"sim");
                $load->destroy;
                $load->destroy;
                $make->show_all;
                $make->show_all;
 
 
        });
        });
 
 
        $run -> signal_connect("clicked" => sub{
        $run -> signal_connect("clicked" => sub{
                my $bin="$verilator/obj_dir/testbench";
                my $bin="$verilator/obj_dir/testbench";
                if (-f $bin){
                if (-f $bin){
                        my $cmd= "cd \"$verilator/obj_dir/\" \n xterm -e bash -c \"$bin; sleep 5\"";
                        my $cmd= "cd \"$verilator/obj_dir/\" \n xterm -e bash -c \"$bin; sleep 5\"";
                        add_info($tview,"$cmd\n");
                        add_info($tview,"$cmd\n");
                        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($tview,"$stderr\n",'red');
                                add_colored_info($tview,"$stderr\n",'red');
                        }else {
                        }else {
                                add_info($tview,"$stdout\n");
                                add_info($tview,"$stdout\n");
                        }
                        }
 
 
                }else{
                }else{
                        add_colored_info($tview,"Cannot find $bin executable binary file! make sure you have compiled the testbench successfully\n", 'red')
                        add_colored_info($tview,"Cannot find $bin executable binary file! make sure you have compiled the testbench successfully\n", 'red')
                }
                }
 
 
                });
                });
 
 
 
 
}
}
 
 
 
 
 
 
1;
1;
 
 

powered by: WebSVN 2.1.0

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