aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2018-07-20 17:33:57 +0200
committerClifford Wolf <clifford@clifford.at>2018-07-20 17:33:57 +0200
commitf6fa0300ae95a0896a12b9acf0c7e76851c13d37 (patch)
tree13fbcf6ace44f5c523830469104314474534009e
parente16b4a325e2b0721e29cba93804923dedf74a68c (diff)
downloadnextpnr-f6fa0300ae95a0896a12b9acf0c7e76851c13d37.tar.gz
nextpnr-f6fa0300ae95a0896a12b9acf0c7e76851c13d37.tar.bz2
nextpnr-f6fa0300ae95a0896a12b9acf0c7e76851c13d37.zip
Improve iCE40 and common Loc code
Signed-off-by: Clifford Wolf <clifford@clifford.at>
-rw-r--r--common/nextpnr.h19
-rw-r--r--ice40/arch.cc31
-rw-r--r--ice40/arch.h15
-rw-r--r--ice40/archdefs.h2
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;