From 6af1b5b19c279c09319f3fa8c094df89c06e9f7e Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Thu, 29 Jan 2026 18:47:12 +0000 Subject: [PATCH] Don't treat ABC 'Error:' output as indicating a fatal error, since these messages aren't necessarily fatal --- passes/techmap/abc.cc | 58 +++++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/passes/techmap/abc.cc b/passes/techmap/abc.cc index e73be611a..ae0f3e053 100644 --- a/passes/techmap/abc.cc +++ b/passes/techmap/abc.cc @@ -1127,9 +1127,34 @@ void AbcModuleState::prepare_module(RTLIL::Design *design, RTLIL::Module *module handle_loops(assign_map, module); } +static bool is_abc_prompt(const std::string &line, std::string &rest) { + size_t pos = 0; + while (true) { + // The prompt may not start at the start of the line, because + // ABC can output progress and maybe other data that isn't + // newline-terminated. + size_t start = line.find("abc ", pos); + if (start == std::string::npos) + return false; + pos = start + 4; + + size_t digits = 0; + while (pos + digits < line.size() && line[pos + digits] >= '0' && line[pos + digits] <= '9') + ++digits; + if (digits < 2) + return false; + if (line.substr(pos + digits, 2) == "> ") { + rest = line.substr(pos + digits + 2); + return true; + } + } +} + bool read_until_abc_done(abc_output_filter &filt, int fd, DeferredLogs &logs) { std::string line; char buf[1024]; + bool seen_source_cmd = false; + bool seen_yosys_abc_done = false; while (true) { int ret = read(fd, buf, sizeof(buf) - 1); if (ret < 0) { @@ -1144,23 +1169,30 @@ bool read_until_abc_done(abc_output_filter &filt, int fd, DeferredLogs &logs) { char *end = buf + ret; while (start < end) { char *p = static_cast(memchr(start, '\n', end - start)); - if (p == nullptr) { - break; + char *upto = p == nullptr ? end : p + 1; + line.append(start, upto - start); + start = upto; + + std::string rest; + bool is_prompt = is_abc_prompt(line, rest); + if (is_prompt && seen_source_cmd) { + // This is the first prompt after we sourced the script. + // We are done here. + // We won't have seen a newline yet since ABC is waiting at the prompt. + if (!seen_yosys_abc_done) + logs.log_error("ABC script did not complete successfully\n"); + return seen_yosys_abc_done; } - line.append(start, p + 1 - start); - if (line.substr(0, 14) == "YOSYS_ABC_DONE") { - // Ignore any leftover output, there should only be a prompt perhaps - return true; - } - // If ABC aborted the sourced script, it returns to the prompt and will - // never print YOSYS_ABC_DONE. Treat this as a failed run, not a hang. - if (line.substr(0, 7) == "Error: ") { - logs.log_error("ABC: %s", line.c_str()); - return false; + if (line.empty() || line[line.size() - 1] != '\n') { + // No newline yet, wait for more text + continue; } filt.next_line(line); + if (is_prompt && rest.substr(0, 7) == "source ") + seen_source_cmd = true; + if (line.substr(0, 14) == "YOSYS_ABC_DONE") + seen_yosys_abc_done = true; line.clear(); - start = p + 1; } line.append(start, end - start); }