diff --git a/src/V3AstNodeDType.h b/src/V3AstNodeDType.h index 41c512617..10d90c33f 100644 --- a/src/V3AstNodeDType.h +++ b/src/V3AstNodeDType.h @@ -402,10 +402,7 @@ public: ASTGEN_MEMBERS_AstBasicDType; void dump(std::ostream& str) const override; // width/widthMin/numeric compared elsewhere - bool same(const AstNode* samep) const override { - const AstBasicDType* const sp = static_cast(samep); - return m == sp->m; - } + bool same(const AstNode* samep) const override; bool similarDType(const AstNodeDType* samep) const override { return type() == samep->type() && same(samep); } diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 9f2dc67bb..a88ef0a06 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -233,6 +233,15 @@ int AstBasicDType::widthTotalBytes() const { } } +bool AstBasicDType::same(const AstNode* samep) const { + const AstBasicDType* const sp = static_cast(samep); + if (!rangep() && !sp->rangep() && m == sp->m) { + return true; + } else { + return m == sp->m && rangep() && rangep()->sameTree(sp->rangep()); + } +} + int AstNodeUOrStructDType::widthTotalBytes() const { if (width() <= 8) { return 1; diff --git a/src/V3Param.cpp b/src/V3Param.cpp index 741d102d8..b10521f90 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -342,6 +342,7 @@ class ParamProcessor final { // TODO: This parameter value number lookup via a constructed key string is not // particularly robust for type parameters. We should really have a type // equivalence predicate function. + if (const AstRefDType* const refp = VN_CAST(nodep, RefDType)) nodep = refp->skipRefp(); const string key = paramValueKey(nodep); // cppcheck-has-bug-suppress unreadVariable V3Hash hash = V3Hasher::uncachedHash(nodep); @@ -705,7 +706,7 @@ class ParamProcessor final { << modvarp->prettyNameQ()); } else { UINFO(9, "Parameter type assignment expr=" << exprp << " to " << origp << endl); - if (exprp->sameTree(origp)) { + if (exprp->similarDType(origp)) { // Setting parameter to its default value. Just ignore it. // This prevents making additional modules, and makes coverage more // obvious as it won't show up under a unique module page name. diff --git a/test_regress/t/t_class_param_type.v b/test_regress/t/t_class_param_type.v index 1501f0819..45a1b78ed 100644 --- a/test_regress/t/t_class_param_type.v +++ b/test_regress/t/t_class_param_type.v @@ -18,12 +18,32 @@ class Cls; endfunction endclass +class ParclsDefaultType #(type T=Cls); + static function int get_p; + return T::get_p(); + endfunction +endclass + typedef Cls cls_t; typedef cls_t cls2_t; module t (/*AUTOARG*/); initial begin + automatic ParclsDefaultType#(Cls) pdt1 = new; + automatic ParclsDefaultType#(cls_t) pdt2 = pdt1; + automatic ParclsDefaultType#(cls2_t) pdt3 = pdt2; + automatic Parcls#(Cls) p1 = new; + automatic Parcls#(cls_t) p2 = p1; + automatic Parcls#(cls2_t) p3 = p2; + + if (pdt1 != pdt2) $stop; + if (pdt2 != pdt3) $stop; + if (p1 != p2) $stop; + if (p2 != p3) $stop; + + if (p1.get_p() != 20) $stop; + if (pdt1.get_p() != 20) $stop; if (Parcls#(cls2_t)::get_p() != 20) $stop; $write("*-* All Finished *-*\n");