def get_phy_tiles(conn, tile_pkey):
    """ Returns the locations of all physical tiles for specified tile. """
    c = conn.cursor()
    c2 = conn.cursor()

    phy_locs = []
    for (phy_tile_pkey, ) in c.execute(
            "SELECT phy_tile_pkey FROM tile_map WHERE tile_pkey = ?",
        (tile_pkey, )):
        c2.execute("SELECT grid_x, grid_y FROM phy_tile WHERE pkey = ?",
                   (phy_tile_pkey, ))
        loc = c2.fetchone()
        phy_locs.append(grid_types.GridLoc(*loc))

    return phy_locs
def make_connection(conn, input_only_nodes, output_only_nodes, find_wire,
                    find_pip, find_connector, tile_name, tile_type, pip,
                    delayless_switch_pkey, const_connectors):
    """ Attempt to connect graph nodes on either side of a pip.

    Args:
        input_only_nodes (set of node_pkey): Nodes that can only be used as
            sinks. This is because a synthetic tile will use this node as a
            source.
        output_only_nodes (set of node_pkey): Nodes that can only be used as
            sources. This is because a synthetic tile will use this node as a
            sink.
        find_wire (function): Return value from create_find_wire.
        find_pip (function): Return value from create_find_pip.
        find_connector (function): Return value from create_find_connector.
        tile_name (str): Name of tile pip belongs too.
        pip (prjxray.tile.Pip): Pip being connected.
        switch_pkey (int): Primary key to switch table of switch to be used
            in this connection.

    Returns:
        None if connection cannot be made, otherwise returns tuple of:
            src_graph_node_pkey (int) - Primary key into graph_node table of
                source.
            dest_graph_node_pkey (int) - Primary key into graph_node table of
                destination.
            switch_pkey (int) - Primary key into switch table of switch used
                in connection.
            phy_tile_pkey (int) - Primary key into table of parent physical
                tile of the pip.
            pip_pkey (int) - Primary key into pip_in_tile table for this pip.

    """

    src_wire_pkey, tile_pkey, phy_tile_pkey, src_node_pkey = find_wire(
        tile_name, tile_type, pip.net_from)
    sink_wire_pkey, tile_pkey2, phy_tile_pkey2, sink_node_pkey = find_wire(
        tile_name, tile_type, pip.net_to)

    assert phy_tile_pkey == phy_tile_pkey2
    assert tile_pkey == tile_pkey2

    c = conn.cursor()
    c.execute("SELECT grid_x, grid_y FROM tile WHERE pkey = ?", (tile_pkey, ))
    loc = grid_types.GridLoc(*c.fetchone())

    # Skip nodes that are reserved because of ROI
    if src_node_pkey in input_only_nodes:
        return

    if sink_node_pkey in output_only_nodes:
        return

    src_connector = find_connector(src_wire_pkey, src_node_pkey)
    if src_connector is None:
        return

    sink_connector = find_connector(sink_wire_pkey, sink_node_pkey)
    if sink_connector is None:
        return

    pip_pkey, pip_is_directional, pip_is_pseudo, pip_can_invert = \
        find_pip(tile_type, pip.name)

    assert not pip_is_pseudo

    for src_graph_node_pkey, switch_pkey, dest_graph_node_pkey in src_connector.connect_at(
            pip_pkey=pip_pkey,
            src_wire_pkey=src_wire_pkey,
            dest_wire_pkey=sink_wire_pkey,
            loc=loc,
            other_connector=sink_connector):
        yield (src_graph_node_pkey, dest_graph_node_pkey, switch_pkey,
               phy_tile_pkey, pip_pkey, False)

    if not pip_is_directional:
        for src_graph_node_pkey, switch_pkey, dest_graph_node_pkey in sink_connector.connect_at(
                pip_pkey=pip_pkey,
                src_wire_pkey=sink_wire_pkey,
                dest_wire_pkey=src_wire_pkey,
                loc=loc,
                other_connector=src_connector):
            yield (src_graph_node_pkey, dest_graph_node_pkey, switch_pkey,
                   phy_tile_pkey, pip_pkey, True)

    # Make additional connections to constant network if the sink needs it.
    for constant_src in yield_ties_to_wire(pip.net_to):
        for src_graph_node_pkey, switch_pkey, dest_graph_node_pkey in const_connectors[
                constant_src].connect_at(switch_pkey=delayless_switch_pkey,
                                         loc=loc,
                                         other_connector=sink_connector):
            yield (src_graph_node_pkey, dest_graph_node_pkey, switch_pkey,
                   phy_tile_pkey, None, False)