#!/usr/bin/env python3
import argparse
import os
import re
import json

import lxml.etree as ET
import sdf_timing.sdfparse
from sdf_timing.utils import get_scale_seconds

from termcolor import colored

DEBUG = 0


def log(ltype, message, outdesc=None):
    """Prints log messages.

    Parameters
    ----------
    ltype: str
        Log type, can be INFO, WARNING, ERROR
    message: str
        Log message
    """

    LOGLEVELS = ["INFO", "WARNING", "ERROR", "ALL"]
    SUPPRESSBELOW = "ERROR"

    if ltype not in LOGLEVELS[:-1]:
        return

    dat = {
        "INFO": (0, "green"),
        "WARNING": (1, "yellow"),
        "ERROR": (2, "red"),
        "ALL": (3, "black")
    }

    if dat[ltype][0] >= dat[SUPPRESSBELOW][0]:
        print(colored("{}: {}".format(ltype, message), dat[ltype][1]))
        if outdesc:
            print(
                colored("{}: {}".format(ltype, message), dat[ltype][1]),
                file=outdesc
            )


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

# RAM 2x1 ports, their widths and associated clocks.
# FIXME: Read that from the techfile or phy_db.pickle
RAM_2X1_PORTS = {
    "input":
        [
            # RAM part 1, port 1
            ["WIDTH_SELECT1_0", 2, None],
            ["CLK1EN_0", 1, None],  # "CLK1_0"],
            ["CS1_0", 1, None],  # "CLK1_0"],
            ["A1_0", 11, "CLK1_0"],
            ["WD_0", 18, "CLK1_0"],
            ["WEN1_0", 2, "CLK1_0"],
            ["P1_0", 1, "CLK1_0"],

            # RAM part 1, port 2
            ["WIDTH_SELECT2_0", 2, None],
            ["CLK2EN_0", 1, None],  # "CLK2_0"],
            ["CS2_0", 1, None],  # "CLK2_0"],
            ["A2_0", 11, "CLK2_0"],
            ["P2_0", 1, "CLK2_0"],

            # RAM part 1, common
            ["CONCAT_EN_0", 1, None],
            ["PIPELINE_RD_0", 1, None],
            ["FIFO_EN_0", 1, None],
            ["DIR_0", 1, None],
            ["SYNC_FIFO_0", 1, None],
            ["ASYNC_FLUSH_0", 1, None],

            # RAM part 2, port 1
            ["WIDTH_SELECT1_1", 2, None],
            ["CLK1EN_1", 1, None],  # "CLK1_1"],
            ["CS1_1", 1, None],  # "CLK1_1"],
            ["A1_1", 11, "CLK1_1"],
            ["WD_1", 18, "CLK1_1"],
            ["WEN1_1", 2, "CLK1_1"],
            ["P1_1", 1, "CLK1_1"],

            # RAM part 2, port 2
            ["WIDTH_SELECT2_1", 2, None],
            ["CLK2EN_1", 1, None],  # "CLK2_1"],
            ["CS2_1", 1, None],  # "CLK2_1"],
            ["A2_1", 11, "CLK2_1"],
            ["P2_1", 1, "CLK2_1"],

            # RAM part 2, common
            ["CONCAT_EN_1", 1, None],
            ["PIPELINE_RD_1", 1, None],
            ["FIFO_EN_1", 1, None],
            ["DIR_1", 1, None],
            ["SYNC_FIFO_1", 1, None],
            ["ASYNC_FLUSH_1", 1, None],

            # Common, unknown
            ["DS", 1, None],
            ["DS_RB1", 1, None],
            ["LS", 1, None],
            ["LS_RB1", 1, None],
            ["SD", 1, None],
            ["SD_RB1", 1, None],
            ["RMA", 4, None],
            ["RMB", 4, None],
            ["RMEA", 1, None],
            ["RMEB", 1, None],
            ["TEST1A", 1, None],
            ["TEST1B", 1, None],
        ],
    "clock":
        [
            # RAM part 1
            ["CLK1_0", 1, None],
            ["CLK2_0", 1, None],

            # RAM part 2
            ["CLK1_1", 1, None],
            ["CLK2_1", 1, None],
        ],
    "output":
        [
            # RAM part 1, port 1
            ["Almost_Full_0", 1, "CLK1_0"],
            ["PUSH_FLAG_0", 4, "CLK1_0"],

            # RAM part 1, port 2
            ["Almost_Empty_0", 1, "CLK2_0"],
            ["POP_FLAG_0", 4, "CLK2_0"],
            ["RD_0", 18, "CLK2_0"],

            # RAM part 2, port 1
            ["Almost_Full_1", 1, "CLK1_1"],
            ["PUSH_FLAG_1", 4, "CLK1_1"],

            # RAM part 2, port 2
            ["Almost_Empty_1", 1, "CLK2_1"],
            ["POP_FLAG_1", 4, "CLK2_1"],
            ["RD_1", 18, "CLK2_1"],
        ],
}

# A list of non-routable ports
RAM_2X1_NON_ROUTABLE_PORTS = {
    "input":
        [
            ["CLK1S_0", 1, None],
            ["CLK2S_0", 1, None],
            ["CLK1S_1", 1, None],
            ["CLK2S_1", 1, None],
            ["ASYNC_FLUSH_S0", 1, None],
            ["ASYNC_FLUSH_S1", 1, None],
        ]
}

# A list of test ports
RAM_TEST_PORTS = [
    "DS",
    "DS_RB1",
    "LS",
    "LS_RB1",
    "SD",
    "SD_RB1",
    "RMA",
    "RMB",
    "RMEA",
    "RMEB",
    "TEST1A",
    "TEST1B",
]

# A list of test ports specific to a device
RAM_2X1_TEST_PORTS = {
    "ql-eos-s3": RAM_TEST_PORTS,
    "ql-pp3e": [],
}

