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

📄 eth_subenv.sv

📁 VMM 文档加源码, synopsys公司很好的验证资料
💻 SV
📖 第 1 页 / 共 2 页
字号:
// // -------------------------------------------------------------//    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.// -------------------------------------------------------------//`ifndef ETH_SUBENV__SV`define ETH_SUBENV__SV`include "vmm_ral.sv"`include "vmm_subenv.sv"`include "mii.sv"class oc_eth_subenv_cfg;   rand mii_cfg       mii;   rand bit [47:0] dut_addr;   rand bit [ 7:0] n_tx_bd;   rand bit [15:0] max_frame_len;   // Stop when both limits are reached   rand int unsigned run_for_n_frames;         bit [31:0] avail_txbd[$];   vmm_mam_region dma_bfrs[*]; // Indexed by BD offset   constraint test_cfg_valid {      mii.is_10Mb == 0;      mii.full_duplex == 0;      n_tx_bd > 1;      n_tx_bd <= 128;   }   constraint coverage_driven {      max_frame_len inside {1500, 1518, 'h0600};   }   constraint reasonable {      run_for_n_frames < 100;   }   function new();      this.mii = new;   endfunction: new   function string psdisplay(string prefix = "");      $sformat(psdisplay, "%sDUT MAC Addr: %h.%h.%h.%h.%h.%h", prefix,               dut_addr[47:40], dut_addr[39:32], dut_addr[31:24], dut_addr[23:16], dut_addr[15:8], dut_addr[7:0]);      $sformat(psdisplay, "%s\n%s%0d TxBD\n", psdisplay, prefix, this.n_tx_bd);      $sformat(psdisplay, "%s\n%s%0d bytes max frame length", psdisplay,               prefix, this.max_frame_len);      $sformat(psdisplay, "%s\n%sfor %0d Tx frames", psdisplay, prefix,               this.run_for_n_frames);   endfunctionendclass: oc_eth_subenv_cfg//// Self-Checking Structure//class scoreboard;   oc_eth_subenv_cfg cfg;   vmm_log  log;   eth_frame to_phy_side[$];   function new(string            inst,                oc_eth_subenv_cfg cfg);      this.cfg = cfg;      this.log = new("Scoreboard", inst);   endfunction: new   function void sent_from_mac_side(eth_frame fr);      // Is it too long?      if (fr.byte_size() > this.cfg.max_frame_len) return;      // Will it be accepted by the PHY-side MAC layer?      if (fr.fcs) return;// Not if it has a bad FCS      to_phy_side.push_back(fr);   endfunction   function void received_by_phy_side(eth_frame fr);      eth_frame exp;      string diff;      if (this.cfg.run_for_n_frames > 0) begin         this.cfg.run_for_n_frames--;      end      if (this.to_phy_side.size() == 0) begin         `vmm_error(this.log, $psprintf("Unexpected frame received on PHY side (none expected):\n%s",                                        fr.psdisplay("   ")));         return;      end      exp = this.to_phy_side.pop_front();      if (!fr.compare(exp, diff)) begin         `vmm_error(this.log, $psprintf("Unexpected frame received on PHY side: %s:\n%s\n%s",                                        diff, fr.psdisplay("   Actual: "),                                        exp.psdisplay("   Expect: ")));         return;      end      `vmm_note(this.log, $psprintf("Expected frame received on PHY side (%0d left):\n%s",                                    this.cfg.run_for_n_frames,                                    fr.psdisplay("   ")));   endfunctionendclass: scoreboardtypedef class frmwr_emulator;virtual class frmwr_emulator_callbacks extends vmm_xactor_callbacks;   virtual task pre_frame_tx(frmwr_emulator   xactor,                             ref eth_frame frame,                             ref bit       drop);   endtask   virtual function void post_frame_rx(frmwr_emulator         xactor,                                       /*const*/ eth_frame frame);   endfunctionendclass: frmwr_emulator_callbacksclass frmwr_emulator extends vmm_xactor;   eth_frame_channel tx_chan;   scoreboard sb;   local oc_eth_subenv_cfg              cfg;   local ral_block_oc_ethernet ral;   local wb_ram                ram;   local vmm_mam               dma_mam;   local bit [31:0] busy_txbd[$];   function new(string            instance,                int unsigned      stream_id = -1,                oc_eth_subenv_cfg cfg,                eth_frame_channel tx_chan,                scoreboard        sb,                ral_block_oc_ethernet ral,                wb_ram            dma_ram,                vmm_mam           dma_mam);      super.new("FRMWR Emulator", instance, stream_id);      this.tx_chan = tx_chan;      this.sb   = sb;      this.cfg  = cfg;      this.ral  = ral;      this.ram  = dma_ram;      this.dma_mam = dma_mam;      this.reset_xactor();   endfunction: new   function void reset_xactor(reset_e typ = SOFT_RST );      super.reset_xactor(typ);      tx_chan.flush();   endfunction: reset_xactor   virtual task main();      fork         super.main();         this.tx_driver();      join   endtask: main   local task tx_driver();      logic [ 7:0] bytes[];      forever begin         eth_frame        fr;         bit              drop = 0;         vmm_rw::status_e status;         // Wait for a free Tx buffer if none available         wait (this.cfg.avail_txbd.size() > 0);                  this.wait_if_stopped_or_empty(this.tx_chan);         this.tx_chan.activate(fr);         `vmm_callback(frmwr_emulator_callbacks,                       pre_frame_tx(this, fr, drop));         if (!drop) begin            vmm_mam_region bfr;            int            len;            bit            wrap = 0;            int            bd_addr;            this.tx_chan.start();            bfr = dma_mam.request_region(fr.byte_size());            // Write the frame in the DMA RAM            `vmm_trace(this.log, $psprintf("Buffering TX Frame at 'h%h:\n%s",                                           bfr.get_start_offset(),                                           fr.psdisplay("   ")));                        // We need full DWORDs            len = fr.byte_size();            bytes = new [len + (4 - len % 4)];            fr.byte_pack(bytes);            for (int i = 0; i < len; i += 4) begin               this.ram.write(bfr.get_start_offset() + i,                              {bytes[i], bytes[i+1], bytes[i+2], bytes[i+3]});            end            // Set the TxBD accordingly            `vmm_debug(this.log, $psprintf("Updating TxBD at 'h%h",                                           bd_addr));            bd_addr = this.cfg.avail_txbd.pop_front();            ral.TxBD[bd_addr].PTR.write(status, bfr.get_start_offset());            if (status !== vmm_rw::IS_OK) begin               `vmm_error(this.log, $psprintf("Unable to set TxBD[%0d].PTR",                                              bd_addr));            end            cfg.dma_bfrs[bd_addr] = bfr;            ral.TxBD[bd_addr].LEN.set(len);            ral.TxBD[bd_addr].RD.write(status, 1);            if (status !== vmm_rw::IS_OK) begin               `vmm_error(this.log, $psprintf("Unable to mark TxBD[%0d] ready",                                              bd_addr));            end            this.busy_txbd.push_back(bd_addr);            this.tx_chan.complete();            this.sb.sent_from_mac_side(fr);         end // drop                  this.tx_chan.remove();      end

⌨️ 快捷键说明

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