8000 Allow methodcall and new to access interface arrays by nbstrike · Pull Request #5973 · verilator/verilator · GitHub
[go: up one dir, main page]

Skip to content

Allow methodcall and new to access interface arrays #5973

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
May 30, 2025
Prev Previous commit
Next Next commit
Move V3Inst to handle AstArraySel as a visitor.
  • Loading branch information
nbstrike committed May 10, 2025
commit 0f6378e3003d5a54122f4c66274f3e599aeb6714
87 changes: 30 additions & 57 deletions src/V3Inst.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -466,60 +466,33 @@ class InstDeVisitor final : public VNVisitor {
VL_DO_DANGLING(pushDeletep(nodep), nodep);
}
}

void visit(AstArg* nodep) override {
if (AstArraySel* const arrselp = VN_CAST(nodep->exprp(), ArraySel)) {
// handle single element selection from RHS array
if (const AstUnpackArrayDType* const arrp
= VN_CAST(arrselp->fromp()->dtypep()->skipRefp(), UnpackArrayDType)) {
if (!VN_IS(arrp->subDTypep()->skipRefp(), IfaceRefDType)) return;
if (VN_AS(arrp->subDTypep()->skipRefp(), IfaceRefDType)->isVirtual()) return;
V3Const::constifyParamsEdit(arrselp->bitp());
const AstConst* const constp = VN_CAST(arrselp->bitp(), Const);
if (!constp) {
arrselp->bitp()->v3warn(E_UNSUPPORTED,
"Non-constant index in RHS interface array selection");
return;
}
const string index = AstNode::encodeNumber(constp->toSInt());
const AstVarRef* const varrefp = VN_CAST(arrselp->fromp(), VarRef);
UASSERT_OBJ(varrefp, arrselp, "No interface varref under array");
AstVarXRef* const newp = new AstVarXRef{
nodep->fileline(), varrefp->name() + "__BRA__" + index + "__KET__", "",
VAccess::READ};
newp->dtypep(arrp->subDTypep());
newp->classOrPackagep(varrefp->classOrPackagep());
arrselp->addNextHere(newp);
VL_DO_DANGLING(arrselp->unlinkFrBack()->deleteTree(), arrselp);
void visit(AstArraySel* nodep) override {
if (const AstUnpackArrayDType* const arrp
= VN_CAST(nodep->fromp()->dtypep()->skipRefp(), UnpackArrayDType)) {
if (!VN_IS(arrp->subDTypep()->skipRefp(), IfaceRefDType)) return;
if (VN_AS(arrp->subDTypep()->skipRefp(), IfaceRefDType)->isVirtual()) return;
V3Const::constifyParamsEdit(nodep->bitp());
const AstConst* const constp = VN_CAST(nodep->bitp(), Const);
if (!constp) {
nodep->bitp()->v3warn(E_UNSUPPORTED,
"Non-constant index in RHS interface array selection");
return;
}
const string index = AstNode::encodeNumber(constp->toSInt());
const AstVarRef* const varrefp = VN_CAST(nodep->fromp(), VarRef);
UASSERT_OBJ(varrefp, nodep, "No interface varref under array");
AstVarXRef* const newp = new AstVarXRef{
nodep->fileline(), varrefp->name() + "__BRA__" + index + "__KET__", "",
VAccess::READ};
newp->dtypep(arrp->subDTypep());
newp->classOrPackagep(varrefp->classOrPackagep());
nodep->addNextHere(newp);
VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
}
}

void visit(AstNodeAssign* nodep) override {
if (AstArraySel* const arrselp = VN_CAST(nodep->rhsp(), ArraySel)) {
// handle single element selection from RHS array
if (const AstUnpackArrayDType* const arrp
= VN_CAST(arrselp->fromp()->dtypep()->skipRefp(), UnpackArrayDType)) {
if (!VN_IS(arrp->subDTypep()->skipRefp(), IfaceRefDType)) return;
if (VN_AS(arrp->subDTypep()->skipRefp(), IfaceRefDType)->isVirtual()) return;
V3Const::constifyParamsEdit(arrselp->bitp());
const AstConst* const constp = VN_CAST(arrselp->bitp(), Const);
if (!constp) {
arrselp->bitp()->v3warn(E_UNSUPPORTED,
"Non-constant index in RHS interface array selection");
return;
}
const string index = AstNode::encodeNumber(constp->toSInt());
const AstVarRef* const varrefp = VN_CAST(arrselp->fromp(), VarRef);
UASSERT_OBJ(varrefp, arrselp, "No interface varref under array");
AstVarXRef* const newp = new AstVarXRef{
nodep->fileline(), varrefp->name() + "__BRA__" + index + "__KET__", "",
VAccess::READ};
newp->dtypep(arrp->subDTypep());
newp->classOrPackagep(varrefp->classOrPackagep());
arrselp->addNextHere(newp);
VL_DO_DANGLING(arrselp->unlinkFrBack()->deleteTree(), arrselp);
}
iterateChildren(nodep);
} else if (AstSliceSel* const arrslicep = VN_CAST(nodep->rhsp(), SliceSel)) {
if (const AstUnpackArrayDType* const arrp
= VN_CAST(arrslicep->fromp()->dtypep(), UnpackArrayDType)) {
Expand Down Expand Up @@ -547,23 +520,21 @@ class InstDeVisitor final : public VNVisitor {
"Array size mismatch in interface assignment");
return;
}
for (int i = 0; i < lhsarrp->elementsConst(); ++i) {
for (uint32_t i = 0; i < lhsarrp->elementsConst(); ++i) {
const string index = AstNode::encodeNumber(i);
AstNodeExpr* lhsp = nullptr;
if (AstVarRef* const varrefp = VN_CAST(nodep->lhsp(), VarRef)) {
AstVarRef* const newvarp = varrefp->cloneTree(false);
AstArraySel* newarrselp = new AstArraySel(
AstArraySel* newarrselp = new AstArraySel{
nodep->fileline(), newvarp,
new AstConst(nodep->fileline(),
V3Number(nodep->fileline(), 32, i)));
new AstConst{nodep->fileline(), i}};
lhsp = newarrselp;
} else if (AstMemberSel* const prevselp
= VN_CAST(nodep->lhsp(), MemberSel)) {
AstMemberSel* membselp = prevselp->cloneTree(false);
AstArraySel* newarrselp = new AstArraySel(
AstArraySel* newarrselp = new AstArraySel{
nodep->fileline(), membselp,
new AstConst(nodep->fileline(),
V3Number(nodep->fileline(), 32, i)));
new AstConst{nodep->fileline(), i}};
lhsp = newarrselp;
} else {
nodep->v3warn(E_UNSUPPORTED,
Expand All @@ -579,7 +550,8 @@ class InstDeVisitor final : public VNVisitor {
AstAssign* const assignp = new AstAssign(nodep->fileline(), lhsp, rhsp);
nodep->addNextHere(assignp);
}
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
// VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
}
} else {
iterateChildren(nodep);
Expand All @@ -592,6 +564,7 @@ class InstDeVisitor final : public VNVisitor {
void visit(AstNode* nodep) override { iterateChildren(nodep); }
void visit(AstNew* nodep) override { iterateChildren(nodep); }
void visit(AstMethodCall* nodep) override { iterateChildren(nodep); }
void visit(AstArg* nodep) override { iterateChildren(nodep); }

public:
// CONSTRUCTORS
Expand Down
Loading
0