Skip to content

Commit

Permalink
iCE40: bel timing import (f4pga#693)
Browse files Browse the repository at this point in the history
iCE40: bel timing import
  • Loading branch information
elms committed Jun 27, 2019
2 parents 284e68a + affc1c0 commit 3948971
Show file tree
Hide file tree
Showing 9 changed files with 473 additions and 150 deletions.
60 changes: 39 additions & 21 deletions common/cmake/devices.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,10 @@ function(DEFINE_DEVICE_TYPE)
# Defines a device type with the specified architecture. ARCH_XML argument
# must be a file target (see ADD_FILE_TARGET).
#
# optional SCRIPTs can be run after the standard flow to augment the
# final arch xml. The name and script must be provided and each
# script will be run as `cmd < input > output`
#
# DEFINE_DEVICE_TYPE defines a dummy target <arch>_<device_type>_arch that
# will build the merged architecture file for the device type.
#
Expand All @@ -266,17 +270,6 @@ function(DEFINE_DEVICE_TYPE)
${ARGN}
)

add_custom_target(${DEFINE_DEVICE_TYPE_DEVICE_TYPE})
foreach(ARG ARCH)
if("${DEFINE_DEVICE_TYPE_${ARG}}" STREQUAL "")
message(FATAL_ERROR "Required argument ${ARG} is the empty string.")
endif()
set_target_properties(
${DEFINE_DEVICE_TYPE_DEVICE_TYPE}
PROPERTIES ${ARG} ${DEFINE_DEVICE_TYPE_${ARG}}
)
endforeach()

#
# Generate a arch.xml for a device.
#
Expand Down Expand Up @@ -309,8 +302,10 @@ function(DEFINE_DEVICE_TYPE)
${SPECIALIZE_CARRYCHAINS}
${SPECIALIZE_CARRYCHAINS_DEPS}
)
add_file_target(FILE ${DEVICE_UNIQUE_PACK_FILE} GENERATED)

add_file_target(FILE ${DEVICE_UNIQUE_PACK_FILE} GENERATED)
get_file_target(FINAL_TARGET ${DEVICE_UNIQUE_PACK_FILE})
get_file_location(FINAL_FILE ${DEVICE_UNIQUE_PACK_FILE})
set(FINAL_OUTPUT ${DEVICE_UNIQUE_PACK_FILE})

# for each script generate next chain of deps
Expand All @@ -322,21 +317,25 @@ function(DEFINE_DEVICE_TYPE)
separate_arguments(CMD_W_ARGS UNIX_COMMAND ${SCRIPT})
list(GET CMD_W_ARGS 0 CMD)
set(TEMP_TARGET arch.${OUTPUT_NAME}.xml)
set(DEPS ${PYTHON3} ${PYTHON3_TARGET} ${CMD})
append_file_dependency(DEPS ${FINAL_OUTPUT})

add_custom_command(
OUTPUT ${TEMP_TARGET}
COMMAND ${PYTHON3} ${CMD_W_ARGS} ${FINAL_OUTPUT} > ${TEMP_TARGET}
DEPENDS
${PYTHON3} ${PYTHON3_TARGET}
${CMD} ${FINAL_OUTPUT}
COMMAND ${CMD_W_ARGS} < ${FINAL_FILE} > ${TEMP_TARGET}
DEPENDS ${DEPS}
)

add_file_target(FILE ${TEMP_TARGET} GENERATED)
get_file_target(FINAL_TARGET ${TEMP_TARGET})
get_file_location(FINAL_FILE ${TEMP_TARGET})
set(FINAL_OUTPUT ${TEMP_TARGET})
add_file_target(FILE ${FINAL_OUTPUT} GENERATED)
endforeach(SCRIPT_IND RANGE ${SCRIPT_LEN})
endif (DEFINE_DEVICE_TYPE_SCRIPTS)

