From 73f200fe74d6844ec4b8bbaf0b7b4a8edb2696cd Mon Sep 17 00:00:00 2001
From: Miodrag Milanovic <mmicko@gmail.com>
Date: Sat, 9 Feb 2019 13:34:57 +0100
Subject: Load chipdb from filesystem as option

---
 CMakeLists.txt     |  11 +++-
 ecp5/arch.cc       |  29 +++++++++-
 ecp5/arch.h        |   2 +-
 ecp5/family.cmake  | 127 +++++++++++++++++++++--------------------
 ice40/arch.cc      |  31 +++++++++-
 ice40/arch.h       |   2 +-
 ice40/family.cmake | 164 +++++++++++++++++++++++++++--------------------------
 7 files changed, 217 insertions(+), 149 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 33a703d5..79ab066a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,6 +7,7 @@ option(BUILD_PYTHON "Build Python Integration" ON)
 option(BUILD_TESTS "Build GUI" OFF)
 option(COVERAGE "Add code coverage info" OFF)
 option(STATIC_BUILD "Create static build" OFF)
+option(EXTERNAL_CHIPDB "Create build with pre-built chipdb binaries" OFF)
 
 set(link_param "")
 if (STATIC_BUILD)
@@ -16,6 +17,14 @@ if (STATIC_BUILD)
     endif()
 endif()
 
+if (EXTERNAL_CHIPDB)
+    if (NOT DEFINED EXTERNAL_CHIPDB_ROOT)
+        message(STATUS "EXTERNAL_CHIPDB_ROOT not defined using -DEXTERNAL_CHIPDB_ROOT=/path/to/nextpnr. Default to /usr/local/share/nextpnr")
+        set(EXTERNAL_CHIPDB_ROOT "/usr/local/share/nextpnr")
+    endif()
+    add_definitions("-DEXTERNAL_CHIPDB_ROOT=\"${EXTERNAL_CHIPDB_ROOT}\"")
+endif()
+
 # List of families to build
 set(FAMILIES generic ice40 ecp5)
 
@@ -66,7 +75,7 @@ endif()
 find_package(Sanitizers)
 
 # List of Boost libraries to include
-set(boost_libs filesystem thread program_options)
+set(boost_libs filesystem thread program_options iostreams)
 
 if (BUILD_GUI AND NOT BUILD_PYTHON)
     message(FATAL_ERROR "GUI requires Python to build")
diff --git a/ecp5/arch.cc b/ecp5/arch.cc
index a2036033..75949b2f 100644
--- a/ecp5/arch.cc
+++ b/ecp5/arch.cc
@@ -19,6 +19,7 @@
  */
 
 #include <algorithm>
+#include <boost/iostreams/device/mapped_file.hpp>
 #include <boost/range/adaptor/reversed.hpp>
 #include <cmath>
 #include <cstring>
@@ -63,11 +64,37 @@ static const ChipInfoPOD *get_chip_info(const RelPtr<ChipInfoPOD> *ptr) { return
 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_source blob_files[3];
+
+const char *mmap_file(int index, const char *filename)
+{
+    try {
+        blob_files[index].open(filename);
+        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);
+    }
+}
+
+void load_chipdb()
+{
+    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");
+}
+#endif
 //#define LFE5U_45F_ONLY
 
 Arch::Arch(ArchArgs args) : args(args)
 {
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) || defined(EXTERNAL_CHIPDB_ROOT)
     load_chipdb();
 #endif
 #ifdef LFE5U_45F_ONLY
diff --git a/ecp5/arch.h b/ecp5/arch.h
index 4f2aaaa9..713c320e 100644
--- a/ecp5/arch.h
+++ b/ecp5/arch.h
@@ -204,7 +204,7 @@ NPNR_PACKED_STRUCT(struct ChipInfoPOD {
     RelPtr<SpeedGradePOD> speed_grades;
 });
 
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) || defined(EXTERNAL_CHIPDB_ROOT)
 extern const char *chipdb_blob_25k;
 extern const char *chipdb_blob_45k;
 extern const char *chipdb_blob_85k;
