#!/usr/bin/env python3
"""
Functions related to parsing and processing of data stored in a QuickLogic
TechFile.
"""
from copy import deepcopy
import itertools
import argparse
from collections import defaultdict
import pickle
import re
import csv

import lxml.etree as ET

from data_structs import Pin, PinDirection, Quadrant, ClockCell, Cell, CellType, \
    Tile, TileType, Loc, SwitchboxPinLoc, SwitchboxPinType, Switchbox, SwitchboxPin, \
    SwitchConnection, SwitchPin, PackagePin, OPPOSITE_DIRECTION
from utils import yield_muxes, get_loc_of_cell, find_cell_in_tile, natural_keys
from connections import build_connections, check_connections
from connections import hop_to_str, get_name_and_hop, is_regular_hop_wire

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

# A List of cells and their pins which are clocks. These are relevant only for
# cells modeled as pb_types in VPR and are used to determine whether an input
# pin should be of type "input"/"output" or "clock".
CLOCK_PINS = {
    "LOGIC": ("QCK", ),
    "CLOCK": ("IC", ),
    "GMUX": (
        "IP",
        "IC",
        "IZ",
    ),
    "RAM": (
        "CLK1_0",
        "CLK1_1",
        "CLK2_0",
        "CLK2_1",
    ),
}

# A list of const pins
CONST_PINS = (
    "GND",
    "VCC",
)

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


def parse_library(xml_library):
    """
    Loads cell definitions from the XML
    """

    KNOWN_PORT_ATTRIB = [
        "hardWired",
        "isInvertible",
        "isAsynchronous",
        "realPortName",
        "isblank",
        "io",
        "unet",
    ]

    cells = []

    for xml_node in xml_library:

        # Skip those
        if xml_node.tag in ["PortProperties"]:
            continue

        cell_type = xml_node.tag
        cell_pins = []

        # Load pins
        for xml_pins in itertools.chain(xml_node.findall("INPUT"),
                                        xml_node.findall("OUTPUT")):

            # Pin direction
            if xml_pins.tag == "INPUT":
                direction = PinDirection.INPUT
            elif xml_pins.tag == "OUTPUT":
                direction = PinDirection.OUTPUT
            else:
                assert False, xml_pins.tag

            # "mport"
            for xml_mport in xml_pins:
                xml_bus = xml_mport.find("bus")

                # Check if the port is routable. Skip it if it is not.
                is_routable = xml_mport.get("routable", "true") == "true"
                if not is_routable:
                    continue

                # Gather attributes
                port_attrib = {}
                for key, val in xml_mport.attrib.items():
                    if key in KNOWN_PORT_ATTRIB:
                        port_attrib[key] = str(val)

                # A bus
                if xml_bus is not None:
                    lsb = int(xml_bus.attrib["lsb"])
                    msb = int(xml_bus.attrib["msb"])
                    stp = int(xml_bus.attrib["step"])

                    for i in range(lsb, msb + 1, stp):
                        cell_pins.append(
                            Pin(
                                name="{}[{}]".format(
                                    xml_bus.attrib["name"], i
                                ),
                                direction=direction,
                                attrib=port_attrib,
                            )
                        )

                # A single pin
                else:
                    name = xml_mport.attrib["name"]

                    # HACK: Do not import the CLOCK.OP pin
                    if cell_type == "CLOCK" and name == "OP":
                        continue

                    if cell_type in CLOCK_PINS and \
                       name in CLOCK_PINS[cell_type]:
                        port_attrib["clock"] = "true"

                    cell_pins.append(
                        Pin(
                            name=name,
                            direction=direction,
                            attrib=port_attrib,
                        )
                    )

        # Add the cell
        cells.append(CellType(type=cell_type, pins=cell_pins))

    return cells


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


def load_logic_cells(xml_placement, cellgrid, cells_library):

    # Load "LOGIC" tiles
    xml_logic = xml_placement.find("LOGIC")
    assert xml_logic is not None

    exceptions = set()
    xml_exceptions = xml_logic.find("EXCEPTIONS")
    if xml_exceptions is not None:
        for xml in xml_exceptions:
            tag = xml.tag.upper()

            # FIXME: Is this connect decoding of those werid loc specs?
            x = 1 + ord(tag[0]) - ord("A")
            y = 1 + int(tag[1:])

            exceptions.add(Loc(x=x, y=y, z=0))

    xml_logicmatrix = xml_logic.find("LOGICMATRIX")
    assert xml_logicmatrix is not None

    x0 = int(xml_logicmatrix.get("START_COLUMN"))
    nx = int(xml_logicmatrix.get("COLUMNS"))
    y0 = int(xml_logicmatrix.get("START_ROW"))
    ny = int(xml_logicmatrix.get("ROWS"))

    for j in range(ny):
        for i in range(nx):
            loc = Loc(x0 + i, y0 + j, 0)

            if loc in exceptions:
                continue

            cell_type = "LOGIC"
            assert cell_type in cells_library, cell_type

            cellgrid[loc].append(
                Cell(type=cell_type, index=None, name=cell_type, alias=None)
            )


