In this Phase, We will define a packet and then test it whether it is generating as expected.
Packet is modeled using class. Packet class should be able to generate all possible packet types randomly. Packet class should also implement required methods like packing(), unpacking(), compare() and display() methods.
We will write the packet class in packet.sv file. Packet class variables and constraints have been derived from stimulus generation plan.
Revisit Stimulus Generation Plan
1) Packet DA: Generate packet DA with the configured address.
2) Payload length: generate payload length ranging from 2 to 255.
3) Correct or Incorrect Length field.
4) Generate good and bad FCS.
1) Declare FCS types as enumerated data types. Name members as GOOD_FCS and BAD_FCS.
typedefenum { GOOD_FCS, BAD_FCS } fcs_kind_t;
2) Declare the length type as enumerated data type. Name members as GOOD_LENGTH and BAD_LENGTH.
functionbyte cal_fcs;
integer i;
byte result ;
result = 0;
result = result ^ da;
result = result ^ sa;
result = result ^ length;
for (i = 0;i< data.size;i++)
result = result ^ data[i];
result = fcs ^ result;
return result;
endfunction : cal_fcs
10) Define display methods:
Display method displays the current value of the packet fields to standard output.
Packing is commonly used to convert the high level data to low level data that can be applied to DUT. In packet class various fields are generated. Required fields are concatenated to form a stream of bytes which can be driven conveniently to DUT interface by the driver.
The unpack() method does exactly the opposite of pack method. Unpacking is commonly used to convert a data stream coming from DUT to high level data packet object.
14) Define a compare method.
Compares the current value of the object instance with the current value of the specified object instance.
If the value is different, FALSE is returned.
virtualfunctionbit compare(packet pkt);
compare = 1;
if(pkt == null)
begin $display(" ** ERROR ** : pkt : received a null object ");
compare = 0;
end else begin if(pkt.da !== this.da)
begin $display(" ** ERROR **: pkt : Da field did not match");
compare = 0;
end if(pkt.sa !== this.sa)
begin $display(" ** ERROR **: pkt : Sa field did not match");
compare = 0;
end
if(pkt.length !== this.length)
begin $display(" ** ERROR **: pkt : Length field did not match");
compare = 0;
end foreach(this.data[i])
if(pkt.data[i] !== this.data[i])
begin $display(" ** ERROR **: pkt : Data[%0d] field did not match",i);
compare = 0;
end
if(pkt.fcs !== this.fcs)
begin $display(" ** ERROR **: pkt : fcs field did not match %h %h",pkt.fcs ,this.fcs);
compare = 0;
end end endfunction : compare
Packet Class Source Code
`ifndef GUARD_PACKET
`define GUARD_PACKET
//Define the enumerated types for packet types
typedefenum { GOOD_FCS, BAD_FCS } fcs_kind_t;
typedefenum { GOOD_LENGTH, BAD_LENGTH } length_kind_t;
class packet;
rand fcs_kind_t fcs_kind;
rand length_kind_t length_kind;
randbit [7:0] length;
randbit [7:0] da;
randbit [7:0] sa;
randbyte data[];//Payload using Dynamic array,size is generated on the fly
randbyte fcs;
constraint address_c { da inside {`P0,`P1,`P2,`P3} ; }
///// method to calculate the fcs /////
functionbyte cal_fcs;
integer i;
byte result ;
result = 0;
result = result ^ da;
result = result ^ sa;
result = result ^ length;
for (i = 0;i< data.size;i++)
result = result ^ data[i];
result = fcs ^ result;
return result;
endfunction : cal_fcs
//// method to compare the packets /////
virtualfunctionbit compare(packet pkt);
compare = 1;
if(pkt == null)
begin $display(" ** ERROR ** : pkt : received a null object ");
compare = 0;
end else begin if(pkt.da !== this.da)
begin $display(" ** ERROR **: pkt : Da field did not match");
compare = 0;
end if(pkt.sa !== this.sa)
begin $display(" ** ERROR **: pkt : Sa field did not match");
compare = 0;
end
if(pkt.length !== this.length)
begin $display(" ** ERROR **: pkt : Length field did not match");
compare = 0;
end foreach(this.data[i])
if(pkt.data[i] !== this.data[i])
begin $display(" ** ERROR **: pkt : Data[%0d] field did not match",i);
compare = 0;
end
if(pkt.fcs !== this.fcs)
begin $display(" ** ERROR **: pkt : fcs field did not match %h %h",pkt.fcs ,this.fcs);
compare = 0;
end end endfunction : compare
endclass
Now we will write a small program to test our packet implantation. This program block is not used to verify the DUT.
Write a simple program block and do the instance of packet class. Randomize the packet and call the display method to analyze the generation. Then pack the packet in to bytes and then unpack bytes and then call compare method to check all the methods.
Program Block Source Code
program test;
packet pkt1 = new();
packet pkt2 = new();
logic [7:0] bytes[];
initial repeat(10)
if(pkt1.randomize)
begin $display(" Randomization Successes full.");
pkt1.display();
void'(pkt1.byte_pack(bytes));
pkt2 = new();
pkt2.byte_unpack(bytes);
if(pkt2.compare(pkt1))
$display(" Packing,Unpacking and compare worked");
else $display(" *** Something went wrong in Packing or Unpacking or compare ***");
end else $display(" *** Randomization Failed ***");