diff --git a/ecp5/family.cmake b/ecp5/family.cmake
index 679325b2..e23635ba 100644
--- a/ecp5/family.cmake
+++ b/ecp5/family.cmake
@@ -1,70 +1,71 @@
+if (NOT EXTERNAL_CHIPDB)
+    set(devices 25k 45k 85k)
 
-set(devices 25k 45k 85k)
+    if (NOT DEFINED TRELLIS_ROOT)
+        message(STATUS "TRELLIS_ROOT not defined using -DTRELLIS_ROOT=/path/to/prjtrellis. Default to /usr/local/share/trellis")
+        set(TRELLIS_ROOT "/usr/local/share/trellis")
+    endif()
 
-if (NOT DEFINED TRELLIS_ROOT)
-    message(STATUS "TRELLIS_ROOT not defined using -DTRELLIS_ROOT=/path/to/prjtrellis. Default to /usr/local/share/trellis")
-    set(TRELLIS_ROOT "/usr/local/share/trellis")
-endif()
+    file(GLOB found_pytrellis ${TRELLIS_ROOT}/libtrellis/pytrellis.*)
 
-file(GLOB found_pytrellis ${TRELLIS_ROOT}/libtrellis/pytrellis.*)
+    if ("${found_pytrellis}" STREQUAL "")
+        message(FATAL_ERROR "failed to find pytrellis library in ${TRELLIS_ROOT}/libtrellis/")
+    endif()
 
-if ("${found_pytrellis}" STREQUAL "")
-    message(FATAL_ERROR "failed to find pytrellis library in ${TRELLIS_ROOT}/libtrellis/")
-endif()
+    set(DB_PY ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/trellis_import.py)
 
-set(DB_PY ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/trellis_import.py)
+    file(MAKE_DIRECTORY ecp5/chipdbs/)
+    add_library(ecp5_chipdb OBJECT ecp5/chipdbs/)
+    target_compile_definitions(ecp5_chipdb PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family})
+    target_include_directories(ecp5_chipdb PRIVATE ${family}/)
 
-file(MAKE_DIRECTORY ecp5/chipdbs/)
-add_library(ecp5_chipdb OBJECT ecp5/chipdbs/)
-target_compile_definitions(ecp5_chipdb PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family})
-target_include_directories(ecp5_chipdb PRIVATE ${family}/)
+    if (CMAKE_HOST_WIN32)
+    set(ENV_CMD ${CMAKE_COMMAND} -E env "PYTHONPATH=\"${TRELLIS_ROOT}/libtrellis\;${TRELLIS_ROOT}/util/common\;${TRELLIS_ROOT}/timing/util\"")
+    else()
+    set(ENV_CMD ${CMAKE_COMMAND} -E env "PYTHONPATH=${TRELLIS_ROOT}/libtrellis:${TRELLIS_ROOT}/util/common:${TRELLIS_ROOT}/timing/util")
+    endif()
 
