#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2019-2022 F4PGA Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0


""" Convert a PCF file into a VPR io.place file. """
from __future__ import print_function
import argparse
import sys
import csv
from os import environ
import lxml.etree as ET
import constraint
import prjxray.db
from collections import defaultdict, OrderedDict, namedtuple
from pathlib import Path
from subprocess import run as subprocess_run

from f4pga.utils.eblif import parse_blif


PlaceConstraint = namedtuple("PlaceConstraint", "name x y z comment")

HEADER_TEMPLATE = """\
#{name:<{nl}} x   y   z    pcf_line
#{s:-^{nl}} --  --  -    ----"""

CONSTRAINT_TEMPLATE = "{name:<{nl}} {x: 3} {y: 3} {z: 2}  # {comment}"


def get_root_cluster(curr):
    while True:
        parent = curr.getparent()
        if parent is None:
            return None

        parent_parent = parent.getparent()
        if parent_parent is None:
            return curr

        curr = parent


class PlaceConstraints(object):
    def __init__(self, net_file):
        self.constraints = OrderedDict()
        self.block_to_loc = dict()

        net_xml = ET.parse(net_file)
        self.net_root = net_xml.getroot()

    def load_loc_sites_from_net_file(self):
        """
        .place files expect top-level block (cluster) names, not net names, so
        build a mapping from net names to block names from the .net file.
        """
        self.net_to_block = {}
        self.block_to_root_block = {}

        for el in self.net_root.iter("block"):
            root_block = get_root_cluster(el)
            if root_block is not None:
                self.block_to_root_block[el.attrib["name"]] = root_block.attrib["name"]

        for attr in self.net_root.xpath("//attribute"):
            name = attr.attrib["name"]
            if name != "LOC":
                continue

            # Get block name
            top_block = attr.getparent()
            assert top_block is not None
            while top_block.getparent() is not self.net_root:
                assert top_block is not None
                top_block = top_block.getparent()

            self.block_to_loc[top_block.get("name")] = attr.text

    def constrain_block(self, block_name, loc, comment=""):
        assert len(loc) == 3
        assert block_name not in self.constraints, block_name

        place_constraint = PlaceConstraint(
            name=block_name,
            x=loc[0],
            y=loc[1],
            z=loc[2],
            comment=comment,
        )

        root_block = self.block_to_root_block[block_name]

        self.constraints[root_block] = place_constraint

    def output_place_constraints(self, f):
        if not self.constraints:
            return

        max_name_length = max(len(c.name) for c in self.constraints.values())

        constrained_blocks = {}

        for vpr_net, constraint in self.constraints.items():
            name = constraint.name

            # This block is already constrained, check if there is no
            # conflict there.
            if name in constrained_blocks:
                existing = constrained_blocks[name]

                if existing.x != constraint.x or existing.y != constraint.y or existing.z != constraint.z:
                    print("Error: block '{}' has multiple conflicting constraints!".format(name))
                    print("", constrained_blocks[name])
                    print("", constraint)
                    exit(-1)

                # Don't write the second constraing
                continue

            # omit if no corresponding block name for the net
            if name is not None:
                print(
                    CONSTRAINT_TEMPLATE.format(
                        name=name,
                        nl=max_name_length,
                        x=constraint.x,
                        y=constraint.y,
                        z=constraint.z,
                        comment=constraint.comment,
                    ),
                    file=f,
                )

                # Add to constrained block list
                constrained_blocks[name] = constraint

    def get_loc_sites(self):
        """Yields user-constraints (block, location) pairs"""

        if self.block_to_loc is None:
            return

        for loc in self.block_to_loc:
            yield (loc, self.block_to_loc[loc])

    def get_used_instances(self, instance):
        """
        Returns a list containing the root clusters of the specified instances in the packed netlist
        that are marked as used.

        An instance is marked as used when the XML element relative to the instance name has
        children tags.

        E.g.:
            <block name="idelayctrl_block" instance="IDELAYCTRL[0]">
                <inputs>
                    <port name="REFCLK">refclk</port>
                </inputs>
                ...
            </block>
            ...

            <block name="open" instance="IDELAYCTRL[0]" />
        """

        instances = list()

        for el in self.net_root.iter("block"):
            inst = el.attrib["instance"]
            if instance in inst:
                if len(el.getchildren()) != 0:
                    instances.append(get_root_cluster(el).attrib["name"])

        return instances


