From 41a038b79b4069b7262b9cbd96b925463ccd5ab5 Mon Sep 17 00:00:00 2001 From: Todd Strader Date: Fri, 13 Dec 2024 12:00:49 -0500 Subject: [PATCH] Fix interface bracketed array parameter access (#5678) (#5677) --- src/V3Param.cpp | 29 ++++++++------ .../t/t_interface_array_parameter_access.py | 18 +++++++++ .../t/t_interface_array_parameter_access.v | 39 +++++++++++++++++++ 3 files changed, 75 insertions(+), 11 deletions(-) create mode 100755 test_regress/t/t_interface_array_parameter_access.py create mode 100644 test_regress/t/t_interface_array_parameter_access.v diff --git a/src/V3Param.cpp b/src/V3Param.cpp index fd5479feb..0d6a3c6ca 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -1249,18 +1249,25 @@ class ParamVisitor final : public VNVisitor { UINFO(9, "Hit module boundary, done looking for interface" << endl); break; } - if (VN_IS(backp, Var) && VN_AS(backp, Var)->isIfaceRef() - && VN_AS(backp, Var)->childDTypep() - && (VN_CAST(VN_CAST(backp, Var)->childDTypep(), IfaceRefDType) - || (VN_CAST(VN_CAST(backp, Var)->childDTypep(), UnpackArrayDType) - && VN_CAST(VN_CAST(backp, Var)->childDTypep()->getChildDTypep(), - IfaceRefDType)))) { - const AstIfaceRefDType* ifacerefp - = VN_CAST(VN_CAST(backp, Var)->childDTypep(), IfaceRefDType); - if (!ifacerefp) { - ifacerefp = VN_CAST(VN_CAST(backp, Var)->childDTypep()->getChildDTypep(), - IfaceRefDType); + if (const AstVar* const varp = VN_CAST(backp, Var)) { + if (!varp->isIfaceRef()) { continue; } + const AstIfaceRefDType* ifacerefp = nullptr; + if (const AstNodeDType* const typep = varp->childDTypep()) { + ifacerefp = VN_CAST(typep, IfaceRefDType); + if (!ifacerefp) { + if (const AstUnpackArrayDType* const unpackp + = VN_CAST(typep, UnpackArrayDType)) { + ifacerefp = VN_CAST(typep->getChildDTypep(), IfaceRefDType); + } + } + if (!ifacerefp) { + if (const AstBracketArrayDType* const unpackp + = VN_CAST(typep, BracketArrayDType)) { + ifacerefp = VN_CAST(typep->subDTypep(), IfaceRefDType); + } + } } + if (!ifacerefp) { continue; } // Interfaces passed in on the port map have ifaces if (const AstIface* const ifacep = ifacerefp->ifacep()) { if (dotted == backp->name()) { diff --git a/test_regress/t/t_interface_array_parameter_access.py b/test_regress/t/t_interface_array_parameter_access.py new file mode 100755 index 000000000..d4f986441 --- /dev/null +++ b/test_regress/t/t_interface_array_parameter_access.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_interface_array_parameter_access.v b/test_regress/t/t_interface_array_parameter_access.v new file mode 100644 index 000000000..33de01a6a --- /dev/null +++ b/test_regress/t/t_interface_array_parameter_access.v @@ -0,0 +1,39 @@ +// DESCRIPTION: Verilator: Get parameter from array of interfaces +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2024 by Todd Strader +// SPDX-License-Identifier: CC0-1.0 + +interface intf + #(parameter int FOO = 4) + (input wire clk, + input wire rst); + modport modp (input clk, rst); +endinterface + +module sub (intf.modp the_intf_port [4]); + localparam int intf_foo = the_intf_port[0].FOO; + + initial begin + if (intf_foo != 4) $stop; + end +endmodule + +module t ( + clk +); + logic rst; + input clk; + + intf the_intf [4] (.*); + + sub + the_sub ( + .the_intf_port (the_intf) + ); + + always @(posedge clk) begin + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule