aboutsummaryrefslogtreecommitdiffstats
path: root/passes
diff options
context:
space:
mode:
authorMarcelina Koƛcielnicka <mwk@0x04.net>2021-08-21 23:36:00 +0200
committerMarcelina Koƛcielnicka <mwk@0x04.net>2021-08-22 15:38:29 +0200
commit62d41d46397a93d1efa2b8282203d192b256d824 (patch)
tree88af5c8c56f947d484faf12f55e48f7102242ff9 /passes
parent21e710eb556d14d1cdfe4a3387a1dbe3e05ca04c (diff)
downloadyosys-62d41d46397a93d1efa2b8282203d192b256d824.tar.gz
yosys-62d41d46397a93d1efa2b8282203d192b256d824.tar.bz2
yosys-62d41d46397a93d1efa2b8282203d192b256d824.zip
opt_clean: Make the init attribute follow the FF's Q.
Previously, opt_clean would reconnect all ports (including FF Q ports) to a "canonical" SigBit chosen by complex rules, but would leave the init attribute on the old wire. This change applies the same canonicalization rules to the init attributes, ensuring that init moves to wherever the Q port moved. Part of another jab at #2920.
Diffstat (limited to 'passes')
-rw-r--r--passes/opt/opt_clean.cc24
1 files changed, 24 insertions, 0 deletions
diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc
index 08e9d6b79..cb2c261c4 100644
--- a/passes/opt/opt_clean.cc
+++ b/passes/opt/opt_clean.cc
@@ -339,6 +339,7 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos
used_signals_nodrivers.add(it2.second);
}
}
+ dict<RTLIL::SigBit, RTLIL::State> init_bits;
for (auto &it : module->wires_) {
RTLIL::Wire *wire = it.second;
if (wire->port_id > 0) {
@@ -354,6 +355,29 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos
assign_map.apply(sig);
used_signals.add(sig);
}
+ auto it2 = wire->attributes.find(ID::init);
+ if (it2 != wire->attributes.end()) {
+ RTLIL::Const &val = it2->second;
+ SigSpec sig = assign_map(wire);
+ for (int i = 0; i < GetSize(val) && i < GetSize(sig); i++)
+ if (val.bits[i] != State::Sx)
+ init_bits[sig[i]] = val.bits[i];
+ wire->attributes.erase(it2);
+ }
+ }
+
+ for (auto wire : module->wires()) {
+ bool found = false;
+ Const val(State::Sx, wire->width);
+ for (int i = 0; i < wire->width; i++) {
+ auto it = init_bits.find(RTLIL::SigBit(wire, i));
+ if (it != init_bits.end()) {
+ val.bits[i] = it->second;
+ found = true;
+ }
+ }
+ if (found)
+ wire->attributes[ID::init] = val;
}
pool<RTLIL::Wire*> del_wires_queue;