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 45 and 48

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 45 Rev 48
Line 1... Line 1...
#! /usr/bin/perl -w
#! /usr/bin/perl -w
use Glib qw/TRUE FALSE/;
use constant::boolean;
use strict;
use strict;
use warnings;
use warnings;
 
 
use FindBin;
use FindBin;
use lib $FindBin::Bin;
use lib $FindBin::Bin;
Line 14... Line 14...
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 List::MoreUtils qw( minmax );
use List::MoreUtils qw( minmax );
 
 
 
 
 
 
################
################
#       Comile
#       Compile
#################
#################
 
 
 
 
 
 
sub is_capital_sensitive()
sub is_capital_sensitive()
Line 33... Line 33...
  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{
 
        my $ref=shift;
 
        my %inputs=%{$ref};
 
        my $store = Gtk2::TreeStore->new('Glib::String');
 
         for my $i (sort { $a cmp $b} keys %inputs ) {
 
                my $iter = $store->append(undef);
 
 
 
                $store->set($iter, 0, $i);
 
                for my $capital (sort { $a cmp $b} keys %{$inputs{$i}}) {
 
                        my $iter2 = $store->append($iter);
 
                        $store->set($iter2, 0, $capital);
 
                }
 
        }
 
        return $store;
 
 
 
}
 
 
 
sub gen_tree_combo{
 
        my $model=shift;
 
        my $combo = Gtk2::ComboBox->new_with_model($model);
 
        my $renderer = Gtk2::CellRendererText->new();
 
        $combo->pack_start($renderer, TRUE);
 
        $combo->set_attributes($renderer, "text", 0);
 
        $combo->set_cell_data_func($renderer, \&is_capital_sensitive);
 
        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);
