📄 mac.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.// -------------------------------------------------------------//class eth_mac_cfg; rand bit [47:0] addr; rand bit promiscuous; rand bit full_duplex; rand int unsigned rate; rand time slot_time; // In local timeunits (ns) rand time ifg; // In local timeunits (ns) rand time ifg_part1; // In local timeunits (ns) rand int unsigned attempt_limit; rand int unsigned backoff_limit; constraint local_unicast_addr { addr[47:46] == 2'b00; } constraint eth_mac_cfg_valid { rate inside {1, 10, 100, 1000}; ifg_part1 < ifg; } constraint default_values { if (rate == 1) { slot_time == 512 * 1000; ifg == 96000; ifg_part1 == ifg * 2 / 3; attempt_limit == 16; backoff_limit == 10; } if (rate == 10) { slot_time == 512 * 100; ifg == 9600; ifg_part1 == ifg * 2 / 3; attempt_limit == 16; backoff_limit == 10; } if (rate == 100) { slot_time == 512 * 10; ifg == 960; ifg_part1 == ifg * 2 / 3; attempt_limit == 16; backoff_limit == 10; } if (rate == 1000) { slot_time == 4096 * 1; ifg == 96; ifg_part1 == ifg * 2 / 3; attempt_limit == 16; backoff_limit == 10; } } constraint supported { rate != 1000; } function string psdisplay(string prefix); $sformat(psdisplay, "%sMAC Addr: %h.%h.%h.%h.%h.%h", prefix, addr[47:40], addr[39:32], addr[31:24], addr[23:16], addr[15:8], addr[7:0]); $sformat(psdisplay, "%s\n%s%0s%0s duplex, %0d Mb/s", psdisplay, prefix, (this.promiscuous) ? "promiscuous, " : "", (this.full_duplex) ? "full" : "half", this.rate); $sformat(psdisplay, "%s\n%sSlotTime=%0d, ifg=%0d/%0d, %0d attempts, %0d backOff", psdisplay, prefix, this.slot_time, this.ifg, this.ifg_part1, this.attempt_limit, this.backoff_limit); endfunctionendclass: eth_mac_cfg class eth_frame_tx_status extends vmm_data; static vmm_log log = new("eth_frame_tx_status", "class"); bit successful; int unsigned n_attempts; function new(); super.new(this.log); endfunction: newendclass: eth_frame_tx_statustypedef class eth_mac;virtual class eth_mac_callbacks extends vmm_xactor_callbacks; virtual task pre_frame_tx(eth_mac xactor, ref eth_frame frame, ref bit drop); endtask virtual task pre_frame_tx_attempt(eth_mac xactor, eth_frame frame, int unsigned attempt_count, ref bit drop); endtask virtual task post_frame_tx(eth_mac xactor, eth_frame frame, eth_frame_tx_status status); endtask virtual function void post_frame_rx(eth_mac xactor, eth_frame frame); endfunctionendclass: eth_mac_callbacksclass eth_mac extends vmm_xactor; eth_frame_channel tx_chan; eth_frame_channel rx_chan; eth_frame_channel pls_tx_chan; eth_frame_channel pls_rx_chan; // Example 4-82 eth_pls_indications indications; local eth_mac_cfg cfg; local eth_mac_cfg hard_rst_cfg; // Example 4-83 function new(string instance, int unsigned stream_id = -1, eth_mac_cfg cfg, eth_frame_channel tx_chan = null, eth_frame_channel rx_chan = null, eth_frame_channel pls_tx_chan = null, eth_frame_channel pls_rx_chan = null, eth_pls_indications indications = null); super.new("Ethernet MAC Layer", instance, stream_id); this.cfg = cfg; if (tx_chan == null) tx_chan = new({this.log.get_name(), " Tx frames"}, instance); this.tx_chan = tx_chan; if (rx_chan == null) rx_chan = new({this.log.get_name(), " Rx frames"}, instance); this.rx_chan = rx_chan; if (pls_tx_chan == null) pls_tx_chan = new({this.log.get_name(), " PHY->MAC frames"}, instance); this.pls_tx_chan = pls_tx_chan; if (pls_rx_chan == null) pls_rx_chan = new({this.log.get_name(), " MAC->PHY frames"}, instance); this.pls_rx_chan = pls_rx_chan; if (indications == null) indications = new(this.log); this.indications = indications; this.hard_rst_cfg = cfg; endfunction: new extern virtual function void reconfigure(eth_mac_cfg cfg); 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(); local int unsigned maxBackOff; extern local task back_off(int unsigned n_attempts); local bit transmitting; local event transmitting_e; local bit deferring; local event deferring_e; extern local task deference(); extern local task defer();endclass: eth_mactypedef class eth_mac_monitor;virtual class eth_mac_monitor_callbacks extends vmm_xactor_callbacks; typedef enum {TO_MAC, TO_PHY} directions_e; virtual function void post_frame_rx(eth_mac_monitor xactor, eth_mac_monitor_callbacks::directions_e direction, eth_frame frame); endfunctionendclass: eth_mac_monitor_callbacksclass eth_mac_monitor extends vmm_xactor; eth_frame_channel to_phy_chan; eth_frame_channel to_mac_chan; eth_frame_channel pls_to_phy_chan; eth_frame_channel pls_to_mac_chan; eth_pls_indications indications; local eth_mac_cfg cfg; local eth_mac_cfg hard_rst_cfg; function new(string instance, int unsigned stream_id = -1, eth_mac_cfg cfg, eth_frame_channel to_phy_chan = null, eth_frame_channel to_mac_chan = null, eth_frame_channel pls_to_phy_chan = null, eth_frame_channel pls_to_mac_chan = null, eth_pls_indications indications = null); super.new("Ethernet MAC Layer Monitor", instance, stream_id); this.cfg = cfg; if (to_phy_chan == null) to_phy_chan = new({this.log.get_name(), " ->MAC frames"}, instance); this.to_phy_chan = to_phy_chan; if (to_mac_chan == null) to_mac_chan = new({this.log.get_name(), " <-MAC frames"}, instance); this.to_mac_chan = to_mac_chan; if (pls_to_phy_chan == null) pls_to_phy_chan = new({this.log.get_name(), " PHY->MAC frames"}, instance); this.pls_to_phy_chan = pls_to_phy_chan; if (pls_to_mac_chan == null) pls_to_mac_chan = new({this.log.get_name(), " MAC->PHY frames"}, instance); this.pls_to_mac_chan = pls_to_mac_chan; if (indications == null) indications = new(this.log); this.indications = indications; this.hard_rst_cfg = cfg; endfunction: new extern virtual function void reconfigure(eth_mac_cfg cfg); extern virtual function void reset_xactor(reset_e typ = SOFT_RST); extern protected virtual task main(); extern protected task to_phy_monitor(); extern protected task to_mac_monitor();endclass: eth_mac_monitor // // eth_mac //function void eth_mac::reconfigure(eth_mac_cfg cfg); this.cfg = cfg;endfunction: reconfigure function void eth_mac::reset_xactor(reset_e typ); super.reset_xactor(typ); this.tx_chan.flush(); this.rx_chan.flush(); this.pls_tx_chan.flush(); this.pls_rx_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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -