aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorDavid Shah <dave@ds0.me>2019-01-25 13:15:36 +0000
committerDavid Shah <dave@ds0.me>2019-03-22 10:31:54 +0000
commit3dedc6259396fd4960a9aa43e05f9011323fb7cd (patch)
tree66af4e0f1eb291cd72375ce8d1854be406bc1539 /common
parent05e9ae183d7d971f1df30e0cc989d20ee6f309a9 (diff)
downloadnextpnr-3dedc6259396fd4960a9aa43e05f9011323fb7cd.tar.gz
nextpnr-3dedc6259396fd4960a9aa43e05f9011323fb7cd.tar.bz2
nextpnr-3dedc6259396fd4960a9aa43e05f9011323fb7cd.zip
HeAP: Weight arcs by criticality for timing-driven placement
Signed-off-by: David Shah <dave@ds0.me>
Diffstat (limited to 'common')
-rw-r--r--common/placer_heap.cc24
1 files changed, 18 insertions, 6 deletions
diff --git a/common/placer_heap.cc b/common/placer_heap.cc
index 884c18e0..73aeb9b4 100644
--- a/common/placer_heap.cc
+++ b/common/placer_heap.cc
@@ -39,6 +39,7 @@
#include "placer_math.h"
#include "placer1.h"
#include "util.h"
+#include "timing.h"
NEXTPNR_NAMESPACE_BEGIN
namespace {
@@ -187,6 +188,10 @@ class HeAPPlacer
legal_hpwl = total_hpwl();
log_info("Legalised HPWL = %d (%s)\n", int(legal_hpwl), valid ? "valid" : "invalid");
+
+ if (ctx->timing_driven)
+ get_criticalities(ctx, &net_crit);
+
if (legal_hpwl < best_hpwl) {
best_hpwl = legal_hpwl;
stalled = 0;
@@ -278,6 +283,8 @@ class HeAPPlacer
// Performance counting
double solve_time = 0, cl_time = 0, sl_time = 0;
+ NetCriticalityMap net_crit;
+
// Place cells with the BEL attribute set to constrain them
void place_constraints()
{
@@ -516,9 +523,9 @@ class HeAPPlacer
template <typename Tf> void foreach_port(NetInfo *net, Tf func)
{
if (net->driver.cell != nullptr)
- func(net->driver);
- for (auto &user : net->users)
- func(user);
+ func(net->driver, -1);
+ for (size_t i = 0; i < net->users.size(); i++)
+ func(net->users.at(i), i);
}
// Build the system of equations for either X or Y
@@ -541,7 +548,7 @@ class HeAPPlacer
// Find the bounds of the net in this axis, and the ports that correspond to these bounds
PortRef *lbport = nullptr, *ubport = nullptr;
int lbpos = std::numeric_limits<int>::max(), ubpos = std::numeric_limits<int>::min();
- foreach_port(ni, [&](PortRef &port) {
+ foreach_port(ni, [&](PortRef &port, int user_idx) {
int pos = cell_pos(port.cell);
if (pos < lbpos) {
lbpos = pos;
@@ -573,7 +580,7 @@ class HeAPPlacer
};
// Add all relevant connections to the matrix
- foreach_port(ni, [&](PortRef &port) {
+ foreach_port(ni, [&](PortRef &port, int user_idx) {
int this_pos = cell_pos(port.cell);
auto process_arc = [&](PortRef *other) {
if (other == &port)
@@ -582,7 +589,12 @@ class HeAPPlacer
// if (o_pos == this_pos)
// return; // FIXME: or clamp to 1?
double weight = 1.0 / (ni->users.size() * std::max<double>(1, std::abs(o_pos - this_pos)));
- // FIXME: add criticality to weighting
+
+ if (user_idx != -1 && net_crit.count(ni->name)) {
+ auto &nc = net_crit.at(ni->name);
+ if (user_idx < int(nc.criticality.size()))
+ weight *= (1.0 + 20 * std::pow(nc.criticality.at(user_idx), 2));
+ }
// If cell 0 is not fixed, it will stamp +w on its equation and -w on the other end's equation,
// if the other end isn't fixed