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

Subversion Repositories light52

[/] [light52/] [trunk/] [tools/] [build_rom/] [src/] [build_rom.py] - Blame information for rev 20

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

Line No. Rev Author Line
1 4 ja_rd
#!/usr/bin/env python
2
"""
3
build_rom.py: Create VHDL package with ROM initialization constant from
4
Intel-HEX object code file.
5
"""
6
__author__ = "Jose A. Ruiz"
7
__license__ = "LGPL"
8
 
9
 
10
"""
11
Please see the usage instructions and the comments for function 'main'.
12
"""
13
 
14
 
15
import sys
16
import getopt
17
 
18
 
19
 
20
def usage():
21
    """Print usage instructions"""
22
    print ""
23
    print "usage:"
24
    print "python build_rom.py [arguments]\n"
25
    print "Builds VHDL ROM constant from template and Intel HEX object file.\n"
26
    print "ALL of the following arguments should be given, in any order:"
27
    print "{f|file} <filename>        Object code file name"
28
    print "{c|constant} <name>        Name of target VHDL constant"
29
    print "{p|package} <name>         Name of target VHDL package"
30
    print "{n|name} <name>            Name of project (used only in comment)"
31
    print "{o|output} <filename>      Target VHDL file name"
32
    print ""
33
    print "Additionally, any of these arguments can be given:"
34
    print "{v|vhdl} <filename>        VHDL template"
35
    print "         (defaults to templates/obj_code_kg_template.vhdl)"
36
    print "{i|indent} <number>        Indentation in VHDL tables (decimal)"
37
    print "         (defaults to 4)"
38
 
39
 
40
def help():
41
    """Print help message a bit longer than usage message."""
42
    print "\nPurpose:\n"
43
    print "Reads the code and data binary files and 'slices' them in byte"
44
    print "columns."
45
    print "The data columns are converted to VHDL strings and then inserted"
46
    print "into the vhdl template, in place of tags @code0@ .. @code3@ and "
47
    print "@data0@ .. @data3@. Column 0 is LSB and column3 is MSB.\n"
48
    print "Tags like @data31@ and @data20@ etc. can be used to initialize"
49
    print "memories in 16-bit buses, also split in byte columns.\n"
50
    print "Template tags are replaced as follows:"
51
    print "@obj_pkg_name@        : Name of package in target vhdl file."
52
    print "@const_name@          : Name of constant (VHDL table)."
53
    print "@obj_size@            : Total size of code table in bytes."
54
    print "@project@             : Project name."
55
    print "@xcode_size@          : Size of XCODE memory."
56
    print "@xdata_size@          : Size of XDATA memory."
57
 
58
def parse_hex_line(line):
59
    """Parse code line in HEX object file."""
60
    line = line.strip()
61
    slen = int(line[1:3],16)
62
    sloc = int(line[3:7],16)
63
    stype = line[7:9]
64
    sdata = line[9:len(line)-2]
65
    schk = int(line[len(line)-2:],16)
66
 
67
    csum = slen + int(sloc / 256) + (sloc % 256) + int(stype,16)
68
    bytes = [0, ] * slen
69
    for i in range(slen):
70
        sbyte = int(sdata[i*2:i*2+2],16)
71
        bytes[i] = sbyte;
72
        csum = csum + sbyte
73
 
74
    csum = ~csum
75
    csum = csum + 1
76
    csum = csum % 256
77
    if csum != schk:
78
        return (None, None)
79
 
80
    return (sloc, bytes)
81
 
82
 
83
def read_ihex_file(ihex_filename):
84
    """
85
    Read Intel HEX file into a 64KB array.
86
    The file is assumed not to have any object code outside the 64K boundary.
87
    Return the 64K array plus the size and bounds of the read data.
88
    """
89
 
90
    # CODE array, initialized to 64K of zeros...
91
    xcode = [0, ] * 65536
92
    # ...and code boundaries, initialized out of range.
93
    bottom = 100000
94
    top = -1
95
    (xcode, top, bottom)
96
 
97
    # Read the whole file to a list of lines...
98
    fin = open(ihex_filename, "r")
99
    ihex_lines = fin.readlines()
100
    fin.close()
101
 
102
    # ...and parse the lines one by one.
103
    total_bytes = 0
104
    for line in ihex_lines:
105
        (address, bytes) = parse_hex_line(line)
106
        if address == None:
107
            print "Checksum error!"
108
            sys.exit(1)
109
        total_bytes = total_bytes + len(bytes)
110
        for i in range(len(bytes)):
111
            xcode[address + i] = bytes[i]
112
 
113
        if address < bottom:
114
            bottom = address
115
 
116
        if (address + len(bytes)) > top:
117
            top = (address + len(bytes))
118
 
119
    print "Read %d bytes from file '%s'" % (total_bytes, ihex_filename)
120
    print "Code range %04xh to %04xh" % (bottom, top)
121
    return (xcode, total_bytes, bottom, top)
122
 
123
 
124
def build_vhdl_code(params, xcode, obj_size):
125
    """
126
    Read VHDL template file and replace all the tags with the values given in
127
    the command line parameters.
128
    Return the new file contents as a string.
129
    """
