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

Subversion Repositories ion

[/] [ion/] [trunk/] [src/] [bin2hdl.py] - Blame information for rev 82

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

Line No. Rev Author Line
1 2 ja_rd
""" xcxcxc
2
 
3
 
4
"""
5
import sys
6
import getopt
7
import math
8
 
9
 
10
def usage():
11 77 ja_rd
    print ""
12 2 ja_rd
    print "usage:"
13
    print "python bin2hdl.py [arguments]\n"
14
    print "Inserts data in VHDL template\n"
15
    print "ALL of the following arguments should be given, in any order:"
16
    print "{c|code} <filename>        Code binary image file name"
17
    print "{v|vhdl} <filename>        VHDL template"
18
    print "{a|architecture} <name>    Name of target VHDL architecture"
19
    print "{e|entity} <name>          Name of target VHDL entity"
20
    print "{o|output} <filename>      Target VHDL file name"
21 77 ja_rd
    print "code_size <number>         Size of bram memory in words (decimal)"
22 2 ja_rd
    print "data_size <number>         Size of data memory in words (decimal)"
23 77 ja_rd
    print "flash_size <number>        Size of flash memory in words (decimal)"
24
    print "(note the flash and xram info are used in simulation only)"
25 2 ja_rd
    print ""
26
    print "Additionally, any of these arguments can be given:"
27 24 ja_rd
    print "{s|sim_len} <number>       Length of simulation in clock cycles"
28 33 ja_rd
    print "{d|data} <filename>        Data binary image file name or 'empty'"
29 2 ja_rd
    print "{h|help}                   Display some help text and exit"
30
    print "{i|indent} <number>        Indentation in VHDL tables (decimal)"
31
 
32
def help():
33
    print "\nPurpose:\n"
34
    print "Reads the code and data binary files and 'slices' them in byte"
35
    print "columns."
36
    print "The data columns are converted to VHDL strings and then inserted"
37
    print "into the vhdl template, in place of tags @code0@ .. @code3@ and "
38
    print "@data0@ .. @data3@. Column 0 is LSB and column3 is MSB.\n"
39 33 ja_rd
    print "Tags like @data31@ and @data20@ etc. can be used to initialize"
40
    print "memories in 16-bit buses, also split in byte columns.\n"
41 2 ja_rd
    print "Other template tags are replaced as follows:"
42
    print "@entity_name@         : Name of entity in target vhdl file"
43
    print "@arch_name@           : Name of architecture in target vhdl file"
44 24 ja_rd
    print "@sim_len@             : Length of simulation in clock cycles"
45 2 ja_rd
    print "@code_table_size@     : Size of code RAM block, in words"
46
    print "@code_addr_size@      : ceil(Log2(@code_table_size@))"
47
    print "@data_table_size@     : Size of data RAM block, in words"
48
    print "@data_addr_size@      : ceil(Log2(@data_table_size@))"
49
 
50
 
51 77 ja_rd
def build_vhdl_flash_table(flash, table_size, indent_size):
52
    # Build vhdl table for flash data
53
 
54
    # fill up empty table space with zeros
55
    if len(flash) < table_size*4:
56
        flash = flash + '\0'*4*(table_size-len(flash)/4)
57
 
58
    num_words = len(flash)/4
59
    remaining = num_words;
60
    col = 0
61
    vhdl_flash_string = "\n" + " "*indent_size
62
    for w in range(num_words):
63
        b0 = ord(flash[w*4+0]);
64
        b1 = ord(flash[w*4+1]);
65
        b2 = ord(flash[w*4+2]);
66
        b3 = ord(flash[w*4+3]);
67
 
68
        if remaining > 1:
69
            item = "X\"%02X%02X%02X%02X\"," % (b0, b1, b2, b3)
70
        else:
71
            item = "X\"%02X%02X%02X%02X\"" % (b0, b1, b2, b3)
72
 
73
        remaining = remaining - 1
74
        col = col + 1
75
        if col == 4:
76
           col = 0
77
           item = item + "\n" + " "*indent_size
78
 
79
        vhdl_flash_string = vhdl_flash_string + item
80
 
81
    return vhdl_flash_string
82
 
83
 
