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

📄 mii_mac.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.// -------------------------------------------------------------//// Example 4-84typedef class mii_mac_layer;virtual class mii_mac_layer_callbacks extends vmm_xactor_callbacks;   virtual task pre_frame_tx(mii_mac_layer     xactor,                             /*const*/ eth_frame         frame,                             ref logic [7:0]   bytes[]);   endtask   virtual task pre_symbol_tx(mii_mac_layer         xactor,                              /*const*/ eth_frame       frame,                              /*const*/ ref logic [7:0] bytes[],                              /*const*/ input integer   nibble_no,                              ref logic [3:0]       symbol,                              ref logic             en,                              ref logic             err,                              ref bit               drop);   endtask   virtual task post_frame_tx(mii_mac_layer         xactor,                              /*const*/ eth_frame       frame,                              /*const*/ ref logic [7:0] bytes[],                              ref bit               error);   endtask   virtual function void post_frame_rx(mii_mac_layer      xactor,                                       /*const*/ eth_frame    frame,                                       /*const*/ logic [7:0]  bytes[],                                       /*const*/ int unsigned n_bytes);   endfunction   virtual function post_symbol_rx(mii_mac_layer      xactor,                                   /*const*/ int unsigned nibble_count,                                   /*const*/ logic [3:0]  symbol,                                   /*const*/ logic        dv,                                   /*const*/ logic        err);   endfunctionendclass: mii_mac_layer_callbacks// Example 4-13// Example 4-48class mii_mac_layer extends vmm_xactor;   // Example 4-55   virtual mii_if.mac_layer sigs;   // Example 4-57   // Example 4-61   eth_frame_channel   tx_chan;   eth_frame_channel   rx_chan;   eth_pls_indications indications;   local mii_cfg   cfg;   local eth_frame rx_factory;   local mii_cfg   hard_rst_cfg;   local eth_frame hard_rst_rx_factory;   local int frame_count;   local eth_utils utils;   // Example 4-54   // Example 4-61   function new(string                   instance,                int unsigned             stream_id = -1,                mii_cfg                  cfg,                virtual mii_if.mac_layer sigs,                eth_frame_channel        tx_chan     = null,                eth_frame_channel        rx_chan     = null,                eth_pls_indications      indications = null,                eth_frame                rx_factory  = null);      super.new("MII MAC Layer", instance, stream_id);      this.cfg = cfg;      // Example 4-55      this.sigs = sigs;      if (tx_chan == null) begin         tx_chan = new({this.log.get_name(), " MAC->PHY frames"}, instance);      end      this.tx_chan = tx_chan;      if (rx_chan == null) rx_chan = new({this.log.get_name(), " PHY->MAC frames"}, instance);      this.rx_chan = rx_chan;      this.log.is_above(this.tx_chan.log);      this.log.is_above(this.rx_chan.log);      if (indications == null) indications = new(this.log);      this.indications = indications;      if (rx_factory == null) rx_factory = new;      this.rx_factory = rx_factory;             this.hard_rst_cfg        = cfg;      this.hard_rst_rx_factory = rx_factory;      this.frame_count = 0;      this.utils = new;      this.sigs.mtx.txd    <= 4'h0;      this.sigs.mtx.tx_en  <= 1'b0;      this.sigs.mtx.tx_err <= 1'b0;   endfunction: new   extern virtual function void reconfigure(mii_cfg   cfg        = null,                                            eth_frame rx_factory = null);   extern virtual function void reset_xactor(reset_e typ = SOFT_RST);   extern protected virtual task main();      extern local task tx_driver();   extern local task rx_monitor();   extern local task crs_monitor();   extern local task col_monitor();endclass: mii_mac_layerfunction void mii_mac_layer::reconfigure(mii_cfg   cfg,                                         eth_frame rx_factory);   if (cfg != null) this.cfg = cfg;   if (rx_factory != null) this.rx_factory = rx_factory;endfunction: reconfigure   // Example 4-52function void mii_mac_layer::reset_xactor(reset_e typ);   super.reset_xactor(typ);   this.sigs.mtx.txd    <= 4'h0;   this.sigs.mtx.tx_en  <= 1'b0;   this.sigs.mtx.tx_err <= 1'b0;   this.tx_chan.flush();   this.rx_chan.flush();   this.indications.reset();   this.frame_count = 0;   if (typ >= FIRM_RST) begin      this.indications.reset( , vmm_notify::HARD );   end   if (typ >= HARD_RST) begin      this.cfg        = this.hard_rst_cfg;      this.rx_factory = this.hard_rst_rx_factory;   endendfunction: reset_xactor// Example 4-51task mii_mac_layer::main();   fork      super.main();      this.tx_driver();      this.rx_monitor();      this.crs_monitor();      this.col_monitor();         join_noneendtask: maintask mii_mac_layer::tx_driver();   logic [7:0] bytes[];   while (1) begin      eth_frame fr;      bit       error = 0;      bit       col   = 0;            this.wait_if_stopped_or_empty(this.tx_chan);      this.tx_chan.activate(fr);      this.utils.frame_to_bytes(fr, bytes);      // Example 4-85      `vmm_callback(mii_mac_layer_callbacks,                    pre_frame_tx(this,                                 fr,                                 bytes));      // Example 4-25      if (log.start_msg(vmm_log::DEBUG_TYP , vmm_log::TRACE_SEV )) begin         log.text("Transmitting frame...");         log.text(fr.psdisplay("   "));         log.end_msg();      end      this.tx_chan.start();      // Example 4-7      foreach (bytes[i]) begin         logic [3:0] nibble0, nibble1;         logic       en;         logic       err;         bit         drop;         {nibble1, nibble0} = bytes[i];         en     = 1'b1;         err    = 1'b0;         drop   = 1'b0;                  `vmm_callback(mii_mac_layer_callbacks,                       pre_symbol_tx(this,                                     fr,                                     bytes,                                     i*2,                                     nibble0,                                     en,                                     err,                                     drop));                  if (!drop) begin            // Example 4-7            // Example 4-56            @this.sigs.mtx;            this.sigs.mtx.txd    <= nibble0;            this.sigs.mtx.tx_en  <= en;            this.sigs.mtx.tx_err <= err;            error |= err;            if (this.sigs.col == 1'b1) col = 1;         end         en     = 1'b1;         err    = 1'b0;         drop   = 1'b0;                  `vmm_callback(mii_mac_layer_callbacks,                       pre_symbol_tx(this,                                     fr,                                     bytes,                                     i*2 + 1,                                     nibble1,                                     en,                                     err,                                     drop));         if (!drop) begin            // Example 4-7             @this.sigs.mtx;            this.sigs.mtx.txd    <= nibble1;            this.sigs.mtx.tx_en  <= en;            this.sigs.mtx.tx_err <= err;            error |= err;            if (this.sigs.col == 1'b1) col = 1;         end         if (col && !this.cfg.full_duplex) begin            error = 1;            `vmm_debug(this.log, "Jamming...");            // Jam the transmission            for (int j = 0; j < 8; j++) begin               nibble0 = $random;               en      = 1'b1;               err     = 1'b0;               drop    = 1'b0;                        `vmm_callback(mii_mac_layer_callbacks,                             pre_symbol_tx(this,                                           fr,                                           bytes,                                           i*2 + 2 + j,                                           nibble0,                                           en,                                           err,                                           drop));               if (!drop) begin                  @this.sigs.mtx;                  this.sigs.mtx.txd    <= nibble0;                  this.sigs.mtx.tx_en  <= en;                  this.sigs.mtx.tx_err <= err;               end            end            break;         end      end      this.tx_chan.complete();      if (log.start_msg(vmm_log::DEBUG_TYP , vmm_log::TRACE_SEV )) begin         log.text("Transmitted frame...");         log.text(fr.psdisplay("   "));         log.end_msg();      end      @this.sigs.mtx;      this.sigs.mtx.txd    <= 4'b0;      this.sigs.mtx.tx_en  <= 1'b0;      this.sigs.mtx.tx_err <= 1'b0;      `vmm_callback(mii_mac_layer_callbacks,                    post_frame_tx(this,                                  fr,                                  bytes,                                  error));      this.tx_chan.remove();   endendtask: tx_drivertask mii_mac_layer::rx_monitor();   logic [7:0] bytes[];   integer     n_bytes;   bit         err;   bytes = new [1600];   // Has the monitor been started in the middle of a frame being received?   if (this.sigs.mrx.rx_dv) begin      `vmm_warning(this.log, "Monitor started in the middle of a PHY->MAC transfer");      wait (this.sigs.mrx.rx_dv === 1'b0);   end   while (1) begin      logic [7:0] a_byte;      // Wait for the start of the frame      wait (this.sigs.mrx.rx_dv === 1'b1);      `vmm_debug(this.log, "Started to receive symbols...");     // Wait for the SFD      while (this.sigs.mrx.rxd !== 4'b1101) begin         if (this.sigs.mrx.rx_dv !== 1'b1) begin            // Indicate a false carrier            // ToDo...            this.indications.reset(eth_pls_indications::CARRIER);            break;         end         @(this.sigs.mrx);      end      `vmm_debug(this.log, "Started to receive a frame...");      @(this.sigs.mrx); // Skip SFD...      // Collect nibbles into bytes (MS first)      // until tx_en is deasserted      n_bytes = 0;      err     = 0;      while (this.sigs.mrx.rx_dv === 1'b1) begin         a_byte[3:0] = this.sigs.mrx.rxd;         if (this.sigs.mrx.rx_err !== 1'b0) err = 1;         `vmm_callback(mii_mac_layer_callbacks,                       post_symbol_rx(this,                                      n_bytes * 2,                                      this.sigs.mrx.rxd,                                      1'b1,                                      this.sigs.mrx.rx_err));         // Example 4-56         @this.sigs.mrx;         if (this.sigs.mrx.rx_dv !== 1'b1) break;         a_byte[7:4] = this.sigs.mrx.rxd;         if (this.sigs.mrx.rx_err !== 1'b0) err = 1;         `vmm_callback(mii_mac_layer_callbacks,                       post_symbol_rx(this,                                      n_bytes * 2 + 1,                                      this.sigs.mrx.rxd,                                      1'b1,                                      this.sigs.mrx.rx_err));         // Increase byte buffer if necessary         if (n_bytes >= bytes.size()) begin            bytes = new [bytes.size() * 2] (bytes);         end         bytes[n_bytes++] = a_byte;                  @this.sigs.mrx;      end      // End of frame. Unpack and forward it      if (!err) begin         eth_frame fr = this.utils.bytes_to_frame(this.log, bytes, n_bytes,                                                  this.rx_factory);         if (fr == null) continue;         fr.stream_id = this.stream_id;         fr.data_id   = this.frame_count++;                  if (log.start_msg(vmm_log::DEBUG_TYP , vmm_log::TRACE_SEV )) begin            log.text("Received frame...");            log.text(fr.psdisplay("   "));            log.end_msg();         end         `vmm_callback(mii_mac_layer_callbacks,                       post_frame_rx(this,                                     fr,                                     bytes,                                     n_bytes));         this.rx_chan.sneak(fr);      end   endendtask: rx_monitor   task mii_mac_layer::crs_monitor();   while (1) begin      wait (this.sigs.crs === 1'b1);      this.indications.indicate(eth_pls_indications::CARRIER);      wait (this.sigs.crs === 1'b0);      this.indications.reset(eth_pls_indications::CARRIER);   endendtask: crs_monitor   task mii_mac_layer::col_monitor();   while (1) begin      wait (this.sigs.col === 1'b1);      this.indications.indicate(eth_pls_indications::COLLISION);      wait (this.sigs.col === 1'b0);      this.indications.reset(eth_pls_indications::COLLISION);   endendtask: col_monitor

⌨️ 快捷键说明

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