def load_other_cells(xml_placement, cellgrid, cells_library):

    # Loop over XML entries
    for xml in xml_placement:

        # Got a "Cell" tag
        if xml.tag == "Cell":
            cell_name = xml.get("name")
            cell_type = xml.get("type")

            assert cell_type in cells_library, (
                cell_type,
                cell_name,
            )

            # Cell matrix
            xml_matrices = [x for x in xml if x.tag.startswith("Matrix")]
            for xml_matrix in xml_matrices:
                x0 = int(xml_matrix.get("START_COLUMN"))
                nx = int(xml_matrix.get("COLUMNS"))
                y0 = int(xml_matrix.get("START_ROW"))
                ny = int(xml_matrix.get("ROWS"))

                for j in range(ny):
                    for i in range(nx):
                        loc = Loc(x0 + i, y0 + j, 0)

                        cellgrid[loc].append(
                            Cell(
                                type=cell_type,
                                index=None,
                                name=cell_name,
                                alias=None,
                            )
                        )

            # A single cell
            if len(xml_matrices) == 0:
                x = int(xml.get("column"))
                y = int(xml.get("row"))

                loc = Loc(x, y, 0)
                alias = xml.get("Alias", None)

                cellgrid[loc].append(
                    Cell(
                        type=cell_type,
                        index=None,
                        name=cell_name,
                        alias=alias,
                    )
                )

        # Got something else, parse recursively
        else:
            load_other_cells(xml, cellgrid, cells_library)


def make_tile_type_name(cells):
    """
    Generate the tile type name from cell types
    """
    cell_types = sorted([c.type for c in cells])
    cell_counts = {t: 0 for t in cell_types}

    for cell in cells:
        cell_counts[cell.type] += 1

    parts = []
    for t, c in cell_counts.items():
        if c == 1:
            parts.append(t)
        else:
            parts.append("{}x{}".format(c, t))

    return "_".join(parts).upper()


def parse_placement(xml_placement, cells_library):

    # Load tilegrid quadrants
    quadrants = {}

    xml_quadrants = xml_placement.find("Quadrants")
    assert xml_quadrants is not None

    xmin = None
    xmax = None
    ymin = None
    ymax = None

    for xml_quadrant in xml_quadrants:
        name = xml_quadrant.get("name")
        x0 = int(xml_quadrant.get("ColStartNum"))
        x1 = int(xml_quadrant.get("ColEndNum"))
        y0 = int(xml_quadrant.get("RowStartNum"))
        y1 = int(xml_quadrant.get("RowEndNum"))

        quadrants[name] = Quadrant(
            name=name,
            x0=x0,
            x1=x1,
            y0=y0,
            y1=y1,
        )

        xmin = min(xmin, x0) if xmin is not None else x0
        xmax = max(xmax, x1) if xmax is not None else x1
        ymin = min(ymin, y0) if ymin is not None else y0
        ymax = max(ymax, y1) if ymax is not None else y1

    # Define the initial tile grid. Group cells with the same location
    # together.
    cellgrid = defaultdict(lambda: [])

    # Load LOGIC cells into it
    load_logic_cells(xml_placement, cellgrid, cells_library)
    # Load other cells
    load_other_cells(xml_placement, cellgrid, cells_library)

    # Assign each location with a tile type name generated basing on cells
    # present there.
    tile_types = {}
    tile_types_at_loc = {}
    for loc, cells in cellgrid.items():

        # Generate type and assign
        type = make_tile_type_name(cells)
        tile_types_at_loc[loc] = type

        # A new type? complete its definition
        if type not in tile_types:

            cell_types = [c.type for c in cells]
            cell_count = {
                t: len([c for c in cells if c.type == t])
                for t in cell_types
            }

            tile_type = TileType(type, cell_count)
            tile_type.make_pins(cells_library)
            tile_types[type] = tile_type

    # Make the final tilegrid
    tilegrid = {}
    for loc, type in tile_types_at_loc.items():

        # Group cells by type
        tile_cells_by_type = defaultdict(lambda: [])
        for cell in cellgrid[loc]:

            tile_cells_by_type[cell.type].append(cell)

        # Create a list of cell instances within the tile
        tile_cells = []
        for cell_type, cell_list in tile_cells_by_type.items():
            cell_list.sort(key=lambda c: natural_keys(c.name))

            for i, cell in enumerate(cell_list):
                tile_cells.append(
                    Cell(
                        type=cell.type,
                        index=i,
                        name=cell.name,
                        alias=cell.alias
                    )
                )

        tilegrid[loc] = Tile(
            type=type,
            name="TILE_X{}Y{}".format(loc.x, loc.y),
            cells=tile_cells
        )

    return quadrants, tile_types, tilegrid


def populate_switchboxes(xml_sbox, switchbox_grid):
    """
    Assings each tile in the grid its switchbox type.
    """
    xmin = int(xml_sbox.attrib["ColStartNum"])
    xmax = int(xml_sbox.attrib["ColEndNum"])
    ymin = int(xml_sbox.attrib["RowStartNum"])
    ymax = int(xml_sbox.attrib["RowEndNum"])

    for y, x in itertools.product(range(ymin, ymax + 1), range(xmin,
                                                               xmax + 1)):
        loc = Loc(x, y, 0)

        assert loc not in switchbox_grid, loc
        switchbox_grid[loc] = xml_sbox.tag


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


