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/] [emulate_ram_gen.pl] - Rev 25

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

#!/usr/bin/perl -w
use strict;
use warnings;
use List::Util 'shuffle';
require "widget.pl"; 				
 
 
use constant RESET_CMD 		=> " $ENV{'PRONOC_WORK'}/toolchain/bin/jtag_main -n 127 -d \"I:1,D:1:1,I:0\" ";
use constant UNRESET_CMD 	=> " $ENV{'PRONOC_WORK'}/toolchain/bin/jtag_main -n 127 -d \"I:1,D:1:0,I:0\" ";
use constant READ_DONE_CMD 	=> " $ENV{'PRONOC_WORK'}/toolchain/bin/jtag_main -n 127 -d \"I:2,R:1:0,I:0\" ";
use constant UPDATE_WB_ADDR  	=> 0x7;
use constant UPDATE_WB_WR_DATA  => 0x6;
use constant UPDATE_WB_RD_DATA  => 0x5;
use constant RD_WR_STATUS	=> 0x4;
use constant PROBE_ST 		=> 0x2;
use constant SOURCE_ST		=> 0x1;
use constant BYPAS_ST 		=> 0x0;
 
 
sub get_data{					
 
	my ( $x, $y, $ref, $traffic, $ratio_in,$num, $line_num, $dest)=@_;
	my %noc_info= %$ref;
	my $C=$noc_info{C};
	my $xn=$noc_info{NX};
	my $yn=$noc_info{NY};				
	my $MAX_PCK_NUM   = $noc_info{MAX_PCK_NUM};
	my $MAX_SIM_CLKs  = $noc_info{MAX_SIM_CLKs};
	my $MAX_PCK_SIZ   = $noc_info{MAX_PCK_SIZ};
 
 
	my $Xw          =   log2($xn);   # number of node in x axis
        my $Yw          =   log2($yn);   # number of node in y axis
        my $Cw          =  ($C > 1)? log2($C): 1;
        #$Fw          =   2+V+Fpay,
        my $RATIOw      =   log2(100),
        my $PCK_CNTw    =   log2($MAX_PCK_NUM+1),
        my $CLK_CNTw    =   log2($MAX_SIM_CLKs+1),
        my $PCK_SIZw    =   log2($MAX_PCK_SIZ+1);
 
	my $Dw=$PCK_CNTw+ $RATIOw + $PCK_SIZw + $Xw + $Yw + $Cw +1;  				
	my $val=0;
	my $q=0;
	my $i=0;
	my $last_adr=($traffic eq 'random' && $line_num<($xn* $yn)-2 )? 0 : 1; 
	#print "my $last_adr=($traffic eq 'random' && $line_num<($xn* $yn)-2 )? 0 : 1; \n";
	my @fileds=get_ram_line($C, $x, $y, $xn, $yn, $traffic,$ratio_in,$line_num,$dest,$last_adr);
	my ($pck_num_to_send_,$ratio_in_,$pck_size_,$dest_x_,$dest_y_,$pck_class_in_,$last_adr_)=@fileds;
	my @sizes= ($PCK_CNTw, $RATIOw , $PCK_SIZw , $Xw , $Yw , $Cw ,1);
 
	foreach my $p (@fileds){
		$val= $val << $q;	
		$val= $val + $p;
		$i++;
		$q=$sizes[$i] if(defined $sizes[$i]);
	} 
 
	my $sum = 0;
 
	foreach my $num (@sizes){
			$sum = $sum + $num;
	}
	my $result = sprintf("%010x", $val);
	#print"$result\n";	
	return ($result,$last_adr,$Dw);
 
 
 
 
 
#ram_do= {pck_num_to_send_,ratio_in_,pck_size_,dest_x_,dest_y_,pck_class_in_,last_adr_}; 
 
 
}
 
