diff options
author | Eddie Hung <e.hung@imperial.ac.uk> | 2018-07-25 18:21:39 -0700 |
---|---|---|
committer | Eddie Hung <e.hung@imperial.ac.uk> | 2018-07-25 18:21:39 -0700 |
commit | 760a47779aca8aabbc11b4a769e987a1ce42ad0c (patch) | |
tree | 06aa1a8bb02876854ddfa8aa2d182bb2a5c06222 /common/timing.cc | |
parent | a21cc4dd5bbbf1c9e5894d8c30a2c3252d21dfd0 (diff) | |
download | nextpnr-760a47779aca8aabbc11b4a769e987a1ce42ad0c.tar.gz nextpnr-760a47779aca8aabbc11b4a769e987a1ce42ad0c.tar.bz2 nextpnr-760a47779aca8aabbc11b4a769e987a1ce42ad0c.zip |
Add compute_fmax() with refactoring, plus print out Fmax estimate post-place and post-route
Diffstat (limited to 'common/timing.cc')
-rw-r--r-- | common/timing.cc | 76 |
1 files changed, 40 insertions, 36 deletions
diff --git a/common/timing.cc b/common/timing.cc index 2c467961..784952f8 100644 --- a/common/timing.cc +++ b/common/timing.cc @@ -76,40 +76,51 @@ static delay_t follow_net(Context *ctx, NetInfo *net, int path_length, delay_t s return net_budget; } -void assign_budget(Context *ctx) +static UpdateMap compute_min_slack(Context *ctx, delay_t &min_slack) { UpdateMap updates; - delay_t min_slack = delay_t(1.0e12 / ctx->target_freq); - - log_break(); - log_info("Annotating ports with timing budgets\n"); - // Clear delays to a very high value first delay_t default_slack = delay_t(1.0e12 / ctx->target_freq); - for (auto &net : ctx->nets) { - for (auto &usr : net.second->users) { - usr.budget = default_slack; - } - } - min_slack = default_slack; - // Go through all clocked drivers and set up paths + + // Go through all clocked drivers and distribute the available path + // slack evenly into the budget of every sink on the path --- + // record this value into the UpdateMap for (auto &cell : ctx->cells) { for (auto port : cell.second->ports) { if (port.second.type == PORT_OUT) { IdString clock_domain = ctx->getPortClock(cell.second.get(), port.first); if (clock_domain != IdString()) { - delay_t slack = delay_t(1.0e12 / ctx->target_freq); // TODO: clock constraints + delay_t slack = default_slack; // TODO: clock constraints delay_t clkToQ; if (ctx->getCellDelay(cell.second.get(), clock_domain, port.first, clkToQ)) slack -= clkToQ; - if (port.second.net) { - log_break(); + if (port.second.net) follow_net(ctx, port.second.net, 0, slack, updates, min_slack); - } } } } } + return updates; +} + +void assign_budget(Context *ctx) +{ + + log_break(); + log_info("Annotating ports with timing budgets\n"); + // Clear delays to a very high value first + delay_t default_slack = delay_t(1.0e12 / ctx->target_freq); + for (auto &net : ctx->nets) { + for (auto &usr : net.second->users) { + usr.budget = default_slack; + } + } + + delay_t min_slack = default_slack; + auto updates = compute_min_slack(ctx, min_slack); + + // If user has not specified a frequency, adjust the target frequency + // to be equivalent to the critical path if (!ctx->user_freq) { ctx->target_freq = 1e12 / (default_slack - min_slack); if (ctx->verbose) @@ -145,27 +156,12 @@ void assign_budget(Context *ctx) void update_budget(Context *ctx) { - UpdateMap updates; delay_t default_slack = delay_t(1.0e12 / ctx->target_freq); - delay_t min_slack = delay_t(1.0e12 / ctx->target_freq); - - // Go through all clocked drivers and distribute the available path slack evenly into every budget - for (auto &cell : ctx->cells) { - for (auto& port : cell.second->ports) { - if (port.second.type == PORT_OUT) { - IdString clock_domain = ctx->getPortClock(cell.second.get(), port.first); - if (clock_domain != IdString()) { - delay_t slack = default_slack; // TODO: clock constraints - delay_t clkToQ; - if (ctx->getCellDelay(cell.second.get(), clock_domain, port.first, clkToQ)) - slack -= clkToQ; - if (port.second.net) - follow_net(ctx, port.second.net, 0, slack, updates, min_slack); - } - } - } - } + delay_t min_slack = default_slack; + auto updates = compute_min_slack(ctx, min_slack); + // If user has not specified a frequency, adjust the target frequency + // to be +5% higher than the current critical path if (!ctx->user_freq) { ctx->target_freq = 1.05 * (1e12 / (default_slack - min_slack)); if (ctx->verbose) @@ -199,4 +195,12 @@ void update_budget(Context *ctx) } } +float compute_fmax(Context *ctx) +{ + delay_t default_slack = delay_t(1.0e12 / ctx->target_freq); + delay_t min_slack = default_slack; + compute_min_slack(ctx, min_slack); + return 1e12 / (default_slack - min_slack); +} + NEXTPNR_NAMESPACE_END |