diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index 8b3ccd0ed..f82a13199 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -24,6 +24,7 @@ Anthony Donlon Anthony Moore Arkadiusz Kozdra Arthur Rosa +Artur Bieniek Aylon Chaim Porat Bartłomiej Chmiel Brian Li diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 8ca414718..8dc92b97d 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -2461,11 +2461,11 @@ class WidthVisitor final : public VNVisitor { // if (debug() >= 9) nodep->dumpTree("- VRout: "); if (nodep->access().isWriteOrRW() && nodep->varp()->direction() == VDirection::CONSTREF) { nodep->v3error("Assigning to const ref variable: " << nodep->prettyNameQ()); - } else if (!nodep->varp()->isForced() && nodep->access().isWriteOrRW() - && nodep->varp()->isInput() && !nodep->varp()->isFuncLocal() - && nodep->varp()->isReadOnly() && (!m_ftaskp || !m_ftaskp->isConstructor()) - && !VN_IS(m_procedurep, InitialAutomatic) - && !VN_IS(m_procedurep, InitialStatic)) { + } else if (nodep->access().isWriteOrRW() && nodep->varp()->isInput() + && !nodep->varp()->isFuncLocal() && nodep->varp()->isReadOnly() + && (!m_ftaskp || !m_ftaskp->isConstructor()) + && !VN_IS(m_procedurep, InitialAutomatic) && !VN_IS(m_procedurep, InitialStatic) + && !VN_IS(nodep->abovep(), AssignForce) && !VN_IS(nodep->abovep(), Release)) { nodep->v3warn(ASSIGNIN, "Assigning to input/const variable: " << nodep->prettyNameQ()); } else if (nodep->access().isWriteOrRW() && nodep->varp()->isConst() && !m_paramsOnly && (!m_ftaskp || !m_ftaskp->isConstructor()) diff --git a/test_regress/t/t_force_input_assign_bad.out b/test_regress/t/t_force_input_assign_bad.out new file mode 100644 index 000000000..133179ba5 --- /dev/null +++ b/test_regress/t/t_force_input_assign_bad.out @@ -0,0 +1,14 @@ +%Error-ASSIGNIN: t/t_force_input_assign_bad.v:18:10: Assigning to input/const variable: 'i' + : ... note: In instance 't' + 18 | s1.i = 2; + | ^ + ... For error description see https://verilator.org/warn/ASSIGNIN?v=latest +%Error-ASSIGNIN: t/t_force_input_assign_bad.v:21:10: Assigning to input/const variable: 'i' + : ... note: In instance 't' + 21 | s2.i = 2; + | ^ +%Error-ASSIGNIN: t/t_force_input_assign_bad.v:25:17: Assigning to input/const variable: 'i' + : ... note: In instance 't' + 25 | assign s3.i = 2; + | ^ +%Error: Exiting due to diff --git a/test_regress/t/t_force_input_assign_bad.py b/test_regress/t/t_force_input_assign_bad.py new file mode 100755 index 000000000..d8bbae00a --- /dev/null +++ b/test_regress/t/t_force_input_assign_bad.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 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('vlt') + +test.lint(expect_filename=test.golden_filename, + verilator_flags2=['--error-limit 1000'], + fails=True) + +test.passes() diff --git a/test_regress/t/t_force_input_assign_bad.v b/test_regress/t/t_force_input_assign_bad.v new file mode 100644 index 000000000..380dc433d --- /dev/null +++ b/test_regress/t/t_force_input_assign_bad.v @@ -0,0 +1,32 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +module sub(input [1:0] i); +endmodule + +module t; + sub s1(1); + sub s2(1); + sub s3(1); + sub s4(1); + sub s5(1); + initial begin + // these should fail + s1.i = 2; + force s1.i = '1; + + s2.i = 2; + release s2.i; + + force s3.i = '1; + assign s3.i = 2; + + // these should not + force s4.i = '1; + + release s5.i; + end +endmodule