mirror of https://github.com/openXC7/prjxray.git
114 lines
2.9 KiB
Python
114 lines
2.9 KiB
Python
#!/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
|
|
"""
|
|
This script loads the pin dump of the desired BEL from Vivado and groups pins into ports.
|
|
|
|
Ports that are not connected to the PL are not included. These ports are usually test and
|
|
debug related ports, which are not useful from a P&R perspective.
|
|
|
|
Ports are then written to a JSON file.
|
|
"""
|
|
import argparse
|
|
import csv
|
|
import json
|
|
import re
|
|
|
|
from collections import defaultdict
|
|
|
|
from prjxray.util import OpenSafeFile
|
|
|
|
|
|
def main():
|
|
|
|
BUS_REGEX = re.compile("(.*[A-Z_])([0-9]+)$")
|
|
|
|
# Parse arguments
|
|
parser = argparse.ArgumentParser(
|
|
description=__doc__,
|
|
formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
|
|
parser.add_argument("csv", type=str, help="BEL pin dump file")
|
|
parser.add_argument(
|
|
"json",
|
|
type=str,
|
|
help="Output JSON file with BEL pins grouped into ports")
|
|
|
|
parser.add_argument(
|
|
"--special-pins",
|
|
default="",
|
|
type=str,
|
|
required=False,
|
|
help="Some pins cannot be decoded with the regex")
|
|
|
|
args = parser.parse_args()
|
|
|
|
# Load pin dump
|
|
with OpenSafeFile(args.csv, "r") as fp:
|
|
pin_dump = list(csv.DictReader(fp))
|
|
|
|
# Group pins into ports
|
|
ports = defaultdict(lambda: {"direction": None, "width": 0})
|
|
|
|
special_pins = args.special_pins.split(",")
|
|
|
|
for pin in list(pin_dump):
|
|
pin_name = pin["name"]
|
|
|
|
name = None
|
|
if pin_name in special_pins:
|
|
# Full match
|
|
name = pin_name
|
|
else:
|
|
# Partial match
|
|
for special_pin in special_pins:
|
|
if pin_name.startswith(special_pin):
|
|
name = special_pin
|
|
break
|
|
|
|
if name is None:
|
|
match = BUS_REGEX.match(pin_name)
|
|
if match:
|
|
name = match.group(1)
|
|
else:
|
|
name = pin_name
|
|
|
|
# Get direction
|
|
is_input = int(pin["is_input"])
|
|
is_output = int(pin["is_output"])
|
|
is_clock = int(pin["is_clock"])
|
|
|
|
if is_input:
|
|
direction = "input"
|
|
if is_clock:
|
|
direction = "clock"
|
|
elif is_output:
|
|
direction = "output"
|
|
else:
|
|
assert False, pin
|
|
|
|
# Add to port
|
|
port = ports[name]
|
|
|
|
if port["direction"] is None:
|
|
port["direction"] = direction
|
|
else:
|
|
assert port["direction"] == direction, (port, direction, name)
|
|
|
|
port["width"] += 1
|
|
|
|
# Write pin ports to a JSON file
|
|
with OpenSafeFile(args.json, "w") as fp:
|
|
json.dump(ports, fp, indent=1, sort_keys=True)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|