import argparse
import pickle
import re
from collections import defaultdict, namedtuple
import fasm

from connections import get_name_and_hop

from pathlib import Path
from data_structs import Loc, SwitchboxPinLoc, PinDirection, ConnectionType
from utils import get_quadrant_for_loc
from verilogmodule import VModule

from quicklogic_fasm.qlfasm import QL732BAssembler, load_quicklogic_database

Feature = namedtuple('Feature', 'loc typ signature value')
RouteEntry = namedtuple('RouteEntry', 'typ stage_id switch_id mux_id sel_id')
MultiLocCellMapping = namedtuple(
    'MultiLocCellMapping', 'typ fromlocset toloc pinnames'
)


class Fasm2Bels(object):
    '''Class for parsing FASM file and producing BEL representation.

    It takes FASM lines and VPR database and converts the data to Basic
    Elements and connections between them. It allows converting this data to
    Verilog.
    '''

    class Fasm2BelsException(Exception):
        '''Exception for Fasm2Bels errors and unsupported features.
        '''

        def __init__(self, message):
            self.message = message

        def __str__(self):
            return self.message

    def __init__(self, vpr_db, package_name):
        '''Prepares required structures for converting FASM to BELs.

        Parameters
        ----------
        vpr_db: dict
            A dictionary containing cell_library, loc_map, vpr_tile_types,
            vpr_tile_grid, vpr_switchbox_types, vpr_switchbox_grid,
            connections, vpr_package_pinmaps
        '''

        # load vpr_db data
        self.quadrants = vpr_db["phy_quadrants"]
        self.cells_library = vpr_db["cells_library"]
        self.vpr_tile_types = vpr_db["tile_types"]
        self.vpr_tile_grid = vpr_db["phy_tile_grid"]
        self.vpr_switchbox_types = vpr_db["switchbox_types"]
        self.vpr_switchbox_grid = vpr_db["switchbox_grid"]
        self.connections = vpr_db["connections"]
        self.package_name = package_name

        self.io_to_fbio = dict()

        for name, package in db['package_pinmaps'][self.package_name].items():
            self.io_to_fbio[package[0].loc] = name

        # Add ASSP to all locations it covers
        # TODO maybe this should be added in original vpr_tile_grid
        # set all cels in row 1 and column 2 to ASSP
        # In VPR grid, the ASSP tile is located in (1, 1)
        assplocs = set()
        ramlocs = dict()
        multlocs = dict()

        for phy_loc, tile in self.vpr_tile_grid.items():
            tile_type = self.vpr_tile_types[tile.type]
            if "ASSP" in tile_type.cells:
                assplocs.add(phy_loc)

            if "RAM" in tile_type.cells:
                ramcell = [cell for cell in tile.cells if cell.type == "RAM"]
                cellname = ramcell[0].name
                if cellname not in ramlocs:
                    ramlocs[cellname] = set()

                ramlocs[cellname].add(phy_loc)

            if "MULT" in tile_type.cells:
                multcell = [cell for cell in tile.cells if cell.type == "MULT"]
                cellname = multcell[0].name
                if cellname not in multlocs:
                    multlocs[cellname] = set()

                multlocs[cellname].add(phy_loc)

        # this map represents the mapping from input name to its inverter name
        self.inversionpins = {
            'LOGIC':
                {
                    'TA1': 'TAS1',
                    'TA2': 'TAS2',
                    'TB1': 'TBS1',
                    'TB2': 'TBS2',
                    'BA1': 'BAS1',
                    'BA2': 'BAS2',
                    'BB1': 'BBS1',
                    'BB2': 'BBS2',
                    'QCK': 'QCKS'
                }
        }

        # prepare helper structure for connections
        self.connections_by_loc = defaultdict(list)
        for connection in self.connections:
            self.connections_by_loc[connection.dst].append(connection)
            self.connections_by_loc[connection.src].append(connection)

        # a mapping from the type of cell FASM line refers to to its parser
        self.featureparsers = {
            'LOGIC': self.parse_logic_line,
            'QMUX': self.parse_logic_line,
            'GMUX': self.parse_logic_line,
            'INTERFACE': self.parse_interface_line,
            'ROUTING': self.parse_routing_line,
            'CAND0': self.parse_colclk_line,
            'CAND1': self.parse_colclk_line,
            'CAND2': self.parse_colclk_line,
            'CAND3': self.parse_colclk_line,
            'CAND4': self.parse_colclk_line,
        }

        # a mapping from cell type to a set of possible pin names
        self.pinnames = defaultdict(set)
        for celltype in self.cells_library.values():
            typ = celltype.type
            for pin in celltype.pins:
                self.pinnames[typ].add(pin.name)

        # a mapping from cell types that occupy multiple locations
        # to a single location
        self.multiloccells = {
            'ASSP':
                MultiLocCellMapping(
                    'ASSP', assplocs, Loc(1, 1, 0), self.pinnames['ASSP']
                )
        }
        for ram in ramlocs:
            self.multiloccells[ram] = MultiLocCellMapping(
                ram, ramlocs[ram],
                list(ramlocs[ram])[0], self.pinnames['RAM']
            )
        for mult in multlocs:
            self.multiloccells[mult] = MultiLocCellMapping(
                mult, multlocs[mult],
                list(multlocs[mult])[1], self.pinnames['MULT']
            )

        # helper routing data
        self.routingdata = defaultdict(list)
        # a dictionary holding bit settings for BELs
        self.belinversions = defaultdict(lambda: defaultdict(list))
        # a dictionary holding bit settings for IOs
        self.interfaces = defaultdict(lambda: defaultdict(list))
        # a dictionary holding simplified connections between BELs
        self.designconnections = defaultdict(dict)
        # a dictionary holding hops from routing
        self.designhops = defaultdict(dict)

        # Clock column drivers (CAND) data
        self.colclk_data = defaultdict(lambda: defaultdict(list))
        # A map of clock wires that connect to switchboxes
        self.cand_map = defaultdict(lambda: dict())

        # A map of original (loc, pin) to new (loc, pin). Created during
        # aggregation of multi-loc cells.
        self.org_loc_map = {}

    def parse_logic_line(self, feature: Feature):
        '''Parses a setting for a BEL.

        Parameters
        ----------
        feature: Feature
            FASM line for BEL
        '''
        belname, setting = feature.signature.split('.', 1)
        if feature.value == 1:
            # FIXME handle ZINV pins
            if 'ZINV.' in setting:
                setting = setting.replace('ZINV.', '')
            elif 'INV.' in setting:
                setting = setting.replace('INV.', '')
            self.belinversions[feature.loc][belname].append(setting)

    def parse_interface_line(self, feature: Feature):
        '''Parses a setting for IO.

        Parameters
        ----------
        feature: Feature
            FASM line for BEL
        '''
        belname, setting = feature.signature.split('.', 1)
        if feature.value == 1:
            setting = setting.replace('ZINV.', '')
            setting = setting.replace('INV.', '')
            self.interfaces[feature.loc][belname].append(setting)

    def parse_routing_line(self, feature: Feature):
        '''Parses a routing setting.

        Parameters
        ----------
        feature: Feature
            FASM line for BEL
        '''
        match = re.match(
            r'^I_highway\.IM(?P<switch_id>[0-9]+)\.I_pg(?P<sel_id>[0-9]+)$',
            feature.signature
        )
        if match:
            typ = 'HIGHWAY'
            stage_id = 3  # FIXME: Get HIGHWAY stage id from the switchbox def
            switch_id = int(match.group('switch_id'))
            mux_id = 0
            sel_id = int(match.group('sel_id'))
        match = re.match(
            r'^I_street\.Isb(?P<stage_id>[0-9])(?P<switch_id>[0-9])\.I_M(?P<mux_id>[0-9]+)\.I_pg(?P<sel_id>[0-9]+)$',  # noqa: E501
            feature.signature
        )
        if match:
            typ = 'STREET'
            stage_id = int(match.group('stage_id')) - 1
            switch_id = int(match.group('switch_id')) - 1
            mux_id = int(match.group('mux_id'))
            sel_id = int(match.group('sel_id'))
        self.routingdata[feature.loc].append(
            RouteEntry(
                typ=typ,
                stage_id=stage_id,
                switch_id=switch_id,
                mux_id=mux_id,
                sel_id=sel_id
            )
        )

    def parse_colclk_line(self, feature: Feature):
        self.colclk_data[feature.loc][feature.typ].append(feature)

    def parse_fasm_lines(self, fasmlines):
        '''Parses FASM lines.

        Parameters
        ----------
        fasmlines: list
            A list of FasmLine objects
        '''

        loctyp = re.compile(
            r'^X(?P<x>[0-9]+)Y(?P<y>[0-9]+)\.(?P<type>[A-Z]+[0-4]?)\.(?P<signature>.*)$'
        )  # noqa: E501

        for line in fasmlines:
            if not line.set_feature:
                continue
            match = loctyp.match(line.set_feature.feature)
            if not match:
                raise self.Fasm2BelsException(
                    f'FASM features have unsupported format:  {line.set_feature}'
                )  # noqa: E501
            loc = Loc(x=int(match.group('x')), y=int(match.group('y')), z=0)
            typ = match.group('type')
            feature = Feature(
                loc=loc,
                typ=typ,
                signature=match.group('signature'),
                value=line.set_feature.value
            )
            self.featureparsers[typ](feature)

    def decode_switchbox(self, switchbox, features):
        '''Decodes all switchboxes to extract full connections' info.

        For every output, this method determines its input in the routing
        switchboxes. In this representation, an input and output can be either
        directly connected to a BEL, or to a hop wire.

        Parameters
        ----------
        switchbox: a Switchbox object from vpr_switchbox_types
        features: features regarding given switchbox

        Returns
        -------
        dict: a mapping from output pin to input pin for a given switchbox
        '''
        # Group switchbox connections by destinationa
        conn_by_dst = defaultdict(set)
        for c in switchbox.connections:
            conn_by_dst[c.dst].add(c)

        # Prepare data structure
        mux_sel = {}
        for stage_id, stage in switchbox.stages.items():
            mux_sel[stage_id] = {}
            for switch_id, switch in stage.switches.items():
                mux_sel[stage_id][switch_id] = {}
                for mux_id, mux in switch.muxes.items():
                    mux_sel[stage_id][switch_id][mux_id] = None

        for feature in features:
            assert mux_sel[feature.stage_id][feature.switch_id][
                feature.mux_id] is None, feature  # noqa: E501
            mux_sel[feature.stage_id][feature.switch_id][
                feature.mux_id] = feature.sel_id  # noqa: E501

        def expand_mux(out_loc):
            """
            Expands a multiplexer output until a switchbox input is reached.
            Returns name of the input or None if not found.

            Parameters
            ----------
            out_loc: the last output location

            Returns
            -------
            str: None if input name not found, else string
            """

            # Get mux selection, If it is set to None then the mux is
            # not active
            sel = mux_sel[out_loc.stage_id][out_loc.switch_id][out_loc.mux_id]
            if sel is None:
                return None  # TODO can we return None?

            stage = switchbox.stages[out_loc.stage_id]
            switch = stage.switches[out_loc.switch_id]
            mux = switch.muxes[out_loc.mux_id]
            pin = mux.inputs[sel]

            if pin.name is not None:
                return pin.name

            inp_loc = SwitchboxPinLoc(
                stage_id=out_loc.stage_id,
                switch_id=out_loc.switch_id,
                mux_id=out_loc.mux_id,
                pin_id=sel,
                pin_direction=PinDirection.INPUT
            )

            # Expand all "upstream" muxes that connect to the selected
            # input pin
            assert inp_loc in conn_by_dst, inp_loc
            for c in conn_by_dst[inp_loc]:
                inp = expand_mux(c.src)
                if inp is not None:
                    return inp

            # Nothing found
            return None  # TODO can we return None?

        # For each output pin of a switchbox determine to which input is it
        # connected to.
        routes = {}
        for out_pin in switchbox.outputs.values():
            out_loc = out_pin.locs[0]
            routes[out_pin.name] = expand_mux(out_loc)

        return routes

    def process_switchbox(self, loc, switchbox, features):
        '''Processes all switchboxes and extract hops from connections.

        The function extracts final connections from inputs to outputs, and
        hops into separate structures for further processing.

        Parameters
        ----------
        loc: Loc
            location of the current switchbox
        switchbox: Switchbox
            a switchbox
        features: list
            list of features regarding given switchbox
        '''
        routes = self.decode_switchbox(switchbox, features)
        for k, v in routes.items():
            if v is not None:
                if re.match('[VH][0-9][LRBT][0-9]', k):
                    self.designhops[Loc(loc.x, loc.y, 0)][k] = v
                else:
                    self.designconnections[loc][k] = v

    def resolve_hops(self):
        '''Resolves remaining hop wires.

        It determines the absolute input for the given pin by resolving hop
        wires and adds those final connections to the design connections.
        '''
        for loc, conns in self.designconnections.items():
            for pin, source in conns.items():
                hop = get_name_and_hop(source)
                tloc = loc
                while hop[1] is not None:
                    tloc = Loc(tloc[0] + hop[1][0], tloc[1] + hop[1][1], 0)
                    # in some cases BEL is distanced from a switchbox, in those
                    # cases the hop will not point to another hop. We should
                    # simply return the pin here in the correct location
                    if hop[0] in self.designhops[tloc]:
                        hop = get_name_and_hop(self.designhops[tloc][hop[0]])
                    else:
                        hop = (hop[0], None)
                self.designconnections[loc][pin] = (tloc, hop[0])

    def resolve_connections(self):
        '''Resolves connections between BELs and IOs.
        '''
        keys = sorted(self.routingdata.keys(), key=lambda loc: (loc.x, loc.y))
        for loc in keys:
            routingfeatures = self.routingdata[loc]

            if loc in self.vpr_switchbox_grid:
                typ = self.vpr_switchbox_grid[loc]
                switchbox = self.vpr_switchbox_types[typ]
                self.process_switchbox(loc, switchbox, routingfeatures)
        self.resolve_hops()

    def remap_multiloc_loc(self, loc, pinname=None, celltype=None):
        '''Unifies coordinates of cells occupying multiple locations.

        Some cells, like ASSP, RAM or multipliers occupy multiple locations.
        This method groups bits and connections for those cells into a single
        artificial location.

        Parameters
        ----------
        loc: Loc
            The current location
        pinname: str
            The optional name of the pin (used to determine to which cell
            pin refers to)
        celltype: str
            The optional name of the cell type

        Returns
        -------
        Loc: the new location of the cell
        '''
        finloc = loc
        for multiloc in self.multiloccells.values():
            if pinname is None or pinname in multiloc.pinnames or celltype == multiloc.typ:
                if loc in multiloc.fromlocset:
                    finloc = multiloc.toloc
                    break
        return finloc

    def resolve_multiloc_cells(self):
        '''Groups cells that are scattered around multiple locations.
        '''
        newbelinversions = defaultdict(lambda: defaultdict(list))
        newdesignconnections = defaultdict(dict)

        for bellockey, bellocpair in self.belinversions.items():
            for belloctype, belloc in bellocpair.items():
                if belloctype in self.multiloccells:
                    newbelinversions[self.remap_multiloc_loc(
                        bellockey, celltype=belloctype
                    )][belloctype].extend(belloc)
        self.belinversion = newbelinversions

        for loc, conns in self.designconnections.items():
            for pin, src in conns.items():
                dstloc = self.remap_multiloc_loc(loc, pinname=pin)
                srcloc = self.remap_multiloc_loc(src[0], pinname=src[1])

                if srcloc != src[0]:
                    k, v = ((srcloc, src[1]), src)
                    if k in self.org_loc_map:
                        assert v == self.org_loc_map[k], (
                            k, self.org_loc_map[k], v
                        )
                    self.org_loc_map[k] = v

                if dstloc != loc:
                    k, v = ((dstloc, pin), (loc, pin))
                    if k in self.org_loc_map:
                        assert v == self.org_loc_map[k], (
                            k, self.org_loc_map[k], v
                        )
                    self.org_loc_map[k] = v

                newdesignconnections[dstloc][pin] = (srcloc, src[1])
        self.designconnections = newdesignconnections

    def get_clock_for_gmux(self, gmux, loc):
        '''Returns location of a CLOCK cell associated with the given GMUX
        cell. Returns None if not found

        Parameters
        ----------
        gmux: str
            The GMUX cell name
        loc: Loc
            The GMUX location

        Returns
        -------
        Loc: the new location of the cell or None
        '''

        connections = [
            c for c in self.connections if c.src.type == ConnectionType.TILE
            and c.dst.type == ConnectionType.TILE
        ]
        for connection in connections:

            # Only to a GMUX at the given location
            dst = connection.dst
            if dst.loc != loc or "GMUX" not in dst.pin:
                continue

            # GMUX cells are named "GMUX<index>".
            cell, pin = dst.pin.split("_", maxsplit=1)
            match = re.match(r"GMUX(?P<idx>[0-9]+)", cell)
            if match is None:
                continue

            # Not the cell that we are looking for
            if cell != gmux:
                continue

            # We are only interested in the IP connection
            if pin != "IP":
                continue

            # Must go from CLOCK<n>.IC pin
            cell, pin = connection.src.pin.split("_", maxsplit=1)
            if not cell.startswith("CLOCK") or pin != "IC":
                continue

            # Return the source location
            return connection.src.loc

        # Not found
        return None

    def get_gmux_for_qmux(self, qmux, loc):
        '''Returns a map of the given QMUX selection to driving GMUX cells.

        Parameters
        ----------
        qmux: str
            The QMUX cell name
        loc: Loc
            The QMUX location

        Returns
        -------
        Dict: A dict indexed by the selection index holding tuples with format:
            (loc, cell, pin)
        '''

        sel_map = {}

        connections = [
            c for c in self.connections if c.dst.type == ConnectionType.CLOCK
        ]
        for connection in connections:

            # Only to a QMUX at the given location
            dst = connection.dst
            if dst.loc != loc or "QMUX" not in dst.pin:
                continue

            # QMUX cells are named "QMUX_<quad><index>".
            cell, pin = dst.pin.split(".", maxsplit=1)
            match = re.match(r"QMUX_(?P<quad>[A-Z]+)(?P<idx>[0-9]+)", cell)
            if match is None:
                continue

            # This is not for the given QMUX
            qmux_idx = int(match.group("idx"))
            if qmux != "QMUX{}".format(qmux_idx):
                continue

            # Get the QCLKIN pin index. These are named "QCLKIN<index>"
            match = re.match(r"QCLKIN(?P<idx>[0-9]+)", pin)
            if match is None:
                continue
            qclkin_idx = int(match.group("idx"))

            # Get the source endpoint of the connection
            cell, pin = connection.src.pin.split("_", maxsplit=1)
            match = re.match(r"GMUX(?P<idx>[0-9]+)", cell)
            if match is None:
                continue
            gmux_idx = int(match.group("idx"))

            # Since fasm2bels uses physical database, it is not aware of
            # other QMUX inputs that QCLKIN0. Assume that the connection
            # found is to the QCLKIN0 pin and add QCLKIN1..2 to the map
            # as well.
            assert qclkin_idx == 0, connection

            # Make map entries
            for i in range(3):

                # Calculate GMUX index for QCLKIN<i> input of the QMUX
                idx = (gmux_idx + i) % 5

                # Add to the map
                sel_map[i] = (
                    connection.src.loc,
                    "GMUX{}".format(idx),
                    pin,
                )

        return sel_map

    def get_qmux_for_cand(self, cand, loc):
        ''' Returns a QMUX cell and its location that drives the given CAND
        cell.

        Parameters
        ----------
        cand: str
            The CAND cell name
        loc: Loc
            The CAND location

        Returns
        -------
        Tuple: A tuple holding (loc, cell)
        '''

        connections = [
            c for c in self.connections if c.dst.type == ConnectionType.CLOCK
        ]
        for connection in connections:

            # Only to a CAND at the given location
            # Note: Check also the row above. CAND cells are located in two
            # rows but with fasm features everything gets aligned to even rows
            dst = connection.dst
            if (dst.loc != loc and dst.loc != Loc(loc.x, loc.y - 1, loc.z)) or \
               "CAND" not in dst.pin:
                continue

            # CAND cells are named "CAND<index>_<quad>_<column>".
            cell, pin = dst.pin.split(".", maxsplit=1)
            match = re.match(
                r"CAND(?P<idx>[0-9]+)_(?P<quad>[A-Z]+)_(?P<col>[0-9]+)", cell
            )
            if match is None:
                continue

            # This is not for the given CAND
            if cand != "CAND{}".format(match.group("idx")):
                continue

            # QMUX cells are named "QMUX_<quad><index>".
            cell, pin = connection.src.pin.split(".", maxsplit=1)
            match = re.match(r"QMUX_(?P<quad>[A-Z]+)(?P<idx>[0-9]+)", cell)
            if match is None:
                continue

            # Return the QMUX and its location
            return "QMUX{}".format(match.group("idx")), connection.src.loc

        # None found
        return None, None

    def resolve_gmux(self):
        '''Resolves GMUX cells, updates the designconnections map. Also creates
        connections to CLOCK cells whenever necessary.

        Returns
        -------
        Dict: A map of GMUX names to their output wires
        '''

        # Process GMUX
        gmux_map = dict()
        gmux_locs = [
            loc for loc, tile in self.vpr_tile_grid.items()
            if "GMUX" in tile.type
        ]
        for loc in gmux_locs:

            # Group GMUX input pin connections by GMUX cell names
            gmux_connections = defaultdict(lambda: dict())
            for cell_pin, conn in self.designconnections[loc].items():
                if cell_pin.startswith("GMUX"):
                    cell, pin = cell_pin.split("_", maxsplit=1)
                    gmux_connections[cell][pin] = conn

            # Examine each GMUX config
            for gmux, connections in gmux_connections.items():

                # FIXME: Handle IS0 inversion (if any)

                # The IS0 pin has to be routed
                if "IS0" not in connections:
                    print(
                        "WARNING: Pin '{}.IS0' at '{}' is unrouted!".format(
                            gmux, loc
                        )
                    )
                    continue

                # TODO: For now support only static GMUX settings
                if connections["IS0"][1] not in ["GND", "VCC"]:
                    print(
                        "WARNING: Non-static GMUX selection (at '{}') not supported yet!"
                        .format(loc)
                    )
                    continue

                # Static selection
                sel = int(connections["IS0"][1] == "VCC")

                # IP selected
                if sel == 0:

                    # Create a global clock wire for the CLOCK pad
                    match = re.match(r"GMUX(?P<idx>[0-9]+)", gmux)
                    assert match is not None, gmux

                    idx = int(match.group("idx"))
                    wire = "CLK{}".format(idx)

                    # Get the clock pad location
                    clock_loc = self.get_clock_for_gmux(gmux, loc)
                    assert clock_loc is not None, gmux

                    # Check if the clock pad is enabled. If not then discard
                    # the GMUX
                    bel_features = []
                    for bel, features in self.interfaces.get(clock_loc,
                                                             {}).items():
                        for feature in features:
                            bel_features.append("{}.{}".format(bel, feature))

                    if "ASSP.ASSPInvPortAlias" not in bel_features:
                        continue

                    # Connect it to the output wire of the GMUX
                    self.designconnections[clock_loc]["CLOCK0_IC"] = (
                        None, wire
                    )

                    # The GMUX is implicit. Remove all connections to it
                    self.designconnections[loc] = {
                        k: v
                        for k, v in self.designconnections[loc].items()
                        if not k.startswith(gmux)
                    }

                # IC selected
                else:

                    # Check if the IC pin has an active driver. If not then
                    # discard the mux.
                    if connections.get("IC", (None, None))[1] in [None, "GND",
                                                                  "VCC"]:
                        continue

                    # Create a wire for the GMUX output
                    wire = "{}_X{}Y{}".format(gmux, loc.x, loc.y)

                    # Remove the IS0 connection
                    del self.designconnections[loc]["{}_IS0".format(gmux)]

                    # Connect the output
                    self.designconnections[loc]["{}_IZ".format(gmux)
                                                ] = (None, wire)

                # Store the wire
                gmux_map[gmux] = wire

        return gmux_map

    def resolve_qmux(self, gmux_map):
        '''Resolves QMUX cells, updates the designconnections map.

        Parameters
        ----------
        gmux_map: Dict
            A map of QMUX cells to their GMUX driving wires.

        Returns
        -------
        Dict: A map of locations and QMUX names to their driving wires
        '''

        # Process QMUX
        qmux_map = defaultdict(lambda: dict())
        qmux_locs = [
            loc for loc, tile in self.vpr_tile_grid.items()
            if "QMUX" in tile.type
        ]
        for loc in qmux_locs:

            # Group QMUX input pin connections by QMUX cell names
            qmux_connections = defaultdict(lambda: dict())
            for cell_pin, conn in self.designconnections[loc].items():
                if cell_pin.startswith("QMUX"):
                    cell, pin = cell_pin.split("_", maxsplit=1)
                    qmux_connections[cell][pin] = conn

            # Examine each QMUX config
            for qmux, connections in qmux_connections.items():

                # FIXME: Handle IS0 and IS1 inversion (if any)

                # Both IS0 and IS1 must be routed to something
                if "IS0" not in connections:
                    print(
                        "WARNING: Pin '{}.IS0' at '{}' is unrouted!".format(
                            qmux, loc
                        )
                    )
                if "IS1" not in connections:
                    print(
                        "WARNING: Pin '{}.IS1' at '{}' is unrouted!".format(
                            qmux, loc
                        )
                    )

                if "IS0" not in connections or "IS1" not in connections:
                    continue

                # TODO: For now support only static QMUX settings
                if connections["IS0"][1] not in ["GND", "VCC"]:
                    print(
                        "WARNING: Non-static QMUX selection (at '{}') not supported yet!"
                        .format(loc)
                    )
                    continue
                if connections["IS1"][1] not in ["GND", "VCC"]:
                    print(
                        "WARNING: Non-static QMUX selection (at '{}') not supported yet!"
                        .format(loc)
                    )
                    continue

                # Get associated GMUXes
                sel_map = self.get_gmux_for_qmux(qmux, loc)

                # Static selection
                sel = int(connections["IS0"][1] == "VCC"
                          ) * 2 + int(connections["IS1"][1] == "VCC")

                # Input from the routing network selected, create a new wire
                if sel == 3:

                    # Check if the HSCKIN input is connected to an active
                    # driver. If not then discard the QMUX
                    if connections.get("HSCKIN", (None, None))[1] in \
                       [None, "GND", "VCC"]:
                        continue

                    # Create a wire for the QMUX output
                    wire = "{}_X{}Y{}".format(qmux, loc.x, loc.y)

                    # Remove IS0 and IS1 from the connection map.
                    del self.designconnections[loc]["{}_IS0".format(qmux)]
                    del self.designconnections[loc]["{}_IS1".format(qmux)]

                    # Connect the output
                    self.designconnections[loc]["{}_IZ".format(qmux)
                                                ] = (None, wire)

                # Input from a GMUX is selected, assign its wire here
                else:

                    # The GMUX is not active. Discard the QMUX
                    gmux_loc, gmux_cell, gmux_pin = sel_map[sel]
                    if gmux_cell not in gmux_map:
                        continue

                    # Use the wire of that GMUX
                    wire = gmux_map[gmux_cell]

                    # The QMUX is implicit. Remove all connections to it
                    self.designconnections[loc] = {
                        k: v
                        for k, v in self.designconnections[loc].items()
                        if not k.startswith(qmux)
                    }

                # Store the wire
                qmux_map[loc][qmux] = wire

        return dict(qmux_map)

    def resolve_cand(self, qmux_map):
        '''Resolves CAND cells, creates the cand_map map.

        Parameters
        ----------
        qmux_map: Dict
            A map of locations and CAND names to their driving QMUXes.

        Returns
        -------
        None
        '''

        # Process CAND
        for loc, all_features in self.colclk_data.items():
            for cand, features in all_features.items():

                hilojoint = False
                enjoint = False

                for feature in features:
                    if feature.signature == "I_hilojoint":
                        hilojoint = bool(feature.value)
                    if feature.signature == "I_enjoint":
                        enjoint = bool(feature.value)

                # TODO: Do not support dynamically enabled CANDs for now.
                assert enjoint is False, "Dynamically enabled CANDs are not supported yet"

                # Statically disabled, skip this one
                if hilojoint is False:
                    continue

                # Find a QMUX driving this CAND cell
                qmux_cell, qmux_loc = self.get_qmux_for_cand(cand, loc)
                assert qmux_cell is not None, (cand, loc)

                # The QMUX is not active, skip this one
                if qmux_loc not in qmux_map:
                    continue

                # Get the wire
                wire = qmux_map[qmux_loc][qmux_cell]

                # Populate the column clock to switchbox connection map
                quadrant = get_quadrant_for_loc(loc, self.quadrants)
                for y in range(quadrant.y0, quadrant.y1 + 1):
                    sb_loc = Loc(loc.x, y, 0)
                    self.cand_map[sb_loc][cand] = wire

    def resolve_global_clock_network(self):
        '''Resolves the global clock network. Creates the cand_map, updates
        the designconnections.

        Returns
        -------
        None
        '''

        # Resolve GMUXes
        gmux_map = self.resolve_gmux()
        # Resolve QMUXes
        qmux_map = self.resolve_qmux(gmux_map)
        # Resolve CANDs
        self.resolve_cand(qmux_map)

    def produce_verilog(self, pcf_data):
        '''Produces string containing Verilog module representing FASM.

        Returns
        -------
        str, str: a Verilog module and PCF
        '''

        module = VModule(
            self.vpr_tile_grid, self.vpr_tile_types, self.cells_library,
            pcf_data, self.belinversions, self.interfaces,
            self.designconnections, self.org_loc_map, self.cand_map,
            self.inversionpins, self.io_to_fbio
        )
        module.parse_bels()
        verilog = module.generate_verilog()
        pcf = module.generate_pcf()
        qcf = module.generate_qcf()
        return verilog, pcf, qcf

    def convert_to_verilog(self, fasmlines):
        '''Runs all methods required to convert FASM lines to Verilog module.

        Parameters
        ----------
        fasmlines: list
            FASM lines to process

        Returns
        -------
        str: a Verilog module
        '''
        self.parse_fasm_lines(fasmlines)
        self.resolve_connections()
        self.resolve_multiloc_cells()
        self.resolve_global_clock_network()
        verilog, pcf, qcf = self.produce_verilog(pcf_data)
        return verilog, pcf, qcf


def parse_pcf(pcf):
    pcf_data = {}
    with open(pcf, 'r') as fp:
        for line in fp:
            line = line.strip().split()
            if len(line) < 3:
                continue
            if len(line) > 3 and not line[3].startswith("#"):
                continue
            if line[0] != 'set_io':
                continue
            pcf_data[line[2]] = line[1]
    return pcf_data


if __name__ == '__main__':
    # Parse arguments
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter
    )

    parser.add_argument("input_file", type=Path, help="Input fasm file")

    parser.add_argument(
        "--vpr-db", type=str, required=True, help="VPR database file"
    )

    parser.add_argument(
        "--package-name",
        type=str,
        required=True,
        choices=['PD64', 'PU64', 'WR42'],
        default='PD64',
        help="The package name"
    )

    parser.add_argument(
        "--input-type",
        type=str,
        choices=['bitstream', 'fasm'],
        default='fasm',
        help="Determines whether the input is a FASM file or bitstream"
    )

    parser.add_argument(
        "--output-verilog",
        type=Path,
        required=True,
        help="Output Verilog file"
    )
    parser.add_argument(
        "--input-pcf",
        type=Path,
        required=False,
        help="Pins constraint file to maintain original pin names"
    )

    parser.add_argument("--output-pcf", type=Path, help="Output PCF file")

    parser.add_argument("--output-qcf", type=Path, help="Output QCF file")

    args = parser.parse_args()

    pcf_data = {}

    if args.input_pcf is not None:
        pcf_data = parse_pcf(args.input_pcf)

    # Load data from the database
    with open(args.vpr_db, "rb") as fp:
        db = pickle.load(fp)

    f2b = Fasm2Bels(db, args.package_name)

    if args.input_type == 'bitstream':
        qlfasmdb = load_quicklogic_database()
        assembler = QL732BAssembler(qlfasmdb)
        assembler.read_bitstream(args.input_file)
        fasmlines = assembler.disassemble()
        fasmlines = [
            line for line in fasm.parse_fasm_string('\n'.join(fasmlines))
        ]
    else:
        fasmlines = [
            line for line in fasm.parse_fasm_filename(args.input_file)
        ]

    verilog, pcf, qcf = f2b.convert_to_verilog(fasmlines)

    with open(args.output_verilog, 'w') as outv:
        outv.write(verilog)
    if args.output_pcf:
        with open(args.output_pcf, 'w') as outpcf:
            outpcf.write(pcf)
    if args.output_qcf:
        with open(args.output_qcf, 'w') as outqcf:
            outqcf.write(qcf)
