From 9dc01cf5402c31f69f49d7d0ab751a8543f3edaa Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 2 May 2017 19:16:54 -0400 Subject: [PATCH] Support arrayed parameter overrides, bug1153. --- Changes | 4 +++- src/V3Const.cpp | 8 ++++++++ src/V3Param.cpp | 10 ++++++++-- src/verilog.l | 2 +- test_regress/t/t_param_array2.pl | 18 ++++++++++++++++++ test_regress/t/t_param_array2.v | 21 +++++++++++++++++++++ 6 files changed, 59 insertions(+), 4 deletions(-) create mode 100755 test_regress/t/t_param_array2.pl create mode 100644 test_regress/t/t_param_array2.v diff --git a/Changes b/Changes index f278ae6f5..386df678c 100644 --- a/Changes +++ b/Changes @@ -5,7 +5,9 @@ The contributors that suggested a given feature are shown in []. Thanks! * Verilator 3.903 devel -*** Support ports of array of reals, bug1154. [J Briquet] +*** Support ports of array of reals, bug1154. [J Briquet] + +*** Support arrayed parameter overrides, bug1153. [John Stevenson] **** Fix non-arrayed cells with interface arrays, bug1153. [John Stevenson] diff --git a/src/V3Const.cpp b/src/V3Const.cpp index fc704bc64..22aae59d1 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -1491,6 +1491,14 @@ private: did=true; } } + else if (m_params && valuep->castInitArray() && nodep->backp()->castPin()) { + // Allow parameters to pass arrays + // Earlier recursion of InitArray made sure each array value is constant + // This exception is fairly fragile, i.e. doesn't support arrays of arrays or other stuff + AstNode* newp = valuep->cloneTree(false); + nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep); + did = true; + } } } if (!did && m_required) { diff --git a/src/V3Param.cpp b/src/V3Param.cpp index c0fdce4ef..f68d6e254 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -493,6 +493,12 @@ void ParamVisitor::visitCell(AstCell* nodep) { if (AstVar* modvarp = pinp->modVarp()) { if (!modvarp->isGParam()) { pinp->v3error("Attempted parameter setting of non-parameter: Param "<prettyName()<<" of "<prettyName()); + } else if (pinp->exprp()->castInitArray() + && modvarp->subDTypep()->castUnpackArrayDType()) { + // Array assigned to array + AstNode* exprp = pinp->exprp(); + longname += "_" + paramSmallName(nodep->modp(),modvarp)+paramValueNumber(exprp); + any_overrides = true; } else { AstConst* exprp = pinp->exprp()->castConst(); AstConst* origp = modvarp->valuep()->castConst(); @@ -651,11 +657,11 @@ void ParamVisitor::visitCell(AstCell* nodep) { for (AstPin* pinp = nodep->paramsp(); pinp; pinp=pinp->nextp()->castPin()) { if (pinp->exprp()) { if (AstVar* modvarp = pinp->modVarp()) { - AstConst* constp = pinp->exprp()->castConst(); + AstNode* newp = pinp->exprp(); // Const or InitArray // Remove any existing parameter if (modvarp->valuep()) modvarp->valuep()->unlinkFrBack()->deleteTree(); // Set this parameter to value requested by cell - modvarp->valuep(constp->cloneTree(false)); + modvarp->valuep(newp->cloneTree(false)); } else if (AstParamTypeDType* modptp = pinp->modPTypep()) { AstNodeDType* dtypep = pinp->exprp()->castNodeDType(); diff --git a/src/verilog.l b/src/verilog.l index 25e1f14b5..78bd21c46 100644 --- a/src/verilog.l +++ b/src/verilog.l @@ -873,7 +873,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} /* Attributes */ /* Note simulators vary in support for "(* /_*something*_/ foo*)" where _ doesn't exist */ { - "(*"({ws}|{crnl})*({id}|{escid}) { yymore(); yy_push_state(ATTRMODE); } // Doesn't match (*), but (* attr_spec + "(*"({ws}|{crnl})*({id}|{escid}) { yymore(); yy_push_state(ATTRMODE); } /* Doesn't match (*), but (* attr_spec */ } /************************************************************************/ diff --git a/test_regress/t/t_param_array2.pl b/test_regress/t/t_param_array2.pl new file mode 100755 index 000000000..f91289753 --- /dev/null +++ b/test_regress/t/t_param_array2.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_param_array2.v b/test_regress/t/t_param_array2.v new file mode 100644 index 000000000..93bde7de4 --- /dev/null +++ b/test_regress/t/t_param_array2.v @@ -0,0 +1,21 @@ +// 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; + localparam int c[4] = '{5, 6, 7, 8}; + a #(.p(c)) i_a (); +endmodule + +module a + #( parameter int p[4] = '{1, 2, 3, 4} ); + initial begin + if (p[0] != 5) $stop; + if (p[1] != 6) $stop; + if (p[2] != 7) $stop; + if (p[3] != 8) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule