#! /usr/bin/perl # MIPS I system # Copyright 2011-2012 Stefan Schuermans # Copyleft GNU public license V2 or later # http://www.gnu.org/copyleft/gpl.html use strict; use warnings; require("crc32.pl"); # parse C data my @bytes = (); while (my $line = <>) { chomp $line; # tcpdump -XX if ($line =~ /^ *[0-9A-FXa-fx]+: +([0-9A-Fa-f ]+)/) { my $data = $1; $data =~ s/ .*$//; # remove ASCII in case the begin was [0-9A-Fa-f]+ $data =~ s/[^0-9A-Fa-f]//g; $data =~ s/(..)/$1,/g; for my $part (split(/,/, $data)) { if ($part =~ /^([0-9A-Fa-f]{2})/) { my $val = $1; push (@bytes, hex($val)); } } } # C data elsif ($line =~ /^ *([0-9A-FXa-fx, ]+)/) { my $data = $1; for my $part (split(/,/, $data)) { if ($part =~ /^ *0[xX]([0-9A-Fa-f]{1,2})/) { my $val = $1; push (@bytes, hex($val)); } } } } # add CRC if (@bytes >= 4) { my @bytes_no_crc = @bytes; my @crc_bytes = (); unshift (@crc_bytes, pop(@bytes_no_crc)); unshift (@crc_bytes, pop(@bytes_no_crc)); unshift (@crc_bytes, pop(@bytes_no_crc)); unshift (@crc_bytes, pop(@bytes_no_crc)); my $crc_calc = crc32([@bytes_no_crc]); my $mismatch = 0; for (my $i = 0; $i < 4; $i++) { if (shift(@crc_bytes) != shift(@{$crc_calc})) { $mismatch = 1; } } if ($mismatch) { my $crc = crc32([@bytes]); push(@bytes, @{$crc}); } else { print STDERR "warning: CRC32 already present -> not added\n"; } } else { my $crc = crc32([@bytes]); push(@bytes, @{$crc}); } # add preamble my $pos = 0; while ($pos < @bytes && $bytes[$pos] == 0x55) { $pos++; } if ($pos > 4 && $pos < @bytes && $bytes[$pos] == 0xD5) { print STDERR "warning: preamble already present -> not added\n"; } else { unshift(@bytes, 0xD5); for (my $i = 0; $i < 7; $i++) { unshift(@bytes, 0x55); } } # bytes to nibbles my @nibbles = (); foreach my $byte (@bytes) { push(@nibbles, $byte & 0xF); push(@nibbles, $byte >> 4 & 0xF); } # output VHDL data printf(" TYPE t_eth_data IS ARRAY(0 TO %u - 1) OF " . "std_logic_vector(3 DOWNTO 0);\n", @nibbles + 0); print(" CONSTANT eth_data: t_eth_data := (\n"); for (my $pos = 0; $pos < @nibbles; ) { print(" "); for (my $i = 0; $i < 8 and $pos < @nibbles; ++$i, ++$pos) { if ($pos + 1 < @nibbles) { printf(" X\"%X\",", $nibbles[$pos]); } else { printf(" X\"%X\"", $nibbles[$pos]); } } print("\n"); } print(" );\n");