From c0f1af87f6c1c6843e536a87ef88e39fa3428c5b Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 17 Jul 2018 17:03:44 +0200 Subject: [PATCH 1/3] Add Loc struct for x/y/z bel locations Signed-off-by: Clifford Wolf --- common/nextpnr.h | 9 +++++++++ ice40/arch.h | 31 +++++++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/common/nextpnr.h b/common/nextpnr.h index 50465869..375e1cd7 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -157,6 +157,11 @@ struct GraphicElement std::string text; }; +struct Loc +{ + int x = -1, y = -1, z = -1; +}; + NEXTPNR_NAMESPACE_END #include "archdefs.h" @@ -310,6 +315,10 @@ struct Context : Arch Context(ArchArgs args) : Arch(args) {} + BelId getBelByLocation(Loc loc) const { + return getBelByLocation(loc.x, loc.y, loc.z); + } + // -------------------------------------------------------------- // provided by router1.cc diff --git a/ice40/arch.h b/ice40/arch.h index 5dab414b..d840c6ea 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -424,7 +424,34 @@ struct Arch : BaseCtx return range; } - BelRange getBelsAtSameTile(BelId bel) const; + Loc getBelLocation(BelId bel) const + { + Loc loc; + loc.x = chip_info->bel_data[bel.index].x; + loc.y = chip_info->bel_data[bel.index].y; + loc.z = chip_info->bel_data[bel.index].z; + 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; + } + + bool getBelGlobalBuf(BelId bel) const + { + return chip_info->bel_data[bel.index].type == TYPE_SB_GB; + } + + BelRange getBelsAtSameTile(BelId bel) const NPNR_DEPRECATED; BelType getBelType(BelId bel) const { @@ -655,7 +682,7 @@ struct Arch : BaseCtx // ------------------------------------------------- - void estimatePosition(BelId bel, int &x, int &y, bool &gb) const; + void estimatePosition(BelId bel, int &x, int &y, bool &gb) const NPNR_DEPRECATED; delay_t estimateDelay(WireId src, WireId dst) const; delay_t getDelayEpsilon() const { return 20; } delay_t getRipupDelayPenalty() const { return 200; } From f6fa0300ae95a0896a12b9acf0c7e76851c13d37 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 20 Jul 2018 17:33:57 +0200 Subject: [PATCH 2/3] 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; From fd8239e170a7391d9c25d8681083507d9960abef Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 20 Jul 2018 18:09:22 +0200 Subject: [PATCH 3/3] Add Location APIs to generic arch Signed-off-by: Clifford Wolf --- common/nextpnr.h | 4 ---- generic/arch.cc | 28 +++++++++++++++++++--------- generic/arch.h | 13 ++++++++++--- ice40/arch.cc | 26 +++++++++++++++++++------- ice40/arch.h | 2 +- 5 files changed, 49 insertions(+), 24 deletions(-) diff --git a/common/nextpnr.h b/common/nextpnr.h index 4cdc4d00..40fd3d13 100644 --- a/common/nextpnr.h +++ b/common/nextpnr.h @@ -339,10 +339,6 @@ struct Context : Arch Context(ArchArgs args) : Arch(args) {} - BelId getBelByLocation(Loc loc) const { - return getBelByLocation(loc.x, loc.y, loc.z); - } - // -------------------------------------------------------------- // provided by router1.cc diff --git a/generic/arch.cc b/generic/arch.cc index 390830aa..b7ec847e 100644 --- a/generic/arch.cc +++ b/generic/arch.cc @@ -29,8 +29,8 @@ void Arch::addWire(IdString name, int x, int y) NPNR_ASSERT(wires.count(name) == 0); WireInfo &wi = wires[name]; wi.name = name; - wi.grid_x = x; - wi.grid_y = y; + wi.x = x; + wi.y = y; wire_ids.push_back(name); } @@ -62,18 +62,28 @@ void Arch::addAlias(IdString name, IdString srcWire, IdString dstWire, DelayInfo pip_ids.push_back(name); } -void Arch::addBel(IdString name, IdString type, int x, int y, bool gb) +void Arch::addBel(IdString name, IdString type, int x, int y, int z, bool gb) { + Loc loc; + loc.x = x; + loc.y = y; + loc.z = z; + NPNR_ASSERT(bels.count(name) == 0); + NPNR_ASSERT(bel_by_loc.count(loc) == 0); BelInfo &bi = bels[name]; bi.name = name; bi.type = type; - bi.grid_x = x; - bi.grid_y = y; + bi.x = x; + bi.y = y; + bi.z = z; bi.gb = gb; bel_ids.push_back(name); bel_ids_by_type[type].push_back(name); + + bel_by_loc[loc] = name; + bels_by_tile[x][y].push_back(name); } void Arch::addBelInput(IdString bel, IdString name, IdString wire) @@ -348,8 +358,8 @@ const std::vector &Arch::getGroupGroups(GroupId group) const { return g void Arch::estimatePosition(BelId bel, int &x, int &y, bool &gb) const { - x = bels.at(bel).grid_x; - y = bels.at(bel).grid_y; + x = bels.at(bel).x; + y = bels.at(bel).y; gb = bels.at(bel).gb; } @@ -357,8 +367,8 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const { const WireInfo &s = wires.at(src); const WireInfo &d = wires.at(dst); - int dx = abs(s.grid_x - d.grid_x); - int dy = abs(s.grid_y - d.grid_y); + int dx = abs(s.x - d.x); + int dy = abs(s.y - d.y); return (dx + dy) * grid_distance_to_delay; } diff --git a/generic/arch.h b/generic/arch.h index 5d7ac540..ea4bb565 100644 --- a/generic/arch.h +++ b/generic/arch.h @@ -44,7 +44,7 @@ struct WireInfo BelPin uphill_bel_pin; std::vector downhill_bel_pins; DecalXY decalxy; - int grid_x, grid_y; + int x, y; }; struct PinInfo @@ -59,7 +59,7 @@ struct BelInfo IdString name, type, bound_cell; std::unordered_map pins; DecalXY decalxy; - int grid_x, grid_y; + int x, y, z; bool gb; }; @@ -85,6 +85,9 @@ struct Arch : BaseCtx std::vector bel_ids, wire_ids, pip_ids; std::unordered_map> bel_ids_by_type; + std::unordered_map bel_by_loc; + std::unordered_map>> bels_by_tile; + std::unordered_map> decal_graphics; DecalXY frame_decalxy; @@ -94,7 +97,7 @@ struct Arch : BaseCtx void addPip(IdString name, IdString srcWire, IdString dstWire, DelayInfo delay); void addAlias(IdString name, IdString srcWire, IdString dstWire, DelayInfo delay); - void addBel(IdString name, IdString type, int x, int y, bool gb); + void addBel(IdString name, IdString type, int x, int y, int z, bool gb); void addBelInput(IdString bel, IdString name, IdString wire); void addBelOutput(IdString bel, IdString name, IdString wire); void addBelInout(IdString bel, IdString name, IdString wire); @@ -129,6 +132,10 @@ struct Arch : BaseCtx BelId getBelByName(IdString name) const; IdString getBelName(BelId bel) const; + Loc getBelLocation(BelId bel) const; + BelId getBelByLocation(Loc loc) const; + std::vector getBelsByTile(int x, int y) const; + bool getBelGlobalBuf(BelId bel) const; uint32_t getBelChecksum(BelId bel) const; void bindBel(BelId bel, IdString cell, PlaceStrength strength); void unbindBel(BelId bel); diff --git a/ice40/arch.cc b/ice40/arch.cc index ceafca17..e9a7d2b6 100644 --- a/ice40/arch.cc +++ b/ice40/arch.cc @@ -255,24 +255,36 @@ BelId Arch::getBelByName(IdString name) const return ret; } -BelId Arch::getBelByLocation(int x, int y, int z) const +BelId Arch::getBelByLocation(Loc loc) const { + BelId bel; + if (bel_by_loc.empty()) { - for (int i = 0; i < chip_info->num_bels; i++) - bel_by_loc[getBelLocation(BelId{i})] = i; + for (int i = 0; i < chip_info->num_bels; i++) { + BelId b; + b.index = i; + bel_by_loc[getBelLocation(b)] = i; + } } - auto it = bel_by_loc.find(Loc{x, y, z}); + auto it = bel_by_loc.find(loc); if (it != bel_by_loc.end()) - return BelId{it->second}; - return BelId(); + bel.index = it->second; + + return bel; } 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); + + Loc loc; + loc.x = x; + loc.y = y; + loc.z = 0; + + br.b.cursor = Arch::getBelByLocation(loc).index; br.e.cursor = br.b.cursor; if (br.e.cursor != -1) { diff --git a/ice40/arch.h b/ice40/arch.h index f86428a9..beba2ccf 100644 --- a/ice40/arch.h +++ b/ice40/arch.h @@ -450,7 +450,7 @@ struct Arch : BaseCtx return loc; } - BelId getBelByLocation(int x, int y, int z) const; + BelId getBelByLocation(Loc loc) const; BelRange getBelsByTile(int x, int y) const; bool getBelGlobalBuf(BelId bel) const