OpenCores
URL https://opencores.org/ocsvn/light52/light52/trunk

Subversion Repositories light52

[/] [light52/] [trunk/] [tools/] [build_rom/] [src/] [build_rom.py] - Diff between revs 4 and 22

Only display areas with differences | Details | Blame | View Log

Rev 4 Rev 22
#!/usr/bin/env python
#!/usr/bin/env python
"""
"""
build_rom.py: Create VHDL package with ROM initialization constant from
build_rom.py: Create VHDL package with ROM initialization constant from
Intel-HEX object code file.
Intel-HEX object code file.
 
Please use with --help to get some brief usage instructions.
"""
"""
__author__ = "Jose A. Ruiz"
__author__ = "Jose A. Ruiz"
__license__ = "LGPL"
__license__ = "LGPL"
 
 
 
 
"""
"""
Please see the usage instructions and the comments for function 'main'.
Please see the usage instructions and the comments for function 'main'.
"""
"""
 
 
 
 
import sys
import sys
import getopt
import getopt
 
 
 
 
 
 
def usage():
def usage():
    """Print usage instructions"""
    """Print usage instructions"""
    print ""
    print ""
    print "usage:"
    print "usage:"
    print "python build_rom.py [arguments]\n"
    print "python build_rom.py [arguments]\n"
    print "Builds VHDL ROM constant from template and Intel HEX object file.\n"
    print "Builds VHDL ROM constant from template and Intel HEX object file.\n"
    print "ALL of the following arguments should be given, in any order:"
    print "ALL of the following arguments should be given, in any order:"
    print "{f|file} <filename>        Object code file name"
    print "{f|file} <filename>        Object code file name"
    print "{c|constant} <name>        Name of target VHDL constant"
 
    print "{p|package} <name>         Name of target VHDL package"
 
    print "{n|name} <name>            Name of project (used only in comment)"
 
    print "{o|output} <filename>      Target VHDL file name"
 
    print ""
    print ""
    print "Additionally, any of these arguments can be given:"
    print "Additionally, any of these arguments can be given:"
 
    print "{h|help}                   Show help string and exit"
 
    print "{c|constant} <name>        Name of target VHDL object code constant"
 
    print "{p|package} <name>         Name of target VHDL package"
 
    print "{n|name} <name>            Name of project (used only in comments)"
 
    print "{o|output} <filename>      Target VHDL file name"
 
    print "{xcode} <number>           Size of XCODE memory in bytes"
 
    print "         (defaults to 2048)"
 
    print "{xdata} <number>           Size of XDATA memory in bytes"
 
    print "         (defaults to 0)"
    print "{v|vhdl} <filename>        VHDL template"
    print "{v|vhdl} <filename>        VHDL template"
    print "         (defaults to templates/obj_code_kg_template.vhdl)"
    print "         (defaults to templates/obj_code_kg_template.vhdl)"
    print "{i|indent} <number>        Indentation in VHDL tables (decimal)"
    print "{i|indent} <number>        Indentation in VHDL tables (decimal)"
    print "         (defaults to 4)"
    print "         (defaults to 4)"
 
 
 
 
 
 
def help():
def help():
    """Print help message a bit longer than usage message."""
    """Print help message a bit longer than usage message."""
    print "\nPurpose:\n"
    print "\nPurpose:\n"
    print "Reads the code and data binary files and 'slices' them in byte"
    print "Builds initialization package for Light52 MCU core."
    print "columns."
    print "The object code bytes are converted to VHDL strings and then inserted"
    print "The data columns are converted to VHDL strings and then inserted"
    print "into the vhdl template, in place of tag @code_bytes@.\n"
    print "into the vhdl template, in place of tags @code0@ .. @code3@ and "
 
    print "@data0@ .. @data3@. Column 0 is LSB and column3 is MSB.\n"
 
    print "Tags like @data31@ and @data20@ etc. can be used to initialize"
 
    print "memories in 16-bit buses, also split in byte columns.\n"
 
    print "Template tags are replaced as follows:"
    print "Template tags are replaced as follows:"
    print "@obj_pkg_name@        : Name of package in target vhdl file."
    print "@obj_pkg_name@        : Name of package in target vhdl file."
    print "@const_name@          : Name of constant (VHDL table)."
    print "@const_name@          : Name of object code constant (VHDL table)."
    print "@obj_size@            : Total size of code table in bytes."
    print "@obj_size@            : Total size of code table in bytes."
    print "@project@             : Project name."
    print "@obj_bytes@           : Array of object code bytes."
 
    print "@project_name@        : Project name."
    print "@xcode_size@          : Size of XCODE memory."
    print "@xcode_size@          : Size of XCODE memory."
    print "@xdata_size@          : Size of XDATA memory."
    print "@xdata_size@          : Size of XDATA memory."
 
 
