forked from github/verilator
Auto-extend and WIDTH warn on unsized X/Zs, bug1423.
This commit is contained in:
parent
03ebd5554f
commit
37c8cc82b2
2
Changes
2
Changes
@ -14,6 +14,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
|
||||
|
||||
**** Add error when use parameters without value, bug1424. [Peter Gerst]
|
||||
|
||||
**** Auto-extend and WIDTH warn on unsized X/Zs, bug1423. [Udi Finkelstein]
|
||||
|
||||
**** Fix missing VL_SHIFTL_ errors, bug1412, bug1415. [Larry Lee]
|
||||
|
||||
**** Fix MinGW GCC 6 printf formats, bug1413. [Sergey Kvachonok]
|
||||
|
@ -1656,8 +1656,20 @@ V3Number& V3Number::opAssign(const V3Number& lhs) {
|
||||
V3Number& V3Number::opExtendS(const V3Number& lhs, uint32_t lbits) {
|
||||
// Note may be a width change during the sign extension
|
||||
setZero();
|
||||
for(int bit=0; bit<this->width(); bit++) {
|
||||
setBit(bit,lhs.bitIsExtend(bit, lbits));
|
||||
for (int bit=0; bit < width(); bit++) {
|
||||
char extendWith = lhs.bitIsExtend(bit, lbits);
|
||||
setBit(bit, extendWith);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
V3Number& V3Number::opExtendXZ(const V3Number& lhs, uint32_t lbits) {
|
||||
// Note may be a width change during the X/Z extension
|
||||
setZero();
|
||||
for (int bit=0; bit < width(); bit++) {
|
||||
char extendWith = lhs.bitIsExtend(bit, lbits);
|
||||
if (extendWith == '1' || extendWith == 1) extendWith = 0;
|
||||
setBit(bit, lhs.bitIsExtend(bit, lbits));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -199,6 +199,7 @@ public:
|
||||
bool isLtXZ(const V3Number& rhs) const; // operator< with XZ compared
|
||||
void isSigned(bool ssigned) { m_signed=ssigned; }
|
||||
bool isUnknown() const;
|
||||
bool isMsbXZ() const { return bitIsXZ(m_width); }
|
||||
uint32_t toUInt() const;
|
||||
vlsint32_t toSInt() const;
|
||||
vluint64_t toUQuad() const;
|
||||
@ -231,8 +232,9 @@ public:
|
||||
V3Number& opBitsZ (const V3Number& lhs); // Z->1, 0/1/X->0
|
||||
V3Number& opBitsNonZ(const V3Number& lhs); // Z->0, 0/1/X->1
|
||||
//
|
||||
V3Number& opAssign (const V3Number& lhs);
|
||||
V3Number& opExtendS (const V3Number& lhs, uint32_t lbits); // Sign extension
|
||||
V3Number& opAssign (const V3Number& lhs);
|
||||
V3Number& opExtendS (const V3Number& lhs, uint32_t lbits); // Sign extension
|
||||
V3Number& opExtendXZ(const V3Number& lhs, uint32_t lbits); // X/Z extension
|
||||
V3Number& opRedOr (const V3Number& lhs);
|
||||
V3Number& opRedAnd (const V3Number& lhs);
|
||||
V3Number& opRedXor (const V3Number& lhs);
|
||||
|
@ -3170,8 +3170,26 @@ private:
|
||||
nodepr = newp;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false; // No change
|
||||
// X/Z also upper bit extend. In pre-SV only to 32-bits, SV forever.
|
||||
else if (!constp->num().sized()
|
||||
// Make it the proper size. Careful of proper extension of 0's/1's
|
||||
&& expWidth > 32 && constp->num().isMsbXZ()) {
|
||||
constp->v3warn(WIDTH, "Unsized constant being X/Z extended to "
|
||||
<<expWidth<<" bits: "<<constp->prettyName());
|
||||
V3Number num (constp->fileline(), expWidth);
|
||||
num.opExtendXZ(constp->num(), constp->width());
|
||||
AstNode* newp = new AstConst(constp->fileline(), num);
|
||||
// Spec says always unsigned with proper width
|
||||
if (debug()>4) constp->dumpTree(cout," fixUnszExtend_old: ");
|
||||
if (debug()>4) newp->dumpTree(cout," _new: ");
|
||||
constp->replaceWith(newp);
|
||||
constp->deleteTree(); VL_DANGLING(constp);
|
||||
// Tell caller the new constp, and that we changed it.
|
||||
nodepr = newp;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false; // No change
|
||||
}
|
||||
|
||||
bool similarDTypeRecurse(AstNodeDType* node1p, AstNodeDType* node2p) {
|
||||
|
@ -3,16 +3,16 @@
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2019 by Wilson Snyder.
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
module t(/*AUTOARG*/);
|
||||
|
||||
initial begin
|
||||
// verilator lint_off WIDTH
|
||||
if (32'hxxxxxxxx !== 'hx) $stop;
|
||||
if (32'hzzzzzzzz !== 'hz) $stop;
|
||||
if (32'h???????? !== 'h?) $stop;
|
||||
if (32'hxxxxxxxx !== 'dx) $stop;
|
||||
if (32'hzzzzzzzz !== 'dz) $stop;
|
||||
if (32'h???????? !== 'd?) $stop;
|
||||
if (68'hx_xxxxxxxx_xxxxxxxx !== 'dX) $stop;
|
||||
if (68'hz_zzzzzzzz_zzzzzzzz !== 'dZ) $stop;
|
||||
if (68'h?_????????_???????? !== 'd?) $stop;
|
||||
// verilator lint_on WIDTH
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
|
5
test_regress/t/t_const_bad.out
Normal file
5
test_regress/t/t_const_bad.out
Normal file
@ -0,0 +1,5 @@
|
||||
%Warning-WIDTH: t/t_const_bad.v:12: Unsized constant being X/Z extended to 68 bits: ?32?bxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
%Warning-WIDTH: Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.
|
||||
%Warning-WIDTH: t/t_const_bad.v:13: Unsized constant being X/Z extended to 68 bits: ?32?bzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
|
||||
%Warning-WIDTH: t/t_const_bad.v:14: Unsized constant being X/Z extended to 68 bits: ?32?bzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
|
||||
%Error: Exiting due to
|
22
test_regress/t/t_const_bad.pl
Executable file
22
test_regress/t/t_const_bad.pl
Executable file
@ -0,0 +1,22 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2004 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.
|
||||
|
||||
scenarios(vlt => 1);
|
||||
|
||||
compile(
|
||||
v_flags2 => ["--lint-only"],
|
||||
verilator_make_gcc => 0,
|
||||
make_top_shell => 0,
|
||||
make_main => 0,
|
||||
fails => 1,
|
||||
expect_filename => $Self->{golden_filename},
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
19
test_regress/t/t_const_bad.v
Normal file
19
test_regress/t/t_const_bad.v
Normal file
@ -0,0 +1,19 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2019 by Wilson Snyder.
|
||||
|
||||
module t(/*AUTOARG*/);
|
||||
|
||||
initial begin
|
||||
if (32'hxxxxxxxx !== 'hx) $stop;
|
||||
if (32'hzzzzzzzz !== 'hz) $stop;
|
||||
if (32'h???????? !== 'h?) $stop;
|
||||
if (68'hx_xxxxxxxx_xxxxxxxx !== 'dX) $stop;
|
||||
if (68'hz_zzzzzzzz_zzzzzzzz !== 'dZ) $stop;
|
||||
if (68'h?_????????_???????? !== 'd?) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule
|
Loading…
Reference in New Issue
Block a user