#!/usr/bin/env python3 # Tool for converting width of verilog hex files import sys import argparse import re # Assume little-endian, and that widths are multiples of 4 def width_convert(ilines, width, base): olines = [] pad_fmt = "{:>0" + str(width // 4) + "}" accum = "" for l in ilines: if l.startswith("@"): if len(accum): olines.append(pad_fmt.format(accum)) accum = "" # TODO: address scaling wrong if input not byte-sized: olines.append("@{:x}".format((int(l[1:], 16) - base) // (width // 8))) continue for num in re.findall(r"[0-9a-fA-F]+", l): accum = num + accum while len(accum) >= width // 4: olines.append(accum[len(accum) - width // 4 :]) accum = accum[:len(accum) - width // 4] if len(accum): olines.append(pad_fmt.format(accum)) return olines def parseint(arg, name, default): if arg is None: arg = default try: if type(arg) is str and arg.startswith("0x"): arg = int(arg, 16) else: arg = int(arg) except ValueError: sys.exit("Invalid value for {}: {}".format(name, arg)) return arg if __name__ == "__main__": parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument("input", help="Input file name") parser.add_argument("--width", "-w", help="Output hex width (default 32)") parser.add_argument("--base", "-b", help="Base address for @ commands (subtracted)") parser.add_argument("--output", "-o", help="Output file name") args = parser.parse_args() if args.output is None: ofile = sys.stdout else: ofile = open(args.output, "w") if args.input is None: ifile = sys.stdin else: ifile = open(args.input) width = parseint(args.width, "width", 32) base = parseint(args.base, "base", 0) olines = width_convert(ifile, width, base) for l in olines: ofile.write(l + "\n")