diff options
author | David Shah <davey1576@gmail.com> | 2018-06-13 10:50:05 +0200 |
---|---|---|
committer | David Shah <davey1576@gmail.com> | 2018-06-13 10:50:05 +0200 |
commit | a76f5c5678980c8b2e958252a68ba03676d63229 (patch) | |
tree | a9f32a39a91164b36ca55d567baf177bbaece1cc /common | |
parent | ddf549b117987c1e52412b58531c48a6050b51d1 (diff) | |
download | nextpnr-a76f5c5678980c8b2e958252a68ba03676d63229.tar.gz nextpnr-a76f5c5678980c8b2e958252a68ba03676d63229.tar.bz2 nextpnr-a76f5c5678980c8b2e958252a68ba03676d63229.zip |
Remove IO buffers when fed by SB_IO
Signed-off-by: David Shah <davey1576@gmail.com>
Diffstat (limited to 'common')
-rw-r--r-- | common/design_utils.h | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/common/design_utils.h b/common/design_utils.h index 2acc7d20..daf6e050 100644 --- a/common/design_utils.h +++ b/common/design_utils.h @@ -22,6 +22,8 @@ #ifndef DESIGN_UTILS_H #define DESIGN_UTILS_H +#include <algorithm> + NEXTPNR_NAMESPACE_BEGIN /* @@ -35,23 +37,36 @@ void replace_port(CellInfo *old_cell, IdString old_name, CellInfo *rep_cell, // If a net drives a given port of a cell matching a predicate (in many // cases more than one cell type, e.g. SB_DFFxx so a predicate is used), return // the first instance of that cell (otherwise nullptr). If exclusive is set to -// true, then this cell must be the only load +// true, then this cell must be the only load. If ignore_cell is set, that cell +// is not considered template <typename F1> CellInfo *net_only_drives(NetInfo *net, F1 cell_pred, IdString port, - bool exclusive = false) + bool exclusive = false, CellInfo *exclude = nullptr) { if (net == nullptr) return nullptr; - if (exclusive && (net->users.size() != 1)) { - return nullptr; - } else { - for (const auto &load : net->users) { - if (cell_pred(load.cell) && load.port == port) { - return load.cell; + if (exclusive) { + if (exclude == nullptr) { + if (net->users.size() != 1) + return nullptr; + } else { + if (net->users.size() > 2) { + return nullptr; + } else if (net->users.size() == 2) { + if (std::find_if(net->users.begin(), net->users.end(), + [exclude](const PortRef &ref) { + return ref.cell == exclude; + }) == net->users.end()) + return nullptr; } } - return nullptr; } + for (const auto &load : net->users) { + if (load.cell != exclude && cell_pred(load.cell) && load.port == port) { + return load.cell; + } + } + return nullptr; } // If a net is driven by a given port of a cell matching a predicate, return |