From f6fa0300ae95a0896a12b9acf0c7e76851c13d37 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 20 Jul 2018 17:33:57 +0200 Subject: Improve iCE40 and common Loc code Signed-off-by: Clifford Wolf --- common/nextpnr.h | 19 +++++++++++++++++++ ice40/arch.cc | 31 ++++++++++++++++++++++++++++++- ice40/arch.h | 15 +++------------ ice40/archdefs.h | 2 -- 4 files changed, 52 insertions(+), 15 deletions(-) diff --git a/common/nextpnr.h b/common/nextpnr.h index 8ef958cd..4cdc4d00 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -27,6 +27,8 @@ #include #include +#include + #ifndef NEXTPNR_H #define NEXTPNR_H @@ -161,10 +163,27 @@ struct GraphicElement struct Loc { int x = -1, y = -1, z = -1; + + bool operator==(const Loc &other) const { return (x == other.x) && (y == other.y) && (z == other.z); } + bool operator!=(const Loc &other) const { return (x != other.x) || (y != other.y) || (z == other.z); } }; NEXTPNR_NAMESPACE_END +namespace std { +template <> struct hash +{ + std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX Loc &obj) const noexcept + { + std::size_t seed = 0; + boost::hash_combine(seed, hash()(obj.x)); + boost::hash_combine(seed, hash()(obj.y)); + boost::hash_combine(seed, hash()(obj.z)); + return seed; + } +}; +} // namespace std + #include "archdefs.h" NEXTPNR_NAMESPACE_BEGIN diff --git a/ice40/arch.cc b/ice40/arch.cc index 786d8ba1..ceafca17 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -255,11 +255,40 @@ BelId Arch::getBelByName(IdString name) const return ret; } +BelId Arch::getBelByLocation(int x, int y, int z) const +{ + if (bel_by_loc.empty()) { + for (int i = 0; i < chip_info->num_bels; i++) + bel_by_loc[getBelLocation(BelId{i})] = i; + } + + auto it = bel_by_loc.find(Loc{x, y, z}); + if (it != bel_by_loc.end()) + return BelId{it->second}; + return BelId(); +} + +BelRange Arch::getBelsByTile(int x, int y) const +{ + // In iCE40 chipdb bels at the same tile are consecutive and dense z ordinates are used + BelRange br; + br.b.cursor = Arch::getBelByLocation(x, y, 0); + br.e.cursor = br.b.cursor; + + if (br.e.cursor != -1) { + while (br.e.cursor < chip_info->num_bels && + chip_info->bel_data[br.e.cursor].x == x && + chip_info->bel_data[br.e.cursor].y == y) + br.e.cursor++; + } + + return br; +} + BelRange Arch::getBelsAtSameTile(BelId bel) const { BelRange br; NPNR_ASSERT(bel != BelId()); - // This requires Bels at the same tile are consecutive int x = chip_info->bel_data[bel.index].x; int y = chip_info->bel_data[bel.index].y; int start = bel.index, end = bel.index; diff --git a/ice40/arch.h b/ice40/arch.h index 805876e4..f86428a9 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -350,6 +350,7 @@ struct Arch : BaseCtx mutable std::unordered_map bel_by_name; mutable std::unordered_map wire_by_name; mutable std::unordered_map pip_by_name; + mutable std::unordered_map bel_by_loc; std::vector bel_to_cell; std::vector wire_to_net; @@ -449,18 +450,8 @@ struct Arch : BaseCtx return loc; } - BelId getBelByLocation(int x, int y, int z) const - { - // FIXME - return BelId(); - } - - BelRange getBelsByTile(int x, int y) const - { - BelRange range; - // FIXME - return range; - } + BelId getBelByLocation(int x, int y, int z) const; + BelRange getBelsByTile(int x, int y) const; bool getBelGlobalBuf(BelId bel) const { diff --git a/ice40/archdefs.h b/ice40/archdefs.h index 14b0d2be..dec6f702 100644 --- a/ice40/archdefs.h +++ b/ice40/archdefs.h @@ -21,8 +21,6 @@ #error Include "archdefs.h" via "nextpnr.h" only. #endif -#include - NEXTPNR_NAMESPACE_BEGIN typedef int delay_t; -- cgit v1.2.3