def update_switchbox_pins(switchbox):
    """
    Identifies top-level inputs and outputs of the switchbox and updates lists
    of them.
    """
    switchbox.inputs = {}
    switchbox.outputs = {}

    # Top-level inputs and their locations. Indexed by pin names.
    input_locs = defaultdict(lambda: [])

    for stage_id, stage in switchbox.stages.items():
        for switch_id, switch in stage.switches.items():
            for mux_id, mux in switch.muxes.items():

                # Add the mux output pin as top level output if necessary
                if mux.output.name is not None:

                    loc = SwitchboxPinLoc(
                        stage_id=stage.id,
                        switch_id=switch.id,
                        mux_id=mux.id,
                        pin_id=0,
                        pin_direction=PinDirection.OUTPUT
                    )

                    if stage.type == "STREET":
                        pin_type = SwitchboxPinType.LOCAL
                    else:
                        pin_type = SwitchboxPinType.HOP

                    pin = SwitchboxPin(
                        id=len(switchbox.outputs),
                        name=mux.output.name,
                        direction=PinDirection.OUTPUT,
                        locs=[loc],
                        type=pin_type
                    )

                    assert pin.name not in switchbox.outputs, pin
                    switchbox.outputs[pin.name] = pin

                # Add the mux input pins as top level inputs if necessary
                for pin in mux.inputs.values():
                    if pin.name is not None:

                        loc = SwitchboxPinLoc(
                            stage_id=stage.id,
                            switch_id=switch.id,
                            mux_id=mux.id,
                            pin_id=pin.id,
                            pin_direction=PinDirection.INPUT
                        )

                        input_locs[pin.name].append(loc)

    # Add top-level input pins to the switchbox.
    keys = sorted(input_locs.keys(), key=lambda k: k[0])
    for name, locs in {k: input_locs[k] for k in keys}.items():

        # Determine the pin type
        is_hop = is_regular_hop_wire(name)
        _, hop = get_name_and_hop(name)

        if name in ["VCC", "GND"]:
            pin_type = SwitchboxPinType.CONST
        elif name.startswith("CAND"):
            pin_type = SwitchboxPinType.GCLK
        elif is_hop:
            pin_type = SwitchboxPinType.HOP
        elif hop is not None:
            pin_type = SwitchboxPinType.FOREIGN
        else:
            pin_type = SwitchboxPinType.LOCAL

        pin = SwitchboxPin(
            id=len(switchbox.inputs),
            name=name,
            direction=PinDirection.INPUT,
            locs=locs,
            type=pin_type
        )

        assert pin.name not in switchbox.inputs, pin
        switchbox.inputs[pin.name] = pin

    return switchbox


def parse_switchbox(xml_sbox, xml_common=None):
    """
    Parses the switchbox definition from XML. Returns a Switchbox object
    """
    switchbox = Switchbox(type=xml_sbox.tag)

    # Identify stages. Append stages from the "COMMON_STAGES" section if
    # given.
    stages = [n for n in xml_sbox if n.tag.startswith("STAGE")]

    if xml_common is not None:
        common_stages = [n for n in xml_common if n.tag.startswith("STAGE")]
        stages.extend(common_stages)

    # Load stages
    for xml_stage in stages:

        # Get stage id
        stage_id = int(xml_stage.attrib["StageNumber"])
        assert stage_id not in switchbox.stages, (
            stage_id, switchbox.stages.keys()
        )

        stage_type = xml_stage.attrib["StageType"]

        # Add the new stage
        stage = Switchbox.Stage(id=stage_id, type=stage_type)
        switchbox.stages[stage_id] = stage

        # Process outputs
        switches = {}
        for xml_output in xml_stage.findall("Output"):
            out_switch_id = int(xml_output.attrib["SwitchNum"])
            out_pin_id = int(xml_output.attrib["SwitchOutputNum"])
            out_pin_name = xml_output.get("JointOutputName", None)

            # These indicate unconnected top-level output.
            if out_pin_name in ["-1"]:
                out_pin_name = None

            # Add a new switch if needed
            if out_switch_id not in switches:
                switches[out_switch_id] = Switchbox.Switch(
                    out_switch_id, stage_id
                )
            switch = switches[out_switch_id]

            # Add a mux for the output
            mux = Switchbox.Mux(out_pin_id, switch.id)
            assert mux.id not in switch.muxes, mux
            switch.muxes[mux.id] = mux

            # Add output pin to the mux
            mux.output = SwitchPin(
                id=0, name=out_pin_name, direction=PinDirection.OUTPUT
            )

            # Process inputs
            for xml_input in xml_output:
                inp_pin_id = int(xml_input.tag.replace("Input", ""))
                inp_pin_name = xml_input.get("WireName", None)
                inp_hop_dir = xml_input.get("Direction", None)
                inp_hop_len = int(xml_input.get("Length", "-1"))

                # These indicate unconnected top-level input.
                if inp_pin_name in ["-1"]:
                    inp_pin_name = None

                # Append the actual wire length and hop diretion to names of
                # pins that connect to HOP wires.
                is_hop = (inp_hop_dir in ["Left", "Right", "Top", "Bottom"])
                if is_hop:
                    inp_pin_name = "{}_{}{}".format(
                        inp_pin_name, inp_hop_dir[0], inp_hop_len
                    )

                # Add the input to the mux
                pin = SwitchPin(
                    id=inp_pin_id,
                    name=inp_pin_name,
                    direction=PinDirection.INPUT
                )

                assert pin.id not in mux.inputs, pin
                mux.inputs[pin.id] = pin

                # Add internal connection
                if stage_type == "STREET" and stage_id > 0:
                    conn_stage_id = int(xml_input.attrib["Stage"])
                    conn_switch_id = int(xml_input.attrib["SwitchNum"])
                    conn_pin_id = int(xml_input.attrib["SwitchOutputNum"])

                    conn = SwitchConnection(
                        src=SwitchboxPinLoc(
                            stage_id=conn_stage_id,
                            switch_id=conn_switch_id,
                            mux_id=conn_pin_id,
                            pin_id=0,
                            pin_direction=PinDirection.OUTPUT
                        ),
                        dst=SwitchboxPinLoc(
                            stage_id=stage.id,
                            switch_id=switch.id,
                            mux_id=mux.id,
                            pin_id=inp_pin_id,
                            pin_direction=PinDirection.INPUT
                        ),
                    )

                    assert conn not in switchbox.connections, conn
                    switchbox.connections.add(conn)

        # Add switches to the stage
        stage.switches = switches

    # Update top-level pins
    update_switchbox_pins(switchbox)

    return switchbox


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


