From 7559af587931e43a78bff8351c094c5d8c5c6eaf Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 22 Feb 2023 19:11:02 -0500 Subject: [PATCH] Fix missing error on negative replicate (#3963). --- Changes | 3 ++- src/V3Number.cpp | 14 ++++++++----- test_regress/t/t_math_repl2_bad.out | 5 +++++ test_regress/t/t_math_repl2_bad.pl | 19 ++++++++++++++++++ test_regress/t/t_math_repl2_bad.v | 31 +++++++++++++++++++++++++++++ 5 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 test_regress/t/t_math_repl2_bad.out create mode 100755 test_regress/t/t_math_repl2_bad.pl create mode 100644 test_regress/t/t_math_repl2_bad.v diff --git a/Changes b/Changes index 7676fdf5d..6770adf25 100644 --- a/Changes +++ b/Changes @@ -47,7 +47,8 @@ Verilator 5.007 devel * Fix constant format field widths (#3946). [Todd Strader] * Fix class field linking when a super classes is a param (#3949). [Ryszard Rozak, Antmicro Ltd] * Fix CMake bad C identifiers (#3948) (#3951). [Zixi Li] -* Fix build on HP PA architecture. (#3954) [John David Anglin] +* Fix build on HP PA architecture (#3954). [John David Anglin] +* Fix missing error on negative replicate (#3963). [Benjamin Menküc] * Fix packed array structure replication. diff --git a/src/V3Number.cpp b/src/V3Number.cpp index c29829059..6b241fac3 100644 --- a/src/V3Number.cpp +++ b/src/V3Number.cpp @@ -1435,15 +1435,19 @@ 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); - setZero(); - if (rhsval > 8192) { + if (rhsval > (1UL << 24)) { + v3error("More than a 16 Mbit replication, perhaps the replication factor" + " was two's-complement negative: " + << rhsval); + } else if (rhsval > 8192) { v3warn(WIDTHCONCAT, "More than a 8k bit replication is probably wrong: " << rhsval); } + setZero(); int obit = 0; - for (unsigned times = 0; times < rhsval; times++) { - for (int bit = 0; bit < lhs.width(); bit++) { + for (unsigned times = 0; times < rhsval; ++times) { + for (int bit = 0; bit < lhs.width(); ++bit) { setBit(obit, lhs.bitIs(bit)); - obit++; + ++obit; } } return *this; diff --git a/test_regress/t/t_math_repl2_bad.out b/test_regress/t/t_math_repl2_bad.out new file mode 100644 index 000000000..5d3ff0d0d --- /dev/null +++ b/test_regress/t/t_math_repl2_bad.out @@ -0,0 +1,5 @@ +%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 + : ... In instance t + 28 | out <= {{(P24 - P29){1'b0}}, in}; + | ^ +%Error: Internal Error: ../V3Number.h:#: `num` member accessed when data type is UNINITIALIZED diff --git a/test_regress/t/t_math_repl2_bad.pl b/test_regress/t/t_math_repl2_bad.pl new file mode 100755 index 000000000..9c9fb65a0 --- /dev/null +++ b/test_regress/t/t_math_repl2_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 2010 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 => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_math_repl2_bad.v b/test_regress/t/t_math_repl2_bad.v new file mode 100644 index 000000000..346dcebde --- /dev/null +++ b/test_regress/t/t_math_repl2_bad.v @@ -0,0 +1,31 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2023 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t(/*AUTOARG*/ + // Outputs + out, + // Inputs + clk, in + ); + + parameter P32 = 32; + parameter P24 = 24; + localparam P29 = P24 + 5; + + input clk; + output reg [P24-1:0] out; + + input [P29 - 1:0] in; + + always @(posedge clk) begin + if (P29 >= P24) begin + out <= in[P29 - 1 -: P24]; + end + else begin + out <= {{(P24 - P29){1'b0}}, in}; + end + end +endmodule