Home > Enterprise >  Packed Unions in SystemVerilog
Packed Unions in SystemVerilog

Time:11-25

The code is not too long so I am posting the complete code.

// Code your design here
module temp;
typedef enum logic[15:0]
{
  ADD = 16'h0000,
  SUB = 16'h0001
} my_opcode_t;

typedef enum logic[15:0]
{
  REG = 16'h0000,
  MEM = 16'h0001
} my_dest_t;
  
  typedef struct packed
{
  my_opcode_t  opcode; // 16-bit opcode, enumerated type
  my_dest_t    dest; // 16-bit destination, enumerated type
  logic [15:0] opA;
  logic [15:0] opB;
} my_opcode_struct_t;

my_opcode_struct_t cmd1;
  
  
typedef union packed
{
  my_opcode_struct_t opcode_s; //"fields view" to the struct
  logic[1:0][31:0] dword; // "dword view" to the struct
} my_opcode_union_t;

my_opcode_union_t cmd2;

initial begin
  $display("cmd1 = %p",cmd1);
  $display("cmd2 = %p", cmd2);
  // Access opcode_s struct fields within the union
  cmd2.opcode_s.opcode = ADD;
  cmd2.opcode_s.dest = REG;
  cmd2.opcode_s.opA = 16'h0001;
  cmd2.opcode_s.opB = 16'h0002;
  $display("cmd1 = %p",cmd1);
  $display("cmd2 = %p", cmd2);

  // Access dwords struct fields within the union
  cmd2.dword[1] = 32'h0001_0001; // opcode=SUB, dest=MEM
  cmd2.dword[0] = 32'h0007_0008; // opA=7, opB=8
  $display("cmd2 = %p", cmd2);
  end
endmodule

Source: enter image description here

I ran this code in EDA playground. I did not understand why is it showing"

cmd2='{opcode_s:'{opcode:SUB, dest:MEM, opA:'h7,opB:'h8}}

I was expecting, it would print dword values. What is it missing in my understanding about unions? Is it because we are not using cmd2.dword[0] or cmd2.dword[1] it is printing some garbage values?

CodePudding user response:

The reason you do not print dword values is due to the behavior of the %p format specifier. Refer to IEEE Std 1800-2017, section 21.2.1.7 Assignment pattern format:

The %p format specifier may be used to print aggregate expressions such as unpacked structures, arrays, and unions. ... For unions, only the first declared elements shall be printed.

If you change your union declaration as follows (with dword first):

typedef union packed
{
  logic[1:0][31:0] dword; // "dword view" to the struct
  my_opcode_struct_t opcode_s; //"fields view" to the struct
} my_opcode_union_t;

you will see this output:

cmd1 = '{opcode:'hxxxx, dest:'hxxxx, opA:'hxxxx, opB:'hxxxx}
cmd2 = '{dword:'hxxxxxxxxxxxxxxxx}
cmd1 = '{opcode:'hxxxx, dest:'hxxxx, opA:'hxxxx, opB:'hxxxx}
cmd2 = '{dword:'h10002}
cmd2 = '{dword:'h1000100070008}
  • Related