<filename>xc/common/utils/prjxray_create_ioplace.py
""" Convert a PCF file into a VPR io.place file. """
from __future__ import print_function
import argparse
import csv
import json
import sys
import os
import vpr_io_place
from lib.parse_pcf import parse_simple_pcf


def main():
    parser = argparse.ArgumentParser(
        description='Convert a PCF file into a VPR io.place file.'
    )
    parser.add_argument(
        "--pcf",
        '-p',
        "-P",
        type=argparse.FileType('r'),
        required=False,
        help='PCF input file'
    )
    parser.add_argument(
        "--blif",
        '-b',
        type=argparse.FileType('r'),
        required=True,
        help='BLIF / eBLIF file'
    )
    parser.add_argument(
        "--map",
        '-m',
        "-M",
        type=argparse.FileType('r'),
        required=True,
        help='Pin map CSV file'
    )
    parser.add_argument(
        "--output",
        '-o',
        "-O",
        type=argparse.FileType('w'),
        default=sys.stdout,
        help='The output io.place file'
    )
    parser.add_argument(
        "--iostandard_defs", help='(optional) Output IOSTANDARD def file'
    )
    parser.add_argument(
        "--iostandard",
        default="LVCMOS33",
        help='Default IOSTANDARD to use for pins',
    )
    parser.add_argument(
        "--drive",
        type=int,
        default=12,
        help='Default drive to use for pins',
    )
    parser.add_argument(
        "--net",
        '-n',
        type=argparse.FileType('r'),
        required=True,
        help='top.net file'
    )

    args = parser.parse_args()

    io_place = vpr_io_place.IoPlace()
    io_place.read_io_list_from_eblif(args.blif)
    io_place.load_block_names_from_net_file(args.net)

    # Map of pad names to VPR locations.
    pad_map = {}

    for pin_map_entry in csv.DictReader(args.map):
        pad_map[pin_map_entry['name']] = (
            (
                int(pin_map_entry['x']),
                int(pin_map_entry['y']),
                int(pin_map_entry['z']),
            ),
            pin_map_entry['is_output'],
            pin_map_entry['iob'],
        )

    iostandard_defs = {}

    # Load iostandard constraints. This is a temporary workaround that allows
    # to pass them into fasm2bels. As soon as there is support for XDC this
    # will not be needed anymore.
    # If there is a JSON file with the same name as the PCF file then it is
    # loaded and used as iostandard constraint source NOT for the design but
    # to be used in fasm2bels.
    iostandard_constraints = {}

    if args.pcf:
        fname = args.pcf.name.replace(".pcf", ".json")
        if os.path.isfile(fname):
            with open(fname, "r") as fp:
                iostandard_constraints = json.load(fp)
    net_to_pad = io_place.net_to_pad
    if args.pcf:
        pcf_constraints = parse_simple_pcf(args.pcf)
        net_to_pad |= set(
            (constr.net, constr.pad) for constr in pcf_constraints
        )
    # Check for conflicting pad constraints
    net_to_pad_map = dict()
    for (net, pad) in net_to_pad:
        if net not in net_to_pad_map:
            net_to_pad_map[net] = pad
        elif pad != net_to_pad_map[net]:
            print(
                """ERROR:
Conflicting pad constraints for net {}:\n{}\n{}""".format(
                    net, pad, net_to_pad_map[net]
                ),
                file=sys.stderr
            )
            sys.exit(1)
    # Constrain nets
    for net, pad in net_to_pad:
        if not io_place.is_net(net):
            print(
                """ERROR:
Constrained net {} is not in available netlist:\n{}""".format(
                    net, '\n'.join(io_place.get_nets())
                ),
                file=sys.stderr
            )
            sys.exit(1)

        if pad not in pad_map:
            print(
                """ERROR:
Constrained pad {} is not in available pad map:\n{}""".format(
                    pad, '\n'.join(sorted(pad_map.keys()))
                ),
                file=sys.stderr
            )
            sys.exit(1)

        loc, is_output, iob = pad_map[pad]
        io_place.constrain_net(
            net_name=net,
            loc=loc,
            comment="set_property LOC {} [get_ports {{{}}}]".format(pad, net)
        )
        if pad in iostandard_constraints:
            iostandard_defs[iob] = iostandard_constraints[pad]
        else:
            if is_output:
                iostandard_defs[iob] = {
                    'DRIVE': args.drive,
                    'IOSTANDARD': args.iostandard,
                }
            else:
                iostandard_defs[iob] = {
                    'IOSTANDARD': args.iostandard,
                }

    io_place.output_io_place(args.output)

    # Write iostandard definitions
    if args.iostandard_defs:
        with open(args.iostandard_defs, 'w') as f:
            json.dump(iostandard_defs, f, indent=2)


if __name__ == '__main__':
    main()

<filename>xc/common/utils/prjxray_create_ioplace.py
""" Convert a PCF file into a VPR io.place file. """
from __future__ import print_function
import argparse
import csv
import json
import sys
import os
import vpr_io_place
from lib.parse_pcf import parse_simple_pcf


