-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathDbgParser.py
124 lines (110 loc) · 4.55 KB
/
DbgParser.py
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
118
119
120
121
122
123
124
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2020-2022 F4PGA Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
# Parses .bit files where it is a frame-by-frame structure (debug bitstream)
# This is for files that do a write to the FAR and then a write of FDRI data and then repeat
import pathlib
def parse_bit_file(bitFile, verbose=False):
header_st = 0
firstByte_st = 1
secondByte_st = 2
thirdByte_st = 3
fourthByte_st = 4
currentState = header_st
# Use state machine to find sync word (0xAA995566).
# Sync word marks the end of the header and the start of actual commands
with bitFile.open('rb') as f:
assert f is not None
while currentState != fourthByte_st:
byte = f.read(1)
if currentState == header_st and ord(byte) == 0xAA:
currentState = firstByte_st
elif currentState == firstByte_st and ord(byte) == 0x99:
currentState = secondByte_st
elif currentState == secondByte_st and ord(byte) == 0x55:
currentState = thirdByte_st
elif currentState == thirdByte_st and ord(byte) == 0x66:
currentState = fourthByte_st
else:
currentState = header_st
return extract_frame_data(f, verbose)
def extract_frame_data(fd, verbose):
frames = dict()
while True:
# Find type 1 write to FAR
# Look for any of 0x30002001 (Set FAR), 0x30004065 (Write frame contents), or 0x30000001 (CRC)
flg = lookFor3(
fd, 0x30, 0x00, 0x20, 0x01, 0x30, 0x00, 0x40, 0x65, 0x30, 0x00,
0x00, 0x01
)
if flg == 0: # Set FAR
bytes = fd.read(4)
frameword = (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] <<
8) | bytes[3]
if verbose:
print("frameword = {}".format(hex(frameword)))
elif flg == 1: # Frame contents
frmContents = []
for i in range(101):
bytes = fd.read(4)
word = (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] <<
8) | bytes[3]
frmContents.append(word)
frames[frameword] = frmContents
elif flg == 2: # CRC
# Skip the actual CRC word
fd.read(4)
# Increment frame # to prep for next frame
frameword += 1
else:
break
return frames
# Repeated read 4 word chunks and look for either b0b1b2b3, b4b5b6b7, or b8b9babb
# Return 0, 1, or 2 depending on what matched
def lookFor3(f, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb):
#print("Looking for: {} {} {} {}".format(hex(str(b0)), hex(str(b1)),hex(str(b2)), hex(str(b3))))
while (1):
bytes = f.read(4)
if len(bytes) < 4:
return -1
if bytes[0] == b0 and bytes[1] == b1 and bytes[2] == b2 and bytes[
3] == b3:
return 0
elif bytes[0] == b4 and bytes[1] == b5 and bytes[2] == b6 and bytes[
3] == b7:
return 1
elif bytes[0] == b8 and bytes[1] == b9 and bytes[2] == ba and bytes[
3] == bb:
return 2
# Print frame contents
def dumpframe(frames, frame, wordoffset=0, flen=101):
print("frame #: " + hex(frame))
f = frames[frame]
for i in range(wordoffset, wordoffset + flen):
w = f[i]
print(" " + str(i) + " " + hex(w))
# Given a path will read the frame data into a data structure and return it.
# It is a dict where the keys are the frame numbers (integers) and the values are the 101 words of frame data in a list
# Later, this can be used to look up the individual values
def loadFrames(bitFile):
return parse_bit_file(bitFile, False)
if __name__ == '__main__':
bitfilePath = pathlib.Path(
"/home/nelson/mempatch/testing/tests/master/128b1/vivado/128b1.bit"
)
frames = loadFrames(bitfilePath)
dumpframe(frames, 0x00c0000f, 10, 10)