#!/usr/bin/perl #------------------------------------------------------------------------------ # Xilinx .COE to .MIF Converter Module # filename: coe_dec2hex.pl # # by Jeremy Webb # # Rev 1.0, April 14, 2006 # # This utility is intended to convert a Xilinx Coefficient File (.COE) # to a Xilinx Memory Initialization File (.MIF) file. This script # basically converts base 10 integers to hexadecimal values. This script # defaults to 18-bit resolution for the dec2hex conversion. # # Revision History: # 1.0 04/14/2006 Initial release # # Please report bugs, errors, etc. #------------------------------------------------------------------------------ # Package and Command Setup: use strict; use Toolbox::Simple qw(dec2hex); # Retrieve command line argument my $file = $ARGV[0]; # COE File my $resin = $ARGV[1]; # Defaults to 18: # Initialize Variables: my $res; # Hexadecimal Bit Resolution. if ($file eq "") { print_usage(); exit 1; } elsif ($file eq "HELP") { print_help(); exit 1; } if ($resin eq "") { $res = 18; } else { $res = $resin; } # Determine number of hex digits in MIF file. my $base2pwr = 2**$res; my $pwrhex = dec2hex($base2pwr); my @pwrchars = split("",$pwrhex); my $pwrcharcnt = scalar(@pwrchars); my $fullhex = $pwrcharcnt * 4; my $diffhex = $fullhex - $res; # Open file for reading: open inF, "< $file" or die "Can't open $file : $!"; my (@data) = ; # Strip the .v from the file name and use for the module name: $file =~ s/\.coe$//; my @newdata; foreach my $i (@data) { chomp($i); if ($i =~ m/\x3D/) { $i =~ s/\x3D//; } else { $i =~ s/\x2c//; $i =~ s/\x3B//; push(@newdata,$i); #print("$i\n"); } # print("$i\n"); } my $newfile = join ".", $file, "mif"; # check to make sure that the file doesn't exist. die "Oops! A file called '$newfile' already exists.\n" if -e $newfile; # Open Hex File: open(my $hexfile, ">", $newfile); my @hexdata_long; my $lines = scalar(@newdata); my $line = 0; for ($line = 0; $line < $lines; $line++) { my $decval = $newdata[$line]; my $newhex = dec2hex($decval); #print($hexfile "$newhex\n"); #print("$newhex\n"); push(@hexdata_long, $newhex); } my @chars; my @hexchars; my @hexdata_short; my $lines = scalar(@hexdata_long); my $line = 0; for ($line = 0; $line < $lines; $line++) { my $hexdata = $hexdata_long[$line]; @chars = split("",$hexdata); my $charcnt = scalar(@chars); if ($charcnt < $pwrcharcnt) { my $charnew = $pwrcharcnt - $charcnt; # Create a string containing $charnew zeros. my $zeros = (0) x $charnew; # Prepend the string of zeros to the hex data. my $newhex = join "", $zeros,$hexdata; #print("$newhex, $charnew, $charcnt, $zeros\n"); # Push the new hex data onto the array: push(@hexdata_short, $newhex); } elsif ($charcnt > $pwrcharcnt) { my $charnew = $charcnt - $pwrcharcnt; # Create a string containing $charnew ones. my $ones = ("F") x $charnew; # Separate the leading "F"'s in the hex data: my $newhex; ($newhex = $hexdata) =~ s/$ones//i; #print "Hex: $newhex\n"; # Cut-off hex value to the resolution requested: # Convert the hex value back to decimal: my $newdec = hex($newhex); #print "New Decimal: $newdec\n"; # Convert the decimal number into binary: my $binhex = sprintf("%b", $newdec); #print "New Binary: $binhex\n"; # Split the binary number into individual bits: my @binchars = split("",$binhex); # Determine the number of binary bits: my $bincharcnt = scalar(@binchars); #print "Binary Bit Count: $bincharcnt\n"; # Combine the binary numbers: my $last = $fullhex - 1; my $combdbin = join("",@binchars[$diffhex...$last]); # Convert the binary number to a decimal: my $combdhex = oct("0b" . $combdbin); # Convert the decimal number back to a hexadecimal: my $comb = sprintf("%X",$combdhex); #print "New Hex: $comb\n"; # Push the new hex data onto the array: push(@hexdata_short, $comb); } else { push(@hexdata_short, $hexdata); #print("$hexdata\n"); } } foreach my $i (@hexdata_short) { print("\U$i\E\n"); print($hexfile "\U$i\E\n"); } close($hexfile); exit; #------------------------------------------------------------------------------ # Generic Error and Exit routine #------------------------------------------------------------------------------ sub dienice { my($errmsg) = @_; print"$errmsg\n"; exit; } sub print_usage { print("\nUsage: coe_dec2hex.pl [FILE] [RES]\n"); print("\n"); print("Options:\n"); print("\tFILE\tWhere FILE is the Xilinx Coefficient File (*.coe) containing base-10 numbers.\n"); print("\tRES\tHexadecimal Resolution in bits. For example, 18. DEFAULT: 18\n"); print("\n"); print("\tHELP\tType: coe_dec2hex.pl HELP, to display information about this script.\n"); print("\n"); return; } sub print_help { print("\nCOE_DEC2HEX.PL HELP \n"); print("\n"); print("This utility is intended to convert a Xilinx Coefficient File (.COE) \n"); print("to a Xilinx Memory Initialization File (.MIF) file. This script \n"); print("basically converts base 10 integers to hexadecimal values. This script\n"); print("defaults to 18-bit resolution for the decimal-to-hexadecimal conversion.\n"); print("\n"); return; }