add_custom_target(
${DEFINE_DEVICE_TYPE_ARCH}_${DEFINE_DEVICE_TYPE_DEVICE_TYPE}_arch
DEPENDS ${FINAL_OUTPUT}
DEPENDS ${FINAL_TARGET}
)
add_dependencies(
all_merged_arch_xmls
Expand All @@ -346,16 +345,33 @@ function(DEFINE_DEVICE_TYPE)
set(ARCH_SCHEMA ${symbiflow-arch-defs_SOURCE_DIR}/common/xml/fpga_architecture.xsd)
xml_lint(
NAME ${DEFINE_DEVICE_TYPE_ARCH}_${DEFINE_DEVICE_TYPE_DEVICE_TYPE}_arch_lint
FILE ${FINAL_OUTPUT}
FILE ${FINAL_FILE}
LINT_OUTPUT ${XMLLINT_OUTPUT}
SCHEMA ${ARCH_SCHEMA}
)

append_file_dependency(FINAL_DEPS ${FINAL_OUTPUT})

add_custom_target(
${DEFINE_DEVICE_TYPE_DEVICE_TYPE}
DEPENDS ${FINAL_DEPS}
)

foreach(ARG ARCH)
if("${DEFINE_DEVICE_TYPE_${ARG}}" STREQUAL "")
message(FATAL_ERROR "Required argument ${ARG} is the empty string.")
endif()
set_target_properties(
${DEFINE_DEVICE_TYPE_DEVICE_TYPE}
PROPERTIES ${ARG} ${DEFINE_DEVICE_TYPE_${ARG}}
)
endforeach()

set_target_properties(
${DEFINE_DEVICE_TYPE_DEVICE_TYPE}
PROPERTIES
DEVICE_MERGED_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${FINAL_OUTPUT}
)
)

endfunction()

Expand Down Expand Up @@ -443,7 +459,7 @@ function(DEFINE_DEVICE)
${symbiflow-arch-defs_SOURCE_DIR}/common/wire.eblif
${DEVICE_MERGED_FILE} ${DEVICE_MERGED_FILE_TARGET}
${QUIET_CMD} ${QUIET_CMD_TARGET}
${VPR} ${VPR_TARGET}
${VPR} ${VPR_TARGET} ${DEFINE_DEVICE_DEVICE_TYPE}
COMMAND
${QUIET_CMD} ${VPR} ${DEVICE_MERGED_FILE}
--device ${DEVICE_FULL}
Expand Down Expand Up @@ -885,6 +901,8 @@ function(ADD_FPGA_TARGET)
set(OUT_ROUTE ${OUT_LOCAL}/${TOP}.route)

set(VPR_DEPS "")
append_file_dependency(VPR_DEPS ${OUT_EBLIF_REL})
list(APPEND VPR_DEPS ${DEFINE_DEVICE_DEVICE_TYPE})

get_file_location(OUT_RRXML_VIRT_LOCATION ${OUT_RRXML_VIRT})
get_file_location(OUT_RRXML_REAL_LOCATION ${OUT_RRXML_REAL})
Expand Down
103 changes: 1 addition & 102 deletions ice40/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,105 +1,4 @@
function(icestorm_setup)
get_target_property_required(PYTHON3 env PYTHON3)

set(ICESTORM_SRC ${symbiflow-arch-defs_SOURCE_DIR}/third_party/icestorm CACHE PATH "Path to icestorm repository")
set(PYUTILS_PATH ${symbiflow-arch-defs_SOURCE_DIR}/utils:${symbiflow-arch-defs_SOURCE_DIR}/ice40/utils/fasm_icebox)

get_target_property_required(PYTHON_PREFIX env CONDA_DIR)
set(ICESTORM_PREFIX "PREFIX=${PYTHON_PREFIX}")

add_conda_package(
NAME pkg-config
PROVIDES pkg-config
)
add_conda_package(
NAME libftdi
NO_EXE
)
get_target_property(LIBFTDI_TARGET env LIBFTDI_TARGET)

add_conda_pip(
NAME numpy
NO_EXE
)

add_thirdparty_package(
NAME fasm
BUILD_INSTALL_COMMAND "cd ${symbiflow-arch-defs_SOURCE_DIR}/third_party/fasm && ${PYTHON3} setup.py install"
PROVIDES fasm
)

get_target_property(FASM_TARGET env FASM_TARGET)

set(FASM2ASC ${symbiflow-arch-defs_SOURCE_DIR}/ice40/utils/fasm_icebox/fasm2asc.py)
add_custom_target(
fasm2asc_deps
DEPENDS numpy ${FASM_TARGET} ${FASM2ASC}
)

get_target_property_required(PKG-CONFIG env PKG-CONFIG)
get_target_property_required(PKG-CONFIG_TARGET env PKG-CONFIG_TARGET)

add_thirdparty_package(
NAME icestorm
PROVIDES iceprog icebox_hlc2asc icebox_vlog icepack icetime icebox
BUILD_INSTALL_COMMAND "make -C ${ICESTORM_SRC} ${ICESTORM_PREFIX} PKG_CONFIG=${PKG-CONFIG} install"
DEPENDS ${LIBFTDI_TARGET} ${PKG-CONFIG_TARGET}
)

