diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index bf76be7cd..1a86f4570 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -104,3 +104,4 @@ Yossi Nivin Yuri Victorovich Yutetsu TAKATSUKASA Yves Mathieu +Zhanglei Wang diff --git a/src/V3Const.cpp b/src/V3Const.cpp index 5e7984bdf..267a84e79 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -1346,10 +1346,15 @@ private: && (nodep->msbConst() > maxDeclBit || nodep->lsbConst() > maxDeclBit)) { // See also warning in V3Width // Must adjust by element width as declRange() is in number of elements + string msbLsbProtected; + if (nodep->declElWidth() == 0) { + msbLsbProtected = "(nodep->declElWidth() == 0) " + std::to_string(nodep->msbConst()) + ":" + std::to_string(nodep->lsbConst()); + } else { + msbLsbProtected = std::to_string(nodep->msbConst() / nodep->declElWidth()) + ":" + std::to_string(nodep->lsbConst() / nodep->declElWidth()); + } nodep->v3warn(SELRANGE, "Selection index out of range: " - << (nodep->msbConst() / nodep->declElWidth()) << ":" - << (nodep->lsbConst() / nodep->declElWidth()) << " outside " + << msbLsbProtected << " outside " << nodep->declRange().hiMaxSelect() << ":0" << (nodep->declRange().lo() >= 0 ? "" diff --git a/test_regress/t/t_bigmem_bad.out b/test_regress/t/t_bigmem_bad.out new file mode 100644 index 000000000..ec7bfe78a --- /dev/null +++ b/test_regress/t/t_bigmem_bad.out @@ -0,0 +1,7 @@ +%Warning-SELRANGE: t/t_bigmem_bad.v:14:19: Selection index out of range: (nodep->declElWidth() == 0) -1:0 outside 268435455:0 + : ... In instance t_bigmem + 14 | if (wen) mem[addr] <= data; + | ^ + ... 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. +%Error: Exiting due to diff --git a/test_regress/t/t_bigmem_bad.pl b/test_regress/t/t_bigmem_bad.pl new file mode 100755 index 000000000..8e592a491 --- /dev/null +++ b/test_regress/t/t_bigmem_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 2021 by filamoon. 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_bigmem_bad.v b/test_regress/t/t_bigmem_bad.v new file mode 100644 index 000000000..eadfb3f1e --- /dev/null +++ b/test_regress/t/t_bigmem_bad.v @@ -0,0 +1,16 @@ +// This test shall generate a warning, but not an internal error. +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2021 by Zhanglei Wang. +// SPDX-License-Identifier: CC0-1.0 +module t_bigmem( + input wire clk, + input wire [27:0] addr, + input wire [255:0] data, + input wire wen +); + reg [(1<<28)-1:0][255:0] mem; + always @(posedge clk) begin + if (wen) mem[addr] <= data; + end +endmodule