-if (CMAKE_HOST_WIN32)
-set(ENV_CMD ${CMAKE_COMMAND} -E env "PYTHONPATH=\"${TRELLIS_ROOT}/libtrellis\;${TRELLIS_ROOT}/util/common\;${TRELLIS_ROOT}/timing/util\"")
-else()
-set(ENV_CMD ${CMAKE_COMMAND} -E env "PYTHONPATH=${TRELLIS_ROOT}/libtrellis:${TRELLIS_ROOT}/util/common:${TRELLIS_ROOT}/timing/util")
-endif()
-
-if (MSVC)
-    target_sources(ecp5_chipdb PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/resource/embed.cc)
-    set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/ecp5/resources/chipdb.rc PROPERTIES LANGUAGE RC)
-    foreach (dev ${devices})
-        set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.bin)
-        set(DEV_CC_BBA_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.bba)
-	set(DEV_CONSTIDS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/constids.inc)
-        add_custom_command(OUTPUT ${DEV_CC_BBA_DB}
-		COMMAND ${ENV_CMD} python3 ${DB_PY} -p ${DEV_CONSTIDS_INC} ${dev} > ${DEV_CC_BBA_DB}
-                DEPENDS ${DB_PY}
-                )
-        add_custom_command(OUTPUT ${DEV_CC_DB}
-                COMMAND bbasm ${DEV_CC_BBA_DB} ${DEV_CC_DB}
-                DEPENDS bbasm ${DEV_CC_BBA_DB}
-                )
-        target_sources(ecp5_chipdb PRIVATE ${DEV_CC_DB})
-        set_source_files_properties(${DEV_CC_DB} PROPERTIES HEADER_FILE_ONLY TRUE)
-        foreach (target ${family_targets})
-            target_sources(${target} PRIVATE $<TARGET_OBJECTS:ecp5_chipdb> ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/resource/chipdb.rc)
-        endforeach (target)
-    endforeach (dev)
-else()
-    target_compile_options(ecp5_chipdb PRIVATE -g0 -O0 -w)
-    foreach (dev ${devices})
-        set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.cc)
-        set(DEV_CC_BBA_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.bba)
-	set(DEV_CONSTIDS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/constids.inc)
-        add_custom_command(OUTPUT ${DEV_CC_BBA_DB}
-		COMMAND ${ENV_CMD} python3 ${DB_PY} -p ${DEV_CONSTIDS_INC} ${dev} > ${DEV_CC_BBA_DB}.new
-                COMMAND mv ${DEV_CC_BBA_DB}.new ${DEV_CC_BBA_DB}
-                DEPENDS ${DB_PY}
-                )
-        add_custom_command(OUTPUT ${DEV_CC_DB}
-                COMMAND bbasm --c ${DEV_CC_BBA_DB} ${DEV_CC_DB}.new
-                COMMAND mv ${DEV_CC_DB}.new ${DEV_CC_DB}
-                DEPENDS bbasm ${DEV_CC_BBA_DB}
-                )
-        target_sources(ecp5_chipdb PRIVATE ${DEV_CC_DB})
-        foreach (target ${family_targets})
-            target_sources(${target} PRIVATE $<TARGET_OBJECTS:ecp5_chipdb>)
-        endforeach (target)
-    endforeach (dev)
-endif()
+    if (MSVC)
+        target_sources(ecp5_chipdb PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/resource/embed.cc)
+        set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/ecp5/resources/chipdb.rc PROPERTIES LANGUAGE RC)
+        foreach (dev ${devices})
+            set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.bin)
+            set(DEV_CC_BBA_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.bba)
+        set(DEV_CONSTIDS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/constids.inc)
+            add_custom_command(OUTPUT ${DEV_CC_BBA_DB}
+            COMMAND ${ENV_CMD} python3 ${DB_PY} -p ${DEV_CONSTIDS_INC} ${dev} > ${DEV_CC_BBA_DB}
+                    DEPENDS ${DB_PY}
+                    )
+            add_custom_command(OUTPUT ${DEV_CC_DB}
+                    COMMAND bbasm ${DEV_CC_BBA_DB} ${DEV_CC_DB}
+                    DEPENDS bbasm ${DEV_CC_BBA_DB}
+                    )
+            target_sources(ecp5_chipdb PRIVATE ${DEV_CC_DB})
+            set_source_files_properties(${DEV_CC_DB} PROPERTIES HEADER_FILE_ONLY TRUE)
+            foreach (target ${family_targets})
+                target_sources(${target} PRIVATE $<TARGET_OBJECTS:ecp5_chipdb> ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/resource/chipdb.rc)
+            endforeach (target)
+        endforeach (dev)
+    else()
+        target_compile_options(ecp5_chipdb PRIVATE -g0 -O0 -w)
+        foreach (dev ${devices})
+            set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.cc)
+            set(DEV_CC_BBA_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.bba)
+        set(DEV_CONSTIDS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/constids.inc)
+            add_custom_command(OUTPUT ${DEV_CC_BBA_DB}
+            COMMAND ${ENV_CMD} python3 ${DB_PY} -p ${DEV_CONSTIDS_INC} ${dev} > ${DEV_CC_BBA_DB}.new
+                    COMMAND mv ${DEV_CC_BBA_DB}.new ${DEV_CC_BBA_DB}
+                    DEPENDS ${DB_PY}
+                    )
+            add_custom_command(OUTPUT ${DEV_CC_DB}
+                    COMMAND bbasm --c ${DEV_CC_BBA_DB} ${DEV_CC_DB}.new
+                    COMMAND mv ${DEV_CC_DB}.new ${DEV_CC_DB}
+                    DEPENDS bbasm ${DEV_CC_BBA_DB}
+                    )
+            target_sources(ecp5_chipdb PRIVATE ${DEV_CC_DB})
+            foreach (target ${family_targets})
+                target_sources(${target} PRIVATE $<TARGET_OBJECTS:ecp5_chipdb>)
+            endforeach (target)
+        endforeach (dev)
+    endif()
+endif()
\ No newline at end of file
diff --git a/ice40/arch.cc b/ice40/arch.cc
index f6084e72..23a2130c 100644
--- a/ice40/arch.cc
+++ b/ice40/arch.cc
@@ -19,6 +19,7 @@
  */
 
 #include <algorithm>