def parse_hex_line(line):
def parse_hex_line(line):
    """Parse code line in HEX object file."""
    """Parse code line in HEX object file."""
    line = line.strip()
    line = line.strip()
    slen = int(line[1:3],16)
    slen = int(line[1:3],16)
    sloc = int(line[3:7],16)
    sloc = int(line[3:7],16)
    stype = line[7:9]
    stype = line[7:9]
    sdata = line[9:len(line)-2]
    sdata = line[9:len(line)-2]
    schk = int(line[len(line)-2:],16)
    schk = int(line[len(line)-2:],16)
 
 
    csum = slen + int(sloc / 256) + (sloc % 256) + int(stype,16)
    csum = slen + int(sloc / 256) + (sloc % 256) + int(stype,16)
    bytes = [0, ] * slen
    bytes = [0, ] * slen
    for i in range(slen):
    for i in range(slen):
        sbyte = int(sdata[i*2:i*2+2],16)
        sbyte = int(sdata[i*2:i*2+2],16)
        bytes[i] = sbyte;
        bytes[i] = sbyte;
        csum = csum + sbyte
        csum = csum + sbyte
 
 
    csum = ~csum
    csum = ~csum
    csum = csum + 1
    csum = csum + 1
    csum = csum % 256
    csum = csum % 256
    if csum != schk:
    if csum != schk:
        return (None, None)
        return (None, None)
 
 
    return (sloc, bytes)
    return (sloc, bytes)
 
 
 
 
def read_ihex_file(ihex_filename):
def read_ihex_file(ihex_filename):
    """
    """
    Read Intel HEX file into a 64KB array.
    Read Intel HEX file into a 64KB array.
    The file is assumed not to have any object code outside the 64K boundary.
    The file is assumed not to have any object code outside the 64K boundary.
    Return the 64K array plus the size and bounds of the read data.
    Return the 64K array plus the size and bounds of the read data.
    """
    """
 
 
    # CODE array, initialized to 64K of zeros...
    # CODE array, initialized to 64K of zeros...
    xcode = [0, ] * 65536
    xcode = [0, ] * 65536
    # ...and code boundaries, initialized out of range.
    # ...and code boundaries, initialized out of range.
    bottom = 100000
    bottom = 100000
    top = -1
    top = -1
    (xcode, top, bottom)
    (xcode, top, bottom)
 
 
    # Read the whole file to a list of lines...
    # Read the whole file to a list of lines...
    fin = open(ihex_filename, "r")
    fin = open(ihex_filename, "r")
    ihex_lines = fin.readlines()
    ihex_lines = fin.readlines()
    fin.close()
    fin.close()
 
 
    # ...and parse the lines one by one.
    # ...and parse the lines one by one.
    total_bytes = 0
    total_bytes = 0
    for line in ihex_lines:
    for line in ihex_lines:
        (address, bytes) = parse_hex_line(line)
        (address, bytes) = parse_hex_line(line)
        if address == None:
        if address == None:
            print "Checksum error!"
            print "Checksum error!"
            sys.exit(1)
            sys.exit(1)
        total_bytes = total_bytes + len(bytes)
        total_bytes = total_bytes + len(bytes)
        for i in range(len(bytes)):
        for i in range(len(bytes)):
            xcode[address + i] = bytes[i]
            xcode[address + i] = bytes[i]
 
 
        if address < bottom:
        if address < bottom:
            bottom = address
            bottom = address
 
 
        if (address + len(bytes)) > top:
        if (address + len(bytes)) > top:
            top = (address + len(bytes))
            top = (address + len(bytes))
 
 
    print "Read %d bytes from file '%s'" % (total_bytes, ihex_filename)
    print "Read %d bytes from file '%s'" % (total_bytes, ihex_filename)
    print "Code range %04xh to %04xh" % (bottom, top)
    print "Code range %04xh to %04xh" % (bottom, top)
    return (xcode, total_bytes, bottom, top)
    return (xcode, total_bytes, bottom, top)
 
 
 
 