def parse_wire_mapping_table(xml_root, switchbox_grid, switchbox_types):
    """
    Parses the "DeviceWireMappingTable" section. Returns a dict indexed by
    locations.
    """

    def yield_locs_and_maps():
        """
        Yields locations and wire mappings associated with it.
        """
        RE_LOC = re.compile(r"^(Row|Col)_([0-9]+)_([0-9]+)$")

        # Rows
        xml_rows = [e for e in xml_root if e.tag.startswith("Row_")]
        for xml_row in xml_rows:

            # Decode row range
            match = RE_LOC.match(xml_row.tag)
            assert match is not None, xml_row.tag

            row_beg = int(xml_row.attrib["RowStartNum"])
            row_end = int(xml_row.attrib["RowEndNum"])

            assert row_beg == int(match.group(2)), \
                (xml_row.tag, row_beg, row_end)
            assert row_end == int(match.group(3)), \
                (xml_row.tag, row_beg, row_end)

            # Columns
            xml_cols = [e for e in xml_row if e.tag.startswith("Col_")]
            for xml_col in xml_cols:

                # Decode column range
                match = RE_LOC.match(xml_col.tag)
                assert match is not None, xml_col.tag

                col_beg = int(xml_col.attrib["ColStartNum"])
                col_end = int(xml_col.attrib["ColEndNum"])

                assert col_beg == int(match.group(2)), \
                    (xml_col.tag, col_beg, col_end)
                assert col_end == int(match.group(3)), \
                    (xml_col.tag, col_beg, col_end)

                # Wire maps
                xml_maps = [e for e in xml_col if e.tag.startswith("Stage_")]

                # Yield wire maps for each location
                for y in range(row_beg, row_end + 1):
                    for x in range(col_beg, col_end + 1):
                        yield (Loc(x=x, y=y, z=0), xml_maps)

    # Process wire maps
    wire_maps = defaultdict(lambda: {})

    RE_STAGE = re.compile(r"^Stage_([0-9])$")
    RE_JOINT = re.compile(r"^Join\.([0-9]+)\.([0-9]+)\.([0-9]+)$")
    RE_WIREMAP = re.compile(
        r"^WireMap\.(Top|Bottom|Left|Right)\.Length_([0-9])\.(.*)$"
    )

    for loc, xml_maps in yield_locs_and_maps():
        for xml_map in xml_maps:

            # Decode stage id
            match = RE_STAGE.match(xml_map.tag)
            assert match is not None, xml_map.tag

            stage_id = int(xml_map.attrib["StageNumber"])
            assert stage_id == int(match.group(1)), \
                (xml_map.tag, stage_id)

            # Decode wire joints
            joints = {
                k: v
                for k, v in xml_map.attrib.items()
                if k.startswith("Join.")
            }
            for joint_key, joint_map in joints.items():

                # Decode the joint key
                match = RE_JOINT.match(joint_key)
                assert match is not None, joint_key

                pin_loc = SwitchboxPinLoc(
                    stage_id=stage_id,
                    switch_id=int(match.group(1)),
                    mux_id=int(match.group(2)),
                    pin_id=int(match.group(3)),
                    pin_direction=PinDirection.
                    INPUT  # FIXME: Are those always inputs ?
                )

                # Decode the wire name
                match = RE_WIREMAP.match(joint_map)
                assert match is not None, joint_map

                wire_hop_dir = match.group(1)
                wire_hop_len = int(match.group(2))
                wire_name = match.group(3)

                # Compute location of the tile that the wire is connected to
                if wire_hop_dir == "Top":
                    tile_loc = Loc(x=loc.x, y=loc.y - wire_hop_len, z=0)
                elif wire_hop_dir == "Bottom":
                    tile_loc = Loc(x=loc.x, y=loc.y + wire_hop_len, z=0)
                elif wire_hop_dir == "Left":
                    tile_loc = Loc(x=loc.x - wire_hop_len, y=loc.y, z=0)
                elif wire_hop_dir == "Right":
                    tile_loc = Loc(x=loc.x + wire_hop_len, y=loc.y, z=0)
                else:
                    assert False, wire_hop_dir

                # Append to the map
                wire_maps[loc][pin_loc] = (wire_name, tile_loc)

    return wire_maps


