Facing Error while using UVM Pack Method

Hi,

I am facing this error while using uvm pack method
** Error: trans.sv(41): The actual (this.packed_data) and formal (bitstream) for a ref must be equivalent types.
** Error: trans.sv(45): The actual (this.packed_data) and formal (bitstream) for a ref must be equivalent types.

Here my code



module exp;
  
  `include "uvm_macros.svh"
  import uvm_pkg::* ; 
  
  class ethernet_trans extends uvm_sequence_item;
  
    bit [55:0] preamble = 'b10101010_10101010_10101010_10101010_10101010_10101010_10101010;
    bit [7:0] sfd = 'b10101011;
    rand bit [47:0] destination_address, source_address;
    rand bit [15:0] length;
    rand byte unsigned data_q [$];
    bit[127:0] packed_data [];
    bit [31:0] fcs = 'h0000_0000;     //initially 00
   
    constraint data_size_c {data_q.size == length;}
    
    constraint length_c {length <= 1500;
                        length >= 46;}
    
    constraint size_len_c { solve length before data_q.size;}
  
    `uvm_object_utils_begin(ethernet_trans)
      `uvm_field_int(preamble, UVM_ALL_ON | UVM_NOPACK)
      `uvm_field_int(sfd, UVM_ALL_ON | UVM_NOPACK)
      `uvm_field_int(destination_address, UVM_ALL_ON | UVM_NOPACK)
      `uvm_field_int(source_address, UVM_ALL_ON | UVM_NOPACK)
      `uvm_field_int(length, UVM_ALL_ON | UVM_NOPACK)
      `uvm_field_queue_int(data_q, UVM_ALL_ON | UVM_NOPACK)
      `uvm_field_int(fcs, UVM_ALL_ON | UVM_NOPACK)
    `uvm_object_utils_end
     
    function void fcs_calc();
      void'(pack(packed_data));       //for fcs calculation     //Error in this line
      foreach(packed_data[i]) begin
        fcs = packed_data[i] ^ 'h82608edb;       //'h82608edb
      end
      void'(pack(packed_data));       //final packet for transfer //Error in this line
    endfunction
      
    function void post_randomize;
      fcs_calc;
    endfunction
   
    virtual function void do_pack(uvm_packer packer);
      super.do_pack(packer);
      packer.pack_field(destination_address, $bits(destination_address));
      packer.pack_field(source_address, $bits(source_address));
      packer.pack_field(length, $bits(length));
      foreach(data_q[i])
        packer.pack_field(data_q[i],8);
      packer.pack_field(fcs, $bits(fcs));
    endfunction
    
    function new(string name ="ethernet_trans");
      super.new(name);
    endfunction
    
  endclass : ethernet_trans

  ethernet_trans packet;
  
  initial begin
    packet = new;
    assert(packet.randomize());
    foreach(packet.packed_data[i]) begin
      `uvm_info("PACK",$sformatf("bit_packed_data[%0d] = %b",i,packed_data[i]),UVM_LOW)
    end
  end
    
endmodule

Thanks in Advance

In reply to Bharat.manvani:

The uvm_object::pack() method requires an argument variable whose type is a dynamic array of a single bit, not a packed array of 128 bits. .

Hi @dave_59

Can you please check this

module exp;

`include “uvm_macros.svh”
import uvm_pkg::* ;

class ethernet_trans extends uvm_sequence_item;

bit [55:0] preamble = 'b10101010_10101010_10101010_10101010_10101010_10101010_10101010;
bit [7:0] sfd = 'b10101011;
rand bit [47:0] destination_address, source_address;
rand bit [15:0] length;
rand byte unsigned data_q [$];

:white_check_mark: bit[127:0] packed_data ; ////// it’s already bit type and dynamic
bit [31:0] fcs = 'h0000_0000; //initially 00

constraint data_size_c {data_q.size == length;}

constraint length_c {length <= 1500;
                    length >= 46;}

constraint size_len_c { solve length before data_q.size;}

`uvm_object_utils_begin(ethernet_trans)
  `uvm_field_int(preamble, UVM_ALL_ON | UVM_NOPACK)
  `uvm_field_int(sfd, UVM_ALL_ON | UVM_NOPACK)
  `uvm_field_int(destination_address, UVM_ALL_ON | UVM_NOPACK)
  `uvm_field_int(source_address, UVM_ALL_ON | UVM_NOPACK)
  `uvm_field_int(length, UVM_ALL_ON | UVM_NOPACK)
  `uvm_field_queue_int(data_q, UVM_ALL_ON | UVM_NOPACK)
  `uvm_field_int(fcs, UVM_ALL_ON | UVM_NOPACK)
`uvm_object_utils_end

function void fcs_calc();
  void'(pack(packed_data));       //for fcs calculation     //Error in this line
  foreach(packed_data[i]) begin
    fcs = packed_data[i] ^ 'h82608edb;       //'h82608edb
  end
  void'(pack(packed_data));       //final packet for transfer //Error in this line
endfunction

function void post_randomize;
  fcs_calc;
endfunction

virtual function void do_pack(uvm_packer packer);
  super.do_pack(packer);
  packer.pack_field(destination_address, $bits(destination_address));
  packer.pack_field(source_address, $bits(source_address));
  packer.pack_field(length, $bits(length));
  foreach(data_q[i])
    packer.pack_field(data_q[i],8);
  packer.pack_field(fcs, $bits(fcs));
endfunction

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

endclass : ethernet_trans

ethernet_trans packet;

initial begin
packet = new;
assert(packet.randomize());
foreach(packet.packed_data[i]) begin
`uvm_info(“PACK”,$sformatf(“bit_packed_data[%0d] = %b”,i,packed_data[i]),UVM_LOW)
end
end

endmodule

In reply to Bharat.manvani:

It needs to be a packed array of a single bit.