diff --git a/Changes b/Changes index 418720645..b9f225d21 100644 --- a/Changes +++ b/Changes @@ -21,6 +21,8 @@ indicates the contributor was also the author of the fix; Thanks! **** Fix mis-optimizing public DPI functions, bug963. [Wei Song] +**** Fix internal error on interface array, bug978. [Johan Bjork] + * Verilator 3.876 2015-08-12 diff --git a/src/V3LinkCells.cpp b/src/V3LinkCells.cpp index ada7f12a2..6288909dc 100644 --- a/src/V3LinkCells.cpp +++ b/src/V3LinkCells.cpp @@ -348,14 +348,34 @@ private: // This is quite similar to how classes work; when unpacked classes are better supported // may remap interfaces to be more like a class. if (!nodep->hasIfaceVar()) { - string varName = nodep->name()+"__Viftop"; // V3LinkDot looks for this naming - AstIfaceRefDType* idtypep = new AstIfaceRefDType(nodep->fileline(), nodep->name(), nodep->modp()->name()); - idtypep->cellp(nodep); // Only set when real parent cell known - idtypep->ifacep(NULL); // cellp overrides - AstVar* varp = new AstVar(nodep->fileline(), AstVarType::IFACEREF, varName, VFlagChildDType(), idtypep); - varp->isIfaceParent(true); - nodep->addNextHere(varp); - nodep->hasIfaceVar(true); + if (nodep->rangep()) { + int count = nodep->rangep()->lsbConst(); + for (int i = 0; i < count; i++) { + string varName = nodep->name() + "__BRA__" + cvtToStr(i) + "__KET__" + + "__Viftop"; // V3LinkDot looks for this naming + AstIfaceRefDType *idtypep = new AstIfaceRefDType(nodep->fileline(), + nodep->name(), + nodep->modp()->name()); + idtypep->cellp(nodep); // Only set when real parent cell known + idtypep->ifacep(NULL); // cellp overrides + AstVar *varp = new AstVar(nodep->fileline(), AstVarType::IFACEREF, varName, + VFlagChildDType(), idtypep); + varp->isIfaceParent(true); + nodep->addNextHere(varp); + nodep->hasIfaceVar(true); + } + } else { + string varName = nodep->name() + "__Viftop"; // V3LinkDot looks for this naming + AstIfaceRefDType *idtypep = new AstIfaceRefDType(nodep->fileline(), nodep->name(), + nodep->modp()->name()); + idtypep->cellp(nodep); // Only set when real parent cell known + idtypep->ifacep(NULL); // cellp overrides + AstVar *varp = new AstVar(nodep->fileline(), AstVarType::IFACEREF, varName, + VFlagChildDType(), idtypep); + varp->isIfaceParent(true); + nodep->addNextHere(varp); + nodep->hasIfaceVar(true); + } } } if (nodep->modp()) { diff --git a/test_regress/t/t_array_interface.pl b/test_regress/t/t_array_interface.pl new file mode 100755 index 000000000..f91289753 --- /dev/null +++ b/test_regress/t/t_array_interface.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_array_interface.v b/test_regress/t/t_array_interface.v new file mode 100644 index 000000000..f2f67f0b7 --- /dev/null +++ b/test_regress/t/t_array_interface.v @@ -0,0 +1,28 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2015 by Johan Bjork. + +interface intf; + logic a; + modport source(output a); + modport sink(input a); +endinterface + +module t +#( + parameter N = 1 +) +( input [N-1:0] a_in, + output[N-1:0] a_out +); + intf ifs[N-1:0] (); + logic [N-1:0] a_q; + + assign a_out = a_q; + assign ifs[0].a = a_in[0]; + initial begin + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule