From f96d336b973360d65e788d952d32ce4c07abb698 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 1 Jan 2022 12:50:43 -0500 Subject: [PATCH] Internals: Pre-elaboration progress towards class parameters. --- src/V3LinkCells.cpp | 17 ++++++++++++++- src/V3Param.cpp | 3 ++- src/verilog.y | 3 +-- test_regress/t/t_class_param.out | 31 +++++++++++++++++++++++++--- test_regress/t/t_class_unsup_bad.out | 3 --- 5 files changed, 47 insertions(+), 10 deletions(-) diff --git a/src/V3LinkCells.cpp b/src/V3LinkCells.cpp index 32322db7a..d87761387 100644 --- a/src/V3LinkCells.cpp +++ b/src/V3LinkCells.cpp @@ -123,7 +123,7 @@ private: V3GraphVertex* vertex(AstNodeModule* nodep) { // Return corresponding vertex for this module if (!nodep->user1p()) nodep->user1p(new LinkCellsVertex(&m_graph, nodep)); - return (nodep->user1u().toGraphVertex()); + return nodep->user1u().toGraphVertex(); } AstNodeModule* findModuleSym(const string& modName) { @@ -185,6 +185,9 @@ private: // Module: Pick up modnames, so we can resolve cells later VL_RESTORER(m_modp); { + // For nested modules/classes, child below parent + if (m_modp) new V3GraphEdge{&m_graph, vertex(m_modp), vertex(nodep), 1}; + // m_modp = nodep; UINFO(4, "Link Module: " << nodep << endl); if (nodep->fileline()->filebasenameNoExt() != nodep->prettyName() @@ -449,6 +452,18 @@ private: } virtual void visit(AstRefDType* nodep) override { + iterateChildren(nodep); + for (AstPin* pinp = nodep->paramsp(); pinp; pinp = VN_AS(pinp->nextp(), Pin)) { + pinp->param(true); + if (pinp->name() == "") pinp->name("__paramNumber" + cvtToStr(pinp->pinNum())); + } + } + virtual void visit(AstClassOrPackageRef* nodep) override { + iterateChildren(nodep); + // Inside a class, an extends or reference to another class + // Note we don't add a V3GraphEdge{vertex(m_modp), vertex(nodep->classOrPackagep()} + // We could for an extends, but for another reference we cannot, as + // it is legal to have classes both with parameters that link to each other for (AstPin* pinp = nodep->paramsp(); pinp; pinp = VN_AS(pinp->nextp(), Pin)) { pinp->param(true); if (pinp->name() == "") pinp->name("__paramNumber" + cvtToStr(pinp->pinNum())); diff --git a/src/V3Param.cpp b/src/V3Param.cpp index 9b0918854..e6064a6a7 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -641,10 +641,11 @@ class ParamProcessor final { longnamer += "_" + paramSmallName(srcModp, modvarp) + paramValueNumber(exprp); any_overridesr = true; } else { + V3Const::constifyParamsEdit(pinp->exprp()); AstConst* const exprp = VN_CAST(pinp->exprp(), Const); const AstConst* const origp = VN_CAST(modvarp->valuep(), Const); if (!exprp) { - // if (debug()) pinp->dumpTree(cout, "error:"); + if (debug()) pinp->dumpTree(cout, "-nodes: "); pinp->v3error("Can't convert defparam value to constant: Param " << pinp->prettyNameQ() << " of " << nodep->prettyNameQ()); pinp->exprp()->replaceWith(new AstConst( diff --git a/src/verilog.y b/src/verilog.y index 5de0e81c8..a3f850c3b 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -6225,8 +6225,7 @@ class_item: // ==IEEE: class_item | timeunits_declaration { $$ = $1; } //UNSUP covergroup_declaration { $$ = $1; } // // local_parameter_declaration under parameter_declaration - | parameter_declaration ';' - { $$ = $1; BBUNSUP($2, "Unsupported: class parameters"); } // 1800-2009 + | parameter_declaration ';' { $$ = $1; } | ';' { $$ = nullptr; } // | error ';' { $$ = nullptr; } diff --git a/test_regress/t/t_class_param.out b/test_regress/t/t_class_param.out index e232809d9..f1badbdd8 100644 --- a/test_regress/t/t_class_param.out +++ b/test_regress/t/t_class_param.out @@ -1,5 +1,30 @@ -%Error-UNSUPPORTED: t/t_class_param.v:18:30: Unsupported: class parameters - 18 | localparam P = PMINUS1 + 1; - | ^ +%Error-UNSUPPORTED: t/t_class_param.v:32:11: Unsupported: parameterized classes + : ... In instance t + 32 | Cls #(.P(4)) c4; + | ^ ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error-UNSUPPORTED: t/t_class_param.v:34:12: Unsupported: parameterized classes + : ... In instance t + 34 | Wrap #(.PMINUS1(15)) w16; + | ^~~~~~~ +%Error-UNSUPPORTED: t/t_class_param.v:7:23: Unsupported: class parameters + : ... In instance t + 7 | class Cls #(parameter P = 12); + | ^ +%Error-UNSUPPORTED: t/t_class_param.v:17:24: Unsupported: class parameters + : ... In instance t + 17 | class Wrap #(parameter PMINUS1 = 3); + | ^~~~~~~ +%Error-UNSUPPORTED: t/t_class_param.v:18:15: Unsupported: class parameters + : ... In instance t + 18 | localparam P = PMINUS1 + 1; + | ^ +%Error-UNSUPPORTED: t/t_class_param.v:19:9: Unsupported: parameterized classes + : ... In instance t + 19 | Cls#(P) c1; + | ^ +%Error-UNSUPPORTED: t/t_class_param.v:25:14: Unsupported: parameterized classes + : ... In instance t + 25 | typedef Cls#(5) Cls5_t; + | ^ %Error: Exiting due to diff --git a/test_regress/t/t_class_unsup_bad.out b/test_regress/t/t_class_unsup_bad.out index 9b2c8fa30..eba10d537 100644 --- a/test_regress/t/t_class_unsup_bad.out +++ b/test_regress/t/t_class_unsup_bad.out @@ -5,9 +5,6 @@ %Error-UNSUPPORTED: t/t_class_unsup_bad.v:8:1: Unsupported: virtual data type 8 | virtual vi_t vi2; | ^~~~~~~ -%Error-UNSUPPORTED: t/t_class_unsup_bad.v:14:26: Unsupported: class parameters - 14 | localparam LOCPAR = 10; - | ^ %Error: t/t_class_unsup_bad.v:29:24: Syntax error: 'const'/'rand'/'randc' not allowed before function/task declaration 29 | const function void func_const; endfunction | ^~~~~~~~~~