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

Subversion Repositories ion

[/] [ion/] [trunk/] [tools/] [build_pkg/] [build_pkg.py] - Blame information for rev 247

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

Line No. Rev Author Line
1 220 ja_rd
"""
2
    build_pkg.py -- builds simulation and synthesis configuration package.
3
 
4
    The generated package contains configuration constants used by the
5
    simulation test bench 'mips_tb.vhdl' and by the hardware demo
6
    'c2sb_demo.vhdl'.
7
 
8
    It too includes memory initialization constants containing object code,
9
    used to initialize simulated and inferred memories, both in simulation
10
    and in synthesis.
11
 
12
    In the code samples, this script is used to generate two separate packages
13
    for simulation and synthesis. Please refer to the makefiles for detailed
14
    usage examples.
15
"""
16
 
17
import sys
18
import os
19
import getopt
20
 
21
 
22
 
23
def usage():
24
    """Print usage instructions"""
25
    print ""
26
    print "usage:"
27
    print "python build_pkg.py [arguments]\n"
28
    print "Builds VHDL package from template and binary object files.\n"
29
    print "The following arguments can be given, in any order:"
30
    print ""
31
    print "{b|bin} <filename>         Object code file name (Plain binary)"
32
    print "{n|name} <name>            Name of object code constant"
33
    print "{p|package} <name>         Name of target VHDL package"
34
    print "{project} <name>           Name of project (used only in comment)"
35
    print "{o|output} <filename>      Target VHDL file name"
36
    print "{v|vhdl} <filename>        VHDL template"
37
    print "         (defaults to templates/obj_code_kg_template.vhdl)"
38
    print "{i|indent} <number>        Indentation in VHDL tables (decimal)"
39
    print "         (defaults to 4)"
40
    print "{o|output} <filename>      Target VHDL file name"
41
    print "{t|templates} <path>       Path of VHDL template directory"
42
    print "         (defaults to '../templates')"
43
    print ""
44
    print "The following optional parameters will define a constant in the VHDL"
45
    print "package if they are used (simulation configuration):"
46
    print ""
47
    print "{s|sim_length} <value>     Value of SIMULATION_LENGTH constant."
48
    print "{log_trigger} <value>      Value of LOG_TRIGGER_ADDRESS constant."
49
    print "{xram_size} <value>        Value of SRAM_SIZE constant."
50
    print "{flash_size} <value>       Value of PROM_SIZE constant."
51
    print "{xram_size} <value>        Value of SRAM_SIZE constant."
52
    print ""
53
    print "The following optional parameters will define a constant in the VHDL"
54
    print "package if they are used (simulation and synthesis configuration):"
55
    print ""
56
    print "{bram_size} <value>        Value of BRAM_SIZE constant."
57
 
58
 
59
def help():
60
    """Print help message a bit longer than the usage message."""
61
    print "\nPurpose:\n"
62
    print "Builds a VHDL package with configuration constants used in the "
63
    print "simulation test bench and in the synthesis of the SoC entity."
64
    print ""
65
    print "The package file is built from a template (presumably the template"
66
    print "included with this tool)."
67
    print ""
68
    print "See the makefiles of the code samples for usage examples."
69
 
70
 
71
def parse_hex_line(line):
72
    """Parse code line in HEX object file."""
73
    line = line.strip()
74
    slen = int(line[1:3],16)
75
    sloc = int(line[3:7],16)
76
    stype = line[7:9]
77
    sdata = line[9:len(line)-2]
78
    schk = int(line[len(line)-2:],16)
79
 
80
    csum = slen + int(sloc / 256) + (sloc % 256) + int(stype,16)
81
    bytes = [0, ] * slen
82
    for i in range(slen):
83
        sbyte = int(sdata[i*2:i*2+2],16)
84
        bytes[i] = sbyte;
85
        csum = csum + sbyte
86
 
87
    csum = ~csum
88
    csum = csum + 1
89
    csum = csum % 256
90
    if csum != schk:
91
        return (None, None)
92
 
93
    return (sloc, bytes)
94
 
95
 
96
 
97
def read_bin_file(bin_filename):
98
    """
99
    Read binary file into a byte array.
100
    Returns (code, size, bottom, top), where:
101
 
102
    code = array of bytes in file order (endianess irrelevant).
103
    size = number of bytes read from file.
104
    bottom = always zero.
105
    top = size - 1
106
    """
