blob: 6be280ea2acbb0323f9fb6e9dd8fb7f6df6e86c7 [file] [log] [blame]
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 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
""" Load tileconn.json and node_wires.json and verify both node names and
node <-> wire mapping against raw node data. """
import argparse
import datetime
import json
import multiprocessing
import os.path
import progressbar
import pyjson5 as json5
from prjxray import util, lib
from prjxray.grid import Grid
from prjxray.connections import Connections
from prjxray.node_model import NodeModel
def read_json5(fname):
with open(fname, 'r') as f:
return json5.load(f)
def read_raw_node_data(pool, root_dir):
""" Read raw node data from root dir. """
_, nodes = lib.read_root_csv(root_dir)
raw_node_data = []
with progressbar.ProgressBar(max_value=len(nodes)) as bar:
for idx, node in enumerate(pool.imap_unordered(
read_json5,
nodes,
chunksize=20,
)):
bar.update(idx)
raw_node_data.append(node)
bar.update(idx + 1)
return raw_node_data
def main():
parser = argparse.ArgumentParser(
description="Verify tileconn and node_wires.")
parser.add_argument('--root_dir', required=True)
parser.add_argument('--output_dir', required=True)
parser.add_argument('--max_cpu', type=int, default=10)
parser.add_argument('--ignored_wires')
args = parser.parse_args()
print('{} Reading tilegrid'.format(datetime.datetime.now()))
with open(os.path.join(util.get_db_root(), util.get_fabric(),
'tilegrid.json')) as f:
tilegrid = json.load(f)
grid = Grid(db=None, tilegrid=tilegrid)
print('{} Reading tileconn'.format(datetime.datetime.now()))
with open(os.path.join(args.output_dir, 'tileconn.json')) as f:
tileconn = json.load(f)
print(
'{} Reading tile wires from tile types'.format(
datetime.datetime.now()))
tile_wires = {}
for f in os.listdir(args.output_dir):
if f.endswith('.json') and f.startswith('tile_type_'):
if '_site_type_' in f:
continue
tile_type = f[len('tile_type_'):-len('.json')]
with open(os.path.join(args.output_dir, f)) as fin:
tile_wires[tile_type] = json.load(fin)['wires']
connections = Connections(
tilegrid=tilegrid,
tileconn=tileconn,
tile_wires=tile_wires,
)
print('{} Reading node wires'.format(datetime.datetime.now()))
with open(os.path.join(args.output_dir, 'node_wires.json')) as f:
node_wires = json.load(f)
print('{} Build initial node model'.format(datetime.datetime.now()))
node_model = NodeModel(
grid=grid,
connections=connections,
tile_wires=tile_wires,
node_wires=node_wires,
progressbar=progressbar.progressbar)
print('{} Build node model'.format(datetime.datetime.now()))
nodes = set(node_model.get_nodes())
print('{} Read raw node data for testing'.format(datetime.datetime.now()))
processes = min(multiprocessing.cpu_count(), args.max_cpu)
with multiprocessing.Pool(processes=processes) as pool:
raw_node_data = read_raw_node_data(pool, args.root_dir)
print('{} Read ignored wires list'.format(datetime.datetime.now()))
ignored_wires = []
ignored_wires_file = args.ignored_wires
if os.path.exists(ignored_wires_file):
with open(ignored_wires_file) as f:
ignored_wires = set(tuple(l.strip().split('/')) for l in f)
print(
'{} Verify nodes against raw node data'.format(
datetime.datetime.now()))
for node in progressbar.progressbar(raw_node_data):
tile, wire = node['node'].split('/')
assert (tile, wire) in nodes
wires_for_model = node_model.get_wires_for_node(tile, wire)
wires = set()
for wire in node['wires']:
wire_tile, wire_name = wire['wire'].split('/')
wires.add((wire_tile, wire_name))
if len(wires) != len(wires_for_model):
wires2 = set(wires_for_model)
a_minus_b = wires - wires2
b_minus_a = wires2 - wires
assert len(b_minus_a) == 0
assert len(a_minus_b - ignored_wires) == 0, a_minus_b
for tile, wire in wires_for_model:
assert (tile, wire) in wires
if __name__ == '__main__':
main()