diff --git a/prjxray/util.py b/prjxray/util.py index 9494ca19..4ff8b54a 100644 --- a/prjxray/util.py +++ b/prjxray/util.py @@ -1,7 +1,7 @@ import os import re from .roi import Roi - +from prjxray.grid import BlockType def get_db_root(): # Used during tilegrid db bootstrap @@ -172,7 +172,7 @@ def addr2btype(base_addr): return block_type_i2s[block_type_i] -def gen_tile_bits(db_file, tilej, strict=False, verbose=False): +def gen_tile_bits(tile_segbits, tile, strict=False, verbose=False): ''' For given tile and corresponding db_file structure yield (absolute address, absolute FDRI bit offset, tag) @@ -182,20 +182,22 @@ def gen_tile_bits(db_file, tilej, strict=False, verbose=False): For each tag bit in the corresponding block_type entry, calculate absolute address and bit offsets ''' - 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) - bitbase = 32 * blockj["offset"] - frames = tilej["bits"][block_type]["frames"] + for block_type in tile_segbits: + assert block_type.value in tile["bits"], "block type %s is not present in current tile" % block_type.value - for line, (tag, bits, mode) in db_file[block_type]: - assert mode is None - for bitstr in bits: + block = tile["bits"][block_type.value] + + baseaddr = int(block["baseaddr"], 0) + bitbase = 32 * block["offset"] + frames = block["frames"] + + for tag in tile_segbits[block_type]: + for bit in tile_segbits[block_type][tag]: # 31_06 - _bit_inv, (bit_addroff, bit_bitoff) = parse_tagbit(bitstr) - assert bit_addroff <= frames, "ERROR: bit out of bound" - yield (baseaddr + bit_addroff, bitbase + bit_bitoff, tag) + word_column, word_bit, isset = bit + assert word_column <= frames, "ERROR: bit out of bound --> word_column = %s; frames = %s" % (word_column, frames) + yield word_column + baseaddr, word_bit + bitbase, tag def specn(): diff --git a/utils/checkdb.py b/utils/checkdb.py index aafc62fb..a4959356 100755 --- a/utils/checkdb.py +++ b/utils/checkdb.py @@ -17,7 +17,7 @@ import parsedb import glob -def make_tile_mask(db_file, tile_name, tilej, strict=False, verbose=False): +def make_tile_mask(tile_segbits, tile_name, tilej, strict=False, verbose=False): ''' Return dict key: (address, bit index) @@ -30,7 +30,7 @@ def make_tile_mask(db_file, tile_name, tilej, strict=False, verbose=False): ret = dict() for absaddr, bitaddr, tag in util.gen_tile_bits( - db_file, tilej, strict=strict, verbose=verbose): + tile_segbits, tilej, strict=strict, verbose=verbose): name = "%s.%s" % (tile_name, tag) ret.setdefault((absaddr, bitaddr), name) return ret @@ -54,33 +54,6 @@ def parsedb_all(db_root, verbose=False): 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): ''' Verifies that no two tiles use the same bit @@ -91,8 +64,8 @@ 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 = set() - db_files = dict() + tiles_type_done = dict() + tile_segbits = dict() tiles_checked = 0 @@ -100,15 +73,22 @@ def check_tile_overlap(db, db_root, strict=False, verbose=False): tile_type = tilej["type"] if tile_type not in tiles_type_done: - db_files = parsedb_file(db_root, db_files, tilej) - tiles_type_done.add(tile_type) + segbits = db.get_tile_segbits(tile_type).segbits + tile_segbits[tile_type] = segbits + + # 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 - if tile_type not in mall: - verbose and print("Adding tile type: %s" % tile_type) mall[tile_type] = {} + if tiles_type_done[tile_type]: + continue + mtile = make_tile_mask( - db_files[tile_type], + tile_segbits[tile_type], tile_name, tilej, strict=strict, @@ -119,8 +99,11 @@ def check_tile_overlap(db, db_root, strict=False, verbose=False): if len(mtile) == 0: continue - collisions = set(mall[tile_type].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):