""" Script for addressing CARRY4 output congestion in elaborated netlists.

Usage:

    python3 fix_carry.py < input-netlist-json > output-netlist-json

Description:

    In the 7-series SLICEL (and SLICEM) sites, there can be output congestion
    if both the CO and O of the CARRY4 are used. This congestion can be
    avoided by using a transparent/open latch or register on the output of the
    CARRY4.

    VPR does not currently support either of those options, so for now, if
    both CO and O are used, the CO output is converted into a LUT equation to
    recompute the CO output from O, DI and S.  See carry_map.v and
    clean_carry_map.v for details.

    If VPR could emit the transparent/open latch on output congestion, this
    would no longer be required.  The major problem with transparent latch
    support is that it requires constants to be routed to the G/GE/CLR/PRE
    ports, which VPR cannot express as a result of packing.

    This script identifies CARRY4 chains in the netlist, identifies if there
    is output congestion on the O and CO ports, and marks the congestion by
    changing CARRY_CO_DIRECT (e.g. directly use the CO port) to CARRY_CO_LUT
    (compute the CO value using a LUT equation).


Diagram showing one row of the 7-series CLE, focusing on O/CO congestion.
This diagram shows that if both the O and CO outputs are needed, once must
pass through the flip flop (xFF in the diagram).

                                      CLE Row

+--------------------------------------------------------------------------+
|                                                                          |
|                                                                          |
|                                               +---+                      |
|                                               |    +                     |
|                                               |     +                    |
|                                     +-------->+ O    +                   |
|              CO CHAIN               |         |       +                  |
|                                     |         |       +---------------------> xMUX
|                 ^                   |   +---->+ CO    +                  |
|                 |                   |   |     |      +                   |
|                 |                   |   |     |     +                    |
|       +---------+----------+        |   |     |    +                     |
|       |                    |        |   |     +---+                      |
|       |     CARRY ROW      |        |   |                                |
|  +--->+ S              O   +--------+   |       xOUTMUX                  |
|       |                    |        |   |                                |
|       |                    |        +   |                                |
|  +--->+ DI             CO  +-------+o+--+                                |
|       |      CI CHAIN      |        +   |                                |
|       |                    |        |   |                                |
|       +---------+----------+        |   |       xFFMUX                   |
|                 ^                   |   |                                |
|                 |                   |   |     +---+                      |
|                 +                   |   |     |    +                     |
|                                     |   +     |     +    +-----------+   |
|                                     +--+o+--->+ O    +   |           |   |
|                                         +     |       +  |    xFF    |   |
|                                         |     |       +->--D----   Q +------> xQ
|                                         |     |       +  |           |   |
|                                         +---->+ CO   +   |           |   |
|                                               |     +    +-----------+   |
|                                               |    +                     |
|                                               +---+                      |
|                                                                          |
|                                                                          |
+--------------------------------------------------------------------------+


This script operates on a slightly different cell structure than a plain CARRY4.
carry_map.v converts the CARRY4 into:

                                              +------------------+  +-----------------+
                                              |                  |  |                 |
                                              |              CO3 +->+ CARRY_CO_DIRECT |
                                              |                  |  |                 |
                                              | DI3              |  +-----------------+
                                              |                  |
                                              | S3           O3  |
                                              |                  |
                                              | DI2              |  +-----------------+
                                              |                  |  |                 |
                                              | S2           CO2 +->+ CARRY_CO_DIRECT |
                                              |                  |  |                 |
                                              | DI1              |  +-----------------+
                                              |                  |
                                              | S1           O2  |
                                              |      CARRY4      |
                                              | DI0 (chained)    |  +-----------------+
                                              |                  |  |                 |
                                              | S0           CO1 +->+ CARRY_CO_DIRECT |
                                              |                  |  |                 |
                                              | CYINIT           |  +-----------------+
                                              |                  |
                         +-----------------+  |              O1  |
                         |                 |  |                  |
                      +->+ CARRY_COUT_PLUG +->+ CI               |  +-----------------+
                      |  |                 |  |                  |  |                 |
                      |  +-----------------+  |              CO0 +->+ CARRY_CO_DIRECT |
                      |                       |                  |  |                 |
                      |                       |                  |  +-----------------+
                      +-------------------+   |                  |
                                          |   |              O0  |
+------------------+  +-----------------+ |   |                  |
|                  |  |                 | |   +------------------+
|              CO3 +->+ CARRY_CO_DIRECT +-+
|                  |  |                 |
| DI3              |  +-----------------+
|                  |
| S3           O3  |
|                  |
| DI2              |  +-----------------+
|                  |  |                 |
| S2           CO2 +->+ CARRY_CO_DIRECT |
|                  |  |                 |
| DI1              |  +-----------------+
|                  |
| S1           O2  |
|       CARRY4     |
| DI0   (root)     |  +-----------------+
|                  |  |                 |
| S0           CO1 +->+ CARRY_CO_DIRECT |
|                  |  |                 |
| CYINIT           |  +-----------------+
|                  |
|              O1  |
|                  |
| CI               |  +-----------------+
|                  |  |                 |
|              CO0 +->+ CARRY_CO_DIRECT |
|                  |  |                 |
|                  |  +-----------------+
|                  |
|              O0  |
|                  |
+------------------+

Each CARRY4 spans the 4 rows of the SLICEL/SLICEM.
Row 0 is the S0/DI0/O0/CO0 ports, row 1 is S1/DI1/O1/CO1 ports, etc.

So there are five cases the script has to handle:

 - No congestion is present between O and CO ->

    Do nothing.

 - Congestion is present on rows 0-2 and row above is in use ->

    Change CARRY_CO_DIRECT to CARRY_CO_LUT.

    Routing and LUT delays are incurred in this case.

 - Congestion is present on rows 0-2 and row above is not in use ->

    Remap CO to O from the row above, and set S on the next row to 0 to
    ensure O outputs CI from the row below.

    No additional delays for this change.

 - Congestion is present on row 3 and CO3 is not connected to another CARRY ->

    Change CARRY_CO_DIRECT to CARRY_CO_TOP_POP.  This adds 1 dummy layer to
    the carry chain to output the CO.

    No additional delays for this change.

 - Congestion is present on row 3 and CO3 is connected directly to another
   CARRY4 ->

    Change CARRY_CO_DIRECT to CARRY_CO_LUT *and* change the chained
    CARRY_COUT_PLUG to be directly connected to the previous CO3.

    Routing and LUT delays are incurred in this case.

    Diagram for this case:

                                                 +-------------------+  +-----------------+
                                                 |                   |  |                 |
                                                 |               CO3 +->+ CARRY_CO_DIRECT |
                                                 |                   |  |                 |
                                                 |  DI3              |  +-----------------+
                                                 |                   |
                                                 |  S3           O3  |
                                                 |                   |
                                                 |  DI2              |  +-----------------+
                                                 |                   |  |                 |
                                                 |  S2           CO2 +->+ CARRY_CO_DIRECT |
                                                 |                   |  |                 |
                                                 |  DI1              |  +-----------------+
                                                 |                   |
                                                 |  S1           O2  |
                                                 |       CARRY4      |
                                                 |  DI0 (chained)    |  +-----------------+
                                                 |                   |  |                 |
                                                 |  S0           CO1 +->+ CARRY_CO_DIRECT |
                                                 |                   |  |                 |
                                                 |  CYINIT           |  +-----------------+
                                                 |                   |
                          +-----------------+    |               O1  |
                          |                 |    |                   |
                       +->+ CARRY_COUT_PLUG +--->+  CI               |  +-----------------+
                       |  |                 |    |                   |  |                 |
                       |  +-----------------+    |               CO0 +->+ CARRY_CO_DIRECT |
                       |                         |                   |  |                 |
+-------------------+  |  +-----------------+    |                   |  +-----------------+
|                   |  |  |                 |    |                   |
|               CO3 +--+->+ CARRY_CO_LUT    +-+  |               O0  |
|                   |     |                 | |  |                   |
|  DI3              |     +-----------------+ |  +-------------------+
|                   |                         |
|  S3           O3  |                         +------>
|                   |
|  DI2              |     +-----------------+
|                   |     |                 |
|  S2           CO2 +---->+ CARRY_CO_DIRECT |
|                   |     |                 |
|  DI1              |     +-----------------+
|                   |
|  S1           O2  |
|        CARRY4     |
|  DI0   (root)     |     +-----------------+
|                   |     |                 |
|  S0           CO1 +---->+ CARRY_CO_DIRECT |
|                   |     |                 |
|  CYINIT           |     +-----------------+
|                   |
|               O1  |
|                   |
|  CI               |     +-----------------+
|                   |     |                 |
|               CO0 +---->+ CARRY_CO_DIRECT |
|                   |     |                 |
|                   |     +-----------------+
|                   |
|               O0  |
|                   |
+-------------------+

After this script is run, clean_carry_map.v is used to convert CARRY_CO_DIRECT
into a direct connection, and CARRY_CO_LUT is mapped to a LUT to compute the
carry output.

"""
import json
import sys


