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

📄 mac.sv

📁 VMM 文档加源码, synopsys公司很好的验证资料
💻 SV
📖 第 1 页 / 共 2 页
字号:
   endendfunction: reset_xactor   task eth_mac::main();   fork      super.main();      this.tx_driver();      this.rx_monitor();      this.deference();   join_noneendtask: maintask eth_mac::tx_driver();   eth_frame fr;   while (1) begin      bit drop = 0;      eth_frame_tx_status status = new;      status.successful = 0;      status.n_attempts = 0;      this.transmitting = 0;            this.wait_if_stopped_or_empty(this.tx_chan);      this.tx_chan.activate(fr);      `vmm_callback(eth_mac_callbacks,                    pre_frame_tx(this,                                 fr,                                 drop));      if (drop) begin         this.tx_chan.remove();         fr.notify.indicate(vmm_data::ENDED , status);         continue;      end            this.tx_chan.start();      while (status.n_attempts < this.cfg.attempt_limit && !status.successful) begin         bit col = 0;         `vmm_callback(eth_mac_callbacks,                       pre_frame_tx_attempt(this,                                            fr,                                            status.n_attempts,                                            drop));         if (drop) break;         if (log.start_msg(vmm_log::DEBUG_TYP , vmm_log::TRACE_SEV )) begin            string prefix;            log.text("Attempting to transmitting frame...");            $sformat(prefix, "   Attempt #%0d: ", status.n_attempts);            log.text(fr.psdisplay(prefix));            log.end_msg();         end               if (status.n_attempts > 0) this.back_off(status.n_attempts);         this.defer();         // Watch for collisions         if (!this.cfg.full_duplex) begin            fork               begin                  this.indications.wait_for(eth_pls_indications::COLLISION);                  col = 1;                  `vmm_debug(this.log, "Collision!");               end            join_none         end         // PLS Tx channel has a blocking model         this.transmitting = 1;         this.pls_tx_chan.put(fr);         this.transmitting = 0;         disable fork;         status.n_attempts++;         // If there were no collisions, success!         if (!col) begin            status.successful = 1;            break;         end      end            if (log.start_msg(vmm_log::DEBUG_TYP , vmm_log::TRACE_SEV )) begin         string prefix;         log.text("Done transmitting frame...");         $sformat(prefix, "   %0s: ", (status.successful) ? "Success" : "Failure");         log.text(fr.psdisplay(prefix));         log.end_msg();      end            this.tx_chan.complete();      `vmm_callback(eth_mac_callbacks,                    post_frame_tx(this,                                  fr,                                  status));      fr.notify.indicate(vmm_data::ENDED , status);      this.tx_chan.remove();   endendtask: tx_driver            task eth_mac::rx_monitor();   eth_frame fr;   while (1) begin      this.pls_rx_chan.get(fr);      `vmm_callback(eth_mac_callbacks,                    post_frame_rx(this,                                  fr));      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            if (this.cfg.promiscuous ||          this.cfg.addr === fr.dst ||          fr.dst[47] === 1'b1) begin         this.rx_chan.sneak(fr);      end else begin         `vmm_debug(this.log, "Frame ignored because of wrong unicast address");      end   endendtask: rx_monitor   task eth_mac::back_off(int unsigned n_attempts);   int unsigned n;   if (n_attempts == 1) this.maxBackOff = 2;   else if (n_attempts < this.cfg.backoff_limit) this.maxBackOff *= 2;   n = $random() % this.maxBackOff;   `vmm_debug(this.log, $psprintf("Backing off for %0d slotTimes...", n));   #(this.cfg.slot_time * n);endtask: back_offtask eth_mac::deference();   forever begin      this.deferring = 0;      `vmm_debug(this.log, "Deference: not active");      if (this.cfg.full_duplex) begin         wait (this.transmitting === 1'b1);         this.deferring = 1;         wait (this.transmitting === 1'b0);         #(this.cfg.ifg);      end else begin         bit wasTransmitting;         `vmm_debug(this.log, "Deference: Waiting for CRS");         this.indications.wait_for(eth_pls_indications::CARRIER);         wasTransmitting = this.transmitting;         this.deferring = 1;         `vmm_debug(this.log, "Deference: ACTIVE. Waiting for ~CRS");         this.indications.wait_for_off(eth_pls_indications::CARRIER);         wait (this.transmitting === 1'b0);         `vmm_debug(this.log, "Deference: IFG");         if (wasTransmitting) begin            #(this.cfg.ifg_part1);         end else begin: interFrameSpacingPart1            forever begin               fork                  begin                     #(this.cfg.ifg_part1);                     disable interFrameSpacingPart1;                  end               join_none               this.indications.wait_for(eth_pls_indications::CARRIER);               disable fork;               this.indications.wait_for_off(eth_pls_indications::CARRIER);            end         end         #(this.cfg.ifg - this.cfg.ifg_part1);      end   endendtask: deferencetask eth_mac::defer();  `vmm_debug(this.log, "Deferring...");   wait(this.deferring === 1'b0);  `vmm_debug(this.log, "Deferred.");endtask: defer   //   // eth_mac_monitor   //   function void eth_mac_monitor::reconfigure(eth_mac_cfg cfg);   this.cfg = cfg;endfunction: reconfigure   function void eth_mac_monitor::reset_xactor(reset_e typ);   super.reset_xactor(typ);   this.to_phy_chan.flush();   this.to_mac_chan.flush();   this.pls_to_phy_chan.flush();   this.pls_to_mac_chan.flush();   this.indications.reset();   if (typ >= FIRM_RST) begin      this.indications.reset(, vmm_notify::HARD );   end   if (typ >= HARD_RST) begin      this.cfg = this.hard_rst_cfg;   endendfunction: reset_xactor   task eth_mac_monitor::main();   fork      super.main();      this.to_phy_monitor();      this.to_mac_monitor();   join_noneendtask: maintask eth_mac_monitor::to_phy_monitor();   eth_frame fr;   while (1) begin      this.pls_to_phy_chan.get(fr);      `vmm_callback(eth_mac_monitor_callbacks,                    post_frame_rx(this,                                  eth_mac_monitor_callbacks::TO_PHY,                                  fr));      this.to_phy_chan.sneak(fr);   endendtask: to_phy_monitor   task eth_mac_monitor::to_mac_monitor();   eth_frame fr;   while (1) begin      this.pls_to_mac_chan.get(fr);      `vmm_callback(eth_mac_monitor_callbacks,                    post_frame_rx(this,                                  eth_mac_monitor_callbacks::TO_MAC,                                  fr));            this.to_mac_chan.sneak(fr);   endendtask: to_mac_monitor

⌨️ 快捷键说明

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