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

Subversion Repositories ion

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

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

powered by: WebSVN 2.1.0

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