diff --git a/kernel/fstdata.cc b/kernel/fstdata.cc index 899447773..dd88590b2 100644 --- a/kernel/fstdata.cc +++ b/kernel/fstdata.cc @@ -397,41 +397,11 @@ int FstData::getWidth(fstHandle signal) } // Auto-discover scope from FST by finding the top module -std::string FstData::autoScope(Module *topmod) { +std::vector FstData::autoScope(Module *topmod) { - log("Auto-discovering scope from file...\n"); + log("Auto-discovering scopes from file...\n"); std::string top = RTLIL::unescape_id(topmod->name); - log("Available scopes:\n"); - std::set unique_scopes; - for (const auto& var : vars) { - unique_scopes.insert(var.scope); - } - for (const auto& scope : unique_scopes) { - log(" %s\n", scope.c_str()); - } - - // Option 1 - Instance based scope matching - // Will fail if the DUT instance name != the top module name - log("Trying instance-based scope matching...\n"); - for (const auto& var : vars) { - // Check if this scope ends with our top module - log_debug("Checking scope: %s\n", var.scope.c_str()); - if (var.scope == top || - var.scope.find("." + top) != std::string::npos) { - // Extract the full path up to (and including) the top module - size_t pos = var.scope.find(top); - if (pos != std::string::npos) { - std::string scope = var.scope.substr(0, pos + top.length()); - return scope; - } - } - } - - // Option 2 - Port based scope matching - // Matches based on exact port name matching of the top module - log("Trying port-based scope matching...\n"); - // Map top module port name to their bit widths (RTL reference point) dict top2widths; for (auto wire : topmod->wires()) { @@ -456,7 +426,7 @@ std::string FstData::autoScope(Module *topmod) { if (last_dot != std::string::npos) { // no '.' means no scope/signal extraction is possible std::string scope = name.substr(0, last_dot); std::string signal_name = name.substr(last_dot + 1); - + // Check that signal is in the top module and width matches if (top2widths.count(signal_name)) { int signal_width = getWidth(handle); @@ -467,24 +437,23 @@ std::string FstData::autoScope(Module *topmod) { } } - // Find scopes with exact matches - // If there is a tie, return the longest scope - std::string result = ""; + // Find scopes with exact matches and add to array + std::vector results; for (const auto& entry : scopes2matches) { int num_matches = entry.second; if (num_matches == GetSize(top2widths)) { std::string scope = entry.first; - if (result.empty() || scope.length() > result.length()) { - result = scope; - } + results.push_back(scope); } } - if (!result.empty()) { - return result; + if (results.empty()) { + log_warning("Could not auto-discover scope for module '%s'...\n", + RTLIL::unescape_id(topmod->name).c_str()); + } else { + log("Found %d scopes for module '%s':\n", GetSize(results), RTLIL::unescape_id(topmod->name).c_str()); + for (const auto& scope : results) { + log(" %s\n", scope.c_str()); + } } - - // No match found - log_warning("Could not auto-discover scope for module '%s'...\n", - RTLIL::unescape_id(topmod->name).c_str()); - return ""; + return results; } diff --git a/kernel/fstdata.h b/kernel/fstdata.h index f95806cca..01e175691 100644 --- a/kernel/fstdata.h +++ b/kernel/fstdata.h @@ -58,7 +58,7 @@ class FstData double getTimescale() { return timescale; } const char *getTimescaleString() { return timescale_str.c_str(); } int getWidth(fstHandle signal); - std::string autoScope(Module *topmod); + std::vector autoScope(Module *topmod); private: void extractVarNames(); diff --git a/passes/sat/sim.cc b/passes/sat/sim.cc index 113a15bdd..eb3f39480 100644 --- a/passes/sat/sim.cc +++ b/passes/sat/sim.cc @@ -1475,11 +1475,12 @@ struct SimWorker : SimShared fst = new FstData(sim_filename); timescale = fst->getTimescaleString(); if (scope.empty()) { - scope = fst->autoScope(topmod); - if (scope.empty()) { + scopes = fst->autoScope(topmod); + if (scopes.empty()) { log_error("No scope found for module '%s'. Please specify -scope explicitly.\n", RTLIL::unescape_id(topmod->name).c_str()); } + scope = scopes[0]; // Use the first scope found by default } log("Using scope: \"%s\"\n", scope.c_str()); diff --git a/passes/silimate/reg_rename.cc b/passes/silimate/reg_rename.cc index 5635b6869..05e5200fb 100644 --- a/passes/silimate/reg_rename.cc +++ b/passes/silimate/reg_rename.cc @@ -200,11 +200,12 @@ struct RegRenamePass : public Pass { try { FstData fst(vcd_filename); if (scope.empty()) { - scope = fst.autoScope(topmod); - if (scope.empty()) { + scopes = fst->autoScope(topmod); + if (scopes.empty()) { log_error("No scope found for module '%s'. Please specify -scope explicitly.\n", RTLIL::unescape_id(topmod->name).c_str()); } + scope = scopes[0]; // Use the first scope found by default } log("Using scope: \"%s\"\n", scope.c_str()); for (auto &var : fst.getVars()) {