# A list of ports relevant only in RAM mode
RAM_PORTS = [
    "WEN1",
    "WEN2",
    "A1",
    "A2",
]

# A list of ports relevant only in FIFO mode
FIFO_PORTS = [
    "DIR",
    "SYNC_FIFO",
    "ASYNC_FLUSH",
    "P1",
    "P2",
    "Almost_Full",
    "Almost_Empty",
    "PUSH_FLAG",
    "POP_FLAG",
]

# A clock map for FIFO operating in DIR=1 mode
FIFO_CLOCK_MAP = {
    "CLK1_0": "CLK2_0",
    "CLK2_0": "CLK1_0",
    "CLK1_1": "CLK2_1",
    "CLK2_1": "CLK1_1",
    "CLK1": "CLK2",
    "CLK2": "CLK1",
}

# A list of non-splitable ports
NON_SPLITABLE_PORTS = [
    "WIDTH_SELECT1_0",
    "WIDTH_SELECT2_0",
    "WIDTH_SELECT1_1",
    "WIDTH_SELECT2_1",
    "WIDTH_SELECT1",
    "WIDTH_SELECT2",
]

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


def blacklist_ports(ports, blacklist):
    """
    Removes port present on the blacklist
    """

    new_ports = dict()

    for key, ports in ports.items():
        new_ports[key] = []

        for name, width, assoc_clock in ports:
            if name not in blacklist:
                new_ports[key].append([name, width, assoc_clock])

    return new_ports


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


def yield_ram_modes(ram_tree):
    """
    Yields all possible combinations of ram modes. Generated strings contain
    comma separated control signal conditions.
    """

    def inner(d, cond_prefix=None):
        for k, v in d.items():
            if not cond_prefix:
                cond = k
            else:
                cond = cond_prefix + "," + k

            if v is None:
                yield cond
            else:
                yield from inner(v, cond)

    yield from inner(ram_tree)


def make_mode_name(cond):
    """
    Formats a mode name given a condition set
    """

    name = []
    for c in cond.split(","):
        sig, val = [s.strip() for s in c.strip().split("=")]

        # If the signal name ends with a digit, replace it with a letter
        # FIXME: Assuming start from 1
        if sig[-1].isdigit():
            n = int(sig[-1])
            sig = sig[:-1] + "_" + chr(ord('A') + n - 1)

        # Abbreviate the signal
        fields = sig.split("_")
        sig = "".join([f[0] for f in fields])

        # Append the value
        sig += val
        name.append(sig)

    return "_".join(name)


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


def filter_cells(
        timings, cond, part=None, normalized_names=False, debug=False
):
    """
    Filters SDF timings basing on conditions present in cell type names.

    If a negated condition from the condition list is found in a cell type
    then that cell type is rejected.
    """

    # Make false condition strings
    cond_strs = []
    for c in cond.split(","):
        sig, val = [s.strip() for s in c.strip().split("=")]

        # There appears to be a single CONCAT_EN_0 condition for both cells.
        # Handle it here separately
        if sig == "CONCAT_EN":
            nval = str(1 - int(val))
            cond_strs.append(sig + "_0" + "_EQ_" + nval)
            continue

        # For a single part
        if part is not None:

            assert part in [0, 1], part
            part_str = "_{}".format(int(part))

            # Single bit
            # "<param>_EQ_<!val>"
            nval = str(1 - int(val))
            cond_strs.append(sig + part_str + "_EQ_" + nval)

            # Single bit of a multi-bit parameter
            # "<param>_<bit_idx>_EQ_<!bit_val>"
            # FIXME: Assuming 2-bit max !!
            for b in range(4):
                nval = str(int((int(val) & (1 << b)) == 0))
                if normalized_names:
                    cond_strs.append(sig + part_str + str(b) + "_EQ_" + nval)
                else:
                    cond_strs.append(
                        sig + part_str + "[{}]".format(b) + "_EQ_" + nval
                    )

            # Reject the other part completely
            other_part_str = "_{}".format(int(1 - part))

            cond_strs.append(sig + other_part_str + "_EQ_0")
            cond_strs.append(sig + other_part_str + "_EQ_1")

            # FIXME: Assuming 2-bit max !!
            for b in range(4):
                if normalized_names:
                    cond_strs.append(sig + other_part_str + str(b) + "_EQ_0")
                    cond_strs.append(sig + other_part_str + str(b) + "_EQ_1")
                else:
                    cond_strs.append(
                        sig + other_part_str + "[{}]".format(b) + "_EQ_0"
                    )
                    cond_strs.append(
                        sig + other_part_str + "[{}]".format(b) + "_EQ_1"
                    )

        # For both parts
        else:

            # Assume that control parameters must be equal for both parts
            nval = str(1 - int(val))
            cond_strs.append(sig + "_0" + "_EQ_" + nval)
            cond_strs.append(sig + "_1" + "_EQ_" + nval)

            for b in range(4):
                nval = str(int((int(val) & (1 << b)) == 0))
                if normalized_names:
                    cond_strs.append(sig + "_0" + str(b) + "_EQ_" + nval)
                    cond_strs.append(sig + "_1" + str(b) + "_EQ_" + nval)
                else:
                    cond_strs.append(
                        sig + "_0" + "[{}]".format(b) + "_EQ_" + nval
                    )
                    cond_strs.append(
                        sig + "_1" + "[{}]".format(b) + "_EQ_" + nval
                    )

    # DEBUG
    if debug:
        print(cond)
        for s in cond_strs:
            print("", "!" + s)

    # Filter
    cells = {}
    for cell_type, cell_data in timings.items():

        if debug:
            print("", "check", cell_type)

        # If any of the false conditions is found in the cell_type then the
        # cell is rejected
        reject = False
        for s in cond_strs:
            if s in cell_type:
                if debug:
                    print(" ", "reject", s)
                reject = True

        # The cell is ok
        if not reject:
            if debug:
                print(" ", "OK")
            assert cell_type not in cells
            cells[cell_type] = cell_data

    return cells


