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

📄 utils.sv

📁 VMM 文档加源码, synopsys公司很好的验证资料
💻 SV
字号:
// // -------------------------------------------------------------//    Copyright 2004-2008 Synopsys, Inc.//    All Rights Reserved Worldwide// //    Licensed under the Apache License, Version 2.0 (the//    "License"); you may not use this file except in//    compliance with the License.  You may obtain a copy of//    the License at// //        http://www.apache.org/licenses/LICENSE-2.0// //    Unless required by applicable law or agreed to in//    writing, software distributed under the License is//    distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR//    CONDITIONS OF ANY KIND, either express or implied.  See//    the License for the specific language governing//    permissions and limitations under the License.// -------------------------------------------------------------// //// Ethernet utility class//class eth_utils;   local static bit [31:0] crc_table[256];   local static logic init;   /*extern*/ function new();   if (this.init !== 1'b1) begin      bit [7:0] i;            // Initialize the CRC syndrom table      i = 0;      repeat (256) begin         bit [31:0] r;                  r = {i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7]} << 24;         repeat (8) begin            if (r[31]) r = (r << 1) ^ 32'h04C11DB7;            else r <<= 1;         end         this.crc_table[i] =            {r[00], r[01], r[02], r[03], r[04], r[05], r[06], r[07],             r[08], r[09], r[10], r[11], r[12], r[13], r[14], r[15],             r[16], r[17], r[18], r[19], r[20], r[21], r[22], r[23],             r[24], r[25], r[26], r[27], r[28], r[29], r[30], r[31]};         i++;      end      this.init = 1'b1;   end // if (this.init !== 1'b1)endfunction: new   extern function eth_frame bytes_to_frame(vmm_log               log,                                            const ref logic [7:0] bytes[],                                            integer               n_bytes,                                            eth_frame             factory);   extern function void frame_to_bytes(/*const*/ eth_frame frame,                                       ref logic [7:0] bytes[]);   extern function bit [31:0] compute_crc32(const ref logic [7:0] bytes[],                                            input int unsigned   offset = 0,                                            input integer        len    = -1);endclass: eth_utils/*function eth_utils::new();*/   function eth_frame eth_utils::bytes_to_frame(vmm_log               log,                                             const ref logic [7:0] bytes[],                                             integer               n_bytes,                                             eth_frame             factory);   integer i = 0;   integer start_offset;   logic [31:0] fcs;   bytes_to_frame = null;   start_offset = 0;   // Ignore the preamble & SFD   while (i < n_bytes && bytes[i] === 8'b01010101) i++;   if (bytes[i] === 8'b11010101) start_offset = i+1;   // A frame must be at LEAST 18 bytes long (and even that   // would violate the minimum frame length)   if (n_bytes - start_offset < 18) begin      // That is not an error. Could be a frame that was      // aborted due to collision      `vmm_debug(log, "Received frame was <18 bytes long!");      return null;   end   // The last 4 bytes are supposed to be the FCS   fcs = {bytes[n_bytes-4], bytes[n_bytes-3],          bytes[n_bytes-2], bytes[n_bytes-1]};   begin      bit [31:0] crc;      crc = this.compute_crc32(bytes, start_offset, n_bytes-start_offset-4);      if (crc !== fcs) begin         // Bad FCS values indicate partial frames or         // jammed frames due to collisions. Not an error either         `vmm_debug(log, $psprintf("Received frame with bad FCS: %h instead of %h", fcs, crc));         return null;      end   end   // Example 4-62   // Looks like we have a valid frame!   $cast(bytes_to_frame, factory.copy());        bytes_to_frame.byte_unpack(bytes, start_offset,                              n_bytes - start_offset - 4);   // FCS must be good   bytes_to_frame.fcs = 32'h0;endfunction: bytes_to_frame // Example 4-37function void eth_utils::frame_to_bytes(/*const*/ eth_frame frame,                                        ref logic [7:0] bytes[]);   integer i;   // Preallocate the necessary number of bytes   i = frame.byte_size() + 4;   if (i < 64) i = 64;   bytes = new [i + 8];   // Preamble   for (i = 0; i < 7; i++) begin      bytes[i] = 8'b01010101;   end   // SFD   bytes[7] = 8'b11010101;   i = frame.byte_pack(bytes, 8) + 8;   // Padding?   while (i < 64/*max*/  - 4/*FCS*/ + 8/*Preamble*/) begin      bytes[i++] = $random;   end   // Append the FCS   // Example 4-37   {bytes[i], bytes[i+1], bytes[i+2], bytes[i+3]} =      this.compute_crc32(bytes, 8, i-8) ^ frame.fcs;endfunction: frame_to_bytesfunction bit [31:0] eth_utils::compute_crc32(const ref logic [7:0] bytes[],                                             input int unsigned    offset,                                             input integer         len);   logic [31:0] crc;   integer      i;   if (len < 0) len = bytes.size() - offset;   crc = 32'hFFFFFFFF;   for (i = offset; i < offset+len && i < bytes.size(); i++) begin      // If any bit of the packed data is 'x', it      // will cause a run-time failure because of an      // invalid index in crc_table[]      if ((^bytes[i]) === 1'bx) begin         return 32'hXXXXXXXX;      end      crc = this.crc_table[crc[7:0] ^ bytes[i]] ^                    {8'h00, crc[31:8]};   end   // Invert final result   crc = ~crc;   // Swap bytes to obtain transmit order   compute_crc32[31:24] = crc[ 7: 0];   compute_crc32[23:16] = crc[15: 8];   compute_crc32[15: 8] = crc[23:16];   compute_crc32[ 7: 0] = crc[31:24];endfunction: compute_crc32

⌨️ 快捷键说明

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