diff --git a/Changes b/Changes index ae6acf5d3..a6eee82ae 100644 --- a/Changes +++ b/Changes @@ -25,6 +25,7 @@ Verilator 5.039 devel * Support covergroup extends, etc., as unsupported (#6160). [Artur Bieniek, Antmicro Ltd.] * Change control file `public_flat_*` and other signal attributes to support __ in names (#6140). * Fix constructor parameters in inheritance hierarchies (#6036) (#6070). [Petr Nohavica] +* Fix replicate of negative giving 'REPLICATE has no expected width' internal error (#6048). * Fix cmake `-Wno` compiler flag testing (#6145). [Martin Stadler] * Fix class extends dotted error (#6162). [Igor Zaworski, Antmicro Ltd.] * Fix genvar error with `-O0` (#6165). [Max Wipfli] diff --git a/src/V3AstNodeExpr.h b/src/V3AstNodeExpr.h index b4c2f9a81..d816fa2d5 100644 --- a/src/V3AstNodeExpr.h +++ b/src/V3AstNodeExpr.h @@ -3367,7 +3367,11 @@ public: : ASTGEN_SUPER_Replicate(fl, lhsp, rhsp) { if (lhsp) { if (const AstConst* const constp = VN_CAST(rhsp, Const)) { - dtypeSetLogicSized(lhsp->width() * constp->toUInt(), VSigning::UNSIGNED); + if (constp->num().isFourState() || constp->num().isNegative()) { // V3Width warns + dtypeSetLogicSized(lhsp->width(), VSigning::UNSIGNED); + } else { + dtypeSetLogicSized(lhsp->width() * constp->toSInt(), VSigning::UNSIGNED); + } } } } diff --git a/src/V3Number.cpp b/src/V3Number.cpp index ce1477b25..d483c0cf3 100644 --- a/src/V3Number.cpp +++ b/src/V3Number.cpp @@ -1471,11 +1471,7 @@ V3Number& V3Number::opRepl(const V3Number& lhs, // i op repl, L(i)*value(rhs) bit return NUM_ASSERT_OP_ARGS1(lhs); NUM_ASSERT_LOGIC_ARGS1(lhs); - if (rhsval > (1UL << 24)) { - v3error("More than a 16 Mbit replication, perhaps the replication factor" - " was two's-complement negative: " - << rhsval << " (" << static_cast(rhsval) << ")"); - } else if (rhsval > 8192) { + if (rhsval > 8192) { v3warn(WIDTHCONCAT, "More than a 8k bit replication is probably wrong: " << rhsval); } setZero(); diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 32eacdca9..973ab54aa 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -798,10 +798,18 @@ class WidthVisitor final : public VNVisitor { iterateCheckSizedSelf(nodep, "RHS", nodep->countp(), SELF, BOTH); V3Const::constifyParamsNoWarnEdit(nodep->countp()); // rhsp may change - uint32_t times = 1; + int32_t times = 1; // IEEE replicate value is integral const AstConst* const constp = VN_CAST(nodep->countp(), Const); - if (constp) times = constp->toUInt(); + if (constp) { + if (constp->num().isFourState() || constp->num().isNegative()) { + nodep->v3error("Replication value of < 0 or X/Z not legal" + " (IEEE 1800-2023 11.4.12.1): " + << constp->prettyNameQ()); + } else { + times = constp->toSInt(); + } + } AstNodeDType* const vdtypep = m_vup->dtypeNullSkipRefp(); if (VN_IS(vdtypep, QueueDType) || VN_IS(vdtypep, DynArrayDType) diff --git a/test_regress/t/t_math_repl2_bad.out b/test_regress/t/t_math_repl2_bad.out index 3f21714bb..9f5fecdc7 100644 --- a/test_regress/t/t_math_repl2_bad.out +++ b/test_regress/t/t_math_repl2_bad.out @@ -1,7 +1,12 @@ -%Error: t/t_math_repl2_bad.v:28:30: More than a 16 Mbit replication, perhaps the replication factor was two's-complement negative: 4294967291 (-5) +%Error: t/t_math_repl2_bad.v:28:30: Replication value of < 0 or X/Z not legal (IEEE 1800-2023 11.4.12.1): '32'hfffffffb' : ... note: In instance 't' 28 | out <= {{(P24 - P29){1'b0}}, in}; | ^ ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. -%Error: Internal Error: ../V3Number.h:#: `num` member accessed when data type is UNINITIALIZED - ... This fatal error may be caused by the earlier error(s); resolve those first. +%Warning-WIDTHTRUNC: t/t_math_repl2_bad.v:28:14: Operator ASSIGNDLY expects 24 bits on the Assign RHS, but Assign RHS's REPLICATE generates 30 bits. + : ... note: In instance 't' + 28 | out <= {{(P24 - P29){1'b0}}, in}; + | ^~ + ... For warning description see https://verilator.org/warn/WIDTHTRUNC?v=latest + ... Use "/* verilator lint_off WIDTHTRUNC */" and lint_on around source to disable this message. +%Error: Exiting due to diff --git a/test_regress/t/t_math_repl3_bad.out b/test_regress/t/t_math_repl3_bad.out new file mode 100644 index 000000000..33fa422b5 --- /dev/null +++ b/test_regress/t/t_math_repl3_bad.out @@ -0,0 +1,28 @@ +%Error: t/t_math_repl3_bad.v:14:50: Replication value of < 0 or X/Z not legal (IEEE 1800-2023 11.4.12.1): '32'hfffffff8' + : ... note: In instance 't' + 14 | link_data_reg_in = {{((NUM_LANES - 2) * 8) {1'b0}}, link_data_reg[15:8]}; + | ^ + ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. +%Warning-SELRANGE: t/t_math_repl3_bad.v:14:72: Selection index out of range: 15:8 outside 7:0 + : ... note: In instance 't' + 14 | link_data_reg_in = {{((NUM_LANES - 2) * 8) {1'b0}}, link_data_reg[15:8]}; + | ^ + ... For warning description see https://verilator.org/warn/SELRANGE?v=latest + ... Use "/* verilator lint_off SELRANGE */" and lint_on around source to disable this message. +%Warning-WIDTHTRUNC: t/t_math_repl3_bad.v:14:24: Operator ASSIGN expects 8 bits on the Assign RHS, but Assign RHS's REPLICATE generates 9 bits. + : ... note: In instance 't' + 14 | link_data_reg_in = {{((NUM_LANES - 2) * 8) {1'b0}}, link_data_reg[15:8]}; + | ^ + ... For warning description see https://verilator.org/warn/WIDTHTRUNC?v=latest + ... Use "/* verilator lint_off WIDTHTRUNC */" and lint_on around source to disable this message. +%Error: t/t_math_repl3_bad.v:16:19: Replication value of < 0 or X/Z not legal (IEEE 1800-2023 11.4.12.1): '32'bzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz' + : ... note: In instance 't' + 16 | other = {32'bz{1'b1}}; + | ^ +%Warning-WIDTHEXPAND: t/t_math_repl3_bad.v:16:11: Operator ASSIGN expects 2 bits on the Assign RHS, but Assign RHS's REPLICATE generates 1 bits. + : ... note: In instance 't' + 16 | other = {32'bz{1'b1}}; + | ^ + ... For warning description see https://verilator.org/warn/WIDTHEXPAND?v=latest + ... Use "/* verilator lint_off WIDTHEXPAND */" and lint_on around source to disable this message. +%Error: Exiting due to diff --git a/test_regress/t/t_math_repl3_bad.py b/test_regress/t/t_math_repl3_bad.py new file mode 100755 index 000000000..55203b6c9 --- /dev/null +++ b/test_regress/t/t_math_repl3_bad.py @@ -0,0 +1,16 @@ +#!/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('linter') + +test.lint(fails=True, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_math_repl3_bad.v b/test_regress/t/t_math_repl3_bad.v new file mode 100644 index 000000000..b3f86c0ab --- /dev/null +++ b/test_regress/t/t_math_repl3_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, 2025 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t #( + parameter NUM_LANES = 1); + + reg [(NUM_LANES*8)-1:0] link_data_reg, link_data_reg_in; + reg [1:0] other; + always @(*) begin + if (NUM_LANES >= 2) begin // Not a generate if + link_data_reg_in = {{((NUM_LANES - 2) * 8) {1'b0}}, link_data_reg[15:8]}; + end + other = {32'bz{1'b1}}; + end +endmodule