aboutsummaryrefslogtreecommitdiffstats
path: root/fpga_interchange/site_router.cc
diff options
context:
space:
mode:
authorgatecat <gatecat@ds0.me>2021-07-22 14:09:40 +0100
committerGitHub <noreply@github.com>2021-07-22 14:09:40 +0100
commit5212e38512586a6aea0a3b075d30cd172026cd3e (patch)
tree9ea2c4a1091424cd131e8fdab67a4f9339213894 /fpga_interchange/site_router.cc
parent8733cce5fa44e095e654f487781555bd20edc48f (diff)
parent580a45485afe48a77272f44f8aa99875cdd4d441 (diff)
downloadnextpnr-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.cc80
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;
}