aboutsummaryrefslogtreecommitdiffstats
path: root/fpga_interchange
diff options
context:
space:
mode:
authorMaciej Kurc <mkurc@antmicro.com>2021-07-16 13:55:19 +0200
committerMaciej Kurc <mkurc@antmicro.com>2021-07-16 13:55:19 +0200
commit0336f55b16373874cf4ac5661d9724d0a358454c (patch)
treefd02b86d6a98eb890ab6ee4c6fa07e92a9b96cd4 /fpga_interchange
parent044c9ba2d4e66cf34214fdfd62fb90a872da64b1 (diff)
downloadnextpnr-0336f55b16373874cf4ac5661d9724d0a358454c.tar.gz
nextpnr-0336f55b16373874cf4ac5661d9724d0a358454c.tar.bz2
nextpnr-0336f55b16373874cf4ac5661d9724d0a358454c.zip
LUT mapping ceche optimizations 2
Signed-off-by: Maciej Kurc <mkurc@antmicro.com>
Diffstat (limited to 'fpga_interchange')
-rw-r--r--fpga_interchange/luts.cc80
-rw-r--r--fpga_interchange/site_lut_mapping_cache.cc9
-rw-r--r--fpga_interchange/site_lut_mapping_cache.h21
3 files changed, 17 insertions, 93 deletions
diff --git a/fpga_interchange/luts.cc b/fpga_interchange/luts.cc
index 2ac3b6da..9c68739e 100644
--- a/fpga_interchange/luts.cc
+++ b/fpga_interchange/luts.cc
@@ -446,86 +446,6 @@ bool LutMapper::remap_luts(const Context *ctx, SiteLutMappingResult* lut_mapping
lut_mapping->cells.push_back(cell);
}
-/*
-#ifdef DEBUG_LUT_ROTATION
- log_info("Final mapping:\n");
- for (size_t cell_idx = 0; cell_idx < cells.size(); ++cell_idx) {
- CellInfo *cell = cells[cell_idx];
- for (auto &cell_pin_pair : cell->cell_bel_pins) {
- log_info("%s %s %s =>", cell->type.c_str(ctx), cell->name.c_str(ctx), cell_pin_pair.first.c_str(ctx));
- for (auto bel_pin : cell_pin_pair.second) {
- log(" %s", bel_pin.c_str(ctx));
- }
- log("\n");
- }
- }
-#endif
-*/
-
-
-
-
-/*
-
- // Push new cell -> BEL pin maps out to cells now that equations have been
- // verified!
- for (size_t cell_idx = 0; cell_idx < cells.size(); ++cell_idx) {
- CellInfo *cell = cells[cell_idx];
- auto &lut_bel = *lut_bels[cell_idx];
-
- for (size_t pin_idx = 0; pin_idx < cell->lut_cell.pins.size(); ++pin_idx) {
- auto &bel_pins = cell->cell_bel_pins[cell->lut_cell.pins[pin_idx]];
- bel_pins.clear();
- bel_pins.push_back(lut_bel.pins[cell_to_bel_pin_remaps[cell_idx][pin_idx]]);
- }
- }
-
- if (cells.size() == element.lut_bels.size()) {
- for (size_t cell_idx = 0; cell_idx < cells.size(); ++cell_idx) {
- CellInfo *cell = cells[cell_idx];
- auto &lut_bel = *lut_bels[cell_idx];
- cell->lut_cell.vcc_pins.clear();
- for (size_t bel_pin_idx = 0; bel_pin_idx < lut_bel.pins.size(); ++bel_pin_idx) {
- if ((used_pins & (1 << bel_pin_idx)) == 0) {
- NPNR_ASSERT(bel_to_cell_pin_remaps[cell_idx][bel_pin_idx] == -1);
- cell->lut_cell.vcc_pins.emplace(lut_bel.pins.at(bel_pin_idx));
- }
- }
- }
- } else {
- // Look to see if wires can be run from element inputs to unused
- // outputs. If not, block the BEL pin by tying to VCC.
- //
- // FIXME: The assumption is that unused pins are tied VCC.
- // This is not generally true.
- //
- // 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, 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) {
- CellInfo *cell = cells[cell_idx];
- log(", %s => %s", ctx->nameOfBel(cell->bel), cell->name.c_str(ctx));
- }
- log("\n");
-#endif
-
- for (size_t cell_idx = 0; cell_idx < cells.size(); ++cell_idx) {
- CellInfo *cell = cells[cell_idx];
- auto &lut_bel = *lut_bels[cell_idx];
- cell->lut_cell.vcc_pins.clear();
- for (size_t bel_pin_idx = 0; bel_pin_idx < lut_bel.pins.size(); ++bel_pin_idx) {
- if ((vcc_pins & (1 << bel_pin_idx)) != 0) {
- NPNR_ASSERT(bel_to_cell_pin_remaps[cell_idx][bel_pin_idx] == -1);
- auto pin = lut_bel.pins.at(bel_pin_idx);
- cell->lut_cell.vcc_pins.emplace(pin);
- }
- }
- }
- }
-*/
-
return true;
}
diff --git a/fpga_interchange/site_lut_mapping_cache.cc b/fpga_interchange/site_lut_mapping_cache.cc
index 03ef03be..44a72772 100644
--- a/fpga_interchange/site_lut_mapping_cache.cc
+++ b/fpga_interchange/site_lut_mapping_cache.cc
@@ -61,7 +61,7 @@ SiteLutMappingKey SiteLutMappingKey::create (const SiteInformation& siteInfo) {
SiteLutMappingKey key;
key.tileType = siteInfo.tile_type;
key.siteType = ctx->chip_info->sites[siteInfo.site].site_type;
- key.cells.reserve(lutCells.size());
+ key.numCells = 0;
// Get bound nets. Store localized (to the LUT cluster) net indices only
// to get always the same key for the same LUT port configuration even
@@ -69,7 +69,9 @@ SiteLutMappingKey SiteLutMappingKey::create (const SiteInformation& siteInfo) {
dict<IdString, int32_t> netMap;
for (CellInfo* cellInfo : lutCells) {
- SiteLutMappingKey::Cell cell;
+ NPNR_ASSERT(key.numCells < SiteLutMappingKey::MAX_LUT_CELLS);
+ auto& cell = key.cells[key.numCells++];
+
cell.type = cellInfo->type;
cell.belIndex = cellInfo->bel.index;
@@ -103,9 +105,6 @@ SiteLutMappingKey SiteLutMappingKey::create (const SiteInformation& siteInfo) {
NPNR_ASSERT(portId < SiteLutMappingKey::MAX_LUT_INPUTS);
cell.conns[portId++] = netId;
}
-
- // Add the cell entry
- key.cells.push_back(cell);
}
// Compute hash
diff --git a/fpga_interchange/site_lut_mapping_cache.h b/fpga_interchange/site_lut_mapping_cache.h
index b07e3e77..df1ce474 100644
--- a/fpga_interchange/site_lut_mapping_cache.h
+++ b/fpga_interchange/site_lut_mapping_cache.h
@@ -28,7 +28,7 @@ NEXTPNR_NAMESPACE_BEGIN
// Key structure used in site LUT mapping cache
struct SiteLutMappingKey {
- // Maximum number of LUT cells
+ // Maximum number of LUT cells per site
static constexpr size_t MAX_LUT_CELLS = 8;
// Maximum number of LUT inputs per cell
static constexpr size_t MAX_LUT_INPUTS = 6;
@@ -44,18 +44,21 @@ struct SiteLutMappingKey {
int32_t conns [MAX_LUT_INPUTS];
};
- int32_t tileType; // Tile type
- int32_t siteType; // Site type in that tile type
- std::vector<Cell> cells; // LUT cell data
+ int32_t tileType; // Tile type
+ int32_t siteType; // Site type in that tile type
+ size_t numCells; // LUT cell count
+ Cell cells[MAX_LUT_CELLS]; // LUT cell data
- unsigned int hash_; // Precomputed hash
+ unsigned int hash_; // Precomputed hash
static SiteLutMappingKey create (const SiteInformation& siteInfo);
void computeHash () {
hash_ = mkhash(0, tileType);
hash_ = mkhash(hash_, siteType);
- for (const auto& cell : cells) {
+ hash_ = mkhash(hash_, numCells);
+ for (size_t j=0; j<numCells; ++j) {
+ const auto& cell = cells[j];
hash_ = mkhash(hash_, cell.type.index);
hash_ = mkhash(hash_, cell.belIndex);
for (size_t i=0; i<MAX_LUT_INPUTS; ++i) {
@@ -68,14 +71,16 @@ struct SiteLutMappingKey {
return (hash_ == other.hash_) &&
(tileType == other.tileType) &&
(siteType == other.siteType) &&
- (cells == other.cells);
+ (numCells == other.numCells) &&
+ (!memcmp(cells, other.cells, sizeof(Cell) * numCells));
}
bool operator != (const SiteLutMappingKey &other) const {
return (hash_ != other.hash_) ||
(tileType != other.tileType) ||
(siteType != other.siteType) ||
- (cells != other.cells);
+ (numCells != other.numCells) ||
+ (memcmp(cells, other.cells, sizeof(Cell) * numCells));
}
unsigned int hash () const {