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 42 and 43

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

Rev 42 Rev 43
#! /usr/bin/perl -w
#! /usr/bin/perl -w
use Glib qw/TRUE FALSE/;
use Glib qw/TRUE FALSE/;
use strict;
use strict;
use warnings;
use warnings;
 
 
 
use FindBin;
 
use lib $FindBin::Bin;
 
 
use soc;
use soc;
#use ip;
 
#use interface;
 
#use POSIX 'strtol';
 
 
 
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 Gtk2;
use Gtk2;
#use Gtk2::Pango;
 
 
 
use List::MoreUtils qw( minmax );
use List::MoreUtils qw( minmax );
 
 
 
 
 
 
################
################
#       Comile
#       Comile
#################
#################
 
 
 
 
 
 
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 gen_combo_model{
sub gen_combo_model{
        my $ref=shift;
        my $ref=shift;
        my %inputs=%{$ref};
        my %inputs=%{$ref};
        my $store = Gtk2::TreeStore->new('Glib::String');
        my $store = Gtk2::TreeStore->new('Glib::String');
         for my $i (sort { $a cmp $b} keys %inputs ) {
         for my $i (sort { $a cmp $b} keys %inputs ) {
                my $iter = $store->append(undef);
                my $iter = $store->append(undef);
 
 
                $store->set($iter, 0, $i);
                $store->set($iter, 0, $i);
                for my $capital (sort { $a cmp $b} keys %{$inputs{$i}}) {
                for my $capital (sort { $a cmp $b} keys %{$inputs{$i}}) {
                        my $iter2 = $store->append($iter);
                        my $iter2 = $store->append($iter);
                        $store->set($iter2, 0, $capital);
                        $store->set($iter2, 0, $capital);
                }
                }
        }
        }
        return $store;
        return $store;
 
 
}
}
 
 
sub gen_tree_combo{
sub gen_tree_combo{
        my $model=shift;
        my $model=shift;
        my $combo = Gtk2::ComboBox->new_with_model($model);
        my $combo = Gtk2::ComboBox->new_with_model($model);
        my $renderer = Gtk2::CellRendererText->new();
        my $renderer = Gtk2::CellRendererText->new();
        $combo->pack_start($renderer, TRUE);
        $combo->pack_start($renderer, TRUE);
        $combo->set_attributes($renderer, "text", 0);
        $combo->set_attributes($renderer, "text", 0);
        $combo->set_cell_data_func($renderer, \&is_capital_sensitive);
        $combo->set_cell_data_func($renderer, \&is_capital_sensitive);
        return $combo;
        return $combo;
 
 
}
}
 
 
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');
        #get the list of boards located in "boards/*" folder
        #get the list of boards located in "boards/*" folder
        my @dirs = grep {-d} glob("../boards/*");
        my @dirs = grep {-d} glob("../boards/*");
        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 $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,Verilator,Modelsim"
        my $compilers=$self->object_get_attribute('compile','compilers');#"QuartusII,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 $compiler_options = ($old_compiler eq "QuartusII")? select_board  ($self,$name,$top,$target_dir):
        my $compiler_options = ($old_compiler eq "QuartusII")? select_board  ($self,$name,$top,$target_dir):
                               ($old_compiler eq "Modelsim")?  select_model_path  ($self,$name,$top,$target_dir):
                               ($old_compiler eq "Modelsim")?  select_model_path  ($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');
        my $next=def_image_button('icons/right.png','Next');
        $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"){
                if($compiler_type eq "QuartusII"){
                        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);}
                        if($new_board_name eq "Add New Board") {add_new_fpga_board($self,$name,$top,$target_dir,$end_func);}
                        else {get_pin_assignment($self,$name,$top,$target_dir,$end_func);}
                        else {get_pin_assignment($self,$name,$top,$target_dir,$end_func);}
                }elsif($compiler_type eq "Modelsim"){
                }elsif($compiler_type eq "Modelsim"){
                        modelsim_compilation($self,$name,$top,$target_dir);
                        modelsim_compilation($self,$name,$top,$target_dir);
 
 
                }else{#verilator
                }else{#verilator
                        verilator_compilation_win($self,$name,$top,$target_dir);
                        verilator_compilation_win($self,$name,$top,$target_dir);
 
 
                }
                }
 
 
                $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 = ($new_board_name eq "QuartusII")? select_board  ($self,$name,$top,$target_dir):
                $compiler_options = ($new_board_name eq "QuartusII")? select_board  ($self,$name,$top,$target_dir):
                                    ($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):
                                 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)=@_;
        my ($self,$name,$top,$target_dir)=@_;
 
 
        #get the list of boards located in "boards/*" folder
        #get the list of boards located in "boards/*" folder
        my @dirs = grep {-d} glob("../boards/*");
        my @dirs = grep {-d} glob("../boards/*");
        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 $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/\" path. You can add your boards by adding its required files in aformentioned path. Note that currently only Altera FPGAs are supported. For boards from other vendors, you need to directly use their own compiler and call $name.v file in your top level module.",'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/\" path. You can add your boards by adding its required files in aformentioned path. Note that currently only Altera FPGAs are supported. For boards from other vendors, you need to directly use their own compiler and call $name.v file in your top level module.",'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','quartus_bin');
        my $bin = $self->object_get_attribute('compile','quartus_bin');
        my $Quartus_bin=  $ENV{QUARTUS_BIN};
        my $Quartus_bin=  $ENV{QUARTUS_BIN};
        $col=0;
        $col=0;
        $self->object_add_attribute('compile','quartus_bin',$ENV{QUARTUS_BIN}) if (!defined $bin && defined $Quartus_bin);
        $self->object_add_attribute('compile','quartus_bin',$ENV{QUARTUS_BIN}) if (!defined $bin && defined $Quartus_bin);
        $table->attach(gen_label_help("Path to quartus/bin directory. You can set a default path as QUARTUS_BIN envirement variable in ~/.bashrc file.
        $table->attach(gen_label_help("Path to quartus/bin directory. You can set a default path as QUARTUS_BIN envirement variable in ~/.bashrc file.
e.g:  export QUARTUS_BIN=/home/alireza/altera/13.0sp1/quartus/bin",'Quartus  bin:'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
e.g:  export QUARTUS_BIN=/home/alireza/altera/13.0sp1/quartus/bin",'Quartus  bin:'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
        $table->attach(get_dir_in_object ($self,'compile','quartus_bin',undef,undef,undef),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$row++;
        $table->attach(get_dir_in_object ($self,'compile','quartus_bin',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 envirement variable in ~/.bashrc file.
        $table->attach(gen_label_help("Path to modelsim/bin directory. You can set a default path as MODELSIM_BIN envirement 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;
 
 
}
}
 
 
 
 
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)=@_;
        my ($self,$name,$top,$target_dir,$end_func)=@_;
        my $window = def_popwin_size(50,80,"Add New FPGA Board",'percent');
        my $window = def_popwin_size(50,80,"Add New FPGA Board",'percent');
        my $table = def_table(2, 2, FALSE);
        my $table = def_table(2, 2, FALSE);
        my $scrolled_win = new Gtk2::ScrolledWindow (undef, undef);
        my $scrolled_win = new Gtk2::ScrolledWindow (undef, undef);
        $scrolled_win->set_policy( "automatic", "automatic" );
        $scrolled_win->set_policy( "automatic", "automatic" );
        $scrolled_win->add_with_viewport($table);
        $scrolled_win->add_with_viewport($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');
    my $auto=def_image_button('icons/advance.png','Auto-fill');
    my $auto=def_image_button('icons/advance.png','Auto-fill');
 
 
        $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($auto,5,6,9,10,'shrink','shrink',2,2);
        $mtable->attach($auto,5,6,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);
 
 
        set_tip($auto, "Auto-fill JTAG configuration. The board must be powered on and be connecred to the PC.");
        set_tip($auto, "Auto-fill JTAG configuration. The board must be powered on and be connecred to the PC.");
 
 
 
 
 
 
        my $widgets= add_new_fpga_board_widgets($self,$name,$top,$target_dir,$end_func);
        my $widgets= add_new_fpga_board_widgets($self,$name,$top,$target_dir,$end_func);
        my ($Twin,$tview)=create_text();
        my ($Twin,$tview)=create_text();
        add_colors_to_textview($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 = add_new_fpga_board_files($self);
                my $result = add_new_fpga_board_files($self);
                if(! defined $result ){
                if(! defined $result ){
                        select_compiler($self,$name,$top,$target_dir,$end_func);
                        select_compiler($self,$name,$top,$target_dir,$end_func);
                        message_dialog("The new board has been added successfully!");
                        message_dialog("The new board has been added successfully!");
 
 
                        $window->destroy;
                        $window->destroy;
 
 
                }else {
                }else {
                        show_info(\$tview," ");
                        show_info(\$tview," ");
                        show_colored_info(\$tview,$result,'red');
                        show_colored_info(\$tview,$result,'red');
 
 
                }
                }
 
 
 
 
 
 
        });
        });
 
 
        $auto-> signal_connect("clicked" => sub{
        $auto-> signal_connect("clicked" => sub{
                my $pid;
                my $pid;
                my $hw;
                my $hw;
                my $dir = Cwd::getcwd();
                my $dir = Cwd::getcwd();
                my $project_dir   = abs_path("$dir/../../"); #mpsoc directory address           
                my $project_dir   = abs_path("$dir/../../"); #mpsoc directory address           
                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','quartus_qsf');
                                        my $qsf=$self->object_get_attribute('compile','quartus_qsf');
                                        if(!defined $qsf ){
                                        if(!defined $qsf ){
                                                add_colored_info (\$tview,"Cannot detect devce location in JTAG chin. Please enter the QSF file or fill in manually \n",'red');
                                                add_colored_info (\$tview,"Cannot detect devce location in JTAG chin. Please enter the QSF file or fill in manually \n",'red');
 
 
                                        }else{
                                        }else{
                                                #search for device nam ein qsf file
                                                #search for device nam ein 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_fpga_board_widgets($self,$name,$top,$target_dir,$end_func);
                $widgets= add_new_fpga_board_widgets($self,$name,$top,$target_dir,$end_func);
                $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_fpga_board_widgets{
sub add_new_fpga_board_widgets{
        my ($self,$name,$top,$target_dir,$end_func)=@_;
        my ($self,$name,$top,$target_dir,$end_func)=@_;
        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 Borad USB-Blaster product ID (PID). Power on your FPGA board and connect it to your PC. Then press Auto-fill button to find PID. Optinally you can run mpsoc/
        my $help4="FPGA Borad USB-Blaster product ID (PID). Power on your FPGA board and connect it to your PC. Then press Auto-fill button to find PID. Optinally 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. Optinally 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. Optinally 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 devive location in jtag chain. Optinally 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 devive location in jtag chain. Optinally you can run \$QUARTUS_BIN/jtagconfig to find your target device location in jtag chain.";
 
 
 
 
 
 
 
 
        my @info = (
        my @info = (
        { label=>"FPGA Borad name:",                   param_name=>'quartus_board', type=>"Entry",     default_val=>undef, content=>undef, info=>$help1, param_parent=>'compile', ref_delay=> undef},
        { label=>"FPGA Borad name:",                   param_name=>'quartus_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=>'quartus_qsf',   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=>'quartus_qsf',   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=>'quartus_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=>'quartus_v',     type=>"FILE_path", default_val=>undef, content=>"v", info=>$help3, param_parent=>'compile',ref_delay=>undef },
        );
        );
 
 
        my @usb = (
        my @usb = (
        { label=>"FPGA Borad USB Blaster PID:",        param_name=>'quartus_pid',   type=>"Entry",     default_val=>undef, content=>undef, info=>$help4, param_parent=>'compile', ref_delay=> undef},
        { label=>"FPGA Borad USB Blaster PID:",        param_name=>'quartus_pid',   type=>"Entry",     default_val=>undef, content=>undef, info=>$help4, param_parent=>'compile', ref_delay=> undef},
        { label=>"FPGA Borad Programming Hardware Name:", param_name=>'quartus_hardware',   type=>"Entry",     default_val=>undef, content=>undef, info=>$help5, param_parent=>'compile', ref_delay=> undef},
        { label=>"FPGA Borad Programming Hardware Name:", param_name=>'quartus_hardware',   type=>"Entry",     default_val=>undef, content=>undef, info=>$help5, param_parent=>'compile', ref_delay=> undef},
        { label=>"FPGA Borad 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 Borad 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,(Gtk2::HSeparator->new,gen_label_in_center("FPGA Board JTAG Configuration"),Gtk2::HSeparator->new));
        my $labl=def_pack_vbox(FALSE, 0,(Gtk2::HSeparator->new,gen_label_in_center("FPGA Board JTAG Configuration"),Gtk2::HSeparator->new));
 
 
        $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_fpga_board_files{
sub add_new_fpga_board_files{
        my $self=shift;
        my $self=shift;
 
 
        #check the board name
        #check the board name
        my $board_name=$self->object_get_attribute('compile','quartus_board');
        my $board_name=$self->object_get_attribute('compile','quartus_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','quartus_qsf');
        my $qsf=$self->object_get_attribute('compile','quartus_qsf');
        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','quartus_v');
        my $top=$self->object_get_attribute('compile','quartus_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 $dir = Cwd::getcwd();
        my $dir = Cwd::getcwd();
        my $path="$dir/../boards/$board_name";
        my $path="$dir/../boards/$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/sh
        print $file "#!/bin/sh
 
 
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/sh
print $file "#!/bin/sh
 
 
#usage:
#usage:
#       sh program_device.sh  programming_file.sof
#       sh 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)=@_;
        my ($self,$name,$top,$target_dir,$end_func)=@_;
        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 = new Gtk2::ScrolledWindow (undef, undef);
        my $scrolled_win = new Gtk2::ScrolledWindow (undef, undef);
        $scrolled_win->set_policy( "automatic", "automatic" );
        $scrolled_win->set_policy( "automatic", "automatic" );
        $scrolled_win->add_with_viewport($table);
        $scrolled_win->add_with_viewport($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/$board_name/jtag_intfc.sh","${fpath}../sw/jtag_intfc.sh");
        copy("../boards/$board_name/jtag_intfc.sh","${fpath}../sw/jtag_intfc.sh");
        my $n= $self->object_get_attribute('soc_name',undef);
        my $m= $self->object_get_attribute('mpsoc_name',undef);
        if(!defined $n){        # we are compiling a complete NoC-based mpsoc                                           
        if(defined $m){ # we are compiling a complete NoC-based mpsoc                                           
                my $nx= $self->object_get_attribute('noc_param',"NX");
                 my ($nr,$ne,$router_p,$ref_tops)= get_noc_verilator_top_modules_info($self);
                my $ny= $self->object_get_attribute('noc_param',"NY");
         for (my $tile_num=0;$tile_num<$ne;$tile_num++){
                for (my $y=0;$y<$ny;$y++){for (my $x=0; $x<$nx;$x++){
 
                        my $tile_num= $y*$nx+$x;
 
                        #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/$board_name/jtag_intfc.sh","${fpath}../sw/tile$tile_num/jtag_intfc.sh");
                        copy("../boards/$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/$board_name/program_device.sh","${fpath}../program_device.sh");
        copy("../boards/$board_name/program_device.sh","${fpath}../program_device.sh");
 
 
        #get boards pin list
        #get boards pin list
        my $top_v= "../boards/$board_name/$board_name.v";
        my $top_v= "../boards/$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!");
                message_dialog("Error: Could not load the board pin list. The $top_v does not exist!");
                $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 @lables= ('Port Direction','Port Range     ','Port name      ','Assigment Type','Board Port name ','Board Port Range');
        my @lables= ('Port Direction','Port Range     ','Port name      ','Assigment Type','Board Port name ','Board Port Range');
        foreach my $p (@lables){
        foreach my $p (@lables){
                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";
                                }
                                }
                        }
                        }
                        $portrange = "[ $portrange ]" ;
                        $portrange = "[ $portrange ]" ;
                }
                }
 
 
                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 = Gtk2::TreePath->new_from_indices(@indices);
                          my $path = Gtk2::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;
                quartus_compilation($self,$board,$name,$top,$target_dir,$end_func);
                quartus_compilation($self,$board,$name,$top,$target_dir,$end_func);
 
 
        });
        });
        $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);
 
 
        });
        });
 
 
 
 
        $window->add ($mtable);
        $window->add ($mtable);
        $window->show_all();
        $window->show_all();
}
}
 
 
 
 
 
 
 
 
 
 
sub quartus_compilation{
sub quartus_compilation{
        my ($self,$board,$name,$top,$target_dir,$end_func)=@_;
        my ($self,$board,$name,$top,$target_dir,$end_func)=@_;
 
 
        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,7, 8, 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 $dialog = Gtk2::MessageDialog->new (my $window,
                my $dialog = Gtk2::MessageDialog->new (my $window,
                                      'destroy-with-parent',
                                      'destroy-with-parent',
                                      'question', # message type
                                      'question', # message type
                                      'yes-no', # which set of buttons?
                                      'yes-no', # which set of buttons?
                                      "Are you sure you want to regenaret the Top.v file? Note that any changes you have made will be lost");
                                      "Are you sure you want to regenaret the Top.v file? Note that any changes you have made will be lost");
                my $response = $dialog->run;
                my $response = $dialog->run;
                if ($response eq 'yes') {
                if ($response eq 'yes') {
                        gen_top_v($self,$board,$name,$top);
                        gen_top_v($self,$board,$name,$top);
                        $app->load_source("$board_top_file");
                        $app->load_source("$board_top_file");
                }
                }
                $dialog->destroy;
                $dialog->destroy;
 
 
        });
        });
 
 
 
 
 
 
        $back-> signal_connect("clicked" => sub{
        $back-> signal_connect("clicked" => sub{
 
 
                $window->destroy;
                $window->destroy;
                get_pin_assignment($self,$name,$top,$target_dir);
                get_pin_assignment($self,$name,$top,$target_dir);
 
 
        });
        });
 
 
 
 
        #compile
        #compile
        $run-> signal_connect("clicked" => sub{
        $run-> signal_connect("clicked" => sub{
 
                my $load= show_gif("icons/load.gif");
 
                $table->attach ($load,8, 9, 1,2,'shrink','shrink',2,2);
 
                $load->show_all;
 
 
                set_gui_status($self,'save_project',1);
                set_gui_status($self,'save_project',1);
                $app->do_save();
                $app->do_save();
                my $error = 0;
                my $error = 0;
                add_info(\$tview,"CREATE: start creating Quartus project in $target_dir\n");
                add_info(\$tview,"CREATE: start creating Quartus project in $target_dir\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,'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/${name}.qsf";
                my $qsf_file="$target_dir/${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/$board_name/*.qsf");
                my @qsfs =   glob("../boards/$board_name/*.qsf");
                if(!defined $qsfs[0]){
                if(!defined $qsfs[0]){
                        message_dialog("Error: ../boards/$board_name folder does not contain the qsf file.!");
                        message_dialog("Error: ../boards/$board_name folder does not contain the qsf file.!");
                        $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);
                }
                }
 
 
 
 
                #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");
 
 
                }
                }
                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');;
                add_info(\$tview, "Start Quartus compilation.....\n");
                add_info(\$tview, "Start Quartus compilation.....\n");
                my @compilation_command =(
                my @compilation_command =(
                        "cd \"$target_dir/\" \n xterm -e sh -c '$Quartus_bin/quartus_map --64bit $name --read_settings_files=on; echo \$? > status' ",
                        "cd \"$target_dir/\" \n xterm -e sh -c '$Quartus_bin/quartus_map --64bit $name --read_settings_files=on; echo \$? > status' ",
                        "cd \"$target_dir/\" \n xterm -e sh -c '$Quartus_bin/quartus_fit --64bit $name --read_settings_files=on; echo \$? > status' ",
                        "cd \"$target_dir/\" \n xterm -e sh -c '$Quartus_bin/quartus_fit --64bit $name --read_settings_files=on; echo \$? > status' ",
                        "cd \"$target_dir/\" \n xterm -e sh -c '$Quartus_bin/quartus_asm --64bit $name --read_settings_files=on; echo \$? > status' ",
                        "cd \"$target_dir/\" \n xterm -e sh -c '$Quartus_bin/quartus_asm --64bit $name --read_settings_files=on; echo \$? > status' ",
                        "cd \"$target_dir/\" \n xterm -e sh -c '$Quartus_bin/quartus_sta --64bit $name;echo \$? > status' ");
                        "cd \"$target_dir/\" \n xterm -e sh -c '$Quartus_bin/quartus_sta --64bit $name;echo \$? > status' ");
 
 
                foreach my $cmd (@compilation_command){
                foreach my $cmd (@compilation_command){
                        add_info(\$tview,"$cmd\n");
                        add_info(\$tview,"$cmd\n");
                        unlink "$target_dir/status";
                        unlink "$target_dir/status";
                        my ($stdout,$exit)=run_cmd_in_back_ground_get_stdout( $cmd);
                        my ($stdout,$exit)=run_cmd_in_back_ground_get_stdout( $cmd);
                        open(my $fh,  "<$target_dir/status") || die "Can not open: $!";
                        open(my $fh,  "<$target_dir/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)=run_cmd_in_back_ground_get_stdout("cd \"$target_dir/output_files/\" \n grep -h \"Error (\" *");
                                ($stdout,$exit)=run_cmd_in_back_ground_get_stdout("cd \"$target_dir/output_files/\" \n grep -h \"Error (\" *");
                                add_colored_info(\$tview,"$stdout\n Quartus compilation failed !\n",'red');
                                add_colored_info(\$tview,"$stdout\n Quartus compilation failed !\n",'red');
                                $error=1;
                                $error=1;
                                last;
                                last;
                        }
                        }
                }
                }
                add_colored_info(\$tview,"Quartus compilation is done successfully in $target_dir!\n", 'blue') if($error==0);
                add_colored_info(\$tview,"Quartus compilation is done successfully in $target_dir!\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');
                        }
                        }
                }
                }
 
                $load->destroy;
 
 
        });
        });
 
 
 
 
        #Programe the board 
        #Programe the board 
        $prog-> signal_connect("clicked" => sub{
        $prog-> signal_connect("clicked" => sub{
                my $error = 0;
                my $error = 0;
                my $sof_file="$target_dir/output_files/${name}.sof";
                my $sof_file="$target_dir/output_files/${name}.sof";
                my $bash_file="$target_dir/program_device.sh";
                my $bash_file="$target_dir/program_device.sh";
 
 
                add_info(\$tview,"Programe the board using quartus_pgm and $sof_file file\n");
                add_info(\$tview,"Programe 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 exists! This file veries depend on your target board and must be available inside mpsoc/boards/[board_name].\n", 'red');
                        add_colored_info(\$tview,"\tThe $bash_file does not exists! This file veries depend on your target board and must be available inside mpsoc/boards/[board_name].\n", 'red');
                        $error=1;
                        $error=1;
                }
                }
                return if($error);
                return if($error);
                my $command = "sh $bash_file $sof_file";
                my $command = "sh $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 programed successfully!\n",'red');
                        add_colored_info(\$tview,"Board was not programed 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 programed successfully!\n",'red');
                                add_colored_info(\$tview,"Board was not programed successfully!\n",'red');
                        }else{
                        }else{
                                add_info(\$tview,"$stdout\n");
                                add_info(\$tview,"$stdout\n");
                                add_colored_info(\$tview,"Board is programed successfully!\n",'blue');
                                add_colored_info(\$tview,"Board is programed successfully!\n",'blue');
 
 
                        }
                        }
 
 
                }
                }
        });
        });
 
 
 
 
}
}
 
 
 
 
 
 
 
 
 
 
 
 
sub modelsim_compilation{
sub modelsim_compilation{
        my ($self,$name,$top,$target_dir)=@_;
        my ($self,$name,$top,$target_dir)=@_;
        #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');
        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');
        my $regen=def_image_button('icons/refresh.png','Regenerate testbench.v');
        my $regen=def_image_button('icons/refresh.png','Regenerate testbench.v');
        #create testbench.v
        #create testbench.v
        gen_modelsim_soc_testbench ($self,$name,$top,$target_dir) if ((-f "$target_dir/src_verilog/testbench.v")==0);
        gen_modelsim_soc_testbench ($self,$name,$top,$target_dir) unless (-f "$target_dir/src_verilog/testbench.v");
 
 
 
 
 
 
        my ($app,$table,$tview,$window) = software_main("$target_dir/src_verilog",'testbench.v');
        my ($app,$table,$tview,$window) = software_main("$target_dir/src_verilog",'testbench.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,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 $dialog = Gtk2::MessageDialog->new (my $window,
                my $dialog = Gtk2::MessageDialog->new (my $window,
                                      'destroy-with-parent',
                                      'destroy-with-parent',
                                      'question', # message type
                                      'question', # message type
                                      'yes-no', # which set of buttons?
                                      'yes-no', # which set of buttons?
                                      "Are you sure you want to regenaret the testbench.v file? Note that any changes you have made will be lost");
                                      "Are you sure you want to regenaret the testbench.v file? Note that any changes you have made will be lost");
                my $response = $dialog->run;
                my $response = $dialog->run;
                if ($response eq 'yes') {
                if ($response eq 'yes') {
                        gen_modelsim_soc_testbench ($self,$name,$top,$target_dir);
                        gen_modelsim_soc_testbench ($self,$name,$top,$target_dir);
                        $app->load_source("$target_dir/src_verilog/testbench.v");
                        $app->load_source("$target_dir/src_verilog/testbench.v");
                }
                }
                $dialog->destroy;
                $dialog->destroy;
 
 
        });
        });
 
 
 
 
 
 
 
 
 
 
 
 
        $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);
 
 
        });
        });
 
 
 
 
        #creat modelsim dir
        #creat modelsim dir
        add_info(\$tview,"creat Modelsim dir in $target_dir\n");
        add_info(\$tview,"creat Modelsim dir in $target_dir\n");
        my $model="$target_dir/Modelsim";
        my $model="$target_dir/Modelsim";
        rmtree("$model");
        rmtree("$model");
        rmtree("$target_dir/rtl_work");
        rmtree("$target_dir/rtl_work");
        mkpath("$model/rtl_work",1,01777);
        mkpath("$model/rtl_work",1,01777);
 
 
        #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
