Reputation: 2559
This is an example for illustration. In SystemVerilog, it has array assignment pattern and struct assignment pattern syntax. No matter the union construct here is packed or unpacked, whether it is synthesizable or not, is it a valid usage for assignment pattern? If yes, what value should be for union x
?
typedef struct {
int a;
byte b;
union packed {
int c;
bit [31:0] d;
} x;
} S;
module top (s);
output S s;
assign s = '{int:2, default:1};
endmodule
If no, is it means I have to specify the initial value each field by field for the unpacked structure?
initial begin
s.a = 2;
s.b = 1;
s.x.c = 2;
end
Upvotes: 1
Views: 10952
Reputation: 348
I think identifying union members by type instead of name is an anti-pattern, but YMMV. I had the same question, and I think the answer is "you can't."
It might clarify the issue if the union members are themselves packed structs:
module tb();
typedef struct packed {
logic [7:0] b1;
logic [7:0] b0;
} two_bytes_t;
typedef struct packed {
logic [3:0] n3;
logic [3:0] n2;
logic [3:0] n1;
logic [3:0] n0;
} four_nibbles_t;
typedef union packed {
two_bytes_t two_bytes;
four_nibbles_t four_nibbles;
} my_union_t;
my_union_t my_union;
typedef struct packed {
logic [7:0] a;
my_union_t u;
} my_struct_t;
my_struct_t my_struct;
initial begin
my_union.two_bytes = '{b0: 1, b1: 2};
my_union.four_nibbles = '{n0: 1, n1: 1, n2: 3, n3: 4};
$display("%p", my_union);
`ifdef UNDEFINED
// this doesn't work:
//
my_struct = '{
u.two_bytes: '{b0: 3, b1: 4},
default: '0
};
// produces:
// u.two_bytes: '{b0: 3, b1: 4},
// |
// xmelab: *E,CUVUNF (./foo.sv,35|14): Hierarchical name component lookup failed for 'u' at 'tb'.
// u.two_bytes: '{b0: 3, b1: 4},
// |
// xmelab: *E,URCEN (./foo.sv,35|4): Unresolved constant expression VST_AP_ITEM.
`endif
// this works:
my_struct = '0;
my_struct.u.two_bytes = '{b0: 1, b1: 2};
$display("%p", my_struct);
end
endmodule : tb
Upvotes: 0
Reputation: 246
I tried this modified example:
typedef bit [31:0] Word;
typedef struct {
int a;
byte b;
union packed {
int c;
Word d;
} x;
union packed {
Word d;
int c;
} y;
} S;
module top (s);
output S s;
assign s = '{ int:2, Word:3, default:1 };
initial begin
#10
$display ("s.a = %d, s.b = %h, s.x.c = %d, s.x.d = %h s.y.d = %h s.y.c = %d",
s.a, s.b, s.x.c, s.x.d, s.y.d, s.y.c);
end
endmodule
Modelsim gives this output:
s.a = 2, s.b = 01, s.x.c = 3, s.x.d = 00000003 s.y.d = 00000002 s.y.c = 2
whereas VCS gives this output:
s.a = 2, s.b = 01, s.x.c = 3, s.x.d = 00000003 s.y.d = 00000003 s.y.c = 3
This shows that simulators treat such code the way they want and there is no standard behaviour to be expected.
The following syntax would be safer to use:
assign s = '{ int:2, default:1, x:3, y:4 };
With this both Modelsim & VCS give:
s.a = 2, s.b = 01, s.x.c = 3, s.x.d = 00000003 s.y.d = 00000004 s.y.c = 4
Upvotes: 1
Reputation: 587
I modified your code little bit to print the assigned values.
typedef struct {
int a;
byte b;
union packed {
int c;
bit [31:0] d;
} x;
} S;
module top (s);
output S s;
assign s = '{int:2, default:1};
initial begin
#10
$display ("s.a = %d, s.b = %h, s.x.c = %d, s.x.d = %h", s.a, s.b, s.x.c, s.x.d);
end
endmodule
Following is the result from ncsim:
s.a = 2, s.b = 01, s.x.c = 1, s.x.d = 00000001
And from vcs:
s.a = 2, s.b = 01, s.x.c = 1, s.x.d = 00000001
Hope this answers your question.
Upvotes: 2