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/] [orcc.pl] - Rev 48
Compare with Previous | Blame | View Log
#!/usr/bin/perl -w use constant::boolean; use strict; use warnings; use FindBin; use lib $FindBin::Bin; use String::Scanf; # imports sscanf() sub select_orcc_generated_srcs { my ($self)=@_; #my $window = def_popwin_size(80,80,"Generate software using ORCC compiler",'percent'); #my $table = def_table(10, 10, FALSE); #$table->attach_defaults($infobox,0,20,$row,$row+1); #pass noc parameter to trace generator my %p; my $params_ref=$self->object_get_attribute('noc_param'); if(defined $params_ref ){ $p{'noc_param'}=$params_ref; } #pass mpsoc name to trace genrator my $mpsoc_name=$self->object_get_attribute('mpsoc_name'); $p{'mpsoc_name'}=$mpsoc_name; #pass soc names to trace genrator my ($NE, $NR, $RAw, $EAw, $Fw)=get_topology_info($self); for (my $tile_num=0;$tile_num<$NE;$tile_num++){ my ($soc_name,$num)= $self->mpsoc_get_tile_soc_name($tile_num); my $top=$self->mpsoc_get_soc($soc_name); if(defined $top){ my @nis=get_NI_instance_list($top); my $inst_name=$top->top_get_def_of_instance($nis[0],'instance'); $p{'ni_name'}{$tile_num}=$inst_name; $p{'soc_name'}{$tile_num}=$soc_name; } } my $trace_gen= trace_gen_main('orcc',\%p);#,$window); #$window->add ($trace_gen); #$window->show_all(); return $trace_gen; my $table; $self->object_add_attribute("file_id",undef,0); $self->object_add_attribute("trace_id",undef,0); my $col=0; my $row=0; my $add = def_image_button('icons/import.png',"Load"); set_tip($add,'Select ORCC generated CSV file'); $table->attach($add,$col,$col+1,$row,$row+1,'shrink','shrink',2,2);$col++; my ($infobox,$info)= create_txview(); my $draw = def_image_button('icons/diagram.png'); set_tip($draw,'View Actor Connection Graph'); $table->attach($draw,$col,$col+1,$row,$row+1,'shrink','shrink',2,2);$col++; $draw->signal_connect ( 'clicked'=> sub{ show_trace_diagram($self,'trace'); }); $row++; $col=0; my $map=actor_map($self,$info); $table->attach_defaults($map,0,5,$row,$row+1); my $i; for ($i=$row; $i<5; $i++){ my $temp=gen_label_in_center(" "); $table->attach_defaults ($temp, 0, 6 , $i, $i+1); } $row=$i; $col=5; my $next=def_image_button('icons/right.png','Next'); $table->attach($next,$col,$col+1,$row,$row+1,'shrink','shrink',2,2);$col++; $add->signal_connect ( 'clicked'=> sub{ my $file; my $dialog = gen_file_dialog('Select the ORCC generated CSV File','csv'); if ( "ok" eq $dialog->run ) { $file = $dialog->get_filename; load_orcc_csv($self,$file,$info); } $dialog->destroy; }); } sub load_orcc_file{ my($self,$tview)=@_; my $file; my $dialog = gen_file_dialog( undef,"csv"); if ( "ok" eq $dialog->run ) { $file = $dialog->get_filename; load_orcc_csv($self,$file,$tview); } $dialog->destroy; } sub load_orcc_csv{ my ($self,$file,$info)=@_; add_info($info,"Use $file for generating actors network\n"); unless (-e $file){ add_colored_info($info,"Cannot find $file\n",'red'); return; } my $f_id=$self->object_get_attribute("file_id",undef); my $t_id=$self->object_get_attribute("trace_id",undef); open my $in, "<:encoding(utf8)", $file or die "$file: $!"; my $sect=0; my $net; my @actors; my %chanels; while (my $line = <$in>) { chomp $line; $line =~ s/[^\S\n]+//g; #remove space if ($line =~ /Name,Package,Actors,Connections/){ $sect=1; next; } if ($line =~ /Name,Incoming,Outgoing,Inputs,Outputs/){ $sect=2; next; } if ($line =~ /Source,SrcPort,Target,TgtPort/){ $sect=3; next; } if($sect==1){ my @fileds=split(/\s*,\s*/,$line); if(defined $fileds[0]){$net=$fileds[0] if($fileds[0]=~/^\w/);} } if($sect==2){ my @fileds=split(/\s*,\s*/,$line); if(defined $fileds[0]){ push(@actors,$fileds[0]) if($fileds[0]=~/^\w/);} } if($sect==3){ my @fileds=split(/\s*,\s*/,$line); if(defined $fileds[0]){ my $src=$fileds[0]; my $src_port=$fileds[1]; my $dest=$fileds[2]; my $dst_port=$fileds[3]; my $buff_Size=$fileds[4]; $chanels{"${src}:$src_port"}= (defined $chanels{"${src}:$src_port"})? $chanels{"${src}:$src_port"}+1 : 0; my $cc=$chanels{"${src}:$src_port"}; #print "find chanel for ** ${src}_$src_port -> ${dest}_$dst_port**: $cc\n"; add_trace($self, "${net}:${f_id}:","raw",$t_id, $src,$dest, 1,$file, $src_port,$dst_port,$buff_Size,$chanels{"${src}:$src_port"},0); #print "add_trace($self, \"${net}:${f_id}:\",\"raw\",$t_id, $src,$dest, 1,$file, $src_port,$dst_port,$buff_Size,$chanels{\"${src}:$src_port\"});\n"; $t_id++; } } $self->set_gui_status('ref',0); } my $num=scalar @actors; if($num==0){ add_colored_info($info,"Could not find any actor in $file\n",'red'); return; } add_info($info,"total of $num actors have found:\n\t"); my $n=1; foreach my $act (@actors){ add_colored_info($info,"$n-$act ",'blue'); $n++; } add_info($info,"\n"); $f_id++; $self->object_add_attribute("trace_id",undef,$t_id); $self->object_add_attribute("file_id",undef,$f_id); } sub update_merge_actor_list{ my ($self,$tview)=@_; #delete old merge objects remove_all_traces ($self,'merge'); #add not mereged traces my $t_id=0; my $ungrouped_ref= $self->object_get_attribute("grouping",'ungrouped'); my @ungrouped = (defined $ungrouped_ref)? @{$ungrouped_ref}:[]; foreach my $actor (@ungrouped){ my @injectors= get_all_source_traces_of_actr($self,$actor,'raw'); foreach my $inject (@injectors) { my ($src,$dst, $Mbytes, $file_id, $file_name,$init_weight,$min_pck, $max_pck, $burst, $injct_rate, $injct_rate_var,$src_port,$dst_port,$buff_size,$chanel,$vc,$class )=get_trace($self,'raw',$inject); my $tdst=$self->get_item_group_name('grouping',$dst); $dst_port=0 if (!defined $dst_port); if($tdst ne $dst){ $dst_port="${dst}_$dst_port"; } add_trace($self, "$file_id",'merge',$t_id, $src,$tdst,$Mbytes,$file_name, $src_port,$dst_port,$buff_size,$chanel,$vc,$class); if(defined $min_pck){ add_trace_extra($self, "$file_id",'merge',$t_id,$min_pck, $max_pck, $burst, $injct_rate, $injct_rate_var ); } $t_id++; } } #update group list my $group_num=$self->object_get_attribute("grouping",'group_num'); my $gname=$self->object_get_attribute("grouping",'group_name_root'); for(my $i=0;$i<$group_num;$i=$i+1){ my $gref = $self->object_get_attribute("grouping","$gname($i)"); next if(! defined $gref); my @grouped = @{$gref}; next if (scalar @grouped == 0); my $merged_actor = $self->object_get_attribute('grouping',"group($i)"."_name"); $merged_actor = "group($i)" if(!defined $merged_actor); #my $tile =get_task_give_tile($self,$merged_actor); # print "my $tile =get_task_give_tile($self,$merged_actor);\n"; #my $tile_id=get_tile_id($self,$merged_actor); #my $tile_id = tile_id_number($tile); #add_info($tview,"Generating $merged_actor.c grouped actor file from: @grouped actors\n"); my $mpsoc_name=$self->object_get_attribute('mpsoc_name'); $mpsoc_name = 'tmp' if (!defined $mpsoc_name); my $target_dir = "$ENV{'PRONOC_WORK'}/MPSOC/$mpsoc_name"; #setp 1 : find local communication ports in merged actor foreach my $actor (@grouped) { my @injectors= get_all_source_traces_of_actr($self,$actor,'raw'); #Where does it transfer? foreach my $inject (@injectors) { my ($src,$dst, $Mbytes, $file_id, $file_name,$init_weight,$min_pck, $max_pck, $burst, $injct_rate, $injct_rate_var,$src_port,$dst_port,$buff_size,$chanel,$vc,$class )=get_trace($self,'raw',$inject); $dst_port=0 if (!defined $dst_port); $src_port=0 if (!defined $src_port); my $dst_actor=$dst; if (check_scolar_exist_in_array($dst,\@grouped)){ #print "$src $src_port is locally connected to $dst $dst_port\n"; $self->object_add_attribute("locally_connected","${dst}_${dst_port}","${src}_${src_port}"); } else { #my ($net,$num,$name)=split(':',$src); my $merge_src="$merged_actor"; $src_port="${src}_$src_port"; my $file="$target_dir/sw/$actor.c"; my $tdst=$self->get_item_group_name('grouping',$dst); # ($dnet,$dnum,$dname)=split(':',$tdst); if($tdst ne $dst){ #my ($dnet,$dnum,$dname)=split(':',$dst); $dst_port="${dst}_$dst_port"; } add_trace($self, "$file_id",'merge',$t_id, $merge_src,$tdst, $Mbytes,$file, $src_port,$dst_port,$buff_size,$chanel,$vc,$class); if(defined $min_pck){ add_trace_extra($self, "$file_id",'merge',$t_id,$min_pck, $max_pck, $burst, $injct_rate, $injct_rate_var ); } $t_id++; }#else }#$ink=ject }#actor } } sub get_port_num{ my ($self,$hash_ref,$actor,$port_name,$chanel) =@_; return undef if(!defined $hash_ref); my %hash = %{$hash_ref}; my $port_num =(defined $chanel)? $hash{$actor}{$port_name}{$chanel} : $hash{$actor}{$port_name}; if(!defined $port_num){ #its a merged actor my $merge_actor=$self->get_item_group_name('grouping',$actor); #my($net,$num,$name)=split(':',$merge_actor); my $merge_port="${actor}_$port_name"; return $hash{$merge_actor}{$merge_port}{$chanel} if(defined $chanel); return $hash{$merge_actor}{$merge_port}; } return $port_num; } sub get_fifo_list{ my ($self)=@_; my %fifos; my ($NE, $NR, $RAw, $EAw, $Fw)=get_topology_info($self); for (my $tile_num=0;$tile_num<$NE;$tile_num++){ my $actor=get_task_assigned_to_tile($self,$tile_num); next if(!defined $actor); my $fifo_num=0; my $ref = $self->get_items_in_a_group("grouping",$actor); my @merge_actors = (defined $ref)? @{$ref} : ($actor); foreach my $actor (@merge_actors){ my @injectors= get_all_source_traces_of_actr($self,$actor,'raw'); foreach my $inject (@injectors) { my ($src,$dst, $Mbytes, $file_id, $file_name,$init_weight,$min_pck, $max_pck, $burst, $injct_rate, $injct_rate_var,$src_port,$dst_port,$buff_size,$chanel,$vc,$class )=get_trace($self,'raw',$inject); $fifos{"${actor}_${src_port}"}{'size'}=$buff_size; $fifos{"$actor"}{'file'}="$file_name"; $fifos{"${actor}_${src_port}"}{'fifo_num'}=$fifo_num; $fifos{"${actor}_${src_port}"}{'chanel_num'}= 0 if(!defined $fifos{"${actor}_${src_port}"}{'chanel_num'}); $fifos{"${actor}_${src_port}"}{'chanel_num'}++; $fifo_num++; $fifos{"tile_$tile_num"}{'fifo_num'}=$fifo_num; } } } for (my $tile_num=0;$tile_num<$NE;$tile_num++){ my $actor=get_task_assigned_to_tile($self,$tile_num); next if(!defined $actor); my $fifo_num=$fifos{"tile_$tile_num"}{'fifo_num'}; $fifo_num= 0 if(!defined $fifo_num); my $ref = $self->get_items_in_a_group("grouping",$actor); my @merge_actors = (defined $ref)? @{$ref} : ($actor); foreach my $actor (@merge_actors){ my @sinkers = get_all_dest_traces_of_actr ($self,$actor,'raw'); foreach my $sink (@sinkers){ my ($src,$dst, $Mbytes, $file_id, $file_name,$init_weight,$min_pck, $max_pck, $burst, $injct_rate, $injct_rate_var,$src_port,$dst_port,$buff_size,$chanel,$vc,$class )=get_trace($self,'raw',$sink); $fifos{"${actor}_${dst_port}"}{'size'}=$buff_size; $fifos{"$actor"}{'file'}="$file_name"; $fifos{"${actor}_${dst_port}"}{'chanel_num'}=$fifos{"${src}_${src_port}"}{'chanel_num'}; my $src_fifo_name= $self->object_get_attribute("locally_connected","${actor}_${dst_port}"); if (defined $src_fifo_name){ #its localy connected. src fifo num and dst fifo num are identical $fifos{"${actor}_${dst_port}"}{'fifo_num'}=$fifos{"$src_fifo_name"}{'fifo_num'}; #print "\$fifos{\"${actor}_${dst_port}\"}{'fifo_num'}=\$fifos{\"$src_fifo_name\"}{'fifo_num'}=$fifos{$src_fifo_name}{'fifo_num'};\n"; }else{ $fifos{"${actor}_${dst_port}"}{'fifo_num'}=$fifo_num; $fifo_num++; $fifos{"tile_$tile_num"}{'fifo_num'}=$fifo_num; } } } } # print Dumper (\%fifos); return %fifos; } sub get_dest_chanel_from_orcc_file{ my ($actor_file,$actor,$dst_port)=@_; #print ("-------------------\n"); my $str = "${actor}_${dst_port}->read_inds\\s*\\["; my $txt = load_file($actor_file); my $n = capture_number_after($str,$txt); return $n; } sub genereate_output_orcc{ my ($self,$tview,$window)=@_; # Code each actor destination port my %soc_names=%{$self->object_get_attribute('soc_name')}; my %ni_names =%{$self->object_get_attribute('ni_name')}; add_info($tview,"Generating grouped actor files\n"); my $group_num=$self->object_get_attribute("grouping",'group_num'); my $gname=$self->object_get_attribute("grouping",'group_name_root'); my $mpsoc_name=$self->object_get_attribute('mpsoc_name'); my $target_dir = "$ENV{'PRONOC_WORK'}/MPSOC/$mpsoc_name"; update_merge_actor_list ($self,$tview); my %srcp_number=get_srcport_constant_list($self,'merge'); my %dstp_number=get_destport_constant_list($self,'merge'); #print "srcport:\n". Dumper(%srcp_number); #print "dstport:\n". Dumper(%dstp_number); add_info($tview,"Generating source files\n"); my $ungrouped_ref= $self->object_get_attribute("grouping",'ungrouped'); my @ungrouped = (defined $ungrouped_ref)? @{$ungrouped_ref}:[]; my %fifos=get_fifo_list($self); my ($NE, $NR, $RAw, $EAw, $Fw)=get_topology_info($self); for (my $tile_num=0;$tile_num<$NE;$tile_num++){ my $target_orccdir= "$target_dir/sw/tile${tile_num}/orcc"; my $actor_tile ="tile($tile_num)"; my $actor_tile_id=$tile_num; my $src_lib_file="$target_dir/sw/tile${actor_tile_id}/SOURCE_LIB"; my $actor=get_task_assigned_to_tile($self,$tile_num); my $soc_name=$soc_names{$actor_tile_id}; my $ni_name=$ni_names{$actor_tile_id}; my $max_dst_port_num=0; #remove old orcc lib folder rmtree("$target_orccdir"); #generate main.c my $r; my @actors_file_names; my $main_c = "$target_dir/sw/tile${actor_tile_id}/main.c"; unlink $main_c; #delete old main.c file open my $fd, ">$main_c" or $r = "$!\n"; if(defined $r) { add_colored_info($tview,"Could not open $main_c to write: $r",'red'); return; } #generate source_lib file my $src_lib="SOURCE_LIB += $soc_name.c "; if (!defined $actor){ print $fd main_c_template($soc_name); close($fd); #write makefile source lib list file save_file($src_lib_file,$src_lib); next; } mkpath("$target_orccdir",1,0755); print $fd autogen_warning(); print $fd get_license_header($main_c); my $ref = $self->get_items_in_a_group("grouping",$actor); my @merge_actors = (defined $ref)? @{$ref} : ($actor); my $main_include = "#include <stddef.h> #include \"$soc_name.h\" #include \"orcc/orcc_lib.h\" "; my $main_def=""; my $main_fifo_def=""; my $main_fifo_assign=""; my $main_fifo_rst_ptr=" volatile unsigned char iport_array[${ni_name}_NUM_VCs]; volatile unsigned char oport_array[${ni_name}_NUM_VCs]; unsigned int credit_buff[${ni_name}_NUM_VCs]; void reset_all_fifo_ptr(void){\n"; my $all_got_packet_function=""; my $all_sent_packet_done_function=""; my $all_check_packet_function=""; my $all_update_credit=""; my $all_init_actor=""; my $all_run_actor=""; my $actors_str=''; #start generation foreach my $actor (@merge_actors){ my $actor_file= get_actr_file_name($self,$actor,'raw'); my ($fname,$fpath,$fsuffix) = fileparse("$actor_file",qr"\..[^.]*$"); my $target_actor_file="$target_orccdir/$fname.c"; my $target_actor_header="$target_orccdir/$fname.h"; open my $fc, ">$target_actor_file" or $r = "$!\n"; if(defined $r) { add_colored_info($tview,"Could not open $target_actor_file to write: $r",'red'); return; } my $LH=uc "${fname}"; my $actor_h="#ifndef\t ${LH}_H\n\t#define\t${LH}_H\n\n"; my $schedul=''; my $Hw_fifo_define='' ; my $transfer_str=''; my $sink_str=''; my $crdit_update=''; my $actor_got_pck_func= " char ${actor}_got_packet_function( unsigned char iport, unsigned int v){ "; my $actor_update_credit= " char ${actor}_update_credit (unsigned int credit_port,unsigned int credit_value){ "; my $actor_check_pck_func= " char ${actor}_check_packet_function (unsigned char iport,unsigned int size){ "; my $actor_sent_pck_done_func= " char ${actor}_sent_packet_done_function (unsigned char oport){ "; my $actor_init=" void ${actor}_init_actor (schedinfo_t * si) { "; my $actor_local_connect; #schedular function $schedul =" ${actor}_scheduler(si);"; #For each actor which is mapped to this tile, we need to find all the traces going in and out to this tile #1- get the actor generated C file name: #push(@actors_file_names, $actor_file); #2- where it mapped? # my $actor_tile = $self->object_get_attribute("MAP_TILE",$actor); # my $actor_tile_id=get_tile_id($self,$actor); #3- How many traces it transfers? my @injectors= get_all_source_traces_of_actr($self,$actor,'raw'); #4- Where does it transffer? foreach my $inject (@injectors) { my ($src,$dst, $Mbytes, $file_id, $file_name,$init_weight,$min_pck, $max_pck, $burst, $injct_rate, $injct_rate_var,$src_port,$dst_port,$buff_size,$chanel,$vc,$class )=get_trace($self,'raw',$inject); $vc= 0 if(!defined $vc); $class= 0 if(!defined $class); #my $dst_tile = $self->object_get_attribute("MAP_TILE",$dst_actor); my $dst_actor=$self->get_item_group_name('grouping',$dst); my $dst_tile = get_task_give_tile($self,$dst_actor); #my $dst_tile_id=get_tile_id($self,$dst_actor); my $dst_tile_id=tile_id_number($dst_tile); if($dst_tile eq $actor_tile){ # this trace is connected locally in one tile #my $rr="\t\t${dst}_$dst_port->read_inds[$chanel]= ${src}_${src_port}->write_ind;\n"; #$actor_local_connect=(defined $actor_local_connect)? $actor_local_connect.$rr:$rr; next; } #5-Now generate all transfer functions (add inject ports) #my ($net,$num,$name)=split(':',$actor); #print "dstp_number{$dst}{$dst_port}= $dstp_number{$dst}{$dst_port};\n"; my $srcportnum = get_port_num($self,\%srcp_number,$src,$src_port,$chanel); my $dstportnum = get_port_num($self,\%dstp_number,$dst,$dst_port); if(!defined $dstportnum){ print Dumper (\$self); print Dumper (\%dstp_number); print "my $dstportnum = get_port_num($self,\%dstp_number,$dst,$dst_port);\n"; print "***********************fix me**********\n"; exit(); } if($chanel==0){ $Hw_fifo_define=$Hw_fifo_define." // transfer ${src_port} port definitions: #define ${src_port}_w $init_weight #define ${src_port}_v $vc #define ${src_port}_class_num $class #define ${src_port}_queue_pointer (unsigned int)&tokens_${src_port}[0] #define ${src_port}_queue_size_in_byte (SIZE_${src_port} << ${actor}_${src_port}_size_shift) #define ${src_port}_end_index index_${src_port} "; #$actor_init.="\t${actor}_${src_port}->write_ind=0;\n"; } $Hw_fifo_define=$Hw_fifo_define." // ${src_port} read chanel ${chanel} definition #define ${src_port}_ch${chanel}_dest_port_num $dstportnum #define ${src_port}_ch${chanel}_dest_phy_addr PHY_ADDR_ENDP_${dst_tile_id} #define ${src_port}_ch${chanel}_src_port_num $srcportnum #define ${src_port}_ch${chanel}_start_index ${actor}_${src_port}->read_inds[$chanel] #define ${src_port}_ch${chanel}_start_index_in_byte ((${src_port}_ch${chanel}_start_index % SIZE_${src_port}) << ${actor}_${src_port}_size_shift) #define ${src_port}_ch${chanel}_has_data_to_send (${src_port}_end_index > ${src_port}_ch${chanel}_start_index) #define ${src_port}_ch${chanel}_data_to_send_size (${src_port}_end_index - ${src_port}_ch${chanel}_start_index) #define ${src_port}_ch${chanel}_send_data_size_in_byte (${src_port}_ch${chanel}_data_to_send_size << ${actor}_${src_port}_size_shift) static unsigned int ${src_port}_ch${chanel}_credit = ${src_port}_queue_size_in_byte; static unsigned int ${src_port}_ch${chanel}_send_data; "; #$actor_init.="\t${src_port}_ch${chanel}_credit = ${src_port}_queue_size_in_byte;\n"; #$actor_init.="\t${actor}_${src_port}->read_inds[$chanel]=0;\n"; $transfer_str=$transfer_str." if(${src_port}_ch${chanel}_has_data_to_send){ // if the sent vc is not busy and the sent_done_isr is not asserted sent a new packet if(${ni_name}_send_is_free(${src_port}_v) && (oport_array[${src_port}_v]==255) ){ //(${ni_name}_packet_is_sent(${src_port}_v)==0)) { //ask NI to transfer the data if(transfer_manage (${src_port}_w, ${src_port}_v, ${src_port}_class_num,${src_port}_ch${chanel}_dest_port_num , ${src_port}_queue_pointer , ${src_port}_queue_size_in_byte, ${src_port}_ch${chanel}_start_index_in_byte, ${src_port}_ch${chanel}_send_data_size_in_byte, ${src_port}_ch${chanel}_dest_phy_addr, ${src_port}_ch${chanel}_credit,${src_port}_ch${chanel}_src_port_num, & ${src_port}_ch${chanel}_send_data, & ${src_port}_ch${chanel}_credit )){ } }//has data }//not busy "; $actor_sent_pck_done_func=$actor_sent_pck_done_func." if(oport == ${src_port}_ch${chanel}_src_port_num){ ${src_port}_ch${chanel}_start_index= ${src_port}_ch${chanel}_start_index+ (${src_port}_ch${chanel}_send_data>>${actor}_${src_port}_size_shift); #ifdef ORCC_DEBUG_EN if (${src_port}_ch${chanel}_data_to_send_size > SIZE_${src_port}){ printf (\"Error the waiting data in ${actor} ${src_port} quque (\%u) is larger than the queue size (\%u)\\n\",${src_port}_ch${chanel}_data_to_send_size,SIZE_${src_port} ); } #endif return 1; } "; $actor_update_credit =$actor_update_credit." if( credit_port == ${src_port}_ch${chanel}_src_port_num){ ${src_port}_ch${chanel}_credit += (credit_value << ${actor}_${src_port}_size_shift); //credit value in byte #ifdef ORCC_DEBUG_EN if (${src_port}_ch${chanel}_credit > (SIZE_${src_port} << ${actor}_${src_port}_size_shift )){ printf (\"Error the credit counter in ${actor} ${src_port}_ch${chanel} (\%u) is larger than the queue size (\%u)\\n\",${src_port}_ch${chanel}_credit,SIZE_${src_port} ); } #endif return 1; } "; }# end inject #6-Where the packet comes from? we need to update the sender with the remaining credit my @sinkers = get_all_dest_traces_of_actr ($self,$actor,'raw'); foreach my $sink (@sinkers){ my ($src,$dst, $Mbytes, $file_id, $file_name,$init_weight,$min_pck, $max_pck, $burst, $injct_rate, $injct_rate_var,$src_port,$dst_port,$buff_size,$chanel,$vc,$class )=get_trace($self,'raw',$sink); my $dst_chnl =get_dest_chanel_from_orcc_file($actor_file,$actor,$dst_port); my $srcportnum = get_port_num($self,\%srcp_number,$src,$src_port,$chanel); my $src_actor=$self->get_item_group_name('grouping',$src); my $src_tile = get_task_give_tile($self,$src_actor); #my $src_tile_id=get_tile_id($self,$src); my $src_tile_id=tile_id_number($src_tile); #print "my $srcportnum = get_port_num($self,\%srcp_number,$src,$src_port,$chanel);\n"; if($src_tile eq $actor_tile){ next; } if(!defined $srcportnum){ print Dumper (\$self); print Dumper (\%srcp_number); print "my $srcportnum = get_port_num($self,\%srcp_number,$src,$src_port,$chanel);\n"; print "***********************fix me**********\n"; exit(); } #7 We need to add sink ports #save the input port index before running the credit #$actor_init.=\t${actor}_${dst_port}->read_inds[0]=0; #$actor_init.=\t${actor}_${dst_port}->write_ind=0; $actor_init =$actor_init." \tread_${dst_port}(); \tindex_${dst_port}_sender=index_$dst_port; "; my $dstportnum = get_port_num($self,\%dstp_number,$dst,$dst_port); $max_dst_port_num=$dstportnum if($dstportnum > $max_dst_port_num ); $Hw_fifo_define=$Hw_fifo_define." // Receiver port ${dst_port} port definitions: static unsigned int index_${dst_port}_sender; #define ${dst_port}_credit_w 1 #define ${dst_port}_credit_v 0 //Alternatively it can be another VC #define ${dst_port}_credit_class_num 0 //Alternatively it can be another class #define ${dst_port}_credit_dest_port 0 //0 is reserved for credit #define ${dst_port}_credit_pointer (unsigned int)&credit_send_buff #define ${dst_port}_credit_size_in_byte 4 #define ${dst_port}_credit_start_index 0 #define ${dst_port}_credit_send_data_size_in_byte 4 #define ${dst_port}_credit_dest_phy_addr PHY_ADDR_ENDP_${src_tile_id} #define ${dst_port}_has_credit_to_send (index_$dst_port > index_${dst_port}_sender) #define ${dst_port}_src_port_num $srcportnum #define ${dst_port}_dst_port_num $dstportnum #define ${dst_port}_queu_pointer (unsigned int)&tokens_${dst_port}[0] #define ${dst_port}_queue_size_in_byte (SIZE_${dst_port} << ${actor}_${dst_port}_size_shift) #define ${dst_port}_start_index_in_byte ((${actor}_${dst_port}->write_ind % SIZE_${dst_port})<< ${actor}_${dst_port}_size_shift) #define ${dst_port}_read_indx ${actor}_${dst_port}->read_inds[$dst_chnl] #define ${dst_port}_data_num_to_process (${actor}_${dst_port}->write_ind -${dst_port}_read_indx) "; $crdit_update=$crdit_update." if( ${dst_port}_has_credit_to_send){ if(${ni_name}_send_is_free(${dst_port}_credit_v) && (oport_array[${dst_port}_credit_v]==255) ){ // (${ni_name}_packet_is_sent(${dst_port}_credit_v)==0)){ //credit_num = (SIZE_${dst_port} - ${dst_port}_data_num_to_process)& 0xFFFF; credit_num = (index_$dst_port - index_${dst_port}_sender)& 0xFFFF; credit_send_buff= ( (${dst_port}_src_port_num <<16) | credit_num ); // most significant 16 bits indicates the port, list significant 16 bits are credit in word #ifdef ORCC_DEBUG_EN if(${dst_port}_data_num_to_process > SIZE_${dst_port}){ printf(\"Error ${dst_port}_data_num_to_process (\%u) is larger than SIZE_${dst_port} (\%u)\\n\",${dst_port}_data_num_to_process,SIZE_${dst_port}); } #endif if( transfer_manage (${dst_port}_credit_w, ${dst_port}_credit_v, ${dst_port}_credit_class_num, ${dst_port}_credit_dest_port, ${dst_port}_credit_pointer, ${dst_port}_credit_size_in_byte, ${dst_port}_credit_start_index, ${dst_port}_credit_send_data_size_in_byte, ${dst_port}_credit_dest_phy_addr, 5,${dst_port}_credit_dest_port, &tmp1,&tmp2 ) ){ index_${dst_port}_sender=index_${dst_port}; } } } "; $actor_got_pck_func=$actor_got_pck_func." if (iport == ${dst_port}_dst_port_num){ ${ni_name}_receive (v, ${dst_port}_queu_pointer , ${dst_port}_queue_size_in_byte, ${dst_port}_start_index_in_byte); return 1; } "; $actor_check_pck_func =$actor_check_pck_func." if(iport==${dst_port}_dst_port_num){ ${actor}_${dst_port}->write_ind = ${actor}_${dst_port}->write_ind + (size >> ${actor}_${dst_port}_size_shift); #ifdef ORCC_DEBUG_EN unsigned int diff = ${actor}_${dst_port}->write_ind - ${dst_port}_read_indx; if(diff > SIZE_${dst_port})\{ printf (\"Error in ${actor}_${dst_port}: Write_index(\%u) - Read_index(\%u) is larger than queue size (\%u)\\n\",${actor}_${dst_port}->write_ind , ${dst_port}_read_indx,SIZE_${dst_port}); } #endif return 1; } "; #print "\$fifos{\"$name\"}{'file'}=$file_name\n"; #print "\$fifos ${name}_${dst_port}'size'=$buff_size;\n"; } #sink $actor_h=$actor_h."void ${actor}_initialize(schedinfo_t *);\n"; $actor_h=$actor_h."void ${actor}_scheduler(schedinfo_t *);\n"; $actor_h=$actor_h."char ${actor}_got_packet_function(unsigned char , unsigned int);\n"; $all_got_packet_function=$all_got_packet_function."\t\t\t\t${actor}_got_packet_function(iport,i);\n"; $actor_got_pck_func=$actor_got_pck_func." #ifdef ORCC_DEBUG_EN printf(\"Wrong got pck port \%u\\n\",iport); #endif return 0; } "; $actor_h=$actor_h."char ${actor}_check_packet_function(unsigned char,unsigned int);\n"; $all_check_packet_function = $all_check_packet_function."\t\t\t\t${actor}_check_packet_function(iport,size);\n"; $actor_check_pck_func=$actor_check_pck_func." #ifdef ORCC_DEBUG_EN printf(\"Wrong check pck port \%u\\n\",iport); #endif return 0; } "; $actor_h=$actor_h."char ${actor}_sent_packet_done_function(unsigned char);\n"; $all_sent_packet_done_function = $all_sent_packet_done_function."\t\t\t\t${actor}_sent_packet_done_function(oport);\n"; $actor_sent_pck_done_func=$actor_sent_pck_done_func." #ifdef ORCC_DEBUG_EN printf(\"Wrong sent done port \%u\\n\",oport); #endif return 0; } "; $actor_h=$actor_h."char ${actor}_update_credit(unsigned int, unsigned int);\n"; $all_update_credit=$all_update_credit."\t\t\t\t${actor}_update_credit(credit_port,credit_value);\n"; $actor_update_credit =$actor_update_credit." #ifdef ORCC_DEBUG_EN printf(\"Wrong ${actor} Credit port \%u\\n\",credit_port); #endif return 0; } "; $actor_h=$actor_h."void ${actor}_init_actor(schedinfo_t *);\n"; $all_init_actor=$all_init_actor."\t${actor}_init_actor(&si);\n"; $actor_init=$actor_init." ${actor}_initialize(si); } "; $actor_h=$actor_h."void ${actor}_run_actor(schedinfo_t *);\n"; $all_run_actor=$all_run_actor."\t\t${actor}_run_actor(&si);\n"; #$all_run_actor=$all_run_actor.$actor_local_connect if(defined $actor_local_connect); my $t = (length $crdit_update > 10 )? "unsigned int tmp1,tmp2,credit_num,credit_send_buff;" : ""; my $actor_run=" void ${actor}_run_actor (schedinfo_t * si) { //unsigned int credit_send_buff; //run schedular $schedul //check if input ports have credit update to send $t $crdit_update //check if output port has data to send $transfer_str #if (ORCC_SENT_DONT_INT_EN == 0) if(${ni_name}_any_sent_done_isr_is_asserted()) sent_packet_done_function(); #endif #if (ORCC_SAVE_DONT_INT_EN == 0) if(${ni_name}_any_save_done_isr_is_asserted()) check_packet_function(); #endif #if (ORCC_GOT_PCK_INT_EN == 0) if(${ni_name}_any_got_pck_isr_is_asserted()) got_packet_function(); #endif #if (ORCC_GOT_ERR_INT_EN == 0) if(${ni_name}_any_err_isr_is_asserted()) error_handling_function(); #endif } "; my $r; add_colored_info($tview,"actor name: $actor\n",'green'); #copy orcc lib files my $orcc_lib_dir = get_project_dir()."/mpsoc/src_c/orcc/lib"; opendir(DIR,"$orcc_lib_dir") or $r= "$!\n"; if(defined $r) { add_colored_info($tview,"cannot open directory: $r",'red'); return; } foreach my $name (readdir(DIR)) { # add_colored_info($tview,"copy ($orcc_lib_dir/$name,$target_dir/sw/tile${actor_tile_id}/);\n ",'red'); copy ("$orcc_lib_dir/$name","$target_orccdir/"); } #print $fe "orcc/$fname.c "; #$main_include=$main_include."#include \"orcc/$fname.c\"\n"; $main_include=$main_include."#include \"orcc/$fname.h\"\n"; $src_lib="$src_lib orcc/$fname.c"; print $fc " // Generated from $actor_file\n"; my $defines=""; my $pval = $self->object_get_attribute("map_param","add_debug"); $defines .= ($pval eq '1\'b1')? "#define ORCC_DEBUG_EN\n" : ""; $pval = $self->object_get_attribute("map_param","sent_int"); $defines .= ($pval eq '1\'b1')? "#define ORCC_SENT_DONT_INT_EN 1\n" : "#define ORCC_SENT_DONT_INT_EN 0\n"; $pval = $self->object_get_attribute("map_param","receive_int"); $defines .= ($pval eq '1\'b1')? "#define ORCC_SAVE_DONT_INT_EN 1\n" : "#define ORCC_SAVE_DONT_INT_EN 0\n"; $pval = $self->object_get_attribute("map_param","receive_int"); $defines .= ($pval eq '1\'b1')? "#define ORCC_GOT_PCK_INT_EN 1\n" : "#define ORCC_GOT_PCK_INT_EN 0\n"; $pval = $self->object_get_attribute("map_param","got_err_int"); $defines .= ($pval eq '1\'b1')? "#define ORCC_GOT_ERR_INT_EN 1\n" : "#define ORCC_GOT_ERR_INT_EN 0\n"; print $fc " #include <stddef.h> #include \"../$soc_name.h\" #include \"orcc_lib.h\" #include \"../../phy_addr.h\" #include \"$fname.h\" extern volatile unsigned char oport_array [${ni_name}_NUM_VCs]; "; my $origen_def=""; my $origen_fuctions=""; #read actor file name and remove unnecessarily codes. comment every files start with #include and extern open my $fh, "<", $actor_file or $r = "$!\n"; if(defined $r) { add_colored_info($tview,"Could not open $actor_file: $r",'red'); return; } while (my $line = <$fh>) { chomp $line; #search for fifo size inside the file if( $line =~ /^\s*#define\s+SIZE_\w+/){ #example: #define SIZE_operand_1 32 my $text = $line; $text =~ s/\s+/ /g; # remove extra spaces $text =~ s/^\s+//; #ltrim my ($fifo_name,$size) = sscanf("#define SIZE_%s %u",$text); $actor_h = $actor_h."#define SIZE_${actor}_$fifo_name $size\n"; $fifos{"${actor}_$fifo_name"}{'size'}=$size; } $line = '//'.$line if( $line =~ /^\s*#include/); # comment every line start with #include if( $line =~ /^\s*extern\s+/){ my $extern=0; $line =~ s/\s+/ /g; # remove extra spaces $line =~ s/^\s+//; #ltrim #fifo my ($type,$fifo_name) = sscanf("extern fifo_%s_t *%s;",$line); if(defined $type){ $extern=1; if (defined $fifos{$fifo_name}){ #add fifo definition: my $size = $fifos{$fifo_name}{'size'}; #if(!defined $size ){ $size = "$fifo_name"; #$size=~ s/^\s*${actor}_//g; $size = "SIZE_$size"; #} my $fnum = $fifos{"$fifo_name"}{'fifo_num'}; my $ch_num= $fifos{"$fifo_name"}{'chanel_num'}; $ch_num =1 if(!defined $ch_num); my $src_fifo_name= $self->object_get_attribute("locally_connected","$fifo_name"); #printf "$src_fifo_name locally connected $fifo_name\n"; unless (defined $src_fifo_name){#check if destintion port is not localy connected $main_fifo_def=$main_fifo_def . "DECLARE_FIFO(${type}, $size, $fnum, $ch_num);\n"; } $main_fifo_assign=$main_fifo_assign . "fifo_${type}_t *$fifo_name = &fifo_$fnum;\n"; $main_fifo_rst_ptr.="\t${fifo_name}->write_ind=0;\n"; for (my $c=0; $c<$ch_num; $c++){ $main_fifo_rst_ptr.="\t${fifo_name}->read_inds[$c]=0;\n" } $origen_fuctions= $origen_fuctions . "$line \n"; #$main_fifo_rst_ptr.="\t printf(\"${fifo_name}_addr=%u\\n\", &${fifo_name}->contents[0]);\n"; my $shift = ($type eq "i8" || $type eq "u8") ? 0 : ($type eq "i16" || $type eq "u16") ? 1 : ($type eq "i32" || $type eq "u32") ? 2 : ($type eq "i64" || $type eq "u64") ? 3 : "undef_type check orcc.pl"; $origen_def=$origen_def. "#define ${fifo_name}_size_shift $shift \n"; }else{ print Dumper(\%fifos); add_colored_info($tview,"Could not find $fifo_name in csv file\n",'red'); return; } } #connection_t my ($connect_name) = sscanf("extern connection_t %s;",$line); if(defined $connect_name ){ $extern=1; $main_def=$main_def . " connection_t $connect_name = {0, 0, 0, 0};// We dont need connection as they are done in hardware. just define to prevent error\n"; $origen_fuctions= $origen_fuctions . "$line \n"; } #actor_t my ($actor_name) = sscanf("extern actor_t %s;",$line); if(defined $actor_name ){ $extern=1; if (defined $fifos{"$actor_name"}{'file'}){ # print "===============================================================\n"; #add actor definition #search in network.c file for actor definition my $csv=$fifos{"$actor_name"}{'file'}; my ($fname,$path,$suffix) = fileparse("$csv",qr"\..[^.]*$"); my $net= "$path/${fname}.c"; my @lines = get_line_have_string($net,"actor_t $actor_name",$tview); if(defined $lines[0]){ #print $fd "void ${actor_name}_initialize(schedinfo_t *);\n"; #print $fd "void ${actor_name}_scheduler (schedinfo_t *);\n"; #print $fd "$lines[0]\n"; $origen_fuctions= $origen_fuctions . "$line \n"; $actors_str=$actors_str."$lines[0]\n" if($actor_name eq $actor); } } } $line= "//$line\n" ; # comment every files start with extern add_colored_info($tview,"The Auto generator does not know how to define this extern definition:\n $line \n",'red') if($extern == 0); $origen_fuctions = $origen_fuctions. "$line\n"; }#extern elsif( $line =~ /^\s?#define\s+/){ $origen_def=$origen_def. "$line\n"; }else{ $origen_fuctions = $origen_fuctions. "$line\n"; } } print $fc " $origen_def $Hw_fifo_define $origen_fuctions $actor_got_pck_func $actor_update_credit $actor_check_pck_func $actor_sent_pck_done_func $actor_run $actor_init "; close($fc); $actor_h.="$defines unsigned int transfer_manage (unsigned int, unsigned int, unsigned int, unsigned char, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned char, unsigned int *, unsigned int *); void got_packet_function(void); void check_packet_function (void); void sent_packet_done_function (void); void error_handling_function (void); #endif "; open my $fp, ">$target_actor_header" or $r = "$!\n"; if(defined $r) { add_colored_info($tview,"Could not open $target_actor_header to write: $r",'red'); return; } print $fp $actor_h; close($fp); } my $got_pck_func= " void got_packet_function(void){ unsigned int i ; unsigned char iport; for (i=0;i<${ni_name}_NUM_VCs;i++){ if((${ni_name}_got_packet(i)) && (iport_array[i]==255) && ni_receive_is_free(i) ) { iport =${ni_name}_RECEIVE_PRECAP_DATA_REG(i); iport_array[i]=iport; if(iport==0){ //a credit update packet is recived; ${ni_name}_receive (i, (unsigned int)& credit_buff[i] , 4, 0); }else{ $all_got_packet_function } ${ni_name}_ack_got_pck_isr(i); }//If ${ni_name} got packet }//for }// got_packet_function "; my $sent_packet_done_function = " void sent_packet_done_function (void){ unsigned char oport; unsigned int i; for (i=0;i<${ni_name}_NUM_VCs;i++){ if(${ni_name}_packet_is_sent(i)) { oport= oport_array[i]; if(oport==0){ // a credit update packet has sent out }else{ $all_sent_packet_done_function } oport_array[i]=255; ${ni_name}_ack_send_done_isr(i); }//If ${ni_name}_packet_is_sent }//for }//sent_packet_done_function "; my $check_pck_func =" void check_packet_function (void){ unsigned char iport; unsigned int i ,size ; unsigned int credit_value,credit_port; #ifdef ORCC_DEBUG_EN struct SRC_INFOS src_info; #endif for (i=0;i<${ni_name}_NUM_VCs;i++){ if(${ni_name}_packet_is_saved(i)) { size=${ni_name}_RECEIVE_DATA_SIZE_REG(i); //size in byte iport= iport_array[i]; #ifdef ORCC_DEBUG_EN src_info=get_src_info(i); if(iport != src_info.r) printf (\"Error: iport missmatch \%u != \%u \\n\",iport, src_info.r ); #endif iport_array[i]=255; if(iport==0){ // a credit update packet has been received credit_port = credit_buff[i] >> 16; //output port num credit_value = (credit_buff[i] & 0xFFFF); // credit value in word $all_update_credit }else{ $all_check_packet_function } ${ni_name}_ack_save_done_isr(i); }//If ${ni_name}_packet_is_saved }//for }// check_packet_function "; my $ni_isr=' /* transfer_manage w: initial weight v: Virtual chanel number class_num: message class number dest_port: destination queue number queue_pointer: address in byte queue_size: queue size in byte start_index: start index byte number end_index: end index byte number dest_phy_addr credit: Number of byte available in destination queue */ unsigned int transfer_manage (unsigned int w, unsigned int v, unsigned int class_num, unsigned char dest_port, unsigned int queue_pointer,unsigned int queue_size, unsigned int start_index, unsigned int send_data_size_in_byte, unsigned int dest_phy_addr,unsigned int credit, unsigned char port_num, unsigned int * sent_dat_size, unsigned int * dest_credit_size){ unsigned int start_addr_pointer; unsigned int data_size=send_data_size_in_byte; '; $ni_isr=$ni_isr." if (${ni_name}_send_is_busy(v)) return 0 ; // if VC is busy sending previous packet do nothing "; $ni_isr=$ni_isr.' if(credit==0) return 0; if(data_size==0) return 0; start_addr_pointer = queue_pointer + start_index; if(data_size > credit) data_size = credit; // we dont want to send more data than the receiver credit if((start_index + data_size) > queue_size) data_size = queue_size-start_index; // we only send data until end of the queue. The rest will be sent in next round starting from beginning of the queue if(data_size==0) return 0; '; $ni_isr=$ni_isr." oport_array[v]= port_num; // port_num and data size should be saved before calling transfer function. * sent_dat_size = data_size; * dest_credit_size -= data_size; ${ni_name}_transfer (w, v, class_num, dest_port , start_addr_pointer, data_size, dest_phy_addr); return 1; } void error_handling_function(){ unsigned int i; for (i=0;i<${ni_name}_NUM_VCs;i++){ if(${ni_name}_got_buff_ovf(i)) { printf (\"VC%u:The receiver allocated buffer size is smaller than the received packet size in core\%u\\n\",i,COREID); ${ni_name}_ack_buff_ovf_isr(i); } if(${ni_name}_got_send_dsize_err(i)) { printf (\"VC%u:The send data size is not set in core\%u\\n\",i,COREID); ${ni_name}_ack_send_dsize_err_isr(i); } if(${ni_name}_got_burst_size_err(i)){ printf (\"VC%u:The burst size is not set in core\%u\\n\",i,COREID); ${ni_name}_ack_burst_size_err_isr(i); } if(${ni_name}_got_invalid_send_req(i)){ printf( \"VC%u:A new send request is received while the DMA is still busy sending previous packet in core\%u\\n\",i,COREID); ${ni_name}_ack_invalid_send_req_isr(i); } if(${ni_name}_got_crc_mismatch(i)){ printf( \"VC%u:CRC miss-matched in core\%u\\n\",i,COREID); ${ni_name}_ack_crc_mismatch_isr(i); } }//for }//error_handle void ${ni_name}_isr(void){ //place your interrupt code here #if (ORCC_GOT_ERR_INT_EN == 1) if(${ni_name}_any_err_isr_is_asserted() ){ // An error ocure error_handling_function(); } #endif #if (ORCC_SENT_DONT_INT_EN == 1) if( ${ni_name}_any_sent_done_isr_is_asserted() ){ //check which VC has finished sending the packet. sent_packet_done_function(); } #endif #if (ORCC_GOT_PCK_INT_EN == 1 || ORCC_SAVE_DONT_INT_EN ==1) // regardless of ORCC_SAVE_DONT_INT_EN we need to check if the fifo pointer has been updated with last packet data size before sending save command for new packet to NI. if( ${ni_name}_any_save_done_isr_is_asserted()){ //check which VC has finished saving the packet. This function must be called before got_packet_function check_packet_function(); } #endif #if (ORCC_GOT_PCK_INT_EN == 1) if(${ni_name}_any_got_pck_isr_is_asserted() ){ //check which VC got packet got_packet_function(); } #endif return; } "; my $v_val= $self->object_get_attribute('noc_param','V'); my $opr =''; for (my $i=0;$i<$v_val; $i++){ $opr = $opr."\toport_array[$i]=255;\n"; $opr = $opr."\tiport_array[$i]=255;\n"; } $main_fifo_rst_ptr.= "$opr }\n"; my $main=" int main(){ schedinfo_t si; reset_all_fifo_ptr(); $all_init_actor general_int_init(); general_int_add(${ni_name}_INT_PIN, ${ni_name}_isr, 0); //${ni_name}_INT_PIN // Enable ${ni_name} interrupt (its connected to interrupt pin 0) general_int_enable(${ni_name}_INT_PIN); general_cpu_int_en(); // hw interrupt enable function: // ${ni_name}_initial (burst_size, errors_int_en, send_int_en, save_int_en, got_pck_int_en) ${ni_name}_initial (16,ORCC_GOT_ERR_INT_EN,ORCC_SENT_DONT_INT_EN,ORCC_SAVE_DONT_INT_EN,ORCC_GOT_PCK_INT_EN); delay(100); while(1){ $all_run_actor } return 0; } "; my $log2=log2($max_dst_port_num +1); print $fd " $main_include #define MAX_DST_PORT_NUM $max_dst_port_num // make sure that the HDATA_PRECAPw widh is >= log2(MAX_DST_PORT_NUM) #if ( $log2 > ${ni_name}_HDATA_PRECAPw ) #error \" The value of HDATA_PRECAPw should be defined at least $log2. Open the processing tile generator and increase the NI HDATA_PRECAPw value >= $log2\" #endif //make dure Byte_En is asserted in NI #if (${ni_name}_BYTE_EN == 0) #error \" The NI NI BYTE_EN parameter should be set as one for correct data comminication between cores. \" #endif // a simple delay function void delay ( unsigned int num ){ while (num>0){ num--; nop(); // asm volatile (\"nop\"); } return; } $actors_str $main_fifo_def $main_fifo_assign $main_fifo_rst_ptr $main_def $got_pck_func $check_pck_func $sent_packet_done_function $ni_isr $main "; close($fd); save_file($src_lib_file,$src_lib); add_colored_info($tview,"$main_c file has been created successfully from @actors_file_names file \n",'blue'); } #actor #done message_dialog("The source files have been generated successfully"); #print Dumper (\$self); } #end sub sub get_line_have_string{ my ($file,$str,$tview)=@_; my $r; my @matches; open my $fh, "<", $file or $r = "$!\n"; if(defined $r) { add_colored_info($tview,"Could not open $file: $r",'red'); return; } while (my $line = <$fh>) { chomp $line; $line =~ s/\s+/ /g; # remove extra spaces $line =~ s/^\s+//; #ltrim if ($line =~ /$str/){ push(@matches,$line); } } return @matches; } sub get_destport_constant_list{ my ($self,$category)=@_; my %destport_const; #1- Get list of all actors my @actors= get_all_tasks($self,$category); foreach my $actor (@actors){ my $i=1; #2- for each actor get the list of all input ports my @sinkers= get_all_dest_traces_of_actr($self,$actor,$category); #3- number each source port of this actor foreach my $sink (@sinkers){ my ($src,$dst, $Mbytes, $file_id, $file_name,$init_weight,$min_pck, $max_pck, $burst, $injct_rate, $injct_rate_var,$src_port,$dst_port,$buff_size,$chanel,$vc,$class )=get_trace($self,$category,$sink); $destport_const{$actor}{$dst_port}= $i; #print "destport_const{$actor}{$dst_port}= $i;\n"; $i++; } } return %destport_const; } sub get_srcport_constant_list{ my ($self,$category)=@_; my %srcport_const; #1- Get list of all actors my @actors= get_all_tasks($self,$category); #print "@actors\n**************************************************"; foreach my $actor (@actors){ my $i=1; #2- for each actor get the list of all output ports my @injectors= get_all_source_traces_of_actr($self,$actor,$category); #3- number each source port of this actor foreach my $inject (@injectors){ my ($src,$dst, $Mbytes, $file_id, $file_name,$init_weight,$min_pck, $max_pck, $burst, $injct_rate, $injct_rate_var,$src_port,$dst_port,$buff_size,$chanel,$vc,$class )=get_trace($self,$category,$inject); $srcport_const{$actor}{$src_port}{$chanel}= $i; $i++; } } return %srcport_const; } sub get_all_dest_traces_of_actr{ my ($self,$actor,$category)=@_; my @traces =get_trace_list($self,$category); my @sources; foreach my $p (@traces){ my ($src,$dst, $Mbytes, $file_id, $file_name,$init_weight,$min_pck, $max_pck, $burst, $injct_rate, $injct_rate_var)=get_trace($self,$category,$p); push (@sources,$p) if($dst eq $actor); } return @sources; } sub get_all_source_traces_of_actr{ my ($self,$actor,$category)=@_; my @traces =get_trace_list($self,$category); my @dests; foreach my $p (@traces){ my ($src,$dst, $Mbytes, $file_id, $file_name,$init_weight,$min_pck, $max_pck, $burst, $injct_rate, $injct_rate_var)=get_trace($self,$category,$p); push (@dests,$p) if($src eq $actor); } return @dests; } sub get_actr_file_name { my ($self,$actor,$category)=@_; my @traces =get_trace_list($self,$category); foreach my $p (@traces){ my ($src,$dst, $Mbytes, $file_id, $file_name,$init_weight,$min_pck, $max_pck, $burst, $injct_rate, $injct_rate_var)=get_trace($self,$category,$p); if($src eq $actor || $dst eq $actor){ #the actor supposed to be located next to CSV file and have the same file name as actor name my ($fname,$path,$suffix) = fileparse("$file_name",qr"\..[^.]*$"); #my ($net,$num,$name)=split(':',$actor); return "$path/${actor}.c"; } } return undef; } 1;