aboutsummaryrefslogtreecommitdiffstats
path: root/common/timing.cc
diff options
context:
space:
mode:
authorgatecat <gatecat@ds0.me>2021-03-03 10:39:03 +0000
committergatecat <gatecat@ds0.me>2021-03-04 10:29:36 +0000
commite681e0f14cc4ed65891f35b042a59eaee483669f (patch)
tree282931061c4d9fb30b27e896679ab90c5d2268e4 /common/timing.cc
parent296e6d10c21b22b5cf553136d11a7af241eb9679 (diff)
downloadnextpnr-e681e0f14cc4ed65891f35b042a59eaee483669f.tar.gz
nextpnr-e681e0f14cc4ed65891f35b042a59eaee483669f.tar.bz2
nextpnr-e681e0f14cc4ed65891f35b042a59eaee483669f.zip
timing: Slack and criticality computation
Signed-off-by: gatecat <gatecat@ds0.me>
Diffstat (limited to 'common/timing.cc')
-rw-r--r--common/timing.cc40
1 files changed, 40 insertions, 0 deletions
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<delay_t>::max();
+ dp.worst_hold_slack = std::numeric_limits<delay_t>::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);