get_target_property_required(ICEBOX_VLOG env ICEBOX_VLOG)
get_target_property_required(ICEPACK env ICEPACK)
get_target_property_required(ICETIME env ICETIME)
get_target_property_required(ICEBOX_HLC2ASC env ICEBOX_HLC2ASC)

get_target_property(ICEBOX_VLOG_TARGET env ICEBOX_VLOG_TARGET)
get_target_property(ICEPACK_TARGET env ICEPACK_TARGET)
get_target_property(ICETIME_TARGET env ICETIME_TARGET)
get_target_property(ICEBOX_HLC2ASC_TARGET env ICEBOX_HLC2ASC_TARGET)

get_target_property_required(ICEBOX env ICEBOX)
get_filename_component(ICEBOX_PATH ${ICEBOX} DIRECTORY)

set(PYPATH_ARG "PYTHONPATH=\${ICEBOX_PATH}:${PYUTILS_PATH}")
define_arch(
ARCH ice40
YOSYS_SCRIPT ${symbiflow-arch-defs_SOURCE_DIR}/ice40/yosys/synth.tcl
DEVICE_FULL_TEMPLATE \${DEVICE}-\${PACKAGE}
VPR_ARCH_ARGS
--clock_modeling route
--allow_unrelated_clustering off
--target_ext_pin_util 0.7
--router_init_wirelength_abort_threshold 2
RR_PATCH_TOOL
${symbiflow-arch-defs_SOURCE_DIR}/ice40/utils/ice40_import_routing_from_icebox.py
RR_PATCH_CMD "\${QUIET_CMD} \${CMAKE_COMMAND} -E env ${PYPATH_ARG} \
\${PYTHON3} \${RR_PATCH_TOOL} \
--device=\${DEVICE} \
--read_rr_graph \${OUT_RRXML_VIRT} \
--write_rr_graph \${OUT_RRXML_REAL}"
PLACE_TOOL
${symbiflow-arch-defs_SOURCE_DIR}/ice40/utils/ice40_create_ioplace.py
PLACE_TOOL_CMD "\${QUIET_CMD} \${CMAKE_COMMAND} -E env ${PYPATH_ARG} \
\${PYTHON3} \${PLACE_TOOL} \
--map \${PINMAP} \
--blif \${OUT_EBLIF} \
--pcf \${INPUT_IO_FILE}"
CELLS_SIM ${YOSYS_DATADIR}/ice40/cells_sim.v
BIT_TO_V ${ICEBOX_VLOG_TARGET}
BIT_TO_V_CMD "${ICEBOX_VLOG} -D -c -n \${TOP} -p \${INPUT_IO_FILE} -d \${PACKAGE} \${OUT_BITSTREAM} > \${OUT_BIT_VERILOG}"
BITSTREAM_EXTENSION asc
BIT_TO_BIN ${ICEPACK_TARGET}
BIT_TO_BIN_CMD "${ICEPACK} \${OUT_BITSTREAM} > \${OUT_BIN}"
BIT_TIME ${ICETIME_TARGET}
BIN_EXTENSION bin
BIT_TIME_CMD "${ICETIME} -v -t -p \${INPUT_IO_FILE} -d \${DEVICE} \${OUT_BITSTREAM} -o \${OUT_TIME_VERILOG}"
FASM_TO_BIT fasm2asc_deps
FASM_TO_BIT_CMD "\${QUIET_CMD} \${CMAKE_COMMAND} -E env ${PYPATH_ARG} \
\${PYTHON3} ${FASM2ASC} --device \${DEVICE} \${OUT_FASM} \${OUT_BITSTREAM}"
USE_FASM
ROUTE_CHAN_WIDTH 100
)

endfunction()
include(icestorm.cmake)

icestorm_setup()

Expand Down
39 changes: 38 additions & 1 deletion ice40/devices/top-routing-virt/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,41 @@
add_subdirectory(tiles)

add_file_target(FILE arch.xml SCANNER_TYPE xml)
define_device_type(DEVICE_TYPE top-routing-virt ARCH ice40 ARCH_XML arch.xml)

get_target_property_required(CONDA_DIR env CONDA_DIR)
get_target_property_required(PYTHON3 env PYTHON3)
get_target_property_required(PYTHON3_TARGET env PYTHON3_TARGET)
get_target_property_required(ICESTORM_TARGET env ICESTORM_TARGET)

