Merge pull request #151 from Silimate/reg-rename

[ENG-1913] Significant reg_rename speedup
This commit is contained in:
Akash Levy 2026-04-16 16:27:13 -07:00 committed by GitHub
commit a19dfc535c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 57 additions and 35 deletions

View File

@ -21,7 +21,6 @@
#include "kernel/fstdata.h" #include "kernel/fstdata.h"
#include "kernel/yosys.h" #include "kernel/yosys.h"
#include "passes/silimate/reg_rename.h" #include "passes/silimate/reg_rename.h"
#include <regex>
USING_YOSYS_NAMESPACE USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN PRIVATE_NAMESPACE_BEGIN
@ -64,9 +63,17 @@ struct RegRenameInstance {
if (debug) if (debug)
log("Processing registers in scope: %s (module: %s)\n", log("Processing registers in scope: %s (module: %s)\n",
vcd_scope.c_str(), log_id(module->name)); vcd_scope.c_str(), log_id(module->name));
else
log("Processing registers in %s\n",
log_id(module->name));
// Map of old bits to new bits of a renamed reg wire
dict<SigBit, SigBit> bit_map;
pool<Wire *> wiresToRemove; // Caches of target wires and wires to remove
dict<IdString, Wire*> targetWireCache;
pool<Wire *> wireRemoveCache;
// Loop through all cells in the module // Loop through all cells in the module
for (auto cell : module->cells()) { for (auto cell : module->cells()) {
@ -112,56 +119,71 @@ struct RegRenameInstance {
std::string regName = RTLIL::unescape_id(wireName); std::string regName = RTLIL::unescape_id(wireName);
int wireWidth = vcd_reg_widths[{vcd_scope, regName}]; int wireWidth = vcd_reg_widths[{vcd_scope, regName}];
if (wireWidth == 0) { if (wireWidth == 0) {
if (debug) log_warning("Unable to find matching register %s in VCD for cell %s in scope %s\n",
log("Register '%s' not found in VCD scope '%s' (cell: %s)\n", regName.c_str(), cellName.c_str(), vcd_scope.c_str());
regName.c_str(), vcd_scope.c_str(), cellName.c_str());
continue; continue;
} }
// Validate bit index // Validate bit index
if (bitIndex >= wireWidth) { if (bitIndex >= wireWidth) {
log_warning("Bit index %d exceeds wire width %d for '%s'\n", log_warning("Bit index %d exceeds wire width %d for '%s'\n",
bitIndex, wireWidth, wireName.c_str()); bitIndex, wireWidth, wireName.c_str());
continue; continue;
} }
IdString wireId = RTLIL::escape_id(wireName); IdString wireId = RTLIL::escape_id(wireName);
// Single-bit wire requires only simple renaming // Find or create the target wire of the correct VCD-derived width
if (wireWidth == 1 && bitIndex == 0) { Wire *targetWire = nullptr;
if (oldWire->name != wireId && !module->wire(wireId)) {
if (debug) // Check if the target wire was already created
log("Renaming %s to %s\n", log_id(oldWire), wireName.c_str()); auto cache_it = targetWireCache.find(wireId);
module->rename(oldWire, wireId); if (cache_it != targetWireCache.end()) {
} targetWire = cache_it->second;
continue; } else {
// If the cache misses, create the target wire
targetWire = module->wire(wireId);
if (!targetWire) {
if (debug)
log("Creating wire %s[%d:0] in scope %s\n",
wireName.c_str(), wireWidth - 1, vcd_scope.c_str());
targetWire = module->addWire(wireId, wireWidth);
}
targetWireCache[wireId] = targetWire;
} }
// Multi-bit wire requires creating a new wire and rewiring connections // Skip self-mapping (e.g. oldWire is already the target wire)
Wire *targetWire = module->wire(wireId); if (targetWire == oldWire)
continue;
if (!targetWire) {
if (debug)
log("Creating wire %s[%d:0] in scope %s\n",
wireName.c_str(), wireWidth - 1, vcd_scope.c_str());
targetWire = module->addWire(wireId, wireWidth);
}
if (debug) if (debug)
log("Connecting %s to %s[%d]\n", log("Connecting %s to %s[%d]\n",
log_id(oldWire), wireName.c_str(), bitIndex); log_id(oldWire), wireName.c_str(), bitIndex);
auto rewriter = [&](SigSpec &sig) { // Record the mapping for each bit of the old wire to the target wire
sig.replace(SigBit(oldWire), SigSpec(targetWire, bitIndex, 1)); for (int i = 0; i < GetSize(oldWire); i++)
}; bit_map[SigBit(oldWire, i)] = SigBit(targetWire, bitIndex + i);
module->rewrite_sigspecs(rewriter);
wireRemoveCache.insert(oldWire);
wiresToRemove.insert(oldWire);
} }
} }
} }
// Apply all bit-level rewrites in a single pass over the module.
if (!bit_map.empty()) {
auto rewriter = [&](SigSpec &sig) {
for (int i = 0; i < GetSize(sig); i++) {
auto it = bit_map.find(sig[i]);
if (it != bit_map.end())
sig.replace(i, SigSpec(it->second));
}
};
module->rewrite_sigspecs(rewriter);
}
// Delete the old unused wires // Delete the old unused wires
module->remove(wiresToRemove); module->remove(wireRemoveCache);
} }
void process_all(dict<std::pair<std::string, std::string>, int> &vcd_reg_widths) void process_all(dict<std::pair<std::string, std::string>, int> &vcd_reg_widths)