Add back error/warning for combinational loops

This commit is contained in:
rowanG077 2023-06-23 14:14:12 +02:00 committed by myrtle
parent d2a489d5e9
commit 240f89081f
2 changed files with 15 additions and 9 deletions

View File

@ -206,8 +206,10 @@ void TimingAnalyser::topo_sort()
}
}
}
bool ignore_loops = bool_or_default(ctx->settings, ctx->id("timing/ignoreLoops"), false);
bool no_loops = topo.sort();
if (!no_loops && verbose_mode) {
if (!no_loops && !ignore_loops) {
log_info("Found %d combinational loops:\n", int(topo.loops.size()));
int i = 0;
for (auto &loop : topo.loops) {
@ -217,6 +219,11 @@ void TimingAnalyser::topo_sort()
ctx->nameOf(port_info(port).net));
}
}
if (ctx->force)
log_warning("Timing analysis failed due to combinational loops.\n");
else
log_error("Timing analysis failed due to combinational loops.\n");
}
have_loops = !no_loops;
std::swap(topological_order, topo.sorted);
@ -661,9 +668,6 @@ dict<domain_id_t, delay_t> TimingAnalyser::max_delay_by_domain_pairs()
auto dp = domain_pair_id(launch, capture);
auto l = domains.at(launch);
auto c = domains.at(capture);
delay_t delay = arr.second.value.maxDelay() - req.second.value.minDelay();
if (!domain_delay.count(dp) || domain_delay.at(dp) < delay)
domain_delay[dp] = delay;
@ -814,6 +818,7 @@ CriticalPath TimingAnalyser::build_critical_path_report(domain_id_t domain_pair,
}
}
pool<std::pair<IdString, IdString>> visited;
std::vector<PortRef> crit_path_rev;
auto cursor = endpoint;
@ -824,9 +829,13 @@ CriticalPath TimingAnalyser::build_critical_path_report(domain_id_t domain_pair,
int port_clocks;
auto portClass = ctx->getPortTimingClass(cell, port.name, port_clocks);
if (portClass != TMG_CLOCK_INPUT && portClass != TMG_IGNORE && port.type == PortType::PORT_IN) {
// combinational loop
if (!visited.insert(std::make_pair(cell->name, port.name)).second)
break;
if (portClass != TMG_CLOCK_INPUT && portClass != TMG_IGNORE && port.type == PortType::PORT_IN)
crit_path_rev.emplace_back(PortRef{cell, port.name});
}
if (!ports.at(cursor).arrival.count(dp.key.launch))
break;
@ -1023,8 +1032,6 @@ void TimingAnalyser::build_slack_histogram_report()
for (auto &arr : pd.arrival) {
auto &launch = domains.at(arr.first).key;
// @gatecat: old timing analysis includes async path
// The slack doesn't make much sense so I filter it out.
if (launch.clock != capture.clock || launch.is_async())
continue;

View File

@ -99,7 +99,6 @@ struct TimingAnalyser
TimingResult &get_timing_result() { return result; }
bool setup_only = false;
bool verbose_mode = false;
bool have_loops = false;
bool updated_domains = false;