Fix slicing mix of big and little-endian, bug1033.

This commit is contained in:
Wilson Snyder 2016-02-09 22:16:12 -05:00
parent ca532d23f0
commit 4945282369
7 changed files with 97 additions and 12 deletions

View File

@ -21,6 +21,8 @@ indicates the contributor was also the author of the fix; Thanks!
**** Fix crash on very deep function trees, bug1028. [Jonathan Kimmitt]
**** Fix slicing mix of big and little-endian, bug1033. [Geoff Barrett]
* Verilator 3.880 2015-12-19

View File

@ -412,10 +412,10 @@ public:
AstVar* pinVarp = pinp->modVarp();
AstVarRef* connectRefp = pinp->exprp()->castVarRef();
AstVarXRef* connectXRefp = pinp->exprp()->castVarXRef();
AstBasicDType* pinBasicp = pinVarp->dtypep()->basicp(); // Maybe NULL
AstBasicDType* pinBasicp = pinVarp->dtypep()->castBasicDType(); // Maybe NULL
AstBasicDType* connBasicp = NULL;
AstAssignW* assignp = NULL;
if (connectRefp) connBasicp = connectRefp->varp()->dtypep()->basicp();
if (connectRefp) connBasicp = connectRefp->varp()->dtypep()->castBasicDType();
//
if (!alwaysCvt
&& connectRefp

View File

@ -102,6 +102,9 @@ class SliceCloneVisitor : public AstNVisitor {
AstUnpackArrayDType* adtypep = nodep->fromp()->dtypep()->skipRefp()->castUnpackArrayDType();
if (!adtypep) nodep->v3fatalSrc("slice select tried to expand an array without an ArrayDType");
unsigned idx = nodep->start() + m_selBits[m_vecIdx][m_depth] - adtypep->lsb();
if (adtypep->rangep()->littleEndian()) { // Little must iterate backwards
idx = adtypep->rangep()->elementsConst() - 1 - idx;
}
AstNode* constp = new AstConst(bitp->fileline(), V3Number(bitp->fileline(), bitp->castConst()->num().width(), idx));
bitp->replaceWith(constp);
} else {
@ -255,15 +258,15 @@ class SliceVisitor : public AstNVisitor {
return clones;
}
AstArraySel* insertImplicit(AstNode* nodep, unsigned start, unsigned count) {
AstArraySel* insertImplicit(AstNode* nodep, unsigned startDim, unsigned numDimensions) {
// Insert any implicit slices as explicit slices (ArraySel nodes).
// Return a new pointer to replace nodep() in the ArraySel.
UINFO(9," insertImplicit (start="<<start<<",c="<<count<<") "<<nodep<<endl);
UINFO(9," insertImplicit (startDim="<<startDim<<",c="<<numDimensions<<") "<<nodep<<endl);
AstVarRef* refp = nodep->user1p()->castNode()->castVarRef();
if (!refp) nodep->v3fatalSrc("No VarRef in user1 of node "<<nodep);
AstVar* varp = refp->varp();
AstNode* topp = nodep;
for (unsigned i = start; i < start + count; ++i) {
for (unsigned i = startDim; i < startDim + numDimensions; ++i) {
AstNodeDType* dtypep = varp->dtypep()->dtypeDimensionp(i-1);
AstUnpackArrayDType* adtypep = dtypep->castUnpackArrayDType();
if (!adtypep) nodep->v3fatalSrc("insertImplicit tried to expand an array without an ArrayDType");

18
test_regress/t/t_array_rev.pl Executable file
View File

@ -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;

View File

@ -0,0 +1,60 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2016 by Geoff Barrett.
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
integer cyc=0;
// verilator lint_off LITENDIAN
logic arrd [0:1] = '{ 1'b1, 1'b0 };
// verilator lint_on LITENDIAN
logic y0, y1;
logic localbkw [1:0];
arr_rev arr_rev_u (
.arrbkw (arrd),
.y0(y0),
.y1(y1)
);
always @ (posedge clk) begin
if (arrd[0] != 1'b1) $stop;
if (arrd[1] != 1'b0) $stop;
localbkw = arrd;
`ifdef TEST_VERBOSE
$write("localbkw[0]=%b\n", localbkw[0]);
$write("localbkw[1]=%b\n", localbkw[1]);
`endif
if (localbkw[0] != 1'b0) $stop;
if (localbkw[1] != 1'b1) $stop;
`ifdef TEST_VERBOSE
$write("y0=%b\n", y0);
$write("y1=%b\n", y1);
`endif
if (y0 != 1'b0) $stop;
if (y1 != 1'b1) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule
module arr_rev
(
input var logic arrbkw [1:0],
output var logic y0,
output var logic y1
);
always_comb y0 = arrbkw[0];
always_comb y1 = arrbkw[1];
endmodule

View File

@ -8,12 +8,14 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Version 2.0.
compile (
verilator_flags2 => ["--lint-only"],
fails=>1,
expect=>
q{%Error: t/t_inst_misarray_bad.v:\d+: Illegal assignment of constant to unpacked array
%Error: Exiting due to.*},
);
verilator_flags2 => ["--lint-only"],
fails=>0,
verilator_make_gcc => 0,
make_top_shell => 0,
make_main => 0,
# Once got illegal assignment, but new slicing rules don't always detect this.
# Due to V3Width.cpp pinwidth != conwidth requirement on data type mismatches
);
ok(1);

View File

@ -8,7 +8,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Version 2.0.
compile (
v_flags2 => ["--lint-only"],
verilator_flags2 => ["--lint-only"],
fails=>0,
verilator_make_gcc => 0,
make_top_shell => 0,