CLOCKS = {
    "PLLE2_ADV_VPR": {
        "sinks": frozenset(("CLKFBIN", "CLKIN1", "CLKIN2", "DCLK")),
        "sources": frozenset(("CLKFBOUT", "CLKOUT0", "CLKOUT1", "CLKOUT2", "CLKOUT3", "CLKOUT4", "CLKOUT5")),
        "type": "PLLE2_ADV",
    },
    "MMCME2_ADV_VPR": {
        "sinks": frozenset(("CLKFBIN", "CLKIN1", "CLKIN2", "DCLK", "PSCLK")),
        "sources": frozenset(
            (
                "CLKFBOUT",
                "CLKFBOUTB",
                "CLKOUT0",
                "CLKOUT0B",
                "CLKOUT1",
                "CLKOUT1B",
                "CLKOUT2",
                "CLKOUT2B",
                "CLKOUT3",
                "CLKOUT3B",
                "CLKOUT4",
                "CLKOUT5",
                "CLKOUT6",
            )
        ),
        "type": "MMCME2_ADV",
    },
    "BUFGCTRL_VPR": {
        "sinks": frozenset(("I0", "I1")),
        "sources": frozenset(("O",)),
        "type": "BUFGCTRL",
    },
    "PS7_VPR": {
        "sinks": frozenset(
            (
                "DMA0ACLK",
                "DMA1ACLK",
                "DMA2ACLK",
                "DMA3ACLK",
                "EMIOENET0GMIIRXCLK",
                "EMIOENET0GMIITXCLK",
                "EMIOENET1GMIIRXCLK",
                "EMIOENET1GMIITXCLK",
                "EMIOSDIO0CLKFB",
                "EMIOSDIO1CLKFB",
                "EMIOSPI0SCLKI",
                "EMIOSPI1SCLKI",
                "EMIOTRACECLK",
                "EMIOTTC0CLKI[0]",
                "EMIOTTC0CLKI[1]",
                "EMIOTTC0CLKI[2]",
                "EMIOTTC1CLKI[0]",
                "EMIOTTC1CLKI[1]",
                "EMIOTTC1CLKI[2]",
                "EMIOWDTCLKI",
                "FCLKCLKTRIGN[0]",
                "FCLKCLKTRIGN[1]",
                "FCLKCLKTRIGN[2]",
                "FCLKCLKTRIGN[3]",
                "MAXIGP0ACLK",
                "MAXIGP1ACLK",
                "SAXIACPACLK",
                "SAXIGP0ACLK",
                "SAXIGP1ACLK",
                "SAXIHP0ACLK",
                "SAXIHP1ACLK",
                "SAXIHP2ACLK",
                "SAXIHP3ACLK",
            )
        ),
        "sources": frozenset(
            (
                "FCLKCLK[0]",
                "FCLKCLK[1]",
                "FCLKCLK[2]",
                "FCLKCLK[3]",
                "EMIOSDIO0CLK",
                "EMIOSDIO1CLK",
                # There are also EMIOSPI[01]CLKO and EMIOSPI[01]CLKTN but seem
                # to be more of a GPIO outputs than clock sources for the FPGA
                # fabric.
            )
        ),
        "type": "PS7",
    },
    "IBUF_VPR": {
        "sources": frozenset(("O",)),
        "sinks": frozenset(("I",)),
        "type": "IBUF",
    },
    "IBUFDS_GTE2_VPR": {
        "sources": frozenset(("O",)),
        "sinks": frozenset(),
        "type": "IBUFDS_GTE2",
    },
    "GTPE2_COMMON_VPR": {
        "sources": frozenset(),
        "sinks": frozenset(("GTREFCLK0", "GTREFCLK1")),
        "type": "GTPE2_COMMON",
    },
    "GTPE2_CHANNEL_VPR": {
        "sources": frozenset(("TXOUTCLK", "RXOUTCLK")),
        "sinks": frozenset(),
        "type": "GTPE2_CHANNEL",
    },
}

GTP_PRIMITIVES = ["IBUFDS_GTE2", "GTPE2_COMMON", "GTPE2_CHANNEL"]


def eprint(*args, **kwargs):
    print(*args, file=sys.stderr, **kwargs)


def get_cmt(cmt_dict, loc):
    """Returns the clock region of an input location."""
    for k, v in cmt_dict.items():
        for x, y in v["vpr_loc"]:
            if x == loc[0] and y == loc[1]:
                return v["clock_region"]

    return None


