From 0892b39ad2e43ada3787576c2897b8e60d4d194f Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Fri, 23 Feb 2024 08:53:42 +0000 Subject: [PATCH] Fix incorrect code generation for change expression on typedefed unpacked array (#4915) --- src/V3SenExprBuilder.h | 5 +++-- test_regress/t/t_unopt_array.v | 13 +++++++++---- test_regress/t/t_unopt_array_typedef.pl | 24 ++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 6 deletions(-) create mode 100755 test_regress/t/t_unopt_array_typedef.pl diff --git a/src/V3SenExprBuilder.h b/src/V3SenExprBuilder.h index 203f446fb..8d0bba03c 100644 --- a/src/V3SenExprBuilder.h +++ b/src/V3SenExprBuilder.h @@ -139,7 +139,8 @@ class SenExprBuilder final { return prevp; } - if (AstUnpackArrayDType* const dtypep = VN_CAST(exprp->dtypep(), UnpackArrayDType)) { + if (AstUnpackArrayDType* const dtypep + = VN_CAST(exprp->dtypep()->skipRefp(), UnpackArrayDType)) { AstCMethodHard* const cmhp = new AstCMethodHard{flp, wrPrev(), "assign", rdCurr()}; cmhp->dtypeSetVoid(); m_postUpdates.push_back(cmhp->makeStmt()); @@ -167,7 +168,7 @@ class SenExprBuilder final { return {nullptr, false}; // We already warn for this in V3LinkResolve case VEdgeType::ET_CHANGED: case VEdgeType::ET_HYBRID: // - if (VN_IS(senp->dtypep(), UnpackArrayDType)) { + if (VN_IS(senp->dtypep()->skipRefp(), UnpackArrayDType)) { AstCMethodHard* const resultp = new AstCMethodHard{flp, currp(), "neq", prevp()}; resultp->dtypeSetBit(); return {resultp, true}; diff --git a/test_regress/t/t_unopt_array.v b/test_regress/t/t_unopt_array.v index 9f3bc9718..899315663 100644 --- a/test_regress/t/t_unopt_array.v +++ b/test_regress/t/t_unopt_array.v @@ -74,18 +74,23 @@ module Test (/*AUTOARG*/ input [31:0] in; output wire [31:0] out; - reg [31:0] stage [3:0]; +`ifdef USE_TYPEDEF + typedef reg [3:0][31:0] stage_t [3:0]; + stage_t stage; +`else + reg [3:0][31:0] stage [3:0]; +`endif genvar g; generate for (g=0; g<4; g++) begin always_comb begin - if (g==0) stage[g] = in; - else stage[g] = {stage[g-1][30:0],1'b1}; + if (g==0) stage[g] = {4{in}}; + else stage[g] = {4{stage[g-1][0][30:0],1'b1}}; end end endgenerate - assign out = stage[3]; + assign out = stage[3][0]; endmodule diff --git a/test_regress/t/t_unopt_array_typedef.pl b/test_regress/t/t_unopt_array_typedef.pl new file mode 100755 index 000000000..ecce1d841 --- /dev/null +++ b/test_regress/t/t_unopt_array_typedef.pl @@ -0,0 +1,24 @@ +#!/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); + +top_filename("t/t_unopt_array.v"); + +compile( + verilator_flags2 => ["-Wno-UNOPTFLAT +define+USE_TYPEDEF"], + ); + +execute( + check_finished => 1, + ); + +ok(1); +1;