sub get_ram_line{
	my ($C, $x, $y, $xn, $yn, $traffic,$ratio_in,$line_num,$dest,$last_adr_)=@_;
 
	my $pck_num_to_send_=2000000;
	my $pck_size_=4;
	my $pck_class_in_=0;
 
 
	my $xw=log2($xn);
	my $yw=log2($yn);
 
	#print "$traffic\n";
	my $dest_x_;
	my $dest_y_;
 
	if( $traffic eq "transposed 1"){
		 $dest_x_= $xn-$y-1;
		 $dest_y_= $yn-$x-1;
 
	} elsif( $traffic eq "transposed 2"){
 
		$dest_x_  = $y;
		$dest_y_  = $x;
	} elsif( $traffic eq "bit reverse"){
		my $joint_addr= ($x << log2($xn))+$y;
		my $reverse_addr=0;
		my $pos=0;
		for(my $i=0; $i<($xw+$yw); $i++){#reverse the address
			 $pos= ((($xw+$yw)-1)-$i);
			 $reverse_addr|= (($joint_addr >> $pos) & 0x01) << $i;
                   # reverse_addr[i]  = joint_addr [((Xw+Yw)-1)-i];
		}
		$dest_x_  = $reverse_addr>>$yw;
		$dest_y_  = $reverse_addr&(0xFF>> (8-$yw));
 
	 } elsif( $traffic  eq "bit complement") {
 
		 $dest_x_   = (~$x) &(0xFF>> (8-$xw));
		 $dest_y_   = (~$y) &(0xFF>> (8-$yw));
 
 
    }  elsif( $traffic eq "tornado") {
 
		#[(x+(k/2-1)) mod k, (y+(k/2-1)) mod k],
		 $dest_x_   = (($x + (($xn/2)-1))%$xn);
		 $dest_y_   = (($y + (($yn/2)-1))%$yn);
 
	} elsif( $traffic eq "random") {
		 #my $num=($y * $xn) +	$x;
		 $pck_num_to_send_=2;
		 $dest_x_   = $dest % $xn;
		 $dest_y_   = $dest  / $xn;
 
 
 
	}else{#off
		 print "***********************************$traffic is not defined*******************************************\n";
		 $dest_x_= $x;
		 $dest_y_= $y;
 
	}
 
	#print"  ($pck_num_to_send_,$ratio_in,$pck_size_,$dest_x_,$dest_y_,$pck_class_in_,$last_adr_);\n";
	return  ($pck_num_to_send_,$ratio_in,$pck_size_,$dest_x_,$dest_y_,$pck_class_in_,$last_adr_);
 
 
}
 
 
 
 
 
sub help {
		print 
"	usage: ./ram_gen X  Y TRAFFIC
		X:  number of node in X direction 2<x<=16
		Y:  number of node in Y direction 2<y<=16
		TRAFFIC : select one of the following traffic patterns :
			tornado,
			transposed 1,
			transposed 2,
			random, 
 
";	
 
}	
 
 
 
 
 
 
sub gen_ram{
	my ($data,$mem_width)=get_data(@_);
	my $result = sprintf("%8x", $data);
 
 
 
	return $result;
 
 
}	
 
sub random_dest_gen {
	my $n=shift;
	my @c=(0..$n-1);
	my @o;	
	for (my $i=0; $i<$n; $i++){
		my @l= shuffle @c;
		@l=remove_scolar_from_array(\@l,$i);
		$o[$i]=\@l;
 
	}
	return \@o;
 
}
 