class VprGrid(object):
    """This class contains a set of dictionaries helpful
    to have a fast lookup at the various coordinates mapping."""

    def __init__(self, vpr_grid_map, graph_limit):
        self.site_dict = dict()
        self.site_type_dict = dict()
        self.cmt_dict = dict()
        self.tile_dict = dict()
        self.vpr_loc_cmt = dict()
        self.canon_loc = dict()

        if graph_limit is not None:
            limits = graph_limit.split(",")
            xmin, ymin, xmax, ymax = [int(x) for x in limits]

        with open(vpr_grid_map, "r") as csv_vpr_grid:
            csv_reader = csv.DictReader(csv_vpr_grid)
            for row in csv_reader:
                site_name = row["site_name"]
                site_type = row["site_type"]
                phy_tile = row["physical_tile"]
                vpr_x = row["vpr_x"]
                vpr_y = row["vpr_y"]
                can_x = row["canon_x"]
                can_y = row["canon_y"]
                clk_region = row["clock_region"]
                connected_to_site = row["connected_to_site"]

                if graph_limit is not None:
                    if int(can_x) < xmin or int(can_x) > xmax:
                        continue
                    if int(can_y) < ymin or int(can_y) > ymax:
                        continue

                clk_region = None if not clk_region else int(clk_region)

                # Generating the site dictionary
                self.site_dict[site_name] = {
                    "type": site_type,
                    "tile": phy_tile,
                    "vpr_loc": (int(vpr_x), int(vpr_y)),
                    "canon_loc": (int(can_x), int(can_y)),
                    "clock_region": clk_region,
                    "connected_to_site": connected_to_site,
                }

                # Generating site types dictionary.
                if site_type not in self.site_type_dict:
                    self.site_type_dict[site_type] = []

                self.site_type_dict[site_type].append((site_name, phy_tile, clk_region))

                # Generating the cmt dictionary.
                # Each entry has:
                #   - canonical location
                #   - a list of vpr coordinates
                #   - clock region
                if phy_tile not in self.cmt_dict:
                    self.cmt_dict[phy_tile] = {
                        "canon_loc": (int(can_x), int(can_y)),
                        "vpr_loc": [(int(vpr_x), int(vpr_y))],
                        "clock_region": clk_region,
                    }
                else:
                    self.cmt_dict[phy_tile]["vpr_loc"].append((int(vpr_x), int(vpr_y)))

                # Generating the tile dictionary.
                # Each tile has a list of (site, site_type) pairs
                if phy_tile not in self.tile_dict:
                    self.tile_dict[phy_tile] = []

                self.tile_dict[phy_tile].append((site_name, site_type))

                self.vpr_loc_cmt[(int(vpr_x), int(vpr_y))] = clk_region

                self.canon_loc[(int(vpr_x), int(vpr_y))] = (int(can_x), int(can_y))

    def get_site_dict(self):
        return self.site_dict

    def get_site_type_dict(self):
        return self.site_type_dict

    def get_cmt_dict(self):
        return self.cmt_dict

    def get_tile_dict(self):
        return self.tile_dict

    def get_vpr_loc_cmt(self):
        """
        Returns a dictionary containing the mapping between
        VPR physical locations to the belonging clock region.

        Dictionary content:
            - key   : (x, y) coordinate on the VPR grid
            - value : clock region corresponding to the (x, y) coordinates
        """
        return self.vpr_loc_cmt

    def get_canon_loc(self):
        return self.canon_loc