107
    objcode = [0, ] * 128*1024 # FIXME arbitrary limit should be removed
108
    bottom = 0
109
    top = -1
110
    #(objcode, top, bottom)
111
 
112
    # Read binary file
113
    f = open(bin_filename, "rb")
114
    try:
115
        size = os.path.getsize(bin_filename)
116
        objcode = [0, ] * size
117
        i = 0
118
        byte = f.read(1)
119
        while byte != "":
120
            objcode[i] = ord(byte)
121
            # Do stuff with byte.
122
            byte = f.read(1)
123
            i = i + 1
124
    finally:
125
            f.close()
126
 
127
    top = i-1
128
    total_bytes = i
129
    print "Read %d bytes from file '%s'" % (total_bytes, bin_filename)
130
    return (objcode, total_bytes, bottom, top)
131
 
132
 
133
def defined(pkg, val):
134
 
135
    return pkg.has_key(val) and pkg[val]
136
 
137
 
138
 
139
def build_vhdl_code(template_filename, blocks, package_params):
140
 
141
    fin = open(template_filename, "r")
142
    lines = fin.readlines()
143
    fin.close()
144
 
145
    vhdl_code = ""
146
 
147
    for line in lines:
148
        line = line.strip()
149
 
150
        while(True):
151
            if line.rfind("@obj_tables@") >= 0:
152
                obj_str = "";
153
                for block in blocks:
154
                    block_size = block['top']
155
                    block_data = block['data']
156
                    if not block.has_key('constant_name'):
157
                        print "Missing initialization constant name"
158
                        sys.exit(2)
159
                    block_name = block['constant_name']
160
                    block_top = block['top']
161
 
162
                    if block_top <= 0:
163
                        # If the array is empty, we need to use special syntax 
164
                        obj_str = obj_str + \
165
                                  ("constant %s : t_obj_code(0 to 0) := " + \
166
                                  "(others => X\"00\");\n") % block_name
167
                    else:
168
                        # Array contains binary data from file: write it
169
                        obj_str = obj_str + \
170
                                  "constant %s : t_obj_code(0 to %d) := (\n" % \
171
                                  (block_name, block_top-1)
172
                        obj_str = obj_str + " "*package_params['indent']
173
                        for i in range(block_size):
174
                            if i != (block_size-1):
175
                                sbyte = "X\"%02x\", " % block_data[i]
176
                            else:
177
                                sbyte = "X\"%02x\" " % block_data[i]
178
                            obj_str = obj_str + sbyte
179
                            if (i % 8) == 7:
180
                                obj_str = obj_str + "\n" + " "*package_params['indent']
181
                        obj_str = obj_str + ");\n\n"
182
 
183
                line = line.replace("@obj_tables@",obj_str)
184
            elif line.rfind("@constants@") >= 0:
185
                str = ""
186
 
187
                if defined(package_params, 'sim_length'):
188
                    str = str + \
189
                          "constant SIMULATION_LENGTH : integer := %d;\n" % \
190
                          int(package_params['sim_length'])
191
                if defined(package_params,'trigger_address'):
192
                    str = str + \
193
                          "constant LOG_TRIGGER_ADDRESS : t_word := X\"%08x\";\n" % \
194
                          int(package_params['trigger_address'],16)
195
                if defined(package_params,'xram_size'):
196
                    str = str + \
197
                          "constant SRAM_SIZE : integer := %d;\n" % \
198
                          int(package_params['xram_size'])
199
                if defined(package_params,'flash_size'):
200
                    str = str + \
201
                          "constant PROM_SIZE : integer := %d;\n" % \
202
                          int(package_params['flash_size'])
203
                if defined(package_params,'boot_bram_size'):
204
                    str = str + \
205
                          "constant BRAM_SIZE : integer := %d;\n" % \
206
                          int(package_params['boot_bram_size'])
207
 
208
                line = line.replace("@constants@", str)
209
            elif line.rfind("@project_name@") >= 0:
210
                line = line.replace("@project_name@",package_params['proj_name'])
211
            elif line.rfind("@obj_pkg_name@") >= 0:
212
                line = line.replace("@obj_pkg_name@",package_params['package_name'])
213
            else:
214
                break
215
 
216
        vhdl_code = vhdl_code + line + "\n"
217
 
218
    return vhdl_code
219
 
