diff --git a/prjxray/util.py b/prjxray/util.py index 390e0c81..3fa592c5 100644 --- a/prjxray/util.py +++ b/prjxray/util.py @@ -71,3 +71,23 @@ def db_root_arg(parser): db_root_kwargs['required'] = False db_root_kwargs['default'] = os.path.join(database_dir, database) parser.add_argument('--db-root', help="Database root.", **db_root_kwargs) + + +def parse_db_line(line): + parts = line.split() + # Ex: CLBLL_L.SLICEL_X0.AMUX.A5Q + assert len(parts), "Empty line" + tag = parts[0] + assert re.match(r'[A-Z0-9_.]+', + tag), "Invalid tag name: %s, line: %s" % (tag, line) + orig_bits = line.replace(tag + " ", "") + # <0 candidates> etc + if "<" in orig_bits: + return tag, set(), orig_bits + + # Ex: !30_06 !30_08 !30_11 30_07 + bits = frozenset(parts[1:]) + for bit in bits: + assert re.match( + r'[!]*[0-9][0-9]_[0-9][0-9]', bit), "Invalid bit: %s" % bit + return tag, bits, None diff --git a/utils/dbfixup.py b/utils/dbfixup.py index 1dd5f872..4f069da7 100755 --- a/utils/dbfixup.py +++ b/utils/dbfixup.py @@ -17,20 +17,6 @@ clb_int_zero_db = [ ] -def parse_line(line): - parts = line.split() - # Ex: CLBLL_L.SLICEL_X0.AMUX.A5Q - tag = parts[0] - orig_bits = line.replace(tag + " ", "") - # <0 candidates> etc - if "<" in orig_bits: - return tag, set(), orig_bits - - # Ex: !30_06 !30_08 !30_11 30_07 - bits = set(parts[1:]) - return tag, bits, None - - def zero_range(bits, wordmin, wordmax): """ If any bits occur wordmin <= word <= wordmax, @@ -134,7 +120,7 @@ def add_zero_bits(fn_in, fn_out, zero_db, clb_int=False, verbose=False): if line == llast: continue - tag, bits, mode = parse_line(line) + tag, bits, mode = util.parse_db_line(line) assert mode not in ( "", ""), "Entries must be resolved. line: %s" % (line, ) @@ -146,6 +132,7 @@ def add_zero_bits(fn_in, fn_out, zero_db, clb_int=False, verbose=False): """ if clb_int: zero_range(bits, 22, 25) + bits = set(bits) zero_groups( tag, bits, zero_db, strict=not clb_int, verbose=verbose) diff --git a/utils/environment.sh b/utils/environment.sh index fb69da52..76b1e6bb 100644 --- a/utils/environment.sh +++ b/utils/environment.sh @@ -26,4 +26,5 @@ export XRAY_BITS2FASM="python3 ${XRAY_UTILS_DIR}/bits2fasm.py" export XRAY_FASM2FRAMES="python3 ${XRAY_UTILS_DIR}/fasm2frames.py" export XRAY_BITTOOL="${XRAY_TOOLS_DIR}/bittool" export XRAY_BLOCKWIDTH="python3 ${XRAY_UTILS_DIR}/blockwidth.py" +export XRAY_PARSEDB="python3 ${XRAY_UTILS_DIR}/parsedb.py" diff --git a/utils/mergedb.sh b/utils/mergedb.sh index 391d3e40..848d50f3 100755 --- a/utils/mergedb.sh +++ b/utils/mergedb.sh @@ -71,6 +71,6 @@ esac touch "$db" sort -u "$tmp1" "$db" | grep -v '<.*>' > "$tmp2" || true -mv "$tmp2" "$db" +${XRAY_PARSEDB} --strict "$tmp2" "$db" rm -f "$tmp1" diff --git a/utils/parsedb.py b/utils/parsedb.py new file mode 100755 index 00000000..e3837798 --- /dev/null +++ b/utils/parsedb.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 + +from prjxray import util + + +def run(fnin, fnout=None, strict=False, verbose=False): + lines = open(fnin, 'r').read().split('\n') + tags = set() + bitss = set() + for line in lines: + line = line.strip() + if line == '': + continue + tag, bits, mode = util.parse_db_line(line) + if strict: + assert not mode, "strict: got ill defined line: %s" % (line, ) + assert tag not in tags, "strict: got duplicate tag %s (ex: %s)" % ( + tag, line) + assert bits not in bitss, "strict: got duplicate bits %s (ex: %s)" % ( + bits, line) + tags.add(tag) + bitss.add(bits) + + if fnout: + with open(fnout, "w") as fout: + for line in sorted(lines): + line = line.strip() + if line == '': + continue + fout.write(line + '\n') + + +def main(): + import argparse + + parser = argparse.ArgumentParser( + description="Parse a db, check for consistency") + + util.db_root_arg(parser) + parser.add_argument('--verbose', action='store_true', help='') + parser.add_argument( + '--strict', + action='store_true', + help='Complain on unresolved entries (ex: <0 candidates>, )') + parser.add_argument('fin', help='') + parser.add_argument('fout', nargs='?', help='') + args = parser.parse_args() + + run(args.fin, args.fout, strict=args.strict, verbose=args.verbose) + + +if __name__ == '__main__': + main()