def find_top_module(design):
    """
    Looks for the top-level module in the design. Returns its name. Throws
    an exception if none was found.
    """

    for name, module in design["modules"].items():
        attrs = module["attributes"]
        if "top" in attrs and int(attrs["top"]) == 1:
            return name

    raise RuntimeError("No top-level module found in the design!")


def find_carry4_chains(design, top_module, bit_to_cells):
    """ Identify CARRY4 carry chains starting from the root CARRY4.

    All non-root CARRY4 cells should end up as part of a chain, otherwise
    an assertion is raised.

    Arguments:
     design (dict) - "design" field from Yosys JSON format
     top_module (str) - Name of top module.
     bit_to_cells (dict) - Map of net bit identifier and cell information.
        Computes in "create_bit_to_cell_map".

    Returns:
        list of list of strings - List of CARRY4 chains.  Each chain is a list
            of cellnames.  The cells are listed in chain order, starting from
            the root.

    """
    cells = design["modules"][top_module]["cells"]

    used_carry4s = set()
    root_carry4s = []
    nonroot_carry4s = {}
    for cellname in cells:
        cell = cells[cellname]
        if cell["type"] != "CARRY4_VPR":
            continue
        connections = cell["connections"]

        if "CIN" in connections:
            cin_connections = connections["CIN"]
            assert len(cin_connections) == 1

            # Goto driver of CIN, should be a CARRY_COUT_PLUG.
            plug_cellname, port, bit_idx = bit_to_cells[cin_connections[0]][0]
            plug_cell = cells[plug_cellname]
            assert plug_cell["type"] == "CARRY_COUT_PLUG", plug_cellname
            assert port == "COUT"

            plug_connections = plug_cell["connections"]

            cin_connections = plug_connections["CIN"]
            assert len(cin_connections) == 1

            # Goto driver of CIN, should be a CARRY_CO_DIRECT.
            direct_cellname, port, bit_idx = bit_to_cells[cin_connections[0]
                                                          ][0]
            direct_cell = cells[direct_cellname]
            assert direct_cell["type"] == "CARRY_CO_DIRECT", direct_cellname
            assert port == "OUT"

            direct_connections = direct_cell["connections"]

            co_connections = direct_connections["CO"]
            assert len(co_connections) == 1

            nonroot_carry4s[co_connections[0]] = cellname
        else:
            used_carry4s.add(cellname)
            root_carry4s.append(cellname)

    # Walk from each root CARRY4 to each child CARRY4 module.
    chains = []
    for cellname in root_carry4s:
        chain = [cellname]

        while True:
            # Follow CO3 to the next CARRY4, if any.
            cell = cells[cellname]
            connections = cell["connections"]

            co3_connections = connections.get("CO3", None)
            if co3_connections is None:
                # No next CARRY4, stop here.
                break

            found_next_link = False
            for connection in co3_connections:
                next_cellname = nonroot_carry4s.get(connection, None)
                if next_cellname is not None:
                    cellname = next_cellname
                    used_carry4s.add(cellname)
                    chain.append(cellname)
                    found_next_link = True
                    break

            if not found_next_link:
                break

        chains.append(chain)

    # Make sure all non-root CARRY4's got used.
    for bit, cellname in nonroot_carry4s.items():
        assert cellname in used_carry4s, (bit, cellname)

    return chains


