From e7de2c5a05a185ccbb3abe21d2150b241a146fe5 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 21 Sep 2024 19:19:12 -0400 Subject: [PATCH] Remove warning on unsized numbers exceeding 32-bits. --- Changes | 1 + src/V3Number.cpp | 23 ++++---- ...sized_bad.py => t_const_number_unsized.py} | 6 +- test_regress/t/t_const_number_unsized.v | 56 +++++++++++++++++++ test_regress/t/t_lint_unsized_bad.out | 18 ------ test_regress/t/t_lint_unsized_bad.v | 12 ---- 6 files changed, 74 insertions(+), 42 deletions(-) rename test_regress/t/{t_lint_unsized_bad.py => t_const_number_unsized.py} (83%) create mode 100644 test_regress/t/t_const_number_unsized.v delete mode 100644 test_regress/t/t_lint_unsized_bad.out delete mode 100644 test_regress/t/t_lint_unsized_bad.v diff --git a/Changes b/Changes index c14c35625..2b14c8b99 100644 --- a/Changes +++ b/Changes @@ -29,6 +29,7 @@ Verilator 5.029 devel * Support inside array constraints (#5448). [Arkadiusz Kozdra, Antmicro Ltd.] * Add partial coverage symbol and branch data in lcov info files (#5388). [Andrew Nolte] * Add method to check if there are VPI callbacks of the given type (#5399). [Kaleb Barrett] +* Remove warning on unsized numbers exceeding 32-bits. * Improve Verilation thread pool (#5161). [Bartłomiej Chmiel, Antmicro Ltd.] * Improve performance of V3VariableOrder with parallelism (#5406). [Bartłomiej Chmiel, Antmicro Ltd.] * Improve parser error handling. [Arkadiusz Kozdra, Antmicro Ltd.] diff --git a/src/V3Number.cpp b/src/V3Number.cpp index 02d9e0a4c..bb59c39bb 100644 --- a/src/V3Number.cpp +++ b/src/V3Number.cpp @@ -198,7 +198,7 @@ void V3Number::create(const char* sourcep) { } // Otherwise... else if (!sized()) { - width(32, false); // Says IEEE 1800-2012 5.7.1 + width(v3Global.opt.maxNumWidth(), false); // Will change width below if (unbased) isSigned(true); // Also says the spec. } @@ -213,6 +213,7 @@ void V3Number::create(const char* sourcep) { } int obit = 0; // Start at LSB + int base_align = 1; if (std::tolower(base) == 'd') { // Ignore leading zeros so we don't issue too many digit errors when lots of leading 0's while (*value_startp == '_' || *value_startp == '0') value_startp++; @@ -258,11 +259,13 @@ void V3Number::create(const char* sourcep) { case 'z': case '?': { got_z = 1; + if (!userSized) width(32, false); setAllBitsZ(); break; } case 'x': { got_x = 1; + if (!userSized) width(32, false); setAllBitsX(); break; } @@ -288,6 +291,7 @@ void V3Number::create(const char* sourcep) { } switch (std::tolower(base)) { case 'b': { + base_align = 1; switch (std::tolower(*cp)) { case '0': setBit(obit++, 0); break; case '1': setBit(obit++, 1); break; @@ -302,6 +306,7 @@ void V3Number::create(const char* sourcep) { case 'o': case 'c': { + base_align = 3; switch (std::tolower(*cp)) { // clang-format off case '0': setBit(obit++, 0); setBit(obit++, 0); setBit(obit++, 0); break; case '1': setBit(obit++, 1); setBit(obit++, 0); setBit(obit++, 0); break; @@ -322,6 +327,7 @@ void V3Number::create(const char* sourcep) { } case 'h': { + base_align = 4; switch (std::tolower(*cp)) { // clang-format off case '0': setBit(obit++,0); setBit(obit++,0); setBit(obit++,0); setBit(obit++,0); break; case '1': setBit(obit++,1); setBit(obit++,0); setBit(obit++,0); setBit(obit++,0); break; @@ -359,6 +365,11 @@ void V3Number::create(const char* sourcep) { } } + // If was unsized, trim width per IEEE 1800-2023 5.7.1 + if (!userSized && !m_data.m_autoExtend) { + width(std::max(32, base_align * ((widthMin() + base_align - 1) / base_align)), false); + } + // Z or X extend specific width values. Spec says we don't 1 extend. // This fixes 2'bx to become 2'bxx. while (obit <= width() && obit && bitIsXZ(obit - 1)) { @@ -372,15 +383,7 @@ void V3Number::create(const char* sourcep) { } void V3Number::warnTooMany(const string& value) { - static int warned = 0; - v3error("Too many digits for " - << width() << " bit number: '" << value << "'\n" - << ((!sized() && !warned++) - ? (V3Error::warnMore() + "... As that number was unsized" - + " ('...) it is limited to 32 bits" - " (IEEE 1800-2023 5.7.1)\n" - + V3Error::warnMore() + "... Suggest adding a size to it.") - : "")); + v3error("Too many digits for " << width() << " bit number: '" << value << "'\n"); } void V3Number::nodep(AstNode* nodep) VL_MT_STABLE { diff --git a/test_regress/t/t_lint_unsized_bad.py b/test_regress/t/t_const_number_unsized.py similarity index 83% rename from test_regress/t/t_lint_unsized_bad.py rename to test_regress/t/t_const_number_unsized.py index 31228c9a7..dbdaf4551 100755 --- a/test_regress/t/t_lint_unsized_bad.py +++ b/test_regress/t/t_const_number_unsized.py @@ -9,8 +9,10 @@ import vltest_bootstrap -test.scenarios('linter') +test.scenarios('simulator_st') -test.lint(fails=True, expect_filename=test.golden_filename) +test.compile() + +test.execute() test.passes() diff --git a/test_regress/t/t_const_number_unsized.v b/test_regress/t/t_const_number_unsized.v new file mode 100644 index 000000000..2f9a54b63 --- /dev/null +++ b/test_regress/t/t_const_number_unsized.v @@ -0,0 +1,56 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2017 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +`define stop $stop +`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); +`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0h exp=%0h\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); + +module t; + int s; + logic [255:0] n; + + initial begin + s = $bits('d123); + `checkd(s, 32); + s = $bits('h123); + `checkd(s, 32); + s = $bits('o123); + `checkd(s, 32); + s = $bits('b101); + `checkd(s, 32); + + // verilator lint_off WIDTHEXPAND + + // Used to warn "Too many digits for 32 bit number" + // ... As that number was unsized ('...) it is limited to 32 bits + // But other simulators don't warn, and language of (IEEE 1800-2023 5.7.1) + // has been updated to accepting this legal + n = 'd123456789123456789123456789; + s = $bits('d123456789123456789123456789); + `checkh(n, 256'h661efdf2e3b19f7c045f15); + `checkd(s, 87); + + n = 'h123456789123456789123456789; + s = $bits('h123456789123456789123456789); + `checkh(n, 256'h123456789123456789123456789); + `checkd(s, 108); + + //FIX octal digits in master test, if don't merge this + n = 'o123456777123456777123456777; + s = $bits('o123456777123456777123456777); + `checkh(n, 256'h53977fca72eff94e5dff); + `checkd(s, 81); + + n = 'b10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010; + s = $bits('b10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010); + `checkh(n, 256'haaaaaaaaaaaaaaaaaaaaaaa); + `checkd(s, 92); + + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule diff --git a/test_regress/t/t_lint_unsized_bad.out b/test_regress/t/t_lint_unsized_bad.out deleted file mode 100644 index 5256ac6c8..000000000 --- a/test_regress/t/t_lint_unsized_bad.out +++ /dev/null @@ -1,18 +0,0 @@ -%Error: t/t_lint_unsized_bad.v:8:22: Too many digits for 32 bit number: ''d123456789123456789123456789' - ... As that number was unsized ('...) it is limited to 32 bits (IEEE 1800-2023 5.7.1) - ... Suggest adding a size to it. - 8 | bit [256:0] num = 'd123456789123456789123456789; - | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -%Error: t/t_lint_unsized_bad.v:9:22: Too many digits for 32 bit number: ''h123456789123456789123456789' - 9 | bit [256:0] num = 'h123456789123456789123456789; - | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -%Error: t/t_lint_unsized_bad.v:10:22: Illegal character in octal constant - 10 | bit [256:0] num = 'o123456789123456789123456789; - | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -%Error: t/t_lint_unsized_bad.v:10:22: Too many digits for 32 bit number: ''o123456789123456789123456789' - 10 | bit [256:0] num = 'o123456789123456789123456789; - | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -%Error: t/t_lint_unsized_bad.v:11:22: Too many digits for 32 bit number: ''b10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010' - 11 | bit [256:0] num = 'b10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010; - | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -%Error: Exiting due to diff --git a/test_regress/t/t_lint_unsized_bad.v b/test_regress/t/t_lint_unsized_bad.v deleted file mode 100644 index 7bbd77c77..000000000 --- a/test_regress/t/t_lint_unsized_bad.v +++ /dev/null @@ -1,12 +0,0 @@ -// DESCRIPTION: Verilator: Verilog Test module -// -// This file ONLY is placed under the Creative Commons Public Domain, for -// any use, without warranty, 2017 by Wilson Snyder. -// SPDX-License-Identifier: CC0-1.0 - -module t; - bit [256:0] num = 'd123456789123456789123456789; - bit [256:0] num = 'h123456789123456789123456789; - bit [256:0] num = 'o123456789123456789123456789; - bit [256:0] num = 'b10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010; -endmodule