From 71bc60fb91441e7e6e9451d3b884c1944957c48a Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 30 Apr 2024 18:38:37 -0400 Subject: [PATCH] Add error on zero width select (#5028). --- Changes | 1 + src/V3Width.cpp | 5 +++++ test_regress/t/t_bigmem_bad.out | 12 ++++++++---- test_regress/t/t_select_bad_range4.out | 8 ++++---- test_regress/t/t_select_bad_width0.out | 19 +++++++++++++++++++ test_regress/t/t_select_bad_width0.pl | 19 +++++++++++++++++++ test_regress/t/t_select_bad_width0.v | 24 ++++++++++++++++++++++++ 7 files changed, 80 insertions(+), 8 deletions(-) create mode 100644 test_regress/t/t_select_bad_width0.out create mode 100755 test_regress/t/t_select_bad_width0.pl create mode 100644 test_regress/t/t_select_bad_width0.v diff --git a/Changes b/Changes index e261cba34..5a954ecd7 100644 --- a/Changes +++ b/Changes @@ -17,6 +17,7 @@ Verilator 5.025 devel * Support empty queue as dynarray default value (#5055). [Arkadiusz Kozdra, Antmicro Ltd.] * Add CITATION.cff (#5057) (#5058). [Gijs Burghoorn] * Add VPI eval needed tracking (#5065). [Todd Strader] +* Add error on zero width select (#5028). * Fix missing flex include path variable (#4970) (#4971). [Christopher Taylor] * Fix missing parameters with comma to be errors (#4979) (#5012). [Paul Swirhun] * Fix bound queue printing (#5032). [Aleksander Kiryk, Antmicro Ltd.] diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 5b988c3ee..fb6c52257 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -913,6 +913,11 @@ class WidthVisitor final : public VNVisitor { return; } int width = nodep->widthConst(); + if (width <= 0) { + nodep->v3error("Width of bit extract must be positive (IEEE 1800-2023 11.5.1)"); + nodep->dtypeSetBit(); + return; + } UASSERT_OBJ(nodep->dtypep(), nodep, "dtype wasn't set"); // by V3WidthSel if (VN_IS(nodep->lsbp(), Const) && nodep->msbConst() < nodep->lsbConst()) { nodep->v3warn(E_UNSUPPORTED, "Unsupported: left < right of bit extract: " diff --git a/test_regress/t/t_bigmem_bad.out b/test_regress/t/t_bigmem_bad.out index fc31e3e90..9bf62ffce 100644 --- a/test_regress/t/t_bigmem_bad.out +++ b/test_regress/t/t_bigmem_bad.out @@ -1,7 +1,11 @@ -%Warning-SELRANGE: t/t_bigmem_bad.v:14:19: Selection index out of range: (nodep->declElWidth() == 0) -1:0 outside 268435455:0 - : ... note: In instance 't_bigmem' +%Error: t/t_bigmem_bad.v:14:19: Width of bit extract must be positive (IEEE 1800-2023 11.5.1) + : ... note: 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. +%Warning-WIDTHTRUNC: t/t_bigmem_bad.v:14:26: Operator ASSIGNDLY expects 1 bits on the Assign RHS, but Assign RHS's VARREF 'data' generates 256 bits. + : ... note: In instance 't_bigmem' + 14 | if (wen) mem[addr] <= data; + | ^~ + ... 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_select_bad_range4.out b/test_regress/t/t_select_bad_range4.out index 395b1bee4..e2d32618d 100644 --- a/test_regress/t/t_select_bad_range4.out +++ b/test_regress/t/t_select_bad_range4.out @@ -6,15 +6,15 @@ : ... note: In instance 't' 20 | sel2 = mi[44 +: -1]; | ^ -%Error-UNSUPPORTED: t/t_select_bad_range4.v:20:16: Unsupported: left < right of bit extract: 2<4 - : ... note: In instance 't' +%Error: t/t_select_bad_range4.v:20:16: Width of bit extract must be positive (IEEE 1800-2023 11.5.1) + : ... note: In instance 't' 20 | sel2 = mi[44 +: -1]; | ^ - ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest -%Warning-WIDTHEXPAND: t/t_select_bad_range4.v:20:12: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS's SEL generates 3 bits. +%Warning-WIDTHEXPAND: t/t_select_bad_range4.v:20:12: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS's SEL generates 1 bits. : ... note: In instance 't' 20 | sel2 = mi[44 +: -1]; | ^ + ... 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: t/t_select_bad_range4.v:21:16: Width of :+ or :- is huge; vector of over 1 billion bits: 32'h20000000 : ... note: In instance 't' diff --git a/test_regress/t/t_select_bad_width0.out b/test_regress/t/t_select_bad_width0.out new file mode 100644 index 000000000..96068ff07 --- /dev/null +++ b/test_regress/t/t_select_bad_width0.out @@ -0,0 +1,19 @@ +%Error: t/t_select_bad_width0.v:15:21: Width of bit extract must be positive (IEEE 1800-2023 11.5.1) + : ... note: In instance 't' + 15 | int part = val[left +: ZERO]; + | ^ +%Warning-WIDTHEXPAND: t/t_select_bad_width0.v:15:21: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS's SEL generates 1 bits. + : ... note: In instance 't' + 15 | int part = val[left +: ZERO]; + | ^ + ... 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: t/t_select_bad_width0.v:17:17: Width of bit extract must be positive (IEEE 1800-2023 11.5.1) + : ... note: In instance 't' + 17 | part = val[left -: ZERO]; + | ^ +%Warning-WIDTHEXPAND: t/t_select_bad_width0.v:17:12: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS's SEL generates 1 bits. + : ... note: In instance 't' + 17 | part = val[left -: ZERO]; + | ^ +%Error: Exiting due to diff --git a/test_regress/t/t_select_bad_width0.pl b/test_regress/t/t_select_bad_width0.pl new file mode 100755 index 000000000..59ba0d6c6 --- /dev/null +++ b/test_regress/t/t_select_bad_width0.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 => $Self->{vlt_all}, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_select_bad_width0.v b/test_regress/t/t_select_bad_width0.v new file mode 100644 index 000000000..671bb14ab --- /dev/null +++ b/test_regress/t/t_select_bad_width0.v @@ -0,0 +1,24 @@ +// 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(/*AUTOARG*/); + + parameter int ZERO = 0; + + initial begin + bit [31:0] val = '1; + int left = 4; + + int part = val[left +: ZERO]; + $display(part); + part = val[left -: ZERO]; + $display(part); + + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule