From 1665d15d4df566f352458fb610062314f1659371 Mon Sep 17 00:00:00 2001 From: Todd Strader Date: Fri, 20 Sep 2024 14:29:31 -0400 Subject: [PATCH] Fix user-type parameter overlap (#5469) --- src/V3Param.cpp | 17 ++++++ test_regress/t/t_interface_derived_type.py | 18 +++++++ test_regress/t/t_interface_derived_type.v | 62 ++++++++++++++++++++++ 3 files changed, 97 insertions(+) create mode 100755 test_regress/t/t_interface_derived_type.py create mode 100644 test_regress/t/t_interface_derived_type.v diff --git a/src/V3Param.cpp b/src/V3Param.cpp index 41d50dc49..e29a10f63 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -348,7 +348,24 @@ class ParamProcessor final { if (dtypep->isRanged()) { key += "[" + cvtToStr(dtypep->left()) + ":" + cvtToStr(dtypep->right()) + "]"; } + } else if (const AstPackArrayDType* const dtypep = VN_CAST(nodep, PackArrayDType)) { + key += "["; + key += cvtToStr(dtypep->left()); + key += ":"; + key += cvtToStr(dtypep->right()); + key += "] "; + key += paramValueString(dtypep->subDTypep()); + } else if (const AstInitArray* const initp = VN_CAST(nodep, InitArray)) { + key += "{"; + for (auto it : initp->map()) { + key += paramValueString(it.second->valuep()); + key += ","; + } + key += "}"; + } else if (const AstNodeDType* const dtypep = VN_CAST(nodep, NodeDType)) { + key += dtypep->prettyDTypeName(true); } + UASSERT_OBJ(!key.empty(), nodep, "Parameter yielded no value string"); return key; } diff --git a/test_regress/t/t_interface_derived_type.py b/test_regress/t/t_interface_derived_type.py new file mode 100755 index 000000000..d4f986441 --- /dev/null +++ b/test_regress/t/t_interface_derived_type.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_derived_type.v b/test_regress/t/t_interface_derived_type.v new file mode 100644 index 000000000..cee8559bc --- /dev/null +++ b/test_regress/t/t_interface_derived_type.v @@ -0,0 +1,62 @@ +// DESCRIPTION: Verilator: SystemVerilog interface test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2012 by Iztok Jeras. +// SPDX-License-Identifier: CC0-1.0 + +interface intf #( + parameter type data_t = bit, + parameter int arr[2][4] +) (); + data_t data; + // TODO -- some kind of issue with multi-dimensional array constness: + // %Error: t/t_interface_derived_type.v:12:12: Expecting expression to be constant, but variable isn't const: 'arr' + // : ... note: In instance 't.sub16' + // 19 | logic [arr[0][0]-1:0] other_data; + // | ^~~ + // `define SHOW_2D_BUG + `ifdef SHOW_2D_BUG + logic [arr[0][0]-1:0] other_data; + `else + logic [$bits(data)-1:0] other_data; + `endif +endinterface + +module t (/*AUTOARG*/ + // Inputs + clk + ); + + input clk; + + // finish report + always @ (posedge clk) begin + $write("*-* All Finished *-*\n"); + $finish; + end + + sub #(.width(8), .arr('{'{8, 2, 3, 4}, '{1, 2, 3, 4}})) sub8 (); + sub #(.width(16), .arr('{'{16, 2, 3, 4}, '{1, 2, 3, 4}})) sub16 (); + +endmodule + +module sub #( + parameter int width, + parameter int arr[2][4] +) (); + typedef struct packed { + logic [3:3] [0:0] [width-1:0] field; + } user_type_t; + + intf #( + .data_t(user_type_t), + .arr(arr) + ) the_intf (); + + logic [width-1:0] signal; + + always_comb begin + the_intf.data.field = signal; + the_intf.other_data = signal; + end +endmodule