def parse_port_mapping_table(xml_root, switchbox_grid):
    """
    Parses switchbox port mapping tables. Returns a dict indexed by locations
    containing a dict with switchbox port to tile port name correspondence.
    """
    port_maps = defaultdict(lambda: {})

    # Sections are named "*_Table"
    xml_tables = [e for e in xml_root if e.tag.endswith("_Table")]
    for xml_table in xml_tables:

        # Get the origin
        origin = xml_table.tag.split("_")[0]
        assert origin in ["Left", "Right", "Top", "Bottom"], origin

        # Get switchbox types affected by the mapping
        sbox_types_xml = xml_table.find("SBoxTypes")
        assert sbox_types_xml is not None
        switchbox_types = set(
            [
                v for k, v in sbox_types_xml.attrib.items()
                if k.startswith("type")
            ]
        )

        # Get their locations
        locs = [
            loc for loc, type in switchbox_grid.items()
            if type in switchbox_types
        ]

        # Get the first occurrence of a switchbox with one of considered types
        # that is closes to the (0, 0) according to manhattan distance.
        base_loc = None
        for loc in locs:
            if not base_loc:
                base_loc = loc
            elif (loc.x + loc.y) < (base_loc.x + base_loc.y):
                base_loc = loc

        # Parse the port mapping table(s)
        for port_mapping_xml in xml_table.findall("PortMappingTable"):

            # Get the direction of the switchbox offset
            orientation = port_mapping_xml.attrib["Orientation"]
            if orientation == "Horizontal":
                assert origin in ["Top", "Bottom"], (origin, orientation)
                dx, dy = (+1, 0)
            elif orientation == "Vertical":
                assert origin in ["Left", "Right"], (origin, orientation)
                dx, dy = (0, +1)

            # Process the mapping of switchbox output ports
            for index_xml in port_mapping_xml.findall("Index"):
                pin_name = index_xml.attrib["Mapped_Interface_Name"]
                output_num = index_xml.attrib["SwitchOutputNum"]

                # Skip this index - empty switchbox
                if (pin_name == "-1"):
                    continue

                # Determine the mapped port direction
                if output_num == "-1":
                    pin_direction = PinDirection.INPUT
                else:
                    pin_direction = PinDirection.OUTPUT

                sbox_xmls = [e for e in index_xml if e.tag.startswith("SBox")]
                for sbox_xml in sbox_xmls:

                    offset = int(sbox_xml.attrib["Offset"])
                    mapped_name = sbox_xml.get("MTB_PortName", None)

                    # "-1" means unconnected
                    if mapped_name == "-1":
                        mapped_name = None

                    # Get the location for the map
                    loc = Loc(
                        x=base_loc.x + dx * offset,
                        y=base_loc.y + dy * offset,
                        z=0
                    )

                    # Append mapping
                    key = (pin_name, pin_direction)
                    assert key not in port_maps[loc], (loc, key)

                    port_maps[loc][key] = mapped_name

    # Make a normal dict
    port_maps = dict(port_maps)

    return port_maps


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


def parse_clock_network(xml_clock_network):
    """
    Parses the "CLOCK_NETWORK" section of the techfile
    """

    def parse_cell(xml_cell, quadrant=None):
        """
        Parses a "Cell" tag inside "CLOCK_NETWORK"
        """
        NON_PIN_TAGS = ("name", "type", "row", "column")

        cell_loc = Loc(
            x=int(xml_cell.attrib["column"]),
            y=int(xml_cell.attrib["row"]),
            z=0
        )

        # Get the cell's pinmap
        pin_map = {
            k: v
            for k, v in xml_cell.attrib.items()
            if k not in NON_PIN_TAGS
        }

        # Return the cell
        return ClockCell(
            type=xml_cell.attrib["type"],
            name=xml_cell.attrib["name"],
            loc=cell_loc,
            quadrant=quadrant,
            pin_map=pin_map
        )

    clock_cells = {}

    # Parse GMUX cells
    xml_gmux = xml_clock_network.find("GMUX")
    assert xml_gmux is not None

    for xml_cell in xml_gmux.findall("Cell"):
        clock_cell = parse_cell(xml_cell)
        clock_cells[clock_cell.name] = clock_cell

    # Parse QMUX cells
    xml_qmux = xml_clock_network.find("QMUX")
    assert xml_qmux is not None

    for xml_quad in xml_qmux:
        for xml_cell in xml_quad.findall("Cell"):
            clock_cell = parse_cell(xml_cell, xml_quad.tag)
            clock_cells[clock_cell.name] = clock_cell

    # Parse CAND cells
    xml_cand = xml_clock_network.find("COL_CLKEN")
    assert xml_cand is not None

    for xml_quad in xml_cand:
        for xml_cell in xml_quad.findall("Cell"):
            clock_cell = parse_cell(xml_cell, xml_quad.tag)
            clock_cells[clock_cell.name] = clock_cell

    # Since we are not going to use dynamic enables on CAND we remove the EN
    # pin connection from the pinmap. This way the connections between
    # switchboxes which drive them can be used for generic routing.
    for cell_name in clock_cells.keys():

        cell = clock_cells[cell_name]
        pin_map = cell.pin_map

        if cell.type == "CAND" and "EN" in pin_map:
            del pin_map["EN"]

        clock_cells[cell_name] = ClockCell(
            name=cell.name,
            type=cell.type,
            loc=cell.loc,
            quadrant=cell.quadrant,
            pin_map=pin_map
        )

    return clock_cells


