Package: cocotbext-eth
Ethernet interface modules for CocotbGitHub repository:https://github.com/alexforencich/cocotbext-ethIntroductionEthernet interface models forcocotb.Includes PHY-attach interface models for MII, GMII, RGMII, and XGMII; PHY chip interface models for MII, GMII, and RGMII; PTP clock simulation models; and a generic Ethernet MAC model that supports rate enforcement and PTP timestamping.InstallationInstallation from pip (release version, stable):$ pip install cocotbext-ethInstallation from git (latest development version, potentially unstable):$ pip install https://github.com/alexforencich/cocotbext-eth/archive/master.zipInstallation for active development:$ git clone https://github.com/alexforencich/cocotbext-eth
$ pip install -e cocotbext-ethDocumentation and usage examplesSee thetestsdirectory,verilog-ethernet, andcorundumfor complete testbenches using these modules.GMIITheGmiiSourceandGmiiSinkclasses can be used to drive, receive, and monitor GMII traffic.  TheGmiiSourcedrives GMII traffic into a design.  TheGmiiSinkreceives GMII traffic, including monitoring internal interfaces.  TheGmiiPhyclass is a wrapper aroundGmiiSourceandGmiiSinkthat also provides clocking and rate-switching to emulate a GMII PHY chip.To use these modules, import the one you need and connect it to the DUT:from cocotbext.eth import GmiiSource, GmiiSink

gmii_source = GmiiSource(dut.rxd, dut.rx_er, dut.rx_en, dut.clk, dut.rst)
gmii_sink = GmiiSink(dut.txd, dut.tx_er, dut.tx_en, dut.clk, dut.rst)To send data into a design with aGmiiSource, callsend()orsend_nowait().  Accepted data types are iterables that can be converted to bytearray orGmiiFrameobjects.  Optionally, callwait()to wait for the transmit operation to complete.  Example:await gmii_source.send(GmiiFrame.from_payload(b'test data'))
# wait for operation to complete (optional)
await gmii_source.wait()It is also possible to wait for the transmission of a specific frame to complete by passing an event in the tx_complete field of theGmiiFrameobject, and then awaiting the event.  The frame, with simulation time fields set, will be returned in the event data.  Example:frame = GmiiFrame.from_payload(b'test data', tx_complete=Event())
await gmii_source.send(frame)
await frame.tx_complete.wait()
print(frame.tx_complete.data.sim_time_sfd)To receive data with aGmiiSink, callrecv()orrecv_nowait().  Optionally callwait()to wait for new receive data.data = await gmii_sink.recv()TheGmiiPhyclass provides a model of a GMII PHY chip.  It wraps instances ofGmiiSource(rx) andGmiiSink(tx), provides the necessary clocking components, and provides theset_speed()method to change the link speed.set_speed()changes thetx_clkandrx_clkfrequencies, switches betweengtx_clkandtx_clk, and selects the appropriate mode (MII or GMII) on the source and sink instances.  In general, theGmiiPhyclass is intended to be used for integration tests where the design expects to be directly connected to an external GMII PHY chip and contains all of the necessary IO and clocking logic.  Example:from cocotbext.eth import GmiiFrame, GmiiPhy

gmii_phy = GmiiPhy(dut.txd, dut.tx_er, dut.tx_en, dut.tx_clk, dut.gtx_clk,
    dut.rxd, dut.rx_er, dut.rx_en, dut.rx_clk, dut.rst, speed=1000e6)

gmii_phy.set_speed(100e6)

