aboutsummaryrefslogtreecommitdiffstats
path: root/common/timing.cc
diff options
context:
space:
mode:
authorDavid Shah <dave@ds0.me>2018-11-12 13:42:25 +0000
committerDavid Shah <dave@ds0.me>2018-11-12 14:03:58 +0000
commitfc5e6bec9ab8bf2c25b2b943de4013daf727dfb8 (patch)
tree1f3c4171cb20e3ec8123ceef576c383fa0034d24 /common/timing.cc
parent11579a1046640a21b79aa6a1f579d3464267d0a1 (diff)
downloadnextpnr-fc5e6bec9ab8bf2c25b2b943de4013daf727dfb8.tar.gz
nextpnr-fc5e6bec9ab8bf2c25b2b943de4013daf727dfb8.tar.bz2
nextpnr-fc5e6bec9ab8bf2c25b2b943de4013daf727dfb8.zip
timing: Add support for clock constraints
Signed-off-by: David Shah <dave@ds0.me>
Diffstat (limited to 'common/timing.cc')
-rw-r--r--common/timing.cc25
1 files changed, 22 insertions, 3 deletions
diff --git a/common/timing.cc b/common/timing.cc
index 8351b1f3..fec74312 100644
--- a/common/timing.cc
+++ b/common/timing.cc
@@ -315,13 +315,26 @@ struct Timing
const auto endpoint_arrival = net_arrival + net_delay + setup;
auto path_budget = clk_period - endpoint_arrival;
delay_t period;
-
+ // Set default period
if (edge == startdomain.first.edge) {
period = clk_period;
} else {
period = clk_period / 2;
}
-
+ if (clksig != async_clock) {
+ if (ctx->nets.at(clksig)->clkconstr) {
+ if (edge == startdomain.first.edge) {
+ // same edge
+ period = ctx->nets.at(clksig)->clkconstr->period.minDelay();
+ } else if (edge == RISING_EDGE) {
+ // falling -> rising
+ period = ctx->nets.at(clksig)->clkconstr->low.minDelay();
+ } else if (edge == FALLING_EDGE) {
+ // rising -> falling
+ period = ctx->nets.at(clksig)->clkconstr->high.minDelay();
+ }
+ }
+ }
if (update) {
auto budget_share = budget_override ? 0 : path_budget / net_length_plus_one;
usr.budget = std::min(usr.budget, net_delay + budget_share);
@@ -637,7 +650,13 @@ void timing_analysis(Context *ctx, bool print_histogram, bool print_fmax, bool p
if (print_fmax) {
log_break();
for (auto &clock : clock_reports) {
- log_info("Max frequency for clock '%s': %.02f MHz\n", clock.first.c_str(ctx), clock_fmax[clock.first]);
+ if (ctx->nets.at(clock.first)->clkconstr) {
+ float target = 1000 / ctx->getDelayNS(ctx->nets.at(clock.first)->clkconstr->period.minDelay());
+ log_info("Max frequency for clock '%s': %.02f MHz (%s at %.02f MHz)\n", clock.first.c_str(ctx),
+ clock_fmax[clock.first], (target < clock_fmax[clock.first]) ? "PASS" : "FAIL", target);
+ } else {
+ log_info("Max frequency for clock '%s': %.02f MHz\n", clock.first.c_str(ctx), clock_fmax[clock.first]);
+ }
}
log_break();