diff --git a/utils/bits2fasm.py b/utils/bits2fasm.py index cfdff8d2..f280407d 100755 --- a/utils/bits2fasm.py +++ b/utils/bits2fasm.py @@ -26,6 +26,26 @@ def comment(s): enumdb = dict() +# TODO: migrate to library +def process_db(tile_type, process): + fns = [ + # sites + "%s/%s/segbits_%s.db" % ( + os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"), + tile_type.lower()), + # interconnect + "%s/%s/segbits_int_%s.db" % ( + os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"), + tile_type[-1].lower()), + ] + + for fn in fns: + if os.path.exists(fn): + with open(fn, "r") as f: + for line in f: + process(line) + + def get_enums(tile_type): if tile_type in enumdb: return enumdb[tile_type] @@ -33,10 +53,8 @@ def get_enums(tile_type): enumdb[tile_type] = {} def process(l): - l = l.strip() - # CLBLM_L.SLICEL_X1.ALUT.INIT[10] 29_14 - parts = line.split() + parts = l.strip().split() name = parts[0] bit_vals = parts[1:] @@ -44,23 +62,7 @@ def get_enums(tile_type): # only 1 bit => non-enumerated value enumdb[tile_type][name] = len(bit_vals) != 1 - main_fn = "%s/%s/segbits_%s.db" % ( - os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"), - tile_type.lower()) - int_fn = "%s/%s/segbits_int_%s.db" % ( - os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"), - tile_type[-1].lower()) - - if not os.path.exists(main_fn) or not os.path.exists(int_fn): - raise NoDB(tile_type) - - with open(main_fn, "r") as f: - for line in f: - process(line) - - with open(int_fn, "r") as f: - for line in f: - process(line) + process_db(tile_type, process) return enumdb[tile_type] @@ -158,9 +160,16 @@ def tag_matched(entry, segbits): segbits.remove(bit) -def seg_decode(seginfo, segbits): +decode_warnings = set() + + +def seg_decode(seginfo, segbits, verbose=False): fasms = set() + # already failed? + if seginfo["type"] in decode_warnings: + return fasms + try: for entry in get_database(seginfo["type"]): if not tagmatch(entry, segbits): @@ -169,7 +178,9 @@ def seg_decode(seginfo, segbits): #fasms.add('%s.%s 1' % (seginfo['tile_name'], entry[0])) fasms.add(mk_fasm(seginfo, entry)) except NoDB: - print("WARNING: failed to load DB for %s" % seginfo["type"]) + verbose and comment( + "WARNING: failed to load DB for %s" % seginfo["type"]) + decode_warnings.add(seginfo["type"]) return fasms @@ -184,7 +195,7 @@ def handle_segment(segname, grid, bitdata, verbose=False): segbits = mk_segbits(seginfo, bitdata) - fasms = seg_decode(seginfo, segbits) + fasms = seg_decode(seginfo, segbits, verbose=verbose) # Found something to print? if len(segbits) == 0 and len(fasms) == 0: diff --git a/utils/fasm2frames.py b/utils/fasm2frames.py index 72cab3ed..361baa8e 100755 --- a/utils/fasm2frames.py +++ b/utils/fasm2frames.py @@ -23,6 +23,26 @@ def parsebit(val): return int(seg_word_column), int(word_bit_n), isset +# TODO: migrate to library +def process_db(tile_type, process): + fns = [ + # sites + "%s/%s/segbits_%s.db" % ( + os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"), + tile_type.lower()), + # interconnect + "%s/%s/segbits_int_%s.db" % ( + os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"), + tile_type[-1].lower()), + ] + + for fn in fns: + if os.path.exists(fn): + with open(fn, "r") as f: + for line in f: + process(line) + + ''' Loosely based on segprint function Maybe better to return as two distinct dictionaries? @@ -44,10 +64,8 @@ def get_database(tile_type): segbitsdb[tile_type] = {} def process(l): - l = l.strip() - # CLBLM_L.SLICEL_X1.ALUT.INIT[10] 29_14 - parts = line.split() + parts = l.strip().split() name = parts[0] bit_vals = parts[1:] @@ -59,6 +77,7 @@ def get_database(tile_type): raise Exception( "Expect single bit DB entries to be set, got %s" % l) # Treat like an enumerated value with keys 0 or 1 + assert name not in segbitsdb[tile_type] segbitsdb[tile_type][name] = { '0': [(seg_word_column, word_bit_n, 0)], '1': [(seg_word_column, word_bit_n, 1)], @@ -67,30 +86,14 @@ def get_database(tile_type): # An enumerated value # Split the base name and selected key m = re.match(r'(.+)[.](.+)', name) - name = m.group(1) + namepart = m.group(1) key = m.group(2) # May or may not be the first key encountered - bits_map = segbitsdb[tile_type].setdefault(name, {}) + bits_map = segbitsdb[tile_type].setdefault(namepart, {}) bits_map[key] = [parsebit(x) for x in bit_vals] - main_fn = "%s/%s/segbits_%s.db" % ( - os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"), - tile_type.lower()) - int_fn = "%s/%s/segbits_int_%s.db" % ( - os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"), - tile_type[-1].lower()) - - if not os.path.exists(main_fn) or not os.path.exists(int_fn): - raise Exception(tile_type) - - with open(main_fn, "r") as f: - for line in f: - process(line) - - with open(int_fn, "r") as f: - for line in f: - process(line) + process_db(tile_type, process) return segbitsdb[tile_type] diff --git a/utils/segprint.py b/utils/segprint.py index 51a1cae9..19d8031b 100755 --- a/utils/segprint.py +++ b/utils/segprint.py @@ -16,33 +16,41 @@ segbitsdb = dict() # TODO: migrate to library +def process_db(tile_type, process): + fns = [ + # sites + "%s/%s/segbits_%s.db" % ( + os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"), + tile_type.lower()), + # interconnect + "%s/%s/segbits_int_%s.db" % ( + os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"), + tile_type[-1].lower()), + ] + + for fn in fns: + if os.path.exists(fn): + with open(fn, "r") as f: + for line in f: + process(line) + + def get_database(tile_type): + tags = list() + if tile_type in segbitsdb: return segbitsdb[tile_type] - main_fn = "%s/%s/segbits_%s.db" % ( - os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"), - tile_type.lower()) - int_fn = "%s/%s/segbits_int_%s.db" % ( - os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"), - tile_type[-1].lower()) + def process(l): + tags.append(l.split()) - if not os.path.exists(main_fn) or not os.path.exists(int_fn): + process_db(tile_type, process) + + if len(tags) == 0: raise NoDB(tile_type) - segbitsdb[tile_type] = list() - - with open(main_fn, "r") as f: - for line in f: - line = line.split() - segbitsdb[tile_type].append(line) - - with open(int_fn, "r") as f: - for line in f: - line = line.split() - segbitsdb[tile_type].append(line) - - return segbitsdb[tile_type] + segbitsdb[tile_type] = tags + return tags def mk_segbits(seginfo, bitdata): @@ -107,8 +115,16 @@ def tag_matched(entry, segbits): segbits.remove(bit) -def seg_decode(flag_decode_emit, seginfo, segbits): +decode_warnings = set() + + +def seg_decode(flag_decode_emit, seginfo, segbits, verbose=False): segtags = set() + + # already failed? + if seginfo["type"] in decode_warnings: + return segtags + try: for entry in get_database(seginfo["type"]): if not tagmatch(entry, segbits): @@ -117,13 +133,20 @@ def seg_decode(flag_decode_emit, seginfo, segbits): if flag_decode_emit: segtags.add(entry[0]) except NoDB: - print("WARNING: failed to load DB for %s" % seginfo["type"]) + verbose and print( + "WARNING: failed to load DB for %s" % seginfo["type"]) + decode_warnings.add(seginfo["type"]) return segtags def handle_segment( - segname, grid, bitdata, flag_decode_emit, flag_decode_omit, - omit_empty_segs): + segname, + grid, + bitdata, + flag_decode_emit, + flag_decode_omit, + omit_empty_segs, + verbose=False): assert segname @@ -135,7 +158,8 @@ def handle_segment( segbits = mk_segbits(seginfo, bitdata) if flag_decode_emit or flag_decode_omit: - segtags = seg_decode(flag_decode_emit, seginfo, segbits) + segtags = seg_decode( + flag_decode_emit, seginfo, segbits, verbose=verbose) else: segtags = set() @@ -222,7 +246,8 @@ def run( omit_empty_segs=False, flag_unknown_bits=False, flag_decode_emit=False, - flag_decode_omit=False): + flag_decode_omit=False, + verbose=False): grid = mk_grid() bitdata = load_bitdata(bits_file) @@ -244,8 +269,13 @@ def run( # revisit? for segname in segnames: handle_segment( - segname, grid, bitdata, flag_decode_emit, flag_decode_omit, - omit_empty_segs) + segname, + grid, + bitdata, + flag_decode_emit, + flag_decode_omit, + omit_empty_segs, + verbose=verbose) def main(): @@ -277,7 +307,9 @@ def main(): 'segnames', nargs='*', help='List of tile or tile:block to print') args = parser.parse_args() - run(args.bits_file, args.segnames, args.z, args.b, args.d, args.D) + run( + args.bits_file, args.segnames, args.z, args.b, args.d, args.D, + args.verbose) if __name__ == '__main__':