84
 
85 2 ja_rd
def build_vhdl_tables(code,table_size, indent_size):
86
    # Build the four byte column tables. [0] is LSB, [3] is MSB
87 77 ja_rd
    # Useful only for BRAM and SRAM tables
88 2 ja_rd
    tables = [[0 for i in range(table_size)] for i in range(4)]
89
 
90
    # Separate binary data into byte columns
91
    # (here's where data endianess matters, we're assuming big endian)
92
    byte = 0    # byte 0 is LSB, 3 is MSB
93
    index = 0   # index into column table    
94
    for c in code:
95
        #print str(ord(c)) + " " +  str(byte) + " " + str(index)
96
        tables[3-byte][index] = ord(c)
97
        #for k in tables:
98
        #    print k[0:4]
99
        byte = byte + 1
100
        if byte == 4:
101
            byte = 0
102
            index = index + 1
103
 
104
    # Write the data for each of the four column tables as a VHDL byte
105
    # constant table.
106 56 ja_rd
    vhdl_data_strings = [" "*indent_size]*7
107 2 ja_rd
 
108
    for j in range(4):
109
        col = 0
110
        word = len(tables[j])
111
        for c in tables[j]:
112
            word = word - 1
113
            if word > 0:
114
                item = "X\"%02X\"," % c
115
            else:
116
                item = "X\"%02X\"" % c
117
            col = col + 1
118
            if col == 8:
119
                col = 0
120
                item = item + "\n" + " "*indent_size
121
            vhdl_data_strings[j] = vhdl_data_strings[j] + item
122 33 ja_rd
        vhdl_data_strings[j] = "\n" + vhdl_data_strings[j]
123
 
124 56 ja_rd
    # ok, now build init strings for 16-bit wide memories, split in 2 byte 
125 33 ja_rd
    # columns: an odd column with bytes 3:1 and an even column with bytes 2:0
126
    byte_order = [3,1,2,0]
127
    for j in range(2):
128
        col = 0
129
        word_count = len(tables[j*2])
130
        for i in range(word_count):
131
            w_high = tables[byte_order[j*2+0]][i]
132
            w_low  = tables[byte_order[j*2+1]][i]
133
            word_count = word_count - 1
134
            if word_count > 0:
135
                item_h = "X\"%02X\"," % w_high
136
                item_l = "X\"%02X\"," % w_low
137
            else:
138
                item_h = "X\"%02X\"," % w_high
139
                item_l = "X\"%02X\"" % w_low
140
            item = item_h + item_l
141
            col = col + 1
142
            if col == 4:
143
                col = 0
144
                item = item + "\n" + " "*indent_size
145
            vhdl_data_strings[4+j] = vhdl_data_strings[4+j] + item
146
        vhdl_data_strings[4+j] = "\n" + vhdl_data_strings[4+j]
147
 
148 56 ja_rd
    # finally, build init strings for 32-bit wide memories not split into 
149
    # byte columns; useful for read-only 32-bit wide BRAMs
150
    byte_order = [3,2,1,0]
151
    col = 0
152
    word_count = len(tables[0])
153
    for i in range(word_count):
154
        w3 = tables[byte_order[0]][i]
155
        w2 = tables[byte_order[1]][i]
156
        w1 = tables[byte_order[2]][i]
157
        w0 = tables[byte_order[3]][i]
158
 
159
        word_count = word_count - 1
160
        if word_count > 0:
161
            item = "X\"%02X%02X%02X%02X\"," % (w3, w2, w1, w0)
162
        else:
163
            item = "X\"%02X%02X%02X%02X\"" % (w3, w2, w1, w0)
164
 
165
        col = col + 1
166
        if col == 4:
167
            col = 0
168
            item = item + "\n" + " "*indent_size
169
        vhdl_data_strings[6] = vhdl_data_strings[6] + item
170
    vhdl_data_strings[6] = "\n" + vhdl_data_strings[6]
171
 
172
 
173
 
174 2 ja_rd
    return vhdl_data_strings
175
 
176
def main(argv):
177 77 ja_rd
    code_filename = ""          # file with bram contents ('code')
178
    data_filename = ""          # file with xram contents ('data')
