From f5776a6d6490ada3471cf29b4ae074ae48cab07e Mon Sep 17 00:00:00 2001 From: Catherine Date: Wed, 15 Jan 2025 14:42:20 +0000 Subject: [PATCH] CMake: eliminate `family.cmake`/`CMakeLists.txt` split. While it served a purpose (granting the ability to build `.bba` files separately from the rest of nextpnr), it made things excessively convoluted, especially around paths. This commit removes the ability to pre-generate chip databases. As far as I know, I was the primary user of that feature. It can be added back if there is demand for it. In exchange the per-family `CMakeLists.txt` files are now much easier to understand. --- BBAsm.cmake | 124 ------------- CMakeLists.txt | 10 +- README.md | 15 +- cmake/BBAsm.cmake | 164 ++++++++++++++++++ .../CodeCoverage.cmake | 0 cmake/FindApycula.cmake | 2 + cmake/FindIceStorm.cmake | 14 ++ cmake/FindOxide.cmake | 13 ++ cmake/FindTrellis.cmake | 63 +++++++ ecp5/CMakeLists.txt | 149 ++++------------ ecp5/family.cmake | 21 --- generic/{family.cmake => CMakeLists.txt} | 2 +- gowin/CMakeLists.txt | 79 ++++----- gowin/family.cmake | 21 --- himbaechel/{family.cmake => CMakeLists.txt} | 6 +- ice40/CMakeLists.txt | 130 ++++++-------- ice40/family.cmake | 21 --- machxo2/CMakeLists.txt | 146 +++++----------- machxo2/family.cmake | 24 --- mistral/{family.cmake => CMakeLists.txt} | 0 nexus/CMakeLists.txt | 86 ++++----- nexus/family.cmake | 21 --- 22 files changed, 465 insertions(+), 646 deletions(-) delete mode 100644 BBAsm.cmake create mode 100644 cmake/BBAsm.cmake rename CodeCoverage.cmake => cmake/CodeCoverage.cmake (100%) create mode 100644 cmake/FindApycula.cmake create mode 100644 cmake/FindIceStorm.cmake create mode 100644 cmake/FindOxide.cmake create mode 100644 cmake/FindTrellis.cmake delete mode 100644 ecp5/family.cmake rename generic/{family.cmake => CMakeLists.txt} (76%) delete mode 100644 gowin/family.cmake rename himbaechel/{family.cmake => CMakeLists.txt} (79%) delete mode 100644 ice40/family.cmake delete mode 100644 machxo2/family.cmake rename mistral/{family.cmake => CMakeLists.txt} (100%) delete mode 100644 nexus/family.cmake diff --git a/BBAsm.cmake b/BBAsm.cmake deleted file mode 100644 index 5cdaff9b..00000000 --- a/BBAsm.cmake +++ /dev/null @@ -1,124 +0,0 @@ -include(TestBigEndian) - -test_big_endian(IS_BIG_ENDIAN) -if (IS_BIG_ENDIAN) - set(BBASM_ENDIAN_FLAG "--be") -else() - set(BBASM_ENDIAN_FLAG "--le") -endif() - -# Example usage: -# -# add_bba_compile_command( -# TARGET chipdb-ice40 -# OUTPUT ice40/chipdb-hx8k.bin -# INPUT ice40/chipdb-hx8k.bba -# MODE binary -# ) -# -# All paths are relative to ${CMAKE_BINARY_DIR} (sic!). -# -function(add_bba_compile_command) - cmake_parse_arguments(arg "" "DEPENDS;TARGET;OUTPUT;INPUT;MODE" "" ${ARGN}) - - cmake_path(ABSOLUTE_PATH arg_INPUT BASE_DIRECTORY ${CMAKE_BINARY_DIR}) - - if (NOT arg_DEPENDS) - set(arg_DEPENDS ${arg_INPUT}) - endif() - - if (arg_MODE STREQUAL "binary" OR arg_MODE STREQUAL "resource") - - add_custom_command( - OUTPUT - ${CMAKE_BINARY_DIR}/${arg_OUTPUT} - COMMAND - bbasm ${BBASM_ENDIAN_FLAG} - ${arg_INPUT} - ${CMAKE_BINARY_DIR}/${arg_OUTPUT}.new - COMMAND - ${CMAKE_COMMAND} -E rename # atomic update - ${CMAKE_BINARY_DIR}/${arg_OUTPUT}.new - ${CMAKE_BINARY_DIR}/${arg_OUTPUT} - DEPENDS - bbasm - ${arg_DEPENDS} - VERBATIM - ) - - if (arg_MODE STREQUAL "resource") - - file(WRITE ${CMAKE_BINARY_DIR}/${arg_OUTPUT}.rc - "${arg_OUTPUT} RCDATA \"${CMAKE_BINARY_DIR}/${arg_OUTPUT}\"") - - target_sources( - ${arg_TARGET} PRIVATE - ${CMAKE_BINARY_DIR}/${arg_OUTPUT}.rc - ) - - else() - - target_sources( - ${arg_TARGET} PRIVATE - ${CMAKE_BINARY_DIR}/${arg_OUTPUT} - ) - - endif() - - elseif (arg_MODE STREQUAL "embed") - - add_custom_command( - OUTPUT - ${CMAKE_BINARY_DIR}/${arg_OUTPUT}.cc - ${CMAKE_BINARY_DIR}/${arg_OUTPUT} - COMMAND - bbasm ${BBASM_ENDIAN_FLAG} --e - ${arg_INPUT} - ${CMAKE_BINARY_DIR}/${arg_OUTPUT}.cc.new - ${CMAKE_BINARY_DIR}/${arg_OUTPUT}.new - COMMAND - ${CMAKE_COMMAND} -E rename # atomic update - ${CMAKE_BINARY_DIR}/${arg_OUTPUT}.cc.new - ${CMAKE_BINARY_DIR}/${arg_OUTPUT}.cc - COMMAND - ${CMAKE_COMMAND} -E rename # atomic update - ${CMAKE_BINARY_DIR}/${arg_OUTPUT}.new - ${CMAKE_BINARY_DIR}/${arg_OUTPUT} - DEPENDS - bbasm - ${arg_DEPENDS} - VERBATIM - ) - - target_sources( - ${arg_TARGET} PRIVATE - ${CMAKE_BINARY_DIR}/${arg_OUTPUT}.cc - ) - - elseif (arg_MODE STREQUAL "string") - - add_custom_command( - OUTPUT - ${CMAKE_BINARY_DIR}/${arg_OUTPUT}.cc - COMMAND - bbasm ${BBASM_ENDIAN_FLAG} --c - ${arg_INPUT} - ${CMAKE_BINARY_DIR}/${arg_OUTPUT}.cc.new - COMMAND - ${CMAKE_COMMAND} -E rename # atomic update - ${CMAKE_BINARY_DIR}/${arg_OUTPUT}.cc.new - ${CMAKE_BINARY_DIR}/${arg_OUTPUT}.cc - DEPENDS - bbasm - ${arg_DEPENDS} - VERBATIM - ) - - target_sources( - ${arg_TARGET} PRIVATE - ${CMAKE_BINARY_DIR}/${arg_OUTPUT}.cc - ) - - endif() - -endfunction() diff --git a/CMakeLists.txt b/CMakeLists.txt index f2c89e55..16cc3c1d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,8 @@ cmake_minimum_required(VERSION 3.25) project(nextpnr CXX) +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) + include(CheckCXXCompilerFlag) if (NOT DEFINED CMAKE_SUPPRESS_DEVELOPER_WARNINGS) @@ -22,6 +24,7 @@ option(USE_OPENMP "Use OpenMP to accelerate analytic placer" OFF) option(COVERAGE "Add code coverage info" OFF) option(STATIC_BUILD "Create static build" OFF) option(EXTERNAL_CHIPDB "Create build with pre-built chipdb binaries" OFF) +option(SERIALIZE_CHIPDBS "Serialize device data preprocessing to minimize memory use" ON) option(WERROR "pass -Werror to compiler (used for CI)" OFF) option(PROFILER "Link against libprofiler" OFF) option(USE_IPO "Compile nextpnr with IPO" ON) @@ -60,6 +63,8 @@ else() set(BBASM_MODE "string") endif() +set(BBASM_SERIALIZE ${SERIALIZE_CHIPDBS}) + find_package(Threads) if (Threads_FOUND) find_package(TBB QUIET) @@ -206,7 +211,7 @@ add_subdirectory(3rdparty/json11) add_subdirectory(3rdparty/oourafft) -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/3rdparty/sanitizers-cmake/cmake;${CMAKE_SOURCE_DIR}" ${CMAKE_MODULE_PATH}) +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/3rdparty/sanitizers-cmake/cmake" ${CMAKE_MODULE_PATH}) find_package(Sanitizers) if (COVERAGE) @@ -326,7 +331,8 @@ foreach (family ${ARCH}) endif() # Include the family-specific CMakeFile - include(${family}/family.cmake) + add_subdirectory(${family}) + # include(${family}/family.cmake) foreach (target ${family_targets}) foreach (lib_dep ${EXTRA_LIB_DEPS}) target_link_libraries(${target} PRIVATE ${lib_dep}) diff --git a/README.md b/README.md index a5db81a2..b012a1c1 100644 --- a/README.md +++ b/README.md @@ -163,7 +163,7 @@ sudo make install The nextpnr GUI is not built by default, to reduce the number of dependencies for a standard headless build. To enable it, add `-DBUILD_GUI=ON` to the CMake command line and ensure that Qt5 and OpenGL are available: - - On Ubuntu 22.04 LTS, install `qtcreator qtbase5-dev qt5-qmake` + - On Ubuntu 22.04 LTS, install `qtcreator qtbase5-dev qt5-qmake` - On other Ubuntu versions, install `qt5-default` - For MSVC vcpkg, install `qt5-base` (32-bit) or `qt5-base:x64-windows` (64-bit) - For Homebrew, install `qt5` and add qt5 in path: `echo 'export PATH="/usr/local/opt/qt/bin:$PATH"' >> ~/.bash_profile` @@ -181,19 +181,6 @@ sudo make install To build every available stable architecture, use `-DARCH=all`. To include experimental arches (currently nexus), use `-DARCH=all+alpha`. -Pre-generating chip databases ------------------------------ - -It is possible to pre-generate chip databases (`.bba` files). This can come in handy when building on time-constrained cloud instances, or in situations where Python is unable to use modules. To do this, build the architecture as a standalone project, which will produce the chip database alone. For example, for iCE40: - -``` -cd ice40 -cmake . -make -``` - -This will create a `chipdb` directory with `.bba` files. Provide the path to this directory when building nextpnr by using `-D_CHIPDB=/path/to/chipdb`. - Cross-compilation ----------------- diff --git a/cmake/BBAsm.cmake b/cmake/BBAsm.cmake new file mode 100644 index 00000000..c7d59446 --- /dev/null +++ b/cmake/BBAsm.cmake @@ -0,0 +1,164 @@ +include(TestBigEndian) + +test_big_endian(IS_BIG_ENDIAN) +if (IS_BIG_ENDIAN) + set(BBASM_ENDIAN_FLAG "--be") +else() + set(BBASM_ENDIAN_FLAG "--le") +endif() + +# Example usage (note the `.new`, used for atomic updates): +# +# add_bba_produce_command( +# COMMAND ${Python_EXECUTABLE} +# ${CMAKE_CURRENT_SOURCE_DIR}/chipdb.py +# -o ${CMAKE_CURRENT_BINARY_DIR}/chipdb-hx8k.bba.new +# OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/chipdb-hx8k.bba +# INPUTS ${CMAKE_CURRENT_SOURCE_DIR}/chipdb.py +# ) +# +# Paths must be absolute. +# +function(add_bba_produce_command) + cmake_parse_arguments(arg "" "OUTPUT" "COMMAND;INPUTS" ${ARGN}) + + cmake_path(GET arg_OUTPUT PARENT_PATH arg_OUTPUT_DIR) + file(MAKE_DIRECTORY ${arg_OUTPUT_DIR}) + + list(GET arg_COMMAND 0 arg_EXECUTABLE) + + add_custom_command( + OUTPUT + ${arg_OUTPUT} + COMMAND + ${arg_COMMAND} + COMMAND + ${CMAKE_COMMAND} -E rename # atomic update + ${arg_OUTPUT}.new + ${arg_OUTPUT} + DEPENDS + ${arg_EXECUTABLE} + ${arg_INPUTS} + $ENV{SERIALIZE_BBA_PRODUCE_COMMAND} + VERBATIM + ) + + if (BBASM_SERIALIZE) + set(ENV{SERIALIZE_BBA_PRODUCE_COMMAND} ${arg_OUTPUT}) + endif() + +endfunction() + +# Example usage: +# +# add_bba_compile_command( +# TARGET chipdb-ice40 +# OUTPUT ${CMAKE_BINARY_DIR}/chipdb/ice40/chipdb-1k.bin +# INPUT ${CMAKE_CURRENT_BINARY_DIR}/chipdb-1k.bba +# IDENT ice40/chipdb-1k.bba +# MODE binary +# ) +# +# Paths must be absolute. +# +function(add_bba_compile_command) + cmake_parse_arguments(arg "" "TARGET;OUTPUT;INPUT;IDENT;MODE" "" ${ARGN}) + + cmake_path(GET arg_OUTPUT PARENT_PATH arg_OUTPUT_DIR) + file(MAKE_DIRECTORY ${arg_OUTPUT_DIR}) + + if (arg_MODE STREQUAL "binary" OR arg_MODE STREQUAL "resource") + + add_custom_command( + OUTPUT + ${arg_OUTPUT} + COMMAND + bbasm ${BBASM_ENDIAN_FLAG} + ${arg_INPUT} + ${arg_OUTPUT}.new + COMMAND + ${CMAKE_COMMAND} -E rename # atomic update + ${arg_OUTPUT}.new + ${arg_OUTPUT} + DEPENDS + bbasm + ${arg_INPUT} + VERBATIM + ) + + if (arg_MODE STREQUAL "resource") + + file(WRITE ${arg_OUTPUT}.rc + "${arg_IDENT} RCDATA \"${arg_OUTPUT}\"") + + target_sources( + ${arg_TARGET} PRIVATE + ${arg_OUTPUT}.rc + ) + + else() + + target_sources( + ${arg_TARGET} PRIVATE + ${arg_OUTPUT} + ) + + endif() + + elseif (arg_MODE STREQUAL "embed") + + add_custom_command( + OUTPUT + ${arg_OUTPUT}.cc + ${arg_OUTPUT} + COMMAND + bbasm ${BBASM_ENDIAN_FLAG} --e + ${arg_INPUT} + ${arg_OUTPUT}.cc.new + ${arg_OUTPUT}.new + COMMAND + ${CMAKE_COMMAND} -E rename # atomic update + ${arg_OUTPUT}.cc.new + ${arg_OUTPUT}.cc + COMMAND + ${CMAKE_COMMAND} -E rename # atomic update + ${arg_OUTPUT}.new + ${arg_OUTPUT} + DEPENDS + bbasm + ${arg_INPUT} + VERBATIM + ) + + target_sources( + ${arg_TARGET} PRIVATE + ${arg_OUTPUT}.cc + ) + + elseif (arg_MODE STREQUAL "string") + + add_custom_command( + OUTPUT + ${arg_OUTPUT}.cc + COMMAND + bbasm ${BBASM_ENDIAN_FLAG} --c + ${arg_INPUT} + ${arg_OUTPUT}.cc.new + COMMAND + ${CMAKE_COMMAND} -E rename # atomic update + ${arg_OUTPUT}.cc.new + ${arg_OUTPUT}.cc + DEPENDS + bbasm + ${arg_INPUT} + VERBATIM + ) + + target_sources( + ${arg_TARGET} PRIVATE + ${arg_OUTPUT}.cc + ) + + endif() + +endfunction() diff --git a/CodeCoverage.cmake b/cmake/CodeCoverage.cmake similarity index 100% rename from CodeCoverage.cmake rename to cmake/CodeCoverage.cmake diff --git a/cmake/FindApycula.cmake b/cmake/FindApycula.cmake new file mode 100644 index 00000000..d63fd552 --- /dev/null +++ b/cmake/FindApycula.cmake @@ -0,0 +1,2 @@ +find_program (GOWIN_BBA_EXECUTABLE gowin_bba) +message(STATUS "gowin_bba executable: ${GOWIN_BBA_EXECUTABLE}") diff --git a/cmake/FindIceStorm.cmake b/cmake/FindIceStorm.cmake new file mode 100644 index 00000000..ac64d01a --- /dev/null +++ b/cmake/FindIceStorm.cmake @@ -0,0 +1,14 @@ +set(icestorm_default_install_prefix ${CMAKE_INSTALL_PREFIX}) +if (DEFINED ENV{ICESTORM_INSTALL_PREFIX}) + set(icestorm_default_install_prefix $ENV{ICESTORM_INSTALL_PREFIX}) +endif() +set(ICESTORM_INSTALL_PREFIX ${icestorm_default_install_prefix} CACHE STRING + "IceStorm install prefix") +message(STATUS "IceStorm install prefix: ${ICESTORM_INSTALL_PREFIX}") + +if (NOT ICEBOX_DATADIR) + set(ICEBOX_DATADIR ${ICESTORM_INSTALL_PREFIX}/share/icebox) +endif() +message(STATUS "icebox data directory: ${ICEBOX_DATADIR}") + +return(PROPAGATE ICEBOX_DATADIR) diff --git a/cmake/FindOxide.cmake b/cmake/FindOxide.cmake new file mode 100644 index 00000000..01dcbf14 --- /dev/null +++ b/cmake/FindOxide.cmake @@ -0,0 +1,13 @@ +if (DEFINED ENV{OXIDE_INSTALL_PREFIX}) + set(oxide_default_install_prefix $ENV{OXIDE_INSTALL_PREFIX}) +else() + set(oxide_default_install_prefix ${CMAKE_INSTALL_PREFIX}) +endif() +set(OXIDE_INSTALL_PREFIX "${oxide_default_install_prefix}" CACHE STRING + "prjoxide install prefix") +message(STATUS "prjoxide install prefix: ${OXIDE_INSTALL_PREFIX}") + +set(PRJOXIDE_TOOL ${OXIDE_INSTALL_PREFIX}/bin/prjoxide) +message(STATUS "prjoxide tool path: ${PRJOXIDE_TOOL}") + +return(PROPAGATE PRJOXIDE_TOOL) diff --git a/cmake/FindTrellis.cmake b/cmake/FindTrellis.cmake new file mode 100644 index 00000000..a7e29c4e --- /dev/null +++ b/cmake/FindTrellis.cmake @@ -0,0 +1,63 @@ +set(TRELLIS_PROGRAM_PREFIX "" CACHE STRING + "Trellis name prefix") +if (TRELLIS_PROGRAM_PREFIX) + message(STATUS "Trellis program prefix: ${TRELLIS_PROGRAM_PREFIX}") +endif() + +if (DEFINED ENV{TRELLIS_INSTALL_PREFIX}) + set(trellis_default_install_prefix $ENV{TRELLIS_INSTALL_PREFIX}) +else() + set(trellis_default_install_prefix ${CMAKE_INSTALL_PREFIX}) +endif() + +set(TRELLIS_INSTALL_PREFIX ${trellis_default_install_prefix} CACHE STRING + "Trellis install prefix") +message(STATUS "Trellis install prefix: ${TRELLIS_INSTALL_PREFIX}") + +if (NOT TRELLIS_LIBDIR) + # The pytrellis library isn't a normal shared library, but rather a native Python library; + # it does not follow the normal platform conventions for shared libraries, so we can't just + # use find_library() here. Instead, we emulate the useful parts of the find_library() logic + # for use with find_path(). + set(pytrellis_paths) + foreach (prefix_path ${CMAKE_PREFIX_PATH}) + list(APPEND pytrellis_paths ${prefix_path}/lib) + if (CMAKE_LIBRARY_ARCHITECTURE) + list(APPEND pytrellis_paths ${prefix_path}/lib/${CMAKE_LIBRARY_ARCHITECTURE}) + endif() + endforeach() + list(APPEND pytrellis_paths ${CMAKE_LIBRARY_PATH}) + if (NOT NO_CMAKE_SYSTEM_PATH) + foreach (prefix_path ${CMAKE_SYSTEM_PREFIX_PATH}) + list(APPEND pytrellis_paths ${prefix_path}/lib) + if (CMAKE_LIBRARY_ARCHITECTURE) + list(APPEND pytrellis_paths ${prefix_path}/lib/${CMAKE_LIBRARY_ARCHITECTURE}) + endif() + endforeach() + list(APPEND pytrellis_paths ${CMAKE_SYSTEM_LIBRARY_PATH}) + endif() + message(STATUS "Searching for pytrellis in: ${pytrellis_paths}") + + if (WIN32) + set(pytrellis_lib pytrellis.pyd) + else() + set(pytrellis_lib pytrellis${CMAKE_SHARED_MODULE_SUFFIX}) + endif() + + find_path(TRELLIS_LIBDIR ${pytrellis_lib} + HINTS ${TRELLIS_INSTALL_PREFIX}/lib/${TRELLIS_PROGRAM_PREFIX}trellis + PATHS ${pytrellis_paths} + PATH_SUFFIXES ${TRELLIS_PROGRAM_PREFIX}trellis + DOC "Location of the pytrellis library") + if (NOT TRELLIS_LIBDIR) + message(FATAL_ERROR "Failed to locate the pytrellis library") + endif() +endif() +message(STATUS "Trellis library directory: ${TRELLIS_LIBDIR}") + +if (NOT TRELLIS_DATADIR) + set(TRELLIS_DATADIR ${TRELLIS_INSTALL_PREFIX}/share/${TRELLIS_PROGRAM_PREFIX}trellis) +endif() +message(STATUS "Trellis data directory: ${TRELLIS_DATADIR}") + +return(PROPAGATE TRELLIS_LIBDIR TRELLIS_DATADIR) diff --git a/ecp5/CMakeLists.txt b/ecp5/CMakeLists.txt index e6f20806..72d8ebb1 100644 --- a/ecp5/CMakeLists.txt +++ b/ecp5/CMakeLists.txt @@ -1,120 +1,47 @@ -cmake_minimum_required(VERSION 3.25) -project(chipdb-ecp5 NONE) +include(FindTrellis) + +add_library(chipdb-${family} OBJECT) +target_compile_options(chipdb-${family} PRIVATE -w -g0 -O0) +target_compile_definitions(chipdb-${family} PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family}) +target_include_directories(chipdb-${family} PRIVATE .) + +foreach (family_target ${family_targets}) + target_link_libraries(${family_target} PRIVATE chipdb-${family}) +endforeach() set(ALL_ECP5_DEVICES 25k 45k 85k) set(ECP5_DEVICES ${ALL_ECP5_DEVICES} CACHE STRING "Include support for these ECP5 devices (available: ${ALL_ECP5_DEVICES})") message(STATUS "Enabled ECP5 devices: ${ECP5_DEVICES}") -if (DEFINED ECP5_CHIPDB) - add_custom_target(chipdb-ecp5-bbas ALL) -else() - # shared among all families - set(SERIALIZE_CHIPDBS TRUE CACHE BOOL - "Serialize device data preprocessing to minimize memory use") - - set(TRELLIS_PROGRAM_PREFIX "" CACHE STRING - "Trellis name prefix") - if (TRELLIS_PROGRAM_PREFIX) - message(STATUS "Trellis program prefix: ${TRELLIS_PROGRAM_PREFIX}") +foreach (device ${ECP5_DEVICES}) + if (NOT device IN_LIST ALL_ECP5_DEVICES) + message(FATAL_ERROR "Device ${device} is not a supported ECP5 device") endif() - if (DEFINED ENV{TRELLIS_INSTALL_PREFIX}) - set(trellis_default_install_prefix $ENV{TRELLIS_INSTALL_PREFIX}) - else() - set(trellis_default_install_prefix ${CMAKE_INSTALL_PREFIX}) - endif() + add_bba_produce_command( + COMMAND ${Python3_EXECUTABLE} + ${CMAKE_CURRENT_SOURCE_DIR}/trellis_import.py + -L ${TRELLIS_LIBDIR} + -L ${TRELLIS_DATADIR}/util/common + -L ${TRELLIS_DATADIR}/timing/util + -p ${CMAKE_CURRENT_SOURCE_DIR}/constids.inc + -g ${CMAKE_CURRENT_SOURCE_DIR}/gfx.h + ${device} + > ${CMAKE_CURRENT_BINARY_DIR}/chipdb-${device}.bba.new + OUTPUT + ${CMAKE_CURRENT_BINARY_DIR}/chipdb-${device}.bba + INPUTS + ${CMAKE_CURRENT_SOURCE_DIR}/trellis_import.py + ${CMAKE_CURRENT_SOURCE_DIR}/constids.inc + ${CMAKE_CURRENT_SOURCE_DIR}/gfx.h + ) - set(TRELLIS_INSTALL_PREFIX ${trellis_default_install_prefix} CACHE STRING - "Trellis install prefix") - message(STATUS "Trellis install prefix: ${TRELLIS_INSTALL_PREFIX}") - - if (NOT TRELLIS_LIBDIR) - # The pytrellis library isn't a normal shared library, but rather a native Python library; - # it does not follow the normal platform conventions for shared libraries, so we can't just - # use find_library() here. Instead, we emulate the useful parts of the find_library() logic - # for use with find_path(). - set(pytrellis_paths) - foreach (prefix_path ${CMAKE_PREFIX_PATH}) - list(APPEND pytrellis_paths ${prefix_path}/lib) - if (CMAKE_LIBRARY_ARCHITECTURE) - list(APPEND pytrellis_paths ${prefix_path}/lib/${CMAKE_LIBRARY_ARCHITECTURE}) - endif() - endforeach() - list(APPEND pytrellis_paths ${CMAKE_LIBRARY_PATH}) - if (NOT NO_CMAKE_SYSTEM_PATH) - foreach (prefix_path ${CMAKE_SYSTEM_PREFIX_PATH}) - list(APPEND pytrellis_paths ${prefix_path}/lib) - if (CMAKE_LIBRARY_ARCHITECTURE) - list(APPEND pytrellis_paths ${prefix_path}/lib/${CMAKE_LIBRARY_ARCHITECTURE}) - endif() - endforeach() - list(APPEND pytrellis_paths ${CMAKE_SYSTEM_LIBRARY_PATH}) - endif() - message(STATUS "Searching for pytrellis in: ${pytrellis_paths}") - - if (WIN32) - set(pytrellis_lib pytrellis.pyd) - else() - set(pytrellis_lib pytrellis${CMAKE_SHARED_MODULE_SUFFIX}) - endif() - - find_path(TRELLIS_LIBDIR ${pytrellis_lib} - HINTS ${TRELLIS_INSTALL_PREFIX}/lib/${TRELLIS_PROGRAM_PREFIX}trellis - PATHS ${pytrellis_paths} - PATH_SUFFIXES ${TRELLIS_PROGRAM_PREFIX}trellis - DOC "Location of the pytrellis library") - if (NOT TRELLIS_LIBDIR) - message(FATAL_ERROR "Failed to locate the pytrellis library") - endif() - endif() - message(STATUS "Trellis library directory: ${TRELLIS_LIBDIR}") - - if (NOT TRELLIS_DATADIR) - set(TRELLIS_DATADIR ${TRELLIS_INSTALL_PREFIX}/share/${TRELLIS_PROGRAM_PREFIX}trellis) - endif() - message(STATUS "Trellis data directory: ${TRELLIS_DATADIR}") - - set(all_device_bbas) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chipdb) - foreach (device ${ECP5_DEVICES}) - if (NOT device IN_LIST ALL_ECP5_DEVICES) - message(FATAL_ERROR "Device ${device} is not a supported ECP5 device") - endif() - - set(device_bba chipdb/chipdb-${device}.bba) - add_custom_command( - OUTPUT ${device_bba} - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/trellis_import.py - -L ${TRELLIS_LIBDIR} - -L ${TRELLIS_DATADIR}/util/common - -L ${TRELLIS_DATADIR}/timing/util - -p ${CMAKE_CURRENT_SOURCE_DIR}/constids.inc - -g ${CMAKE_CURRENT_SOURCE_DIR}/gfx.h - ${device} - > ${device_bba}.new - # atomically update - COMMAND ${CMAKE_COMMAND} -E rename ${device_bba}.new ${device_bba} - DEPENDS - ${CMAKE_CURRENT_SOURCE_DIR}/trellis_import.py - ${CMAKE_CURRENT_SOURCE_DIR}/constids.inc - ${CMAKE_CURRENT_SOURCE_DIR}/gfx.h - ${PREVIOUS_CHIPDB_TARGET} - VERBATIM) - list(APPEND all_device_bbas ${device_bba}) - if (SERIALIZE_CHIPDBS) - set(PREVIOUS_CHIPDB_TARGET ${CMAKE_CURRENT_BINARY_DIR}/${device_bba}) - endif() - endforeach() - - add_custom_target(chipdb-ecp5-bbas ALL DEPENDS ${all_device_bbas}) - - get_directory_property(has_parent PARENT_DIRECTORY) - if (has_parent) - set(ECP5_CHIPDB ${CMAKE_CURRENT_BINARY_DIR}/chipdb PARENT_SCOPE) - # serialize chipdb build across multiple architectures - set(PREVIOUS_CHIPDB_TARGET chipdb-ecp5-bbas PARENT_SCOPE) - else() - message(STATUS "Build nextpnr with -DECP5_CHIPDB=${CMAKE_CURRENT_BINARY_DIR}/chipdb") - endif() -endif() + add_bba_compile_command( + TARGET chipdb-${family} + OUTPUT ${CMAKE_BINARY_DIR}/share/${family}/chipdb-${device}.bin + INPUT ${CMAKE_CURRENT_BINARY_DIR}/chipdb-${device}.bba + IDENT ${family}/chipdb-${device}.bin + MODE ${BBASM_MODE} + ) +endforeach() diff --git a/ecp5/family.cmake b/ecp5/family.cmake deleted file mode 100644 index 9ad95208..00000000 --- a/ecp5/family.cmake +++ /dev/null @@ -1,21 +0,0 @@ -add_subdirectory(${family}) -message(STATUS "Using ECP5 chipdb: ${ECP5_CHIPDB}") - -add_library(chipdb-${family} OBJECT) -target_compile_options(chipdb-${family} PRIVATE -w -g0 -O0) -target_compile_definitions(chipdb-${family} PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family}) -target_include_directories(chipdb-${family} PRIVATE ${family}) - -foreach (family_target ${family_targets}) - target_link_libraries(${family_target} PRIVATE chipdb-${family}) -endforeach() - -foreach (device ${ECP5_DEVICES}) - add_bba_compile_command( - DEPENDS chipdb-${family}-bbas - TARGET chipdb-${family} - OUTPUT ${family}/chipdb-${device}.bin - INPUT ${ECP5_CHIPDB}/chipdb-${device}.bba - MODE ${BBASM_MODE} - ) -endforeach() diff --git a/generic/family.cmake b/generic/CMakeLists.txt similarity index 76% rename from generic/family.cmake rename to generic/CMakeLists.txt index f6f6e030..2ca2269f 100644 --- a/generic/family.cmake +++ b/generic/CMakeLists.txt @@ -1,6 +1,6 @@ set(VIADUCT_UARCHES "example" "okami" "fabulous") foreach (uarch ${VIADUCT_UARCHES}) - aux_source_directory(${family}/viaduct/${uarch} UARCH_FILES) + aux_source_directory(viaduct/${uarch} UARCH_FILES) foreach (target ${family_targets}) target_sources(${target} PRIVATE ${UARCH_FILES}) endforeach() diff --git a/gowin/CMakeLists.txt b/gowin/CMakeLists.txt index 2a78250a..7d168b70 100644 --- a/gowin/CMakeLists.txt +++ b/gowin/CMakeLists.txt @@ -1,53 +1,40 @@ -cmake_minimum_required(VERSION 3.25) -project(chipdb-gowin NONE) +include(FindApycula) + +add_library(chipdb-${family} OBJECT) +target_compile_options(chipdb-${family} PRIVATE -w -g0 -O0) +target_compile_definitions(chipdb-${family} PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family}) +target_include_directories(chipdb-${family} PRIVATE .) + +foreach (family_target ${family_targets}) + target_link_libraries(${family_target} PRIVATE chipdb-${family}) +endforeach() set(ALL_GOWIN_DEVICES GW1N-1 GW1NZ-1 GW1N-4 GW1N-9 GW1N-9C GW1NS-2 GW1NS-4 GW2A-18) set(GOWIN_DEVICES ${ALL_GOWIN_DEVICES} CACHE STRING "Include support for these Gowin devices (available: ${ALL_GOWIN_DEVICES})") message(STATUS "Enabled Gowin devices: ${GOWIN_DEVICES}") -find_program (GOWIN_BBA_EXECUTABLE gowin_bba) -message(STATUS "gowin_bba executable: ${GOWIN_BBA_EXECUTABLE}") - -if (DEFINED GOWIN_CHIPDB) - add_custom_target(chipdb-gowin-bbas ALL) -else() - # shared among all families - set(SERIALIZE_CHIPDBS TRUE CACHE BOOL - "Serialize device data preprocessing to minimize memory use") - - set(all_device_bbas) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chipdb) - foreach (device ${GOWIN_DEVICES}) - if (NOT device IN_LIST ALL_GOWIN_DEVICES) - message(FATAL_ERROR "Device ${device} is not a supported Gowin device") - endif() - - set(device_bba chipdb/chipdb-${device}.bba) - add_custom_command( - OUTPUT ${device_bba} - COMMAND ${GOWIN_BBA_EXECUTABLE} -d ${device} -i ${CMAKE_CURRENT_SOURCE_DIR}/constids.inc -o ${device_bba}.new - # atomically update - COMMAND ${CMAKE_COMMAND} -E rename ${device_bba}.new ${device_bba} - DEPENDS - ${GOWIN_BBA_EXECUTABLE} - ${PREVIOUS_CHIPDB_TARGET} - ${CMAKE_CURRENT_SOURCE_DIR}/constids.inc - VERBATIM) - list(APPEND all_device_bbas ${device_bba}) - if (SERIALIZE_CHIPDBS) - set(PREVIOUS_CHIPDB_TARGET ${CMAKE_CURRENT_BINARY_DIR}/${device_bba}) - endif() - endforeach() - - add_custom_target(chipdb-gowin-bbas ALL DEPENDS ${all_device_bbas}) - - get_directory_property(has_parent PARENT_DIRECTORY) - if (has_parent) - set(GOWIN_CHIPDB ${CMAKE_CURRENT_BINARY_DIR}/chipdb PARENT_SCOPE) - # serialize chipdb build across multiple architectures - set(PREVIOUS_CHIPDB_TARGET chipdb-gowin-bbas PARENT_SCOPE) - else() - message(STATUS "Build nextpnr with -DGOWIN_CHIPDB=${CMAKE_CURRENT_BINARY_DIR}/chipdb") +foreach (device ${GOWIN_DEVICES}) + if (NOT device IN_LIST ALL_GOWIN_DEVICES) + message(FATAL_ERROR "Device ${device} is not a supported Gowin device") endif() -endif() + + add_bba_produce_command( + COMMAND ${GOWIN_BBA_EXECUTABLE} + -d ${device} + -i ${CMAKE_CURRENT_SOURCE_DIR}/constids.inc + -o ${CMAKE_CURRENT_BINARY_DIR}/chipdb-${device}.bba.new + OUTPUT + ${CMAKE_CURRENT_BINARY_DIR}/chipdb-${device}.bba + INPUTS + ${CMAKE_CURRENT_SOURCE_DIR}/constids.inc + ) + + add_bba_compile_command( + TARGET chipdb-${family} + OUTPUT ${CMAKE_BINARY_DIR}/share/${family}/chipdb-${device}.bin + INPUT ${CMAKE_CURRENT_BINARY_DIR}/chipdb-${device}.bba + IDENT ${family}/chipdb-${device}.bin + MODE ${BBASM_MODE} + ) +endforeach() diff --git a/gowin/family.cmake b/gowin/family.cmake deleted file mode 100644 index 33fd97d9..00000000 --- a/gowin/family.cmake +++ /dev/null @@ -1,21 +0,0 @@ -add_subdirectory(${family}) -message(STATUS "Using Gowin chipdb: ${GOWIN_CHIPDB}") - -add_library(chipdb-${family} OBJECT) -target_compile_options(chipdb-${family} PRIVATE -w -g0 -O0) -target_compile_definitions(chipdb-${family} PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family}) -target_include_directories(chipdb-${family} PRIVATE ${family}) - -foreach (family_target ${family_targets}) - target_link_libraries(${family_target} PRIVATE chipdb-${family}) -endforeach() - -foreach (device ${GOWIN_DEVICES}) - add_bba_compile_command( - DEPENDS chipdb-${family}-bbas - TARGET chipdb-${family} - OUTPUT ${family}/chipdb-${device}.bin - INPUT ${GOWIN_CHIPDB}/chipdb-${device}.bba - MODE ${BBASM_MODE} - ) -endforeach() diff --git a/himbaechel/family.cmake b/himbaechel/CMakeLists.txt similarity index 79% rename from himbaechel/family.cmake rename to himbaechel/CMakeLists.txt index 99eb7a12..441452a8 100644 --- a/himbaechel/family.cmake +++ b/himbaechel/CMakeLists.txt @@ -10,14 +10,14 @@ foreach (item ${HIMBAECHEL_UARCH}) endforeach() foreach (uarch ${HIMBAECHEL_UARCH}) - add_subdirectory(${family}/uarch/${uarch}) - aux_source_directory(${family}/uarch/${uarch} HM_UARCH_FILES) + add_subdirectory(uarch/${uarch}) + aux_source_directory(uarch/${uarch} HM_UARCH_FILES) foreach (target ${family_targets}) target_sources(${target} PRIVATE ${HM_UARCH_FILES}) endforeach() if (BUILD_TESTS) foreach (target ${family_test_targets}) - aux_source_directory(${family}/uarch/${uarch}/tests/ HM_UARCH_TEST_FILES) + aux_source_directory(uarch/${uarch}/tests/ HM_UARCH_TEST_FILES) target_sources(${target} PRIVATE ${HM_UARCH_TEST_FILES}) endforeach() endif() diff --git a/ice40/CMakeLists.txt b/ice40/CMakeLists.txt index 12cf0561..95d472d1 100644 --- a/ice40/CMakeLists.txt +++ b/ice40/CMakeLists.txt @@ -1,90 +1,60 @@ -cmake_minimum_required(VERSION 3.25) -project(chipdb-ice40 NONE) +include(FindIceStorm) + +add_library(chipdb-${family} OBJECT) +target_compile_options(chipdb-${family} PRIVATE -w -g0 -O0) +target_compile_definitions(chipdb-${family} PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family}) +target_include_directories(chipdb-${family} PRIVATE .) + +foreach (family_target ${family_targets}) + target_link_libraries(${family_target} PRIVATE chipdb-${family}) +endforeach() set(ALL_ICE40_DEVICES 384 1k 5k u4k 8k) set(ICE40_DEVICES ${ALL_ICE40_DEVICES} CACHE STRING "Include support for these iCE40 devices (available: ${ALL_ICE40_DEVICES})") message(STATUS "Enabled iCE40 devices: ${ICE40_DEVICES}") -if (DEFINED ICE40_CHIPDB) - add_custom_target(chipdb-ice40-bbas ALL) -else() - # shared among all families - set(SERIALIZE_CHIPDBS TRUE CACHE BOOL - "Serialize device data preprocessing to minimize memory use") - - set(icestorm_default_install_prefix ${CMAKE_INSTALL_PREFIX}) - # for compatibility with old build scripts - if (DEFINED ICEBOX_ROOT) - message(WARNING "-DICEBOX_ROOT= is deprecated, use -DICESTORM_INSTALL_PREFIX=${ICEBOX_ROOT} instead") - get_filename_component(dir ${ICEBOX_ROOT} DIRECTORY) - get_filename_component(dir ${dir} DIRECTORY) - set(icestorm_default_install_prefix ${dir}) - elseif (DEFINED ENV{ICESTORM_INSTALL_PREFIX}) - set(icestorm_default_install_prefix $ENV{ICESTORM_INSTALL_PREFIX}) +foreach (device ${ICE40_DEVICES}) + if (NOT device IN_LIST ALL_ICE40_DEVICES) + message(FATAL_ERROR "Device ${device} is not a supported iCE40 device") endif() - set(ICESTORM_INSTALL_PREFIX ${icestorm_default_install_prefix} CACHE STRING - "IceStorm install prefix") - message(STATUS "IceStorm install prefix: ${ICESTORM_INSTALL_PREFIX}") - if (NOT ICEBOX_DATADIR) - set(ICEBOX_DATADIR ${ICESTORM_INSTALL_PREFIX}/share/icebox) - endif() - message(STATUS "icebox data directory: ${ICEBOX_DATADIR}") - - set(all_device_bbas) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chipdb) - foreach (device ${ICE40_DEVICES}) - if (NOT device IN_LIST ALL_ICE40_DEVICES) - message(FATAL_ERROR "Device ${device} is not a supported iCE40 device") - endif() - - if (device STREQUAL "5k") - set(timing_opts - --slow ${ICEBOX_DATADIR}/timings_up5k.txt) - elseif (device STREQUAL "u4k") - set(timing_opts - --slow ${ICEBOX_DATADIR}/timings_u4k.txt) - elseif (device STREQUAL "384") - set(timing_opts - --slow ${ICEBOX_DATADIR}/timings_lp384.txt) - else() - set(timing_opts - --fast ${ICEBOX_DATADIR}/timings_hx${device}.txt - --slow ${ICEBOX_DATADIR}/timings_lp${device}.txt) - endif() - - set(device_bba chipdb/chipdb-${device}.bba) - add_custom_command( - OUTPUT ${device_bba} - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/chipdb.py - -p ${CMAKE_CURRENT_SOURCE_DIR}/constids.inc - -g ${CMAKE_CURRENT_SOURCE_DIR}/gfx.h - ${timing_opts} - ${ICEBOX_DATADIR}/chipdb-${device}.txt - > ${device_bba}.new - # atomically update - COMMAND ${CMAKE_COMMAND} -E rename ${device_bba}.new ${device_bba} - DEPENDS - ${CMAKE_CURRENT_SOURCE_DIR}/chipdb.py - ${CMAKE_CURRENT_SOURCE_DIR}/constids.inc - ${CMAKE_CURRENT_SOURCE_DIR}/gfx.h - ${PREVIOUS_CHIPDB_TARGET} - VERBATIM) - list(APPEND all_device_bbas ${device_bba}) - if (SERIALIZE_CHIPDBS) - set(PREVIOUS_CHIPDB_TARGET ${CMAKE_CURRENT_BINARY_DIR}/${device_bba}) - endif() - endforeach() - - add_custom_target(chipdb-ice40-bbas ALL DEPENDS ${all_device_bbas}) - - get_directory_property(has_parent PARENT_DIRECTORY) - if (has_parent) - set(ICE40_CHIPDB ${CMAKE_CURRENT_BINARY_DIR}/chipdb PARENT_SCOPE) - # serialize chipdb build across multiple architectures - set(PREVIOUS_CHIPDB_TARGET chipdb-ice40-bbas PARENT_SCOPE) + if (device STREQUAL "5k") + set(timing_opts + --slow ${ICEBOX_DATADIR}/timings_up5k.txt) + elseif (device STREQUAL "u4k") + set(timing_opts + --slow ${ICEBOX_DATADIR}/timings_u4k.txt) + elseif (device STREQUAL "384") + set(timing_opts + --slow ${ICEBOX_DATADIR}/timings_lp384.txt) else() - message(STATUS "Build nextpnr with -DICE40_CHIPDB=${CMAKE_CURRENT_BINARY_DIR}/chipdb") + set(timing_opts + --fast ${ICEBOX_DATADIR}/timings_hx${device}.txt + --slow ${ICEBOX_DATADIR}/timings_lp${device}.txt) endif() -endif() + + add_bba_produce_command( + COMMAND ${Python3_EXECUTABLE} + ${CMAKE_CURRENT_SOURCE_DIR}/chipdb.py + -p ${CMAKE_CURRENT_SOURCE_DIR}/constids.inc + -g ${CMAKE_CURRENT_SOURCE_DIR}/gfx.h + ${timing_opts} + ${ICEBOX_DATADIR}/chipdb-${device}.txt + > ${CMAKE_CURRENT_BINARY_DIR}/chipdb-${device}.bba.new + OUTPUT + ${CMAKE_CURRENT_BINARY_DIR}/chipdb-${device}.bba + INPUTS + ${CMAKE_CURRENT_SOURCE_DIR}/chipdb.py + ${CMAKE_CURRENT_SOURCE_DIR}/constids.inc + ${CMAKE_CURRENT_SOURCE_DIR}/gfx.h + ) + + add_bba_compile_command( + TARGET chipdb-${family} + OUTPUT ${CMAKE_BINARY_DIR}/share/${family}/chipdb-${device}.bin + INPUT ${CMAKE_CURRENT_BINARY_DIR}/chipdb-${device}.bba + IDENT ${family}/chipdb-${device}.bin + MODE ${BBASM_MODE} + ) +endforeach() diff --git a/ice40/family.cmake b/ice40/family.cmake deleted file mode 100644 index 942796e3..00000000 --- a/ice40/family.cmake +++ /dev/null @@ -1,21 +0,0 @@ -add_subdirectory(${family}) -message(STATUS "Using iCE40 chipdb: ${ICE40_CHIPDB}") - -add_library(chipdb-${family} OBJECT) -target_compile_options(chipdb-${family} PRIVATE -w -g0 -O0) -target_compile_definitions(chipdb-${family} PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family}) -target_include_directories(chipdb-${family} PRIVATE ${family}) - -foreach (family_target ${family_targets}) - target_link_libraries(${family_target} PRIVATE chipdb-${family}) -endforeach() - -foreach (device ${ICE40_DEVICES}) - add_bba_compile_command( - DEPENDS chipdb-${family}-bbas - TARGET chipdb-${family} - OUTPUT ${family}/chipdb-${device}.bin - INPUT ${ICE40_CHIPDB}/chipdb-${device}.bba - MODE ${BBASM_MODE} - ) -endforeach() diff --git a/machxo2/CMakeLists.txt b/machxo2/CMakeLists.txt index 98cfe0cd..148b36fb 100644 --- a/machxo2/CMakeLists.txt +++ b/machxo2/CMakeLists.txt @@ -1,114 +1,52 @@ -cmake_minimum_required(VERSION 3.25) -project(chipdb-machxo2 NONE) +include(FindTrellis) +add_library(chipdb-${family} OBJECT) +target_compile_options(chipdb-${family} PRIVATE -w -g0 -O0) +target_compile_definitions(chipdb-${family} PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family}) +target_include_directories(chipdb-${family} PRIVATE .) + +foreach (family_target ${family_targets}) + target_link_libraries(${family_target} PRIVATE chipdb-${family}) +endforeach() + +# Note that the four *X (MachXO) devices fail to import with prjtrellis commit 14ac883fa. set(ALL_MACHXO2_DEVICES 256X 640X 1200X 2280X 256 640 1200 2000 4000 7000 1300 2100 4300 6900 9400 4300D 9400D) set(MACHXO2_DEVICES 1200 6900 CACHE STRING "Include support for these MachXO2/XO3 devices (available: ${ALL_MACHXO2_DEVICES})") message(STATUS "Enabled MachXO2/XO3 devices: ${MACHXO2_DEVICES}") -if (DEFINED MACHXO2_CHIPDB) - add_custom_target(chipdb-machxo2-bbas ALL) -else() - # shared among all families - set(SERIALIZE_CHIPDBS TRUE CACHE BOOL - "Serialize device data preprocessing to minimize memory use") +configure_file(machxo2_available.h.in ${CMAKE_CURRENT_BINARY_DIR}/generated/machxo2_available.h) +target_sources(chipdb-${family} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/generated/machxo2_available.h) +target_include_directories(chipdb-${family} PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/generated) - set(TRELLIS_PROGRAM_PREFIX "" CACHE STRING - "Trellis name prefix") - if (TRELLIS_PROGRAM_PREFIX) - message(STATUS "Trellis program prefix: ${TRELLIS_PROGRAM_PREFIX}") +foreach (device ${MACHXO2_DEVICES}) + if (NOT device IN_LIST ALL_MACHXO2_DEVICES) + message(FATAL_ERROR "Device ${device} is not a supported MachXO2/XO3 device") endif() - set(TRELLIS_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX} CACHE STRING - "Trellis install prefix") - message(STATUS "Trellis install prefix: ${TRELLIS_INSTALL_PREFIX}") + add_bba_produce_command( + COMMAND ${Python3_EXECUTABLE} + ${CMAKE_CURRENT_SOURCE_DIR}/facade_import.py + -L ${TRELLIS_LIBDIR} + -L ${TRELLIS_DATADIR}/util/common + -L ${TRELLIS_DATADIR}/timing/util + -p ${CMAKE_CURRENT_SOURCE_DIR}/constids.inc + -g ${CMAKE_CURRENT_SOURCE_DIR}/gfx.h + ${device} + > ${CMAKE_CURRENT_BINARY_DIR}/chipdb-${device}.bba.new + OUTPUT + ${CMAKE_CURRENT_BINARY_DIR}/chipdb-${device}.bba + INPUTS + ${CMAKE_CURRENT_SOURCE_DIR}/facade_import.py + ${CMAKE_CURRENT_SOURCE_DIR}/constids.inc + ${CMAKE_CURRENT_SOURCE_DIR}/gfx.h + ) - if (NOT TRELLIS_LIBDIR) - # The pytrellis library isn't a normal shared library, but rather a native Python library; - # it does not follow the normal platform conventions for shared libraries, so we can't just - # use find_library() here. Instead, we emulate the useful parts of the find_library() logic - # for use with find_path(). - set(pytrellis_paths) - foreach (prefix_path ${CMAKE_PREFIX_PATH}) - list(APPEND pytrellis_paths ${prefix_path}/lib) - if (CMAKE_LIBRARY_ARCHITECTURE) - list(APPEND pytrellis_paths ${prefix_path}/lib/${CMAKE_LIBRARY_ARCHITECTURE}) - endif() - endforeach() - list(APPEND pytrellis_paths ${CMAKE_LIBRARY_PATH}) - if (NOT NO_CMAKE_SYSTEM_PATH) - foreach (prefix_path ${CMAKE_SYSTEM_PREFIX_PATH}) - list(APPEND pytrellis_paths ${prefix_path}/lib) - if (CMAKE_LIBRARY_ARCHITECTURE) - list(APPEND pytrellis_paths ${prefix_path}/lib/${CMAKE_LIBRARY_ARCHITECTURE}) - endif() - endforeach() - list(APPEND pytrellis_paths ${CMAKE_SYSTEM_LIBRARY_PATH}) - endif() - message(STATUS "Searching for pytrellis in: ${pytrellis_paths}") - - if (WIN32) - set(pytrellis_lib pytrellis.pyd) - else() - set(pytrellis_lib pytrellis${CMAKE_SHARED_MODULE_SUFFIX}) - endif() - - find_path(TRELLIS_LIBDIR ${pytrellis_lib} - HINTS ${TRELLIS_INSTALL_PREFIX}/lib/${TRELLIS_PROGRAM_PREFIX}trellis - PATHS ${pytrellis_paths} - PATH_SUFFIXES ${TRELLIS_PROGRAM_PREFIX}trellis - DOC "Location of the pytrellis library") - if (NOT TRELLIS_LIBDIR) - message(FATAL_ERROR "Failed to locate the pytrellis library") - endif() - endif() - message(STATUS "Trellis library directory: ${TRELLIS_LIBDIR}") - - if (NOT TRELLIS_DATADIR) - set(TRELLIS_DATADIR ${TRELLIS_INSTALL_PREFIX}/share/${TRELLIS_PROGRAM_PREFIX}trellis) - endif() - message(STATUS "Trellis data directory: ${TRELLIS_DATADIR}") - - set(all_device_bbas) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chipdb) - foreach (device ${MACHXO2_DEVICES}) - if (NOT device IN_LIST ALL_MACHXO2_DEVICES) - message(FATAL_ERROR "Device ${device} is not a supported MachXO2/XO3 device") - endif() - - set(device_bba chipdb/chipdb-${device}.bba) - add_custom_command( - OUTPUT ${device_bba} - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/facade_import.py - -L ${TRELLIS_LIBDIR} - -L ${TRELLIS_DATADIR}/util/common - -L ${TRELLIS_DATADIR}/timing/util - -p ${CMAKE_CURRENT_SOURCE_DIR}/constids.inc - -g ${CMAKE_CURRENT_SOURCE_DIR}/gfx.h - ${device} - > ${device_bba}.new - # atomically update - COMMAND ${CMAKE_COMMAND} -E rename ${device_bba}.new ${device_bba} - DEPENDS - ${CMAKE_CURRENT_SOURCE_DIR}/facade_import.py - ${CMAKE_CURRENT_SOURCE_DIR}/constids.inc - ${CMAKE_CURRENT_SOURCE_DIR}/gfx.h - ${PREVIOUS_CHIPDB_TARGET} - VERBATIM) - list(APPEND all_device_bbas ${device_bba}) - if (SERIALIZE_CHIPDBS) - set(PREVIOUS_CHIPDB_TARGET ${CMAKE_CURRENT_BINARY_DIR}/${device_bba}) - endif() - endforeach() - - add_custom_target(chipdb-machxo2-bbas ALL DEPENDS ${all_device_bbas}) - - get_directory_property(has_parent PARENT_DIRECTORY) - if (has_parent) - set(MACHXO2_CHIPDB ${CMAKE_CURRENT_BINARY_DIR}/chipdb PARENT_SCOPE) - # serialize chipdb build across multiple architectures - set(PREVIOUS_CHIPDB_TARGET chipdb-machxo2-bbas PARENT_SCOPE) - else() - message(STATUS "Build nextpnr with -DMACHXO2_CHIPDB=${CMAKE_CURRENT_BINARY_DIR}/chipdb") - endif() -endif() + add_bba_compile_command( + TARGET chipdb-${family} + OUTPUT ${CMAKE_BINARY_DIR}/share/${family}/chipdb-${device}.bin + INPUT ${CMAKE_CURRENT_BINARY_DIR}/chipdb-${device}.bba + IDENT ${family}/chipdb-${device}.bin + MODE ${BBASM_MODE} + ) +endforeach() diff --git a/machxo2/family.cmake b/machxo2/family.cmake deleted file mode 100644 index f2b46a43..00000000 --- a/machxo2/family.cmake +++ /dev/null @@ -1,24 +0,0 @@ -add_subdirectory(${family}) -message(STATUS "Using MachXO2/XO3 chipdb: ${MACHXO2_CHIPDB}") - -add_library(chipdb-${family} OBJECT) -target_compile_options(chipdb-${family} PRIVATE -w -g0 -O0) -target_compile_definitions(chipdb-${family} PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family}) -target_include_directories(chipdb-${family} PRIVATE ${family}) - -configure_file(${family}/machxo2_available.h.in ${CMAKE_CURRENT_BINARY_DIR}/generated/machxo2_available.h) -target_sources(chipdb-${family} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/generated/machxo2_available.h) - -foreach (family_target ${family_targets}) - target_link_libraries(${family_target} PRIVATE chipdb-${family}) -endforeach() - -foreach (device ${MACHXO2_DEVICES}) - add_bba_compile_command( - DEPENDS chipdb-${family}-bbas - TARGET chipdb-${family} - OUTPUT ${family}/chipdb-${device}.bin - INPUT ${MACHXO2_CHIPDB}/chipdb-${device}.bba - MODE ${BBASM_MODE} - ) -endforeach() diff --git a/mistral/family.cmake b/mistral/CMakeLists.txt similarity index 100% rename from mistral/family.cmake rename to mistral/CMakeLists.txt diff --git a/nexus/CMakeLists.txt b/nexus/CMakeLists.txt index c1cec4d0..e801ae13 100644 --- a/nexus/CMakeLists.txt +++ b/nexus/CMakeLists.txt @@ -1,62 +1,42 @@ -cmake_minimum_required(VERSION 3.25) -project(chipdb-nexus NONE) - -set(ALL_NEXUS_FAMILIES LIFCL) +include(FindOxide) # NOTE: Unlike iCE40 and ECP5; one database can cover all densities of a given family - +set(ALL_NEXUS_FAMILIES LIFCL) set(NEXUS_FAMILIES ${ALL_NEXUS_FAMILIES} CACHE STRING "Include support for these Nexus families (available: ${ALL_NEXUS_FAMILIES})") message(STATUS "Enabled Nexus families: ${NEXUS_FAMILIES}") -if (DEFINED NEXUS_CHIPDB) - add_custom_target(chipdb-nexus-bbas ALL) -else() - # shared among all families - if (DEFINED ENV{OXIDE_INSTALL_PREFIX}) - set(oxide_default_install_prefix $ENV{OXIDE_INSTALL_PREFIX}) - else() - set(oxide_default_install_prefix ${CMAKE_INSTALL_PREFIX}) +add_library(chipdb-${family} OBJECT) +target_compile_options(chipdb-${family} PRIVATE -w -g0 -O0) +target_compile_definitions(chipdb-${family} PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family}) +target_include_directories(chipdb-${family} PRIVATE .) + +foreach (family_target ${family_targets}) + target_link_libraries(${family_target} PRIVATE chipdb-${family}) +endforeach() + +foreach (subfamily ${NEXUS_FAMILIES}) + if (NOT subfamily IN_LIST ALL_NEXUS_FAMILIES) + message(FATAL_ERROR "${subfamily} is not a supported Nexus family") endif() - set(OXIDE_INSTALL_PREFIX "${oxide_default_install_prefix}" CACHE STRING - "prjoxide install prefix") - message(STATUS "prjoxide install prefix: ${OXIDE_INSTALL_PREFIX}") - set(all_device_bbas) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chipdb) - foreach (subfamily ${NEXUS_FAMILIES}) - if (NOT subfamily IN_LIST ALL_NEXUS_FAMILIES) - message(FATAL_ERROR "${subfamily} is not a supported Nexus family") - endif() + add_bba_produce_command( + COMMAND ${PRJOXIDE_TOOL} + bba-export ${subfamily} + ${CMAKE_CURRENT_SOURCE_DIR}/constids.inc + ${CMAKE_CURRENT_BINARY_DIR}/chipdb-${subfamily}.bba.new + OUTPUT + ${CMAKE_CURRENT_BINARY_DIR}/chipdb-${subfamily}.bba + INPUTS + ${CMAKE_CURRENT_SOURCE_DIR}/bba_version.inc + ${CMAKE_CURRENT_SOURCE_DIR}/constids.inc + ) - set(family_bba chipdb/chipdb-${subfamily}.bba) - set(PRJOXIDE_TOOL ${OXIDE_INSTALL_PREFIX}/bin/prjoxide) - add_custom_command( - OUTPUT ${family_bba} - COMMAND - ${PRJOXIDE_TOOL} bba-export ${subfamily} ${CMAKE_CURRENT_SOURCE_DIR}/constids.inc ${family_bba}.new - # atomically update - COMMAND ${CMAKE_COMMAND} -E rename ${family_bba}.new ${family_bba} - DEPENDS - ${PRJOXIDE_TOOL} - ${CMAKE_CURRENT_SOURCE_DIR}/constids.inc - ${CMAKE_CURRENT_SOURCE_DIR}/bba_version.inc - ${PREVIOUS_CHIPDB_TARGET} - VERBATIM) - list(APPEND all_device_bbas ${family_bba}) - if (SERIALIZE_CHIPDBS) - set(PREVIOUS_CHIPDB_TARGET ${CMAKE_CURRENT_BINARY_DIR}/${family_bba}) - endif() - endforeach() - - add_custom_target(chipdb-nexus-bbas ALL DEPENDS ${all_device_bbas}) - - get_directory_property(has_parent PARENT_DIRECTORY) - if (has_parent) - set(NEXUS_CHIPDB ${CMAKE_CURRENT_BINARY_DIR}/chipdb PARENT_SCOPE) - # serialize chipdb build across multiple architectures - set(PREVIOUS_CHIPDB_TARGET chipdb-nexus-bbas PARENT_SCOPE) - else() - message(STATUS "Build nextpnr with -DNEXUS_CHIPDB=${CMAKE_CURRENT_BINARY_DIR}/chipdb") - endif() -endif() + add_bba_compile_command( + TARGET chipdb-${family} + OUTPUT ${CMAKE_BINARY_DIR}/share/${family}/chipdb-${subfamily}.bin + INPUT ${CMAKE_CURRENT_BINARY_DIR}/chipdb-${subfamily}.bba + IDENT ${family}/chipdb-${subfamily}.bin + MODE ${BBASM_MODE} + ) +endforeach() diff --git a/nexus/family.cmake b/nexus/family.cmake deleted file mode 100644 index 68049662..00000000 --- a/nexus/family.cmake +++ /dev/null @@ -1,21 +0,0 @@ -add_subdirectory(${family}) -message(STATUS "Using Nexus chipdb: ${NEXUS_CHIPDB}") - -add_library(chipdb-${family} OBJECT) -target_compile_options(chipdb-${family} PRIVATE -w -g0 -O0) -target_compile_definitions(chipdb-${family} PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family}) -target_include_directories(chipdb-${family} PRIVATE ${family}) - -foreach (family_target ${family_targets}) - target_link_libraries(${family_target} PRIVATE chipdb-${family}) -endforeach() - -foreach (subfamily ${NEXUS_FAMILIES}) - add_bba_compile_command( - DEPENDS chipdb-${family}-bbas - TARGET chipdb-${family} - OUTPUT ${family}/chipdb-${subfamily}.bin - INPUT ${NEXUS_CHIPDB}/chipdb-${subfamily}.bba - MODE ${BBASM_MODE} - ) -endforeach()