From 223bb9ba9add0b0f41d17045a2c12f50e3f8fe01 Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Sun, 4 May 2025 19:28:51 +0100 Subject: [PATCH] Fix streaming to/from packed arrays (#5976) bug from 6bb57e463035a94fafaefe652e747303f9c548e0 Fixes RTLMeter OpenTitan. Fixes #5955. --- .github/workflows/rtlmeter.yml | 4 +- src/V3Width.cpp | 5 +- test_regress/t/t_stream5.v | 15 ++++-- test_regress/t/t_stream_unpack.v | 80 ++++++++++++++++++++++++++++++++ 4 files changed, 96 insertions(+), 8 deletions(-) diff --git a/.github/workflows/rtlmeter.yml b/.github/workflows/rtlmeter.yml index 187d9d60f..cb2e43edf 100644 --- a/.github/workflows/rtlmeter.yml +++ b/.github/workflows/rtlmeter.yml @@ -52,7 +52,7 @@ jobs: - "OpenPiton:1x1:*" - "OpenPiton:2x2:*" - "OpenPiton:4x4:*" - # - "OpenTitan:*" + - "OpenTitan:*" - "VeeR-EH1:asic*" - "VeeR-EH1:default*" - "VeeR-EH1:hiperf*" @@ -92,7 +92,7 @@ jobs: - "OpenPiton:1x1:*" - "OpenPiton:2x2:*" - "OpenPiton:4x4:*" - # - "OpenTitan:*" + - "OpenTitan:*" - "VeeR-EH1:asic*" - "VeeR-EH1:default*" - "VeeR-EH1:hiperf*" diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 5e75473b2..ad749136d 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -5233,7 +5233,7 @@ class WidthVisitor final : public VNVisitor { << lwidth << " bits) is narrower than the stream (" << rwidth << " bits) (IEEE 1800-2023 11.4.14)"); } - if (VN_IS(lhsDTypeSkippedRefp, NodeArrayDType)) { + if (VN_IS(lhsDTypeSkippedRefp, UnpackArrayDType)) { streamp->unlinkFrBack(); nodep->rhsp(new AstCvtPackedToArray{streamp->fileline(), streamp, lhsDTypeSkippedRefp}); @@ -5241,7 +5241,6 @@ class WidthVisitor final : public VNVisitor { } if (const AstNodeStream* const streamp = VN_CAST(nodep->lhsp(), NodeStream)) { const AstNodeDType* const rhsDTypep = nodep->rhsp()->dtypep()->skipRefp(); - const int lwidth = widthUnpacked(streamp->lhsp()->dtypep()->skipRefp()); const int rwidth = widthUnpacked(rhsDTypep); if (rwidth != 0 && rwidth < lwidth) { @@ -5251,7 +5250,7 @@ class WidthVisitor final : public VNVisitor { << " bits, but source expression only provides " << rwidth << " bits (IEEE 1800-2023 11.4.14.3)"); } - if (VN_IS(rhsDTypep, NodeArrayDType)) { + if (VN_IS(rhsDTypep, UnpackArrayDType)) { AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack(); nodep->rhsp( new AstCvtArrayToPacked{rhsp->fileline(), rhsp, streamp->dtypep()}); diff --git a/test_regress/t/t_stream5.v b/test_regress/t/t_stream5.v index 1eab118d9..8ece51a8f 100644 --- a/test_regress/t/t_stream5.v +++ b/test_regress/t/t_stream5.v @@ -8,15 +8,21 @@ module t(/*AUTOARG*/); logic [15:0] i16; logic [15:0] o16; + logic [3:0][3:0] p16; logic [31:0] i32; logic [31:0] o32; + logic [7:0][3:0] p32; logic [63:0] i64; logic [63:0] o64; + logic [15:0][3:0] p64; always_comb begin o16 = {<<4{i16}}; + p16 = {<<4{i16}}; o32 = {<<4{i32}}; + p32 = {<<4{i32}}; o64 = {<<4{i64}}; + p64 = {<<4{i64}}; end initial begin @@ -24,12 +30,15 @@ module t(/*AUTOARG*/); i32 = 32'hcafefade; i64 = 64'hdeaddeedcafefade; #100ns; - $display("o16=0x%h i16=0x%h", o16, i16); + $display("o16=0x%h p16=0x%h i16=0x%h", o16, p16, i16); if (o16 != 16'hEDAF) $stop; - $display("o32=0x%h i32=0x%h", o32, i32); + if (p16 != 16'hEDAF) $stop; + $display("o32=0x%h p32=0x%h i32=0x%h", o32, p32, i32); if (o32 != 32'hEDAFEFAC) $stop; - $display("o64=0x%h i64=0x%h", o64, i64); + if (p32 != 32'hEDAFEFAC) $stop; + $display("o64=0x%h p64=0x%h i64=0x%h", o64, p64, i64); if (o64 != 64'hEDAFEFACDEEDDAED) $stop; + if (p64 != 64'hEDAFEFACDEEDDAED) $stop; $write("*-* All Finished *-*\n"); $finish; end diff --git a/test_regress/t/t_stream_unpack.v b/test_regress/t/t_stream_unpack.v index 895b56a5f..fce34bb57 100644 --- a/test_regress/t/t_stream_unpack.v +++ b/test_regress/t/t_stream_unpack.v @@ -20,8 +20,10 @@ module t (/*AUTOARG*/); bit6_unpacked_t arr; bit [1:0] arr2[3]; bit6_t arr6[1]; + bit6_t [0:0] parr6; bit6_t bit6 = 6'b111000; bit [5:0] ans; + bit [2:0][1:0] ans_packed; enum_t ans_enum; logic [1:0] a [3] = {1, 0, 3}; logic [1:0] b [3] = {1, 2, 0}; @@ -42,6 +44,12 @@ module t (/*AUTOARG*/); { >> bit {ans}} = arr; `checkh(ans, bit6); + ans_packed = { >> bit {arr} }; + `checkh(ans_packed, bit6); + + { >> bit {ans_packed}} = arr; + `checkh(ans_packed, bit6); + ans_enum = enum_t'({ >> bit {arr} }); `checkh(ans_enum, bit6); @@ -57,6 +65,12 @@ module t (/*AUTOARG*/); { << bit {ans} } = arr; `checkh(ans, bit6); + ans_packed = { << bit {arr} }; + `checkh(ans_packed, bit6); + + { << bit {ans_packed} } = arr; + `checkh(ans_packed, bit6); + ans_enum = enum_t'({ << bit {arr} }); `checkh(ans_enum, bit6); @@ -72,6 +86,12 @@ module t (/*AUTOARG*/); { >> bit[1:0] {ans} } = arr2; `checkh(ans, bit6); + ans_packed = { >> bit[1:0] {arr2} }; + `checkh(ans_packed, bit6); + + { >> bit[1:0] {ans_packed} } = arr2; + `checkh(ans_packed, bit6); + ans_enum = enum_t'({ >> bit[1:0] {arr2} }); `checkh(ans_enum, bit6); @@ -84,6 +104,12 @@ module t (/*AUTOARG*/); { << bit[1:0] {ans} } = arr2; `checkh(ans, bit6); + ans_packed = { << bit[1:0] {arr2} }; + `checkh(ans_packed, bit6); + + { << bit[1:0] {ans_packed} } = arr2; + `checkh(ans_packed, bit6); + ans_enum = enum_t'({ << bit[1:0] {arr2} }); `checkh(ans_enum, bit6); @@ -99,6 +125,12 @@ module t (/*AUTOARG*/); { >> bit[5:0] {ans} } = arr6; `checkh(ans, bit6); + ans_packed = { >> bit[5:0] {arr6} }; + `checkh(ans_packed, bit6); + + { >> bit[5:0] {ans_packed} } = arr6; + `checkh(ans_packed, bit6); + ans_enum = enum_t'({ >> bit[5:0] {arr6} }); `checkh(ans_enum, bit6); @@ -114,9 +146,57 @@ module t (/*AUTOARG*/); { << bit[5:0] {ans} } = arr6; `checkh(ans, bit6); + ans_packed = { << bit[5:0] {arr6} }; + `checkh(ans_packed, bit6); + + { << bit[5:0] {ans_packed} } = arr6; + `checkh(ans_packed, bit6); + ans_enum = enum_t'({ << bit[5:0] {arr6} }); `checkh(ans_enum, bit6); + { >> bit [5:0] {parr6} } = bit6; + `checkh(parr6, bit6); + + parr6 = { >> bit [5:0] {bit6}}; + `checkh(parr6, bit6); + + ans = { >> bit[5:0] {parr6} }; + `checkh(ans, bit6); + + { >> bit[5:0] {ans} } = parr6; + `checkh(ans, bit6); + + ans_packed = { >> bit[5:0] {parr6} }; + `checkh(ans_packed, bit6); + + { >> bit[5:0] {ans_packed} } = parr6; + `checkh(ans_packed, bit6); + + ans_enum = enum_t'({ >> bit[5:0] {parr6} }); + `checkh(ans_enum, bit6); + + { << bit [5:0] {parr6} } = bit6; + `checkh(parr6, bit6); + + parr6 = { << bit [5:0] {bit6}}; + `checkh(parr6, bit6); + + ans = { << bit[5:0] {parr6} }; + `checkh(ans, bit6); + + { << bit[5:0] {ans} } = parr6; + `checkh(ans, bit6); + + ans_packed = { << bit[5:0] {parr6} }; + `checkh(ans_packed, bit6); + + { << bit[5:0] {ans_packed} } = parr6; + `checkh(ans_packed, bit6); + + ans_enum = enum_t'({ << bit[5:0] {parr6} }); + `checkh(ans_enum, bit6); + d = { >> {a, b, c}}; `checkh(d, 16'b0100110110001100);