CRC generation post_randomize upon packing the bits

I am trying to create a base class transaction to pack the frame to transmit as serial data.I am unable to pack the CRC fileds after ranomization,and I seet that the dynamic array has data,but it does not get packed into bits,and CRC calculation is always displayed as 0,hene require help in seeking the right pointers for CRC,packed into frame for serial tx.


class can_transaction extends uvm_sequence_item;
  //parameterized data randomizationfor can txn type
  rand  bit  SOF ;
  rand  bit[10:0] can_identifier ;
  rand  bit  RTR ;
  rand  bit  IDE ;
        bit  R0  ; //reserved bit
  rand  bit [3:0]  DLC ;
  rand  bit [7:0]  data[] ;
        bit [15:0] CRC=16'h0000 ;
  rand  bit [1:0]  ACK ;
  rand  bit [6:0]  EOF ;
  rand  bit [6:0]  IFS ;
  
  //crc calulation
  bit crc_next ;
  logic [14:0] crc_reg=15'h0000 ;
  bit bit_frame[] ;
  int pkt_len,bit_frm_len;
  bit [7:0] data_byte[] ;
  bit pack_frame[];
    int count=0 ; 
  bit[7:0] data_bit[];
  constraint priority_c {
                          solve DLC before data ;
                        }

  constraint DATA_Size_C {
                           data.size()==DLC;
                         }

  constraint DLC_C {
                     DLC inside {[8:8]};
                   }

  constraint identifier_c {               
                           !(can_identifier[10:4]==7'b1111111);
                             can_identifier==4'b0111 ;
                          }
                          
  constraint ACK_C {
                     ACK==2'b11 ;
                   }


  //---------------------------------------------------------------------------
  // UVM Factory Registration Macro
  //---------------------------------------------------------------------------
  //We will define packing and unpacking methods manually,
  //so use UVM_NOPACK for excluding atomic creation of packing
  //and un packing method.
    `uvm_object_utils_begin(can_transaction)
    `uvm_field_int(SOF, UVM_ALL_ON | UVM_NOPACK )
    `uvm_field_int(can_identifier, UVM_ALL_ON| UVM_NOPACK ) 
    `uvm_field_int(RTR, UVM_ALL_ON | UVM_NOPACK )
    `uvm_field_int(IDE, UVM_ALL_ON| UVM_NOPACK )
    `uvm_field_int(R0, UVM_ALL_ON| UVM_NOPACK )
    `uvm_field_int(DLC, UVM_ALL_ON | UVM_NOPACK )
    `uvm_field_array_int(data, UVM_ALL_ON | UVM_NOPACK )
    //`uvm_field_int(CRC, UVM_ALL_ON | UVM_NOPACK )
    //`uvm_field_int(ACK, UVM_ALL_ON | UVM_NOPACK )
    //`uvm_field_int(EOF, UVM_ALL_ON | UVM_NOPACK )
    //`uvm_field_int(IFS, UVM_ALL_ON | UVM_NOPACK )
  `uvm_object_utils_end


  //---------------------------------------------------------------------------
  // Standard UVM Methods:
  //---------------------------------------------------------------------------
  function new (string name="can_transaction");
    super.new(name);
  endfunction

  //---------------------------------------------------------------------------
  //print method
  //---------------------------------------------------------------------------
  virtual function void do_print(uvm_printer printer);
    super.do_print(printer);
    printer.print_field(.name("SOF"),
                        .value(SOF),
                        .size($bits(SOF)),
                        .radix(UVM_HEX));
    printer.print_field(.name("can_identifier"),
                        .value(can_identifier),
                        .size($bits(can_identifier)),
                        .radix(UVM_HEX));
    printer.print_field(.name("RTR"),
                        .value(RTR),
                        .size($bits(RTR)),
                        .radix(UVM_HEX));
    printer.print_field(.name("IDE"),
                        .value(IDE),
                        .size($bits(IDE)),
                        .radix(UVM_HEX));
    printer.print_field(.name("R0"),
                        .value(R0),
                        .size($bits(R0)),
                        .radix(UVM_HEX));
    printer.print_field(.name("DLC"),
                        .value(DLC),
                        .size($bits(DLC)),
                        .radix(UVM_HEX));
    foreach(data[i])
        printer.print_field(.name("data"),
                            .value(data[i]),
                            .size($bits(data[i])),
                            .radix(UVM_HEX));

    printer.print_field(.name("CRC"),
                        .value(CRC),
                        .size($bits(CRC)),
                        .radix(UVM_HEX));

   // printer.print_field(.name("ACK"),
   //                     .value(ACK),
   //                     .size($bits(ACK)),
   //                     .radix(UVM_HEX));

   // printer.print_field(.name("EOF"),
   //                     .value(EOF),
   //                     .size($bits(EOF)),
   //                     .radix(UVM_HEX));
   // printer.print_field(.name("IFS"),
   //                     .value(IFS),
   //                     .size($bits(IFS)),
   //                     .radix(UVM_HEX));
  endfunction
  
  virtual function void do_pack(uvm_packer packer);
    //super.do_pack(packer);
    packer.pack_field_int(SOF,$bits(SOF)          );
    packer.pack_field_int(can_identifier,$bits(can_identifier));
    packer.pack_field_int(RTR,$bits(RTR));
    packer.pack_field_int(IDE,$bits(IDE));
    packer.pack_field_int(R0,$bits(R0));
    packer.pack_field_int(DLC,$bits(DLC));
    foreach(data[i])
    begin
        packer.pack_field_int(data[i],$bits(data[i]));
    end
    //packer.pack_field_int(CRC,$bits(CRC));
    //packer.pack_field_int(EOF,$bits(EOF));
    //packer.pack_field_int(IFS,$bits(IFS));
  endfunction


  virtual function void do_unpack(uvm_packer packer);
    //super.do_unpack(packer);
    SOF=packer.unpack_field_int($bits(SOF)          );
    can_identifier=packer.unpack_field_int($bits(can_identifier));
    RTR=packer.unpack_field_int($bits(RTR));
    IDE=packer.unpack_field_int($bits(IDE));
    R0=packer.unpack_field_int($bits(R0));
    DLC=packer.unpack_field_int($bits(DLC));
    data.delete();
    data=new[DLC];
    foreach(data[i])    
      data[i]=packer.unpack_field_int($bits(data[i]));
    //CRC=packer.unpack_field_int($bits(CRC));
    //EOF=packer.unpack_field_int($bits(EOF));
    //IFS=packer.unpack_field_int($bits(IFS));
  endfunction

  
  virtual function bit [14:0] function_calc_can2_0_crc_15();
      pack(bit_frame);

     //bit_frame={<<{SOF,can_identifier,RTR,IDE,R0,DLC,data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7]}}; 
     `uvm_info("CAN CRC FUNC1",$sformatf("bit_frame_len=%0d  CRC value:%0h",$bits(bit_frame),CRC),UVM_LOW) 
      foreach(bit_frame[i])
      begin
       count++ ;
          $display("count=%0d bit_frame[%0d]=%0d",count,i,bit_frame[i]);
        crc_next=(crc_reg[14]^bit_frame[i]);
        crc_reg[14:1]=crc_reg[13:0]; //left shift
        crc_reg[0]=0 ;
      end
      if(crc_next)
      begin
        crc_reg[14:0]=(crc_reg[14:0]^15'h4599) ;
        CRC[15:0]={1'b1,crc_reg} ;
        `uvm_info("CAN PACKET TXN:CRC FUNC2",$sformatf("crc_reg=%0h, CRC value:%0h",crc_reg,CRC),UVM_LOW)
      end
      return(CRC);
  endfunction : function_calc_can2_0_crc_15

 
 	function void post_randomize();
	  uvm_table_printer uvm_default_table_printer=new();
	  function_calc_can2_0_crc_15();
	  this.do_print(uvm_default_table_printer);
  endfunction  

endclass : can_transaction

In reply to RKCH:

I’m not getting the result you are. I added these 4 lines to make a complete reproducable testcase,

module top;
  can_transaction can = new("can");
  initial assert(can.randomize);
endmodule

# UVM_INFO testbench.sv(188) @ 0: reporter@@can [CAN PACKET TXN:CRC FUNC2] crc_reg=4599, CRC value:c599