diff --git a/Changes b/Changes index 36154147d..c90d1c3c1 100644 --- a/Changes +++ b/Changes @@ -5,6 +5,8 @@ The contributors that suggested a given feature are shown in []. Thanks! * Verilator 3.905 devel +*** Fix extract of packed array with non-zero LSB, bug1172. [James Pallister] + *** Fix shifts by more than 32-bit numbers, bug1174. [Clifford Wolf] *** Fix power operator on wide constants, bug761. [Clifford Wolf] diff --git a/src/V3WidthSel.cpp b/src/V3WidthSel.cpp index daed2cdfa..c6bb5fd29 100644 --- a/src/V3WidthSel.cpp +++ b/src/V3WidthSel.cpp @@ -223,7 +223,11 @@ private: // SELBIT(array, index) -> SEL(array, index*width-of-subindex, width-of-subindex) AstNode* subp = rhsp; if (fromRange.lo()!=0 || fromRange.hi()<0) { - subp = newSubNeg (subp, fromRange.lo()); + if (fromRange.littleEndian()) { + subp = newSubNeg(fromRange.hi(), subp); + } else { + subp = newSubNeg(subp, fromRange.lo()); + } } if (!fromRange.elements() || (adtypep->width() % fromRange.elements())!=0) adtypep->v3fatalSrc("Array extraction with width miscomputed " @@ -311,11 +315,20 @@ private: if (!fromRange.elements() || (adtypep->width() % fromRange.elements())!=0) adtypep->v3fatalSrc("Array extraction with width miscomputed " <width()<<"/"< msb) { + nodep->v3error("["<width() / fromRange.elements(); AstSel* newp = new AstSel (nodep->fileline(), fromp, - new AstConst(nodep->fileline(),AstConst::Unsized32(),lsb*elwidth), - new AstConst(nodep->fileline(),AstConst::Unsized32(),(msb-lsb+1)*elwidth)); + new AstMul(nodep->fileline(), newSubLsbOf(lsbp, fromRange), + new AstConst(nodep->fileline(), AstConst::Unsized32(), elwidth)), + new AstConst(nodep->fileline(), AstConst::Unsized32(), (msb-lsb+1)*elwidth)); newp->declRange(fromRange); newp->declElWidth(elwidth); newp->dtypeFrom(sliceDType(adtypep, msb, lsb)); diff --git a/test_regress/t/t_typedef_array.pl b/test_regress/t/t_typedef_array.pl new file mode 100755 index 000000000..f91289753 --- /dev/null +++ b/test_regress/t/t_typedef_array.pl @@ -0,0 +1,18 @@ +#!/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 ( + ); + +execute ( + check_finished=>1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_typedef_array.v b/test_regress/t/t_typedef_array.v new file mode 100644 index 000000000..1cc4c44e5 --- /dev/null +++ b/test_regress/t/t_typedef_array.v @@ -0,0 +1,26 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2017 by James Pallister. + +typedef logic logic_alias_t; + +module t; + logic_alias_t [6:1] signal; + // verilator lint_off LITENDIAN + logic_alias_t [1:6] signal2; + // verilator lint_on LITENDIAN + + initial begin + signal[6:1] = 'b100001; + signal[3] = 'b1; + signal2[1:6] = 'b100001; + signal2[4] = 'b1; + + if (signal != 'b100101) $stop; + if (signal2 != 'b100101) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule +