How to add header and payload bytes in a transaction class?

Dear all,

I am trying to add 2 header bytes to payload bytes, in order to calculate the CRC which is based on the calculation of header and payload bytes and using polynomial (x^16 + x^12 + x^5 + x). I need to add the crc to the transaction packets.

The payload bytes are created by dynamic array method. When I try to add the 2 header bytes with dynamic array bytes for the calculation of CRC, it gives error. Can some one plz tell me how to add the 2 header bytes with payload bytes? plz find below the portion of code. Plz have a look at it and give me suggestion.

Code is as follows:-

`include "uvm_macros.svh"

import uvm_pkg::*;

class transaction extends uvm_sequence_item;
     
   rand bit [7:0] sync;
   rand bit [7:0] sof;  
   rand bit [15:0] header; 
   rand bit [7:0] payload[]; 
   rand bit [15:0] crc;
   rand bit [7:0] eof;
   
  constraint data_size_c { payload.size inside { [1 : 10]};}; 
         
    function new(string name = "");
         super.new(name);
    endfunction : new
    
      
   function [15:0] cal_crc;
        int j;
        bit [7:0]data;
        bit [15:0] n;
        bit [7:0] N[];
        reg [15:0] newcrc;
   
     n = header;
     N = n + payload;
      for ( j = 0; j <= N ; j++)
        begin
         
         bit [15:0] crc;
         reg [7:0] d;
         reg [15:0] c;
         //reg [15:0] newcrc;
         
       //  begin
         d = data[j];   
         c = crc;
         
         newcrc[0] = d[4] ^ d[0] ^ c[8] ^ c[12];
         newcrc[1] = d[5] ^ d[1] ^ c[9] ^ c[13];
         newcrc[2] = d[6] ^ d[2] ^ c[10] ^ c[14];
         newcrc[3] = d[7] ^ d[3] ^ c[11] ^ c[15];
         newcrc[4] = d[4] ^ c[12];
         newcrc[5] = d[5] ^ d[4] ^ d[0] ^ c[8] ^ c[12] ^ c[13];
         newcrc[6] = d[6] ^ d[5] ^ d[1] ^ c[9] ^ c[13] ^ c[14];
         newcrc[7] = d[7] ^ d[6] ^ d[2] ^ c[10] ^ c[14] ^ c[15];
         newcrc[8] = d[7] ^ d[3] ^ c[0] ^ c[11] ^ c[15];
         newcrc[9] = d[4] ^ c[1] ^ c[12];
         newcrc[10] = d[5] ^ c[2] ^ c[13];
         newcrc[11] = d[6] ^ c[3] ^ c[14];
         newcrc[12] = d[7] ^ d[4] ^ d[0] ^ c[4] ^ c[8] ^ c[12] ^ c[15];
         newcrc[13] = d[5] ^ d[1] ^ c[5] ^ c[9] ^ c[13];
         newcrc[14] = d[6] ^ d[2] ^ c[6] ^ c[10] ^ c[14];
         newcrc[15] = d[7] ^ d[3] ^ c[7] ^ c[11] ^ c[15];
       
         $display("The value of CRC result newcrc = %h ",newcrc); 
         return newcrc; //result;
        end
    endfunction : cal_crc
        
   function void post_randomize();  
          crc =  cal_crc();
    endfunction : post_randomize 
    
    `uvm_object_utils_begin(transaction)
       `uvm_field_int(sync, UVM_ALL_ON|UVM_NOPACK)
       `uvm_field_int(sof, UVM_ALL_ON|UVM_NOPACK)
       `uvm_field_int(header, UVM_ALL_ON|UVM_NOPACK)
       `uvm_field_array_int(payload, UVM_ALL_ON|UVM_NOPACK)
       `uvm_field_int(crc, UVM_ALL_ON|UVM_NOPACK)
       `uvm_field_int(eof, UVM_ALL_ON|UVM_NOPACK)
    `uvm_object_utils_end

endclass

Any help would be appreciated,

Thanks,
Swapnil

Can you please tell us what the error is, and give us the complete testcase to save the readers on this forum the time to solve your problems.

In reply to dave_59:

Dear sir,
I am getting following errors when I tried to add header bytes to the payload bytes in order to calculate CRC which is dependent on both header(2 bytes) and payload bytes.

Errors are:- Error: transaction.sv(30): Illegal operation on unpacked types
Error: transaction.sv(30): Cannot assign a packed type to an unpacked type.

So can you plz tell me how to defeat this error as I really need to add the header bytes to the payload bytes.

Help is appreaciated.

Thanks,
Swapnil

In reply to swapnilm:

OK, so the statement N = n + payload; is giving you trouble?

Can you give an example of values for n and payload and what the result should be? Did you really mean mathematical “addition” or do you mean “concatenation”?

How do expect the statement for ( j = 0; j <= N ; j++) to loop since N is an array, not an integer? You have a return statement inside your loop so the loop only executes once. Where does data get its value?

In reply to dave_59:

Swapnil,
Based on your description it looks like you need to first put header as 2 elements in the new “N” array, followed by “payload”.

If so, try the following:


   function [15:0] cal_crc;
        int j;
        bit [7:0]data;
        bit [15:0] n;
        bit [7:0] N[];
        reg [15:0] newcrc;
 
     n = header;
     N = new [this.payload.size + 2]; // 2 more for header
     N = { >> {n, payload} };
     `uvm_info ("CVC-Dbg", $sformatf("header + payload: %p", N), UVM_MEDIUM);

      for ( j = 0; j < N.size ; j++)
        begin
 

i.e. use streaming operator >> - works fine for simple data types.

