diff options
author | Keith Rothman <537074+litghost@users.noreply.github.com> | 2021-04-01 15:19:21 -0700 |
---|---|---|
committer | Keith Rothman <537074+litghost@users.noreply.github.com> | 2021-04-06 10:42:05 -0700 |
commit | 8773c645cae199d85d63461614c70854f54ae4db (patch) | |
tree | 0ee2eff57a0912fcb75be7f3815f4f655bec8bd9 /fpga_interchange/luts.cc | |
parent | c11ad31393389e0a16d84c2934332ea3755de60c (diff) | |
download | nextpnr-8773c645cae199d85d63461614c70854f54ae4db.tar.gz nextpnr-8773c645cae199d85d63461614c70854f54ae4db.tar.bz2 nextpnr-8773c645cae199d85d63461614c70854f54ae4db.zip |
[interchange] Prevent site router from generating incorrect LUTs.
The previous logic tied LUT input pins to VCC if a wire was unplacable.
This missed a case where the net was present to the input of the LUT,
but a wire was still not legal. This case is now prevented by tying the
output of the LUT to an unused net.
Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
Diffstat (limited to 'fpga_interchange/luts.cc')
-rw-r--r-- | fpga_interchange/luts.cc | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/fpga_interchange/luts.cc b/fpga_interchange/luts.cc index 5903630a..3312f8ce 100644 --- a/fpga_interchange/luts.cc +++ b/fpga_interchange/luts.cc @@ -17,11 +17,12 @@ * */ -#include "nextpnr.h" -#include "log.h" #include "luts.h" +#include "nextpnr.h" +#include "log.h" + //#define DEBUG_LUT_ROTATION NEXTPNR_NAMESPACE_BEGIN @@ -167,16 +168,20 @@ uint32_t LutMapper::check_wires(const Context *ctx) const { } } - return check_wires(bel_to_cell_pin_remaps, lut_bels, used_pins); + HashTables::HashSet<const LutBel *> blocked_luts; + return check_wires(bel_to_cell_pin_remaps, lut_bels, used_pins, + &blocked_luts); } 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 + const std::vector<const LutBel *> &lut_bels, uint32_t used_pins, + HashTables::HashSet<const LutBel *> *blocked_luts) const { std::vector<const LutBel *> unused_luts; for (auto &lut_bel_pair : element.lut_bels) { if (std::find(lut_bels.begin(), lut_bels.end(), &lut_bel_pair.second) == lut_bels.end()) { unused_luts.push_back(&lut_bel_pair.second); + blocked_luts->emplace(&lut_bel_pair.second); } } @@ -238,6 +243,7 @@ uint32_t LutMapper::check_wires(const std::vector<std::vector<int32_t>> &bel_to_ if (rotate_and_merge_lut_equation(&equation_result, *lut_bel, wire_equation, wire_bel_to_cell_pin_map, used_pins_with_wire)) { valid_pin_for_wire = true; + blocked_luts->erase(lut_bel); } } @@ -250,7 +256,7 @@ uint32_t LutMapper::check_wires(const std::vector<std::vector<int32_t>> &bel_to_ return vcc_mask; } -bool LutMapper::remap_luts(const Context *ctx) +bool LutMapper::remap_luts(const Context *ctx, HashTables::HashSet<const LutBel *> *blocked_luts) { std::unordered_map<NetInfo *, LutPin> lut_pin_map; std::vector<const LutBel *> lut_bels; @@ -408,7 +414,7 @@ bool LutMapper::remap_luts(const Context *ctx) // // Use Arch::prefered_constant_net_type to determine what // constant net should be used for unused pins. - uint32_t vcc_pins = check_wires(bel_to_cell_pin_remaps, lut_bels, used_pins); + uint32_t vcc_pins = check_wires(bel_to_cell_pin_remaps, lut_bels, used_pins, blocked_luts); #if defined(DEBUG_LUT_ROTATION) log_info("vcc_pins = 0x%x", vcc_pins); for (size_t cell_idx = 0; cell_idx < cells.size(); ++cell_idx) { |