Fix LITENDIAN warning on arrayed cells, bug1202.

This commit is contained in:
Wilson Snyder 2017-09-13 19:09:49 -04:00
parent 9d055f8c13
commit 8c9ca7a1b3
7 changed files with 74 additions and 2 deletions

View File

@ -6,6 +6,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
*** Fix ordering of arrayed cell wide connections, bug1202 partial. [Mike Popoloski]
**** Fix LITENDIAN warning on arrayed cells, bug1202. [Mike Popoloski]
**** Fix enum ranges without colons, bug1204. [Mike Popoloski]

View File

@ -3205,6 +3205,11 @@ Warns that a packed vector is declared with little endian bit numbering
and little numbering is now thus often due to simple oversight instead of
intent.
Also warns that a cell is declared with little endian range (i.e. [0:7] or
[7]) and is connected to a N-wide signal. Based on IEEE the bits will
likely be backwards from what you expect (i.e. cell [0] will connect to
signal bit [N-1] not bit [0]).
Ignoring this warning will only suppress the lint check, it will simulate
correctly.

View File

@ -350,6 +350,10 @@ private:
// NOP: Arrayed instants: widths match so connect to each instance
} else if (expwidth == pinwidth*m_cellRangep->elementsConst()) {
// Arrayed instants: one bit for each of the instants (each assign is 1 pinwidth wide)
if (m_cellRangep->littleEndian()) {
nodep->v3warn(LITENDIAN,"Little endian cell range connecting to vector: MSB < LSB of cell range: "
<<m_cellRangep->lsbConst()<<":"<<m_cellRangep->msbConst());
}
AstNode* exprp = nodep->exprp()->unlinkFrBack();
bool inputPin = nodep->modVarp()->isInput();
if (!inputPin && !exprp->castVarRef()

View File

@ -539,7 +539,8 @@ private:
int width = nodep->elementsConst();
if (width > (1<<28)) nodep->v3error("Width of bit range is huge; vector of over 1billion bits: 0x"<<hex<<width);
// Note width() not set on range; use elementsConst()
if (nodep->littleEndian() && !nodep->backp()->castUnpackArrayDType()) {
if (nodep->littleEndian() && !nodep->backp()->castUnpackArrayDType()
&& !nodep->backp()->castCell()) { // For cells we warn in V3Inst
nodep->v3warn(LITENDIAN,"Little bit endian vector: MSB < LSB of bit range: "<<nodep->lsbConst()<<":"<<nodep->msbConst());
}
}

View File

@ -21,7 +21,12 @@ module t ();
wire [2:0] X = 3'b110;
// Should not cause LITENDIAN warning?
// Should not cause LITENDIAN warning, as no harm in array selections.
// verilator lint_on LITENDIAN
foo_intf foo1 [N] (.x(1'b1));
foo_subm sub1 [N] (.x(1'b1));
// Will cause LITENDIAN warning?
// verilator lint_off LITENDIAN
foo_intf foos [N] (.x(X));
foo_intf fool [1:3] (.x(X));

View File

@ -0,0 +1,23 @@
#!/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 (
v_flags2 => ["--lint-only"],
fails=>$Self->{v3},
expect=>
q{%Warning-LITENDIAN: t/t_interface_array_nocolon_bad.v:\d+: Little endian cell range connecting to vector: MSB < LSB of cell range: 0:2
%Warning-LITENDIAN: Use [^\n]+
%Warning-LITENDIAN: t/t_interface_array_nocolon_bad.v:\d+: Little endian cell range connecting to vector: MSB < LSB of cell range: 1:3
%Warning-LITENDIAN: t/t_interface_array_nocolon_bad.v:\d+: Little endian cell range connecting to vector: MSB < LSB of cell range: 0:2
%Warning-LITENDIAN: t/t_interface_array_nocolon_bad.v:\d+: Little endian cell range connecting to vector: MSB < LSB of cell range: 1:3
%Error: Exiting due to},
);
ok(1);
1;

View File

@ -0,0 +1,32 @@
// DESCRIPTION: Verilator: Functionally demonstrate an array of interfaces
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2017 by Mike Popoloski.
interface foo_intf
(
input x
);
endinterface
module foo_subm
(
input x
);
endmodule
module t ();
localparam N = 3;
wire [2:0] X = 3'b110;
// Will cause LITENDIAN warning?
foo_intf foos [N] (.x(X)); // bad
foo_intf fool [1:3] (.x(X)); // bad
foo_intf foom [3:1] (.x(X)); // ok
foo_subm subs [N] (.x(X)); // bad
foo_subm subl [1:3] (.x(X)); // bad
foo_subm subm [3:1] (.x(X)); // ok
endmodule