set(ICEBOX_TIMING ${symbiflow-arch-defs_SOURCE_DIR}/third_party/icestorm/icefuzz/timings.py)
set(CLEAN_ICEBOX_TIMING cleaned_timing.txt)
set(TIMING_TXT_FILE ${ICEBOX_SHARE}/timings_hx1k.txt)
set(SDF_FILE timings_hx1k.sdf)

add_custom_command(
OUTPUT ${SDF_FILE}
COMMAND grep -v \\* ${TIMING_TXT_FILE} > ${CLEAN_ICEBOX_TIMING}
COMMAND ${PYTHON3} ${ICEBOX_TIMING} -t ${CLEAN_ICEBOX_TIMING} -s > ${SDF_FILE}
BYPRODUCTS ${CLEAN_ICEBOX_TIMING}
DEPENDS ${TIMING_TXT_FILE} ${ICESTORM_TARGET} ${ICEBOX_TIMING} ${PYTHON3} ${PYTHON3_TARGET}
)

add_custom_target(
ice40_sdf_target
DEPENDS ${SDF_FILE}
)
get_target_property_required(ICE40_IMPORT_TIMING ice40_import_timing_deps ICE40_IMPORT_TIMING)
set(TIMING_IMPORT_CMD "${PYTHON3} ${ICE40_IMPORT_TIMING} --read_sdf ${SDF_FILE} --write_arch_xml /dev/stdout --read_arch_xml /dev/stdin")

define_device_type(
DEVICE_TYPE top-routing-virt
ARCH ice40
ARCH_XML arch.xml
SCRIPT_OUTPUT_NAME timing
SCRIPTS ${TIMING_IMPORT_CMD}
)

add_dependencies(ice40_top-routing-virt_arch ice40_import_timing_deps ice40_sdf_target)
get_target_property_required(VIRT_DEVICE_MERGED_FILE top-routing-virt DEVICE_MERGED_FILE)
get_file_target(DEVICE_MERGED_FILE_TARGET ${VIRT_DEVICE_MERGED_FILE})
add_dependencies(${DEVICE_MERGED_FILE_TARGET} ice40_import_timing_deps ice40_sdf_target)
117 changes: 117 additions & 0 deletions ice40/icestorm.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
function(icestorm_setup)
get_target_property_required(PYTHON3 env PYTHON3)
get_target_property_required(PYTHON3_TARGET env PYTHON3_TARGET)

set(ICESTORM_SRC ${symbiflow-arch-defs_SOURCE_DIR}/third_party/icestorm CACHE PATH "Path to icestorm repository")
set(PYUTILS_PATH ${symbiflow-arch-defs_SOURCE_DIR}/utils:${symbiflow-arch-defs_SOURCE_DIR}/ice40/utils/fasm_icebox)

get_target_property_required(PYTHON_PREFIX env CONDA_DIR)
set(ICESTORM_PREFIX "PREFIX=${PYTHON_PREFIX}")

add_conda_package(
NAME pkg-config
PROVIDES pkg-config
)
add_conda_package(
NAME libftdi
NO_EXE
)
get_target_property(LIBFTDI_TARGET env LIBFTDI_TARGET)

add_conda_pip(
NAME numpy
NO_EXE
)

add_thirdparty_package(
NAME fasm
BUILD_INSTALL_COMMAND "cd ${symbiflow-arch-defs_SOURCE_DIR}/third_party/fasm && ${PYTHON3} setup.py develop"
PROVIDES fasm
DEPENDS ${PYTHON3} ${PYTHON3_TARGET}
)

get_target_property_required(FASM_TARGET env FASM_TARGET)

set(FASM2ASC ${symbiflow-arch-defs_SOURCE_DIR}/ice40/utils/fasm_icebox/fasm2asc.py)
add_custom_target(
fasm2asc_deps
DEPENDS numpy ${FASM_TARGET} ${FASM2ASC} ${PYTHON3} ${PYTHON3_TARGET}
)

get_target_property_required(SDF_TIMING_TARGET env SDF_TIMING_TARGET)
add_custom_target(
ice40_import_timing_deps
DEPENDS ${ICE40_IMPORT_TIMING} ${SDF_TIMING_TARGET} ${PYTHON3} ${PYTHON3_TARGET}
)

set_target_properties(
ice40_import_timing_deps
PROPERTIES ICE40_IMPORT_TIMING ${symbiflow-arch-defs_SOURCE_DIR}/ice40/utils/ice40_import_bel_timing.py
)