";
";
 
 
#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" );
#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){
                my ($name,$path,$suffix) = fileparse("$p",qr"\..[^.]*$");
                my ($name,$path,$suffix) = fileparse("$p",qr"\..[^.]*$");
                if(check_file_has_string($p,'module')){
                if(check_file_has_string($p,'module')){
                        if ($suffix eq ".sv"){$tcl=$tcl."vlog -sv -work work +incdir+$path \{$p\}\n";}
                        if ($suffix eq ".sv"){$tcl=$tcl."vlog -sv -work work +incdir+$path \{$p\}\n";}
                        else {$tcl=$tcl."vlog -vlog01compat -work work +incdir+$path \{$p\}\n";}
                        else {$tcl=$tcl."vlog -vlog01compat -work work +incdir+$path \{$p\}\n";}
                }
                }
        }
        }
 
 
$tcl="$tcl
$tcl="$tcl
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 run.tcl file\n");
        add_info(\$tview,"Create run.tcl file\n");
        save_file ("$model/run.tcl",$tcl);
        save_file ("$model/run.tcl",$tcl);
        $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->do_save();
                $app->do_save();
                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_bin/vsim -do $model/run.tcl";
                my $cmd="cd $target_dir; $modelsim_bin/vsim -do $model/run.tcl";
 
 
                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 verilator_compilation {
sub verilator_compilation {
        my ($top_ref,$target_dir,$outtext)=@_;
        my ($top_ref,$target_dir,$outtext)=@_;
 
 
        my %tops = %{$top_ref};
        my %tops = %{$top_ref};
        #creat verilator dir
        #creat verilator dir
        add_info(\$outtext,"creat verilator dir in $target_dir\n");
        add_info(\$outtext,"creat verilator dir in $target_dir\n");
        my $verilator="$target_dir/verilator";
        my $verilator="$target_dir/verilator";
        rmtree("$verilator/rtl_work");
        rmtree("$verilator/rtl_work");
        rmtree("$verilator/processed_rtl");
        rmtree("$verilator/processed_rtl");
        mkpath("$verilator/rtl_work/",1,01777);
        mkpath("$verilator/rtl_work/",1,01777);
        mkpath("$verilator/processed_rtl/",1,01777);
        mkpath("$verilator/processed_rtl/",1,01777);
 
 
 
        my @ff = ("$target_dir/src_verilog");
 
        push (@ff,"$target_dir/src_verilator") if (-d "$target_dir/src_verilator");
 
 
 
 
 
 
        #copy all verilog files in rtl_work folder
        #copy all verilog files in rtl_work folder
        add_info(\$outtext,"Copy all verilog files in rtl_work folder\n");
        add_info(\$outtext,"Copy all verilog files in rtl_work folder\n");
        my @files = File::Find::Rule->file()
        my @files = File::Find::Rule->file()
                ->name( '*.v','*.V','*.sv','*.vh')
                ->name( '*.v','*.V','*.sv','*.vh')
                ->in( "$target_dir/src_verilog","$target_dir/src_verilator" );
                ->in( @ff );
        foreach my $file (@files) {
        foreach my $file (@files) {
                copy($file,"$verilator/rtl_work/");
                copy($file,"$verilator/rtl_work/");
        }
        }
 
 
        @files = File::Find::Rule->file()
        @files = File::Find::Rule->file()
                ->name( '*.sv','*.vh' )
                ->name( '*.sv','*.vh' )
            ->in( "$target_dir/src_verilog","$target_dir/src_verilator" );
            ->in( @ff );
        foreach my $file (@files) {
        foreach my $file (@files) {
                copy($file,"$verilator/processed_rtl");
                copy($file,"$verilator/processed_rtl");
        }
        }
 
 
 
 
 
 
        #"split all verilog modules in separate  files"
        #"split all verilog modules in separate  files"
        add_info(\$outtext,"split all verilog modules in separate files\n");
        add_info(\$outtext,"split all verilog modules in separate files\n");
        my $split = Verilog::EditFiles->new
        my $split = Verilog::EditFiles->new
        (outdir => "$verilator/processed_rtl",
        (outdir => "$verilator/processed_rtl",
        translate_synthesis => 0,
        translate_synthesis => 0,
        celldefine => 0,
        celldefine => 0,
        );
        );
        $split->read_and_split(glob("$verilator/rtl_work/*.v"));
        $split->read_and_split(glob("$verilator/rtl_work/*.v"));
        $split->write_files();
        $split->write_files();
        $split->read_and_split(glob("$verilator/rtl_work/*.sv"));
        $split->read_and_split(glob("$verilator/rtl_work/*.sv"));
        $split->write_files();
        $split->write_files();
 
 
 
 
        #run verilator
        #run verilator
        #my $cmd= "cd \"$verilator/processed_rtl\" \n xterm -e sh -c ' verilator  --cc $name.v --profile-cfuncs --prefix \"Vtop\" -O3  -CFLAGS -O3'";
        #my $cmd= "cd \"$verilator/processed_rtl\" \n xterm -e sh -c ' verilator  --cc $name.v --profile-cfuncs --prefix \"Vtop\" -O3  -CFLAGS -O3'";
        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');
                my $cmd= "cd \"$verilator/processed_rtl\" \n  verilator  --cc $tops{$top}  --prefix \"$top\" -O3  -CFLAGS -O3";
                my $cmd= "cd \"$verilator/processed_rtl\" \n  verilator  --cc $tops{$top}  --prefix \"$top\" -O3  -CFLAGS -O3";
                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");
                        add_info(\$outtext,"$stderr\n");
                }else {
                }else {
                        add_info(\$outtext,"$stdout\n");
                        add_info(\$outtext,"$stdout\n");
                }
                }
        }
        }
 
 
 
 
        #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) {
                if (-f "$verilator/processed_rtl/obj_dir/$top.cpp"){#succsess
                if (-f "$verilator/processed_rtl/obj_dir/$top.cpp"){#succsess
 
 
 
 
                }else {
                }else {
                        return 0;
                        return 0;
                }
                }
        }
        }
        #generate makefile
        #generate makefile
        gen_verilator_makefile($top_ref,"$verilator/processed_rtl/obj_dir/Makefile");
        gen_verilator_makefile($top_ref,"$verilator/processed_rtl/obj_dir/Makefile");
        return 1;
        return 1;
}
}
 
 
 
 
sub gen_verilator_makefile{
sub gen_verilator_makefile{
        my ($top_ref,$target_dir) =@_;
        my ($top_ref,$target_dir) =@_;
        my %tops = %{$top_ref};
        my %tops = %{$top_ref};
        my $p='';
        my $p='';
        my $q='';
        my $q='';
        my $h='';
        my $h='';
        my $l;
        my $l;
        my $lib_num=0;
        my $lib_num=0;
        my $all_lib="";
        my $all_lib="";
        foreach my $top (sort keys %tops) {
        foreach my $top (sort keys %tops) {
                $p = "$p ${top}__ALL.a ";
                $p = "$p ${top}__ALL.a ";
                $q = $q."lib$lib_num:\n\t\$(MAKE) -f ${top}.mk\n";
                $q = $q."lib$lib_num:\n\t\$(MAKE) -f ${top}.mk\n";
                $h = "$h ${top}.h ";
                $h = "$h ${top}.h ";
                $l = $top;
                $l = $top;
                $all_lib=$all_lib." lib$lib_num";
                $all_lib=$all_lib." lib$lib_num";
                $lib_num++;
                $lib_num++;
        }
        }
 
 
 
 
        my $make= "
        my $make= "
 
 
default: sim
default: sim
 
 
 
 
 
 
include $l.mk
include $l.mk
 
 
lib: $all_lib
lib: $all_lib
 
 
$q
$q
 
 
 
 
#######################################################################
#######################################################################
# Compile flags
# Compile flags
 
 
CPPFLAGS += -DVL_DEBUG=1
CPPFLAGS += -DVL_DEBUG=1
ifeq (\$(CFG_WITH_CCWARN),yes)  # Local... Else don't burden users
ifeq (\$(CFG_WITH_CCWARN),yes)  # Local... Else don't burden users
CPPFLAGS += -DVL_THREADED=1
CPPFLAGS += -DVL_THREADED=1
CPPFLAGS += -W -Werror -Wall
CPPFLAGS += -W -Werror -Wall
endif
endif
 
 
#######################################################################
#######################################################################
# Linking final exe -- presumes have a sim_main.cpp
# Linking final exe -- presumes have a sim_main.cpp
 
 
 
 
sim:    testbench.o \$(VK_GLOBAL_OBJS) $p
sim:    testbench.o \$(VK_GLOBAL_OBJS) $p
        \$(LINK) \$(LDFLAGS) -g \$^ \$(LOADLIBES) \$(LDLIBS) -o testbench \$(LIBS) -Wall -O3 2>&1 | c++filt
        \$(LINK) \$(LDFLAGS) -g \$^ \$(LOADLIBES) \$(LDLIBS) -o testbench \$(LIBS) -Wall -O3 2>&1 | c++filt
 
 
testbench.o: testbench.cpp $h
testbench.o: testbench.cpp $h
 
 
clean:
clean:
        rm *.o *.a testbench
        rm *.o *.a testbench
";
";
 
 
 
 
 
 
save_file ($target_dir,$make);
save_file ($target_dir,$make);
 
 
 
 
 
 
 
 
}
}
 
 
 
 
 
 
sub verilator_compilation_win {
sub verilator_compilation_win {
        my ($self,$name,$top,$target_dir)=@_;
        my ($self,$name,$top,$target_dir)=@_;
        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_text();
        my ($outbox,$outtext)= create_text();
        add_colors_to_textview($outtext);
 
 
 
        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");
 
        $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);
        $mtable->attach($next,8,9,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);
                verilator_testbench($self,$name,$top,$target_dir);
 
 
        });
        });
 
 
        $window->add ($mtable);
        $window->add ($mtable);
        $window->show_all();
        $window->show_all();
 
 
 
 
        my $result;
        my $result;
 
 
        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 %tops;
                my %tops;
                $tops{"Vtop"}= "$name.v";
                $tops{"Vtop"}= "$name.v";
                $result = verilator_compilation (\%tops,$target_dir,$outtext);
                $result = verilator_compilation (\%tops,$target_dir,$outtext);
                $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);
                $result = gen_mpsoc_verilator_model ($self,$name,$top,$target_dir,$outtext);
 
 
 
 
        }
        }
 
 
 
 
        #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();
 
                $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();
                $next->destroy();
                $next->destroy();
        }
        }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
}
}
 
 
 
 
 
 
 
 
 
 
sub  gen_mpsoc_verilator_model{
sub  gen_mpsoc_verilator_model{
        my ($self,$name,$top,$target_dir,$outtext)=@_;
        my ($self,$name,$top,$target_dir,$outtext)=@_;
        my $dir = Cwd::getcwd();
        my $dir = Cwd::getcwd();
        my $project_dir   = abs_path("$dir/..");
        my $project_dir   = abs_path("$dir/..");
        my $src_verilator_dir="$project_dir/src_verilator";
        my $src_verilator_dir="$project_dir/src_verilator";
        my $sw_dir      = "$target_dir/sw";
        my $target_verilog_dr ="$target_dir/src_verilog";
 
        my $target_verilator_dr ="$target_dir/src_verilator";
 
 
 
        my $sw_dir      = "$target_dir/sw";
 
        my $src_noc_dir="$project_dir/src_noc";
 
        mkpath("$target_verilator_dr",1,01777);
 
 
        #copy src_verilator files
        #copy src_verilator files
        add_info(\$outtext,"Copy verilator files\n");
        my @files_list = File::Find::Rule->file()
        my @files=(
                            ->name( '*.v','*.V','*.sv' )
                "$src_verilator_dir/noc_connection.sv",
                            ->in( "$src_verilator_dir" );
                "$src_verilator_dir/router_verilator.v"
 
        );
        #make sure source files have key word 'module' 
        if (-d "$target_dir/src_verilator/"==0){
        my @files;
                mkpath("$target_dir/src_verilator/",1,01777);
        foreach my $p (@files_list){
 
                push (@files,$p)        if(check_file_has_string($p,'module'));
        }
        }
        copy_file_and_folders (\@files,$project_dir,"$target_dir/src_verilator");
        copy_file_and_folders (\@files,$project_dir,$target_verilator_dr);
 
 
 
 
 
 
 
        #copy src_noc files
 
        #my @files2;
 
        #push (@files2,$src_noc_dir);
 
        #copy_file_and_folders (\@files2,$project_dir,$target_verilog_dr);
 
 
 
 
        #create each tile top module 
        #create each tile top module 
        my $nx= $self->object_get_attribute('noc_param',"NX");
 
    my $ny= $self->object_get_attribute('noc_param',"NY");
 
    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
        /* verilator lint_off WIDTH */
 
        localparam  P=(TOPOLOGY==\"RING\" || TOPOLOGY==\"LINE\")? 3 : 5;
 
        localparam  ROUTE_TYPE = (ROUTE_NAME == \"XY\" || ROUTE_NAME == \"TRANC_XY\" )?    \"DETERMINISTIC\" :
 
                        (ROUTE_NAME == \"DUATO\" || ROUTE_NAME == \"TRANC_DUATO\" )?   \"FULL_ADAPTIVE\": \"PAR_ADAPTIVE\";
 
        /* verilator lint_on WIDTH */
 
        //simulation parameter
        //simulation parameter
 
 
\n \n \`endif" ;
\n \n \`endif" ;
        save_file("$target_dir/src_verilator/parameter.v",$noc_param_v);
        save_file("$target_verilator_dr/parameter.v",$noc_param_v);
 
 
 
 
 
 
   my %tops = (
 
        "Vrouter" => "router_verilator.v",
 
        "Vnoc" => "noc_connection.sv"
 
    );
 
 
 
    for (my $y=0;$y<$ny;$y++){
    my ($nr,$ne,$router_p,$ref_tops)= get_noc_verilator_top_modules_info($self);
                for (my $x=0; $x<$nx;$x++){
    my %tops = %{$ref_tops};
 
 
 
    for (my $tile_num=0;$tile_num<$ne;$tile_num++){
 
 
                my $tile_num= $y*$nx+$x;
 
                #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);
                if(!defined $soc_name){
 
                        #this tile is not connected to any ip. the noc input ports will be connected to ground
 
                                my $soc_v="\n\n // Tile:$tile_num (x=$x,y=$y)   is not assigned to any ip\n";
 
                                $soc_v="$soc_v
 
 
 
        assign ni_credit_out[$tile_num]={V{1'b0}};
 
        assign ni_flit_out[$tile_num]={Fw{1'b0}};
 
        assign ni_flit_out_wr[$tile_num]=1'b0;
 
        ";
 
                next;
 
 
 
                }
 
                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= $y*$nx+$x;
                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 $nocparam =$mpsoc->object_get_attribute('noc_param',undef);
 
                my ($NE, $NR, $RAw, $EAw, $Fw) = get_topology_info($mpsoc);
 
                my %y=%{$nocparam};
 
                $y{'EAw'} = $EAw;
 
                $y{'RAw'} = $RAw;
 
                $y{'Fw'}  = $Fw;
                my @nis=get_NI_instance_list($top);
                my @nis=get_NI_instance_list($top);
                $soc->soc_add_instance_param($nis[0] ,$nocparam );
                $soc->soc_add_instance_param($nis[0] ,\%y );
                my $tile=($nx*$y)+ $x;
 
 
 
 
                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_verilatore ($soc,$sw_path,"tile_$tile",\%params);
                $verilator = $verilator.soc_generate_verilatore ($soc,$sw_path,"tile_$tile",\%params);
                $tops{"Vtile$tile_num"}= "tile_$tile.v";
                $tops{"Vtile$tile_num"}= "tile_$tile.v";
 
 
 
 
        }}
        }
 
 
        save_file ("$target_dir/src_verilator/verilator_tiles.v",$verilator);
        save_file ("$target_verilator_dr/verilator_tiles.v",$verilator);
        my $result = verilator_compilation (\%tops,$target_dir,$outtext);
        my $result = verilator_compilation (\%tops,$target_dir,$outtext);
        $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 @intfcs=$soc_top->top_get_intfc_list();
        my @intfcs=$soc_top->top_get_intfc_list();
        my %PP;
        my %PP;
        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' : '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);
                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";
                }
                }
 
 
 
 
        }
        }
        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>
#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;
/*
/*
$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) {
        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()) {
 
 
                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
 
 
 
 
 
 
                }//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 = eval { do $p };
        my ($soc,$r,$err) = regen_object($p);
        if ($@ || !defined $soc){
        if ($r){
                show_info(\$outtext,"**Error reading  $p file: $@\n");
                show_info(\$outtext,"**Error reading  $p file: $err\n");
               next;
               next;
        }
        }
        return $soc;
        return $soc;
}
}
 
 
 
 
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 $soc_top= $self->soc_get_top ();
        my $parameter_h=gen_noc_param_h($mpsoc);
 
 
 
        my ($nr,$ne,$router_p,$ref_tops,$includ_h)= get_noc_verilator_top_modules_info($mpsoc);
 
        $parameter_h=$parameter_h.$includ_h;
 
 
 
 
        my $nx= $mpsoc->object_get_attribute('noc_param',"NX");
 
    my $ny= $mpsoc->object_get_attribute('noc_param',"NY");
 
 
 
        my $libh="";
        my $libh="";
        my $inst= "";
        my $inst= "";
        my $newinst="";
        my $newinst="";
 
 
        my $tile_x="";
        my $tile_addr="";
        my $tile_y="";
 
        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='';
 
 
        for (my $y=0;$y<$ny;$y++){for (my $x=0; $x<$nx;$x++){
        for (my $endp=0; $endp<$ne;$endp++){
                my $t= $y*$nx+$x;
 
                my ($soc_name,$num)= $mpsoc->mpsoc_get_tile_soc_name($t);
 
                if(defined $soc_name) {#we have a conncted tile
 
 
 
                        #get ni instance name
 
                        my $ni_name;
 
                        my $soc=eval_soc($mpsoc,$soc_name,$tview);
 
                        my $soc_top=$soc->object_get_attribute('top_ip',undef);
 
                        my @intfcs=$soc_top->top_get_intfc_list();
 
                        my @instances=$soc->soc_get_all_instances();
 
                        foreach my $id (@instances){
 
                                        my $category = $soc->soc_get_category($id);
 
                                        if ($category eq 'NoC') {
 
                                                 $ni_name=  $soc->soc_get_instance_name($id);
 
                                        }
 
                        }
 
 
 
 
 
                                $libh=$libh."#include \"Vtile${t}.h\"\n";
 
                                $inst=$inst."Vtile${t}\t*tile${t};\t  // Instantiation of tile${t}\n";
 
                                $newinst = $newinst."\ttile${t}\t=\tnew Vtile${t};\n";
 
                                $tile_flit_in = $tile_flit_in . "\ttile${t}->${ni_name}_flit_in  = noc->ni_flit_out [${t}];\n";
 
                                $tile_flit_in_l = $tile_flit_in_l . "\t\ttile${t}->${ni_name}_flit_in[j]  = noc->ni_flit_out [${t}][j];\n";
 
                                $tile_credit= $tile_credit."\ttile${t}->${ni_name}_credit_in= noc->ni_credit_out[${t}];\n";
 
                                $noc_credit= $noc_credit."\tnoc->ni_credit_in[${t}] = tile${t}->${ni_name}_credit_out;\n";
 
                                $noc_flit_in=$noc_flit_in."\tnoc->ni_flit_in [${t}]  = tile${t}->${ni_name}_flit_out;\n";
 
                                $noc_flit_in_l=$noc_flit_in_l."\t\t\tnoc->ni_flit_in [${t}][j]  = tile${t}->${ni_name}_flit_out[j];\n";
 
                                $noc_flit_in_wr= $noc_flit_in_wr."\tif(tile${t}->${ni_name}_flit_out_wr) noc->ni_flit_in_wr = noc->ni_flit_in_wr | ((vluint64_t)1<<${t});\n";
 
                                $tile_flit_in_wr=$tile_flit_in_wr."\ttile${t}->${ni_name}_flit_in_wr= ((noc->ni_flit_out_wr >> ${t}) & 0x01);\n";
 
                                $noc_flit_in_wr_l= $noc_flit_in_wr_l."\tif(tile${t}->${ni_name}_flit_out_wr) MY_VL_SETBIT_W(noc->ni_flit_in_wr ,${t});\n";
 
                                $tile_flit_in_wr_l=$tile_flit_in_wr_l."\ttile${t}->${ni_name}_flit_in_wr=   (VL_BITISSET_W(noc->ni_flit_out_wr,${t})>0);\n";
 
                                $tile_eval=$tile_eval."\ttile${t}->eval();\n";
 
                                $tile_final=$tile_final."\ttile${t}->final();\n";
 
 
 
 
 
 
                my $e_addr=endp_addr_encoder($mpsoc,$endp);
 
                my $router_num = get_connected_router_id_to_endp($mpsoc,$endp);
 
                my $r_addr=router_addr_encoder($mpsoc,$router_num);
 
 
 
 
 
                my ($soc_name,$num)= $mpsoc->mpsoc_get_tile_soc_name($endp);
 
                if(defined $soc_name) {#we have a conncted tile
 
 
 
                        #get ni instance name
 
                        my $ni_name;
 
                        my $soc=eval_soc($mpsoc,$soc_name,$tview);
 
                        my $soc_top=$soc->object_get_attribute('top_ip',undef);
 
                        my @intfcs=$soc_top->top_get_intfc_list();
 
                        my @instances=$soc->soc_get_all_instances();
 
                        foreach my $id (@instances){
 
                                        my $category = $soc->soc_get_category($id);
 
                                        if ($category eq 'NoC') {
 
                                                 $ni_name=  $soc->soc_get_instance_name($id);
 
                                        }
 
                        }
 
 
 
 
 
                                $libh=$libh."#include \"Vtile${endp}.h\"\n";
 
                                $inst=$inst."Vtile${endp}\t*tile${endp};\t  // Instantiation of tile${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_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";
 
                                $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_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";
 
                                $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";
 
                                $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_final=$tile_final."\ttile${endp}->final();\n";
 
 
 
 
 
                                foreach my $intfc (@intfcs){
 
                                        my $key=($intfc eq 'plug:clk[0]')? 'clk' :
 
                                                         ($intfc eq 'plug:reset[0]')? 'reset':
 
                                                         ($intfc eq 'plug:enable[0]')? 'en' :
 
                                                         'other';
 
 
 
                                        my @ports=$soc_top->top_get_intfc_ports_list($intfc);
 
                                        foreach my $p (@ports){
 
                                                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_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';      ;
 
                                                $top_port_info="$top_port_info $type  $range  tile${endp}->$p \n";
 
                                        }#ports
 
 
 
                                }#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_e_addr=$e_addr;\n";
 
 
 
                        }else{
 
                                #this tile is not connected to any ip. the noc input ports will be connected to ground
 
                                $no_connected=$no_connected."\n // Tile:$endp ($e_addr)   is not assigned to any ip\n";
 
                                $no_connected=$no_connected."\t\tnoc->ni_credit_in[${endp}]=0; \n";
 
 
 
                        }
 
 
                                foreach my $intfc (@intfcs){
 
                                        my $key=($intfc eq 'plug:clk[0]')? 'clk' :
 
                                                         ($intfc eq 'plug:reset[0]')? 'reset':
 
                                                         ($intfc eq 'plug:enable[0]')? 'en' :
 
                                                         'other';
 
 
 
                                        my @ports=$soc_top->top_get_intfc_ports_list($intfc);
 
                                        foreach my $p (@ports){
 
                                                my($inst,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
 
                                                $tile_reset=$tile_reset."\t\ttile${t}->$p=reset;\n" if $key eq 'reset';
 
                                                $tile_clk=$tile_clk."\t\ttile${t}->$p=clk;\n" if $key eq 'clk';
 
                                                $tile_en=$tile_en."\t\ttile${t}->$p=enable;\n" if $key eq 'en'; ;
 
                                                $top_port_info="$top_port_info $type  $range  tile${t}->$p \n";
 
                                        }#ports
 
 
 
                                }#interface
 
 
 
                                $tile_x= $tile_x."\ttile${t}->${ni_name}_current_x=$x;\n";
 
                                $tile_y= $tile_y."\ttile${t}->${ni_name}_current_y=$y;\n";
 
                        }else{
 
                                #this tile is not connected to any ip. the noc input ports will be connected to ground
 
                                $no_connected=$no_connected."\n // Tile:$t (x=$x,y=$y)   is not assigned to any ip\n";
 
                                $no_connected=$no_connected."\t\tnoc->ni_credit_in[${t}]=0; \n";
 
 
 
                        }
 
 
 
 
        }
 
        my $main_c=get_license_header("testbench.cpp");
 
 
        }}
$main_c="$main_c
        my $main_c=get_license_header("testbench.cpp");
 
$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>
#include <verilated.h>          // Defines common routines
#include <verilated.h>          // Defines common routines
 
 
#include \"Vnoc.h\"
#include \"Vnoc.h\"
#include \"Vrouter.h\"
 
$libh
$libh
 
 
 
Vnoc                    *noc;
 
$inst
 
int reset,clk,enable;
 
 
/*
 
$top_port_info
 
*/
 
 
 
 
 
#ifndef  NX
 
        #define  NX     $nx
 
#endif
 
 
 
#ifndef  NY
 
        #define  NY     $ny
 
#endif
 
 
 
#ifndef  NC
 
        #define  NC             ($nx*$ny)
 
#endif
 
 
 
 
#include \"parameter.h\"
 
 
Vrouter                 *router[NC];                     // Instantiation of router
 
Vnoc                    *noc;
 
$inst
 
 
 
 
/*
 
$top_port_info
 
*/
 
 
 
 
int reset,clk,enable;
 
unsigned int main_time = 0; // Current simulation time
unsigned int main_time = 0; // Current simulation time
 
 
void update_all_instances_inputs(void);
void update_all_instances_inputs(void);
 
 
 
 
int main(int argc, char** argv) {
int main(int argc, char** argv) {
        int i,j,x,y;
        int i,j,x,y;
 
 
        Verilated::commandArgs(argc, argv);   // Remember args
        Verilated::commandArgs(argc, argv);   // Remember args
 
        Vrouter_new();             // Create instance
        for(i=0;i<NC;i++)       router[i]       = new Vrouter;             // Create instance
 
        noc                                                             = new Vnoc;
        noc                                                             = new Vnoc;
$newinst
$newinst
 
 
        /********************
        /********************
        *       initialize input
        *       initialize input
        *********************/
        *********************/
 
 
 
 
        reset=1;
        reset=1;
        enable=1;
        enable=1;
        $no_connected
        $no_connected
        for(x=0;x<NX;x++)for(y=0;y<NY;y++){
 
                                        i=(y*NX)+x;
$tile_addr
                                        router[i]->current_x            = x;
 
                                        router[i]->current_y            = y;
 
        }
 
$tile_x
 
$tile_y
 
 
 
        main_time=0;
        main_time=0;
        printf(\"Start Simulation\\n\");
        printf(\"Start Simulation\\n\");
        while (!Verilated::gotFinish()) {
        while (!Verilated::gotFinish()) {
 
 
                if (main_time >= 10 ) {
                if (main_time >= 10 ) {
                        reset=0;
                        reset=0;
                }
                }
 
 
 
 
                if ((main_time % 5) == 0) {
                if ((main_time % 5) == 0) {
                        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
 
 
                }
                }
                else{
                else{
                        clk = 0;       // Toggle clock
                        clk = 0;       // Toggle clock
                        update_all_instances_inputs();
                        update_all_instances_inputs();
 
 
 
 
 
 
                }
                }
 
 
 
 
                //clk,reset,enable
                //clk,reset,enable
                noc-> clk = clk;
                noc-> clk = clk;
                noc-> reset = reset;
                noc-> reset = reset;
$tile_reset
$tile_reset
$tile_clk
$tile_clk
$tile_en
$tile_en
                for(i=0;i<NC;i++){
 
                        router[i]->reset= reset;
        connect_routers_reset_clk();
                        router[i]->clk= clk;
 
                }
 
 
 
                //eval instances
                //eval instances
                noc->eval();
                noc->eval();
                for(i=0;i<NC;i++) {
                routers_eval();
                                router[i]->eval();
 
                }
 
$tile_eval
$tile_eval
 
 
 
 
                main_time++;
                main_time++;
 
 
 
 
 
 
        }//while
        }//while
 
 
        // Simulation is dne
        // Simulation is done
        for(i=0;i<NC;i++) {
        routers_final();
                router[i]->final();
 
        }
 
        noc->final();
        noc->final();
$tile_final
$tile_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;
}
}
 
 
 
 
void update_all_instances_inputs(void){
void update_all_instances_inputs(void){
 
 
        int x,y,i,j;
        int x,y,i,j;
        int flit_out_all_size = sizeof(router[0]->flit_out_all)/sizeof(router[0]->flit_out_all[0]);
 
 
 
#if (NC<=64)
#if (NC<=64)
        noc->ni_flit_in_wr =0;
        noc->ni_flit_in_wr =0;
#else
#else
        for(j=0;j<(sizeof(noc->ni_flit_in_wr)/sizeof(noc->ni_flit_in_wr[0])); j++) noc->ni_flit_in_wr[j]=0;
        for(j=0;j<(sizeof(noc->ni_flit_in_wr)/sizeof(noc->ni_flit_in_wr[0])); j++) noc->ni_flit_in_wr[j]=0;
#endif
#endif
        for(x=0;x<NX;x++)for(y=0;y<NY;y++){
 
                i=(y*NX)+x;
 
                router[i]->flit_in_we_all = noc->router_flit_out_we_all[i];
 
                router[i]->credit_in_all = noc->router_credit_out_all[i];
 
                router[i]->congestion_in_all = noc->router_congestion_out_all[i];
 
                for(j=0;j<flit_out_all_size;j++) router[i]->flit_in_all[j]      = noc->router_flit_out_all[i][j];
 
                noc->router_flit_in_we_all[i] = router[i]->flit_out_we_all ;
 
                noc->router_credit_in_all[i]    =       router[i]->credit_out_all;
 
                noc->router_congestion_in_all[i]=       router[i]->congestion_out_all;
 
                for(j=0;j<flit_out_all_size;j++) noc->router_flit_in_all[i][j]  = router[i]->flit_out_all[j] ;
 
        }       //for
 
 
 
 
 
 
        connect_all_routers_to_noc ();
 
 
 
 
#if (Fpay<=32)
#if (Fpay<=32)
        //tile[i]->flit_in  = noc->ni_flit_out [i];
        //tile[i]->flit_in  = noc->ni_flit_out [i];
$tile_flit_in
$tile_flit_in
#else
#else
        for(j=0;j<(sizeof(traffic[i]->flit_out)/sizeof(traffic[i]->flit_out[0])); j++){
        for(j=0;j<(sizeof(traffic[i]->flit_out)/sizeof(traffic[i]->flit_out[0])); j++){
                //traffic[i]->flit_in[j]  = noc->ni_flit_out [i][j];
                //traffic[i]->flit_in[j]  = noc->ni_flit_out [i][j];
$tile_flit_in_l
$tile_flit_in_l
        }
        }
#endif
#endif
 
 
        //traffic[i]->credit_in= noc->ni_credit_out[i];
        //traffic[i]->credit_in= noc->ni_credit_out[i];
$tile_credit
$tile_credit
 
 
        //noc->ni_credit_in[i] = traffic[i]->credit_out;
        //noc->ni_credit_in[i] = traffic[i]->credit_out;
$noc_credit
$noc_credit
 
 
#if (Fpay<=32)
#if (Fpay<=32)
        //noc->ni_flit_in [i]  = traffic[i]->flit_out;
        //noc->ni_flit_in [i]  = traffic[i]->flit_out;
$noc_flit_in
$noc_flit_in
 
 
#else
#else
        for(j=0;j<(sizeof(traffic[i]->flit_out)/sizeof(traffic[i]->flit_out[0])); j++){
        for(j=0;j<(sizeof(traffic[i]->flit_out)/sizeof(traffic[i]->flit_out[0])); j++){
                 //noc->ni_flit_in [i][j]  = traffic[i]->flit_out[j];
                 //noc->ni_flit_in [i][j]  = traffic[i]->flit_out[j];
$noc_flit_in_l
$noc_flit_in_l
        }
        }
#endif
#endif
 
 
 
 
#if (NC<=64)
#if (NC<=64)
                //if(traffic[i]->flit_out_wr) noc->ni_flit_in_wr = noc->ni_flit_in_wr | ((vluint64_t)1<<i);
                //if(traffic[i]->flit_out_wr) noc->ni_flit_in_wr = noc->ni_flit_in_wr | ((vluint64_t)1<<i);
$noc_flit_in_wr
$noc_flit_in_wr
 
 
                //traffic[i]->flit_in_wr= ((noc->ni_flit_out_wr >> i) & 0x01);
                //traffic[i]->flit_in_wr= ((noc->ni_flit_out_wr >> i) & 0x01);
$tile_flit_in_wr
$tile_flit_in_wr
#else
#else
                //if(traffic[i]->flit_out_wr) MY_VL_SETBIT_W(noc->ni_flit_in_wr ,i);
                //if(traffic[i]->flit_out_wr) MY_VL_SETBIT_W(noc->ni_flit_in_wr ,i);
$noc_flit_in_wr_l
$noc_flit_in_wr_l
 
 
                //traffic[i]->flit_in_wr=   (VL_BITISSET_W(noc->ni_flit_out_wr,i)>0);
                //traffic[i]->flit_in_wr=   (VL_BITISSET_W(noc->ni_flit_out_wr,i)>0);
$tile_flit_in_wr_l
$tile_flit_in_wr_l
 
 
#endif
#endif
 
 
 
 
 
 
}
}
";
";
 
 
        save_file("$dir/testbench.cpp",$main_c);
 
 
 
}
 
 
 
 
 
 
 
sub soc_get_all_parameters {
 
        my $soc=shift;
 
        my @instances=$soc->soc_get_all_instances();
 
 
 
        my %all_param;
 
        foreach my $id (@instances){
 
 
 
                my $module      =$soc->soc_get_module($id);
 
                my $category    =$soc->soc_get_category($id);
 
                my $inst        = $soc->soc_get_instance_name($id);
 
                my %params      = $soc->soc_get_module_param($id);
 
                my $ip = ip->lib_new ();
 
                my @param_order=$soc->soc_get_instance_param_order($id);
 
 
 
                foreach my $p (sort keys %params){
 
                        my $inst_param= "$inst\_$p";
 
                        #add instance name to parameter value
 
                        $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);
 
                        $vfile_param_type= "Don't include" if (!defined $vfile_param_type );
 
                        $vfile_param_type= "Parameter"  if ($vfile_param_type eq 1);
 
                        $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"  );
 
                        print"$all_param{ $inst_param} =        $params{ $p} if($vfile_param_type eq \"Parameter\" || $vfile_param_type eq \"Localparam\"  );   \n";
 
                }
 
        }
 
        return %all_param;
 
}
 
 
 
sub soc_get_all_parameters_order {
 
        my $soc=shift;
 
        my @instances=$soc->soc_get_all_instances();
 
        my $ip = ip->lib_new ();
 
        my @all_order;
 
        foreach my $id (@instances){
 
                my $module      =$soc->soc_get_module($id);
 
                my $category    =$soc->soc_get_category($id);
 
                my $inst        = $soc->soc_get_instance_name($id);
 
                my @order       = $soc->soc_get_instance_param_order($id);
 
 
 
                foreach my $p ( @order){
 
                        my $inst_param= "$inst\_$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= "Parameter"  if ($vfile_param_type eq 1);
 
                        $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"  );
 
                }
 
        }
 
        return @all_order;
 
}
 
 
 
 
        save_file("$dir/parameter.h",$parameter_h);
 
        save_file("$dir/testbench.cpp",$main_c);
 
 
 
}
 
 
sub gen_modelsim_soc_testbench {
 
        my ($self,$name,$top,$target_dir)=@_;
 
        my $dir="$target_dir/src_verilog";
 
        my $soc_top= $self->object_get_attribute('top_ip',undef);
 
        my @intfcs=$soc_top->top_get_intfc_list();
 
        my %PP;
 
        my $top_port_def="// ${name}.v IO definition \n";
 
        my $pin_assign;
 
        my $rst_inputs='';
 
 
 
 
 
 
sub soc_get_all_parameters {
 
        my $soc=shift;
 
        my @instances=$soc->soc_get_all_instances();
 
 
 
        my %all_param;
 
        foreach my $id (@instances){
 
 
 
                my $module      =$soc->soc_get_module($id);
 
                my $category    =$soc->soc_get_category($id);
 
                my $inst        = $soc->soc_get_instance_name($id);
 
                my %params      = $soc->soc_get_module_param($id);
 
                my $ip = ip->lib_new ();
 
                my @param_order=$soc->soc_get_instance_param_order($id);
 
 
 
                foreach my $p (sort keys %params){
 
                        my $inst_param= "$inst\_$p";
 
                        #add instance name to parameter value
 
                        $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);
 
                        $vfile_param_type= "Don't include" if (!defined $vfile_param_type );
 
                        $vfile_param_type= "Parameter"  if ($vfile_param_type eq 1);
 
                        $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"  );
 
                        #print"$all_param{ $inst_param} =       $params{ $p} if($vfile_param_type eq \"Parameter\" || $vfile_param_type eq \"Localparam\"  );   \n";
 
                }
 
        }
 
        return %all_param;
 
}
 
 
 
sub soc_get_all_parameters_order {
 
        my $soc=shift;
 
        my @instances=$soc->soc_get_all_instances();
 
        my $ip = ip->lib_new ();
 
        my @all_order;
 
        foreach my $id (@instances){
 
                my $module      =$soc->soc_get_module($id);
 
                my $category    =$soc->soc_get_category($id);
 
                my $inst        = $soc->soc_get_instance_name($id);
 
                my @order       = $soc->soc_get_instance_param_order($id);
 
 
 
                foreach my $p ( @order){
 
                        my $inst_param= "$inst\_$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= "Parameter"  if ($vfile_param_type eq 1);
 
                        $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"  );
 
                }
 
        }
 
        return @all_order;
 
}
 
 
        #add functions
 
        my $d = Cwd::getcwd();
 
        open my $file1, "<", "$d/lib/verilog/functions.v" or die;
 
        my $functions_all='';
 
        while (my $f1 = readline ($file1)) {
 
                 $functions_all="$functions_all $f1 ";
 
        }
 
        close($file1);
 
 
 
        #get parameters
 
        my $params_v="";
 
        my $n= $self->object_get_attribute('soc_name',undef);
 
 
 
        if(defined $n){ #we are compiling a single tile as SoC
sub gen_modelsim_soc_testbench {
                my $core_id= $self->object_get_attribute('global_param','CORE_ID');
        my ($self,$name,$top,$target_dir)=@_;
                my $sw_loc = $self->object_get_attribute('global_param','SW_LOC');
        my $dir="$target_dir/src_verilog";
 
        my $soc_top= $self->object_get_attribute('top_ip',undef);
 
        my @intfcs=$soc_top->top_get_intfc_list();
 
        my %PP;
 
        my $top_port_def="// ${name}.v IO definition \n";
 
        my $pin_assign;
 
        my $rst_inputs='';
 
 
                        $params_v="\tlocalparam\tCORE_ID=$core_id;
 
\tlocalparam\tSW_LOC=\"$sw_loc\";\n";
 
                my %params=soc_get_all_parameters($self);
 
                my @order= soc_get_all_parameters_order($self);
 
                foreach my $p (@order){
 
                        add_text_to_string(\$params_v,"\tlocalparam  $p = $params{$p};\n") if(defined $params{$p} );
 
                }
 
        }else{ # we are simulating a mpsoc
 
                $params_v= gen_socs_param($self);
 
 
 
 
 
        }
 
 
 
        foreach my $intfc (@intfcs){
        #add functions
                my $key= ( $intfc eq 'plug:clk[0]')? 'clk' :
        my $d = Cwd::getcwd();
                         ( $intfc eq 'plug:reset[0]')? 'reset':
        open my $file1, "<", "$d/lib/verilog/functions.v" or die;
                         ( $intfc eq 'plug:enable[0]')? 'en' : 'other';
        my $functions_all='';
                my $key1="${key}1";
        while (my $f1 = readline ($file1)) {
                my $key0="${key}0";
                 $functions_all="$functions_all $f1 ";
 
        }
 
        close($file1);
 
 
                my @ports=$soc_top->top_get_intfc_ports_list($intfc);
        #get parameters
                my $f=1;
        my $params_v="";
                foreach my $p (@ports){
        my $n= $self->object_get_attribute('soc_name',undef);
                        my($inst,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
 
 
        if(defined $n){ #we are compiling a single tile as SoC
 
                my $core_id= $self->object_get_attribute('global_param','CORE_ID');
 
                my $sw_loc = $self->object_get_attribute('global_param','SW_LOC');
 
 
 
                        $params_v="\tlocalparam\tCORE_ID=$core_id;
 
\tlocalparam\tSW_LOC=\"$sw_loc\";\n";
 
                my %params=soc_get_all_parameters($self);
 
                my @order= soc_get_all_parameters_order($self);
 
                foreach my $p (@order){
 
                        add_text_to_string(\$params_v,"\tlocalparam  $p = $params{$p};\n") if(defined $params{$p} );
 
                }
 
        }else{ # we are simulating a mpsoc
 
                $params_v= gen_socs_param($self);
 
 
                        $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";
 
 
 
 
        }
 
 
                        if  (length($range)!=0){
        foreach my $intfc (@intfcs){
#                               #replace parameter with their values            #
                my $key= ( $intfc eq 'plug:clk[0]')? 'clk' :
#                               my @a= split (/\b/,$range);
                         ( $intfc eq 'plug:reset[0]')? 'reset':
#                               print "a=@a\n";
                         ( $intfc eq 'plug:enable[0]')? 'en' : 'other';
#                               foreach my $l (@a){
                my $key1="${key}1";
#                                       my $value=$params{$l};
                my $key0="${key}0";
#                                       if(defined $value){
 
#                                               chomp $value;
                my @ports=$soc_top->top_get_intfc_ports_list($intfc);
#                                               ($range=$range)=~ s/\b$l\b/$value/g      if(defined $params{$l});
                my $f=1;
#                                               print "($range=$range)=~ s/\b$l\b/$value/g      if(defined $params{$l}); \n";
                foreach my $p (@ports){
#                                       }
                        my($inst,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
#                               }
 
                                $range = "[ $range ]" ;
                        $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";
 
 
 
 
 
                        if  (length($range)!=0){
 
#                               #replace parameter with their values            #
 
#                               my @a= split (/\b/,$range);
 
#                               print "a=@a\n";
 
#                               foreach my $l (@a){
 
#                                       my $value=$params{$l};
 
#                                       if(defined $value){
 
#                                               chomp $value;
 
#                                               ($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";
 
#                                       }
 
#                               }
 
                                $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 $test_v= get_license_header("testbench.v");
my $test_v= get_license_header("testbench.v");
 
 
$test_v ="$test_v
$test_v ="$test_v
 
 
`timescale       1ns/1ps
`timescale       1ns/1ps
 
 
module testbench;
module testbench;
 
 
$functions_all
$functions_all
 
 
$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{
 
        my ($self,$name,$top,$target_dir)=@_;
 
        my $verilator="$target_dir/verilator";
 
        my $dir="$verilator";
 
 
 
        my ($app,$table,$tview,$window) = software_main($dir,'testbench.cpp');
 
 
 
        my $n= $self->object_get_attribute('soc_name',undef);
 
        if(defined $n){ #we are compiling a single tile as SoC
 
                gen_verilator_soc_testbench (@_) if((-f "$dir/testbench.cpp")==0);
 
        }
 
        else { # we are compiling a complete NoC-based mpsoc
 
                gen_verilator_mpsoc_testbench (@_,$tview) if((-f "$dir/testbench.cpp")==0);
 
 
 
        }
 
 
 
        #copy makefile
}
        #copy("../script/verilator_soc_make", "$verilator/processed_rtl/obj_dir/Makefile"); 
 
 
 
 
sub verilator_testbench{
 
        my ($self,$name,$top,$target_dir)=@_;
 
        my $verilator="$target_dir/verilator";
 
        my $dir="$verilator";
 
 
 
        my ($app,$table,$tview,$window) = software_main($dir,'testbench.cpp');
 
 
 
        my $n= $self->object_get_attribute('soc_name',undef);
 
        if(defined $n){ #we are compiling a single tile as SoC
 
                gen_verilator_soc_testbench (@_) if((-f "$dir/testbench.cpp")==0);
 
        }
 
        else { # we are compiling a complete NoC-based mpsoc
 
                gen_verilator_mpsoc_testbench (@_,$tview) if((-f "$dir/testbench.cpp")==0);
 
 
 
        }
 
 
 
        #copy makefile
 
        #copy("../script/verilator_soc_make", "$verilator/processed_rtl/obj_dir/Makefile");
 
 
 
 
        my $make = def_image_button('icons/gen.png','Compile');
 
        my $regen=def_image_button('icons/refresh.png','Regenerate Testbench.cpp');
 
        my $run = def_image_button('icons/run.png','Run');
 
        my $back=def_image_button('icons/left.png','Previous');
 
 
 
        $table->attach ($back,1,2,1,2,'shrink','shrink',0,0);
 
        $table->attach ($regen,3,4,1,2,'shrink','shrink',0,0);
 
        $table->attach ($make,7, 8, 1,2,'shrink','shrink',0,0);
 
        $table->attach ($run,9, 10, 1,2,'shrink','shrink',0,0);
 
 
 
        $back-> signal_connect("clicked" => sub{
 
 
 
                $window->destroy;
        my $make = def_image_button('icons/gen.png','Compile');
                verilator_compilation_win($self,$name,$top,$target_dir);
        my $regen=def_image_button('icons/refresh.png','Regenerate Testbench.cpp');
 
        my $run = def_image_button('icons/run.png','Run');
 
        my $back=def_image_button('icons/left.png','Previous');
 
 
        });
 
 
 
        $regen-> signal_connect("clicked" => sub{
 
                my $dialog = Gtk2::MessageDialog->new (my $window,
 
                                      'destroy-with-parent',
 
                                      'question', # message type
 
                                      'yes-no', # which set of buttons?
 
                                      "Are you sure you want to regenaret the testbench.cpp file? Note that any changes you have made will be lost");
 
                my $response = $dialog->run;
 
                if ($response eq 'yes') {
 
                        my $n= $self->object_get_attribute('soc_name',undef);
 
                        if(defined $n){ #we are compiling a single tile as SoC
 
                                gen_verilator_soc_testbench ($self,$name,$top,$target_dir);
 
                        }
 
                        else { # we are compiling a complete NoC-based mpsoc
 
                                gen_verilator_mpsoc_testbench ($self,$name,$top,$target_dir,$tview);
 
 
 
                        }
        $table->attach ($back,1,2,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 ($run,9, 10, 1,2,'shrink','shrink',0,0);
 
 
                        $app->load_source("$dir/testbench.cpp");
        $back-> signal_connect("clicked" => sub{
                }
 
                $dialog->destroy;
 
 
 
        });
                $window->destroy;
 
                verilator_compilation_win($self,$name,$top,$target_dir);
 
 
 
        });
 
 
        $make -> signal_connect("clicked" => sub{
        $regen-> signal_connect("clicked" => sub{
                $app->do_save();
                my $dialog = Gtk2::MessageDialog->new (my $window,
                copy("$dir/testbench.cpp", "$verilator/processed_rtl/obj_dir/testbench.cpp");
                                      'destroy-with-parent',
 
                                      'question', # message type
 
                                      'yes-no', # which set of buttons?
 
                                      "Are you sure you want to regenaret the testbench.cpp file? Note that any changes you have made will be lost");
 
                my $response = $dialog->run;
 
                if ($response eq 'yes') {
 
                        my $n= $self->object_get_attribute('soc_name',undef);
 
                        if(defined $n){ #we are compiling a single tile as SoC
 
                                gen_verilator_soc_testbench ($self,$name,$top,$target_dir);
 
                        }
 
                        else { # we are compiling a complete NoC-based mpsoc
 
                                gen_verilator_mpsoc_testbench ($self,$name,$top,$target_dir,$tview);
 
 
                my $tops_ref=$self->object_get_attribute('verilator','libs');
                        }
                my %tops=%{$tops_ref};
 
                my $lib_num=0;
 
 
 
                foreach my $top (sort keys %tops) {
                        $app->load_source("$dir/testbench.cpp");
                                run_make_file("$verilator/processed_rtl/obj_dir/",$tview,"lib$lib_num");
                }
                                $lib_num++;
                $dialog->destroy;
                }
 
                run_make_file("$verilator/processed_rtl/obj_dir/",$tview,"sim");
 
 
 
        });
        });
 
 
        $run -> signal_connect("clicked" => sub{
 
                my $bin="$verilator/processed_rtl/obj_dir/testbench";
 
                if (-f $bin){
 
                        my $cmd= "cd \"$verilator/processed_rtl/obj_dir/\" \n xterm -e sh -c $bin";
 
                        add_info(\$tview,"$cmd\n");
 
                        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
 
                        if(length $stderr>1){
 
                                add_colored_info(\$tview,"$stderr\n",'red');
 
                        }else {
 
                                add_info(\$tview,"$stdout\n");
 
                        }
 
 
 
                }else{
        $make -> signal_connect("clicked" => sub{
                        add_colored_info(\$tview,"Cannot find $bin executable binary file! make sure you have compiled the testbench successfully\n", 'red')
                $make->hide_all;
                }
                my $load= show_gif("icons/load.gif");
 
                $table->attach ($load,8, 9, 1,2,'shrink','shrink',0,0);
 
                $table->show_all;
 
                $app->do_save();
 
                copy("$dir/testbench.cpp", "$verilator/processed_rtl/obj_dir/testbench.cpp");
 
                copy("$dir/parameter.h", "$verilator/processed_rtl/obj_dir/parameter.h") if(-f "$dir/parameter.h");
 
 
 
                my $tops_ref=$self->object_get_attribute('verilator','libs');
 
                my %tops=%{$tops_ref};
 
                my $lib_num=0;
 
 
 
                foreach my $top (sort keys %tops) {
 
                                run_make_file("$verilator/processed_rtl/obj_dir/",$tview,"lib$lib_num");
 
                                $lib_num++;
 
                }
 
                run_make_file("$verilator/processed_rtl/obj_dir/",$tview,"sim");
 
                $load->destroy;
 
                $make->show_all;
 
 
 
        });
 
 
 
        $run -> signal_connect("clicked" => sub{
 
                my $bin="$verilator/processed_rtl/obj_dir/testbench";
 
                if (-f $bin){
 
                        my $cmd= "cd \"$verilator/processed_rtl/obj_dir/\" \n xterm -e sh -c $bin";
 
                        add_info(\$tview,"$cmd\n");
 
                        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
 
                        if(length $stderr>1){
 
                                add_colored_info(\$tview,"$stderr\n",'red');
 
                        }else {
 
                                add_info(\$tview,"$stdout\n");
 
                        }
 
 
                });
                }else{
 
                        add_colored_info(\$tview,"Cannot find $bin executable binary file! make sure you have compiled the testbench successfully\n", 'red')
 
                }
 
 
 
                });
 
 
}
 
 
 
 
}
 
 
1;
 
 
 
 No newline at end of file
 No newline at end of file
 
1;
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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