def build_vhdl_code(params, xcode, obj_size):
def build_vhdl_code(params, xcode, obj_size):
    """
    """
    Read VHDL template file and replace all the tags with the values given in
    Read VHDL template file and replace all the tags with the values given in
    the command line parameters.
    the command line parameters.
    Return the new file contents as a string.
    Return the new file contents as a string.
    """
    """
 
 
    # The resulting VHDL text will be stored here.
    # The resulting VHDL text will be stored here.
    vhdl_code = ""
    vhdl_code = ""
 
 
 
 
    # Open file and read it into a list of lines.
    # Open file and read it into a list of lines.
    fin = open(params['template'], "r")
    fin = open(params['template'], "r")
    lines = fin.readlines()
    lines = fin.readlines()
    fin.close()
    fin.close()
 
 
    # Now process the template lines one by one.
    # Now process the template lines one by one.
    for line in lines:
    for line in lines:
        line = line.strip()
        line = line.strip()
 
 
        if line.rfind("@obj_bytes@") >= 0:
        if line.rfind("@obj_bytes@") >= 0:
            # insert object code as list of byte literals.
            # insert object code as list of byte literals.
            obj_str = "    "
            obj_str = "    "
            for i in range(obj_size):
            for i in range(obj_size):
                if i != (obj_size-1):
                if i != (obj_size-1):
                    sbyte = "X\"%02x\", " % xcode[i]
                    sbyte = "X\"%02x\", " % xcode[i]
                else:
                else:
                    sbyte = "X\"%02x\" " % xcode[i]
                    sbyte = "X\"%02x\" " % xcode[i]
                obj_str = obj_str + sbyte
                obj_str = obj_str + sbyte
                if (i % 8) == 7:
                if (i % 8) == 7:
                    obj_str = obj_str + "\n    "
                    obj_str = obj_str + "\n    "
 
 
            line = line.replace("@obj_bytes@",obj_str)
            line = line.replace("@obj_bytes@",obj_str)
 
 
        elif line.rfind("@obj_size@") >= 0:
        elif line.rfind("@obj_size@") >= 0:
            # Insert object code size (not necessarily equal to xcode_size)
            # Insert object code size (not necessarily equal to xcode_size)
            line = line.replace("@obj_size@","%d" % (obj_size-1))
            line = line.replace("@obj_size@","%d" % (obj_size-1))
 
 
        elif line.rfind("@xcode_size@") >= 0:
        elif line.rfind("@xcode_size@") >= 0:
            # Insert XCODE memory
            # Insert XCODE memory
            line = line.replace("@xcode_size@","%d" % (params['xcode_size']))
            line = line.replace("@xcode_size@","%d" % (params['xcode_size']))
 
 
        elif line.rfind("@xdata_size@") >= 0:
        elif line.rfind("@xdata_size@") >= 0:
            # Insert XDATA memory
            # Insert XDATA memory
            line = line.replace("@xdata_size@","%d" % (params['xdata_size']))
            line = line.replace("@xdata_size@","%d" % (params['xdata_size']))
 
 
        elif line.rfind("@obj_pkg_name@") >= 0:
        elif line.rfind("@obj_pkg_name@") >= 0:
            # Insert package name: hardwired
            # Insert package name: hardwired
            line = line.replace("@obj_pkg_name@",params['package'])
            line = line.replace("@obj_pkg_name@",params['package'])
 
 
        elif line.rfind("@project_name@") >= 0:
        elif line.rfind("@project_name@") >= 0:
            # Insert project name 
            # Insert project name 
            line = line.replace("@project_name@",params['project'])
            line = line.replace("@project_name@",params['project'])
 
 
 
 
        vhdl_code = vhdl_code + line + "\n"
        vhdl_code = vhdl_code + line + "\n"
 
 
    return vhdl_code
    return vhdl_code
 
 
 
 
