Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial SQLite3 XC7 routing graph implementation. #445

Merged
merged 10 commits into from Mar 9, 2019
422 changes: 422 additions & 0 deletions utils/lib/connection_database.py

Large diffs are not rendered by default.

26 changes: 14 additions & 12 deletions utils/lib/rr_graph/graph2.py
Expand Up @@ -114,13 +114,16 @@ def __init__(self, switches, segments, block_types, grid, nodes):
# pin name -> block type id, pin class idx, pin idx
self.pin_name_map = {}

self.pin_ptc_to_name_map = {}

# Create pin_name_map and sanity check block_types.
for idx, block_type in enumerate(self.block_types):
assert idx == block_type.id
for pin_class_idx, pin_class in enumerate(block_type.pin_class):
for pin in pin_class.pin:
assert pin.name not in self.pin_name_map
self.pin_name_map[pin.name] = (block_type.id, pin_class_idx, pin.ptc)
self.pin_ptc_to_name_map[(block_type.id, pin.ptc)] = pin.name

# Create mapping from grid locations and pins to nodes.
for idx, node in enumerate(self.nodes):
Expand Down Expand Up @@ -283,22 +286,22 @@ def check_ptc(self):
for node in self.nodes:
assert node.loc.ptc is not None, node

def set_track_ptc(self, track, ptc):
node_d = self.nodes[track]._asdict()
loc_d = self.nodes[track].loc._asdict()
assert loc_d['ptc'] is None
loc_d['ptc'] = ptc
node_d['loc'] = NodeLoc(**loc_d)

self.nodes[track] = Node(**node_d)

def create_channels(self, pad_segment, pool=None):
""" Pack tracks into channels and return Channels definition for tracks."""
assert len(self.tracks) > 0

xs = []
ys = []

def set_track_ptc(track, ptc):
node_d = self.nodes[track]._asdict()
loc_d = self.nodes[track].loc._asdict()
assert loc_d['ptc'] is None
loc_d['ptc'] = ptc
node_d['loc'] = NodeLoc(**loc_d)

self.nodes[track] = Node(**node_d)

for track in self.tracks:
track_node = self.nodes[track]

Expand Down Expand Up @@ -342,7 +345,6 @@ def set_track_ptc(track, ptc):
x_channel_models = {}
y_channel_models = {}


if pool is not None:
for y in x_tracks:
x_channel_models[y] = pool.apply_async(process_track, (x_tracks[y],))
Expand All @@ -360,7 +362,7 @@ def set_track_ptc(track, ptc):
x_list.append(len(x_channel_models[y].trees))
for idx, tree in enumerate(x_channel_models[y].trees):
for i in tree:
set_track_ptc(track=i[2], ptc=idx)
self.set_track_ptc(track=i[2], ptc=idx)
else:
x_list.append(0)

Expand All @@ -374,7 +376,7 @@ def set_track_ptc(track, ptc):
y_list.append(len(y_channel_models[x].trees))
for idx, tree in enumerate(y_channel_models[x].trees):
for i in tree:
set_track_ptc(track=i[2], ptc=idx)
self.set_track_ptc(track=i[2], ptc=idx)
else:
y_list.append(0)

Expand Down
12 changes: 7 additions & 5 deletions utils/lib/rr_graph_xml/graph2.py
Expand Up @@ -185,17 +185,19 @@ def __init__(self, input_xml, progressbar=None):

self.graph = graph2.Graph(**graph_input)

def serialize_to_xml(self, tool_version, tool_comment, pad_segment, pool=None):
def serialize_to_xml(self, tool_version, tool_comment, pad_segment, channels_obj=None, pool=None):
output_xml = ET.Element('rr_graph', {
'tool_name': 'vpr',
'tool_version': tool_version,
'tool_comment': tool_comment,
})

channels_obj = self.graph.create_channels(
pad_segment=pad_segment,
pool=pool,
)
if channels_obj is None:
channels_obj = self.graph.create_channels(
pad_segment=pad_segment,
pool=pool,
)

self.graph.check_ptc()

channels_xml = ET.SubElement(output_xml, 'channels')
Expand Down
4 changes: 2 additions & 2 deletions xc7/make/device_define.cmake
Expand Up @@ -53,7 +53,7 @@ function(ADD_XC7_DEVICE_DEFINE)
add_subdirectory(${DEVICE}-roi-virt)

