From 5e66675c12048adc17f4dfecfc44dec59bd9020d Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 5 Jan 2018 14:04:32 +0100 Subject: [PATCH] Add tileconnloops.py script Signed-off-by: Clifford Wolf --- utils/tileconnloops.py | 82 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 utils/tileconnloops.py diff --git a/utils/tileconnloops.py b/utils/tileconnloops.py new file mode 100644 index 00000000..2bfa3685 --- /dev/null +++ b/utils/tileconnloops.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python3 +# +# Produces a complete database of wires in the ROI and their connections and tests if each +# routing node is a tree (i.e. fails with an error when a loop is found). + +import os, sys, json + +with open("%s/%s/tilegrid.json" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")), "r") as f: + tilegrid = json.load(f)["tiles"] + +with open("%s/%s/tileconn.json" % (os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE")), "r") as f: + tileconn = json.load(f) + +grid = dict() +wirepairs = dict() +remwires = set() + +for tilename, tiledata in tilegrid.items(): + key = (tiledata["grid_x"], tiledata["grid_y"]) + grid[key] = tilename + +def check_tileconn_entry(tilename, tiledata, entry, idx): + if idx == 0: + otheridx = 1 + otherxy = (tiledata["grid_x"] + entry["grid_deltas"][0], tiledata["grid_y"] + entry["grid_deltas"][1]) + else: + otheridx = 0 + otherxy = (tiledata["grid_x"] - entry["grid_deltas"][0], tiledata["grid_y"] - entry["grid_deltas"][1]) + + if otherxy not in grid: + return + + othertilename = grid[otherxy] + othertiledata = tilegrid[othertilename] + + if othertiledata["type"] != entry["tile_types"][otheridx]: + return + + print(" Found relevant entry (%s %s %d %d): %s" % (entry["tile_types"][0], entry["tile_types"][1], + entry["grid_deltas"][0], entry["grid_deltas"][1], othertilename)) + + for pair in entry["wire_pairs"]: + wirename = "%s/%s" % (tilename, pair[idx]) + otherwirename = "%s/%s" % (othertilename, pair[otheridx]) + + remwires.add(wirename) + remwires.add(otherwirename) + + if wirename not in wirepairs: + wirepairs[wirename] = set() + wirepairs[wirename].add(otherwirename) + + if otherwirename not in wirepairs: + wirepairs[otherwirename] = set() + wirepairs[otherwirename].add(wirename) + +for tilename, tiledata in tilegrid.items(): + print("Connecting wires in tile %s." % tilename) + for entry in tileconn: + if entry["tile_types"][0] == tiledata["type"]: + check_tileconn_entry(tilename, tiledata, entry, 0) + if entry["tile_types"][1] == tiledata["type"]: + check_tileconn_entry(tilename, tiledata, entry, 1) + +def check_wire(wire, source): + for next_wire in wirepairs[wire]: + if next_wire == source: + continue + print(" %s" % next_wire) + if next_wire not in remwires: + print(" ** FOUND LOOP IN THIS NODE **") + sys.exit(1) + remwires.remove(next_wire) + check_wire(next_wire, wire) + +while len(remwires): + wire = remwires.pop() + print("Checking %s:" % wire) + check_wire(wire, None) + +print("NO LOOP FOUND: OK") +