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/] [mpsoc_gen.pl] - Rev 44
Go to most recent revision | Compare with Previous | Blame | View Log
#! /usr/bin/perl -w use Glib qw/TRUE FALSE/; use strict; use warnings; use FindBin; use lib $FindBin::Bin; use mpsoc; use soc; use ip; use interface; use POSIX 'strtol'; use File::Path; use File::Copy; use Cwd 'abs_path'; use Gtk2; use Gtk2::Pango; require "widget.pl"; require "mpsoc_verilog_gen.pl"; require "hdr_file_gen.pl"; require "readme_gen.pl"; require "soc_gen.pl"; require "diagram.pl"; sub get_pos{ my ($item,@list)=@_; my $pos=0; foreach my $p (@list){ #print "$p eq $item\n"; if ($p eq $item){return $pos;} $pos++; } return undef; } sub initial_default_param{ my $mpsoc=shift; my @socs=$mpsoc->mpsoc_get_soc_list(); foreach my $soc_name (@socs){ my %param_value; my $top=$mpsoc->mpsoc_get_soc($soc_name); my @insts=$top->top_get_all_instances(); my @exceptions=get_NI_instance_list($top); @insts=get_diff_array(\@insts,\@exceptions); foreach my $inst (@insts){ my @params=$top->top_get_parameter_list($inst); foreach my $p (@params){ my ($default,$type,$content,$info,$global_param,$redefine)=$top->top_get_parameter($inst,$p); $param_value{$p}=$default; } } $top->top_add_default_soc_param(\%param_value); } } ############# # get_soc_lists ############ sub get_soc_list { my ($mpsoc,$info)=@_; my $path=$mpsoc->object_get_attribute('setting','soc_path'); $path =~ s/ /\\ /g; my @socs; my @files = glob "$path/*.SOC"; for my $p (@files){ my ($soc,$r,$err) = regen_object($p); # Read if ($r){ add_info(\$info,"**Error reading $p file: $err\n"); next; } my $top=$soc->soc_get_top(); if (defined $top){ my @instance_list=$top->top_get_all_instances(); #check if the soc has ni port foreach my $instanc(@instance_list){ my $category=$top->top_get_def_of_instance($instanc,'category'); if($category eq 'NoC') { my $name=$soc->object_get_attribute('soc_name'); $mpsoc->mpsoc_add_soc($name,$top); #print" $name\n"; } } } }# files # initial default soc parameter initial_default_param($mpsoc); return $mpsoc->mpsoc_get_soc_list; } sub get_NI_instance_list { my $top=shift; my @nis; my @instance_list=$top->top_get_all_instances(); #check if the soc has ni port foreach my $instanc(@instance_list){ my $category=$top->top_get_def_of_instance($instanc,'category'); push(@nis,$instanc) if($category eq 'NoC') ; } return @nis; } #################### # get_conflict_decision ########################### sub b_box{ # create a new button my @label=@_; my $button = Gtk2::Button->new_from_stock(@label); my $box=def_vbox(FALSE,5); $box->pack_start($button, FALSE, FALSE,0); return ($box,$button); } sub get_conflict_decision{ my ($mpsoc,$name,$inserted,$conflicts,$msg)=@_; $msg="\tThe inserted tile number(s) have been mapped previously to \n\t\t\"$msg\".\n\tDo you want to remove the conflicted tiles number(s) in newly \n\tinsterd range or remove them from the previous ones? "; my $wind=def_popwin_size(10,30,"warning",'percent'); my $label= gen_label_in_left($msg); my $table=def_table(2,6,FALSE); $table->attach_defaults ($label , 0, 6, 0,1); $wind->add($table); my ($box1,$b1)= b_box("Remove Previous"); my ($box2,$b2)= b_box("Remove Current"); my ($box3,$b3)= b_box("Cancel"); $table->attach_defaults ($box1 , 0, 1, 1,2); $table->attach_defaults ($box2 , 3, 4, 1,2); $table->attach_defaults ($box3 , 5, 6, 1,2); $wind->show_all(); $b1->signal_connect( "clicked"=> sub{ #Remove Previous my @socs=$mpsoc->mpsoc_get_soc_list(); foreach my $p (@socs){ if($p ne $name){ my @taken_tiles=$mpsoc->mpsoc_get_soc_tiles_num($p); my @diff=get_diff_array(\@taken_tiles,$inserted); $mpsoc->mpsoc_add_soc_tiles_num($p,\@diff) if(scalar @diff ); $mpsoc->mpsoc_add_soc_tiles_num($p,undef) if(scalar @diff ==0 ); } } $mpsoc->mpsoc_add_soc_tiles_num($name,$inserted) if(defined $inserted ); set_gui_status($mpsoc,"ref",1); $wind->destroy(); }); $b2->signal_connect( "clicked"=> sub{#Remove Current my @new= get_diff_array($inserted,$conflicts); $mpsoc->mpsoc_add_soc_tiles_num($name,\@new) if(scalar @new ); $mpsoc->mpsoc_add_soc_tiles_num($name,undef) if(scalar @new ==0 ); set_gui_status($mpsoc,"ref",1); $wind->destroy(); }); $b3->signal_connect( "clicked"=> sub{ $wind->destroy(); }); } ############# # check_inserted_ip_nums ########## sub check_inserted_ip_nums{ my ($mpsoc,$name,$str)=@_; my @all_num=(); $str= remove_all_white_spaces ($str); if($str !~ /^[0-9.:,]+$/){ message_dialog ("The Ip numbers contains invalid character" ); return; } my @chunks=split(',',$str); foreach my $p (@chunks){ my @range=split(':',$p); my $size= scalar @range; if($size==1){ # its a number if ( grep( /^$range[0]$/, @all_num ) ) { message_dialog ("Multiple definition for Ip number $range[0]" ); return; } push(@all_num,$range[0]); }elsif($size ==2){# its a range my($min,$max)=@range; if($min>$max) {message_dialog ("invalid range: [$p]" ); return;} for (my $i=$min; $i<=$max; $i++){ if ( grep( /^$i$/, @all_num ) ) { message_dialog ("Multiple definition for Ip number $i in $p" ); return; } push(@all_num,$i); } }else{message_dialog ("invalid range: [$p]" ); return; } } #check if range does not exceed the tile numbers my ($max_tile_num)=get_topology_info($mpsoc); my @f=sort { $a <=> $b } @all_num; my @l; foreach my $num (@f){ push(@l,$num) if($num<$max_tile_num); } @all_num=@l; #check if any ip number exists in the rest my $conflicts_msg; my @conflicts; my @socs=$mpsoc->mpsoc_get_soc_list(); foreach my $p (@socs){ if($p ne $name){ my @taken_tiles=$mpsoc->mpsoc_get_soc_tiles_num($p); my @c=get_common_array(\@all_num,\@taken_tiles); if (scalar @c) { my $str=join(',', @c); $conflicts_msg = (defined $conflicts_msg)? "$conflicts_msg\n\t\t $str->$p" : "$str->$p"; @conflicts= (defined $conflicts_msg)? (@conflicts,@c): @c; } }#if } if (defined $conflicts_msg) { get_conflict_decision($mpsoc,$name,\@all_num,\@conflicts,$conflicts_msg); }else { #save the entered ips if( scalar @all_num>0){ $mpsoc->mpsoc_add_soc_tiles_num($name,\@all_num);} else {$mpsoc->mpsoc_add_soc_tiles_num($name,undef);} set_gui_status($mpsoc,"ref",1); } } ################# # get_soc_parameter_setting ################ sub get_soc_parameter_setting{ my ($mpsoc,$soc_name,$tile)=@_; my $window = (defined $tile)? def_popwin_size(40,40,"Parameter setting for $soc_name located in tile($tile) ",'percent'):def_popwin_size(40,40,"Default Parameter setting for $soc_name ",'percent'); my $table = def_table(10, 7, TRUE); my $scrolled_win = new Gtk2::ScrolledWindow (undef, undef); $scrolled_win->set_policy( "automatic", "automatic" ); $scrolled_win->add_with_viewport($table); my $row=0; my $top=$mpsoc->mpsoc_get_soc($soc_name); #read soc parameters my %param_value=(defined $tile) ? $top->top_get_custom_soc_param($tile) : $top->top_get_default_soc_param(); my @insts=$top->top_get_all_instances(); my @exceptions=get_NI_instance_list($top); @insts=get_diff_array(\@insts,\@exceptions); foreach my $inst (@insts){ my @params=$top->top_get_parameter_list($inst); foreach my $p (@params){ my ($default,$type,$content,$info,$global_param,$redefine)=$top->top_get_parameter($inst,$p); if ($type eq "Entry"){ my $entry=gen_entry($param_value{$p}); $table->attach_defaults ($entry, 3, 6, $row, $row+1); $entry-> signal_connect("changed" => sub{$param_value{$p}=$entry->get_text();}); } elsif ($type eq "Combo-box"){ my @combo_list=split(",",$content); my $pos=get_item_pos($param_value{$p}, @combo_list) if(defined $param_value{$p}); my $combo=gen_combo(\@combo_list, $pos); $table->attach_defaults ($combo, 3, 6, $row, $row+1); $combo-> signal_connect("changed" => sub{$param_value{$p}=$combo->get_active_text();}); } elsif ($type eq "Spin-button"){ my ($min,$max,$step)=split(",",$content); $param_value{$p}=~ s/\D//g; $min=~ s/\D//g; $max=~ s/\D//g; $step=~ s/\D//g; my $spin=gen_spin($min,$max,$step); $spin->set_value($param_value{$p}); $table->attach_defaults ($spin, 3, 4, $row, $row+1); $spin-> signal_connect("value_changed" => sub{$param_value{$p}=$spin->get_value_as_int();}); # $box=def_label_spin_help_box ($param,$info, $value,$min,$max,$step, 2); } my $label =gen_label_in_center($p); $table->attach_defaults ($label, 0, 3, $row, $row+1); if (defined $info){ my $info_button=def_image_button('icons/help.png'); $table->attach_defaults ($info_button, 6, 7, $row, $row+1); $info_button->signal_connect('clicked'=>sub{ message_dialog($info); }); } $row++; } } my $ok = def_image_button('icons/select.png','OK'); my $okbox=def_hbox(TRUE,0); $okbox->pack_start($ok, FALSE, FALSE,0); my $mtable = def_table(10, 1, TRUE); $mtable->attach_defaults($scrolled_win,0,1,0,9); $mtable->attach_defaults($okbox,0,1,9,10); $window->add ($mtable); $window->show_all(); $ok-> signal_connect("clicked" => sub{ $window->destroy; #save new values if(!defined $tile ) { $top->top_add_default_soc_param(\%param_value); } else { $top->top_add_custom_soc_param(\%param_value,$tile); } #set_gui_status($mpsoc,"refresh_soc",1); #$$refresh_soc->clicked; }); } ################ # tile_set_widget ################ sub tile_set_widget{ my ($mpsoc,$soc_name,$num,$table,$show,$row)=@_; #my $lable=gen_label_in_left($soc); my @all_num= $mpsoc->mpsoc_get_soc_tiles_num($soc_name); my $init=compress_nums(@all_num); my $entry; if (defined $init){$entry=gen_entry($init) ;} else {$entry=gen_entry();} my $set= def_image_button('icons/right.png'); my $remove= def_image_button('icons/cancel.png'); #my $setting= def_image_button('icons/setting.png','setting'); my $button = def_colored_button($soc_name,$num); $button->signal_connect("clicked"=> sub{ get_soc_parameter_setting($mpsoc,$soc_name,undef); }); $set->signal_connect("clicked"=> sub{ my $data=$entry->get_text(); check_inserted_ip_nums($mpsoc,$soc_name,$data); }); $remove->signal_connect("clicked"=> sub{ $mpsoc->mpsoc_remove_soc($soc_name); set_gui_status($mpsoc,"ref",1); }); if($show){ $table->attach ( $button, 0, 1, $row,$row+1,'fill','fill',2,2); $table->attach ( $remove, 1, 2, $row,$row+1,'fill','shrink',2,2); $table->attach ( $entry , 2, 3, $row,$row+1,'fill','shrink',2,2); $table->attach ( $set, 3, 4, $row,$row+1,'fill','shrink',2,2); $row++; } return $row; } ################## # defualt_tilles_setting ################### sub defualt_tilles_setting { my ($mpsoc,$table,$show,$row,$info)=@_; #title my $separator1 = Gtk2::HSeparator->new; my $separator2 = Gtk2::HSeparator->new; my $title2=gen_label_in_center("Tile Configuration"); my $box1=def_vbox(FALSE, 1); $box1->pack_start( $separator1, FALSE, FALSE, 3); $box1->pack_start( $title2, FALSE, FALSE, 3); $box1->pack_start( $separator2, FALSE, FALSE, 3); if($show){$table->attach_defaults ($box1 ,0,4, $row,$row+1);$row++;} my $label = gen_label_in_left("Tiles path:"); my $entry = Gtk2::Entry->new; my $browse= def_image_button("icons/browse.png"); my $file= $mpsoc->object_get_attribute('setting','soc_path'); if(defined $file){$entry->set_text($file);} $browse->signal_connect("clicked"=> sub{ my $entry_ref=$_[1]; my $file; my $dialog = Gtk2::FileChooserDialog->new( 'Select tile directory', undef, # 'open', 'select-folder', 'gtk-cancel' => 'cancel', 'gtk-ok' => 'ok', ); if ( "ok" eq $dialog->run ) { $file = $dialog->get_filename; $$entry_ref->set_text($file); $mpsoc->object_add_attribute('setting','soc_path',$file); $mpsoc->mpsoc_remove_all_soc(); set_gui_status($mpsoc,"ref",1); #check_input_file($file,$socgen,$info); #print "file = $file\n"; } $dialog->destroy; } , \$entry); $entry->signal_connect("activate"=>sub{ my $file_name=$entry->get_text(); $mpsoc->object_add_attribute('setting','soc_path',$file_name); $mpsoc->mpsoc_remove_all_soc(); set_gui_status($mpsoc,"ref",1); #check_input_file($file_name,$socgen,$info); }); if($show){ my $tmp=gen_label_in_left(" "); $table->attach ($label, 0, 1 , $row,$row+1,'fill','shrink',2,2); $table->attach ($tmp, 1, 2 , $row,$row+1,'fill','shrink',2,2); $table->attach ($entry, 2, 3 , $row,$row+1,'fill','shrink',2,2); $table->attach ($browse, 3, 4, $row,$row+1,'fill','shrink',2,2); $row++; } my @socs=$mpsoc->mpsoc_get_soc_list(); if( scalar @socs == 0){ @socs=get_soc_list($mpsoc,$info); } @socs=$mpsoc->mpsoc_get_soc_list(); my $lab1=gen_label_in_center(' Tile name'); my $lab2=gen_label_help('Define the tile numbers that each IP is mapped to. you can add individual numbers or ranges as follow eg: 0,2,5:10 ', ' Tile numbers '); if($show){ $table->attach_defaults ($lab1 ,0,1, $row,$row+1); $table->attach_defaults ($lab2 ,2,3, $row,$row+1);$row++; } my $soc_num=0; foreach my $soc_name (@socs){ $row=tile_set_widget ($mpsoc,$soc_name,$soc_num,$table,$show,$row); $soc_num++; } return $row; } ####################### # noc_config ###################### sub noc_config{ my ($mpsoc,$table)=@_; #title my $row=0; my $title=gen_label_in_center("NoC Configuration"); $table->attach ($title , 0, 4, $row, $row+1,'expand','shrink',2,2); $row++; my $separator = Gtk2::HSeparator->new; $table->attach ($separator , 0, 4 , $row, $row+1,'fill','fill',2,2); $row++; my $label; my $param; my $default; my $type; my $content; my $info; #parameter start my $b1; my $show_noc=$mpsoc->object_get_attribute('setting','show_noc_setting'); if(!defined $show_noc){ $show_noc=1; $mpsoc->object_add_attribute('setting','show_noc_setting',$show_noc); } if($show_noc == 0){ $b1= def_image_button("icons/down.png","NoC Parameters"); $label=gen_label_in_center(' '); $table->attach ( $label , 2, 3, $row,$row+1 ,'fill','shrink',2,2); $table->attach ( $b1 , 0, 2, $row,$row+1,'fill','shrink',2,2); $row++; } my $coltmp=0; #Router type $label='Router Type'; $param='ROUTER_TYPE'; $default='"VC_BASED"'; $content='"INPUT_QUEUED","VC_BASED"'; $type='Combo-box'; $info=" Input-queued: simple router with low performance and does not support fully adaptive routing. VC-based routers offer higher performance, fully adaptive routing and traffic isolation for different packet classes."; ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,$show_noc,'noc_type',1); my $router_type=$mpsoc->object_get_attribute('noc_type',"ROUTER_TYPE"); #topology $label='Topology'; $param='TOPOLOGY'; $default='"MESH"'; $content='"MESH","TORUS","RING","LINE","FATTREE","TREE"'; $type='Combo-box'; $info="NoC topology"; ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,$show_noc,'noc_param',1); my $topology=$mpsoc->object_get_attribute('noc_param','TOPOLOGY'); #topology T1 parameter $label= ($topology eq '"FATTREE"' || $topology eq '"TREE"')? 'K' : 'Routers per row'; $param= 'T1'; $default= '2'; $content=($topology eq '"MESH"' || $topology eq '"TORUS"') ? '2,16,1': ($topology eq '"FATTREE"' || $topology eq '"TREE"' )? '2,6,1':'2,64,1'; $info= ($topology eq '"FATTREE"' || $topology eq '"TREE"' )? 'number of last level individual router`s endpoints.' :'Number of NoC routers in row (X dimention)'; $type= 'Spin-button'; ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,$show_noc,'noc_param',1); #Topology T2 parameter if($topology eq '"MESH"' || $topology eq '"TORUS"' || $topology eq '"FATTREE"' || $topology eq '"TREE"' ) { $label= ($topology eq '"FATTREE"' || $topology eq '"TREE"')? 'L' :'Routers per column'; $param= 'T2'; $default='2'; $content='2,16,1'; $info= ($topology eq '"FATTREE"' || $topology eq '"TREE"')? 'Fattree layer number (The height of FT)':'Number of NoC routers in column (Y dimention)'; $type= 'Spin-button'; ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,$show_noc,'noc_param',1); } else { $mpsoc->object_add_attribute('noc_param','T2',1); } #Topology T3 parameter if($topology eq '"MESH"' || $topology eq '"TORUS"' || $topology eq '"RING"' || $topology eq '"LINE"') { $label="Router's endpoint number"; $param= 'T3'; $default='1'; $content='1,4,1'; $info= "In $topology topology, each router can have up to 4 endpoint processing tile."; $type= 'Spin-button'; ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,$show_noc,'noc_param',1); } #VC number per port if($router_type eq '"VC_BASED"'){ my $v=$mpsoc->object_get_attribute('noc_param','V'); if(defined $v){ $mpsoc->object_add_attribute('noc_param','V',2) if($v eq 1);} $label='VC number per port'; $param='V'; $default='2'; $type='Spin-button'; $content='2,16,1'; $info='Number of Virtual Channel per each router port'; ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,$show_noc,'noc_param',1); } else { $mpsoc->object_add_attribute('noc_param','V',1); $mpsoc->object_add_attribute('noc_param','C',0); } #buffer width per VC $label=($router_type eq '"VC_BASED"')? 'Buffer flits per VC': "Buffer flits"; $param='B'; $default='4'; $content='2,256,1'; $type='Spin-button'; $info=($router_type eq '"VC_BASED"')? 'Buffer queue size per VC in flits' : 'Buffer queue size in flits'; ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,$show_noc,'noc_param',undef); #packet payload width $label='Payload width'; $param='Fpay'; $default='32'; $content='32,256,32'; $type='Spin-button'; $info="The packet payload width in bits"; ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info,$table,$row,undef,$show_noc,'noc_param',undef); #routing algorithm $label='Routing Algorithm'; $param="ROUTE_NAME"; $type="Combo-box"; if($router_type eq '"VC_BASED"'){ $content=($topology eq '"MESH"')? '"XY","WEST_FIRST","NORTH_LAST","NEGETIVE_FIRST","ODD_EVEN","DUATO"' : ($topology eq '"TORUS"')? '"TRANC_XY","TRANC_WEST_FIRST","TRANC_NORTH_LAST","TRANC_NEGETIVE_FIRST","TRANC_DUATO"': ($topology eq '"RING"')? '"TRANC_XY"' : ($topology eq '"LINE"')? '"XY"': ($topology eq '"FATTREE"')? '"NCA_RND_UP","NCA_STRAIGHT_UP","NCA_DST_UP"': ($topology eq '"TREE"')? '"NCA"' : '"UNKNOWN"'; }else{ $content=($topology eq '"MESH"')? '"XY","WEST_FIRST","NORTH_LAST","NEGETIVE_FIRST","ODD_EVEN"' : ($topology eq '"TORUS"')? '"TRANC_XY","TRANC_WEST_FIRST","TRANC_NORTH_LAST","TRANC_NEGETIVE_FIRST"': ($topology eq '"RING"')? '"TRANC_XY"' : ($topology eq '"LINE"')? '"XY"': ($topology eq '"FATTREE"')? '"NCA_RND_UP","NCA_STRAIGHT_UP","NCA_DST_UP"' : ($topology eq '"TREE"')? '"NCA"' : '"UNKNOWN"'; } $default=($topology eq '"MESH"' || $topology eq '"LINE"' )? '"XY"': ($topology eq '"TORUS"'|| $topology eq '"RING"')? '"TRANC_XY"' : ($topology eq '"FATTREE"')? '"NCA_STRAIGHT_UP"' : ($topology eq '"TREE"')? '"NCA"' : '"UNKNOWN"'; my $info_mesh="Select the routing algorithm: XY(DoR) , partially adaptive (Turn models). Fully adaptive (Duato) "; my $info_fat="Nearest common ancestor (NCA) where the up port is selected randomly (RND), based on destination endpoint address (DST) or it is the top port that is located in front of the the port which has received the packet (STRAIGHT) "; $info=($topology eq '"FATTREE"')? $info_fat : ($topology eq '"TREE"') ? "Nearest common ancestor": $info_mesh; ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,$show_noc,'noc_param',1); #MIN_PCK_SIZE # 2 //minimum packet size in flits. The minimum value is 1. $label='Minimum packet size'; $param='MIN_PCK_SIZE'; $default='2'; $content='1,65535,1'; $type='Spin-button'; $info="The minimum packet size in flits. In atomic VC re-allocation, it is just important to define if the single-flit sized packets are allowed to be injected to the NoC by defining this parameter value as one. Setting any larger value than one results in the same architecture and the NoC works correctly even if it receives smaller packets size as while as they are not single flit -sized packets. However, for non-atomic VC reallocation NoCs, you have to define the exact value as it defines the NoC control registers' internal buffers. The NoC may crash once it receives packets having smaler size than the defined minimum packet size."; ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,$show_noc,'noc_param',undef); #SSA $label='SSA Ebable'; $param='SSA_EN'; $default='"NO"'; $content='"YES","NO"'; $type='Combo-box'; $info="Enable single cycle latency on packets traversing in the same direction using static straight allocator (SSA)"; ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,$show_noc,'noc_param',undef); if($show_noc == 1){ $b1= def_image_button("icons/up.png","NoC Parameters"); $table->attach ( $b1 , 0, 2, $row,$row+1,'fill','shrink',2,2); $row++; } $b1->signal_connect("clicked" => sub{ $show_noc=($show_noc==1)?0:1; $mpsoc->object_add_attribute('setting','show_noc_setting',$show_noc); set_gui_status($mpsoc,"ref",1); }); #advance parameter start my $advc; my $adv_set=$mpsoc->object_get_attribute('setting','show_adv_setting'); if($adv_set == 0){ $advc= def_image_button("icons/down.png","Advance Parameters"); $table->attach ( $advc , 0, 2, $row,$row+1,'fill','shrink',2,2); $row++; } #Fully and partially adaptive routing setting my $route=$mpsoc->object_get_attribute('noc_param',"ROUTE_NAME"); $label="Congestion index"; $param="CONGESTION_INDEX"; $type="Spin-button"; $content="0,12,1"; $info="Congestion index determines how congestion information is collected from neighboring routers. Please refer to the usere manual for more information"; $default=3; if($route ne '"XY"' and $route ne '"TRANC_XY"' ){ ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,$adv_set,'noc_param',undef); } else { ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,0,'noc_param',undef); } #Fully adaptive routing setting my $v=$mpsoc->object_get_attribute('noc_param',"V"); $label="Select Escap VC"; $param="ESCAP_VC_MASK"; $type="Check-box"; $content=$v; $default="$v\'b"; for (my $i=1; $i<=$v-1; $i++){$default= "${default}0";} $default= "${default}1"; $info="Select the escap VC for fully adaptive routing."; if( $route eq '"TRANC_DUATO"' or $route eq '"DUATO"' ){ ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,$adv_set, 'noc_param',undef); } else{ ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,0, 'noc_param',undef); } # VC reallocation type $label=($router_type eq '"VC_BASED"')? 'VC reallocation type': 'Queue reallocation type'; $param='VC_REALLOCATION_TYPE'; $info="VC reallocation type: If set as atomic only empty VCs can be allocated for new packets. Whereas, in non-atomic a non-empty VC which has received the last packet tail flit can accept a new packet"; $default='"NONATOMIC"'; $content='"ATOMIC","NONATOMIC"'; $type='Combo-box'; ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,$adv_set,'noc_param',undef); #vc/sw allocator type $label = 'VC/SW combination type'; $param='COMBINATION_TYPE'; $default='"COMB_NONSPEC"'; $content='"BASELINE","COMB_SPEC1","COMB_SPEC2","COMB_NONSPEC"'; $type='Combo-box'; $info="The joint VC/ switch allocator type. using canonical combination is not recommanded"; if ($router_type eq '"VC_BASED"'){ ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,$adv_set,'noc_param',undef); } else{ ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,0,'noc_param',undef); } # Crossbar mux type $label='Crossbar mux type'; $param='MUX_TYPE'; $default='"BINARY"'; $content='"ONE_HOT","BINARY"'; $type='Combo-box'; $info="Crossbar multiplexer type"; ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,$adv_set,'noc_param',undef); #class if($router_type eq '"VC_BASED"'){ $label='class number'; $param='C'; $default= 0; $info='Number of message classes. Each specific class can use different set of VC'; $content='0,16,1'; $type='Spin-button'; ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,$adv_set,'noc_param',5); my $class=$mpsoc->object_get_attribute('noc_param',"C"); my $v=$mpsoc->object_get_attribute('noc_param',"V"); $default= "$v\'b"; for (my $i=1; $i<=$v; $i++){ $default= "${default}1"; } #print "\$default=$default\n"; for (my $i=0; $i<=$class-1; $i++){ $label="Class $i Permitted VCs"; $param="Cn_$i"; $type="Check-box"; $content=$v; $info="Select the permitted VCs which the message class $i can be sent via them."; ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,$adv_set,'class_param',undef); } }#($router_type eq '"VC_BASED"') #simulation debuge enable $label='Debug enable'; $param='DEBUG_EN'; $info= "Add extra verilog code for debuging NoC for simulation"; $default='0'; $content='0,1'; $type='Combo-box'; ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,$adv_set,'noc_param'); #pipeline reg $label="Add pipeline reg after crossbar"; $param="ADD_PIPREG_AFTER_CROSSBAR"; $type="Check-box"; $content=1; $default="1\'b0"; $info="If enabeled it adds a pipline register at the output port of the router."; ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,$adv_set,'noc_param'); #MAX_SBP_NUM = 4 // $label="Number of multiple router bypassing "; $param="MAX_SBP_NUM "; $type='Spin-button'; $content='0,1,1'; $default=0; $info="maximum number of routers which a packet can by pass during one clock cycle. Define it as zero will disable bypassing."; #($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$adv_set,'noc_param'); #FIRST_ARBITER_EXT_P_EN $label='Swich allocator first level arbiters external priority enable'; $param='FIRST_ARBITER_EXT_P_EN'; $default= 1; $info='If set as 1 then the switch allocator\'s input (first) arbiters\' priority registers are enabled only when a request get both input and output arbiters\' grants'; $content='0,1'; $type="Combo-box"; ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info,$table,$row,undef,$adv_set,'noc_param'); #Arbiter type $label='SW allocator arbitration type'; $param='SWA_ARBITER_TYPE'; $default='"RRA"'; $content='"RRA","WRRA"'; #,"WRRA_CLASSIC"'; $type='Combo-box'; $info="Switch allocator arbitertion type: RRA: Round robin arbiter. Only local fairness in a router. WRRA: Weighted round robin arbiter. Results in global fairness in the NoC. Switch allocation requests are grated acording to their weight which increases due to contention"; ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,$adv_set,'noc_param',1); my $arbiter=$mpsoc->object_get_attribute('noc_param',"SWA_ARBITER_TYPE"); my $wrra_show = ($arbiter ne '"RRA"' && $adv_set == 1 )? 1 : 0; # weight width $label='Weight width'; $param='WEIGHTw'; $default='4'; $content='2,7,1'; $info= 'Maximum weight width'; $type= 'Spin-button'; ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,$wrra_show,'noc_param',undef); #WRRA_CONFIG_INDEX $label='Weight configuration index'; $param='WRRA_CONFIG_INDEX'; $default='0'; $content='0,7,1'; $info= 'WRRA_CONFIG_INDEX: '; $type= 'Spin-button'; #($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$wrra_show,'noc_param',undef); if($adv_set == 1){ $advc= def_image_button("icons/up.png","Advance Parameters"); $table->attach ( $advc , 0, 2, $row,$row+1,'fill','shrink',2,2); $row++; } $advc->signal_connect("clicked" => sub{ $adv_set=($adv_set==1)?0:1; $mpsoc->object_add_attribute('setting','show_adv_setting',$adv_set); set_gui_status($mpsoc,"ref",1); }); #other fixed parameters # AVC_ATOMIC_EN $label='AVC_ATOMIC_EN'; $param='AVC_ATOMIC_EN'; $default= 0; $info='AVC_ATOMIC_EN'; $content='0,1'; $type="Combo-box"; ($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,0,'noc_param'); #ROUTE_SUBFUNC #$label='ROUTE_SUBFUNC'; #$param='ROUTE_SUBFUNC'; #$default= '"XY"'; #$info='ROUTE_SUBFUNC'; #$content='"XY"'; #$type="Combo-box"; #($row,$coltmp)=add_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,undef,0,'noc_param'); return $row; } ####################### # get_config ###################### sub get_config{ my ($mpsoc,$info)=@_; my $table=def_table(20,10,FALSE);# my ($row,$col,$homogeneous)=@_; #my $scrolled_win = new Gtk2::ScrolledWindow (undef, undef); #$scrolled_win->set_policy( "automatic", "automatic" ); #$scrolled_win->add_with_viewport($table); #noc_setting my $row=noc_config ($mpsoc,$table); #tiles setting my $tile_set; my $show=$mpsoc->object_get_attribute('setting','show_tile_setting'); if($show == 0){ $tile_set= def_image_button("icons/down.png","Tiles setting"); $table->attach ( $tile_set , 0, 2, $row,$row+1,'fill','shrink',2,2); $row++; } $row=defualt_tilles_setting($mpsoc,$table,$show,$row,$info); #end tile setting if($show == 1){ $tile_set= def_image_button("icons/up.png","Tiles setting"); $table->attach ( $tile_set , 0, 2, $row,$row+1,'fill','shrink',2,2); $row++; } $tile_set->signal_connect("clicked" => sub{ $show=($show==1)?0:1; $mpsoc->object_add_attribute('setting','show_tile_setting',$show); set_gui_status($mpsoc,"ref",1); }); #for(my $i=$row; $i<25; $i++){ #my $empty_col=gen_label_in_left(' '); #$table->attach_defaults ($empty_col , 0, 1, $i,$i+1); #} return $table; } ############# # gen_all_tiles ########### sub gen_all_tiles{ my ($mpsoc,$info, $hw_dir,$sw_dir)=@_; my ($NE, $NR, $RAw, $EAw, $Fw)=get_topology_info($mpsoc); my $mpsoc_name=$mpsoc->object_get_attribute('mpsoc_name'); my $target_dir = "$ENV{'PRONOC_WORK'}/MPSOC/$mpsoc_name"; my @generated_tiles; for (my $tile_num=0;$tile_num<$NE;$tile_num++){ #print "$tile_num\n"; my ($soc_name,$num)= $mpsoc->mpsoc_get_tile_soc_name($tile_num); next if(!defined $soc_name); my $path=$mpsoc->object_get_attribute('setting','soc_path'); $path=~ s/ /\\ /g; my $p = "$path/$soc_name.SOC"; my ($soc,$r,$err) = regen_object($p); if ($r){ show_info(\$info,"**Error reading $p file: $err\n"); next; } #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 $top=$mpsoc->mpsoc_get_soc($soc_name); my @nis=get_NI_instance_list($top); $soc->soc_add_instance_param($nis[0] ,$nocparam ); #foreach my $p ( sort keys %nocparam ) { # print "$p = $nocparam{$p} \n"; #} my $sw_path = "$sw_dir/tile$tile_num"; #print "$sw_path\n"; if( grep (/^$soc_name$/,@generated_tiles)){ # This soc is generated before only create the software file generate_soc($soc,$info,$target_dir,$hw_dir,$sw_path,0,0); }else{ generate_soc($soc,$info,$target_dir,$hw_dir,$sw_path,0,1,"merge"); move ("$hw_dir/$soc_name.v","$hw_dir/tiles/"); my @tmp= ("$hw_dir/tiles/$soc_name.v"); add_to_project_file_list(\@tmp,"$hw_dir/tiles",$hw_dir); } }#$tile_num } ################ # generate_soc ################# sub generate_soc_files{ my ($mpsoc,$soc,$info)=@_; my $mpsoc_name=$mpsoc->object_get_attribute('mpsoc_name'); my $soc_name=$soc->object_get_attribute('soc_name'); # copy all files in project work directory my $dir = Cwd::getcwd(); my $project_dir = abs_path("$dir/../../"); #make target dir my $target_dir = "$ENV{'PRONOC_WORK'}/MPSOC/$mpsoc_name"; mkpath("$target_dir/src_verilog/lib/",1,0755); mkpath("$target_dir/src_verilog/tiles/",1,0755); mkpath("$target_dir/sw",1,0755); my ($file_v,$tmp)=soc_generate_verilog($soc,"$target_dir/sw"); # Write object file open(FILE, ">lib/soc/$soc_name.SOC") || die "Can not open: $!"; print FILE perl_file_header("$soc_name.SOC"); print FILE Data::Dumper->Dump([\%$soc],['soc']); close(FILE) || die "Error closing file: $!"; # Write verilog file open(FILE, ">lib/verilog/$soc_name.v") || die "Can not open: $!"; print FILE $file_v; close(FILE) || die "Error closing file: $!"; #copy hdl codes in src_verilog my ($hdl_ref,$warnings)= get_all_files_list($soc,"hdl_files"); foreach my $f(@{$hdl_ref}){ my $n="$project_dir$f"; if (-f "$n") { copy ("$n","$target_dir/src_verilog/lib"); }elsif(-f "$f" ){ copy ("$f","$target_dir/src_verilog/lib"); } } show_info(\$info,$warnings) if(defined $warnings); #save project hdl file/folder list my @new_file_ref; foreach my $f(@{$hdl_ref}){ my ($name,$path,$suffix) = fileparse("$f",qr"\..[^.]*$"); push(@new_file_ref,"$target_dir/src_verilog/lib/$name$suffix"); } open(FILE, ">$target_dir/src_verilog/file_list") || die "Can not open: $!"; print FILE Data::Dumper->Dump([\@new_file_ref],['files']); close(FILE) || die "Error closing file: $!"; #my @pathes=("$dir/../src_peripheral","$dir/../src_noc","$dir/../src_processor"); #foreach my $p(@pathes){ # find( # sub { # return unless ( -f $_ ); # $_ =~ /\.v$/ && copy( $File::Find::name, "$target_dir/src_verilog/lib/" ); # }, # $p # ); #} move ("$dir/lib/verilog/$soc_name.v","$target_dir/src_verilog/tiles/"); copy_noc_files($project_dir,"$target_dir/src_verilog/lib"); # Write header file generate_header_file($soc,$project_dir,$target_dir,$target_dir,$dir); #use File::Copy::Recursive qw(dircopy); #dircopy("$dir/../src_processor/aeMB/compiler","$target_dir/sw/") or die("$!\n"); my $msg="SoC \"$soc_name\" has been created successfully at $target_dir/ "; return $msg; } sub generate_mpsoc_lib_file { my ($mpsoc,$info) = @_; my $name=$mpsoc->object_get_attribute('mpsoc_name'); $mpsoc->mpsoc_remove_all_soc_tops(); open(FILE, ">lib/mpsoc/$name.MPSOC") || die "Can not open: $!"; print FILE perl_file_header("$name.MPSOC"); print FILE Data::Dumper->Dump([\%$mpsoc],['mpsoc']); close(FILE) || die "Error closing file: $!"; get_soc_list($mpsoc,$info); } ################ # generate_mpsoc ################# sub generate_mpsoc{ my ($mpsoc,$info,$show_sucess_msg)=@_; my $name=$mpsoc->object_get_attribute('mpsoc_name'); my $error = check_verilog_identifier_syntax($name); if ( defined $error ){ #message_dialog("The \"$name\" is given with an unacceptable formatting. The mpsoc name will be used as top level verilog module name so it must follow Verilog identifier declaration formatting:\n $error"); my $message = "The \"$name\" is given with an unacceptable formatting. The mpsoc name will be used as top level verilog module name so it must follow Verilog identifier declaration formatting:\n $error"; add_colored_info(\$info, $message,'red' ); return 0; } my $size= (defined $name)? length($name) :0; if ($size ==0) { message_dialog("Please define the MPSoC name!"); return 0; } # make target dir my $dir = Cwd::getcwd(); my $target_dir = "$ENV{'PRONOC_WORK'}/MPSOC/$name"; my $hw_dir = "$target_dir/src_verilog"; my $sw_dir = "$target_dir/sw"; # rmtree ($hw_dir); mkpath("$hw_dir",1,01777); mkpath("$hw_dir/lib/",1,0755); mkpath("$hw_dir/tiles",1,0755); mkpath("$sw_dir",1,0755); #remove old rtl files that were copied by ProNoC my ($old_file_ref,$r,$err) = regen_object("$hw_dir/file_list"); if (defined $old_file_ref){ remove_file_and_folders($old_file_ref,$target_dir); } unlink "$hw_dir/file_list"; #generate/copy all tiles HDL/SW codes gen_all_tiles($mpsoc,$info, $hw_dir,$sw_dir ); #generate header file containig the tiles physical addresses gen_tiles_physical_addrsses_header_file($mpsoc,"$sw_dir/phy_addr.h"); #copy all NoC HDL files my @files = glob( "$dir/../src_noc/*.v" ); copy_file_and_folders(\@files,$dir,"$hw_dir/lib/"); add_to_project_file_list(\@files,"$hw_dir/lib/",$hw_dir); my ($file_v,$top_v)=mpsoc_generate_verilog($mpsoc,$sw_dir); # Write object file generate_mpsoc_lib_file($mpsoc,$info); # Write verilog file open(FILE, ">lib/verilog/$name.v") || die "Can not open: $!"; print FILE $file_v; close(FILE) || die "Error closing file: $!"; my $l=autogen_warning().get_license_header("${name}_top.v"); open(FILE, ">lib/verilog/${name}_top.v") || die "Can not open: $!"; print FILE "$l\n$top_v"; close(FILE) || die "Error closing file: $!"; #gen_socs($mpsoc,$info); move ("$dir/lib/verilog/$name.v","$target_dir/src_verilog/"); move ("$dir/lib/verilog/${name}_top.v","$target_dir/src_verilog/"); #generate makefile open(FILE, ">$sw_dir/Makefile") || die "Can not open: $!"; print FILE mpsoc_sw_make(); close(FILE) || die "Error closing file: $!"; #generate prog_mem open(FILE, ">$sw_dir/program.sh") || die "Can not open: $!"; print FILE mpsoc_mem_prog(); close(FILE) || die "Error closing file: $!"; my @ff= ("$target_dir/src_verilog/$name.v","$target_dir/src_verilog/${name}_top.v"); add_to_project_file_list(\@ff,"$hw_dir/lib/",$hw_dir); message_dialog("MPSoC \"$name\" has been created successfully at $target_dir/ " ) if($show_sucess_msg); return 1; } sub mpsoc_sw_make { my $make="SUBDIRS := \$(wildcard */.) all: \$(SUBDIRS) \$(SUBDIRS): \t\$(MAKE) -C \$@ .PHONY: all \$(SUBDIRS) clean: \t\$(MAKE) -C \$(CODE_DIR) clean "; return $make; } sub mpsoc_mem_prog { my $string=' #!/bin/sh #JTAG_INTFC="$PRONOC_WORK/toolchain/bin/JTAG_INTFC" source ./jtag_intfc.sh #reset and disable cpus, then release the reset but keep the cpus disabled $JTAG_INTFC -n 127 -d "I:1,D:2:3,D:2:2,I:0" # jtag instruction # 0: bypass # 1: getting data # jtag data : # bit 0 is reset # bit 1 is disable # I:1 set jtag_enable in active mode # D:2:3 load jtag_enable data register with 0x3 reset=1 disable=1 # D:2:2 load jtag_enable data register with 0x2 reset=0 disable=1 # I:0 set jtag_enable in bypass mode #programe the memory for i in $(ls -d */); do echo "Enter ${i%%/}" cd ${i%%/} sh write_memory.sh cd .. done #Enable the cpu $JTAG_INTFC -n 127 -d "I:1,D:2:0,I:0" # I:1 set jtag_enable in active mode # D:2:0 load jtag_enable data register with 0x0 reset=0 disable=0 # I:0 set jtag_enable in bypass mode '; return $string; } sub get_tile_LIST{ my ($mpsoc,$x,$y,$soc_num,$row,$table)=@_; my $instance_name=$mpsoc->mpsoc_get_instance_info($soc_num); if(!defined $instance_name){ $mpsoc->mpsoc_set_default_ip($soc_num); $instance_name=$mpsoc->mpsoc_get_instance_info($soc_num); } #ipname my $col=0; my $label=gen_label_in_left("IP_$soc_num($x,$y)"); $table->attach_defaults ( $label, $col, $col+1 , $row, $row+1);$col+=2; #instance name my $entry=gen_entry($instance_name); $table->attach_defaults ( $entry, $col, $col+1 , $row, $row+1);$col+=2; $entry->signal_connect( 'changed'=> sub{ my $new_instance=$entry->get_text(); $mpsoc->mpsoc_set_ip_inst_name($soc_num,$new_instance); set_gui_status($mpsoc,"ref",20); print "changed to $new_instance\n "; }); #combo box my @list=('A','B'); my $combo=gen_combo(\@list,0); $table->attach_defaults ( $combo, $col, $col+1 , $row, $row+1);$col+=2; #setting my $setting= def_image_button("icons/setting.png","Browse"); $table->attach_defaults ( $setting, $col, $col+1 , $row, $row+1);$col+=2; } sub get_tile{ my ($mpsoc,$tile)=@_; my ($soc_name,$num)= $mpsoc->mpsoc_get_tile_soc_name($tile); my $button; my $topology=$mpsoc->object_get_attribute('noc_param','TOPOLOGY'); if( defined $soc_name){ my $setting=$mpsoc->mpsoc_get_tile_param_setting($tile); $button=($setting eq 'Custom')? def_colored_button("Tile $tile*\n$soc_name",$num) : def_colored_button("Tile $tile\n$soc_name",$num) ; }else { $button =def_colored_button("Tile $tile\n",50) if(! defined $soc_name); } $button->signal_connect("clicked" => sub{ my $window = def_popwin_size(40,40,"Parameter setting for Tile $tile ",'percent'); my $table = def_table(6, 2, TRUE); my $scrolled_win = new Gtk2::ScrolledWindow (undef, undef); $scrolled_win->set_policy( "automatic", "automatic" ); $scrolled_win->add_with_viewport($table); my $row=0; my ($soc_name,$g,$t)=$mpsoc->mpsoc_get_tile_soc_name($tile); my @socs=$mpsoc->mpsoc_get_soc_list(); my @list=(' ',@socs); my $pos=(defined $soc_name)? get_scolar_pos($soc_name,@list): 0; my $combo=gen_combo(\@list, $pos); my $lable=gen_label_in_left(" Processing tile name:"); $table->attach_defaults($lable,0,3,$row,$row+1); $table->attach_defaults($combo,3,7,$row,$row+1);$row++; my $separator1 = Gtk2::HSeparator->new; $table->attach_defaults($separator1,0,7,$row,$row+1);$row++; my $ok = def_image_button('icons/select.png','OK'); my $okbox=def_hbox(TRUE,0); $okbox->pack_start($ok, FALSE, FALSE,0); my $param_setting=$mpsoc->mpsoc_get_tile_param_setting($tile); @list=('Default','Custom'); $pos=(defined $param_setting)? get_scolar_pos($param_setting,@list): 0; my $nn=(defined $soc_name)? $soc_name : 'soc'; my ($box2,$combo2)=gen_combo_help("Defualt: the tail will get defualt parameter setting of $nn.\n Custom: it will allow custom parameter setting for this tile only." , \@list, $pos); my $lable2=gen_label_in_left(" Parameter Setting:"); $table->attach_defaults($lable2,0,3,$row,$row+1); $table->attach_defaults($box2,3,7,$row,$row+1);$row++; $combo2->signal_connect('changed'=>sub{ my $in=$combo2->get_active_text(); $mpsoc->mpsoc_set_tile_param_setting($tile,$in); }); $combo->signal_connect('changed'=>sub{ my $new_soc=$combo->get_active_text(); if ($new_soc eq ' '){ #unconnect tile $mpsoc->mpsoc_set_tile_free($tile); }else { $mpsoc->mpsoc_set_tile_soc_name($tile,$new_soc); } }); my $mtable = def_table(10, 1, TRUE); $mtable->attach_defaults($scrolled_win,0,1,0,9); $mtable->attach_defaults($okbox,0,1,9,10); $window->add ($mtable); $window->show_all(); $ok-> signal_connect("clicked" => sub{ $window->destroy; set_gui_status($mpsoc,"refresh_soc",1); my $soc_name=$combo->get_active_text(); my $setting=$combo2->get_active_text(); if ($soc_name ne ' ' && $setting ne 'Default'){ get_soc_parameter_setting ($mpsoc,$soc_name,$tile); } #save new values #$top->top_add_default_soc_param(\%param_value); #set_gui_status($mpsoc,"refresh_soc",1); #$$refresh_soc->clicked; }); }); #$button->show_all; return $button; } ########## # gen_tiles ######### sub gen_tiles{ my ($mpsoc)=@_; my ($NE, $NR, $RAw, $EAw, $Fw)=get_topology_info($mpsoc); my $topology=$mpsoc->object_get_attribute('noc_param','TOPOLOGY'); my $table; my $dim_y = floor(sqrt($NE)); $table=def_table($NE%8,$NE/8,FALSE);# my ($row,$col,$homogeneous)=@_; for (my $i=0; $i<$NE;$i++){ my $tile=get_tile($mpsoc,$i); my $y= int($i/$dim_y); my $x= $i % $dim_y; $table->attach_defaults ($tile, $x, $x+1 , $y, $y+1); } return $table; } sub software_edit_mpsoc { my $self=shift; my $name=$self->object_get_attribute('mpsoc_name'); if (length($name)==0){ message_dialog("Please define the MPSoC name!"); return ; } my $target_dir = "$ENV{'PRONOC_WORK'}/MPSOC/$name"; my $sw = "$target_dir/sw"; my ($app,$table,$tview) = software_main($sw); my $make = def_image_button('icons/gen.png','Compile'); my $prog= def_image_button('icons/write.png','Program the memories'); $table->attach ($make,5, 6, 1,2,'shrink','shrink',0,0); $table->attach ($prog,9, 10, 1,2,'shrink','shrink',0,0); $make -> signal_connect("clicked" => sub{ my $load= show_gif("icons/load.gif"); $table->attach ($load,7, 8, 1,2,'shrink','shrink',0,0); $load->show_all; $app->do_save(); append_to_textview($tview,' '); run_make_file($sw,$tview); $load->destroy; }); #Programe the board $prog-> signal_connect("clicked" => sub{ my $error = 0; my $bash_file="$sw/program.sh"; my $jtag_intfc="$sw/jtag_intfc.sh"; add_info(\$tview,"Programe the board using quartus_pgm and $bash_file file\n"); #check if the programming file exists unless (-f $bash_file) { add_colored_info(\$tview,"\tThe $bash_file does not exists! \n", 'red'); $error=1; } #check if the jtag_intfc.sh file exists unless (-f $jtag_intfc) { add_colored_info(\$tview,"\tThe $jtag_intfc does not exists!. Press the compile button and select your FPGA board first to generate $jtag_intfc file\n", 'red'); $error=1; } return if($error); my $command = "cd $sw; sh program.sh"; 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,"Memory was not programed successfully!\n",'red'); }else { if($exit){ add_colored_info(\$tview,"$stdout\n",'red'); add_colored_info(\$tview,"Memory was not programed successfully!\n",'red'); }else{ add_info(\$tview,"$stdout\n"); add_colored_info(\$tview,"Memory is programed successfully!\n",'blue'); } } }); } ############# # load_mpsoc ############# sub load_mpsoc{ my ($mpsoc,$info)=@_; my $file; my $dialog = Gtk2::FileChooserDialog->new( 'Select a File', undef, 'open', 'gtk-cancel' => 'cancel', 'gtk-ok' => 'ok', ); my $filter = Gtk2::FileFilter->new(); $filter->set_name("MPSoC"); $filter->add_pattern("*.MPSOC"); $dialog->add_filter ($filter); my $dir = Cwd::getcwd(); $dialog->set_current_folder ("$dir/lib/mpsoc") ; my @newsocs=$mpsoc->mpsoc_get_soc_list(); add_info(\$info,''); if ( "ok" eq $dialog->run ) { $file = $dialog->get_filename; my ($name,$path,$suffix) = fileparse("$file",qr"\..[^.]*$"); if($suffix eq '.MPSOC'){ my ($pp,$r,$err) = regen_object($file ); if ($r){ add_info(\$info,"**Error: cannot open $file file: $err\n"); $dialog->destroy; return; } clone_obj($mpsoc,$pp); #read save mpsoc socs my @oldsocs=$mpsoc->mpsoc_get_soc_list(); #add exsiting SoCs and add them to mpsoc my $error; #print "old: @oldsocs\n new @newsocs \n"; foreach my $p (@oldsocs) { #print "$p\n"; my @num= $mpsoc->mpsoc_get_soc_tiles_num($p); if (scalar @num && ( grep (/^$p$/,@newsocs)==0)){ my $m="Processing tile $p that has been used for ties @num but is not located in librray anymore\n"; $error = (defined $error ) ? "$error $m" : $m; } $mpsoc->mpsoc_remove_soc ($p) if (grep (/^$p$/,@newsocs)==0); } @newsocs=get_soc_list($mpsoc,$info); # add all existing socs add_info(\$info,"**Error: \n $error\n") if(defined $error); set_gui_status($mpsoc,"load_file",0); } } $dialog->destroy; } ############ # main ############ sub mpsocgen_main{ my $infc = interface->interface_new(); my $soc = ip->lib_new (); my $mpsoc= mpsoc->mpsoc_new(); set_gui_status($mpsoc,"ideal",0); my $main_table = Gtk2::Table->new (25, 12, FALSE); # The box which holds the info, warning, error ... mesages my ($infobox,$info)= create_text(); my $noc_conf_box=get_config ($mpsoc,$info); my $noc_tiles=gen_tiles($mpsoc); my $scr_conf = new Gtk2::ScrolledWindow (undef, undef); $scr_conf->set_policy( "automatic", "automatic" ); $scr_conf->add_with_viewport($noc_conf_box); my $scr_tile = new Gtk2::ScrolledWindow (undef, undef); $scr_tile->set_policy( "automatic", "automatic" ); $scr_tile->add_with_viewport($noc_tiles); $main_table->set_row_spacings (4); $main_table->set_col_spacings (1); my $generate = def_image_button('icons/gen.png','Generate RTL'); my $open = def_image_button('icons/browse.png','Load MPSoC'); my $compile = def_image_button('icons/gate.png','Compile RTL'); my $software = def_image_button('icons/binary.png','Software'); my $entry=gen_entry_object($mpsoc,'mpsoc_name',undef,undef,undef,undef); my $entrybox=labele_widget_info(" MPSoC name:",$entry); my $diagram = def_image_button('icons/diagram.png','Diagram'); my $h1=gen_hpaned($scr_conf,.3,$scr_tile); my $v2=gen_vpaned($h1,.55,$infobox); $main_table->attach_defaults ($v2 , 0, 12, 0,24); $main_table->attach ($open,0, 3, 24,25,'expand','shrink',2,2); $main_table->attach_defaults ($entrybox,3, 6, 24,25); $main_table->attach ($diagram, 6, 7, 24,25,'expand','shrink',2,2); $main_table->attach ($generate, 8, 9, 24,25,'expand','shrink',2,2); $main_table->attach ($software, 9, 10, 24,25,'expand','shrink',2,2); $main_table->attach ($compile, 10, 12, 24,25,'expand','shrink',2,2); #check soc status every 0.5 second. referesh device table if there is any changes Glib::Timeout->add (100, sub{ my ($state,$timeout)= get_gui_status($mpsoc); if ($timeout>0){ $timeout--; set_gui_status($mpsoc,$state,$timeout); }elsif ($state eq 'save_project'){ # Write object file my $name=$mpsoc->object_get_attribute('mpsoc_name'); open(FILE, ">lib/mpsoc/$name.MPSOC") || die "Can not open: $!"; print FILE perl_file_header("$name.MPSOC"); print FILE Data::Dumper->Dump([\%$mpsoc],[$name]); close(FILE) || die "Error closing file: $!"; set_gui_status($mpsoc,"ideal",0); } elsif( $state ne "ideal" ){ $noc_conf_box->destroy(); $noc_conf_box=get_config ($mpsoc,$info); $scr_conf->add_with_viewport($noc_conf_box); $noc_tiles->destroy(); $noc_tiles=gen_tiles($mpsoc); $scr_tile->add_with_viewport($noc_tiles); $h1 -> pack1($scr_conf, TRUE, TRUE); $h1 -> pack2($scr_tile, TRUE, TRUE); $v2-> pack1($h1, TRUE, TRUE); $h1->show_all; $main_table->show_all(); my $saved_name=$mpsoc->object_get_attribute('mpsoc_name'); if(defined $saved_name) {$entry->set_text($saved_name);} set_gui_status($mpsoc,"ideal",0); } return TRUE; } ); $generate-> signal_connect("clicked" => sub{ generate_mpsoc($mpsoc,$info,1); set_gui_status($mpsoc,"refresh_soc",1); }); $open-> signal_connect("clicked" => sub{ set_gui_status($mpsoc,"ref",5); load_mpsoc($mpsoc,$info); }); $compile -> signal_connect("clicked" => sub{ $mpsoc->object_add_attribute('compile','compilers',"QuartusII,Verilator,Modelsim"); my $name=$mpsoc->object_get_attribute('mpsoc_name'); if (length($name)==0){ message_dialog("Please define the MPSoC name!"); return ; } my $target_dir = "$ENV{'PRONOC_WORK'}/MPSOC/$name"; my $top_file = "$target_dir/src_verilog/${name}_top.v"; if (-f $top_file){ generate_mpsoc($mpsoc,$info,0); select_compiler($mpsoc,$name,$top_file,$target_dir); } else { message_dialog("Cannot find $top_file file. Please run RTL Generator first!"); return; } }); $software -> signal_connect("clicked" => sub{ software_edit_mpsoc($mpsoc); }); $diagram-> signal_connect("clicked" => sub{ show_topology_diagram ($mpsoc); }); my $sc_win = new Gtk2::ScrolledWindow (undef, undef); $sc_win->set_policy( "automatic", "automatic" ); $sc_win->add_with_viewport($main_table); return $sc_win; }
Go to most recent revision | Compare with Previous | Blame | View Log