mirror of
https://github.com/YosysHQ/yosys
synced 2026-07-17 04:35:44 +00:00
passes simple test
This commit is contained in:
parent
e678e2a0c3
commit
186fc15f8f
1 changed files with 70 additions and 9 deletions
|
|
@ -24,6 +24,17 @@
|
|||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
struct CellTracker {
|
||||
Cell *cell;
|
||||
int index;
|
||||
};
|
||||
|
||||
struct RegTracker {
|
||||
std::map<std::string, CellTracker> renamedRegs;
|
||||
std::string origRegWidth;
|
||||
Module *module;
|
||||
};
|
||||
|
||||
struct RegRenamePass : public Pass {
|
||||
RegRenamePass() : Pass("reg_rename", "renames register output wires to the correct register name") { }
|
||||
void help() override
|
||||
|
|
@ -49,7 +60,7 @@ struct RegRenamePass : public Pass {
|
|||
|
||||
// Data structure used to keep track of multi-bit registers.
|
||||
// Relevant for correct register annotation.
|
||||
|
||||
std::map<std::string, RegTracker> regTrackers;
|
||||
|
||||
// Regex to match register output wires
|
||||
// .*_reg[NUMBER] or .*_reg, can match NUMBER and part before _reg
|
||||
|
|
@ -62,23 +73,23 @@ struct RegRenamePass : public Pass {
|
|||
std::string name = cell->name.c_str();
|
||||
if (std::regex_match(name, match, reg_regex)) {
|
||||
|
||||
|
||||
std::string origRegWidth = cell->get_string_attribute("$ORIG_REG_WIDTH");
|
||||
log("Original register width for cell %s: %s\n", cell->name.c_str(), origRegWidth.c_str());
|
||||
|
||||
// baseName is the part before _reg
|
||||
std::string baseName = match[1].str();
|
||||
std::string registerName = baseName;
|
||||
if (match.size() > 2 && match[2].matched) {
|
||||
|
||||
// Check if the register is a multi-bit register
|
||||
bool isMultiBit = match.size() > 2 && match[2].matched;
|
||||
std::string indexStr;
|
||||
if (isMultiBit) {
|
||||
// indexStr is the NUMBER in .*_reg[NUMBER]
|
||||
std::string indexStr = match[2].str();
|
||||
registerName += indexStr;
|
||||
indexStr = match[2].str();
|
||||
registerName += "_" + indexStr;
|
||||
}
|
||||
|
||||
for (auto conn : cell->connections()) {
|
||||
if (conn.first == ID::Q && conn.second.is_wire()) {
|
||||
Wire *wire = conn.second.as_wire();
|
||||
|
||||
|
||||
// Skip if this wire is a module port (input/output)
|
||||
if (wire->port_input || wire->port_output) {
|
||||
log("Skipping port wire %s in register renaming for cell %s in module %s\n",
|
||||
|
|
@ -94,6 +105,15 @@ struct RegRenamePass : public Pass {
|
|||
// Rename register
|
||||
log("Renaming register wire %s to %s for cell %s in module %s\n",
|
||||
wire->name.c_str(), registerName, log_id(cell), log_id(module));
|
||||
|
||||
// Log relevant information for multi-bit registers for wire reconstruction
|
||||
if (isMultiBit) {
|
||||
std::string origRegWidth = cell->get_string_attribute("$ORIG_REG_WIDTH");
|
||||
regTrackers[baseName].origRegWidth = origRegWidth;
|
||||
regTrackers[baseName].renamedRegs[registerName] = CellTracker{cell, std::stoi(indexStr)};
|
||||
regTrackers[baseName].module = module;
|
||||
}
|
||||
|
||||
module->rename(wire, registerName);
|
||||
count++;
|
||||
}
|
||||
|
|
@ -101,6 +121,47 @@ struct RegRenamePass : public Pass {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &[baseName, regTracker] : regTrackers) {
|
||||
|
||||
// Get the module for this register
|
||||
Module *mod = regTracker.module;
|
||||
|
||||
// Create a new wire for the multi-bit register
|
||||
int width = std::stoi(regTracker.origRegWidth);
|
||||
log("Creating new wire %s for register %s with width %d\n", baseName.c_str(), baseName.c_str(), width);
|
||||
Wire *newWire = mod->addWire(baseName, width);
|
||||
|
||||
pool<Wire *> oldWires;
|
||||
|
||||
// Connect the renamed registers to the corresponding index of the new wire
|
||||
for (const auto &[renamedRegName, cellTracker] : regTracker.renamedRegs) {
|
||||
|
||||
// Get the old wire (the Q output that was renamed)
|
||||
Wire *oldWire = cellTracker.cell->getPort(ID::Q).as_wire();
|
||||
|
||||
// Get the index of the renamed register
|
||||
int index = cellTracker.index;
|
||||
log("Connecting renamed register %s to index %d\n", renamedRegName.c_str(), index);
|
||||
|
||||
// Connect the renamed register to the corresponding index of the new wire
|
||||
mod->connect(SigSpec(newWire, index, 1), cellTracker.cell->getPort(ID::Q));
|
||||
|
||||
// Replace all uses of oldWire with newWire[index] throughout the module
|
||||
auto rewriter = [&](SigSpec &sig) {
|
||||
sig.replace(SigBit(oldWire), SigSpec(newWire, index, 1));
|
||||
};
|
||||
mod->rewrite_sigspecs(rewriter);
|
||||
|
||||
// Add the old wire to the list of old wires to delete
|
||||
oldWires.insert(oldWire);
|
||||
}
|
||||
|
||||
// Delete the old wires
|
||||
mod->remove(oldWires);
|
||||
}
|
||||
|
||||
|
||||
log("Renamed %d registers in %d modules\n", count, moduleCount);
|
||||
log_flush();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue