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