Files
DRAMSys/resources/scripts/analyse_trace.pl

379 lines
9.7 KiB
Perl

#!/usr/bin/perl
use List::Util 'max';
use warnings;
use strict;
my $filename = shift || die("Please provide a input STL file");
my $numberOfRows = 16384;
my $numberOfBanks = 8;
my $numberOfColumns = 1024;
my $numberOfBytes = 8; # Byte Offset from e.g. DIMM
my $numberOfBits = 32;
my $burstLength = 8;
my $addressCorrection = 1;
my $numberOfRowBits = log($numberOfRows)/log(2);
my $numberOfBankBits = log($numberOfBanks)/log(2);
my $numberOfColumnBits = log($numberOfColumns)/log(2);
my $numberOfByteBits = log($numberOfBytes)/log(2);
my $numberOfBurstBits = log($burstLength)/log(2);
print "Number of Address Bits:\t".$numberOfBits."\n\n";
print "Number of Row Bits:\t".$numberOfRowBits."\n";
print "Number of Bank Bits:\t".$numberOfBankBits."\n";
print "Number of Col Bits:\t".$numberOfColumnBits."\n";
print ">Burst Bits in Col:\t".$numberOfBurstBits."\n";
print "Number of Byte Bits:\t".$numberOfByteBits."\n";
my $numberOfXBits = $numberOfBits - $numberOfRowBits - $numberOfBankBits - $numberOfColumnBits - $numberOfByteBits;
print "Number of Unused Bits:\t".$numberOfXBits."\n";
print "\n";
print "\n";
open(FH, "$filename");
my @activityCounter;
my @mapping;
# Initialize:
for(my $i = 0; $i < $numberOfBits; $i++)
{
$activityCounter[$i] = 0;
}
for(my $i = $numberOfXBits-1; $i >= 0; $i--)
{
$mapping[$numberOfBits-($numberOfXBits-$i)] = "X".$i;
}
my $old_address = "00000000000000000000000000000000";
while(<FH>)
{
# Get the adress:
$_ =~ /\d+:\s+\w+\s+0x([\w\d]+)\s*[\d\w]*/;
my $address = $1;
$address = sprintf( "%0".$numberOfBits."b", hex( $address ) * $addressCorrection );
# $i = 0 :: most significant bit
for(my $i = 0; $i < $numberOfBits; $i++)
{
my $new = substr($address, $i, 1);
my $old = substr($old_address, $i, 1);
if($new ne $old)
{
$activityCounter[$numberOfBits-1-$i]++;
}
}
$old_address = $address;
}
close(FH);
# Make Consistency Check:
for(my $i = 0; $i < ($numberOfByteBits+$numberOfBankBits); $i++)
{
if($activityCounter[$i] != 0)
{
print "Bits of lower C part or Y have toggled, this should not happen\n";
exit -1;
}
}
# Print bit numbers:
print "Bits\t\t";
for(my $i = $numberOfBits-1; $i >= 0; $i--)
{
print $i."\t";
}
#Print Activity
print "\nActivity\t";
for(my $i = $numberOfBits-1; $i >= 0; $i--)
{
print $activityCounter[$i]."\t";
}
#Print relative Activity
print "\nPercent\t\t";
my $sum = 0;
my @percent;
for(my $i = $numberOfBits-1; $i >= 0; $i--)
{
$sum = $sum + $activityCounter[$i];
}
for(my $i = $numberOfBits-1; $i >= 0; $i--)
{
my $string = $activityCounter[$i]/$sum*100;
$string = sprintf("%.2f", $string);
$string =~ s/\./,/g;
$percent[$i] = $string."%";
$string .= "%\t";
print $string;
}
#Fix Byte Offset:
for(my $i = 0; $i < $numberOfByteBits; $i++)
{
$activityCounter[$i] = -1;
$mapping[$i] = "Y$i";
}
#Fix Constant 0 Bits in Column due to Burstlength:
for(my $i=0; $i < $numberOfBurstBits; $i++)
{
$activityCounter[$numberOfByteBits + $i] = -1;
$mapping[$numberOfByteBits + $i] = "C$i";
}
#Search Column Locations
for(my $i = $numberOfBurstBits; $i < $numberOfColumnBits; $i++)
{
my $maximum = max(@activityCounter);
my ($index) = grep $activityCounter[$_] == $maximum , 0.. $#activityCounter;
$mapping[$index] = "C$i";
$activityCounter[$index] = -1;
}
#Search Bank Locations
for(my $i = 0; $i < $numberOfBankBits; $i++)
{
my $maximum = max(@activityCounter);
my ($index) = grep $activityCounter[$_] == $maximum , 0.. $#activityCounter;
$mapping[$index] = "B$i";
$activityCounter[$index] = -1;
}
#Search Row Locations
for(my $i = 0; $i < $numberOfRowBits; $i++)
{
my $maximum = max(@activityCounter);
my ($index) = grep $activityCounter[$_] == $maximum , 0.. $#activityCounter;
$mapping[$index] = "R$i";
$activityCounter[$index] = -1;
}
#Print final mapping
my $header = '
strict graph G
{
forcelabels=true;
rankdir=LR;
{
graph [fontname = "courier"];
node [shape=square, fontname="courier", fixedsize=true, width=0.85, height=0.85]
edge [fontname = "courier"];
';
for(my $i = $numberOfBits-1; $i >= 0; $i--)
{
$header .= " $i [pos=\"".($numberOfBits-1-$i).",0!\", xlp=\"-5,0\", label=\"$i\n".$percent[$i]."\" ]\n";
}
my $pos = 0;
for(my $i = $numberOfXBits-1; $i >= 0; $i--)
{
my $pos2 = $numberOfBits-$pos-1;
$header .= " X$i [ label=\"$pos2\nX$i\" pos=\"$pos,-5!\"]\n";
$pos++;
}
for(my $i = $numberOfBankBits-1; $i >= 0; $i--)
{
my $pos2 = $numberOfBits-$pos-1;
$header .= " B$i [ label=\"$pos2\nB$i\" pos=\"$pos,-5!\"]\n";
$pos++;
}
for(my $i = $numberOfRowBits-1; $i >= 0; $i--)
{
my $pos2 = $numberOfBits-$pos-1;
$header .= " R$i [ label=\"$pos2\nR$i\" pos=\"$pos,-5!\"]\n";
$pos++;
}
for(my $i = $numberOfColumnBits-1; $i >= 0; $i--)
{
my $pos2 = $numberOfBits-$pos-1;
$header .= " C$i [ label=\"$pos2\nC$i\" pos=\"$pos,-5!\"]\n";
$pos++;
}
for(my $i = $numberOfByteBits-1; $i >= 0; $i--)
{
my $pos2 = $numberOfBits-$pos-1;
$header .= " Y$i [ label=\"$pos2\nY$i\" pos=\"$pos,-5!\"]\n";
$pos++;
}
$header .= " }\n";
print "\nMapping\t\t";
my $maximum = max(@activityCounter);
for(my $i = $numberOfBits-1; $i >= 0; $i--)
{
if($mapping[$i] =~ /X\d/)
{
$header .= "$i -- ".$mapping[$i]." [ color=\"grey\"];\n";
}
elsif($mapping[$i] =~ /B\d/)
{
$header .= "$i -- ".$mapping[$i]." [ color=\"green\"];\n";
}
elsif($mapping[$i] =~ /R\d/)
{
$header .= "$i -- ".$mapping[$i]." [ color=\"blue\"];\n";
}
elsif($mapping[$i] =~ /C\d/)
{
$header .= "$i -- ".$mapping[$i]." [ color=\"red\"];\n";
}
elsif($mapping[$i] =~ /Y\d/)
{
$header .= "$i -- ".$mapping[$i]." [ color=\"grey\"];\n";
}
print $mapping[$i]."\t";
}
$header .= "}";
print "\n";
#Generate Scrambled Trace:
#Generate Configuration for 32x32 MUX:
# Assumption e.g. 32 bit:
# B R C
# X X B B B R R R R R R R R R R R R R R C C C C C C C C C C Y Y Y
# 31 30 29 27 26 13 12 3 2 0
# A B C D E F
#
#print "A:".($numberOfBits-1)."\n";
#print "B:".($numberOfBits-$numberOfXBits-1)."\n";
#print "C:".($numberOfBits-$numberOfXBits-$numberOfBankBits-1)."\n";
#print "D:".($numberOfBits-$numberOfXBits-$numberOfBankBits-$numberOfRowBits-1)."\n";
#print "E:".($numberOfBits-$numberOfXBits-$numberOfBankBits-$numberOfRowBits-$numberOfColumnBits-1)."\n";
#print "F:".($numberOfBits-$numberOfXBits-$numberOfBankBits-$numberOfRowBits-$numberOfColumnBits-$numberOfByteBits)."\n";
my @confVectorDecimal;
my @checkVector;
my $XCounter = 0;
my $rowCounter = 0;
my $bankCounter = 0;
my $columnCounter = 0;
my $byteCounter = 0;
for(my $i = $numberOfBits-1; $i >= 0; $i--)
{
if($mapping[$i] =~ /X(\d+)/)
{
my $idx = $numberOfBits-$numberOfXBits+$1;
#print "\$1=".$1." i=".$i." idx=".$idx." mapping=".$mapping[$i]."\n";
$confVectorDecimal[$idx] = $i;
$checkVector[$idx] = "X";
}
elsif($mapping[$i] =~ /B(\d+)/)
{
my $idx = $numberOfBits-$numberOfXBits-$numberOfBankBits+$1;
#print "\$1=".$1." i=".$i." idx=".$idx." mapping=".$mapping[$i]."\n";
$confVectorDecimal[$idx] = $i;
$checkVector[$idx] = "B";
}
elsif($mapping[$i] =~ /R(\d+)/)
{
my $idx = $numberOfBits-$numberOfXBits-$numberOfBankBits-$numberOfRowBits+$1;
#print "\$1=".$1." i=".$i." idx=".$idx." mapping=".$mapping[$i]."\n";
$confVectorDecimal[$idx] = $i;
$checkVector[$idx] = "R";
}
elsif($mapping[$i] =~ /C(\d+)/)
{
my $idx = $numberOfBits-$numberOfXBits-$numberOfBankBits-$numberOfRowBits-$numberOfColumnBits+$1;
#print "\$1=".$1." i=".$i." idx=".$idx." mapping=".$mapping[$i]."\n";
$confVectorDecimal[$idx] = $i;
$checkVector[$idx] = "C";
}
elsif($mapping[$i] =~ /Y(\d+)/)
{
my $idx = $numberOfBits-$numberOfXBits-$numberOfBankBits-$numberOfRowBits-$numberOfColumnBits-$numberOfByteBits+$1;
#print "\$1=".$1." i=".$i." idx=".$idx." mapping=".$mapping[$i]."\n";
$confVectorDecimal[$idx] = $i;
$checkVector[$idx] = "Y";
}
}
print "\n";
print "\n";
print "Configuration Vector for the mapping ";
for(my $m = $numberOfBits-1; $m >= 0; $m--)
{
print $checkVector[$m];
}
print ":\n\n";
for(my $m = $numberOfBits-1; $m >= 0; $m--)
{
#Debug:
print "mux: $m\t-->\t".$confVectorDecimal[$m]."\n";
}
print "\n";
print "\n";
for(my $m = $numberOfBits-1; $m >= 0; $m--)
{
print sprintf( "%05b", $confVectorDecimal[$m] );
}
print "\n";
print "\n";
# Generate Graph
my $dotname;
my $pdfname;
my $stlname;
if($filename =~ /(.+)\.stl/)
{
$dotname = $1.".dot";
$pdfname = $1.".pdf";
$stlname = $1."_scram.stl";
open(FH,">$dotname");
print FH $header;
close(FH);
system("neato -o $pdfname -Tpdf $dotname");
}
open(FH, "$filename");
open(SH, ">$stlname");
while(<FH>)
{
# Get all the data adress:
$_ =~ /(\d+):\s+(\w+)\s+0x([\w\d]+)/; # XXX
my $time = $1;
my $command = $2;
my $address = $3;
my $new_address;
# Convert to binary:
$address = sprintf( "%032b", hex( $address ) );
# Swap adresses:
$new_address = "";
for(my $m = $numberOfBits-1; $m >= 0; $m--)
{
#print $confVectorDecimal[$m]."\n";
$new_address .= substr($address,$numberOfBits-1-$confVectorDecimal[$m],1);
}
# Convert to Hex:
$new_address = sprintf("%X", oct( "0b$new_address" ) );
print SH $time.":\t".$command."\t0x".$new_address."\n";
}
close(FH);
close(SH);