HTH
Ajeetha, CVC

In reply to ajeetha:

Hello Ajeetha Madam,
Thank you so much for your suggestion. It has helped in solving my problem. So I replaced data[j] with N[j] as an input byte to calculate the CRC. Thats correct, right?
Also I put return newcrc outside the for loop and not inside the for loop? Because it gives different crc values. So In order to calculate the crc value for each byte of N[j] , its better to put return newcrc outside the For loop, right? Please correct me if I am wrong.This is how I did it as shown below:-

function [15:0] cal_crc;
int j;
bit [7:0]data;
bit [15:0] n;
bit [7:0] N;
reg [15:0] newcrc;

   n = header;
   N = new [this.payload.size + 2]; // 2 more for header
   N = { >> {n, payload} };
   `uvm_info ("CVC-Dbg", $sformatf("header + payload: %p", N), UVM_MEDIUM);

  for ( j = 0; j < N.size ; j++)
    begin         
     bit [15:0] crc;
     reg [7:0] d;
     reg [15:0] c;
     //reg [15:0] newcrc;
 
     d =  N[j]; // data[j];          
     c = crc;
     
     newcrc[0] = d[4] ^ d[0] ^ c[8] ^ c[12];
     newcrc[1] = d[5] ^ d[1] ^ c[9] ^ c[13];
     newcrc[2] = d[6] ^ d[2] ^ c[10] ^ c[14];
     newcrc[3] = d[7] ^ d[3] ^ c[11] ^ c[15];
     newcrc[4] = d[4] ^ c[12];
     newcrc[5] = d[5] ^ d[4] ^ d[0] ^ c[8] ^ c[12] ^ c[13];
     newcrc[6] = d[6] ^ d[5] ^ d[1] ^ c[9] ^ c[13] ^ c[14];
     newcrc[7] = d[7] ^ d[6] ^ d[2] ^ c[10] ^ c[14] ^ c[15];
     newcrc[8] = d[7] ^ d[3] ^ c[0] ^ c[11] ^ c[15];
     newcrc[9] = d[4] ^ c[1] ^ c[12];
     newcrc[10] = d[5] ^ c[2] ^ c[13];
     newcrc[11] = d[6] ^ c[3] ^ c[14];
     newcrc[12] = d[7] ^ d[4] ^ d[0] ^ c[4] ^ c[8] ^ c[12] ^ c[15];
     newcrc[13] = d[5] ^ d[1] ^ c[5] ^ c[9] ^ c[13];
     newcrc[14] = d[6] ^ d[2] ^ c[6] ^ c[10] ^ c[14];
     newcrc[15] = d[7] ^ d[3] ^ c[7] ^ c[11] ^ c[15];
   
     $display("The value of CRC result newcrc = %h ",newcrc); 
     //return newcrc; 
    end
    return newcrc; 
endfunction : cal_crc

function void post_randomize();
crc = cal_crc();
endfunction : post_randomize

Please correct me if I am wrong mam?
I appreciate your help,

Thanks,
Swapnil

In reply to swapnilm:

Swapnil,

I believe you want to do c = newcrc; each time through the loop. Otherwise c is always 0. There is no need to do N =new[…];. Anytime you assign an array to dynamic array, the dynamic array is automatically re-sized to fit. Also, it would really help to format your code to make it more readable

class packet;
     bit [15:0]     m_header;
     rand bit [7:0] m_payload;
     bit [15:0]     m_crc
function bit [15:0] cal_crc;
       bit [7:0] N[];
       bit [15:0] newcrc;
       N = { >> {m_header, m_payload} };
       `uvm_info ("CVC-Dbg", $sformatf("header + payload: %p", N), UVM_MEDIUM);
      foreach(N[j])
        begin         
         bit [7:0]  d = N[j];
         bit [15:0] c = newcrc;
         newcrc[0] = d[4] ^ d[0] ^ c[8] ^ c[12];
         newcrc[1] = d[5] ^ d[1] ^ c[9] ^ c[13];
         newcrc[2] = d[6] ^ d[2] ^ c[10] ^ c[14];
         newcrc[3] = d[7] ^ d[3] ^ c[11] ^ c[15];
         newcrc[4] = d[4] ^ c[12];
         newcrc[5] = d[5] ^ d[4] ^ d[0] ^ c[8] ^ c[12] ^ c[13];
         newcrc[6] = d[6] ^ d[5] ^ d[1] ^ c[9] ^ c[13] ^ c[14];
         newcrc[7] = d[7] ^ d[6] ^ d[2] ^ c[10] ^ c[14] ^ c[15];
         newcrc[8] = d[7] ^ d[3] ^ c[0] ^ c[11] ^ c[15];
         newcrc[9] = d[4] ^ c[1] ^ c[12];
         newcrc[10] = d[5] ^ c[2] ^ c[13];
         newcrc[11] = d[6] ^ c[3] ^ c[14];
         newcrc[12] = d[7] ^ d[4] ^ d[0] ^ c[4] ^ c[8] ^ c[12] ^ c[15];
         newcrc[13] = d[5] ^ d[1] ^ c[5] ^ c[9] ^ c[13];
         newcrc[14] = d[6] ^ d[2] ^ c[6] ^ c[10] ^ c[14];
         newcrc[15] = d[7] ^ d[3] ^ c[7] ^ c[11] ^ c[15]; 
       end
       $display("The value of CRC result newcrc = %h ",newcrc);  
       return newcrc; 
    endfunction : cal_crc
        
   function void post_randomize();  
          crc =  cal_crc();
    endfunction : post_randomize
endclass : packet