await gmii_phy.rx.send(GmiiFrame.from_payload(b'test RX data'))
tx_data = await gmii_phy.tx.recv()Signalstxd,rxd: datatx_er,rx_er: error (when asserted withtx_enorrx_dv)tx_en,rx_dv: data validConstructor parameters:data: data signal (txd, rxd, etc.)er: error signal (tx_er, rx_er, etc.) (optional)dv: data valid signal (tx_en, rx_dv, etc.)clock: clock signalreset: reset signal (optional)enable: clock enable (optional)mii_select: MII mode select (optional)reset_active_level: reset active level (optional, defaultTrue)Attributes:queue_occupancy_bytes: number of bytes in queuequeue_occupancy_frames: number of frames in queuequeue_occupancy_limit_bytes: max number of bytes in queue allowed before backpressure is applied (source only)queue_occupancy_limit_frames: max number of frames in queue allowed before backpressure is applied (source only)mii_mode: control MII mode whenmii_selectsignal is not connectedMethodssend(frame): sendframe(blocking) (source)send_nowait(frame): sendframe(non-blocking) (source)recv(): receive a frame as aGmiiFrame(blocking) (sink)recv_nowait(): receive a frame as aGmiiFrame(non-blocking) (sink)count(): returns the number of items in the queue (all)empty(): returnsTrueif the queue is empty (all)full(): returnsTrueif the queue occupancy limits are met (source)idle(): returnsTrueif no transfer is in progress (all) or if the queue is not empty (source)clear(): drop all data in queue (all)wait(): wait for idle (source)wait(timeout=0, timeout_unit='ns'): wait for frame received (sink)GMII timing diagramExample transfer via GMII at 1 Gbps:__    __    __    __    _       __    __    __    __
tx_clk     __/  \__/  \__/  \__/  \__/  ... _/  \__/  \__/  \__/  \__
                    _____ _____ _____ _     _ _____ _____
tx_d[7:0]  XXXXXXXXX_55__X_55__X_55__X_ ... _X_72__X_fb__XXXXXXXXXXXX

tx_er      ____________________________ ... _________________________
                    ___________________     _____________
tx_en      ________/                    ...              \___________GmiiFrame objectTheGmiiFrameobject is a container for a frame to be transferred via GMII.  Thedatafield contains the packet data in the form of a list of bytes.errorcontains theersignal level state associated with each byte as a list of ints.Attributes:data: bytearrayerror: error field, optional; list, each entry qualifies the corresponding entry indata.sim_time_start: simulation time of first transfer cycle of frame.sim_time_sfd: simulation time at which the SFD was transferred.sim_time_end: simulation time of last transfer cycle of frame.start_lane: byte lane in which the start control character was transferred.tx_complete: event or callable triggered when frame is transmitted.Methods:from_payload(payload, min_len=60): createGmiiFramefrom payload data, inserts preamble, zero-pads frame to minimum length and computes and inserts FCS (class method)from_raw_payload(payload): createGmiiFramefrom payload data, inserts preamble only (class method)get_preamble_len(): locate SFD and return preamble lengthget_preamble(): return preambleget_payload(strip_fcs=True): return payload, optionally strip FCSget_fcs(): return FCScheck_fcs(): returnsTrueif FCS is correctnormalize(): packerrorto the same length asdata, replicating last element if necessary, initialize to list of0if not specified.compact(): removeerrorif all zeroMIITheMiiSourceandMiiSinkclasses can be used to drive, receive, and monitor MII traffic.  TheMiiSourcedrives MII traffic into a design.  TheMiiSinkreceives MII traffic, including monitoring internal interfaces.  TheMiiPhyclass is a wrapper aroundMiiSourceandMiiSinkthat also provides clocking and rate-switching to emulate an MII PHY chip.To use these modules, import the one you need and connect it to the DUT:from cocotbext.eth import MiiSource, MiiSink

mii_source = MiiSource(dut.rxd, dut.rx_er, dut.rx_en, dut.clk, dut.rst)
mii_sink = MiiSink(dut.txd, dut.tx_er, dut.tx_en, dut.clk, dut.rst)All signals must be passed separately into these classes.To send data into a design with anMiiSource, callsend()orsend_nowait().  Accepted data types are iterables that can be converted to bytearray orGmiiFrameobjects.  Optionally, callwait()to wait for the transmit operation to complete.  Example:await mii_source.send(GmiiFrame.from_payload(b'test data'))
# wait for operation to complete (optional)
await mii_source.wait()It is also possible to wait for the transmission of a specific frame to complete by passing an event in the tx_complete field of theGmiiFrameobject, and then awaiting the event.  The frame, with simulation time fields set, will be returned in the event data.  Example:frame = GmiiFrame.from_payload(b'test data', tx_complete=Event())
await mii_source.send(frame)
await frame.tx_complete.wait()
print(frame.tx_complete.data.sim_time_sfd)To receive data with anMiiSink, callrecv()orrecv_nowait().  Optionally callwait()to wait for new receive data.data = await mii_sink.recv()TheMiiPhyclass provides a model of an MII PHY chip.  It wraps instances ofMiiSource(rx) andMiiSink(tx), provides the necessary clocking components, and provides theset_speed()method to change the link speed.set_speed()changes thetx_clkandrx_clkfrequencies.  In general, theMiiPhyclass is intended to be used for integration tests where the design expects to be directly connected to an external MII PHY chip and contains all of the necessary IO and clocking logic.  Example:from cocotbext.eth import GmiiFrame, MiiPhy

