Code Browser Pages:
| // by gopi@testbench.in `include "vmm.sv" `ifndef PKT_CLASS `define PKT_CLASS `define MCAST_ADD_VAL 48'h81_81_81_81_81_81 `define MCAST_ADD_INV 48'h81_00_00_00_00_81 `define UCAST_ADD_VAL 48'h00_ff_00_ff_00_ff `define UCAST_ADD_INV 48'h00_ff_ff_ff_ff_00 `define MCAST_PAUSE_ADD 48'h01_80_c2_00_00_01 `define MAX_NUM_OF_VLANS 4 `define SA_ADD 48'h00_00_00_00_00_00 `define SEED 0 `ifndef PACK `define SHOW 0 `else `define SHOW 1 `endif typedef enum {MCAST_VALID,MCAST_INVALID,UCAST_VALID,UCAST_INVALID,BCAST}DA_e ; typedef enum {LENGTH,JUMBO,PAUSE,CNTRL} TYPE_e ; typedef enum {SVLAN,VLAN,MVLAN,NOTAG} TAG_e ; typedef enum {LES_46,EQL_46,BW_47_TO_1500,GTR_1536,LEN_INVALID} LENGTH_e ; typedef enum {TIME_ZERO,TIME_FFFF,TIME_RAND} TIME_e ; typedef enum {LEN_GOOD,LEN_BAD} LENERR_e ; typedef enum {RANDTYPE,ZERO} PAYLOAD_e ; class packet extends vmm_data; static vmm_log log = new("packet", "class"); rand DA_e DA_t ; rand TAG_e TAG_t ; rand TYPE_e TYPE_t ; rand LENGTH_e LENGTH_t; rand TIME_e TIME_t ; rand LENERR_e LENERR_t; rand integer Num_Of_Vlans; rand integer length; static integer No; integer Pkt_No; bit [7:0] Pkt_Packed []; bit [7:0] data [$]; bit [31 :0]Crc; bit [31:0] Table [256]; PAYLOAD_e PAYLOAD_t; constraint length_c { if ((TYPE_t == LENGTH )& LENGTH_t == LES_46) {length inside { [1 :45]}; } else if ((TYPE_t == LENGTH )& LENGTH_t == EQL_46) {length == 46 ; } else if ((TYPE_t == LENGTH )& LENGTH_t == BW_47_TO_1500){length inside { [47 :1500]}; } else if ((TYPE_t == LENGTH )& LENGTH_t == GTR_1536) {length inside { [1536 :1636]};} else if ((TYPE_t == LENGTH )& LENGTH_t == LEN_INVALID) {length inside { [1501:1535]}; } else if (TYPE_t == JUMBO & LENERR_t == LEN_GOOD) {length inside { [47 :9000]}; } else if (TYPE_t == JUMBO & LENERR_t == LEN_BAD) {length inside { [1:46],[9001 :9999]}; } else if (TYPE_t == PAUSE & LENERR_t == LEN_GOOD ) {length == 42 ; } else if (TYPE_t == PAUSE & LENERR_t == LEN_BAD ) {length inside {[1:41],[43:9999]};} else if (TYPE_t == CNTRL & LENERR_t == LEN_GOOD ) {length == 46 ; } else if (TYPE_t == CNTRL & LENERR_t == LEN_BAD ) {length inside {[1:45],[47:9999]};} } constraint len_c {LENGTH_t dist {LES_46 := 15,EQL_46 := 5,BW_47_TO_1500 := 45,GTR_1536 := 15,LEN_INVALID := 15}; } constraint tag_c {TAG_t dist {SVLAN := 25 ,VLAN := 20,MVLAN := 30,NOTAG := 25}; } constraint lenerr_c { LENERR_t dist {LEN_GOOD:= 70,LEN_BAD :=30};} constraint type_c { TYPE_t dist {LENGTH := 82,JUMBO := 3,PAUSE := 12,CNTRL := 3}; } constraint pausetime_c { if(TYPE_t == PAUSE ) TIME_t dist { TIME_ZERO := 10,TIME_FFFF := 10,TIME_RAND := 80}; } constraint vlans { if (TAG_t == MVLAN) {Num_Of_Vlans inside {[2 : `MAX_NUM_OF_VLANS] };}} constraint test_case ; function new(); super.new(this.log); CrcTable(); Num_Of_Vlans = 0; PAYLOAD_t = RANDTYPE; if(No === 'bx) No = 0; endfunction virtual function vmm_data copy (vmm_data to = null); packet cpy; if (to != null) begin if (!$cast(cpy, to)) begin `vmm_fatal(log,"Not a pkt instance"); return; end end else cpy = new; this.copy_data(cpy); cpy.DA_t = this.DA_t ; cpy.TAG_t = this.TAG_t ; cpy.TYPE_t = this.TYPE_t ; cpy.LENGTH_t = this.LENGTH_t ; cpy.TIME_t = this.TIME_t ; cpy.LENERR_t = this.LENERR_t ; cpy.Num_Of_Vlans = this.Num_Of_Vlans ; cpy.length = this.length ; cpy.Pkt_No = this.Pkt_No ; copy = cpy; endfunction function void pre_randomize(); No++ ; Pkt_No = No ; endfunction virtual function string psdisplay(string prefix = ""); psdisplay = prefix; if (DA_t == MCAST_VALID ) psdisplay = $psprintf (" ",psdisplay,"|MCAST_VALID "); if (DA_t == MCAST_INVALID) psdisplay = $psprintf (" ",psdisplay,"|MCAST_INVALID"); if (DA_t == UCAST_VALID ) psdisplay = $psprintf (" ",psdisplay,"|UCAST_VALID "); if (DA_t == UCAST_INVALID) psdisplay = $psprintf (" ",psdisplay,"|UCAST_INVALID"); if (DA_t == BCAST ) psdisplay = $psprintf (" ",psdisplay,"|BCAST "); psdisplay = $psprintf(" ",psdisplay,"|SA"); if (TAG_t == SVLAN ) psdisplay = $psprintf (" ",psdisplay,"|SVLAN "); if (TAG_t == VLAN ) psdisplay = $psprintf (" ",psdisplay,"|VLAN "); if (TAG_t == MVLAN ) psdisplay = $psprintf (" ",psdisplay,"|MVLAN"); if (TAG_t == MVLAN ) psdisplay = $psprintf (" ",psdisplay,"0",Num_Of_Vlans); if (TAG_t == NOTAG ) psdisplay = $psprintf (" ",psdisplay,"|NOTAG "); if (TYPE_t == LENGTH ) psdisplay = $psprintf (" ",psdisplay,"|LENGTH"); if (TYPE_t == JUMBO ) psdisplay = $psprintf (" ",psdisplay,"|JUMBO "); if (TYPE_t == PAUSE ) psdisplay = $psprintf (" ",psdisplay,"|PAUSE "); if (TYPE_t == CNTRL ) psdisplay = $psprintf (" ",psdisplay,"|CNTRL "); if (TYPE_t == LENGTH ) begin if (LENGTH_t== LES_46 ) psdisplay = $psprintf (" ",psdisplay,"|LES_46 "); if (LENGTH_t== EQL_46 ) psdisplay = $psprintf (" ",psdisplay,"|EQL_46 "); if (LENGTH_t== BW_47_TO_1500) psdisplay = $psprintf (" ",psdisplay,"|BW_47_TO_1500"); if (LENGTH_t== GTR_1536 ) psdisplay = $psprintf (" ",psdisplay,"|GTR_1536 "); if (LENGTH_t== LEN_INVALID ) psdisplay = $psprintf (" ",psdisplay,"|LEN_INVALID "); end else if (TYPE_t == PAUSE ) begin if (TIME_t == TIME_ZERO ) psdisplay = $psprintf (" ",psdisplay,"|TIME_ZERO "); if (TIME_t == TIME_FFFF ) psdisplay = $psprintf (" ",psdisplay,"|TIME_FFFF "); if (TIME_t == TIME_RAND ) psdisplay = $psprintf (" ",psdisplay,"|TIME_RAND "); end else psdisplay = $psprintf(" ",psdisplay,"| "); psdisplay = $psprintf(" ",psdisplay,"|DataLen: 0",length); if (LENERR_t== LEN_GOOD ) psdisplay = $psprintf (" ",psdisplay,"|LEN_GOOD"); if (LENERR_t== LEN_BAD ) psdisplay = $psprintf (" ",psdisplay,"|LEN_BAD "); endfunction virtual task CrcTable(); integer i,j; bit[31:0] crc; for(i = 0; i < 256; i++) begin crc = i; for(j = 0; j < 8; j++) begin if(crc[0] == 1) begin crc = {1'b0,crc[31:1]}; crc = crc ^ 32'hEDB8_8320; end else begin crc = {1'b0,crc[31:1]}; end end Table[255 - i] = crc; end endtask virtual task calcCrc(bit [7:0] pkt); integer i; i = Crc[7:0] ^ pkt; Crc = {8'h0,Crc[31:8]}; Crc = Crc ^ Table[255 - i]; endtask virtual function int unsigned byte_pack(ref logic [7:0] bytes[], input int unsigned offset = 0, input int kind = -1); bit [47:0] temp; integer i; if (DA_t == MCAST_VALID & TYPE_t != PAUSE ) temp = `MCAST_ADD_VAL; else if (DA_t == MCAST_VALID & TYPE_t == PAUSE ) temp = `MCAST_PAUSE_ADD; else if (DA_t == MCAST_INVALID ) temp = `MCAST_ADD_INV; else if (DA_t == UCAST_VALID ) temp = `UCAST_ADD_VAL; else if (DA_t == UCAST_INVALID ) temp = `UCAST_ADD_INV; else if (DA_t == BCAST ) temp = 48'hFF_FF_FF_FF_FF_FF; else `vmm_debug(this.log,$psprintf (" DA TYPE ERROR IN ENV ")); bytes = new[6 + bytes.size()](bytes); {bytes[bytes.size() - 6],bytes[bytes.size() -5],bytes[bytes.size() -4],bytes[bytes.size() -3],bytes[bytes.size() -2],bytes[bytes.size() -1]}=temp; `vmm_debug(this.log,$psprintf("\nDA :0",{bytes[bytes.size() - 6],bytes[bytes.size() -5],bytes[bytes.size() -4],bytes[bytes.size() -3],bytes[bytes.size() -2],bytes[bytes.size() -1]})); bytes = new[6 + bytes.size()](bytes); {bytes[bytes.size() - 6],bytes[bytes.size() -5],bytes[bytes.size() -4],bytes[bytes.size() -3],bytes[bytes.size() -2],bytes[bytes.size() -1]}=`SA_ADD; `vmm_debug(this.log,$psprintf("\n size 0 ",bytes.size())); `vmm_debug(this.log,$psprintf("SA :0",{bytes[bytes.size() - 6],bytes[bytes.size() -5],bytes[bytes.size() -4],bytes[bytes.size() -3],bytes[bytes.size() -2],bytes[bytes.size() -1]})); if(TAG_t == VLAN) begin bytes = new[2 + bytes.size()](bytes); {bytes[bytes.size() - 2],bytes[bytes.size() - 1]} = 16'h81_00; `vmm_debug(this.log,$psprintf("\n size 0 ",bytes.size())); `vmm_debug(this.log,$psprintf("VLAN :0",{bytes[bytes.size() - 2],bytes[bytes.size() - 1]})); bytes = new[2 + bytes.size()](bytes); {bytes[bytes.size() - 2],bytes[bytes.size() - 1]} = 16'h11_11; `vmm_debug(this.log,$psprintf("\n size 0 ",bytes.size())); `vmm_debug(this.log,$psprintf("TAG CONTROL:0",{bytes[bytes.size() - 2],bytes[bytes.size() - 1]})); end else if (TAG_t == SVLAN) begin bytes = new[2 + bytes.size()](bytes); {bytes[bytes.size() - 2],bytes[bytes.size() - 1]} = 16'h92_00; `vmm_debug(this.log,$psprintf("\n size 0 ",bytes.size())); `vmm_debug(this.log,$psprintf("SVALN :0",{bytes[bytes.size() - 2],bytes[bytes.size() - 1]}) ); bytes = new[2 + bytes.size()](bytes); {bytes[bytes.size() - 2],bytes[bytes.size() - 1]} = 16'h11_11; `vmm_debug(this.log,$psprintf("\n size 0 ",bytes.size())); `vmm_debug(this.log,$psprintf("TAG CONTROL:0",{bytes[bytes.size() - 2],bytes[bytes.size() - 1]})); end else if (TAG_t == MVLAN) begin for (i =0;i< Num_Of_Vlans ;i++) begin bytes = new[2 + bytes.size()](bytes); {bytes[bytes.size() - 2],bytes[bytes.size() - 1]} = 16'h81_00; `vmm_debug(this.log,$psprintf("\n size 0 ",bytes.size())); `vmm_debug(this.log,$psprintf("MVALN :0",{bytes[bytes.size() - 2],bytes[bytes.size() - 1]} )); bytes = new[2 + bytes.size()](bytes); {bytes[bytes.size() - 2],bytes[bytes.size() - 1]} = 16'h11_11; `vmm_debug(this.log,$psprintf("\n size 0 ",bytes.size())); `vmm_debug(this.log,$psprintf("TAG CONTROL:0",{bytes[bytes.size() - 2],bytes[bytes.size() - 1]})); end end if (TYPE_t == LENGTH) begin bytes = new[2 + bytes.size()](bytes); if(LENERR_t == LEN_GOOD ) {bytes[bytes.size() - 2],bytes[bytes.size() - 1]} = length; else {bytes[bytes.size() - 2],bytes[bytes.size() - 1]} = length + 1 + $random()%30; `vmm_debug(this.log,$psprintf("\n size 0 ",bytes.size())); `vmm_debug(this.log,$psprintf("LENGTH :0,0",{bytes[bytes.size() - 2],bytes[bytes.size() - 1]},{bytes[bytes.size() - 2],bytes[bytes.size() - 1]})); end else if (TYPE_t == JUMBO) begin bytes = new[2 + bytes.size()](bytes); {bytes[bytes.size() - 2],bytes[bytes.size() - 1]} = 32'h88_70; `vmm_debug(this.log,$psprintf("\n size 0 ",bytes.size())); `vmm_debug(this.log,$psprintf("JUMBO :0",{bytes[bytes.size() - 2],bytes[bytes.size() - 1]})); end else if (TYPE_t == PAUSE) begin bytes = new[4 + bytes.size()](bytes); {bytes[bytes.size() - 4],bytes[bytes.size() - 3],bytes[bytes.size() - 2],bytes[bytes.size() - 1]} = 64'h88_08_00_01; `vmm_debug(this.log,$psprintf("\n size 0 ",bytes.size())); `vmm_debug(this.log,$psprintf("PAUSE :0",{bytes[bytes.size() - 4],bytes[bytes.size() - 3],bytes[bytes.size() - 2],bytes[bytes.size() - 1]} )); bytes = new[2 + bytes.size()](bytes); if(TIME_t == TIME_ZERO) i=0; else if(TIME_t == TIME_FFFF) i=32'hFFFF; else i= $random(); {bytes[bytes.size() - 2],bytes[bytes.size() - 1]} = i; `vmm_debug(this.log,$psprintf("\n size 0 ",bytes.size())); `vmm_debug(this.log,$psprintf("PAUSETIME :0",{bytes[bytes.size() - 2],bytes[bytes.size() - 1]}) ); end else if (TYPE_t == CNTRL) begin bytes = new[2 + bytes.size()](bytes); {bytes[bytes.size() - 2],bytes[bytes.size() - 1]} = 32'h88_08; `vmm_debug(this.log,$psprintf("\n size 0 ",bytes.size())); `vmm_debug(this.log,$psprintf("CNTRL :0",{bytes[bytes.size() - 2],bytes[bytes.size() - 1]})); end bytes = new[length + bytes.size()](bytes); `vmm_debug(this.log,$psprintf("\n size 0 ",bytes.size())); `vmm_debug(this.log,$psprintf(" DATA LENGTH :0 ",length)); bytes[bytes.size() - length ]=Pkt_No; for(i = bytes.size() - length ;i < bytes.size() ;i++) if(PAYLOAD_t == RANDTYPE) bytes[i]= $random(); else bytes[i]= 0; Pkt_Packed = new[bytes.size()]; foreach(Pkt_Packed[i]) Pkt_Packed[i] = bytes[i]; byte_pack = bytes.size(); endfunction //packing //unpacking function for converting recived data to class properties virtual function int unsigned byte_unpack(const ref logic [7:0] bytes[], input int unsigned offset = 0, input int len = -1, input int kind = -1); bit[7:0] byte1,byte2; bit[47:0] add; integer length,i,q; q = 0; byte1 = 8'h00; length = bytes.size(); Pkt_Packed = new[length]; while(byte1 != 8'hd5) begin byte1 = bytes[q]; q++; end `vmm_debug(this.log,$psprintf(" Preamble length 0 ",q)); Pkt_Packed = new[bytes.size() - q]; foreach(Pkt_Packed[i]) Pkt_Packed[i] = bytes[q+i]; add[47:40] = bytes[q];q++; add[39:32] = bytes[q];q++; add[31:24] = bytes[q];q++; add[23:16] = bytes[q];q++; add[15: 8] = bytes[q];q++; add[ 7: 0] = bytes[q];q++; if(add == `MCAST_ADD_VAL) DA_t = MCAST_VALID ; else if(add == `MCAST_PAUSE_ADD) begin DA_t = MCAST_VALID ; TYPE_t = PAUSE ; end else if(add == `MCAST_ADD_INV) DA_t = MCAST_INVALID ; else if(add == `UCAST_ADD_VAL) DA_t = UCAST_VALID ; else if(add == `UCAST_ADD_INV ) DA_t = UCAST_INVALID; else if(add == 48'hFF_FF_FF_FF_FF_FF) DA_t = BCAST ; `vmm_debug(this.log,$psprintf(" DA is %h ",add)); add[47:40] = bytes[q];q++; add[39:32] = bytes[q];q++; add[31:24] = bytes[q];q++; add[23:16] = bytes[q];q++; add[15: 8] = bytes[q];q++; add[ 7: 0] = bytes[q];q++; `vmm_debug(this.log,$psprintf(" SA is %h ",add)); TAG_t = NOTAG ; for(Num_Of_Vlans = 0; Num_Of_Vlans < 10;Num_Of_Vlans++) begin byte1 = bytes[q];q++; byte2 = bytes[q];q++; if(({byte1,byte2} == 16'h92_00)|| ({byte1,byte2} == 16'h81_00)) begin `vmm_debug(this.log,$psprintf(" Vlan :%h ",{byte1,byte2})); if({byte1,byte2} == 16'h92_00) TAG_t = SVLAN ; else if({byte1,byte2} == 16'h81_00) TAG_t = VLAN ; byte1 = bytes[q];q++; byte2 = bytes[q];q++; `vmm_debug(this.log,$psprintf(" TagFeild :%h ",{byte1,byte2})); end else break; end `vmm_debug(this.log,$psprintf(" TYPEFeild :%h ",{byte1,byte2})); `vmm_debug(this.log,$psprintf("Num_Of_Vlans 0",Num_Of_Vlans)); if(Num_Of_Vlans > 1) TAG_t = MVLAN ; if({byte1,byte2} == 32'h88_70) TYPE_t = JUMBO ; else if({byte1,byte2} == 16'h88_08) begin `vmm_debug(this.log,$psprintf(" CNTRL PKT Recieved ")); byte1 = bytes[q];q++; byte2 = bytes[q];q++; `vmm_debug(this.log,$psprintf(" TYPEFeild :%h ",{byte1,byte2})); if({byte1,byte2} == 16'h00_01) begin `vmm_debug(this.log,$psprintf(" PAUSE PKT Recieved ")); byte1 = bytes[q];q++; byte2 = bytes[q];q++; `vmm_debug(this.log,$psprintf(" Pause time :%h ",{byte1,byte2})); if({byte1,byte2} == 16'h0) TIME_t = TIME_ZERO; else if({byte1,byte2} == 16'hFFFF) TIME_t = TIME_FFFF; else TIME_t = TIME_RAND; end end else if(({byte1,byte2} < 1535) && ({byte1,byte2} > 1)) TYPE_t = LENGTH ; length = bytes.size() - 4 - q; endfunction virtual function bit check_crc(); integer i; Crc = 32'hffff_ffff; for(i = 0;i < Pkt_Packed.size() - 4;i++) calcCrc(Pkt_Packed[i]); if({Pkt_Packed[Pkt_Packed.size() - 4],Pkt_Packed[Pkt_Packed.size() - 3],Pkt_Packed[Pkt_Packed.size() - 2],Pkt_Packed[Pkt_Packed.size() - 1]} == ~{Crc[7:0],Crc[15:8],Crc[23:16],Crc[31:24]}) begin `vmm_debug(this.log,$psprintf(" GOOD CRC ")); check_crc = 1; end else begin `vmm_debug(this.log,$psprintf(" BAD CRC ")); check_crc = 0;end `vmm_debug(this.log,$psprintf(" %h %h",{Pkt_Packed[Pkt_Packed.size() - 4],Pkt_Packed[Pkt_Packed.size() - 3],Pkt_Packed[Pkt_Packed.size() - 2],Pkt_Packed[Pkt_Packed.size() - 1]},~{Crc[7:0],Crc[15:8],Crc[23:16],Crc[31:24]})); endfunction virtual function bit compare(vmm_data to,output string diff,input int kind = -1); packet cmp; integer i; compare = 1; // Assume success by default. diff = "No differences found"; if (!$cast(cmp, to)) begin `vmm_fatal(this.log, "Attempting to compare to a non packet instance"); compare = 0; diff = "Cannot compare non packets"; return; end if(this.Pkt_Packed.size() < 60 ) begin if( cmp.Pkt_Packed.size() != 64) begin diff = $psprintf("ERROR in length match: sent pkt length is 0 expected pkt length is 64 , recieved packet length is 0 ",this.Pkt_Packed.size(),cmp.Pkt_Packed.size()); compare = 0; return ; end end else if((4 + this.Pkt_Packed.size() ) != cmp.Pkt_Packed.size()) begin diff = $psprintf("ERROR in length match 0 0 ",this.Pkt_Packed.size(),cmp.Pkt_Packed.size()); compare = 0; return ; end foreach(Pkt_Packed[i]) if(this.Pkt_Packed[i] != cmp.Pkt_Packed[i]) begin diff = $psprintf("0 ERROR in data match %h %h ",i,this.Pkt_Packed[i],cmp.Pkt_Packed[i]); compare = 0; return ; end endfunction virtual function vmm_data allocate(); packet p = new; allocate = p; endfunction endclass `endif |