#! /usr/bin/perl -w

### -------------------------------------------------------------- ###
#                                                                    #
# File       : log_trace.pl                                          #
# Authors    : Sroka Marek                                          #
# Date       : 20/07/2006                                            #
# Modif.     : 18/08/2006                                            #
# Version    : 1.0                                                   #
#                                                                    #
# Origin     : this description has been developed by CAO-VLSI team  #
#              at ASIM laboratory, University Pierre et Marie Curie  #
#              4 Place Jussieu 75252 Paris Cedex 05 - France         #
#                                                                    #
### -------------------------------------------------------------- ###

my $TAB1='|  ';
my $TAB2='+--';

sub usage() 
{
    print "usage : $0 rob_trace_file nm_file\n";
    print "      * rob_trace_file : Trace file generate by simulation\n";
    print "      * nm_file        : List of symbol (generate by nm)\n";
    exit(1);
}

my $rob = $ARGV[0];
my $nm  = $ARGV[1];

if (not defined $rob) 
{
    usage();
}

unless (defined $nm) 
{
    usage();
}

my %calls=();
my %end=();

open (nm_f,$nm) or die "could not open $nm : $!\n";

my $current_section;

while ($line = <nm_f>) 
{ 
    if ($line =~ /([0-9a-f]{8}) [Tt] (.*)/) 
    { 
        my $addr=hex $1;
        $calls{$addr}=$2;
        $end{$current_section} = $addr if (defined $current_section);
        $current_section=$addr;
    }
}

$end{$current_section}=0xffffffff;

close nm_f;

my @pile  = ();
my $depth = 0;
open (rob_f,$rob) or die "could not open $rob : $!\n";

print "[ time     ] ","depth"," ","address "," ","function\n";

while (<rob_f>) 
{
    if (/(\d+) inst OK - \@([0-9a-f]{8})/) 
    {
        my $addr        = hex $2;
        my $time        = sprintf "%-8d",$1;
	my $print_addr  = sprintf "%-8x",$addr;

        if (exists $calls{$addr}) 
	{ 
	    my $print_depth = sprintf "%-5d",$depth;
	    $depth = $depth + 1;

            #print "[ $time ] ",$print_depth," ",$print_addr," ",$TAB1x@pile,"[1;32m$calls{$addr}[0m\n";
	    print "[ $time ] ",$print_depth," ",$print_addr," ",$TAB1 x(@pile-1),$TAB2,"  $calls{$addr}\n";
            push(@pile,$addr);
        }

        while (@pile and ($addr < $pile[-1] or $addr >= $end{$pile[-1]})) 
	{
	    $depth = $depth - 1;
	    my $print_depth = sprintf "%-5d",$depth;

            my $end=pop(@pile);
            #print "[ $time ] ",$print_depth," ","        "," ",$TAB2x@pile,"[0;31m$calls{$end}[0m\n";
	    print "[ $time ] ",$print_depth," ","        "," ",$TAB1 x@pile,"  $calls{$end}\n";
	}
    }
}
close rob_f;