# SYNTH_TILES used in ROI.
set(CHANNELS ${symbiflow-arch-defs_SOURCE_DIR}/xc7/archs/${ARCH}/channels.json)
set(CHANNELS ${CMAKE_CURRENT_SOURCE_DIR}/${DEVICE}-roi-virt/channels.db)
set(SYNTH_TILES ${CMAKE_CURRENT_SOURCE_DIR}/${DEVICE}-roi-virt/synth_tiles.json)
get_file_location(SYNTH_TILES_LOCATION ${SYNTH_TILES})
get_file_location(CHANNELS_LOCATIONS ${CHANNELS})
Expand All @@ -68,7 +68,7 @@ function(ADD_XC7_DEVICE_DEFINE)
ARCH ${ARCH}
DEVICE_TYPE ${DEVICE}-roi-virt
PACKAGES test
RR_PATCH_EXTRA_ARGS --synth_tiles ${SYNTH_TILES_LOCATION} --channels ${CHANNELS_LOCATIONS}
RR_PATCH_EXTRA_ARGS --synth_tiles ${SYNTH_TILES_LOCATION} --connection_database ${CHANNELS_LOCATIONS}
RR_PATCH_DEPS ${DEVICE_RR_PATCH_DEPS}
)

Expand Down
79 changes: 60 additions & 19 deletions xc7/make/project_xray.cmake
Expand Up @@ -132,6 +132,8 @@ function(PROJECT_XRAY_ARCH)
set(DEVICE ${PROJECT_XRAY_ARCH_DEVICE})

set(ARCH_IMPORT ${symbiflow-arch-defs_SOURCE_DIR}/xc7/utils/prjxray_arch_import.py)
set(CREATE_SYNTH_TILES ${symbiflow-arch-defs_SOURCE_DIR}/xc7/utils/prjxray_create_synth_tiles.py)
set(CREATE_EDGES ${symbiflow-arch-defs_SOURCE_DIR}/xc7/utils/prjxray_create_edges.py)
set(DEPS ${PRJXRAY_DB_DIR}/${PART}/tilegrid.json)

set(ARCH_INCLUDE_FILES "")
Expand All @@ -151,12 +153,33 @@ function(PROJECT_XRAY_ARCH)
list(APPEND ARCH_INCLUDE_FILES ${MODEL_XML} ${INCLUDE_FILES})
endforeach()

set(OUTPUTS arch.xml)
set(ROI_ARG "")
set(ROI_ARG_FOR_CREATE_EDGES "")

if(NOT "${PROJECT_XRAY_ARCH_USE_ROI}" STREQUAL "")
set(OUTPUTS arch.xml synth_tiles.json)
add_custom_command(
OUTPUT synth_tiles.json
COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${PRJXRAY_DIR}:${symbiflow-arch-defs_SOURCE_DIR}/utils
${PYTHON3} ${CREATE_SYNTH_TILES}
--db_root ${PRJXRAY_DB_DIR}/${PART}/
--roi ${PROJECT_XRAY_ARCH_USE_ROI}
--synth_tiles ${CMAKE_CURRENT_BINARY_DIR}/synth_tiles.json
DEPENDS
${CREATE_SYNTH_TILES}
${PROJECT_XRAY_ARCH_USE_ROI}
${PYTHON3} ${PYTHON3_TARGET}
)

add_file_target(FILE synth_tiles.json GENERATED)
set_target_properties(${ARCH_TARGET} PROPERTIES USE_ROI TRUE)
set_target_properties(${ARCH_TARGET} PROPERTIES
SYNTH_TILES ${CMAKE_CURRENT_SOURCE_DIR}/synth_tiles.json)

set(ROI_ARG --use_roi ${PROJECT_XRAY_ARCH_USE_ROI} --synth_tiles ${CMAKE_CURRENT_BINARY_DIR}/synth_tiles.json)
list(APPEND DEPS ${PROJECT_XRAY_ARCH_USE_ROI})
list(APPEND DEPS ${PROJECT_XRAY_ARCH_USE_ROI} synth_tiles.json)

set(ROI_ARG_FOR_CREATE_EDGES --synth_tiles ${CMAKE_CURRENT_BINARY_DIR}/synth_tiles.json)
list(APPEND CHANNELS_DEPS synth_tiles.json)
endif()

