Simplify and improve chipdb embedding/loading.
This commit is contained in:
parent
dc209f6344
commit
89e0cc8078
46
common/embed.cc
Normal file
46
common/embed.cc
Normal file
@ -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
|
50
common/embed.h
Normal file
50
common/embed.h
Normal file
@ -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
|
86
ecp5/arch.cc
86
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;
|
||||
|
||||
boost::iostreams::mapped_file blob_files[3];
|
||||
|
||||
const char *mmap_file(int index, const char *filename)
|
||||
{
|
||||
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);
|
||||
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");
|
||||
}
|
||||
|
||||
auto ptr = reinterpret_cast<const RelPtr<ChipInfoPOD> *>(get_chipdb(chipdb));
|
||||
if (ptr == nullptr)
|
||||
return nullptr;
|
||||
return ptr->get();
|
||||
}
|
||||
|
||||
void load_chipdb()
|
||||
bool Arch::isAvailable(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");
|
||||
return get_chip_info(chip) != nullptr;
|
||||
}
|
||||
#endif
|
||||
//#define LFE5U_45F_ONLY
|
||||
|
||||
std::vector<std::string> Arch::getSupportedPackages(ArchArgs::ArchArgsTypes chip)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
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 {
|
||||
chip_info = get_chip_info(args.type);
|
||||
if (chip_info == nullptr)
|
||||
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 {
|
||||
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()) {
|
||||
|
13
ecp5/arch.h
13
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;
|
||||
|
||||
|
@ -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})
|
||||
|
30
ecp5/main.cc
30
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)");
|
||||
|
@ -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"
|
@ -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
|
@ -1,4 +0,0 @@
|
||||
#define BINARYFILE 256
|
||||
#define IDR_CHIPDB_25K 101
|
||||
#define IDR_CHIPDB_45K 102
|
||||
#define IDR_CHIPDB_85K 103
|
@ -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")
|
||||
|
@ -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 = "";
|
||||
|
@ -1,3 +0,0 @@
|
||||
if(ICE40_HX1K_ONLY)
|
||||
target_compile_definitions(gui_${family} PRIVATE ICE40_HX1K_ONLY=1)
|
||||
endif()
|
@ -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 = "";
|
||||
|
110
ice40/arch.cc
110
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;
|
||||
|
||||
boost::iostreams::mapped_file blob_files[5];
|
||||
|
||||
const char *mmap_file(int index, const char *filename)
|
||||
{
|
||||
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);
|
||||
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");
|
||||
}
|
||||
|
||||
auto ptr = reinterpret_cast<const RelPtr<ChipInfoPOD> *>(get_chipdb(chipdb));
|
||||
if (ptr == nullptr)
|
||||
return nullptr;
|
||||
return ptr->get();
|
||||
}
|
||||
|
||||
void load_chipdb()
|
||||
bool Arch::isAvailable(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");
|
||||
return get_chip_info(chip) != nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::vector<std::string> Arch::getSupportedPackages(ArchArgs::ArchArgsTypes chip)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
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");
|
||||
}
|
||||
|
17
ice40/arch.h
17
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"); }
|
||||
|
@ -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")
|
||||
|
@ -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}>)
|
||||
|
@ -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)
|
||||
|
@ -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"
|
@ -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
|
@ -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
|
Loading…
Reference in New Issue
Block a user