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

Subversion Repositories ion

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

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
    print "{d|data} <filename>        Data binary image file name"
25
    print "{h|help}                   Display some help text and exit"
26
    print "{i|indent} <number>        Indentation in VHDL tables (decimal)"
27
 
28
def help():
29
    print "\nPurpose:\n"
30
    print "Reads the code and data binary files and 'slices' them in byte"
31
    print "columns."
32
    print "The data columns are converted to VHDL strings and then inserted"
33
    print "into the vhdl template, in place of tags @code0@ .. @code3@ and "
34
    print "@data0@ .. @data3@. Column 0 is LSB and column3 is MSB.\n"
35
    print "Other template tags are replaced as follows:"
36
    print "@entity_name@         : Name of entity in target vhdl file"
37
    print "@arch_name@           : Name of architecture in target vhdl file"
38
    print "@code_table_size@     : Size of code RAM block, in words"
39
    print "@code_addr_size@      : ceil(Log2(@code_table_size@))"
40
    print "@data_table_size@     : Size of data RAM block, in words"
41
    print "@data_addr_size@      : ceil(Log2(@data_table_size@))"
42
 
43
 
44
def build_vhdl_tables(code,table_size, indent_size):
45
    # Build the four byte column tables. [0] is LSB, [3] is MSB
46
    tables = [[0 for i in range(table_size)] for i in range(4)]
47
 
48
    # Separate binary data into byte columns
49
    # (here's where data endianess matters, we're assuming big endian)
50
    byte = 0    # byte 0 is LSB, 3 is MSB
51
    index = 0   # index into column table    
52
    for c in code:
53
        #print str(ord(c)) + " " +  str(byte) + " " + str(index)
54
        tables[3-byte][index] = ord(c)
55
        #for k in tables:
56
        #    print k[0:4]
57
        byte = byte + 1
58
        if byte == 4:
59
            byte = 0
60
            index = index + 1
61
 
62
    # Write the data for each of the four column tables as a VHDL byte
63
    # constant table.
64
    vhdl_data_strings = [" "*indent_size]*4
65
 
66
    for j in range(4):
67
        col = 0
68
        word = len(tables[j])
69
        for c in tables[j]:
70
            word = word - 1
71
            if word > 0:
72
                item = "X\"%02X\"," % c
73
            else:
74
                item = "X\"%02X\"" % c
75
            col = col + 1
76
            if col == 8:
77
                col = 0
78
                item = item + "\n" + " "*indent_size
79
            vhdl_data_strings[j] = vhdl_data_strings[j] + item
80
 
81
    return vhdl_data_strings
82
 
83
def main(argv):
84
    code_filename = ""          # file with code sections (text+reginfo+rodata)
85
    data_filename = ""          # file with data sections (data+bss)
86
    vhdl_filename = ""          # name of vhdl template file
87
    entity_name = "mips_tb"     # name of vhdl entity to be generated
88
    arch_name = "testbench"     # name of vhdl architecture to be generated
89
    target_filename = "tb.vhdl" # name of target vhdl file
90
    indent = 4                  # indentation for table data, in spaces
91
    code_table_size = -1        # size of VHDL table
92
    data_table_size = -1        # size of VHDL table
93
    bin_words = 0               # size of binary file in 32-bit words 
94
 
95
    #
96
 
97
    try:
98
        opts, args = getopt.getopt(argv, "hc:d:v:a:e:o:i:",
99
        ["help", "code=", "data=", "vhdl=", "architecture=",
100
         "entity=", "output=", "indent=", "code_size=", "data_size="])
101
    except getopt.GetoptError:
102
        usage()
103
        sys.exit(2)
104
 
105
    # Parse coommand line parameters
106
    for opt, arg in opts:
107
        if opt in ("-h", "--help"):
108
            usage()
109
            help()
110
            exit(1)
111
        if opt in ("-v", "--vhdl"):
112
            vhdl_filename = arg
113
        elif opt in ("-o", "--output"):
114
            target_filename = arg
115
        elif opt in ("-c", "--code"):
116
            code_filename = arg
117
        elif opt in ("-d", "--data"):
118
            data_filename = arg