+#include <boost/iostreams/device/mapped_file.hpp>
 #include <cmath>
 #include "cells.h"
 #include "gfx.h"
@@ -48,9 +49,37 @@ static const ChipInfoPOD *get_chip_info(const RelPtr<ChipInfoPOD> *ptr) { return
 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_8k = nullptr;
+
+boost::iostreams::mapped_file_source blob_files[4];
+
+const char *mmap_file(int index, const char *filename)
+{
+    try {
+        blob_files[index].open(filename);
+        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);
+    }
+}
+
+void load_chipdb()
+{
+    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_8k = mmap_file(3, EXTERNAL_CHIPDB_ROOT "/ice40/chipdb-8k.bin");
+}
+#endif
 Arch::Arch(ArchArgs args) : args(args)
 {
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) || defined(EXTERNAL_CHIPDB_ROOT)
     load_chipdb();
 #endif
 
diff --git a/ice40/arch.h b/ice40/arch.h
index 2dd6b06c..b25e3aee 100644
--- a/ice40/arch.h
+++ b/ice40/arch.h
@@ -244,7 +244,7 @@ NPNR_PACKED_STRUCT(struct ChipInfoPOD {
     RelPtr<RelPtr<char>> tile_wire_names;
 });
 
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) || defined(EXTERNAL_CHIPDB_ROOT)
 extern const char *chipdb_blob_384;
 extern const char *chipdb_blob_1k;
 extern const char *chipdb_blob_5k;
diff --git a/ice40/family.cmake b/ice40/family.cmake
index 0e1d36e6..b61a8d9e 100644
--- a/ice40/family.cmake
+++ b/ice40/family.cmake
@@ -1,84 +1,86 @@
-if(ICE40_HX1K_ONLY)
-    set(devices 1k)
-    foreach (target ${family_targets})
-        target_compile_definitions(${target} PRIVATE ICE40_HX1K_ONLY=1)
-    endforeach (target)
-else()
-    set(devices 384 1k 5k 8k)
-endif()
+if (NOT EXTERNAL_CHIPDB)
+    if(ICE40_HX1K_ONLY)
+        set(devices 1k)
+        foreach (target ${family_targets})
+            target_compile_definitions(${target} PRIVATE ICE40_HX1K_ONLY=1)
+        endforeach (target)
+    else()
+        set(devices 384 1k 5k 8k)
+    endif()
 
-set(DB_PY ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdb.py)
+    set(DB_PY ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdb.py)
 
-set(ICEBOX_ROOT "/usr/local/share/icebox" CACHE STRING "icebox location root")
-file(MAKE_DIRECTORY ice40/chipdbs/)
-add_library(ice40_chipdb OBJECT ice40/chipdbs/)
-target_compile_definitions(ice40_chipdb PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family})
-target_include_directories(ice40_chipdb PRIVATE ${family}/)
+    set(ICEBOX_ROOT "/usr/local/share/icebox" CACHE STRING "icebox location root")
+    file(MAKE_DIRECTORY ice40/chipdbs/)
+    add_library(ice40_chipdb OBJECT ice40/chipdbs/)
+    target_compile_definitions(ice40_chipdb PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family})
+    target_include_directories(ice40_chipdb PRIVATE ${family}/)
 