def create_bit_to_cell_map(design, top_module):
    """ Create map from net bit identifier to cell information.

    Arguments:
     design (dict) - "design" field from Yosys JSON format
     top_module (str) - Name of top module.

    Returns:
     bit_to_cells (dict) - Map of net bit identifier and cell information.

    The map keys are the net bit identifier used to mark which net a cell port
    is connected too.  The map values are a list of cell ports that are in the
    net.  The first element of the list is the driver port, and the remaining
    elements are sink ports.

    The list elements are 3-tuples with:
      cellname (str) - The name of the cell this port belongs too
      port (str) - The name of the port this element is connected too.
      bit_idx (int) - For multi bit ports, a 0-based index into the port.

    """
    bit_to_cells = {}

    cells = design["modules"][top_module]["cells"]

    for cellname in cells:
        cell = cells[cellname]
        port_directions = cell["port_directions"]
        for port, connections in cell["connections"].items():
            is_output = port_directions[port] == "output"
            for bit_idx, bit in enumerate(connections):

                list_of_cells = bit_to_cells.get(bit, None)
                if list_of_cells is None:
                    list_of_cells = [None]
                    bit_to_cells[bit] = list_of_cells

                if is_output:
                    # First element of list of cells is net driver.
                    assert list_of_cells[0] is None, (
                        bit, list_of_cells[0], cellname
                    )
                    list_of_cells[0] = (cellname, port, bit_idx)
                else:
                    list_of_cells.append((cellname, port, bit_idx))

    return bit_to_cells


