ffinit: Fortify the code a bit.

This fixes handling of messy cases involving repeatedly setting and
removing the same init bit.
This commit is contained in:
Marcelina Kościelnicka 2020-07-28 02:11:29 +02:00
parent 45e96d5d87
commit 773b056ffb
1 changed files with 19 additions and 24 deletions

View File

@ -83,22 +83,24 @@ struct FfInitVals
void set_init(RTLIL::SigBit bit, RTLIL::State val) void set_init(RTLIL::SigBit bit, RTLIL::State val)
{ {
bit = (*sigmap)(bit); SigBit mbit = (*sigmap)(bit);
auto it = initbits.find(bit); SigBit abit = bit;
if (it != initbits.end()) { auto it = initbits.find(mbit);
auto it2 = it->second.second.wire->attributes.find(ID::init); if (it != initbits.end())
it2->second[it->second.second.offset] = val; abit = it->second.second;
} else { else if (val == State::Sx)
log_assert(bit.wire); return;
initbits[bit] = std::make_pair(val,bit); log_assert(abit.wire);
auto it2 = bit.wire->attributes.find(ID::init); initbits[mbit] = std::make_pair(val,abit);
if (it2 != bit.wire->attributes.end()) { auto it2 = abit.wire->attributes.find(ID::init);
it2->second[bit.offset] = val; if (it2 != abit.wire->attributes.end()) {
} else { it2->second[abit.offset] = val;
Const cval(State::Sx, GetSize(bit.wire)); if (it2->second.is_fully_undef())
cval[bit.offset] = val; abit.wire->attributes.erase(it2);
bit.wire->attributes[ID::init] = cval; } else if (val != State::Sx) {
} Const cval(State::Sx, GetSize(abit.wire));
cval[abit.offset] = val;
abit.wire->attributes[ID::init] = cval;
} }
} }
@ -111,14 +113,7 @@ struct FfInitVals
void remove_init(RTLIL::SigBit bit) void remove_init(RTLIL::SigBit bit)
{ {
auto it = initbits.find((*sigmap)(bit)); set_init(bit, State::Sx);
if (it != initbits.end()) {
auto it2 = it->second.second.wire->attributes.find(ID::init);
it2->second[it->second.second.offset] = State::Sx;
if (it2->second.is_fully_undef())
it->second.second.wire->attributes.erase(it2);
initbits.erase(it);
}
} }
void remove_init(const RTLIL::SigSpec &sig) void remove_init(const RTLIL::SigSpec &sig)