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

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);

powered by: WebSVN 2.1.0

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