mii_phy = MiiPhy(dut.txd, dut.tx_er, dut.tx_en, dut.tx_clk,
    dut.rxd, dut.rx_er, dut.rx_en, dut.rx_clk, dut.rst, speed=100e6)

mii_phy.set_speed(10e6)

await mii_phy.rx.send(GmiiFrame.from_payload(b'test RX data'))
tx_data = await mii_phy.tx.recv()Signalstxd,rxd: datatx_er,rx_er: error (when asserted withtx_enorrx_dv)tx_en,rx_dv: data validConstructor parameters:data: data signal (txd, rxd, etc.)er: error signal (tx_er, rx_er, etc.) (optional)dv: data valid signal (tx_en, rx_dv, etc.)clock: clock signalreset: reset signal (optional)enable: clock enable (optional)reset_active_level: reset active level (optional, defaultTrue)Attributes:queue_occupancy_bytes: number of bytes in queuequeue_occupancy_frames: number of frames in queuequeue_occupancy_limit_bytes: max number of bytes in queue allowed before backpressure is applied (source only)queue_occupancy_limit_frames: max number of frames in queue allowed before backpressure is applied (source only)Methodssend(frame): sendframe(blocking) (source)send_nowait(frame): sendframe(non-blocking) (source)recv(): receive a frame as aGmiiFrame(blocking) (sink)recv_nowait(): receive a frame as aGmiiFrame(non-blocking) (sink)count(): returns the number of items in the queue (all)empty(): returnsTrueif the queue is empty (all)full(): returnsTrueif the queue occupancy limits are met (source)idle(): returnsTrueif no transfer is in progress (all) or if the queue is not empty (source)clear(): drop all data in queue (all)wait(): wait for idle (source)wait(timeout=0, timeout_unit='ns'): wait for frame received (sink)MII timing diagramExample transfer via MII at 100 Mbps:_   _   _   _   _   _       _   _   _   _
tx_clk     _/ \_/ \_/ \_/ \_/ \_/  ... _/ \_/ \_/ \_/ \_
                 ___ ___ ___ ___ _     _ ___ ___
tx_d[3:0]  XXXXXX_5_X_5_X_5_X_5_X_ ... _X_f_X_b_XXXXXXXX

tx_er      _______________________ ... _________________
                 _________________     _________
tx_en      _____/                  ...          \_______RGMIITheRgmiiSourceandRgmiiSinkclasses can be used to drive, receive, and monitor RGMII traffic.  TheRgmiiSourcedrives RGMII traffic into a design.  TheRgmiiSinkreceives RGMII traffic, including monitoring internal interfaces.  TheRgmiiPhyclass is a wrapper aroundRgmiiSourceandRgmiiSinkthat also provides clocking and rate-switching to emulate an RGMII PHY chip.To use these modules, import the one you need and connect it to the DUT:from cocotbext.eth import RgmiiSource, RgmiiSink

rgmii_source = RgmiiSource(dut.rxd, dut.rx_ctl, dut.clk, dut.rst)
rgmii_sink = RgmiiSink(dut.txd, dut.tx_ctl, dut.clk, dut.rst)All signals must be passed separately into these classes.To send data into a design with anRgmiiSource, callsend()orsend_nowait().  Accepted data types are iterables that can be converted to bytearray orGmiiFrameobjects.  Optionally, callwait()to wait for the transmit operation to complete.  Example:await rgmii_source.send(GmiiFrame.from_payload(b'test data'))
# wait for operation to complete (optional)
await rgmii_source.wait()It is also possible to wait for the transmission of a specific frame to complete by passing an event in the tx_complete field of theGmiiFrameobject, and then awaiting the event.  The frame, with simulation time fields set, will be returned in the event data.  Example:frame = GmiiFrame.from_payload(b'test data', tx_complete=Event())
await rgmii_source.send(frame)
await frame.tx_complete.wait()
print(frame.tx_complete.data.sim_time_sfd)To receive data with anRgmiiSink, callrecv()orrecv_nowait().  Optionally callwait()to wait for new receive data.data = await rgmii_sink.recv()TheRgmiiPhyclass provides a model of an RGMII PHY chip.  It wraps instances ofRgmiiSource(rx) andRgmiiSink(tx), provides the necessary clocking components, and provides theset_speed()method to change the link speed.set_speed()changes therx_clkfrequency and selects the appropriate mode (SDR or DDR) on the source and sink instances.  In general, theRgmiiPhyclass is intended to be used for integration tests where the design expects to be directly connected to an external RGMII PHY chip and contains all of the necessary IO and clocking logic.  Example:from cocotbext.eth import GmiiFrame, RgmiiPhy

rgmii_phy = RgmiiPhy(dut.txd, dut.tx_ctl, dut.tx_clk,
    dut.rxd, dut.rx_ctl, dut.rx_clk, dut.rst, speed=1000e6)

rgmii_phy.set_speed(100e6)

await rgmii_phy.rx.send(GmiiFrame.from_payload(b'test RX data'))
tx_data = await rgmii_phy.tx.recv()Signalstxd,rxd: data (DDR)tx_ctl,rx_ctl: control (DDR, combination of valid and error)Constructor parameters:data: data signal (txd, rxd, etc.)ctrl: controlclock: clock signalreset: reset signal (optional)enable: clock enable (optional)mii_select: MII mode select (optional)reset_active_level: reset active level (optional, defaultTrue)Attributes:queue_occupancy_bytes: number of bytes in queuequeue_occupancy_frames: number of frames in queuequeue_occupancy_limit_bytes: max number of bytes in queue allowed before backpressure is applied (source only)queue_occupancy_limit_frames: max number of frames in queue allowed before backpressure is applied (source only)mii_mode: control MII mode whenmii_selectsignal is not connectedMethodssend(frame): sendframe(blocking) (source)send_nowait(frame): sendframe(non-blocking) (source)recv(): receive a frame as aGmiiFrame(blocking) (sink)recv_nowait(): receive a frame as aGmiiFrame(non-blocking) (sink)count(): returns the number of items in the queue (all)empty(): returnsTrueif the queue is empty (all)full(): returnsTrueif the queue occupancy limits are met (source)idle(): returnsTrueif no transfer is in progress (all) or if the queue is not empty (source)clear(): drop all data in queue (all)wait(): wait for idle (source)wait(timeout=0, timeout_unit='ns'): wait for frame received (sink)RGMII timing diagramExample transfer via RGMII at 1 Gbps:___     ___     ___     _       ___     ___
tx_clk     _/   \___/   \___/   \___/  ... _/   \___/   \___
                   ___ ___ ___ ___ ___     ___ ___
tx_d[3:0]  XXXXXXXX_5_X_5_X_5_X_5_X_5_ ... _f_X_b_XXXXXXXXXX
                   ___________________     _______
tx_ctl     _______/                    ...        \_________XGMIITheXgmiiSourceandXgmiiSinkclasses can be used to drive, receive, and monitor XGMII traffic.  TheXgmiiSourcedrives XGMII traffic into a design.  TheXgmiiSinkreceives XGMII traffic, including monitoring internal interfaces.  The modules are capable of operating with XGMII interface widths of 32 or 64 bits.To use these modules, import the one you need and connect it to the DUT:from cocotbext.eth import XgmiiSource, XgmiiSink

xgmii_source = XgmiiSource(dut.rxd, dut.rxc, dut.clk, dut.rst)
xgmii_sink = XgmiiSink(dut.txd, dut.txc, dut.clk, dut.rst)All signals must be passed separately into these classes.To send data into a design with anXgmiiSource, callsend()orsend_nowait().  Accepted data types are iterables that can be converted to bytearray orXgmiiFrameobjects.  Optionally, callwait()to wait for the transmit operation to complete.  Example:await xgmii_source.send(XgmiiFrame.from_payload(b'test data'))
# wait for operation to complete (optional)
await xgmii_source.wait()It is also possible to wait for the transmission of a specific frame to complete by passing an event in the tx_complete field of theXgmiiFrameobject, and then awaiting the event.  The frame, with simulation time fields set, will be returned in the event data.  Example:frame = XgmiiFrame.from_payload(b'test data', tx_complete=Event())
await xgmii_source.send(frame)
await frame.tx_complete.wait()
print(frame.tx_complete.data.sim_time_sfd)To receive data with anXgmiiSink, callrecv()orrecv_nowait().  Optionally callwait()to wait for new receive data.data = await xgmii_sink.recv()Signalstxd,rxd: datatxc,rxc: controlConstructor parameters:data: data signal (txd, rxd, etc.)ctrl: control signal (txc, rxc, etc.)clock: clock signalreset: reset signal (optional)enable: clock enable (optional)reset_active_level: reset active level (optional, defaultTrue)Attributes:queue_occupancy_bytes: number of bytes in queuequeue_occupancy_frames: number of frames in queuequeue_occupancy_limit_bytes: max number of bytes in queue allowed before backpressure is applied (source only)queue_occupancy_limit_frames: max number of frames in queue allowed before backpressure is applied (source only)Methodssend(frame): sendframe(blocking) (source)send_nowait(frame): sendframe(non-blocking) (source)recv(): receive a frame as anXgmiiFrame(blocking) (sink)recv_nowait(): receive a frame as anXgmiiFrame(non-blocking) (sink)count(): returns the number of items in the queue (all)empty(): returnsTrueif the queue is empty (all)full(): returnsTrueif the queue occupancy limits are met (source)idle(): returnsTrueif no transfer is in progress (all) or if the queue is not empty (source)clear(): drop all data in queue (all)wait(): wait for idle (source)wait(timeout=0, timeout_unit='ns'): wait for frame received (sink)XGMII timing diagramExample transfer via 64-bit XGMII:__    __    __    __    __    _       __    __
tx_clk     __/  \__/  \__/  \__/  \__/  \__/  ... _/  \__/  \__
           __ _____ _____ _____ _____ _____ _     _ _____ _____
txd[63:56] __X_07__X_d5__X_51__X_01__X_09__X_ ... _X_fb__X_07__
           __ _____ _____ _____ _____ _____ _     _ _____ _____
txd[55:48] __X_07__X_55__X_5a__X_00__X_08__X_ ... _X_72__X_07__
           __ _____ _____ _____ _____ _____ _     _ _____ _____
txd[47:40] __X_07__X_55__X_d5__X_00__X_07__X_ ... _X_0d__X_07__
           __ _____ _____ _____ _____ _____ _     _ _____ _____
txd[39:32] __X_07__X_55__X_d4__X_80__X_06__X_ ... _X_37__X_07__
           __ _____ _____ _____ _____ _____ _     _ _____ _____
txd[31:24] __X_07__X_55__X_d3__X_55__X_05__X_ ... _X_2d__X_07__
           __ _____ _____ _____ _____ _____ _     _ _____ _____
txd[23:16] __X_07__X_55__X_d2__X_54__X_04__X_ ... _X_2c__X_07__
           __ _____ _____ _____ _____ _____ _     _ _____ _____
txd[15:8]  __X_07__X_55__X_d1__X_53__X_03__X_ ... _X_2b__X_07__
           __ _____ _____ _____ _____ _____ _     _ _____ _____
txd[7:0]   __X_07__X_fb__X_da__X_52__X_02__X_ ... _X_2a__X_fd__
           __ _____ _____ _____ _____ _____ _     _ _____ _____
txc[7:0]   __X_ff__X_01__X_00__X_00__X_00__X_ ... _X_00__X_ff__XgmiiFrame objectTheXgmiiFrameobject is a container for a frame to be transferred via XGMII.  Thedatafield contains the packet data in the form of a list of bytes.ctrlcontains the control signal level state associated with each byte as a list of ints.  Whenctrlis high, the correspondingdatabyte is interpreted as an XGMII control character.Attributes:data: bytearrayctrl: control field, optional; list, each entry qualifies the corresponding entry indataas an XGMII control character.sim_time_start: simulation time of first transfer cycle of frame.sim_time_sfd: simulation time at which the SFD was transferred.sim_time_end: simulation time of last transfer cycle of frame.start_lane: byte lane in which the start control character was transferred.tx_complete: event or callable triggered when frame is transmitted.Methods:from_payload(payload, min_len=60): createXgmiiFramefrom payload data, inserts preamble, zero-pads frame to minimum length and computes and inserts FCS (class method)from_raw_payload(payload): createXgmiiFramefrom payload data, inserts preamble only (class method)get_preamble_len(): locate SFD and return preamble lengthget_preamble(): return preambleget_payload(strip_fcs=True): return payload, optionally strip FCSget_fcs(): return FCScheck_fcs(): returnsTrueif FCS is correctnormalize(): packctrlto the same length asdata, replicating last element if necessary, initialize to list of0if not specified.compact(): removectrlif all zeroEthernet MAC modelTheEthMac,EthMacTxandEthMacRxmodules are models of an Ethernet MAC with an AXI stream interface.  TheEthMacRxmodule drives Ethernet frames in the form of AXI stream traffic into a design.  TheEthMacTxmodule accepts Ethernet frames in the form of AXI stream traffic from a design.EthMacis a wrapper module containingEthMacRx(rx) andEthMacTx(tx).  The modules are capable of operating with any interface width.  The MAC models enforce the correct data rates and timings in both the receive and transmit direction, and can also collect PTP timestamps from a PTP hardware clock.To use these modules, import the one you need and connect it to the DUT:from cocotbext.axi import AxiStreamBus
from cocotbext.eth import EthMac

mac = EthMac(
    tx_clk=dut.tx_clk,
    tx_rst=dut.tx_rst,
    tx_bus=AxiStreamBus.from_prefix(dut, "tx_axis"),
    tx_ptp_time=dut.tx_ptp_time,
    tx_ptp_ts=dut.tx_ptp_ts,
    tx_ptp_ts_tag=dut.tx_ptp_ts_tag,
    tx_ptp_ts_valid=dut.tx_ptp_ts_valid,
    rx_clk=dut.rx_clk,
    rx_rst=dut.rx_rst,
    rx_bus=AxiStreamBus.from_prefix(dut, "rx_axis"),
    rx_ptp_time=dut.rx_ptp_time,
    ifg=12, speed=speed
)To send data into a design, callsend()orsend_nowait().  Accepted data types are iterables that can be converted to bytearray orEthMacFrameobjects.  Optionally, callwait()to wait for the transmit operation to complete.  Example:await mac.tx.send(EthMacFrame.from_payload(b'test data'))
# wait for operation to complete (optional)
await mac.tx.wait()It is also possible to wait for the transmission of a specific frame to complete by passing an event in the tx_complete field of theEthMacFrameobject, and then awaiting the event.  The frame, with simulation time fields set, will be returned in the event data.  Example:frame = EthMacFrame.from_payload(b'test data', tx_complete=Event())
await mac.tx.send(frame)
await frame.tx_complete.wait()
print(frame.tx_complete.data.sim_time_sfd)To receive data, callrecv()orrecv_nowait().  Optionally callwait()to wait for new receive data.data = await mac.tx.recv()PTP timestamping requires free-running PTP clocks driving the PTP time inputs, synchronous with the corresponding MAC clocks.  The values of these fields are then captured when the frame SFD is transferred and returned either on tuser (for received frames) or on a separate streaming interface (for transmitted frames).  Additionally, on the transmit path, a tag value from tuser is returned along with the timestamp.Signalstdata: payload data, must be a multiple of 8 bitstvalid: qualifies all other signalstready: indicates sink is ready for data (tx only)tlast: marks the last cycle of a frametkeep: qualifies data byte, data bus width must be evenly divisible bytkeepsignal widthtuser: user data, carries frame error mark and captured receive PTP timestamp (RX) or PTP timestamp tag (TX)ptp_time: PTP time input from PHC, captured intoptp_timestampfield coincident with transfer of frame SFD and output onptp_ts(TX) ortuser(RX)ptp_ts: captured transmit PTP timestampptp_ts_tag: captured transmit PTP timestamp tagptp_ts_valid: qualifies captured transmit PTP timestampConstructor parameters (EthMacRxandEthMacTx):bus:AxiStreamBusobject containing AXI stream interface signalsclock: clock signalreset: reset signal (optional)ptp_time: PTP time input from PHC (optional)ptp_ts: PTP timestamp (optional) (tx)ptp_ts_tag: PTP timestamp tag (optional) (tx)ptp_ts_valid: PTP timestamp valid (optional) (tx)reset_active_level: reset active level (optional, defaultTrue)ifg: IFG size in byte times (optional, default12)speed: link speed in bits per second (optional, default1000e6)Constructor parameters (EthMac):tx_bus:AxiStreamBusobject containing transmit AXI stream interface signalstx_clk: transmit clocktx_rst: transmit reset (optional)tx_ptp_time: transmit PTP time input from PHC (optional)tx_ptp_ts: transmit PTP timestamp (optional)tx_ptp_ts_tag: transmit PTP timestamp tag (optional)tx_ptp_ts_valid: transmit PTP timestamp valid (optional)rx_bus:AxiStreamBusobject containing receive AXI stream interface signalsrx_clk: receive clockrx_rst: receive reset (optional)rx_ptp_time: receive PTP time input from PHC (optional)reset_active_level: reset active level (optional, defaultTrue)ifg: IFG size in byte times (optional, default12)speed: link speed in bits per second (optional, default1000e6)Attributes:queue_occupancy_bytes: number of bytes in queuequeue_occupancy_frames: number of frames in queuequeue_occupancy_limit_bytes: max number of bytes in queue allowed before backpressure is applied (RX only)queue_occupancy_limit_frames: max number of frames in queue allowed before backpressure is applied (RX only)ifg: IFG size in byte timesspeed: link speed in bits per secondMethodssend(frame): sendframe(blocking) (rx)send_nowait(frame): sendframe(non-blocking) (rx)recv(): receive a frame as anEthMacFrame(blocking) (tx)recv_nowait(): receive a frame as anEthMacFrame(non-blocking) (tx)count(): returns the number of items in the queue (all)empty(): returnsTrueif the queue is empty (all)full(): returnsTrueif the queue occupancy limits are met (rx)idle(): returnsTrueif no transfer is in progress (all) or if the queue is not empty (rx)clear(): drop all data in queue (all)wait(): wait for idle (rx)wait(timeout=0, timeout_unit='ns'): wait for frame received (tx)EthMacFrame objectTheEthMacFrameobject is a container for a frame to be transferred via XGMII.  Thedatafield contains the packet data in the form of a list of bytes.Attributes:data: bytearraysim_time_start: simulation time of first transfer cycle of frame.sim_time_sfd: simulation time at which the SFD was transferred.sim_time_end: simulation time of last transfer cycle of frame.ptp_tag: PTP timestamp tag for transmitted frames.ptp_timestamp: captured value ofptp_timeat frame SFDtx_complete: event or callable triggered when frame is transmitted.Methods:from_payload(payload, min_len=60): createEthMacFramefrom payload data, zero-pads frame to minimum length and computes and inserts FCS (class method)from_raw_payload(payload): createEthMacFramefrom payload data (class method)get_payload(strip_fcs=True): return payload, optionally strip FCSget_fcs(): return FCScheck_fcs(): returnsTrueif FCS is correctPTP clockThePtpClockclass implements a PTP hardware clock that produces IEEE 1588 format 96-bit time-of-day and 64-bit relative PTP timestamps.To use this module, import it and connect it to the DUT:from cocotbext.eth import PtpClock