class ClockPlacer(object):
    def __init__(self, vpr_grid, io_locs, blif_data, roi, graph_limit, allow_bufg_logic_sources=False):
        self.roi = roi
        self.cmt_to_bufg_tile = {}
        self.bufg_from_cmt = {
            "TOP": [],
            "BOT": [],
        }
        self.pll_cmts = set()
        self.mmcm_cmts = set()
        self.gtp_cmts = set()

        cmt_dict = vpr_grid.get_cmt_dict()
        site_type_dict = vpr_grid.get_site_type_dict()

        try:
            top_cmt_tile = next(k for k, v in cmt_dict.items() if k.startswith("CLK_BUFG_TOP"))
            _, thresh_top_y = cmt_dict[top_cmt_tile]["canon_loc"]
        except StopIteration:
            thresh_top_y = None

        try:
            bot_cmt_tile = next(k for k, v in cmt_dict.items() if k.startswith("CLK_BUFG_BOT"))
            _, thresh_bot_y = cmt_dict[bot_cmt_tile]["canon_loc"]
        except StopIteration:
            thresh_bot_y = None

        if graph_limit is None:
            assert thresh_top_y is not None, "BUFG sites in the top half of the device not found"
            assert thresh_bot_y is not None, "BUFG sites in the bottom half of the device not found"
        else:
            assert (
                thresh_top_y is not None or thresh_bot_y is not None
            ), "The device grid does not contain any BUFG sites"

        for k, v in cmt_dict.items():
            clock_region = v["clock_region"]
            x, y = v["canon_loc"]
            if clock_region is None:
                continue
            elif clock_region in self.cmt_to_bufg_tile:
                continue
            elif thresh_top_y is not None and y <= thresh_top_y:
                self.cmt_to_bufg_tile[clock_region] = "TOP"
            elif thresh_bot_y is not None and y >= thresh_bot_y:
                self.cmt_to_bufg_tile[clock_region] = "BOT"

        for _, _, clk_region in site_type_dict["PLLE2_ADV"]:
            self.pll_cmts.add(clk_region)

        if any(site in GTP_PRIMITIVES for site in site_type_dict):
            assert "IBUFDS_GTE2" in site_type_dict
            for _, _, clk_region in site_type_dict["IBUFDS_GTE2"]:
                self.gtp_cmts.add(clk_region)

        for _, _, clk_region in site_type_dict["MMCME2_ADV"]:
            self.mmcm_cmts.add(clk_region)

        self.input_pins = {}
        if not self.roi:
            for input_pin in blif_data["inputs"]["args"]:
                if input_pin not in io_locs.keys():
                    continue

                loc = io_locs[input_pin]
                cmt = get_cmt(cmt_dict, loc)
                assert cmt is not None, loc

                self.input_pins[input_pin] = cmt

        self.clock_blocks = {}

        self.clock_sources = {}
        self.clock_sources_cname = {}

        self.clock_cmts = {}

        if "subckt" not in blif_data.keys():
            return

        for subckt in blif_data["subckt"]:
            if "cname" not in subckt:
                continue
            bel = subckt["args"][0]

            assert "cname" in subckt and len(subckt["cname"]) == 1, subckt

            if bel not in CLOCKS:
                continue

            cname = subckt["cname"][0]

            clock = {
                "name": cname,
                "subckt": bel,
                "sink_nets": [],
                "source_nets": [],
            }

            sources = CLOCKS[bel]["sources"]

            ports = dict(arg.split("=", maxsplit=1) for arg in subckt["args"][1:])

            for source in sources:
                source_net = ports[source]
                if source_net == "$true" or source_net == "$false":
                    continue

                self.clock_sources[source_net] = []
                self.clock_sources_cname[source_net] = cname
                clock["source_nets"].append(source_net)

            self.clock_blocks[cname] = clock

            # Both PS7 and BUFGCTRL has specialized constraints,
            # do not bind based on input pins.
            if bel not in ["PS7_VPR", "BUFGCTRL_VPR"]:
                for port in ports.values():
                    if port not in io_locs:
                        continue

                    if cname in self.clock_cmts:
                        assert_out = (cname, port, self.clock_cmts[cname], self.input_pins[port])
                        assert self.clock_cmts[cname] == self.input_pins[port], assert_out
                    else:
                        self.clock_cmts[cname] = self.input_pins[port]

        for subckt in blif_data["subckt"]:
            if "cname" not in subckt:
                continue

            bel = subckt["args"][0]
            if bel not in CLOCKS:
                continue

            sinks = CLOCKS[bel]["sinks"]
            ports = dict(arg.split("=", maxsplit=1) for arg in subckt["args"][1:])

            assert "cname" in subckt and len(subckt["cname"]) == 1, subckt
            cname = subckt["cname"][0]
            clock = self.clock_blocks[cname]

            for sink in sinks:
                if sink not in ports:
                    continue

                sink_net = ports[sink]
                if sink_net == "$true" or sink_net == "$false":
                    continue

                clock["sink_nets"].append(sink_net)

                if sink_net not in self.input_pins and sink_net not in self.clock_sources:
                    # Allow IBUFs. At this point we cannot distinguish between
                    # IBUFs for clock and logic.
                    if bel == "IBUF_VPR":
                        continue

                    # Allow BUFGs to be driven by generic sources but only
                    # when enabled.
                    if bel == "BUFGCTRL_VPR" and allow_bufg_logic_sources:
                        continue

                    # The clock source comes from logic, disallow that
                    eprint(
                        "The clock net '{}' driving '{}' sources at logic which is not allowed!".format(sink_net, bel)
                    )
                    exit(-1)

                if sink_net in self.input_pins:
                    if sink_net not in self.clock_sources:
                        self.clock_sources[sink_net] = []

                self.clock_sources[sink_net].append(cname)

    def assign_cmts(self, vpr_grid, blocks, block_locs):
        """Assign CMTs to subckt's that require it (e.g. BURF/PLL/MMCM)."""

        problem = constraint.Problem()

        site_dict = vpr_grid.get_site_dict()
        vpr_loc_cmt = vpr_grid.get_vpr_loc_cmt()

        # Any clocks that have LOC's already defined should be respected.
        # Store the parent CMT in clock_cmts.
        for block, loc in block_locs.items():
            if block in self.clock_blocks:
                clock = self.clock_blocks[block]
                if CLOCKS[clock["subckt"]]["type"] == "BUFGCTRL":
                    pass
                else:
                    site = site_dict[loc.replace('"', "")]
                    assert site is not None, (block, loc)

                    clock_region_pkey = site["clock_region"]

                    if block in self.clock_cmts:
                        assert clock_region_pkey == self.clock_cmts[block], (block, clock_region_pkey)
                    else:
                        self.clock_cmts[block] = clock_region_pkey

        # Any clocks that were previously constrained must be preserved
        for block, (loc_x, loc_y, _) in blocks.items():
            if block in self.clock_blocks:
                clock = self.clock_blocks[block]
                if CLOCKS[clock["subckt"]]["type"] == "BUFGCTRL":
                    pass
                else:
                    cmt = vpr_loc_cmt[(loc_x, loc_y)]

                    if block in self.clock_cmts:
                        assert cmt == self.clock_cmts[block], (block, cmt)
                    else:
                        self.clock_cmts[block] = cmt

        # Non-clock IBUF's increase the solution space if they are not
        # constrainted by a LOC.  Given that non-clock IBUF's don't need to
        # solved for, remove them.
        unused_blocks = set()
        any_variable = False
        for clock_name, clock in self.clock_blocks.items():
            used = False
            if CLOCKS[clock["subckt"]]["type"] != "IBUF":
                used = True

            for source_net in clock["source_nets"]:
                if len(self.clock_sources[source_net]) > 0:
                    used = True
                    break

            if not used:
                unused_blocks.add(clock_name)
                continue

            if CLOCKS[clock["subckt"]]["type"] == "BUFGCTRL":
                problem.addVariable(clock_name, list(self.bufg_from_cmt.keys()))
                any_variable = True
            else:
                # Constrained objects have a domain of 1
                if clock_name in self.clock_cmts:
                    problem.addVariable(clock_name, (self.clock_cmts[clock_name],))
                    any_variable = True
                else:
                    problem.addVariable(clock_name, list(self.cmt_to_bufg_tile.keys()))
                    any_variable = True

        # Remove unused blocks from solutions.
        for clock_name in unused_blocks:
            del self.clock_blocks[clock_name]

        exclusive_clocks = defaultdict(set)
        ibuf_cmt_sinks = defaultdict(set)

        for net in self.clock_sources:
            is_net_ibuf = False

            if net not in self.input_pins:
                source_clock_name = self.clock_sources_cname[net]
                if source_clock_name not in unused_blocks:
                    source_block = self.clock_blocks[source_clock_name]
                    if CLOCKS[source_block["subckt"]]["type"] == "IBUF":
                        is_net_ibuf = True

            for clock_name in self.clock_sources[net]:
                if clock_name in unused_blocks:
                    continue

                clock = self.clock_blocks[clock_name]

                if CLOCKS[clock["subckt"]]["type"] == "PLLE2_ADV":
                    problem.addConstraint(lambda cmt: cmt in self.pll_cmts, (clock_name,))
                    exclusive_clocks["PLLE2_ADV"].add(clock_name)
                    if is_net_ibuf:
                        ibuf_cmt_sinks[source_clock_name].add(clock_name)

                if CLOCKS[clock["subckt"]]["type"] == "MMCME2_ADV":
                    problem.addConstraint(lambda cmt: cmt in self.mmcm_cmts, (clock_name,))
                    exclusive_clocks["MMCME2_ADV"].add(clock_name)
                    if is_net_ibuf:
                        ibuf_cmt_sinks[source_clock_name].add(clock_name)

                if net in self.input_pins:
                    if CLOCKS[clock["subckt"]]["type"] == "BUFGCTRL":
                        # BUFGCTRL do not get a CMT, instead they get either top or
                        # bottom.
                        problem.addConstraint(
                            lambda clock: clock == self.cmt_to_bufg_tile[self.input_pins[net]], (clock_name,)
                        )
                    elif CLOCKS[clock["subckt"]]["type"] != "IBUF":
                        problem.addConstraint(lambda clock: clock == self.input_pins[net], (clock_name,))
                else:
                    source_clock_name = self.clock_sources_cname[net]
                    source_block = self.clock_blocks[source_clock_name]
                    is_net_bufg = CLOCKS[source_block["subckt"]]["type"] == "BUFGCTRL"

                    if is_net_bufg:
                        continue

                    if CLOCKS[clock["subckt"]]["type"] == "BUFGCTRL":
                        # BUFG's need to be in the right half.
                        problem.addConstraint(
                            lambda source, sink_bufg: self.cmt_to_bufg_tile[source] == sink_bufg,
                            (source_clock_name, clock_name),
                        )
                    elif not is_net_ibuf:
                        problem.addConstraint(lambda source, sink: source == sink, (source_clock_name, clock_name))

        # Ensure that in case of an IBUF driving multiple CMTs at least one of
        # them is in the same clock region as the IBUF.
        for source, sinks in ibuf_cmt_sinks.items():
            problem.addConstraint(
                lambda s, *k: s in k,
                (
                    source,
                    *sinks,
                ),
            )

        # Prevent constraining exclusive clock source sets to the same resource
        for typ, clocks in exclusive_clocks.items():
            problem.addConstraint(constraint.AllDifferentConstraint(), list(clocks))

        if any_variable:
            solutions = problem.getSolutions()
            assert len(solutions) > 0, "No solution found!"

            self.clock_cmts.update(solutions[0])

    def place_clocks(self, canon_grid, vpr_grid, loc_in_use, block_locs, blocks, grid_capacities):
        self.assign_cmts(vpr_grid, blocks, block_locs)

        site_type_dict = vpr_grid.get_site_type_dict()

        # Key is (type, clock_region_pkey)
        available_placements = {}
        available_locs = {}
        vpr_locs = {}

        for clock_type in CLOCKS.values():
            if clock_type == "IBUF" or clock_type["type"] not in site_type_dict:
                continue

            for loc, tile_name, clock_region_pkey in site_type_dict[clock_type["type"]]:
                if clock_type["type"] == "BUFGCTRL":
                    if "_TOP_" in tile_name:
                        key = (clock_type["type"], "TOP")
                    elif "_BOT_" in tile_name:
                        key = (clock_type["type"], "BOT")
                else:
                    key = (clock_type["type"], clock_region_pkey)

                if key not in available_placements:
                    available_placements[key] = []
                    available_locs[key] = []

                available_placements[key].append(loc)
                vpr_loc = get_vpr_coords_from_site_name(canon_grid, vpr_grid, loc, grid_capacities)

                if vpr_loc is None:
                    continue

                available_locs[key].append(vpr_loc)
                vpr_locs[loc] = vpr_loc

        for clock_name, clock in self.clock_blocks.items():
            # All clocks should have an assigned CMTs at this point.
            assert clock_name in self.clock_cmts, clock_name

            bel_type = CLOCKS[clock["subckt"]]["type"]

            # Skip LOCing the PS7. There is only one
            if bel_type == "PS7":
                continue

            if bel_type == "IBUF":
                continue

            key = (bel_type, self.clock_cmts[clock_name])

            if clock_name in blocks:
                # This block has a LOC constraint from the user, verify that
                # this LOC constraint makes sense.
                assert blocks[clock_name] in available_locs[key], (clock_name, blocks[clock_name], available_locs[key])
                continue

            loc = None
            for potential_loc in sorted(available_placements[key]):
                # This block has no existing placement, make one
                vpr_loc = vpr_locs[potential_loc]
                if vpr_loc in loc_in_use:
                    continue

                loc_in_use.add(vpr_loc)
                yield clock_name, potential_loc
                loc = potential_loc
                break

            # No free LOC!!!
            assert loc is not None, (clock_name, available_placements[key])

    def has_clock_nets(self):
        return self.clock_sources


