diff options
author | gatecat <gatecat@ds0.me> | 2021-07-22 14:09:40 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-22 14:09:40 +0100 |
commit | 5212e38512586a6aea0a3b075d30cd172026cd3e (patch) | |
tree | 9ea2c4a1091424cd131e8fdab67a4f9339213894 /fpga_interchange/site_router.cc | |
parent | 8733cce5fa44e095e654f487781555bd20edc48f (diff) | |
parent | 580a45485afe48a77272f44f8aa99875cdd4d441 (diff) | |
download | nextpnr-5212e38512586a6aea0a3b075d30cd172026cd3e.tar.gz nextpnr-5212e38512586a6aea0a3b075d30cd172026cd3e.tar.bz2 nextpnr-5212e38512586a6aea0a3b075d30cd172026cd3e.zip |
Merge pull request #757 from antmicro/lut-mapping-cache
interchange: Add caching of site LUT mapping solution
Diffstat (limited to 'fpga_interchange/site_router.cc')
-rw-r--r-- | fpga_interchange/site_router.cc | 80 |
1 files changed, 55 insertions, 25 deletions
diff --git a/fpga_interchange/site_router.cc b/fpga_interchange/site_router.cc index f209bd8c..947081f4 100644 --- a/fpga_interchange/site_router.cc +++ b/fpga_interchange/site_router.cc @@ -1050,42 +1050,71 @@ static void apply_routing(Context *ctx, const SiteArch &site_arch, pool<std::pai static bool map_luts_in_site(const SiteInformation &site_info, pool<std::pair<IdString, IdString>> *blocked_wires) { const Context *ctx = site_info.ctx; - const std::vector<LutElement> &lut_elements = ctx->lut_elements.at(site_info.tile_type); - std::vector<LutMapper> lut_mappers; - lut_mappers.reserve(lut_elements.size()); - for (size_t i = 0; i < lut_elements.size(); ++i) { - lut_mappers.push_back(LutMapper(lut_elements[i])); - } + bool enable_cache = !ctx->arch_args.disable_lut_mapping_cache; - for (CellInfo *cell : site_info.cells_in_site) { - if (cell->lut_cell.pins.empty()) { - continue; - } + // Create a site LUT mapping key + SiteLutMappingKey key = SiteLutMappingKey::create(site_info); - BelId bel = cell->bel; - const auto &bel_data = bel_info(ctx->chip_info, bel); - if (bel_data.lut_element != -1) { - lut_mappers[bel_data.lut_element].cells.push_back(cell); + // Get the solution from cache. If not found then compute it + SiteLutMappingResult lutMapping; + if (!enable_cache || !ctx->site_lut_mapping_cache.get(key, &lutMapping)) { + + const std::vector<LutElement> &lut_elements = ctx->lut_elements.at(site_info.tile_type); + std::vector<LutMapper> lut_mappers; + lut_mappers.reserve(lut_elements.size()); + for (size_t i = 0; i < lut_elements.size(); ++i) { + lut_mappers.push_back(LutMapper(lut_elements[i])); } - } - blocked_wires->clear(); - for (LutMapper lut_mapper : lut_mappers) { - if (lut_mapper.cells.empty()) { - continue; + for (CellInfo *cell : site_info.cells_in_site) { + if (cell->lut_cell.pins.empty()) { + continue; + } + + BelId bel = cell->bel; + const auto &bel_data = bel_info(ctx->chip_info, bel); + if (bel_data.lut_element != -1) { + lut_mappers[bel_data.lut_element].cells.push_back(cell); + } } - pool<const LutBel *, hash_ptr_ops> blocked_luts; - if (!lut_mapper.remap_luts(ctx, &blocked_luts)) { - return false; + bool res = true; + + lutMapping.blockedWires.clear(); + for (LutMapper lut_mapper : lut_mappers) { + if (lut_mapper.cells.empty()) { + continue; + } + + pool<const LutBel *, hash_ptr_ops> blocked_luts; + if (!lut_mapper.remap_luts(ctx, &lutMapping, &blocked_luts)) { + res = false; + break; + } + + for (const LutBel *lut_bel : blocked_luts) { + lutMapping.blockedWires.emplace(std::make_pair(lut_bel->name, lut_bel->output_pin)); + } } - for (const LutBel *lut_bel : blocked_luts) { - blocked_wires->emplace(std::make_pair(lut_bel->name, lut_bel->output_pin)); + lutMapping.isValid = res; + + // Add the solution to the cache + if (enable_cache) { + ctx->site_lut_mapping_cache.add(key, lutMapping); } } - return true; + // Apply the solution if valid + if (lutMapping.isValid) { + + lutMapping.apply(site_info); + + blocked_wires->clear(); + blocked_wires->insert(lutMapping.blockedWires.begin(), lutMapping.blockedWires.end()); + } + + return lutMapping.isValid; } // Block outputs of unavailable LUTs to prevent site router from using them. @@ -1255,6 +1284,7 @@ bool SiteRouter::checkSiteRouting(const Context *ctx, const TileStatus &tile_sta // Because site routing checks are expensive, cache them. // SiteRouter::bindBel/unbindBel should correctly invalid the cache by // setting dirty=true. + if (!dirty) { return site_ok; } |