def populate_clk_mux_port_maps(
        port_maps, clock_cells, tile_grid, cells_library
):
    """
    Converts global clock network cells port mappings and appends them to
    the port_maps used later for switchbox specialization.
    """

    for clock_cell in clock_cells.values():
        cell_type = clock_cell.type
        loc = clock_cell.loc

        # Find the cell in the cells_library to get its pin definitions
        assert cell_type in cells_library, cell_type
        cell_pins = cells_library[cell_type].pins

        # Find the cell in a tile
        tile = tile_grid[loc]
        cell = find_cell_in_tile(clock_cell.name, tile)

        # Add the mux location to the port map
        if loc not in port_maps:
            port_maps[loc] = {}

        # Add map entries
        for mux_pin_name, sbox_pin_name in clock_cell.pin_map.items():

            # Get the pin definition to get its driection.
            cell_pin = [p for p in cell_pins if p.name == mux_pin_name]
            assert len(cell_pin) == 1, (clock_cell, mux_pin_name)
            cell_pin = cell_pin[0]

            # Skip hard-wired pins
            if cell_pin.attrib.get("hardWired", None) == "true":
                continue

            # Add entry to the map
            key = (sbox_pin_name, OPPOSITE_DIRECTION[cell_pin.direction])

            assert key not in port_maps[loc], (port_maps[loc], key)
            port_maps[loc][key] = "{}{}_{}".format(
                cell.type, cell.index, mux_pin_name
            )


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


def specialize_switchboxes_with_port_maps(
        switchbox_types, switchbox_grid, port_maps
):
    """
    Specializes switchboxes by applying port mapping.
    """

    for loc, port_map in port_maps.items():

        # No switchbox at that location
        if loc not in switchbox_grid:
            continue

        # Get the switchbox type
        switchbox_type = switchbox_grid[loc]
        switchbox = switchbox_types[switchbox_type]

        # Make a copy of the switchbox
        suffix = "X{}Y{}".format(loc.x, loc.y)
        if not switchbox.type.endswith(suffix):
            new_type = "{}_{}".format(switchbox.type, suffix)
        else:
            new_type = switchbox_type
        new_switchbox = Switchbox(new_type)
        new_switchbox.stages = deepcopy(switchbox.stages)
        new_switchbox.connections = deepcopy(switchbox.connections)

        # Remap pin names
        did_remap = False
        for stage, switch, mux in yield_muxes(new_switchbox):

            # Remap output
            alt_name = "{}.{}.{}".format(stage.id, switch.id, mux.id)

            pin = mux.output
            keys = ((pin.name, pin.direction), (alt_name, pin.direction))

            for key in keys:
                if key in port_map:
                    did_remap = True
                    mux.output = SwitchPin(
                        id=pin.id,
                        name=port_map[key],
                        direction=pin.direction,
                    )
                    break

            # Remap inputs
            for pin in mux.inputs.values():
                key = (pin.name, pin.direction)
                if key in port_map:
                    did_remap = True
                    mux.inputs[pin.id] = SwitchPin(
                        id=pin.id,
                        name=port_map[key],
                        direction=pin.direction,
                    )

        # Nothing remapped, discard the new switchbox
        if not did_remap:
            continue

        # Update top-level pins
        update_switchbox_pins(new_switchbox)

        # Add to the switchbox types and the grid
        switchbox_types[new_switchbox.type] = new_switchbox
        switchbox_grid[loc] = new_switchbox.type


def specialize_switchboxes_with_wire_maps(
        switchbox_types, switchbox_grid, port_maps, wire_maps
):
    """
    Specializes switchboxes by applying wire mapping.
    """

    for loc, wire_map in wire_maps.items():

        # No switchbox at that location
        if loc not in switchbox_grid:
            continue

        # Get the switchbox type
        switchbox_type = switchbox_grid[loc]
        switchbox = switchbox_types[switchbox_type]

        # Make a copy of the switchbox
        suffix = "X{}Y{}".format(loc.x, loc.y)
        if not switchbox.type.endswith(suffix):
            new_type = "{}_{}".format(switchbox.type, suffix)
        else:
            new_type = switchbox_type
        new_switchbox = Switchbox(new_type)
        new_switchbox.stages = deepcopy(switchbox.stages)
        new_switchbox.connections = deepcopy(switchbox.connections)

        # Remap pin names
        did_remap = False
        for pin_loc, (wire_name, map_loc) in wire_map.items():

            # Get port map at the destination location of the wire that is
            # being remapped.
            assert map_loc in port_maps, (map_loc, wire_name)
            port_map = port_maps[map_loc]

            # Get the actual tile pin name
            key = (wire_name, PinDirection.INPUT)
            assert key in port_map, (map_loc, key)
            pin_name = port_map[key]

            # Append the hop to the wire name. Only if the map indicates that
            # the pin is connected.
            if pin_name is not None:
                hop = (
                    map_loc.x - loc.x,
                    map_loc.y - loc.y,
                )
                pin_name += "_{}".format(hop_to_str(hop))

            # Rename pin
            stage = new_switchbox.stages[pin_loc.stage_id]
            switch = stage.switches[pin_loc.switch_id]
            mux = switch.muxes[pin_loc.mux_id]
            pin = mux.inputs[pin_loc.pin_id]

            new_pin = SwitchPin(
                id=pin.id, direction=pin.direction, name=pin_name
            )

            mux.inputs[new_pin.id] = new_pin
            did_remap = True

        # Nothing remapped, discard the new switchbox
        if not did_remap:
            continue

        # Update top-level pins
        update_switchbox_pins(new_switchbox)

        # Add to the switchbox types and the grid
        switchbox_types[new_switchbox.type] = new_switchbox
        switchbox_grid[loc] = new_switchbox.type


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


def find_special_cells(tile_grid):
    """
    Finds cells that occupy more than one tilegrid location.
    """
    cells = {}

    # Assign each cell name its locations.
    for loc, tile in tile_grid.items():
        for cell_type, cell_names in tile.cell_names.items():
            for cell_name, in cell_names:

                # Skip LOGIC as it is always contained in a single tile
                if cell_name == "LOGIC":
                    continue

                if cell_name not in cells:
                    cells[cell_name] = {"type": cell_type, "locs": [loc]}
                else:
                    cells[cell_name]["locs"].append(loc)

    # Leave only those that have more than one location
    cells = {k: v for k, v in cells.items() if len(v["locs"]) > 1}


