Beispiel #1
0
def yield_nodes(nodes):
    with progressbar_utils.ProgressBar(max_value=len(nodes)) as bar:
        for idx, node in enumerate(nodes):
            yield node

            if idx % 1024 == 0:
                bar.update(idx)
Beispiel #2
0
def import_graph_edges(conn, graph, node_mapping):
    # First yield existing edges
    print('{} Importing existing edges.'.format(now()))
    for edge in graph.edges:
        yield (edge.src_node, edge.sink_node, edge.switch_id, None)

    # Then yield edges from database.
    cur = conn.cursor()

    cur.execute("SELECT count() FROM graph_edge;" "")
    (num_edges, ) = cur.fetchone()

    get_tile_name = create_get_tile_name(conn)
    get_pip_wire_names = create_get_pip_wire_names(conn)

    switch_name_map = {}

    print('{} Importing edges from database.'.format(now()))
    with progressbar_utils.ProgressBar(max_value=num_edges) as bar:
        for idx, (src_graph_node, dest_graph_node, switch_pkey, phy_tile_pkey,
                  pip_pkey, backward) in enumerate(
                      cur.execute("""
SELECT
  src_graph_node_pkey,
  dest_graph_node_pkey,
  switch_pkey,
  phy_tile_pkey,
  pip_in_tile_pkey,
  backward
FROM
  graph_edge;
                """)):
            if src_graph_node not in node_mapping:
                continue

            if dest_graph_node not in node_mapping:
                continue

            if pip_pkey is not None:
                tile_name = get_tile_name(phy_tile_pkey)
                src_net, dest_net = get_pip_wire_names(pip_pkey)

                if not backward:
                    pip_name = '{}.{}.{}'.format(tile_name, dest_net, src_net)
                else:
                    pip_name = '{}.{}.{}'.format(tile_name, src_net, dest_net)
            else:
                pip_name = None

            switch_id = get_switch_name(conn, graph, switch_name_map,
                                        switch_pkey)

            src_node = node_mapping[src_graph_node]
            sink_node = node_mapping[dest_graph_node]

            if pip_name is not None:
                yield (src_node, sink_node, switch_id,
                       (('fasm_features', check_feature(pip_name)), ))
            else:
                yield (src_node, sink_node, switch_id, ())

            if idx % 1024 == 0:
                bar.update(idx)
Beispiel #3
0
def classify_nodes(conn, get_switch_timing):
    write_cur = conn.cursor()

    # Nodes are NULL if they they only have either a site pin or 1 pip, but
    # nothing else.
    write_cur.execute(
        """
UPDATE node SET classification = ?
    WHERE (node.site_wire_pkey IS NULL AND node.number_pips <= 1) OR
          (node.site_wire_pkey IS NOT NULL AND node.number_pips == 0)
    ;""", (NodeClassification.NULL.value, ))
    write_cur.execute(
        """
UPDATE node SET classification = ?
    WHERE node.number_pips > 1 and node.site_wire_pkey IS NULL;""",
        (NodeClassification.CHANNEL.value, ))
    write_cur.execute(
        """
UPDATE node SET classification = ?
    WHERE node.number_pips > 1 and node.site_wire_pkey IS NOT NULL;""",
        (NodeClassification.EDGES_TO_CHANNEL.value, ))

    null_nodes = []
    edges_to_channel = []
    edge_with_mux = []

    cur = conn.cursor()
    cur.execute("""
SELECT
  count(pkey)
FROM
  node
WHERE
  number_pips == 1
  AND site_wire_pkey IS NOT NULL;""")
    num_nodes = cur.fetchone()[0]
    with progressbar_utils.ProgressBar(max_value=num_nodes) as bar:
        bar.update(0)
        for idx, (node, site_wire_pkey) in enumerate(
                cur.execute("""
SELECT
  pkey,
  site_wire_pkey
FROM
  node
WHERE
  number_pips == 1
  AND site_wire_pkey IS NOT NULL;""")):
            bar.update(idx)

            write_cur.execute(
                """
WITH wire_in_node(
  wire_pkey, phy_tile_pkey, wire_in_tile_pkey
) AS (
  SELECT
    wire.pkey,
    wire.phy_tile_pkey,
    wire.wire_in_tile_pkey
  FROM
    wire
  WHERE
    wire.node_pkey = ?
)
SELECT
  pip_in_tile.pkey,
  pip_in_tile.src_wire_in_tile_pkey,
  pip_in_tile.dest_wire_in_tile_pkey,
  wire_in_node.wire_pkey,
  wire_in_node.wire_in_tile_pkey,
  wire_in_node.phy_tile_pkey
FROM
  wire_in_node
  INNER JOIN pip_in_tile
WHERE
  pip_in_tile.is_pseudo = 0 AND (
  pip_in_tile.src_wire_in_tile_pkey = wire_in_node.wire_in_tile_pkey
  OR pip_in_tile.dest_wire_in_tile_pkey = wire_in_node.wire_in_tile_pkey)
LIMIT
  1;
""", (node, ))

            (pip_pkey, src_wire_in_tile_pkey, dest_wire_in_tile_pkey,
             wire_in_node_pkey, wire_in_tile_pkey,
             phy_tile_pkey) = write_cur.fetchone()
            assert write_cur.fetchone() is None, node

            assert (wire_in_tile_pkey == src_wire_in_tile_pkey
                    or wire_in_tile_pkey
                    == dest_wire_in_tile_pkey), (wire_in_tile_pkey, pip_pkey)

            if src_wire_in_tile_pkey == wire_in_tile_pkey:
                other_wire = dest_wire_in_tile_pkey
            else:
                other_wire = src_wire_in_tile_pkey

            write_cur.execute(
                """
            SELECT node_pkey FROM wire WHERE
                wire_in_tile_pkey = ? AND
                phy_tile_pkey = ?;
                """, (other_wire, phy_tile_pkey))

            (other_node_pkey, ) = write_cur.fetchone()
            assert write_cur.fetchone() is None
            assert other_node_pkey is not None, (other_wire, phy_tile_pkey)

            write_cur.execute(
                """
            SELECT site_wire_pkey, number_pips
                FROM node WHERE pkey = ?;
                """, (other_node_pkey, ))

            result = write_cur.fetchone()
            assert result is not None, other_node_pkey
            other_site_wire_pkey, other_number_pips = result
            assert write_cur.fetchone() is None

            if other_site_wire_pkey is not None and other_number_pips == 1:
                if src_wire_in_tile_pkey == wire_in_tile_pkey:
                    src_wire_pkey = site_wire_pkey
                    dest_wire_pkey = other_site_wire_pkey
                else:
                    src_wire_pkey = other_site_wire_pkey
                    dest_wire_pkey = site_wire_pkey

                edge_with_mux.append(((node, other_node_pkey), src_wire_pkey,
                                      dest_wire_pkey, pip_pkey))
            elif other_site_wire_pkey is None and other_number_pips == 1:
                null_nodes.append(node)
                null_nodes.append(other_node_pkey)
                pass
            else:
                edges_to_channel.append(node)

    for nodes, src_wire_pkey, dest_wire_pkey, pip_pkey in progressbar_utils.progressbar(
            edge_with_mux):
        assert len(nodes) == 2

        switch_pkey = check_edge_with_mux_timing(conn, get_switch_timing,
                                                 src_wire_pkey, dest_wire_pkey,
                                                 pip_pkey)
        write_cur.execute(
            """
        UPDATE node SET classification = ?
            WHERE pkey IN (?, ?);""",
            (NodeClassification.EDGE_WITH_MUX.value, nodes[0], nodes[1]))

        write_cur.execute(
            """
INSERT INTO edge_with_mux(src_wire_pkey, dest_wire_pkey, pip_in_tile_pkey, switch_pkey)
VALUES
  (?, ?, ?, ?);""", (src_wire_pkey, dest_wire_pkey, pip_pkey, switch_pkey))

    for node in progressbar_utils.progressbar(edges_to_channel):
        write_cur.execute(
            """
        UPDATE node SET classification = ?
            WHERE pkey = ?;""", (
                NodeClassification.EDGES_TO_CHANNEL.value,
                node,
            ))

    for null_node in progressbar_utils.progressbar(null_nodes):
        write_cur.execute(
            """
        UPDATE node SET classification = ?
            WHERE pkey = ?;""", (
                NodeClassification.NULL.value,
                null_node,
            ))

    write_cur.execute("CREATE INDEX node_type_index ON node(classification);")
    write_cur.connection.commit()