def get_tile_capacities(arch_xml_filename):
    arch = ET.parse(arch_xml_filename, ET.XMLParser(remove_blank_text=True))
    root = arch.getroot()

    tile_capacities = {}
    for el in root.iter("tile"):
        tile_name = el.attrib["name"]

        tile_capacities[tile_name] = 0

        for sub_tile in el.iter("sub_tile"):
            capacity = 1

            if "capacity" in sub_tile.attrib:
                capacity = int(sub_tile.attrib["capacity"])

            tile_capacities[tile_name] += capacity

    grid = {}
    for el in root.iter("single"):
        x = int(el.attrib["x"])
        y = int(el.attrib["y"])
        grid[(x, y)] = tile_capacities[el.attrib["type"]]

    return grid


def get_vpr_coords_from_site_name(canon_grid, vpr_grid, site_name, grid_capacities):
    site_name = site_name.replace('"', "")

    site_dict = vpr_grid.get_site_dict()
    canon_loc = vpr_grid.get_canon_loc()

    tile = site_dict[site_name]["tile"]

    capacity = 0
    x, y = site_dict[site_name]["vpr_loc"]
    canon_x, canon_y = canon_loc[(x, y)]

    if (x, y) in grid_capacities.keys():
        capacity = grid_capacities[(x, y)]

    if not capacity:
        # If capacity is zero it means that the site is out of
        # the ROI, hence the site needs to be skipped.
        return None
    elif capacity == 1:
        return (x, y, 0)
    else:
        sites = list(canon_grid.gridinfo_at_loc((canon_x, canon_y)).sites.keys())
        assert capacity == len(sites), (tile, capacity, (x, y))

        instance_idx = sites.index(site_name)

        return (x, y, instance_idx)