def parse_pinmap(xml_root, tile_grid):
    """
    Parses the "Package" section that holds IO pin to BIDIR/CLOCK cell map.

    Returns a dict indexed by package name which holds dicts indexed by logical
    pin names (eg. "FBIO_1"). Then, for each logical pin name there is a list
    of PackagePin objects.
    """
    pin_map = {}

    # Parse "PACKAGE" sections.
    for xml_package in xml_root.findall("PACKAGE"):

        # Initialize map
        pkg_name = xml_package.attrib["name"]
        pkg_pin_map = defaultdict(lambda: set())

        xml_pins = xml_package.find("Pins")
        assert xml_pins is not None

        # Parse pins
        for xml_pin in xml_pins.findall("Pin"):
            pin_name = xml_pin.attrib["name"]
            pin_alias = xml_pin.get("alias", None)
            cell_names = []
            cell_locs = []

            # Parse cells
            for xml_cell in xml_pin.findall("cell"):
                cell_name = xml_cell.attrib["name"]
                cell_loc = get_loc_of_cell(cell_name, tile_grid)
                if cell_loc is None:
                    continue
                cell_names.append(cell_name)
                cell_locs.append(cell_loc)

            # Location not found
            if not cell_locs:
                print(
                    "WARNING: No locs for package pin '{}' of package '{}'".
                    format(pin_name, pkg_name)
                )
                continue

            # Add the pin mapping
            for cell_name, cell_loc in zip(cell_names, cell_locs):

                # Find the cell
                if cell_loc not in tile_grid:
                    print(
                        "WARNING: No tile for package pin '{}' at '{}'".format(
                            pin_name, cell_loc
                        )
                    )
                    continue
                tile = tile_grid[cell_loc]

                cell = find_cell_in_tile(cell_name, tile)
                if cell is None:
                    print(
                        "WARNING: No cell in tile '{}' for package pin '{}' at '{}'"
                        .format(tile.name, pin_name, cell_loc)
                    )
                    continue

                # Store the mapping
                pkg_pin_map[pin_name].add(
                    PackagePin(
                        name=pin_name,
                        alias=pin_alias,
                        loc=cell_loc,
                        cell=cell
                    )
                )

                # Check if there is a CLOCK cell at the same location
                cells = [c for c in tile.cells if c.type == "CLOCK"]
                if len(cells):
                    assert len(cells) == 1, cells

                    # Store the mapping for the CLOCK cell
                    pkg_pin_map[pin_name].add(
                        PackagePin(
                            name=pin_name,
                            alias=pin_alias,
                            loc=cell_loc,
                            cell=cells[0]
                        )
                    )

            # Convert to list
            pkg_pin_map[pin_name] = list(pkg_pin_map[pin_name])

        # Convert to a regular dict
        pin_map[pkg_name] = dict(**pkg_pin_map)

    return pin_map


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


def import_data(xml_root):
    """
    Imports the Quicklogic FPGA tilegrid and routing data from the given
    XML tree
    """

    # Get the "Library" section
    xml_library = xml_root.find("Library")
    assert xml_library is not None

    # Import cells from the library
    cells = parse_library(xml_library)

    # Get the "Placement" section
    xml_placement = xml_root.find("Placement")
    assert xml_placement is not None

    cells_library = {cell.type: cell for cell in cells}
    quadrants, tile_types, tile_grid = parse_placement(
        xml_placement, cells_library
    )

    # Import global clock network definition
    xml_clock_network = xml_placement.find("CLOCK_NETWORK")
    assert xml_clock_network is not None

    clock_cells = parse_clock_network(xml_clock_network)

    # Get the "Routing" section
    xml_routing = xml_root.find("Routing")
    assert xml_routing is not None

    # Import switchboxes
    switchbox_grid = {}
    switchbox_types = {}
    for xml_node in xml_routing:

        # Not a switchbox
        if not xml_node.tag.endswith("_SBOX"):
            continue

        # Load all "variants" of the switchbox
        xml_common = xml_node.find("COMMON_STAGES")
        for xml_sbox in xml_node:
            if xml_sbox != xml_common:

                # Parse the switchbox definition
                switchbox = parse_switchbox(xml_sbox, xml_common)

                assert switchbox.type not in switchbox_types, switchbox.type
                switchbox_types[switchbox.type] = switchbox

                # Populate switchboxes onto the tilegrid
                populate_switchboxes(xml_sbox, switchbox_grid)

    # Get the "DeviceWireMappingTable" section
    xml_wiremap = xml_routing.find("DeviceWireMappingTable")

    if xml_wiremap is not None:
        # Import wire mapping
        wire_maps = parse_wire_mapping_table(
            xml_wiremap, switchbox_grid, switchbox_types
        )

    # Get the "DevicePortMappingTable" section
    xml_portmap = xml_routing.find("DevicePortMappingTable")
    assert xml_portmap is not None

    # Import switchbox port mapping
    port_maps = parse_port_mapping_table(xml_portmap, switchbox_grid)

    # Supply port mapping table with global clock mux map
    populate_clk_mux_port_maps(
        port_maps, clock_cells, tile_grid, cells_library
    )

    if xml_wiremap is not None:
        # Specialize switchboxes with wire maps
        specialize_switchboxes_with_wire_maps(
            switchbox_types, switchbox_grid, port_maps, wire_maps
        )

    # Specialize switchboxes with local port maps
    specialize_switchboxes_with_port_maps(
        switchbox_types, switchbox_grid, port_maps
    )

    # Remove switchbox types not present in the grid anymore due to their
    # specialization.
    for type in list(switchbox_types.keys()):
        if type not in switchbox_grid.values():
            del switchbox_types[type]

    # Get the "Packages" section
    xml_packages = xml_root.find("Packages")
    assert xml_packages is not None

    # Import BIDIR cell names to package pin mapping
    package_pinmaps = parse_pinmap(xml_packages, tile_grid)

    return {
        "quadrants": quadrants,
        "cells_library": cells_library,
        "tile_types": tile_types,
        "tile_grid": tile_grid,
        "switchbox_types": switchbox_types,
        "switchbox_grid": switchbox_grid,
        "clock_cells": clock_cells,
        "package_pinmaps": package_pinmaps
    }


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


