HeAP: Add PlacerHeapCfg

Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
David Shah 2019-02-25 12:48:01 +00:00
parent 7142db28a8
commit bd12c0a486
5 changed files with 45 additions and 12 deletions

View File

@ -33,6 +33,7 @@
#ifdef WITH_HEAP
#include "placer_heap.h"
#include <Eigen/Core>
#include <Eigen/IterativeLinearSolvers>
#include <boost/optional.hpp>
@ -135,7 +136,7 @@ template <typename T> struct EquationSystem
class HeAPPlacer
{
public:
HeAPPlacer(Context *ctx) : ctx(ctx) { Eigen::initParallel(); }
HeAPPlacer(Context *ctx, PlacerHeapCfg cfg) : ctx(ctx), cfg(cfg) { Eigen::initParallel(); }
bool place()
{
@ -292,6 +293,7 @@ class HeAPPlacer
private:
Context *ctx;
PlacerHeapCfg cfg;
int max_x = 0, max_y = 0;
std::vector<std::vector<std::vector<std::vector<BelId>>>> fast_bels;
@ -497,8 +499,7 @@ class HeAPPlacer
cell_locs[cell.first].locked = false;
cell_locs[cell.first].global = ctx->getBelGlobalBuf(bel);
// FIXME
if (has_connectivity(cell.second) && cell.second->type != ctx->id("SB_IO") &&
cell.second->type != ctx->id("TRELLIS_IO")) {
if (has_connectivity(cell.second) && !cfg.ioBufTypes.count(ci->type)) {
place_cells.push_back(ci);
placed = true;
} else {
@ -640,7 +641,8 @@ class HeAPPlacer
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 + 10 * std::pow(nc.criticality.at(user_idx), 2));
weight *= (1.0 + cfg.timingWeight *
std::pow(nc.criticality.at(user_idx), cfg.criticalityExponent));
}
// If cell 0 is not fixed, it will stamp +w on its equation and -w on the other end's equation,
@ -655,7 +657,7 @@ class HeAPPlacer
});
}
if (iter != -1) {
const float alpha = 0.1;
float alpha = cfg.alpha;
for (size_t row = 0; row < solve_cells.size(); row++) {
int l_pos = legal_pos(solve_cells.at(row));
int c_pos = cell_pos(solve_cells.at(row));
@ -1510,20 +1512,32 @@ class HeAPPlacer
};
int HeAPPlacer::CutSpreader::seq = 0;
bool placer_heap(Context *ctx) { return HeAPPlacer(ctx).place(); }
bool placer_heap(Context *ctx, PlacerHeapCfg cfg) { return HeAPPlacer(ctx, cfg).place(); }
PlacerHeapCfg::PlacerHeapCfg(Context *ctx) : Settings(ctx)
{
alpha = get<float>("placerHeap/alpha", 0.1);
criticalityExponent = get<int>("placerHeap/criticalityExponent", 2);
timingWeight = get<int>("placerHeap/timingWeight", 10);
}
NEXTPNR_NAMESPACE_END
#else
#include "log.h"
#include "nextpnr.h"
#include "placer_heap.h"
NEXTPNR_NAMESPACE_BEGIN
bool placer_heap(Context *ctx)
bool placer_heap(Context *ctx, PlacerHeapCfg cfg)
{
log_error("nextpnr was built without the HeAP placer\n");
return false;
}
PlacerHeapCfg::PlacerHeapCfg(Context *ctx) : Settings(ctx) {}
NEXTPNR_NAMESPACE_END
#endif

View File

@ -27,8 +27,21 @@
#ifndef PLACER_HEAP_H
#define PLACER_HEAP
#include "nextpnr.h"
#include "settings.h"
NEXTPNR_NAMESPACE_BEGIN
extern bool placer_heap(Context *ctx);
struct PlacerHeapCfg : public Settings
{
PlacerHeapCfg(Context *ctx);
float alpha;
float criticalityExponent;
float timingWeight;
std::unordered_set<IdString> ioBufTypes;
};
extern bool placer_heap(Context *ctx, PlacerHeapCfg cfg);
NEXTPNR_NAMESPACE_END
#endif

View File

@ -611,7 +611,8 @@ struct Timing
continue;
delay_t dmax = crit_path->at(ClockPair{startdomain.first, startdomain.first}).path_delay;
for (size_t i = 0; i < net->users.size(); i++) {
float criticality = 1.0f - (float(nc.slack.at(i) - worst_slack.at(startdomain.first)) / dmax);
float criticality =
1.0f - ((float(nc.slack.at(i)) - float(worst_slack.at(startdomain.first))) / dmax);
nc.criticality.at(i) = std::min<double>(1.0, std::max<double>(0.0, criticality));
}
nc.max_path_length = nd.max_path_length;

View File

@ -460,7 +460,6 @@ delay_t Arch::estimateDelay(WireId src, WireId dst) const
return (130 - 25 * args.speed) *
(6 + std::max(dx - 5, 0) + std::max(dy - 5, 0) + 2 * (std::min(dx, 5) + std::min(dy, 5)));
}
delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const
@ -517,10 +516,14 @@ bool Arch::place()
return false;
#ifdef WITH_HEAP
} else {
if (!placer_heap(getCtx()))
PlacerHeapCfg cfg(getCtx());
cfg.criticalityExponent = 7;
cfg.ioBufTypes.insert(id_TRELLIS_IO);
if (!placer_heap(getCtx(), cfg))
return false;
}
#endif
permute_luts();
return true;
}

View File

@ -672,7 +672,9 @@ bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay
bool Arch::place()
{
if (bool_or_default(settings, id("heap_placer"), false)) {
if (!placer_heap(getCtx()))
PlacerHeapCfg cfg(getCtx());
cfg.ioBufTypes.insert(id_SB_IO);
if (!placer_heap(getCtx(), cfg))
return false;
} else {
if (!placer1(getCtx(), Placer1Cfg(getCtx())))