forked from f4pga/prjxray
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcheckdb.py
More file actions
executable file
·136 lines (106 loc) · 4.03 KB
/
checkdb.py
File metadata and controls
executable file
·136 lines (106 loc) · 4.03 KB
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
125
126
127
128
129
130
131
132
133
134
135
136
#!/usr/bin/env python3
'''
Check:
-Individual files are valid
-No overlap between any tile
TODO:
Can we use prjxray?
Relies on 074, which is too far into the process
'''
from prjxray import util
from prjxray import db as prjxraydb
import os
import parsedb
#from prjxray import db as prjxraydb
import glob
def make_tile_mask(db_root, tile_name, tilej, strict=False, verbose=False):
'''
Return dict
key: (address, bit index)
val: sample description of where it came from (there may be multiple, only one)
'''
# FIXME: fix mask files https://github.com/SymbiFlow/prjxray/issues/301
# in the meantime build them on the fly
# We may want this to build them anyway
ret = dict()
for absaddr, bitaddr, tag in util.gen_tile_bits(
db_root, tilej, strict=strict, verbose=verbose):
name = "%s.%s" % (tile_name, tag)
ret.setdefault((absaddr, bitaddr), name)
return ret
def parsedb_all(db_root, verbose=False):
'''Verify .db files are individually valid'''
files = 0
for bit_fn in glob.glob('%s/segbits_*.db' % db_root):
verbose and print("Checking %s" % bit_fn)
parsedb.run(bit_fn, fnout=None, strict=True, verbose=verbose)
files += 1
print("segbits_*.db: %d okay" % files)
files = 0
for bit_fn in glob.glob('%s/mask_*.db' % db_root):
verbose and print("Checking %s" % bit_fn)
parsedb.run(bit_fn, fnout=None, strict=True, verbose=verbose)
files += 1
print("mask_*.db: %d okay" % files)
def check_tile_overlap(db, db_root, strict=False, verbose=False):
'''
Verifies that no two tiles use the same bit
Assume .db files are individually valid
Create a mask for all the bits the tile type uses
For each tile, create bitmasks over the entire bitstream for current part
Throw an exception if two tiles share an address
'''
mall = dict()
tiles_checked = 0
def subtiles(tile_names):
for tile_name in tile_names:
yield tile_name, db.tilegrid[tile_name]
for tile_name, tilej in db.tilegrid.items():
# for tile_name, tilej in subtiles(["CLBLL_L_X14Y112", "INT_L_X14Y112"]):
mtile = make_tile_mask(
db_root, tile_name, tilej, strict=strict, verbose=verbose)
verbose and print(
"Checking %s, type %s, bits: %s" %
(tile_name, tilej["type"], len(mtile)))
if len(mtile) == 0:
continue
collisions = set(mall.keys()).intersection(set(mtile.keys()))
if collisions:
print("ERROR: %s collisions" % len(collisions))
for ck in sorted(collisions):
addr, bitaddr = ck
word, bit = util.addr_bit2word(bitaddr)
print(
" %s: had %s, got %s" %
(util.addr2str(addr, word, bit), mall[ck], mtile[ck]))
raise ValueError("%s collisions" % len(collisions))
mall.update(mtile)
tiles_checked += 1
print("Checked %s tiles, %s bits" % (tiles_checked, len(mall)))
def run(db_root, strict=False, verbose=False):
# Start by running a basic check on db files
print("Checking individual .db...")
parsedb_all(db_root, verbose=verbose)
# Now load and verify tile consistency
db = prjxraydb.Database(db_root)
db._read_tilegrid()
'''
these don't load properly without .json files
See: https://github.com/SymbiFlow/prjxray/issues/303
db._read_tile_types()
print(db.tile_types.keys())
'''
verbose and print("")
print("Checking aggregate dir...")
check_tile_overlap(db, db_root, strict=strict, verbose=verbose)
def main():
import argparse
parser = argparse.ArgumentParser(
description="Parse a db repository, checking for consistency")
util.db_root_arg(parser)
parser.add_argument('--strict', action='store_true', help='')
parser.add_argument('--verbose', action='store_true', help='')
args = parser.parse_args()
run(args.db_root, strict=args.strict, verbose=args.verbose)
if __name__ == '__main__':
main()