mirror of https://github.com/openXC7/prjxray.git
Merge pull request #631 from antmicro/check-out-of-bound-bits
checkdb: optimized script and added out-of-bound check
This commit is contained in:
commit
8222b4089b
|
|
@ -172,45 +172,6 @@ def addr2btype(base_addr):
|
|||
return block_type_i2s[block_type_i]
|
||||
|
||||
|
||||
def gen_tile_bits(db_root, tilej, strict=False, verbose=False):
|
||||
'''
|
||||
For given tile yield
|
||||
(absolute address, absolute FDRI bit offset, tag)
|
||||
|
||||
For each address space
|
||||
Find applicable files
|
||||
For each tag bit in those files, calculate absolute address and bit offsets
|
||||
|
||||
Sample file names:
|
||||
segbits_clbll_l.db
|
||||
segbits_int_l.db
|
||||
segbits_bram_l.block_ram.db
|
||||
'''
|
||||
for block_type, blockj in tilej["bits"].items():
|
||||
baseaddr = int(blockj["baseaddr"], 0)
|
||||
bitbase = 32 * blockj["offset"]
|
||||
|
||||
if block_type == "CLB_IO_CLK":
|
||||
fn = "%s/segbits_%s.db" % (db_root, tilej["type"].lower())
|
||||
else:
|
||||
fn = "%s/segbits_%s.db.%s" % (
|
||||
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)))
|
||||
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
|
||||
for bitstr in bits:
|
||||
# 31_06
|
||||
_bit_inv, (bit_addroff, bit_bitoff) = parse_tagbit(bitstr)
|
||||
yield (baseaddr + bit_addroff, bitbase + bit_bitoff, tag)
|
||||
|
||||
|
||||
def specn():
|
||||
# ex: build/specimen_001
|
||||
specdir = os.getenv("SPECDIR")
|
||||
|
|
|
|||
|
|
@ -17,7 +17,34 @@ import parsedb
|
|||
import glob
|
||||
|
||||
|
||||
def make_tile_mask(db_root, tile_name, tilej, strict=False, verbose=False):
|
||||
def gen_tile_bits(tile_segbits, tile_bits):
|
||||
'''
|
||||
For given tile and corresponding db_file structure yield
|
||||
(absolute address, absolute FDRI bit offset, tag)
|
||||
|
||||
For each tag bit in the corresponding block_type entry, calculate absolute address and bit offsets
|
||||
'''
|
||||
|
||||
for block_type in tile_segbits:
|
||||
assert block_type in tile_bits, "block type %s is not present in current tile" % block_type
|
||||
|
||||
block = tile_bits[block_type]
|
||||
|
||||
baseaddr = block.base_address
|
||||
bitbase = 32 * block.offset
|
||||
frames = block.frames
|
||||
|
||||
for tag in tile_segbits[block_type]:
|
||||
for bit in tile_segbits[block_type][tag]:
|
||||
# 31_06
|
||||
word_column = bit.word_column
|
||||
word_bit = bit.word_bit
|
||||
assert word_column <= frames, "ERROR: bit out of bound --> tag: %s; word_column = %s; frames = %s" % (
|
||||
tag, word_column, frames)
|
||||
yield word_column + baseaddr, word_bit + bitbase, tag
|
||||
|
||||
|
||||
def make_tile_mask(tile_segbits, tile_name, tile_bits):
|
||||
'''
|
||||
Return dict
|
||||
key: (address, bit index)
|
||||
|
|
@ -29,8 +56,7 @@ def make_tile_mask(db_root, tile_name, tilej, strict=False, verbose=False):
|
|||
# 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):
|
||||
for absaddr, bitaddr, tag in gen_tile_bits(tile_segbits, tile_bits):
|
||||
name = "%s.%s" % (tile_name, tag)
|
||||
ret.setdefault((absaddr, bitaddr), name)
|
||||
return ret
|
||||
|
|
@ -54,7 +80,7 @@ def parsedb_all(db_root, verbose=False):
|
|||
print("mask_*.db: %d okay" % files)
|
||||
|
||||
|
||||
def check_tile_overlap(db, db_root, strict=False, verbose=False):
|
||||
def check_tile_overlap(db, verbose=False):
|
||||
'''
|
||||
Verifies that no two tiles use the same bit
|
||||
|
||||
|
|
@ -64,40 +90,59 @@ def check_tile_overlap(db, db_root, strict=False, verbose=False):
|
|||
Throw an exception if two tiles share an address
|
||||
'''
|
||||
mall = dict()
|
||||
|
||||
tiles_type_done = dict()
|
||||
tile_segbits = dict()
|
||||
grid = db.grid()
|
||||
tiles_checked = 0
|
||||
|
||||
def subtiles(tile_names):
|
||||
for tile_name in tile_names:
|
||||
yield tile_name, db.tilegrid[tile_name]
|
||||
for tile_name in grid.tiles():
|
||||
tile_info = grid.gridinfo_at_tilename(tile_name)
|
||||
tile_type = tile_info.tile_type
|
||||
tile_bits = tile_info.bits
|
||||
|
||||
for tile_name, tilej in db.tilegrid.items():
|
||||
# for tile_name, tilej in subtiles(["CLBLL_L_X14Y112", "INT_L_X14Y112"]):
|
||||
if tile_type not in tiles_type_done:
|
||||
segbits = db.get_tile_segbits(tile_type).segbits
|
||||
tile_segbits[tile_type] = segbits
|
||||
|
||||
mtile = make_tile_mask(
|
||||
db_root, tile_name, tilej, strict=strict, verbose=verbose)
|
||||
# If segbits has zero length the tile_type is marked True in order to be skipped
|
||||
if len(segbits) == 0:
|
||||
tiles_type_done[tile_type] = True
|
||||
else:
|
||||
tiles_type_done[tile_type] = False
|
||||
|
||||
mall[tile_type] = {}
|
||||
|
||||
if tiles_type_done[tile_type]:
|
||||
continue
|
||||
|
||||
mtile = make_tile_mask(tile_segbits[tile_type], tile_name, tile_bits)
|
||||
verbose and print(
|
||||
"Checking %s, type %s, bits: %s" %
|
||||
(tile_name, tilej["type"], len(mtile)))
|
||||
(tile_name, tile_type, len(mtile)))
|
||||
if len(mtile) == 0:
|
||||
continue
|
||||
|
||||
collisions = set(mall.keys()).intersection(set(mtile.keys()))
|
||||
collisions = set()
|
||||
for bits in mtile.keys():
|
||||
if bits in mall[tile_type].keys():
|
||||
collisions.add(bits)
|
||||
|
||||
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]))
|
||||
" %s: had %s, got %s" % (
|
||||
util.addr2str(addr, word, bit), mall[tile_type][ck],
|
||||
mtile[ck]))
|
||||
raise ValueError("%s collisions" % len(collisions))
|
||||
mall.update(mtile)
|
||||
mall[tile_type].update(mtile)
|
||||
tiles_checked += 1
|
||||
print("Checked %s tiles, %s bits" % (tiles_checked, len(mall)))
|
||||
|
||||
|
||||
def run(db_root, strict=False, verbose=False):
|
||||
def run(db_root, verbose=False):
|
||||
# Start by running a basic check on db files
|
||||
print("Checking individual .db...")
|
||||
parsedb_all(db_root, verbose=verbose)
|
||||
|
|
@ -115,7 +160,7 @@ def run(db_root, strict=False, verbose=False):
|
|||
verbose and print("")
|
||||
|
||||
print("Checking aggregate dir...")
|
||||
check_tile_overlap(db, db_root, strict=strict, verbose=verbose)
|
||||
check_tile_overlap(db, verbose=verbose)
|
||||
|
||||
|
||||
def main():
|
||||
|
|
@ -125,11 +170,10 @@ def main():
|
|||
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)
|
||||
run(args.db_root, verbose=args.verbose)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
|||
Loading…
Reference in New Issue