mirror of https://github.com/openXC7/prjxray.git
checkdb.py: added some optimizations to script
I have restored the check on every single tile while also adding some optimizations to the algorithm. It still is pretty slow, mainly during the INT_[LR] tiles checking, but compared to the previous solution there is a good improvement. Signed-off-by: Alessandro Comodi <acomodi@antmicro.com>
This commit is contained in:
parent
ad1877f9e5
commit
530bb1f243
|
|
@ -172,42 +172,24 @@ def addr2btype(base_addr):
|
||||||
return block_type_i2s[block_type_i]
|
return block_type_i2s[block_type_i]
|
||||||
|
|
||||||
|
|
||||||
def gen_tile_bits(db_root, tilej, strict=False, verbose=False):
|
def gen_tile_bits(db_file, tilej, strict=False, verbose=False):
|
||||||
'''
|
'''
|
||||||
For given tile yield
|
For given tile and corresponding db_file structure yield
|
||||||
(absolute address, absolute FDRI bit offset, tag)
|
(absolute address, absolute FDRI bit offset, tag)
|
||||||
|
|
||||||
For each address space
|
db_file:
|
||||||
Find applicable files
|
{'<block_type_1>': [<bit lines>], '<block_type_2>': [<bit lines>], ...}
|
||||||
For each tag bit in those files, calculate absolute address and bit offsets
|
|
||||||
|
|
||||||
Sample file names:
|
For each tag bit in the corresponding block_type entry, calculate absolute address and bit offsets
|
||||||
segbits_clbll_l.db
|
|
||||||
segbits_int_l.db
|
|
||||||
segbits_bram_l.block_ram.db
|
|
||||||
'''
|
'''
|
||||||
for block_type, blockj in tilej["bits"].items():
|
for block_type, blockj in tilej["bits"].items():
|
||||||
|
assert block_type in db_file, "Block type is not in current tile"
|
||||||
|
|
||||||
baseaddr = int(blockj["baseaddr"], 0)
|
baseaddr = int(blockj["baseaddr"], 0)
|
||||||
bitbase = 32 * blockj["offset"]
|
bitbase = 32 * blockj["offset"]
|
||||||
frames = tilej["bits"][block_type]["frames"]
|
frames = tilej["bits"][block_type]["frames"]
|
||||||
|
|
||||||
if block_type == "CLB_IO_CLK":
|
for line, (tag, bits, mode) in db_file[block_type]:
|
||||||
fn = "%s/segbits_%s.db" % (db_root, tilej["type"].lower())
|
|
||||||
else:
|
|
||||||
fn = "%s/segbits_%s.%s.db" % (
|
|
||||||
db_root, tilej["type"].lower(), block_type.lower())
|
|
||||||
# tilegrid runs a lot earlier than fuzzers
|
|
||||||
# may not have been created yet
|
|
||||||
verbose and print("Check %s: %s" % (fn, os.path.exists(fn)))
|
|
||||||
|
|
||||||
# FIXME: some segbits files are not present and the strict check produces assertion errors
|
|
||||||
# e.g. segbits_cmt_top_r_lower_b.db
|
|
||||||
if strict:
|
|
||||||
assert os.path.exists(fn)
|
|
||||||
elif not os.path.exists(fn):
|
|
||||||
continue
|
|
||||||
|
|
||||||
for line, (tag, bits, mode) in parse_db_lines(fn):
|
|
||||||
assert mode is None
|
assert mode is None
|
||||||
for bitstr in bits:
|
for bitstr in bits:
|
||||||
# 31_06
|
# 31_06
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,9 @@ import os
|
||||||
import parsedb
|
import parsedb
|
||||||
#from prjxray import db as prjxraydb
|
#from prjxray import db as prjxraydb
|
||||||
import glob
|
import glob
|
||||||
|
import json
|
||||||
|
|
||||||
|
def make_tile_mask(db_file, tile_name, tilej, strict=False, verbose=False):
|
||||||
def make_tile_mask(db_root, tile_name, tilej, strict=False, verbose=False):
|
|
||||||
'''
|
'''
|
||||||
Return dict
|
Return dict
|
||||||
key: (address, bit index)
|
key: (address, bit index)
|
||||||
|
|
@ -30,7 +30,7 @@ def make_tile_mask(db_root, tile_name, tilej, strict=False, verbose=False):
|
||||||
|
|
||||||
ret = dict()
|
ret = dict()
|
||||||
for absaddr, bitaddr, tag in util.gen_tile_bits(
|
for absaddr, bitaddr, tag in util.gen_tile_bits(
|
||||||
db_root, tilej, strict=strict, verbose=verbose):
|
db_file, tilej, strict=strict, verbose=verbose):
|
||||||
name = "%s.%s" % (tile_name, tag)
|
name = "%s.%s" % (tile_name, tag)
|
||||||
ret.setdefault((absaddr, bitaddr), name)
|
ret.setdefault((absaddr, bitaddr), name)
|
||||||
return ret
|
return ret
|
||||||
|
|
@ -54,6 +54,33 @@ def parsedb_all(db_root, verbose=False):
|
||||||
print("mask_*.db: %d okay" % files)
|
print("mask_*.db: %d okay" % files)
|
||||||
|
|
||||||
|
|
||||||
|
def parsedb_file(db_root, db_files, tile, strict=False, verbose=False):
|
||||||
|
tile_type = tile["type"]
|
||||||
|
db_files[tile_type] = {}
|
||||||
|
|
||||||
|
for block_type, blockj in tile["bits"].items():
|
||||||
|
db_files[tile_type][block_type] = []
|
||||||
|
if block_type == "CLB_IO_CLK":
|
||||||
|
fn = "%s/segbits_%s.db" % (db_root, tile_type.lower())
|
||||||
|
else:
|
||||||
|
fn = "%s/segbits_%s.%s.db" % (
|
||||||
|
db_root, tile_type.lower(), block_type.lower())
|
||||||
|
# tilegrid runs a lot earlier than fuzzers
|
||||||
|
# may not have been created yet
|
||||||
|
verbose and print("Check %s: %s" % (fn, os.path.exists(fn)))
|
||||||
|
|
||||||
|
# FIXME: some segbits files are not present and the strict check produces assertion errors
|
||||||
|
# e.g. segbits_cmt_top_r_lower_b.db
|
||||||
|
if strict:
|
||||||
|
assert os.path.exists(fn)
|
||||||
|
elif not os.path.exists(fn):
|
||||||
|
continue
|
||||||
|
|
||||||
|
for line in util.parse_db_lines(fn):
|
||||||
|
db_files[tile_type][block_type].append(line)
|
||||||
|
return db_files
|
||||||
|
|
||||||
|
|
||||||
def check_tile_overlap(db, db_root, strict=False, verbose=False):
|
def check_tile_overlap(db, db_root, strict=False, verbose=False):
|
||||||
'''
|
'''
|
||||||
Verifies that no two tiles use the same bit
|
Verifies that no two tiles use the same bit
|
||||||
|
|
@ -65,29 +92,30 @@ def check_tile_overlap(db, db_root, strict=False, verbose=False):
|
||||||
'''
|
'''
|
||||||
mall = dict()
|
mall = dict()
|
||||||
tiles_type_done = set()
|
tiles_type_done = set()
|
||||||
|
db_files = dict()
|
||||||
|
|
||||||
tiles_checked = 0
|
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 db.tilegrid.items():
|
||||||
# for tile_name, tilej in subtiles(["CLBLL_L_X14Y112", "INT_L_X14Y112"]):
|
tile_type = tilej["type"]
|
||||||
|
|
||||||
if tilej['type'] in tiles_type_done or not tilej["bits"]:
|
if tile_type not in tiles_type_done:
|
||||||
continue
|
db_files = parsedb_file(db_root, db_files, tilej)
|
||||||
tiles_type_done.add(tilej['type'])
|
tiles_type_done.add(tile_type)
|
||||||
|
|
||||||
|
if tile_type not in mall:
|
||||||
|
verbose and print("Adding tile type: %s" % tile_type)
|
||||||
|
mall[tile_type] = {}
|
||||||
|
|
||||||
mtile = make_tile_mask(
|
mtile = make_tile_mask(
|
||||||
db_root, tile_name, tilej, strict=strict, verbose=verbose)
|
db_files[tile_type], tile_name, tilej, strict=strict, verbose=verbose)
|
||||||
verbose and print(
|
verbose and print(
|
||||||
"Checking %s, type %s, bits: %s" %
|
"Checking %s, type %s, bits: %s" %
|
||||||
(tile_name, tilej["type"], len(mtile)))
|
(tile_name, tilej["type"], len(mtile)))
|
||||||
if len(mtile) == 0:
|
if len(mtile) == 0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
collisions = set(mall.keys()).intersection(set(mtile.keys()))
|
collisions = set(mall[tile_type].keys()).intersection(set(mtile.keys()))
|
||||||
if collisions:
|
if collisions:
|
||||||
print("ERROR: %s collisions" % len(collisions))
|
print("ERROR: %s collisions" % len(collisions))
|
||||||
for ck in sorted(collisions):
|
for ck in sorted(collisions):
|
||||||
|
|
@ -95,9 +123,9 @@ def check_tile_overlap(db, db_root, strict=False, verbose=False):
|
||||||
word, bit = util.addr_bit2word(bitaddr)
|
word, bit = util.addr_bit2word(bitaddr)
|
||||||
print(
|
print(
|
||||||
" %s: had %s, got %s" %
|
" %s: had %s, got %s" %
|
||||||
(util.addr2str(addr, word, bit), mall[ck], mtile[ck]))
|
(util.addr2str(addr, word, bit), mall[tile_type][ck], mtile[ck]))
|
||||||
raise ValueError("%s collisions" % len(collisions))
|
raise ValueError("%s collisions" % len(collisions))
|
||||||
mall.update(mtile)
|
mall[tile_type].update(mtile)
|
||||||
tiles_checked += 1
|
tiles_checked += 1
|
||||||
print("Checked %s tiles, %s bits" % (tiles_checked, len(mall)))
|
print("Checked %s tiles, %s bits" % (tiles_checked, len(mall)))
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue