From d400584460dc068bd2cd355a31b7dde7caa6f231 Mon Sep 17 00:00:00 2001 From: Todd Strader Date: Wed, 21 May 2025 08:41:29 -0400 Subject: [PATCH] Fix concatenation and type casting (#6012) (#6013) --- src/V3Width.cpp | 6 +++++ test_regress/t/t_concat_casts.py | 18 ++++++++++++++ test_regress/t/t_concat_casts.v | 41 ++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100755 test_regress/t/t_concat_casts.py create mode 100644 test_regress/t/t_concat_casts.v diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 328f2e0da..ee596ee6c 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -2112,6 +2112,7 @@ class WidthVisitor final : public VNVisitor { VFlagChildDType{}, refp}; nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); + userIterate(newp, m_vup); } else { nodep->v3warn(E_UNSUPPORTED, "Unsupported: Cast to " << nodep->dtp()->prettyTypeName()); @@ -2126,6 +2127,11 @@ class WidthVisitor final : public VNVisitor { if (m_vup->prelim()) { if (debug() >= 9) nodep->dumpTree("- CastPre: "); // if (debug()) nodep->backp()->dumpTree("- CastPreUpUp: "); + if (AstSigned* const fromp = VN_CAST(nodep->fromp(), Signed)) { + AstNode* const lhsp = fromp->lhsp()->unlinkFrBack(); + fromp->replaceWith(lhsp); + VL_DO_DANGLING(fromp->deleteTree(), fromp); + } userIterateAndNext(nodep->fromp(), WidthVP{SELF, PRELIM}.p()); if (debug() >= 9) nodep->dumpTree("- CastDit: "); AstNodeDType* const toDtp = nodep->dtypep()->skipRefToEnump(); diff --git a/test_regress/t/t_concat_casts.py b/test_regress/t/t_concat_casts.py new file mode 100755 index 000000000..c39e83d77 --- /dev/null +++ b/test_regress/t/t_concat_casts.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 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_concat_casts.v b/test_regress/t/t_concat_casts.v new file mode 100644 index 000000000..beb5c8637 --- /dev/null +++ b/test_regress/t/t_concat_casts.v @@ -0,0 +1,41 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2025 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +package my_pkg; + typedef enum logic [1:0] { + SIG_0, SIG_1, SIG_2 + } sig_t; +endpackage : my_pkg + + +module t; + import my_pkg::*; + + typedef logic [7:0] foo_t; + typedef logic [31:0] bar_t; + + bar_t [1:0] the_bars; + + foo_t [0:0][1:0] the_foos; + + always_comb begin + the_bars = {32'd7, 32'd8}; + the_foos[0] = {foo_t'(the_bars[1]), foo_t'(the_bars[0])}; + end + + logic [6:0] data; + logic [2:0] opt; + + assign data = 7'b110_0101; + assign opt = {data[5], sig_t'(data[1:0])}; + + initial begin + if (the_foos != 'h0708) $stop(); + if (opt != 'b101) $stop(); + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule