From 9cf172b7a923dac17f30aa30e2bf85294b2cfd1d Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Fri, 3 Apr 2020 14:03:27 -0700 Subject: [PATCH] sta: better handling when no timing paths and unused bits --- passes/cmds/sta.cc | 32 +++++++++++++++++++++++--------- tests/various/sta.ys | 28 ++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/passes/cmds/sta.cc b/passes/cmds/sta.cc index f1c160014..d71816fde 100644 --- a/passes/cmds/sta.cc +++ b/passes/cmds/sta.cc @@ -51,6 +51,8 @@ struct StaWorker int maxarrival; SigBit maxbit; + pool driven; + StaWorker(RTLIL::Module *module) : design(module->design), module(module), sigmap(module), maxarrival(0) { TimingInfo timing; @@ -106,6 +108,7 @@ struct StaWorker auto &d = data[bit]; d.driver = cell; d.dst_port = conn.first; + driven.insert(bit); auto it = t.arrival.find(namebit); if (it == t.arrival.end()) @@ -132,8 +135,10 @@ struct StaWorker for (auto port_name : module->ports) { auto wire = module->wire(port_name); if (wire->port_input) { - for (const auto &b : sigmap(wire)) + for (const auto &b : sigmap(wire)) { queue.emplace_back(b); + driven.insert(b); + } // All primary inputs to arrive at time zero wire->set_intvec_attribute(ID::sta_arrival, std::vector(GetSize(wire), 0)); } @@ -165,8 +170,9 @@ struct StaWorker auto &dst_arrival = dst_arrivals[dst_bit.offset]; auto new_arrival = src_arrival + std::get<1>(d); if (dst_arrival < new_arrival) { + auto dst_wire = dst_bit.wire; dst_arrival = std::max(dst_arrival, new_arrival); - dst_bit.wire->set_intvec_attribute(ID::sta_arrival, dst_arrivals); + dst_wire->set_intvec_attribute(ID::sta_arrival, dst_arrivals); queue.emplace_back(dst_bit); data[dst_bit].backtrack = b; @@ -175,7 +181,7 @@ struct StaWorker auto it = endpoints.find(dst_bit); if (it != endpoints.end()) new_arrival += it->second.required; - if (new_arrival > maxarrival) { + if (new_arrival > maxarrival && driven.count(b)) { maxarrival = new_arrival; maxbit = dst_bit; } @@ -183,14 +189,20 @@ struct StaWorker } } - log("Latest arrival time in '%s' is %d:\n", log_id(module), maxarrival); auto b = maxbit; + if (b == SigBit()) { + log("No timing paths found.\n"); + return; + } + + log("Latest arrival time in '%s' is %d:\n", log_id(module), maxarrival); auto it = endpoints.find(maxbit); if (it != endpoints.end() && it->second.sink) log(" %6d %s (%s.%s)\n", maxarrival, log_id(it->second.sink), log_id(it->second.sink->type), log_id(it->second.port)); else { log(" %6d (%s)\n", maxarrival, b.wire->port_output ? "" : ""); - log_warning("Critical-path does not terminate in a recognised endpoint.\n"); + if (!b.wire->port_output) + log_warning("Critical-path does not terminate in a recognised endpoint.\n"); } auto jt = data.find(b); while (jt != data.end()) { @@ -210,15 +222,17 @@ struct StaWorker std::map arrival_histogram; for (const auto &i : endpoints) { const auto &b = i.first; + if (!driven.count(b)) + continue; + if (!b.wire->attributes.count(ID::sta_arrival)) { - log_warning("Wire %s.%s has no (* sta_arrival *) value.\n", log_id(module), log_signal(b)); + log_warning("Endpoint %s.%s has no (* sta_arrival *) value.\n", log_id(module), log_signal(b)); continue; } + auto arrival = b.wire->get_intvec_attribute(ID::sta_arrival)[b.offset]; if (arrival < 0) { - // FIXME: Might be an unreachable signal - // Might be a constant driven signal (e.g. through OBUF) - //log_warning("Wire %s.%s has no (* sta_arrival *) value.\n", log_id(module), log_signal(b)); + log_warning("Endpoint %s.%s has no (* sta_arrival *) value.\n", log_id(module), log_signal(b)); continue; } arrival += i.second.required; diff --git a/tests/various/sta.ys b/tests/various/sta.ys index 187d11a45..3944b5e7d 100644 --- a/tests/various/sta.ys +++ b/tests/various/sta.ys @@ -13,3 +13,31 @@ EOT logger -expect warning "Critical-path does not terminate in a recognised endpoint\." 1 sta + + +design -reset +read_verilog -specify < o) = 10; +endspecify +endmodule + +module top(input i, output o, p); +buffer b(.i(i), .o(o)); +endmodule +EOT + +sta +logger -expect-no-warnings