#!/usr/bin/env python3
import argparse
import sys
import csv

import eblif

# =============================================================================


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


def get_cell_connection(cell, pin):
    """
    Returns the name of the net connected to the given cell pin. Returns None
    if unconnected
    """

    # Only for subckt
    assert cell["type"] == "subckt"

    # Find the connection and return it
    for i in range(1, len(cell["args"])):
        p, net = cell["args"][i].split("=")
        if p == pin:
            return net

    # Not found
    return None


# =============================================================================


def main():
    parser = argparse.ArgumentParser(
        description='Creates placement constraints other than IOs'
    )

    parser.add_argument(
        "--input",
        '-i',
        "-I",
        type=argparse.FileType('r'),
        default=sys.stdin,
        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(
        "--map",
        type=argparse.FileType('r'),
        required=True,
        help="Clock pinmap CSV file"
    )
    parser.add_argument(
        "--blif",
        '-b',
        type=argparse.FileType('r'),
        required=True,
        help='BLIF / eBLIF file.'
    )

    args = parser.parse_args()

    # Load clock map
    clock_to_gmux = {}
    for row in csv.DictReader(args.map):
        name = row["name"]
        src_loc = (
            int(row["src.x"]),
            int(row["src.y"]),
            int(row["src.z"]),
        )
        dst_loc = (
            int(row["dst.x"]),
            int(row["dst.y"]),
            int(row["dst.z"]),
        )

        clock_to_gmux[src_loc] = (dst_loc, name)

    # Load EBLIF
    eblif_data = eblif.parse_blif(args.blif)

    # Process the IO constraints file. Pass the constraints unchanged, store
    # them.
    io_constraints = {}

    for line in args.input:

        # Strip, skip comments
        line = line.strip()
        if line.startswith("#"):
            continue

        args.output.write(line + "\n")

        # Get block and its location
        block, x, y, z = line.split()[0:4]
        io_constraints[block] = (
            int(x),
            int(y),
            int(z),
        )

    # Analyze the BLIF netlist. Find clock inputs that go through CLOCK IOB to
    # GMUXes.
    clock_connections = []

    IOB_CELL = {"type": "CLOCK_CELL", "ipin": "I_PAD", "opin": "O_CLK"}
    BUF_CELL = {"type": "GMUX_IP", "ipin": "IP", "opin": "IZ"}

    for inp_net in eblif_data["inputs"]["args"]:

        # This one is not constrained, skip it
        if inp_net not in io_constraints:
            continue

        # Search for a CLOCK cell connected to that net
        for cell in eblif_data["subckt"]:
            if cell["type"] == "subckt" and cell["args"][0] == IOB_CELL["type"]:
                net = get_cell_connection(cell, IOB_CELL["ipin"])
                if net == inp_net:
                    iob_cell = cell
                    break
        else:
            continue

        # Get the output net of the CLOCK cell
        con_net = get_cell_connection(iob_cell, IOB_CELL["opin"])
        if not con_net:
            continue

        # Search for a GMUX connected to the CLOCK cell
        for cell in eblif_data["subckt"]:
            if cell["type"] == "subckt" and cell["args"][0] == BUF_CELL["type"]:
                net = get_cell_connection(cell, BUF_CELL["ipin"])
                if net == con_net:
                    buf_cell = cell
                    break
        else:
            continue

        # Get the output net of the GMUX
        clk_net = get_cell_connection(buf_cell, BUF_CELL["opin"])
        if not clk_net:
            continue

        # Store data
        clock_connections.append(
            (inp_net, iob_cell, con_net, buf_cell, clk_net)
        )

    # Emit constraints for GCLK cells
    for inp_net, iob_cell, con_net, buf_cell, clk_net in clock_connections:

        src_loc = io_constraints[inp_net]
        if src_loc not in clock_to_gmux:
            eprint(
                "ERROR: No GMUX location for input CLOCK pad for net '{}' at {}"
                .format(inp_net, src_loc)
            )
            continue

        dst_loc, name = clock_to_gmux[src_loc]

        # FIXME: Silently assuming here that VPR will name the GMUX block as
        # the GMUX cell in EBLIF. In order to fix that there will be a need
        # to read & parse the packed netlist file.
        line = "{} {} {} {} # {}\n".format(
            buf_cell["cname"][0], *dst_loc, name
        )
        args.output.write(line)


# =============================================================================

if __name__ == '__main__':
    main()
