Line 1... |
Line 1... |
#! /usr/bin/perl -w
|
#! /usr/bin/perl -w
|
use Glib qw/TRUE FALSE/;
|
use Glib qw/TRUE FALSE/;
|
use strict;
|
use strict;
|
use warnings;
|
use warnings;
|
|
|
|
use FindBin;
|
|
use lib $FindBin::Bin;
|
|
|
use soc;
|
use soc;
|
#use ip;
|
|
#use interface;
|
|
#use POSIX 'strtol';
|
|
|
|
use File::Path;
|
use File::Path;
|
use File::Find::Rule;
|
use File::Find::Rule;
|
use File::Copy;
|
use File::Copy;
|
use File::Copy::Recursive qw(dircopy);
|
use File::Copy::Recursive qw(dircopy);
|
use Cwd 'abs_path';
|
use Cwd 'abs_path';
|
use Verilog::EditFiles;
|
use Verilog::EditFiles;
|
|
|
use Gtk2;
|
use Gtk2;
|
#use Gtk2::Pango;
|
|
|
|
use List::MoreUtils qw( minmax );
|
use List::MoreUtils qw( minmax );
|
|
|
|
|
|
|
Line 199... |
Line 200... |
}
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sub select_compiler {
|
sub select_compiler {
|
my ($self,$name,$top,$target_dir,$end_func)=@_;
|
my ($self,$name,$top,$target_dir,$end_func)=@_;
|
my $window = def_popwin_size(40,40,"Step 1: Select Compiler",'percent');
|
my $window = def_popwin_size(40,40,"Step 1: Select Compiler",'percent');
|
#get the list of boards located in "boards/*" folder
|
#get the list of boards located in "boards/*" folder
|
my @dirs = grep {-d} glob("../boards/*");
|
my @dirs = grep {-d} glob("../boards/*");
|
Line 399... |
Line 394... |
|
|
|
|
|
|
my $widgets= add_new_fpga_board_widgets($self,$name,$top,$target_dir,$end_func);
|
my $widgets= add_new_fpga_board_widgets($self,$name,$top,$target_dir,$end_func);
|
my ($Twin,$tview)=create_text();
|
my ($Twin,$tview)=create_text();
|
add_colors_to_textview($tview);
|
|
|
|
my $v1=gen_vpaned($widgets,0.3,$Twin);
|
my $v1=gen_vpaned($widgets,0.3,$Twin);
|
|
|
$table->attach_defaults($v1,0,3,0,2);
|
$table->attach_defaults($v1,0,3,0,2);
|
#$table->attach_defaults( $Twin,0,3,1,2);
|
#$table->attach_defaults( $Twin,0,3,1,2);
|
Line 539... |
Line 534... |
$table->show_all();
|
$table->show_all();
|
# my $cmd=" $ENV{'QUARTUS_BIN'}"
|
# my $cmd=" $ENV{'QUARTUS_BIN'}"
|
|
|
});
|
});
|
|
|
|
|
|
|
$window->add ($mtable);
|
$window->add ($mtable);
|
$window->show_all();
|
$window->show_all();
|
|
|
}
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sub add_new_fpga_board_widgets{
|
sub add_new_fpga_board_widgets{
|
my ($self,$name,$top,$target_dir,$end_func)=@_;
|
my ($self,$name,$top,$target_dir,$end_func)=@_;
|
my $table = def_table(2, 2, FALSE);
|
my $table = def_table(2, 2, FALSE);
|
|
|
my $help1="FPGA Board name. Do not use any space in given name";
|
my $help1="FPGA Board name. Do not use any space in given name";
|
Line 757... |
Line 744... |
|
|
$mtable->attach_defaults($scrolled_win,0,10,0,9);
|
$mtable->attach_defaults($scrolled_win,0,10,0,9);
|
$mtable->attach($back,2,3,9,10,'shrink','shrink',2,2);
|
$mtable->attach($back,2,3,9,10,'shrink','shrink',2,2);
|
$mtable->attach($next,8,9,9,10,'shrink','shrink',2,2);
|
$mtable->attach($next,8,9,9,10,'shrink','shrink',2,2);
|
|
|
|
|
|
|
|
|
|
|
my $board_name=$self->object_get_attribute('compile','board');
|
my $board_name=$self->object_get_attribute('compile','board');
|
|
|
#copy board jtag_intfc.sh file
|
#copy board jtag_intfc.sh file
|
my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
|
my ($fname,$fpath,$fsuffix) = fileparse("$top",qr"\..[^.]*$");
|
copy("../boards/$board_name/jtag_intfc.sh","${fpath}../sw/jtag_intfc.sh");
|
copy("../boards/$board_name/jtag_intfc.sh","${fpath}../sw/jtag_intfc.sh");
|
my $n= $self->object_get_attribute('soc_name',undef);
|
my $m= $self->object_get_attribute('mpsoc_name',undef);
|
if(!defined $n){ # we are compiling a complete NoC-based mpsoc
|
if(defined $m){ # we are compiling a complete NoC-based mpsoc
|
my $nx= $self->object_get_attribute('noc_param',"NX");
|
my ($nr,$ne,$router_p,$ref_tops)= get_noc_verilator_top_modules_info($self);
|
my $ny= $self->object_get_attribute('noc_param',"NY");
|
for (my $tile_num=0;$tile_num<$ne;$tile_num++){
|
for (my $y=0;$y<$ny;$y++){for (my $x=0; $x<$nx;$x++){
|
|
my $tile_num= $y*$nx+$x;
|
|
#print "$tile_num\n";
|
#print "$tile_num\n";
|
my ($soc_name,$num)= $self->mpsoc_get_tile_soc_name($tile_num);
|
my ($soc_name,$num)= $self->mpsoc_get_tile_soc_name($tile_num);
|
next if(!defined $soc_name);
|
next if(!defined $soc_name);
|
copy("../boards/$board_name/jtag_intfc.sh","${fpath}../sw/tile$tile_num/jtag_intfc.sh");
|
copy("../boards/$board_name/jtag_intfc.sh","${fpath}../sw/tile$tile_num/jtag_intfc.sh");
|
}}
|
}
|
|
|
}
|
}
|
|
|
|
|
|
|
Line 878... |
Line 859... |
$box=get_range ($board,$self,$type,$text,$portrange,$p);
|
$box=get_range ($board,$self,$type,$text,$portrange,$p);
|
$table->attach($box, 5,6, $loc, $loc+1,'fill','shrink',2,2);
|
$table->attach($box, 5,6, $loc, $loc+1,'fill','shrink',2,2);
|
}
|
}
|
|
|
|
|
|
|
|
|
$combo->signal_connect("changed" => sub{
|
$combo->signal_connect("changed" => sub{
|
|
|
#get and saved new value
|
#get and saved new value
|
my $treeiter= $combo->get_active_iter();
|
my $treeiter= $combo->get_active_iter();
|
my $text = $models{$type}->get_value($treeiter, 0);
|
my $text = $models{$type}->get_value($treeiter, 0);
|
Line 900... |
Line 879... |
|
|
});
|
});
|
|
|
$table->attach($combo, 4,5, $row, $row+1,'fill','shrink',2,2);
|
$table->attach($combo, 4,5, $row, $row+1,'fill','shrink',2,2);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$row++;
|
$row++;
|
|
|
}
|
}
|
$next-> signal_connect("clicked" => sub{
|
$next-> signal_connect("clicked" => sub{
|
|
|
Line 949... |
Line 922... |
}
|
}
|
|
|
my ($app,$table,$tview,$window) = software_main($fpath,'Top.v');
|
my ($app,$table,$tview,$window) = software_main($fpath,'Top.v');
|
$table->attach($back,1,2,1,2,'shrink','shrink',2,2);
|
$table->attach($back,1,2,1,2,'shrink','shrink',2,2);
|
$table->attach($regen,4,5,1,2,'shrink','shrink',2,2);
|
$table->attach($regen,4,5,1,2,'shrink','shrink',2,2);
|
$table->attach ($run,7, 8, 1,2,'shrink','shrink',2,2);
|
$table->attach ($run,6, 7, 1,2,'shrink','shrink',2,2);
|
$table->attach($prog,9,10,1,2,'shrink','shrink',2,2);
|
$table->attach($prog,9,10,1,2,'shrink','shrink',2,2);
|
|
|
|
|
|
|
$regen-> signal_connect("clicked" => sub{
|
$regen-> signal_connect("clicked" => sub{
|
Line 981... |
Line 954... |
});
|
});
|
|
|
|
|
#compile
|
#compile
|
$run-> signal_connect("clicked" => sub{
|
$run-> signal_connect("clicked" => sub{
|
|
my $load= show_gif("icons/load.gif");
|
|
$table->attach ($load,8, 9, 1,2,'shrink','shrink',2,2);
|
|
$load->show_all;
|
|
|
set_gui_status($self,'save_project',1);
|
set_gui_status($self,'save_project',1);
|
$app->do_save();
|
$app->do_save();
|
my $error = 0;
|
my $error = 0;
|
add_info(\$tview,"CREATE: start creating Quartus project in $target_dir\n");
|
add_info(\$tview,"CREATE: start creating Quartus project in $target_dir\n");
|
|
|
Line 1063... |
Line 1040... |
$window->destroy;
|
$window->destroy;
|
}else {
|
}else {
|
message_dialog("Error in Quartus compilation!",'error');
|
message_dialog("Error in Quartus compilation!",'error');
|
}
|
}
|
}
|
}
|
|
$load->destroy;
|
|
|
});
|
});
|
|
|
|
|
#Programe the board
|
#Programe the board
|
Line 1105... |
Line 1083... |
}
|
}
|
|
|
}
|
}
|
});
|
});
|
|
|
|
|
}
|
}
|
|
|
|
|
|
|
|
|
Line 1122... |
Line 1099... |
|
|
my $run=def_image_button('icons/run.png','run');
|
my $run=def_image_button('icons/run.png','run');
|
my $back=def_image_button('icons/left.png','Previous');
|
my $back=def_image_button('icons/left.png','Previous');
|
my $regen=def_image_button('icons/refresh.png','Regenerate testbench.v');
|
my $regen=def_image_button('icons/refresh.png','Regenerate testbench.v');
|
#create testbench.v
|
#create testbench.v
|
gen_modelsim_soc_testbench ($self,$name,$top,$target_dir) if ((-f "$target_dir/src_verilog/testbench.v")==0);
|
gen_modelsim_soc_testbench ($self,$name,$top,$target_dir) unless (-f "$target_dir/src_verilog/testbench.v");
|
|
|
|
|
|
|
my ($app,$table,$tview,$window) = software_main("$target_dir/src_verilog",'testbench.v');
|
my ($app,$table,$tview,$window) = software_main("$target_dir/src_verilog",'testbench.v');
|
$table->attach($back,1,2,1,2,'shrink','shrink',2,2);
|
$table->attach($back,1,2,1,2,'shrink','shrink',2,2);
|
Line 1148... |
Line 1125... |
}
|
}
|
$dialog->destroy;
|
$dialog->destroy;
|
|
|
});
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
$back-> signal_connect("clicked" => sub{
|
$back-> signal_connect("clicked" => sub{
|
|
|
$window->destroy;
|
$window->destroy;
|
select_compiler($self,$name,$top,$target_dir);
|
select_compiler($self,$name,$top,$target_dir);
|
|
|
Line 1241... |
Line 1213... |
rmtree("$verilator/rtl_work");
|
rmtree("$verilator/rtl_work");
|
rmtree("$verilator/processed_rtl");
|
rmtree("$verilator/processed_rtl");
|
mkpath("$verilator/rtl_work/",1,01777);
|
mkpath("$verilator/rtl_work/",1,01777);
|
mkpath("$verilator/processed_rtl/",1,01777);
|
mkpath("$verilator/processed_rtl/",1,01777);
|
|
|
|
my @ff = ("$target_dir/src_verilog");
|
|
push (@ff,"$target_dir/src_verilator") if (-d "$target_dir/src_verilator");
|
|
|
|
|
|
|
#copy all verilog files in rtl_work folder
|
#copy all verilog files in rtl_work folder
|
add_info(\$outtext,"Copy all verilog files in rtl_work folder\n");
|
add_info(\$outtext,"Copy all verilog files in rtl_work folder\n");
|
my @files = File::Find::Rule->file()
|
my @files = File::Find::Rule->file()
|
->name( '*.v','*.V','*.sv','*.vh')
|
->name( '*.v','*.V','*.sv','*.vh')
|
->in( "$target_dir/src_verilog","$target_dir/src_verilator" );
|
->in( @ff );
|
foreach my $file (@files) {
|
foreach my $file (@files) {
|
copy($file,"$verilator/rtl_work/");
|
copy($file,"$verilator/rtl_work/");
|
}
|
}
|
|
|
@files = File::Find::Rule->file()
|
@files = File::Find::Rule->file()
|
->name( '*.sv','*.vh' )
|
->name( '*.sv','*.vh' )
|
->in( "$target_dir/src_verilog","$target_dir/src_verilator" );
|
->in( @ff );
|
foreach my $file (@files) {
|
foreach my $file (@files) {
|
copy($file,"$verilator/processed_rtl");
|
copy($file,"$verilator/processed_rtl");
|
}
|
}
|
|
|
|
|
Line 1357... |
Line 1333... |
|
|
clean:
|
clean:
|
rm *.o *.a testbench
|
rm *.o *.a testbench
|
";
|
";
|
|
|
|
|
|
|
save_file ($target_dir,$make);
|
save_file ($target_dir,$make);
|
|
|
|
|
|
|
|
|
}
|
}
|
|
|
|
|
|
|
sub verilator_compilation_win {
|
sub verilator_compilation_win {
|
my ($self,$name,$top,$target_dir)=@_;
|
my ($self,$name,$top,$target_dir)=@_;
|
my $window = def_popwin_size(80,80,"Step 2: Compile",'percent');
|
my $window = def_popwin_size(80,80,"Step 2: Compile",'percent');
|
my $mtable = def_table(10, 10, FALSE);
|
my $mtable = def_table(10, 10, FALSE);
|
my ($outbox,$outtext)= create_text();
|
my ($outbox,$outtext)= create_text();
|
add_colors_to_textview($outtext);
|
|
|
|
my $next=def_image_button('icons/run.png','Next');
|
my $next=def_image_button('icons/run.png','Next');
|
my $back=def_image_button('icons/left.png','Previous');
|
my $back=def_image_button('icons/left.png','Previous');
|
|
my $load= show_gif("icons/load.gif");
|
|
$mtable->attach($load,8,9,9,10,'shrink','shrink',2,2);
|
|
|
$mtable->attach_defaults ($outbox ,0, 10, 4,9);
|
$mtable->attach_defaults ($outbox ,0, 10, 4,9);
|
$mtable->attach($back,2,3,9,10,'shrink','shrink',2,2);
|
$mtable->attach($back,2,3,9,10,'shrink','shrink',2,2);
|
$mtable->attach($next,8,9,9,10,'shrink','shrink',2,2);
|
|
|
|
|
|
|
|
$back-> signal_connect("clicked" => sub{
|
$back-> signal_connect("clicked" => sub{
|
|
|
Line 1420... |
Line 1393... |
|
|
|
|
#check if verilator model has been generated
|
#check if verilator model has been generated
|
if ($result){
|
if ($result){
|
add_colored_info(\$outtext,"Veriator model has been generated successfully!",'blue');
|
add_colored_info(\$outtext,"Veriator model has been generated successfully!",'blue');
|
|
$load->destroy();
|
|
$mtable->attach($next,8,9,9,10,'shrink','shrink',2,2);
|
}else {
|
}else {
|
add_colored_info(\$outtext,"Verilator compilation failed!\n","red");
|
add_colored_info(\$outtext,"Verilator compilation failed!\n","red");
|
|
$load->destroy();
|
$next->destroy();
|
$next->destroy();
|
}
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
}
|
|
|
|
|
|
|
|
|
Line 1443... |
Line 1411... |
sub gen_mpsoc_verilator_model{
|
sub gen_mpsoc_verilator_model{
|
my ($self,$name,$top,$target_dir,$outtext)=@_;
|
my ($self,$name,$top,$target_dir,$outtext)=@_;
|
my $dir = Cwd::getcwd();
|
my $dir = Cwd::getcwd();
|
my $project_dir = abs_path("$dir/..");
|
my $project_dir = abs_path("$dir/..");
|
my $src_verilator_dir="$project_dir/src_verilator";
|
my $src_verilator_dir="$project_dir/src_verilator";
|
my $sw_dir = "$target_dir/sw";
|
my $target_verilog_dr ="$target_dir/src_verilog";
|
|
my $target_verilator_dr ="$target_dir/src_verilator";
|
|
|
|
my $sw_dir = "$target_dir/sw";
|
|
my $src_noc_dir="$project_dir/src_noc";
|
|
mkpath("$target_verilator_dr",1,01777);
|
|
|
#copy src_verilator files
|
#copy src_verilator files
|
add_info(\$outtext,"Copy verilator files\n");
|
my @files_list = File::Find::Rule->file()
|
my @files=(
|
->name( '*.v','*.V','*.sv' )
|
"$src_verilator_dir/noc_connection.sv",
|
->in( "$src_verilator_dir" );
|
"$src_verilator_dir/router_verilator.v"
|
|
);
|
#make sure source files have key word 'module'
|
if (-d "$target_dir/src_verilator/"==0){
|
my @files;
|
mkpath("$target_dir/src_verilator/",1,01777);
|
foreach my $p (@files_list){
|
|
push (@files,$p) if(check_file_has_string($p,'module'));
|
}
|
}
|
copy_file_and_folders (\@files,$project_dir,"$target_dir/src_verilator");
|
copy_file_and_folders (\@files,$project_dir,$target_verilator_dr);
|
|
|
|
|
|
|
|
#copy src_noc files
|
|
#my @files2;
|
|
#push (@files2,$src_noc_dir);
|
|
#copy_file_and_folders (\@files2,$project_dir,$target_verilog_dr);
|
|
|
|
|
#create each tile top module
|
#create each tile top module
|
my $nx= $self->object_get_attribute('noc_param',"NX");
|
|
my $ny= $self->object_get_attribute('noc_param',"NY");
|
|
my $processors_en=0;
|
my $processors_en=0;
|
my $mpsoc=$self;
|
my $mpsoc=$self;
|
|
|
my $lisence= get_license_header("verilator_tiles");
|
my $lisence= get_license_header("verilator_tiles");
|
my $warning=autogen_warning();
|
my $warning=autogen_warning();
|
my $verilator=$lisence.$warning;
|
my $verilator=$lisence.$warning;
|
|
|
|
|
# generate NoC parameter file
|
# generate NoC parameter file
|
my ($noc_param,$pass_param)=gen_noc_param_v($self);
|
my ($noc_param,$pass_param)=gen_noc_param_v($self);
|
|
|
my $noc_param_v= " \`ifdef INCLUDE_PARAM \n \n
|
my $noc_param_v= " \`ifdef INCLUDE_PARAM \n \n
|
$noc_param
|
$noc_param
|
/* verilator lint_off WIDTH */
|
|
localparam P=(TOPOLOGY==\"RING\" || TOPOLOGY==\"LINE\")? 3 : 5;
|
|
localparam ROUTE_TYPE = (ROUTE_NAME == \"XY\" || ROUTE_NAME == \"TRANC_XY\" )? \"DETERMINISTIC\" :
|
|
(ROUTE_NAME == \"DUATO\" || ROUTE_NAME == \"TRANC_DUATO\" )? \"FULL_ADAPTIVE\": \"PAR_ADAPTIVE\";
|
|
/* verilator lint_on WIDTH */
|
|
//simulation parameter
|
//simulation parameter
|
|
|
\n \n \`endif" ;
|
\n \n \`endif" ;
|
save_file("$target_dir/src_verilator/parameter.v",$noc_param_v);
|
save_file("$target_verilator_dr/parameter.v",$noc_param_v);
|
|
|
|
|
|
|
my %tops = (
|
|
"Vrouter" => "router_verilator.v",
|
|
"Vnoc" => "noc_connection.sv"
|
|
);
|
|
|
|
for (my $y=0;$y<$ny;$y++){
|
my ($nr,$ne,$router_p,$ref_tops)= get_noc_verilator_top_modules_info($self);
|
for (my $x=0; $x<$nx;$x++){
|
my %tops = %{$ref_tops};
|
|
|
|
for (my $tile_num=0;$tile_num<$ne;$tile_num++){
|
|
|
my $tile_num= $y*$nx+$x;
|
|
#print "$tile_num\n";
|
#print "$tile_num\n";
|
my ($soc_name,$num)= $mpsoc->mpsoc_get_tile_soc_name($tile_num);
|
my ($soc_name,$num)= $mpsoc->mpsoc_get_tile_soc_name($tile_num);
|
if(!defined $soc_name){
|
|
#this tile is not connected to any ip. the noc input ports will be connected to ground
|
|
my $soc_v="\n\n // Tile:$tile_num (x=$x,y=$y) is not assigned to any ip\n";
|
|
$soc_v="$soc_v
|
|
|
|
assign ni_credit_out[$tile_num]={V{1'b0}};
|
|
assign ni_flit_out[$tile_num]={Fw{1'b0}};
|
|
assign ni_flit_out_wr[$tile_num]=1'b0;
|
|
";
|
|
next;
|
|
|
|
}
|
|
my $soc=eval_soc($mpsoc,$soc_name,$outtext);
|
my $soc=eval_soc($mpsoc,$soc_name,$outtext);
|
|
|
|
|
my $top=$mpsoc->mpsoc_get_soc($soc_name);
|
my $top=$mpsoc->mpsoc_get_soc($soc_name);
|
my $soc_num= $y*$nx+$x;
|
my $soc_num= $tile_num;
|
|
|
|
|
|
|
|
|
#update core id
|
#update core id
|
$soc->object_add_attribute('global_param','CORE_ID',$tile_num);
|
$soc->object_add_attribute('global_param','CORE_ID',$tile_num);
|
|
|
#update NoC param
|
#update NoC param
|
#my %nocparam = %{$mpsoc->object_get_attribute('noc_param',undef)};
|
|
my $nocparam =$mpsoc->object_get_attribute('noc_param',undef);
|
my $nocparam =$mpsoc->object_get_attribute('noc_param',undef);
|
|
my ($NE, $NR, $RAw, $EAw, $Fw) = get_topology_info($mpsoc);
|
|
my %y=%{$nocparam};
|
|
$y{'EAw'} = $EAw;
|
|
$y{'RAw'} = $RAw;
|
|
$y{'Fw'} = $Fw;
|
my @nis=get_NI_instance_list($top);
|
my @nis=get_NI_instance_list($top);
|
$soc->soc_add_instance_param($nis[0] ,$nocparam );
|
$soc->soc_add_instance_param($nis[0] ,\%y );
|
my $tile=($nx*$y)+ $x;
|
|
|
|
|
my $tile=$tile_num;
|
my $setting=$mpsoc->mpsoc_get_tile_param_setting($tile);
|
my $setting=$mpsoc->mpsoc_get_tile_param_setting($tile);
|
my %params;
|
my %params;
|
if ($setting eq 'Custom'){
|
if ($setting eq 'Custom'){
|
%params= $top->top_get_custom_soc_param($tile);
|
%params= $top->top_get_custom_soc_param($tile);
|
}else{
|
}else{
|
Line 1540... |
Line 1503... |
my $sw_path = "$sw_dir/tile$tile_num";
|
my $sw_path = "$sw_dir/tile$tile_num";
|
$verilator = $verilator.soc_generate_verilatore ($soc,$sw_path,"tile_$tile",\%params);
|
$verilator = $verilator.soc_generate_verilatore ($soc,$sw_path,"tile_$tile",\%params);
|
$tops{"Vtile$tile_num"}= "tile_$tile.v";
|
$tops{"Vtile$tile_num"}= "tile_$tile.v";
|
|
|
|
|
}}
|
}
|
|
|
save_file ("$target_dir/src_verilator/verilator_tiles.v",$verilator);
|
save_file ("$target_verilator_dr/verilator_tiles.v",$verilator);
|
my $result = verilator_compilation (\%tops,$target_dir,$outtext);
|
my $result = verilator_compilation (\%tops,$target_dir,$outtext);
|
$self->object_add_attribute('verilator','libs',\%tops);
|
$self->object_add_attribute('verilator','libs',\%tops);
|
return $result;
|
return $result;
|
|
|
}
|
}
|
Line 1649... |
Line 1612... |
sub eval_soc{
|
sub eval_soc{
|
my ($mpsoc,$soc_name,$outtext)=@_;
|
my ($mpsoc,$soc_name,$outtext)=@_;
|
my $path=$mpsoc->object_get_attribute('setting','soc_path');
|
my $path=$mpsoc->object_get_attribute('setting','soc_path');
|
$path=~ s/ /\\ /g;
|
$path=~ s/ /\\ /g;
|
my $p = "$path/$soc_name.SOC";
|
my $p = "$path/$soc_name.SOC";
|
my $soc = eval { do $p };
|
my ($soc,$r,$err) = regen_object($p);
|
if ($@ || !defined $soc){
|
if ($r){
|
show_info(\$outtext,"**Error reading $p file: $@\n");
|
show_info(\$outtext,"**Error reading $p file: $err\n");
|
next;
|
next;
|
}
|
}
|
return $soc;
|
return $soc;
|
}
|
}
|
|
|
|
|
sub gen_verilator_mpsoc_testbench {
|
sub gen_verilator_mpsoc_testbench {
|
my ($mpsoc,$name,$top,$target_dir,$tview)=@_;
|
my ($mpsoc,$name,$top,$target_dir,$tview)=@_;
|
my $verilator="$target_dir/verilator";
|
my $verilator="$target_dir/verilator";
|
my $dir="$verilator/";
|
my $dir="$verilator/";
|
#my $soc_top= $self->soc_get_top ();
|
my $parameter_h=gen_noc_param_h($mpsoc);
|
|
|
|
my ($nr,$ne,$router_p,$ref_tops,$includ_h)= get_noc_verilator_top_modules_info($mpsoc);
|
|
$parameter_h=$parameter_h.$includ_h;
|
|
|
|
|
my $nx= $mpsoc->object_get_attribute('noc_param',"NX");
|
|
my $ny= $mpsoc->object_get_attribute('noc_param',"NY");
|
|
|
|
my $libh="";
|
my $libh="";
|
my $inst= "";
|
my $inst= "";
|
my $newinst="";
|
my $newinst="";
|
|
|
my $tile_x="";
|
my $tile_addr="";
|
my $tile_y="";
|
|
my $tile_flit_in="";
|
my $tile_flit_in="";
|
my $tile_flit_in_l="";
|
my $tile_flit_in_l="";
|
my $tile_credit="";
|
my $tile_credit="";
|
my $noc_credit="";
|
my $noc_credit="";
|
my $noc_flit_in="";
|
my $noc_flit_in="";
|
Line 1691... |
Line 1655... |
my $tile_clk="";
|
my $tile_clk="";
|
my $tile_en="";
|
my $tile_en="";
|
my $top_port_info="IO type\t port_size\t port_name\n";
|
my $top_port_info="IO type\t port_size\t port_name\n";
|
my $no_connected='';
|
my $no_connected='';
|
|
|
for (my $y=0;$y<$ny;$y++){for (my $x=0; $x<$nx;$x++){
|
for (my $endp=0; $endp<$ne;$endp++){
|
my $t= $y*$nx+$x;
|
|
my ($soc_name,$num)= $mpsoc->mpsoc_get_tile_soc_name($t);
|
|
if(defined $soc_name) {#we have a conncted tile
|
|
|
|
#get ni instance name
|
|
my $ni_name;
|
|
my $soc=eval_soc($mpsoc,$soc_name,$tview);
|
|
my $soc_top=$soc->object_get_attribute('top_ip',undef);
|
|
my @intfcs=$soc_top->top_get_intfc_list();
|
|
my @instances=$soc->soc_get_all_instances();
|
|
foreach my $id (@instances){
|
|
my $category = $soc->soc_get_category($id);
|
|
if ($category eq 'NoC') {
|
|
$ni_name= $soc->soc_get_instance_name($id);
|
|
}
|
|
}
|
|
|
|
|
|
$libh=$libh."#include \"Vtile${t}.h\"\n";
|
|
$inst=$inst."Vtile${t}\t*tile${t};\t // Instantiation of tile${t}\n";
|
|
$newinst = $newinst."\ttile${t}\t=\tnew Vtile${t};\n";
|
|
$tile_flit_in = $tile_flit_in . "\ttile${t}->${ni_name}_flit_in = noc->ni_flit_out [${t}];\n";
|
|
$tile_flit_in_l = $tile_flit_in_l . "\t\ttile${t}->${ni_name}_flit_in[j] = noc->ni_flit_out [${t}][j];\n";
|
|
$tile_credit= $tile_credit."\ttile${t}->${ni_name}_credit_in= noc->ni_credit_out[${t}];\n";
|
|
$noc_credit= $noc_credit."\tnoc->ni_credit_in[${t}] = tile${t}->${ni_name}_credit_out;\n";
|
|
$noc_flit_in=$noc_flit_in."\tnoc->ni_flit_in [${t}] = tile${t}->${ni_name}_flit_out;\n";
|
|
$noc_flit_in_l=$noc_flit_in_l."\t\t\tnoc->ni_flit_in [${t}][j] = tile${t}->${ni_name}_flit_out[j];\n";
|
|
$noc_flit_in_wr= $noc_flit_in_wr."\tif(tile${t}->${ni_name}_flit_out_wr) noc->ni_flit_in_wr = noc->ni_flit_in_wr | ((vluint64_t)1<<${t});\n";
|
|
$tile_flit_in_wr=$tile_flit_in_wr."\ttile${t}->${ni_name}_flit_in_wr= ((noc->ni_flit_out_wr >> ${t}) & 0x01);\n";
|
|
$noc_flit_in_wr_l= $noc_flit_in_wr_l."\tif(tile${t}->${ni_name}_flit_out_wr) MY_VL_SETBIT_W(noc->ni_flit_in_wr ,${t});\n";
|
|
$tile_flit_in_wr_l=$tile_flit_in_wr_l."\ttile${t}->${ni_name}_flit_in_wr= (VL_BITISSET_W(noc->ni_flit_out_wr,${t})>0);\n";
|
|
$tile_eval=$tile_eval."\ttile${t}->eval();\n";
|
|
$tile_final=$tile_final."\ttile${t}->final();\n";
|
|
|
|
|
|
|
my $e_addr=endp_addr_encoder($mpsoc,$endp);
|
|
my $router_num = get_connected_router_id_to_endp($mpsoc,$endp);
|
|
my $r_addr=router_addr_encoder($mpsoc,$router_num);
|
|
|
|
|
|
my ($soc_name,$num)= $mpsoc->mpsoc_get_tile_soc_name($endp);
|
|
if(defined $soc_name) {#we have a conncted tile
|
|
|
|
#get ni instance name
|
|
my $ni_name;
|
|
my $soc=eval_soc($mpsoc,$soc_name,$tview);
|
|
my $soc_top=$soc->object_get_attribute('top_ip',undef);
|
|
my @intfcs=$soc_top->top_get_intfc_list();
|
|
my @instances=$soc->soc_get_all_instances();
|
|
foreach my $id (@instances){
|
|
my $category = $soc->soc_get_category($id);
|
|
if ($category eq 'NoC') {
|
|
$ni_name= $soc->soc_get_instance_name($id);
|
|
}
|
|
}
|
|
|
|
|
|
$libh=$libh."#include \"Vtile${endp}.h\"\n";
|
|
$inst=$inst."Vtile${endp}\t*tile${endp};\t // Instantiation of tile${endp}\n";
|
|
$newinst = $newinst."\ttile${endp}\t=\tnew Vtile${endp};\n";
|
|
$tile_flit_in = $tile_flit_in . "\ttile${endp}->${ni_name}_flit_in = noc->ni_flit_out [${endp}];\n";
|
|
$tile_flit_in_l = $tile_flit_in_l . "\t\ttile${endp}->${ni_name}_flit_in[j] = noc->ni_flit_out [${endp}][j];\n";
|
|
$tile_credit= $tile_credit."\ttile${endp}->${ni_name}_credit_in= noc->ni_credit_out[${endp}];\n";
|
|
$noc_credit= $noc_credit."\tnoc->ni_credit_in[${endp}] = tile${endp}->${ni_name}_credit_out;\n";
|
|
$noc_flit_in=$noc_flit_in."\tnoc->ni_flit_in [${endp}] = tile${endp}->${ni_name}_flit_out;\n";
|
|
$noc_flit_in_l=$noc_flit_in_l."\t\t\tnoc->ni_flit_in [${endp}][j] = tile${endp}->${ni_name}_flit_out[j];\n";
|
|
$noc_flit_in_wr= $noc_flit_in_wr."\tif(tile${endp}->${ni_name}_flit_out_wr) noc->ni_flit_in_wr = noc->ni_flit_in_wr | ((vluint64_t)1<<${endp});\n";
|
|
$tile_flit_in_wr=$tile_flit_in_wr."\ttile${endp}->${ni_name}_flit_in_wr= ((noc->ni_flit_out_wr >> ${endp}) & 0x01);\n";
|
|
$noc_flit_in_wr_l= $noc_flit_in_wr_l."\tif(tile${endp}->${ni_name}_flit_out_wr) MY_VL_SETBIT_W(noc->ni_flit_in_wr ,${endp});\n";
|
|
$tile_flit_in_wr_l=$tile_flit_in_wr_l."\ttile${endp}->${ni_name}_flit_in_wr= (VL_BITISSET_W(noc->ni_flit_out_wr,${endp})>0);\n";
|
|
$tile_eval=$tile_eval."\ttile${endp}->eval();\n";
|
|
$tile_final=$tile_final."\ttile${endp}->final();\n";
|
|
|
|
|
|
foreach my $intfc (@intfcs){
|
|
my $key=($intfc eq 'plug:clk[0]')? 'clk' :
|
|
($intfc eq 'plug:reset[0]')? 'reset':
|
|
($intfc eq 'plug:enable[0]')? 'en' :
|
|
'other';
|
|
|
|
my @ports=$soc_top->top_get_intfc_ports_list($intfc);
|
|
foreach my $p (@ports){
|
|
my($inst,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
|
|
$tile_reset=$tile_reset."\t\ttile${endp}->$p=reset;\n" if $key eq 'reset';
|
|
$tile_clk=$tile_clk."\t\ttile${endp}->$p=clk;\n" if $key eq 'clk';
|
|
$tile_en=$tile_en."\t\ttile${endp}->$p=enable;\n" if $key eq 'en'; ;
|
|
$top_port_info="$top_port_info $type $range tile${endp}->$p \n";
|
|
}#ports
|
|
|
|
}#interface
|
|
|
|
$tile_addr= $tile_addr."\ttile${endp}->${ni_name}_current_r_addr=$r_addr; // noc->er_addr[${endp}];\n";
|
|
$tile_addr= $tile_addr."\ttile${endp}->${ni_name}_current_e_addr=$e_addr;\n";
|
|
|
|
}else{
|
|
#this tile is not connected to any ip. the noc input ports will be connected to ground
|
|
$no_connected=$no_connected."\n // Tile:$endp ($e_addr) is not assigned to any ip\n";
|
|
$no_connected=$no_connected."\t\tnoc->ni_credit_in[${endp}]=0; \n";
|
|
|
|
}
|
|
|
foreach my $intfc (@intfcs){
|
|
my $key=($intfc eq 'plug:clk[0]')? 'clk' :
|
|
($intfc eq 'plug:reset[0]')? 'reset':
|
|
($intfc eq 'plug:enable[0]')? 'en' :
|
|
'other';
|
|
|
|
my @ports=$soc_top->top_get_intfc_ports_list($intfc);
|
|
foreach my $p (@ports){
|
|
my($inst,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
|
|
$tile_reset=$tile_reset."\t\ttile${t}->$p=reset;\n" if $key eq 'reset';
|
|
$tile_clk=$tile_clk."\t\ttile${t}->$p=clk;\n" if $key eq 'clk';
|
|
$tile_en=$tile_en."\t\ttile${t}->$p=enable;\n" if $key eq 'en'; ;
|
|
$top_port_info="$top_port_info $type $range tile${t}->$p \n";
|
|
}#ports
|
|
|
|
}#interface
|
|
|
|
$tile_x= $tile_x."\ttile${t}->${ni_name}_current_x=$x;\n";
|
|
$tile_y= $tile_y."\ttile${t}->${ni_name}_current_y=$y;\n";
|
|
}else{
|
|
#this tile is not connected to any ip. the noc input ports will be connected to ground
|
|
$no_connected=$no_connected."\n // Tile:$t (x=$x,y=$y) is not assigned to any ip\n";
|
|
$no_connected=$no_connected."\t\tnoc->ni_credit_in[${t}]=0; \n";
|
|
|
|
}
|
|
|
|
|
}
|
|
my $main_c=get_license_header("testbench.cpp");
|
|
|
}}
|
$main_c="$main_c
|
my $main_c=get_license_header("testbench.cpp");
|
|
$main_c="$main_c
|
|
#include <stdlib.h>
|
#include <stdlib.h>
|
#include <stdio.h>
|
#include <stdio.h>
|
#include <unistd.h>
|
#include <unistd.h>
|
#include <string.h>
|
#include <string.h>
|
#include <verilated.h> // Defines common routines
|
#include <verilated.h> // Defines common routines
|
|
|
#include \"Vnoc.h\"
|
#include \"Vnoc.h\"
|
#include \"Vrouter.h\"
|
|
$libh
|
$libh
|
|
|
|
Vnoc *noc;
|
|
$inst
|
|
int reset,clk,enable;
|
|
|
/*
|
|
$top_port_info
|
|
*/
|
|
|
|
|
|
#ifndef NX
|
|
#define NX $nx
|
|
#endif
|
|
|
|
#ifndef NY
|
|
#define NY $ny
|
|
#endif
|
|
|
|
#ifndef NC
|
|
#define NC ($nx*$ny)
|
|
#endif
|
|
|
|
|
#include \"parameter.h\"
|
|
|
Vrouter *router[NC]; // Instantiation of router
|
|
Vnoc *noc;
|
|
$inst
|
|
|
|
|
/*
|
|
$top_port_info
|
|
*/
|
|
|
|
|
int reset,clk,enable;
|
|
unsigned int main_time = 0; // Current simulation time
|
unsigned int main_time = 0; // Current simulation time
|
|
|
void update_all_instances_inputs(void);
|
void update_all_instances_inputs(void);
|
|
|
|
|
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
int i,j,x,y;
|
int i,j,x,y;
|
|
|
Verilated::commandArgs(argc, argv); // Remember args
|
Verilated::commandArgs(argc, argv); // Remember args
|
|
Vrouter_new(); // Create instance
|
for(i=0;i<NC;i++) router[i] = new Vrouter; // Create instance
|
|
noc = new Vnoc;
|
noc = new Vnoc;
|
$newinst
|
$newinst
|
|
|
/********************
|
/********************
|
* initialize input
|
* initialize input
|
Line 1819... |
Line 1771... |
|
|
|
|
reset=1;
|
reset=1;
|
enable=1;
|
enable=1;
|
$no_connected
|
$no_connected
|
for(x=0;x<NX;x++)for(y=0;y<NY;y++){
|
|
i=(y*NX)+x;
|
$tile_addr
|
router[i]->current_x = x;
|
|
router[i]->current_y = y;
|
|
}
|
|
$tile_x
|
|
$tile_y
|
|
|
|
main_time=0;
|
main_time=0;
|
printf(\"Start Simulation\\n\");
|
printf(\"Start Simulation\\n\");
|
while (!Verilated::gotFinish()) {
|
while (!Verilated::gotFinish()) {
|
|
|
if (main_time >= 10 ) {
|
if (main_time >= 10 ) {
|
reset=0;
|
reset=0;
|
}
|
}
|
Line 1856... |
Line 1804... |
noc-> clk = clk;
|
noc-> clk = clk;
|
noc-> reset = reset;
|
noc-> reset = reset;
|
$tile_reset
|
$tile_reset
|
$tile_clk
|
$tile_clk
|
$tile_en
|
$tile_en
|
for(i=0;i<NC;i++){
|
|
router[i]->reset= reset;
|
connect_routers_reset_clk();
|
router[i]->clk= clk;
|
|
}
|
|
|
|
//eval instances
|
//eval instances
|
noc->eval();
|
noc->eval();
|
for(i=0;i<NC;i++) {
|
routers_eval();
|
router[i]->eval();
|
|
}
|
|
$tile_eval
|
$tile_eval
|
|
|
|
|
main_time++;
|
main_time++;
|
|
|
|
|
|
|
}//while
|
}//while
|
|
|
// Simulation is dne
|
// Simulation is done
|
for(i=0;i<NC;i++) {
|
routers_final();
|
router[i]->final();
|
|
}
|
|
noc->final();
|
noc->final();
|
$tile_final
|
$tile_final
|
}
|
}
|
|
|
double sc_time_stamp () { // Called by \$time in Verilog
|
double sc_time_stamp () { // Called by \$time in Verilog
|
return main_time;
|
return main_time;
|
}
|
}
|
|
|
|
|
void update_all_instances_inputs(void){
|
void update_all_instances_inputs(void){
|
|
|
int x,y,i,j;
|
int x,y,i,j;
|
int flit_out_all_size = sizeof(router[0]->flit_out_all)/sizeof(router[0]->flit_out_all[0]);
|
|
|
|
#if (NC<=64)
|
#if (NC<=64)
|
noc->ni_flit_in_wr =0;
|
noc->ni_flit_in_wr =0;
|
#else
|
#else
|
for(j=0;j<(sizeof(noc->ni_flit_in_wr)/sizeof(noc->ni_flit_in_wr[0])); j++) noc->ni_flit_in_wr[j]=0;
|
for(j=0;j<(sizeof(noc->ni_flit_in_wr)/sizeof(noc->ni_flit_in_wr[0])); j++) noc->ni_flit_in_wr[j]=0;
|
#endif
|
#endif
|
for(x=0;x<NX;x++)for(y=0;y<NY;y++){
|
|
i=(y*NX)+x;
|
|
router[i]->flit_in_we_all = noc->router_flit_out_we_all[i];
|
|
router[i]->credit_in_all = noc->router_credit_out_all[i];
|
|
router[i]->congestion_in_all = noc->router_congestion_out_all[i];
|
|
for(j=0;j<flit_out_all_size;j++) router[i]->flit_in_all[j] = noc->router_flit_out_all[i][j];
|
|
noc->router_flit_in_we_all[i] = router[i]->flit_out_we_all ;
|
|
noc->router_credit_in_all[i] = router[i]->credit_out_all;
|
|
noc->router_congestion_in_all[i]= router[i]->congestion_out_all;
|
|
for(j=0;j<flit_out_all_size;j++) noc->router_flit_in_all[i][j] = router[i]->flit_out_all[j] ;
|
|
} //for
|
|
|
|
|
|
|
connect_all_routers_to_noc ();
|
|
|
|
|
#if (Fpay<=32)
|
#if (Fpay<=32)
|
//tile[i]->flit_in = noc->ni_flit_out [i];
|
//tile[i]->flit_in = noc->ni_flit_out [i];
|
$tile_flit_in
|
$tile_flit_in
|
Line 1959... |
Line 1891... |
#endif
|
#endif
|
|
|
|
|
|
|
}
|
}
|
";
|
";
|
|
|
save_file("$dir/testbench.cpp",$main_c);
|
|
|
|
}
|
|
|
|
|
|
|
|
sub soc_get_all_parameters {
|
|
my $soc=shift;
|
|
my @instances=$soc->soc_get_all_instances();
|
|
|
|
my %all_param;
|
|
foreach my $id (@instances){
|
|
|
|
my $module =$soc->soc_get_module($id);
|
|
my $category =$soc->soc_get_category($id);
|
|
my $inst = $soc->soc_get_instance_name($id);
|
|
my %params = $soc->soc_get_module_param($id);
|
|
my $ip = ip->lib_new ();
|
|
my @param_order=$soc->soc_get_instance_param_order($id);
|
|
|
|
foreach my $p (sort keys %params){
|
|
my $inst_param= "$inst\_$p";
|
|
#add instance name to parameter value
|
|
$params{$p}=add_instantc_name_to_parameters(\%params,$inst,$params{$p});
|
|
my ($default,$type,$content,$info,$vfile_param_type,$redefine_param)= $ip->ip_get_parameter($category,$module,$p);
|
|
$vfile_param_type= "Don't include" if (!defined $vfile_param_type );
|
|
$vfile_param_type= "Parameter" if ($vfile_param_type eq 1);
|
|
$vfile_param_type= "Localparam" if ($vfile_param_type eq 0);
|
|
$all_param{ $inst_param} = $params{ $p} if($vfile_param_type eq "Parameter" || $vfile_param_type eq "Localparam" );
|
|
print"$all_param{ $inst_param} = $params{ $p} if($vfile_param_type eq \"Parameter\" || $vfile_param_type eq \"Localparam\" ); \n";
|
|
}
|
|
}
|
|
return %all_param;
|
|
}
|
|
|
|
sub soc_get_all_parameters_order {
|
|
my $soc=shift;
|
|
my @instances=$soc->soc_get_all_instances();
|
|
my $ip = ip->lib_new ();
|
|
my @all_order;
|
|
foreach my $id (@instances){
|
|
my $module =$soc->soc_get_module($id);
|
|
my $category =$soc->soc_get_category($id);
|
|
my $inst = $soc->soc_get_instance_name($id);
|
|
my @order = $soc->soc_get_instance_param_order($id);
|
|
|
|
foreach my $p ( @order){
|
|
my $inst_param= "$inst\_$p";
|
|
my ($default,$type,$content,$info,$vfile_param_type,$redefine_param)= $ip->ip_get_parameter($category,$module,$p);
|
|
$vfile_param_type= "Don't include" if (!defined $vfile_param_type );
|
|
$vfile_param_type= "Parameter" if ($vfile_param_type eq 1);
|
|
$vfile_param_type= "Localparam" if ($vfile_param_type eq 0);
|
|
push(@all_order, $inst_param) if($vfile_param_type eq "Parameter" || $vfile_param_type eq "Localparam" );
|
|
}
|
|
}
|
|
return @all_order;
|
|
}
|
|
|
|
|
save_file("$dir/parameter.h",$parameter_h);
|
|
save_file("$dir/testbench.cpp",$main_c);
|
|
|
|
}
|
|
|
sub gen_modelsim_soc_testbench {
|
|
my ($self,$name,$top,$target_dir)=@_;
|
|
my $dir="$target_dir/src_verilog";
|
|
my $soc_top= $self->object_get_attribute('top_ip',undef);
|
|
my @intfcs=$soc_top->top_get_intfc_list();
|
|
my %PP;
|
|
my $top_port_def="// ${name}.v IO definition \n";
|
|
my $pin_assign;
|
|
my $rst_inputs='';
|
|
|
|
|
|
|
sub soc_get_all_parameters {
|
|
my $soc=shift;
|
|
my @instances=$soc->soc_get_all_instances();
|
|
|
|
my %all_param;
|
|
foreach my $id (@instances){
|
|
|
|
my $module =$soc->soc_get_module($id);
|
|
my $category =$soc->soc_get_category($id);
|
|
my $inst = $soc->soc_get_instance_name($id);
|
|
my %params = $soc->soc_get_module_param($id);
|
|
my $ip = ip->lib_new ();
|
|
my @param_order=$soc->soc_get_instance_param_order($id);
|
|
|
|
foreach my $p (sort keys %params){
|
|
my $inst_param= "$inst\_$p";
|
|
#add instance name to parameter value
|
|
$params{$p}=add_instantc_name_to_parameters(\%params,$inst,$params{$p});
|
|
my ($default,$type,$content,$info,$vfile_param_type,$redefine_param)= $ip->ip_get_parameter($category,$module,$p);
|
|
$vfile_param_type= "Don't include" if (!defined $vfile_param_type );
|
|
$vfile_param_type= "Parameter" if ($vfile_param_type eq 1);
|
|
$vfile_param_type= "Localparam" if ($vfile_param_type eq 0);
|
|
$all_param{ $inst_param} = $params{ $p} if($vfile_param_type eq "Parameter" || $vfile_param_type eq "Localparam" );
|
|
#print"$all_param{ $inst_param} = $params{ $p} if($vfile_param_type eq \"Parameter\" || $vfile_param_type eq \"Localparam\" ); \n";
|
|
}
|
|
}
|
|
return %all_param;
|
|
}
|
|
|
|
sub soc_get_all_parameters_order {
|
|
my $soc=shift;
|
|
my @instances=$soc->soc_get_all_instances();
|
|
my $ip = ip->lib_new ();
|
|
my @all_order;
|
|
foreach my $id (@instances){
|
|
my $module =$soc->soc_get_module($id);
|
|
my $category =$soc->soc_get_category($id);
|
|
my $inst = $soc->soc_get_instance_name($id);
|
|
my @order = $soc->soc_get_instance_param_order($id);
|
|
|
|
foreach my $p ( @order){
|
|
my $inst_param= "$inst\_$p";
|
|
my ($default,$type,$content,$info,$vfile_param_type,$redefine_param)= $ip->ip_get_parameter($category,$module,$p);
|
|
$vfile_param_type= "Don't include" if (!defined $vfile_param_type );
|
|
$vfile_param_type= "Parameter" if ($vfile_param_type eq 1);
|
|
$vfile_param_type= "Localparam" if ($vfile_param_type eq 0);
|
|
push(@all_order, $inst_param) if($vfile_param_type eq "Parameter" || $vfile_param_type eq "Localparam" );
|
|
}
|
|
}
|
|
return @all_order;
|
|
}
|
|
|
#add functions
|
|
my $d = Cwd::getcwd();
|
|
open my $file1, "<", "$d/lib/verilog/functions.v" or die;
|
|
my $functions_all='';
|
|
while (my $f1 = readline ($file1)) {
|
|
$functions_all="$functions_all $f1 ";
|
|
}
|
|
close($file1);
|
|
|
|
#get parameters
|
|
my $params_v="";
|
|
my $n= $self->object_get_attribute('soc_name',undef);
|
|
|
|
if(defined $n){ #we are compiling a single tile as SoC
|
sub gen_modelsim_soc_testbench {
|
my $core_id= $self->object_get_attribute('global_param','CORE_ID');
|
my ($self,$name,$top,$target_dir)=@_;
|
my $sw_loc = $self->object_get_attribute('global_param','SW_LOC');
|
my $dir="$target_dir/src_verilog";
|
|
my $soc_top= $self->object_get_attribute('top_ip',undef);
|
|
my @intfcs=$soc_top->top_get_intfc_list();
|
|
my %PP;
|
|
my $top_port_def="// ${name}.v IO definition \n";
|
|
my $pin_assign;
|
|
my $rst_inputs='';
|
|
|
$params_v="\tlocalparam\tCORE_ID=$core_id;
|
|
\tlocalparam\tSW_LOC=\"$sw_loc\";\n";
|
|
my %params=soc_get_all_parameters($self);
|
|
my @order= soc_get_all_parameters_order($self);
|
|
foreach my $p (@order){
|
|
add_text_to_string(\$params_v,"\tlocalparam $p = $params{$p};\n") if(defined $params{$p} );
|
|
}
|
|
}else{ # we are simulating a mpsoc
|
|
$params_v= gen_socs_param($self);
|
|
|
|
|
|
}
|
|
|
|
foreach my $intfc (@intfcs){
|
#add functions
|
my $key= ( $intfc eq 'plug:clk[0]')? 'clk' :
|
my $d = Cwd::getcwd();
|
( $intfc eq 'plug:reset[0]')? 'reset':
|
open my $file1, "<", "$d/lib/verilog/functions.v" or die;
|
( $intfc eq 'plug:enable[0]')? 'en' : 'other';
|
my $functions_all='';
|
my $key1="${key}1";
|
while (my $f1 = readline ($file1)) {
|
my $key0="${key}0";
|
$functions_all="$functions_all $f1 ";
|
|
}
|
|
close($file1);
|
|
|
my @ports=$soc_top->top_get_intfc_ports_list($intfc);
|
#get parameters
|
my $f=1;
|
my $params_v="";
|
foreach my $p (@ports){
|
my $n= $self->object_get_attribute('soc_name',undef);
|
my($inst,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
|
|
|
if(defined $n){ #we are compiling a single tile as SoC
|
|
my $core_id= $self->object_get_attribute('global_param','CORE_ID');
|
|
my $sw_loc = $self->object_get_attribute('global_param','SW_LOC');
|
|
|
|
$params_v="\tlocalparam\tCORE_ID=$core_id;
|
|
\tlocalparam\tSW_LOC=\"$sw_loc\";\n";
|
|
my %params=soc_get_all_parameters($self);
|
|
my @order= soc_get_all_parameters_order($self);
|
|
foreach my $p (@order){
|
|
add_text_to_string(\$params_v,"\tlocalparam $p = $params{$p};\n") if(defined $params{$p} );
|
|
}
|
|
}else{ # we are simulating a mpsoc
|
|
$params_v= gen_socs_param($self);
|
|
|
$PP{$key1}= (defined $PP{$key1})? "$PP{$key1} $p=1;\n" : "$p=1;\n";
|
|
$PP{$key0}= (defined $PP{$key0})? "$PP{$key0} $p=0;\n" : "$p=0;\n";
|
|
|
|
|
}
|
|
|
if (length($range)!=0){
|
foreach my $intfc (@intfcs){
|
# #replace parameter with their values #
|
my $key= ( $intfc eq 'plug:clk[0]')? 'clk' :
|
# my @a= split (/\b/,$range);
|
( $intfc eq 'plug:reset[0]')? 'reset':
|
# print "a=@a\n";
|
( $intfc eq 'plug:enable[0]')? 'en' : 'other';
|
# foreach my $l (@a){
|
my $key1="${key}1";
|
# my $value=$params{$l};
|
my $key0="${key}0";
|
# if(defined $value){
|
|
# chomp $value;
|
my @ports=$soc_top->top_get_intfc_ports_list($intfc);
|
# ($range=$range)=~ s/\b$l\b/$value/g if(defined $params{$l});
|
my $f=1;
|
# print "($range=$range)=~ s/\b$l\b/$value/g if(defined $params{$l}); \n";
|
foreach my $p (@ports){
|
# }
|
my($inst,$range,$type,$intfc_name,$intfc_port)= $soc_top->top_get_port($p);
|
# }
|
|
$range = "[ $range ]" ;
|
$PP{$key1}= (defined $PP{$key1})? "$PP{$key1} $p=1;\n" : "$p=1;\n";
|
}
|
$PP{$key0}= (defined $PP{$key0})? "$PP{$key0} $p=0;\n" : "$p=0;\n";
|
|
|
|
|
|
if (length($range)!=0){
|
|
# #replace parameter with their values #
|
|
# my @a= split (/\b/,$range);
|
|
# print "a=@a\n";
|
|
# foreach my $l (@a){
|
|
# my $value=$params{$l};
|
|
# if(defined $value){
|
|
# chomp $value;
|
|
# ($range=$range)=~ s/\b$l\b/$value/g if(defined $params{$l});
|
|
# print "($range=$range)=~ s/\b$l\b/$value/g if(defined $params{$l}); \n";
|
|
# }
|
|
# }
|
|
$range = "[ $range ]" ;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
if($type eq 'input'){
|
if($type eq 'input'){
|
$top_port_def="$top_port_def reg $range $p;\n"
|
$top_port_def="$top_port_def reg $range $p;\n"
|
}else{
|
}else{
|
$top_port_def="$top_port_def wire $range $p;\n"
|
$top_port_def="$top_port_def wire $range $p;\n"
|
}
|
}
|
$pin_assign=(defined $pin_assign)? "$pin_assign,\n\t\t.$p($p)": "\t\t.$p($p)";
|
$pin_assign=(defined $pin_assign)? "$pin_assign,\n\t\t.$p($p)": "\t\t.$p($p)";
|
$rst_inputs= "$rst_inputs $p=0;\n" if ($key eq 'other' && $type eq 'input' );
|
$rst_inputs= "$rst_inputs $p=0;\n" if ($key eq 'other' && $type eq 'input' );
|
}
|
}
|
|
|
|
|
}
|
}
|
|
|
my $test_v= get_license_header("testbench.v");
|
my $test_v= get_license_header("testbench.v");
|
|
|
$test_v ="$test_v
|
$test_v ="$test_v
|
|
|
`timescale 1ns/1ps
|
`timescale 1ns/1ps
|
|
|
module testbench;
|
module testbench;
|
|
|
Line 2157... |
Line 2090... |
|
|
|
|
end
|
end
|
|
|
endmodule
|
endmodule
|
";
|
";
|
save_file("$dir/testbench.v",$test_v);
|
save_file("$dir/testbench.v",$test_v);
|
|
|
|
|
|
|
}
|
|
|
|
sub verilator_testbench{
|
|
my ($self,$name,$top,$target_dir)=@_;
|
|
my $verilator="$target_dir/verilator";
|
|
my $dir="$verilator";
|
|
|
|
my ($app,$table,$tview,$window) = software_main($dir,'testbench.cpp');
|
|
|
|
my $n= $self->object_get_attribute('soc_name',undef);
|
|
if(defined $n){ #we are compiling a single tile as SoC
|
|
gen_verilator_soc_testbench (@_) if((-f "$dir/testbench.cpp")==0);
|
|
}
|
|
else { # we are compiling a complete NoC-based mpsoc
|
|
gen_verilator_mpsoc_testbench (@_,$tview) if((-f "$dir/testbench.cpp")==0);
|
|
|
|
}
|
|
|
|
#copy makefile
|
}
|
#copy("../script/verilator_soc_make", "$verilator/processed_rtl/obj_dir/Makefile");
|
|
|
|
|
sub verilator_testbench{
|
|
my ($self,$name,$top,$target_dir)=@_;
|
|
my $verilator="$target_dir/verilator";
|
|
my $dir="$verilator";
|
|
|
|
my ($app,$table,$tview,$window) = software_main($dir,'testbench.cpp');
|
|
|
|
my $n= $self->object_get_attribute('soc_name',undef);
|
|
if(defined $n){ #we are compiling a single tile as SoC
|
|
gen_verilator_soc_testbench (@_) if((-f "$dir/testbench.cpp")==0);
|
|
}
|
|
else { # we are compiling a complete NoC-based mpsoc
|
|
gen_verilator_mpsoc_testbench (@_,$tview) if((-f "$dir/testbench.cpp")==0);
|
|
|
|
}
|
|
|
|
#copy makefile
|
|
#copy("../script/verilator_soc_make", "$verilator/processed_rtl/obj_dir/Makefile");
|
|
|
|
|
my $make = def_image_button('icons/gen.png','Compile');
|
|
my $regen=def_image_button('icons/refresh.png','Regenerate Testbench.cpp');
|
|
my $run = def_image_button('icons/run.png','Run');
|
|
my $back=def_image_button('icons/left.png','Previous');
|
|
|
|
$table->attach ($back,1,2,1,2,'shrink','shrink',0,0);
|
|
$table->attach ($regen,3,4,1,2,'shrink','shrink',0,0);
|
|
$table->attach ($make,7, 8, 1,2,'shrink','shrink',0,0);
|
|
$table->attach ($run,9, 10, 1,2,'shrink','shrink',0,0);
|
|
|
|
$back-> signal_connect("clicked" => sub{
|
|
|
|
$window->destroy;
|
my $make = def_image_button('icons/gen.png','Compile');
|
verilator_compilation_win($self,$name,$top,$target_dir);
|
my $regen=def_image_button('icons/refresh.png','Regenerate Testbench.cpp');
|
|
my $run = def_image_button('icons/run.png','Run');
|
|
my $back=def_image_button('icons/left.png','Previous');
|
|
|
});
|
|
|
|
$regen-> signal_connect("clicked" => sub{
|
|
my $dialog = Gtk2::MessageDialog->new (my $window,
|
|
'destroy-with-parent',
|
|
'question', # message type
|
|
'yes-no', # which set of buttons?
|
|
"Are you sure you want to regenaret the testbench.cpp file? Note that any changes you have made will be lost");
|
|
my $response = $dialog->run;
|
|
if ($response eq 'yes') {
|
|
my $n= $self->object_get_attribute('soc_name',undef);
|
|
if(defined $n){ #we are compiling a single tile as SoC
|
|
gen_verilator_soc_testbench ($self,$name,$top,$target_dir);
|
|
}
|
|
else { # we are compiling a complete NoC-based mpsoc
|
|
gen_verilator_mpsoc_testbench ($self,$name,$top,$target_dir,$tview);
|
|
|
|
}
|
$table->attach ($back,1,2,1,2,'shrink','shrink',0,0);
|
|
$table->attach ($regen,3,4,1,2,'shrink','shrink',0,0);
|
|
$table->attach ($make,6, 7, 1,2,'shrink','shrink',0,0);
|
|
$table->attach ($run,9, 10, 1,2,'shrink','shrink',0,0);
|
|
|
$app->load_source("$dir/testbench.cpp");
|
$back-> signal_connect("clicked" => sub{
|
}
|
|
$dialog->destroy;
|
|
|
|
});
|
$window->destroy;
|
|
verilator_compilation_win($self,$name,$top,$target_dir);
|
|
|
|
});
|
|
|
$make -> signal_connect("clicked" => sub{
|
$regen-> signal_connect("clicked" => sub{
|
$app->do_save();
|
my $dialog = Gtk2::MessageDialog->new (my $window,
|
copy("$dir/testbench.cpp", "$verilator/processed_rtl/obj_dir/testbench.cpp");
|
'destroy-with-parent',
|
|
'question', # message type
|
|
'yes-no', # which set of buttons?
|
|
"Are you sure you want to regenaret the testbench.cpp file? Note that any changes you have made will be lost");
|
|
my $response = $dialog->run;
|
|
if ($response eq 'yes') {
|
|
my $n= $self->object_get_attribute('soc_name',undef);
|
|
if(defined $n){ #we are compiling a single tile as SoC
|
|
gen_verilator_soc_testbench ($self,$name,$top,$target_dir);
|
|
}
|
|
else { # we are compiling a complete NoC-based mpsoc
|
|
gen_verilator_mpsoc_testbench ($self,$name,$top,$target_dir,$tview);
|
|
|
my $tops_ref=$self->object_get_attribute('verilator','libs');
|
}
|
my %tops=%{$tops_ref};
|
|
my $lib_num=0;
|
|
|
|
foreach my $top (sort keys %tops) {
|
$app->load_source("$dir/testbench.cpp");
|
run_make_file("$verilator/processed_rtl/obj_dir/",$tview,"lib$lib_num");
|
}
|
$lib_num++;
|
$dialog->destroy;
|
}
|
|
run_make_file("$verilator/processed_rtl/obj_dir/",$tview,"sim");
|
|
|
|
});
|
});
|
|
|
$run -> signal_connect("clicked" => sub{
|
|
my $bin="$verilator/processed_rtl/obj_dir/testbench";
|
|
if (-f $bin){
|
|
my $cmd= "cd \"$verilator/processed_rtl/obj_dir/\" \n xterm -e sh -c $bin";
|
|
add_info(\$tview,"$cmd\n");
|
|
my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
|
|
if(length $stderr>1){
|
|
add_colored_info(\$tview,"$stderr\n",'red');
|
|
}else {
|
|
add_info(\$tview,"$stdout\n");
|
|
}
|
|
|
|
}else{
|
$make -> signal_connect("clicked" => sub{
|
add_colored_info(\$tview,"Cannot find $bin executable binary file! make sure you have compiled the testbench successfully\n", 'red')
|
$make->hide_all;
|
}
|
my $load= show_gif("icons/load.gif");
|
|
$table->attach ($load,8, 9, 1,2,'shrink','shrink',0,0);
|
|
$table->show_all;
|
|
$app->do_save();
|
|
copy("$dir/testbench.cpp", "$verilator/processed_rtl/obj_dir/testbench.cpp");
|
|
copy("$dir/parameter.h", "$verilator/processed_rtl/obj_dir/parameter.h") if(-f "$dir/parameter.h");
|
|
|
|
my $tops_ref=$self->object_get_attribute('verilator','libs');
|
|
my %tops=%{$tops_ref};
|
|
my $lib_num=0;
|
|
|
|
foreach my $top (sort keys %tops) {
|
|
run_make_file("$verilator/processed_rtl/obj_dir/",$tview,"lib$lib_num");
|
|
$lib_num++;
|
|
}
|
|
run_make_file("$verilator/processed_rtl/obj_dir/",$tview,"sim");
|
|
$load->destroy;
|
|
$make->show_all;
|
|
|
|
});
|
|
|
|
$run -> signal_connect("clicked" => sub{
|
|
my $bin="$verilator/processed_rtl/obj_dir/testbench";
|
|
if (-f $bin){
|
|
my $cmd= "cd \"$verilator/processed_rtl/obj_dir/\" \n xterm -e sh -c $bin";
|
|
add_info(\$tview,"$cmd\n");
|
|
my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
|
|
if(length $stderr>1){
|
|
add_colored_info(\$tview,"$stderr\n",'red');
|
|
}else {
|
|
add_info(\$tview,"$stdout\n");
|
|
}
|
|
|
});
|
}else{
|
|
add_colored_info(\$tview,"Cannot find $bin executable binary file! make sure you have compiled the testbench successfully\n", 'red')
|
|
}
|
|
|
|
});
|
|
|
}
|
|
|
|
|
}
|
|
|
1;
|
|
|
|
No newline at end of file
|
No newline at end of file
|
|
1;
|
|
|
No newline at end of file
|
No newline at end of file
|