Line 203... Line 177...
 
 
 
 
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
 
        my @dirs = grep {-d} glob("../boards/*");
 
        my ($fpgas,$init);
 
        foreach my $dir (@dirs) {
 
                my ($name,$path,$suffix) = fileparse("$dir",qr"\..[^.]*$");
 
                $init=$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,Vivado,Verilator,Modelsim"
 
 
        my $compiler=gen_combobox_object ($self,'compile','type',$compilers,"QuartusII",undef,undef);
        my $compiler=gen_combobox_object ($self,'compile','type',$compilers,"QuartusII",undef,undef);
        $table->attach(gen_label_in_center("Compiler tool"),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
        $table->attach(gen_label_in_center("Compiler tool"),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
        $table->attach($compiler,$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
        $table->attach($compiler,$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
        $row++;$col=0;
        $row++;$col=0;
 
 
 
 
 
 
        my $old_board_name=$self->object_get_attribute('compile','board');
        my $old_board_name=$self->object_get_attribute('compile','board');
        my $old_compiler=$self->object_get_attribute('compile','type');
        my $old_compiler=$self->object_get_attribute('compile','type');
        my $compiler_options = ($old_compiler eq "QuartusII")? select_board  ($self,$name,$top,$target_dir):
        my $vendor= ($old_compiler eq "QuartusII")? 'Altera' : 'Xilinx';
 
 
 
        #get the list of boards located in "boards/*" folder
 
        my @dirs = grep {-d} glob("../boards/$vendor/*");
 
        my ($fpgas,$init);
 
        foreach my $dir (@dirs) {
 
                my ($name,$path,$suffix) = fileparse("$dir",qr"\..[^.]*$");
 
                $init=$name;
 
                $fpgas= (defined $fpgas)? "$fpgas,$name" : "$name";
 
        }
 
 
 
 
 
        my $compiler_options =
 
                ($old_compiler eq "QuartusII")? select_board  ($self,$name,$top,$target_dir,$vendor):
 
                ($old_compiler eq "Vivado"   )? select_board  ($self,$name,$top,$target_dir,$vendor):
                               ($old_compiler eq "Modelsim")?  select_model_path  ($self,$name,$top,$target_dir):
                               ($old_compiler eq "Modelsim")?  select_model_path  ($self,$name,$top,$target_dir):
 
                ($old_compiler eq "Verilator")? select_parallel_process_num ($self,$name,$top,$target_dir):
                                                                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++){
Line 243... Line 224...
        $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',FALSE,1);
        $table->attach($next,$col,$col+1,$row,$row+1,'shrink','shrink',2,2);$col++;
        $table->attach($next,$col,$col+1,$row,$row+1,'shrink','shrink',2,2);$col++;
        $next-> signal_connect("clicked" => sub{
        $next-> signal_connect("clicked" => sub{
                my $compiler_type=$self->object_get_attribute('compile','type');
                my $compiler_type=$self->object_get_attribute('compile','type');
                if($compiler_type eq "QuartusII"){
                if($compiler_type eq "QuartusII" || $compiler_type eq "Vivado"){
 
                        $vendor= ($compiler_type eq "QuartusII")? 'Altera' : 'Xilinx';
                        my $new_board_name=$self->object_get_attribute('compile','board');
                        my $new_board_name=$self->object_get_attribute('compile','board');
                        if(defined $old_board_name) {
                        if(defined $old_board_name) {
                                if ($old_board_name ne $new_board_name){
                                if ($old_board_name ne $new_board_name){
                                        remove_pin_assignment($self);
                                        remove_pin_assignment($self);
                                        my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
                                        my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
Line 265... Line 247...
                                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,$vendor);}
                        else {get_pin_assignment($self,$name,$top,$target_dir,$end_func);}
                        else {get_pin_assignment($self,$name,$top,$target_dir,$end_func,$vendor);}
                }elsif($compiler_type eq "Modelsim"){
                }
                        modelsim_compilation($self,$name,$top,$target_dir);
 
 
 
 
 
 
 
 
 
 
 
 
                elsif($compiler_type eq "Modelsim"){
 
                        modelsim_compilation($self,$name,$top,$target_dir,$vendor);
 
 
                }else{#verilator
                }else{#verilator
                        verilator_compilation_win($self,$name,$top,$target_dir);
                        verilator_compilation_win($self,$name,$top,$target_dir,$vendor);
 
 
                }
                }
 
 
                $window->destroy;
                $window->destroy;
 
 
        });
        });
 
 
        $compiler->signal_connect("changed" => sub{
        $compiler->signal_connect("changed" => sub{
                $compiler_options->destroy;
                $compiler_options->destroy;
                my $new_board_name=$self->object_get_attribute('compile','type');
                my $new_board_name=$self->object_get_attribute('compile','type');
                $compiler_options = ($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,"Altera"):
 
                        ($new_board_name eq "Vivado")? select_board  ($self,$name,$top,$target_dir,"Xilinx"):
                                    ($new_board_name eq "Modelsim")?  select_model_path  ($self,$name,$top,$target_dir):
                                    ($new_board_name eq "Modelsim")?  select_model_path  ($self,$name,$top,$target_dir):
 
                        ($new_board_name eq "Verilator")? select_parallel_process_num ($self,$name,$top,$target_dir):
                                 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;
 
 
        });
        });
Line 296... Line 288...
 
 
 
 
 
 
 
 
 
 
 
 
sub select_board {
sub select_board {
        my ($self,$name,$top,$target_dir)=@_;
        my ($self,$name,$top,$target_dir,$vendor)=@_;
 
 
        #get the list of boards located in "boards/*" folder
        #get the list of boards located in "boards/*" folder
        my @dirs = grep {-d} glob("../boards/*");
        my @dirs = grep {-d} glob("../boards/$vendor/*");
        my ($fpgas,$init);
        my ($fpgas,$init);
        $fpgas="Add New Board";
        $fpgas="Add New Board";
 
 
        foreach my $dir (@dirs) {
        foreach my $dir (@dirs) {
                my ($name,$path,$suffix) = fileparse("$dir",qr"\..[^.]*$");
                my ($name,$path,$suffix) = fileparse("$dir",qr"\..[^.]*$");
Line 313... Line 306...
                $init="$name";
                $init="$name";
        }
        }
        my $table = def_table(2, 2, FALSE);
        my $table = def_table(2, 2, FALSE);
        my $col=0;
        my $col=0;
        my $row=0;
        my $row=0;
 
    my $compiler = ($vendor eq "Altera")? 'quartus' : 'vivado';
 
    my $bin_name = "$compiler bin";
 
    my $env = ($vendor eq "Altera")? "QUARTUS_BIN" : "VIVADO_BIN";
 
        my $Fpga_bin=   $ENV{$env};
 
 
        my $old_board_name=$self->object_get_attribute('compile','board');
        my $old_board_name=$self->object_get_attribute('compile','board');
        $table->attach(gen_label_help("The list of supported boards are obtained from \"mpsoc/boards/\" 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/$vendor\" path. You can add your boards by adding its required files in aformentioned path. Note that currently Altera and Xilinx FPGAs are supported.",'Targeted Board:'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
        $table->attach(gen_combobox_object ($self,'compile','board',$fpgas,$init,undef,undef),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$row++;
        $table->attach(gen_combobox_object ($self,'compile','board',$fpgas,$init,undef,undef),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$row++;
 
        my $bin =  $self->object_get_attribute('compile',$bin_name);
 
 
        my $bin = $self->object_get_attribute('compile','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',$bin_name,$Fpga_bin) if (!defined $bin && defined $Fpga_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 $vendor/bin directory. You can set a default path as $env environment 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 $env=/home/alireza/$compiler/bin","$env:"),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
        $table->attach(get_dir_in_object ($self,'compile','quartus_bin',undef,undef,undef),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$row++;
        $table->attach(get_dir_in_object ($self,'compile',$bin_name,undef,undef,undef),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$row++;
 
 
 
 
 
 
 
 
 
 
        return $table;
        return $table;
 
 
}
}
 
 
 
 
 
 
 
 
sub select_model_path {
sub select_model_path {
        my ($self,$name,$top,$target_dir)=@_;
        my ($self,$name,$top,$target_dir)=@_;
 
 
 
 
        my $table = def_table(2, 2, FALSE);
        my $table = def_table(2, 2, FALSE);
Line 346... Line 348...
 
 
        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 environment variable in ~/.bashrc file.
e.g.  export MODELSIM_BIN=/home/alireza/altera/modeltech/bin",'Modelsim  bin:'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
e.g.  export MODELSIM_BIN=/home/alireza/altera/modeltech/bin",'Modelsim  bin:'),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$col++;
        $table->attach(get_dir_in_object ($self,'compile','modelsim_bin',undef,undef,undef),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$row++;
        $table->attach(get_dir_in_object ($self,'compile','modelsim_bin',undef,undef,undef),$col,$col+1,$row,$row+1,'fill','shrink',2,2);$row++;
 
 
        return $table;
        return $table;
 
 
}
}
 
 
 
 
 
sub select_parallel_process_num {
 
        my ($self,$name,$top,$target_dir)=@_;
 
        my $table = def_table(2, 2, FALSE);
 
        my $col=0;
 
        my $row=0;
 
 
 
        #get total number of processor in the system
 
        my $cmd = "nproc\n";
 
        my $cpu_num=4;
 
        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
 
        if(length $stderr>1){
 
                #nproc command has failed. set default 4 paralel processor
 
 
 
        }else {
 
                 my ($number ) = $stdout =~ /(\d+)/;
 
                 if (defined  $number ){
 
                        $cpu_num =$number if  ($number > 0 );
 
                 }
 
        }
 
        ($row,$col)= add_param_widget ($self,"Paralle run:" , "cpu_num", 1, 'Spin-button', "1,$cpu_num,1","specify the number of processors the Verilator can use at once to run parallel compilations/simulations", $table,$row,$col,1, 'compile', undef,undef,'vertical');
 
        return $table;
 
}
 
sub select_parallel_thread_num {
 
        my ($self,$name,$top,$target_dir)=@_;
 
        my $table = def_table(2, 2, FALSE);
 
        my $col=0;
 
        my $row=0;
 
 
 
        #get total number of processor in the system
 
        my $cmd = "nproc\n";
 
        my $cpu_num=4;
 
        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
 
        if(length $stderr>1){
 
                #nproc command has failed. set default 4 paralel processor
 
 
 
        }else {
 
                 my ($number ) = $stdout =~ /(\d+)/;
 
                 if (defined  $number ){
 
                        $cpu_num =$number if  ($number > 0 );
 
                 }
 
        }
 
        ($row,$col)= add_param_widget ($self,"Thread run:" , "thread_num", 1, 'Spin-button', "1,$cpu_num,1","specify the number of threads the Verilator can use at once in one simulation", $table,$row,$col,1, 'compile', undef,undef,'vertical');
 
        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');
Line 366... Line 416...
        $self->object_remove_attribute('compile_pin_range_lsb');
        $self->object_remove_attribute('compile_pin_range_lsb');
}
}
 
 
 
 
 
 
 
sub add_new_fpga_board{
 
 
 
        my ($self,$name,$top,$target_dir,$end_func,$vendor)=@_;
 
 
sub add_new_fpga_board{
        my $window = def_popwin_size(50,80,"Add New $vendor FPGA Board",'percent');
        my ($self,$name,$top,$target_dir,$end_func)=@_;
 
        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=add_widget_to_scrolled_win($table);
        $scrolled_win->set_policy( "automatic", "automatic" );
 
        $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');
 
 
 
        $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) if (defined $name);
        $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.");
 
 
        my ($Twin,$tview)=create_txview();
 
 
 
 
 
        my $widgets=
 
                ($vendor eq 'Altera')? add_new_altera_fpga_board_widgets($self,$name,$top,$target_dir,$end_func,$vendor):
 
                add_new_xilinx_fpga_board_widgets($self,$name,$top,$target_dir,$end_func,$vendor,$tview);
 
 
        my $widgets= add_new_fpga_board_widgets($self,$name,$top,$target_dir,$end_func);
 
        my ($Twin,$tview)=create_text();
 
 
 
 
 
        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);
Line 412... Line 459...
                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 = ($vendor eq 'Altera')?
                if(! defined $result ){
                        add_new_altera_fpga_board_files($self,$vendor):
                        select_compiler($self,$name,$top,$target_dir,$end_func);
                        add_new_xilinx_fpga_board_files($self,$vendor);
                        message_dialog("The new board has been added successfully!");
 
 
 
 
                if(! defined $result ){
 
                        select_compiler($self,$name,$top,$target_dir,$end_func) if (defined $name);
                        $window->destroy;
                        $window->destroy;
 
                        message_dialog("The new board has been added successfully!");
                }else {
                }else {
                        show_info(\$tview," ");
                        show_info($tview," ");
                        show_colored_info(\$tview,$result,'red');
                        show_colored_info($tview,$result,'red');
 
 
                }
                }
 
 
 
        });
 
 
 
 
        });
 
 
 
 
        if($vendor eq 'Altera'){
 
            my $auto=def_image_button('icons/advance.png','Auto-fill');
 
            set_tip($auto, "Auto-fill JTAG configuration. The board must be powered on and be connected to the PC.");
 
                $mtable->attach($auto,5,6,9,10,'shrink','shrink',2,2);
        $auto-> signal_connect("clicked" => sub{
        $auto-> signal_connect("clicked" => sub{
                my $pid;
                my $pid;
                my $hw;
                my $hw;
                my $dir = Cwd::getcwd();
 
                my $project_dir   = abs_path("$dir/../../"); #mpsoc directory address           
                        my $project_dir   = get_project_dir();
                my $command=  "$project_dir/mpsoc/src_c/jtag/jtag_libusb/list_usb_dev";
                my $command=  "$project_dir/mpsoc/src_c/jtag/jtag_libusb/list_usb_dev";
                add_info(\$tview,"$command\n");
                        add_info($tview,"$command\n");
                my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($command);
                my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($command);
                if(length $stderr>1){
                if(length $stderr>1){
                        add_colored_info(\$tview,"$stderr\n",'red');
                                add_colored_info($tview,"$stderr\n",'red');
                        add_colored_info(\$tview,"$command was not run successfully!\n",'red');
                                add_colored_info($tview,"$command was not run successfully!\n",'red');
                }else {
                }else {
 
 
                        if($exit){
                        if($exit){
                                add_colored_info(\$tview,"$stdout\n",'red');
                                        add_colored_info($tview,"$stdout\n",'red');
                                add_colored_info(\$tview,"$command was not run successfully!\n",'red');
                                        add_colored_info($tview,"$command was not run successfully!\n",'red');
                        }else{
                        }else{
                                add_info(\$tview,"$stdout\n");
                                        add_info($tview,"$stdout\n");
                                my @a=split /vid=9fb/, $stdout;
                                my @a=split /vid=9fb/, $stdout;
                                if(defined $a[1]){
                                if(defined $a[1]){
                                        my @b=split /pid=/, $a[1];
                                        my @b=split /pid=/, $a[1];
                                        my @c=split /\n/, $b[1];
                                        my @c=split /\n/, $b[1];
                                        $pid=$c[0];
                                        $pid=$c[0];
                                        $self->object_add_attribute('compile','quartus_pid',$pid);
                                        $self->object_add_attribute('compile','quartus_pid',$pid);
                                        add_colored_info(\$tview,"Detected PID: $pid\n",'blue');
                                                add_colored_info($tview,"Detected PID: $pid\n",'blue');
 
 
                                }else{
                                }else{
                                        add_colored_info(\$tview,"The Altera vendor ID of 9fb is not detected. Make sure You have connected your Altera board to your USB port\n",'red');
                                                add_colored_info($tview,"The Altera vendor ID of 9fb is not detected. Make sure You have connected your Altera board to your USB port\n",'red');
                                        return;
                                        return;
                                }
                                }
                        }
                        }
                }
                }
 
 
 
 
                $command=  "$ENV{QUARTUS_BIN}/jtagconfig";
                $command=  "$ENV{QUARTUS_BIN}/jtagconfig";
                add_info(\$tview,"$command\n");
                        add_info($tview,"$command\n");
                ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($command);
                ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($command);
                if(length $stderr>1){
                if(length $stderr>1){
                        add_colored_info(\$tview,"$stderr\n",'red');
                                add_colored_info($tview,"$stderr\n",'red');
                        add_colored_info(\$tview,"$command was not run successfully!\n",'red');
                                add_colored_info($tview,"$command was not run successfully!\n",'red');
                }else {
                }else {
 
 
                        if($exit){
                        if($exit){
                                add_colored_info(\$tview,"$stdout\n",'red');
                                        add_colored_info($tview,"$stdout\n",'red');
                                add_colored_info(\$tview,"$command was not run successfully!\n",'red');
                                        add_colored_info($tview,"$command was not run successfully!\n",'red');
                        }else{
                        }else{
                                add_info(\$tview,"$stdout\n");
                                        add_info($tview,"$stdout\n");
                                my @a=split /1\)\s+/, $stdout;
                                my @a=split /1\)\s+/, $stdout;
                                if(defined $a[1]){
                                if(defined $a[1]){
                                        my @b=split /\s+/, $a[1];
                                        my @b=split /\s+/, $a[1];
                                        $hw=$b[0];
                                        $hw=$b[0];
                                        $self->object_add_attribute('compile','quartus_hardware',$hw);
                                        $self->object_add_attribute('compile','quartus_hardware',$hw);
                                        add_colored_info(\$tview,"Detected Hardware: $hw\n",'blue');
                                                add_colored_info($tview,"Detected Hardware: $hw\n",'blue');
                                        my $qsf=$self->object_get_attribute('compile','quartus_qsf');
                                                my $qsf=$self->object_get_attribute('compile','board_confg_file');
                                        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 device 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){
Line 508... Line 559...
                                                                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_altera_fpga_board_widgets($self,$name,$top,$target_dir,$end_func,$vendor);
                $v1-> pack1($widgets, TRUE, TRUE);
                $v1-> pack1($widgets, TRUE, TRUE);
                #$table->attach_defaults($widgets,0,3,0,1); 
                #$table->attach_defaults($widgets,0,3,0,1); 
                $table->show_all();
                $table->show_all();
         #      my $cmd=" $ENV{'QUARTUS_BIN'}"
         #      my $cmd=" $ENV{'QUARTUS_BIN'}"
 
 
        });
        });
 
 
 
 
 
        }
 
 
 
 
 
 
 
 
        $window->add ($mtable);
        $window->add ($mtable);
        $window->show_all();
        $window->show_all();
 
 
}
}
 
 
 
 
 
 
 
sub add_new_xilinx_fpga_board_widgets{
 
        my ($self,$name,$top,$target_dir,$end_func,$vendor,$tview)=@_;
 
        my $table = def_table(2, 2, FALSE);
 
 
sub add_new_fpga_board_widgets{
        my $col=0;
        my ($self,$name,$top,$target_dir,$end_func)=@_;
        my $row=0;
 
 
 
        my $help1="Your given FPGA Board name. Do not use any space in given name";
 
        my $help2="Path to FPGA board xdc file. In your Xilinx board installation CD or in the Internet, search for a xdc file containing your FPGA device pin assignment constrain).";
 
        my $help3="Path to FPGA_board_top.v file. A Verilog file containing all your FPGA device IO ports.";
 
        my $help4="Your Board name (Board PART) e.g. digilentinc.com:arty-z7-20:part0:1.0";
 
        my $help5="Your FPGA device name (PART) e.g. xc7z020clg400-1 ";
 
        my $help6="The order number of target device in jtag chain. Run jtag targets after \"connect\" command in xsct terminal to list all available targets.";
 
        my $help7="Path to Vivado board files repository. E.g download the repo from https://github.com/Digilent/vivado-boards and save in \$ProNoC_work/toolchain/board_files folder.";
 
        my $help8="Hardware device name e.g. xc7z020_1. To find it you can connect your FPGA board to your PC. In tcl terminal run
 
                open_hw
 
                connect_hw_server
 
                open_hw_target
 
                get_hw_devices
 
It supposed to show the list of your hardware devices in your FPGA. Select the name represent your FPGA device
 
                ";
 
 
 
 
 
        my $repo ="$ENV{PRONOC_WORK}/toolchain/board_files";
 
 
 
 
 
        $row++;
 
 
 
        my @info = (
 
        { label=>"FPGA board display name:",        param_name=>'fpga_board', type=>"Entry",     default_val=>undef, content=>undef, info=>$help1, param_parent=>'compile', ref_delay=> undef},
 
        { label=>"Set board repo:", param_name=>'fpga_board_repo',  type=>"DIR_path", default_val=>"$repo", content=>undef, info=>$help7, param_parent=>'compile',ref_delay=>undef},
 
        { label=>"FPGA board part name:", param_name=>'fpga_board_part', type=>"EntryCombo",default_val=>undef, content=>undef, info =>$help4, param_parent=>'compile', ref_delay=> undef},
 
        { label=>"FPGA part name:",       param_name=>'fpga_part', type=>"Entry",     default_val=>undef, content=>undef, info=>$help5, param_parent=>'compile', ref_delay=> undef},
 
    { label=>"FPGA Hardware device name:", param_name=>'fpga_hw_device', type=>"EntryCombo", default_val=>undef, content=>undef, info=>$help8, param_parent=>'compile', ref_delay=> undef},
 
        { label=>"Target device JTAG chain order number", param_name=>'fpga_board_order',  type=>"Spin-button", default_val=>1, content=>"0,256,1", info=>$help6, param_parent=>'compile',ref_delay=>undef},
 
        { label=>'FPGA board xdc file:',    param_name=>'board_confg_file',   type=>"FILE_path", default_val=>undef, content=>"xdc", info=>$help2, param_parent=>'compile', ref_delay=>undef},
 
        { label=>"FPGA board golden top Verilog file", param_name=>'fpga_board_v',     type=>"FILE_path", default_val=>undef, content=>"v", info=>$help3, param_parent=>'compile',ref_delay=>undef},
 
                );
 
        my %widgets;
 
        my %rows;
 
        foreach my $d (@info) {
 
                $rows{$d->{param_name}} =$row;
 
                ($row,$col,$widgets{$d->{param_name}})=add_param_widget ($self, $d->{label}, $d->{param_name}, $d->{default_val}, $d->{type}, $d->{content}, $d->{info}, $table,$row,$col,1, $d->{param_parent}, $d->{ref_delay},undef,'vertical');
 
        }
 
 
 
        my $icon = 'icons/advance.png';
 
        my $search=def_image_button($icon,undef);
 
        my $search_board=def_image_button ($icon,undef);
 
        my $search_dev=def_image_button ($icon,undef);
 
        my $search_chain=def_image_button ($icon,undef);
 
 
 
        $table->attach($search,4,5,$rows{'fpga_board_part'},$rows{'fpga_board_part'}+1,'fill','shrink',2,2);
 
        $table->attach($search_board,4,5,$rows{'fpga_part'},$rows{'fpga_part'}+1,'fill','shrink',2,2);
 
        $table->attach($search_dev,4,5,$rows{'fpga_hw_device'},$rows{'fpga_hw_device'}+1,'fill','shrink',2,2);
 
        $table->attach($search_chain,4,5,$rows{'fpga_board_order'},$rows{'fpga_board_order'}+1,'fill','shrink',2,2);
 
 
 
 
 
        $search->signal_connect("clicked" => sub{
 
                        my $load= show_gif("icons/load.gif");
 
                        $table->attach ($load,5, 6, $rows{'fpga_board_part'},$rows{'fpga_board_part'}+ 1,'shrink','shrink',0,0);
 
                        $table->show_all;
 
                        my $result=     set_xilinx_board_from_repo($self,$tview);
 
                        update_combo_entry_content($widgets{'fpga_board_part'}, $result);
 
                        $load->destroy;
 
                        $table->show_all;
 
                });
 
 
 
 
 
        $search_board->signal_connect("clicked" => sub{
 
                        my $load= show_gif("icons/load.gif");
 
                        $table->attach ($load,5, 6, $rows{'fpga_part'},$rows{'fpga_part'}+1, 'shrink','shrink',0,0);
 
                        $table->show_all;
 
                        my $result=     get_xilinx_board_part($self,$tview);
 
                        $widgets{'fpga_part'}->set_text($result);
 
                        #print "result = $result\n";
 
                        $load->destroy;
 
                        $table->show_all;
 
                });
 
        $search_dev->signal_connect("clicked" => sub{
 
                        my $load= show_gif("icons/load.gif");
 
                        $table->attach ($load,5, 6, $rows{'fpga_hw_device'},$rows{'fpga_hw_device'}+ 1,'shrink','shrink',0,0);
 
                        $table->show_all;
 
                        my $result=     get_xilinx_device_names($self,$tview);
 
                        update_combo_entry_content($widgets{'fpga_hw_device'}, $result);
 
                        $load->destroy;
 
                        $table->show_all;
 
                });
 
        $search_chain->signal_connect("clicked" => sub{
 
                my $targets = show_all_xilinx_targets($self,$tview);
 
                if(!defined $targets){
 
                        add_info($tview,"Unable to find the FPGA board target list. Make sure you have connected your FPGA board to your PC first and it is powered on.\n");
 
                        return;
 
                }
 
 
 
                my @lines=split(/\r?\n/,$targets);
 
                my @list1;
 
                my @list2;
 
                foreach my $p (@lines){
 
                        $p =~ s/^\s+//;#left trim
 
                        my @words=split(/\s+/,$p);
 
                        push (@list1,$words[0]);
 
                        push (@list2,$words[1]);
 
                }
 
                my $hw =  $self->object_get_attribute('compile','fpga_hw_device');
 
                if( !defined $hw){
 
                        add_colored_info($tview,"Please define the FPGA hardware device name first!\n",'red');
 
                        return;
 
                }
 
                my $pos = find_the_most_similar_position ($hw ,@list2);
 
                add_info($tview,"$hw matched with target $list1[$pos] $list2[$pos]  ");
 
                $widgets{'fpga_board_order'}->set_value($list1[$pos]);
 
        });
 
 
 
        return ($row, $col, $table);
 
}
 
 
 
 
 
 
 
sub set_xilinx_board_from_repo{
 
        my ($self,$tview)=@_;
 
        my $bin =  $self->object_get_attribute('compile',"vivado bin");
 
        my $vivado =(defined $bin)?  "${bin}/vivado" :  "vivado";
 
        my $result;
 
        my $repo= $self->object_get_attribute('compile','fpga_board_repo');
 
        my $tcl= get_project_dir()."/mpsoc/perl_gui/lib/tcl/vivado_get_boards.tcl -tclargs $repo";
 
        my $command = "cd $ENV{PRONOC_WORK}/tmp;   $vivado -mode tcl -source $tcl";
 
 
 
        add_info($tview,"$command\n");
 
        my $stdout=run_cmd_textview_errors($command,$tview);
 
        return if (!defined $stdout);
 
        add_info($tview,"$stdout\n");
 
        my @boards=split(/\s+/,$stdout);
 
        my $r=0;
 
        foreach my $board (@boards){
 
                my @pp=split(':',$board);
 
                if(scalar @pp  == 4 && $pp[1] =~ /[a-zA-Z]+/) {
 
                        $r=1;
 
                        $result= (!defined $result)? "$board" : $result.",$board";
 
                }
 
        }
 
        add_colored_info($tview,"$stdout\n",'red') if($r==0);
 
        return $result;
 
}
 
 
 
 
 
sub get_xilinx_device_names{
 
        my ($self,$tview)=@_;
 
        my $bin =  $self->object_get_attribute('compile',"vivado bin");
 
        my $vivado =(defined $bin)?  "${bin}/vivado" :  "vivado";
 
        my $result;
 
        my $repo= $self->object_get_attribute('compile','fpga_board_repo');
 
        my $tcl= get_project_dir()."/mpsoc/perl_gui/lib/tcl/vivado_get_hw_device.tcl -tclargs";
 
        my $command = "cd $ENV{PRONOC_WORK}/tmp;   $vivado -mode tcl -source $tcl";
 
 
 
        add_info($tview,"$command\n");
 
        my $stdout=run_cmd_textview_errors($command,$tview);
 
        if (!defined $stdout){
 
                add_info($tview,"Unable to find the FPGA board devices list. Make sure you have connected your FPGA board to your PC first and it is powered on.\n");
 
                return;
 
        }
 
        add_info($tview,"$stdout\n");
 
        my $devices =  capture_string_between ('\n\*RESULT:',$stdout,"\n");
 
        my @D=split(/\s+/,$devices);
 
        return join ',', @D;
 
}
 
 
 
 
 
 
 
 
 
 
 
 
 
sub get_xilinx_board_part{
 
        my ($self,$tview)=@_;
 
        my $bin =  $self->object_get_attribute('compile',"vivado bin");
 
        my $vivado =(defined $bin)?  "${bin}/vivado" :  "vivado";
 
        my $result;
 
        my $repo= $self->object_get_attribute('compile','fpga_board_repo');
 
        my $board_part= $self->object_get_attribute('compile' ,'fpga_board_part');
 
        if (!defined $board_part  ){
 
                add_colored_info($tview,"Please define the FPGA board part name first!\n",'red');
 
                return;
 
        }
 
 
 
        my $tcl= get_project_dir()."/mpsoc/perl_gui/lib/tcl/vivado_get_part.tcl -tclargs $board_part $repo ";
 
 
 
 
 
        my $command = "cd $ENV{PRONOC_WORK}/tmp;   $vivado -mode tcl -source $tcl";
 
 
 
        add_info($tview,"$command\n");
 
        my $stdout=run_cmd_textview_errors($command,$tview);
 
        return if (!defined $stdout);
 
        add_info($tview,"$stdout\n");
 
        return capture_string_between ('\n\*RESULT:',$stdout,"\n");
 
}
 
 
 
 
 
 
 
sub add_new_altera_fpga_board_widgets{
 
        my ($self,$name,$top,$target_dir,$end_func,$vendor)=@_;
        my $table = def_table(2, 2, FALSE);
        my $table = def_table(2, 2, FALSE);
 
 
        my $help1="FPGA Board name. Do not use any space in given name";
        my $help1="FPGA Board name. Do not use any space in given name";
        my $help2="Path to FPGA board qsf file. In your Altra board installation CD or in the Internet search for a QSF file containing your FPGA device name with other necessary global project setting including the pin assignments (e.g DE10_Nano_golden_top.qsf).";
        my $help2="Path to FPGA board qsf file. In your Altra board installation CD or in the Internet search for a QSF file containing your FPGA device name with other necessary global project setting including the pin assignments (e.g DE10_Nano_golden_top.qsf).";
        my $help3="Path to FPGA_board_top.v file. In your Altra board installation CD or in the Internet search for a verilog file containing all your FPGA device IO ports (e.g DE10_Nano_golden_top.v).";
        my $help3="Path to FPGA_board_top.v file. In your Altra board installation CD or in the Internet search for a Verilog file containing all your FPGA device IO ports (e.g DE10_Nano_golden_top.v).";
        my $help4="FPGA 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 Board USB-Blaster product ID (PID). Power on your FPGA board and connect it to your PC. Then press Auto-fill button to find PID. Optionally you can run mpsoc/
src_c/jtag/jtag_libusb/list_usb_dev to find your USB-Blaster PID. Search for PID of a device having 9fb (altera) Vendor ID (VID)";
src_c/jtag/jtag_libusb/list_usb_dev to find your USB-Blaster PID. Search for PID of a device having 9fb (altera) Vendor ID (VID)";
        my $help5="Power on your FPGA board and connect it to your PC. Then press Auto-fill button to find your hardware name. 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. Optionally you can run \$QUARTUS_BIN/jtagconfig to find your programming hardware name.
an example of output from the 'jtagconfig' command:
an example of output from the 'jtagconfig' command:
\t  1) ByteBlasterMV on LPT1
\t  1) ByteBlasterMV on LPT1
\t       090010DD   EPXA10
\t       090010DD   EPXA10
\t       049220DD   EPXA_ARM922
\t       049220DD   EPXA_ARM922
or
or
\t   1) DE-SoC [1-3]
\t   1) DE-SoC [1-3]
\t       48A00477   SOCVHP5
\t       48A00477   SOCVHP5
\t       02D020DC   5CS(EBA6ES|XFC6c6ES)
\t       02D020DC   5CS(EBA6ES|XFC6c6ES)
ByteBlasterMV \& DE-SoC are the programming hardware name.";
ByteBlasterMV \& DE-SoC are the programming hardware name.";
my $help6="Power on your FPGA board and connect it to your PC. Then press Auto-fill button to find your 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 device location in jtag chain. Optionally you can run \$QUARTUS_BIN/jtagconfig to find your target device location in jtag chain.";
 
 
 
 
 
 
 
 
        my @info = (
        my @info = (
        { label=>"FPGA Borad name:",                   param_name=>'quartus_board', type=>"Entry",     default_val=>undef, content=>undef, info=>$help1, param_parent=>'compile', ref_delay=> undef},
        { label=>"FPGA Board Name:",                   param_name=>'fpga_board', type=>"Entry",     default_val=>undef, content=>undef, info=>$help1, param_parent=>'compile', ref_delay=> undef},
        { label=>'FPGA board golden top QSF file:',    param_name=>'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=>'board_confg_file',   type=>"FILE_path", default_val=>undef, content=>"qsf", info=>$help2, param_parent=>'compile', ref_delay=>undef},
        { label=>"FPGA board golden top verilog file", param_name=>'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=>'fpga_board_v',     type=>"FILE_path", default_val=>undef, content=>"v", info=>$help3, param_parent=>'compile',ref_delay=>undef },
        );
        );
 
 
        my @usb = (
        my @usb = (
        { label=>"FPGA 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 Board USB Blaster PID:",        param_name=>'quartus_pid',   type=>"Entry",     default_val=>undef, content=>undef, info=>$help4, param_parent=>'compile', ref_delay=> undef},
        { label=>"FPGA 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 Board Programming Hardware Name:", param_name=>'quartus_hardware',   type=>"Entry",     default_val=>undef, content=>undef, info=>$help5, param_parent=>'compile', ref_delay=> undef},
        { label=>"FPGA 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 Board Device location in JTAG chain:", param_name=>'quartus_device',   type=>"Spin-button",     default_val=>0, content=>"0,100,1", info=>$help6, param_parent=>'compile', ref_delay=> undef},
        );
        );
 
 
 
 
        my $col=0;
        my $col=0;
        my $row=0;
        my $row=0;
        foreach my $d (@info) {
        foreach my $d (@info) {
                ($row,$col)=add_param_widget ($self, $d->{label}, $d->{param_name}, $d->{default_val}, $d->{type}, $d->{content}, $d->{info}, $table,$row,$col,1, $d->{param_parent}, $d->{ref_delay},undef,"vertical");
                ($row,$col)=add_param_widget ($self, $d->{label}, $d->{param_name}, $d->{default_val}, $d->{type}, $d->{content}, $d->{info}, $table,$row,$col,1, $d->{param_parent}, $d->{ref_delay},undef,"vertical");
        }
        }
 
 
        my $labl=def_pack_vbox(FALSE, 0,(Gtk2::HSeparator->new,gen_label_in_center("FPGA Board JTAG Configuration"),Gtk2::HSeparator->new));
        my $labl=def_pack_vbox(FALSE, 0,(gen_Hsep(),gen_label_in_center("FPGA Board JTAG Configuration"),gen_Hsep()));
 
 
        $table->attach( $labl,0,3,$row,$row+1,'fill','shrink',2,2); $row++; $col=0;
        $table->attach( $labl,0,3,$row,$row+1,'fill','shrink',2,2); $row++; $col=0;
 
 
        foreach my $d (@usb) {
        foreach my $d (@usb) {
                ($row,$col)=add_param_widget ($self, $d->{label}, $d->{param_name}, $d->{default_val}, $d->{type}, $d->{content}, $d->{info}, $table,$row,$col,1, $d->{param_parent}, $d->{ref_delay},undef,"vertical");
                ($row,$col)=add_param_widget ($self, $d->{label}, $d->{param_name}, $d->{default_val}, $d->{type}, $d->{content}, $d->{info}, $table,$row,$col,1, $d->{param_parent}, $d->{ref_delay},undef,"vertical");
Line 598... Line 851...
 
 
        return ($row, $col, $table);
        return ($row, $col, $table);
}
}
 
 
 
 
 
sub add_new_xilinx_fpga_board_files{
 
        my ($self,$vendor)=@_;
 
        #check the board name
 
        my $board_name=$self->object_get_attribute('compile','fpga_board');
 
        return "Please define the Board Name\n" if(! defined $board_name );
 
        return "Please define the Board Name\n" if(length($board_name) ==0 );
 
        my $r=check_verilog_identifier_syntax($board_name);
 
        return "Error in given Board Name: $r\n" if(defined $r );
 
 
 
        #check xdc file 
 
        my $xdc=$self->object_get_attribute('compile','board_confg_file');
 
        return "Please define the xdc file\n" if(!defined $xdc );
 
        $xdc=add_project_dir_to_addr($xdc);
 
 
 
        #check v file 
 
        my $top=$self->object_get_attribute('compile','fpga_board_v');
 
        return "Please define the verilog file file\n" if(!defined $top );
 
        $top=add_project_dir_to_addr($top);
 
 
 
        #check board part 
 
        my $part=$self->object_get_attribute('compile','fpga_part');
 
        my $board_part=$self->object_get_attribute('compile','fpga_board_part');
 
        return "Please define at least one of FPGA board part or FPGA part names"if(!defined $part && !defined $board_part  );
 
 
 
        #make board directory
 
        my $project_dir = get_project_dir();
 
        my $path="$project_dir/mpsoc/boards/$vendor/$board_name";
 
        mkpath($path,1,01777);
 
        return "Error cannot make $path path" if ((-d $path)==0);
 
        copy( $xdc,"$path/$board_name.xdc");
 
        copy($top,"$path/$board_name.v");
 
 
sub add_new_fpga_board_files{
 
        my $self=shift;
 
 
        my $a=$self->object_get_attribute('compile','fpga_board_order');
 
        my $jtag_intfc="#!/bin/bash
 
JTAG_INTFC=\"\$PRONOC_WORK/toolchain/bin/jtag_xilinx_xsct -a $a -b 36\"
 
#it works only for 32-bit jtag data width for 64 pass -b 68
 
";
 
        save_file ("$path/jtag_intfc.sh",$jtag_intfc);
 
 
 
 
 
        my $bin =  $self->object_get_attribute('compile',"vivado bin");
 
    my $hw_dev=$self->object_get_attribute('compile',"fpga_hw_device");
 
    my $repo=  $self->object_get_attribute('compile','fpga_board_repo');
 
 
 
 
 
        my $tcl="proc set_project_properties { } {\n";
 
        if(-d $repo){
 
                $tcl=$tcl."\tset_property  \"board_part_repo_paths\" [list \"$repo\"] [current_project]\n";
 
        }else {
 
                $tcl=$tcl."\tset_property  \"board_part_repo_paths\" [get_property LOCAL_ROOT_DIR [xhub::get_xstores xilinx_board_store]] [current_project]\n" if(defined $board_part);
 
        }
 
        $tcl=$tcl."\tset_property \"part\" \"$part\" [current_project]\n" if(defined $part);
 
        $tcl=$tcl."\tset_property \"board_part\" \"$board_part\" [current_project]\n" if(defined $board_part);
 
        $tcl=$tcl."\tset_property \"default_lib\" \"xil_defaultlib\" [current_project]\n}\n";
 
 
 
 
 
 
 
        if (defined $hw_dev){
 
$tcl=$tcl."\n
 
proc program_board {bit_file} {
 
        open_hw
 
        connect_hw_server
 
        open_hw_target
 
        set_property PROGRAM.FILE \$bit_file [get_hw_devices $hw_dev]
 
        program_hw_devices [get_hw_devices $hw_dev]
 
        refresh_hw_device [get_hw_devices $hw_dev]
 
}
 
";
 
        }
 
        save_file ("$path/board_property.tcl",$tcl);
 
 
 
 
 
        $self->object_add_attribute('compile','board',$board_name);
 
        return undef;
 
 
 
 
 
}
 
 
 
 
 
sub add_new_altera_fpga_board_files{
 
        my ($self,$vendor)=@_;
 
 
        #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','fpga_board');
        return "Please define the Board Name\n" if(! defined $board_name );
        return "Please define the Board Name\n" if(! defined $board_name );
        return "Please define the Board Name\n" if(length($board_name) ==0 );
        return "Please define the Board Name\n" if(length($board_name) ==0 );
        my $r=check_verilog_identifier_syntax($board_name);
        my $r=check_verilog_identifier_syntax($board_name);
        return "Error in given Board Name: $r\n" if(defined $r );
        return "Error in given Board Name: $r\n" if(defined $r );
 
 
        #check qsf file 
        #check qsf file 
        my $qsf=$self->object_get_attribute('compile','quartus_qsf');
        my $qsf=$self->object_get_attribute('compile','board_confg_file');
        return "Please define the QSF file\n" if(!defined $qsf );
        return "Please define the QSF file\n" if(!defined $qsf );
 
 
        #check v file 
        #check v file 
        my $top=$self->object_get_attribute('compile','quartus_v');
        my $top=$self->object_get_attribute('compile','fpga_board_v');
        return "Please define the verilog file file\n" if(!defined $top );
        return "Please define the verilog file file\n" if(!defined $top );
 
 
        #check PID
        #check PID
        my $pid=$self->object_get_attribute('compile','quartus_pid');
        my $pid=$self->object_get_attribute('compile','quartus_pid');
        return "Please define the PID\n" if(! defined $pid );
        return "Please define the PID\n" if(! defined $pid );
Line 637... Line 968...
        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 $project_dir = get_project_dir();
        my $path="$dir/../boards/$board_name";
        my $path="$project_dir/mpsoc/boards/$vendor/$board_name";
        mkpath($path,1,01777);
        mkpath($path,1,01777);
        return "Error cannot make $path path" if ((-d $path)==0);
        return "Error cannot make $path path" if ((-d $path)==0);
 
 
        #generate new qsf file
        #generate new qsf file
        $qsf=add_project_dir_to_addr($qsf);
        $qsf=add_project_dir_to_addr($qsf);
Line 724... Line 1055...
$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,$vendor)=@_;
        my $window = def_popwin_size(80,80,"Step 2: Pin Assignment",'percent');
        my $window = def_popwin_size(80,80,"Step 2: Pin Assignment",'percent');
 
 
        my $table = def_table(2, 2, FALSE);
        my $table = def_table(2, 2, FALSE);
        my $scrolled_win = new Gtk2::ScrolledWindow (undef, undef);
        my $scrolled_win = add_widget_to_scrolled_win($table);
        $scrolled_win->set_policy( "automatic", "automatic" );
 
        $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/$vendor/$board_name/jtag_intfc.sh","${fpath}../sw/jtag_intfc.sh");
        my $m= $self->object_get_attribute('mpsoc_name',undef);
        my $m= $self->object_get_attribute('mpsoc_name',undef);
        if(defined $m){ # we are compiling a complete NoC-based mpsoc                                           
        if(defined $m){ # we are compiling a complete NoC-based mpsoc                                           
                 my ($nr,$ne,$router_p,$ref_tops)= get_noc_verilator_top_modules_info($self);
                 my ($nr,$ne,$router_p,$ref_tops)= get_noc_verilator_top_modules_info($self);
         for (my $tile_num=0;$tile_num<$ne;$tile_num++){
         for (my $tile_num=0;$tile_num<$ne;$tile_num++){
                    #print "$tile_num\n";
                    #print "$tile_num\n";
                        my ($soc_name,$num)= $self->mpsoc_get_tile_soc_name($tile_num);
                        my ($soc_name,$num)= $self->mpsoc_get_tile_soc_name($tile_num);
                        next if(!defined $soc_name);
                        next if(!defined $soc_name);
                        copy("../boards/$board_name/jtag_intfc.sh","${fpath}../sw/tile$tile_num/jtag_intfc.sh");
                        copy("../boards/$vendor/$board_name/jtag_intfc.sh","${fpath}../sw/tile$tile_num/jtag_intfc.sh");
                }
                }
 
 
        }
        }
 
 
 
 
 
 
        #copy board program_device.sh file 
        #copy board program_device.sh file 
        copy("../boards/$board_name/program_device.sh","${fpath}../program_device.sh");
        copy("../boards/$vendor/$board_name/program_device.sh","${fpath}../program_device.sh");
 
 
        #get boards pin list
        #get boards pin list
        my $top_v= "../boards/$board_name/$board_name.v";
        my $top_v= "../boards/$vendor/$board_name/$board_name.v";
 
 
        if(!-f $top_v){
        if(!-f $top_v){
                message_dialog("Error: Could not load the board pin list. The $top_v does not exist!");
                message_dialog("Error: Could not load the board pin list. The $top_v does not exist!",'error');
                $window->destroy;
                $window->destroy;
        }
        }
 
 
        my $board=read_top_v_file($top_v);
        my $board=read_top_v_file($top_v);
 
 
Line 790... Line 1120...
 
 
        }
        }
 
 
        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 @labels= ('Port Direction','Port Range     ','Port name      ','Assignment Type','Board Port name ','Board Port Range');
        foreach my $p (@lables){
        foreach my $p (@labels){
                my $l=gen_label_in_left($p);
                my $l=gen_label_in_left($p);
                $l->set_markup("<b>  $p    </b>");
                $l->set_markup("<b>  $p    </b>");
                $table->attach ($l, $col,$col+1, $row, $row+1,'fill','shrink',2,2);
                $table->attach ($l, $col,$col+1, $row, $row+1,'fill','shrink',2,2);
                $col++
                $col++
        }
        }
Line 822... Line 1152...
                                        chomp $value;
                                        chomp $value;
                                        ($portrange=$portrange)=~ s/\b$l\b/$value/g      if(defined $param{$l});
                                        ($portrange=$portrange)=~ s/\b$l\b/$value/g      if(defined $param{$l});
                                #       print"($portrange=$portrange)=~ s/\b$l\b/$value/g      if(defined $param{$l})\n";
                                #       print"($portrange=$portrange)=~ s/\b$l\b/$value/g      if(defined $param{$l})\n";
                                }
                                }
                        }
                        }
 
 
 
                        my($s1,$s2)=split (":",$portrange);
 
                        {
 
                                no warnings 'numeric';
 
                                $s1 = eval $s1;
 
                                $s2 = eval $s2;
 
                        }
                        $portrange = "[ $portrange ]" ;
                        $portrange = "[ $portrange ]" ;
 
                    if(defined $s1 && defined $s2 ){
 
                        $portrange = "" if($s1 eq 0 && $s2 eq 0);                  #the upper and lower range are equal zero so remove it                         
 
                        }
                }
                }
 
 
                my $label1= gen_label_in_left("  $porttype");
                my $label1= gen_label_in_left("  $porttype");
                my $label2= gen_label_in_left("  $portrange");
                my $label2= gen_label_in_left("  $portrange");
                my $label3= gen_label_in_left("  $p");
                my $label3= gen_label_in_left("  $p");
Line 848... Line 1188...
                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 = 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);
Line 885... Line 1225...
 
 
        }
        }
        $next-> signal_connect("clicked" => sub{
        $next-> signal_connect("clicked" => sub{
 
 
                $window->destroy;
                $window->destroy;
                quartus_compilation($self,$board,$name,$top,$target_dir,$end_func);
                fpga_compilation($self,$board,$name,$top,$target_dir,$end_func,$vendor);
 
 
        });
        });
        $back-> signal_connect("clicked" => sub{
        $back-> signal_connect("clicked" => sub{
 
 
                $window->destroy;
                $window->destroy;
                select_compiler($self,$name,$top,$target_dir,$end_func);
                select_compiler($self,$name,$top,$target_dir,$end_func,$vendor);
 
 
        });
        });
 
 
 
 
        $window->add ($mtable);
        $window->add ($mtable);
Line 904... Line 1244...
 
 
 
 
 
 
 
 
 
 
sub quartus_compilation{
sub fpga_compilation{
        my ($self,$board,$name,$top,$target_dir,$end_func)=@_;
        my ($self,$board,$name,$top,$target_dir,$end_func,$vendor)=@_;
 
 
        my $run=def_image_button('icons/gate.png','Compile');
        my $run=def_image_button('icons/gate.png','Compile');
        my $back=def_image_button('icons/left.png','Previous');
        my $back=def_image_button('icons/left.png','Previous');
        my $regen=def_image_button('icons/refresh.png','Regenerate Top.v');
        my $regen=def_image_button('icons/refresh.png','Regenerate Top.v');
        my $prog=def_image_button('icons/write.png','Program the board');
        my $prog=def_image_button('icons/write.png','Program the board');
Line 928... Line 1268...
        $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,
 
                                      'destroy-with-parent',
                my $response =  yes_no_dialog("Are you sure you want to regenerate the Top.v file? Note that any changes you have made will be lost");
                                      'question', # message type
 
                                      '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");
 
                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->refresh_source("$board_top_file");
                }
                }
                $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,$end_func,$vendor);
 
 
        });
        });
 
 
 
 
        #compile
        #compile