def import_routing_timing(csv_file):
    """
    Reads and parses switchbox delay data from the CSV file. Returns a tree of
    dicts indexed by:
        [switchbox_type][stage_id][switch_id][mux_id][pin_id][num_inputs].

    The last dict holds tuples with rise and fall delays. Delay values are
    expressed in [ns].
    """

    # Read and parse CSV
    with open(csv_file, "r") as fp:

        # Read the first line, it should specify timing units
        line = fp.readline()
        line = line.strip().split(",")

        assert len(line) >= 3, line
        assert line[0] == "unit", line[0]

        # FIXME: For now support "ns" only
        assert line[2] == "ns", line[2]
        scale = 1.0  # Set the timing scale to 1ns

        # Read the rest of the timing data
        data = [r for r in csv.DictReader(fp)]

        # Try to guess whether the stage/switch/mux indexing starts from 0 or 1
        stage_ofs = min([int(t["Stage_Num"]) for t in data])
        switch_ofs = min([int(t["Switch_Num"]) for t in data])
        mux_ofs = min([int(t["Output_Num"]) for t in data])
        pin_ofs = min([int(t["Input_Num"]) for t in data])

        # Reformat
        switchbox_timings = {}
        for timing in data:

            # Switchbox type
            switchbox_type = timing["SBox_Type"]
            if switchbox_type not in switchbox_timings:
                switchbox_timings[switchbox_type] = {}

            # Stage id
            stage_timings = switchbox_timings[switchbox_type]
            stage_id = int(timing["Stage_Num"]) - stage_ofs
            if stage_id not in stage_timings:
                stage_timings[stage_id] = {}

            # Switch id
            switch_timings = stage_timings[stage_id]
            switch_id = int(timing["Switch_Num"]) - switch_ofs
            if switch_id not in switch_timings:
                switch_timings[switch_id] = {}

            # Mux id
            mux_timings = switch_timings[switch_id]
            mux_id = int(timing["Output_Num"]) - mux_ofs
            if mux_id not in mux_timings:
                mux_timings[mux_id] = {}

            # Mux route (edge), correspond to its input pin id.
            edge_timings = mux_timings[mux_id]
            pin_id = int(timing["Input_Num"]) - pin_ofs
            if pin_id not in edge_timings:
                edge_timings[pin_id] = {}

            # Load count and delays. Apply scaling so the timing is expressed
            # always is nanoseconds.
            edge_timing = edge_timings[pin_id]
            num_loads = int(timing["Num_Loads"])
            rise_delay = float(timing["Rise_Delay"]) * scale
            fall_delay = float(timing["Fall_Delay"]) * scale

            edge_timing[num_loads] = (rise_delay, fall_delay)

    return switchbox_timings


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


def main():

    # Parse arguments
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter
    )

    parser.add_argument(
        "--techfile",
        type=str,
        required=True,
        help="Quicklogic 'TechFile' XML file"
    )
    parser.add_argument(
        "--routing-timing",
        type=str,
        default=None,
        help="Quicklogic routing delay CSV file"
    )
    parser.add_argument(
        "--db",
        type=str,
        default="phy_database.pickle",
        help="Device name for the parsed 'database' file"
    )

    args = parser.parse_args()

    # Read and parse the XML techfile
    xml_tree = ET.parse(args.techfile)
    xml_techfile = xml_tree.getroot()

    # Load data from the techfile
    data = import_data(xml_techfile)

    # Build the connection map
    connections = build_connections(
        data["tile_types"],
        data["tile_grid"],
        data["switchbox_types"],
        data["switchbox_grid"],
        data["clock_cells"],
    )

    check_connections(connections)

    # Load timing data if given
    if args.routing_timing is not None:
        switchbox_timing = import_routing_timing(args.routing_timing)
    else:
        switchbox_timing = None

    # Prepare the database
    db_root = {
        "phy_quadrants": data["quadrants"],
        "cells_library": data["cells_library"],
        "tile_types": data["tile_types"],
        "phy_tile_grid": data["tile_grid"],
        "phy_clock_cells": data["clock_cells"],
        "switchbox_types": data["switchbox_types"],
        "switchbox_grid": data["switchbox_grid"],
        "connections": connections,
        "package_pinmaps": data["package_pinmaps"]
    }

    if switchbox_timing is not None:
        db_root["switchbox_timing"] = switchbox_timing

    # FIXME: Use something more platform-independent than pickle.
    with open(args.db, "wb") as fp:
        pickle.dump(db_root, fp, protocol=3)


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

if __name__ == "__main__":
    main()