sub run_cmd_update_info {
	my ($cmd,$info)=@_;
	my ($stdout,$exit,$stderr)=run_cmd_in_back_ground_get_stdout($cmd);
		if($exit){
			add_info($info, "$stdout\n") if(defined $stdout);
			add_info($info, "$stderr\n") if(defined $stderr);
 
		}
	return $exit;
}
 
 
 
 
 
 
 
 
sub programe_pck_gens{
	my ($ref, $traffic,$ratio_in,$info)= @_;
	my %noc_info= %$ref;
	my $C=$noc_info{C};
	my $xn=$noc_info{NX};
	my $yn=$noc_info{NY};
    #print( "@_\n" );
	my @traffics=("tornado", "transposed 1", "transposed 2", "bit reverse", "bit complement","random", "hot spot" );
	my $xc=$xn * $yn;
	my @randoms=@{random_dest_gen($xc)};
 
	if ( !defined $xn || $xn!~ /\s*\d+\b/ ){ add_info($info,"programe_pck_gens:invalid X value\n"); help(); return 0;}
	if ( !defined $yn || $yn!~ /\s*\d+\b/ ){ add_info($info,"programe_pck_gens:invalid Y value\n"); help(); return 0;}
	if ( !grep( /^$traffic$/, @traffics ) ){add_info($info,"programe_pck_gens:$traffic is an invalid Traffic name\n"); help(); return 0;}
	if ( $xn <2 || $xn >16 ){ add_info($info,"programe_pck_gens:invalid X value: ($xn). should be between 2 and 16 \n"); help(); return 0;}
	if ( $yn <2 || $yn >16 ){ add_info($info,"programe_pck_gens:invalid Y value:($yn). should be between 2 and 16 \n"); help(); return 0;}
 
	#reset the FPGA board	
	#run_cmd_in_back_ground("quartus_stp -t ./lib/tcl/mem.tcl reset");
	return if(run_cmd_update_info(RESET_CMD,$info));
 
 
my $argument='';
my $argument2='';
 
for (my $x=0; $x<$xn; $x=$x+1){
	for (my $y=0; $y<$yn; $y=$y+1){
		my $num=($y * $xn) +	$x;
		$num= ($num<=9)? "0$num" : $num;
		#add_info($info, "programe M$num\n");
		my $line=0;
		my ($ram_val,$end,$Dw);
		my $repeat=($traffic eq 'random')? "0x2710" : "0x0"; # 10000 : 0;
 
		$argument=undef;
		do{
			($ram_val,$end,$Dw)=get_data($x, $y, $ref, $traffic,$ratio_in,$num,$line,@{$randoms[$num]}[$line]);
			if(!defined $argument ) { #first row
				$argument="-n $num -d \"I:".UPDATE_WB_ADDR.",D:$Dw:0,I:".UPDATE_WB_WR_DATA.",D:$Dw:0x$ram_val"; 
			}
			#$argument="$argument M$num $line $ram_val";
			else {
				$argument=$argument.",D:$Dw:0x$ram_val";
 
			}
			#$argument="$argument M$num $line $ram_val";
			$line++;
			#print "\$line=$line\n";
		} while($end == 0);
		$argument=$argument.",I:0\"";
		#program the memory
		#print "$cmd\n";
		my $cmd="$ENV{'PRONOC_WORK'}/toolchain/bin/jtag_main $argument";
 		return if(run_cmd_update_info ($cmd,$info));
		my $source_index=$num+128;
 
		$cmd= "$ENV{'PRONOC_WORK'}/toolchain/bin/jtag_main -n $source_index -d \"I:".SOURCE_ST.",D:100:$repeat,I:0\"";
		return if(run_cmd_update_info ($cmd,$info));		
		#$argument2="$argument2 P$num $repeat";
 
 
 
		#my $file="./RAM/M$num.mif\n";
		#unless(open FILE, '>'.$file) { die "\nUnable to create $file\n";}
 
		# Write data to the file.
		#my $ram_content= gen_ram(0, $x, $y, $xn, $yn, $traffic,"M$num");
		#print FILE $ram_content;
		# close the file.
		#close FILE;
 
	}	
}
#print "quartus_stp -t ./lib/tcl/mem.tcl $argument\n";
# ($result,$exit)=run_cmd_in_back_ground_get_stdout("quartus_stp -t ./lib/tcl/mem.tcl $argument");
#add_info($info,"update packet generators\n");
#print "($result,$exit)\n";
#return 0 if ($exit);
#print "quartus_stp -t ./lib/tcl/source.tcl $argument2\n";
#($result,$exit)=run_cmd_in_back_ground_get_stdout("quartus_stp -t ./lib/tcl/source.tcl $argument2");
#print "($result,$exit)\n";
#return 0 if ($exit);
 
# deassert the reset
 
	return if(run_cmd_update_info (UNRESET_CMD,$info));
#run_cmd_in_back_ground("quartus_stp -t ./lib/tcl/mem.tcl unreset");
#add_info($info,"$r\n");
 
return 1;
 
}
 
 
 
