Fix shift of > 32-bit number (#4719).
This commit is contained in:
parent
a022b672a0
commit
7167d4bdc0
1
Changes
1
Changes
|
|
@ -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]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
Loading…
Reference in New Issue