Fix MULTIDRIVEN in generates (#7709)

This commit is contained in:
Todd Strader
2026-06-03 19:50:56 -04:00
committed by GitHub
parent 72db0b575e
commit 7bd41bfbb9
5 changed files with 79 additions and 32 deletions
+26 -29
View File
@@ -9948,7 +9948,7 @@ class WidthVisitor final : public VNVisitor {
}
void checkForceReleaseLhs(AstNode* nodep, AstNode* lhsp) {
// V3Force can't check as vector may have expanded, or propagated constant into index
if (AstNode* const selNodep = selectNonConstantRecurse(lhsp))
if (AstNode* const selNodep = V3Width::selectNonConstantRecurse(lhsp))
nodep->v3error((VN_IS(nodep, Release) ? "Release"s : "Force"s)
+ " left-hand-side must not have variable bit/part select "
"(IEEE 1800-2023 10.6.2)\n"
@@ -9956,34 +9956,6 @@ class WidthVisitor final : public VNVisitor {
<< selNodep->warnOther() << "... Location of non-constant index\n"
<< selNodep->warnContextSecondary());
}
AstNode* selectNonConstantRecurse(AstNode* nodep, bool inSel = false) {
// If node has a non-constant select, return that select
AstNode* resultp = nullptr;
if (AstNodeSel* const anodep = VN_CAST(nodep, NodeSel)) {
resultp = selectNonConstantRecurse(anodep->fromp(), inSel);
if (resultp) return resultp;
resultp = selectNonConstantRecurse(anodep->bitp(), true);
} else if (AstSel* const anodep = VN_CAST(nodep, Sel)) {
resultp = selectNonConstantRecurse(anodep->fromp(), inSel);
if (resultp) return resultp;
resultp = selectNonConstantRecurse(anodep->lsbp(), true);
} else if (AstNodeVarRef* const anodep = VN_CAST(nodep, NodeVarRef)) {
if (inSel && !anodep->varp()->isParam() && !anodep->varp()->isGenVar()) return anodep;
} else {
if (AstNode* const refp = nodep->op1p())
resultp = selectNonConstantRecurse(refp, inSel);
if (resultp) return resultp;
if (AstNode* const refp = nodep->op2p())
resultp = selectNonConstantRecurse(refp, inSel);
if (resultp) return resultp;
if (AstNode* const refp = nodep->op3p())
resultp = selectNonConstantRecurse(refp, inSel);
if (resultp) return resultp;
if (AstNode* const refp = nodep->op4p())
resultp = selectNonConstantRecurse(refp, inSel);
}
return resultp;
}
//----------------------------------------------------------------------
// METHODS - special type detection
@@ -10139,3 +10111,28 @@ AstNode* V3Width::widthGenerateParamsEdit(
// No WidthRemoveVisitor, as don't want to drop $signed etc inside gen blocks
return nodep;
}
AstNode* V3Width::selectNonConstantRecurse(AstNode* nodep, bool inSel) {
// If node has a non-constant select, return that select
AstNode* resultp = nullptr;
if (AstNodeSel* const anodep = VN_CAST(nodep, NodeSel)) {
resultp = selectNonConstantRecurse(anodep->fromp(), inSel);
if (resultp) return resultp;
resultp = selectNonConstantRecurse(anodep->bitp(), true);
} else if (AstSel* const anodep = VN_CAST(nodep, Sel)) {
resultp = selectNonConstantRecurse(anodep->fromp(), inSel);
if (resultp) return resultp;
resultp = selectNonConstantRecurse(anodep->lsbp(), true);
} else if (AstNodeVarRef* const anodep = VN_CAST(nodep, NodeVarRef)) {
if (inSel && !anodep->varp()->isParam() && !anodep->varp()->isGenVar()) return anodep;
} else {
if (AstNode* const refp = nodep->op1p()) resultp = selectNonConstantRecurse(refp, inSel);
if (resultp) return resultp;
if (AstNode* const refp = nodep->op2p()) resultp = selectNonConstantRecurse(refp, inSel);
if (resultp) return resultp;
if (AstNode* const refp = nodep->op3p()) resultp = selectNonConstantRecurse(refp, inSel);
if (resultp) return resultp;
if (AstNode* const refp = nodep->op4p()) resultp = selectNonConstantRecurse(refp, inSel);
}
return resultp;
}