Hello all,
I am stuck at one place. I want to unpack my payload bytes which are actually produced by dynamic array. Some uvm geeks suggested me to use another parameter,length, in order to unpack the size of the payload but the specifications doesnt allow me to do that. Please find below the transaction class code. And some part of monitor class run phase.
Transaction class:-
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;
//rand bit [7:0] length; // dont want to use this kind of parameter bcoz the specifications doesnt support it.
constraint data_size_c { payload.size inside { [1 : 4]};};
//constraint length_c { length== payload.size }; // dont want to use this kind of parameter bcoz the specifications doesnt support it.
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 = new [this.payload.size + 2]; // 2 more for header
N = { >> {n, payload} };
`uvm_info ("TXHP", $sformatf("header + payload: %h", N), UVM_MEDIUM);
for ( j = 0; j < N.size ; j++)
begin
bit [15:0] crc;
reg [7:0] d;
reg [15:0] c;
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; //result;
end
return newcrc; //result;
endfunction : cal_crc
function void post_randomize();
crc = cal_crc();
uvm_report_info(get_full_name(),"Appending crc into the packet ",UVM_LOW);
endfunction : post_randomize
`uvm_object_utils_begin(transaction)
uvm_default_packer.use_metadata = 1;
//int i;
`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
function void do_pack(uvm_packer packer);
int i;
super.do_pack(packer);
// uvm_default_packer.use_metadata = 1;
packer.pack_field_int(sync,$bits(sync));
packer.pack_field_int(sof,$bits(sof));
packer.pack_field_int(header,$bits(header));
foreach(payload[i])
packer.pack_field_int(payload[i],8);
packer.pack_field_int(crc,$bits(crc));
packer.pack_field_int(eof,$bits(eof));
endfunction : do_pack
function void do_unpack(uvm_packer packer);
int i;
super.do_unpack(packer); //super.do_pack(packer);
//uvm_default_packer.use_metadata = 1;
sync = packer.unpack_field_int($bits(sync));
sof = packer.unpack_field_int($bits(sof));
header = packer.unpack_field_int($bits(header));
payload.delete(); // added later by me
payload = new [payload.size]; //added later
foreach(payload[i])
payload[i] = packer.unpack_field_int(8);
crc = packer.unpack_field_int($bits(crc));
eof = packer.unpack_field_int($bits(eof));
endfunction : do_unpack
endclass: transaction
Monitor (run phase part):-
task run_phase(uvm_phase phase);
transaction pkt;
forever
begin
bit [7:0] bq[$],bytes[];
repeat(3)@(dut_vi.clock); //keep repeat(3) at 3 or 4 only in order to match the first byte.
foreach(dut_vi.data[j]) // this works
// for ( int j = 0; j < pkt.size ; j++)
begin
$display("san- Display of the packet contents %h",dut_vi.data);
@(dut_vi.clock); //added later
bq.push_back(dut_vi.data);
$display("san1- Display of the packet contents %p",bq);
@(dut_vi.clock); //keep this uncommented
end
$display("san3- Display of the packet contents %h",bq.size());
bytes = new[bq.size()] (bq); //(bq)
@(dut_vi.clock);
uvm_report_info(get_full_name(),"Received packet from the DUT into the Monitor...",UVM_LOW);
// pkt = transaction::type_id::create("pkt");
pkt = new("pkt1");
uvm_default_packer.use_metadata = 1;
void'(pkt.unpack_bytes(bytes)); // void'(tx.unpack_bytes(bytes)); //gives some sync values with unpack_bytes. and no values with pack_bytes.
//The unpack methods extract property values from an array of bits,bytes or ints.
pkt.print();
@(dut_vi.clock);
Montr2Agnt_port.write(pkt);
uvm_report_info(get_full_name(),"Sending received packet from monitor to the Scoreboard ...",UVM_LOW);
end
endtask: run_phase
Please help me out here as this is urgent and important. I m stuck at here since some time now.
Any help is appreciated.
Thanks