mirror of https://github.com/YosysHQ/yosys.git
Major rewrite of wire selection in setundef -init
Signed-off-by: Clifford Wolf <clifford@clifford.at>
This commit is contained in:
parent
6cc60ffd67
commit
b33176dafb
|
@ -393,53 +393,112 @@ struct SetundefPass : public Pass {
|
||||||
ffbits.insert(bit);
|
ffbits.insert(bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto wire : module->wires())
|
auto process_initwires = [&]()
|
||||||
{
|
{
|
||||||
if (!wire->attributes.count("\\init"))
|
dict<Wire*, int> wire_weights;
|
||||||
continue;
|
|
||||||
|
|
||||||
for (auto bit : sigmap(wire))
|
for (auto wire : initwires)
|
||||||
ffbits.erase(bit);
|
{
|
||||||
|
int weight = 0;
|
||||||
|
|
||||||
initwires.insert(wire);
|
for (auto bit : sigmap(wire))
|
||||||
}
|
weight += ffbits.count(bit) ? +1 : -1;
|
||||||
|
|
||||||
|
wire_weights[wire] = weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
initwires.sort([&](Wire *a, Wire *b) { return wire_weights.at(a) > wire_weights.at(b); });
|
||||||
|
|
||||||
|
for (auto wire : initwires)
|
||||||
|
{
|
||||||
|
Const &initval = wire->attributes["\\init"];
|
||||||
|
initval.bits.resize(GetSize(wire), State::Sx);
|
||||||
|
|
||||||
|
for (int i = 0; i < GetSize(wire); i++) {
|
||||||
|
SigBit bit = sigmap(SigBit(wire, i));
|
||||||
|
if (initval[i] == State::Sx && ffbits.count(bit)) {
|
||||||
|
initval[i] = worker.next_bit();
|
||||||
|
ffbits.erase(bit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (initval.is_fully_undef())
|
||||||
|
wire->attributes.erase("\\init");
|
||||||
|
}
|
||||||
|
|
||||||
|
initwires.clear();
|
||||||
|
};
|
||||||
|
|
||||||
for (int wire_types = 0; wire_types < 2; wire_types++)
|
for (int wire_types = 0; wire_types < 2; wire_types++)
|
||||||
{
|
{
|
||||||
pool<SigBit> ffbitsToErase;
|
// prioritize wires that already have an init attribute
|
||||||
for (auto wire : module->wires())
|
if (!ffbits.empty())
|
||||||
{
|
{
|
||||||
if (wire->name[0] == (wire_types ? '\\' : '$')) {
|
for (auto wire : module->wires())
|
||||||
next_wire:
|
{
|
||||||
|
if (wire->name[0] == (wire_types ? '\\' : '$'))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!wire->attributes.count("\\init"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Const &initval = wire->attributes["\\init"];
|
||||||
|
initval.bits.resize(GetSize(wire), State::Sx);
|
||||||
|
|
||||||
|
if (initval.is_fully_undef()) {
|
||||||
|
wire->attributes.erase("\\init");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < GetSize(wire); i++)
|
||||||
|
if (initval[i] != State::Sx)
|
||||||
|
ffbits.erase(sigmap(SigBit(wire, i)));
|
||||||
|
|
||||||
|
initwires.insert(wire);
|
||||||
|
}
|
||||||
|
|
||||||
|
process_initwires();
|
||||||
|
}
|
||||||
|
|
||||||
|
// next consider wires that completely contain bits to be initialized
|
||||||
|
if (!ffbits.empty())
|
||||||
|
{
|
||||||
|
for (auto wire : module->wires())
|
||||||
|
{
|
||||||
|
if (wire->name[0] == (wire_types ? '\\' : '$'))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (auto bit : sigmap(wire))
|
||||||
|
if (!ffbits.count(bit))
|
||||||
|
goto next_wire;
|
||||||
|
|
||||||
|
initwires.insert(wire);
|
||||||
|
|
||||||
|
next_wire:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto bit : sigmap(wire))
|
process_initwires();
|
||||||
if (!ffbits.count(bit)) {
|
}
|
||||||
goto next_wire;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto bit : sigmap(wire)) {
|
// finally use whatever wire we can find.
|
||||||
ffbitsToErase.insert(bit);
|
if (!ffbits.empty())
|
||||||
|
{
|
||||||
|
for (auto wire : module->wires())
|
||||||
|
{
|
||||||
|
if (wire->name[0] == (wire_types ? '\\' : '$'))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (auto bit : sigmap(wire))
|
||||||
|
if (ffbits.count(bit))
|
||||||
|
initwires.insert(wire);
|
||||||
}
|
}
|
||||||
|
|
||||||
initwires.insert(wire);
|
process_initwires();
|
||||||
}
|
|
||||||
for (const auto & bit : ffbitsToErase) {
|
|
||||||
ffbits.erase(bit);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto wire : initwires)
|
log_assert(ffbits.empty());
|
||||||
{
|
|
||||||
Const &initval = wire->attributes["\\init"];
|
|
||||||
|
|
||||||
for (int i = 0; i < GetSize(wire); i++)
|
|
||||||
if (GetSize(initval) <= i)
|
|
||||||
initval.bits.push_back(worker.next_bit());
|
|
||||||
else if (initval.bits[i] == State::Sx)
|
|
||||||
initval.bits[i] = worker.next_bit();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module->rewrite_sigspecs(worker);
|
module->rewrite_sigspecs(worker);
|
||||||
|
|
Loading…
Reference in New Issue