⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eth_frame.sv

📁 VMM 文档加源码, synopsys公司很好的验证资料
💻 SV
📖 第 1 页 / 共 2 页
字号:
            $sformat(diff, "pause_time (16'd%0d !== 16'd%0d)",                     this.pause_time, fr.pause_time);            return 0;         end         no_data = 1;      end   end   if (!no_data) begin      if (fr.data.size() !== this.data.size()) begin         $sformat(diff, "data.size() (16'd%0d !== 16'd%0d)",                  this.data.size(), fr.data.size());         return 0;      end      foreach(this.data[i]) begin         if (fr.data[i] !== this.data[i]) begin            $sformat(diff, "data[%0d] (8'h%h !== 8'h%h)",                     i, this.data[i], fr.data[i]);            return 0;         end      end   end   // For FCS, we only care whether they indicate valid or not   if ((fr.fcs === 32'h0000_0000) !== (this.fcs === 32'h0000_0000)) begin      $sformat(diff, "FCS (%0s !== %0s)",               (fr.fcs === 32'h0000_0000) ? "valid" : "invalid",               (this.fcs === 32'h0000_0000) ? "valid" : "invalid");      return 0;   end   return 1;endfunction: comparefunction string eth_frame::psdisplay(string prefix);   bit no_data = 0;          $sformat(psdisplay, "%sEthernet Frame #%0d.%0d.%0d:\n", prefix,            this.stream_id, this.scenario_id, this.data_id);   $sformat(psdisplay, "%s%s   dst=48'h%h, src=48'h%h, len/typ=16'h%h\n",            psdisplay, prefix, this.dst, this.src, this.len_typ);   case (this.format)   TAGGED: begin      $sformat(psdisplay, "%s%s   (tagged) pri=3'd%0d cfi=%b vlan=12'h%h\n",               psdisplay, prefix,               this.user_priority, this.cfi, this.vlan_id);   end   CONTROL: begin      case (this.opcode)      PAUSE: begin         $sformat(psdisplay, "%s%s   PAUSE for %0d quantas\n",                psdisplay, prefix, this.pause_time);         no_data = 1;      end      default: begin         $sformat(psdisplay, "%s%s   opcode=16'h%h\n",                  psdisplay, prefix, this.opcode);      end      endcase   end   endcase   if (!no_data) begin      int i;      $sformat(psdisplay, "%s%s   len=%0d, data=", psdisplay, prefix,               data.size());      for(i = 0; i < this.data.size(); i++) begin         $sformat(psdisplay, "%s 0x%h", psdisplay, this.data[i]);         if (this.data.size() > 8 && i == 5) begin            $sformat(psdisplay, "%s ..", psdisplay);            i = this.data.size() - 3;         end      end      $sformat(psdisplay, "%s\n", psdisplay);   end   $sformat(psdisplay, "%s%s   FCS is %0s", psdisplay, prefix,            (fcs) ? "BAD" : "good");endfunction: psdisplayfunction bit eth_frame::is_valid(bit silent,                                 int kind);   is_valid = this.randomize(null);   if (!is_valid && !silent) begin      `vmm_error(this.log, "Frame is not valid");   endendfunction: is_validfunction int unsigned eth_frame::byte_size(int kind);   byte_size = 18 + data.size();   if (format == TAGGED) byte_size += 4;endfunction: byte_sizefunction int unsigned eth_frame::byte_pack(ref logic [7:0]    array[],                                           input int unsigned offset,                                           input int          kind);   int i;          if (array.size() < offset + this.byte_size(kind)) begin      array = new [offset + this.byte_size(kind)] (array);   end   i = offset;   {array[i  ], array[i+1], array[i+2], array[i+3], array[i+ 4], array[i+ 5]} = this.dst;   {array[i+6], array[i+7], array[i+8], array[i+9], array[i+10], array[i+11]} = this.src;   i += 12;   case (this.format)   UNTAGGED: begin      {array[i], array[i+1]} = this.len_typ;      i += 2;   end   TAGGED: begin      {array[i], array[i+1]} = 16'h8100;      i += 2;      {array[i], array[i+1]} = {this.user_priority, this.cfi, this.vlan_id};      i += 2;      {array[i], array[i+1]} = this.len_typ;      i += 2;   end   // Example 4-38   CONTROL: begin      {array[i], array[i+1]} = 16'h8808;      i += 2;      {array[i], array[i+1]} = this.opcode;      i += 2;      case (this.opcode)      PAUSE: begin         {array[i], array[i+1]} = this.pause_time;         i += 2;      end      endcase   end   endcase   foreach(this.data[j]) begin      array[i++] = this.data[j];   end   {array[i],    array[i+1],    array[i+2],    array[i+3]} = this.utils.compute_crc32(array, offset, i-offset);   byte_pack = i - offset + 4;endfunction: byte_packfunction int unsigned eth_frame::byte_unpack(const ref logic [7:0] array[],                                             input int unsigned    offset,                                             input int             len,                                             input int             kind);   int array_len;   int i, j, k;   int no_data = 0;   // Invalidate this instance to make sure we   // do not have left-over data from a previous instance   // in case of not enough data supplied   this.dst           = 48'hx;   this.src           = 48'hx;   this.user_priority = 3'bx;   this.cfi           = 1'bx;   this.vlan_id       = 12'hx;   this.len_typ       = 16'hx;   this.opcode        = 16'hx;   this.pause_time    = 16'hx;   this.data          = new [0];   this.fcs           = 32'hXXXX_XXXX;   array_len = array.size();   if (len) begin      array_len = len + offset;      if (array_len > array.size()) array_len = array.size();   end   i = offset;   byte_unpack = 0;   // Assume untagged data frame by default   this.format = eth_frame::UNTAGGED;   // Unpack the dst and src addresses   for (k = 0; i < array_len && k < 6; k++) begin      this.dst[47-k*8 -:8] = array[i];      i++;      byte_unpack++;   end   if (i >= array_len) return byte_unpack;   for (k = 0; i < array_len && k < 6; k++) begin      this.src[47-k*8 -:8] = array[i];      i++;      byte_unpack++;   end   if (i >= array_len) return byte_unpack;   // Is this a tagged frame?   if (i+1 >= array_len) return byte_unpack;   // Example 4-41   if ({array[i], array[i+1]} == 16'h8100) begin      this.format = eth_frame::TAGGED;      i += 2;      byte_unpack += 2;      if (i+1 >= array_len) return byte_unpack;      {this.user_priority, this.cfi, this.vlan_id} = {array[i], array[i+1]};      i += 2;      byte_unpack += 2;      if (i+1 >= array_len) return byte_unpack;      this.len_typ = {array[i], array[i+1]};      i += 2;      byte_unpack += 2;   end else if ({array[i], array[i+1]} == 16'h8808) begin      this.len_typ = 16'h8808;      this.format = eth_frame::CONTROL;      i += 2;      byte_unpack += 2;      if (i+1 >= array_len) return byte_unpack;      this.opcode = {array[i], array[i+1]};      i += 2;      byte_unpack += 2;      case (this.opcode)         PAUSE: begin            if (i+1 >= array_len) return byte_unpack;            this.pause_time = {array[i], array[i+1]};            i += 2;            byte_unpack += 2;            no_data = 1;         end      endcase   end else begin      this.len_typ = {array[i], array[i+1]};      i += 2;      byte_unpack += 2;   end   if (i >= array_len) return byte_unpack;   if (no_data == 0) begin      int l = (this.len_typ >= 'h0600 ||               this.len_typ > array_len - 1) ? array_len - i : this.len_typ;      this.data = new [l];         foreach(this.data[k]) begin         this.data[k] = array[i];         i++;         byte_unpack++;      end   end   this.fcs = 32'hx;   if (i+4 > array_len) return byte_unpack;   this.fcs = {array[i], array[i+1], array[i+2], array[i+3]} ^              this.utils.compute_crc32(array, offset, i-offset);endfunction: byte_unpackfunction bit [31:0] eth_frame::compute_fcs();   logic [7:0] bytes[];   int i;   i = this.byte_pack(bytes) - 4;   compute_fcs = {bytes[i], bytes[i+1], bytes[i+2], bytes[i+3]};endfunction: compute_fcs

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -