blob: f6815a1e46c6c2c946996da27f9147cbbfb80953 [file] [log] [blame] [edit]
////////////////////////////////////////////////
////s~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~s////
////s www.testbench.in s////
////s s////
////s SystemVerilog Tutorial s////
////s gopi@testbench.in s////
////s~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~s////
////////////////////////////////////////////////
`ifndef GUARD_PACKET
`define GUARD_PACKET
//Define the enumerated types for packet types
typedef enum { GOOD_FCS, BAD_FCS } fcs_kind_t;
typedef enum { GOOD_LENGTH, BAD_LENGTH } length_kind_t;
class packet;
rand fcs_kind_t fcs_kind;
rand length_kind_t length_kind;
rand bit [7:0] length;
rand bit [7:0] da;
rand bit [7:0] sa;
rand byte data[];//Payload using Dynamic array,size is generated on the fly
rand byte fcs;
constraint address_c { da inside {`P0,`P1,`P2,`P3} ; }
constraint payload_size_c { data.size inside { [1 : 250]};}
constraint length_kind_c {
(length_kind == GOOD_LENGTH) -> length == data.size;
(length_kind == BAD_LENGTH) -> length == data.size + 2 ; }
constraint solve_size_length { solve data.size before length; }
constraint fcs_kind_c {
(fcs_kind == GOOD_FCS) -> fcs == 8'b0;
(fcs_kind == BAD_FCS) -> fcs == 8'b1; }
///// method to calculate the fcs /////
function byte 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 print the packet fields ////
virtual function void display();
$display("\n---------------------- PACKET KIND ------------------------- ");
$display(" fcs_kind : %s ",fcs_kind.name() );
$display(" length_kind : %s ",length_kind.name() );
$display("-------- PACKET ---------- ");
$display(" 0 : %h ",da);
$display(" 1 : %h ",sa);
$display(" 2 : %h ",length);
foreach(data[i])
$write("%3d : %0h ",i + 3,data[i]);
$display("\n %2d : %h ",data.size() + 3 , cal_fcs);
$display("----------------------------------------------------------- \n");
endfunction : display
///// method to pack the packet into bytes/////
virtual function int unsigned byte_pack(ref logic [7:0] bytes[]);
bytes = new[data.size + 4];
bytes[0] = da;
bytes[1] = sa;
bytes[2] = length;
foreach(data[i])
bytes[3 + i] = data[i];
bytes[data.size() + 3] = cal_fcs;
byte_pack = bytes.size;
endfunction : byte_pack
////method to unpack the bytes in to packet /////
virtual function void byte_unpack(const ref logic [7:0] bytes[]);
this.da = bytes[0];
this.sa = bytes[1];
this.length = bytes[2];
this.fcs = bytes[bytes.size - 1];
this.data = new[bytes.size - 4];
foreach(data[i])
data[i] = bytes[i + 3];
this.fcs = 0;
if(bytes[bytes.size - 1] != cal_fcs)
this.fcs = 1;
endfunction : byte_unpack
//// method to compare the packets /////
virtual function bit 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
/*
program test;
packet pkt1 = new();
packet pkt2 = new();
logic [7:0] bytes[];
initial
repeat(10)
if(pkt1.randomize)
begin
$display(" Randomization Sucessesfull.");
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 ***");
endprogram
*/
`endif