220
 
221
def main(argv):
222
 
223
    try:
224
        opts, _ = getopt.getopt(argv, "hp:c:o:i:v:b:t:n:s:",
225
        ["help", "package=", "constant=",
226
         "output=", "indent=", "vhdl=", "bin=", "templates=",
227
         "name=", "sim_length=",
228
         # parameters with no short-form
229
         "project=", "log_trigger=", "xram_size=", "flash_size=",
230
         "bram_size=",
231
         "empty"])
232
    except getopt.GetoptError, err:
233
        print ""
234
        print err
235
        usage()
236
        sys.exit(2)
237
 
238
    # Set default values for all command line parameters
239
    template_dir_name = "../templates"
240
    vhdl_filename = "obj_code_pkg_template.vhdl"
241
    target_filename = None
242
 
243
    package_params = {
244 232 ja_rd
        'boot_bram_size': 1024,
245 220 ja_rd
        'xram_size': 0,
246
        'flash_size': 0,
247
        'trigger_address': None,
248
        'indent': 2,
249
        'project_name': "<anonymous>",
250
        'package_name': "obj_code_pkg"
251
        }
252
 
253
    block_params = {}
254
    blocks = []
255
 
256
 
257
    # Parse command line parameters
258
    for opt, arg in opts:
259
        # Options that affect the whole file
260
        if opt in ("-h", "--help"):
261
            usage()
262
            help()
263
            exit(1)
264
        if opt in ("-v", "--vhdl"):
265
            vhdl_filename = arg
266
        elif opt in ("-t", "--templates"):
267
            template_dir_name = arg
268
        elif opt in ("-i", "--indent"):
269
            package_params['indent'] = int(arg)
270
        elif opt in ("-o", "--output"):
271
            target_filename = arg
272
        elif opt in ("-p", "--package"):
273
            package_params['package_name'] = arg
274
        elif opt in ("--project"):
275
            package_params['proj_name'] = arg
276
        elif opt in ("--log_trigger"):
277
            package_params['trigger_address'] = arg
278
        elif opt in ("-s", "--sim_length"):
279
            package_params['sim_length'] = arg
280
        elif opt in ("--xram_size"):
281
            package_params['xram_size'] = arg
282
        elif opt in ("--flash_size"):
283
            package_params['flash_size'] = arg
284
        elif opt in ("--bram_size"):
285
            package_params['boot_bram_size'] = arg
286
        # Options for one initialization block 
287
        elif opt in ("-n", "--name"):
288
            if block_params.has_key('constant_name'):
289
                blocks.append(block_params)
290
                block_params = {}
291
            block_params['constant_name'] = arg
292
        elif opt in ("-b", "--bin"):
293
            if block_params.has_key('bin_filename'):
294
                blocks.append(block_params)
295
                block_params = {}
296
            block_params['bin_filename'] = arg
297
 
298
    if len(block_params.keys())>0:
299
        blocks.append(block_params)
300
 
301
    # Make sure we have a target file name
302
    if not target_filename:
303
        print "Target file not specified -- use -o"
304
        sys.exit(1)
305
 
306
    # Read all the binary data blocks
307
    for block in blocks:
308
        if block.has_key('bin_filename'):
309
            if block['bin_filename']:
310 232 ja_rd
                (xcode, size, _, top) = read_bin_file(block['bin_filename']);
311 220 ja_rd
                block['data'] = xcode
312 232 ja_rd
                block['top'] = size
313 220 ja_rd
        else:
314
            # Named block is empty
315
            block['data'] = []
316
            block['top'] = 0
317
 
318
    # Compose template file name         
319
    template_filename = template_dir_name + "/" + vhdl_filename
320
 
321
    # Ready to go: build the package file contents
322
    vhdl_code = build_vhdl_code(template_filename, blocks, package_params);
323
 
324
    # Finally, write the package text to the target file
325
    fout = None
326
    try:
327
        fout = open(target_filename, "w")
328
        fout.write(vhdl_code)
329
        fout.close()
330
        print "VHDL code written to %s" % target_filename
331
    except:
332
        print "Trouble opening %s for output" % target_filename
333
    finally:
334
        if fout: fout.close()
335
 
336
 
337
if __name__ == "__main__":
338
    main(sys.argv[1:])
339
 
340
    sys.exit(0)
341
 

powered by: WebSVN 2.1.0

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