diff --git a/passes/cmds/splitnetlist.cc b/passes/cmds/splitnetlist.cc index e5db7b5c2..cd51ae250 100644 --- a/passes/cmds/splitnetlist.cc +++ b/passes/cmds/splitnetlist.cc @@ -76,6 +76,16 @@ void sigCellDrivers(RTLIL::Design *design, dict sig2CellsInFanin[actual] = newSet; } newSet->insert(cell); + for (int i = 0; i < actual.size(); i++) { + SigSpec bit_sig = actual.extract(i, 1); + if (sig2CellsInFanin.count(bit_sig)) { + newSet = sig2CellsInFanin[bit_sig]; + } else { + newSet = new std::set; + sig2CellsInFanin[bit_sig] = newSet; + } + newSet->insert(cell); + } } } } @@ -92,38 +102,20 @@ void lhs2rhs(RTLIL::Design *design, dict &lhsSig continue; } if (!lhs.is_chunk()) { - if (lhs.chunks().size() != rhs.chunks().size()) { - auto rit = rhs.chunks().rbegin(); - long unsigned rhsSize = 0; - while (rit != rhs.chunks().rend()) { - RTLIL::SigSpec sub_rhs = *rit; - if (sub_rhs.is_fully_const()) { - rhsSize += (sub_rhs.as_chunk()).width; - } else { - rhsSize++; - } - rit++; - } - if (lhs.chunks().size() != rhsSize) { - continue; - } + // If lhs is not a chunk (leaf) ie: assign {a,b} = ..., then bitblast both lhs and rhs + std::vector lhsBits; + for (int i = 0; i < lhs.size(); i++) { + SigSpec bit_sig = lhs.extract(i, 1); + lhsBits.push_back(bit_sig); } - auto lit = lhs.chunks().rbegin(); - auto rit = rhs.chunks().rbegin(); - while (rit != rhs.chunks().rend()) { - RTLIL::SigSpec sub_lhs = *lit; - RTLIL::SigSpec sub_rhs = *rit; - if (sub_rhs.is_fully_const()) { - int constSize = (sub_rhs.as_chunk()).width; - while (constSize--) { - lit++; - } - rit++; - continue; - } - lhsSig2rhsSig[sub_lhs] = sub_rhs; - lit++; - rit++; + std::vector rhsBits; + for (int i = 0; i < rhs.size(); i++) { + SigSpec bit_sig = rhs.extract(i, 1); + rhsBits.push_back(bit_sig); + } + for (uint32_t i = 0; i < lhsBits.size(); i++) { + if (i < rhsBits.size()) + lhsSig2rhsSig[lhsBits[i]] = rhsBits[i]; } } else { lhsSig2rhsSig[lhs] = rhs; @@ -172,7 +164,29 @@ struct SplitNetlist : public ScriptPass { if (!wire->port_output) continue; std::string output_port_name = wire->name.c_str(); - std::string_view po_prefix = rtrim_until(std::string_view(output_port_name), '_'); + if (output_port_name.empty()) + continue; + // We want to truncate the final __ part of the string + // Example: "add_Y_0_" + // Result: "add_Y" + std::string::iterator end = output_port_name.end()-1; + if ((*end) == '_') { + // Last character is an _, it is a bit blasted index + end--; + for (; end != output_port_name.begin(); end--) { + if ((*end) != '_') { + // Truncate until the next _ + continue; + } else { + // Truncate the _ + break; + } + } + } + std::string no_bitblast_prefix; + std::copy(output_port_name.begin(), end, std::back_inserter(no_bitblast_prefix)); + // We then truncate the port name, Result: "add" + std::string_view po_prefix = rtrim_until(std::string_view(no_bitblast_prefix), '_'); std::set visitedCells; std::set visitedSigSpec; RTLIL::SigSpec actual = wire;