def filter_instances(timings, name):
    """
    Filters a single cell instance from the given timing data
    """

    cells = {}
    for cell_type, cell_data in timings.items():

        # Don't have that instance
        if name not in cell_data:
            continue

        # Leave only the one that we are looking for
        cells[cell_type] = {name: cell_data[name]}

    return cells


def find_timings(timings, src_pin, dst_pin):
    path_timings = {}

    for cell_type, cell_data in timings.items():

        # FIXME: Skip falling edges
        if "FALLING" in cell_type:
            continue

        for inst_name, inst_data in cell_data.items():
            for tname, tdata in inst_data.items():

                # Got matching pins
                if src_pin in tdata["from_pin"]:
                    if dst_pin in tdata["to_pin"]:

                        if tname in path_timings:
                            print("new", cell_type)
                            print("old", path_timings[tname][0])
                            # FIXME
                            continue

                        path_timings[tname] = (
                            cell_type,
                            inst_name,
                            tdata,
                        )

    return path_timings


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


def make_single_ram(ports):
    """
    Makes port definition for a single RAM cell (not 2x1)
    """

    new_ports = {
        "input": set(),
        "clock": set(),
        "output": set(),
    }

    for key in ["input", "clock", "output"]:
        all_port_names = set([p[0] for p in ports[key]])

        for name, width, assoc_clock in ports[key]:

            # Make a generic associated clock name
            if assoc_clock is not None:
                if assoc_clock.endswith("_0"):
                    base_assoc_clock = assoc_clock[:-2]
                if assoc_clock.endswith("_1"):
                    base_assoc_clock = assoc_clock[:-2]
            else:
                base_assoc_clock = None

            # Make a generic port name
            if name.endswith("_0"):
                base = name[:-2]
                if (base + "_1") in all_port_names:
                    new_ports[key].add((base, width, base_assoc_clock))

            elif name.endswith("_1"):
                base = name[:-2]
                if (base + "_0") in all_port_names:
                    new_ports[key].add((base, width, base_assoc_clock))

            # This is a common port for both RAMs, add it unchanged
            else:
                assert key == "input", (
                    key,
                    name,
                    width,
                    assoc_clock,
                )
                new_ports[key].add((
                    name,
                    width,
                    assoc_clock,
                ))

    return new_ports


def remap_clocks(ports, clock_map):
    """
    Remaps clock dependencies of all ports and returns a new port map.
    Does not remap clocks for "P1" and "P2" ports.
    """

    new_ports = {
        "input": set(),
        "clock": set(),
        "output": set(),
    }

    for key in ["input", "clock", "output"]:
        for name, width, assoc_clock in ports[key]:

            # P1 and P2 are not subject to the remap
            if "P1" not in name and "P2" not in name:

                # Remap the associated clock
                if assoc_clock in clock_map:
                    assoc_clock = clock_map[assoc_clock]

            new_ports[key].add((
                name,
                width,
                assoc_clock,
            ))

    return new_ports


def filter_ports(ports, ports_to_filter):
    """
    Removes timing relation from ports of a model
    """

    # Make a copy
    new_ports = dict()

    for key in ["input", "clock", "output"]:
        new_ports[key] = []

        for name, width, assoc_clock in ports[key]:
            if key in ["input", "output"]:
                if name.endswith("_0") or name.endswith("_1"):
                    generic_name = name[:-2]
                    if generic_name in ports_to_filter:
                        assoc_clock = None

                if name in ports_to_filter:
                    assoc_clock = None

            new_ports[key].append((
                name,
                width,
                assoc_clock,
            ))

    return new_ports


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


def make_pin_name(port, index):
    """
    Formats a pin name of a multi-bit port
    """
    return "{}_b{}".format(port, index)


def split_port_bit_index(name):
    """
    Extracts bit index from the port
    """

    m = re.match(r"(?P<name>.*)(_b(?P<bit>[0-9]+))$", name)
    if m is not None:
        return m.group("name"), int(m.group("bit")),

    return name, None


def parse_port_name(name):
    """
    Parses a port name. Returns the base name, cell index and bit index.

    >>> parse_port_name("A_PORT")
    ('A_PORT', None, None)
    >>> parse_port_name("A_PORT_0")
    ('A_PORT', 0, None)
    >>> parse_port_name("A_PORT_b31")
    ('A_PORT', None, 31)
    >>> parse_port_name("A_PORT_0_b15")
    ('A_PORT', 0, 15)
    """

    # A multi-bit port
    m = re.match(r"(?P<name>.*)(_b(?P<bit>[0-9]+))$", name)
    if m is not None:
        port = m.group("name")
        bit = int(m.group("bit"))
    else:
        port = name
        bit = None

    # A port of a sub-cell
    m = re.match(r"(?P<name>.*)(_(?P<cell>[0-9]+))$", port)
    if m is not None:
        return m.group("name"), int(m.group("cell")), bit

    return port, None, bit


def split_ports(ports):
    """
    Splits multi-bit ports into single-bit
    """

    split_ports = dict()
    for key in ports.keys():

        split_ports[key] = list()

        for name, width, assoc_clock in ports[key]:
            if width == 1 or name in NON_SPLITABLE_PORTS:
                split_ports[key].append((
                    name,
                    width,
                    assoc_clock,
                ))
            else:
                for i in range(width):
                    split_ports[key].append(
                        (make_pin_name(name, i), 1, assoc_clock)
                    )

    return split_ports


def make_model(model_name, ports):
    """
    Makex a model XML given the port definition
    """

    # The model root
    xml_model = ET.Element("model", {
        "name": model_name,
    })

    # Port lists
    xml_ports = {
        "input": ET.SubElement(xml_model, "input_ports"),
        "output": ET.SubElement(xml_model, "output_ports"),
    }
    xml_ports["clock"] = xml_ports["input"]

    # Emits a XML tag for a port
    def add_port(xml_parent, name, width, assoc_clock):

        # A clock
        if key == "clock":
            assert assoc_clock is None, (name, width, assoc_clock)
            attrs = {"is_clock": "1"}

        # An input / output
        else:
            if assoc_clock is not None:
                attrs = {"clock": assoc_clock}
            else:
                attrs = dict()

        ET.SubElement(xml_parent, "port", {"name": name, **attrs})

    # Add ports
    for key in ["clock", "input", "output"]:
        for name, width, assoc_clock in ports[key]:
            add_port(xml_ports[key], name, width, assoc_clock)

    return xml_model


def make_pb_type(
        pb_name,
        ports,
        model_name,
        timings=None,
        timescale=1.0,
        normalized_names=False
):

    stats = {
        "total_timings": 0,
        "missing_timings": 0,
    }

    # The pb_type tag
    if model_name:
        attrs = {"blif_model": ".subckt {}".format(model_name)}
    else:
        attrs = dict()

    xml_pb = ET.Element("pb_type", {"name": pb_name, "num_pb": "1", **attrs})

    # Ports
    for key in ["clock", "input", "output"]:
        for name, width, *data in ports[key]:
            ET.SubElement(
                xml_pb, key, {
                    "name": name,
                    "num_pins": str(width),
                }
            )

    # fasm
    if model_name:
        xml_metadata = ET.SubElement(xml_pb, "metadata")
        xml_fasmprefix = ET.SubElement(
            xml_metadata, "meta", {"name": "fasm_prefix"}
        )
        xml_fasmprefix.text = "RAM.RAM"
        xml_fasm = ET.SubElement(xml_metadata, "meta", {"name": "fasm_params"})
        if "_0_" in pb_name:
            xml_fasm.text = "\n\
               INIT[9215:0] = INIT\n"

        elif "_1_" in pb_name:
            xml_fasm.text = "\n\
               INIT[18431:9216] = INIT\n"

        else:
            xml_fasm.text = "\n\
               INIT[18431:0] = INIT\n"

    # Timings
    if timings is not None:

        # Setup and hold
        for name, width, assoc_clock in ports["input"]:
            if assoc_clock is None:
                continue

            # Split the port and its bit index (if any)
            alias, bit = split_port_bit_index(name)

            # Find all timing paths for that port
            path_timings = find_timings(timings, assoc_clock, alias.upper())

            # Bit index suffix
            if bit is not None:
                if normalized_names:
                    suffix = "{}".format(bit)
                else:
                    suffix = "[{}]".format(bit)
            else:
                suffix = ""

            # Setup
            for key in path_timings:

                if key.startswith("setup") and key.endswith(suffix):
                    tim = path_timings[key][2]
                    delay = tim["delay_paths"]["nominal"]["avg"] * timescale
                    break

                if key.startswith("setuphold") and key.endswith(suffix):
                    tim = path_timings[key][2]
                    print("SETUPHOLD", tim)
                    exit(-1)
                    delay = tim["delay_paths"]["nominal"]["avg"] * timescale
                    break

            else:
                delay = 1e-10
                stats["missing_timings"] += 1
                log(
                    "WARNING",
                    "No setup timing for '{}'->'{}' for pb_type '{}'".format(
                        alias + suffix, assoc_clock, pb_name
                    )
                )

            stats["total_timings"] += 1

            ET.SubElement(
                xml_pb, "T_setup", {
                    "port": name,
                    "clock": assoc_clock,
                    "value": "{:+e}".format(delay)
                }
            )

            # Hold
            for key in path_timings:

                if key.startswith("hold") and key.endswith(suffix):
                    tim = path_timings[key][2]
                    delay = tim["delay_paths"]["nominal"]["avg"] * timescale
                    break

                if key.startswith("setuphold") and key.endswith(suffix):
                    tim = path_timings[key][2]
                    print("SETUPHOLD", tim)
                    exit(-1)
                    delay = tim["delay_paths"]["nominal"]["avg"] * timescale
                    break

            else:
                delay = 1e-10
                stats["missing_timings"] += 1
                log(
                    "WARNING",
                    "No hold timing for '{}'->'{}' for pb_type '{}'".format(
                        alias + suffix, assoc_clock, pb_name
                    )
                )

            stats["total_timings"] += 1

            ET.SubElement(
                xml_pb, "T_hold", {
                    "port": name,
                    "clock": assoc_clock,
                    "value": "{:+e}".format(delay)
                }
            )

        # Clock to Q
        for name, width, assoc_clock in ports["output"]:
            if assoc_clock is None:
                continue

            # Split the port and its bit index (if any)
            alias, bit = split_port_bit_index(name)

            # Find all timing paths for that port
            path_timings = find_timings(timings, assoc_clock, alias.upper())

            # Index suffixes
            # Bit index suffix
            if bit is not None:
                if normalized_names:
                    suffix = "{}".format(bit)
                else:
                    suffix = "[{}]".format(bit)
            else:
                suffix = ""

            # "Clock to Q"
            for key in path_timings:

                if key.startswith("iopath") and key.endswith(suffix):
                    tim = path_timings[key][2]
                    delay_min = tim["delay_paths"]["slow"]["min"] * timescale
                    delay_max = tim["delay_paths"]["slow"]["max"] * timescale
                    break

            else:
                delay_min = 1e-10
                delay_max = 1e-10
                stats["missing_timings"] += 1
                log(
                    "WARNING",
                    "No \"clock to Q\" timing for '{}'->'{}' for pb_type '{}'".
                    format(assoc_clock, alias + suffix, pb_name)
                )

            stats["total_timings"] += 1

            ET.SubElement(
                xml_pb, "T_clock_to_Q", {
                    "port": name,
                    "clock": assoc_clock,
                    "min": "{:+e}".format(delay_min),
                    "max": "{:+e}".format(delay_max)
                }
            )

    return xml_pb, stats


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


