Rework Arch::logicCellsCompatible() to take pointer + size, allowing use of std::array

This commit is contained in:
Eddie Hung 2018-08-10 19:50:27 -07:00
parent ded8308683
commit a41500a015
3 changed files with 18 additions and 17 deletions

View File

@ -802,7 +802,7 @@ struct Arch : BaseCtx
bool isBelLocationValid(BelId bel) const; bool isBelLocationValid(BelId bel) const;
// Helper function for above // Helper function for above
bool logicCellsCompatible(const std::vector<const CellInfo *> &cells) const; bool logicCellsCompatible(const CellInfo** it, const size_t size) const;
// ------------------------------------------------- // -------------------------------------------------
// Assign architecure-specific arguments to nets and cells, which must be // Assign architecure-specific arguments to nets and cells, which must be

View File

@ -23,15 +23,17 @@
#include "nextpnr.h" #include "nextpnr.h"
#include "util.h" #include "util.h"
#include <boost/range/iterator_range.hpp>
NEXTPNR_NAMESPACE_BEGIN NEXTPNR_NAMESPACE_BEGIN
bool Arch::logicCellsCompatible(const std::vector<const CellInfo *> &cells) const bool Arch::logicCellsCompatible(const CellInfo** it, const size_t size) const
{ {
bool dffs_exist = false, dffs_neg = false; bool dffs_exist = false, dffs_neg = false;
const NetInfo *cen = nullptr, *clk = nullptr, *sr = nullptr; const NetInfo *cen = nullptr, *clk = nullptr, *sr = nullptr;
int locals_count = 0; int locals_count = 0;
for (auto cell : cells) { for (auto cell : boost::make_iterator_range(it, it+size)) {
NPNR_ASSERT(cell->belType == id_ICESTORM_LC); NPNR_ASSERT(cell->belType == id_ICESTORM_LC);
if (cell->lcInfo.dffEnable) { if (cell->lcInfo.dffEnable) {
if (!dffs_exist) { if (!dffs_exist) {
@ -71,16 +73,15 @@ bool Arch::logicCellsCompatible(const std::vector<const CellInfo *> &cells) cons
bool Arch::isBelLocationValid(BelId bel) const bool Arch::isBelLocationValid(BelId bel) const
{ {
if (getBelType(bel) == id_ICESTORM_LC) { if (getBelType(bel) == id_ICESTORM_LC) {
static std::vector<const CellInfo *> bel_cells; std::array<const CellInfo *, 8> bel_cells;
bel_cells.clear(); size_t num_cells = 0;
Loc bel_loc = getBelLocation(bel); Loc bel_loc = getBelLocation(bel);
for (auto bel_other : getBelsByTile(bel_loc.x, bel_loc.y)) { for (auto bel_other : getBelsByTile(bel_loc.x, bel_loc.y)) {
CellInfo *ci_other = getBoundBelCell(bel_other); CellInfo *ci_other = getBoundBelCell(bel_other);
if (ci_other != nullptr) { if (ci_other != nullptr)
bel_cells.emplace_back(ci_other); bel_cells[num_cells++] = ci_other;
} }
} return logicCellsCompatible(bel_cells.data(), num_cells);
return logicCellsCompatible(bel_cells);
} else { } else {
CellInfo *ci = getBoundBelCell(bel); CellInfo *ci = getBoundBelCell(bel);
if (ci == nullptr) if (ci == nullptr)
@ -95,18 +96,18 @@ bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const
if (cell->type == id_ICESTORM_LC) { if (cell->type == id_ICESTORM_LC) {
NPNR_ASSERT(getBelType(bel) == id_ICESTORM_LC); NPNR_ASSERT(getBelType(bel) == id_ICESTORM_LC);
static std::vector<const CellInfo *> bel_cells; std::array<const CellInfo *, 8> bel_cells;
bel_cells.clear(); size_t num_cells = 0;
Loc bel_loc = getBelLocation(bel); Loc bel_loc = getBelLocation(bel);
for (auto bel_other : getBelsByTile(bel_loc.x, bel_loc.y)) { for (auto bel_other : getBelsByTile(bel_loc.x, bel_loc.y)) {
CellInfo *ci_other = getBoundBelCell(bel_other); CellInfo *ci_other = getBoundBelCell(bel_other);
if (ci_other != nullptr && bel_other != bel) { if (ci_other != nullptr && bel_other != bel)
bel_cells.emplace_back(ci_other); bel_cells[num_cells++] = ci_other;
}
} }
bel_cells.emplace_back(cell); bel_cells[num_cells++] = cell;
return logicCellsCompatible(bel_cells); return logicCellsCompatible(bel_cells.data(), num_cells);
} else if (cell->type == id_SB_IO) { } else if (cell->type == id_SB_IO) {
// Do not allow placement of input SB_IOs on blocks where there a PLL is outputting to. // Do not allow placement of input SB_IOs on blocks where there a PLL is outputting to.

View File

@ -97,7 +97,7 @@ class ChainConstrainer
} }
tile.push_back(cell); tile.push_back(cell);
chains.back().cells.push_back(cell); chains.back().cells.push_back(cell);
bool split_chain = (!ctx->logicCellsCompatible(tile)) || (int(chains.back().cells.size()) > max_length); bool split_chain = (!ctx->logicCellsCompatible(tile.data(), tile.size())) || (int(chains.back().cells.size()) > max_length);
if (split_chain) { if (split_chain) {
CellInfo *passout = make_carry_pass_out(cell->ports.at(ctx->id("COUT"))); CellInfo *passout = make_carry_pass_out(cell->ports.at(ctx->id("COUT")));
tile.pop_back(); tile.pop_back();