nexus: Build and embed chipdb automatically

Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
David Shah 2020-10-15 12:10:02 +01:00
parent 7645354917
commit 9affda5626
7 changed files with 119 additions and 15 deletions

View File

@ -286,6 +286,7 @@ endforeach (family)
file(GLOB_RECURSE CLANGFORMAT_FILES *.cc *.h) file(GLOB_RECURSE CLANGFORMAT_FILES *.cc *.h)
string(REGEX REPLACE "[^;]*/ice40/chipdb/chipdb-[^;]*.cc" "" CLANGFORMAT_FILES "${CLANGFORMAT_FILES}") 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 "[^;]*/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 "[^;]*/3rdparty[^;]*" "" CLANGFORMAT_FILES "${CLANGFORMAT_FILES}")
string(REGEX REPLACE "[^;]*/generated[^;]*" "" CLANGFORMAT_FILES "${CLANGFORMAT_FILES}") string(REGEX REPLACE "[^;]*/generated[^;]*" "" CLANGFORMAT_FILES "${CLANGFORMAT_FILES}")

1
nexus/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/chipdb/

57
nexus/CMakeLists.txt Normal file
View File

@ -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()

View File

@ -20,6 +20,7 @@
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include "embed.h"
#include "log.h" #include "log.h"
#include "nextpnr.h" #include "nextpnr.h"
#include "placer1.h" #include "placer1.h"
@ -43,8 +44,6 @@ static std::tuple<int, int, std::string> split_identifier_name(const std::string
name.substr(second_slash + 1)); name.substr(second_slash + 1));
}; };
static const DatabasePOD *get_chipdb(const RelPtr<DatabasePOD> *ptr) { return ptr->get(); }
} // namespace } // 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()); 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); package = args.device.substr(last_sep + 2, (package_end - (last_sep + 2)) + 1);
rating = args.device.substr(package_end + 1); rating = args.device.substr(package_end + 1);
// Load database (FIXME: baked-in databases too) // Load database
try { std::string chipdb = stringf("nexus/chipdb-%s.bin", family.c_str());
blob_file.open(args.chipdb); auto db_ptr = reinterpret_cast<const RelPtr<DatabasePOD> *>(get_chipdb(chipdb));
if (!blob_file.is_open()) if (db_ptr == nullptr)
log_error("Unable to read chipdb %s\n", args.chipdb.c_str()); log_error("Failed to load chipdb '%s'\n", chipdb.c_str());
const char *blob = reinterpret_cast<const char *>(blob_file.data()); db = db_ptr->get();
db = get_chipdb(reinterpret_cast<const RelPtr<DatabasePOD> *>(blob));
} catch (...) {
log_error("Unable to read chipdb %s\n", args.chipdb.c_str());
}
// Check database version and family // Check database version and family
if (db->version != bba_version) { if (db->version != bba_version) {
log_error("Provided database version %d is %s than nextpnr version %d, please rebuild database/nextpnr.\n", log_error("Provided database version %d is %s than nextpnr version %d, please rebuild database/nextpnr.\n",

View File

@ -820,7 +820,6 @@ const int bba_version =
struct ArchArgs struct ArchArgs
{ {
std::string chipdb;
std::string device; std::string device;
}; };

View File

@ -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 $<TARGET_OBJECTS:chipdb-${family}>)
endforeach()

View File

@ -47,7 +47,6 @@ NexusCommandHandler::NexusCommandHandler(int argc, char **argv) : CommandHandler
po::options_description NexusCommandHandler::getArchOptions() po::options_description NexusCommandHandler::getArchOptions()
{ {
po::options_description specific("Architecture specific options"); po::options_description specific("Architecture specific options");
specific.add_options()("chipdb", po::value<std::string>(), "name of chip database binary");
specific.add_options()("device", po::value<std::string>(), "device name"); specific.add_options()("device", po::value<std::string>(), "device name");
specific.add_options()("fasm", po::value<std::string>(), "fasm file to write"); specific.add_options()("fasm", po::value<std::string>(), "fasm file to write");
specific.add_options()("pdc", po::value<std::string>(), "physical constraints file"); specific.add_options()("pdc", po::value<std::string>(), "physical constraints file");
@ -68,7 +67,6 @@ void NexusCommandHandler::customBitstream(Context *ctx)
std::unique_ptr<Context> NexusCommandHandler::createContext(std::unordered_map<std::string, Property> &values) std::unique_ptr<Context> NexusCommandHandler::createContext(std::unordered_map<std::string, Property> &values)
{ {
ArchArgs chipArgs; ArchArgs chipArgs;
chipArgs.chipdb = vm["chipdb"].as<std::string>();
chipArgs.device = vm["device"].as<std::string>(); chipArgs.device = vm["device"].as<std::string>();
return std::unique_ptr<Context>(new Context(chipArgs)); return std::unique_ptr<Context>(new Context(chipArgs));
} }