Fix streaming to/from packed arrays (#5976)

bug from 6bb57e4630

Fixes RTLMeter OpenTitan. Fixes #5955.
This commit is contained in:
Geza Lore 2025-05-04 19:28:51 +01:00 committed by GitHub
parent 70c84d3abd
commit 223bb9ba9a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 96 additions and 8 deletions

View File

@ -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*"

View File

@ -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()});

View File

@ -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

View File

@ -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);