get_target_property_required(PKG-CONFIG env PKG-CONFIG)
get_target_property_required(PKG-CONFIG_TARGET env PKG-CONFIG_TARGET)

add_thirdparty_package(
NAME icestorm
PROVIDES iceprog icebox_hlc2asc icebox_vlog icepack icetime icebox
BUILD_INSTALL_COMMAND "make -C ${ICESTORM_SRC} ${ICESTORM_PREFIX} PKG_CONFIG=${PKG-CONFIG} install"
DEPENDS ${LIBFTDI_TARGET} ${PKG-CONFIG_TARGET}
)

get_target_property_required(ICEBOX_VLOG env ICEBOX_VLOG)
get_target_property_required(ICEPACK env ICEPACK)
get_target_property_required(ICETIME env ICETIME)
get_target_property_required(ICEBOX_HLC2ASC env ICEBOX_HLC2ASC)

get_target_property(ICEBOX_VLOG_TARGET env ICEBOX_VLOG_TARGET)
get_target_property(ICEPACK_TARGET env ICEPACK_TARGET)
get_target_property(ICETIME_TARGET env ICETIME_TARGET)
get_target_property(ICEBOX_HLC2ASC_TARGET env ICEBOX_HLC2ASC_TARGET)

get_target_property_required(ICEBOX env ICEBOX)
get_filename_component(ICEBOX_PATH ${ICEBOX} DIRECTORY)
set(ICEBOX_SHARE ${ICEBOX_PATH}/../share/icebox CACHE PATH "")

set(PYPATH_ARG "PYTHONPATH=\${ICEBOX_PATH}:${PYUTILS_PATH}")
define_arch(
ARCH ice40
YOSYS_SCRIPT ${symbiflow-arch-defs_SOURCE_DIR}/ice40/yosys/synth.tcl
DEVICE_FULL_TEMPLATE \${DEVICE}-\${PACKAGE}
VPR_ARCH_ARGS
--clock_modeling route
--allow_unrelated_clustering off
--target_ext_pin_util 0.7
--router_init_wirelength_abort_threshold 2
--congested_routing_iteration_threshold 0.8
RR_PATCH_TOOL
${symbiflow-arch-defs_SOURCE_DIR}/ice40/utils/ice40_import_routing_from_icebox.py
RR_PATCH_CMD "\${QUIET_CMD} \${CMAKE_COMMAND} -E env ${PYPATH_ARG} \
\${PYTHON3} \${RR_PATCH_TOOL} \
--device=\${DEVICE} \
--read_rr_graph \${OUT_RRXML_VIRT} \
--write_rr_graph \${OUT_RRXML_REAL}"
PLACE_TOOL
${symbiflow-arch-defs_SOURCE_DIR}/ice40/utils/ice40_create_ioplace.py
PLACE_TOOL_CMD "\${QUIET_CMD} \${CMAKE_COMMAND} -E env ${PYPATH_ARG} \
\${PYTHON3} \${PLACE_TOOL} \
--map \${PINMAP} \
--blif \${OUT_EBLIF} \
--pcf \${INPUT_IO_FILE}"
CELLS_SIM ${YOSYS_DATADIR}/ice40/cells_sim.v
BIT_TO_V ${ICEBOX_VLOG_TARGET}
BIT_TO_V_CMD "${ICEBOX_VLOG} -D -c -n \${TOP} -p \${INPUT_IO_FILE} -d \${PACKAGE} \${OUT_BITSTREAM} > \${OUT_BIT_VERILOG}"
BITSTREAM_EXTENSION asc
BIT_TO_BIN ${ICEPACK_TARGET}
BIT_TO_BIN_CMD "${ICEPACK} \${OUT_BITSTREAM} > \${OUT_BIN}"
BIT_TIME ${ICETIME_TARGET}
BIN_EXTENSION bin
BIT_TIME_CMD "${ICETIME} -v -t -p \${INPUT_IO_FILE} -d \${DEVICE} \${OUT_BITSTREAM} -o \${OUT_TIME_VERILOG}"
FASM_TO_BIT fasm2asc_deps
FASM_TO_BIT_CMD "\${QUIET_CMD} \${CMAKE_COMMAND} -E env ${PYPATH_ARG} \
\${PYTHON3} ${FASM2ASC} --device \${DEVICE} \${OUT_FASM} \${OUT_BITSTREAM}"
USE_FASM
ROUTE_CHAN_WIDTH 100
)

endfunction()

0 comments on commit 3948971

Please sign in to comment.