placer1: Make budget-based placement an option
Signed-off-by: David Shah <davey1576@gmail.com>
This commit is contained in:
parent
a218c27305
commit
0d80181c5e
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -29,6 +29,7 @@ struct Placer1Cfg : public Settings
|
||||
Placer1Cfg(Context *ctx);
|
||||
float constraintWeight;
|
||||
int minBelsForGridPick;
|
||||
bool budgetBased;
|
||||
};
|
||||
|
||||
extern bool placer1(Context *ctx, Placer1Cfg cfg);
|
||||
|
Loading…
Reference in New Issue
Block a user