Line 959... Line 1293...
                my $load= show_gif("icons/load.gif");
                my $load= show_gif("icons/load.gif");
                $table->attach ($load,8, 9, 1,2,'shrink','shrink',2,2);
                $table->attach ($load,8, 9, 1,2,'shrink','shrink',2,2);
                $load->show_all;
                $load->show_all;
 
 
                set_gui_status($self,'save_project',1);
                set_gui_status($self,'save_project',1);
                $app->do_save();
                $app->ask_to_save_changes();
                my $error = 0;
 
                add_info(\$tview,"CREATE: start creating Quartus project in $target_dir\n");
 
 
 
                #get list of source file
                quartus_run_compile ($self,$app,$tview,$target_dir,$name,$window,$end_func,$vendor) if($vendor eq 'Altera');
                add_info(\$tview,"        Read the list of all source files $target_dir/src_verilog\n");
                xilinx_run_compile ($self,$app,$tview,$target_dir,$name,$window,$end_func,$vendor)  if($vendor eq 'Xilinx');
                my @files = File::Find::Rule->file()
 
                            ->name( '*.v','*.V','*.sv' )
 
                            ->in( "$target_dir/src_verilog" );
 
 
 
                #make sure source files have key word 'module' 
                $load->destroy;
                my @sources;
 
                foreach my $p (@files){
 
                        push (@sources,$p)      if(check_file_has_string($p,'module'));
 
                }
 
                my $files = join ("\n",@sources);
 
                add_info(\$tview,"$files\n");
 
 
 
                #creat project qsf file
        });
                my $qsf_file="$target_dir/${name}.qsf";
 
                save_file ($qsf_file,"# Generated using ProNoC\n");
 
 
 
                #append global assignets to qsf file
 
                my $board_name=$self->object_get_attribute('compile','board');
 
                my @qsfs =   glob("../boards/$board_name/*.qsf");
 
                if(!defined $qsfs[0]){
 
                        message_dialog("Error: ../boards/$board_name folder does not contain the qsf file.!");
 
                        $window->destroy;
 
                }
 
 
 
 
        #Programe the board 
 
        $prog-> signal_connect("clicked" => sub{
 
                quartus_program_the_board($self,$tview,$target_dir,$name,$vendor) if($vendor eq 'Altera');
 
                vivado_program_the_board($self,$tview,$target_dir,$name,$vendor) if($vendor eq 'Xilinx');
 
        });
 
 
 
}
 
 
 
