from extract_lines import *
import sys

def to_std_logic(num, length):
    """
    Convert the "num" numerical argument to a binary string
    over "length" bits. If num is None, make the string undefined
    ("UUUUUU.....UUUU")
    """
    out = []
    for i in range(length):
        if num == None:
            out.append('U')
        else:
            if num & (1 << i):
                out.append('1')
            else:
                out.append('0')
    out.reverse()
    return "".join(out)

def subst_coeff(matchobj):
    # Convert from signed int string to 32-bit signed int
    value = int(matchobj.group(1))    
    # Extract word width
    width = int(matchobj.group(2))
    
    return to_std_logic(value, width)
    
def extract_coeffs(inFile, outFile):
    # Read-in filter architecture file
    fin = file(inFile, "r")
    lines = fin.readlines()
    fin.close()

    # Extract filter coefficients
    coeffs = extract_lines(lines, 
        "-- Constants", # Find coeff table declaration
        "^$", # End on empty line
        # Extract value and width
        r".*to_signed\(([-+]?\b\d+\b), +([-+]?\b\d+\b)\).*",
        subst_coeff) # Use substitution function to reformat value
    
    # Find bit width from string width    
    width = len(coeffs[0])
    
    # Save coefficients
    fout = file(outFile, "w+")
    fout.write("# Filter coefficients from file %s\n" % inFile)
    fout.write("# " + "K(n)".center(width).replace(' ','-') + "\n")
    
    for coeff in coeffs:
        fout.write("  %s\n" % coeff)
    fout.close()
    
if __name__ == "__main__":
    extract_coeffs("filter.vhd", "coeffs.txt")