Code Browser Pages:
Files in
vmm_switch_4.tar



filelist
Globals.sv
interface.sv
Current file: Packet.sv
README.txt



////////////////////////////////////////////////
////s~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~s////
////s           www.testbench.in           s////
////s                                      s////
////s             VMM 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 extends vmm_data;

static vmm_log log = new("Packet","Class");

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 bit [7:0] 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 : 255]};}

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; }

function new();
     super.new(this.log);
endfunction:new

function void post_randomize();
     if(fcs_kind == GOOD_FCS)
         fcs = 8'b0;
     else
        fcs = 8'b1;
     fcs = cal_fcs();
endfunction : post_randomize

///// method to calculate the fcs /////
virtual 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

virtual function vmm_data allocate();
     Packet pkt;
     pkt = new();
     return pkt;
endfunction:allocate

virtual function string psdisplay(string prefix = "");
    int i;

    $write(psdisplay, "      packet #0.0.0\n", prefix,this.stream_id, this.scenario_id, this.data_id);
    $write(psdisplay, "      da:0x%h\n", psdisplay, prefix,this.da);
    $write(psdisplay, "      sa:0x%h\n", psdisplay, prefix,this.sa);
    $write(psdisplay, "      length:0x%h (data.size=0)\n", psdisplay, prefix,this.length,this.data.size());
    $write(psdisplay, "      data[0]:0x%h", psdisplay, prefix,0,data[0]);
    if(data.size() > 1)
        $write(psdisplay, "   data[0]:0x%h", 1,data[1]);
    if(data.size() > 4)
        $write(psdisplay, "  ....  ");
    if(data.size() > 2)
        $write(psdisplay, "   data[0]:0x%h", data.size() -2,data[data.size() -2]);
    if(data.size() > 3)
        $write(psdisplay, "   data[0]:0x%h", data.size() -1,data[data.size() -1]);
    $write(psdisplay, "\n      fcs:0x%h \n", psdisplay, prefix, this.fcs);

 endfunction


virtual function vmm_data copy(vmm_data to = null);
    Packet cpy;

    // Copying to a new instance?
    if (to == null)
       cpy = new;
     else

    // Copying to an existing instance. Correct type?
    if (!$cast(cpy, to))
       begin
       `vmm_fatal(this.log, "Attempting to copy to a non packet instance");
       copy = null;
       return copy;
       end


    super.copy_data(cpy);

    cpy.da = this.da;
    cpy.sa = this.sa;
    cpy.length = this.length;
    cpy.data = new[this.data.size()];
    foreach(data[i])
        begin
       cpy.data[i] = this.data[i];
        end
    cpy.fcs = this.fcs;
    copy = cpy;
 endfunction:copy



virtual function bit compare(input vmm_data   to,output string diff,input int   kind = -1);
    Packet cmp;

    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 compare;
     end

    // data types are the same, do comparison:
    if (this.da != cmp.da)
    begin
       diff = $psprintf("Different DA values: 0 != 0", this.da, cmp.da);
       compare = 0;
       return compare;
    end

    if (this.sa != cmp.sa)
    begin
       diff = $psprintf("Different SA values: 0 != 0", this.sa, cmp.sa);
       compare = 0;
       return compare;
    end
    if (this.length != cmp.length)
    begin
       diff = $psprintf("Different LEN values: 0 != 0", this.length, cmp.length);
       compare = 0;
       return compare;
    end

    foreach(data[i])
       if (this.data[i] != cmp.data[i])
       begin
          diff = $psprintf("Different data[0] values: 0x%h != 0x%h",i, this.data[i], cmp.data[i]);
          compare = 0;
          return compare;
       end
    if (this.fcs != cmp.fcs)
    begin
       diff = $psprintf("Different FCS values: 0 != 0", this.fcs, cmp.fcs);
       compare = 0;
       return compare;
    end
 endfunction:compare

virtual function int unsigned byte_pack(
                     ref logic [7:0] bytes[],
                     input int unsigned offset =0 ,
                     input int   kind = -1);
      byte_pack = 0;
      bytes = new[this.data.size() + 4];
      bytes[0] = this.da;
      bytes[1] = this.sa;
      bytes[2] = this.length;

      foreach(data[i])
          bytes[3+i] = data[i];

      bytes[this.data.size() + 3 ] = fcs;
      byte_pack = this.data.size() + 4;
endfunction:byte_pack

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);
      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])
      this.data[i] = bytes[i+3];
      return bytes.size();
endfunction:byte_unpack

endclass

/////////////////////////////////////////////////////////
//// Create vmm_channel and vmm_atomic_gen for packet////
/////////////////////////////////////////////////////////
`vmm_channel(Packet)
`vmm_atomic_gen(Packet, "Packet Gen")

/////////////////////////////////////////////////////////
////    Test to check the packet implementation      ////
/////////////////////////////////////////////////////////
program test;

    Packet pkt1 = new();
    Packet pkt2 = new();
    string diff;
    logic [7:0] bytes[];

    initial
    repeat(100)
       if(pkt1.randomize)
       begin
          $display(" Randomization Sucessesfull.");
          $display(pkt1.psdisplay("Pkt1"));
          void'(pkt1.byte_pack(bytes));
          pkt2 = new();
          pkt2.byte_unpack(bytes);
          $display(pkt1.psdisplay("Pkt2"));
          if(pkt2.compare(pkt1,diff))
              $display(" Packing,Unpacking and compare worked");
          else
              $display(" *** Something went wrong in Packing or Unpacking or compare *** \n \n ",diff);

       end
       else
       $display(" *** Randomization Failed ***");

    final
    $display(" ******************** End of testcase *****************");
endprogram




`endif