Auto-extend and WIDTH warn on unsized X/Zs, bug1423.

This commit is contained in:
Wilson Snyder 2019-05-07 21:57:38 -04:00
parent 03ebd5554f
commit 37c8cc82b2
8 changed files with 90 additions and 10 deletions

View File

@ -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]

View File

@ -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;
}

View File

@ -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);

View File

@ -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) {

View File

@ -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;

View 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
View 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;

View 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