From 6c6f03cf7c05987245dbb421166cd451f853d478 Mon Sep 17 00:00:00 2001 From: Ryszard Rozak Date: Tue, 12 Sep 2023 17:06:12 +0200 Subject: [PATCH] Fix static cast from a stream type (#4469) (#4485) --- src/V3Width.cpp | 12 +++++++----- test_regress/t/t_stream_dynamic.v | 25 ++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/V3Width.cpp b/src/V3Width.cpp index e428c072a..eaffda787 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -1970,8 +1970,10 @@ private: newp = new AstNToI{nodep->fileline(), nodep->fromp()->unlinkFrBack(), toDtp}; } else if (!basicp->isDouble() && !fromDtp->isDouble()) { AstNodeDType* const origDTypep = nodep->dtypep(); - const int width = toDtp->width(); - castSized(nodep, nodep->fromp(), width); + if (!VN_IS(fromDtp, StreamDType)) { + const int width = toDtp->width(); + castSized(nodep, nodep->fromp(), width); + } nodep->dtypeFrom(origDTypep); // If was enum, need dtype to preserve as enum // Note castSized might modify nodep->fromp() } else { @@ -7362,9 +7364,9 @@ private: // UNSUP unpacked struct/unions (treated like BasicDType) const AstNodeDType* fromBaseDtp = computeCastableBase(fromDtp); - const bool fromNumericable = VN_IS(fromBaseDtp, BasicDType) - || VN_IS(fromBaseDtp, EnumDType) - || VN_IS(fromBaseDtp, NodeUOrStructDType); + const bool fromNumericable + = VN_IS(fromBaseDtp, BasicDType) || VN_IS(fromBaseDtp, EnumDType) + || VN_IS(fromBaseDtp, StreamDType) || VN_IS(fromBaseDtp, NodeUOrStructDType); const AstNodeDType* toBaseDtp = computeCastableBase(toDtp); const bool toNumericable diff --git a/test_regress/t/t_stream_dynamic.v b/test_regress/t/t_stream_dynamic.v index 0c02f1db8..f92b250ea 100644 --- a/test_regress/t/t_stream_dynamic.v +++ b/test_regress/t/t_stream_dynamic.v @@ -8,15 +8,20 @@ `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); `define checks(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); +typedef enum bit [5:0] { + A = 6'b111000, + B = 6,b111111 +} enum_t; + module t (/*AUTOARG*/); initial begin bit arr[]; bit [1:0] arr2[$]; - bit [4:0] arr5[]; bit [5:0] arr6[$]; string v; bit [5:0] bit6 = 6'b111000; bit [5:0] ans; + enum_t ans_enum; { >> bit {arr}} = bit6; v = $sformatf("%p", arr); `checks(v, "'{'h0, 'h0, 'h0, 'h1, 'h1, 'h1} "); @@ -24,36 +29,54 @@ module t (/*AUTOARG*/); ans = { >> bit {arr} }; `checkh(ans, bit6); + ans_enum = enum_t'({ >> bit {arr} }); + `checkh(ans_enum, bit6); + { << bit {arr}} = bit6; v = $sformatf("%p", arr); `checks(v, "'{'h1, 'h1, 'h1, 'h0, 'h0, 'h0} "); ans = { << bit {arr} }; `checkh(ans, bit6); + ans_enum = enum_t'({ << bit {arr} }); + `checkh(ans_enum, bit6); + { >> bit[1:0] {arr2}} = bit6; v = $sformatf("%p", arr2); `checks(v, "'{'h0, 'h2, 'h3} "); ans = { >> bit[1:0] {arr2} }; `checkh(ans, bit6); + ans_enum = enum_t'({ >> bit[1:0] {arr2} }); + `checkh(ans_enum, bit6); + { << bit[1:0] {arr2}} = bit6; v = $sformatf("%p", arr2); `checks(v, "'{'h3, 'h2, 'h0} "); ans = { << bit[1:0] {arr2} }; `checkh(ans, bit6); + ans_enum = enum_t'({ << bit[1:0] {arr2} }); + `checkh(ans_enum, bit6); + { >> bit [5:0] {arr6} } = bit6; v = $sformatf("%p", arr6); `checks(v, "'{'h38} "); ans = { >> bit[5:0] {arr6} }; `checkh(ans, bit6); + ans_enum = enum_t'({ >> bit[5:0] {arr6} }); + `checkh(ans_enum, bit6); + { << bit [5:0] {arr6} } = bit6; v = $sformatf("%p", arr6); `checks(v, "'{'h38} "); ans = { << bit[5:0] {arr6} }; `checkh(ans, bit6); + ans_enum = enum_t'({ << bit[5:0] {arr6} }); + `checkh(ans_enum, bit6); + $write("*-* All Finished *-*\n"); $finish; end