ptp_clock = PtpClock(
    ts_tod=dut.ts_tod,
    ts_rel=dut.ts_rel,
    ts_step=dut.ts_step,
    pps=dut.pps,
    clock=dut.clk,
    reset=dut.reset,
    period_ns=6.4
)Once the clock is instantiated, it will generate a continuous stream of monotonically increasing PTP timestamps on every clock edge.Internally, thePtpClockmodule uses 32-bit fractional ns fields for higher frequency resolution.  Only the upper 16 bits are returned in the timestamps, but the full fns value can be accessed with thets_tod_fnsandts_rel_fnsattributes.All APIs that handle fractional values use theDecimaltype for maximum precision, as the combination of timestamp range and resolution is usually too much for normal floating point numbers to handle without significant loss of precision.Signalsts_tod: 96-bit time-of-day timestamp (48 bit seconds, 32 bit ns, 16 bit fractional ns)ts_rel: 64-bit relative timestamp (48 bit ns, 16 bit fractional ns)ts_step: step output, pulsed when non-monotonic step occurspps: pulse-per-second output, pulsed when ts_tod seconds field incrementsConstructor parameters:ts_tod: 96-bit time-of-day timestamp signal (optional)ts_rel: 64-bit relative timestamp signal (optional)ts_step: timestamp step signal (optional)pps: pulse-per-second signal (optional)clock: clockreset: reset (optional)reset_active_level: reset active level (optional, defaultTrue)period_ns: clock period (nanoseconds, default6.4)Attributes:ts_tod_s: current 96-bit ToD timestamp seconds fieldts_tod_ns: current 96-bit ToD timestamp ns fieldts_tod_fns: current 96-bit ToD timestamp fractional ns fieldts_rel_ns: current 64-bit relative timestamp ns fieldts_rel_fns: current 64-bit relative timestamp fractional ns fieldMethodsset_period(ns, fns): set clock period from separate fieldsset_drift(num, denom): set clock drift from separate fieldsset_period_ns(t): set clock period and drift in ns (Decimal)get_period_ns(): return current clock period in ns (Decimal)set_ts_tod(ts_s, ts_ns, ts_fns): set 96-bit ToD timestamp from separate fieldsset_ts_tod_96(ts): set 96-bit ToD timestamp from integerset_ts_tod_ns(t): set 96-bit ToD timestamp from ns (Decimal)set_ts_tod_s(t): set 96-bit ToD timestamp from seconds (Decimal)set_ts_tod_sim_time(): set 96-bit ToD timestamp from sim timeget_ts_tod(): return current 96-bit ToD timestamp as separate fieldsget_ts_tod_96(): return current 96-bit ToD timestamp as an integerget_ts_tod_ns(): return current 96-bit ToD timestamp in ns (Decimal)get_ts_tod_s(): return current 96-bit ToD timestamp in seconds (Decimal)set_ts_rel(ts_ns, ts_fns): set 64-bit relative timestamp from separate fieldsset_ts_rel_64(ts): set 64-bit relative timestamp from integerset_ts_rel_ns(t): set 64-bit relative timestamp from ns (Decimal)set_ts_rel_s(t): set 64-bit relative timestamp from seconds (Decimal)set_ts_rel_sim_time(): set 64-bit relative timestamp from sim timeget_ts_rel(): return current 64-bit relative timestamp as separate fieldsget_ts_rel_64(): return current 64-bit relative timestamp as an integerget_ts_rel_ns(): return current 64-bit relative timestamp in ns (Decimal)get_ts_rel_s(): return current 64-bit relative timestamp in seconds (Decimal)PTP clock (sim time)ThePtpClockSimTimeclass implements a PTP hardware clock that produces IEEE 1588 format 96-bit time-of-day and 64-bit relative PTP timestamps, derived from the current simulation time.  This module can be used in place ofPtpClockso that captured PTP timestamps can be easily compared to captured simulation time.To use this module, import it and connect it to the DUT:from cocotbext.eth import PtpClockSimTime

