#!/usr/bin/perl -w

use strict;

# system "clear";

sub trim {
   my($string)=@_;
   for ($string) {
       s/^\s+//;
       s/\s+$//;
   }
   return $string;
}

#
# Load out file generated with "make ltc_rd" into @Lines string array.
#

my $Filename = $ARGV[0];

my @Lines = ("");
open(OUTDAT, "<$Filename") || die "out could not be opened!\n";

while(<OUTDAT>)
{
   push(@Lines, $_);
}
close(OUTDAT);

#
#  Definition of constants.
#

my $LastClockValue = -1;
my $LastTimeStamp = 0;
my $DataCount = 0;
my $IdleCount = 0;
my $Count = 0;
my $ErrorCount = 0;      # Data words with RXERR set
my $MismatchCount = 0;   # Data words differing between real and correct data value.


print "MEASURED    CORRECT           XORED               TIME          REL. TIME\n";

for(my $i = 2; $i < @Lines; $i++)
{

   my @parts = split(/ +|\t/, $Lines[$i]);
   
   my $Sample = $parts[1];
   my $RXCLK = $parts[2];
   my $RXDATA = hex($parts[4]);
   my $RXDV = $parts[6];
   my $RXERR = $parts[8];
   my $CorrectValue;
   
   $Count = $Count+1;

   # For data words we are sensitive to the rising edge of $RXCLK while $RXDV is high and $RXERR is low.  
   if ( ($LastClockValue == 0) & ($RXCLK == 1) & ($RXDV == 1) )
   {
   
        $DataCount = $DataCount + 1;
	$RXDATA = $RXDATA;   
	
	if ($DataCount <= 4)
	{
	   $CorrectValue = 0xAAAA;
	}
	elsif ($DataCount < (128 + 5))
	{
#	  $CorrectValue = ((2*($DataCount - 4)-1) + ((2*($DataCount - 4)) << 8)) & 0xFFFF; 
          $CorrectValue = ((2*($DataCount - 4)-1) + ((2*($DataCount - 4)-2) << 8)) & 0xFFFF; 
	}
	else
	{
	   $CorrectValue = 0;
	}

	
#        print sprintf("Data=0x%04X, /Data=0x%04X, DV=%d, ERR=%d, Sample %d, Clk=%d, TD=%1.1fns\n", $RXDATA, (~$RXDATA) & 0b1111111111111111, $RXDV, $RXERR, $Sample, $RXCLK, ($Sample-$LastTimeStamp)*500/1000);
	 
	 if ($RXDATA == $CorrectValue)
	 {
	    # Measured data equal to theoretical data.
    	    print sprintf("0x%04X      0x%04X                                t=%04.1fns    TD=%1.1fns\n", $RXDATA, $CorrectValue, $Sample*500/1000, ($Sample-$LastTimeStamp)*500/1000);
	 }
	 else
	 {
	    # Measured data deviate from theoretical data.
	    
	    my $MismatchMask = (($RXDATA ^ $CorrectValue) & 0xFFFF);
	    my $MismatchMask_High = (($RXDATA ^ $CorrectValue) & 0xFF00) >> 8;
	    my $MismatchMask_Low = (($RXDATA ^ $CorrectValue) & 0xFF);
	    
	    
	    my $a1 = ($RXDATA & 0b1111000000000000) >> 12;
	    my $a2 = ($RXDATA & 0b0000111100000000) >> 8;
	    my $b1 = ($CorrectValue & 0b1111000000000000) >> 12;
	    my $b2 = ($CorrectValue & 0b0000111100000000) >> 8;
#	    print sprintf("0x%04X  !=  0x%04X   %04b %04b... != %04b %04b...  t=%04.1fns    TD=%1.1fns\n", $RXDATA, $CorrectValue, $a1, $a2, $b1, $b2, $Sample*500/1000, ($Sample-$LastTimeStamp)*500/1000);

    
	    print sprintf("0x%04X  !=  0x%04X     %08b %08b          t=%04.1fns    TD=%1.1fns\n", $RXDATA, $CorrectValue, $MismatchMask_High, $MismatchMask_Low, $Sample*500/1000, ($Sample-$LastTimeStamp)*500/1000);
	    
	    $MismatchCount = $MismatchCount+1;
	 }
	 
	$LastTimeStamp = $Sample;
   }
   # For idle words we are sensitive to the rising edge of $RXCLK while $RXDV is low and $RXERR is low.  
   elsif ( ($LastClockValue == 0) & ($RXCLK == 1) & ($RXDV == 0) )
   {
        $IdleCount = $IdleCount+1;
   }
   # For error words we are sensitive to the rising edge of $RXCLK while RXERR is high.  
   elsif ( ($LastClockValue == 0) & ($RXCLK == 1) & ($RXERR == 1) )
   {
        $ErrorCount = $ErrorCount+1;
   }

   
   $LastClockValue = $RXCLK;
   
  }

print "\n";
print "$Count samples analysed in '$Filename':\n";
if ((2*$DataCount) == 272)
{
  print "Correct number of data bytes recognized: 272.\n";
}
else
{
  print "Wrong number of valid data bytes recognized: ".2*$DataCount." (should be 272).\n";
}
print "$MismatchCount wrong data words.\n";
print "$IdleCount idle words recognized.\n";
print "$ErrorCount error words flagged (RX-ERR bit set).\n";
print "\n";
