diff --git a/src/V3AstNodeExpr.h b/src/V3AstNodeExpr.h index 5b2bb9d43..185ac1484 100644 --- a/src/V3AstNodeExpr.h +++ b/src/V3AstNodeExpr.h @@ -4426,6 +4426,21 @@ public: bool sizeMattersLhs() const override { return false; } int instrCount() const override { return widthInstrs() * 16; } }; +class AstCastWrap final : public AstNodeUniop { + // A cast which has been expanded and the LHSP does all the lifting + // This remains until V3Width final commit pass to suppress ENUMVALUE warnings +public: + AstCastWrap(FileLine* fl, AstNodeExpr* lhsp) + : ASTGEN_SUPER_CastWrap(fl, lhsp) {} + ASTGEN_MEMBERS_AstCastWrap; + void numberOperate(V3Number& out, const V3Number& lhs) override { out.opAssign(lhs); } + string emitVerilog() override { return "(%l)"; } + string emitC() override { V3ERROR_NA_RETURN(""); } + bool cleanOut() const override { return false; } + bool cleanLhs() const override { return false; } + bool sizeMattersLhs() const override { return false; } + int instrCount() const override { return 0; } +}; class AstCountOnes final : public AstNodeUniop { // Number of bits set in vector public: diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 2632f7679..aa1de5970 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -1861,7 +1861,7 @@ private: UINFO(9, "CAST " << nodep << endl); nodep->dtypep(iterateEditMoveDTypep(nodep, nodep->subDTypep())); if (m_vup->prelim()) { - // if (debug()) nodep->dumpTree("- CastPre: "); + if (debug() >= 9) nodep->dumpTree("- CastPre: "); // if (debug()) nodep->backp()->dumpTree("- CastPreUpUp: "); userIterateAndNext(nodep->fromp(), WidthVP{SELF, PRELIM}.p()); AstNodeDType* const toDtp = nodep->dtypep()->skipRefToEnump(); @@ -1937,19 +1937,22 @@ private: } if (!newp) newp = nodep->fromp()->unlinkFrBack(); nodep->fromp(newp); - // if (debug()) nodep->dumpTree("- CastOut: "); + if (debug() >= 9) nodep->dumpTree("- CastOut: "); // if (debug()) nodep->backp()->dumpTree("- CastOutUpUp: "); } if (m_vup->final()) { - // if (debug()) nodep->dumpTree(cout, "- CastFPit: "); + if (debug() >= 9) nodep->dumpTree(cout, "- CastFPit: "); iterateCheck(nodep, "value", nodep->fromp(), SELF, FINAL, nodep->fromp()->dtypep(), EXTEND_EXP, false); - AstNode* const underp = nodep->fromp()->unlinkFrBack(); - // if (debug()) underp->dumpTree("- CastRep: "); + if (debug() >= 9) nodep->dumpTree("- CastFin: "); + AstNodeExpr* const underp = nodep->fromp()->unlinkFrBack(); underp->dtypeFrom(nodep); - nodep->replaceWith(underp); - VL_DO_DANGLING(pushDeletep(nodep), nodep); underp->didWidth(true); + AstNodeExpr* const newp = new AstCastWrap{nodep->fileline(), underp}; + newp->didWidth(true); + if (debug() >= 9) newp->dumpTree("- CastRep: "); + nodep->replaceWith(newp); + VL_DO_DANGLING(pushDeletep(nodep), nodep); } } void visit(AstCastSize* nodep) override { @@ -1974,6 +1977,10 @@ private: } // if (debug()) nodep->dumpTree("- CastSizeOut: "); } + void visit(AstCastWrap* nodep) override { + // Inserted by V3Width only so we know has been resolved + UASSERT_OBJ(nodep->didWidth(), nodep, "CastWrap should have width'ed earlier"); + } void castSized(AstNode* nodep, AstNode* underp, int width) { const AstBasicDType* underDtp = VN_CAST(underp->dtypep(), BasicDType); if (!underDtp) underDtp = underp->dtypep()->basicp(); diff --git a/src/V3WidthCommit.h b/src/V3WidthCommit.h index 5b262b058..f9b2e191b 100644 --- a/src/V3WidthCommit.h +++ b/src/V3WidthCommit.h @@ -177,6 +177,13 @@ private: } editDType(nodep); } + void visit(AstCastWrap* nodep) override { + iterateChildren(nodep); + editDType(nodep); + UINFO(6, " Replace " << nodep << " w/ " << nodep->lhsp() << endl); + nodep->replaceWith(nodep->lhsp()->unlinkFrBack()); + VL_DO_DANGLING(pushDeletep(nodep), nodep); + } void visit(AstNodeDType* nodep) override { // visitIterateNodeDType(nodep); } diff --git a/test_regress/t/t_cast_param_type.pl b/test_regress/t/t_cast_param_type.pl new file mode 100755 index 000000000..09b2ce4eb --- /dev/null +++ b/test_regress/t/t_cast_param_type.pl @@ -0,0 +1,17 @@ +#!/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(linter => 1); + +lint( + ); + +ok(1); +1; diff --git a/test_regress/t/t_cast_param_type.v b/test_regress/t/t_cast_param_type.v new file mode 100644 index 000000000..81b24c854 --- /dev/null +++ b/test_regress/t/t_cast_param_type.v @@ -0,0 +1,23 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2022 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +typedef enum logic [1:0] {A, B, C } letters_t; + +module SubA + #(parameter letters_t LETTER = A) + (); +endmodule + +module SubB + #(parameter letters_t LETTER = letters_t'(0)) + (); +endmodule + +module t (); + SubA suba0 (); + SubA #(.LETTER(letters_t'(1))) suba1 (); + SubB #(.LETTER(letters_t'(1))) subb2 (); +endmodule diff --git a/test_regress/t/t_debug_emitv.out b/test_regress/t/t_debug_emitv.out index ac753a612..dc2725f00 100644 --- a/test_regress/t/t_debug_emitv.out +++ b/test_regress/t/t_debug_emitv.out @@ -7,7 +7,7 @@ module Vt_debug_emitv_t; ???? // ENUMITEM 'ZERO' 32'h0 ???? // ENUMITEM 'ONE' - 'sh1 + 32'h1 ???? // REFDTYPE 'e_t' struct packed {