From 044c9ba2d4e66cf34214fdfd62fb90a872da64b1 Mon Sep 17 00:00:00 2001 From: Maciej Kurc Date: Fri, 16 Jul 2021 13:28:40 +0200 Subject: LUT mapping cache optimizations 1 Signed-off-by: Maciej Kurc --- fpga_interchange/site_lut_mapping_cache.cc | 28 ++++++++++++---- fpga_interchange/site_lut_mapping_cache.h | 52 +++++++++++++++--------------- 2 files changed, 48 insertions(+), 32 deletions(-) diff --git a/fpga_interchange/site_lut_mapping_cache.cc b/fpga_interchange/site_lut_mapping_cache.cc index bcde7621..03ef03be 100644 --- a/fpga_interchange/site_lut_mapping_cache.cc +++ b/fpga_interchange/site_lut_mapping_cache.cc @@ -73,29 +73,44 @@ SiteLutMappingKey SiteLutMappingKey::create (const SiteInformation& siteInfo) { cell.type = cellInfo->type; cell.belIndex = cellInfo->bel.index; + memset((void*)cell.conns, 0, + sizeof(int32_t) * SiteLutMappingKey::MAX_LUT_INPUTS); + + size_t portId = 0; for (const auto& port : cellInfo->ports) { const auto& portInfo = port.second; + + // Consider only LUT inputs + if (portInfo.type != PORT_IN) { + continue; + } + + // Assign net id if any + int32_t netId = 0; if (portInfo.net != nullptr) { auto netInfo = portInfo.net; - int32_t netId = -1; auto it = netMap.find(netInfo->name); if (it != netMap.end()) { netId = it->second; } else { - netId = (int32_t)netMap.size(); + netId = (int32_t)netMap.size() + 1; netMap[netInfo->name] = netId; } - - cell.conns[portInfo.name] = netId; } + + NPNR_ASSERT(portId < SiteLutMappingKey::MAX_LUT_INPUTS); + cell.conns[portId++] = netId; } // Add the cell entry key.cells.push_back(cell); } + // Compute hash + key.computeHash(); + return key; } @@ -120,9 +135,10 @@ bool SiteLutMappingResult::apply (const SiteInformation& siteInfo) { // Cell <-> BEL pin map size_t numPins = cellInfo->lut_cell.pins.size(); for (size_t pinIdx = 0; pinIdx < numPins; ++pinIdx) { - IdString cellPin = cellInfo->lut_cell.pins[pinIdx]; - auto &belPins = cellInfo->cell_bel_pins[cellPin]; + const IdString& cellPin = cellInfo->lut_cell.pins[pinIdx]; + auto &belPins = cellInfo->cell_bel_pins[cellPin]; + // There is only one pin belPins.resize(1); belPins[0] = cell.belPins[cellPin]; } diff --git a/fpga_interchange/site_lut_mapping_cache.h b/fpga_interchange/site_lut_mapping_cache.h index 4a81711f..b07e3e77 100644 --- a/fpga_interchange/site_lut_mapping_cache.h +++ b/fpga_interchange/site_lut_mapping_cache.h @@ -28,6 +28,11 @@ NEXTPNR_NAMESPACE_BEGIN // Key structure used in site LUT mapping cache struct SiteLutMappingKey { + // Maximum number of LUT cells + static constexpr size_t MAX_LUT_CELLS = 8; + // Maximum number of LUT inputs per cell + static constexpr size_t MAX_LUT_INPUTS = 6; + // LUT Cell data struct Cell { IdString type; // Cell type @@ -35,51 +40,46 @@ struct SiteLutMappingKey { // Port to net assignments. These are local net ids generated during // key creation. This is to abstract connections from actual design - // net names. - dict conns; - - bool operator == (const Cell& other) const { - return (type == other.type) && - (belIndex == other.belIndex) && - (conns == other.conns); - } - - bool operator < (const Cell& other) const { - return belIndex < other.belIndex; - } + // net names. the Id 0 means unconnected. + int32_t conns [MAX_LUT_INPUTS]; }; int32_t tileType; // Tile type int32_t siteType; // Site type in that tile type std::vector cells; // LUT cell data + 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_, cell.type.index); + hash_ = mkhash(hash_, cell.belIndex); + for (size_t i=0; i