From 06584f2e74bff6bf5a179e7f4a0dbebda7ef6caf Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Mon, 6 Aug 2018 14:14:41 -0700 Subject: [PATCH] Compute critical path report --- common/timing.cc | 51 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/common/timing.cc b/common/timing.cc index 49e8a5ef..8fe5cd49 100644 --- a/common/timing.cc +++ b/common/timing.cc @@ -145,7 +145,6 @@ struct Timing } } } - #else // First, compute the topographical order of nets to walk through // the circuit, assuming it is a _acyclic_ graph @@ -297,6 +296,8 @@ struct Timing } } + const NetInfo* crit_net = nullptr; + // Now go backwards topographically to determine the minimum path slack, // and to distribute all path slack evenly between all nets on the path for (auto net : boost::adaptors::reverse(topographical_order)) { @@ -314,7 +315,14 @@ struct Timing usr.budget = std::min(usr.budget, net_delay + budget_share); net_min_remaining_budget = std::min(net_min_remaining_budget, path_budget - budget_share); - min_slack = std::min(min_slack, path_budget); + if (path_budget < min_slack) { + min_slack = path_budget; + if (crit_path) { + crit_path->clear(); + crit_path->push_back(&usr); + crit_net = net; + } + } if (slack_histogram) { int slack_ps = ctx->getDelayNS(path_budget) * 1000; (*slack_histogram)[slack_ps]++; @@ -337,6 +345,45 @@ struct Timing } } } + + if (crit_path) { + // Walk backwards from the most critical net + while (crit_net) { + const PortInfo* crit_ipin = nullptr; + delay_t max_arrival = std::numeric_limits::min(); + + // Look at all input ports on its driving cell + for (const auto& port : crit_net->driver.cell->ports) { + if (port.second.type == PORT_IN && port.second.net) { + DelayInfo comb_delay; + bool is_path = ctx->getCellDelay(crit_net->driver.cell, port.first, crit_net->driver.port, comb_delay); + if (is_path) { + // If input port is influenced by a clock, skip + if (ctx->getPortClock(crit_net->driver.cell, port.first) != IdString()) + continue; + + // And find the fanin net with the latest arrival time + const auto net_arrival = net_data.at(port.second.net).max_arrival; + if (net_arrival > max_arrival) { + max_arrival = net_arrival; + crit_ipin = &port.second; + } + } + } + } + + if (!crit_ipin) break; + + for (auto &usr : crit_ipin->net->users) { + if (usr.cell->name == crit_net->driver.cell->name && usr.port == crit_ipin->name) { + crit_path->push_back(&usr); + break; + } + } + crit_net = crit_ipin->net; + } + std::reverse(crit_path->begin(), crit_path->end()); + } #endif return min_slack; }