rlm@23: #!/usr/bin/perl -w rlm@23: #========================================================================== rlm@23: # bsc-trace.pl rlm@23: # rlm@23: # Author : Christopher Batten (cbatten@mit.edu) rlm@23: # Date : April 12, 2005 rlm@23: # rlm@23: (our $usageMsg = <<'ENDMSG') =~ s/^\#//gm; rlm@23: # rlm@23: # Simple script which converts bsv "one-per-line" trace output into rlm@23: # a more compact and readable column format. rlm@23: # rlm@23: ENDMSG rlm@23: rlm@23: use strict "vars"; rlm@23: use warnings; rlm@23: no warnings("once"); rlm@23: use Getopt::Long; rlm@23: use File::Basename; rlm@23: rlm@23: #-------------------------------------------------------------------------- rlm@23: # Command line processing rlm@23: #-------------------------------------------------------------------------- rlm@23: rlm@23: our %opts; rlm@23: rlm@23: sub usage() rlm@23: { rlm@23: rlm@23: print "\n"; rlm@23: print " Usage: bsc-trace.pl [trace-file]\n"; rlm@23: print "\n"; rlm@23: print " Options:\n"; rlm@23: print " --help print this message\n"; rlm@23: print " format string\n"; rlm@23: print " [trace-file] output trace from BSV simulation (default is STDIN)\n"; rlm@23: print "$usageMsg"; rlm@23: rlm@23: exit(); rlm@23: } rlm@23: rlm@23: sub processCommandLine() rlm@23: { rlm@23: rlm@23: $opts{"help"} = 0; rlm@23: rlm@23: Getopt::Long::GetOptions( \%opts, 'help|?' ) or usage(); rlm@23: rlm@23: ($opts{"format"} = shift(@ARGV)) or usage(); rlm@23: ($opts{"trace-file"} = shift(@ARGV)) or ($opts{"trace-file"} = "-"); rlm@23: $opts{"help"} and usage(); rlm@23: rlm@23: } rlm@23: rlm@23: #-------------------------------------------------------------------------- rlm@23: # Main rlm@23: #-------------------------------------------------------------------------- rlm@23: rlm@23: sub main() rlm@23: { rlm@23: rlm@23: processCommandLine(); rlm@23: require $opts{"format"}; rlm@23: rlm@23: my $cycle = 0; rlm@23: my %traceHash; rlm@23: rlm@23: my $traceFile = $opts{"trace-file"}; rlm@23: open( FIN, "<$traceFile" ) or die("Could not open BSV trace file ($traceFile)!"); rlm@23: rlm@23: print " processor-state [ icache ] [ dcache ] [ mem-arb ] executed-instruction\n"; rlm@23: rlm@23: my $labelLine = $settings::labelString; rlm@23: foreach my $tag ( keys %settings::headers){ rlm@23: my $theLabel = $settings::headers{$tag}; rlm@23: $labelLine =~ s/{$tag}/$theLabel/; rlm@23: } rlm@23: print " $labelLine\n"; rlm@23: rlm@23: while ( my $line = ) { rlm@23: rlm@23: if ( $line =~ /^ => Cycle =\s+(\d+)$/ ) { rlm@23: rlm@23: my $tempTraceLine = $settings::traceString; rlm@23: foreach my $tag ( keys %settings::fields ) { rlm@23: rlm@23: my $theTraceString = $traceHash{$tag}; rlm@23: my $theEmptyString = $settings::fields{$tag}; rlm@23: rlm@23: # Substitute the trace field in ... rlm@23: if ( defined($theTraceString) ) { rlm@23: rlm@23: # If the trace string is shorter than the empty string then rlm@23: # add some spaces at the end so things line up ... rlm@23: my $theTraceStringLen = length($theTraceString); rlm@23: my $theEmptyStringLen = length($theEmptyString); rlm@23: if ( $theTraceStringLen < $theEmptyStringLen ) { rlm@23: $theTraceString .= (" "x ($theEmptyStringLen-$theTraceStringLen)); rlm@23: } rlm@23: rlm@23: $tempTraceLine =~ s/{$tag}/$theTraceString/; rlm@23: rlm@23: } rlm@23: rlm@23: # Substitute the empty field in ... rlm@23: else { rlm@23: $tempTraceLine =~ s/{$tag}/$theEmptyString/; rlm@23: } rlm@23: rlm@23: } rlm@23: rlm@23: print " CYC: ".sprintf("%4d",$cycle)." $tempTraceLine\n"; rlm@23: rlm@23: $cycle = $1; rlm@23: %traceHash = (); rlm@23: } rlm@23: elsif ( $line =~ /^ => (\S+) (.*)$/ ) { rlm@23: $traceHash{$1} = $2; rlm@23: } rlm@23: else { rlm@23: print $line; rlm@23: } rlm@23: rlm@23: } rlm@23: close( FIN ); rlm@23: rlm@23: } rlm@23: rlm@23: main();