diff --git a/Changes b/Changes index c2b729799..e23035261 100644 --- a/Changes +++ b/Changes @@ -10,6 +10,8 @@ The contributors that suggested a given feature are shown in []. Thanks! **** Make Syms file honor --output-split-cfuncs, bug1499. [Todd Strader] +**** Fix error on multidimensional cells, bug1505. [Anderson Ignacio Da Silva] + * Verilator 4.018 2019-08-29 diff --git a/src/V3ParseGrammar.cpp b/src/V3ParseGrammar.cpp index 420070526..35f1d5529 100644 --- a/src/V3ParseGrammar.cpp +++ b/src/V3ParseGrammar.cpp @@ -88,12 +88,17 @@ AstNode* V3ParseGrammar::createSupplyExpr(FileLine* fileline, string name, int v AstRange* V3ParseGrammar::scrubRange(AstNodeRange* nrangep) { // Remove any UnsizedRange's from list for (AstNodeRange* nodep = nrangep, *nextp; nodep; nodep = nextp) { - nextp = VN_CAST(nrangep->nextp(), NodeRange); + nextp = VN_CAST(nodep->nextp(), NodeRange); if (!VN_IS(nodep, Range)) { nodep->v3error("Unsupported or syntax error: Unsized range in cell or other declaration"); nodep->unlinkFrBack(); nodep->deleteTree(); VL_DANGLING(nodep); } } + if (nrangep && nrangep->nextp()) { + // Not supported by at least 2 of big 3 + nrangep->nextp()->v3error("Unsupported: Multidimensional cells/interfaces."); + nrangep->nextp()->unlinkFrBackWithNext()->deleteTree(); + } return VN_CAST(nrangep, Range); } diff --git a/src/verilog.y b/src/verilog.y index 30ca397ac..7e76a6d00 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -2201,7 +2201,7 @@ mpInstnameList: // Similar to instnameList, but for modport instantiatio ; mpInstnameParen: // Similar to instnameParen, but for modport instantiations which have no parenthesis - id instRangeE sigAttrListE { $$ = VARDONEA($1,*$1,$2,$3); } + id instRangeListE sigAttrListE { $$ = VARDONEA($1,*$1,$2,$3); } ; instnameList: @@ -2211,25 +2211,34 @@ instnameList: instnameParen: // // Must clone m_instParamp as may be comma'ed list of instances - id instRangeE '(' cellpinList ')' { $$ = new AstCell($1, GRAMMARP->m_instModuleFl, + id instRangeListE '(' cellpinList ')' { $$ = new AstCell($1, GRAMMARP->m_instModuleFl, *$1, GRAMMARP->m_instModule, $4, AstPin::cloneTreeNull(GRAMMARP->m_instParamp, true), GRAMMARP->scrubRange($2)); $$->trace(GRAMMARP->allTracingOn($1)); } - | id instRangeE { $$ = new AstCell($1, GRAMMARP->m_instModuleFl, + | id instRangeListE { $$ = new AstCell($1, GRAMMARP->m_instModuleFl, *$1, GRAMMARP->m_instModule, NULL, AstPin::cloneTreeNull(GRAMMARP->m_instParamp, true), GRAMMARP->scrubRange($2)); $$->trace(GRAMMARP->allTracingOn($1)); } - //UNSUP instRangeE '(' cellpinList ')' { UNSUP } // UDP + //UNSUP instRangeListE '(' cellpinList ')' { UNSUP } // UDP // // Adding above and switching to the Verilog-Perl syntax // // causes a shift conflict due to use of idClassSel inside exprScope. // // It also breaks allowing "id foo;" instantiation syntax. ; -instRangeE: +instRangeListE: /* empty */ { $$ = NULL; } - | '[' constExpr ']' { $$ = new AstRange($1, new AstConst($1, 0), new AstSub($1, $2, new AstConst($1, 1))); } + | instRangeList { $$ = $1; } + ; + +instRangeList: + instRange { $$ = $1; } + | instRangeList instRange { $$ = VN_CAST($1->addNextNull($2), Range); } + ; + +instRange: + '[' constExpr ']' { $$ = new AstRange($1, new AstConst($1, 0), new AstSub($1, $2, new AstConst($1, 1))); } | '[' constExpr ':' constExpr ']' { $$ = new AstRange($1,$2,$4); } ; @@ -3626,7 +3635,7 @@ gateUnsupList: ; gateRangeE: - instRangeE { $$ = $1; GATERANGE(GRAMMARP->scrubRange($1)); } + instRangeListE { $$ = $1; GATERANGE(GRAMMARP->scrubRange($1)); } ; gateBuf: diff --git a/test_regress/t/t_mod_interface_array.pl b/test_regress/t/t_mod_interface_array0.pl similarity index 100% rename from test_regress/t/t_mod_interface_array.pl rename to test_regress/t/t_mod_interface_array0.pl diff --git a/test_regress/t/t_mod_interface_array.v b/test_regress/t/t_mod_interface_array0.v similarity index 100% rename from test_regress/t/t_mod_interface_array.v rename to test_regress/t/t_mod_interface_array0.v diff --git a/test_regress/t/t_mod_interface_array_noinl.pl b/test_regress/t/t_mod_interface_array0_noinl.pl similarity index 92% rename from test_regress/t/t_mod_interface_array_noinl.pl rename to test_regress/t/t_mod_interface_array0_noinl.pl index e4adc68ac..9db4bf967 100755 --- a/test_regress/t/t_mod_interface_array_noinl.pl +++ b/test_regress/t/t_mod_interface_array0_noinl.pl @@ -9,7 +9,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di scenarios(simulator => 1); -top_filename("t/t_mod_interface_array.v"); +top_filename("t/t_mod_interface_array0.v"); compile( v_flags2 => ["-Oi"], diff --git a/test_regress/t/t_mod_interface_array3.out b/test_regress/t/t_mod_interface_array3.out new file mode 100644 index 000000000..ad92220e4 --- /dev/null +++ b/test_regress/t/t_mod_interface_array3.out @@ -0,0 +1,7 @@ +%Error: t/t_mod_interface_array3.v:24: Unsupported: Multidimensional cells/interfaces. + a_if iface [2:0][1:0]; + ^ +%Error: t/t_mod_interface_array3.v:26: Unsupported: Multidimensional cells/interfaces. + sub i_sub[2:0][1:0] (.s(str)); + ^ +%Error: Exiting due to diff --git a/test_regress/t/t_mod_interface_array3.pl b/test_regress/t/t_mod_interface_array3.pl new file mode 100755 index 000000000..3361369bf --- /dev/null +++ b/test_regress/t/t_mod_interface_array3.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. + +scenarios(simulator => 1); + +compile( + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_mod_interface_array3.v b/test_regress/t/t_mod_interface_array3.v new file mode 100644 index 000000000..6e0ab4aef --- /dev/null +++ b/test_regress/t/t_mod_interface_array3.v @@ -0,0 +1,44 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2015 by Johan Bjork. + +`define checks(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); + +interface a_if (); + string s; +endinterface + +module sub (output string s); + initial s = $sformatf("%m"); +endmodule + +module t + ( + clk + ); + input clk; + + string str [2:0][1:0]; + + a_if iface [2:0][1:0]; + + sub i_sub[2:0][1:0] (.s(str)); + + initial begin + // TODO make self checking + $display(iface[0][0]); + $display(iface[0][1]); + $display(iface[1][0]); + $display(iface[1][1]); + $display(iface[2][0]); + $display(iface[2][1]); + + $display(str[0][0]); + $display(str[0][1]); + $display(str[1][0]); + $display(str[1][1]); + $display(str[2][0]); + $display(str[2][1]); + end +endmodule