OpenCores
URL https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk

Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc

[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [perl_gui/] [lib/] [perl/] [diagram.pl] - Rev 43

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 soc;
require "widget.pl"; 
require "emulator.pl";
use File::Copy;
 
 
 
 
sub get_dot_file{
	my $self= shift;
	my $self_name=$self->object_get_attribute('soc_name');
	my $remove_clk = $self->object_get_attribute("tile_diagram","show_clk");
	my $remove_reset = $self->object_get_attribute("tile_diagram","show_reset");
	my $remove_unused = $self->object_get_attribute("tile_diagram","show_unused");
 
	my $dotfile=
"digraph G {
	graph [rankdir = LR , splines=polyline, overlap = false]; 
	node[shape=record];
";
 
	my @all_instances=$self->soc_get_all_instances();
	#print "@all_instances\n";
	my $graph_connect= '';
	my $n=0;
	#my %socket_color;
	foreach my $instance_id (@all_instances){
		my $first=1;
		my $instance_name=$self->soc_get_instance_name($instance_id);
		$dotfile="$dotfile \n\t$instance_id \[label=\"{  ";
 
		my @sockets= $self->soc_get_all_sockets_of_an_instance($instance_id);
		@sockets = remove_scolar_from_array(\@sockets,'clk') if ($remove_clk);
		@sockets = remove_scolar_from_array(\@sockets,'reset') if ($remove_reset);
 
 
		foreach my $socket (@sockets){
 
			my @nums=$self->soc_list_socket_nums($instance_id,$socket);
			foreach my $num (@nums){
				my $name= $self->soc_get_socket_name ($instance_id,$socket,$num);
				my  ($s_type,$s_value,$s_connection_num)=$self->soc_get_socket_of_instance($instance_id,$socket);
				my $v=$self->soc_get_module_param_value($instance_id,$s_value);
				$v=1 if ( length( $v || '' ) ==0);
				#for(my $i=$v-1; $i>=0; $i--) {
				for(my $i=0; $i<$v; $i++) {
					#$socket_color{socket_${socket}\_$i}=$n;
					#$n = ($n<30)? $n+1 : 0;
					my ($ref1,$ref2)= $self->soc_get_modules_plug_connected_to_socket($instance_id,$socket,$i);
					my %connected_plugs=%$ref1;
					my %connected_plug_nums=%$ref2;
					if(%connected_plugs || $remove_unused==0){ 
						$dotfile= ($first)? "$dotfile\{<socket_${socket}\_$i>$name\_$i" : "$dotfile |<socket_${socket}_${i}>$name\_${i}";
						$first=0;
					}
				}
 
			}
		}	
 
 
		$dotfile=($first)? "$dotfile $instance_name"  : "$dotfile}|$instance_name";
		$first=1;
		my @plugs= $self->soc_get_all_plugs_of_an_instance($instance_id);
		@plugs = remove_scolar_from_array(\@plugs,'clk') if ($remove_clk);
		@plugs = remove_scolar_from_array(\@plugs,'reset') if ($remove_reset);
 
		my %plug_order;
		my @noconnect;
		foreach my $plug (@plugs){
 
			my @nums=$self->soc_list_plug_nums($instance_id,$plug);
			foreach my $num (@nums){
				my ($addr,$base,$end,$name,$connect_id,$connect_socket,$connect_socket_num)=$self->soc_get_plug($instance_id,$plug,$num);
 
				if(defined $connect_socket || $remove_unused==0){ 
					#$dotfile= ($first)?  "$dotfile |{<plug_${plug}_${num}>$name" :  "$dotfile|<plug_${plug}_${num}>$name";
					if(defined $connect_id && defined $connect_socket){
						my @sockets= $self->soc_get_all_sockets_of_an_instance($connect_id);
						my $order_val=0;
						my $s1=get_pos($connect_id, @all_instances);
						my $s2=get_pos($connect_socket,  @sockets);
						$order_val=$s1*1000000+$s2*10000+$connect_socket_num;
						$plug_order{$order_val}=  "<plug_${plug}_${num}>$name";
					}else {push (@noconnect,"<plug_${plug}_${num}>$name");}
				}
 
 
				#my $connect_name=$self->soc_get_instance_name($connect_id);
				#my $color = get_color_hex_string($n);
				#$n = ($n<30)? $n+1 : 0;
 
				$graph_connect="$graph_connect $instance_id:plug_${plug}_${num} ->  $connect_id:socket_${connect_socket}_${connect_socket_num} [  dir=none]\n" if(defined $connect_socket);
 
			}
		}
		foreach my $p (sort {$a<=>$b} keys %plug_order){
					my $k=$plug_order{$p};
					#print "$instance_name   : $k=\$plug_order{$p}\n";
					$dotfile= ($first) ?   "$dotfile |{ ${k}": "$dotfile |${k}";
					$first=0;
 
				}
 
		foreach my $k (@noconnect){
			$dotfile= ($first) ?   "$dotfile |{ ${k}": "$dotfile |${k}";
			$first=0;
		}
 
		$dotfile=  "$dotfile} }\"];";
 
 
 
	}
	$dotfile="$dotfile\n\n$graph_connect";
	$dotfile="$dotfile\n\n}\n";
 
 
	return $dotfile;
 
 
}
 
 
 
 
 
sub show_tile_diagram {
	my $self= shift;
 
	my $table=def_table(20,20,FALSE);
 
	my $window=def_popwin_size(80,80,"Processing Tile functional block diagram",'percent');	
	my $scrolled_win = new Gtk2::ScrolledWindow (undef, undef);	
	$scrolled_win->set_policy( "automatic", "automatic" );
 
	$window->add ($table);
 
	my $plus = def_image_button('icons/plus.png',undef,TRUE);
	my $minues = def_image_button('icons/minus.png',undef,TRUE);
	my $unused = gen_check_box_object ($self,"tile_diagram","show_unused",0,undef,undef);
	my $save = def_image_button('icons/save.png',undef,TRUE);
	my $clk = gen_check_box_object ($self,"tile_diagram","show_clk",0,undef,undef);
	my $reset = gen_check_box_object ($self,"tile_diagram","show_reset",0,undef,undef);
	#my $save = def_image_button('icons/save.png',undef,TRUE);
 
	my $scale=$self->object_get_attribute("tile_diagram","scale");
	$scale= 1 if (!defined $scale);
 
 
 
 
	my $col=0;
	$table->attach ($plus ,  $col, $col+1,0,1,'shrink','shrink',2,2); $col++;
	$table->attach ($minues,  $col, $col+1,0,1,'shrink','shrink',2,2); $col++;
	$table->attach ($save,  $col, $col+1,0,1,'shrink','shrink',2,2); $col++;
	$table->attach (gen_label_in_left("     Remove unconnected Interfaces"),  $col,  $col+1,0,1,'shrink','shrink',2,2); $col++;
	$table->attach ($unused,  $col,  $col+1,0,1,'shrink','shrink',2,2); $col++;
	$table->attach (gen_label_in_left("     Remove Clk Interfaces"),  $col,  $col+1,0,1,'shrink','shrink',2,2); $col++;
	$table->attach ($clk,  $col,  $col+1,0,1,'shrink','shrink',2,2); $col++;
	$table->attach (gen_label_in_left("     Remove Reset Interfaces"),  $col,  $col+1,0,1,'shrink','shrink',2,2); $col++;
	$table->attach ($reset,  $col,  $col+1,0,1,'shrink','shrink',2,2); $col++;
	while ($col<20){
 
		my $tmp=gen_label_in_left('');
		$table->attach_defaults ($tmp, $col,  $col+1,0,1);$col++;
	}
 
	$plus  -> signal_connect("clicked" => sub{ 
		$scale*=1.1 if ($scale <10);
		$self->object_add_attribute("tile_diagram","scale", $scale );
		show_diagram ($self,$scrolled_win,$table,"tile_diagram");
	});	
	$minues  -> signal_connect("clicked" => sub{ 
		$scale*=.9  if ($scale >0.1); ;
		$self->object_add_attribute("tile_diagram","scale", $scale );
		show_diagram ($self,$scrolled_win,$table,"tile_diagram");
	});
	$save-> signal_connect("clicked" => sub{ 
			save_diagram_as ($self);
		});	
	$unused-> signal_connect("toggled" => sub{
		if(gen_diagram($self,'tile')){
			show_diagram ($self,$scrolled_win,$table,"tile_diagram");
		}
 
	});
	$clk-> signal_connect("toggled" => sub{
		if(gen_diagram($self,'tile')){
			show_diagram ($self,$scrolled_win,$table,"tile_diagram");
	}
 
	});
	$reset-> signal_connect("toggled" => sub{
		if(gen_diagram($self,'tile')){
			show_diagram ($self,$scrolled_win,$table,"tile_diagram");
		}
 
	});
 
	if(gen_diagram($self,'tile')){
		show_diagram ($self,$scrolled_win,$table,"tile_diagram");
	}
	$window->show_all();
}
 
 
sub show_topology_diagram {
	my $self= shift;
 
	my $table=def_table(20,20,FALSE);
 
	my $window=def_popwin_size(80,80,"NoC-based MCSoC topology block diagram",'percent');	
	my $scrolled_win = new Gtk2::ScrolledWindow (undef, undef);	
	$scrolled_win->set_policy( "automatic", "automatic" );
 
	$window->add ($table);
 
	my $plus = def_image_button('icons/plus.png',undef,TRUE);
	my $minues = def_image_button('icons/minus.png',undef,TRUE);
	my $save = def_image_button('icons/save.png',undef,TRUE);
 
	my $scale=$self->object_get_attribute("tile_diagram","scale");
	$scale= 1 if (!defined $scale);
 
 
 
 
	my $col=0;
	$table->attach ($plus ,  $col, $col+1,0,1,'shrink','shrink',2,2); $col++;
	$table->attach ($minues,  $col, $col+1,0,1,'shrink','shrink',2,2); $col++;
	$table->attach ($save,  $col, $col+1,0,1,'shrink','shrink',2,2); $col++;
	#$table->attach (gen_label_in_left("     Remove unconnected Interfaces"),  $col,  $col+1,0,1,'shrink','shrink',2,2); $col++;
	#$table->attach (gen_label_in_left("     Remove Clk Interfaces"),  $col,  $col+1,0,1,'shrink','shrink',2,2); $col++;
	#$table->attach (gen_label_in_left("     Remove Reset Interfaces"),  $col,  $col+1,0,1,'shrink','shrink',2,2); $col++;
	while ($col<20){		
		my $tmp=gen_label_in_left('');
		$table->attach_defaults ($tmp, $col,  $col+1,0,1);$col++;
	}
 
	$plus  -> signal_connect("clicked" => sub{ 
		$scale*=1.1 if ($scale <10);
		$self->object_add_attribute("topology_diagram","scale", $scale );
		show_diagram ($self,$scrolled_win,$table,"topology_diagram");
	});	
	$minues  -> signal_connect("clicked" => sub{ 
		$scale*=.9  if ($scale >0.1); ;
		$self->object_add_attribute("topology_diagram","scale", $scale );
		show_diagram ($self,$scrolled_win,$table,"topology_diagram");
	});
	$save-> signal_connect("clicked" => sub{ 
			save_diagram_as ($self);
		});	
 
 
	if(gen_diagram($self,'topology')){
		show_diagram ($self,$scrolled_win,$table,"topology_diagram");
	}
	$window->show_all();
}
 
 
 
 
 
sub gen_diagram {
	my ($self,$type)=@_;
 
	my $dotfile;
	$dotfile=   get_dot_file($self) if ($type eq 'tile');
	$dotfile=   get_topology_dot_file($self) if ($type eq 'topology');
	$dotfile=   generate_custom_topology_dot_file($self) if ($type eq 'custom_topology');	
	$dotfile=   generate_trace_dot_file($self) if ($type eq 'trace');	
	$dotfile=   generate_map_dot_file($self) if ($type eq 'map');										
 
	my $tmp_dir  = "$ENV{'PRONOC_WORK'}/tmp";
	#mkpath("$tmp_dir/",1,01777);
	#open(FILE,  ">$tmp_dir/diagram.txt") || die "Can not open: $!";
	#print FILE $dotfile;
	#close(FILE) || die "Error closing file: $!";
 
	#unlink "$tmp_dir/diagram.png";
 
	my $cmd;
	#$cmd=  "dot  $tmp_dir/diagram.txt | neato -n  -Tpng -o $tmp_dir/diagram.png" if ($type eq 'tile' || $type eq 'trace'  );
	#$cmd = "dot  $tmp_dir/diagram.txt -Kfdp -n -Tpng -o $tmp_dir/diagram.png" if ( $type eq 'map' || $type eq 'topology' || $type eq 'custom_topology' );	
 	$cmd=  " dot   | neato -n  -Tpng -o $tmp_dir/diagram.png" if ($type eq 'tile' || $type eq 'trace'  );
	$cmd = " dot   -Kfdp -n -Tpng -o $tmp_dir/diagram.png" if ( $type eq 'map' || $type eq 'topology' || $type eq 'custom_topology' );	
    $cmd = "echo \'$dotfile\' | $cmd";
 
	my ($stdout,$exit,$stderr)= run_cmd_in_back_ground_get_stdout ($cmd);
 
	if ( length( $stderr || '' ) !=0)  {
		message_dialog("$stderr\nHave you installed graphviz? If not run \n \t \"sudo apt-get install graphviz\" \n in terminal");
		return 0 unless (-f "$tmp_dir/diagram.png");
	}
		return  1;
}
 
 
 
sub show_diagram {
	my ($self,$scrolled_win,$table, $name)=@_;
 
	$scrolled_win->destroy;
	$scrolled_win = new Gtk2::ScrolledWindow (undef, undef);	
	$scrolled_win->set_policy( "automatic", "automatic" );
	$table->attach_defaults ($scrolled_win, 0, 20, 1, 20); #,'fill','shrink',2,2);		
	my $scale=$self->object_get_attribute($name,"scale");
	$scale= 1 if (!defined $scale);
	my $tmp_dir  = "$ENV{'PRONOC_WORK'}/tmp";
	my $diagram=open_image("$tmp_dir/diagram.png",70*$scale,70*$scale,'percent');
 
	$scrolled_win->add_with_viewport($diagram);
	$scrolled_win->show_all();	
 
 
 
 
}
 
 
sub save_diagram_as {
	my $self= shift;
 
	my $file;
	my $title ='Save as';
 
 
 
	my @extensions=('png');
	my $open_in=undef;
	my $dialog = Gtk2::FileChooserDialog->new(
            	'Save file', undef,
            	'save',
            	'gtk-cancel' => 'cancel',
            	'gtk-ok'     => 'ok',
        	);
	# if(defined $extension){
 
		foreach my $ext (@extensions){
			my $filter = Gtk2::FileFilter->new();
			$filter->set_name($ext);
			$filter->add_pattern("*.$ext");
			$dialog->add_filter ($filter);
		}
 
	# }
	  if(defined  $open_in){
		$dialog->set_current_folder ($open_in); 
		# print "$open_in\n";
 
	}
 
	if ( "ok" eq $dialog->run ) {
	    		$file = $dialog->get_filename;
			my $ext = $dialog->get_filter;
			$ext=$ext->get_name;
			my ($name,$path,$suffix) = fileparse("$file",qr"\..[^.]*$");
			$file = ($suffix eq ".$ext" )? $file : "$file.$ext";
 
			$self->object_add_attribute("graph_save","name",$file);
			$self->object_add_attribute("graph_save","extension",$ext);
			my $tmp  = "$ENV{'PRONOC_WORK'}/tmp/diagram.png";
			copy ($tmp,$file);
 
 
 
	      		 }
	     		$dialog->destroy;
}
 
 
 
sub generate_trace_dot_file{
	my $self=shift;
	my $dotfile=
"digraph G {
	graph [rankdir = LR , splines=polyline, overlap = false]; 
 
";
 
#add nodes
	#my @tasks=get_all_tasks($self);
	#foreach my $p (@tasks){
	#	$dotfile=$dotfile."\"$p\" [label=\"{   $p} }\"];\n"; 		
	#}	
 
#add connections
 
	my @traces= $self->get_trace_list();
	foreach my $p (@traces) {	
		my ($src,$dst, $Mbytes, $file_id, $file_name)=$self->get_trace($p);
		$dotfile=$dotfile."\"$src\" -> \"$dst\"  [label=\"$Mbytes\" ];\n";	
	}
 
	$dotfile=$dotfile."\n}\n";
	return $dotfile;
 
}
 
 
 
sub generate_map_dot_file{
	my $self=shift;
	my $dotfile=
"digraph G {
	graph [rankdir = LR ,splines=spline,  overlap = false]; 
	node[shape=record];
 
	";
 
 
 
#add nodes
	my $nx=$self->object_get_attribute('noc_param','T1');
	my $ny=$self->object_get_attribute('noc_param','T2');
	my $nc= $nx * $ny;
	my @tasks=get_all_tasks($self);
 
	my @mappedtasks;
 
 
	for(my $y=0; $y<$ny; $y++){ 
 
 
				for(my $x=0; $x<$nx; $x++){
					my $id=$y*$nx+$x;
					my $task=get_task_assigned_to_tile($self,$x,$y);
					push(@mappedtasks,$task) if (defined $task); 
 
					$task= "_" if (!defined $task); 
					my $n = ($ny==1)?   "tile(${x})" : "tile${id}(${x}_$y)" ;
					my $m = ($ny==1)?   "tile(${x})" : "tile(${x}_$y)" ;
					my $node = "\"$m\"";					
					my $label =   "\"<S$task> $n|<R$task> $task\"" ;
					my $xx=$x*1.5;
					my $yy=($ny-$y-1)*1.5;
 
					$dotfile=$dotfile."
$node\[
	label = $label
    pos = \"$xx,$yy!\"
];";					
 
 
 
				}
 
	}					
 
 
	$dotfile=$dotfile."\n\n";
 
	#add connections
	my @traces= $self->get_trace_list();
	foreach my $p (@traces){
		my ($src,$dst, $Mbytes, $file_id, $file_name)=$self->get_trace($p);
 
		my $src_tile= $self->object_get_attribute("MAP_TILE","$src");
		my $dst_tile= $self->object_get_attribute("MAP_TILE","$dst");
 
		next if ( $src_tile eq "-" ||  $dst_tile eq "-" ) ;
 
 
 
		$dotfile=$dotfile." \"$src_tile\" :  \"S$src\" ->  \"$dst_tile\" : \"R$dst\"  ;\n";
 
 
	}
 
 
 
 
	$dotfile=$dotfile."\n}\n";
	return $dotfile;
 
}
 
 
 
 
 
sub show_trace_diagram {
	my ($self,$type)=@_;
 
	my $table=def_table(20,20,FALSE);
 
	my $window=def_popwin_size(80,80,"Processing Tile functional block diagram",'percent');	
	my $scrolled_win = new Gtk2::ScrolledWindow (undef, undef);	
	$scrolled_win->set_policy( "automatic", "automatic" );
 
	$window->add ($table);
 
	my $plus = def_image_button('icons/plus.png',undef,TRUE);
	my $minues = def_image_button('icons/minus.png',undef,TRUE);
	my $save = def_image_button('icons/save.png',undef,TRUE);
 
 
	my $scale=$self->object_get_attribute("${type}_diagram","scale");
	$scale= 1 if (!defined $scale);
 
 
 
 
	my $col=0;
	$table->attach ($plus ,  $col, $col+1,0,1,'shrink','shrink',2,2); $col++;
	$table->attach ($minues,  $col, $col+1,0,1,'shrink','shrink',2,2); $col++;
	$table->attach ($save,  $col, $col+1,0,1,'shrink','shrink',2,2); $col++;
 
	while ($col<20){
 
 
 
		my $tmp=gen_label_in_left('');
		$table->attach_defaults ($tmp, $col,  $col+1,0,1);$col++;
	}
 
	$plus  -> signal_connect("clicked" => sub{ 
		$scale*=1.1 if ($scale <10);
		$self->object_add_attribute("${type}_diagram","scale", $scale );
		show_diagram ($self,$scrolled_win,$table, "${type}_diagram");
	});	
	$minues  -> signal_connect("clicked" => sub{ 
		$scale*=.9  if ($scale >0.1); ;
		$self->object_add_attribute("${type}_diagram","scale", $scale );
		show_diagram ($self,$scrolled_win,$table, "${type}_diagram");
	});
	$save-> signal_connect("clicked" => sub{ 
			save_diagram_as ($self);
		});	
 
 
 
 
	if(gen_diagram($self,$type)){
		show_diagram ($self,$scrolled_win,$table, "${type}_diagram");
	}
	$window->show_all();
 
 
 
 
}	
 
 
 
 
 
 
sub node_connection{
	my ($sn,$sx,$sy,$sp,$dn,$dx,$dy,$dp)=@_;
	my $spp = (defined $sp) ? ":\"p$sp\"" : " ";
	my $dpp = (defined $dp) ? ":\"p$dp\"" : " ";
	my $sname = (defined $sy) ? "\"$sn${sx}_${sy}\"" : "\"$sn${sx}\"";
	my $dname = (defined $dy) ? "\"$dn${dx}_${dy}\"" : "\"$dn${dx}\"";
 
	my $t= "$sname  $spp -> $dname  $dpp [  dir=none];\n"; 
	return $t;	
}
 
sub node_connection2{
	my ($sn,$sx,$sp,$dn,$dx,$dy,$dp)=@_;
	my $spp = (defined $sp) ? ":\"p$sp\"" : " ";
	my $dpp = (defined $dp) ? ":\"p$dp\"" : " ";
	my $sname =   "\"$sn${sx}\"";
	my $dname =  "\"$dn${dx}\"";
 
	my $t= "$sname  $spp -> $dname  $dpp [  dir=none];\n"; 
	return $t;	
}
 
 
sub generate_mesh_dot_file_old{
	my $self=shift;
	my $dotfile=
"digraph G {
	graph [rankdir = LR , splines = true, overlap = true]; 
 
 
 
	node[shape=record];
 
	";
 
#five_port_router [
#	label="{ |2| } | {3|R0|1} | { |4|0}"
#	shape=record
#	color=blue
#	style=filled
#	fillcolor=blue
#];	
 
#add nodes
	my $nx=$self->object_get_attribute('noc_param','T1');
	my $ny=$self->object_get_attribute('noc_param','T2');
	my $nc= $nx * $ny;
	my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
	my $btrace= ($topology eq '"TORUS"' || $topology eq '"RING"');
	my $oned = ($topology eq '"RING"' || $topology eq '"LINE"');	
	for(my $y=0; $y<$ny; $y++){ 		
				for(my $x=0; $x<$nx; $x++){
					my $id=$y*$nx+$x;
 
 
					my $n =    "R${id}" ;
					my $node = "${x}_$y";					
					my $label =  ($oned)?
					 "\{ |<p2>| \} | \{<p3>2|$n|<p1>1\} | \{ |<p4>|<p0>0\}"
					:  "\{ |<p2>2| \} | \{<p3>3|$n|<p1>1\} | \{ |<p4>4|<p0>0\}";
					my $xx=$x*2.5;
					my $yy=($ny-$y-1)*2.5+1;
					my $tx=$xx+0.75;
					my $ty=$yy-1;
					$dotfile=$dotfile."
\"R$node\"\[
	label = \"$label\"
    pos = \"$xx,$yy!\"
    shape=record
	color=blue
	style=filled
	fillcolor=blue
];
 
T$node\[
	label = \"Tile_$id($node)\"
    pos = \"$tx,$ty!\"
    shape=record
	color=orange
	style=filled
	fillcolor=orange
];";					
 
;									
		}
 
	}					
 
 
	$dotfile=$dotfile."\n\n";
 
	#add connections
	for(my $y=0; $y<$ny; $y++){ 		
		for(my $x=0; $x<$nx; $x++){
			 $dotfile=$dotfile.node_connection('R',$x,$y,1,'R',($x+1),$y,3) if($x <$nx-1);	
			 $dotfile=$dotfile.node_connection('R',$x,$y,1,'R',0,$y,3) if($x == ($nx-1) && $btrace);
			 $dotfile=$dotfile.node_connection('R',$x,$y,2,'R',$x,($y-1),4)if($y>0) ; 
             $dotfile=$dotfile.node_connection('R',$x,$y,2,'R',$x,($ny-1),4)   if($y ==0 && $btrace && !$oned);
             $dotfile=$dotfile.node_connection('R',$x,$y,0,'T',$x,$y);
 
 
 
	}}
 
 
 
 
	$dotfile=$dotfile."\n}\n";
	return $dotfile;
 
}
 
 
##################################
#
##################################
 
 
sub generate_mesh_dot_file{
	my $self=shift;
	my $dotfile=
"digraph G {
	graph [rankdir = RL , splines = true, overlap = true]; 
 
 
	node[shape=record];
 
	";
 
#five_port_router [
#	label="{ |2| } | {3|R0|1} | { |4|0}"
#	shape=record
#	color=blue
#	style=filled
#	fillcolor=blue
#];	
 
#add nodes
	my $nx=$self->object_get_attribute('noc_param','T1');
	my $ny=$self->object_get_attribute('noc_param','T2');
	my $nz=$self->object_get_attribute('noc_param','T3');
	my $NE = $nx*$ny*$nz;
	my $NR = $nx*$ny; 	
	my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
 
 
	my $btrace= ($topology eq '"TORUS"' || $topology eq '"RING"');
	my $oned = ($topology eq '"RING"' || $topology eq '"LINE"');
 
	#generate endpoints
	for(my $y=0; $y<$ny; $y++){ 		
				for(my $x=0; $x<$nx; $x++){
					for(my $z=0; $z<$nz; $z++){
						my $id=($y*$nx+$x)*$nz+$z;						
						my $offsetx = ($z==0 || $z==3) ? 1.05 : -1.05; 
						my $offsety = ($z==0 || $z==1) ? -0.85 : +0.85; 
						my $tx=$x*3+$offsetx;
						my $ty=($ny-$y-1)*2.5+1+$offsety;
 
$dotfile=$dotfile."
 
T$id\[
	label = \"T${id}\"
    pos = \"$tx,$ty!\"
    shape=record
	color=orange
	style=filled
	fillcolor=orange
];";								
 
	}}}
 
#generate routers	
	for(my $y=0; $y<$ny; $y++){ 		
				for(my $x=0; $x<$nx; $x++){
					my $e0 = '0';
					my $e1 = ($nz>1)? ( ($oned)? '3':'5') : ' ';
					my $e2 = ($nz>2)? ( ($oned)? '4':'6') : ' ';
					my $e3 = ($nz>3)? ( ($oned)? '5':'7') : ' ';
 
					my $id=$y*$nx+$x;									
					my $n = "R${id}";								
					my $label =  ($oned)?
					 "\{<p7>$e2 |<p2> |<p8>$e3 \} | \{<p3>2|$n|<p1>1\} | \{<p6>$e1 |<p4> |<p5>$e0\}"
					:"\{<p7>$e2 |<p2>2|<p8>$e3 \} | \{<p3>3|$n|<p1>1\} | \{<p6>$e1 |<p4>4|<p5>$e0\}";
					my $xx=$x*3;
					my $yy=($ny-$y-1)*2.5+1;
 
 
 
$dotfile=$dotfile."
\"$n\"\[
	label = \"$label\"
    pos = \"$xx,$yy!\"
    shape=record
	color=blue
	style=filled
	fillcolor=blue
];
 
";					
 
				}}							
 
 
	$dotfile=$dotfile."\n\n";
 
	#add connections
	for(my $y=0; $y<$ny; $y++){ 		
		for(my $x=0; $x<$nx; $x++){
 
			 $dotfile=$dotfile.node_connection('R',get_router_num($self,$x,$y),undef,1,'R',get_router_num($self,($x+1),$y),undef,3) if($x <$nx-1);	
			 $dotfile=$dotfile.node_connection('R',get_router_num($self,$x,$y),undef,1,'R',get_router_num($self,0,$y),undef,3) if($x == ($nx-1) && $btrace);
			 $dotfile=$dotfile.node_connection('R',get_router_num($self,$x,$y),undef,2,'R',get_router_num($self,$x,($y-1)),undef,4)if($y>0) ; 
             $dotfile=$dotfile.node_connection('R',get_router_num($self,$x,$y),undef,2,'R',get_router_num($self,$x,($ny-1)),undef,4) if($y ==0 && $btrace && !$oned);
          #   $dotfile=$dotfile.node_connection('R',$x,$y,0,'T',$x,$y);               
    }}
 
	for(my $id=0; $id<$NE; $id++){ 
		my $rid=int($id/$nz);
		my $p =  $id%$nz+5;
		$dotfile=$dotfile.node_connection('R',$rid,undef,$p,'T',$id,undef);               
 
	}
 
	$dotfile=$dotfile."\n}\n";
	return $dotfile;
 
 
 
}
 
 
 
