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

Subversion Repositories ion

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

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

powered by: WebSVN 2.1.0

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