119
        elif opt in ("-a", "--architecture"):
120
            arch_name = arg
121
        elif opt in ("-e", "--entity"):
122
            entity_name = arg
123
        elif opt in ("-i", "--indent"):
124
            indent = int(arg)
125
        elif opt == "--code_size":
126
            code_table_size = int(arg)
127
        elif opt == "--data_size":
128
            data_table_size = int(arg)
129
 
130
    # See if all mandatory options are there
131
    if code_filename=="" or vhdl_filename=="" or \
132
       code_table_size < 0 or data_table_size<0:
133
        usage()
134
        sys.exit(2)
135
 
136
 
137
    # Open binary code and data input files and read them into buffers
138
    try:
139
        fin = open(code_filename, "rb")
140
        code = fin.read()
141
        fin.close()
142
    except IOError:
143
        print "Binary File %s not found" % code_filename
144
 
145
    if data_filename != "":
146
        try:
147
            fin = open(data_filename, "rb")
148
            data = fin.read()
149
            fin.close()
150
        except IOError:
151
            print "Binary File %s not found" % data_filename
152
 
153
    #print "Read " + str(len(code)) + " bytes."
154
 
155
    # Make sure the code and data will fit in the tables
156
    bin_words = len(code) / 4
157
    if bin_words > code_table_size:
158
        print "Code does not fit table: " + str(bin_words) + " words,",
159
        print str(code_table_size) + " table entries"
160
        sys.exit(1)
161
 
162
    if data_filename != "":
163
        # FIXME We're not checking for BSS size here, only .data (?)
164
        bin_words = len(data) / 4
165
        if bin_words > data_table_size:
166
            print "Data does not fit table: " + str(bin_words) + " words,",
167
            print str(data_table_size) + " table entries"
168
            sys.exit(1)
169
 
170
 
171
    # Build the VHDL strings for each slice of both code and data tables
172
    vhdl_code_strings = build_vhdl_tables(code, code_table_size, indent)
173
    if data_filename != "":
174
        vhdl_data_strings = build_vhdl_tables(data, data_table_size, indent)
175
    else:
176
        # In case we didn't get a data binary, we want the vhdl compilation 
177
        # to fail when @data@ tags are used, just to catch the error
178
        vhdl_data_strings = ["error: missing data binary file"]*4
179
 
180
    # Now start scanning the VHDL template, inserting data where needed
181
 
182
    # Read template file...
183
    fin = open(vhdl_filename, "r")
184
    vhdl_lines = fin.readlines()
185
    fin.close()
186
 
187
    # ...and build the keyword and replacement tables
188
    keywords = ["@code0@","@code1@","@code2@","@code3@",
189
                "@data0@","@data1@","@data2@","@data3@",
190
                "@entity_name@","@arch_name@",
191
                "@code_table_size@","@code_addr_size@",
192
                "@data_table_size@","@data_addr_size@"];
193
    replacement = vhdl_code_strings + vhdl_data_strings + \
194
                 [entity_name, arch_name,
195
                  str(code_table_size),
196
                  str(int(math.floor(math.log(code_table_size,2)))),
197
                  str(data_table_size),
198
                  str(int(math.floor(math.log(data_table_size,2))))]
199
 
200
    # Now traverse the template lines replacing any keywords with the proper 
201
    # vhdl stuff we just built above.
202
    output = ""
203
    for vhdl_line in vhdl_lines:
204
        temp = vhdl_line
205
        for i in range(len(keywords)):
206
            if temp.rfind(keywords[i]) >= 0:
207
                temp = temp.replace(keywords[i], replacement[i])
208
                # uncomment this break to check for ONE keyword per line only
209
                #break
210
        output = output + temp
211
 
212
    try:
213
        fout = open(target_filename, "w")
214
        fout.write(output)
215
        fout.close()
216
        print "Wrote VHDL file '%s'" % target_filename
217
    except IOError:
218
        print "Could not write to file %s" % target_filename
219
 
220
 
221
    sys.exit(0)
222
 
223
 
224
 
225
if __name__ == "__main__":
226
    main(sys.argv[1:])
227
 
228
    sys.exit(0)
229
 

powered by: WebSVN 2.1.0

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