diff --git a/prjxray/util.py b/prjxray/util.py index 0b4cf689..35f9939f 100644 --- a/prjxray/util.py +++ b/prjxray/util.py @@ -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") diff --git a/utils/checkdb.py b/utils/checkdb.py index 425cf4d6..d788e3b3 100755 --- a/utils/checkdb.py +++ b/utils/checkdb.py @@ -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__':