Fix 'bad select range' warning missing some cases, bug43.

This commit is contained in:
Wilson Snyder 2008-11-12 20:54:58 -05:00
parent 4eeeb72dd5
commit e46e7bbf99
5 changed files with 87 additions and 2 deletions

View File

@ -3,6 +3,10 @@ Revision history for Verilator
The contributors that suggested a given feature are shown in []. [by ...]
indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.68***
**** Fix 'bad select range' warning missing some cases, bug43. [Lane Brooks]
* Verilator 3.681 2008/11/12
*** Add SystemVerilog unique and priority case.

View File

@ -222,6 +222,7 @@ private:
&& (!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"

View File

@ -302,13 +302,22 @@ private:
int selwidth = V3Number::log2b(frommsb+1-1)+1; // Width to address a bit
nodep->fromp()->iterateAndNext(*this,WidthVP(selwidth,selwidth,BOTH).p());
if (widthBad(nodep->lsbp(),selwidth,selwidth)
&& nodep->lsbp()->width()!=32)
&& nodep->lsbp()->width()!=32) {
nodep->v3warn(WIDTH,"Bit extraction of var["<<frommsb<<":"<<fromlsb<<"] requires "
<<selwidth<<" bit index, not "
<<nodep->lsbp()->width()
<<(nodep->lsbp()->width()!=nodep->lsbp()->widthMin()
?" or "+cvtToStr(nodep->lsbp()->widthMin()):"")
<<" bits.");
}
if (nodep->lsbp()->castConst() && nodep->msbConst() > frommsb) {
// See also warning in V3Const
// We need to check here, because the widthCheck may silently
// add another SEL which will loose the out-of-range check
nodep->v3error("Selection index out of range: "
<<nodep->msbConst()<<":"<<nodep->lsbConst()
<<" outside "<<frommsb<<":"<<fromlsb);
}
widthCheck(nodep,"Extract Range",nodep->lsbp(),selwidth,selwidth,true);
}
}
@ -909,7 +918,7 @@ bool WidthVisitor::fixAutoExtend (AstNode*& nodepr, int expWidth) {
void WidthVisitor::widthCheck (AstNode* nodep, const char* side,
AstNode* underp, int expWidth, int expWidthMin,
bool ignoreWarn) {
//UINFO(0,"wchk "<<nodep<<endl<<" "<<underp<<endl<<" e"<<expWidth<<" m"<<expWidthMin<<" i"<<ignoreWarn<<endl);
//UINFO(9,"wchk "<<side<<endl<<" "<<nodep<<endl<<" "<<underp<<endl<<" e"<<expWidth<<" m"<<expWidthMin<<" i"<<ignoreWarn<<endl);
if (expWidthMin==0) expWidthMin = expWidth;
bool bad = widthBad(underp,expWidth,expWidthMin);
if (bad && fixAutoExtend(underp/*ref*/,expWidth)) bad=false; // Changes underp

View File

@ -0,0 +1,19 @@
#!/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
# General Public License or the Perl Artistic License.
compile (
v_flags2 => ["--lint-only"],
fails=>$Last_Self->{v3},
expect=>
'%Error: t/t_select_bad_range2.v:\d+: Selection index out of range: 3:2 outside 1:0
%Error: Exiting due to.*',
);
ok(1);
1;

View File

@ -0,0 +1,52 @@
// 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*/
// Inputs
clk
);
input clk;
reg [1:0] in;
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire [1:0] out10; // From test of Test.v
wire [1:0] out32; // From test of Test.v
// End of automatics
Test test (/*AUTOINST*/
// Outputs
.out32 (out32[1:0]),
.out10 (out10[1:0]),
// Inputs
.in (in[1:0]));
// Test loop
always @ (posedge clk) begin
in <= in + 1;
`ifdef TEST_VERBOSE
$write("[%0t] in=%d out32=%d out10=%d\n",$time, in, out32, out10);
`endif
if (in==3) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
module Test (/*AUTOARG*/
// Outputs
out32, out10,
// Inputs
in
);
input [1:0] in;
output [1:0] out32;
output [1:0] out10;
assign out32 = in[3:2];
assign out10 = in[1:0];
endmodule