def auto_interconnect(pb_type):
    """
    Automatically generates an interconnect that connects matching ports of
    a child pb_type to its parent. Moreover, when a child pb_type is suffixed
    with sth. like "_0" then parent ports with the same suffix are matched.
    """

    def get_ports(pb, type):
        """
        Yields pb_type ports of the given type
        """
        for port in pb.findall(type):
            yield port.attrib["name"], int(port.attrib["num_pins"]),

    # Get parent for the interconnect (can be either "mode" or "pb_type")
    assert pb_type.tag == "mode"

    pb_parent = pb_type.getparent()
    assert pb_parent.tag == "pb_type"

    pb_children = list(pb_type.findall("pb_type"))

    # Upstream ports
    parent_name = pb_parent.attrib["name"]
    parent_ports = set([(*p, "I") for p in get_ports(pb_parent, "input")])
    parent_ports |= set([(*p, "I") for p in get_ports(pb_parent, "clock")])
    parent_ports |= set([(*p, "O") for p in get_ports(pb_parent, "output")])

    # Downstream ports
    children = {}
    for child in pb_children:
        name = child.attrib["name"]
        ports = set([(*p, "I") for p in get_ports(child, "input")])
        ports |= set([(*p, "I") for p in get_ports(child, "clock")])
        ports |= set([(*p, "O") for p in get_ports(child, "output")])

        children[name] = ports

    # Adds a connection
    def add_connection(xml, iname, oname, reverse=False):
        if reverse:
            ET.SubElement(
                xml, "direct", {
                    "name": "{}_to_{}".format(oname, iname),
                    "input": oname,
                    "output": iname
                }
            )
        else:
            ET.SubElement(
                xml, "direct", {
                    "name": "{}_to_{}".format(iname, oname),
                    "input": iname,
                    "output": oname
                }
            )

    # Create the interconnect
    ic = ET.SubElement(pb_type, "interconnect")

    for child in sorted(children.keys()):
        child_ports = sorted(list(children[child]), key=lambda x: x[0])

        # Get the child cell index
        m = re.match(r"(.*)(_(?P<idx>[0-9]+))$", child)
        if m is not None:
            child_index = int(m.group("idx"))
        else:
            child_index = None

        # Loop over all child ports
        for dn_port, dn_width, dn_type in child_ports:

            # Got a 1-to-1 match
            if (dn_port, dn_width, dn_type) in parent_ports:
                iname = "{}.{}".format(parent_name, dn_port)
                oname = "{}.{}".format(child, dn_port)
                add_connection(ic, iname, oname, dn_type == "O")
                continue

            # Parse the child port name
            dn_alias, dn_index, dn_bit = parse_port_name(dn_port)

            # Got a match with the child cell index
            up_port = "{}_{}".format(dn_alias, child_index)
            if (up_port, dn_width, dn_type) in parent_ports:
                iname = "{}.{}".format(parent_name, up_port)
                oname = "{}.{}".format(child, dn_port)
                add_connection(ic, iname, oname, dn_type == "O")
                continue

            # The downstream port is split into bits
            if dn_bit is not None:

                # Try without the cell index
                ports = [(*p, ) for p in parent_ports if p[0] == dn_alias]
                assert len(ports) < 2, ports

                if ports:
                    up_port, up_width, up_type = ports[0]
                    iname = "{}.{}[{}]".format(parent_name, up_port, dn_bit)
                    oname = "{}.{}".format(child, dn_port)
                    add_connection(ic, iname, oname, dn_type == "O")
                    continue

                up_alias = "{}_{}".format(dn_alias, dn_index)
                ports = [(*p, ) for p in parent_ports if p[0] == up_alias]
                assert len(ports) < 2, ports

                if ports:
                    up_port, up_width, up_type = ports[0]
                    iname = "{}.{}[{}]".format(parent_name, up_port, dn_bit)
                    oname = "{}.{}".format(child, dn_port)
                    add_connection(ic, iname, oname, dn_type == "O")
                    continue

            # Couldn't find a matching port
            print(
                "ERROR: No matching parent port in '{}' for '{}.{}'".format(
                    parent_name, child, dn_port
                )
            )

    return ic


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


def make_ports(ports, separator=",\n"):
    verilog = ""

    for key in ["clock", "input", "output"]:
        if key == "clock":
            type = "input"
        else:
            type = key

        verilog += "\n"

        for name, width, assoc_clock in ports[key]:
            if width > 1:
                verilog += "  {:<6} [{:2d}:0] {}{}".format(
                    type, width - 1, name, separator
                )
            else:
                verilog += "  {:<6}        {}{}".format(type, name, separator)

    return verilog


def make_ram2x1_instance(device, ports, separator=",\n"):
    verilog = ""

    verilog += "\n   ram8k_2x1_cell # (.INIT(INIT)) I1 ( \n"

    for key in ["clock", "input", "output"]:
        for name, width, assoc_clock in ports[key]:
            if name not in RAM_2X1_TEST_PORTS[device]:
                if name[:-3] not in RAM_2X1_TEST_PORTS[device]:
                    if name.find("_0") >= 0 or name.find("_1") >= 0:
                        verilog += "      .{}({}){}".format(
                            name, name, separator
                        )
                    elif name.find("_b") >= 0:
                        verilog += "      .{}({}){}".format(
                            name.replace("_b", "_0_b"), name, separator
                        )
                    else:
                        verilog += "      .{}_0({}){}".format(
                            name, name, separator
                        )

    verilog = verilog[:-2] + ");\n\n"

    return verilog