-if (MSVC)
-    target_sources(ice40_chipdb PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/ice40/resource/embed.cc)
-    set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/ice40/resources/chipdb.rc PROPERTIES LANGUAGE RC)
-    foreach (dev ${devices})
-        if (dev EQUAL "5k")
-            set(OPT_FAST "")
-            set(OPT_SLOW --slow ${ICEBOX_ROOT}/timings_up5k.txt)
-        elseif(dev EQUAL "384")
-            set(OPT_FAST "")
-            set(OPT_SLOW --slow ${ICEBOX_ROOT}/timings_lp384.txt)
-        else()
-            set(OPT_FAST --fast ${ICEBOX_ROOT}/timings_hx${dev}.txt)
-            set(OPT_SLOW --slow ${ICEBOX_ROOT}/timings_lp${dev}.txt)
-        endif()
-        set(DEV_TXT_DB ${ICEBOX_ROOT}/chipdb-${dev}.txt)
-        set(DEV_CC_BBA_DB ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdbs/chipdb-${dev}.bba)
-        set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdbs/chipdb-${dev}.bin)
-        set(DEV_CONSTIDS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ice40/constids.inc)
-        set(DEV_GFXH ${CMAKE_CURRENT_SOURCE_DIR}/ice40/gfx.h)
-        add_custom_command(OUTPUT ${DEV_CC_BBA_DB}
-                COMMAND ${PYTHON_EXECUTABLE} ${DB_PY} -p ${DEV_CONSTIDS_INC} -g ${DEV_GFXH} ${OPT_FAST} ${OPT_SLOW} ${DEV_TXT_DB} > ${DEV_CC_BBA_DB}
-                DEPENDS ${DEV_CONSTIDS_INC} ${DEV_GFXH} ${DEV_TXT_DB} ${DB_PY}
-                )
-        add_custom_command(OUTPUT ${DEV_CC_DB}
-                COMMAND bbasm ${DEV_CC_BBA_DB} ${DEV_CC_DB}
-                DEPENDS bbasm ${DEV_CC_BBA_DB}
-        )
-        target_sources(ice40_chipdb PRIVATE ${DEV_CC_DB})
-        set_source_files_properties(${DEV_CC_DB} PROPERTIES HEADER_FILE_ONLY TRUE)
-        foreach (target ${family_targets})
-            target_sources(${target} PRIVATE $<TARGET_OBJECTS:ice40_chipdb> ${CMAKE_CURRENT_SOURCE_DIR}/ice40/resource/chipdb.rc)
-        endforeach (target)
-    endforeach (dev)
-else()
-    target_compile_options(ice40_chipdb PRIVATE -g0 -O0 -w)
-    foreach (dev ${devices})
-        if (dev EQUAL "5k")
-            set(OPT_FAST "")
-            set(OPT_SLOW --slow ${ICEBOX_ROOT}/timings_up5k.txt)
-        elseif(dev EQUAL "384")
-            set(OPT_FAST "")
-            set(OPT_SLOW --slow ${ICEBOX_ROOT}/timings_lp384.txt)
-        else()
-            set(OPT_FAST --fast ${ICEBOX_ROOT}/timings_hx${dev}.txt)
-            set(OPT_SLOW --slow ${ICEBOX_ROOT}/timings_lp${dev}.txt)
-        endif()
-        set(DEV_TXT_DB ${ICEBOX_ROOT}/chipdb-${dev}.txt)
-        set(DEV_CC_BBA_DB ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdbs/chipdb-${dev}.bba)
-        set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdbs/chipdb-${dev}.cc)
-        set(DEV_CONSTIDS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ice40/constids.inc)
-        set(DEV_GFXH ${CMAKE_CURRENT_SOURCE_DIR}/ice40/gfx.h)
-        add_custom_command(OUTPUT ${DEV_CC_BBA_DB}
-                COMMAND ${PYTHON_EXECUTABLE} ${DB_PY} -p ${DEV_CONSTIDS_INC} -g ${DEV_GFXH} ${OPT_FAST} ${OPT_SLOW} ${DEV_TXT_DB} > ${DEV_CC_BBA_DB}.new
-                COMMAND mv ${DEV_CC_BBA_DB}.new ${DEV_CC_BBA_DB}
-                DEPENDS ${DEV_CONSTIDS_INC} ${DEV_GFXH} ${DEV_TXT_DB} ${DB_PY}
-        )
-        add_custom_command(OUTPUT ${DEV_CC_DB}
-                COMMAND bbasm --c ${DEV_CC_BBA_DB} ${DEV_CC_DB}.new
-                COMMAND mv ${DEV_CC_DB}.new ${DEV_CC_DB}
-                DEPENDS bbasm ${DEV_CC_BBA_DB}
-        )
-        target_sources(ice40_chipdb PRIVATE ${DEV_CC_DB})
-        foreach (target ${family_targets})
-            target_sources(${target} PRIVATE $<TARGET_OBJECTS:ice40_chipdb>)
-        endforeach (target)
-    endforeach (dev)
-endif()
+    if (MSVC)
+        target_sources(ice40_chipdb PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/ice40/resource/embed.cc)
+        set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/ice40/resources/chipdb.rc PROPERTIES LANGUAGE RC)
+        foreach (dev ${devices})
+            if (dev EQUAL "5k")
+                set(OPT_FAST "")
+                set(OPT_SLOW --slow ${ICEBOX_ROOT}/timings_up5k.txt)
+            elseif(dev EQUAL "384")
+                set(OPT_FAST "")
+                set(OPT_SLOW --slow ${ICEBOX_ROOT}/timings_lp384.txt)
+            else()
+                set(OPT_FAST --fast ${ICEBOX_ROOT}/timings_hx${dev}.txt)
+                set(OPT_SLOW --slow ${ICEBOX_ROOT}/timings_lp${dev}.txt)
+            endif()
+            set(DEV_TXT_DB ${ICEBOX_ROOT}/chipdb-${dev}.txt)
+            set(DEV_CC_BBA_DB ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdbs/chipdb-${dev}.bba)
+            set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdbs/chipdb-${dev}.bin)
+            set(DEV_CONSTIDS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ice40/constids.inc)
+            set(DEV_GFXH ${CMAKE_CURRENT_SOURCE_DIR}/ice40/gfx.h)
+            add_custom_command(OUTPUT ${DEV_CC_BBA_DB}
+                    COMMAND ${PYTHON_EXECUTABLE} ${DB_PY} -p ${DEV_CONSTIDS_INC} -g ${DEV_GFXH} ${OPT_FAST} ${OPT_SLOW} ${DEV_TXT_DB} > ${DEV_CC_BBA_DB}
+                    DEPENDS ${DEV_CONSTIDS_INC} ${DEV_GFXH} ${DEV_TXT_DB} ${DB_PY}
+                    )
+            add_custom_command(OUTPUT ${DEV_CC_DB}
+                    COMMAND bbasm ${DEV_CC_BBA_DB} ${DEV_CC_DB}
+                    DEPENDS bbasm ${DEV_CC_BBA_DB}
+            )
+            target_sources(ice40_chipdb PRIVATE ${DEV_CC_DB})
+            set_source_files_properties(${DEV_CC_DB} PROPERTIES HEADER_FILE_ONLY TRUE)
+            foreach (target ${family_targets})
+                target_sources(${target} PRIVATE $<TARGET_OBJECTS:ice40_chipdb> ${CMAKE_CURRENT_SOURCE_DIR}/ice40/resource/chipdb.rc)
+            endforeach (target)
+        endforeach (dev)
+    else()
+        target_compile_options(ice40_chipdb PRIVATE -g0 -O0 -w)
+        foreach (dev ${devices})
+            if (dev EQUAL "5k")
+                set(OPT_FAST "")
+                set(OPT_SLOW --slow ${ICEBOX_ROOT}/timings_up5k.txt)
+            elseif(dev EQUAL "384")
+                set(OPT_FAST "")
+                set(OPT_SLOW --slow ${ICEBOX_ROOT}/timings_lp384.txt)
+            else()
+                set(OPT_FAST --fast ${ICEBOX_ROOT}/timings_hx${dev}.txt)
+                set(OPT_SLOW --slow ${ICEBOX_ROOT}/timings_lp${dev}.txt)
+            endif()
+            set(DEV_TXT_DB ${ICEBOX_ROOT}/chipdb-${dev}.txt)
+            set(DEV_CC_BBA_DB ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdbs/chipdb-${dev}.bba)
+            set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ice40/chipdbs/chipdb-${dev}.cc)
+            set(DEV_CONSTIDS_INC ${CMAKE_CURRENT_SOURCE_DIR}/ice40/constids.inc)
+            set(DEV_GFXH ${CMAKE_CURRENT_SOURCE_DIR}/ice40/gfx.h)
+            add_custom_command(OUTPUT ${DEV_CC_BBA_DB}
+                    COMMAND ${PYTHON_EXECUTABLE} ${DB_PY} -p ${DEV_CONSTIDS_INC} -g ${DEV_GFXH} ${OPT_FAST} ${OPT_SLOW} ${DEV_TXT_DB} > ${DEV_CC_BBA_DB}.new
+                    COMMAND mv ${DEV_CC_BBA_DB}.new ${DEV_CC_BBA_DB}
+                    DEPENDS ${DEV_CONSTIDS_INC} ${DEV_GFXH} ${DEV_TXT_DB} ${DB_PY}
+            )
+            add_custom_command(OUTPUT ${DEV_CC_DB}
+                    COMMAND bbasm --c ${DEV_CC_BBA_DB} ${DEV_CC_DB}.new
+                    COMMAND mv ${DEV_CC_DB}.new ${DEV_CC_DB}
+                    DEPENDS bbasm ${DEV_CC_BBA_DB}
+            )
+            target_sources(ice40_chipdb PRIVATE ${DEV_CC_DB})
+            foreach (target ${family_targets})
+                target_sources(${target} PRIVATE $<TARGET_OBJECTS:ice40_chipdb>)
+            endforeach (target)
+        endforeach (dev)
+    endif()
+endif()
\ No newline at end of file
-- 
cgit v1.2.3