def is_bit_used(bit_to_cells, bit):
    """ Is the net bit specified used by any sinks? """
    list_of_cells = bit_to_cells[bit]

    return len(list_of_cells) > 1


def is_bit_used_other_than_carry4_cin(design, top_module, bit, bit_to_cells):
    """ Is the net bit specified used by any sinks other than a carry chain? """
    cells = design["modules"][top_module]["cells"]
    list_of_cells = bit_to_cells[bit]
    assert len(list_of_cells) == 2, bit

    direct_cellname, port, _ = list_of_cells[1]
    direct_cell = cells[direct_cellname]
    assert direct_cell['type'] == "CARRY_CO_DIRECT"
    assert port == "CO"

    # Follow to output
    connections = direct_cell["connections"]["OUT"]
    assert len(connections) == 1

    for cellname, port, bit_idx in bit_to_cells[connections[0]][1:]:
        cell = cells[cellname]
        if cell["type"] == "CARRY_COUT_PLUG" and port == "CIN":
            continue
        else:
            return True, direct_cellname

    return False, direct_cellname


def create_bit_to_net_map(design, top_module):
    """ Create map from net bit identifier to net information.

    Arguments:
     design (dict) - "design" field from Yosys JSON format
     top_module (str) - Name of top module.

    Returns:
     bit_to_nets (dict) - Map of net bit identifier to net information.
    """
    bit_to_nets = {}

    nets = design["modules"][top_module]["netnames"]

    for net in nets:
        for bit_idx, bit in enumerate(nets[net]["bits"]):
            bit_to_nets[bit] = (net, bit_idx)

    return bit_to_nets


def fixup_cin(design, top_module, bit_to_cells, co_bit, direct_cellname):
    """ Move connection from CARRY_CO_LUT.OUT -> CARRY_COUT_PLUG.CIN to
        directly to preceeding CARRY4.
    """
    cells = design["modules"][top_module]["cells"]

    direct_cell = cells[direct_cellname]
    assert direct_cell["type"] == "CARRY_CO_LUT"

    # Follow to output
    connections = direct_cell["connections"]["OUT"]
    assert len(connections) == 1

    for cellname, port, bit_idx in bit_to_cells[connections[0]][1:]:
        cell = cells[cellname]
        if cell["type"] == "CARRY_COUT_PLUG" and port == "CIN":
            assert bit_idx == 0

            cells[cellname]["connections"]["CIN"][0] = co_bit


