aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/place_common.cc18
-rw-r--r--common/place_common.h12
-rw-r--r--common/placer1.cc54
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;