append_file_dependency(DEPS ${symbiflow-arch-defs_SOURCE_DIR}/xc7/archs/${PART}/pin_assignments.json)
Expand All @@ -165,15 +188,15 @@ function(PROJECT_XRAY_ARCH)
string(REPLACE ";" "," TILE_TYPES_COMMA "${PROJECT_XRAY_ARCH_TILE_TYPES}")

add_custom_command(
OUTPUT ${OUTPUTS}
OUTPUT arch.xml
COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${PRJXRAY_DIR}:${symbiflow-arch-defs_SOURCE_DIR}/utils
${PYTHON3} ${ARCH_IMPORT}
--part ${PROJECT_XRAY_ARCH_PART}
--output-arch ${CMAKE_CURRENT_BINARY_DIR}/arch.xml
--tile-types "${TILE_TYPES_COMMA}"
--pin_assignments ${PIN_ASSIGNMENTS}
--device ${DEVICE}
${ROI_ARG}
--part ${PROJECT_XRAY_ARCH_PART}
--output-arch ${CMAKE_CURRENT_BINARY_DIR}/arch.xml
--tile-types "${TILE_TYPES_COMMA}"
--pin_assignments ${PIN_ASSIGNMENTS}
--device ${DEVICE}
${ROI_ARG}
DEPENDS
${ARCH_IMPORT}
${DEPS}
Expand All @@ -184,11 +207,29 @@ function(PROJECT_XRAY_ARCH)
get_file_target(ARCH_TARGET arch.xml)
set_target_properties(${ARCH_TARGET} PROPERTIES INCLUDE_FILES "${ARCH_INCLUDE_FILES}")

if(NOT "${PROJECT_XRAY_ARCH_USE_ROI}" STREQUAL "")
add_file_target(FILE synth_tiles.json GENERATED)
set_target_properties(${ARCH_TARGET} PROPERTIES USE_ROI TRUE)
set_target_properties(${ARCH_TARGET} PROPERTIES SYNTH_TILES ${CMAKE_CURRENT_SOURCE_DIR}/synth_tiles.json)
endif()
set(GENERIC_CHANNELS
${symbiflow-arch-defs_SOURCE_DIR}/xc7/archs/${PART}/channels.db)
append_file_dependency(CHANNELS_DEPS ${GENERIC_CHANNELS})
append_file_dependency(CHANNELS_DEPS ${symbiflow-arch-defs_SOURCE_DIR}/xc7/archs/${PART}/pin_assignments.json)
get_file_location(GENERIC_CHANNELS_LOCATION ${GENERIC_CHANNELS})
list(APPEND CHANNELS_DEPS ${PRJXRAY_DB_DIR}/${PART}/tilegrid.json)
list(APPEND CHANNELS_DEPS ${PRJXRAY_DB_DIR}/${PART}/tileconn.json)

add_custom_command(
OUTPUT channels.db
COMMAND ${CMAKE_COMMAND} -E copy ${GENERIC_CHANNELS_LOCATION} ${CMAKE_CURRENT_BINARY_DIR}/channels.db
COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${PRJXRAY_DIR}:${symbiflow-arch-defs_SOURCE_DIR}/utils
${PYTHON3} ${CREATE_EDGES}
--db_root ${PRJXRAY_DB_DIR}/${PART}/
--pin_assignments ${PIN_ASSIGNMENTS}
--connection_database ${CMAKE_CURRENT_BINARY_DIR}/channels.db
${ROI_ARG_FOR_CREATE_EDGES}
DEPENDS
${PYTHON3} ${PYTHON3_TARGET} ${CREATE_EDGES}
${CHANNELS_DEPS}
)

add_file_target(FILE channels.db GENERATED)
endfunction()

function(PROJECT_XRAY_PREPARE_DATABASE)
Expand All @@ -212,13 +253,13 @@ function(PROJECT_XRAY_PREPARE_DATABASE)
file(GLOB DEPS ${PRJXRAY_DB_DIR}/${PART}/*.json)
file(GLOB DEPS2 ${PRJXRAY_DIR}/prjxray/*.py)

set(CHANNELS channels.json)
set(CHANNELS channels.db)
add_custom_command(
OUTPUT ${CHANNELS}
COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${PRJXRAY_DIR}:${symbiflow-arch-defs_SOURCE_DIR}/utils
${PYTHON3} ${FORM_CHANNELS}
--db_root ${PRJXRAY_DB_DIR}/${PART}/
--channels ${CMAKE_CURRENT_BINARY_DIR}/${CHANNELS}
--connection_database ${CMAKE_CURRENT_BINARY_DIR}/${CHANNELS}
DEPENDS
${FORM_CHANNELS}
${DEPS} ${DEPS2} simplejson progressbar2 intervaltree
Expand All @@ -233,10 +274,10 @@ function(PROJECT_XRAY_PREPARE_DATABASE)
COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${PRJXRAY_DIR}:${symbiflow-arch-defs_SOURCE_DIR}/utils
${PYTHON3} ${ASSIGN_PINS}
--db_root ${PRJXRAY_DB_DIR}/${PART}/
--channels ${CMAKE_CURRENT_BINARY_DIR}/${CHANNELS}
--connection_database ${CMAKE_CURRENT_BINARY_DIR}/${CHANNELS}
--pin_assignments ${CMAKE_CURRENT_BINARY_DIR}/${PIN_ASSIGNMENTS}
DEPENDS
${FORM_CHANNELS}
${ASSIGN_PINS}
${DEPS} ${DEPS2} ${CHANNELS}
${PYTHON3} ${PYTHON3_TARGET}
)
Expand Down
64 changes: 7 additions & 57 deletions xc7/utils/prjxray_arch_import.py
Expand Up @@ -108,10 +108,10 @@ def main():
'--pin_assignments', required=True, type=argparse.FileType('r'))
parser.add_argument(
'--use_roi', required=False)
parser.add_argument(
'--synth_tiles', required=False)
parser.add_argument(
'--device', required=True)
parser.add_argument(
'--synth_tiles', required=False)

args = parser.parse_args()

Expand Down Expand Up @@ -147,22 +147,14 @@ def main():
g = db.grid()
x_min, x_max, y_min, y_max = g.dims()

# FIXME: There is an issue in the routing phase. (https://github.com/SymbiFlow/symbiflow-arch-defs/issues/353)
# if a zynq device is selected the grid must be expanded by 1
if args.device == 'xc7z010':
x_max += 1
y_max += 1

name = '{}-test'.format(args.device)
fixed_layout_xml = ET.SubElement(layout_xml, 'fixed_layout', {
'name': name,
'height': str(y_max+1),
'width': str(x_max+1),
'height': str(y_max+2),
litghost marked this conversation as resolved.
Show resolved Hide resolved
'width': str(x_max+2),
})

only_emit_roi = False
roi_inputs = []
roi_outputs = []

synth_tiles = {}
synth_tiles['tiles'] = {}
Expand All @@ -171,6 +163,9 @@ def main():
with open(args.use_roi) as f:
j = json.load(f)

with open(args.synth_tiles) as f:
synth_tiles = json.load(f)

roi = Roi(
db=db,
x1=j['info']['GRID_X_MIN'],
Expand All @@ -179,51 +174,6 @@ def main():
y2=j['info']['GRID_Y_MAX'],
)

synth_tiles['info'] = j['info']
for port in j['ports']:
if port['name'].startswith('dout['):
roi_outputs.append(port)
port_type = 'input'
is_clock = False
elif port['name'].startswith('din['):
roi_inputs.append(port)
is_clock = False
port_type = 'output'
elif port['name'].startswith('clk'):
roi_inputs.append(port)
port_type = 'output'
is_clock = True
else:
assert False, port

tile, wire = port['wire'].split('/')

# Make sure connecting wire is not in ROI!
loc = g.loc_of_tilename(tile)
if roi.tile_in_roi(loc):
# Or if in the ROI, make sure it has no sites.
gridinfo = g.gridinfo_at_tilename(tile)
assert len(db.get_tile_type(gridinfo.tile_type).get_sites()) == 0, tile



if tile not in synth_tiles['tiles']:
synth_tiles['tiles'][tile] = {
'pins': [],
'loc': g.loc_of_tilename(tile),
}

synth_tiles['tiles'][tile]['pins'].append({
'roi_name': port['name'].replace('[', '_').replace(']','_'),
'wire': wire,
'pad': port['pin'],
'port_type': port_type,
'is_clock': is_clock,
})

with open(args.synth_tiles, 'w') as f:
json.dump(synth_tiles, f)

synth_tile_map = add_synthetic_tile(complexblocklist_xml)

for loc in g.tile_locations():
Expand Down