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()("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()("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()("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()("pack-only", "pack design only without placement or routing");
|
||||||
|
|
||||||
general.add_options()("ignore-loops", "ignore combinational loops in timing analysis");
|
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>());
|
settings->set("placer1/constraintWeight", vm["cstrweight"].as<float>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vm.count("placer-budgets")) {
|
||||||
|
settings->set("placer1/budgetBased", true);
|
||||||
|
}
|
||||||
if (vm.count("freq")) {
|
if (vm.count("freq")) {
|
||||||
auto freq = vm["freq"].as<double>();
|
auto freq = vm["freq"].as<double>();
|
||||||
if (freq > 0)
|
if (freq > 0)
|
||||||
|
@ -45,8 +45,7 @@
|
|||||||
namespace std {
|
namespace std {
|
||||||
template <> struct hash<std::pair<NEXTPNR_NAMESPACE_PREFIX IdString, std::size_t>>
|
template <> struct hash<std::pair<NEXTPNR_NAMESPACE_PREFIX IdString, std::size_t>>
|
||||||
{
|
{
|
||||||
std::size_t
|
std::size_t operator()(const std::pair<NEXTPNR_NAMESPACE_PREFIX IdString, std::size_t> &idp) const noexcept
|
||||||
operator()(const std::pair<NEXTPNR_NAMESPACE_PREFIX IdString, std::size_t> &idp) const noexcept
|
|
||||||
{
|
{
|
||||||
std::size_t seed = 0;
|
std::size_t seed = 0;
|
||||||
boost::hash_combine(seed, hash<NEXTPNR_NAMESPACE_PREFIX IdString>()(idp.first));
|
boost::hash_combine(seed, hash<NEXTPNR_NAMESPACE_PREFIX IdString>()(idp.first));
|
||||||
@ -54,7 +53,7 @@ namespace std {
|
|||||||
return seed;
|
return seed;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
} // namespace std
|
||||||
|
|
||||||
NEXTPNR_NAMESPACE_BEGIN
|
NEXTPNR_NAMESPACE_BEGIN
|
||||||
|
|
||||||
@ -175,7 +174,7 @@ class SAPlacer
|
|||||||
if ((placed_cells - constr_placed_cells) % 500 != 0)
|
if ((placed_cells - constr_placed_cells) % 500 != 0)
|
||||||
log_info(" initial placement placed %d/%d cells\n", int(placed_cells - constr_placed_cells),
|
log_info(" initial placement placed %d/%d cells\n", int(placed_cells - constr_placed_cells),
|
||||||
int(autoplaced.size()));
|
int(autoplaced.size()));
|
||||||
if (ctx->slack_redist_iter > 0)
|
if (cfg.budgetBased && ctx->slack_redist_iter > 0)
|
||||||
assign_budget(ctx);
|
assign_budget(ctx);
|
||||||
ctx->yield();
|
ctx->yield();
|
||||||
auto iplace_end = std::chrono::high_resolution_clock::now();
|
auto iplace_end = std::chrono::high_resolution_clock::now();
|
||||||
@ -184,6 +183,7 @@ class SAPlacer
|
|||||||
log_info("Running simulated annealing placer.\n");
|
log_info("Running simulated annealing placer.\n");
|
||||||
|
|
||||||
// Invoke timing analysis to obtain criticalities
|
// Invoke timing analysis to obtain criticalities
|
||||||
|
if (!cfg.budgetBased)
|
||||||
get_criticalities(ctx, &net_crit);
|
get_criticalities(ctx, &net_crit);
|
||||||
|
|
||||||
// Calculate costs after initial placement
|
// Calculate costs after initial placement
|
||||||
@ -280,15 +280,16 @@ class SAPlacer
|
|||||||
ctx->shuffle(autoplaced);
|
ctx->shuffle(autoplaced);
|
||||||
|
|
||||||
// Legalisation is a big change so force a slack redistribution here
|
// 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 */);
|
assign_budget(ctx, true /* quiet */);
|
||||||
}
|
}
|
||||||
require_legal = false;
|
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 */);
|
assign_budget(ctx, true /* quiet */);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoke timing analysis to obtain criticalities
|
// Invoke timing analysis to obtain criticalities
|
||||||
|
if (!cfg.budgetBased)
|
||||||
get_criticalities(ctx, &net_crit);
|
get_criticalities(ctx, &net_crit);
|
||||||
// Need to rebuild costs after criticalities change
|
// Need to rebuild costs after criticalities change
|
||||||
setup_costs();
|
setup_costs();
|
||||||
@ -518,12 +519,17 @@ class SAPlacer
|
|||||||
return 0;
|
return 0;
|
||||||
if (ctx->getPortTimingClass(net->driver.cell, net->driver.port, cc) == TMG_IGNORE)
|
if (ctx->getPortTimingClass(net->driver.cell, net->driver.port, cc) == TMG_IGNORE)
|
||||||
return 0;
|
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);
|
auto crit = net_crit.find(net->name);
|
||||||
if (crit == net_crit.end() || crit->second.criticality.empty())
|
if (crit == net_crit.end() || crit->second.criticality.empty())
|
||||||
return 0;
|
return 0;
|
||||||
double delay = ctx->getDelayNS(ctx->predictDelay(net, net->users.at(user)));
|
double delay = ctx->getDelayNS(ctx->predictDelay(net, net->users.at(user)));
|
||||||
return delay * std::pow(crit->second.criticality.at(user), crit_exp);
|
return delay * std::pow(crit->second.criticality.at(user), crit_exp);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set up the cost maps
|
// Set up the cost maps
|
||||||
void setup_costs()
|
void setup_costs()
|
||||||
@ -690,6 +696,7 @@ Placer1Cfg::Placer1Cfg(Context *ctx) : Settings(ctx)
|
|||||||
{
|
{
|
||||||
constraintWeight = get<float>("placer1/constraintWeight", 10);
|
constraintWeight = get<float>("placer1/constraintWeight", 10);
|
||||||
minBelsForGridPick = get<int>("placer1/minBelsForGridPick", 64);
|
minBelsForGridPick = get<int>("placer1/minBelsForGridPick", 64);
|
||||||
|
budgetBased = get<bool>("placer1/budgetBased", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool placer1(Context *ctx, Placer1Cfg cfg)
|
bool placer1(Context *ctx, Placer1Cfg cfg)
|
||||||
|
@ -29,6 +29,7 @@ struct Placer1Cfg : public Settings
|
|||||||
Placer1Cfg(Context *ctx);
|
Placer1Cfg(Context *ctx);
|
||||||
float constraintWeight;
|
float constraintWeight;
|
||||||
int minBelsForGridPick;
|
int minBelsForGridPick;
|
||||||
|
bool budgetBased;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern bool placer1(Context *ctx, Placer1Cfg cfg);
|
extern bool placer1(Context *ctx, Placer1Cfg cfg);
|
||||||
|
Loading…
Reference in New Issue
Block a user