sub vivado_program_the_board {
 
        my      ($self,$tview,$target_dir,$name,$vendor) =@_;
 
 
 
        my $bit_file="$target_dir/Vivado/xilinx_compile/${name}.runs/impl_1/Top.bit";
 
 
 
 
 
 
 
        unless (-f "$target_dir/Vivado/program_board.tcl"){
 
        #create tcl file
 
        my $xpr = "\$tcl_path/xilinx_compile/${name}.xpr";
 
        my $tcl="
 
#Get tcl shell path relative to current script
 
set tcl_path    [file dirname [info script]]
 
 
 
set projectName $name
 
 
 
source \"\$tcl_path/board_property.tcl\"
 
set projectXpr \"$xpr\"
 
#Open project
 
open_project   \$projectXpr
 
program_board \"\$tcl_path/xilinx_compile/${name}.runs/impl_1/Top.bit\"
 
close_project
 
exit
 
 
 
        ";
 
        save_file ("$target_dir/Vivado/program_board.tcl",$tcl);
 
        add_info($tview,"File $target_dir/Vivado/program_board.tcl is created\n");
 
        }
 
 
 
        #check bit file existance
 
        unless (-f $bit_file){
 
                add_colored_info($tview,"Could not find $bit_file. Click on project Compile button first and make sure it runs successfully.",'red');
 
                return
 
        }
 
 
 
 
 
        #run vivado using program_board.tcl
 
        my $error =run_vivado ($self,$target_dir,$tview,"$target_dir/Vivado/program_board.tcl");
 
        add_colored_info($tview,"Board is programmed successfully!\n",'blue') if($error==0);
 
 
 
 
 
}
 
 
 
 
 
 
 
 
 
sub quartus_program_the_board{
 
        my ($self,$tview,$target_dir,$name,$vendor)=@_;
 
        my $error = 0;
 
        my $sof_file="$target_dir/Quartus/output_files/${name}.sof";
 
        my $bash_file="$target_dir/program_device.sh";
 
 
 
        add_info($tview,"Program the board using Quartus_pgm and $sof_file file\n");
 
        #check if the programming file exists
 
        unless (-f $sof_file) {
 
                add_colored_info($tview,"\tThe $sof_file does not exists! Make sure you have compiled the code successfully.\n", 'red');
 
                $error=1;
 
        }
 
        #check if the program_device.sh file exists
 
        unless (-f $bash_file) {
 
                add_colored_info($tview,"\tThe $bash_file does not exist! This file varies depending on your target board and must be available inside mpsoc/boards/$vendor/[board_name].\n", 'red');
 
                $error=1;
 
        }
 
        return if($error);
 
        my $command = "bash $bash_file $sof_file";
 
        add_info($tview,"$command\n");
 
        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($command);
 
        if(length $stderr>1){
 
                add_colored_info($tview,"$stderr\n",'red');
 
                add_colored_info($tview,"Board was not programmed successfully!\n",'red');
 
        }else {
 
                if($exit){
 
                        add_colored_info($tview,"$stdout\n",'red');
 
                        add_colored_info($tview,"Board was not programmed successfully!\n",'red');
 
                }else{
 
                        add_info($tview,"$stdout\n");
 
                        add_colored_info($tview,"Board is programmed successfully!\n",'blue');
 
                }
 
 
 
        }
 
}
 
 
 
 
 
sub quartus_run_compile{
 
        my ($self,$app,$tview,$target_dir,$name,$window,$end_func,$vendor)=@_;
 
 
 
        my $error = 0;
 
        add_info($tview,"CREATE: start creating Quartus project in $target_dir/Quartus folder\n");
 
 
 
        mkpath("$target_dir/Quartus",1,01777);
 
 
 
        #get list of source file
 
        add_info($tview,"        Read the list of all source files $target_dir/src_verilog\n");
 
        my @files = File::Find::Rule->file()
 
                          ->name( '*.v','*.V','*.sv' )
 
                          ->in( "$target_dir/src_verilog" );
 
 
 
        #make sure source files have key word 'module' 
 
        my @sources;
 
        foreach my $p (@files){
 
                push (@sources,$p)      if(check_file_has_string($p,'endpackage'));
 
        }
 
        foreach my $p (@files){
 
                push (@sources,$p)      if(check_file_has_string($p,'module'));
 
        }
 
        my $files = join ("\n",@sources);
 
        add_info($tview,"$files\n");
 
 
 
        #creat project qsf file
 
        my $qsf_file="$target_dir/Quartus/${name}.qsf";
 
        save_file ($qsf_file,"# Generated using ProNoC\n");
 
 
 
        #append global assignets to qsf file
 
        my $board_name=$self->object_get_attribute('compile','board');
 
        my @qsfs =   glob("../boards/$vendor/$board_name/*.qsf");
 
        if(!defined $qsfs[0]){
 
                message_dialog("Error: ../boards/$vendor/$board_name folder does not contain the qsf file.!",'error');
 
                $window->destroy;
 
        }
 
 
                my $assignment_file =  $qsfs[0];
                my $assignment_file =  $qsfs[0];
 
 
                if(-f $assignment_file){
                if(-f $assignment_file){
                        merg_files ($assignment_file,$qsf_file);
                        merg_files ($assignment_file,$qsf_file);
                }
                }
 
 
 
        my %paths;
 
 
                #add the list of source fils to qsf file
                #add the list of source fils to qsf file
                my $s="\n\n\n set_global_assignment -name TOP_LEVEL_ENTITY Top\n";
                my $s="\n\n\n set_global_assignment -name TOP_LEVEL_ENTITY Top\n";
                foreach my $p (@sources){
                foreach my $p (@sources){
                        my ($name,$path,$suffix) = fileparse("$p",qr"\..[^.]*$");
                        my ($name,$path,$suffix) = fileparse("$p",qr"\..[^.]*$");
                        $s="$s set_global_assignment -name VERILOG_FILE $p\n" if ($suffix eq ".v");
                        $s="$s set_global_assignment -name VERILOG_FILE $p\n" if ($suffix eq ".v");
                        $s="$s set_global_assignment -name SYSTEMVERILOG_FILE $p\n" if ($suffix eq ".sv");
                        $s="$s set_global_assignment -name SYSTEMVERILOG_FILE $p\n" if ($suffix eq ".sv");
 
                $paths{$path}=1;
 
        }
 
 
 
 
 
 
 
 
 
 
 
 
 
        foreach my $p (sort keys %paths){
 
                $s="$s set_global_assignment -name SEARCH_PATH  $p\n";
                }
                }
 
 
                append_text_to_file($qsf_file,$s);
                append_text_to_file($qsf_file,$s);
                add_info(\$tview,"\n Qsf file has been created\n");
        add_info($tview,"\n Qsf file has been created\n");
 
 
 
 
 
 
 
 
                #start compilation
                #start compilation
                my $Quartus_bin= $self->object_get_attribute('compile','quartus_bin');;
        my $Quartus_bin= $self->object_get_attribute('compile','quartus bin');
                add_info(\$tview, "Start Quartus compilation.....\n");
        my @qfiles = ("quartus_map","quartus_fit","quartus_asm","quartus_sta");
 
        foreach my $f (@qfiles){
 
                unless(-f "$Quartus_bin/$f" ){
 
                        $error=1;
 
                        add_colored_info($tview, "$Quartus_bin/$f No such file or directory\n",'red');
 
                        last;
 
                }
 
 
 
        }
 
 
 
        my $run_sh = "#!/bin/bash
 
$Quartus_bin/quartus_map --64bit $name --read_settings_files=on
 
$Quartus_bin/quartus_fit --64bit $name --read_settings_files=on
 
$Quartus_bin/quartus_asm --64bit $name --read_settings_files=on
 
$Quartus_bin/quartus_sta --64bit $name
 
        ";
 
 
 
        save_file("$target_dir/Quartus/run.sh",  $run_sh);
 
 
 
        add_info($tview, "Start Quartus compilation.....\n");
                my @compilation_command =(
                my @compilation_command =(
                        "cd \"$target_dir/\" \n xterm -e bash -c '$Quartus_bin/quartus_map --64bit $name --read_settings_files=on; echo \$? > status' ",
                "cd \"$target_dir/Quartus\" \n xterm -e bash -c '$Quartus_bin/quartus_map --64bit $name --read_settings_files=on; echo \$? > status; sleep 1' ",
                        "cd \"$target_dir/\" \n xterm -e bash -c '$Quartus_bin/quartus_fit --64bit $name --read_settings_files=on; echo \$? > status' ",
                "cd \"$target_dir/Quartus\" \n xterm -e bash -c '$Quartus_bin/quartus_fit --64bit $name --read_settings_files=on; echo \$? > status; sleep 1' ",
                        "cd \"$target_dir/\" \n xterm -e bash -c '$Quartus_bin/quartus_asm --64bit $name --read_settings_files=on; echo \$? > status' ",
                "cd \"$target_dir/Quartus\" \n xterm -e bash -c '$Quartus_bin/quartus_asm --64bit $name --read_settings_files=on; echo \$? > status; sleep 1' ",
                        "cd \"$target_dir/\" \n xterm -e bash -c '$Quartus_bin/quartus_sta --64bit $name;echo \$? > status' ");
                "cd \"$target_dir/Quartus\" \n xterm -e bash -c '$Quartus_bin/quartus_sta --64bit $name; echo \$? > status; sleep 1 ' ");
 
 
                foreach my $cmd (@compilation_command){
                foreach my $cmd (@compilation_command){
                        add_info(\$tview,"$cmd\n");
                        last if($error);
                        unlink "$target_dir/status";
                add_info($tview,"$cmd\n");
                        my ($stdout,$exit)=run_cmd_in_back_ground_get_stdout( $cmd);
                unlink "$target_dir/Quartus/status";
                        open(my $fh,  "<$target_dir/status") || die "Can not open: $!";
                my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout( $cmd);
 
                if($exit){
 
                        add_colored_info($tview, "$stdout\n",'red') if(defined $stdout);
 
                        add_colored_info($tview, "$stderr\n",'red') if(defined $stderr);
 
                        $error=1;
 
                        last;
 
                }
 
 
 
                open(my $fh,  "<$target_dir/Quartus/status") || die "Can not open: $!";
                        read($fh,my $status,1);
                        read($fh,my $status,1);
                        close($fh);
                        close($fh);
                        if("$status" != "0"){
                        if("$status" != "0"){
                                ($stdout,$exit)=run_cmd_in_back_ground_get_stdout("cd \"$target_dir/output_files/\" \n grep -h \"Error (\" *");
                        ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout("cd \"$target_dir/Quartus/output_files/\" \n grep -h \"Error (\" *");
                                add_colored_info(\$tview,"$stdout\n Quartus compilation failed !\n",'red');
                        add_colored_info($tview,"$stderr\n",'red') if(defined $stderr);
 
                        add_colored_info($tview,"$stdout\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 failed !\n",'red') if($error==1);
 
        add_colored_info($tview,"Quartus compilation is done successfully in $target_dir/Quartus!\n", 'blue') if($error==0);
                if (defined $end_func){
                if (defined $end_func){
                        if ($error==0){
                        if ($error==0){
                                $end_func->($self);
                                $end_func->($self);
                                $window->destroy;
                                $window->destroy;
                        }else {
                        }else {
                                message_dialog("Error in Quartus compilation!",'error');
                                message_dialog("Error in Quartus compilation!",'error');
                        }
                        }
                }
                }
                $load->destroy;
 
 
 
        });
 
 
 
 
 
        #Programe the board 
}
        $prog-> signal_connect("clicked" => sub{
 
                my $error = 0;
 
                my $sof_file="$target_dir/output_files/${name}.sof";
 
                my $bash_file="$target_dir/program_device.sh";
 
 
 
                add_info(\$tview,"Programe the board using quartus_pgm and $sof_file file\n");
 
                #check if the programming file exists
 
                unless (-f $sof_file) {
 
                        add_colored_info(\$tview,"\tThe $sof_file does not exists! Make sure you have compiled the code successfully.\n", 'red');
 
                        $error=1;
 
 
sub xilinx_run_compile{
 
        my ($self,$app,$tview,$target_dir,$name,$window,$end_func,$vendor)=@_;
 
 
 
        add_info($tview,"CREATE: start creating Vivado project in $target_dir/Vivado\n");
 
        #get list of source file
 
        add_info($tview,"        Read the list of all source files $target_dir/src_verilog\n");
 
        my @files = File::Find::Rule->file()
 
                          ->name( '*.v','*.V','*.sv' )
 
                          ->in( "$target_dir/src_verilog" );
 
 
 
        #make sure source files have key word 'module' 
 
        my @sources;
 
        foreach my $p (@files){
 
                push (@sources,$p)      if(check_file_has_string($p,'endpackage'));
                }
                }
                #check if the program_device.sh file exists
        foreach my $p (@files){
                unless (-f $bash_file) {
                push (@sources,$p)      if(check_file_has_string($p,'module'));
                        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;
 
                }
                }
                return if($error);
 
                my $command = "bash $bash_file $sof_file";
        my %paths;
                add_info(\$tview,"$command\n");
        foreach my $p (@files){
                my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($command);
                my ($name,$path,$suffix) = fileparse("$p",qr"\..[^.]*$");
                if(length $stderr>1){
                #print "$path\n";
                        add_colored_info(\$tview,"$stderr\n",'red');
                my $remove="$target_dir/";
                        add_colored_info(\$tview,"Board was not programed successfully!\n",'red');
                $path =~ s/$remove//;
 
                $paths{$path}=1;
 
        }
 
 
 
 
 
 
 
 
 
        my $incdir="set include_dir_list [list";
 
        foreach my $p (sort keys %paths){
 
                $incdir.=" \$Dir/$p";
 
         }
 
        $incdir.="]";
 
 
 
        my $files = join ("\n",@sources);
 
 
 
 
 
 
 
        #add mem initial file to sources
 
        my $mem_files="";
 
        my @initial_files = File::Find::Rule->file()
 
                          ->name( '*.mem')
 
                          ->in( "$target_dir/sw" );
 
        mkpath("$target_dir/Vivado/xilinx_mem",1,01777) unless -f "$target_dir/Vivado/xilinx_mem";
 
        foreach my $f   (@initial_files){
 
                #       /home/alireza/work/hca_git/mpsoc_work/SOC/mor1k_soc/sw/RAM/ram0.mif  fpr soc
 
                #   /home/alireza/work/hca_git/mpsoc_work/MPSOC/newAdder/sw/tile0/RAM/ram0.mif fpr mpsoc
 
                my @m = split('\/sw\/',$f );
 
                my $d = $m[-1];#take the last file path name after /sw/
 
                $d=~ s/RAM//g; #remove RAM
 
                $d=~ s/\///g; #remove /
 
                $d = "tile0".$d unless($m[-1]=~/^tile/); #add tile0 to soc
 
                copy($f,"$target_dir/Vivado/xilinx_mem/$d");
 
                $mem_files="$mem_files \$tcl_path/xilinx_mem/$d";
 
        }
 
        add_info($tview,"HDL sources:\n$files\nMem sources:\n$mem_files\n");
 
        #make tcl file
 
        my $tcl="
 
#Get tcl shell path relative to current script
 
set tcl_path    [file dirname [info script]]
 
set Dir \"\$tcl_path/..\"
 
";
 
 
 
        $tcl=$tcl."set projectName $name";
 
 
 
        $tcl =$tcl."
 
source \"\$tcl_path/board_property.tcl\"
 
#Create output directory and clear contents
 
set outputdir \"\$tcl_path/xilinx_compile\"";
 
        $tcl =$tcl.'
 
file mkdir $outputdir
 
set files [glob -nocomplain "$outputdir/*"]
 
if {[llength $files] != 0} {
 
    puts "deleting contents of $outputdir"
 
    file delete -force {*}[glob -directory $outputdir *]; # clear folder contents
 
} else {
 
    puts "$outputdir is empty"
 
}
 
 
 
#Create project
 
create_project  $projectName $outputdir
 
 
 
set_project_properties
 
 
 
#add source files to Vivado project
 
';
 
 
 
        #get top level port names
 
        #get boards pin list
 
        my $top_v= "$target_dir/src_verilog/Top.v";
 
        if(!-f $top_v){
 
                message_dialog("Error: Could not load the board pin list. The Top.v does not exist!",'error');
 
                $window->destroy;
 
        }
 
 
 
 
 
        my @ports=verilog_file_get_ports_list(read_verilog_file($top_v),"Top");
 
 
 
        #get board tcl
 
        my $board_name=$self->object_get_attribute('compile','board');
 
        my @tcls= glob("../boards/$vendor/$board_name/*.tcl");
 
        foreach my $f (@tcls){
 
                copy($f,"$target_dir/Vivado");
 
        }
 
 
 
        #get board xdc
 
        my @xdcs= glob("../boards/$vendor/$board_name/*.xdc");
 
        my $i=1;
 
 
 
        foreach my $f (@xdcs){
 
                my $out="";
 
                #capture file content
 
                my $string= load_file($f);
 
                my @lines=split('\n',$string);
 
                #make sure lines describing the port name are not comment
 
                foreach my $l (@lines){
 
                        foreach my $p (@ports){
 
 
 
                                $l=~ s/^\s*#/ /g if($l =~ /^\s*#/   && $l =~  /\[\s*get_ports\s*[{\s]\s*$p[\s\[\]\}]/ );#             /\[get_ports\s*{\s*$p[\s\}\[]/);
 
 
 
                        }
 
                        $out=$out."$l\n";
 
                }
 
                my ($fname,$fpath,$fsuffix) = fileparse("$f",qr"\..[^.]*$");
 
                my $xdc_file = "$target_dir/Vivado/$fname.xdc";
 
                #save new xdc file
 
                save_file($xdc_file,$out);
 
                #add xdc to tcl file
 
                $tcl =$tcl."add_files -fileset constrs_1 \$tcl_path/$fname.xdc\n";
 
                $i++;
 
        }
 
 
 
        #internal clock constrain
 
        my $clk_xdc=get_clk_constrain_file($self);
 
        #save_file ("$target_dir/clk.xdc",$clk_xdc);
 
        #$tcl =$tcl."add_files -fileset constrs_1 \$tcl_path/clk.xdc\n";
 
 
 
 
 
 
 
        $tcl =$tcl."add_files ";
 
        #add hdl sources
 
        foreach my $f (@sources){
 
                my $p =cut_dir_path($f,'src_verilog');
 
                $tcl =$tcl." \$Dir/src_verilog/$p ";
 
        }
 
        $tcl =$tcl."\n";
 
 
 
        $tcl =$tcl."#add memory initial files to Vivado project
 
        add_files -norecurse $mem_files" if(length($mem_files)>3);
 
 
 
 
 
        $tcl =$tcl."\n set_property \"top\"  \"Top\" [current_fileset]\n";
 
        $tcl =$tcl."
 
        update_compile_order -fileset sources_1
 
        #launch synthesis
 
 
 
        # Make all reset syncron
 
        set_property verilog_define {{SYNC_RESET_MODE}} [current_fileset]
 
 
 
        # include source dirs
 
        $incdir
 
        set_property include_dirs  \$include_dir_list [current_fileset]
 
 
 
        launch_runs synth_1
 
        wait_on_run synth_1
 
        #Run implementation and generate bitstream
 
        set_property STEPS.PHYS_OPT_DESIGN.IS_ENABLED true [get_runs impl_1]
 
        launch_runs impl_1 -to_step write_bitstream
 
        wait_on_run impl_1
 
        puts \"Implementation done!\"
 
        ";
 
 
 
 
 
        $tcl =$tcl."\nexit";
 
        #creat make_project tcl file
 
        save_file ("$target_dir/Vivado/make_project.tcl",$tcl);
 
 
 
        my $error =run_vivado ($self,$target_dir,$tview,"$target_dir/Vivado/make_project.tcl");
 
        add_colored_info($tview,"Vivado compilation is done successfully in $target_dir/Vivado!\n", 'blue') if($error==0);
 
        if (defined $end_func){
 
                if ($error==0){
 
                        $end_func->($self);
 
                        $window->destroy;
                }else {
                }else {
 
                        message_dialog("Error in Vivado compilation!",'error');
 
                }
 
        }
 
 
 
 
 
}
 
 
 
 
 
sub run_vivado {
 
        my ($self,$target_dir,$tview,$tcl)=@_;
 
        my $error=0;
 
        #start compilation
 
        my $vivado_bin= $self->object_get_attribute('compile','vivado bin');
 
        add_info($tview, "Start compilation using vivado.....\n");
 
        my @compilation_command =(
 
                "cd \"$target_dir/Vivado/\" \n xterm -e bash -c '$vivado_bin/vivado -mode tcl -source $tcl'"
 
        );
 
 
 
        save_file("$target_dir/Vivado/run.sh",  "#!/bin/bash \n $vivado_bin/vivado -mode tcl -source $tcl");
 
 
 
 
 
        my $log="$target_dir/Vivado/vivado.log";
 
        #unlink $log;
 
 
 
        foreach my $cmd (@compilation_command){
 
                add_info($tview,"$cmd\n");
 
 
 
                my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout( $cmd);
                        if($exit){
                        if($exit){
                                add_colored_info(\$tview,"$stdout\n",'red');
                        $error=1;
                                add_colored_info(\$tview,"Board was not programed successfully!\n",'red');
                        add_colored_info($tview, "$stdout\n",'red') if(defined $stdout);
                        }else{
                        add_colored_info($tview, "$stderr\n",'red') if(defined $stderr);
                                add_info(\$tview,"$stdout\n");
                }
                                add_colored_info(\$tview,"Board is programed successfully!\n",'blue');
 
 
 
                        }
                        }
 
 
 
        #check vivado.log for error
 
        my $r;
 
        open my $fd, "<" , $log or $r=$!;
 
        if(defined $r ) {
 
                add_colored_info($tview, "could not open $log to check errors: $r\n",'red');
 
                $error=1;
                }
                }
        });
        else{
 
 
 
                #check error
 
                while (my $line = <$fd>) {
 
                        chomp $line;
 
                        if( $line =~ /ERROR:/){
 
                                add_colored_info($tview, "$line\n",'red');
 
                                $error=1;
 
                        }
 
                }
 
 
 
                #check warning
 
                close($fd);
 
                open $fd, "<" , $log;
 
                #print  "$log\n";
 
                if($error==0){
 
                        while (my $line = <$fd>) {
 
                                chomp $line;
 
                                if( $line =~ /^\s*WARNING:/){
 
                                        add_info($tview, "$line\n");
 
 
}
}
 
                        }
 
                }
 
 
 
                #check critical warning
 
                close($fd);
 
                open $fd, "<" , $log;
 
                #print  "$log\n";
 
                if($error==0){
 
                        while (my $line = <$fd>) {
 
                                chomp $line;
 
                                if( $line =~ /^\s*CRITICAL WARNING:/){
 
                                        add_colored_info($tview, "$line\n",'green');
 
                                }
 
                        }
 
                }
 
                close($fd);
 
        }
 
        return $error;
 
}
 
 
 
 
 
 
 
 
 
 
sub modelsim_compilation{
sub modelsim_compilation{
        my ($self,$name,$top,$target_dir)=@_;
        my ($self,$name,$top,$target_dir,$vendor)=@_;
        #my $window = def_popwin_size(80,80,"Step 2: Compile",'percent');
        #my $window = def_popwin_size(80,80,"Step 2: Compile",'percent');
 
 
 
 
        my $run=def_image_button('icons/run.png','run');
        my $run=def_image_button('icons/run.png','_run',FALSE,1);
        my $back=def_image_button('icons/left.png','Previous');
        my $back=def_image_button('icons/left.png','Previous');
        my $regen=def_image_button('icons/refresh.png','Regenerate testbench.v');
        my $regen=def_image_button('icons/refresh.png','Regenerate testbench.v');
 
 
 
 
 
        #creat modelsim dir
 
 
 
        my $model="$target_dir/Modelsim";
 
        unlink("$model/model.tcl");
 
        rmtree("$target_dir/rtl_work");
 
        mkpath("$model/rtl_work",1,01777);
 
 
 
        my ($app,$table,$tview,$window) = software_main("$target_dir/Modelsim",undef);
        #create testbench.v
        #create testbench.v
        gen_modelsim_soc_testbench ($self,$name,$top,$target_dir) unless (-f "$target_dir/src_verilog/testbench.v");
        gen_modelsim_soc_testbench ($self,$name,$top,$target_dir,$tview) unless (-f "$target_dir/Modelsim/testbench.v");
 
        $app->refresh_source("$target_dir/Modelsim/testbench.v");
 
 
 
 
 
 
        my ($app,$table,$tview,$window) = software_main("$target_dir/src_verilog",'testbench.v');
        add_info($tview,"create Modelsim dir in $target_dir\n");
        $table->attach($back,1,2,1,2,'shrink','shrink',2,2);
        $table->attach($back,1,2,1,2,'shrink','shrink',2,2);
        $table->attach($regen,4,5,1,2,'shrink','shrink',2,2);
        $table->attach($regen,4,5,1,2,'shrink','shrink',2,2);
        $table->attach ($run,9, 10, 1,2,'shrink','shrink',0,0);
        $table->attach ($run,9, 10, 1,2,'shrink','shrink',0,0);
 
 
 
 
 
 
        $regen-> signal_connect("clicked" => sub{
        $regen-> signal_connect("clicked" => sub{
                my $dialog = Gtk2::MessageDialog->new (my $window,
                my $response =  yes_no_dialog("Are you sure you want to regenerate the testbench.v file? Note that any changes you have made will be lost");
                                      'destroy-with-parent',
 
                                      'question', # message type
 
                                      '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");
 
                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,$tview);
                        $app->load_source("$target_dir/src_verilog/testbench.v");
                        $app->refresh_source("$target_dir/Modelsim/testbench.v");
                }
                }
                $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);
 
 
        });
        });
 
 
 
        #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");
 
        my @files = File::Find::Rule->file()
 
                ->name( '*.v','*.V','*.sv' )
 
                ->in( "$target_dir/src_verilog" );
 
 
 
        #get list of all verilog files in src_sim folder 
 
    my @sim_files = File::Find::Rule->file()
 
                ->name( '*.v','*.V','*.sv' )
 
                ->in( "$target_dir/src_sim" );
 
        push (@files, @sim_files);
 
        #add testnemch.v
 
        push (@files, "$target_dir/Modelsim/testbench.v");
 
 
 
        #create a file list
 
        my $tt =create_file_list($target_dir,\@files,'modelsim');
 
        save_file("$target_dir/Modelsim/file_list.f",  "$tt");
 
 
        #creat modelsim dir
 
        add_info(\$tview,"creat Modelsim dir in $target_dir\n");
 
        my $model="$target_dir/Modelsim";
 
        rmtree("$model");
 
        rmtree("$target_dir/rtl_work");
 
        mkpath("$model/rtl_work",1,01777);
 
 
 
        #create modelsim.tcl file
        #create modelsim.tcl file
