blob: 0910eecdc94ccc7e4ad058bf0837d6f5890bc093 [file] [log] [blame] [edit]
import enum
import os
from lib.rr_graph import graph2
from lib.rr_graph import tracks
class NodeClassification(enum.Enum):
NULL = 1
CHANNEL = 2
EDGES_TO_CHANNEL = 3
EDGE_WITH_MUX = 4
def create_tables(conn):
""" Create connection database scheme. """
connection_database_sql_file = os.path.join(
os.path.dirname(__file__), "connection_database.sql"
)
with open(connection_database_sql_file, 'r') as f:
c = conn.cursor()
c.executescript(f.read())
conn.commit()
c = conn.cursor()
c.execute(
"""
INSERT INTO
switch(name, internal_capacitance, drive_resistance, intrinsic_delay, switch_type)
VALUES
("__vpr_delayless_switch__", 0.0, 0.0, 0.0, "mux"),
("short", 0.0, 0.0, 0.0, "short")
"""
)
conn.commit()
def get_wire_pkey(conn, tile_name, wire):
c = conn.cursor()
c.execute(
"""
WITH selected_tile(phy_tile_pkey, tile_type_pkey) AS (
SELECT
pkey,
tile_type_pkey
FROM
phy_tile
WHERE
name = ?
)
SELECT
wire.pkey
FROM
wire
WHERE
wire.phy_tile_pkey = (
SELECT
selected_tile.phy_tile_pkey
FROM
selected_tile
)
AND wire.wire_in_tile_pkey = (
SELECT
wire_in_tile.pkey
FROM
wire_in_tile
WHERE
wire_in_tile.name = ?
AND wire_in_tile.tile_type_pkey = (
SELECT
tile_type_pkey
FROM
selected_tile
)
);
""", (tile_name, wire)
)
results = c.fetchone()
assert results is not None, (tile_name, wire)
return results[0]
def get_track_model(conn, track_pkey):
assert track_pkey is not None
track_list = []
track_nodes = []
c2 = conn.cursor()
graph_node_pkey = {}
for idx, (pkey, graph_node_type, x_low, x_high, y_low,
y_high) in enumerate(c2.execute("""
SELECT pkey, graph_node_type, x_low, x_high, y_low, y_high
FROM graph_node WHERE track_pkey = ?""", (track_pkey, ))):
node_type = graph2.NodeType(graph_node_type)
if node_type == graph2.NodeType.CHANX:
direction = 'X'
elif node_type == graph2.NodeType.CHANY:
direction = 'Y'
graph_node_pkey[pkey] = idx
track_nodes.append(pkey)
track_list.append(
tracks.Track(
direction=direction,
x_low=x_low,
x_high=x_high,
y_low=y_low,
y_high=y_high
)
)
track_connections = set()
for src_graph_node_pkey, dest_graph_node_pkey in c2.execute("""
SELECT src_graph_node_pkey, dest_graph_node_pkey
FROM graph_edge WHERE track_pkey = ?""", (track_pkey, )):
src_idx = graph_node_pkey[src_graph_node_pkey]
dest_idx = graph_node_pkey[dest_graph_node_pkey]
track_connections.add(tuple(sorted((src_idx, dest_idx))))
tracks_model = tracks.Tracks(track_list, list(track_connections))
return tracks_model, track_nodes
def yield_wire_info_from_node(conn, node_pkey):
""" Yield tile types and wires attached to specified node.
Parameters
----------
conn : sqlite3.Connection
Connection database object.
node_pkey : int
Primary key into node table
Yields
-------
tile_type : str
Name of tile type for wire being yielded.
wire : str
Name of wire for wire being yielded.
Note: This function yields the prjxray tile_type and wire name. This
function does NOT tile_type's and wire names coorsponding to the VPR tiles.
"""
c2 = conn.cursor()
for tile_type, wire in c2.execute("""
WITH wires_in_node(phy_tile_pkey, wire_in_tile_pkey) AS (
SELECT
phy_tile_pkey,
wire_in_tile_pkey
FROM
wire
WHERE
node_pkey = ?
),
tile_for_wire(
wire_in_tile_pkey, tile_type_pkey
) AS (
SELECT
wires_in_node.wire_in_tile_pkey,
phy_tile.tile_type_pkey
FROM
phy_tile
INNER JOIN wires_in_node ON phy_tile.pkey = wires_in_node.phy_tile_pkey
),
tile_type_for_wire(
wire_in_tile_pkey, tile_type_name
) AS (
SELECT
tile_for_wire.wire_in_tile_pkey,
tile_type.name
FROM
tile_type
INNER JOIN tile_for_wire ON tile_type.pkey = tile_for_wire.tile_type_pkey
)
SELECT
tile_type_for_wire.tile_type_name,
wire_in_tile.name
FROM
wire_in_tile
INNER JOIN tile_type_for_wire ON tile_type_for_wire.wire_in_tile_pkey = wire_in_tile.pkey;
""", (node_pkey, )):
yield tile_type, wire
def yield_logical_wire_info_from_node(conn, node_pkey):
""" Yield tile types and wires attached to specified node.
Parameters
----------
conn : sqlite3.Connection
Connection database object.
node_pkey : int
Primary key into node table
Yields
-------
tile_type : str
Name of tile type for wire being yielded.
wire : str
Name of wire for wire being yielded.
Note: This function yields the prjxray tile_type and wire name. This
function does NOT tile_type's and wire names coorsponding to the VPR tiles.
"""
c2 = conn.cursor()
for tile_type, wire in c2.execute("""
WITH wires_in_node(tile_pkey, wire_in_tile_pkey) AS (
SELECT
tile_pkey,
wire_in_tile_pkey
FROM
wire
WHERE
node_pkey = ?
),
tile_for_wire(
wire_in_tile_pkey, tile_type_pkey
) AS (
SELECT
wires_in_node.wire_in_tile_pkey,
tile.tile_type_pkey
FROM
tile
INNER JOIN wires_in_node ON tile.pkey = wires_in_node.tile_pkey
),
tile_type_for_wire(
wire_in_tile_pkey, tile_type_name
) AS (
SELECT
tile_for_wire.wire_in_tile_pkey,
tile_type.name
FROM
tile_type
INNER JOIN tile_for_wire ON tile_type.pkey = tile_for_wire.tile_type_pkey
)
SELECT
tile_type_for_wire.tile_type_name,
wire_in_tile.name
FROM
wire_in_tile
INNER JOIN tile_type_for_wire ON tile_type_for_wire.wire_in_tile_pkey = wire_in_tile.pkey;
""", (node_pkey, )):
yield tile_type, wire
def node_to_site_pins(conn, node_pkey):
FIND_WIRE_WITH_SITE_PIN = """
WITH wires_in_node(
pkey, tile_pkey, wire_in_tile_pkey
) AS (
SELECT
pkey,
tile_pkey,
wire_in_tile_pkey
FROM
wire
WHERE
node_pkey = ?
)
SELECT
wires_in_node.pkey,
wires_in_node.tile_pkey,
wire_in_tile.pkey
FROM
wires_in_node
INNER JOIN wire_in_tile ON wires_in_node.wire_in_tile_pkey = wire_in_tile.pkey
WHERE
wire_in_tile.site_pin_pkey IS NOT NULL;
"""
c = conn.cursor()
for wire_pkey, tile_pkey, wire_in_tile_pkey in c.execute(
FIND_WIRE_WITH_SITE_PIN, (node_pkey, )):
yield wire_pkey, tile_pkey, wire_in_tile_pkey
def get_pin_name_of_wire(conn, wire_pkey):
""" Returns pin name of wire.
For unsplit tiles, this is the name of the wire.
For split tiles with only 1 site, this is the name of the site pin
connected to this wire.
For wires that are not a pin, returns None.
Parameters
----------
conn : sqlite3.Connection
Connection database object.
wire_pkey : int
Primary key into wire table
Returns
-------
pin : str
VPR pin name for given wire_pkey.
Returns none if this wire is not a pin.
"""
c = conn.cursor()
c.execute(
"""
SELECT wire_in_tile_pkey, tile_pkey FROM wire WHERE pkey = ?
""", (wire_pkey, )
)
wire_in_tile_pkey, tile_pkey = c.fetchone()
c.execute(
"""
SELECT site_as_tile_pkey FROM tile WHERE pkey = ?
""", (tile_pkey, )
)
site_as_tile_pkey = c.fetchone()[0]
c.execute(
"""
SELECT name, site_pin_pkey FROM wire_in_tile WHERE pkey = ?;
""", (wire_in_tile_pkey, )
)
wire_name, site_pin_pkey = c.fetchone()
if site_pin_pkey is None:
return None
if site_as_tile_pkey is not None:
c.execute(
"SELECT name FROM site_pin WHERE pkey = ?", (site_pin_pkey, )
)
return c.fetchone()[0]
else:
return wire_name
def get_wire_in_tile_from_pin_name(conn, tile_type_str, wire_str):
""" Returns wire_in_tile rows match specified tile type and pin name.
Because a split tile type can appear in multiple tiles (e.g. SLICEL in
CLBLL_L, CLBLL_R, etc), multiple wire_in_tile rows may be returned. The
site table primary key disambiguates which row to use.
Parameters
----------
conn : sqlite3.Connection
Connection database object.
tile_type_str : str
Name of tile_type this pin belongs to.
wire_str : str
Name of pin to get wire_in_tile rows for.
Returns
-------
wire_in_tile_pkeys : dict of int to int
Map of site table primary keys to wire_in_tile primary keys. Unsplit
tiles will always have only one dictionary entry. Split tiles may have
more than one.
site_pin_pkey : int
Row into site_pin table for this pin.
"""
# Find the generic wire_in_tile_pkey for the specified tile_type name and
# wire name.
c = conn.cursor()
# Find if this tile_type is a split tile.
c.execute(
"""
SELECT
site_pkey
FROM
site_as_tile
WHERE
parent_tile_type_pkey = (
SELECT
pkey
FROM
tile_type
WHERE
name = ?
);
""", (tile_type_str, )
)
result = c.fetchone()
wire_is_pin = result is not None
if wire_is_pin:
# This tile is a split tile, lookup for the wire_in_tile_pkey is based
# on the site pin name, rather than the wire name.
site_pkey = result[0]
c.execute(
"""
SELECT
pkey,
site_pin_pkey,
site_pkey
FROM
wire_in_tile
WHERE
site_pin_pkey = (
SELECT
pkey
FROM
site_pin
WHERE
site_type_pkey = (
SELECT
site_type_pkey
FROM
site
WHERE
pkey = ?
)
AND name = ?
);""", (site_pkey, wire_str)
)
else:
c.execute(
"""
SELECT
pkey,
site_pin_pkey,
site_pkey
FROM
wire_in_tile
WHERE
name = ?
and tile_type_pkey = (
SELECT
pkey
FROM
tile_type
WHERE
name = ?
);
""", (wire_str, tile_type_str)
)
wire_in_tile_pkeys = {}
the_site_pin_pkey = None
for wire_in_tile_pkey, site_pin_pkey, site_pkey in c:
wire_in_tile_pkeys[site_pkey] = wire_in_tile_pkey
if the_site_pin_pkey is not None:
assert the_site_pin_pkey == site_pin_pkey, (
tile_type_str, wire_str
)
else:
the_site_pin_pkey = site_pin_pkey
assert the_site_pin_pkey is not None, (tile_type_str, wire_str)
return wire_in_tile_pkeys, the_site_pin_pkey