mirror of
https://github.com/YosysHQ/yosys
synced 2026-07-17 04:35:44 +00:00
opt_prienc: guard ConstEval fingerprint inputs against constant/aliased bits
The round-robin detector fed sigmap(wire) signals straight into ConstEval::set() while sweeping test vectors. On real designs a candidate bus can have bits tied to constants, repeated bits, or a req/start pair that alias to the same net after sigmap. ConstEval::set() asserts (current_val[i].wire != NULL || current_val[i] == value[i]) when asked to re-pin such a bit to a conflicting value, crashing the pass (consteval.h:83) on designs like veer/picorv32/murax/raygentop under formal synthesis. Add clean_set_signals() and reject any fingerprint candidate whose set-signals contain constant bits, repeated bits, or overlap each other, in both the priority-encoder and round-robin paths. Skipping an unclean candidate only forgoes a possible rewrite; it never produces an incorrect one. Clean candidates (the intended patterns) are unaffected. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
84f4054584
commit
676ac184ed
1 changed files with 22 additions and 0 deletions
|
|
@ -243,6 +243,23 @@ struct OptPriEncWorker {
|
|||
return vs;
|
||||
}
|
||||
|
||||
// ConstEval::set() requires every (sigmap-canonical) bit it pins to be a
|
||||
// distinct free wire bit. Real designs can tie parts of a bus to constants
|
||||
// or alias nets together, so guard the fingerprint inputs: reject signals
|
||||
// containing constant or repeated bits, and (across the whole set) any
|
||||
// overlap between them. This prevents a ConstEval assertion; skipping an
|
||||
// unclean candidate only forgoes a possible rewrite, never yields a wrong
|
||||
// one.
|
||||
static bool clean_set_signals(std::initializer_list<const SigSpec*> sigs) {
|
||||
pool<SigBit> seen;
|
||||
for (const SigSpec* sp : sigs)
|
||||
for (auto bit : *sp) {
|
||||
if (bit.wire == nullptr) return false;
|
||||
if (!seen.insert(bit).second) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Run all candidate test vectors through ConstEval and try to match each of
|
||||
// the four PE variants against the recorded outputs. Returns the matched
|
||||
// variant, or NONE.
|
||||
|
|
@ -257,6 +274,9 @@ struct OptPriEncWorker {
|
|||
if (!clz_full_ok && !ctz_full_ok && !clz_short_ok && !ctz_short_ok)
|
||||
return PEVariant::NONE;
|
||||
|
||||
if (!clean_set_signals({&T_sig}))
|
||||
return PEVariant::NONE;
|
||||
|
||||
auto vs = gen_test_vectors(N);
|
||||
for (auto& v : vs) {
|
||||
ce.push();
|
||||
|
|
@ -440,6 +460,8 @@ struct OptPriEncWorker {
|
|||
int fingerprint_rr(SigSpec req_sig, SigSpec start_sig, SigSpec S_sig,
|
||||
int N, int W) {
|
||||
ConstEval ce(module);
|
||||
if (!clean_set_signals({&req_sig, &start_sig}))
|
||||
return -1;
|
||||
bool ok0 = true, ok1 = true;
|
||||
auto deck = gen_test_vectors(N);
|
||||
int checks = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue