diff --git a/Changes b/Changes index 2c76dba5e..40b9b157e 100644 --- a/Changes +++ b/Changes @@ -14,6 +14,7 @@ Verilator 5.031 devel **Minor:** * Add coverage point hierarchy to coverage reports (#5575) (#5576). [Andrew Nolte] +* Add error when improperly storing to parameter (#5147). [Gökçe Aydos] * Fix can't locate scope error in interface task delayed assignment (#5462) (#5568). [Zhou Shen] * Fix BLKANDNBLK for for VARXREFs (#5569). [Todd Strader] * Fix VPI error instead of fatal for vpi_get_value() on large signals (#5571). [Todd Strader] diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index 8387f70c9..e4b3cee54 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -2069,7 +2069,7 @@ public: bool isTristate() const { return m_tristate; } bool isPrimaryIO() const VL_MT_SAFE { return m_primaryIO; } bool isPrimaryInish() const { return isPrimaryIO() && isNonOutput(); } - bool isIfaceRef() const { return (varType() == VVarType::IFACEREF); } + bool isIfaceRef() const { return varType() == VVarType::IFACEREF; } bool isIfaceParent() const { return m_isIfaceParent; } bool isInternal() const { return m_isInternal; } bool isSignal() const { return varType().isSignal(); } @@ -2085,11 +2085,11 @@ public: && !isSc() && !isPrimaryIO() && !isConst() && !isDouble() && !isString()); } bool isClassMember() const { return varType() == VVarType::MEMBER; } - bool isStatementTemp() const { return (varType() == VVarType::STMTTEMP); } - bool isXTemp() const { return (varType() == VVarType::XTEMP); } + bool isStatementTemp() const { return varType() == VVarType::STMTTEMP; } + bool isXTemp() const { return varType() == VVarType::XTEMP; } bool isParam() const { return varType().isParam(); } - bool isGParam() const { return (varType() == VVarType::GPARAM); } - bool isGenVar() const { return (varType() == VVarType::GENVAR); } + bool isGParam() const { return varType() == VVarType::GPARAM; } + bool isGenVar() const { return varType() == VVarType::GENVAR; } bool isBitLogic() const { AstBasicDType* bdtypep = basicp(); return bdtypep && bdtypep->isBitLogic(); diff --git a/src/V3LinkLValue.cpp b/src/V3LinkLValue.cpp index 3cbbcbfd9..160d0075e 100644 --- a/src/V3LinkLValue.cpp +++ b/src/V3LinkLValue.cpp @@ -48,6 +48,13 @@ class LinkLValueVisitor final : public VNVisitor { if (m_setIfRand && !(nodep->varp() && nodep->varp()->isRand())) return; if (m_setRefLvalue != VAccess::NOCHANGE) nodep->access(m_setRefLvalue); if (nodep->varp() && nodep->access().isWriteOrRW()) { + if (nodep->varp()->isParam()) { + // All parameters that did get constified happened before now + // as V3LinkLValue runs after V3Param + nodep->v3error("Storing to parameter variable " + << nodep->prettyNameQ() + << " in a context that is determed only at runtime"); + } if (m_setContinuously) { nodep->varp()->isContinuously(true); // Strength may only be specified in continuous assignment, diff --git a/test_regress/t/t_param_store_bad.out b/test_regress/t/t_param_store_bad.out new file mode 100644 index 000000000..7a47a6e14 --- /dev/null +++ b/test_regress/t/t_param_store_bad.out @@ -0,0 +1,4 @@ +%Error: t/t_param_store_bad.v:12:31: Storing to parameter variable 'S' in a context that is determed only at runtime + 12 | $value$plusargs("S=%s", S); + | ^ +%Error: Exiting due to diff --git a/test_regress/t/t_param_store_bad.py b/test_regress/t/t_param_store_bad.py new file mode 100755 index 000000000..31228c9a7 --- /dev/null +++ b/test_regress/t/t_param_store_bad.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('linter') + +test.lint(fails=True, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_param_store_bad.v b/test_regress/t/t_param_store_bad.v new file mode 100644 index 000000000..5f617d9d7 --- /dev/null +++ b/test_regress/t/t_param_store_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, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t #( + string S = "" + ); + + initial begin + $value$plusargs("S=%s", S); // BAD assignment to S + #1; // Original bug got compile time error only with this line + $display("S=%s", S); + $finish; + end + +endmodule