3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-07-01 13:08:54 +00:00

setundef: strip init attributes from undriven wires (fixes #5835)

When `setundef -undriven` connects an undriven wire to a replacement
value, the wire's \\init attribute (if present) is now removed. Previously,
the init attribute was left intact, causing downstream passes like
opt_merge to report "Conflicting init values" errors because the init
value contradicted the newly assigned constant.

For wires that are entirely undriven, the init attribute is removed
completely. For partially undriven wires (where only some bits are
undriven), only the corresponding init bits are cleared to x.

Wires driven by flip-flops or other cells are not affected, as they
are excluded from the undriven signal set before this code runs.
This commit is contained in:
junyao 2026-05-31 00:18:49 +08:00
parent e56c6a954c
commit 46f9f887f7
2 changed files with 83 additions and 0 deletions

View file

@ -355,6 +355,28 @@ struct SetundefPass : public Pass {
bits.append(worker.next_bit());
module->connect(RTLIL::SigSig(c, bits));
}
// Remove init attributes from undriven wires to prevent
// conflicts with the values we just assigned (issue #5835).
for (auto &c : sig.chunks()) {
if (c.wire && c.wire->attributes.count(ID::init)) {
if (c.wire->width == c.width && c.offset == 0) {
c.wire->attributes.erase(ID::init);
log("Removing init attribute from undriven wire %s.\n", log_id(c.wire));
} else {
Const &initval = c.wire->attributes[ID::init];
initval.resize(GetSize(c.wire), State::Sx);
for (int i = c.offset; i < c.offset + c.width; i++)
initval.set(i, State::Sx);
if (initval.is_fully_undef()) {
c.wire->attributes.erase(ID::init);
log("Removing init attribute from undriven wire %s.\n", log_id(c.wire));
} else {
log("Clearing init attribute bits [%d:%d] from partially undriven wire %s.\n",
c.offset + c.width - 1, c.offset, log_id(c.wire));
}
}
}
}
}
}