Return value of pack() and unpack()

I am trying to understand the return value of pack(), unpack(), pack_bytes(), and unpack_bytes() in UVM.

I have the following transaction:

class my_trans extends uvm_sequence_item;
  `uvm_object_utils_begin(my_trans)
    `uvm_field_int(addr,  UVM_ALL_ON)
    `uvm_field_int(data,  UVM_ALL_ON)
    `uvm_field_int(wr_en, UVM_ALL_ON)
  `uvm_object_utils_end

  rand bit [1:0] addr;
  rand bit       data;
  rand bit       wr_en;

  function new(string name="my_trans");
    super.new(name);
  endfunction
endclass

Total field width is only 4 bits:

  • addr : 2 bits

  • data : 1 bit

  • wr_en : 1 bit

I then perform:

num_bits = tx.pack(packed_bits);
num_bits = rx.unpack(packed_bits);

Output:

------------------------------
Name     Type      Size  Value
------------------------------
tx       my_trans  -     @165
  addr   integral  2     'h2
  data   integral  1     'h0
  wr_en  integral  1     'h1
------------------------------

UVM_INFO ... pack()   : bits=8
UVM_INFO ... unpack() : bits=8

According to the UVM source code:

function int uvm_object::m_unpack_post(uvm_packer packer);
  int size_before_unpack = packer.get_packed_size();
  packer.unpack_object(this);
  return size_before_unpack - packer.get_packed_size();
endfunction

and

function int uvm_packer::get_packed_size();
  return m_pack_iter - m_unpack_iter;
endfunction

I would expect pack() and unpack() to report the number of bits actually packed/unpacked. Since my object contains only 4 bits of data, I expected the return value to be 4.

However, both functions return 8.

Environment:

  • Simulator: Aldec

  • UVM Library: IEEE 1800.2-2020

  • The same code run with Synopsys UVM 1.2 returns the expected value.

Questions:

  1. Is the return value of pack()/unpack() in IEEE 1800.2-2020 expected to be byte-aligned?

  2. Is there a change in packer behavior between UVM 1.2 and IEEE 1800.2-2020?

  3. Am I misunderstanding the API or using it incorrectly?

  4. Could this be a simulator/UVM library issue in Aldec and other simulators?

  5. If anyone can explain the logic they are using for building this APIs?

Any insight would be appreciated.

There were substantial changes to the pack/unpack mechanism in UVM between the Accellera UVM 1.2 standard and the IEEE 1800.2 UVM standard. The raw stream contents are not compatible between different versions of UVM. We strongly recommend overriding the do_pack/unpack() methods with explicit packing and unpacking code. And we also recommend avoiding the UVM field macros.