aboutsummaryrefslogtreecommitdiffstats
path: root/fpga_interchange/luts.cc
diff options
context:
space:
mode:
Diffstat (limited to 'fpga_interchange/luts.cc')
-rw-r--r--fpga_interchange/luts.cc42
1 files changed, 41 insertions, 1 deletions
diff --git a/fpga_interchange/luts.cc b/fpga_interchange/luts.cc
index 930e25d1..5903630a 100644
--- a/fpga_interchange/luts.cc
+++ b/fpga_interchange/luts.cc
@@ -22,6 +22,8 @@
#include "log.h"
#include "luts.h"
+//#define DEBUG_LUT_ROTATION
+
NEXTPNR_NAMESPACE_BEGIN
bool rotate_and_merge_lut_equation(std::vector<LogicLevel> *result, const LutBel &lut_bel,
@@ -128,7 +130,45 @@ struct LutPin
bool operator<(const LutPin &other) const { return max_pin < other.max_pin; }
};
-//#define DEBUG_LUT_ROTATION
+
+uint32_t LutMapper::check_wires(const Context *ctx) const {
+ // Unlike the 3 argument version of check_wires, this version needs to
+ // calculate following data based on current cell pin mapping, etc:
+ //
+ // - Index map from bel pins to cell pins, -1 for unmapped
+ // - Mask of used pins
+ // - Vector of unused LUT BELs.
+
+ uint32_t used_pins = 0;
+
+ std::vector<std::vector<int32_t>> bel_to_cell_pin_remaps;
+ std::vector<const LutBel *> lut_bels;
+ bel_to_cell_pin_remaps.resize(cells.size());
+ lut_bels.resize(cells.size());
+ for (size_t cell_idx = 0; cell_idx < cells.size(); ++cell_idx) {
+ const CellInfo *cell = cells[cell_idx];
+
+
+ auto &bel_data = bel_info(ctx->chip_info, cell->bel);
+ IdString bel_name(bel_data.name);
+ auto &lut_bel = element.lut_bels.at(bel_name);
+ lut_bels[cell_idx] = &lut_bel;
+
+ bel_to_cell_pin_remaps[cell_idx].resize(lut_bel.pins.size(), -1);
+
+ for (size_t pin_idx = 0; pin_idx < cell->lut_cell.pins.size(); ++pin_idx) {
+ IdString lut_cell_pin = cell->lut_cell.pins[pin_idx];
+ const std::vector<IdString> bel_pins = cell->cell_bel_pins.at(lut_cell_pin);
+ NPNR_ASSERT(bel_pins.size() == 1);
+
+ size_t bel_pin_idx = lut_bel.pin_to_index.at(bel_pins[0]);
+ bel_to_cell_pin_remaps[cell_idx][bel_pin_idx] = pin_idx;
+ used_pins |= (1 << bel_pin_idx);
+ }
+ }
+
+ return check_wires(bel_to_cell_pin_remaps, lut_bels, used_pins);
+}
uint32_t LutMapper::check_wires(const std::vector<std::vector<int32_t>> &bel_to_cell_pin_remaps,
const std::vector<const LutBel *> &lut_bels, uint32_t used_pins) const