From f8b0e359b95ac7fb60e5758b275fb656c93aaad8 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 13 Feb 2023 22:06:52 -0500 Subject: [PATCH] Support class parameters without initial values. --- Changes | 1 + src/V3Param.cpp | 17 ++++++++++++++--- test_regress/t/t_class_param_noinit.pl | 21 +++++++++++++++++++++ test_regress/t/t_class_param_noinit.v | 17 +++++++++++++++++ test_regress/t/t_class_param_noinit_bad.out | 5 +++++ test_regress/t/t_class_param_noinit_bad.pl | 19 +++++++++++++++++++ test_regress/t/t_class_param_noinit_bad.v | 18 ++++++++++++++++++ 7 files changed, 95 insertions(+), 3 deletions(-) create mode 100755 test_regress/t/t_class_param_noinit.pl create mode 100644 test_regress/t/t_class_param_noinit.v create mode 100644 test_regress/t/t_class_param_noinit_bad.out create mode 100755 test_regress/t/t_class_param_noinit_bad.pl create mode 100644 test_regress/t/t_class_param_noinit_bad.v diff --git a/Changes b/Changes index 22c55a30a..1f1f57347 100644 --- a/Changes +++ b/Changes @@ -21,6 +21,7 @@ Verilator 5.007 devel * Support unpacked unions. * Support interface classes and class implements. * Support global clocking and $global_clock. +* Support class parameters without initial values. * Support struct I/O in --lib-create (#3378) (#3892). [Varun Koyyalagunta] * Support function calls without parenthesis (#3903) (#3902). [Ryszard Rozak, Antmicro Ltd] * Support class extending its parameter (#3904). [Ryszard Rozak, Antmicro Ltd] diff --git a/src/V3Param.cpp b/src/V3Param.cpp index e4ebfd493..77f5bef82 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -820,12 +820,18 @@ class ParamProcessor final { } for (auto* stmtp = srcModpr->stmtsp(); stmtp; stmtp = stmtp->nextp()) { - if (auto* dtypep = VN_CAST(stmtp, ParamTypeDType)) { + if (AstParamTypeDType* dtypep = VN_CAST(stmtp, ParamTypeDType)) { if (VN_IS(dtypep->subDTypep(), VoidDType)) { nodep->v3error("Missing type parameter: " << dtypep->prettyNameQ()); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } } + if (AstVar* const varp = VN_CAST(stmtp, Var)) { + if (VN_IS(srcModpr, Class) && varp->isParam() && !varp->valuep()) { + nodep->v3error("Class parameter without initial value is never given value" + << " (IEEE 1800-2017 6.20.1): " << varp->prettyNameQ()); + } + } } // Delete the parameters from the cell; they're not relevant any longer. @@ -911,6 +917,7 @@ class ParamVisitor final : public VNVisitor { bool m_iterateModule = false; // Iterating module body string m_generateHierName; // Generate portion of hierarchy name string m_unlinkedTxt; // Text for AstUnlinkedRef + AstNodeModule* m_modp; // Module iterating std::vector m_dots; // Dot references to process std::multimap m_cellps; // Cells left to process (in current module) std::multimap m_workQueue; // Modules left to process @@ -941,7 +948,11 @@ class ParamVisitor final : public VNVisitor { if (modp->someInstanceName().empty()) modp->someInstanceName(modp->origName()); // Iterate the body - iterateChildren(modp); + { + VL_RESTORER(m_modp); + m_modp = modp; + iterateChildren(modp); + } // Process interface cells, then non-interface cells, which may reference an interface // cell. @@ -1053,7 +1064,7 @@ class ParamVisitor final : public VNVisitor { if (nodep->user5SetOnce()) return; // Process once iterateChildren(nodep); if (nodep->isParam()) { - if (!nodep->valuep()) { + if (!nodep->valuep() && !VN_IS(m_modp, Class)) { nodep->v3error("Parameter without initial value is never given value" << " (IEEE 1800-2017 6.20.1): " << nodep->prettyNameQ()); } else { diff --git a/test_regress/t/t_class_param_noinit.pl b/test_regress/t/t_class_param_noinit.pl new file mode 100755 index 000000000..859050d63 --- /dev/null +++ b/test_regress/t/t_class_param_noinit.pl @@ -0,0 +1,21 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2023 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(simulator => 1); + +compile( + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_class_param_noinit.v b/test_regress/t/t_class_param_noinit.v new file mode 100644 index 000000000..92a1f7df6 --- /dev/null +++ b/test_regress/t/t_class_param_noinit.v @@ -0,0 +1,17 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2023 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +// No init value is legal with classes, as long as not used without the parameter +class Cls #(int A, int B); +endclass + +module t(/*AUTOARG*/); + initial begin + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule diff --git a/test_regress/t/t_class_param_noinit_bad.out b/test_regress/t/t_class_param_noinit_bad.out new file mode 100644 index 000000000..7e021c7b9 --- /dev/null +++ b/test_regress/t/t_class_param_noinit_bad.out @@ -0,0 +1,5 @@ +%Error: t/t_class_param_noinit_bad.v:13:7: Class parameter without initial value is never given value (IEEE 1800-2017 6.20.1): 'B' + : ... In instance t + 13 | Cls #(1) c; + | ^~~ +%Error: Exiting due to diff --git a/test_regress/t/t_class_param_noinit_bad.pl b/test_regress/t/t_class_param_noinit_bad.pl new file mode 100755 index 000000000..a60503a1f --- /dev/null +++ b/test_regress/t/t_class_param_noinit_bad.pl @@ -0,0 +1,19 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(linter => 1); + +lint( + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_class_param_noinit_bad.v b/test_regress/t/t_class_param_noinit_bad.v new file mode 100644 index 000000000..52398d589 --- /dev/null +++ b/test_regress/t/t_class_param_noinit_bad.v @@ -0,0 +1,18 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2023 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +// No init value is legal with classes, as long as not used without the parameter +class Cls #(int A, int B); +endclass + +module t(/*AUTOARG*/); + initial begin + Cls #(1) c; // Bad: missing B + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule