Fix 'bad select range' warning missing some cases, bug43.
This commit is contained in:
parent
4eeeb72dd5
commit
e46e7bbf99
4
Changes
4
Changes
|
|
@ -3,6 +3,10 @@ Revision history for Verilator
|
||||||
The contributors that suggested a given feature are shown in []. [by ...]
|
The contributors that suggested a given feature are shown in []. [by ...]
|
||||||
indicates the contributor was also the author of the fix; Thanks!
|
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
|
* Verilator 3.681 2008/11/12
|
||||||
|
|
||||||
*** Add SystemVerilog unique and priority case.
|
*** Add SystemVerilog unique and priority case.
|
||||||
|
|
|
||||||
|
|
@ -222,6 +222,7 @@ private:
|
||||||
&& (!varp->rangep() || varp->msb()) // else it's non-resolvable parameterized
|
&& (!varp->rangep() || varp->msb()) // else it's non-resolvable parameterized
|
||||||
&& ( ( (nodep->msbConst() > varp->msbMaxSelect())
|
&& ( ( (nodep->msbConst() > varp->msbMaxSelect())
|
||||||
|| (nodep->lsbConst() > varp->msbMaxSelect())))) {
|
|| (nodep->lsbConst() > varp->msbMaxSelect())))) {
|
||||||
|
// See also warning in V3Width
|
||||||
nodep->v3error("Selection index out of range: "
|
nodep->v3error("Selection index out of range: "
|
||||||
<<nodep->msbConst()<<":"<<nodep->lsbConst()
|
<<nodep->msbConst()<<":"<<nodep->lsbConst()
|
||||||
<<" outside "<<varp->msbMaxSelect()<<":0"
|
<<" outside "<<varp->msbMaxSelect()<<":0"
|
||||||
|
|
|
||||||
|
|
@ -302,13 +302,22 @@ private:
|
||||||
int selwidth = V3Number::log2b(frommsb+1-1)+1; // Width to address a bit
|
int selwidth = V3Number::log2b(frommsb+1-1)+1; // Width to address a bit
|
||||||
nodep->fromp()->iterateAndNext(*this,WidthVP(selwidth,selwidth,BOTH).p());
|
nodep->fromp()->iterateAndNext(*this,WidthVP(selwidth,selwidth,BOTH).p());
|
||||||
if (widthBad(nodep->lsbp(),selwidth,selwidth)
|
if (widthBad(nodep->lsbp(),selwidth,selwidth)
|
||||||
&& nodep->lsbp()->width()!=32)
|
&& nodep->lsbp()->width()!=32) {
|
||||||
nodep->v3warn(WIDTH,"Bit extraction of var["<<frommsb<<":"<<fromlsb<<"] requires "
|
nodep->v3warn(WIDTH,"Bit extraction of var["<<frommsb<<":"<<fromlsb<<"] requires "
|
||||||
<<selwidth<<" bit index, not "
|
<<selwidth<<" bit index, not "
|
||||||
<<nodep->lsbp()->width()
|
<<nodep->lsbp()->width()
|
||||||
<<(nodep->lsbp()->width()!=nodep->lsbp()->widthMin()
|
<<(nodep->lsbp()->width()!=nodep->lsbp()->widthMin()
|
||||||
?" or "+cvtToStr(nodep->lsbp()->widthMin()):"")
|
?" or "+cvtToStr(nodep->lsbp()->widthMin()):"")
|
||||||
<<" bits.");
|
<<" 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);
|
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,
|
void WidthVisitor::widthCheck (AstNode* nodep, const char* side,
|
||||||
AstNode* underp, int expWidth, int expWidthMin,
|
AstNode* underp, int expWidth, int expWidthMin,
|
||||||
bool ignoreWarn) {
|
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;
|
if (expWidthMin==0) expWidthMin = expWidth;
|
||||||
bool bad = widthBad(underp,expWidth,expWidthMin);
|
bool bad = widthBad(underp,expWidth,expWidthMin);
|
||||||
if (bad && fixAutoExtend(underp/*ref*/,expWidth)) bad=false; // Changes underp
|
if (bad && fixAutoExtend(underp/*ref*/,expWidth)) bad=false; // Changes underp
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
|
@ -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
|
||||||
Loading…
Reference in New Issue