my $tcl="#!/usr/bin/tclsh
my $tcl="#!/usr/bin/tclsh
 
 
 
 
Line 1150... Line 1885...
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
 
        add_info(\$tview,"Get the list of all verilog files in src_verilog folder\n");
 
        my @files = File::Find::Rule->file()
 
                ->name( '*.v','*.V','*.sv' )
 
                ->in( "$target_dir/src_verilog" );
 
#make sure source files have key word 'module' 
 
        my @sources;
 
        foreach my $p (@files){
 
                my ($name,$path,$suffix) = fileparse("$p",qr"\..[^.]*$");
 
                if(check_file_has_string($p,'module')){
 
                        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";}
 
                }
 
        }
 
 
 
$tcl="$tcl
vlog  +acc=rn  -F $target_dir/Modelsim/file_list.f
 
 
vsim -t 1ps  -L rtl_work -L work -voptargs=\"+acc\"  testbench
vsim -t 1ps  -L rtl_work -L work -voptargs=\"+acc\"  testbench
 
 
add wave *
add wave *
view structure
view structure
view signals
view signals
run -all
run -all
";
";
        add_info(\$tview,"Create run.tcl file\n");
        add_info($tview,"Create model.tcl, run.sh files\n");
        save_file ("$model/run.tcl",$tcl);
        save_file ("$model/model.tcl",$tcl);
 
        my $modelsim_bin= $self->object_get_attribute('compile','modelsim_bin');
 
        my $cmd="cd $target_dir/Modelsim; rm -Rf rtl_work; $modelsim_bin/vsim -do $model/model.tcl";
 
        save_file ("$model/run.sh",'#!/bin/bash'."\n".$cmd);
 
 
        $run -> signal_connect("clicked" => sub{
        $run -> signal_connect("clicked" => sub{
                set_gui_status($self,'save_project',1);
                set_gui_status($self,'save_project',1);
                $app->do_save();
                $app->ask_to_save_changes();
                my $modelsim_bin= $self->object_get_attribute('compile','modelsim_bin');
 
                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();
Line 1201... Line 1925...
 
 
 
 
# 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 {
 
        my ($top_ref,$target_dir,$outtext)=@_;
 
 
 
        my %tops = %{$top_ref};
 
        #creat verilator dir
 
        add_info(\$outtext,"creat verilator dir in $target_dir\n");
 
        my $verilator="$target_dir/verilator";
 
        rmtree("$verilator/rtl_work");
 
        rmtree("$verilator/processed_rtl");
 
        mkpath("$verilator/rtl_work/",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");
 
 
 
 
 
 
sub create_file_list {
 
        my ($target_dir,$files_ref, $platform)=@_;
 
        my @ff=@{$files_ref} if(defined $files_ref);
 
        my $pakages="";
 
        my $file_list="";
 
        my $include="";
 
 
        #copy all verilog files in rtl_work folder
        my %paths;
        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( @ff );
                ->in( @ff );
 
 
 
    @ff =uniq( @ff);
 
 
        foreach my $file (@files) {
        foreach my $file (@files) {
                copy($file,"$verilator/rtl_work/");
                my ($name,$path,$suffix) = fileparse("$file",qr"\..[^.]*$");
 
                #print "$path\n";
 
                my $remove="$target_dir/";
 
                $path =~ s/$remove//;
 
                $paths{$path}=1;
 
 
 
                #put packages at the top of the list 
 
                if(check_file_has_string($file,'endpackage')){
 
                        $pakages.="../${path}${name}$suffix\n" if($platform eq 'modelsim');
 
                        $pakages.="./${name}$suffix\n" if($platform eq 'verilator');
 
                } else{
 
                        $file_list.= "../${path}${name}$suffix\n"if($platform eq 'modelsim');
 
                        $file_list.= "./${name}$suffix\n"if($platform eq 'verilator');
 
                }
 
        }
 
         foreach my $p (sort keys %paths){
 
                $include.="+incdir+../$p\n";
        }
        }
 
 
        @files = File::Find::Rule->file()
        return "$include\n$pakages\n$file_list";
                ->name( '*.sv','*.vh' )
 
            ->in( @ff );
 
        foreach my $file (@files) {
 
                copy($file,"$verilator/processed_rtl");
 
        }
        }
 
 
 
 
 
sub verilator_compilation {
 
        my ($top_ref,$target_dir,$outtext,$cpu_num)=@_;
 
        $cpu_num = 1 if (!defined $cpu_num);
 
        my %tops = %{$top_ref};
 
        #creat verilator dir
 
        add_info($outtext,"create verilator dir in $target_dir\n");
 
        my $verilator="$target_dir/verilator";
 
 
        #"split all verilog modules in separate  files"
        rmtree("$verilator");
        add_info(\$outtext,"split all verilog modules in separate files\n");
        mkpath("$verilator",1,01777);
        my $split = Verilog::EditFiles->new
 
        (outdir => "$verilator/processed_rtl",
 
        translate_synthesis => 0,
 
        celldefine => 0,
 
        );
 
        $split->read_and_split(glob("$verilator/rtl_work/*.v"));
 
        $split->write_files();
 
        $split->read_and_split(glob("$verilator/rtl_work/*.sv"));
 
        $split->write_files();
 
 
 
 
        my @ff = ("$target_dir/src_verilog");
 
        push (@ff,"$target_dir/src_verilator") if (-d "$target_dir/src_verilator");
 
        push (@ff,"$target_dir/src_sim") if (-d "$target_dir/src_sim");
 
 
        #run verilator
        #create a file list
        #my $cmd= "cd \"$verilator/processed_rtl\" \n xterm -e bash -c ' verilator  --cc $name.v --profile-cfuncs --prefix \"Vtop\" -O3  -CFLAGS -O3'";
        add_info($outtext,"make a file list containig all RTL modules\n");
        foreach my $top (sort keys %tops) {
        my $tt =create_file_list($target_dir,\@ff,'verilator');
                add_colored_info(\$outtext,"Generate $top Verilator model from $tops{$top} file\n",'green');
        save_file("$verilator/file_list.f",  "$tt");
                my $cmd= "cd \"$verilator/processed_rtl\" \n  verilator  --cc $tops{$top}  --prefix \"$top\" -O3  -CFLAGS -O3";
 
                add_info(\$outtext,"$cmd\n");
        #check if -Wno-TIMESCALEMOD flag is supported"
 
    my $flag="";
 
 #   my $cmd ="verilator --version | head -n1 | cut -d\" \" -f2";
 
  #     my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
 
 
 
   #    my $current_v=$stdout;
 
   #    $current_v =~ s/[^0-9.]//g;
 
   #    if (defined $current_v){
 
   #            $cmd = "printf \'%s\n\' \"4.0.0\" \"$current_v\" | sort -V | head -n1";
 
   #            my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
 
   #            $stdout =~ s/[^0-9.]//g;
 
   #            if ($stdout eq "4.0.0" ){
 
   #                    add_info($outtext, "Verilator vesrion $current_v is Greater than or equal to 4.0.0. So compile with -Wno-TIMESCALEMOD flag\n");
 
   #                    $flag.="-Wno-TIMESCALEMOD";
 
   #            }else{
 
   #                    add_info($outtext, "Verilator vesrion is $current_v\n");
 
   #            }
 
   #    }
 
  my $pdir        = get_project_dir();
 
  my $tmp = "$pdir/mpsoc/perl_gui/lib/verilog/tmp.v";
 
  my $cmd = "verilator --lint-only $tmp  -Wno-TIMESCALEMOD";
                my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
                my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
                if(length $stderr>1){
 
                        add_info(\$outtext,"$stderr\n");
  if(length $stderr>1){ #-Wno-TIMESCALEMOD not supported                
 
                #add_info($outtext,"$stderr\n"); #verilator compain some ignoerabe warnning as error.  
                }else {
                }else {
                        add_info(\$outtext,"$stdout\n");
                #add_info($outtext,"compile verilator with -Wno-TIMESCALEMOD\n");
                }
                $flag.="-Wno-TIMESCALEMOD";
        }
        }
 
 
 
        #run verilator
        #check if verilator model has been generated 
        my $jobs=0; #a counter to limit the number of paralle process 
 
        my $make_lib="";
 
        $cmd="cd \"$verilator\"; ";
 
        my $vrun="#!/bin/bash
 
cd \"$verilator\"
 
";
 
        #my $cmd= "cd \"$verilator/processed_rtl\" \n xterm -e bash -c ' verilator  --cc $name.v --profile-cfuncs --prefix \"Vtop\" -O3  -CFLAGS -O3'";
 
        my $length = scalar (keys %tops);
        foreach my $top (sort keys %tops) {
        foreach my $top (sort keys %tops) {
                if (-f "$verilator/processed_rtl/obj_dir/$top.cpp"){#succsess
                add_colored_info($outtext,"Generate $top Verilator model from $tops{$top} file\n",'green');
 
                $cmd.= "verilator  -f ./file_list.f --cc $tops{$top}  --prefix \"$top\" $flag -O3  -CFLAGS -O3 & ";
 
                $vrun.="verilator  -f ./file_list.f --cc $tops{$top}  --prefix \"$top\" $flag -O3  -CFLAGS -O3 &\n";
 
 
 
                $make_lib.="make lib$jobs &\n";
 
                $jobs++;
 
 
 
                if( $jobs % $cpu_num == 0 || $jobs == $length){
 
                        $vrun.="wait\n"; $make_lib.="wait\n"; $cmd.="wait\n";
 
                        add_info($outtext,"$cmd\n");
 
                        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
 
                        if(length $stderr>1){
 
                                add_info($outtext,"$stderr\n"); #verilator compain some ignoerabe warnning as error.  
                }else {
                }else {
                        return 0;
                                add_info($outtext,"$stdout\n");
                }
 
        }
        }
        #generate makefile
                        $cmd="cd \"$verilator\"; ";
        gen_verilator_makefile($top_ref,"$verilator/processed_rtl/obj_dir/Makefile");
 
        return 1;
 
}
}
 
 
 
 
sub gen_verilator_makefile{
 
        my ($top_ref,$target_dir) =@_;
 
        my %tops = %{$top_ref};
 
        my $p='';
 
        my $q='';
 
        my $h='';
 
        my $l;
 
        my $lib_num=0;
 
        my $all_lib="";
 
        foreach my $top (sort keys %tops) {
 
                $p = "$p ${top}__ALL.a ";
 
                $q = $q."lib$lib_num:\n\t\$(MAKE) -f ${top}.mk\n";
 
                $h = "$h ${top}.h ";
 
                $l = $top;
 
                $all_lib=$all_lib." lib$lib_num";
 
                $lib_num++;
 
        }
        }
 
 
 
 
        my $make= "
 
 
 
default: sim
 
 
 
 
 
 
        #check if verilator model has been generated 
 
        foreach my $top (sort keys %tops) {
 
 
include $l.mk
                $vrun.="
 
if ! [ -f $verilator/obj_dir/$top.cpp ]; then
 
        echo  \"Failed to generate: $verilator/obj_dir/$top.cpp \"
 
        exit 1
 
fi
 
";
 
 
lib: $all_lib
                if (-f "$verilator/obj_dir/$top.cpp"){#succsess
 
 
$q
 
 
 
 
                }else {
 
                        return 0;
 
                }
 
        }
 
        #generate makefile
 
        gen_verilator_makefile($top_ref,"$verilator/obj_dir/Makefile");
 
 
#######################################################################
$vrun.="        echo  \"Verilator modules are generated successfully\".
# Compile flags
 
 
 
CPPFLAGS += -DVL_DEBUG=1
cd $verilator/obj_dir/
ifeq (\$(CFG_WITH_CCWARN),yes)  # Local... Else don't burden users
 
CPPFLAGS += -DVL_THREADED=1
 
CPPFLAGS += -W -Werror -Wall
 
endif
 
 
 
#######################################################################
#run make file
# Linking final exe -- presumes have a sim_main.cpp
$make_lib
 
 
 
make sim
 
#done
 
";
 
 
sim:    testbench.o \$(VK_GLOBAL_OBJS) $p
 
        \$(LINK) \$(LDFLAGS) -g \$^ \$(LOADLIBES) \$(LDLIBS) -o testbench \$(LIBS) -Wall -O3 2>&1 | c++filt
 
 
 
testbench.o: testbench.cpp $h
        save_file ("$verilator/verilate.sh",$vrun);
 
        #copy topology connection header files
 
        my $project_dir = get_project_dir();
 
        $project_dir= "$project_dir/mpsoc";
 
        my $src_verilator_dir="$project_dir/src_verilator";
 
        my @files = File::Find::Rule->file()
 
                ->name( '*.h')
 
            ->in( "$src_verilator_dir" );
 
        copy_file_and_folders (\@files,$project_dir,"$verilator/obj_dir/");
 
 
clean:
        return 1;
        rm *.o *.a testbench
}
";
 
 
 
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,$vendor)=@_;
        my $window = def_popwin_size(80,80,"Step 2: Compile",'percent');
        my $window = def_popwin_size(80,80,"Step 2: Compile",'percent');
        my $mtable = def_table(10, 10, FALSE);
        my $mtable = def_table(10, 10, FALSE);
        my ($outbox,$outtext)= create_text();
        my ($outbox,$outtext)= create_txview();
 
 
 
 
        my $next=def_image_button('icons/run.png','Next');
        my $next=def_image_button('icons/run.png','Next');
        my $back=def_image_button('icons/left.png','Previous');
        my $back=def_image_button('icons/left.png','Previous');
        my $load= show_gif("icons/load.gif");
        my $load= show_gif("icons/load.gif");
Line 1366... Line 2122...
 
 
        });
        });
        $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,$vendor);
 
 
        });
        });
 
 
        $window->add ($mtable);
        $window->add ($mtable);
        $window->show_all();
        $window->show_all();
 
 
 
 
        my $result;
        my $result;
 
        my $cpu_num = $self->object_get_attribute('compile', 'cpu_num');
 
 
        my $n= $self->object_get_attribute('soc_name',undef);
        my $n= $self->object_get_attribute('soc_name',undef);
        if(defined $n){ #we are compiling a single tile as SoC
        if(defined $n){ #we are compiling a single tile as SoC
 
                my $sw_path     = "$target_dir/sw";
 
                my %params = soc_get_all_parameters($self);
 
                my $verilator = soc_generate_verilator ($self,$sw_path,"verilator_$n",\%params);
                my %tops;
                my %tops;
                $tops{"Vtop"}= "$name.v";
                $tops{"Vtop"}= "--top-module verilator_$n";
                $result = verilator_compilation (\%tops,$target_dir,$outtext);
                my $target_verilator_dr ="$target_dir/src_verilator";
 
        mkpath("$target_verilator_dr",1,01777);
 
        save_file ("$target_verilator_dr/verilator_${n}.sv",$verilator);
 
 
 
 
 
 
 
 
 
 
 
                #$tops{"Vtop"}= "--top-module $name";
 
                $result = verilator_compilation (\%tops,$target_dir,$outtext,$cpu_num);
                $self->object_add_attribute('verilator','libs',\%tops);
                $self->object_add_attribute('verilator','libs',\%tops);
        }
        }
        else { # we are compiling a complete NoC-based mpsoc
        else { # we are compiling a complete NoC-based mpsoc
                $result = gen_mpsoc_verilator_model ($self,$name,$top,$target_dir,$outtext);
                $result = gen_mpsoc_verilator_model ($self,$name,$top,$target_dir,$outtext,$cpu_num);
 
 
 
 
        }
        }
 
 
 
 
        #check if verilator model has been generated 
        #check if verilator model has been generated 
        if ($result){
        if ($result){
                add_colored_info(\$outtext,"Veriator model has been generated successfully!",'blue');
                add_colored_info($outtext,"Veriator model has been generated successfully!",'blue');
                $load->destroy();
                $load->destroy();
                $mtable->attach($next,8,9,9,10,'shrink','shrink',2,2);
                $mtable->attach($next,8,9,9,10,'shrink','shrink',2,2);
        }else {
        }else {
                add_colored_info(\$outtext,"Verilator compilation failed!\n","red");
                add_colored_info($outtext,"Verilator compilation failed!\n","red");
                $load->destroy();
                $load->destroy();
                $next->destroy();
                $next->destroy();
        }
        }
}
}
 
 
 
 
 
 
 
 
 
 
sub  gen_mpsoc_verilator_model{
sub  gen_mpsoc_verilator_model{
        my ($self,$name,$top,$target_dir,$outtext)=@_;
        my ($self,$name,$top,$target_dir,$outtext,$cpu_num)=@_;
        my $dir = Cwd::getcwd();
 
        my $project_dir   = abs_path("$dir/..");
        my $project_dir = get_project_dir();
 
        $project_dir= "$project_dir/mpsoc";
        my $src_verilator_dir="$project_dir/src_verilator";
        my $src_verilator_dir="$project_dir/src_verilator";
        my $target_verilog_dr ="$target_dir/src_verilog";
        my $target_verilog_dr ="$target_dir/src_verilog";
        my $target_verilator_dr ="$target_dir/src_verilator";
        my $target_verilator_dr ="$target_dir/src_verilator";
 
 
        my $sw_dir      = "$target_dir/sw";
        my $sw_dir      = "$target_dir/sw";
        my $src_noc_dir="$project_dir/src_noc";
        my $src_noc_dir="$project_dir/rtl/src_noc";
        mkpath("$target_verilator_dr",1,01777);
        mkpath("$target_verilator_dr",1,01777);
 
 
        #copy src_verilator files
        #copy src_verilator files
        my @files_list = File::Find::Rule->file()
        my @files_list = File::Find::Rule->file()
                            ->name( '*.v','*.V','*.sv' )
                            ->name( '*.v','*.V','*.sv' )
Line 1455... Line 2225...
        $noc_param
        $noc_param
 
 
        //simulation parameter
        //simulation parameter
 
 
\n \n \`endif" ;
\n \n \`endif" ;
        save_file("$target_verilator_dr/parameter.v",$noc_param_v);
        #save_file("$target_verilator_dr/parameter.v",$noc_param_v);
 
 
 
 
 
 
 
 
    my ($nr,$ne,$router_p,$ref_tops)= get_noc_verilator_top_modules_info($self);
    my ($nr,$ne,$router_p,$ref_tops)= get_noc_verilator_top_modules_info($self);
Line 1487... Line 2257...
                $y{'EAw'} = $EAw;
                $y{'EAw'} = $EAw;
                $y{'RAw'} = $RAw;
                $y{'RAw'} = $RAw;
                $y{'Fw'}  = $Fw;
                $y{'Fw'}  = $Fw;
                my @nis=get_NI_instance_list($top);
                my @nis=get_NI_instance_list($top);
                $soc->soc_add_instance_param($nis[0] ,\%y );
                $soc->soc_add_instance_param($nis[0] ,\%y );
 
                my %z;
 
 
 
                my %param_type=  $soc->soc_get_module_param_type($nis[0]);
 
                foreach my $p (sort keys %y){
 
                        $z{$p}=$param_type{$p}; #"Parameter";
 
                }
 
 
 
 
 
 
 
 
 
                $soc->soc_add_instance_param_type($nis[0] ,\%z );
 
 
 
 
                my $tile=$tile_num;
                my $tile=$tile_num;
                my $setting=$mpsoc->mpsoc_get_tile_param_setting($tile);
                my $setting=$mpsoc->mpsoc_get_tile_param_setting($tile);
                my %params;
                my %params;
                if ($setting eq 'Custom'){
                #if ($setting eq 'Custom'){
                         %params= $top->top_get_custom_soc_param($tile);
                         %params= $top->top_get_custom_soc_param($tile);
                }else{
                #}else{
                         %params=$top->top_get_default_soc_param();
                #        %params=$top->top_get_default_soc_param();
                }
                #}
 
 
 
 
                my $sw_path     = "$sw_dir/tile$tile_num";
                my $sw_path     = "$sw_dir/tile$tile_num";
                $verilator = $verilator.soc_generate_verilatore ($soc,$sw_path,"tile_$tile",\%params);
                $verilator = $verilator.soc_generate_verilator ($soc,$sw_path,"tile_$tile",\%params);
                $tops{"Vtile$tile_num"}= "tile_$tile.v";
                $tops{"Vtile$tile_num"}= "--top-module tile_$tile";
 
 
 
 
        }
        }
 
 
        save_file ("$target_verilator_dr/verilator_tiles.v",$verilator);
        save_file ("$target_verilator_dr/verilator_tiles.sv",$verilator);
        my $result = verilator_compilation (\%tops,$target_dir,$outtext);
        my $result = verilator_compilation (\%tops,$target_dir,$outtext,$cpu_num);
        $self->object_add_attribute('verilator','libs',\%tops);
        $self->object_add_attribute('verilator','libs',\%tops);
        return $result;
        return $result;
 
 
}
}
 
 
Line 1519... Line 2301...
        my ($self,$name,$top,$target_dir)=@_;
        my ($self,$name,$top,$target_dir)=@_;
        my $verilator="$target_dir/verilator";
        my $verilator="$target_dir/verilator";
        my $dir="$verilator/";
        my $dir="$verilator/";
        my $soc_top= $self->soc_get_top ();
        my $soc_top= $self->soc_get_top ();
 
 
 
        my $include='#include <stdlib.h>
 
#include <stdio.h>
 
#include <unistd.h>
 
#include <string.h>
 
';
        my @intfcs=$soc_top->top_get_intfc_list();
        my @intfcs=$soc_top->top_get_intfc_list();
        my %PP;
        my %PP;
 
        my %rxds;
        my $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' :
 
                         ( $intfc eq  'socket:RxD_sim[0]')? 'rxd':
 
                         'other';
 
 
 
 
                my $key1="${key}1";
                my $key1="${key}1";
                my $key0="${key}0";
                my $key0="${key}0";
 
 
                my @ports=$soc_top->top_get_intfc_ports_list($intfc);
                my @ports=$soc_top->top_get_intfc_ports_list($intfc);
                foreach my $p (@ports){
                foreach my $p (@ports){
                        my($inst,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
                        my($inst,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
                        $PP{$key1}= (defined $PP{$key1})? "$PP{$key1} top->$p=1;\n" : "top->$p=1;\n";
                        $PP{$key1}= (defined $PP{$key1})? "$PP{$key1} top->$p=1;\n" : "top->$p=1;\n";
                        $PP{$key0}= (defined $PP{$key0})? "$PP{$key0} top->$p=0;\n" : "top->$p=0;\n";
                        $PP{$key0}= (defined $PP{$key0})? "$PP{$key0} top->$p=0;\n" : "top->$p=0;\n";
                        $top_port_info="$top_port_info $type  $range  top->$p \n";
                        $top_port_info="$top_port_info $type  $range  top->$p \n";
                }
                }
 
                if($key eq 'rxd'){
 
                        my @ports=$soc_top->top_get_intfc_ports_list($intfc);
 
                        foreach my $p (@ports){
 
                                my($id,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
 
                                my @q =split  (/RxD_ready_si/,$p);
 
                                $rxds{$id}{p}=$q[0]  if( defined $q[1]);
 
                                $rxds{$id}{top}='top'  if( defined $q[1]);
 
                        }
 
                }
 
 
        }
        }
 
 
 
 
 
 my ($rxd_info, $rxd_num, $rxd_wr_cal,$rxd_cap_cal, $include1)=rxd_testbench_verilator_gen (\%rxds,$dir);
 
 my $include2="";
 
 $include2 .= '#include "RxDsim.h" // Header file for sending charactor to UART from STDIN' if($rxd_num > 0);
 
 
        my $main_c=get_license_header("testbench.cpp");
        my $main_c=get_license_header("testbench.cpp");
 
 
 
 
 
 
$main_c="$main_c
$main_c="$main_c
#include <stdlib.h>
$include
#include <stdio.h>
$include1
#include <unistd.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;
 
$include2
/*
/*
$top_port_info
$top_port_info
*/
*/
 
 
 
 
 
 
int reset,clk;
int reset,clk;
unsigned int main_time = 0; // Current simulation time
unsigned int main_time = 0; // Current simulation time
 
 
int main(int argc, char** argv) {
int main(int argc, char** argv) {
 
        $rxd_info
        Verilated::commandArgs(argc, argv);   // Remember args
        Verilated::commandArgs(argc, argv);   // Remember args
        top     = new Vtop;
        top     = new Vtop;
 
 
        /********************
        /********************
        *       initialize input
        *       initialize input
Line 1569... Line 2379...
        $PP{reset1}
        $PP{reset1}
        $PP{en1}
        $PP{en1}
        main_time=0;
        main_time=0;
        printf(\"Start Simulation\\n\");
        printf(\"Start Simulation\\n\");
        while (!Verilated::gotFinish()) {
        while (!Verilated::gotFinish()) {
 
                $rxd_cap_cal
 
            if ((main_time & 0x3FF)==0) fflush(stdout); // fflush \$dispaly command each 1024 clock cycle
                if (main_time >= 10 ) {
                if (main_time >= 10 ) {
                        $PP{reset0}
                        $PP{reset0}
                }
                }
 
 
 
 
                if ((main_time & 1) == 0) {
                if ((main_time & 1) == 0) {
                        $PP{clk1}      // Toggle clock
                        $PP{clk1}      // Toggle clock
                        // you can change the inputs and read the outputs here in case they are captured at posedge of clock
                        // you can change the inputs and read the outputs here in case they are captured at posedge of clock
 
                        $rxd_wr_cal
 
 
 
 
                }//if
                }//if
                else
                else
                {
                {
Line 1614... Line 2425...
        my $path=$mpsoc->object_get_attribute('setting','soc_path');
        my $path=$mpsoc->object_get_attribute('setting','soc_path');
        $path=~ s/ /\\ /g;
        $path=~ s/ /\\ /g;
        my $p = "$path/$soc_name.SOC";
        my $p = "$path/$soc_name.SOC";
        my ($soc,$r,$err) = regen_object($p);
        my ($soc,$r,$err) = regen_object($p);
        if ($r){
        if ($r){
                show_info(\$outtext,"**Error reading  $p file: $err\n");
                show_info($outtext,"**Error reading  $p file: $err\n");
               next;
               next;
        }
        }
        return $soc;
        return $soc;
}
}
 
 
 
sub rxd_testbench_verilator_gen {
 
my      ($rxds_ref,$dir)=@_;
 
 
 
my $rxd_info='';
 
my $rxd_num=0;
 
my $rxd_func='';
 
my $rxd_wr_cal='';
 
my $rxd_cap_cal='';
 
my $include='';
 
 
 
my %rxds=%{$rxds_ref};
 
 
 
foreach my $rxd (sort keys %rxds){
 
        my $n=$rxds{$rxd}{p};
 
        my $top=$rxds{$rxd}{top};
 
        $rxd_info.="\\t$rxd_num : ${top}_${n}RXD\\n";
 
 
 
        $rxd_func.="
 
        // we have a character to send to interface $rxd_num
 
        if (sent_table[$rxd_num]!=0 &&  $top->${n}RxD_ready_sim){
 
                $top->${n}RxD_din_sim=sent_table[$rxd_num];
 
        $top->${n}RxD_wr_sim=1;
 
        sent_table[$rxd_num]=0;
 
        }else {
 
                $top->${n}RxD_wr_sim=0;
 
        }
 
";
 
        $rxd_num++;
 
}
 
 
 
 
 
 
 
if($rxd_num>0){
 
$rxd_func="
 
#ifndef RXD_SIM_H
 
#define RXD_SIM_H
 
        #define RXD_NUM  $rxd_num  // number of rxd input interfaces
 
        char sent_table[RXD_NUM]={0};
 
        unsigned char active_rxd_num=0;
 
        void write_char_on_RXD( ) {
 
                $rxd_func
 
        }
 
 
 
        int kbhit(void) {
 
          struct termios oldt, newt;
 
          int ch;
 
          int oldf;
 
 
 
          tcgetattr(STDIN_FILENO, &oldt);
 
          newt = oldt;
 
          newt.c_lflag &= ~(ICANON | ECHO);
 
          tcsetattr(STDIN_FILENO, TCSANOW, &newt);
 
          oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
 
          fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
 
 
 
          ch = getchar();
 
 
 
          tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
 
          fcntl(STDIN_FILENO, F_SETFL, oldf);
 
 
 
          if(ch != EOF)
 
          {
 
            ungetc(ch, stdin);
 
            return 1;
 
          }
 
          return 0;
 
        }
 
 
 
        void capture_char_on_RXD (){
 
                char c;
 
                if(kbhit()){
 
                        c=getchar();
 
                        if(c=='+'){
 
                                active_rxd_num++;
 
                                if(active_rxd_num>=$rxd_num) active_rxd_num=0;
 
                                printf(\"The active input interface num is \%u\\n\",active_rxd_num);
 
                        }else if(c=='-'){
 
                                active_rxd_num--;
 
                                if(active_rxd_num>=$rxd_num) active_rxd_num=($rxd_num-1);
 
                                printf(\"The active input interface num is \%u\\n\",active_rxd_num);
 
                        }else{
 
                                sent_table[active_rxd_num]=c;
 
                        }
 
 
 
                }
 
        }
 
#endif
 
        ";
 
 
 
 
 
        $include .='#include <termios.h>
 
#include <fcntl.h>
 
';
 
        $rxd_wr_cal="write_char_on_RXD( );";
 
        $rxd_cap_cal="capture_char_on_RXD( );";
 
        $rxd_info="printf(\"There are total of $rxd_num RXD (UART) interface ports in the top module:\\n${rxd_info}The default interfce is 0. You can switch to different interfaces by pressing + or - key.\\n\");"
 
}
 
 
 
        my $rxsim_c=get_license_header("RxDsim.h");
 
        $rxsim_c.="$rxd_func";
 
        save_file("$dir/RxDsim.h",$rxsim_c) if($rxd_num > 0);
 
 
 
        return ($rxd_info, $rxd_num, $rxd_wr_cal,$rxd_cap_cal, $include);
 
 
 
}
 
 
 
 
 
 
sub gen_verilator_mpsoc_testbench {
sub gen_verilator_mpsoc_testbench {
        my ($mpsoc,$name,$top,$target_dir,$tview)=@_;
        my ($mpsoc,$name,$top,$target_dir,$tview)=@_;
        my $verilator="$target_dir/verilator";
        my $verilator="$target_dir/verilator";
        my $dir="$verilator/";
        my $dir="$verilator/";
        my $parameter_h=gen_noc_param_h($mpsoc);
        my $parameter_h=gen_noc_param_h($mpsoc);
 
 
 
 
        my ($nr,$ne,$router_p,$ref_tops,$includ_h)= get_noc_verilator_top_modules_info($mpsoc);
        my ($nr,$ne,$router_p,$ref_tops,$includ_h)= get_noc_verilator_top_modules_info($mpsoc);
 
 
 
        $parameter_h.="
 
        #define NE  $ne
 
        #define NR  $nr
 
        ";
        $parameter_h=$parameter_h.$includ_h;
        $parameter_h=$parameter_h.$includ_h;
 
 
 
 
 
 
        my $libh="";
        my $libh="";
Line 1654... Line 2578...
        my $tile_reset="";
        my $tile_reset="";
        my $tile_clk="";
        my $tile_clk="";
        my $tile_en="";
        my $tile_en="";
        my $top_port_info="IO type\t  port_size\t  port_name\n";
        my $top_port_info="IO type\t  port_size\t  port_name\n";
        my $no_connected='';
        my $no_connected='';
 
        my %rxds;
 
 
 
        my $tile_chans="";
 
        my $tmp_reg='';
        for (my $endp=0; $endp<$ne;$endp++){
        for (my $endp=0; $endp<$ne;$endp++){
 
 
 
 
                my $e_addr=endp_addr_encoder($mpsoc,$endp);
                my $e_addr=endp_addr_encoder($mpsoc,$endp);
                my $router_num = get_connected_router_id_to_endp($mpsoc,$endp);
                my $router_num = get_connected_router_id_to_endp($mpsoc,$endp);
                my $r_addr=router_addr_encoder($mpsoc,$router_num);
                my $r_addr=router_addr_encoder($mpsoc,$router_num);
 
 
 
 
Line 1678... Line 2606...
                                        if ($category eq 'NoC') {
                                        if ($category eq 'NoC') {
                                                 $ni_name=  $soc->soc_get_instance_name($id);
                                                 $ni_name=  $soc->soc_get_instance_name($id);
                                        }
                                        }
                        }
                        }
 
 
 
                                $tile_chans.="\ttile_chan_out[$endp] = &tile$endp->ni_chan_out;\n\ttile_chan_in[$endp] = &tile$endp->ni_chan_in;\n";
                                $libh=$libh."#include \"Vtile${endp}.h\"\n";
                                $libh=$libh."#include \"Vtile${endp}.h\"\n";
                                $inst=$inst."Vtile${endp}\t*tile${endp};\t  // Instantiation of tile${endp}\n";
                                $inst=$inst."Vtile${endp}\t*tile${endp};\t  // Instantiation of tile${endp}\n";
                                $newinst = $newinst."\ttile${endp}\t=\tnew Vtile${endp};\n";
                                $newinst = $newinst."\ttile${endp}\t=\tnew Vtile${endp};\n";
                                $tile_flit_in = $tile_flit_in . "\ttile${endp}->${ni_name}_flit_in  = noc->ni_flit_out [${endp}];\n";
                                $tile_flit_in = $tile_flit_in . "\ttile${endp}->${ni_name}_flit_in  = noc->ni_flit_out [${endp}];\n";
                                $tile_flit_in_l = $tile_flit_in_l . "\t\ttile${endp}->${ni_name}_flit_in[j]  = noc->ni_flit_out [${endp}][j];\n";
                                $tile_flit_in_l = $tile_flit_in_l . "\t\ttile${endp}->${ni_name}_flit_in[j]  = noc->ni_flit_out [${endp}][j];\n";
Line 1700... Line 2628...
 
 
                                foreach my $intfc (@intfcs){
                                foreach my $intfc (@intfcs){
                                        my $key=($intfc eq 'plug:clk[0]')? 'clk' :
                                        my $key=($intfc eq 'plug:clk[0]')? 'clk' :
                                                         ($intfc eq 'plug:reset[0]')? 'reset':
                                                         ($intfc eq 'plug:reset[0]')? 'reset':
                                                         ($intfc eq 'plug:enable[0]')? 'en' :
                                                         ($intfc eq 'plug:enable[0]')? 'en' :
 
                                                         ($intfc eq 'socket:RxD_sim[0]')? 'rxd':
                                                         'other';
                                                         'other';
 
 
                                        my @ports=$soc_top->top_get_intfc_ports_list($intfc);
                                        my @ports=$soc_top->top_get_intfc_ports_list($intfc);
                                        foreach my $p (@ports){
                                        foreach my $p (@ports){
                                                my($inst,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
                                                my($inst,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
Line 1711... Line 2640...
                                                $tile_clk=$tile_clk."\t\ttile${endp}->$p=clk;\n" if $key eq 'clk';
                                                $tile_clk=$tile_clk."\t\ttile${endp}->$p=clk;\n" if $key eq 'clk';
                                                $tile_en=$tile_en."\t\ttile${endp}->$p=enable;\n" if $key eq 'en';      ;
                                                $tile_en=$tile_en."\t\ttile${endp}->$p=enable;\n" if $key eq 'en';      ;
                                                $top_port_info="$top_port_info $type  $range  tile${endp}->$p \n";
                                                $top_port_info="$top_port_info $type  $range  tile${endp}->$p \n";
                                        }#ports
                                        }#ports
 
 
 
                                        if($key eq 'rxd'){
 
                                                my @ports=$soc_top->top_get_intfc_ports_list($intfc);
 
                                                foreach my $p (@ports){
 
                                                        my($id,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
 
                                                        my @q =split  (/RxD_ready_si/,$p);
 
                                                        $rxds{$endp.$id}{p}=$q[0]  if( defined $q[1]);
 
                                                        $rxds{$endp.$id}{top}="tile$endp"  if( defined $q[1]);
 
                                                }
 
                                        }
 
 
 
 
                                }#interface
                                }#interface
 
 
                                $tile_addr= $tile_addr."\ttile${endp}->${ni_name}_current_r_addr=$r_addr; // noc->er_addr[${endp}];\n";
                                $tile_addr= $tile_addr."\ttile${endp}->${ni_name}_current_r_addr=$r_addr; // noc->er_addr[${endp}];\n";
                                $tile_addr= $tile_addr."\ttile${endp}->${ni_name}_current_e_addr=$e_addr;\n";
                                $tile_addr= $tile_addr."\ttile${endp}->${ni_name}_current_e_addr=$e_addr;\n";
 
 
                        }else{
                        }else{
                                #this tile is not connected to any ip. the noc input ports will be connected to ground
                                #this tile is not connected to any ip. the noc input ports will be connected to ground
                                $no_connected=$no_connected."\n // Tile:$endp ($e_addr)   is not assigned to any ip\n";
                                $tmp_reg.="\tunsigned char tmp1 [1024]={0};\n \tunsigned char tmp2 [1024]={0};";
                                $no_connected=$no_connected."\t\tnoc->ni_credit_in[${endp}]=0; \n";
                                $tile_chans.="\n // Tile:$endp ($e_addr)   is not assigned to any ip. Connet coresponding chan to ground.\n";
 
                                $tile_chans.="\ttile_chan_out[$endp] = tmp1;\n\ttile_chan_in[$endp] = tmp2;\n";
 
 
                        }
                        }
 
 
 
 
        }
        }
 
 
 
        my ($rxd_info, $rxd_num, $rxd_wr_cal,$rxd_cap_cal, $include1)=rxd_testbench_verilator_gen (\%rxds,$dir);
 
        my $include2="";
 
        $include2 .= '#include "RxDsim.h" // Header file for sending charactor to UART from STDIN' if($rxd_num > 0);
 
 
        my $main_c=get_license_header("testbench.cpp");
        my $main_c=get_license_header("testbench.cpp");
 
 
$main_c="$main_c
$main_c="$main_c
#include <stdlib.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>
#include <unistd.h>
#include <unistd.h>
#include <string.h>
#include <string.h>
 
$include1
#include <verilated.h>          // Defines common routines
#include <verilated.h>          // Defines common routines
 
$tmp_reg
 
 
 
 
#include \"Vnoc.h\"
 
$libh
$libh
 
 
Vnoc                    *noc;
 
$inst
$inst
int reset,clk,enable;
int reset,clk,enable;
 
 
 
 
#include \"parameter.h\"
#include \"parameter.h\"
 
void * tile_chan_out[NE];
 
void * tile_chan_in[NE];
 
 
 
 
/*
 
$top_port_info
 
*/
 
 
 
 
 
unsigned int main_time = 0; // Current simulation time
 
 
 
void update_all_instances_inputs(void);
 
 
 
 
 
int main(int argc, char** argv) {
 
        int i,j,x,y;
 
 
 
        Verilated::commandArgs(argc, argv);   // Remember args
 
        Vrouter_new();             // Create instance
 
        noc                                                             = new Vnoc;
 
$newinst
 
 
 
        /********************
 
        *       initialize input
 
        *********************/
 
 
 
 
 
        reset=1;
#define CHAN_SIZE   sizeof(tile0->ni_chan_in)
        enable=1;
 
        $no_connected
 
 
 
$tile_addr
#define conect_r2r(T1,r1,p1,T2,r2,p2)  \\
 
        memcpy(&router##T1 [r1]->chan_in[p1] , &router##T2 [r2]->chan_out[p2], CHAN_SIZE )
 
 
 
#define connect_r2gnd(T,r,p)\\
 
        memset(&router##T [r]->chan_in [p],0x00,CHAN_SIZE)
 
 
        main_time=0;
#define connect_r2e(T,r,p,e) \\
        printf(\"Start Simulation\\n\");
        memcpy(&router##T [r]->chan_in[p], tile_chan_out[e], CHAN_SIZE );\\
        while (!Verilated::gotFinish()) {
        memcpy(tile_chan_in[e], &router##T [r]->chan_out[p], CHAN_SIZE )
 
 
                if (main_time >= 10 ) {
 
                        reset=0;
 
                }
 
 
 
 
 
                if ((main_time % 5) == 0) {
#include \"topology_top.h\"
                        clk = 1;       // Toggle clock
$include2
                        // you can change the inputs and read the outputs here in case they are captured at posedge of clock
 
 
 
                }
/*
                else{
$top_port_info
                        clk = 0;       // Toggle clock
*/
                        update_all_instances_inputs();
 
 
 
 
 
 
unsigned int main_time = 0; // Current simulation time
 
 
                }
 
 
 
 
 
 
void connect_clk_reset_en_all(void){
                //clk,reset,enable
                //clk,reset,enable
                noc-> clk = clk;
 
                noc-> reset = reset;
 
$tile_reset
$tile_reset
$tile_clk
$tile_clk
$tile_en
$tile_en
 
 
        connect_routers_reset_clk();
        connect_routers_reset_clk();
 
}
 
 
                //eval instances
void sim_eval_all(void){
                noc->eval();
 
                routers_eval();
                routers_eval();
 
 
$tile_eval
$tile_eval
 
}
 
 
 
void sim_final_all(void ){
                main_time++;
 
 
 
 
 
 
 
        }//while
 
 
 
        // Simulation is done
 
        routers_final();
        routers_final();
        noc->final();
 
$tile_final
$tile_final
}
}
 
 
double sc_time_stamp () {       // Called by \$time in Verilog
void clk_posedge_event(void) {
        return main_time;
 
}
 
 
 
 
        clk = 1;       // Toggle clock
 
        // you can change the inputs and read the outputs here in case they are captured at posedge of clock
 
        $rxd_wr_cal
 
        connect_clk_reset_en_all();
 
        sim_eval_all();
 
}
 
 
void update_all_instances_inputs(void){
 
 
 
        int x,y,i,j;
void clk_negedge_event(void){
 
 
 
        clk = 0;
 
        topology_connect_all_nodes ();
 
        connect_clk_reset_en_all();
 
        sim_eval_all();
 
}
 
 
#if (NC<=64)
 
        noc->ni_flit_in_wr =0;
 
#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;
 
#endif
 
 
 
        connect_all_routers_to_noc ();
int main(int argc, char** argv) {
 
        int i,j,x,y;
 
        $rxd_info
 
        Verilated::commandArgs(argc, argv);   // Remember args
 
        Vrouter_new();             // Create instance
 
 
 
$newinst
 
 
#if (Fpay<=32)
        /********************
        //tile[i]->flit_in  = noc->ni_flit_out [i];
        *       initialize input
$tile_flit_in
        *********************/
#else
        $tile_chans
        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];
 
$tile_flit_in_l
 
        }
 
#endif
 
 
 
        //traffic[i]->credit_in= noc->ni_credit_out[i];
        reset=1;
$tile_credit
        enable=1;
 
        topology_init();
 
 
        //noc->ni_credit_in[i] = traffic[i]->credit_out;
        $no_connected
$noc_credit
 
 
 
#if (Fpay<=32)
$tile_addr
        //noc->ni_flit_in [i]  = traffic[i]->flit_out;
 
$noc_flit_in
 
 
 
#else
 
        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_flit_in_l
 
        }
 
#endif
 
 
 
 
 
#if (NC<=64)
        main_time=0;
                //if(traffic[i]->flit_out_wr) noc->ni_flit_in_wr = noc->ni_flit_in_wr | ((vluint64_t)1<<i);
        printf(\"Start Simulation\\n\");
$noc_flit_in_wr
        while (!Verilated::gotFinish()) {
 
            $rxd_cap_cal
                //traffic[i]->flit_in_wr= ((noc->ni_flit_out_wr >> i) & 0x01);
            if ((main_time & 0x3FF)==0) fflush(stdout); // fflush \$dispaly command each 1024 clock cycle
$tile_flit_in_wr
                if (main_time >= 10 )   reset=0;
#else
 
                //if(traffic[i]->flit_out_wr) MY_VL_SETBIT_W(noc->ni_flit_in_wr ,i);
                clk_posedge_event( );
$noc_flit_in_wr_l
                //The valus of all registers and input ports valuse change @ posedge of the clock. Once clk is deasserted,  as multiple modules are connected inside the testbench we need several eval for propogating combinational logic values
 
                //between modules when the clock .
 
                for (i=0;i<2*(SMART_MAX+1);i++) clk_negedge_event( );
 
 
                //traffic[i]->flit_in_wr=   (VL_BITISSET_W(noc->ni_flit_out_wr,i)>0);
                main_time++;
$tile_flit_in_wr_l
        }//while
 
 
#endif
        // Simulation is done
 
        sim_final_all();
 
}
 
 
 
double sc_time_stamp () {       // Called by \$time in Verilog
 
        return main_time;
 
}
 
 
 
 
}
 
";
";
 
 
        save_file("$dir/parameter.h",$parameter_h);
        save_file("$dir/parameter.h",$parameter_h);
        save_file("$dir/testbench.cpp",$main_c);
        save_file("$dir/testbench.cpp",$main_c);
 
 
Line 1911... Line 2825...
 
 
                my $module      =$soc->soc_get_module($id);
                my $module      =$soc->soc_get_module($id);
                my $category    =$soc->soc_get_category($id);
                my $category    =$soc->soc_get_category($id);
                my $inst        = $soc->soc_get_instance_name($id);
                my $inst        = $soc->soc_get_instance_name($id);
                my %params      = $soc->soc_get_module_param($id);
                my %params      = $soc->soc_get_module_param($id);
 
                my %params_type = $soc->soc_get_module_param_type($id);
                my $ip = ip->lib_new ();
                my $ip = ip->lib_new ();
                my @param_order=$soc->soc_get_instance_param_order($id);
                my @param_order=$soc->soc_get_instance_param_order($id);
 
 
                foreach my $p (sort keys %params){
                foreach my $p (sort keys %params){
                        my $inst_param= "$inst\_$p";
                        my $inst_param= "$inst\_$p";
                        #add instance name to parameter value
                        #add instance name to parameter value
                        $params{$p}=add_instantc_name_to_parameters(\%params,$inst,$params{$p});
                        $params{$p}=add_instantc_name_to_parameters(\%params,$inst,$params{$p});
                        my ($default,$type,$content,$info,$vfile_param_type,$redefine_param)= $ip->ip_get_parameter($category,$module,$p);
                        my ($default,$type,$content,$info,$vfile_param_type,$redefine_param)= $ip->ip_get_parameter($category,$module,$p);
 
 
                        $vfile_param_type= "Don't include" if (!defined $vfile_param_type );
                        $vfile_param_type= "Don't include" if (!defined $vfile_param_type );
                        $vfile_param_type= "Parameter"  if ($vfile_param_type eq 1);
                        if ($vfile_param_type eq "Localparam"){
                        $vfile_param_type= "Localparam" if ($vfile_param_type eq 0);
                                my $type = $params_type{$p};
 
                                $type = "Localparam" if (! defined $type);
 
                                $vfile_param_type = ($type eq 'Parameter')?  "Parameter" : "Localparam";
 
                        }
 
 
 
                        #$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"  );
                        $all_param{ $inst_param} =      $params{ $p} if($vfile_param_type eq "Parameter" || $vfile_param_type eq "Localparam"  );
                        #print"$all_param{ $inst_param} =       $params{ $p} if($vfile_param_type eq \"Parameter\" || $vfile_param_type eq \"Localparam\"  );   \n";
                        #print"$all_param{ $inst_param} =       $params{ $p} if($vfile_param_type eq \"Parameter\" || $vfile_param_type eq \"Localparam\"  );   \n";
                }
                }
        }
        }
        return %all_param;
        return %all_param;
Line 1939... Line 2861...
        foreach my $id (@instances){
        foreach my $id (@instances){
                my $module      =$soc->soc_get_module($id);
                my $module      =$soc->soc_get_module($id);
                my $category    =$soc->soc_get_category($id);
                my $category    =$soc->soc_get_category($id);
                my $inst        = $soc->soc_get_instance_name($id);
                my $inst        = $soc->soc_get_instance_name($id);
                my @order       = $soc->soc_get_instance_param_order($id);
                my @order       = $soc->soc_get_instance_param_order($id);
 
                my %params_type = $soc->soc_get_module_param_type($id);
                foreach my $p ( @order){
                foreach my $p ( @order){
                        my $inst_param= "$inst\_$p";
                        my $inst_param= "$inst\_$p";
                        my ($default,$type,$content,$info,$vfile_param_type,$redefine_param)= $ip->ip_get_parameter($category,$module,$p);
                        my ($default,$type,$content,$info,$vfile_param_type,$redefine_param)= $ip->ip_get_parameter($category,$module,$p);
                        $vfile_param_type= "Don't include" if (!defined $vfile_param_type );
                        $vfile_param_type= "Don't include" if (!defined $vfile_param_type );
                        $vfile_param_type= "Parameter"  if ($vfile_param_type eq 1);
                        if ($vfile_param_type eq "Localparam"){
                        $vfile_param_type= "Localparam" if ($vfile_param_type eq 0);
                                my $type = $params_type{$p};
 
                                $type = "Localparam" if (! defined $type);
 
                                $vfile_param_type = ($type eq 'Parameter')?  "Parameter" : "Localparam";
 
                        }
 
                        #$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"  );
                        push(@all_order, $inst_param) if($vfile_param_type eq "Parameter" || $vfile_param_type eq "Localparam"  );
                }
                }
        }
        }
        return @all_order;
        return @all_order;
}
}
 
 
 
 
 
 
sub gen_modelsim_soc_testbench {
sub gen_modelsim_soc_testbench {
        my ($self,$name,$top,$target_dir)=@_;
        my ($self,$name,$top,$target_dir,$tview)=@_;
        my $dir="$target_dir/src_verilog";
        my $dir="$target_dir/Modelsim";
        my $soc_top= $self->object_get_attribute('top_ip',undef);
        my $soc_top= $self->object_get_attribute('top_ip',undef);
 
 
        my @intfcs=$soc_top->top_get_intfc_list();
        my @intfcs=$soc_top->top_get_intfc_list();
        my %PP;
        my %PP;
        my $top_port_def="// ${name}.v IO definition \n";
        my $top_port_def="// ${name}.v IO definition \n";
        my $pin_assign;
        my $pin_assign;
        my $rst_inputs='';
        my $rst_inputs='';
 
 
 
 
 
 
 
 
        #add functions
        #add functions
        my $d = Cwd::getcwd();
        my $project_dir   = get_project_dir();
        open my $file1, "<", "$d/lib/verilog/functions.v" or die;
        open my $file1, "<", "$project_dir/mpsoc/perl_gui/lib/verilog/functions.v" or die;
        my $functions_all='';
        my $functions_all='';
        while (my $f1 = readline ($file1)) {
        while (my $f1 = readline ($file1)) {
                 $functions_all="$functions_all $f1 ";
                 $functions_all="$functions_all $f1 ";
        }
        }
        close($file1);
        close($file1);
Line 2037... Line 2965...
                        if($type eq 'input'){
                        if($type eq 'input'){
                                $top_port_def="$top_port_def  reg  $range  $p;\n"
                                $top_port_def="$top_port_def  reg  $range  $p;\n"
                        }else{
                        }else{
                                $top_port_def="$top_port_def  wire  $range  $p;\n"
                                $top_port_def="$top_port_def  wire  $range  $p;\n"
                        }
                        }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
                        $pin_assign=(defined $pin_assign)? "$pin_assign,\n\t\t.$p($p)":  "\t\t.$p($p)";
                        $pin_assign=(defined $pin_assign)? "$pin_assign,\n\t\t.$p($p)":  "\t\t.$p($p)";
                        $rst_inputs= "$rst_inputs $p=0;\n" if ($key eq 'other' && $type eq 'input' );
                        $rst_inputs= "$rst_inputs $p=0;\n" if ($key eq 'other' && $type eq 'input' );
                }
                }
 
 
 
 
        }
        }
 
my $global_localparam=get_golal_param_v();
my $test_v= get_license_header("testbench.v");
my $test_v= get_license_header("testbench.v");
 
 
 
my $mpsoc_name=$self->object_get_attribute('mpsoc_name');
 
#if(defined $mpsoc_name){
 
        if(0){
 
 
 
 
 
        my $top_ip=ip_gen->top_gen_new();
 
        my $target_dir  = "$ENV{'PRONOC_WORK'}/MPSOC/$mpsoc_name";
 
    my $hw_dir     = "$target_dir/src_verilog";
 
    my $sw_dir     = "$target_dir/sw";
 
        my ($socs_v,$io_short,$io_full,$top_io_short,$top_io_full,$top_io_pass,$href)=gen_socs_v($self,$top_ip,$sw_dir,$tview);
 
        my $socs_param= gen_socs_param($self);
 
        my $global_localparam=get_golal_param_v();
 
        my ($clk_set, $clk_io_sim,$clk_io_full, $clk_assigned_port)= get_top_clk_setting($self);
 
 
 
 
 
$test_v.="
 
 
 
$clk_set, $clk_io_sim,$clk_io_full, $clk_assigned_port
 
 
 
`timescale       1ns/1ps
 
 
 
module testbench;
 
 
 
$functions_all
 
 
 
$global_localparam
 
 
 
$socs_param
 
 
 
$top_port_def
 
 
 
 
 
\t${mpsoc_name} the_${mpsoc_name} (
 
$top_io_pass
 
 
 
\t);
 
/*****************************************************************/
 
";
 
 
 
 
 
}
 
 
$test_v ="$test_v
$test_v ="$test_v
 
 
`timescale       1ns/1ps
`timescale       1ns/1ps
 
 
module testbench;
module testbench;
 
 
$functions_all
$functions_all
 
 
 
$global_localparam
 
 
$params_v
$params_v
 
 
$top_port_def
$top_port_def
 
 
 
 
Line 2098... Line 3078...
 
 
 
 
}
}
 
 
sub verilator_testbench{
sub verilator_testbench{
        my ($self,$name,$top,$target_dir)=@_;
        my ($self,$name,$top,$target_dir,$vendor)=@_;
        my $verilator="$target_dir/verilator";
        my $verilator="$target_dir/verilator";
        my $dir="$verilator";
        my $dir="$verilator";
 
 
        my ($app,$table,$tview,$window) = software_main($dir,'testbench.cpp');
        my ($app,$table,$tview,$window) = software_main($dir,'testbench.cpp');
 
 
Line 2114... Line 3094...
                gen_verilator_mpsoc_testbench (@_,$tview) if((-f "$dir/testbench.cpp")==0);
                gen_verilator_mpsoc_testbench (@_,$tview) if((-f "$dir/testbench.cpp")==0);
 
 
        }
        }
 
 
        #copy makefile
        #copy makefile
        #copy("../script/verilator_soc_make", "$verilator/processed_rtl/obj_dir/Makefile");
        #copy("../script/verilator_soc_make", "$verilator/obj_dir/Makefile");
 
 
 
 
 
 
 
 
 
 
