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

Subversion Repositories ion

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

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 33 ja_rd
    vhdl_data_strings = [" "*indent_size]*6
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
    # ok, now build init strings for 16-bit wide memorier, split in 2 byte 
87
    # 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 2 ja_rd
    return vhdl_data_strings
111
 
112
def main(argv):
113
    code_filename = ""          # file with code sections (text+reginfo+rodata)
114
    data_filename = ""          # file with data sections (data+bss)
115
    vhdl_filename = ""          # name of vhdl template file
116
    entity_name = "mips_tb"     # name of vhdl entity to be generated
117
    arch_name = "testbench"     # name of vhdl architecture to be generated
118
    target_filename = "tb.vhdl" # name of target vhdl file
119
    indent = 4                  # indentation for table data, in spaces
120
    code_table_size = -1        # size of VHDL table
121
    data_table_size = -1        # size of VHDL table
122
    bin_words = 0               # size of binary file in 32-bit words 
123 24 ja_rd
    simulation_length = 22000   # length of logic simulation in clock cycles
124 2 ja_rd
 
125
    #
126
 
127
    try:
128 24 ja_rd
        opts, args = getopt.getopt(argv, "hc:d:v:a:e:o:i:s:",
129 2 ja_rd
        ["help", "code=", "data=", "vhdl=", "architecture=",
130 24 ja_rd
         "entity=", "output=", "indent=", "sim_len=",
131
         "code_size=", "data_size="])
132 2 ja_rd
    except getopt.GetoptError:
133
        usage()
134
        sys.exit(2)
135
 
136
    # Parse coommand line parameters
137
    for opt, arg in opts:
138
        if opt in ("-h", "--help"):
139
            usage()
140
            help()
141
            exit(1)
142
        if opt in ("-v", "--vhdl"):
143
            vhdl_filename = arg
144
        elif opt in ("-o", "--output"):
145
            target_filename = arg
146
        elif opt in ("-c", "--code"):
147
            code_filename = arg
148
        elif opt in ("-d", "--data"):
149
            data_filename = arg
150
        elif opt in ("-a", "--architecture"):
151
            arch_name = arg
152
        elif opt in ("-e", "--entity"):
153
            entity_name = arg
154
        elif opt in ("-i", "--indent"):
155
            indent = int(arg)
156 24 ja_rd
        elif opt in ("-s", "--sim_len"):
157
            simulation_length = int(arg)
158 2 ja_rd
        elif opt == "--code_size":
159
            code_table_size = int(arg)
160
        elif opt == "--data_size":
161
            data_table_size = int(arg)
162
 
163
    # See if all mandatory options are there
164
    if code_filename=="" or vhdl_filename=="" or \
165
       code_table_size < 0 or data_table_size<0:
166 33 ja_rd
        print "Some mandatory parameter is missing\n"
167 2 ja_rd
        usage()
168
        sys.exit(2)
169
 
170
 
171
    # Open binary code and data input files and read them into buffers
172
    try:
173
        fin = open(code_filename, "rb")
174
        code = fin.read()
175
        fin.close()
176
    except IOError:
177
        print "Binary File %s not found" % code_filename
178
 
179
    if data_filename != "":
180 33 ja_rd
        if data_filename == "empty":
181
            data = []
182
        else:
183
            try:
184
                fin = open(data_filename, "rb")
185
                data = fin.read()
186
                fin.close()
187
            except IOError:
188
                print "Binary File %s not found" % data_filename
189 2 ja_rd
 
190
    #print "Read " + str(len(code)) + " bytes."
191
 
192
    # Make sure the code and data will fit in the tables
193
    bin_words = len(code) / 4
194
    if bin_words > code_table_size:
195
        print "Code does not fit table: " + str(bin_words) + " words,",
196
        print str(code_table_size) + " table entries"
197
        sys.exit(1)
198
 
199
    if data_filename != "":
200
        # FIXME We're not checking for BSS size here, only .data (?)
201
        bin_words = len(data) / 4
202
        if bin_words > data_table_size:
203
            print "Data does not fit table: " + str(bin_words) + " words,",
204
            print str(data_table_size) + " table entries"
205
            sys.exit(1)
206
 
207
 
208
    # Build the VHDL strings for each slice of both code and data tables
209
    vhdl_code_strings = build_vhdl_tables(code, code_table_size, indent)
210
    if data_filename != "":
211
        vhdl_data_strings = build_vhdl_tables(data, data_table_size, indent)
212
    else:
213
        # In case we didn't get a data binary, we want the vhdl compilation 
214
        # to fail when @data@ tags are used, just to catch the error
215 33 ja_rd
        vhdl_data_strings = ["error: missing data binary file"]*6
216 2 ja_rd
 
217
    # Now start scanning the VHDL template, inserting data where needed
218
 
219
    # Read template file...
220
    fin = open(vhdl_filename, "r")
221
    vhdl_lines = fin.readlines()
222
    fin.close()
223
 
224
    # ...and build the keyword and replacement tables
225
    keywords = ["@code0@","@code1@","@code2@","@code3@",
226 33 ja_rd
                "@code31@", "@code20@",
227 2 ja_rd
                "@data0@","@data1@","@data2@","@data3@",
228 33 ja_rd
                "@data31@", "@data20@",
229 2 ja_rd
                "@entity_name@","@arch_name@",
230 24 ja_rd
                "@sim_len@",
231 33 ja_rd
                "@xram_size@",
232 2 ja_rd
                "@code_table_size@","@code_addr_size@",
233
                "@data_table_size@","@data_addr_size@"];
234
    replacement = vhdl_code_strings + vhdl_data_strings + \
235
                 [entity_name, arch_name,
236 24 ja_rd
                  str(simulation_length),
237 33 ja_rd
                  str(data_table_size),
238
                  str(code_table_size),
239 2 ja_rd
                  str(int(math.floor(math.log(code_table_size,2)))),
240
                  str(data_table_size),
241
                  str(int(math.floor(math.log(data_table_size,2))))]
242
 
243
    # Now traverse the template lines replacing any keywords with the proper 
244
    # vhdl stuff we just built above.
245
    output = ""
246
    for vhdl_line in vhdl_lines:
247
        temp = vhdl_line
248
        for i in range(len(keywords)):
249
            if temp.rfind(keywords[i]) >= 0:
250
                temp = temp.replace(keywords[i], replacement[i])
251
                # uncomment this break to check for ONE keyword per line only
252
                #break
253
        output = output + temp
254
 
255
    try:
256
        fout = open(target_filename, "w")
257
        fout.write(output)
258
        fout.close()
259
        print "Wrote VHDL file '%s'" % target_filename
260
    except IOError:
261
        print "Could not write to file %s" % target_filename
262
 
263
 
264
    sys.exit(0)
265
 
266
 
267
 
268
if __name__ == "__main__":
269
    main(sys.argv[1:])
270
 
271
    sys.exit(0)
272
 

powered by: WebSVN 2.1.0

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