diff options
-rw-r--r-- | common/nextpnr.h | 19 | ||||
-rw-r--r-- | ice40/arch.cc | 31 | ||||
-rw-r--r-- | ice40/arch.h | 15 | ||||
-rw-r--r-- | 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 <unordered_set> #include <vector> +#include <boost/functional/hash.hpp> + #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<NEXTPNR_NAMESPACE_PREFIX Loc> +{ + std::size_t operator()(const NEXTPNR_NAMESPACE_PREFIX Loc &obj) const noexcept + { + std::size_t seed = 0; + boost::hash_combine(seed, hash<int>()(obj.x)); + boost::hash_combine(seed, hash<int>()(obj.y)); + boost::hash_combine(seed, hash<int>()(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<IdString, int> bel_by_name; mutable std::unordered_map<IdString, int> wire_by_name; mutable std::unordered_map<IdString, int> pip_by_name; + mutable std::unordered_map<Loc, int> bel_by_loc; std::vector<IdString> bel_to_cell; std::vector<IdString> 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 <boost/functional/hash.hpp> - NEXTPNR_NAMESPACE_BEGIN typedef int delay_t; |