def make_specify(ports, separator=";\n"):
    verilog = ""

    verilog += "\n  specify\n"
    for key in ["clock", "input", "output"]:
        for name, width, assoc_clock in ports[key]:
            if key == "input":
                if assoc_clock is not None:
                    verilog += "      $setup({}, posedge {}, \"\"){}".format(
                        name, assoc_clock, separator
                    )
                    verilog += "      $hold(posedge {}, {}, \"\"){}".format(
                        assoc_clock, name, separator
                    )
            elif key == "output":
                if assoc_clock is not None:
                    verilog += "      ({}*>{})=\"\"{}".format(
                        assoc_clock, name, separator
                    )

    verilog += "  endspecify\n\n"

    return verilog


def make_blackbox(device, name, ports, specify_ports):

    # Header
    verilog = """
`timescale 1ns/10ps
(* blackbox *)
module {} (
""".format(name)

    # Ports
    verilog += make_ports(ports)
    verilog = verilog[:-2] + "\n"
    verilog += ");\n"

    verilog += "  parameter [18431:0] INIT = 18432'bx;\n"

    # Specify
    verilog += make_specify(specify_ports)

    # RAM2x1 cell instance
    verilog += make_ram2x1_instance(device, ports)

    # Footer
    verilog += "endmodule\n"

    return verilog


def make_techmap(port_blacklist, conditions):

    # The original cell name
    cell_name = "ram8k_2x1_cell_macro"

    # Header
    verilog = "module {} (\n".format(cell_name)

    # Ports
    map_ports = {}
    for key, ports in RAM_2X1_PORTS.items():
        map_ports[key] = list(ports)
        if key in RAM_2X1_NON_ROUTABLE_PORTS:
            map_ports[key] += RAM_2X1_NON_ROUTABLE_PORTS[key]

    verilog += make_ports(map_ports)
    verilog = verilog[:-2] + "\n"
    verilog += ");\n"

    verilog += "\n"

    # Gather significant control parameters
    control_signals = set()
    for condition in conditions:
        for cond_str in condition.split(","):
            sig, val = cond_str.split("=")
            for part in [0, 1]:
                part_sig = "{}_{}".format(sig, part)
                control_signals.add(part_sig)

    # Techmap special parameters
    for sig in sorted(control_signals):
        verilog += "  parameter _TECHMAP_CONSTMSK_{}_ = 1'bx;\n".format(sig)
        verilog += "  parameter _TECHMAP_CONSTVAL_{}_ = 1'bx;\n".format(sig)

    verilog += "\n"

    verilog += "  parameter [18431:0] INIT = 18432'bx;\n"

    # Split condition strings for single and dual ram modes
    sing_conditions = [c for c in conditions if "CONCAT_EN=0" in c]
    dual_conditions = [c for c in conditions if "CONCAT_EN=1" in c]

    # Split RAM mode
    verilog_cond = []
    verilog_cond.append("(_TECHMAP_CONSTVAL_CONCAT_EN_0_ == 1'b0)")
    verilog_cond.append("(_TECHMAP_CONSTVAL_CONCAT_EN_1_ == 1'b0)")
    verilog_cond = " && ".join(verilog_cond)
    verilog += "  // Split RAM\n"
    verilog += "  generate if({}) begin\n".format(verilog_cond)

    # Each part is independent
    model_ports = split_ports(blacklist_ports(RAM_2X1_PORTS, port_blacklist))

    for part in [0, 1]:
        verilog += "    // RAM {}\n".format(part)
        for i, condition in enumerate(sing_conditions):

            # Case condition
            verilog_cond = []
            for condition_str in condition.split(","):
                sig, val = condition_str.split("=")

                if sig == "CONCAT_EN":
                    continue

                cond_part = "(_TECHMAP_CONSTVAL_{}_{}_ == {})".format(
                    sig, part, val
                )
                verilog_cond.append(cond_part)

            verilog_cond = " && ".join(verilog_cond)
            if i == 0:
                verilog += "    if ({}) begin\n".format(verilog_cond)
            else:
                verilog += "    end else if ({}) begin\n".format(verilog_cond)

            # Instance
            mode_name = make_mode_name(condition)
            model_name = "RAM_" + mode_name + "_VPR"

            verilog += "        {} # (\n".format(model_name)

            if part == 0:
                verilog += "        .INIT(INIT[9215:0]),\n"
            else:
                verilog += "        .INIT(INIT[18431:9216]),\n"

            verilog += "        )"
            verilog += "        RAM_{}  (\n".format(part)
            # Ports mapped to the part
            for key in ["clock", "input", "output"]:
                for name, width, assoc_clock in model_ports[key]:

                    # Parse the port name
                    alias, index, bit = parse_port_name(name)

                    # Not for that part
                    if index is not None and part != index:
                        continue

                    if index is None:
                        pname = alias
                    else:
                        pname = "{}_{}".format(alias, index)

                    if bit is not None:
                        portspec = "{}_b{}".format(alias, bit)
                        sigspec = "{}[{}]".format(pname, bit)
                    else:
                        portspec = alias
                        sigspec = pname

                    verilog += "        .{}({}),\n".format(portspec, sigspec)

            verilog = verilog[:-2] + "\n"
            verilog += "        );\n"

        # Error catcher
        verilog += """
    end else begin
      wire _TECHMAP_FAIL_;
    end
"""

    # Non-split (concatenated) RAM mode
    verilog_cond = []
    # It appears that only CONCAT_EN_0 needs to be set
    verilog_cond.append("(_TECHMAP_CONSTVAL_CONCAT_EN_0_ == 1'b1)")
    verilog_cond = " && ".join(verilog_cond)
    verilog += "  // Concatenated RAM\n"
    verilog += "  end else if({}) begin\n".format(verilog_cond)

    for i, condition in enumerate(dual_conditions):

        # Case condition
        verilog_cond = []
        for condition_str in condition.split(","):
            sig, val = condition_str.split("=")

            if sig == "CONCAT_EN":
                continue

            cond_part = "(_TECHMAP_CONSTVAL_{}_0_ == {})".format(sig, val)
            verilog_cond.append(cond_part)

        verilog_cond = " && ".join(verilog_cond)
        if i == 0:
            verilog += "    if ({}) begin\n".format(verilog_cond)
        else:
            verilog += "    end else if ({}) begin\n".format(verilog_cond)

        # Instance
        mode_name = make_mode_name(condition)
        model_name = "RAM_" + mode_name + "_VPR"

        verilog += "        {} # (\n".format(model_name)

        verilog += "        .INIT(INIT[18431:0]),\n"

        verilog += "        )"
        verilog += "      RAM (\n"

        # Ports always mapped 1-to-1
        for key in ["clock", "input", "output"]:
            for name, width, assoc_clock in model_ports[key]:

                # Parse the port name
                alias, index, bit = parse_port_name(name)

                if index is None:
                    pname = alias
                else:
                    pname = "{}_{}".format(alias, index)

                if bit is not None:
                    portspec = "{}_b{}".format(pname, bit)
                    sigspec = "{}[{}]".format(pname, bit)
                else:
                    portspec = pname
                    sigspec = pname

                verilog += "        .{}({}),\n".format(portspec, sigspec)

        verilog = verilog[:-2] + "\n"
        verilog += "      );\n"

    # Error catcher
    verilog += """
    end else begin
      wire _TECHMAP_FAIL_;
    end
"""

    # Error handler for unexpected configuration
    verilog += """
  end else begin
    wire _TECHMAP_FAIL_;

  end endgenerate

"""

    # Footer
    verilog += "endmodule\n"

    return verilog


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


