From e681e0f14cc4ed65891f35b042a59eaee483669f Mon Sep 17 00:00:00 2001 From: gatecat Date: Wed, 3 Mar 2021 10:39:03 +0000 Subject: [PATCH] timing: Slack and criticality computation Signed-off-by: gatecat --- common/timing.cc | 40 ++++++++++++++++++++++++++++++++++++++++ common/timing.h | 7 +++++++ 2 files changed, 47 insertions(+) diff --git a/common/timing.cc b/common/timing.cc index 69927841..2a143854 100644 --- a/common/timing.cc +++ b/common/timing.cc @@ -40,6 +40,8 @@ void TimingAnalyser::setup() reset_times(); walk_forward(); walk_backward(); + compute_slack(); + compute_criticality(); print_fmax(); } @@ -266,6 +268,7 @@ void TimingAnalyser::reset_times() dp.second.criticality = 0; dp.second.budget = 0; } + port.second.worst_crit = 0; } } @@ -417,6 +420,43 @@ void TimingAnalyser::print_fmax() } } +void TimingAnalyser::compute_slack() +{ + for (auto &dp : domain_pairs) { + dp.worst_setup_slack = std::numeric_limits::max(); + dp.worst_hold_slack = std::numeric_limits::max(); + } + for (auto p : topological_order) { + auto &pd = ports.at(p); + for (auto &pdp : pd.domain_pairs) { + auto &dp = domain_pairs.at(pdp.first); + auto &arr = pd.arrival.at(dp.key.launch); + auto &req = pd.required.at(dp.key.capture); + pdp.second.setup_slack = dp.period.minDelay() - (arr.value.maxDelay() - req.value.minDelay()); + if (!setup_only) + pdp.second.hold_slack = arr.value.minDelay() - req.value.maxDelay(); + pdp.second.max_path_length = arr.path_length + req.path_length; + dp.worst_setup_slack = std::min(dp.worst_setup_slack, pdp.second.setup_slack); + if (!setup_only) + dp.worst_hold_slack = std::min(dp.worst_hold_slack, pdp.second.hold_slack); + } + } +} + +void TimingAnalyser::compute_criticality() +{ + for (auto p : topological_order) { + auto &pd = ports.at(p); + for (auto &pdp : pd.domain_pairs) { + auto &dp = domain_pairs.at(pdp.first); + pdp.second.criticality = + 1.0f - (float(pdp.second.setup_slack) - float(dp.worst_setup_slack)) / float(-dp.worst_setup_slack); + NPNR_ASSERT(pdp.second.criticality >= -0.00001f && pdp.second.criticality <= 1.00001f); + pd.worst_crit = std::max(pd.worst_crit, pdp.second.criticality); + } + } +} + domain_id_t TimingAnalyser::domain_id(IdString cell, IdString clock_port, ClockEdge edge) { return domain_id(ctx->cells.at(cell)->ports.at(clock_port).net, edge); diff --git a/common/timing.h b/common/timing.h index 1205cba5..18f21f15 100644 --- a/common/timing.h +++ b/common/timing.h @@ -141,6 +141,9 @@ struct TimingAnalyser void walk_forward(); void walk_backward(); + void compute_slack(); + void compute_criticality(); + void print_fmax(); const DelayPair init_delay{std::numeric_limits::max(), std::numeric_limits::lowest()}; @@ -207,6 +210,8 @@ struct TimingAnalyser std::vector cell_arcs; // routing delay into this port (input ports only) DelayPair route_delay; + // worst criticality across domain pairs + float worst_crit; }; struct PerDomain @@ -221,6 +226,8 @@ struct TimingAnalyser { PerDomainPair(ClockDomainPairKey key) : key(key){}; ClockDomainPairKey key; + DelayPair period; + delay_t worst_setup_slack, worst_hold_slack; }; CellInfo *cell_info(const CellPortKey &key);