From a9ef4b3ff1d137324be4b97b2402fcb86e03efa8 Mon Sep 17 00:00:00 2001 From: Luca Colagrande Date: Wed, 17 Dec 2025 00:08:49 +0100 Subject: [PATCH] Fix nested struct within parameter port list (#6818) (#6824) --- src/V3LinkParse.cpp | 8 +++++--- test_regress/t/t_param_type5.v | 23 +++++++++++++++++------ 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index 24330dacd..e748ddcab 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -583,16 +583,18 @@ class LinkParseVisitor final : public VNVisitor { UINFO(9, "Reused impltypedef " << nodep << " --> " << defp); } else { // Definition must be inserted right after the variable (etc) that needed it - // AstVar, AstTypedef, AstNodeFTask are common containers + // AstVar, AstTypedef, AstNodeFTask, AstParamTypeDType are common containers AstNode* backp = nodep->backp(); for (; backp; backp = backp->backp()) { - if (VN_IS(backp, Var) || VN_IS(backp, Typedef) || VN_IS(backp, NodeFTask)) break; + if (VN_IS(backp, Var) || VN_IS(backp, Typedef) || VN_IS(backp, NodeFTask) + || VN_IS(backp, ParamTypeDType)) + break; } UASSERT_OBJ(backp, nodep, "Implicit enum/struct type created under unexpected node type"); AstNodeDType* const dtypep = nodep->childDTypep(); dtypep->unlinkFrBack(); - if (VN_IS(backp, Typedef)) { + if (VN_IS(backp, Typedef) || VN_IS(backp, ParamTypeDType)) { // A typedef doesn't need us to make yet another level of typedefing // For typedefs just remove the AstRefDType level of abstraction nodep->replaceWith(dtypep); diff --git a/test_regress/t/t_param_type5.v b/test_regress/t/t_param_type5.v index cd73625c7..3744262e4 100644 --- a/test_regress/t/t_param_type5.v +++ b/test_regress/t/t_param_type5.v @@ -7,20 +7,31 @@ class ParamClass #(string P = "ABC", R = "GDF"); endclass -module t #(parameter int A = 0, B = 1, C = 2, type D = int, E = string); - parameter bit F = 1'b0, G = 1'b1; - parameter type H = int, I = string; +module t #( + parameter int A = 0, B = 1, C = 2, type D = int, E = string, F = + struct packed { + struct packed { + logic a; + } b; + } +); + parameter bit G = 1'b0, H = 1'b1; + parameter type I = int, J = string; E str1 = "abc"; - I str2 = ""; + J str2 = ""; + + F struct1; + assign struct1.b.a = 1'b1; + initial begin automatic ParamClass param_class = new; if ($typename(B) != "int") $stop; if ($typename(C) != "int") $stop; if (str1.len() != 3) $stop; - if ($typename(G) != "bit") $stop; + if ($typename(H) != "bit") $stop; if (str2.len() != 0) $stop; if ($typename(param_class.R) != "string") $stop; - + if ($typename(struct1.b.a) != "MEMBERDTYPE 'a'") $stop; $write("*-* All Finished *-*\n"); $finish; end