Reputation: 549
I have the following structs:
typedef struct packed {
logic vld;
logic [`ADDR_RNG] addr;
logic [`CMD_RNG] cmd;
logic [`IDX_RNG] idx;
} pkt1Type_t;
typedef struct packed {
logic vld;
logic [`ADDR2_RNG] addr;
logic [`CMD_RNG] cmd;
logic [`IDX_RNG] idx;
} pkt2Type_t;
typedef struct packed {
logic [???] padding;
pkt1Type_t pkt;
} pkt1TypePadded_t;
typedef struct packed {
logic [???] padding;
pkt2Type_t pkt;
} pkt2TypePadded_t;
typedef union packed {
pkt1TypePadded_t pkt1;
pkt2TypePadded_t pkt2;
} pkt_t;
Where ADDR_RNG and ADDR2_RNG can be different.
As I understand it, SV structs for design (synthesizable) need to be of the same size. Is there a programmatic way to compute the size of pkt1Type_t and pkt2Type_t, find the larger of the 2 and then use it as the range literal in the [???] section above?
Or do I need to compute this manually or through the preprocessor `define?
Upvotes: 1
Views: 1074
Reputation: 42698
The dilemma here is only one union member needs to be padded to the size of the other member. But you cannot have a struct member with 0 width. So your packed union has to be at least 1-bit wider than the largest member
parameter MAXSIZE = ($bits(pkt1Type_t) > $bits(pkt2Type_t)) ?
$bits(pkt1Type_t) : $bits(pkt2Type_t);
typedef struct packed {
logic [MAXSIZE-$bits(pkt1Type_t):0] padding;
pkt1Type_t pkt;
} pkt1TypePadded_t;
typedef struct packed {
logic [MAXSIZE-$bits(pkt2Type_t):0] padding;
pkt2Type_t pkt;
} pkt2TypePadded_t;
typedef union packed {
pkt1TypePadded_t pkt1;
pkt2TypePadded_t pkt2;
} pkt_t;
There might be better approaches for what you are trying to do (i.e. tagged unions, let
construct, but difficult to say without known more what you need to do with this.
Upvotes: 2