From 9affda5626e8207952076b8b12d2981e4bc8533e Mon Sep 17 00:00:00 2001 From: David Shah Date: Thu, 15 Oct 2020 12:10:02 +0100 Subject: [PATCH] nexus: Build and embed chipdb automatically Signed-off-by: David Shah --- CMakeLists.txt | 1 + nexus/.gitignore | 1 + nexus/CMakeLists.txt | 57 ++++++++++++++++++++++++++++++++++++++++++++ nexus/arch.cc | 19 ++++++--------- nexus/arch.h | 1 - nexus/family.cmake | 53 ++++++++++++++++++++++++++++++++++++++++ nexus/main.cc | 2 -- 7 files changed, 119 insertions(+), 15 deletions(-) create mode 100644 nexus/.gitignore create mode 100644 nexus/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index fa46956b..29f73f47 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -286,6 +286,7 @@ endforeach (family) file(GLOB_RECURSE CLANGFORMAT_FILES *.cc *.h) string(REGEX REPLACE "[^;]*/ice40/chipdb/chipdb-[^;]*.cc" "" CLANGFORMAT_FILES "${CLANGFORMAT_FILES}") string(REGEX REPLACE "[^;]*/ecp5/chipdb/chipdb-[^;]*.cc" "" CLANGFORMAT_FILES "${CLANGFORMAT_FILES}") +string(REGEX REPLACE "[^;]*nexus/chipdb/chipdb-[^;]*.cc" "" CLANGFORMAT_FILES "${CLANGFORMAT_FILES}") string(REGEX REPLACE "[^;]*/3rdparty[^;]*" "" CLANGFORMAT_FILES "${CLANGFORMAT_FILES}") string(REGEX REPLACE "[^;]*/generated[^;]*" "" CLANGFORMAT_FILES "${CLANGFORMAT_FILES}") diff --git a/nexus/.gitignore b/nexus/.gitignore new file mode 100644 index 00000000..0cb37421 --- /dev/null +++ b/nexus/.gitignore @@ -0,0 +1 @@ +/chipdb/ diff --git a/nexus/CMakeLists.txt b/nexus/CMakeLists.txt new file mode 100644 index 00000000..30796cfc --- /dev/null +++ b/nexus/CMakeLists.txt @@ -0,0 +1,57 @@ +cmake_minimum_required(VERSION 3.5) +project(chipdb-nexus NONE) + +set(ALL_NEXUS_FAMILIES LIFCL) + +# NOTE: Unlike iCE40 and ECP5; one database can cover all densities of a given family + +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 + set(OXIDE_ROOT "" CACHE STRING + "prjoxide root folder") + message(STATUS "prjoxide root folder: ${OXIDE_ROOT}") + + 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() + + set(family_bba chipdb/chipdb-${subfamily}.bba) + set(BBA_TOOL ${OXIDE_ROOT}/libprjoxide/target/release/oxide_bbaexport) + add_custom_command( + OUTPUT ${family_bba} + COMMAND + ${BBA_TOOL} ${subfamily} ${CMAKE_CURRENT_SOURCE_DIR}/constids.inc ${family_bba}.new + # atomically update + COMMAND ${CMAKE_COMMAND} -E rename ${family_bba}.new ${family_bba} + DEPENDS + ${BBA_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() diff --git a/nexus/arch.cc b/nexus/arch.cc index 63977d6f..40efa62d 100644 --- a/nexus/arch.cc +++ b/nexus/arch.cc @@ -20,6 +20,7 @@ #include +#include "embed.h" #include "log.h" #include "nextpnr.h" #include "placer1.h" @@ -43,8 +44,6 @@ static std::tuple split_identifier_name(const std::string name.substr(second_slash + 1)); }; -static const DatabasePOD *get_chipdb(const RelPtr *ptr) { return ptr->get(); } - } // namespace // ----------------------------------------------------------------------- @@ -78,16 +77,12 @@ Arch::Arch(ArchArgs args) : args(args) log_error("Unknown device string '%s' (expected device name like 'LIFCL-40-8SG72C')\n", args.device.c_str()); package = args.device.substr(last_sep + 2, (package_end - (last_sep + 2)) + 1); rating = args.device.substr(package_end + 1); - // Load database (FIXME: baked-in databases too) - try { - blob_file.open(args.chipdb); - if (!blob_file.is_open()) - log_error("Unable to read chipdb %s\n", args.chipdb.c_str()); - const char *blob = reinterpret_cast(blob_file.data()); - db = get_chipdb(reinterpret_cast *>(blob)); - } catch (...) { - log_error("Unable to read chipdb %s\n", args.chipdb.c_str()); - } + // Load database + std::string chipdb = stringf("nexus/chipdb-%s.bin", family.c_str()); + auto db_ptr = reinterpret_cast *>(get_chipdb(chipdb)); + if (db_ptr == nullptr) + log_error("Failed to load chipdb '%s'\n", chipdb.c_str()); + db = db_ptr->get(); // Check database version and family if (db->version != bba_version) { log_error("Provided database version %d is %s than nextpnr version %d, please rebuild database/nextpnr.\n", diff --git a/nexus/arch.h b/nexus/arch.h index d5481bac..71114f62 100644 --- a/nexus/arch.h +++ b/nexus/arch.h @@ -820,7 +820,6 @@ const int bba_version = struct ArchArgs { - std::string chipdb; std::string device; }; diff --git a/nexus/family.cmake b/nexus/family.cmake index e69de29b..4ee65dbc 100644 --- a/nexus/family.cmake +++ b/nexus/family.cmake @@ -0,0 +1,53 @@ +add_subdirectory(${family}) +message(STATUS "Using Nexus chipdb: ${NEXUS_CHIPDB}") + +set(chipdb_sources) +set(chipdb_binaries) +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${family}/chipdb) +foreach(subfamily ${NEXUS_FAMILIES}) + set(chipdb_bba ${NEXUS_CHIPDB}/chipdb-${subfamily}.bba) + set(chipdb_bin ${family}/chipdb/chipdb-${subfamily}.bin) + set(chipdb_cc ${family}/chipdb/chipdb-${subfamily}.cc) + if(BBASM_MODE STREQUAL "binary") + add_custom_command( + OUTPUT ${chipdb_bin} + COMMAND bbasm ${BBASM_ENDIAN_FLAG} ${chipdb_bba} ${chipdb_bin} + DEPENDS bbasm chipdb-${family}-bbas ${chipdb_bba}) + list(APPEND chipdb_binaries ${chipdb_bin}) + elseif(BBASM_MODE STREQUAL "embed") + add_custom_command( + OUTPUT ${chipdb_cc} ${chipdb_bin} + COMMAND bbasm ${BBASM_ENDIAN_FLAG} --e ${chipdb_bba} ${chipdb_cc} ${chipdb_bin} + DEPENDS bbasm chipdb-${family}-bbas ${chipdb_bba}) + list(APPEND chipdb_sources ${chipdb_cc}) + list(APPEND chipdb_binaries ${chipdb_bin}) + elseif(BBASM_MODE STREQUAL "string") + add_custom_command( + OUTPUT ${chipdb_cc} + COMMAND bbasm ${BBASM_ENDIAN_FLAG} --c ${chipdb_bba} ${chipdb_cc} + DEPENDS bbasm chipdb-${family}-bbas ${chipdb_bba}) + list(APPEND chipdb_sources ${chipdb_cc}) + endif() +endforeach() +if(WIN32) + set(chipdb_rc ${CMAKE_CURRENT_BINARY_DIR}/${family}/resource/chipdb.rc) + list(APPEND chipdb_sources ${chipdb_rc}) + + file(WRITE ${chipdb_rc}) + foreach(subfamily ${NEXUS_FAMILIES}) + file(APPEND ${chipdb_rc} + "${family}/chipdb-${subfamily}.bin RCDATA \"${CMAKE_CURRENT_BINARY_DIR}/${family}/chipdb/chipdb-${subfamily}.bin\"") + endforeach() +endif() + +add_custom_target(chipdb-${family}-bins DEPENDS ${chipdb_sources} ${chipdb_binaries}) + +add_library(chipdb-${family} OBJECT ${NEXUS_CHIPDB} ${chipdb_sources}) +add_dependencies(chipdb-${family} chipdb-${family}-bins) +target_compile_options(chipdb-${family} PRIVATE -g0 -O0 -w) +target_compile_definitions(chipdb-${family} PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family}) +target_include_directories(chipdb-${family} PRIVATE ${family}) + +foreach(family_target ${family_targets}) + target_sources(${family_target} PRIVATE $) +endforeach() diff --git a/nexus/main.cc b/nexus/main.cc index 83b22977..5b0ba94c 100644 --- a/nexus/main.cc +++ b/nexus/main.cc @@ -47,7 +47,6 @@ NexusCommandHandler::NexusCommandHandler(int argc, char **argv) : CommandHandler po::options_description NexusCommandHandler::getArchOptions() { po::options_description specific("Architecture specific options"); - specific.add_options()("chipdb", po::value(), "name of chip database binary"); specific.add_options()("device", po::value(), "device name"); specific.add_options()("fasm", po::value(), "fasm file to write"); specific.add_options()("pdc", po::value(), "physical constraints file"); @@ -68,7 +67,6 @@ void NexusCommandHandler::customBitstream(Context *ctx) std::unique_ptr NexusCommandHandler::createContext(std::unordered_map &values) { ArchArgs chipArgs; - chipArgs.chipdb = vm["chipdb"].as(); chipArgs.device = vm["device"].as(); return std::unique_ptr(new Context(chipArgs)); }