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
Compare Revisions
- This comparison shows the changes necessary to convert path
/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk/mpsoc/perl_gui/lib/perl
- from Rev 26 to Rev 28
- ↔ Reverse comparison
Rev 26 → Rev 28
/emulate_ram_gen.pl
2,13 → 2,19
use strict; |
use warnings; |
use List::Util 'shuffle'; |
require "widget.pl"; |
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 SIM_RAM_GEN => 1; |
|
use constant JTAG_RAM_INDEX => 128; |
use constant JTAG_DONE_RESET_INDEX => 127; |
use constant RESET_NOC => " $ENV{'PRONOC_WORK'}/toolchain/bin/jtag_main -n ".JTAG_DONE_RESET_INDEX." -d \"I:1,D:2:1,I:0\" "; |
use constant UNRESET_NOC => " $ENV{'PRONOC_WORK'}/toolchain/bin/jtag_main -n ".JTAG_DONE_RESET_INDEX." -d \"I:1,D:2:0,I:0\" "; |
|
use constant READ_DONE_CMD => " $ENV{'PRONOC_WORK'}/toolchain/bin/jtag_main -n ".JTAG_DONE_RESET_INDEX." -d \"I:2,R:2: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; |
15,87 → 21,87
use constant PROBE_ST => 0x2; |
use constant SOURCE_ST => 0x1; |
use constant BYPAS_ST => 0x0; |
|
use constant RAM_BIN_FILE => "$ENV{'PRONOC_WORK'}/emulate/emulate_ram.bin"; |
use constant RAM_SIM_FILE => "$ENV{'PRONOC_WORK'}/emulate/ram"; |
|
|
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); |
|
|
|
|
sub reset_cmd { |
my ($ctrl_reset, $noc_reset)=@_; |
my $reset_vector= (($ctrl_reset & 0x1) << 1) + ($noc_reset & 0x1); |
my $cmd = " $ENV{'PRONOC_WORK'}/toolchain/bin/jtag_main -n ".JTAG_DONE_RESET_INDEX." -d \"I:1,D:2:$reset_vector,I:0\" "; |
#print "$cmd\n"; |
return $cmd; |
|
#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); |
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, |
|
"; |
|
#print "$traffic\n"; |
my $dest_x_; |
my $dest_y_; |
} |
|
|
|
|
|
|
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); |
|
} |
#print "\n$cmd \n $stdout"; |
return $exit; |
} |
|
|
sub synthetic_destination{ |
my($traffic,$x,$y,$xn,$yn,$line_num,$rnd)=@_; |
my $dest_x; |
my $dest_y; |
my $xw = log2($xn); |
my $yw = log2($yn); |
|
if( $traffic eq "transposed 1"){ |
$dest_x_= $xn-$y-1; |
$dest_y_= $yn-$x-1; |
$dest_x= $xn-$y-1; |
$dest_y= $yn-$x-1; |
|
} elsif( $traffic eq "transposed 2"){ |
|
$dest_x_ = $y; |
$dest_y_ = $x; |
$dest_x = $y; |
$dest_y = $x; |
} elsif( $traffic eq "bit reverse"){ |
my $joint_addr= ($x << log2($xn))+$y; |
my $reverse_addr=0; |
105,40 → 111,39
$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)); |
|
$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)); |
$dest_x = (~$x) &(0xFF>> (8-$xw)); |
$dest_y = (~$y) &(0xFF>> (8-$yw)); |
|
|
} elsif( $traffic eq "tornado") { |
}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") { |
$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; |
|
my $xc=$xn * $yn; |
my @randoms=@{$rnd}; |
my $num=($y * $xn) + $x; |
my $dest = @{$randoms[$num]}[$line_num-1]; |
#print "$num:$dest, "; # \@{ \$randoms\[$num\]\}\[$line_num\]"; |
$dest_x = $dest % $xn; |
$dest_y = $dest / $xn; |
|
|
}else{#off |
} else{#off |
print "***********************************$traffic is not defined*******************************************\n"; |
$dest_x_= $x; |
$dest_y_= $y; |
$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_); |
return ($dest_x,$dest_y); |
|
|
} |
|
|
145,155 → 150,165
|
|
|
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_synthetic_traffic_ram_line{ |
my ($emulate, $x, $y, $sample_num,$ratio ,$line_num,$rnd)=@_; |
|
|
} |
|
my $ref=$emulate->object_get_attribute("sample$sample_num","noc_info"); |
my %noc_info= %$ref; |
my $xn=$noc_info{NX}; |
my $yn=$noc_info{NY}; |
my $traffic=$emulate->object_get_attribute("sample$sample_num","traffic"); |
|
|
my $pck_num_to_send=$emulate->object_get_attribute("sample$sample_num","PCK_NUM_LIMIT"); |
my $pck_size=$emulate->object_get_attribute("sample$sample_num","PCK_SIZE"); |
my $pck_class_in=0; |
|
|
if($line_num==0){ #first ram line shows how many times the ram content must be read |
#In random traffic each node sends 2 packets to other NC-1 nodes for (pck_num_to_send/2) times |
my $ram_cnt= ($traffic eq 'random')? ($pck_num_to_send/(2*(($xn * $yn)-1)))+1:0 ; |
return (0,$ram_cnt); |
|
} |
return (0,0) if($line_num>1 && $traffic ne 'random'); |
return (0,0) if( $line_num>= $xn * $yn); |
|
|
|
#assign {pck_num_to_send_in,ratio_in, pck_size_in,dest_x_in, dest_y_in,pck_class_in, last_adr_in}= q_a; |
my $last_adr = ( $traffic ne 'random') ? 1 : |
($line_num ==($xn * $yn)-1)? 1 :0; |
|
my ($dest_x, $dest_y)=synthetic_destination($traffic,$x,$y,$xn,$yn,$line_num,$rnd); |
|
my $vs= ( $traffic eq 'random')? 2 : $pck_num_to_send; |
$vs=($vs << 2 )+ ($ratio >>5) ; |
|
sub gen_ram{ |
my ($data,$mem_width)=get_data(@_); |
my $result = sprintf("%8x", $data); |
|
my $vl= ($ratio %32); |
$vl=($vl << PCK_SIZw )+$pck_size; |
$vl=($vl << MAXXw )+$dest_x; |
$vl=($vl << MAXYw )+$dest_y; |
$vl=($vl << MAXCw )+$pck_class_in; |
$vl=($vl << 1 )+$last_adr; |
|
return ($vs,$vl); |
|
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); |
|
|
|
|
|
sub generate_synthetic_traffic_ram{ |
my ($emulate,$x,$y,$sample_num,$ratio , $file,$rnd,$num)=@_; |
my $RAM_size=MAX_PATTERN+4; |
|
|
|
my $line_num; |
my $line_value; |
my $ram; |
if(SIM_RAM_GEN){ |
my $ext= sprintf("%02u.txt",$num); |
open( $ram, '>', RAM_SIM_FILE.$ext) || die "Can not create: \">lib/emulate/emulate_ram.bin\" $!"; |
} |
for ($line_num= 0; $line_num<MAX_PATTERN+4; $line_num++ ) { |
my ($value_s,$value_l)=gen_synthetic_traffic_ram_line ($emulate, $x, $y, $sample_num, $ratio ,$line_num,$rnd); |
|
|
#printf ("\n%08x\t",$value_s); |
#printf ("%08x\t",$value_l); |
if(SIM_RAM_GEN){ |
my $s=sprintf("%08X%08x",$value_s,$value_l); |
print $ram "$s\n"; |
} |
return $exit; |
} |
print_32_bit( $file, $value_s); # most significent 32 bit |
print_32_bit( $file, $value_l); # list significent 32 bit |
|
} |
|
|
if(SIM_RAM_GEN){ |
close($ram); |
} |
#print "\n"; |
|
#last ram three rows reserved for reading data from emulator |
|
} |
|
|
sub print_32_bit { |
my ($file,$v)=@_; |
for (my $i= 24; $i >=0 ; $i-=8) { |
my $byte= ($v >> $i ) & 0xFF; |
print $file pack('C*',$byte); |
#printf ("%02x\t",$byte); |
} |
} |
|
|
sub programe_pck_gens{ |
my ($ref, $traffic,$ratio_in,$info)= @_; |
|
sub generate_emulator_ram { |
my ($emulate, $sample_num,$ratio_in,$info)=@_; |
my $ref=$emulate->object_get_attribute("sample$sample_num","noc_info"); |
my %noc_info= %$ref; |
my $C=$noc_info{C}; |
my $xn=$noc_info{NX}; |
my $yn=$noc_info{NY}; |
#print( "@_\n" ); |
my $xc=$xn*$yn; |
my $rnd=random_dest_gen($xc); # generate a matrix of sudo random number |
my $traffic=$emulate->object_get_attribute("sample$sample_num","traffic"); |
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)); |
#open file pointer |
#open(my $file, RAM_BIN_FILE) || die "Can not create: \">lib/emulate/emulate_ram.bin\" $!"; |
open(my $file, '>', RAM_BIN_FILE) || die "Can not create: \">lib/emulate/emulate_ram.bin\" $!"; |
|
|
my $argument=''; |
my $argument2=''; |
|
for (my $x=0; $x<$xn; $x=$x+1){ |
#generate each node ram data |
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"; |
for (my $x=0; $x<$xn; $x=$x+1){ |
my $num=($y * $xn) + $x; |
generate_synthetic_traffic_ram($emulate,$x,$y,$sample_num,$ratio_in, $file,$rnd,$num); |
|
} |
#$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"; |
} |
} |
close($file); |
return 1; |
|
} |
|
|
#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; |
sub programe_pck_gens{ |
my ($emulate, $sample_num,$ratio_in,$info)= @_; |
|
} |
} |
#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); |
return 0 if(!generate_emulator_ram($emulate, $sample_num,$ratio_in,$info)); |
|
# deassert the reset |
#reset the FPGA board |
#run_cmd_in_back_ground("quartus_stp -t ./lib/tcl/mem.tcl reset"); |
return 0 if(run_cmd_update_info(reset_cmd(1,1),$info)); #reset both noc and jtag |
return 0 if(run_cmd_update_info(reset_cmd(0,1),$info)); #enable jtag keep noc in reset |
#programe packet generators rams |
my $cmd= "$ENV{'PRONOC_WORK'}/toolchain/bin/jtag_main -n ".JTAG_RAM_INDEX." -w 8 -i ".RAM_BIN_FILE." -c"; |
#my ($result,$exit) = run_cmd_in_back_ground_get_stdout($cmd); |
|
return if(run_cmd_update_info (UNRESET_CMD,$info)); |
return 0 if(run_cmd_update_info ($cmd,$info)); |
#print $result; |
|
return 0 if(run_cmd_update_info(reset_cmd(1,1),$info)); #reset both |
return 0 if(run_cmd_update_info(reset_cmd(0,0),$info)); #enable both |
#run_cmd_in_back_ground("quartus_stp -t ./lib/tcl/mem.tcl unreset"); |
#add_info($info,"$r\n"); |
|
302,9 → 317,26
} |
|
|
sub read_jtag_memory{ |
my $addr=shift; |
my $cmd= "$ENV{'PRONOC_WORK'}/toolchain/bin/jtag_main -n ".JTAG_RAM_INDEX." -w 8 -d \"I:".UPDATE_WB_ADDR.",D:64:$addr,I:5,R:64:$addr,I:0\""; |
#print "$cmd\n"; |
my ($result,$exit) = run_cmd_in_back_ground_get_stdout($cmd); |
my @q =split (/###read data#/,$result); |
my $d=$q[1]; |
my $s= substr $d,2; |
#print "$s\n"; |
return hex($s); |
} |
|
|
|
|
|
|
sub read_pack_gen{ |
my ($ref,$info)= @_; |
my ($emulate,$sample_num,$info)= @_; |
my $ref=$emulate->object_get_attribute("sample$sample_num","noc_info"); |
my %noc_info= %$ref; |
my $xn=$noc_info{NX}; |
my $yn=$noc_info{NY}; |
313,9 → 345,13
my $done=0; |
my $counter=0; |
while ($done ==0){ |
|
usleep(300000); |
#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); |
if($exit != 0 ){ |
add_info($info,$result); |
return undef; |
} |
my @q =split (/###read data#/,$result); |
#print "\$result=$result\n"; |
|
322,14 → 358,14
|
$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)); |
return if(run_cmd_update_info (reset_cmd(1,1),$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)); |
return if(run_cmd_update_info (reset_cmd(0,0),$info)); |
#run_cmd_in_back_ground("quartus_stp -t ./lib/tcl/mem.tcl unreset"); |
} |
if($counter>30){ |
340,35 → 376,27
} |
|
add_info($info,"Done is asserted\n"); |
#print" 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){ |
for (my $y=0; $y<$yn; $y=$y+1){ |
for (my $x=0; $x<$xn; $x=$x+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 $read_addr=($num * RAM_SIZE) + MAX_PATTERN +1; |
|
my $sent_pck_addr= sprintf ("%X",$read_addr); |
my $got_pck_addr = sprintf ("%X",$read_addr+1); |
my $latency_addr = sprintf ("%X",$read_addr+2); |
|
$results{$num}{sent_pck}=read_jtag_memory($sent_pck_addr); |
$results{$num}{got_pck}=read_jtag_memory($got_pck_addr); |
$results{$num}{latency}=read_jtag_memory($latency_addr); |
print "read pckgen $num\n"; |
|
|
|
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); |
$sum_of_latency+=$results{$num}{latency}; |
$sum_of_pck+=$results{$num}{got_pck}; |
#$i=$i+2; |
}} |
|
381,6 → 409,7
|
} |
my $avg= ($sum_of_pck>0)? $sum_of_latency/$sum_of_pck : 0; |
|
return sprintf("%.1f", $avg); |
} |
|
/emulator.pl
13,6 → 13,8
|
use File::Basename; |
use File::Path qw/make_path/; |
use File::Copy; |
use File::Find::Rule; |
|
require "widget.pl"; |
require "emulate_ram_gen.pl"; |
23,9 → 25,28
use List::MoreUtils qw(uniq); |
|
|
# hardware parameters taken from noc_emulator.v |
use constant PCK_CNTw =>30; # packet counter width in bits (results in maximum of 2^30 = 1 G packets) |
use constant PCK_SIZw =>14; # packet size width in bits (results in maximum packet size of 2^14 = 16 K flit) |
use constant MAXXw =>4; # maximum nodes in x dimention is 2^MAXXw equal to 16 nodes in x dimention |
use constant MAXYw =>4; # 16 nodes in y dimention : hence max emulator size is 16X16 |
use constant MAXCw =>4; # 16 message classes |
use constant RATIOw =>7; # log2(100) |
use constant MAX_PATTERN => 124; |
use constant RAM_SIZE => (MAX_PATTERN+4); |
|
|
#use constant MAX_PCK_NUM => (2**PCK_CNTw)-1; |
use constant MAX_PCK_NUM => (2**PCK_CNTw)-1; |
use constant MAX_PCK_SIZ => (2**PCK_SIZw)-1; |
use constant MAX_SIM_CLKs=> 100000000; # simulation end at if clock counter reach this number |
|
use constant EMULATION_RTLS => "/mpsoc/src_emulate/rtl/noc_emulator.v , /mpsoc/src_peripheral/jtag/jtag_wb/ , /mpsoc/src_peripheral/ram/generic_ram.v, /mpsoc/src_noc/"; |
|
|
|
|
|
sub gen_chart { |
my $emulate=shift; |
my($width,$hight)=max_win_size(); |
53,6 → 74,10
|
); |
|
|
|
|
|
if(defined $sample_num){ |
my @color; |
my $min_y=200; |
70,7 → 95,7
}#for |
my @x1; |
@x1 = uniq(sort {$a<=>$b} @x) if (scalar @x); |
|
#print "\@x1=@x1\n"; |
if (scalar @x1){ |
$results[0]=\@x1; |
for (my $i=1;$i<=$sample_num; $i++) { |
77,6 → 102,7
my $j=0; |
my $ref=$emulate->object_get_attribute ("sample$i","result"); |
if(defined $ref){ |
#print "$i\n"; |
my %line=%$ref; |
foreach my $k (@x1){ |
$results[$i][$j]=$line{$k}; |
83,7 → 109,11
$min_y= $line{$k} if (defined $line{$k} && $line{$k}!=0 && $min_y > $line{$k}); |
$j++; |
}#$k |
}#if |
}#if |
else { |
$results[$i][$j]=undef; |
|
} |
}#$i |
|
}#if |
98,7 → 128,7
$graphs_info->{$d->{param_name}}= $d->{default_val} if(!defined $graphs_info->{$d->{param_name}}); |
} |
|
#print "gggggggggggggggg=".$graphs_info->{X_Title}; |
|
|
$graph->set ( |
x_label => $graphs_info->{X_Title}, |
485,51 → 515,72
|
|
sub get_noc_configuration{ |
my ($emulate,$n) =@_; |
my($width,$hight)=max_win_size(); |
my $win=def_popwin_size($width/2.5,$hight*.8,"NoC configuration setting"); |
my $table=def_table(10,2,FALSE); |
my $entry=gen_entry(); |
my $row=0; |
my @l; |
my @u; |
my ($emulate,$n) =@_; |
my($width,$hight)=max_win_size(); |
my $win=def_popwin_size($width/2.5,$hight*.8,"NoC configuration setting"); |
my $table=def_table(10,2,FALSE); |
my $row=0; |
|
my $traffics="tornado,transposed 1,transposed 2,bit reverse,bit complement,random"; #TODO hot spot |
|
$l[$row]=gen_label_help("Select the SRAM Object File (sof) for this NoC configration.","SoF file:"); |
my $dir = Cwd::getcwd(); |
my $traffics="tornado,transposed 1,transposed 2,bit reverse,bit complement,random"; #TODO hot spot |
|
my $dir = Cwd::getcwd(); |
my $open_in = abs_path("$ENV{PRONOC_WORK}/emulate/sof"); |
attach_widget_to_table ($table,$row,gen_label_in_left("SoF file:"),gen_button_message ("Select the SRAM Object File (sof) for this NoC configration.","icons/help.png"), get_file_name_object ($emulate,"sample$n","sof_file",'sof',$open_in)); $row++; |
|
|
|
my @siminfo = ( |
{ label=>'Configuration name:', param_name=>'line_name', type=>'Entry', default_val=>"NoC$n", content=>undef, info=>"NoC configration name. This name will be shown in load-latency graph for this configuration", param_parent=>"sample$n", ref_delay=> undef}, |
|
{ label=>"Traffic name", param_name=>'traffic', type=>'Combo-box', default_val=>'random', content=>$traffics, info=>"Select traffic pattern", param_parent=>"sample$n", ref_delay=>undef}, |
|
{ label=>"Packet size in flit:", param_name=>'PCK_SIZE', type=>'Spin-button', default_val=>4, content=>"2,".MAX_PCK_SIZ.",1", info=>undef, param_parent=>"sample$n", ref_delay=>undef}, |
|
{ label=>"Packet number limit:", param_name=>'PCK_NUM_LIMIT', type=>'Spin-button', default_val=>1000000, content=>"2,".MAX_PCK_NUM.",1", info=>"Each node stops sending packets when it reaches packet number limit or simulation clock number limit", param_parent=>"sample$n", ref_delay=>undef}, |
|
{ label=>"Emulation clocks limit:", param_name=>'SIM_CLOCK_LIMIT', type=>'Spin-button', default_val=>MAX_SIM_CLKs, content=>"2,".MAX_SIM_CLKs.",1", info=>"Each node stops sending packets when it reaches packet number limit or simulation clock number limit", param_parent=>"sample$n", ref_delay=>undef}, |
|
|
); |
foreach my $d ( @siminfo) { |
$row=noc_param_widget ($emulate, $d->{label}, $d->{param_name}, $d->{default_val}, $d->{type}, $d->{content}, $d->{info}, $table,$row,1, $d->{param_parent}, $d->{ref_delay}); |
} |
|
|
|
|
my $l= "Define injection ratios. You can define individual ratios seprating by comma (\',\') or define a range of injection ratios with \$min:\$max:\$step format. |
As an example defining 2,3,4:10:2 will result in (2,3,4,6,8,10) injection ratios." ; |
my $u=get_injection_ratios ($emulate,"sample$n","ratios"); |
|
my $open_in = abs_path("$ENV{PRONOC_WORK}/emulate/sof"); |
$u[$row]= get_file_name_object ($emulate,"sample$n","sof_file",'sof',$open_in); |
$row++; |
$l[$row]=gen_label_help("NoC configration name. This name will be shown in load-latency graph for this configuration","Configuration name:"); |
$u[$row]=gen_entry_object ($emulate,"sample$n","line_name","NoC$n"); |
$row++; |
$l[$row]=gen_label_help("Traffic name","Traffic name:"); |
$u[$row]=gen_combobox_object ($emulate,"sample$n","traffic",$traffics,"random"); |
$row++; |
$l[$row]=gen_label_help("Define injection ratios. You can define individual ratios seprating by comma (\',\') or define a range of injection ratios with \$min:\$max:\$step format. |
As an example definnig 2,3,4:10:2 will results in (2,3,4,6,8,10) injection ratios.","Injection ratios:"); |
$u[$row]=get_injection_ratios ($emulate,"sample$n","ratios"); |
$row++; |
my $i=0; |
for ( $i=0; $i<12; $i++){ |
if($i<$row){ |
$table->attach ($l[$i] , 0, 1, $i, $i+1,'fill','shrink',2,2); |
$table->attach ($u[$i] , 1, 2, $i, $i+1,'fill','shrink',2,2); |
}else{ |
my $l=gen_label_in_left(" "); |
$table->attach_defaults ($l , 0, 1, $i, $i+1); |
} |
} |
attach_widget_to_table ($table,$row,gen_label_in_left("Injection ratios:"),gen_button_message ($l,"icons/help.png") , $u); $row++; |
|
my $scrolled_win = new Gtk2::ScrolledWindow (undef, undef); |
$scrolled_win->set_policy( "automatic", "automatic" ); |
$scrolled_win->add_with_viewport($table); |
|
|
my $ok = def_image_button('icons/select.png','OK'); |
my $mtable = def_table(10, 1, TRUE); |
|
$mtable->attach_defaults($scrolled_win,0,1,0,9); |
$mtable-> attach ($ok , 0, 1, 9, 10,'expand','shrink',2,2); |
|
$win->add ($mtable); |
$win->show_all(); |
|
|
|
|
|
|
|
|
|
|
$table->attach ($ok , 1, 2, $i, $i+1,'expand','shrink',2,2); |
|
|
|
$ok->signal_connect("clicked"=> sub{ |
#check if sof file has been selected |
my $s=$emulate->object_get_attribute("sample$n","sof_file"); |
547,9 → 598,14
} |
} |
}); |
|
|
$win->add($table); |
$win->show_all; |
|
|
|
|
|
|
|
|
} |
710,7 → 766,14
$emulate->object_add_attribute ("sample$i","status","failed"); |
$status=0; |
}else { #add info |
my $p= do $sof_info ; |
my $pp= do $sof_info ; |
|
my $p=$pp->{'noc_param'}; |
|
|
|
|
|
$status=0 if $@; |
message_dialog("Error reading: $@") if $@; |
if ($status==1){ |
878,6 → 941,7
add_info($info, "jtagconfig could not find any USB blaster cable: $stdout \n"); |
$emulate->object_add_attribute('status',undef,'programer_failed'); |
set_gui_status($emulate,"ref",2); |
#/***/ |
return; |
}else{ |
add_info($info, "find $usb_blaster\n"); |
896,7 → 960,12
|
|
my $cmd = "$Quartus_bin/quartus_pgm -c \"$usb_blaster\" -m jtag -o \"p;$sof\""; |
|
#my $output = `$cmd 2>&1 1>/dev/null`; # either with backticks |
|
|
|
#/***/ |
my ($stdout,$exit)=run_cmd_in_back_ground_get_stdout("$cmd"); |
if($exit){#programming FPGA board has failed |
$emulate->object_add_attribute('status',undef,'programer_failed'); |
904,27 → 973,29
$emulate->object_add_attribute ("sample$i","status","failed"); |
set_gui_status($emulate,"ref",2); |
next; |
} |
} |
#print "$stdout\n"; |
|
# read noc configuration |
my $traffic = $emulate->object_get_attribute("sample$i","traffic"); |
|
|
my $ref=$emulate->object_get_attribute("sample$i","noc_info"); |
|
|
|
foreach my $ratio_in (@ratios){ |
|
foreach my $ratio_in (@ratios){ |
|
add_info($info, "Configure packet generators for injection ratio of $ratio_in \% \n"); |
next if(!programe_pck_gens($ref,$traffic,$ratio_in,$info)); |
|
my $avg=read_pack_gen($ref,$info); |
my $ref=$emulate->object_get_attribute ("sample$i","result"); |
my %results; |
%results= %{$ref} if(defined $ref); |
#push(@results,$avg); |
$results{$ratio_in}=$avg; |
$emulate->object_add_attribute ("sample$i","result",\%results); |
set_gui_status($emulate,"ref",2); |
add_info($info, "Configure packet generators for injection ratio of $ratio_in \% \n"); |
next if(!programe_pck_gens($emulate,$i,$ratio_in,$info)); |
|
my $avg=read_pack_gen($emulate,$i,$info); |
next if (!defined $avg); |
my $ref=$emulate->object_get_attribute ("sample$i","result"); |
my %results; |
%results= %{$ref} if(defined $ref); |
#push(@results,$avg); |
$results{$ratio_in}=$avg; |
$emulate->object_add_attribute ("sample$i","result",\%results); |
set_gui_status($emulate,"ref",2); |
|
} |
$emulate->object_add_attribute ("sample$i","status","done"); |
978,70 → 1049,40
|
|
sub get_noc_setting_gui { |
my ($emulate,$info_text)=@_; |
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); |
my $row=noc_config ($emulate,$table); |
my ($emulate,$info_text)=@_; |
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); |
my $row=noc_config ($emulate,$table); |
|
my($label,$param,$default,$content,$type,$info); |
my @dirs = grep {-d} glob("../src_emulate/fpga/*"); |
my $fpgas; |
foreach my $dir (@dirs) { |
my ($name,$path,$suffix) = fileparse("$dir",qr"\..[^.]*$"); |
$default=$name; |
$fpgas= (defined $fpgas)? "$fpgas,$name" : "$name"; |
my($label,$param,$default,$content,$type,$info); |
my @dirs = grep {-d} glob("../src_emulate/fpga/*"); |
my $fpgas; |
foreach my $dir (@dirs) { |
my ($name,$path,$suffix) = fileparse("$dir",qr"\..[^.]*$"); |
$default=$name; |
$fpgas= (defined $fpgas)? "$fpgas,$name" : "$name"; |
|
} |
|
|
} |
|
|
|
|
$label='simulation param'; |
$content=$fpgas; |
$type='Entry'; |
$info=" I will add later"; |
|
my %simparam; |
$simparam{'MAX_PCK_NUM'}=2560000; |
$simparam{'MAX_SIM_CLKs'}=1000000; |
$simparam{'MAX_PCK_SIZ'}=10; |
$simparam{'TIMSTMP_FIFO_NUM'}=16; |
|
foreach my $p (sort keys %simparam){ |
# print "\$p, \$simparam{\$p}=$p, $simparam{$p}\n"; |
$row=noc_param_widget ($emulate,$label,$p, $simparam{$p},$type,$content,$info, $table,$row,0,'noc_param'); |
} |
|
|
|
my @fpgainfo = ( |
{ label=>'FPGA board', param_name=>'FPGA_BOARD', type=>'Combo-box', default_val=>undef, content=>$fpgas, info=>undef, param_parent=>'fpga_param', ref_delay=> undef}, |
{ label=>'Save as:', param_name=>'SAVE_NAME', type=>"Entry", default_val=>'emulate1', content=>undef, info=>undef, param_parent=>'fpga_param', ref_delay=>undef}, |
{ label=>"Project directory", param_name=>"SOF_DIR", type=>"DIR_path", default_val=>"$ENV{'PRONOC_WORK'}/emulate", content=>undef, info=>"Define the working directory for generating .sof file", param_parent=>'fpga_param',ref_delay=>undef }, |
|
); |
foreach my $d (@fpgainfo) { |
$row=noc_param_widget ($emulate, $d->{label}, $d->{param_name}, $d->{default_val}, $d->{type}, $d->{content}, $d->{info}, $table,$row,1, $d->{param_parent}, $d->{ref_delay}); |
} |
|
|
|
#FPGA NAME |
$label='FPGA board'; |
$param='FPGA_BOARD'; |
$content=$fpgas; |
$type='Combo-box'; |
$info=" I will add later"; |
$row=noc_param_widget ($emulate,$label,$param, $default,$type,$content,$info, $table,$row,1,'fpga_param'); |
|
|
#save as |
$label='Save as:'; |
$param='SAVE_NAME'; |
$default='emulate1'; |
$content=undef; |
$type="Entry"; |
$info="define generated sof file's name"; |
$row=noc_param_widget ($emulate,$label,$param, $default,$type,$content,$info, $table,$row,1,'fpga_param'); |
|
|
#Project_dir |
$label='Project directory'; |
$param='SOF_DIR'; |
$default="../../mpsoc_work/emulate"; |
$content=undef; |
$type="DIR_path"; |
$info="Define the working directory for generating .sof file"; |
$row=noc_param_widget ($emulate,$label,$param, $default,$type,$content,$info, $table,$row,1,'fpga_param'); |
|
|
|
|
1072,6 → 1113,7
my $fpga_board= $emulate->object_get_attribute ('fpga_param',"FPGA_BOARD"); |
#create work directory |
my $dir_name=$emulate->object_get_attribute ('fpga_param',"SOF_DIR"); |
$dir_name="$dir_name/$fpga_board"; |
my $save_name=$emulate->object_get_attribute ('fpga_param',"SAVE_NAME"); |
$save_name=$fpga_board if (!defined $save_name); |
$dir_name= "$dir_name/$save_name"; |
1080,57 → 1122,89
|
|
#copy all noc source codes |
my @files =("mpsoc/src_noc/*", "mpsoc/src_emulate/rtl/*","mpsoc/src_peripheral/jtag/jtag_wb/*"); |
|
my @files = split(/\s*,\s*/,EMULATION_RTLS); |
|
my $dir = Cwd::getcwd(); |
my $project_dir = abs_path("$dir/../../"); |
my ($stdout,$exit)=run_cmd_in_back_ground_get_stdout("mkdir -p $dir_name/src/" ); |
foreach my $f (@files){ |
($stdout,$exit) =run_cmd_in_back_ground_get_stdout("cp -Rf \"$project_dir\"/$f \"$dir_name/src/\"" ); |
if($exit != 0 ){ print "$stdout\n"; message_dialog($stdout); return;} |
} |
copy_file_and_folders(\@files,$project_dir,"$dir_name/src/"); |
|
foreach my $f(@files){ |
my $n="$project_dir/$f"; |
if (!(-f "$n") && !(-f "$f" ) && !(-d "$n") && !(-d "$f" ) ){ |
add_info ($info, " WARNING: file/folder \"$f\" ($n) dose not exists \n"); |
|
} |
|
|
} |
|
|
|
|
|
#copy fpga board files |
|
($stdout,$exit)=run_cmd_in_back_ground_get_stdout("cp -Rf \"$project_dir/mpsoc/src_emulate/fpga/$fpga_board\"/* \"$dir_name/\""); |
if($exit != 0 ){ print "$stdout\n"; message_dialog($stdout); return;} |
|
#generate emulator_top.v file |
|
open(FILE, ">$dir_name/emulator_top.v") || die "Can not open: $!"; |
print FILE gen_emulate_top_v($emulate); |
#generate parameters for emulator_top.v file |
my ($localparam, $pass_param)=gen_noc_param_v( $emulate); |
open(FILE, ">$dir_name/src/noc_parameters.v") || die "Can not open: $!"; |
print FILE $localparam; |
close(FILE) || die "Error closing file: $!"; |
open(FILE, ">$dir_name/src/pass_parameters.v") || die "Can not open: $!"; |
print FILE $pass_param; |
close(FILE) || die "Error closing file: $!"; |
|
|
#compile the code |
my $Quartus_bin= $ENV{QUARTUS_BIN}; |
add_info($info, "Start Quartus compilation\n $stdout\n"); |
($stdout,$exit)=run_cmd_in_back_ground_get_stdout( " cd \"$dir_name/\" |
xterm -e $Quartus_bin/quartus_map --64bit $fpga_board --read_settings_files=on |
xterm -e $Quartus_bin/quartus_fit --64bit $fpga_board --read_settings_files=on |
xterm -e $Quartus_bin/quartus_asm --64bit $fpga_board --read_settings_files=on |
xterm -e $Quartus_bin/quartus_sta --64bit $fpga_board |
"); |
if($exit != 0){ |
print "Quartus compilation failed !\n"; |
add_info($info, "Quartus compilation failed !\n $stdout\n"); |
return; |
my @compilation_command =("cd \"$dir_name/\" \n xterm -e $Quartus_bin/quartus_map --64bit $fpga_board --read_settings_files=on ", |
"cd \"$dir_name/\" \n xterm -e $Quartus_bin/quartus_fit --64bit $fpga_board --read_settings_files=on ", |
"cd \"$dir_name/\" \n xterm -e $Quartus_bin/quartus_asm --64bit $fpga_board --read_settings_files=on ", |
"cd \"$dir_name/\" \n xterm -e $Quartus_bin/quartus_sta --64bit $fpga_board "); |
|
|
|
|
|
foreach my $cmd (@compilation_command){ |
($stdout,$exit)=run_cmd_in_back_ground_get_stdout( $cmd); |
if($exit != 0){ |
print "Quartus compilation failed !\n"; |
add_info($info, "Quartus compilation failed !\n$cmd\n $stdout\n"); |
return; |
} |
|
} else { |
} |
|
|
|
#save sof file |
my $sofdir="$ENV{PRONOC_WORK}/emulate/sof"; |
mkpath("$sofdir/",1,01777); |
open(FILE, ">$sofdir/$save_name.inf") || die "Can not open: $!"; |
mkpath("$sofdir/$fpga_board/",1,01777); |
open(FILE, ">$sofdir/$fpga_board/$save_name.inf") || die "Can not open: $!"; |
print FILE perl_file_header("$save_name.inf"); |
print FILE Data::Dumper->Dump([$emulate->{'noc_param'}],["NoCparam"]); |
my %pp; |
$pp{'noc_param'}= $emulate->{'noc_param'}; |
$pp{'fpga_param'}= $emulate->{'fpga_param'}; |
print FILE Data::Dumper->Dump([\%pp],["emulate_info"]); |
close(FILE) || die "Error closing file: $!"; |
($stdout,$exit)=run_cmd_in_back_ground_get_stdout("cp $dir_name/output_files/$fpga_board.sof $sofdir/$save_name.sof"); |
if($exit != 0 ){ print "$stdout\n"; message_dialog($stdout); return;} |
message_dialog("sof file has been generated successfully"); return; |
} |
|
|
#find $dir_name -name \*.sof -exec cp '{}' $sofdir/$fpga_board/$save_name.sof" |
@files = File::Find::Rule->file() |
->name( '*.sof' ) |
->in( "$dir_name" ); |
copy($files[0],"$sofdir/$fpga_board/$save_name.sof") or do { |
my $err= "Error copy($files[0] , $sofdir/$fpga_board/$save_name.sof"; |
print "$err\n"; |
message_dialog($err); |
return; |
}; |
message_dialog("sof file has been generated successfully"); |
|
|
|
/hdr_file_gen.pl
22,7 → 22,7
my @plugs= $soc->soc_get_all_plugs_of_an_instance($id); |
my %params= $soc->soc_get_module_param($id); |
#add two extra variable the instance name and base addresses |
my $core_id= $soc->object_add_attribute('global_param','CORE_ID'); |
my $core_id= $soc->object_get_attribute('global_param','CORE_ID'); |
$params{CORE_ID}=(defined $core_id)? $core_id: 0; |
$params{IP}=$inst; |
$params{CORE}=$id; |
64,7 → 64,7
|
|
sub generate_header_file{ |
my ($soc,$project_dir,$target_dir,$dir)= @_; |
my ($soc,$project_dir,$sw_path,$dir)= @_; |
my $soc_name=$soc->object_get_attribute('soc_name'); |
$soc_name = uc($soc_name); |
if(!defined $soc_name){$soc_name='soc'}; |
133,7 → 133,7
open(FILE, ">lib/verilog/tmp") || die "Can not open: $!"; |
print FILE $content; |
close(FILE) || die "Error closing file: $!"; |
move ("$dir/lib/verilog/tmp","$target_dir/sw/$rename"); |
move ("$dir/lib/verilog/tmp","$sw_path/$rename"); |
|
|
} |
148,7 → 148,7
open(FILE, ">lib/verilog/$name.h") || die "Can not open: $!"; |
print FILE $system_h; |
close(FILE) || die "Error closing file: $!"; |
move ("$dir/lib/verilog/$name.h","$target_dir/sw/"); |
move ("$dir/lib/verilog/$name.h","$sw_path/"); |
|
|
|
/mpsoc_gen.pl
11,7 → 11,6
use POSIX 'strtol'; |
|
use File::Path; |
use File::Find; |
use File::Copy; |
|
use Cwd 'abs_path'; |
27,6 → 26,7
require "mpsoc_verilog_gen.pl"; |
require "hdr_file_gen.pl"; |
require "readme_gen.pl"; |
require "soc_gen.pl"; |
|
sub get_pos{ |
my ($item,@list)=@_; |
51,16 → 51,13
$mpsoc->object_add_attribute_order($attribut1,$param); |
$value=$default; |
} |
if( ! defined $ref_delay){ |
$ref_delay=($type eq "Entry") ? 10 : 1; |
|
} |
|
if ($type eq "Entry"){ |
$widget=gen_entry($value); |
$widget-> signal_connect("changed" => sub{ |
my $new_param_value=$widget->get_text(); |
$mpsoc->object_add_attribute($attribut1,$param,$new_param_value); |
set_gui_status($mpsoc,"ref",$ref_delay); |
set_gui_status($mpsoc,"ref",$ref_delay) if(defined $ref_delay); |
|
|
}); |
80,7 → 77,7
$widget-> signal_connect("changed" => sub{ |
my $new_param_value=$widget->get_active_text(); |
$mpsoc->object_add_attribute($attribut1,$param,$new_param_value); |
set_gui_status($mpsoc,"ref",$ref_delay); |
set_gui_status($mpsoc,"ref",$ref_delay) if(defined $ref_delay); |
|
|
}); |
97,7 → 94,7
$widget-> signal_connect("value_changed" => sub{ |
my $new_param_value=$widget->get_value_as_int(); |
$mpsoc->object_add_attribute($attribut1,$param,$new_param_value); |
set_gui_status($mpsoc,"ref",$ref_delay); |
set_gui_status($mpsoc,"ref",$ref_delay) if(defined $ref_delay); |
|
}); |
|
140,7 → 137,7
} |
$mpsoc->object_add_attribute($attribut1,$param,$new_val); |
#print "\$new_val=$new_val\n"; |
set_gui_status($mpsoc,"ref",$ref_delay); |
set_gui_status($mpsoc,"ref",$ref_delay) if(defined $ref_delay); |
}); |
} |
|
150,6 → 147,7
} |
elsif ( $type eq "DIR_path"){ |
$widget =get_dir_in_object ($mpsoc,$attribut1,$param,$value,'ref',10); |
set_gui_status($mpsoc,"ref",$ref_delay) if(defined $ref_delay); |
} |
|
|
160,17 → 158,22
|
my $inf_bt= gen_button_message ($info,"icons/help.png"); |
if($show==1){ |
my $tmp=gen_label_in_left(" "); |
$table->attach_defaults ($label , 0, 4, $row,$row+1); |
$table->attach_defaults ($inf_bt , 4, 5, $row,$row+1); |
$table->attach_defaults ($widget , 5, 9, $row,$row+1); |
$table->attach_defaults ($tmp , 9, 10, $row,$row+1); |
attach_widget_to_table ($table,$row,$label,$inf_bt,$widget); |
$row++; |
} |
return $row; |
} |
|
sub attach_widget_to_table { |
my ($table,$row,$label,$inf_bt,$widget)=@_; |
my $tmp=gen_label_in_left(" "); |
$table->attach ($label , 0, 4, $row,$row+1,'fill','shrink',2,2); |
$table->attach ($inf_bt , 4, 5, $row,$row+1,'fill','shrink',2,2); |
$table->attach ($widget , 5, 9, $row,$row+1,'fill','shrink',2,2); |
$table->attach ($tmp , 9, 10, $row,$row+1,'fill','shrink',2,2); |
} |
|
|
sub initial_default_param{ |
my $mpsoc=shift; |
my @socs=$mpsoc->mpsoc_get_soc_list(); |
749,7 → 752,7
$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=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$show_noc,'noc_type'); |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$show_noc,'noc_type',1); |
my $router_type=$mpsoc->object_get_attribute('noc_type',"ROUTER_TYPE"); |
|
|
761,7 → 764,7
$content='2,16,1'; |
$info= 'Number of NoC routers in row (X dimention)'; |
$type= 'Spin-button'; |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$show_noc,'noc_param'); |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$show_noc,'noc_param',1); |
|
|
|
772,7 → 775,7
$content='2,16,1'; |
$info= 'Number of NoC routers in column (Y dimention)'; |
$type= 'Spin-button'; |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$show_noc,'noc_param'); |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$show_noc,'noc_param',1); |
|
if($router_type eq '"VC_BASED"'){ |
#VC number per port |
784,7 → 787,7
$type='Spin-button'; |
$content='2,16,1'; |
$info='Number of Virtual Channel per each router port'; |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$show_noc,'noc_param'); |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$show_noc,'noc_param',1); |
} else { |
$mpsoc->object_add_attribute('noc_param','V',1); |
$mpsoc->object_add_attribute('noc_param','C',0); |
799,7 → 802,7
$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= noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$show_noc,'noc_param'); |
$row= noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$show_noc,'noc_param',undef); |
|
#packet payload width |
$label='payload width'; |
808,7 → 811,7
$content='32,256,32'; |
$type='Spin-button'; |
$info="The packet payload width in bits"; |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info,$table,$row,$show_noc,'noc_param'); |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info,$table,$row,$show_noc,'noc_param',undef); |
|
#topology |
$label='Topology'; |
817,7 → 820,7
$content='"MESH","TORUS"'; |
$type='Combo-box'; |
$info="NoC topology"; |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$show_noc,'noc_param'); |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$show_noc,'noc_param',1); |
|
#routing algorithm |
my $topology=$mpsoc->object_get_attribute('noc_param','TOPOLOGY'); |
836,7 → 839,7
} |
$default=($topology eq '"MESH"')? '"XY"':'"TRANC_XY"'; |
$info="Select the routing algorithm: XY(DoR) , partially adaptive (Turn models). Fully adaptive (Duato) "; |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$show_noc,'noc_param'); |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$show_noc,'noc_param',1); |
|
|
#SSA |
845,8 → 848,8
$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=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$show_noc,'noc_param'); |
$info="Enable single cycle latency on packets traversing in the same direction using static straight allocator (SSA)"; |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$show_noc,'noc_param',undef); |
|
|
|
883,7 → 886,7
$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; |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$adv_set,'noc_param'); |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$adv_set,'noc_param',undef); |
|
} |
#Fully adaptive routing setting |
899,7 → 902,7
|
|
$info="Select the escap VC for fully adaptive routing."; |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$adv_set,$adv_set,'noc_param'); |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$adv_set, 'noc_param',undef); |
|
} |
|
910,7 → 913,7
$default='"NONATOMIC"'; |
$content='"ATOMIC","NONATOMIC"'; |
$type='Combo-box'; |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$adv_set,'noc_param'); |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$adv_set,'noc_param',undef); |
|
|
|
923,7 → 926,7
$content='"BASELINE","COMB_SPEC1","COMB_SPEC2","COMB_NONSPEC"'; |
$type='Combo-box'; |
$info="The joint VC/ switch allocator type. using canonical combination is not recommanded"; |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$adv_set,'noc_param'); |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$adv_set,'noc_param',undef); |
|
} |
|
934,7 → 937,7
$content='"ONE_HOT","BINARY"'; |
$type='Combo-box'; |
$info="Crossbar multiplexer type"; |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$adv_set,'noc_param'); |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$adv_set,'noc_param',undef); |
|
if($router_type eq '"VC_BASED"'){ |
#class |
944,7 → 947,7
$info='Number of message classes. Each specific class can use different set of VC'; |
$content='0,16,1'; |
$type='Spin-button'; |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$adv_set,'noc_param'); |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$adv_set,'noc_param',5); |
|
|
my $class=$mpsoc->object_get_attribute('noc_param',"C"); |
961,7 → 964,7
$type="Check-box"; |
$content=$v; |
$info="Select the permitted VCs which the message class $i can be sent via them."; |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$adv_set,'noc_param'); |
$row=noc_param_widget ($mpsoc,$label,$param, $default,$type,$content,$info, $table,$row,$adv_set,'noc_param',undef); |
|
|
} |
1138,45 → 1141,57
# |
########### |
|
sub gen_socs { |
my ($mpsoc,$info)=@_; |
my $path=$mpsoc->object_get_attribute('setting','soc_path'); |
$path=~ s/ /\\ /g; |
my @socs; |
my @files = glob "$path/*.SOC"; |
my @soc_list=$mpsoc-> mpsoc_get_soc_list(); |
my @used_socs; |
foreach my $soc_name (@soc_list){ |
my @n=$mpsoc->mpsoc_get_soc_tiles_num($soc_name); |
if(scalar @n){ |
#generate the verilog files of it |
push(@used_socs,$soc_name); |
} |
} |
|
|
|
sub gen_all_tiles{ |
my ($mpsoc,$info, $hw_dir,$sw_dir)=@_; |
my $nx= $mpsoc->object_get_attribute('noc_param',"NX"); |
my $ny= $mpsoc->object_get_attribute('noc_param',"NY"); |
my $mpsoc_name=$mpsoc->object_get_attribute('mpsoc_name'); |
my $target_dir = "$ENV{'PRONOC_WORK'}/MPSOC/$mpsoc_name"; |
|
for my $p (@files){ |
# Read |
|
|
|
|
my @generated_tiles; |
|
#print "nx=$nx,ny=$ny\n"; |
for (my $y=0;$y<$ny;$y++){for (my $x=0; $x<$nx;$x++){ |
|
my $tile_num= $y*$nx+$x; |
#print "$tile_num\n"; |
my ($soc_name,$num)= $mpsoc->mpsoc_get_tile_soc_name($tile_num); |
my $path=$mpsoc->object_get_attribute('setting','soc_path'); |
$path=~ s/ /\\ /g; |
my $p = "$path/$soc_name.SOC"; |
my $soc = eval { do $p }; |
if ($@ || !defined $soc){ |
show_info(\$info,"**Error reading $p file: $@\n"); |
next; |
} |
my $name=$soc->object_get_attribute('soc_name'); |
if( grep (/^$name$/,@used_socs)){ |
#generate the soc |
generate_soc_files($mpsoc,$soc,$info); |
|
#update core id |
$soc->object_add_attribute('global_param','CORE_ID',$tile_num); |
|
|
|
}; |
|
|
} |
|
|
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); |
move ("$hw_dir/$soc_name.v","$hw_dir/tiles/"); |
|
} |
|
|
}} |
|
|
} |
|
|
################ |
# generate_soc |
################# |
1190,7 → 1205,7
# 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_name]); |
print FILE Data::Dumper->Dump([\%$soc],['mpsoc']); |
close(FILE) || die "Error closing file: $!"; |
|
# Write verilog file |
1203,9 → 1218,9
|
# copy all files in project work directory |
my $dir = Cwd::getcwd(); |
my $project_dir = abs_path("$dir/../../"); |
#make target dir |
my $project_dir = abs_path("$dir/../../"); |
my $target_dir = "$project_dir/mpsoc_work/MPSOC/$mpsoc_name"; |
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); |
1271,57 → 1286,141
sub generate_mpsoc{ |
my ($mpsoc,$info)=@_; |
my $name=$mpsoc->object_get_attribute('mpsoc_name'); |
my $size= (defined $name)? length($name) :0; |
if ($size >0){ |
gen_socs($mpsoc,$info); |
my ($file_v,$tmp)=mpsoc_generate_verilog($mpsoc); |
if ( $name =~ /\W+/ ){ |
message_dialog('The mpsoc name must not contain any non-word character:("./\()\':,.;<>~!@#$%^&*|+=[]{}`~?-")!")'); |
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"; |
|
mkpath("$hw_dir/lib/",1,0755); |
mkpath("$hw_dir/tiles",1,0755); |
mkpath("$sw_dir",1,0755); |
|
|
#generate/copy all tiles HDL/SW codes |
gen_all_tiles($mpsoc,$info, $hw_dir,$sw_dir ); |
|
#copy all NoC HDL files |
|
my @files = glob( "$dir/../src_noc/*.v" ); |
copy_file_and_folders(\@files,$dir,"$hw_dir/lib/"); |
|
|
|
my ($file_v,$top_v)=mpsoc_generate_verilog($mpsoc); |
|
|
|
# Write object file |
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: $!"; |
|
# Write object file |
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: $!"; |
# Write verilog file |
open(FILE, ">lib/verilog/$name.v") || die "Can not open: $!"; |
print FILE $file_v; |
close(FILE) || die "Error closing file: $!"; |
|
# 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: $!"; |
|
|
|
|
# copy all files in project work directory |
my $dir = Cwd::getcwd(); |
#make target dir |
my $project_dir = abs_path("$dir/../../"); |
my $target_dir = "$project_dir/mpsoc_work/MPSOC/$name"; |
mkpath("$target_dir/src_verilog/lib/",1,0755); |
mkpath("$target_dir/sw",1,0755); |
|
|
|
#gen_socs($mpsoc,$info); |
|
move ("$dir/lib/verilog/$name.v","$target_dir/src_verilog/"); |
|
|
|
|
|
|
|
|
message_dialog("SoC \"$name\" has been created successfully at $target_dir/ " ); |
#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: $!"; |
|
|
|
|
message_dialog("SoC \"$name\" has been created successfully at $target_dir/ " ); |
|
}else { |
message_dialog("Please define the MPSoC name!"); |
|
} |
|
|
return 1; |
} |
|
sub mpsoc_sw_make { |
my $make=' |
SUBDIRS := $(wildcard */.) |
all: $(SUBDIRS) |
$(SUBDIRS): |
$(MAKE) -C $@ |
|
.PHONY: all $(SUBDIRS) |
|
clean: |
$(MAKE) -C $(CODE_DIR) clean |
'; |
return $make; |
|
} |
|
|
sub mpsoc_mem_prog { |
my $string=' |
#!/bin/sh |
|
|
JTAG_MAIN="$PRONOC_WORK/toolchain/bin/jtag_main" |
|
#reset and disable cpus, then release the reset but keep the cpus disabled |
|
$JTAG_MAIN -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 |
sh ${i%%/}/write_memory.sh |
done |
|
#Enable the cpu |
$JTAG_MAIN -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); |
1771,40 → 1870,4
|
} |
|
########## |
|
########## |
sub copy_noc_files{ |
my ($project_dir,$dest)=@_; |
|
my @noc_files=( |
'/mpsoc/src_noc/arbiter.v', |
'/mpsoc/src_noc/baseline.v', |
'/mpsoc/src_noc/canonical_credit_count.v', |
'/mpsoc/src_noc/class_table.v', |
'/mpsoc/src_noc/combined_vc_sw_alloc.v', |
'/mpsoc/src_noc/comb_nonspec.v', |
'/mpsoc/src_noc/comb_spec2.v', |
'/mpsoc/src_noc/comb-spec1.v', |
'/mpsoc/src_noc/congestion_analyzer.v', |
'/mpsoc/src_noc/credit_count.v', |
'/mpsoc/src_noc/crossbar.v', |
'/mpsoc/src_noc/flit_buffer.v', |
'/mpsoc/src_noc/inout_ports.v', |
'/mpsoc/src_noc/inout_ports.v.classic', |
'/mpsoc/src_noc/input_ports.v', |
'/mpsoc/src_noc/main_comp.v', |
'/mpsoc/src_noc/noc.v', |
'/mpsoc/src_noc/route_mesh.v', |
'/mpsoc/src_noc/router.v', |
'/mpsoc/src_noc/route_torus.v', |
'/mpsoc/src_noc/routing.v', |
'/mpsoc/src_noc/vc_alloc_request_gen.v', |
'/mpsoc/src_noc/ss_allocator.v'); |
foreach my $f (@noc_files){ |
copy ("$project_dir$f",$dest); |
|
} |
|
|
} |
/mpsoc_verilog_gen.pl
19,7 → 19,10
//IO |
\tinput\tclk,reset;\n"; |
my $param_as_in_v; |
# generate top |
my $top_io="\t\t.clk(clk) ,\n\t\t.reset(reset_ored_jtag)"; |
|
|
#generate socs_parameter |
my $socs_param= gen_socs_param($mpsoc); |
|
27,10 → 30,10
my ($noc_param,$pass_param)=gen_noc_param_v($mpsoc); |
|
#generate the noc |
my $noc_v=gen_noc_v(); |
my $noc_v=gen_noc_v($pass_param); |
|
#generate socs |
my $socs_v=gen_socs_v($mpsoc,\$io_v,\$io_def_v); |
my $socs_v=gen_socs_v($mpsoc,\$io_v,\$io_def_v,\$top_io); |
|
#functions |
my $functions=get_functions(); |
44,8 → 47,40
add_text_to_string (\$mpsoc_v,$socs_v); |
add_text_to_string (\$mpsoc_v,"\nendmodule\n"); |
|
my $top_v = (defined $param_as_in_v )? "module ${mpsoc_name}_top #(\n $param_as_in_v\n)(\n$io_v\n);\n": "module ${mpsoc_name}_top (\n $io_v\n);\n"; |
add_text_to_string (\$top_v,$socs_param); |
add_text_to_string (\$top_v,$io_def_v); |
add_text_to_string(\$top_v," |
// Allow software to remote reset/enable the cpu via jtag |
|
wire jtag_cpu_en, jtag_system_reset; |
|
jtag_system_en jtag_en ( |
.cpu_en(jtag_cpu_en), |
.system_reset(jtag_system_reset) |
|
return $mpsoc_v; |
); |
|
wire reset_ored_jtag = reset | jtag_system_reset; |
wire processors_en_anded_jtag = processors_en & jtag_cpu_en; |
|
${mpsoc_name} the_${mpsoc_name} ( |
|
$top_io |
|
|
); |
|
endmodule |
|
|
"); |
|
#my $ins= gen_mpsoc_instance_v($mpsoc,$mpsoc_name,$param_pass_v); |
|
#add_text_to_string(\$top_v,$local_param_v_all."\n".$io_full_v_all); |
#add_text_to_string(\$top_v,$ins); |
return ($mpsoc_v,$top_v); |
} |
|
sub get_functions{ |
173,8 → 208,8
|
|
sub gen_noc_v{ |
my $pass_param = shift; |
|
|
my $noc = read_file("../src_noc/noc.v"); |
my @noc_param=$noc->get_modules_parameters_not_local_order('noc'); |
|
206,9 → 241,9
foreach my $p (@noc_param){ |
my $param=($i==0)? "\t\t.$p($p)":",\n\t\t.$p($p)"; |
$i=1; |
add_text_to_string(\$noc_v,$param); |
#add_text_to_string(\$noc_v,$param); |
} |
add_text_to_string(\$noc_v,"\n\t)\n\tthe_noc\n\t(\n"); |
add_text_to_string(\$noc_v,"$pass_param\n\t)\n\tthe_noc\n\t(\n"); |
|
my @ports= $noc->get_module_ports_order('noc'); |
$i=0; |
293,7 → 328,8
|
|
sub gen_socs_v{ |
my ($mpsoc,$io_v_ref,$io_def_v)=@_; |
my ($mpsoc,$io_v_ref,$io_def_v,$top_io_ref)=@_; |
|
#generate loop |
|
# my $socs_v=' |
346,13 → 382,16
for (my $y=0;$y<$ny;$y++){ |
for (my $x=0; $x<$nx;$x++){ |
my $tile_num=($nx*$y)+ $x; |
|
my ($soc_name,$n,$soc_num)=$mpsoc->mpsoc_get_tile_soc_name($tile_num); |
|
if(defined $soc_name) { |
my ($soc_v,$en)= gen_soc_v($mpsoc,$soc_name,$tile_num,$x,$y,$soc_num,$io_v_ref,$io_def_v); |
|
|
|
my ($soc_v,$en)= gen_soc_v($mpsoc,$soc_name,$tile_num,$x,$y,$soc_num,$io_v_ref,$io_def_v,$top_io_ref); |
add_text_to_string(\$socs_v,$soc_v); |
$processors_en|=$en; |
|
}else{ |
#this tile is not connected to any ip. the noc input ports will be connected to ground |
my $soc_v="\n\n // Tile:$tile_num (x=$x,y=$y) is not assigned to any ip\n"; |
371,6 → 410,7
if($processors_en){ |
add_text_to_string($io_v_ref,",\n\tprocessors_en"); |
add_text_to_string($io_def_v,"\t input processors_en;"); |
add_text_to_string($top_io_ref,",\n\t\t.processors_en(processors_en_anded_jtag)"); |
|
} |
|
386,7 → 426,7
|
|
sub gen_soc_v{ |
my ($mpsoc,$soc_name,$tile_num,$x,$y,$soc_num,$io_v_ref,$io_def_v)=@_; |
my ($mpsoc,$soc_name,$tile_num,$x,$y,$soc_num,$io_v_ref,$io_def_v,$top_io_ref)=@_; |
my $soc_v; |
my $processor_en=0; |
my $xw= log2($mpsoc->object_get_attribute('noc_param',"NX")); |
425,8 → 465,7
|
my $dir = Cwd::getcwd(); |
my $mpsoc_name=$mpsoc->object_get_attribute('mpsoc_name'); |
my $project_dir = abs_path("$dir/../../"); |
my $target_dir = "$project_dir/mpsoc_work/MPSOC/$mpsoc_name"; |
my $target_dir = "$ENV{'PRONOC_WORK'}/MPSOC/$mpsoc_name"; |
my $soc_file="$target_dir/src_verilog/tiles/$soc_name.v"; |
|
my $vdb =read_file($soc_file); |
510,6 → 549,7
} |
#io name |
add_text_to_string($io_v_ref,",\n\t$io_port"); |
add_text_to_string($top_io_ref,",\n\t\t.$io_port($io_port)"); |
#io definition |
my $new_range = add_instantc_name_to_parameters(\%params,"${soc_name}_$soc_num",$range); |
#my $new_range=$range; |
/soc_gen.pl
8,7 → 8,7
use POSIX 'strtol'; |
|
use File::Path; |
use File::Find; |
#use File::Find; |
use File::Copy; |
use File::Copy::Recursive qw(dircopy); |
use Cwd 'abs_path'; |
166,7 → 166,8
$max=~ s/\D//g; |
$step=~ s/\D//g; |
my $spin=gen_spin($min,$max,$step); |
$spin->set_value($value); |
if(defined $value) {$spin->set_value($value);} |
else {$spin->set_value($min);} |
$table->attach ($spin, 3, 4, $row, $row+1,'expand','shrink',2,2); |
$spin-> signal_connect("value_changed" => sub{ $new_param_value{$p}=$spin->get_value_as_int(); }); |
|
853,82 → 854,74
################# |
|
sub generate_soc{ |
my ($soc,$info)=@_; |
my $name=$soc->object_get_attribute('soc_name'); |
if (length($name)>0){ |
my @tmp=split('_',$name); |
if ( $tmp[-1] =~ /^[0-9]+$/ ){ |
message_dialog("The soc name must not end with '_number'!"); |
return 0; |
} |
my ($soc,$info,$target_dir,$hw_path,$sw_path,$gen_top,$gen_hw_lib)=@_; |
my $name=$soc->object_get_attribute('soc_name'); |
|
|
my ($file_v,$top_v,$readme,$prog)=soc_generate_verilog($soc); |
|
my ($file_v,$top_v,$readme)=soc_generate_verilog($soc); |
# Write object file |
open(FILE, ">lib/soc/$name.SOC") || die "Can not open: $!"; |
print FILE perl_file_header("$name.SOC"); |
print FILE Data::Dumper->Dump([\%$soc],['soc']); |
close(FILE) || die "Error closing file: $!"; |
|
# Write object file |
open(FILE, ">lib/soc/$name.SOC") || die "Can not open: $!"; |
print FILE perl_file_header("$name.SOC"); |
print FILE Data::Dumper->Dump([\%$soc],[$name]); |
close(FILE) || die "Error closing file: $!"; |
# Write verilog file |
open(FILE, ">lib/verilog/$name.v") || die "Can not open: $!"; |
print FILE $file_v; |
close(FILE) || die "Error closing file: $!"; |
|
# Write verilog file |
open(FILE, ">lib/verilog/$name.v") || die "Can not open: $!"; |
print FILE $file_v; |
close(FILE) || die "Error closing file: $!"; |
|
# Write Top module file |
# Write Top module file |
if($gen_top){ |
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: $!"; |
} |
|
# Write readme file |
open(FILE, ">lib/verilog/README") || die "Can not open: $!"; |
print FILE $readme; |
close(FILE) || die "Error closing file: $!"; |
|
|
# Write memory prog file |
open(FILE, ">lib/verilog/write_memory.sh") || die "Can not open: $!"; |
print FILE $prog; |
close(FILE) || die "Error closing file: $!"; |
|
my $dir = Cwd::getcwd(); |
my $project_dir = abs_path("$dir/../../"); |
if($gen_hw_lib){ |
|
#make target dir |
my $hw_lib="$hw_path/lib"; |
mkpath("$hw_lib/",1,01777); |
mkpath("$sw_path/",1,01777); |
|
#copy hdl codes in src_verilog |
|
# Write readme file |
open(FILE, ">lib/verilog/README") || die "Can not open: $!"; |
print FILE $readme; |
close(FILE) || die "Error closing file: $!"; |
|
# copy all files in project work directory |
my $dir = Cwd::getcwd(); |
#make target dir |
my $project_dir = abs_path("$dir/../../"); |
my $target_dir = "$project_dir/mpsoc_work/SOC/$name"; |
mkpath("$target_dir/src_verilog/lib/",1,01777); |
mkpath("$target_dir/sw",1,01777); |
|
#copy hdl codes in src_verilog |
|
my ($file_ref,$warnings)= get_all_files_list($soc,"hdl_files"); |
my ($file_ref,$warnings)= get_all_files_list($soc,"hdl_files"); |
|
copy_file_and_folders($file_ref,$project_dir,"$target_dir/src_verilog/lib"); |
|
copy_file_and_folders($file_ref,$project_dir,$hw_lib); |
show_info(\$info,$warnings) if(defined $warnings); |
|
|
#copy jtag control files |
my @jtags=(("/mpsoc/src_peripheral/jtag/jtag_wb"),("jtag")); |
copy_file_and_folders(\@jtags,$project_dir,"$target_dir/src_verilog/lib"); |
|
#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 |
# ); |
#} |
#copy jtag control files |
my @jtags=(("/mpsoc/src_peripheral/jtag/jtag_wb"),("jtag")); |
copy_file_and_folders(\@jtags,$project_dir,$hw_lib); |
move ("$dir/lib/verilog/$name.v","$hw_path/"); |
move ("$dir/lib/verilog/${name}_top.v","$hw_path/"); |
move ("$dir/lib/verilog/README" ,"$sw_path/"); |
move ("$dir/lib/verilog/write_memory.sh" ,"$sw_path/"); |
} |
|
# Copy Software files |
my ($file_ref,$warnings)= get_all_files_list($soc,"sw_files"); |
copy_file_and_folders($file_ref,$project_dir,$sw_path); |
|
|
move ("$dir/lib/verilog/$name.v","$target_dir/src_verilog/"); |
move ("$dir/lib/verilog/${name}_top.v","$target_dir/src_verilog/"); |
move ("$dir/lib/verilog/README" ,"$target_dir/sw/"); |
# Copy Software files |
($file_ref,$warnings)= get_all_files_list($soc,"sw_files"); |
copy_file_and_folders($file_ref,$project_dir,"$target_dir/sw"); |
|
# Write system.h and Software gen files |
generate_header_file($soc,$project_dir,$target_dir,$dir); |
# Write system.h and Software gen files |
generate_header_file($soc,$project_dir,$sw_path,$dir); |
|
|
|
935,7 → 928,7
|
|
# Write main.c file if not exist |
my $n="$target_dir/sw/main.c"; |
my $n="$sw_path/main.c"; |
if (!(-f "$n")) { |
# Write main.c |
open(FILE, ">$n") || die "Can not open: $!"; |
947,15 → 940,8
|
|
|
message_dialog("SoC \"$name\" has been created successfully at $target_dir/ " ); |
exec($^X, $0, @ARGV);# reset ProNoC to apply changes |
|
}else { |
message_dialog("Please define the SoC name!"); |
|
} |
|
return 1; |
|
} |
|
|
1419,8 → 1405,8
my $soc = soc->soc_new(); |
set_gui_status($soc,"ideal",0); |
#my $soc= eval { do 'lib/soc/soc.SOC' }; |
#message_dialog("$ENV{'PRONOC_WORK'}\n"); |
|
|
# main window |
#my $window = def_win_size(1000,800,"Top"); |
# The main table containg the lib tree, selected modules and info section |
1471,6 → 1457,55
$main_table->attach ($generate, 10, 12, 19,20,'expand','shrink',2,2); |
|
|
|
|
|
$generate-> signal_connect("clicked" => sub{ |
my $name=$soc->object_get_attribute('soc_name'); |
|
if (length($name)==0){ |
message_dialog("Please define the SoC name!"); |
return ; |
} |
|
|
my @tmp=split('_',$name); |
if ( $tmp[-1] =~ /^[0-9]+$/ ){ |
message_dialog("The soc name must not end with '_number'!"); |
return ; |
} |
if ( $name =~ /\W+/ ){ |
message_dialog('The soc name must not contain any non-word character:("./\()\':,.;<>~!@#$%^&*|+=[]{}`~?-")!")'); |
return ; |
} |
|
my $target_dir = "$ENV{'PRONOC_WORK'}/SOC/$name"; |
my $hw_dir = "$target_dir/src_verilog"; |
my $sw_path = "$target_dir/sw"; |
|
$soc->object_add_attribute('global_param','CORE_ID',0); |
generate_soc($soc,$info,$target_dir,$hw_dir,$sw_path,1,1); |
message_dialog("SoC \"$name\" has been created successfully at $target_dir/ " ); |
exec($^X, $0, @ARGV);# reset ProNoC to apply changes |
|
}); |
|
$wb-> signal_connect("clicked" => sub{ |
wb_address_setting($soc); |
|
}); |
|
$open-> signal_connect("clicked" => sub{ |
load_soc($soc,$info); |
|
}); |
|
my $sc_win = new Gtk2::ScrolledWindow (undef, undef); |
$sc_win->set_policy( "automatic", "automatic" ); |
$sc_win->add_with_viewport($main_table); |
|
|
|
#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($soc); |
1489,28 → 1524,9
return TRUE; |
|
} ); |
|
|
$generate-> signal_connect("clicked" => sub{ |
generate_soc($soc,$info); |
$refresh_dev_win->clicked; |
|
}); |
|
$wb-> signal_connect("clicked" => sub{ |
wb_address_setting($soc); |
|
}); |
|
$open-> signal_connect("clicked" => sub{ |
load_soc($soc,$info); |
|
}); |
|
my $sc_win = new Gtk2::ScrolledWindow (undef, undef); |
$sc_win->set_policy( "automatic", "automatic" ); |
$sc_win->add_with_viewport($main_table); |
|
return $sc_win; |
#return $main_table; |
|
/temp.pl
1,9 → 1,43
#!/usr/bin/perl |
use warnings; |
use strict; |
use File::System |
use List::Util 'shuffle'; |
|
my $fs = File::System->new('Real'); |
my $fs = File::System->new('My::File::System::Foo'); |
(system("ls")); |
|
|
sub remove_scolar_from_array{ |
my ($array_ref,$item)=@_; |
my @array=@{$array_ref}; |
my @new; |
foreach my $p (@array){ |
if($p ne $item ){ |
push(@new,$p); |
} |
} |
return @new; |
} |
|
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; |
|
} |
|
my $ref=random_dest_gen(16); |
my @random= @{$ref}; |
|
for (my $i=0; $i<16; $i++){ |
for (my $j=0; $j<15; $j++){ |
print @{$random[$i]}[$j]; |
print ","; |
} |
print "\n"; |
} |
/verilog_gen.pl
27,7 → 27,13
|
my @instances=$soc->soc_get_all_instances(); |
my $io_sim_v; |
my $param_as_in_v="\tparameter\tCORE_ID=0"; |
my $core_id= $soc->object_get_attribute('global_param','CORE_ID'); |
$core_id= 0 if(!defined $core_id); |
my $param_as_in_v="\tparameter\tCORE_ID=$core_id"; |
|
|
|
|
my $param_pass_v="\t.CORE_ID(CORE_ID)"; |
my $body_v; |
|
88,8 → 94,8
|
add_text_to_string(\$top_v,$local_param_v_all."\n".$io_full_v_all); |
add_text_to_string(\$top_v,$ins); |
my $readme=gen_system_info($soc,$param_as_in_v); |
return ("$soc_v",$top_v,$readme); |
my ($readme,$prog)=gen_system_info($soc,$param_as_in_v); |
return ("$soc_v",$top_v,$readme,$prog); |
|
|
} |
647,15 → 653,22
#my (@newbase,@newend,@connects); |
|
|
$jtag=''; |
|
my @all_instances=$soc->soc_get_all_instances(); |
|
my @all_instances=$soc->soc_get_all_instances(); |
my %jtagwb; my %ram; |
|
|
foreach my $instance_id (@all_instances){ |
my $category=$soc->soc_get_category($instance_id); |
|
my @plugs= $soc->soc_get_all_plugs_of_an_instance($instance_id); |
foreach my $plug (@plugs){ |
my @nums=$soc->soc_list_plug_nums($instance_id,$plug); |
foreach my $num (@nums){ |
my ($addr,$base,$end,$name,$connect_id,$connect_socket,$connect_socket_num)=$soc->soc_get_plug($instance_id,$plug,$num); |
|
my $instance_name=$soc->soc_get_instance_name($instance_id); |
my $connect_name=$soc->soc_get_instance_name($connect_id); |
#get interfaces |
663,7 → 676,12
|
$base=sprintf("0x%08x", $base); |
$end=sprintf("0x%08x", $end); |
add_text_to_string(\$wb_slaves, "\t$instance_name, $name, $connect_name, $base, $end\n"); |
add_text_to_string(\$wb_slaves, "\t$instance_name, $name, $connect_name, $base, $end\n"); |
if ($category eq 'RAM') { |
$ram{$instance_id}{'base'}=$base; |
$ram{$instance_id}{'end'}=$end; |
$ram{$instance_id}{'connect'}=$connect_id; |
} |
|
}#if |
elsif((defined $connect_socket) && ($connect_socket eq 'wb_master')){ |
676,8 → 694,9
# get jtag_wbs |
if((defined $connect_socket) && ($connect_socket eq 'wb_master') && ($instance_id =~ /jtag_wb/)){ |
my $index=$soc->soc_get_module_param_value($instance_id,'VJTAG_INDEX'); |
|
add_text_to_string(\$jtag, "\t$instance_name, $connect_name, $index\n"); |
|
$jtagwb{$connect_id}{'index'}=$index; |
|
} |
|
686,7 → 705,70
}#foreach my $plug |
}#foreach my $instance_id |
|
#Generate memory programming command |
my $prog='#!/bin/sh |
|
JTAG_MAIN="$PRONOC_WORK/toolchain/bin/jtag_main" |
|
'; |
|
|
foreach my $instance_id (@all_instances){ |
my $category=$soc->soc_get_category($instance_id); |
if ($category eq 'RAM') { |
|
my $jtag_connect=$soc->soc_get_module_param_value($instance_id,'JTAG_CONNECT'); |
my $aw=$soc->soc_get_module_param_value($instance_id,'Aw'); |
my $dw=$soc->soc_get_module_param_value($instance_id,'Dw'); |
my $JTAG_INDEX=$soc->soc_get_module_param_value($instance_id,'JTAG_INDEX'); |
|
#check if jtag_index is a parameter |
my $v=$soc->soc_get_module_param_value($instance_id,$JTAG_INDEX); |
$JTAG_INDEX = $v if (defined $v); |
$v= $soc->object_get_attribute('global_param',$JTAG_INDEX); |
$JTAG_INDEX = $v if (defined $v); |
|
my $BINFILE=$soc->soc_get_module_param_value($instance_id,'INIT_FILE_NAME'); |
($BINFILE)=$BINFILE=~ /"([^"]*)"/ if(defined $BINFILE); |
$BINFILE=(defined $BINFILE) ? $BINFILE.'.bin' : 'ram0.bin'; |
|
my $OFSSET="0x00000000"; |
my $end=((1<<$aw)*($dw/8))-1; |
my $BOUNDRY=sprintf("0x%08x", $end); |
if($jtag_connect =~ /JTAG_WB/){ |
$prog= "$prog \$JTAG_MAIN -n $JTAG_INDEX -s \"$OFSSET\" -e \"$BOUNDRY\" -i \"$BINFILE\" -c"; |
#print "prog= $prog\n"; |
|
}elsif ($jtag_connect eq 'ALTERA_IMCE'){ |
#TODO add later |
|
|
} else{ |
#disabled check if its connected to jtag_wb via the bus |
my $connect_id = $ram{$instance_id}{'connect'}; |
my $OFSSET = $ram{$instance_id}{'base'}; |
my $BOUNDRY = $ram{$instance_id}{'end'}; |
if(defined $connect_id){ |
#print "id=$connect_id\n"; |
my $JTAG_INDEX= $jtagwb{$connect_id}{'index'}; |
if(defined $JTAG_INDEX){ |
$v= $soc->object_get_attribute('global_param',$JTAG_INDEX); |
$JTAG_INDEX = $v if (defined $v); |
$prog= "$prog \$JTAG_MAIN -n $JTAG_INDEX -s \"$OFSSET\" -e \"$BOUNDRY\" -i \"$BINFILE\" -c"; |
#print "prog= $prog\n"; |
|
} |
|
} |
} |
|
|
} |
|
|
} |
|
|
my $lisence= get_license_header("readme"); |
my $warning=autogen_warning(); |
|
705,21 → 787,8
|
sh program.sh |
|
but first, you need to update these variables inside the program.sh file |
|
OFSSET= [offset_in_hex] |
The RAM wishbone bus offset address e.g : 0x0000000. |
BOUNDRY=[boundry_in_hex ] |
The RAM boundary address in hex e.g: 0x00003fff. |
VJTAG_INDEX=[Virtual jtag index number] |
BINFILE=[file_name] |
memory file in binary format. eg ram00.bin |
|
|
you can get OFSSET, BOUNDRY and VJTAG_INDEX values from following |
wishbone buse(s) info & Jtag to wishbone interface (jtag_wb) info sections. |
Also check the memory and jtag_wb are connected to the same bus (have same \"connected to\" filed). |
|
*************************** |
** soc parameters |
*************************** |
747,7 → 816,10
|
"; |
|
return $readme; |
|
|
|
return ($readme,$prog); |
|
|
|