mirror of
https://github.com/verilator/verilator.git
synced 2026-08-30 01:38:21 +02:00
Fix MULTIDRIVEN in generates (#7709)
This commit is contained in:
+26
-29
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user