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

📄 mii_phy.sv

📁 VMM 文档加源码, synopsys公司很好的验证资料
💻 SV
📖 第 1 页 / 共 2 页
字号:
      // Wait for a frame to be received to force a collision      if (this.randomized_col.kind != mii_phy_collision::NONE) begin         `vmm_trace(this.log, $psprintf("Forcing a collision on symbol #%0d...",                                        this.randomized_col.on_symbol));         @ (posedge this.sigs.crs);         repeat (this.randomized_col.on_symbol) @ (this.sigs.ptx);      end      this.tx_chan.start();      this.indications.indicate(eth_pls_indications::CARRIER);      this.txing = 1;      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_phy_layer_callbacks,                       pre_symbol_tx(this,                                     fr,                                     bytes,                                     i*2,                                     nibble0,                                     en,                                     err,                                     drop));         if (!drop) begin            @this.sigs.prx;            this.sigs.prx.rxd    <= nibble0;            this.sigs.prx.rx_dv  <= en;            this.sigs.prx.rx_err <= err;            error |= err;            if (this.sigs.col) col = 1;         end         en     = 1'b1;         err    = 1'b0;         drop   = 1'b0;                  `vmm_callback(mii_phy_layer_callbacks,                       pre_symbol_tx(this,                                     fr,                                     bytes,                                     i*2 + 1,                                     nibble1,                                     en,                                     err,                                     drop));         if (!drop) begin            @this.sigs.prx;            this.sigs.prx.rxd    <= nibble1;            this.sigs.prx.rx_dv  <= en;            this.sigs.prx.rx_err <= err;            error |= err;            if (this.sigs.col) 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_phy_layer_callbacks,                             pre_symbol_tx(this,                                           fr,                                           bytes,                                           i*2 + 2 + j,                                           nibble0,                                           en,                                           err,                                           drop));               if (!drop) begin                  @this.sigs.prx;                  this.sigs.prx.rxd    <= nibble0;                  this.sigs.prx.rx_dv  <= en;                  this.sigs.prx.rx_err <= err;               end            end            break;         end      end      this.txing = 0;      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.prx;      this.sigs.prx.rxd    <= 4'b0;      this.sigs.prx.rx_dv  <= 1'b0;      this.sigs.prx.rx_err <= 1'b0;      // Make sure CRS stays asserted for >1 cycle      fork         begin: hold_crs            repeat (2) @this.sigs.prx;            if (!this.txing && !this.rxing) begin               this.indications.reset(eth_pls_indications::CARRIER);            end         end      join_none      `vmm_callback(mii_phy_layer_callbacks,                    post_frame_tx(this,                                  fr,                                  bytes,                                  error));      this.tx_chan.remove();   endendtask: tx_drivertask mii_phy_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.ptx.tx_en) begin      `vmm_warning(this.log, "Transactor started in the middle of a MAC->PHY transfer");      this.indications.indicate(eth_pls_indications::CARRIER);      wait (this.sigs.ptx.tx_en === 1'b0);   end   if (!this.txing) this.indications.reset(eth_pls_indications::CARRIER);   forever begin      logic [7:0] a_byte;      // Wait for the start of the frame      wait (this.sigs.ptx.tx_en === 1'b1);      this.indications.indicate(eth_pls_indications::CARRIER);      `vmm_debug(this.log, "Started to receive symbols...");      this.rxing = 1;     // Wait for the SFD      while (this.sigs.ptx.txd !== 4'b1101) begin         if (this.sigs.ptx.tx_en !== 1'b1) begin            // Indicate a false carrier            // ToDo...            this.indications.reset(eth_pls_indications::CARRIER);            break;         end         @(this.sigs.ptx);      end      `vmm_debug(this.log, "Started to receive a frame...");      @(this.sigs.ptx); // Skip SFD...      // Collect nibbles into bytes (LS first)      // until tx_en is deasserted      n_bytes = 0;      err     = 0;      while (this.sigs.ptx.tx_en === 1'b1) begin         a_byte[3:0] = this.sigs.ptx.txd;         if (this.sigs.ptx.tx_err !== 1'b0) err = 1;         `vmm_callback(mii_phy_layer_callbacks,                       post_symbol_rx(this,                                      n_bytes * 2,                                      this.sigs.ptx.txd,                                      1'b1,                                      this.sigs.ptx.tx_err));         @this.sigs.ptx;         if (this.sigs.ptx.tx_en !== 1'b1) break;         a_byte[7:4] = this.sigs.ptx.txd;         if (this.sigs.ptx.tx_err !== 1'b0) err = 1;         `vmm_callback(mii_phy_layer_callbacks,                       post_symbol_rx(this,                                      n_bytes * 2 + 1,                                      this.sigs.ptx.txd,                                      1'b1,                                      this.sigs.ptx.tx_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.ptx;      end      this.rxing = 0;      // Make sure CRS stays asserted for >1 cycle      fork         begin            repeat (2) @this.sigs.prx;            if (!this.txing && !this.rxing) begin               this.indications.reset(eth_pls_indications::CARRIER);            end         end      join_none      // 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_phy_layer_callbacks,                       post_frame_rx(this,                                     fr,                                     bytes,                                     n_bytes));                  this.rx_chan.sneak(fr);      end   endendtask: rx_monitor   task mii_phy_layer::crs_driver();   while (1) begin      this.indications.wait_for(eth_pls_indications::CARRIER);      this.sigs.crs <= 1'b1;      this.indications.wait_for_off(eth_pls_indications::CARRIER);      this.sigs.crs <= 1'b0;   endendtask: crs_driver   task mii_phy_layer::col_driver();   fork      while (1) begin         wait (this.sigs.ptx.tx_en === 1'b1 && this.txing);         this.indications.indicate(eth_pls_indications::COLLISION);         wait (this.sigs.ptx.tx_en !== 1'b1 || !this.txing);         if (this.sigs.ptx.tx_en === 1'b1 && !this.txing) begin            // Hold COL pass RX_DV deassert            repeat (2) @this.sigs.prx;         end         this.indications.reset(eth_pls_indications::COLLISION);      end   join_none   while (1) begin      this.indications.wait_for(eth_pls_indications::COLLISION);      this.sigs.col <= 1'b1;      this.indications.wait_for_off(eth_pls_indications::COLLISION);      this.sigs.col <= 1'b0;   endendtask: col_driver

⌨️ 快捷键说明

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