Merge pull request #460 from whitequark/better-embed
Simplify and improve chipdb embedding/loading
This commit is contained in:
commit
4f4aa53120
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 "globals.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "nextpnr.h"
|
#include "nextpnr.h"
|
||||||
|
#include "embed.h"
|
||||||
#include "placer1.h"
|
#include "placer1.h"
|
||||||
#include "placer_heap.h"
|
#include "placer_heap.h"
|
||||||
#include "router1.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(); }
|
static const ChipInfoPOD *get_chip_info(ArchArgs::ArchArgsTypes chip) {
|
||||||
|
std::string chipdb;
|
||||||
#if defined(WIN32)
|
if (chip == ArchArgs::LFE5U_12F || chip == ArchArgs::LFE5U_25F ||
|
||||||
void load_chipdb();
|
chip == ArchArgs::LFE5UM_25F || chip == ArchArgs::LFE5UM5G_25F) {
|
||||||
#endif
|
chipdb = "ecp5/chipdb-25k.bin";
|
||||||
|
} else if (chip == ArchArgs::LFE5U_45F ||
|
||||||
#if defined(EXTERNAL_CHIPDB_ROOT)
|
chip == ArchArgs::LFE5UM_45F || chip == ArchArgs::LFE5UM5G_45F) {
|
||||||
const char *chipdb_blob_25k = nullptr;
|
chipdb = "ecp5/chipdb-45k.bin";
|
||||||
const char *chipdb_blob_45k = nullptr;
|
} else if (chip == ArchArgs::LFE5U_85F ||
|
||||||
const char *chipdb_blob_85k = nullptr;
|
chip == ArchArgs::LFE5UM_85F || chip == ArchArgs::LFE5UM5G_85F) {
|
||||||
|
chipdb = "ecp5/chipdb-85k.bin";
|
||||||
boost::iostreams::mapped_file blob_files[3];
|
} else {
|
||||||
|
log_error("Unknown chip\n");
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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");
|
return get_chip_info(chip) != nullptr;
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
#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)
|
Arch::Arch(ArchArgs args) : args(args)
|
||||||
{
|
{
|
||||||
#if defined(WIN32) || defined(EXTERNAL_CHIPDB_ROOT)
|
chip_info = get_chip_info(args.type);
|
||||||
load_chipdb();
|
if (chip_info == nullptr)
|
||||||
#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");
|
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)
|
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 "
|
log_error("Chip database 'bba' and nextpnr code are out of sync; please rebuild (or contact distribution "
|
||||||
"maintainer)!\n");
|
"maintainer)!\n");
|
||||||
|
|
||||||
package_info = nullptr;
|
package_info = nullptr;
|
||||||
for (int i = 0; i < chip_info->num_packages; i++) {
|
for (int i = 0; i < chip_info->num_packages; i++) {
|
||||||
if (args.package == chip_info->package_info[i].name.get()) {
|
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;
|
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. ************************/
|
/************************ End of chipdb section. ************************/
|
||||||
|
|
||||||
struct BelIterator
|
struct BelIterator
|
||||||
@ -494,6 +484,9 @@ struct Arch : BaseCtx
|
|||||||
ArchArgs args;
|
ArchArgs args;
|
||||||
Arch(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 getChipName() const;
|
||||||
std::string getFullChipName() const;
|
std::string getFullChipName() const;
|
||||||
|
|
||||||
|
@ -30,9 +30,14 @@ foreach(device ${ECP5_DEVICES})
|
|||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
list(APPEND chipdb_sources
|
set(chipdb_rc ${CMAKE_CURRENT_BINARY_DIR}/${family}/resource/chipdb.rc)
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/${family}/resource/embed.cc
|
list(APPEND chipdb_sources ${chipdb_rc})
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/${family}/resource/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()
|
endif()
|
||||||
|
|
||||||
add_custom_target(chipdb-${family}-bins DEPENDS ${chipdb_sources} ${chipdb_binaries})
|
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 ECP5CommandHandler::getArchOptions()
|
||||||
{
|
{
|
||||||
po::options_description specific("Architecture specific options");
|
po::options_description specific("Architecture specific options");
|
||||||
specific.add_options()("12k", "set device type to LFE5U-12F");
|
if (Arch::isAvailable(ArchArgs::LFE5U_12F))
|
||||||
specific.add_options()("25k", "set device type to LFE5U-25F");
|
specific.add_options()("12k", "set device type to LFE5U-12F");
|
||||||
specific.add_options()("45k", "set device type to LFE5U-45F");
|
if (Arch::isAvailable(ArchArgs::LFE5U_25F))
|
||||||
specific.add_options()("85k", "set device type to LFE5U-85F");
|
specific.add_options()("25k", "set device type to LFE5U-25F");
|
||||||
specific.add_options()("um-25k", "set device type to LFE5UM-25F");
|
if (Arch::isAvailable(ArchArgs::LFE5U_45F))
|
||||||
specific.add_options()("um-45k", "set device type to LFE5UM-45F");
|
specific.add_options()("45k", "set device type to LFE5U-45F");
|
||||||
specific.add_options()("um-85k", "set device type to LFE5UM-85F");
|
if (Arch::isAvailable(ArchArgs::LFE5U_85F))
|
||||||
specific.add_options()("um5g-25k", "set device type to LFE5UM5G-25F");
|
specific.add_options()("85k", "set device type to LFE5U-85F");
|
||||||
specific.add_options()("um5g-45k", "set device type to LFE5UM5G-45F");
|
if (Arch::isAvailable(ArchArgs::LFE5UM_25F))
|
||||||
specific.add_options()("um5g-85k", "set device type to LFE5UM5G-85F");
|
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()("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)");
|
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 = BinaryBlobAssembler()
|
||||||
bba.pre('#include "nextpnr.h"')
|
bba.pre('#include "nextpnr.h"')
|
||||||
|
bba.pre('#include "embed.h"')
|
||||||
bba.pre('NEXTPNR_NAMESPACE_BEGIN')
|
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.post('NEXTPNR_NAMESPACE_END')
|
||||||
bba.push("chipdb_blob_%s" % dev_name)
|
bba.push("chipdb_blob_%s" % dev_name)
|
||||||
bba.r("chip_info", "chip_info")
|
bba.r("chip_info", "chip_info")
|
||||||
|
@ -76,48 +76,38 @@ void MainWindow::createMenu()
|
|||||||
menuDesign->addAction(actionSaveConfig);
|
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()
|
void MainWindow::new_proj()
|
||||||
{
|
{
|
||||||
QMap<QString, int> arch;
|
QMap<QString, int> arch;
|
||||||
arch.insert("Lattice ECP5 LFE5U-25F", ArchArgs::LFE5U_25F);
|
if (Arch::isAvailable(ArchArgs::LFE5U_25F))
|
||||||
arch.insert("Lattice ECP5 LFE5U-45F", ArchArgs::LFE5U_45F);
|
arch.insert("Lattice ECP5 LFE5U-25F", ArchArgs::LFE5U_25F);
|
||||||
arch.insert("Lattice ECP5 LFE5U-85F", ArchArgs::LFE5U_85F);
|
if (Arch::isAvailable(ArchArgs::LFE5U_45F))
|
||||||
arch.insert("Lattice ECP5 LFE5UM-25F", ArchArgs::LFE5UM_25F);
|
arch.insert("Lattice ECP5 LFE5U-45F", ArchArgs::LFE5U_45F);
|
||||||
arch.insert("Lattice ECP5 LFE5UM-45F", ArchArgs::LFE5UM_45F);
|
if (Arch::isAvailable(ArchArgs::LFE5U_85F))
|
||||||
arch.insert("Lattice ECP5 LFE5UM-85F", ArchArgs::LFE5UM_85F);
|
arch.insert("Lattice ECP5 LFE5U-85F", ArchArgs::LFE5U_85F);
|
||||||
arch.insert("Lattice ECP5 LFE5UM5G-25F", ArchArgs::LFE5UM5G_25F);
|
if (Arch::isAvailable(ArchArgs::LFE5UM_25F))
|
||||||
arch.insert("Lattice ECP5 LFE5UM5G-45F", ArchArgs::LFE5UM5G_45F);
|
arch.insert("Lattice ECP5 LFE5UM-25F", ArchArgs::LFE5UM_25F);
|
||||||
arch.insert("Lattice ECP5 LFE5UM5G-85F", ArchArgs::LFE5UM5G_85F);
|
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;
|
bool ok;
|
||||||
QString item = QInputDialog::getItem(this, "Select new context", "Chip:", arch.keys(), 0, false, &ok);
|
QString item = QInputDialog::getItem(this, "Select new context", "Chip:", arch.keys(), 0, false, &ok);
|
||||||
if (ok && !item.isEmpty()) {
|
if (ok && !item.isEmpty()) {
|
||||||
ArchArgs chipArgs;
|
ArchArgs chipArgs;
|
||||||
chipArgs.type = (ArchArgs::ArchArgsTypes)arch.value(item);
|
chipArgs.type = (ArchArgs::ArchArgsTypes)arch.value(item);
|
||||||
|
|
||||||
QString package = QInputDialog::getItem(this, "Select package", "Package:", getSupportedPackages(chipArgs.type),
|
QStringList packages;
|
||||||
0, false, &ok);
|
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()) {
|
if (ok && !item.isEmpty()) {
|
||||||
currentProj = "";
|
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);
|
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()
|
void MainWindow::new_proj()
|
||||||
{
|
{
|
||||||
QMap<QString, int> arch;
|
QMap<QString, int> arch;
|
||||||
#ifdef ICE40_HX1K_ONLY
|
if (Arch::isAvailable(ArchArgs::LP384))
|
||||||
arch.insert("Lattice HX1K", ArchArgs::HX1K);
|
arch.insert("Lattice LP384", ArchArgs::LP384);
|
||||||
#else
|
if (Arch::isAvailable(ArchArgs::LP1K))
|
||||||
arch.insert("Lattice LP384", ArchArgs::LP384);
|
arch.insert("Lattice LP1K", ArchArgs::LP1K);
|
||||||
arch.insert("Lattice LP1K", ArchArgs::LP1K);
|
if (Arch::isAvailable(ArchArgs::HX1K))
|
||||||
arch.insert("Lattice HX1K", ArchArgs::HX1K);
|
arch.insert("Lattice HX1K", ArchArgs::HX1K);
|
||||||
arch.insert("Lattice UP5K", ArchArgs::UP5K);
|
if (Arch::isAvailable(ArchArgs::U4K))
|
||||||
arch.insert("Lattice LP8K", ArchArgs::LP8K);
|
arch.insert("Lattice U4K", ArchArgs::U4K);
|
||||||
arch.insert("Lattice HX8K", ArchArgs::HX8K);
|
if (Arch::isAvailable(ArchArgs::UP5K))
|
||||||
#endif
|
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;
|
bool ok;
|
||||||
QString item = QInputDialog::getItem(this, "Select new context", "Chip:", arch.keys(), 0, false, &ok);
|
QString item = QInputDialog::getItem(this, "Select new context", "Chip:", arch.keys(), 0, false, &ok);
|
||||||
if (ok && !item.isEmpty()) {
|
if (ok && !item.isEmpty()) {
|
||||||
ArchArgs chipArgs;
|
ArchArgs chipArgs;
|
||||||
chipArgs.type = (ArchArgs::ArchArgsTypes)arch.value(item);
|
chipArgs.type = (ArchArgs::ArchArgsTypes)arch.value(item);
|
||||||
|
|
||||||
QString package = QInputDialog::getItem(this, "Select package", "Package:", getSupportedPackages(chipArgs.type),
|
QStringList packages;
|
||||||
0, false, &ok);
|
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()) {
|
if (ok && !item.isEmpty()) {
|
||||||
currentProj = "";
|
currentProj = "";
|
||||||
|
110
ice40/arch.cc
110
ice40/arch.cc
@ -19,12 +19,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <boost/iostreams/device/mapped_file.hpp>
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include "cells.h"
|
#include "cells.h"
|
||||||
#include "gfx.h"
|
#include "gfx.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "nextpnr.h"
|
#include "nextpnr.h"
|
||||||
|
#include "embed.h"
|
||||||
#include "placer1.h"
|
#include "placer1.h"
|
||||||
#include "placer_heap.h"
|
#include "placer_heap.h"
|
||||||
#include "router1.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(); }
|
static const ChipInfoPOD *get_chip_info(ArchArgs::ArchArgsTypes chip) {
|
||||||
|
std::string chipdb;
|
||||||
#if defined(WIN32)
|
if (chip == ArchArgs::LP384) {
|
||||||
void load_chipdb();
|
chipdb = "ice40/chipdb-384.bin";
|
||||||
#endif
|
} else if (chip == ArchArgs::LP1K || chip == ArchArgs::HX1K) {
|
||||||
|
chipdb = "ice40/chipdb-1k.bin";
|
||||||
#if defined(EXTERNAL_CHIPDB_ROOT)
|
} else if (chip == ArchArgs::U4K) {
|
||||||
const char *chipdb_blob_384 = nullptr;
|
chipdb = "ice40/chipdb-u4k.bin";
|
||||||
const char *chipdb_blob_1k = nullptr;
|
} else if (chip == ArchArgs::UP5K) {
|
||||||
const char *chipdb_blob_5k = nullptr;
|
chipdb = "ice40/chipdb-5k.bin";
|
||||||
const char *chipdb_blob_u4k = nullptr;
|
} else if (chip == ArchArgs::LP8K || chip == ArchArgs::HX8K) {
|
||||||
const char *chipdb_blob_8k = nullptr;
|
chipdb = "ice40/chipdb-8k.bin";
|
||||||
|
} else {
|
||||||
boost::iostreams::mapped_file blob_files[5];
|
log_error("Unknown chip\n");
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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");
|
return get_chip_info(chip) != nullptr;
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
#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)
|
Arch::Arch(ArchArgs args) : args(args)
|
||||||
{
|
{
|
||||||
#if defined(WIN32) || defined(EXTERNAL_CHIPDB_ROOT)
|
fast_part = (args.type == ArchArgs::HX8K || args.type == ArchArgs::HX1K);
|
||||||
load_chipdb();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ICE40_HX1K_ONLY
|
chip_info = get_chip_info(args.type);
|
||||||
if (args.type == ArchArgs::HX1K) {
|
if (chip_info == nullptr)
|
||||||
fast_part = true;
|
|
||||||
chip_info = get_chip_info(reinterpret_cast<const RelPtr<ChipInfoPOD> *>(chipdb_blob_1k));
|
|
||||||
} else {
|
|
||||||
log_error("Unsupported iCE40 chip type.\n");
|
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;
|
package_info = nullptr;
|
||||||
for (int i = 0; i < chip_info->num_packages; i++) {
|
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
|
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) {
|
if (args.type == ArchArgs::LP384) {
|
||||||
return "Lattice LP384";
|
return "Lattice LP384";
|
||||||
} else if (args.type == ArchArgs::LP1K) {
|
} else if (args.type == ArchArgs::LP1K) {
|
||||||
@ -159,7 +128,6 @@ std::string Arch::getChipName() const
|
|||||||
} else {
|
} else {
|
||||||
log_error("Unknown chip\n");
|
log_error("Unknown chip\n");
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
@ -642,13 +610,10 @@ bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay
|
|||||||
budget = 0;
|
budget = 0;
|
||||||
else {
|
else {
|
||||||
switch (args.type) {
|
switch (args.type) {
|
||||||
#ifndef ICE40_HX1K_ONLY
|
|
||||||
case ArchArgs::HX8K:
|
case ArchArgs::HX8K:
|
||||||
#endif
|
|
||||||
case ArchArgs::HX1K:
|
case ArchArgs::HX1K:
|
||||||
budget = cin ? 190 : (same_y ? 260 : 560);
|
budget = cin ? 190 : (same_y ? 260 : 560);
|
||||||
break;
|
break;
|
||||||
#ifndef ICE40_HX1K_ONLY
|
|
||||||
case ArchArgs::LP384:
|
case ArchArgs::LP384:
|
||||||
case ArchArgs::LP1K:
|
case ArchArgs::LP1K:
|
||||||
case ArchArgs::LP8K:
|
case ArchArgs::LP8K:
|
||||||
@ -658,7 +623,6 @@ bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay
|
|||||||
case ArchArgs::U4K:
|
case ArchArgs::U4K:
|
||||||
budget = cin ? 560 : (same_y ? 660 : 1220);
|
budget = cin ? 560 : (same_y ? 660 : 1220);
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
log_error("Unsupported iCE40 chip type.\n");
|
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;
|
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. ************************/
|
/************************ End of chipdb section. ************************/
|
||||||
|
|
||||||
struct BelIterator
|
struct BelIterator
|
||||||
@ -428,6 +414,9 @@ struct Arch : BaseCtx
|
|||||||
ArchArgs args;
|
ArchArgs args;
|
||||||
Arch(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 getChipName() const;
|
||||||
|
|
||||||
IdString archId() const { return id("ice40"); }
|
IdString archId() const { return id("ice40"); }
|
||||||
|
@ -1113,7 +1113,9 @@ class BinaryBlobAssembler:
|
|||||||
|
|
||||||
bba = BinaryBlobAssembler()
|
bba = BinaryBlobAssembler()
|
||||||
bba.pre('#include "nextpnr.h"')
|
bba.pre('#include "nextpnr.h"')
|
||||||
|
bba.pre('#include "embed.h"')
|
||||||
bba.pre('NEXTPNR_NAMESPACE_BEGIN')
|
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.post('NEXTPNR_NAMESPACE_END')
|
||||||
bba.push("chipdb_blob_%s" % dev_name)
|
bba.push("chipdb_blob_%s" % dev_name)
|
||||||
bba.r("chip_info_%s" % dev_name, "chip_info")
|
bba.r("chip_info_%s" % dev_name, "chip_info")
|
||||||
|
@ -30,9 +30,14 @@ foreach(device ${ICE40_DEVICES})
|
|||||||
endif()
|
endif()
|
||||||
endforeach()
|
endforeach()
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
list(APPEND chipdb_sources
|
set(chipdb_rc ${CMAKE_CURRENT_BINARY_DIR}/${family}/resource/chipdb.rc)
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/${family}/resource/embed.cc
|
list(APPEND chipdb_sources ${chipdb_rc})
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/${family}/resource/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()
|
endif()
|
||||||
|
|
||||||
add_custom_target(chipdb-${family}-bins DEPENDS ${chipdb_sources} ${chipdb_binaries})
|
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_options(chipdb-${family} PRIVATE -g0 -O0 -w)
|
||||||
target_compile_definitions(chipdb-${family} PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family})
|
target_compile_definitions(chipdb-${family} PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family})
|
||||||
target_include_directories(chipdb-${family} PRIVATE ${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})
|
foreach(family_target ${family_targets})
|
||||||
target_sources(${family_target} PRIVATE $<TARGET_OBJECTS:chipdb-${family}>)
|
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 Ice40CommandHandler::getArchOptions()
|
||||||
{
|
{
|
||||||
po::options_description specific("Architecture specific options");
|
po::options_description specific("Architecture specific options");
|
||||||
#ifdef ICE40_HX1K_ONLY
|
if (Arch::isAvailable(ArchArgs::LP384))
|
||||||
specific.add_options()("hx1k", "set device type to iCE40HX1K");
|
specific.add_options()("lp384", "set device type to iCE40LP384");
|
||||||
#else
|
if (Arch::isAvailable(ArchArgs::LP1K))
|
||||||
specific.add_options()("lp384", "set device type to iCE40LP384");
|
specific.add_options()("lp1k", "set device type to iCE40LP1K");
|
||||||
specific.add_options()("lp1k", "set device type to iCE40LP1K");
|
if (Arch::isAvailable(ArchArgs::LP8K))
|
||||||
specific.add_options()("lp8k", "set device type to iCE40LP8K");
|
specific.add_options()("lp8k", "set device type to iCE40LP8K");
|
||||||
specific.add_options()("hx1k", "set device type to iCE40HX1K");
|
if (Arch::isAvailable(ArchArgs::HX1K))
|
||||||
specific.add_options()("hx8k", "set device type to iCE40HX8K");
|
specific.add_options()("hx1k", "set device type to iCE40HX1K");
|
||||||
specific.add_options()("up5k", "set device type to iCE40UP5K");
|
if (Arch::isAvailable(ArchArgs::HX8K))
|
||||||
specific.add_options()("u4k", "set device type to iCE5LP4K");
|
specific.add_options()("hx8k", "set device type to iCE40HX8K");
|
||||||
#endif
|
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()("package", po::value<std::string>(), "set device package");
|
||||||
specific.add_options()("pcf", po::value<std::string>(), "PCF constraints file to ingest");
|
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");
|
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.type = ArchArgs::HX1K;
|
||||||
chipArgs.package = "tq144";
|
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));
|
auto ctx = std::unique_ptr<Context>(new Context(chipArgs));
|
||||||
for (auto &val : values)
|
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