sub read_pack_gen{ 
	my ($ref,$info)= @_;
	my %noc_info= %$ref;
	my $xn=$noc_info{NX};
	my $yn=$noc_info{NY};
#wait for done 
    add_info($info, "wait for done\n");
    my $done=0;
    my $counter=0;
    while ($done ==0){
 
		#my ($result,$exit) = run_cmd_in_back_ground_get_stdout("quartus_stp -t ./lib/tcl/read.tcl done");
		my ($result,$exit) = run_cmd_in_back_ground_get_stdout(READ_DONE_CMD);
		my @q =split  (/###read data#/,$result);
		#print "\$result=$result\n";
 
 
		$done=($q[1] eq "0x0")? 0 : 1;
		#print "\$q[1]=$q[1] done=$done\n";
		usleep(9000);
		$counter++;
		if($counter == 15){ # 
			add_info($info,"Done is not asserted. I reset the board and try again\n");
			return if(run_cmd_update_info (RESET_CMD,$info));
			#run_cmd_in_back_ground("quartus_stp -t ./lib/tcl/mem.tcl reset");
			usleep(300000);
			return if(run_cmd_update_info (UNRESET_CMD,$info));
			#run_cmd_in_back_ground("quartus_stp -t ./lib/tcl/mem.tcl unreset");			
		}
		if($counter>30){
			  #something is wrong
			add_info($info,"Done is not asserted again. I  am going to ignore this test case"); 
			return undef;
		}
	}
 
	add_info($info,"Done is asserted\n");
	#my $i=0;
	my %results;
	my $sum_of_latency=0;
	my $sum_of_pck=0;
	for (my $x=0; $x<$xn; $x=$x+1){
		for (my $y=0; $y<$yn; $y=$y+1){
			my $num=($y * $xn) +	$x; 
			my $source_index=$num+128;
			my $cmd= "$ENV{'PRONOC_WORK'}/toolchain/bin/jtag_main -n $source_index -d \"I:".PROBE_ST.",R:100:0,I:0\"";
			my ($result,$exit) = run_cmd_in_back_ground_get_stdout($cmd);
			my @q =split  (/###read data#/,$result);
 
 
 
		my $d=$q[1];
		#print "num=$num:    ddddd=$d\n";	
		my $s= substr $d,2;
		#print "dddddddd=$s\n";	
		my $latency =substr $s, 0,9;  
		my $got_pck= substr $s, -16, 8;  
		my $sent_pck= substr $s, -8;  
		#print "$latency, $got_pck, $sent_pck\n";	
 
 
		$results{$num}{latency}=hex($latency);
		$results{$num}{got_pck}=hex($got_pck);
		$results{$num}{sent_pck}=hex($sent_pck);
		$sum_of_latency+=hex($latency);
		$sum_of_pck+=hex($got_pck);
		#$i=$i+2;
	}}
 
	foreach my $p (sort keys %results){
 
 
		#print "$p  : \n latency: $results{$p}{latency}\n";
		#print " got_pck : $results{$p}{got_pck}\n";
		#print "sent_pck:$results{$p}{sent_pck}\n\n";
 
	} 
	my $avg= ($sum_of_pck>0)? $sum_of_latency/$sum_of_pck : 0;
	return sprintf("%.1f", $avg);
}	
 
 

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.