From 8b0af0e48d22779b5f2e047541e9e037375cb4cd Mon Sep 17 00:00:00 2001
From: Miodrag Milanovic <mmicko@gmail.com>
Date: Sun, 10 Feb 2019 08:33:52 +0100
Subject: Fix according to comments on PR

---
 CMakeLists.txt     | 4 ++--
 ecp5/family.cmake  | 2 +-
 ice40/family.cmake | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 79ab066a..4f29d132 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -19,8 +19,8 @@ endif()
 
 if (EXTERNAL_CHIPDB)
     if (NOT DEFINED EXTERNAL_CHIPDB_ROOT)
-        message(STATUS "EXTERNAL_CHIPDB_ROOT not defined using -DEXTERNAL_CHIPDB_ROOT=/path/to/nextpnr. Default to /usr/local/share/nextpnr")
-        set(EXTERNAL_CHIPDB_ROOT "/usr/local/share/nextpnr")
+        message(STATUS "EXTERNAL_CHIPDB_ROOT not defined using -DEXTERNAL_CHIPDB_ROOT=/path/to/nextpnr. Default to /usr/share/nextpnr")
+        set(EXTERNAL_CHIPDB_ROOT "/usr/share/nextpnr")
     endif()
     add_definitions("-DEXTERNAL_CHIPDB_ROOT=\"${EXTERNAL_CHIPDB_ROOT}\"")
 endif()
diff --git a/ecp5/family.cmake b/ecp5/family.cmake
index e23635ba..06dc6761 100644
--- a/ecp5/family.cmake
+++ b/ecp5/family.cmake
@@ -68,4 +68,4 @@ if (NOT EXTERNAL_CHIPDB)
             endforeach (target)
         endforeach (dev)
     endif()
-endif()
\ No newline at end of file
+endif()
diff --git a/ice40/family.cmake b/ice40/family.cmake
index b61a8d9e..877b27ee 100644
--- a/ice40/family.cmake
+++ b/ice40/family.cmake
@@ -83,4 +83,4 @@ if (NOT EXTERNAL_CHIPDB)
             endforeach (target)
         endforeach (dev)
     endif()
-endif()
\ No newline at end of file
+endif()
-- 
cgit v1.2.3