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 #ifdef WITH_HEAP
#include "placer_heap.h"
#include <Eigen/Core> #include <Eigen/Core>
#include <Eigen/IterativeLinearSolvers> #include <Eigen/IterativeLinearSolvers>
#include <boost/optional.hpp> #include <boost/optional.hpp>
@ -135,7 +136,7 @@ template <typename T> struct EquationSystem
class HeAPPlacer class HeAPPlacer
{ {
public: public:
HeAPPlacer(Context *ctx) : ctx(ctx) { Eigen::initParallel(); } HeAPPlacer(Context *ctx, PlacerHeapCfg cfg) : ctx(ctx), cfg(cfg) { Eigen::initParallel(); }
bool place() bool place()
{ {
@ -292,6 +293,7 @@ class HeAPPlacer
private: private:
Context *ctx; Context *ctx;
PlacerHeapCfg cfg;
int max_x = 0, max_y = 0; int max_x = 0, max_y = 0;
std::vector<std::vector<std::vector<std::vector<BelId>>>> fast_bels; 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].locked = false;
cell_locs[cell.first].global = ctx->getBelGlobalBuf(bel); cell_locs[cell.first].global = ctx->getBelGlobalBuf(bel);
// FIXME // FIXME
if (has_connectivity(cell.second) && cell.second->type != ctx->id("SB_IO") && if (has_connectivity(cell.second) && !cfg.ioBufTypes.count(ci->type)) {
cell.second->type != ctx->id("TRELLIS_IO")) {
place_cells.push_back(ci); place_cells.push_back(ci);
placed = true; placed = true;
} else { } else {
@ -640,7 +641,8 @@ class HeAPPlacer
if (user_idx != -1 && net_crit.count(ni->name)) { if (user_idx != -1 && net_crit.count(ni->name)) {
auto &nc = net_crit.at(ni->name); auto &nc = net_crit.at(ni->name);
if (user_idx < int(nc.criticality.size())) 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, // 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) { if (iter != -1) {
const float alpha = 0.1; float alpha = cfg.alpha;
for (size_t row = 0; row < solve_cells.size(); row++) { for (size_t row = 0; row < solve_cells.size(); row++) {
int l_pos = legal_pos(solve_cells.at(row)); int l_pos = legal_pos(solve_cells.at(row));
int c_pos = cell_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; 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 NEXTPNR_NAMESPACE_END
#else #else
#include "log.h" #include "log.h"
#include "nextpnr.h" #include "nextpnr.h"
#include "placer_heap.h"
NEXTPNR_NAMESPACE_BEGIN 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"); log_error("nextpnr was built without the HeAP placer\n");
return false; return false;
} }
PlacerHeapCfg::PlacerHeapCfg(Context *ctx) : Settings(ctx) {}
NEXTPNR_NAMESPACE_END NEXTPNR_NAMESPACE_END
#endif #endif

View File

@ -27,8 +27,21 @@
#ifndef PLACER_HEAP_H #ifndef PLACER_HEAP_H
#define PLACER_HEAP #define PLACER_HEAP
#include "nextpnr.h" #include "nextpnr.h"
#include "settings.h"
NEXTPNR_NAMESPACE_BEGIN 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 NEXTPNR_NAMESPACE_END
#endif #endif

View File

@ -611,7 +611,8 @@ struct Timing
continue; continue;
delay_t dmax = crit_path->at(ClockPair{startdomain.first, startdomain.first}).path_delay; delay_t dmax = crit_path->at(ClockPair{startdomain.first, startdomain.first}).path_delay;
for (size_t i = 0; i < net->users.size(); i++) { 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.criticality.at(i) = std::min<double>(1.0, std::max<double>(0.0, criticality));
} }
nc.max_path_length = nd.max_path_length; 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) * 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))); (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 delay_t Arch::predictDelay(const NetInfo *net_info, const PortRef &sink) const
@ -517,10 +516,14 @@ bool Arch::place()
return false; return false;
#ifdef WITH_HEAP #ifdef WITH_HEAP
} else { } else {
if (!placer_heap(getCtx())) PlacerHeapCfg cfg(getCtx());
cfg.criticalityExponent = 7;
cfg.ioBufTypes.insert(id_TRELLIS_IO);
if (!placer_heap(getCtx(), cfg))
return false; return false;
} }
#endif #endif
permute_luts();
return true; return true;
} }

View File

@ -672,7 +672,9 @@ bool Arch::getBudgetOverride(const NetInfo *net_info, const PortRef &sink, delay
bool Arch::place() bool Arch::place()
{ {
if (bool_or_default(settings, id("heap_placer"), false)) { 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; return false;
} else { } else {
if (!placer1(getCtx(), Placer1Cfg(getCtx()))) if (!placer1(getCtx(), Placer1Cfg(getCtx())))