From 6006cdff2c886bc51c235e1a186dca322a516927 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 19 Sep 2017 20:04:45 -0400 Subject: [PATCH] Fix wide array indices causing compile error. --- Changes | 2 ++ src/V3Premit.cpp | 30 +++++++++++++++++++++++------- test_regress/t/t_arraysel_wide.pl | 14 ++++++++++++++ test_regress/t/t_arraysel_wide.v | 29 +++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 7 deletions(-) create mode 100755 test_regress/t/t_arraysel_wide.pl create mode 100644 test_regress/t/t_arraysel_wide.v diff --git a/Changes b/Changes index a6baf97df..1757bb35b 100644 --- a/Changes +++ b/Changes @@ -26,6 +26,8 @@ The contributors that suggested a given feature are shown in []. Thanks! **** Fix .name connections on interfaces, bug1214. [Mike Popoloski] +**** Fix wide array indices causing compile error. + * Verilator 3.910 2017-09-07 diff --git a/src/V3Premit.cpp b/src/V3Premit.cpp index 690e42007..c3fe7a17e 100644 --- a/src/V3Premit.cpp +++ b/src/V3Premit.cpp @@ -135,7 +135,7 @@ private: // ARRAYSEL(*here*, ...) (No wides can be in any argument but first, so we don't check which arg is wide) // ASSIGN(x, SEL*HERE*(ARRAYSEL()...) (m_assignLhs==true handles this.) //UINFO(9, " Check: "<isWide()?"Y":"N")<user1()) { // Not already done if (nodep->isWide()) { @@ -321,13 +321,17 @@ private: } // Operators virtual void visit(AstNodeTermop* nodep) { - nodep->iterateChildren(*this); checkNode(nodep); } + nodep->iterateChildren(*this); checkNode(nodep); + } virtual void visit(AstNodeUniop* nodep) { - nodep->iterateChildren(*this); checkNode(nodep); } + nodep->iterateChildren(*this); checkNode(nodep); + } virtual void visit(AstNodeBiop* nodep) { - nodep->iterateChildren(*this); checkNode(nodep); } + nodep->iterateChildren(*this); checkNode(nodep); + } virtual void visit(AstUCFunc* nodep) { - nodep->iterateChildren(*this); checkNode(nodep); } + nodep->iterateChildren(*this); checkNode(nodep); + } virtual void visit(AstSel* nodep) { nodep->fromp()->iterateAndNext(*this); { // Only the 'from' is part of the assignment LHS @@ -337,9 +341,21 @@ private: nodep->widthp()->iterateAndNext(*this); m_assignLhs = prevAssign; } - checkNode(nodep); } + checkNode(nodep); + } + virtual void visit(AstArraySel* nodep) { + nodep->fromp()->iterateAndNext(*this); + { // Only the 'from' is part of the assignment LHS + bool prevAssign = m_assignLhs; + m_assignLhs = false; + nodep->bitp()->iterateAndNext(*this); + m_assignLhs = prevAssign; + } + checkNode(nodep); + } virtual void visit(AstConst* nodep) { - nodep->iterateChildren(*this); checkNode(nodep); } + nodep->iterateChildren(*this); checkNode(nodep); + } virtual void visit(AstNodeCond* nodep) { nodep->iterateChildren(*this); if (nodep->expr1p()->isWide() diff --git a/test_regress/t/t_arraysel_wide.pl b/test_regress/t/t_arraysel_wide.pl new file mode 100755 index 000000000..385b6a57e --- /dev/null +++ b/test_regress/t/t_arraysel_wide.pl @@ -0,0 +1,14 @@ +#!/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 ( + ); + +ok(1); +1; diff --git a/test_regress/t/t_arraysel_wide.v b/test_regress/t/t_arraysel_wide.v new file mode 100644 index 000000000..f00f68a00 --- /dev/null +++ b/test_regress/t/t_arraysel_wide.v @@ -0,0 +1,29 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2017 by Wilson Snyder. + +module t (/*AUTOARG*/ + // Outputs + nnext, + // Inputs + inibble, onibble + ); + + input [3:0] inibble; + input [106:0] onibble; + + output reg [3:0] nnext [0:7]; + + // verilator lint_off WIDTH + wire [2:0] selline = (onibble >>> 102) & 7; + // verilator lint_on WIDTH + + always_comb begin + for (integer i=0; i<8; i=i+1) begin + nnext[i] = '0; + end + nnext[selline] = inibble; + end + +endmodule