Fix shift of > 32-bit number (#4719).

This commit is contained in:
Wilson Snyder 2023-11-27 21:41:32 -05:00
parent a022b672a0
commit 7167d4bdc0
9 changed files with 43 additions and 40 deletions

View File

@ -35,6 +35,7 @@ Verilator 5.019 devel
* Fix trace when using SystemC with certain configurations (#4676). [Anthony Donlon] * Fix trace when using SystemC with certain configurations (#4676). [Anthony Donlon]
* Fix C++20 compilation errors (#4670). * Fix C++20 compilation errors (#4670).
* Fix compilers seeing empty input due to file system races (#4708). [Flavien Solt] * Fix compilers seeing empty input due to file system races (#4708). [Flavien Solt]
* Fix shift of > 32-bit number (#4719). [Flavien Solt]
* Fix 0**0 with wide numbers (#4721). [Flavien Solt] * Fix 0**0 with wide numbers (#4721). [Flavien Solt]

View File

@ -1221,13 +1221,16 @@ class ConstVisitor final : public VNVisitor {
} }
bool operandHugeShiftL(const AstNodeBiop* nodep) { bool operandHugeShiftL(const AstNodeBiop* nodep) {
return (VN_IS(nodep->rhsp(), Const) && !VN_AS(nodep->rhsp(), Const)->num().isFourState() return (VN_IS(nodep->rhsp(), Const) && !VN_AS(nodep->rhsp(), Const)->num().isFourState()
&& (VN_AS(nodep->rhsp(), Const)->toUInt() >= static_cast<uint32_t>(nodep->width())) && (!VN_AS(nodep->rhsp(), Const)->num().fitsInUInt() // > 2^32 shift
|| (VN_AS(nodep->rhsp(), Const)->toUInt()
>= static_cast<uint32_t>(nodep->width())))
&& nodep->lhsp()->isPure()); && nodep->lhsp()->isPure());
} }
bool operandHugeShiftR(const AstNodeBiop* nodep) { bool operandHugeShiftR(const AstNodeBiop* nodep) {
return (VN_IS(nodep->rhsp(), Const) && !VN_AS(nodep->rhsp(), Const)->num().isFourState() return (VN_IS(nodep->rhsp(), Const) && !VN_AS(nodep->rhsp(), Const)->num().isFourState()
&& (VN_AS(nodep->rhsp(), Const)->toUInt() && (!VN_AS(nodep->rhsp(), Const)->num().fitsInUInt() // > 2^32 shift
>= static_cast<uint32_t>(nodep->lhsp()->width())) || (VN_AS(nodep->rhsp(), Const)->toUInt()
>= static_cast<uint32_t>(nodep->lhsp()->width())))
&& nodep->lhsp()->isPure()); && nodep->lhsp()->isPure());
} }
bool operandIsTwo(const AstNode* nodep) { bool operandIsTwo(const AstNode* nodep) {

View File

@ -54,7 +54,7 @@ void V3Global::readFiles() {
if (v3Global.opt.std()) { if (v3Global.opt.std()) {
parser.parseFile(new FileLine{V3Options::getStdPackagePath()}, parser.parseFile(new FileLine{V3Options::getStdPackagePath()},
V3Options::getStdPackagePath(), false, V3Options::getStdPackagePath(), false,
"Cannot find verilated_std.sv containing built-in std:: definitions:"); "Cannot find verilated_std.sv containing built-in std:: definitions: ");
} }
// Read top module // Read top module

View File

@ -896,14 +896,20 @@ string V3Number::toDecimalU() const VL_MT_STABLE {
//====================================================================== //======================================================================
// ACCESSORS - as numbers // ACCESSORS - as numbers
bool V3Number::fitsInUInt() const VL_MT_SAFE {
if (isFourState()) return false;
// We allow wide numbers that represent values <= 32 bits
for (int i = 1; i < words(); ++i) {
if (m_data.num()[i].m_value) return false;
}
return true;
}
uint32_t V3Number::toUInt() const VL_MT_SAFE { uint32_t V3Number::toUInt() const VL_MT_SAFE {
UASSERT(!isFourState(), "toUInt with 4-state " << *this); UASSERT(!isFourState(), "toUInt with 4-state " << *this);
// We allow wide numbers that represent values <= 32 bits // We allow wide numbers that represent values <= 32 bits
for (int i = 1; i < words(); ++i) { if (VL_UNCOVERABLE(!fitsInUInt())) {
if (m_data.num()[i].m_value) { v3error("Value too wide for 32-bits expected in this context " // LCOV_EXCL_LINE
v3error("Value too wide for 32-bits expected in this context " << *this); << *this);
break;
}
} }
return m_data.num()[0].m_value; return m_data.num()[0].m_value;
} }

View File

@ -638,6 +638,7 @@ public:
bool isAnyXZ() const; bool isAnyXZ() const;
bool isAnyZ() const VL_MT_SAFE; bool isAnyZ() const VL_MT_SAFE;
bool isMsbXZ() const { return bitIsXZ(m_data.width() - 1); } bool isMsbXZ() const { return bitIsXZ(m_data.width() - 1); }
bool fitsInUInt() const VL_MT_SAFE;
uint32_t toUInt() const VL_MT_SAFE; uint32_t toUInt() const VL_MT_SAFE;
int32_t toSInt() const VL_MT_SAFE; int32_t toSInt() const VL_MT_SAFE;
uint64_t toUQuad() const VL_MT_SAFE; uint64_t toUQuad() const VL_MT_SAFE;

View File

@ -2,17 +2,15 @@
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition # DESCRIPTION: Verilator: Verilog Test driver/expect definition
# #
# Copyright 2010 by Wilson Snyder. This program is free software; you # Copyright 2023 by Wilson Snyder. This program is free software; you
# can redistribute it and/or modify it under the terms of either the GNU # 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 # Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0. # Version 2.0.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
scenarios(linter => 1); scenarios(simulator => 1);
lint( compile(
fails => 1,
expect_filename => $Self->{golden_filename},
); );
ok(1); ok(1);

View File

@ -0,0 +1,20 @@
// 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
outl, outr,
// Inputs
lhs
);
input [95:0] lhs;
output [95:0] outl;
output [95:0] outr;
assign outl = lhs << 95'hffff_00000000;
assign outr = lhs >> 95'hffff_00000000;
endmodule

View File

@ -1,5 +0,0 @@
%Error: t/t_math_shift_over_bad.v:19:20: Value too wide for 32-bits expected in this context 64'h123456789abcdef
: ... note: In instance 't'
19 | assign o = i << 64'h01234567_89abcdef;
| ^~~~~~~~~~~~~~~~~~~~~
%Error: Exiting due to

View File

@ -1,21 +0,0 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2016 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
module t (/*AUTOARG*/
// Outputs
o,
// Inputs
clk, i
);
input clk;
input [31:0] i;
output [31:0] o;
assign o = i << 64'h01234567_89abcdef;
endmodule