sub generate_fattree_dot_file{
	my $self=shift;
 
	my $dotfile=
"digraph G {
	graph [rankdir = LR , splines = true, overlap = true]; 	
	node[shape=record];	
	";
 
#add nodes
	my $k=$self->object_get_attribute('noc_param','T1');
	my $nl=$self->object_get_attribute('noc_param','T2');
	my @bp;
	my @hp;
	for(my $p=0; $p<$k; $p++) {push (@bp,"<p$p>$p");}
	for(my $p=$k; $p<2*$k; $p++) {push (@hp,"<p$p>$p");}
	my $bp= join("|",@bp);
	my $hp= join("|",@hp);
	my $NC= powi( $k,$nl  ); #total endpoints
	my $NL= $NC/$k ; #number of nodes in  each layer 
 
 
#add endpoints
for(my $i=0; $i<$NC; $i++){
	my $x=$i%$k;
	my $y=int($i/$k); 		
 
$dotfile=$dotfile."T$i\[
	label = \"T$i\"
    pos = \"$i,0!\"
    shape=house
    margin=0
	color=orange
	style=filled
	fillcolor=orange
];
";
	}
 
	#add roots
	for(my $pos=0; $pos<$NL; $pos++){ 
		my $x=($k)*$pos+($k/2)-0.5;	
		my $y=	1.5*($nl-1)+1;	
		my $r=$pos;
		my $lable = "\{R$r\}|\{$bp\}";
	$dotfile=$dotfile."
\"R$r\"\[
	label=\"$lable\"
    pos = \"$x,$y!\"
    shape=record
	color=blue
	style=filled
	fillcolor=blue
];	
";
	}
 
	#add leaves
	for(my $l=1; $l<$nl; $l++){ 
	for(my $pos=0; $pos<$NL; $pos++){ 
	my $x=($k)*$pos+($k/2)-0.5;	
	my $y=	1.5*($nl-$l-1)+1;	
	my $r=$NL*$l+$pos;
	my $lable = "\{$hp\}|\{R$r\}|\{$bp\}";
	 $dotfile=$dotfile."
\"R$r\"\[
	label=\"$lable\"
    pos = \"$x,$y!\"
    shape=record
	color=blue
	style=filled
	fillcolor=blue
];	
";
		}
	}	
 
 
 
	#connect all down input channels
	my $n=$nl;
	my $nPos = powi( $k, $n-1);
	my $chan_per_direction = ($k * powi( $k , $n-1 )); #up or down
	my $chan_per_level = 2*($k * powi( $k , $n-1 )); #up+down
 
	for (my $level = 0; $level<$n-1; $level++){
	    #input channel are numbered interleavely, the interleaev depends on level
	    my $routers_per_neighborhood = powi($k,$n-1-($level)); 
	    my $routers_per_branch = powi($k,$n-1-($level+1)); 
	    my $level_offset = $routers_per_neighborhood*$k;
	    for ( my $pos = 0; $pos < $nPos; ++$pos ) {
			my $neighborhood = int($pos/$routers_per_neighborhood);
			my $neighborhood_pos = $pos % $routers_per_neighborhood;
			for ( my $port = 0; $port < $k; ++$port ) {
				my $link = 
					(($level+1)*$chan_per_level - $chan_per_direction)  #which levellevel
		  			+$neighborhood*$level_offset   #region in level
		  			+$port*$routers_per_branch*$k  #sub region in region
		 			+($neighborhood_pos)%$routers_per_branch*$k  #router in subregion
		 			+($neighborhood_pos)/$routers_per_branch; #port on router
 
	#int link = (level*chan_per_level - chan_per_direction) + pos*k + port ;
				my $connect_l= int(($link+$chan_per_direction)/$chan_per_level);
				my $tmp=(($link+$chan_per_direction) % $chan_per_level);
				my $connect_pos= int($tmp/$k);
				my $connect_port= ($tmp%$k)+$k;
				my $id1=$NL*$level+$pos;
				my $connect_id=$NL*$connect_l+$connect_pos;
				$dotfile=$dotfile.node_connection('R',$id1,undef,$port,'R',$connect_id,undef,$connect_port);	
			}
	    }
	}
 
	#add endpoints connection
	for(my $i=0; $i<$NC; $i++){ 
		my $r= $NL*($nl-1)+int($i/$k);
		 $dotfile=$dotfile.node_connection('T',$i,undef,undef,'R',$r,undef,$i%($k));	
 
	}
	$dotfile=$dotfile."\n}\n";
	return $dotfile;
}
 
 
 
 
sub generate_tree_dot_file{
	my $self=shift;
 
	my $dotfile=
"digraph G {
	graph [rankdir = LR , splines = true, overlap = true]; 	
	node[shape=record];	
	";
 
 
	my $k=$self->object_get_attribute('noc_param','T1');
	my $nl=$self->object_get_attribute('noc_param','T2');
	#generate routres port interface
	my @bp;
	my @hp;
	for(my $p=0; $p<$k; $p++) {
		push (@bp,"<n$p>") if(($k%2)==0 && $p==$k/2);#if k is odd number add one empty space in the middle
		push (@bp,"<p$p>$p");
 
	}
	for(my $p=$k; $p<2*$k; $p++) {
		if($p==$k+int(($k-1)/2)){
			push (@hp,"<n$p>") if(($k%2)==0);#if k is odd number add one empty space in the middle
			push (@hp,"<p$k>$k");
		}else{
			push (@hp,"<n$p>"); 
		}
	}	
	my $bp= join("|",@bp);
	my $hp= join("|",@hp);
	my ($NE,$NR)=get_topology_info($self);
 
 
 
	#add endpoints
	for(my $i=0; $i<$NE; $i++){
		$dotfile=$dotfile."T$i\[
	label = \"T$i\"
    pos = \"$i,0!\"
    shape=house
    margin=0
	color=orange
	style=filled
	fillcolor=orange
];
";
	}
 
	#add roots
	my $lable = "\{R0\}|\{$bp\}";
	my $x=(($NE-1)/2);
	my $y=	1.5*($nl-1)+1;
	$dotfile=$dotfile."
