diff options
author | Maciej Kurc <mkurc@antmicro.com> | 2021-07-16 13:55:19 +0200 |
---|---|---|
committer | Maciej Kurc <mkurc@antmicro.com> | 2021-07-16 13:55:19 +0200 |
commit | 0336f55b16373874cf4ac5661d9724d0a358454c (patch) | |
tree | fd02b86d6a98eb890ab6ee4c6fa07e92a9b96cd4 | |
parent | 044c9ba2d4e66cf34214fdfd62fb90a872da64b1 (diff) | |
download | nextpnr-0336f55b16373874cf4ac5661d9724d0a358454c.tar.gz nextpnr-0336f55b16373874cf4ac5661d9724d0a358454c.tar.bz2 nextpnr-0336f55b16373874cf4ac5661d9724d0a358454c.zip |
LUT mapping ceche optimizations 2
Signed-off-by: Maciej Kurc <mkurc@antmicro.com>
-rw-r--r-- | fpga_interchange/luts.cc | 80 | ||||
-rw-r--r-- | fpga_interchange/site_lut_mapping_cache.cc | 9 | ||||
-rw-r--r-- | fpga_interchange/site_lut_mapping_cache.h | 21 |
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 { |