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

📄 tb_env.sv

📁 VMM 文档加源码, synopsys公司很好的验证资料
💻 SV
📖 第 1 页 / 共 3 页
字号:
// // -------------------------------------------------------------//    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.// -------------------------------------------------------------// `include "wishbone.sv"`include "mii.sv"class test_cfg;   rand integer unsigned tx_rx_clk_offset;   rand eth_mac_cfg mac;   rand bit [47:0]  dut_addr;   rand mii_cfg     mii;   rand wb_slave_cfg  wb;   rand bit [ 7:0] rx_bd_offset;   rand bit [ 7:0] n_tx_bd;   rand bit [ 7:0] n_rx_bd;   rand bit [31:0] txrx_bfr_base;        bit [31:0] txrx_pnt[*];   rand bit [15:0] max_frame_len;   rand bit        huge_enable;   // Stop when both limits are reached   rand integer unsigned run_for_n_tx_frames;   rand integer unsigned run_for_n_rx_frames;         constraint test_cfg_valid {      tx_rx_clk_offset < 100;      mac.rate inside {10, 100};      mii.is_10Mb == (mac.rate == 10);      mii.full_duplex == mac.full_duplex;      dut_addr[47:46] == 2'b00;      wb.port_size   == wb_cfg::DWORD;      wb.granularity == wb_cfg::BYTE;       wb.cycles      == wb_cfg::CLASSIC;      rx_bd_offset inside {[8'h01:8'h7F]};  // At least one TX BD and one Rx BD      n_tx_bd > 0 && n_tx_bd < rx_bd_offset+1;      n_rx_bd > 0 && n_rx_bd <= 'h80 - rx_bd_offset;      txrx_bfr_base < 32'hFFFF_FFFF - 256 * ((huge_enable) ? 65536 : max_frame_len);      txrx_bfr_base[2:0] == 3'b000;   }   // Example 6-10   constraint coverage_driven {      max_frame_len inside {1500, 1518, 'h0600};   }   constraint reasonable {      run_for_n_tx_frames < 100;      run_for_n_rx_frames < 100;   }   function new();      this.mac = new;      this.mii = new;      this.wb  = 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", psdisplay, this.mac.psdisplay(prefix));      $sformat(psdisplay, "%s\n%sTx/Rx Clock offset: %0d", psdisplay, prefix, this.tx_rx_clk_offset);      $sformat(psdisplay, "%s\n%s", psdisplay, this.wb.psdisplay(prefix));      $sformat(psdisplay, "%s\n%s%0d TxBD, #%0d RxBD based at 'h%h", psdisplay, prefix,               this.n_tx_bd, this.n_rx_bd, this.txrx_bfr_base);      $sformat(psdisplay, "%s\n%s%0d bytes max frame length", psdisplay, prefix,               (this.huge_enable) ? 65536 : this.max_frame_len);      $sformat(psdisplay, "%s\n%sfor %0d Tx + %0d Rx frames", psdisplay, prefix,               this.run_for_n_tx_frames, this.run_for_n_rx_frames);   endfunctionendclass: test_cfg// Example 4-63//// Example of adding supplemental information to// transaction descriptor received by a transactor//class annotated_eth_frame extends eth_frame;   string direction = "Unknown";   virtual function vmm_data allocate();      annotated_eth_frame fr = new;      allocate = fr;   endfunction: allocate   virtual function vmm_data copy(vmm_data to = null);      annotated_eth_frame cpy;      if (to == null) cpy = new;      else if (!$cast(cpy, to)) begin         //`vmm_fatal(to.log, "Unable to copy into non-annotated_eth_frame instance");         $display("Error:Unable to copy into non-annotated_eth_frame instance");         return null;      end      super.copy(cpy);      cpy.direction = this.direction;      copy = cpy;   endfunction: copy   virtual function string psdisplay(string prefix = "");      psdisplay = super.psdisplay({prefix, this.direction, ": "});   endfunction: psdisplayendclass: annotated_eth_frame// Example 5-45//// Self-Checking Structure//class scoreboard;   test_cfg cfg;   vmm_log  log;   eth_frame to_mac_side[$];   eth_frame to_phy_side[$];   // Example 5-56   bit rx_err;   local bit is_tx;   local int frame_len;   // Example 6-6   covergroup frame_coverage;      direction: coverpoint is_tx {         bins Tx = {1};         bins Rx = {0};         // Example 6-7         option.weight = 0;      }       hugen    : coverpoint cfg.huge_enable {         option.weight = 0;      }      // Example 6-10      max_fl   : coverpoint cfg.max_frame_len {         bins fl_1500 = {1500};         bins fl_1518 = {1518};         bins fl_0600 = {'h0600};         option.weight = 0;      }      // Example 6-2      // Example 6-5      frame_len: coverpoint frame_len {         bins max_fl_less_4 = {cfg.max_frame_len - 4};         bins max_fl_less_1 = {cfg.max_frame_len - 1};         bins max_fl        = {cfg.max_frame_len};         bins max_fl_plus_1 = {cfg.max_frame_len + 1};         bins max_fl_plus_4 = {cfg.max_frame_len + 4};         bins max_size      = {65535};         option.weight = 0;      }      // Example 6-3      cross direction, hugen, max_fl, frame_len {         // Example 6-9         option.comment = "Coverage for Example 2-5";      }      // Example 6-8      option.weight = 2 * 3 * 6;   endgroup   // Example 5-46   function new(test_cfg cfg);      this.cfg = cfg;      this.log = new("Scoreboard", "");      this.rx_err = 0;      frame_coverage = new;   endfunction: new   // Example 5-48   function void sent_from_mac_side(eth_frame fr);      // Example 6-4      this.is_tx     = 1;      this.frame_len = fr.byte_size();      this.frame_coverage.sample();      // Is it too long?      if (!this.cfg.huge_enable && 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      if (!this.cfg.mac.promiscuous &&          fr.dst !== this.cfg.mac.addr &&          !fr.dst[47]) return; // Not if wrong unicast address      to_phy_side.push_back(fr);   endfunction   function void sent_from_phy_side(eth_frame fr);      // Example 6-4      this.is_tx     = 0;      this.frame_len = fr.byte_size();      this.frame_coverage.sample();      // Is it too long?      if (!this.cfg.huge_enable && fr.byte_size() > this.cfg.max_frame_len) return;      // Will it be accepted by the MAC-side MAC layer?      if (fr.fcs) return;// Not if it has a bad FCS      if (!this.cfg.mac.promiscuous &&          fr.dst !== this.cfg.dut_addr) return; // Not if wrong unicast address      to_mac_side.push_back(fr);   endfunction   // Example 5-48   function void received_by_mac_side(eth_frame fr);      eth_frame exp;      string diff;      if (this.cfg.run_for_n_rx_frames > 0) begin         this.cfg.run_for_n_rx_frames--;      end      if (this.to_mac_side.size() == 0) begin         `vmm_error(this.log, $psprintf("Unexpected frame received on MAC side (none expected):\n%s",                                        fr.psdisplay("   ")));         return;      end      exp = this.to_mac_side.pop_front();      if (!fr.compare(exp, diff)) begin         `vmm_error(this.log, $psprintf("Unexpected frame received on MAC side: %s:\n%s\n%s",                                        diff, fr.psdisplay("   Actual: "),                                        exp.psdisplay("   Expect: ")));         return;      end      `vmm_note(this.log, $psprintf("Expected frame received on MAC side (%0d left):\n%s",                                    this.cfg.run_for_n_rx_frames,                                    fr.psdisplay("   ")));   endfunction   function void received_by_phy_side(eth_frame fr);      eth_frame exp;      string diff;      if (this.cfg.run_for_n_tx_frames > 0) begin         this.cfg.run_for_n_tx_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_tx_frames,                                    fr.psdisplay("   ")));   endfunctionendclass: scoreboard// Example 5-53class sb_mac_cbs extends eth_mac_callbacks;   scoreboard sb;   function new(scoreboard sb);      this.sb = sb;   endfunction   virtual task post_frame_tx(eth_mac             xactor,                              eth_frame           frame,                              eth_frame_tx_status status);      if (status.successful && !this.sb.rx_err) begin         this.sb.sent_from_phy_side(frame);      end      else begin         this.sb.cfg.run_for_n_rx_frames--;      end      this.sb.rx_err = 0;   endtaskendclasstypedef class sw_emulator;virtual class sw_emulator_callbacks extends vmm_xactor_callbacks;   virtual task pre_frame_tx(sw_emulator   xactor,                             ref eth_frame frame,                             ref bit       drop);   endtask   virtual function void post_frame_rx(sw_emulator         xactor,                                       /*const*/ eth_frame frame);   endfunctionendclass: sw_emulator_callbacksclass sw_emulator extends vmm_xactor;   eth_frame_channel tx_chan;   scoreboard sb;   local test_cfg  cfg;   local wb_master host;   local wb_ram    ram;   local bit [31:0] avail_txbd[$];   local bit [31:0] busy_txbd[$];   bit [31:0] next_rxbd;   local event avail_txbd_e;   function new(string            instance,                int unsigned      stream_id = -1,                test_cfg          cfg,                scoreboard        sb,                wb_master         host,                wb_ram            ram);      super.new("SW Emulator", instance, stream_id);      tx_chan = new("SW Emulator Tx Channel", instance);      this.sb   = sb;      this.cfg  = cfg;      this.host = host;      this.ram  = ram;      this.reset_xactor();   endfunction: new   function void reset_xactor(reset_e typ = SOFT_RST );      super.reset_xactor(typ);      tx_chan.flush();      this.host.reset_xactor(typ);      begin         bit [31:0] bd_addr = 32'h0000_0400;         repeat (this.cfg.n_tx_bd) begin            this.avail_txbd.push_back(bd_addr);            bd_addr += 8;         end         // Push a "wrap" flag         this.avail_txbd.push_back(32'hFFFF_FFFF);         -> this.avail_txbd_e;      end      this.busy_txbd.delete();   endfunction: reset_xactor   virtual task main();      fork         super.main();         this.tx_driver();         this.int_serv();      join   endtask: main   local task tx_driver();      logic [ 7:0] bytes[];      while (1) begin         eth_frame fr;         bit       drop = 0;         bit       ok;         // Wait for a free Tx buffer if none available         while (this.avail_txbd.size() == 0) @(this.avail_txbd_e);

⌨️ 快捷键说明

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