Merge pull request #119 from Silimate/autoscope

Autoscope Improvement
This commit is contained in:
Akash Levy 2026-03-06 16:19:57 -08:00 committed by GitHub
commit 7e6f82ad4d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 22 additions and 47 deletions

View File

@ -397,40 +397,11 @@ int FstData::getWidth(fstHandle signal)
}
// Auto-discover scope from FST by finding the top module
std::string FstData::autoScope(Module *topmod) {
std::string 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<std::string> 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");
std::string scope = "";
// Map top module port name to their bit widths (RTL reference point)
dict<std::string, int> top2widths;
@ -439,7 +410,7 @@ std::string FstData::autoScope(Module *topmod) {
top2widths[RTLIL::unescape_id(wire->name)] = wire->width;
}
}
log("Extracted %d ports from top module\n", GetSize(top2widths));
log("Extracted %d ports from module '%s'\n", GetSize(top2widths), top.c_str());
// For each scope, track the number of matching ports
dict<std::string, int> scopes2matches;
@ -456,7 +427,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 +438,28 @@ 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<std::string> 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",
top.c_str());
return "";
} else {
log("Found %d scopes for module '%s':\n", GetSize(results), top.c_str());
for (const auto& scope : results) {
log(" %s\n", scope.c_str());
}
if (results.size() > 1) {
log_warning("Multiple scopes found for module '%s'. Using the first one.\n",
top.c_str());
}
return results[0];
}
// No match found
log_warning("Could not auto-discover scope for module '%s'...\n",
RTLIL::unescape_id(topmod->name).c_str());
return "";
}