Packet is a class with all the fields in the packet randomly.
Types of possible packets :
Packet with DA with one of the configured port address..
Packets with DA which has unconfigured address.
Packets with valid and invalid length.
Packets with good and bad FCS.
Payload size types: SMALL, MEDIUM and LARGE
Use Constraints to get valid da.
Put packet id as the first feild in data. This is for debugging. Looking at the id ,its easy to identyfy the packet.
A method to unpack the data. When the reciver recives data, it is at low level. Using unpack, da,sa,length,data and fcs feilds can be separated.
CODE: packet.vr ////Define the enumerated types for packet payload size type
//typedef enum payload_size_t { SMALL, MEDIUM, LARGE } ;
//typedef enum packet_kind_t { GOOD, BAD };
class packet{
//Define the enumerated types for packet payload size type
enum payload_size_t = SMALL, MEDIUM, LARGE ;
enum packet_kind_t = GOOD, BAD ;
rand payload_size_t payload_size; // Control field for the payload size
rand packet_kind_t packet_kind; // Control field for GOOD/BAD
bit [7:0] uid; // Unique id field to identify the packet
cfg_drvr cfg;
randbit [7:0] len;
randbit [7:0] da;
randbit [7:0] sa;
bit [7:0] data[*];//Payload using Dynamic array,size is generated on the fly
randbit [7:0] parity;
bit [7:0] mem [4];
// Constrain the len according the payload_size control field
constraint len_size {
(payload_size == SMALL ) => len in {5 : 6};
(payload_size == MEDIUM ) => len in {7 : 8};
(payload_size == LARGE ) => len in {9 : 10}; }
// May be assigned either a good or bad value,parity will be calculated in portrandomize
constraint parity_type {
(packet_kind == GOOD ) => parity == 0;
(packet_kind == BAD ) => parity != 0;}
//////////////////////////////////////////////////////////////
// parity_calc()
//
// Return the byte resulting from xor-ing among all data bytes
// and the byte resulting from concatenating addr and len
//////////////////////////////////////////////////////////////
functionbit [7:0] parity_cal(){
integer i;
bit [7:0] result ;
result = 8'hff;
result = result ^ da;
result = result ^ sa;
result = result ^ len;
data = new [len];
data[0] = uid ;
result = result ^ data[0];
for (i = 1;i<len;i++)
{
data[i] = random();
result = result ^ data[i];
}
parity_cal = result;
}
//post randomize fun to cal parity
taskpost_randomize(){
parity = parity ^ parity_cal();
printf("[PKT] da %h sa %h len %h parit %h \n",this.da,this.sa,this.len,this.parity);
}
//new task,uid is assigned when object is created
tasknew(bit [7:0] i,cfg_drvr cfg){
uid=i;
this.cfg = cfg;
}
//unpacking task for converting recived data to class properties
task byte_unpack(bit [7:0] bytes[$]){
void = bytes.pop_front();
printf("[UNPACKING] bytes size %d\n",bytes.size());
foreach(bytes,i)
printf("[UNPACKING] bytes %b :%0d\n",bytes[i],i);
da = bytes.pop_front();
sa = bytes.pop_front();
len = bytes.pop_front();
data = new [len];
parity = bytes.pop_back();
foreach (data,i) data[i] = bytes.pop_front();