mirror of https://github.com/YosysHQ/yosys.git
autoscoping
This commit is contained in:
parent
0b46d8b201
commit
c459a74c13
|
|
@ -280,3 +280,77 @@ std::string FstData::valueOf(fstHandle signal)
|
|||
}
|
||||
return past_data[signal];
|
||||
}
|
||||
|
||||
// Auto-discover scope from FST by finding the top module
|
||||
std::string FstData::autoScope(Module *topmod) {
|
||||
|
||||
log("Auto-discovering scope from file...\n");
|
||||
std::string top = RTLIL::unescape_id(topmod->name);
|
||||
|
||||
// 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) {
|
||||
return var.scope.substr(0, pos + top.length());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Option 2 - Post based scope matching
|
||||
// Matches based on exact port name matching of the top module
|
||||
log("Trying port-based scope matching...\n");
|
||||
|
||||
// Map port name to their bit widths (RTL reference point)
|
||||
dict<std::string, int> ports;
|
||||
for (auto wire : topmod->wires()) {
|
||||
if (wire->port_input || wire->port_output) {
|
||||
ports[RTLIL::unescape_id(wire->name)] = wire->width;
|
||||
}
|
||||
}
|
||||
|
||||
// For each scope, track which ports were found with matching width
|
||||
// (VCD reference point)
|
||||
dict<std::string, std::set<std::string>> scope_found_ports;
|
||||
for (const auto& var : vars) {
|
||||
|
||||
// Strip array '[]' notation from variable name
|
||||
std::string var_name = var.name;
|
||||
size_t bracket = var_name.find('[');
|
||||
if (bracket != std::string::npos) {
|
||||
var_name = var_name.substr(0, bracket);
|
||||
}
|
||||
|
||||
// Check if this variable name matches one of our port names
|
||||
if (ports.count(var_name)) {
|
||||
// Also check if width matches
|
||||
if (ports[var_name] == var.width) {
|
||||
scope_found_ports[var.scope].insert(var_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Compare RTl and VCD references and find an exact match
|
||||
for (const auto& entry : scope_found_ports) {
|
||||
const std::string& scope = entry.first;
|
||||
const std::set<std::string>& found = entry.second;
|
||||
|
||||
// Check if all port names exist in this scope
|
||||
if (found.size() == ports.size()) {
|
||||
log("Auto-discovered scope: %s (matched all %d ports by name)\n",
|
||||
scope.c_str(), (int)ports.size());
|
||||
return scope;
|
||||
}
|
||||
}
|
||||
|
||||
// No match found
|
||||
log_warning("Could not auto-discover scope for module '%s'...\n",
|
||||
RTLIL::unescape_id(topmod->name).c_str());
|
||||
return "";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ class FstData
|
|||
dict<int,fstHandle> getMemoryHandles(std::string name);
|
||||
double getTimescale() { return timescale; }
|
||||
const char *getTimescaleString() { return timescale_str.c_str(); }
|
||||
std::string autoScope(Module *topmod);
|
||||
private:
|
||||
void extractVarNames();
|
||||
|
||||
|
|
|
|||
|
|
@ -1474,8 +1474,22 @@ struct SimWorker : SimShared
|
|||
log_assert(top == nullptr);
|
||||
fst = new FstData(sim_filename);
|
||||
timescale = fst->getTimescaleString();
|
||||
if (scope.empty())
|
||||
log_error("Scope must be defined for co-simulation.\n");
|
||||
if (scope.empty()) {
|
||||
scope = fst->autoScope(topmod);
|
||||
if (scope.empty()) {
|
||||
std::set<std::string> unique_scopes;
|
||||
for (const auto& var : fst->getVars()) {
|
||||
unique_scopes.insert(var.scope);
|
||||
}
|
||||
log_warning("Available scopes:\n");
|
||||
for (const auto& scope : unique_scopes) {
|
||||
log_warning(" %s\n", scope.c_str());
|
||||
}
|
||||
log_error("No scope found for module '%s'. Please specify -scope explicitly with above options.\n",
|
||||
RTLIL::unescape_id(topmod->name).c_str());
|
||||
}
|
||||
}
|
||||
log("Using scope: \"%s\"\n", scope.c_str());
|
||||
|
||||
top = new SimInstance(this, scope, topmod);
|
||||
register_signals();
|
||||
|
|
|
|||
|
|
@ -188,15 +188,35 @@ struct RegRenamePass : public Pass {
|
|||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
||||
// Extract top module
|
||||
Module *topmod = design->top_module();
|
||||
if (!topmod)
|
||||
log_error("No top module found!\n");
|
||||
|
||||
// Extract pre-optimization register widths from VCD file
|
||||
dict<std::pair<std::string, std::string>, int> vcd_reg_widths;
|
||||
if (!vcd_filename.empty()) {
|
||||
if (scope.empty()) {
|
||||
log_error("No scope provided. Use -scope option.\n");
|
||||
}
|
||||
log("Reading VCD file: %s\n", vcd_filename.c_str());
|
||||
try {
|
||||
FstData fst(vcd_filename);
|
||||
if (scope.empty()) {
|
||||
scope = fst.autoScope(topmod);
|
||||
if (scope.empty()) {
|
||||
log_warning("No scope found for module '%s'. Please specify -scope explicitly.\n",
|
||||
RTLIL::unescape_id(topmod->name).c_str());
|
||||
std::set<std::string> unique_scopes;
|
||||
for (const auto& var : fst.getVars()) {
|
||||
unique_scopes.insert(var.scope);
|
||||
}
|
||||
log_warning("Available scopes:\n");
|
||||
for (const auto& scope : unique_scopes) {
|
||||
log_warning(" %s\n", scope.c_str());
|
||||
}
|
||||
log_error("No scope found for module '%s'. Please specify -scope explicitly with above options.\n",
|
||||
RTLIL::unescape_id(topmod->name).c_str());
|
||||
}
|
||||
}
|
||||
log("Using scope: \"%s\"\n", scope.c_str());
|
||||
for (auto &var : fst.getVars()) {
|
||||
if (var.is_reg) {
|
||||
std::string reg_vcd_scope = var.scope;
|
||||
|
|
@ -223,9 +243,6 @@ struct RegRenamePass : public Pass {
|
|||
}
|
||||
|
||||
// STEP 2: Build hierarchy and process
|
||||
Module *topmod = design->top_module();
|
||||
if (!topmod)
|
||||
log_error("No top module found!\n");
|
||||
log("Building hierarchy from scope: %s\n", scope.c_str());
|
||||
|
||||
// Build hierarchy and process register renamings
|
||||
|
|
|
|||
Loading…
Reference in New Issue