\"R0\"\[
	label=\"$lable\"
    pos = \"$x,$y!\"
    shape=record
	color=blue
	style=filled
	fillcolor=blue
];	
";
 
	#add leaves
	my $t=1;
 
	for(my $l=$nl-1; $l>0; $l--){ 
		my $NL = powi($k,$l);
		$t*=$k;
		for(my $pos=0; $pos<$NL; $pos++){ 			
			my $x= 	$t*$pos + ($t-1)/2 ;
			my $y=	1.5*($nl-$l)-.5;
			my $r=sum_powi($k,$l)+$pos;
	my $lable = "\{$hp\}|\{R$r\}|\{$bp\}";
	 $dotfile=$dotfile."
\"R$r\"\[
	label=\"$lable\"
    pos = \"$x,$y!\"
    shape=record
	color=blue
	style=filled
	fillcolor=blue
];	
";
		}
	}	
 
	#add leave connections
	for(my $l=$nl-1; $l>0; $l--){ 
		my $NL = powi($k,$l);
		for(my $pos=0; $pos<$NL; $pos++){ 
			my $id1=sum_powi($k,$l)+$pos;
			my $id2=sum_powi($k,$l-1)+int($pos/$k);
			$dotfile=$dotfile.node_connection('R',$id1,undef,$k,'R',$id2,undef,$pos % $k);	
		}
	}
 
	#add endpoints connection
	for(my $i=0; $i<$NE; $i++){ 
		 my $r= sum_powi($k,$nl-1)+int($i/$k);
		 $dotfile=$dotfile.node_connection('T',$i,undef,undef,'R',$r,undef,$i%($k));	
 
	}
 
 
 
	$dotfile=$dotfile."\n}\n";
	return $dotfile;
}
 
 
sub get_topology_dot_file{
	my $self=shift;
	my $topology=$self->object_get_attribute('noc_param','TOPOLOGY');
	return generate_mesh_dot_file ($self) if($topology eq '"RING"' || $topology eq '"LINE"' || $topology eq '"MESH"' || $topology eq '"TORUS"' );
	return generate_fattree_dot_file ($self) if($topology eq '"FATTREE"');
	return generate_tree_dot_file($self);
}
 
 
 
 
 
 
 
 
 
 
 
 
return 1;
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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