def main():
    parser = argparse.ArgumentParser(
        description='Convert a PCF file into a VPR io.place file.'
    )
    parser.add_argument(
        "--pcf",
        '-p',
        "-P",
        type=argparse.FileType('r'),
        required=False,
        help='PCF input file'
    )
    parser.add_argument(
        "--blif",
        '-b',
        type=argparse.FileType('r'),
        required=True,
        help='BLIF / eBLIF file'
    )
    parser.add_argument(
        "--map",
        '-m',
        "-M",
        type=argparse.FileType('r'),
        required=True,
        help='Pin map CSV file'
    )
    parser.add_argument(
        "--output",
        '-o',
        "-O",
        type=argparse.FileType('w'),
        default=sys.stdout,
        help='The output io.place file'
    )
    parser.add_argument(
        "--iostandard_defs", help='(optional) Output IOSTANDARD def file'
    )
    parser.add_argument(
        "--iostandard",
        default="LVCMOS33",
        help='Default IOSTANDARD to use for pins',
    )
    parser.add_argument(
        "--drive",
        type=int,
        default=12,
        help='Default drive to use for pins',
    )
    parser.add_argument(
        "--net",
        '-n',
        type=argparse.FileType('r'),
        required=True,
        help='top.net file'
    )

    args = parser.parse_args()

    io_place = vpr_io_place.IoPlace()
    io_place.read_io_list_from_eblif(args.blif)
    io_place.load_block_names_from_net_file(args.net)

    # Map of pad names to VPR locations.
    pad_map = {}

    for pin_map_entry in csv.DictReader(args.map):
        pad_map[pin_map_entry['name']] = (
            (
                int(pin_map_entry['x']),
                int(pin_map_entry['y']),
                int(pin_map_entry['z']),
            ),
            pin_map_entry['is_output'],
            pin_map_entry['iob'],
        )

    iostandard_defs = {}

    # Load iostandard constraints. This is a temporary workaround that allows
    # to pass them into fasm2bels. As soon as there is support for XDC this
    # will not be needed anymore.
    # If there is a JSON file with the same name as the PCF file then it is
    # loaded and used as iostandard constraint source NOT for the design but
    # to be used in fasm2bels.
    iostandard_constraints = {}

    if args.pcf:
        fname = args.pcf.name.replace(".pcf", ".json")
        if os.path.isfile(fname):
            with open(fname, "r") as fp:
                iostandard_constraints = json.load(fp)
    net_to_pad = io_place.net_to_pad
    if args.pcf:
        pcf_constraints = parse_simple_pcf(args.pcf)
        net_to_pad |= set(
            (constr.net, constr.pad) for constr in pcf_constraints
        )
    # Check for conflicting pad constraints
    net_to_pad_map = dict()
    for (net, pad) in net_to_pad:
        if net not in net_to_pad_map:
            net_to_pad_map[net] = pad
        elif pad != net_to_pad_map[net]:
            print(
                """ERROR:
Conflicting pad constraints for net {}:\n{}\n{}""".format(
                    net, pad, net_to_pad_map[net]
                ),
                file=sys.stderr
            )
            sys.exit(1)
    # Constrain nets
    for net, pad in net_to_pad:
        if not io_place.is_net(net):
            print(
                """ERROR:
Constrained net {} is not in available netlist:\n{}""".format(
                    net, '\n'.join(io_place.get_nets())
                ),
                file=sys.stderr
            )
            sys.exit(1)

        if pad not in pad_map:
            print(
                """ERROR:
Constrained pad {} is not in available pad map:\n{}""".format(
                    pad, '\n'.join(sorted(pad_map.keys()))
                ),
                file=sys.stderr
            )
            sys.exit(1)

        loc, is_output, iob = pad_map[pad]
        io_place.constrain_net(
            net_name=net,
            loc=loc,
            comment="set_property LOC {} [get_ports {{{}}}]".format(pad, net)
        )
        if pad in iostandard_constraints:
            iostandard_defs[iob] = iostandard_constraints[pad]
        else:
            if is_output:
                iostandard_defs[iob] = {
                    'DRIVE': args.drive,
                    'IOSTANDARD': args.iostandard,
                }
            else:
                iostandard_defs[iob] = {
                    'IOSTANDARD': args.iostandard,
                }

    io_place.output_io_place(args.output)

    # Write iostandard definitions
    if args.iostandard_defs:
        with open(args.iostandard_defs, 'w') as f:
            json.dump(iostandard_defs, f, indent=2)


if __name__ == '__main__':
    main()

Convert a PCF file into a VPR io.place file. # Map of pad names to VPR locations. # Load iostandard constraints. This is a temporary workaround that allows # to pass them into fasm2bels. As soon as there is support for XDC this # will not be needed anymore. # If there is a JSON file with the same name as the PCF file then it is # loaded and used as iostandard constraint source NOT for the design but # to be used in fasm2bels. # Check for conflicting pad constraints ERROR: Conflicting pad constraints for net {}:\n{}\n{} # Constrain nets ERROR: Constrained net {} is not in available netlist:\n{} ERROR: Constrained pad {} is not in available pad map:\n{} # Write iostandard definitions