Merge pull request #332 from YosysHQ/dave/python-refactor

Improving Python API and adding docs for it
diff --git a/README.md b/README.md
index 10e3bde..efbc6bb 100644
--- a/README.md
+++ b/README.md
@@ -155,6 +155,10 @@
 You can change the location where nextpnr will be installed (this will usually default to `/usr/local`) by using
 `-DCMAKE_INSTALL_PREFIX=/install/prefix`.
 
+It is possible to pre-generate `.bba` files.  This can come in handy when building on time-constrained cloud
+instances, or in situations where python is unable to use modules.  To do this, specify the path to pre-
+generated `.bba` files by passing `-DPREGENERATED_BBA_PATH=` to cmake.
+
 Notes for developers
 --------------------
 
diff --git a/bba/bba.cmake b/bba/bba.cmake
index 3e09427..a6995ca 100644
--- a/bba/bba.cmake
+++ b/bba/bba.cmake
@@ -11,3 +11,11 @@
 IF(NOT CMAKE_CROSSCOMPILING)
     EXPORT(TARGETS bbasm FILE ${CMAKE_BINARY_DIR}/ImportExecutables.cmake )
 ENDIF(NOT CMAKE_CROSSCOMPILING)
+
+include(TestBigEndian)
+TEST_BIG_ENDIAN(IS_BIG_ENDIAN)
+if(IS_BIG_ENDIAN)
+	set(BBASM_ENDIAN_FLAG "--be")
+else()
+	set(BBASM_ENDIAN_FLAG "--le")
+endif()
diff --git a/bba/main.cc b/bba/main.cc
index 32a68c6..d4d16e1 100644
--- a/bba/main.cc
+++ b/bba/main.cc
@@ -70,7 +70,7 @@
 {
     bool debug = false;
     bool verbose = false;
-    bool bigEndian = false;
+    bool bigEndian;
     bool writeC = false;
     char buffer[512];
 
@@ -81,6 +81,7 @@
     options.add_options()("verbose,v", "verbose output");
     options.add_options()("debug,d", "debug output");
     options.add_options()("be,b", "big endian");
+    options.add_options()("le,l", "little endian");
     options.add_options()("c,c", "write c strings");
     options.add_options()("files", po::value<std::vector<std::string>>(), "file parameters");
     pos.add("files", -1);
@@ -106,6 +107,12 @@
         debug = true;
     if (vm.count("be"))
         bigEndian = true;
+    else if (vm.count("le"))
+        bigEndian = false;
+    else {
+        printf("Endian parameter is mandatory\n");
+        exit(-1);
+    }
     if (vm.count("c"))
         writeC = true;
 
diff --git a/ecp5/family.cmake b/ecp5/family.cmake
index ec85756..5512e7d 100644
--- a/ecp5/family.cmake
+++ b/ecp5/family.cmake
@@ -22,7 +22,8 @@
     set(DB_PY ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/trellis_import.py)
 
     file(MAKE_DIRECTORY ecp5/chipdbs/)
-    add_library(ecp5_chipdb OBJECT ecp5/chipdbs/)
+    file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/ecp5/chipdbs/)
+    add_library(ecp5_chipdb OBJECT ${CMAKE_CURRENT_BINARY_DIR}/ecp5/chipdbs/)
     target_compile_definitions(ecp5_chipdb PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family})
     target_include_directories(ecp5_chipdb PRIVATE ${family}/)
 
@@ -37,17 +38,23 @@
         set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/ecp5/resources/chipdb.rc PROPERTIES LANGUAGE RC)
         set(PREV_DEV_CC_BBA_DB)
         foreach (dev ${devices})
-            set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.bin)
+            set(DEV_CC_DB ${CMAKE_CURRENT_BINARY_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} ${PYTHON_EXECUTABLE} ${DB_PY} -p ${DEV_CONSTIDS_INC} ${dev} > ${DEV_CC_BBA_DB}
-                DEPENDS ${DB_PY} ${PREV_DEV_CC_BBA_DB}
-                )
-            add_custom_command(OUTPUT ${DEV_CC_DB}
-                COMMAND bbasm ${DEV_CC_BBA_DB} ${DEV_CC_DB}
-                DEPENDS bbasm ${DEV_CC_BBA_DB}
-                )
+            if (PREGENERATED_BBA_PATH)
+                add_custom_command(OUTPUT ${DEV_CC_DB}
+                    COMMAND bbasm ${BBASM_ENDIAN_FLAG} ${PREGENERATED_BBA_PATH}/chipdb-${dev}.bba ${DEV_CC_DB}
+                    )
+            else()
+                add_custom_command(OUTPUT ${DEV_CC_BBA_DB}
+                    COMMAND ${ENV_CMD} ${PYTHON_EXECUTABLE} ${DB_PY} -p ${DEV_CONSTIDS_INC} ${dev} > ${DEV_CC_BBA_DB}
+                    DEPENDS ${DB_PY} ${PREV_DEV_CC_BBA_DB}
+                    )
+                add_custom_command(OUTPUT ${DEV_CC_DB}
+                    COMMAND bbasm ${BBASM_ENDIAN_FLAG} ${DEV_CC_BBA_DB} ${DEV_CC_DB}
+                    DEPENDS bbasm ${DEV_CC_BBA_DB}
+                    )
+            endif()
             if (SERIALIZE_CHIPDB)
                 set(PREV_DEV_CC_BBA_DB ${DEV_CC_BBA_DB})
             endif()
@@ -61,19 +68,26 @@
         target_compile_options(ecp5_chipdb PRIVATE -g0 -O0 -w)
         set(PREV_DEV_CC_BBA_DB)
         foreach (dev ${devices})
-            set(DEV_CC_DB ${CMAKE_CURRENT_SOURCE_DIR}/ecp5/chipdbs/chipdb-${dev}.cc)
+            set(DEV_CC_DB ${CMAKE_CURRENT_BINARY_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} ${PYTHON_EXECUTABLE} ${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} ${PREV_DEV_CC_BBA_DB}
-                )
-            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}
-                )
+            if (PREGENERATED_BBA_PATH)
+                add_custom_command(OUTPUT ${DEV_CC_DB}
+                    COMMAND bbasm --c ${BBASM_ENDIAN_FLAG} ${PREGENERATED_BBA_PATH}/chipdb-${dev}.bba ${DEV_CC_DB}.new
+                    COMMAND mv ${DEV_CC_DB}.new ${DEV_CC_DB}
+                    )
+            else()
+                add_custom_command(OUTPUT ${DEV_CC_BBA_DB}
+                    COMMAND ${ENV_CMD} ${PYTHON_EXECUTABLE} ${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} ${PREV_DEV_CC_BBA_DB}
+                    )
+                add_custom_command(OUTPUT ${DEV_CC_DB}
+                    COMMAND bbasm --c ${BBASM_ENDIAN_FLAG} ${DEV_CC_BBA_DB} ${DEV_CC_DB}.new
+                    COMMAND mv ${DEV_CC_DB}.new ${DEV_CC_DB}
+                    DEPENDS bbasm ${DEV_CC_BBA_DB}
+                    )
+            endif()
             if (SERIALIZE_CHIPDB)
                 set(PREV_DEV_CC_BBA_DB ${DEV_CC_BBA_DB})
             endif()
diff --git a/ice40/family.cmake b/ice40/family.cmake
index 6c46f45..f22883f 100644
--- a/ice40/family.cmake
+++ b/ice40/family.cmake
@@ -12,7 +12,8 @@
 
     set(ICEBOX_ROOT "/usr/local/share/icebox" CACHE STRING "icebox location root")
     file(MAKE_DIRECTORY ice40/chipdbs/)
-    add_library(ice40_chipdb OBJECT ice40/chipdbs/)
+    file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/ice40/chipdbs/)
+    add_library(ice40_chipdb OBJECT ${CMAKE_CURRENT_BINARY_DIR}/ice40/chipdbs/)
     target_compile_definitions(ice40_chipdb PRIVATE NEXTPNR_NAMESPACE=nextpnr_${family})
     target_include_directories(ice40_chipdb PRIVATE ${family}/)
 
@@ -36,7 +37,7 @@
             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_CC_DB ${CMAKE_CURRENT_BINARY_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}
@@ -44,9 +45,24 @@
                 DEPENDS ${DEV_CONSTIDS_INC} ${DEV_GFXH} ${DEV_TXT_DB} ${DB_PY} ${PREV_DEV_CC_BBA_DB}
                 )
             add_custom_command(OUTPUT ${DEV_CC_DB}
-                COMMAND bbasm ${DEV_CC_BBA_DB} ${DEV_CC_DB}
+                COMMAND bbasm ${BBASM_ENDIAN_FLAG} ${DEV_CC_BBA_DB} ${DEV_CC_DB}
                 DEPENDS bbasm ${DEV_CC_BBA_DB}
                 )
+
+            if(PREGENERATED_BBA_PATH)
+                add_custom_command(OUTPUT ${DEV_CC_DB}
+                    COMMAND bbasm ${BBASM_ENDIAN_FLAG} ${PREGENERATED_BBA_PATH}/chipdb-${dev}.bba ${DEV_CC_DB}
+                    )
+            else()
+                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} ${PREV_DEV_CC_BBA_DB}
+                    )
+                add_custom_command(OUTPUT ${DEV_CC_DB}
+                    COMMAND bbasm ${BBASM_ENDIAN_FLAG} ${DEV_CC_BBA_DB} ${DEV_CC_DB}
+                    DEPENDS bbasm ${DEV_CC_BBA_DB}
+                    )
+            endif()
             if (SERIALIZE_CHIPDB)
                 set(PREV_DEV_CC_BBA_DB ${DEV_CC_BBA_DB})
             endif()
@@ -75,19 +91,26 @@
             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_CC_DB ${CMAKE_CURRENT_BINARY_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} ${PREV_DEV_CC_BBA_DB}
-                )
-            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}
-                )
+            if(PREGENERATED_BBA_PATH)
+                add_custom_command(OUTPUT ${DEV_CC_DB}
+                    COMMAND bbasm --c ${BBASM_ENDIAN_FLAG} ${PREGENERATED_BBA_PATH}/chipdb-${dev}.bba ${DEV_CC_DB}.new
+                    COMMAND mv ${DEV_CC_DB}.new ${DEV_CC_DB}
+                    )
+            else()
+                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} ${PREV_DEV_CC_BBA_DB}
+                    )
+                add_custom_command(OUTPUT ${DEV_CC_DB}
+                    COMMAND bbasm --c ${BBASM_ENDIAN_FLAG} ${DEV_CC_BBA_DB} ${DEV_CC_DB}.new
+                    COMMAND mv ${DEV_CC_DB}.new ${DEV_CC_DB}
+                    DEPENDS bbasm ${DEV_CC_BBA_DB}
+                    )
+            endif()
             if (SERIALIZE_CHIPDB)
                 set(PREV_DEV_CC_BBA_DB ${DEV_CC_BBA_DB})
             endif()