diff options
-rw-r--r-- | .cirrus.yml | 4 | ||||
-rw-r--r-- | .gitmodules | 3 | ||||
-rw-r--r-- | CMakeLists.txt | 11 | ||||
-rw-r--r-- | common/timing.cc | 3 | ||||
-rw-r--r-- | ecp5/arch.cc | 52 | ||||
-rw-r--r-- | ecp5/arch.h | 2 | ||||
-rw-r--r-- | ecp5/family.cmake | 130 | ||||
-rw-r--r-- | ice40/arch.cc | 31 | ||||
-rw-r--r-- | ice40/arch.h | 2 | ||||
-rw-r--r-- | ice40/family.cmake | 162 | ||||
-rw-r--r-- | ice40/pack.cc | 9 | ||||
m--------- | tests | 0 | ||||
-rw-r--r-- | tests/generic/main.cc | 28 | ||||
-rw-r--r-- | tests/gui/quadtree.cc | 122 | ||||
-rw-r--r-- | tests/ice40/hx1k.cc | 106 | ||||
-rw-r--r-- | tests/ice40/hx8k.cc | 106 | ||||
-rw-r--r-- | tests/ice40/lp1k.cc | 106 | ||||
-rw-r--r-- | tests/ice40/lp384.cc | 106 | ||||
-rw-r--r-- | tests/ice40/lp8k.cc | 106 | ||||
-rw-r--r-- | tests/ice40/main.cc | 27 | ||||
-rw-r--r-- | tests/ice40/up5k.cc | 106 |
21 files changed, 258 insertions, 964 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index 38e14513..2347b502 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -6,7 +6,9 @@ task: dockerfile: .cirrus/Dockerfile.ubuntu16.04 build_script: mkdir build && cd build && cmake .. -DARCH=all -DTRELLIS_ROOT=/usr/local/src/prjtrellis -DBUILD_TESTS=on && make -j $(nproc) + submodule_script: git submodule sync --recursive && git submodule update --init --recursive test_generic_script: cd build && ./nextpnr-generic-test test_ice40_script: cd build && ./nextpnr-ice40-test smoketest_ice40_script: export NEXTPNR=$(pwd)/build/nextpnr-ice40 && cd ice40/smoketest/attosoc && ./smoketest.sh - test_ecp5_script: cd build && ./nextpnr-ecp5-test
\ No newline at end of file + test_ecp5_script: cd build && ./nextpnr-ecp5-test + regressiontest_ice40_script: make -j $(nproc) -C tests/ice40/regressions NPNR=$(pwd)/build/nextpnr-ice40 diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..52194b76 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "tests"] + path = tests + url = https://github.com/YosysHQ/nextpnr-tests diff --git a/CMakeLists.txt b/CMakeLists.txt index 33a703d5..4f29d132 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/share/nextpnr") + set(EXTERNAL_CHIPDB_ROOT "/usr/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/common/timing.cc b/common/timing.cc index 13f0e07b..64dcdf71 100644 --- a/common/timing.cc +++ b/common/timing.cc @@ -930,8 +930,7 @@ void timing_analysis(Context *ctx, bool print_histogram, bool print_fmax, bool p unsigned bar_width = 60; auto min_slack = slack_histogram.begin()->first; auto max_slack = slack_histogram.rbegin()->first; - auto bin_size = std::max(1u, (max_slack - min_slack) / num_bins); - num_bins = std::min((max_slack - min_slack) / bin_size, num_bins) + 1; + auto bin_size = std::max<unsigned>(1, ceil((max_slack - min_slack + 1) / float(num_bins))); std::vector<unsigned> bins(num_bins); unsigned max_freq = 0; for (const auto &i : slack_histogram) { diff --git a/ecp5/arch.cc b/ecp5/arch.cc index a2036033..23cdea3b 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 @@ -400,7 +427,28 @@ BelId Arch::getBelByLocation(Loc loc) const delay_t Arch::estimateDelay(WireId src, WireId dst) const { - return (240 - 20 * args.speed) * (abs(src.location.x - dst.location.x) + abs(src.location.y - dst.location.y)); + auto est_location = [&](WireId w) -> std::pair<int16_t, int16_t> { + if (w.location.x == 0 && w.location.y == 0) { + // Global wires + const auto &wire = locInfo(w)->wire_data[w.index]; + // Use location of first downhill bel or pip, if available + if (wire.num_bel_pins > 0) { + return std::make_pair(wire.bel_pins[0].rel_bel_loc.x, wire.bel_pins[0].rel_bel_loc.y); + } else if (wire.num_downhill > 0) { + return std::make_pair(wire.pips_downhill[0].rel_loc.x, wire.pips_downhill[0].rel_loc.y); + } else if (wire.num_uphill > 0) { + return std::make_pair(wire.pips_uphill[0].rel_loc.x, wire.pips_uphill[0].rel_loc.y); + } else { + return std::make_pair<int16_t, int16_t>(0, 0); + } + } else { + return std::make_pair(w.location.x, w.location.y); + } + }; + + auto src_loc = est_location(src), dst_loc = est_location(dst); + + return (240 - 20 * args.speed) * (abs(src_loc.first - dst_loc.first) + abs(src_loc.second - dst_loc.second)); } delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const 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..799851b2 100644 --- a/ecp5/family.cmake +++ b/ecp5/family.cmake @@ -1,70 +1,78 @@ +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.* + /usr/lib/pytrellis.* + /usr/lib64/pytrellis.* + /usr/lib/trellis/pytrellis.* + /usr/lib64/trellis/pytrellis.*) -file(GLOB found_pytrellis ${TRELLIS_ROOT}/libtrellis/pytrellis.*) + if ("${found_pytrellis}" STREQUAL "") + message(FATAL_ERROR "failed to locate pytrellis library!") + endif() -if ("${found_pytrellis}" STREQUAL "") - message(FATAL_ERROR "failed to find pytrellis library in ${TRELLIS_ROOT}/libtrellis/") -endif() + list(GET found_pytrellis 0 PYTRELLIS_LIB) + get_filename_component(PYTRELLIS_LIBDIR ${PYTRELLIS_LIB} DIRECTORY) -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=\"${PYTRELLIS_LIBDIR}\;${TRELLIS_ROOT}/util/common\;${TRELLIS_ROOT}/timing/util\"") + else() + set(ENV_CMD ${CMAKE_COMMAND} -E env "PYTHONPATH=${PYTRELLIS_LIBDIR}\:${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) + 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() 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..877b27ee 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) + 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() diff --git a/ice40/pack.cc b/ice40/pack.cc index a86083b6..c22c4e8c 100644 --- a/ice40/pack.cc +++ b/ice40/pack.cc @@ -770,6 +770,8 @@ static void place_plls(Context *ctx) io_cell->name.c_str(ctx)); if (pll_used_bels.count(found_bel)) { CellInfo *conflict_cell = pll_used_bels.at(found_bel); + if (conflict_cell == ci) + continue; log_error("PLL '%s' PACKAGEPIN forces it to BEL %s but BEL is already assigned to PLL '%s'\n", ci->name.c_str(ctx), ctx->getBelName(found_bel).c_str(ctx), conflict_cell->name.c_str(ctx)); } @@ -1063,7 +1065,12 @@ static void pack_special(Context *ctx) create_ice_cell(ctx, ctx->id("ICESTORM_PLL"), ci->name.str(ctx) + "_PLL"); packed->attrs[ctx->id("TYPE")] = ci->type.str(ctx); packed_cells.insert(ci->name); - + if (!is_sb_pll40_dual(ctx, ci)) { + // Remove second output, so a buffer isn't created for it, for these + // cell types with only one output + packed->ports.erase(ctx->id("PLLOUT_B")); + packed->ports.erase(ctx->id("PLLOUT_B_GLOBAL")); + } for (auto attr : ci->attrs) packed->attrs[attr.first] = attr.second; for (auto param : ci->params) diff --git a/tests b/tests new file mode 160000 +Subproject 691dfb8204131bec7f1c5e139764bf418640f94 diff --git a/tests/generic/main.cc b/tests/generic/main.cc deleted file mode 100644 index a2634711..00000000 --- a/tests/generic/main.cc +++ /dev/null @@ -1,28 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Miodrag Milanovic <miodrag@symbioticeda.com> - * - * 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. - * - */ - -#include "gtest/gtest.h" - -#include <vector> - -int main(int argc, char **argv) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/tests/gui/quadtree.cc b/tests/gui/quadtree.cc deleted file mode 100644 index 6711e906..00000000 --- a/tests/gui/quadtree.cc +++ /dev/null @@ -1,122 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Serge Bazanski <q3k@symbioticeda.com> - * - * 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. - * - */ - -#include "gtest/gtest.h" -#include "nextpnr.h" - -#include "quadtree.h" - -USING_NEXTPNR_NAMESPACE - -using QT = QuadTree<int, int>; - -class QuadTreeTest : public ::testing::Test -{ - protected: - virtual void SetUp() { qt_ = new QT(QT::BoundingBox(0, 0, width_, height_)); } - virtual void TearDown() { delete qt_; } - - int width_ = 100; - int height_ = 100; - QT *qt_; -}; - -// Test that we're doing bound checking correctly. -TEST_F(QuadTreeTest, insert_bound_checking) -{ - ASSERT_TRUE(qt_->insert(QT::BoundingBox(10, 10, 20, 20), 10)); - ASSERT_TRUE(qt_->insert(QT::BoundingBox(0, 0, 100, 100), 10)); - ASSERT_FALSE(qt_->insert(QT::BoundingBox(10, 10, 101, 20), 10)); - ASSERT_FALSE(qt_->insert(QT::BoundingBox(-1, 10, 101, 20), 10)); - ASSERT_FALSE(qt_->insert(QT::BoundingBox(-1, -1, 20, 20), 10)); -} - -// Test whether we are not losing any elements. -TEST_F(QuadTreeTest, insert_count) -{ - auto rng = NEXTPNR_NAMESPACE::DeterministicRNG(); - - // Add 10000 random rectangles. - for (unsigned int i = 0; i < 10000; i++) { - int x0 = rng.rng(width_); - int y0 = rng.rng(height_); - int w = rng.rng(width_ - x0); - int h = rng.rng(width_ - y0); - int x1 = x0 + w; - int y1 = y0 + h; - ASSERT_TRUE(qt_->insert(QT::BoundingBox(x0, y0, x1, y1), i)); - ASSERT_EQ(qt_->size(), i + 1); - } - // Add 100000 random points. - for (unsigned int i = 0; i < 100000; i++) { - int x0 = rng.rng(width_); - int y0 = rng.rng(height_); - int x1 = x0; - int y1 = y0; - ASSERT_TRUE(qt_->insert(QT::BoundingBox(x0, y0, x1, y1), i)); - ASSERT_EQ(qt_->size(), i + 10001); - } -} - -// Test that we can insert and retrieve the same element. -TEST_F(QuadTreeTest, insert_retrieve_same) -{ - auto rng = NEXTPNR_NAMESPACE::DeterministicRNG(); - - // Add 10000 small random rectangles. - rng.rngseed(0); - for (int i = 0; i < 10000; i++) { - int x0 = rng.rng(width_); - int y0 = rng.rng(height_); - int w = rng.rng(width_ - x0); - int h = rng.rng(width_ - y0); - int x1 = x0 + w / 4; - int y1 = y0 + h / 4; - ASSERT_TRUE(qt_->insert(QT::BoundingBox(x0, y0, x1, y1), i)); - } - - // Restart RNG, make sure we get the same rectangles back. - rng.rngseed(0); - for (int i = 0; i < 10000; i++) { - int x0 = rng.rng(width_); - int y0 = rng.rng(height_); - int w = rng.rng(width_ - x0); - int h = rng.rng(width_ - y0); - int x1 = x0 + w / 4; - int y1 = y0 + h / 4; - - // try to find something in the middle of the square - int x = (x1 - x0) / 2 + x0; - int y = (y1 - y0) / 2 + y0; - - auto res = qt_->get(x, y); - // Somewhat arbirary test to make sure we don't return obscene - // amounts of data. - ASSERT_LT(res.size(), 200UL); - bool found = false; - for (auto elem : res) { - // Is this what we're looking for? - if (elem == i) { - found = true; - break; - } - } - ASSERT_TRUE(found); - } -} diff --git a/tests/ice40/hx1k.cc b/tests/ice40/hx1k.cc deleted file mode 100644 index 741c954b..00000000 --- a/tests/ice40/hx1k.cc +++ /dev/null @@ -1,106 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Clifford Wolf <clifford@symbioticeda.com> - * Copyright (C) 2018 Miodrag Milanovic <miodrag@symbioticeda.com> - * - * 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. - * - */ - -#include <vector> -#include "gtest/gtest.h" -#include "nextpnr.h" - -USING_NEXTPNR_NAMESPACE - -class HX1KTest : public ::testing::Test -{ - protected: - virtual void SetUp() - { - chipArgs.type = ArchArgs::HX1K; - chipArgs.package = "tq144"; - ctx = new Context(chipArgs); - } - - virtual void TearDown() { delete ctx; } - - ArchArgs chipArgs; - Context *ctx; -}; - -TEST_F(HX1KTest, bel_names) -{ - int bel_count = 0; - for (auto bel : ctx->getBels()) { - auto name = ctx->getBelName(bel); - ASSERT_EQ(bel, ctx->getBelByName(name)); - bel_count++; - } - ASSERT_EQ(bel_count, 1418); -} - -TEST_F(HX1KTest, wire_names) -{ - int wire_count = 0; - for (auto wire : ctx->getWires()) { - auto name = ctx->getWireName(wire); - assert(wire == ctx->getWireByName(name)); - wire_count++; - } - ASSERT_EQ(wire_count, 32802); -} - -TEST_F(HX1KTest, pip_names) -{ - int pip_count = 0; - for (auto pip : ctx->getPips()) { - auto name = ctx->getPipName(pip); - assert(pip == ctx->getPipByName(name)); - pip_count++; - } - ASSERT_EQ(pip_count, 345504); -} - -TEST_F(HX1KTest, uphill_to_downhill) -{ - for (auto dst : ctx->getWires()) { - for (auto uphill_pip : ctx->getPipsUphill(dst)) { - bool found_downhill = false; - for (auto downhill_pip : ctx->getPipsDownhill(ctx->getPipSrcWire(uphill_pip))) { - if (uphill_pip == downhill_pip) { - ASSERT_FALSE(found_downhill); - found_downhill = true; - } - } - ASSERT_TRUE(found_downhill); - } - } -} - -TEST_F(HX1KTest, downhill_to_uphill) -{ - for (auto dst : ctx->getWires()) { - for (auto downhill_pip : ctx->getPipsDownhill(dst)) { - bool found_uphill = false; - for (auto uphill_pip : ctx->getPipsUphill(ctx->getPipDstWire(downhill_pip))) { - if (uphill_pip == downhill_pip) { - ASSERT_FALSE(found_uphill); - found_uphill = true; - } - } - ASSERT_TRUE(found_uphill); - } - } -} diff --git a/tests/ice40/hx8k.cc b/tests/ice40/hx8k.cc deleted file mode 100644 index 517df0d6..00000000 --- a/tests/ice40/hx8k.cc +++ /dev/null @@ -1,106 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Clifford Wolf <clifford@symbioticeda.com> - * Copyright (C) 2018 Miodrag Milanovic <miodrag@symbioticeda.com> - * - * 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. - * - */ - -#include <vector> -#include "gtest/gtest.h" -#include "nextpnr.h" - -USING_NEXTPNR_NAMESPACE - -class HX8KTest : public ::testing::Test -{ - protected: - virtual void SetUp() - { - chipArgs.type = ArchArgs::HX8K; - chipArgs.package = "ct256"; - ctx = new Context(chipArgs); - } - - virtual void TearDown() { delete ctx; } - - ArchArgs chipArgs; - Context *ctx; -}; - -TEST_F(HX8KTest, bel_names) -{ - int bel_count = 0; - for (auto bel : ctx->getBels()) { - auto name = ctx->getBelName(bel); - ASSERT_EQ(bel, ctx->getBelByName(name)); - bel_count++; - } - ASSERT_EQ(bel_count, 7979); -} - -TEST_F(HX8KTest, wire_names) -{ - int wire_count = 0; - for (auto wire : ctx->getWires()) { - auto name = ctx->getWireName(wire); - assert(wire == ctx->getWireByName(name)); - wire_count++; - } - ASSERT_EQ(wire_count, 165894); -} - -TEST_F(HX8KTest, pip_names) -{ - int pip_count = 0; - for (auto pip : ctx->getPips()) { - auto name = ctx->getPipName(pip); - assert(pip == ctx->getPipByName(name)); - pip_count++; - } - ASSERT_EQ(pip_count, 1806080); -} - -TEST_F(HX8KTest, uphill_to_downhill) -{ - for (auto dst : ctx->getWires()) { - for (auto uphill_pip : ctx->getPipsUphill(dst)) { - bool found_downhill = false; - for (auto downhill_pip : ctx->getPipsDownhill(ctx->getPipSrcWire(uphill_pip))) { - if (uphill_pip == downhill_pip) { - ASSERT_FALSE(found_downhill); - found_downhill = true; - } - } - ASSERT_TRUE(found_downhill); - } - } -} - -TEST_F(HX8KTest, downhill_to_uphill) -{ - for (auto dst : ctx->getWires()) { - for (auto downhill_pip : ctx->getPipsDownhill(dst)) { - bool found_uphill = false; - for (auto uphill_pip : ctx->getPipsUphill(ctx->getPipDstWire(downhill_pip))) { - if (uphill_pip == downhill_pip) { - ASSERT_FALSE(found_uphill); - found_uphill = true; - } - } - ASSERT_TRUE(found_uphill); - } - } -} diff --git a/tests/ice40/lp1k.cc b/tests/ice40/lp1k.cc deleted file mode 100644 index 2fdba08b..00000000 --- a/tests/ice40/lp1k.cc +++ /dev/null @@ -1,106 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Clifford Wolf <clifford@symbioticeda.com> - * Copyright (C) 2018 Miodrag Milanovic <miodrag@symbioticeda.com> - * - * 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. - * - */ - -#include <vector> -#include "gtest/gtest.h" -#include "nextpnr.h" - -USING_NEXTPNR_NAMESPACE - -class LP1KTest : public ::testing::Test -{ - protected: - virtual void SetUp() - { - chipArgs.type = ArchArgs::LP1K; - chipArgs.package = "tq144"; - ctx = new Context(chipArgs); - } - - virtual void TearDown() { delete ctx; } - - ArchArgs chipArgs; - Context *ctx; -}; - -TEST_F(LP1KTest, bel_names) -{ - int bel_count = 0; - for (auto bel : ctx->getBels()) { - auto name = ctx->getBelName(bel); - ASSERT_EQ(bel, ctx->getBelByName(name)); - bel_count++; - } - ASSERT_EQ(bel_count, 1418); -} - -TEST_F(LP1KTest, wire_names) -{ - int wire_count = 0; - for (auto wire : ctx->getWires()) { - auto name = ctx->getWireName(wire); - assert(wire == ctx->getWireByName(name)); - wire_count++; - } - ASSERT_EQ(wire_count, 32802); -} - -TEST_F(LP1KTest, pip_names) -{ - int pip_count = 0; - for (auto pip : ctx->getPips()) { - auto name = ctx->getPipName(pip); - assert(pip == ctx->getPipByName(name)); - pip_count++; - } - ASSERT_EQ(pip_count, 345504); -} - -TEST_F(LP1KTest, uphill_to_downhill) -{ - for (auto dst : ctx->getWires()) { - for (auto uphill_pip : ctx->getPipsUphill(dst)) { - bool found_downhill = false; - for (auto downhill_pip : ctx->getPipsDownhill(ctx->getPipSrcWire(uphill_pip))) { - if (uphill_pip == downhill_pip) { - ASSERT_FALSE(found_downhill); - found_downhill = true; - } - } - ASSERT_TRUE(found_downhill); - } - } -} - -TEST_F(LP1KTest, downhill_to_uphill) -{ - for (auto dst : ctx->getWires()) { - for (auto downhill_pip : ctx->getPipsDownhill(dst)) { - bool found_uphill = false; - for (auto uphill_pip : ctx->getPipsUphill(ctx->getPipDstWire(downhill_pip))) { - if (uphill_pip == downhill_pip) { - ASSERT_FALSE(found_uphill); - found_uphill = true; - } - } - ASSERT_TRUE(found_uphill); - } - } -} diff --git a/tests/ice40/lp384.cc b/tests/ice40/lp384.cc deleted file mode 100644 index a030b77b..00000000 --- a/tests/ice40/lp384.cc +++ /dev/null @@ -1,106 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Clifford Wolf <clifford@symbioticeda.com> - * Copyright (C) 2018 Miodrag Milanovic <miodrag@symbioticeda.com> - * - * 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. - * - */ - -#include <vector> -#include "gtest/gtest.h" -#include "nextpnr.h" - -USING_NEXTPNR_NAMESPACE - -class LP384Test : public ::testing::Test -{ - protected: - virtual void SetUp() - { - chipArgs.type = ArchArgs::LP384; - chipArgs.package = "qn32"; - ctx = new Context(chipArgs); - } - - virtual void TearDown() { delete ctx; } - - ArchArgs chipArgs; - Context *ctx; -}; - -TEST_F(LP384Test, bel_names) -{ - int bel_count = 0; - for (auto bel : ctx->getBels()) { - auto name = ctx->getBelName(bel); - ASSERT_EQ(bel, ctx->getBelByName(name)); - bel_count++; - } - ASSERT_EQ(bel_count, 449); -} - -TEST_F(LP384Test, wire_names) -{ - int wire_count = 0; - for (auto wire : ctx->getWires()) { - auto name = ctx->getWireName(wire); - assert(wire == ctx->getWireByName(name)); - wire_count++; - } - ASSERT_EQ(wire_count, 9830); -} - -TEST_F(LP384Test, pip_names) -{ - int pip_count = 0; - for (auto pip : ctx->getPips()) { - auto name = ctx->getPipName(pip); - assert(pip == ctx->getPipByName(name)); - pip_count++; - } - ASSERT_EQ(pip_count, 94544); -} - -TEST_F(LP384Test, uphill_to_downhill) -{ - for (auto dst : ctx->getWires()) { - for (auto uphill_pip : ctx->getPipsUphill(dst)) { - bool found_downhill = false; - for (auto downhill_pip : ctx->getPipsDownhill(ctx->getPipSrcWire(uphill_pip))) { - if (uphill_pip == downhill_pip) { - ASSERT_FALSE(found_downhill); - found_downhill = true; - } - } - ASSERT_TRUE(found_downhill); - } - } -} - -TEST_F(LP384Test, downhill_to_uphill) -{ - for (auto dst : ctx->getWires()) { - for (auto downhill_pip : ctx->getPipsDownhill(dst)) { - bool found_uphill = false; - for (auto uphill_pip : ctx->getPipsUphill(ctx->getPipDstWire(downhill_pip))) { - if (uphill_pip == downhill_pip) { - ASSERT_FALSE(found_uphill); - found_uphill = true; - } - } - ASSERT_TRUE(found_uphill); - } - } -} diff --git a/tests/ice40/lp8k.cc b/tests/ice40/lp8k.cc deleted file mode 100644 index 7fe6ac37..00000000 --- a/tests/ice40/lp8k.cc +++ /dev/null @@ -1,106 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Clifford Wolf <clifford@symbioticeda.com> - * Copyright (C) 2018 Miodrag Milanovic <miodrag@symbioticeda.com> - * - * 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. - * - */ - -#include <vector> -#include "gtest/gtest.h" -#include "nextpnr.h" - -USING_NEXTPNR_NAMESPACE - -class LP8KTest : public ::testing::Test -{ - protected: - virtual void SetUp() - { - chipArgs.type = ArchArgs::LP8K; - chipArgs.package = "ct256"; - ctx = new Context(chipArgs); - } - - virtual void TearDown() { delete ctx; } - - ArchArgs chipArgs; - Context *ctx; -}; - -TEST_F(LP8KTest, bel_names) -{ - int bel_count = 0; - for (auto bel : ctx->getBels()) { - auto name = ctx->getBelName(bel); - ASSERT_EQ(bel, ctx->getBelByName(name)); - bel_count++; - } - ASSERT_EQ(bel_count, 7979); -} - -TEST_F(LP8KTest, wire_names) -{ - int wire_count = 0; - for (auto wire : ctx->getWires()) { - auto name = ctx->getWireName(wire); - assert(wire == ctx->getWireByName(name)); - wire_count++; - } - ASSERT_EQ(wire_count, 165894); -} - -TEST_F(LP8KTest, pip_names) -{ - int pip_count = 0; - for (auto pip : ctx->getPips()) { - auto name = ctx->getPipName(pip); - assert(pip == ctx->getPipByName(name)); - pip_count++; - } - ASSERT_EQ(pip_count, 1806080); -} - -TEST_F(LP8KTest, uphill_to_downhill) -{ - for (auto dst : ctx->getWires()) { - for (auto uphill_pip : ctx->getPipsUphill(dst)) { - bool found_downhill = false; - for (auto downhill_pip : ctx->getPipsDownhill(ctx->getPipSrcWire(uphill_pip))) { - if (uphill_pip == downhill_pip) { - ASSERT_FALSE(found_downhill); - found_downhill = true; - } - } - ASSERT_TRUE(found_downhill); - } - } -} - -TEST_F(LP8KTest, downhill_to_uphill) -{ - for (auto dst : ctx->getWires()) { - for (auto downhill_pip : ctx->getPipsDownhill(dst)) { - bool found_uphill = false; - for (auto uphill_pip : ctx->getPipsUphill(ctx->getPipDstWire(downhill_pip))) { - if (uphill_pip == downhill_pip) { - ASSERT_FALSE(found_uphill); - found_uphill = true; - } - } - ASSERT_TRUE(found_uphill); - } - } -} diff --git a/tests/ice40/main.cc b/tests/ice40/main.cc deleted file mode 100644 index 60b9fdaa..00000000 --- a/tests/ice40/main.cc +++ /dev/null @@ -1,27 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Miodrag Milanovic <miodrag@symbioticeda.com> - * - * 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. - * - */ - -#include <vector> -#include "gtest/gtest.h" - -int main(int argc, char **argv) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/tests/ice40/up5k.cc b/tests/ice40/up5k.cc deleted file mode 100644 index 582876e8..00000000 --- a/tests/ice40/up5k.cc +++ /dev/null @@ -1,106 +0,0 @@ -/* - * nextpnr -- Next Generation Place and Route - * - * Copyright (C) 2018 Clifford Wolf <clifford@symbioticeda.com> - * Copyright (C) 2018 Miodrag Milanovic <miodrag@symbioticeda.com> - * - * 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. - * - */ - -#include <vector> -#include "gtest/gtest.h" -#include "nextpnr.h" - -USING_NEXTPNR_NAMESPACE - -class UP5KTest : public ::testing::Test -{ - protected: - virtual void SetUp() - { - chipArgs.type = ArchArgs::UP5K; - chipArgs.package = "sg48"; - ctx = new Context(chipArgs); - } - - virtual void TearDown() { delete ctx; } - - ArchArgs chipArgs; - Context *ctx; -}; - -TEST_F(UP5KTest, bel_names) -{ - int bel_count = 0; - for (auto bel : ctx->getBels()) { - auto name = ctx->getBelName(bel); - ASSERT_EQ(bel, ctx->getBelByName(name)); - bel_count++; - } - ASSERT_EQ(bel_count, 5438); -} - -TEST_F(UP5KTest, wire_names) -{ - int wire_count = 0; - for (auto wire : ctx->getWires()) { - auto name = ctx->getWireName(wire); - assert(wire == ctx->getWireByName(name)); - wire_count++; - } - ASSERT_EQ(wire_count, 124503); -} - -TEST_F(UP5KTest, pip_names) -{ - int pip_count = 0; - for (auto pip : ctx->getPips()) { - auto name = ctx->getPipName(pip); - assert(pip == ctx->getPipByName(name)); - pip_count++; - } - ASSERT_EQ(pip_count, 1324704); -} - -TEST_F(UP5KTest, uphill_to_downhill) -{ - for (auto dst : ctx->getWires()) { - for (auto uphill_pip : ctx->getPipsUphill(dst)) { - bool found_downhill = false; - for (auto downhill_pip : ctx->getPipsDownhill(ctx->getPipSrcWire(uphill_pip))) { - if (uphill_pip == downhill_pip) { - ASSERT_FALSE(found_downhill); - found_downhill = true; - } - } - ASSERT_TRUE(found_downhill); - } - } -} - -TEST_F(UP5KTest, downhill_to_uphill) -{ - for (auto dst : ctx->getWires()) { - for (auto downhill_pip : ctx->getPipsDownhill(dst)) { - bool found_uphill = false; - for (auto uphill_pip : ctx->getPipsUphill(ctx->getPipDstWire(downhill_pip))) { - if (uphill_pip == downhill_pip) { - ASSERT_FALSE(found_uphill); - found_uphill = true; - } - } - ASSERT_TRUE(found_uphill); - } - } -} |