def constrain_special_ios(canon_grid, vpr_grid, io_blocks, blif_data, blocks, place_constraints):
    """
    There are special IOs which need extra handling when dealing with placement constraints.

    For instance, the IBUFDS_GTE2 primitive must be placed in correspondance with the location
    of its input PADs, as no other route exists other than that.

    This function reads the connectivity of the top level nets, which have been previously
    constrained, and correctly constrains those blocks which require special handling.
    """

    if "subckt" not in blif_data:
        return

    BEL_TYPES = ["IBUFDS_GTE2_VPR", "GTPE2_CHANNEL_VPR"]
    SPECIAL_IPADS = ["IPAD_GTP_VPR"]

    special_io_map = dict()
    for subckt in blif_data["subckt"]:
        if "cname" not in subckt:
            continue
        bel = subckt["args"][0]

        if bel not in SPECIAL_IPADS:
            continue

        top_net = None
        renamed_net = None
        for port in subckt["args"][1:]:
            port_name, net = port.split("=")

            if port_name == "I":
                assert net in io_blocks, (net, io_blocks)
                top_net = net
            elif port_name == "O":
                renamed_net = net
            else:
                assert False, "ERROR: Special IPAD ports not recognized!"

        special_io_map[renamed_net] = top_net

    blocks_to_constrain = set()
    for subckt in blif_data["subckt"]:
        if "cname" not in subckt:
            continue
        bel = subckt["args"][0]

        if bel not in BEL_TYPES:
            continue

        assert "cname" in subckt and len(subckt["cname"]) == 1, subckt
        cname = subckt["cname"][0]

        for port in subckt["args"][1:]:
            _, net = port.split("=")

            if net not in special_io_map:
                continue

            net = special_io_map[net]
            if net in io_blocks:
                x, y, z = io_blocks[net]

                canon_loc = vpr_grid.get_canon_loc()[(x, y)]

                gridinfo = canon_grid.gridinfo_at_loc(canon_loc)
                sites = sorted(gridinfo.sites.keys())
                site_name = sites[z]

                connected_io_site = vpr_grid.get_site_dict()[site_name]["connected_to_site"]
                assert connected_io_site, (site_name, bel, cname)

                new_z = sites.index(connected_io_site)
                loc = (x, y, new_z)

                blocks_to_constrain.add((cname, loc))

    for block, vpr_loc in blocks_to_constrain:
        place_constraints.constrain_block(block, vpr_loc, "Constraining block {}".format(block))

        blocks[block] = vpr_loc


