From 3cd792d4d7721e364d3b1550426e9b956070582f Mon Sep 17 00:00:00 2001 From: Stan Lee Date: Wed, 29 Apr 2026 11:24:46 -0700 Subject: [PATCH 01/10] warn only on _reg --- passes/silimate/reg_rename.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/silimate/reg_rename.cc b/passes/silimate/reg_rename.cc index b12692803..c5b6148bb 100644 --- a/passes/silimate/reg_rename.cc +++ b/passes/silimate/reg_rename.cc @@ -128,7 +128,7 @@ struct RegRenameInstance { int wireWidth = regInfo.width; int wireOffset = regInfo.offset; - if (wireWidth == 0) { + if (wireWidth == 0 && regName.find("_reg") != std::string::npos) { log_warning("Unable to find matching register %s in VCD for cell %s in scope %s\n", regName.c_str(), cellName.c_str(), vcd_scope.c_str()); continue; From 448ab2a4e76591518b768e1b6192224262727669 Mon Sep 17 00:00:00 2001 From: Stan Lee Date: Wed, 29 Apr 2026 11:30:04 -0700 Subject: [PATCH 02/10] undo --- passes/silimate/reg_rename.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/silimate/reg_rename.cc b/passes/silimate/reg_rename.cc index c5b6148bb..b12692803 100644 --- a/passes/silimate/reg_rename.cc +++ b/passes/silimate/reg_rename.cc @@ -128,7 +128,7 @@ struct RegRenameInstance { int wireWidth = regInfo.width; int wireOffset = regInfo.offset; - if (wireWidth == 0 && regName.find("_reg") != std::string::npos) { + if (wireWidth == 0) { log_warning("Unable to find matching register %s in VCD for cell %s in scope %s\n", regName.c_str(), cellName.c_str(), vcd_scope.c_str()); continue; From 550d48c4178e2002d5b9c280aeed353281dd8131 Mon Sep 17 00:00:00 2001 From: Stan Lee Date: Wed, 29 Apr 2026 15:21:29 -0700 Subject: [PATCH 03/10] fix value conversion bug --- passes/silimate/reg_rename.cc | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/passes/silimate/reg_rename.cc b/passes/silimate/reg_rename.cc index b12692803..bc254e266 100644 --- a/passes/silimate/reg_rename.cc +++ b/passes/silimate/reg_rename.cc @@ -108,11 +108,19 @@ struct RegRenameInstance { size_t last_open = cellName.rfind('['); size_t last_close = cellName.rfind(']'); if (last_open != std::string::npos && last_close != std::string::npos && last_close > last_open) { - wireName = cellName.substr(0, last_open); - bitIndex = std::stoi(cellName.substr(last_open + 1, last_close - last_open - 1)); + + // Check that bracket content is just a single bit index + std::string inner = cellName.substr(last_open + 1, last_close - last_open - 1); + if (!inner.empty() && inner.find_first_not_of("0123456789") == std::string::npos) { + wireName = cellName.substr(0, last_open); + bitIndex = std::stoi(inner); + } else { + wireName = cellName; + bitIndex = 0; + } } else { - wireName = cellName; - bitIndex = 0; + wireName = cellName; + bitIndex = 0; } // Process Q output connection for the cell @@ -301,10 +309,17 @@ struct RegRenamePass : public Pass { std::string signal_bits = ""; // Use the bracket notation to extract the bit range and construct true reg name. - size_t bit_pos = signal_name.rfind('['); - if (bit_pos != std::string::npos) { - signal_bits = signal_name.substr(bit_pos); - signal_name.erase(bit_pos); + if (!signal_name.empty() && signal_name.back() == ']') { + size_t open = signal_name.rfind('['); + if (open != std::string::npos) { + std::string inner = signal_name.substr(open + 1, + signal_name.size() - open - 2); + // Check for alphabetical characters since they can be contained in brackets in a wire name. + if (!inner.empty() && inner.find_first_not_of("0123456789:") == std::string::npos) { + signal_bits = signal_name.substr(open); + signal_name.erase(open); + } + } } // Extract the LSB and MSB indices if present. From 21a2a1b4f877bcda83b083b8d2dbd07d25881a4e Mon Sep 17 00:00:00 2001 From: Stan Lee Date: Wed, 29 Apr 2026 17:07:50 -0700 Subject: [PATCH 04/10] splitcells was the issue? --- passes/cmds/splitcells.cc | 10 +++++----- passes/silimate/reg_rename.cc | 24 +++++++----------------- 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/passes/cmds/splitcells.cc b/passes/cmds/splitcells.cc index 15279e6dd..833672b39 100644 --- a/passes/cmds/splitcells.cc +++ b/passes/cmds/splitcells.cc @@ -188,8 +188,8 @@ struct SplitcellsWorker std::string base_name = cell->name.str(); IdString slice_name; if (blast) { - // Strip existing brackets from cell name - size_t bracket_pos = base_name.find('['); + // Strip existing '[' or '.' from cell name + size_t bracket_pos = base_name.find_first_of('[.'); if (bracket_pos != std::string::npos) { base_name = base_name.substr(0, bracket_pos); } @@ -205,12 +205,12 @@ struct SplitcellsWorker // Extract bit offset from the wire (ex: 0) int bit_offset = user_index(slice_lsb); - // Concatenate wire index (ex: \Memory[0] -> [0]) to the bit offset (ex: [0][bit]) - size_t bracket_pos = wire_name.find('['); + // Concatenate struct attribute or wire index (ex: \Memory[0] -> [0]) to the bit offset + size_t bracket_pos = wire_name.find_first_of('[.'); if (bracket_pos != std::string::npos) { wire_indices = wire_name.substr(bracket_pos) + stringf( "%c%d%c", format[0], bit_offset, format[1]); - } else { // no brackets, so no concatenation using wire, use slice_lsb + name_lsb offset instead + } else { // no '[' or '.', so no concatenation using wire, use slice_lsb + name_lsb offset instead wire_indices = stringf( "%c%d%c", format[0], slice_lsb + wire_offset, format[1]); } diff --git a/passes/silimate/reg_rename.cc b/passes/silimate/reg_rename.cc index bc254e266..73f94c6df 100644 --- a/passes/silimate/reg_rename.cc +++ b/passes/silimate/reg_rename.cc @@ -108,16 +108,10 @@ struct RegRenameInstance { size_t last_open = cellName.rfind('['); size_t last_close = cellName.rfind(']'); if (last_open != std::string::npos && last_close != std::string::npos && last_close > last_open) { - - // Check that bracket content is just a single bit index - std::string inner = cellName.substr(last_open + 1, last_close - last_open - 1); - if (!inner.empty() && inner.find_first_not_of("0123456789") == std::string::npos) { - wireName = cellName.substr(0, last_open); - bitIndex = std::stoi(inner); - } else { - wireName = cellName; - bitIndex = 0; - } + // Check that bracket content is just a single bit index + std::string inner = cellName.substr(last_open + 1, last_close - last_open - 1); + wireName = cellName.substr(0, last_open); + bitIndex = std::stoi(inner); } else { wireName = cellName; bitIndex = 0; @@ -312,13 +306,9 @@ struct RegRenamePass : public Pass { if (!signal_name.empty() && signal_name.back() == ']') { size_t open = signal_name.rfind('['); if (open != std::string::npos) { - std::string inner = signal_name.substr(open + 1, - signal_name.size() - open - 2); - // Check for alphabetical characters since they can be contained in brackets in a wire name. - if (!inner.empty() && inner.find_first_not_of("0123456789:") == std::string::npos) { - signal_bits = signal_name.substr(open); - signal_name.erase(open); - } + std::string inner = signal_name.substr(open + 1, signal_name.size() - open - 2); + signal_bits = signal_name.substr(open); + signal_name.erase(open); } } From f6e6b4afef1feb9102f821ca1262ed73ab9ae55c Mon Sep 17 00:00:00 2001 From: Stan Lee Date: Wed, 29 Apr 2026 17:23:58 -0700 Subject: [PATCH 05/10] better? --- passes/cmds/splitcells.cc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/passes/cmds/splitcells.cc b/passes/cmds/splitcells.cc index 833672b39..4a65cd110 100644 --- a/passes/cmds/splitcells.cc +++ b/passes/cmds/splitcells.cc @@ -189,8 +189,16 @@ struct SplitcellsWorker IdString slice_name; if (blast) { // Strip existing '[' or '.' from cell name - size_t bracket_pos = base_name.find_first_of('[.'); + size_t bracket_pos = base_name.find_first_of("[."); + bool strip_reg = false; if (bracket_pos != std::string::npos) { + + // Check if we will strip off _reg suffix + size_t reg_pos = base_name.find("_reg"); + if (reg_pos != std::string::npos && reg_pos > bracket_pos) { + base_name = base_name.substr(0, reg_pos); + strip_reg = true; + } base_name = base_name.substr(0, bracket_pos); } @@ -206,9 +214,9 @@ struct SplitcellsWorker int bit_offset = user_index(slice_lsb); // Concatenate struct attribute or wire index (ex: \Memory[0] -> [0]) to the bit offset - size_t bracket_pos = wire_name.find_first_of('[.'); + size_t bracket_pos = wire_name.find_first_of("[."); if (bracket_pos != std::string::npos) { - wire_indices = wire_name.substr(bracket_pos) + stringf( + wire_indices = wire_name.substr(bracket_pos) + (strip_reg ? "" : "_reg") + stringf( "%c%d%c", format[0], bit_offset, format[1]); } else { // no '[' or '.', so no concatenation using wire, use slice_lsb + name_lsb offset instead wire_indices = stringf( From 4600078f559b144113422b24e030d90b62ac734c Mon Sep 17 00:00:00 2001 From: Stan Lee Date: Thu, 30 Apr 2026 10:06:29 -0700 Subject: [PATCH 06/10] comments --- passes/cmds/splitcells.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/passes/cmds/splitcells.cc b/passes/cmds/splitcells.cc index 4a65cd110..59f405f5a 100644 --- a/passes/cmds/splitcells.cc +++ b/passes/cmds/splitcells.cc @@ -193,7 +193,7 @@ struct SplitcellsWorker bool strip_reg = false; if (bracket_pos != std::string::npos) { - // Check if we will strip off _reg suffix + // Check if we will strip off _reg suffix from base name size_t reg_pos = base_name.find("_reg"); if (reg_pos != std::string::npos && reg_pos > bracket_pos) { base_name = base_name.substr(0, reg_pos); @@ -206,7 +206,7 @@ struct SplitcellsWorker std::string wire_indices; if (slice_lsb < GetSize(raw_q) && raw_q[slice_lsb].is_wire()) { - // Extract wire name (ex: \Memory[0]) + // Extract wire name (ex: \Memory[0] or \Memory.attr) Wire *w = raw_q[slice_lsb].wire; std::string wire_name = w->name.str(); From 6aab520cad998f01a966b6312d66cf4476690644 Mon Sep 17 00:00:00 2001 From: Stan Lee Date: Thu, 30 Apr 2026 10:14:42 -0700 Subject: [PATCH 07/10] simplify --- passes/silimate/reg_rename.cc | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/passes/silimate/reg_rename.cc b/passes/silimate/reg_rename.cc index 73f94c6df..6a257e84e 100644 --- a/passes/silimate/reg_rename.cc +++ b/passes/silimate/reg_rename.cc @@ -103,18 +103,17 @@ struct RegRenameInstance { cellName.erase(reg_pos, 4); // Index comes from the right-most brackets - std::string wireName; + std::string wireName = cellName; int bitIndex = 0; size_t last_open = cellName.rfind('['); size_t last_close = cellName.rfind(']'); if (last_open != std::string::npos && last_close != std::string::npos && last_close > last_open) { - // Check that bracket content is just a single bit index + // Validate bracket content is just a single bit slice std::string inner = cellName.substr(last_open + 1, last_close - last_open - 1); - wireName = cellName.substr(0, last_open); - bitIndex = std::stoi(inner); - } else { - wireName = cellName; - bitIndex = 0; + if (!inner.empty() && inner.find_first_not_of("0123456789") == std::string::npos) { + wireName = cellName.substr(0, last_open); + bitIndex = std::stoi(inner); + } } // Process Q output connection for the cell From f3c3eceedfb48813c69b74ad082a7764831ffab9 Mon Sep 17 00:00:00 2001 From: Stan Lee Date: Thu, 30 Apr 2026 10:47:23 -0700 Subject: [PATCH 08/10] bugfix --- passes/cmds/splitcells.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/passes/cmds/splitcells.cc b/passes/cmds/splitcells.cc index 59f405f5a..156ff93f5 100644 --- a/passes/cmds/splitcells.cc +++ b/passes/cmds/splitcells.cc @@ -216,7 +216,7 @@ struct SplitcellsWorker // Concatenate struct attribute or wire index (ex: \Memory[0] -> [0]) to the bit offset size_t bracket_pos = wire_name.find_first_of("[."); if (bracket_pos != std::string::npos) { - wire_indices = wire_name.substr(bracket_pos) + (strip_reg ? "" : "_reg") + stringf( + wire_indices = wire_name.substr(bracket_pos) + (strip_reg ? "_reg" : "") + stringf( "%c%d%c", format[0], bit_offset, format[1]); } else { // no '[' or '.', so no concatenation using wire, use slice_lsb + name_lsb offset instead wire_indices = stringf( From 9d9ed4bfe37e3fd9319962b3a6c7a67fd7c2c47f Mon Sep 17 00:00:00 2001 From: Stan Lee Date: Thu, 30 Apr 2026 12:05:57 -0700 Subject: [PATCH 09/10] flatten VCD/RTL scope hierarchy --- passes/silimate/reg_rename.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/passes/silimate/reg_rename.cc b/passes/silimate/reg_rename.cc index 6a257e84e..ea202b8ad 100644 --- a/passes/silimate/reg_rename.cc +++ b/passes/silimate/reg_rename.cc @@ -64,7 +64,7 @@ struct RegRenameInstance { // Processes registers in a given module hierarchy // and renames to allow for correct register annotation - void process_registers(dict, RegInfo> &vcd_reg_widths) + void process_registers(dict &vcd_reg_widths) { if (debug) log("Processing registers in scope: %s (module: %s)\n", @@ -125,7 +125,7 @@ struct RegRenameInstance { // Lookup wire information from VCD std::string regName = RTLIL::unescape_id(wireName); - RegInfo regInfo = vcd_reg_widths[{vcd_scope, regName}]; + RegInfo regInfo = vcd_reg_widths[vcd_scope + "." + regName]; int wireWidth = regInfo.width; int wireOffset = regInfo.offset; @@ -219,7 +219,7 @@ struct RegRenameInstance { module->remove(wireRemoveCache); } - void process_all(dict, RegInfo> &vcd_reg_widths) + void process_all(dict &vcd_reg_widths) { process_registers(vcd_reg_widths); for (auto &it : children) @@ -281,7 +281,7 @@ struct RegRenamePass : public Pass { log_error("No top module found!\n"); // Extract pre-optimization signal widths from VCD file - dict, RegInfo> vcd_reg_widths; + dict vcd_reg_widths; if (!vcd_filename.empty()) { log("Reading VCD file: %s\n", vcd_filename.c_str()); try { @@ -327,7 +327,7 @@ struct RegRenamePass : public Pass { // Map the register's vcd scope and name to // its original width and offset for later lookup. signal_name = RTLIL::unescape_id(signal_name); - vcd_reg_widths[{vcd_scope, signal_name}] = {width, offset}; + vcd_reg_widths[vcd_scope + "." + signal_name] = {width, offset}; if (debug) log("Found signal '%s' in scope '%s' with range [%d:%d] (width %d)\n", signal_name.c_str(), vcd_scope.c_str(), From 386d3fc3089f46506079fd5e85b952619c80e084 Mon Sep 17 00:00:00 2001 From: Stan Lee Date: Thu, 30 Apr 2026 12:30:09 -0700 Subject: [PATCH 10/10] fix --- passes/cmds/splitcells.cc | 2 +- passes/silimate/reg_rename.cc | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/passes/cmds/splitcells.cc b/passes/cmds/splitcells.cc index 156ff93f5..f63215e9c 100644 --- a/passes/cmds/splitcells.cc +++ b/passes/cmds/splitcells.cc @@ -194,7 +194,7 @@ struct SplitcellsWorker if (bracket_pos != std::string::npos) { // Check if we will strip off _reg suffix from base name - size_t reg_pos = base_name.find("_reg"); + size_t reg_pos = base_name.rfind("_reg"); if (reg_pos != std::string::npos && reg_pos > bracket_pos) { base_name = base_name.substr(0, reg_pos); strip_reg = true; diff --git a/passes/silimate/reg_rename.cc b/passes/silimate/reg_rename.cc index ea202b8ad..ff11cecc8 100644 --- a/passes/silimate/reg_rename.cc +++ b/passes/silimate/reg_rename.cc @@ -305,7 +305,6 @@ struct RegRenamePass : public Pass { if (!signal_name.empty() && signal_name.back() == ']') { size_t open = signal_name.rfind('['); if (open != std::string::npos) { - std::string inner = signal_name.substr(open + 1, signal_name.size() - open - 2); signal_bits = signal_name.substr(open); signal_name.erase(open); }