Fix arithmetic right-shift by constants over 32 bits (#5994).

This commit is contained in:
Wilson Snyder 2025-05-10 13:59:56 -04:00
parent d9dcde60a6
commit 0f528d136d
4 changed files with 50 additions and 15 deletions

View File

@ -26,6 +26,7 @@ Verilator 5.037 devel
* Fix inconsistent assignment error with split-var (#5984) (#5988). [Yutetsu TAKATSUKASA]
* Fix AstAssignW conversion (#5991) (#5992). [Ryszard Rozak, Antmicro Ltd.]
* Fix const-bit-op-tree with single-bit masks (#5993) (#5998). [Yutetsu TAKATSUKASA]
* Fix arithmetic right-shift by constants over 32 bits (#5994).
Verilator 5.036 2025-04-27

View File

@ -1853,23 +1853,17 @@ V3Number& V3Number::opShiftRS(const V3Number& lhs, const V3Number& rhs, uint32_t
NUM_ASSERT_LOGIC_ARGS2(lhs, rhs);
if (rhs.isFourState()) return setAllBitsX();
setZero();
for (int bit = 32; bit < rhs.width(); ++bit) {
for (int sbit = 0; sbit < width(); ++sbit) {
setBit(sbit, lhs.bitIs(lbits - 1)); // 0/1/X/Z
}
if (rhs.bitIs1(lbits - 1)) setAllBits1(); // -1 else 0
return *this; // shift of over 2^32 must be -1/0
}
const uint32_t rhsval = rhs.toUInt();
if (rhsval < static_cast<uint32_t>(lhs.width())) {
for (int bit = 0; bit < width(); ++bit) {
setBit(bit, lhs.bitIsExtend(bit + rhsval, lbits));
}
} else {
for (int bit = 0; bit < width(); ++bit) {
setBit(bit, lhs.bitIs(lbits - 1)); // 0/1/X/Z
const bool overflow = rhs.width() > 32 && !rhs.isBitsZero(rhs.width() - 1, 32);
if (!overflow) {
const uint32_t rhsval = rhs.toUInt();
if (rhsval < static_cast<uint32_t>(lhs.width())) {
for (int bit = 0; bit < width(); ++bit) {
setBit(bit, lhs.bitIsExtend(bit + rhsval, lbits));
}
return *this;
}
}
for (int bit = 0; bit < width(); ++bit) setBit(bit, lhs.bitIs(lbits - 1)); // '0/'1/'x/'z
return *this;
}

View File

@ -0,0 +1,18 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2025 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
import vltest_bootstrap
test.scenarios('simulator')
test.compile(verilator_flags2=['--binary'])
test.execute()
test.passes()

View File

@ -0,0 +1,22 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2025 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);
module top(out35);
output wire [2:0] out35;
wire signed [2:0] wire_4;
assign wire_4 = 3'b011;
assign out35 = (wire_4 >>> 36'hffff_ffff_f);
initial begin
#10;
`checkd(out35, '0);
$write("*-* All Finished *-*\n");
$finish;
end
endmodule