From 558a753d3da5a2243a74b8d4e1c24044bdfb5c2e Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Wed, 17 Feb 2021 10:18:24 -0800 Subject: [PATCH] Refactor "get only from iterator" to a utility. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- common/util.h | 23 +++++++++++++++++++++++ fpga_interchange/arch.cc | 7 ++----- fpga_interchange/arch.h | 6 +++++- fpga_interchange/arch_pack_io.cc | 8 ++------ 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 +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 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 { 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);