def p_main(
    net,
    vpr_grid_map,
    arch,
    part,
    blif,
    db_root,
    input=sys.stdin,
    output=sys.stdout,
    roi=False,
    allow_bufg_logic_sources=False,
    graph_limit=None,
):
    device_families = {
        "xc7a": "artix7",
        "xc7k": "kintex7",
        "xc7z": "zynq7",
        "xc7s": "spartan7",
    }

    device_family = None
    for device in device_families:
        if part.startswith(device):
            device_family = device_families[device]
            break

    assert device_family

    db_root = str(Path(db_root) / device_family)
    db = prjxray.db.Database(db_root, part)
    canon_grid = db.grid()

    io_blocks = {}
    loc_in_use = set()
    for line in input:
        output.write(line)

        if line[0] == "#":
            continue
        block, x, y, z = line.strip().split()[0:4]

        io_blocks[block] = (int(x), int(y), int(z))
        loc_in_use.add(io_blocks[block])

    place_constraints = PlaceConstraints(net)
    place_constraints.load_loc_sites_from_net_file()

    grid_capacities = get_tile_capacities(arch)

    eblif_data = parse_blif(blif)

    vpr_grid = VprGrid(vpr_grid_map, graph_limit)

    # Constrain IO blocks and LOCed resources
    blocks = {}
    block_locs = {}
    for block, loc in place_constraints.get_loc_sites():
        vpr_loc = get_vpr_coords_from_site_name(canon_grid, vpr_grid, loc, grid_capacities)
        loc_in_use.add(vpr_loc)

        if block in io_blocks:
            assert io_blocks[block] == vpr_loc, (block, vpr_loc, io_blocks[block])

        blocks[block] = vpr_loc
        block_locs[block] = loc

        place_constraints.constrain_block(block, vpr_loc, "Constraining block {}".format(block))

    # Constrain blocks directly connected to IO in the same x, y location
    constrain_special_ios(canon_grid, vpr_grid, io_blocks, eblif_data, blocks, place_constraints)

    # Constrain clock resources
    clock_placer = ClockPlacer(vpr_grid, io_blocks, eblif_data, roi, graph_limit, allow_bufg_logic_sources)
    if clock_placer.has_clock_nets():
        for block, loc in clock_placer.place_clocks(
            canon_grid, vpr_grid, loc_in_use, block_locs, blocks, grid_capacities
        ):
            vpr_loc = get_vpr_coords_from_site_name(canon_grid, vpr_grid, loc, grid_capacities)
            place_constraints.constrain_block(block, vpr_loc, "Constraining clock block {}".format(block))
    """ Constrain IDELAYCTRL sites

    Prior to the invocation of this script, the IDELAYCTRL sites must have been
    replicated accordingly to the IDELAY specifications.
    There can be three different usage combinations of IDELAYCTRL and IDELAYs in a design:
        1. IODELAYs and IDELAYCTRLs can be constrained to banks as needed,
           through an in-design LOC constraint.
           Manual replication of the constrained IDELAYCTRLs is necessary to provide a
           controller for each bank.
        2. IODELAYs and a single IDELAYCTRL can be left entirely unconstrained,
           becoming a default group. The IDELAYCTRLis replicated depending on bank usage.
           Replication must have happened prior to this step
        3. One or more IODELAY_GROUPs can be defined that contain IODELAYs and a single
           IDELAYCTRL each. These components can be otherwise unconstrained and the IDELAYCTRL
           for each group has to be replicated as needed (depending on bank usage).
           NOTE: IODELAY_GROUPS are not enabled at the moment.
    """
    idelayctrl_cmts = set()
    idelay_instances = place_constraints.get_used_instances("IDELAYE2")
    for inst in idelay_instances:
        x, y, z = io_blocks[inst]
        idelayctrl_cmt = vpr_grid.get_vpr_loc_cmt()[(x, y)]
        idelayctrl_cmts.add(idelayctrl_cmt)

    idelayctrl_instances = place_constraints.get_used_instances("IDELAYCTRL")

    assert len(idelayctrl_cmts) <= len(
        idelayctrl_instances
    ), "The number of IDELAYCTRL blocks and IO banks with IDELAYs used do not match."

    idelayctrl_sites = dict()
    for site_name, _, clk_region in vpr_grid.get_site_type_dict()["IDELAYCTRL"]:
        if clk_region in idelayctrl_cmts:
            idelayctrl_sites[clk_region] = site_name

    # Check and remove user constrained IDELAYCTRLs
    for idelayctrl_block in idelayctrl_instances:
        if idelayctrl_block in blocks.keys():
            x, y, _ = blocks[idelayctrl_block]
            idelayctrl_cmt = vpr_grid.get_vpr_loc_cmt()[(x, y)]

            assert idelayctrl_cmt in idelayctrl_cmts

            idelayctrl_cmts.remove(idelayctrl_cmt)
            idelayctrl_instances.remove(idelayctrl_block)

    # TODO: Add possibility to bind IDELAY banks to IDELAYCTRL sites using
    #       the IDELAY_GROUP attribute.
    for cmt, idelayctrl_block in zip(idelayctrl_cmts, idelayctrl_instances):
        x, y = vpr_grid.get_site_dict()[idelayctrl_sites[cmt]]["vpr_loc"]
        vpr_loc = (x, y, 0)

        place_constraints.constrain_block(
            idelayctrl_block, vpr_loc, "Constraining idelayctrl block {}".format(idelayctrl_block)
        )

    if len(idelayctrl_instances) > 0:
        print("Warning: IDELAY_GROUPS parameters are currently being ignored!", file=sys.stderr)

    place_constraints.output_place_constraints(output)