179
    flash_filename = ""         # file with flash contents ('flash')
180 2 ja_rd
    vhdl_filename = ""          # name of vhdl template file
181
    entity_name = "mips_tb"     # name of vhdl entity to be generated
182
    arch_name = "testbench"     # name of vhdl architecture to be generated
183
    target_filename = "tb.vhdl" # name of target vhdl file
184
    indent = 4                  # indentation for table data, in spaces
185
    code_table_size = -1        # size of VHDL table
186
    data_table_size = -1        # size of VHDL table
187 77 ja_rd
    flash_table_size = 32;      # default size of flash table in 32-bit words
188
    flash = ['\0']*4*flash_table_size # default simulated flash
189 2 ja_rd
    bin_words = 0               # size of binary file in 32-bit words 
190 24 ja_rd
    simulation_length = 22000   # length of logic simulation in clock cycles
191 2 ja_rd
 
192
    #
193
 
194
    try:
195 77 ja_rd
        opts, args = getopt.getopt(argv, "hc:d:v:a:e:o:i:s:f:",
196 2 ja_rd
        ["help", "code=", "data=", "vhdl=", "architecture=",
197 77 ja_rd
         "entity=", "output=", "indent=", "sim_len=", "flash=",
198
         "code_size=", "data_size=", "flash_size="])
199
    except getopt.GetoptError, err:
200
        print ""
201
        print err
202 2 ja_rd
        usage()
203
        sys.exit(2)
204
 
205
    # Parse coommand line parameters
206
    for opt, arg in opts:
207
        if opt in ("-h", "--help"):
208
            usage()
209
            help()
210
            exit(1)
211
        if opt in ("-v", "--vhdl"):
212
            vhdl_filename = arg
213
        elif opt in ("-o", "--output"):
214
            target_filename = arg
215
        elif opt in ("-c", "--code"):
216
            code_filename = arg
217
        elif opt in ("-d", "--data"):
218
            data_filename = arg
219 77 ja_rd
        elif opt in ("-f", "--flash"):
220
            flash_filename = arg
221 2 ja_rd
        elif opt in ("-a", "--architecture"):
222
            arch_name = arg
223
        elif opt in ("-e", "--entity"):
224
            entity_name = arg
225
        elif opt in ("-i", "--indent"):
226
            indent = int(arg)
227 24 ja_rd
        elif opt in ("-s", "--sim_len"):
228
            simulation_length = int(arg)
229 2 ja_rd
        elif opt == "--code_size":
230
            code_table_size = int(arg)
231
        elif opt == "--data_size":
232
            data_table_size = int(arg)
233 77 ja_rd
        elif opt == "--flash_size":
234
            flash_table_size = int(arg)
235 2 ja_rd
 
236
    # See if all mandatory options are there
237
    if code_filename=="" or vhdl_filename=="" or \
238
       code_table_size < 0 or data_table_size<0:
239 33 ja_rd
        print "Some mandatory parameter is missing\n"
240 2 ja_rd
        usage()
241
        sys.exit(2)
242
 
243
 
244
    # Open binary code and data input files and read them into buffers
245
    try:
246
        fin = open(code_filename, "rb")
247
        code = fin.read()
248
        fin.close()
249
    except IOError:
250
        print "Binary File %s not found" % code_filename
251
 
252
    if data_filename != "":
253 33 ja_rd
        if data_filename == "empty":
254
            data = []
255
        else:
256
            try:
257
                fin = open(data_filename, "rb")
258
                data = fin.read()
259
                fin.close()
260
            except IOError:
261
                print "Binary File %s not found" % data_filename
262 2 ja_rd
 
263 77 ja_rd
    if flash_filename != "":
264
        if flash_filename == "empty":
265
            flash = [0]*flash_table_size
266
        else:
267
            try:
268
                fin = open(flash_filename, "rb")
269
                flash = fin.read()
270
                fin.close()
271
            except IOError:
272
                print "Binary File %s not found" % flash_filename
273
 
274 2 ja_rd
    #print "Read " + str(len(code)) + " bytes."
275
 
276
    # Make sure the code and data will fit in the tables
277
    bin_words = len(code) / 4
278
    if bin_words > code_table_size:
