placer1: Make budget-based placement an option

Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
David Shah 2018-12-08 13:59:10 +00:00 committed by David Shah
parent a218c27305
commit 0d80181c5e
3 changed files with 35 additions and 22 deletions

View File

@ -122,6 +122,8 @@ po::options_description CommandHandler::getGeneralOptions()
general.add_options()("randomize-seed,r", "randomize seed value for random number generator");
general.add_options()("slack_redist_iter", po::value<int>(), "number of iterations between slack redistribution");
general.add_options()("cstrweight", po::value<float>(), "placer weighting for relative constraint satisfaction");
general.add_options()("placer-budgets", "use budget rather than criticality in placer timing weights");
general.add_options()("pack-only", "pack design only without placement or routing");
general.add_options()("ignore-loops", "ignore combinational loops in timing analysis");
@ -187,6 +189,9 @@ void CommandHandler::setupContext(Context *ctx)
settings->set("placer1/constraintWeight", vm["cstrweight"].as<float>());
}
if (vm.count("placer-budgets")) {
settings->set("placer1/budgetBased", true);
}
if (vm.count("freq")) {
auto freq = vm["freq"].as<double>();
if (freq > 0)

View File

@ -43,18 +43,17 @@
#include "timing.h"
#include "util.h"
namespace std {
template <> struct hash<std::pair<NEXTPNR_NAMESPACE_PREFIX IdString, std::size_t>>
{
std::size_t
operator()(const std::pair<NEXTPNR_NAMESPACE_PREFIX IdString, std::size_t> &idp) const noexcept
template <> struct hash<std::pair<NEXTPNR_NAMESPACE_PREFIX IdString, std::size_t>>
{
std::size_t operator()(const std::pair<NEXTPNR_NAMESPACE_PREFIX IdString, std::size_t> &idp) const noexcept
{
std::size_t seed = 0;
boost::hash_combine(seed, hash<NEXTPNR_NAMESPACE_PREFIX IdString>()(idp.first));
boost::hash_combine(seed, hash<std::size_t>()(idp.second));
return seed;
}
};
}
};
} // namespace std
NEXTPNR_NAMESPACE_BEGIN
@ -175,7 +174,7 @@ class SAPlacer
if ((placed_cells - constr_placed_cells) % 500 != 0)
log_info(" initial placement placed %d/%d cells\n", int(placed_cells - constr_placed_cells),
int(autoplaced.size()));
if (ctx->slack_redist_iter > 0)
if (cfg.budgetBased && ctx->slack_redist_iter > 0)
assign_budget(ctx);
ctx->yield();
auto iplace_end = std::chrono::high_resolution_clock::now();
@ -184,6 +183,7 @@ class SAPlacer
log_info("Running simulated annealing placer.\n");
// Invoke timing analysis to obtain criticalities
if (!cfg.budgetBased)
get_criticalities(ctx, &net_crit);
// Calculate costs after initial placement
@ -280,15 +280,16 @@ class SAPlacer
ctx->shuffle(autoplaced);
// Legalisation is a big change so force a slack redistribution here
if (ctx->slack_redist_iter > 0)
if (ctx->slack_redist_iter > 0 && cfg.budgetBased)
assign_budget(ctx, true /* quiet */);
}
require_legal = false;
} else if (ctx->slack_redist_iter > 0 && iter % ctx->slack_redist_iter == 0) {
} else if (cfg.budgetBased && ctx->slack_redist_iter > 0 && iter % ctx->slack_redist_iter == 0) {
assign_budget(ctx, true /* quiet */);
}
// Invoke timing analysis to obtain criticalities
if (!cfg.budgetBased)
get_criticalities(ctx, &net_crit);
// Need to rebuild costs after criticalities change
setup_costs();
@ -434,7 +435,7 @@ class SAPlacer
delta += (cfg.constraintWeight / temp) * (new_dist - old_dist) / last_wirelen_cost;
n_move++;
// SA acceptance criterea
if (delta < 0 || (temp > 1e-6 && (ctx->rng() / float(0x0fffffff)) <= std::exp(-100*delta / temp))) {
if (delta < 0 || (temp > 1e-6 && (ctx->rng() / float(0x0fffffff)) <= std::exp(-100 * delta / temp))) {
n_accept++;
} else {
if (other_cell != nullptr)
@ -518,12 +519,17 @@ class SAPlacer
return 0;
if (ctx->getPortTimingClass(net->driver.cell, net->driver.port, cc) == TMG_IGNORE)
return 0;
if (cfg.budgetBased) {
double delay = ctx->getDelayNS(ctx->predictDelay(net, net->users.at(user)));
return std::min(10.0, std::exp(delay - ctx->getDelayNS(net->users.at(user).budget)));
} else {
auto crit = net_crit.find(net->name);
if (crit == net_crit.end() || crit->second.criticality.empty())
return 0;
double delay = ctx->getDelayNS(ctx->predictDelay(net, net->users.at(user)));
return delay * std::pow(crit->second.criticality.at(user), crit_exp);
}
}
// Set up the cost maps
void setup_costs()
@ -690,6 +696,7 @@ Placer1Cfg::Placer1Cfg(Context *ctx) : Settings(ctx)
{
constraintWeight = get<float>("placer1/constraintWeight", 10);
minBelsForGridPick = get<int>("placer1/minBelsForGridPick", 64);
budgetBased = get<bool>("placer1/budgetBased", false);
}
bool placer1(Context *ctx, Placer1Cfg cfg)

View File

@ -29,6 +29,7 @@ struct Placer1Cfg : public Settings
Placer1Cfg(Context *ctx);
float constraintWeight;
int minBelsForGridPick;
bool budgetBased;
};
extern bool placer1(Context *ctx, Placer1Cfg cfg);