def handle_edges_to_channels(conn, null_tile_wires, edge_assignments, channel_wires_to_tracks): c = conn.cursor() c.execute(""" SELECT vcc_track_pkey, gnd_track_pkey FROM constant_sources; """) vcc_track_pkey, gnd_track_pkey = c.fetchone() const_tracks = { 0: gnd_track_pkey, 1: vcc_track_pkey, } for node_pkey, classification in progressbar_utils.progressbar( c.execute( """ SELECT pkey, classification FROM node WHERE classification != ?; """, (NodeClassification.CHANNEL.value, ))): reason = NodeClassification(classification) if reason == NodeClassification.NULL: for (tile_type, wire) in yield_logical_wire_info_from_node(conn, node_pkey): null_tile_wires.add((tile_type, wire)) if reason != NodeClassification.EDGES_TO_CHANNEL: continue c2 = conn.cursor() for wire_pkey, phy_tile_pkey, tile_pkey, wire_in_tile_pkey in c2.execute( """ SELECT pkey, phy_tile_pkey, tile_pkey, wire_in_tile_pkey FROM wire WHERE node_pkey = ?; """, (node_pkey, )): c3 = conn.cursor() c3.execute(""" SELECT grid_x, grid_y FROM tile WHERE pkey = ?;""", (tile_pkey, )) (grid_x, grid_y) = c3.fetchone() c3.execute( """ SELECT name FROM tile_type WHERE pkey = ( SELECT tile_type_pkey FROM tile WHERE pkey = ? ); """, (tile_pkey, )) (tile_type, ) = c3.fetchone() wire = get_pin_name_of_wire(conn, wire_pkey) if wire is None: # This node has no site pin, don't need to assign pin direction. continue for other_phy_tile_pkey, other_wire_in_tile_pkey, pip_pkey, pip in c3.execute( """ WITH wires_from_node(wire_in_tile_pkey, phy_tile_pkey) AS ( SELECT wire_in_tile_pkey, phy_tile_pkey FROM wire WHERE node_pkey = ? AND phy_tile_pkey IS NOT NULL ), other_wires(other_phy_tile_pkey, pip_pkey, other_wire_in_tile_pkey) AS ( SELECT wires_from_node.phy_tile_pkey, undirected_pips.pip_in_tile_pkey, undirected_pips.other_wire_in_tile_pkey FROM undirected_pips INNER JOIN wires_from_node ON undirected_pips.wire_in_tile_pkey = wires_from_node.wire_in_tile_pkey) SELECT other_wires.other_phy_tile_pkey, other_wires.other_wire_in_tile_pkey, pip_in_tile.pkey, pip_in_tile.name FROM other_wires INNER JOIN pip_in_tile ON pip_in_tile.pkey == other_wires.pip_pkey WHERE pip_in_tile.is_directional = 1 AND pip_in_tile.is_pseudo = 0; """, (node_pkey, )): # Need to walk from the wire_in_tile table, to the wire table, # to the node table and get track_pkey. # other_wire_in_tile_pkey -> wire pkey -> node_pkey -> track_pkey c4 = conn.cursor() c4.execute( """ SELECT track_pkey, classification FROM node WHERE pkey = ( SELECT node_pkey FROM wire WHERE phy_tile_pkey = ? AND wire_in_tile_pkey = ? );""", (other_phy_tile_pkey, other_wire_in_tile_pkey)) result = c4.fetchone() assert result is not None, (wire_pkey, pip_pkey, tile_pkey, wire_in_tile_pkey, other_wire_in_tile_pkey) (track_pkey, classification) = result # Some pips do connect to a track at all, e.g. null node if track_pkey is None: # TODO: Handle weird connections. #other_node_class = NodeClassification(classification) #assert other_node_class == NodeClassification.NULL, ( # node_pkey, pip_pkey, pip, other_node_class) continue tracks_model = channel_wires_to_tracks[track_pkey] available_pins = set( tracks_model.get_tracks_for_wire_at_coord( (grid_x, grid_y)).keys()) edge_assignments[(tile_type, wire)].append(available_pins) for constant in yield_ties_to_wire(wire): tracks_model = channel_wires_to_tracks[ const_tracks[constant]] available_pins = set( tracks_model.get_tracks_for_wire_at_coord( (grid_x, grid_y)).keys()) edge_assignments[(tile_type, wire)].append(available_pins)
def handle_direction_connections(conn, direct_connections, edge_assignments): # Edges with mux should have one source tile and one destination_tile. # The pin from the source_tile should face the destination_tile. # # It is expected that all edges_with_mux will lies in a line (e.g. X only or # Y only). c = conn.cursor() for src_wire_pkey, dest_wire_pkey, pip_in_tile_pkey, switch_pkey in progressbar_utils.progressbar( c.execute(""" SELECT src_wire_pkey, dest_wire_pkey, pip_in_tile_pkey, switch_pkey FROM edge_with_mux;""" )): c2 = conn.cursor() # Get the node that is attached to the source. c2.execute(""" SELECT node_pkey FROM wire WHERE pkey = ?""", (src_wire_pkey, )) (src_node_pkey, ) = c2.fetchone() # Find the wire connected to the source. src_wire = list(node_to_site_pins(conn, src_node_pkey)) assert len(src_wire) == 1 source_wire_pkey, src_tile_pkey, src_wire_in_tile_pkey = src_wire[0] c2.execute( """ SELECT tile_type_pkey, grid_x, grid_y FROM tile WHERE pkey = ?""", (src_tile_pkey, )) src_tile_type_pkey, source_loc_grid_x, source_loc_grid_y = c2.fetchone( ) c2.execute(""" SELECT name FROM tile_type WHERE pkey = ?""", (src_tile_type_pkey, )) (source_tile_type, ) = c2.fetchone() source_wire = get_pin_name_of_wire(conn, source_wire_pkey) # Get the node that is attached to the sink. c2.execute(""" SELECT node_pkey FROM wire WHERE pkey = ?""", (dest_wire_pkey, )) (dest_node_pkey, ) = c2.fetchone() # Find the wire connected to the sink. dest_wire = list(node_to_site_pins(conn, dest_node_pkey)) assert len(dest_wire) == 1 destination_wire_pkey, dest_tile_pkey, dest_wire_in_tile_pkey = dest_wire[ 0] c2.execute( """ SELECT tile_type_pkey, grid_x, grid_y FROM tile WHERE pkey = ?;""", (dest_tile_pkey, )) dest_tile_type_pkey, destination_loc_grid_x, destination_loc_grid_y = c2.fetchone( ) c2.execute(""" SELECT name FROM tile_type WHERE pkey = ?""", (dest_tile_type_pkey, )) (destination_tile_type, ) = c2.fetchone() destination_wire = get_pin_name_of_wire(conn, destination_wire_pkey) c2.execute("SELECT name FROM switch WHERE pkey = ?" "", (switch_pkey, )) switch_name = c2.fetchone()[0] direct_connections.add( DirectConnection( from_pin='{}.{}'.format(source_tile_type, source_wire), to_pin='{}.{}'.format(destination_tile_type, destination_wire), switch_name=switch_name, x_offset=destination_loc_grid_x - source_loc_grid_x, y_offset=destination_loc_grid_y - source_loc_grid_y, )) if destination_loc_grid_x == source_loc_grid_x: if destination_loc_grid_y > source_loc_grid_y: source_dir = tracks.Direction.TOP destination_dir = tracks.Direction.BOTTOM else: source_dir = tracks.Direction.BOTTOM destination_dir = tracks.Direction.TOP else: if destination_loc_grid_x > source_loc_grid_x: source_dir = tracks.Direction.RIGHT destination_dir = tracks.Direction.LEFT else: source_dir = tracks.Direction.LEFT destination_dir = tracks.Direction.RIGHT edge_assignments[(source_tile_type, source_wire)].append( (source_dir, )) edge_assignments[(destination_tile_type, destination_wire)].append( (destination_dir, ))
def handle_edges_to_channels(conn, null_tile_wires, edge_assignments, channel_wires_to_tracks): c = conn.cursor() c.execute(""" SELECT vcc_track_pkey, gnd_track_pkey FROM constant_sources; """) vcc_track_pkey, gnd_track_pkey = c.fetchone() const_tracks = { 0: gnd_track_pkey, 1: vcc_track_pkey, } for node_pkey, classification in progressbar.progressbar( c.execute( """ SELECT pkey, classification FROM node WHERE classification != ?; """, (NodeClassification.CHANNEL.value, ))): reason = NodeClassification(classification) if reason == NodeClassification.NULL: for (tile_type, wire) in yield_wire_info_from_node(conn, node_pkey): null_tile_wires.add((tile_type, wire)) if reason != NodeClassification.EDGES_TO_CHANNEL: continue c2 = conn.cursor() for wire_pkey, tile_pkey, wire_in_tile_pkey in c2.execute( """ SELECT pkey, tile_pkey, wire_in_tile_pkey FROM wire WHERE node_pkey = ?; """, (node_pkey, )): c3 = conn.cursor() c3.execute(""" SELECT grid_x, grid_y FROM tile WHERE pkey = ?;""", (tile_pkey, )) (grid_x, grid_y) = c3.fetchone() c3.execute( """ SELECT name FROM tile_type WHERE pkey = ( SELECT tile_type_pkey FROM tile WHERE pkey = ? ); """, (tile_pkey, )) (tile_type, ) = c3.fetchone() wire = get_pin_name_of_wire(conn, wire_pkey) if wire is None: # This node has no site pin, don't need to assign pin direction. continue for pip_pkey, pip, src_wire_in_tile_pkey, dest_wire_in_tile_pkey in c3.execute( """ SELECT pkey, name, src_wire_in_tile_pkey, dest_wire_in_tile_pkey FROM pip_in_tile WHERE is_directional = 1 AND is_pseudo = 0 AND ( src_wire_in_tile_pkey = ? OR dest_wire_in_tile_pkey = ?);""", (wire_in_tile_pkey, wire_in_tile_pkey)): assert (src_wire_in_tile_pkey == wire_in_tile_pkey or dest_wire_in_tile_pkey == wire_in_tile_pkey), pip if src_wire_in_tile_pkey == wire_in_tile_pkey: other_wire_in_tile_pkey = dest_wire_in_tile_pkey else: other_wire_in_tile_pkey = src_wire_in_tile_pkey # Need to walk from the wire_in_tile table, to the wire table, # to the node table and get track_pkey. # other_wire_in_tile_pkey -> wire pkey -> node_pkey -> track_pkey c4 = conn.cursor() c4.execute( """ SELECT track_pkey, classification FROM node WHERE pkey = ( SELECT node_pkey FROM wire WHERE tile_pkey = ? AND wire_in_tile_pkey = ? );""", (tile_pkey, other_wire_in_tile_pkey)) result = c4.fetchone() assert result is not None, (wire_pkey, pip_pkey, tile_pkey, wire_in_tile_pkey, other_wire_in_tile_pkey) (track_pkey, classification) = result # Some pips do connect to a track at all, e.g. null node if track_pkey is None: # TODO: Handle weird connections. #other_node_class = NodeClassification(classification) #assert other_node_class == NodeClassification.NULL, ( # node_pkey, pip_pkey, pip, other_node_class) continue tracks_model = channel_wires_to_tracks[track_pkey] available_pins = set( pin_dir for _, pin_dir in tracks_model.get_tracks_for_wire_at_coord((grid_x, grid_y))) edge_assignments[(tile_type, wire)].append(available_pins) for constant in yield_ties_to_wire(wire): tracks_model = channel_wires_to_tracks[ const_tracks[constant]] available_pins = set( pin_dir for _, pin_dir in tracks_model.get_tracks_for_wire_at_coord((grid_x, grid_y))) edge_assignments[(tile_type, wire)].append(available_pins)