def main():

    # Parse arguments
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--device", type=str, choices=["ql-eos-s3", "ql-pp3e"], required=True
    )
    parser.add_argument(
        "--mode-defs",
        type=str,
        default="ram_modes.json",
        help="A JSON file defining RAM modes"
    )
    parser.add_argument(
        "--sdf", type=str, required=True, help="An SDF file with timing data"
    )
    parser.add_argument(
        "--xml-path", type=str, default="./", help="Output path for XML files"
    )
    parser.add_argument(
        "--vlog-path",
        type=str,
        default="./",
        help="Output path for Verilog files"
    )

    args = parser.parse_args()

    # Prepare RAM port blacklist (containing test ports)
    port_blacklist = set()
    if not RAM_2X1_TEST_PORTS[args.device]:
        port_blacklist = set(RAM_TEST_PORTS)

    # Load the RAM mode tree definition
    with open(args.mode_defs, "r") as fp:
        ram_tree = json.load(fp)

    # Load RAM timings
    with open(args.sdf, "r") as fp:
        ram_timings = sdf_timing.sdfparse.parse(fp.read())
        timescale = get_scale_seconds(ram_timings["header"]["timescale"])

    # Make port definition for a single ram
    ram_ports_all = blacklist_ports(RAM_2X1_PORTS, port_blacklist)
    ram_ports_sing = make_single_ram(ram_ports_all)

    # Gather all RAM instances
    instances = set()
    for v in ram_timings["cells"].values():
        instances |= set(v.keys())

    # Use not normalized names in SDFs (i.e. with brackets)
    # TODO: Make this an argument
    normalized_names = False

    xml_models = {}

    # Generate a pb_type tree for each instance
    for instance in instances:
        print(instance)

        # Initialize the top-level pb_type XML
        xml_pb_root = make_pb_type("RAM", ram_ports_all, None)[0]

        # Wrapper pb_type for split RAM (CONCAT_EN=0)
        xml_mode = ET.SubElement(xml_pb_root, "mode", {"name": "SING"})

        xml_sing = [
            make_pb_type("RAM_0", ram_ports_sing, None)[0],
            make_pb_type("RAM_1", ram_ports_sing, None)[0],
        ]

        for x in xml_sing:
            xml_mode.append(x)

        ic = auto_interconnect(xml_mode)
        xml_mode.append(ic)

        # Wrapper pb_type for non-split RAM (CONCAT_EN=1)
        xml_mode = ET.SubElement(xml_pb_root, "mode", {"name": "DUAL"})
        xml_dual = make_pb_type("RAM_DUAL", ram_ports_all, None)[0]
        xml_mode.append(xml_dual)

        ic = auto_interconnect(xml_mode)
        xml_mode.append(ic)

        # Get timings for this instance
        all_timings = filter_instances(ram_timings["cells"], instance)

        total_timings = 0
        missing_timings = 0

        # Generate RAM modes
        for cond in yield_ram_modes(ram_tree):
            print("", cond)

            mode_name = make_mode_name(cond)
            model_name = "RAM_" + mode_name + "_VPR"

            # CONCAT_EN=0 - the 2x1 RAM is split into two
            if "CONCAT_EN=0" in cond:

                if "FIFO_EN=0" in cond:
                    model_ports = filter_ports(ram_ports_sing, FIFO_PORTS)
                else:
                    model_ports = filter_ports(ram_ports_sing, RAM_PORTS)
                    if "DIR=1" in cond:
                        model_ports = remap_clocks(model_ports, FIFO_CLOCK_MAP)

                # For each part
                for part in [0, 1]:

                    # Filter timings basing on the generated set of conditions
                    # and RAM part
                    timings = filter_cells(
                        all_timings,
                        cond,
                        part,
                        normalized_names=normalized_names
                    )

                    if DEBUG:
                        print(" RAM_" + str(part))
                        for cname, cdata in timings.items():
                            print(" ", cname)
                            for iname, idata in cdata.items():
                                for tname, tdata in idata.items():
                                    print(
                                        "  ", tname, "src={}, dst={}".format(
                                            tdata["from_pin"], tdata["to_pin"]
                                        )
                                    )

                    # Make the mode XML
                    xml_mode = ET.SubElement(
                        xml_sing[part], "mode", {"name": mode_name}
                    )

                    # Make the pb_type XML
                    pb_name = "RAM_{}_{}".format(part, mode_name)
                    xml_pb, stats = make_pb_type(
                        pb_name,
                        split_ports(model_ports),
                        model_name,
                        timings,
                        timescale,
                        normalized_names=normalized_names,
                    )
                    xml_mode.append(xml_pb)

                    total_timings += stats["total_timings"]
                    missing_timings += stats["missing_timings"]

                    # Make the interconnect
                    ic = auto_interconnect(xml_mode)
                    xml_mode.append(ic)

                # Make the model XML
                xml_model = make_model(model_name, split_ports(model_ports))
                xml_models[model_name] = xml_model

            # CONCAT_EN=1 - keep the 2x1 RAM as one
            elif "CONCAT_EN=1" in cond:

                if "FIFO_EN=0" in cond:
                    model_ports = filter_ports(ram_ports_all, FIFO_PORTS)
                else:
                    model_ports = filter_ports(ram_ports_all, RAM_PORTS)
                    if "DIR=1" in cond:
                        model_ports = remap_clocks(model_ports, FIFO_CLOCK_MAP)

                # Filter timings
                timings = filter_cells(
                    all_timings, cond, None, normalized_names=normalized_names
                )

                if DEBUG:
                    print(" Dual RAM")
                    for cname, cdata in timings.items():
                        print(" ", cname)
                        for iname, idata in cdata.items():
                            for tname, tdata in idata.items():
                                print(
                                    "  ", tname, "src={}, dst={}".format(
                                        tdata["from_pin"], tdata["to_pin"]
                                    )
                                )

                # Make the mode XML
                xml_mode = ET.SubElement(xml_dual, "mode", {"name": mode_name})

                # Make the pb_type XML
                pb_name = "RAM_" + mode_name
                xml_pb, stats = make_pb_type(
                    pb_name,
                    split_ports(model_ports),
                    model_name,
                    timings,
                    timescale,
                    normalized_names=normalized_names,
                )
                xml_mode.append(xml_pb)

                total_timings += stats["total_timings"]
                missing_timings += stats["missing_timings"]

                # Make the interconnect
                ic = auto_interconnect(xml_mode)
                xml_mode.append(ic)

                # Make the model XML
                xml_model = make_model(model_name, split_ports(model_ports))
                xml_models[model_name] = xml_model

            # Should not happen
            else:
                assert False, cond

        # Serialize the pb_type XML
        fname = os.path.join(args.xml_path, instance.lower() + ".pb_type.xml")
        ET.ElementTree(xml_pb_root).write(fname, pretty_print=True)

        print("total timings  : {}".format(total_timings))
        print(
            "missing timings: {} {:.2f}%".format(
                missing_timings, 100.0 * missing_timings / total_timings
            )
        )

    # Write models XML
    xml_model_root = ET.Element("models")
    for key in sorted(list(xml_models.keys())):
        xml_model_root.append(xml_models[key])

    fname = os.path.join(args.xml_path, "ram.model.xml")
    ET.ElementTree(xml_model_root).write(fname, pretty_print=True)

    # Make blackboxes
    blackboxes = {}
    for cond in yield_ram_modes(ram_tree):
        mode_name = make_mode_name(cond)
        model_name = "RAM_" + mode_name + "_VPR"

        # CONCAT_EN=0 - the 2x1 RAM is split into two
        if "CONCAT_EN=0" in cond:
            if "DIR=1" in cond:
                ports = remap_clocks(ram_ports_sing, FIFO_CLOCK_MAP)
            else:
                ports = ram_ports_sing

            if "FIFO_EN=0" in cond:
                model_ports = filter_ports(ram_ports_sing, FIFO_PORTS)
            else:
                model_ports = filter_ports(ram_ports_sing, RAM_PORTS)
                if "DIR=1" in cond:
                    model_ports = remap_clocks(model_ports, FIFO_CLOCK_MAP)

            verilog = make_blackbox(
                args.device, model_name, split_ports(ports),
                split_ports(model_ports)
            )
            blackboxes[model_name] = verilog

        # CONCAT_EN=1 - keep the 2x1 RAM as one
        elif "CONCAT_EN=1" in cond:
            if "DIR=1" in cond:
                ports = remap_clocks(ram_ports_all, FIFO_CLOCK_MAP)
            else:
                ports = ram_ports_all

            if "FIFO_EN=0" in cond:
                model_ports = filter_ports(ram_ports_all, FIFO_PORTS)
            else:
                model_ports = filter_ports(ram_ports_all, RAM_PORTS)
                if "DIR=1" in cond:
                    model_ports = remap_clocks(model_ports, FIFO_CLOCK_MAP)

            verilog = make_blackbox(
                args.device, model_name, split_ports(ports),
                split_ports(model_ports)
            )
            blackboxes[model_name] = verilog

    # Write blackbox definitions
    fname = os.path.join(args.vlog_path, "ram_sim.v")
    with open(fname, "w") as fp:
        for k, v in blackboxes.items():
            fp.write(v)

    # Make techmap
    techmap = make_techmap(port_blacklist, list(yield_ram_modes(ram_tree)))
    fname = os.path.join(args.vlog_path, "ram_map.v")
    with open(fname, "w") as fp:
        fp.write(techmap)


if __name__ == "__main__":
    main()