Beispiel #4
0
def import_graph_edges(conn, graph, extra_features, node_mapping):
    # First yield existing edges
    print('{} Importing existing edges.'.format(now()))
    for edge in graph.edges:
        yield (edge.src_node, edge.sink_node, edge.switch_id, None)

    # Then yield edges from database.
    cur = conn.cursor()

    cur.execute("SELECT count() FROM graph_edge;" "")
    (num_edges, ) = cur.fetchone()

    get_tile_name = create_get_tile_name(conn)
    get_pip_wire_names = create_get_pip_wire_names(conn)

    switch_name_map = {}

    nodes_set = set()

    print('{} Importing edges from database.'.format(now()))
    with progressbar_utils.ProgressBar(max_value=num_edges) as bar:
        for idx, (src_graph_node, dest_graph_node, switch_pkey, phy_tile_pkey,
                  pip_pkey, backward) in enumerate(
                      cur.execute("""
SELECT
  src_graph_node_pkey,
  dest_graph_node_pkey,
  switch_pkey,
  phy_tile_pkey,
  pip_in_tile_pkey,
  backward
FROM
  graph_edge;
                """)):
            if src_graph_node not in node_mapping:
                continue

            if dest_graph_node not in node_mapping:
                continue

            src_node, src_node_type = node_mapping[src_graph_node]
            sink_node, sink_node_type = node_mapping[dest_graph_node]

            pin_node_types = [graph2.NodeType.IPIN, graph2.NodeType.OPIN]

            src_node_is_site_pin = src_node_type in pin_node_types
            sink_node_is_site_pin = sink_node_type in pin_node_types

            # It may happen that a same CHAN <-> PIN edge is generated and this is unaccepted
            # by VPR, as it allows only multiple edges between CHAN nodes.
            # If a src_node, sink_node CHAN <-> PIN pair has already an edge, no new edge gets
            # added
            if src_node_is_site_pin ^ sink_node_is_site_pin:
                if (src_node, sink_node) in nodes_set:
                    continue
                else:
                    nodes_set.add((src_node, sink_node))

            if pip_pkey is not None:
                tile_name = get_tile_name(phy_tile_pkey)
                src_net, dest_net = get_pip_wire_names(pip_pkey)

                if not backward:
                    pip_name = '{}.{}.{}'.format(tile_name, dest_net, src_net)
                else:
                    pip_name = '{}.{}.{}'.format(tile_name, src_net, dest_net)
            else:
                pip_name = None

            switch_id = get_switch_name(conn, graph, switch_name_map,
                                        switch_pkey)

            if pip_name is not None:
                feature = check_feature(extra_features, pip_name)
                if feature:
                    yield (src_node, sink_node, switch_id, (('fasm_features',
                                                             feature), ))
                else:
                    yield (src_node, sink_node, switch_id, ())
            else:
                yield (src_node, sink_node, switch_id, ())

            if idx % 1024 == 0:
                bar.update(idx)
Beispiel #5
0
def form_tracks(conn):
    cur = conn.cursor()

    cur.execute('SELECT count(pkey) FROM node WHERE classification == ?;',
                (NodeClassification.CHANNEL.value, ))
    num_nodes = cur.fetchone()[0]

    tracks_to_insert = []
    with progressbar_utils.ProgressBar(max_value=num_nodes) as bar:
        bar.update(0)
        cur2 = conn.cursor()
        for idx, (node, ) in enumerate(
                cur.execute(
                    """
SELECT pkey FROM node WHERE classification == ?;
""", (NodeClassification.CHANNEL.value, ))):
            bar.update(idx)

            unique_pos = set()
            for wire_pkey, grid_x, grid_y in cur2.execute(
                    """
WITH wires_from_node(wire_pkey, tile_pkey) AS (
  SELECT
    pkey,
    tile_pkey
  FROM
    wire
  WHERE
    node_pkey = ? AND tile_pkey IS NOT NULL
)
SELECT
  wires_from_node.wire_pkey,
  tile.grid_x,
  tile.grid_y
FROM
  tile
  INNER JOIN wires_from_node ON tile.pkey = wires_from_node.tile_pkey;
  """, (node, )):
                unique_pos.add((grid_x, grid_y))

            tracks_to_insert.append(create_track(node, unique_pos))

    # Create constant tracks
    vcc_track_to_insert, gnd_track_to_insert = create_constant_tracks(conn)
    vcc_idx = len(tracks_to_insert)
    tracks_to_insert.append(vcc_track_to_insert)
    gnd_idx = len(tracks_to_insert)
    tracks_to_insert.append(gnd_track_to_insert)

    track_pkeys = insert_tracks(conn, tracks_to_insert)
    vcc_track_pkey = track_pkeys[vcc_idx]
    gnd_track_pkey = track_pkeys[gnd_idx]

    write_cur = conn.cursor()
    write_cur.execute(
        """
INSERT INTO constant_sources(vcc_track_pkey, gnd_track_pkey) VALUES (?, ?)
        """, (
            vcc_track_pkey,
            gnd_track_pkey,
        ))

    conn.commit()

    connect_hardpins_to_constant_network(conn, vcc_track_pkey, gnd_track_pkey)