130
 
131
    # The resulting VHDL text will be stored here.
132
    vhdl_code = ""
133
 
134
 
135
    # Open file and read it into a list of lines.
136
    fin = open(params['template'], "r")
137
    lines = fin.readlines()
138
    fin.close()
139
 
140
    # Now process the template lines one by one.
141
    for line in lines:
142
        line = line.strip()
143
 
144
        if line.rfind("@obj_bytes@") >= 0:
145
            # insert object code as list of byte literals.
146
            obj_str = "    "
147
            for i in range(obj_size):
148
                if i != (obj_size-1):
149
                    sbyte = "X\"%02x\", " % xcode[i]
150
                else:
151
                    sbyte = "X\"%02x\" " % xcode[i]
152
                obj_str = obj_str + sbyte
153
                if (i % 8) == 7:
154
                    obj_str = obj_str + "\n    "
155
 
156
            line = line.replace("@obj_bytes@",obj_str)
157
 
158
        elif line.rfind("@obj_size@") >= 0:
159
            # Insert object code size (not necessarily equal to xcode_size)
160
            line = line.replace("@obj_size@","%d" % (obj_size-1))
161
 
162
        elif line.rfind("@xcode_size@") >= 0:
163
            # Insert XCODE memory
164
            line = line.replace("@xcode_size@","%d" % (params['xcode_size']))
165
 
166
        elif line.rfind("@xdata_size@") >= 0:
167
            # Insert XDATA memory
168
            line = line.replace("@xdata_size@","%d" % (params['xdata_size']))
169
 
170
        elif line.rfind("@obj_pkg_name@") >= 0:
171
            # Insert package name: hardwired
172
            line = line.replace("@obj_pkg_name@",params['package'])
173
 
174
        elif line.rfind("@project_name@") >= 0:
175
            # Insert project name 
176
            line = line.replace("@project_name@",params['project'])
177
 
178
 
179
        vhdl_code = vhdl_code + line + "\n"
180
 
181
    return vhdl_code
182
 
183
 
184
def main(argv):
185
    """Main body of the program."""
186
 
187
    # Parse command line parameters using GetOpt 
188
    try:
189
        opts, args = getopt.getopt(argv, "hf:n:p:c:o:i:v:",
190
        ["help", "file=", "name=", "package=", "constant=",
191
         "output=", "indent=", "vhdl=", "xcode=", "xdata=" ])
192
    except getopt.GetoptError, err:
193
        print ""
194
        print err
195
        usage()
196
        sys.exit(2)
197
 
198
    # Command line parameters, initialized to their default values
199
    params = {'project':    '<unknown>',
200
              'package':    'obj_code_pkg',
201
              'indent':     4,
202
              'constant':   'obj_code',
203
              'target':     'obj_code_pkg.vhdl',
204
              'hex':        '',
205
              'xcode_size': 2048,
206
              'xdata_size': 0,
207
              'template':   "./templates/obj_code_pkg_template.vhdl"
208
              }
209
 
210
 
211
    # Parse coommand line parameters
212
    for opt, arg in opts:
213
        if opt in ("-h", "--help"):
214
            usage()
215
            help()
216
            exit(1)
217
        if opt in ("-v", "--vhdl"):
218
            params['template'] = arg
219
        elif opt in ("-o", "--output"):
220
            params['target'] = arg
221
        elif opt in ("-c", "--constant"):
222
            params['constant'] = arg
223
        elif opt in ("-f", "--file"):
224
            params['hex'] = arg
225
        elif opt in ("-p", "--package"):
226
            params['package'] = arg
227
        elif opt in ("-n", "--name"):
228
            params['project'] = arg
229
        elif opt in ("-i", "--indent"):
230
            params['indent'] = int(arg)
231
        elif opt in ("--xcode"):
232
            params['xcode_size'] = int(arg)
233
        elif opt in ("--xdata"):
234
            params['xdata_size'] = int(arg)
235
 
236
    # Ok, now 
237
    if params['hex']:
238
        (xcode, total_bytes, bottom, top) = read_ihex_file(params['hex']);
239
    else:
240
        print "Object HEX file name missing.";
241
        usage()
242
        return 1
243
 
244
 
245
    # Make sure the object code fits the implemented XCODE space.
246
    # If it doesn't, print a warning and let the user deal with it.
247
    # Assuming that XCODE starts at address zero -- that's how the core works.
248
    if params['xcode_size'] < top:
249
        print "\nWARNING: Object code does not fit XCODE space!\n"
250
 
251
 
252
    # Build the package source...
253
    vhdl_code = build_vhdl_code(params, xcode, top);
254
 
255
    # ...and write it to the target file.
256
    fout = None
257
    try:
258
        fout = open(params['target'], "w")
259
        fout.write(vhdl_code)
260
        fout.close()
261
        print "VHDL code table written to %s" % params['target']
262
    except:
263
        print "Trouble opening %s for output" % params['target']
264
    finally:
265
        if fout: fout.close()
266
 
267
 
268
if __name__ == "__main__":
269
    main(sys.argv[1:])
270
    sys.exit(0)
271
 
272
 

powered by: WebSVN 2.1.0

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