diff options
Diffstat (limited to 'ecp5/arch.cc')
-rw-r--r-- | ecp5/arch.cc | 52 |
1 files changed, 50 insertions, 2 deletions
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 |