diff --git a/Changes b/Changes index 58c8272c2..282fd56b5 100644 --- a/Changes +++ b/Changes @@ -40,6 +40,8 @@ The contributors that suggested a given feature are shown in []. Thanks! **** Fix logical not optimization with empty begin, #2291. [Baltazar Ortiz] +**** Fix reduction OR on wide data, broke in v4.026, #2300. [Jack Koening] + * Verilator 4.032 2020-04-04 diff --git a/include/verilatedos.h b/include/verilatedos.h index 352f7f87b..66904c460 100644 --- a/include/verilatedos.h +++ b/include/verilatedos.h @@ -363,7 +363,7 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type #define VL_BYTESIZE 8 ///< Bits in a CData / byte #define VL_SHORTSIZE 16 ///< Bits in a SData / short #define VL_IDATASIZE 32 ///< Bits in a IData / word -#define VL_WORDSIZE IDATASIZE ///< Legacy define +#define VL_WORDSIZE VL_IDATASIZE ///< Legacy define #define VL_QUADSIZE 64 ///< Bits in a QData / quadword #define VL_EDATASIZE 32 ///< Bits in a EData (WData entry) #define VL_EDATASIZE_LOG2 5 ///< log2(VL_EDATASIZE) diff --git a/src/V3Expand.cpp b/src/V3Expand.cpp index cbc2ccfe9..6b33f497f 100644 --- a/src/V3Expand.cpp +++ b/src/V3Expand.cpp @@ -796,7 +796,8 @@ private: } newp = new AstEq( nodep->fileline(), - new AstConst(nodep->fileline(), AstConst::SizedEData(), ~VL_MASK_E(0)), newp); + new AstConst(nodep->fileline(), AstConst::SizedEData(), VL_MASK_E(VL_EDATASIZE)), + newp); VL_DO_DANGLING(replaceWithDelete(nodep, newp), nodep); } else { UINFO(8, " REDAND->EQ " << nodep << endl); diff --git a/test_regress/t/t_math_red.pl b/test_regress/t/t_math_red.pl new file mode 100755 index 000000000..1d046ed3f --- /dev/null +++ b/test_regress/t/t_math_red.pl @@ -0,0 +1,21 @@ +#!/usr/bin/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(simulator => 1); + +compile( + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_math_red.v b/test_regress/t/t_math_red.v new file mode 100644 index 000000000..10cb292b8 --- /dev/null +++ b/test_regress/t/t_math_red.v @@ -0,0 +1,65 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2004 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0) + +module t (/*AUTOARG*/ + // Inputs + clk + ); + + input clk; + integer cyc; initial cyc=0; + + reg [67:0] r; + + wire and_reduce = &r; + wire or_reduce = |r; + wire xor_reduce = ^r; + wire xnor_reduce = ~^r; + wire check_equal = r == 68'hffff_ffff_ffff_ffff_f; + + always @(posedge clk) begin +`ifdef TEST_VERBOSE + $display("cyc=%0d, r = %x, and_reduce = %x, or=%x xor=%x check_equal = %x", + cyc, r, and_reduce, or_reduce, xor_reduce, check_equal); +`endif + cyc <= cyc + 1; + if (cyc == 1) begin + r <= 68'd0; + end + else if (cyc == 10) begin + `checkh(r, 68'h0000_0000_0000_0000_0); + `checkh(and_reduce, '0); + `checkh(or_reduce, '0); + `checkh(xor_reduce, '0); + `checkh(xnor_reduce, '1); + r <= 68'hffff_ffff_ffff_ffff_e; + end + else if (cyc == 11) begin + `checkh(r, 68'hffff_ffff_ffff_ffff_e); + `checkh(and_reduce, '0); + `checkh(or_reduce, '1); + `checkh(xor_reduce, '1); + `checkh(xnor_reduce, '0); + r <= 68'hffff_ffff_ffff_ffff_f; + end + else if (cyc == 12) begin + `checkh(r, 68'hffff_ffff_ffff_ffff_f); + `checkh(and_reduce, '1); + `checkh(or_reduce, '1); + `checkh(xor_reduce, '0); + `checkh(xnor_reduce, '1); + end + else if (cyc == 90) begin + $write("*-* All Finished *-*\n"); + $finish; + end + else begin + r <= 68'd0; + end + end +endmodule