diff --git a/Changes b/Changes index 5fed7394f..a89ef1124 100644 --- a/Changes +++ b/Changes @@ -7,6 +7,8 @@ The contributors that suggested a given feature are shown in []. Thanks! **** Fix trace signal names getting hashed (#2643). [Barbara Gigerl] +**** Fix unpacked array parameters near functions (#2639). [Anderson Ignacio da Silva] + * Verilator 4.104 2020-11-14 diff --git a/src/V3Param.cpp b/src/V3Param.cpp index e27824c74..a73845d39 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -245,7 +245,6 @@ private: typedef std::deque CellList; CellList m_cellps; // Cells left to process (in this module) - AstNodeFTask* m_ftaskp = nullptr; // Function/task reference AstNodeModule* m_modp = nullptr; // Current module being processed string m_unlinkedTxt; // Text for AstUnlinkedRef UnrollStateful m_unroller; // Loop unroller @@ -605,13 +604,6 @@ private: nodep->user5p(genHierNamep); m_cellps.push_back(nodep); } - virtual void visit(AstNodeFTask* nodep) override { - VL_RESTORER(m_ftaskp); - { - m_ftaskp = nodep; - iterateChildren(nodep); - } - } // Make sure all parameters are constantified virtual void visit(AstVar* nodep) override { @@ -633,7 +625,7 @@ private: new AstAssign(nodep->fileline(), new AstVarRef(nodep->fileline(), nodep, VAccess::WRITE), nodep->valuep()->cloneTree(true)))); - if (m_ftaskp) { + if (nodep->isFuncLocal()) { // We put the initial in wrong place under a function. We // should move the parameter out of the function and to the // module, with appropriate dotting, but this confuses LinkDot @@ -648,6 +640,7 @@ private: } // Make sure varrefs cause vars to constify before things above virtual void visit(AstVarRef* nodep) override { + // Might jump across functions, so beware if ever add a m_funcp if (nodep->varp()) iterate(nodep->varp()); } bool ifaceParamReplace(AstVarXRef* nodep, AstNode* candp) { diff --git a/test_regress/t/t_param_array6.pl b/test_regress/t/t_param_array6.pl new file mode 100755 index 000000000..b46d46042 --- /dev/null +++ b/test_regress/t/t_param_array6.pl @@ -0,0 +1,21 @@ +#!/usr/bin/env 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. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(simulator => 1); + +compile( + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_param_array6.v b/test_regress/t/t_param_array6.v new file mode 100644 index 000000000..34766e731 --- /dev/null +++ b/test_regress/t/t_param_array6.v @@ -0,0 +1,61 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2020 by Anderson Ignacio da Silva. +// SPDX-License-Identifier: CC0-1.0 + +package test_pkg; + localparam [31:0] test_arr [4][4:0] + = '{ + '{'h0000, 'h1000, 'h2000, 'h3000, 'h4000}, + '{'h0FFF, 'h1FFF, 'h2FFF, 'h3FFF, 'h4FFF}, + '{ 'd0, 'd0, 'd0, 'd0, 'd0}, + '{ 'd0, 'd1, 'd2, 'd3, 'd4} + }; + + typedef struct packed{ + logic [7:0] val_1; + logic [7:0] val_2; + } test_ret_t; +endpackage + +module t import test_pkg::*; (clk); + input clk; + + function automatic test_ret_t test_f(logic [31:0] val); + test_ret_t temp; + + temp = test_ret_t'(0); + for (int i=0; i<5; i++) begin + if (val >= test_arr[0][i] && val <= test_arr[1][i]) begin + temp.val_1 = test_arr[2][i][7:0]; + temp.val_2 = test_arr[3][i][7:0]; + end + end + return temp; + endfunction + + test_ret_t temp; + logic [31:0] random; + + int cyc; + bit [63:0] sum; + + always @ (posedge clk) begin + cyc <= cyc + 1; + random <= {17'b0, cyc[3:0], 11'b0}; + temp <= test_f(random); +`ifdef TEST_VERBOSE + $display("rand: %h / Values -> val_1: %d / val_2: %d", random, temp.val_1, temp.val_2); +`endif + if (cyc > 10 && cyc < 90) begin + sum <= {48'h0, temp} ^ {sum[62:0],sum[63]^sum[2]^sum[0]}; + end + else if (cyc == 99) begin + $displayh(sum); + if (sum != 64'h74d34ea7a775f994) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end + end +endmodule