def main(argv):
def main(argv):
    """Main body of the program."""
    """Main body of the program."""
 
 
    # Parse command line parameters using GetOpt 
    # Parse command line parameters using GetOpt 
    try:
    try:
        opts, args = getopt.getopt(argv, "hf:n:p:c:o:i:v:",
        opts, args = getopt.getopt(argv, "hf:n:p:c:o:i:v:",
        ["help", "file=", "name=", "package=", "constant=",
        ["help", "file=", "name=", "package=", "constant=",
         "output=", "indent=", "vhdl=", "xcode=", "xdata=" ])
         "output=", "indent=", "vhdl=", "xcode=", "xdata=" ])
    except getopt.GetoptError, err:
    except getopt.GetoptError, err:
        print ""
        print ""
        print err
        print err
        usage()
        usage()
        sys.exit(2)
        sys.exit(2)
 
 
    # Command line parameters, initialized to their default values
    # Command line parameters, initialized to their default values
    params = {'project':    '<unknown>',
    params = {'project':    '<unknown>',
              'package':    'obj_code_pkg',
              'package':    'obj_code_pkg',
              'indent':     4,
              'indent':     4,
              'constant':   'obj_code',
              'constant':   'obj_code',
              'target':     'obj_code_pkg.vhdl',
              'target':     'obj_code_pkg.vhdl',
              'hex':        '',
              'hex':        '',
              'xcode_size': 2048,
              'xcode_size': 2048,
              'xdata_size': 0,
              'xdata_size': 0,
              'template':   "./templates/obj_code_pkg_template.vhdl"
              'template':   "./templates/obj_code_pkg_template.vhdl"
              }
              }
 
 
 
 
    # Parse coommand line parameters
    # Parse coommand line parameters
    for opt, arg in opts:
    for opt, arg in opts:
        if opt in ("-h", "--help"):
        if opt in ("-h", "--help"):
            usage()
            usage()
            help()
            help()
            exit(1)
            exit(1)
        if opt in ("-v", "--vhdl"):
        if opt in ("-v", "--vhdl"):
            params['template'] = arg
            params['template'] = arg
        elif opt in ("-o", "--output"):
        elif opt in ("-o", "--output"):
            params['target'] = arg
            params['target'] = arg
        elif opt in ("-c", "--constant"):
        elif opt in ("-c", "--constant"):
            params['constant'] = arg
            params['constant'] = arg
        elif opt in ("-f", "--file"):
        elif opt in ("-f", "--file"):
            params['hex'] = arg
            params['hex'] = arg
        elif opt in ("-p", "--package"):
        elif opt in ("-p", "--package"):
            params['package'] = arg
            params['package'] = arg
        elif opt in ("-n", "--name"):
        elif opt in ("-n", "--name"):
            params['project'] = arg
            params['project'] = arg
        elif opt in ("-i", "--indent"):
        elif opt in ("-i", "--indent"):
            params['indent'] = int(arg)
            params['indent'] = int(arg)
        elif opt in ("--xcode"):
        elif opt in ("--xcode"):
            params['xcode_size'] = int(arg)
            params['xcode_size'] = int(arg)
        elif opt in ("--xdata"):
        elif opt in ("--xdata"):
            params['xdata_size'] = int(arg)
            params['xdata_size'] = int(arg)
 
 
    # Ok, now 
    # Ok, now read and parse the input Intel HEX object code file.
    if params['hex']:
    if params['hex']:
        (xcode, total_bytes, bottom, top) = read_ihex_file(params['hex']);
        (xcode, total_bytes, bottom, top) = read_ihex_file(params['hex']);
    else:
    else:
        print "Object HEX file name missing.";
        print "Object HEX file name missing.";
        usage()
        usage()
        return 1
        return 1
 
 
 
 
    # Make sure the object code fits the implemented XCODE space.
    # Make sure the object code fits into the implemented XCODE space.
    # If it doesn't, print a warning and let the user deal with it.
    # If it doesn't, print a warning and let the user deal with it.
    # Assuming that XCODE starts at address zero -- that's how the core works.
    # Assuming that XCODE starts at address zero -- that's how the core works.
    if params['xcode_size'] < top:
    if params['xcode_size'] < top:
        print "\nWARNING: Object code does not fit XCODE space!\n"
        print "\nWARNING: Object code does not fit XCODE space!\n"
 
 
 
 
    # Build the package source...
    # Build the package source...
    vhdl_code = build_vhdl_code(params, xcode, top);
    vhdl_code = build_vhdl_code(params, xcode, top);
 
 
    # ...and write it to the target file.
    # ...and write it to the target file.
    fout = None
    fout = None
    try:
    try:
        fout = open(params['target'], "w")
        fout = open(params['target'], "w")
        fout.write(vhdl_code)
        fout.write(vhdl_code)
        fout.close()
        fout.close()
        print "VHDL code table written to %s" % params['target']
        print "VHDL code table written to %s" % params['target']
    except:
    except:
        print "Trouble opening %s for output" % params['target']
        print "Trouble opening %s for output" % params['target']
    finally:
    finally:
        if fout: fout.close()
        if fout: fout.close()
 
 
 
 
if __name__ == "__main__":
if __name__ == "__main__":
    main(sys.argv[1:])
    main(sys.argv[1:])
    sys.exit(0)
    sys.exit(0)
 
 
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.