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]
|
**** 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 missing VL_SHIFTL_ errors, bug1412, bug1415. [Larry Lee]
|
||||||
|
|
||||||
**** Fix MinGW GCC 6 printf formats, bug1413. [Sergey Kvachonok]
|
**** 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) {
|
V3Number& V3Number::opExtendS(const V3Number& lhs, uint32_t lbits) {
|
||||||
// Note may be a width change during the sign extension
|
// Note may be a width change during the sign extension
|
||||||
setZero();
|
setZero();
|
||||||
for(int bit=0; bit<this->width(); bit++) {
|
for (int bit=0; bit < width(); bit++) {
|
||||||
setBit(bit,lhs.bitIsExtend(bit, lbits));
|
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;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -199,6 +199,7 @@ public:
|
||||||
bool isLtXZ(const V3Number& rhs) const; // operator< with XZ compared
|
bool isLtXZ(const V3Number& rhs) const; // operator< with XZ compared
|
||||||
void isSigned(bool ssigned) { m_signed=ssigned; }
|
void isSigned(bool ssigned) { m_signed=ssigned; }
|
||||||
bool isUnknown() const;
|
bool isUnknown() const;
|
||||||
|
bool isMsbXZ() const { return bitIsXZ(m_width); }
|
||||||
uint32_t toUInt() const;
|
uint32_t toUInt() const;
|
||||||
vlsint32_t toSInt() const;
|
vlsint32_t toSInt() const;
|
||||||
vluint64_t toUQuad() const;
|
vluint64_t toUQuad() const;
|
||||||
|
|
@ -233,6 +234,7 @@ public:
|
||||||
//
|
//
|
||||||
V3Number& opAssign (const V3Number& lhs);
|
V3Number& opAssign (const V3Number& lhs);
|
||||||
V3Number& opExtendS (const V3Number& lhs, uint32_t lbits); // Sign extension
|
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& opRedOr (const V3Number& lhs);
|
||||||
V3Number& opRedAnd (const V3Number& lhs);
|
V3Number& opRedAnd (const V3Number& lhs);
|
||||||
V3Number& opRedXor (const V3Number& lhs);
|
V3Number& opRedXor (const V3Number& lhs);
|
||||||
|
|
|
||||||
|
|
@ -3170,6 +3170,24 @@ private:
|
||||||
nodepr = newp;
|
nodepr = newp;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// 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
|
return false; // No change
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,16 +3,16 @@
|
||||||
// This file ONLY is placed into the Public Domain, for any use,
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
// without warranty, 2019 by Wilson Snyder.
|
// without warranty, 2019 by Wilson Snyder.
|
||||||
|
|
||||||
module t (/*AUTOARG*/);
|
module t(/*AUTOARG*/);
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
// verilator lint_off WIDTH
|
// verilator lint_off WIDTH
|
||||||
if (32'hxxxxxxxx !== 'hx) $stop;
|
if (32'hxxxxxxxx !== 'hx) $stop;
|
||||||
if (32'hzzzzzzzz !== 'hz) $stop;
|
if (32'hzzzzzzzz !== 'hz) $stop;
|
||||||
if (32'h???????? !== 'h?) $stop;
|
if (32'h???????? !== 'h?) $stop;
|
||||||
if (32'hxxxxxxxx !== 'dx) $stop;
|
if (68'hx_xxxxxxxx_xxxxxxxx !== 'dX) $stop;
|
||||||
if (32'hzzzzzzzz !== 'dz) $stop;
|
if (68'hz_zzzzzzzz_zzzzzzzz !== 'dZ) $stop;
|
||||||
if (32'h???????? !== 'd?) $stop;
|
if (68'h?_????????_???????? !== 'd?) $stop;
|
||||||
// verilator lint_on WIDTH
|
// verilator lint_on WIDTH
|
||||||
$write("*-* All Finished *-*\n");
|
$write("*-* All Finished *-*\n");
|
||||||
$finish;
|
$finish;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -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