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.
This commit is contained in:
Marcelina Kościelnicka 2021-08-21 23:36:00 +02:00
parent 21e710eb55
commit 62d41d4639
2 changed files with 26 additions and 2 deletions

View File

@ -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;

View File

@ -169,7 +169,7 @@ sub s2(.i(i[1]), .o(w[1]));
assign o = oe ? w : 2'bz;
endmodule
module c(input i, oe, (* init=2'b00 *) inout io, output o1, o2);
module c(input i, oe, (* init=1'b0 *) inout io, output o1, o2);
assign io = oe ? i : 1'bz;
assign {o1,o2} = {io,io};
endmodule
@ -182,5 +182,5 @@ select -assert-count 1 a/c:s %co a/a:init=1'b1 %i
select -assert-count 1 a/a:init
select -assert-count 1 b/c:s* %co %a b/a:init=2'b1x %i
select -assert-count 1 b/a:init
select -assert-count 1 c/t:iobuf %co c/a:init=2'b00 %i
select -assert-count 1 c/t:iobuf %co c/a:init=1'b0 %i
select -assert-count 1 c/a:init