def fixup_congested_rows(design, top_module, bit_to_cells, bit_to_nets, chain):
    """ Walk the specified carry chain, and identify if any outputs are congested.

    Arguments:
     design (dict) - "design" field from Yosys JSON format
     top_module (str) - Name of top module.
     bit_to_cells (dict) - Map of net bit identifier and cell information.
        Computes in "create_bit_to_cell_map".
     bit_to_nets (dict) - Map of net bit identifier to net information.
        Computes in "create_bit_to_net_map".
     chain (list of str) - List of cells in the carry chain.

    """
    cells = design["modules"][top_module]["cells"]

    O_ports = ["O0", "O1", "O2", "O3"]
    CO_ports = ["CO0", "CO1", "CO2", "CO3"]

    def check_if_rest_of_carry4_is_unused(cellname, cell_idx):
        assert cell_idx < len(O_ports)

        cell = cells[cellname]
        connections = cell["connections"]

        for o, co in zip(O_ports[cell_idx:], CO_ports[cell_idx:]):
            o_conns = connections[o]
            assert len(o_conns) == 1
            o_bit = o_conns[0]
            if is_bit_used(bit_to_cells, o_bit):
                return False

            co_conns = connections[co]
            assert len(co_conns) == 1
            co_bit = co_conns[0]
            if is_bit_used(bit_to_cells, co_bit):
                return False

        return True

    # Carry chain is congested if both O and CO is used at the same level.
    # CO to next element in the chain is fine.
    for chain_idx, cellname in enumerate(chain):
        cell = cells[cellname]
        connections = cell["connections"]
        for cell_idx, (o, co) in enumerate(zip(O_ports, CO_ports)):
            o_conns = connections[o]
            assert len(o_conns) == 1
            o_bit = o_conns[0]

            co_conns = connections[co]
            assert len(co_conns) == 1
            co_bit = co_conns[0]

            is_o_used = is_bit_used(bit_to_cells, o_bit)
            is_co_used, direct_cellname = is_bit_used_other_than_carry4_cin(
                design, top_module, co_bit, bit_to_cells
            )

            if is_o_used and is_co_used:
                # Output at this row is congested.
                direct_cell = cells[direct_cellname]

                if co == 'CO3' and chain_idx == len(chain) - 1:
                    # This congestion is on the top of the carry chain,
                    # emit a dummy layer to the chain.
                    direct_cell["type"] = "CARRY_CO_TOP_POP"
                    assert int(direct_cell["parameters"]["TOP_OF_CHAIN"]) == 1
                # If this is the last CARRY4 in the chain, see if the
                # remaining part of the chain is idle.
                elif chain_idx == len(chain) - 1 and \
                    check_if_rest_of_carry4_is_unused(cellname, cell_idx + 1):

                    # Because the rest of the CARRY4 is idle, it is safe to
                    # use the next row up to output the top of the carry.
                    connections["S{}".format(cell_idx + 1)] = ["1'b0"]

                    next_o_conns = connections[O_ports[cell_idx + 1]]
                    assert len(next_o_conns) == 1
                    direct_cell["connections"]["CO"][0] = next_o_conns[0]

                    netname, bit_idx = bit_to_nets[next_o_conns[0]]
                    assert bit_idx == 0

                    # Update annotation that this net is now in use.
                    net = design["module"][top_module]["netnames"][netname]
                    assert net["attributes"].get("unused_bits", None) == "0 "
                    del net["attributes"]["unused_bits"]
                else:
                    # The previous two stragies (use another layer of carry)
                    # only work for the top of the chain.  This appears to be
                    # in the middle of the chain, so just spill it out to a
                    # LUT, and fixup the direct carry chain (if any).
                    direct_cell["type"] = "CARRY_CO_LUT"

                    fixup_cin(
                        design, top_module, bit_to_cells, co_bit,
                        direct_cellname
                    )


def main():
    design = json.load(sys.stdin)
    top_module = find_top_module(design)

    bit_to_cells = create_bit_to_cell_map(design, top_module)
    bit_to_nets = create_bit_to_net_map(design, top_module)

    for chain in find_carry4_chains(design, top_module, bit_to_cells):
        fixup_congested_rows(
            design, top_module, bit_to_cells, bit_to_nets, chain
        )

    json.dump(design, sys.stdout, indent=2)


if __name__ == "__main__":
    main()