279
        print "Code does not fit table: " + str(bin_words) + " words,",
280
        print str(code_table_size) + " table entries"
281
        sys.exit(1)
282
 
283
    if data_filename != "":
284
        # FIXME We're not checking for BSS size here, only .data (?)
285
        bin_words = len(data) / 4
286
        if bin_words > data_table_size:
287
            print "Data does not fit table: " + str(bin_words) + " words,",
288
            print str(data_table_size) + " table entries"
289
            sys.exit(1)
290 77 ja_rd
 
291
    if flash_filename != "":
292
        bin_words = len(flash) / 4
293
        if bin_words > flash_table_size:
294
            print "Flash data does not fit table: " + str(bin_words) + " words,",
295
            print str(flash_table_size) + " table entries"
296
            sys.exit(1)
297 2 ja_rd
 
298
 
299
    # Build the VHDL strings for each slice of both code and data tables
300
    vhdl_code_strings = build_vhdl_tables(code, code_table_size, indent)
301
    if data_filename != "":
302
        vhdl_data_strings = build_vhdl_tables(data, data_table_size, indent)
303
    else:
304
        # In case we didn't get a data binary, we want the vhdl compilation 
305
        # to fail when @data@ tags are used, just to catch the error
306 33 ja_rd
        vhdl_data_strings = ["error: missing data binary file"]*6
307 2 ja_rd
 
308 77 ja_rd
    vhdl_flash_string = build_vhdl_flash_table(flash, flash_table_size, indent)
309
 
310 2 ja_rd
    # Now start scanning the VHDL template, inserting data where needed
311
 
312
    # Read template file...
313
    fin = open(vhdl_filename, "r")
314
    vhdl_lines = fin.readlines()
315
    fin.close()
316
 
317
    # ...and build the keyword and replacement tables
318
    keywords = ["@code0@","@code1@","@code2@","@code3@",
319 33 ja_rd
                "@code31@", "@code20@",
320 56 ja_rd
                "@code-32bit@",
321 2 ja_rd
                "@data0@","@data1@","@data2@","@data3@",
322 33 ja_rd
                "@data31@", "@data20@",
323 56 ja_rd
                "@data-32bit@",
324 77 ja_rd
                "@flash@",
325 2 ja_rd
                "@entity_name@","@arch_name@",
326 24 ja_rd
                "@sim_len@",
327 33 ja_rd
                "@xram_size@",
328 2 ja_rd
                "@code_table_size@","@code_addr_size@",
329 77 ja_rd
                "@data_table_size@","@data_addr_size@",
330
                "@prom_size@"];
331 2 ja_rd
    replacement = vhdl_code_strings + vhdl_data_strings + \
332 77 ja_rd
                 [vhdl_flash_string,
333
                  entity_name, arch_name,
334 24 ja_rd
                  str(simulation_length),
335 33 ja_rd
                  str(data_table_size),
336
                  str(code_table_size),
337 2 ja_rd
                  str(int(math.floor(math.log(code_table_size,2)))),
338
                  str(data_table_size),
339 77 ja_rd
                  str(int(math.floor(math.log(data_table_size,2)))),
340
                  str(flash_table_size)]
341 2 ja_rd
 
342
    # Now traverse the template lines replacing any keywords with the proper 
343
    # vhdl stuff we just built above.
344
    output = ""
345
    for vhdl_line in vhdl_lines:
346
        temp = vhdl_line
347
        for i in range(len(keywords)):
348
            if temp.rfind(keywords[i]) >= 0:
349
                temp = temp.replace(keywords[i], replacement[i])
350
                # uncomment this break to check for ONE keyword per line only
351
                #break
352
        output = output + temp
353
 
354
    try:
355
        fout = open(target_filename, "w")
356
        fout.write(output)
357
        fout.close()
358
        print "Wrote VHDL file '%s'" % target_filename
359
    except IOError:
360
        print "Could not write to file %s" % target_filename
361
 
362
 
363
    sys.exit(0)
364
 
365
 
366
 
367
if __name__ == "__main__":
368
    main(sys.argv[1:])
369
 
370
    sys.exit(0)
371
 

powered by: WebSVN 2.1.0

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