Detect selection index unknown instead of internal erroring

This commit is contained in:
Wilson Snyder 2009-09-16 20:52:52 -04:00
parent 0c0a588b55
commit b798f4fe71
3 changed files with 54 additions and 10 deletions

View File

@ -313,15 +313,24 @@ private:
if (m_warn
&& nodep->lsbp()->castConst()
&& nodep->widthp()->castConst()
&& (!varp->rangep() || varp->msb()) // else it's non-resolvable parameterized
&& ( ( (nodep->msbConst() > varp->msbMaxSelect())
|| (nodep->lsbConst() > varp->msbMaxSelect())))) {
// See also warning in V3Width
nodep->v3error("Selection index out of range: "
<<nodep->msbConst()<<":"<<nodep->lsbConst()
<<" outside "<<varp->msbMaxSelect()<<":0"
<<(varp->lsb()>=0 ? ""
:" (adjusted +"+cvtToStr(-varp->lsb())+" to account for negative lsb)"));
&& (!varp->rangep() || varp->msb())) { // else it's non-resolvable parameterized
if (nodep->lsbp()->castConst()->num().isFourState()
|| nodep->widthp()->castConst()->num().isFourState()) {
nodep->v3error("Selection index is constantly unknown or tristated: "
"lsb="<<nodep->lsbp()->name()<<" width="<<nodep->widthp()->name());
// Replacing nodep will make a mess above, so we replace the offender
replaceZero(nodep->lsbp());
}
else if ((nodep->msbConst() > varp->msbMaxSelect())
|| (nodep->lsbConst() > varp->msbMaxSelect())) {
// See also warning in V3Width
nodep->v3error("Selection index out of range: "
<<nodep->msbConst()<<":"<<nodep->lsbConst()
<<" outside "<<varp->msbMaxSelect()<<":0"
<<(varp->lsb()>=0 ? ""
:" (adjusted +"+cvtToStr(-varp->lsb())+" to account for negative lsb)"));
// Don't replace with zero, we'll do it later
}
}
}
return false; // Not a transform, so NOP
@ -367,7 +376,9 @@ private:
void replaceNum (AstNode* oldp, const V3Number& num) {
// Replace oldp node with a constant set to specified value
UASSERT (oldp, "Null old\n");
if (oldp->castConst()) oldp->v3fatalSrc("Already constant??\n");
if (oldp->castConst() && !oldp->castConst()->num().isFourState()) {
oldp->v3fatalSrc("Already constant??\n");
}
AstNode* newp = new AstConst(oldp->fileline(), num);
newp->widthSignedFrom(oldp);
if (debug()>5) oldp->dumpTree(cout," const_old: ");

View File

@ -0,0 +1,20 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 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.
compile (
v_flags2 => ["--lint-only"],
fails=>$Self->{v3},
expect=>
q{%Error: t/t_select_bad_tri.v:\d+: Selection index is constantly unknown or tristated: lsb=7'bxxxxxxx width=\?32\?sh47
%Error: Exiting due to.*},
);
ok(1);
1;

View File

@ -0,0 +1,13 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2008 by Wilson Snyder.
module t (/*AUTOARG*/);
reg [72:1] in;
initial begin
if (in[( (1'h0 / 1'b0) )+:71] != 71'h0) $stop;
end
endmodule