ptp_clock = PtpClockSimTime(
    ts_tod=dut.ts_tod,
    ts_rel=dut.ts_rel,
    pps=dut.pps,
    clock=dut.clk
)Once the clock is instantiated, it will generate a continuous stream of monotonically increasing PTP timestamps on every clock edge.All APIs that handle fractional values use theDecimaltype for maximum precision, as the combination of timestamp range and resolution is usually too much for normal floating point numbers to handle without significant loss of precision.Signalsts_tod: 96-bit time-of-day timestamp (48 bit seconds, 32 bit ns, 16 bit fractional ns)ts_rel: 64-bit relative timestamp (48 bit ns, 16 bit fractional ns)pps: pulse-per-second output, pulsed when ts_tod seconds field incrementsConstructor parameters:ts_tod: 96-bit time-of-day timestamp signal (optional)ts_rel: 64-bit relative timestamp signal (optional)pps: pulse-per-second signal (optional)clock: clockAttributes:ts_tod_s: current 96-bit ToD timestamp seconds fieldts_tod_ns: current 96-bit ToD timestamp ns fieldts_tod_fns: current 96-bit ToD timestamp fractional ns fieldts_rel_ns: current 64-bit relative timestamp ns fieldts_rel_fns: current 64-bit relative timestamp fractional ns fieldMethodsget_ts_tod(): return current 96-bit ToD timestamp as separate fieldsget_ts_tod_96(): return current 96-bit ToD timestamp as an integerget_ts_tod_ns(): return current 96-bit ToD timestamp in ns (Decimal)get_ts_tod_s(): return current 96-bit ToD timestamp in seconds (Decimal)get_ts_rel(): return current 64-bit relative timestamp as separate fieldsget_ts_rel_96(): return current 64-bit relative timestamp as an integerget_ts_rel_ns(): return current 64-bit relative timestamp in ns (Decimal)get_ts_rel_s(): return current 64-bit relative timestamp in seconds (Decimal)