aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/util.h23
-rw-r--r--fpga_interchange/arch.cc7
-rw-r--r--fpga_interchange/arch.h6
-rw-r--r--fpga_interchange/arch_pack_io.cc8
4 files changed, 32 insertions, 12 deletions
diff --git a/common/util.h b/common/util.h
index 07ebac75..55718344 100644
--- a/common/util.h
+++ b/common/util.h
@@ -158,6 +158,29 @@ inline NetInfo *get_net_or_empty(CellInfo *cell, const IdString port)
return nullptr;
}
+// Get only value from a forward iterator begin/end pair.
+//
+// Generates assertion failure if std::distance(begin, end) != 1.
+template <typename ForwardIterator>
+inline const typename ForwardIterator::reference get_only_value(ForwardIterator begin, ForwardIterator end)
+{
+ NPNR_ASSERT(begin != end);
+ const typename ForwardIterator::reference ret = *begin;
+ ++begin;
+ NPNR_ASSERT(begin == end);
+ return ret;
+}
+
+// Get only value from a forward iterator range pair.
+//
+// Generates assertion failure if std::distance(r.begin(), r.end()) != 1.
+template <typename ForwardRange> inline auto get_only_value(ForwardRange r)
+{
+ auto b = r.begin();
+ auto e = r.end();
+ return get_only_value(b, e);
+}
+
NEXTPNR_NAMESPACE_END
#endif
diff --git a/fpga_interchange/arch.cc b/fpga_interchange/arch.cc
index 561f495d..cce93844 100644
--- a/fpga_interchange/arch.cc
+++ b/fpga_interchange/arch.cc
@@ -806,11 +806,8 @@ void Arch::map_cell_pins(CellInfo *cell, int32_t mapping) const
void Arch::map_port_pins(BelId bel, CellInfo *cell) const
{
IdStringRange pins = getBelPins(bel);
- NPNR_ASSERT(pins.begin() != pins.end());
- auto b = pins.begin();
- IdString pin = *b;
- ++b;
- NPNR_ASSERT(b == pins.end());
+ IdString pin = get_only_value(pins);
+
NPNR_ASSERT(cell->ports.size() == 1);
cell->cell_bel_pins[cell->ports.begin()->first].clear();
cell->cell_bel_pins[cell->ports.begin()->first].push_back(pin);
diff --git a/fpga_interchange/arch.h b/fpga_interchange/arch.h
index 556aa566..1daf5526 100644
--- a/fpga_interchange/arch.h
+++ b/fpga_interchange/arch.h
@@ -656,7 +656,11 @@ struct BelPinRange
BelPinIterator end() const { return e; }
};
-struct IdStringIterator
+struct IdStringIterator : std::iterator<std::forward_iterator_tag,
+ /*T=*/IdString,
+ /*Distance=*/ptrdiff_t,
+ /*pointer=*/IdString *,
+ /*reference=*/IdString>
{
const int32_t *cursor;
diff --git a/fpga_interchange/arch_pack_io.cc b/fpga_interchange/arch_pack_io.cc
index 8a0fdc05..6a0ffe0b 100644
--- a/fpga_interchange/arch_pack_io.cc
+++ b/fpga_interchange/arch_pack_io.cc
@@ -20,6 +20,7 @@
#include "log.h"
#include "nextpnr.h"
+#include "util.h"
NEXTPNR_NAMESPACE_BEGIN
@@ -235,12 +236,7 @@ void Arch::pack_ports()
placed_cells.emplace(port_cell);
IdStringRange package_bel_pins = getBelPins(package_bel);
- // NPNR_ASSERT(std::distance(package_bel_pins.begin(), package_bel_pins.end()) == 1);
- IdStringIterator b = package_bel_pins.begin();
- NPNR_ASSERT(b != package_bel_pins.end());
- ++b;
- NPNR_ASSERT(b == package_bel_pins.end());
- IdString pad_pin = *package_bel_pins.begin();
+ IdString pad_pin = get_only_value(package_bel_pins);
WireId pad_wire = getBelPinWire(package_bel, pad_pin);
place_iobufs(pad_wire, ports[port_pair.first].net, tightly_attached_bels, &placed_cells);