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

Subversion Repositories light52

[/] [light52/] [trunk/] [tools/] [build_rom/] [src/] [build_rom.py] - Rev 20

Go to most recent revision | Compare with Previous | Blame | View Log

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

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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