Line 2135... Line 3115...
        $table->attach ($run,9, 10, 1,2,'shrink','shrink',0,0);
        $table->attach ($run,9, 10, 1,2,'shrink','shrink',0,0);
 
 
        $back-> signal_connect("clicked" => sub{
        $back-> signal_connect("clicked" => sub{
 
 
                $window->destroy;
                $window->destroy;
                verilator_compilation_win($self,$name,$top,$target_dir);
                verilator_compilation_win($self,$name,$top,$target_dir,$vendor);
 
 
        });
        });
 
 
        $regen-> signal_connect("clicked" => sub{
        $regen-> signal_connect("clicked" => sub{
                my $dialog = Gtk2::MessageDialog->new (my $window,
                my $response = yes_no_dialog("Are you sure you want to regenerate the testbench.cpp file? Note that any changes you have made will be lost");
                                      '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') {
                if ($response eq 'yes') {
                        my $n= $self->object_get_attribute('soc_name',undef);
                        my $n= $self->object_get_attribute('soc_name',undef);
                        if(defined $n){ #we are compiling a single tile as SoC
                        if(defined $n){ #we are compiling a single tile as SoC
                                gen_verilator_soc_testbench ($self,$name,$top,$target_dir);
                                gen_verilator_soc_testbench ($self,$name,$top,$target_dir);
                        }
                        }
                        else { # we are compiling a complete NoC-based mpsoc
                        else { # we are compiling a complete NoC-based mpsoc
                                gen_verilator_mpsoc_testbench ($self,$name,$top,$target_dir,$tview);
                                gen_verilator_mpsoc_testbench ($self,$name,$top,$target_dir,$tview);
 
 
                        }
                        }
 
 
                        $app->load_source("$dir/testbench.cpp");
                        $app->refresh_source("$dir/testbench.cpp");
                }
                }
                $dialog->destroy;
 
 
 
        });
        });
 
 
 
 
        $make -> signal_connect("clicked" => sub{
        $make -> signal_connect("clicked" => sub{
                $make->hide_all;
                $make->hide;
                my $load= show_gif("icons/load.gif");
                my $load= show_gif("icons/load.gif");
                $table->attach ($load,8, 9, 1,2,'shrink','shrink',0,0);
                $table->attach ($load,8, 9, 1,2,'shrink','shrink',0,0);
                $table->show_all;
                $table->show_all;
                $app->do_save();
                $app->ask_to_save_changes();
                copy("$dir/testbench.cpp", "$verilator/processed_rtl/obj_dir/testbench.cpp");
                copy("$dir/testbench.cpp", "$verilator/obj_dir/testbench.cpp");
                copy("$dir/parameter.h", "$verilator/processed_rtl/obj_dir/parameter.h") if(-f "$dir/parameter.h");
                copy("$dir/parameter.h", "$verilator/obj_dir/parameter.h") if(-f "$dir/parameter.h");
 
                copy("$dir/RxDsim.h", "$verilator/obj_dir/RxDsim.h") if(-f "$dir/RxDsim.h");
 
 
                my $tops_ref=$self->object_get_attribute('verilator','libs');
                my $tops_ref=$self->object_get_attribute('verilator','libs');
                my %tops=%{$tops_ref};
                my %tops=%{$tops_ref};
                my $lib_num=0;
                my $lib_num=0;
 
                my $cpu_num = $self->object_get_attribute('compile', 'cpu_num');
 
                $cpu_num = 1 if (!defined $cpu_num);
 
                add_colored_info($tview,"Makefie will use the maximum number of $cpu_num core(s) in parallel for compilation\n",'green');
 
                my $length=scalar (keys %tops);
 
                my $cmd="";
                foreach my $top (sort keys %tops) {
                foreach my $top (sort keys %tops) {
                                run_make_file("$verilator/processed_rtl/obj_dir/",$tview,"lib$lib_num");
                        $cmd.= "lib$lib_num & ";
                                $lib_num++;
                                $lib_num++;
 
                        if( $lib_num % $cpu_num == 0 || $lib_num == $length){
 
                                $cmd.="wait\n";
 
                                run_make_file("$verilator/obj_dir/",$tview,$cmd);
 
                                $cmd="";
 
                        }else {
 
                                $cmd.=" make ";
                }
                }
                run_make_file("$verilator/processed_rtl/obj_dir/",$tview,"sim");
                }
 
 
 
 
 
                #foreach my $top (sort keys %tops) {
 
                #               run_make_file("$verilator/obj_dir/",$tview,"lib$lib_num");
 
                #               $lib_num++;
 
                #}
 
 
 
 
 
 
 
                run_make_file("$verilator/obj_dir/",$tview,"sim");
                $load->destroy;
                $load->destroy;
                $make->show_all;
                $make->show_all;
 
 
        });
        });
 
 
        $run -> signal_connect("clicked" => sub{
        $run -> signal_connect("clicked" => sub{
                my $bin="$verilator/processed_rtl/obj_dir/testbench";
                my $bin="$verilator/obj_dir/testbench";
                if (-f $bin){
                if (-f $bin){
                        my $cmd= "cd \"$verilator/processed_rtl/obj_dir/\" \n xterm -e bash -c $bin";
                        my $cmd= "cd \"$verilator/obj_dir/\" \n xterm -e bash -c \"$bin; sleep 5\"";
                        add_info(\$tview,"$cmd\n");
                        add_info($tview,"$cmd\n");
                        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
                        my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
                        if(length $stderr>1){
                        if(length $stderr>1){
                                add_colored_info(\$tview,"$stderr\n",'red');
                                add_colored_info($tview,"$stderr\n",'red');
                        }else {
                        }else {
                                add_info(\$tview,"$stdout\n");
                                add_info($tview,"$stdout\n");
                        }
                        }
 
 
                }else{
                }else{
                        add_colored_info(\$tview,"Cannot find $bin executable binary file! make sure you have compiled the testbench successfully\n", 'red')
                        add_colored_info($tview,"Cannot find $bin executable binary file! make sure you have compiled the testbench successfully\n", 'red')
                }
                }
 
 
                });
                });
 
 
 
 
}
}
 
 
 
 
 
 
1;
1;
 
 
 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.