mirror of https://github.com/YosysHQ/yosys.git
Merge pull request #151 from Silimate/reg-rename
[ENG-1913] Significant reg_rename speedup
This commit is contained in:
commit
a19dfc535c
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue