604 int bits_full_total = 0;
605 std::vector<std::set<RTLIL::SigBit>> batches;
607 if (it.second->port_input) {
608 batches.push_back(
sigmap(it.second).to_sigbit_set());
609 bits_full_total += it.second->width;
613 std::set<RTLIL::SigBit> inputs, outputs;
614 for (
auto &port : it.second->connections()) {
615 std::vector<RTLIL::SigBit> bits =
sigmap(port.second).to_sigbit_vector();
617 outputs.insert(bits.begin(), bits.end());
619 inputs.insert(bits.begin(), bits.end());
621 std::pair<RTLIL::Cell*, std::set<RTLIL::SigBit>> drv(it.second, inputs);
622 for (
auto &bit : outputs)
624 batches.push_back(outputs);
625 bits_full_total += outputs.size();
627 if (
inv_mode && it.second->type ==
"$_NOT_")
628 inv_pairs.insert(std::pair<RTLIL::SigBit, RTLIL::SigBit>(
sigmap(it.second->getPort(
"\\A")),
sigmap(it.second->getPort(
"\\Y"))));
632 int bits_full_count = 0;
633 std::map<std::vector<RTLIL::SigBit>, std::vector<RTLIL::SigBit>> buckets;
634 for (
auto &batch : batches)
636 for (
auto &bit : batch)
638 goto found_selected_wire;
639 bits_full_count += batch.size();
643 log(
" Finding reduced input cone for signal batch %s%c\n",
647 for (
auto &bit : batch) {
648 std::vector<RTLIL::SigBit> inputs;
649 infinder.analyze(inputs, bit, 100 * bits_full_count / bits_full_total);
650 buckets[inputs].push_back(bit);
655 log(
" Sorted %d signal bits into %d buckets.\n", bits_count,
int(buckets.size()));
657 int bucket_count = 0;
658 std::vector<std::vector<equiv_bit_t>> equiv;
659 for (
auto &bucket : buckets)
663 if (bucket.second.size() == 1)
666 if (bucket.first.size() == 0) {
669 for (
size_t idx = 0;
idx < bucket.second.size();
idx++)
674 worker.
analyze(equiv, 100 * bucket_count / (buckets.size() + 1));
678 std::map<RTLIL::SigBit, int> bitusage;
684 log(
" Rewiring %d equivialent groups:\n",
int(equiv.size()));
685 int rewired_sigbits = 0;
686 for (
auto &grp : equiv)
691 for (
size_t i = 1; i < grp.size(); i++)
694 log(
" Skipping not-selected slave: %s\n",
log_signal(grp[i].bit));
698 if (grp[i].bit.wire->port_id == 0 && bitusage[grp[i].bit] <= 1) {
704 log(
" Skipping dependency of master: %s\n",
log_signal(grp[i].bit));
708 log(
" Connect slave%s: %s\n", grp[i].inverted ?
" using inverter" :
"",
log_signal(grp[i].bit));
714 sigmap(port.second).replace(grp[i].bit, dummy_wire, &port.second);
718 if (inv_sig.
size() == 0)
723 inv_cell->
setPort(
"\\A", grp[0].bit);
724 inv_cell->
setPort(
"\\Y", inv_sig);
739 log(
" Reached limit passed using -stop option. Skipping all further reductions.\n");
745 return rewired_sigbits;
bool selected(T1 *module) const
RTLIL::Wire * wire(RTLIL::IdString id)
RTLIL::Cell * addCell(RTLIL::IdString name, RTLIL::IdString type)
std::map< RTLIL::IdString, RTLIL::Wire * > wires_
void rewrite_sigspecs(T functor)
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
static std::string idx(std::string str)
void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN bool inv_mode
bool cell_known(RTLIL::IdString type)
void connect(const RTLIL::SigSig &conn)
bool cell_output(RTLIL::IdString type, RTLIL::IdString port)
RTLIL::Wire * addWire(RTLIL::IdString name, int width=1)
static const char * id2cstr(const RTLIL::IdString &str)
std::map< RTLIL::IdString, RTLIL::Cell * > cells_
void log(const char *format,...)
bool find_bit_in_cone(std::set< RTLIL::Cell * > &celldone, RTLIL::SigBit needle, RTLIL::SigBit haystack)
std::map< RTLIL::IdString, RTLIL::SigSpec > connections_
std::pair< SigSpec, SigSpec > SigSig
std::set< std::pair< RTLIL::SigBit, RTLIL::SigBit > > inv_pairs