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

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

Rev 38 Rev 42
Line 762... Line 762...
 
 
 
 
 
 
 
 
        my $board_name=$self->object_get_attribute('compile','board');
        my $board_name=$self->object_get_attribute('compile','board');
 
 
        #copy board jtag_intfc.sh file 
        #copy board jtag_intfc.sh file 
        my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
        my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
        copy("../boards/$board_name/jtag_intfc.sh","${fpath}../sw/jtag_intfc.sh");
        copy("../boards/$board_name/jtag_intfc.sh","${fpath}../sw/jtag_intfc.sh");
 
        my $n= $self->object_get_attribute('soc_name',undef);
 
        if(!defined $n){        # we are compiling a complete NoC-based mpsoc                                           
 
                my $nx= $self->object_get_attribute('noc_param',"NX");
 
                my $ny= $self->object_get_attribute('noc_param',"NY");
 
                for (my $y=0;$y<$ny;$y++){for (my $x=0; $x<$nx;$x++){
 
                        my $tile_num= $y*$nx+$x;
 
                        #print "$tile_num\n";
 
                        my ($soc_name,$num)= $self->mpsoc_get_tile_soc_name($tile_num);
 
                        next if(!defined $soc_name);
 
                        copy("../boards/$board_name/jtag_intfc.sh","${fpath}../sw/tile$tile_num/jtag_intfc.sh");
 
                }}
 
 
 
        }
 
 
 
 
 
 
        #copy board program_device.sh file 
        #copy board program_device.sh file 
        copy("../boards/$board_name/program_device.sh","${fpath}../program_device.sh");
        copy("../boards/$board_name/program_device.sh","${fpath}../program_device.sh");
 
 
        #get boards pin list
        #get boards pin list
Line 816... Line 832...
                my $portrange=$port_range{$p};
                my $portrange=$port_range{$p};
 
 
                if  (length($portrange)!=0){
                if  (length($portrange)!=0){
                        #replace parameter with their values            
                        #replace parameter with their values            
                        my @a= split (/\b/,$portrange);
                        my @a= split (/\b/,$portrange);
 
 
                        foreach my $l (@a){
                        foreach my $l (@a){
                                my $value=$param{$l};
                                my $value=$param{$l};
                                if(defined $value){
                                if(defined $value){
                                        chomp $value;
                                        chomp $value;
                                        ($portrange=$portrange)=~ s/\b$l\b/$value/g      if(defined $param{$l});
                                        ($portrange=$portrange)=~ s/\b$l\b/$value/g      if(defined $param{$l});
 
                                #       print"($portrange=$portrange)=~ s/\b$l\b/$value/g      if(defined $param{$l})\n";
                                }
                                }
                        }
                        }
                        $portrange = "[ $portrange ]" ;
                        $portrange = "[ $portrange ]" ;
                }
                }
 
 
Line 1147... Line 1165...
 
 
        #creat modelsim dir
        #creat modelsim dir
        add_info(\$tview,"creat Modelsim dir in $target_dir\n");
        add_info(\$tview,"creat Modelsim dir in $target_dir\n");
        my $model="$target_dir/Modelsim";
        my $model="$target_dir/Modelsim";
        rmtree("$model");
        rmtree("$model");
 
        rmtree("$target_dir/rtl_work");
        mkpath("$model/rtl_work",1,01777);
        mkpath("$model/rtl_work",1,01777);
 
 
        #create modelsim.tcl file
        #create modelsim.tcl file
