379 lines
9.7 KiB
Perl
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);
|