aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwhitequark <whitequark@whitequark.org>2020-06-25 15:11:47 +0000
committerwhitequark <whitequark@whitequark.org>2020-06-26 08:36:07 +0000
commit89e0cc8078ecbb57ca450cc6c8a40f6b634b8c9c (patch)
treee34454964eff6bf4d14f40b4f1c271cadea6d1fa
parentdc209f6344545196de8bf4de7abff2fcbd55732e (diff)
downloadnextpnr-89e0cc8078ecbb57ca450cc6c8a40f6b634b8c9c.tar.gz
nextpnr-89e0cc8078ecbb57ca450cc6c8a40f6b634b8c9c.tar.bz2
nextpnr-89e0cc8078ecbb57ca450cc6c8a40f6b634b8c9c.zip
Simplify and improve chipdb embedding/loading.
-rw-r--r--common/embed.cc46
-rw-r--r--common/embed.h50
-rw-r--r--ecp5/arch.cc82
-rw-r--r--ecp5/arch.h13
-rw-r--r--ecp5/family.cmake11
-rw-r--r--ecp5/main.cc30
-rw-r--r--ecp5/resource/chipdb.rc5
-rw-r--r--ecp5/resource/embed.cc28
-rw-r--r--ecp5/resource/resource.h4
-rwxr-xr-xecp5/trellis_import.py2
-rw-r--r--gui/ecp5/mainwindow.cc56
-rw-r--r--gui/ice40/family.cmake3
-rw-r--r--gui/ice40/mainwindow.cc63
-rw-r--r--ice40/arch.cc106
-rw-r--r--ice40/arch.h17
-rw-r--r--ice40/chipdb.py2
-rw-r--r--ice40/family.cmake14
-rw-r--r--ice40/main.cc30
-rw-r--r--ice40/resource/chipdb.rc7
-rw-r--r--ice40/resource/embed.cc32
-rw-r--r--ice40/resource/resource.h6
21 files changed, 266 insertions, 341 deletions
diff --git a/common/embed.cc b/common/embed.cc
new file mode 100644
index 00000000..f8f439b5
--- /dev/null
+++ b/common/embed.cc
@@ -0,0 +1,46 @@
+#if defined(WIN32)
+#include <windows.h>
+#endif
+#include <boost/iostreams/device/mapped_file.hpp>
+#include <boost/filesystem.hpp>
+#include "nextpnr.h"
+#include "embed.h"
+
+NEXTPNR_NAMESPACE_BEGIN
+
+#if defined(EXTERNAL_CHIPDB_ROOT)
+
+const void *get_chipdb(const std::string &filename) {
+ static std::map<std::string, boost::iostreams::mapped_file> files;
+ if (!files.count(filename)) {
+ std::string full_filename = EXTERNAL_CHIPDB_ROOT "/" + filename;
+ if (boost::filesystem::exists(full_filename))
+ files[filename].open(full_filename, boost::iostreams::mapped_file::priv);
+ }
+ if (files.count(filename))
+ return files.at(filename).data();
+ return nullptr;
+}
+
+#elif defined(WIN32)
+
+const void *get_chipdb(const std::string &filename) {
+ HRSRC rc = ::FindResource(nullptr, filename.c_str(), RT_RCDATA);
+ HGLOBAL rcData = ::LoadResource(nullptr, rc);
+ return ::LockResource(rcData);
+}
+
+#else
+
+EmbeddedFile *EmbeddedFile::head = nullptr;
+
+const void *get_chipdb(const std::string &filename) {
+ for (EmbeddedFile *file = EmbeddedFile::head; file; file = file->next)
+ if (file->filename == filename)
+ return file->content;
+ return nullptr;
+}
+
+#endif
+
+NEXTPNR_NAMESPACE_END
diff --git a/common/embed.h b/common/embed.h
new file mode 100644
index 00000000..6111bf1f
--- /dev/null
+++ b/common/embed.h
@@ -0,0 +1,50 @@
+/*
+ * nextpnr -- Next Generation Place and Route
+ *
+ * Copyright (C) 2020 whitequark <whitequark@whitequark.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#ifndef EMBED_H
+#define EMBED_H
+
+#include "nextpnr.h"
+NEXTPNR_NAMESPACE_BEGIN
+
+#if !defined(EXTERNAL_CHIPDB_ROOT) && !defined(WIN32)
+
+struct EmbeddedFile
+{
+ static EmbeddedFile *head;
+
+ std::string filename;
+ const void *content;
+ EmbeddedFile *next = nullptr;
+
+ EmbeddedFile(const std::string &filename, const void *content)
+ : filename(filename), content(content)
+ {
+ next = head;
+ head = this;
+ }
+};
+
+#endif
+
+const void *get_chipdb(const std::string &filename);
+
+NEXTPNR_NAMESPACE_END
+
+#endif // EMBED_H
diff --git a/ecp5/arch.cc b/ecp5/arch.cc
index f947783e..a9ffd1e9 100644
--- a/ecp5/arch.cc
+++ b/ecp5/arch.cc
@@ -27,6 +27,7 @@
#include "globals.h"
#include "log.h"
#include "nextpnr.h"
+#include "embed.h"
#include "placer1.h"
#include "placer_heap.h"
#include "router1.h"
@@ -60,69 +61,52 @@ void IdString::initialize_arch(const BaseCtx *ctx)
// -----------------------------------------------------------------------
-static const ChipInfoPOD *get_chip_info(const RelPtr<ChipInfoPOD> *ptr) { return ptr->get(); }
-
-#if defined(WIN32)
-void load_chipdb();
-#endif
-
-#if defined(EXTERNAL_CHIPDB_ROOT)
-const char *chipdb_blob_25k = nullptr;
-const char *chipdb_blob_45k = nullptr;
-const char *chipdb_blob_85k = nullptr;
+static const ChipInfoPOD *get_chip_info(ArchArgs::ArchArgsTypes chip) {
+ std::string chipdb;
+ if (chip == ArchArgs::LFE5U_12F || chip == ArchArgs::LFE5U_25F ||
+ chip == ArchArgs::LFE5UM_25F || chip == ArchArgs::LFE5UM5G_25F) {
+ chipdb = "ecp5/chipdb-25k.bin";
+ } else if (chip == ArchArgs::LFE5U_45F ||
+ chip == ArchArgs::LFE5UM_45F || chip == ArchArgs::LFE5UM5G_45F) {
+ chipdb = "ecp5/chipdb-45k.bin";
+ } else if (chip == ArchArgs::LFE5U_85F ||
+ chip == ArchArgs::LFE5UM_85F || chip == ArchArgs::LFE5UM5G_85F) {
+ chipdb = "ecp5/chipdb-85k.bin";
+ } else {
+ log_error("Unknown chip\n");
+ }
-boost::iostreams::mapped_file blob_files[3];
+ auto ptr = reinterpret_cast<const RelPtr<ChipInfoPOD> *>(get_chipdb(chipdb));
+ if (ptr == nullptr)
+ return nullptr;
+ return ptr->get();
+}
-const char *mmap_file(int index, const char *filename)
+bool Arch::isAvailable(ArchArgs::ArchArgsTypes chip)
{
- try {
- // WASI only supports MAP_PRIVATE
- blob_files[index].open(filename, boost::iostreams::mapped_file::priv);
- if (!blob_files[index].is_open())
- log_error("Unable to read chipdb %s\n", filename);
- return (const char *)blob_files[index].data();
- } catch (...) {
- log_error("Unable to read chipdb %s\n", filename);
- }
+ return get_chip_info(chip) != nullptr;
}
-void load_chipdb()
+std::vector<std::string> Arch::getSupportedPackages(ArchArgs::ArchArgsTypes chip)
{
- chipdb_blob_25k = mmap_file(0, EXTERNAL_CHIPDB_ROOT "/ecp5/chipdb-25k.bin");
- chipdb_blob_45k = mmap_file(1, EXTERNAL_CHIPDB_ROOT "/ecp5/chipdb-45k.bin");
- chipdb_blob_85k = mmap_file(2, EXTERNAL_CHIPDB_ROOT "/ecp5/chipdb-85k.bin");
+ const ChipInfoPOD *chip_info = get_chip_info(chip);
+ std::vector<std::string> packages;
+ for (int i = 0; i < chip_info->num_packages; i++)
+ packages.push_back(chip_info->package_info[i].name.get());
+ return packages;
}
-#endif
-//#define LFE5U_45F_ONLY
+
+// -----------------------------------------------------------------------
Arch::Arch(ArchArgs args) : args(args)
{
-#if defined(WIN32) || defined(EXTERNAL_CHIPDB_ROOT)
- load_chipdb();
-#endif
-#ifdef LFE5U_45F_ONLY
- if (args.type == ArchArgs::LFE5U_45F) {
- chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_45k));
- } else {
- log_error("Unsupported ECP5 chip type.\n");
- }
-#else
- if (args.type == ArchArgs::LFE5U_12F || args.type == ArchArgs::LFE5U_25F || args.type == ArchArgs::LFE5UM_25F ||
- args.type == ArchArgs::LFE5UM5G_25F) {
- chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_25k));
- } else if (args.type == ArchArgs::LFE5U_45F || args.type == ArchArgs::LFE5UM_45F ||
- args.type == ArchArgs::LFE5UM5G_45F) {
- chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_45k));
- } else if (args.type == ArchArgs::LFE5U_85F || args.type == ArchArgs::LFE5UM_85F ||
- args.type == ArchArgs::LFE5UM5G_85F) {
- chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_85k));
- } else {
+ chip_info = get_chip_info(args.type);
+ if (chip_info == nullptr)
log_error("Unsupported ECP5 chip type.\n");
- }
-#endif
if (chip_info->const_id_count != DB_CONST_ID_COUNT)
log_error("Chip database 'bba' and nextpnr code are out of sync; please rebuild (or contact distribution "
"maintainer)!\n");
+
package_info = nullptr;
for (int i = 0; i < chip_info->num_packages; i++) {
if (args.package == chip_info->package_info[i].name.get()) {
diff --git a/ecp5/arch.h b/ecp5/arch.h
index c13f2041..0f351319 100644
--- a/ecp5/arch.h
+++ b/ecp5/arch.h
@@ -207,16 +207,6 @@ NPNR_PACKED_STRUCT(struct ChipInfoPOD {
RelPtr<SpeedGradePOD> speed_grades;
});
-#if defined(WIN32) || defined(EXTERNAL_CHIPDB_ROOT)
-extern const char *chipdb_blob_25k;
-extern const char *chipdb_blob_45k;
-extern const char *chipdb_blob_85k;
-#else
-extern const char chipdb_blob_25k[];
-extern const char chipdb_blob_45k[];
-extern const char chipdb_blob_85k[];
-#endif
-
/************************ End of chipdb section. ************************/
struct BelIterator
@@ -494,6 +484,9 @@ struct Arch : BaseCtx
ArchArgs args;
Arch(ArchArgs args);
+ static bool isAvailable(ArchArgs::ArchArgsTypes chip);
+ static std::vector<std::string> getSupportedPackages(ArchArgs::ArchArgsTypes chip);
+
std::string getChipName() const;
std::string getFullChipName() const;
diff --git a/ecp5/family.cmake b/ecp5/family.cmake
index 0f96811a..cc97ae5e 100644
--- a/ecp5/family.cmake
+++ b/ecp5/family.cmake
@@ -30,9 +30,14 @@ foreach(device ${ECP5_DEVICES})
endif()
endforeach()
if(WIN32)
- list(APPEND chipdb_sources
- ${CMAKE_CURRENT_SOURCE_DIR}/${family}/resource/embed.cc
- ${CMAKE_CURRENT_SOURCE_DIR}/${family}/resource/chipdb.rc)
+ set(chipdb_rc ${CMAKE_CURRENT_BINARY_DIR}/${family}/resource/chipdb.rc)
+ list(APPEND chipdb_sources ${chipdb_rc})
+
+ file(WRITE ${chipdb_rc})
+ foreach(device ${ECP5_DEVICES})
+ file(APPEND ${chipdb_rc}
+ "${family}/chipdb-${device}.bin RCDATA \"${CMAKE_CURRENT_BINARY_DIR}/${family}/chipdb/chipdb-${device}.bin\"")
+ endforeach()
endif()
add_custom_target(chipdb-${family}-bins DEPENDS ${chipdb_sources} ${chipdb_binaries})
diff --git a/ecp5/main.cc b/ecp5/main.cc
index f1cb9760..311f5401 100644
--- a/ecp5/main.cc
+++ b/ecp5/main.cc
@@ -49,16 +49,26 @@ ECP5CommandHandler::ECP5CommandHandler(int argc, char **argv) : CommandHandler(a
po::options_description ECP5CommandHandler::getArchOptions()
{
po::options_description specific("Architecture specific options");
- specific.add_options()("12k", "set device type to LFE5U-12F");
- specific.add_options()("25k", "set device type to LFE5U-25F");
- specific.add_options()("45k", "set device type to LFE5U-45F");
- specific.add_options()("85k", "set device type to LFE5U-85F");
- specific.add_options()("um-25k", "set device type to LFE5UM-25F");
- specific.add_options()("um-45k", "set device type to LFE5UM-45F");
- specific.add_options()("um-85k", "set device type to LFE5UM-85F");
- specific.add_options()("um5g-25k", "set device type to LFE5UM5G-25F");
- specific.add_options()("um5g-45k", "set device type to LFE5UM5G-45F");
- specific.add_options()("um5g-85k", "set device type to LFE5UM5G-85F");
+ if (Arch::isAvailable(ArchArgs::LFE5U_12F))
+ specific.add_options()("12k", "set device type to LFE5U-12F");
+ if (Arch::isAvailable(ArchArgs::LFE5U_25F))
+ specific.add_options()("25k", "set device type to LFE5U-25F");
+ if (Arch::isAvailable(ArchArgs::LFE5U_45F))
+ specific.add_options()("45k", "set device type to LFE5U-45F");
+ if (Arch::isAvailable(ArchArgs::LFE5U_85F))
+ specific.add_options()("85k", "set device type to LFE5U-85F");
+ if (Arch::isAvailable(ArchArgs::LFE5UM_25F))
+ specific.add_options()("um-25k", "set device type to LFE5UM-25F");
+ if (Arch::isAvailable(ArchArgs::LFE5UM_45F))
+ specific.add_options()("um-45k", "set device type to LFE5UM-45F");
+ if (Arch::isAvailable(ArchArgs::LFE5UM_85F))
+ specific.add_options()("um-85k", "set device type to LFE5UM-85F");
+ if (Arch::isAvailable(ArchArgs::LFE5UM5G_25F))
+ specific.add_options()("um5g-25k", "set device type to LFE5UM5G-25F");
+ if (Arch::isAvailable(ArchArgs::LFE5UM5G_45F))
+ specific.add_options()("um5g-45k", "set device type to LFE5UM5G-45F");
+ if (Arch::isAvailable(ArchArgs::LFE5UM5G_85F))
+ specific.add_options()("um5g-85k", "set device type to LFE5UM5G-85F");
specific.add_options()("package", po::value<std::string>(), "select device package (defaults to CABGA381)");
specific.add_options()("speed", po::value<int>(), "select device speedgrade (6, 7 or 8)");
diff --git a/ecp5/resource/chipdb.rc b/ecp5/resource/chipdb.rc
deleted file mode 100644
index 60f690c6..00000000
--- a/ecp5/resource/chipdb.rc
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "resource.h"
-
-IDR_CHIPDB_25K BINARYFILE "ecp5/chipdb/chipdb-25k.bin"
-IDR_CHIPDB_45K BINARYFILE "ecp5/chipdb/chipdb-45k.bin"
-IDR_CHIPDB_88K BINARYFILE "ecp5/chipdb/chipdb-85k.bin"
diff --git a/ecp5/resource/embed.cc b/ecp5/resource/embed.cc
deleted file mode 100644
index adbb7781..00000000
--- a/ecp5/resource/embed.cc
+++ /dev/null
@@ -1,28 +0,0 @@
-#include <cstdio>
-#include <windows.h>
-#include "nextpnr.h"
-#include "resource.h"
-
-NEXTPNR_NAMESPACE_BEGIN
-
-const char *chipdb_blob_25k;
-const char *chipdb_blob_45k;
-const char *chipdb_blob_85k;
-
-const char *LoadFileInResource(int name, int type, DWORD &size)
-{
- HMODULE handle = ::GetModuleHandle(NULL);
- HRSRC rc = ::FindResource(handle, MAKEINTRESOURCE(name), MAKEINTRESOURCE(type));
- HGLOBAL rcData = ::LoadResource(handle, rc);
- size = ::SizeofResource(handle, rc);
- return static_cast<const char *>(::LockResource(rcData));
-}
-void load_chipdb()
-{
- DWORD size = 0;
- chipdb_blob_25k = LoadFileInResource(IDR_CHIPDB_25K, BINARYFILE, size);
- chipdb_blob_45k = LoadFileInResource(IDR_CHIPDB_45K, BINARYFILE, size);
- chipdb_blob_85k = LoadFileInResource(IDR_CHIPDB_85K, BINARYFILE, size);
-}
-
-NEXTPNR_NAMESPACE_END \ No newline at end of file
diff --git a/ecp5/resource/resource.h b/ecp5/resource/resource.h
deleted file mode 100644
index 1a18bee2..00000000
--- a/ecp5/resource/resource.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#define BINARYFILE 256
-#define IDR_CHIPDB_25K 101
-#define IDR_CHIPDB_45K 102
-#define IDR_CHIPDB_85K 103
diff --git a/ecp5/trellis_import.py b/ecp5/trellis_import.py
index b591e09f..174f475f 100755
--- a/ecp5/trellis_import.py
+++ b/ecp5/trellis_import.py
@@ -391,7 +391,9 @@ def write_database(dev_name, chip, ddrg, endianness):
bba = BinaryBlobAssembler()
bba.pre('#include "nextpnr.h"')
+ bba.pre('#include "embed.h"')
bba.pre('NEXTPNR_NAMESPACE_BEGIN')
+ bba.post('EmbeddedFile chipdb_file_%s("ecp5/chipdb-%s.bin", chipdb_blob_%s);' % (dev_name, dev_name, dev_name))
bba.post('NEXTPNR_NAMESPACE_END')
bba.push("chipdb_blob_%s" % dev_name)
bba.r("chip_info", "chip_info")
diff --git a/gui/ecp5/mainwindow.cc b/gui/ecp5/mainwindow.cc
index 880af047..5ae1e50f 100644
--- a/gui/ecp5/mainwindow.cc
+++ b/gui/ecp5/mainwindow.cc
@@ -76,48 +76,38 @@ void MainWindow::createMenu()
menuDesign->addAction(actionSaveConfig);
}
-static const ChipInfoPOD *get_chip_info(const RelPtr<ChipInfoPOD> *ptr) { return ptr->get(); }
-
-static QStringList getSupportedPackages(ArchArgs::ArchArgsTypes chip)
-{
- QStringList packages;
- const ChipInfoPOD *chip_info;
- if (chip == ArchArgs::LFE5U_25F || chip == ArchArgs::LFE5UM_25F || chip == ArchArgs::LFE5UM5G_25F) {
- chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_25k));
- } else if (chip == ArchArgs::LFE5U_45F || chip == ArchArgs::LFE5UM_45F || chip == ArchArgs::LFE5UM5G_45F) {
- chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_45k));
- } else if (chip == ArchArgs::LFE5U_85F || chip == ArchArgs::LFE5UM_85F || chip == ArchArgs::LFE5UM5G_85F) {
- chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_85k));
- } else {
- log_error("Unsupported ECP5 chip type.\n");
- }
-
- for (int i = 0; i < chip_info->num_packages; i++) {
- packages << chip_info->package_info[i].name.get();
- }
- return packages;
-}
-
void MainWindow::new_proj()
{
QMap<QString, int> arch;
- arch.insert("Lattice ECP5 LFE5U-25F", ArchArgs::LFE5U_25F);
- arch.insert("Lattice ECP5 LFE5U-45F", ArchArgs::LFE5U_45F);
- arch.insert("Lattice ECP5 LFE5U-85F", ArchArgs::LFE5U_85F);
- arch.insert("Lattice ECP5 LFE5UM-25F", ArchArgs::LFE5UM_25F);
- arch.insert("Lattice ECP5 LFE5UM-45F", ArchArgs::LFE5UM_45F);
- arch.insert("Lattice ECP5 LFE5UM-85F", ArchArgs::LFE5UM_85F);
- arch.insert("Lattice ECP5 LFE5UM5G-25F", ArchArgs::LFE5UM5G_25F);
- arch.insert("Lattice ECP5 LFE5UM5G-45F", ArchArgs::LFE5UM5G_45F);
- arch.insert("Lattice ECP5 LFE5UM5G-85F", ArchArgs::LFE5UM5G_85F);
+ if (Arch::isAvailable(ArchArgs::LFE5U_25F))
+ arch.insert("Lattice ECP5 LFE5U-25F", ArchArgs::LFE5U_25F);
+ if (Arch::isAvailable(ArchArgs::LFE5U_45F))
+ arch.insert("Lattice ECP5 LFE5U-45F", ArchArgs::LFE5U_45F);
+ if (Arch::isAvailable(ArchArgs::LFE5U_85F))
+ arch.insert("Lattice ECP5 LFE5U-85F", ArchArgs::LFE5U_85F);
+ if (Arch::isAvailable(ArchArgs::LFE5UM_25F))
+ arch.insert("Lattice ECP5 LFE5UM-25F", ArchArgs::LFE5UM_25F);
+ if (Arch::isAvailable(ArchArgs::LFE5UM_45F))
+ arch.insert("Lattice ECP5 LFE5UM-45F", ArchArgs::LFE5UM_45F);
+ if (Arch::isAvailable(ArchArgs::LFE5UM_85F))
+ arch.insert("Lattice ECP5 LFE5UM-85F", ArchArgs::LFE5UM_85F);
+ if (Arch::isAvailable(ArchArgs::LFE5UM5G_25F))
+ arch.insert("Lattice ECP5 LFE5UM5G-25F", ArchArgs::LFE5UM5G_25F);
+ if (Arch::isAvailable(ArchArgs::LFE5UM5G_45F))
+ arch.insert("Lattice ECP5 LFE5UM5G-45F", ArchArgs::LFE5UM5G_45F);
+ if (Arch::isAvailable(ArchArgs::LFE5UM5G_85F))
+ arch.insert("Lattice ECP5 LFE5UM5G-85F", ArchArgs::LFE5UM5G_85F);
+
bool ok;
QString item = QInputDialog::getItem(this, "Select new context", "Chip:", arch.keys(), 0, false, &ok);
if (ok && !item.isEmpty()) {
ArchArgs chipArgs;
chipArgs.type = (ArchArgs::ArchArgsTypes)arch.value(item);
- QString package = QInputDialog::getItem(this, "Select package", "Package:", getSupportedPackages(chipArgs.type),
- 0, false, &ok);
+ QStringList packages;
+ for (auto package : Arch::getSupportedPackages(chipArgs.type))
+ packages.append(QLatin1String(package.data(), package.size()));
+ QString package = QInputDialog::getItem(this, "Select package", "Package:", packages, 0, false, &ok);
if (ok && !item.isEmpty()) {
currentProj = "";
diff --git a/gui/ice40/family.cmake b/gui/ice40/family.cmake
index ede5b805..e69de29b 100644
--- a/gui/ice40/family.cmake
+++ b/gui/ice40/family.cmake
@@ -1,3 +0,0 @@
-if(ICE40_HX1K_ONLY)
- target_compile_definitions(gui_${family} PRIVATE ICE40_HX1K_ONLY=1)
-endif()
diff --git a/gui/ice40/mainwindow.cc b/gui/ice40/mainwindow.cc
index dc8a3a23..3dcf90ae 100644
--- a/gui/ice40/mainwindow.cc
+++ b/gui/ice40/mainwindow.cc
@@ -74,59 +74,34 @@ void MainWindow::createMenu()
menuDesign->addAction(actionSaveAsc);
}
-static const ChipInfoPOD *get_chip_info(const RelPtr<ChipInfoPOD> *ptr) { return ptr->get(); }
-
-static QStringList getSupportedPackages(ArchArgs::ArchArgsTypes chip)
-{
- QStringList packages;
- const ChipInfoPOD *chip_info;
-#ifdef ICE40_HX1K_ONLY
- if (chip == ArchArgs::HX1K) {
- chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_1k));
- } else {
- log_error("Unsupported iCE40 chip type.\n");
- }
-#else
- if (chip == ArchArgs::LP384) {
- chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_384));
- } else if (chip == ArchArgs::LP1K || chip == ArchArgs::HX1K) {
- chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_1k));
- } else if (chip == ArchArgs::UP5K) {
- chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_5k));
- } else if (chip == ArchArgs::LP8K || chip == ArchArgs::HX8K) {
- chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_8k));
- } else {
- log_error("Unsupported iCE40 chip type.\n");
- }
-#endif
-
- for (int i = 0; i < chip_info->num_packages; i++) {
- packages << chip_info->packages_data[i].name.get();
- }
- return packages;
-}
-
void MainWindow::new_proj()
{
QMap<QString, int> arch;
-#ifdef ICE40_HX1K_ONLY
- arch.insert("Lattice HX1K", ArchArgs::HX1K);
-#else
- arch.insert("Lattice LP384", ArchArgs::LP384);
- arch.insert("Lattice LP1K", ArchArgs::LP1K);
- arch.insert("Lattice HX1K", ArchArgs::HX1K);
- arch.insert("Lattice UP5K", ArchArgs::UP5K);
- arch.insert("Lattice LP8K", ArchArgs::LP8K);
- arch.insert("Lattice HX8K", ArchArgs::HX8K);
-#endif
+ if (Arch::isAvailable(ArchArgs::LP384))
+ arch.insert("Lattice LP384", ArchArgs::LP384);
+ if (Arch::isAvailable(ArchArgs::LP1K))
+ arch.insert("Lattice LP1K", ArchArgs::LP1K);
+ if (Arch::isAvailable(ArchArgs::HX1K))
+ arch.insert("Lattice HX1K", ArchArgs::HX1K);
+ if (Arch::isAvailable(ArchArgs::U4K))
+ arch.insert("Lattice U4K", ArchArgs::U4K);
+ if (Arch::isAvailable(ArchArgs::UP5K))
+ arch.insert("Lattice UP5K", ArchArgs::UP5K);
+ if (Arch::isAvailable(ArchArgs::LP8K))
+ arch.insert("Lattice LP8K", ArchArgs::LP8K);
+ if (Arch::isAvailable(ArchArgs::HX8K))
+ arch.insert("Lattice HX8K", ArchArgs::HX8K);
+
bool ok;
QString item = QInputDialog::getItem(this, "Select new context", "Chip:", arch.keys(), 0, false, &ok);
if (ok && !item.isEmpty()) {
ArchArgs chipArgs;
chipArgs.type = (ArchArgs::ArchArgsTypes)arch.value(item);
- QString package = QInputDialog::getItem(this, "Select package", "Package:", getSupportedPackages(chipArgs.type),
- 0, false, &ok);
+ QStringList packages;
+ for (auto package : Arch::getSupportedPackages(chipArgs.type))
+ packages.append(QLatin1String(package.data(), package.size()));
+ QString package = QInputDialog::getItem(this, "Select package", "Package:", packages, 0, false, &ok);
if (ok && !item.isEmpty()) {
currentProj = "";
diff --git a/ice40/arch.cc b/ice40/arch.cc
index 545066ce..cdef91df 100644
--- a/ice40/arch.cc
+++ b/ice40/arch.cc
@@ -19,12 +19,12 @@
*/
#include <algorithm>
-#include <boost/iostreams/device/mapped_file.hpp>
#include <cmath>
#include "cells.h"
#include "gfx.h"
#include "log.h"
#include "nextpnr.h"
+#include "embed.h"
#include "placer1.h"
#include "placer_heap.h"
#include "router1.h"
@@ -44,75 +44,51 @@ void IdString::initialize_arch(const BaseCtx *ctx)
// -----------------------------------------------------------------------
-static const ChipInfoPOD *get_chip_info(const RelPtr<ChipInfoPOD> *ptr) { return ptr->get(); }
-
-#if defined(WIN32)
-void load_chipdb();
-#endif
-
-#if defined(EXTERNAL_CHIPDB_ROOT)
-const char *chipdb_blob_384 = nullptr;
-const char *chipdb_blob_1k = nullptr;
-const char *chipdb_blob_5k = nullptr;
-const char *chipdb_blob_u4k = nullptr;
-const char *chipdb_blob_8k = nullptr;
+static const ChipInfoPOD *get_chip_info(ArchArgs::ArchArgsTypes chip) {
+ std::string chipdb;
+ if (chip == ArchArgs::LP384) {
+ chipdb = "ice40/chipdb-384.bin";
+ } else if (chip == ArchArgs::LP1K || chip == ArchArgs::HX1K) {
+ chipdb = "ice40/chipdb-1k.bin";
+ } else if (chip == ArchArgs::U4K) {
+ chipdb = "ice40/chipdb-u4k.bin";
+ } else if (chip == ArchArgs::UP5K) {
+ chipdb = "ice40/chipdb-5k.bin";
+ } else if (chip == ArchArgs::LP8K || chip == ArchArgs::HX8K) {
+ chipdb = "ice40/chipdb-8k.bin";
+ } else {
+ log_error("Unknown chip\n");
+ }
-boost::iostreams::mapped_file blob_files[5];
+ auto ptr = reinterpret_cast<const RelPtr<ChipInfoPOD> *>(get_chipdb(chipdb));
+ if (ptr == nullptr)
+ return nullptr;
+ return ptr->get();
+}
-const char *mmap_file(int index, const char *filename)
+bool Arch::isAvailable(ArchArgs::ArchArgsTypes chip)
{
- try {
- blob_files[index].open(filename, boost::iostreams::mapped_file::priv);
- if (!blob_files[index].is_open())
- log_error("Unable to read chipdb %s\n", filename);
- return (const char *)blob_files[index].data();
- } catch (...) {
- log_error("Unable to read chipdb %s\n", filename);
- }
+ return get_chip_info(chip) != nullptr;
}
-void load_chipdb()
+std::vector<std::string> Arch::getSupportedPackages(ArchArgs::ArchArgsTypes chip)
{
- chipdb_blob_384 = mmap_file(0, EXTERNAL_CHIPDB_ROOT "/ice40/chipdb-384.bin");
- chipdb_blob_1k = mmap_file(1, EXTERNAL_CHIPDB_ROOT "/ice40/chipdb-1k.bin");
- chipdb_blob_5k = mmap_file(2, EXTERNAL_CHIPDB_ROOT "/ice40/chipdb-5k.bin");
- chipdb_blob_u4k = mmap_file(3, EXTERNAL_CHIPDB_ROOT "/ice40/chipdb-u4k.bin");
- chipdb_blob_8k = mmap_file(4, EXTERNAL_CHIPDB_ROOT "/ice40/chipdb-8k.bin");
+ const ChipInfoPOD *chip_info = get_chip_info(chip);
+ std::vector<std::string> packages;
+ for (int i = 0; i < chip_info->num_packages; i++)
+ packages.push_back(chip_info->packages_data[i].name.get());
+ return packages;
}
-#endif
+
+// -----------------------------------------------------------------------
+
Arch::Arch(ArchArgs args) : args(args)
{
-#if defined(WIN32) || defined(EXTERNAL_CHIPDB_ROOT)
- load_chipdb();
-#endif
+ fast_part = (args.type == ArchArgs::HX8K || args.type == ArchArgs::HX1K);
-#ifdef ICE40_HX1K_ONLY
- if (args.type == ArchArgs::HX1K) {
- fast_part = true;
- chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_1k));
- } else {
+ chip_info = get_chip_info(args.type);
+ if (chip_info == nullptr)
log_error("Unsupported iCE40 chip type.\n");
- }
-#else
- if (args.type == ArchArgs::LP384) {
- fast_part = false;
- chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_384));
- } else if (args.type == ArchArgs::LP1K || args.type == ArchArgs::HX1K) {
- fast_part = args.type == ArchArgs::HX1K;
- chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_1k));
- } else if (args.type == ArchArgs::UP5K) {
- fast_part = false;
- chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_5k));
- } else if (args.type == ArchArgs::U4K) {
- fast_part = false;
- chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_u4k));
- } else if (args.type == ArchArgs::LP8K || args.type == ArchArgs::HX8K) {
- fast_part = args.type == ArchArgs::HX8K;
- chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_8k));
- } else {
- log_error("Unsupported iCE40 chip type.\n");
- }
-#endif
package_info = nullptr;
for (int i = 0; i < chip_info->num_packages; i++) {
@@ -135,13 +111,6 @@ Arch::Arch(ArchArgs args) : args(args)
std::string Arch::getChipName() const
{
-#ifdef ICE40_HX1K_ONLY
- if (args.type == ArchArgs::HX1K) {
- return "Lattice LP1K";
- } else {
- log_error("Unsupported iCE40 chip type.\n");
- }
-#else
if (args.type == ArchArgs::LP384) {
return "Lattice LP384";
} else if (args.type == ArchArgs::LP1K) {
@@ -159,7 +128,6 @@ std::string Arch::getChipName() const
} else {
log_error("Unknown chip\n");
}
-#endif
}
// -----------------------------------------------------------------------
@@ -642,13 +610,10 @@ bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay
budget = 0;
else {
switch (args.type) {
-#ifndef ICE40_HX1K_ONLY
case ArchArgs::HX8K:
-#endif
case ArchArgs::HX1K:
budget = cin ? 190 : (same_y ? 260 : 560);
break;
-#ifndef ICE40_HX1K_ONLY
case ArchArgs::LP384:
case ArchArgs::LP1K:
case ArchArgs::LP8K:
@@ -658,7 +623,6 @@ bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay
case ArchArgs::U4K:
budget = cin ? 560 : (same_y ? 660 : 1220);
break;
-#endif
default:
log_error("Unsupported iCE40 chip type.\n");
}
diff --git a/ice40/arch.h b/ice40/arch.h
index 356891ce..0d8e7d76 100644
--- a/ice40/arch.h
+++ b/ice40/arch.h
@@ -244,20 +244,6 @@ NPNR_PACKED_STRUCT(struct ChipInfoPOD {
RelPtr<RelPtr<char>> tile_wire_names;
});
-#if defined(WIN32) || defined(EXTERNAL_CHIPDB_ROOT)
-extern const char *chipdb_blob_384;
-extern const char *chipdb_blob_1k;
-extern const char *chipdb_blob_5k;
-extern const char *chipdb_blob_u4k;
-extern const char *chipdb_blob_8k;
-#else
-extern const char chipdb_blob_384[];
-extern const char chipdb_blob_1k[];
-extern const char chipdb_blob_5k[];
-extern const char chipdb_blob_u4k[];
-extern const char chipdb_blob_8k[];
-#endif
-
/************************ End of chipdb section. ************************/
struct BelIterator
@@ -428,6 +414,9 @@ struct Arch : BaseCtx
ArchArgs args;
Arch(ArchArgs args);
+ static bool isAvailable(ArchArgs::ArchArgsTypes chip);
+ static std::vector<std::string> getSupportedPackages(ArchArgs::ArchArgsTypes chip);
+
std::string getChipName() const;
IdString archId() const { return id("ice40"); }
diff --git a/ice40/chipdb.py b/ice40/chipdb.py
index 195c08ae..7b3ad999 100644
--- a/ice40/chipdb.py
+++ b/ice40/chipdb.py
@@ -1113,7 +1113,9 @@ class BinaryBlobAssembler:
bba = BinaryBlobAssembler()
bba.pre('#include "nextpnr.h"')
+bba.pre('#include "embed.h"')
bba.pre('NEXTPNR_NAMESPACE_BEGIN')
+bba.post('EmbeddedFile chipdb_file_%s("ice40/chipdb-%s.bin", chipdb_blob_%s);' % (dev_name, dev_name, dev_name))
bba.post('NEXTPNR_NAMESPACE_END')
bba.push("chipdb_blob_%s" % dev_name)
bba.r("chip_info_%s" % dev_name, "chip_info")
diff --git a/ice40/family.cmake b/ice40/family.cmake
index 5921fa3c..fd16df40 100644
--- a/ice40/family.cmake
+++ b/ice40/family.cmake
@@ -30,9 +30,14 @@ foreach(device ${ICE40_DEVICES})
endif()
endforeach()
if(WIN32)
- list(APPEND chipdb_sources
- ${CMAKE_CURRENT_SOURCE_DIR}/${family}/resource/embed.cc
- ${CMAKE_CURRENT_SOURCE_DIR}/${family}/resource/chipdb.rc)
+ set(chipdb_rc ${CMAKE_CURRENT_BINARY_DIR}/${family}/resource/chipdb.rc)
+ list(APPEND chipdb_sources ${chipdb_rc})
+
+ file(WRITE ${chipdb_rc})
+ foreach(device ${ICE40_DEVICES})
+ file(APPEND ${chipdb_rc}
+ "${family}/chipdb-${device}.bin RCDATA \"${CMAKE_CURRENT_BINARY_DIR}/${family}/chipdb/chipdb-${device}.bin\"")
+ endforeach()
endif()
add_custom_target(chipdb-${family}-bins DEPENDS ${chipdb_sources} ${chipdb_binaries})
@@ -42,9 +47,6 @@ 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})
-if(ICE40_DEVICES STREQUAL "1k")
- target_compile_definitions(chipdb-${family} PUBLIC ICE40_HX1K_ONLY=1)
-endif()
foreach(family_target ${family_targets})
target_sources(${family_target} PRIVATE $<TARGET_OBJECTS:chipdb-${family}>)
diff --git a/ice40/main.cc b/ice40/main.cc
index 07c91399..497d580b 100644
--- a/ice40/main.cc
+++ b/ice40/main.cc
@@ -50,17 +50,20 @@ Ice40CommandHandler::Ice40CommandHandler(int argc, char **argv) : CommandHandler
po::options_description Ice40CommandHandler::getArchOptions()
{
po::options_description specific("Architecture specific options");
-#ifdef ICE40_HX1K_ONLY
- specific.add_options()("hx1k", "set device type to iCE40HX1K");
-#else
- specific.add_options()("lp384", "set device type to iCE40LP384");
- specific.add_options()("lp1k", "set device type to iCE40LP1K");
- specific.add_options()("lp8k", "set device type to iCE40LP8K");
- specific.add_options()("hx1k", "set device type to iCE40HX1K");
- specific.add_options()("hx8k", "set device type to iCE40HX8K");
- specific.add_options()("up5k", "set device type to iCE40UP5K");
- specific.add_options()("u4k", "set device type to iCE5LP4K");
-#endif
+ if (Arch::isAvailable(ArchArgs::LP384))
+ specific.add_options()("lp384", "set device type to iCE40LP384");
+ if (Arch::isAvailable(ArchArgs::LP1K))
+ specific.add_options()("lp1k", "set device type to iCE40LP1K");
+ if (Arch::isAvailable(ArchArgs::LP8K))
+ specific.add_options()("lp8k", "set device type to iCE40LP8K");
+ if (Arch::isAvailable(ArchArgs::HX1K))
+ specific.add_options()("hx1k", "set device type to iCE40HX1K");
+ if (Arch::isAvailable(ArchArgs::HX8K))
+ specific.add_options()("hx8k", "set device type to iCE40HX8K");
+ if (Arch::isAvailable(ArchArgs::UP5K))
+ specific.add_options()("up5k", "set device type to iCE40UP5K");
+ if (Arch::isAvailable(ArchArgs::U4K))
+ specific.add_options()("u4k", "set device type to iCE5LP4K");
specific.add_options()("package", po::value<std::string>(), "set device package");
specific.add_options()("pcf", po::value<std::string>(), "PCF constraints file to ingest");
specific.add_options()("asc", po::value<std::string>(), "asc bitstream file to write");
@@ -204,11 +207,6 @@ std::unique_ptr<Context> Ice40CommandHandler::createContext(std::unordered_map<s
chipArgs.type = ArchArgs::HX1K;
chipArgs.package = "tq144";
}
-#ifdef ICE40_HX1K_ONLY
- if (chipArgs.type != ArchArgs::HX1K) {
- log_error("This version of nextpnr-ice40 is built with HX1K-support only.\n");
- }
-#endif
auto ctx = std::unique_ptr<Context>(new Context(chipArgs));
for (auto &val : values)
diff --git a/ice40/resource/chipdb.rc b/ice40/resource/chipdb.rc
deleted file mode 100644
index 0b248d74..00000000
--- a/ice40/resource/chipdb.rc
+++ /dev/null
@@ -1,7 +0,0 @@
-#include "resource.h"
-
-IDR_CHIPDB_384 BINARYFILE "ice40/chipdb/chipdb-384.bin"
-IDR_CHIPDB_1K BINARYFILE "ice40/chipdb/chipdb-1k.bin"
-IDR_CHIPDB_5K BINARYFILE "ice40/chipdb/chipdb-5k.bin"
-IDR_CHIPDB_U4K BINARYFILE "ice40/chipdb/chipdb-u4k.bin"
-IDR_CHIPDB_8K BINARYFILE "ice40/chipdb/chipdb-8k.bin"
diff --git a/ice40/resource/embed.cc b/ice40/resource/embed.cc
deleted file mode 100644
index 048ac474..00000000
--- a/ice40/resource/embed.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-#include <cstdio>
-#include <windows.h>
-#include "nextpnr.h"
-#include "resource.h"
-
-NEXTPNR_NAMESPACE_BEGIN
-
-const char *chipdb_blob_384;
-const char *chipdb_blob_1k;
-const char *chipdb_blob_5k;
-const char *chipdb_blob_u4k;
-const char *chipdb_blob_8k;
-
-const char *LoadFileInResource(int name, int type, DWORD &size)
-{
- HMODULE handle = ::GetModuleHandle(NULL);
- HRSRC rc = ::FindResource(handle, MAKEINTRESOURCE(name), MAKEINTRESOURCE(type));
- HGLOBAL rcData = ::LoadResource(handle, rc);
- size = ::SizeofResource(handle, rc);
- return static_cast<const char *>(::LockResource(rcData));
-}
-void load_chipdb()
-{
- DWORD size = 0;
- chipdb_blob_384 = LoadFileInResource(IDR_CHIPDB_384, BINARYFILE, size);
- chipdb_blob_1k = LoadFileInResource(IDR_CHIPDB_1K, BINARYFILE, size);
- chipdb_blob_5k = LoadFileInResource(IDR_CHIPDB_5K, BINARYFILE, size);
- chipdb_blob_u4k = LoadFileInResource(IDR_CHIPDB_U4K, BINARYFILE, size);
- chipdb_blob_8k = LoadFileInResource(IDR_CHIPDB_8K, BINARYFILE, size);
-}
-
-NEXTPNR_NAMESPACE_END
diff --git a/ice40/resource/resource.h b/ice40/resource/resource.h
deleted file mode 100644
index 4dacbf61..00000000
--- a/ice40/resource/resource.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#define BINARYFILE 256
-#define IDR_CHIPDB_384 101
-#define IDR_CHIPDB_1K 102
-#define IDR_CHIPDB_5K 103
-#define IDR_CHIPDB_8K 104
-#define IDR_CHIPDB_U4K 105