my $tcl="#!/usr/bin/tclsh
my $tcl="#!/usr/bin/tclsh
 
 
Line 1191... Line 1210...
        $run -> signal_connect("clicked" => sub{
        $run -> signal_connect("clicked" => sub{
                set_gui_status($self,'save_project',1);
                set_gui_status($self,'save_project',1);
                $app->do_save();
                $app->do_save();
                my $modelsim_bin= $self->object_get_attribute('compile','modelsim_bin');
                my $modelsim_bin= $self->object_get_attribute('compile','modelsim_bin');
                my $cmd="cd $target_dir; $modelsim_bin/vsim -do $model/run.tcl";
                my $cmd="cd $target_dir; $modelsim_bin/vsim -do $model/run.tcl";
 
 
                add_info(\$tview,"$cmd\n");
                add_info(\$tview,"$cmd\n");
                my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
                my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
                if(length $stderr>1){
                if(length $stderr>1){
                        add_colored_info(\$tview,"$stderr\n","red");
                        add_colored_info(\$tview,"$stderr\n","red");
 
 
Line 1226... Line 1246...
 
 
        #copy all verilog files in rtl_work folder
        #copy all verilog files in rtl_work folder
        add_info(\$outtext,"Copy all verilog files in rtl_work folder\n");
        add_info(\$outtext,"Copy all verilog files in rtl_work folder\n");
        my @files = File::Find::Rule->file()
        my @files = File::Find::Rule->file()
                ->name( '*.v','*.V','*.sv','*.vh')
                ->name( '*.v','*.V','*.sv','*.vh')
                ->in( "$target_dir/src_verilog" );
                ->in( "$target_dir/src_verilog","$target_dir/src_verilator" );
        foreach my $file (@files) {
        foreach my $file (@files) {
                copy($file,"$verilator/rtl_work/");
                copy($file,"$verilator/rtl_work/");
        }
        }
 
 
        @files = File::Find::Rule->file()
        @files = File::Find::Rule->file()
                ->name( '*.sv','*.vh' )
                ->name( '*.sv','*.vh' )
            ->in( "$target_dir/src_verilog" );
            ->in( "$target_dir/src_verilog","$target_dir/src_verilator" );
        foreach my $file (@files) {
        foreach my $file (@files) {
                copy($file,"$verilator/processed_rtl");
                copy($file,"$verilator/processed_rtl");
        }
        }
 
 
 
 
Line 1256... Line 1276...
 
 
 
 
        #run verilator
        #run verilator
        #my $cmd= "cd \"$verilator/processed_rtl\" \n xterm -e sh -c ' verilator  --cc $name.v --profile-cfuncs --prefix \"Vtop\" -O3  -CFLAGS -O3'";
        #my $cmd= "cd \"$verilator/processed_rtl\" \n xterm -e sh -c ' verilator  --cc $name.v --profile-cfuncs --prefix \"Vtop\" -O3  -CFLAGS -O3'";
        foreach my $top (sort keys %tops) {
        foreach my $top (sort keys %tops) {
                my $cmd= "cd \"$verilator/processed_rtl\" \n  verilator  --cc $tops{$top} --profile-cfuncs --prefix \"$top\" -O3  -CFLAGS -O3";
                add_colored_info(\$outtext,"Generate $top Verilator model from $tops{$top} file\n",'green');
 
                my $cmd= "cd \"$verilator/processed_rtl\" \n  verilator  --cc $tops{$top}  --prefix \"$top\" -O3  -CFLAGS -O3";
                add_info(\$outtext,"$cmd\n");
                add_info(\$outtext,"$cmd\n");
                my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
                my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
                if(length $stderr>1){
                if(length $stderr>1){
                        add_info(\$outtext,"$stderr\n");
                        add_info(\$outtext,"$stderr\n");
                }else {
                }else {
Line 1270... Line 1291...
 
 
 
 
        #check if verilator model has been generated 
        #check if verilator model has been generated 
        foreach my $top (sort keys %tops) {
        foreach my $top (sort keys %tops) {
                if (-f "$verilator/processed_rtl/obj_dir/$top.cpp"){#succsess
                if (-f "$verilator/processed_rtl/obj_dir/$top.cpp"){#succsess
                        #generate makefile
 
                        gen_verilator_makefile($top_ref,"$verilator/processed_rtl/obj_dir/Makefile");
 
 
 
                }else {
                }else {
                        return 0;
                        return 0;
                }
                }
        }
        }
 
        #generate makefile
 
        gen_verilator_makefile($top_ref,"$verilator/processed_rtl/obj_dir/Makefile");
        return 1;
        return 1;
}
}
 
 
 
 
sub gen_verilator_makefile{
sub gen_verilator_makefile{
Line 1288... Line 1310...
        my %tops = %{$top_ref};
        my %tops = %{$top_ref};
        my $p='';
        my $p='';
        my $q='';
        my $q='';
        my $h='';
        my $h='';
        my $l;
        my $l;
 
        my $lib_num=0;
 
        my $all_lib="";
        foreach my $top (sort keys %tops) {
        foreach my $top (sort keys %tops) {
                $p = "$p ${top}__ALL.a ";
                $p = "$p ${top}__ALL.a ";
                $q = "$q\t\$(MAKE) -f ${top}.mk\n";
                $q = $q."lib$lib_num:\n\t\$(MAKE) -f ${top}.mk\n";
                $h = "$h ${top}.h ";
                $h = "$h ${top}.h ";
                $l = $top;
                $l = $top;
 
                $all_lib=$all_lib." lib$lib_num";
 
                $lib_num++;
        }
        }
 
 
 
 
        my $make= "
        my $make= "
 
 
Line 1304... Line 1330...
 
 
 
 
 
 
include $l.mk
include $l.mk
 
 
lib:
lib: $all_lib
 
 
$q
$q
 
 
 
 
#######################################################################
#######################################################################
# Compile flags
# Compile flags
Line 1327... Line 1354...
        \$(LINK) \$(LDFLAGS) -g \$^ \$(LOADLIBES) \$(LDLIBS) -o testbench \$(LIBS) -Wall -O3 2>&1 | c++filt
        \$(LINK) \$(LDFLAGS) -g \$^ \$(LOADLIBES) \$(LDLIBS) -o testbench \$(LIBS) -Wall -O3 2>&1 | c++filt
 
 
testbench.o: testbench.cpp $h
testbench.o: testbench.cpp $h
 
 
clean:
clean:
        rm *.o *.a main
        rm *.o *.a testbench
";
";
 
 
 
 
 
 
save_file ($target_dir,$make);
save_file ($target_dir,$make);
Line 1369... Line 1396...
 
 
                $window->destroy;
                $window->destroy;
                verilator_testbench($self,$name,$top,$target_dir);
                verilator_testbench($self,$name,$top,$target_dir);
 
 
        });
        });
 
 
 
        $window->add ($mtable);
 
        $window->show_all();
 
 
 
 
 
        my $result;
 
 
 
        my $n= $self->object_get_attribute('soc_name',undef);
 
        if(defined $n){ #we are compiling a single tile as SoC
        my %tops;
        my %tops;
        $tops{"Vtop"}= "$name.v";
        $tops{"Vtop"}= "$name.v";
        my $result = verilator_compilation (\%tops,$target_dir,$outtext);
                $result = verilator_compilation (\%tops,$target_dir,$outtext);
 
                $self->object_add_attribute('verilator','libs',\%tops);
 
        }
 
        else { # we are compiling a complete NoC-based mpsoc
 
                $result = gen_mpsoc_verilator_model ($self,$name,$top,$target_dir,$outtext);
 
 
 
 
 
        }
 
 
 
 
        #check if verilator model has been generated 
        #check if verilator model has been generated 
        if ($result){
        if ($result){
                add_colored_info(\$outtext,"Veriator model has been generated successfully!",'blue');
                add_colored_info(\$outtext,"Veriator model has been generated successfully!",'blue');
        }else {
        }else {
                add_colored_info(\$outtext,"Verilator compilation failed!\n","red");
                add_colored_info(\$outtext,"Verilator compilation failed!\n","red");
Line 1383... Line 1428...
        }
        }
 
 
 
 
 
 
 
 
        $window->add ($mtable);
 
        $window->show_all();
 
 
 
 
 
 
 
}
}
 
 
 
 
 
 
 
 
 
 
 
sub  gen_mpsoc_verilator_model{
 
        my ($self,$name,$top,$target_dir,$outtext)=@_;
 
        my $dir = Cwd::getcwd();
 
        my $project_dir   = abs_path("$dir/..");
 
        my $src_verilator_dir="$project_dir/src_verilator";
 
        my $sw_dir      = "$target_dir/sw";
 
 
 
 
 
        #copy src_verilator files
 
        add_info(\$outtext,"Copy verilator files\n");
 
        my @files=(
 
                "$src_verilator_dir/noc_connection.sv",
 
                "$src_verilator_dir/router_verilator.v"
 
        );
 
        if (-d "$target_dir/src_verilator/"==0){
 
                mkpath("$target_dir/src_verilator/",1,01777);
 
        }
 
        copy_file_and_folders (\@files,$project_dir,"$target_dir/src_verilator");
 
 
 
        #create each tile top module 
 
        my $nx= $self->object_get_attribute('noc_param',"NX");
 
    my $ny= $self->object_get_attribute('noc_param',"NY");
 
    my $processors_en=0;
 
    my $mpsoc=$self;
 
 
 
    my $lisence= get_license_header("verilator_tiles");
 
        my $warning=autogen_warning();
 
    my $verilator=$lisence.$warning;
 
 
 
 
 
    # generate NoC parameter file
 
        my ($noc_param,$pass_param)=gen_noc_param_v($self);
 
 
 
        my $noc_param_v= " \`ifdef     INCLUDE_PARAM \n \n
 
        $noc_param
 
        /* verilator lint_off WIDTH */
 
        localparam  P=(TOPOLOGY==\"RING\" || TOPOLOGY==\"LINE\")? 3 : 5;
 
        localparam  ROUTE_TYPE = (ROUTE_NAME == \"XY\" || ROUTE_NAME == \"TRANC_XY\" )?    \"DETERMINISTIC\" :
 
                        (ROUTE_NAME == \"DUATO\" || ROUTE_NAME == \"TRANC_DUATO\" )?   \"FULL_ADAPTIVE\": \"PAR_ADAPTIVE\";
 
        /* verilator lint_on WIDTH */
 
        //simulation parameter
 
 
 
\n \n \`endif" ;
 
        save_file("$target_dir/src_verilator/parameter.v",$noc_param_v);
 
 
 
 
 
 
 
   my %tops = (
 
        "Vrouter" => "router_verilator.v",
 
        "Vnoc" => "noc_connection.sv"
 
    );
 
 
 
    for (my $y=0;$y<$ny;$y++){
 
                for (my $x=0; $x<$nx;$x++){
 
 
 
                my $tile_num= $y*$nx+$x;
 
                #print "$tile_num\n";
 
                my ($soc_name,$num)= $mpsoc->mpsoc_get_tile_soc_name($tile_num);
 
                if(!defined $soc_name){
 
                        #this tile is not connected to any ip. the noc input ports will be connected to ground
 
                                my $soc_v="\n\n // Tile:$tile_num (x=$x,y=$y)   is not assigned to any ip\n";
 
                                $soc_v="$soc_v
 
 
 
        assign ni_credit_out[$tile_num]={V{1'b0}};
 
        assign ni_flit_out[$tile_num]={Fw{1'b0}};
 
        assign ni_flit_out_wr[$tile_num]=1'b0;
 
        ";
 
                next;
 
 
 
                }
 
                my $soc=eval_soc($mpsoc,$soc_name,$outtext);
 
 
 
 
 
                my $top=$mpsoc->mpsoc_get_soc($soc_name);
 
                my $soc_num= $y*$nx+$x;
 
 
 
 
 
 
 
 
 
                #update core id
 
                $soc->object_add_attribute('global_param','CORE_ID',$tile_num);
 
                #update NoC param
 
                #my %nocparam = %{$mpsoc->object_get_attribute('noc_param',undef)};
 
                my $nocparam =$mpsoc->object_get_attribute('noc_param',undef);
 
                my @nis=get_NI_instance_list($top);
 
                $soc->soc_add_instance_param($nis[0] ,$nocparam );
 
                my $tile=($nx*$y)+ $x;
 
 
 
                my $setting=$mpsoc->mpsoc_get_tile_param_setting($tile);
 
                my %params;
 
                if ($setting eq 'Custom'){
 
                         %params= $top->top_get_custom_soc_param($tile);
 
                }else{
 
                         %params=$top->top_get_default_soc_param();
 
                }
 
 
 
 
 
                my $sw_path     = "$sw_dir/tile$tile_num";
 
                $verilator = $verilator.soc_generate_verilatore ($soc,$sw_path,"tile_$tile",\%params);
 
                $tops{"Vtile$tile_num"}= "tile_$tile.v";
 
 
 
 
 
        }}
 
 
 
        save_file ("$target_dir/src_verilator/verilator_tiles.v",$verilator);
 
        my $result = verilator_compilation (\%tops,$target_dir,$outtext);
 
        $self->object_add_attribute('verilator','libs',\%tops);
 
        return $result;
 
 
 
}
 
 
 
 
sub gen_verilator_soc_testbench {
sub gen_verilator_soc_testbench {
        my ($self,$name,$top,$target_dir)=@_;
        my ($self,$name,$top,$target_dir)=@_;
        my $verilator="$target_dir/verilator";
        my $verilator="$target_dir/verilator";
        my $dir="$verilator/";
        my $dir="$verilator/";
        my $soc_top= $self->soc_get_top ();
        my $soc_top= $self->soc_get_top ();
 
 
        my @intfcs=$soc_top->top_get_intfc_list();
        my @intfcs=$soc_top->top_get_intfc_list();
        my %PP;
        my %PP;
        my $top_port_info="IO type\t  port_size\t  port_name\n";
        my $top_port_info="IO type\t  port_size\t  port_name\n";
        foreach my $intfc (@intfcs){
        foreach my $intfc (@intfcs){
                my $key= ( $intfc eq 'plug:clk[0]')? 'clk' :
                my $key= ( $intfc eq 'plug:clk[0]')? 'clk' :
Line 1485... Line 1644...
 
 
 
 
 
 
}
}
 
 
 
sub eval_soc{
 
        my ($mpsoc,$soc_name,$outtext)=@_;
 
        my $path=$mpsoc->object_get_attribute('setting','soc_path');
 
        $path=~ s/ /\\ /g;
 
        my $p = "$path/$soc_name.SOC";
 
        my  $soc = eval { do $p };
 
        if ($@ || !defined $soc){
 
                show_info(\$outtext,"**Error reading  $p file: $@\n");
 
               next;
 
        }
 
        return $soc;
 
}
 
 
 
 
 
sub gen_verilator_mpsoc_testbench {
 
        my ($mpsoc,$name,$top,$target_dir,$tview)=@_;
 
        my $verilator="$target_dir/verilator";
 
        my $dir="$verilator/";
 
        #my $soc_top= $self->soc_get_top ();
 
 
 
        my $nx= $mpsoc->object_get_attribute('noc_param',"NX");
 
    my $ny= $mpsoc->object_get_attribute('noc_param',"NY");
 
 
 
        my $libh="";
 
        my $inst= "";
 
        my $newinst="";
 
 
 
        my $tile_x="";
 
        my $tile_y="";
 
        my $tile_flit_in="";
 
        my $tile_flit_in_l="";
 
        my $tile_credit="";
 
        my $noc_credit="";
 
        my $noc_flit_in="";
 
        my $noc_flit_in_l="";
 
        my $noc_flit_in_wr="";
 
        my $noc_flit_in_wr_l="";
 
        my $tile_flit_in_wr="";
 
        my $tile_flit_in_wr_l="";
 
        my $tile_eval="";
 
        my $tile_final="";
 
        my $tile_reset="";
 
        my $tile_clk="";
 
        my $tile_en="";
 
        my $top_port_info="IO type\t  port_size\t  port_name\n";
 
        my $no_connected='';
 
 
 
        for (my $y=0;$y<$ny;$y++){for (my $x=0; $x<$nx;$x++){
 
                my $t= $y*$nx+$x;
 
                my ($soc_name,$num)= $mpsoc->mpsoc_get_tile_soc_name($t);
 
                if(defined $soc_name) {#we have a conncted tile
 
 
 
                        #get ni instance name
 
                        my $ni_name;
 
                        my $soc=eval_soc($mpsoc,$soc_name,$tview);
 
                        my $soc_top=$soc->object_get_attribute('top_ip',undef);
 
                        my @intfcs=$soc_top->top_get_intfc_list();
 
                        my @instances=$soc->soc_get_all_instances();
 
                        foreach my $id (@instances){
 
                                        my $category = $soc->soc_get_category($id);
 
                                        if ($category eq 'NoC') {
 
                                                 $ni_name=  $soc->soc_get_instance_name($id);
 
                                        }
 
                        }
 
 
 
 
 
                                $libh=$libh."#include \"Vtile${t}.h\"\n";
 
                                $inst=$inst."Vtile${t}\t*tile${t};\t  // Instantiation of tile${t}\n";
 
                                $newinst = $newinst."\ttile${t}\t=\tnew Vtile${t};\n";
 
                                $tile_flit_in = $tile_flit_in . "\ttile${t}->${ni_name}_flit_in  = noc->ni_flit_out [${t}];\n";
 
                                $tile_flit_in_l = $tile_flit_in_l . "\t\ttile${t}->${ni_name}_flit_in[j]  = noc->ni_flit_out [${t}][j];\n";
 
                                $tile_credit= $tile_credit."\ttile${t}->${ni_name}_credit_in= noc->ni_credit_out[${t}];\n";
 
                                $noc_credit= $noc_credit."\tnoc->ni_credit_in[${t}] = tile${t}->${ni_name}_credit_out;\n";
 
                                $noc_flit_in=$noc_flit_in."\tnoc->ni_flit_in [${t}]  = tile${t}->${ni_name}_flit_out;\n";
 
                                $noc_flit_in_l=$noc_flit_in_l."\t\t\tnoc->ni_flit_in [${t}][j]  = tile${t}->${ni_name}_flit_out[j];\n";
 
                                $noc_flit_in_wr= $noc_flit_in_wr."\tif(tile${t}->${ni_name}_flit_out_wr) noc->ni_flit_in_wr = noc->ni_flit_in_wr | ((vluint64_t)1<<${t});\n";
 
                                $tile_flit_in_wr=$tile_flit_in_wr."\ttile${t}->${ni_name}_flit_in_wr= ((noc->ni_flit_out_wr >> ${t}) & 0x01);\n";
 
                                $noc_flit_in_wr_l= $noc_flit_in_wr_l."\tif(tile${t}->${ni_name}_flit_out_wr) MY_VL_SETBIT_W(noc->ni_flit_in_wr ,${t});\n";
 
                                $tile_flit_in_wr_l=$tile_flit_in_wr_l."\ttile${t}->${ni_name}_flit_in_wr=   (VL_BITISSET_W(noc->ni_flit_out_wr,${t})>0);\n";
 
                                $tile_eval=$tile_eval."\ttile${t}->eval();\n";
 
                                $tile_final=$tile_final."\ttile${t}->final();\n";
 
 
 
 
 
 
 
 
 
 
 
 
 
                                foreach my $intfc (@intfcs){
 
                                        my $key=($intfc eq 'plug:clk[0]')? 'clk' :
 
                                                         ($intfc eq 'plug:reset[0]')? 'reset':
 
                                                         ($intfc eq 'plug:enable[0]')? 'en' :
 
                                                         'other';
 
 
 
                                        my @ports=$soc_top->top_get_intfc_ports_list($intfc);
 
                                        foreach my $p (@ports){
 
                                                my($inst,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
 
                                                $tile_reset=$tile_reset."\t\ttile${t}->$p=reset;\n" if $key eq 'reset';
 
                                                $tile_clk=$tile_clk."\t\ttile${t}->$p=clk;\n" if $key eq 'clk';
 
                                                $tile_en=$tile_en."\t\ttile${t}->$p=enable;\n" if $key eq 'en'; ;
 
                                                $top_port_info="$top_port_info $type  $range  tile${t}->$p \n";
 
                                        }#ports
 
 
 
                                }#interface
 
 
 
                                $tile_x= $tile_x."\ttile${t}->${ni_name}_current_x=$x;\n";
 
                                $tile_y= $tile_y."\ttile${t}->${ni_name}_current_y=$y;\n";
 
                        }else{
 
                                #this tile is not connected to any ip. the noc input ports will be connected to ground
 
                                $no_connected=$no_connected."\n // Tile:$t (x=$x,y=$y)   is not assigned to any ip\n";
 
                                $no_connected=$no_connected."\t\tnoc->ni_credit_in[${t}]=0; \n";
 
 
 
                        }
 
 
 
 
 
        }}
 
        my $main_c=get_license_header("testbench.cpp");
 
$main_c="$main_c
 
#include <stdlib.h>
 
#include <stdio.h>
 
#include <unistd.h>
 
#include <string.h>
 
#include <verilated.h>          // Defines common routines
 
 
 
#include \"Vnoc.h\"
 
#include \"Vrouter.h\"
 
$libh
 
 
 
 
 
/*
 
$top_port_info
 
*/
 
 
 
 
 
#ifndef  NX
 
        #define  NX     $nx
 
#endif
 
 
 
#ifndef  NY
 
        #define  NY     $ny
 
#endif
 
 
 
#ifndef  NC
 
        #define  NC             ($nx*$ny)
 
#endif
 
 
 
 
 
Vrouter                 *router[NC];                     // Instantiation of router
 
Vnoc                    *noc;
 
$inst
 
 
 
 
 
 
 
int reset,clk,enable;
 
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
 
 
 
        for(i=0;i<NC;i++)       router[i]       = new Vrouter;             // Create instance
 
        noc                                                             = new Vnoc;
 
$newinst
 
 
 
        /********************
 
        *       initialize input
 
        *********************/
 
 
 
 
 
        reset=1;
 
        enable=1;
 
        $no_connected
 
        for(x=0;x<NX;x++)for(y=0;y<NY;y++){
 
                                        i=(y*NX)+x;
 
                                        router[i]->current_x            = x;
 
                                        router[i]->current_y            = y;
 
        }
 
$tile_x
 
$tile_y
 
 
 
        main_time=0;
 
        printf(\"Start Simulation\\n\");
 
        while (!Verilated::gotFinish()) {
 
 
 
                if (main_time >= 10 ) {
 
                        reset=0;
 
                }
 
 
 
 
 
                if ((main_time % 5) == 0) {
 
                        clk = 1;       // Toggle clock
 
                        // you can change the inputs and read the outputs here in case they are captured at posedge of clock
 
 
 
                }
 
                else{
 
                        clk = 0;       // Toggle clock
 
                        update_all_instances_inputs();
 
 
 
 
 
 
 
                }
 
 
 
 
 
                //clk,reset,enable
 
                noc-> clk = clk;
 
                noc-> reset = reset;
 
$tile_reset
 
$tile_clk
 
$tile_en
 
                for(i=0;i<NC;i++){
 
                        router[i]->reset= reset;
 
                        router[i]->clk= clk;
 
                }
 
 
 
                //eval instances
 
                noc->eval();
 
                for(i=0;i<NC;i++) {
 
                                router[i]->eval();
 
                }
 
$tile_eval
 
 
 
 
 
                main_time++;
 
 
 
 
 
 
 
        }//while
 
 
 
        // Simulation is dne
 
        for(i=0;i<NC;i++) {
 
                router[i]->final();
 
        }
 
        noc->final();
 
$tile_final
 
}
 
 
 
double sc_time_stamp () {       // Called by \$time in Verilog
 
        return main_time;
 
}
 
 
 
 
 
void update_all_instances_inputs(void){
 
 
 
        int x,y,i,j;
 
        int flit_out_all_size = sizeof(router[0]->flit_out_all)/sizeof(router[0]->flit_out_all[0]);
 
 
 
#if (NC<=64)
 
        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
 
        for(x=0;x<NX;x++)for(y=0;y<NY;y++){
 
                i=(y*NX)+x;
 
                router[i]->flit_in_we_all = noc->router_flit_out_we_all[i];
 
                router[i]->credit_in_all = noc->router_credit_out_all[i];
 
                router[i]->congestion_in_all = noc->router_congestion_out_all[i];
 
                for(j=0;j<flit_out_all_size;j++) router[i]->flit_in_all[j]      = noc->router_flit_out_all[i][j];
 
                noc->router_flit_in_we_all[i] = router[i]->flit_out_we_all ;
 
                noc->router_credit_in_all[i]    =       router[i]->credit_out_all;
 
                noc->router_congestion_in_all[i]=       router[i]->congestion_out_all;
 
                for(j=0;j<flit_out_all_size;j++) noc->router_flit_in_all[i][j]  = router[i]->flit_out_all[j] ;
 
        }       //for
 
 
 
 
 
 
 
 
 
#if (Fpay<=32)
 
        //tile[i]->flit_in  = noc->ni_flit_out [i];
 
$tile_flit_in
 
#else
 
        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];
 
$tile_credit
 
 
 
        //noc->ni_credit_in[i] = traffic[i]->credit_out;
 
$noc_credit
 
 
 
#if (Fpay<=32)
 
        //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)
 
                //if(traffic[i]->flit_out_wr) noc->ni_flit_in_wr = noc->ni_flit_in_wr | ((vluint64_t)1<<i);
 
$noc_flit_in_wr
 
 
 
                //traffic[i]->flit_in_wr= ((noc->ni_flit_out_wr >> i) & 0x01);
 
$tile_flit_in_wr
 
#else
 
                //if(traffic[i]->flit_out_wr) MY_VL_SETBIT_W(noc->ni_flit_in_wr ,i);
 
$noc_flit_in_wr_l
 
 
 
                //traffic[i]->flit_in_wr=   (VL_BITISSET_W(noc->ni_flit_out_wr,i)>0);
 
$tile_flit_in_wr_l
 
 
 
#endif
 
 
 
 
 
 
 
}
 
";
 
 
 
        save_file("$dir/testbench.cpp",$main_c);
 
 
 
}
 
 
 
 
 
 
 
sub soc_get_all_parameters {
 
        my $soc=shift;
 
        my @instances=$soc->soc_get_all_instances();
 
 
 
        my %all_param;
 
        foreach my $id (@instances){
 
 
 
                my $module      =$soc->soc_get_module($id);
 
                my $category    =$soc->soc_get_category($id);
 
                my $inst        = $soc->soc_get_instance_name($id);
 
                my %params      = $soc->soc_get_module_param($id);
 
                my $ip = ip->lib_new ();
 
                my @param_order=$soc->soc_get_instance_param_order($id);
 
 
 
                foreach my $p (sort keys %params){
 
                        my $inst_param= "$inst\_$p";
 
                        #add instance name to parameter value
 
                        $params{$p}=add_instantc_name_to_parameters(\%params,$inst,$params{$p});
 
                        my ($default,$type,$content,$info,$vfile_param_type,$redefine_param)= $ip->ip_get_parameter($category,$module,$p);
 
                        $vfile_param_type= "Don't include" if (!defined $vfile_param_type );
 
                        $vfile_param_type= "Parameter"  if ($vfile_param_type eq 1);
 
                        $vfile_param_type= "Localparam" if ($vfile_param_type eq 0);
 
                        $all_param{ $inst_param} =      $params{ $p} if($vfile_param_type eq "Parameter" || $vfile_param_type eq "Localparam"  );
 
                        print"$all_param{ $inst_param} =        $params{ $p} if($vfile_param_type eq \"Parameter\" || $vfile_param_type eq \"Localparam\"  );   \n";
 
                }
 
        }
 
        return %all_param;
 
}
 
 
 
sub soc_get_all_parameters_order {
 
        my $soc=shift;
 
        my @instances=$soc->soc_get_all_instances();
 
        my $ip = ip->lib_new ();
 
        my @all_order;
 
        foreach my $id (@instances){
 
                my $module      =$soc->soc_get_module($id);
 
                my $category    =$soc->soc_get_category($id);
 
                my $inst        = $soc->soc_get_instance_name($id);
 
                my @order       = $soc->soc_get_instance_param_order($id);
 
 
 
                foreach my $p ( @order){
 
                        my $inst_param= "$inst\_$p";
 
                        my ($default,$type,$content,$info,$vfile_param_type,$redefine_param)= $ip->ip_get_parameter($category,$module,$p);
 
                        $vfile_param_type= "Don't include" if (!defined $vfile_param_type );
 
                        $vfile_param_type= "Parameter"  if ($vfile_param_type eq 1);
 
                        $vfile_param_type= "Localparam" if ($vfile_param_type eq 0);
 
                        push(@all_order, $inst_param) if($vfile_param_type eq "Parameter" || $vfile_param_type eq "Localparam"  );
 
                }
 
        }
 
        return @all_order;
 
}
 
 
 
 
 
 
sub gen_modelsim_soc_testbench {
sub gen_modelsim_soc_testbench {
        my ($self,$name,$top,$target_dir)=@_;
        my ($self,$name,$top,$target_dir)=@_;
        my $dir="$target_dir/src_verilog";
        my $dir="$target_dir/src_verilog";
        my $soc_top= $self->object_get_attribute('top_ip',undef);
        my $soc_top= $self->object_get_attribute('top_ip',undef);
Line 1496... Line 2031...
        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='';
 
 
        #read port list 
 
        my $vdb=read_verilog_file($top);
 
        my %param = $vdb->get_modules_parameters("${name}_top");
 
 
 
 
 
 
 
 
        #add functions
 
        my $d = Cwd::getcwd();
 
        open my $file1, "<", "$d/lib/verilog/functions.v" or die;
 
        my $functions_all='';
 
        while (my $f1 = readline ($file1)) {
 
                 $functions_all="$functions_all $f1 ";
 
        }
 
        close($file1);
 
 
 
        #get parameters
 
        my $params_v="";
 
        my $n= $self->object_get_attribute('soc_name',undef);
 
 
 
        if(defined $n){ #we are compiling a single tile as SoC
 
                my $core_id= $self->object_get_attribute('global_param','CORE_ID');
 
                my $sw_loc = $self->object_get_attribute('global_param','SW_LOC');
 
 
 
                        $params_v="\tlocalparam\tCORE_ID=$core_id;
 
\tlocalparam\tSW_LOC=\"$sw_loc\";\n";
 
                my %params=soc_get_all_parameters($self);
 
                my @order= soc_get_all_parameters_order($self);
 
                foreach my $p (@order){
 
                        add_text_to_string(\$params_v,"\tlocalparam  $p = $params{$p};\n") if(defined $params{$p} );
 
                }
 
        }else{ # we are simulating a mpsoc
 
                $params_v= gen_socs_param($self);
 
 
 
 
 
        }
 
 
        foreach my $intfc (@intfcs){
        foreach my $intfc (@intfcs){
                my $key= ( $intfc eq 'plug:clk[0]')? 'clk' :
                my $key= ( $intfc eq 'plug:clk[0]')? 'clk' :
                         ( $intfc eq 'plug:reset[0]')? 'reset':
                         ( $intfc eq 'plug:reset[0]')? 'reset':
                         ( $intfc eq 'plug:enable[0]')? 'en' : 'other';
                         ( $intfc eq 'plug:enable[0]')? 'en' : 'other';
Line 1522... Line 2081...
                        $PP{$key1}= (defined $PP{$key1})? "$PP{$key1} $p=1;\n" : "$p=1;\n";
                        $PP{$key1}= (defined $PP{$key1})? "$PP{$key1} $p=1;\n" : "$p=1;\n";
                        $PP{$key0}= (defined $PP{$key0})? "$PP{$key0} $p=0;\n" : "$p=0;\n";
                        $PP{$key0}= (defined $PP{$key0})? "$PP{$key0} $p=0;\n" : "$p=0;\n";
 
 
 
 
                        if  (length($range)!=0){
                        if  (length($range)!=0){
                                #replace parameter with their values            
#                               #replace parameter with their values            #
                                my @a= split (/\b/,$range);
#                               my @a= split (/\b/,$range);
                                foreach my $l (@a){
#                               print "a=@a\n";
                                        my $value=$param{$l};
#                               foreach my $l (@a){
                                        if(defined $value){
#                                       my $value=$params{$l};
                                                chomp $value;
#                                       if(defined $value){
                                                ($range=$range)=~ s/\b$l\b/$value/g      if(defined $param{$l});
#                                               chomp $value;
                                        }
#                                               ($range=$range)=~ s/\b$l\b/$value/g      if(defined $params{$l});
                                }
#                                               print "($range=$range)=~ s/\b$l\b/$value/g      if(defined $params{$l}); \n";
 
#                                       }
 
#                               }
                                $range = "[ $range ]" ;
                                $range = "[ $range ]" ;
                        }
                        }
 
 
 
 
 
 
 
 
 
 
                        if($type eq 'input'){
                        if($type eq 'input'){
                                $top_port_def="$top_port_def  reg  $range  $p;\n"
                                $top_port_def="$top_port_def  reg  $range  $p;\n"
                        }else{
                        }else{
                                $top_port_def="$top_port_def  wire  $range  $p;\n"
                                $top_port_def="$top_port_def  wire  $range  $p;\n"
                        }
                        }
Line 1556... Line 2119...
 
 
`timescale       1ns/1ps
`timescale       1ns/1ps
 
 
module testbench;
module testbench;
 
 
 
$functions_all
 
 
 
$params_v
 
 
$top_port_def
$top_port_def
 
 
 
 
        $name uut (
        $name uut (
$pin_assign
$pin_assign
Line 1601... Line 2168...
 
 
sub verilator_testbench{
sub verilator_testbench{
        my ($self,$name,$top,$target_dir)=@_;
        my ($self,$name,$top,$target_dir)=@_;
        my $verilator="$target_dir/verilator";
        my $verilator="$target_dir/verilator";
        my $dir="$verilator";
        my $dir="$verilator";
 
 
 
        my ($app,$table,$tview,$window) = software_main($dir,'testbench.cpp');
 
 
 
        my $n= $self->object_get_attribute('soc_name',undef);
 
        if(defined $n){ #we are compiling a single tile as SoC
        gen_verilator_soc_testbench (@_) if((-f "$dir/testbench.cpp")==0);
        gen_verilator_soc_testbench (@_) if((-f "$dir/testbench.cpp")==0);
 
        }
 
        else { # we are compiling a complete NoC-based mpsoc
 
                gen_verilator_mpsoc_testbench (@_,$tview) if((-f "$dir/testbench.cpp")==0);
 
 
 
        }
 
 
        #copy makefile
        #copy makefile
        #copy("../script/verilator_soc_make", "$verilator/processed_rtl/obj_dir/Makefile"); 
        #copy("../script/verilator_soc_make", "$verilator/processed_rtl/obj_dir/Makefile"); 
 
 
 
 
        my ($app,$table,$tview,$window) = software_main($dir,'testbench.cpp');
 
 
 
 
 
        my $make = def_image_button('icons/gen.png','Compile');
        my $make = def_image_button('icons/gen.png','Compile');
        my $regen=def_image_button('icons/refresh.png','Regenerate Testbench.cpp');
        my $regen=def_image_button('icons/refresh.png','Regenerate Testbench.cpp');
        my $run = def_image_button('icons/run.png','Run');
        my $run = def_image_button('icons/run.png','Run');
Line 1634... Line 2212...
                                      'question', # message type
                                      'question', # message type
                                      'yes-no', # which set of buttons?
                                      'yes-no', # which set of buttons?
                                      "Are you sure you want to regenaret the testbench.cpp file? Note that any changes you have made will be lost");
                                      "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;
                my $response = $dialog->run;
                if ($response eq 'yes') {
                if ($response eq 'yes') {
 
                        my $n= $self->object_get_attribute('soc_name',undef);
 
                        if(defined $n){ #we are compiling a single tile as SoC
                        gen_verilator_soc_testbench ($self,$name,$top,$target_dir);
                        gen_verilator_soc_testbench ($self,$name,$top,$target_dir);
 
                        }
 
                        else { # we are compiling a complete NoC-based mpsoc
 
                                gen_verilator_mpsoc_testbench ($self,$name,$top,$target_dir,$tview);
 
 
 
                        }
 
 
                        $app->load_source("$dir/testbench.cpp");
                        $app->load_source("$dir/testbench.cpp");
                }
                }
                $dialog->destroy;
                $dialog->destroy;
 
 
        });
        });
 
 
 
 
        $make -> signal_connect("clicked" => sub{
        $make -> signal_connect("clicked" => sub{
                $app->do_save();
                $app->do_save();
                copy("$dir/testbench.cpp", "$verilator/processed_rtl/obj_dir/testbench.cpp");
                copy("$dir/testbench.cpp", "$verilator/processed_rtl/obj_dir/testbench.cpp");
                run_make_file("$verilator/processed_rtl/obj_dir/",$tview);
 
 
                my $tops_ref=$self->object_get_attribute('verilator','libs');
 
                my %tops=%{$tops_ref};
 
                my $lib_num=0;
 
 
 
                foreach my $top (sort keys %tops) {
 
                                run_make_file("$verilator/processed_rtl/obj_dir/",$tview,"lib$lib_num");
 
                                $lib_num++;
 
                }
 
                run_make_file("$verilator/processed_rtl/obj_dir/",$tview,"sim");
 
 
        });
        });
 
 
        $run -> signal_connect("clicked" => sub{
        $run -> signal_connect("clicked" => sub{
                my $bin="$verilator/processed_rtl/obj_dir/testbench";
                my $bin="$verilator/processed_rtl/obj_dir/testbench";

powered by: WebSVN 2.1.0

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