diff options
author | Clifford Wolf <clifford@clifford.at> | 2019-06-05 10:26:48 +0200 |
---|---|---|
committer | Clifford Wolf <clifford@clifford.at> | 2019-06-05 10:26:48 +0200 |
commit | b33176dafb03589952d3ac425e7cd8eeec61ea6a (patch) | |
tree | 9d77b9a76640efc212009c082f42e07c9b741248 /passes | |
parent | 6cc60ffd67784fa74e3ccbf9c2c273ad610e14b2 (diff) | |
download | yosys-b33176dafb03589952d3ac425e7cd8eeec61ea6a.tar.gz yosys-b33176dafb03589952d3ac425e7cd8eeec61ea6a.tar.bz2 yosys-b33176dafb03589952d3ac425e7cd8eeec61ea6a.zip |
Major rewrite of wire selection in setundef -init
Signed-off-by: Clifford Wolf <clifford@clifford.at>
Diffstat (limited to 'passes')
-rw-r--r-- | passes/cmds/setundef.cc | 119 |
1 files changed, 89 insertions, 30 deletions
diff --git a/passes/cmds/setundef.cc b/passes/cmds/setundef.cc index e46d0a1dc..3eedc86b8 100644 --- a/passes/cmds/setundef.cc +++ b/passes/cmds/setundef.cc @@ -393,53 +393,112 @@ struct SetundefPass : public Pass { ffbits.insert(bit); } - for (auto wire : module->wires()) + auto process_initwires = [&]() { - if (!wire->attributes.count("\\init")) - continue; + dict<Wire*, int> wire_weights; - for (auto bit : sigmap(wire)) - ffbits.erase(bit); + for (auto wire : initwires) + { + 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++) { - pool<SigBit> ffbitsToErase; - for (auto wire : module->wires()) + // prioritize wires that already have an init attribute + if (!ffbits.empty()) { - if (wire->name[0] == (wire_types ? '\\' : '$')) { - next_wire: - continue; - } + for (auto wire : module->wires()) + { + if (wire->name[0] == (wire_types ? '\\' : '$')) + continue; - for (auto bit : sigmap(wire)) - if (!ffbits.count(bit)) { - goto next_wire; + 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 (auto bit : sigmap(wire)) { - ffbitsToErase.insert(bit); + for (int i = 0; i < GetSize(wire); i++) + if (initval[i] != State::Sx) + ffbits.erase(sigmap(SigBit(wire, i))); + + initwires.insert(wire); } - initwires.insert(wire); + process_initwires(); } - for (const auto & bit : ffbitsToErase) { - ffbits.erase(bit); + + // 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; + } + + process_initwires(); } - } - for (auto wire : initwires) - { - Const &initval = wire->attributes["\\init"]; + // finally use whatever wire we can find. + 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); + } - 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(); + process_initwires(); + } } + + log_assert(ffbits.empty()); } module->rewrite_sigspecs(worker); |