How to create 9bit bytes for transaction class in UVM by using pack_bytes packing function?

Hello All UVM geeks,

I am creating a transaction (TX)class. I am facing an issue with packing of bits in pack and unpack functions for creation of packets. Actually I want to send 9bit byte, rather than 8bit byte. So I want to create 9bits bytes/groups inside the TX class. Its giving me issue while using pack/pack_bytes/pack_ints. I tried to use pack_bytes as shown below.

bit [8:0] bytes;

pkt_len = tx.pack_bytes(bytes)

Then it gives me below error:
The actual (bytes) and formal (bytestream) for a ref must be equivalent types.

I know the meaning of this error. But then the Question is: How do I make the groupings of these 9bits bytes from the TX class itself??

Please someone guide me or help me here.

Thanks and regds,
Swapnil

In reply to swapnilm:

Can some UVM geek please give me some answers/solutions here please? Would really appreciate that,

Regds,
Swapnil

If you look in uvm_object.svh, you’ll notice that the prototype for pack_bytes(…) is:

function int pack_bytes(ref byte unsigned bytestream[], ...)

This means that the method expects an array of byte, not bit[8:0 as you are giving it. If you want a method that packs into 9bit slices, you’ll have to implement your own. What you could do is use your own packer class that extends uvm_packer. Have a look in uvm_packer.svh at how get_bytes(…) is implemented and adapt that.

Pseudo-code:


class my_packer extends uvm_packer;
  function void get_9bit_slices(ref bit[8:0] slices[]);
    // implementation
  endfunction
endclass

class my_sequence_item extends uvm_sequence_item;
  function int pack_9bit_slices(ref bit[8:0] slices[], input my_packer packer);
    m_pack(packer);
    packer.get_9bit_slices(slices);
    return packer.get_packed_size();
  endfunction
endclass

In reply to swapnilm:

Hi Swapnil,

You can do this way … by using do_pack and do_unpack functions. Description from LRM below.

do_pack The do_pack method is the user-definable hook called by the pack methods.
do_unpack The do_unpack method is the user-definable hook called by the unpack method.

rand bit [8:0] da;
rand bit [8:0] sa;
rand bit [8:0] length;
rand bit [8:0] data;

function void do_pack(uvm_packer packer);
super.do_pack(packer);
packer.pack_field_int(da,$bits(da)); // $bits will return number of bits required for a field
packer.pack_field_int(sa,$bits(sa));
packer.pack_field_int(length,$bits(length));
foreach(data[i])
packer.pack_field_int(data[i],9);
packer.pack_field_int(fcs,$bits(fcs));
endfunction : do_pack

Similarly implement do_unpack method. then when you call pack_ints then your user defined do_pack and do_unpack will be effective and you can use it as you wish. Here there is a wastage of space since for 9 bits you are using whole int but its fine. Let me know if it works for you.

Thanks
Chaitanya.

In reply to Chaitanya_K:

This is already implemented by the field automation macros, if you use them.