aboutsummaryrefslogtreecommitdiffstats
path: root/nexus
diff options
context:
space:
mode:
authorDavid Shah <dave@ds0.me>2020-10-15 12:10:02 +0100
committerDavid Shah <dave@ds0.me>2020-11-30 08:45:27 +0000
commit9affda5626e8207952076b8b12d2981e4bc8533e (patch)
treeaec5756059fcdfa96c97bab2da75306caf5fb0b5 /nexus
parent7645354917b93417ebeef974f5ca8961c9a1a3c8 (diff)
downloadnextpnr-9affda5626e8207952076b8b12d2981e4bc8533e.tar.gz
nextpnr-9affda5626e8207952076b8b12d2981e4bc8533e.tar.bz2
nextpnr-9affda5626e8207952076b8b12d2981e4bc8533e.zip
nexus: Build and embed chipdb automatically
Signed-off-by: David Shah <dave@ds0.me>
Diffstat (limited to 'nexus')
-rw-r--r--nexus/.gitignore1
-rw-r--r--nexus/CMakeLists.txt57
-rw-r--r--nexus/arch.cc19
-rw-r--r--nexus/arch.h1
-rw-r--r--nexus/family.cmake53
-rw-r--r--nexus/main.cc2
6 files changed, 118 insertions, 15 deletions
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 <boost/algorithm/string.hpp>
+#include "embed.h"
#include "log.h"
#include "nextpnr.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));
};
-static const DatabasePOD *get_chipdb(const RelPtr<DatabasePOD> *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<const char *>(blob_file.data());
- db = get_chipdb(reinterpret_cast<const RelPtr<DatabasePOD> *>(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<const RelPtr<DatabasePOD> *>(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 $<TARGET_OBJECTS:chipdb-${family}>)
+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<std::string>(), "name of chip database binary");
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()("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)
{
ArchArgs chipArgs;
- chipArgs.chipdb = vm["chipdb"].as<std::string>();
chipArgs.device = vm["device"].as<std::string>();
return std::unique_ptr<Context>(new Context(chipArgs));
}