From 072d76fe8efc630c49b1ae0ee96b7fc731602b09 Mon Sep 17 00:00:00 2001 From: Ryszard Rozak Date: Tue, 7 Feb 2023 15:10:19 +0100 Subject: [PATCH] Use VAR_BASE as attr type if a select's base is a ref (#3943) Signed-off-by: Ryszard Rozak --- src/V3Ast.h | 6 +----- src/V3AstNodes.cpp | 2 +- src/V3LinkResolve.cpp | 27 +++------------------------ src/V3Width.cpp | 2 -- test_regress/t/t_class_param.v | 19 +++++++++++++++++++ 5 files changed, 24 insertions(+), 32 deletions(-) diff --git a/src/V3Ast.h b/src/V3Ast.h index a7a7ecd90..eb8e03d19 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -371,7 +371,6 @@ public: // DT_PUBLIC, // V3LinkParse moves to AstTypedef::attrPublic // - ENUM_BASE, // V3LinkResolve creates for AstPreSel, V3LinkParam removes ENUM_FIRST, // V3Width processes ENUM_LAST, // V3Width processes ENUM_NUM, // V3Width processes @@ -380,8 +379,6 @@ public: ENUM_NAME, // V3Width processes ENUM_VALID, // V3Width processes // - MEMBER_BASE, // V3LinkResolve creates for AstPreSel, V3LinkParam removes - // TYPENAME, // V3Width processes // VAR_BASE, // V3LinkResolve creates for AstPreSel, V3LinkParam removes @@ -407,9 +404,8 @@ public: "DIM_BITS", "DIM_DIMENSIONS", "DIM_HIGH", "DIM_INCREMENT", "DIM_LEFT", "DIM_LOW", "DIM_RIGHT", "DIM_SIZE", "DIM_UNPK_DIMENSIONS", "DT_PUBLIC", - "ENUM_BASE", "ENUM_FIRST", "ENUM_LAST", "ENUM_NUM", + "ENUM_FIRST", "ENUM_LAST", "ENUM_NUM", "ENUM_NEXT", "ENUM_PREV", "ENUM_NAME", "ENUM_VALID", - "MEMBER_BASE", "TYPENAME", "VAR_BASE", "VAR_CLOCK_ENABLE", "VAR_FORCEABLE", "VAR_PUBLIC", "VAR_PUBLIC_FLAT", "VAR_PUBLIC_FLAT_RD", "VAR_PUBLIC_FLAT_RW", diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 1a4a07cc6..acd53aa89 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -869,7 +869,7 @@ AstNode* AstArraySel::baseFromp(AstNode* nodep, bool overMembers) { continue; } // AstNodeSelPre stashes the associated variable under an ATTROF - // of VAttrType::VAR_BASE/MEMBER_BASE so it isn't constified + // of VAttrType::VAR_BASE so it isn't constified else if (VN_IS(nodep, AttrOf)) { nodep = VN_AS(nodep, AttrOf)->fromp(); continue; diff --git a/src/V3LinkResolve.cpp b/src/V3LinkResolve.cpp index 6eb2a3897..bdd81ed3f 100644 --- a/src/V3LinkResolve.cpp +++ b/src/V3LinkResolve.cpp @@ -145,34 +145,13 @@ private: void visit(AstNodePreSel* nodep) override { if (!nodep->attrp()) { iterateChildren(nodep); - // Constification may change the fromp() to a constant, which will lose the - // variable we're extracting from (to determine MSB/LSB/endianness/etc.) - // So we replicate it in another node - // Note that V3Param knows not to replace AstVarRef's under AstAttrOf's AstNode* const basefromp = AstArraySel::baseFromp(nodep, false); - if (AstNodeVarRef* const varrefp - = VN_CAST(basefromp, NodeVarRef)) { // Maybe varxref - so need to clone - nodep->attrp(new AstAttrOf{nodep->fileline(), VAttrType::VAR_BASE, - varrefp->cloneTree(false)}); - } else if (AstUnlinkedRef* const uvxrp - = VN_CAST(basefromp, UnlinkedRef)) { // Maybe unlinked - so need to clone - nodep->attrp(new AstAttrOf{nodep->fileline(), VAttrType::VAR_BASE, - uvxrp->cloneTree(false)}); - } else if (auto* const fromp = VN_CAST(basefromp, LambdaArgRef)) { - nodep->attrp(new AstAttrOf{nodep->fileline(), VAttrType::VAR_BASE, - fromp->cloneTree(false)}); - } else if (AstMemberSel* const fromp = VN_CAST(basefromp, MemberSel)) { - nodep->attrp(new AstAttrOf{nodep->fileline(), VAttrType::MEMBER_BASE, - fromp->cloneTree(false)}); - } else if (AstEnumItemRef* const fromp = VN_CAST(basefromp, EnumItemRef)) { - nodep->attrp(new AstAttrOf{nodep->fileline(), VAttrType::ENUM_BASE, - fromp->cloneTree(false)}); - } else if (VN_IS(basefromp, Replicate)) { + if (VN_IS(basefromp, Replicate)) { // From {...}[...] syntax in IEEE 2017 if (basefromp) UINFO(1, " Related node: " << basefromp << endl); } else { - if (basefromp) UINFO(1, " Related node: " << basefromp << endl); - nodep->v3fatalSrc("Illegal bit select; no signal/member being extracted from"); + nodep->attrp(new AstAttrOf{nodep->fileline(), VAttrType::VAR_BASE, + basefromp->cloneTree(false)}); } } } diff --git a/src/V3Width.cpp b/src/V3Width.cpp index c1f617621..b672e8a80 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -1452,8 +1452,6 @@ private: // Don't iterate children, don't want to lose VarRef. switch (nodep->attrType()) { case VAttrType::VAR_BASE: - case VAttrType::MEMBER_BASE: - case VAttrType::ENUM_BASE: // Soon to be handled in V3LinkWidth SEL generation, under attrp() and newSubLsbOf break; case VAttrType::DIM_DIMENSIONS: diff --git a/test_regress/t/t_class_param.v b/test_regress/t/t_class_param.v index 5b9b2a451..7ebf1550b 100644 --- a/test_regress/t/t_class_param.v +++ b/test_regress/t/t_class_param.v @@ -90,6 +90,20 @@ class ClsWithParamField; endfunction endclass +class DictWrapper; + int m_dict[string]; +endclass + +class DictOperator #(type T) extends T; + function void set(string s, int x); + m_dict[s] = x; + endfunction + + function int get(string s); + return m_dict[s]; + endfunction +endclass + module t (/*AUTOARG*/); Cls c12; @@ -103,6 +117,7 @@ module t (/*AUTOARG*/); SelfRefClassIntParam::self_int_t src10; IntQueue qi; ClsWithParamField cls_param_field; + DictOperator #(DictWrapper) dict_op; int arr [1:0] = '{1, 2}; initial begin c12 = new; @@ -116,6 +131,7 @@ module t (/*AUTOARG*/); src10 = new; qi = new; cls_param_field = new; + dict_op = new; if (Cls#()::PBASE != 12) $stop; if (Cls#(4)::PBASE != 4) $stop; if (Cls8_t::PBASE != 8) $stop; @@ -167,6 +183,9 @@ module t (/*AUTOARG*/); cls_param_field.m_queue = '{1, 5, 7}; if (cls_param_field.get(2) != 7) $stop; + dict_op.set("abcd", 1); + if(dict_op.get("abcd") != 1) $stop; + $write("*-* All Finished *-*\n"); $finish; end