| #!/usr/bin/env python3 |
| # -*- coding: utf-8 -*- |
| # |
| # Copyright (C) 2017-2020 The Project X-Ray Authors. |
| # |
| # Use of this source code is governed by a ISC-style |
| # license that can be found in the LICENSE file or at |
| # https://opensource.org/licenses/ISC |
| # |
| # SPDX-License-Identifier: ISC |
| # |
| # 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 |
| |
| from prjxray.util import OpenSafeFile |
| |
| def main(): |
| with OpenSafeFile("%s/%s/tilegrid.json" % (os.getenv("XRAY_DATABASE_DIR"), |
| os.getenv("XRAY_DATABASE")), "r") as f: |
| tilegrid = json.load(f) |
| |
| with OpenSafeFile("%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") |
| |
| |
| if __name__ == "__main__": |
| main() |