def main(
    net,
    vpr_grid_map,
    arch,
    part,
    blif,
    db_root=None,
    input=None,
    output=None,
    roi=False,
    allow_bufg_logic_sources=False,
    graph_limit=None,
):
    p_main(
        net=Path(net).open("r"),
        vpr_grid_map=vpr_grid_map,
        arch=arch,
        db_root=environ.get(
            "DATABASE_DIR", subprocess_run("prjxray-config", capture_output=True).stdout.decode("utf-8").strip()
        )
        if db_root is None
        else db_root,
        part=part,
        blif=Path(blif).open("r"),
        input=sys.stdin if input is None else Path(input).open("r"),
        output=sys.stdout if output is None else Path(output).open("w"),
        roi=roi,
        allow_bufg_logic_sources=allow_bufg_logic_sources,
        graph_limit=graph_limit,
    )


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Convert a PCF file into a VPR io.place file.")
    parser.add_argument(
        "--input", "-i", "-I", type=argparse.FileType("r"), default=sys.stdout, help="The input constraints place file"
    )
    parser.add_argument(
        "--output",
        "-o",
        "-O",
        type=argparse.FileType("w"),
        default=sys.stdout,
        help="The output constraints place file",
    )
    parser.add_argument("--net", "-n", type=argparse.FileType("r"), required=True, help="top.net file")
    parser.add_argument("--vpr_grid_map", help="Map of canonical to VPR grid locations", required=True)
    parser.add_argument("--arch", help="Arch XML", required=True)
    parser.add_argument("--db_root", required=True)
    parser.add_argument("--part", required=True)
    parser.add_argument("--blif", "-b", type=argparse.FileType("r"), required=True, help="BLIF / eBLIF file")
    parser.add_argument("--roi", action="store_true", help="Using ROI")
    parser.add_argument(
        "--allow-bufg-logic-sources", action="store_true", help="When set allows BUFGs to be driven by logic"
    )
    parser.add_argument("--graph_limit", help="Graph limit parameters")
    args = parser.parse_args()

    p_main(
        net=args.net,
        vpr_grid_map=args.vpr_grid_map,
        arch=args.arch,
        db_root=args.db_root,
        part=args.part,
        blif=args.blif,
        input=args.input,
        output=args.output,
        roi=args.roi,
        allow_bufg_logic_sources=args.allow_bufg_logic_sources,
        graph_limit=args.graph_limit,
    )
