From e46e7bbf99c375bd318c25f81f16e110606c80e4 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 12 Nov 2008 20:54:58 -0500 Subject: [PATCH] Fix 'bad select range' warning missing some cases, bug43. --- Changes | 4 +++ src/V3Const.cpp | 1 + src/V3Width.cpp | 13 +++++-- test_regress/t/t_select_bad_range2.pl | 19 ++++++++++ test_regress/t/t_select_bad_range2.v | 52 +++++++++++++++++++++++++++ 5 files changed, 87 insertions(+), 2 deletions(-) create mode 100755 test_regress/t/t_select_bad_range2.pl create mode 100644 test_regress/t/t_select_bad_range2.v diff --git a/Changes b/Changes index 61e8a9407..69505c813 100644 --- a/Changes +++ b/Changes @@ -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. diff --git a/src/V3Const.cpp b/src/V3Const.cpp index 11ea66fdf..d64143e98 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -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: " <msbConst()<<":"<lsbConst() <<" outside "<msbMaxSelect()<<":0" diff --git a/src/V3Width.cpp b/src/V3Width.cpp index b1aebb36f..6635b4bb7 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -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["<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: " + <msbConst()<<":"<lsbConst() + <<" outside "<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 "< ["--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; + diff --git a/test_regress/t/t_select_bad_range2.v b/test_regress/t/t_select_bad_range2.v new file mode 100644 index 000000000..73486f83c --- /dev/null +++ b/test_regress/t/t_select_bad_range2.v @@ -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