forked from f4pga/prjxray
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tileconnloops.py
executable file
·106 lines (85 loc) · 3.42 KB
/
tileconnloops.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/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()