diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/place_common.cc | 18 | ||||
-rw-r--r-- | common/place_common.h | 12 | ||||
-rw-r--r-- | common/placer1.cc | 54 |
3 files changed, 45 insertions, 39 deletions
diff --git a/common/place_common.cc b/common/place_common.cc index 60735890..b2f0e849 100644 --- a/common/place_common.cc +++ b/common/place_common.cc @@ -25,7 +25,7 @@ NEXTPNR_NAMESPACE_BEGIN // Get the total estimated wirelength for a net -wirelen_t get_net_wirelength(const Context *ctx, const NetInfo *net, float &tns) +wirelen_t get_net_metric(const Context *ctx, const NetInfo *net, MetricType type, float &tns) { wirelen_t wirelength = 0; int driver_x, driver_y; @@ -47,7 +47,7 @@ wirelen_t get_net_wirelength(const Context *ctx, const NetInfo *net, float &tns) CellInfo *load_cell = load.cell; if (load_cell->bel == BelId()) continue; - if (ctx->timing_driven) { + if (ctx->timing_driven && type == MetricType::COST) { WireId user_wire = ctx->getWireBelPin(load_cell->bel, ctx->portPinFromId(load.port)); delay_t raw_wl = ctx->estimateDelay(drv_wire, user_wire); float slack = ctx->getDelayNS(load.budget) - ctx->getDelayNS(raw_wl); @@ -66,7 +66,7 @@ wirelen_t get_net_wirelength(const Context *ctx, const NetInfo *net, float &tns) xmax = std::max(xmax, load_x); ymax = std::max(ymax, load_y); } - if (ctx->timing_driven) { + if (ctx->timing_driven && type == MetricType::COST) { wirelength = wirelen_t((((ymax - ymin) + (xmax - xmin)) * std::min(5.0, (1.0 + std::exp(-worst_slack / 5))))); } else { wirelength = wirelen_t((ymax - ymin) + (xmax - xmin)); @@ -76,7 +76,7 @@ wirelen_t get_net_wirelength(const Context *ctx, const NetInfo *net, float &tns) } // Get the total wirelength for a cell -wirelen_t get_cell_wirelength(const Context *ctx, const CellInfo *cell) +wirelen_t get_cell_metric(const Context *ctx, const CellInfo *cell, MetricType type) { std::set<IdString> nets; for (auto p : cell->ports) { @@ -86,16 +86,16 @@ wirelen_t get_cell_wirelength(const Context *ctx, const CellInfo *cell) wirelen_t wirelength = 0; float tns = 0; for (auto n : nets) { - wirelength += get_net_wirelength(ctx, ctx->nets.at(n).get(), tns); + wirelength += get_net_metric(ctx, ctx->nets.at(n).get(), type, tns); } return wirelength; } -wirelen_t get_cell_wirelength_at_bel(const Context *ctx, CellInfo *cell, BelId bel) +wirelen_t get_cell_metric_at_bel(const Context *ctx, CellInfo *cell, BelId bel, MetricType type) { BelId oldBel = cell->bel; cell->bel = bel; - wirelen_t wirelen = get_cell_wirelength(ctx, cell); + wirelen_t wirelen = get_cell_metric(ctx, cell, type); cell->bel = oldBel; return wirelen; } @@ -118,7 +118,7 @@ bool place_single_cell(Context *ctx, CellInfo *cell, bool require_legality) for (auto bel : ctx->getBels()) { if (ctx->getBelType(bel) == targetType && (!require_legality || ctx->isValidBelForCell(cell, bel))) { if (ctx->checkBelAvail(bel)) { - wirelen_t wirelen = get_cell_wirelength_at_bel(ctx, cell, bel); + wirelen_t wirelen = get_cell_metric_at_bel(ctx, cell, bel, MetricType::COST); if (iters >= 4) wirelen += ctx->rng(25); if (wirelen <= best_wirelen) { @@ -126,7 +126,7 @@ bool place_single_cell(Context *ctx, CellInfo *cell, bool require_legality) best_bel = bel; } } else { - wirelen_t wirelen = get_cell_wirelength_at_bel(ctx, cell, bel); + wirelen_t wirelen = get_cell_metric_at_bel(ctx, cell, bel, MetricType::COST); if (iters >= 4) wirelen += ctx->rng(25); if (wirelen <= best_ripup_wirelen) { diff --git a/common/place_common.h b/common/place_common.h index 67956072..32250604 100644 --- a/common/place_common.h +++ b/common/place_common.h @@ -26,14 +26,20 @@ NEXTPNR_NAMESPACE_BEGIN typedef int64_t wirelen_t; +enum class MetricType +{ + COST, + WIRELENGTH +}; + // Return the wirelength of a net -wirelen_t get_net_wirelength(const Context *ctx, const NetInfo *net, float &tns); +wirelen_t get_net_metric(const Context *ctx, const NetInfo *net, MetricType type, float &tns); // Return the wirelength of all nets connected to a cell -wirelen_t get_cell_wirelength(const Context *ctx, const CellInfo *cell); +wirelen_t get_cell_metric(const Context *ctx, const CellInfo *cell, MetricType type); // Return the wirelength of all nets connected to a cell, when the cell is at a given bel -wirelen_t get_cell_wirelength_at_bel(const Context *ctx, CellInfo *cell, BelId bel); +wirelen_t get_cell_metric_at_bel(const Context *ctx, CellInfo *cell, BelId bel, MetricType type); // Place a single cell in the lowest wirelength Bel available, optionally requiring validity check bool place_single_cell(Context *ctx, CellInfo *cell, bool require_legality); diff --git a/common/placer1.cc b/common/placer1.cc index 53295a91..74a11040 100644 --- a/common/placer1.cc +++ b/common/placer1.cc @@ -135,17 +135,17 @@ class SAPlacer log_info("Running simulated annealing placer.\n"); - // Calculate wirelength after initial placement - curr_wirelength = 0; + // Calculate metric after initial placement + curr_metric = 0; curr_tns = 0; for (auto &net : ctx->nets) { - wirelen_t wl = get_net_wirelength(ctx, net.second.get(), curr_tns); - wirelengths[net.first] = wl; - curr_wirelength += wl; + wirelen_t wl = get_net_metric(ctx, net.second.get(), MetricType::COST, curr_tns); + metrics[net.first] = wl; + curr_metric += wl; } int n_no_progress = 0; - double avg_wirelength = curr_wirelength; + double avg_metric = curr_metric; temp = 10000; // Main simulated annealing loop @@ -154,9 +154,9 @@ class SAPlacer improved = false; if (iter % 5 == 0 || iter == 1) - log_info(" at iteration #%d: temp = %f, wire length = " + log_info(" at iteration #%d: temp = %f, cost = " "%.0f, est tns = %.02fns\n", - iter, temp, double(curr_wirelength), curr_tns); + iter, temp, double(curr_metric), curr_tns); for (int m = 0; m < 15; ++m) { // Loop through all automatically placed cells @@ -177,7 +177,7 @@ class SAPlacer if (temp <= 1e-3 && n_no_progress >= 5) { if (iter % 5 != 0) - log_info(" at iteration #%d: temp = %f, wire length = %f\n", iter, temp, double(curr_wirelength)); + log_info(" at iteration #%d: temp = %f, cost = %f\n", iter, temp, double(curr_metric)); break; } @@ -187,8 +187,8 @@ class SAPlacer double upper = 0.6, lower = 0.4; - if (curr_wirelength < 0.95 * avg_wirelength) { - avg_wirelength = 0.8 * avg_wirelength + 0.2 * curr_wirelength; + if (curr_metric < 0.95 * avg_metric) { + avg_metric = 0.8 * avg_metric + 0.2 * curr_metric; } else { if (Raccept >= 0.8) { temp *= 0.7; @@ -223,14 +223,14 @@ class SAPlacer assign_budget(ctx); } - // Recalculate total wirelength entirely to avoid rounding errors + // Recalculate total metric entirely to avoid rounding errors // accumulating over time - curr_wirelength = 0; + curr_metric = 0; curr_tns = 0; for (auto &net : ctx->nets) { - wirelen_t wl = get_net_wirelength(ctx, net.second.get(), curr_tns); - wirelengths[net.first] = wl; - curr_wirelength += wl; + wirelen_t wl = get_net_metric(ctx, net.second.get(), MetricType::COST, curr_tns); + metrics[net.first] = wl; + curr_metric += wl; } } // Final post-pacement validitiy check @@ -320,7 +320,7 @@ class SAPlacer if (other_cell->belStrength > STRENGTH_WEAK) return false; } - wirelen_t new_wirelength = 0, delta; + wirelen_t new_metric = 0, delta; ctx->unbindBel(oldBel); if (other != IdString()) { ctx->unbindBel(newBel); @@ -350,17 +350,17 @@ class SAPlacer } } - new_wirelength = curr_wirelength; + new_metric = curr_metric; - // Recalculate wirelengths for all nets touched by the peturbation + // Recalculate metrics for all nets touched by the peturbation for (auto net : update) { - new_wirelength -= wirelengths.at(net->name); + new_metric -= metrics.at(net->name); float temp_tns = 0; - wirelen_t net_new_wl = get_net_wirelength(ctx, net, temp_tns); - new_wirelength += net_new_wl; + wirelen_t net_new_wl = get_net_metric(ctx, net, MetricType::COST, temp_tns); + new_metric += net_new_wl; new_lengths.push_back(std::make_pair(net->name, net_new_wl)); } - delta = new_wirelength - curr_wirelength; + delta = new_metric - curr_metric; n_move++; // SA acceptance criterea if (delta < 0 || (temp > 1e-6 && (ctx->rng() / float(0x3fffffff)) <= std::exp(-delta / temp))) { @@ -373,9 +373,9 @@ class SAPlacer ctx->unbindBel(newBel); goto swap_fail; } - curr_wirelength = new_wirelength; + curr_metric = new_metric; for (auto new_wl : new_lengths) - wirelengths.at(new_wl.first) = new_wl.second; + metrics.at(new_wl.first) = new_wl.second; return true; swap_fail: @@ -413,8 +413,8 @@ class SAPlacer } Context *ctx; - std::unordered_map<IdString, wirelen_t> wirelengths; - wirelen_t curr_wirelength = std::numeric_limits<wirelen_t>::max(); + std::unordered_map<IdString, wirelen_t> metrics; + wirelen_t curr_metric = std::numeric_limits<wirelen_t>::max(); float curr_tns = 0; float temp = 1000; bool improved = false; |