1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
"""
# *.BIT file parser
#
# Copyright (c) 2009 Michael Buesch <mb@bu3sch.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""
import sys
class BitfileException(Exception): pass
class Bitfile:
# Magic header
MAGIC = "\x00\x09\x0f\xf0\x0f\xf0\x0f\xf0\x0f\xf0\x00\x00\x01"
# Field IDs
FIELD_SRCFILE = 0x61
FIELD_FPGA = 0x62
FIELD_DATE = 0x63
FIELD_TIME = 0x64
FIELD_PAYLOAD = 0x65
def __init__(self):
self.srcfile = ""
self.fpga = ""
self.date = ""
self.time = ""
self.payload = ""
def getSrcFile(self):
return self.srcfile
def getFPGA(self):
return self.fpga
def getDate(self):
return self.date
def getTime(self):
return self.time
def getPayload(self):
return self.payload
def parseFile(self, filename):
try:
data = file(filename, "rb").read()
except (IOError), e:
raise BitfileException("Failed to read \"" + filename + "\": " + e.strerror)
self.__parse(data)
def __parse(self, data):
try:
magic = data[0:len(self.MAGIC)]
if magic != self.MAGIC:
raise BitfileException("Invalid magic header")
i = len(self.MAGIC)
while i < len(data):
i += self.__parseNextField(data, i)
except (IndexError), e:
raise BitfileException("Failed to parse BIT file")
if not self.fpga:
raise BitfileException("No FPGA ID string found")
if not self.payload:
raise BitfileException("No payload found")
def __parseNextField(self, data, i):
fieldId = ord(data[i + 0])
if (fieldId == self.FIELD_SRCFILE):
data = self.__parse16bitField(data, i + 1)
self.srcfile = data.strip().strip("\x00")
return len(data) + 3
if (fieldId == self.FIELD_FPGA):
data = self.__parse16bitField(data, i + 1)
self.fpga = data.strip().strip("\x00")
return len(data) + 3
if (fieldId == self.FIELD_DATE):
data = self.__parse16bitField(data, i + 1)
self.date = data.strip().strip("\x00")
return len(data) + 3
if (fieldId == self.FIELD_TIME):
data = self.__parse16bitField(data, i + 1)
self.time = data.strip().strip("\x00")
return len(data) + 3
if (fieldId == self.FIELD_PAYLOAD):
self.payload = self.__parse32bitField(data, i + 1)
return len(self.payload) + 5
raise BitfileException("Found unknown data field 0x%02X" % fieldId)
def __parse16bitField(self, data, i):
fieldLen = (ord(data[i + 0]) << 8) | ord(data[i + 1])
return data[i + 2 : i + 2 + fieldLen]
def __parse32bitField(self, data, i):
fieldLen = (ord(data[i + 0]) << 24) | (ord(data[i + 1]) << 16) |\
(ord(data[i + 2]) << 8) | ord(data[i + 3])
return data[i + 4 : i + 4 + fieldLen]
if __name__ == "__main__":
b = Bitfile()
b.parseFile(sys.argv[1])
print "Source file", b.getSrcFile()
print "FPGA", b.getFPGA()
print "Date", b.getDate()
print "Time", b.getTime()
|