parent
7336b9ebfc
commit
10c3320c6b
|
|
@ -196,6 +196,7 @@ Ricardo Barbedo
|
||||||
Richard Myers
|
Richard Myers
|
||||||
Risto Pejašinović
|
Risto Pejašinović
|
||||||
Robert Balas
|
Robert Balas
|
||||||
|
Robin Heinemann
|
||||||
Rupert Swarbrick
|
Rupert Swarbrick
|
||||||
Ryan Ziegler
|
Ryan Ziegler
|
||||||
Ryszard Rozak
|
Ryszard Rozak
|
||||||
|
|
|
||||||
|
|
@ -1388,13 +1388,20 @@ public:
|
||||||
string verilogKwd() const override { return "struct"; }
|
string verilogKwd() const override { return "struct"; }
|
||||||
};
|
};
|
||||||
class AstUnionDType final : public AstNodeUOrStructDType {
|
class AstUnionDType final : public AstNodeUOrStructDType {
|
||||||
|
bool m_isSoft; // Is a "union soft"
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// UNSUP: bool isTagged;
|
// UNSUP: bool isTagged;
|
||||||
// VSigning below is mispurposed to indicate if packed or not
|
// VSigning below is mispurposed to indicate if packed or not
|
||||||
AstUnionDType(FileLine* fl, VSigning numericUnpack)
|
// isSoft implies packed
|
||||||
: ASTGEN_SUPER_UnionDType(fl, numericUnpack) {}
|
AstUnionDType(FileLine* fl, bool isSoft, VSigning numericUnpack)
|
||||||
|
: ASTGEN_SUPER_UnionDType(fl, numericUnpack)
|
||||||
|
, m_isSoft(isSoft) {
|
||||||
|
packed(packed() | m_isSoft);
|
||||||
|
}
|
||||||
ASTGEN_MEMBERS_AstUnionDType;
|
ASTGEN_MEMBERS_AstUnionDType;
|
||||||
string verilogKwd() const override { return "union"; }
|
string verilogKwd() const override { return "union"; }
|
||||||
|
bool isSoft() const { return m_isSoft; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // Guard
|
#endif // Guard
|
||||||
|
|
|
||||||
|
|
@ -2882,10 +2882,14 @@ class WidthVisitor final : public VNVisitor {
|
||||||
pushDeletep(itemp->valuep()->unlinkFrBack());
|
pushDeletep(itemp->valuep()->unlinkFrBack());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const bool isHardPackedUnion
|
||||||
|
= nodep->packed() && VN_IS(nodep, UnionDType) && !VN_CAST(nodep, UnionDType)->isSoft();
|
||||||
|
|
||||||
// Determine bit assignments and width
|
// Determine bit assignments and width
|
||||||
if (VN_IS(nodep, UnionDType) || nodep->packed()) {
|
if (VN_IS(nodep, UnionDType) || nodep->packed()) {
|
||||||
int lsb = 0;
|
int lsb = 0;
|
||||||
int width = 0;
|
int width = 0;
|
||||||
|
bool first = true;
|
||||||
// Report errors on first member first
|
// Report errors on first member first
|
||||||
AstMemberDType* itemp;
|
AstMemberDType* itemp;
|
||||||
// MSB is first, so loop backwards
|
// MSB is first, so loop backwards
|
||||||
|
|
@ -2895,11 +2899,17 @@ class WidthVisitor final : public VNVisitor {
|
||||||
if (itemp->isFourstate()) nodep->isFourstate(true);
|
if (itemp->isFourstate()) nodep->isFourstate(true);
|
||||||
itemp->lsb(lsb);
|
itemp->lsb(lsb);
|
||||||
if (VN_IS(nodep, UnionDType)) {
|
if (VN_IS(nodep, UnionDType)) {
|
||||||
width = std::max(width, itemp->width());
|
const int itemWidth = itemp->width();
|
||||||
|
if (!first && isHardPackedUnion && itemWidth != width) {
|
||||||
|
itemp->v3error("Hard packed union members must have equal size "
|
||||||
|
"(IEEE 1800-2023 7.3.1)");
|
||||||
|
}
|
||||||
|
width = std::max(width, itemWidth);
|
||||||
} else {
|
} else {
|
||||||
lsb += itemp->width();
|
lsb += itemp->width();
|
||||||
width += itemp->width();
|
width += itemp->width();
|
||||||
}
|
}
|
||||||
|
first = false;
|
||||||
}
|
}
|
||||||
nodep->widthForce(width, width); // Signing stays as-is, as parsed from declaration
|
nodep->widthForce(width, width); // Signing stays as-is, as parsed from declaration
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -2304,7 +2304,7 @@ struct_unionDecl<nodeUOrStructDTypep>: // IEEE: part of data_type
|
||||||
/*cont*/ struct_union_memberListEnd
|
/*cont*/ struct_union_memberListEnd
|
||||||
{ $$ = $<nodeUOrStructDTypep>4; $$->addMembersp($5); SYMP->popScope($$); }
|
{ $$ = $<nodeUOrStructDTypep>4; $$->addMembersp($5); SYMP->popScope($$); }
|
||||||
| yUNION taggedSoftE packedSigningE '{'
|
| yUNION taggedSoftE packedSigningE '{'
|
||||||
/*mid*/ { $<nodeUOrStructDTypep>$ = new AstUnionDType{$1, $3}; SYMP->pushNew($<nodeUOrStructDTypep>$); }
|
/*mid*/ { $<nodeUOrStructDTypep>$ = new AstUnionDType{$1, $2, $3}; SYMP->pushNew($<nodeUOrStructDTypep>$); }
|
||||||
/*cont*/ struct_union_memberListEnd
|
/*cont*/ struct_union_memberListEnd
|
||||||
{ $$ = $<nodeUOrStructDTypep>5; $$->addMembersp($6); SYMP->popScope($$); }
|
{ $$ = $<nodeUOrStructDTypep>5; $$->addMembersp($6); SYMP->popScope($$); }
|
||||||
;
|
;
|
||||||
|
|
@ -2440,9 +2440,9 @@ random_qualifier<qualifiers>: // ==IEEE: random_qualifier
|
||||||
| yRANDC { $$ = VMemberQualifiers::none(); $$.m_randc = true; }
|
| yRANDC { $$ = VMemberQualifiers::none(); $$.m_randc = true; }
|
||||||
;
|
;
|
||||||
|
|
||||||
taggedSoftE:
|
taggedSoftE<cbool>:
|
||||||
/*empty*/ { }
|
/*empty*/ { $$ = false; }
|
||||||
| ySOFT { BBUNSUP($<fl>1, "Unsupported: 'union soft'"); }
|
| ySOFT { $$ = true; }
|
||||||
//UNSUP yTAGGED { UNSUP }
|
//UNSUP yTAGGED { UNSUP }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,10 @@ module t_dpi_result_type_bad;
|
||||||
typedef struct packed { bit [63:0] x; bit [63:0] y; } struct_2_state_128;
|
typedef struct packed { bit [63:0] x; bit [63:0] y; } struct_2_state_128;
|
||||||
|
|
||||||
// 2-state packed unions of width > 32
|
// 2-state packed unions of width > 32
|
||||||
typedef union packed { bit [ 32:0] x; bit y; } union_2_state_33;
|
typedef union packed { bit [ 32:0] x; bit [ 32:0] y; } union_2_state_33;
|
||||||
typedef union packed { bit [ 63:0] x; bit y; } union_2_state_64;
|
typedef union packed { bit [ 63:0] x; bit [ 63:0] y; } union_2_state_64;
|
||||||
typedef union packed { bit [ 64:0] x; bit y; } union_2_state_65;
|
typedef union packed { bit [ 64:0] x; bit [ 64:0] y; } union_2_state_65;
|
||||||
typedef union packed { bit [127:0] x; bit y; } union_2_state_128;
|
typedef union packed { bit [127:0] x; bit [127:0] y; } union_2_state_128;
|
||||||
|
|
||||||
// 4-state packed arrays of any size
|
// 4-state packed arrays of any size
|
||||||
typedef logic [ 0:0] array_4_state_1_t;
|
typedef logic [ 0:0] array_4_state_1_t;
|
||||||
|
|
@ -59,17 +59,17 @@ module t_dpi_result_type_bad;
|
||||||
typedef struct packed { logic [63:0] x; bit [63:0] y; } struct_4_state_128;
|
typedef struct packed { logic [63:0] x; bit [63:0] y; } struct_4_state_128;
|
||||||
|
|
||||||
// 4-state packed unions of any size
|
// 4-state packed unions of any size
|
||||||
typedef union packed { logic [ 0:0] x; bit y; } union_4_state_1;
|
typedef union packed { logic [ 0:0] x; bit [ 0:0] y; } union_4_state_1;
|
||||||
typedef union packed { logic [ 1:0] x; bit y; } union_4_state_2;
|
typedef union packed { logic [ 1:0] x; bit [ 1:0] y; } union_4_state_2;
|
||||||
typedef union packed { logic [ 7:0] x; bit y; } union_4_state_8;
|
typedef union packed { logic [ 7:0] x; bit [ 7:0] y; } union_4_state_8;
|
||||||
typedef union packed { logic [ 8:0] x; bit y; } union_4_state_9;
|
typedef union packed { logic [ 8:0] x; bit [ 8:0] y; } union_4_state_9;
|
||||||
typedef union packed { logic [ 15:0] x; bit y; } union_4_state_16;
|
typedef union packed { logic [ 15:0] x; bit [ 15:0] y; } union_4_state_16;
|
||||||
typedef union packed { logic [ 16:0] x; bit y; } union_4_state_17;
|
typedef union packed { logic [ 16:0] x; bit [ 16:0] y; } union_4_state_17;
|
||||||
typedef union packed { logic [ 31:0] x; bit y; } union_4_state_32;
|
typedef union packed { logic [ 31:0] x; bit [ 31:0] y; } union_4_state_32;
|
||||||
typedef union packed { logic [ 32:0] x; bit y; } union_4_state_33;
|
typedef union packed { logic [ 32:0] x; bit [ 32:0] y; } union_4_state_33;
|
||||||
typedef union packed { logic [ 63:0] x; bit y; } union_4_state_64;
|
typedef union packed { logic [ 63:0] x; bit [ 63:0] y; } union_4_state_64;
|
||||||
typedef union packed { logic [ 64:0] x; bit y; } union_4_state_65;
|
typedef union packed { logic [ 64:0] x; bit [ 64:0] y; } union_4_state_65;
|
||||||
typedef union packed { logic [127:0] x; bit y; } union_4_state_128;
|
typedef union packed { logic [127:0] x; bit [127:0] y; } union_4_state_128;
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// Imports
|
// Imports
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
typedef logic [5:0] udata6_t;
|
typedef logic [5:0] udata6_t;
|
||||||
|
|
||||||
typedef union packed {
|
typedef union soft packed {
|
||||||
udata6_t a;
|
udata6_t a;
|
||||||
logic [2 : 0] b;
|
logic [2 : 0] b;
|
||||||
} sub_t;
|
} sub_t;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
// Packed struct in package
|
// Packed struct in package
|
||||||
package TEST_TYPES;
|
package TEST_TYPES;
|
||||||
typedef union packed {
|
typedef union soft packed {
|
||||||
logic [64 : 0] a;
|
logic [64 : 0] a;
|
||||||
logic [2 : 0] b;
|
logic [2 : 0] b;
|
||||||
} sub_t;
|
} sub_t;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
%Error: t/t_union_hard_bad.v:11:21: Hard packed union members must have equal size (IEEE 1800-2023 7.3.1)
|
||||||
|
: ... note: In instance 't'
|
||||||
|
11 | bit [7 : 0] val1;
|
||||||
|
| ^~~~
|
||||||
|
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
|
||||||
|
%Error: Exiting due to
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||||
|
#
|
||||||
|
# Copyright 2024 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('vlt')
|
||||||
|
|
||||||
|
test.lint(fails=True, expect_filename=test.golden_filename)
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||||
|
// any use, without warranty, 2024 by Wilson Snyder.
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
module t
|
||||||
|
(/*AUTOARG*/);
|
||||||
|
|
||||||
|
union packed {
|
||||||
|
bit [7 : 0] val1;
|
||||||
|
bit [3 : 0] val2;
|
||||||
|
} u;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
u.val1 = 8'h7c;
|
||||||
|
if(u.val1 != 8'h7c) $stop;
|
||||||
|
u.val2 = 4'h6;
|
||||||
|
if(u.val2 != 4'h6) $stop;
|
||||||
|
$display("%p", u);
|
||||||
|
if(u.val1 != 8'h76) $stop;
|
||||||
|
$write("*-* All Finished *-*\n");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -11,6 +11,8 @@ import vltest_bootstrap
|
||||||
|
|
||||||
test.scenarios('vlt')
|
test.scenarios('vlt')
|
||||||
|
|
||||||
test.lint(fails=True, expect_filename=test.golden_filename)
|
test.compile()
|
||||||
|
|
||||||
|
test.execute()
|
||||||
|
|
||||||
test.passes()
|
test.passes()
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,24 @@ module t(/*AUTOARG*/);
|
||||||
bit [3:0] val2;
|
bit [3:0] val2;
|
||||||
} u;
|
} u;
|
||||||
|
|
||||||
|
union soft packed {
|
||||||
|
bit [7 : 0] val1;
|
||||||
|
bit [3 : 0] val2;
|
||||||
|
} u2;
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
u.val1 = 8'h7c;
|
u.val1 = 8'h7c;
|
||||||
if (u.val1 != 8'h7c) $stop;
|
if (u.val1 != 8'h7c) $stop;
|
||||||
u.val2 = 4'h6;
|
u.val2 = 4'h6;
|
||||||
if (u.val2 != 4'h6) $stop;
|
if (u.val2 != 4'h6) $stop;
|
||||||
$display("%p", u);
|
$display("%p", u);
|
||||||
if (u.ual1 != 8'h76) $stop;
|
if(u.val1 != 8'h76) $stop;
|
||||||
|
u2.val1 = 8'h7c;
|
||||||
|
if(u2.val1 != 8'h7c) $stop;
|
||||||
|
u2.val2 = 4'h6;
|
||||||
|
if(u2.val2 != 4'h6) $stop;
|
||||||
|
$display("%p", u2);
|
||||||
|
if(u2.val1 != 8'h76) $stop;
|
||||||
$write("*-* All Finished *-*\n");
|
$write("*-* All Finished *-*\n");
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue